Laurent@705: #!/usr/bin/env python Laurent@705: # -*- coding: utf-8 -*- Laurent@705: Laurent@705: #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor Laurent@705: #based on the plcopen standard. Laurent@705: # Laurent@705: #Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD Laurent@705: # Laurent@705: #See COPYING file for copyrights details. Laurent@705: # Laurent@705: #This library is free software; you can redistribute it and/or Laurent@705: #modify it under the terms of the GNU General Public Laurent@705: #License as published by the Free Software Foundation; either Laurent@705: #version 2.1 of the License, or (at your option) any later version. Laurent@705: # Laurent@705: #This library is distributed in the hope that it will be useful, Laurent@705: #but WITHOUT ANY WARRANTY; without even the implied warranty of Laurent@705: #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Laurent@705: #General Public License for more details. Laurent@705: # Laurent@705: #You should have received a copy of the GNU General Public Laurent@705: #License along with this library; if not, write to the Free Software Laurent@705: #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Laurent@705: Laurent@705: import wx Laurent@705: Laurent@705: from plcopen.structures import TestIdentifier, IEC_KEYWORDS Laurent@705: Laurent@705: def GetPouTypes(): Laurent@705: _ = lambda x : x Laurent@705: return [_("function"), _("functionBlock"), _("program")] Laurent@705: POU_TYPES_DICT = dict([(_(pou_type), pou_type) for pou_type in GetPouTypes()]) Laurent@705: Laurent@705: def GetPouLanguages(): Laurent@705: _ = lambda x : x Laurent@705: return [_("IL"), _("ST"), _("LD"), _("FBD"), _("SFC")] Laurent@705: POU_LANGUAGES_DICT = dict([(_(language), language) for language in GetPouLanguages()]) Laurent@705: Laurent@705: class PouDialog(wx.Dialog): Laurent@705: Laurent@705: def __init__(self, parent, pou_type = None): Laurent@705: wx.Dialog.__init__(self, id=-1, parent=parent, Laurent@705: name='PouDialog', title=_('Create a new POU'), Laurent@705: size=wx.Size(300, 200), style=wx.DEFAULT_DIALOG_STYLE) Laurent@705: self.SetClientSize(wx.Size(300, 200)) Laurent@705: Laurent@705: main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) Laurent@705: main_sizer.AddGrowableCol(0) Laurent@705: main_sizer.AddGrowableRow(0) Laurent@705: Laurent@705: infos_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=3, vgap=15) Laurent@705: infos_sizer.AddGrowableCol(1) Laurent@714: main_sizer.AddSizer(infos_sizer, border=20, Laurent@714: flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) Laurent@705: Laurent@714: pouname_label = wx.StaticText(self, label=_('POU Name:')) Laurent@714: infos_sizer.AddWindow(pouname_label, border=4, Laurent@714: flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP) Laurent@705: Laurent@714: self.PouName = wx.TextCtrl(self) Laurent@714: infos_sizer.AddWindow(self.PouName, flag=wx.GROW) Laurent@705: Laurent@714: poutype_label = wx.StaticText(self, label=_('POU Type:')) Laurent@714: infos_sizer.AddWindow(poutype_label, border=4, Laurent@714: flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP) Laurent@705: Laurent@714: self.PouType = wx.ComboBox(self, style=wx.CB_READONLY) Laurent@714: self.Bind(wx.EVT_COMBOBOX, self.OnTypeChanged, self.PouType) Laurent@714: infos_sizer.AddWindow(self.PouType, flag=wx.GROW) Laurent@705: Laurent@714: language_label = wx.StaticText(self, label=_('Language:')) Laurent@714: infos_sizer.AddWindow(language_label, border=4, Laurent@714: flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP) Laurent@705: Laurent@714: self.Language = wx.ComboBox(self, style=wx.CB_READONLY) Laurent@714: infos_sizer.AddWindow(self.Language, flag=wx.GROW) Laurent@705: 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@705: Laurent@705: self.SetSizer(main_sizer) Laurent@705: Laurent@705: for option in GetPouTypes(): Laurent@705: self.PouType.Append(_(option)) Laurent@705: if pou_type is not None: Laurent@705: self.PouType.SetStringSelection(_(pou_type)) Laurent@705: self.RefreshLanguage() Laurent@705: Laurent@705: self.PouNames = [] Laurent@705: self.PouElementNames = [] Laurent@705: Laurent@705: def OnOK(self, event): Laurent@705: error = [] Laurent@705: pou_name = self.PouName.GetValue() Laurent@705: if pou_name == "": Laurent@705: error.append(_("POU Name")) Laurent@705: if self.PouType.GetSelection() == -1: Laurent@705: error.append(_("POU Type")) Laurent@705: if self.Language.GetSelection() == -1: Laurent@705: error.append(_("Language")) Laurent@705: message = None Laurent@705: question = False Laurent@705: if len(error) > 0: Laurent@705: text = "" Laurent@705: for i, item in enumerate(error): Laurent@705: if i == 0: Laurent@705: text += item Laurent@705: elif i == len(error) - 1: Laurent@705: text += _(" and %s")%item Laurent@705: else: Laurent@705: text += _(", %s")%item Laurent@705: message = _("Form isn't complete. %s must be filled!") % text Laurent@705: elif not TestIdentifier(pou_name): Laurent@705: message = _("\"%s\" is not a valid identifier!") % pou_name Laurent@705: elif pou_name.upper() in IEC_KEYWORDS: Laurent@705: message = _("\"%s\" is a keyword. It can't be used!") % pou_name Laurent@705: elif pou_name.upper() in self.PouNames: Laurent@705: message = _("\"%s\" pou already exists!") % pou_name Laurent@705: elif pou_name.upper() in self.PouElementNames: Laurent@705: message = _("A POU has an element named \"%s\". This could cause a conflict. Do you wish to continue?") % pou_name Laurent@705: question = True Laurent@705: if message is not None: Laurent@705: if question: Laurent@705: dialog = wx.MessageDialog(self, message, _("Warning"), wx.YES_NO|wx.ICON_EXCLAMATION) Laurent@705: result = dialog.ShowModal() Laurent@705: dialog.Destroy() Laurent@705: if result == wx.ID_YES: Laurent@705: self.EndModal(wx.ID_OK) Laurent@705: else: Laurent@705: dialog = wx.MessageDialog(self, message, _("Error"), wx.OK|wx.ICON_ERROR) Laurent@705: dialog.ShowModal() Laurent@705: dialog.Destroy() Laurent@705: else: Laurent@705: self.EndModal(wx.ID_OK) Laurent@705: Laurent@705: def RefreshLanguage(self): Laurent@705: selection = POU_LANGUAGES_DICT.get(self.Language.GetStringSelection(), "") Laurent@705: self.Language.Clear() Laurent@705: for language in GetPouLanguages(): Laurent@705: if language != "SFC" or POU_TYPES_DICT[self.PouType.GetStringSelection()] != "function": Laurent@705: self.Language.Append(_(language)) Laurent@705: if self.Language.FindString(_(selection)) != wx.NOT_FOUND: Laurent@705: self.Language.SetStringSelection(_(selection)) Laurent@705: Laurent@705: def OnTypeChanged(self, event): Laurent@705: self.RefreshLanguage() Laurent@705: event.Skip() Laurent@705: Laurent@705: def SetPouNames(self, pou_names): Laurent@705: self.PouNames = [pou_name.upper() for pou_name in pou_names] Laurent@705: Laurent@705: def SetPouElementNames(self, element_names): Laurent@705: self.PouElementNames = [element_name.upper() for element_name in element_names] Laurent@705: Laurent@705: def SetValues(self, values): Laurent@705: for item, value in values.items(): Laurent@705: if item == "pouName": Laurent@705: self.PouName.SetValue(value) Laurent@705: elif item == "pouType": Laurent@705: self.PouType.SetStringSelection(_(value)) Laurent@705: elif item == "language": Laurent@705: self.Language.SetStringSelection(_(value)) Laurent@705: Laurent@705: def GetValues(self): Laurent@705: values = {} Laurent@705: values["pouName"] = self.PouName.GetValue() Laurent@705: values["pouType"] = POU_TYPES_DICT[self.PouType.GetStringSelection()] Laurent@705: values["language"] = POU_LANGUAGES_DICT[self.Language.GetStringSelection()] Laurent@705: return values