dialogs/SFCStepDialog.py
changeset 1250 7e6de17c687a
parent 814 5743cbdff669
child 1252 18cd1357e8d3
equal deleted inserted replaced
1249:b956c924cbbd 1250:7e6de17c687a
    21 #License along with this library; if not, write to the Free Software
    21 #License along with this library; if not, write to the Free Software
    22 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    22 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    23 
    23 
    24 import wx
    24 import wx
    25 
    25 
    26 from graphics import *
    26 from graphics.SFC_Objects import SFC_Step
       
    27 from BlockPreviewDialog import BlockPreviewDialog
    27 
    28 
    28 #-------------------------------------------------------------------------------
    29 #-------------------------------------------------------------------------------
    29 #                          Edit Step Content Dialog
    30 #                         Set SFC Step Parameters Dialog
    30 #-------------------------------------------------------------------------------
    31 #-------------------------------------------------------------------------------
    31 
    32 
    32 class SFCStepDialog(wx.Dialog):
    33 """
       
    34 Class that implements a dialog for defining parameters of a SFC step graphic
       
    35 element
       
    36 """
       
    37 
       
    38 class SFCStepDialog(BlockPreviewDialog):
    33     
    39     
    34     def __init__(self, parent, controller, initial = False):
    40     def __init__(self, parent, controller, tagname, initial=False):
    35         wx.Dialog.__init__(self, parent, title=_('Edit Step'), 
    41         """
    36               size=wx.Size(400, 250))
    42         Constructor
       
    43         @param parent: Parent wx.Window of dialog for modal
       
    44         @param controller: Reference to project controller
       
    45         @param tagname: Tagname of project POU edited
       
    46         @param initial: True if step is initial (default: False)
       
    47         """
       
    48         BlockPreviewDialog.__init__(self,parent, controller, tagname,  
       
    49               size=wx.Size(400, 250), title=_('Edit Step'))
    37         
    50         
    38         main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
    51         # Init common sizers
    39         main_sizer.AddGrowableCol(0)
    52         self._init_sizers(2, 0, 6, None, 2, 1)
    40         main_sizer.AddGrowableRow(0)
       
    41         
    53         
    42         column_sizer = wx.BoxSizer(wx.HORIZONTAL)
    54         # Create label for SFC step name
    43         main_sizer.AddSizer(column_sizer, border=20, 
    55         name_label = wx.StaticText(self, label=_('Name:'))
    44               flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
    56         self.LeftGridSizer.AddWindow(name_label, flag=wx.GROW)
    45         
    57         
    46         left_gridsizer = wx.FlexGridSizer(cols=1, hgap=0, rows=6, vgap=5)
    58         # Create text control for defining SFC step name
    47         left_gridsizer.AddGrowableCol(0)
       
    48         column_sizer.AddSizer(left_gridsizer, 1, border=5, 
       
    49                               flag=wx.GROW|wx.RIGHT)
       
    50         
       
    51         name_label = wx.StaticText(self, label=_('Name:'))
       
    52         left_gridsizer.AddWindow(name_label, flag=wx.GROW)
       
    53         
       
    54         self.StepName = wx.TextCtrl(self)
    59         self.StepName = wx.TextCtrl(self)
    55         self.Bind(wx.EVT_TEXT, self.OnNameChanged, self.StepName)
    60         self.Bind(wx.EVT_TEXT, self.OnNameChanged, self.StepName)
    56         left_gridsizer.AddWindow(self.StepName, flag=wx.GROW)
    61         self.LeftGridSizer.AddWindow(self.StepName, flag=wx.GROW)
    57         
    62         
       
    63         # Create label for SFC step connectors
    58         connectors_label = wx.StaticText(self, label=_('Connectors:'))
    64         connectors_label = wx.StaticText(self, label=_('Connectors:'))
    59         left_gridsizer.AddWindow(connectors_label, flag=wx.GROW)
    65         self.LeftGridSizer.AddWindow(connectors_label, flag=wx.GROW)
    60         
    66         
    61         self.Input = wx.CheckBox(self, label=_("Input"))
    67         # Create check boxes for defining connectors available on SFC step
    62         self.Bind(wx.EVT_CHECKBOX, self.OnConnectorsChanged, self.Input)
    68         self.ConnectorsCheckBox = {}
    63         left_gridsizer.AddWindow(self.Input, flag=wx.GROW)
    69         for name, label in [("input", _("Input")),
       
    70                             ("output", _("Output")),
       
    71                             ("action", _("Action"))]:
       
    72             check_box = wx.CheckBox(self, label=label)
       
    73             self.Bind(wx.EVT_CHECKBOX, self.OnConnectorsChanged, check_box)
       
    74             self.LeftGridSizer.AddWindow(check_box, flag=wx.GROW)
       
    75             self.ConnectorsCheckBox[name] = check_box
    64         
    76         
    65         self.Output = wx.CheckBox(self, label=_("Output"))
    77         # Add preview panel and associated label to sizers
    66         self.Bind(wx.EVT_CHECKBOX, self.OnConnectorsChanged, self.Output)
    78         self.RightGridSizer.AddWindow(self.PreviewLabel, flag=wx.GROW)
    67         left_gridsizer.AddWindow(self.Output, flag=wx.GROW)
    79         self.RightGridSizer.AddWindow(self.Preview, flag=wx.GROW)
    68         
    80         
    69         self.Action = wx.CheckBox(self, label=_("Action"))
    81         # Add buttons sizer to sizers
    70         self.Bind(wx.EVT_CHECKBOX, self.OnConnectorsChanged, self.Action)
    82         self.MainSizer.AddSizer(self.ButtonSizer, border=20, 
    71         left_gridsizer.AddWindow(self.Action, flag=wx.GROW)
       
    72         
       
    73         right_gridsizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
       
    74         right_gridsizer.AddGrowableCol(0)
       
    75         right_gridsizer.AddGrowableRow(1)
       
    76         column_sizer.AddSizer(right_gridsizer, 1, border=5, 
       
    77               flag=wx.GROW|wx.LEFT)
       
    78         
       
    79         preview_label = wx.StaticText(self, label=_('Preview:'))
       
    80         right_gridsizer.AddWindow(preview_label, flag=wx.GROW)
       
    81         
       
    82         self.Preview = wx.Panel(self,
       
    83               style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER)
       
    84         self.Preview.SetBackgroundColour(wx.Colour(255,255,255))
       
    85         setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE)
       
    86         setattr(self.Preview, "RefreshStepModel", lambda x:None)
       
    87         setattr(self.Preview, "GetScaling", lambda:None)
       
    88         setattr(self.Preview, "IsOfType", controller.IsOfType)
       
    89         self.Preview.Bind(wx.EVT_PAINT, self.OnPaint)
       
    90         right_gridsizer.AddWindow(self.Preview, flag=wx.GROW)
       
    91         
       
    92         button_sizer = self.CreateButtonSizer(
       
    93                   wx.OK|wx.CANCEL|wx.CENTRE)
       
    94         self.Bind(wx.EVT_BUTTON, self.OnOK, 
       
    95                   button_sizer.GetAffirmativeButton())
       
    96         main_sizer.AddSizer(button_sizer, border=20, 
       
    97               flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
    83               flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
    98         
    84         
    99         self.SetSizer(main_sizer)
    85         # Save flag that indicates that step is initial
       
    86         self.Initial = initial
   100         
    87         
   101         self.Step = None
    88         # Step name text control is default control having keyboard focus
   102         self.Initial = initial
       
   103         self.MinStepSize = None
       
   104     
       
   105         self.PouNames = []
       
   106         self.Variables = []
       
   107         self.StepNames = []
       
   108         
       
   109         self.StepName.SetFocus()
    89         self.StepName.SetFocus()
   110     
    90     
   111     def SetPreviewFont(self, font):
       
   112         self.Preview.SetFont(font)
       
   113     
       
   114     def OnOK(self, event):
       
   115         message = None
       
   116         step_name = self.StepName.GetValue()
       
   117         if step_name == "":
       
   118             message = _("You must type a name!")
       
   119         elif not TestIdentifier(step_name):
       
   120             message = _("\"%s\" is not a valid identifier!") % step_name
       
   121         elif step_name.upper() in IEC_KEYWORDS:
       
   122             message = _("\"%s\" is a keyword. It can't be used!") % step_name
       
   123         elif step_name.upper() in self.PouNames:
       
   124             message = _("A POU named \"%s\" already exists!") % step_name
       
   125         elif step_name.upper() in self.Variables:
       
   126             message = _("A variable with \"%s\" as name already exists in this pou!") % step_name
       
   127         elif step_name.upper() in self.StepNames:
       
   128             message = _("\"%s\" step already exists!") % step_name
       
   129         if message is not None:
       
   130             dialog = wx.MessageDialog(self, message, _("Error"), wx.OK|wx.ICON_ERROR)
       
   131             dialog.ShowModal()
       
   132             dialog.Destroy()    
       
   133         else:
       
   134             self.EndModal(wx.ID_OK)
       
   135     
       
   136     def SetMinStepSize(self, size):
       
   137         self.MinStepSize = size
       
   138 
       
   139     def SetPouNames(self, pou_names):
       
   140         self.PouNames = [pou_name.upper() for pou_name in pou_names]
       
   141 
       
   142     def SetVariables(self, variables):
       
   143         self.Variables = [var["Name"].upper() for var in variables]
       
   144 
       
   145     def SetStepNames(self, step_names):
       
   146         self.StepNames = [step_name.upper() for step_name in step_names]
       
   147 
       
   148     def SetValues(self, values):
    91     def SetValues(self, values):
   149         value_name = values.get("name", None)
    92         """
   150         if value_name:
    93         Set default block parameters
   151             self.StepName.SetValue(value_name)
    94         @param values: Block parameters values
   152         else:
    95         """
   153             self.StepName.SetValue("")
    96         # For each parameters defined, set corresponding control value
   154         self.Input.SetValue(values.get("input", False))
    97         for name, value in values.items():
   155         self.Output.SetValue(values.get("output", False))
    98             
   156         self.Action.SetValue(values.get("action", False))
    99             # Parameter is step name
       
   100             if name == "name":
       
   101                 self.StepName.ChangeValue(value)
       
   102         
       
   103             # Set value of other controls
       
   104             else:
       
   105                 control = self.ConnectorsCheckBox.get(name, None)
       
   106                 if control is not None:
       
   107                     control.SetValue(value)
       
   108         
       
   109         # Refresh preview panel
   157         self.RefreshPreview()
   110         self.RefreshPreview()
   158         
   111         
   159     def GetValues(self):
   112     def GetValues(self):
   160         values = {}
   113         """
   161         values["name"] = self.StepName.GetValue()
   114         Return step parameters defined in dialog
   162         values["input"] = self.Input.IsChecked()
   115         @return: {parameter_name: parameter_value,...}
   163         values["output"] = self.Output.IsChecked()
   116         """
   164         values["action"] = self.Action.IsChecked()
   117         values = {"name": self.StepName.GetValue()}
   165         values["width"], values["height"] = self.Step.GetSize()
   118         values.update({
       
   119             name: control.IsChecked()
       
   120             for name, control in self.ConnectorsCheckBox.iteritems()})
       
   121         values["width"], values["height"] = self.Element.GetSize()
   166         return values
   122         return values
   167     
   123     
       
   124     def OnOK(self, event):
       
   125         """
       
   126         Called when dialog OK button is pressed
       
   127         Test if step name defined is valid
       
   128         @param event: wx.Event from OK button
       
   129         """
       
   130         message = None
       
   131         
       
   132         # Get step name typed by user
       
   133         step_name = self.StepName.GetValue()
       
   134         
       
   135         # Test that a name have been defined
       
   136         if step_name == "":
       
   137             message = _("Form isn't complete. Name must be filled!")
       
   138         
       
   139         # If an error have been identify, show error message dialog
       
   140         if message is not None:
       
   141             self.ShowErrorMessage(message)
       
   142         
       
   143         # Test step name validity
       
   144         elif self.TestElementName(step_name):
       
   145             # Call BlockPreviewDialog function
       
   146             BlockPreviewDialog.OnOK(self, event)
       
   147     
   168     def OnConnectorsChanged(self, event):
   148     def OnConnectorsChanged(self, event):
       
   149         """
       
   150         Called when a step connector value changed
       
   151         @param event: wx.CheckBoxEvent
       
   152         """
   169         self.RefreshPreview()
   153         self.RefreshPreview()
   170         event.Skip()
   154         event.Skip()
   171 
   155 
   172     def OnNameChanged(self, event):
   156     def OnNameChanged(self, event):
       
   157         """
       
   158         Called when step name value changed
       
   159         @param event: wx.TextEvent
       
   160         """
   173         self.RefreshPreview()
   161         self.RefreshPreview()
   174         event.Skip()
   162         event.Skip()
   175     
   163     
   176     def RefreshPreview(self):
   164     def RefreshPreview(self):
   177         dc = wx.ClientDC(self.Preview)
   165         """
   178         dc.SetFont(self.Preview.GetFont())
   166         Refresh preview panel of graphic element
   179         dc.Clear()
   167         Override BlockPreviewDialog function
   180         self.Step = SFC_Step(self.Preview, self.StepName.GetValue(), self.Initial)
   168         """
   181         if self.Input.IsChecked():
   169         # Set graphic element displayed, creating a SFC step element
   182             self.Step.AddInput()
   170         self.Element = SFC_Step(self.Preview, 
   183         else:
   171                                 self.StepName.GetValue(), 
   184             self.Step.RemoveInput()
   172                                 self.Initial)
   185         if self.Output.IsChecked():
   173         
   186             self.Step.AddOutput()
   174         # Update connectors of SFC step element according to check boxes value
   187         else:
   175         for name, control in self.ConnectorsCheckBox.iteritems():
   188             self.Step.RemoveOutput()
   176             if control.IsChecked():
   189         if self.Action.IsChecked():
   177                 getattr(self.Element, "Add" + name.capitalize())()
   190             self.Step.AddAction()    
   178             else:
   191         else:
   179                 getattr(self.Element, "Remove" + name.capitalize())()
   192             self.Step.RemoveAction()
   180         
   193         width, height = self.MinStepSize
   181         # Call BlockPreviewDialog function
   194         min_width, min_height = self.Step.GetMinSize()
   182         BlockPreviewDialog.RefreshPreview(self)
   195         width, height = max(min_width, width), max(min_height, height)
       
   196         self.Step.SetSize(width, height)
       
   197         clientsize = self.Preview.GetClientSize()
       
   198         x = (clientsize.width - width) / 2
       
   199         y = (clientsize.height - height) / 2
       
   200         self.Step.SetPosition(x, y)
       
   201         self.Step.Draw(dc)
       
   202 
       
   203     def OnPaint(self, event):
       
   204         self.RefreshPreview()
       
   205         event.Skip()