# HG changeset patch # User 'Laurent Bessard ' # Date 1253606212 -7200 # Node ID 26bc7d5d42644a314074cc8a63426aed762a6348 # Parent c1c92d068ac5ab20d949ccf27da7c4e5d3b92264# Parent f4c0e9c9b3b96b4bb82d0aee7356a8db8dbe45f7 BCT Changes merged diff -r f4c0e9c9b3b9 -r 26bc7d5d4264 DataTypeEditor.py --- a/DataTypeEditor.py Mon Sep 21 10:31:38 2009 -0600 +++ b/DataTypeEditor.py Tue Sep 22 09:56:52 2009 +0200 @@ -598,6 +598,9 @@ def IsViewing(self, tagname): return self.TagName == tagname + def IsDebugging(self): + return False + def SetMode(self, mode): pass diff -r f4c0e9c9b3b9 -r 26bc7d5d4264 Dialogs.py --- a/Dialogs.py Mon Sep 21 10:31:38 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 f4c0e9c9b3b9 -r 26bc7d5d4264 GraphicViewer.py --- a/GraphicViewer.py Mon Sep 21 10:31:38 2009 -0600 +++ b/GraphicViewer.py Tue Sep 22 09:56:52 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 f4c0e9c9b3b9 -r 26bc7d5d4264 PLCControler.py --- a/PLCControler.py Mon Sep 21 10:31:38 2009 -0600 +++ b/PLCControler.py Tue Sep 22 09:56:52 2009 +0200 @@ -532,6 +532,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 @@ -2495,10 +2498,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 f4c0e9c9b3b9 -r 26bc7d5d4264 PLCGenerator.py --- a/PLCGenerator.py Mon Sep 21 10:31:38 2009 -0600 +++ b/PLCGenerator.py Tue Sep 22 09:56:52 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 f4c0e9c9b3b9 -r 26bc7d5d4264 PLCOpenEditor.py --- a/PLCOpenEditor.py Mon Sep 21 10:31:38 2009 -0600 +++ b/PLCOpenEditor.py Tue Sep 22 09:56:52 2009 +0200 @@ -111,7 +111,8 @@ from VariablePanel import VariablePanel # Define PLCOpenEditor controls id -[ID_PLCOPENEDITOR, ID_PLCOPENEDITORTREENOTEBOOK, +[ID_PLCOPENEDITOR, ID_PLCOPENEDITORLEFTNOTEBOOK, + ID_PLCOPENEDITORBOTTOMNOTEBOOK, ID_PLCOPENEDITORRIGHTNOTEBOOK, ID_PLCOPENEDITORTYPESTREE, ID_PLCOPENEDITORINSTANCESTREE, ID_PLCOPENEDITORMAINSPLITTER, ID_PLCOPENEDITORSECONDSPLITTER, ID_PLCOPENEDITORTHIRDSPLITTER, ID_PLCOPENEDITORLIBRARYPANEL, @@ -120,7 +121,7 @@ ID_PLCOPENEDITORTOOLBAR, ID_PLCOPENEDITORDEFAULTTOOLBAR, ID_PLCOPENEDITORSFCTOOLBAR, ID_PLCOPENEDITORFBDTOOLBAR, ID_PLCOPENEDITORLDTOOLBAR, -] = [wx.NewId() for _init_ctrls in range(17)] +] = [wx.NewId() for _init_ctrls in range(19)] # Define PLCOpenEditor FileMenu extra items id [ID_PLCOPENEDITORFILEMENUGENERATE, @@ -250,7 +251,7 @@ [TITLE, TOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, TYPESTREE, INSTANCESTREE, LIBRARYTREE, SCALING -] = [wx.NewId() for _refresh_elements in range(9)] +] = range(9) def GetShortcutKeyCallbackFunction(viewer_function): def ShortcutKeyFunction(self, event): @@ -272,7 +273,7 @@ def GetDeleteElementFunction(remove_function, parent_type=None, check_function=None): def DeleteElementFunction(self, selected): name = self.TypesTree.GetItemText(selected) - if check_function is None or not check_function(self.Controler, name, self.Debug): + if check_function is None or not check_function(self.Controler, name): if parent_type is not None: parent_name = GetParentName(self.TypesTree, selected, parent_type) remove_function(self.Controler, parent_name, name) @@ -284,12 +285,12 @@ #------------------------------------------------------------------------------- -# PLCOpenEditor Main Class +# IDEFrame Base Class #------------------------------------------------------------------------------- UNEDITABLE_NAMES_DICT = dict([(_(name), name) for name in UNEDITABLE_NAMES]) -class PLCOpenEditor(wx.Frame): +class IDEFrame(wx.Frame): # Compatibility function for wx versions < 2.6 if wx.VERSION < (2, 6, 0): @@ -301,71 +302,12 @@ def _init_coll_MenuBar_Menus(self, parent): parent.Append(menu=self.FileMenu, title=_(u'File')) - if not self.Debug: - parent.Append(menu=self.EditMenu, title=_(u'Edit')) + parent.Append(menu=self.EditMenu, title=_(u'Edit')) parent.Append(menu=self.DisplayMenu, title=_(u'Display')) parent.Append(menu=self.HelpMenu, title=_(u'Help')) def _init_coll_FileMenu_Items(self, parent): - if self.ModeSolo: - AppendMenu(parent, help='', id=wx.ID_NEW, - kind=wx.ITEM_NORMAL, text=_(u'New\tCTRL+N')) - AppendMenu(parent, help='', id=wx.ID_OPEN, - kind=wx.ITEM_NORMAL, text=_(u'Open\tCTRL+O')) - AppendMenu(parent, help='', id=wx.ID_CLOSE, - kind=wx.ITEM_NORMAL, text=_(u'Close Tab\tCTRL+W')) - if self.ModeSolo: - AppendMenu(parent, help='', id=wx.ID_CLOSE_ALL, - kind=wx.ITEM_NORMAL, text=_(u'Close Project')) - parent.AppendSeparator() - if not self.Debug: - AppendMenu(parent, help='', id=wx.ID_SAVE, - kind=wx.ITEM_NORMAL, text=_(u'Save\tCTRL+S')) - if self.ModeSolo: - AppendMenu(parent, help='', id=wx.ID_SAVEAS, - kind=wx.ITEM_NORMAL, text=_(u'Save As...\tCTRL+SHIFT+S')) - AppendMenu(parent, help='', id=ID_PLCOPENEDITORFILEMENUGENERATE, - kind=wx.ITEM_NORMAL, text=_(u'Generate Program\tCTRL+G')) - parent.AppendSeparator() - AppendMenu(parent, help='', id=wx.ID_PAGE_SETUP, - kind=wx.ITEM_NORMAL, text=_(u'Page Setup')) - AppendMenu(parent, help='', id=wx.ID_PREVIEW, - kind=wx.ITEM_NORMAL, text=_(u'Preview')) - AppendMenu(parent, help='', id=wx.ID_PRINT, - kind=wx.ITEM_NORMAL, text=_(u'Print')) - if not self.Debug: - parent.AppendSeparator() - AppendMenu(parent, help='', id=wx.ID_PROPERTIES, - kind=wx.ITEM_NORMAL, text=_(u'Properties')) - parent.AppendSeparator() - if self.ModeSolo: - AppendMenu(parent, help='', id=wx.ID_EXIT, - kind=wx.ITEM_NORMAL, text=_(u'Quit\tCTRL+Q')) - else: - AppendMenu(parent, help='', id=wx.ID_STOP, - kind=wx.ITEM_NORMAL, text=_(u'Close\tCTRL+Q')) - - if self.ModeSolo: - self.Bind(wx.EVT_MENU, self.OnNewProjectMenu, id=wx.ID_NEW) - self.Bind(wx.EVT_MENU, self.OnOpenProjectMenu, id=wx.ID_OPEN) - self.Bind(wx.EVT_MENU, self.OnCloseTabMenu, id=wx.ID_CLOSE) - if self.ModeSolo: - self.Bind(wx.EVT_MENU, self.OnCloseProjectMenu, id=wx.ID_CLOSE_ALL) - if not self.Debug: - self.Bind(wx.EVT_MENU, self.OnSaveProjectMenu, id=wx.ID_SAVE) - if self.ModeSolo: - self.Bind(wx.EVT_MENU, self.OnSaveProjectAsMenu, id=wx.ID_SAVEAS) - self.Bind(wx.EVT_MENU, self.OnGenerateProgramMenu, - id=ID_PLCOPENEDITORFILEMENUGENERATE) - self.Bind(wx.EVT_MENU, self.OnPageSetupMenu, id=wx.ID_PAGE_SETUP) - self.Bind(wx.EVT_MENU, self.OnPreviewMenu, id=wx.ID_PREVIEW) - self.Bind(wx.EVT_MENU, self.OnPrintMenu, id=wx.ID_PRINT) - if not self.Debug: - self.Bind(wx.EVT_MENU, self.OnPropertiesMenu, id=wx.ID_PROPERTIES) - if self.ModeSolo: - self.Bind(wx.EVT_MENU, self.OnQuitMenu, id=wx.ID_EXIT) - else: - self.Bind(wx.EVT_MENU, self.OnQuitMenu, id=wx.ID_STOP) + pass def _init_coll_EditMenu_Items(self, parent): AppendMenu(parent, help='', id=wx.ID_UNDO, @@ -420,7 +362,7 @@ def _init_coll_DisplayMenu_Items(self, parent): AppendMenu(parent, help='', id=wx.ID_REFRESH, kind=wx.ITEM_NORMAL, text=_(u'Refresh\tF5')) - if not self.Debug and not self.ModeSolo: + if self.EnableDebug: AppendMenu(parent, help='', id=wx.ID_CLEAR, kind=wx.ITEM_NORMAL, text=_(u'Clear Errors\tCTRL+K')) parent.AppendSeparator() @@ -432,36 +374,23 @@ kind=wx.ITEM_RADIO, text=str(int(round(value * 100))) + "%") self.Bind(wx.EVT_MENU, self.GenerateZoomFunction(idx), id=new_id) self.Bind(wx.EVT_MENU, self.OnRefreshMenu, id=wx.ID_REFRESH) - if not self.Debug and not self.ModeSolo: + if self.EnableDebug: self.Bind(wx.EVT_MENU, self.OnClearErrorsMenu, id=wx.ID_CLEAR) def _init_coll_HelpMenu_Items(self, parent): - AppendMenu(parent, help='', id=wx.ID_HELP, - kind=wx.ITEM_NORMAL, text=_(u'PLCOpenEditor\tF1')) - #AppendMenu(parent, help='', id=wx.ID_HELP_CONTENTS, - # kind=wx.ITEM_NORMAL, text=u'PLCOpen\tF2') - #AppendMenu(parent, help='', id=wx.ID_HELP_CONTEXT, - # kind=wx.ITEM_NORMAL, text=u'IEC 61131-3\tF3') - if self.ModeSolo: - AppendMenu(parent, help='', id=wx.ID_ABOUT, - kind=wx.ITEM_NORMAL, text=_(u'About')) - self.Bind(wx.EVT_MENU, self.OnPLCOpenEditorMenu, id=wx.ID_HELP) - #self.Bind(wx.EVT_MENU, self.OnPLCOpenMenu, id=wx.ID_HELP_CONTENTS) - self.Bind(wx.EVT_MENU, self.OnAboutMenu, id=wx.ID_ABOUT) + pass def _init_utils(self): self.MenuBar = wx.MenuBar() self.FileMenu = wx.Menu(title='') - if not self.Debug: - self.EditMenu = wx.Menu(title='') + self.EditMenu = wx.Menu(title='') self.DisplayMenu = wx.Menu(title='') self.HelpMenu = wx.Menu(title='') self._init_coll_MenuBar_Menus(self.MenuBar) self._init_coll_FileMenu_Items(self.FileMenu) - if not self.Debug: - self._init_coll_EditMenu_Items(self.EditMenu) + self._init_coll_EditMenu_Items(self.EditMenu) self._init_coll_DisplayMenu_Items(self.DisplayMenu) self._init_coll_HelpMenu_Items(self.HelpMenu) @@ -482,21 +411,55 @@ self.LibraryPanel.SetSizer(self.MainLibrarySizer) def _init_ctrls(self, prnt): - wx.Frame.__init__(self, id=ID_PLCOPENEDITOR, name=u'PLCOpenEditor', + wx.Frame.__init__(self, id=ID_PLCOPENEDITOR, name='IDEFrame', parent=prnt, pos=wx.DefaultPosition, size=wx.Size(1000, 600), - style=wx.DEFAULT_FRAME_STYLE, title=_(u'PLCOpenEditor')) + style=wx.DEFAULT_FRAME_STYLE) self._init_utils() self.SetClientSize(wx.Size(1000, 600)) self.SetMenuBar(self.MenuBar) - self.Bind(wx.EVT_CLOSE, self.OnCloseFrame) + + self.TabsImageList = wx.ImageList(31, 16) + self.TabsImageListIndexes = {} + + #----------------------------------------------------------------------- + # Creating main structure + #----------------------------------------------------------------------- if USE_AUI: self.AUIManager = wx.aui.AuiManager(self) self.AUIManager.SetDockSizeConstraint(0.5, 0.5) self.Panes = {} - - self.TreeNoteBook = wx.aui.AuiNotebook(self) - self.AUIManager.AddPane(self.TreeNoteBook, wx.aui.AuiPaneInfo().Caption(_("Project")).Left().Layer(1).BestSize(wx.Size(200, 500)).CloseButton(False)) + + self.LeftNoteBook = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORLEFTNOTEBOOK, + style=wx.aui.AUI_NB_TOP|wx.aui.AUI_NB_TAB_SPLIT|wx.aui.AUI_NB_TAB_MOVE| + wx.aui.AUI_NB_SCROLL_BUTTONS|wx.aui.AUI_NB_TAB_EXTERNAL_MOVE) + self.AUIManager.AddPane(self.LeftNoteBook, + wx.aui.AuiPaneInfo().Caption(_("Project")).Left().Layer(1). + BestSize(wx.Size(300, 500)).CloseButton(False)) + + self.BottomNoteBook = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORBOTTOMNOTEBOOK, + style=wx.aui.AUI_NB_TOP|wx.aui.AUI_NB_TAB_SPLIT|wx.aui.AUI_NB_TAB_MOVE| + wx.aui.AUI_NB_SCROLL_BUTTONS|wx.aui.AUI_NB_TAB_EXTERNAL_MOVE) + self.AUIManager.AddPane(self.BottomNoteBook, + wx.aui.AuiPaneInfo().Bottom().Layer(0). + BestSize(wx.Size(800, 200)).CloseButton(False)) + + self.RightNoteBook = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORRIGHTNOTEBOOK, + style=wx.aui.AUI_NB_TOP|wx.aui.AUI_NB_TAB_SPLIT|wx.aui.AUI_NB_TAB_MOVE| + wx.aui.AUI_NB_SCROLL_BUTTONS|wx.aui.AUI_NB_TAB_EXTERNAL_MOVE) + self.AUIManager.AddPane(self.RightNoteBook, + wx.aui.AuiPaneInfo().Right().Layer(0). + BestSize(wx.Size(250, 400)).CloseButton(False)) + + self.TabsOpened = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORTABSOPENED, + style=wx.aui.AUI_NB_DEFAULT_STYLE|wx.aui.AUI_NB_WINDOWLIST_BUTTON) + self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED, + self.OnPouSelectedChanged) + self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE, + self.OnPageClose) + self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_END_DRAG, + self.OnPageDragged) + self.AUIManager.AddPane(self.TabsOpened, wx.aui.AuiPaneInfo().CentrePane()) else: self.MainSplitter = wx.SplitterWindow(id=ID_PLCOPENEDITORMAINSPLITTER, @@ -505,50 +468,86 @@ self.MainSplitter.SetNeedUpdating(True) self.MainSplitter.SetMinimumPaneSize(1) - self.TreeNoteBook = wx.Notebook(id=ID_PLCOPENEDITORTREENOTEBOOK, - name='TreeNoteBook', parent=self.MainSplitter, pos=wx.Point(0, + self.LeftNoteBook = wx.Notebook(id=ID_PLCOPENEDITORLEFTNOTEBOOK, + name='LeftNoteBook', parent=self.MainSplitter, pos=wx.Point(0, + 0), size=wx.Size(0, 0), style=0) + + self.SecondSplitter = wx.SplitterWindow(id=ID_PLCOPENEDITORSECONDSPLITTER, + name='SecondSplitter', parent=self.MainSplitter, point=wx.Point(0, 0), + size=wx.Size(0, 0), style=wx.SP_3D) + self.SecondSplitter.SetMinimumPaneSize(1) + + self.MainSplitter.SplitVertically(self.LeftNoteBook, self.SecondSplitter, 200) + + self.ThirdSplitter = wx.SplitterWindow(id=ID_PLCOPENEDITORTHIRDSPLITTER, + name='ThirdSplitter', parent=self.SecondSplitter, point=wx.Point(0, 0), + size=wx.Size(0, 0), style=wx.SP_3D) + self.ThirdSplitter.SetMinimumPaneSize(1) + + self.BottomNoteBook = wx.Notebook(id=ID_PLCOPENEDITORBOTTOMNOTEBOOK, + name='BottomNoteBook', parent=self.SecondSplitter, pos=wx.Point(0, 0), size=wx.Size(0, 0), style=0) - typestreestyle = wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER - if not self.Debug: - typestreestyle |= wx.TR_EDIT_LABELS + self.SecondSplitter.SplitHorizontally(self.ThirdSplitter, self.BottomNoteBook, -200) + + self.TabsOpened = wx.Notebook(id=ID_PLCOPENEDITORTABSOPENED, + name='TabsOpened', parent=self.ThirdSplitter, pos=wx.Point(0, + 0), size=wx.Size(0, 0), style=0) + self.TabsOpened.SetImageList(self.TabsImageList) + if wx.VERSION >= (2, 6, 0): + self.TabsOpened.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, + self.OnPouSelectedChanged, id=ID_PLCOPENEDITORTABSOPENED) + else: + wx.EVT_NOTEBOOK_PAGE_CHANGED(self.TabsOpened, ID_PLCOPENEDITORTABSOPENED, + self.OnPouSelectedChanged) + + self.RightNoteBook = wx.Notebook(id=ID_PLCOPENEDITORRIGHTNOTEBOOK, + name='RightNoteBook', parent=self.ThirdSplitter, pos=wx.Point(0, + 0), size=wx.Size(0, 0), style=0) + + self.ThirdSplitter.SplitVertically(self.TabsOpened, self.RightNoteBook, -250) + + #----------------------------------------------------------------------- + # Creating PLCopen Project tree + #----------------------------------------------------------------------- + self.TypesTree = wx.TreeCtrl(id=ID_PLCOPENEDITORTYPESTREE, - name='TypesTree', parent=self.TreeNoteBook, + name='TypesTree', parent=self.LeftNoteBook, pos=wx.Point(0, 0), size=wx.Size(0, 0), - style=typestreestyle) - if not self.Debug: - if wx.Platform == '__WXMSW__': - self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnTypesTreeRightUp, - id=ID_PLCOPENEDITORTYPESTREE) - self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnTypesTreeItemSelected, - id=ID_PLCOPENEDITORTYPESTREE) + style=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER|wx.TR_EDIT_LABELS) + if wx.Platform == '__WXMSW__': + self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnTypesTreeRightUp, + id=ID_PLCOPENEDITORTYPESTREE) + self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnTypesTreeItemSelected, + id=ID_PLCOPENEDITORTYPESTREE) + else: + if wx.VERSION >= (2, 6, 0): + self.TypesTree.Bind(wx.EVT_RIGHT_UP, self.OnTypesTreeRightUp) + self.TypesTree.Bind(wx.EVT_LEFT_UP, self.OnTypesTreeLeftUp) else: - if wx.VERSION >= (2, 6, 0): - self.TypesTree.Bind(wx.EVT_RIGHT_UP, self.OnTypesTreeRightUp) - self.TypesTree.Bind(wx.EVT_LEFT_UP, self.OnTypesTreeLeftUp) - else: - wx.EVT_RIGHT_UP(self.TypesTree, self.OnTypesTreeRightUp) - wx.EVT_LEFT_UP(self.TypesTree, self.OnTypesTreeLeftUp) - self.Bind(wx.EVT_TREE_SEL_CHANGING, self.OnTypesTreeItemChanging, - id=ID_PLCOPENEDITORTYPESTREE) - self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnTypesTreeBeginDrag, + wx.EVT_RIGHT_UP(self.TypesTree, self.OnTypesTreeRightUp) + wx.EVT_LEFT_UP(self.TypesTree, self.OnTypesTreeLeftUp) + self.Bind(wx.EVT_TREE_SEL_CHANGING, self.OnTypesTreeItemChanging, id=ID_PLCOPENEDITORTYPESTREE) - self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnTypesTreeItemBeginEdit, - id=ID_PLCOPENEDITORTYPESTREE) - self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnTypesTreeItemEndEdit, - id=ID_PLCOPENEDITORTYPESTREE) - self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnTypesTreeItemActivated, - id=ID_PLCOPENEDITORTYPESTREE) + self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnTypesTreeBeginDrag, + id=ID_PLCOPENEDITORTYPESTREE) + self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnTypesTreeItemBeginEdit, + id=ID_PLCOPENEDITORTYPESTREE) + self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnTypesTreeItemEndEdit, + id=ID_PLCOPENEDITORTYPESTREE) + self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnTypesTreeItemActivated, + id=ID_PLCOPENEDITORTYPESTREE) + self.LeftNoteBook.AddPage(self.TypesTree, _("Types")) + + #----------------------------------------------------------------------- + # Creating PLCopen Project tree + #----------------------------------------------------------------------- self.InstancesTree = wx.TreeCtrl(id=ID_PLCOPENEDITORINSTANCESTREE, - name='InstancesTree', parent=self.TreeNoteBook, + name='InstancesTree', parent=self.LeftNoteBook, pos=wx.Point(0, 0), size=wx.Size(0, 0), style=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER) - - self.TabsImageList = wx.ImageList(31, 16) - self.TabsImageListIndexes = {} - - if self.Debug: + if self.EnableDebug: if wx.VERSION >= (2, 6, 0): self.InstancesTree.Bind(wx.EVT_RIGHT_UP, self.OnInstancesTreeRightUp) else: @@ -557,140 +556,66 @@ id=ID_PLCOPENEDITORINSTANCESTREE) self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnInstancesTreeItemActivated, id=ID_PLCOPENEDITORINSTANCESTREE) - - self.TreeNoteBook.AddPage(self.InstancesTree, _("Instances")) - self.TreeNoteBook.AddPage(self.TypesTree, _("Types")) - - if USE_AUI: - self.TabsOpened = wx.aui.AuiNotebook(self) - self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED, - self.OnPouSelectedChanged) - self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE, - self.OnPageClose) - self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_END_DRAG, - self.OnPageDragged) - self.AUIManager.AddPane(self.TabsOpened, wx.aui.AuiPaneInfo().CentrePane()) - - self.DebugVariablePanel = DebugVariablePanel(self, self.Controler.DataProducer) - self.AUIManager.AddPane(self.DebugVariablePanel, wx.aui.AuiPaneInfo().Caption(_("Variables")).Right().Layer(0).BestSize(wx.Size(250, 600)).CloseButton(False)) - else: - self.SecondSplitter = wx.SplitterWindow(id=ID_PLCOPENEDITORSECONDSPLITTER, - name='SecondSplitter', parent=self.MainSplitter, point=wx.Point(0, 0), - size=wx.Size(0, 0), style=wx.SP_3D) - self.SecondSplitter.SetMinimumPaneSize(1) - - self.MainSplitter.SplitVertically(self.TreeNoteBook, self.SecondSplitter, 200) - - self.TabsOpened = wx.Notebook(id=ID_PLCOPENEDITORTABSOPENED, - name='TabsOpened', parent=self.SecondSplitter, pos=wx.Point(0, - 0), size=wx.Size(0, 0), style=0) - if wx.VERSION >= (2, 6, 0): - self.TabsOpened.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, - self.OnPouSelectedChanged, id=ID_PLCOPENEDITORTABSOPENED) - else: - wx.EVT_NOTEBOOK_PAGE_CHANGED(self.TabsOpened, ID_PLCOPENEDITORTABSOPENED, - self.OnPouSelectedChanged) - - self.DebugVariablePanel = DebugVariablePanel(self.SecondSplitter, self.Controler.DataProducer) - - self.SecondSplitter.SplitVertically(self.TabsOpened, self.DebugVariablePanel, -250) + self.LeftNoteBook.AddPage(self.InstancesTree, _("Instances")) + + #----------------------------------------------------------------------- + # Creating Tool Bar + #----------------------------------------------------------------------- + + if USE_AUI: + ToolBar = wx.ToolBar(self, ID_PLCOPENEDITORTOOLBAR, wx.DefaultPosition, wx.DefaultSize, + wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER) + ToolBar.SetToolBitmapSize(wx.Size(25, 25)) + ToolBar.AddRadioTool(ID_PLCOPENEDITORTOOLBARSELECTION, + wx.Bitmap(os.path.join(CWD, 'Images', 'select.png')), wx.NullBitmap, _("Select an object")) + ToolBar.Realize() + self.Panes["ToolBar"] = ToolBar + self.AUIManager.AddPane(ToolBar, wx.aui.AuiPaneInfo(). + Name("ToolBar").Caption(_("Toolbar")). + ToolbarPane().Top(). + LeftDockable(False).RightDockable(False)) else: - self.TreeNoteBook.AddPage(self.TypesTree, _("Types")) - self.TreeNoteBook.AddPage(self.InstancesTree, _("Instances")) - - if USE_AUI: - ToolBar = wx.ToolBar(self, ID_PLCOPENEDITORTOOLBAR, wx.DefaultPosition, wx.DefaultSize, - wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER) - ToolBar.SetToolBitmapSize(wx.Size(25, 25)) - ToolBar.AddRadioTool(ID_PLCOPENEDITORTOOLBARSELECTION, - wx.Bitmap(os.path.join(CWD, 'Images', 'select.png')), wx.NullBitmap, _("Select an object")) - ToolBar.Realize() - self.Panes["ToolBar"] = ToolBar - self.AUIManager.AddPane(ToolBar, wx.aui.AuiPaneInfo(). - Name("ToolBar").Caption(_("Toolbar")). - ToolbarPane().Top(). - LeftDockable(False).RightDockable(False)) - else: - self.ToolBar = self.CreateToolBar(wx.TB_HORIZONTAL|wx.TB_FLAT|wx.NO_BORDER, - ID_PLCOPENEDITORTOOLBAR, 'ToolBar') - self.ToolBar.SetToolBitmapSize(wx.Size(25, 25)) - self.ToolBar.AddRadioTool(ID_PLCOPENEDITORTOOLBARSELECTION, - wx.Bitmap(os.path.join(CWD, 'Images', 'select.png')), wx.NullBitmap, _("Select an object")) - self.ToolBar.Realize() + self.ToolBar = self.CreateToolBar(wx.TB_HORIZONTAL|wx.TB_FLAT|wx.NO_BORDER, + ID_PLCOPENEDITORTOOLBAR, 'ToolBar') + self.ToolBar.SetToolBitmapSize(wx.Size(25, 25)) + self.ToolBar.AddRadioTool(ID_PLCOPENEDITORTOOLBARSELECTION, + wx.Bitmap(os.path.join(CWD, 'Images', 'select.png')), wx.NullBitmap, _("Select an object")) + self.ToolBar.Realize() self.Bind(wx.EVT_TOOL, self.OnSelectionTool, id=ID_PLCOPENEDITORTOOLBARSELECTION) - - if USE_AUI: - self.VariablePanelIndexer = VariablePanelIndexer(self, self, self.Controler) - self.AUIManager.AddPane(self.VariablePanelIndexer, wx.aui.AuiPaneInfo().Caption(_("Variables")).Bottom().Layer(0).BestSize(wx.Size(800, 200)).CloseButton(False)) - - self.TabsOpened = wx.aui.AuiNotebook(self) - self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED, - self.OnPouSelectedChanged) - self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE, - self.OnPageClose) - self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_END_DRAG, - self.OnPageDragged) - self.AUIManager.AddPane(self.TabsOpened, wx.aui.AuiPaneInfo().CentrePane().MinSize(wx.Size(0, 0))) - - self.LibraryPanel = wx.Panel(id=ID_PLCOPENEDITORLIBRARYPANEL, - name='LibraryPanel', parent=self, pos=wx.Point(0, - 0), size=wx.Size(0, 0), style=0) - self.AUIManager.AddPane(self.LibraryPanel, wx.aui.AuiPaneInfo().Caption(_("Library")).Right().Layer(0).BestSize(wx.Size(250, 400)).CloseButton(False)) - else: - self.SecondSplitter = wx.SplitterWindow(id=ID_PLCOPENEDITORSECONDSPLITTER, - name='SecondSplitter', parent=self.MainSplitter, point=wx.Point(0, 0), - size=wx.Size(0, 0), style=wx.SP_3D) - self.SecondSplitter.SetMinimumPaneSize(1) - - self.MainSplitter.SplitVertically(self.TreeNoteBook, self.SecondSplitter, 200) - - self.VariablePanelIndexer = VariablePanelIndexer(self.SecondSplitter, self, self.Controler) - - self.ThirdSplitter = wx.SplitterWindow(id=ID_PLCOPENEDITORTHIRDSPLITTER, - name='ThirdSplitter', parent=self.SecondSplitter, point=wx.Point(0, 0), - size=wx.Size(0, 0), style=wx.SP_3D) - self.ThirdSplitter.SetMinimumPaneSize(1) - - self.SecondSplitter.SplitHorizontally(self.ThirdSplitter, self.VariablePanelIndexer, -200) - - self.TabsOpened = wx.Notebook(id=ID_PLCOPENEDITORTABSOPENED, - name='TabsOpened', parent=self.ThirdSplitter, pos=wx.Point(0, - 0), size=wx.Size(0, 0), style=0) - self.TabsOpened.SetImageList(self.TabsImageList) - if wx.VERSION >= (2, 6, 0): - self.TabsOpened.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, - self.OnPouSelectedChanged, id=ID_PLCOPENEDITORTABSOPENED) - else: - wx.EVT_NOTEBOOK_PAGE_CHANGED(self.TabsOpened, ID_PLCOPENEDITORTABSOPENED, - self.OnPouSelectedChanged) - - self.LibraryPanel = wx.Panel(id=ID_PLCOPENEDITORLIBRARYPANEL, - name='LibraryPanel', parent=self.ThirdSplitter, pos=wx.Point(0, - 0), size=wx.Size(0, 0), style=wx.SUNKEN_BORDER) - - self.ThirdSplitter.SplitVertically(self.TabsOpened, self.LibraryPanel, -250) - - if wx.Platform == '__WXMSW__': - librarytreestyle = wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER - else: - librarytreestyle = wx.TR_HAS_BUTTONS|wx.TR_HIDE_ROOT|wx.TR_SINGLE|wx.SUNKEN_BORDER - self.LibraryTree = wx.TreeCtrl(id=ID_PLCOPENEDITORLIBRARYTREE, - name='LibraryTree', parent=self.LibraryPanel, - pos=wx.Point(0, 0), size=wx.Size(0, 0), - style=librarytreestyle) - self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnLibraryTreeItemSelected, - id=ID_PLCOPENEDITORLIBRARYTREE) - self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnLibraryTreeBeginDrag, - id=ID_PLCOPENEDITORLIBRARYTREE) - - self.LibraryComment = wx.TextCtrl(id=ID_PLCOPENEDITORLIBRARYCOMMENT, - name='LibraryComment', parent=self.LibraryPanel, - pos=wx.Point(0, 0), size=wx.Size(0, 60), - style=wx.TE_READONLY|wx.TE_MULTILINE) - - self._init_sizers() + + self.VariablePanelIndexer = VariablePanelIndexer(self.BottomNoteBook, self) + self.BottomNoteBook.AddPage(self.VariablePanelIndexer, _("Variables")) + + self.LibraryPanel = wx.Panel(id=ID_PLCOPENEDITORLIBRARYPANEL, + name='LibraryPanel', parent=self.RightNoteBook, pos=wx.Point(0, + 0), size=wx.Size(0, 0), style=0) + self.RightNoteBook.AddPage(self.LibraryPanel, _("Library")) + + if wx.Platform == '__WXMSW__': + librarytreestyle = wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER + else: + librarytreestyle = wx.TR_HAS_BUTTONS|wx.TR_HIDE_ROOT|wx.TR_SINGLE|wx.SUNKEN_BORDER + self.LibraryTree = wx.TreeCtrl(id=ID_PLCOPENEDITORLIBRARYTREE, + name='LibraryTree', parent=self.LibraryPanel, + pos=wx.Point(0, 0), size=wx.Size(0, 0), + style=librarytreestyle) + self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnLibraryTreeItemSelected, + id=ID_PLCOPENEDITORLIBRARYTREE) + self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnLibraryTreeBeginDrag, + id=ID_PLCOPENEDITORLIBRARYTREE) + + self.LibraryComment = wx.TextCtrl(id=ID_PLCOPENEDITORLIBRARYCOMMENT, + name='LibraryComment', parent=self.LibraryPanel, + pos=wx.Point(0, 0), size=wx.Size(0, 60), + style=wx.TE_READONLY|wx.TE_MULTILINE) + + self._init_sizers() + + if self.EnableDebug: + self.DebugVariablePanel = DebugVariablePanel(self.RightNoteBook, self.Controler) + self.RightNoteBook.AddPage(self.DebugVariablePanel, _("Debugger")) if USE_AUI: self.AUIManager.Update() @@ -700,24 +625,12 @@ # @param controler The controler been used by PLCOpenEditor (default: None). # @param fileOpen The filepath to open if no controler defined (default: None). # @param debug The filepath to open if no controler defined (default: False). - def __init__(self, parent, controler = None, fileOpen = None, debug = False): - # Variable indicating that PLCOpenEditor was opened with a defined controler - self.ModeSolo = controler == None - self.Debug = debug - if self.ModeSolo: - # If no controler defined, create a new one - self.Controler = PLCControler() - # Open the filepath if defined - if fileOpen is not None: - self.Controler.OpenXMLFile(fileOpen) - else: - self.Controler = controler + def __init__(self, parent, enable_debug = False): + self.Controler = None + self.EnableDebug = enable_debug self._init_ctrls(parent) - # Define PLCOpenEditor icon - self.SetIcon(wx.Icon(os.path.join(CWD,"Images", "poe.ico"),wx.BITMAP_TYPE_ICO)) - # Define Tree item icon list self.TreeImageList = wx.ImageList(16, 16) self.TreeImageDict = {} @@ -777,21 +690,31 @@ self.PageSetupData.SetMarginTopLeft(wx.Point(10, 15)) self.PageSetupData.SetMarginBottomRight(wx.Point(10, 20)) - # Refresh elements that need to - if not self.ModeSolo or fileOpen is not None: - self._Refresh(TYPESTREE, INSTANCESTREE, LIBRARYTREE) - self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU) - + self.SetRefreshFunctions() + + self.Maximize() #------------------------------------------------------------------------------- # General Functions #------------------------------------------------------------------------------- + def SetRefreshFunctions(self): + self.RefreshFunctions = { + TITLE : self.RefreshTitle, + TOOLBAR : self.RefreshToolBar, + FILEMENU : self.RefreshFileMenu, + EDITMENU : self.RefreshEditMenu, + DISPLAYMENU : self.RefreshDisplayMenu, + TYPESTREE : self.RefreshTypesTree, + INSTANCESTREE : self.RefreshInstancesTree, + LIBRARYTREE : self.RefreshLibraryTree, + SCALING : self.RefreshScaling} + ## Call PLCOpenEditor refresh functions. # @param elements List of elements to refresh. def _Refresh(self, *elements): for element in elements: - self.RefreshFunctions[element](self) + self.RefreshFunctions[element]() ## Callback function when AUINotebook Page closed with CloseButton # @param event AUINotebook Event. @@ -800,16 +723,16 @@ selected = event.GetSelection() if selected >= 0: # Remove corresponding VariablePanel - if not self.Debug: - tagname = self.TabsOpened.GetPage(selected).GetTagName() - self.VariablePanelIndexer.RemoveVariablePanel(tagname) + window = self.TabsOpened.GetPage(selected) + if not window.IsDebugging(): + self.VariablePanelIndexer.RemoveVariablePanel(window.GetTagName()) # Refresh Tab selection if self.TabsOpened.GetPageCount() > 0: new_index = min(selected, self.TabsOpened.GetPageCount() - 1) self.TabsOpened.SetSelection(new_index) - if not self.Debug: - tagname = self.TabsOpened.GetPage(new_index).GetTagName() - self.VariablePanelIndexer.ChangeVariablePanel(tagname) + window = self.TabsOpened.GetPage(selected) + if not window.IsDebugging(): + self.VariablePanelIndexer.ChangeVariablePanel(window.GetTagName()) # Refresh all window elements that have changed self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU) wx.CallAfter(self.RefreshTabCtrlEvent) @@ -838,22 +761,13 @@ def GetDrawingMode(self): return self.DrawingMode - def RefreshTitle(self): - name = _("PLCOpenEditor") - if self.Debug: - name += _(" (Debug)") - if self.Controler.HasOpenedProject() > 0: - self.SetTitle("%s - %s"%(name, self.Controler.GetFilename())) - else: - self.SetTitle(name) - def RefreshScaling(self): for i in xrange(self.TabsOpened.GetPageCount()): editor = self.TabsOpened.GetPage(i) editor.RefreshScaling() def ShowProperties(self): - old_values = self.Controler.GetProjectProperties(self.Debug) + old_values = self.Controler.GetProjectProperties() dialog = ProjectDialog(self) dialog.SetValues(old_values) if dialog.ShowModal() == wx.ID_OK: @@ -865,16 +779,6 @@ TYPESTREE, INSTANCESTREE, SCALING) dialog.Destroy() - def OnCloseFrame(self, event): - if not self.ModeSolo and getattr(self, "_onclose", None) is not None: - self.AUIManager.UnInit() - self._onclose() - event.Skip() - elif self.CheckSaveBeforeClosing(): - event.Skip() - else: - event.Veto() - #------------------------------------------------------------------------------- # Notebook Unified Functions #------------------------------------------------------------------------------- @@ -979,160 +883,31 @@ #------------------------------------------------------------------------------- def RefreshFileMenu(self): - if self.Controler.HasOpenedProject(): - selected = self.TabsOpened.GetSelection() - if selected >= 0: - graphic_viewer = isinstance(self.TabsOpened.GetPage(selected), Viewer) - else: - graphic_viewer = False - if self.TabsOpened.GetPageCount() > 0: - self.FileMenu.Enable(wx.ID_CLOSE, True) - if graphic_viewer: - self.FileMenu.Enable(wx.ID_PREVIEW, True) - self.FileMenu.Enable(wx.ID_PRINT, True) - else: - self.FileMenu.Enable(wx.ID_PREVIEW, False) - self.FileMenu.Enable(wx.ID_PRINT, False) - else: - self.FileMenu.Enable(wx.ID_CLOSE, False) - self.FileMenu.Enable(wx.ID_PREVIEW, False) - self.FileMenu.Enable(wx.ID_PRINT, False) - self.FileMenu.Enable(wx.ID_PAGE_SETUP, True) - if not self.Debug: - self.FileMenu.Enable(wx.ID_SAVE, True) - self.FileMenu.Enable(wx.ID_PROPERTIES, True) - if self.ModeSolo: - self.FileMenu.Enable(wx.ID_CLOSE_ALL, True) - self.FileMenu.Enable(wx.ID_SAVEAS, True) - self.FileMenu.Enable(ID_PLCOPENEDITORFILEMENUGENERATE, True) - else: - self.FileMenu.Enable(wx.ID_CLOSE, False) - self.FileMenu.Enable(wx.ID_PAGE_SETUP, False) - self.FileMenu.Enable(wx.ID_PREVIEW, False) - self.FileMenu.Enable(wx.ID_PRINT, False) - if not self.Debug: - self.FileMenu.Enable(wx.ID_SAVE, False) - self.FileMenu.Enable(wx.ID_PROPERTIES, False) - if self.ModeSolo: - self.FileMenu.Enable(wx.ID_CLOSE_ALL, False) - self.FileMenu.Enable(wx.ID_SAVEAS, False) - self.FileMenu.Enable(ID_PLCOPENEDITORFILEMENUGENERATE, False) - - def OnNewProjectMenu(self, event): - dialog = ProjectDialog(self) - if dialog.ShowModal() == wx.ID_OK: - properties = dialog.GetValues() - self.Controler.CreateNewProject(properties) - self._Refresh(TITLE, FILEMENU, EDITMENU, TYPESTREE, INSTANCESTREE, - LIBRARYTREE) - event.Skip() - - def OnOpenProjectMenu(self, event): - if not self.CheckSaveBeforeClosing(): - return - filepath = self.Controler.GetFilePath() - if filepath != "": - directory = os.path.dirname(filepath) - else: - directory = os.getcwd() - dialog = wx.FileDialog(self, _("Choose a file"), directory, "", _("PLCOpen files (*.xml)|*.xml|All files|*.*"), wx.OPEN) - if dialog.ShowModal() == wx.ID_OK: - filepath = dialog.GetPath() - if os.path.isfile(filepath): - self.DeleteAllPages() - self.VariablePanelIndexer.RemoveAllPanels() - self.Controler.OpenXMLFile(filepath) - self._Refresh(TYPESTREE, INSTANCESTREE, LIBRARYTREE) - self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU) - dialog.Destroy() - event.Skip() + pass + + def ResetView(self): + self.DeleteAllPages() + self.VariablePanelIndexer.RemoveAllPanels() + self.TypesTree.DeleteAllItems() + self.InstancesTree.DeleteAllItems() + self.LibraryTree.DeleteAllItems() + self.Controler = None def OnCloseTabMenu(self, event): selected = self.TabsOpened.GetSelection() if selected >= 0: - if not self.Debug: - tagname = self.TabsOpened.GetPage(selected).GetTagName() - self.VariablePanelIndexer.RemoveVariablePanel(tagname) + window = self.TabsOpened.GetPage(selected) + if not window.IsDebugging(): + self.VariablePanelIndexer.RemoveVariablePanel(window.GetTagName()) self.TabsOpened.DeletePage(selected) if self.TabsOpened.GetPageCount() > 0: new_index = min(selected, self.TabsOpened.GetPageCount() - 1) self.TabsOpened.SetSelection(new_index) - if not self.Debug: - tagname = self.TabsOpened.GetPage(new_index).GetTagName() - self.VariablePanelIndexer.ChangeVariablePanel(tagname) + window = self.TabsOpened.GetPage(new_index) + if not window.IsDebugging(): + self.VariablePanelIndexer.ChangeVariablePanel(window.GetTagName()) self._Refresh(TOOLBAR, FILEMENU, EDITMENU) event.Skip() - - def OnCloseProjectMenu(self, event): - if not self.CheckSaveBeforeClosing(): - return - self.DeleteAllPages() - self.VariablePanelIndexer.RemoveAllPanels() - self.TypesTree.DeleteAllItems() - self.InstancesTree.DeleteAllItems() - self.Controler.Reset() - self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU) - event.Skip() - - def OnSaveProjectMenu(self, event): - if not self.ModeSolo and getattr(self, "_onsave", None) != None: - self._onsave() - else: - self.SaveProject() - event.Skip() - - def OnSaveProjectAsMenu(self, event): - self.SaveProjectAs() - event.Skip() - - def OnGenerateProgramMenu(self, event): - dialog = wx.FileDialog(self, _("Choose a file"), os.getcwd(), self.Controler.GetProgramFilePath(), _("ST files (*.st)|*.st|All files|*.*"), wx.SAVE|wx.CHANGE_DIR) - if dialog.ShowModal() == wx.ID_OK: - filepath = dialog.GetPath() - message_text = "" - header, icon = _("Done"), wx.ICON_INFORMATION - if os.path.isdir(os.path.dirname(filepath)): - program, errors, warnings = self.Controler.GenerateProgram(filepath) - message_text += "".join([_("warning: %s\n") for warning in warnings]) - if len(errors) > 0: - message_text += "".join([_("error: %s\n") for warning in warnings]) - message_text += _("Can't generate program to file %s!")%filepath - header, icon = _("Error"), wx.ICON_ERROR - else: - message_text += _("Program was successfully generated!") - else: - message_text += _("\"%s\" is not a valid folder!")%os.path.dirname(filepath) - header, icon = _("Error"), wx.ICON_ERROR - message = wx.MessageDialog(self, message_text, header, wx.OK|icon) - message.ShowModal() - message.Destroy() - dialog.Destroy() - event.Skip() - - def SaveProject(self): - result = self.Controler.SaveXMLFile() - if not result: - self.SaveProjectAs() - else: - self.RefreshTitle() - - def SaveProjectAs(self): - filepath = self.Controler.GetFilePath() - if filepath != "": - directory, filename = os.path.split(filepath) - else: - directory, filename = os.getcwd(), "%(projectName)s.xml"%self.Controler.GetProjectProperties(self.Debug) - dialog = wx.FileDialog(self, _("Choose a file"), directory, filename, _("PLCOpen files (*.xml)|*.xml|All files|*.*"), wx.SAVE|wx.OVERWRITE_PROMPT) - if dialog.ShowModal() == wx.ID_OK: - filepath = dialog.GetPath() - if os.path.isdir(os.path.dirname(filepath)): - result = self.Controler.SaveXMLFile(filepath) - if not result: - self.ShowErrorMessage(_("Can't save project to file %s!")%filepath) - else: - self.ShowErrorMessage(_("\"%s\" is not a valid folder!")%os.path.dirname(filepath)) - self.RefreshTitle() - dialog.Destroy() def OnPageSetupMenu(self, event): dialog = wx.PageSetupDialog(self, self.PageSetupData) @@ -1145,12 +920,13 @@ def OnPreviewMenu(self, event): selected = self.TabsOpened.GetSelection() if selected != -1: + window = self.TabsOpened.GetPage(selected) data = wx.PrintDialogData(self.PrintData) - properties = self.Controler.GetProjectProperties(self.Debug) + properties = self.Controler.GetProjectProperties(window.IsDebugging()) page_size = map(int, properties["pageSize"]) margins = (self.PageSetupData.GetMarginTopLeft(), self.PageSetupData.GetMarginBottomRight()) - printout = GraphicPrintout(self.TabsOpened.GetPage(selected), page_size, margins, True) - printout2 = GraphicPrintout(self.TabsOpened.GetPage(selected), page_size, margins, True) + printout = GraphicPrintout(window, page_size, margins, True) + printout2 = GraphicPrintout(window, page_size, margins, True) preview = wx.PrintPreview(printout, printout2, data) if preview.Ok(): @@ -1164,13 +940,14 @@ def OnPrintMenu(self, event): selected = self.TabsOpened.GetSelection() if selected != -1: + window = self.TabsOpened.GetPage(selected) dialog_data = wx.PrintDialogData(self.PrintData) dialog_data.SetToPage(1) - properties = self.Controler.GetProjectProperties(self.Debug) + properties = self.Controler.GetProjectProperties(window.IsDebugging()) page_size = map(int, properties["pageSize"]) margins = (self.PageSetupData.GetMarginTopLeft(), self.PageSetupData.GetMarginBottomRight()) printer = wx.Printer(dialog_data) - printout = GraphicPrintout(self.TabsOpened.GetPage(selected), page_size, margins) + printout = GraphicPrintout(window, page_size, margins) if not printer.Print(self, printout, True): self.ShowErrorMessage(_("There was a problem printing.\nPerhaps your current printer is not set correctly?")) @@ -1186,53 +963,66 @@ # don't call event.Skip() here or it will attempt to close the # frame twice for some reason - #------------------------------------------------------------------------------- # Edit Menu Functions #------------------------------------------------------------------------------- def RefreshEditMenu(self): - if not self.Debug: + if self.Controler is not None: + undo, redo = self.Controler.GetBufferState() + self.EditMenu.Enable(wx.ID_UNDO, undo) + self.EditMenu.Enable(wx.ID_REDO, redo) + self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, True) self.EditMenu.Check(ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, - self.Controler.IsProjectBufferEnabled()) - if self.Controler.HasOpenedProject(): - undo, redo = self.Controler.GetBufferState() - self.EditMenu.Enable(wx.ID_UNDO, undo) - self.EditMenu.Enable(wx.ID_REDO, redo) - self.EditMenu.Enable(wx.ID_ADD, True) - self.EditMenu.Enable(wx.ID_DELETE, True) - if self.TabsOpened.GetPageCount() > 0: - self.EditMenu.Enable(wx.ID_CUT, True) - self.EditMenu.Enable(wx.ID_COPY, True) - if self.GetCopyBuffer() is not None: - self.EditMenu.Enable(wx.ID_PASTE, True) - else: - self.EditMenu.Enable(wx.ID_PASTE, False) - self.EditMenu.Enable(wx.ID_SELECTALL, True) + self.Controler.IsProjectBufferEnabled()) + self.EditMenu.Enable(wx.ID_ADD, True) + self.EditMenu.Enable(wx.ID_DELETE, True) + if self.TabsOpened.GetPageCount() > 0: + self.EditMenu.Enable(wx.ID_CUT, True) + self.EditMenu.Enable(wx.ID_COPY, True) + if self.GetCopyBuffer() is not None: + self.EditMenu.Enable(wx.ID_PASTE, True) else: - self.EditMenu.Enable(wx.ID_CUT, False) - self.EditMenu.Enable(wx.ID_COPY, False) self.EditMenu.Enable(wx.ID_PASTE, False) - self.EditMenu.Enable(wx.ID_SELECTALL, False) + self.EditMenu.Enable(wx.ID_SELECTALL, True) else: - self.EditMenu.Enable(wx.ID_UNDO, False) - self.EditMenu.Enable(wx.ID_REDO, False) self.EditMenu.Enable(wx.ID_CUT, False) self.EditMenu.Enable(wx.ID_COPY, False) self.EditMenu.Enable(wx.ID_PASTE, False) self.EditMenu.Enable(wx.ID_SELECTALL, False) - self.EditMenu.Enable(wx.ID_ADD, False) - self.EditMenu.Enable(wx.ID_DELETE, False) + else: + self.EditMenu.Enable(wx.ID_UNDO, False) + self.EditMenu.Enable(wx.ID_REDO, False) + self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, False) + self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, False) + self.EditMenu.Enable(wx.ID_CUT, False) + self.EditMenu.Enable(wx.ID_COPY, False) + self.EditMenu.Enable(wx.ID_PASTE, False) + self.EditMenu.Enable(wx.ID_SELECTALL, False) + self.EditMenu.Enable(wx.ID_ADD, False) + self.EditMenu.Enable(wx.ID_DELETE, False) def CloseTabsWithoutModel(self): idxs = range(self.TabsOpened.GetPageCount()) idxs.reverse() for idx in idxs: - tagname = self.TabsOpened.GetPage(idx).GetTagName() - if self.Controler.GetEditedElement(tagname, self.Debug) is None: - self.VariablePanelIndexer.RemoveVariablePanel(tagname) - self.TabsOpened.DeletePage(idx) - + window = self.TabsOpened.GetPage(idx) + if not window.IsDebugging(): + tagname = window.GetTagName() + if self.Controler.GetEditedElement(tagname) is None: + self.VariablePanelIndexer.RemoveVariablePanel(tagname) + self.TabsOpened.DeletePage(idx) + + def CloseDebugTabs(self): + if self.EnableDebug: + idxs = range(self.TabsOpened.GetPageCount()) + idxs.reverse() + for idx in idxs: + window = self.TabsOpened.GetPage(idx) + if window.IsDebugging(): + self.TabsOpened.DeletePage(idx) + self.DebugVariablePanel.ResetGrid() + def OnUndoMenu(self, event): self.Controler.LoadPrevious() self.CloseTabsWithoutModel() @@ -1301,7 +1091,7 @@ #------------------------------------------------------------------------------- def RefreshDisplayMenu(self): - if self.Controler.HasOpenedProject(): + if self.Controler is not None: if self.TabsOpened.GetPageCount() > 0: self.DisplayMenu.Enable(wx.ID_REFRESH, True) selected = self.TabsOpened.GetSelection() @@ -1319,16 +1109,16 @@ else: self.DisplayMenu.Enable(wx.ID_REFRESH, False) self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, False) - if not self.Debug and not self.ModeSolo: + if self.EnableDebug: self.DisplayMenu.Enable(wx.ID_CLEAR, True) else: self.DisplayMenu.Enable(wx.ID_REFRESH, False) - if not self.Debug and not self.ModeSolo: + if self.EnableDebug: self.DisplayMenu.Enable(wx.ID_CLEAR, False) self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, False) def OnRefreshMenu(self, event): - self.RefreshEditor(not self.Debug) + self.RefreshEditor() event.Skip() def OnClearErrorsMenu(self, event): @@ -1373,19 +1163,18 @@ def OnPouSelectedChanged(self, event): old_selected = self.TabsOpened.GetSelection() if old_selected >= 0: - if self.Debug: - pass - else: - self.TabsOpened.GetPage(old_selected).ResetBuffer() + window = self.TabsOpened.GetPage(old_selected) + if not window.IsDebugging(): + window.ResetBuffer() selected = event.GetSelection() if selected >= 0: window = self.TabsOpened.GetPage(selected) - if not self.Debug: + if not window.IsDebugging(): self.SelectTypesTreeItem(window.GetTagName()) else: self.SelectInstancesTreeItem(self.InstancesTree.GetRootItem(), window.GetInstancePath()) window.RefreshView() - if not self.Debug: + if not window.IsDebugging(): self.VariablePanelIndexer.ChangeVariablePanel(window.GetTagName()) self._Refresh(FILEMENU, EDITMENU, DISPLAYMENU, TOOLBAR) event.Skip() @@ -1395,7 +1184,7 @@ if selected != -1: window = self.TabsOpened.GetPage(selected) window.RefreshView() - if variablepanel: + if window.IsDebugging() and variablepanel: self.RefreshVariablePanel(window.GetTagName()) def RefreshVariablePanel(self, tagname): @@ -1417,16 +1206,17 @@ def RefreshPageTitles(self): for idx in xrange(self.TabsOpened.GetPageCount()): window = self.TabsOpened.GetPage(idx) + debug = window.IsDebugging() words = window.GetTagName().split("::") if words[0] == "P": - pou_type = self.Controler.GetEditedElementType(window.GetTagName(), self.Debug)[1].upper() - pou_body_type = self.Controler.GetEditedElementBodyType(window.GetTagName(), self.Debug) + pou_type = self.Controler.GetEditedElementType(window.GetTagName(), debug)[1].upper() + pou_body_type = self.Controler.GetEditedElementBodyType(window.GetTagName(), debug) self.SetPageBitmap(idx, self.GenerateBitmap(pou_type, pou_body_type)) elif words[0] == "T": - pou_body_type = self.Controler.GetEditedElementBodyType(window.GetTagName(), self.Debug) + pou_body_type = self.Controler.GetEditedElementBodyType(window.GetTagName(), debug) self.SetPageBitmap(idx, self.GenerateBitmap("TRANSITION", pou_body_type)) elif words[0] == "A": - pou_body_type = self.Controler.GetEditedElementBodyType(window.GetTagName(), self.Debug) + pou_body_type = self.Controler.GetEditedElementBodyType(window.GetTagName(), debug) self.SetPageBitmap(idx, self.GenerateBitmap("ACTION", pou_body_type)) elif words[0] == "C": self.SetPageBitmap(idx, self.GenerateBitmap("CONFIGURATION")) @@ -1434,8 +1224,11 @@ self.SetPageBitmap(idx, self.GenerateBitmap("RESOURCE")) elif words[0] == "D": self.SetPageBitmap(idx, self.GenerateBitmap("DATATYPE")) - if self.Debug: - self.TabsOpened.SetPageText(idx, window.GetInstancePath()) + if debug: + text = window.GetInstancePath() + if len(text) > 15: + text = "..." + text[-12:] + self.TabsOpened.SetPageText(idx, text) else: self.TabsOpened.SetPageText(idx, "-".join(words[1:])) @@ -1457,7 +1250,7 @@ #------------------------------------------------------------------------------- def RefreshTypesTree(self): - infos = self.Controler.GetProjectInfos(self.Debug) + infos = self.Controler.GetProjectInfos() root = self.TypesTree.GetRootItem() if not root.IsOk(): root = self.TypesTree.AddRoot(infos["name"]) @@ -1479,7 +1272,7 @@ self.TypesTree.SetItemBackgroundColour(root, wx.WHITE) self.TypesTree.SetItemTextColour(root, wx.BLACK) if infos["type"] == ITEM_POU: - self.TypesTree.SetItemImage(root, self.TreeImageDict[self.Controler.GetPouBodyType(infos["name"], self.Debug)]) + self.TypesTree.SetItemImage(root, self.TreeImageDict[self.Controler.GetPouBodyType(infos["name"])]) else: self.TypesTree.SetItemImage(root, self.TreeImageDict[infos["type"]]) @@ -1544,7 +1337,7 @@ self.SelectedItem = event.GetItem() if self.SelectedItem is not None and self.TypesTree.GetPyData(self.SelectedItem) == ITEM_POU: block_name = self.TypesTree.GetItemText(self.SelectedItem) - block_type = self.Controler.GetPouType(block_name, self.Debug) + block_type = self.Controler.GetPouType(block_name) if block_type != "program": data = wx.TextDataObject(str((block_name, block_type, ""))) dragSource = wx.DropSource(self.TypesTree) @@ -1575,7 +1368,7 @@ if itemtype == ITEM_PROJECT: self.Controler.SetProjectProperties(name = new_name) elif itemtype == ITEM_DATATYPE: - if new_name.upper() in [name.upper() for name in self.Controler.GetProjectDataTypeNames(self.Debug) if name != old_name]: + if new_name.upper() in [name.upper() for name in self.Controler.GetProjectDataTypeNames() if name != old_name]: message = _("\"%s\" data type already exists!")%new_name abort = True if not abort: @@ -1584,10 +1377,10 @@ self.Controler.ComputeDataTypeName(new_name)) self.RefreshPageTitles() elif itemtype == ITEM_POU: - if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug) if name != old_name]: + if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames() if name != old_name]: message = _("\"%s\" pou already exists!")%new_name abort = True - elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(debug = self.Debug)]: + elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables()]: messageDialog = wx.MessageDialog(self, _("A POU has an element named \"%s\". This could cause a conflict. Do you wish to continue?")%new_name, _("Error"), wx.YES_NO|wx.ICON_QUESTION) if messageDialog.ShowModal() == wx.ID_NO: abort = True @@ -1600,9 +1393,9 @@ self.RefreshPageTitles() elif itemtype == ITEM_TRANSITION: pou_name = GetParentName(self.TypesTree, item, ITEM_POU) - if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]: + if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]: message = _("A POU named \"%s\" already exists!")%new_name - elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name, self.Debug) if name != old_name]: + elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name) if name != old_name]: message = _("A variable with \"%s\" as name already exists in this pou!")%new_name else: self.Controler.ChangePouTransitionName(pou_name, old_name, new_name) @@ -1611,9 +1404,9 @@ self.RefreshPageTitles() elif itemtype == ITEM_ACTION: pou_name = GetParentName(self.TypesTree, item, ITEM_POU) - if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]: + if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]: message = _("A POU named \"%s\" already exists!")%new_name - elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name, self.Debug) if name != old_name]: + elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name) if name != old_name]: message = _("A variable with \"%s\" as name already exists in this pou!")%new_name else: self.Controler.ChangePouActionName(pou_name, old_name, new_name) @@ -1621,15 +1414,15 @@ self.Controler.ComputePouActionName(pou_name, new_name)) self.RefreshPageTitles() elif itemtype == ITEM_CONFIGURATION: - if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames(self.Debug) if name != old_name]: + if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames() if name != old_name]: message = _("\"%s\" config already exists!")%new_name abort = True - elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]: + elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]: messageDialog = wx.MessageDialog(self, _("There is a POU named \"%s\". This could cause a conflict. Do you wish to continue?")%new_name, _("Error"), wx.YES_NO|wx.ICON_QUESTION) if messageDialog.ShowModal() == wx.ID_NO: abort = True messageDialog.Destroy() - elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(debug = self.Debug)]: + elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables()]: messageDialog = wx.MessageDialog(self, _("A POU has an element named \"%s\". This could cause a conflict. Do you wish to continue?")%new_name, _("Error"), wx.YES_NO|wx.ICON_QUESTION) if messageDialog.ShowModal() == wx.ID_NO: abort = True @@ -1641,15 +1434,15 @@ self.RefreshPageTitles() elif itemtype == ITEM_RESOURCE: config_name = GetParentName(self.TypesTree, item, ITEM_CONFIGURATION) - if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames(self.Debug)]: + if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames()]: message = _("\"%s\" config already exists!")%new_name abort = True - elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]: + elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]: messageDialog = wx.MessageDialog(self, _("There is a POU named \"%s\". This could cause a conflict. Do you wish to continue?")%new_name, _("Error"), wx.YES_NO|wx.ICON_QUESTION) if messageDialog.ShowModal() == wx.ID_NO: abort = True messageDialog.Destroy() - elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(debug = self.Debug)]: + elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables()]: messageDialog = wx.MessageDialog(self, _("A POU has an element named \"%s\". This could cause a conflict. Do you wish to continue?")%new_name, _("Error"), wx.YES_NO|wx.ICON_QUESTION) if messageDialog.ShowModal() == wx.ID_NO: abort = True @@ -1754,7 +1547,7 @@ self.AddPage(new_window, "") self.VariablePanelIndexer.AddVariablePanel(tagname, "resource") elif elementtype in [ITEM_POU, ITEM_TRANSITION, ITEM_ACTION]: - bodytype = self.Controler.GetEditedElementBodyType(tagname, self.Debug) + bodytype = self.Controler.GetEditedElementBodyType(tagname) if bodytype == "FBD": new_window = Viewer(self.TabsOpened, tagname, self, self.Controler) new_window.RefreshScaling(False) @@ -1773,7 +1566,7 @@ new_window.SetKeywords(ST_KEYWORDS) self.AddPage(new_window, "") words = tagname.split("::") - self.VariablePanelIndexer.AddVariablePanel(tagname, self.Controler.GetPouType(words[1], self.Debug)) + self.VariablePanelIndexer.AddVariablePanel(tagname, self.Controler.GetPouType(words[1])) elif elementtype == ITEM_DATATYPE: new_window = DataTypeEditor(self.TabsOpened, tagname, self, self.Controler) self.AddPage(new_window, "") @@ -1801,7 +1594,7 @@ type = self.TypesTree.GetPyData(item) if type == ITEM_POU: menu = wx.Menu(title='') - if self.Controler.GetPouBodyType(name, self.Debug) == "SFC": + if self.Controler.GetPouBodyType(name) == "SFC": new_id = wx.NewId() AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Transition")) self.Bind(wx.EVT_MENU, self.GenerateAddTransitionFunction(name), id=new_id) @@ -1817,7 +1610,7 @@ AppendMenu(menu, help='', id=wx.ID_COPY, kind=wx.ITEM_NORMAL, text=_("Copy")) self.Bind(wx.EVT_MENU, self.OnCopyPou, id=wx.ID_COPY) - pou_type = self.Controler.GetPouType(name, self.Debug) + pou_type = self.Controler.GetPouType(name) if pou_type in ["function", "functionBlock"]: change_menu = wx.Menu(title='') if pou_type == "function": @@ -1919,7 +1712,7 @@ #------------------------------------------------------------------------------- def RefreshInstancesTree(self): - infos = self.Controler.GetProjectTopology(self.Debug) + infos = self.Controler.GetProjectTopology(self.EnableDebug) root = self.InstancesTree.GetRootItem() if not root.IsOk(): root = self.InstancesTree.AddRoot(infos["name"]) @@ -1953,105 +1746,110 @@ self.InstancesTree.Delete(item) def OnInstancesTreeBeginDrag(self, event): - selected_item = event.GetItem() - selected_infos = self.InstancesTree.GetPyData(selected_item) - if selected_item is not None and selected_infos[0] in ITEMS_VARIABLE: - var_path = self.InstancesTree.GetItemText(selected_item).split(" (")[0] - parent_item = self.InstancesTree.GetItemParent(selected_item) - while self.InstancesTree.GetPyData(parent_item)[0] != ITEM_PROJECT: - parent_name = self.InstancesTree.GetItemText(parent_item).split(" (")[0] - var_path = "%s.%s"%(parent_name, var_path) - parent_item = self.InstancesTree.GetItemParent(parent_item) - data = wx.TextDataObject(str((var_path, "debug"))) - dragSource = wx.DropSource(self.InstancesTree) - dragSource.SetData(data) - dragSource.DoDragDrop() - event.Skip() - - def OnInstancesTreeItemActivated(self, event): - selected_item = event.GetItem() - selected_infos = self.InstancesTree.GetPyData(selected_item) - if selected_item is not None and selected_infos[0] in [ITEM_FUNCTIONBLOCK, ITEM_PROGRAM, ITEM_TRANSITION, ITEM_ACTION]: - instance_path = self.InstancesTree.GetItemText(selected_item).split(" (")[0] - parent_item = self.InstancesTree.GetItemParent(selected_item) - while self.InstancesTree.GetPyData(parent_item)[0] != ITEM_PROJECT: - parent_name = self.InstancesTree.GetItemText(parent_item).split(" (")[0] - instance_path = "%s.%s"%(parent_name, instance_path) - parent_item = self.InstancesTree.GetItemParent(parent_item) - openedidx = self.IsOpened(instance_path) - if openedidx is not None: - old_selected = self.TabsOpened.GetSelection() - if old_selected != openedidx: - if old_selected >= 0: - self.TabsOpened.GetPage(old_selected).ResetBuffer() - self.TabsOpened.SetSelection(openedidx) - elif selected_infos[1] is not None: - bodytype = self.Controler.GetEditedElementBodyType(selected_infos[1], self.Debug) - if bodytype == "FBD": - new_window = Viewer(self.TabsOpened, selected_infos[1], self, self.Controler, True, instance_path) - new_window.RefreshScaling(False) - elif bodytype == "LD": - new_window = LD_Viewer(self.TabsOpened, selected_infos[1], self, self.Controler, True, instance_path) - new_window.RefreshScaling(False) - elif bodytype == "SFC": - new_window = SFC_Viewer(self.TabsOpened, selected_infos[1], self, self.Controler, True, instance_path) - new_window.RefreshScaling(False) - else: - new_window = TextViewer(self.TabsOpened, selected_infos[1], self, self.Controler, True, instance_path) - new_window.SetTextSyntax(bodytype) - if bodytype == "IL": - new_window.SetKeywords(IL_KEYWORDS) - else: - new_window.SetKeywords(ST_KEYWORDS) - self.AddPage(new_window, "") - new_window.SetFocus() - self.RefreshPageTitles() - if selected_item is not None and selected_infos[0] in ITEMS_VARIABLE: - var_path, var_type = self.InstancesTree.GetItemText(selected_item).split(" (") - var_type = var_type.split(")")[0] - - if self.Controler.IsOfType(var_type, "ANY_NUM", self.Debug) or\ - self.Controler.IsOfType(var_type, "ANY_BIT", self.Debug): + if self.Controler.DebugAvailable(): + selected_item = event.GetItem() + selected_infos = self.InstancesTree.GetPyData(selected_item) + if selected_item is not None and selected_infos[0] in ITEMS_VARIABLE: + var_path = self.InstancesTree.GetItemText(selected_item).split(" (")[0] parent_item = self.InstancesTree.GetItemParent(selected_item) while self.InstancesTree.GetPyData(parent_item)[0] != ITEM_PROJECT: parent_name = self.InstancesTree.GetItemText(parent_item).split(" (")[0] var_path = "%s.%s"%(parent_name, var_path) parent_item = self.InstancesTree.GetItemParent(parent_item) + data = wx.TextDataObject(str((var_path, "debug"))) + dragSource = wx.DropSource(self.InstancesTree) + dragSource.SetData(data) + dragSource.DoDragDrop() + event.Skip() + else: + event.Veto() + + def OnInstancesTreeItemActivated(self, event): + if self.Controler.DebugAvailable(): + selected_item = event.GetItem() + selected_infos = self.InstancesTree.GetPyData(selected_item) + if selected_item is not None and selected_infos[0] in [ITEM_FUNCTIONBLOCK, ITEM_PROGRAM, ITEM_TRANSITION, ITEM_ACTION]: + instance_path = self.InstancesTree.GetItemText(selected_item).split(" (")[0] + parent_item = self.InstancesTree.GetItemParent(selected_item) + while self.InstancesTree.GetPyData(parent_item)[0] != ITEM_PROJECT: + parent_name = self.InstancesTree.GetItemText(parent_item).split(" (")[0] + instance_path = "%s.%s"%(parent_name, instance_path) + parent_item = self.InstancesTree.GetItemParent(parent_item) + openedidx = self.IsOpened(instance_path) + if openedidx is not None: + old_selected = self.TabsOpened.GetSelection() + if old_selected != openedidx: + if old_selected >= 0: + self.TabsOpened.GetPage(old_selected).ResetBuffer() + self.TabsOpened.SetSelection(openedidx) + elif selected_infos[1] is not None: + bodytype = self.Controler.GetEditedElementBodyType(selected_infos[1], True) + if bodytype == "FBD": + new_window = Viewer(self.TabsOpened, selected_infos[1], self, self.Controler, True, instance_path) + new_window.RefreshScaling(False) + elif bodytype == "LD": + new_window = LD_Viewer(self.TabsOpened, selected_infos[1], self, self.Controler, True, instance_path) + new_window.RefreshScaling(False) + elif bodytype == "SFC": + new_window = SFC_Viewer(self.TabsOpened, selected_infos[1], self, self.Controler, True, instance_path) + new_window.RefreshScaling(False) + else: + new_window = TextViewer(self.TabsOpened, selected_infos[1], self, self.Controler, True, instance_path) + new_window.SetTextSyntax(bodytype) + if bodytype == "IL": + new_window.SetKeywords(IL_KEYWORDS) + else: + new_window.SetKeywords(ST_KEYWORDS) + self.AddPage(new_window, "") + new_window.SetFocus() + self.RefreshPageTitles() + if selected_item is not None and selected_infos[0] in ITEMS_VARIABLE: + var_path, var_type = self.InstancesTree.GetItemText(selected_item).split(" (") + var_type = var_type.split(")")[0] - self.OpenGraphicViewer(var_path) + if self.Controler.IsOfType(var_type, "ANY_NUM", True) or\ + self.Controler.IsOfType(var_type, "ANY_BIT", True): + parent_item = self.InstancesTree.GetItemParent(selected_item) + while self.InstancesTree.GetPyData(parent_item)[0] != ITEM_PROJECT: + parent_name = self.InstancesTree.GetItemText(parent_item).split(" (")[0] + var_path = "%s.%s"%(parent_name, var_path) + parent_item = self.InstancesTree.GetItemParent(parent_item) + + self.OpenGraphicViewer(var_path) event.Skip() def OpenGraphicViewer(self, var_path): - new_window = GraphicViewer(self.TabsOpened, self, self.Controler.DataProducer, var_path) + new_window = GraphicViewer(self.TabsOpened, self, self.Controler, var_path) self.AddPage(new_window, "") new_window.SetFocus() self.RefreshPageTitles() def OnInstancesTreeRightUp(self, event): - if wx.Platform == '__WXMSW__': - selected_item = event.GetItem() - else: - selected_item = self.InstancesTree.GetSelection() - selected_infos = self.InstancesTree.GetPyData(selected_item) - if selected_item is not None and selected_infos[0] in ITEMS_VARIABLE: - var_path, var_type = self.InstancesTree.GetItemText(selected_item).split(" (") - var_type = var_type.split(")")[0] - - if self.Controler.IsOfType(var_type, "ANY_NUM", self.Debug) or\ - self.Controler.IsOfType(var_type, "ANY_BIT", self.Debug): - parent_item = self.InstancesTree.GetItemParent(selected_item) - while self.InstancesTree.GetPyData(parent_item)[0] != ITEM_PROJECT: - parent_name = self.InstancesTree.GetItemText(parent_item).split(" (")[0] - var_path = "%s.%s"%(parent_name, var_path) - parent_item = self.InstancesTree.GetItemParent(parent_item) + if self.Controler.DebugAvailable(): + if wx.Platform == '__WXMSW__': + selected_item = event.GetItem() + else: + selected_item = self.InstancesTree.GetSelection() + selected_infos = self.InstancesTree.GetPyData(selected_item) + if selected_item is not None and selected_infos[0] in ITEMS_VARIABLE: + var_path, var_type = self.InstancesTree.GetItemText(selected_item).split(" (") + var_type = var_type.split(")")[0] - menu = wx.Menu(title='') - new_id = wx.NewId() - AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Graphic Panel")) - self.Bind(wx.EVT_MENU, self.AddVariableGraphicFunction(var_path), id=new_id) - new_id = wx.NewId() - AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("CSV Log")) - self.PopupMenu(menu) + if self.Controler.IsOfType(var_type, "ANY_NUM", True) or\ + self.Controler.IsOfType(var_type, "ANY_BIT", True): + parent_item = self.InstancesTree.GetItemParent(selected_item) + while self.InstancesTree.GetPyData(parent_item)[0] != ITEM_PROJECT: + parent_name = self.InstancesTree.GetItemText(parent_item).split(" (")[0] + var_path = "%s.%s"%(parent_name, var_path) + parent_item = self.InstancesTree.GetItemParent(parent_item) + + menu = wx.Menu(title='') + new_id = wx.NewId() + AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Graphic Panel")) + self.Bind(wx.EVT_MENU, self.AddVariableGraphicFunction(var_path), id=new_id) + new_id = wx.NewId() + AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("CSV Log")) + self.PopupMenu(menu) event.Skip() def AddVariableGraphicFunction(self, iec_path): @@ -2090,59 +1888,58 @@ #------------------------------------------------------------------------------- def RefreshLibraryTree(self): - if not self.Debug: - to_delete = [] - blocktypes = self.Controler.GetBlockTypes(debug = self.Debug) - root = self.LibraryTree.GetRootItem() - if not root.IsOk(): - if wx.Platform == '__WXMSW__': - root = self.LibraryTree.AddRoot(_("Block Types")) - self.LibraryTree.SetPyData(root, {"type" : CATEGORY}) + to_delete = [] + blocktypes = self.Controler.GetBlockTypes() + root = self.LibraryTree.GetRootItem() + if not root.IsOk(): + if wx.Platform == '__WXMSW__': + root = self.LibraryTree.AddRoot(_("Block Types")) + self.LibraryTree.SetPyData(root, {"type" : CATEGORY}) + else: + root = self.LibraryTree.AddRoot("") + if wx.VERSION >= (2, 6, 0): + category_item, root_cookie = self.LibraryTree.GetFirstChild(root) + else: + category_item, root_cookie = self.LibraryTree.GetFirstChild(root, 0) + for category in blocktypes: + category_name = category["name"] + if not category_item.IsOk(): + category_item = self.LibraryTree.AppendItem(root, _(category_name)) + if wx.Platform != '__WXMSW__': + category_item, root_cookie = self.LibraryTree.GetNextChild(root, root_cookie) + else: + self.LibraryTree.SetItemText(category_item, _(category_name)) + self.LibraryTree.SetPyData(category_item, {"type" : CATEGORY}) + if wx.VERSION >= (2, 6, 0): + blocktype_item, category_cookie = self.LibraryTree.GetFirstChild(category_item) + else: + blocktype_item, category_cookie = self.LibraryTree.GetFirstChild(category_item, 0) + for blocktype in category["list"]: + if not blocktype_item.IsOk(): + blocktype_item = self.LibraryTree.AppendItem(category_item, blocktype["name"]) + if wx.Platform != '__WXMSW__': + blocktype_item, category_cookie = self.LibraryTree.GetNextChild(category_item, category_cookie) else: - root = self.LibraryTree.AddRoot("") - if wx.VERSION >= (2, 6, 0): - category_item, root_cookie = self.LibraryTree.GetFirstChild(root) - else: - category_item, root_cookie = self.LibraryTree.GetFirstChild(root, 0) - for category in blocktypes: - category_name = category["name"] - if not category_item.IsOk(): - category_item = self.LibraryTree.AppendItem(root, _(category_name)) - if wx.Platform != '__WXMSW__': - category_item, root_cookie = self.LibraryTree.GetNextChild(root, root_cookie) - else: - self.LibraryTree.SetItemText(category_item, _(category_name)) - self.LibraryTree.SetPyData(category_item, {"type" : CATEGORY}) - if wx.VERSION >= (2, 6, 0): - blocktype_item, category_cookie = self.LibraryTree.GetFirstChild(category_item) - else: - blocktype_item, category_cookie = self.LibraryTree.GetFirstChild(category_item, 0) - for blocktype in category["list"]: - if not blocktype_item.IsOk(): - blocktype_item = self.LibraryTree.AppendItem(category_item, blocktype["name"]) - if wx.Platform != '__WXMSW__': - blocktype_item, category_cookie = self.LibraryTree.GetNextChild(category_item, category_cookie) - else: - self.LibraryTree.SetItemText(blocktype_item, blocktype["name"]) - self.LibraryTree.SetPyData(blocktype_item, {"type" : BLOCK, "block_type" : blocktype["type"], "inputs" : tuple([type for name, type, modifier in blocktype["inputs"]])}) - blocktype_item, category_cookie = self.LibraryTree.GetNextChild(category_item, category_cookie) - while blocktype_item.IsOk(): - to_delete.append(blocktype_item) - blocktype_item, category_cookie = self.LibraryTree.GetNextChild(category_item, category_cookie) - category_item, root_cookie = self.LibraryTree.GetNextChild(root, root_cookie) - while category_item.IsOk(): - to_delete.append(category_item) - category_item, root_cookie = self.LibraryTree.GetNextChild(root, root_cookie) - for item in to_delete: - self.LibraryTree.Delete(item) - if wx.Platform == '__WXMSW__': - self.LibraryTree.Expand(root) + self.LibraryTree.SetItemText(blocktype_item, blocktype["name"]) + self.LibraryTree.SetPyData(blocktype_item, {"type" : BLOCK, "block_type" : blocktype["type"], "inputs" : tuple([type for name, type, modifier in blocktype["inputs"]])}) + blocktype_item, category_cookie = self.LibraryTree.GetNextChild(category_item, category_cookie) + while blocktype_item.IsOk(): + to_delete.append(blocktype_item) + blocktype_item, category_cookie = self.LibraryTree.GetNextChild(category_item, category_cookie) + category_item, root_cookie = self.LibraryTree.GetNextChild(root, root_cookie) + while category_item.IsOk(): + to_delete.append(category_item) + category_item, root_cookie = self.LibraryTree.GetNextChild(root, root_cookie) + for item in to_delete: + self.LibraryTree.Delete(item) + if wx.Platform == '__WXMSW__': + self.LibraryTree.Expand(root) def OnLibraryTreeItemSelected(self, event): selected = event.GetItem() pydata = self.LibraryTree.GetPyData(selected) if pydata is not None and pydata["type"] != CATEGORY: - blocktype = self.Controler.GetBlockType(self.LibraryTree.GetItemText(selected), pydata["inputs"], debug = self.Debug) + blocktype = self.Controler.GetBlockType(self.LibraryTree.GetItemText(selected), pydata["inputs"]) if blocktype: comment = blocktype["comment"] self.LibraryComment.SetValue(_(comment) + blocktype.get("usage", "")) @@ -2167,56 +1964,55 @@ #------------------------------------------------------------------------------- def ResetToolBar(self): - if not self.Debug: - for item in self.CurrentToolBar: - if wx.VERSION >= (2, 6, 0): - self.Unbind(wx.EVT_MENU, id=item) - else: - self.Disconnect(id=item, eventType=wx.wxEVT_COMMAND_MENU_SELECTED) - + for item in self.CurrentToolBar: + if wx.VERSION >= (2, 6, 0): + self.Unbind(wx.EVT_MENU, id=item) + else: + self.Disconnect(id=item, eventType=wx.wxEVT_COMMAND_MENU_SELECTED) + + if USE_AUI: + ToolBar = self.Panes["ToolBar"] + else: + ToolBar = self.ToolBar + if ToolBar: + ToolBar.DeleteTool(item) + ToolBar.Realize() if USE_AUI: - ToolBar = self.Panes["ToolBar"] - else: - ToolBar = self.ToolBar - if ToolBar: - ToolBar.DeleteTool(item) - ToolBar.Realize() - if USE_AUI: - self.AUIManager.GetPane("ToolBar").BestSize(ToolBar.GetBestSize()) - self.AUIManager.Update() + self.AUIManager.GetPane("ToolBar").BestSize(ToolBar.GetBestSize()) + self.AUIManager.Update() def RefreshToolBar(self): - if not self.Debug: - selected = self.TabsOpened.GetSelection() - if selected != -1: - language = self.Controler.GetEditedElementBodyType(self.TabsOpened.GetPage(selected).GetTagName(), self.Debug) + selected = self.TabsOpened.GetSelection() + language = None + if selected != -1: + window = self.TabsOpened.GetPage(selected) + if not window.IsDebugging(): + language = self.Controler.GetEditedElementBodyType(window.GetTagName()) + if language is not None and language != self.CurrentLanguage: + self.ResetToolBar() + self.CurrentLanguage = language + self.CurrentToolBar = [] + if USE_AUI: + ToolBar = self.Panes["ToolBar"] else: - language = None - if language is not None and language != self.CurrentLanguage: - self.ResetToolBar() - self.CurrentLanguage = language - self.CurrentToolBar = [] + ToolBar = self.ToolBar + if ToolBar: + for radio, modes, id, method, picture, help in ToolBarItems[language]: + if modes & self.DrawingMode: + if radio or self.DrawingMode == FREEDRAWING_MODE: + ToolBar.AddRadioTool(id, wx.Bitmap(os.path.join(CWD, "Images", picture)), wx.NullBitmap, help) + else: + ToolBar.AddSimpleTool(id, wx.Bitmap(os.path.join(CWD, "Images", picture)), help) + self.Bind(wx.EVT_TOOL, getattr(self, method), id=id) + self.CurrentToolBar.append(id) + ToolBar.Realize() if USE_AUI: - ToolBar = self.Panes["ToolBar"] - else: - ToolBar = self.ToolBar - if ToolBar: - for radio, modes, id, method, picture, help in ToolBarItems[language]: - if modes & self.DrawingMode: - if radio or self.DrawingMode == FREEDRAWING_MODE: - ToolBar.AddRadioTool(id, wx.Bitmap(os.path.join(CWD, "Images", picture)), wx.NullBitmap, help) - else: - ToolBar.AddSimpleTool(id, wx.Bitmap(os.path.join(CWD, "Images", picture)), help) - self.Bind(wx.EVT_TOOL, getattr(self, method), id=id) - self.CurrentToolBar.append(id) - ToolBar.Realize() - if USE_AUI: - self.AUIManager.GetPane("ToolBar").BestSize(ToolBar.GetBestSize()) - self.AUIManager.Update() - elif not language: - self.ResetToolBar() - self.CurrentLanguage = language - self.ResetCurrentMode() + self.AUIManager.GetPane("ToolBar").BestSize(ToolBar.GetBestSize()) + self.AUIManager.Update() + elif not language: + self.ResetToolBar() + self.CurrentLanguage = language + self.ResetCurrentMode() #------------------------------------------------------------------------------- @@ -2379,27 +2175,22 @@ def OnAddDataTypeMenu(self, event): dialog = DataTypeDialog(self, _("Add a new data type"), _("Please enter data type name"), "", wx.OK|wx.CANCEL) - dialog.SetDataTypeNames(self.Controler.GetProjectDataTypeNames(self.Debug)) + dialog.SetDataTypeNames(self.Controler.GetProjectDataTypeNames()) if dialog.ShowModal() == wx.ID_OK: self.Controler.ProjectAddDataType(dialog.GetValue()) - self.RefreshTitle() - self.RefreshEditMenu() - self.RefreshTypesTree() + self._Refresh(TITLE, EDITMENU, TYPESTREE) dialog.Destroy() event.Skip() def GenerateAddPouFunction(self, pou_type): def OnAddPouMenu(event): dialog = PouDialog(self, pou_type) - dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) - dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(debug = self.Debug)) + dialog.SetPouNames(self.Controler.GetProjectPouNames()) + dialog.SetPouElementNames(self.Controler.GetProjectPouVariables()) if dialog.ShowModal() == wx.ID_OK: values = dialog.GetValues() self.Controler.ProjectAddPou(values["pouName"], values["pouType"], values["language"]) - self.RefreshTitle() - self.RefreshEditMenu() - self.RefreshTypesTree() - self.RefreshLibraryTree() + self._Refresh(TITLE, EDITMENU, TYPESTREE, LIBRARYTREE) dialog.Destroy() event.Skip() return OnAddPouMenu @@ -2407,14 +2198,12 @@ def GenerateAddTransitionFunction(self, pou_name): def OnAddTransitionMenu(event): dialog = PouTransitionDialog(self) - dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) - dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(pou_name, self.Debug)) + dialog.SetPouNames(self.Controler.GetProjectPouNames()) + dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(pou_name)) if dialog.ShowModal() == wx.ID_OK: values = dialog.GetValues() self.Controler.ProjectAddPouTransition(pou_name, values["transitionName"], values["language"]) - self.RefreshTitle() - self.RefreshEditMenu() - self.RefreshTypesTree() + self._Refresh(TITLE, EDITMENU, TYPESTREE) dialog.Destroy() event.Skip() return OnAddTransitionMenu @@ -2422,44 +2211,36 @@ def GenerateAddActionFunction(self, pou_name): def OnAddActionMenu(event): dialog = PouActionDialog(self) - dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) - dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(pou_name, self.Debug)) + dialog.SetPouNames(self.Controler.GetProjectPouNames()) + dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(pou_name)) if dialog.ShowModal() == wx.ID_OK: values = dialog.GetValues() self.Controler.ProjectAddPouAction(pou_name, values["actionName"], values["language"]) - self.RefreshTitle() - self.RefreshEditMenu() - self.RefreshTypesTree() + self._Refresh(TITLE, EDITMENU, TYPESTREE) dialog.Destroy() event.Skip() return OnAddActionMenu def OnAddConfigurationMenu(self, event): dialog = ConfigurationNameDialog(self, _("Please enter configuration name"), _("Add new configuration")) - dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) - dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(debug = self.Debug)) + dialog.SetPouNames(self.Controler.GetProjectPouNames()) + dialog.SetPouElementNames(self.Controler.GetProjectPouVariables()) if dialog.ShowModal() == wx.ID_OK: value = dialog.GetValue() self.Controler.ProjectAddConfiguration(value) - self.RefreshTitle() - self.RefreshEditMenu() - self.RefreshTypesTree() - self.RefreshInstancesTree() + self._Refresh(TITLE, EDITMENU, TYPESTREE, INSTANCESTREE) dialog.Destroy() event.Skip() def GenerateAddResourceFunction(self, config_name): def OnAddResourceMenu(event): dialog = ResourceNameDialog(self, _("Please enter resource name"), _("Add new resource")) - dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) - dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(debug = self.Debug)) + dialog.SetPouNames(self.Controler.GetProjectPouNames()) + dialog.SetPouElementNames(self.Controler.GetProjectPouVariables()) if dialog.ShowModal() == wx.ID_OK: value = dialog.GetValue() self.Controler.ProjectAddConfigurationResource(config_name, value) - self.RefreshTitle() - self.RefreshEditMenu() - self.RefreshTypesTree() - self.RefreshInstancesTree() + self._Refresh(TITLE, EDITMENU, TYPESTREE, INSTANCESTREE) dialog.Destroy() event.Skip() return OnAddResourceMenu @@ -2469,11 +2250,7 @@ selected = self.TypesTree.GetSelection() if self.TypesTree.GetPyData(selected) == ITEM_POU: self.Controler.ProjectChangePouType(name, new_type) - self.RefreshTitle() - self.RefreshEditMenu() - self.RefreshTypesTree() - self.RefreshLibraryTree() - self.RefreshToolBar() + self._Refresh(TITLE, TOOLBAR, EDITMENU, TYPESTREE, LIBRARYTREE) event.Skip() return OnChangePouTypeMenu @@ -2481,14 +2258,10 @@ selected = self.TypesTree.GetSelection() if self.TypesTree.GetPyData(selected) == ITEM_POU: dialog = PouNameDialog(self, _("Please enter POU name"), _("Create a new POU from"), "", wx.OK|wx.CANCEL) - dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) + dialog.SetPouNames(self.Controler.GetProjectPouNames()) if dialog.ShowModal() == wx.ID_OK: self.Controler.ProjectCreatePouFrom(dialog.GetValue(), self.TypesTree.GetItemText(selected)) - self.RefreshTitle() - self.RefreshEditMenu() - self.RefreshTypesTree() - self.RefreshLibraryTree() - self.RefreshToolBar() + self._Refresh(TITLE, TOOLBAR, EDITMENU, TYPESTREE, LIBRARYTREE) event.Skip() def OnCopyPou(self, event): @@ -2530,20 +2303,15 @@ selected = self.TypesTree.GetSelection() if self.TypesTree.GetPyData(selected) == ITEM_DATATYPE: name = self.TypesTree.GetItemText(selected) - if not self.Controler.DataTypeIsUsed(name, self.Debug): + if not self.Controler.DataTypeIsUsed(name): self.Controler.ProjectRemoveDataType(name) tagname = self.Controler.ComputeDataTypeName(name) idx = self.IsOpened(tagname) if idx is not None: self.TabsOpened.DeletePage(idx) - self.RefreshTitle() - self.RefreshEditMenu() - self.RefreshTypesTree() - self.RefreshToolBar() + self._Refresh(TITLE, TOOLBAR, EDITMENU, TYPESTREE) else: - message = wx.MessageDialog(self, _("\"%s\" is used by one or more POUs. It can't be removed!")%name, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() + self.ShowErrorMessage(_("\"%s\" is used by one or more POUs. It can't be removed!")) event.Skip() def OnRenamePouMenu(self, event): @@ -2556,23 +2324,16 @@ selected = self.TypesTree.GetSelection() if self.TypesTree.GetPyData(selected) == ITEM_POU: name = self.TypesTree.GetItemText(selected) - if not self.Controler.PouIsUsed(name, self.Debug): + if not self.Controler.PouIsUsed(name): self.Controler.ProjectRemovePou(name) tagname = self.Controler.ComputePouName(name) idx = self.IsOpened(tagname) if idx is not None: self.VariablePanelIndexer.RemoveVariablePanel(tagname) self.TabsOpened.DeletePage(idx) - self.RefreshTitle() - self.RefreshEditMenu() - self.RefreshTypesTree() - self.RefreshInstancesTree() - self.RefreshLibraryTree() - self.RefreshToolBar() + self._Refresh(TITLE, TOOLBAR, EDITMENU, TYPESTREE, INSTANCESTREE, LIBRARYTREE) else: - message = wx.MessageDialog(self, _("\"%s\" is used by one or more POUs. It can't be removed!")%name, _("Error"), wx.OK|wx.ICON_ERROR) - message.ShowModal() - message.Destroy() + self.ShowErrorMessage(_("\"%s\" is used by one or more POUs. It can't be removed!")) event.Skip() def OnRemoveTransitionMenu(self, event): @@ -2591,9 +2352,7 @@ if idx is not None: self.VariablePanelIndexer.RemoveVariablePanel(tagname) self.TabsOpened.DeletePage(idx) - self.RefreshTitle() - self.RefreshEditMenu() - self.RefreshTypesTree() + self._Refresh(TITLE, EDITMENU, TYPESTREE) event.Skip() def OnRemoveActionMenu(self, event): @@ -2612,9 +2371,7 @@ if idx is not None: self.VariablePanelIndexer.RemoveVariablePanel(tagname) self.TabsOpened.DeletePage(idx) - self.RefreshTitle() - self.RefreshEditMenu() - self.RefreshTypesTree() + self._Refresh(TITLE, EDITMENU, TYPESTREE) event.Skip() def OnRemoveConfigurationMenu(self, event): @@ -2627,10 +2384,7 @@ if idx is not None: self.VariablePanelIndexer.RemoveVariablePanel(tagname) self.TabsOpened.DeletePage(idx) - self.RefreshTitle() - self.RefreshEditMenu() - self.RefreshTypesTree() - self.RefreshInstancesTree() + self._Refresh(TITLE, EDITMENU, TYPESTREE, INSTANCESTREE) event.Skip() def OnRemoveResourceMenu(self, event): @@ -2649,10 +2403,7 @@ if idx is not None: self.VariablePanelIndexer.RemoveVariablePanel(tagname) self.TabsOpened.DeletePage(idx) - self.RefreshTitle() - self.RefreshEditMenu() - self.RefreshTypesTree() - self.RefreshInstancesTree() + self._Refresh(TITLE, EDITMENU, TYPESTREE, INSTANCESTREE) event.Skip() def OnPLCOpenEditorMenu(self, event): @@ -2696,22 +2447,252 @@ viewer = self.TabsOpened.GetPage(i) viewer.ClearErrors() - RefreshFunctions = { - TITLE : RefreshTitle, - TOOLBAR : RefreshToolBar, - FILEMENU : RefreshFileMenu, - EDITMENU : RefreshEditMenu, - DISPLAYMENU : RefreshDisplayMenu, - TYPESTREE : RefreshTypesTree, - INSTANCESTREE : RefreshInstancesTree, - LIBRARYTREE : RefreshLibraryTree, - SCALING : RefreshScaling} - -current_num = 0 -def GetNewNum(): - global current_num - current_num += 1 - return current_num +#------------------------------------------------------------------------------- +# PLCOpenEditor Main Class +#------------------------------------------------------------------------------- + +class PLCOpenEditor(IDEFrame): + + # Compatibility function for wx versions < 2.6 + 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_FileMenu_Items(self, parent): + AppendMenu(parent, help='', id=wx.ID_NEW, + kind=wx.ITEM_NORMAL, text=_(u'New\tCTRL+N')) + AppendMenu(parent, help='', id=wx.ID_OPEN, + kind=wx.ITEM_NORMAL, text=_(u'Open\tCTRL+O')) + AppendMenu(parent, help='', id=wx.ID_CLOSE, + kind=wx.ITEM_NORMAL, text=_(u'Close Tab\tCTRL+W')) + AppendMenu(parent, help='', id=wx.ID_CLOSE_ALL, + kind=wx.ITEM_NORMAL, text=_(u'Close Project')) + parent.AppendSeparator() + AppendMenu(parent, help='', id=wx.ID_SAVE, + kind=wx.ITEM_NORMAL, text=_(u'Save\tCTRL+S')) + AppendMenu(parent, help='', id=wx.ID_SAVEAS, + kind=wx.ITEM_NORMAL, text=_(u'Save As...\tCTRL+SHIFT+S')) + AppendMenu(parent, help='', id=ID_PLCOPENEDITORFILEMENUGENERATE, + kind=wx.ITEM_NORMAL, text=_(u'Generate Program\tCTRL+G')) + parent.AppendSeparator() + AppendMenu(parent, help='', id=wx.ID_PAGE_SETUP, + kind=wx.ITEM_NORMAL, text=_(u'Page Setup')) + AppendMenu(parent, help='', id=wx.ID_PREVIEW, + kind=wx.ITEM_NORMAL, text=_(u'Preview')) + AppendMenu(parent, help='', id=wx.ID_PRINT, + kind=wx.ITEM_NORMAL, text=_(u'Print')) + parent.AppendSeparator() + AppendMenu(parent, help='', id=wx.ID_PROPERTIES, + kind=wx.ITEM_NORMAL, text=_(u'Properties')) + parent.AppendSeparator() + AppendMenu(parent, help='', id=wx.ID_EXIT, + kind=wx.ITEM_NORMAL, text=_(u'Quit\tCTRL+Q')) + + self.Bind(wx.EVT_MENU, self.OnNewProjectMenu, id=wx.ID_NEW) + self.Bind(wx.EVT_MENU, self.OnOpenProjectMenu, id=wx.ID_OPEN) + self.Bind(wx.EVT_MENU, self.OnCloseTabMenu, id=wx.ID_CLOSE) + self.Bind(wx.EVT_MENU, self.OnCloseProjectMenu, id=wx.ID_CLOSE_ALL) + self.Bind(wx.EVT_MENU, self.OnSaveProjectMenu, id=wx.ID_SAVE) + self.Bind(wx.EVT_MENU, self.OnSaveProjectAsMenu, id=wx.ID_SAVEAS) + self.Bind(wx.EVT_MENU, self.OnGenerateProgramMenu, + id=ID_PLCOPENEDITORFILEMENUGENERATE) + self.Bind(wx.EVT_MENU, self.OnPageSetupMenu, id=wx.ID_PAGE_SETUP) + self.Bind(wx.EVT_MENU, self.OnPreviewMenu, id=wx.ID_PREVIEW) + self.Bind(wx.EVT_MENU, self.OnPrintMenu, id=wx.ID_PRINT) + self.Bind(wx.EVT_MENU, self.OnPropertiesMenu, id=wx.ID_PROPERTIES) + self.Bind(wx.EVT_MENU, self.OnQuitMenu, id=wx.ID_EXIT) + + def _init_coll_HelpMenu_Items(self, parent): + AppendMenu(parent, help='', id=wx.ID_HELP, + kind=wx.ITEM_NORMAL, text=_(u'PLCOpenEditor\tF1')) + #AppendMenu(parent, help='', id=wx.ID_HELP_CONTENTS, + # kind=wx.ITEM_NORMAL, text=u'PLCOpen\tF2') + #AppendMenu(parent, help='', id=wx.ID_HELP_CONTEXT, + # kind=wx.ITEM_NORMAL, text=u'IEC 61131-3\tF3') + AppendMenu(parent, help='', id=wx.ID_ABOUT, + kind=wx.ITEM_NORMAL, text=_(u'About')) + self.Bind(wx.EVT_MENU, self.OnPLCOpenEditorMenu, id=wx.ID_HELP) + #self.Bind(wx.EVT_MENU, self.OnPLCOpenMenu, id=wx.ID_HELP_CONTENTS) + self.Bind(wx.EVT_MENU, self.OnAboutMenu, id=wx.ID_ABOUT) + + ## Constructor of the PLCOpenEditor class. + # @param parent The parent window. + # @param controler The controler been used by PLCOpenEditor (default: None). + # @param fileOpen The filepath to open if no controler defined (default: None). + # @param debug The filepath to open if no controler defined (default: False). + def __init__(self, parent, fileOpen = None): + IDEFrame.__init__(self, parent) + + # Open the filepath if defined + if fileOpen is not None: + # Create a new controller + self.Controler = PLCControler() + self.Controler.OpenXMLFile(fileOpen) + self._Refresh(TYPESTREE, INSTANCESTREE, LIBRARYTREE) + + # Define PLCOpenEditor icon + self.SetIcon(wx.Icon(os.path.join(CWD,"Images", "poe.ico"),wx.BITMAP_TYPE_ICO)) + + self.Bind(wx.EVT_CLOSE, self.OnCloseFrame) + + self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU) + + def OnCloseFrame(self, event): + if self.Controler is None or self.CheckSaveBeforeClosing(): + if USE_AUI: + self.AUIManager.UnInit() + event.Skip() + else: + event.Veto() + + def RefreshTitle(self): + name = _("PLCOpenEditor") + if self.Controler is not None: + self.SetTitle("%s - %s"%(name, self.Controler.GetFilename())) + else: + self.SetTitle(name) + +#------------------------------------------------------------------------------- +# File Menu Functions +#------------------------------------------------------------------------------- + + def RefreshFileMenu(self): + if self.Controler is not None: + selected = self.TabsOpened.GetSelection() + if selected >= 0: + graphic_viewer = isinstance(self.TabsOpened.GetPage(selected), Viewer) + else: + graphic_viewer = False + if self.TabsOpened.GetPageCount() > 0: + self.FileMenu.Enable(wx.ID_CLOSE, True) + if graphic_viewer: + self.FileMenu.Enable(wx.ID_PREVIEW, True) + self.FileMenu.Enable(wx.ID_PRINT, True) + else: + self.FileMenu.Enable(wx.ID_PREVIEW, False) + self.FileMenu.Enable(wx.ID_PRINT, False) + else: + self.FileMenu.Enable(wx.ID_CLOSE, False) + self.FileMenu.Enable(wx.ID_PREVIEW, False) + self.FileMenu.Enable(wx.ID_PRINT, False) + self.FileMenu.Enable(wx.ID_PAGE_SETUP, True) + self.FileMenu.Enable(wx.ID_SAVE, True) + self.FileMenu.Enable(wx.ID_PROPERTIES, True) + self.FileMenu.Enable(wx.ID_CLOSE_ALL, True) + self.FileMenu.Enable(wx.ID_SAVEAS, True) + self.FileMenu.Enable(ID_PLCOPENEDITORFILEMENUGENERATE, True) + else: + self.FileMenu.Enable(wx.ID_CLOSE, False) + self.FileMenu.Enable(wx.ID_PAGE_SETUP, False) + self.FileMenu.Enable(wx.ID_PREVIEW, False) + self.FileMenu.Enable(wx.ID_PRINT, False) + self.FileMenu.Enable(wx.ID_SAVE, False) + self.FileMenu.Enable(wx.ID_PROPERTIES, False) + self.FileMenu.Enable(wx.ID_CLOSE_ALL, False) + self.FileMenu.Enable(wx.ID_SAVEAS, False) + self.FileMenu.Enable(ID_PLCOPENEDITORFILEMENUGENERATE, False) + + def OnNewProjectMenu(self, event): + if self.Controler is not None and not self.CheckSaveBeforeClosing(): + return + dialog = ProjectDialog(self) + if dialog.ShowModal() == wx.ID_OK: + properties = dialog.GetValues() + self.ResetView() + self.Controler = PLCControler() + self.Controler.CreateNewProject(properties) + self._Refresh(TITLE, FILEMENU, EDITMENU, TYPESTREE, INSTANCESTREE, + LIBRARYTREE) + event.Skip() + + def OnOpenProjectMenu(self, event): + if self.Controler is not None and not self.CheckSaveBeforeClosing(): + return + filepath = "" + if self.Controler is not None: + filepath = self.Controler.GetFilePath() + if filepath != "": + directory = os.path.dirname(filepath) + else: + directory = os.getcwd() + dialog = wx.FileDialog(self, _("Choose a file"), directory, "", _("PLCOpen files (*.xml)|*.xml|All files|*.*"), wx.OPEN) + if dialog.ShowModal() == wx.ID_OK: + filepath = dialog.GetPath() + if os.path.isfile(filepath): + self.ResetView() + self.Controler = PLCControler() + self.Controler.OpenXMLFile(filepath) + self._Refresh(TYPESTREE, INSTANCESTREE, LIBRARYTREE) + self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU) + dialog.Destroy() + event.Skip() + + def OnCloseProjectMenu(self, event): + if not self.CheckSaveBeforeClosing(): + return + self.ResetView() + self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU) + event.Skip() + + def OnSaveProjectMenu(self, event): + self.SaveProject() + event.Skip() + + def OnSaveProjectAsMenu(self, event): + self.SaveProjectAs() + event.Skip() + + def OnGenerateProgramMenu(self, event): + dialog = wx.FileDialog(self, _("Choose a file"), os.getcwd(), self.Controler.GetProgramFilePath(), _("ST files (*.st)|*.st|All files|*.*"), wx.SAVE|wx.CHANGE_DIR) + if dialog.ShowModal() == wx.ID_OK: + filepath = dialog.GetPath() + message_text = "" + header, icon = _("Done"), wx.ICON_INFORMATION + if os.path.isdir(os.path.dirname(filepath)): + program, errors, warnings = self.Controler.GenerateProgram(filepath) + message_text += "".join([_("warning: %s\n") for warning in warnings]) + if len(errors) > 0: + message_text += "".join([_("error: %s\n") for warning in warnings]) + message_text += _("Can't generate program to file %s!")%filepath + header, icon = _("Error"), wx.ICON_ERROR + else: + message_text += _("Program was successfully generated!") + else: + message_text += _("\"%s\" is not a valid folder!")%os.path.dirname(filepath) + header, icon = _("Error"), wx.ICON_ERROR + message = wx.MessageDialog(self, message_text, header, wx.OK|icon) + message.ShowModal() + message.Destroy() + dialog.Destroy() + event.Skip() + + def SaveProject(self): + result = self.Controler.SaveXMLFile() + if not result: + self.SaveProjectAs() + else: + self.RefreshTitle() + + def SaveProjectAs(self): + filepath = self.Controler.GetFilePath() + if filepath != "": + directory, filename = os.path.split(filepath) + else: + directory, filename = os.getcwd(), "%(projectName)s.xml"%self.Controler.GetProjectProperties() + dialog = wx.FileDialog(self, _("Choose a file"), directory, filename, _("PLCOpen files (*.xml)|*.xml|All files|*.*"), wx.SAVE|wx.OVERWRITE_PROMPT) + if dialog.ShowModal() == wx.ID_OK: + filepath = dialog.GetPath() + if os.path.isdir(os.path.dirname(filepath)): + result = self.Controler.SaveXMLFile(filepath) + if not result: + self.ShowErrorMessage(_("Can't save project to file %s!")%filepath) + else: + self.ShowErrorMessage(_("\"%s\" is not a valid folder!")%os.path.dirname(filepath)) + self.RefreshTitle() + dialog.Destroy() #------------------------------------------------------------------------------- # Create Project Dialog @@ -3828,17 +3809,16 @@ self._init_sizers() - def __init__(self, parent, window, controler): + def __init__(self, parent, window): self._init_ctrls(parent) self.ParentWindow = window - self.Controler = controler self.VariablePanelList = {} self.CurrentPanel = None def AddVariablePanel(self, tagname, element_type): - new_panel = VariablePanel(self, self.ParentWindow, self.Controler, element_type) + new_panel = VariablePanel(self, self.ParentWindow, self.ParentWindow.Controler, element_type) new_panel.SetTagName(tagname) new_panel.Hide() new_panel.RefreshView() @@ -3892,6 +3872,8 @@ panel.ClearErrors() #------------------------------------------------------------------------------- + grid.SetRowMinimalHeight(row, 28) + grid.AutoSizeRow(row, False) # Debug Variables Panel #------------------------------------------------------------------------------- @@ -4147,7 +4129,7 @@ self.DeleteButton = wx.Button(id=ID_DEBUGVARIABLEPANELDELETEBUTTON, label=_('Delete'), name='DeleteButton', parent=self, pos=wx.Point(0, 0), - size=wx.Size(72, 32), style=0) + size=wx.DefaultSize, style=0) self.Bind(wx.EVT_BUTTON, self.OnDeleteButton, id=ID_DEBUGVARIABLEPANELDELETEBUTTON) self._init_sizers() @@ -4180,6 +4162,13 @@ self.Table.ResetView(self.VariablesGrid) self.Thaw() + def ResetGrid(self): + self.DeleteDataConsumers() + self.Table.Empty() + self.Freeze() + self.Table.ResetView(self.VariablesGrid) + self.Thaw() + def OnDeleteButton(self, event): idx = self.VariablesGrid.GetGridCursorRow() item = self.Table.GetItem(idx) diff -r f4c0e9c9b3b9 -r 26bc7d5d4264 RessourceEditor.py --- a/RessourceEditor.py Mon Sep 21 10:31:38 2009 -0600 +++ b/RessourceEditor.py Tue Sep 22 09:56:52 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 f4c0e9c9b3b9 -r 26bc7d5d4264 SFCViewer.py --- a/SFCViewer.py Mon Sep 21 10:31:38 2009 -0600 +++ b/SFCViewer.py Tue Sep 22 09:56:52 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 f4c0e9c9b3b9 -r 26bc7d5d4264 TextViewer.py --- a/TextViewer.py Mon Sep 21 10:31:38 2009 -0600 +++ b/TextViewer.py Tue Sep 22 09:56:52 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): @@ -503,7 +509,6 @@ self.AutoCompSetIgnoreCase(True) self.AutoCompShow(len(words[-1]), " ".join(kw)) else: - wx.CallAfter(self.RefreshModel) event.Skip() def OnKillFocus(self, event): diff -r f4c0e9c9b3b9 -r 26bc7d5d4264 VariablePanel.py --- a/VariablePanel.py Mon Sep 21 10:31:38 2009 -0600 +++ b/VariablePanel.py Tue Sep 22 09:56:52 2009 +0200 @@ -25,8 +25,18 @@ from types import TupleType -from PLCOpenEditor import AppendMenu from plcopen.structures import LOCATIONDATATYPES, TestIdentifier, IEC_KEYWORDS + +# 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 @@ -556,29 +566,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 +601,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 +673,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 +703,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 +717,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 +730,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 +739,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,10 +772,7 @@ self.SaveValues(False) self.ParentWindow.RefreshEditor(variablepanel = False) self.Controler.BufferProject() - self.ParentWindow.RefreshTitle() - self.ParentWindow.RefreshEditMenu() - self.ParentWindow.RefreshInstancesTree() - self.ParentWindow.RefreshLibraryTree() + self.ParentWindow._Refresh(TITLE, EDITMENU, INSTANCESTREE, LIBRARYTREE) event.Skip() return VariableTypeFunction @@ -839,10 +839,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): @@ -867,22 +864,22 @@ self.VarPanel = var_panel self.Row = -1 - self.Bind(wx.EVT_SIZE, self.OnSize) + self.Bind(wx.EVT_SIZE, self.OnSize) # create text control - self.txt = wx.TextCtrl(self, -1, '') + self.txt = wx.TextCtrl(self, -1, '', size=wx.Size(0, 0)) # create browse button - self.btn = wx.Button(self, -1, '...', size=(20,20)) + self.btn = wx.Button(self, -1, label='...', size=wx.Size(30, 0)) 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) - self.Layout() + self.Sizer = wx.FlexGridSizer(cols=2, hgap=0, rows=1, vgap=0) + self.Sizer.AddWindow(self.txt, 0, border=0, flag=wx.ALL|wx.GROW) + self.Sizer.AddWindow(self.btn, 0, border=0, flag=wx.ALL|wx.GROW) + self.Sizer.AddGrowableCol(0) + self.Sizer.AddGrowableRow(0) + + self.SetSizer(self.Sizer) def SetRow(self, row): '''set the grid row that we're working on''' @@ -890,12 +887,13 @@ 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) + #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) + self.Layout() def OnBtnBrowseClick(self, event): # pop up the location browser dialog @@ -964,9 +962,8 @@ return True 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.text_browse.SetDimensions(rect.x + 1, rect.y, + rect.width, rect.height, wx.SIZE_ALLOW_MINUS_ONE) def Clone(self): @@ -1042,7 +1039,7 @@ # add plugins to the tree root = self.tree.AddRoot(_('Plugins')) ctrl = self.VarPanel.Controler - self.AddChildPluginsToTree(ctrl.PluginsRoot, root) + self.AddChildPluginsToTree(ctrl, root) # -- buttons -- diff -r f4c0e9c9b3b9 -r 26bc7d5d4264 Viewer.py --- a/Viewer.py Mon Sep 21 10:31:38 2009 -0600 +++ b/Viewer.py Tue Sep 22 09:56:52 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 @@ -452,7 +453,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) @@ -1716,7 +1717,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 +1747,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 +1778,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 +1896,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 +1931,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 +1951,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 +2018,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 +2060,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 +2100,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 +2206,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 +2243,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 +2826,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 f4c0e9c9b3b9 -r 26bc7d5d4264 dialogs/ActionBlockDialog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/ActionBlockDialog.py Tue Sep 22 09:56:52 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 f4c0e9c9b3b9 -r 26bc7d5d4264 dialogs/ConnectionDialog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/ConnectionDialog.py Tue Sep 22 09:56:52 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 f4c0e9c9b3b9 -r 26bc7d5d4264 dialogs/FBDBlockDialog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/FBDBlockDialog.py Tue Sep 22 09:56:52 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 f4c0e9c9b3b9 -r 26bc7d5d4264 dialogs/FBDVariableDialog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/FBDVariableDialog.py Tue Sep 22 09:56:52 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 f4c0e9c9b3b9 -r 26bc7d5d4264 dialogs/LDElementDialog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/LDElementDialog.py Tue Sep 22 09:56:52 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 f4c0e9c9b3b9 -r 26bc7d5d4264 dialogs/LDPowerRailDialog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/LDPowerRailDialog.py Tue Sep 22 09:56:52 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 f4c0e9c9b3b9 -r 26bc7d5d4264 dialogs/PouNameDialog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/PouNameDialog.py Tue Sep 22 09:56:52 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 f4c0e9c9b3b9 -r 26bc7d5d4264 dialogs/SFCDivergenceDialog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/SFCDivergenceDialog.py Tue Sep 22 09:56:52 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 f4c0e9c9b3b9 -r 26bc7d5d4264 dialogs/SFCStepDialog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/SFCStepDialog.py Tue Sep 22 09:56:52 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 f4c0e9c9b3b9 -r 26bc7d5d4264 dialogs/SFCStepNameDialog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/SFCStepNameDialog.py Tue Sep 22 09:56:52 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 f4c0e9c9b3b9 -r 26bc7d5d4264 dialogs/SFCTransitionDialog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/SFCTransitionDialog.py Tue Sep 22 09:56:52 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 f4c0e9c9b3b9 -r 26bc7d5d4264 dialogs/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/__init__.py Tue Sep 22 09:56:52 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 f4c0e9c9b3b9 -r 26bc7d5d4264 examples/example.xml --- a/examples/example.xml Mon Sep 21 10:31:38 2009 -0600 +++ b/examples/example.xml Tue Sep 22 09:56:52 2009 +0200 @@ -12,7 +12,7 @@ contentDescription="Example of PLCOpenEditor usage"/> @@ -527,12 +527,14 @@ + + + + + + + - - - - - diff -r f4c0e9c9b3b9 -r 26bc7d5d4264 generate_IEC_std.py --- a/generate_IEC_std.py Mon Sep 21 10:31:38 2009 -0600 +++ b/generate_IEC_std.py Tue Sep 22 09:56:52 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 f4c0e9c9b3b9 -r 26bc7d5d4264 graphics/GraphicCommons.py --- a/graphics/GraphicCommons.py Mon Sep 21 10:31:38 2009 -0600 +++ b/graphics/GraphicCommons.py Tue Sep 22 09:56:52 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 f4c0e9c9b3b9 -r 26bc7d5d4264 i18n/app.fil --- a/i18n/app.fil Mon Sep 21 10:31:38 2009 -0600 +++ b/i18n/app.fil Tue Sep 22 09:56:52 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 f4c0e9c9b3b9 -r 26bc7d5d4264 plcopen/iec_std.csv --- a/plcopen/iec_std.csv Mon Sep 21 10:31:38 2009 -0600 +++ b/plcopen/iec_std.csv Tue Sep 22 09:56:52 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 f4c0e9c9b3b9 -r 26bc7d5d4264 plcopen/structures.py --- a/plcopen/structures.py Mon Sep 21 10:31:38 2009 -0600 +++ b/plcopen/structures.py Tue Sep 22 09:56:52 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