etisserant@0: #!/usr/bin/env python etisserant@0: # -*- coding: utf-8 -*- etisserant@0: etisserant@0: #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor etisserant@0: #based on the plcopen standard. etisserant@0: # lbessard@58: #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD etisserant@0: # etisserant@0: #See COPYING file for copyrights details. etisserant@0: # etisserant@0: #This library is free software; you can redistribute it and/or etisserant@5: #modify it under the terms of the GNU General Public etisserant@0: #License as published by the Free Software Foundation; either etisserant@0: #version 2.1 of the License, or (at your option) any later version. etisserant@0: # etisserant@0: #This library is distributed in the hope that it will be useful, etisserant@0: #but WITHOUT ANY WARRANTY; without even the implied warranty of etisserant@0: #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU lbessard@58: #General Public License for more details. etisserant@0: # etisserant@5: #You should have received a copy of the GNU General Public etisserant@0: #License along with this library; if not, write to the Free Software etisserant@0: #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA etisserant@0: etisserant@0: from datetime import datetime lbessard@120: import wx, wx.grid lbessard@120: lbessard@120: if wx.VERSION >= (2, 8, 0): lbessard@120: import wx.aui lbessard@292: USE_AUI = True lbessard@292: else: lbessard@292: USE_AUI = False etisserant@0: etisserant@0: from SFCViewer import * etisserant@0: from LDViewer import * etisserant@0: from Viewer import * lbessard@27: from TextViewer import * lbessard@27: from RessourceEditor import * lbessard@125: from DataTypeEditor import * etisserant@0: from PLCControler import * lbessard@107: from plcopen.structures import LOCATIONDATATYPES etisserant@0: etisserant@0: import os, re, platform, sys, time, traceback, getopt etisserant@0: greg@190: base_folder = os.path.split(sys.path[0])[0] greg@190: sys.path.append(base_folder) greg@190: from docutils import * greg@190: lbessard@218: from types import TupleType lbessard@218: etisserant@0: __version__ = "$Revision$" etisserant@0: lbessard@125: CWD = os.path.split(os.path.realpath(__file__))[0] etisserant@0: lbessard@235: [ID_PLCOPENEDITOR, ID_PLCOPENEDITORTREENOTEBOOK, lbessard@235: ID_PLCOPENEDITORTYPESTREE, ID_PLCOPENEDITORINSTANCESTREE, lbessard@121: ID_PLCOPENEDITORMAINSPLITTER, ID_PLCOPENEDITORSECONDSPLITTER, lbessard@239: ID_PLCOPENEDITORTHIRDSPLITTER, ID_PLCOPENEDITORLIBRARYPANEL, lbessard@239: ID_PLCOPENEDITORLIBRARYTREE, ID_PLCOPENEDITORLIBRARYCOMMENT, lbessard@239: ID_PLCOPENEDITORTABSOPENED, ID_PLCOPENEDITORTABSOPENED, lbessard@121: ID_PLCOPENEDITORTOOLBAR, ID_PLCOPENEDITORDEFAULTTOOLBAR, lbessard@121: ID_PLCOPENEDITORSFCTOOLBAR, ID_PLCOPENEDITORFBDTOOLBAR, lbessard@121: ID_PLCOPENEDITORLDTOOLBAR, lbessard@239: ] = [wx.NewId() for _init_ctrls in range(17)] lbessard@6: lbessard@185: [ID_PLCOPENEDITORFILEMENUGENERATE, lbessard@185: ] = [wx.NewId() for _init_coll_FileMenu_Items in range(1)] lbessard@185: lbessard@185: [ID_PLCOPENEDITOREDITMENUADDDATATYPE, ID_PLCOPENEDITOREDITMENUADDFUNCTION, lbessard@185: ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK, ID_PLCOPENEDITOREDITMENUADDPROGRAM, lbessard@185: ID_PLCOPENEDITOREDITMENUADDCONFIGURATION, lbessard@185: ] = [wx.NewId() for _init_coll_EditMenu_Items in range(5)] etisserant@0: lbessard@27: lbessard@27: #------------------------------------------------------------------------------- lbessard@27: # ToolBars definitions lbessard@27: #------------------------------------------------------------------------------- lbessard@27: lbessard@27: lbessard@64: [ID_PLCOPENEDITORTOOLBARSELECTION, ID_PLCOPENEDITORTOOLBARCOMMENT, lbessard@64: ID_PLCOPENEDITORTOOLBARVARIABLE, ID_PLCOPENEDITORTOOLBARBLOCK, lbessard@64: ID_PLCOPENEDITORTOOLBARCONNECTION, ID_PLCOPENEDITORTOOLBARWIRE, lbessard@64: ID_PLCOPENEDITORTOOLBARPOWERRAIL, ID_PLCOPENEDITORTOOLBARRUNG, lbessard@64: ID_PLCOPENEDITORTOOLBARCOIL, ID_PLCOPENEDITORTOOLBARCONTACT, lbessard@64: ID_PLCOPENEDITORTOOLBARBRANCH, ID_PLCOPENEDITORTOOLBARINITIALSTEP, lbessard@64: ID_PLCOPENEDITORTOOLBARSTEP, ID_PLCOPENEDITORTOOLBARTRANSITION, lbessard@64: ID_PLCOPENEDITORTOOLBARACTIONBLOCK, ID_PLCOPENEDITORTOOLBARDIVERGENCE, lbessard@64: ID_PLCOPENEDITORTOOLBARJUMP, lbessard@27: ] = [wx.NewId() for _init_coll_DefaultToolBar_Items in range(17)] lbessard@27: lbessard@27: ToolBarItems = { etisserant@184: "FBD" : [(True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, etisserant@184: ID_PLCOPENEDITORTOOLBARCOMMENT, "OnCommentTool", etisserant@184: "add_comment.png", "Create a new comment"), etisserant@184: (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, etisserant@184: ID_PLCOPENEDITORTOOLBARVARIABLE, "OnVariableTool", etisserant@184: "add_variable.png", "Create a new variable"), etisserant@184: (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, etisserant@184: ID_PLCOPENEDITORTOOLBARBLOCK, "OnBlockTool", etisserant@184: "add_block.png", "Create a new block"), etisserant@184: (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, etisserant@184: ID_PLCOPENEDITORTOOLBARCONNECTION, "OnConnectionTool", etisserant@184: "add_connection.png", "Create a new connection")], etisserant@184: "LD" : [(True, FREEDRAWING_MODE, etisserant@184: ID_PLCOPENEDITORTOOLBARCOMMENT, "OnCommentTool", etisserant@184: "add_comment.png", "Create a new comment"), etisserant@184: (True, FREEDRAWING_MODE, etisserant@184: ID_PLCOPENEDITORTOOLBARPOWERRAIL, "OnPowerRailTool", etisserant@184: "add_powerrail.png", "Create a new power rail"), etisserant@184: (False, DRIVENDRAWING_MODE, etisserant@184: ID_PLCOPENEDITORTOOLBARRUNG, "OnRungTool", etisserant@184: "add_rung.png", "Create a new rung"), etisserant@184: (True, FREEDRAWING_MODE, etisserant@184: ID_PLCOPENEDITORTOOLBARCOIL, "OnCoilTool", etisserant@184: "add_coil.png", "Create a new coil"), etisserant@184: (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, etisserant@184: ID_PLCOPENEDITORTOOLBARCONTACT, "OnContactTool", etisserant@184: "add_contact.png", "Create a new contact"), etisserant@184: (False, DRIVENDRAWING_MODE, etisserant@184: ID_PLCOPENEDITORTOOLBARBRANCH, "OnBranchTool", etisserant@184: "add_branch.png", "Create a new branch"), etisserant@184: (True, FREEDRAWING_MODE, etisserant@184: ID_PLCOPENEDITORTOOLBARVARIABLE, "OnVariableTool", etisserant@184: "add_variable.png", "Create a new variable"), etisserant@184: (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, etisserant@184: ID_PLCOPENEDITORTOOLBARBLOCK, "OnBlockTool", etisserant@184: "add_block.png", "Create a new block"), etisserant@184: (True, FREEDRAWING_MODE, etisserant@184: ID_PLCOPENEDITORTOOLBARCONNECTION, "OnConnectionTool", etisserant@184: "add_connection.png", "Create a new connection")], etisserant@184: "SFC" : [(True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, etisserant@184: ID_PLCOPENEDITORTOOLBARCOMMENT, "OnCommentTool", etisserant@184: "add_comment.png", "Create a new comment"), etisserant@184: (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, etisserant@184: ID_PLCOPENEDITORTOOLBARINITIALSTEP, "OnInitialStepTool", etisserant@184: "add_initial_step.png", "Create a new initial step"), etisserant@184: (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, etisserant@184: ID_PLCOPENEDITORTOOLBARSTEP, "OnStepTool", etisserant@184: "add_step.png", "Create a new step"), etisserant@184: (True, FREEDRAWING_MODE, etisserant@184: ID_PLCOPENEDITORTOOLBARTRANSITION, "OnTransitionTool", etisserant@184: "add_transition.png", "Create a new transition"), etisserant@184: (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, etisserant@184: ID_PLCOPENEDITORTOOLBARACTIONBLOCK, "OnActionBlockTool", etisserant@184: "add_action.png", "Create a new action block"), etisserant@184: (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, etisserant@184: ID_PLCOPENEDITORTOOLBARDIVERGENCE, "OnDivergenceTool", etisserant@184: "add_divergence.png", "Create a new divergence"), etisserant@184: (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, etisserant@184: ID_PLCOPENEDITORTOOLBARJUMP, "OnJumpTool", etisserant@184: "add_jump.png", "Create a new jump"), etisserant@184: (True, FREEDRAWING_MODE, etisserant@184: ID_PLCOPENEDITORTOOLBARVARIABLE, "OnVariableTool", etisserant@184: "add_variable.png", "Create a new variable"), etisserant@184: (True, FREEDRAWING_MODE, etisserant@184: ID_PLCOPENEDITORTOOLBARBLOCK, "OnBlockTool", etisserant@184: "add_block.png", "Create a new block"), etisserant@184: (True, FREEDRAWING_MODE, etisserant@184: ID_PLCOPENEDITORTOOLBARCONNECTION, "OnConnectionTool", etisserant@184: "add_connection.png", "Create a new connection"), etisserant@184: (True, FREEDRAWING_MODE, etisserant@184: ID_PLCOPENEDITORTOOLBARPOWERRAIL, "OnPowerRailTool", etisserant@184: "add_powerrail.png", "Create a new power rail"), etisserant@184: (True, FREEDRAWING_MODE, etisserant@184: ID_PLCOPENEDITORTOOLBARCONTACT, "OnContactTool", etisserant@184: "add_contact.png", "Create a new contact")], lbessard@82: "ST" : [], lbessard@82: "IL" : [] lbessard@27: } lbessard@27: lbessard@114: def AppendMenu(parent, help, id, kind, text): lbessard@114: if wx.VERSION >= (2, 6, 0): lbessard@114: parent.Append(help=help, id=id, kind=kind, text=text) lbessard@114: else: lbessard@114: parent.Append(helpString=help, id=id, kind=kind, item=text) lbessard@114: lbessard@235: class PLCOpenEditor(wx.Frame): etisserant@0: lbessard@163: CopyBuffer = None lbessard@163: lbessard@114: if wx.VERSION < (2, 6, 0): lbessard@114: def Bind(self, event, function, id = None): lbessard@114: if id is not None: lbessard@114: event(self, id, function) lbessard@114: else: lbessard@114: event(self, function) lbessard@114: lbessard@185: def _init_coll_MenuBar_Menus(self, parent): etisserant@220: parent.Append(menu=self.FileMenu, title=u'File') etisserant@0: parent.Append(menu=self.EditMenu, title=u'Edit') etisserant@0: parent.Append(menu=self.HelpMenu, title=u'Help') etisserant@0: lbessard@185: def _init_coll_FileMenu_Items(self, parent): etisserant@220: if self.ModeSolo: etisserant@220: AppendMenu(parent, help='', id=wx.ID_NEW, etisserant@220: kind=wx.ITEM_NORMAL, text=u'New\tCTRL+N') etisserant@220: AppendMenu(parent, help='', id=wx.ID_OPEN, etisserant@220: kind=wx.ITEM_NORMAL, text=u'Open\tCTRL+O') lbessard@185: AppendMenu(parent, help='', id=wx.ID_CLOSE, lbessard@185: kind=wx.ITEM_NORMAL, text=u'Close Tab\tCTRL+W') etisserant@220: if self.ModeSolo: etisserant@220: AppendMenu(parent, help='', id=wx.ID_CLOSE_ALL, etisserant@220: kind=wx.ITEM_NORMAL, text=u'Close Project') etisserant@220: parent.AppendSeparator() lbessard@249: if not self.Debug: lbessard@249: AppendMenu(parent, help='', id=wx.ID_SAVE, lbessard@249: kind=wx.ITEM_NORMAL, text=u'Save\tCTRL+S') etisserant@220: if self.ModeSolo: etisserant@220: AppendMenu(parent, help='', id=wx.ID_SAVEAS, etisserant@220: kind=wx.ITEM_NORMAL, text=u'Save As...\tCTRL+SHIFT+S') etisserant@220: AppendMenu(parent, help='', id=ID_PLCOPENEDITORFILEMENUGENERATE, etisserant@220: kind=wx.ITEM_NORMAL, text=u'Generate Program\tCTRL+G') etisserant@220: parent.AppendSeparator() lbessard@213: AppendMenu(parent, help='', id=wx.ID_PAGE_SETUP, lbessard@213: kind=wx.ITEM_NORMAL, text=u'Page Setup') lbessard@213: AppendMenu(parent, help='', id=wx.ID_PREVIEW, lbessard@213: kind=wx.ITEM_NORMAL, text=u'Preview') lbessard@213: AppendMenu(parent, help='', id=wx.ID_PRINT, lbessard@213: kind=wx.ITEM_NORMAL, text=u'Print') lbessard@249: if not self.Debug: lbessard@249: parent.AppendSeparator() lbessard@249: AppendMenu(parent, help='', id=wx.ID_PROPERTIES, lbessard@249: kind=wx.ITEM_NORMAL, text=u'Properties') lbessard@221: parent.AppendSeparator() etisserant@220: if self.ModeSolo: etisserant@220: AppendMenu(parent, help='', id=wx.ID_EXIT, etisserant@220: kind=wx.ITEM_NORMAL, text=u'Quit\tCTRL+Q') lbessard@221: else: lbessard@298: AppendMenu(parent, help='', id=wx.ID_STOP, lbessard@221: kind=wx.ITEM_NORMAL, text=u'Close\tCTRL+Q') lbessard@221: lbessard@221: if self.ModeSolo: lbessard@221: self.Bind(wx.EVT_MENU, self.OnNewProjectMenu, id=wx.ID_NEW) lbessard@221: self.Bind(wx.EVT_MENU, self.OnOpenProjectMenu, id=wx.ID_OPEN) lbessard@185: self.Bind(wx.EVT_MENU, self.OnCloseTabMenu, id=wx.ID_CLOSE) lbessard@221: if self.ModeSolo: lbessard@221: self.Bind(wx.EVT_MENU, self.OnCloseProjectMenu, id=wx.ID_CLOSE_ALL) lbessard@249: if not self.Debug: lbessard@249: self.Bind(wx.EVT_MENU, self.OnSaveProjectMenu, id=wx.ID_SAVE) lbessard@221: if self.ModeSolo: lbessard@221: self.Bind(wx.EVT_MENU, self.OnSaveProjectAsMenu, id=wx.ID_SAVEAS) lbessard@221: self.Bind(wx.EVT_MENU, self.OnGenerateProgramMenu, lbessard@221: id=ID_PLCOPENEDITORFILEMENUGENERATE) lbessard@213: self.Bind(wx.EVT_MENU, self.OnPageSetupMenu, id=wx.ID_PAGE_SETUP) lbessard@213: self.Bind(wx.EVT_MENU, self.OnPreviewMenu, id=wx.ID_PREVIEW) lbessard@213: self.Bind(wx.EVT_MENU, self.OnPrintMenu, id=wx.ID_PRINT) lbessard@249: if not self.Debug: lbessard@249: self.Bind(wx.EVT_MENU, self.OnPropertiesMenu, id=wx.ID_PROPERTIES) lbessard@221: if self.ModeSolo: lbessard@221: self.Bind(wx.EVT_MENU, self.OnQuitMenu, id=wx.ID_EXIT) lbessard@221: else: lbessard@298: self.Bind(wx.EVT_MENU, self.OnQuitMenu, id=wx.ID_STOP) lbessard@185: lbessard@185: def _init_coll_EditMenu_Items(self, parent): lbessard@185: AppendMenu(parent, help='', id=wx.ID_REFRESH, lbessard@185: kind=wx.ITEM_NORMAL, text=u'Refresh\tCTRL+R') lbessard@249: if not self.Debug: lbessard@249: if not self.ModeSolo: lbessard@249: AppendMenu(parent, help='', id=wx.ID_CLEAR, lbessard@249: kind=wx.ITEM_NORMAL, text=u'Clear Errors\tCTRL+K') lbessard@249: AppendMenu(parent, help='', id=wx.ID_UNDO, lbessard@249: kind=wx.ITEM_NORMAL, text=u'Undo\tCTRL+Z') lbessard@249: AppendMenu(parent, help='', id=wx.ID_REDO, lbessard@249: kind=wx.ITEM_NORMAL, text=u'Redo\tCTRL+Y') lbessard@249: parent.AppendSeparator() lbessard@249: AppendMenu(parent, help='', id=wx.ID_CUT, lbessard@249: kind=wx.ITEM_NORMAL, text=u'Cut\tCTRL+X') lbessard@249: AppendMenu(parent, help='', id=wx.ID_COPY, lbessard@249: kind=wx.ITEM_NORMAL, text=u'Copy\tCTRL+C') lbessard@249: AppendMenu(parent, help='', id=wx.ID_PASTE, lbessard@249: kind=wx.ITEM_NORMAL, text=u'Paste\tCTRL+V') lbessard@249: parent.AppendSeparator() lbessard@249: addmenu = wx.Menu(title='') lbessard@249: parent.AppendMenu(wx.ID_ADD, "Add Element", addmenu) lbessard@249: AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDDATATYPE, lbessard@249: kind=wx.ITEM_NORMAL, text=u'Data Type') lbessard@249: AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDFUNCTION, lbessard@249: kind=wx.ITEM_NORMAL, text=u'Function') lbessard@249: AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK, lbessard@249: kind=wx.ITEM_NORMAL, text=u'Function Block') lbessard@249: AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDPROGRAM, lbessard@249: kind=wx.ITEM_NORMAL, text=u'Program') lbessard@249: AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDCONFIGURATION, lbessard@249: kind=wx.ITEM_NORMAL, text=u'Configuration') lbessard@249: AppendMenu(parent, help='', id=wx.ID_DELETE, lbessard@249: kind=wx.ITEM_NORMAL, text=u'Delete') lbessard@185: self.Bind(wx.EVT_MENU, self.OnRefreshMenu, id=wx.ID_REFRESH) lbessard@249: if not self.Debug: lbessard@249: if not self.ModeSolo: lbessard@249: self.Bind(wx.EVT_MENU, self.OnClearErrorsMenu, id=wx.ID_CLEAR) lbessard@249: self.Bind(wx.EVT_MENU, self.OnUndoMenu, id=wx.ID_UNDO) lbessard@249: self.Bind(wx.EVT_MENU, self.OnRedoMenu, id=wx.ID_REDO) lbessard@249: self.Bind(wx.EVT_MENU, self.OnCutMenu, id=wx.ID_CUT) lbessard@249: self.Bind(wx.EVT_MENU, self.OnCopyMenu, id=wx.ID_COPY) lbessard@249: self.Bind(wx.EVT_MENU, self.OnPasteMenu, id=wx.ID_PASTE) lbessard@249: self.Bind(wx.EVT_MENU, self.OnAddDataTypeMenu, lbessard@249: id=ID_PLCOPENEDITOREDITMENUADDDATATYPE) lbessard@249: self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction("function"), lbessard@249: id=ID_PLCOPENEDITOREDITMENUADDFUNCTION) lbessard@249: self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction("functionBlock"), lbessard@249: id=ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK) lbessard@249: self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction("program"), lbessard@249: id=ID_PLCOPENEDITOREDITMENUADDPROGRAM) lbessard@249: self.Bind(wx.EVT_MENU, self.OnAddConfigurationMenu, lbessard@249: id=ID_PLCOPENEDITOREDITMENUADDCONFIGURATION) lbessard@249: self.Bind(wx.EVT_MENU, self.OnDeleteMenu, id=wx.ID_DELETE) lbessard@185: etisserant@0: def _init_coll_HelpMenu_Items(self, parent): lbessard@185: AppendMenu(parent, help='', id=wx.ID_HELP, lbessard@114: kind=wx.ITEM_NORMAL, text=u'PLCOpenEditor\tF1') lbessard@223: #AppendMenu(parent, help='', id=wx.ID_HELP_CONTENTS, lbessard@223: # kind=wx.ITEM_NORMAL, text=u'PLCOpen\tF2') greg@190: #AppendMenu(parent, help='', id=wx.ID_HELP_CONTEXT, greg@190: # kind=wx.ITEM_NORMAL, text=u'IEC 61131-3\tF3') lbessard@47: if self.ModeSolo: lbessard@185: AppendMenu(parent, help='', id=wx.ID_ABOUT, lbessard@47: kind=wx.ITEM_NORMAL, text=u'About') greg@190: self.Bind(wx.EVT_MENU, self.OnPLCOpenEditorMenu, id=wx.ID_HELP) lbessard@223: #self.Bind(wx.EVT_MENU, self.OnPLCOpenMenu, id=wx.ID_HELP_CONTENTS) greg@190: self.Bind(wx.EVT_MENU, self.OnAboutMenu, id=wx.ID_ABOUT) etisserant@0: etisserant@0: def _init_utils(self): lbessard@185: self.MenuBar = wx.MenuBar() etisserant@0: etisserant@220: self.FileMenu = wx.Menu(title='') lbessard@114: self.EditMenu = wx.Menu(title='') etisserant@0: self.HelpMenu = wx.Menu(title='') lbessard@163: lbessard@185: self._init_coll_MenuBar_Menus(self.MenuBar) etisserant@220: self._init_coll_FileMenu_Items(self.FileMenu) etisserant@0: self._init_coll_EditMenu_Items(self.EditMenu) etisserant@0: self._init_coll_HelpMenu_Items(self.HelpMenu) lbessard@239: lbessard@239: def _init_coll_MainLibrarySizer_Items(self, parent): lbessard@239: parent.AddWindow(self.LibraryTree, 0, border=0, flag=wx.GROW) lbessard@239: parent.AddSizer(self.LibraryComment, 0, border=0, flag=wx.GROW) lbessard@239: lbessard@239: def _init_coll_MainLibrarySizer_Growables(self, parent): lbessard@239: parent.AddGrowableCol(0) lbessard@239: parent.AddGrowableRow(0) lbessard@239: lbessard@239: def _init_sizers(self): lbessard@239: self.MainLibrarySizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0) lbessard@239: lbessard@239: self._init_coll_MainLibrarySizer_Growables(self.MainLibrarySizer) lbessard@239: self._init_coll_MainLibrarySizer_Items(self.MainLibrarySizer) lbessard@239: lbessard@239: self.LibraryPanel.SetSizer(self.MainLibrarySizer) lbessard@163: etisserant@0: def _init_ctrls(self, prnt): lbessard@235: wx.Frame.__init__(self, id=ID_PLCOPENEDITOR, name=u'PLCOpenEditor', lbessard@235: parent=prnt, pos=wx.DefaultPosition, size=wx.Size(1000, 600), lbessard@235: style=wx.DEFAULT_FRAME_STYLE, title=u'PLCOpenEditor') etisserant@0: self._init_utils() etisserant@0: self.SetClientSize(wx.Size(1000, 600)) lbessard@185: self.SetMenuBar(self.MenuBar) lbessard@92: self.Bind(wx.EVT_CLOSE, self.OnCloseFrame) lbessard@64: lbessard@292: if USE_AUI: lbessard@120: self.AUIManager = wx.aui.AuiManager(self) lbessard@121: self.AUIManager.SetDockSizeConstraint(0.5, 0.5) lbessard@120: self.Panes = {} lbessard@120: lbessard@292: self.TreeNoteBook = wx.aui.AuiNotebook(self) lbessard@292: self.AUIManager.AddPane(self.TreeNoteBook, wx.aui.AuiPaneInfo().Caption("Project").Left().Layer(1).BestSize(wx.Size(200, 500)).CloseButton(False)) lbessard@292: lbessard@292: else: lbessard@120: self.MainSplitter = wx.SplitterWindow(id=ID_PLCOPENEDITORMAINSPLITTER, lbessard@120: name='MainSplitter', parent=self, point=wx.Point(0, 0), lbessard@120: size=wx.Size(0, 0), style=wx.SP_3D) lbessard@120: self.MainSplitter.SetNeedUpdating(True) lbessard@120: self.MainSplitter.SetMinimumPaneSize(1) lbessard@120: lbessard@235: self.TreeNoteBook = wx.Notebook(id=ID_PLCOPENEDITORTREENOTEBOOK, lbessard@235: name='TreeNoteBook', parent=self.MainSplitter, pos=wx.Point(0, lbessard@235: 0), size=wx.Size(0, 0), style=0) lbessard@292: lbessard@249: typestreestyle = wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER lbessard@249: if not self.Debug: lbessard@253: typestreestyle |= wx.TR_EDIT_LABELS lbessard@235: self.TypesTree = wx.TreeCtrl(id=ID_PLCOPENEDITORTYPESTREE, lbessard@235: name='TypesTree', parent=self.TreeNoteBook, lbessard@235: pos=wx.Point(0, 0), size=wx.Size(0, 0), lbessard@249: style=typestreestyle) lbessard@249: if not self.Debug: lbessard@249: if wx.Platform == '__WXMSW__': lbessard@249: self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnTypesTreeRightUp, lbessard@249: id=ID_PLCOPENEDITORTYPESTREE) lbessard@249: self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnTypesTreeItemSelected, lbessard@249: id=ID_PLCOPENEDITORTYPESTREE) lbessard@249: else: lbessard@249: if wx.VERSION >= (2, 6, 0): lbessard@249: self.TypesTree.Bind(wx.EVT_RIGHT_UP, self.OnTypesTreeRightUp) lbessard@249: self.TypesTree.Bind(wx.EVT_LEFT_UP, self.OnTypesTreeLeftUp) lbessard@249: else: lbessard@249: wx.EVT_RIGHT_UP(self.TypesTree, self.OnTypesTreeRightUp) lbessard@249: wx.EVT_LEFT_UP(self.TypesTree, self.OnTypesTreeLeftUp) lbessard@249: self.Bind(wx.EVT_TREE_SEL_CHANGING, self.OnTypesTreeItemChanging, lbessard@249: id=ID_PLCOPENEDITORTYPESTREE) lbessard@249: self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnTypesTreeBeginDrag, lbessard@235: id=ID_PLCOPENEDITORTYPESTREE) lbessard@249: self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnTypesTreeItemBeginEdit, lbessard@235: id=ID_PLCOPENEDITORTYPESTREE) lbessard@249: self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnTypesTreeItemEndEdit, lbessard@235: id=ID_PLCOPENEDITORTYPESTREE) lbessard@249: self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnTypesTreeItemActivated, lbessard@249: id=ID_PLCOPENEDITORTYPESTREE) lbessard@235: lbessard@235: self.InstancesTree = wx.TreeCtrl(id=ID_PLCOPENEDITORINSTANCESTREE, lbessard@235: name='InstancesTree', parent=self.TreeNoteBook, lbessard@235: pos=wx.Point(0, 0), size=wx.Size(0, 0), lbessard@249: style=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER) lbessard@249: if self.Debug: lbessard@249: self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnInstancesTreeBeginDrag, lbessard@249: id=ID_PLCOPENEDITORINSTANCESTREE) lbessard@249: self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnInstancesTreeItemActivated, lbessard@249: id=ID_PLCOPENEDITORINSTANCESTREE) lbessard@120: lbessard@253: self.TreeNoteBook.AddPage(self.InstancesTree, "Instances") lbessard@253: self.TreeNoteBook.AddPage(self.TypesTree, "Types") lbessard@253: lbessard@292: if USE_AUI: lbessard@292: self.TabsOpened = wx.aui.AuiNotebook(self) lbessard@292: self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED, lbessard@292: self.OnPouSelectedChanged) lbessard@294: self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE, lbessard@294: self.OnPageClose) lbessard@292: self.AUIManager.AddPane(self.TabsOpened, wx.aui.AuiPaneInfo().CentrePane()) lbessard@292: else: lbessard@249: self.TabsOpened = wx.Notebook(id=ID_PLCOPENEDITORTABSOPENED, lbessard@249: name='TabsOpened', parent=self.MainSplitter, pos=wx.Point(0, lbessard@249: 0), size=wx.Size(0, 0), style=0) lbessard@249: if wx.VERSION >= (2, 6, 0): lbessard@249: self.TabsOpened.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, lbessard@249: self.OnPouSelectedChanged, id=ID_PLCOPENEDITORTABSOPENED) lbessard@249: else: lbessard@249: wx.EVT_NOTEBOOK_PAGE_CHANGED(self.TabsOpened, ID_PLCOPENEDITORTABSOPENED, lbessard@249: self.OnPouSelectedChanged) lbessard@121: lbessard@249: self.MainSplitter.SplitVertically(self.TreeNoteBook, self.TabsOpened, 200) lbessard@249: else: lbessard@253: self.TreeNoteBook.AddPage(self.TypesTree, "Types") lbessard@253: self.TreeNoteBook.AddPage(self.InstancesTree, "Instances") lbessard@253: lbessard@292: if USE_AUI: lbessard@249: ToolBar = wx.ToolBar(self, ID_PLCOPENEDITORTOOLBAR, wx.DefaultPosition, wx.DefaultSize, lbessard@249: wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER) lbessard@249: ToolBar.SetToolBitmapSize(wx.Size(25, 25)) lbessard@249: ToolBar.AddRadioTool(ID_PLCOPENEDITORTOOLBARSELECTION, lbessard@249: wx.Bitmap(os.path.join(CWD, 'Images', 'select.png')), wx.NullBitmap, "Select an object") lbessard@249: ToolBar.Realize() lbessard@249: self.Panes["ToolBar"] = ToolBar lbessard@249: self.AUIManager.AddPane(ToolBar, wx.aui.AuiPaneInfo(). lbessard@249: Name("ToolBar").Caption("Toolbar"). lbessard@249: ToolbarPane().Top(). lbessard@249: LeftDockable(False).RightDockable(False)) lbessard@292: else: lbessard@292: self.ToolBar = self.CreateToolBar(wx.TB_HORIZONTAL|wx.TB_FLAT|wx.NO_BORDER, lbessard@292: ID_PLCOPENEDITORTOOLBAR, 'ToolBar') lbessard@292: self.ToolBar.SetToolBitmapSize(wx.Size(25, 25)) lbessard@292: self.ToolBar.AddRadioTool(ID_PLCOPENEDITORTOOLBARSELECTION, lbessard@292: wx.Bitmap(os.path.join(CWD, 'Images', 'select.png')), wx.NullBitmap, "Select an object") lbessard@292: self.ToolBar.Realize() lbessard@121: lbessard@249: self.Bind(wx.EVT_TOOL, self.OnSelectionTool, lbessard@249: id=ID_PLCOPENEDITORTOOLBARSELECTION) lbessard@239: lbessard@292: if USE_AUI: lbessard@292: self.VariablePanelIndexer = VariablePanelIndexer(self, self, self.Controler) lbessard@292: self.AUIManager.AddPane(self.VariablePanelIndexer, wx.aui.AuiPaneInfo().Caption("Variables").Bottom().Layer(0).BestSize(wx.Size(800, 200)).CloseButton(False)) lbessard@292: lbessard@292: self.TabsOpened = wx.aui.AuiNotebook(self) lbessard@292: self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED, lbessard@292: self.OnPouSelectedChanged) lbessard@294: self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE, lbessard@294: self.OnPageClose) lbessard@292: self.AUIManager.AddPane(self.TabsOpened, wx.aui.AuiPaneInfo().CentrePane().MinSize(wx.Size(0, 0))) lbessard@292: lbessard@292: self.LibraryPanel = wx.Panel(id=ID_PLCOPENEDITORLIBRARYPANEL, lbessard@292: name='LibraryPanel', parent=self, pos=wx.Point(0, lbessard@292: 0), size=wx.Size(0, 0), style=0) lbessard@292: self.AUIManager.AddPane(self.LibraryPanel, wx.aui.AuiPaneInfo().Caption("Library").Right().Layer(0).BestSize(wx.Size(250, 400)).CloseButton(False)) lbessard@292: else: lbessard@249: self.SecondSplitter = wx.SplitterWindow(id=ID_PLCOPENEDITORSECONDSPLITTER, lbessard@249: name='SecondSplitter', parent=self.MainSplitter, point=wx.Point(0, 0), lbessard@249: size=wx.Size(0, 0), style=wx.SP_3D) lbessard@249: self.SecondSplitter.SetMinimumPaneSize(1) lbessard@249: lbessard@249: self.MainSplitter.SplitVertically(self.TreeNoteBook, self.SecondSplitter, 200) lbessard@249: lbessard@249: self.VariablePanelIndexer = VariablePanelIndexer(self.SecondSplitter, self, self.Controler) lbessard@239: lbessard@249: self.ThirdSplitter = wx.SplitterWindow(id=ID_PLCOPENEDITORTHIRDSPLITTER, lbessard@249: name='ThirdSplitter', parent=self.SecondSplitter, point=wx.Point(0, 0), lbessard@249: size=wx.Size(0, 0), style=wx.SP_3D) lbessard@249: self.ThirdSplitter.SetMinimumPaneSize(1) lbessard@249: lbessard@249: self.SecondSplitter.SplitHorizontally(self.ThirdSplitter, self.VariablePanelIndexer, -200) lbessard@249: lbessard@249: self.TabsOpened = wx.Notebook(id=ID_PLCOPENEDITORTABSOPENED, lbessard@292: name='TabsOpened', parent=self.ThirdSplitter, pos=wx.Point(0, lbessard@249: 0), size=wx.Size(0, 0), style=0) lbessard@292: self.TabsImageList = wx.ImageList(16, 31) lbessard@292: self.TabsOpened.SetImageList(self.TabsImageList) lbessard@292: self.TabsImageListIndexes = {} lbessard@249: if wx.VERSION >= (2, 6, 0): lbessard@249: self.TabsOpened.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, lbessard@249: self.OnPouSelectedChanged, id=ID_PLCOPENEDITORTABSOPENED) lbessard@249: else: lbessard@249: wx.EVT_NOTEBOOK_PAGE_CHANGED(self.TabsOpened, ID_PLCOPENEDITORTABSOPENED, lbessard@249: self.OnPouSelectedChanged) lbessard@249: lbessard@249: self.LibraryPanel = wx.Panel(id=ID_PLCOPENEDITORLIBRARYPANEL, lbessard@249: name='LibraryPanel', parent=self.ThirdSplitter, pos=wx.Point(0, lbessard@249: 0), size=wx.Size(0, 0), style=wx.SUNKEN_BORDER) lbessard@249: lbessard@249: self.ThirdSplitter.SplitVertically(self.TabsOpened, self.LibraryPanel, -250) lbessard@292: lbessard@249: if wx.Platform == '__WXMSW__': lbessard@249: librarytreestyle = wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER lbessard@249: else: lbessard@249: librarytreestyle = wx.TR_HAS_BUTTONS|wx.TR_HIDE_ROOT|wx.TR_SINGLE|wx.SUNKEN_BORDER lbessard@249: self.LibraryTree = wx.TreeCtrl(id=ID_PLCOPENEDITORLIBRARYTREE, lbessard@249: name='LibraryTree', parent=self.LibraryPanel, lbessard@249: pos=wx.Point(0, 0), size=wx.Size(0, 0), lbessard@249: style=librarytreestyle) lbessard@249: self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnLibraryTreeItemSelected, lbessard@249: id=ID_PLCOPENEDITORLIBRARYTREE) lbessard@249: self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnLibraryTreeBeginDrag, lbessard@249: id=ID_PLCOPENEDITORLIBRARYTREE) lbessard@249: lbessard@249: self.LibraryComment = wx.TextCtrl(id=ID_PLCOPENEDITORLIBRARYCOMMENT, lbessard@249: name='LibraryComment', parent=self.LibraryPanel, lbessard@249: pos=wx.Point(0, 0), size=wx.Size(0, 60), lbessard@249: style=wx.TE_READONLY|wx.TE_MULTILINE) lbessard@249: lbessard@249: self._init_sizers() lbessard@239: lbessard@292: if USE_AUI: lbessard@241: self.AUIManager.Update() lbessard@241: lbessard@249: def __init__(self, parent, controler = None, fileOpen = None, debug = False): lbessard@47: self.ModeSolo = controler == None lbessard@249: self.Debug = debug lbessard@121: if self.ModeSolo: lbessard@121: self.Controler = PLCControler() lbessard@121: if fileOpen is not None: lbessard@121: self.Controler.OpenXMLFile(fileOpen) lbessard@121: else: lbessard@121: self.Controler = controler lbessard@121: etisserant@0: self._init_ctrls(parent) etisserant@0: lbessard@185: self.SetIcon(wx.Icon(os.path.join(CWD,"Images","poe.ico"),wx.BITMAP_TYPE_ICO)) greg@176: lbessard@235: self.TypesTreeImageList = wx.ImageList(16, 16) lbessard@235: self.InstancesTreeImageList = wx.ImageList(16, 16) lbessard@235: self.TypesTreeImageDict = {} lbessard@235: self.InstancesTreeImageDict = {} etisserant@184: for language in LANGUAGES: lbessard@235: self.TypesTreeImageDict[language]=self.TypesTreeImageList.Add(wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%language))) lbessard@235: self.InstancesTreeImageDict[language]=self.InstancesTreeImageList.Add(wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%language))) etisserant@184: etisserant@184: for imgname, itemtype in [ etisserant@184: #editables etisserant@184: ("PROJECT", ITEM_PROJECT), etisserant@184: #("POU", ITEM_POU), etisserant@184: #("VARIABLE", ITEM_VARIABLE), etisserant@184: ("TRANSITION", ITEM_TRANSITION), etisserant@184: ("ACTION", ITEM_ACTION), etisserant@184: ("CONFIGURATION", ITEM_CONFIGURATION), etisserant@184: ("RESOURCE", ITEM_RESOURCE), etisserant@184: ("DATATYPE", ITEM_DATATYPE), etisserant@184: # uneditables etisserant@184: ("DATATYPES", ITEM_DATATYPES), etisserant@184: ("FUNCTION", ITEM_FUNCTION), etisserant@184: ("FUNCTIONBLOCK", ITEM_FUNCTIONBLOCK), etisserant@184: ("PROGRAM", ITEM_PROGRAM), lbessard@235: ("VAR_LOCAL", ITEM_VAR_LOCAL), lbessard@235: ("VAR_LOCAL", ITEM_VAR_GLOBAL), lbessard@235: ("VAR_LOCAL", ITEM_VAR_EXTERNAL), lbessard@235: ("VAR_LOCAL", ITEM_VAR_TEMP), lbessard@235: ("VAR_INPUT", ITEM_VAR_INPUT), lbessard@235: ("VAR_OUTPUT", ITEM_VAR_OUTPUT), lbessard@235: ("VAR_INOUT", ITEM_VAR_INOUT), etisserant@184: ("TRANSITIONS", ITEM_TRANSITIONS), etisserant@184: ("ACTIONS", ITEM_ACTIONS), etisserant@184: ("CONFIGURATIONS", ITEM_CONFIGURATIONS), etisserant@184: ("RESOURCES", ITEM_RESOURCES), etisserant@184: ("PROPERTIES", ITEM_PROPERTIES)]: lbessard@235: self.TypesTreeImageDict[itemtype]=self.TypesTreeImageList.Add(wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%imgname))) lbessard@235: self.InstancesTreeImageDict[itemtype]=self.InstancesTreeImageList.Add(wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%imgname))) lbessard@235: self.TypesTree.AssignImageList(self.TypesTreeImageList) lbessard@235: self.InstancesTree.AssignImageList(self.InstancesTreeImageList) lbessard@9: lbessard@6: self.CurrentToolBar = [] lbessard@27: self.CurrentLanguage = "" lbessard@122: self.SelectedItem = None lbessard@231: self.Errors = [] lbessard@71: self.DrawingMode = FREEDRAWING_MODE lbessard@71: #self.DrawingMode = DRIVENDRAWING_MODE lbessard@6: lbessard@213: self.PrintData = wx.PrintData() lbessard@213: self.PrintData.SetPaperId(wx.PAPER_A4) lbessard@213: self.PrintData.SetPrintMode(wx.PRINT_MODE_PRINTER) lbessard@213: self.PageSetupData = wx.PageSetupDialogData(self.PrintData) lbessard@213: self.PageSetupData.SetMarginTopLeft(wx.Point(10, 15)) lbessard@213: self.PageSetupData.SetMarginBottomRight(wx.Point(10, 20)) lbessard@213: lbessard@121: if not self.ModeSolo or fileOpen is not None: lbessard@235: self.RefreshTypesTree() lbessard@235: self.RefreshInstancesTree() lbessard@239: self.RefreshLibraryTree() lbessard@121: etisserant@0: self.RefreshFileMenu() etisserant@0: self.RefreshEditMenu() lbessard@56: self.RefreshTitle() etisserant@0: self.RefreshToolBar() etisserant@0: lbessard@122: def ResetSelectedItem(self): lbessard@122: self.SelectedItem = None lbessard@122: lbessard@121: def OnPageClose(self, event): lbessard@294: selected = event.GetSelection() lbessard@121: if selected >= 0: lbessard@294: if not self.Debug: lbessard@294: tagname = self.TabsOpened.GetPage(selected).GetTagName() lbessard@294: self.VariablePanelIndexer.RemoveVariablePanel(tagname) lbessard@235: if self.TabsOpened.GetPageCount() > 0: lbessard@235: new_index = min(selected, self.TabsOpened.GetPageCount() - 1) lbessard@235: self.TabsOpened.SetSelection(new_index) lbessard@294: if not self.Debug: lbessard@294: tagname = self.TabsOpened.GetPage(new_index).GetTagName() lbessard@294: self.VariablePanelIndexer.ChangeVariablePanel(tagname) lbessard@121: self.RefreshTitle() lbessard@121: self.RefreshFileMenu() lbessard@121: self.RefreshEditMenu() lbessard@121: self.RefreshToolBar() lbessard@121: event.Skip() lbessard@121: lbessard@114: def GetCopyBuffer(self): lbessard@163: return PLCOpenEditor.CopyBuffer lbessard@114: lbessard@114: def SetCopyBuffer(self, element): lbessard@163: PLCOpenEditor.CopyBuffer = element lbessard@114: self.RefreshEditMenu() lbessard@114: lbessard@27: def GetDrawingMode(self): lbessard@27: return self.DrawingMode lbessard@27: lbessard@56: def RefreshTitle(self): lbessard@253: name = "PLCOpenEditor" lbessard@253: if self.Debug: lbessard@253: name += " (Debug)" lbessard@56: if self.Controler.HasOpenedProject() > 0: lbessard@253: self.SetTitle("%s - %s"%(name, self.Controler.GetFilename())) lbessard@253: else: lbessard@253: self.SetTitle(name) lbessard@56: lbessard@27: def ShowProperties(self): lbessard@249: old_values = self.Controler.GetProjectProperties(self.Debug) lbessard@27: dialog = ProjectDialog(self) lbessard@27: dialog.SetValues(old_values) lbessard@64: if dialog.ShowModal() == wx.ID_OK: lbessard@27: new_values = dialog.GetValues() lbessard@27: new_values["creationDateTime"] = old_values["creationDateTime"] lbessard@145: if new_values != old_values: lbessard@145: self.Controler.SetProjectProperties(None, new_values) lbessard@145: self.RefreshTitle() lbessard@145: self.RefreshFileMenu() lbessard@145: self.RefreshEditMenu() lbessard@235: self.RefreshTypesTree() lbessard@235: for i in xrange(self.TabsOpened.GetPageCount()): lbessard@249: editor = self.TabsOpened.GetPage(i) lbessard@145: editor.RefreshScaling() lbessard@27: dialog.Destroy() lbessard@27: lbessard@56: def OnCloseFrame(self, event): lbessard@107: if not self.ModeSolo and getattr(self, "_onclose", None) is not None: lbessard@121: self.AUIManager.UnInit() lbessard@90: self._onclose() lbessard@90: event.Skip() lbessard@90: elif not self.Controler.ProjectIsSaved(): lbessard@80: dialog = wx.MessageDialog(self, "There are changes, do you want to save?", "Close Application", wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION) lbessard@56: answer = dialog.ShowModal() lbessard@56: dialog.Destroy() lbessard@64: if answer == wx.ID_YES: lbessard@56: self.SaveProject() lbessard@56: event.Skip() lbessard@64: elif answer == wx.ID_NO: lbessard@80: self.Controler.Reset() lbessard@121: self.AUIManager.UnInit() lbessard@56: event.Skip() lbessard@80: else: lbessard@80: event.Veto() lbessard@56: else: lbessard@56: event.Skip() lbessard@56: lbessard@163: #------------------------------------------------------------------------------- lbessard@163: # Notebook Unified Functions lbessard@163: #------------------------------------------------------------------------------- lbessard@163: lbessard@292: def GenerateBitmap(self, icon1_name, icon2_name = None): lbessard@292: if not USE_AUI: lbessard@292: index = self.TabsImageListIndexes.get((icon1_name, icon2_name), None) lbessard@292: if index is not None: lbessard@292: return index lbessard@292: if icon2_name is None: lbessard@292: tmp_bitmap = wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%icon1_name)) lbessard@292: else: lbessard@292: icon1 = wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%icon1_name)) lbessard@292: icon2 = wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%icon2_name)) lbessard@292: width = icon1.GetWidth() + icon2.GetWidth() - 1 lbessard@292: height = max(icon1.GetHeight(), icon2.GetHeight()) lbessard@292: tmp_bitmap = wx.EmptyBitmap(width, height) lbessard@292: dc = wx.MemoryDC() lbessard@292: dc.SelectObject(tmp_bitmap) lbessard@292: dc.Clear() lbessard@292: dc.DrawBitmap(icon1, 0, 0) lbessard@292: dc.DrawBitmap(icon2, icon1.GetWidth() - 1, 0) lbessard@292: if USE_AUI: lbessard@292: return tmp_bitmap lbessard@292: else: lbessard@292: index = self.TabsImageList.Add(tmp_bitmap) lbessard@292: self.TabsImageListIndexes[(icon1_name, icon2_name)] = index lbessard@292: return index lbessard@292: lbessard@163: def DeleteAllPages(self): lbessard@292: if USE_AUI: lbessard@235: for idx in xrange(self.TabsOpened.GetPageCount()): lbessard@235: self.TabsOpened.DeletePage(0) lbessard@163: else: lbessard@163: self.TabsOpened.DeleteAllPages() lbessard@163: lbessard@203: def SetPageBitmap(self, idx, bitmap): lbessard@292: if USE_AUI: lbessard@235: return self.TabsOpened.SetPageBitmap(idx, bitmap) lbessard@203: else: lbessard@203: return self.TabsOpened.SetPageImage(idx, bitmap) lbessard@203: lbessard@163: lbessard@163: #------------------------------------------------------------------------------- lbessard@163: # File Menu Functions lbessard@163: #------------------------------------------------------------------------------- lbessard@163: lbessard@163: def RefreshFileMenu(self): lbessard@221: if self.Controler.HasOpenedProject(): lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@221: if selected >= 0: lbessard@235: graphic_viewer = isinstance(self.TabsOpened.GetPage(selected), Viewer) lbessard@221: else: lbessard@221: graphic_viewer = False lbessard@235: if self.TabsOpened.GetPageCount() > 0: lbessard@221: self.FileMenu.Enable(wx.ID_CLOSE, True) lbessard@221: if graphic_viewer: lbessard@221: self.FileMenu.Enable(wx.ID_PREVIEW, True) lbessard@221: self.FileMenu.Enable(wx.ID_PRINT, True) lbessard@213: else: lbessard@213: self.FileMenu.Enable(wx.ID_PREVIEW, False) lbessard@213: self.FileMenu.Enable(wx.ID_PRINT, False) lbessard@221: else: lbessard@221: self.FileMenu.Enable(wx.ID_CLOSE, False) lbessard@221: self.FileMenu.Enable(wx.ID_PREVIEW, False) lbessard@221: self.FileMenu.Enable(wx.ID_PRINT, False) lbessard@221: self.FileMenu.Enable(wx.ID_SAVE, True) lbessard@221: self.FileMenu.Enable(wx.ID_PAGE_SETUP, True) lbessard@221: self.FileMenu.Enable(wx.ID_PROPERTIES, True) lbessard@221: if self.ModeSolo: lbessard@185: self.FileMenu.Enable(wx.ID_CLOSE_ALL, True) lbessard@185: self.FileMenu.Enable(wx.ID_SAVEAS, True) lbessard@185: self.FileMenu.Enable(ID_PLCOPENEDITORFILEMENUGENERATE, True) lbessard@221: else: lbessard@221: self.FileMenu.Enable(wx.ID_CLOSE, False) lbessard@221: self.FileMenu.Enable(wx.ID_SAVE, False) lbessard@221: self.FileMenu.Enable(wx.ID_PAGE_SETUP, False) lbessard@221: self.FileMenu.Enable(wx.ID_PREVIEW, False) lbessard@221: self.FileMenu.Enable(wx.ID_PRINT, False) lbessard@221: self.FileMenu.Enable(wx.ID_PROPERTIES, False) lbessard@221: if self.ModeSolo: lbessard@185: self.FileMenu.Enable(wx.ID_CLOSE_ALL, False) lbessard@185: self.FileMenu.Enable(wx.ID_SAVEAS, False) lbessard@185: self.FileMenu.Enable(ID_PLCOPENEDITORFILEMENUGENERATE, False) lbessard@163: etisserant@0: def OnNewProjectMenu(self, event): etisserant@0: dialog = ProjectDialog(self) lbessard@64: if dialog.ShowModal() == wx.ID_OK: lbessard@145: properties = dialog.GetValues() lbessard@145: self.Controler.CreateNewProject(properties) lbessard@56: self.RefreshTitle() etisserant@0: self.RefreshFileMenu() etisserant@0: self.RefreshEditMenu() lbessard@235: self.RefreshTypesTree() lbessard@235: self.RefreshInstancesTree() lbessard@239: self.RefreshLibraryTree() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnOpenProjectMenu(self, event): lbessard@144: if not self.Controler.ProjectIsSaved(): lbessard@144: dialog = wx.MessageDialog(self, "There are changes, do you want to save?", "Close Application", wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION) lbessard@144: answer = dialog.ShowModal() lbessard@144: dialog.Destroy() lbessard@144: if answer == wx.ID_YES: lbessard@144: self.SaveProject() lbessard@144: elif answer == wx.ID_CANCEL: lbessard@144: return etisserant@0: filepath = self.Controler.GetFilePath() etisserant@0: if filepath != "": etisserant@0: directory = os.path.dirname(filepath) etisserant@0: else: etisserant@0: directory = os.getcwd() lbessard@64: dialog = wx.FileDialog(self, "Choose a file", directory, "", "PLCOpen files (*.xml)|*.xml|All files|*.*", wx.OPEN) lbessard@64: if dialog.ShowModal() == wx.ID_OK: etisserant@0: filepath = dialog.GetPath() etisserant@0: if os.path.isfile(filepath): lbessard@144: self.DeleteAllPages() lbessard@144: self.VariablePanelIndexer.RemoveAllPanels() etisserant@0: self.Controler.OpenXMLFile(filepath) lbessard@235: self.RefreshTypesTree() lbessard@235: self.RefreshInstancesTree() lbessard@239: self.RefreshLibraryTree() lbessard@56: self.RefreshTitle() etisserant@0: self.RefreshFileMenu() etisserant@0: self.RefreshEditMenu() etisserant@0: self.RefreshToolBar() etisserant@0: dialog.Destroy() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnCloseTabMenu(self, event): lbessard@235: selected = self.TabsOpened.GetSelection() etisserant@0: if selected >= 0: lbessard@249: if not self.Debug: lbessard@249: tagname = self.TabsOpened.GetPage(selected).GetTagName() lbessard@249: self.VariablePanelIndexer.RemoveVariablePanel(tagname) lbessard@294: self.TabsOpened.DeletePage(selected) lbessard@235: if self.TabsOpened.GetPageCount() > 0: lbessard@235: new_index = min(selected, self.TabsOpened.GetPageCount() - 1) lbessard@235: self.TabsOpened.SetSelection(new_index) lbessard@249: if not self.Debug: lbessard@249: tagname = self.TabsOpened.GetPage(new_index).GetTagName() lbessard@249: self.VariablePanelIndexer.ChangeVariablePanel(tagname) etisserant@0: self.RefreshFileMenu() etisserant@0: self.RefreshEditMenu() etisserant@0: self.RefreshToolBar() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnCloseProjectMenu(self, event): lbessard@144: if not self.Controler.ProjectIsSaved(): lbessard@144: dialog = wx.MessageDialog(self, "There are changes, do you want to save?", "Close Application", wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION) lbessard@144: answer = dialog.ShowModal() lbessard@144: dialog.Destroy() lbessard@144: if answer == wx.ID_YES: lbessard@144: self.SaveProject() lbessard@144: elif answer == wx.ID_CANCEL: lbessard@144: return lbessard@121: self.DeleteAllPages() lbessard@121: self.VariablePanelIndexer.RemoveAllPanels() lbessard@235: self.TypesTree.DeleteAllItems() lbessard@235: self.InstancesTree.DeleteAllItems() lbessard@102: self.Controler.Reset() lbessard@56: self.RefreshTitle() etisserant@0: self.RefreshFileMenu() etisserant@0: self.RefreshEditMenu() etisserant@0: self.RefreshToolBar() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnSaveProjectMenu(self, event): lbessard@90: if not self.ModeSolo and getattr(self, "_onsave", None) != None: lbessard@90: self._onsave() lbessard@90: else: lbessard@90: self.SaveProject() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnSaveProjectAsMenu(self, event): etisserant@0: self.SaveProjectAs() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnGenerateProgramMenu(self, event): lbessard@64: dialog = wx.FileDialog(self, "Choose a file", os.getcwd(), self.Controler.GetProgramFilePath(), "ST files (*.st)|*.st|All files|*.*", wx.SAVE|wx.CHANGE_DIR) lbessard@64: if dialog.ShowModal() == wx.ID_OK: lbessard@4: filepath = dialog.GetPath() lbessard@4: if os.path.isdir(os.path.dirname(filepath)): lbessard@4: result = self.Controler.GenerateProgram(filepath) etisserant@171: if result is not None: etisserant@171: message = wx.MessageDialog(self, "Can't generate program to file %s :\n%s"%(filepath, result), "Error", wx.OK|wx.ICON_ERROR) lbessard@4: message.ShowModal() lbessard@4: message.Destroy() lbessard@67: else: lbessard@67: message = wx.MessageDialog(self, "Program was successfully generated!", "Done", wx.OK|wx.ICON_INFORMATION) lbessard@67: message.ShowModal() lbessard@67: message.Destroy() lbessard@4: else: lbessard@64: message = wx.MessageDialog(self, "%s is not a valid folder!"%os.path.dirname(filepath), "Error", wx.OK|wx.ICON_ERROR) lbessard@4: message.ShowModal() lbessard@4: message.Destroy() lbessard@4: dialog.Destroy() etisserant@0: event.Skip() etisserant@0: etisserant@0: def SaveProject(self): etisserant@0: result = self.Controler.SaveXMLFile() etisserant@0: if not result: etisserant@0: self.SaveProjectAs() lbessard@56: else: lbessard@56: self.RefreshTitle() etisserant@0: etisserant@0: def SaveProjectAs(self): etisserant@0: filepath = self.Controler.GetFilePath() etisserant@0: if filepath != "": etisserant@0: directory, filename = os.path.split(filepath) etisserant@0: else: lbessard@249: directory, filename = os.getcwd(), "%(projectName)s.xml"%self.Controler.GetProjectProperties(self.Debug) lbessard@64: dialog = wx.FileDialog(self, "Choose a file", directory, filename, "PLCOpen files (*.xml)|*.xml|All files|*.*", wx.SAVE|wx.OVERWRITE_PROMPT) lbessard@64: if dialog.ShowModal() == wx.ID_OK: etisserant@0: filepath = dialog.GetPath() etisserant@0: if os.path.isdir(os.path.dirname(filepath)): etisserant@0: result = self.Controler.SaveXMLFile(filepath) etisserant@0: if not result: lbessard@64: message = wx.MessageDialog(self, "Can't save project to file %s!"%filepath, "Error", wx.OK|wx.ICON_ERROR) etisserant@0: message.ShowModal() etisserant@0: message.Destroy() etisserant@0: else: lbessard@64: message = wx.MessageDialog(self, "%s is not a valid folder!"%os.path.dirname(filepath), "Error", wx.OK|wx.ICON_ERROR) etisserant@0: message.ShowModal() etisserant@0: message.Destroy() lbessard@56: self.RefreshTitle() etisserant@0: dialog.Destroy() etisserant@0: lbessard@213: def OnPageSetupMenu(self, event): lbessard@213: dialog = wx.PageSetupDialog(self, self.PageSetupData) lbessard@213: if dialog.ShowModal() == wx.ID_OK: lbessard@213: self.PageSetupData = wx.PageSetupDialogData(dialog.GetPageSetupData()) lbessard@213: self.PrintData = wx.PrintData(self.PageSetupData.GetPrintData()) lbessard@213: dialog.Destroy() lbessard@213: event.Skip() lbessard@213: lbessard@213: def OnPreviewMenu(self, event): lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@213: if selected != -1: lbessard@213: data = wx.PrintDialogData(self.PrintData) lbessard@249: properties = self.Controler.GetProjectProperties(self.Debug) lbessard@213: page_size = map(int, properties["pageSize"]) lbessard@213: margins = (self.PageSetupData.GetMarginTopLeft(), self.PageSetupData.GetMarginBottomRight()) lbessard@235: printout = GraphicPrintout(self.TabsOpened.GetPage(selected), page_size, margins, True) lbessard@235: printout2 = GraphicPrintout(self.TabsOpened.GetPage(selected), page_size, margins, True) lbessard@213: preview = wx.PrintPreview(printout, printout2, data) lbessard@213: lbessard@213: if preview.Ok(): etisserant@220: preview_frame = wx.PreviewFrame(preview, self, "Print preview") lbessard@213: lbessard@213: preview_frame.Initialize() lbessard@213: lbessard@213: preview_frame.Show(True) lbessard@213: event.Skip() lbessard@213: lbessard@213: def OnPrintMenu(self, event): lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@213: if selected != -1: lbessard@213: dialog_data = wx.PrintDialogData(self.PrintData) lbessard@213: dialog_data.SetToPage(1) lbessard@249: properties = self.Controler.GetProjectProperties(self.Debug) lbessard@213: page_size = map(int, properties["pageSize"]) lbessard@213: margins = (self.PageSetupData.GetMarginTopLeft(), self.PageSetupData.GetMarginBottomRight()) lbessard@213: printer = wx.Printer(dialog_data) lbessard@235: printout = GraphicPrintout(self.TabsOpened.GetPage(selected), page_size, margins) lbessard@213: lbessard@213: if not printer.Print(self, printout, True): lbessard@213: wx.MessageBox("There was a problem printing.\nPerhaps your current printer is not set correctly?", "Printing", wx.OK) lbessard@213: printout.Destroy() lbessard@213: event.Skip() lbessard@213: lbessard@27: def OnPropertiesMenu(self, event): lbessard@27: self.ShowProperties() lbessard@27: event.Skip() lbessard@27: etisserant@0: def OnQuitMenu(self, event): etisserant@0: self.Close() etisserant@0: event.Skip() etisserant@0: lbessard@163: lbessard@163: #------------------------------------------------------------------------------- lbessard@163: # Edit Project Menu Functions lbessard@163: #------------------------------------------------------------------------------- lbessard@163: lbessard@163: def RefreshEditMenu(self): lbessard@217: if self.Controler.HasOpenedProject(): lbessard@217: undo, redo = self.Controler.GetBufferState() lbessard@217: self.EditMenu.Enable(wx.ID_UNDO, undo) lbessard@217: self.EditMenu.Enable(wx.ID_REDO, redo) lbessard@217: else: lbessard@217: self.EditMenu.Enable(wx.ID_UNDO, False) lbessard@217: self.EditMenu.Enable(wx.ID_REDO, False) lbessard@217: if self.Controler.HasOpenedProject(): lbessard@235: if self.TabsOpened.GetPageCount() > 0: lbessard@217: self.EditMenu.Enable(wx.ID_REFRESH, True) lbessard@185: else: lbessard@185: self.EditMenu.Enable(wx.ID_REFRESH, False) lbessard@217: self.EditMenu.Enable(wx.ID_ADD, True) lbessard@217: self.EditMenu.Enable(wx.ID_DELETE, True) lbessard@217: else: lbessard@217: self.EditMenu.Enable(wx.ID_REFRESH, False) lbessard@217: self.EditMenu.Enable(wx.ID_ADD, False) lbessard@217: self.EditMenu.Enable(wx.ID_DELETE, False) lbessard@217: self.EditMenu.Enable(wx.ID_CUT, True) lbessard@217: self.EditMenu.Enable(wx.ID_COPY, True) lbessard@217: if self.CopyBuffer is not None: lbessard@217: self.EditMenu.Enable(wx.ID_PASTE, True) lbessard@217: else: lbessard@217: self.EditMenu.Enable(wx.ID_PASTE, False) lbessard@163: lbessard@163: def OnRefreshMenu(self, event): lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@3: if selected != -1: lbessard@235: window = self.TabsOpened.GetPage(selected) lbessard@163: window.RefreshView() lbessard@249: if not self.Debug: lbessard@249: self.VariablePanelIndexer.RefreshVariablePanel(window.GetTagName()) lbessard@163: event.Skip() lbessard@163: lbessard@231: def OnClearErrorsMenu(self, event): lbessard@231: self.ClearErrors() lbessard@231: event.Skip() lbessard@231: lbessard@163: def OnUndoMenu(self, event): lbessard@163: self.Controler.LoadPrevious() lbessard@235: idxs = range(self.TabsOpened.GetPageCount()) lbessard@163: idxs.reverse() lbessard@163: for idx in idxs: lbessard@235: tagname = self.TabsOpened.GetPage(idx).GetTagName() lbessard@249: if self.Controler.GetEditedElement(tagname, self.Debug) is None: lbessard@163: self.VariablePanelIndexer.RemoveVariablePanel(tagname) lbessard@235: self.TabsOpened.DeletePage(idx) lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@163: if selected != -1: lbessard@235: window = self.TabsOpened.GetPage(selected) lbessard@163: window.RefreshView() lbessard@163: self.VariablePanelIndexer.RefreshVariablePanel(window.GetTagName()) lbessard@163: self.RefreshTitle() lbessard@163: self.RefreshEditMenu() lbessard@235: self.RefreshTypesTree() lbessard@239: self.RefreshInstancesTree() lbessard@239: self.RefreshLibraryTree() lbessard@163: event.Skip() lbessard@163: lbessard@163: def OnRedoMenu(self, event): lbessard@163: self.Controler.LoadNext() lbessard@235: idxs = range(self.TabsOpened.GetPageCount()) lbessard@163: idxs.reverse() lbessard@163: for idx in idxs: lbessard@235: tagname = self.TabsOpened.GetPage(idx).GetTagName() lbessard@249: if self.Controler.GetEditedElement(tagname, self.Debug) is None: lbessard@163: self.VariablePanelIndexer.RemoveVariablePanel(tagname) lbessard@235: self.TabsOpened.DeletePage(idx) lbessard@235: selected = self.TabsOpened.GetSelection() etisserant@0: if selected != -1: lbessard@235: window = self.TabsOpened.GetPage(selected) lbessard@163: window.RefreshView() lbessard@163: self.VariablePanelIndexer.RefreshVariablePanel(window.GetTagName()) lbessard@163: self.RefreshTitle() lbessard@163: self.RefreshEditMenu() lbessard@235: self.RefreshTypesTree() lbessard@239: self.RefreshInstancesTree() lbessard@239: self.RefreshLibraryTree() lbessard@163: event.Skip() lbessard@163: lbessard@163: def OnCutMenu(self, event): lbessard@223: control = self.FindFocus() lbessard@294: if isinstance(control, (Viewer, TextViewer)): lbessard@223: control.Cut() lbessard@294: elif isinstance(control, wx.TextCtrl): lbessard@223: control.ProcessEvent(event) lbessard@163: event.Skip() lbessard@163: lbessard@163: def OnCopyMenu(self, event): lbessard@223: control = self.FindFocus() lbessard@294: if isinstance(control, (Viewer, TextViewer)): lbessard@223: control.Copy() lbessard@294: elif isinstance(control, wx.TextCtrl): lbessard@223: control.ProcessEvent(event) lbessard@163: event.Skip() lbessard@163: lbessard@163: def OnPasteMenu(self, event): lbessard@223: control = self.FindFocus() lbessard@294: if isinstance(control, (Viewer, TextViewer)): lbessard@223: control.Paste() lbessard@294: elif isinstance(control, wx.TextCtrl): lbessard@223: control.ProcessEvent(event) lbessard@163: event.Skip() lbessard@163: lbessard@163: def OnDeleteMenu(self, event): lbessard@163: window = self.FindFocus() lbessard@235: if window == self.TypesTree: lbessard@235: selected = self.TypesTree.GetSelection() lbessard@163: if selected.IsOk(): lbessard@235: type = self.TypesTree.GetPyData(selected) lbessard@163: tagname = "" lbessard@163: if type == ITEM_DATATYPE: lbessard@235: name = self.TypesTree.GetItemText(selected) lbessard@249: if not self.Controler.DataTypeIsUsed(name, self.Debug): lbessard@163: self.Controler.ProjectRemoveDataType(name) lbessard@163: tagname = self.Controler.ComputeDataTypeName(name) lbessard@163: else: lbessard@163: message = wx.MessageDialog(self, "%s is used by one or more POUs. It can't be removed!"%selected, "Error", wx.OK|wx.ICON_ERROR) lbessard@163: message.ShowModal() lbessard@163: message.Destroy() lbessard@163: elif type == ITEM_POU: lbessard@235: name = self.TypesTree.GetItemText(selected) lbessard@249: if not self.Controler.PouIsUsed(name, self.Debug): lbessard@249: self.Controler.ProjectRemovePou(name) lbessard@249: tagname = self.Controler.ComputePouName(name) lbessard@163: else: lbessard@163: message = wx.MessageDialog(self, "%s is used by one or more POUs. It can't be removed!"%selected, "Error", wx.OK|wx.ICON_ERROR) lbessard@163: message.ShowModal() lbessard@163: message.Destroy() lbessard@163: elif type in [ITEM_TRANSITION, ITEM_ACTION]: lbessard@235: item = self.TypesTree.GetItemParent(selected) lbessard@235: item_type = self.TypesTree.GetPyData(item) lbessard@163: while item_type != ITEM_POU: lbessard@235: item = self.TypesTree.GetItemParent(item) lbessard@235: item_type = self.TypesTree.GetPyData(item) lbessard@235: pou_name = self.TypesTree.GetItemText(item) lbessard@163: if type == ITEM_TRANSITION: lbessard@235: transition = self.TypesTree.GetItemText(selected) lbessard@163: self.Controler.ProjectRemovePouTransition(pou_name, transition) lbessard@163: tagname = self.Controler.ComputePouTransitionName(pou_name, transition) lbessard@163: elif type == ITEM_ACTION: lbessard@235: action = self.TypesTree.GetItemText(selected) lbessard@163: self.Controler.ProjectRemovePouAction(pou_name, action) lbessard@163: tagname = self.Controler.ComputePouActionName(pou_name, action) lbessard@163: elif type == ITEM_CONFIGURATION: lbessard@235: name = self.TypesTree.GetItemText(selected) lbessard@163: self.Controler.ProjectRemoveConfiguration(name) lbessard@163: tagname = self.Controler.ComputeConfigurationName(name) lbessard@163: elif type == ITEM_RESOURCE: lbessard@235: resource = self.TypesTree.GetItemText(selected) lbessard@235: item = self.TypesTree.GetItemParent(selected) lbessard@235: item_type = self.TypesTree.GetPyData(item) lbessard@163: while item_type != ITEM_CONFIGURATION: lbessard@235: item = self.TypesTree.GetItemParent(item) lbessard@235: item_type = self.TypesTree.GetPyData(item) lbessard@235: config_name = self.TypesTree.GetItemText(item) lbessard@163: self.Controler.ProjectRemoveConfigurationResource(config_name, resource) lbessard@163: tagname = self.Controler.ComputeConfigurationResourceName(config_name, selected) lbessard@163: idx = self.IsOpened(tagname) lbessard@163: if idx is not None: lbessard@163: self.VariablePanelIndexer.RemoveVariablePanel(tagname) lbessard@235: self.TabsOpened.DeletePage(idx) lbessard@163: self.RefreshTitle() lbessard@163: self.RefreshEditMenu() lbessard@235: self.RefreshTypesTree() lbessard@239: self.RefreshInstancesTree() lbessard@239: self.RefreshLibraryTree() lbessard@163: self.RefreshToolBar() lbessard@163: elif isinstance(window, (Viewer, TextViewer)): lbessard@163: event = wx.KeyEvent(wx.EVT_CHAR._getEvtType()) lbessard@163: event.m_keyCode = wx.WXK_DELETE lbessard@163: window.ProcessEvent(event) lbessard@163: event.Skip() lbessard@163: lbessard@163: lbessard@163: #------------------------------------------------------------------------------- lbessard@163: # Project Editor Panels Management Functions lbessard@163: #------------------------------------------------------------------------------- lbessard@163: etisserant@0: def OnPouSelectedChanged(self, event): lbessard@235: old_selected = self.TabsOpened.GetSelection() lbessard@235: if old_selected >= 0: lbessard@249: if self.Debug: lbessard@249: pass lbessard@249: else: lbessard@249: self.TabsOpened.GetPage(old_selected).ResetBuffer() lbessard@235: selected = event.GetSelection() lbessard@235: if selected >= 0: lbessard@235: window = self.TabsOpened.GetPage(selected) lbessard@260: if not self.Debug: lbessard@249: self.SelectTypesTreeItem(window.GetTagName()) lbessard@249: else: lbessard@249: self.SelectInstancesTreeItem(self.InstancesTree.GetRootItem(), window.GetInstancePath()) lbessard@235: window.RefreshView() lbessard@249: if not self.Debug: lbessard@249: self.VariablePanelIndexer.ChangeVariablePanel(window.GetTagName()) lbessard@235: self.RefreshFileMenu() lbessard@235: self.RefreshEditMenu() lbessard@235: self.RefreshToolBar() etisserant@0: event.Skip() etisserant@0: lbessard@163: def RefreshEditor(self, variablepanel = True): lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@163: if selected != -1: lbessard@235: window = self.TabsOpened.GetPage(selected) lbessard@163: window.RefreshView() lbessard@163: if variablepanel: lbessard@163: self.RefreshVariablePanel(window.GetTagName()) lbessard@163: lbessard@163: def RefreshVariablePanel(self, tagname): lbessard@163: self.VariablePanelIndexer.RefreshVariablePanel(tagname) lbessard@163: lbessard@163: def RefreshEditorNames(self, old_tagname, new_tagname): lbessard@235: for i in xrange(self.TabsOpened.GetPageCount()): lbessard@235: editor = self.TabsOpened.GetPage(i) lbessard@163: if editor.GetTagName() == old_tagname: lbessard@163: editor.SetTagName(new_tagname) lbessard@163: self.VariablePanelIndexer.UpdateVariablePanelTagName(old_tagname, new_tagname) lbessard@163: lbessard@163: def IsOpened(self, tagname): lbessard@235: for idx in xrange(self.TabsOpened.GetPageCount()): lbessard@235: if self.TabsOpened.GetPage(idx).IsViewing(tagname): lbessard@163: return idx lbessard@163: return None lbessard@163: lbessard@163: def RefreshPageTitles(self): lbessard@235: for idx in xrange(self.TabsOpened.GetPageCount()): lbessard@235: window = self.TabsOpened.GetPage(idx) lbessard@163: words = window.GetTagName().split("::") lbessard@203: if words[0] == "P": lbessard@249: pou_type = self.Controler.GetEditedElementType(window.GetTagName(), self.Debug)[1].upper() lbessard@249: pou_body_type = self.Controler.GetEditedElementBodyType(window.GetTagName(), self.Debug) lbessard@292: self.SetPageBitmap(idx, self.GenerateBitmap(pou_type, pou_body_type)) lbessard@203: elif words[0] == "T": lbessard@249: pou_body_type = self.Controler.GetEditedElementBodyType(window.GetTagName(), self.Debug) lbessard@292: self.SetPageBitmap(idx, self.GenerateBitmap("TRANSITION", pou_body_type)) lbessard@203: elif words[0] == "A": lbessard@249: pou_body_type = self.Controler.GetEditedElementBodyType(window.GetTagName(), self.Debug) lbessard@292: self.SetPageBitmap(idx, self.GenerateBitmap("ACTION", pou_body_type)) lbessard@203: elif words[0] == "C": lbessard@292: self.SetPageBitmap(idx, self.GenerateBitmap("CONFIGURATION")) lbessard@203: elif words[0] == "R": lbessard@292: self.SetPageBitmap(idx, self.GenerateBitmap("RESOURCE")) lbessard@203: elif words[0] == "D": lbessard@292: self.SetPageBitmap(idx, self.GenerateBitmap("DATATYPE")) lbessard@249: if self.Debug: lbessard@249: self.TabsOpened.SetPageText(idx, window.GetInstancePath()) lbessard@249: else: lbessard@249: self.TabsOpened.SetPageText(idx, "-".join(words[1:])) lbessard@163: lbessard@163: lbessard@163: #------------------------------------------------------------------------------- lbessard@239: # Types Tree Management Functions lbessard@163: #------------------------------------------------------------------------------- lbessard@163: lbessard@235: def RefreshTypesTree(self): lbessard@249: infos = self.Controler.GetProjectInfos(self.Debug) lbessard@235: root = self.TypesTree.GetRootItem() lbessard@163: if not root.IsOk(): lbessard@235: root = self.TypesTree.AddRoot(infos["name"]) lbessard@235: self.GenerateTypesTreeBranch(root, infos) lbessard@239: self.TypesTree.Expand(root) lbessard@235: lbessard@235: def GenerateTypesTreeBranch(self, root, infos, topology=False): lbessard@163: to_delete = [] lbessard@235: self.TypesTree.SetItemText(root, infos["name"]) lbessard@235: self.TypesTree.SetPyData(root, infos["type"]) lbessard@235: if infos.get("tagname", None) in self.Errors: lbessard@235: self.TypesTree.SetItemBackgroundColour(root, wx.Colour(255, 255, 0)) lbessard@235: self.TypesTree.SetItemTextColour(root, wx.RED) lbessard@235: else: lbessard@235: self.TypesTree.SetItemBackgroundColour(root, wx.WHITE) lbessard@235: self.TypesTree.SetItemTextColour(root, wx.BLACK) lbessard@235: if infos["type"] == ITEM_POU: lbessard@249: self.TypesTree.SetItemImage(root, self.TypesTreeImageDict[self.Controler.GetPouBodyType(infos["name"], self.Debug)]) lbessard@235: else: lbessard@235: self.TypesTree.SetItemImage(root, self.TypesTreeImageDict[infos["type"]]) etisserant@184: lbessard@163: if wx.VERSION >= (2, 6, 0): lbessard@235: item, root_cookie = self.TypesTree.GetFirstChild(root) lbessard@235: else: lbessard@235: item, root_cookie = self.TypesTree.GetFirstChild(root, 0) lbessard@163: for values in infos["values"]: lbessard@163: if not item.IsOk(): lbessard@235: item = self.TypesTree.AppendItem(root, "") lbessard@163: if wx.Platform != '__WXMSW__': lbessard@235: item, root_cookie = self.TypesTree.GetNextChild(root, root_cookie) lbessard@235: self.GenerateTypesTreeBranch(item, values) lbessard@235: item, root_cookie = self.TypesTree.GetNextChild(root, root_cookie) lbessard@163: while item.IsOk(): lbessard@163: to_delete.append(item) lbessard@235: item, root_cookie = self.TypesTree.GetNextChild(root, root_cookie) lbessard@163: for item in to_delete: lbessard@235: self.TypesTree.Delete(item) lbessard@235: lbessard@235: def SelectTypesTreeItem(self, tagname): lbessard@249: if self.TypesTree is not None: lbessard@235: root = self.TypesTree.GetRootItem() lbessard@231: words = tagname.split("::") lbessard@231: if words[0] == "D": lbessard@235: return self.RecursiveTypesTreeItemSelection(root, [(words[1], ITEM_DATATYPE)]) lbessard@231: elif words[0] == "P": lbessard@235: return self.RecursiveTypesTreeItemSelection(root, [(words[1], ITEM_POU)]) lbessard@231: elif words[0] == "T": lbessard@235: return self.RecursiveTypesTreeItemSelection(root, [(words[1], ITEM_POU), (words[2], ITEM_TRANSITION)]) lbessard@231: elif words[0] == "A": lbessard@235: return self.RecursiveTypesTreeItemSelection(root, [(words[1], ITEM_POU), (words[2], ITEM_ACTION)]) lbessard@231: elif words[0] == "C": lbessard@235: return self.RecursiveTypesTreeItemSelection(root, [(words[1], ITEM_CONFIGURATION)]) lbessard@231: elif words[0] == "R": lbessard@235: return self.RecursiveTypesTreeItemSelection(root, [(words[1], ITEM_CONFIGURATION), (words[2], ITEM_RESOURCE)]) lbessard@231: return False lbessard@231: lbessard@235: def RecursiveTypesTreeItemSelection(self, root, items): lbessard@122: found = False lbessard@249: if self.TypesTree is not None: lbessard@122: if wx.VERSION >= (2, 6, 0): lbessard@235: item, root_cookie = self.TypesTree.GetFirstChild(root) lbessard@122: else: lbessard@235: item, root_cookie = self.TypesTree.GetFirstChild(root, 0) lbessard@122: while item.IsOk() and not found: lbessard@235: if (self.TypesTree.GetItemText(item), self.TypesTree.GetPyData(item)) == items[0]: lbessard@122: if len(items) == 1: lbessard@122: self.SelectedItem = item lbessard@235: self.TypesTree.SelectItem(item) lbessard@122: wx.CallAfter(self.ResetSelectedItem) lbessard@122: return True lbessard@122: else: lbessard@235: found = self.RecursiveTypesTreeItemSelection(item, items[1:]) lbessard@122: else: lbessard@235: found = self.RecursiveTypesTreeItemSelection(item, items) lbessard@235: item, root_cookie = self.TypesTree.GetNextChild(root, root_cookie) lbessard@122: return found lbessard@122: lbessard@235: def OnTypesTreeBeginDrag(self, event): lbessard@131: if wx.Platform == '__WXMSW__': lbessard@134: self.SelectedItem = event.GetItem() lbessard@235: if self.SelectedItem is not None and self.TypesTree.GetPyData(self.SelectedItem) == ITEM_POU: lbessard@235: block_name = self.TypesTree.GetItemText(self.SelectedItem) lbessard@249: block_type = self.Controler.GetPouType(block_name, self.Debug) lbessard@53: if block_type != "program": lbessard@64: data = wx.TextDataObject(str((block_name, block_type, ""))) lbessard@235: dragSource = wx.DropSource(self.TypesTree) lbessard@53: dragSource.SetData(data) lbessard@53: dragSource.DoDragDrop() lbessard@122: self.ResetSelectedItem() lbessard@7: lbessard@235: def OnTypesTreeItemBeginEdit(self, event): lbessard@163: selected = event.GetItem() lbessard@235: if self.TypesTree.GetPyData(selected) in ITEMS_UNEDITABLE: lbessard@163: event.Veto() lbessard@163: else: lbessard@163: event.Skip() lbessard@107: lbessard@235: def OnTypesTreeItemEndEdit(self, event): lbessard@6: message = None lbessard@6: abort = False etisserant@0: new_name = event.GetLabel() etisserant@0: if new_name != "": lbessard@6: if not TestIdentifier(new_name): lbessard@6: message = "\"%s\" is not a valid identifier!"%new_name lbessard@6: elif new_name.upper() in IEC_KEYWORDS: lbessard@6: message = "\"%s\" is a keyword. It can't be used!"%new_name lbessard@6: else: etisserant@0: item = event.GetItem() lbessard@235: old_name = self.TypesTree.GetItemText(item) lbessard@235: itemtype = self.TypesTree.GetPyData(item) etisserant@0: if itemtype == ITEM_PROJECT: lbessard@56: self.Controler.SetProjectProperties(name = new_name) lbessard@125: elif itemtype == ITEM_DATATYPE: lbessard@249: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectDataTypeNames(self.Debug) if name != old_name]: lbessard@125: message = "\"%s\" data type already exists!"%new_name lbessard@125: abort = True lbessard@125: if not abort: lbessard@125: self.Controler.ChangeDataTypeName(old_name, new_name) lbessard@145: self.RefreshEditorNames(self.Controler.ComputeDataTypeName(old_name), lbessard@145: self.Controler.ComputeDataTypeName(new_name)) lbessard@125: self.RefreshPageTitles() etisserant@0: elif itemtype == ITEM_POU: lbessard@249: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug) if name != old_name]: lbessard@6: message = "\"%s\" pou already exists!"%new_name lbessard@6: abort = True lbessard@249: elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(debug = self.Debug)]: lbessard@64: messageDialog = wx.MessageDialog(self, "A variable is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?"%new_name, "Error", wx.YES_NO|wx.ICON_QUESTION) lbessard@64: if messageDialog.ShowModal() == wx.ID_NO: lbessard@6: abort = True lbessard@6: messageDialog.Destroy() lbessard@6: if not abort: lbessard@6: self.Controler.ChangePouName(old_name, new_name) lbessard@145: self.RefreshEditorNames(self.Controler.ComputePouName(old_name), lbessard@145: self.Controler.ComputePouName(new_name)) lbessard@121: self.RefreshPageTitles() etisserant@0: elif itemtype == ITEM_TRANSITION: lbessard@235: parent = self.TypesTree.GetItemParent(item) lbessard@235: parent_type = self.TypesTree.GetPyData(parent) lbessard@107: while parent_type != ITEM_POU: lbessard@235: parent = self.TypesTree.GetItemParent(parent) lbessard@235: parent_type = self.TypesTree.GetPyData(parent) lbessard@235: pou_name = self.TypesTree.GetItemText(parent) lbessard@249: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]: lbessard@6: message = "A pou with \"%s\" as name exists!"%new_name lbessard@249: elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name, self.Debug) if name != old_name]: lbessard@6: message = "A variable with \"%s\" as name already exists in this pou!"%new_name lbessard@6: else: lbessard@6: self.Controler.ChangePouTransitionName(pou_name, old_name, new_name) lbessard@145: self.RefreshEditorNames(self.Controler.ComputePouTransitionName(pou_name, old_name), lbessard@145: self.Controler.ComputePouTransitionName(pou_name, new_name)) lbessard@121: self.RefreshPageTitles() etisserant@0: elif itemtype == ITEM_ACTION: lbessard@235: parent = self.TypesTree.GetItemParent(item) lbessard@235: parent_type = self.TypesTree.GetPyData(parent) lbessard@107: while parent_type != ITEM_POU: lbessard@235: parent = self.TypesTree.GetItemParent(parent) lbessard@235: parent_type = self.TypesTree.GetPyData(parent) lbessard@235: pou_name = self.TypesTree.GetItemText(parent) lbessard@249: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]: lbessard@6: message = "A pou with \"%s\" as name exists!"%new_name lbessard@249: elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name, self.Debug) if name != old_name]: lbessard@6: message = "A variable with \"%s\" as name already exists in this pou!"%new_name lbessard@6: else: lbessard@6: self.Controler.ChangePouActionName(pou_name, old_name, new_name) lbessard@145: self.RefreshEditorNames(self.Controler.ComputePouActionName(pou_name, old_name), lbessard@145: self.Controler.ComputePouActionName(pou_name, new_name)) lbessard@121: self.RefreshPageTitles() lbessard@107: elif itemtype == ITEM_CONFIGURATION: lbessard@249: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames(self.Debug) if name != old_name]: lbessard@107: message = "\"%s\" config already exists!"%new_name lbessard@107: abort = True lbessard@249: elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]: lbessard@107: messageDialog = wx.MessageDialog(self, "A pou is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?"%new_name, "Error", wx.YES_NO|wx.ICON_QUESTION) lbessard@107: if messageDialog.ShowModal() == wx.ID_NO: lbessard@107: abort = True lbessard@107: messageDialog.Destroy() lbessard@249: elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(debug = self.Debug)]: lbessard@107: messageDialog = wx.MessageDialog(self, "A variable is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?"%new_name, "Error", wx.YES_NO|wx.ICON_QUESTION) lbessard@107: if messageDialog.ShowModal() == wx.ID_NO: lbessard@107: abort = True lbessard@107: messageDialog.Destroy() lbessard@107: if not abort: lbessard@107: self.Controler.ChangeConfigurationName(old_name, new_name) lbessard@145: self.RefreshEditorNames(self.Controler.ComputeConfigurationName(old_name), lbessard@145: self.Controler.ComputeConfigurationName(new_name)) lbessard@121: self.RefreshPageTitles() lbessard@107: elif itemtype == ITEM_RESOURCE: lbessard@235: parent = self.TypesTree.GetItemParent(item) lbessard@235: parent_type = self.TypesTree.GetPyData(parent) lbessard@107: while parent_type != ITEM_CONFIGURATION: lbessard@235: parent = self.TypesTree.GetItemParent(parent) lbessard@235: parent_type = self.TypesTree.GetPyData(parent) lbessard@235: config_name = self.TypesTree.GetItemText(parent) lbessard@249: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames(self.Debug)]: lbessard@107: message = "\"%s\" config already exists!"%new_name lbessard@107: abort = True lbessard@249: elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]: lbessard@107: messageDialog = wx.MessageDialog(self, "A pou is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?"%new_name, "Error", wx.YES_NO|wx.ICON_QUESTION) lbessard@107: if messageDialog.ShowModal() == wx.ID_NO: lbessard@107: abort = True lbessard@107: messageDialog.Destroy() lbessard@249: elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(debug = self.Debug)]: lbessard@107: messageDialog = wx.MessageDialog(self, "A variable is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?"%new_name, "Error", wx.YES_NO|wx.ICON_QUESTION) lbessard@107: if messageDialog.ShowModal() == wx.ID_NO: lbessard@107: abort = True lbessard@107: messageDialog.Destroy() lbessard@107: if not abort: lbessard@107: self.Controler.ChangeConfigurationResourceName(config_name, old_name, new_name) lbessard@145: self.RefreshEditorNames(self.Controler.ComputeConfigurationResourceName(config_name, old_name), lbessard@145: self.Controler.ComputeConfigurationResourceName(config_name, new_name)) lbessard@121: self.RefreshPageTitles() lbessard@6: if message or abort: lbessard@6: if message: lbessard@64: messageDialog = wx.MessageDialog(self, message, "Error", wx.OK|wx.ICON_ERROR) lbessard@6: messageDialog.ShowModal() lbessard@6: messageDialog.Destroy() etisserant@0: item = event.GetItem() lbessard@235: wx.CallAfter(self.TypesTree.EditLabel, item) etisserant@0: event.Veto() lbessard@6: else: lbessard@235: wx.CallAfter(self.RefreshTypesTree) lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@121: if selected != -1: lbessard@235: self.TabsOpened.GetPage(selected).RefreshView() lbessard@6: event.Skip() etisserant@0: lbessard@235: def OnTypesTreeItemActivated(self, event): etisserant@0: selected = event.GetItem() lbessard@235: if self.TypesTree.IsExpanded(selected): lbessard@235: self.TypesTree.Collapse(selected) lbessard@235: else: lbessard@235: self.TypesTree.Expand(selected) lbessard@235: name = self.TypesTree.GetItemText(selected) lbessard@235: data = self.TypesTree.GetPyData(selected) etisserant@0: if name == "Properties": lbessard@27: self.ShowProperties() lbessard@125: if data == ITEM_DATATYPE: lbessard@125: self.EditProjectElement(data, self.Controler.ComputeDataTypeName(name)) lbessard@125: elif data == ITEM_POU: lbessard@121: self.EditProjectElement(data, self.Controler.ComputePouName(name)) lbessard@121: elif data == ITEM_CONFIGURATION: lbessard@121: self.EditProjectElement(data, self.Controler.ComputeConfigurationName(name)) lbessard@102: elif data == ITEM_RESOURCE: lbessard@235: item = self.TypesTree.GetItemParent(selected) lbessard@235: item_type = self.TypesTree.GetPyData(item) lbessard@102: while item_type != ITEM_CONFIGURATION: lbessard@235: item = self.TypesTree.GetItemParent(item) lbessard@235: item_type = self.TypesTree.GetPyData(item) lbessard@235: config_name = self.TypesTree.GetItemText(item) lbessard@121: self.EditProjectElement(data, self.Controler.ComputeConfigurationResourceName(config_name, name)) lbessard@102: elif data in [ITEM_TRANSITION, ITEM_ACTION]: lbessard@235: item = self.TypesTree.GetItemParent(selected) lbessard@235: item_type = self.TypesTree.GetPyData(item) lbessard@102: while item_type != ITEM_POU: lbessard@235: item = self.TypesTree.GetItemParent(item) lbessard@235: item_type = self.TypesTree.GetPyData(item) lbessard@235: pou_name = self.TypesTree.GetItemText(item) lbessard@121: if data == ITEM_TRANSITION: lbessard@121: tagname = self.Controler.ComputePouTransitionName(pou_name, name) lbessard@121: elif data == ITEM_ACTION: lbessard@121: tagname = self.Controler.ComputePouActionName(pou_name, name) lbessard@121: self.EditProjectElement(data, tagname) lbessard@129: event.Skip() lbessard@102: lbessard@235: def TypesTreeItemSelect(self, select_item): lbessard@235: name = self.TypesTree.GetItemText(select_item) lbessard@235: data = self.TypesTree.GetPyData(select_item) lbessard@131: if data == ITEM_DATATYPE: lbessard@131: self.EditProjectElement(data, self.Controler.ComputeDataTypeName(name), True) lbessard@131: elif data == ITEM_POU: lbessard@131: self.EditProjectElement(data, self.Controler.ComputePouName(name), True) lbessard@131: elif data == ITEM_CONFIGURATION: lbessard@131: self.EditProjectElement(data, self.Controler.ComputeConfigurationName(name), True) lbessard@131: elif data == ITEM_RESOURCE: lbessard@235: item = self.TypesTree.GetItemParent(select_item) lbessard@235: item_type = self.TypesTree.GetPyData(item) lbessard@131: while item_type != ITEM_CONFIGURATION: lbessard@235: item = self.TypesTree.GetItemParent(item) lbessard@235: item_type = self.TypesTree.GetPyData(item) lbessard@235: config_name = self.TypesTree.GetItemText(item) lbessard@131: self.EditProjectElement(data, self.Controler.ComputeConfigurationResourceName(config_name, name), True) lbessard@131: elif data in [ITEM_TRANSITION, ITEM_ACTION]: lbessard@235: item = self.TypesTree.GetItemParent(select_item) lbessard@235: item_type = self.TypesTree.GetPyData(item) lbessard@131: while item_type != ITEM_POU: lbessard@235: item = self.TypesTree.GetItemParent(item) lbessard@235: item_type = self.TypesTree.GetPyData(item) lbessard@235: pou_name = self.TypesTree.GetItemText(item) lbessard@131: if data == ITEM_TRANSITION: lbessard@131: tagname = self.Controler.ComputePouTransitionName(pou_name, name) lbessard@131: elif data == ITEM_ACTION: lbessard@131: tagname = self.Controler.ComputePouActionName(pou_name, name) lbessard@131: self.EditProjectElement(data, tagname, True) lbessard@131: lbessard@235: def OnTypesTreeLeftUp(self, event): lbessard@122: if self.SelectedItem is not None: lbessard@235: self.TypesTree.SelectItem(self.SelectedItem) lbessard@235: self.TypesTreeItemSelect(self.SelectedItem) lbessard@122: wx.CallAfter(self.ResetSelectedItem) lbessard@122: event.Skip() lbessard@122: lbessard@235: def OnTypesTreeItemSelected(self, event): lbessard@235: self.TypesTreeItemSelect(event.GetItem()) lbessard@235: event.Skip() lbessard@235: lbessard@235: def OnTypesTreeItemChanging(self, event): lbessard@235: if self.TypesTree.GetPyData(event.GetItem()) not in ITEMS_UNEDITABLE and self.SelectedItem is None: lbessard@122: self.SelectedItem = event.GetItem() lbessard@122: event.Veto() lbessard@122: else: lbessard@122: event.Skip() lbessard@121: lbessard@121: def EditProjectElement(self, elementtype, tagname, onlyopened = False): lbessard@121: openedidx = self.IsOpened(tagname) lbessard@121: if openedidx is not None: lbessard@235: old_selected = self.TabsOpened.GetSelection() lbessard@121: if old_selected != openedidx: lbessard@121: if old_selected >= 0: lbessard@235: self.TabsOpened.GetPage(old_selected).ResetBuffer() lbessard@235: self.TabsOpened.SetSelection(openedidx) lbessard@235: self.TabsOpened.GetPage(openedidx).RefreshView() lbessard@121: self.VariablePanelIndexer.ChangeVariablePanel(tagname) lbessard@121: self.RefreshPageTitles() lbessard@121: self.RefreshFileMenu() lbessard@121: self.RefreshEditMenu() lbessard@121: self.RefreshToolBar() lbessard@121: elif not onlyopened: lbessard@125: if elementtype == ITEM_CONFIGURATION: lbessard@235: new_window = ConfigurationEditor(self.TabsOpened, tagname, self, self.Controler) lbessard@235: self.TabsOpened.AddPage(new_window, "") lbessard@125: self.VariablePanelIndexer.AddVariablePanel(tagname, "config") lbessard@125: elif elementtype == ITEM_RESOURCE: lbessard@235: new_window = ResourceEditor(self.TabsOpened, tagname, self, self.Controler) lbessard@235: self.TabsOpened.AddPage(new_window, "") lbessard@125: self.VariablePanelIndexer.AddVariablePanel(tagname, "resource") lbessard@125: elif elementtype in [ITEM_POU, ITEM_TRANSITION, ITEM_ACTION]: lbessard@249: bodytype = self.Controler.GetEditedElementBodyType(tagname, self.Debug) lbessard@235: if bodytype == "FBD": lbessard@235: new_window = Viewer(self.TabsOpened, tagname, self, self.Controler) lbessard@235: new_window.RefreshScaling(False) lbessard@235: elif bodytype == "LD": lbessard@235: new_window = LD_Viewer(self.TabsOpened, tagname, self, self.Controler) lbessard@235: new_window.RefreshScaling(False) lbessard@235: elif bodytype == "SFC": lbessard@235: new_window = SFC_Viewer(self.TabsOpened, tagname, self, self.Controler) lbessard@235: new_window.RefreshScaling(False) lbessard@235: else: lbessard@235: new_window = TextViewer(self.TabsOpened, tagname, self, self.Controler) lbessard@249: new_window.SetTextSyntax(bodytype) lbessard@235: if bodytype == "IL": lbessard@235: new_window.SetKeywords(IL_KEYWORDS) lbessard@235: else: lbessard@235: new_window.SetKeywords(ST_KEYWORDS) lbessard@235: self.TabsOpened.AddPage(new_window, "") lbessard@121: words = tagname.split("::") lbessard@249: self.VariablePanelIndexer.AddVariablePanel(tagname, self.Controler.GetPouType(words[1], self.Debug)) lbessard@235: elif elementtype == ITEM_DATATYPE: lbessard@235: new_window = DataTypeEditor(self.TabsOpened, tagname, self, self.Controler) lbessard@235: self.TabsOpened.AddPage(new_window, "") lbessard@121: self.VariablePanelIndexer.ChangeVariablePanel(tagname) lbessard@121: openedidx = self.IsOpened(tagname) lbessard@235: old_selected = self.TabsOpened.GetSelection() lbessard@121: if old_selected != openedidx: lbessard@121: if old_selected >= 0: lbessard@235: self.TabsOpened.GetPage(old_selected).ResetBuffer() lbessard@235: for i in xrange(self.TabsOpened.GetPageCount()): lbessard@235: window = self.TabsOpened.GetPage(i) lbessard@121: if window.GetTagName() == tagname: lbessard@235: self.TabsOpened.SetSelection(i) lbessard@114: window.RefreshView() lbessard@129: window.SetFocus() lbessard@121: self.RefreshPageTitles() lbessard@114: self.RefreshFileMenu() lbessard@114: self.RefreshEditMenu() lbessard@114: self.RefreshToolBar() etisserant@0: lbessard@235: def OnTypesTreeRightUp(self, event): lbessard@159: if wx.Platform == '__WXMSW__': lbessard@163: item = event.GetItem() lbessard@163: else: lbessard@235: item = self.TypesTree.GetSelection() lbessard@235: name = self.TypesTree.GetItemText(item) lbessard@235: type = self.TypesTree.GetPyData(item) lbessard@163: if type == ITEM_POU: lbessard@163: menu = wx.Menu(title='') lbessard@249: if self.Controler.GetPouBodyType(name, self.Debug) == "SFC": lbessard@163: new_id = wx.NewId() lbessard@163: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Add Transition") lbessard@163: self.Bind(wx.EVT_MENU, self.GenerateAddTransitionFunction(name), id=new_id) lbessard@163: new_id = wx.NewId() lbessard@163: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Add Action") lbessard@163: self.Bind(wx.EVT_MENU, self.GenerateAddActionFunction(name), id=new_id) lbessard@163: menu.AppendSeparator() lbessard@163: new_id = wx.NewId() lbessard@275: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Create A New POU From") lbessard@274: self.Bind(wx.EVT_MENU, self.OnCreatePouFromMenu, id=new_id) lbessard@275: pou_type = self.Controler.GetPouType(name, self.Debug) lbessard@275: if pou_type in ["function", "functionBlock"]: lbessard@275: change_menu = wx.Menu(title='') lbessard@275: if pou_type == "function": lbessard@275: new_id = wx.NewId() lbessard@275: AppendMenu(change_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Function Block") lbessard@275: self.Bind(wx.EVT_MENU, self.GenerateChangePouTypeFunction(name, "functionBlock"), id=new_id) lbessard@275: new_id = wx.NewId() lbessard@275: AppendMenu(change_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Program") lbessard@275: self.Bind(wx.EVT_MENU, self.GenerateChangePouTypeFunction(name, "program"), id=new_id) lbessard@275: menu.AppendMenu(wx.NewId(), "Change POU Type To", change_menu) lbessard@274: new_id = wx.NewId() lbessard@163: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Delete") lbessard@163: self.Bind(wx.EVT_MENU, self.OnRemovePouMenu, id=new_id) lbessard@163: self.PopupMenu(menu) lbessard@163: elif type == ITEM_CONFIGURATION: lbessard@163: menu = wx.Menu(title='') lbessard@163: new_id = wx.NewId() lbessard@163: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Add Resource") lbessard@163: self.Bind(wx.EVT_MENU, self.GenerateAddResourceFunction(name), id=new_id) lbessard@163: new_id = wx.NewId() lbessard@163: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Delete") lbessard@163: self.Bind(wx.EVT_MENU, self.OnRemoveConfigurationMenu, id=new_id) lbessard@163: self.PopupMenu(menu) lbessard@163: elif type in [ITEM_DATATYPE, ITEM_TRANSITION, ITEM_ACTION, ITEM_RESOURCE]: lbessard@163: menu = wx.Menu(title='') lbessard@163: new_id = wx.NewId() lbessard@163: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Delete") lbessard@163: if type == ITEM_DATATYPE: lbessard@163: self.Bind(wx.EVT_MENU, self.OnRemoveDataTypeMenu, id=new_id) lbessard@163: elif type == ITEM_TRANSITION: lbessard@163: self.Bind(wx.EVT_MENU, self.OnRemoveTransitionMenu, id=new_id) lbessard@163: elif type == ITEM_ACTION: lbessard@163: self.Bind(wx.EVT_MENU, self.OnRemoveActionMenu, id=new_id) lbessard@163: elif type == ITEM_RESOURCE: lbessard@163: self.Bind(wx.EVT_MENU, self.OnRemoveResourceMenu, id=new_id) lbessard@163: self.PopupMenu(menu) etisserant@184: elif type in ITEMS_UNEDITABLE: lbessard@163: if name == "Data Types": lbessard@163: menu = wx.Menu(title='') lbessard@163: new_id = wx.NewId() lbessard@163: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Add DataType") lbessard@163: self.Bind(wx.EVT_MENU, self.OnAddDataTypeMenu, id=new_id) lbessard@163: self.PopupMenu(menu) lbessard@163: elif name in ["Functions", "Function Blocks", "Programs"]: lbessard@163: menu = wx.Menu(title='') lbessard@163: new_id = wx.NewId() lbessard@163: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Add Pou") lbessard@163: self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction({"Functions" : "function", "Function Blocks" : "functionBlock", "Programs" : "program"}[name]), id=new_id) lbessard@163: self.PopupMenu(menu) lbessard@163: elif name == "Configurations": lbessard@163: menu = wx.Menu(title='') lbessard@163: new_id = wx.NewId() lbessard@163: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Add Configuration") lbessard@163: self.Bind(wx.EVT_MENU, self.OnAddConfigurationMenu, id=new_id) lbessard@163: self.PopupMenu(menu) lbessard@163: elif name == "Transitions": lbessard@163: menu = wx.Menu(title='') lbessard@163: new_id = wx.NewId() lbessard@163: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Add Transition") lbessard@235: parent = self.TypesTree.GetItemParent(item) lbessard@235: parent_type = self.TypesTree.GetPyData(parent) lbessard@163: while parent_type != ITEM_POU: lbessard@235: parent = self.TypesTree.GetItemParent(parent) lbessard@235: parent_type = self.TypesTree.GetPyData(parent) lbessard@235: self.Bind(wx.EVT_MENU, self.GenerateAddTransitionFunction(self.TypesTree.GetItemText(parent)), id=new_id) lbessard@163: self.PopupMenu(menu) lbessard@163: elif name == "Actions": lbessard@163: menu = wx.Menu(title='') lbessard@163: new_id = wx.NewId() lbessard@163: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Add Action") lbessard@235: parent = self.TypesTree.GetItemParent(item) lbessard@235: parent_type = self.TypesTree.GetPyData(parent) lbessard@163: while parent_type != ITEM_POU: lbessard@235: parent = self.TypesTree.GetItemParent(parent) lbessard@235: parent_type = self.TypesTree.GetPyData(parent) lbessard@235: self.Bind(wx.EVT_MENU, self.GenerateAddActionFunction(self.TypesTree.GetItemText(parent)), id=new_id) lbessard@163: self.PopupMenu(menu) lbessard@163: elif name == "Resources": lbessard@163: menu = wx.Menu(title='') lbessard@163: new_id = wx.NewId() lbessard@163: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Add Resource") lbessard@235: parent = self.TypesTree.GetItemParent(item) lbessard@235: parent_type = self.TypesTree.GetPyData(parent) lbessard@163: while parent_type != ITEM_CONFIGURATION: lbessard@235: parent = self.TypesTree.GetItemParent(parent) lbessard@235: parent_type = self.TypesTree.GetPyData(parent) lbessard@235: self.Bind(wx.EVT_MENU, self.GenerateAddResourceFunction(self.TypesTree.GetItemText(parent)), id=new_id) lbessard@163: self.PopupMenu(menu) lbessard@163: event.Skip() lbessard@163: lbessard@163: lbessard@163: #------------------------------------------------------------------------------- lbessard@239: # Instances Tree Management Functions lbessard@235: #------------------------------------------------------------------------------- lbessard@235: lbessard@235: def RefreshInstancesTree(self): lbessard@249: infos = self.Controler.GetProjectTopology(self.Debug) lbessard@235: root = self.InstancesTree.GetRootItem() lbessard@235: if not root.IsOk(): lbessard@235: root = self.InstancesTree.AddRoot(infos["name"]) lbessard@235: self.GenerateInstancesTreeBranch(root, infos) lbessard@239: self.InstancesTree.Expand(root) lbessard@235: lbessard@235: def GenerateInstancesTreeBranch(self, root, infos): lbessard@235: to_delete = [] lbessard@235: if infos.get("elmt_type", None) is not None: lbessard@249: self.InstancesTree.SetItemText(root, "%s (%s)"%(infos["name"], infos["elmt_type"])) lbessard@235: else: lbessard@235: self.InstancesTree.SetItemText(root, infos["name"]) lbessard@249: self.InstancesTree.SetPyData(root, (infos["type"], infos.get("tagname", None))) lbessard@235: self.InstancesTree.SetItemImage(root, self.InstancesTreeImageDict[infos["type"]]) lbessard@235: lbessard@235: if wx.VERSION >= (2, 6, 0): lbessard@235: item, root_cookie = self.InstancesTree.GetFirstChild(root) lbessard@235: else: lbessard@235: item, root_cookie = self.InstancesTree.GetFirstChild(root, 0) lbessard@235: for values in infos["values"]: lbessard@235: if not item.IsOk(): lbessard@235: item = self.InstancesTree.AppendItem(root, "") lbessard@235: if wx.Platform != '__WXMSW__': lbessard@235: item, root_cookie = self.InstancesTree.GetNextChild(root, root_cookie) lbessard@235: self.GenerateInstancesTreeBranch(item, values) lbessard@235: item, root_cookie = self.InstancesTree.GetNextChild(root, root_cookie) lbessard@235: while item.IsOk(): lbessard@235: to_delete.append(item) lbessard@235: item, root_cookie = self.InstancesTree.GetNextChild(root, root_cookie) lbessard@235: for item in to_delete: lbessard@235: self.InstancesTree.Delete(item) lbessard@235: lbessard@249: def OnInstancesTreeBeginDrag(self, event): lbessard@249: selected_item = event.GetItem() lbessard@249: selected_infos = self.InstancesTree.GetPyData(selected_item) lbessard@249: if selected_item is not None and selected_infos[0] in ITEMS_VARIABLE: lbessard@249: var_path = self.InstancesTree.GetItemText(selected_item).split(" (")[0] lbessard@249: parent_item = self.InstancesTree.GetItemParent(selected_item) lbessard@249: while self.InstancesTree.GetPyData(parent_item)[0] != ITEM_PROJECT: lbessard@249: parent_name = self.InstancesTree.GetItemText(parent_item).split(" (")[0] lbessard@249: var_path = "%s.%s"%(parent_name, var_path) lbessard@249: parent_item = self.InstancesTree.GetItemParent(parent_item) lbessard@249: data = wx.TextDataObject(str((var_path, "debug"))) lbessard@249: dragSource = wx.DropSource(self.InstancesTree) lbessard@249: dragSource.SetData(data) lbessard@249: dragSource.DoDragDrop() lbessard@249: event.Skip() lbessard@249: lbessard@249: def OnInstancesTreeItemActivated(self, event): lbessard@249: selected_item = event.GetItem() lbessard@249: selected_infos = self.InstancesTree.GetPyData(selected_item) lbessard@249: if selected_item is not None and selected_infos[0] in [ITEM_FUNCTIONBLOCK, ITEM_PROGRAM, ITEM_TRANSITION, ITEM_ACTION]: lbessard@249: instance_path = self.InstancesTree.GetItemText(selected_item).split(" (")[0] lbessard@249: parent_item = self.InstancesTree.GetItemParent(selected_item) lbessard@249: while self.InstancesTree.GetPyData(parent_item)[0] != ITEM_PROJECT: lbessard@249: parent_name = self.InstancesTree.GetItemText(parent_item).split(" (")[0] lbessard@249: instance_path = "%s.%s"%(parent_name, instance_path) lbessard@249: parent_item = self.InstancesTree.GetItemParent(parent_item) lbessard@249: openedidx = self.IsOpened(instance_path) lbessard@249: if openedidx is not None: lbessard@249: old_selected = self.TabsOpened.GetSelection() lbessard@249: if old_selected != openedidx: lbessard@249: if old_selected >= 0: lbessard@249: self.TabsOpened.GetPage(old_selected).ResetBuffer() lbessard@249: self.TabsOpened.SetSelection(openedidx) lbessard@249: self.TabsOpened.GetPage(openedidx).RefreshView() lbessard@249: elif selected_infos[1] is not None: lbessard@249: bodytype = self.Controler.GetEditedElementBodyType(selected_infos[1], self.Debug) lbessard@249: if bodytype == "FBD": lbessard@249: new_window = Viewer(self.TabsOpened, selected_infos[1], self, self.Controler, True, instance_path) lbessard@249: new_window.RefreshScaling(False) lbessard@249: elif bodytype == "LD": lbessard@249: new_window = LD_Viewer(self.TabsOpened, selected_infos[1], self, self.Controler, True, instance_path) lbessard@249: new_window.RefreshScaling(False) lbessard@249: elif bodytype == "SFC": lbessard@249: new_window = SFC_Viewer(self.TabsOpened, selected_infos[1], self, self.Controler, True, instance_path) lbessard@249: new_window.RefreshScaling(False) lbessard@249: else: lbessard@249: new_window = TextViewer(self.TabsOpened, selected_infos[1], self, self.Controler, True, instance_path) lbessard@249: new_window.SetTextSyntax(bodytype) lbessard@249: if bodytype == "IL": lbessard@249: new_window.SetKeywords(IL_KEYWORDS) lbessard@249: else: lbessard@249: new_window.SetKeywords(ST_KEYWORDS) lbessard@249: self.TabsOpened.AddPage(new_window, "") lbessard@249: new_window.RefreshView() lbessard@249: new_window.SetFocus() lbessard@249: self.RefreshPageTitles() lbessard@249: event.Skip() lbessard@249: lbessard@249: def SelectInstancesTreeItem(self, root, instancepath): lbessard@249: found = False lbessard@249: if self.InstancesTree is not None: lbessard@262: paths = instancepath.split(".", 1) lbessard@249: if wx.VERSION >= (2, 6, 0): lbessard@249: item, root_cookie = self.InstancesTree.GetFirstChild(root) lbessard@249: else: lbessard@249: item, root_cookie = self.InstancesTree.GetFirstChild(root, 0) lbessard@249: while item.IsOk() and not found: lbessard@262: name = self.InstancesTree.GetItemText(item).split(" (")[0] lbessard@262: if name == paths[0]: lbessard@249: if len(paths) == 1: lbessard@249: self.InstancesTree.SelectItem(item) lbessard@249: return True lbessard@249: else: lbessard@262: found = self.SelectInstancesTreeItem(item, paths[1]) lbessard@262: item, root_cookie = self.InstancesTree.GetNextChild(root, root_cookie) lbessard@249: return found lbessard@249: lbessard@235: #------------------------------------------------------------------------------- lbessard@239: # Library Tree Management Functions lbessard@239: #------------------------------------------------------------------------------- lbessard@239: lbessard@239: def RefreshLibraryTree(self): lbessard@249: if not self.Debug: lbessard@249: to_delete = [] lbessard@249: blocktypes = self.Controler.GetBlockTypes(debug = self.Debug) lbessard@249: root = self.LibraryTree.GetRootItem() lbessard@249: if not root.IsOk(): lbessard@249: if wx.Platform == '__WXMSW__': lbessard@249: root = self.LibraryTree.AddRoot("Block Types") lbessard@249: self.LibraryTree.SetPyData(root, {"type" : CATEGORY}) lbessard@249: else: lbessard@249: root = self.LibraryTree.AddRoot("") lbessard@249: if wx.VERSION >= (2, 6, 0): lbessard@249: category_item, root_cookie = self.LibraryTree.GetFirstChild(root) lbessard@245: else: lbessard@249: category_item, root_cookie = self.LibraryTree.GetFirstChild(root, 0) lbessard@249: for category in blocktypes: lbessard@249: if not category_item.IsOk(): lbessard@249: category_item = self.LibraryTree.AppendItem(root, category["name"]) lbessard@239: if wx.Platform != '__WXMSW__': lbessard@249: category_item, root_cookie = self.LibraryTree.GetNextChild(root, root_cookie) lbessard@239: else: lbessard@249: self.LibraryTree.SetItemText(category_item, category["name"]) lbessard@249: self.LibraryTree.SetPyData(category_item, {"type" : CATEGORY}) lbessard@249: if wx.VERSION >= (2, 6, 0): lbessard@249: blocktype_item, category_cookie = self.LibraryTree.GetFirstChild(category_item) lbessard@249: else: lbessard@249: blocktype_item, category_cookie = self.LibraryTree.GetFirstChild(category_item, 0) lbessard@249: for blocktype in category["list"]: lbessard@249: if not blocktype_item.IsOk(): lbessard@249: blocktype_item = self.LibraryTree.AppendItem(category_item, blocktype["name"]) lbessard@249: if wx.Platform != '__WXMSW__': lbessard@249: blocktype_item, category_cookie = self.LibraryTree.GetNextChild(category_item, category_cookie) lbessard@249: else: lbessard@249: self.LibraryTree.SetItemText(blocktype_item, blocktype["name"]) lbessard@249: self.LibraryTree.SetPyData(blocktype_item, {"type" : BLOCK, "block_type" : blocktype["type"], "inputs" : tuple([type for name, type, modifier in blocktype["inputs"]])}) lbessard@249: blocktype_item, category_cookie = self.LibraryTree.GetNextChild(category_item, category_cookie) lbessard@249: while blocktype_item.IsOk(): lbessard@249: to_delete.append(blocktype_item) lbessard@249: blocktype_item, category_cookie = self.LibraryTree.GetNextChild(category_item, category_cookie) lbessard@249: category_item, root_cookie = self.LibraryTree.GetNextChild(root, root_cookie) lbessard@249: while category_item.IsOk(): lbessard@249: to_delete.append(category_item) lbessard@249: category_item, root_cookie = self.LibraryTree.GetNextChild(root, root_cookie) lbessard@249: for item in to_delete: lbessard@249: self.LibraryTree.Delete(item) lbessard@249: if wx.Platform == '__WXMSW__': lbessard@249: self.LibraryTree.Expand(root) lbessard@239: lbessard@239: def OnLibraryTreeItemSelected(self, event): lbessard@239: selected = event.GetItem() lbessard@239: pydata = self.LibraryTree.GetPyData(selected) lbessard@239: if pydata["type"] != CATEGORY: lbessard@249: blocktype = self.Controler.GetBlockType(self.LibraryTree.GetItemText(selected), pydata["inputs"], debug = self.Debug) lbessard@239: if blocktype: lbessard@239: self.LibraryComment.SetValue(blocktype["comment"]) lbessard@239: else: lbessard@239: self.LibraryComment.SetValue("") lbessard@239: else: lbessard@239: self.LibraryComment.SetValue("") lbessard@239: event.Skip() lbessard@239: lbessard@239: def OnLibraryTreeBeginDrag(self, event): lbessard@239: selected = event.GetItem() lbessard@239: pydata = self.LibraryTree.GetPyData(selected) lbessard@239: if selected is not None and pydata["type"] == BLOCK: lbessard@239: data = wx.TextDataObject(str((self.LibraryTree.GetItemText(selected), lbessard@239: pydata["block_type"], "", pydata["inputs"]))) lbessard@239: dragSource = wx.DropSource(self.LibraryTree) lbessard@239: dragSource.SetData(data) lbessard@239: dragSource.DoDragDrop() lbessard@239: lbessard@239: #------------------------------------------------------------------------------- lbessard@163: # ToolBar Management Functions lbessard@163: #------------------------------------------------------------------------------- lbessard@163: lbessard@6: def ResetToolBar(self): lbessard@249: if not self.Debug: lbessard@249: for item in self.CurrentToolBar: lbessard@249: if wx.VERSION >= (2, 6, 0): lbessard@249: self.Unbind(wx.EVT_MENU, id=item) lbessard@249: else: lbessard@249: self.Disconnect(id=item, eventType=wx.wxEVT_COMMAND_MENU_SELECTED) lbessard@249: lbessard@292: if USE_AUI: lbessard@292: ToolBar = self.Panes["ToolBar"] lbessard@292: else: lbessard@249: ToolBar = self.ToolBar lbessard@249: if ToolBar: lbessard@249: ToolBar.DeleteTool(item) lbessard@249: ToolBar.Realize() lbessard@292: if USE_AUI: lbessard@249: self.AUIManager.GetPane("ToolBar").BestSize(ToolBar.GetBestSize()) lbessard@249: self.AUIManager.Update() lbessard@249: lbessard@249: def RefreshToolBar(self): lbessard@249: if not self.Debug: lbessard@249: selected = self.TabsOpened.GetSelection() lbessard@249: if selected != -1: lbessard@249: language = self.Controler.GetEditedElementBodyType(self.TabsOpened.GetPage(selected).GetTagName(), self.Debug) lbessard@114: else: lbessard@249: language = None lbessard@249: if language is not None and language != self.CurrentLanguage: lbessard@249: self.ResetToolBar() lbessard@249: self.CurrentLanguage = language lbessard@249: self.CurrentToolBar = [] lbessard@292: if USE_AUI: lbessard@292: ToolBar = self.Panes["ToolBar"] lbessard@292: else: lbessard@249: ToolBar = self.ToolBar lbessard@249: if ToolBar: lbessard@249: for radio, modes, id, method, picture, help in ToolBarItems[language]: lbessard@249: if modes & self.DrawingMode: lbessard@249: if radio or self.DrawingMode == FREEDRAWING_MODE: lbessard@249: ToolBar.AddRadioTool(id, wx.Bitmap(os.path.join(CWD, "Images", picture)), wx.NullBitmap, help) lbessard@249: else: lbessard@249: ToolBar.AddSimpleTool(id, wx.Bitmap(os.path.join(CWD, "Images", picture)), help) lbessard@249: self.Bind(wx.EVT_TOOL, getattr(self, method), id=id) lbessard@249: self.CurrentToolBar.append(id) lbessard@249: ToolBar.Realize() lbessard@292: if USE_AUI: lbessard@249: self.AUIManager.GetPane("ToolBar").BestSize(ToolBar.GetBestSize()) lbessard@249: self.AUIManager.Update() lbessard@249: elif not language: lbessard@249: self.ResetToolBar() lbessard@249: self.CurrentLanguage = language lbessard@249: self.ResetCurrentMode() etisserant@0: lbessard@163: lbessard@163: #------------------------------------------------------------------------------- lbessard@231: # ToolBar Items Functions lbessard@163: #------------------------------------------------------------------------------- lbessard@163: lbessard@163: def ResetCurrentMode(self): lbessard@235: selected = self.TabsOpened.GetSelection() etisserant@0: if selected != -1: lbessard@235: window = self.TabsOpened.GetPage(selected) lbessard@163: window.SetMode(MODE_SELECTION) lbessard@292: if USE_AUI: lbessard@292: ToolBar = self.Panes["ToolBar"] lbessard@292: else: lbessard@163: ToolBar = self.ToolBar lbessard@163: if ToolBar: lbessard@163: ToolBar.ToggleTool(ID_PLCOPENEDITORTOOLBARSELECTION, True) lbessard@163: lbessard@163: def ResetToolToggle(self, id): lbessard@292: if USE_AUI: lbessard@292: tool = self.Panes["ToolBar"].FindById(id) lbessard@292: else: lbessard@163: tool = self.ToolBar.FindById(id) lbessard@163: tool.SetToggle(False) lbessard@163: lbessard@163: def OnSelectionTool(self, event): lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@56: if selected != -1: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_SELECTION) lbessard@163: event.Skip() lbessard@163: lbessard@163: def OnCommentTool(self, event): lbessard@163: self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARCOMMENT) lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@56: if selected != -1: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_COMMENT) lbessard@163: event.Skip() lbessard@163: lbessard@163: def OnVariableTool(self, event): lbessard@163: self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARVARIABLE) lbessard@235: selected = self.TabsOpened.GetSelection() etisserant@0: if selected != -1: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_VARIABLE) lbessard@163: event.Skip() lbessard@163: lbessard@163: def OnBlockTool(self, event): lbessard@163: self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARBLOCK) lbessard@235: selected = self.TabsOpened.GetSelection() etisserant@0: if selected != -1: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_BLOCK) lbessard@163: event.Skip() lbessard@163: lbessard@163: def OnConnectionTool(self, event): lbessard@163: self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARCONNECTION) lbessard@235: selected = self.TabsOpened.GetSelection() etisserant@0: if selected != -1: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_CONNECTION) lbessard@163: event.Skip() lbessard@163: lbessard@163: def OnPowerRailTool(self, event): lbessard@163: self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARPOWERRAIL) lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@163: if selected != -1: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_POWERRAIL) lbessard@163: event.Skip() lbessard@163: lbessard@163: def OnRungTool(self, event): lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@163: if selected != -1: lbessard@235: self.TabsOpened.GetPage(selected).AddLadderRung() lbessard@163: event.Skip() lbessard@163: lbessard@163: def OnCoilTool(self, event): lbessard@163: self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARCOIL) lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@163: if selected != -1: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_COIL) lbessard@163: event.Skip() lbessard@163: lbessard@163: def OnContactTool(self, event): lbessard@163: if self.DrawingMode == FREEDRAWING_MODE: lbessard@163: self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARCONTACT) lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@163: if selected != -1: lbessard@163: if self.DrawingMode == FREEDRAWING_MODE: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_CONTACT) lbessard@163: else: lbessard@235: self.TabsOpened.GetPage(selected).AddLadderContact() lbessard@163: event.Skip() lbessard@163: lbessard@163: def OnBranchTool(self, event): lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@163: if selected != -1: lbessard@235: self.TabsOpened.GetPage(selected).AddLadderBranch() lbessard@163: event.Skip() lbessard@163: lbessard@163: def OnInitialStepTool(self, event): lbessard@163: self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARINITIALSTEP) lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@163: if selected != -1: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_INITIALSTEP) lbessard@163: event.Skip() lbessard@163: lbessard@163: def OnStepTool(self, event): lbessard@163: if self.GetDrawingMode() == FREEDRAWING_MODE: lbessard@163: self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARSTEP) lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@163: if selected != -1: lbessard@163: if self.GetDrawingMode() == FREEDRAWING_MODE: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_STEP) lbessard@163: else: lbessard@235: self.TabsOpened.GetPage(selected).AddStep() lbessard@163: event.Skip() lbessard@163: lbessard@163: def OnActionBlockTool(self, event): lbessard@163: if self.GetDrawingMode() == FREEDRAWING_MODE: lbessard@163: self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARACTIONBLOCK) lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@163: if selected != -1: lbessard@163: if self.GetDrawingMode() == FREEDRAWING_MODE: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_ACTION) lbessard@163: else: lbessard@235: self.TabsOpened.GetPage(selected).AddStepAction() lbessard@163: event.Skip() lbessard@163: lbessard@163: def OnTransitionTool(self, event): lbessard@163: self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARTRANSITION) lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@163: if selected != -1: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_TRANSITION) lbessard@163: event.Skip() lbessard@163: lbessard@163: def OnDivergenceTool(self, event): lbessard@163: if self.GetDrawingMode() == FREEDRAWING_MODE: lbessard@163: self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARDIVERGENCE) lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@163: if selected != -1: lbessard@163: if self.GetDrawingMode() == FREEDRAWING_MODE: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_DIVERGENCE) lbessard@163: else: lbessard@235: self.TabsOpened.GetPage(selected).AddDivergence() lbessard@163: event.Skip() lbessard@163: lbessard@163: def OnJumpTool(self, event): lbessard@163: if self.GetDrawingMode() == FREEDRAWING_MODE: lbessard@163: self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARJUMP) lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@163: if selected != -1: lbessard@163: if self.GetDrawingMode() == FREEDRAWING_MODE: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_JUMP) lbessard@163: else: lbessard@235: self.TabsOpened.GetPage(selected).AddJump() lbessard@163: event.Skip() lbessard@163: lbessard@163: lbessard@163: #------------------------------------------------------------------------------- lbessard@163: # Add Project Elements Functions lbessard@163: #------------------------------------------------------------------------------- lbessard@163: lbessard@125: def OnAddDataTypeMenu(self, event): lbessard@125: dialog = DataTypeDialog(self, "Add a new data type", "Please enter data type name", "", wx.OK|wx.CANCEL) lbessard@249: dialog.SetDataTypeNames(self.Controler.GetProjectDataTypeNames(self.Debug)) lbessard@125: if dialog.ShowModal() == wx.ID_OK: lbessard@125: self.Controler.ProjectAddDataType(dialog.GetValue()) lbessard@125: self.RefreshTitle() lbessard@125: self.RefreshEditMenu() lbessard@235: self.RefreshTypesTree() lbessard@125: dialog.Destroy() lbessard@125: event.Skip() lbessard@163: lbessard@163: def GenerateAddPouFunction(self, pou_type): lbessard@163: def OnAddPouMenu(event): lbessard@163: dialog = PouDialog(self, pou_type) lbessard@249: dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) lbessard@249: dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(debug = self.Debug)) lbessard@163: if dialog.ShowModal() == wx.ID_OK: lbessard@163: values = dialog.GetValues() lbessard@163: self.Controler.ProjectAddPou(values["pouName"], values["pouType"], values["language"]) lbessard@125: self.RefreshTitle() lbessard@125: self.RefreshEditMenu() lbessard@235: self.RefreshTypesTree() lbessard@239: self.RefreshLibraryTree() lbessard@163: dialog.Destroy() lbessard@163: event.Skip() lbessard@163: return OnAddPouMenu lbessard@163: lbessard@163: def GenerateAddTransitionFunction(self, pou_name): lbessard@163: def OnAddTransitionMenu(event): lbessard@163: dialog = PouTransitionDialog(self) lbessard@249: dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) lbessard@249: dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(pou_name, self.Debug)) lbessard@163: if dialog.ShowModal() == wx.ID_OK: lbessard@163: values = dialog.GetValues() lbessard@163: self.Controler.ProjectAddPouTransition(pou_name, values["transitionName"], values["language"]) lbessard@80: self.RefreshTitle() lbessard@80: self.RefreshEditMenu() lbessard@235: self.RefreshTypesTree() lbessard@239: dialog.Destroy() lbessard@163: event.Skip() lbessard@163: return OnAddTransitionMenu lbessard@163: lbessard@163: def GenerateAddActionFunction(self, pou_name): lbessard@163: def OnAddActionMenu(event): lbessard@163: dialog = PouActionDialog(self) lbessard@249: dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) lbessard@249: dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(pou_name, self.Debug)) lbessard@163: if dialog.ShowModal() == wx.ID_OK: lbessard@163: values = dialog.GetValues() lbessard@163: self.Controler.ProjectAddPouAction(pou_name, values["actionName"], values["language"]) lbessard@163: self.RefreshTitle() lbessard@163: self.RefreshEditMenu() lbessard@235: self.RefreshTypesTree() lbessard@163: dialog.Destroy() lbessard@163: event.Skip() lbessard@163: return OnAddActionMenu etisserant@0: etisserant@0: def OnAddConfigurationMenu(self, event): lbessard@80: dialog = ConfigurationNameDialog(self, "Please enter configuration name", "Add new configuration") lbessard@249: dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) lbessard@249: dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(debug = self.Debug)) lbessard@64: if dialog.ShowModal() == wx.ID_OK: etisserant@0: value = dialog.GetValue() etisserant@0: self.Controler.ProjectAddConfiguration(value) lbessard@80: self.RefreshTitle() lbessard@80: self.RefreshEditMenu() lbessard@235: self.RefreshTypesTree() lbessard@239: self.RefreshInstancesTree() etisserant@0: dialog.Destroy() etisserant@0: event.Skip() etisserant@0: lbessard@163: def GenerateAddResourceFunction(self, config_name): greg@177: def OnAddResourceMenu(event): lbessard@80: dialog = ResourceNameDialog(self, "Please enter resource name", "Add new resource") lbessard@249: dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) lbessard@249: dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(debug = self.Debug)) lbessard@64: if dialog.ShowModal() == wx.ID_OK: etisserant@0: value = dialog.GetValue() etisserant@0: self.Controler.ProjectAddConfigurationResource(config_name, value) lbessard@163: self.RefreshTitle() lbessard@163: self.RefreshEditMenu() lbessard@235: self.RefreshTypesTree() lbessard@239: self.RefreshInstancesTree() lbessard@163: dialog.Destroy() lbessard@163: event.Skip() lbessard@163: return OnAddResourceMenu lbessard@163: lbessard@275: def GenerateChangePouTypeFunction(self, name, new_type): lbessard@275: def OnChangePouTypeMenu(event): lbessard@275: selected = self.TypesTree.GetSelection() lbessard@275: if self.TypesTree.GetPyData(selected) == ITEM_POU: lbessard@275: self.Controler.ProjectChangePouType(name, new_type) lbessard@275: self.RefreshTitle() lbessard@275: self.RefreshEditMenu() lbessard@275: self.RefreshTypesTree() lbessard@275: self.RefreshLibraryTree() lbessard@275: self.RefreshToolBar() lbessard@275: event.Skip() lbessard@275: return OnChangePouTypeMenu lbessard@163: lbessard@274: def OnCreatePouFromMenu(self, event): lbessard@274: selected = self.TypesTree.GetSelection() lbessard@274: if self.TypesTree.GetPyData(selected) == ITEM_POU: lbessard@274: dialog = PouNameDialog(self, "Please enter POU name", "Create a new POU from", "", wx.OK|wx.CANCEL) lbessard@274: dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) lbessard@274: if dialog.ShowModal() == wx.ID_OK: lbessard@274: self.Controler.ProjectCreatePouFrom(dialog.GetValue(), self.TypesTree.GetItemText(selected)) lbessard@274: self.RefreshTitle() lbessard@274: self.RefreshEditMenu() lbessard@274: self.RefreshTypesTree() lbessard@274: self.RefreshLibraryTree() lbessard@274: self.RefreshToolBar() lbessard@274: event.Skip() lbessard@274: lbessard@275: #------------------------------------------------------------------------------- lbessard@275: # Remove Project Elements Functions lbessard@275: #------------------------------------------------------------------------------- lbessard@275: lbessard@163: def OnRemoveDataTypeMenu(self, event): lbessard@235: selected = self.TypesTree.GetSelection() lbessard@235: if self.TypesTree.GetPyData(selected) == ITEM_DATATYPE: lbessard@235: name = self.TypesTree.GetItemText(selected) lbessard@249: if not self.Controler.DataTypeIsUsed(name, self.Debug): lbessard@163: self.Controler.ProjectRemoveDataType(name) lbessard@163: tagname = self.Controler.ComputeDataTypeName(name) lbessard@121: idx = self.IsOpened(tagname) lbessard@121: if idx is not None: lbessard@235: self.TabsOpened.DeletePage(idx) lbessard@80: self.RefreshTitle() lbessard@80: self.RefreshEditMenu() lbessard@235: self.RefreshTypesTree() lbessard@163: self.RefreshToolBar() lbessard@163: else: lbessard@163: message = wx.MessageDialog(self, "%s is used by one or more POUs. It can't be removed!"%selected, "Error", wx.OK|wx.ICON_ERROR) lbessard@163: message.ShowModal() lbessard@163: message.Destroy() lbessard@163: event.Skip() lbessard@163: lbessard@163: def OnRemovePouMenu(self, event): lbessard@235: selected = self.TypesTree.GetSelection() lbessard@235: if self.TypesTree.GetPyData(selected) == ITEM_POU: lbessard@235: name = self.TypesTree.GetItemText(selected) lbessard@249: if not self.Controler.PouIsUsed(name, self.Debug): lbessard@163: self.Controler.ProjectRemovePou(name) lbessard@163: tagname = self.Controler.ComputePouName(name) lbessard@163: idx = self.IsOpened(tagname) lbessard@163: if idx is not None: lbessard@163: self.VariablePanelIndexer.RemoveVariablePanel(tagname) lbessard@235: self.TabsOpened.DeletePage(idx) lbessard@80: self.RefreshTitle() lbessard@80: self.RefreshEditMenu() lbessard@235: self.RefreshTypesTree() lbessard@239: self.RefreshInstancesTree() lbessard@239: self.RefreshLibraryTree() lbessard@163: self.RefreshToolBar() lbessard@163: else: lbessard@163: message = wx.MessageDialog(self, "%s is used by one or more POUs. It can't be removed!"%selected, "Error", wx.OK|wx.ICON_ERROR) lbessard@163: message.ShowModal() lbessard@163: message.Destroy() lbessard@163: event.Skip() lbessard@163: lbessard@163: def OnRemoveTransitionMenu(self, event): lbessard@235: selected = self.TypesTree.GetSelection() lbessard@235: if self.TypesTree.GetPyData(selected) == ITEM_TRANSITION: lbessard@235: transition = self.TypesTree.GetItemText(selected) lbessard@235: item = self.TypesTree.GetItemParent(selected) lbessard@235: item_type = self.TypesTree.GetPyData(item) lbessard@163: while item_type != ITEM_POU: lbessard@235: item = self.TypesTree.GetItemParent(item) lbessard@235: item_type = self.TypesTree.GetPyData(item) lbessard@235: pou_name = self.TypesTree.GetItemText(item) lbessard@163: self.Controler.ProjectRemovePouTransition(pou_name, transition) lbessard@163: tagname = self.Controler.ComputePouTransitionName(pou_name, transition) lbessard@163: idx = self.IsOpened(tagname) lbessard@163: if idx is not None: lbessard@163: self.VariablePanelIndexer.RemoveVariablePanel(tagname) lbessard@235: self.TabsOpened.DeletePage(idx) lbessard@163: self.RefreshTitle() lbessard@163: self.RefreshEditMenu() lbessard@235: self.RefreshTypesTree() lbessard@163: event.Skip() lbessard@163: lbessard@163: def OnRemoveActionMenu(self, event): lbessard@235: selected = self.TypesTree.GetSelection() lbessard@235: if self.TypesTree.GetPyData(selected) == ITEM_ACTION: lbessard@235: action = self.TypesTree.GetItemText(selected) lbessard@235: item = self.TypesTree.GetItemParent(selected) lbessard@235: item_type = self.TypesTree.GetPyData(item) lbessard@163: while item_type != ITEM_POU: lbessard@235: item = self.TypesTree.GetItemParent(item) lbessard@235: item_type = self.TypesTree.GetPyData(item) lbessard@235: pou_name = self.TypesTree.GetItemText(item) lbessard@163: self.Controler.ProjectRemovePouAction(pou_name, action) lbessard@163: tagname = self.Controler.ComputePouActionName(pou_name, action) lbessard@163: idx = self.IsOpened(tagname) lbessard@163: if idx is not None: lbessard@163: self.VariablePanelIndexer.RemoveVariablePanel(tagname) lbessard@235: self.TabsOpened.DeletePage(idx) lbessard@163: self.RefreshTitle() lbessard@163: self.RefreshEditMenu() lbessard@235: self.RefreshTypesTree() lbessard@163: event.Skip() lbessard@163: lbessard@239: def OnRemoveConfigurationMenu(self, event): lbessard@239: selected = self.TypesTree.GetSelection() lbessard@239: if self.TypesTree.GetPyData(selected) == ITEM_CONFIGURATION: lbessard@239: name = self.TypesTree.GetItemText(selected) lbessard@239: self.Controler.ProjectRemoveConfiguration(name) lbessard@239: tagname = self.Controler.ComputeConfigurationName(name) lbessard@239: idx = self.IsOpened(tagname) lbessard@239: if idx is not None: lbessard@239: self.VariablePanelIndexer.RemoveVariablePanel(tagname) lbessard@239: self.TabsOpened.DeletePage(idx) lbessard@239: self.RefreshTitle() lbessard@239: self.RefreshEditMenu() lbessard@239: self.RefreshTypesTree() lbessard@239: self.RefreshInstancesTree() lbessard@239: event.Skip() lbessard@239: lbessard@163: def OnRemoveResourceMenu(self, event): lbessard@235: selected = self.TypesTree.GetSelection() lbessard@235: if self.TypesTree.GetPyData(selected) == ITEM_RESOURCE: lbessard@235: resource = self.TypesTree.GetItemText(selected) lbessard@235: item = self.TypesTree.GetItemParent(selected) lbessard@235: item_type = self.TypesTree.GetPyData(item) lbessard@163: while item_type != ITEM_CONFIGURATION: lbessard@235: item = self.TypesTree.GetItemParent(item) lbessard@235: item_type = self.TypesTree.GetPyData(item) lbessard@235: config_name = self.TypesTree.GetItemText(item) lbessard@163: self.Controler.ProjectRemoveConfigurationResource(config_name, resource) lbessard@163: tagname = self.Controler.ComputeConfigurationResourceName(config_name, selected) lbessard@163: idx = self.IsOpened(tagname) lbessard@163: if idx is not None: lbessard@163: self.VariablePanelIndexer.RemoveVariablePanel(tagname) lbessard@235: self.TabsOpened.DeletePage(idx) lbessard@163: self.RefreshTitle() lbessard@163: self.RefreshEditMenu() lbessard@235: self.RefreshTypesTree() lbessard@239: self.RefreshInstancesTree() etisserant@0: event.Skip() greg@190: greg@190: def OnPLCOpenEditorMenu(self, event): greg@190: wx.MessageBox("No documentation available.\nComing soon.") lbessard@223: #event.Skip() greg@190: etisserant@0: def OnPLCOpenMenu(self, event): greg@190: open_pdf(os.path.join(CWD, "plcopen", "TC6_XML_V101.pdf")) greg@190: event.Skip() greg@190: greg@190: def OnAboutMenu(self, event): greg@190: OpenHtmlFrame(self,"About PLCOpenEditor", os.path.join(CWD, "doc","about.html"), wx.Size(350, 350)) greg@190: event.Skip() lbessard@231: lbessard@231: lbessard@231: #------------------------------------------------------------------------------- lbessard@231: # Errors showing functions lbessard@231: #------------------------------------------------------------------------------- lbessard@231: lbessard@231: def ShowError(self, infos, start, end): lbessard@231: self.EditProjectElement(self.Controler.GetElementType(infos[0]), infos[0]) lbessard@235: self.SelectTypesTreeItem(infos[0]) lbessard@231: if infos[1] == "name": lbessard@231: self.Errors.append(infos[0]) lbessard@235: self.RefreshTypesTree() lbessard@235: self.TypesTree.Unselect() lbessard@231: elif infos[1] == "variable": lbessard@231: self.VariablePanelIndexer.AddVariableError(infos) lbessard@231: else: lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@231: if selected != -1: lbessard@235: viewer = self.TabsOpened.GetPage(selected) lbessard@231: viewer.AddShownError(infos[1:], start, end) lbessard@231: viewer.RefreshView() lbessard@231: lbessard@231: def ClearErrors(self): lbessard@231: self.Errors = [] lbessard@235: self.RefreshTypesTree() lbessard@231: self.VariablePanelIndexer.ClearErrors() lbessard@235: for i in xrange(self.TabsOpened.GetPageCount()): lbessard@235: viewer = self.TabsOpened.GetPage(i) lbessard@231: viewer.ClearErrors() greg@190: etisserant@0: current_num = 0 etisserant@0: def GetNewNum(): etisserant@0: global current_num etisserant@0: current_num += 1 etisserant@0: return current_num etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Create Project Dialog etisserant@0: #------------------------------------------------------------------------------- etisserant@0: lbessard@145: [ID_SCALINGPANEL, ID_SCALINGPANELXSCALE, lbessard@145: ID_SCALINGPANELYSCALE, ID_SCALINGPANELSTATICTEXT1, lbessard@145: ID_SCALINGPANELSTATICTEXT2, lbessard@145: ] = [wx.NewId() for _init_ctrls in range(5)] lbessard@145: lbessard@145: class ScalingPanel(wx.Panel): lbessard@145: lbessard@145: def _init_coll_ScalingPanelSizer_Items(self, parent): lbessard@145: parent.AddWindow(self.staticText1, 0, border=10, flag=wx.GROW|wx.TOP|wx.LEFT) lbessard@145: parent.AddWindow(self.XScale, 0, border=10, flag=wx.GROW|wx.TOP|wx.RIGHT) lbessard@145: parent.AddWindow(self.staticText2, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.LEFT) lbessard@145: parent.AddWindow(self.YScale, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.RIGHT) lbessard@145: lbessard@145: def _init_coll_ScalingPanelSizer_Growables(self, parent): lbessard@145: parent.AddGrowableCol(1) lbessard@145: lbessard@145: def _init_sizers(self): lbessard@145: self.ScalingPanelSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=2, vgap=5) lbessard@145: lbessard@145: self._init_coll_ScalingPanelSizer_Items(self.ScalingPanelSizer) lbessard@145: self._init_coll_ScalingPanelSizer_Growables(self.ScalingPanelSizer) lbessard@145: lbessard@145: self.SetSizer(self.ScalingPanelSizer) lbessard@145: lbessard@145: def _init_ctrls(self, prnt): lbessard@145: wx.Panel.__init__(self, id=ID_SCALINGPANEL, lbessard@145: name='ScalingPanel', parent=prnt, pos=wx.Point(0, 0), lbessard@163: size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) lbessard@145: lbessard@145: self.staticText1 = wx.StaticText(id=ID_SCALINGPANELSTATICTEXT1, lbessard@145: label='X Scale:', name='staticText1', parent=self, lbessard@145: pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0) lbessard@145: lbessard@145: self.XScale = wx.SpinCtrl(id=ID_SCALINGPANELXSCALE, lbessard@145: name='XScale', parent=self, pos=wx.Point(0, 0), lbessard@145: size=wx.Size(0, 24), style=0, min=0, max=2**16) lbessard@145: lbessard@145: self.staticText2 = wx.StaticText(id=ID_SCALINGPANELSTATICTEXT2, lbessard@145: label='Y Scale:', name='staticText2', parent=self, lbessard@145: pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0) lbessard@145: lbessard@145: self.YScale = wx.SpinCtrl(id=ID_SCALINGPANELYSCALE, lbessard@145: name='YScale', parent=self, pos=wx.Point(0, 0), lbessard@145: size=wx.Size(0, 24), style=0, min=0, max=2**16) lbessard@145: lbessard@145: self._init_sizers() lbessard@145: lbessard@145: def __init__(self, parent): lbessard@145: self._init_ctrls(parent) lbessard@145: lbessard@145: def SetScaling(self, x, y): lbessard@145: self.XScale.SetValue(x) lbessard@145: self.YScale.SetValue(y) lbessard@145: lbessard@145: def GetScaling(self): lbessard@145: return self.XScale.GetValue(), self.YScale.GetValue() lbessard@145: lbessard@145: [ID_PROJECTDIALOG, ID_PROJECTDIALOGMAINNOTEBOOK, lbessard@145: ID_PROJECTDIALOGPROJECTPANEL, ID_PROJECTDIALOGAUTHORPANEL, lbessard@145: ID_PROJECTDIALOGGRAPHICSPANEL, ID_PROJECTDIALOGMISCELLANEOUSPANEL, lbessard@145: ID_PROJECTDIALOGPROJECTNAME, ID_PROJECTDIALOGPROJECTVERSION, lbessard@64: ID_PROJECTDIALOGPRODUCTNAME, ID_PROJECTDIALOGPRODUCTVERSION, lbessard@145: ID_PROJECTDIALOGPRODUCTRELEASE, ID_PROJECTDIALOGCOMPANYNAME, lbessard@145: ID_PROJECTDIALOGCOMPANYURL, ID_PROJECTDIALOGAUTHORNAME, lbessard@145: ID_PROJECTDIALOGORGANIZATION, ID_PROJECTDIALOGLANGUAGE, lbessard@145: ID_PROJECTDIALOGCONTENTDESCRIPTION, ID_PROJECTDIALOGSCALINGNOTEBOOK, lbessard@145: ID_PROJECTDIALOGPAGEWIDTH, ID_PROJECTDIALOGPAGEHEIGHT, lbessard@64: ID_PROJECTDIALOGSTATICTEXT1, ID_PROJECTDIALOGSTATICTEXT2, lbessard@64: ID_PROJECTDIALOGSTATICTEXT3, ID_PROJECTDIALOGSTATICTEXT4, lbessard@64: ID_PROJECTDIALOGSTATICTEXT5, ID_PROJECTDIALOGSTATICTEXT6, lbessard@145: ID_PROJECTDIALOGSTATICTEXT7, ID_PROJECTDIALOGSTATICTEXT8, lbessard@145: ID_PROJECTDIALOGSTATICTEXT9, ID_PROJECTDIALOGSTATICTEXT10, lbessard@145: ID_PROJECTDIALOGSTATICTEXT11, ID_PROJECTDIALOGSTATICTEXT12, lbessard@145: ID_PROJECTDIALOGSTATICTEXT13, ID_PROJECTDIALOGSTATICTEXT14, lbessard@145: ID_PROJECTDIALOGSTATICTEXT15, lbessard@145: ] = [wx.NewId() for _init_ctrls in range(35)] lbessard@145: etisserant@0: class ProjectDialog(wx.Dialog): lbessard@114: if wx.VERSION < (2, 6, 0): lbessard@114: def Bind(self, event, function, id = None): lbessard@114: if id is not None: lbessard@114: event(self, id, function) lbessard@114: else: lbessard@114: event(self, function) lbessard@114: etisserant@0: def _init_coll_flexGridSizer1_Items(self, parent): lbessard@145: parent.AddSizer(self.MainNotebook, 0, border=0, flag=wx.GROW) lbessard@64: parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) lbessard@64: lbessard@64: def _init_coll_flexGridSizer1_Growables(self, parent): lbessard@64: parent.AddGrowableCol(0) lbessard@64: parent.AddGrowableRow(0) lbessard@64: lbessard@145: def _init_coll_ProjectPanelSizer_Items(self, parent): lbessard@145: parent.AddWindow(self.staticText1, 0, border=10, flag=wx.GROW|wx.TOP|wx.LEFT) lbessard@145: parent.AddWindow(self.ProjectName, 0, border=10, flag=wx.GROW|wx.TOP|wx.RIGHT) lbessard@145: parent.AddWindow(self.staticText2, 0, border=10, flag=wx.GROW|wx.LEFT) lbessard@145: parent.AddWindow(self.ProjectVersion, 0, border=10, flag=wx.GROW|wx.RIGHT) lbessard@145: parent.AddWindow(self.staticText3, 0, border=10, flag=wx.GROW|wx.LEFT) lbessard@145: parent.AddWindow(self.ProductName, 0, border=10, flag=wx.GROW|wx.RIGHT) lbessard@145: parent.AddWindow(self.staticText4, 0, border=10, flag=wx.GROW|wx.LEFT) lbessard@145: parent.AddWindow(self.ProductVersion, 0, border=10, flag=wx.GROW|wx.RIGHT) lbessard@145: parent.AddWindow(self.staticText5, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.LEFT) lbessard@145: parent.AddWindow(self.ProductRelease, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.RIGHT) lbessard@145: lbessard@145: def _init_coll_ProjectPanelSizer_Growables(self, parent): lbessard@64: parent.AddGrowableCol(1) lbessard@145: lbessard@145: def _init_coll_AuthorPanelSizer_Items(self, parent): lbessard@145: parent.AddWindow(self.staticText6, 0, border=10, flag=wx.GROW|wx.TOP|wx.LEFT) lbessard@145: parent.AddWindow(self.CompanyName, 0, border=10, flag=wx.GROW|wx.TOP|wx.RIGHT) lbessard@145: parent.AddWindow(self.staticText7, 0, border=10, flag=wx.GROW|wx.LEFT) lbessard@145: parent.AddWindow(self.CompanyURL, 0, border=10, flag=wx.GROW|wx.RIGHT) lbessard@145: parent.AddWindow(self.staticText8, 0, border=10, flag=wx.GROW|wx.LEFT) lbessard@145: parent.AddWindow(self.AuthorName, 0, border=10, flag=wx.GROW|wx.RIGHT) lbessard@145: parent.AddWindow(self.staticText9, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.LEFT) lbessard@145: parent.AddWindow(self.Organization, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.RIGHT) lbessard@145: lbessard@145: def _init_coll_AuthorPanelSizer_Growables(self, parent): lbessard@145: parent.AddGrowableCol(1) lbessard@145: lbessard@145: def _init_coll_GraphicsPanelSizer_Items(self, parent): lbessard@145: parent.AddWindow(self.staticText12, 0, border=10, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) lbessard@145: parent.AddSizer(self.GraphicsPageSizeSizer, 0, border=10, flag=wx.GROW|wx.LEFT|wx.RIGHT) lbessard@145: parent.AddWindow(self.staticText15, 0, border=10, flag=wx.GROW|wx.LEFT|wx.RIGHT) lbessard@145: parent.AddWindow(self.ScalingNotebook, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.LEFT|wx.RIGHT) lbessard@145: lbessard@145: def _init_coll_GraphicsPanelSizer_Growables(self, parent): lbessard@145: parent.AddGrowableCol(0) lbessard@145: parent.AddGrowableRow(3) lbessard@145: lbessard@145: def _init_coll_GraphicsPageSizeSizer_Items(self, parent): lbessard@145: parent.AddWindow(self.staticText13, 0, border=12, flag=wx.GROW|wx.LEFT) lbessard@145: parent.AddWindow(self.PageWidth, 0, border=0, flag=wx.GROW) lbessard@145: parent.AddWindow(self.staticText14, 0, border=12, flag=wx.GROW|wx.LEFT) lbessard@145: parent.AddWindow(self.PageHeight, 0, border=0, flag=wx.GROW) lbessard@145: lbessard@145: def _init_coll_GraphicsPageSizeSizer_Growables(self, parent): lbessard@145: parent.AddGrowableCol(1) lbessard@145: lbessard@145: def _init_coll_MiscellaneousPanelSizer_Items(self, parent): lbessard@145: parent.AddWindow(self.staticText10, 0, border=10, flag=wx.GROW|wx.TOP|wx.LEFT) lbessard@145: parent.AddWindow(self.Language, 0, border=10, flag=wx.GROW|wx.TOP|wx.RIGHT) lbessard@145: parent.AddWindow(self.staticText11, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.LEFT) lbessard@145: parent.AddWindow(self.ContentDescription, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.RIGHT) lbessard@145: lbessard@145: def _init_coll_MiscellaneousPanelSizer_Growables(self, parent): lbessard@145: parent.AddGrowableCol(1) lbessard@145: parent.AddGrowableRow(1) lbessard@64: etisserant@0: def _init_sizers(self): lbessard@64: self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) lbessard@145: self.ProjectPanelSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=5, vgap=15) lbessard@145: self.AuthorPanelSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=4, vgap=15) lbessard@145: self.GraphicsPanelSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=4, vgap=5) lbessard@145: self.GraphicsPageSizeSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=2, vgap=5) lbessard@145: self.MiscellaneousPanelSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=2, vgap=15) etisserant@0: etisserant@0: self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) lbessard@64: self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) lbessard@145: self._init_coll_ProjectPanelSizer_Items(self.ProjectPanelSizer) lbessard@145: self._init_coll_ProjectPanelSizer_Growables(self.ProjectPanelSizer) lbessard@145: self._init_coll_AuthorPanelSizer_Items(self.AuthorPanelSizer) lbessard@145: self._init_coll_AuthorPanelSizer_Growables(self.AuthorPanelSizer) lbessard@145: self._init_coll_GraphicsPanelSizer_Items(self.GraphicsPanelSizer) lbessard@145: self._init_coll_GraphicsPanelSizer_Growables(self.GraphicsPanelSizer) lbessard@145: self._init_coll_GraphicsPageSizeSizer_Items(self.GraphicsPageSizeSizer) lbessard@145: self._init_coll_GraphicsPageSizeSizer_Growables(self.GraphicsPageSizeSizer) lbessard@145: self._init_coll_MiscellaneousPanelSizer_Items(self.MiscellaneousPanelSizer) lbessard@145: self._init_coll_MiscellaneousPanelSizer_Growables(self.MiscellaneousPanelSizer) etisserant@0: etisserant@0: self.SetSizer(self.flexGridSizer1) lbessard@145: self.ProjectPanel.SetSizer(self.ProjectPanelSizer) lbessard@145: self.AuthorPanel.SetSizer(self.AuthorPanelSizer) lbessard@145: self.GraphicsPanel.SetSizer(self.GraphicsPanelSizer) lbessard@145: self.MiscellaneousPanel.SetSizer(self.MiscellaneousPanelSizer) etisserant@0: etisserant@0: def _init_ctrls(self, prnt): lbessard@64: wx.Dialog.__init__(self, id=ID_PROJECTDIALOG, etisserant@0: name='ProjectDialog', parent=prnt, pos=wx.Point(376, 223), lbessard@145: size=wx.Size(500, 350), style=wx.DEFAULT_DIALOG_STYLE, etisserant@0: title='Create a new project') lbessard@145: self.SetClientSize(wx.Size(500, 350)) lbessard@145: lbessard@145: self.MainNotebook = wx.Notebook(id=ID_PROJECTDIALOGMAINNOTEBOOK, lbessard@145: name='MainNotebook', parent=self, pos=wx.Point(0, lbessard@145: 0), size=wx.Size(0, 0), style=0) lbessard@145: lbessard@145: # Project Panel elements lbessard@145: lbessard@145: self.ProjectPanel = wx.Panel(id=ID_PROJECTDIALOGPROJECTPANEL, lbessard@145: name='ProjectPanel', parent=self.MainNotebook, pos=wx.Point(0, 0), lbessard@145: size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) etisserant@0: lbessard@64: self.staticText1 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT1, lbessard@145: label='Project Name (required):', name='staticText1', parent=self.ProjectPanel, lbessard@64: pos=wx.Point(0, 0), size=wx.Size(200, 17), style=0) lbessard@64: lbessard@64: self.ProjectName = wx.TextCtrl(id=ID_PROJECTDIALOGPROJECTNAME, lbessard@145: name='ProjectName', parent=self.ProjectPanel, pos=wx.Point(0, 0), lbessard@64: size=wx.Size(0, 24), style=0) lbessard@64: lbessard@64: self.staticText2 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT2, lbessard@145: label='Project Version (optional):', name='staticText2', parent=self.ProjectPanel, lbessard@64: pos=wx.Point(0, 0), size=wx.Size(200, 17), style=0) lbessard@64: lbessard@145: self.ProjectVersion = wx.TextCtrl(id=ID_PROJECTDIALOGPROJECTVERSION, lbessard@145: name='ProjectVersion', parent=self.ProjectPanel, pos=wx.Point(0, 0), lbessard@145: size=wx.Size(0, 24), style=0) lbessard@145: lbessard@145: self.staticText3 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT3, lbessard@145: label='Product Name (required):', name='staticText3', parent=self.ProjectPanel, lbessard@145: pos=wx.Point(0, 0), size=wx.Size(200, 17), style=0) lbessard@145: lbessard@145: self.ProductName = wx.TextCtrl(id=ID_PROJECTDIALOGPRODUCTNAME, lbessard@145: name='ProductName', parent=self.ProjectPanel, pos=wx.Point(0, 0), lbessard@145: size=wx.Size(0, 24), style=0) lbessard@145: lbessard@145: self.staticText4 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT4, lbessard@145: label='Product Version (required):', name='staticText4', parent=self.ProjectPanel, lbessard@145: pos=wx.Point(0, 0), size=wx.Size(200, 17), style=0) lbessard@145: lbessard@145: self.ProductVersion = wx.TextCtrl(id=ID_PROJECTDIALOGPRODUCTVERSION, lbessard@145: name='ProductVersion', parent=self.ProjectPanel, pos=wx.Point(0, 0), lbessard@145: size=wx.Size(0, 24), style=0) lbessard@145: lbessard@145: self.staticText5 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT5, lbessard@145: label='Product Release (optional):', name='staticText5', parent=self.ProjectPanel, lbessard@145: pos=wx.Point(0, 0), size=wx.Size(200, 17), style=0) lbessard@145: lbessard@145: self.ProductRelease = wx.TextCtrl(id=ID_PROJECTDIALOGPRODUCTRELEASE, lbessard@145: name='ProductRelease', parent=self.ProjectPanel, pos=wx.Point(0, 0), lbessard@145: size=wx.Size(0, 24), style=0) lbessard@145: lbessard@145: self.MainNotebook.AddPage(self.ProjectPanel, "Project") lbessard@145: lbessard@145: # Author Panel elements lbessard@145: lbessard@145: self.AuthorPanel = wx.Panel(id=ID_PROJECTDIALOGAUTHORPANEL, lbessard@145: name='AuthorPanel', parent=self.MainNotebook, pos=wx.Point(0, 0), lbessard@145: size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) lbessard@145: lbessard@145: self.staticText6 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT6, lbessard@145: label='Company Name (required):', name='staticText6', parent=self.AuthorPanel, lbessard@145: pos=wx.Point(0, 0), size=wx.Size(200, 17), style=0) lbessard@145: lbessard@64: self.CompanyName = wx.TextCtrl(id=ID_PROJECTDIALOGCOMPANYNAME, lbessard@145: name='CompanyName', parent=self.AuthorPanel, pos=wx.Point(0, 0), lbessard@64: size=wx.Size(0, 24), style=0) lbessard@64: lbessard@145: self.staticText7 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT7, lbessard@145: label='Company URL (optional):', name='staticText7', parent=self.AuthorPanel, lbessard@64: pos=wx.Point(0, 0), size=wx.Size(200, 17), style=0) lbessard@64: lbessard@64: self.CompanyURL = wx.TextCtrl(id=ID_PROJECTDIALOGCOMPANYURL, lbessard@145: name='CompanyURL', parent=self.AuthorPanel, pos=wx.Point(0, 0), lbessard@64: size=wx.Size(0, 24), style=0) lbessard@64: lbessard@145: self.staticText8 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT8, lbessard@145: label='Author Name (optional):', name='staticText8', parent=self.AuthorPanel, lbessard@64: pos=wx.Point(0, 0), size=wx.Size(200, 17), style=0) lbessard@64: lbessard@145: self.AuthorName = wx.TextCtrl(id=ID_PROJECTDIALOGAUTHORNAME, lbessard@145: name='AuthorName', parent=self.AuthorPanel, pos=wx.Point(0, 0), lbessard@64: size=wx.Size(0, 24), style=0) lbessard@64: lbessard@145: self.staticText9 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT9, lbessard@145: label='Organization (optional):', name='staticText9', parent=self.AuthorPanel, lbessard@64: pos=wx.Point(0, 0), size=wx.Size(200, 17), style=0) lbessard@64: lbessard@145: self.Organization = wx.TextCtrl(id=ID_PROJECTDIALOGORGANIZATION, lbessard@145: name='Organization', parent=self.AuthorPanel, pos=wx.Point(0, 0), lbessard@64: size=wx.Size(0, 24), style=0) lbessard@64: lbessard@145: self.MainNotebook.AddPage(self.AuthorPanel, "Author") lbessard@145: lbessard@145: # Graphics Panel elements lbessard@145: lbessard@145: self.GraphicsPanel = wx.Panel(id=ID_PROJECTDIALOGGRAPHICSPANEL, lbessard@145: name='GraphicsPanel', parent=self.MainNotebook, pos=wx.Point(0, 0), lbessard@145: size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) lbessard@145: lbessard@145: self.staticText12 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT12, lbessard@145: label='Page Size (optional):', name='staticText12', parent=self.GraphicsPanel, lbessard@64: pos=wx.Point(0, 0), size=wx.Size(200, 17), style=0) lbessard@64: lbessard@145: self.staticText13 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT13, lbessard@145: label='Width:', name='staticText13', parent=self.GraphicsPanel, lbessard@145: pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0) lbessard@145: lbessard@145: self.PageWidth = wx.SpinCtrl(id=ID_PROJECTDIALOGPAGEWIDTH, lbessard@145: name='PageWidth', parent=self.GraphicsPanel, pos=wx.Point(0, 0), lbessard@145: size=wx.Size(0, 24), style=0, min=0, max=2**16) lbessard@145: lbessard@145: self.staticText14 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT14, lbessard@145: label='Height:', name='staticText14', parent=self.GraphicsPanel, lbessard@145: pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0) lbessard@145: lbessard@145: self.PageHeight = wx.SpinCtrl(id=ID_PROJECTDIALOGPAGEHEIGHT, lbessard@145: name='PageHeight', parent=self.GraphicsPanel, pos=wx.Point(0, 0), lbessard@145: size=wx.Size(0, 24), style=0, min=0, max=2**16) lbessard@145: lbessard@145: self.staticText15 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT15, lbessard@145: label='Scaling:', name='staticText15', parent=self.GraphicsPanel, lbessard@145: pos=wx.Point(0, 0), size=wx.Size(200, 17), style=0) lbessard@145: lbessard@145: self.ScalingNotebook = wx.Notebook(id=ID_PROJECTDIALOGSCALINGNOTEBOOK, lbessard@145: name='ScalingNotebook', parent=self.GraphicsPanel, pos=wx.Point(0, lbessard@145: 0), size=wx.Size(0, 0), style=0) lbessard@145: lbessard@145: self.Scalings = {} lbessard@145: for language in ["FBD", "LD", "SFC"]: lbessard@145: window = ScalingPanel(self.ScalingNotebook) lbessard@145: self.Scalings[language] = window lbessard@145: self.ScalingNotebook.AddPage(window, language) lbessard@145: lbessard@145: self.MainNotebook.AddPage(self.GraphicsPanel, "Graphics") lbessard@145: lbessard@145: # Miscellaneous Panel elements lbessard@145: lbessard@145: self.MiscellaneousPanel = wx.Panel(id=ID_PROJECTDIALOGMISCELLANEOUSPANEL, lbessard@145: name='MiscellaneousPanel', parent=self.MainNotebook, pos=wx.Point(0, 0), lbessard@145: size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) lbessard@145: lbessard@145: self.staticText10 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT10, lbessard@145: label='Language (optional):', name='staticText10', parent=self.MiscellaneousPanel, lbessard@145: pos=wx.Point(0, 0), size=wx.Size(200, 17), style=0) lbessard@145: lbessard@145: self.Language = wx.Choice(id=ID_PROJECTDIALOGLANGUAGE, lbessard@145: name='Language', parent=self.MiscellaneousPanel, pos=wx.Point(0, 0), lbessard@64: size=wx.Size(0, 24), style=0) lbessard@64: lbessard@145: self.staticText11 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT11, lbessard@145: label='Content Description (optional):', name='staticText11', parent=self.MiscellaneousPanel, lbessard@64: pos=wx.Point(0, 0), size=wx.Size(200, 17), style=0) lbessard@64: lbessard@64: self.ContentDescription = wx.TextCtrl(id=ID_PROJECTDIALOGCONTENTDESCRIPTION, lbessard@145: name='ContentDescription', parent=self.MiscellaneousPanel, pos=wx.Point(0, 0), lbessard@145: size=wx.Size(0, 24), style=wx.TE_MULTILINE) lbessard@145: lbessard@145: self.MainNotebook.AddPage(self.MiscellaneousPanel, "Miscellaneous") lbessard@64: lbessard@64: self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) lbessard@64: self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId()) lbessard@64: etisserant@0: self._init_sizers() etisserant@0: etisserant@0: def __init__(self, parent): etisserant@0: self._init_ctrls(parent) lbessard@64: lbessard@145: languages = ["", "en-US", "fr-FR"] lbessard@145: lbessard@145: for language in languages: lbessard@145: self.Language.Append(language) lbessard@145: etisserant@0: def OnOK(self, event): etisserant@0: error = [] etisserant@0: if self.ProjectName.GetValue() == "": etisserant@0: error.append("Project Name") etisserant@0: if self.CompanyName.GetValue() == "": etisserant@0: error.append("Company Name") etisserant@0: if self.ProductName.GetValue() == "": etisserant@0: error.append("Product Name") etisserant@0: if self.ProductVersion.GetValue() == "": etisserant@0: error.append("Product Version") etisserant@0: if len(error) > 0: etisserant@0: text = "" etisserant@0: for i, item in enumerate(error): etisserant@0: if i == 0: etisserant@0: text += item etisserant@0: elif i == len(error) - 1: etisserant@0: text += " and %s"%item etisserant@0: else: lbessard@145: text += ", %s"%item lbessard@64: message = wx.MessageDialog(self, "Form isn't complete. %s must be filled!"%text, "Error", wx.OK|wx.ICON_ERROR) etisserant@0: message.ShowModal() etisserant@0: message.Destroy() etisserant@0: else: lbessard@64: self.EndModal(wx.ID_OK) etisserant@0: etisserant@0: def SetValues(self, values): etisserant@0: for item, value in values.items(): etisserant@0: if item == "projectName": etisserant@0: self.ProjectName.SetValue(value) lbessard@145: elif item == "projectVersion": lbessard@145: self.ProjectVersion.SetValue(value) etisserant@0: elif item == "productName": etisserant@0: self.ProductName.SetValue(value) etisserant@0: elif item == "productVersion": etisserant@0: self.ProductVersion.SetValue(value) etisserant@0: elif item == "productRelease": etisserant@0: self.ProductRelease.SetValue(value) lbessard@145: elif item == "companyName": lbessard@145: self.CompanyName.SetValue(value) lbessard@145: elif item == "companyURL": lbessard@145: self.CompanyURL.SetValue(value) lbessard@145: elif item == "authorName": lbessard@145: self.AuthorName.SetValue(value) lbessard@145: elif item == "organization": lbessard@145: self.Organization.SetValue(value) lbessard@145: elif item == "language": lbessard@145: self.Language.SetStringSelection(value) etisserant@0: elif item == "contentDescription": etisserant@0: self.ContentDescription.SetValue(value) lbessard@145: elif item == "pageSize": lbessard@145: self.PageWidth.SetValue(value[0]) lbessard@145: self.PageHeight.SetValue(value[1]) lbessard@145: elif item == "scaling": lbessard@145: for language, (x, y) in value.items(): lbessard@145: if language in self.Scalings: lbessard@145: self.Scalings[language].SetScaling(x, y) lbessard@145: etisserant@0: def GetValues(self): etisserant@0: values = {} etisserant@0: values["projectName"] = self.ProjectName.GetValue() lbessard@145: if self.ProjectVersion.GetValue() != "": lbessard@145: values["projectVersion"] = self.ProjectVersion.GetValue() etisserant@0: values["productName"] = self.ProductName.GetValue() etisserant@0: values["productVersion"] = self.ProductVersion.GetValue() lbessard@145: if self.ProductRelease.GetValue() != "": etisserant@0: values["productRelease"] = self.ProductRelease.GetValue() lbessard@145: values["companyName"] = self.CompanyName.GetValue() lbessard@145: if self.CompanyURL.GetValue() != "": lbessard@145: values["companyURL"] = self.CompanyURL.GetValue() lbessard@145: if self.AuthorName.GetValue() != "": lbessard@145: values["authorName"] = self.AuthorName.GetValue() lbessard@145: if self.Organization.GetValue() != "": lbessard@145: values["organization"] = self.Organization.GetValue() lbessard@145: if self.Language.GetStringSelection() != "": lbessard@145: values["language"] = self.Language.GetStringSelection() lbessard@145: if self.ProductRelease.GetValue() != "": etisserant@0: values["contentDescription"] = self.ContentDescription.GetValue() lbessard@145: values["pageSize"] = (self.PageWidth.GetValue(), self.PageHeight.GetValue()) lbessard@145: values["scaling"] = {} lbessard@145: for language in ["FBD", "LD", "SFC"]: lbessard@145: values["scaling"][language] = self.Scalings[language].GetScaling() etisserant@0: return values etisserant@0: etisserant@0: #------------------------------------------------------------------------------- lbessard@125: # Edit Step Name Dialog lbessard@125: #------------------------------------------------------------------------------- lbessard@125: lbessard@125: class DataTypeDialog(wx.TextEntryDialog): lbessard@125: lbessard@125: if wx.VERSION < (2, 6, 0): lbessard@125: def Bind(self, event, function, id = None): lbessard@125: if id is not None: lbessard@125: event(self, id, function) lbessard@125: else: lbessard@125: event(self, function) lbessard@125: lbessard@125: def __init__(self, parent, message, caption = "Please enter text", defaultValue = "", lbessard@125: style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition): lbessard@125: wx.TextEntryDialog.__init__(self, parent, message, caption, defaultValue, style, pos) lbessard@125: lbessard@125: self.DataTypeNames = [] lbessard@125: if wx.VERSION >= (2, 8, 0): lbessard@125: self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(2).GetSizer().GetItem(1).GetSizer().GetAffirmativeButton().GetId()) lbessard@125: elif wx.VERSION >= (2, 6, 0): lbessard@125: self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetAffirmativeButton().GetId()) lbessard@125: else: lbessard@125: self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId()) lbessard@125: lbessard@125: def OnOK(self, event): lbessard@125: datatype_name = self.GetSizer().GetItem(1).GetWindow().GetValue() lbessard@125: if datatype_name == "": lbessard@125: message = wx.MessageDialog(self, "You must type a name!", "Error", wx.OK|wx.ICON_ERROR) lbessard@125: message.ShowModal() lbessard@125: message.Destroy() lbessard@125: elif not TestIdentifier(datatype_name): lbessard@125: message = wx.MessageDialog(self, "\"%s\" is not a valid identifier!"%datatype_name, "Error", wx.OK|wx.ICON_ERROR) lbessard@125: message.ShowModal() lbessard@125: message.Destroy() lbessard@125: elif datatype_name.upper() in IEC_KEYWORDS: lbessard@125: message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%datatype_name, "Error", wx.OK|wx.ICON_ERROR) lbessard@125: message.ShowModal() lbessard@125: message.Destroy() lbessard@125: elif datatype_name.upper() in self.DataTypeNames: lbessard@125: message = wx.MessageDialog(self, "\"%s\" data type already exists!"%datatype_name, "Error", wx.OK|wx.ICON_ERROR) lbessard@125: message.ShowModal() lbessard@125: message.Destroy() lbessard@125: else: lbessard@125: self.EndModal(wx.ID_OK) lbessard@125: lbessard@125: def SetDataTypeNames(self, datatype_names): lbessard@125: self.DataTypeNames = [datatype_name.upper() for datatype_name in datatype_names] lbessard@125: lbessard@125: def GetValue(self): lbessard@125: return self.GetSizer().GetItem(1).GetWindow().GetValue() lbessard@125: lbessard@125: #------------------------------------------------------------------------------- etisserant@0: # Create Pou Dialog etisserant@0: #------------------------------------------------------------------------------- etisserant@0: lbessard@64: [ID_POUDIALOG, ID_POUDIALOGPOUNAME, lbessard@64: ID_POUDIALOGPOUTYPE, ID_POUDIALOGLANGUAGE, ID_POUDIALOGSTATICTEXT1, lbessard@64: ID_POUDIALOGSTATICTEXT2, ID_POUDIALOGSTATICTEXT3, lbessard@64: ] = [wx.NewId() for _init_ctrls in range(7)] etisserant@0: etisserant@0: class PouDialog(wx.Dialog): lbessard@114: if wx.VERSION < (2, 6, 0): lbessard@114: def Bind(self, event, function, id = None): lbessard@114: if id is not None: lbessard@114: event(self, id, function) lbessard@114: else: lbessard@114: event(self, function) lbessard@114: etisserant@0: def _init_coll_flexGridSizer1_Items(self, parent): lbessard@64: parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) lbessard@64: parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) lbessard@64: lbessard@64: def _init_coll_flexGridSizer1_Growables(self, parent): lbessard@64: parent.AddGrowableCol(0) lbessard@64: parent.AddGrowableRow(0) lbessard@64: lbessard@64: def _init_coll_MainSizer_Items(self, parent): lbessard@118: parent.AddWindow(self.staticText1, 0, border=4, flag=wx.GROW|wx.TOP) lbessard@64: parent.AddWindow(self.PouName, 0, border=0, flag=wx.GROW) lbessard@118: parent.AddWindow(self.staticText2, 0, border=4, flag=wx.GROW|wx.TOP) lbessard@64: parent.AddWindow(self.PouType, 0, border=0, flag=wx.GROW) lbessard@118: parent.AddWindow(self.staticText3, 0, border=4, flag=wx.GROW|wx.TOP) lbessard@64: parent.AddWindow(self.Language, 0, border=0, flag=wx.GROW) lbessard@64: lbessard@64: def _init_coll_MainSizer_Growables(self, parent): lbessard@64: parent.AddGrowableCol(1) lbessard@64: etisserant@0: def _init_sizers(self): lbessard@64: self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) lbessard@64: self.MainSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=3, vgap=15) etisserant@0: etisserant@0: self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) lbessard@64: self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) lbessard@64: self._init_coll_MainSizer_Items(self.MainSizer) lbessard@64: self._init_coll_MainSizer_Growables(self.MainSizer) etisserant@0: etisserant@0: self.SetSizer(self.flexGridSizer1) lbessard@64: etisserant@0: def _init_ctrls(self, prnt): lbessard@64: wx.Dialog.__init__(self, id=ID_POUDIALOG, lbessard@16: name='PouDialog', parent=prnt, pos=wx.Point(376, 223), etisserant@0: size=wx.Size(300, 200), style=wx.DEFAULT_DIALOG_STYLE, lbessard@16: title='Create a new POU') etisserant@0: self.SetClientSize(wx.Size(300, 200)) etisserant@0: lbessard@64: self.staticText1 = wx.StaticText(id=ID_POUDIALOGSTATICTEXT1, lbessard@64: label='POU Name:', name='staticText1', parent=self, lbessard@64: pos=wx.Point(0, 0), size=wx.Size(100, 17), style=0) lbessard@64: lbessard@64: self.PouName = wx.TextCtrl(id=ID_POUDIALOGPOUNAME, lbessard@64: name='POUName', parent=self, pos=wx.Point(0, 0), lbessard@64: size=wx.Size(0, 24), style=0) lbessard@64: lbessard@64: self.staticText2 = wx.StaticText(id=ID_POUDIALOGSTATICTEXT2, lbessard@64: label='POU Type:', name='staticText2', parent=self, lbessard@64: pos=wx.Point(0, 0), size=wx.Size(100, 17), style=0) lbessard@64: lbessard@64: self.PouType = wx.Choice(id=ID_POUDIALOGPOUTYPE, lbessard@64: name='POUType', parent=self, pos=wx.Point(0, 0), lbessard@64: size=wx.Size(0, 24), style=0) lbessard@64: self.Bind(wx.EVT_CHOICE, self.OnTypeChanged, id=ID_POUDIALOGPOUTYPE) lbessard@64: lbessard@64: self.staticText3 = wx.StaticText(id=ID_POUDIALOGSTATICTEXT3, lbessard@64: label='Language:', name='staticText3', parent=self, lbessard@64: pos=wx.Point(0, 0), size=wx.Size(100, 17), style=0) lbessard@64: lbessard@64: self.Language = wx.Choice(id=ID_POUDIALOGLANGUAGE, lbessard@64: name='Language', parent=self, pos=wx.Point(0, 0), lbessard@64: size=wx.Size(0, 24), style=0) lbessard@64: lbessard@64: self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) lbessard@64: self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId()) lbessard@64: etisserant@0: self._init_sizers() etisserant@0: lbessard@163: def __init__(self, parent, pou_type = None): etisserant@0: self._init_ctrls(parent) etisserant@0: lbessard@163: for option in ["function", "functionBlock", "program"]: etisserant@0: self.PouType.Append(option) lbessard@163: if pou_type is not None: lbessard@163: self.PouType.SetStringSelection(pou_type) etisserant@0: self.RefreshLanguage() etisserant@0: lbessard@6: self.PouNames = [] lbessard@70: self.PouElementNames = [] lbessard@6: etisserant@0: def OnOK(self, event): etisserant@0: error = [] etisserant@0: pou_name = self.PouName.GetValue() etisserant@0: if pou_name == "": etisserant@0: error.append("POU Name") etisserant@0: if self.PouType.GetStringSelection() == "": etisserant@0: error.append("POU Type") etisserant@0: if self.Language.GetStringSelection() == "": etisserant@0: error.append("Language") etisserant@0: if len(error) > 0: etisserant@0: text = "" etisserant@0: for i, item in enumerate(error): etisserant@0: if i == 0: etisserant@0: text += item etisserant@0: elif i == len(error) - 1: etisserant@0: text += " and %s"%item etisserant@0: else: etisserant@0: text += ", %s"%item lbessard@64: message = wx.MessageDialog(self, "Form isn't complete. %s must be filled!"%text, "Error", wx.OK|wx.ICON_ERROR) etisserant@0: message.ShowModal() etisserant@0: message.Destroy() etisserant@0: elif not TestIdentifier(pou_name): lbessard@64: message = wx.MessageDialog(self, "\"%s\" is not a valid identifier!"%pou_name, "Error", wx.OK|wx.ICON_ERROR) etisserant@0: message.ShowModal() etisserant@0: message.Destroy() etisserant@0: elif pou_name.upper() in IEC_KEYWORDS: lbessard@64: message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%pou_name, "Error", wx.OK|wx.ICON_ERROR) etisserant@0: message.ShowModal() etisserant@0: message.Destroy() etisserant@0: elif pou_name.upper() in self.PouNames: lbessard@64: message = wx.MessageDialog(self, "\"%s\" pou already exists!"%pou_name, "Error", wx.OK|wx.ICON_ERROR) etisserant@0: message.ShowModal() etisserant@0: message.Destroy() lbessard@70: elif pou_name.upper() in self.PouElementNames: lbessard@70: message = wx.MessageDialog(self, "A pou has an element with \"%s\" for name. It can generate a conflict. Do you wish to continue?"%pou_name, "Warning", wx.YES_NO|wx.ICON_EXCLAMATION) lbessard@70: result = message.ShowModal() lbessard@70: message.Destroy() lbessard@70: if result == wx.ID_YES: lbessard@70: self.EndModal(wx.ID_OK) etisserant@0: else: lbessard@64: self.EndModal(wx.ID_OK) etisserant@0: etisserant@0: def RefreshLanguage(self): etisserant@0: selection = self.Language.GetStringSelection() etisserant@0: self.Language.Clear() etisserant@0: for option in ["IL","ST","LD","FBD","SFC"]: lbessard@64: if option != "SFC" or self.PouType.GetStringSelection() != "function": etisserant@0: self.Language.Append(option) lbessard@64: if self.Language.FindString(selection) != wx.NOT_FOUND: etisserant@0: self.Language.SetStringSelection(selection) etisserant@0: etisserant@0: def OnTypeChanged(self, event): etisserant@0: self.RefreshLanguage() etisserant@0: event.Skip() etisserant@0: etisserant@0: def SetPouNames(self, pou_names): etisserant@0: self.PouNames = [pou_name.upper() for pou_name in pou_names] etisserant@0: lbessard@70: def SetPouElementNames(self, element_names): lbessard@70: self.PouElementNames = [element_name.upper() for element_name in element_names] lbessard@70: etisserant@0: def SetValues(self, values): etisserant@0: for item, value in values.items(): etisserant@0: if item == "pouName": etisserant@0: self.PouName.SetValue(value) etisserant@0: elif item == "pouType": etisserant@0: self.PouType.SetStringSelection(value) etisserant@0: elif item == "language": etisserant@0: self.Language.SetStringSelection(value) etisserant@0: etisserant@0: def GetValues(self): etisserant@0: values = {} etisserant@0: values["pouName"] = self.PouName.GetValue() etisserant@0: values["pouType"] = self.PouType.GetStringSelection() etisserant@0: values["language"] = self.Language.GetStringSelection() etisserant@0: return values etisserant@0: etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Create Pou Transition Dialog etisserant@0: #------------------------------------------------------------------------------- etisserant@0: lbessard@64: [ID_POUTRANSITIONDIALOG, ID_POUTRANSITIONDIALOGTRANSITIONNAME, lbessard@64: ID_POUTRANSITIONDIALOGLANGUAGE, ID_POUTRANSITIONDIALOGSTATICTEXT1, lbessard@64: ID_POUTRANSITIONDIALOGSTATICTEXT2, lbessard@64: ] = [wx.NewId() for _init_ctrls in range(5)] etisserant@0: etisserant@0: class PouTransitionDialog(wx.Dialog): lbessard@114: if wx.VERSION < (2, 6, 0): lbessard@114: def Bind(self, event, function, id = None): lbessard@114: if id is not None: lbessard@114: event(self, id, function) lbessard@114: else: lbessard@114: event(self, function) lbessard@114: etisserant@0: def _init_coll_flexGridSizer1_Items(self, parent): lbessard@64: parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) lbessard@64: parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) lbessard@64: lbessard@64: def _init_coll_flexGridSizer1_Growables(self, parent): lbessard@64: parent.AddGrowableCol(0) lbessard@64: parent.AddGrowableRow(0) lbessard@64: lbessard@64: def _init_coll_MainSizer_Items(self, parent): lbessard@118: parent.AddWindow(self.staticText1, 0, border=4, flag=wx.GROW|wx.TOP) lbessard@64: parent.AddWindow(self.TransitionName, 0, border=0, flag=wx.GROW) lbessard@118: parent.AddWindow(self.staticText2, 0, border=4, flag=wx.GROW|wx.TOP) lbessard@64: parent.AddWindow(self.Language, 0, border=0, flag=wx.GROW) lbessard@64: lbessard@64: def _init_coll_MainSizer_Growables(self, parent): lbessard@64: parent.AddGrowableCol(1) lbessard@64: etisserant@0: def _init_sizers(self): lbessard@64: self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) lbessard@64: self.MainSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=2, vgap=15) etisserant@0: etisserant@0: self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) lbessard@64: self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) lbessard@64: self._init_coll_MainSizer_Items(self.MainSizer) lbessard@64: self._init_coll_MainSizer_Growables(self.MainSizer) etisserant@0: etisserant@0: self.SetSizer(self.flexGridSizer1) etisserant@0: etisserant@0: def _init_ctrls(self, prnt): lbessard@64: wx.Dialog.__init__(self, id=ID_POUTRANSITIONDIALOG, lbessard@45: name='PouTransitionDialog', parent=prnt, pos=wx.Point(376, 223), etisserant@0: size=wx.Size(350, 200), style=wx.DEFAULT_DIALOG_STYLE, lbessard@45: title='Create a new transition') lbessard@45: self.SetClientSize(wx.Size(350, 160)) etisserant@0: lbessard@64: self.staticText1 = wx.StaticText(id=ID_POUTRANSITIONDIALOGSTATICTEXT1, lbessard@64: label='Transition Name:', name='staticText1', parent=self, lbessard@64: pos=wx.Point(0, 0), size=wx.Size(120, 17), style=0) lbessard@64: lbessard@64: self.TransitionName = wx.TextCtrl(id=ID_POUTRANSITIONDIALOGTRANSITIONNAME, lbessard@64: name='TransitionName', parent=self, pos=wx.Point(0, 0), lbessard@64: size=wx.Size(0, 24), style=0) lbessard@64: lbessard@64: self.staticText2 = wx.StaticText(id=ID_POUTRANSITIONDIALOGSTATICTEXT2, lbessard@64: label='Language:', name='staticText2', parent=self, lbessard@64: pos=wx.Point(0, 0), size=wx.Size(120, 17), style=0) lbessard@64: lbessard@64: self.Language = wx.Choice(id=ID_POUTRANSITIONDIALOGLANGUAGE, lbessard@64: name='Language', parent=self, pos=wx.Point(0, 0), lbessard@64: size=wx.Size(0, 24), style=0) lbessard@64: lbessard@64: self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) lbessard@64: self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId()) lbessard@64: etisserant@0: self._init_sizers() etisserant@0: etisserant@0: def __init__(self, parent): etisserant@0: self._init_ctrls(parent) lbessard@45: etisserant@0: for option in ["IL","ST","LD","FBD"]: etisserant@0: self.Language.Append(option) lbessard@70: lbessard@70: self.PouNames = [] lbessard@70: self.PouElementNames = [] etisserant@0: etisserant@0: def OnOK(self, event): etisserant@0: error = [] lbessard@70: transition_name = self.TransitionName.GetValue() etisserant@0: if self.TransitionName.GetValue() == "": etisserant@0: error.append("Transition Name") etisserant@0: if self.Language.GetStringSelection() == "": etisserant@0: error.append("Language") etisserant@0: if len(error) > 0: etisserant@0: text = "" etisserant@0: for i, item in enumerate(error): etisserant@0: if i == 0: etisserant@0: text += item etisserant@0: elif i == len(error) - 1: etisserant@0: text += " and %s"%item etisserant@0: else: etisserant@0: text += ", %s"%item lbessard@64: message = wx.MessageDialog(self, "Form isn't complete. %s must be filled!"%text, "Error", wx.OK|wx.ICON_ERROR) etisserant@0: message.ShowModal() etisserant@0: message.Destroy() lbessard@70: elif not TestIdentifier(transition_name): lbessard@70: message = wx.MessageDialog(self, "\"%s\" is not a valid identifier!"%transition_name, "Error", wx.OK|wx.ICON_ERROR) lbessard@70: message.ShowModal() lbessard@70: message.Destroy() lbessard@70: elif transition_name.upper() in IEC_KEYWORDS: lbessard@70: message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%transition_name, "Error", wx.OK|wx.ICON_ERROR) lbessard@70: message.ShowModal() lbessard@70: message.Destroy() lbessard@70: elif transition_name.upper() in self.PouNames: lbessard@70: message = wx.MessageDialog(self, "A pou with \"%s\" for name exists!"%transition_name, "Error", wx.OK|wx.ICON_ERROR) lbessard@70: message.ShowModal() lbessard@70: message.Destroy() lbessard@70: elif transition_name.upper() in self.PouElementNames: lbessard@70: message = wx.MessageDialog(self, "\"%s\" element for this pou already exists!"%transition_name, "Error", wx.OK|wx.ICON_ERROR) lbessard@70: message.ShowModal() lbessard@70: message.Destroy() etisserant@0: else: lbessard@64: self.EndModal(wx.ID_OK) lbessard@70: lbessard@70: def SetPouNames(self, pou_names): lbessard@70: self.PouNames = [pou_name.upper() for pou_name in pou_names] lbessard@70: lbessard@70: def SetPouElementNames(self, pou_names): lbessard@70: self.PouElementNames = [pou_name.upper() for pou_name in pou_names] lbessard@70: etisserant@0: def SetValues(self, values): etisserant@0: for item, value in values.items(): lbessard@45: if item == "transitionName": etisserant@0: self.TransitionName.SetValue(value) etisserant@0: elif item == "language": etisserant@0: self.Language.SetStringSelection(value) etisserant@0: etisserant@0: def GetValues(self): etisserant@0: values = {} etisserant@0: values["transitionName"] = self.TransitionName.GetValue() etisserant@0: values["language"] = self.Language.GetStringSelection() etisserant@0: return values etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Create Pou Action Dialog etisserant@0: #------------------------------------------------------------------------------- etisserant@0: lbessard@64: [ID_POUACTIONDIALOG, ID_POUACTIONDIALOGACTIONNAME, lbessard@64: ID_POUACTIONDIALOGLANGUAGE, ID_POUACTIONDIALOGSTATICTEXT1, lbessard@64: ID_POUACTIONDIALOGSTATICTEXT2, lbessard@64: ] = [wx.NewId() for _init_ctrls in range(5)] etisserant@0: etisserant@0: class PouActionDialog(wx.Dialog): lbessard@114: if wx.VERSION < (2, 6, 0): lbessard@114: def Bind(self, event, function, id = None): lbessard@114: if id is not None: lbessard@114: event(self, id, function) lbessard@114: else: lbessard@114: event(self, function) lbessard@114: etisserant@0: def _init_coll_flexGridSizer1_Items(self, parent): lbessard@64: parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) lbessard@64: parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) lbessard@64: lbessard@64: def _init_coll_flexGridSizer1_Growables(self, parent): lbessard@64: parent.AddGrowableCol(0) lbessard@64: parent.AddGrowableRow(0) lbessard@64: lbessard@64: def _init_coll_MainSizer_Items(self, parent): lbessard@118: parent.AddWindow(self.staticText1, 0, border=4, flag=wx.GROW|wx.TOP) lbessard@64: parent.AddWindow(self.ActionName, 0, border=0, flag=wx.GROW) lbessard@118: parent.AddWindow(self.staticText2, 0, border=4, flag=wx.GROW|wx.TOP) lbessard@64: parent.AddWindow(self.Language, 0, border=0, flag=wx.GROW) lbessard@64: lbessard@64: def _init_coll_MainSizer_Growables(self, parent): lbessard@64: parent.AddGrowableCol(1) lbessard@64: etisserant@0: def _init_sizers(self): lbessard@64: self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) lbessard@64: self.MainSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=2, vgap=15) etisserant@0: etisserant@0: self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) lbessard@64: self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) lbessard@64: self._init_coll_MainSizer_Items(self.MainSizer) lbessard@64: self._init_coll_MainSizer_Growables(self.MainSizer) etisserant@0: etisserant@0: self.SetSizer(self.flexGridSizer1) etisserant@0: etisserant@0: def _init_ctrls(self, prnt): lbessard@64: wx.Dialog.__init__(self, id=ID_POUACTIONDIALOG, lbessard@45: name='PouActionDialog', parent=prnt, pos=wx.Point(376, 223), lbessard@64: size=wx.Size(320, 200), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER, lbessard@45: title='Create a new action') lbessard@45: self.SetClientSize(wx.Size(320, 160)) etisserant@0: lbessard@64: self.staticText1 = wx.StaticText(id=ID_POUACTIONDIALOGSTATICTEXT1, lbessard@64: label='Action Name:', name='staticText1', parent=self, lbessard@64: pos=wx.Point(0, 0), size=wx.Size(100, 17), style=0) lbessard@64: lbessard@64: self.ActionName = wx.TextCtrl(id=ID_POUACTIONDIALOGACTIONNAME, lbessard@64: name='ActionName', parent=self, pos=wx.Point(0, 0), lbessard@64: size=wx.Size(0, 24), style=0) lbessard@64: lbessard@64: self.staticText2 = wx.StaticText(id=ID_POUACTIONDIALOGSTATICTEXT2, lbessard@64: label='Language:', name='staticText2', parent=self, lbessard@64: pos=wx.Point(0, 0), size=wx.Size(100, 17), style=0) lbessard@64: lbessard@64: self.Language = wx.Choice(id=ID_POUACTIONDIALOGLANGUAGE, lbessard@64: name='Language', parent=self, pos=wx.Point(0, 0), lbessard@64: size=wx.Size(0, 24), style=0) lbessard@64: lbessard@64: self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) lbessard@64: self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId()) lbessard@64: etisserant@0: self._init_sizers() etisserant@0: etisserant@0: def __init__(self, parent): etisserant@0: self._init_ctrls(parent) lbessard@45: etisserant@0: for option in ["IL","ST","LD","FBD"]: etisserant@0: self.Language.Append(option) etisserant@0: lbessard@70: self.PouNames = [] lbessard@70: self.PouElementNames = [] lbessard@70: etisserant@0: def OnOK(self, event): etisserant@0: error = [] lbessard@70: action_name = self.ActionName.GetValue() lbessard@70: if action_name == "": etisserant@0: error.append("Action Name") etisserant@0: if self.Language.GetStringSelection() == "": etisserant@0: error.append("Language") etisserant@0: if len(error) > 0: etisserant@0: text = "" etisserant@0: for i, item in enumerate(error): etisserant@0: if i == 0: etisserant@0: text += item etisserant@0: elif i == len(error) - 1: etisserant@0: text += " and %s"%item etisserant@0: else: etisserant@0: text += ", %s"%item lbessard@64: message = wx.MessageDialog(self, "Form isn't complete. %s must be filled!"%text, "Error", wx.OK|wx.ICON_ERROR) etisserant@0: message.ShowModal() etisserant@0: message.Destroy() lbessard@70: elif not TestIdentifier(action_name): lbessard@70: message = wx.MessageDialog(self, "\"%s\" is not a valid identifier!"%action_name, "Error", wx.OK|wx.ICON_ERROR) lbessard@70: message.ShowModal() lbessard@70: message.Destroy() lbessard@70: elif action_name.upper() in IEC_KEYWORDS: lbessard@70: message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%action_name, "Error", wx.OK|wx.ICON_ERROR) lbessard@70: message.ShowModal() lbessard@70: message.Destroy() lbessard@70: elif action_name.upper() in self.PouNames: lbessard@70: message = wx.MessageDialog(self, "A pou with \"%s\" for name exists!"%action_name, "Error", wx.OK|wx.ICON_ERROR) lbessard@70: message.ShowModal() lbessard@70: message.Destroy() lbessard@70: elif action_name.upper() in self.PouElementNames: lbessard@70: message = wx.MessageDialog(self, "\"%s\" element for this pou already exists!"%action_name, "Error", wx.OK|wx.ICON_ERROR) lbessard@70: message.ShowModal() lbessard@70: message.Destroy() etisserant@0: else: lbessard@64: self.EndModal(wx.ID_OK) lbessard@70: lbessard@70: def SetPouNames(self, pou_names): lbessard@70: self.PouNames = [pou_name.upper() for pou_name in pou_names] lbessard@70: lbessard@70: def SetPouElementNames(self, element_names): lbessard@70: self.PouElementNames = [element_name.upper() for element_name in element_names] lbessard@70: etisserant@0: def SetValues(self, values): etisserant@0: for item, value in values.items(): lbessard@45: if item == "actionName": etisserant@0: self.ActionName.SetValue(value) etisserant@0: elif item == "language": etisserant@0: self.Language.SetStringSelection(value) etisserant@0: etisserant@0: def GetValues(self): etisserant@0: values = {} etisserant@0: values["actionName"] = self.ActionName.GetValue() etisserant@0: values["language"] = self.Language.GetStringSelection() etisserant@0: return values etisserant@0: etisserant@0: #------------------------------------------------------------------------------- lbessard@80: # Configuration Name Dialog lbessard@80: #------------------------------------------------------------------------------- lbessard@80: lbessard@80: class ConfigurationNameDialog(wx.TextEntryDialog): lbessard@80: lbessard@114: if wx.VERSION < (2, 6, 0): lbessard@114: def Bind(self, event, function, id = None): lbessard@114: if id is not None: lbessard@114: event(self, id, function) lbessard@114: else: lbessard@114: event(self, function) lbessard@114: lbessard@80: def __init__(self, parent, message, caption = "Please enter configuration name", defaultValue = "", lbessard@80: style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition): lbessard@80: wx.TextEntryDialog.__init__(self, parent, message, caption, defaultValue, style, pos) lbessard@80: lbessard@80: self.PouNames = [] lbessard@80: self.PouElementNames = [] lbessard@80: lbessard@144: if wx.VERSION >= (2, 8, 0): lbessard@144: self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(2).GetSizer().GetItem(1).GetSizer().GetAffirmativeButton().GetId()) lbessard@144: elif wx.VERSION >= (2, 6, 0): lbessard@144: self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetAffirmativeButton().GetId()) lbessard@144: else: lbessard@144: self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId()) lbessard@144: lbessard@80: def OnOK(self, event): lbessard@80: config_name = self.GetSizer().GetItem(1).GetWindow().GetValue() lbessard@80: if config_name == "": lbessard@80: message = wx.MessageDialog(self, "You must type a name!", "Error", wx.OK|wx.ICON_ERROR) lbessard@80: message.ShowModal() lbessard@80: message.Destroy() lbessard@80: elif not TestIdentifier(config_name): lbessard@80: message = wx.MessageDialog(self, "\"%s\" is not a valid identifier!"%config_name, "Error", wx.OK|wx.ICON_ERROR) lbessard@80: message.ShowModal() lbessard@80: message.Destroy() lbessard@80: elif config_name.upper() in IEC_KEYWORDS: lbessard@80: message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%config_name, "Error", wx.OK|wx.ICON_ERROR) lbessard@80: message.ShowModal() lbessard@80: message.Destroy() lbessard@80: elif config_name.upper() in self.PouNames: lbessard@80: message = wx.MessageDialog(self, "A pou with \"%s\" as name exists!"%config_name, "Error", wx.OK|wx.ICON_ERROR) lbessard@80: message.ShowModal() lbessard@80: message.Destroy() lbessard@80: elif config_name.upper() in self.PouElementNames: lbessard@80: message = wx.MessageDialog(self, "A pou has an element with \"%s\" for name. It can generate a conflict. Do you wish to continue?"%config_name, "Warning", wx.YES_NO|wx.ICON_EXCLAMATION) lbessard@80: result = message.ShowModal() lbessard@80: message.Destroy() lbessard@80: if result == wx.ID_YES: lbessard@80: self.EndModal(wx.ID_OK) lbessard@80: else: lbessard@80: self.EndModal(wx.ID_OK) lbessard@80: lbessard@80: def SetPouNames(self, pou_names): lbessard@80: self.PouNames = [pou_name.upper() for pou_name in pou_names] lbessard@80: lbessard@80: def SetPouElementNames(self, pou_names): lbessard@80: self.PouElementNames = [pou_name.upper() for pou_name in pou_names] lbessard@80: lbessard@80: def GetValue(self): lbessard@80: return self.GetSizer().GetItem(1).GetWindow().GetValue() lbessard@80: lbessard@80: #------------------------------------------------------------------------------- lbessard@80: # Resource Name Dialog lbessard@80: #------------------------------------------------------------------------------- lbessard@80: lbessard@80: class ResourceNameDialog(wx.TextEntryDialog): lbessard@80: lbessard@114: if wx.VERSION < (2, 6, 0): lbessard@114: def Bind(self, event, function, id = None): lbessard@114: if id is not None: lbessard@114: event(self, id, function) lbessard@114: else: lbessard@114: event(self, function) lbessard@114: lbessard@80: def __init__(self, parent, message, caption = "Please enter resource name", defaultValue = "", lbessard@80: style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition): lbessard@80: wx.TextEntryDialog.__init__(self, parent, message, caption, defaultValue, style, pos) lbessard@80: lbessard@80: self.PouNames = [] lbessard@80: self.PouElementNames = [] lbessard@80: lbessard@144: if wx.VERSION >= (2, 8, 0): lbessard@144: self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(2).GetSizer().GetItem(1).GetSizer().GetAffirmativeButton().GetId()) lbessard@144: elif wx.VERSION >= (2, 6, 0): lbessard@144: self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetAffirmativeButton().GetId()) lbessard@144: else: lbessard@144: self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId()) lbessard@144: lbessard@80: def OnOK(self, event): lbessard@80: resource_name = self.GetSizer().GetItem(1).GetWindow().GetValue() lbessard@80: if resource_name == "": lbessard@80: message = wx.MessageDialog(self, "You must type a name!", "Error", wx.OK|wx.ICON_ERROR) lbessard@80: message.ShowModal() lbessard@80: message.Destroy() lbessard@80: elif not TestIdentifier(resource_name): lbessard@80: message = wx.MessageDialog(self, "\"%s\" is not a valid identifier!"%resource_name, "Error", wx.OK|wx.ICON_ERROR) lbessard@80: message.ShowModal() lbessard@80: message.Destroy() lbessard@80: elif resource_name.upper() in IEC_KEYWORDS: lbessard@80: message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%resource_name, "Error", wx.OK|wx.ICON_ERROR) lbessard@80: message.ShowModal() lbessard@80: message.Destroy() lbessard@80: elif resource_name.upper() in self.PouNames: lbessard@80: message = wx.MessageDialog(self, "A pou with \"%s\" as name exists!"%resource_name, "Error", wx.OK|wx.ICON_ERROR) lbessard@80: message.ShowModal() lbessard@80: message.Destroy() lbessard@80: elif resource_name.upper() in self.PouElementNames: lbessard@80: message = wx.MessageDialog(self, "A pou has an element with \"%s\" for name. It can generate a conflict. Do you wish to continue?"%resource_name, "Warning", wx.YES_NO|wx.ICON_EXCLAMATION) lbessard@80: result = message.ShowModal() lbessard@80: message.Destroy() lbessard@80: if result == wx.ID_YES: lbessard@80: self.EndModal(wx.ID_OK) lbessard@80: else: lbessard@80: self.EndModal(wx.ID_OK) lbessard@80: lbessard@80: def SetPouNames(self, pou_names): lbessard@80: self.PouNames = [pou_name.upper() for pou_name in pou_names] lbessard@80: lbessard@80: def SetPouElementNames(self, pou_names): lbessard@80: self.PouElementNames = [pou_name.upper() for pou_name in pou_names] lbessard@80: lbessard@80: def GetValue(self): lbessard@80: return self.GetSizer().GetItem(1).GetWindow().GetValue() lbessard@80: lbessard@80: #------------------------------------------------------------------------------- lbessard@121: # Variables Editor Panel lbessard@121: #------------------------------------------------------------------------------- lbessard@121: lbessard@121: class VariablePanelIndexer(wx.Panel): lbessard@121: lbessard@121: def _init_sizers(self): lbessard@121: self.MainSizer = wx.BoxSizer(wx.HORIZONTAL) lbessard@121: lbessard@121: self.SetSizer(self.MainSizer) lbessard@121: lbessard@121: def _init_ctrls(self, prnt): lbessard@121: wx.Panel.__init__(self, id=wx.NewId(), lbessard@121: name='VariablePanelIndexer', parent=prnt, pos=wx.Point(0, 0), lbessard@121: size=wx.Size(0, 300), style=wx.TAB_TRAVERSAL) lbessard@121: lbessard@121: self._init_sizers() lbessard@121: lbessard@145: def __init__(self, parent, window, controler): lbessard@121: self._init_ctrls(parent) lbessard@121: lbessard@145: self.ParentWindow = window lbessard@121: self.Controler = controler lbessard@121: lbessard@121: self.VariablePanelList = {} lbessard@121: self.CurrentPanel = None lbessard@121: lbessard@121: def AddVariablePanel(self, tagname, element_type): lbessard@121: new_panel = VariablePanel(self, self.ParentWindow, self.Controler, element_type) lbessard@121: new_panel.SetTagName(tagname) lbessard@121: new_panel.Hide() lbessard@121: new_panel.RefreshView() lbessard@121: self.MainSizer.AddWindow(new_panel, 1, border=0, flag=wx.GROW) lbessard@121: self.VariablePanelList[tagname] = new_panel lbessard@121: lbessard@121: def RemoveVariablePanel(self, tagname): lbessard@121: if tagname in self.VariablePanelList: lbessard@121: panel = self.VariablePanelList.pop(tagname) lbessard@121: self.MainSizer.Remove(panel) lbessard@294: panel.Destroy() lbessard@121: if self.CurrentPanel == tagname: lbessard@121: self.CurrentPanel = None lbessard@121: lbessard@121: def RemoveAllPanels(self): lbessard@294: for tagname in self.VariablePanelList.keys(): lbessard@294: self.RemoveVariablePanel(tagname) lbessard@121: lbessard@121: def UpdateVariablePanelTagName(self, old_tagname, new_tagname): lbessard@145: if old_tagname in self.VariablePanelList: lbessard@121: self.VariablePanelList[new_tagname] = self.VariablePanelList.pop(old_tagname) lbessard@121: if self.CurrentPanel == old_tagname: lbessard@121: self.CurrentPanel = new_tagname lbessard@121: lbessard@121: def ChangeVariablePanel(self, tagname): lbessard@125: if tagname in self.VariablePanelList: lbessard@125: if tagname != self.CurrentPanel: lbessard@125: if self.CurrentPanel is not None: lbessard@125: self.VariablePanelList[self.CurrentPanel].Hide() lbessard@125: self.CurrentPanel = tagname lbessard@125: self.VariablePanelList[self.CurrentPanel].RefreshView() lbessard@125: self.VariablePanelList[self.CurrentPanel].Show() lbessard@125: self.MainSizer.Layout() lbessard@125: else: lbessard@121: if self.CurrentPanel is not None: lbessard@121: self.VariablePanelList[self.CurrentPanel].Hide() lbessard@125: self.CurrentPanel = None lbessard@121: self.MainSizer.Layout() lbessard@121: lbessard@121: def RefreshVariablePanel(self, tagname): lbessard@121: if tagname in self.VariablePanelList: lbessard@121: self.VariablePanelList[self.CurrentPanel].RefreshView() lbessard@121: lbessard@231: def AddVariableError(self, infos): lbessard@231: self.ChangeVariablePanel(infos[0]) lbessard@231: if self.CurrentPanel is not None: lbessard@231: self.VariablePanelList[self.CurrentPanel].AddVariableError(infos[2:]) lbessard@231: lbessard@231: def ClearErrors(self): lbessard@231: for panel in self.VariablePanelList.values(): lbessard@231: panel.ClearErrors() lbessard@231: lbessard@121: #------------------------------------------------------------------------------- lbessard@121: # Variables Editor Panel etisserant@0: #------------------------------------------------------------------------------- etisserant@0: lbessard@64: class VariableTable(wx.grid.PyGridTableBase): etisserant@0: etisserant@0: """ lbessard@64: A custom wx.grid.Grid Table using user supplied data etisserant@0: """ etisserant@0: def __init__(self, parent, data, colnames): etisserant@0: # The base class must be initialized *first* lbessard@64: wx.grid.PyGridTableBase.__init__(self) etisserant@0: self.data = data lbessard@58: self.old_value = None etisserant@0: self.colnames = colnames lbessard@231: self.Errors = {} etisserant@0: self.Parent = parent etisserant@0: # XXX etisserant@0: # we need to store the row length and collength to etisserant@0: # see if the table has changed size etisserant@0: self._rows = self.GetNumberRows() etisserant@0: self._cols = self.GetNumberCols() etisserant@0: etisserant@0: def GetNumberCols(self): etisserant@0: return len(self.colnames) etisserant@0: etisserant@0: def GetNumberRows(self): etisserant@0: return len(self.data) etisserant@0: etisserant@0: def GetColLabelValue(self, col): etisserant@0: if col < len(self.colnames): etisserant@0: return self.colnames[col] etisserant@0: etisserant@0: def GetRowLabelValues(self, row): etisserant@0: return row etisserant@0: etisserant@0: def GetValue(self, row, col): etisserant@0: if row < self.GetNumberRows(): lbessard@47: if col == 0: lbessard@80: return self.data[row]["Number"] etisserant@0: name = str(self.data[row].get(self.GetColLabelValue(col), "")) etisserant@0: return name etisserant@0: etisserant@0: def SetValue(self, row, col, value): etisserant@0: if col < len(self.colnames): lbessard@58: colname = self.GetColLabelValue(col) lbessard@58: if colname == "Name": lbessard@58: self.old_value = self.data[row][colname] lbessard@58: self.data[row][colname] = value lbessard@58: lbessard@68: def GetValueByName(self, row, colname): lbessard@68: if row < self.GetNumberRows(): lbessard@68: return self.data[row].get(colname) lbessard@68: lbessard@68: def SetValueByName(self, row, colname, value): lbessard@68: if row < self.GetNumberRows(): lbessard@68: self.data[row][colname] = value lbessard@68: lbessard@58: def GetOldValue(self): lbessard@58: return self.old_value lbessard@58: etisserant@0: def ResetView(self, grid): etisserant@0: """ lbessard@64: (wx.grid.Grid) -> Reset the grid view. Call this to etisserant@0: update the grid if rows and columns have been added or deleted etisserant@0: """ etisserant@0: grid.BeginBatch() etisserant@0: for current, new, delmsg, addmsg in [ lbessard@64: (self._rows, self.GetNumberRows(), wx.grid.GRIDTABLE_NOTIFY_ROWS_DELETED, wx.grid.GRIDTABLE_NOTIFY_ROWS_APPENDED), lbessard@64: (self._cols, self.GetNumberCols(), wx.grid.GRIDTABLE_NOTIFY_COLS_DELETED, wx.grid.GRIDTABLE_NOTIFY_COLS_APPENDED), etisserant@0: ]: etisserant@0: if new < current: lbessard@64: msg = wx.grid.GridTableMessage(self,delmsg,new,current-new) etisserant@0: grid.ProcessTableMessage(msg) etisserant@0: elif new > current: lbessard@64: msg = wx.grid.GridTableMessage(self,addmsg,new-current) etisserant@0: grid.ProcessTableMessage(msg) etisserant@0: self.UpdateValues(grid) etisserant@0: grid.EndBatch() etisserant@0: etisserant@0: self._rows = self.GetNumberRows() etisserant@0: self._cols = self.GetNumberCols() etisserant@0: # update the column rendering scheme etisserant@0: self._updateColAttrs(grid) etisserant@0: etisserant@0: # update the scrollbars and the displayed part of the grid etisserant@0: grid.AdjustScrollbars() etisserant@0: grid.ForceRefresh() etisserant@0: etisserant@0: def UpdateValues(self, grid): etisserant@0: """Update all displayed values""" etisserant@0: # This sends an event to the grid table to update all of the values lbessard@64: msg = wx.grid.GridTableMessage(self, wx.grid.GRIDTABLE_REQUEST_VIEW_GET_VALUES) etisserant@0: grid.ProcessTableMessage(msg) etisserant@0: etisserant@0: def _updateColAttrs(self, grid): etisserant@0: """ lbessard@64: wx.grid.Grid -> update the column attributes to add the etisserant@0: appropriate renderer given the column name. etisserant@0: etisserant@0: Otherwise default to the default renderer. etisserant@0: """ etisserant@0: etisserant@0: typelist = None etisserant@0: accesslist = None etisserant@0: for row in range(self.GetNumberRows()): etisserant@0: for col in range(self.GetNumberCols()): etisserant@0: editor = None etisserant@0: renderer = None etisserant@0: colname = self.GetColLabelValue(col) lbessard@68: if col != 0 and self.GetValueByName(row, "Edit"): lbessard@68: grid.SetReadOnly(row, col, False) lbessard@68: if colname == "Name": lbessard@68: if self.Parent.PouIsUsed and self.GetValueByName(row, "Class") in ["Input", "Output", "InOut"]: lbessard@68: grid.SetReadOnly(row, col, True) lbessard@68: else: lbessard@68: editor = wx.grid.GridCellTextEditor() lbessard@68: renderer = wx.grid.GridCellStringRenderer() lbessard@107: elif colname == "Initial Value": lbessard@64: editor = wx.grid.GridCellTextEditor() lbessard@64: renderer = wx.grid.GridCellStringRenderer() lbessard@107: elif colname == "Location": lbessard@107: if self.GetValueByName(row, "Class") in ["Local", "Global"]: lbessard@107: editor = wx.grid.GridCellTextEditor() lbessard@107: renderer = wx.grid.GridCellStringRenderer() lbessard@107: else: lbessard@107: grid.SetReadOnly(row, col, True) lbessard@68: elif colname == "Class": lbessard@68: if len(self.Parent.ClassList) == 1 or self.Parent.PouIsUsed and self.GetValueByName(row, "Class") in ["Input", "Output", "InOut"]: lbessard@68: grid.SetReadOnly(row, col, True) lbessard@68: else: lbessard@68: editor = wx.grid.GridCellChoiceEditor() lbessard@68: excluded = [] lbessard@68: if self.Parent.PouIsUsed: lbessard@253: excluded.extend(["Input","Output","InOut"]) lbessard@253: if self.Parent.IsFunctionBlockType(self.data[row]["Type"]): lbessard@253: excluded.extend(["Local","Temp"]) lbessard@68: editor.SetParameters(",".join([choice for choice in self.Parent.ClassList if choice not in excluded])) lbessard@68: elif colname in ["Retain", "Constant"]: lbessard@64: editor = wx.grid.GridCellChoiceEditor() lbessard@68: editor.SetParameters(self.Parent.OptionList) lbessard@68: elif colname == "Type": lbessard@68: editor = wx.grid.GridCellTextEditor() lbessard@68: else: lbessard@68: grid.SetReadOnly(row, col, True) lbessard@68: etisserant@0: grid.SetCellEditor(row, col, editor) etisserant@0: grid.SetCellRenderer(row, col, renderer) etisserant@0: lbessard@231: if row in self.Errors and self.Errors[row][0] == colname.lower(): lbessard@231: grid.SetCellBackgroundColour(row, col, wx.Colour(255, 255, 0)) lbessard@231: grid.SetCellTextColour(row, col, wx.RED) lbessard@231: grid.MakeCellVisible(row, col) lbessard@231: else: lbessard@231: grid.SetCellTextColour(row, col, wx.BLACK) lbessard@231: grid.SetCellBackgroundColour(row, col, wx.WHITE) etisserant@0: etisserant@0: def SetData(self, data): etisserant@0: self.data = data etisserant@0: etisserant@0: def GetData(self): etisserant@0: return self.data etisserant@0: etisserant@0: def GetCurrentIndex(self): etisserant@0: return self.CurrentIndex etisserant@0: etisserant@0: def SetCurrentIndex(self, index): etisserant@0: self.CurrentIndex = index etisserant@0: etisserant@0: def AppendRow(self, row_content): etisserant@0: self.data.append(row_content) etisserant@0: etisserant@0: def RemoveRow(self, row_index): etisserant@0: self.data.pop(row_index) lbessard@12: lbessard@12: def GetRow(self, row_index): lbessard@12: return self.data[row_index] etisserant@0: etisserant@0: def Empty(self): etisserant@0: self.data = [] etisserant@0: self.editors = [] etisserant@0: lbessard@231: def AddError(self, infos): lbessard@231: self.Errors[infos[0]] = infos[1:] lbessard@231: lbessard@231: def ClearErrors(self): lbessard@231: self.Errors = {} lbessard@231: lbessard@53: class VariableDropTarget(wx.TextDropTarget): lbessard@53: lbessard@53: def __init__(self, parent): lbessard@53: wx.TextDropTarget.__init__(self) lbessard@90: self.ParentWindow = parent lbessard@53: lbessard@53: def OnDropText(self, x, y, data): lbessard@182: x, y = self.ParentWindow.VariablesGrid.CalcUnscrolledPosition(x, y) lbessard@90: col = self.ParentWindow.VariablesGrid.XToCol(x) lbessard@97: row = self.ParentWindow.VariablesGrid.YToRow(y - self.ParentWindow.VariablesGrid.GetColLabelSize()) lbessard@64: if col != wx.NOT_FOUND and row != wx.NOT_FOUND: lbessard@90: if self.ParentWindow.Table.GetColLabelValue(col) != "Location": lbessard@53: return lbessard@107: message = None lbessard@107: if not self.ParentWindow.Table.GetValueByName(row, "Edit"): lbessard@107: message = "Can't affect a location to a function block instance" lbessard@107: elif self.ParentWindow.Table.GetValueByName(row, "Class") not in ["Local", "Global"]: lbessard@107: message = "Can affect a location only to local or global variables" lbessard@107: else: lbessard@107: try: lbessard@107: values = eval(data) lbessard@107: except: lbessard@218: message = "Invalid value \"%s\" for location"%data lbessard@107: values = None lbessard@218: if not isinstance(values, TupleType): lbessard@218: message = "Invalid value \"%s\" for location"%data lbessard@218: values = None lbessard@218: if values is not None and values[1] == "location": lbessard@107: location = values[0] lbessard@107: variable_type = self.ParentWindow.Table.GetValueByName(row, "Type") lbessard@266: base_type = self.ParentWindow.Controler.GetBaseType(variable_type) lbessard@107: message = None lbessard@210: if location.startswith("%"): lbessard@219: if base_type != values[2]: lbessard@210: message = "Incompatible data types between \"%s\" and \"%s\""%(values[2], variable_type) lbessard@210: else: lbessard@107: self.ParentWindow.Table.SetValue(row, col, location) lbessard@107: self.ParentWindow.Table.ResetView(self.ParentWindow.VariablesGrid) lbessard@107: self.ParentWindow.SaveValues() lbessard@210: else: lbessard@219: if location[0].isdigit() and base_type != "BOOL": lbessard@210: message = "Incompatible size of data between \"%s\" and \"BOOL\""%location lbessard@210: elif location[0] not in LOCATIONDATATYPES: lbessard@210: message = "Unrecognized data size \"%s\""%location[0] lbessard@219: elif base_type not in LOCATIONDATATYPES[location[0]]: lbessard@210: message = "Incompatible size of data between \"%s\" and \"%s\""%(location, variable_type) lbessard@210: else: lbessard@210: dialog = wx.SingleChoiceDialog(self.ParentWindow, "Select a variable class:", "Variable class", ["Input", "Output", "Memory"], wx.OK|wx.CANCEL) lbessard@210: if dialog.ShowModal() == wx.ID_OK: lbessard@210: selected = dialog.GetSelection() lbessard@210: if selected == 0: lbessard@210: location = "%I" + location lbessard@210: elif selected == 1: lbessard@210: location = "%Q" + location lbessard@210: else: lbessard@210: location = "%M" + location lbessard@210: self.ParentWindow.Table.SetValue(row, col, location) lbessard@210: self.ParentWindow.Table.ResetView(self.ParentWindow.VariablesGrid) lbessard@210: self.ParentWindow.SaveValues() lbessard@210: dialog.Destroy() lbessard@249: if message is not None: lbessard@218: wx.CallAfter(self.ShowMessage, message) lbessard@218: lbessard@218: def ShowMessage(self, message): lbessard@249: message = wx.MessageDialog(self.ParentWindow, message, "Error", wx.OK|wx.ICON_ERROR) lbessard@249: message.ShowModal() lbessard@249: message.Destroy() lbessard@53: lbessard@121: [ID_VARIABLEEDITORPANEL, ID_VARIABLEEDITORPANELVARIABLESGRID, lbessard@121: ID_VARIABLEEDITORPANELRETURNTYPE, ID_VARIABLEEDITORPANELCLASSFILTER, lbessard@121: ID_VARIABLEEDITORPANELADDBUTTON, ID_VARIABLEEDITORPANELDELETEBUTTON, lbessard@121: ID_VARIABLEEDITORPANELUPBUTTON, ID_VARIABLEEDITORPANELDOWNBUTTON, lbessard@121: ID_VARIABLEEDITORPANELSTATICTEXT1, ID_VARIABLEEDITORPANELSTATICTEXT2, lbessard@121: ID_VARIABLEEDITORPANELSTATICTEXT3, lbessard@121: ] = [wx.NewId() for _init_ctrls in range(11)] lbessard@121: lbessard@121: class VariablePanel(wx.Panel): lbessard@114: lbessard@114: if wx.VERSION < (2, 6, 0): lbessard@114: def Bind(self, event, function, id = None): lbessard@114: if id is not None: lbessard@114: event(self, id, function) lbessard@114: else: lbessard@114: event(self, function) lbessard@114: lbessard@121: def _init_coll_MainSizer_Items(self, parent): lbessard@64: parent.AddWindow(self.VariablesGrid, 0, border=0, flag=wx.GROW) lbessard@64: parent.AddSizer(self.ControlPanelSizer, 0, border=0, flag=wx.GROW) lbessard@47: lbessard@121: def _init_coll_MainSizer_Growables(self, parent): lbessard@47: parent.AddGrowableCol(0) lbessard@47: parent.AddGrowableRow(0) lbessard@47: lbessard@47: def _init_coll_ControlPanelSizer_Items(self, parent): lbessard@64: parent.AddSizer(self.ChoicePanelSizer, 0, border=0, flag=wx.GROW) lbessard@64: parent.AddSizer(self.ButtonPanelSizer, 0, border=0, flag=wx.ALIGN_CENTER) lbessard@47: lbessard@47: def _init_coll_ControlPanelSizer_Growables(self, parent): lbessard@47: parent.AddGrowableCol(0) lbessard@47: parent.AddGrowableRow(0) lbessard@47: parent.AddGrowableRow(1) lbessard@47: lbessard@47: def _init_coll_ChoicePanelSizer_Items(self, parent): lbessard@64: parent.AddWindow(self.staticText1, 0, border=0, flag=wx.ALIGN_BOTTOM) etisserant@52: parent.AddWindow(self.ReturnType, 0, border=0, flag=0) lbessard@64: parent.AddWindow(self.staticText2, 0, border=0, flag=wx.ALIGN_BOTTOM) lbessard@47: parent.AddWindow(self.ClassFilter, 0, border=0, flag=0) lbessard@47: lbessard@47: def _init_coll_ButtonPanelSizer_Items(self, parent): etisserant@52: parent.AddWindow(self.UpButton, 0, border=0, flag=0) lbessard@51: parent.AddWindow(self.AddButton, 0, border=0, flag=0) etisserant@52: parent.AddWindow(self.DownButton, 0, border=0, flag=0) lbessard@51: parent.AddWindow(self.DeleteButton, 0, border=0, flag=0) etisserant@52: lbessard@47: def _init_coll_ButtonPanelSizer_Growables(self, parent): lbessard@47: parent.AddGrowableCol(0) lbessard@47: parent.AddGrowableCol(1) lbessard@47: parent.AddGrowableCol(2) lbessard@47: parent.AddGrowableCol(3) lbessard@47: parent.AddGrowableRow(0) etisserant@0: etisserant@0: def _init_sizers(self): lbessard@121: self.MainSizer = wx.FlexGridSizer(cols=2, hgap=10, rows=1, vgap=0) etisserant@52: self.ControlPanelSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) etisserant@52: self.ChoicePanelSizer = wx.GridSizer(cols=1, hgap=5, rows=4, vgap=5) etisserant@52: self.ButtonPanelSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=0) lbessard@47: lbessard@121: self._init_coll_MainSizer_Items(self.MainSizer) lbessard@121: self._init_coll_MainSizer_Growables(self.MainSizer) lbessard@47: self._init_coll_ControlPanelSizer_Items(self.ControlPanelSizer) lbessard@47: self._init_coll_ControlPanelSizer_Growables(self.ControlPanelSizer) lbessard@47: self._init_coll_ChoicePanelSizer_Items(self.ChoicePanelSizer) lbessard@47: self._init_coll_ButtonPanelSizer_Items(self.ButtonPanelSizer) lbessard@47: self._init_coll_ButtonPanelSizer_Growables(self.ButtonPanelSizer) lbessard@47: lbessard@121: self.SetSizer(self.MainSizer) lbessard@121: lbessard@121: def _init_ctrls(self, prnt): lbessard@121: wx.Panel.__init__(self, id=ID_VARIABLEEDITORPANEL, lbessard@121: name='VariableEditorPanel', parent=prnt, pos=wx.Point(0, 0), lbessard@80: size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) lbessard@68: lbessard@121: self.staticText1 = wx.StaticText(id=ID_VARIABLEEDITORPANELSTATICTEXT1, lbessard@121: label='Return Type:', name='staticText1', parent=self, lbessard@47: pos=wx.Point(0, 0), size=wx.Size(95, 17), style=0) lbessard@47: lbessard@121: self.ReturnType = wx.Choice(id=ID_VARIABLEEDITORPANELRETURNTYPE, lbessard@121: name='ReturnType', parent=self, pos=wx.Point(0, 0), etisserant@52: size=wx.Size(145, 24), style=0) lbessard@121: self.Bind(wx.EVT_CHOICE, self.OnReturnTypeChanged, id=ID_VARIABLEEDITORPANELRETURNTYPE) lbessard@121: lbessard@121: self.staticText2 = wx.StaticText(id=ID_VARIABLEEDITORPANELSTATICTEXT2, lbessard@121: label='Class Filter:', name='staticText2', parent=self, lbessard@47: pos=wx.Point(0, 0), size=wx.Size(95, 17), style=0) lbessard@47: lbessard@121: self.ClassFilter = wx.Choice(id=ID_VARIABLEEDITORPANELCLASSFILTER, lbessard@121: name='ClassFilter', parent=self, pos=wx.Point(0, 0), etisserant@52: size=wx.Size(145, 24), style=0) lbessard@121: self.Bind(wx.EVT_CHOICE, self.OnClassFilter, id=ID_VARIABLEEDITORPANELCLASSFILTER) lbessard@121: lbessard@121: self.VariablesGrid = wx.grid.Grid(id=ID_VARIABLEEDITORPANELVARIABLESGRID, lbessard@121: name='VariablesGrid', parent=self, pos=wx.Point(0, 0), lbessard@64: size=wx.Size(0, 150), style=wx.VSCROLL) etisserant@0: self.VariablesGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False, etisserant@0: 'Sans')) etisserant@0: self.VariablesGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL, etisserant@0: False, 'Sans')) lbessard@107: self.VariablesGrid.SetSelectionBackground(wx.WHITE) lbessard@107: self.VariablesGrid.SetSelectionForeground(wx.BLACK) lbessard@114: if wx.VERSION >= (2, 6, 0): lbessard@114: self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnVariablesGridCellChange) lbessard@114: self.VariablesGrid.Bind(wx.grid.EVT_GRID_SELECT_CELL, self.OnVariablesGridSelectCell) lbessard@114: self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.OnVariablesGridCellLeftClick) lbessard@114: self.VariablesGrid.Bind(wx.grid.EVT_GRID_EDITOR_SHOWN, self.OnVariablesGridEditorShown) lbessard@114: else: lbessard@114: wx.grid.EVT_GRID_CELL_CHANGE(self.VariablesGrid, self.OnVariablesGridCellChange) lbessard@114: wx.grid.EVT_GRID_SELECT_CELL(self.VariablesGrid, self.OnVariablesGridSelectCell) lbessard@114: wx.grid.EVT_GRID_CELL_LEFT_CLICK(self.VariablesGrid, self.OnVariablesGridCellLeftClick) lbessard@114: wx.grid.EVT_GRID_EDITOR_SHOWN(self.VariablesGrid, self.OnVariablesGridEditorShown) lbessard@53: self.VariablesGrid.SetDropTarget(VariableDropTarget(self)) lbessard@53: lbessard@121: self.AddButton = wx.Button(id=ID_VARIABLEEDITORPANELADDBUTTON, label='Add', lbessard@294: name='AddButton', parent=self, pos=wx.Point(0, 0), etisserant@0: size=wx.Size(72, 32), style=0) lbessard@121: self.Bind(wx.EVT_BUTTON, self.OnAddButton, id=ID_VARIABLEEDITORPANELADDBUTTON) lbessard@121: lbessard@121: self.DeleteButton = wx.Button(id=ID_VARIABLEEDITORPANELDELETEBUTTON, label='Delete', lbessard@294: name='DeleteButton', parent=self, pos=wx.Point(0, 0), etisserant@0: size=wx.Size(72, 32), style=0) lbessard@121: self.Bind(wx.EVT_BUTTON, self.OnDeleteButton, id=ID_VARIABLEEDITORPANELDELETEBUTTON) lbessard@121: lbessard@121: self.UpButton = wx.Button(id=ID_VARIABLEEDITORPANELUPBUTTON, label='^', lbessard@294: name='UpButton', parent=self, pos=wx.Point(0, 0), etisserant@0: size=wx.Size(32, 32), style=0) lbessard@121: self.Bind(wx.EVT_BUTTON, self.OnUpButton, id=ID_VARIABLEEDITORPANELUPBUTTON) lbessard@121: lbessard@121: self.DownButton = wx.Button(id=ID_VARIABLEEDITORPANELDOWNBUTTON, label='v', lbessard@294: name='DownButton', parent=self, pos=wx.Point(0, 0), etisserant@0: size=wx.Size(32, 32), style=0) lbessard@121: self.Bind(wx.EVT_BUTTON, self.OnDownButton, id=ID_VARIABLEEDITORPANELDOWNBUTTON) lbessard@68: etisserant@0: self._init_sizers() etisserant@0: lbessard@121: def __init__(self, parent, window, controler, element_type): lbessard@121: self._init_ctrls(parent) lbessard@90: self.ParentWindow = window lbessard@47: self.Controler = controler lbessard@47: self.ElementType = element_type lbessard@47: lbessard@47: self.Filter = "All" etisserant@0: self.FilterChoices = [] etisserant@0: self.FilterChoiceTransfer = {"All" : "All", "Interface" : "Interface", lbessard@37: " Input" : "Input", " Output" : "Output", " InOut" : "InOut", lbessard@37: " External" : "External", "Variables" : "Variables", " Local" : "Local", lbessard@37: " Temp" : "Temp", "Global" : "Global", "Access" : "Access"} etisserant@0: lbessard@121: if element_type in ["config", "resource"]: lbessard@47: self.DefaultTypes = {"All" : "Global"} lbessard@80: self.DefaultValue = {"Name" : "", "Class" : "", "Type" : "INT", "Location" : "", "Initial Value" : "", "Retain" : "No", "Constant" : "No", "Edit" : True} lbessard@47: else: lbessard@37: self.DefaultTypes = {"All" : "Local", "Interface" : "Input", "Variables" : "Local"} lbessard@80: self.DefaultValue = {"Name" : "", "Class" : "", "Type" : "INT", "Location" : "", "Initial Value" : "", "Retain" : "No", "Constant" : "No", "Edit" : True} lbessard@121: if element_type in ["config", "resource"] or element_type in ["program", "transition", "action"]: lbessard@70: self.Table = VariableTable(self, [], ["#", "Name", "Class", "Type", "Location", "Initial Value", "Retain", "Constant"]) lbessard@121: if element_type not in ["config", "resource"]: etisserant@0: self.FilterChoices = ["All","Interface"," Input"," Output"," InOut"," External","Variables"," Local"," Temp","Global","Access"] etisserant@0: else: etisserant@0: self.FilterChoices = ["All","Global","Access"] lbessard@70: self.ColSizes = [40, 80, 70, 80, 80, 80, 60, 70] lbessard@70: self.ColAlignements = [wx.ALIGN_CENTER, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_CENTER, wx.ALIGN_CENTER] lbessard@70: else: lbessard@70: self.Table = VariableTable(self, [], ["#", "Name", "Class", "Type", "Initial Value", "Retain", "Constant"]) etisserant@0: self.FilterChoices = ["All","Interface"," Input"," Output"," InOut"," External","Variables"," Local"," Temp"] lbessard@70: self.ColSizes = [40, 120, 70, 80, 120, 60, 70] lbessard@70: self.ColAlignements = [wx.ALIGN_CENTER, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_CENTER, wx.ALIGN_CENTER] etisserant@0: for choice in self.FilterChoices: etisserant@0: self.ClassFilter.Append(choice) lbessard@37: reverse_transfer = {} lbessard@37: for filter, choice in self.FilterChoiceTransfer.items(): lbessard@37: reverse_transfer[choice] = filter lbessard@37: self.ClassFilter.SetStringSelection(reverse_transfer[self.Filter]) etisserant@0: self.RefreshTypeList() etisserant@0: etisserant@0: self.OptionList = "Yes,No" etisserant@0: lbessard@121: if element_type == "function": lbessard@125: for base_type in self.Controler.GetBaseTypes(): lbessard@125: self.ReturnType.Append(base_type) etisserant@0: self.ReturnType.Enable(True) etisserant@0: else: etisserant@0: self.ReturnType.Enable(False) lbessard@47: self.staticText1.Hide() etisserant@0: self.ReturnType.Hide() etisserant@0: etisserant@0: self.VariablesGrid.SetTable(self.Table) etisserant@0: self.VariablesGrid.SetRowLabelSize(0) lbessard@107: for col in range(self.Table.GetNumberCols()): lbessard@107: attr = wx.grid.GridCellAttr() lbessard@107: attr.SetAlignment(self.ColAlignements[col], wx.ALIGN_CENTRE) lbessard@107: self.VariablesGrid.SetColAttr(col, attr) lbessard@107: self.VariablesGrid.SetColSize(col, self.ColSizes[col]) lbessard@107: lbessard@121: def SetTagName(self, tagname): lbessard@121: self.TagName = tagname lbessard@121: lbessard@253: def IsFunctionBlockType(self, name): lbessard@253: bodytype = self.Controler.GetEditedElementBodyType(self.TagName, self.ParentWindow.Debug) lbessard@253: pouname, poutype = self.Controler.GetEditedElementType(self.TagName, self.ParentWindow.Debug) lbessard@253: if poutype != "function" and bodytype in ["ST", "IL"]: lbessard@253: return False lbessard@253: else: lbessard@253: return name in self.Controler.GetFunctionBlockTypes(self.TagName, self.ParentWindow.Debug) lbessard@253: lbessard@47: def RefreshView(self): lbessard@249: self.PouNames = self.Controler.GetProjectPouNames(self.ParentWindow.Debug) lbessard@47: lbessard@121: words = self.TagName.split("::") lbessard@47: if self.ElementType == "config": lbessard@47: self.PouIsUsed = False lbessard@47: returnType = None lbessard@249: self.Values = self.Controler.GetConfigurationGlobalVars(words[1], self.ParentWindow.Debug) lbessard@47: elif self.ElementType == "resource": lbessard@47: self.PouIsUsed = False lbessard@47: returnType = None lbessard@249: self.Values = self.Controler.GetConfigurationResourceGlobalVars(words[1], words[2], self.ParentWindow.Debug) lbessard@249: else: lbessard@249: self.PouIsUsed = self.Controler.PouIsUsed(words[1], self.ParentWindow.Debug) lbessard@249: returnType = self.Controler.GetEditedElementInterfaceReturnType(self.TagName, self.ParentWindow.Debug) lbessard@249: self.Values = self.Controler.GetEditedElementInterfaceVars(self.TagName, self.ParentWindow.Debug) lbessard@68: lbessard@68: if returnType and self.ReturnType.IsEnabled(): lbessard@68: self.ReturnType.SetStringSelection(returnType) lbessard@68: lbessard@68: self.RefreshValues() lbessard@68: self.RefreshButtons() lbessard@67: lbessard@80: def OnReturnTypeChanged(self, event): lbessard@121: words = self.TagName.split("::") lbessard@121: self.Controler.SetPouInterfaceReturnType(words[1], self.ReturnType.GetStringSelection()) lbessard@80: self.Controler.BufferProject() lbessard@258: self.ParentWindow.RefreshEditor(variablepanel = False) lbessard@90: self.ParentWindow.RefreshTitle() lbessard@90: self.ParentWindow.RefreshEditMenu() lbessard@258: self.ParentWindow.RefreshInstancesTree() lbessard@268: self.ParentWindow.RefreshLibraryTree() lbessard@80: event.Skip() lbessard@80: etisserant@0: def OnClassFilter(self, event): lbessard@37: self.Filter = self.FilterChoiceTransfer[self.ClassFilter.GetStringSelection()] etisserant@0: self.RefreshTypeList() etisserant@0: self.RefreshValues() lbessard@37: self.RefreshButtons() etisserant@0: event.Skip() etisserant@0: etisserant@0: def RefreshTypeList(self): etisserant@0: if self.Filter == "All": lbessard@37: self.ClassList = [self.FilterChoiceTransfer[choice] for choice in self.FilterChoices if self.FilterChoiceTransfer[choice] not in ["All","Interface","Variables"]] etisserant@0: elif self.Filter == "Interface": etisserant@0: self.ClassList = ["Input","Output","InOut","External"] etisserant@0: elif self.Filter == "Variables": etisserant@0: self.ClassList = ["Local","Temp"] etisserant@0: else: etisserant@0: self.ClassList = [self.Filter] etisserant@0: lbessard@37: def RefreshButtons(self): lbessard@102: if getattr(self, "Table", None): lbessard@56: table_length = len(self.Table.data) lbessard@56: row_class = None lbessard@56: if table_length and self.PouIsUsed: lbessard@56: row = self.VariablesGrid.GetGridCursorRow() lbessard@56: row_class = self.Table.GetValueByName(row, "Class") lbessard@56: self.AddButton.Enable(not self.PouIsUsed or self.Filter not in ["Interface", "Input", "Output", "InOut"]) lbessard@56: self.DeleteButton.Enable(table_length > 0 and row_class not in ["Input", "Output", "InOut"]) lbessard@56: self.UpButton.Enable(table_length > 0 and self.Filter == "All" and row_class not in ["Input", "Output", "InOut"]) lbessard@56: self.DownButton.Enable(table_length > 0 and self.Filter == "All" and row_class not in ["Input", "Output", "InOut"]) lbessard@47: etisserant@0: def OnAddButton(self, event): lbessard@11: new_row = self.DefaultValue.copy() lbessard@11: if self.Filter in self.DefaultTypes: lbessard@11: new_row["Class"] = self.DefaultTypes[self.Filter] lbessard@11: else: lbessard@11: new_row["Class"] = self.Filter lbessard@12: self.Values.append(new_row) lbessard@68: self.SaveValues() lbessard@12: self.RefreshValues() lbessard@37: self.RefreshButtons() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnDeleteButton(self, event): lbessard@12: row = self.Table.GetRow(self.VariablesGrid.GetGridCursorRow()) lbessard@12: self.Values.remove(row) lbessard@68: self.SaveValues() lbessard@12: self.RefreshValues() lbessard@37: self.RefreshButtons() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnUpButton(self, event): lbessard@12: self.MoveValue(self.VariablesGrid.GetGridCursorRow(), -1) lbessard@37: self.RefreshButtons() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnDownButton(self, event): lbessard@12: self.MoveValue(self.VariablesGrid.GetGridCursorRow(), 1) lbessard@37: self.RefreshButtons() etisserant@0: event.Skip() etisserant@0: lbessard@6: def OnVariablesGridCellChange(self, event): lbessard@6: row, col = event.GetRow(), event.GetCol() lbessard@6: colname = self.Table.GetColLabelValue(col) lbessard@6: value = self.Table.GetValue(row, col) lbessard@6: if colname == "Name": lbessard@6: if not TestIdentifier(value): lbessard@64: message = wx.MessageDialog(self, "\"%s\" is not a valid identifier!"%value, "Error", wx.OK|wx.ICON_ERROR) lbessard@6: message.ShowModal() lbessard@6: message.Destroy() lbessard@6: event.Veto() lbessard@6: elif value.upper() in IEC_KEYWORDS: lbessard@64: message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%value, "Error", wx.OK|wx.ICON_ERROR) lbessard@6: message.ShowModal() lbessard@6: message.Destroy() lbessard@6: event.Veto() lbessard@6: elif value.upper() in self.PouNames: lbessard@64: message = wx.MessageDialog(self, "A pou with \"%s\" as name exists!"%value, "Error", wx.OK|wx.ICON_ERROR) lbessard@6: message.ShowModal() lbessard@6: message.Destroy() lbessard@6: event.Veto() lbessard@6: elif value.upper() in [var["Name"].upper() for var in self.Values if var != self.Table.data[row]]: lbessard@64: message = wx.MessageDialog(self, "A variable with \"%s\" as name exists in this pou!"%value, "Error", wx.OK|wx.ICON_ERROR) lbessard@6: message.ShowModal() lbessard@6: message.Destroy() lbessard@6: event.Veto() lbessard@6: else: lbessard@58: self.SaveValues(False) lbessard@58: old_value = self.Table.GetOldValue() lbessard@58: if old_value != "": lbessard@121: self.Controler.UpdateEditedElementUsedVariable(self.TagName, old_value, value) lbessard@58: self.Controler.BufferProject() lbessard@121: self.ParentWindow.RefreshEditor(variablepanel = False) lbessard@90: self.ParentWindow.RefreshTitle() lbessard@90: self.ParentWindow.RefreshEditMenu() lbessard@239: self.ParentWindow.RefreshInstancesTree() lbessard@268: self.ParentWindow.RefreshLibraryTree() lbessard@6: event.Skip() lbessard@6: else: lbessard@47: self.SaveValues() lbessard@107: if colname == "Class": lbessard@107: self.Table.ResetView(self.VariablesGrid) lbessard@6: event.Skip() lbessard@68: lbessard@68: def OnVariablesGridEditorShown(self, event): lbessard@68: row, col = event.GetRow(), event.GetCol() lbessard@253: classtype = self.Table.GetValueByName(row, "Class") lbessard@68: if self.Table.GetColLabelValue(col) == "Type": lbessard@68: type_menu = wx.Menu(title='') lbessard@68: base_menu = wx.Menu(title='') lbessard@125: for base_type in self.Controler.GetBaseTypes(): lbessard@68: new_id = wx.NewId() lbessard@114: AppendMenu(base_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=base_type) lbessard@68: self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(base_type), id=new_id) lbessard@114: type_menu.AppendMenu(wx.NewId(), "Base Types", base_menu) lbessard@125: datatype_menu = wx.Menu(title='') lbessard@253: for datatype in self.Controler.GetDataTypes(basetypes = False, debug = self.ParentWindow.Debug): lbessard@125: new_id = wx.NewId() lbessard@125: AppendMenu(datatype_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=datatype) lbessard@125: self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(datatype), id=new_id) lbessard@125: type_menu.AppendMenu(wx.NewId(), "User Data Types", datatype_menu) lbessard@68: functionblock_menu = wx.Menu(title='') lbessard@253: bodytype = self.Controler.GetEditedElementBodyType(self.TagName, self.ParentWindow.Debug) lbessard@253: pouname, poutype = self.Controler.GetEditedElementType(self.TagName, self.ParentWindow.Debug) lbessard@253: if classtype in ["Input","Output","InOut","External","Global"] or poutype != "function" and bodytype in ["ST", "IL"]: lbessard@253: for functionblock_type in self.Controler.GetFunctionBlockTypes(self.TagName, self.ParentWindow.Debug): lbessard@253: new_id = wx.NewId() lbessard@253: AppendMenu(functionblock_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=functionblock_type) lbessard@253: self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(functionblock_type), id=new_id) lbessard@253: type_menu.AppendMenu(wx.NewId(), "Function Block Types", functionblock_menu) lbessard@68: rect = self.VariablesGrid.BlockToDeviceRect((row, col), (row, col)) lbessard@68: self.VariablesGrid.PopupMenuXY(type_menu, rect.x + rect.width, rect.y + self.VariablesGrid.GetColLabelSize()) lbessard@68: event.Veto() lbessard@68: else: lbessard@68: event.Skip() lbessard@68: lbessard@68: def GetVariableTypeFunction(self, base_type): lbessard@68: def VariableTypeFunction(event): lbessard@68: row = self.VariablesGrid.GetGridCursorRow() lbessard@68: self.Table.SetValueByName(row, "Type", base_type) lbessard@68: self.Table.ResetView(self.VariablesGrid) lbessard@98: self.SaveValues(False) lbessard@121: self.ParentWindow.RefreshEditor(variablepanel = False) lbessard@98: self.Controler.BufferProject() lbessard@98: self.ParentWindow.RefreshTitle() lbessard@98: self.ParentWindow.RefreshEditMenu() lbessard@268: self.ParentWindow.RefreshInstancesTree() lbessard@268: self.ParentWindow.RefreshLibraryTree() lbessard@68: event.Skip() lbessard@68: return VariableTypeFunction lbessard@68: lbessard@68: def OnVariablesGridCellLeftClick(self, event): lbessard@211: row = event.GetRow() lbessard@211: if event.GetCol() == 0 and self.Table.GetValueByName(row, "Edit"): lbessard@47: row = event.GetRow() lbessard@47: var_name = self.Table.GetValueByName(row, "Name") lbessard@47: var_class = self.Table.GetValueByName(row, "Class") lbessard@47: var_type = self.Table.GetValueByName(row, "Type") lbessard@121: data = wx.TextDataObject(str((var_name, var_class, var_type, self.TagName))) lbessard@64: dragSource = wx.DropSource(self.VariablesGrid) lbessard@47: dragSource.SetData(data) lbessard@135: dragSource.DoDragDrop() lbessard@47: event.Skip() lbessard@47: lbessard@37: def OnVariablesGridSelectCell(self, event): lbessard@64: wx.CallAfter(self.RefreshButtons) lbessard@37: event.Skip() lbessard@37: lbessard@12: def MoveValue(self, value_index, move): lbessard@12: new_index = max(0, min(value_index + move, len(self.Values) - 1)) lbessard@12: if new_index != value_index: lbessard@12: self.Values.insert(new_index, self.Values.pop(value_index)) lbessard@268: self.SaveValues() lbessard@28: self.RefreshValues() lbessard@12: self.VariablesGrid.SetGridCursor(new_index, self.VariablesGrid.GetGridCursorCol()) lbessard@268: etisserant@0: def RefreshValues(self): lbessard@37: if len(self.Table.data) > 0: lbessard@47: self.VariablesGrid.SetGridCursor(0, 1) etisserant@0: data = [] lbessard@80: for num, variable in enumerate(self.Values): etisserant@0: if variable["Class"] in self.ClassList: lbessard@80: variable["Number"] = num + 1 etisserant@0: data.append(variable) etisserant@0: self.Table.SetData(data) etisserant@0: self.Table.ResetView(self.VariablesGrid) lbessard@47: lbessard@58: def SaveValues(self, buffer = True): lbessard@121: words = self.TagName.split("::") lbessard@47: if self.ElementType == "config": lbessard@121: self.Controler.SetConfigurationGlobalVars(words[1], self.Values) lbessard@47: elif self.ElementType == "resource": lbessard@121: self.Controler.SetConfigurationResourceGlobalVars(words[1], words[2], self.Values) lbessard@47: else: lbessard@47: if self.ReturnType.IsEnabled(): lbessard@121: self.Controler.SetPouInterfaceReturnType(words[1], self.ReturnType.GetStringSelection()) lbessard@121: self.Controler.SetPouInterfaceVars(words[1], self.Values) lbessard@58: if buffer: lbessard@58: self.Controler.BufferProject() lbessard@90: self.ParentWindow.RefreshTitle() lbessard@90: self.ParentWindow.RefreshEditMenu() lbessard@268: self.ParentWindow.RefreshInstancesTree() lbessard@268: self.ParentWindow.RefreshLibraryTree() lbessard@47: lbessard@231: def AddVariableError(self, infos): lbessard@231: if isinstance(infos[0], TupleType): lbessard@231: for i in xrange(*infos[0]): lbessard@231: self.Table.AddError((i,) + infos[1:]) lbessard@231: else: lbessard@231: self.Table.AddError(infos) lbessard@231: self.Table.ResetView(self.VariablesGrid) lbessard@231: lbessard@231: def ClearErrors(self): lbessard@231: self.Table.ClearErrors() lbessard@231: self.Table.ResetView(self.VariablesGrid) lbessard@231: lbessard@213: UPPER_DIV = lambda x, y: (x / y) + {True : 0, False : 1}[(x % y) == 0] lbessard@213: lbessard@213: class GraphicPrintout(wx.Printout): lbessard@213: def __init__(self, viewer, page_size, margins, preview = False): lbessard@213: wx.Printout.__init__(self) lbessard@213: self.Viewer = viewer lbessard@213: self.PageSize = page_size lbessard@221: if self.PageSize[0] == 0 or self.PageSize[1] == 0: lbessard@221: self.PageSize = (1050, 1485) lbessard@213: self.Preview = preview lbessard@213: self.Margins = margins lbessard@221: self.FontSize = 5 lbessard@221: self.TextMargin = 3 lbessard@213: lbessard@213: maxx, maxy = viewer.GetMaxSize() lbessard@221: self.PageGrid = (UPPER_DIV(maxx, self.PageSize[0]), lbessard@221: UPPER_DIV(maxy, self.PageSize[1])) lbessard@213: lbessard@213: def GetPageNumber(self): lbessard@213: return self.PageGrid[0] * self.PageGrid[1] lbessard@213: lbessard@213: def HasPage(self, page): lbessard@213: return page <= self.GetPageNumber() lbessard@213: lbessard@213: def GetPageInfo(self): lbessard@213: page_number = self.GetPageNumber() lbessard@213: return (1, page_number, 1, page_number) lbessard@213: lbessard@213: def OnBeginDocument(self, startPage, endPage): lbessard@213: dc = self.GetDC() lbessard@213: if not self.Preview and isinstance(dc, wx.PostScriptDC): lbessard@213: dc.SetResolution(720) lbessard@213: super(GraphicPrintout, self).OnBeginDocument(startPage, endPage) lbessard@213: lbessard@213: def OnPrintPage(self, page): lbessard@213: dc = self.GetDC() lbessard@221: dc.SetUserScale(1.0, 1.0) lbessard@221: dc.SetDeviceOrigin(0, 0) lbessard@213: dc.printing = not self.Preview lbessard@213: lbessard@213: # Get the size of the DC in pixels lbessard@213: ppiPrinterX, ppiPrinterY = self.GetPPIPrinter() lbessard@213: ppiScreenX, ppiScreenY = self.GetPPIScreen() lbessard@213: pw, ph = self.GetPageSizePixels() lbessard@213: dw, dh = dc.GetSizeTuple() lbessard@213: Xscale = (float(dw) * float(ppiPrinterX)) / (float(pw) * 25.4) lbessard@213: Yscale = (float(dh) * float(ppiPrinterY)) / (float(ph) * 25.4) lbessard@213: lbessard@221: fontsize = self.FontSize * Yscale lbessard@221: text_margin = self.TextMargin * Yscale lbessard@221: lbessard@213: margin_left = self.Margins[0].x * Xscale lbessard@213: margin_top = self.Margins[0].y * Yscale lbessard@213: area_width = dw - self.Margins[1].x * Xscale - margin_left lbessard@213: area_height = dh - self.Margins[1].y * Yscale - margin_top lbessard@213: lbessard@213: dc.SetPen(wx.BLACK_PEN) lbessard@213: dc.SetBrush(wx.TRANSPARENT_BRUSH) lbessard@213: dc.DrawRectangle(margin_left, margin_top, area_width, area_height) lbessard@213: lbessard@221: dc.SetFont(wx.Font(fontsize, wx.DEFAULT, wx.NORMAL, wx.NORMAL)) lbessard@213: dc.SetTextForeground(wx.BLACK) lbessard@213: block_name = " - ".join(self.Viewer.GetTagName().split("::")[1:]) lbessard@213: text_width, text_height = dc.GetTextExtent(block_name) lbessard@213: dc.DrawText(block_name, margin_left, margin_top - text_height - self.TextMargin) lbessard@213: dc.DrawText("Page: %d" % page, margin_left, margin_top + area_height + self.TextMargin) lbessard@213: lbessard@213: # Calculate the position on the DC for centering the graphic lbessard@213: posX = area_width * ((page - 1) % self.PageGrid[0]) lbessard@213: posY = area_height * ((page - 1) / self.PageGrid[0]) lbessard@213: lbessard@213: scaleX = float(area_width) / float(self.PageSize[0]) lbessard@213: scaleY = float(area_height) / float(self.PageSize[1]) lbessard@213: scale = min(scaleX, scaleY) lbessard@213: lbessard@213: # Set the scale and origin lbessard@213: dc.SetDeviceOrigin(-posX + margin_left, -posY + margin_top) lbessard@221: dc.SetClippingRegion(posX, posY, self.PageSize[0] * scale, self.PageSize[1] * scale) lbessard@213: dc.SetUserScale(scale, scale) lbessard@213: lbessard@213: #------------------------------------------- lbessard@213: lbessard@213: self.Viewer.DoDrawing(dc, True) lbessard@213: lbessard@213: return True lbessard@213: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Exception Handler etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: Max_Traceback_List_Size = 20 etisserant@0: etisserant@0: def Display_Exception_Dialog(e_type,e_value,e_tb): etisserant@0: trcbck_lst = [] etisserant@0: for i,line in enumerate(traceback.extract_tb(e_tb)): etisserant@0: trcbck = " " + str(i+1) + ". " etisserant@0: if line[0].find(os.getcwd()) == -1: etisserant@0: trcbck += "file : " + str(line[0]) + ", " etisserant@0: else: etisserant@0: trcbck += "file : " + str(line[0][len(os.getcwd()):]) + ", " etisserant@0: trcbck += "line : " + str(line[1]) + ", " + "function : " + str(line[2]) etisserant@0: trcbck_lst.append(trcbck) etisserant@0: etisserant@0: # Allow clicking.... etisserant@0: cap = wx.Window_GetCapture() etisserant@0: if cap: etisserant@0: cap.ReleaseMouse() etisserant@0: etisserant@0: dlg = wx.SingleChoiceDialog(None, etisserant@0: """ etisserant@0: An error happens. etisserant@0: etisserant@0: Click on OK for saving an error report. etisserant@0: etisserant@0: Please contact LOLITech at: etisserant@0: +33 (0)3 29 52 95 67 etisserant@0: bugs_PLCOpenEditor@lolitech.fr etisserant@0: etisserant@0: etisserant@0: Error: etisserant@0: """ + etisserant@0: str(e_type) + " : " + str(e_value), etisserant@0: "Error", etisserant@0: trcbck_lst) etisserant@0: try: etisserant@0: res = (dlg.ShowModal() == wx.ID_OK) etisserant@0: finally: etisserant@0: dlg.Destroy() etisserant@0: etisserant@0: return res etisserant@0: etisserant@0: def Display_Error_Dialog(e_value): lbessard@64: message = wx.MessageDialog(None, str(e_value), "Error", wx.OK|wx.ICON_ERROR) etisserant@0: message.ShowModal() etisserant@0: message.Destroy() etisserant@0: etisserant@0: def get_last_traceback(tb): etisserant@0: while tb.tb_next: etisserant@0: tb = tb.tb_next etisserant@0: return tb etisserant@0: etisserant@0: etisserant@0: def format_namespace(d, indent=' '): etisserant@0: return '\n'.join(['%s%s: %s' % (indent, k, repr(v)[:10000]) for k, v in d.iteritems()]) etisserant@0: etisserant@0: etisserant@0: ignored_exceptions = [] # a problem with a line in a module is only reported once per session etisserant@0: lbessard@65: def AddExceptHook(path, app_version='[No version]'):#, ignored_exceptions=[]): etisserant@0: etisserant@0: def handle_exception(e_type, e_value, e_traceback): etisserant@0: traceback.print_exception(e_type, e_value, e_traceback) # this is very helpful when there's an exception in the rest of this func etisserant@0: last_tb = get_last_traceback(e_traceback) etisserant@0: ex = (last_tb.tb_frame.f_code.co_filename, last_tb.tb_frame.f_lineno) etisserant@0: if str(e_value).startswith("!!!"): etisserant@0: Display_Error_Dialog(e_value) etisserant@0: elif ex not in ignored_exceptions: etisserant@0: result = Display_Exception_Dialog(e_type,e_value,e_traceback) etisserant@0: if result: etisserant@0: ignored_exceptions.append(ex) etisserant@0: info = { etisserant@0: 'app-title' : wx.GetApp().GetAppName(), # app_title etisserant@0: 'app-version' : app_version, etisserant@0: 'wx-version' : wx.VERSION_STRING, etisserant@0: 'wx-platform' : wx.Platform, etisserant@0: 'python-version' : platform.python_version(), #sys.version.split()[0], etisserant@0: 'platform' : platform.platform(), etisserant@0: 'e-type' : e_type, etisserant@0: 'e-value' : e_value, etisserant@0: 'date' : time.ctime(), etisserant@0: 'cwd' : os.getcwd(), etisserant@0: } etisserant@0: if e_traceback: etisserant@0: info['traceback'] = ''.join(traceback.format_tb(e_traceback)) + '%s: %s' % (e_type, e_value) etisserant@0: last_tb = get_last_traceback(e_traceback) etisserant@0: exception_locals = last_tb.tb_frame.f_locals # the locals at the level of the stack trace where the exception actually occurred etisserant@0: info['locals'] = format_namespace(exception_locals) etisserant@0: if 'self' in exception_locals: etisserant@0: info['self'] = format_namespace(exception_locals['self'].__dict__) etisserant@0: etisserant@0: output = open(path+os.sep+"bug_report_"+info['date'].replace(':','-').replace(' ','_')+".txt",'w') etisserant@0: lst = info.keys() etisserant@0: lst.sort() etisserant@0: for a in lst: etisserant@0: output.write(a+":\n"+str(info[a])+"\n\n") etisserant@0: etisserant@0: #sys.excepthook = lambda *args: wx.CallAfter(handle_exception, *args) etisserant@0: sys.excepthook = handle_exception etisserant@0: etisserant@0: if __name__ == '__main__': lbessard@92: def usage(): lbessard@92: print "\nUsage of PLCOpenEditor.py :" lbessard@92: print "\n %s [Filepath]\n"%sys.argv[0] lbessard@92: lbessard@92: try: lbessard@92: opts, args = getopt.getopt(sys.argv[1:], "h", ["help"]) lbessard@92: except getopt.GetoptError: lbessard@92: # print help information and exit: lbessard@92: usage() lbessard@92: sys.exit(2) lbessard@92: lbessard@92: for o, a in opts: lbessard@92: if o in ("-h", "--help"): lbessard@92: usage() lbessard@92: sys.exit() lbessard@92: lbessard@92: fileOpen = None lbessard@92: if len(args) > 1: lbessard@92: usage() lbessard@92: sys.exit() lbessard@92: elif len(args) == 1: lbessard@92: fileOpen = args[0] lbessard@92: lbessard@64: app = wx.PySimpleApp() lbessard@64: wx.InitAllImageHandlers() etisserant@0: etisserant@0: # Install a exception handle for bug reports lbessard@65: AddExceptHook(os.getcwd(),__version__) etisserant@0: lbessard@92: frame = PLCOpenEditor(None, fileOpen=fileOpen) etisserant@0: etisserant@0: frame.Show() etisserant@0: app.MainLoop() etisserant@0: