dialogs/ConnectionDialog.py
changeset 1245 d34ba528346b
parent 856 b64e436f000e
child 1246 101625efb1c1
equal deleted inserted replaced
1244:336d515096b1 1245:d34ba528346b
    22 #License along with this library; if not, write to the Free Software
    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
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    24 
    24 
    25 import wx
    25 import wx
    26 
    26 
    27 from graphics import *
    27 from graphics.GraphicCommons import CONNECTOR, CONTINUATION
       
    28 from graphics.FBD_Objects import FBD_Connector
       
    29 from BlockPreviewDialog import BlockPreviewDialog
    28 
    30 
    29 #-------------------------------------------------------------------------------
    31 #-------------------------------------------------------------------------------
    30 #                          Create New Connection Dialog
    32 #                       Set Connection Parameters Dialog
    31 #-------------------------------------------------------------------------------
    33 #-------------------------------------------------------------------------------
    32 
    34 
    33 class ConnectionDialog(wx.Dialog):
    35 class ConnectionDialog(BlockPreviewDialog):
    34     
    36     
    35     def __init__(self, parent, controller, apply_button=False):
    37     def __init__(self, parent, controller, tagname, apply_button=False):
    36         wx.Dialog.__init__(self, parent,
    38         """
       
    39         Constructor
       
    40         @param parent: Parent wx.Window of dialog for modal
       
    41         @param controller: Reference to project controller
       
    42         @param tagname: Tagname of project POU edited
       
    43         @param apply_button: Enable button for applying connector modification
       
    44         to all connector having the same name in POU (default: False)
       
    45         """
       
    46         BlockPreviewDialog.__init__(self, parent, controller, tagname, 
    37               size=wx.Size(350, 220), title=_('Connection Properties'))
    47               size=wx.Size(350, 220), title=_('Connection Properties'))
    38         
    48         
       
    49         # Create dialog main sizer
    39         main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
    50         main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
    40         main_sizer.AddGrowableCol(0)
    51         main_sizer.AddGrowableCol(0)
    41         main_sizer.AddGrowableRow(0)
    52         main_sizer.AddGrowableRow(0)
    42         
    53         
       
    54         # Create a sizer for dividing FBD connection parameters in two columns
    43         column_sizer = wx.BoxSizer(wx.HORIZONTAL)
    55         column_sizer = wx.BoxSizer(wx.HORIZONTAL)
    44         main_sizer.AddSizer(column_sizer, border=20, 
    56         main_sizer.AddSizer(column_sizer, border=20, 
    45               flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
    57               flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
    46         
    58         
       
    59         # Create a sizer for left column
    47         left_gridsizer = wx.FlexGridSizer(cols=1, hgap=0, rows=5, vgap=5)
    60         left_gridsizer = wx.FlexGridSizer(cols=1, hgap=0, rows=5, vgap=5)
    48         left_gridsizer.AddGrowableCol(0)
    61         left_gridsizer.AddGrowableCol(0)
    49         column_sizer.AddSizer(left_gridsizer, 1, border=5, 
    62         column_sizer.AddSizer(left_gridsizer, 1, border=5, 
    50               flag=wx.GROW|wx.RIGHT)
    63               flag=wx.GROW|wx.RIGHT)
    51         
    64         
       
    65         # Create label for connection type
    52         type_label = wx.StaticText(self, label=_('Type:'))
    66         type_label = wx.StaticText(self, label=_('Type:'))
    53         left_gridsizer.AddWindow(type_label, flag=wx.GROW)
    67         left_gridsizer.AddWindow(type_label, flag=wx.GROW)
    54         
    68         
    55         self.ConnectorRadioButton = wx.RadioButton(self, 
    69         # Create radio buttons for selecting connection type
    56               label=_('Connector'), style=wx.RB_GROUP)
    70         self.ConnectionRadioButtons = {}
    57         self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, self.ConnectorRadioButton)
    71         first = True
    58         self.ConnectorRadioButton.SetValue(True)
    72         for type, label in [(CONNECTOR, _('Connector')),
    59         left_gridsizer.AddWindow(self.ConnectorRadioButton, flag=wx.GROW)
    73                             (CONTINUATION, _('Continuation'))]:
    60         
    74             radio_button = wx.RadioButton(self, label=label, 
    61         self.ConnectionRadioButton = wx.RadioButton(self, label=_('Continuation'))
    75                   style=(wx.RB_GROUP if first else wx.RB_SINGLE))
    62         self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, self.ConnectionRadioButton)
    76             radio_button.SetValue(first)
    63         left_gridsizer.AddWindow(self.ConnectionRadioButton, flag=wx.GROW)
    77             self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, radio_button)
    64         
    78             left_gridsizer.AddWindow(radio_button, flag=wx.GROW)
       
    79             self.ConnectionRadioButtons[type] = radio_button
       
    80             first = False
       
    81         
       
    82         # Create label for connection name
    65         name_label = wx.StaticText(self, label=_('Name:'))
    83         name_label = wx.StaticText(self, label=_('Name:'))
    66         left_gridsizer.AddWindow(name_label, flag=wx.GROW)
    84         left_gridsizer.AddWindow(name_label, flag=wx.GROW)
    67         
    85         
       
    86         # Create text control for defining connection name
    68         self.ConnectionName = wx.TextCtrl(self)
    87         self.ConnectionName = wx.TextCtrl(self)
    69         self.Bind(wx.EVT_TEXT, self.OnNameChanged, self.ConnectionName)
    88         self.Bind(wx.EVT_TEXT, self.OnNameChanged, self.ConnectionName)
    70         left_gridsizer.AddWindow(self.ConnectionName, flag=wx.GROW)
    89         left_gridsizer.AddWindow(self.ConnectionName, flag=wx.GROW)
    71         
    90         
       
    91         # Create a sizer for right column
    72         right_gridsizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
    92         right_gridsizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
    73         right_gridsizer.AddGrowableCol(0)
    93         right_gridsizer.AddGrowableCol(0)
    74         right_gridsizer.AddGrowableRow(1)
    94         right_gridsizer.AddGrowableRow(1)
    75         column_sizer.AddSizer(right_gridsizer, 1, border=5, 
    95         column_sizer.AddSizer(right_gridsizer, 1, border=5, 
    76               flag=wx.GROW|wx.LEFT)
    96               flag=wx.GROW|wx.LEFT)
    77         
    97         
    78         preview_label = wx.StaticText(self, label=_('Preview:'))
    98         # Add preview panel and associated label to sizers
    79         right_gridsizer.AddWindow(preview_label, flag=wx.GROW)
    99         right_gridsizer.AddWindow(self.PreviewLabel, flag=wx.GROW)
    80         
       
    81         self.Preview = wx.Panel(self, 
       
    82               style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER)
       
    83         self.Preview.SetBackgroundColour(wx.Colour(255,255,255))
       
    84         setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE)
       
    85         setattr(self.Preview, "GetScaling", lambda:None)
       
    86         setattr(self.Preview, "IsOfType", controller.IsOfType)
       
    87         self.Preview.Bind(wx.EVT_PAINT, self.OnPaint)
       
    88         right_gridsizer.AddWindow(self.Preview, flag=wx.GROW)
   100         right_gridsizer.AddWindow(self.Preview, flag=wx.GROW)
    89         
   101         
    90         button_sizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
   102         # Add buttons sizer to sizers
    91         self.Bind(wx.EVT_BUTTON, self.OnOK, button_sizer.GetAffirmativeButton())
   103         main_sizer.AddSizer(self.ButtonSizer, border=20, 
    92         main_sizer.AddSizer(button_sizer, border=20, 
       
    93               flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
   104               flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
    94         
   105         
       
   106         # Add button for applying connection name modification to all connection
       
   107         # of POU
    95         if apply_button:
   108         if apply_button:
    96             self.ApplyToAllButton = wx.Button(self, label=_("Propagate Name"))
   109             self.ApplyToAllButton = wx.Button(self, label=_("Propagate Name"))
    97             self.ApplyToAllButton.SetToolTipString(
   110             self.ApplyToAllButton.SetToolTipString(
    98                 _("Apply name modification to all continuations with the same name"))
   111                 _("Apply name modification to all continuations with the same name"))
    99             self.Bind(wx.EVT_BUTTON, self.OnApplyToAll, self.ApplyToAllButton)
   112             self.Bind(wx.EVT_BUTTON, self.OnApplyToAll, self.ApplyToAllButton)
   100             button_sizer.AddWindow(self.ApplyToAllButton)
   113             self.ButtonSizer.AddWindow(self.ApplyToAllButton, border=10,
       
   114                     flag=wx.LEFT)
       
   115         else:
       
   116             self.ConnectionName.ChangeValue(
       
   117                 controller.GenerateNewName(
       
   118                         tagname, None, "Connection%d", 0))
   101         
   119         
   102         self.SetSizer(main_sizer)
   120         self.SetSizer(main_sizer)
   103         
   121         
   104         self.Connection = None
   122         # Connector radio button is default control having keyboard focus
   105         self.MinConnectionSize = None
   123         self.ConnectionRadioButtons[CONNECTOR].SetFocus()
   106         
       
   107         self.PouNames = []
       
   108         self.PouElementNames = []
       
   109         
       
   110         self.ConnectorRadioButton.SetFocus()
       
   111     
       
   112     def SetPreviewFont(self, font):
       
   113         self.Preview.SetFont(font)
       
   114     
       
   115     def SetMinConnectionSize(self, size):
       
   116         self.MinConnectionSize = size
       
   117     
   124     
   118     def SetValues(self, values):
   125     def SetValues(self, values):
       
   126         """
       
   127         Set default connection parameters
       
   128         @param values: Connection parameters values
       
   129         """
       
   130         # For each parameters defined, set corresponding control value
   119         for name, value in values.items():
   131         for name, value in values.items():
       
   132             
       
   133             # Parameter is connection type
   120             if name == "type":
   134             if name == "type":
   121                 if value == CONNECTOR:
   135                 self.ConnectionRadioButtons[value].SetValue(True)
   122                     self.ConnectorRadioButton.SetValue(True)
   136             
   123                 elif value == CONTINUATION:
   137             # Parameter is connection name
   124                     self.ConnectionRadioButton.SetValue(True)
       
   125             elif name == "name":
   138             elif name == "name":
   126                 self.ConnectionName.SetValue(value)
   139                 self.ConnectionName.SetValue(value)
       
   140         
       
   141         # Refresh preview panel
   127         self.RefreshPreview()
   142         self.RefreshPreview()
   128     
   143     
   129     def GetValues(self):
   144     def GetValues(self):
   130         values = {}
   145         """
   131         if self.ConnectorRadioButton.GetValue():
   146         Return connection parameters defined in dialog
   132             values["type"] = CONNECTOR
   147         @return: {parameter_name: parameter_value,...}
   133         else:
   148         """
   134             values["type"] = CONTINUATION
   149         values = {
   135         values["name"] = self.ConnectionName.GetValue()
   150             "type": (CONNECTOR 
   136         values["width"], values["height"] = self.Connection.GetSize()
   151                      if self.ConnectionRadioButtons[CONNECTOR].GetValue()
       
   152                      else CONTINUATION),
       
   153             "name": self.ConnectionName.GetValue()}
       
   154         values["width"], values["height"] = self.Element.GetSize()
   137         return values
   155         return values
   138 
   156 
   139     def SetPouNames(self, pou_names):
   157     def TestConnectionName(self):
   140         self.PouNames = [pou_name.upper() for pou_name in pou_names]
   158         """
   141         
   159         Test that connection name is valid
   142     def SetPouElementNames(self, element_names):
   160         @return: True if connection name is valid
   143         self.PouElementNames = [element_name.upper() for element_name in element_names]
   161         """
   144     
       
   145     def TestName(self):
       
   146         message = None
   162         message = None
       
   163         
       
   164         # Get connection name typed by user
   147         connection_name = self.ConnectionName.GetValue()
   165         connection_name = self.ConnectionName.GetValue()
       
   166         
       
   167         # Test that a name have been defined
   148         if connection_name == "":
   168         if connection_name == "":
   149             message = _("Form isn't complete. Name must be filled!")
   169             message = _("Form isn't complete. Name must be filled!")
   150         elif not TestIdentifier(connection_name):
   170         
   151             message = _("\"%s\" is not a valid identifier!") % connection_name
   171         # If an error have been identify, show error message dialog
   152         elif connection_name.upper() in IEC_KEYWORDS:
       
   153             message = _("\"%s\" is a keyword. It can't be used!") % connection_name
       
   154         elif connection_name.upper() in self.PouNames:
       
   155             message = _("\"%s\" pou already exists!") % connection_name
       
   156         elif connection_name.upper() in self.PouElementNames:
       
   157             message = _("\"%s\" element for this pou already exists!") % connection_name
       
   158         if message is not None:
   172         if message is not None:
   159             dialog = wx.MessageDialog(self, message, _("Error"), wx.OK|wx.ICON_ERROR)
   173             self.ShowErrorMessage(message)
   160             dialog.ShowModal()
   174             # Test failed
   161             dialog.Destroy()
       
   162             return False
   175             return False
   163         return True
   176         
       
   177         # Return result of element name test
       
   178         return self.TestElementName(connection_name)
   164         
   179         
   165     def OnOK(self, event):
   180     def OnOK(self, event):
   166         if self.TestName():
   181         """
       
   182         Called when dialog OK button is pressed
       
   183         Test if connection name is valid
       
   184         @param event: wx.Event from OK button
       
   185         """
       
   186         # Close dialog if connection name is valid
       
   187         if self.TestConnectionName():
   167             self.EndModal(wx.ID_OK)
   188             self.EndModal(wx.ID_OK)
   168 
   189 
   169     def OnApplyToAll(self, event):
   190     def OnApplyToAll(self, event):
   170         if self.TestName():
   191         """
       
   192         Called when Apply To All button is pressed
       
   193         Test if connection name is valid
       
   194         @param event: wx.Event from OK button
       
   195         """
       
   196         # Close dialog if connection name is valid
       
   197         if self.TestConnectionName():
   171             self.EndModal(wx.ID_YESTOALL)
   198             self.EndModal(wx.ID_YESTOALL)
   172 
   199 
   173     def OnTypeChanged(self, event):
   200     def OnTypeChanged(self, event):
       
   201         """
       
   202         Called when connection type changed
       
   203         @param event: wx.RadioButtonEvent
       
   204         """
   174         self.RefreshPreview()
   205         self.RefreshPreview()
   175         event.Skip()
   206         event.Skip()
   176 
   207 
   177     def OnNameChanged(self, event):
   208     def OnNameChanged(self, event):
       
   209         """
       
   210         Called when connection name value changed
       
   211         @param event: wx.TextEvent
       
   212         """
   178         self.RefreshPreview()
   213         self.RefreshPreview()
   179         event.Skip()
   214         event.Skip()
   180         
   215         
   181     def RefreshPreview(self):
   216     def RefreshPreview(self):
   182         dc = wx.ClientDC(self.Preview)
   217         """
   183         dc.SetFont(self.Preview.GetFont())
   218         Refresh preview panel of graphic element
   184         dc.Clear()
   219         Override BlockPreviewDialog function
   185         if self.ConnectorRadioButton.GetValue():
   220         """
   186             self.Connection = FBD_Connector(self.Preview, CONNECTOR, self.ConnectionName.GetValue())
   221         # Set graphic element displayed, creating a FBD connection element
   187         else:
   222         self.Element = FBD_Connector(self.Preview, 
   188             self.Connection = FBD_Connector(self.Preview, CONTINUATION, self.ConnectionName.GetValue())
   223                 (CONNECTOR
   189         width, height = self.MinConnectionSize
   224                  if self.ConnectionRadioButtons[CONNECTOR].GetValue()
   190         min_width, min_height = self.Connection.GetMinSize()
   225                  else CONTINUATION),
   191         width, height = max(min_width, width), max(min_height, height)
   226                 self.ConnectionName.GetValue())
   192         self.Connection.SetSize(width, height)
   227         
   193         clientsize = self.Preview.GetClientSize()
   228         # Call BlockPreviewDialog function
   194         x = (clientsize.width - width) / 2
   229         BlockPreviewDialog.RefreshPreview(self)
   195         y = (clientsize.height - height) / 2
   230         
   196         self.Connection.SetPosition(x, y)
       
   197         self.Connection.Draw(dc)
       
   198 
       
   199     def OnPaint(self, event):
       
   200         self.RefreshPreview()
       
   201         event.Skip()