andrej@1511: #!/usr/bin/env python andrej@1511: # -*- coding: utf-8 -*- andrej@1511: andrej@1511: # This file is part of Beremiz, a Integrated Development Environment for andrej@1511: # programming IEC 61131-3 automates supporting plcopen standard and CanFestival. andrej@1511: # andrej@1511: # Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD andrej@1511: # andrej@1511: # See COPYING file for copyrights details. andrej@1511: # andrej@1511: # This program is free software; you can redistribute it and/or andrej@1511: # modify it under the terms of the GNU General Public License andrej@1511: # as published by the Free Software Foundation; either version 2 andrej@1511: # of the License, or (at your option) any later version. andrej@1511: # andrej@1511: # This program is distributed in the hope that it will be useful, andrej@1511: # but WITHOUT ANY WARRANTY; without even the implied warranty of andrej@1511: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the andrej@1511: # GNU General Public License for more details. andrej@1511: # andrej@1511: # You should have received a copy of the GNU General Public License andrej@1511: # along with this program; if not, write to the Free Software andrej@1511: # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Laurent@814: Laurent@814: import os, sys Laurent@814: import cPickle Laurent@814: from types import TupleType Laurent@814: Laurent@814: import wx, wx.grid Laurent@814: import wx.aui Laurent@814: Laurent@814: from editors.EditorPanel import EditorPanel Laurent@814: from editors.SFCViewer import SFC_Viewer Laurent@814: from editors.LDViewer import LD_Viewer Laurent@814: from editors.TextViewer import TextViewer Laurent@814: from editors.Viewer import Viewer, ZOOM_FACTORS Laurent@814: from editors.ResourceEditor import ConfigurationEditor, ResourceEditor Laurent@814: from editors.DataTypeEditor import DataTypeEditor Laurent@814: from PLCControler import * Laurent@1193: from controls import CustomTree, LibraryPanel, PouInstanceVariablesPanel, SearchResultPanel Laurent@1198: from controls.DebugVariablePanel import DebugVariablePanel laurent@819: from dialogs import ProjectDialog, PouDialog, PouTransitionDialog, PouActionDialog, FindInPouDialog, SearchInProjectDialog Laurent@814: from util.BitmapLibrary import GetBitmap Laurent@814: Laurent@814: # Define PLCOpenEditor controls id Edouard@1408: [ID_PLCOPENEDITOR, ID_PLCOPENEDITORLEFTNOTEBOOK, Edouard@1408: ID_PLCOPENEDITORBOTTOMNOTEBOOK, ID_PLCOPENEDITORRIGHTNOTEBOOK, Edouard@1408: ID_PLCOPENEDITORPROJECTTREE, ID_PLCOPENEDITORMAINSPLITTER, Edouard@1408: ID_PLCOPENEDITORSECONDSPLITTER, ID_PLCOPENEDITORTHIRDSPLITTER, Edouard@1408: ID_PLCOPENEDITORLIBRARYPANEL, ID_PLCOPENEDITORLIBRARYSEARCHCTRL, Edouard@1408: ID_PLCOPENEDITORLIBRARYTREE, ID_PLCOPENEDITORLIBRARYCOMMENT, Edouard@1408: ID_PLCOPENEDITORTABSOPENED, ID_PLCOPENEDITORTABSOPENED, Edouard@1408: ID_PLCOPENEDITOREDITORMENUTOOLBAR, ID_PLCOPENEDITOREDITORTOOLBAR, Edouard@1408: ID_PLCOPENEDITORPROJECTPANEL, Laurent@814: ] = [wx.NewId() for _init_ctrls in range(17)] Laurent@814: Laurent@814: # Define PLCOpenEditor EditMenu extra items id Edouard@1408: [ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, ID_PLCOPENEDITOREDITMENUADDDATATYPE, Edouard@1408: ID_PLCOPENEDITOREDITMENUADDFUNCTION, ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK, Laurent@814: ID_PLCOPENEDITOREDITMENUADDPROGRAM, ID_PLCOPENEDITOREDITMENUADDCONFIGURATION, Laurent@814: ID_PLCOPENEDITOREDITMENUFINDNEXT, ID_PLCOPENEDITOREDITMENUFINDPREVIOUS, Edouard@1401: ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT, ID_PLCOPENEDITOREDITMENUADDRESOURCE Edouard@1401: ] = [wx.NewId() for _init_coll_EditMenu_Items in range(10)] Laurent@814: Laurent@814: # Define PLCOpenEditor DisplayMenu extra items id Edouard@1408: [ID_PLCOPENEDITORDISPLAYMENURESETPERSPECTIVE, surkovsv93@1530: ID_PLCOPENEDITORDISPLAYMENUSWITCHPERSPECTIVE, surkovsv93@1530: ] = [wx.NewId() for _init_coll_DisplayMenu_Items in range(2)] Laurent@814: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # EditorToolBar definitions Laurent@814: #------------------------------------------------------------------------------- Laurent@814: Laurent@814: # Define PLCOpenEditor Toolbar items id Laurent@814: [ID_PLCOPENEDITOREDITORTOOLBARSELECTION, ID_PLCOPENEDITOREDITORTOOLBARCOMMENT, Laurent@814: ID_PLCOPENEDITOREDITORTOOLBARVARIABLE, ID_PLCOPENEDITOREDITORTOOLBARBLOCK, Laurent@814: ID_PLCOPENEDITOREDITORTOOLBARCONNECTION, ID_PLCOPENEDITOREDITORTOOLBARWIRE, Laurent@814: ID_PLCOPENEDITOREDITORTOOLBARPOWERRAIL, ID_PLCOPENEDITOREDITORTOOLBARRUNG, Laurent@814: ID_PLCOPENEDITOREDITORTOOLBARCOIL, ID_PLCOPENEDITOREDITORTOOLBARCONTACT, Laurent@814: ID_PLCOPENEDITOREDITORTOOLBARBRANCH, ID_PLCOPENEDITOREDITORTOOLBARINITIALSTEP, Laurent@814: ID_PLCOPENEDITOREDITORTOOLBARSTEP, ID_PLCOPENEDITOREDITORTOOLBARTRANSITION, Laurent@814: ID_PLCOPENEDITOREDITORTOOLBARACTIONBLOCK, ID_PLCOPENEDITOREDITORTOOLBARDIVERGENCE, Edouard@1408: ID_PLCOPENEDITOREDITORTOOLBARJUMP, ID_PLCOPENEDITOREDITORTOOLBARMOTION, Laurent@814: ] = [wx.NewId() for _init_coll_DefaultEditorToolBar_Items in range(18)] Laurent@814: Laurent@814: Laurent@814: Edouard@1408: # Define behaviour of each Toolbar item according to current POU body type Laurent@814: # Informations meaning are in this order: Laurent@814: # - Item is toggled Laurent@814: # - PLCOpenEditor mode where item is displayed (could be more then one) Laurent@814: # - Item id Laurent@814: # - Item callback function name Laurent@814: # - Item icon filename Laurent@814: # - Item tooltip text Laurent@814: EditorToolBarItems = { Laurent@814: "FBD" : [(True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, Laurent@814: ID_PLCOPENEDITOREDITORTOOLBARMOTION, "OnMotionTool", Laurent@814: "move", _("Move the view")), Laurent@814: (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, Laurent@814: ID_PLCOPENEDITOREDITORTOOLBARCOMMENT, "OnCommentTool", Laurent@814: "add_comment", _("Create a new comment")), Laurent@814: (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, Laurent@814: ID_PLCOPENEDITOREDITORTOOLBARVARIABLE, "OnVariableTool", Laurent@814: "add_variable", _("Create a new variable")), Laurent@814: (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, Laurent@814: ID_PLCOPENEDITOREDITORTOOLBARBLOCK, "OnBlockTool", Laurent@814: "add_block", _("Create a new block")), Edouard@1408: (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, Edouard@1408: ID_PLCOPENEDITOREDITORTOOLBARCONNECTION, "OnConnectionTool", Laurent@814: "add_connection", _("Create a new connection"))], Laurent@814: "LD" : [(True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, Laurent@814: ID_PLCOPENEDITOREDITORTOOLBARMOTION, "OnMotionTool", Laurent@814: "move", _("Move the view")), Edouard@1408: (True, FREEDRAWING_MODE, Edouard@1408: ID_PLCOPENEDITOREDITORTOOLBARCOMMENT, "OnCommentTool", Laurent@814: "add_comment", _("Create a new comment")), Edouard@1408: (True, FREEDRAWING_MODE, Edouard@1408: ID_PLCOPENEDITOREDITORTOOLBARPOWERRAIL, "OnPowerRailTool", Laurent@814: "add_powerrail", _("Create a new power rail")), Edouard@1408: (False, DRIVENDRAWING_MODE, Edouard@1408: ID_PLCOPENEDITOREDITORTOOLBARRUNG, "OnRungTool", Laurent@814: "add_rung", _("Create a new rung")), Edouard@1408: (True, FREEDRAWING_MODE, Edouard@1408: ID_PLCOPENEDITOREDITORTOOLBARCOIL, "OnCoilTool", Laurent@814: "add_coil", _("Create a new coil")), Edouard@1408: (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, Edouard@1408: ID_PLCOPENEDITOREDITORTOOLBARCONTACT, "OnContactTool", Laurent@814: "add_contact", _("Create a new contact")), Edouard@1408: (False, DRIVENDRAWING_MODE, Edouard@1408: ID_PLCOPENEDITOREDITORTOOLBARBRANCH, "OnBranchTool", Laurent@814: "add_branch", _("Create a new branch")), Edouard@1408: (True, FREEDRAWING_MODE, Edouard@1408: ID_PLCOPENEDITOREDITORTOOLBARVARIABLE, "OnVariableTool", Laurent@814: "add_variable", _("Create a new variable")), Edouard@1408: (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, Edouard@1408: ID_PLCOPENEDITOREDITORTOOLBARBLOCK, "OnBlockTool", Laurent@814: "add_block", _("Create a new block")), Edouard@1408: (True, FREEDRAWING_MODE, Edouard@1408: ID_PLCOPENEDITOREDITORTOOLBARCONNECTION, "OnConnectionTool", Laurent@814: "add_connection", _("Create a new connection"))], Laurent@814: "SFC" : [(True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, Laurent@814: ID_PLCOPENEDITOREDITORTOOLBARMOTION, "OnMotionTool", Laurent@814: "move", _("Move the view")), Edouard@1408: (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, Edouard@1408: ID_PLCOPENEDITOREDITORTOOLBARCOMMENT, "OnCommentTool", Laurent@814: "add_comment", _("Create a new comment")), Edouard@1408: (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, Edouard@1408: ID_PLCOPENEDITOREDITORTOOLBARINITIALSTEP, "OnInitialStepTool", Laurent@814: "add_initial_step", _("Create a new initial step")), Edouard@1408: (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, Edouard@1408: ID_PLCOPENEDITOREDITORTOOLBARSTEP, "OnStepTool", Laurent@814: "add_step", _("Create a new step")), Edouard@1408: (True, FREEDRAWING_MODE, Edouard@1408: ID_PLCOPENEDITOREDITORTOOLBARTRANSITION, "OnTransitionTool", Laurent@814: "add_transition", _("Create a new transition")), Edouard@1408: (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, Edouard@1408: ID_PLCOPENEDITOREDITORTOOLBARACTIONBLOCK, "OnActionBlockTool", Laurent@814: "add_action", _("Create a new action block")), Edouard@1408: (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, Edouard@1408: ID_PLCOPENEDITOREDITORTOOLBARDIVERGENCE, "OnDivergenceTool", Laurent@814: "add_divergence", _("Create a new divergence")), Edouard@1408: (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, Edouard@1408: ID_PLCOPENEDITOREDITORTOOLBARJUMP, "OnJumpTool", Laurent@814: "add_jump", _("Create a new jump")), Edouard@1408: (True, FREEDRAWING_MODE, Edouard@1408: ID_PLCOPENEDITOREDITORTOOLBARVARIABLE, "OnVariableTool", Laurent@814: "add_variable", _("Create a new variable")), Edouard@1408: (True, FREEDRAWING_MODE, Edouard@1408: ID_PLCOPENEDITOREDITORTOOLBARBLOCK, "OnBlockTool", Laurent@814: "add_block", _("Create a new block")), Edouard@1408: (True, FREEDRAWING_MODE, Edouard@1408: ID_PLCOPENEDITOREDITORTOOLBARCONNECTION, "OnConnectionTool", Laurent@814: "add_connection", _("Create a new connection")), Edouard@1408: (True, FREEDRAWING_MODE, Edouard@1408: ID_PLCOPENEDITOREDITORTOOLBARPOWERRAIL, "OnPowerRailTool", Laurent@814: "add_powerrail", _("Create a new power rail")), Edouard@1408: (True, FREEDRAWING_MODE, Edouard@1408: ID_PLCOPENEDITOREDITORTOOLBARCONTACT, "OnContactTool", Laurent@814: "add_contact", _("Create a new contact"))], Laurent@814: "ST" : [], Laurent@814: "IL" : [], Laurent@814: "debug": [(True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, Laurent@814: ID_PLCOPENEDITOREDITORTOOLBARMOTION, "OnMotionTool", Laurent@814: "move", _("Move the view"))], Laurent@814: } Laurent@814: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # Helper Functions Laurent@814: #------------------------------------------------------------------------------- Laurent@814: Laurent@814: import base64 Laurent@814: Laurent@814: def EncodeFileSystemPath(path, use_base64=True): Laurent@814: path = path.encode(sys.getfilesystemencoding()) Laurent@814: if use_base64: Laurent@814: return base64.encodestring(path) Laurent@814: return path Laurent@814: Laurent@814: def DecodeFileSystemPath(path, is_base64=True): Laurent@814: if is_base64: Laurent@814: path = base64.decodestring(path) Laurent@814: return unicode(path, sys.getfilesystemencoding()) Laurent@814: Laurent@814: # Compatibility function for wx versions < 2.6 Laurent@814: def AppendMenu(parent, help, id, kind, text): Laurent@814: if wx.VERSION >= (2, 6, 0): Laurent@814: parent.Append(help=help, id=id, kind=kind, text=text) Laurent@814: else: Laurent@814: parent.Append(helpString=help, id=id, kind=kind, item=text) Laurent@814: Edouard@1408: [TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, PROJECTTREE, Laurent@814: POUINSTANCEVARIABLESPANEL, LIBRARYTREE, SCALING, PAGETITLES Laurent@814: ] = range(10) Laurent@814: Laurent@814: def GetShortcutKeyCallbackFunction(viewer_function): Laurent@814: def ShortcutKeyFunction(self, event): Laurent@814: control = self.FindFocus() Laurent@814: if control is not None and control.GetName() in ["Viewer", "TextViewer"]: Laurent@814: getattr(control.ParentWindow, viewer_function)() Laurent@814: elif isinstance(control, wx.stc.StyledTextCtrl): Laurent@814: getattr(control, viewer_function)() Laurent@814: elif isinstance(control, wx.TextCtrl): Laurent@814: control.ProcessEvent(event) Laurent@814: return ShortcutKeyFunction Laurent@814: Laurent@814: def GetDeleteElementFunction(remove_function, parent_type=None, check_function=None): Laurent@814: def DeleteElementFunction(self, selected): Laurent@814: name = self.ProjectTree.GetItemText(selected) Laurent@1129: if check_function is None or check_function(name): Laurent@814: if parent_type is not None: Laurent@814: item_infos = self.ProjectTree.GetPyData(selected) Laurent@814: parent_name = item_infos["tagname"].split("::")[1] Laurent@814: remove_function(self.Controler, parent_name, name) Laurent@814: else: Laurent@814: remove_function(self.Controler, name) Laurent@814: return DeleteElementFunction Laurent@814: Laurent@814: if wx.Platform == '__WXMSW__': Laurent@814: TAB_BORDER = 6 Laurent@814: NOTEBOOK_BORDER = 6 Laurent@814: else: Laurent@814: TAB_BORDER = 7 Laurent@814: NOTEBOOK_BORDER = 2 Laurent@814: Laurent@814: def SimplifyTabLayout(tabs, rect): Laurent@814: for tab in tabs: Laurent@814: if tab["pos"][0] == rect.x: Laurent@814: others = [t for t in tabs if t != tab] Laurent@814: others.sort(lambda x,y: cmp(x["pos"][0], y["pos"][0])) Laurent@814: for other in others: Edouard@1408: if (other["pos"][1] == tab["pos"][1] and Laurent@814: other["size"][1] == tab["size"][1] and Laurent@814: other["pos"][0] == tab["pos"][0] + tab["size"][0] + TAB_BORDER): Edouard@1408: Laurent@814: tab["size"] = (tab["size"][0] + other["size"][0] + TAB_BORDER, tab["size"][1]) Laurent@814: tab["pages"].extend(other["pages"]) Laurent@814: tabs.remove(other) Edouard@1408: Laurent@814: if tab["size"][0] == rect.width: Laurent@814: return True Edouard@1408: Laurent@814: elif tab["pos"][1] == rect.y: Laurent@814: others = [t for t in tabs if t != tab] Laurent@814: others.sort(lambda x,y: cmp(x["pos"][1], y["pos"][1])) Laurent@814: for other in others: Edouard@1408: if (other["pos"][0] == tab["pos"][0] and Laurent@814: other["size"][0] == tab["size"][0] and Laurent@814: other["pos"][1] == tab["pos"][1] + tab["size"][1] + TAB_BORDER): Edouard@1408: Laurent@814: tab["size"] = (tab["size"][0], tab["size"][1] + other["size"][1] + TAB_BORDER) Laurent@814: tab["pages"].extend(other["pages"]) Laurent@814: tabs.remove(other) Edouard@1408: Laurent@814: if tab["size"][1] == rect.height: Laurent@814: return True Laurent@814: return False Edouard@1408: Laurent@814: def ComputeTabsLayout(tabs, rect): Laurent@814: if len(tabs) == 0: Laurent@814: return tabs Laurent@814: if len(tabs) == 1: Laurent@814: return tabs[0] Laurent@814: split = None Laurent@814: for idx, tab in enumerate(tabs): Laurent@814: if len(tab["pages"]) == 0: Laurent@814: raise ValueError, "Not possible" Laurent@814: if tab["size"][0] == rect.width: Laurent@814: if tab["pos"][1] == rect.y: Laurent@814: split = (wx.TOP, float(tab["size"][1]) / float(rect.height)) Edouard@1408: split_rect = wx.Rect(rect.x, rect.y + tab["size"][1] + TAB_BORDER, Laurent@814: rect.width, rect.height - tab["size"][1] - TAB_BORDER) Laurent@814: elif tab["pos"][1] == rect.height + 1 - tab["size"][1]: Laurent@814: split = (wx.BOTTOM, 1.0 - float(tab["size"][1]) / float(rect.height)) Edouard@1408: split_rect = wx.Rect(rect.x, rect.y, Laurent@814: rect.width, rect.height - tab["size"][1] - TAB_BORDER) Laurent@814: break Laurent@814: elif tab["size"][1] == rect.height: Laurent@814: if tab["pos"][0] == rect.x: Laurent@814: split = (wx.LEFT, float(tab["size"][0]) / float(rect.width)) Edouard@1408: split_rect = wx.Rect(rect.x + tab["size"][0] + TAB_BORDER, rect.y, Laurent@814: rect.width - tab["size"][0] - TAB_BORDER, rect.height) Laurent@814: elif tab["pos"][0] == rect.width + 1 - tab["size"][0]: Laurent@814: split = (wx.RIGHT, 1.0 - float(tab["size"][0]) / float(rect.width)) Edouard@1408: split_rect = wx.Rect(rect.x, rect.y, Laurent@814: rect.width - tab["size"][0] - TAB_BORDER, rect.height) Laurent@814: break Laurent@814: if split != None: Laurent@814: split_tab = tabs.pop(idx) Laurent@814: return {"split": split, Edouard@1408: "tab": split_tab, Laurent@814: "others": ComputeTabsLayout(tabs, split_rect)} Laurent@814: else: Laurent@814: if SimplifyTabLayout(tabs, rect): Laurent@814: return ComputeTabsLayout(tabs, rect) Laurent@814: return tabs Laurent@814: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # IDEFrame Base Class Laurent@814: #------------------------------------------------------------------------------- Laurent@814: Laurent@814: UNEDITABLE_NAMES_DICT = dict([(_(name), name) for name in UNEDITABLE_NAMES]) Laurent@814: Laurent@814: class IDEFrame(wx.Frame): Edouard@1408: Laurent@814: # Compatibility function for wx versions < 2.6 Laurent@814: if wx.VERSION < (2, 6, 0): Laurent@814: def Bind(self, event, function, id = None): Laurent@814: if id is not None: Laurent@814: event(self, id, function) Laurent@814: else: Laurent@814: event(self, function) Edouard@1408: Laurent@814: def _init_coll_MenuBar_Menus(self, parent): Laurent@814: parent.Append(menu=self.FileMenu, title=_(u'&File')) Laurent@814: parent.Append(menu=self.EditMenu, title=_(u'&Edit')) Laurent@814: parent.Append(menu=self.DisplayMenu, title=_(u'&Display')) Laurent@814: parent.Append(menu=self.HelpMenu, title=_(u'&Help')) Laurent@814: Laurent@814: def _init_coll_FileMenu_Items(self, parent): Laurent@814: pass Edouard@1408: Laurent@814: def _init_coll_AddMenu_Items(self, parent, add_config=True): Laurent@814: AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUADDDATATYPE, Laurent@814: kind=wx.ITEM_NORMAL, text=_(u'&Data Type')) Laurent@814: AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUADDFUNCTION, Laurent@814: kind=wx.ITEM_NORMAL, text=_(u'&Function')) Laurent@814: AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK, Laurent@814: kind=wx.ITEM_NORMAL, text=_(u'Function &Block')) Laurent@814: AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUADDPROGRAM, Laurent@814: kind=wx.ITEM_NORMAL, text=_(u'&Program')) Edouard@1401: AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUADDRESOURCE, Edouard@1401: kind=wx.ITEM_NORMAL, text=_(u'&Resource')) Laurent@814: if add_config: Laurent@814: AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUADDCONFIGURATION, Laurent@814: kind=wx.ITEM_NORMAL, text=_(u'&Configuration')) Edouard@1408: Laurent@814: def _init_coll_EditMenu_Items(self, parent): Laurent@814: AppendMenu(parent, help='', id=wx.ID_UNDO, Laurent@814: kind=wx.ITEM_NORMAL, text=_(u'Undo') + '\tCTRL+Z') Laurent@814: AppendMenu(parent, help='', id=wx.ID_REDO, Laurent@814: kind=wx.ITEM_NORMAL, text=_(u'Redo') + '\tCTRL+Y') Laurent@814: #AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, Laurent@814: # kind=wx.ITEM_CHECK, text=_(u'Enable Undo/Redo')) Laurent@814: enable_undo_redo = _(u'Enable Undo/Redo') # Keeping text in translations for possible menu reactivation Laurent@814: parent.AppendSeparator() Laurent@814: AppendMenu(parent, help='', id=wx.ID_CUT, Laurent@814: kind=wx.ITEM_NORMAL, text=_(u'Cut') + '\tCTRL+X') Laurent@814: AppendMenu(parent, help='', id=wx.ID_COPY, Laurent@814: kind=wx.ITEM_NORMAL, text=_(u'Copy') + '\tCTRL+C') Laurent@814: AppendMenu(parent, help='', id=wx.ID_PASTE, Laurent@814: kind=wx.ITEM_NORMAL, text=_(u'Paste') + '\tCTRL+V') Laurent@814: parent.AppendSeparator() Laurent@814: AppendMenu(parent, help='', id=wx.ID_FIND, Laurent@814: kind=wx.ITEM_NORMAL, text=_(u'Find') + '\tCTRL+F') Laurent@814: AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUFINDNEXT, Laurent@814: kind=wx.ITEM_NORMAL, text=_(u'Find Next') + '\tCTRL+K') Laurent@814: AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUFINDPREVIOUS, Laurent@814: kind=wx.ITEM_NORMAL, text=_(u'Find Previous') + '\tCTRL+SHIFT+K') Laurent@814: parent.AppendSeparator() Laurent@814: AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT, Laurent@814: kind=wx.ITEM_NORMAL, text=_(u'Search in Project') + '\tCTRL+SHIFT+F') Laurent@814: parent.AppendSeparator() Laurent@814: add_menu = wx.Menu(title='') Laurent@814: self._init_coll_AddMenu_Items(add_menu) Laurent@814: parent.AppendMenu(wx.ID_ADD, _(u"&Add Element"), add_menu) Laurent@814: AppendMenu(parent, help='', id=wx.ID_SELECTALL, Laurent@814: kind=wx.ITEM_NORMAL, text=_(u'Select All') + '\tCTRL+A') Laurent@814: AppendMenu(parent, help='', id=wx.ID_DELETE, Laurent@814: kind=wx.ITEM_NORMAL, text=_(u'&Delete')) Laurent@814: self.Bind(wx.EVT_MENU, self.OnUndoMenu, id=wx.ID_UNDO) Laurent@814: self.Bind(wx.EVT_MENU, self.OnRedoMenu, id=wx.ID_REDO) Laurent@814: #self.Bind(wx.EVT_MENU, self.OnEnableUndoRedoMenu, id=ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO) Laurent@814: self.Bind(wx.EVT_MENU, self.OnCutMenu, id=wx.ID_CUT) Laurent@814: self.Bind(wx.EVT_MENU, self.OnCopyMenu, id=wx.ID_COPY) Laurent@814: self.Bind(wx.EVT_MENU, self.OnPasteMenu, id=wx.ID_PASTE) Laurent@814: self.Bind(wx.EVT_MENU, self.OnFindMenu, id=wx.ID_FIND) Edouard@1408: self.Bind(wx.EVT_MENU, self.OnFindNextMenu, Laurent@814: id=ID_PLCOPENEDITOREDITMENUFINDNEXT) Edouard@1408: self.Bind(wx.EVT_MENU, self.OnFindPreviousMenu, Laurent@814: id=ID_PLCOPENEDITOREDITMENUFINDPREVIOUS) Edouard@1408: self.Bind(wx.EVT_MENU, self.OnSearchInProjectMenu, Laurent@814: id=ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT) Edouard@1408: self.Bind(wx.EVT_MENU, self.OnSearchInProjectMenu, Laurent@814: id=ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT) Laurent@814: self.Bind(wx.EVT_MENU, self.OnAddDataTypeMenu, Laurent@814: id=ID_PLCOPENEDITOREDITMENUADDDATATYPE) Laurent@814: self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction("function"), Laurent@814: id=ID_PLCOPENEDITOREDITMENUADDFUNCTION) Laurent@814: self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction("functionBlock"), Laurent@814: id=ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK) Laurent@814: self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction("program"), Laurent@814: id=ID_PLCOPENEDITOREDITMENUADDPROGRAM) Edouard@1408: self.Bind(wx.EVT_MENU, self.AddResourceMenu, Edouard@1401: id=ID_PLCOPENEDITOREDITMENUADDRESOURCE) Laurent@814: self.Bind(wx.EVT_MENU, self.OnAddConfigurationMenu, Laurent@814: id=ID_PLCOPENEDITOREDITMENUADDCONFIGURATION) Laurent@814: self.Bind(wx.EVT_MENU, self.OnSelectAllMenu, id=wx.ID_SELECTALL) Laurent@814: self.Bind(wx.EVT_MENU, self.OnDeleteMenu, id=wx.ID_DELETE) Edouard@1408: Laurent@814: self.AddToMenuToolBar([(wx.ID_UNDO, "undo", _(u'Undo'), None), Laurent@814: (wx.ID_REDO, "redo", _(u'Redo'), None), Laurent@814: None, Laurent@814: (wx.ID_CUT, "cut", _(u'Cut'), None), Laurent@814: (wx.ID_COPY, "copy", _(u'Copy'), None), Laurent@814: (wx.ID_PASTE, "paste", _(u'Paste'), None), Laurent@814: None, Laurent@814: (ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT, "find", _(u'Search in Project'), None)]) Laurent@814: Laurent@814: def _init_coll_DisplayMenu_Items(self, parent): Laurent@814: AppendMenu(parent, help='', id=wx.ID_REFRESH, Laurent@814: kind=wx.ITEM_NORMAL, text=_(u'Refresh') + '\tCTRL+R') Laurent@814: if self.EnableDebug: Laurent@814: AppendMenu(parent, help='', id=wx.ID_CLEAR, Laurent@814: kind=wx.ITEM_NORMAL, text=_(u'Clear Errors') + '\tCTRL+K') Laurent@814: parent.AppendSeparator() Laurent@814: zoommenu = wx.Menu(title='') Laurent@814: parent.AppendMenu(wx.ID_ZOOM_FIT, _("Zoom"), zoommenu) Laurent@814: for idx, value in enumerate(ZOOM_FACTORS): Laurent@814: new_id = wx.NewId() Laurent@814: AppendMenu(zoommenu, help='', id=new_id, Laurent@814: kind=wx.ITEM_RADIO, text=str(int(round(value * 100))) + "%") Laurent@814: self.Bind(wx.EVT_MENU, self.GenerateZoomFunction(idx), id=new_id) Edouard@1408: Laurent@814: parent.AppendSeparator() surkovsv93@1530: AppendMenu(parent, help='', id=ID_PLCOPENEDITORDISPLAYMENUSWITCHPERSPECTIVE, surkovsv93@1530: kind=wx.ITEM_NORMAL, text=_(u'Switch perspective') + '\tF12') surkovsv93@1530: self.Bind(wx.EVT_MENU, self.SwitchFullScrMode, id=ID_PLCOPENEDITORDISPLAYMENUSWITCHPERSPECTIVE) surkovsv93@1530: Laurent@814: AppendMenu(parent, help='', id=ID_PLCOPENEDITORDISPLAYMENURESETPERSPECTIVE, Laurent@814: kind=wx.ITEM_NORMAL, text=_(u'Reset Perspective')) Laurent@814: self.Bind(wx.EVT_MENU, self.OnResetPerspective, id=ID_PLCOPENEDITORDISPLAYMENURESETPERSPECTIVE) Edouard@1408: Laurent@814: self.Bind(wx.EVT_MENU, self.OnRefreshMenu, id=wx.ID_REFRESH) Laurent@814: if self.EnableDebug: Laurent@814: self.Bind(wx.EVT_MENU, self.OnClearErrorsMenu, id=wx.ID_CLEAR) Edouard@1408: Laurent@814: def _init_coll_HelpMenu_Items(self, parent): Laurent@814: pass Laurent@814: Laurent@814: def _init_utils(self): Laurent@814: self.MenuBar = wx.MenuBar() Laurent@814: Laurent@814: self.FileMenu = wx.Menu(title='') Laurent@814: self.EditMenu = wx.Menu(title='') Laurent@814: self.DisplayMenu = wx.Menu(title='') Laurent@814: self.HelpMenu = wx.Menu(title='') Edouard@1408: Laurent@814: self._init_coll_MenuBar_Menus(self.MenuBar) Laurent@814: self._init_coll_FileMenu_Items(self.FileMenu) Laurent@814: self._init_coll_EditMenu_Items(self.EditMenu) Laurent@814: self._init_coll_DisplayMenu_Items(self.DisplayMenu) Laurent@814: self._init_coll_HelpMenu_Items(self.HelpMenu) Laurent@814: andrej@1490: def _init_icon(self, parent): andrej@1490: if self.icon: andrej@1490: self.SetIcon(self.icon) andrej@1490: elif parent and parent.icon: andrej@1490: self.SetIcon(parent.icon) andrej@1490: Laurent@814: def _init_ctrls(self, prnt): Laurent@814: wx.Frame.__init__(self, id=ID_PLCOPENEDITOR, name='IDEFrame', Laurent@814: parent=prnt, pos=wx.DefaultPosition, size=wx.Size(1000, 600), Laurent@814: style=wx.DEFAULT_FRAME_STYLE) andrej@1490: self._init_icon(prnt) Laurent@814: self.SetClientSize(wx.Size(1000, 600)) Laurent@814: self.Bind(wx.EVT_ACTIVATE, self.OnActivated) Edouard@1408: Laurent@814: self.TabsImageList = wx.ImageList(31, 16) Laurent@814: self.TabsImageListIndexes = {} Edouard@1408: Laurent@814: #----------------------------------------------------------------------- Laurent@814: # Creating main structure Laurent@814: #----------------------------------------------------------------------- Edouard@1408: Laurent@814: self.AUIManager = wx.aui.AuiManager(self) Laurent@814: self.AUIManager.SetDockSizeConstraint(0.5, 0.5) Laurent@814: self.Panes = {} Edouard@1408: Laurent@814: self.LeftNoteBook = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORLEFTNOTEBOOK, Laurent@814: style=wx.aui.AUI_NB_TOP|wx.aui.AUI_NB_TAB_SPLIT|wx.aui.AUI_NB_TAB_MOVE| Laurent@814: wx.aui.AUI_NB_SCROLL_BUTTONS|wx.aui.AUI_NB_TAB_EXTERNAL_MOVE) Edouard@1408: self.LeftNoteBook.Bind(wx.aui.EVT_AUINOTEBOOK_ALLOW_DND, Laurent@814: self.OnAllowNotebookDnD) Edouard@1408: self.AUIManager.AddPane(self.LeftNoteBook, Laurent@814: wx.aui.AuiPaneInfo().Name("ProjectPane"). Laurent@814: Left().Layer(1). Laurent@814: BestSize(wx.Size(300, 500)).CloseButton(False)) Edouard@1408: Laurent@814: self.BottomNoteBook = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORBOTTOMNOTEBOOK, Laurent@814: style=wx.aui.AUI_NB_TOP|wx.aui.AUI_NB_TAB_SPLIT|wx.aui.AUI_NB_TAB_MOVE| Laurent@814: wx.aui.AUI_NB_SCROLL_BUTTONS|wx.aui.AUI_NB_TAB_EXTERNAL_MOVE) Edouard@1408: self.BottomNoteBook.Bind(wx.aui.EVT_AUINOTEBOOK_ALLOW_DND, Laurent@814: self.OnAllowNotebookDnD) Edouard@1408: self.AUIManager.AddPane(self.BottomNoteBook, Laurent@814: wx.aui.AuiPaneInfo().Name("ResultPane"). Laurent@814: Bottom().Layer(0). Laurent@814: BestSize(wx.Size(800, 300)).CloseButton(False)) Edouard@1408: Laurent@814: self.RightNoteBook = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORRIGHTNOTEBOOK, Laurent@814: style=wx.aui.AUI_NB_TOP|wx.aui.AUI_NB_TAB_SPLIT|wx.aui.AUI_NB_TAB_MOVE| Laurent@814: wx.aui.AUI_NB_SCROLL_BUTTONS|wx.aui.AUI_NB_TAB_EXTERNAL_MOVE) Edouard@1408: self.RightNoteBook.Bind(wx.aui.EVT_AUINOTEBOOK_ALLOW_DND, Laurent@814: self.OnAllowNotebookDnD) Edouard@1408: self.AUIManager.AddPane(self.RightNoteBook, Laurent@814: wx.aui.AuiPaneInfo().Name("LibraryPane"). Laurent@814: Right().Layer(0). Laurent@814: BestSize(wx.Size(250, 400)).CloseButton(False)) Edouard@1408: Edouard@1408: self.TabsOpened = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORTABSOPENED, Laurent@814: style=wx.aui.AUI_NB_DEFAULT_STYLE|wx.aui.AUI_NB_WINDOWLIST_BUTTON) Laurent@814: self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGING, Laurent@814: self.OnPouSelectedChanging) Laurent@814: self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED, Laurent@814: self.OnPouSelectedChanged) Laurent@814: self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE, Laurent@814: self.OnPageClose) Laurent@814: self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_END_DRAG, Laurent@814: self.OnPageDragged) Edouard@1408: self.AUIManager.AddPane(self.TabsOpened, Laurent@814: wx.aui.AuiPaneInfo().CentrePane().Name("TabsPane")) Edouard@1408: Laurent@814: #----------------------------------------------------------------------- Laurent@814: # Creating PLCopen Project Types Tree Laurent@814: #----------------------------------------------------------------------- Edouard@1408: Laurent@814: self.MainTabs = {} Edouard@1408: Laurent@814: self.ProjectPanel = wx.SplitterWindow(id=ID_PLCOPENEDITORPROJECTPANEL, Laurent@814: name='ProjectPanel', parent=self.LeftNoteBook, point=wx.Point(0, 0), Laurent@814: size=wx.Size(0, 0), style=wx.SP_3D) Edouard@1408: Laurent@814: self.ProjectTree = CustomTree(id=ID_PLCOPENEDITORPROJECTTREE, Edouard@1408: name='ProjectTree', parent=self.ProjectPanel, Laurent@814: pos=wx.Point(0, 0), size=wx.Size(0, 0), Laurent@1167: style=wx.SUNKEN_BORDER, Laurent@1167: agwStyle=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.TR_EDIT_LABELS) Laurent@814: self.ProjectTree.SetBackgroundBitmap(GetBitmap("custom_tree_background"), Laurent@814: wx.ALIGN_RIGHT|wx.ALIGN_BOTTOM) Laurent@814: add_menu = wx.Menu() Laurent@814: self._init_coll_AddMenu_Items(add_menu) Laurent@814: self.ProjectTree.SetAddMenu(add_menu) Laurent@1240: self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnProjectTreeRightUp, Laurent@1240: id=ID_PLCOPENEDITORPROJECTTREE) Laurent@1240: self.ProjectTree.Bind(wx.EVT_LEFT_UP, self.OnProjectTreeLeftUp) Laurent@1240: self.Bind(wx.EVT_TREE_SEL_CHANGING, self.OnProjectTreeItemChanging, Laurent@1240: id=ID_PLCOPENEDITORPROJECTTREE) Laurent@814: self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnProjectTreeBeginDrag, Laurent@814: id=ID_PLCOPENEDITORPROJECTTREE) Laurent@814: self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnProjectTreeItemBeginEdit, Laurent@814: id=ID_PLCOPENEDITORPROJECTTREE) Laurent@814: self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnProjectTreeItemEndEdit, Laurent@814: id=ID_PLCOPENEDITORPROJECTTREE) Laurent@814: self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnProjectTreeItemActivated, Laurent@814: id=ID_PLCOPENEDITORPROJECTTREE) Laurent@1106: self.ProjectTree.Bind(wx.EVT_MOTION, self.OnProjectTreeMotion) Edouard@1408: Laurent@814: #----------------------------------------------------------------------- Laurent@814: # Creating PLCopen Project POU Instance Variables Panel Laurent@814: #----------------------------------------------------------------------- Edouard@1408: Laurent@814: self.PouInstanceVariablesPanel = PouInstanceVariablesPanel(self.ProjectPanel, self, self.Controler, self.EnableDebug) Edouard@1408: Laurent@814: self.MainTabs["ProjectPanel"] = (self.ProjectPanel, _("Project")) Laurent@814: self.LeftNoteBook.AddPage(*self.MainTabs["ProjectPanel"]) Edouard@1408: Laurent@814: self.ProjectPanel.SplitHorizontally(self.ProjectTree, self.PouInstanceVariablesPanel, 300) Edouard@1408: Laurent@814: #----------------------------------------------------------------------- Laurent@814: # Creating Tool Bar Laurent@814: #----------------------------------------------------------------------- Edouard@1408: Laurent@814: MenuToolBar = wx.ToolBar(self, ID_PLCOPENEDITOREDITORMENUTOOLBAR, wx.DefaultPosition, wx.DefaultSize, Laurent@814: wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER) Laurent@814: MenuToolBar.SetToolBitmapSize(wx.Size(25, 25)) Laurent@814: MenuToolBar.Realize() Laurent@814: self.Panes["MenuToolBar"] = MenuToolBar Laurent@814: self.AUIManager.AddPane(MenuToolBar, wx.aui.AuiPaneInfo(). Laurent@814: Name("MenuToolBar").Caption(_("Menu ToolBar")). Laurent@814: ToolbarPane().Top(). Laurent@814: LeftDockable(False).RightDockable(False)) Edouard@1408: Laurent@814: EditorToolBar = wx.ToolBar(self, ID_PLCOPENEDITOREDITORTOOLBAR, wx.DefaultPosition, wx.DefaultSize, Laurent@814: wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER) Laurent@814: EditorToolBar.SetToolBitmapSize(wx.Size(25, 25)) Edouard@1408: EditorToolBar.AddRadioTool(ID_PLCOPENEDITOREDITORTOOLBARSELECTION, Laurent@814: GetBitmap("select"), wx.NullBitmap, _("Select an object")) Laurent@814: EditorToolBar.Realize() Laurent@814: self.Panes["EditorToolBar"] = EditorToolBar Laurent@814: self.AUIManager.AddPane(EditorToolBar, wx.aui.AuiPaneInfo(). Laurent@814: Name("EditorToolBar").Caption(_("Editor ToolBar")). Laurent@814: ToolbarPane().Top().Position(1). Laurent@814: LeftDockable(False).RightDockable(False)) Edouard@1408: Edouard@1408: self.Bind(wx.EVT_MENU, self.OnSelectionTool, Laurent@814: id=ID_PLCOPENEDITOREDITORTOOLBARSELECTION) Edouard@1408: Laurent@814: #----------------------------------------------------------------------- Laurent@814: # Creating Search Panel Laurent@814: #----------------------------------------------------------------------- Edouard@1408: Laurent@814: self.SearchResultPanel = SearchResultPanel(self.BottomNoteBook, self) Laurent@814: self.MainTabs["SearchResultPanel"] = (self.SearchResultPanel, _("Search")) Laurent@814: self.BottomNoteBook.AddPage(*self.MainTabs["SearchResultPanel"]) Edouard@1408: Laurent@814: #----------------------------------------------------------------------- Laurent@814: # Creating Library Panel Laurent@814: #----------------------------------------------------------------------- Edouard@1408: Laurent@814: self.LibraryPanel = LibraryPanel(self, True) Laurent@814: self.MainTabs["LibraryPanel"] = (self.LibraryPanel, _("Library")) Laurent@814: self.RightNoteBook.AddPage(*self.MainTabs["LibraryPanel"]) Edouard@1408: Laurent@814: self._init_utils() Laurent@814: self.SetMenuBar(self.MenuBar) Edouard@1408: Laurent@814: if self.EnableDebug: Laurent@902: self.DebugVariablePanel = DebugVariablePanel(self.RightNoteBook, self.Controler, self) Laurent@814: self.MainTabs["DebugVariablePanel"] = (self.DebugVariablePanel, _("Debugger")) Laurent@814: self.RightNoteBook.AddPage(*self.MainTabs["DebugVariablePanel"]) Edouard@1408: Laurent@814: self.AUIManager.Update() Edouard@1408: Laurent@814: self.FindDialog = FindInPouDialog(self) Laurent@814: self.FindDialog.Hide() Edouard@1408: Laurent@814: ## Constructor of the PLCOpenEditor class. Laurent@814: # @param parent The parent window. Laurent@814: # @param controler The controler been used by PLCOpenEditor (default: None). Laurent@814: # @param fileOpen The filepath to open if no controler defined (default: None). Laurent@814: # @param debug The filepath to open if no controler defined (default: False). Laurent@814: def __init__(self, parent, enable_debug = False): Laurent@814: self.Controler = None Laurent@814: self.Config = wx.ConfigBase.Get() Laurent@814: self.EnableDebug = enable_debug Edouard@1408: Laurent@814: self._init_ctrls(parent) Edouard@1408: Laurent@814: # Define Tree item icon list Laurent@814: self.TreeImageList = wx.ImageList(16, 16) Laurent@814: self.TreeImageDict = {} Edouard@1408: Laurent@814: # Icons for languages Laurent@814: for language in LANGUAGES: Laurent@814: self.TreeImageDict[language] = self.TreeImageList.Add(GetBitmap(language)) Edouard@1408: Laurent@814: # Icons for other items Laurent@814: for imgname, itemtype in [ Laurent@814: #editables Laurent@814: ("PROJECT", ITEM_PROJECT), Laurent@814: #("POU", ITEM_POU), Laurent@814: #("VARIABLE", ITEM_VARIABLE), Laurent@814: ("TRANSITION", ITEM_TRANSITION), Laurent@814: ("ACTION", ITEM_ACTION), Laurent@814: ("CONFIGURATION", ITEM_CONFIGURATION), Laurent@814: ("RESOURCE", ITEM_RESOURCE), Laurent@814: ("DATATYPE", ITEM_DATATYPE), Laurent@814: # uneditables Laurent@814: ("DATATYPES", ITEM_DATATYPES), Laurent@814: ("FUNCTION", ITEM_FUNCTION), Laurent@814: ("FUNCTIONBLOCK", ITEM_FUNCTIONBLOCK), Laurent@814: ("PROGRAM", ITEM_PROGRAM), Laurent@814: ("VAR_LOCAL", ITEM_VAR_LOCAL), Laurent@814: ("VAR_LOCAL", ITEM_VAR_GLOBAL), Laurent@814: ("VAR_LOCAL", ITEM_VAR_EXTERNAL), Laurent@814: ("VAR_LOCAL", ITEM_VAR_TEMP), Laurent@814: ("VAR_INPUT", ITEM_VAR_INPUT), Laurent@814: ("VAR_OUTPUT", ITEM_VAR_OUTPUT), Laurent@814: ("VAR_INOUT", ITEM_VAR_INOUT), Laurent@814: ("TRANSITIONS", ITEM_TRANSITIONS), Laurent@814: ("ACTIONS", ITEM_ACTIONS), Laurent@814: ("CONFIGURATIONS", ITEM_CONFIGURATIONS), Laurent@814: ("RESOURCES", ITEM_RESOURCES), Laurent@814: ("PROPERTIES", ITEM_PROPERTIES)]: Laurent@814: self.TreeImageDict[itemtype] = self.TreeImageList.Add(GetBitmap(imgname)) Edouard@1408: Laurent@814: # Assign icon list to TreeCtrls Laurent@814: self.ProjectTree.SetImageList(self.TreeImageList) Laurent@814: self.PouInstanceVariablesPanel.SetTreeImageList(self.TreeImageList) Edouard@1408: Laurent@814: self.CurrentEditorToolBar = [] Laurent@814: self.CurrentMenu = None Laurent@814: self.SelectedItem = None Laurent@1106: self.LastToolTipItem = None Laurent@814: self.SearchParams = None Laurent@814: self.Highlights = {} Laurent@814: self.DrawingMode = FREEDRAWING_MODE Laurent@814: #self.DrawingMode = DRIVENDRAWING_MODE Laurent@814: self.AuiTabCtrl = [] Edouard@1408: Laurent@980: # Save default perspective Laurent@980: notebooks = {} Laurent@980: for notebook, entry_name in [(self.LeftNoteBook, "leftnotebook"), Laurent@980: (self.BottomNoteBook, "bottomnotebook"), Laurent@980: (self.RightNoteBook, "rightnotebook")]: Laurent@980: notebooks[entry_name] = self.SaveTabLayout(notebook) Laurent@980: self.DefaultPerspective = { Laurent@980: "perspective": self.AUIManager.SavePerspective(), Laurent@980: "notebooks": notebooks, Laurent@980: } Edouard@1408: Edouard@1408: Laurent@814: # Initialize Printing configuring elements Laurent@814: self.PrintData = wx.PrintData() Laurent@814: self.PrintData.SetPaperId(wx.PAPER_A4) Laurent@814: self.PrintData.SetPrintMode(wx.PRINT_MODE_PRINTER) Laurent@814: self.PageSetupData = wx.PageSetupDialogData(self.PrintData) Laurent@814: self.PageSetupData.SetMarginTopLeft(wx.Point(10, 15)) Laurent@814: self.PageSetupData.SetMarginBottomRight(wx.Point(10, 20)) Edouard@1408: Laurent@814: self.SetRefreshFunctions() Laurent@1129: self.SetDeleteFunctions() Edouard@1408: Laurent@814: def __del__(self): Laurent@814: self.FindDialog.Destroy() Edouard@1408: Laurent@814: def Show(self): Laurent@814: wx.Frame.Show(self) Laurent@814: wx.CallAfter(self.RestoreLastState) Edouard@1408: Laurent@814: def OnActivated(self, event): Laurent@814: if event.GetActive(): Laurent@814: wx.CallAfter(self._Refresh, TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU) Laurent@814: event.Skip() Laurent@814: Laurent@999: def SelectTab(self, tab): Laurent@999: for notebook in [self.LeftNoteBook, self.BottomNoteBook, self.RightNoteBook]: Laurent@999: idx = notebook.GetPageIndex(tab) Laurent@1015: if idx != wx.NOT_FOUND and idx != notebook.GetSelection(): Laurent@999: notebook.SetSelection(idx) Laurent@999: return Laurent@999: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # Saving and restoring frame organization functions Laurent@814: #------------------------------------------------------------------------------- Laurent@814: Laurent@814: def GetTabInfos(self, tab): Laurent@980: for page_name, (page_ref, page_title) in self.MainTabs.iteritems(): Laurent@981: if page_ref == tab: Laurent@981: return ("main", page_name) Laurent@814: return None Edouard@1408: Laurent@814: def SaveTabLayout(self, notebook): Laurent@814: tabs = [] Laurent@814: for child in notebook.GetChildren(): Laurent@814: if isinstance(child, wx.aui.AuiTabCtrl): Laurent@814: if child.GetPageCount() > 0: Laurent@814: pos = child.GetPosition() Laurent@814: tab = {"pos": (pos.x, pos.y), "pages": []} Laurent@814: tab_size = child.GetSize() Laurent@814: for page_idx in xrange(child.GetPageCount()): Laurent@814: page = child.GetWindowFromIdx(page_idx) Laurent@814: if not tab.has_key("size"): Laurent@814: tab["size"] = (tab_size[0], tab_size[1] + page.GetSize()[1]) Laurent@814: tab_infos = self.GetTabInfos(page) Laurent@814: if tab_infos is not None: Laurent@814: tab["pages"].append((tab_infos, page_idx == child.GetActivePage())) Laurent@814: tabs.append(tab) Laurent@814: tabs.sort(lambda x, y: cmp(x["pos"], y["pos"])) Laurent@814: size = notebook.GetSize() Laurent@814: return ComputeTabsLayout(tabs, wx.Rect(1, 1, size[0] - NOTEBOOK_BORDER, size[1] - NOTEBOOK_BORDER)) Edouard@1408: Laurent@814: def LoadTab(self, notebook, page_infos): Laurent@814: if page_infos[0] == "main": Laurent@814: infos = self.MainTabs.get(page_infos[1]) Laurent@814: if infos is not None: Laurent@814: page_ref, page_title = infos Laurent@814: notebook.AddPage(page_ref, page_title) Laurent@814: return notebook.GetPageIndex(page_ref) Laurent@814: elif page_infos[0] == "editor": Laurent@814: tagname = page_infos[1] Laurent@814: page_ref = self.EditProjectElement(self.Controler.GetElementType(tagname), tagname) Laurent@814: if page_ref is not None: Laurent@814: page_ref.RefreshView() Laurent@814: return notebook.GetPageIndex(page_ref) Laurent@814: elif page_infos[0] == "debug": Laurent@814: instance_path = page_infos[1] Laurent@814: instance_infos = self.Controler.GetInstanceInfos(instance_path, self.EnableDebug) Laurent@814: if instance_infos is not None: Laurent@814: return notebook.GetPageIndex(self.OpenDebugViewer(instance_infos["class"], instance_path, instance_infos["type"])) Laurent@814: return None Edouard@1408: Laurent@814: def LoadTabLayout(self, notebook, tabs, mode="all", first_index=None): Laurent@814: if isinstance(tabs, ListType): Laurent@814: if len(tabs) == 0: Laurent@814: return Laurent@814: raise ValueError, "Not supported" Edouard@1408: Laurent@814: if tabs.has_key("split"): Laurent@814: self.LoadTabLayout(notebook, tabs["others"]) Edouard@1408: Laurent@814: split_dir, split_ratio = tabs["split"] Laurent@814: first_index = self.LoadTabLayout(notebook, tabs["tab"], mode="first") Laurent@814: notebook.Split(first_index, split_dir) Laurent@814: self.LoadTabLayout(notebook, tabs["tab"], mode="others", first_index=first_index) Edouard@1408: Laurent@814: elif mode == "first": Laurent@814: return self.LoadTab(notebook, tabs["pages"][0][0]) Laurent@814: else: Laurent@814: selected = first_index Laurent@814: if mode == "others": Laurent@814: add_tabs = tabs["pages"][1:] Laurent@814: else: Laurent@814: add_tabs = tabs["pages"] Laurent@814: for page_infos, page_selected in add_tabs: Laurent@814: page_idx = self.LoadTab(notebook, page_infos) Laurent@814: if page_selected: Laurent@814: selected = page_idx Laurent@814: if selected is not None: Laurent@814: wx.CallAfter(notebook.SetSelection, selected) Edouard@1408: Laurent@814: def ResetPerspective(self): Laurent@814: if self.DefaultPerspective is not None: Laurent@814: self.AUIManager.LoadPerspective(self.DefaultPerspective["perspective"]) Edouard@1408: Laurent@814: for notebook in [self.LeftNoteBook, self.BottomNoteBook, self.RightNoteBook]: Laurent@814: for idx in xrange(notebook.GetPageCount()): Laurent@814: notebook.RemovePage(0) Edouard@1408: Laurent@814: notebooks = self.DefaultPerspective["notebooks"] Laurent@814: for notebook, entry_name in [(self.LeftNoteBook, "leftnotebook"), Laurent@814: (self.BottomNoteBook, "bottomnotebook"), Laurent@814: (self.RightNoteBook, "rightnotebook")]: Laurent@814: self.LoadTabLayout(notebook, notebooks.get(entry_name)) Edouard@1408: Laurent@814: self._Refresh(EDITORTOOLBAR) Edouard@1408: Laurent@814: def RestoreLastState(self): Laurent@814: frame_size = None Laurent@814: if self.Config.HasEntry("framesize"): Laurent@814: frame_size = cPickle.loads(str(self.Config.Read("framesize"))) Edouard@1408: Laurent@814: if frame_size is None: Laurent@814: self.Maximize() Laurent@814: else: Laurent@814: self.SetClientSize(frame_size) Edouard@1408: Laurent@814: def SaveLastState(self): Laurent@814: if not self.IsMaximized(): Laurent@814: self.Config.Write("framesize", cPickle.dumps(self.GetClientSize())) Laurent@814: elif self.Config.HasEntry("framesize"): Laurent@814: self.Config.DeleteEntry("framesize") Edouard@1408: Laurent@814: self.Config.Flush() Laurent@814: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # General Functions Laurent@814: #------------------------------------------------------------------------------- Laurent@814: Laurent@814: def SetRefreshFunctions(self): Laurent@814: self.RefreshFunctions = { Laurent@814: TITLE : self.RefreshTitle, Laurent@814: EDITORTOOLBAR : self.RefreshEditorToolBar, Laurent@814: FILEMENU : self.RefreshFileMenu, Laurent@814: EDITMENU : self.RefreshEditMenu, Laurent@814: DISPLAYMENU : self.RefreshDisplayMenu, Laurent@814: PROJECTTREE : self.RefreshProjectTree, Edouard@1408: POUINSTANCEVARIABLESPANEL : self.RefreshPouInstanceVariablesPanel, Laurent@814: LIBRARYTREE : self.RefreshLibraryPanel, Laurent@814: SCALING : self.RefreshScaling, Laurent@814: PAGETITLES: self.RefreshPageTitles} Laurent@814: Laurent@814: ## Call PLCOpenEditor refresh functions. Laurent@814: # @param elements List of elements to refresh. Laurent@814: def _Refresh(self, *elements): Laurent@814: try: Laurent@814: for element in elements: Laurent@814: self.RefreshFunctions[element]() Laurent@814: except wx.PyDeadObjectError: Laurent@814: # ignore exceptions caused by refresh while quitting Laurent@814: pass Laurent@814: Laurent@814: ## Callback function when AUINotebook Page closed with CloseButton Laurent@814: # @param event AUINotebook Event. Laurent@814: def OnPageClose(self, event): Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected > -1: Laurent@814: window = self.TabsOpened.GetPage(selected) Edouard@1408: Laurent@814: if window.CheckSaveBeforeClosing(): Edouard@1408: Laurent@814: # Refresh all window elements that have changed Laurent@814: wx.CallAfter(self._Refresh, TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU) Laurent@814: wx.CallAfter(self.RefreshTabCtrlEvent) Laurent@814: wx.CallAfter(self.CloseFindInPouDialog) Laurent@814: event.Skip() Laurent@814: else: Laurent@814: event.Veto() Edouard@1408: Laurent@814: Laurent@1015: def GetCopyBuffer(self, primary_selection=False): Laurent@814: data = None Laurent@1028: if primary_selection and wx.Platform == '__WXMSW__': Laurent@1028: return data Laurent@1028: else: Laurent@1028: wx.TheClipboard.UsePrimarySelection(primary_selection) Laurent@814: if wx.TheClipboard.Open(): Laurent@814: dataobj = wx.TextDataObject() Laurent@814: if wx.TheClipboard.GetData(dataobj): Laurent@814: data = dataobj.GetText() Laurent@814: wx.TheClipboard.Close() Laurent@814: return data Edouard@1408: Laurent@1015: def SetCopyBuffer(self, text, primary_selection=False): Laurent@1028: if primary_selection and wx.Platform == '__WXMSW__': Laurent@1028: return Laurent@1028: else: Laurent@1028: wx.TheClipboard.UsePrimarySelection(primary_selection) Laurent@814: if wx.TheClipboard.Open(): Laurent@814: data = wx.TextDataObject() Laurent@814: data.SetText(text) Laurent@814: wx.TheClipboard.SetData(data) Laurent@814: wx.TheClipboard.Flush() Laurent@814: wx.TheClipboard.Close() Laurent@1087: self.RefreshEditMenu() Laurent@814: Laurent@814: def GetDrawingMode(self): Laurent@814: return self.DrawingMode Laurent@814: Laurent@814: def RefreshScaling(self): Laurent@814: for i in xrange(self.TabsOpened.GetPageCount()): Laurent@814: editor = self.TabsOpened.GetPage(i) Laurent@814: editor.RefreshScaling() Laurent@814: Laurent@814: def EditProjectSettings(self): Laurent@814: old_values = self.Controler.GetProjectProperties() Laurent@814: dialog = ProjectDialog(self) Laurent@814: dialog.SetValues(old_values) Laurent@814: if dialog.ShowModal() == wx.ID_OK: Laurent@814: new_values = dialog.GetValues() Laurent@814: new_values["creationDateTime"] = old_values["creationDateTime"] Laurent@814: if new_values != old_values: Laurent@814: self.Controler.SetProjectProperties(None, new_values) Edouard@1408: self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, Laurent@814: PROJECTTREE, POUINSTANCEVARIABLESPANEL, SCALING) Laurent@814: dialog.Destroy() Laurent@814: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # Notebook Unified Functions Laurent@814: #------------------------------------------------------------------------------- Edouard@1408: Laurent@814: ## Function that add a tab in Notebook, calling refresh for tab DClick event Laurent@814: # for wx.aui.AUINotebook. Laurent@814: # @param window Panel to display in tab. Laurent@814: # @param text title for the tab ctrl. Laurent@814: def AddPage(self, window, text): Laurent@814: self.TabsOpened.AddPage(window, text) Laurent@814: self.RefreshTabCtrlEvent() Edouard@1408: Laurent@814: ## Function that add a tab in Notebook, calling refresh for tab DClick event Laurent@814: # for wx.aui.AUINotebook. Laurent@814: # @param window Panel to display in tab. Laurent@814: # @param text title for the tab ctrl. Laurent@814: def DeletePage(self, window): Laurent@814: for idx in xrange(self.TabsOpened.GetPageCount()): Laurent@814: if self.TabsOpened.GetPage(idx) == window: Laurent@814: self.TabsOpened.DeletePage(idx) Laurent@814: self.RefreshTabCtrlEvent() Edouard@1408: return Edouard@1408: Edouard@1408: ## Function that fix difference in deleting all tabs between Laurent@814: # wx.Notebook and wx.aui.AUINotebook. Laurent@814: def DeleteAllPages(self): Laurent@814: for idx in xrange(self.TabsOpened.GetPageCount()): Laurent@814: self.TabsOpened.DeletePage(0) Laurent@814: self.RefreshTabCtrlEvent() Laurent@814: Edouard@1408: ## Function that fix difference in setting picture on tab between Laurent@814: # wx.Notebook and wx.aui.AUINotebook. Laurent@814: # @param idx Tab index. Laurent@814: # @param bitmap wx.Bitmap to define on tab. Laurent@814: # @return True if operation succeeded Laurent@814: def SetPageBitmap(self, idx, bitmap): Laurent@814: return self.TabsOpened.SetPageBitmap(idx, bitmap) Laurent@814: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # Dialog Message Functions Laurent@814: #------------------------------------------------------------------------------- Laurent@814: Laurent@814: ## Function displaying an Error dialog in PLCOpenEditor. Laurent@814: # @param message The message to display. Laurent@814: def ShowErrorMessage(self, message): Laurent@814: dialog = wx.MessageDialog(self, message, _("Error"), wx.OK|wx.ICON_ERROR) Laurent@814: dialog.ShowModal() Laurent@814: dialog.Destroy() Laurent@814: Laurent@814: ## Function displaying an Error dialog in PLCOpenEditor. Laurent@814: # @return False if closing cancelled. Laurent@814: def CheckSaveBeforeClosing(self, title=_("Close Project")): Laurent@814: if not self.Controler.ProjectIsSaved(): Laurent@814: dialog = wx.MessageDialog(self, _("There are changes, do you want to save?"), title, wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION) Laurent@814: answer = dialog.ShowModal() Laurent@814: dialog.Destroy() Laurent@814: if answer == wx.ID_YES: Laurent@814: self.SaveProject() Laurent@814: elif answer == wx.ID_CANCEL: Laurent@814: return False Edouard@1408: Laurent@814: for idx in xrange(self.TabsOpened.GetPageCount()): Laurent@814: window = self.TabsOpened.GetPage(idx) Laurent@814: if not window.CheckSaveBeforeClosing(): Laurent@814: return False Edouard@1408: Laurent@814: return True Laurent@814: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # File Menu Functions Laurent@814: #------------------------------------------------------------------------------- Laurent@814: Laurent@814: def RefreshFileMenu(self): Laurent@814: pass Laurent@814: Laurent@814: def ResetView(self): Laurent@814: self.DeleteAllPages() Laurent@814: self.ProjectTree.DeleteAllItems() Laurent@814: self.ProjectTree.Enable(False) Laurent@814: self.PouInstanceVariablesPanel.ResetView() Laurent@814: self.LibraryPanel.ResetTree() Laurent@814: self.LibraryPanel.SetController(None) Laurent@814: if self.EnableDebug: Laurent@916: self.DebugVariablePanel.ResetView() Laurent@814: self.Controler = None Laurent@814: Laurent@814: def OnCloseTabMenu(self, event): Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected >= 0: Laurent@814: self.TabsOpened.DeletePage(selected) Laurent@814: if self.TabsOpened.GetPageCount() > 0: Laurent@814: new_index = min(selected, self.TabsOpened.GetPageCount() - 1) Laurent@814: self.TabsOpened.SetSelection(new_index) Laurent@814: # Refresh all window elements that have changed Laurent@814: self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU) Laurent@814: self.RefreshTabCtrlEvent() Laurent@814: Laurent@814: def OnPageSetupMenu(self, event): Laurent@814: dialog = wx.PageSetupDialog(self, self.PageSetupData) Laurent@814: if dialog.ShowModal() == wx.ID_OK: Laurent@814: self.PageSetupData = wx.PageSetupDialogData(dialog.GetPageSetupData()) Laurent@814: self.PrintData = wx.PrintData(self.PageSetupData.GetPrintData()) Laurent@814: dialog.Destroy() Laurent@814: Laurent@814: def OnPreviewMenu(self, event): Edouard@1408: selected = self.TabsOpened.GetSelection() Laurent@814: if selected != -1: Laurent@814: window = self.TabsOpened.GetPage(selected) Laurent@814: data = wx.PrintDialogData(self.PrintData) Laurent@814: properties = self.Controler.GetProjectProperties(window.IsDebugging()) Laurent@814: page_size = map(int, properties["pageSize"]) Laurent@814: margins = (self.PageSetupData.GetMarginTopLeft(), self.PageSetupData.GetMarginBottomRight()) Laurent@814: printout = GraphicPrintout(window, page_size, margins, True) Laurent@814: printout2 = GraphicPrintout(window, page_size, margins, True) Laurent@814: preview = wx.PrintPreview(printout, printout2, data) Laurent@814: Laurent@814: if preview.Ok(): Laurent@814: preview_frame = wx.PreviewFrame(preview, self, _("Print preview"), style=wx.DEFAULT_FRAME_STYLE|wx.FRAME_FLOAT_ON_PARENT) Laurent@814: Laurent@814: preview_frame.Initialize() Edouard@1408: Laurent@814: preview_canvas = preview.GetCanvas() Laurent@814: preview_canvas.SetMinSize(preview_canvas.GetVirtualSize()) Laurent@814: preview_frame.Fit() Edouard@1408: Laurent@814: preview_frame.Show(True) Laurent@814: Laurent@814: def OnPrintMenu(self, event): Edouard@1408: selected = self.TabsOpened.GetSelection() Laurent@814: if selected != -1: Laurent@814: window = self.TabsOpened.GetPage(selected) Laurent@814: dialog_data = wx.PrintDialogData(self.PrintData) Laurent@814: dialog_data.SetToPage(1) Laurent@814: properties = self.Controler.GetProjectProperties(window.IsDebugging()) Laurent@814: page_size = map(int, properties["pageSize"]) Laurent@814: margins = (self.PageSetupData.GetMarginTopLeft(), self.PageSetupData.GetMarginBottomRight()) Laurent@814: printer = wx.Printer(dialog_data) Laurent@814: printout = GraphicPrintout(window, page_size, margins) Edouard@1408: Laurent@814: if not printer.Print(self, printout, True) and printer.GetLastError() != wx.PRINTER_CANCELLED: Laurent@814: self.ShowErrorMessage(_("There was a problem printing.\nPerhaps your current printer is not set correctly?")) Laurent@814: printout.Destroy() Laurent@814: Laurent@814: def OnPropertiesMenu(self, event): Laurent@814: self.EditProjectSettings() Laurent@814: Laurent@814: def OnQuitMenu(self, event): Laurent@814: self.Close() Laurent@814: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # Edit Menu Functions Laurent@814: #------------------------------------------------------------------------------- Laurent@814: Laurent@814: def RefreshEditMenu(self): Laurent@814: MenuToolBar = self.Panes["MenuToolBar"] Laurent@814: if self.Controler is not None: Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected > -1: Laurent@814: window = self.TabsOpened.GetPage(selected) Laurent@814: undo, redo = window.GetBufferState() Laurent@814: else: Laurent@814: undo, redo = self.Controler.GetBufferState() Laurent@814: self.EditMenu.Enable(wx.ID_UNDO, undo) Laurent@814: MenuToolBar.EnableTool(wx.ID_UNDO, undo) Laurent@814: self.EditMenu.Enable(wx.ID_REDO, redo) Laurent@814: MenuToolBar.EnableTool(wx.ID_REDO, redo) Laurent@814: #self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, True) Edouard@1408: #self.EditMenu.Check(ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, Laurent@814: # self.Controler.IsProjectBufferEnabled()) Laurent@814: self.EditMenu.Enable(wx.ID_FIND, selected > -1) Edouard@1408: self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUFINDNEXT, Laurent@814: selected > -1 and self.SearchParams is not None) Edouard@1408: self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUFINDPREVIOUS, Laurent@814: selected > -1 and self.SearchParams is not None) Laurent@814: self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT, True) Laurent@814: MenuToolBar.EnableTool(ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT, True) Laurent@814: self.EditMenu.Enable(wx.ID_ADD, True) Laurent@814: self.EditMenu.Enable(wx.ID_DELETE, True) Laurent@814: if self.TabsOpened.GetPageCount() > 0: Laurent@814: self.EditMenu.Enable(wx.ID_CUT, True) Laurent@814: MenuToolBar.EnableTool(wx.ID_CUT, True) Laurent@814: self.EditMenu.Enable(wx.ID_COPY, True) Laurent@814: MenuToolBar.EnableTool(wx.ID_COPY, True) Laurent@814: if self.GetCopyBuffer() is not None: Laurent@814: self.EditMenu.Enable(wx.ID_PASTE, True) Laurent@814: MenuToolBar.EnableTool(wx.ID_PASTE, True) Laurent@814: else: Laurent@814: self.EditMenu.Enable(wx.ID_PASTE, False) Laurent@814: MenuToolBar.EnableTool(wx.ID_PASTE, False) Laurent@814: self.EditMenu.Enable(wx.ID_SELECTALL, True) Laurent@814: else: Laurent@814: self.EditMenu.Enable(wx.ID_CUT, False) Laurent@814: MenuToolBar.EnableTool(wx.ID_CUT, False) Laurent@814: self.EditMenu.Enable(wx.ID_COPY, False) Laurent@814: MenuToolBar.EnableTool(wx.ID_COPY, False) Laurent@814: self.EditMenu.Enable(wx.ID_PASTE, False) Laurent@814: MenuToolBar.EnableTool(wx.ID_PASTE, False) Laurent@814: self.EditMenu.Enable(wx.ID_SELECTALL, False) Laurent@814: else: Laurent@814: self.EditMenu.Enable(wx.ID_UNDO, False) Laurent@814: MenuToolBar.EnableTool(wx.ID_UNDO, False) Laurent@814: self.EditMenu.Enable(wx.ID_REDO, False) Laurent@814: MenuToolBar.EnableTool(wx.ID_REDO, False) Laurent@814: #self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, False) Laurent@814: self.EditMenu.Enable(wx.ID_CUT, False) Laurent@814: MenuToolBar.EnableTool(wx.ID_CUT, False) Laurent@814: self.EditMenu.Enable(wx.ID_COPY, False) Laurent@814: MenuToolBar.EnableTool(wx.ID_COPY, False) Laurent@814: self.EditMenu.Enable(wx.ID_PASTE, False) Laurent@814: MenuToolBar.EnableTool(wx.ID_PASTE, False) Laurent@814: self.EditMenu.Enable(wx.ID_SELECTALL, False) Laurent@814: self.EditMenu.Enable(wx.ID_FIND, False) Laurent@814: self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUFINDNEXT, False) Laurent@814: self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUFINDPREVIOUS, False) Laurent@814: self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT, False) Laurent@814: MenuToolBar.EnableTool(ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT, False) Laurent@814: self.EditMenu.Enable(wx.ID_ADD, False) Laurent@814: self.EditMenu.Enable(wx.ID_DELETE, False) Edouard@1408: Laurent@814: def CloseTabsWithoutModel(self, refresh=True): Laurent@814: idxs = range(self.TabsOpened.GetPageCount()) Laurent@814: idxs.reverse() Laurent@814: for idx in idxs: Laurent@814: window = self.TabsOpened.GetPage(idx) Laurent@814: if window.HasNoModel(): Laurent@814: self.TabsOpened.DeletePage(idx) Laurent@814: if refresh: Laurent@814: self.RefreshEditor() Laurent@814: Laurent@814: def OnUndoMenu(self, event): Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected != -1: Laurent@814: window = self.TabsOpened.GetPage(selected) Laurent@814: window.Undo() Laurent@814: else: Laurent@814: self.Controler.LoadPrevious() Edouard@1408: self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE, Edouard@1408: SCALING, PAGETITLES) Edouard@1408: Laurent@814: def OnRedoMenu(self, event): Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected != -1: Laurent@814: window = self.TabsOpened.GetPage(selected) Laurent@814: window.Redo() Laurent@814: else: Laurent@814: self.Controler.LoadNext() Edouard@1408: self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE, Laurent@814: SCALING, PAGETITLES) Edouard@1408: Laurent@814: def OnEnableUndoRedoMenu(self, event): Laurent@814: self.Controler.EnableProjectBuffer(event.IsChecked()) Laurent@814: self.RefreshEditMenu() Laurent@814: Laurent@814: OnCutMenu = GetShortcutKeyCallbackFunction("Cut") Laurent@814: OnCopyMenu = GetShortcutKeyCallbackFunction("Copy") Laurent@814: OnPasteMenu = GetShortcutKeyCallbackFunction("Paste") Laurent@814: Laurent@814: def OnSelectAllMenu(self, event): Laurent@814: control = self.FindFocus() Laurent@814: if control is not None and control.GetName() == "Viewer": Laurent@814: control.Parent.SelectAll() Laurent@814: elif isinstance(control, wx.stc.StyledTextCtrl): Laurent@814: control.SelectAll() Laurent@814: elif isinstance(control, wx.TextCtrl): Laurent@814: control.SetSelection(0, control.GetLastPosition()) Laurent@814: elif isinstance(control, wx.ComboBox): Laurent@814: control.SetMark(0, control.GetLastPosition() + 1) Edouard@1408: Laurent@1129: def SetDeleteFunctions(self): Laurent@1129: self.DeleteFunctions = { Laurent@1129: ITEM_DATATYPE: GetDeleteElementFunction( Edouard@1408: PLCControler.ProjectRemoveDataType, Laurent@1129: check_function=self.CheckDataTypeIsUsedBeforeDeletion), Laurent@1129: ITEM_POU: GetDeleteElementFunction( Edouard@1408: PLCControler.ProjectRemovePou, Laurent@1129: check_function=self.CheckPouIsUsedBeforeDeletion), Laurent@1129: ITEM_TRANSITION: GetDeleteElementFunction( Laurent@1129: PLCControler.ProjectRemovePouTransition, ITEM_POU), Laurent@1129: ITEM_ACTION: GetDeleteElementFunction( Laurent@1129: PLCControler.ProjectRemovePouAction, ITEM_POU), Laurent@1129: ITEM_CONFIGURATION: GetDeleteElementFunction( Laurent@1129: PLCControler.ProjectRemoveConfiguration), Laurent@1129: ITEM_RESOURCE: GetDeleteElementFunction( Laurent@1129: PLCControler.ProjectRemoveConfigurationResource, ITEM_CONFIGURATION) Laurent@1129: } Edouard@1408: Laurent@814: def OnDeleteMenu(self, event): Laurent@814: window = self.FindFocus() Laurent@814: if window == self.ProjectTree or window is None: Laurent@814: selected = self.ProjectTree.GetSelection() Laurent@1165: if selected is not None and selected.IsOk(): Laurent@814: function = self.DeleteFunctions.get(self.ProjectTree.GetPyData(selected)["type"], None) Laurent@814: if function is not None: Laurent@814: function(self, selected) Laurent@814: self.CloseTabsWithoutModel() Edouard@1408: self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, PROJECTTREE, Laurent@814: POUINSTANCEVARIABLESPANEL, LIBRARYTREE) Laurent@814: elif isinstance(window, (Viewer, TextViewer)): Laurent@814: event = wx.KeyEvent(wx.EVT_CHAR._getEvtType()) Laurent@814: event.m_keyCode = wx.WXK_DELETE Laurent@814: window.ProcessEvent(event) Laurent@814: Laurent@814: def OnFindMenu(self, event): Laurent@814: if not self.FindDialog.IsShown(): Laurent@814: self.FindDialog.Show() surkovsv93@1556: self.FindDialog.FindPattern.SetFocus() Edouard@1408: Laurent@814: def CloseFindInPouDialog(self): Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected == -1 and self.FindDialog.IsShown(): Laurent@814: self.FindDialog.Hide() Edouard@1408: Laurent@814: def OnFindNextMenu(self, event): Laurent@814: self.FindInPou(1) Edouard@1408: Laurent@814: def OnFindPreviousMenu(self, event): Laurent@814: self.FindInPou(-1) Edouard@1408: Laurent@814: def FindInPou(self, direction, search_params=None): Laurent@814: if search_params is not None: Laurent@814: self.SearchParams = search_params Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected != -1: Laurent@814: window = self.TabsOpened.GetPage(selected) Laurent@814: window.Find(direction, self.SearchParams) Edouard@1408: Laurent@814: def OnSearchInProjectMenu(self, event): Laurent@814: dialog = SearchInProjectDialog(self) Laurent@814: if dialog.ShowModal() == wx.ID_OK: Laurent@814: criteria = dialog.GetCriteria() surkovsv93@1556: if len(criteria) > 0: surkovsv93@1556: result = self.Controler.SearchInProject(criteria) surkovsv93@1556: self.ClearSearchResults() surkovsv93@1556: self.SearchResultPanel.SetSearchResults(criteria, result) surkovsv93@1556: self.SelectTab(self.SearchResultPanel) Edouard@1408: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # Display Menu Functions Laurent@814: #------------------------------------------------------------------------------- Laurent@814: Laurent@814: def RefreshDisplayMenu(self): Laurent@814: if self.Controler is not None: Laurent@814: if self.TabsOpened.GetPageCount() > 0: Laurent@814: self.DisplayMenu.Enable(wx.ID_REFRESH, True) Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected != -1: Laurent@814: window = self.TabsOpened.GetPage(selected) Laurent@814: if isinstance(window, Viewer): Laurent@814: self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, True) Laurent@814: zoommenu = self.DisplayMenu.FindItemById(wx.ID_ZOOM_FIT).GetSubMenu() Laurent@814: zoomitem = zoommenu.FindItemByPosition(window.GetScale()) Laurent@814: zoomitem.Check(True) Laurent@814: else: Laurent@814: self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, False) Laurent@814: else: Laurent@814: self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, False) Laurent@814: else: Laurent@814: self.DisplayMenu.Enable(wx.ID_REFRESH, False) Laurent@814: self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, False) Laurent@814: if self.EnableDebug: Laurent@814: self.DisplayMenu.Enable(wx.ID_CLEAR, True) Laurent@814: else: Laurent@814: self.DisplayMenu.Enable(wx.ID_REFRESH, False) Laurent@814: if self.EnableDebug: Laurent@814: self.DisplayMenu.Enable(wx.ID_CLEAR, False) Laurent@814: self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, False) Edouard@1408: Laurent@814: def OnRefreshMenu(self, event): Laurent@814: self.RefreshEditor() Laurent@814: Laurent@814: def OnClearErrorsMenu(self, event): Laurent@814: self.ClearErrors() Laurent@814: Laurent@814: def GenerateZoomFunction(self, idx): Laurent@814: def ZoomFunction(event): Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected != -1: Laurent@814: window = self.TabsOpened.GetPage(selected) Laurent@814: window.SetScale(idx) Laurent@814: window.RefreshVisibleElements() Laurent@814: window.RefreshScrollBars() Laurent@814: event.Skip() Laurent@814: return ZoomFunction Laurent@814: Laurent@814: def OnResetPerspective(self, event): Laurent@814: self.ResetPerspective() Laurent@814: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # Project Editor Panels Management Functions Laurent@814: #------------------------------------------------------------------------------- Edouard@1408: Laurent@814: def OnPageDragged(self, event): Laurent@814: wx.CallAfter(self.RefreshTabCtrlEvent) Laurent@814: event.Skip() Edouard@1408: Laurent@814: def OnAllowNotebookDnD(self, event): Laurent@814: event.Allow() Edouard@1408: Laurent@814: def RefreshTabCtrlEvent(self): Laurent@814: auitabctrl = [] Laurent@814: for child in self.TabsOpened.GetChildren(): Laurent@814: if isinstance(child, wx.aui.AuiTabCtrl): Laurent@814: auitabctrl.append(child) Laurent@814: if child not in self.AuiTabCtrl: Laurent@814: child.Bind(wx.EVT_LEFT_DCLICK, self.GetTabsOpenedDClickFunction(child)) Laurent@814: self.AuiTabCtrl = auitabctrl Laurent@814: if self.TabsOpened.GetPageCount() == 0: Laurent@814: pane = self.AUIManager.GetPane(self.TabsOpened) Laurent@814: if pane.IsMaximized(): Laurent@814: self.AUIManager.RestorePane(pane) Laurent@814: self.AUIManager.Update() Edouard@1408: Laurent@814: def EnsureTabVisible(self, tab): Laurent@814: notebook = tab.GetParent() Laurent@814: notebook.SetSelection(notebook.GetPageIndex(tab)) Edouard@1408: Laurent@814: def OnPouSelectedChanging(self, event): Laurent@989: selected = self.TabsOpened.GetSelection() Laurent@989: if selected >= 0: Laurent@989: window = self.TabsOpened.GetPage(selected) Laurent@989: if not window.IsDebugging(): Laurent@989: window.ResetBuffer() Laurent@814: event.Skip() Edouard@1408: Laurent@814: def OnPouSelectedChanged(self, event): Laurent@989: selected = self.TabsOpened.GetSelection() Laurent@989: if selected >= 0: Laurent@989: window = self.TabsOpened.GetPage(selected) Laurent@989: tagname = window.GetTagName() Laurent@989: if not window.IsDebugging(): Laurent@1158: self.SelectProjectTreeItem(tagname) Laurent@1233: self.PouInstanceVariablesPanel.SetPouType(tagname) Laurent@989: window.RefreshView() Laurent@989: self.EnsureTabVisible(self.LibraryPanel) Laurent@989: else: Laurent@989: instance_path = window.GetInstancePath() Laurent@989: if tagname == "": Laurent@989: instance_path = instance_path.rsplit(".", 1)[0] Laurent@989: tagname = self.Controler.GetPouInstanceTagName(instance_path, self.EnableDebug) Laurent@989: self.EnsureTabVisible(self.DebugVariablePanel) Laurent@989: wx.CallAfter(self.PouInstanceVariablesPanel.SetPouType, tagname, instance_path) Laurent@989: wx.CallAfter(self._Refresh, FILEMENU, EDITMENU, DISPLAYMENU, EDITORTOOLBAR) Laurent@814: event.Skip() Edouard@1408: Laurent@814: def RefreshEditor(self): Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected >= 0: Laurent@814: window = self.TabsOpened.GetPage(selected) Laurent@814: tagname = window.GetTagName() Laurent@814: if not window.IsDebugging(): Laurent@814: self.SelectProjectTreeItem(tagname) Laurent@814: self.PouInstanceVariablesPanel.SetPouType(tagname) Laurent@814: else: Laurent@814: instance_path = window.GetInstancePath() Laurent@814: if tagname == "": Laurent@814: instance_path = instance_path.rsplit(".", 1)[0] Laurent@814: tagname = self.Controler.GetPouInstanceTagName(instance_path, self.EnableDebug) Laurent@814: self.PouInstanceVariablesPanel.SetPouType(tagname, instance_path) Laurent@814: for child in self.TabsOpened.GetChildren(): Laurent@814: if isinstance(child, wx.aui.AuiTabCtrl): Laurent@814: active_page = child.GetActivePage() Laurent@814: if active_page >= 0: Laurent@814: window = child.GetWindowFromIdx(active_page) Laurent@814: window.RefreshView() Laurent@814: self._Refresh(FILEMENU, EDITMENU, DISPLAYMENU, EDITORTOOLBAR) Edouard@1408: Laurent@814: def RefreshEditorNames(self, old_tagname, new_tagname): Laurent@814: for i in xrange(self.TabsOpened.GetPageCount()): Laurent@814: editor = self.TabsOpened.GetPage(i) Laurent@814: if editor.GetTagName() == old_tagname: Laurent@814: editor.SetTagName(new_tagname) Edouard@1408: Laurent@814: def IsOpened(self, tagname): Laurent@814: for idx in xrange(self.TabsOpened.GetPageCount()): Laurent@814: if self.TabsOpened.GetPage(idx).IsViewing(tagname): Laurent@814: return idx Laurent@814: return None Laurent@814: Laurent@814: def RefreshPageTitles(self): Laurent@814: for idx in xrange(self.TabsOpened.GetPageCount()): Laurent@814: window = self.TabsOpened.GetPage(idx) Laurent@814: icon = window.GetIcon() Laurent@814: if icon is not None: Laurent@814: self.SetPageBitmap(idx, icon) Laurent@814: self.TabsOpened.SetPageText(idx, window.GetTitle()) Laurent@814: Laurent@814: def GetTabsOpenedDClickFunction(self, tabctrl): Laurent@814: def OnTabsOpenedDClick(event): Laurent@814: pos = event.GetPosition() Laurent@814: if tabctrl.TabHitTest(pos.x, pos.y, None): surkovsv93@1530: self.SwitchFullScrMode(event) Laurent@814: event.Skip() Laurent@814: return OnTabsOpenedDClick Laurent@814: surkovsv93@1530: def SwitchFullScrMode(self,evt): surkovsv93@1530: pane = self.AUIManager.GetPane(self.TabsOpened) surkovsv93@1530: if pane.IsMaximized(): surkovsv93@1530: self.AUIManager.RestorePane(pane) surkovsv93@1530: else: surkovsv93@1530: self.AUIManager.MaximizePane(pane) surkovsv93@1530: self.AUIManager.Update() surkovsv93@1530: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # Types Tree Management Functions Laurent@814: #------------------------------------------------------------------------------- Laurent@814: Laurent@814: def RefreshProjectTree(self): Laurent@1105: # Extract current selected item tagname Laurent@1105: selected = self.ProjectTree.GetSelection() Laurent@1105: if selected is not None and selected.IsOk(): Laurent@1105: item_infos = self.ProjectTree.GetPyData(selected) Laurent@1105: tagname = item_infos.get("tagname", None) Laurent@1105: else: Laurent@1105: tagname = None Edouard@1408: Laurent@1105: # Refresh treectrl items according to project infos Laurent@814: infos = self.Controler.GetProjectInfos() Laurent@814: root = self.ProjectTree.GetRootItem() Laurent@1164: if root is None or not root.IsOk(): Laurent@814: root = self.ProjectTree.AddRoot(infos["name"]) Laurent@814: self.GenerateProjectTreeBranch(root, infos) Laurent@814: self.ProjectTree.Expand(root) Edouard@1408: Laurent@1105: # Select new item corresponding to previous selected item Laurent@1105: if tagname is not None: Laurent@1158: self.SelectProjectTreeItem(tagname) Laurent@814: Laurent@1164: def GenerateProjectTreeBranch(self, root, infos, item_alone=False): Laurent@814: to_delete = [] Laurent@814: item_name = infos["name"] Laurent@814: if infos["type"] in ITEMS_UNEDITABLE: Laurent@814: if len(infos["values"]) == 1: Laurent@1164: return self.GenerateProjectTreeBranch(root, infos["values"][0], True) Laurent@814: item_name = _(item_name) Laurent@814: self.ProjectTree.SetItemText(root, item_name) Laurent@814: self.ProjectTree.SetPyData(root, infos) Laurent@814: highlight_colours = self.Highlights.get(infos.get("tagname", None), (wx.WHITE, wx.BLACK)) Laurent@814: self.ProjectTree.SetItemBackgroundColour(root, highlight_colours[0]) Laurent@814: self.ProjectTree.SetItemTextColour(root, highlight_colours[1]) Laurent@1188: self.ProjectTree.SetItemExtraImage(root, None) Laurent@814: if infos["type"] == ITEM_POU: Edouard@1408: self.ProjectTree.SetItemImage(root, Laurent@1164: self.TreeImageDict[self.Controler.GetPouBodyType(infos["name"])]) Laurent@1164: if item_alone: Laurent@1164: self.ProjectTree.SetItemExtraImage(root, self.Controler.GetPouType(infos["name"])) Laurent@814: elif infos.has_key("icon") and infos["icon"] is not None: Laurent@814: icon_name = infos["icon"] Laurent@814: if not self.TreeImageDict.has_key(icon_name): Laurent@814: self.TreeImageDict[icon_name] = self.TreeImageList.Add(GetBitmap(icon_name)) Laurent@814: self.ProjectTree.SetItemImage(root, self.TreeImageDict[icon_name]) Laurent@814: elif self.TreeImageDict.has_key(infos["type"]): Edouard@1408: self.ProjectTree.SetItemImage(root, self.TreeImageDict[infos["type"]]) Edouard@1408: Laurent@1164: item, root_cookie = self.ProjectTree.GetFirstChild(root) Laurent@814: for values in infos["values"]: Laurent@814: if values["type"] not in ITEMS_UNEDITABLE or len(values["values"]) > 0: Laurent@1164: if item is None or not item.IsOk(): Laurent@814: item = self.ProjectTree.AppendItem(root, "") Laurent@1165: item, root_cookie = self.ProjectTree.GetNextChild(root, root_cookie) Laurent@814: self.GenerateProjectTreeBranch(item, values) Laurent@814: item, root_cookie = self.ProjectTree.GetNextChild(root, root_cookie) Laurent@1164: while item is not None and item.IsOk(): Laurent@814: to_delete.append(item) Laurent@814: item, root_cookie = self.ProjectTree.GetNextChild(root, root_cookie) Laurent@814: for item in to_delete: Laurent@814: self.ProjectTree.Delete(item) Laurent@814: Laurent@1165: TagNamePartsItemTypes = { Laurent@1165: "D": [ITEM_DATATYPE], Laurent@1165: "P": [ITEM_POU], Laurent@1165: "T": [ITEM_POU, ITEM_TRANSITION], Laurent@1165: "A": [ITEM_POU, ITEM_ACTION], Laurent@1165: "C": [ITEM_CONFIGURATION], Laurent@1165: "R": [ITEM_CONFIGURATION, ITEM_RESOURCE]} Laurent@1165: Laurent@814: def SelectProjectTreeItem(self, tagname): Laurent@1158: result = False Laurent@814: if self.ProjectTree is not None: Laurent@814: root = self.ProjectTree.GetRootItem() Laurent@1165: if root is not None and root.IsOk(): Laurent@814: words = tagname.split("::") Laurent@1165: result = self.RecursiveProjectTreeItemSelection(root, Laurent@1165: zip(words[1:], self.TagNamePartsItemTypes.get(words[0], []))) Laurent@1158: return result Laurent@814: Laurent@814: def RecursiveProjectTreeItemSelection(self, root, items): Laurent@814: found = False Laurent@1164: item, root_cookie = self.ProjectTree.GetFirstChild(root) Laurent@1164: while item is not None and item.IsOk() and not found: Laurent@814: item_infos = self.ProjectTree.GetPyData(item) Laurent@814: if (item_infos["name"].split(":")[-1].strip(), item_infos["type"]) == items[0]: Laurent@814: if len(items) == 1: Laurent@814: self.SelectedItem = item Laurent@1158: self.ProjectTree.SelectItem(item) Laurent@1158: self.ResetSelectedItem() Laurent@814: return True Laurent@814: else: Laurent@814: found = self.RecursiveProjectTreeItemSelection(item, items[1:]) Laurent@814: else: Laurent@814: found = self.RecursiveProjectTreeItemSelection(item, items) Laurent@814: item, root_cookie = self.ProjectTree.GetNextChild(root, root_cookie) Laurent@814: return found Laurent@814: Laurent@1243: def ResetSelectedItem(self): Laurent@1243: self.SelectedItem = None Laurent@1243: Laurent@814: def OnProjectTreeBeginDrag(self, event): Edouard@1408: selected_item = (self.SelectedItem Laurent@1243: if self.SelectedItem is not None Laurent@1243: else event.GetItem()) Laurent@1243: if selected_item.IsOk() and self.ProjectTree.GetPyData(selected_item)["type"] == ITEM_POU: Laurent@1243: block_name = self.ProjectTree.GetItemText(selected_item) Laurent@814: block_type = self.Controler.GetPouType(block_name) Laurent@814: if block_type != "program": Laurent@814: data = wx.TextDataObject(str((block_name, block_type, ""))) Laurent@814: dragSource = wx.DropSource(self.ProjectTree) Laurent@814: dragSource.SetData(data) Laurent@814: dragSource.DoDragDrop() Laurent@814: self.ResetSelectedItem() Laurent@814: Laurent@814: def OnProjectTreeItemBeginEdit(self, event): Laurent@814: selected = event.GetItem() Laurent@814: if self.ProjectTree.GetPyData(selected)["type"] in ITEMS_UNEDITABLE: Laurent@814: event.Veto() Laurent@814: else: Laurent@814: event.Skip() Laurent@814: Laurent@814: def OnProjectTreeItemEndEdit(self, event): Laurent@814: message = None Laurent@814: abort = False Laurent@814: new_name = event.GetLabel() Laurent@814: if new_name != "": Laurent@814: if not TestIdentifier(new_name): Laurent@814: message = _("\"%s\" is not a valid identifier!")%new_name Laurent@814: elif new_name.upper() in IEC_KEYWORDS: Laurent@814: message = _("\"%s\" is a keyword. It can't be used!")%new_name Laurent@814: else: Laurent@814: item = event.GetItem() Laurent@814: old_name = self.ProjectTree.GetItemText(item) Laurent@814: item_infos = self.ProjectTree.GetPyData(item) Laurent@814: if item_infos["type"] == ITEM_PROJECT: Laurent@814: self.Controler.SetProjectProperties(name = new_name) Laurent@814: elif item_infos["type"] == ITEM_DATATYPE: Laurent@814: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectDataTypeNames() if name != old_name]: Laurent@814: message = _("\"%s\" data type already exists!")%new_name Laurent@814: abort = True Laurent@814: if not abort: Laurent@814: self.Controler.ChangeDataTypeName(old_name, new_name) Edouard@1408: self.RefreshEditorNames(self.Controler.ComputeDataTypeName(old_name), Laurent@814: self.Controler.ComputeDataTypeName(new_name)) Laurent@814: self.RefreshPageTitles() Laurent@814: elif item_infos["type"] == ITEM_POU: Laurent@814: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames() if name != old_name]: Laurent@814: message = _("\"%s\" pou already exists!")%new_name Laurent@814: abort = True Laurent@1171: elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariableNames()]: Laurent@814: messageDialog = wx.MessageDialog(self, _("A POU has an element named \"%s\". This could cause a conflict. Do you wish to continue?")%new_name, _("Error"), wx.YES_NO|wx.ICON_QUESTION) Laurent@814: if messageDialog.ShowModal() == wx.ID_NO: Laurent@814: abort = True Laurent@814: messageDialog.Destroy() Laurent@814: if not abort: Laurent@814: self.Controler.ChangePouName(old_name, new_name) Edouard@1408: self.RefreshEditorNames(self.Controler.ComputePouName(old_name), Laurent@814: self.Controler.ComputePouName(new_name)) Laurent@814: self.RefreshLibraryPanel() Laurent@814: self.RefreshPageTitles() Laurent@814: elif item_infos["type"] == ITEM_TRANSITION: andrej@1610: pou_item = self.ProjectTree.GetItemParent(event.GetItem()) andrej@1610: pou_name = self.ProjectTree.GetItemText(pou_item) Laurent@814: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]: Laurent@814: message = _("A POU named \"%s\" already exists!")%new_name Laurent@1171: elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariableNames(pou_name) if name != old_name]: Laurent@814: message = _("A variable with \"%s\" as name already exists in this pou!")%new_name Laurent@814: else: Laurent@814: words = item_infos["tagname"].split("::") Laurent@814: self.Controler.ChangePouTransitionName(words[1], old_name, new_name) Edouard@1408: self.RefreshEditorNames(self.Controler.ComputePouTransitionName(words[1], old_name), Laurent@814: self.Controler.ComputePouTransitionName(words[1], new_name)) Laurent@814: self.RefreshPageTitles() Laurent@814: elif item_infos["type"] == ITEM_ACTION: andrej@1610: pou_item = self.ProjectTree.GetItemParent(event.GetItem()) andrej@1610: pou_name = self.ProjectTree.GetItemText(pou_item) Laurent@814: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]: Laurent@814: message = _("A POU named \"%s\" already exists!")%new_name Laurent@1171: elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariableNames(pou_name) if name != old_name]: Laurent@814: message = _("A variable with \"%s\" as name already exists in this pou!")%new_name Laurent@814: else: Laurent@814: words = item_infos["tagname"].split("::") Laurent@814: self.Controler.ChangePouActionName(words[1], old_name, new_name) Edouard@1408: self.RefreshEditorNames(self.Controler.ComputePouActionName(words[1], old_name), Laurent@814: self.Controler.ComputePouActionName(words[1], new_name)) Laurent@814: self.RefreshPageTitles() Laurent@814: elif item_infos["type"] == ITEM_CONFIGURATION: Laurent@814: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames() if name != old_name]: Laurent@814: message = _("\"%s\" config already exists!")%new_name Laurent@814: abort = True Laurent@814: elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]: Laurent@814: messageDialog = wx.MessageDialog(self, _("There is a POU named \"%s\". This could cause a conflict. Do you wish to continue?")%new_name, _("Error"), wx.YES_NO|wx.ICON_QUESTION) Laurent@814: if messageDialog.ShowModal() == wx.ID_NO: Laurent@814: abort = True Laurent@814: messageDialog.Destroy() Laurent@1171: elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariableNames()]: Laurent@814: messageDialog = wx.MessageDialog(self, _("A POU has an element named \"%s\". This could cause a conflict. Do you wish to continue?")%new_name, _("Error"), wx.YES_NO|wx.ICON_QUESTION) Laurent@814: if messageDialog.ShowModal() == wx.ID_NO: Laurent@814: abort = True Laurent@814: messageDialog.Destroy() Laurent@814: if not abort: Laurent@814: self.Controler.ChangeConfigurationName(old_name, new_name) Edouard@1408: self.RefreshEditorNames(self.Controler.ComputeConfigurationName(old_name), Laurent@814: self.Controler.ComputeConfigurationName(new_name)) Laurent@814: self.RefreshPageTitles() Laurent@814: elif item_infos["type"] == ITEM_RESOURCE: Laurent@814: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames()]: Laurent@814: message = _("\"%s\" config already exists!")%new_name Laurent@814: abort = True Laurent@814: elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]: Laurent@814: messageDialog = wx.MessageDialog(self, _("There is a POU named \"%s\". This could cause a conflict. Do you wish to continue?")%new_name, _("Error"), wx.YES_NO|wx.ICON_QUESTION) Laurent@814: if messageDialog.ShowModal() == wx.ID_NO: Laurent@814: abort = True Laurent@814: messageDialog.Destroy() Laurent@1171: elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariableNames()]: Laurent@814: messageDialog = wx.MessageDialog(self, _("A POU has an element named \"%s\". This could cause a conflict. Do you wish to continue?")%new_name, _("Error"), wx.YES_NO|wx.ICON_QUESTION) Laurent@814: if messageDialog.ShowModal() == wx.ID_NO: Laurent@814: abort = True Laurent@814: messageDialog.Destroy() Laurent@814: if not abort: Laurent@814: words = item_infos["tagname"].split("::") Laurent@814: self.Controler.ChangeConfigurationResourceName(words[1], old_name, new_name) Edouard@1408: self.RefreshEditorNames(self.Controler.ComputeConfigurationResourceName(words[1], old_name), Laurent@814: self.Controler.ComputeConfigurationResourceName(words[1], new_name)) Laurent@814: self.RefreshPageTitles() Laurent@814: if message or abort: Laurent@814: if message: Laurent@814: self.ShowErrorMessage(message) Laurent@814: event.Veto() Laurent@814: else: Laurent@814: wx.CallAfter(self.RefreshProjectTree) Laurent@814: self.RefreshEditor() Laurent@814: self._Refresh(TITLE, FILEMENU, EDITMENU) Laurent@814: event.Skip() Edouard@1408: Laurent@814: def OnProjectTreeItemActivated(self, event): Laurent@814: selected = event.GetItem() Laurent@814: name = self.ProjectTree.GetItemText(selected) Laurent@814: item_infos = self.ProjectTree.GetPyData(selected) Laurent@814: if item_infos["type"] == ITEM_PROJECT: Laurent@814: self.EditProjectSettings() Laurent@814: else: Laurent@814: if item_infos["type"] in [ITEM_DATATYPE, ITEM_POU, Laurent@814: ITEM_CONFIGURATION, ITEM_RESOURCE, Laurent@814: ITEM_TRANSITION, ITEM_ACTION]: Laurent@814: self.EditProjectElement(item_infos["type"], item_infos["tagname"]) Laurent@814: event.Skip() Edouard@1408: Laurent@814: def ProjectTreeItemSelect(self, select_item): Laurent@1164: if select_item is not None and select_item.IsOk(): Laurent@1112: name = self.ProjectTree.GetItemText(select_item) Laurent@1112: item_infos = self.ProjectTree.GetPyData(select_item) Laurent@1112: if item_infos["type"] in [ITEM_DATATYPE, ITEM_POU, Laurent@1112: ITEM_CONFIGURATION, ITEM_RESOURCE, Laurent@1112: ITEM_TRANSITION, ITEM_ACTION]: Laurent@1112: self.EditProjectElement(item_infos["type"], item_infos["tagname"], True) Laurent@1112: self.PouInstanceVariablesPanel.SetPouType(item_infos["tagname"]) Edouard@1408: Laurent@814: def OnProjectTreeLeftUp(self, event): Laurent@814: if self.SelectedItem is not None: Laurent@814: self.ProjectTree.SelectItem(self.SelectedItem) Laurent@814: self.ProjectTreeItemSelect(self.SelectedItem) Laurent@1240: self.ResetSelectedItem() Laurent@814: event.Skip() Edouard@1408: Laurent@1106: def OnProjectTreeMotion(self, event): Laurent@1106: if not event.Dragging(): Laurent@1106: pt = wx.Point(event.GetX(), event.GetY()) Laurent@1106: item, flags = self.ProjectTree.HitTest(pt) Laurent@1164: if item is not None and item.IsOk() and flags & wx.TREE_HITTEST_ONITEMLABEL: Laurent@1106: item_infos = self.ProjectTree.GetPyData(item) Laurent@1106: if item != self.LastToolTipItem and self.LastToolTipItem is not None: Laurent@1106: self.ProjectTree.SetToolTip(None) Laurent@1106: self.LastToolTipItem = None Edouard@1408: if (self.LastToolTipItem != item and Laurent@1106: item_infos["type"] in [ITEM_POU, ITEM_TRANSITION, ITEM_ACTION]): Laurent@1106: bodytype = self.Controler.GetEditedElementBodyType( Laurent@1106: item_infos["tagname"]) Laurent@1106: if item_infos["type"] == ITEM_POU: Laurent@1106: block_type = { Laurent@1106: "program": _("Program"), Laurent@1106: "functionBlock": _("Function Block"), Laurent@1106: "function": _("Function") Laurent@1106: }[self.Controler.GetPouType(item_infos["name"])] Laurent@1106: elif item_infos["type"] == ITEM_TRANSITION: Laurent@1106: block_type = "Transition" Laurent@1106: else: Laurent@1106: block_type = "Action" Laurent@1106: self.LastToolTipItem = item Edouard@1408: wx.CallAfter(self.ProjectTree.SetToolTipString, Laurent@1106: "%s : %s : %s" % ( Laurent@1106: block_type, bodytype, item_infos["name"])) Laurent@1106: elif self.LastToolTipItem is not None: Laurent@1106: self.ProjectTree.SetToolTip(None) Laurent@1106: self.LastToolTipItem = None Laurent@1106: event.Skip() Edouard@1408: Laurent@814: def OnProjectTreeItemChanging(self, event): Laurent@814: if self.ProjectTree.GetPyData(event.GetItem())["type"] not in ITEMS_UNEDITABLE and self.SelectedItem is None: Laurent@814: self.SelectedItem = event.GetItem() Laurent@814: event.Veto() Laurent@814: else: Laurent@814: event.Skip() Edouard@1408: Laurent@814: def EditProjectElement(self, element, tagname, onlyopened = False): Laurent@814: openedidx = self.IsOpened(tagname) Laurent@814: if openedidx is not None: Laurent@814: old_selected = self.TabsOpened.GetSelection() Laurent@814: if old_selected != openedidx: Laurent@814: if old_selected >= 0: Laurent@814: self.TabsOpened.GetPage(old_selected).ResetBuffer() Laurent@814: self.TabsOpened.SetSelection(openedidx) Laurent@814: self._Refresh(FILEMENU, EDITMENU, EDITORTOOLBAR, PAGETITLES) Laurent@814: elif not onlyopened: Laurent@870: if isinstance(element, EditorPanel): Laurent@814: new_window = element Laurent@814: self.AddPage(element, "") Laurent@870: elif self.Controler.GetEditedElement(tagname) is not None: Laurent@870: new_window = None Laurent@870: if element == ITEM_CONFIGURATION: Laurent@870: new_window = ConfigurationEditor(self.TabsOpened, tagname, self, self.Controler) Laurent@870: new_window.SetIcon(GetBitmap("CONFIGURATION")) Laurent@870: self.AddPage(new_window, "") Laurent@870: elif element == ITEM_RESOURCE: Laurent@870: new_window = ResourceEditor(self.TabsOpened, tagname, self, self.Controler) Laurent@870: new_window.SetIcon(GetBitmap("RESOURCE")) Laurent@870: self.AddPage(new_window, "") Laurent@870: elif element in [ITEM_POU, ITEM_TRANSITION, ITEM_ACTION]: Laurent@870: bodytype = self.Controler.GetEditedElementBodyType(tagname) Laurent@870: if bodytype == "FBD": Laurent@870: new_window = Viewer(self.TabsOpened, tagname, self, self.Controler) Laurent@870: new_window.RefreshScaling(False) Laurent@870: elif bodytype == "LD": Laurent@870: new_window = LD_Viewer(self.TabsOpened, tagname, self, self.Controler) Laurent@870: new_window.RefreshScaling(False) Laurent@870: elif bodytype == "SFC": Laurent@870: new_window = SFC_Viewer(self.TabsOpened, tagname, self, self.Controler) Laurent@870: new_window.RefreshScaling(False) Laurent@870: else: Laurent@870: new_window = TextViewer(self.TabsOpened, tagname, self, self.Controler) Laurent@870: new_window.SetTextSyntax(bodytype) Laurent@870: if bodytype == "IL": Laurent@870: new_window.SetKeywords(IL_KEYWORDS) Laurent@870: else: Laurent@870: new_window.SetKeywords(ST_KEYWORDS) Laurent@870: if element == ITEM_POU: Laurent@870: pou_type = self.Controler.GetEditedElementType(tagname)[1].upper() Laurent@870: icon = GetBitmap(pou_type, bodytype) Laurent@870: elif element == ITEM_TRANSITION: Laurent@870: icon = GetBitmap("TRANSITION", bodytype) Laurent@870: elif element == ITEM_ACTION: Laurent@870: icon = GetBitmap("ACTION", bodytype) Laurent@870: new_window.SetIcon(icon) Laurent@870: self.AddPage(new_window, "") Laurent@870: elif element == ITEM_DATATYPE: Laurent@870: new_window = DataTypeEditor(self.TabsOpened, tagname, self, self.Controler) Laurent@870: new_window.SetIcon(GetBitmap("DATATYPE")) Laurent@870: self.AddPage(new_window, "") Laurent@814: if new_window is not None: Laurent@814: openedidx = self.IsOpened(tagname) Laurent@814: old_selected = self.TabsOpened.GetSelection() Laurent@814: if old_selected != openedidx: Laurent@814: if old_selected >= 0: Laurent@814: self.TabsOpened.GetPage(old_selected).ResetBuffer() Laurent@814: for i in xrange(self.TabsOpened.GetPageCount()): Laurent@814: window = self.TabsOpened.GetPage(i) Laurent@814: if window == new_window: Laurent@814: self.TabsOpened.SetSelection(i) Laurent@814: window.SetFocus() Laurent@814: self.RefreshPageTitles() Laurent@814: return new_window Edouard@1408: Laurent@814: def OnProjectTreeRightUp(self, event): Laurent@1240: item = event.GetItem() Laurent@814: self.ProjectTree.SelectItem(item) Laurent@814: self.ProjectTreeItemSelect(item) Laurent@814: name = self.ProjectTree.GetItemText(item) Laurent@814: item_infos = self.ProjectTree.GetPyData(item) Edouard@1408: Laurent@814: menu = None Laurent@814: if item_infos["type"] in ITEMS_UNEDITABLE + [ITEM_PROJECT]: Laurent@814: if item_infos["type"] == ITEM_PROJECT: Laurent@814: name = "Project" Laurent@814: else: Laurent@814: name = UNEDITABLE_NAMES_DICT[name] Edouard@1408: Laurent@814: if name == "Data Types": Laurent@814: menu = wx.Menu(title='') Laurent@814: new_id = wx.NewId() Laurent@814: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add DataType")) Laurent@814: self.Bind(wx.EVT_MENU, self.OnAddDataTypeMenu, id=new_id) Edouard@1408: Laurent@814: elif name in ["Functions", "Function Blocks", "Programs", "Project"]: Laurent@814: menu = wx.Menu(title='') Edouard@1408: Laurent@814: if name != "Project": Laurent@814: new_id = wx.NewId() Laurent@814: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add POU")) Laurent@814: self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction({"Functions" : "function", "Function Blocks" : "functionBlock", "Programs" : "program"}[name]), id=new_id) Laurent@814: Laurent@814: new_id = wx.NewId() Laurent@814: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Paste POU")) Laurent@814: self.Bind(wx.EVT_MENU, self.OnPastePou, id=new_id) Laurent@814: if self.GetCopyBuffer() is None: Laurent@814: menu.Enable(new_id, False) Laurent@814: Laurent@814: elif name == "Configurations": Laurent@814: menu = wx.Menu(title='') Laurent@814: new_id = wx.NewId() Laurent@814: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Configuration")) Laurent@814: self.Bind(wx.EVT_MENU, self.OnAddConfigurationMenu, id=new_id) Edouard@1408: Laurent@814: elif name == "Transitions": Laurent@814: menu = wx.Menu(title='') Laurent@814: new_id = wx.NewId() Laurent@814: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Transition")) Laurent@1010: parent = self.ProjectTree.GetItemParent(item) Laurent@1010: parent_type = self.ProjectTree.GetPyData(parent)["type"] Laurent@814: while parent_type != ITEM_POU: Laurent@814: parent = self.ProjectTree.GetItemParent(parent) Laurent@814: parent_type = self.ProjectTree.GetPyData(parent)["type"] Laurent@814: self.Bind(wx.EVT_MENU, self.GenerateAddTransitionFunction(self.ProjectTree.GetItemText(parent)), id=new_id) Edouard@1408: Laurent@814: elif name == "Actions": Laurent@814: menu = wx.Menu(title='') Laurent@814: new_id = wx.NewId() Laurent@814: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Action")) Laurent@814: parent = self.ProjectTree.GetItemParent(item) Laurent@814: parent_type = self.ProjectTree.GetPyData(parent)["type"] Laurent@814: while parent_type != ITEM_POU: Laurent@814: parent = self.ProjectTree.GetItemParent(parent) Laurent@814: parent_type = self.ProjectTree.GetPyData(parent)["type"] Laurent@814: self.Bind(wx.EVT_MENU, self.GenerateAddActionFunction(self.ProjectTree.GetItemText(parent)), id=new_id) Edouard@1408: Laurent@814: elif name == "Resources": Laurent@814: menu = wx.Menu(title='') Laurent@814: new_id = wx.NewId() Laurent@814: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Resource")) Laurent@814: parent = self.ProjectTree.GetItemParent(item) Laurent@814: parent_type = self.ProjectTree.GetPyData(parent)["type"] Laurent@814: while parent_type not in [ITEM_CONFIGURATION, ITEM_PROJECT]: Laurent@814: parent = self.ProjectTree.GetItemParent(parent) Laurent@814: parent_type = self.ProjectTree.GetPyData(parent)["type"] Laurent@1024: parent_name = None Laurent@814: if parent_type == ITEM_PROJECT: Laurent@1024: config_names = self.Controler.GetProjectConfigNames() Laurent@1024: if len(config_names) > 0: Laurent@1024: parent_name = config_names[0] Laurent@814: else: Laurent@814: parent_name = self.ProjectTree.GetItemText(parent) Laurent@1024: if parent_name is not None: Laurent@1024: self.Bind(wx.EVT_MENU, self.GenerateAddResourceFunction(parent_name), id=new_id) Edouard@1408: Laurent@814: else: Laurent@814: if item_infos["type"] == ITEM_POU: Laurent@814: menu = wx.Menu(title='') Laurent@814: if self.Controler.GetPouBodyType(name) == "SFC": Laurent@814: new_id = wx.NewId() Laurent@814: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Transition")) Laurent@814: self.Bind(wx.EVT_MENU, self.GenerateAddTransitionFunction(name), id=new_id) Laurent@814: new_id = wx.NewId() Laurent@814: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Action")) Laurent@814: self.Bind(wx.EVT_MENU, self.GenerateAddActionFunction(name), id=new_id) Laurent@814: menu.AppendSeparator() Edouard@1408: Laurent@814: new_id = wx.NewId() Laurent@814: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Copy POU")) Laurent@814: self.Bind(wx.EVT_MENU, self.OnCopyPou, id=new_id) Edouard@1408: Laurent@814: pou_type = self.Controler.GetPouType(name) Laurent@814: if pou_type in ["function", "functionBlock"]: Laurent@814: change_menu = wx.Menu(title='') Laurent@814: if pou_type == "function": Laurent@814: new_id = wx.NewId() Laurent@814: AppendMenu(change_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Function Block")) Laurent@814: self.Bind(wx.EVT_MENU, self.GenerateChangePouTypeFunction(name, "functionBlock"), id=new_id) Laurent@814: new_id = wx.NewId() Laurent@814: AppendMenu(change_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Program")) Laurent@814: self.Bind(wx.EVT_MENU, self.GenerateChangePouTypeFunction(name, "program"), id=new_id) Laurent@814: menu.AppendMenu(wx.NewId(), _("Change POU Type To"), change_menu) Laurent@814: new_id = wx.NewId() Laurent@814: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Rename")) Laurent@814: self.Bind(wx.EVT_MENU, self.OnRenamePouMenu, id=new_id) Edouard@1408: Laurent@814: elif item_infos["type"] == ITEM_CONFIGURATION: Laurent@814: menu = wx.Menu(title='') Laurent@814: new_id = wx.NewId() Laurent@814: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Resource")) Laurent@814: self.Bind(wx.EVT_MENU, self.GenerateAddResourceFunction(name), id=new_id) Edouard@1408: Laurent@814: elif item_infos["type"] in [ITEM_DATATYPE, ITEM_TRANSITION, ITEM_ACTION, ITEM_RESOURCE]: Laurent@814: menu = wx.Menu(title='') Edouard@1408: Laurent@814: if menu is not None: Laurent@814: new_id = wx.NewId() Laurent@814: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Delete")) Laurent@814: self.Bind(wx.EVT_MENU, self.OnDeleteMenu, id=new_id) Edouard@1408: Laurent@814: if menu is not None: andrej@1480: self.FindFocus().PopupMenu(menu) Laurent@814: menu.Destroy() Edouard@1408: Laurent@1240: self.ResetSelectedItem() Edouard@1408: Laurent@814: event.Skip() Laurent@814: Laurent@814: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # Instances Tree Management Functions Laurent@814: #------------------------------------------------------------------------------- Laurent@814: Laurent@814: def GetTreeImage(self, var_class): Laurent@814: return self.TreeImageDict[var_class] Edouard@1408: Laurent@814: def RefreshPouInstanceVariablesPanel(self): Laurent@814: self.PouInstanceVariablesPanel.RefreshView() Laurent@814: Laurent@814: def OpenDebugViewer(self, instance_category, instance_path, instance_type): Laurent@814: openedidx = self.IsOpened(instance_path) Laurent@930: new_window = None Laurent@814: if openedidx is not None: Laurent@814: old_selected = self.TabsOpened.GetSelection() Laurent@814: if old_selected != openedidx: Laurent@814: if old_selected >= 0: Laurent@814: self.TabsOpened.GetPage(old_selected).ResetBuffer() Laurent@814: self.TabsOpened.SetSelection(openedidx) Edouard@1408: Laurent@814: elif instance_category in ITEMS_VARIABLE: Laurent@887: if self.Controler.IsNumType(instance_type, True): Laurent@1364: self.AddDebugVariable(instance_path, True) Edouard@1408: Laurent@814: else: Laurent@814: bodytype = self.Controler.GetEditedElementBodyType(instance_type, True) Laurent@814: if bodytype == "FBD": Laurent@814: new_window = Viewer(self.TabsOpened, instance_type, self, self.Controler, True, instance_path) Laurent@814: new_window.RefreshScaling(False) Laurent@814: elif bodytype == "LD": Laurent@814: new_window = LD_Viewer(self.TabsOpened, instance_type, self, self.Controler, True, instance_path) Laurent@814: new_window.RefreshScaling(False) Laurent@814: elif bodytype == "SFC": Laurent@814: new_window = SFC_Viewer(self.TabsOpened, instance_type, self, self.Controler, True, instance_path) Laurent@814: new_window.RefreshScaling(False) Laurent@814: else: Laurent@814: new_window = TextViewer(self.TabsOpened, instance_type, self, self.Controler, True, instance_path) Laurent@814: new_window.SetTextSyntax(bodytype) Laurent@814: if bodytype == "IL": Laurent@814: new_window.SetKeywords(IL_KEYWORDS) Laurent@814: else: Laurent@814: new_window.SetKeywords(ST_KEYWORDS) Edouard@1408: Laurent@814: if new_window is not None: Laurent@814: if instance_category in [ITEM_FUNCTIONBLOCK, ITEM_PROGRAM]: Laurent@814: pou_type = self.Controler.GetEditedElementType(instance_type, True)[1].upper() Laurent@814: icon = GetBitmap(pou_type, bodytype) Laurent@814: elif instance_category == ITEM_TRANSITION: Laurent@814: icon = GetBitmap("TRANSITION", bodytype) Laurent@814: elif instance_category == ITEM_ACTION: Laurent@814: icon = GetBitmap("ACTION", bodytype) Edouard@1408: Laurent@885: if new_window is not None: Laurent@885: new_window.SetIcon(icon) Laurent@885: self.AddPage(new_window, "") Laurent@885: new_window.RefreshView() Laurent@885: new_window.SetFocus() Laurent@885: self.RefreshPageTitles() Laurent@814: return new_window Laurent@814: Laurent@814: def ResetGraphicViewers(self): Laurent@887: if self.EnableDebug: Laurent@887: self.DebugVariablePanel.ResetGraphicsValues() Laurent@814: Laurent@814: def CloseObsoleteDebugTabs(self): Laurent@814: if self.EnableDebug: Laurent@814: idxs = range(self.TabsOpened.GetPageCount()) Laurent@814: idxs.reverse() Laurent@814: for idx in idxs: Laurent@814: editor = self.TabsOpened.GetPage(idx) Laurent@1364: if isinstance(editor, Viewer) and editor.IsDebugging(): Laurent@814: instance_infos = self.Controler.GetInstanceInfos(editor.GetInstancePath(), self.EnableDebug) Laurent@814: if instance_infos is None: Laurent@814: self.TabsOpened.DeletePage(idx) Laurent@814: else: Laurent@1176: editor.SubscribeAllDataConsumers() Laurent@897: elif editor.IsDebugging(): Laurent@1176: editor.SubscribeAllDataConsumers() Laurent@1207: self.DebugVariablePanel.SubscribeAllDataConsumers() Edouard@1408: Laurent@1214: def AddDebugVariable(self, iec_path, force=False, graph=False): Laurent@814: if self.EnableDebug: Laurent@1214: self.DebugVariablePanel.InsertValue(iec_path, force=force, graph=graph) Laurent@814: self.EnsureTabVisible(self.DebugVariablePanel) Edouard@1408: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # Library Panel Management Function Laurent@814: #------------------------------------------------------------------------------- Laurent@814: Laurent@814: def RefreshLibraryPanel(self): Laurent@814: self.LibraryPanel.RefreshTree() Edouard@1408: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # ToolBars Management Functions Laurent@814: #------------------------------------------------------------------------------- Laurent@814: Laurent@814: def AddToMenuToolBar(self, items): Laurent@814: MenuToolBar = self.Panes["MenuToolBar"] Laurent@814: if MenuToolBar.GetToolsCount() > 0: Laurent@814: MenuToolBar.AddSeparator() Laurent@814: for toolbar_item in items: Laurent@814: if toolbar_item is None: Laurent@814: MenuToolBar.AddSeparator() Laurent@814: else: Laurent@814: id, bitmap, help, callback = toolbar_item Laurent@814: MenuToolBar.AddSimpleTool(id=id, shortHelpString=help, bitmap=GetBitmap(bitmap)) Laurent@814: if callback is not None: Laurent@814: self.Bind(wx.EVT_TOOL, callback, id=id) Laurent@814: MenuToolBar.Realize() Laurent@814: self.AUIManager.GetPane("MenuToolBar").BestSize(MenuToolBar.GetBestSize()) Laurent@814: Laurent@814: def ResetEditorToolBar(self): Laurent@814: EditorToolBar = self.Panes["EditorToolBar"] Edouard@1408: Laurent@814: for item in self.CurrentEditorToolBar: Laurent@814: if wx.VERSION >= (2, 6, 0): Laurent@814: self.Unbind(wx.EVT_MENU, id=item) Laurent@814: else: Edouard@1408: self.Disconnect(id=item, eventType=wx.wxEVT_COMMAND_MENU_SELECTED) Edouard@1408: Laurent@814: if EditorToolBar: Laurent@814: EditorToolBar.DeleteTool(item) Edouard@1408: Laurent@814: if EditorToolBar: Laurent@814: EditorToolBar.Realize() Laurent@814: self.AUIManager.GetPane("EditorToolBar").BestSize(EditorToolBar.GetBestSize()) Laurent@814: self.AUIManager.GetPane("EditorToolBar").Hide() Laurent@814: self.AUIManager.Update() Laurent@814: Laurent@814: def RefreshEditorToolBar(self): Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: menu = None Laurent@814: if selected != -1: Laurent@814: window = self.TabsOpened.GetPage(selected) Laurent@1364: if isinstance(window, (Viewer, TextViewer)): Laurent@814: if not window.IsDebugging(): Laurent@814: menu = self.Controler.GetEditedElementBodyType(window.GetTagName()) Laurent@814: else: Laurent@814: menu = "debug" Laurent@814: if menu is not None and menu != self.CurrentMenu: Laurent@814: self.ResetEditorToolBar() Laurent@814: self.CurrentMenu = menu Laurent@814: self.CurrentEditorToolBar = [] Laurent@814: EditorToolBar = self.Panes["EditorToolBar"] Laurent@814: if EditorToolBar: Laurent@814: for radio, modes, id, method, picture, help in EditorToolBarItems[menu]: Laurent@814: if modes & self.DrawingMode: Laurent@814: if radio or self.DrawingMode == FREEDRAWING_MODE: Laurent@814: EditorToolBar.AddRadioTool(id, GetBitmap(picture), wx.NullBitmap, help) Laurent@814: else: Laurent@814: EditorToolBar.AddSimpleTool(id, GetBitmap(picture), help) Laurent@814: self.Bind(wx.EVT_MENU, getattr(self, method), id=id) Laurent@814: self.CurrentEditorToolBar.append(id) Laurent@814: EditorToolBar.Realize() Laurent@814: self.AUIManager.GetPane("EditorToolBar").BestSize(EditorToolBar.GetBestSize()) Laurent@814: self.AUIManager.GetPane("EditorToolBar").Show() Laurent@814: self.AUIManager.Update() Laurent@814: elif menu is None: Laurent@814: self.ResetEditorToolBar() Laurent@814: self.CurrentMenu = menu Laurent@814: self.ResetCurrentMode() Laurent@814: Laurent@814: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # EditorToolBar Items Functions Laurent@814: #------------------------------------------------------------------------------- Laurent@814: Laurent@814: def ResetCurrentMode(self): Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected != -1: Laurent@814: window = self.TabsOpened.GetPage(selected) Laurent@814: window.SetMode(MODE_SELECTION) Laurent@814: EditorToolBar = self.Panes["EditorToolBar"] Laurent@814: if EditorToolBar: Laurent@814: EditorToolBar.ToggleTool(ID_PLCOPENEDITOREDITORTOOLBARSELECTION, False) Laurent@814: EditorToolBar.ToggleTool(ID_PLCOPENEDITOREDITORTOOLBARSELECTION, True) Edouard@1408: Laurent@814: def ResetToolToggle(self, id): Laurent@814: tool = self.Panes["EditorToolBar"].FindById(id) Laurent@814: tool.SetToggle(False) Laurent@814: Laurent@814: def OnSelectionTool(self, event): Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected != -1: Laurent@814: self.TabsOpened.GetPage(selected).SetMode(MODE_SELECTION) Edouard@1408: Laurent@814: def OnMotionTool(self, event): Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected != -1: Laurent@814: self.TabsOpened.GetPage(selected).SetMode(MODE_MOTION) Edouard@1408: Laurent@814: def OnCommentTool(self, event): Laurent@814: self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARCOMMENT) Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected != -1: Laurent@814: self.TabsOpened.GetPage(selected).SetMode(MODE_COMMENT) Edouard@1408: Laurent@814: def OnVariableTool(self, event): Laurent@814: self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARVARIABLE) Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected != -1: Laurent@814: self.TabsOpened.GetPage(selected).SetMode(MODE_VARIABLE) Edouard@1408: Laurent@814: def OnBlockTool(self, event): Laurent@814: self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARBLOCK) Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected != -1: Laurent@814: self.TabsOpened.GetPage(selected).SetMode(MODE_BLOCK) Edouard@1408: Laurent@814: def OnConnectionTool(self, event): Laurent@814: self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARCONNECTION) Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected != -1: Laurent@814: self.TabsOpened.GetPage(selected).SetMode(MODE_CONNECTION) Edouard@1408: Laurent@814: def OnPowerRailTool(self, event): Laurent@814: self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARPOWERRAIL) Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected != -1: Laurent@814: self.TabsOpened.GetPage(selected).SetMode(MODE_POWERRAIL) Edouard@1408: Laurent@814: def OnRungTool(self, event): Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected != -1: Laurent@814: self.TabsOpened.GetPage(selected).AddLadderRung() Laurent@814: event.Skip() Edouard@1408: Laurent@814: def OnCoilTool(self, event): Laurent@814: self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARCOIL) Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected != -1: Laurent@814: self.TabsOpened.GetPage(selected).SetMode(MODE_COIL) Laurent@814: event.Skip() Edouard@1408: Laurent@814: def OnContactTool(self, event): Laurent@814: if self.DrawingMode == FREEDRAWING_MODE: Laurent@814: self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARCONTACT) Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected != -1: Laurent@814: if self.DrawingMode == FREEDRAWING_MODE: Laurent@814: self.TabsOpened.GetPage(selected).SetMode(MODE_CONTACT) Laurent@814: else: Laurent@814: self.TabsOpened.GetPage(selected).AddLadderContact() Edouard@1408: Edouard@1408: def OnBranchTool(self, event): Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected != -1: Laurent@814: self.TabsOpened.GetPage(selected).AddLadderBranch() Edouard@1408: Laurent@814: def OnInitialStepTool(self, event): Laurent@814: self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARINITIALSTEP) Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected != -1: Laurent@814: self.TabsOpened.GetPage(selected).SetMode(MODE_INITIALSTEP) Edouard@1408: Laurent@814: def OnStepTool(self, event): Laurent@814: if self.GetDrawingMode() == FREEDRAWING_MODE: Laurent@814: self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARSTEP) Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected != -1: Laurent@814: if self.GetDrawingMode() == FREEDRAWING_MODE: Laurent@814: self.TabsOpened.GetPage(selected).SetMode(MODE_STEP) Laurent@814: else: Laurent@814: self.TabsOpened.GetPage(selected).AddStep() Edouard@1408: Laurent@814: def OnActionBlockTool(self, event): Laurent@814: if self.GetDrawingMode() == FREEDRAWING_MODE: Laurent@814: self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARACTIONBLOCK) Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected != -1: Laurent@814: if self.GetDrawingMode() == FREEDRAWING_MODE: Laurent@814: self.TabsOpened.GetPage(selected).SetMode(MODE_ACTION) Laurent@814: else: Laurent@814: self.TabsOpened.GetPage(selected).AddStepAction() Edouard@1408: Laurent@814: def OnTransitionTool(self, event): Laurent@814: self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARTRANSITION) Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected != -1: Laurent@814: self.TabsOpened.GetPage(selected).SetMode(MODE_TRANSITION) Edouard@1408: Laurent@814: def OnDivergenceTool(self, event): Laurent@814: if self.GetDrawingMode() == FREEDRAWING_MODE: Laurent@814: self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARDIVERGENCE) Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected != -1: Laurent@814: if self.GetDrawingMode() == FREEDRAWING_MODE: Laurent@814: self.TabsOpened.GetPage(selected).SetMode(MODE_DIVERGENCE) Laurent@814: else: Laurent@814: self.TabsOpened.GetPage(selected).AddDivergence() Edouard@1408: Laurent@814: def OnJumpTool(self, event): Laurent@814: if self.GetDrawingMode() == FREEDRAWING_MODE: Laurent@814: self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARJUMP) Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected != -1: Laurent@814: if self.GetDrawingMode() == FREEDRAWING_MODE: Laurent@814: self.TabsOpened.GetPage(selected).SetMode(MODE_JUMP) Laurent@814: else: Laurent@814: self.TabsOpened.GetPage(selected).AddJump() Edouard@1408: Laurent@814: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # Add Project Elements Functions Laurent@814: #------------------------------------------------------------------------------- Laurent@814: Laurent@814: def OnAddDataTypeMenu(self, event): Laurent@814: tagname = self.Controler.ProjectAddDataType() Laurent@814: if tagname is not None: Laurent@814: self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE) Laurent@814: self.EditProjectElement(ITEM_DATATYPE, tagname) Edouard@1408: Laurent@814: def GenerateAddPouFunction(self, pou_type): Laurent@814: def OnAddPouMenu(event): Laurent@814: dialog = PouDialog(self, pou_type) Laurent@814: dialog.SetPouNames(self.Controler.GetProjectPouNames()) Laurent@1171: dialog.SetPouElementNames(self.Controler.GetProjectPouVariableNames()) Laurent@814: dialog.SetValues({"pouName": self.Controler.GenerateNewName(None, None, "%s%%d" % pou_type)}) Laurent@814: if dialog.ShowModal() == wx.ID_OK: Laurent@814: values = dialog.GetValues() Laurent@814: tagname = self.Controler.ProjectAddPou(values["pouName"], values["pouType"], values["language"]) Laurent@814: if tagname is not None: Laurent@814: self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, LIBRARYTREE) Laurent@814: self.EditProjectElement(ITEM_POU, tagname) Laurent@814: dialog.Destroy() Laurent@814: return OnAddPouMenu Laurent@814: Laurent@814: def GenerateAddTransitionFunction(self, pou_name): Laurent@814: def OnAddTransitionMenu(event): Laurent@814: dialog = PouTransitionDialog(self) Laurent@814: dialog.SetPouNames(self.Controler.GetProjectPouNames()) Laurent@1171: dialog.SetPouElementNames(self.Controler.GetProjectPouVariableNames(pou_name)) Laurent@814: dialog.SetValues({"transitionName": self.Controler.GenerateNewName(None, None, "transition%d")}) Edouard@1408: if dialog.ShowModal() == wx.ID_OK: Laurent@814: values = dialog.GetValues() Laurent@814: tagname = self.Controler.ProjectAddPouTransition(pou_name, values["transitionName"], values["language"]) Laurent@814: if tagname is not None: Laurent@814: self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE) Laurent@814: self.EditProjectElement(ITEM_TRANSITION, tagname) Laurent@814: dialog.Destroy() Laurent@814: return OnAddTransitionMenu Laurent@814: Laurent@814: def GenerateAddActionFunction(self, pou_name): Laurent@814: def OnAddActionMenu(event): Laurent@814: dialog = PouActionDialog(self) Laurent@814: dialog.SetPouNames(self.Controler.GetProjectPouNames()) Laurent@1171: dialog.SetPouElementNames(self.Controler.GetProjectPouVariableNames(pou_name)) Laurent@814: dialog.SetValues({"actionName": self.Controler.GenerateNewName(None, None, "action%d")}) Laurent@814: if dialog.ShowModal() == wx.ID_OK: Laurent@814: values = dialog.GetValues() Laurent@814: tagname = self.Controler.ProjectAddPouAction(pou_name, values["actionName"], values["language"]) Laurent@814: if tagname is not None: Laurent@814: self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE) Laurent@814: self.EditProjectElement(ITEM_ACTION, tagname) Laurent@814: dialog.Destroy() Laurent@814: return OnAddActionMenu Laurent@814: Laurent@814: def OnAddConfigurationMenu(self, event): Laurent@814: tagname = self.Controler.ProjectAddConfiguration() Laurent@814: if tagname is not None: Laurent@814: self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL) Laurent@814: self.EditProjectElement(ITEM_CONFIGURATION, tagname) Laurent@814: Edouard@1408: def AddResourceMenu(self, event): Edouard@1408: config_names = self.Controler.GetProjectConfigNames() Edouard@1408: if len(config_names) > 0: Edouard@1408: tagname = self.Controler.ProjectAddConfigurationResource(config_names[0]) Edouard@1408: if tagname is not None: Edouard@1408: self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL) Edouard@1408: self.EditProjectElement(ITEM_RESOURCE, tagname) Edouard@1408: Laurent@814: def GenerateAddResourceFunction(self, config_name): Laurent@814: def OnAddResourceMenu(event): Laurent@814: tagname = self.Controler.ProjectAddConfigurationResource(config_name) Laurent@814: if tagname is not None: Laurent@814: self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL) Laurent@814: self.EditProjectElement(ITEM_RESOURCE, tagname) Laurent@814: return OnAddResourceMenu Laurent@814: Laurent@814: def GenerateChangePouTypeFunction(self, name, new_type): Laurent@814: def OnChangePouTypeMenu(event): Laurent@814: selected = self.ProjectTree.GetSelection() Edouard@1408: if self.ProjectTree.GetPyData(selected)["type"] == ITEM_POU: Laurent@814: self.Controler.ProjectChangePouType(name, new_type) Laurent@814: self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, PROJECTTREE, LIBRARYTREE) Laurent@814: return OnChangePouTypeMenu Laurent@814: Laurent@814: def OnCopyPou(self, event): Laurent@814: selected = self.ProjectTree.GetSelection() Laurent@814: pou_name = self.ProjectTree.GetItemText(selected) Edouard@1408: Laurent@814: pou_xml = self.Controler.GetPouXml(pou_name) Laurent@814: if pou_xml is not None: Laurent@814: self.SetCopyBuffer(pou_xml) Laurent@814: self._Refresh(EDITMENU) Laurent@814: Laurent@814: def OnPastePou(self, event): Laurent@814: selected = self.ProjectTree.GetSelection() Edouard@1408: Edouard@1408: if self.ProjectTree.GetPyData(selected)["type"] != ITEM_PROJECT: Laurent@814: pou_type = self.ProjectTree.GetItemText(selected) Laurent@814: pou_type = UNEDITABLE_NAMES_DICT[pou_type] # one of 'Functions', 'Function Blocks' or 'Programs' Laurent@814: pou_type = {'Functions': 'function', 'Function Blocks': 'functionBlock', 'Programs': 'program'}[pou_type] Laurent@814: else: Laurent@814: pou_type = None Edouard@1408: Laurent@814: pou_xml = self.GetCopyBuffer() Laurent@814: Laurent@814: result = self.Controler.PastePou(pou_type, pou_xml) Laurent@814: Laurent@814: if not isinstance(result, TupleType): Laurent@1129: self.ShowErrorMessage(result) Laurent@814: else: Laurent@814: self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, PROJECTTREE, LIBRARYTREE) Laurent@814: self.EditProjectElement(ITEM_POU, result[0]) Laurent@814: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # Remove Project Elements Functions Laurent@814: #------------------------------------------------------------------------------- Laurent@814: Laurent@1129: def CheckElementIsUsedBeforeDeletion(self, check_function, title, name): Laurent@1129: if not check_function(name): Laurent@1129: return True Edouard@1408: Edouard@1408: dialog = wx.MessageDialog(self, Edouard@1408: _("\"%s\" is used by one or more POUs. Do you wish to continue?") % name, Laurent@1129: title, wx.YES_NO|wx.ICON_QUESTION) Laurent@1129: answer = dialog.ShowModal() Laurent@1129: dialog.Destroy() Laurent@1129: return answer == wx.ID_YES Laurent@1129: Laurent@1129: def CheckDataTypeIsUsedBeforeDeletion(self, name): Laurent@1129: return self.CheckElementIsUsedBeforeDeletion( Laurent@1129: self.Controler.DataTypeIsUsed, Laurent@1129: _("Remove Datatype"), name) Edouard@1408: Laurent@1129: def CheckPouIsUsedBeforeDeletion(self, name): Laurent@1129: return self.CheckElementIsUsedBeforeDeletion( Laurent@1129: self.Controler.PouIsUsed, Laurent@1129: _("Remove Pou"), name) Edouard@1408: Laurent@814: def OnRemoveDataTypeMenu(self, event): Laurent@814: selected = self.ProjectTree.GetSelection() Laurent@814: if self.ProjectTree.GetPyData(selected)["type"] == ITEM_DATATYPE: Laurent@814: name = self.ProjectTree.GetItemText(selected) Laurent@1129: if self.CheckDataTypeIsUsedBeforeDeletion(name): Laurent@814: self.Controler.ProjectRemoveDataType(name) Laurent@814: tagname = self.Controler.ComputeDataTypeName(name) Laurent@814: idx = self.IsOpened(tagname) Laurent@814: if idx is not None: Laurent@814: self.TabsOpened.DeletePage(idx) Laurent@814: self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, PROJECTTREE) Edouard@1408: Laurent@814: def OnRenamePouMenu(self, event): Laurent@814: selected = self.ProjectTree.GetSelection() Edouard@1408: if self.ProjectTree.GetPyData(selected)["type"] == ITEM_POU: Laurent@814: wx.CallAfter(self.ProjectTree.EditLabel, selected) Laurent@814: Laurent@814: def OnRemovePouMenu(self, event): Laurent@814: selected = self.ProjectTree.GetSelection() Laurent@814: if self.ProjectTree.GetPyData(selected)["type"] == ITEM_POU: Laurent@814: name = self.ProjectTree.GetItemText(selected) Laurent@1129: if self.CheckPouIsUsedBeforeDeletion(name): Laurent@814: self.Controler.ProjectRemovePou(name) Laurent@814: tagname = self.Controler.ComputePouName(name) Laurent@814: idx = self.IsOpened(tagname) Laurent@814: if idx is not None: Laurent@814: self.TabsOpened.DeletePage(idx) Laurent@814: self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE) Laurent@814: Laurent@814: def OnRemoveTransitionMenu(self, event): Laurent@814: selected = self.ProjectTree.GetSelection() Laurent@814: item_infos = self.ProjectTree.GetPyData(selected) Edouard@1408: if item_infos["type"] == ITEM_TRANSITION: Laurent@814: transition = self.ProjectTree.GetItemText(selected) Laurent@814: pou_name = item_infos["tagname"].split("::")[1] Laurent@814: self.Controler.ProjectRemovePouTransition(pou_name, transition) Laurent@814: tagname = self.Controler.ComputePouTransitionName(pou_name, transition) Laurent@814: idx = self.IsOpened(tagname) Laurent@814: if idx is not None: Laurent@814: self.TabsOpened.DeletePage(idx) Laurent@814: self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE) Laurent@814: Laurent@814: def OnRemoveActionMenu(self, event): Laurent@814: selected = self.ProjectTree.GetSelection() Laurent@814: item_infos = self.ProjectTree.GetPyData(selected) Edouard@1408: if item_infos["type"] == ITEM_ACTION: Laurent@814: action = self.ProjectTree.GetItemText(selected) Laurent@814: pou_name = item_infos["tagname"].split("::")[1] Laurent@814: self.Controler.ProjectRemovePouAction(pou_name, action) Laurent@814: tagname = self.Controler.ComputePouActionName(pou_name, action) Laurent@814: idx = self.IsOpened(tagname) Laurent@814: if idx is not None: Laurent@814: self.TabsOpened.DeletePage(idx) Laurent@814: self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE) Laurent@814: Laurent@814: def OnRemoveConfigurationMenu(self, event): Laurent@814: selected = self.ProjectTree.GetSelection() Edouard@1408: if self.ProjectTree.GetPyData(selected)["type"] == ITEM_CONFIGURATION: Laurent@814: name = self.ProjectTree.GetItemText(selected) Laurent@814: self.Controler.ProjectRemoveConfiguration(name) Laurent@814: tagname = self.Controler.ComputeConfigurationName(name) Laurent@814: idx = self.IsOpened(tagname) Laurent@814: if idx is not None: Laurent@814: self.TabsOpened.DeletePage(idx) Laurent@814: self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL) Laurent@814: Laurent@814: def OnRemoveResourceMenu(self, event): Laurent@814: selected = self.ProjectTree.GetSelection() Laurent@814: item_infos = self.ProjectTree.GetPyData(selected) Laurent@814: if item_infos["type"] == ITEM_RESOURCE: Laurent@814: resource = self.ProjectTree.GetItemText(selected) Laurent@814: config_name = item_infos["tagname"].split("::")[1] Laurent@814: self.Controler.ProjectRemoveConfigurationResource(config_name, resource) Laurent@814: tagname = self.Controler.ComputeConfigurationResourceName(config_name, selected) Laurent@814: idx = self.IsOpened(tagname) Laurent@814: if idx is not None: Laurent@814: self.TabsOpened.DeletePage(idx) Laurent@814: self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL) Laurent@814: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # Highlights showing functions Laurent@814: #------------------------------------------------------------------------------- Laurent@814: Laurent@814: def ShowHighlight(self, infos, start, end, highlight_type): Laurent@814: self.SelectProjectTreeItem(infos[0]) Laurent@814: if infos[1] == "name": Laurent@814: self.Highlights[infos[0]] = highlight_type Laurent@814: self.RefreshProjectTree() Laurent@814: self.ProjectTree.Unselect() Laurent@814: else: Laurent@814: self.EditProjectElement(self.Controler.GetElementType(infos[0]), infos[0]) Laurent@814: selected = self.TabsOpened.GetSelection() Laurent@814: if selected != -1: Laurent@814: viewer = self.TabsOpened.GetPage(selected) Laurent@814: viewer.AddHighlight(infos[1:], start, end, highlight_type) Laurent@814: Laurent@814: def ShowError(self, infos, start, end): Laurent@814: self.ShowHighlight(infos, start, end, ERROR_HIGHLIGHT) Laurent@814: Laurent@814: def ShowSearchResult(self, infos, start, end): Laurent@814: self.ShowHighlight(infos, start, end, SEARCH_RESULT_HIGHLIGHT) Laurent@814: Laurent@814: def ClearHighlights(self, highlight_type=None): Laurent@814: if highlight_type is None: Laurent@814: self.Highlights = {} Laurent@814: else: Laurent@814: self.Highlights = dict([(name, highlight) for name, highlight in self.Highlights.iteritems() if highlight != highlight_type]) Laurent@814: self.RefreshProjectTree() Laurent@814: for i in xrange(self.TabsOpened.GetPageCount()): Laurent@814: viewer = self.TabsOpened.GetPage(i) Laurent@814: viewer.ClearHighlights(highlight_type) Laurent@814: Laurent@814: def ClearErrors(self): Laurent@814: self.ClearHighlights(ERROR_HIGHLIGHT) Laurent@814: Laurent@814: def ClearSearchResults(self): Laurent@814: self.ClearHighlights(SEARCH_RESULT_HIGHLIGHT) laurent@838: laurent@838: #------------------------------------------------------------------------------- laurent@838: # Viewer Printout laurent@838: #------------------------------------------------------------------------------- laurent@838: laurent@838: UPPER_DIV = lambda x, y: (x / y) + {True : 0, False : 1}[(x % y) == 0] laurent@838: laurent@838: class GraphicPrintout(wx.Printout): laurent@838: def __init__(self, viewer, page_size, margins, preview = False): laurent@838: wx.Printout.__init__(self) laurent@838: self.Viewer = viewer laurent@838: self.PageSize = page_size laurent@838: if self.PageSize[0] == 0 or self.PageSize[1] == 0: laurent@838: self.PageSize = (1050, 1485) laurent@838: self.Preview = preview laurent@838: self.Margins = margins laurent@838: self.FontSize = 5 laurent@838: self.TextMargin = 3 Edouard@1408: laurent@838: maxx, maxy = viewer.GetMaxSize() Edouard@1408: self.PageGrid = (UPPER_DIV(maxx, self.PageSize[0]), laurent@838: UPPER_DIV(maxy, self.PageSize[1])) Edouard@1408: laurent@838: def GetPageNumber(self): laurent@838: return self.PageGrid[0] * self.PageGrid[1] Edouard@1408: laurent@838: def HasPage(self, page): laurent@838: return page <= self.GetPageNumber() Edouard@1408: laurent@838: def GetPageInfo(self): laurent@838: page_number = self.GetPageNumber() laurent@838: return (1, page_number, 1, page_number) laurent@838: laurent@838: def OnBeginDocument(self, startPage, endPage): laurent@838: dc = self.GetDC() laurent@838: if not self.Preview and isinstance(dc, wx.PostScriptDC): laurent@838: dc.SetResolution(720) laurent@838: super(GraphicPrintout, self).OnBeginDocument(startPage, endPage) laurent@838: laurent@838: def OnPrintPage(self, page): laurent@838: dc = self.GetDC() laurent@838: dc.SetUserScale(1.0, 1.0) laurent@838: dc.SetDeviceOrigin(0, 0) laurent@838: dc.printing = not self.Preview Edouard@1408: laurent@838: # Get the size of the DC in pixels laurent@838: ppiPrinterX, ppiPrinterY = self.GetPPIPrinter() laurent@838: ppiScreenX, ppiScreenY = self.GetPPIScreen() laurent@838: pw, ph = self.GetPageSizePixels() laurent@838: dw, dh = dc.GetSizeTuple() laurent@838: Xscale = (float(dw) * float(ppiPrinterX)) / (float(pw) * 25.4) laurent@838: Yscale = (float(dh) * float(ppiPrinterY)) / (float(ph) * 25.4) Edouard@1408: laurent@838: fontsize = self.FontSize * Yscale laurent@838: text_margin = self.TextMargin * Yscale Edouard@1408: laurent@838: margin_left = self.Margins[0].x * Xscale laurent@838: margin_top = self.Margins[0].y * Yscale laurent@838: area_width = dw - self.Margins[1].x * Xscale - margin_left laurent@838: area_height = dh - self.Margins[1].y * Yscale - margin_top Edouard@1408: laurent@838: dc.SetPen(MiterPen(wx.BLACK)) Edouard@1408: dc.SetBrush(wx.TRANSPARENT_BRUSH) laurent@838: dc.DrawRectangle(margin_left, margin_top, area_width, area_height) Edouard@1408: laurent@838: dc.SetFont(wx.Font(fontsize, wx.DEFAULT, wx.NORMAL, wx.NORMAL)) laurent@838: dc.SetTextForeground(wx.BLACK) laurent@838: block_name = " - ".join(self.Viewer.GetTagName().split("::")[1:]) laurent@838: text_width, text_height = dc.GetTextExtent(block_name) laurent@838: dc.DrawText(block_name, margin_left, margin_top - text_height - self.TextMargin) laurent@838: dc.DrawText(_("Page: %d") % page, margin_left, margin_top + area_height + self.TextMargin) Edouard@1408: laurent@838: # Calculate the position on the DC for centering the graphic laurent@838: posX = area_width * ((page - 1) % self.PageGrid[0]) laurent@838: posY = area_height * ((page - 1) / self.PageGrid[0]) laurent@838: laurent@838: scaleX = float(area_width) / float(self.PageSize[0]) laurent@838: scaleY = float(area_height) / float(self.PageSize[1]) laurent@838: scale = min(scaleX, scaleY) laurent@838: laurent@838: # Set the scale and origin laurent@838: dc.SetDeviceOrigin(-posX + margin_left, -posY + margin_top) laurent@838: dc.SetClippingRegion(posX, posY, self.PageSize[0] * scale, self.PageSize[1] * scale) laurent@838: dc.SetUserScale(scale, scale) Edouard@1408: laurent@838: #------------------------------------------- Edouard@1408: laurent@838: self.Viewer.DoDrawing(dc, True) Edouard@1408: laurent@838: return True laurent@838: