Laurent@814: #!/usr/bin/env python Laurent@814: # -*- coding: utf-8 -*- Laurent@814: andrej@1571: # This file is part of Beremiz, a Integrated Development Environment for andrej@1571: # programming IEC 61131-3 automates supporting plcopen standard and CanFestival. Laurent@814: # andrej@1571: # Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD andrej@1696: # Copyright (C) 2017: Andrey Skvortsov Laurent@814: # andrej@1571: # See COPYING file for copyrights details. Laurent@814: # andrej@1571: # This program is free software; you can redistribute it and/or andrej@1571: # modify it under the terms of the GNU General Public License andrej@1571: # as published by the Free Software Foundation; either version 2 andrej@1571: # of the License, or (at your option) any later version. Laurent@814: # andrej@1571: # This program is distributed in the hope that it will be useful, andrej@1571: # but WITHOUT ANY WARRANTY; without even the implied warranty of andrej@1571: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the andrej@1571: # GNU General Public License for more details. Laurent@814: # andrej@1571: # You should have received a copy of the GNU General Public License andrej@1571: # along with this program; if not, write to the Free Software andrej@1571: # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Laurent@814: andrej@1853: andrej@1853: from __future__ import absolute_import Laurent@814: import wx Laurent@814: Laurent@1246: from graphics.GraphicCommons import CONTACT_NORMAL, CONTACT_REVERSE, \ Laurent@1246: CONTACT_RISING, CONTACT_FALLING, COIL_NORMAL, COIL_REVERSE, COIL_SET, \ Laurent@1246: COIL_RESET, COIL_RISING, COIL_FALLING Laurent@1246: from graphics.LD_Objects import LD_Contact, LD_Coil andrej@1853: from dialogs.BlockPreviewDialog import BlockPreviewDialog Laurent@814: andrej@1782: # ------------------------------------------------------------------------------- Laurent@1246: # Set Ladder Element Parmeters Dialog andrej@1782: # ------------------------------------------------------------------------------- Laurent@814: Laurent@1246: Laurent@1246: class LDElementDialog(BlockPreviewDialog): andrej@1736: """ andrej@1736: Class that implements a dialog for defining parameters of a LD contact or coil andrej@1736: graphic element andrej@1736: """ andrej@1730: Laurent@1246: def __init__(self, parent, controller, tagname, type): Laurent@1246: """ Laurent@1246: Constructor Laurent@1246: @param parent: Parent wx.Window of dialog for modal Laurent@1246: @param controller: Reference to project controller Laurent@1246: @param tagname: Tagname of project POU edited Laurent@1246: @param type: Type of LD element ('contact or 'coil') Laurent@1246: """ andrej@1730: BlockPreviewDialog.__init__(self, parent, controller, tagname, andrej@1768: title=(_("Edit Contact Values") andrej@1768: if type == "contact" andrej@1768: else _("Edit Coil Values"))) andrej@1730: Laurent@1250: # Init common sizers andrej@1768: self._init_sizers(2, 0, (7 if type == "contact" else 9), andrej@1768: None, 2, 1) andrej@1730: Laurent@1246: # Create label for LD element modifier Laurent@814: modifier_label = wx.StaticText(self, label=_('Modifier:')) andrej@1730: self.LeftGridSizer.AddWindow(modifier_label, border=5, andrej@1768: flag=wx.GROW | wx.BOTTOM) andrej@1730: Laurent@1246: # Create radio buttons for selecting LD element modifier Laurent@1246: self.ModifierRadioButtons = {} Laurent@1246: first = True andrej@1730: element_modifiers = ([CONTACT_NORMAL, CONTACT_REVERSE, Laurent@1246: CONTACT_RISING, CONTACT_FALLING] Laurent@1246: if type == "contact" Laurent@1246: else [COIL_NORMAL, COIL_REVERSE, COIL_SET, Laurent@1246: COIL_RESET, COIL_RISING, COIL_FALLING]) andrej@1767: modifiers_label = \ andrej@1767: [_("Normal"), _("Negated")] + \ andrej@1767: ([_("Set"), _("Reset")] if type == "coil" else []) + \ andrej@1767: [_("Rising Edge"), _("Falling Edge")] andrej@1730: Laurent@1246: for modifier, label in zip(element_modifiers, modifiers_label): andrej@1730: radio_button = wx.RadioButton(self, label=label, andrej@1768: style=(wx.RB_GROUP if first else 0)) Laurent@1246: radio_button.SetValue(first) Laurent@1246: self.Bind(wx.EVT_RADIOBUTTON, self.OnModifierChanged, radio_button) Laurent@1250: self.LeftGridSizer.AddWindow(radio_button, flag=wx.GROW) Laurent@1246: self.ModifierRadioButtons[modifier] = radio_button Laurent@1246: first = False andrej@1730: Laurent@1246: # Create label for LD element variable Laurent@1246: element_variable_label = wx.StaticText(self, label=_('Variable:')) Laurent@1250: self.LeftGridSizer.AddWindow(element_variable_label, border=5, andrej@1768: flag=wx.GROW | wx.TOP) andrej@1730: Laurent@1246: # Create a combo box for defining LD element variable Laurent@1370: self.ElementVariable = wx.ComboBox(self, style=wx.CB_SORT) andrej@1730: self.Bind(wx.EVT_COMBOBOX, self.OnVariableChanged, Laurent@1246: self.ElementVariable) andrej@1730: self.Bind(wx.EVT_TEXT, self.OnVariableChanged, andrej@1730: self.ElementVariable) Laurent@1250: self.LeftGridSizer.AddWindow(self.ElementVariable, border=5, andrej@1768: flag=wx.GROW | wx.TOP) andrej@1730: Laurent@1246: # Add preview panel and associated label to sizers Laurent@1250: self.RightGridSizer.AddWindow(self.PreviewLabel, flag=wx.GROW) Laurent@1250: self.RightGridSizer.AddWindow(self.Preview, flag=wx.GROW) andrej@1730: Laurent@1246: # Add buttons sizer to sizers andrej@1730: self.MainSizer.AddSizer(self.ButtonSizer, border=20, andrej@1768: flag=wx.ALIGN_RIGHT | wx.BOTTOM | wx.LEFT | wx.RIGHT) andrej@1730: Laurent@1246: # Save LD element class Laurent@1246: self.ElementClass = (LD_Contact if type == "contact" else LD_Coil) andrej@1730: Laurent@1246: # Extract list of variables defined in POU Laurent@1246: self.RefreshVariableList() andrej@1730: Laurent@1246: # Set values in ElementVariable Laurent@1246: for name, (var_type, value_type) in self.VariableList.iteritems(): Laurent@1246: # Only select BOOL variable and avoid input for coil Laurent@1246: if (type == "contact" or var_type != "Input") and \ Laurent@1246: value_type == "BOOL": Laurent@1246: self.ElementVariable.Append(name) andrej@1730: andrej@1696: self.Fit() Laurent@1246: # Normal radio button is default control having keyboard focus Laurent@1246: self.ModifierRadioButtons[element_modifiers[0]].SetFocus() andrej@1730: Laurent@1246: def GetElementModifier(self): Laurent@1246: """ Laurent@1246: Return modifier selected for LD element Laurent@1246: @return: Modifier selected (None if not found) Laurent@1246: """ Laurent@1246: # Go through radio buttons and return modifier associated to the one Laurent@1246: # that is selected Laurent@1246: for modifier, control in self.ModifierRadioButtons.iteritems(): Laurent@1246: if control.GetValue(): Laurent@1246: return modifier Laurent@1246: return None Laurent@814: Laurent@814: def SetValues(self, values): Laurent@1246: """ Laurent@1246: Set default LD element parameters Laurent@1252: @param values: LD element parameters values Laurent@1246: """ Laurent@1246: # For each parameters defined, set corresponding control value Laurent@814: for name, value in values.items(): andrej@1730: Laurent@1246: # Parameter is LD element variable Laurent@1246: if name == "variable": Laurent@1370: self.ElementVariable.SetValue(value) andrej@1730: Laurent@1246: # Set value of other controls Laurent@1246: elif name == "modifier": Laurent@1246: self.ModifierRadioButtons[value].SetValue(True) andrej@1730: Laurent@1246: # Refresh preview panel Edouard@2591: self.RefreshPreview() Laurent@814: Laurent@814: def GetValues(self): Laurent@1246: """ Laurent@1246: Return LD element parameters defined in dialog Laurent@1246: @return: {parameter_name: parameter_value,...} Laurent@1246: """ Laurent@1246: values = { Laurent@1246: "variable": self.ElementVariable.GetValue(), Laurent@1246: "modifier": self.GetElementModifier()} Laurent@814: values["width"], values["height"] = self.Element.GetSize() Laurent@814: return values Laurent@814: Laurent@1246: def OnModifierChanged(self, event): Laurent@1246: """ Laurent@1246: Called when LD element modifier changed Laurent@1246: @param event: wx.RadioButtonEvent Laurent@1246: """ Edouard@2591: self.RefreshPreview() Laurent@814: event.Skip() Laurent@814: Laurent@1246: def OnVariableChanged(self, event): Laurent@1246: """ Laurent@1246: Called when LD element associated variable changed Laurent@1246: @param event: wx.ComboBoxEvent Laurent@1246: """ Edouard@2591: self.RefreshPreview() Laurent@814: event.Skip() Laurent@814: Edouard@2587: def DrawPreview(self): Laurent@1246: """ Laurent@1246: Refresh preview panel of graphic element Laurent@1246: Override BlockPreviewDialog function Laurent@1246: """ andrej@1698: value = self.ElementVariable.GetValue() andrej@1730: Laurent@1246: # Set graphic element displayed, creating a LD element Laurent@1246: self.Element = self.ElementClass( andrej@1878: self.Preview, andrej@1878: self.GetElementModifier(), andrej@1878: value) andrej@1698: andrej@1698: button = self.ButtonSizer.GetAffirmativeButton() andrej@1698: button.Enable(value != "") andrej@1730: Laurent@1246: # Call BlockPreviewDialog function Edouard@2587: BlockPreviewDialog.DrawPreview(self) andrej@1730: andrej@1698: def OnOK(self, event): andrej@1698: if self.ElementVariable.GetValue() != "": andrej@1698: self.EndModal(wx.ID_OK)