dialogs/FBDBlockDialog.py
changeset 1242 ec2c415fc65e
parent 1237 0c8b8ef9559b
child 1244 336d515096b1
equal deleted inserted replaced
1241:368f8516706c 1242:ec2c415fc65e
    29 from graphics.FBD_Objects import FBD_Block
    29 from graphics.FBD_Objects import FBD_Block
    30 from controls.LibraryPanel import LibraryPanel
    30 from controls.LibraryPanel import LibraryPanel
    31 from BlockPreviewDialog import BlockPreviewDialog
    31 from BlockPreviewDialog import BlockPreviewDialog
    32 
    32 
    33 #-------------------------------------------------------------------------------
    33 #-------------------------------------------------------------------------------
    34 #                          Create New Block Dialog
    34 #                         Set Block Parameters Dialog
    35 #-------------------------------------------------------------------------------
    35 #-------------------------------------------------------------------------------
    36 
    36 
       
    37 """
       
    38 Class that implements a dialog for defining parameters of a FBD block graphic
       
    39 element
       
    40 """
       
    41 
    37 class FBDBlockDialog(BlockPreviewDialog):
    42 class FBDBlockDialog(BlockPreviewDialog):
    38     
    43     
    39     def __init__(self, parent, controller, tagname):
    44     def __init__(self, parent, controller, tagname):
       
    45         """
       
    46         Constructor
       
    47         @param parent: Parent wx.Window of dialog for modal
       
    48         @param controller: Reference to project controller
       
    49         @param tagname: Tagname of project POU edited
       
    50         """
    40         BlockPreviewDialog.__init__(self, parent, controller, tagname,
    51         BlockPreviewDialog.__init__(self, parent, controller, tagname,
    41               size=wx.Size(600, 450), title=_('Block Properties'))
    52               size=wx.Size(600, 450), title=_('Block Properties'))
    42         
    53         
       
    54         # Create dialog main sizer
    43         main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=4, vgap=10)
    55         main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=4, vgap=10)
    44         main_sizer.AddGrowableCol(0)
    56         main_sizer.AddGrowableCol(0)
    45         main_sizer.AddGrowableRow(0)
    57         main_sizer.AddGrowableRow(0)
    46         
    58         
       
    59         # Create a sizer for dividing FBD block parameters in two columns
    47         column_sizer = wx.BoxSizer(wx.HORIZONTAL)
    60         column_sizer = wx.BoxSizer(wx.HORIZONTAL)
    48         main_sizer.AddSizer(column_sizer, border=20, 
    61         main_sizer.AddSizer(column_sizer, border=20, 
    49               flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
    62               flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
    50         
    63         
       
    64         # Create static box around library panel
    51         type_staticbox = wx.StaticBox(self, label=_('Type:'))
    65         type_staticbox = wx.StaticBox(self, label=_('Type:'))
    52         left_staticboxsizer = wx.StaticBoxSizer(type_staticbox, wx.VERTICAL)
    66         left_staticboxsizer = wx.StaticBoxSizer(type_staticbox, wx.VERTICAL)
    53         column_sizer.AddSizer(left_staticboxsizer, 1, border=5, 
    67         column_sizer.AddSizer(left_staticboxsizer, 1, border=5, 
    54               flag=wx.GROW|wx.RIGHT)
    68               flag=wx.GROW|wx.RIGHT)
    55         
    69         
       
    70         # Create Library panel and add it to static box
    56         self.LibraryPanel = LibraryPanel(self)
    71         self.LibraryPanel = LibraryPanel(self)
       
    72         # Set function to call when selection in Library panel changed
    57         setattr(self.LibraryPanel, "_OnTreeItemSelected", 
    73         setattr(self.LibraryPanel, "_OnTreeItemSelected", 
    58               self.OnLibraryTreeItemSelected)
    74               self.OnLibraryTreeItemSelected)
    59         left_staticboxsizer.AddWindow(self.LibraryPanel, 1, border=5, 
    75         left_staticboxsizer.AddWindow(self.LibraryPanel, 1, border=5, 
    60               flag=wx.GROW|wx.TOP)
    76               flag=wx.GROW|wx.TOP)
    61         
    77         
       
    78         # Create sizer for other block parameters and preview panle
    62         right_gridsizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=5)
    79         right_gridsizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=5)
    63         right_gridsizer.AddGrowableCol(0)
    80         right_gridsizer.AddGrowableCol(0)
    64         right_gridsizer.AddGrowableRow(2)
    81         right_gridsizer.AddGrowableRow(2)
    65         column_sizer.AddSizer(right_gridsizer, 1, border=5, 
    82         column_sizer.AddSizer(right_gridsizer, 1, border=5, 
    66               flag=wx.GROW|wx.LEFT)
    83               flag=wx.GROW|wx.LEFT)
    67         
    84         
       
    85         # Create sizer for other block parameters
    68         top_right_gridsizer = wx.FlexGridSizer(cols=2, hgap=0, rows=4, vgap=5)
    86         top_right_gridsizer = wx.FlexGridSizer(cols=2, hgap=0, rows=4, vgap=5)
    69         top_right_gridsizer.AddGrowableCol(1)
    87         top_right_gridsizer.AddGrowableCol(1)
    70         right_gridsizer.AddSizer(top_right_gridsizer, flag=wx.GROW)
    88         right_gridsizer.AddSizer(top_right_gridsizer, flag=wx.GROW)
    71         
    89         
       
    90         # Create label for block name
    72         name_label = wx.StaticText(self, label=_('Name:'))
    91         name_label = wx.StaticText(self, label=_('Name:'))
    73         top_right_gridsizer.AddWindow(name_label, 
    92         top_right_gridsizer.AddWindow(name_label, 
    74               flag=wx.ALIGN_CENTER_VERTICAL)
    93               flag=wx.ALIGN_CENTER_VERTICAL)
    75         
    94         
       
    95         # Create text control for defining block name
    76         self.BlockName = wx.TextCtrl(self)
    96         self.BlockName = wx.TextCtrl(self)
    77         self.Bind(wx.EVT_TEXT, self.OnNameChanged, self.BlockName)
    97         self.Bind(wx.EVT_TEXT, self.OnNameChanged, self.BlockName)
    78         top_right_gridsizer.AddWindow(self.BlockName, flag=wx.GROW)
    98         top_right_gridsizer.AddWindow(self.BlockName, flag=wx.GROW)
    79         
    99         
       
   100         # Create label for extended block input number
    80         inputs_label = wx.StaticText(self, label=_('Inputs:'))
   101         inputs_label = wx.StaticText(self, label=_('Inputs:'))
    81         top_right_gridsizer.AddWindow(inputs_label, 
   102         top_right_gridsizer.AddWindow(inputs_label, 
    82               flag=wx.ALIGN_CENTER_VERTICAL)
   103               flag=wx.ALIGN_CENTER_VERTICAL)
    83         
   104         
       
   105         # Create spin control for defining extended block input number
    84         self.Inputs = wx.SpinCtrl(self, min=2, max=20,
   106         self.Inputs = wx.SpinCtrl(self, min=2, max=20,
    85               style=wx.SP_ARROW_KEYS)
   107               style=wx.SP_ARROW_KEYS)
    86         self.Bind(wx.EVT_SPINCTRL, self.OnInputsChanged, self.Inputs)
   108         self.Bind(wx.EVT_SPINCTRL, self.OnInputsChanged, self.Inputs)
    87         top_right_gridsizer.AddWindow(self.Inputs, flag=wx.GROW)
   109         top_right_gridsizer.AddWindow(self.Inputs, flag=wx.GROW)
    88         
   110         
    89         execution_order_label = wx.StaticText(self, label=_('Execution Order:'))
   111         # Create label for block execution order
       
   112         execution_order_label = wx.StaticText(self, 
       
   113               label=_('Execution Order:'))
    90         top_right_gridsizer.AddWindow(execution_order_label, 
   114         top_right_gridsizer.AddWindow(execution_order_label, 
    91               flag=wx.ALIGN_CENTER_VERTICAL)
   115               flag=wx.ALIGN_CENTER_VERTICAL)
    92         
   116         
       
   117         # Create spin control for defining block execution order
    93         self.ExecutionOrder = wx.SpinCtrl(self, min=0, style=wx.SP_ARROW_KEYS)
   118         self.ExecutionOrder = wx.SpinCtrl(self, min=0, style=wx.SP_ARROW_KEYS)
    94         self.Bind(wx.EVT_SPINCTRL, self.OnExecutionOrderChanged, self.ExecutionOrder)
   119         self.Bind(wx.EVT_SPINCTRL, self.OnExecutionOrderChanged, 
       
   120                   self.ExecutionOrder)
    95         top_right_gridsizer.AddWindow(self.ExecutionOrder, flag=wx.GROW)
   121         top_right_gridsizer.AddWindow(self.ExecutionOrder, flag=wx.GROW)
    96                 
   122                 
    97         execution_control_label = wx.StaticText(self, label=_('Execution Control:'))
   123         # Create label for block execution control
       
   124         execution_control_label = wx.StaticText(self, 
       
   125               label=_('Execution Control:'))
    98         top_right_gridsizer.AddWindow(execution_control_label, 
   126         top_right_gridsizer.AddWindow(execution_control_label, 
    99               flag=wx.ALIGN_CENTER_VERTICAL)
   127               flag=wx.ALIGN_CENTER_VERTICAL)
   100         
   128         
       
   129         # Create check box to enable block execution control
   101         self.ExecutionControl = wx.CheckBox(self)
   130         self.ExecutionControl = wx.CheckBox(self)
   102         self.Bind(wx.EVT_CHECKBOX, self.OnExecutionOrderChanged, self.ExecutionControl)
   131         self.Bind(wx.EVT_CHECKBOX, self.OnExecutionOrderChanged, 
       
   132                   self.ExecutionControl)
   103         top_right_gridsizer.AddWindow(self.ExecutionControl, flag=wx.GROW)
   133         top_right_gridsizer.AddWindow(self.ExecutionControl, flag=wx.GROW)
   104         
   134         
       
   135         # Add preview panel and associated label to sizers
   105         right_gridsizer.AddWindow(self.PreviewLabel, flag=wx.GROW)
   136         right_gridsizer.AddWindow(self.PreviewLabel, flag=wx.GROW)
   106         right_gridsizer.AddWindow(self.Preview, flag=wx.GROW)
   137         right_gridsizer.AddWindow(self.Preview, flag=wx.GROW)
   107         
   138         
   108         main_sizer.AddSizer(self.ButtonSizer, border=20, 
   139         main_sizer.AddSizer(self.ButtonSizer, border=20, 
   109               flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
   140               flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
   110         
   141         
   111         self.SetSizer(main_sizer)
   142         self.SetSizer(main_sizer)
   112         
   143         
       
   144         self.ParamsControl = {
       
   145             "extension": self.Inputs,
       
   146             "executionOrder": self.ExecutionOrder,
       
   147             "executionControl": self.ExecutionControl
       
   148         }
       
   149         
       
   150         # Init controls value and sensibility
   113         self.BlockName.SetValue("")
   151         self.BlockName.SetValue("")
   114         self.BlockName.Enable(False)
   152         self.BlockName.Enable(False)
   115         self.Inputs.Enable(False)
   153         self.Inputs.Enable(False)
       
   154         
       
   155         # Variable containing last name typed
   116         self.CurrentBlockName = None
   156         self.CurrentBlockName = None
   117         
   157         
       
   158         # Refresh Library panel values
   118         self.LibraryPanel.SetBlockList(controller.GetBlockTypes(tagname))
   159         self.LibraryPanel.SetBlockList(controller.GetBlockTypes(tagname))
   119         self.LibraryPanel.SetFocus()
   160         self.LibraryPanel.SetFocus()
   120     
   161     
   121     def OnOK(self, event):
   162     def OnOK(self, event):
       
   163         """
       
   164         Called when dialog OK button is pressed
       
   165         Test if parameters defined are valid
       
   166         @param event: wx.Event from OK button
       
   167         """
   122         message = None
   168         message = None
       
   169         
       
   170         # Get block type selected
   123         selected = self.LibraryPanel.GetSelectedBlock()
   171         selected = self.LibraryPanel.GetSelectedBlock()
       
   172         
       
   173         # Get block type name and if block is a function block
   124         block_name = self.BlockName.GetValue()
   174         block_name = self.BlockName.GetValue()
   125         name_enabled = self.BlockName.IsEnabled()
   175         name_enabled = self.BlockName.IsEnabled()
       
   176         
       
   177         # Test that a type has been selected for block
   126         if selected is None:
   178         if selected is None:
   127             message = _("Form isn't complete. Valid block type must be selected!")
   179             message = _("Form isn't complete. Valid block type must be selected!")
       
   180         
       
   181         # Test, if block is a function block, that a name have been defined
   128         elif name_enabled and block_name == "":
   182         elif name_enabled and block_name == "":
   129             message = _("Form isn't complete. Name must be filled!")
   183             message = _("Form isn't complete. Name must be filled!")
       
   184         
       
   185         # Show error message if an error is detected
   130         if message is not None:
   186         if message is not None:
   131             self.ShowMessage(message)
   187             self.ShowMessage(message)
       
   188         
       
   189         # Test block name validity if necessary
   132         elif not name_enabled or self.TestBlockName(block_name):
   190         elif not name_enabled or self.TestBlockName(block_name):
   133             BlockPreviewDialog.OnOK(self, event)
   191             BlockPreviewDialog.OnOK(self, event)
   134 
   192     
   135     def SetValues(self, values):
   193     def SetValues(self, values):
       
   194         """
       
   195         Set default block parameters
       
   196         @param values: Block parameters values
       
   197         """
       
   198         # Extract block type defined in parameters
   136         blocktype = values.get("type", None)
   199         blocktype = values.get("type", None)
   137         default_name_model = re.compile("%s[0-9]+" % blocktype)
   200         
       
   201         # Define regular expression for determine if block name is block
       
   202         # default name
       
   203         default_name_model = re.compile(
       
   204             "%s[0-9]+" % blocktype if blocktype is not None else ".*")
       
   205         
       
   206         # Select block type in library panel    
   138         if blocktype is not None:
   207         if blocktype is not None:
   139             self.LibraryPanel.SelectTreeItem(blocktype, 
   208             self.LibraryPanel.SelectTreeItem(blocktype, 
   140                                              values.get("inputs", None))
   209                                              values.get("inputs", None))
       
   210         
       
   211         # For each parameters defined, set corresponding control value
   141         for name, value in values.items():
   212         for name, value in values.items():
   142             if name == "name":
   213             if name == "name":
       
   214                 # Parameter is block name
   143                 if value != "":
   215                 if value != "":
       
   216                     # Set default block name for testing
   144                     self.DefaultBlockName = value
   217                     self.DefaultBlockName = value
       
   218                     
       
   219                     # Test if block name is type default block name and save
       
   220                     # block name if not (name have been typed by user)
   145                     if default_name_model.match(value) is None:
   221                     if default_name_model.match(value) is None:
   146                         self.CurrentBlockName = value
   222                         self.CurrentBlockName = value
       
   223             
   147                 self.BlockName.ChangeValue(value)
   224                 self.BlockName.ChangeValue(value)
   148             elif name == "extension":
   225             
   149                 self.Inputs.SetValue(value)
   226             else:
   150             elif name == "executionOrder":
   227                 control = self.ParamsControl.get(name, None)
   151                 self.ExecutionOrder.SetValue(value)
   228                 if control is not None:
   152             elif name == "executionControl":
   229                     control.SetValue(value)
   153                    self.ExecutionControl.SetValue(value)
   230         
       
   231         # Refresh preview panel
   154         self.RefreshPreview()
   232         self.RefreshPreview()
   155 
   233 
   156     def GetValues(self):
   234     def GetValues(self):
       
   235         """
       
   236         Return block parameters defined in dialog
       
   237         @return: {parameter_name: parameter_value,...}
       
   238         """
   157         values = self.LibraryPanel.GetSelectedBlock()
   239         values = self.LibraryPanel.GetSelectedBlock()
   158         if self.BlockName.IsEnabled() and self.BlockName.GetValue() != "":
   240         if self.BlockName.IsEnabled() and self.BlockName.GetValue() != "":
   159             values["name"] = self.BlockName.GetValue()
   241             values["name"] = self.BlockName.GetValue()
   160         values["width"], values["height"] = self.Block.GetSize()
   242         values["width"], values["height"] = self.Block.GetSize()
   161         values["extension"] = self.Inputs.GetValue()
   243         values.update({
   162         values["executionOrder"] = self.ExecutionOrder.GetValue()
   244             name: control.GetValue()
   163         values["executionControl"] = self.ExecutionControl.GetValue()
   245             for name, control in self.ParamsControl.iteritems()})
   164         return values
   246         return values
   165         
   247         
   166     def OnLibraryTreeItemSelected(self, event):
   248     def OnLibraryTreeItemSelected(self, event):
       
   249         """
       
   250         Called when block type selected in library panel
       
   251         @param event: wx.TreeEvent
       
   252         """
       
   253         # Get type selected in library panel
   167         values = self.LibraryPanel.GetSelectedBlock()
   254         values = self.LibraryPanel.GetSelectedBlock()
       
   255         
       
   256         # Get block type informations
   168         blocktype = (self.Controller.GetBlockType(values["type"], 
   257         blocktype = (self.Controller.GetBlockType(values["type"], 
   169                                                   values["inputs"])
   258                                                   values["inputs"])
   170                      if values is not None else None)
   259                      if values is not None else None)
   171         
   260         
       
   261         # Set input number spin control according to block type informations
   172         if blocktype is not None:
   262         if blocktype is not None:
   173             self.Inputs.SetValue(len(blocktype["inputs"]))
   263             self.Inputs.SetValue(len(blocktype["inputs"]))
   174             self.Inputs.Enable(blocktype["extensible"])
   264             self.Inputs.Enable(blocktype["extensible"])
   175         else:
   265         else:
   176             self.Inputs.SetValue(2)
   266             self.Inputs.SetValue(2)
   177             self.Inputs.Enable(False)
   267             self.Inputs.Enable(False)
   178         
   268         
       
   269         # Update block name with default value if block type is a function and
       
   270         # current block name wasn't typed by user
   179         if blocktype is not None and blocktype["type"] != "function":
   271         if blocktype is not None and blocktype["type"] != "function":
   180             self.BlockName.Enable(True)
   272             self.BlockName.Enable(True)
   181             self.BlockName.ChangeValue(
   273             self.BlockName.ChangeValue(
   182                 self.CurrentBlockName
   274                 self.CurrentBlockName
   183                 if self.CurrentBlockName is not None
   275                 if self.CurrentBlockName is not None
   185                     self.TagName, None, values["type"]+"%d", 0))
   277                     self.TagName, None, values["type"]+"%d", 0))
   186         else:
   278         else:
   187             self.BlockName.Enable(False)
   279             self.BlockName.Enable(False)
   188             self.BlockName.ChangeValue("")
   280             self.BlockName.ChangeValue("")
   189         
   281         
       
   282         # Refresh preview panel
   190         self.RefreshPreview()
   283         self.RefreshPreview()
   191     
   284     
   192     def OnNameChanged(self, event):
   285     def OnNameChanged(self, event):
       
   286         """
       
   287         Called when block name value changed
       
   288         @param event: wx.TextEvent
       
   289         """
   193         if self.BlockName.IsEnabled():
   290         if self.BlockName.IsEnabled():
       
   291             # Save block name typed by user
   194             self.CurrentBlockName = self.BlockName.GetValue()
   292             self.CurrentBlockName = self.BlockName.GetValue()
   195             self.RefreshPreview()
   293             self.RefreshPreview()
   196         event.Skip()
   294         event.Skip()
   197     
   295     
   198     def OnInputsChanged(self, event):
   296     def OnInputsChanged(self, event):
       
   297         """
       
   298         Called when block inputs number changed
       
   299         @param event: wx.SpinEvent
       
   300         """
   199         if self.Inputs.IsEnabled():
   301         if self.Inputs.IsEnabled():
   200             self.RefreshPreview()
   302             self.RefreshPreview()
   201         event.Skip()
   303         event.Skip()
   202     
   304     
   203     def OnExecutionOrderChanged(self, event):
   305     def OnExecutionOrderChanged(self, event):
       
   306         """
       
   307         Called when block execution order value changed
       
   308         @param event: wx.SpinEvent
       
   309         """
   204         self.RefreshPreview()
   310         self.RefreshPreview()
   205         event.Skip()
   311         event.Skip()
   206     
   312     
   207     def OnExecutionControlChanged(self, event):
   313     def OnExecutionControlChanged(self, event):
       
   314         """
       
   315         Called when block execution control value changed
       
   316         @param event: wx.SpinEvent
       
   317         """
   208         self.RefreshPreview()
   318         self.RefreshPreview()
   209         event.Skip()
   319         event.Skip()
   210     
   320     
   211     def RefreshPreview(self):
   321     def RefreshPreview(self):
       
   322         """
       
   323         Refresh preview panel of graphic element
       
   324         Override BlockPreviewDialog function
       
   325         """
       
   326         # Get type selected in library panel
   212         values = self.LibraryPanel.GetSelectedBlock()
   327         values = self.LibraryPanel.GetSelectedBlock()
       
   328         
       
   329         # If a block type is selected in library panel
   213         if values is not None:
   330         if values is not None:
   214             if self.BlockName.IsEnabled():
   331             blockname = (self.BlockName.GetValue()
   215                 blockname = self.BlockName.GetValue()
   332                          if self.BlockName.IsEnabled()
   216             else:
   333                          else "")
   217                 blockname = ""
   334             
       
   335             # Set graphic element displayed, creating a FBD block element
   218             self.Block = FBD_Block(self.Preview, values["type"], 
   336             self.Block = FBD_Block(self.Preview, values["type"], 
   219                     blockname, 
   337                     blockname, 
   220                     extension = self.Inputs.GetValue(), 
   338                     extension = self.Inputs.GetValue(), 
   221                     inputs = values["inputs"], 
   339                     inputs = values["inputs"], 
   222                     executionControl = self.ExecutionControl.GetValue(), 
   340                     executionControl = self.ExecutionControl.GetValue(), 
   223                     executionOrder = self.ExecutionOrder.GetValue())
   341                     executionOrder = self.ExecutionOrder.GetValue())
       
   342         
       
   343         # Reset graphic element displayed
   224         else:
   344         else:
   225             self.Block = None 
   345             self.Block = None 
       
   346         
       
   347         # Call BlockPreviewDialog function
   226         BlockPreviewDialog.RefreshPreview(self)
   348         BlockPreviewDialog.RefreshPreview(self)