laurent@507: # -*- coding: utf-8 -*- laurent@507: laurent@507: #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor laurent@507: #based on the plcopen standard. laurent@507: # laurent@507: #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD laurent@507: # laurent@507: #See COPYING file for copyrights details. laurent@507: # laurent@507: #This library is free software; you can redistribute it and/or laurent@507: #modify it under the terms of the GNU General Public laurent@507: #License as published by the Free Software Foundation; either laurent@507: #version 2.1 of the License, or (at your option) any later version. laurent@507: # laurent@507: #This library is distributed in the hope that it will be useful, laurent@507: #but WITHOUT ANY WARRANTY; without even the implied warranty of laurent@507: #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU laurent@507: #General Public License for more details. laurent@507: # laurent@507: #You should have received a copy of the GNU General Public laurent@507: #License along with this library; if not, write to the Free Software laurent@507: #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA laurent@507: laurent@507: import re laurent@507: from types import TupleType laurent@507: laurent@507: import wx laurent@577: laurent@577: from controls import CustomEditableListBox laurent@507: Laurent@714: #------------------------------------------------------------------------------- Laurent@714: # Helpers Laurent@714: #------------------------------------------------------------------------------- Laurent@714: laurent@507: DIMENSION_MODEL = re.compile("([0-9]+)\.\.([0-9]+)$") laurent@507: Laurent@714: #------------------------------------------------------------------------------- Laurent@714: # Array Type Dialog Laurent@714: #------------------------------------------------------------------------------- laurent@507: laurent@507: class ArrayTypeDialog(wx.Dialog): laurent@507: Laurent@714: def __init__(self, parent, datatypes, infos): Laurent@714: wx.Dialog.__init__(self, parent, Laurent@714: size=wx.Size(500, 300), title=_('Edit array type properties')) laurent@507: Laurent@714: main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=10) Laurent@714: main_sizer.AddGrowableCol(0) Laurent@714: main_sizer.AddGrowableRow(1) laurent@507: Laurent@714: top_sizer = wx.BoxSizer(wx.HORIZONTAL) Laurent@714: main_sizer.AddSizer(top_sizer, border=20, Laurent@714: flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) laurent@507: Laurent@714: basetype_label = wx.StaticText(self, label=_('Base Type:')) Laurent@714: top_sizer.AddWindow(basetype_label, 1, flag=wx.ALIGN_BOTTOM) laurent@507: Laurent@714: self.BaseType = wx.ComboBox(self, style=wx.CB_READONLY) Laurent@714: top_sizer.AddWindow(self.BaseType, 1, flag=wx.GROW) laurent@507: Laurent@714: self.Dimensions = CustomEditableListBox(self, label=_("Dimensions:"), Laurent@714: style=wx.gizmos.EL_ALLOW_NEW| Laurent@714: wx.gizmos.EL_ALLOW_EDIT| Laurent@714: wx.gizmos.EL_ALLOW_DELETE) Laurent@714: for func in ["_OnLabelEndEdit", Laurent@714: "_OnAddButton", Laurent@714: "_OnDelButton", Laurent@714: "_OnUpButton", Laurent@714: "_OnDownButton"]: Laurent@714: setattr(self.Dimensions, func, self.OnDimensionsChanged) Laurent@714: main_sizer.AddSizer(self.Dimensions, border=20, Laurent@714: flag=wx.GROW|wx.LEFT|wx.RIGHT) laurent@507: Laurent@714: button_sizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) Laurent@714: self.Bind(wx.EVT_BUTTON, self.OnOK, button_sizer.GetAffirmativeButton()) Laurent@714: main_sizer.AddSizer(button_sizer, border=20, Laurent@714: flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) laurent@507: Laurent@714: self.SetSizer(main_sizer) laurent@507: laurent@507: for datatype in datatypes: laurent@507: self.BaseType.Append(datatype) laurent@507: laurent@507: if isinstance(infos, TupleType) and infos[0] == "array": laurent@507: self.BaseType.SetStringSelection(infos[1]) laurent@507: self.Dimensions.SetStrings(map(lambda x : "..".join(x), infos[2])) laurent@507: elif infos in datatypes: laurent@507: self.BaseType.SetStringSelection(infos) laurent@507: laurent@577: self.BaseType.SetFocus() laurent@577: laurent@507: def GetDimensions(self): laurent@507: dimensions_list = [] laurent@507: for dimensions in self.Dimensions.GetStrings(): laurent@507: result = DIMENSION_MODEL.match(dimensions) laurent@507: if result is None: laurent@507: message = wx.MessageDialog(self, _("\"%s\" value isn't a valid array dimension!")%dimensions, _("Error"), wx.OK|wx.ICON_ERROR) laurent@507: message.ShowModal() laurent@507: message.Destroy() laurent@507: return None laurent@507: bounds = result.groups() laurent@507: if int(bounds[0]) >= int(bounds[1]): laurent@507: message = wx.MessageDialog(self, _("\"%s\" value isn't a valid array dimension!\nRight value must be greater than left value.")%dimensions, _("Error"), wx.OK|wx.ICON_ERROR) laurent@507: message.ShowModal() laurent@507: message.Destroy() laurent@507: return None laurent@507: dimensions_list.append(bounds) laurent@507: return dimensions_list laurent@507: laurent@507: def OnDimensionsChanged(self, event): laurent@507: wx.CallAfter(self.GetDimensions) laurent@507: event.Skip() laurent@507: laurent@507: def OnOK(self, event): laurent@507: if self.GetDimensions() is not None: laurent@507: self.EndModal(wx.ID_OK) laurent@507: laurent@507: def GetValue(self): laurent@577: return "array", self.BaseType.GetStringSelection(), self.GetDimensions()