Laurent@814: # -*- coding: utf-8 -*-
Laurent@814: 
Laurent@814: #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
Laurent@814: #based on the plcopen standard. 
Laurent@814: #
Laurent@814: #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
Laurent@814: #
Laurent@814: #See COPYING file for copyrights details.
Laurent@814: #
Laurent@814: #This library is free software; you can redistribute it and/or
Laurent@814: #modify it under the terms of the GNU General Public
Laurent@814: #License as published by the Free Software Foundation; either
Laurent@814: #version 2.1 of the License, or (at your option) any later version.
Laurent@814: #
Laurent@814: #This library is distributed in the hope that it will be useful,
Laurent@814: #but WITHOUT ANY WARRANTY; without even the implied warranty of
Laurent@814: #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Laurent@814: #General Public License for more details.
Laurent@814: #
Laurent@814: #You should have received a copy of the GNU General Public
Laurent@814: #License along with this library; if not, write to the Free Software
Laurent@814: #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Laurent@814: 
Laurent@814: import wx
Laurent@814: 
Laurent@1252: from graphics.SFC_Objects import SFC_Transition
Laurent@1252: from BlockPreviewDialog import BlockPreviewDialog
Laurent@814: 
Laurent@814: #-------------------------------------------------------------------------------
Laurent@1252: #                        Set Transition Parameters Dialog
Laurent@814: #-------------------------------------------------------------------------------
Laurent@814: 
Laurent@1252: """
Laurent@1252: Class that implements a dialog for defining parameters of a transition graphic
Laurent@1252: element
Laurent@1252: """
Laurent@1252: 
Laurent@1252: class SFCTransitionDialog(BlockPreviewDialog):
Laurent@1252:     
Laurent@1252:     def __init__(self, parent, controller, tagname, connection=True):
Laurent@1252:         """
Laurent@1252:         Constructor
Laurent@1252:         @param parent: Parent wx.Window of dialog for modal
Laurent@1252:         @param controller: Reference to project controller
Laurent@1252:         @param tagname: Tagname of project POU edited
Laurent@1252:         @param connection: True if transition value can be defined by a
Laurent@1252:         connection (default: True)
Laurent@1252:         """
Laurent@1252:         BlockPreviewDialog.__init__(self, parent, controller, tagname,
Laurent@814:               size=wx.Size(350, 300), title=_('Edit transition'))
Laurent@814:         
Laurent@1252:         # Init common sizers
Laurent@1252:         self._init_sizers(2, 0, 8, None, 2, 1)
Laurent@1252:         
Laurent@1252:         # Create label for transition type
Laurent@814:         type_label = wx.StaticText(self, label=_('Type:'))
Laurent@1252:         self.LeftGridSizer.AddWindow(type_label, flag=wx.GROW)
Laurent@1252:         
Laurent@1252:         # Create combo box for selecting reference value
Laurent@1252:         reference = wx.ComboBox(self, style=wx.CB_READONLY)
Laurent@1252:         reference.Append("")
Laurent@1252:         for transition in controller.GetEditedElementTransitions(tagname):
Laurent@1252:             reference.Append(transition)
Laurent@1252:         self.Bind(wx.EVT_COMBOBOX, self.OnReferenceChanged, reference)
Laurent@1252:         
Laurent@1252:         # Create Text control for defining inline value
Laurent@1252:         inline = wx.TextCtrl(self)
Laurent@1252:         self.Bind(wx.EVT_TEXT, self.OnInlineChanged, inline)
Laurent@1252:         
Laurent@1252:         # Create radio buttons for selecting power rail type
Laurent@1252:         self.TypeRadioButtons = {}
Laurent@1252:         first = True
Laurent@1252:         for type, label, control in [('reference', _('Reference'), reference),
Laurent@1252:                                      ('inline', _('Inline'), inline),
Laurent@1252:                                      ('connection', _('Connection'), None)]:
Laurent@1252:             radio_button = wx.RadioButton(self, label=label, 
Laurent@1252:                   style=(wx.RB_GROUP if first else 0))
Laurent@1252:             radio_button.SetValue(first)
Laurent@1252:             self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, radio_button)
Laurent@1252:             self.LeftGridSizer.AddWindow(radio_button, flag=wx.GROW)
Laurent@1252:             if control is not None:
Laurent@1252:                 control.Enable(first)
Laurent@1252:                 self.LeftGridSizer.AddWindow(control, flag=wx.GROW)
Laurent@1252:             self.TypeRadioButtons[type] = (radio_button, control)
Laurent@1252:             first = False
Laurent@1252:         
Laurent@1252:         # Create label for transition priority
Laurent@814:         priority_label = wx.StaticText(self, label=_('Priority:'))
Laurent@1252:         self.LeftGridSizer.AddWindow(priority_label, flag=wx.GROW)
Laurent@1252:         
Laurent@1252:         # Create spin control for defining priority value
Laurent@814:         self.Priority = wx.SpinCtrl(self, min=0, style=wx.SP_ARROW_KEYS)
Laurent@814:         self.Bind(wx.EVT_TEXT, self.OnPriorityChanged, self.Priority)
Laurent@1252:         self.LeftGridSizer.AddWindow(self.Priority, flag=wx.GROW)
Laurent@1252:         
Laurent@1252:         # Add preview panel and associated label to sizers
Laurent@1252:         self.RightGridSizer.AddWindow(self.PreviewLabel, flag=wx.GROW)
Laurent@1252:         self.RightGridSizer.AddWindow(self.Preview, flag=wx.GROW)
Laurent@1252:         
Laurent@1252:         # Add buttons sizer to sizers
Laurent@1252:         self.MainSizer.AddSizer(self.ButtonSizer, border=20, 
Laurent@814:               flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
Laurent@814:         
Laurent@1252:         # Reference radio button is default control having keyboard focus
Laurent@1252:         self.TypeRadioButtons["reference"][0].SetFocus()
Laurent@1252:     
Laurent@1252:     def GetTransitionType(self):
Laurent@1252:         """
Laurent@1252:         Return type selected for SFC transition and associated value
Laurent@1252:         @return: Type selected and associated value (None if no value)
Laurent@1252:         """
Laurent@1252:         # Go through radio buttons and return type and value associated to the
Laurent@1252:         # one that is selected
Laurent@1252:         for type, (radio, control) in self.TypeRadioButtons.iteritems():
Laurent@1252:             if radio.GetValue():
Laurent@1252:                 if isinstance(control, wx.ComboBox):
Laurent@1252:                     return type, control.GetStringSelection()
Laurent@1252:                 elif isinstance(control, wx.TextCtrl):
Laurent@1252:                     return type, control.GetValue()
Laurent@1252:                 else:
Laurent@1252:                     return type, None
Laurent@1252:         return None, None
Laurent@1252:     
Laurent@1252:     def SetValues(self, values):
Laurent@1252:         """
Laurent@1252:         Set default SFC transition parameters
Laurent@1252:         @param values: Transition parameters values
Laurent@1252:         """
Laurent@1252:         # Extract transition value according to type
Laurent@1252:         type_value = values.get("value", None)
Laurent@1252:         
Laurent@1252:         # For each parameters defined, set corresponding control value
Laurent@1252:         for name, value in values.items():
Laurent@1252:             
Laurent@1252:             # Parameter is SFC transition priority
Laurent@1252:             if name == "priority":
Laurent@1252:                 self.Priority.SetValue(values["priority"])
Laurent@1252:             
Laurent@1252:             # Parameter is SFC transition type
Laurent@1252:             elif name == "type":
Laurent@1252:                 for type, (radio, control) in self.TypeRadioButtons.iteritems():
Laurent@1252:                     radio.SetValue(type == value)
Laurent@1252:                     if control is not None:
Laurent@1252:                         # Enable associated control to type and set value
Laurent@1252:                         control.Enable(type == value)
Laurent@1252:                         if type == value:
Laurent@1252:                             if isinstance(control, wx.ComboBox):
Laurent@1252:                                 control.SetStringSelection(type_value)
Laurent@1252:                             elif isinstance(control, wx.TextCtrl):
Laurent@1252:                                 control.ChangeValue(type_value)
Laurent@1252:         
Laurent@1252:         # Refresh preview panel
Laurent@1252:         self.RefreshPreview()
Laurent@1252:         
Laurent@1252:     def GetValues(self):
Laurent@1252:         """
Laurent@1252:         Return SFC transition parameters defined in dialog
Laurent@1252:         @return: {parameter_name: parameter_value,...}
Laurent@1252:         """
Laurent@1252:         values = {"priority" : self.Priority.GetValue()}
Laurent@1252:         values["type"], values["value"] = self.GetTransitionType()
Laurent@1252:         values["width"], values["height"] = self.Element.GetSize()
Laurent@1252:         return values
Laurent@1252:     
Laurent@1252:     def OnOK(self, event):
Laurent@1252:         """
Laurent@1252:         Called when dialog OK button is pressed
Laurent@1252:         Test if parameters defined are valid
Laurent@1252:         @param event: wx.Event from OK button
Laurent@1252:         """
Laurent@1252:         message = None
Laurent@1252:         
Laurent@1252:         # Get transition type and value associated
Laurent@1252:         type, value = self.GetTransitionType()
Laurent@1252:         
Laurent@1252:         # Test that value associated to type is defined
Laurent@1252:         if type != "connection" and value == "":
Laurent@1252:             message = _("Form isn't complete. %s must be filled!") % type
Laurent@1252:         
Laurent@1252:         # Show error message if an error is detected
Laurent@1252:         if message is not None:
Laurent@1252:             self.ShowErrorMessage(message)
Laurent@1252:         
Laurent@1252:         else:
Laurent@1252:             # Call BlockPreviewDialog function
Laurent@1252:             BlockPreviewDialog.OnOK(self, event)
Laurent@1252: 
Laurent@1252:     def OnTypeChanged(self, event):
Laurent@1252:         """
Laurent@1252:         Called when transition type changed
Laurent@1252:         @param event: wx.RadioButtonEvent
Laurent@1252:         """
Laurent@1252:         # Refresh sensibility of control associated to transition types
Laurent@1252:         for type, (radio, control) in self.TypeRadioButtons.iteritems():
Laurent@1252:             if control is not None:
Laurent@1252:                 control.Enable(radio.GetValue())
Laurent@1252:         
Laurent@1252:         # Refresh preview panel
Laurent@1252:         self.RefreshPreview()
Laurent@1252:         event.Skip()
Laurent@1252: 
Laurent@1252:     def OnReferenceChanged(self, event):
Laurent@1252:         """
Laurent@1252:         Called when SFC transition reference value changed
Laurent@1252:         @param event: wx.ComboBoxEvent
Laurent@1252:         """
Laurent@1252:         self.RefreshPreview()
Laurent@1252:         event.Skip()
Laurent@1252: 
Laurent@1252:     def OnInlineChanged(self, event):
Laurent@1252:         """
Laurent@1252:         Called when SFC transition inline value changed
Laurent@1252:         @param event: wx.TextEvent
Laurent@1252:         """
Laurent@1252:         self.RefreshPreview()
Laurent@1252:         event.Skip()
Laurent@1252: 
Laurent@1252:     def OnPriorityChanged(self, event):
Laurent@1252:         """
Laurent@1252:         Called when block inputs number changed
Laurent@1252:         @param event: wx.SpinEvent
Laurent@1252:         """
Laurent@1252:         self.RefreshPreview()
Laurent@1252:         event.Skip()
Laurent@1252: 
Laurent@1252:     def RefreshPreview(self):
Laurent@1252:         """
Laurent@1252:         Refresh preview panel of graphic element
Laurent@1252:         Override BlockPreviewDialog function
Laurent@1252:         """
Laurent@1252:         # Set graphic element displayed, creating a SFC transition
Laurent@814:         self.Element = SFC_Transition(self.Preview)
Laurent@1252:         self.Element.SetType(*self.GetTransitionType())
Laurent@1252:         self.Element.SetPriority(self.Priority.GetValue())
Laurent@1252:         
Laurent@1252:         # Call BlockPreviewDialog function
Laurent@1252:         BlockPreviewDialog.RefreshPreview(self)