etisserant@0: #!/usr/bin/env python etisserant@0: # -*- coding: utf-8 -*- etisserant@0: etisserant@0: #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor etisserant@0: #based on the plcopen standard. etisserant@0: # lbessard@58: #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD etisserant@0: # etisserant@0: #See COPYING file for copyrights details. etisserant@0: # etisserant@0: #This library is free software; you can redistribute it and/or etisserant@5: #modify it under the terms of the GNU General Public etisserant@0: #License as published by the Free Software Foundation; either etisserant@0: #version 2.1 of the License, or (at your option) any later version. etisserant@0: # etisserant@0: #This library is distributed in the hope that it will be useful, etisserant@0: #but WITHOUT ANY WARRANTY; without even the implied warranty of etisserant@0: #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU lbessard@58: #General Public License for more details. etisserant@0: # etisserant@5: #You should have received a copy of the GNU General Public etisserant@0: #License along with this library; if not, write to the Free Software etisserant@0: #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA etisserant@0: etisserant@0: from datetime import datetime lbessard@120: import wx, wx.grid Edouard@685: import wx.aui laurent@391: import os, re, platform, sys, time, traceback, getopt laurent@391: import cPickle laurent@391: laurent@391: CWD = os.path.split(os.path.realpath(__file__))[0] laurent@391: base_folder = os.path.split(CWD)[0] laurent@391: sys.path.append(base_folder) Laurent@714: Laurent@714: from utils.BitmapLibrary import AddBitmapFolder, GetBitmap Laurent@714: AddBitmapFolder(os.path.join(CWD, "Images")) Laurent@714: Edouard@682: from docutil import * laurent@391: laurent@391: from types import TupleType laurent@391: laurent@391: __version__ = "$Revision: 1.130 $" laurent@391: laurent@391: if __name__ == '__main__': laurent@391: # Usage message displayed when help request or when error detected in laurent@391: # command line laurent@391: def usage(): laurent@391: print "\nUsage of PLCOpenEditor.py :" laurent@391: print "\n %s [Filepath]\n"%sys.argv[0] laurent@391: laurent@391: # Parse options given to PLCOpenEditor in command line laurent@391: try: laurent@391: opts, args = getopt.getopt(sys.argv[1:], "h", ["help"]) laurent@391: except getopt.GetoptError: laurent@391: # print help information and exit: laurent@391: usage() laurent@391: sys.exit(2) laurent@391: laurent@391: # Extract if help has been requested laurent@391: for o, a in opts: laurent@391: if o in ("-h", "--help"): laurent@391: usage() laurent@391: sys.exit() laurent@391: laurent@391: # Extract the optional filename to open laurent@391: fileOpen = None laurent@391: if len(args) > 1: laurent@391: usage() laurent@391: sys.exit() laurent@391: elif len(args) == 1: laurent@391: fileOpen = args[0] laurent@391: laurent@391: # Create wxApp (Need to create App before internationalization because of laurent@391: # Windows) laurent@391: app = wx.PySimpleApp() laurent@391: laurent@391: # Import module for internationalization laurent@391: import gettext laurent@391: import __builtin__ laurent@391: laurent@391: # Get folder containing translation files laurent@391: localedir = os.path.join(CWD,"locale") laurent@391: # Get the default language laurent@537: langid = wx.LANGUAGE_DEFAULT laurent@391: # Define translation domain (name of translation files) laurent@391: domain = "PLCOpenEditor" laurent@391: laurent@391: # Define locale for wx laurent@391: loc = __builtin__.__dict__.get('loc', None) laurent@391: if loc is None: laurent@513: test_loc = wx.Locale(langid) laurent@513: test_loc.AddCatalogLookupPathPrefix(localedir) laurent@513: if test_loc.AddCatalog(domain): laurent@513: loc = wx.Locale(langid) laurent@513: else: laurent@513: loc = wx.Locale(wx.LANGUAGE_ENGLISH) laurent@391: __builtin__.__dict__['loc'] = loc laurent@391: # Define location for searching translation files laurent@391: loc.AddCatalogLookupPathPrefix(localedir) laurent@391: # Define locale domain laurent@391: loc.AddCatalog(domain) laurent@391: laurent@391: if __name__ == '__main__': laurent@391: __builtin__.__dict__['_'] = wx.GetTranslation laurent@391: etisserant@0: from SFCViewer import * etisserant@0: from LDViewer import * etisserant@0: from Viewer import * lbessard@27: from TextViewer import * lbessard@301: from GraphicViewer import * lbessard@27: from RessourceEditor import * lbessard@125: from DataTypeEditor import * etisserant@0: from PLCControler import * laurent@566: from SearchResultPanel import SearchResultPanel Laurent@711: from controls import CustomTree, LibraryPanel, PouInstanceVariablesPanel, DebugVariablePanel Laurent@738: from dialogs import ProjectDialog, PouTransitionDialog, PouActionDialog, FindInPouDialog etisserant@0: laurent@391: # Define PLCOpenEditor controls id laurent@407: [ID_PLCOPENEDITOR, ID_PLCOPENEDITORLEFTNOTEBOOK, laurent@407: ID_PLCOPENEDITORBOTTOMNOTEBOOK, ID_PLCOPENEDITORRIGHTNOTEBOOK, laurent@684: ID_PLCOPENEDITORPROJECTTREE, ID_PLCOPENEDITORMAINSPLITTER, laurent@684: ID_PLCOPENEDITORSECONDSPLITTER, ID_PLCOPENEDITORTHIRDSPLITTER, laurent@684: ID_PLCOPENEDITORLIBRARYPANEL, ID_PLCOPENEDITORLIBRARYSEARCHCTRL, laurent@684: ID_PLCOPENEDITORLIBRARYTREE, ID_PLCOPENEDITORLIBRARYCOMMENT, laurent@684: ID_PLCOPENEDITORTABSOPENED, ID_PLCOPENEDITORTABSOPENED, laurent@684: ID_PLCOPENEDITOREDITORMENUTOOLBAR, ID_PLCOPENEDITOREDITORTOOLBAR, laurent@684: ID_PLCOPENEDITORPROJECTPANEL, laurent@676: ] = [wx.NewId() for _init_ctrls in range(17)] lbessard@6: laurent@390: # Define PLCOpenEditor FileMenu extra items id lbessard@185: [ID_PLCOPENEDITORFILEMENUGENERATE, lbessard@185: ] = [wx.NewId() for _init_coll_FileMenu_Items in range(1)] lbessard@185: laurent@390: # Define PLCOpenEditor EditMenu extra items id greg@350: [ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, ID_PLCOPENEDITOREDITMENUADDDATATYPE, greg@350: ID_PLCOPENEDITOREDITMENUADDFUNCTION, ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK, laurent@566: ID_PLCOPENEDITOREDITMENUADDPROGRAM, ID_PLCOPENEDITOREDITMENUADDCONFIGURATION, Laurent@738: ID_PLCOPENEDITOREDITMENUFINDNEXT, ID_PLCOPENEDITOREDITMENUFINDPREVIOUS, laurent@566: ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT, Laurent@738: ] = [wx.NewId() for _init_coll_EditMenu_Items in range(9)] etisserant@0: laurent@673: # Define PLCOpenEditor DisplayMenu extra items id laurent@673: [ID_PLCOPENEDITORDISPLAYMENURESETPERSPECTIVE, laurent@673: ] = [wx.NewId() for _init_coll_DisplayMenu_Items in range(1)] lbessard@27: lbessard@27: #------------------------------------------------------------------------------- laurent@660: # EditorToolBar definitions lbessard@27: #------------------------------------------------------------------------------- lbessard@27: laurent@390: # Define PLCOpenEditor Toolbar items id laurent@660: [ID_PLCOPENEDITOREDITORTOOLBARSELECTION, ID_PLCOPENEDITOREDITORTOOLBARCOMMENT, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARVARIABLE, ID_PLCOPENEDITOREDITORTOOLBARBLOCK, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARCONNECTION, ID_PLCOPENEDITOREDITORTOOLBARWIRE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARPOWERRAIL, ID_PLCOPENEDITOREDITORTOOLBARRUNG, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARCOIL, ID_PLCOPENEDITOREDITORTOOLBARCONTACT, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARBRANCH, ID_PLCOPENEDITOREDITORTOOLBARINITIALSTEP, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARSTEP, ID_PLCOPENEDITOREDITORTOOLBARTRANSITION, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARACTIONBLOCK, ID_PLCOPENEDITOREDITORTOOLBARDIVERGENCE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARJUMP, ID_PLCOPENEDITOREDITORTOOLBARMOTION, laurent@660: ] = [wx.NewId() for _init_coll_DefaultEditorToolBar_Items in range(18)] lbessard@27: laurent@390: # Define behaviour of each Toolbar item according to current POU body type laurent@390: # Informations meaning are in this order: laurent@390: # - Item is toggled laurent@390: # - PLCOpenEditor mode where item is displayed (could be more then one) laurent@390: # - Item id laurent@390: # - Item callback function name laurent@390: # - Item icon filename laurent@390: # - Item tooltip text laurent@660: EditorToolBarItems = { etisserant@184: "FBD" : [(True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARMOTION, "OnMotionTool", Laurent@714: "move", _("Move the view")), laurent@575: (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARCOMMENT, "OnCommentTool", Laurent@714: "add_comment", _("Create a new comment")), etisserant@184: (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARVARIABLE, "OnVariableTool", Laurent@714: "add_variable", _("Create a new variable")), etisserant@184: (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARBLOCK, "OnBlockTool", Laurent@714: "add_block", _("Create a new block")), etisserant@184: (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARCONNECTION, "OnConnectionTool", Laurent@714: "add_connection", _("Create a new connection"))], laurent@577: "LD" : [(True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARMOTION, "OnMotionTool", Laurent@714: "move", _("Move the view")), laurent@577: (True, FREEDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARCOMMENT, "OnCommentTool", Laurent@714: "add_comment", _("Create a new comment")), etisserant@184: (True, FREEDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARPOWERRAIL, "OnPowerRailTool", Laurent@714: "add_powerrail", _("Create a new power rail")), etisserant@184: (False, DRIVENDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARRUNG, "OnRungTool", Laurent@714: "add_rung", _("Create a new rung")), etisserant@184: (True, FREEDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARCOIL, "OnCoilTool", Laurent@714: "add_coil", _("Create a new coil")), etisserant@184: (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARCONTACT, "OnContactTool", Laurent@714: "add_contact", _("Create a new contact")), etisserant@184: (False, DRIVENDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARBRANCH, "OnBranchTool", Laurent@714: "add_branch", _("Create a new branch")), etisserant@184: (True, FREEDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARVARIABLE, "OnVariableTool", Laurent@714: "add_variable", _("Create a new variable")), etisserant@184: (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARBLOCK, "OnBlockTool", Laurent@714: "add_block", _("Create a new block")), etisserant@184: (True, FREEDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARCONNECTION, "OnConnectionTool", Laurent@714: "add_connection", _("Create a new connection"))], laurent@575: "SFC" : [(True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARMOTION, "OnMotionTool", Laurent@714: "move", _("Move the view")), laurent@575: (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARCOMMENT, "OnCommentTool", Laurent@714: "add_comment", _("Create a new comment")), etisserant@184: (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARINITIALSTEP, "OnInitialStepTool", Laurent@714: "add_initial_step", _("Create a new initial step")), etisserant@184: (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARSTEP, "OnStepTool", Laurent@714: "add_step", _("Create a new step")), etisserant@184: (True, FREEDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARTRANSITION, "OnTransitionTool", Laurent@714: "add_transition", _("Create a new transition")), etisserant@184: (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARACTIONBLOCK, "OnActionBlockTool", Laurent@714: "add_action", _("Create a new action block")), etisserant@184: (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARDIVERGENCE, "OnDivergenceTool", Laurent@714: "add_divergence", _("Create a new divergence")), etisserant@184: (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARJUMP, "OnJumpTool", Laurent@714: "add_jump", _("Create a new jump")), etisserant@184: (True, FREEDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARVARIABLE, "OnVariableTool", Laurent@714: "add_variable", _("Create a new variable")), etisserant@184: (True, FREEDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARBLOCK, "OnBlockTool", Laurent@714: "add_block", _("Create a new block")), etisserant@184: (True, FREEDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARCONNECTION, "OnConnectionTool", Laurent@714: "add_connection", _("Create a new connection")), etisserant@184: (True, FREEDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARPOWERRAIL, "OnPowerRailTool", Laurent@714: "add_powerrail", _("Create a new power rail")), etisserant@184: (True, FREEDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARCONTACT, "OnContactTool", Laurent@714: "add_contact", _("Create a new contact"))], lbessard@82: "ST" : [], laurent@660: "IL" : [], laurent@660: "debug": [(True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, laurent@660: ID_PLCOPENEDITOREDITORTOOLBARMOTION, "OnMotionTool", Laurent@714: "move", _("Move the view"))], lbessard@27: } lbessard@27: laurent@390: #------------------------------------------------------------------------------- laurent@390: # Helper Functions laurent@390: #------------------------------------------------------------------------------- laurent@390: Laurent@727: import base64 Laurent@727: Laurent@727: def EncodeFileSystemPath(path, use_base64=True): Laurent@727: path = path.encode(sys.getfilesystemencoding()) Laurent@727: if use_base64: Laurent@727: return base64.encodestring(path) Laurent@727: return path Laurent@727: Laurent@727: def DecodeFileSystemPath(path, is_base64=True): Laurent@727: if is_base64: Laurent@727: path = base64.decodestring(path) Laurent@727: return unicode(path, sys.getfilesystemencoding()) Laurent@727: laurent@390: # Compatibility function for wx versions < 2.6 lbessard@114: def AppendMenu(parent, help, id, kind, text): lbessard@114: if wx.VERSION >= (2, 6, 0): lbessard@114: parent.Append(help=help, id=id, kind=kind, text=text) lbessard@114: else: lbessard@114: parent.Append(helpString=help, id=id, kind=kind, item=text) lbessard@114: laurent@684: [TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, PROJECTTREE, laurent@684: POUINSTANCEVARIABLESPANEL, LIBRARYTREE, SCALING, PAGETITLES laurent@586: ] = range(10) laurent@390: laurent@390: def GetShortcutKeyCallbackFunction(viewer_function): laurent@390: def ShortcutKeyFunction(self, event): laurent@390: control = self.FindFocus() laurent@599: if control is not None and control.GetName() in ["Viewer", "TextViewer"]: Laurent@699: getattr(control.ParentWindow, viewer_function)() laurent@587: elif isinstance(control, wx.stc.StyledTextCtrl): laurent@587: getattr(control, viewer_function)() laurent@390: elif isinstance(control, wx.TextCtrl): laurent@390: control.ProcessEvent(event) laurent@390: return ShortcutKeyFunction laurent@390: laurent@390: def GetDeleteElementFunction(remove_function, parent_type=None, check_function=None): laurent@390: def DeleteElementFunction(self, selected): laurent@684: name = self.ProjectTree.GetItemText(selected) laurent@407: if check_function is None or not check_function(self.Controler, name): laurent@390: if parent_type is not None: laurent@687: item_infos = self.ProjectTree.GetPyData(selected) laurent@687: parent_name = item_infos["tagname"].split("::")[1] laurent@390: remove_function(self.Controler, parent_name, name) laurent@390: else: laurent@390: remove_function(self.Controler, name) laurent@390: else: laurent@391: self.ShowErrorMessage(_("\"%s\" is used by one or more POUs. It can't be removed!")%name) laurent@390: return DeleteElementFunction laurent@390: laurent@680: if wx.Platform == '__WXMSW__': laurent@680: TAB_BORDER = 6 laurent@680: NOTEBOOK_BORDER = 6 laurent@680: else: laurent@680: TAB_BORDER = 7 laurent@680: NOTEBOOK_BORDER = 2 laurent@680: laurent@691: def SimplifyTabLayout(tabs, rect): laurent@676: for tab in tabs: laurent@676: if tab["pos"][0] == rect.x: laurent@676: others = [t for t in tabs if t != tab] laurent@676: others.sort(lambda x,y: cmp(x["pos"][0], y["pos"][0])) laurent@676: for other in others: laurent@676: if (other["pos"][1] == tab["pos"][1] and laurent@676: other["size"][1] == tab["size"][1] and laurent@680: other["pos"][0] == tab["pos"][0] + tab["size"][0] + TAB_BORDER): laurent@676: laurent@680: tab["size"] = (tab["size"][0] + other["size"][0] + TAB_BORDER, tab["size"][1]) laurent@676: tab["pages"].extend(other["pages"]) laurent@676: tabs.remove(other) laurent@676: laurent@676: if tab["size"][0] == rect.width: laurent@676: return True laurent@676: laurent@676: elif tab["pos"][1] == rect.y: laurent@676: others = [t for t in tabs if t != tab] laurent@676: others.sort(lambda x,y: cmp(x["pos"][1], y["pos"][1])) laurent@676: for other in others: laurent@676: if (other["pos"][0] == tab["pos"][0] and laurent@676: other["size"][0] == tab["size"][0] and laurent@680: other["pos"][1] == tab["pos"][1] + tab["size"][1] + TAB_BORDER): laurent@676: laurent@680: tab["size"] = (tab["size"][0], tab["size"][1] + other["size"][1] + TAB_BORDER) laurent@676: tab["pages"].extend(other["pages"]) laurent@676: tabs.remove(other) laurent@676: laurent@676: if tab["size"][1] == rect.height: laurent@676: return True laurent@676: return False laurent@676: laurent@691: def ComputeTabsLayout(tabs, rect): laurent@676: if len(tabs) == 0: laurent@676: return tabs laurent@673: if len(tabs) == 1: laurent@673: return tabs[0] laurent@673: split = None laurent@673: for idx, tab in enumerate(tabs): laurent@680: if len(tab["pages"]) == 0: Laurent@720: raise ValueError, "Not possible" laurent@673: if tab["size"][0] == rect.width: laurent@673: if tab["pos"][1] == rect.y: laurent@673: split = (wx.TOP, float(tab["size"][1]) / float(rect.height)) laurent@680: split_rect = wx.Rect(rect.x, rect.y + tab["size"][1] + TAB_BORDER, laurent@680: rect.width, rect.height - tab["size"][1] - TAB_BORDER) laurent@673: elif tab["pos"][1] == rect.height + 1 - tab["size"][1]: laurent@673: split = (wx.BOTTOM, 1.0 - float(tab["size"][1]) / float(rect.height)) laurent@673: split_rect = wx.Rect(rect.x, rect.y, laurent@680: rect.width, rect.height - tab["size"][1] - TAB_BORDER) laurent@673: break laurent@673: elif tab["size"][1] == rect.height: laurent@673: if tab["pos"][0] == rect.x: laurent@673: split = (wx.LEFT, float(tab["size"][0]) / float(rect.width)) laurent@680: split_rect = wx.Rect(rect.x + tab["size"][0] + TAB_BORDER, rect.y, laurent@680: rect.width - tab["size"][0] - TAB_BORDER, rect.height) laurent@673: elif tab["pos"][0] == rect.width + 1 - tab["size"][0]: laurent@673: split = (wx.RIGHT, 1.0 - float(tab["size"][0]) / float(rect.width)) laurent@673: split_rect = wx.Rect(rect.x, rect.y, laurent@680: rect.width - tab["size"][0] - TAB_BORDER, rect.height) laurent@673: break laurent@673: if split != None: laurent@673: split_tab = tabs.pop(idx) laurent@673: return {"split": split, laurent@673: "tab": split_tab, laurent@691: "others": ComputeTabsLayout(tabs, split_rect)} laurent@676: else: laurent@691: if SimplifyTabLayout(tabs, rect): laurent@691: return ComputeTabsLayout(tabs, rect) laurent@673: return tabs laurent@401: laurent@390: #------------------------------------------------------------------------------- laurent@407: # IDEFrame Base Class laurent@390: #------------------------------------------------------------------------------- laurent@390: laurent@391: UNEDITABLE_NAMES_DICT = dict([(_(name), name) for name in UNEDITABLE_NAMES]) laurent@391: laurent@407: class IDEFrame(wx.Frame): etisserant@0: laurent@680: Starting = False laurent@680: laurent@384: # Compatibility function for wx versions < 2.6 lbessard@114: if wx.VERSION < (2, 6, 0): lbessard@114: def Bind(self, event, function, id = None): lbessard@114: if id is not None: lbessard@114: event(self, id, function) lbessard@114: else: lbessard@114: event(self, function) lbessard@114: lbessard@185: def _init_coll_MenuBar_Menus(self, parent): laurent@587: parent.Append(menu=self.FileMenu, title=_(u'&File')) laurent@587: parent.Append(menu=self.EditMenu, title=_(u'&Edit')) laurent@587: parent.Append(menu=self.DisplayMenu, title=_(u'&Display')) laurent@587: parent.Append(menu=self.HelpMenu, title=_(u'&Help')) etisserant@0: lbessard@185: def _init_coll_FileMenu_Items(self, parent): laurent@407: pass lbessard@185: laurent@687: def _init_coll_AddMenu_Items(self, parent, add_config=True): laurent@684: AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUADDDATATYPE, laurent@684: kind=wx.ITEM_NORMAL, text=_(u'&Data Type')) laurent@684: AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUADDFUNCTION, laurent@684: kind=wx.ITEM_NORMAL, text=_(u'&Function')) laurent@684: AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK, laurent@684: kind=wx.ITEM_NORMAL, text=_(u'Function &Block')) laurent@684: AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUADDPROGRAM, laurent@684: kind=wx.ITEM_NORMAL, text=_(u'&Program')) laurent@687: if add_config: laurent@687: AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUADDCONFIGURATION, laurent@687: kind=wx.ITEM_NORMAL, text=_(u'&Configuration')) laurent@684: lbessard@185: def _init_coll_EditMenu_Items(self, parent): lbessard@332: AppendMenu(parent, help='', id=wx.ID_UNDO, laurent@391: kind=wx.ITEM_NORMAL, text=_(u'Undo\tCTRL+Z')) lbessard@332: AppendMenu(parent, help='', id=wx.ID_REDO, laurent@391: kind=wx.ITEM_NORMAL, text=_(u'Redo\tCTRL+Y')) laurent@559: #AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, laurent@559: # kind=wx.ITEM_CHECK, text=_(u'Enable Undo/Redo')) laurent@560: enable_undo_redo = _(u'Enable Undo/Redo') # Keeping text in translations for possible menu reactivation lbessard@332: parent.AppendSeparator() lbessard@332: AppendMenu(parent, help='', id=wx.ID_CUT, laurent@391: kind=wx.ITEM_NORMAL, text=_(u'Cut\tCTRL+X')) lbessard@332: AppendMenu(parent, help='', id=wx.ID_COPY, laurent@391: kind=wx.ITEM_NORMAL, text=_(u'Copy\tCTRL+C')) lbessard@332: AppendMenu(parent, help='', id=wx.ID_PASTE, laurent@391: kind=wx.ITEM_NORMAL, text=_(u'Paste\tCTRL+V')) lbessard@332: parent.AppendSeparator() Laurent@738: AppendMenu(parent, help='', id=wx.ID_FIND, Laurent@738: kind=wx.ITEM_NORMAL, text=_(u'Find\tCTRL+F')) Laurent@738: AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUFINDNEXT, Laurent@738: kind=wx.ITEM_NORMAL, text=_(u'Find Next\tCTRL+K')) Laurent@738: AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUFINDPREVIOUS, Laurent@738: kind=wx.ITEM_NORMAL, text=_(u'Find Previous\tCTRL+SHIFT+K')) Laurent@738: parent.AppendSeparator() laurent@566: AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT, Laurent@738: kind=wx.ITEM_NORMAL, text=_(u'Search in Project\tCTRL+SHIFT+F')) laurent@566: parent.AppendSeparator() laurent@684: add_menu = wx.Menu(title='') laurent@684: self._init_coll_AddMenu_Items(add_menu) laurent@684: parent.AppendMenu(wx.ID_ADD, _(u"&Add Element"), add_menu) lbessard@332: AppendMenu(parent, help='', id=wx.ID_SELECTALL, laurent@391: kind=wx.ITEM_NORMAL, text=_(u'Select All\tCTRL+A')) lbessard@332: AppendMenu(parent, help='', id=wx.ID_DELETE, Edouard@656: kind=wx.ITEM_NORMAL, text=_(u'&Delete')) lbessard@332: self.Bind(wx.EVT_MENU, self.OnUndoMenu, id=wx.ID_UNDO) lbessard@332: self.Bind(wx.EVT_MENU, self.OnRedoMenu, id=wx.ID_REDO) laurent@562: #self.Bind(wx.EVT_MENU, self.OnEnableUndoRedoMenu, id=ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO) lbessard@332: self.Bind(wx.EVT_MENU, self.OnCutMenu, id=wx.ID_CUT) lbessard@332: self.Bind(wx.EVT_MENU, self.OnCopyMenu, id=wx.ID_COPY) lbessard@332: self.Bind(wx.EVT_MENU, self.OnPasteMenu, id=wx.ID_PASTE) Laurent@738: self.Bind(wx.EVT_MENU, self.OnFindMenu, id=wx.ID_FIND) Laurent@738: self.Bind(wx.EVT_MENU, self.OnFindNextMenu, Laurent@738: id=ID_PLCOPENEDITOREDITMENUFINDNEXT) Laurent@738: self.Bind(wx.EVT_MENU, self.OnFindPreviousMenu, Laurent@738: id=ID_PLCOPENEDITOREDITMENUFINDPREVIOUS) Laurent@738: self.Bind(wx.EVT_MENU, self.OnSearchInProjectMenu, Laurent@738: id=ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT) laurent@566: self.Bind(wx.EVT_MENU, self.OnSearchInProjectMenu, laurent@566: id=ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT) lbessard@332: self.Bind(wx.EVT_MENU, self.OnAddDataTypeMenu, lbessard@332: id=ID_PLCOPENEDITOREDITMENUADDDATATYPE) lbessard@332: self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction("function"), lbessard@332: id=ID_PLCOPENEDITOREDITMENUADDFUNCTION) lbessard@332: self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction("functionBlock"), lbessard@332: id=ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK) lbessard@332: self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction("program"), lbessard@332: id=ID_PLCOPENEDITOREDITMENUADDPROGRAM) lbessard@332: self.Bind(wx.EVT_MENU, self.OnAddConfigurationMenu, lbessard@332: id=ID_PLCOPENEDITOREDITMENUADDCONFIGURATION) lbessard@332: self.Bind(wx.EVT_MENU, self.OnSelectAllMenu, id=wx.ID_SELECTALL) lbessard@332: self.Bind(wx.EVT_MENU, self.OnDeleteMenu, id=wx.ID_DELETE) laurent@660: Laurent@714: self.AddToMenuToolBar([(wx.ID_UNDO, "undo", _(u'Undo'), None), Laurent@714: (wx.ID_REDO, "redo", _(u'Redo'), None), laurent@660: None, Laurent@714: (wx.ID_CUT, "cut", _(u'Cut'), None), Laurent@714: (wx.ID_COPY, "copy", _(u'Copy'), None), Laurent@714: (wx.ID_PASTE, "paste", _(u'Paste'), None), laurent@666: None, Laurent@714: (ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT, "find", _(u'Search in Project'), None)]) lbessard@332: lbessard@332: def _init_coll_DisplayMenu_Items(self, parent): lbessard@185: AppendMenu(parent, help='', id=wx.ID_REFRESH, Edouard@569: kind=wx.ITEM_NORMAL, text=_(u'Refresh\tCTRL+R')) laurent@407: if self.EnableDebug: lbessard@332: AppendMenu(parent, help='', id=wx.ID_CLEAR, laurent@391: kind=wx.ITEM_NORMAL, text=_(u'Clear Errors\tCTRL+K')) lbessard@332: parent.AppendSeparator() lbessard@332: zoommenu = wx.Menu(title='') laurent@391: parent.AppendMenu(wx.ID_ZOOM_FIT, _("Zoom"), zoommenu) lbessard@332: for idx, value in enumerate(ZOOM_FACTORS): lbessard@332: new_id = wx.NewId() lbessard@332: AppendMenu(zoommenu, help='', id=new_id, lbessard@332: kind=wx.ITEM_RADIO, text=str(int(round(value * 100))) + "%") lbessard@332: self.Bind(wx.EVT_MENU, self.GenerateZoomFunction(idx), id=new_id) laurent@673: Edouard@685: parent.AppendSeparator() Edouard@685: AppendMenu(parent, help='', id=ID_PLCOPENEDITORDISPLAYMENURESETPERSPECTIVE, Edouard@685: kind=wx.ITEM_NORMAL, text=_(u'Reset Perspective')) Edouard@685: self.Bind(wx.EVT_MENU, self.OnResetPerspective, id=ID_PLCOPENEDITORDISPLAYMENURESETPERSPECTIVE) laurent@673: lbessard@185: self.Bind(wx.EVT_MENU, self.OnRefreshMenu, id=wx.ID_REFRESH) laurent@407: if self.EnableDebug: lbessard@332: self.Bind(wx.EVT_MENU, self.OnClearErrorsMenu, id=wx.ID_CLEAR) laurent@673: etisserant@0: def _init_coll_HelpMenu_Items(self, parent): laurent@407: pass etisserant@0: etisserant@0: def _init_utils(self): lbessard@185: self.MenuBar = wx.MenuBar() etisserant@0: etisserant@220: self.FileMenu = wx.Menu(title='') laurent@407: self.EditMenu = wx.Menu(title='') lbessard@332: self.DisplayMenu = wx.Menu(title='') etisserant@0: self.HelpMenu = wx.Menu(title='') lbessard@163: lbessard@185: self._init_coll_MenuBar_Menus(self.MenuBar) etisserant@220: self._init_coll_FileMenu_Items(self.FileMenu) laurent@407: self._init_coll_EditMenu_Items(self.EditMenu) lbessard@332: self._init_coll_DisplayMenu_Items(self.DisplayMenu) etisserant@0: self._init_coll_HelpMenu_Items(self.HelpMenu) lbessard@239: etisserant@0: def _init_ctrls(self, prnt): laurent@407: wx.Frame.__init__(self, id=ID_PLCOPENEDITOR, name='IDEFrame', lbessard@235: parent=prnt, pos=wx.DefaultPosition, size=wx.Size(1000, 600), laurent@407: style=wx.DEFAULT_FRAME_STYLE) etisserant@0: self.SetClientSize(wx.Size(1000, 600)) laurent@666: self.Bind(wx.EVT_ACTIVATE, self.OnActivated) laurent@673: self.Bind(wx.EVT_SIZE, self.OnResize) laurent@407: laurent@407: self.TabsImageList = wx.ImageList(31, 16) laurent@407: self.TabsImageListIndexes = {} laurent@407: laurent@407: #----------------------------------------------------------------------- laurent@407: # Creating main structure laurent@407: #----------------------------------------------------------------------- lbessard@64: Edouard@685: self.AUIManager = wx.aui.AuiManager(self) Edouard@685: self.AUIManager.SetDockSizeConstraint(0.5, 0.5) Edouard@685: self.Panes = {} Edouard@685: Edouard@685: self.LeftNoteBook = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORLEFTNOTEBOOK, Edouard@685: style=wx.aui.AUI_NB_TOP|wx.aui.AUI_NB_TAB_SPLIT|wx.aui.AUI_NB_TAB_MOVE| Edouard@685: wx.aui.AUI_NB_SCROLL_BUTTONS|wx.aui.AUI_NB_TAB_EXTERNAL_MOVE) Edouard@685: self.LeftNoteBook.Bind(wx.aui.EVT_AUINOTEBOOK_ALLOW_DND, Edouard@685: self.OnAllowNotebookDnD) Edouard@685: self.AUIManager.AddPane(self.LeftNoteBook, Edouard@685: wx.aui.AuiPaneInfo().Name("ProjectPane"). Edouard@685: Left().Layer(1). Edouard@685: BestSize(wx.Size(300, 500)).CloseButton(False)) Edouard@685: Edouard@685: self.BottomNoteBook = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORBOTTOMNOTEBOOK, Edouard@685: style=wx.aui.AUI_NB_TOP|wx.aui.AUI_NB_TAB_SPLIT|wx.aui.AUI_NB_TAB_MOVE| Edouard@685: wx.aui.AUI_NB_SCROLL_BUTTONS|wx.aui.AUI_NB_TAB_EXTERNAL_MOVE) Edouard@685: self.BottomNoteBook.Bind(wx.aui.EVT_AUINOTEBOOK_ALLOW_DND, Edouard@685: self.OnAllowNotebookDnD) Edouard@685: self.AUIManager.AddPane(self.BottomNoteBook, Edouard@685: wx.aui.AuiPaneInfo().Name("ResultPane"). Edouard@685: Bottom().Layer(0). Edouard@685: BestSize(wx.Size(800, 300)).CloseButton(False)) Edouard@685: Edouard@685: self.RightNoteBook = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORRIGHTNOTEBOOK, Edouard@685: style=wx.aui.AUI_NB_TOP|wx.aui.AUI_NB_TAB_SPLIT|wx.aui.AUI_NB_TAB_MOVE| Edouard@685: wx.aui.AUI_NB_SCROLL_BUTTONS|wx.aui.AUI_NB_TAB_EXTERNAL_MOVE) Edouard@685: self.RightNoteBook.Bind(wx.aui.EVT_AUINOTEBOOK_ALLOW_DND, Edouard@685: self.OnAllowNotebookDnD) Edouard@685: self.AUIManager.AddPane(self.RightNoteBook, Edouard@685: wx.aui.AuiPaneInfo().Name("LibraryPane"). Edouard@685: Right().Layer(0). Edouard@685: BestSize(wx.Size(250, 400)).CloseButton(False)) Edouard@685: Edouard@685: self.TabsOpened = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORTABSOPENED, Edouard@685: style=wx.aui.AUI_NB_DEFAULT_STYLE|wx.aui.AUI_NB_WINDOWLIST_BUTTON) Edouard@685: self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGING, Laurent@711: self.OnPouSelectedChanging) Edouard@685: self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED, Laurent@711: self.OnPouSelectedChanged) Edouard@685: self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE, Laurent@711: self.OnPageClose) Edouard@685: self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_END_DRAG, Laurent@711: self.OnPageDragged) Edouard@685: self.AUIManager.AddPane(self.TabsOpened, Edouard@685: wx.aui.AuiPaneInfo().CentrePane().Name("TabsPane")) laurent@407: laurent@407: #----------------------------------------------------------------------- laurent@673: # Creating PLCopen Project Types Tree laurent@407: #----------------------------------------------------------------------- laurent@407: laurent@673: self.MainTabs = {} laurent@673: laurent@684: self.ProjectPanel = wx.SplitterWindow(id=ID_PLCOPENEDITORPROJECTPANEL, laurent@684: name='ProjectPanel', parent=self.LeftNoteBook, point=wx.Point(0, 0), laurent@684: size=wx.Size(0, 0), style=wx.SP_3D) laurent@684: laurent@684: self.ProjectTree = CustomTree(id=ID_PLCOPENEDITORPROJECTTREE, laurent@684: name='ProjectTree', parent=self.ProjectPanel, lbessard@235: pos=wx.Point(0, 0), size=wx.Size(0, 0), laurent@407: style=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER|wx.TR_EDIT_LABELS) Laurent@714: self.ProjectTree.SetBackgroundBitmap(GetBitmap("custom_tree_background"), laurent@684: wx.ALIGN_RIGHT|wx.ALIGN_BOTTOM) laurent@684: add_menu = wx.Menu() laurent@684: self._init_coll_AddMenu_Items(add_menu) laurent@684: self.ProjectTree.SetAddMenu(add_menu) laurent@407: if wx.Platform == '__WXMSW__': laurent@684: self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnProjectTreeRightUp, laurent@684: id=ID_PLCOPENEDITORPROJECTTREE) laurent@684: self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnProjectTreeItemSelected, laurent@684: id=ID_PLCOPENEDITORPROJECTTREE) laurent@407: else: Laurent@705: self.ProjectTree.Bind(wx.EVT_RIGHT_UP, self.OnProjectTreeRightUp) Laurent@705: self.ProjectTree.Bind(wx.EVT_LEFT_UP, self.OnProjectTreeLeftUp) laurent@684: self.Bind(wx.EVT_TREE_SEL_CHANGING, self.OnProjectTreeItemChanging, laurent@684: id=ID_PLCOPENEDITORPROJECTTREE) laurent@684: self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnProjectTreeBeginDrag, laurent@684: id=ID_PLCOPENEDITORPROJECTTREE) laurent@684: self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnProjectTreeItemBeginEdit, laurent@684: id=ID_PLCOPENEDITORPROJECTTREE) laurent@684: self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnProjectTreeItemEndEdit, laurent@684: id=ID_PLCOPENEDITORPROJECTTREE) laurent@684: self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnProjectTreeItemActivated, laurent@684: id=ID_PLCOPENEDITORPROJECTTREE) laurent@673: laurent@407: #----------------------------------------------------------------------- laurent@684: # Creating PLCopen Project POU Instance Variables Panel laurent@407: #----------------------------------------------------------------------- lbessard@235: laurent@684: self.PouInstanceVariablesPanel = PouInstanceVariablesPanel(self.ProjectPanel, self, self.Controler, self.EnableDebug) laurent@684: laurent@684: self.MainTabs["ProjectPanel"] = (self.ProjectPanel, _("Project")) laurent@684: self.LeftNoteBook.AddPage(*self.MainTabs["ProjectPanel"]) laurent@684: laurent@684: self.ProjectPanel.SplitHorizontally(self.ProjectTree, self.PouInstanceVariablesPanel, 300) laurent@407: laurent@407: #----------------------------------------------------------------------- laurent@407: # Creating Tool Bar laurent@407: #----------------------------------------------------------------------- laurent@673: Edouard@685: MenuToolBar = wx.ToolBar(self, ID_PLCOPENEDITOREDITORMENUTOOLBAR, wx.DefaultPosition, wx.DefaultSize, Edouard@685: wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER) Edouard@685: MenuToolBar.SetToolBitmapSize(wx.Size(25, 25)) Edouard@685: MenuToolBar.Realize() Edouard@685: self.Panes["MenuToolBar"] = MenuToolBar Edouard@685: self.AUIManager.AddPane(MenuToolBar, wx.aui.AuiPaneInfo(). Edouard@685: Name("MenuToolBar").Caption(_("Menu ToolBar")). Edouard@685: ToolbarPane().Top(). Edouard@685: LeftDockable(False).RightDockable(False)) Edouard@685: Edouard@685: EditorToolBar = wx.ToolBar(self, ID_PLCOPENEDITOREDITORTOOLBAR, wx.DefaultPosition, wx.DefaultSize, Edouard@685: wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER) Edouard@685: EditorToolBar.SetToolBitmapSize(wx.Size(25, 25)) Edouard@685: EditorToolBar.AddRadioTool(ID_PLCOPENEDITOREDITORTOOLBARSELECTION, Laurent@714: GetBitmap("select"), wx.NullBitmap, _("Select an object")) Edouard@685: EditorToolBar.Realize() Edouard@685: self.Panes["EditorToolBar"] = EditorToolBar Edouard@685: self.AUIManager.AddPane(EditorToolBar, wx.aui.AuiPaneInfo(). Edouard@685: Name("EditorToolBar").Caption(_("Editor ToolBar")). Edouard@685: ToolbarPane().Top().Position(1). Edouard@685: LeftDockable(False).RightDockable(False)) lbessard@121: laurent@660: self.Bind(wx.EVT_MENU, self.OnSelectionTool, laurent@660: id=ID_PLCOPENEDITOREDITORTOOLBARSELECTION) laurent@407: laurent@673: #----------------------------------------------------------------------- laurent@673: # Creating Search Panel laurent@673: #----------------------------------------------------------------------- laurent@673: laurent@566: self.SearchResultPanel = SearchResultPanel(self.BottomNoteBook, self) laurent@673: self.MainTabs["SearchResultPanel"] = (self.SearchResultPanel, _("Search")) laurent@673: self.BottomNoteBook.AddPage(*self.MainTabs["SearchResultPanel"]) laurent@673: laurent@673: #----------------------------------------------------------------------- laurent@673: # Creating Library Panel laurent@673: #----------------------------------------------------------------------- laurent@673: laurent@676: self.LibraryPanel = LibraryPanel(self, True) laurent@673: self.MainTabs["LibraryPanel"] = (self.LibraryPanel, _("Library")) laurent@673: self.RightNoteBook.AddPage(*self.MainTabs["LibraryPanel"]) laurent@676: laurent@660: self._init_utils() laurent@660: self.SetMenuBar(self.MenuBar) laurent@676: laurent@407: if self.EnableDebug: Laurent@714: self.DebugVariablePanel = DebugVariablePanel(self.RightNoteBook, self.Controler) laurent@673: self.MainTabs["DebugVariablePanel"] = (self.DebugVariablePanel, _("Debugger")) laurent@673: self.RightNoteBook.AddPage(*self.MainTabs["DebugVariablePanel"]) lbessard@239: Edouard@685: self.AUIManager.Update() lbessard@241: Laurent@738: self.FindDialog = FindInPouDialog(self) Laurent@738: self.FindDialog.Hide() Laurent@738: laurent@390: ## Constructor of the PLCOpenEditor class. laurent@390: # @param parent The parent window. laurent@390: # @param controler The controler been used by PLCOpenEditor (default: None). laurent@390: # @param fileOpen The filepath to open if no controler defined (default: None). laurent@390: # @param debug The filepath to open if no controler defined (default: False). laurent@407: def __init__(self, parent, enable_debug = False): laurent@407: self.Controler = None laurent@535: self.Config = wx.ConfigBase.Get() laurent@407: self.EnableDebug = enable_debug lbessard@121: etisserant@0: self._init_ctrls(parent) etisserant@0: laurent@390: # Define Tree item icon list laurent@390: self.TreeImageList = wx.ImageList(16, 16) laurent@390: self.TreeImageDict = {} laurent@390: laurent@390: # Icons for languages etisserant@184: for language in LANGUAGES: Laurent@714: self.TreeImageDict[language] = self.TreeImageList.Add(GetBitmap(language)) laurent@390: laurent@390: # Icons for other items etisserant@184: for imgname, itemtype in [ etisserant@184: #editables etisserant@184: ("PROJECT", ITEM_PROJECT), etisserant@184: #("POU", ITEM_POU), etisserant@184: #("VARIABLE", ITEM_VARIABLE), etisserant@184: ("TRANSITION", ITEM_TRANSITION), etisserant@184: ("ACTION", ITEM_ACTION), etisserant@184: ("CONFIGURATION", ITEM_CONFIGURATION), etisserant@184: ("RESOURCE", ITEM_RESOURCE), etisserant@184: ("DATATYPE", ITEM_DATATYPE), etisserant@184: # uneditables etisserant@184: ("DATATYPES", ITEM_DATATYPES), etisserant@184: ("FUNCTION", ITEM_FUNCTION), etisserant@184: ("FUNCTIONBLOCK", ITEM_FUNCTIONBLOCK), etisserant@184: ("PROGRAM", ITEM_PROGRAM), lbessard@235: ("VAR_LOCAL", ITEM_VAR_LOCAL), lbessard@235: ("VAR_LOCAL", ITEM_VAR_GLOBAL), lbessard@235: ("VAR_LOCAL", ITEM_VAR_EXTERNAL), lbessard@235: ("VAR_LOCAL", ITEM_VAR_TEMP), lbessard@235: ("VAR_INPUT", ITEM_VAR_INPUT), lbessard@235: ("VAR_OUTPUT", ITEM_VAR_OUTPUT), lbessard@235: ("VAR_INOUT", ITEM_VAR_INOUT), etisserant@184: ("TRANSITIONS", ITEM_TRANSITIONS), etisserant@184: ("ACTIONS", ITEM_ACTIONS), etisserant@184: ("CONFIGURATIONS", ITEM_CONFIGURATIONS), etisserant@184: ("RESOURCES", ITEM_RESOURCES), etisserant@184: ("PROPERTIES", ITEM_PROPERTIES)]: Laurent@714: self.TreeImageDict[itemtype] = self.TreeImageList.Add(GetBitmap(imgname)) laurent@390: laurent@390: # Assign icon list to TreeCtrls laurent@684: self.ProjectTree.SetImageList(self.TreeImageList) laurent@684: self.PouInstanceVariablesPanel.SetTreeImageList(self.TreeImageList) lbessard@9: laurent@660: self.CurrentEditorToolBar = [] laurent@660: self.CurrentMenu = None lbessard@122: self.SelectedItem = None Laurent@738: self.SearchParams = None laurent@566: self.Highlights = {} lbessard@71: self.DrawingMode = FREEDRAWING_MODE lbessard@71: #self.DrawingMode = DRIVENDRAWING_MODE Edouard@685: self.AuiTabCtrl = [] laurent@673: self.DefaultPerspective = None lbessard@6: laurent@390: # Initialize Printing configuring elements lbessard@213: self.PrintData = wx.PrintData() lbessard@213: self.PrintData.SetPaperId(wx.PAPER_A4) lbessard@213: self.PrintData.SetPrintMode(wx.PRINT_MODE_PRINTER) lbessard@213: self.PageSetupData = wx.PageSetupDialogData(self.PrintData) lbessard@213: self.PageSetupData.SetMarginTopLeft(wx.Point(10, 15)) lbessard@213: self.PageSetupData.SetMarginBottomRight(wx.Point(10, 20)) lbessard@213: laurent@407: self.SetRefreshFunctions() laurent@535: Laurent@738: def __del__(self): Laurent@738: self.FindDialog.Destroy() Laurent@738: laurent@680: def ResetStarting(self): laurent@680: self.Starting = False laurent@680: laurent@535: def Show(self): laurent@535: wx.Frame.Show(self) laurent@673: wx.CallAfter(self.RestoreLastState) laurent@535: laurent@666: def OnActivated(self, event): laurent@666: if event.GetActive(): laurent@666: wx.CallAfter(self._Refresh, TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU) laurent@666: event.Skip() laurent@673: laurent@673: #------------------------------------------------------------------------------- laurent@673: # Saving and restoring frame organization functions laurent@673: #------------------------------------------------------------------------------- laurent@673: laurent@673: def OnResize(self, event): laurent@673: if self.Starting: laurent@691: self.RestoreLastLayout() laurent@680: if wx.Platform == '__WXMSW__': laurent@680: wx.CallAfter(self.ResetStarting) laurent@680: else: laurent@680: self.ResetStarting() laurent@680: wx.CallAfter(self.RefreshEditor) laurent@673: event.Skip() laurent@673: laurent@675: def GetProjectConfiguration(self): laurent@676: projects = {} laurent@676: try: laurent@676: if self.Config.HasEntry("projects"): Laurent@728: projects = cPickle.loads(str(self.Config.Read("projects"))) laurent@676: except: laurent@676: pass laurent@676: Laurent@727: return projects.get( Laurent@727: EncodeFileSystemPath(os.path.realpath(self.Controler.GetFilePath())), {}) laurent@675: laurent@675: def SavePageState(self, page): laurent@675: state = page.GetState() laurent@675: if state is not None: laurent@675: if self.Config.HasEntry("projects"): Laurent@728: projects = cPickle.loads(str(self.Config.Read("projects"))) laurent@675: else: laurent@675: projects = {} laurent@675: Laurent@727: project_infos = projects.setdefault( Laurent@727: EncodeFileSystemPath(os.path.realpath(self.Controler.GetFilePath())), {}) laurent@675: editors_state = project_infos.setdefault("editors_state", {}) laurent@675: laurent@675: if page.IsDebugging(): laurent@675: editors_state[page.GetInstancePath()] = state laurent@675: else: laurent@675: editors_state[page.GetTagName()] = state laurent@675: laurent@675: self.Config.Write("projects", cPickle.dumps(projects)) laurent@675: self.Config.Flush() laurent@675: laurent@673: def GetTabInfos(self, tab): laurent@673: if isinstance(tab, EditorPanel): laurent@673: if tab.IsDebugging(): laurent@673: return ("debug", tab.GetInstancePath()) laurent@673: else: laurent@673: return ("editor", tab.GetTagName()) laurent@673: else: laurent@673: for page_name, (page_ref, page_title) in self.MainTabs.iteritems(): laurent@673: if page_ref == tab: laurent@673: return ("main", page_name) laurent@673: return None laurent@675: laurent@691: def SaveTabLayout(self, notebook): laurent@673: tabs = [] laurent@673: for child in notebook.GetChildren(): laurent@673: if isinstance(child, wx.aui.AuiTabCtrl): Laurent@720: if child.GetPageCount() > 0: Laurent@720: pos = child.GetPosition() Laurent@720: tab = {"pos": (pos.x, pos.y), "pages": []} Laurent@720: tab_size = child.GetSize() Laurent@720: for page_idx in xrange(child.GetPageCount()): Laurent@720: page = child.GetWindowFromIdx(page_idx) Laurent@720: if not tab.has_key("size"): Laurent@720: tab["size"] = (tab_size[0], tab_size[1] + page.GetSize()[1]) Laurent@720: tab_infos = self.GetTabInfos(page) Laurent@720: if tab_infos is not None: Laurent@720: tab["pages"].append((tab_infos, page_idx == child.GetActivePage())) Laurent@720: tabs.append(tab) laurent@673: tabs.sort(lambda x, y: cmp(x["pos"], y["pos"])) laurent@673: size = notebook.GetSize() laurent@691: return ComputeTabsLayout(tabs, wx.Rect(1, 1, size[0] - NOTEBOOK_BORDER, size[1] - NOTEBOOK_BORDER)) laurent@673: laurent@673: def LoadTab(self, notebook, page_infos): laurent@673: if page_infos[0] == "main": laurent@673: infos = self.MainTabs.get(page_infos[1]) laurent@673: if infos is not None: laurent@673: page_ref, page_title = infos laurent@673: notebook.AddPage(page_ref, page_title) laurent@673: return notebook.GetPageIndex(page_ref) laurent@673: elif page_infos[0] == "editor": laurent@673: tagname = page_infos[1] laurent@673: page_ref = self.EditProjectElement(self.Controler.GetElementType(tagname), tagname) laurent@687: if page_ref is not None: laurent@687: page_ref.RefreshView() laurent@687: return notebook.GetPageIndex(page_ref) laurent@673: elif page_infos[0] == "debug": laurent@673: instance_path = page_infos[1] laurent@687: instance_infos = self.Controler.GetInstanceInfos(instance_path, self.EnableDebug) laurent@684: if instance_infos is not None: laurent@684: return notebook.GetPageIndex(self.OpenDebugViewer(instance_infos["class"], instance_path, instance_infos["type"])) laurent@673: return None laurent@673: laurent@691: def LoadTabLayout(self, notebook, tabs, mode="all", first_index=None): laurent@673: if isinstance(tabs, ListType): laurent@673: if len(tabs) == 0: laurent@673: return laurent@673: raise ValueError, "Not supported" laurent@673: laurent@673: if tabs.has_key("split"): laurent@691: self.LoadTabLayout(notebook, tabs["others"]) laurent@673: laurent@673: split_dir, split_ratio = tabs["split"] laurent@691: first_index = self.LoadTabLayout(notebook, tabs["tab"], mode="first") laurent@673: notebook.Split(first_index, split_dir) laurent@691: self.LoadTabLayout(notebook, tabs["tab"], mode="others", first_index=first_index) laurent@673: laurent@673: elif mode == "first": laurent@673: return self.LoadTab(notebook, tabs["pages"][0][0]) laurent@673: else: laurent@673: selected = first_index laurent@673: if mode == "others": laurent@673: add_tabs = tabs["pages"][1:] laurent@673: else: laurent@673: add_tabs = tabs["pages"] laurent@673: for page_infos, page_selected in add_tabs: laurent@673: page_idx = self.LoadTab(notebook, page_infos) laurent@673: if page_selected: laurent@673: selected = page_idx laurent@673: if selected is not None: laurent@673: wx.CallAfter(notebook.SetSelection, selected) laurent@676: laurent@676: def ResetPerspective(self): Edouard@685: if self.DefaultPerspective is not None: laurent@676: self.AUIManager.LoadPerspective(self.DefaultPerspective["perspective"]) laurent@676: laurent@676: for notebook in [self.LeftNoteBook, self.BottomNoteBook, self.RightNoteBook]: laurent@676: for idx in xrange(notebook.GetPageCount()): laurent@676: notebook.RemovePage(0) laurent@676: laurent@676: notebooks = self.DefaultPerspective["notebooks"] laurent@676: for notebook, entry_name in [(self.LeftNoteBook, "leftnotebook"), laurent@676: (self.BottomNoteBook, "bottomnotebook"), laurent@676: (self.RightNoteBook, "rightnotebook")]: laurent@691: self.LoadTabLayout(notebook, notebooks.get(entry_name)) laurent@676: Laurent@709: self._Refresh(EDITORTOOLBAR) Laurent@709: laurent@673: def RestoreLastState(self): laurent@535: frame_size = None laurent@535: if self.Config.HasEntry("framesize"): laurent@535: frame_size = cPickle.loads(str(self.Config.Read("framesize"))) laurent@535: laurent@673: self.Starting = True laurent@535: if frame_size is None: laurent@535: self.Maximize() laurent@535: else: laurent@535: self.SetClientSize(frame_size) laurent@673: laurent@691: def RestoreLastLayout(self): Edouard@685: notebooks = {} Edouard@685: for notebook, entry_name in [(self.LeftNoteBook, "leftnotebook"), Edouard@685: (self.BottomNoteBook, "bottomnotebook"), Edouard@685: (self.RightNoteBook, "rightnotebook")]: laurent@691: notebooks[entry_name] = self.SaveTabLayout(notebook) Edouard@685: self.DefaultPerspective = { Edouard@685: "perspective": self.AUIManager.SavePerspective(), Edouard@685: "notebooks": notebooks, Edouard@685: } Edouard@685: Edouard@685: try: Edouard@685: if self.Config.HasEntry("perspective"): Laurent@760: self.AUIManager.LoadPerspective(unicode(self.Config.Read("perspective"))) Edouard@685: Edouard@685: if self.Config.HasEntry("notebooks"): Edouard@685: notebooks = cPickle.loads(str(self.Config.Read("notebooks"))) Edouard@685: Edouard@685: for notebook in [self.LeftNoteBook, self.BottomNoteBook, self.RightNoteBook]: Edouard@685: for idx in xrange(notebook.GetPageCount()): Edouard@685: notebook.RemovePage(0) Edouard@685: Edouard@685: for notebook, entry_name in [(self.LeftNoteBook, "leftnotebook"), Edouard@685: (self.BottomNoteBook, "bottomnotebook"), Edouard@685: (self.RightNoteBook, "rightnotebook")]: laurent@691: self.LoadTabLayout(notebook, notebooks.get(entry_name)) Edouard@685: except: Edouard@685: self.ResetPerspective() Edouard@685: laurent@691: self.LoadProjectLayout() Laurent@709: Laurent@709: self._Refresh(EDITORTOOLBAR) laurent@673: laurent@673: def SaveLastState(self): laurent@535: if not self.IsMaximized(): laurent@535: self.Config.Write("framesize", cPickle.dumps(self.GetClientSize())) laurent@535: elif self.Config.HasEntry("framesize"): laurent@535: self.Config.DeleteEntry("framesize") laurent@673: Edouard@685: notebooks = {} Edouard@685: for notebook, entry_name in [(self.LeftNoteBook, "leftnotebook"), Edouard@685: (self.BottomNoteBook, "bottomnotebook"), Edouard@685: (self.RightNoteBook, "rightnotebook")]: laurent@691: notebooks[entry_name] = self.SaveTabLayout(notebook) Edouard@685: self.Config.Write("notebooks", cPickle.dumps(notebooks)) Edouard@685: Laurent@695: pane = self.AUIManager.GetPane(self.TabsOpened) Laurent@695: if pane.IsMaximized(): Laurent@695: self.AUIManager.RestorePane(pane) Edouard@685: self.Config.Write("perspective", self.AUIManager.SavePerspective()) Edouard@685: laurent@691: self.SaveProjectLayout() laurent@673: laurent@675: for i in xrange(self.TabsOpened.GetPageCount()): laurent@675: self.SavePageState(self.TabsOpened.GetPage(i)) laurent@675: laurent@535: self.Config.Flush() laurent@390: laurent@691: def SaveProjectLayout(self): Edouard@685: if self.Controler is not None: laurent@673: tabs = [] laurent@673: laurent@676: projects = {} laurent@676: try: laurent@676: if self.Config.HasEntry("projects"): Laurent@728: projects = cPickle.loads(str(self.Config.Read("projects"))) laurent@676: except: laurent@676: pass laurent@673: Laurent@727: project_infos = projects.setdefault( Laurent@727: EncodeFileSystemPath(os.path.realpath(self.Controler.GetFilePath())), {}) laurent@691: project_infos["tabs"] = self.SaveTabLayout(self.TabsOpened) laurent@673: if self.EnableDebug: laurent@673: project_infos["debug_vars"] = self.DebugVariablePanel.GetDebugVariables() laurent@676: laurent@673: self.Config.Write("projects", cPickle.dumps(projects)) laurent@673: self.Config.Flush() laurent@673: laurent@691: def LoadProjectLayout(self): Edouard@685: if self.Controler is not None: laurent@676: project = self.GetProjectConfiguration() laurent@676: laurent@676: try: laurent@676: if project.has_key("tabs"): laurent@691: self.LoadTabLayout(self.TabsOpened, project["tabs"]) laurent@676: except: laurent@676: self.DeleteAllPages() laurent@676: laurent@676: if self.EnableDebug: laurent@676: try: laurent@676: for variable in project.get("debug_vars", []): laurent@673: self.DebugVariablePanel.InsertValue(variable, force=True) laurent@676: except: laurent@676: self.DebugVariablePanel.ResetGrid() laurent@673: laurent@390: #------------------------------------------------------------------------------- laurent@390: # General Functions laurent@390: #------------------------------------------------------------------------------- laurent@390: laurent@407: def SetRefreshFunctions(self): laurent@407: self.RefreshFunctions = { laurent@407: TITLE : self.RefreshTitle, laurent@660: EDITORTOOLBAR : self.RefreshEditorToolBar, laurent@407: FILEMENU : self.RefreshFileMenu, laurent@407: EDITMENU : self.RefreshEditMenu, laurent@407: DISPLAYMENU : self.RefreshDisplayMenu, laurent@684: PROJECTTREE : self.RefreshProjectTree, laurent@684: POUINSTANCEVARIABLESPANEL : self.RefreshPouInstanceVariablesPanel, laurent@676: LIBRARYTREE : self.RefreshLibraryPanel, laurent@586: SCALING : self.RefreshScaling, laurent@586: PAGETITLES: self.RefreshPageTitles} laurent@407: laurent@390: ## Call PLCOpenEditor refresh functions. laurent@390: # @param elements List of elements to refresh. laurent@390: def _Refresh(self, *elements): Edouard@683: try: Edouard@683: for element in elements: Edouard@683: self.RefreshFunctions[element]() Edouard@683: except wx.PyDeadObjectError: Edouard@683: # ignore exceptions caused by refresh while quitting Edouard@683: pass laurent@390: laurent@390: ## Callback function when AUINotebook Page closed with CloseButton laurent@390: # @param event AUINotebook Event. lbessard@121: def OnPageClose(self, event): laurent@675: selected = self.TabsOpened.GetSelection() laurent@675: if selected > -1: Laurent@733: window = self.TabsOpened.GetPage(selected) Laurent@733: Laurent@733: if window.CheckSaveBeforeClosing(): Laurent@733: self.SavePageState(window) Laurent@733: Laurent@733: # Refresh all window elements that have changed Laurent@733: wx.CallAfter(self._Refresh, TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU) Laurent@733: wx.CallAfter(self.RefreshTabCtrlEvent) Laurent@738: wx.CallAfter(self.CloseFindInPouDialog) Laurent@733: event.Skip() Laurent@733: else: Laurent@733: event.Veto() Laurent@738: lbessard@341: lbessard@114: def GetCopyBuffer(self): laurent@384: data = None Laurent@745: if wx.TheClipboard.Open(): laurent@384: dataobj = wx.TextDataObject() laurent@384: if wx.TheClipboard.GetData(dataobj): laurent@384: data = dataobj.GetText() laurent@384: wx.TheClipboard.Close() laurent@384: return data laurent@384: laurent@384: def SetCopyBuffer(self, text): Laurent@745: if wx.TheClipboard.Open(): laurent@384: data = wx.TextDataObject() laurent@384: data.SetText(text) laurent@384: wx.TheClipboard.SetData(data) laurent@384: wx.TheClipboard.Flush() laurent@384: wx.TheClipboard.Close() lbessard@114: self.RefreshEditMenu() lbessard@114: lbessard@27: def GetDrawingMode(self): lbessard@27: return self.DrawingMode lbessard@27: lbessard@331: def RefreshScaling(self): lbessard@331: for i in xrange(self.TabsOpened.GetPageCount()): lbessard@331: editor = self.TabsOpened.GetPage(i) lbessard@331: editor.RefreshScaling() lbessard@331: laurent@684: def EditProjectSettings(self): laurent@407: old_values = self.Controler.GetProjectProperties() lbessard@27: dialog = ProjectDialog(self) lbessard@27: dialog.SetValues(old_values) lbessard@64: if dialog.ShowModal() == wx.ID_OK: lbessard@27: new_values = dialog.GetValues() lbessard@27: new_values["creationDateTime"] = old_values["creationDateTime"] lbessard@145: if new_values != old_values: lbessard@145: self.Controler.SetProjectProperties(None, new_values) laurent@660: self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, laurent@684: PROJECTTREE, POUINSTANCEVARIABLESPANEL, SCALING) lbessard@27: dialog.Destroy() lbessard@27: laurent@390: #------------------------------------------------------------------------------- laurent@390: # Notebook Unified Functions laurent@390: #------------------------------------------------------------------------------- lbessard@337: laurent@390: ## Function that add a tab in Notebook, calling refresh for tab DClick event laurent@390: # for wx.aui.AUINotebook. laurent@390: # @param window Panel to display in tab. laurent@390: # @param text title for the tab ctrl. lbessard@337: def AddPage(self, window, text): lbessard@337: self.TabsOpened.AddPage(window, text) lbessard@341: self.RefreshTabCtrlEvent() lbessard@341: laurent@611: ## Function that add a tab in Notebook, calling refresh for tab DClick event laurent@611: # for wx.aui.AUINotebook. laurent@611: # @param window Panel to display in tab. laurent@611: # @param text title for the tab ctrl. laurent@611: def DeletePage(self, window): laurent@611: for idx in xrange(self.TabsOpened.GetPageCount()): laurent@611: if self.TabsOpened.GetPage(idx) == window: laurent@611: self.TabsOpened.DeletePage(idx) laurent@611: self.RefreshTabCtrlEvent() laurent@611: return laurent@611: laurent@390: ## Function that fix difference in deleting all tabs between laurent@390: # wx.Notebook and wx.aui.AUINotebook. lbessard@163: def DeleteAllPages(self): Edouard@685: for idx in xrange(self.TabsOpened.GetPageCount()): Edouard@685: self.TabsOpened.DeletePage(0) laurent@390: self.RefreshTabCtrlEvent() laurent@390: laurent@390: ## Function that fix difference in setting picture on tab between laurent@390: # wx.Notebook and wx.aui.AUINotebook. laurent@390: # @param idx Tab index. laurent@390: # @param bitmap wx.Bitmap to define on tab. laurent@390: # @return True if operation succeeded lbessard@203: def SetPageBitmap(self, idx, bitmap): Edouard@685: return self.TabsOpened.SetPageBitmap(idx, bitmap) lbessard@203: laurent@390: #------------------------------------------------------------------------------- laurent@390: # Dialog Message Functions laurent@390: #------------------------------------------------------------------------------- laurent@390: laurent@390: ## Function displaying an Error dialog in PLCOpenEditor. laurent@390: # @param message The message to display. laurent@390: def ShowErrorMessage(self, message): laurent@391: dialog = wx.MessageDialog(self, message, _("Error"), wx.OK|wx.ICON_ERROR) laurent@390: dialog.ShowModal() laurent@390: dialog.Destroy() laurent@390: laurent@390: ## Function displaying an Error dialog in PLCOpenEditor. laurent@390: # @return False if closing cancelled. laurent@450: def CheckSaveBeforeClosing(self, title=_("Close Project")): laurent@390: if not self.Controler.ProjectIsSaved(): laurent@450: dialog = wx.MessageDialog(self, _("There are changes, do you want to save?"), title, wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION) lbessard@56: answer = dialog.ShowModal() lbessard@56: dialog.Destroy() lbessard@64: if answer == wx.ID_YES: lbessard@56: self.SaveProject() laurent@390: elif answer == wx.ID_CANCEL: laurent@390: return False Laurent@733: Laurent@733: for idx in xrange(self.TabsOpened.GetPageCount()): Laurent@733: window = self.TabsOpened.GetPage(idx) Laurent@733: if not window.CheckSaveBeforeClosing(): Laurent@733: return False Laurent@733: laurent@390: return True lbessard@163: lbessard@163: #------------------------------------------------------------------------------- lbessard@163: # File Menu Functions lbessard@163: #------------------------------------------------------------------------------- lbessard@163: lbessard@163: def RefreshFileMenu(self): laurent@407: pass etisserant@0: laurent@411: def ResetView(self): laurent@411: self.DeleteAllPages() laurent@684: self.ProjectTree.DeleteAllItems() laurent@687: self.ProjectTree.Enable(False) laurent@684: self.PouInstanceVariablesPanel.ResetView() laurent@676: self.LibraryPanel.ResetTree() Laurent@714: self.LibraryPanel.SetController(None) Laurent@758: if self.EnableDebug: Laurent@758: self.DebugVariablePanel.ResetGrid() laurent@411: self.Controler = None etisserant@0: etisserant@0: def OnCloseTabMenu(self, event): lbessard@235: selected = self.TabsOpened.GetSelection() etisserant@0: if selected >= 0: lbessard@294: self.TabsOpened.DeletePage(selected) lbessard@235: if self.TabsOpened.GetPageCount() > 0: lbessard@235: new_index = min(selected, self.TabsOpened.GetPageCount() - 1) lbessard@235: self.TabsOpened.SetSelection(new_index) laurent@478: # Refresh all window elements that have changed laurent@660: self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU) laurent@478: self.RefreshTabCtrlEvent() etisserant@0: lbessard@213: def OnPageSetupMenu(self, event): lbessard@213: dialog = wx.PageSetupDialog(self, self.PageSetupData) lbessard@213: if dialog.ShowModal() == wx.ID_OK: lbessard@213: self.PageSetupData = wx.PageSetupDialogData(dialog.GetPageSetupData()) lbessard@213: self.PrintData = wx.PrintData(self.PageSetupData.GetPrintData()) lbessard@213: dialog.Destroy() lbessard@213: lbessard@213: def OnPreviewMenu(self, event): lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@213: if selected != -1: laurent@407: window = self.TabsOpened.GetPage(selected) lbessard@213: data = wx.PrintDialogData(self.PrintData) laurent@407: properties = self.Controler.GetProjectProperties(window.IsDebugging()) lbessard@213: page_size = map(int, properties["pageSize"]) lbessard@213: margins = (self.PageSetupData.GetMarginTopLeft(), self.PageSetupData.GetMarginBottomRight()) laurent@407: printout = GraphicPrintout(window, page_size, margins, True) laurent@407: printout2 = GraphicPrintout(window, page_size, margins, True) lbessard@213: preview = wx.PrintPreview(printout, printout2, data) lbessard@213: lbessard@213: if preview.Ok(): laurent@559: preview_frame = wx.PreviewFrame(preview, self, _("Print preview"), style=wx.DEFAULT_FRAME_STYLE|wx.FRAME_FLOAT_ON_PARENT) lbessard@213: lbessard@213: preview_frame.Initialize() lbessard@213: laurent@559: preview_canvas = preview.GetCanvas() laurent@559: preview_canvas.SetMinSize(preview_canvas.GetVirtualSize()) laurent@559: preview_frame.Fit() laurent@559: lbessard@213: preview_frame.Show(True) lbessard@213: lbessard@213: def OnPrintMenu(self, event): lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@213: if selected != -1: laurent@407: window = self.TabsOpened.GetPage(selected) lbessard@213: dialog_data = wx.PrintDialogData(self.PrintData) lbessard@213: dialog_data.SetToPage(1) laurent@407: properties = self.Controler.GetProjectProperties(window.IsDebugging()) lbessard@213: page_size = map(int, properties["pageSize"]) lbessard@213: margins = (self.PageSetupData.GetMarginTopLeft(), self.PageSetupData.GetMarginBottomRight()) lbessard@213: printer = wx.Printer(dialog_data) laurent@407: printout = GraphicPrintout(window, page_size, margins) lbessard@213: laurent@559: if not printer.Print(self, printout, True) and printer.GetLastError() != wx.PRINTER_CANCELLED: laurent@391: self.ShowErrorMessage(_("There was a problem printing.\nPerhaps your current printer is not set correctly?")) lbessard@213: printout.Destroy() lbessard@213: lbessard@27: def OnPropertiesMenu(self, event): laurent@690: self.EditProjectSettings() lbessard@27: etisserant@0: def OnQuitMenu(self, event): etisserant@0: self.Close() etisserant@0: lbessard@163: #------------------------------------------------------------------------------- lbessard@332: # Edit Menu Functions lbessard@163: #------------------------------------------------------------------------------- lbessard@163: lbessard@163: def RefreshEditMenu(self): laurent@660: MenuToolBar = self.Panes["MenuToolBar"] laurent@407: if self.Controler is not None: laurent@586: selected = self.TabsOpened.GetSelection() laurent@586: if selected > -1: laurent@586: window = self.TabsOpened.GetPage(selected) laurent@586: undo, redo = window.GetBufferState() laurent@586: else: laurent@613: undo, redo = self.Controler.GetBufferState() laurent@407: self.EditMenu.Enable(wx.ID_UNDO, undo) laurent@660: MenuToolBar.EnableTool(wx.ID_UNDO, undo) laurent@407: self.EditMenu.Enable(wx.ID_REDO, redo) laurent@660: MenuToolBar.EnableTool(wx.ID_REDO, redo) laurent@562: #self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, True) laurent@562: #self.EditMenu.Check(ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, laurent@562: # self.Controler.IsProjectBufferEnabled()) Laurent@738: self.EditMenu.Enable(wx.ID_FIND, selected > -1) Laurent@738: self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUFINDNEXT, Laurent@738: selected > -1 and self.SearchParams is not None) Laurent@738: self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUFINDPREVIOUS, Laurent@738: selected > -1 and self.SearchParams is not None) laurent@566: self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT, True) laurent@666: MenuToolBar.EnableTool(ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT, True) laurent@407: self.EditMenu.Enable(wx.ID_ADD, True) laurent@407: self.EditMenu.Enable(wx.ID_DELETE, True) laurent@407: if self.TabsOpened.GetPageCount() > 0: laurent@407: self.EditMenu.Enable(wx.ID_CUT, True) laurent@660: MenuToolBar.EnableTool(wx.ID_CUT, True) laurent@407: self.EditMenu.Enable(wx.ID_COPY, True) laurent@660: MenuToolBar.EnableTool(wx.ID_COPY, True) Laurent@743: if self.GetCopyBuffer() is not None: Laurent@743: self.EditMenu.Enable(wx.ID_PASTE, True) Laurent@743: MenuToolBar.EnableTool(wx.ID_PASTE, True) Laurent@743: else: Laurent@743: self.EditMenu.Enable(wx.ID_PASTE, False) Laurent@743: MenuToolBar.EnableTool(wx.ID_PASTE, False) laurent@407: self.EditMenu.Enable(wx.ID_SELECTALL, True) lbessard@332: else: lbessard@331: self.EditMenu.Enable(wx.ID_CUT, False) laurent@660: MenuToolBar.EnableTool(wx.ID_CUT, False) lbessard@331: self.EditMenu.Enable(wx.ID_COPY, False) laurent@660: MenuToolBar.EnableTool(wx.ID_COPY, False) lbessard@331: self.EditMenu.Enable(wx.ID_PASTE, False) laurent@660: MenuToolBar.EnableTool(wx.ID_PASTE, False) lbessard@331: self.EditMenu.Enable(wx.ID_SELECTALL, False) laurent@407: else: laurent@407: self.EditMenu.Enable(wx.ID_UNDO, False) laurent@660: MenuToolBar.EnableTool(wx.ID_UNDO, False) laurent@407: self.EditMenu.Enable(wx.ID_REDO, False) laurent@660: MenuToolBar.EnableTool(wx.ID_REDO, False) laurent@562: #self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, False) laurent@407: self.EditMenu.Enable(wx.ID_CUT, False) laurent@660: MenuToolBar.EnableTool(wx.ID_CUT, False) laurent@407: self.EditMenu.Enable(wx.ID_COPY, False) laurent@660: MenuToolBar.EnableTool(wx.ID_COPY, False) laurent@407: self.EditMenu.Enable(wx.ID_PASTE, False) laurent@660: MenuToolBar.EnableTool(wx.ID_PASTE, False) laurent@407: self.EditMenu.Enable(wx.ID_SELECTALL, False) Laurent@738: self.EditMenu.Enable(wx.ID_FIND, False) Laurent@738: self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUFINDNEXT, False) Laurent@738: self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUFINDPREVIOUS, False) laurent@566: self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT, False) laurent@666: MenuToolBar.EnableTool(ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT, False) laurent@407: self.EditMenu.Enable(wx.ID_ADD, False) laurent@407: self.EditMenu.Enable(wx.ID_DELETE, False) lbessard@331: laurent@654: def CloseTabsWithoutModel(self, refresh=True): lbessard@235: idxs = range(self.TabsOpened.GetPageCount()) lbessard@163: idxs.reverse() lbessard@163: for idx in idxs: laurent@407: window = self.TabsOpened.GetPage(idx) laurent@586: if window.HasNoModel(): laurent@586: self.TabsOpened.DeletePage(idx) laurent@654: if refresh: laurent@654: self.RefreshEditor() laurent@407: laurent@390: def OnUndoMenu(self, event): laurent@586: selected = self.TabsOpened.GetSelection() laurent@586: if selected != -1: laurent@586: window = self.TabsOpened.GetPage(selected) laurent@586: window.Undo() laurent@613: else: laurent@613: self.Controler.LoadPrevious() laurent@684: self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE, laurent@613: SCALING, PAGETITLES) lbessard@163: lbessard@163: def OnRedoMenu(self, event): laurent@586: selected = self.TabsOpened.GetSelection() laurent@586: if selected != -1: laurent@586: window = self.TabsOpened.GetPage(selected) laurent@586: window.Redo() laurent@613: else: laurent@613: self.Controler.LoadNext() laurent@684: self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE, laurent@613: SCALING, PAGETITLES) laurent@390: greg@350: def OnEnableUndoRedoMenu(self, event): greg@350: self.Controler.EnableProjectBuffer(event.IsChecked()) greg@350: self.RefreshEditMenu() greg@350: laurent@390: OnCutMenu = GetShortcutKeyCallbackFunction("Cut") laurent@390: OnCopyMenu = GetShortcutKeyCallbackFunction("Copy") laurent@390: OnPasteMenu = GetShortcutKeyCallbackFunction("Paste") laurent@390: lbessard@331: def OnSelectAllMenu(self, event): lbessard@341: control = self.FindFocus() laurent@599: if control is not None and control.GetName() == "Viewer": laurent@586: control.Parent.SelectAll() laurent@587: elif isinstance(control, wx.stc.StyledTextCtrl): laurent@587: control.SelectAll() lbessard@341: elif isinstance(control, wx.TextCtrl): lbessard@341: control.SetSelection(0, control.GetLastPosition()) lbessard@341: elif isinstance(control, wx.ComboBox): lbessard@341: control.SetMark(0, control.GetLastPosition() + 1) lbessard@331: laurent@390: DeleteFunctions = { laurent@390: ITEM_DATATYPE: GetDeleteElementFunction(PLCControler.ProjectRemoveDataType, check_function=PLCControler.DataTypeIsUsed), laurent@390: ITEM_POU: GetDeleteElementFunction(PLCControler.ProjectRemovePou, check_function=PLCControler.PouIsUsed), laurent@390: ITEM_TRANSITION: GetDeleteElementFunction(PLCControler.ProjectRemovePouTransition, ITEM_POU), laurent@390: ITEM_ACTION: GetDeleteElementFunction(PLCControler.ProjectRemovePouAction, ITEM_POU), laurent@390: ITEM_CONFIGURATION: GetDeleteElementFunction(PLCControler.ProjectRemoveConfiguration), laurent@390: ITEM_RESOURCE: GetDeleteElementFunction(PLCControler.ProjectRemoveConfigurationResource, ITEM_CONFIGURATION) laurent@390: } laurent@390: lbessard@163: def OnDeleteMenu(self, event): lbessard@163: window = self.FindFocus() laurent@684: if window == self.ProjectTree or window is None: laurent@684: selected = self.ProjectTree.GetSelection() lbessard@163: if selected.IsOk(): laurent@687: function = self.DeleteFunctions.get(self.ProjectTree.GetPyData(selected)["type"], None) laurent@390: if function is not None: laurent@390: function(self, selected) laurent@390: self.CloseTabsWithoutModel() laurent@684: self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, PROJECTTREE, laurent@684: POUINSTANCEVARIABLESPANEL, LIBRARYTREE) lbessard@163: elif isinstance(window, (Viewer, TextViewer)): lbessard@163: event = wx.KeyEvent(wx.EVT_CHAR._getEvtType()) lbessard@163: event.m_keyCode = wx.WXK_DELETE lbessard@163: window.ProcessEvent(event) lbessard@163: Laurent@738: def OnFindMenu(self, event): Laurent@738: if not self.FindDialog.IsShown(): Laurent@738: self.FindDialog.Show() Laurent@738: Laurent@738: def CloseFindInPouDialog(self): Laurent@738: selected = self.TabsOpened.GetSelection() Laurent@738: if selected == -1 and self.FindDialog.IsShown(): Laurent@738: self.FindDialog.Hide() Laurent@738: Laurent@738: def OnFindNextMenu(self, event): Laurent@738: self.FindInPou(1) Laurent@738: Laurent@738: def OnFindPreviousMenu(self, event): Laurent@738: self.FindInPou(-1) Laurent@738: Laurent@738: def FindInPou(self, direction, search_params=None): Laurent@738: if search_params is not None: Laurent@738: self.SearchParams = search_params Laurent@738: selected = self.TabsOpened.GetSelection() Laurent@738: if selected != -1: Laurent@738: window = self.TabsOpened.GetPage(selected) Laurent@738: window.Find(direction, self.SearchParams) Laurent@738: laurent@566: def OnSearchInProjectMenu(self, event): laurent@566: dialog = SearchInProjectDialog(self) laurent@566: if dialog.ShowModal() == wx.ID_OK: laurent@566: criteria = dialog.GetCriteria() laurent@566: result = self.Controler.SearchInProject(criteria) laurent@566: self.ClearSearchResults() laurent@566: self.SearchResultPanel.SetSearchResults(criteria, result) laurent@566: self.BottomNoteBook.SetSelection(self.BottomNoteBook.GetPageIndex(self.SearchResultPanel)) laurent@566: lbessard@163: #------------------------------------------------------------------------------- lbessard@332: # Display Menu Functions lbessard@332: #------------------------------------------------------------------------------- lbessard@332: lbessard@332: def RefreshDisplayMenu(self): laurent@407: if self.Controler is not None: lbessard@332: if self.TabsOpened.GetPageCount() > 0: lbessard@332: self.DisplayMenu.Enable(wx.ID_REFRESH, True) lbessard@332: selected = self.TabsOpened.GetSelection() lbessard@332: if selected != -1: lbessard@332: window = self.TabsOpened.GetPage(selected) lbessard@332: if isinstance(window, Viewer): lbessard@332: self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, True) lbessard@332: zoommenu = self.DisplayMenu.FindItemById(wx.ID_ZOOM_FIT).GetSubMenu() lbessard@332: zoomitem = zoommenu.FindItemByPosition(window.GetScale()) lbessard@332: zoomitem.Check(True) lbessard@332: else: lbessard@332: self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, False) lbessard@332: else: lbessard@332: self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, False) lbessard@332: else: lbessard@332: self.DisplayMenu.Enable(wx.ID_REFRESH, False) lbessard@332: self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, False) laurent@407: if self.EnableDebug: greg@352: self.DisplayMenu.Enable(wx.ID_CLEAR, True) lbessard@332: else: lbessard@332: self.DisplayMenu.Enable(wx.ID_REFRESH, False) laurent@407: if self.EnableDebug: greg@352: self.DisplayMenu.Enable(wx.ID_CLEAR, False) lbessard@332: self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, False) lbessard@332: lbessard@332: def OnRefreshMenu(self, event): laurent@407: self.RefreshEditor() lbessard@332: lbessard@332: def OnClearErrorsMenu(self, event): lbessard@332: self.ClearErrors() lbessard@332: lbessard@332: def GenerateZoomFunction(self, idx): lbessard@332: def ZoomFunction(event): lbessard@332: selected = self.TabsOpened.GetSelection() lbessard@332: if selected != -1: lbessard@332: window = self.TabsOpened.GetPage(selected) lbessard@332: window.SetScale(idx) greg@361: window.RefreshVisibleElements() greg@361: window.RefreshScrollBars() lbessard@332: event.Skip() lbessard@332: return ZoomFunction lbessard@332: laurent@673: def OnResetPerspective(self, event): laurent@676: self.ResetPerspective() lbessard@332: lbessard@332: #------------------------------------------------------------------------------- lbessard@163: # Project Editor Panels Management Functions lbessard@163: #------------------------------------------------------------------------------- lbessard@163: laurent@390: def OnPageDragged(self, event): laurent@390: wx.CallAfter(self.RefreshTabCtrlEvent) laurent@390: event.Skip() laurent@390: laurent@618: def OnAllowNotebookDnD(self, event): laurent@618: event.Allow() laurent@618: laurent@390: def RefreshTabCtrlEvent(self): Edouard@685: auitabctrl = [] Edouard@685: for child in self.TabsOpened.GetChildren(): Edouard@685: if isinstance(child, wx.aui.AuiTabCtrl): Edouard@685: auitabctrl.append(child) Edouard@685: if child not in self.AuiTabCtrl: Edouard@685: child.Bind(wx.EVT_LEFT_DCLICK, self.GetTabsOpenedDClickFunction(child)) Edouard@685: self.AuiTabCtrl = auitabctrl Edouard@685: if self.TabsOpened.GetPageCount() == 0: Edouard@685: pane = self.AUIManager.GetPane(self.TabsOpened) Edouard@685: if pane.IsMaximized(): Edouard@685: self.AUIManager.RestorePane(pane) Edouard@685: self.AUIManager.Update() laurent@390: laurent@687: def EnsureTabVisible(self, tab): laurent@687: notebook = tab.GetParent() laurent@687: notebook.SetSelection(notebook.GetPageIndex(tab)) laurent@390: laurent@631: def OnPouSelectedChanging(self, event): laurent@673: if not self.Starting: laurent@673: selected = self.TabsOpened.GetSelection() laurent@673: if selected >= 0: laurent@673: window = self.TabsOpened.GetPage(selected) laurent@673: if not window.IsDebugging(): laurent@673: window.ResetBuffer() laurent@673: event.Skip() laurent@673: laurent@673: def OnPouSelectedChanged(self, event): laurent@673: if not self.Starting: laurent@673: selected = self.TabsOpened.GetSelection() laurent@673: if selected >= 0: laurent@673: window = self.TabsOpened.GetPage(selected) laurent@684: tagname = window.GetTagName() laurent@673: if not window.IsDebugging(): laurent@684: wx.CallAfter(self.SelectProjectTreeItem, tagname) laurent@684: wx.CallAfter(self.PouInstanceVariablesPanel.SetPouType, tagname) laurent@673: window.RefreshView() laurent@687: self.EnsureTabVisible(self.LibraryPanel) laurent@673: else: laurent@684: instance_path = window.GetInstancePath() laurent@687: if tagname == "": laurent@687: instance_path = instance_path.rsplit(".", 1)[0] laurent@687: tagname = self.Controler.GetPouInstanceTagName(instance_path, self.EnableDebug) laurent@687: self.EnsureTabVisible(self.DebugVariablePanel) laurent@684: wx.CallAfter(self.PouInstanceVariablesPanel.SetPouType, tagname, instance_path) laurent@673: wx.CallAfter(self._Refresh, FILEMENU, EDITMENU, DISPLAYMENU, EDITORTOOLBAR) Laurent@734: event.Skip() Laurent@708: laurent@673: def RefreshEditor(self): laurent@631: selected = self.TabsOpened.GetSelection() laurent@631: if selected >= 0: laurent@631: window = self.TabsOpened.GetPage(selected) Laurent@703: tagname = window.GetTagName() laurent@407: if not window.IsDebugging(): Laurent@703: self.SelectProjectTreeItem(tagname) Laurent@703: self.PouInstanceVariablesPanel.SetPouType(tagname) laurent@673: else: Laurent@703: instance_path = window.GetInstancePath() Laurent@703: if tagname == "": Laurent@703: instance_path = instance_path.rsplit(".", 1)[0] Laurent@703: tagname = self.Controler.GetPouInstanceTagName(instance_path, self.EnableDebug) Laurent@703: self.PouInstanceVariablesPanel.SetPouType(tagname, instance_path) Edouard@685: for child in self.TabsOpened.GetChildren(): Edouard@685: if isinstance(child, wx.aui.AuiTabCtrl): Edouard@685: active_page = child.GetActivePage() Edouard@685: if active_page >= 0: Edouard@685: window = child.GetWindowFromIdx(active_page) Edouard@685: window.RefreshView() laurent@673: self._Refresh(FILEMENU, EDITMENU, DISPLAYMENU, EDITORTOOLBAR) laurent@586: lbessard@163: def RefreshEditorNames(self, old_tagname, new_tagname): lbessard@235: for i in xrange(self.TabsOpened.GetPageCount()): lbessard@235: editor = self.TabsOpened.GetPage(i) lbessard@163: if editor.GetTagName() == old_tagname: lbessard@163: editor.SetTagName(new_tagname) laurent@586: lbessard@163: def IsOpened(self, tagname): lbessard@235: for idx in xrange(self.TabsOpened.GetPageCount()): lbessard@235: if self.TabsOpened.GetPage(idx).IsViewing(tagname): lbessard@163: return idx lbessard@163: return None lbessard@163: lbessard@163: def RefreshPageTitles(self): lbessard@235: for idx in xrange(self.TabsOpened.GetPageCount()): lbessard@235: window = self.TabsOpened.GetPage(idx) laurent@586: icon = window.GetIcon() laurent@586: if icon is not None: laurent@586: self.SetPageBitmap(idx, icon) laurent@586: self.TabsOpened.SetPageText(idx, window.GetTitle()) lbessard@163: lbessard@335: def GetTabsOpenedDClickFunction(self, tabctrl): lbessard@331: def OnTabsOpenedDClick(event): lbessard@335: pos = event.GetPosition() lbessard@335: if tabctrl.TabHitTest(pos.x, pos.y, None): lbessard@335: pane = self.AUIManager.GetPane(self.TabsOpened) lbessard@335: if pane.IsMaximized(): lbessard@335: self.AUIManager.RestorePane(pane) lbessard@335: else: lbessard@335: self.AUIManager.MaximizePane(pane) lbessard@335: self.AUIManager.Update() lbessard@331: event.Skip() lbessard@331: return OnTabsOpenedDClick lbessard@163: lbessard@163: #------------------------------------------------------------------------------- lbessard@239: # Types Tree Management Functions lbessard@163: #------------------------------------------------------------------------------- lbessard@163: laurent@684: def RefreshProjectTree(self): laurent@407: infos = self.Controler.GetProjectInfos() laurent@684: root = self.ProjectTree.GetRootItem() lbessard@163: if not root.IsOk(): laurent@684: root = self.ProjectTree.AddRoot(infos["name"]) laurent@684: self.GenerateProjectTreeBranch(root, infos) laurent@684: self.ProjectTree.Expand(root) lbessard@235: laurent@390: def ResetSelectedItem(self): laurent@390: self.SelectedItem = None laurent@390: laurent@684: def GenerateProjectTreeBranch(self, root, infos): lbessard@163: to_delete = [] laurent@391: item_name = infos["name"] laurent@512: if infos["type"] in ITEMS_UNEDITABLE: laurent@684: if len(infos["values"]) == 1: laurent@684: return self.GenerateProjectTreeBranch(root, infos["values"][0]) laurent@684: item_name = _(item_name) laurent@684: self.ProjectTree.SetItemText(root, item_name) laurent@687: self.ProjectTree.SetPyData(root, infos) laurent@566: highlight_colours = self.Highlights.get(infos.get("tagname", None), (wx.WHITE, wx.BLACK)) laurent@684: self.ProjectTree.SetItemBackgroundColour(root, highlight_colours[0]) laurent@684: self.ProjectTree.SetItemTextColour(root, highlight_colours[1]) lbessard@235: if infos["type"] == ITEM_POU: laurent@684: self.ProjectTree.SetItemImage(root, self.TreeImageDict[self.Controler.GetPouBodyType(infos["name"])]) laurent@687: elif infos.has_key("icon") and infos["icon"] is not None: Laurent@714: icon_name = infos["icon"] Laurent@714: if not self.TreeImageDict.has_key(icon_name): Laurent@714: self.TreeImageDict[icon_name] = self.TreeImageList.Add(GetBitmap(icon_name)) Laurent@714: self.ProjectTree.SetItemImage(root, self.TreeImageDict[icon_name]) laurent@687: elif self.TreeImageDict.has_key(infos["type"]): laurent@684: self.ProjectTree.SetItemImage(root, self.TreeImageDict[infos["type"]]) laurent@687: lbessard@163: if wx.VERSION >= (2, 6, 0): laurent@684: item, root_cookie = self.ProjectTree.GetFirstChild(root) laurent@390: else: laurent@684: item, root_cookie = self.ProjectTree.GetFirstChild(root, 0) lbessard@163: for values in infos["values"]: laurent@684: if values["type"] not in ITEMS_UNEDITABLE or len(values["values"]) > 0: laurent@684: if not item.IsOk(): laurent@684: item = self.ProjectTree.AppendItem(root, "") laurent@684: if wx.Platform != '__WXMSW__': laurent@684: item, root_cookie = self.ProjectTree.GetNextChild(root, root_cookie) laurent@684: self.GenerateProjectTreeBranch(item, values) laurent@684: item, root_cookie = self.ProjectTree.GetNextChild(root, root_cookie) lbessard@163: while item.IsOk(): lbessard@163: to_delete.append(item) laurent@684: item, root_cookie = self.ProjectTree.GetNextChild(root, root_cookie) lbessard@163: for item in to_delete: laurent@684: self.ProjectTree.Delete(item) laurent@684: laurent@684: def SelectProjectTreeItem(self, tagname): laurent@684: if self.ProjectTree is not None: laurent@684: root = self.ProjectTree.GetRootItem() laurent@635: if root.IsOk(): laurent@635: words = tagname.split("::") laurent@635: if words[0] == "D": laurent@684: return self.RecursiveProjectTreeItemSelection(root, [(words[1], ITEM_DATATYPE)]) laurent@635: elif words[0] == "P": laurent@684: return self.RecursiveProjectTreeItemSelection(root, [(words[1], ITEM_POU)]) laurent@635: elif words[0] == "T": laurent@684: return self.RecursiveProjectTreeItemSelection(root, [(words[1], ITEM_POU), (words[2], ITEM_TRANSITION)]) laurent@635: elif words[0] == "A": laurent@684: return self.RecursiveProjectTreeItemSelection(root, [(words[1], ITEM_POU), (words[2], ITEM_ACTION)]) laurent@635: elif words[0] == "C": laurent@684: return self.RecursiveProjectTreeItemSelection(root, [(words[1], ITEM_CONFIGURATION)]) laurent@635: elif words[0] == "R": laurent@684: return self.RecursiveProjectTreeItemSelection(root, [(words[1], ITEM_CONFIGURATION), (words[2], ITEM_RESOURCE)]) lbessard@231: return False lbessard@231: laurent@684: def RecursiveProjectTreeItemSelection(self, root, items): lbessard@122: found = False laurent@635: if wx.VERSION >= (2, 6, 0): laurent@684: item, root_cookie = self.ProjectTree.GetFirstChild(root) laurent@635: else: laurent@684: item, root_cookie = self.ProjectTree.GetFirstChild(root, 0) laurent@635: while item.IsOk() and not found: laurent@687: item_infos = self.ProjectTree.GetPyData(item) laurent@687: if (item_infos["name"].split(":")[-1].strip(), item_infos["type"]) == items[0]: laurent@635: if len(items) == 1: laurent@635: self.SelectedItem = item Laurent@718: wx.CallAfter(self.ProjectTree.SelectItem, item) laurent@635: wx.CallAfter(self.ResetSelectedItem) laurent@635: return True laurent@635: else: laurent@684: found = self.RecursiveProjectTreeItemSelection(item, items[1:]) lbessard@122: else: laurent@684: found = self.RecursiveProjectTreeItemSelection(item, items) laurent@684: item, root_cookie = self.ProjectTree.GetNextChild(root, root_cookie) lbessard@122: return found lbessard@122: laurent@684: def OnProjectTreeBeginDrag(self, event): lbessard@131: if wx.Platform == '__WXMSW__': lbessard@134: self.SelectedItem = event.GetItem() laurent@687: if self.SelectedItem is not None and self.ProjectTree.GetPyData(self.SelectedItem)["type"] == ITEM_POU: laurent@684: block_name = self.ProjectTree.GetItemText(self.SelectedItem) laurent@407: block_type = self.Controler.GetPouType(block_name) lbessard@53: if block_type != "program": lbessard@64: data = wx.TextDataObject(str((block_name, block_type, ""))) laurent@684: dragSource = wx.DropSource(self.ProjectTree) lbessard@53: dragSource.SetData(data) lbessard@53: dragSource.DoDragDrop() lbessard@122: self.ResetSelectedItem() lbessard@7: laurent@684: def OnProjectTreeItemBeginEdit(self, event): lbessard@163: selected = event.GetItem() laurent@687: if self.ProjectTree.GetPyData(selected)["type"] in ITEMS_UNEDITABLE: lbessard@163: event.Veto() lbessard@163: else: lbessard@163: event.Skip() lbessard@107: laurent@684: def OnProjectTreeItemEndEdit(self, event): lbessard@6: message = None lbessard@6: abort = False etisserant@0: new_name = event.GetLabel() etisserant@0: if new_name != "": lbessard@6: if not TestIdentifier(new_name): laurent@391: message = _("\"%s\" is not a valid identifier!")%new_name lbessard@6: elif new_name.upper() in IEC_KEYWORDS: laurent@391: message = _("\"%s\" is a keyword. It can't be used!")%new_name lbessard@6: else: etisserant@0: item = event.GetItem() laurent@684: old_name = self.ProjectTree.GetItemText(item) laurent@687: item_infos = self.ProjectTree.GetPyData(item) laurent@687: if item_infos["type"] == ITEM_PROJECT: lbessard@56: self.Controler.SetProjectProperties(name = new_name) laurent@687: elif item_infos["type"] == ITEM_DATATYPE: laurent@407: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectDataTypeNames() if name != old_name]: laurent@391: message = _("\"%s\" data type already exists!")%new_name lbessard@125: abort = True lbessard@125: if not abort: lbessard@125: self.Controler.ChangeDataTypeName(old_name, new_name) lbessard@145: self.RefreshEditorNames(self.Controler.ComputeDataTypeName(old_name), lbessard@145: self.Controler.ComputeDataTypeName(new_name)) lbessard@125: self.RefreshPageTitles() laurent@687: elif item_infos["type"] == ITEM_POU: laurent@407: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames() if name != old_name]: laurent@391: message = _("\"%s\" pou already exists!")%new_name lbessard@6: abort = True laurent@407: elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables()]: b@427: 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) lbessard@64: if messageDialog.ShowModal() == wx.ID_NO: lbessard@6: abort = True lbessard@6: messageDialog.Destroy() lbessard@6: if not abort: lbessard@6: self.Controler.ChangePouName(old_name, new_name) lbessard@145: self.RefreshEditorNames(self.Controler.ComputePouName(old_name), lbessard@145: self.Controler.ComputePouName(new_name)) laurent@676: self.RefreshLibraryPanel() lbessard@121: self.RefreshPageTitles() laurent@687: elif item_infos["type"] == ITEM_TRANSITION: laurent@407: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]: b@427: message = _("A POU named \"%s\" already exists!")%new_name laurent@407: elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name) if name != old_name]: laurent@391: message = _("A variable with \"%s\" as name already exists in this pou!")%new_name lbessard@6: else: laurent@687: words = item_infos["tagname"].split("::") laurent@687: self.Controler.ChangePouTransitionName(words[1], old_name, new_name) laurent@687: self.RefreshEditorNames(self.Controler.ComputePouTransitionName(words[1], old_name), laurent@687: self.Controler.ComputePouTransitionName(words[1], new_name)) lbessard@121: self.RefreshPageTitles() laurent@687: elif item_infos["type"] == ITEM_ACTION: laurent@407: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]: b@427: message = _("A POU named \"%s\" already exists!")%new_name laurent@407: elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name) if name != old_name]: laurent@391: message = _("A variable with \"%s\" as name already exists in this pou!")%new_name lbessard@6: else: laurent@687: words = item_infos["tagname"].split("::") laurent@687: self.Controler.ChangePouActionName(words[1], old_name, new_name) laurent@687: self.RefreshEditorNames(self.Controler.ComputePouActionName(words[1], old_name), laurent@687: self.Controler.ComputePouActionName(words[1], new_name)) lbessard@121: self.RefreshPageTitles() laurent@687: elif item_infos["type"] == ITEM_CONFIGURATION: laurent@407: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames() if name != old_name]: laurent@391: message = _("\"%s\" config already exists!")%new_name lbessard@107: abort = True laurent@407: elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]: b@427: 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) lbessard@107: if messageDialog.ShowModal() == wx.ID_NO: lbessard@107: abort = True lbessard@107: messageDialog.Destroy() laurent@407: elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables()]: b@427: 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) lbessard@107: if messageDialog.ShowModal() == wx.ID_NO: lbessard@107: abort = True lbessard@107: messageDialog.Destroy() lbessard@107: if not abort: lbessard@107: self.Controler.ChangeConfigurationName(old_name, new_name) lbessard@145: self.RefreshEditorNames(self.Controler.ComputeConfigurationName(old_name), lbessard@145: self.Controler.ComputeConfigurationName(new_name)) lbessard@121: self.RefreshPageTitles() laurent@687: elif item_infos["type"] == ITEM_RESOURCE: laurent@407: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames()]: laurent@391: message = _("\"%s\" config already exists!")%new_name lbessard@107: abort = True laurent@407: elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]: b@427: 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) lbessard@107: if messageDialog.ShowModal() == wx.ID_NO: lbessard@107: abort = True lbessard@107: messageDialog.Destroy() laurent@407: elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables()]: b@427: 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) lbessard@107: if messageDialog.ShowModal() == wx.ID_NO: lbessard@107: abort = True lbessard@107: messageDialog.Destroy() lbessard@107: if not abort: laurent@687: words = item_infos["tagname"].split("::") laurent@687: self.Controler.ChangeConfigurationResourceName(words[1], old_name, new_name) laurent@687: self.RefreshEditorNames(self.Controler.ComputeConfigurationResourceName(words[1], old_name), laurent@687: self.Controler.ComputeConfigurationResourceName(words[1], new_name)) lbessard@121: self.RefreshPageTitles() lbessard@6: if message or abort: lbessard@6: if message: laurent@390: self.ShowErrorMessage(message) etisserant@0: item = event.GetItem() laurent@684: wx.CallAfter(self.ProjectTree.EditLabel, item) etisserant@0: event.Veto() lbessard@6: else: laurent@684: wx.CallAfter(self.RefreshProjectTree) greg@350: self.RefreshEditor() laurent@390: self._Refresh(TITLE, FILEMENU, EDITMENU) lbessard@6: event.Skip() etisserant@0: laurent@684: def OnProjectTreeItemActivated(self, event): etisserant@0: selected = event.GetItem() laurent@684: name = self.ProjectTree.GetItemText(selected) laurent@687: item_infos = self.ProjectTree.GetPyData(selected) laurent@687: if item_infos["type"] == ITEM_PROJECT: laurent@684: self.EditProjectSettings() Laurent@700: else: Laurent@700: if item_infos["type"] in [ITEM_DATATYPE, ITEM_POU, laurent@687: ITEM_CONFIGURATION, ITEM_RESOURCE, laurent@687: ITEM_TRANSITION, ITEM_ACTION]: Laurent@700: self.EditProjectElement(item_infos["type"], item_infos["tagname"]) Laurent@700: event.Skip() lbessard@102: laurent@684: def ProjectTreeItemSelect(self, select_item): laurent@684: name = self.ProjectTree.GetItemText(select_item) laurent@687: item_infos = self.ProjectTree.GetPyData(select_item) laurent@687: if item_infos["type"] in [ITEM_DATATYPE, ITEM_POU, laurent@687: ITEM_CONFIGURATION, ITEM_RESOURCE, laurent@687: ITEM_TRANSITION, ITEM_ACTION]: laurent@687: self.EditProjectElement(item_infos["type"], item_infos["tagname"], True) laurent@687: self.PouInstanceVariablesPanel.SetPouType(item_infos["tagname"]) laurent@684: laurent@684: def OnProjectTreeLeftUp(self, event): lbessard@122: if self.SelectedItem is not None: laurent@684: self.ProjectTree.SelectItem(self.SelectedItem) laurent@684: self.ProjectTreeItemSelect(self.SelectedItem) lbessard@122: wx.CallAfter(self.ResetSelectedItem) lbessard@122: event.Skip() lbessard@122: laurent@684: def OnProjectTreeItemSelected(self, event): laurent@684: self.ProjectTreeItemSelect(event.GetItem()) lbessard@235: event.Skip() lbessard@235: laurent@684: def OnProjectTreeItemChanging(self, event): laurent@687: if self.ProjectTree.GetPyData(event.GetItem())["type"] not in ITEMS_UNEDITABLE and self.SelectedItem is None: lbessard@122: self.SelectedItem = event.GetItem() lbessard@122: event.Veto() lbessard@122: else: lbessard@122: event.Skip() lbessard@121: laurent@586: def EditProjectElement(self, element, tagname, onlyopened = False): lbessard@121: openedidx = self.IsOpened(tagname) lbessard@121: if openedidx is not None: lbessard@235: old_selected = self.TabsOpened.GetSelection() lbessard@121: if old_selected != openedidx: lbessard@121: if old_selected >= 0: lbessard@235: self.TabsOpened.GetPage(old_selected).ResetBuffer() lbessard@235: self.TabsOpened.SetSelection(openedidx) laurent@660: self._Refresh(FILEMENU, EDITMENU, EDITORTOOLBAR, PAGETITLES) lbessard@121: elif not onlyopened: laurent@586: new_window = None laurent@586: if element == ITEM_CONFIGURATION: lbessard@235: new_window = ConfigurationEditor(self.TabsOpened, tagname, self, self.Controler) Laurent@714: new_window.SetIcon(GetBitmap("CONFIGURATION")) lbessard@337: self.AddPage(new_window, "") laurent@586: elif element == ITEM_RESOURCE: lbessard@235: new_window = ResourceEditor(self.TabsOpened, tagname, self, self.Controler) Laurent@714: new_window.SetIcon(GetBitmap("RESOURCE")) lbessard@337: self.AddPage(new_window, "") laurent@586: elif element in [ITEM_POU, ITEM_TRANSITION, ITEM_ACTION]: laurent@407: bodytype = self.Controler.GetEditedElementBodyType(tagname) lbessard@235: if bodytype == "FBD": lbessard@235: new_window = Viewer(self.TabsOpened, tagname, self, self.Controler) lbessard@235: new_window.RefreshScaling(False) lbessard@235: elif bodytype == "LD": lbessard@235: new_window = LD_Viewer(self.TabsOpened, tagname, self, self.Controler) lbessard@235: new_window.RefreshScaling(False) lbessard@235: elif bodytype == "SFC": lbessard@235: new_window = SFC_Viewer(self.TabsOpened, tagname, self, self.Controler) lbessard@235: new_window.RefreshScaling(False) lbessard@235: else: lbessard@235: new_window = TextViewer(self.TabsOpened, tagname, self, self.Controler) lbessard@249: new_window.SetTextSyntax(bodytype) lbessard@235: if bodytype == "IL": lbessard@235: new_window.SetKeywords(IL_KEYWORDS) lbessard@235: else: lbessard@235: new_window.SetKeywords(ST_KEYWORDS) laurent@586: if element == ITEM_POU: laurent@586: pou_type = self.Controler.GetEditedElementType(tagname)[1].upper() Laurent@714: icon = GetBitmap(pou_type, bodytype) laurent@586: elif element == ITEM_TRANSITION: Laurent@714: icon = GetBitmap("TRANSITION", bodytype) laurent@586: elif element == ITEM_ACTION: Laurent@714: icon = GetBitmap("ACTION", bodytype) laurent@586: new_window.SetIcon(icon) lbessard@337: self.AddPage(new_window, "") laurent@586: elif element == ITEM_DATATYPE: laurent@451: new_window = DataTypeEditor(self.TabsOpened, tagname, self, self.Controler) Laurent@714: new_window.SetIcon(GetBitmap("DATATYPE")) lbessard@337: self.AddPage(new_window, "") laurent@586: elif isinstance(element, EditorPanel): laurent@586: new_window = element laurent@586: self.AddPage(element, "") laurent@586: if new_window is not None: laurent@675: project_infos = self.GetProjectConfiguration() laurent@675: if project_infos.has_key("editors_state"): laurent@675: state = project_infos["editors_state"].get(tagname) laurent@675: if state is not None: laurent@675: wx.CallAfter(new_window.SetState, state) laurent@675: laurent@586: openedidx = self.IsOpened(tagname) laurent@586: old_selected = self.TabsOpened.GetSelection() laurent@586: if old_selected != openedidx: laurent@586: if old_selected >= 0: laurent@586: self.TabsOpened.GetPage(old_selected).ResetBuffer() laurent@586: for i in xrange(self.TabsOpened.GetPageCount()): laurent@586: window = self.TabsOpened.GetPage(i) laurent@586: if window == new_window: laurent@586: self.TabsOpened.SetSelection(i) laurent@586: window.SetFocus() laurent@586: self.RefreshPageTitles() laurent@673: return new_window etisserant@0: laurent@684: def OnProjectTreeRightUp(self, event): lbessard@159: if wx.Platform == '__WXMSW__': lbessard@163: item = event.GetItem() lbessard@163: else: laurent@684: item, flags = self.ProjectTree.HitTest(wx.Point(event.GetX(), event.GetY())) laurent@684: self.ProjectTree.SelectItem(item) laurent@684: self.ProjectTreeItemSelect(item) laurent@684: name = self.ProjectTree.GetItemText(item) laurent@687: item_infos = self.ProjectTree.GetPyData(item) laurent@666: laurent@666: menu = None Laurent@712: if item_infos["type"] in ITEMS_UNEDITABLE + [ITEM_PROJECT]: Laurent@712: if item_infos["type"] == ITEM_PROJECT: Laurent@712: name = "Project" Laurent@712: else: Laurent@712: name = UNEDITABLE_NAMES_DICT[name] laurent@666: lbessard@163: if name == "Data Types": lbessard@163: menu = wx.Menu(title='') lbessard@163: new_id = wx.NewId() laurent@391: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add DataType")) lbessard@163: self.Bind(wx.EVT_MENU, self.OnAddDataTypeMenu, id=new_id) laurent@666: Laurent@712: elif name in ["Functions", "Function Blocks", "Programs", "Project"]: lbessard@163: menu = wx.Menu(title='') Laurent@712: Laurent@712: if name != "Project": Laurent@712: new_id = wx.NewId() Laurent@712: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add POU")) Laurent@712: self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction({"Functions" : "function", "Function Blocks" : "functionBlock", "Programs" : "program"}[name]), id=new_id) b@428: laurent@447: new_id = wx.NewId() laurent@447: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Paste POU")) laurent@447: self.Bind(wx.EVT_MENU, self.OnPastePou, id=new_id) b@428: if self.GetCopyBuffer() is None: laurent@447: menu.Enable(new_id, False) b@428: lbessard@163: elif name == "Configurations": lbessard@163: menu = wx.Menu(title='') lbessard@163: new_id = wx.NewId() laurent@391: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Configuration")) lbessard@163: self.Bind(wx.EVT_MENU, self.OnAddConfigurationMenu, id=new_id) laurent@666: lbessard@163: elif name == "Transitions": lbessard@163: menu = wx.Menu(title='') lbessard@163: new_id = wx.NewId() laurent@391: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Transition")) laurent@687: parent = self.ProjectTree.GetItemParent(item)["type"] laurent@684: parent_type = self.ProjectTree.GetPyData(parent) lbessard@163: while parent_type != ITEM_POU: laurent@684: parent = self.ProjectTree.GetItemParent(parent) laurent@687: parent_type = self.ProjectTree.GetPyData(parent)["type"] laurent@684: self.Bind(wx.EVT_MENU, self.GenerateAddTransitionFunction(self.ProjectTree.GetItemText(parent)), id=new_id) laurent@666: lbessard@163: elif name == "Actions": lbessard@163: menu = wx.Menu(title='') lbessard@163: new_id = wx.NewId() laurent@391: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Action")) laurent@684: parent = self.ProjectTree.GetItemParent(item) laurent@687: parent_type = self.ProjectTree.GetPyData(parent)["type"] lbessard@163: while parent_type != ITEM_POU: laurent@684: parent = self.ProjectTree.GetItemParent(parent) laurent@687: parent_type = self.ProjectTree.GetPyData(parent)["type"] laurent@684: self.Bind(wx.EVT_MENU, self.GenerateAddActionFunction(self.ProjectTree.GetItemText(parent)), id=new_id) laurent@666: lbessard@163: elif name == "Resources": lbessard@163: menu = wx.Menu(title='') lbessard@163: new_id = wx.NewId() laurent@391: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Resource")) laurent@684: parent = self.ProjectTree.GetItemParent(item) laurent@687: parent_type = self.ProjectTree.GetPyData(parent)["type"] laurent@687: while parent_type not in [ITEM_CONFIGURATION, ITEM_PROJECT]: laurent@684: parent = self.ProjectTree.GetItemParent(parent) laurent@687: parent_type = self.ProjectTree.GetPyData(parent)["type"] laurent@687: if parent_type == ITEM_PROJECT: laurent@687: parent_name = None laurent@687: else: laurent@687: parent_name = self.ProjectTree.GetItemText(parent) laurent@687: self.Bind(wx.EVT_MENU, self.GenerateAddResourceFunction(parent_name), id=new_id) laurent@666: laurent@666: else: laurent@687: if item_infos["type"] == ITEM_POU: laurent@666: menu = wx.Menu(title='') laurent@666: if self.Controler.GetPouBodyType(name) == "SFC": laurent@666: new_id = wx.NewId() laurent@666: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Transition")) laurent@666: self.Bind(wx.EVT_MENU, self.GenerateAddTransitionFunction(name), id=new_id) laurent@666: new_id = wx.NewId() laurent@666: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Action")) laurent@666: self.Bind(wx.EVT_MENU, self.GenerateAddActionFunction(name), id=new_id) laurent@666: menu.AppendSeparator() laurent@666: laurent@666: new_id = wx.NewId() laurent@666: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Copy POU")) laurent@666: self.Bind(wx.EVT_MENU, self.OnCopyPou, id=new_id) laurent@666: laurent@666: pou_type = self.Controler.GetPouType(name) laurent@666: if pou_type in ["function", "functionBlock"]: laurent@666: change_menu = wx.Menu(title='') laurent@666: if pou_type == "function": laurent@666: new_id = wx.NewId() laurent@666: AppendMenu(change_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Function Block")) laurent@666: self.Bind(wx.EVT_MENU, self.GenerateChangePouTypeFunction(name, "functionBlock"), id=new_id) laurent@666: new_id = wx.NewId() laurent@666: AppendMenu(change_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Program")) laurent@666: self.Bind(wx.EVT_MENU, self.GenerateChangePouTypeFunction(name, "program"), id=new_id) laurent@666: menu.AppendMenu(wx.NewId(), _("Change POU Type To"), change_menu) laurent@666: new_id = wx.NewId() laurent@666: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Rename")) laurent@666: self.Bind(wx.EVT_MENU, self.OnRenamePouMenu, id=new_id) laurent@666: laurent@687: elif item_infos["type"] == ITEM_CONFIGURATION: laurent@666: menu = wx.Menu(title='') laurent@666: new_id = wx.NewId() laurent@666: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Resource")) laurent@666: self.Bind(wx.EVT_MENU, self.GenerateAddResourceFunction(name), id=new_id) laurent@666: laurent@687: elif item_infos["type"] in [ITEM_DATATYPE, ITEM_TRANSITION, ITEM_ACTION, ITEM_RESOURCE]: laurent@666: menu = wx.Menu(title='') laurent@666: laurent@666: if menu is not None: laurent@666: new_id = wx.NewId() laurent@666: AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Delete")) laurent@666: self.Bind(wx.EVT_MENU, self.OnDeleteMenu, id=new_id) laurent@666: laurent@666: if menu is not None: laurent@666: self.PopupMenu(menu) laurent@666: menu.Destroy() laurent@666: lbessard@163: event.Skip() lbessard@163: lbessard@163: lbessard@163: #------------------------------------------------------------------------------- lbessard@239: # Instances Tree Management Functions lbessard@235: #------------------------------------------------------------------------------- lbessard@235: laurent@684: def GetTreeImage(self, var_class): laurent@684: return self.TreeImageDict[var_class] laurent@684: laurent@684: def RefreshPouInstanceVariablesPanel(self): laurent@684: self.PouInstanceVariablesPanel.RefreshView() lbessard@341: laurent@673: def OpenDebugViewer(self, instance_category, instance_path, instance_type): laurent@673: openedidx = self.IsOpened(instance_path) laurent@673: if openedidx is not None: laurent@673: old_selected = self.TabsOpened.GetSelection() laurent@673: if old_selected != openedidx: laurent@673: if old_selected >= 0: laurent@673: self.TabsOpened.GetPage(old_selected).ResetBuffer() laurent@673: self.TabsOpened.SetSelection(openedidx) laurent@673: laurent@673: elif instance_category in ITEMS_VARIABLE: laurent@673: if self.Controler.IsOfType(instance_type, "ANY_NUM", True) or\ laurent@673: self.Controler.IsOfType(instance_type, "ANY_BIT", True): laurent@673: laurent@673: return self.OpenGraphicViewer(instance_path) laurent@673: laurent@673: else: laurent@673: bodytype = self.Controler.GetEditedElementBodyType(instance_type, True) laurent@673: new_window = None laurent@673: if bodytype == "FBD": laurent@673: new_window = Viewer(self.TabsOpened, instance_type, self, self.Controler, True, instance_path) laurent@673: new_window.RefreshScaling(False) laurent@673: elif bodytype == "LD": laurent@673: new_window = LD_Viewer(self.TabsOpened, instance_type, self, self.Controler, True, instance_path) laurent@673: new_window.RefreshScaling(False) laurent@673: elif bodytype == "SFC": laurent@673: new_window = SFC_Viewer(self.TabsOpened, instance_type, self, self.Controler, True, instance_path) laurent@673: new_window.RefreshScaling(False) laurent@673: else: laurent@673: new_window = TextViewer(self.TabsOpened, instance_type, self, self.Controler, True, instance_path) laurent@673: new_window.SetTextSyntax(bodytype) laurent@673: if bodytype == "IL": laurent@673: new_window.SetKeywords(IL_KEYWORDS) laurent@673: else: laurent@673: new_window.SetKeywords(ST_KEYWORDS) laurent@673: if new_window is not None: laurent@675: project_infos = self.GetProjectConfiguration() laurent@675: if project_infos.has_key("editors_state"): laurent@675: state = project_infos["editors_state"].get(instance_path) laurent@675: if state is not None: laurent@675: wx.CallAfter(new_window.SetState, state) laurent@675: laurent@673: if instance_category in [ITEM_FUNCTIONBLOCK, ITEM_PROGRAM]: laurent@673: pou_type = self.Controler.GetEditedElementType(instance_type, True)[1].upper() Laurent@714: icon = GetBitmap(pou_type, bodytype) laurent@673: elif instance_category == ITEM_TRANSITION: Laurent@714: icon = GetBitmap("TRANSITION", bodytype) laurent@673: elif instance_category == ITEM_ACTION: Laurent@714: icon = GetBitmap("ACTION", bodytype) laurent@673: new_window.SetIcon(icon) laurent@673: self.AddPage(new_window, "") laurent@673: new_window.RefreshView() laurent@673: new_window.SetFocus() laurent@673: self.RefreshPageTitles() laurent@673: return new_window laurent@673: laurent@673: return None laurent@673: lbessard@341: def OpenGraphicViewer(self, var_path): lbessard@341: new_window = GraphicViewer(self.TabsOpened, self, self.Controler, var_path) Laurent@714: new_window.SetIcon(GetBitmap("GRAPH")) lbessard@341: self.AddPage(new_window, "") laurent@648: new_window.RefreshView() lbessard@341: new_window.SetFocus() lbessard@341: self.RefreshPageTitles() laurent@673: return new_window lbessard@301: lbessard@337: def ResetGraphicViewers(self): lbessard@337: for i in xrange(self.TabsOpened.GetPageCount()): lbessard@337: editor = self.TabsOpened.GetPage(i) lbessard@337: if isinstance(editor, GraphicViewer): lbessard@337: editor.ResetView() lbessard@337: laurent@647: def CloseObsoleteDebugTabs(self): laurent@479: if self.EnableDebug: laurent@479: idxs = range(self.TabsOpened.GetPageCount()) laurent@479: idxs.reverse() laurent@479: for idx in idxs: laurent@647: editor = self.TabsOpened.GetPage(idx) laurent@647: if editor.IsDebugging(): laurent@687: instance_infos = self.Controler.GetInstanceInfos(editor.GetInstancePath(), self.EnableDebug) laurent@684: if instance_infos is None: laurent@647: self.TabsOpened.DeletePage(idx) laurent@647: elif isinstance(editor, GraphicViewer): laurent@660: editor.ResetView(True) laurent@647: else: laurent@647: editor.RefreshView() laurent@647: self.DebugVariablePanel.UnregisterObsoleteData() laurent@479: laurent@684: def AddDebugVariable(self, iec_path, force=False): laurent@479: if self.EnableDebug: laurent@684: self.DebugVariablePanel.InsertValue(iec_path, force=force) laurent@687: self.EnsureTabVisible(self.DebugVariablePanel) laurent@479: lbessard@235: #------------------------------------------------------------------------------- laurent@676: # Library Panel Management Function laurent@676: #------------------------------------------------------------------------------- laurent@676: laurent@676: def RefreshLibraryPanel(self): laurent@676: self.LibraryPanel.RefreshTree() laurent@676: lbessard@239: #------------------------------------------------------------------------------- laurent@660: # ToolBars Management Functions laurent@660: #------------------------------------------------------------------------------- laurent@660: laurent@660: def AddToMenuToolBar(self, items): laurent@660: MenuToolBar = self.Panes["MenuToolBar"] laurent@660: if MenuToolBar.GetToolsCount() > 0: laurent@660: MenuToolBar.AddSeparator() laurent@660: for toolbar_item in items: laurent@660: if toolbar_item is None: laurent@660: MenuToolBar.AddSeparator() laurent@660: else: laurent@660: id, bitmap, help, callback = toolbar_item Laurent@714: MenuToolBar.AddSimpleTool(id=id, shortHelpString=help, bitmap=GetBitmap(bitmap)) laurent@660: if callback is not None: laurent@660: self.Bind(wx.EVT_TOOL, callback, id=id) laurent@660: MenuToolBar.Realize() Edouard@685: self.AUIManager.GetPane("MenuToolBar").BestSize(MenuToolBar.GetBestSize()) laurent@660: laurent@660: def ResetEditorToolBar(self): Edouard@685: EditorToolBar = self.Panes["EditorToolBar"] laurent@660: laurent@660: for item in self.CurrentEditorToolBar: laurent@407: if wx.VERSION >= (2, 6, 0): laurent@407: self.Unbind(wx.EVT_MENU, id=item) laurent@407: else: laurent@407: self.Disconnect(id=item, eventType=wx.wxEVT_COMMAND_MENU_SELECTED) laurent@599: laurent@660: if EditorToolBar: laurent@660: EditorToolBar.DeleteTool(item) laurent@660: laurent@660: if EditorToolBar: laurent@660: EditorToolBar.Realize() Edouard@685: self.AUIManager.GetPane("EditorToolBar").BestSize(EditorToolBar.GetBestSize()) Laurent@708: self.AUIManager.GetPane("EditorToolBar").Hide() Edouard@685: self.AUIManager.Update() lbessard@249: laurent@660: def RefreshEditorToolBar(self): laurent@407: selected = self.TabsOpened.GetSelection() laurent@660: menu = None laurent@407: if selected != -1: laurent@407: window = self.TabsOpened.GetPage(selected) Laurent@708: if isinstance(window, (Viewer, TextViewer, GraphicViewer)): Laurent@708: if not window.IsDebugging(): Laurent@708: menu = self.Controler.GetEditedElementBodyType(window.GetTagName()) Laurent@708: else: Laurent@708: menu = "debug" laurent@660: if menu is not None and menu != self.CurrentMenu: laurent@660: self.ResetEditorToolBar() laurent@660: self.CurrentMenu = menu laurent@660: self.CurrentEditorToolBar = [] Edouard@685: EditorToolBar = self.Panes["EditorToolBar"] laurent@660: if EditorToolBar: laurent@660: for radio, modes, id, method, picture, help in EditorToolBarItems[menu]: laurent@407: if modes & self.DrawingMode: laurent@407: if radio or self.DrawingMode == FREEDRAWING_MODE: Laurent@714: EditorToolBar.AddRadioTool(id, GetBitmap(picture), wx.NullBitmap, help) laurent@407: else: Laurent@714: EditorToolBar.AddSimpleTool(id, GetBitmap(picture), help) laurent@660: self.Bind(wx.EVT_MENU, getattr(self, method), id=id) laurent@660: self.CurrentEditorToolBar.append(id) laurent@660: EditorToolBar.Realize() Edouard@685: self.AUIManager.GetPane("EditorToolBar").BestSize(EditorToolBar.GetBestSize()) Laurent@708: self.AUIManager.GetPane("EditorToolBar").Show() Edouard@685: self.AUIManager.Update() Laurent@708: elif menu is None: laurent@660: self.ResetEditorToolBar() laurent@660: self.CurrentMenu = menu laurent@407: self.ResetCurrentMode() etisserant@0: lbessard@163: lbessard@163: #------------------------------------------------------------------------------- laurent@660: # EditorToolBar Items Functions lbessard@163: #------------------------------------------------------------------------------- lbessard@163: lbessard@163: def ResetCurrentMode(self): lbessard@235: selected = self.TabsOpened.GetSelection() etisserant@0: if selected != -1: lbessard@235: window = self.TabsOpened.GetPage(selected) lbessard@163: window.SetMode(MODE_SELECTION) Edouard@685: EditorToolBar = self.Panes["EditorToolBar"] laurent@660: if EditorToolBar: laurent@660: EditorToolBar.ToggleTool(ID_PLCOPENEDITOREDITORTOOLBARSELECTION, False) laurent@660: EditorToolBar.ToggleTool(ID_PLCOPENEDITOREDITORTOOLBARSELECTION, True) lbessard@163: lbessard@163: def ResetToolToggle(self, id): Edouard@685: tool = self.Panes["EditorToolBar"].FindById(id) lbessard@163: tool.SetToggle(False) lbessard@163: lbessard@163: def OnSelectionTool(self, event): lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@56: if selected != -1: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_SELECTION) laurent@575: laurent@575: def OnMotionTool(self, event): laurent@575: selected = self.TabsOpened.GetSelection() laurent@575: if selected != -1: laurent@575: self.TabsOpened.GetPage(selected).SetMode(MODE_MOTION) lbessard@163: lbessard@163: def OnCommentTool(self, event): laurent@660: self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARCOMMENT) lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@56: if selected != -1: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_COMMENT) lbessard@163: lbessard@163: def OnVariableTool(self, event): laurent@660: self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARVARIABLE) lbessard@235: selected = self.TabsOpened.GetSelection() etisserant@0: if selected != -1: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_VARIABLE) lbessard@163: lbessard@163: def OnBlockTool(self, event): laurent@660: self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARBLOCK) lbessard@235: selected = self.TabsOpened.GetSelection() etisserant@0: if selected != -1: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_BLOCK) lbessard@163: lbessard@163: def OnConnectionTool(self, event): laurent@660: self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARCONNECTION) lbessard@235: selected = self.TabsOpened.GetSelection() etisserant@0: if selected != -1: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_CONNECTION) laurent@575: lbessard@163: def OnPowerRailTool(self, event): laurent@660: self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARPOWERRAIL) lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@163: if selected != -1: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_POWERRAIL) laurent@575: lbessard@163: def OnRungTool(self, event): lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@163: if selected != -1: lbessard@235: self.TabsOpened.GetPage(selected).AddLadderRung() lbessard@163: event.Skip() lbessard@163: lbessard@163: def OnCoilTool(self, event): laurent@660: self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARCOIL) lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@163: if selected != -1: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_COIL) lbessard@163: event.Skip() lbessard@163: lbessard@163: def OnContactTool(self, event): lbessard@163: if self.DrawingMode == FREEDRAWING_MODE: laurent@660: self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARCONTACT) lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@163: if selected != -1: lbessard@163: if self.DrawingMode == FREEDRAWING_MODE: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_CONTACT) lbessard@163: else: lbessard@235: self.TabsOpened.GetPage(selected).AddLadderContact() lbessard@163: lbessard@163: def OnBranchTool(self, event): lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@163: if selected != -1: lbessard@235: self.TabsOpened.GetPage(selected).AddLadderBranch() lbessard@163: lbessard@163: def OnInitialStepTool(self, event): laurent@660: self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARINITIALSTEP) lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@163: if selected != -1: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_INITIALSTEP) lbessard@163: lbessard@163: def OnStepTool(self, event): lbessard@163: if self.GetDrawingMode() == FREEDRAWING_MODE: laurent@660: self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARSTEP) lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@163: if selected != -1: lbessard@163: if self.GetDrawingMode() == FREEDRAWING_MODE: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_STEP) lbessard@163: else: lbessard@235: self.TabsOpened.GetPage(selected).AddStep() laurent@575: lbessard@163: def OnActionBlockTool(self, event): lbessard@163: if self.GetDrawingMode() == FREEDRAWING_MODE: laurent@660: self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARACTIONBLOCK) lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@163: if selected != -1: lbessard@163: if self.GetDrawingMode() == FREEDRAWING_MODE: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_ACTION) lbessard@163: else: lbessard@235: self.TabsOpened.GetPage(selected).AddStepAction() laurent@575: lbessard@163: def OnTransitionTool(self, event): laurent@660: self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARTRANSITION) lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@163: if selected != -1: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_TRANSITION) laurent@575: lbessard@163: def OnDivergenceTool(self, event): lbessard@163: if self.GetDrawingMode() == FREEDRAWING_MODE: laurent@660: self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARDIVERGENCE) lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@163: if selected != -1: lbessard@163: if self.GetDrawingMode() == FREEDRAWING_MODE: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_DIVERGENCE) lbessard@163: else: lbessard@235: self.TabsOpened.GetPage(selected).AddDivergence() lbessard@163: lbessard@163: def OnJumpTool(self, event): lbessard@163: if self.GetDrawingMode() == FREEDRAWING_MODE: laurent@660: self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARJUMP) lbessard@235: selected = self.TabsOpened.GetSelection() lbessard@163: if selected != -1: lbessard@163: if self.GetDrawingMode() == FREEDRAWING_MODE: lbessard@235: self.TabsOpened.GetPage(selected).SetMode(MODE_JUMP) lbessard@163: else: lbessard@235: self.TabsOpened.GetPage(selected).AddJump() laurent@575: lbessard@163: lbessard@163: #------------------------------------------------------------------------------- lbessard@163: # Add Project Elements Functions lbessard@163: #------------------------------------------------------------------------------- lbessard@163: lbessard@125: def OnAddDataTypeMenu(self, event): Laurent@705: tagname = self.Controler.ProjectAddDataType() Laurent@705: if tagname is not None: Laurent@705: self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE) Laurent@705: self.EditProjectElement(ITEM_DATATYPE, tagname) Laurent@705: lbessard@163: def GenerateAddPouFunction(self, pou_type): lbessard@163: def OnAddPouMenu(event): lbessard@163: dialog = PouDialog(self, pou_type) laurent@407: dialog.SetPouNames(self.Controler.GetProjectPouNames()) laurent@407: dialog.SetPouElementNames(self.Controler.GetProjectPouVariables()) Laurent@705: dialog.SetValues({"pouName": self.Controler.GenerateNewName(None, None, "%s%%d" % pou_type)}) lbessard@163: if dialog.ShowModal() == wx.ID_OK: lbessard@163: values = dialog.GetValues() laurent@555: tagname = self.Controler.ProjectAddPou(values["pouName"], values["pouType"], values["language"]) laurent@555: if tagname is not None: laurent@684: self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, LIBRARYTREE) laurent@555: self.EditProjectElement(ITEM_POU, tagname) lbessard@163: dialog.Destroy() lbessard@163: return OnAddPouMenu lbessard@163: lbessard@163: def GenerateAddTransitionFunction(self, pou_name): lbessard@163: def OnAddTransitionMenu(event): lbessard@163: dialog = PouTransitionDialog(self) laurent@407: dialog.SetPouNames(self.Controler.GetProjectPouNames()) laurent@407: dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(pou_name)) Laurent@705: dialog.SetValues({"transitionName": self.Controler.GenerateNewName(None, None, "transition%d")}) lbessard@163: if dialog.ShowModal() == wx.ID_OK: lbessard@163: values = dialog.GetValues() laurent@555: tagname = self.Controler.ProjectAddPouTransition(pou_name, values["transitionName"], values["language"]) laurent@555: if tagname is not None: laurent@684: self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE) laurent@555: self.EditProjectElement(ITEM_TRANSITION, tagname) laurent@555: dialog.Destroy() lbessard@163: return OnAddTransitionMenu lbessard@163: lbessard@163: def GenerateAddActionFunction(self, pou_name): lbessard@163: def OnAddActionMenu(event): lbessard@163: dialog = PouActionDialog(self) laurent@407: dialog.SetPouNames(self.Controler.GetProjectPouNames()) laurent@407: dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(pou_name)) Laurent@705: dialog.SetValues({"actionName": self.Controler.GenerateNewName(None, None, "action%d")}) lbessard@163: if dialog.ShowModal() == wx.ID_OK: lbessard@163: values = dialog.GetValues() laurent@555: tagname = self.Controler.ProjectAddPouAction(pou_name, values["actionName"], values["language"]) laurent@555: if tagname is not None: laurent@684: self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE) laurent@555: self.EditProjectElement(ITEM_ACTION, tagname) lbessard@163: dialog.Destroy() lbessard@163: return OnAddActionMenu etisserant@0: etisserant@0: def OnAddConfigurationMenu(self, event): Laurent@705: tagname = self.Controler.ProjectAddConfiguration() Laurent@705: if tagname is not None: Laurent@705: self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL) Laurent@705: self.EditProjectElement(ITEM_CONFIGURATION, tagname) Laurent@705: dialog.Destroy() Laurent@705: Laurent@705: def GenerateAddResourceFunction(self, config_name): Laurent@705: def OnAddResourceMenu(event): Laurent@705: tagname = self.Controler.ProjectAddConfigurationResource(config_name) laurent@555: if tagname is not None: laurent@684: self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL) Laurent@705: self.EditProjectElement(ITEM_RESOURCE, tagname) lbessard@163: return OnAddResourceMenu lbessard@163: lbessard@275: def GenerateChangePouTypeFunction(self, name, new_type): lbessard@275: def OnChangePouTypeMenu(event): laurent@684: selected = self.ProjectTree.GetSelection() laurent@687: if self.ProjectTree.GetPyData(selected)["type"] == ITEM_POU: lbessard@275: self.Controler.ProjectChangePouType(name, new_type) laurent@684: self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, PROJECTTREE, LIBRARYTREE) lbessard@275: return OnChangePouTypeMenu lbessard@163: b@428: def OnCopyPou(self, event): laurent@684: selected = self.ProjectTree.GetSelection() laurent@684: pou_name = self.ProjectTree.GetItemText(selected) laurent@447: laurent@447: pou_xml = self.Controler.GetPouXml(pou_name) laurent@447: if pou_xml is not None: laurent@447: self.SetCopyBuffer(pou_xml) laurent@447: self._Refresh(EDITMENU) b@428: b@428: def OnPastePou(self, event): laurent@684: selected = self.ProjectTree.GetSelection() Laurent@712: Laurent@712: if self.ProjectTree.GetPyData(selected)["type"] != ITEM_PROJECT: Laurent@712: pou_type = self.ProjectTree.GetItemText(selected) Laurent@712: pou_type = UNEDITABLE_NAMES_DICT[pou_type] # one of 'Functions', 'Function Blocks' or 'Programs' Laurent@712: pou_type = {'Functions': 'function', 'Function Blocks': 'functionBlock', 'Programs': 'program'}[pou_type] Laurent@712: else: Laurent@712: pou_type = None Laurent@712: b@428: pou_xml = self.GetCopyBuffer() b@428: b@428: result = self.Controler.PastePou(pou_type, pou_xml) b@428: Laurent@712: if not isinstance(result, TupleType): b@428: message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR) b@428: message.ShowModal() b@428: message.Destroy() b@428: else: laurent@684: self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, PROJECTTREE, LIBRARYTREE) Laurent@712: self.EditProjectElement(ITEM_POU, result[0]) b@428: lbessard@275: #------------------------------------------------------------------------------- lbessard@275: # Remove Project Elements Functions lbessard@275: #------------------------------------------------------------------------------- lbessard@275: lbessard@163: def OnRemoveDataTypeMenu(self, event): laurent@684: selected = self.ProjectTree.GetSelection() laurent@687: if self.ProjectTree.GetPyData(selected)["type"] == ITEM_DATATYPE: laurent@684: name = self.ProjectTree.GetItemText(selected) laurent@407: if not self.Controler.DataTypeIsUsed(name): lbessard@163: self.Controler.ProjectRemoveDataType(name) lbessard@163: tagname = self.Controler.ComputeDataTypeName(name) lbessard@121: idx = self.IsOpened(tagname) lbessard@121: if idx is not None: lbessard@235: self.TabsOpened.DeletePage(idx) laurent@684: self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, PROJECTTREE) lbessard@163: else: laurent@407: self.ShowErrorMessage(_("\"%s\" is used by one or more POUs. It can't be removed!")) lbessard@163: lbessard@311: def OnRenamePouMenu(self, event): laurent@684: selected = self.ProjectTree.GetSelection() laurent@687: if self.ProjectTree.GetPyData(selected)["type"] == ITEM_POU: laurent@684: wx.CallAfter(self.ProjectTree.EditLabel, selected) lbessard@311: lbessard@163: def OnRemovePouMenu(self, event): laurent@684: selected = self.ProjectTree.GetSelection() laurent@687: if self.ProjectTree.GetPyData(selected)["type"] == ITEM_POU: laurent@684: name = self.ProjectTree.GetItemText(selected) laurent@407: if not self.Controler.PouIsUsed(name): lbessard@163: self.Controler.ProjectRemovePou(name) lbessard@163: tagname = self.Controler.ComputePouName(name) lbessard@163: idx = self.IsOpened(tagname) lbessard@163: if idx is not None: lbessard@235: self.TabsOpened.DeletePage(idx) laurent@684: self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE) lbessard@163: else: laurent@407: self.ShowErrorMessage(_("\"%s\" is used by one or more POUs. It can't be removed!")) lbessard@163: lbessard@163: def OnRemoveTransitionMenu(self, event): laurent@684: selected = self.ProjectTree.GetSelection() laurent@687: item_infos = self.ProjectTree.GetPyData(selected) laurent@687: if item_infos["type"] == ITEM_TRANSITION: laurent@684: transition = self.ProjectTree.GetItemText(selected) laurent@687: pou_name = item_infos["tagname"].split("::")[1] lbessard@163: self.Controler.ProjectRemovePouTransition(pou_name, transition) lbessard@163: tagname = self.Controler.ComputePouTransitionName(pou_name, transition) lbessard@163: idx = self.IsOpened(tagname) lbessard@163: if idx is not None: lbessard@235: self.TabsOpened.DeletePage(idx) laurent@684: self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE) lbessard@163: lbessard@163: def OnRemoveActionMenu(self, event): laurent@684: selected = self.ProjectTree.GetSelection() laurent@687: item_infos = self.ProjectTree.GetPyData(selected) laurent@687: if item_infos["type"] == ITEM_ACTION: laurent@684: action = self.ProjectTree.GetItemText(selected) laurent@687: pou_name = item_infos["tagname"].split("::")[1] lbessard@163: self.Controler.ProjectRemovePouAction(pou_name, action) lbessard@163: tagname = self.Controler.ComputePouActionName(pou_name, action) lbessard@163: idx = self.IsOpened(tagname) lbessard@163: if idx is not None: lbessard@235: self.TabsOpened.DeletePage(idx) laurent@684: self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE) lbessard@163: lbessard@239: def OnRemoveConfigurationMenu(self, event): laurent@684: selected = self.ProjectTree.GetSelection() laurent@687: if self.ProjectTree.GetPyData(selected)["type"] == ITEM_CONFIGURATION: laurent@684: name = self.ProjectTree.GetItemText(selected) lbessard@239: self.Controler.ProjectRemoveConfiguration(name) lbessard@239: tagname = self.Controler.ComputeConfigurationName(name) lbessard@239: idx = self.IsOpened(tagname) lbessard@239: if idx is not None: lbessard@239: self.TabsOpened.DeletePage(idx) laurent@684: self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL) lbessard@239: lbessard@163: def OnRemoveResourceMenu(self, event): laurent@684: selected = self.ProjectTree.GetSelection() laurent@687: item_infos = self.ProjectTree.GetPyData(selected) laurent@687: if item_infos["type"] == ITEM_RESOURCE: laurent@684: resource = self.ProjectTree.GetItemText(selected) laurent@687: config_name = item_infos["tagname"].split("::")[1] lbessard@163: self.Controler.ProjectRemoveConfigurationResource(config_name, resource) lbessard@163: tagname = self.Controler.ComputeConfigurationResourceName(config_name, selected) lbessard@163: idx = self.IsOpened(tagname) lbessard@163: if idx is not None: lbessard@235: self.TabsOpened.DeletePage(idx) laurent@684: self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL) greg@190: greg@190: def OnPLCOpenEditorMenu(self, event): laurent@391: wx.MessageBox(_("No documentation available.\nComing soon.")) greg@190: etisserant@0: def OnPLCOpenMenu(self, event): greg@190: open_pdf(os.path.join(CWD, "plcopen", "TC6_XML_V101.pdf")) greg@190: greg@190: def OnAboutMenu(self, event): laurent@391: OpenHtmlFrame(self,_("About PLCOpenEditor"), os.path.join(CWD, "doc","about.html"), wx.Size(350, 350)) lbessard@231: lbessard@231: lbessard@231: #------------------------------------------------------------------------------- laurent@566: # Highlights showing functions laurent@566: #------------------------------------------------------------------------------- laurent@566: laurent@566: def ShowHighlight(self, infos, start, end, highlight_type): laurent@684: self.SelectProjectTreeItem(infos[0]) lbessard@231: if infos[1] == "name": laurent@566: self.Highlights[infos[0]] = highlight_type laurent@684: self.RefreshProjectTree() laurent@684: self.ProjectTree.Unselect() lbessard@231: else: laurent@566: self.EditProjectElement(self.Controler.GetElementType(infos[0]), infos[0]) laurent@586: selected = self.TabsOpened.GetSelection() laurent@586: if selected != -1: laurent@586: viewer = self.TabsOpened.GetPage(selected) laurent@586: viewer.AddHighlight(infos[1:], start, end, highlight_type) laurent@566: laurent@566: def ShowError(self, infos, start, end): laurent@566: self.ShowHighlight(infos, start, end, ERROR_HIGHLIGHT) laurent@566: laurent@566: def ShowSearchResult(self, infos, start, end): laurent@566: self.ShowHighlight(infos, start, end, SEARCH_RESULT_HIGHLIGHT) laurent@566: laurent@566: def ClearHighlights(self, highlight_type=None): laurent@566: if highlight_type is None: laurent@566: self.Highlights = {} laurent@566: else: laurent@566: self.Highlights = dict([(name, highlight) for name, highlight in self.Highlights.iteritems() if highlight != highlight_type]) laurent@684: self.RefreshProjectTree() lbessard@235: for i in xrange(self.TabsOpened.GetPageCount()): lbessard@235: viewer = self.TabsOpened.GetPage(i) laurent@566: viewer.ClearHighlights(highlight_type) laurent@566: laurent@566: def ClearErrors(self): laurent@566: self.ClearHighlights(ERROR_HIGHLIGHT) laurent@566: laurent@566: def ClearSearchResults(self): laurent@566: self.ClearHighlights(SEARCH_RESULT_HIGHLIGHT) laurent@390: laurent@407: #------------------------------------------------------------------------------- laurent@407: # PLCOpenEditor Main Class laurent@407: #------------------------------------------------------------------------------- laurent@407: laurent@407: class PLCOpenEditor(IDEFrame): laurent@407: laurent@407: # Compatibility function for wx versions < 2.6 laurent@407: if wx.VERSION < (2, 6, 0): laurent@407: def Bind(self, event, function, id = None): laurent@407: if id is not None: laurent@407: event(self, id, function) laurent@407: else: laurent@407: event(self, function) laurent@407: laurent@407: def _init_coll_FileMenu_Items(self, parent): laurent@407: AppendMenu(parent, help='', id=wx.ID_NEW, laurent@407: kind=wx.ITEM_NORMAL, text=_(u'New\tCTRL+N')) laurent@407: AppendMenu(parent, help='', id=wx.ID_OPEN, laurent@407: kind=wx.ITEM_NORMAL, text=_(u'Open\tCTRL+O')) laurent@407: AppendMenu(parent, help='', id=wx.ID_CLOSE, laurent@407: kind=wx.ITEM_NORMAL, text=_(u'Close Tab\tCTRL+W')) laurent@407: AppendMenu(parent, help='', id=wx.ID_CLOSE_ALL, Edouard@656: kind=wx.ITEM_NORMAL, text=_(u'Close Project\tCTRL+SHIFT+W')) laurent@407: parent.AppendSeparator() laurent@407: AppendMenu(parent, help='', id=wx.ID_SAVE, laurent@407: kind=wx.ITEM_NORMAL, text=_(u'Save\tCTRL+S')) laurent@407: AppendMenu(parent, help='', id=wx.ID_SAVEAS, laurent@407: kind=wx.ITEM_NORMAL, text=_(u'Save As...\tCTRL+SHIFT+S')) laurent@407: AppendMenu(parent, help='', id=ID_PLCOPENEDITORFILEMENUGENERATE, laurent@407: kind=wx.ITEM_NORMAL, text=_(u'Generate Program\tCTRL+G')) laurent@407: parent.AppendSeparator() laurent@407: AppendMenu(parent, help='', id=wx.ID_PAGE_SETUP, Edouard@656: kind=wx.ITEM_NORMAL, text=_(u'Page Setup\tCTRL+ALT+P')) laurent@407: AppendMenu(parent, help='', id=wx.ID_PREVIEW, Edouard@656: kind=wx.ITEM_NORMAL, text=_(u'Preview\tCTRL+SHIFT+P')) laurent@407: AppendMenu(parent, help='', id=wx.ID_PRINT, Edouard@656: kind=wx.ITEM_NORMAL, text=_(u'Print\tCTRL+P')) laurent@407: parent.AppendSeparator() laurent@407: AppendMenu(parent, help='', id=wx.ID_PROPERTIES, Edouard@656: kind=wx.ITEM_NORMAL, text=_(u'&Properties')) laurent@407: parent.AppendSeparator() laurent@407: AppendMenu(parent, help='', id=wx.ID_EXIT, laurent@407: kind=wx.ITEM_NORMAL, text=_(u'Quit\tCTRL+Q')) laurent@407: laurent@407: self.Bind(wx.EVT_MENU, self.OnNewProjectMenu, id=wx.ID_NEW) laurent@407: self.Bind(wx.EVT_MENU, self.OnOpenProjectMenu, id=wx.ID_OPEN) laurent@407: self.Bind(wx.EVT_MENU, self.OnCloseTabMenu, id=wx.ID_CLOSE) laurent@407: self.Bind(wx.EVT_MENU, self.OnCloseProjectMenu, id=wx.ID_CLOSE_ALL) laurent@407: self.Bind(wx.EVT_MENU, self.OnSaveProjectMenu, id=wx.ID_SAVE) laurent@407: self.Bind(wx.EVT_MENU, self.OnSaveProjectAsMenu, id=wx.ID_SAVEAS) laurent@407: self.Bind(wx.EVT_MENU, self.OnGenerateProgramMenu, laurent@407: id=ID_PLCOPENEDITORFILEMENUGENERATE) laurent@407: self.Bind(wx.EVT_MENU, self.OnPageSetupMenu, id=wx.ID_PAGE_SETUP) laurent@407: self.Bind(wx.EVT_MENU, self.OnPreviewMenu, id=wx.ID_PREVIEW) laurent@407: self.Bind(wx.EVT_MENU, self.OnPrintMenu, id=wx.ID_PRINT) laurent@407: self.Bind(wx.EVT_MENU, self.OnPropertiesMenu, id=wx.ID_PROPERTIES) laurent@407: self.Bind(wx.EVT_MENU, self.OnQuitMenu, id=wx.ID_EXIT) laurent@660: Laurent@714: self.AddToMenuToolBar([(wx.ID_NEW, "new", _(u'New'), None), Laurent@714: (wx.ID_OPEN, "open", _(u'Open'), None), Laurent@714: (wx.ID_SAVE, "save", _(u'Save'), None), Laurent@714: (wx.ID_SAVEAS, "saveas", _(u'Save As...'), None), Laurent@714: (wx.ID_PRINT, "print", _(u'Print'), None)]) laurent@660: laurent@407: def _init_coll_HelpMenu_Items(self, parent): laurent@407: AppendMenu(parent, help='', id=wx.ID_HELP, laurent@407: kind=wx.ITEM_NORMAL, text=_(u'PLCOpenEditor\tF1')) laurent@407: #AppendMenu(parent, help='', id=wx.ID_HELP_CONTENTS, laurent@407: # kind=wx.ITEM_NORMAL, text=u'PLCOpen\tF2') laurent@407: #AppendMenu(parent, help='', id=wx.ID_HELP_CONTEXT, laurent@407: # kind=wx.ITEM_NORMAL, text=u'IEC 61131-3\tF3') laurent@407: AppendMenu(parent, help='', id=wx.ID_ABOUT, laurent@407: kind=wx.ITEM_NORMAL, text=_(u'About')) laurent@407: self.Bind(wx.EVT_MENU, self.OnPLCOpenEditorMenu, id=wx.ID_HELP) laurent@407: #self.Bind(wx.EVT_MENU, self.OnPLCOpenMenu, id=wx.ID_HELP_CONTENTS) laurent@407: self.Bind(wx.EVT_MENU, self.OnAboutMenu, id=wx.ID_ABOUT) laurent@407: laurent@407: ## Constructor of the PLCOpenEditor class. laurent@407: # @param parent The parent window. laurent@407: # @param controler The controler been used by PLCOpenEditor (default: None). laurent@407: # @param fileOpen The filepath to open if no controler defined (default: None). laurent@407: # @param debug The filepath to open if no controler defined (default: False). laurent@407: def __init__(self, parent, fileOpen = None): laurent@407: IDEFrame.__init__(self, parent) laurent@407: laurent@500: result = None laurent@500: laurent@407: # Open the filepath if defined Laurent@727: if fileOpen is not None: Laurent@727: fileOpen = DecodeFileSystemPath(fileOpen, False) Laurent@727: if os.path.isfile(fileOpen): Laurent@727: # Create a new controller Laurent@727: controler = PLCControler() Laurent@727: result = controler.OpenXMLFile(fileOpen) Laurent@727: if result is None: Laurent@727: self.Controler = controler Laurent@727: self.LibraryPanel.SetController(controler) Laurent@727: self.ProjectTree.Enable(True) Laurent@727: self.PouInstanceVariablesPanel.SetController(controler) Laurent@727: self._Refresh(PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE) laurent@407: laurent@407: # Define PLCOpenEditor icon Laurent@714: self.SetIcon(wx.Icon(os.path.join(CWD, "Images", "poe.ico"),wx.BITMAP_TYPE_ICO)) laurent@407: laurent@407: self.Bind(wx.EVT_CLOSE, self.OnCloseFrame) laurent@407: laurent@660: self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU) laurent@500: laurent@500: if result is not None: laurent@500: self.ShowErrorMessage(result) laurent@407: laurent@407: def OnCloseFrame(self, event): laurent@450: if self.Controler is None or self.CheckSaveBeforeClosing(_("Close Application")): Edouard@685: self.AUIManager.UnInit() laurent@535: laurent@673: self.SaveLastState() laurent@535: laurent@407: event.Skip() laurent@407: else: laurent@407: event.Veto() laurent@407: laurent@407: def RefreshTitle(self): laurent@407: name = _("PLCOpenEditor") laurent@407: if self.Controler is not None: laurent@407: self.SetTitle("%s - %s"%(name, self.Controler.GetFilename())) laurent@407: else: laurent@407: self.SetTitle(name) laurent@407: laurent@407: #------------------------------------------------------------------------------- laurent@407: # File Menu Functions laurent@407: #------------------------------------------------------------------------------- laurent@407: laurent@407: def RefreshFileMenu(self): laurent@660: MenuToolBar = self.Panes["MenuToolBar"] laurent@407: if self.Controler is not None: laurent@407: selected = self.TabsOpened.GetSelection() laurent@407: if selected >= 0: laurent@407: graphic_viewer = isinstance(self.TabsOpened.GetPage(selected), Viewer) laurent@407: else: laurent@407: graphic_viewer = False laurent@407: if self.TabsOpened.GetPageCount() > 0: laurent@407: self.FileMenu.Enable(wx.ID_CLOSE, True) laurent@407: if graphic_viewer: laurent@407: self.FileMenu.Enable(wx.ID_PREVIEW, True) laurent@407: self.FileMenu.Enable(wx.ID_PRINT, True) laurent@660: MenuToolBar.EnableTool(wx.ID_PRINT, True) laurent@407: else: laurent@407: self.FileMenu.Enable(wx.ID_PREVIEW, False) laurent@407: self.FileMenu.Enable(wx.ID_PRINT, False) laurent@660: MenuToolBar.EnableTool(wx.ID_PRINT, False) laurent@407: else: laurent@407: self.FileMenu.Enable(wx.ID_CLOSE, False) laurent@407: self.FileMenu.Enable(wx.ID_PREVIEW, False) laurent@407: self.FileMenu.Enable(wx.ID_PRINT, False) laurent@660: MenuToolBar.EnableTool(wx.ID_PRINT, False) laurent@407: self.FileMenu.Enable(wx.ID_PAGE_SETUP, True) laurent@660: project_modified = not self.Controler.ProjectIsSaved() laurent@660: self.FileMenu.Enable(wx.ID_SAVE, project_modified) laurent@660: MenuToolBar.EnableTool(wx.ID_SAVE, project_modified) laurent@407: self.FileMenu.Enable(wx.ID_PROPERTIES, True) laurent@407: self.FileMenu.Enable(wx.ID_CLOSE_ALL, True) laurent@407: self.FileMenu.Enable(wx.ID_SAVEAS, True) laurent@660: MenuToolBar.EnableTool(wx.ID_SAVEAS, True) laurent@407: self.FileMenu.Enable(ID_PLCOPENEDITORFILEMENUGENERATE, True) laurent@407: else: laurent@407: self.FileMenu.Enable(wx.ID_CLOSE, False) laurent@407: self.FileMenu.Enable(wx.ID_PAGE_SETUP, False) laurent@407: self.FileMenu.Enable(wx.ID_PREVIEW, False) laurent@407: self.FileMenu.Enable(wx.ID_PRINT, False) laurent@660: MenuToolBar.EnableTool(wx.ID_PRINT, False) laurent@407: self.FileMenu.Enable(wx.ID_SAVE, False) laurent@660: MenuToolBar.EnableTool(wx.ID_SAVE, False) laurent@407: self.FileMenu.Enable(wx.ID_PROPERTIES, False) laurent@407: self.FileMenu.Enable(wx.ID_CLOSE_ALL, False) laurent@407: self.FileMenu.Enable(wx.ID_SAVEAS, False) laurent@660: MenuToolBar.EnableTool(wx.ID_SAVEAS, False) laurent@407: self.FileMenu.Enable(ID_PLCOPENEDITORFILEMENUGENERATE, False) laurent@407: laurent@407: def OnNewProjectMenu(self, event): laurent@407: if self.Controler is not None and not self.CheckSaveBeforeClosing(): laurent@407: return laurent@407: dialog = ProjectDialog(self) laurent@407: if dialog.ShowModal() == wx.ID_OK: laurent@407: properties = dialog.GetValues() laurent@411: self.ResetView() laurent@407: self.Controler = PLCControler() laurent@407: self.Controler.CreateNewProject(properties) Laurent@714: self.LibraryPanel.SetController(self.Controler) laurent@684: self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL, laurent@407: LIBRARYTREE) laurent@407: laurent@407: def OnOpenProjectMenu(self, event): laurent@407: if self.Controler is not None and not self.CheckSaveBeforeClosing(): laurent@407: return laurent@407: filepath = "" laurent@407: if self.Controler is not None: laurent@407: filepath = self.Controler.GetFilePath() laurent@407: if filepath != "": laurent@407: directory = os.path.dirname(filepath) laurent@407: else: laurent@407: directory = os.getcwd() laurent@500: laurent@500: result = None laurent@500: laurent@407: dialog = wx.FileDialog(self, _("Choose a file"), directory, "", _("PLCOpen files (*.xml)|*.xml|All files|*.*"), wx.OPEN) laurent@407: if dialog.ShowModal() == wx.ID_OK: laurent@407: filepath = dialog.GetPath() laurent@407: if os.path.isfile(filepath): laurent@411: self.ResetView() laurent@687: controler = PLCControler() laurent@687: result = controler.OpenXMLFile(filepath) laurent@500: if result is None: laurent@687: self.Controler = controler Laurent@714: self.LibraryPanel.SetController(controler) laurent@687: self.ProjectTree.Enable(True) laurent@687: self.PouInstanceVariablesPanel.SetController(controler) laurent@691: self.LoadProjectLayout() laurent@684: self._Refresh(PROJECTTREE, LIBRARYTREE) laurent@660: self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU) laurent@407: dialog.Destroy() laurent@500: laurent@500: if result is not None: laurent@500: self.ShowErrorMessage(result) laurent@407: laurent@407: def OnCloseProjectMenu(self, event): laurent@407: if not self.CheckSaveBeforeClosing(): laurent@407: return laurent@691: self.SaveProjectLayout() laurent@411: self.ResetView() laurent@660: self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU) laurent@407: laurent@407: def OnSaveProjectMenu(self, event): laurent@407: self.SaveProject() laurent@407: laurent@407: def OnSaveProjectAsMenu(self, event): laurent@407: self.SaveProjectAs() laurent@407: laurent@407: def OnGenerateProgramMenu(self, event): laurent@407: dialog = wx.FileDialog(self, _("Choose a file"), os.getcwd(), self.Controler.GetProgramFilePath(), _("ST files (*.st)|*.st|All files|*.*"), wx.SAVE|wx.CHANGE_DIR) laurent@407: if dialog.ShowModal() == wx.ID_OK: laurent@407: filepath = dialog.GetPath() laurent@407: message_text = "" laurent@407: header, icon = _("Done"), wx.ICON_INFORMATION laurent@407: if os.path.isdir(os.path.dirname(filepath)): laurent@407: program, errors, warnings = self.Controler.GenerateProgram(filepath) laurent@407: message_text += "".join([_("warning: %s\n") for warning in warnings]) laurent@407: if len(errors) > 0: laurent@540: message_text += "".join([_("error: %s\n") for error in errors]) laurent@407: message_text += _("Can't generate program to file %s!")%filepath laurent@407: header, icon = _("Error"), wx.ICON_ERROR laurent@407: else: laurent@407: message_text += _("Program was successfully generated!") laurent@407: else: laurent@407: message_text += _("\"%s\" is not a valid folder!")%os.path.dirname(filepath) laurent@407: header, icon = _("Error"), wx.ICON_ERROR laurent@407: message = wx.MessageDialog(self, message_text, header, wx.OK|icon) laurent@407: message.ShowModal() laurent@407: message.Destroy() laurent@407: dialog.Destroy() laurent@407: laurent@407: def SaveProject(self): laurent@407: result = self.Controler.SaveXMLFile() laurent@407: if not result: laurent@407: self.SaveProjectAs() laurent@407: else: laurent@586: self._Refresh(TITLE, FILEMENU, PAGETITLES) laurent@586: laurent@407: def SaveProjectAs(self): laurent@407: filepath = self.Controler.GetFilePath() laurent@407: if filepath != "": laurent@407: directory, filename = os.path.split(filepath) laurent@407: else: laurent@407: directory, filename = os.getcwd(), "%(projectName)s.xml"%self.Controler.GetProjectProperties() laurent@407: dialog = wx.FileDialog(self, _("Choose a file"), directory, filename, _("PLCOpen files (*.xml)|*.xml|All files|*.*"), wx.SAVE|wx.OVERWRITE_PROMPT) laurent@407: if dialog.ShowModal() == wx.ID_OK: laurent@407: filepath = dialog.GetPath() laurent@407: if os.path.isdir(os.path.dirname(filepath)): laurent@407: result = self.Controler.SaveXMLFile(filepath) laurent@407: if not result: laurent@407: self.ShowErrorMessage(_("Can't save project to file %s!")%filepath) laurent@407: else: laurent@407: self.ShowErrorMessage(_("\"%s\" is not a valid folder!")%os.path.dirname(filepath)) laurent@586: self._Refresh(TITLE, FILEMENU, PAGETITLES) laurent@407: dialog.Destroy() etisserant@0: etisserant@0: #------------------------------------------------------------------------------- laurent@390: # Debug Variables Panel lbessard@341: #------------------------------------------------------------------------------- lbessard@341: lbessard@341: #------------------------------------------------------------------------------- lbessard@341: # Viewer Printout lbessard@341: #------------------------------------------------------------------------------- lbessard@341: lbessard@213: UPPER_DIV = lambda x, y: (x / y) + {True : 0, False : 1}[(x % y) == 0] lbessard@213: lbessard@213: class GraphicPrintout(wx.Printout): lbessard@213: def __init__(self, viewer, page_size, margins, preview = False): lbessard@213: wx.Printout.__init__(self) lbessard@213: self.Viewer = viewer lbessard@213: self.PageSize = page_size lbessard@221: if self.PageSize[0] == 0 or self.PageSize[1] == 0: lbessard@221: self.PageSize = (1050, 1485) lbessard@213: self.Preview = preview lbessard@213: self.Margins = margins lbessard@221: self.FontSize = 5 lbessard@221: self.TextMargin = 3 lbessard@213: lbessard@213: maxx, maxy = viewer.GetMaxSize() lbessard@221: self.PageGrid = (UPPER_DIV(maxx, self.PageSize[0]), lbessard@221: UPPER_DIV(maxy, self.PageSize[1])) lbessard@213: lbessard@213: def GetPageNumber(self): lbessard@213: return self.PageGrid[0] * self.PageGrid[1] lbessard@213: lbessard@213: def HasPage(self, page): lbessard@213: return page <= self.GetPageNumber() lbessard@213: lbessard@213: def GetPageInfo(self): lbessard@213: page_number = self.GetPageNumber() lbessard@213: return (1, page_number, 1, page_number) lbessard@213: lbessard@213: def OnBeginDocument(self, startPage, endPage): lbessard@213: dc = self.GetDC() lbessard@213: if not self.Preview and isinstance(dc, wx.PostScriptDC): lbessard@213: dc.SetResolution(720) lbessard@213: super(GraphicPrintout, self).OnBeginDocument(startPage, endPage) lbessard@213: lbessard@213: def OnPrintPage(self, page): lbessard@213: dc = self.GetDC() lbessard@221: dc.SetUserScale(1.0, 1.0) lbessard@221: dc.SetDeviceOrigin(0, 0) lbessard@213: dc.printing = not self.Preview lbessard@213: lbessard@213: # Get the size of the DC in pixels lbessard@213: ppiPrinterX, ppiPrinterY = self.GetPPIPrinter() lbessard@213: ppiScreenX, ppiScreenY = self.GetPPIScreen() lbessard@213: pw, ph = self.GetPageSizePixels() lbessard@213: dw, dh = dc.GetSizeTuple() lbessard@213: Xscale = (float(dw) * float(ppiPrinterX)) / (float(pw) * 25.4) lbessard@213: Yscale = (float(dh) * float(ppiPrinterY)) / (float(ph) * 25.4) lbessard@213: lbessard@221: fontsize = self.FontSize * Yscale lbessard@221: text_margin = self.TextMargin * Yscale lbessard@221: lbessard@213: margin_left = self.Margins[0].x * Xscale lbessard@213: margin_top = self.Margins[0].y * Yscale lbessard@213: area_width = dw - self.Margins[1].x * Xscale - margin_left lbessard@213: area_height = dh - self.Margins[1].y * Yscale - margin_top lbessard@213: laurent@563: dc.SetPen(MiterPen(wx.BLACK)) lbessard@213: dc.SetBrush(wx.TRANSPARENT_BRUSH) lbessard@213: dc.DrawRectangle(margin_left, margin_top, area_width, area_height) lbessard@213: lbessard@221: dc.SetFont(wx.Font(fontsize, wx.DEFAULT, wx.NORMAL, wx.NORMAL)) lbessard@213: dc.SetTextForeground(wx.BLACK) lbessard@213: block_name = " - ".join(self.Viewer.GetTagName().split("::")[1:]) lbessard@213: text_width, text_height = dc.GetTextExtent(block_name) lbessard@213: dc.DrawText(block_name, margin_left, margin_top - text_height - self.TextMargin) laurent@391: dc.DrawText(_("Page: %d") % page, margin_left, margin_top + area_height + self.TextMargin) lbessard@213: lbessard@213: # Calculate the position on the DC for centering the graphic lbessard@213: posX = area_width * ((page - 1) % self.PageGrid[0]) lbessard@213: posY = area_height * ((page - 1) / self.PageGrid[0]) lbessard@213: lbessard@213: scaleX = float(area_width) / float(self.PageSize[0]) lbessard@213: scaleY = float(area_height) / float(self.PageSize[1]) lbessard@213: scale = min(scaleX, scaleY) lbessard@213: lbessard@213: # Set the scale and origin lbessard@213: dc.SetDeviceOrigin(-posX + margin_left, -posY + margin_top) lbessard@221: dc.SetClippingRegion(posX, posY, self.PageSize[0] * scale, self.PageSize[1] * scale) lbessard@213: dc.SetUserScale(scale, scale) lbessard@213: lbessard@213: #------------------------------------------- lbessard@213: lbessard@213: self.Viewer.DoDrawing(dc, True) lbessard@213: lbessard@213: return True lbessard@213: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Exception Handler etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: Max_Traceback_List_Size = 20 etisserant@0: etisserant@0: def Display_Exception_Dialog(e_type,e_value,e_tb): etisserant@0: trcbck_lst = [] etisserant@0: for i,line in enumerate(traceback.extract_tb(e_tb)): laurent@391: trcbck = " " + str(i+1) + _(". ") etisserant@0: if line[0].find(os.getcwd()) == -1: laurent@391: trcbck += _("file : ") + str(line[0]) + _(", ") laurent@391: else: laurent@391: trcbck += _("file : ") + str(line[0][len(os.getcwd()):]) + _(", ") laurent@391: trcbck += _("line : ") + str(line[1]) + _(", ") + _("function : ") + str(line[2]) etisserant@0: trcbck_lst.append(trcbck) etisserant@0: etisserant@0: # Allow clicking.... etisserant@0: cap = wx.Window_GetCapture() etisserant@0: if cap: etisserant@0: cap.ReleaseMouse() etisserant@0: etisserant@0: dlg = wx.SingleChoiceDialog(None, laurent@391: _(""" b@427: An error has occurred. b@427: b@427: Click OK to save an error report. etisserant@0: greg@454: Please be kind enough to send this file to: greg@454: edouard.tisserant@gmail.com etisserant@0: etisserant@0: Error: laurent@391: """) + laurent@391: str(e_type) + _(" : ") + str(e_value), laurent@391: _("Error"), etisserant@0: trcbck_lst) etisserant@0: try: etisserant@0: res = (dlg.ShowModal() == wx.ID_OK) etisserant@0: finally: etisserant@0: dlg.Destroy() etisserant@0: etisserant@0: return res etisserant@0: etisserant@0: def Display_Error_Dialog(e_value): laurent@391: message = wx.MessageDialog(None, str(e_value), _("Error"), wx.OK|wx.ICON_ERROR) etisserant@0: message.ShowModal() etisserant@0: message.Destroy() etisserant@0: etisserant@0: def get_last_traceback(tb): etisserant@0: while tb.tb_next: etisserant@0: tb = tb.tb_next etisserant@0: return tb etisserant@0: etisserant@0: etisserant@0: def format_namespace(d, indent=' '): etisserant@0: return '\n'.join(['%s%s: %s' % (indent, k, repr(v)[:10000]) for k, v in d.iteritems()]) etisserant@0: etisserant@0: etisserant@0: ignored_exceptions = [] # a problem with a line in a module is only reported once per session etisserant@0: lbessard@65: def AddExceptHook(path, app_version='[No version]'):#, ignored_exceptions=[]): etisserant@0: etisserant@0: def handle_exception(e_type, e_value, e_traceback): etisserant@0: traceback.print_exception(e_type, e_value, e_traceback) # this is very helpful when there's an exception in the rest of this func etisserant@0: last_tb = get_last_traceback(e_traceback) etisserant@0: ex = (last_tb.tb_frame.f_code.co_filename, last_tb.tb_frame.f_lineno) etisserant@0: if str(e_value).startswith("!!!"): etisserant@0: Display_Error_Dialog(e_value) etisserant@0: elif ex not in ignored_exceptions: etisserant@0: result = Display_Exception_Dialog(e_type,e_value,e_traceback) etisserant@0: if result: etisserant@0: ignored_exceptions.append(ex) etisserant@0: info = { etisserant@0: 'app-title' : wx.GetApp().GetAppName(), # app_title etisserant@0: 'app-version' : app_version, etisserant@0: 'wx-version' : wx.VERSION_STRING, etisserant@0: 'wx-platform' : wx.Platform, etisserant@0: 'python-version' : platform.python_version(), #sys.version.split()[0], etisserant@0: 'platform' : platform.platform(), etisserant@0: 'e-type' : e_type, etisserant@0: 'e-value' : e_value, etisserant@0: 'date' : time.ctime(), etisserant@0: 'cwd' : os.getcwd(), etisserant@0: } etisserant@0: if e_traceback: etisserant@0: info['traceback'] = ''.join(traceback.format_tb(e_traceback)) + '%s: %s' % (e_type, e_value) etisserant@0: last_tb = get_last_traceback(e_traceback) etisserant@0: exception_locals = last_tb.tb_frame.f_locals # the locals at the level of the stack trace where the exception actually occurred etisserant@0: info['locals'] = format_namespace(exception_locals) etisserant@0: if 'self' in exception_locals: etisserant@0: info['self'] = format_namespace(exception_locals['self'].__dict__) etisserant@0: etisserant@0: output = open(path+os.sep+"bug_report_"+info['date'].replace(':','-').replace(' ','_')+".txt",'w') etisserant@0: lst = info.keys() etisserant@0: lst.sort() etisserant@0: for a in lst: etisserant@0: output.write(a+":\n"+str(info[a])+"\n\n") etisserant@0: etisserant@0: #sys.excepthook = lambda *args: wx.CallAfter(handle_exception, *args) etisserant@0: sys.excepthook = handle_exception etisserant@0: etisserant@0: if __name__ == '__main__': lbessard@64: wx.InitAllImageHandlers() etisserant@0: etisserant@0: # Install a exception handle for bug reports lbessard@65: AddExceptHook(os.getcwd(),__version__) etisserant@0: lbessard@92: frame = PLCOpenEditor(None, fileOpen=fileOpen) etisserant@0: etisserant@0: frame.Show() etisserant@0: app.MainLoop() etisserant@0: