Laurent@1236: #!/usr/bin/env python Laurent@1236: # -*- coding: utf-8 -*- Laurent@1236: Laurent@1236: #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor Laurent@1236: #based on the plcopen standard. Laurent@1236: # Laurent@1236: #Copyright (C) 2013: Edouard TISSERANT and Laurent BESSARD Laurent@1236: # Laurent@1236: #See COPYING file for copyrights details. Laurent@1236: # Laurent@1236: #This library is free software; you can redistribute it and/or Laurent@1236: #modify it under the terms of the GNU General Public Laurent@1236: #License as published by the Free Software Foundation; either Laurent@1236: #version 2.1 of the License, or (at your option) any later version. Laurent@1236: # Laurent@1236: #This library is distributed in the hope that it will be useful, Laurent@1236: #but WITHOUT ANY WARRANTY; without even the implied warranty of Laurent@1236: #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Laurent@1236: #General Public License for more details. Laurent@1236: # Laurent@1236: #You should have received a copy of the GNU General Public Laurent@1236: #License along with this library; if not, write to the Free Software Laurent@1236: #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Laurent@1236: Laurent@1236: import wx Laurent@1236: Laurent@1236: from plcopen.structures import TestIdentifier, IEC_KEYWORDS Laurent@1236: from graphics.GraphicCommons import FREEDRAWING_MODE Laurent@1236: Laurent@1236: #------------------------------------------------------------------------------- Laurent@1236: # Dialog with preview for graphic block Laurent@1236: #------------------------------------------------------------------------------- Laurent@1236: Laurent@1236: """ Laurent@1236: Class that implements a generic dialog containing a preview panel for displaying Laurent@1236: graphic created by dialog Laurent@1236: """ Laurent@1236: Laurent@1236: class BlockPreviewDialog(wx.Dialog): Laurent@1236: Laurent@1236: def __init__(self, parent, controller, tagname, size, title): Laurent@1236: wx.Dialog.__init__(self, parent, size=size, title=title) Laurent@1236: Laurent@1236: self.Controller = controller Laurent@1236: self.TagName = tagname Laurent@1236: Laurent@1236: self.PreviewLabel = wx.StaticText(self, label=_('Preview:')) Laurent@1236: Laurent@1236: self.Preview = wx.Panel(self, style=wx.SIMPLE_BORDER) Laurent@1236: self.Preview.SetBackgroundColour(wx.WHITE) Laurent@1236: setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE) Laurent@1236: setattr(self.Preview, "GetScaling", lambda:None) Laurent@1236: setattr(self.Preview, "GetBlockType", controller.GetBlockType) Laurent@1236: setattr(self.Preview, "IsOfType", controller.IsOfType) Laurent@1236: self.Preview.Bind(wx.EVT_PAINT, self.OnPaint) Laurent@1236: Laurent@1236: self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) Laurent@1236: self.Bind(wx.EVT_BUTTON, self.OnOK, Laurent@1236: self.ButtonSizer.GetAffirmativeButton()) Laurent@1236: Laurent@1236: self.Block = None Laurent@1236: self.DefaultBlockName = None Laurent@1236: self.MinBlockSize = None Laurent@1236: Laurent@1236: def __del__(self): Laurent@1236: self.Controller = None Laurent@1236: Laurent@1236: def SetMinBlockSize(self, size): Laurent@1236: self.MinBlockSize = size Laurent@1236: Laurent@1236: def SetPreviewFont(self, font): Laurent@1236: self.Preview.SetFont(font) Laurent@1236: Laurent@1236: def TestBlockName(self, block_name): Laurent@1236: format = None Laurent@1236: uppercase_block_name = block_name.upper() Laurent@1236: if not TestIdentifier(block_name): Laurent@1236: format = _("\"%s\" is not a valid identifier!") Laurent@1236: elif uppercase_block_name in IEC_KEYWORDS: Laurent@1236: format = _("\"%s\" is a keyword. It can't be used!") Laurent@1236: elif uppercase_block_name in self.Controller.GetProjectPouNames(): Laurent@1236: format = _("\"%s\" pou already exists!") Laurent@1237: elif ((self.DefaultBlockName is None or Laurent@1237: self.DefaultBlockName.upper() != uppercase_block_name) and Laurent@1236: uppercase_block_name in self.Controller.GetEditedElementVariables( Laurent@1236: self.TagName)): Laurent@1236: format = _("\"%s\" element for this pou already exists!") Laurent@1236: Laurent@1236: if format is not None: Laurent@1236: self.ShowErrorMessage(format % block_name) Laurent@1236: return False Laurent@1236: Laurent@1236: return True Laurent@1236: Laurent@1236: def ShowErrorMessage(self, message): Laurent@1236: dialog = wx.MessageDialog(self, message, Laurent@1236: _("Error"), Laurent@1236: wx.OK|wx.ICON_ERROR) Laurent@1236: dialog.ShowModal() Laurent@1236: dialog.Destroy() Laurent@1236: Laurent@1236: def OnOK(self, event): Laurent@1236: self.EndModal(wx.ID_OK) Laurent@1236: Laurent@1236: def RefreshPreview(self): Laurent@1236: dc = wx.ClientDC(self.Preview) Laurent@1236: dc.SetFont(self.Preview.GetFont()) Laurent@1236: dc.Clear() Laurent@1236: Laurent@1236: if self.Block is not None: Laurent@1236: min_width, min_height = self.Block.GetMinSize() Laurent@1236: width = max(self.MinBlockSize[0], min_width) Laurent@1236: height = max(self.MinBlockSize[1], min_height) Laurent@1236: self.Block.SetSize(width, height) Laurent@1241: client_size = self.Preview.GetClientSize() Laurent@1241: if (width * 1.2 > client_size.width or Laurent@1241: height * 1.2 > client_size.height): Laurent@1241: scale = max(float(width) / client_size.width, Laurent@1241: float(height) / client_size.height) * 1.2 Laurent@1241: x = int(client_size.width * scale - width) / 2 Laurent@1241: y = int(client_size.height * scale - height) / 2 Laurent@1241: else: Laurent@1241: x = (client_size.width - width) / 2 Laurent@1241: y = (client_size.height - height) / 2 Laurent@1241: scale = 1.0 Laurent@1241: dc.SetUserScale(1.0 / scale, 1.0 / scale) Laurent@1236: self.Block.SetPosition(x, y) Laurent@1236: self.Block.Draw(dc) Laurent@1236: Laurent@1236: def OnPaint(self, event): Laurent@1236: self.RefreshPreview() Laurent@1236: event.Skip() Laurent@1236: