# HG changeset patch # User Laurent Bessard # Date 1370818557 -7200 # Node ID a5d1d2a2f3660289e2c76417320b130217d19074 # Parent 1a30c70fa025306ba2754f092970d2301f2034f0 Added support for default function block name in FBDBlockDialog diff -r 1a30c70fa025 -r a5d1d2a2f366 dialogs/BlockPreviewDialog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/BlockPreviewDialog.py Mon Jun 10 00:55:57 2013 +0200 @@ -0,0 +1,123 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor +#based on the plcopen standard. +# +#Copyright (C) 2013: Edouard TISSERANT and Laurent BESSARD +# +#See COPYING file for copyrights details. +# +#This library is free software; you can redistribute it and/or +#modify it under the terms of the GNU General Public +#License as published by the Free Software Foundation; either +#version 2.1 of the License, or (at your option) any later version. +# +#This library is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +#General Public License for more details. +# +#You should have received a copy of the GNU General Public +#License along with this library; if not, write to the Free Software +#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +import wx + +from plcopen.structures import TestIdentifier, IEC_KEYWORDS +from graphics.GraphicCommons import FREEDRAWING_MODE + +#------------------------------------------------------------------------------- +# Dialog with preview for graphic block +#------------------------------------------------------------------------------- + +""" +Class that implements a generic dialog containing a preview panel for displaying +graphic created by dialog +""" + +class BlockPreviewDialog(wx.Dialog): + + def __init__(self, parent, controller, tagname, size, title): + wx.Dialog.__init__(self, parent, size=size, title=title) + + self.Controller = controller + self.TagName = tagname + + self.PreviewLabel = wx.StaticText(self, label=_('Preview:')) + + self.Preview = wx.Panel(self, style=wx.SIMPLE_BORDER) + self.Preview.SetBackgroundColour(wx.WHITE) + setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE) + setattr(self.Preview, "GetScaling", lambda:None) + setattr(self.Preview, "GetBlockType", controller.GetBlockType) + setattr(self.Preview, "IsOfType", controller.IsOfType) + self.Preview.Bind(wx.EVT_PAINT, self.OnPaint) + + self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) + self.Bind(wx.EVT_BUTTON, self.OnOK, + self.ButtonSizer.GetAffirmativeButton()) + + self.Block = None + self.DefaultBlockName = None + self.MinBlockSize = None + + def __del__(self): + self.Controller = None + + def SetMinBlockSize(self, size): + self.MinBlockSize = size + + def SetPreviewFont(self, font): + self.Preview.SetFont(font) + + def TestBlockName(self, block_name): + format = None + uppercase_block_name = block_name.upper() + if not TestIdentifier(block_name): + format = _("\"%s\" is not a valid identifier!") + elif uppercase_block_name in IEC_KEYWORDS: + format = _("\"%s\" is a keyword. It can't be used!") + elif uppercase_block_name in self.Controller.GetProjectPouNames(): + format = _("\"%s\" pou already exists!") + elif (self.DefaultBlockName.upper() != uppercase_block_name and + uppercase_block_name in self.Controller.GetEditedElementVariables( + self.TagName)): + format = _("\"%s\" element for this pou already exists!") + + if format is not None: + self.ShowErrorMessage(format % block_name) + return False + + return True + + def ShowErrorMessage(self, message): + dialog = wx.MessageDialog(self, message, + _("Error"), + wx.OK|wx.ICON_ERROR) + dialog.ShowModal() + dialog.Destroy() + + def OnOK(self, event): + self.EndModal(wx.ID_OK) + + def RefreshPreview(self): + dc = wx.ClientDC(self.Preview) + dc.SetFont(self.Preview.GetFont()) + dc.Clear() + + if self.Block is not None: + min_width, min_height = self.Block.GetMinSize() + width = max(self.MinBlockSize[0], min_width) + height = max(self.MinBlockSize[1], min_height) + self.Block.SetSize(width, height) + clientsize = self.Preview.GetClientSize() + x = (clientsize.width - width) / 2 + y = (clientsize.height - height) / 2 + self.Block.SetPosition(x, y) + self.Block.Draw(dc) + + def OnPaint(self, event): + self.RefreshPreview() + event.Skip() + \ No newline at end of file diff -r 1a30c70fa025 -r a5d1d2a2f366 dialogs/FBDBlockDialog.py --- a/dialogs/FBDBlockDialog.py Thu Jun 06 23:48:25 2013 +0200 +++ b/dialogs/FBDBlockDialog.py Mon Jun 10 00:55:57 2013 +0200 @@ -22,19 +22,22 @@ #License along with this library; if not, write to the Free Software #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +import re + import wx -from graphics import * +from graphics.FBD_Objects import FBD_Block from controls.LibraryPanel import LibraryPanel +from BlockPreviewDialog import BlockPreviewDialog #------------------------------------------------------------------------------- # Create New Block Dialog #------------------------------------------------------------------------------- -class FBDBlockDialog(wx.Dialog): - - def __init__(self, parent, controller): - wx.Dialog.__init__(self, parent, +class FBDBlockDialog(BlockPreviewDialog): + + def __init__(self, parent, controller, tagname): + BlockPreviewDialog.__init__(self, parent, controller, tagname, size=wx.Size(600, 450), title=_('Block Properties')) main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=4, vgap=10) @@ -99,49 +102,22 @@ self.Bind(wx.EVT_CHECKBOX, self.OnExecutionOrderChanged, self.ExecutionControl) top_right_gridsizer.AddWindow(self.ExecutionControl, flag=wx.GROW) - preview_label = wx.StaticText(self, label=_('Preview:')) - right_gridsizer.AddWindow(preview_label, flag=wx.GROW) - - self.Preview = wx.Panel(self, - style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER) - self.Preview.SetBackgroundColour(wx.Colour(255,255,255)) - setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE) - setattr(self.Preview, "GetScaling", lambda:None) - setattr(self.Preview, "GetBlockType", controller.GetBlockType) - setattr(self.Preview, "IsOfType", controller.IsOfType) - self.Preview.Bind(wx.EVT_PAINT, self.OnPaint) + right_gridsizer.AddWindow(self.PreviewLabel, flag=wx.GROW) right_gridsizer.AddWindow(self.Preview, flag=wx.GROW) - button_sizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) - self.Bind(wx.EVT_BUTTON, self.OnOK, button_sizer.GetAffirmativeButton()) - main_sizer.AddSizer(button_sizer, border=20, + main_sizer.AddSizer(self.ButtonSizer, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) self.SetSizer(main_sizer) - self.Controller = controller - self.BlockName.SetValue("") self.BlockName.Enable(False) self.Inputs.Enable(False) - self.Block = None - self.MinBlockSize = None - self.First = True - - self.PouNames = [] - self.PouElementNames = [] - + self.CurrentBlockName = None + + self.LibraryPanel.SetBlockList(controller.GetBlockTypes(tagname)) self.LibraryPanel.SetFocus() - def __del__(self): - self.Controller = None - - def SetBlockList(self, blocklist): - self.LibraryPanel.SetBlockList(blocklist) - - def SetPreviewFont(self, font): - self.Preview.SetFont(font) - def OnOK(self, event): message = None selected = self.LibraryPanel.GetSelectedBlock() @@ -151,37 +127,23 @@ message = _("Form isn't complete. Valid block type must be selected!") elif name_enabled and block_name == "": message = _("Form isn't complete. Name must be filled!") - elif name_enabled and not TestIdentifier(block_name): - message = _("\"%s\" is not a valid identifier!") % block_name - elif name_enabled and block_name.upper() in IEC_KEYWORDS: - message = _("\"%s\" is a keyword. It can't be used!") % block_name - elif name_enabled and block_name.upper() in self.PouNames: - message = _("\"%s\" pou already exists!") % block_name - elif name_enabled and block_name.upper() in self.PouElementNames: - message = _("\"%s\" element for this pou already exists!") % block_name if message is not None: - dialog = wx.MessageDialog(self, message, _("Error"), wx.OK|wx.ICON_ERROR) - dialog.ShowModal() - dialog.Destroy() - else: - self.EndModal(wx.ID_OK) - - def SetMinBlockSize(self, size): - self.MinBlockSize = size - - def SetPouNames(self, pou_names): - self.PouNames = [pou_name.upper() for pou_name in pou_names] - - def SetPouElementNames(self, element_names): - self.PouElementNames = [element_name.upper() for element_name in element_names] - + self.ShowMessage(message) + elif name_enabled and self.TestBlockName(block_name): + BlockPreviewDialog.OnOK(self, event) + def SetValues(self, values): blocktype = values.get("type", None) + default_name_model = re.compile("%s[0-9]+" % blocktype) if blocktype is not None: - self.LibraryPanel.SelectTreeItem(blocktype, values.get("inputs", None)) + self.LibraryPanel.SelectTreeItem(blocktype, + values.get("inputs", None)) for name, value in values.items(): if name == "name": - self.BlockName.SetValue(value) + self.DefaultBlockName = value + if default_name_model.match(value) is None: + self.CurrentBlockName = value + self.BlockName.ChangeValue(value) elif name == "extension": self.Inputs.SetValue(value) elif name == "executionOrder": @@ -199,26 +161,36 @@ values["executionOrder"] = self.ExecutionOrder.GetValue() values["executionControl"] = self.ExecutionControl.GetValue() return values - + def OnLibraryTreeItemSelected(self, event): values = self.LibraryPanel.GetSelectedBlock() - if values is not None: - blocktype = self.Controller.GetBlockType(values["type"], values["inputs"]) - else: - blocktype = None + blocktype = (self.Controller.GetBlockType(values["type"], + values["inputs"]) + if values is not None else None) + if blocktype is not None: self.Inputs.SetValue(len(blocktype["inputs"])) self.Inputs.Enable(blocktype["extensible"]) - self.BlockName.Enable(blocktype["type"] != "function") - wx.CallAfter(self.RefreshPreview) + else: + self.Inputs.SetValue(2) + self.Inputs.Enable(False) + + if blocktype is not None and blocktype["type"] != "function": + self.BlockName.Enable(True) + self.BlockName.ChangeValue( + self.CurrentBlockName + if self.CurrentBlockName is not None + else self.Controller.GenerateNewName( + self.TagName, None, values["type"]+"%d", 0)) else: self.BlockName.Enable(False) - self.Inputs.Enable(False) - self.Inputs.SetValue(2) - wx.CallAfter(self.ErasePreview) + self.BlockName.ChangeValue("") + + self.RefreshPreview() def OnNameChanged(self, event): if self.BlockName.IsEnabled(): + self.CurrentBlockName = self.BlockName.GetValue() self.RefreshPreview() event.Skip() @@ -235,15 +207,7 @@ self.RefreshPreview() event.Skip() - def ErasePreview(self): - dc = wx.ClientDC(self.Preview) - dc.Clear() - self.Block = None - def RefreshPreview(self): - dc = wx.ClientDC(self.Preview) - dc.SetFont(self.Preview.GetFont()) - dc.Clear() values = self.LibraryPanel.GetSelectedBlock() if values is not None: if self.BlockName.IsEnabled(): @@ -256,19 +220,6 @@ inputs = values["inputs"], executionControl = self.ExecutionControl.GetValue(), executionOrder = self.ExecutionOrder.GetValue()) - width, height = self.MinBlockSize - min_width, min_height = self.Block.GetMinSize() - width, height = max(min_width, width), max(min_height, height) - self.Block.SetSize(width, height) - clientsize = self.Preview.GetClientSize() - x = (clientsize.width - width) / 2 - y = (clientsize.height - height) / 2 - self.Block.SetPosition(x, y) - self.Block.Draw(dc) else: - self.Block = None - - def OnPaint(self, event): - if self.Block is not None: - self.RefreshPreview() - event.Skip() + self.Block = None + BlockPreviewDialog.RefreshPreview(self) diff -r 1a30c70fa025 -r a5d1d2a2f366 editors/Viewer.py --- a/editors/Viewer.py Thu Jun 06 23:48:25 2013 +0200 +++ b/editors/Viewer.py Mon Jun 10 00:55:57 2013 +0200 @@ -2197,11 +2197,8 @@ return width, height def AddNewBlock(self, bbox): - dialog = FBDBlockDialog(self.ParentWindow, self.Controler) + dialog = FBDBlockDialog(self.ParentWindow, self.Controler, self.TagName) dialog.SetPreviewFont(self.GetFont()) - dialog.SetBlockList(self.Controler.GetBlockTypes(self.TagName, self.Debug)) - dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) - dialog.SetPouElementNames(self.Controler.GetEditedElementVariables(self.TagName, self.Debug)) dialog.SetMinBlockSize((bbox.width, bbox.height)) if dialog.ShowModal() == wx.ID_OK: id = self.GetNewId() @@ -2501,14 +2498,8 @@ #------------------------------------------------------------------------------- def EditBlockContent(self, block): - dialog = FBDBlockDialog(self.ParentWindow, self.Controler) + dialog = FBDBlockDialog(self.ParentWindow, self.Controler, self.TagName) dialog.SetPreviewFont(self.GetFont()) - dialog.SetBlockList(self.Controler.GetBlockTypes(self.TagName, self.Debug)) - dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) - variable_names = self.Controler.GetEditedElementVariables(self.TagName, self.Debug) - if block.GetName() != "": - variable_names.remove(block.GetName()) - dialog.SetPouElementNames(variable_names) dialog.SetMinBlockSize(block.GetSize()) old_values = {"name" : block.GetName(), "type" : block.GetType(),