# HG changeset patch # User 'Laurent Bessard ' # Date 1254500083 -7200 # Node ID e183bffc05f0606564adc94b4af8de44b928a2a1 # Parent eebcf66f2d5a48ade254ab4888eb6d0ee69d6d68# Parent c7e0254be378ed5c9ba44763c5b750a065374116 Changes from bct merged diff -r c7e0254be378 -r e183bffc05f0 DataTypeEditor.py --- a/DataTypeEditor.py Wed Sep 30 15:23:31 2009 -0600 +++ b/DataTypeEditor.py Fri Oct 02 18:14:43 2009 +0200 @@ -598,6 +598,9 @@ def IsViewing(self, tagname): return self.TagName == tagname + def IsDebugging(self): + return False + def SetMode(self, mode): pass @@ -823,7 +826,6 @@ self.StructureElementsTable.SetValueByName(row, "Type", base_type) self.RefreshTypeInfos() self.StructureElementsTable.ResetView(self.StructureElementsGrid) - event.Skip() return ElementTypeFunction def RefreshDisplayedInfos(self): diff -r c7e0254be378 -r e183bffc05f0 Dialogs.py --- a/Dialogs.py Wed Sep 30 15:23:31 2009 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2597 +0,0 @@ -#!/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) 2007: 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 -import wx.grid - -from graphics import * - -#------------------------------------------------------------------------------- -# Create New Block Dialog -#------------------------------------------------------------------------------- - -[ID_BLOCKPROPERTIESDIALOG, ID_BLOCKPROPERTIESDIALOGNAME, - ID_BLOCKPROPERTIESDIALOGTYPETREE, ID_BLOCKPROPERTIESDIALOGTYPEDESC, - ID_BLOCKPROPERTIESDIALOGINPUTS, ID_BLOCKPROPERTIESDIALOGPREVIEW, - ID_BLOCKPROPERTIESDIALOGEXECUTIONORDER, ID_BLOCKPROPERTIESDIALOGEXECUTIONCONTROL, - ID_BLOCKPROPERTIESDIALOGSTATICTEXT1, ID_BLOCKPROPERTIESDIALOGSTATICTEXT2, - ID_BLOCKPROPERTIESDIALOGSTATICTEXT3, ID_BLOCKPROPERTIESDIALOGSTATICTEXT4, - ID_BLOCKPROPERTIESDIALOGSTATICTEXT5, ID_BLOCKPROPERTIESDIALOGSTATICTEXT6, -] = [wx.NewId() for _init_ctrls in range(14)] - -[CATEGORY, BLOCK] = range(2) - -class BlockPropertiesDialog(wx.Dialog): - - if wx.VERSION < (2, 6, 0): - def Bind(self, event, function, id = None): - if id is not None: - event(self, id, function) - else: - event(self, function) - - def _init_coll_flexGridSizer1_Items(self, parent): - parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) - parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) - - def _init_coll_flexGridSizer1_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(0) - - def _init_coll_MainSizer_Items(self, parent): - parent.AddSizer(self.LeftBoxSizer, 1, border=5, flag=wx.GROW|wx.RIGHT) - parent.AddSizer(self.RightGridSizer, 1, border=5, flag=wx.GROW|wx.LEFT) - - def _init_coll_LeftBoxSizer_Items(self, parent): - parent.AddWindow(self.TypeTree, 3, border=5, flag=wx.GROW|wx.BOTTOM) - parent.AddWindow(self.TypeDesc, 1, border=0, flag=wx.GROW) - - def _init_coll_RightGridSizer_Items(self, parent): - parent.AddSizer(self.RightUpGridSizer, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.staticText6, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW) - - def _init_coll_RightGridSizer_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(2) - - def _init_coll_RightUpGridSizer_Items(self, parent): - parent.AddWindow(self.staticText2, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP) - parent.AddWindow(self.BlockName, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.staticText3, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP) - parent.AddWindow(self.Inputs, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.staticText4, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP) - parent.AddWindow(self.ExecutionOrder, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.staticText5, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP) - parent.AddWindow(self.ExecutionControl, 0, border=0, flag=wx.GROW) - - def _init_coll_RightUpGridSizer_Growables(self, parent): - parent.AddGrowableCol(1) - - def _init_sizers(self): - self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) - self.MainSizer = wx.BoxSizer(wx.HORIZONTAL) - self.LeftBoxSizer = wx.StaticBoxSizer(self.staticbox1, wx.VERTICAL) - self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=5) - self.RightUpGridSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=4, vgap=5) - - self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) - self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) - self._init_coll_MainSizer_Items(self.MainSizer) - self._init_coll_LeftBoxSizer_Items(self.LeftBoxSizer) - self._init_coll_RightGridSizer_Items(self.RightGridSizer) - self._init_coll_RightGridSizer_Growables(self.RightGridSizer) - self._init_coll_RightUpGridSizer_Items(self.RightUpGridSizer) - self._init_coll_RightUpGridSizer_Growables(self.RightUpGridSizer) - - self.SetSizer(self.flexGridSizer1) - - def _init_ctrls(self, prnt): - wx.Dialog.__init__(self, id=ID_BLOCKPROPERTIESDIALOG, - name='BlockPropertiesDialog', parent=prnt, pos=wx.Point(376, 223), - size=wx.Size(600, 400), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER, - title=_('Block Properties')) - self.SetClientSize(wx.Size(600, 400)) - - self.staticbox1 = wx.StaticBox(id=ID_BLOCKPROPERTIESDIALOGSTATICTEXT1, - label=_('Type:'), name='staticBox1', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 0), style=0) - - self.staticText2 = wx.StaticText(id=ID_BLOCKPROPERTIESDIALOGSTATICTEXT2, - label=_('Name:'), name='staticText2', parent=self, - pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) - - self.staticText3 = wx.StaticText(id=ID_BLOCKPROPERTIESDIALOGSTATICTEXT2, - label=_('Inputs:'), name='staticText4', parent=self, - pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) - - self.staticText4 = wx.StaticText(id=ID_BLOCKPROPERTIESDIALOGSTATICTEXT4, - label=_('Execution Order:'), name='staticText4', parent=self, - pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) - - self.staticText5 = wx.StaticText(id=ID_BLOCKPROPERTIESDIALOGSTATICTEXT5, - label=_('Execution Control:'), name='staticText5', parent=self, - pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) - - self.staticText6 = wx.StaticText(id=ID_BLOCKPROPERTIESDIALOGSTATICTEXT6, - label=_('Preview:'), name='staticText6', parent=self, - pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) - - if wx.Platform == '__WXMSW__': - treestyle = wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER - else: - treestyle = wx.TR_HAS_BUTTONS|wx.TR_HIDE_ROOT|wx.TR_SINGLE|wx.SUNKEN_BORDER - self.TypeTree = wx.TreeCtrl(id=ID_BLOCKPROPERTIESDIALOGTYPETREE, - name='TypeTree', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 0), style=treestyle) - self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnTypeTreeItemSelected, - id=ID_BLOCKPROPERTIESDIALOGTYPETREE) - - self.TypeDesc = wx.TextCtrl(id=ID_BLOCKPROPERTIESDIALOGTYPEDESC, - name='TypeDesc', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 0), style=wx.TE_READONLY|wx.TE_MULTILINE) - - self.BlockName = wx.TextCtrl(id=ID_BLOCKPROPERTIESDIALOGNAME, value='', - name='BlockName', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 24), style=0) - self.Bind(wx.EVT_TEXT, self.OnNameChanged, id=ID_BLOCKPROPERTIESDIALOGNAME) - - self.Inputs = wx.SpinCtrl(id=ID_BLOCKPROPERTIESDIALOGINPUTS, - name='Inputs', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=2, max=20) - self.Bind(wx.EVT_SPINCTRL, self.OnInputsChanged, id=ID_BLOCKPROPERTIESDIALOGINPUTS) - - self.ExecutionOrder = wx.SpinCtrl(id=ID_BLOCKPROPERTIESDIALOGEXECUTIONORDER, - name='ExecutionOrder', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0) - self.Bind(wx.EVT_SPINCTRL, self.OnExecutionOrderChanged, id=ID_BLOCKPROPERTIESDIALOGEXECUTIONORDER) - - self.ExecutionControl = wx.CheckBox(id=ID_BLOCKPROPERTIESDIALOGEXECUTIONCONTROL, - name='ExecutionControl', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 24), style=0) - self.Bind(wx.EVT_CHECKBOX, self.OnExecutionOrderChanged, id=ID_BLOCKPROPERTIESDIALOGEXECUTIONCONTROL) - - self.Preview = wx.Panel(id=ID_BLOCKPROPERTIESDIALOGPREVIEW, - name='Preview', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 0), 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", self.Controler.GetBlockType) - setattr(self.Preview, "IsOfType", self.Controler.IsOfType) - - self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) - if wx.VERSION >= (2, 5, 0): - self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId()) - self.Preview.Bind(wx.EVT_PAINT, self.OnPaint) - else: - self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId()) - wx.EVT_PAINT(self.Preview, self.OnPaint) - - self._init_sizers() - - def __init__(self, parent, controler): - self.Controler = controler - self._init_ctrls(parent) - self.BlockName.SetValue("") - self.BlockName.Enable(False) - self.Inputs.Enable(False) - self.Block = None - self.MinBlockSize = None - self.First = True - - self.PouNames = [] - self.PouElementNames = [] - - def SetPreviewFont(self, font): - self.Preview.SetFont(font) - - def FindTreeItem(self, root, name, inputs = None): - if root.IsOk(): - pydata = self.TypeTree.GetPyData(root) - type_inputs = pydata.get("inputs", None) - type_extension = pydata.get("extension", None) - if inputs is not None and type_inputs is not None: - if type_extension is not None: - same_inputs = type_inputs == inputs[:type_extension] - else: - same_inputs = type_inputs == inputs - else: - same_inputs = True - if self.TypeTree.GetItemText(root) == name and same_inputs: - return root - else: - if wx.VERSION < (2, 6, 0): - item, root_cookie = self.TypeTree.GetFirstChild(root, 0) - else: - item, root_cookie = self.TypeTree.GetFirstChild(root) - while item.IsOk(): - result = self.FindTreeItem(item, name, inputs) - if result: - return result - item, root_cookie = self.TypeTree.GetNextChild(root, root_cookie) - return None - - def OnOK(self, event): - selected = self.TypeTree.GetSelection() - block_name = self.BlockName.GetValue() - name_enabled = self.BlockName.IsEnabled() - if not selected.IsOk() or self.TypeTree.GetItemParent(selected) == self.TypeTree.GetRootItem() or selected == self.TypeTree.GetRootItem(): - message = wx.MessageDialog(self, _("Form isn't complete. Valid block type must be selected!"), _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - elif name_enabled and block_name == "": - message = wx.MessageDialog(self, _("Form isn't complete. Name must be filled!"), _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - elif name_enabled and not TestIdentifier(block_name): - message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%block_name, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - elif name_enabled and block_name.upper() in IEC_KEYWORDS: - message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%block_name, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - elif name_enabled and block_name.upper() in self.PouNames: - message = wx.MessageDialog(self, _("\"%s\" pou already exists!")%block_name, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - elif name_enabled and block_name.upper() in self.PouElementNames: - message = wx.MessageDialog(self, _("\"%s\" element for this pou already exists!")%block_name, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - else: - self.EndModal(wx.ID_OK) - - def SetBlockList(self, blocktypes): - if wx.Platform == '__WXMSW__': - root = self.TypeTree.AddRoot(_("Block Types")) - else: - root = self.TypeTree.AddRoot("") - self.TypeTree.SetPyData(root, {"type" : CATEGORY}) - for category in blocktypes: - category_name = category["name"] - category_item = self.TypeTree.AppendItem(root, _(category_name)) - self.TypeTree.SetPyData(category_item, {"type" : CATEGORY}) - for blocktype in category["list"]: - blocktype_item = self.TypeTree.AppendItem(category_item, blocktype["name"]) - block_data = {"type" : BLOCK, - "inputs" : tuple([type for name, type, modifier in blocktype["inputs"]]), - "extension" : None} - if blocktype["extensible"]: - block_data["extension"] = len(blocktype["inputs"]) - self.TypeTree.SetPyData(blocktype_item, block_data) - if wx.Platform == '__WXMSW__': - self.TypeTree.Expand(root) - - 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] - - def SetValues(self, values): - blocktype = values.get("type", None) - if blocktype is not None: - inputs = values.get("inputs", None) - item = self.FindTreeItem(self.TypeTree.GetRootItem(), blocktype, inputs) - if item: - self.TypeTree.SelectItem(item) - for name, value in values.items(): - if name == "name": - self.BlockName.SetValue(value) - elif name == "extension": - self.Inputs.SetValue(value) - elif name == "executionOrder": - self.ExecutionOrder.SetValue(value) - elif name == "executionControl": - self.ExecutionControl.SetValue(value) - self.RefreshPreview() - - def GetValues(self): - values = {} - item = self.TypeTree.GetSelection() - values["type"] = self.TypeTree.GetItemText(item) - values["inputs"] = self.TypeTree.GetPyData(item)["inputs"] - if self.BlockName.GetValue() != "": - values["name"] = self.BlockName.GetValue() - values["width"], values["height"] = self.Block.GetSize() - values["extension"] = self.Inputs.GetValue() - values["executionOrder"] = self.ExecutionOrder.GetValue() - values["executionControl"] = self.ExecutionControl.GetValue() - return values - - def OnTypeTreeItemSelected(self, event): - self.BlockName.SetValue("") - selected = event.GetItem() - pydata = self.TypeTree.GetPyData(selected) - if pydata["type"] != CATEGORY: - blocktype = self.Controler.GetBlockType(self.TypeTree.GetItemText(selected), pydata["inputs"]) - if blocktype: - self.Inputs.SetValue(len(blocktype["inputs"])) - self.Inputs.Enable(blocktype["extensible"]) - self.BlockName.Enable(blocktype["type"] != "function") - comment = blocktype["comment"] - self.TypeDesc.SetValue(_(comment) + blocktype.get("usage", "")) - wx.CallAfter(self.RefreshPreview) - else: - self.BlockName.Enable(False) - self.Inputs.Enable(False) - self.Inputs.SetValue(2) - self.TypeDesc.SetValue("") - wx.CallAfter(self.ErasePreview) - else: - self.BlockName.Enable(False) - self.Inputs.Enable(False) - self.Inputs.SetValue(2) - self.TypeDesc.SetValue("") - wx.CallAfter(self.ErasePreview) - event.Skip() - - def OnNameChanged(self, event): - if self.BlockName.IsEnabled(): - self.RefreshPreview() - event.Skip() - - def OnInputsChanged(self, event): - if self.Inputs.IsEnabled(): - self.RefreshPreview() - event.Skip() - - def OnExecutionOrderChanged(self, event): - self.RefreshPreview() - event.Skip() - - def OnExecutionControlChanged(self, event): - 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() - item = self.TypeTree.GetSelection() - if item.IsOk(): - pydata = self.TypeTree.GetPyData(item) - if pydata["type"] == CATEGORY: - self.Block = None - else: - blocktype = self.TypeTree.GetItemText(item) - if blocktype: - self.Block = FBD_Block(self.Preview, blocktype, - self.BlockName.GetValue(), - extension = self.Inputs.GetValue(), - inputs = pydata["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() - -#------------------------------------------------------------------------------- -# Create New Variable Dialog -#------------------------------------------------------------------------------- - -[ID_VARIABLEPROPERTIESDIALOG, ID_VARIABLEPROPERTIESDIALOGSPACER, - ID_VARIABLEPROPERTIESDIALOGNAME, ID_VARIABLEPROPERTIESDIALOGCLASS, - ID_VARIABLEPROPERTIESDIALOGPREVIEW, ID_VARIABLEPROPERTIESDIALOGEXPRESSION, - ID_VARIABLEPROPERTIESDIALOGEXECUTIONORDER, ID_VARIABLEPROPERTIESDIALOGSTATICTEXT1, - ID_VARIABLEPROPERTIESDIALOGSTATICTEXT2, ID_VARIABLEPROPERTIESDIALOGSTATICTEXT3, - ID_VARIABLEPROPERTIESDIALOGSTATICTEXT4, ID_VARIABLEPROPERTIESDIALOGSTATICTEXT5 -] = [wx.NewId() for _init_ctrls in range(12)] - -VARIABLE_CLASSES_DICT = {INPUT : _("Input"), - INOUT : _("InOut"), - OUTPUT : _("Output")} -VARIABLE_CLASSES_DICT_REVERSE = dict([(value, key) for key, value in VARIABLE_CLASSES_DICT.iteritems()]) - -class VariablePropertiesDialog(wx.Dialog): - - if wx.VERSION < (2, 6, 0): - def Bind(self, event, function, id = None): - if id is not None: - event(self, id, function) - else: - event(self, function) - - def _init_coll_flexGridSizer1_Items(self, parent): - parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) - parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) - - def _init_coll_flexGridSizer1_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(0) - - def _init_coll_MainSizer_Items(self, parent): - parent.AddSizer(self.TopSizer, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.staticText5, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW) - - def _init_coll_MainSizer_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(2) - - def _init_coll_TopSizer_Items(self, parent): - parent.AddSizer(self.LeftGridSizer, 1, border=5, flag=wx.GROW|wx.RIGHT) - parent.AddSizer(self.RightGridSizer, 1, border=5, flag=wx.GROW|wx.LEFT) - - def _init_coll_LeftGridSizer_Items(self, parent): - parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.Class, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.Expression, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.ExecutionOrder, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW) - - def _init_coll_LeftGridSizer_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(2) - - def _init_coll_RightGridSizer_Items(self, parent): - parent.AddWindow(self.staticText4, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.VariableName, 0, border=0, flag=wx.GROW) - - def _init_coll_RightGridSizer_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(1) - - def _init_sizers(self): - self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) - self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=5) - self.TopSizer = wx.BoxSizer(wx.HORIZONTAL) - self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=7, vgap=5) - self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5) - - self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) - self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) - self._init_coll_MainSizer_Items(self.MainSizer) - self._init_coll_MainSizer_Growables(self.MainSizer) - self._init_coll_TopSizer_Items(self.TopSizer) - self._init_coll_LeftGridSizer_Items(self.LeftGridSizer) - self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer) - self._init_coll_RightGridSizer_Items(self.RightGridSizer) - self._init_coll_RightGridSizer_Growables(self.RightGridSizer) - - self.SetSizer(self.flexGridSizer1) - - def _init_ctrls(self, prnt, ctrler): - wx.Dialog.__init__(self, id=ID_VARIABLEPROPERTIESDIALOG, - name='VariablePropertiesDialog', parent=prnt, pos=wx.Point(376, 223), - size=wx.Size(400, 380), style=wx.DEFAULT_DIALOG_STYLE, - title=_('Variable Properties')) - self.SetClientSize(wx.Size(400, 380)) - - self.staticText1 = wx.StaticText(id=ID_VARIABLEPROPERTIESDIALOGSTATICTEXT1, - label=_('Class:'), name='staticText1', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) - - self.staticText2 = wx.StaticText(id=ID_VARIABLEPROPERTIESDIALOGSTATICTEXT2, - label=_('Expression:'), name='staticText2', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) - - self.staticText3 = wx.StaticText(id=ID_VARIABLEPROPERTIESDIALOGSTATICTEXT3, - label=_('Execution Order:'), name='staticText3', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) - - self.staticText4 = wx.StaticText(id=ID_VARIABLEPROPERTIESDIALOGSTATICTEXT4, - label=_('Name:'), name='staticText4', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) - - self.staticText5 = wx.StaticText(id=ID_VARIABLEPROPERTIESDIALOGSTATICTEXT5, - label=_('Preview:'), name='staticText5', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) - - self.Class = wx.ComboBox(id=ID_VARIABLEPROPERTIESDIALOGCLASS, - name='Class', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 28), style=wx.CB_READONLY) - self.Bind(wx.EVT_COMBOBOX, self.OnClassChanged, id=ID_VARIABLEPROPERTIESDIALOGCLASS) - - self.VariableName = wx.ListBox(id=ID_VARIABLEPROPERTIESDIALOGNAME, - name='Name', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 90), style=wx.LB_SINGLE|wx.LB_SORT) - self.Bind(wx.EVT_LISTBOX, self.OnNameChanged, id=ID_VARIABLEPROPERTIESDIALOGNAME) - - self.Expression = wx.TextCtrl(id=ID_VARIABLEPROPERTIESDIALOGEXPRESSION, - name='Expression', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 24), style=0) - self.Bind(wx.EVT_TEXT, self.OnExpressionChanged, id=ID_VARIABLEPROPERTIESDIALOGEXPRESSION) - - self.ExecutionOrder = wx.SpinCtrl(id=ID_VARIABLEPROPERTIESDIALOGEXECUTIONORDER, - name='ExecutionOrder', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0) - self.Bind(wx.EVT_SPINCTRL, self.OnExecutionOrderChanged, id=ID_VARIABLEPROPERTIESDIALOGEXECUTIONORDER) - - self.Spacer = wx.Panel(id=ID_VARIABLEPROPERTIESDIALOGSPACER, - name='Spacer', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) - - self.Preview = wx.Panel(id=ID_VARIABLEPROPERTIESDIALOGPREVIEW, - name='Preview', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 0), 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, "IsOfType", ctrler.IsOfType) - - self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) - if wx.VERSION >= (2, 5, 0): - self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId()) - self.Preview.Bind(wx.EVT_PAINT, self.OnPaint) - else: - self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId()) - wx.EVT_PAINT(self.Preview, self.OnPaint) - - self._init_sizers() - - def __init__(self, parent, controler, transition = ""): - self._init_ctrls(parent, controler) - self.Transition = transition - self.Variable = None - self.VarList = [] - self.MinVariableSize = None - - for choice in VARIABLE_CLASSES_DICT.itervalues(): - self.Class.Append(choice) - self.Class.SetStringSelection(VARIABLE_CLASSES_DICT[INPUT]) - - self.RefreshNameList() - - def SetPreviewFont(self, font): - self.Preview.SetFont(font) - - def RefreshNameList(self): - selected = self.VariableName.GetStringSelection() - var_class = VARIABLE_CLASSES_DICT_REVERSE[self.Class.GetStringSelection()] - self.VariableName.Clear() - self.VariableName.Append("") - for name, var_type, value_type in self.VarList: - if var_type != "Input" or var_class == INPUT: - self.VariableName.Append(name) - if selected != "" and self.VariableName.FindString(selected) != wx.NOT_FOUND: - self.VariableName.SetStringSelection(selected) - self.Expression.Enable(False) - else: - self.VariableName.SetStringSelection("") - self.Expression.Enable(var_class == INPUT) - self.VariableName.Enable(self.VariableName.GetCount() > 0) - - def SetMinVariableSize(self, size): - self.MinVariableSize = size - - def SetVariables(self, vars): - self.VarList = vars - self.RefreshNameList() - - def SetValues(self, values): - value_type = values.get("type", None) - value_name = values.get("name", None) - if value_type: - self.Class.SetStringSelection(VARIABLE_CLASSES_DICT[value_type]) - self.RefreshNameList() - if value_name: - if self.VariableName.FindString(value_name) != wx.NOT_FOUND: - self.VariableName.SetStringSelection(value_name) - self.Expression.Enable(False) - else: - self.Expression.SetValue(value_name) - self.VariableName.Enable(False) - if "executionOrder" in values: - self.ExecutionOrder.SetValue(values["executionOrder"]) - self.RefreshPreview() - - def GetValues(self): - values = {} - values["type"] = VARIABLE_CLASSES_DICT_REVERSE[self.Class.GetStringSelection()] - expression = self.Expression.GetValue() - if self.Expression.IsEnabled() and expression != "": - values["name"] = expression - else: - values["name"] = self.VariableName.GetStringSelection() - values["value_type"] = None - for var_name, var_type, value_type in self.VarList: - if var_name == values["name"]: - values["value_type"] = value_type - values["width"], values["height"] = self.Variable.GetSize() - values["executionOrder"] = self.ExecutionOrder.GetValue() - return values - - def OnOK(self, event): - expression = self.Expression.GetValue() - if self.Expression.IsEnabled(): - value = expression - else: - value = self.VariableName.GetStringSelection() - if value == "": - message = wx.MessageDialog(self, _("At least a variable or an expression must be selected!"), _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - elif value.upper() in IEC_KEYWORDS: - message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%value, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - else: - self.EndModal(wx.ID_OK) - - def OnClassChanged(self, event): - self.RefreshNameList() - self.RefreshPreview() - event.Skip() - - def OnNameChanged(self, event): - if self.VariableName.GetStringSelection() != "": - self.Expression.Enable(False) - elif VARIABLE_CLASSES_DICT_REVERSE[self.Class.GetStringSelection()] == INPUT: - self.Expression.Enable(True) - self.RefreshPreview() - event.Skip() - - def OnExpressionChanged(self, event): - if self.Expression.GetValue() != "": - self.VariableName.Enable(False) - else: - self.VariableName.Enable(True) - self.RefreshPreview() - event.Skip() - - def OnExecutionOrderChanged(self, event): - self.RefreshPreview() - event.Skip() - - def RefreshPreview(self): - dc = wx.ClientDC(self.Preview) - dc.SetFont(self.Preview.GetFont()) - dc.Clear() - expression = self.Expression.GetValue() - if self.Expression.IsEnabled() and expression != "": - name = expression - else: - name = self.VariableName.GetStringSelection() - type = "" - for var_name, var_type, value_type in self.VarList: - if var_name == name: - type = value_type - classtype = VARIABLE_CLASSES_DICT_REVERSE[self.Class.GetStringSelection()] - self.Variable = FBD_Variable(self.Preview, classtype, name, type, executionOrder = self.ExecutionOrder.GetValue()) - width, height = self.MinVariableSize - min_width, min_height = self.Variable.GetMinSize() - width, height = max(min_width, width), max(min_height, height) - self.Variable.SetSize(width, height) - clientsize = self.Preview.GetClientSize() - x = (clientsize.width - width) / 2 - y = (clientsize.height - height) / 2 - self.Variable.SetPosition(x, y) - self.Variable.Draw(dc) - - def OnPaint(self, event): - self.RefreshPreview() - event.Skip() - -#------------------------------------------------------------------------------- -# Create New Connection Dialog -#------------------------------------------------------------------------------- - -[ID_CONNECTIONPROPERTIESDIALOG, ID_CONNECTIONPROPERTIESDIALOGSPACER, - ID_CONNECTIONPROPERTIESDIALOGNAME, ID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON1, - ID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON2, ID_CONNECTIONPROPERTIESDIALOGPREVIEW, - ID_CONNECTIONPROPERTIESDIALOGSTATICTEXT1, ID_CONNECTIONPROPERTIESDIALOGSTATICTEXT2, - ID_CONNECTIONPROPERTIESDIALOGSTATICTEXT3, -] = [wx.NewId() for _init_ctrls in range(9)] - -class ConnectionPropertiesDialog(wx.Dialog): - - if wx.VERSION < (2, 6, 0): - def Bind(self, event, function, id = None): - if id is not None: - event(self, id, function) - else: - event(self, function) - - def _init_coll_flexGridSizer1_Items(self, parent): - parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) - parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) - - def _init_coll_flexGridSizer1_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(0) - - def _init_coll_MainSizer_Items(self, parent): - parent.AddSizer(self.LeftGridSizer, 1, border=5, flag=wx.GROW|wx.RIGHT) - parent.AddSizer(self.RightGridSizer, 1, border=5, flag=wx.GROW|wx.LEFT) - - def _init_coll_LeftGridSizer_Items(self, parent): - parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.radioButton1, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.radioButton2, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.ConnectionName, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW) - - def _init_coll_LeftGridSizer_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(5) - - def _init_coll_RightGridSizer_Items(self, parent): - parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW) - - def _init_coll_RightGridSizer_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(1) - - def _init_sizers(self): - self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) - self.MainSizer = wx.BoxSizer(wx.HORIZONTAL) - self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=6, vgap=5) - self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5) - - self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) - self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) - self._init_coll_MainSizer_Items(self.MainSizer) - self._init_coll_LeftGridSizer_Items(self.LeftGridSizer) - self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer) - self._init_coll_RightGridSizer_Items(self.RightGridSizer) - self._init_coll_RightGridSizer_Growables(self.RightGridSizer) - - self.SetSizer(self.flexGridSizer1) - - def _init_ctrls(self, prnt, ctrler): - wx.Dialog.__init__(self, id=ID_CONNECTIONPROPERTIESDIALOG, - name='ConnectionPropertiesDialog', parent=prnt, pos=wx.Point(376, 223), - size=wx.Size(350, 220), style=wx.DEFAULT_DIALOG_STYLE, - title=_('Connection Properties')) - self.SetClientSize(wx.Size(350, 220)) - - self.staticText1 = wx.StaticText(id=ID_CONNECTIONPROPERTIESDIALOGSTATICTEXT1, - label=_('Type:'), name='staticText1', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) - - self.staticText2 = wx.StaticText(id=ID_CONNECTIONPROPERTIESDIALOGSTATICTEXT2, - label=_('Name:'), name='staticText2', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) - - self.staticText3 = wx.StaticText(id=ID_CONNECTIONPROPERTIESDIALOGSTATICTEXT3, - label=_('Preview:'), name='staticText3', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) - - self.radioButton1 = wx.RadioButton(id=ID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON1, - label=_('Connector'), name='radioButton1', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.RB_GROUP) - self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON1) - self.radioButton1.SetValue(True) - - self.radioButton2 = wx.RadioButton(id=ID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON2, - label=_('Continuation'), name='radioButton2', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) - self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON2) - self.radioButton2.SetValue(False) - - self.ConnectionName = wx.TextCtrl(id=ID_CONNECTIONPROPERTIESDIALOGNAME, - name='Name', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 24), style=0) - self.Bind(wx.EVT_TEXT, self.OnNameChanged, id=ID_CONNECTIONPROPERTIESDIALOGNAME) - - self.Preview = wx.Panel(id=ID_CONNECTIONPROPERTIESDIALOGPREVIEW, - name='Preview', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 0), 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, "IsOfType", ctrler.IsOfType) - - self.Spacer = wx.Panel(id=ID_CONNECTIONPROPERTIESDIALOGSPACER, - name='Spacer', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) - - self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) - if wx.VERSION >= (2, 5, 0): - self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId()) - self.Preview.Bind(wx.EVT_PAINT, self.OnPaint) - else: - self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId()) - wx.EVT_PAINT(self.Preview, self.OnPaint) - - self._init_sizers() - - def __init__(self, parent, controler): - self._init_ctrls(parent, controler) - self.Connection = None - self.MinConnectionSize = None - - self.PouNames = [] - self.PouElementNames = [] - - def SetPreviewFont(self, font): - self.Preview.SetFont(font) - - def SetMinConnectionSize(self, size): - self.MinConnectionSize = size - - def SetValues(self, values): - for name, value in values.items(): - if name == "type": - if value == CONNECTOR: - self.radioButton1.SetValue(True) - elif value == CONTINUATION: - self.radioButton2.SetValue(True) - elif name == "name": - self.ConnectionName.SetValue(value) - self.RefreshPreview() - - def GetValues(self): - values = {} - if self.radioButton1.GetValue(): - values["type"] = CONNECTOR - else: - values["type"] = CONTINUATION - values["name"] = self.ConnectionName.GetValue() - values["width"], values["height"] = self.Connection.GetSize() - return values - - 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] - - def OnOK(self, event): - connection_name = self.ConnectionName.GetValue() - if connection_name == "": - message = wx.MessageDialog(self, _("Form isn't complete. Name must be filled!"), _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - elif not TestIdentifier(connection_name): - message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%connection_name, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - elif connection_name.upper() in IEC_KEYWORDS: - message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%connection_name, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - elif connection_name.upper() in self.PouNames: - message = wx.MessageDialog(self, _("\"%s\" pou already exists!")%connection_name, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - elif connection_name.upper() in self.PouElementNames: - message = wx.MessageDialog(self, _("\"%s\" element for this pou already exists!")%connection_name, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - else: - self.EndModal(wx.ID_OK) - - def OnTypeChanged(self, event): - self.RefreshPreview() - event.Skip() - - def OnNameChanged(self, event): - self.RefreshPreview() - event.Skip() - - def RefreshPreview(self): - dc = wx.ClientDC(self.Preview) - dc.SetFont(self.Preview.GetFont()) - dc.Clear() - if self.radioButton1.GetValue(): - self.Connection = FBD_Connector(self.Preview, CONNECTOR, self.ConnectionName.GetValue()) - else: - self.Connection = FBD_Connector(self.Preview, CONTINUATION, self.ConnectionName.GetValue()) - width, height = self.MinConnectionSize - min_width, min_height = self.Connection.GetMinSize() - width, height = max(min_width, width), max(min_height, height) - self.Connection.SetSize(width, height) - clientsize = self.Preview.GetClientSize() - x = (clientsize.width - width) / 2 - y = (clientsize.height - height) / 2 - self.Connection.SetPosition(x, y) - self.Connection.Draw(dc) - - def OnPaint(self, event): - self.RefreshPreview() - event.Skip() - -#------------------------------------------------------------------------------- -# Edit Ladder Element Properties Dialog -#------------------------------------------------------------------------------- - - -[ID_LDELEMENTDIALOG, ID_LDELEMENTDIALOGSPACER, - ID_LDELEMENTDIALOGNAME, ID_LDELEMENTDIALOGRADIOBUTTON1, - ID_LDELEMENTDIALOGRADIOBUTTON2, ID_LDELEMENTDIALOGRADIOBUTTON3, - ID_LDELEMENTDIALOGRADIOBUTTON4, ID_LDELEMENTDIALOGRADIOBUTTON5, - ID_LDELEMENTDIALOGRADIOBUTTON6, ID_LDELEMENTDIALOGPREVIEW, - ID_LDELEMENTDIALOGSTATICTEXT1, ID_LDELEMENTDIALOGSTATICTEXT2, - ID_LDELEMENTDIALOGSTATICTEXT3, -] = [wx.NewId() for _init_ctrls in range(13)] - -class LDElementDialog(wx.Dialog): - - if wx.VERSION < (2, 6, 0): - def Bind(self, event, function, id = None): - if id is not None: - event(self, id, function) - else: - event(self, function) - - def _init_coll_flexGridSizer1_Items(self, parent): - parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) - parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) - - def _init_coll_flexGridSizer1_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(0) - - def _init_coll_MainSizer_Items(self, parent): - parent.AddSizer(self.LeftGridSizer, 1, border=5, flag=wx.GROW|wx.RIGHT) - parent.AddSizer(self.RightGridSizer, 1, border=5, flag=wx.GROW|wx.LEFT) - - def _init_coll_LeftGridSizer_Items(self, parent): - parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW) - parent.AddSizer(self.RadioButtonSizer, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.ElementName, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW) - - def _init_coll_LeftGridSizer_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(7) - - def _init_coll_RadioButtonSizer_Items(self, parent): - parent.AddWindow(self.radioButton1, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.radioButton2, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.radioButton3, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.radioButton4, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.radioButton5, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.radioButton6, 0, border=0, flag=wx.GROW) - - def _init_coll_RightGridSizer_Items(self, parent): - parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW) - - def _init_coll_RightGridSizer_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(1) - - def _init_sizers(self): - self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) - self.MainSizer = wx.BoxSizer(wx.HORIZONTAL) - self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=5, vgap=5) - self.RadioButtonSizer = wx.BoxSizer(wx.VERTICAL) - self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5) - - self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) - self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) - self._init_coll_MainSizer_Items(self.MainSizer) - self._init_coll_LeftGridSizer_Items(self.LeftGridSizer) - self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer) - self._init_coll_RadioButtonSizer_Items(self.RadioButtonSizer) - self._init_coll_RightGridSizer_Items(self.RightGridSizer) - self._init_coll_RightGridSizer_Growables(self.RightGridSizer) - - self.SetSizer(self.flexGridSizer1) - - def _init_ctrls(self, prnt, ctrler, title, extra_size = 0): - wx.Dialog.__init__(self, id=ID_LDELEMENTDIALOG, - name='LDElementDialog', parent=prnt, pos=wx.Point(376, 223), - size=wx.Size(350, 260 + extra_size), style=wx.DEFAULT_DIALOG_STYLE, - title=title) - self.SetClientSize(wx.Size(350, 260 + extra_size)) - - self.staticText1 = wx.StaticText(id=ID_LDELEMENTDIALOGSTATICTEXT1, - label=_('Modifier:'), name='staticText1', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) - - self.staticText2 = wx.StaticText(id=ID_LDELEMENTDIALOGSTATICTEXT2, - label=_('Name:'), name='staticText2', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) - - self.staticText3 = wx.StaticText(id=ID_LDELEMENTDIALOGSTATICTEXT3, - label=_('Preview:'), name='staticText3', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) - - self.radioButton1 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON1, - label=_("Normal"), name='radioButton1', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.RB_GROUP) - self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON1) - self.radioButton1.SetValue(True) - - self.radioButton2 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON2, - label=_("Negated"), name='radioButton2', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) - self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON2) - - self.radioButton3 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON3, - label=_("Set"), name='radioButton3', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) - self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON3) - - self.radioButton4 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON4, - label=_("Reset"), name='radioButton4', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) - self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON4) - - self.radioButton5 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON5, - label=_("Rising Edge"), name='radioButton5', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) - self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON5) - - self.radioButton6 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON6, - label=_("Falling Edge"), name='radioButton6', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) - self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON6) - - self.ElementName = wx.ComboBox(id=ID_LDELEMENTDIALOGNAME, - name='Name', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 28), style=wx.CB_READONLY) - self.Bind(wx.EVT_COMBOBOX, self.OnNameChanged, id=ID_LDELEMENTDIALOGNAME) - - self.Preview = wx.Panel(id=ID_LDELEMENTDIALOGPREVIEW, - name='Preview', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 0), 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, "IsOfType", ctrler.IsOfType) - - self.Spacer = wx.Panel(id=ID_LDELEMENTDIALOGSPACER, - name='Spacer', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) - - self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) - - if wx.VERSION >= (2, 5, 0): - self.Preview.Bind(wx.EVT_PAINT, self.OnPaint) - else: - wx.EVT_PAINT(self.Preview, self.OnPaint) - - self._init_sizers() - - def __init__(self, parent, controler, type): - self.Type = type - if type == "contact": - self._init_ctrls(parent, controler, _("Edit Contact Values")) - self.Element = LD_Contact(self.Preview, CONTACT_NORMAL, "") - self.radioButton3.Hide() - self.radioButton4.Hide() - elif type == "coil": - self._init_ctrls(parent, controler, _("Edit Coil Values"), 50) - self.Element = LD_Coil(self.Preview, COIL_NORMAL, "") - - - def SetPreviewFont(self, font): - self.Preview.SetFont(font) - - def SetElementSize(self, size): - min_width, min_height = self.Element.GetMinSize() - width, height = max(min_width, size[0]), max(min_height, size[1]) - self.Element.SetSize(width, height) - - def SetVariables(self, vars): - self.ElementName.Clear() - for name in vars: - self.ElementName.Append(name) - self.ElementName.Enable(self.ElementName.GetCount() > 0) - - def SetValues(self, values): - for name, value in values.items(): - if name == "name": - self.Element.SetName(value) - self.ElementName.SetStringSelection(value) - elif name == "type": - self.Element.SetType(value) - if self.Type == "contact": - if value == CONTACT_NORMAL: - self.radioButton1.SetValue(True) - elif value == CONTACT_REVERSE: - self.radioButton2.SetValue(True) - elif value == CONTACT_RISING: - self.radioButton5.SetValue(True) - elif value == CONTACT_FALLING: - self.radioButton6.SetValue(True) - elif self.Type == "coil": - if value == COIL_NORMAL: - self.radioButton1.SetValue(True) - elif value == COIL_REVERSE: - self.radioButton2.SetValue(True) - elif value == COIL_SET: - self.radioButton3.SetValue(True) - elif value == COIL_RESET: - self.radioButton4.SetValue(True) - elif value == COIL_RISING: - self.radioButton5.SetValue(True) - elif value == COIL_FALLING: - self.radioButton6.SetValue(True) - - def GetValues(self): - values = {} - values["name"] = self.Element.GetName() - values["type"] = self.Element.GetType() - values["width"], values["height"] = self.Element.GetSize() - return values - - def OnTypeChanged(self, event): - if self.Type == "contact": - if self.radioButton1.GetValue(): - self.Element.SetType(CONTACT_NORMAL) - elif self.radioButton2.GetValue(): - self.Element.SetType(CONTACT_REVERSE) - elif self.radioButton5.GetValue(): - self.Element.SetType(CONTACT_RISING) - elif self.radioButton6.GetValue(): - self.Element.SetType(CONTACT_FALLING) - elif self.Type == "coil": - if self.radioButton1.GetValue(): - self.Element.SetType(COIL_NORMAL) - elif self.radioButton2.GetValue(): - self.Element.SetType(COIL_REVERSE) - elif self.radioButton3.GetValue(): - self.Element.SetType(COIL_SET) - elif self.radioButton4.GetValue(): - self.Element.SetType(COIL_RESET) - elif self.radioButton5.GetValue(): - self.Element.SetType(COIL_RISING) - elif self.radioButton6.GetValue(): - self.Element.SetType(COIL_FALLING) - self.RefreshPreview() - event.Skip() - - def OnNameChanged(self, event): - self.Element.SetName(self.ElementName.GetStringSelection()) - self.RefreshPreview() - event.Skip() - - def RefreshPreview(self): - dc = wx.ClientDC(self.Preview) - dc.SetFont(self.Preview.GetFont()) - dc.Clear() - clientsize = self.Preview.GetClientSize() - width, height = self.Element.GetSize() - self.Element.SetPosition((clientsize.width - width) / 2, (clientsize.height - height) / 2) - self.Element.Draw(dc) - - def OnPaint(self, event): - self.RefreshPreview() - event.Skip() - - -#------------------------------------------------------------------------------- -# Edit Ladder Power Rail Properties Dialog -#------------------------------------------------------------------------------- - - -[ID_LDPOWERRAILDIALOG, ID_LDPOWERRAILDIALOGSPACER, - ID_LDPOWERRAILDIALOGTYPE, ID_LDPOWERRAILDIALOGRADIOBUTTON1, - ID_LDPOWERRAILDIALOGRADIOBUTTON2, ID_LDPOWERRAILDIALOGPREVIEW, - ID_LDPOWERRAILDIALOGSTATICTEXT1, ID_LDPOWERRAILDIALOGSTATICTEXT2, - ID_LDPOWERRAILDIALOGSTATICTEXT3, ID_LDPOWERRAILDIALOGPINNUMBER, -] = [wx.NewId() for _init_ctrls in range(10)] - -class LDPowerRailDialog(wx.Dialog): - - if wx.VERSION < (2, 6, 0): - def Bind(self, event, function, id = None): - if id is not None: - event(self, id, function) - else: - event(self, function) - - def _init_coll_flexGridSizer1_Items(self, parent): - parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) - parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) - - def _init_coll_flexGridSizer1_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(0) - - def _init_coll_MainSizer_Items(self, parent): - parent.AddSizer(self.LeftGridSizer, 1, border=5, flag=wx.GROW|wx.RIGHT) - parent.AddSizer(self.RightGridSizer, 1, border=5, flag=wx.GROW|wx.LEFT) - - def _init_coll_LeftGridSizer_Items(self, parent): - parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.radioButton1, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.radioButton2, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.PinNumber, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW) - - def _init_coll_LeftGridSizer_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(5) - - def _init_coll_RightGridSizer_Items(self, parent): - parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW) - - def _init_coll_RightGridSizer_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(1) - - def _init_sizers(self): - self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) - self.MainSizer = wx.BoxSizer(wx.HORIZONTAL) - self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=6, vgap=5) - self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5) - - self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) - self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) - self._init_coll_MainSizer_Items(self.MainSizer) - self._init_coll_LeftGridSizer_Items(self.LeftGridSizer) - self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer) - self._init_coll_RightGridSizer_Items(self.RightGridSizer) - self._init_coll_RightGridSizer_Growables(self.RightGridSizer) - - self.SetSizer(self.flexGridSizer1) - - def _init_ctrls(self, prnt, ctrler): - wx.Dialog.__init__(self, id=ID_LDPOWERRAILDIALOG, - name='PowerRailDialog', parent=prnt, pos=wx.Point(376, 223), - size=wx.Size(350, 260), style=wx.DEFAULT_DIALOG_STYLE, - title=_('Power Rail Properties')) - self.SetClientSize(wx.Size(350, 260)) - - self.staticText1 = wx.StaticText(id=ID_LDPOWERRAILDIALOGSTATICTEXT1, - label=_('Type:'), name='staticText1', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) - - self.staticText2 = wx.StaticText(id=ID_LDPOWERRAILDIALOGSTATICTEXT2, - label=_('Pin number:'), name='staticText2', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) - - self.staticText3 = wx.StaticText(id=ID_LDPOWERRAILDIALOGSTATICTEXT3, - label=_('Preview:'), name='staticText3', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) - - self.radioButton1 = wx.RadioButton(id=ID_LDPOWERRAILDIALOGRADIOBUTTON1, - label=_('Left PowerRail'), name='radioButton1', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.RB_GROUP) - self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDPOWERRAILDIALOGRADIOBUTTON1) - self.radioButton1.SetValue(True) - - self.radioButton2 = wx.RadioButton(id=ID_LDPOWERRAILDIALOGRADIOBUTTON2, - label=_('Right PowerRail'), name='radioButton2', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) - self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDPOWERRAILDIALOGRADIOBUTTON2) - - self.PinNumber = wx.SpinCtrl(id=ID_LDPOWERRAILDIALOGPINNUMBER, - name='PinNumber', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=1, max=50) - self.Bind(wx.EVT_SPINCTRL, self.OnPinNumberChanged, id=ID_LDPOWERRAILDIALOGPINNUMBER) - - self.Preview = wx.Panel(id=ID_LDPOWERRAILDIALOGPREVIEW, - name='Preview', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 0), 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, "IsOfType", ctrler.IsOfType) - - self.Spacer = wx.Panel(id=ID_LDELEMENTDIALOGSPACER, - name='Spacer', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) - - self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) - - if wx.VERSION >= (2, 5, 0): - self.Preview.Bind(wx.EVT_PAINT, self.OnPaint) - else: - wx.EVT_PAINT(self.Preview, self.OnPaint) - - self._init_sizers() - - def __init__(self, parent, controler, type = LEFTRAIL, number = 1): - self._init_ctrls(parent, controler) - self.Type = type - if type == LEFTRAIL: - self.radioButton1.SetValue(True) - elif type == RIGHTRAIL: - self.radioButton2.SetValue(True) - self.PinNumber.SetValue(number) - - self.PowerRailMinSize = (0, 0) - self.PowerRail = None - - def SetPreviewFont(self, font): - self.Preview.SetFont(font) - - def SetMinSize(self, size): - self.PowerRailMinSize = size - self.RefreshPreview() - - def GetValues(self): - values = {} - values["type"] = self.Type - values["number"] = self.PinNumber.GetValue() - values["width"], values["height"] = self.PowerRail.GetSize() - return values - - def OnTypeChanged(self, event): - if self.radioButton1.GetValue(): - self.Type = LEFTRAIL - elif self.radioButton2.GetValue(): - self.Type = RIGHTRAIL - self.RefreshPreview() - event.Skip() - - def OnPinNumberChanged(self, event): - self.RefreshPreview() - event.Skip() - - def RefreshPreview(self): - dc = wx.ClientDC(self.Preview) - dc.SetFont(self.Preview.GetFont()) - dc.Clear() - self.PowerRail = LD_PowerRail(self.Preview, self.Type, connectors = [True for i in xrange(self.PinNumber.GetValue())]) - min_width, min_height = 2, LD_LINE_SIZE * self.PinNumber.GetValue() - width, height = max(min_width, self.PowerRailMinSize[0]), max(min_height, self.PowerRailMinSize[1]) - self.PowerRail.SetSize(width, height) - clientsize = self.Preview.GetClientSize() - self.PowerRail.SetPosition((clientsize.width - width) / 2, (clientsize.height - height) / 2) - self.PowerRail.Draw(dc) - - def OnPaint(self, event): - self.RefreshPreview() - event.Skip() - - -#------------------------------------------------------------------------------- -# Edit Step Content Dialog -#------------------------------------------------------------------------------- - -[ID_STEPCONTENTDIALOG, ID_STEPCONTENTDIALOGSPACER, - ID_STEPCONTENTDIALOGNAME, ID_STEPCONTENTDIALOGPREVIEW, - ID_STEPCONTENTDIALOGCHECKBOX1, ID_STEPCONTENTDIALOGCHECKBOX2, - ID_STEPCONTENTDIALOGCHECKBOX3, ID_STEPCONTENTDIALOGSTATICTEXT1, - ID_STEPCONTENTDIALOGSTATICTEXT2, ID_STEPCONTENTDIALOGSTATICTEXT3, -] = [wx.NewId() for _init_ctrls in range(10)] - -class StepContentDialog(wx.Dialog): - - if wx.VERSION < (2, 6, 0): - def Bind(self, event, function, id = None): - if id is not None: - event(self, id, function) - else: - event(self, function) - - def _init_coll_flexGridSizer1_Items(self, parent): - parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) - parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) - - def _init_coll_flexGridSizer1_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(0) - - def _init_coll_MainSizer_Items(self, parent): - parent.AddSizer(self.LeftGridSizer, 1, border=5, flag=wx.GROW|wx.RIGHT) - parent.AddSizer(self.RightGridSizer, 1, border=5, flag=wx.GROW|wx.LEFT) - - def _init_coll_LeftGridSizer_Items(self, parent): - parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.StepName, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.checkBox1, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.checkBox2, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.checkBox3, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW) - - def _init_coll_LeftGridSizer_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(6) - - def _init_coll_RightGridSizer_Items(self, parent): - parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW) - - def _init_coll_RightGridSizer_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(1) - - def _init_sizers(self): - self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) - self.MainSizer = wx.BoxSizer(wx.HORIZONTAL) - self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=7, vgap=5) - self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5) - - self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) - self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) - self._init_coll_MainSizer_Items(self.MainSizer) - self._init_coll_LeftGridSizer_Items(self.LeftGridSizer) - self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer) - self._init_coll_RightGridSizer_Items(self.RightGridSizer) - self._init_coll_RightGridSizer_Growables(self.RightGridSizer) - - self.SetSizer(self.flexGridSizer1) - - def _init_ctrls(self, prnt, ctrler): - wx.Dialog.__init__(self, id=ID_STEPCONTENTDIALOG, - name='StepContentDialog', parent=prnt, pos=wx.Point(376, 223), - size=wx.Size(400, 250), style=wx.DEFAULT_DIALOG_STYLE, - title=_('Edit Step')) - self.SetClientSize(wx.Size(400, 250)) - - self.staticText1 = wx.StaticText(id=ID_STEPCONTENTDIALOGSTATICTEXT1, - label=_('Name:'), name='staticText1', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) - - self.staticText2 = wx.StaticText(id=ID_STEPCONTENTDIALOGSTATICTEXT2, - label=_('Connectors:'), name='staticText2', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) - - self.staticText3 = wx.StaticText(id=ID_STEPCONTENTDIALOGSTATICTEXT3, - label=_('Preview:'), name='staticText4', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) - - self.StepName = wx.TextCtrl(id=ID_STEPCONTENTDIALOGNAME, - name='Name', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 24), style=0) - self.Bind(wx.EVT_TEXT, self.OnNameChanged, id=ID_STEPCONTENTDIALOGNAME) - - self.checkBox1 = wx.CheckBox(id=ID_STEPCONTENTDIALOGCHECKBOX1, - label=_("Input"), name='checkBox1', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) - self.Bind(wx.EVT_CHECKBOX, self.OnConnectorsChanged, id=ID_STEPCONTENTDIALOGCHECKBOX1) - - self.checkBox2 = wx.CheckBox(id=ID_STEPCONTENTDIALOGCHECKBOX2, - label=_("Output"), name='checkBox2', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) - self.Bind(wx.EVT_CHECKBOX, self.OnConnectorsChanged, id=ID_STEPCONTENTDIALOGCHECKBOX2) - - self.checkBox3 = wx.CheckBox(id=ID_STEPCONTENTDIALOGCHECKBOX3, - label=_("Action"), name='checkBox3', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) - self.Bind(wx.EVT_CHECKBOX, self.OnConnectorsChanged, id=ID_STEPCONTENTDIALOGCHECKBOX3) - - self.Spacer = wx.Panel(id=ID_STEPCONTENTDIALOGSPACER, - name='Spacer', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) - - self.Preview = wx.Panel(id=ID_STEPCONTENTDIALOGPREVIEW, - name='Preview', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 0), 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, "RefreshStepModel", lambda x:None) - setattr(self.Preview, "GetScaling", lambda:None) - setattr(self.Preview, "IsOfType", ctrler.IsOfType) - - self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) - if wx.VERSION >= (2, 5, 0): - self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId()) - self.Preview.Bind(wx.EVT_PAINT, self.OnPaint) - else: - self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId()) - wx.EVT_PAINT(self.Preview, self.OnPaint) - - self._init_sizers() - - def __init__(self, parent, controler, initial = False): - self._init_ctrls(parent, controler) - self.Step = None - self.Initial = initial - self.MinStepSize = None - - self.PouNames = [] - self.Variables = [] - self.StepNames = [] - - def SetPreviewFont(self, font): - self.Preview.SetFont(font) - - def OnOK(self, event): - step_name = self.StepName.GetValue() - if step_name == "": - message = wx.MessageDialog(self, _("You must type a name!"), _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - elif not TestIdentifier(step_name): - message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - elif step_name.upper() in IEC_KEYWORDS: - message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - elif step_name.upper() in self.PouNames: - message = wx.MessageDialog(self, _("A POU named \"%s\" already exists!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - elif step_name.upper() in self.Variables: - message = wx.MessageDialog(self, _("A variable with \"%s\" as name already exists in this pou!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - elif step_name.upper() in self.StepNames: - message = wx.MessageDialog(self, _("\"%s\" step already exists!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - else: - self.EndModal(wx.ID_OK) - - def SetMinStepSize(self, size): - self.MinStepSize = size - - def SetPouNames(self, pou_names): - self.PouNames = [pou_name.upper() for pou_name in pou_names] - - def SetVariables(self, variables): - self.Variables = [var["Name"].upper() for var in variables] - - def SetStepNames(self, step_names): - self.StepNames = [step_name.upper() for step_name in step_names] - - def SetValues(self, values): - value_name = values.get("name", None) - if value_name: - self.StepName.SetValue(value_name) - else: - self.StepName.SetValue("") - self.checkBox1.SetValue(values.get("input", False)) - self.checkBox2.SetValue(values.get("output", False)) - self.checkBox3.SetValue(values.get("action", False)) - self.RefreshPreview() - - def GetValues(self): - values = {} - values["name"] = self.StepName.GetValue() - values["input"] = self.checkBox1.IsChecked() - values["output"] = self.checkBox2.IsChecked() - values["action"] = self.checkBox3.IsChecked() - values["width"], values["height"] = self.Step.GetSize() - return values - - def OnConnectorsChanged(self, event): - self.RefreshPreview() - event.Skip() - - def OnNameChanged(self, event): - self.RefreshPreview() - event.Skip() - - def RefreshPreview(self): - dc = wx.ClientDC(self.Preview) - dc.SetFont(self.Preview.GetFont()) - dc.Clear() - self.Step = SFC_Step(self.Preview, self.StepName.GetValue(), self.Initial) - if self.checkBox1.IsChecked(): - self.Step.AddInput() - else: - self.Step.RemoveInput() - if self.checkBox2.IsChecked(): - self.Step.AddOutput() - else: - self.Step.RemoveOutput() - if self.checkBox3.IsChecked(): - self.Step.AddAction() - else: - self.Step.RemoveAction() - width, height = self.MinStepSize - min_width, min_height = self.Step.GetMinSize() - width, height = max(min_width, width), max(min_height, height) - self.Step.SetSize(width, height) - clientsize = self.Preview.GetClientSize() - x = (clientsize.width - width) / 2 - y = (clientsize.height - height) / 2 - self.Step.SetPosition(x, y) - self.Step.Draw(dc) - - def OnPaint(self, event): - self.RefreshPreview() - event.Skip() - -#------------------------------------------------------------------------------- -# Edit Transition Content Dialog -#------------------------------------------------------------------------------- - -[ID_TRANSITIONCONTENTDIALOG, ID_TRANSITIONCONTENTDIALOGSPACER, - ID_TRANSITIONCONTENTDIALOGREFERENCE, ID_TRANSITIONCONTENTDIALOGINLINE, - ID_TRANSITIONCONTENTDIALOGPRIORITY, ID_TRANSITIONCONTENTDIALOGPREVIEW, - ID_TRANSITIONCONTENTDIALOGRADIOBUTTON1, ID_TRANSITIONCONTENTDIALOGRADIOBUTTON2, - ID_TRANSITIONCONTENTDIALOGRADIOBUTTON3, ID_TRANSITIONCONTENTDIALOGSTATICTEXT1, - ID_TRANSITIONCONTENTDIALOGSTATICTEXT2, ID_TRANSITIONCONTENTDIALOGSTATICTEXT3, -] = [wx.NewId() for _init_ctrls in range(12)] - -class TransitionContentDialog(wx.Dialog): - - if wx.VERSION < (2, 6, 0): - def Bind(self, event, function, id = None): - if id is not None: - event(self, id, function) - else: - event(self, function) - - def _init_coll_flexGridSizer1_Items(self, parent): - parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) - parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) - - def _init_coll_flexGridSizer1_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(0) - - def _init_coll_MainSizer_Items(self, parent): - parent.AddSizer(self.LeftGridSizer, 1, border=5, flag=wx.GROW|wx.RIGHT) - parent.AddSizer(self.RightGridSizer, 1, border=5, flag=wx.GROW|wx.LEFT) - - def _init_coll_LeftGridSizer_Items(self, parent): - parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.radioButton1, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.Reference, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.radioButton2, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.Inline, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.radioButton3, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.Priority, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW) - - def _init_coll_LeftGridSizer_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(6) - - def _init_coll_RightGridSizer_Items(self, parent): - parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW) - - def _init_coll_RightGridSizer_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(1) - - def _init_sizers(self): - self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) - self.MainSizer = wx.BoxSizer(wx.HORIZONTAL) - self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=9, vgap=5) - self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5) - - self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) - self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) - self._init_coll_MainSizer_Items(self.MainSizer) - self._init_coll_LeftGridSizer_Items(self.LeftGridSizer) - self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer) - self._init_coll_RightGridSizer_Items(self.RightGridSizer) - self._init_coll_RightGridSizer_Growables(self.RightGridSizer) - - self.SetSizer(self.flexGridSizer1) - - def _init_ctrls(self, prnt, ctrler): - wx.Dialog.__init__(self, id=ID_TRANSITIONCONTENTDIALOG, - name='ProjectDialog', parent=prnt, pos=wx.Point(376, 223), - size=wx.Size(350, 300), style=wx.DEFAULT_DIALOG_STYLE, - title=_('Edit transition')) - self.SetClientSize(wx.Size(350, 300)) - - self.staticText1 = wx.StaticText(id=ID_TRANSITIONCONTENTDIALOGSTATICTEXT1, - label=_('Type:'), name='staticText1', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) - - self.staticText2 = wx.StaticText(id=ID_TRANSITIONCONTENTDIALOGSTATICTEXT2, - label=_('Preview:'), name='staticText2', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) - - self.staticText3 = wx.StaticText(id=ID_TRANSITIONCONTENTDIALOGSTATICTEXT3, - label=_('Priority:'), name='staticText3', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) - - self.radioButton1 = wx.RadioButton(id=ID_TRANSITIONCONTENTDIALOGRADIOBUTTON1, - label=_('Reference'), name='radioButton1', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.RB_GROUP) - self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_TRANSITIONCONTENTDIALOGRADIOBUTTON1) - self.radioButton1.SetValue(True) - - self.Reference = wx.ComboBox(id=ID_TRANSITIONCONTENTDIALOGREFERENCE, - name='Reference', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 28), style=wx.CB_READONLY) - self.Bind(wx.EVT_COMBOBOX, self.OnReferenceChanged, id=ID_TRANSITIONCONTENTDIALOGREFERENCE) - - self.radioButton2 = wx.RadioButton(id=ID_TRANSITIONCONTENTDIALOGRADIOBUTTON2, - label=_('Inline'), name='radioButton2', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) - self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_TRANSITIONCONTENTDIALOGRADIOBUTTON2) - self.radioButton2.SetValue(False) - - self.Inline = wx.TextCtrl(id=ID_TRANSITIONCONTENTDIALOGINLINE, - name='Inline', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 24), style=0) - self.Bind(wx.EVT_TEXT, self.OnInlineChanged, id=ID_TRANSITIONCONTENTDIALOGINLINE) - self.Inline.Enable(False) - - self.radioButton3 = wx.RadioButton(id=ID_TRANSITIONCONTENTDIALOGRADIOBUTTON3, - label=_('Connection'), name='radioButton3', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) - self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_TRANSITIONCONTENTDIALOGRADIOBUTTON3) - self.radioButton3.SetValue(False) - if not self.Connection: - self.radioButton3.Hide() - - self.Priority = wx.SpinCtrl(id=ID_TRANSITIONCONTENTDIALOGPRIORITY, - name='Priority', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0) - self.Bind(wx.EVT_TEXT, self.OnPriorityChanged, id=ID_TRANSITIONCONTENTDIALOGPRIORITY) - - self.Preview = wx.Panel(id=ID_TRANSITIONCONTENTDIALOGPREVIEW, - name='Preview', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 0), 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, "RefreshTransitionModel", lambda x:None) - setattr(self.Preview, "GetScaling", lambda:None) - setattr(self.Preview, "IsOfType", ctrler.IsOfType) - - self.Spacer = wx.Panel(id=ID_TRANSITIONCONTENTDIALOGSPACER, - name='Spacer', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) - - self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) - if wx.VERSION >= (2, 5, 0): - self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId()) - self.Preview.Bind(wx.EVT_PAINT, self.OnPaint) - else: - self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId()) - wx.EVT_PAINT(self.Preview, self.OnPaint) - - self._init_sizers() - - def __init__(self, parent, controler, connection): - self.Connection = connection - self._init_ctrls(parent, controler) - self.Transition = None - self.MinTransitionSize = None - - self.Element = SFC_Transition(self.Preview) - - def SetPreviewFont(self, font): - self.Preview.SetFont(font) - - def SetElementSize(self, size): - min_width, min_height = self.Element.GetMinSize() - width, height = max(min_width, size[0]), max(min_height, size[1]) - self.Element.SetSize(width, height) - - def OnOK(self, event): - error = [] - if self.radioButton1.GetValue() and self.Reference.GetStringSelection() == "": - error.append(_("Reference")) - if self.radioButton2.GetValue() and self.Inline.GetValue() == "": - error.append(_("Inline")) - if len(error) > 0: - text = "" - for i, item in enumerate(error): - if i == 0: - text += item - elif i == len(error) - 1: - text += _(" and %s")%item - else: - text += _(", %s")%item - message = wx.MessageDialog(self, _("Form isn't complete. %s must be filled!")%text, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - else: - self.EndModal(wx.ID_OK) - - def OnTypeChanged(self, event): - if self.radioButton1.GetValue(): - self.Element.SetType("reference", self.Reference.GetStringSelection()) - self.Reference.Enable(True) - self.Inline.Enable(False) - elif self.radioButton2.GetValue(): - self.Element.SetType("inline", self.Inline.GetValue()) - self.Reference.Enable(False) - self.Inline.Enable(True) - else: - self.Element.SetType("connection") - self.Reference.Enable(False) - self.Inline.Enable(False) - self.RefreshPreview() - event.Skip() - - def OnReferenceChanged(self, event): - self.Element.SetType("reference", self.Reference.GetStringSelection()) - self.RefreshPreview() - event.Skip() - - def OnInlineChanged(self, event): - self.Element.SetType("inline", self.Inline.GetValue()) - self.RefreshPreview() - event.Skip() - - def OnPriorityChanged(self, event): - self.Element.SetPriority(int(self.Priority.GetValue())) - self.RefreshPreview() - event.Skip() - - def SetTransitions(self, transitions): - self.Reference.Append("") - for transition in transitions: - self.Reference.Append(transition) - - def SetValues(self, values): - if values["type"] == "reference": - self.radioButton1.SetValue(True) - self.radioButton2.SetValue(False) - self.radioButton3.SetValue(False) - self.Reference.Enable(True) - self.Inline.Enable(False) - self.Reference.SetStringSelection(values["value"]) - self.Element.SetType("reference", values["value"]) - elif values["type"] == "inline": - self.radioButton1.SetValue(False) - self.radioButton2.SetValue(True) - self.radioButton3.SetValue(False) - self.Reference.Enable(False) - self.Inline.Enable(True) - self.Inline.SetValue(values["value"]) - self.Element.SetType("inline", values["value"]) - elif values["type"] == "connection" and self.Connection: - self.radioButton1.SetValue(False) - self.radioButton2.SetValue(False) - self.radioButton3.SetValue(True) - self.Reference.Enable(False) - self.Inline.Enable(False) - self.Element.SetType("connection") - self.Priority.SetValue(values["priority"]) - self.Element.SetPriority(values["priority"]) - self.RefreshPreview() - - def GetValues(self): - values = {"priority" : int(self.Priority.GetValue())} - if self.radioButton1.GetValue(): - values["type"] = "reference" - values["value"] = self.Reference.GetStringSelection() - elif self.radioButton2.GetValue(): - values["type"] = "inline" - values["value"] = self.Inline.GetValue() - else: - values["type"] = "connection" - values["value"] = None - return values - - def RefreshPreview(self): - dc = wx.ClientDC(self.Preview) - dc.SetFont(self.Preview.GetFont()) - dc.Clear() - clientsize = self.Preview.GetClientSize() - posx, posy = self.Element.GetPosition() - rect = self.Element.GetBoundingBox() - diffx, diffy = posx - rect.x, posy - rect.y - self.Element.SetPosition((clientsize.width - rect.width) / 2 + diffx, (clientsize.height - rect.height) / 2 + diffy) - self.Element.Draw(dc) - - def OnPaint(self, event): - self.RefreshPreview() - event.Skip() - -#------------------------------------------------------------------------------- -# Create New Divergence Dialog -#------------------------------------------------------------------------------- - -[ID_DIVERGENCECREATEDIALOG, ID_DIVERGENCECREATEDIALOGSPACER, - ID_DIVERGENCECREATEDIALOGRADIOBUTTON1, ID_DIVERGENCECREATEDIALOGRADIOBUTTON2, - ID_DIVERGENCECREATEDIALOGRADIOBUTTON3, ID_DIVERGENCECREATEDIALOGRADIOBUTTON4, - ID_DIVERGENCECREATEDIALOGSEQUENCES, ID_DIVERGENCECREATEDIALOGPREVIEW, - ID_DIVERGENCECREATEDIALOGSTATICTEXT1, ID_DIVERGENCECREATEDIALOGSTATICTEXT2, - ID_DIVERGENCECREATEDIALOGSTATICTEXT3, -] = [wx.NewId() for _init_ctrls in range(11)] - -class DivergenceCreateDialog(wx.Dialog): - - if wx.VERSION < (2, 6, 0): - def Bind(self, event, function, id = None): - if id is not None: - event(self, id, function) - else: - event(self, function) - - def _init_coll_flexGridSizer1_Items(self, parent): - parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) - parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) - - def _init_coll_flexGridSizer1_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(0) - - def _init_coll_MainSizer_Items(self, parent): - parent.AddSizer(self.LeftGridSizer, 1, border=5, flag=wx.GROW|wx.RIGHT) - parent.AddSizer(self.RightGridSizer, 1, border=5, flag=wx.GROW|wx.LEFT) - - def _init_coll_LeftGridSizer_Items(self, parent): - parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.radioButton1, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.radioButton2, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.radioButton3, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.radioButton4, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.Sequences, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW) - - def _init_coll_LeftGridSizer_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(7) - - def _init_coll_RightGridSizer_Items(self, parent): - parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW) - - def _init_coll_RightGridSizer_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(1) - - def _init_sizers(self): - self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) - self.MainSizer = wx.BoxSizer(wx.HORIZONTAL) - self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=8, vgap=5) - self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5) - - self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) - self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) - self._init_coll_MainSizer_Items(self.MainSizer) - self._init_coll_LeftGridSizer_Items(self.LeftGridSizer) - self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer) - self._init_coll_RightGridSizer_Items(self.RightGridSizer) - self._init_coll_RightGridSizer_Growables(self.RightGridSizer) - - self.SetSizer(self.flexGridSizer1) - - def _init_ctrls(self, prnt, ctrler): - wx.Dialog.__init__(self, id=ID_DIVERGENCECREATEDIALOG, - name='DivergencePropertiesDialog', parent=prnt, pos=wx.Point(376, 223), - size=wx.Size(500, 300), style=wx.DEFAULT_DIALOG_STYLE, - title=_('Create a new divergence or convergence')) - self.SetClientSize(wx.Size(500, 300)) - - self.staticText1 = wx.StaticText(id=ID_DIVERGENCECREATEDIALOGSTATICTEXT1, - label=_('Type:'), name='staticText1', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) - - self.radioButton1 = wx.RadioButton(id=ID_DIVERGENCECREATEDIALOGRADIOBUTTON1, - label=_('Selection Divergence'), name='radioButton1', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.RB_GROUP) - self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_DIVERGENCECREATEDIALOGRADIOBUTTON1) - self.radioButton1.SetValue(True) - - self.radioButton2 = wx.RadioButton(id=ID_DIVERGENCECREATEDIALOGRADIOBUTTON2, - label=_('Selection Convergence'), name='radioButton2', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) - self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_DIVERGENCECREATEDIALOGRADIOBUTTON2) - self.radioButton2.SetValue(False) - - self.radioButton3 = wx.RadioButton(id=ID_DIVERGENCECREATEDIALOGRADIOBUTTON3, - label=_('Simultaneous Divergence'), name='radioButton3', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) - self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_DIVERGENCECREATEDIALOGRADIOBUTTON3) - self.radioButton3.SetValue(False) - - self.radioButton4 = wx.RadioButton(id=ID_DIVERGENCECREATEDIALOGRADIOBUTTON4, - label=_('Simultaneous Convergence'), name='radioButton4', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) - self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_DIVERGENCECREATEDIALOGRADIOBUTTON4) - self.radioButton4.SetValue(False) - - self.staticText2 = wx.StaticText(id=ID_DIVERGENCECREATEDIALOGSTATICTEXT2, - label=_('Number of sequences:'), name='staticText2', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) - - self.Sequences = wx.SpinCtrl(id=ID_DIVERGENCECREATEDIALOGSEQUENCES, - name='Sequences', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 24), style=0, min=2, max=20) - self.Bind(wx.EVT_SPINCTRL, self.OnSequencesChanged, id=ID_DIVERGENCECREATEDIALOGSEQUENCES) - - self.staticText3 = wx.StaticText(id=ID_DIVERGENCECREATEDIALOGSTATICTEXT3, - label=_('Preview:'), name='staticText3', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) - - self.Preview = wx.Panel(id=ID_DIVERGENCECREATEDIALOGPREVIEW, - name='Preview', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 0), 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, "IsOfType", ctrler.IsOfType) - - self.Spacer = wx.Panel(id=ID_TRANSITIONCONTENTDIALOGSPACER, - name='Spacer', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) - - self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) - - if wx.VERSION >= (2, 5, 0): - self.Preview.Bind(wx.EVT_PAINT, self.OnPaint) - else: - wx.EVT_PAINT(self.Preview, self.OnPaint) - - self._init_sizers() - - def __init__(self, parent, controler): - self._init_ctrls(parent, controler) - - self.Divergence = None - self.MinSize = (0, 0) - - def SetPreviewFont(self, font): - self.Preview.SetFont(font) - - def GetValues(self): - values = {} - if self.radioButton1.GetValue(): - values["type"] = SELECTION_DIVERGENCE - elif self.radioButton2.GetValue(): - values["type"] = SELECTION_CONVERGENCE - elif self.radioButton3.GetValue(): - values["type"] = SIMULTANEOUS_DIVERGENCE - else: - values["type"] = SIMULTANEOUS_CONVERGENCE - values["number"] = self.Sequences.GetValue() - return values - - def SetMinSize(self, size): - self.MinSize = size - - def OnTypeChanged(self, event): - self.RefreshPreview() - event.Skip() - - def OnSequencesChanged(self, event): - self.RefreshPreview() - event.Skip() - - def RefreshPreview(self): - dc = wx.ClientDC(self.Preview) - dc.SetFont(self.Preview.GetFont()) - dc.Clear() - if self.radioButton1.GetValue(): - self.Divergence = SFC_Divergence(self.Preview, SELECTION_DIVERGENCE, self.Sequences.GetValue()) - elif self.radioButton2.GetValue(): - self.Divergence = SFC_Divergence(self.Preview, SELECTION_CONVERGENCE, self.Sequences.GetValue()) - elif self.radioButton3.GetValue(): - self.Divergence = SFC_Divergence(self.Preview, SIMULTANEOUS_DIVERGENCE, self.Sequences.GetValue()) - else: - self.Divergence = SFC_Divergence(self.Preview, SIMULTANEOUS_CONVERGENCE, self.Sequences.GetValue()) - width, height = self.Divergence.GetSize() - min_width, min_height = max(width, self.MinSize[0]), max(height, self.MinSize[1]) - self.Divergence.SetSize(min_width, min_height) - clientsize = self.Preview.GetClientSize() - x = (clientsize.width - min_width) / 2 - y = (clientsize.height - min_height) / 2 - self.Divergence.SetPosition(x, y) - self.Divergence.Draw(dc) - - def OnPaint(self, event): - self.RefreshPreview() - event.Skip() - - -#------------------------------------------------------------------------------- -# Action Block Dialog -#------------------------------------------------------------------------------- - -def GetActionTableColnames(): - _ = lambda x: x - return [_("Qualifier"), _("Duration"), _("Type"), _("Value"), _("Indicator")] - -def GetTypeList(): - _ = lambda x: x - return [_("Action"), _("Variable"), _("Inline")] - -class ActionTable(wx.grid.PyGridTableBase): - - """ - A custom wx.Grid Table using user supplied data - """ - def __init__(self, parent, data, colnames): - # The base class must be initialized *first* - wx.grid.PyGridTableBase.__init__(self) - self.data = data - self.colnames = colnames - self.Parent = parent - # XXX - # we need to store the row length and collength to - # see if the table has changed size - self._rows = self.GetNumberRows() - self._cols = self.GetNumberCols() - - def GetNumberCols(self): - return len(self.colnames) - - def GetNumberRows(self): - return len(self.data) - - def GetColLabelValue(self, col, translate=True): - if col < len(self.colnames): - colname = self.colnames[col] - if translate: - return _(colname) - return colname - - def GetRowLabelValues(self, row, translate=True): - return row - - def GetValue(self, row, col): - if row < self.GetNumberRows(): - colname = self.GetColLabelValue(col, False) - name = str(self.data[row].get(colname, "")) - if colname == "Type": - return _(name) - return name - - def GetValueByName(self, row, colname): - return self.data[row].get(colname) - - def SetValue(self, row, col, value): - if col < len(self.colnames): - colname = self.GetColLabelValue(col, False) - if colname == "Type": - value = self.Parent.TranslateType[value] - self.data[row][colname] = value - - def ResetView(self, grid): - """ - (wx.Grid) -> Reset the grid view. Call this to - update the grid if rows and columns have been added or deleted - """ - grid.BeginBatch() - for current, new, delmsg, addmsg in [ - (self._rows, self.GetNumberRows(), wx.grid.GRIDTABLE_NOTIFY_ROWS_DELETED, wx.grid.GRIDTABLE_NOTIFY_ROWS_APPENDED), - (self._cols, self.GetNumberCols(), wx.grid.GRIDTABLE_NOTIFY_COLS_DELETED, wx.grid.GRIDTABLE_NOTIFY_COLS_APPENDED), - ]: - if new < current: - msg = wx.grid.GridTableMessage(self,delmsg,new,current-new) - grid.ProcessTableMessage(msg) - elif new > current: - msg = wx.grid.GridTableMessage(self,addmsg,new-current) - grid.ProcessTableMessage(msg) - self.UpdateValues(grid) - grid.EndBatch() - - self._rows = self.GetNumberRows() - self._cols = self.GetNumberCols() - # update the column rendering scheme - self._updateColAttrs(grid) - - # update the scrollbars and the displayed part of the grid - grid.AdjustScrollbars() - grid.ForceRefresh() - - def UpdateValues(self, grid): - """Update all displayed values""" - # This sends an event to the grid table to update all of the values - msg = wx.grid.GridTableMessage(self, wx.grid.GRIDTABLE_REQUEST_VIEW_GET_VALUES) - grid.ProcessTableMessage(msg) - - def _updateColAttrs(self, grid): - """ - wx.Grid -> update the column attributes to add the - appropriate renderer given the column name. - - Otherwise default to the default renderer. - """ - - for row in range(self.GetNumberRows()): - for col in range(self.GetNumberCols()): - editor = None - renderer = None - readonly = False - colname = self.GetColLabelValue(col, False) - if colname == "Qualifier": - editor = wx.grid.GridCellChoiceEditor() - editor.SetParameters(self.Parent.QualifierList) - if colname == "Duration": - editor = wx.grid.GridCellTextEditor() - renderer = wx.grid.GridCellStringRenderer() - if self.Parent.DurationList[self.data[row]["Qualifier"]]: - readonly = False - else: - readonly = True - self.data[row]["Duration"] = "" - elif colname == "Type": - editor = wx.grid.GridCellChoiceEditor() - editor.SetParameters(self.Parent.TypeList) - elif colname == "Value": - type = self.data[row]["Type"] - if type == "Action": - editor = wx.grid.GridCellChoiceEditor() - editor.SetParameters(self.Parent.ActionList) - elif type == "Variable": - editor = wx.grid.GridCellChoiceEditor() - editor.SetParameters(self.Parent.VariableList) - elif type == "Inline": - editor = wx.grid.GridCellTextEditor() - renderer = wx.grid.GridCellStringRenderer() - elif colname == "Indicator": - editor = wx.grid.GridCellChoiceEditor() - editor.SetParameters(self.Parent.VariableList) - - grid.SetCellEditor(row, col, editor) - grid.SetCellRenderer(row, col, renderer) - grid.SetReadOnly(row, col, readonly) - - grid.SetCellBackgroundColour(row, col, wx.WHITE) - - def SetData(self, data): - self.data = data - - def GetData(self): - return self.data - - def GetCurrentIndex(self): - return self.CurrentIndex - - def SetCurrentIndex(self, index): - self.CurrentIndex = index - - def AppendRow(self, row_content): - self.data.append(row_content) - - def RemoveRow(self, row_index): - self.data.pop(row_index) - - def MoveRow(self, row_index, move, grid): - new_index = max(0, min(row_index + move, len(self.data) - 1)) - if new_index != row_index: - self.data.insert(new_index, self.data.pop(row_index)) - grid.SetGridCursor(new_index, grid.GetGridCursorCol()) - - def Empty(self): - self.data = [] - self.editors = [] - -[ID_ACTIONBLOCKDIALOG, ID_ACTIONBLOCKDIALOGVARIABLESGRID, - ID_ACTIONBLOCKDIALOGSTATICTEXT1, ID_ACTIONBLOCKDIALOGADDBUTTON, - ID_ACTIONBLOCKDIALOGDELETEBUTTON, ID_ACTIONBLOCKDIALOGUPBUTTON, - ID_ACTIONBLOCKDIALOGDOWNBUTTON, -] = [wx.NewId() for _init_ctrls in range(7)] - -class ActionBlockDialog(wx.Dialog): - - if wx.VERSION < (2, 6, 0): - def Bind(self, event, function, id = None): - if id is not None: - event(self, id, function) - else: - event(self, function) - - def _init_coll_flexGridSizer1_Items(self, parent): - parent.AddSizer(self.TopSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) - parent.AddSizer(self.GridButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.LEFT|wx.RIGHT) - parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) - - def _init_coll_flexGridSizer1_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(0) - - def _init_coll_TopSizer_Items(self, parent): - parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.ActionsGrid, 0, border=0, flag=wx.GROW) - - def _init_coll_TopSizer_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(1) - - def _init_coll_GridButtonSizer_Items(self, parent): - parent.AddWindow(self.AddButton, 0, border=10, flag=wx.GROW|wx.LEFT) - parent.AddWindow(self.DeleteButton, 0, border=10, flag=wx.GROW|wx.LEFT) - parent.AddWindow(self.UpButton, 0, border=10, flag=wx.GROW|wx.LEFT) - parent.AddWindow(self.DownButton, 0, border=10, flag=wx.GROW|wx.LEFT) - - def _init_sizers(self): - self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=10) - self.TopSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5) - self.GridButtonSizer = wx.BoxSizer(wx.HORIZONTAL) - - self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) - self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) - self._init_coll_TopSizer_Items(self.TopSizer) - self._init_coll_TopSizer_Growables(self.TopSizer) - self._init_coll_GridButtonSizer_Items(self.GridButtonSizer) - - self.SetSizer(self.flexGridSizer1) - - def _init_ctrls(self, prnt): - wx.Dialog.__init__(self, id=ID_ACTIONBLOCKDIALOG, - name='ActionBlockDialog', parent=prnt, pos=wx.Point(376, 223), - size=wx.Size(500, 300), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER, - title=_('Edit action block properties')) - self.SetClientSize(wx.Size(500, 300)) - - self.staticText1 = wx.StaticText(id=ID_ACTIONBLOCKDIALOGSTATICTEXT1, - label=_('Actions:'), name='staticText1', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) - - self.ActionsGrid = wx.grid.Grid(id=ID_ACTIONBLOCKDIALOGVARIABLESGRID, - name='ActionsGrid', parent=self, pos=wx.Point(0, 0), - size=wx.Size(0, 0), style=wx.VSCROLL) - self.ActionsGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False, - 'Sans')) - self.ActionsGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL, - False, 'Sans')) - self.ActionsGrid.DisableDragGridSize() - self.ActionsGrid.EnableScrolling(False, True) - self.ActionsGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnActionsGridCellChange) - - self.AddButton = wx.Button(id=ID_ACTIONBLOCKDIALOGADDBUTTON, label=_('Add'), - name='AddButton', parent=self, pos=wx.Point(0, 0), - size=wx.DefaultSize, style=0) - self.Bind(wx.EVT_BUTTON, self.OnAddButton, id=ID_ACTIONBLOCKDIALOGADDBUTTON) - - self.DeleteButton = wx.Button(id=ID_ACTIONBLOCKDIALOGDELETEBUTTON, label=_('Delete'), - name='DeleteButton', parent=self, pos=wx.Point(0, 0), - size=wx.DefaultSize, style=0) - self.Bind(wx.EVT_BUTTON, self.OnDeleteButton, id=ID_ACTIONBLOCKDIALOGDELETEBUTTON) - - self.UpButton = wx.Button(id=ID_ACTIONBLOCKDIALOGUPBUTTON, label='^', - name='UpButton', parent=self, pos=wx.Point(0, 0), - size=wx.Size(32, 32), style=0) - self.Bind(wx.EVT_BUTTON, self.OnUpButton, id=ID_ACTIONBLOCKDIALOGUPBUTTON) - - self.DownButton = wx.Button(id=ID_ACTIONBLOCKDIALOGDOWNBUTTON, label='v', - name='DownButton', parent=self, pos=wx.Point(0, 0), - size=wx.Size(32, 32), style=0) - self.Bind(wx.EVT_BUTTON, self.OnDownButton, id=ID_ACTIONBLOCKDIALOGDOWNBUTTON) - - self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) - if wx.VERSION >= (2, 5, 0): - self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId()) - else: - self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId()) - - self._init_sizers() - - def __init__(self, parent): - self._init_ctrls(parent) - - self.DefaultValue = {"Qualifier" : "N", "Duration" : "", "Type" : "Action", "Value" : "", "Indicator" : ""} - self.Table = ActionTable(self, [], GetActionTableColnames()) - typelist = GetTypeList() - self.TypeList = ",".join(map(_,typelist)) - self.TranslateType = dict([(_(value), value) for value in typelist]) - self.ColSizes = [60, 90, 80, 110, 80] - self.ColAlignements = [wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT] - - self.ActionsGrid.SetTable(self.Table) - self.ActionsGrid.SetRowLabelSize(0) - - for col in range(self.Table.GetNumberCols()): - attr = wx.grid.GridCellAttr() - attr.SetAlignment(self.ColAlignements[col], wx.ALIGN_CENTRE) - self.ActionsGrid.SetColAttr(col, attr) - self.ActionsGrid.SetColMinimalWidth(col, self.ColSizes[col]) - self.ActionsGrid.AutoSizeColumn(col, False) - - self.Table.ResetView(self.ActionsGrid) - - def OnOK(self, event): - self.ActionsGrid.SetGridCursor(0, 0) - self.EndModal(wx.ID_OK) - - def OnAddButton(self, event): - self.Table.AppendRow(self.DefaultValue.copy()) - self.Table.ResetView(self.ActionsGrid) - event.Skip() - - def OnDeleteButton(self, event): - row = self.ActionsGrid.GetGridCursorRow() - self.Table.RemoveRow(row) - self.Table.ResetView(self.ActionsGrid) - event.Skip() - - def OnUpButton(self, event): - row = self.ActionsGrid.GetGridCursorRow() - self.Table.MoveRow(row, -1, self.ActionsGrid) - self.Table.ResetView(self.ActionsGrid) - event.Skip() - - def OnDownButton(self, event): - row = self.ActionsGrid.GetGridCursorRow() - self.Table.MoveRow(row, 1, self.ActionsGrid) - self.Table.ResetView(self.ActionsGrid) - event.Skip() - - def OnActionsGridCellChange(self, event): - self.Table.ResetView(self.ActionsGrid) - event.Skip() - - def SetQualifierList(self, list): - self.QualifierList = "," + ",".join(list) - self.DurationList = list - - def SetVariableList(self, list): - self.VariableList = "," + ",".join([variable["Name"] for variable in list]) - - def SetActionList(self, list): - self.ActionList = "," + ",".join(list) - - def SetValues(self, actions): - for action in actions: - row = {"Qualifier" : action["qualifier"], "Value" : action["value"]} - if action["type"] == "reference": - if action["value"] in self.ActionList: - row["Type"] = "Action" - elif action["value"] in self.VariableList: - row["Type"] = "Variable" - else: - row["Type"] = "Inline" - else: - row["Type"] = "Inline" - if "duration" in action: - row["Duration"] = action["duration"] - else: - row["Duration"] = "" - if "indicator" in action: - row["Indicator"] = action["indicator"] - else: - row["Indicator"] = "" - self.Table.AppendRow(row) - self.Table.ResetView(self.ActionsGrid) - - def GetValues(self): - values = [] - for data in self.Table.GetData(): - action = {"qualifier" : data["Qualifier"], "value" : data["Value"]} - if data["Type"] in ["Action", "Variable"]: - action["type"] = "reference" - else: - action["type"] = "inline" - if data["Duration"] != "": - action["duration"] = data["Duration"] - if data["Indicator"] != "": - action["indicator"] = data["Indicator"] - values.append(action) - return values - - -#------------------------------------------------------------------------------- -# Edit Step Name Dialog -#------------------------------------------------------------------------------- - -class StepNameDialog(wx.TextEntryDialog): - - if wx.VERSION < (2, 6, 0): - def Bind(self, event, function, id = None): - if id is not None: - event(self, id, function) - else: - event(self, function) - - - def __init__(self, parent, message, caption = "Please enter text", defaultValue = "", - style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition): - wx.TextEntryDialog.__init__(self, parent, message, caption, defaultValue, style, pos) - - self.PouNames = [] - self.Variables = [] - self.StepNames = [] - if wx.VERSION >= (2, 8, 0): - self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(2).GetSizer().GetItem(1).GetSizer().GetAffirmativeButton().GetId()) - elif wx.VERSION >= (2, 6, 0): - self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetAffirmativeButton().GetId()) - else: - self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId()) - - def OnOK(self, event): - step_name = self.GetSizer().GetItem(1).GetWindow().GetValue() - if step_name == "": - message = wx.MessageDialog(self, _("You must type a name!"), _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - elif not TestIdentifier(step_name): - message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - elif step_name.upper() in IEC_KEYWORDS: - message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - elif step_name.upper() in self.PouNames: - message = wx.MessageDialog(self, _("A POU named \"%s\" already exists!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - elif step_name.upper() in self.Variables: - message = wx.MessageDialog(self, _("A variable with \"%s\" as name already exists in this pou!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - elif step_name.upper() in self.StepNames: - message = wx.MessageDialog(self, _("\"%s\" step already exists!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - else: - self.EndModal(wx.ID_OK) - - def SetPouNames(self, pou_names): - self.PouNames = [pou_name.upper() for pou_name in pou_names] - - def SetVariables(self, variables): - self.Variables = [var["Name"].upper() for var in variables] - - def SetStepNames(self, step_names): - self.StepNames = [step_name.upper() for step_name in step_names] - - def GetValue(self): - return self.GetSizer().GetItem(1).GetWindow().GetValue() - -#------------------------------------------------------------------------------- -# POU Name Dialog -#------------------------------------------------------------------------------- - -class PouNameDialog(wx.TextEntryDialog): - - if wx.VERSION < (2, 6, 0): - def Bind(self, event, function, id = None): - if id is not None: - event(self, id, function) - else: - event(self, function) - - - def __init__(self, parent, message, caption = "Please enter text", defaultValue = "", - style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition): - wx.TextEntryDialog.__init__(self, parent, message, caption, defaultValue, style, pos) - - self.PouNames = [] - if wx.VERSION >= (2, 8, 0): - self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(2).GetSizer().GetItem(1).GetSizer().GetAffirmativeButton().GetId()) - elif wx.VERSION >= (2, 6, 0): - self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetAffirmativeButton().GetId()) - else: - self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId()) - - def OnOK(self, event): - step_name = self.GetSizer().GetItem(1).GetWindow().GetValue() - if step_name == "": - message = wx.MessageDialog(self, _("You must type a name!"), _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - elif not TestIdentifier(step_name): - message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - elif step_name.upper() in IEC_KEYWORDS: - message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - elif step_name.upper() in self.PouNames: - message = wx.MessageDialog(self, _("A POU named \"%s\" already exists!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() - else: - self.EndModal(wx.ID_OK) - - def SetPouNames(self, pou_names): - self.PouNames = [pou_name.upper() for pou_name in pou_names] - - def GetValue(self): - return self.GetSizer().GetItem(1).GetWindow().GetValue() diff -r c7e0254be378 -r e183bffc05f0 GraphicViewer.py --- a/GraphicViewer.py Wed Sep 30 15:23:31 2009 -0600 +++ b/GraphicViewer.py Fri Oct 02 18:14:43 2009 +0200 @@ -213,6 +213,9 @@ def SelectAll(self): pass + def ClearErrors(self): + pass + def NewValue(self, tick, value): self.Datas.append((float(tick), {True:1., False:0.}.get(value, float(value)))) if self.CurrentValue + self.CurrentRange == len(self.Datas) - 1: diff -r c7e0254be378 -r e183bffc05f0 PLCControler.py --- a/PLCControler.py Wed Sep 30 15:23:31 2009 -0600 +++ b/PLCControler.py Fri Oct 02 18:14:43 2009 +0200 @@ -75,6 +75,13 @@ "InOut" : (plcopen.interface_inOutVars, ITEM_VAR_INOUT) } +LOCATIONS_ITEMS = [LOCATION_PLUGIN, + LOCATION_MODULE, + LOCATION_GROUP, + LOCATION_VAR_INPUT, + LOCATION_VAR_OUTPUT, + LOCATION_VAR_MEMORY] = range(6) + ScriptDirectory = os.path.split(os.path.realpath(__file__))[0] def GetUneditableNames(): @@ -532,6 +539,9 @@ errors.append("No project opened") return "", errors, warnings + def DebugAvailable(self): + return self.CurrentCompiledProject is not None + def ProgramTransferred(self): self.CurrentCompiledProject = self.NextCompiledProject @@ -1167,6 +1177,9 @@ for i in xrange(len(self.PluginTypes)): self.PluginTypes.pop(0) + def GetVariableLocationTree(self): + return [] + # Function that returns the block definition associated to the block type given def GetBlockType(self, type, inputs = None, debug = False): for category in BlockTypes + self.PluginTypes: @@ -1845,7 +1858,7 @@ connection.setconnectionParameter(idx, None) idx += 1 - def AddEditedElementPouVar(self, tagname, type, name): + def AddEditedElementPouVar(self, tagname, type, name, location="", description=""): if self.Project is not None: words = tagname.split("::") if words[0] in ['P', 'T', 'A']: @@ -1853,7 +1866,7 @@ if pou is not None: if pou.interface is None: pou.interface = plcopen.pou_interface() - pou.addpouVar(type, name) + pou.addpouVar(type, name, location, description) def ChangeEditedElementPouVar(self, tagname, old_type, old_name, new_type, new_name): if self.Project is not None: @@ -2495,10 +2508,7 @@ new_instance = plcopen.pouInstance() new_instance.setname(instance["Name"]) new_instance.settypeName(instance["Type"]) - if instance["Task"] != "": - task_list[instance["Task"]].appendpouInstance(new_instance) - else: - resource.appendpouInstance(new_instance) + task_list.get(instance["Task"], resource).appendpouInstance(new_instance) def GetEditedResourceInfos(self, tagname, debug = False): resource = self.GetEditedElement(tagname, debug) diff -r c7e0254be378 -r e183bffc05f0 PLCGenerator.py --- a/PLCGenerator.py Wed Sep 30 15:23:31 2009 -0600 +++ b/PLCGenerator.py Fri Oct 02 18:14:43 2009 +0200 @@ -610,7 +610,7 @@ if isinstance(instance, (plcopen.fbdObjects_inVariable, plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable)): expression = instance.getexpression() var_type = self.GetVariableType(expression) - if expression == pou.getname(): + if pou.getpouType() == "function" and expression == pou.getname(): returntype_content = pou.interface.getreturnType().getcontent() if returntype_content["name"] == "derived": var_type = returntype_content["value"].getname() diff -r c7e0254be378 -r e183bffc05f0 PLCOpenEditor.py Binary file PLCOpenEditor.py has changed diff -r c7e0254be378 -r e183bffc05f0 RessourceEditor.py --- a/RessourceEditor.py Wed Sep 30 15:23:31 2009 -0600 +++ b/RessourceEditor.py Fri Oct 02 18:14:43 2009 +0200 @@ -55,6 +55,9 @@ def IsViewing(self, tagname): return self.TagName == tagname + def IsDebugging(self): + return False + def SetMode(self, mode): pass @@ -460,6 +463,9 @@ def IsViewing(self, tagname): return self.TagName == tagname + def IsDebugging(self): + return False + def SetMode(self, mode): pass diff -r c7e0254be378 -r e183bffc05f0 SFCViewer.py --- a/SFCViewer.py Wed Sep 30 15:23:31 2009 -0600 +++ b/SFCViewer.py Fri Oct 02 18:14:43 2009 +0200 @@ -359,7 +359,7 @@ #------------------------------------------------------------------------------- def AddInitialStep(self, pos): - dialog = StepNameDialog(self.ParentWindow, _("Please enter step name"), _("Add a new initial step"), "", wx.OK|wx.CANCEL) + dialog = SFCStepNameDialog(self.ParentWindow, _("Please enter step name"), _("Add a new initial step"), "", wx.OK|wx.CANCEL) dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) dialog.SetVariables(self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)) dialog.SetStepNames([block.GetName() for block in self.Blocks if isinstance(block, SFC_Step)]) @@ -381,7 +381,7 @@ def AddStep(self): if self.SelectedElement in self.Wires or isinstance(self.SelectedElement, SFC_Step): - dialog = StepNameDialog(self.ParentWindow, _("Add a new step"), _("Please enter step name"), "", wx.OK|wx.CANCEL) + dialog = SFCStepNameDialog(self.ParentWindow, _("Add a new step"), _("Please enter step name"), "", wx.OK|wx.CANCEL) dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) dialog.SetVariables(self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)) dialog.SetStepNames([block.GetName() for block in self.Blocks if isinstance(block, SFC_Step)]) @@ -464,7 +464,7 @@ def AddDivergence(self): if self.SelectedElement in self.Wires or isinstance(self.SelectedElement, Graphic_Group) or isinstance(self.SelectedElement, SFC_Step): - dialog = DivergenceCreateDialog(self.ParentWindow) + dialog = SFCDivergenceDialog(self.ParentWindow) dialog.SetPreviewFont(self.GetFont()) if dialog.ShowModal() == wx.ID_OK: value = dialog.GetValues() @@ -723,7 +723,7 @@ if self.GetDrawingMode() == FREEDRAWING_MODE: Viewer.EditStepContent(self, step) else: - dialog = StepNameDialog(self.ParentWindow, _("Edit step name"), _("Please enter step name"), step.GetName(), wx.OK|wx.CANCEL) + dialog = SFCStepNameDialog(self.ParentWindow, _("Edit step name"), _("Please enter step name"), step.GetName(), wx.OK|wx.CANCEL) dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) dialog.SetVariables(self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)) dialog.SetStepNames([block.GetName() for block in self.Blocks if isinstance(block, SFC_Step) and block.GetName() != step.GetName()]) diff -r c7e0254be378 -r e183bffc05f0 TextViewer.py --- a/TextViewer.py Wed Sep 30 15:23:31 2009 -0600 +++ b/TextViewer.py Fri Oct 02 18:14:43 2009 +0200 @@ -157,7 +157,9 @@ self.ParentWindow = window self.Controler = controler - self.SetModEventMask(wx.stc.STC_MOD_BEFOREINSERT|wx.stc.STC_MOD_BEFOREDELETE) + self.SetModEventMask(wx.stc.STC_MOD_BEFOREINSERT| + wx.stc.STC_MOD_BEFOREDELETE| + wx.stc.STC_PERFORMED_USER) self.Bind(wx.stc.EVT_STC_STYLENEEDED, self.OnStyleNeeded, id=ID_TEXTVIEWER) if controler: @@ -181,27 +183,31 @@ else: return self.TagName == tagname + def IsDebugging(self): + return self.Debug + def SetMode(self, mode): pass def OnModification(self, event): if not self.DisableEvents: mod_type = event.GetModificationType() - if not (mod_type&wx.stc.STC_PERFORMED_UNDO or mod_type&wx.stc.STC_PERFORMED_REDO): - if mod_type&wx.stc.STC_MOD_BEFOREINSERT: - if self.CurrentAction == None: - self.StartBuffering() - elif self.CurrentAction[0] != "Add" or self.CurrentAction[1] != event.GetPosition() - 1: - self.Controler.EndBuffering() - self.StartBuffering() - self.CurrentAction = ("Add", event.GetPosition()) - elif mod_type&wx.stc.STC_MOD_BEFOREDELETE: - if self.CurrentAction == None: - self.StartBuffering() - elif self.CurrentAction[0] != "Delete" or self.CurrentAction[1] != event.GetPosition() + 1: - self.Controler.EndBuffering() - self.StartBuffering() - self.CurrentAction = ("Delete", event.GetPosition()) + if mod_type&wx.stc.STC_MOD_BEFOREINSERT: + if self.CurrentAction == None: + self.StartBuffering() + elif self.CurrentAction[0] != "Add" or self.CurrentAction[1] != event.GetPosition() - 1: + self.Controler.EndBuffering() + self.StartBuffering() + self.CurrentAction = ("Add", event.GetPosition()) + wx.CallAfter(self.RefreshModel) + elif mod_type&wx.stc.STC_MOD_BEFOREDELETE: + if self.CurrentAction == None: + self.StartBuffering() + elif self.CurrentAction[0] != "Delete" or self.CurrentAction[1] != event.GetPosition() + 1: + self.Controler.EndBuffering() + self.StartBuffering() + self.CurrentAction = ("Delete", event.GetPosition()) + wx.CallAfter(self.RefreshModel) event.Skip() def OnDoDrop(self, event): @@ -210,20 +216,41 @@ except: values = event.GetDragText() if isinstance(values, tuple): - if values[1] in ["functionBlock", "program", "location", "debug"]: + message = None + if values[1] in ["functionBlock", "program", "debug"]: event.SetDragText("") elif values[1] == "function": event.SetDragText(values[0]) - elif values[1] != "location": - if values[3] == self.TagName: - self.ResetBuffer() - event.SetDragText(values[0]) - wx.CallAfter(self.RefreshModel) + elif values[1] == "location": + pou_name, pou_type = self.Controler.GetEditedElementType(self.TagName, self.Debug) + if len(values) > 2 and pou_type == "program": + var_name = values[3] + if var_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]: + message = _("\"%s\" pou already exists!")%blockname + elif var_name.upper() in [name.upper() for name in self.Controler.GetEditedElementVariables(self.TagName, self.Debug)]: + message = _("\"%s\" element for this pou already exists!")%blockname + else: + if values[2] is not None: + var_type = values[2] + else: + var_type = LOCATIONDATATYPES.get(values[0][2], ["BOOL"])[0] + self.Controler.AddEditedElementPouVar(self.TagName, var_type, var_name, values[0], values[4]) + self.ParentWindow.RefreshVariablePanel(self.TagName) + self.RefreshVariableTree() + event.SetDragText(var_name) else: event.SetDragText("") - message = wx.MessageDialog(self.ParentWindow, _("Variable don't belong to this POU!"), _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() + elif values[3] == self.TagName: + self.ResetBuffer() + event.SetDragText(values[0]) + wx.CallAfter(self.RefreshModel) + else: + message = _("Variable don't belong to this POU!") + if message is not None: + dialog = wx.MessageDialog(self, message, _("Error"), wx.OK|wx.ICON_ERROR) + dialog.ShowModal() + dialog.Destroy() + event.SetDragText("") event.Skip() def SetTextSyntax(self, syntax): @@ -272,11 +299,7 @@ self.EmptyUndoBuffer() self.DisableEvents = False - words = self.TagName.split("::") - - self.Variables = self.GenerateVariableTree([(variable["Name"], variable["Type"], variable["Tree"]) for variable in self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)]) - if self.Controler.GetEditedElementType(self.TagName, self.Debug)[1] == "function" or words[0] == "T" and self.TextSyntax == "IL": - self.Variables[words[-1].upper()] = {} + self.RefreshVariableTree() self.Functions = [] for category in self.Controler.GetBlockTypes(self.TagName, self.Debug): @@ -290,6 +313,12 @@ self.Colourise(0, -1) + def RefreshVariableTree(self): + words = self.TagName.split("::") + self.Variables = self.GenerateVariableTree([(variable["Name"], variable["Type"], variable["Tree"]) for variable in self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)]) + if self.Controler.GetEditedElementType(self.TagName, self.Debug)[1] == "function" or words[0] == "T" and self.TextSyntax == "IL": + self.Variables[words[-1].upper()] = {} + def GenerateVariableTree(self, list): tree = {} for var_name, var_type, (var_tree, var_dimension) in list: @@ -503,7 +532,6 @@ self.AutoCompSetIgnoreCase(True) self.AutoCompShow(len(words[-1]), " ".join(kw)) else: - wx.CallAfter(self.RefreshModel) event.Skip() def OnKillFocus(self, event): diff -r c7e0254be378 -r e183bffc05f0 VariablePanel.py --- a/VariablePanel.py Wed Sep 30 15:23:31 2009 -0600 +++ b/VariablePanel.py Fri Oct 02 18:14:43 2009 +0200 @@ -21,12 +21,26 @@ #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 os import wx, wx.grid from types import TupleType -from PLCOpenEditor import AppendMenu from plcopen.structures import LOCATIONDATATYPES, TestIdentifier, IEC_KEYWORDS +from PLCControler import LOCATION_PLUGIN, LOCATION_MODULE, LOCATION_GROUP, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY + +CWD = os.path.split(os.path.realpath(__file__))[0] + +# Compatibility function for wx versions < 2.6 +def AppendMenu(parent, help, id, kind, text): + if wx.VERSION >= (2, 6, 0): + parent.Append(help=help, id=id, kind=kind, text=text) + else: + parent.Append(helpString=help, id=id, kind=kind, item=text) + +[TITLE, TOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, TYPESTREE, + INSTANCESTREE, LIBRARYTREE, SCALING +] = range(9) #------------------------------------------------------------------------------- # Variables Editor Panel @@ -158,7 +172,6 @@ Otherwise default to the default renderer. """ - for row in range(self.GetNumberRows()): for col in range(self.GetNumberCols()): editor = None @@ -177,7 +190,7 @@ renderer = wx.grid.GridCellStringRenderer() elif colname == "Location": if self.GetValueByName(row, "Class") in ["Local", "Global"]: - editor = LocationCellEditor(self.Parent) + editor = LocationCellEditor(self, self.Parent.Controler) renderer = wx.grid.GridCellStringRenderer() else: grid.SetReadOnly(row, col, True) @@ -556,29 +569,29 @@ self.TagName = tagname def IsFunctionBlockType(self, name): - bodytype = self.Controler.GetEditedElementBodyType(self.TagName, self.ParentWindow.Debug) - pouname, poutype = self.Controler.GetEditedElementType(self.TagName, self.ParentWindow.Debug) + bodytype = self.Controler.GetEditedElementBodyType(self.TagName) + pouname, poutype = self.Controler.GetEditedElementType(self.TagName) if poutype != "function" and bodytype in ["ST", "IL"]: return False else: - return name in self.Controler.GetFunctionBlockTypes(self.TagName, self.ParentWindow.Debug) + return name in self.Controler.GetFunctionBlockTypes(self.TagName) def RefreshView(self): - self.PouNames = self.Controler.GetProjectPouNames(self.ParentWindow.Debug) + self.PouNames = self.Controler.GetProjectPouNames() words = self.TagName.split("::") if self.ElementType == "config": self.PouIsUsed = False returnType = None - self.Values = self.Controler.GetConfigurationGlobalVars(words[1], self.ParentWindow.Debug) + self.Values = self.Controler.GetConfigurationGlobalVars(words[1]) elif self.ElementType == "resource": self.PouIsUsed = False returnType = None - self.Values = self.Controler.GetConfigurationResourceGlobalVars(words[1], words[2], self.ParentWindow.Debug) - else: - self.PouIsUsed = self.Controler.PouIsUsed(words[1], self.ParentWindow.Debug) - returnType = self.Controler.GetEditedElementInterfaceReturnType(self.TagName, self.ParentWindow.Debug) - self.Values = self.Controler.GetEditedElementInterfaceVars(self.TagName, self.ParentWindow.Debug) + self.Values = self.Controler.GetConfigurationResourceGlobalVars(words[1], words[2]) + else: + self.PouIsUsed = self.Controler.PouIsUsed(words[1]) + returnType = self.Controler.GetEditedElementInterfaceReturnType(self.TagName) + self.Values = self.Controler.GetEditedElementInterfaceVars(self.TagName) if returnType and self.ReturnType.IsEnabled(): self.ReturnType.SetStringSelection(returnType) @@ -591,10 +604,7 @@ self.Controler.SetPouInterfaceReturnType(words[1], self.ReturnType.GetStringSelection()) self.Controler.BufferProject() self.ParentWindow.RefreshEditor(variablepanel = False) - self.ParentWindow.RefreshTitle() - self.ParentWindow.RefreshEditMenu() - self.ParentWindow.RefreshInstancesTree() - self.ParentWindow.RefreshLibraryTree() + self.ParentWindow._Refresh(TITLE, EDITMENU, INSTANCETREE, LIBRARYTREE) event.Skip() def OnClassFilter(self, event): @@ -666,7 +676,7 @@ def OnVariablesGridCellChange(self, event): row, col = event.GetRow(), event.GetCol() - colname = self.Table.GetColLabelValue(col) + colname = self.Table.GetColLabelValue(col, False) value = self.Table.GetValue(row, col) if colname == "Name" and value != "": @@ -696,11 +706,8 @@ if old_value != "": self.Controler.UpdateEditedElementUsedVariable(self.TagName, old_value, value) self.Controler.BufferProject() - self.ParentWindow.RefreshEditor(variablepanel = False) - self.ParentWindow.RefreshTitle() - self.ParentWindow.RefreshEditMenu() - self.ParentWindow.RefreshInstancesTree() - self.ParentWindow.RefreshLibraryTree() + self.ParentWindow.RefreshEditor(variablepanel = False) + self.ParentWindow._Refresh(TITLE, EDITMENU, INSTANCETREE, LIBRARYTREE) event.Skip() else: self.SaveValues() @@ -713,7 +720,6 @@ label_value = self.Table.GetColLabelValue(col) if label_value == "Type": - debug = self.ParentWindow.Debug type_menu = wx.Menu(title='') # the root menu # build a submenu containing standard IEC types @@ -727,7 +733,7 @@ # build a submenu containing user-defined types datatype_menu = wx.Menu(title='') - datatypes = self.Controler.GetDataTypes(basetypes = False, debug = debug) + datatypes = self.Controler.GetDataTypes(basetypes = False) for datatype in datatypes: new_id = wx.NewId() AppendMenu(datatype_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=datatype) @@ -736,14 +742,14 @@ type_menu.AppendMenu(wx.NewId(), _("User Data Types"), datatype_menu) # build a submenu containing function block types - bodytype = self.Controler.GetEditedElementBodyType(self.TagName, debug) - pouname, poutype = self.Controler.GetEditedElementType(self.TagName, debug) + bodytype = self.Controler.GetEditedElementBodyType(self.TagName) + pouname, poutype = self.Controler.GetEditedElementType(self.TagName) classtype = self.Table.GetValueByName(row, "Class") if classtype in ["Input", "Output", "InOut", "External", "Global"] or \ poutype != "function" and bodytype in ["ST", "IL"]: functionblock_menu = wx.Menu(title='') - fbtypes = self.Controler.GetFunctionBlockTypes(self.TagName, debug) + fbtypes = self.Controler.GetFunctionBlockTypes(self.TagName) for functionblock_type in fbtypes: new_id = wx.NewId() AppendMenu(functionblock_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=functionblock_type) @@ -769,11 +775,7 @@ self.SaveValues(False) self.ParentWindow.RefreshEditor(variablepanel = False) self.Controler.BufferProject() - self.ParentWindow.RefreshTitle() - self.ParentWindow.RefreshEditMenu() - self.ParentWindow.RefreshInstancesTree() - self.ParentWindow.RefreshLibraryTree() - event.Skip() + self.ParentWindow._Refresh(TITLE, EDITMENU, INSTANCESTREE, LIBRARYTREE) return VariableTypeFunction def OnVariablesGridCellLeftClick(self, event): @@ -839,10 +841,7 @@ self.Controler.SetPouInterfaceVars(words[1], self.Values) if buffer: self.Controler.BufferProject() - self.ParentWindow.RefreshTitle() - self.ParentWindow.RefreshEditMenu() - self.ParentWindow.RefreshInstancesTree() - self.ParentWindow.RefreshLibraryTree() + self.ParentWindow._Refresh(TITLE, EDITMENU, INSTANCESTREE, LIBRARYTREE) def AddVariableError(self, infos): if isinstance(infos[0], TupleType): @@ -857,325 +856,311 @@ self.Table.ResetView(self.VariablesGrid) class LocationCellControl(wx.PyControl): + + def _init_coll_MainSizer_Items(self, parent): + parent.AddWindow(self.Location, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.BrowseButton, 0, border=0, flag=wx.GROW) + + def _init_coll_MainSizer_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(0) + + def _init_sizers(self): + self.MainSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=1, vgap=0) + + self._init_coll_MainSizer_Items(self.MainSizer) + self._init_coll_MainSizer_Growables(self.MainSizer) + + self.SetSizer(self.MainSizer) + + def _init_ctrls(self, prnt): + wx.Control.__init__(self, id=-1, + name='LocationCellControl', parent=prnt, + size=wx.DefaultSize, style=0) + + # create location text control + self.Location = wx.TextCtrl(id=-1, name='Location', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 0), style=0) + + # create browse button + self.BrowseButton = wx.Button(id=-1, label='...', + name='staticText1', parent=self, pos=wx.Point(0, 0), + size=wx.Size(30, 0), style=0) + self.BrowseButton.Bind(wx.EVT_BUTTON, self.OnBrowseButtonClick) + + self.Bind(wx.EVT_SIZE, self.OnSize) + + self._init_sizers() + ''' Custom cell editor control with a text box and a button that launches the BrowseVariableLocationsDialog. ''' - def __init__(self, parent, var_panel): - wx.Control.__init__(self, parent, -1) - self.ParentWindow = parent - self.VarPanel = var_panel - self.Row = -1 - - self.Bind(wx.EVT_SIZE, self.OnSize) - - # create text control - self.txt = wx.TextCtrl(self, -1, '') - - # create browse button - self.btn = wx.Button(self, -1, '...', size=(20,20)) - self.btn.Bind(wx.EVT_BUTTON, self.OnBtnBrowseClick) - - szr = wx.BoxSizer(wx.HORIZONTAL) - szr.Add(self.txt, proportion=1, flag=wx.EXPAND) - szr.Add(self.btn, proportion=0, flag=wx.ALIGN_RIGHT) - - szr.SetSizeHints(self) - self.SetSizer(szr) + def __init__(self, parent, locations): + self._init_ctrls(parent) + self.Locations = locations + self.VarType = None + + def SetVarType(self, vartype): + self.VarType = vartype + + def SetValue(self, value): + self.Location.SetValue(value) + + def GetValue(self): + return self.Location.GetValue() + + def OnSize(self, event): self.Layout() - def SetRow(self, row): - '''set the grid row that we're working on''' - self.Row = row - - def OnSize(self, event): - '''resize the button and text control to fit''' - overall_width = self.GetSize()[0] - btn_width, btn_height = self.btn.GetSize() - new_txt_width = overall_width - btn_width - - self.txt.SetSize(wx.Size(new_txt_width, -1)) - self.btn.SetDimensions(new_txt_width, -1, btn_width, btn_height) - - def OnBtnBrowseClick(self, event): + def OnBrowseButtonClick(self, event): # pop up the location browser dialog - dia = BrowseVariableLocationsDialog(self.ParentWindow, self.VarPanel) - dia.ShowModal() - - if dia.Selection: - loc, iec_type, doc = dia.Selection + dialog = BrowseLocationsDialog(self, self.VarType, self.Locations) + if dialog.ShowModal() == wx.ID_OK: + infos = dialog.GetValues() # set the location - self.SetText(loc) - - # set the variable type and documentation - # NOTE: this update won't be displayed until editing is complete - # (when EndEdit is called). - # we can't call VarPanel.RefreshValues() here because it causes - # an exception. - self.VarPanel.Table.SetValueByName(self.Row, 'Type', iec_type) - self.VarPanel.Table.SetValueByName(self.Row, 'Documentation', doc) - - self.txt.SetFocus() - - def SetText(self, text): - self.txt.SetValue(text) + self.Location.SetValue(infos["location"]) + + dialog.Destroy() + + self.Location.SetFocus() def SetInsertionPoint(self, i): - self.txt.SetInsertionPoint(i) - - def GetText(self): - return self.txt.GetValue() - + self.Location.SetInsertionPoint(i) + def SetFocus(self): - self.txt.SetFocus() + self.Location.SetFocus() class LocationCellEditor(wx.grid.PyGridCellEditor): ''' Grid cell editor that uses LocationCellControl to display a browse button. ''' - def __init__(self, var_panel): + def __init__(self, table, controler): wx.grid.PyGridCellEditor.__init__(self) - self.VarPanel = var_panel - + self.Table = table + self.Controler = controler + def Create(self, parent, id, evt_handler): - self.text_browse = LocationCellControl(parent, self.VarPanel) - self.SetControl(self.text_browse) + locations = self.Controler.GetVariableLocationTree() + if len(locations) > 0: + self.CellControl = LocationCellControl(parent, locations) + else: + self.CellControl = wx.TextCtrl(parent, -1) + self.SetControl(self.CellControl) if evt_handler: - self.text_browse.PushEventHandler(evt_handler) + self.CellControl.PushEventHandler(evt_handler) def BeginEdit(self, row, col, grid): - loc = self.VarPanel.Table.GetValueByName(row, 'Location') - self.text_browse.SetText(loc) - self.text_browse.SetRow(row) - self.text_browse.SetFocus() + self.CellControl.SetValue(self.Table.GetValueByName(row, 'Location')) + if isinstance(self.CellControl, LocationCellControl): + self.CellControl.SetVarType(self.Controler.GetBaseType(self.Table.GetValueByName(row, 'Type'))) + self.CellControl.SetFocus() def EndEdit(self, row, col, grid): - loc = self.text_browse.GetText() - old_loc = self.VarPanel.Table.GetValueByName(row, 'Location') - + loc = self.CellControl.GetValue() + old_loc = self.Table.GetValueByName(row, 'Location') if loc != old_loc: - self.VarPanel.Table.SetValueByName(row, 'Location', loc) - - # NOTE: this is a really lame hack to force this row's - # 'Type' cell to redraw (since it may have changed). - # There's got to be a better way than this. - self.VarPanel.VariablesGrid.AutoSizeRow(row) + self.Table.SetValueByName(row, 'Location', loc) return True + return False def SetSize(self, rect): - # -2 and +5 give this some extra vertical padding - self.text_browse.SetDimensions(rect.x, rect.y-2, - rect.width, rect.height+5, + self.CellControl.SetDimensions(rect.x + 1, rect.y, + rect.width, rect.height, wx.SIZE_ALLOW_MINUS_ONE) def Clone(self): - return LocationCellEditor(self.VarPanel) - -class BrowseVariableLocationsDialog(wx.Dialog): - # turn LOCATIONDATATYPES inside-out - LOCATION_SIZES = {} - for size, types in LOCATIONDATATYPES.iteritems(): - for type in types: - LOCATION_SIZES[type] = size - - class PluginData: - '''contains a plugin's VariableLocationTree''' - def __init__(self, plugin): - self.subtree = plugin.GetVariableLocationTree() - - class SubtreeData: - '''contains a subtree of a plugin's VariableLocationTree''' - def __init__(self, subtree): - self.subtree = subtree - - class VariableData: - '''contains all the information about a valid variable location''' - def __init__(self, type, dir, loc): - self.type = type - - loc_suffix = '.'.join([str(x) for x in loc]) - - size = BrowseVariableLocationsDialog.LOCATION_SIZES[type] - self.loc = size + loc_suffix - - # if a direction was given, use it - # (if not we'll prompt the user to select one) - if dir: - self.loc = '%' + dir + self.loc - - def __init__(self, parent, var_panel): - self.VarPanel = var_panel - self.Selection = None - - # create the dialog - wx.Dialog.__init__(self, parent=parent, title=_('Browse Variables'), - style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER, - size=(-1, 400)) - - # create the root sizer - sizer = wx.BoxSizer(wx.VERTICAL) - self.SetSizer(sizer) - - # create the tree control - self.tree = wx.TreeCtrl(self, style=wx.TR_DEFAULT_STYLE|wx.TR_HIDE_ROOT) - sizer.Add(self.tree, 1, wx.EXPAND|wx.ALL, border=20) - - # create the Direction sizer and field - dsizer = wx.BoxSizer(wx.HORIZONTAL) - sizer.Add(dsizer, 0, wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.EXPAND, border=20) - - # direction label - ltext = wx.StaticText(self, -1, _('Direction:')) - dsizer.Add(ltext, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL, border=20) - - # direction choice - self.DirChoice = wx.Choice(id=-1, parent=self, choices=[_('Input'), _('Output'), _('Memory')]) - dsizer.Add(self.DirChoice, flag=wx.EXPAND) - # set a default for the choice - self.SetSelectedDirection('I') - - # create the button sizer - btsizer = wx.BoxSizer(wx.HORIZONTAL) - sizer.Add(btsizer, 0, wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.ALIGN_RIGHT, border=20) - - # add plugins to the tree - root = self.tree.AddRoot(_('Plugins')) - ctrl = self.VarPanel.Controler - self.AddChildPluginsToTree(ctrl.PluginsRoot, root) - - # -- buttons -- - - # ok button - self.OkButton = wx.Button(self, wx.ID_OK, _('Use Location')) - self.OkButton.SetDefault() - btsizer.Add(self.OkButton, flag=wx.RIGHT, border=5) - - # cancel button - b = wx.Button(self, wx.ID_CANCEL, _('Cancel')) - btsizer.Add(b) - - # -- event handlers -- - - # accept the location on doubleclick or clicking the Use Location button - self.Bind(wx.EVT_BUTTON, self.OnOk, self.OkButton) - self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnOk, self.tree) - - # disable the Add button when we're not on a valid variable - self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChange, self.tree) - - # handle the Expand event. this lets us create the tree as it's expanded - # (trying to create it all at once is slow since plugin variable location - # trees can be big) - wx.EVT_TREE_ITEM_EXPANDING(self.tree, self.tree.GetId(), self.OnExpand) - - def OnExpand(self, event): - item = event.GetItem() - if not item.IsOk(): - item = self.tree.GetSelection() - - data = self.tree.GetPyData(item) - self.ExpandTree(item, data.subtree) - - def AddChildPluginsToTree(self, plugin, root): - for p in plugin.IECSortedChilds(): - plug_name = p.BaseParams.getName() - new_item = self.tree.AppendItem(root, plug_name) - - # make it look like the tree item has children (since it doesn't yet) - self.tree.SetItemHasChildren(new_item) - - # attach the plugin data to the tree item - self.tree.SetPyData(new_item, BrowseVariableLocationsDialog.PluginData(p)) - - # add child plugins recursively - self.AddChildPluginsToTree(p, new_item) - - def ExpandTree(self, root, subtree): - items = subtree.items() - items.sort() - - for node_name, data in items: - if isinstance(data, dict): - # this is a new subtree - - new_item = self.tree.AppendItem(root, node_name) - self.tree.SetItemHasChildren(new_item) - - # attach the new subtree's data to the tree item - new_data = BrowseVariableLocationsDialog.SubtreeData(data) - self.tree.SetPyData(new_item, new_data) + return LocationCellEditor(self.Table, self.Locations) + +def GetDirChoiceOptions(): + _ = lambda x : x + return [(_("All"), [LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY]), + (_("Input"), [LOCATION_VAR_INPUT]), + (_("Output"), [LOCATION_VAR_OUTPUT]), + (_("Memory"), [LOCATION_VAR_MEMORY])] +DIRCHOICE_OPTIONS_FILTER = dict([(_(option), filter) for option, filter in GetDirChoiceOptions()]) + +# turn LOCATIONDATATYPES inside-out +LOCATION_SIZES = {} +for size, types in LOCATIONDATATYPES.iteritems(): + for type in types: + LOCATION_SIZES[type] = size + +[ID_BROWSELOCATIONSDIALOG, ID_BROWSELOCATIONSDIALOGLOCATIONSTREE, + ID_BROWSELOCATIONSDIALOGDIRCHOICE, ID_BROWSELOCATIONSDIALOGSTATICTEXT1, + ID_BROWSELOCATIONSDIALOGSTATICTEXT2, +] = [wx.NewId() for _init_ctrls in range(5)] + +class BrowseLocationsDialog(wx.Dialog): + + if wx.VERSION < (2, 6, 0): + def Bind(self, event, function, id = None): + if id is not None: + event(self, id, function) + else: + event(self, function) + + def _init_coll_MainSizer_Items(self, parent): + parent.AddWindow(self.staticText1, 0, border=20, flag=wx.TOP|wx.LEFT|wx.RIGHT|wx.GROW) + parent.AddWindow(self.LocationsTree, 0, border=20, flag=wx.LEFT|wx.RIGHT|wx.GROW) + parent.AddSizer(self.ButtonGridSizer, 0, border=20, flag=wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.GROW) + + def _init_coll_MainSizer_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(1) + + def _init_coll_ButtonGridSizer_Items(self, parent): + parent.AddWindow(self.staticText2, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) + parent.AddWindow(self.DirChoice, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) + parent.AddSizer(self.ButtonSizer, 0, border=0, flag=wx.ALIGN_RIGHT) + + def _init_coll_ButtonGridSizer_Growables(self, parent): + parent.AddGrowableCol(2) + parent.AddGrowableRow(0) + + def _init_sizers(self): + self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=10) + self.ButtonGridSizer = wx.FlexGridSizer(cols=3, hgap=5, rows=1, vgap=0) + + self._init_coll_MainSizer_Items(self.MainSizer) + self._init_coll_MainSizer_Growables(self.MainSizer) + self._init_coll_ButtonGridSizer_Items(self.ButtonGridSizer) + self._init_coll_ButtonGridSizer_Growables(self.ButtonGridSizer) + + self.SetSizer(self.MainSizer) + + def _init_ctrls(self, prnt): + wx.Dialog.__init__(self, id=ID_BROWSELOCATIONSDIALOG, + name='BrowseLocationsDialog', parent=prnt, + size=wx.Size(600, 400), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER, + title=_('Browse Locations')) + + self.staticText1 = wx.StaticText(id=ID_BROWSELOCATIONSDIALOGSTATICTEXT1, + label=_('Locations available:'), name='staticText1', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) + + if wx.Platform == '__WXMSW__': + treestyle = wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER + else: + treestyle = wx.TR_HAS_BUTTONS|wx.TR_HIDE_ROOT|wx.TR_SINGLE|wx.SUNKEN_BORDER + self.LocationsTree = wx.TreeCtrl(id=ID_BROWSELOCATIONSDIALOGLOCATIONSTREE, + name='LocationsTree', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 0), style=treestyle) + self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnLocationsTreeItemActivated, + id=ID_BROWSELOCATIONSDIALOGLOCATIONSTREE) + + self.staticText2 = wx.StaticText(id=ID_BROWSELOCATIONSDIALOGSTATICTEXT2, + label=_('Direction:'), name='staticText2', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) + + self.DirChoice = wx.ComboBox(id=ID_BROWSELOCATIONSDIALOGDIRCHOICE, + name='DirChoice', parent=self, pos=wx.Point(0, 0), + size=wx.DefaultSize, style=wx.CB_READONLY) + self.Bind(wx.EVT_COMBOBOX, self.OnDirChoice, id=ID_BROWSELOCATIONSDIALOGDIRCHOICE) + + self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) + if wx.VERSION >= (2, 5, 0): + self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId()) + else: + self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId()) + + self._init_sizers() + + def __init__(self, parent, var_type, locations): + self._init_ctrls(parent) + self.VarType = var_type + self.Locations = locations + + # Define Tree item icon list + self.TreeImageList = wx.ImageList(16, 16) + self.TreeImageDict = {} + + # Icons for items + for imgname, itemtype in [ + ("CONFIGURATION", LOCATION_PLUGIN), + ("RESOURCE", LOCATION_MODULE), + ("PROGRAM", LOCATION_GROUP), + ("VAR_INPUT", LOCATION_VAR_INPUT), + ("VAR_OUTPUT", LOCATION_VAR_OUTPUT), + ("VAR_LOCAL", LOCATION_VAR_MEMORY)]: + self.TreeImageDict[itemtype]=self.TreeImageList.Add(wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%imgname))) + + # Assign icon list to TreeCtrls + self.LocationsTree.SetImageList(self.TreeImageList) + + # Set a options for the choice + for option, filter in GetDirChoiceOptions(): + self.DirChoice.Append(_(option)) + self.DirChoice.SetStringSelection(_("All")) + self.RefreshFilter() + + self.RefreshLocationsTree() + + def RefreshFilter(self): + self.Filter = DIRCHOICE_OPTIONS_FILTER[self.DirChoice.GetStringSelection()] + + def RefreshLocationsTree(self): + root = self.LocationsTree.GetRootItem() + if not root.IsOk(): + if wx.Platform == '__WXMSW__': + root = self.LocationsTree.AddRoot(_('Plugins')) + else: + root = self.LocationsTree.AddRoot("") + self.GenerateLocationsTreeBranch(root, self.Locations) + self.LocationsTree.Expand(root) + + def GenerateLocationsTreeBranch(self, root, locations): + to_delete = [] + if wx.VERSION >= (2, 6, 0): + item, root_cookie = self.LocationsTree.GetFirstChild(root) + else: + item, root_cookie = self.LocationsTree.GetFirstChild(root, 0) + for loc_infos in locations: + infos = loc_infos.copy() + if infos["type"] in [LOCATION_PLUGIN, LOCATION_MODULE, LOCATION_GROUP] or\ + infos["type"] in self.Filter and (infos["IEC_type"] == self.VarType or + infos["IEC_type"] is None and LOCATION_SIZES[self.VarType] == infos["size"]): + children = [child for child in infos.pop("children")] + if not item.IsOk(): + item = self.LocationsTree.AppendItem(root, infos["name"]) + if wx.Platform != '__WXMSW__': + item, root_cookie = self.LocationsTree.GetNextChild(root, root_cookie) else: - # this is a new leaf. - - # data is a tuple containing (IEC type, I/Q/M/None, IEC path tuple) - type, dir, loc = data - - node_name = '%s (%s)' % (node_name, type) - new_item = self.tree.AppendItem(root, node_name) - - vd = BrowseVariableLocationsDialog.VariableData(type, dir, loc) - self.tree.SetPyData(new_item, vd) - - def OnSelChange(self, event): - '''updates the text field and the "Use Location" button.''' - item = self.tree.GetSelection() - data = self.tree.GetPyData(item) - - if isinstance(data, BrowseVariableLocationsDialog.VariableData): - self.OkButton.Enable() - - location = data.loc - if location[0] == '%': - # location has a fixed direction - self.SetSelectedDirection(location[1]) - self.DirChoice.Disable() - else: - # this location can have any direction (user selects) - self.DirChoice.Enable() - else: - self.OkButton.Disable() - self.DirChoice.Disable() - - def GetSelectedDirection(self): - selected = self.DirChoice.GetSelection() - if selected == 0: - return 'I' - elif selected == 1: - return 'Q' - else: - return 'M' - - def SetSelectedDirection(self, dir_letter): - if dir_letter == 'I': - self.DirChoice.SetSelection(0) - elif dir_letter == 'Q': - self.DirChoice.SetSelection(1) - else: - self.DirChoice.SetSelection(2) - - def OnOk(self, event): - item = self.tree.GetSelection() - data = self.tree.GetPyData(item) - - if not isinstance(data, BrowseVariableLocationsDialog.VariableData): - return - - location = data.loc - - if location[0] != '%': - # no direction was given, grab the one from the wxChoice - dir = self.GetSelectedDirection() - location = '%' + dir + location - - # walk up the tree, building documentation for the variable - documentation = self.tree.GetItemText(item) - parent = self.tree.GetItemParent(item) - root = self.tree.GetRootItem() - while parent != root: - text = self.tree.GetItemText(parent) - documentation = text + ":" + documentation - parent = self.tree.GetItemParent(parent) - - self.Selection = (location, data.type, documentation) - self.Destroy() + self.LocationsTree.SetItemText(item, infos["name"]) + self.LocationsTree.SetPyData(item, infos) + self.LocationsTree.SetItemImage(item, self.TreeImageDict[infos["type"]]) + self.GenerateLocationsTreeBranch(item, children) + item, root_cookie = self.LocationsTree.GetNextChild(root, root_cookie) + while item.IsOk(): + to_delete.append(item) + item, root_cookie = self.LocationsTree.GetNextChild(root, root_cookie) + for item in to_delete: + self.LocationsTree.Delete(item) + + def OnLocationsTreeItemActivated(self, event): + infos = self.LocationsTree.GetPyData(event.GetItem()) + if infos["type"] not in [LOCATION_PLUGIN, LOCATION_MODULE, LOCATION_GROUP]: + wx.CallAfter(self.EndModal, wx.ID_OK) + event.Skip() + + def OnDirChoice(self, event): + self.RefreshFilter() + self.RefreshLocationsTree() + + def GetValues(self): + selected = self.LocationsTree.GetSelection() + return self.LocationsTree.GetPyData(selected) + + def OnOK(self, event): + selected = self.LocationsTree.GetSelection() + var_infos = None + if selected.IsOk(): + var_infos = self.LocationsTree.GetPyData(selected) + if var_infos is None or var_infos["type"] in [LOCATION_PLUGIN, LOCATION_MODULE, LOCATION_GROUP]: + message = wx.MessageDialog(self, _("A location must be selected!"), _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + else: + self.EndModal(wx.ID_OK) + \ No newline at end of file diff -r c7e0254be378 -r e183bffc05f0 Viewer.py --- a/Viewer.py Wed Sep 30 15:23:31 2009 -0600 +++ b/Viewer.py Fri Oct 02 18:14:43 2009 +0200 @@ -33,7 +33,8 @@ from plcopen.structures import * from PLCControler import ITEM_POU -from Dialogs import * +from dialogs import * +from graphics import * from types import TupleType @@ -200,6 +201,8 @@ self.ParentWindow = parent def OnDropText(self, x, y, data): + tagname = self.ParentWindow.GetTagName() + pou_name, pou_type = self.ParentWindow.Controler.GetEditedElementType(tagname, self.ParentWindow.Debug) x, y = self.ParentWindow.CalcUnscrolledPosition(x, y) x = int(x / self.ParentWindow.ViewScale[0]) y = int(y / self.ParentWindow.ViewScale[1]) @@ -218,17 +221,16 @@ pass elif values[1] == "program": message = _("Programs can't be used by other POUs!") - elif values[1] in ["function", "functionBlock", "program"]: - name, type = self.ParentWindow.Controler.GetEditedElementType(self.ParentWindow.GetTagName(), self.ParentWindow.Debug) - words = self.ParentWindow.TagName.split("::") - if name == values[0]: - message = _("\"%s\" can't use itself!")%name - elif type == "function" and values[1] != "function": + elif values[1] in ["function", "functionBlock"]: + words = tagname.split("::") + if pou_name == values[0]: + message = _("\"%s\" can't use itself!")%pou_name + elif pou_type == "function" and values[1] != "function": message = _("Function Blocks can't be used in Functions!") elif words[0] == "T" and values[1] != "function": message = _("Function Blocks can't be used in Transitions!") - elif self.ParentWindow.Controler.PouIsUsedBy(name, values[0], self.ParentWindow.Debug): - message = _("\"%s\" is already used by \"%s\"!")%(name, values[0]) + elif self.ParentWindow.Controler.PouIsUsedBy(pou_name, values[0], self.ParentWindow.Debug): + message = _("\"%s\" is already used by \"%s\"!")%(pou_name, values[0]) else: blockname = values[2] if len(values) > 3: @@ -244,7 +246,7 @@ dialog.Destroy() if blockname.upper() in [name.upper() for name in self.ParentWindow.Controler.GetProjectPouNames(self.ParentWindow.Debug)]: message = _("\"%s\" pou already exists!")%blockname - elif blockname.upper() in [name.upper() for name in self.ParentWindow.Controler.GetEditedElementVariables(self.ParentWindow.GetTagName(), self.ParentWindow.Debug)]: + elif blockname.upper() in [name.upper() for name in self.ParentWindow.Controler.GetEditedElementVariables(tagname, self.ParentWindow.Debug)]: message = _("\"%s\" element for this pou already exists!")%blockname else: id = self.ParentWindow.GetNewId() @@ -258,34 +260,67 @@ block.SetPosition(x, y) block.SetSize(width, height) self.ParentWindow.AddBlock(block) - self.ParentWindow.Controler.AddEditedElementBlock(self.ParentWindow.GetTagName(), id, values[0], blockname) + self.ParentWindow.Controler.AddEditedElementBlock(tagname, id, values[0], blockname) self.ParentWindow.RefreshBlockModel(block) self.ParentWindow.RefreshBuffer() self.ParentWindow.RefreshScrollBars() self.ParentWindow.RefreshVisibleElements() - self.ParentWindow.ParentWindow.RefreshVariablePanel(self.ParentWindow.GetTagName()) + self.ParentWindow.ParentWindow.RefreshVariablePanel(tagname) self.ParentWindow.Refresh(False) - elif values[1] != "location": - tagname = self.ParentWindow.GetTagName() - if values[3] == tagname: - if values[1] == "Output": - var_class = OUTPUT - elif values[1] == "InOut": - var_class = INPUT + elif values[1] == "location": + if len(values) > 2 and pou_type == "program": + var_name = values[3] + if var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetProjectPouNames(self.ParentWindow.Debug)]: + message = _("\"%s\" pou already exists!")%blockname + elif var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetEditedElementVariables(tagname, self.ParentWindow.Debug)]: + message = _("\"%s\" element for this pou already exists!")%blockname else: - var_class = INPUT - tree = dict([(var["Name"], var["Tree"]) for var in self.ParentWindow.Controler.GetEditedElementInterfaceVars(tagname, self.ParentWindow.Debug)]).get(values[0], None) - if tree is not None: - if len(tree[0]) > 0: - menu = wx.Menu(title='') - self.GenerateTreeMenu(x, y, scaling, menu, "", var_class, [(values[0], values[2], tree)]) - self.ParentWindow.PopupMenuXY(menu) + if values[0][1] == "Q": + var_class = OUTPUT else: - self.AddParentVariableBlock(x, y, scaling, var_class, values[0], values[2]) + var_class = INPUT + if values[2] is not None: + var_type = values[2] + else: + var_type = LOCATIONDATATYPES.get(values[0][2], ["BOOL"])[0] + id = self.ParentWindow.GetNewId() + variable = FBD_Variable(self.ParentWindow, var_class, var_name, var_type, id) + width, height = variable.GetMinSize() + if scaling is not None: + x = round(float(x) / float(scaling[0])) * scaling[0] + y = round(float(y) / float(scaling[1])) * scaling[1] + width = round(float(width) / float(scaling[0]) + 0.5) * scaling[0] + height = round(float(height) / float(scaling[1]) + 0.5) * scaling[1] + variable.SetPosition(x, y) + variable.SetSize(width, height) + self.ParentWindow.AddBlock(variable) + self.ParentWindow.Controler.AddEditedElementPouVar(tagname, var_type, var_name, values[0], values[4]) + self.ParentWindow.Controler.AddEditedElementVariable(tagname, id, var_class) + self.ParentWindow.RefreshVariableModel(variable) + self.ParentWindow.RefreshBuffer() + self.ParentWindow.RefreshScrollBars() + self.ParentWindow.RefreshVisibleElements() + self.ParentWindow.ParentWindow.RefreshVariablePanel(tagname) + self.ParentWindow.Refresh(False) + elif values[3] == tagname: + if values[1] == "Output": + var_class = OUTPUT + elif values[1] == "InOut": + var_class = INPUT + else: + var_class = INPUT + tree = dict([(var["Name"], var["Tree"]) for var in self.ParentWindow.Controler.GetEditedElementInterfaceVars(tagname, self.ParentWindow.Debug)]).get(values[0], None) + if tree is not None: + if len(tree[0]) > 0: + menu = wx.Menu(title='') + self.GenerateTreeMenu(x, y, scaling, menu, "", var_class, [(values[0], values[2], tree)]) + self.ParentWindow.PopupMenuXY(menu) else: - message = _("Unknown variable \"%s\" for this POU!") % values[0] + self.AddParentVariableBlock(x, y, scaling, var_class, values[0], values[2]) else: - message = _("Variable don't belong to this POU!") + message = _("Unknown variable \"%s\" for this POU!") % values[0] + else: + message = _("Variable don't belong to this POU!") if message is not None: wx.CallAfter(self.ShowMessage, message) @@ -452,7 +487,7 @@ def __init__(self, parent, tagname, window, controler, debug = False, instancepath = ""): wx.ScrolledWindow.__init__(self, parent, pos=wx.Point(0, 0), size=wx.Size(0, 0), style=wx.HSCROLL | wx.VSCROLL | wx.ALWAYS_SHOW_SB) - DebugViewer.__init__(self, controler.DataProducer, debug) + DebugViewer.__init__(self, controler, debug) self._init_menus() # Adding a rubberband to Viewer self.rubberBand = RubberBand(drawingSurface=self) @@ -1162,97 +1197,82 @@ self.SelectedElement.AlignElements(ALIGN_LEFT, None) self.RefreshBuffer() self.Refresh(False) - event.Skip() def OnAlignCenterMenu(self, event): if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group): self.SelectedElement.AlignElements(ALIGN_CENTER, None) self.RefreshBuffer() self.Refresh(False) - event.Skip() def OnAlignRightMenu(self, event): if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group): self.SelectedElement.AlignElements(ALIGN_RIGHT, None) self.RefreshBuffer() self.Refresh(False) - event.Skip() def OnAlignTopMenu(self, event): if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group): self.SelectedElement.AlignElements(None, ALIGN_TOP) self.RefreshBuffer() self.Refresh(False) - event.Skip() def OnAlignMiddleMenu(self, event): if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group): self.SelectedElement.AlignElements(None, ALIGN_MIDDLE) self.RefreshBuffer() self.Refresh(False) - event.Skip() def OnAlignBottomMenu(self, event): if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group): self.SelectedElement.AlignElements(None, ALIGN_BOTTOM) self.RefreshBuffer() self.Refresh(False) - event.Skip() def OnNoModifierMenu(self, event): if self.SelectedElement is not None and self.IsBlock(self.SelectedElement): self.SelectedElement.SetConnectorNegated(False) self.SelectedElement.Refresh() self.RefreshBuffer() - event.Skip() def OnNegatedMenu(self, event): if self.SelectedElement is not None and self.IsBlock(self.SelectedElement): self.SelectedElement.SetConnectorNegated(True) self.SelectedElement.Refresh() self.RefreshBuffer() - event.Skip() def OnRisingEdgeMenu(self, event): if self.SelectedElement is not None and self.IsBlock(self.SelectedElement): self.SelectedElement.SetConnectorEdge("rising") self.SelectedElement.Refresh() self.RefreshBuffer() - event.Skip() def OnFallingEdgeMenu(self, event): if self.SelectedElement is not None and self.IsBlock(self.SelectedElement): self.SelectedElement.SetConnectorEdge("falling") self.SelectedElement.Refresh() self.RefreshBuffer() - event.Skip() def OnAddSegmentMenu(self, event): if self.SelectedElement is not None and self.IsWire(self.SelectedElement): self.SelectedElement.AddSegment() self.SelectedElement.Refresh() - event.Skip() def OnDeleteSegmentMenu(self, event): if self.SelectedElement is not None and self.IsWire(self.SelectedElement): self.SelectedElement.DeleteSegment() self.SelectedElement.Refresh() - event.Skip() def OnAddBranchMenu(self, event): if self.SelectedElement is not None and self.IsBlock(self.SelectedElement): self.AddDivergenceBranch(self.SelectedElement) - event.Skip() def OnDeleteBranchMenu(self, event): if self.SelectedElement is not None and self.IsBlock(self.SelectedElement): self.RemoveDivergenceBranch(self.SelectedElement) - event.Skip() def OnEditBlockMenu(self, event): if self.SelectedElement is not None: self.ParentWindow.EditProjectElement(ITEM_POU, "P::%s"%self.SelectedElement.GetType()) - event.Skip() def OnDeleteMenu(self, event): if self.SelectedElement is not None: @@ -1260,7 +1280,6 @@ self.SelectedElement = None self.RefreshBuffer() self.Refresh(False) - event.Skip() def OnClearExecutionOrderMenu(self, event): self.Controler.ClearEditedElementExecutionOrder(self.TagName) @@ -1716,7 +1735,7 @@ return width, height def AddNewBlock(self, bbox): - dialog = BlockPropertiesDialog(self.ParentWindow, self.Controler) + dialog = FBDBlockDialog(self.ParentWindow, self.Controler) dialog.SetPreviewFont(self.GetFont()) dialog.SetBlockList(self.Controler.GetBlockTypes(self.TagName, self.Debug)) dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) @@ -1746,9 +1765,9 @@ def AddNewVariable(self, bbox): words = self.TagName.split("::") if words[0] == "T": - dialog = VariablePropertiesDialog(self.ParentWindow, self.Controler, words[2]) + dialog = FBDVariableDialog(self.ParentWindow, self.Controler, words[2]) else: - dialog = VariablePropertiesDialog(self.ParentWindow, self.Controler) + dialog = FBDVariableDialog(self.ParentWindow, self.Controler) dialog.SetPreviewFont(self.GetFont()) dialog.SetMinVariableSize((bbox.width, bbox.height)) varlist = [] @@ -1777,7 +1796,7 @@ dialog.Destroy() def AddNewConnection(self, bbox): - dialog = ConnectionPropertiesDialog(self.ParentWindow, self.Controler) + dialog = ConnectionDialog(self.ParentWindow, self.Controler) dialog.SetPreviewFont(self.GetFont()) dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) dialog.SetPouElementNames(self.Controler.GetEditedElementVariables(self.TagName, self.Debug)) @@ -1895,7 +1914,7 @@ dialog.Destroy() def AddNewStep(self, bbox, initial = False): - dialog = StepContentDialog(self.ParentWindow, self.Controler, initial) + dialog = SFCStepDialog(self.ParentWindow, self.Controler, initial) dialog.SetPreviewFont(self.GetFont()) dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) dialog.SetVariables(self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)) @@ -1930,7 +1949,7 @@ dialog.Destroy() def AddNewTransition(self, bbox): - dialog = TransitionContentDialog(self.ParentWindow, self.Controler, self.GetDrawingMode() == FREEDRAWING_MODE) + dialog = SFCTransitionDialog(self.ParentWindow, self.Controler, self.GetDrawingMode() == FREEDRAWING_MODE) dialog.SetPreviewFont(self.GetFont()) dialog.SetTransitions(self.Controler.GetEditedElementTransitions(self.TagName, self.Debug)) if dialog.ShowModal() == wx.ID_OK: @@ -1950,7 +1969,7 @@ dialog.Destroy() def AddNewDivergence(self, bbox): - dialog = DivergenceCreateDialog(self.ParentWindow, self.Controler) + dialog = SFCDivergenceDialog(self.ParentWindow, self.Controler) dialog.SetPreviewFont(self.GetFont()) dialog.SetMinSize((bbox.width, bbox.height)) if dialog.ShowModal() == wx.ID_OK: @@ -2017,7 +2036,7 @@ #------------------------------------------------------------------------------- def EditBlockContent(self, block): - dialog = BlockPropertiesDialog(self.ParentWindow, self.Controler) + dialog = FBDBlockDialog(self.ParentWindow, self.Controler) dialog.SetPreviewFont(self.GetFont()) dialog.SetBlockList(self.Controler.GetBlockTypes(self.TagName, self.Debug)) dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) @@ -2059,9 +2078,9 @@ def EditVariableContent(self, variable): words = self.TagName.split("::") if words[0] == "T": - dialog = VariablePropertiesDialog(self.ParentWindow, self.Controler, words[2]) + dialog = FBDVariableDialog(self.ParentWindow, self.Controler, words[2]) else: - dialog = VariablePropertiesDialog(self.ParentWindow, self.Controler) + dialog = FBDVariableDialog(self.ParentWindow, self.Controler) dialog.SetPreviewFont(self.GetFont()) dialog.SetMinVariableSize(variable.GetSize()) varlist = [] @@ -2099,7 +2118,7 @@ dialog.Destroy() def EditConnectionContent(self, connection): - dialog = ConnectionPropertiesDialog(self.ParentWindow, self.Controler) + dialog = ConnectionDialog(self.ParentWindow, self.Controler) dialog.SetPreviewFont(self.GetFont()) dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) dialog.SetPouElementNames(self.Controler.GetEditedElementVariables(self.TagName, self.Debug)) @@ -2205,7 +2224,7 @@ dialog.Destroy() def EditStepContent(self, step): - dialog = StepContentDialog(self.ParentWindow, self.Controler, step.GetInitial()) + dialog = SFCStepDialog(self.ParentWindow, self.Controler, step.GetInitial()) dialog.SetPreviewFont(self.GetFont()) dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) dialog.SetVariables(self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)) @@ -2242,7 +2261,7 @@ step.Refresh(rect) def EditTransitionContent(self, transition): - dialog = TransitionContentDialog(self.ParentWindow, self.Controler, self.GetDrawingMode() == FREEDRAWING_MODE) + dialog = SFCTransitionDialog(self.ParentWindow, self.Controler, self.GetDrawingMode() == FREEDRAWING_MODE) dialog.SetPreviewFont(self.GetFont()) dialog.SetTransitions(self.Controler.GetEditedElementTransitions(self.TagName, self.Debug)) dialog.SetValues({"type":transition.GetType(),"value":transition.GetCondition(), "priority":transition.GetPriority()}) @@ -2825,6 +2844,9 @@ self.SelectedElement.Draw(dc) if not printing: + if self.Debug: + xstart, ystart = self.GetViewStart() + dc.DrawText(_("Debug: %s") % self.InstancePath, 2, 2) if self.rubberBand.IsShown(): self.rubberBand.Draw(dc) dc.EndDrawing() diff -r c7e0254be378 -r e183bffc05f0 dialogs/ActionBlockDialog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/ActionBlockDialog.py Fri Oct 02 18:14:43 2009 +0200 @@ -0,0 +1,402 @@ +# -*- coding: utf-8 -*- + +#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor +#based on the plcopen standard. +# +#Copyright (C) 2007: 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 +import wx.grid + +#------------------------------------------------------------------------------- +# Action Block Dialog +#------------------------------------------------------------------------------- + +def GetActionTableColnames(): + _ = lambda x: x + return [_("Qualifier"), _("Duration"), _("Type"), _("Value"), _("Indicator")] + +def GetTypeList(): + _ = lambda x: x + return [_("Action"), _("Variable"), _("Inline")] + +class ActionTable(wx.grid.PyGridTableBase): + + """ + A custom wx.Grid Table using user supplied data + """ + def __init__(self, parent, data, colnames): + # The base class must be initialized *first* + wx.grid.PyGridTableBase.__init__(self) + self.data = data + self.colnames = colnames + self.Parent = parent + # XXX + # we need to store the row length and collength to + # see if the table has changed size + self._rows = self.GetNumberRows() + self._cols = self.GetNumberCols() + + def GetNumberCols(self): + return len(self.colnames) + + def GetNumberRows(self): + return len(self.data) + + def GetColLabelValue(self, col, translate=True): + if col < len(self.colnames): + colname = self.colnames[col] + if translate: + return _(colname) + return colname + + def GetRowLabelValues(self, row, translate=True): + return row + + def GetValue(self, row, col): + if row < self.GetNumberRows(): + colname = self.GetColLabelValue(col, False) + name = str(self.data[row].get(colname, "")) + if colname == "Type": + return _(name) + return name + + def GetValueByName(self, row, colname): + return self.data[row].get(colname) + + def SetValue(self, row, col, value): + if col < len(self.colnames): + colname = self.GetColLabelValue(col, False) + if colname == "Type": + value = self.Parent.TranslateType[value] + self.data[row][colname] = value + + def ResetView(self, grid): + """ + (wx.Grid) -> Reset the grid view. Call this to + update the grid if rows and columns have been added or deleted + """ + grid.BeginBatch() + for current, new, delmsg, addmsg in [ + (self._rows, self.GetNumberRows(), wx.grid.GRIDTABLE_NOTIFY_ROWS_DELETED, wx.grid.GRIDTABLE_NOTIFY_ROWS_APPENDED), + (self._cols, self.GetNumberCols(), wx.grid.GRIDTABLE_NOTIFY_COLS_DELETED, wx.grid.GRIDTABLE_NOTIFY_COLS_APPENDED), + ]: + if new < current: + msg = wx.grid.GridTableMessage(self,delmsg,new,current-new) + grid.ProcessTableMessage(msg) + elif new > current: + msg = wx.grid.GridTableMessage(self,addmsg,new-current) + grid.ProcessTableMessage(msg) + self.UpdateValues(grid) + grid.EndBatch() + + self._rows = self.GetNumberRows() + self._cols = self.GetNumberCols() + # update the column rendering scheme + self._updateColAttrs(grid) + + # update the scrollbars and the displayed part of the grid + grid.AdjustScrollbars() + grid.ForceRefresh() + + def UpdateValues(self, grid): + """Update all displayed values""" + # This sends an event to the grid table to update all of the values + msg = wx.grid.GridTableMessage(self, wx.grid.GRIDTABLE_REQUEST_VIEW_GET_VALUES) + grid.ProcessTableMessage(msg) + + def _updateColAttrs(self, grid): + """ + wx.Grid -> update the column attributes to add the + appropriate renderer given the column name. + + Otherwise default to the default renderer. + """ + + for row in range(self.GetNumberRows()): + for col in range(self.GetNumberCols()): + editor = None + renderer = None + readonly = False + colname = self.GetColLabelValue(col, False) + if colname == "Qualifier": + editor = wx.grid.GridCellChoiceEditor() + editor.SetParameters(self.Parent.QualifierList) + if colname == "Duration": + editor = wx.grid.GridCellTextEditor() + renderer = wx.grid.GridCellStringRenderer() + if self.Parent.DurationList[self.data[row]["Qualifier"]]: + readonly = False + else: + readonly = True + self.data[row]["Duration"] = "" + elif colname == "Type": + editor = wx.grid.GridCellChoiceEditor() + editor.SetParameters(self.Parent.TypeList) + elif colname == "Value": + type = self.data[row]["Type"] + if type == "Action": + editor = wx.grid.GridCellChoiceEditor() + editor.SetParameters(self.Parent.ActionList) + elif type == "Variable": + editor = wx.grid.GridCellChoiceEditor() + editor.SetParameters(self.Parent.VariableList) + elif type == "Inline": + editor = wx.grid.GridCellTextEditor() + renderer = wx.grid.GridCellStringRenderer() + elif colname == "Indicator": + editor = wx.grid.GridCellChoiceEditor() + editor.SetParameters(self.Parent.VariableList) + + grid.SetCellEditor(row, col, editor) + grid.SetCellRenderer(row, col, renderer) + grid.SetReadOnly(row, col, readonly) + + grid.SetCellBackgroundColour(row, col, wx.WHITE) + + def SetData(self, data): + self.data = data + + def GetData(self): + return self.data + + def GetCurrentIndex(self): + return self.CurrentIndex + + def SetCurrentIndex(self, index): + self.CurrentIndex = index + + def AppendRow(self, row_content): + self.data.append(row_content) + + def RemoveRow(self, row_index): + self.data.pop(row_index) + + def MoveRow(self, row_index, move, grid): + new_index = max(0, min(row_index + move, len(self.data) - 1)) + if new_index != row_index: + self.data.insert(new_index, self.data.pop(row_index)) + grid.SetGridCursor(new_index, grid.GetGridCursorCol()) + + def Empty(self): + self.data = [] + self.editors = [] + +[ID_ACTIONBLOCKDIALOG, ID_ACTIONBLOCKDIALOGVARIABLESGRID, + ID_ACTIONBLOCKDIALOGSTATICTEXT1, ID_ACTIONBLOCKDIALOGADDBUTTON, + ID_ACTIONBLOCKDIALOGDELETEBUTTON, ID_ACTIONBLOCKDIALOGUPBUTTON, + ID_ACTIONBLOCKDIALOGDOWNBUTTON, +] = [wx.NewId() for _init_ctrls in range(7)] + +class ActionBlockDialog(wx.Dialog): + + if wx.VERSION < (2, 6, 0): + def Bind(self, event, function, id = None): + if id is not None: + event(self, id, function) + else: + event(self, function) + + def _init_coll_flexGridSizer1_Items(self, parent): + parent.AddSizer(self.TopSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) + parent.AddSizer(self.GridButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.LEFT|wx.RIGHT) + parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) + + def _init_coll_flexGridSizer1_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(0) + + def _init_coll_TopSizer_Items(self, parent): + parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.ActionsGrid, 0, border=0, flag=wx.GROW) + + def _init_coll_TopSizer_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(1) + + def _init_coll_GridButtonSizer_Items(self, parent): + parent.AddWindow(self.AddButton, 0, border=10, flag=wx.GROW|wx.LEFT) + parent.AddWindow(self.DeleteButton, 0, border=10, flag=wx.GROW|wx.LEFT) + parent.AddWindow(self.UpButton, 0, border=10, flag=wx.GROW|wx.LEFT) + parent.AddWindow(self.DownButton, 0, border=10, flag=wx.GROW|wx.LEFT) + + def _init_sizers(self): + self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=10) + self.TopSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5) + self.GridButtonSizer = wx.BoxSizer(wx.HORIZONTAL) + + self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) + self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) + self._init_coll_TopSizer_Items(self.TopSizer) + self._init_coll_TopSizer_Growables(self.TopSizer) + self._init_coll_GridButtonSizer_Items(self.GridButtonSizer) + + self.SetSizer(self.flexGridSizer1) + + def _init_ctrls(self, prnt): + wx.Dialog.__init__(self, id=ID_ACTIONBLOCKDIALOG, + name='ActionBlockDialog', parent=prnt, pos=wx.Point(376, 223), + size=wx.Size(500, 300), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER, + title=_('Edit action block properties')) + self.SetClientSize(wx.Size(500, 300)) + + self.staticText1 = wx.StaticText(id=ID_ACTIONBLOCKDIALOGSTATICTEXT1, + label=_('Actions:'), name='staticText1', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + + self.ActionsGrid = wx.grid.Grid(id=ID_ACTIONBLOCKDIALOGVARIABLESGRID, + name='ActionsGrid', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 0), style=wx.VSCROLL) + self.ActionsGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False, + 'Sans')) + self.ActionsGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL, + False, 'Sans')) + self.ActionsGrid.DisableDragGridSize() + self.ActionsGrid.EnableScrolling(False, True) + self.ActionsGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnActionsGridCellChange) + + self.AddButton = wx.Button(id=ID_ACTIONBLOCKDIALOGADDBUTTON, label=_('Add'), + name='AddButton', parent=self, pos=wx.Point(0, 0), + size=wx.DefaultSize, style=0) + self.Bind(wx.EVT_BUTTON, self.OnAddButton, id=ID_ACTIONBLOCKDIALOGADDBUTTON) + + self.DeleteButton = wx.Button(id=ID_ACTIONBLOCKDIALOGDELETEBUTTON, label=_('Delete'), + name='DeleteButton', parent=self, pos=wx.Point(0, 0), + size=wx.DefaultSize, style=0) + self.Bind(wx.EVT_BUTTON, self.OnDeleteButton, id=ID_ACTIONBLOCKDIALOGDELETEBUTTON) + + self.UpButton = wx.Button(id=ID_ACTIONBLOCKDIALOGUPBUTTON, label='^', + name='UpButton', parent=self, pos=wx.Point(0, 0), + size=wx.Size(32, 32), style=0) + self.Bind(wx.EVT_BUTTON, self.OnUpButton, id=ID_ACTIONBLOCKDIALOGUPBUTTON) + + self.DownButton = wx.Button(id=ID_ACTIONBLOCKDIALOGDOWNBUTTON, label='v', + name='DownButton', parent=self, pos=wx.Point(0, 0), + size=wx.Size(32, 32), style=0) + self.Bind(wx.EVT_BUTTON, self.OnDownButton, id=ID_ACTIONBLOCKDIALOGDOWNBUTTON) + + self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) + if wx.VERSION >= (2, 5, 0): + self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId()) + else: + self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId()) + + self._init_sizers() + + def __init__(self, parent): + self._init_ctrls(parent) + + self.DefaultValue = {"Qualifier" : "N", "Duration" : "", "Type" : "Action", "Value" : "", "Indicator" : ""} + self.Table = ActionTable(self, [], GetActionTableColnames()) + typelist = GetTypeList() + self.TypeList = ",".join(map(_,typelist)) + self.TranslateType = dict([(_(value), value) for value in typelist]) + self.ColSizes = [60, 90, 80, 110, 80] + self.ColAlignements = [wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT] + + self.ActionsGrid.SetTable(self.Table) + self.ActionsGrid.SetRowLabelSize(0) + + for col in range(self.Table.GetNumberCols()): + attr = wx.grid.GridCellAttr() + attr.SetAlignment(self.ColAlignements[col], wx.ALIGN_CENTRE) + self.ActionsGrid.SetColAttr(col, attr) + self.ActionsGrid.SetColMinimalWidth(col, self.ColSizes[col]) + self.ActionsGrid.AutoSizeColumn(col, False) + + self.Table.ResetView(self.ActionsGrid) + + def OnOK(self, event): + self.ActionsGrid.SetGridCursor(0, 0) + self.EndModal(wx.ID_OK) + + def OnAddButton(self, event): + self.Table.AppendRow(self.DefaultValue.copy()) + self.Table.ResetView(self.ActionsGrid) + event.Skip() + + def OnDeleteButton(self, event): + row = self.ActionsGrid.GetGridCursorRow() + self.Table.RemoveRow(row) + self.Table.ResetView(self.ActionsGrid) + event.Skip() + + def OnUpButton(self, event): + row = self.ActionsGrid.GetGridCursorRow() + self.Table.MoveRow(row, -1, self.ActionsGrid) + self.Table.ResetView(self.ActionsGrid) + event.Skip() + + def OnDownButton(self, event): + row = self.ActionsGrid.GetGridCursorRow() + self.Table.MoveRow(row, 1, self.ActionsGrid) + self.Table.ResetView(self.ActionsGrid) + event.Skip() + + def OnActionsGridCellChange(self, event): + self.Table.ResetView(self.ActionsGrid) + event.Skip() + + def SetQualifierList(self, list): + self.QualifierList = "," + ",".join(list) + self.DurationList = list + + def SetVariableList(self, list): + self.VariableList = "," + ",".join([variable["Name"] for variable in list]) + + def SetActionList(self, list): + self.ActionList = "," + ",".join(list) + + def SetValues(self, actions): + for action in actions: + row = {"Qualifier" : action["qualifier"], "Value" : action["value"]} + if action["type"] == "reference": + if action["value"] in self.ActionList: + row["Type"] = "Action" + elif action["value"] in self.VariableList: + row["Type"] = "Variable" + else: + row["Type"] = "Inline" + else: + row["Type"] = "Inline" + if "duration" in action: + row["Duration"] = action["duration"] + else: + row["Duration"] = "" + if "indicator" in action: + row["Indicator"] = action["indicator"] + else: + row["Indicator"] = "" + self.Table.AppendRow(row) + self.Table.ResetView(self.ActionsGrid) + + def GetValues(self): + values = [] + for data in self.Table.GetData(): + action = {"qualifier" : data["Qualifier"], "value" : data["Value"]} + if data["Type"] in ["Action", "Variable"]: + action["type"] = "reference" + else: + action["type"] = "inline" + if data["Duration"] != "": + action["duration"] = data["Duration"] + if data["Indicator"] != "": + action["indicator"] = data["Indicator"] + values.append(action) + return values diff -r c7e0254be378 -r e183bffc05f0 dialogs/ConnectionDialog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/ConnectionDialog.py Fri Oct 02 18:14:43 2009 +0200 @@ -0,0 +1,249 @@ +#!/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) 2007: 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 graphics import * + +#------------------------------------------------------------------------------- +# Create New Connection Dialog +#------------------------------------------------------------------------------- + +[ID_CONNECTIONDIALOG, ID_CONNECTIONDIALOGSPACER, + ID_CONNECTIONDIALOGNAME, ID_CONNECTIONDIALOGRADIOBUTTON1, + ID_CONNECTIONDIALOGRADIOBUTTON2, ID_CONNECTIONDIALOGPREVIEW, + ID_CONNECTIONDIALOGSTATICTEXT1, ID_CONNECTIONDIALOGSTATICTEXT2, + ID_CONNECTIONDIALOGSTATICTEXT3, +] = [wx.NewId() for _init_ctrls in range(9)] + +class ConnectionDialog(wx.Dialog): + + if wx.VERSION < (2, 6, 0): + def Bind(self, event, function, id = None): + if id is not None: + event(self, id, function) + else: + event(self, function) + + def _init_coll_flexGridSizer1_Items(self, parent): + parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) + parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) + + def _init_coll_flexGridSizer1_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(0) + + def _init_coll_MainSizer_Items(self, parent): + parent.AddSizer(self.LeftGridSizer, 1, border=5, flag=wx.GROW|wx.RIGHT) + parent.AddSizer(self.RightGridSizer, 1, border=5, flag=wx.GROW|wx.LEFT) + + def _init_coll_LeftGridSizer_Items(self, parent): + parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.radioButton1, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.radioButton2, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.ConnectionName, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW) + + def _init_coll_LeftGridSizer_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(5) + + def _init_coll_RightGridSizer_Items(self, parent): + parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW) + + def _init_coll_RightGridSizer_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(1) + + def _init_sizers(self): + self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) + self.MainSizer = wx.BoxSizer(wx.HORIZONTAL) + self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=6, vgap=5) + self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5) + + self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) + self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) + self._init_coll_MainSizer_Items(self.MainSizer) + self._init_coll_LeftGridSizer_Items(self.LeftGridSizer) + self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer) + self._init_coll_RightGridSizer_Items(self.RightGridSizer) + self._init_coll_RightGridSizer_Growables(self.RightGridSizer) + + self.SetSizer(self.flexGridSizer1) + + def _init_ctrls(self, prnt, ctrler): + wx.Dialog.__init__(self, id=ID_CONNECTIONDIALOG, + name='ConnectionDialog', parent=prnt, pos=wx.Point(376, 223), + size=wx.Size(350, 220), style=wx.DEFAULT_DIALOG_STYLE, + title=_('Connection Properties')) + self.SetClientSize(wx.Size(350, 220)) + + self.staticText1 = wx.StaticText(id=ID_CONNECTIONDIALOGSTATICTEXT1, + label=_('Type:'), name='staticText1', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + + self.staticText2 = wx.StaticText(id=ID_CONNECTIONDIALOGSTATICTEXT2, + label=_('Name:'), name='staticText2', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + + self.staticText3 = wx.StaticText(id=ID_CONNECTIONDIALOGSTATICTEXT3, + label=_('Preview:'), name='staticText3', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + + self.radioButton1 = wx.RadioButton(id=ID_CONNECTIONDIALOGRADIOBUTTON1, + label=_('Connector'), name='radioButton1', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.RB_GROUP) + self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_CONNECTIONDIALOGRADIOBUTTON1) + self.radioButton1.SetValue(True) + + self.radioButton2 = wx.RadioButton(id=ID_CONNECTIONDIALOGRADIOBUTTON2, + label=_('Continuation'), name='radioButton2', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) + self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_CONNECTIONDIALOGRADIOBUTTON2) + self.radioButton2.SetValue(False) + + self.ConnectionName = wx.TextCtrl(id=ID_CONNECTIONDIALOGNAME, + name='Name', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 24), style=0) + self.Bind(wx.EVT_TEXT, self.OnNameChanged, id=ID_CONNECTIONDIALOGNAME) + + self.Preview = wx.Panel(id=ID_CONNECTIONDIALOGPREVIEW, + name='Preview', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 0), 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, "IsOfType", ctrler.IsOfType) + + self.Spacer = wx.Panel(id=ID_CONNECTIONDIALOGSPACER, + name='Spacer', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) + + self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) + if wx.VERSION >= (2, 5, 0): + self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId()) + self.Preview.Bind(wx.EVT_PAINT, self.OnPaint) + else: + self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId()) + wx.EVT_PAINT(self.Preview, self.OnPaint) + + self._init_sizers() + + def __init__(self, parent, controler): + self._init_ctrls(parent, controler) + self.Connection = None + self.MinConnectionSize = None + + self.PouNames = [] + self.PouElementNames = [] + + def SetPreviewFont(self, font): + self.Preview.SetFont(font) + + def SetMinConnectionSize(self, size): + self.MinConnectionSize = size + + def SetValues(self, values): + for name, value in values.items(): + if name == "type": + if value == CONNECTOR: + self.radioButton1.SetValue(True) + elif value == CONTINUATION: + self.radioButton2.SetValue(True) + elif name == "name": + self.ConnectionName.SetValue(value) + self.RefreshPreview() + + def GetValues(self): + values = {} + if self.radioButton1.GetValue(): + values["type"] = CONNECTOR + else: + values["type"] = CONTINUATION + values["name"] = self.ConnectionName.GetValue() + values["width"], values["height"] = self.Connection.GetSize() + return values + + 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] + + def OnOK(self, event): + connection_name = self.ConnectionName.GetValue() + if connection_name == "": + message = wx.MessageDialog(self, _("Form isn't complete. Name must be filled!"), _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + elif not TestIdentifier(connection_name): + message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%connection_name, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + elif connection_name.upper() in IEC_KEYWORDS: + message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%connection_name, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + elif connection_name.upper() in self.PouNames: + message = wx.MessageDialog(self, _("\"%s\" pou already exists!")%connection_name, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + elif connection_name.upper() in self.PouElementNames: + message = wx.MessageDialog(self, _("\"%s\" element for this pou already exists!")%connection_name, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + else: + self.EndModal(wx.ID_OK) + + def OnTypeChanged(self, event): + self.RefreshPreview() + event.Skip() + + def OnNameChanged(self, event): + self.RefreshPreview() + event.Skip() + + def RefreshPreview(self): + dc = wx.ClientDC(self.Preview) + dc.SetFont(self.Preview.GetFont()) + dc.Clear() + if self.radioButton1.GetValue(): + self.Connection = FBD_Connector(self.Preview, CONNECTOR, self.ConnectionName.GetValue()) + else: + self.Connection = FBD_Connector(self.Preview, CONTINUATION, self.ConnectionName.GetValue()) + width, height = self.MinConnectionSize + min_width, min_height = self.Connection.GetMinSize() + width, height = max(min_width, width), max(min_height, height) + self.Connection.SetSize(width, height) + clientsize = self.Preview.GetClientSize() + x = (clientsize.width - width) / 2 + y = (clientsize.height - height) / 2 + self.Connection.SetPosition(x, y) + self.Connection.Draw(dc) + + def OnPaint(self, event): + self.RefreshPreview() + event.Skip() \ No newline at end of file diff -r c7e0254be378 -r e183bffc05f0 dialogs/FBDBlockDialog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/FBDBlockDialog.py Fri Oct 02 18:14:43 2009 +0200 @@ -0,0 +1,410 @@ +#!/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) 2007: 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 graphics import * + +#------------------------------------------------------------------------------- +# Create New Block Dialog +#------------------------------------------------------------------------------- + +[ID_FBDBLOCKDIALOG, ID_FBDBLOCKDIALOGNAME, + ID_FBDBLOCKDIALOGTYPETREE, ID_FBDBLOCKDIALOGTYPEDESC, + ID_FBDBLOCKDIALOGINPUTS, ID_FBDBLOCKDIALOGPREVIEW, + ID_FBDBLOCKDIALOGEXECUTIONORDER, ID_FBDBLOCKDIALOGEXECUTIONCONTROL, + ID_FBDBLOCKDIALOGSTATICTEXT1, ID_FBDBLOCKDIALOGSTATICTEXT2, + ID_FBDBLOCKDIALOGSTATICTEXT3, ID_FBDBLOCKDIALOGSTATICTEXT4, + ID_FBDBLOCKDIALOGSTATICTEXT5, ID_FBDBLOCKDIALOGSTATICTEXT6, +] = [wx.NewId() for _init_ctrls in range(14)] + +[CATEGORY, BLOCK] = range(2) + +class FBDBlockDialog(wx.Dialog): + + if wx.VERSION < (2, 6, 0): + def Bind(self, event, function, id = None): + if id is not None: + event(self, id, function) + else: + event(self, function) + + def _init_coll_flexGridSizer1_Items(self, parent): + parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) + parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) + + def _init_coll_flexGridSizer1_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(0) + + def _init_coll_MainSizer_Items(self, parent): + parent.AddSizer(self.LeftBoxSizer, 1, border=5, flag=wx.GROW|wx.RIGHT) + parent.AddSizer(self.RightGridSizer, 1, border=5, flag=wx.GROW|wx.LEFT) + + def _init_coll_LeftBoxSizer_Items(self, parent): + parent.AddWindow(self.TypeTree, 3, border=5, flag=wx.GROW|wx.BOTTOM) + parent.AddWindow(self.TypeDesc, 1, border=0, flag=wx.GROW) + + def _init_coll_RightGridSizer_Items(self, parent): + parent.AddSizer(self.RightUpGridSizer, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.staticText6, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW) + + def _init_coll_RightGridSizer_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(2) + + def _init_coll_RightUpGridSizer_Items(self, parent): + parent.AddWindow(self.staticText2, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP) + parent.AddWindow(self.BlockName, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.staticText3, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP) + parent.AddWindow(self.Inputs, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.staticText4, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP) + parent.AddWindow(self.ExecutionOrder, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.staticText5, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP) + parent.AddWindow(self.ExecutionControl, 0, border=0, flag=wx.GROW) + + def _init_coll_RightUpGridSizer_Growables(self, parent): + parent.AddGrowableCol(1) + + def _init_sizers(self): + self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) + self.MainSizer = wx.BoxSizer(wx.HORIZONTAL) + self.LeftBoxSizer = wx.StaticBoxSizer(self.staticbox1, wx.VERTICAL) + self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=5) + self.RightUpGridSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=4, vgap=5) + + self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) + self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) + self._init_coll_MainSizer_Items(self.MainSizer) + self._init_coll_LeftBoxSizer_Items(self.LeftBoxSizer) + self._init_coll_RightGridSizer_Items(self.RightGridSizer) + self._init_coll_RightGridSizer_Growables(self.RightGridSizer) + self._init_coll_RightUpGridSizer_Items(self.RightUpGridSizer) + self._init_coll_RightUpGridSizer_Growables(self.RightUpGridSizer) + + self.SetSizer(self.flexGridSizer1) + + def _init_ctrls(self, prnt): + wx.Dialog.__init__(self, id=ID_FBDBLOCKDIALOG, + name='FBDBlockDialog', parent=prnt, pos=wx.Point(376, 223), + size=wx.Size(600, 400), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER, + title=_('Block Properties')) + self.SetClientSize(wx.Size(600, 400)) + + self.staticbox1 = wx.StaticBox(id=ID_FBDBLOCKDIALOGSTATICTEXT1, + label=_('Type:'), name='staticBox1', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 0), style=0) + + self.staticText2 = wx.StaticText(id=ID_FBDBLOCKDIALOGSTATICTEXT2, + label=_('Name:'), name='staticText2', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) + + self.staticText3 = wx.StaticText(id=ID_FBDBLOCKDIALOGSTATICTEXT2, + label=_('Inputs:'), name='staticText4', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) + + self.staticText4 = wx.StaticText(id=ID_FBDBLOCKDIALOGSTATICTEXT4, + label=_('Execution Order:'), name='staticText4', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) + + self.staticText5 = wx.StaticText(id=ID_FBDBLOCKDIALOGSTATICTEXT5, + label=_('Execution Control:'), name='staticText5', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) + + self.staticText6 = wx.StaticText(id=ID_FBDBLOCKDIALOGSTATICTEXT6, + label=_('Preview:'), name='staticText6', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) + + if wx.Platform == '__WXMSW__': + treestyle = wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER + else: + treestyle = wx.TR_HAS_BUTTONS|wx.TR_HIDE_ROOT|wx.TR_SINGLE|wx.SUNKEN_BORDER + self.TypeTree = wx.TreeCtrl(id=ID_FBDBLOCKDIALOGTYPETREE, + name='TypeTree', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 0), style=treestyle) + self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnTypeTreeItemSelected, + id=ID_FBDBLOCKDIALOGTYPETREE) + + self.TypeDesc = wx.TextCtrl(id=ID_FBDBLOCKDIALOGTYPEDESC, + name='TypeDesc', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 0), style=wx.TE_READONLY|wx.TE_MULTILINE) + + self.BlockName = wx.TextCtrl(id=ID_FBDBLOCKDIALOGNAME, value='', + name='BlockName', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 24), style=0) + self.Bind(wx.EVT_TEXT, self.OnNameChanged, id=ID_FBDBLOCKDIALOGNAME) + + self.Inputs = wx.SpinCtrl(id=ID_FBDBLOCKDIALOGINPUTS, + name='Inputs', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=2, max=20) + self.Bind(wx.EVT_SPINCTRL, self.OnInputsChanged, id=ID_FBDBLOCKDIALOGINPUTS) + + self.ExecutionOrder = wx.SpinCtrl(id=ID_FBDBLOCKDIALOGEXECUTIONORDER, + name='ExecutionOrder', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0) + self.Bind(wx.EVT_SPINCTRL, self.OnExecutionOrderChanged, id=ID_FBDBLOCKDIALOGEXECUTIONORDER) + + self.ExecutionControl = wx.CheckBox(id=ID_FBDBLOCKDIALOGEXECUTIONCONTROL, + name='ExecutionControl', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 24), style=0) + self.Bind(wx.EVT_CHECKBOX, self.OnExecutionOrderChanged, id=ID_FBDBLOCKDIALOGEXECUTIONCONTROL) + + self.Preview = wx.Panel(id=ID_FBDBLOCKDIALOGPREVIEW, + name='Preview', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 0), 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", self.Controler.GetBlockType) + setattr(self.Preview, "IsOfType", self.Controler.IsOfType) + + self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) + if wx.VERSION >= (2, 5, 0): + self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId()) + self.Preview.Bind(wx.EVT_PAINT, self.OnPaint) + else: + self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId()) + wx.EVT_PAINT(self.Preview, self.OnPaint) + + self._init_sizers() + + def __init__(self, parent, controler): + self.Controler = controler + self._init_ctrls(parent) + self.BlockName.SetValue("") + self.BlockName.Enable(False) + self.Inputs.Enable(False) + self.Block = None + self.MinBlockSize = None + self.First = True + + self.PouNames = [] + self.PouElementNames = [] + + def SetPreviewFont(self, font): + self.Preview.SetFont(font) + + def FindTreeItem(self, root, name, inputs = None): + if root.IsOk(): + pydata = self.TypeTree.GetPyData(root) + type_inputs = pydata.get("inputs", None) + type_extension = pydata.get("extension", None) + if inputs is not None and type_inputs is not None: + if type_extension is not None: + same_inputs = type_inputs == inputs[:type_extension] + else: + same_inputs = type_inputs == inputs + else: + same_inputs = True + if self.TypeTree.GetItemText(root) == name and same_inputs: + return root + else: + if wx.VERSION < (2, 6, 0): + item, root_cookie = self.TypeTree.GetFirstChild(root, 0) + else: + item, root_cookie = self.TypeTree.GetFirstChild(root) + while item.IsOk(): + result = self.FindTreeItem(item, name, inputs) + if result: + return result + item, root_cookie = self.TypeTree.GetNextChild(root, root_cookie) + return None + + def OnOK(self, event): + selected = self.TypeTree.GetSelection() + block_name = self.BlockName.GetValue() + name_enabled = self.BlockName.IsEnabled() + if not selected.IsOk() or self.TypeTree.GetItemParent(selected) == self.TypeTree.GetRootItem() or selected == self.TypeTree.GetRootItem(): + message = wx.MessageDialog(self, _("Form isn't complete. Valid block type must be selected!"), _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + elif name_enabled and block_name == "": + message = wx.MessageDialog(self, _("Form isn't complete. Name must be filled!"), _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + elif name_enabled and not TestIdentifier(block_name): + message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%block_name, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + elif name_enabled and block_name.upper() in IEC_KEYWORDS: + message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%block_name, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + elif name_enabled and block_name.upper() in self.PouNames: + message = wx.MessageDialog(self, _("\"%s\" pou already exists!")%block_name, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + elif name_enabled and block_name.upper() in self.PouElementNames: + message = wx.MessageDialog(self, _("\"%s\" element for this pou already exists!")%block_name, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + else: + self.EndModal(wx.ID_OK) + + def SetBlockList(self, blocktypes): + if wx.Platform == '__WXMSW__': + root = self.TypeTree.AddRoot(_("Block Types")) + else: + root = self.TypeTree.AddRoot("") + self.TypeTree.SetPyData(root, {"type" : CATEGORY}) + for category in blocktypes: + category_name = category["name"] + category_item = self.TypeTree.AppendItem(root, _(category_name)) + self.TypeTree.SetPyData(category_item, {"type" : CATEGORY}) + for blocktype in category["list"]: + blocktype_item = self.TypeTree.AppendItem(category_item, blocktype["name"]) + block_data = {"type" : BLOCK, + "inputs" : tuple([type for name, type, modifier in blocktype["inputs"]]), + "extension" : None} + if blocktype["extensible"]: + block_data["extension"] = len(blocktype["inputs"]) + self.TypeTree.SetPyData(blocktype_item, block_data) + if wx.Platform == '__WXMSW__': + self.TypeTree.Expand(root) + + 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] + + def SetValues(self, values): + blocktype = values.get("type", None) + if blocktype is not None: + inputs = values.get("inputs", None) + item = self.FindTreeItem(self.TypeTree.GetRootItem(), blocktype, inputs) + if item: + self.TypeTree.SelectItem(item) + for name, value in values.items(): + if name == "name": + self.BlockName.SetValue(value) + elif name == "extension": + self.Inputs.SetValue(value) + elif name == "executionOrder": + self.ExecutionOrder.SetValue(value) + elif name == "executionControl": + self.ExecutionControl.SetValue(value) + self.RefreshPreview() + + def GetValues(self): + values = {} + item = self.TypeTree.GetSelection() + values["type"] = self.TypeTree.GetItemText(item) + values["inputs"] = self.TypeTree.GetPyData(item)["inputs"] + if self.BlockName.GetValue() != "": + values["name"] = self.BlockName.GetValue() + values["width"], values["height"] = self.Block.GetSize() + values["extension"] = self.Inputs.GetValue() + values["executionOrder"] = self.ExecutionOrder.GetValue() + values["executionControl"] = self.ExecutionControl.GetValue() + return values + + def OnTypeTreeItemSelected(self, event): + self.BlockName.SetValue("") + selected = event.GetItem() + pydata = self.TypeTree.GetPyData(selected) + if pydata["type"] != CATEGORY: + blocktype = self.Controler.GetBlockType(self.TypeTree.GetItemText(selected), pydata["inputs"]) + if blocktype: + self.Inputs.SetValue(len(blocktype["inputs"])) + self.Inputs.Enable(blocktype["extensible"]) + self.BlockName.Enable(blocktype["type"] != "function") + comment = blocktype["comment"] + self.TypeDesc.SetValue(_(comment) + blocktype.get("usage", "")) + wx.CallAfter(self.RefreshPreview) + else: + self.BlockName.Enable(False) + self.Inputs.Enable(False) + self.Inputs.SetValue(2) + self.TypeDesc.SetValue("") + wx.CallAfter(self.ErasePreview) + else: + self.BlockName.Enable(False) + self.Inputs.Enable(False) + self.Inputs.SetValue(2) + self.TypeDesc.SetValue("") + wx.CallAfter(self.ErasePreview) + event.Skip() + + def OnNameChanged(self, event): + if self.BlockName.IsEnabled(): + self.RefreshPreview() + event.Skip() + + def OnInputsChanged(self, event): + if self.Inputs.IsEnabled(): + self.RefreshPreview() + event.Skip() + + def OnExecutionOrderChanged(self, event): + self.RefreshPreview() + event.Skip() + + def OnExecutionControlChanged(self, event): + 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() + item = self.TypeTree.GetSelection() + if item.IsOk(): + pydata = self.TypeTree.GetPyData(item) + if pydata["type"] == CATEGORY: + self.Block = None + else: + blocktype = self.TypeTree.GetItemText(item) + if blocktype: + self.Block = FBD_Block(self.Preview, blocktype, + self.BlockName.GetValue(), + extension = self.Inputs.GetValue(), + inputs = pydata["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() diff -r c7e0254be378 -r e183bffc05f0 dialogs/FBDVariableDialog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/FBDVariableDialog.py Fri Oct 02 18:14:43 2009 +0200 @@ -0,0 +1,326 @@ +#!/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) 2007: 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 graphics import * + +#------------------------------------------------------------------------------- +# Create New Variable Dialog +#------------------------------------------------------------------------------- + +[ID_FBDVARIABLEDIALOG, ID_FBDVARIABLEDIALOGSPACER, + ID_FBDVARIABLEDIALOGNAME, ID_FBDVARIABLEDIALOGCLASS, + ID_FBDVARIABLEDIALOGPREVIEW, ID_FBDVARIABLEDIALOGEXPRESSION, + ID_FBDVARIABLEDIALOGEXECUTIONORDER, ID_FBDVARIABLEDIALOGSTATICTEXT1, + ID_FBDVARIABLEDIALOGSTATICTEXT2, ID_FBDVARIABLEDIALOGSTATICTEXT3, + ID_FBDVARIABLEDIALOGSTATICTEXT4, ID_FBDVARIABLEDIALOGSTATICTEXT5 +] = [wx.NewId() for _init_ctrls in range(12)] + +VARIABLE_CLASSES_DICT = {INPUT : _("Input"), + INOUT : _("InOut"), + OUTPUT : _("Output")} +VARIABLE_CLASSES_DICT_REVERSE = dict([(value, key) for key, value in VARIABLE_CLASSES_DICT.iteritems()]) + +class FBDVariableDialog(wx.Dialog): + + if wx.VERSION < (2, 6, 0): + def Bind(self, event, function, id = None): + if id is not None: + event(self, id, function) + else: + event(self, function) + + def _init_coll_flexGridSizer1_Items(self, parent): + parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) + parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) + + def _init_coll_flexGridSizer1_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(0) + + def _init_coll_MainSizer_Items(self, parent): + parent.AddSizer(self.TopSizer, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.staticText5, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW) + + def _init_coll_MainSizer_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(2) + + def _init_coll_TopSizer_Items(self, parent): + parent.AddSizer(self.LeftGridSizer, 1, border=5, flag=wx.GROW|wx.RIGHT) + parent.AddSizer(self.RightGridSizer, 1, border=5, flag=wx.GROW|wx.LEFT) + + def _init_coll_LeftGridSizer_Items(self, parent): + parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.Class, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.Expression, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.ExecutionOrder, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW) + + def _init_coll_LeftGridSizer_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(2) + + def _init_coll_RightGridSizer_Items(self, parent): + parent.AddWindow(self.staticText4, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.VariableName, 0, border=0, flag=wx.GROW) + + def _init_coll_RightGridSizer_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(1) + + def _init_sizers(self): + self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) + self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=5) + self.TopSizer = wx.BoxSizer(wx.HORIZONTAL) + self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=7, vgap=5) + self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5) + + self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) + self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) + self._init_coll_MainSizer_Items(self.MainSizer) + self._init_coll_MainSizer_Growables(self.MainSizer) + self._init_coll_TopSizer_Items(self.TopSizer) + self._init_coll_LeftGridSizer_Items(self.LeftGridSizer) + self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer) + self._init_coll_RightGridSizer_Items(self.RightGridSizer) + self._init_coll_RightGridSizer_Growables(self.RightGridSizer) + + self.SetSizer(self.flexGridSizer1) + + def _init_ctrls(self, prnt, ctrler): + wx.Dialog.__init__(self, id=ID_FBDVARIABLEDIALOG, + name='FBDVariableDialog', parent=prnt, pos=wx.Point(376, 223), + size=wx.Size(400, 380), style=wx.DEFAULT_DIALOG_STYLE, + title=_('Variable Properties')) + self.SetClientSize(wx.Size(400, 380)) + + self.staticText1 = wx.StaticText(id=ID_FBDVARIABLEDIALOGSTATICTEXT1, + label=_('Class:'), name='staticText1', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + + self.staticText2 = wx.StaticText(id=ID_FBDVARIABLEDIALOGSTATICTEXT2, + label=_('Expression:'), name='staticText2', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + + self.staticText3 = wx.StaticText(id=ID_FBDVARIABLEDIALOGSTATICTEXT3, + label=_('Execution Order:'), name='staticText3', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + + self.staticText4 = wx.StaticText(id=ID_FBDVARIABLEDIALOGSTATICTEXT4, + label=_('Name:'), name='staticText4', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + + self.staticText5 = wx.StaticText(id=ID_FBDVARIABLEDIALOGSTATICTEXT5, + label=_('Preview:'), name='staticText5', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + + self.Class = wx.ComboBox(id=ID_FBDVARIABLEDIALOGCLASS, + name='Class', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 28), style=wx.CB_READONLY) + self.Bind(wx.EVT_COMBOBOX, self.OnClassChanged, id=ID_FBDVARIABLEDIALOGCLASS) + + self.VariableName = wx.ListBox(id=ID_FBDVARIABLEDIALOGNAME, + name='Name', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 90), style=wx.LB_SINGLE|wx.LB_SORT) + self.Bind(wx.EVT_LISTBOX, self.OnNameChanged, id=ID_FBDVARIABLEDIALOGNAME) + + self.Expression = wx.TextCtrl(id=ID_FBDVARIABLEDIALOGEXPRESSION, + name='Expression', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 24), style=0) + self.Bind(wx.EVT_TEXT, self.OnExpressionChanged, id=ID_FBDVARIABLEDIALOGEXPRESSION) + + self.ExecutionOrder = wx.SpinCtrl(id=ID_FBDVARIABLEDIALOGEXECUTIONORDER, + name='ExecutionOrder', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0) + self.Bind(wx.EVT_SPINCTRL, self.OnExecutionOrderChanged, id=ID_FBDVARIABLEDIALOGEXECUTIONORDER) + + self.Spacer = wx.Panel(id=ID_FBDVARIABLEDIALOGSPACER, + name='Spacer', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) + + self.Preview = wx.Panel(id=ID_FBDVARIABLEDIALOGPREVIEW, + name='Preview', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 0), 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, "IsOfType", ctrler.IsOfType) + + self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) + if wx.VERSION >= (2, 5, 0): + self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId()) + self.Preview.Bind(wx.EVT_PAINT, self.OnPaint) + else: + self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId()) + wx.EVT_PAINT(self.Preview, self.OnPaint) + + self._init_sizers() + + def __init__(self, parent, controler, transition = ""): + self._init_ctrls(parent, controler) + self.Transition = transition + self.Variable = None + self.VarList = [] + self.MinVariableSize = None + + for choice in VARIABLE_CLASSES_DICT.itervalues(): + self.Class.Append(choice) + self.Class.SetStringSelection(VARIABLE_CLASSES_DICT[INPUT]) + + self.RefreshNameList() + + def SetPreviewFont(self, font): + self.Preview.SetFont(font) + + def RefreshNameList(self): + selected = self.VariableName.GetStringSelection() + var_class = VARIABLE_CLASSES_DICT_REVERSE[self.Class.GetStringSelection()] + self.VariableName.Clear() + self.VariableName.Append("") + for name, var_type, value_type in self.VarList: + if var_type != "Input" or var_class == INPUT: + self.VariableName.Append(name) + if selected != "" and self.VariableName.FindString(selected) != wx.NOT_FOUND: + self.VariableName.SetStringSelection(selected) + self.Expression.Enable(False) + else: + self.VariableName.SetStringSelection("") + self.Expression.Enable(var_class == INPUT) + self.VariableName.Enable(self.VariableName.GetCount() > 0) + + def SetMinVariableSize(self, size): + self.MinVariableSize = size + + def SetVariables(self, vars): + self.VarList = vars + self.RefreshNameList() + + def SetValues(self, values): + value_type = values.get("type", None) + value_name = values.get("name", None) + if value_type: + self.Class.SetStringSelection(VARIABLE_CLASSES_DICT[value_type]) + self.RefreshNameList() + if value_name: + if self.VariableName.FindString(value_name) != wx.NOT_FOUND: + self.VariableName.SetStringSelection(value_name) + self.Expression.Enable(False) + else: + self.Expression.SetValue(value_name) + self.VariableName.Enable(False) + if "executionOrder" in values: + self.ExecutionOrder.SetValue(values["executionOrder"]) + self.RefreshPreview() + + def GetValues(self): + values = {} + values["type"] = VARIABLE_CLASSES_DICT_REVERSE[self.Class.GetStringSelection()] + expression = self.Expression.GetValue() + if self.Expression.IsEnabled() and expression != "": + values["name"] = expression + else: + values["name"] = self.VariableName.GetStringSelection() + values["value_type"] = None + for var_name, var_type, value_type in self.VarList: + if var_name == values["name"]: + values["value_type"] = value_type + values["width"], values["height"] = self.Variable.GetSize() + values["executionOrder"] = self.ExecutionOrder.GetValue() + return values + + def OnOK(self, event): + expression = self.Expression.GetValue() + if self.Expression.IsEnabled(): + value = expression + else: + value = self.VariableName.GetStringSelection() + if value == "": + message = wx.MessageDialog(self, _("At least a variable or an expression must be selected!"), _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + elif value.upper() in IEC_KEYWORDS: + message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%value, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + else: + self.EndModal(wx.ID_OK) + + def OnClassChanged(self, event): + self.RefreshNameList() + self.RefreshPreview() + event.Skip() + + def OnNameChanged(self, event): + if self.VariableName.GetStringSelection() != "": + self.Expression.Enable(False) + elif VARIABLE_CLASSES_DICT_REVERSE[self.Class.GetStringSelection()] == INPUT: + self.Expression.Enable(True) + self.RefreshPreview() + event.Skip() + + def OnExpressionChanged(self, event): + if self.Expression.GetValue() != "": + self.VariableName.Enable(False) + else: + self.VariableName.Enable(True) + self.RefreshPreview() + event.Skip() + + def OnExecutionOrderChanged(self, event): + self.RefreshPreview() + event.Skip() + + def RefreshPreview(self): + dc = wx.ClientDC(self.Preview) + dc.SetFont(self.Preview.GetFont()) + dc.Clear() + expression = self.Expression.GetValue() + if self.Expression.IsEnabled() and expression != "": + name = expression + else: + name = self.VariableName.GetStringSelection() + type = "" + for var_name, var_type, value_type in self.VarList: + if var_name == name: + type = value_type + classtype = VARIABLE_CLASSES_DICT_REVERSE[self.Class.GetStringSelection()] + self.Variable = FBD_Variable(self.Preview, classtype, name, type, executionOrder = self.ExecutionOrder.GetValue()) + width, height = self.MinVariableSize + min_width, min_height = self.Variable.GetMinSize() + width, height = max(min_width, width), max(min_height, height) + self.Variable.SetSize(width, height) + clientsize = self.Preview.GetClientSize() + x = (clientsize.width - width) / 2 + y = (clientsize.height - height) / 2 + self.Variable.SetPosition(x, y) + self.Variable.Draw(dc) + + def OnPaint(self, event): + self.RefreshPreview() + event.Skip() diff -r c7e0254be378 -r e183bffc05f0 dialogs/LDElementDialog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/LDElementDialog.py Fri Oct 02 18:14:43 2009 +0200 @@ -0,0 +1,290 @@ +#!/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) 2007: 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 graphics import * + +#------------------------------------------------------------------------------- +# Edit Ladder Element Properties Dialog +#------------------------------------------------------------------------------- + + +[ID_LDELEMENTDIALOG, ID_LDELEMENTDIALOGSPACER, + ID_LDELEMENTDIALOGNAME, ID_LDELEMENTDIALOGRADIOBUTTON1, + ID_LDELEMENTDIALOGRADIOBUTTON2, ID_LDELEMENTDIALOGRADIOBUTTON3, + ID_LDELEMENTDIALOGRADIOBUTTON4, ID_LDELEMENTDIALOGRADIOBUTTON5, + ID_LDELEMENTDIALOGRADIOBUTTON6, ID_LDELEMENTDIALOGPREVIEW, + ID_LDELEMENTDIALOGSTATICTEXT1, ID_LDELEMENTDIALOGSTATICTEXT2, + ID_LDELEMENTDIALOGSTATICTEXT3, +] = [wx.NewId() for _init_ctrls in range(13)] + +class LDElementDialog(wx.Dialog): + + if wx.VERSION < (2, 6, 0): + def Bind(self, event, function, id = None): + if id is not None: + event(self, id, function) + else: + event(self, function) + + def _init_coll_flexGridSizer1_Items(self, parent): + parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) + parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) + + def _init_coll_flexGridSizer1_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(0) + + def _init_coll_MainSizer_Items(self, parent): + parent.AddSizer(self.LeftGridSizer, 1, border=5, flag=wx.GROW|wx.RIGHT) + parent.AddSizer(self.RightGridSizer, 1, border=5, flag=wx.GROW|wx.LEFT) + + def _init_coll_LeftGridSizer_Items(self, parent): + parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW) + parent.AddSizer(self.RadioButtonSizer, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.ElementName, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW) + + def _init_coll_LeftGridSizer_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(7) + + def _init_coll_RadioButtonSizer_Items(self, parent): + parent.AddWindow(self.radioButton1, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.radioButton2, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.radioButton3, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.radioButton4, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.radioButton5, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.radioButton6, 0, border=0, flag=wx.GROW) + + def _init_coll_RightGridSizer_Items(self, parent): + parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW) + + def _init_coll_RightGridSizer_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(1) + + def _init_sizers(self): + self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) + self.MainSizer = wx.BoxSizer(wx.HORIZONTAL) + self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=5, vgap=5) + self.RadioButtonSizer = wx.BoxSizer(wx.VERTICAL) + self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5) + + self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) + self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) + self._init_coll_MainSizer_Items(self.MainSizer) + self._init_coll_LeftGridSizer_Items(self.LeftGridSizer) + self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer) + self._init_coll_RadioButtonSizer_Items(self.RadioButtonSizer) + self._init_coll_RightGridSizer_Items(self.RightGridSizer) + self._init_coll_RightGridSizer_Growables(self.RightGridSizer) + + self.SetSizer(self.flexGridSizer1) + + def _init_ctrls(self, prnt, ctrler, title, extra_size = 0): + wx.Dialog.__init__(self, id=ID_LDELEMENTDIALOG, + name='LDElementDialog', parent=prnt, pos=wx.Point(376, 223), + size=wx.Size(350, 260 + extra_size), style=wx.DEFAULT_DIALOG_STYLE, + title=title) + self.SetClientSize(wx.Size(350, 260 + extra_size)) + + self.staticText1 = wx.StaticText(id=ID_LDELEMENTDIALOGSTATICTEXT1, + label=_('Modifier:'), name='staticText1', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + + self.staticText2 = wx.StaticText(id=ID_LDELEMENTDIALOGSTATICTEXT2, + label=_('Name:'), name='staticText2', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + + self.staticText3 = wx.StaticText(id=ID_LDELEMENTDIALOGSTATICTEXT3, + label=_('Preview:'), name='staticText3', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + + self.radioButton1 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON1, + label=_("Normal"), name='radioButton1', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.RB_GROUP) + self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON1) + self.radioButton1.SetValue(True) + + self.radioButton2 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON2, + label=_("Negated"), name='radioButton2', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) + self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON2) + + self.radioButton3 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON3, + label=_("Set"), name='radioButton3', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) + self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON3) + + self.radioButton4 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON4, + label=_("Reset"), name='radioButton4', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) + self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON4) + + self.radioButton5 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON5, + label=_("Rising Edge"), name='radioButton5', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) + self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON5) + + self.radioButton6 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON6, + label=_("Falling Edge"), name='radioButton6', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) + self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON6) + + self.ElementName = wx.ComboBox(id=ID_LDELEMENTDIALOGNAME, + name='Name', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 28), style=wx.CB_READONLY) + self.Bind(wx.EVT_COMBOBOX, self.OnNameChanged, id=ID_LDELEMENTDIALOGNAME) + + self.Preview = wx.Panel(id=ID_LDELEMENTDIALOGPREVIEW, + name='Preview', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 0), 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, "IsOfType", ctrler.IsOfType) + + self.Spacer = wx.Panel(id=ID_LDELEMENTDIALOGSPACER, + name='Spacer', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) + + self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) + + if wx.VERSION >= (2, 5, 0): + self.Preview.Bind(wx.EVT_PAINT, self.OnPaint) + else: + wx.EVT_PAINT(self.Preview, self.OnPaint) + + self._init_sizers() + + def __init__(self, parent, controler, type): + self.Type = type + if type == "contact": + self._init_ctrls(parent, controler, _("Edit Contact Values")) + self.Element = LD_Contact(self.Preview, CONTACT_NORMAL, "") + self.radioButton3.Hide() + self.radioButton4.Hide() + elif type == "coil": + self._init_ctrls(parent, controler, _("Edit Coil Values"), 50) + self.Element = LD_Coil(self.Preview, COIL_NORMAL, "") + + + def SetPreviewFont(self, font): + self.Preview.SetFont(font) + + def SetElementSize(self, size): + min_width, min_height = self.Element.GetMinSize() + width, height = max(min_width, size[0]), max(min_height, size[1]) + self.Element.SetSize(width, height) + + def SetVariables(self, vars): + self.ElementName.Clear() + for name in vars: + self.ElementName.Append(name) + self.ElementName.Enable(self.ElementName.GetCount() > 0) + + def SetValues(self, values): + for name, value in values.items(): + if name == "name": + self.Element.SetName(value) + self.ElementName.SetStringSelection(value) + elif name == "type": + self.Element.SetType(value) + if self.Type == "contact": + if value == CONTACT_NORMAL: + self.radioButton1.SetValue(True) + elif value == CONTACT_REVERSE: + self.radioButton2.SetValue(True) + elif value == CONTACT_RISING: + self.radioButton5.SetValue(True) + elif value == CONTACT_FALLING: + self.radioButton6.SetValue(True) + elif self.Type == "coil": + if value == COIL_NORMAL: + self.radioButton1.SetValue(True) + elif value == COIL_REVERSE: + self.radioButton2.SetValue(True) + elif value == COIL_SET: + self.radioButton3.SetValue(True) + elif value == COIL_RESET: + self.radioButton4.SetValue(True) + elif value == COIL_RISING: + self.radioButton5.SetValue(True) + elif value == COIL_FALLING: + self.radioButton6.SetValue(True) + + def GetValues(self): + values = {} + values["name"] = self.Element.GetName() + values["type"] = self.Element.GetType() + values["width"], values["height"] = self.Element.GetSize() + return values + + def OnTypeChanged(self, event): + if self.Type == "contact": + if self.radioButton1.GetValue(): + self.Element.SetType(CONTACT_NORMAL) + elif self.radioButton2.GetValue(): + self.Element.SetType(CONTACT_REVERSE) + elif self.radioButton5.GetValue(): + self.Element.SetType(CONTACT_RISING) + elif self.radioButton6.GetValue(): + self.Element.SetType(CONTACT_FALLING) + elif self.Type == "coil": + if self.radioButton1.GetValue(): + self.Element.SetType(COIL_NORMAL) + elif self.radioButton2.GetValue(): + self.Element.SetType(COIL_REVERSE) + elif self.radioButton3.GetValue(): + self.Element.SetType(COIL_SET) + elif self.radioButton4.GetValue(): + self.Element.SetType(COIL_RESET) + elif self.radioButton5.GetValue(): + self.Element.SetType(COIL_RISING) + elif self.radioButton6.GetValue(): + self.Element.SetType(COIL_FALLING) + self.RefreshPreview() + event.Skip() + + def OnNameChanged(self, event): + self.Element.SetName(self.ElementName.GetStringSelection()) + self.RefreshPreview() + event.Skip() + + def RefreshPreview(self): + dc = wx.ClientDC(self.Preview) + dc.SetFont(self.Preview.GetFont()) + dc.Clear() + clientsize = self.Preview.GetClientSize() + width, height = self.Element.GetSize() + self.Element.SetPosition((clientsize.width - width) / 2, (clientsize.height - height) / 2) + self.Element.Draw(dc) + + def OnPaint(self, event): + self.RefreshPreview() + event.Skip() diff -r c7e0254be378 -r e183bffc05f0 dialogs/LDPowerRailDialog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/LDPowerRailDialog.py Fri Oct 02 18:14:43 2009 +0200 @@ -0,0 +1,206 @@ +# -*- coding: utf-8 -*- + +#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor +#based on the plcopen standard. +# +#Copyright (C) 2007: 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 graphics import * + + +#------------------------------------------------------------------------------- +# Edit Ladder Power Rail Properties Dialog +#------------------------------------------------------------------------------- + + +[ID_LDPOWERRAILDIALOG, ID_LDPOWERRAILDIALOGSPACER, + ID_LDPOWERRAILDIALOGTYPE, ID_LDPOWERRAILDIALOGRADIOBUTTON1, + ID_LDPOWERRAILDIALOGRADIOBUTTON2, ID_LDPOWERRAILDIALOGPREVIEW, + ID_LDPOWERRAILDIALOGSTATICTEXT1, ID_LDPOWERRAILDIALOGSTATICTEXT2, + ID_LDPOWERRAILDIALOGSTATICTEXT3, ID_LDPOWERRAILDIALOGPINNUMBER, +] = [wx.NewId() for _init_ctrls in range(10)] + +class LDPowerRailDialog(wx.Dialog): + + if wx.VERSION < (2, 6, 0): + def Bind(self, event, function, id = None): + if id is not None: + event(self, id, function) + else: + event(self, function) + + def _init_coll_flexGridSizer1_Items(self, parent): + parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) + parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) + + def _init_coll_flexGridSizer1_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(0) + + def _init_coll_MainSizer_Items(self, parent): + parent.AddSizer(self.LeftGridSizer, 1, border=5, flag=wx.GROW|wx.RIGHT) + parent.AddSizer(self.RightGridSizer, 1, border=5, flag=wx.GROW|wx.LEFT) + + def _init_coll_LeftGridSizer_Items(self, parent): + parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.radioButton1, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.radioButton2, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.PinNumber, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW) + + def _init_coll_LeftGridSizer_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(5) + + def _init_coll_RightGridSizer_Items(self, parent): + parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW) + + def _init_coll_RightGridSizer_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(1) + + def _init_sizers(self): + self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) + self.MainSizer = wx.BoxSizer(wx.HORIZONTAL) + self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=6, vgap=5) + self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5) + + self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) + self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) + self._init_coll_MainSizer_Items(self.MainSizer) + self._init_coll_LeftGridSizer_Items(self.LeftGridSizer) + self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer) + self._init_coll_RightGridSizer_Items(self.RightGridSizer) + self._init_coll_RightGridSizer_Growables(self.RightGridSizer) + + self.SetSizer(self.flexGridSizer1) + + def _init_ctrls(self, prnt, ctrler): + wx.Dialog.__init__(self, id=ID_LDPOWERRAILDIALOG, + name='PowerRailDialog', parent=prnt, pos=wx.Point(376, 223), + size=wx.Size(350, 260), style=wx.DEFAULT_DIALOG_STYLE, + title=_('Power Rail Properties')) + self.SetClientSize(wx.Size(350, 260)) + + self.staticText1 = wx.StaticText(id=ID_LDPOWERRAILDIALOGSTATICTEXT1, + label=_('Type:'), name='staticText1', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + + self.staticText2 = wx.StaticText(id=ID_LDPOWERRAILDIALOGSTATICTEXT2, + label=_('Pin number:'), name='staticText2', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + + self.staticText3 = wx.StaticText(id=ID_LDPOWERRAILDIALOGSTATICTEXT3, + label=_('Preview:'), name='staticText3', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + + self.radioButton1 = wx.RadioButton(id=ID_LDPOWERRAILDIALOGRADIOBUTTON1, + label=_('Left PowerRail'), name='radioButton1', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.RB_GROUP) + self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDPOWERRAILDIALOGRADIOBUTTON1) + self.radioButton1.SetValue(True) + + self.radioButton2 = wx.RadioButton(id=ID_LDPOWERRAILDIALOGRADIOBUTTON2, + label=_('Right PowerRail'), name='radioButton2', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) + self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDPOWERRAILDIALOGRADIOBUTTON2) + + self.PinNumber = wx.SpinCtrl(id=ID_LDPOWERRAILDIALOGPINNUMBER, + name='PinNumber', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=1, max=50) + self.Bind(wx.EVT_SPINCTRL, self.OnPinNumberChanged, id=ID_LDPOWERRAILDIALOGPINNUMBER) + + self.Preview = wx.Panel(id=ID_LDPOWERRAILDIALOGPREVIEW, + name='Preview', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 0), 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, "IsOfType", ctrler.IsOfType) + + self.Spacer = wx.Panel(id=ID_LDELEMENTDIALOGSPACER, + name='Spacer', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) + + self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) + + if wx.VERSION >= (2, 5, 0): + self.Preview.Bind(wx.EVT_PAINT, self.OnPaint) + else: + wx.EVT_PAINT(self.Preview, self.OnPaint) + + self._init_sizers() + + def __init__(self, parent, controler, type = LEFTRAIL, number = 1): + self._init_ctrls(parent, controler) + self.Type = type + if type == LEFTRAIL: + self.radioButton1.SetValue(True) + elif type == RIGHTRAIL: + self.radioButton2.SetValue(True) + self.PinNumber.SetValue(number) + + self.PowerRailMinSize = (0, 0) + self.PowerRail = None + + def SetPreviewFont(self, font): + self.Preview.SetFont(font) + + def SetMinSize(self, size): + self.PowerRailMinSize = size + self.RefreshPreview() + + def GetValues(self): + values = {} + values["type"] = self.Type + values["number"] = self.PinNumber.GetValue() + values["width"], values["height"] = self.PowerRail.GetSize() + return values + + def OnTypeChanged(self, event): + if self.radioButton1.GetValue(): + self.Type = LEFTRAIL + elif self.radioButton2.GetValue(): + self.Type = RIGHTRAIL + self.RefreshPreview() + event.Skip() + + def OnPinNumberChanged(self, event): + self.RefreshPreview() + event.Skip() + + def RefreshPreview(self): + dc = wx.ClientDC(self.Preview) + dc.SetFont(self.Preview.GetFont()) + dc.Clear() + self.PowerRail = LD_PowerRail(self.Preview, self.Type, connectors = [True for i in xrange(self.PinNumber.GetValue())]) + min_width, min_height = 2, LD_LINE_SIZE * self.PinNumber.GetValue() + width, height = max(min_width, self.PowerRailMinSize[0]), max(min_height, self.PowerRailMinSize[1]) + self.PowerRail.SetSize(width, height) + clientsize = self.Preview.GetClientSize() + self.PowerRail.SetPosition((clientsize.width - width) / 2, (clientsize.height - height) / 2) + self.PowerRail.Draw(dc) + + def OnPaint(self, event): + self.RefreshPreview() + event.Skip() diff -r c7e0254be378 -r e183bffc05f0 dialogs/PouNameDialog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/PouNameDialog.py Fri Oct 02 18:14:43 2009 +0200 @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- + +#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor +#based on the plcopen standard. +# +#Copyright (C) 2007: 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 + +#------------------------------------------------------------------------------- +# POU Name Dialog +#------------------------------------------------------------------------------- + +class PouNameDialog(wx.TextEntryDialog): + + if wx.VERSION < (2, 6, 0): + def Bind(self, event, function, id = None): + if id is not None: + event(self, id, function) + else: + event(self, function) + + + def __init__(self, parent, message, caption = "Please enter text", defaultValue = "", + style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition): + wx.TextEntryDialog.__init__(self, parent, message, caption, defaultValue, style, pos) + + self.PouNames = [] + if wx.VERSION >= (2, 8, 0): + self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(2).GetSizer().GetItem(1).GetSizer().GetAffirmativeButton().GetId()) + elif wx.VERSION >= (2, 6, 0): + self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetAffirmativeButton().GetId()) + else: + self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId()) + + def OnOK(self, event): + step_name = self.GetSizer().GetItem(1).GetWindow().GetValue() + if step_name == "": + message = wx.MessageDialog(self, _("You must type a name!"), _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + elif not TestIdentifier(step_name): + message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + elif step_name.upper() in IEC_KEYWORDS: + message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + elif step_name.upper() in self.PouNames: + message = wx.MessageDialog(self, _("A pou with \"%s\" as name exists!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + else: + self.EndModal(wx.ID_OK) + + def SetPouNames(self, pou_names): + self.PouNames = [pou_name.upper() for pou_name in pou_names] + + def GetValue(self): + return self.GetSizer().GetItem(1).GetWindow().GetValue() diff -r c7e0254be378 -r e183bffc05f0 dialogs/SFCDivergenceDialog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/SFCDivergenceDialog.py Fri Oct 02 18:14:43 2009 +0200 @@ -0,0 +1,223 @@ +# -*- coding: utf-8 -*- + +#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor +#based on the plcopen standard. +# +#Copyright (C) 2007: 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 graphics import * + +#------------------------------------------------------------------------------- +# Create New Divergence Dialog +#------------------------------------------------------------------------------- + +[ID_SFCDIVERGENCEDIALOG, ID_SFCDIVERGENCEDIALOGSPACER, + ID_SFCDIVERGENCEDIALOGRADIOBUTTON1, ID_SFCDIVERGENCEDIALOGRADIOBUTTON2, + ID_SFCDIVERGENCEDIALOGRADIOBUTTON3, ID_SFCDIVERGENCEDIALOGRADIOBUTTON4, + ID_SFCDIVERGENCEDIALOGSEQUENCES, ID_SFCDIVERGENCEDIALOGPREVIEW, + ID_SFCDIVERGENCEDIALOGSTATICTEXT1, ID_SFCDIVERGENCEDIALOGSTATICTEXT2, + ID_SFCDIVERGENCEDIALOGSTATICTEXT3, +] = [wx.NewId() for _init_ctrls in range(11)] + +class SFCDivergenceDialog(wx.Dialog): + + if wx.VERSION < (2, 6, 0): + def Bind(self, event, function, id = None): + if id is not None: + event(self, id, function) + else: + event(self, function) + + def _init_coll_flexGridSizer1_Items(self, parent): + parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) + parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) + + def _init_coll_flexGridSizer1_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(0) + + def _init_coll_MainSizer_Items(self, parent): + parent.AddSizer(self.LeftGridSizer, 1, border=5, flag=wx.GROW|wx.RIGHT) + parent.AddSizer(self.RightGridSizer, 1, border=5, flag=wx.GROW|wx.LEFT) + + def _init_coll_LeftGridSizer_Items(self, parent): + parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.radioButton1, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.radioButton2, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.radioButton3, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.radioButton4, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.Sequences, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW) + + def _init_coll_LeftGridSizer_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(7) + + def _init_coll_RightGridSizer_Items(self, parent): + parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW) + + def _init_coll_RightGridSizer_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(1) + + def _init_sizers(self): + self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) + self.MainSizer = wx.BoxSizer(wx.HORIZONTAL) + self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=8, vgap=5) + self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5) + + self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) + self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) + self._init_coll_MainSizer_Items(self.MainSizer) + self._init_coll_LeftGridSizer_Items(self.LeftGridSizer) + self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer) + self._init_coll_RightGridSizer_Items(self.RightGridSizer) + self._init_coll_RightGridSizer_Growables(self.RightGridSizer) + + self.SetSizer(self.flexGridSizer1) + + def _init_ctrls(self, prnt, ctrler): + wx.Dialog.__init__(self, id=ID_SFCDIVERGENCEDIALOG, + name='SFCDivergenceDialog', parent=prnt, pos=wx.Point(376, 223), + size=wx.Size(500, 300), style=wx.DEFAULT_DIALOG_STYLE, + title=_('Create a new divergence or convergence')) + self.SetClientSize(wx.Size(500, 300)) + + self.staticText1 = wx.StaticText(id=ID_SFCDIVERGENCEDIALOGSTATICTEXT1, + label=_('Type:'), name='staticText1', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + + self.radioButton1 = wx.RadioButton(id=ID_SFCDIVERGENCEDIALOGRADIOBUTTON1, + label=_('Selection Divergence'), name='radioButton1', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.RB_GROUP) + self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_SFCDIVERGENCEDIALOGRADIOBUTTON1) + self.radioButton1.SetValue(True) + + self.radioButton2 = wx.RadioButton(id=ID_SFCDIVERGENCEDIALOGRADIOBUTTON2, + label=_('Selection Convergence'), name='radioButton2', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) + self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_SFCDIVERGENCEDIALOGRADIOBUTTON2) + self.radioButton2.SetValue(False) + + self.radioButton3 = wx.RadioButton(id=ID_SFCDIVERGENCEDIALOGRADIOBUTTON3, + label=_('Simultaneous Divergence'), name='radioButton3', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) + self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_SFCDIVERGENCEDIALOGRADIOBUTTON3) + self.radioButton3.SetValue(False) + + self.radioButton4 = wx.RadioButton(id=ID_SFCDIVERGENCEDIALOGRADIOBUTTON4, + label=_('Simultaneous Convergence'), name='radioButton4', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) + self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_SFCDIVERGENCEDIALOGRADIOBUTTON4) + self.radioButton4.SetValue(False) + + self.staticText2 = wx.StaticText(id=ID_SFCDIVERGENCEDIALOGSTATICTEXT2, + label=_('Number of sequences:'), name='staticText2', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + + self.Sequences = wx.SpinCtrl(id=ID_SFCDIVERGENCEDIALOGSEQUENCES, + name='Sequences', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 24), style=0, min=2, max=20) + self.Bind(wx.EVT_SPINCTRL, self.OnSequencesChanged, id=ID_SFCDIVERGENCEDIALOGSEQUENCES) + + self.staticText3 = wx.StaticText(id=ID_SFCDIVERGENCEDIALOGSTATICTEXT3, + label=_('Preview:'), name='staticText3', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + + self.Preview = wx.Panel(id=ID_SFCDIVERGENCEDIALOGPREVIEW, + name='Preview', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 0), 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, "IsOfType", ctrler.IsOfType) + + self.Spacer = wx.Panel(id=ID_TRANSITIONCONTENTDIALOGSPACER, + name='Spacer', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) + + self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) + + if wx.VERSION >= (2, 5, 0): + self.Preview.Bind(wx.EVT_PAINT, self.OnPaint) + else: + wx.EVT_PAINT(self.Preview, self.OnPaint) + + self._init_sizers() + + def __init__(self, parent, controler): + self._init_ctrls(parent, controler) + + self.Divergence = None + self.MinSize = (0, 0) + + def SetPreviewFont(self, font): + self.Preview.SetFont(font) + + def GetValues(self): + values = {} + if self.radioButton1.GetValue(): + values["type"] = SELECTION_DIVERGENCE + elif self.radioButton2.GetValue(): + values["type"] = SELECTION_CONVERGENCE + elif self.radioButton3.GetValue(): + values["type"] = SIMULTANEOUS_DIVERGENCE + else: + values["type"] = SIMULTANEOUS_CONVERGENCE + values["number"] = self.Sequences.GetValue() + return values + + def SetMinSize(self, size): + self.MinSize = size + + def OnTypeChanged(self, event): + self.RefreshPreview() + event.Skip() + + def OnSequencesChanged(self, event): + self.RefreshPreview() + event.Skip() + + def RefreshPreview(self): + dc = wx.ClientDC(self.Preview) + dc.SetFont(self.Preview.GetFont()) + dc.Clear() + if self.radioButton1.GetValue(): + self.Divergence = SFC_Divergence(self.Preview, SELECTION_DIVERGENCE, self.Sequences.GetValue()) + elif self.radioButton2.GetValue(): + self.Divergence = SFC_Divergence(self.Preview, SELECTION_CONVERGENCE, self.Sequences.GetValue()) + elif self.radioButton3.GetValue(): + self.Divergence = SFC_Divergence(self.Preview, SIMULTANEOUS_DIVERGENCE, self.Sequences.GetValue()) + else: + self.Divergence = SFC_Divergence(self.Preview, SIMULTANEOUS_CONVERGENCE, self.Sequences.GetValue()) + width, height = self.Divergence.GetSize() + min_width, min_height = max(width, self.MinSize[0]), max(height, self.MinSize[1]) + self.Divergence.SetSize(min_width, min_height) + clientsize = self.Preview.GetClientSize() + x = (clientsize.width - min_width) / 2 + y = (clientsize.height - min_height) / 2 + self.Divergence.SetPosition(x, y) + self.Divergence.Draw(dc) + + def OnPaint(self, event): + self.RefreshPreview() + event.Skip() diff -r c7e0254be378 -r e183bffc05f0 dialogs/SFCStepDialog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/SFCStepDialog.py Fri Oct 02 18:14:43 2009 +0200 @@ -0,0 +1,270 @@ +# -*- coding: utf-8 -*- + +#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor +#based on the plcopen standard. +# +#Copyright (C) 2007: 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 graphics import * + +#------------------------------------------------------------------------------- +# Edit Step Content Dialog +#------------------------------------------------------------------------------- + +[ID_SFCSTEPDIALOG, ID_SFCSTEPDIALOGSPACER, + ID_SFCSTEPDIALOGNAME, ID_SFCSTEPDIALOGPREVIEW, + ID_SFCSTEPDIALOGCHECKBOX1, ID_SFCSTEPDIALOGCHECKBOX2, + ID_SFCSTEPDIALOGCHECKBOX3, ID_SFCSTEPDIALOGSTATICTEXT1, + ID_SFCSTEPDIALOGSTATICTEXT2, ID_SFCSTEPDIALOGSTATICTEXT3, +] = [wx.NewId() for _init_ctrls in range(10)] + +class SFCStepDialog(wx.Dialog): + + if wx.VERSION < (2, 6, 0): + def Bind(self, event, function, id = None): + if id is not None: + event(self, id, function) + else: + event(self, function) + + def _init_coll_flexGridSizer1_Items(self, parent): + parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) + parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) + + def _init_coll_flexGridSizer1_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(0) + + def _init_coll_MainSizer_Items(self, parent): + parent.AddSizer(self.LeftGridSizer, 1, border=5, flag=wx.GROW|wx.RIGHT) + parent.AddSizer(self.RightGridSizer, 1, border=5, flag=wx.GROW|wx.LEFT) + + def _init_coll_LeftGridSizer_Items(self, parent): + parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.StepName, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.checkBox1, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.checkBox2, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.checkBox3, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW) + + def _init_coll_LeftGridSizer_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(6) + + def _init_coll_RightGridSizer_Items(self, parent): + parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW) + + def _init_coll_RightGridSizer_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(1) + + def _init_sizers(self): + self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) + self.MainSizer = wx.BoxSizer(wx.HORIZONTAL) + self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=7, vgap=5) + self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5) + + self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) + self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) + self._init_coll_MainSizer_Items(self.MainSizer) + self._init_coll_LeftGridSizer_Items(self.LeftGridSizer) + self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer) + self._init_coll_RightGridSizer_Items(self.RightGridSizer) + self._init_coll_RightGridSizer_Growables(self.RightGridSizer) + + self.SetSizer(self.flexGridSizer1) + + def _init_ctrls(self, prnt, ctrler): + wx.Dialog.__init__(self, id=ID_SFCSTEPDIALOG, + name='SFCStepDialog', parent=prnt, pos=wx.Point(376, 223), + size=wx.Size(400, 250), style=wx.DEFAULT_DIALOG_STYLE, + title=_('Edit Step')) + self.SetClientSize(wx.Size(400, 250)) + + self.staticText1 = wx.StaticText(id=ID_SFCSTEPDIALOGSTATICTEXT1, + label=_('Name:'), name='staticText1', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + + self.staticText2 = wx.StaticText(id=ID_SFCSTEPDIALOGSTATICTEXT2, + label=_('Connectors:'), name='staticText2', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + + self.staticText3 = wx.StaticText(id=ID_SFCSTEPDIALOGSTATICTEXT3, + label=_('Preview:'), name='staticText4', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + + self.StepName = wx.TextCtrl(id=ID_SFCSTEPDIALOGNAME, + name='Name', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 24), style=0) + self.Bind(wx.EVT_TEXT, self.OnNameChanged, id=ID_SFCSTEPDIALOGNAME) + + self.checkBox1 = wx.CheckBox(id=ID_SFCSTEPDIALOGCHECKBOX1, + label=_("Input"), name='checkBox1', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) + self.Bind(wx.EVT_CHECKBOX, self.OnConnectorsChanged, id=ID_SFCSTEPDIALOGCHECKBOX1) + + self.checkBox2 = wx.CheckBox(id=ID_SFCSTEPDIALOGCHECKBOX2, + label=_("Output"), name='checkBox2', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) + self.Bind(wx.EVT_CHECKBOX, self.OnConnectorsChanged, id=ID_SFCSTEPDIALOGCHECKBOX2) + + self.checkBox3 = wx.CheckBox(id=ID_SFCSTEPDIALOGCHECKBOX3, + label=_("Action"), name='checkBox3', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) + self.Bind(wx.EVT_CHECKBOX, self.OnConnectorsChanged, id=ID_SFCSTEPDIALOGCHECKBOX3) + + self.Spacer = wx.Panel(id=ID_SFCSTEPDIALOGSPACER, + name='Spacer', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) + + self.Preview = wx.Panel(id=ID_SFCSTEPDIALOGPREVIEW, + name='Preview', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 0), 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, "RefreshStepModel", lambda x:None) + setattr(self.Preview, "GetScaling", lambda:None) + setattr(self.Preview, "IsOfType", ctrler.IsOfType) + + self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) + if wx.VERSION >= (2, 5, 0): + self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId()) + self.Preview.Bind(wx.EVT_PAINT, self.OnPaint) + else: + self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId()) + wx.EVT_PAINT(self.Preview, self.OnPaint) + + self._init_sizers() + + def __init__(self, parent, controler, initial = False): + self._init_ctrls(parent, controler) + self.Step = None + self.Initial = initial + self.MinStepSize = None + + self.PouNames = [] + self.Variables = [] + self.StepNames = [] + + def SetPreviewFont(self, font): + self.Preview.SetFont(font) + + def OnOK(self, event): + step_name = self.StepName.GetValue() + if step_name == "": + message = wx.MessageDialog(self, _("You must type a name!"), _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + elif not TestIdentifier(step_name): + message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + elif step_name.upper() in IEC_KEYWORDS: + message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + elif step_name.upper() in self.PouNames: + message = wx.MessageDialog(self, _("A pou with \"%s\" as name exists!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + elif step_name.upper() in self.Variables: + message = wx.MessageDialog(self, _("A variable with \"%s\" as name already exists in this pou!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + elif step_name.upper() in self.StepNames: + message = wx.MessageDialog(self, _("\"%s\" step already exists!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + else: + self.EndModal(wx.ID_OK) + + def SetMinStepSize(self, size): + self.MinStepSize = size + + def SetPouNames(self, pou_names): + self.PouNames = [pou_name.upper() for pou_name in pou_names] + + def SetVariables(self, variables): + self.Variables = [var["Name"].upper() for var in variables] + + def SetStepNames(self, step_names): + self.StepNames = [step_name.upper() for step_name in step_names] + + def SetValues(self, values): + value_name = values.get("name", None) + if value_name: + self.StepName.SetValue(value_name) + else: + self.StepName.SetValue("") + self.checkBox1.SetValue(values.get("input", False)) + self.checkBox2.SetValue(values.get("output", False)) + self.checkBox3.SetValue(values.get("action", False)) + self.RefreshPreview() + + def GetValues(self): + values = {} + values["name"] = self.StepName.GetValue() + values["input"] = self.checkBox1.IsChecked() + values["output"] = self.checkBox2.IsChecked() + values["action"] = self.checkBox3.IsChecked() + values["width"], values["height"] = self.Step.GetSize() + return values + + def OnConnectorsChanged(self, event): + self.RefreshPreview() + event.Skip() + + def OnNameChanged(self, event): + self.RefreshPreview() + event.Skip() + + def RefreshPreview(self): + dc = wx.ClientDC(self.Preview) + dc.SetFont(self.Preview.GetFont()) + dc.Clear() + self.Step = SFC_Step(self.Preview, self.StepName.GetValue(), self.Initial) + if self.checkBox1.IsChecked(): + self.Step.AddInput() + else: + self.Step.RemoveInput() + if self.checkBox2.IsChecked(): + self.Step.AddOutput() + else: + self.Step.RemoveOutput() + if self.checkBox3.IsChecked(): + self.Step.AddAction() + else: + self.Step.RemoveAction() + width, height = self.MinStepSize + min_width, min_height = self.Step.GetMinSize() + width, height = max(min_width, width), max(min_height, height) + self.Step.SetSize(width, height) + clientsize = self.Preview.GetClientSize() + x = (clientsize.width - width) / 2 + y = (clientsize.height - height) / 2 + self.Step.SetPosition(x, y) + self.Step.Draw(dc) + + def OnPaint(self, event): + self.RefreshPreview() + event.Skip() diff -r c7e0254be378 -r e183bffc05f0 dialogs/SFCStepNameDialog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/SFCStepNameDialog.py Fri Oct 02 18:14:43 2009 +0200 @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- + +#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor +#based on the plcopen standard. +# +#Copyright (C) 2007: 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 + +#------------------------------------------------------------------------------- +# Edit Step Name Dialog +#------------------------------------------------------------------------------- + +class SFCStepNameDialog(wx.TextEntryDialog): + + if wx.VERSION < (2, 6, 0): + def Bind(self, event, function, id = None): + if id is not None: + event(self, id, function) + else: + event(self, function) + + + def __init__(self, parent, message, caption = "Please enter text", defaultValue = "", + style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition): + wx.TextEntryDialog.__init__(self, parent, message, caption, defaultValue, style, pos) + + self.PouNames = [] + self.Variables = [] + self.StepNames = [] + if wx.VERSION >= (2, 8, 0): + self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(2).GetSizer().GetItem(1).GetSizer().GetAffirmativeButton().GetId()) + elif wx.VERSION >= (2, 6, 0): + self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetAffirmativeButton().GetId()) + else: + self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId()) + + def OnOK(self, event): + step_name = self.GetSizer().GetItem(1).GetWindow().GetValue() + if step_name == "": + message = wx.MessageDialog(self, _("You must type a name!"), _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + elif not TestIdentifier(step_name): + message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + elif step_name.upper() in IEC_KEYWORDS: + message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + elif step_name.upper() in self.PouNames: + message = wx.MessageDialog(self, _("A pou with \"%s\" as name exists!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + elif step_name.upper() in self.Variables: + message = wx.MessageDialog(self, _("A variable with \"%s\" as name already exists in this pou!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + elif step_name.upper() in self.StepNames: + message = wx.MessageDialog(self, _("\"%s\" step already exists!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + else: + self.EndModal(wx.ID_OK) + + def SetPouNames(self, pou_names): + self.PouNames = [pou_name.upper() for pou_name in pou_names] + + def SetVariables(self, variables): + self.Variables = [var["Name"].upper() for var in variables] + + def SetStepNames(self, step_names): + self.StepNames = [step_name.upper() for step_name in step_names] + + def GetValue(self): + return self.GetSizer().GetItem(1).GetWindow().GetValue() diff -r c7e0254be378 -r e183bffc05f0 dialogs/SFCTransitionDialog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/SFCTransitionDialog.py Fri Oct 02 18:14:43 2009 +0200 @@ -0,0 +1,305 @@ +# -*- coding: utf-8 -*- + +#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor +#based on the plcopen standard. +# +#Copyright (C) 2007: 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 graphics import * + +#------------------------------------------------------------------------------- +# Edit Transition Content Dialog +#------------------------------------------------------------------------------- + +[ID_SFCTRANSITIONDIALOG, ID_SFCTRANSITIONDIALOGSPACER, + ID_SFCTRANSITIONDIALOGREFERENCE, ID_SFCTRANSITIONDIALOGINLINE, + ID_SFCTRANSITIONDIALOGPRIORITY, ID_SFCTRANSITIONDIALOGPREVIEW, + ID_SFCTRANSITIONDIALOGRADIOBUTTON1, ID_SFCTRANSITIONDIALOGRADIOBUTTON2, + ID_SFCTRANSITIONDIALOGRADIOBUTTON3, ID_SFCTRANSITIONDIALOGSTATICTEXT1, + ID_SFCTRANSITIONDIALOGSTATICTEXT2, ID_SFCTRANSITIONDIALOGSTATICTEXT3, +] = [wx.NewId() for _init_ctrls in range(12)] + +class SFCTransitionDialog(wx.Dialog): + + if wx.VERSION < (2, 6, 0): + def Bind(self, event, function, id = None): + if id is not None: + event(self, id, function) + else: + event(self, function) + + def _init_coll_flexGridSizer1_Items(self, parent): + parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) + parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) + + def _init_coll_flexGridSizer1_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(0) + + def _init_coll_MainSizer_Items(self, parent): + parent.AddSizer(self.LeftGridSizer, 1, border=5, flag=wx.GROW|wx.RIGHT) + parent.AddSizer(self.RightGridSizer, 1, border=5, flag=wx.GROW|wx.LEFT) + + def _init_coll_LeftGridSizer_Items(self, parent): + parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.radioButton1, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.Reference, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.radioButton2, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.Inline, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.radioButton3, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.Priority, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW) + + def _init_coll_LeftGridSizer_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(6) + + def _init_coll_RightGridSizer_Items(self, parent): + parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW) + + def _init_coll_RightGridSizer_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(1) + + def _init_sizers(self): + self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) + self.MainSizer = wx.BoxSizer(wx.HORIZONTAL) + self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=9, vgap=5) + self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5) + + self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) + self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) + self._init_coll_MainSizer_Items(self.MainSizer) + self._init_coll_LeftGridSizer_Items(self.LeftGridSizer) + self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer) + self._init_coll_RightGridSizer_Items(self.RightGridSizer) + self._init_coll_RightGridSizer_Growables(self.RightGridSizer) + + self.SetSizer(self.flexGridSizer1) + + def _init_ctrls(self, prnt, ctrler): + wx.Dialog.__init__(self, id=ID_SFCTRANSITIONDIALOG, + name='SFCTransitionDialog', parent=prnt, pos=wx.Point(376, 223), + size=wx.Size(350, 300), style=wx.DEFAULT_DIALOG_STYLE, + title=_('Edit transition')) + self.SetClientSize(wx.Size(350, 300)) + + self.staticText1 = wx.StaticText(id=ID_SFCTRANSITIONDIALOGSTATICTEXT1, + label=_('Type:'), name='staticText1', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + + self.staticText2 = wx.StaticText(id=ID_SFCTRANSITIONDIALOGSTATICTEXT2, + label=_('Preview:'), name='staticText2', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + + self.staticText3 = wx.StaticText(id=ID_SFCTRANSITIONDIALOGSTATICTEXT3, + label=_('Priority:'), name='staticText3', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + + self.radioButton1 = wx.RadioButton(id=ID_SFCTRANSITIONDIALOGRADIOBUTTON1, + label=_('Reference'), name='radioButton1', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.RB_GROUP) + self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_SFCTRANSITIONDIALOGRADIOBUTTON1) + self.radioButton1.SetValue(True) + + self.Reference = wx.ComboBox(id=ID_SFCTRANSITIONDIALOGREFERENCE, + name='Reference', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 28), style=wx.CB_READONLY) + self.Bind(wx.EVT_COMBOBOX, self.OnReferenceChanged, id=ID_SFCTRANSITIONDIALOGREFERENCE) + + self.radioButton2 = wx.RadioButton(id=ID_SFCTRANSITIONDIALOGRADIOBUTTON2, + label=_('Inline'), name='radioButton2', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) + self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_SFCTRANSITIONDIALOGRADIOBUTTON2) + self.radioButton2.SetValue(False) + + self.Inline = wx.TextCtrl(id=ID_SFCTRANSITIONDIALOGINLINE, + name='Inline', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 24), style=0) + self.Bind(wx.EVT_TEXT, self.OnInlineChanged, id=ID_SFCTRANSITIONDIALOGINLINE) + self.Inline.Enable(False) + + self.radioButton3 = wx.RadioButton(id=ID_SFCTRANSITIONDIALOGRADIOBUTTON3, + label=_('Connection'), name='radioButton3', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) + self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_SFCTRANSITIONDIALOGRADIOBUTTON3) + self.radioButton3.SetValue(False) + if not self.Connection: + self.radioButton3.Hide() + + self.Priority = wx.SpinCtrl(id=ID_SFCTRANSITIONDIALOGPRIORITY, + name='Priority', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0) + self.Bind(wx.EVT_TEXT, self.OnPriorityChanged, id=ID_SFCTRANSITIONDIALOGPRIORITY) + + self.Preview = wx.Panel(id=ID_SFCTRANSITIONDIALOGPREVIEW, + name='Preview', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 0), 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, "RefreshTransitionModel", lambda x:None) + setattr(self.Preview, "GetScaling", lambda:None) + setattr(self.Preview, "IsOfType", ctrler.IsOfType) + + self.Spacer = wx.Panel(id=ID_SFCTRANSITIONDIALOGSPACER, + name='Spacer', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) + + self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) + if wx.VERSION >= (2, 5, 0): + self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId()) + self.Preview.Bind(wx.EVT_PAINT, self.OnPaint) + else: + self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId()) + wx.EVT_PAINT(self.Preview, self.OnPaint) + + self._init_sizers() + + def __init__(self, parent, controler, connection): + self.Connection = connection + self._init_ctrls(parent, controler) + self.Transition = None + self.MinTransitionSize = None + + self.Element = SFC_Transition(self.Preview) + + def SetPreviewFont(self, font): + self.Preview.SetFont(font) + + def SetElementSize(self, size): + min_width, min_height = self.Element.GetMinSize() + width, height = max(min_width, size[0]), max(min_height, size[1]) + self.Element.SetSize(width, height) + + def OnOK(self, event): + error = [] + if self.radioButton1.GetValue() and self.Reference.GetStringSelection() == "": + error.append(_("Reference")) + if self.radioButton2.GetValue() and self.Inline.GetValue() == "": + error.append(_("Inline")) + if len(error) > 0: + text = "" + for i, item in enumerate(error): + if i == 0: + text += item + elif i == len(error) - 1: + text += _(" and %s")%item + else: + text += _(", %s")%item + message = wx.MessageDialog(self, _("Form isn't complete. %s must be filled!")%text, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + else: + self.EndModal(wx.ID_OK) + + def OnTypeChanged(self, event): + if self.radioButton1.GetValue(): + self.Element.SetType("reference", self.Reference.GetStringSelection()) + self.Reference.Enable(True) + self.Inline.Enable(False) + elif self.radioButton2.GetValue(): + self.Element.SetType("inline", self.Inline.GetValue()) + self.Reference.Enable(False) + self.Inline.Enable(True) + else: + self.Element.SetType("connection") + self.Reference.Enable(False) + self.Inline.Enable(False) + self.RefreshPreview() + event.Skip() + + def OnReferenceChanged(self, event): + self.Element.SetType("reference", self.Reference.GetStringSelection()) + self.RefreshPreview() + event.Skip() + + def OnInlineChanged(self, event): + self.Element.SetType("inline", self.Inline.GetValue()) + self.RefreshPreview() + event.Skip() + + def OnPriorityChanged(self, event): + self.Element.SetPriority(int(self.Priority.GetValue())) + self.RefreshPreview() + event.Skip() + + def SetTransitions(self, transitions): + self.Reference.Append("") + for transition in transitions: + self.Reference.Append(transition) + + def SetValues(self, values): + if values["type"] == "reference": + self.radioButton1.SetValue(True) + self.radioButton2.SetValue(False) + self.radioButton3.SetValue(False) + self.Reference.Enable(True) + self.Inline.Enable(False) + self.Reference.SetStringSelection(values["value"]) + self.Element.SetType("reference", values["value"]) + elif values["type"] == "inline": + self.radioButton1.SetValue(False) + self.radioButton2.SetValue(True) + self.radioButton3.SetValue(False) + self.Reference.Enable(False) + self.Inline.Enable(True) + self.Inline.SetValue(values["value"]) + self.Element.SetType("inline", values["value"]) + elif values["type"] == "connection" and self.Connection: + self.radioButton1.SetValue(False) + self.radioButton2.SetValue(False) + self.radioButton3.SetValue(True) + self.Reference.Enable(False) + self.Inline.Enable(False) + self.Element.SetType("connection") + self.Priority.SetValue(values["priority"]) + self.Element.SetPriority(values["priority"]) + self.RefreshPreview() + + def GetValues(self): + values = {"priority" : int(self.Priority.GetValue())} + if self.radioButton1.GetValue(): + values["type"] = "reference" + values["value"] = self.Reference.GetStringSelection() + elif self.radioButton2.GetValue(): + values["type"] = "inline" + values["value"] = self.Inline.GetValue() + else: + values["type"] = "connection" + values["value"] = None + return values + + def RefreshPreview(self): + dc = wx.ClientDC(self.Preview) + dc.SetFont(self.Preview.GetFont()) + dc.Clear() + clientsize = self.Preview.GetClientSize() + posx, posy = self.Element.GetPosition() + rect = self.Element.GetBoundingBox() + diffx, diffy = posx - rect.x, posy - rect.y + self.Element.SetPosition((clientsize.width - rect.width) / 2 + diffx, (clientsize.height - rect.height) / 2 + diffy) + self.Element.Draw(dc) + + def OnPaint(self, event): + self.RefreshPreview() + event.Skip() diff -r c7e0254be378 -r e183bffc05f0 dialogs/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/__init__.py Fri Oct 02 18:14:43 2009 +0200 @@ -0,0 +1,36 @@ +#!/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) 2007: 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 + +# Package initialization + +from ConnectionDialog import ConnectionDialog +from ActionBlockDialog import ActionBlockDialog +from FBDBlockDialog import FBDBlockDialog, CATEGORY, BLOCK +from FBDVariableDialog import FBDVariableDialog +from LDElementDialog import LDElementDialog +from LDPowerRailDialog import LDPowerRailDialog +from SFCStepDialog import SFCStepDialog +from SFCStepNameDialog import SFCStepNameDialog +from SFCTransitionDialog import SFCTransitionDialog +from SFCDivergenceDialog import SFCDivergenceDialog diff -r c7e0254be378 -r e183bffc05f0 examples/example.xml --- a/examples/example.xml Wed Sep 30 15:23:31 2009 -0600 +++ b/examples/example.xml Fri Oct 02 18:14:43 2009 +0200 @@ -12,7 +12,7 @@ contentDescription="Example of PLCOpenEditor usage"/> @@ -527,12 +527,14 @@ + + + + + + + - - - - - diff -r c7e0254be378 -r e183bffc05f0 generate_IEC_std.py --- a/generate_IEC_std.py Wed Sep 30 15:23:31 2009 -0600 +++ b/generate_IEC_std.py Fri Oct 02 18:14:43 2009 +0200 @@ -150,12 +150,12 @@ { identifier_c param_name("%(input_name)s"); /* Get the value from a foo( = ) style call */ - symbol_c *%(input_name)s_param_value = function_call_param_iterator.search(¶m_name); + symbol_c *%(input_name)s_param_value = function_call_param_iterator.search_f(¶m_name); symbol_c *%(input_name)s_type_symbol = NULL; /* Get the value from a foo() style call */ if (%(input_name)s_param_value == NULL) - %(input_name)s_param_value = function_call_param_iterator.next(); + %(input_name)s_param_value = function_call_param_iterator.next_nf(); if (%(input_name)s_param_value != NULL) { %(input_name)s_type_symbol = search_expression_type->get_type(%(input_name)s_param_value); last_type_symbol = last_type_symbol && %(input_name)s_type_symbol && search_expression_type->is_same_type(%(input_name)s_type_symbol, last_type_symbol) ? search_expression_type->common_type(%(input_name)s_type_symbol, last_type_symbol) : %(input_name)s_type_symbol ; @@ -213,11 +213,11 @@ identifier_c param_name(my_name); /* Get the value from a foo( = ) style call */ - param_value = function_call_param_iterator.search(¶m_name); + param_value = function_call_param_iterator.search_f(¶m_name); /* Get the value from a foo() style call */ if (param_value == NULL) - param_value = function_call_param_iterator.next(); + param_value = function_call_param_iterator.next_nf(); if (param_value != NULL){ symbol_c *current_type_symbol = search_expression_type->get_type(param_value); last_type_symbol = last_type_symbol && search_expression_type->is_same_type(current_type_symbol, last_type_symbol) ? search_expression_type->common_type(current_type_symbol, last_type_symbol) : current_type_symbol ; @@ -231,7 +231,14 @@ result_type_rule = fdecl["return_type_rule"] res += { - "copy_input" : "symbol_c * return_type_symbol = last_type_symbol;\n", + "copy_input" : """symbol_c * return_type_symbol; +if (search_expression_type->is_literal_integer_type(last_type_symbol)) + return_type_symbol = &search_constant_type_c::%s_type_name; +else + return_type_symbol = last_type_symbol; +"""%({True: "lword", False: """lint_type_name; +else if (search_expression_type->is_literal_real_type(last_type_symbol)) + return_type_symbol = &search_constant_type_c::lreal"""}[reduce(lambda x, y: x or y, [paramtype == "ANY_BIT" for paramname,paramtype,unused in fdecl["inputs"]], False)]), "defined" : "symbol_c * return_type_symbol = &search_constant_type_c::%s_type_name;\n"%fdecl["outputs"][0][1].lower(), }.get(result_type_rule, "symbol_c * return_type_symbol = %s;\n"%result_type_rule) @@ -380,7 +387,7 @@ """ search_type_code = matiec_header + """ -void *compute_standard_function_default(function_invocation_c *st_symbol = NULL, il_formal_funct_call_c *il_symbol = NULL) { +void *search_expression_type_c::compute_standard_function_default(function_invocation_c *st_symbol = NULL, il_formal_funct_call_c *il_symbol = NULL) { function_type_t current_function_type; function_call_param_iterator_c *tmp_function_call_param_iterator; if (st_symbol != NULL && il_symbol == NULL) { @@ -423,7 +430,7 @@ return NULL; } -void *compute_standard_function_il(il_function_call_c *symbol, symbol_c *param_data_type) { +void *search_expression_type_c::compute_standard_function_il(il_function_call_c *symbol, symbol_c *param_data_type) { function_type_t current_function_type = get_function_type((identifier_c *)symbol->function_name); function_call_param_iterator_c function_call_param_iterator(symbol); diff -r c7e0254be378 -r e183bffc05f0 graphics/GraphicCommons.py --- a/graphics/GraphicCommons.py Wed Sep 30 15:23:31 2009 -0600 +++ b/graphics/GraphicCommons.py Fri Oct 02 18:14:43 2009 +0200 @@ -211,8 +211,9 @@ class DebugViewer: def __init__(self, producer, debug, register_tick=True): - self.DataProducer = producer + self.DataProducer = None self.Debug = debug + self.RegisterTick = register_tick self.Inhibited = False self.DataConsumers = {} @@ -222,15 +223,24 @@ self.RefreshTimer = wx.Timer(self, -1) self.Bind(wx.EVT_TIMER, self.OnRefreshTimer, self.RefreshTimer) - if register_tick and debug: - self.DataProducer.SubscribeDebugIECVariable("__tick__", self) + self.SetDataProducer(producer) def __del__(self): - if self.Debug: - self.DataProducer.UnsubscribeDebugIECVariable("__tick__", self) + self.DataProducer = None self.DeleteDataConsumers() self.RefreshTimer.Stop() - + + def SetDataProducer(self, producer): + if self.RegisterTick and self.Debug: + if producer is not None: + producer.SubscribeDebugIECVariable("__tick__", self) + elif self.DataProducer is not None: + self.DataProducer.UnsubscribeDebugIECVariable("__tick__", self) + self.DataProducer = producer + + def IsDebugging(self): + return self.Debug + def Inhibit(self, inhibit): self.Inhibited = inhibit for consumer, iec_path in self.DataConsumers.iteritems(): diff -r c7e0254be378 -r e183bffc05f0 i18n/app.fil --- a/i18n/app.fil Wed Sep 30 15:23:31 2009 -0600 +++ b/i18n/app.fil Fri Oct 02 18:14:43 2009 +0200 @@ -7,6 +7,17 @@ ../SFCViewer.py ../LDViewer.py ../GraphicViewer.py +../dialogs/ActionBlockDialog.py +../dialogs/ConnectionDialog.py +../dialogs/FBDBlockDialog.py +../dialogs/FBDVariableDialog.py +../dialogs/LDElementDialog.py +../dialogs/LDPowerRailDialog.py +../dialogs/PouNameDialog.py +../dialogs/SFCDivergenceDialog.py +../dialogs/SFCStepDialog.py +../dialogs/SFCStepNameDialog.py +../dialogs/SFCTransitionDialog.py ../Dialogs.py ../DataTypeEditor.py ../plcopen/iec_std.csv diff -r c7e0254be378 -r e183bffc05f0 plcopen/iec_std.csv --- a/plcopen/iec_std.csv Wed Sep 30 15:23:31 2009 -0600 +++ b/plcopen/iec_std.csv Fri Oct 02 18:14:43 2009 +0200 @@ -13,67 +13,67 @@ ;;;;;;;; ;;;;;;;; Standard_functions_type;name;baseinputnumber;inputs;outputs;comment;extensible;python_eval_c_code_format;return_type_rule -_("Type conversion");*_TO_**;1;(ANY);ANY;_("Data type conversion");no;ANY_TO_ANY_FORMAT_GEN(ANY_TO_ANY_LIST,fdecl);defined -;TRUNC;1;(ANY_REAL);ANY_INT;_("Rounding up/down");no;("int", None, None);&search_constant_type_c::constant_int_type_name -;BCD_TO_**;1;(ANY_BIT);ANY_INT;_("Conversion from BCD");no;ANY_TO_ANY_FORMAT_GEN(BCD_TO_ANY_LIST,fdecl);defined -;*_TO_BCD;1;(ANY_INT);ANY_BIT;_("Conversion to BCD");no;ANY_TO_ANY_FORMAT_GEN(ANY_TO_BCD_LIST,fdecl);&search_constant_type_c::constant_int_type_name -;DATE_AND_TIME_TO_TIME_OF_DAY;1;(DT);TOD;_("Conversion to time-of-day");no;(None, "__date_and_time_to_time_of_day", None);defined -;DATE_AND_TIME_TO_DATE;1;(DT);DATE;_("Conversion to date");no;(None, "__date_and_time_to_date", None);defined -_("Numerical");ABS;1;(ANY_NUM);ANY_NUM;_("Absolute number");no;(None, "__abs_", "IN_type");IN_type_symbol -;SQRT;1;(ANY_REAL);ANY_REAL;_("Square root (base 2)");no;(None, "__sqrt_", "IN_type");IN_type_symbol -;LN;1;(ANY_REAL);ANY_REAL;_("Natural logarithm");no;(None, "__ln_", "IN_type");IN_type_symbol -;LOG;1;(ANY_REAL);ANY_REAL;_("Logarithm to base 10");no;(None, "__log_", "IN_type");IN_type_symbol -;EXP;1;(ANY_REAL);ANY_REAL;_("Exponentiation");no;(None, "__exp_", "IN_type");IN_type_symbol -;SIN;1;(ANY_REAL);ANY_REAL;_("Sine");no;(None, "__sin_", "IN_type");IN_type_symbol -;COS;1;(ANY_REAL);ANY_REAL;_("Cosine");no;(None, "__cos_", "IN_type");IN_type_symbol -;TAN;1;(ANY_REAL);ANY_REAL;_("Tangent");no;(None, "__tan_", "IN_type");IN_type_symbol -;ASIN;1;(ANY_REAL);ANY_REAL;_("Arc sine");no;(None, "__asin_", "IN_type");IN_type_symbol -;ACOS;1;(ANY_REAL);ANY_REAL;_("Arc cosine");no;(None, "__acos_", "IN_type");IN_type_symbol -;ATAN;1;(ANY_REAL);ANY_REAL;_("Arc tangent");no;(None, "__atan_", "IN_type");IN_type_symbol -_("Arithmetic");ADD;1;(ANY_NUM, ANY_NUM);ANY_NUM;_("Addition");yes;(None, "__add_", "return_type");copy_input -;ADD;1;(TIME, TIME);TIME;_("Time addition");no;(None, "__time_add", None);defined -;ADD;1;(TOD, TIME);TOD;_("Time-of-day addition");no;(None, "__time_add", None);defined -;ADD;1;(DT, TIME);DT;_("Date addition");no;(None, "__time_add", None);defined -;MUL;1;(ANY_NUM, ANY_NUM);ANY_NUM;_("Multiplication");yes;(None, "__mul_", "return_type");copy_input -;MUL;1;(TIME, ANY_NUM);TIME;_("Time multiplication");no;(None, "__time_mul", None);defined -;SUB;1;(ANY_NUM, ANY_NUM);ANY_NUM;_("Subtraction");no;(None, "__sub_", "return_type");copy_input -;SUB;1;(TIME, TIME);TIME;_("Time subtraction");no;(None, "__time_sub", None);defined -;SUB;1;(DATE, DATE);TIME;_("Date subtraction");no;(None, "__time_sub", None);defined -;SUB;1;(TOD, TIME);TOD;_("Time-of-day subtraction");no;(None, "__time_sub", None);defined -;SUB;1;(TOD, TOD);TIME;_("Time-of-day subtraction");no;(None, "__time_sub", None);defined -;SUB;1;(DT, TIME);DT;_("Date and time subtraction");no;(None, "__time_sub", None);defined -;SUB;1;(DT, DT);TIME;_("Date and time subtraction");no;(None, "__time_sub", None);defined -;DIV;1;(ANY_NUM, ANY_NUM);ANY_NUM;_("Division");no;(None, "__div_", "return_type");copy_input -;DIV;1;(TIME, ANY_NUM);TIME;_("Time division");no;(None, "__time_div", None);defined -;MOD;1;(ANY_NUM, ANY_NUM);ANY_NUM;_("Remainder (modulo)");no;(None, "__mod_", "return_type");copy_input -;EXPT;1;(ANY_REAL, ANY_NUM);ANY_REAL;_("Exponent");no;(None, "__expt_", "IN1_type");copy_input -;MOVE;1;(ANY);ANY;_("Assignment");no;(None, "__move_", "return_type");copy_input -_("Bit-shift");SHL;1;(ANY_BIT, N);ANY_BIT;_("Shift left");no;(None, "__shl_", "IN_type");IN_type_symbol -;SHR;1;(ANY_BIT, N);ANY_BIT;_("Shift right");no;(None, "__shr_", "IN_type");IN_type_symbol -;ROR;1;(ANY_NBIT, N);ANY_NBIT;_("Rotate right");no;(None, "__ror_", "IN_type");IN_type_symbol -;ROL;1;(ANY_NBIT, N);ANY_NBIT;_("Rotate left");no;(None, "__rol_", "IN_type");IN_type_symbol -_("Bitwise");AND;1;(ANY_BIT, ANY_BIT);ANY_BIT;_("Bitwise AND");yes;(None, "__and_", "return_type");copy_input -;OR;1;(ANY_BIT, ANY_BIT);ANY_BIT;_("Bitwise OR");yes;(None, "__or_", "return_type");copy_input -;XOR;1;(ANY_BIT, ANY_BIT);ANY_BIT;_("Bitwise XOR");yes;(None, "__xor_", "return_type");copy_input -;NOT;1;(ANY_BIT);ANY_BIT;_("Bitwise inverting");no;(None, "__not_", "return_type");IN_type_symbol -_("Selection");SEL;0;(G, ANY, ANY);ANY;_("Binary selection (1 of 2)");no;(None, "__sel_", "IN0_type");copy_input -;MAX;1;(ANY, ANY);ANY;_("Maximum");yes;(None, "__max_", "return_type");copy_input -;MIN;1;(ANY, ANY);ANY;_("Minimum");yes;(None, "__min_", "return_type");copy_input -;LIMIT;1;(MN, ANY, MX);ANY;_("Limitation");no;(None, "__limit_", "IN_type");IN_type_symbol -;MUX;0;(K, ANY, ANY);ANY;_("Multiplexer (select 1 of N)");yes;(None, "__mux_", "return_type");copy_input -_("Comparison");GT;1;(ANY, ANY);BOOL;_("Greater than");yes;(None, "__gt_", "common_type");defined -;GE;1;(ANY, ANY);BOOL;_("Greater than or equal to");yes;(None, "__ge_", "common_type");defined -;EQ;1;(ANY, ANY);BOOL;_("Equal to");yes;(None, "__eq_", "common_type");defined -;LT;1;(ANY, ANY);BOOL;_("Less than");yes;(None, "__lt_", "common_type");defined -;LE;1;(ANY, ANY);BOOL;_("Less than or equal to");yes;(None, "__le_", "common_type");defined -;NE;1;(ANY, ANY);BOOL;_("Not equal to");yes;(None, "__ne_", "common_type");defined -_("Character string");LEN;1;(STRING);INT;_("Length of string");no;(None, "__len", None);defined -;LEFT;1;(STRING, L);STRING;_("string left of");no;(None, "__left", None);defined -;RIGHT;1;(STRING, L);STRING;_("string right of");no;(None, "__right", None);defined -;MID;1;(STRING, L, P);STRING;_("string from the middle");no;(None, "__mid", None);defined -;CONCAT;1;(STRING, STRING);STRING;_("Concatenation");yes;(None, "__concat", None);defined -;CONCAT;1;(DATE, TOD);DT;_("Time concatenation");no;(None, "__time_add", None);defined -;INSERT;1;(STRING, STRING, P);STRING;_("Insertion (into)");no;(None, "__insert", None);defined -;DELETE;1;(STRING, L, P);STRING;_("Deletion (within)");no;(None, "__delete", None);defined -;REPLACE;1;(STRING, STRING, L, P);STRING;_("Replacement (within)");no;(None, "__replace", None);defined -;FIND;1;(STRING, STRING);INT;_("Find position");no;(None, "__find", None);defined +Type conversion;*_TO_**;1;(ANY);ANY;Data type conversion;no;ANY_TO_ANY_FORMAT_GEN(ANY_TO_ANY_LIST,fdecl);defined +;TRUNC;1;(ANY_REAL);ANY_INT;Rounding up/down;no;("int", None, None);&search_constant_type_c::integer +;BCD_TO_**;1;(ANY_BIT);ANY_INT;Conversion from BCD;no;ANY_TO_ANY_FORMAT_GEN(BCD_TO_ANY_LIST,fdecl);defined +;*_TO_BCD;1;(ANY_INT);ANY_BIT;Conversion to BCD;no;ANY_TO_ANY_FORMAT_GEN(ANY_TO_BCD_LIST,fdecl);&search_constant_type_c::integer +;DATE_AND_TIME_TO_TIME_OF_DAY;1;(DT);TOD;Conversion to time-of-day;no;(None, "__date_and_time_to_time_of_day", None);defined +;DATE_AND_TIME_TO_DATE;1;(DT);DATE;Conversion to date;no;(None, "__date_and_time_to_date", None);defined +Numerical;ABS;1;(ANY_NUM);ANY_NUM;Absolute number;no;(None, "__abs_", "IN_type");IN_type_symbol +;SQRT;1;(ANY_REAL);ANY_REAL;Square root (base 2);no;(None, "__sqrt_", "IN_type");IN_type_symbol +;LN;1;(ANY_REAL);ANY_REAL;Natural logarithm;no;(None, "__ln_", "IN_type");IN_type_symbol +;LOG;1;(ANY_REAL);ANY_REAL;Logarithm to base 10;no;(None, "__log_", "IN_type");IN_type_symbol +;EXP;1;(ANY_REAL);ANY_REAL;Exponentiation;no;(None, "__exp_", "IN_type");IN_type_symbol +;SIN;1;(ANY_REAL);ANY_REAL;Sine;no;(None, "__sin_", "IN_type");IN_type_symbol +;COS;1;(ANY_REAL);ANY_REAL;Cosine;no;(None, "__cos_", "IN_type");IN_type_symbol +;TAN;1;(ANY_REAL);ANY_REAL;Tangent;no;(None, "__tan_", "IN_type");IN_type_symbol +;ASIN;1;(ANY_REAL);ANY_REAL;Arc sine;no;(None, "__asin_", "IN_type");IN_type_symbol +;ACOS;1;(ANY_REAL);ANY_REAL;Arc cosine;no;(None, "__acos_", "IN_type");IN_type_symbol +;ATAN;1;(ANY_REAL);ANY_REAL;Arc tangent;no;(None, "__atan_", "IN_type");IN_type_symbol +Arithmetic;ADD;1;(ANY_NUM, ANY_NUM);ANY_NUM;Addition;yes;(None, "__add_", "return_type");copy_input +;ADD;1;(TIME, TIME);TIME;Time addition;no;(None, "__time_add", None);defined +;ADD;1;(TOD, TIME);TOD;Time-of-day addition;no;(None, "__time_add", None);defined +;ADD;1;(DT, TIME);DT;Date addition;no;(None, "__time_add", None);defined +;MUL;1;(ANY_NUM, ANY_NUM);ANY_NUM;Multiplication;yes;(None, "__mul_", "return_type");copy_input +;MUL;1;(TIME, ANY_NUM);TIME;Time multiplication;no;(None, "__time_mul", None);defined +;SUB;1;(ANY_NUM, ANY_NUM);ANY_NUM;Subtraction;no;(None, "__sub_", "return_type");copy_input +;SUB;1;(TIME, TIME);TIME;Time subtraction;no;(None, "__time_sub", None);defined +;SUB;1;(DATE, DATE);TIME;Date subtraction;no;(None, "__time_sub", None);defined +;SUB;1;(TOD, TIME);TOD;Time-of-day subtraction;no;(None, "__time_sub", None);defined +;SUB;1;(TOD, TOD);TIME;Time-of-day subtraction;no;(None, "__time_sub", None);defined +;SUB;1;(DT, TIME);DT;Date and time subtraction;no;(None, "__time_sub", None);defined +;SUB;1;(DT, DT);TIME;Date and time subtraction;no;(None, "__time_sub", None);defined +;DIV;1;(ANY_NUM, ANY_NUM);ANY_NUM;Division;no;(None, "__div_", "return_type");copy_input +;DIV;1;(TIME, ANY_NUM);TIME;Time division;no;(None, "__time_div", None);defined +;MOD;1;(ANY_NUM, ANY_NUM);ANY_NUM;Remainder (modulo);no;(None, "__mod_", "return_type");copy_input +;EXPT;1;(ANY_REAL, ANY_NUM);ANY_REAL;Exponent;no;(None, "__expt_", "IN1_type");copy_input +;MOVE;1;(ANY);ANY;Assignment;no;(None, "__move_", "return_type");copy_input +Bit-shift;SHL;1;(ANY_BIT, N);ANY_BIT;Shift left;no;(None, "__shl_", "IN_type");IN_type_symbol +;SHR;1;(ANY_BIT, N);ANY_BIT;Shift right;no;(None, "__shr_", "IN_type");IN_type_symbol +;ROR;1;(ANY_NBIT, N);ANY_NBIT;Rotate right;no;(None, "__ror_", "IN_type");IN_type_symbol +;ROL;1;(ANY_NBIT, N);ANY_NBIT;Rotate left;no;(None, "__rol_", "IN_type");IN_type_symbol +Bitwise;AND;1;(ANY_BIT, ANY_BIT);ANY_BIT;Bitwise AND;yes;(None, "__and_", "return_type");copy_input +;OR;1;(ANY_BIT, ANY_BIT);ANY_BIT;Bitwise OR;yes;(None, "__or_", "return_type");copy_input +;XOR;1;(ANY_BIT, ANY_BIT);ANY_BIT;Bitwise EXOR;yes;(None, "__xor_", "return_type");copy_input +;NOT;1;(ANY_BIT);ANY_BIT;Bitwise inverting;no;(None, "__not_", "return_type");IN_type_symbol +Selection;SEL;0;(G, ANY, ANY);ANY;Binary selection (1 of 2);no;(None, "__sel_", "IN0_type");copy_input +;MAX;1;(ANY, ANY);ANY;Maximum;yes;(None, "__max_", "return_type");copy_input +;MIN;1;(ANY, ANY);ANY;Minimum;yes;(None, "__min_", "return_type");copy_input +;LIMIT;1;(MN, ANY, MX);ANY;Limitation;no;(None, "__limit_", "IN_type");IN_type_symbol +;MUX;0;(K, ANY, ANY);ANY;Multiplexer (select 1 of N);yes;(None, "__mux_", "return_type");copy_input +Comparison;GT;1;(ANY, ANY);BOOL;Greater than;yes;(None, "__gt_", "common_type");defined +;GE;1;(ANY, ANY);BOOL;Greater than or equal to;yes;(None, "__ge_", "common_type");defined +;EQ;1;(ANY, ANY);BOOL;Equal to;yes;(None, "__eq_", "common_type");defined +;LT;1;(ANY, ANY);BOOL;Less than;yes;(None, "__lt_", "common_type");defined +;LE;1;(ANY, ANY);BOOL;Less than or equal to;yes;(None, "__le_", "common_type");defined +;NE;1;(ANY, ANY);BOOL;Not equal to;yes;(None, "__ne_", "common_type");defined +Character string;LEN;1;(STRING);INT;Length of string;no;(None, "__len", None);defined +;LEFT;1;(STRING, L);STRING;string left of;no;(None, "__left", None);defined +;RIGHT;1;(STRING, L);STRING;string right of;no;(None, "__right", None);defined +;MID;1;(STRING, L, P);STRING;string from the middle;no;(None, "__mid", None);defined +;CONCAT;1;(STRING, STRING);STRING;Concatenation;yes;(None, "__concat", None);defined +;CONCAT;1;(DATE, TOD);DT;Time concatenation;no;(None, "__time_add", None);defined +;INSERT;1;(STRING, STRING, P);STRING;Insertion (into);no;(None, "__insert", None);defined +;DELETE;1;(STRING, L, P);STRING;Deletion (within);no;(None, "__delete", None);defined +;REPLACE;1;(STRING, STRING, L, P);STRING;Replacement (within);no;(None, "__replace", None);defined +;FIND;1;(STRING, STRING);INT;Find position;no;(None, "__find", None);defined diff -r c7e0254be378 -r e183bffc05f0 plcopen/plcopen.py --- a/plcopen/plcopen.py Wed Sep 30 15:23:31 2009 -0600 +++ b/plcopen/plcopen.py Fri Oct 02 18:14:43 2009 +0200 @@ -924,7 +924,7 @@ self.interface.appendcontent({"name" : VarTypes[vartype], "value" : varlist}) setattr(cls, "setvars", setvars) - def addpouVar(self, type, name): + def addpouVar(self, type, name, location="", description=""): if self.interface is None: self.interface = PLCOpenClasses["pou_interface"]() content = self.interface.getcontent() @@ -938,10 +938,25 @@ var = PLCOpenClasses["varListPlain_variable"]() var.setname(name) var_type = PLCOpenClasses["dataType"]() - derived_type = PLCOpenClasses["derivedTypes_derived"]() - derived_type.setname(type) - var_type.setcontent({"name" : "derived", "value" : derived_type}) + if type in [x for x,y in TypeHierarchy_list if not x.startswith("ANY")]: + if type == "STRING": + var_type.setcontent({"name" : "string", "value" : PLCOpenClasses["elementaryTypes_string"]()}) + elif type == "WSTRING": + var_type.setcontent({"name" : "wstring", "value" : PLCOpenClasses["elementaryTypes_wstring"]()}) + else: + var_type.setcontent({"name" : type, "value" : None}) + else: + derived_type = PLCOpenClasses["derivedTypes_derived"]() + derived_type.setname(type) + var_type.setcontent({"name" : "derived", "value" : derived_type}) var.settype(var_type) + if location != "": + var.setaddress(location) + if description != "": + ft = PLCOpenClasses["formattedText"]() + ft.settext(description) + var.setdocumentation(ft) + content[-1]["value"].appendvariable(var) setattr(cls, "addpouVar", addpouVar) diff -r c7e0254be378 -r e183bffc05f0 plcopen/structures.py --- a/plcopen/structures.py Wed Sep 30 15:23:31 2009 -0600 +++ b/plcopen/structures.py Fri Oct 02 18:14:43 2009 +0200 @@ -423,7 +423,7 @@ ANY_TO_ANY_LIST=[ # simple type conv are let as C cast - (("ANY_NUM","ANY_BIT"),("ANY_NUM","ANY_BIT"), ("return_type", None, None)), + (("ANY_NUM","ANY_BIT"),("ANY_NUM","ANY_BIT"), ("return_type", "__move_", "IN_type")), # TO_TIME (("ANY_INT","ANY_BIT"),("ANY_DATE","TIME"), ("return_type", "__int_to_time", None)), (("ANY_REAL",),("ANY_DATE","TIME"), ("return_type", "__real_to_time", None)), @@ -469,8 +469,6 @@ outs = reduce(lambda a,b: a or b, map(lambda testtype : IsOfType(fdecl["outputs"][0][1],testtype), OutTypes)) inps = reduce(lambda a,b: a or b, map(lambda testtype : IsOfType(fdecl["inputs"][0][1],testtype), InTypes)) if inps and outs and fdecl["outputs"][0][1] != fdecl["inputs"][0][1]: - if Format[1] is None: - return (Format[0], "__move_", "IN_type") return Format return None