PLCOpenEditor.py
changeset 451 20464365086e
parent 450 b31d1dfb407b
child 456 dc379f8db18d
equal deleted inserted replaced
450:b31d1dfb407b 451:20464365086e
     1 (binary file text/x-python, hash: 6aebfc5e174a423ddbc5b3a8b9440383e321e18e)
     1 #!/usr/bin/env python
       
     2 # -*- coding: utf-8 -*-
       
     3 
       
     4 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
       
     5 #based on the plcopen standard. 
       
     6 #
       
     7 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
       
     8 #
       
     9 #See COPYING file for copyrights details.
       
    10 #
       
    11 #This library is free software; you can redistribute it and/or
       
    12 #modify it under the terms of the GNU General Public
       
    13 #License as published by the Free Software Foundation; either
       
    14 #version 2.1 of the License, or (at your option) any later version.
       
    15 #
       
    16 #This library is distributed in the hope that it will be useful,
       
    17 #but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    18 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    19 #General Public License for more details.
       
    20 #
       
    21 #You should have received a copy of the GNU General Public
       
    22 #License along with this library; if not, write to the Free Software
       
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    24 
       
    25 from datetime import datetime
       
    26 import wx, wx.grid
       
    27 
       
    28 if wx.VERSION >= (2, 8, 0):
       
    29     import wx.aui
       
    30     USE_AUI = True
       
    31 else:
       
    32     USE_AUI = False
       
    33 
       
    34 import os, re, platform, sys, time, traceback, getopt
       
    35 import cPickle
       
    36 
       
    37 CWD = os.path.split(os.path.realpath(__file__))[0]
       
    38 base_folder = os.path.split(CWD)[0]
       
    39 sys.path.append(base_folder)
       
    40 from docutils import *
       
    41 
       
    42 from types import TupleType
       
    43 
       
    44 __version__ = "$Revision: 1.130 $"
       
    45 
       
    46 if __name__ == '__main__':
       
    47     # Usage message displayed when help request or when error detected in 
       
    48     # command line
       
    49     def usage():
       
    50         print "\nUsage of PLCOpenEditor.py :"
       
    51         print "\n   %s [Filepath]\n"%sys.argv[0]
       
    52 
       
    53     # Parse options given to PLCOpenEditor in command line
       
    54     try:
       
    55         opts, args = getopt.getopt(sys.argv[1:], "h", ["help"])
       
    56     except getopt.GetoptError:
       
    57         # print help information and exit:
       
    58         usage()
       
    59         sys.exit(2)
       
    60     
       
    61     # Extract if help has been requested
       
    62     for o, a in opts:
       
    63         if o in ("-h", "--help"):
       
    64             usage()
       
    65             sys.exit()
       
    66     
       
    67     # Extract the optional filename to open
       
    68     fileOpen = None
       
    69     if len(args) > 1:
       
    70         usage()
       
    71         sys.exit()
       
    72     elif len(args) == 1:
       
    73         fileOpen = args[0]
       
    74     
       
    75     # Create wxApp (Need to create App before internationalization because of
       
    76     # Windows) 
       
    77     app = wx.PySimpleApp()
       
    78 
       
    79 # Import module for internationalization
       
    80 import gettext
       
    81 import __builtin__
       
    82 
       
    83 # Get folder containing translation files
       
    84 localedir = os.path.join(CWD,"locale")
       
    85 # Get the default language
       
    86 langid = wx.LANGUAGE_DEFAULT
       
    87 # Define translation domain (name of translation files)
       
    88 domain = "PLCOpenEditor"
       
    89 
       
    90 # Define locale for wx
       
    91 loc = __builtin__.__dict__.get('loc', None)
       
    92 if loc is None:
       
    93     loc = wx.Locale(langid)
       
    94     __builtin__.__dict__['loc'] = loc
       
    95 # Define location for searching translation files
       
    96 loc.AddCatalogLookupPathPrefix(localedir)
       
    97 # Define locale domain
       
    98 loc.AddCatalog(domain)
       
    99 
       
   100 if __name__ == '__main__':
       
   101     __builtin__.__dict__['_'] = wx.GetTranslation
       
   102 
       
   103 from SFCViewer import *
       
   104 from LDViewer import *
       
   105 from Viewer import *
       
   106 from TextViewer import *
       
   107 from GraphicViewer import *
       
   108 from RessourceEditor import *
       
   109 from DataTypeEditor import *
       
   110 from PLCControler import *
       
   111 from VariablePanel import VariablePanel
       
   112 
       
   113 # Define PLCOpenEditor controls id
       
   114 [ID_PLCOPENEDITOR, ID_PLCOPENEDITORLEFTNOTEBOOK, 
       
   115  ID_PLCOPENEDITORBOTTOMNOTEBOOK, ID_PLCOPENEDITORRIGHTNOTEBOOK, 
       
   116  ID_PLCOPENEDITORTYPESTREE, ID_PLCOPENEDITORINSTANCESTREE, 
       
   117  ID_PLCOPENEDITORMAINSPLITTER, ID_PLCOPENEDITORSECONDSPLITTER, 
       
   118  ID_PLCOPENEDITORTHIRDSPLITTER, ID_PLCOPENEDITORLIBRARYPANEL, 
       
   119  ID_PLCOPENEDITORLIBRARYTREE, ID_PLCOPENEDITORLIBRARYCOMMENT, 
       
   120  ID_PLCOPENEDITORTABSOPENED, ID_PLCOPENEDITORTABSOPENED,
       
   121  ID_PLCOPENEDITORTOOLBAR, ID_PLCOPENEDITORDEFAULTTOOLBAR, 
       
   122  ID_PLCOPENEDITORSFCTOOLBAR, ID_PLCOPENEDITORFBDTOOLBAR, 
       
   123  ID_PLCOPENEDITORLDTOOLBAR,
       
   124 ] = [wx.NewId() for _init_ctrls in range(19)]
       
   125 
       
   126 # Define PLCOpenEditor FileMenu extra items id
       
   127 [ID_PLCOPENEDITORFILEMENUGENERATE, 
       
   128 ] = [wx.NewId() for _init_coll_FileMenu_Items in range(1)]
       
   129 
       
   130 # Define PLCOpenEditor EditMenu extra items id
       
   131 [ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, ID_PLCOPENEDITOREDITMENUADDDATATYPE, 
       
   132  ID_PLCOPENEDITOREDITMENUADDFUNCTION, ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK, 
       
   133  ID_PLCOPENEDITOREDITMENUADDPROGRAM, ID_PLCOPENEDITOREDITMENUADDCONFIGURATION, 
       
   134 ] = [wx.NewId() for _init_coll_EditMenu_Items in range(6)]
       
   135 
       
   136 
       
   137 #-------------------------------------------------------------------------------
       
   138 #                            ToolBars definitions
       
   139 #-------------------------------------------------------------------------------
       
   140 
       
   141 # Define PLCOpenEditor Toolbar items id
       
   142 [ID_PLCOPENEDITORTOOLBARSELECTION, ID_PLCOPENEDITORTOOLBARCOMMENT,
       
   143  ID_PLCOPENEDITORTOOLBARVARIABLE, ID_PLCOPENEDITORTOOLBARBLOCK,
       
   144  ID_PLCOPENEDITORTOOLBARCONNECTION, ID_PLCOPENEDITORTOOLBARWIRE,
       
   145  ID_PLCOPENEDITORTOOLBARPOWERRAIL, ID_PLCOPENEDITORTOOLBARRUNG,
       
   146  ID_PLCOPENEDITORTOOLBARCOIL, ID_PLCOPENEDITORTOOLBARCONTACT,
       
   147  ID_PLCOPENEDITORTOOLBARBRANCH, ID_PLCOPENEDITORTOOLBARINITIALSTEP,
       
   148  ID_PLCOPENEDITORTOOLBARSTEP, ID_PLCOPENEDITORTOOLBARTRANSITION,
       
   149  ID_PLCOPENEDITORTOOLBARACTIONBLOCK, ID_PLCOPENEDITORTOOLBARDIVERGENCE,
       
   150  ID_PLCOPENEDITORTOOLBARJUMP,
       
   151 ] = [wx.NewId() for _init_coll_DefaultToolBar_Items in range(17)]
       
   152 
       
   153 # Define behaviour of each Toolbar item according to current POU body type 
       
   154 # Informations meaning are in this order:
       
   155 #  - Item is toggled
       
   156 #  - PLCOpenEditor mode where item is displayed (could be more then one)
       
   157 #  - Item id
       
   158 #  - Item callback function name
       
   159 #  - Item icon filename
       
   160 #  - Item tooltip text
       
   161 ToolBarItems = {
       
   162     "FBD" : [(True, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
       
   163               ID_PLCOPENEDITORTOOLBARCOMMENT, "OnCommentTool",
       
   164               "add_comment.png", _("Create a new comment")),
       
   165              (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
       
   166               ID_PLCOPENEDITORTOOLBARVARIABLE, "OnVariableTool",
       
   167               "add_variable.png", _("Create a new variable")),
       
   168              (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
       
   169               ID_PLCOPENEDITORTOOLBARBLOCK, "OnBlockTool",
       
   170               "add_block.png", _("Create a new block")),
       
   171              (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, 
       
   172               ID_PLCOPENEDITORTOOLBARCONNECTION, "OnConnectionTool", 
       
   173               "add_connection.png", _("Create a new connection"))],
       
   174     "LD"  : [(True, FREEDRAWING_MODE, 
       
   175               ID_PLCOPENEDITORTOOLBARCOMMENT, "OnCommentTool", 
       
   176               "add_comment.png", _("Create a new comment")),
       
   177              (True, FREEDRAWING_MODE, 
       
   178               ID_PLCOPENEDITORTOOLBARPOWERRAIL, "OnPowerRailTool", 
       
   179               "add_powerrail.png", _("Create a new power rail")),
       
   180              (False, DRIVENDRAWING_MODE, 
       
   181               ID_PLCOPENEDITORTOOLBARRUNG, "OnRungTool", 
       
   182               "add_rung.png", _("Create a new rung")),
       
   183              (True, FREEDRAWING_MODE, 
       
   184               ID_PLCOPENEDITORTOOLBARCOIL, "OnCoilTool", 
       
   185               "add_coil.png", _("Create a new coil")),
       
   186              (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, 
       
   187               ID_PLCOPENEDITORTOOLBARCONTACT, "OnContactTool", 
       
   188               "add_contact.png", _("Create a new contact")),
       
   189              (False, DRIVENDRAWING_MODE, 
       
   190               ID_PLCOPENEDITORTOOLBARBRANCH, "OnBranchTool", 
       
   191               "add_branch.png", _("Create a new branch")),
       
   192              (True, FREEDRAWING_MODE, 
       
   193               ID_PLCOPENEDITORTOOLBARVARIABLE, "OnVariableTool", 
       
   194               "add_variable.png", _("Create a new variable")),
       
   195              (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, 
       
   196               ID_PLCOPENEDITORTOOLBARBLOCK, "OnBlockTool", 
       
   197               "add_block.png", _("Create a new block")),
       
   198              (True, FREEDRAWING_MODE, 
       
   199               ID_PLCOPENEDITORTOOLBARCONNECTION, "OnConnectionTool", 
       
   200               "add_connection.png", _("Create a new connection"))],
       
   201     "SFC" : [(True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, 
       
   202               ID_PLCOPENEDITORTOOLBARCOMMENT, "OnCommentTool", 
       
   203               "add_comment.png", _("Create a new comment")),
       
   204              (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, 
       
   205               ID_PLCOPENEDITORTOOLBARINITIALSTEP, "OnInitialStepTool", 
       
   206               "add_initial_step.png", _("Create a new initial step")),
       
   207              (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, 
       
   208               ID_PLCOPENEDITORTOOLBARSTEP, "OnStepTool", 
       
   209               "add_step.png", _("Create a new step")),
       
   210              (True, FREEDRAWING_MODE, 
       
   211               ID_PLCOPENEDITORTOOLBARTRANSITION, "OnTransitionTool", 
       
   212               "add_transition.png", _("Create a new transition")),
       
   213              (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, 
       
   214               ID_PLCOPENEDITORTOOLBARACTIONBLOCK, "OnActionBlockTool", 
       
   215               "add_action.png", _("Create a new action block")),
       
   216              (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, 
       
   217               ID_PLCOPENEDITORTOOLBARDIVERGENCE, "OnDivergenceTool", 
       
   218               "add_divergence.png", _("Create a new divergence")),
       
   219              (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, 
       
   220               ID_PLCOPENEDITORTOOLBARJUMP, "OnJumpTool", 
       
   221               "add_jump.png", _("Create a new jump")),
       
   222              (True, FREEDRAWING_MODE, 
       
   223               ID_PLCOPENEDITORTOOLBARVARIABLE, "OnVariableTool", 
       
   224               "add_variable.png", _("Create a new variable")),
       
   225              (True, FREEDRAWING_MODE, 
       
   226               ID_PLCOPENEDITORTOOLBARBLOCK, "OnBlockTool", 
       
   227               "add_block.png", _("Create a new block")),
       
   228              (True, FREEDRAWING_MODE, 
       
   229               ID_PLCOPENEDITORTOOLBARCONNECTION, "OnConnectionTool", 
       
   230               "add_connection.png", _("Create a new connection")),
       
   231              (True, FREEDRAWING_MODE, 
       
   232               ID_PLCOPENEDITORTOOLBARPOWERRAIL, "OnPowerRailTool", 
       
   233               "add_powerrail.png", _("Create a new power rail")),
       
   234              (True, FREEDRAWING_MODE, 
       
   235               ID_PLCOPENEDITORTOOLBARCONTACT, "OnContactTool", 
       
   236               "add_contact.png", _("Create a new contact"))],
       
   237     "ST"  : [],
       
   238     "IL"  : []
       
   239 }
       
   240 
       
   241 #-------------------------------------------------------------------------------
       
   242 #                               Helper Functions
       
   243 #-------------------------------------------------------------------------------
       
   244 
       
   245 # Compatibility function for wx versions < 2.6
       
   246 def AppendMenu(parent, help, id, kind, text):
       
   247     if wx.VERSION >= (2, 6, 0):
       
   248         parent.Append(help=help, id=id, kind=kind, text=text)
       
   249     else:
       
   250         parent.Append(helpString=help, id=id, kind=kind, item=text)
       
   251 
       
   252 [TITLE, TOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, TYPESTREE, 
       
   253  INSTANCESTREE, LIBRARYTREE, SCALING
       
   254 ] = range(9)
       
   255 
       
   256 def GetShortcutKeyCallbackFunction(viewer_function):
       
   257     def ShortcutKeyFunction(self, event):
       
   258         control = self.FindFocus()
       
   259         if isinstance(control, (Viewer, TextViewer)):
       
   260             getattr(control, viewer_function)()
       
   261         elif isinstance(control, wx.TextCtrl):
       
   262             control.ProcessEvent(event)
       
   263     return ShortcutKeyFunction
       
   264 
       
   265 def GetParentName(tree, item, parent_type):
       
   266     parent_item = tree.GetItemParent(item)
       
   267     parent_item_type = tree.GetPyData(parent_item)
       
   268     while parent_item_type != parent_type:
       
   269         parent_item = tree.GetItemParent(parent_item)
       
   270         parent_item_type = tree.GetPyData(parent_item)
       
   271     return tree.GetItemText(parent_item)
       
   272 
       
   273 def GetDeleteElementFunction(remove_function, parent_type=None, check_function=None):
       
   274     def DeleteElementFunction(self, selected):
       
   275         name = self.TypesTree.GetItemText(selected)
       
   276         if check_function is None or not check_function(self.Controler, name):
       
   277             if parent_type is not None:
       
   278                 parent_name = GetParentName(self.TypesTree, selected, parent_type)
       
   279                 remove_function(self.Controler, parent_name, name)
       
   280             else:
       
   281                 remove_function(self.Controler, name)
       
   282         else:
       
   283             self.ShowErrorMessage(_("\"%s\" is used by one or more POUs. It can't be removed!")%name)
       
   284     return DeleteElementFunction
       
   285 
       
   286 
       
   287 #-------------------------------------------------------------------------------
       
   288 #                              IDEFrame Base Class
       
   289 #-------------------------------------------------------------------------------
       
   290 
       
   291 UNEDITABLE_NAMES_DICT = dict([(_(name), name) for name in UNEDITABLE_NAMES])
       
   292 
       
   293 class IDEFrame(wx.Frame):
       
   294     
       
   295     # Compatibility function for wx versions < 2.6
       
   296     if wx.VERSION < (2, 6, 0):
       
   297         def Bind(self, event, function, id = None):
       
   298             if id is not None:
       
   299                 event(self, id, function)
       
   300             else:
       
   301                 event(self, function)
       
   302     
       
   303     def _init_coll_MenuBar_Menus(self, parent):
       
   304         parent.Append(menu=self.FileMenu, title=_(u'File'))
       
   305         parent.Append(menu=self.EditMenu, title=_(u'Edit'))
       
   306         parent.Append(menu=self.DisplayMenu, title=_(u'Display'))
       
   307         parent.Append(menu=self.HelpMenu, title=_(u'Help'))
       
   308 
       
   309     def _init_coll_FileMenu_Items(self, parent):
       
   310         pass
       
   311     
       
   312     def _init_coll_EditMenu_Items(self, parent):
       
   313         AppendMenu(parent, help='', id=wx.ID_UNDO,
       
   314               kind=wx.ITEM_NORMAL, text=_(u'Undo\tCTRL+Z'))
       
   315         AppendMenu(parent, help='', id=wx.ID_REDO,
       
   316               kind=wx.ITEM_NORMAL, text=_(u'Redo\tCTRL+Y'))
       
   317         AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO,
       
   318               kind=wx.ITEM_CHECK, text=_(u'Enable Undo/Redo'))
       
   319         parent.AppendSeparator()
       
   320         AppendMenu(parent, help='', id=wx.ID_CUT,
       
   321               kind=wx.ITEM_NORMAL, text=_(u'Cut\tCTRL+X'))
       
   322         AppendMenu(parent, help='', id=wx.ID_COPY,
       
   323               kind=wx.ITEM_NORMAL, text=_(u'Copy\tCTRL+C'))
       
   324         AppendMenu(parent, help='', id=wx.ID_PASTE,
       
   325               kind=wx.ITEM_NORMAL, text=_(u'Paste\tCTRL+V'))
       
   326         parent.AppendSeparator()
       
   327         addmenu = wx.Menu(title='')
       
   328         parent.AppendMenu(wx.ID_ADD, _("Add Element"), addmenu)
       
   329         AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDDATATYPE,
       
   330               kind=wx.ITEM_NORMAL, text=_(u'Data Type'))
       
   331         AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDFUNCTION,
       
   332               kind=wx.ITEM_NORMAL, text=_(u'Function'))
       
   333         AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK,
       
   334               kind=wx.ITEM_NORMAL, text=_(u'Function Block'))
       
   335         AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDPROGRAM,
       
   336               kind=wx.ITEM_NORMAL, text=_(u'Program'))
       
   337         AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDCONFIGURATION,
       
   338               kind=wx.ITEM_NORMAL, text=_(u'Configuration'))
       
   339         AppendMenu(parent, help='', id=wx.ID_SELECTALL,
       
   340               kind=wx.ITEM_NORMAL, text=_(u'Select All\tCTRL+A'))
       
   341         AppendMenu(parent, help='', id=wx.ID_DELETE,
       
   342               kind=wx.ITEM_NORMAL, text=_(u'Delete'))
       
   343         self.Bind(wx.EVT_MENU, self.OnUndoMenu, id=wx.ID_UNDO)
       
   344         self.Bind(wx.EVT_MENU, self.OnRedoMenu, id=wx.ID_REDO)
       
   345         self.Bind(wx.EVT_MENU, self.OnEnableUndoRedoMenu, id=ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO)
       
   346         self.Bind(wx.EVT_MENU, self.OnCutMenu, id=wx.ID_CUT)
       
   347         self.Bind(wx.EVT_MENU, self.OnCopyMenu, id=wx.ID_COPY)
       
   348         self.Bind(wx.EVT_MENU, self.OnPasteMenu, id=wx.ID_PASTE)
       
   349         self.Bind(wx.EVT_MENU, self.OnAddDataTypeMenu,
       
   350               id=ID_PLCOPENEDITOREDITMENUADDDATATYPE)
       
   351         self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction("function"),
       
   352               id=ID_PLCOPENEDITOREDITMENUADDFUNCTION)
       
   353         self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction("functionBlock"),
       
   354               id=ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK)
       
   355         self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction("program"),
       
   356               id=ID_PLCOPENEDITOREDITMENUADDPROGRAM)
       
   357         self.Bind(wx.EVT_MENU, self.OnAddConfigurationMenu,
       
   358               id=ID_PLCOPENEDITOREDITMENUADDCONFIGURATION)
       
   359         self.Bind(wx.EVT_MENU, self.OnSelectAllMenu, id=wx.ID_SELECTALL)
       
   360         self.Bind(wx.EVT_MENU, self.OnDeleteMenu, id=wx.ID_DELETE)
       
   361 
       
   362     def _init_coll_DisplayMenu_Items(self, parent):
       
   363         AppendMenu(parent, help='', id=wx.ID_REFRESH,
       
   364               kind=wx.ITEM_NORMAL, text=_(u'Refresh\tF5'))
       
   365         if self.EnableDebug:
       
   366             AppendMenu(parent, help='', id=wx.ID_CLEAR,
       
   367                   kind=wx.ITEM_NORMAL, text=_(u'Clear Errors\tCTRL+K'))
       
   368         parent.AppendSeparator()
       
   369         zoommenu = wx.Menu(title='')
       
   370         parent.AppendMenu(wx.ID_ZOOM_FIT, _("Zoom"), zoommenu)
       
   371         for idx, value in enumerate(ZOOM_FACTORS):
       
   372             new_id = wx.NewId()
       
   373             AppendMenu(zoommenu, help='', id=new_id,
       
   374                   kind=wx.ITEM_RADIO, text=str(int(round(value * 100))) + "%")
       
   375             self.Bind(wx.EVT_MENU, self.GenerateZoomFunction(idx), id=new_id)
       
   376         self.Bind(wx.EVT_MENU, self.OnRefreshMenu, id=wx.ID_REFRESH)
       
   377         if self.EnableDebug:
       
   378             self.Bind(wx.EVT_MENU, self.OnClearErrorsMenu, id=wx.ID_CLEAR)
       
   379 
       
   380     def _init_coll_HelpMenu_Items(self, parent):
       
   381         pass
       
   382 
       
   383     def _init_utils(self):
       
   384         self.MenuBar = wx.MenuBar()
       
   385 
       
   386         self.FileMenu = wx.Menu(title='')
       
   387         self.EditMenu = wx.Menu(title='')
       
   388         self.DisplayMenu = wx.Menu(title='')
       
   389         self.HelpMenu = wx.Menu(title='')
       
   390         
       
   391         self._init_coll_MenuBar_Menus(self.MenuBar)
       
   392         self._init_coll_FileMenu_Items(self.FileMenu)
       
   393         self._init_coll_EditMenu_Items(self.EditMenu)
       
   394         self._init_coll_DisplayMenu_Items(self.DisplayMenu)
       
   395         self._init_coll_HelpMenu_Items(self.HelpMenu)
       
   396 
       
   397     def _init_coll_MainLibrarySizer_Items(self, parent):
       
   398         parent.AddWindow(self.LibraryTree, 0, border=0, flag=wx.GROW)
       
   399         parent.AddSizer(self.LibraryComment, 0, border=0, flag=wx.GROW)
       
   400 
       
   401     def _init_coll_MainLibrarySizer_Growables(self, parent):
       
   402         parent.AddGrowableCol(0)
       
   403         parent.AddGrowableRow(0)
       
   404 
       
   405     def _init_sizers(self):
       
   406         self.MainLibrarySizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
       
   407         
       
   408         self._init_coll_MainLibrarySizer_Growables(self.MainLibrarySizer)
       
   409         self._init_coll_MainLibrarySizer_Items(self.MainLibrarySizer)
       
   410         
       
   411         self.LibraryPanel.SetSizer(self.MainLibrarySizer)
       
   412         
       
   413     def _init_ctrls(self, prnt):
       
   414         wx.Frame.__init__(self, id=ID_PLCOPENEDITOR, name='IDEFrame',
       
   415               parent=prnt, pos=wx.DefaultPosition, size=wx.Size(1000, 600),
       
   416               style=wx.DEFAULT_FRAME_STYLE)
       
   417         self._init_utils()
       
   418         self.SetClientSize(wx.Size(1000, 600))
       
   419         self.SetMenuBar(self.MenuBar)
       
   420         
       
   421         self.TabsImageList = wx.ImageList(31, 16)
       
   422         self.TabsImageListIndexes = {}
       
   423         
       
   424         #-----------------------------------------------------------------------
       
   425         #                          Creating main structure
       
   426         #-----------------------------------------------------------------------
       
   427         
       
   428         if USE_AUI:
       
   429             self.AUIManager = wx.aui.AuiManager(self)
       
   430             self.AUIManager.SetDockSizeConstraint(0.5, 0.5)
       
   431             self.Panes = {}
       
   432             
       
   433             self.LeftNoteBook = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORLEFTNOTEBOOK,
       
   434                   style=wx.aui.AUI_NB_TOP|wx.aui.AUI_NB_TAB_SPLIT|wx.aui.AUI_NB_TAB_MOVE|
       
   435                         wx.aui.AUI_NB_SCROLL_BUTTONS|wx.aui.AUI_NB_TAB_EXTERNAL_MOVE)
       
   436             self.AUIManager.AddPane(self.LeftNoteBook, 
       
   437                   wx.aui.AuiPaneInfo().Caption(_("Project")).Left().Layer(1).
       
   438                   BestSize(wx.Size(300, 500)).CloseButton(False))
       
   439         
       
   440             self.BottomNoteBook = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORBOTTOMNOTEBOOK,
       
   441                   style=wx.aui.AUI_NB_TOP|wx.aui.AUI_NB_TAB_SPLIT|wx.aui.AUI_NB_TAB_MOVE|
       
   442                         wx.aui.AUI_NB_SCROLL_BUTTONS|wx.aui.AUI_NB_TAB_EXTERNAL_MOVE)
       
   443             self.AUIManager.AddPane(self.BottomNoteBook, 
       
   444                   wx.aui.AuiPaneInfo().Bottom().Layer(0).
       
   445                   BestSize(wx.Size(800, 300)).CloseButton(False))
       
   446             
       
   447             self.RightNoteBook = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORRIGHTNOTEBOOK,
       
   448                   style=wx.aui.AUI_NB_TOP|wx.aui.AUI_NB_TAB_SPLIT|wx.aui.AUI_NB_TAB_MOVE|
       
   449                         wx.aui.AUI_NB_SCROLL_BUTTONS|wx.aui.AUI_NB_TAB_EXTERNAL_MOVE)
       
   450             self.AUIManager.AddPane(self.RightNoteBook, 
       
   451                   wx.aui.AuiPaneInfo().Right().Layer(0).
       
   452                   BestSize(wx.Size(250, 400)).CloseButton(False))
       
   453         
       
   454             self.TabsOpened = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORTABSOPENED, 
       
   455                   style=wx.aui.AUI_NB_DEFAULT_STYLE|wx.aui.AUI_NB_WINDOWLIST_BUTTON)
       
   456             self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED,
       
   457                     self.OnPouSelectedChanged)
       
   458             self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE,
       
   459                     self.OnPageClose)
       
   460             self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_END_DRAG,
       
   461                     self.OnPageDragged)
       
   462             self.AUIManager.AddPane(self.TabsOpened, wx.aui.AuiPaneInfo().CentrePane())
       
   463         
       
   464         else:
       
   465             self.MainSplitter = wx.SplitterWindow(id=ID_PLCOPENEDITORMAINSPLITTER,
       
   466                   name='MainSplitter', parent=self, point=wx.Point(0, 0),
       
   467                   size=wx.Size(0, 0), style=wx.SP_3D)
       
   468             self.MainSplitter.SetNeedUpdating(True)
       
   469             self.MainSplitter.SetMinimumPaneSize(1)
       
   470             
       
   471             self.LeftNoteBook = wx.Notebook(id=ID_PLCOPENEDITORLEFTNOTEBOOK,
       
   472                   name='LeftNoteBook', parent=self.MainSplitter, pos=wx.Point(0,
       
   473                   0), size=wx.Size(0, 0), style=0)
       
   474         
       
   475             self.SecondSplitter = wx.SplitterWindow(id=ID_PLCOPENEDITORSECONDSPLITTER,
       
   476                   name='SecondSplitter', parent=self.MainSplitter, point=wx.Point(0, 0),
       
   477                   size=wx.Size(0, 0), style=wx.SP_3D)
       
   478             self.SecondSplitter.SetMinimumPaneSize(1)
       
   479                 
       
   480             self.MainSplitter.SplitVertically(self.LeftNoteBook, self.SecondSplitter, 200)
       
   481             
       
   482             self.ThirdSplitter = wx.SplitterWindow(id=ID_PLCOPENEDITORTHIRDSPLITTER,
       
   483                   name='ThirdSplitter', parent=self.SecondSplitter, point=wx.Point(0, 0),
       
   484                   size=wx.Size(0, 0), style=wx.SP_3D)
       
   485             self.ThirdSplitter.SetMinimumPaneSize(1)
       
   486             
       
   487             self.BottomNoteBook = wx.Notebook(id=ID_PLCOPENEDITORBOTTOMNOTEBOOK,
       
   488                   name='BottomNoteBook', parent=self.SecondSplitter, pos=wx.Point(0,
       
   489                   0), size=wx.Size(0, 0), style=0)
       
   490             
       
   491             self.SecondSplitter.SplitHorizontally(self.ThirdSplitter, self.BottomNoteBook, -200)
       
   492             
       
   493             self.TabsOpened = wx.Notebook(id=ID_PLCOPENEDITORTABSOPENED,
       
   494                   name='TabsOpened', parent=self.ThirdSplitter, pos=wx.Point(0,
       
   495                   0), size=wx.Size(0, 0), style=0)
       
   496             self.TabsOpened.SetImageList(self.TabsImageList)
       
   497             if wx.VERSION >= (2, 6, 0):
       
   498                 self.TabsOpened.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED,
       
   499                     self.OnPouSelectedChanged, id=ID_PLCOPENEDITORTABSOPENED)
       
   500             else:
       
   501                 wx.EVT_NOTEBOOK_PAGE_CHANGED(self.TabsOpened, ID_PLCOPENEDITORTABSOPENED,
       
   502                     self.OnPouSelectedChanged)
       
   503             
       
   504             self.RightNoteBook = wx.Notebook(id=ID_PLCOPENEDITORRIGHTNOTEBOOK,
       
   505                   name='RightNoteBook', parent=self.ThirdSplitter, pos=wx.Point(0,
       
   506                   0), size=wx.Size(0, 0), style=0)
       
   507             
       
   508             self.ThirdSplitter.SplitVertically(self.TabsOpened, self.RightNoteBook, -250)
       
   509         
       
   510         #-----------------------------------------------------------------------
       
   511         #                       Creating PLCopen Project tree
       
   512         #-----------------------------------------------------------------------
       
   513         
       
   514         self.TypesTree = wx.TreeCtrl(id=ID_PLCOPENEDITORTYPESTREE,
       
   515                   name='TypesTree', parent=self.LeftNoteBook, 
       
   516                   pos=wx.Point(0, 0), size=wx.Size(0, 0),
       
   517                   style=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER|wx.TR_EDIT_LABELS)
       
   518         if wx.Platform == '__WXMSW__':
       
   519             self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnTypesTreeRightUp,
       
   520                   id=ID_PLCOPENEDITORTYPESTREE)
       
   521             self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnTypesTreeItemSelected,
       
   522                   id=ID_PLCOPENEDITORTYPESTREE)
       
   523         else:
       
   524             if wx.VERSION >= (2, 6, 0):
       
   525                 self.TypesTree.Bind(wx.EVT_RIGHT_UP, self.OnTypesTreeRightUp)
       
   526                 self.TypesTree.Bind(wx.EVT_LEFT_UP, self.OnTypesTreeLeftUp)
       
   527             else:
       
   528                 wx.EVT_RIGHT_UP(self.TypesTree, self.OnTypesTreeRightUp)
       
   529                 wx.EVT_LEFT_UP(self.TypesTree, self.OnTypesTreeLeftUp)
       
   530             self.Bind(wx.EVT_TREE_SEL_CHANGING, self.OnTypesTreeItemChanging,
       
   531                   id=ID_PLCOPENEDITORTYPESTREE)
       
   532         self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnTypesTreeBeginDrag,
       
   533               id=ID_PLCOPENEDITORTYPESTREE)
       
   534         self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnTypesTreeItemBeginEdit,
       
   535               id=ID_PLCOPENEDITORTYPESTREE)
       
   536         self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnTypesTreeItemEndEdit,
       
   537               id=ID_PLCOPENEDITORTYPESTREE)
       
   538         self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnTypesTreeItemActivated,
       
   539               id=ID_PLCOPENEDITORTYPESTREE)
       
   540         self.LeftNoteBook.AddPage(self.TypesTree, _("Types"))
       
   541 
       
   542         #-----------------------------------------------------------------------
       
   543         #                       Creating PLCopen Project tree
       
   544         #-----------------------------------------------------------------------
       
   545         
       
   546         self.InstancesTree = wx.TreeCtrl(id=ID_PLCOPENEDITORINSTANCESTREE,
       
   547                   name='InstancesTree', parent=self.LeftNoteBook, 
       
   548                   pos=wx.Point(0, 0), size=wx.Size(0, 0),
       
   549                   style=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER)
       
   550         if self.EnableDebug:
       
   551             if wx.VERSION >= (2, 6, 0):
       
   552                 self.InstancesTree.Bind(wx.EVT_RIGHT_UP, self.OnInstancesTreeRightUp)
       
   553             else:
       
   554                 wx.EVT_RIGHT_UP(self.InstancesTree, self.OnInstancesTreeRightUp)
       
   555             self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnInstancesTreeBeginDrag,
       
   556                   id=ID_PLCOPENEDITORINSTANCESTREE)
       
   557             self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnInstancesTreeItemActivated,
       
   558                   id=ID_PLCOPENEDITORINSTANCESTREE)
       
   559         self.LeftNoteBook.AddPage(self.InstancesTree, _("Instances"))
       
   560         
       
   561         #-----------------------------------------------------------------------
       
   562         #                            Creating Tool Bar
       
   563         #-----------------------------------------------------------------------
       
   564 
       
   565         if USE_AUI:
       
   566             ToolBar = wx.ToolBar(self, ID_PLCOPENEDITORTOOLBAR, wx.DefaultPosition, wx.DefaultSize,
       
   567                     wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER)
       
   568             ToolBar.SetToolBitmapSize(wx.Size(25, 25))
       
   569             ToolBar.AddRadioTool(ID_PLCOPENEDITORTOOLBARSELECTION, 
       
   570                   wx.Bitmap(os.path.join(CWD, 'Images', 'select.png')), wx.NullBitmap, _("Select an object"))
       
   571             ToolBar.Realize()
       
   572             self.Panes["ToolBar"] = ToolBar
       
   573             self.AUIManager.AddPane(ToolBar, wx.aui.AuiPaneInfo().
       
   574                       Name("ToolBar").Caption(_("Toolbar")).
       
   575                       ToolbarPane().Top().
       
   576                       LeftDockable(False).RightDockable(False))
       
   577         else:
       
   578             self.ToolBar = self.CreateToolBar(wx.TB_HORIZONTAL|wx.TB_FLAT|wx.NO_BORDER, 
       
   579                   ID_PLCOPENEDITORTOOLBAR, 'ToolBar')
       
   580             self.ToolBar.SetToolBitmapSize(wx.Size(25, 25))
       
   581             self.ToolBar.AddRadioTool(ID_PLCOPENEDITORTOOLBARSELECTION, 
       
   582                   wx.Bitmap(os.path.join(CWD, 'Images', 'select.png')), wx.NullBitmap, _("Select an object"))
       
   583             self.ToolBar.Realize()
       
   584             
       
   585             self.Bind(wx.EVT_TOOL, self.OnSelectionTool, 
       
   586                   id=ID_PLCOPENEDITORTOOLBARSELECTION)
       
   587         
       
   588         self.VariablePanelIndexer = VariablePanelIndexer(self.BottomNoteBook, self)
       
   589         self.BottomNoteBook.AddPage(self.VariablePanelIndexer, _("Variables"))
       
   590 
       
   591         self.LibraryPanel = wx.Panel(id=ID_PLCOPENEDITORLIBRARYPANEL,
       
   592               name='LibraryPanel', parent=self.RightNoteBook, pos=wx.Point(0,
       
   593               0), size=wx.Size(0, 0), style=0)
       
   594         self.RightNoteBook.AddPage(self.LibraryPanel, _("Library"))
       
   595         
       
   596         if wx.Platform == '__WXMSW__':
       
   597             librarytreestyle = wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER
       
   598         else:
       
   599             librarytreestyle = wx.TR_HAS_BUTTONS|wx.TR_HIDE_ROOT|wx.TR_SINGLE|wx.SUNKEN_BORDER
       
   600         self.LibraryTree = wx.TreeCtrl(id=ID_PLCOPENEDITORLIBRARYTREE,
       
   601                   name='LibraryTree', parent=self.LibraryPanel, 
       
   602                   pos=wx.Point(0, 0), size=wx.Size(0, 0),
       
   603                   style=librarytreestyle)
       
   604         self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnLibraryTreeItemSelected,
       
   605               id=ID_PLCOPENEDITORLIBRARYTREE)
       
   606         self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnLibraryTreeBeginDrag,
       
   607               id=ID_PLCOPENEDITORLIBRARYTREE)
       
   608         
       
   609         self.LibraryComment = wx.TextCtrl(id=ID_PLCOPENEDITORLIBRARYCOMMENT,
       
   610                   name='LibraryComment', parent=self.LibraryPanel, 
       
   611                   pos=wx.Point(0, 0), size=wx.Size(0, 60), 
       
   612                   style=wx.TE_READONLY|wx.TE_MULTILINE)
       
   613         
       
   614         self._init_sizers()
       
   615         
       
   616         if self.EnableDebug:
       
   617             self.DebugVariablePanel = DebugVariablePanel(self.RightNoteBook, self.Controler)
       
   618             self.RightNoteBook.AddPage(self.DebugVariablePanel, _("Debugger"))
       
   619         
       
   620         if USE_AUI:
       
   621             self.AUIManager.Update()
       
   622     
       
   623     ## Constructor of the PLCOpenEditor class.
       
   624     #  @param parent The parent window.
       
   625     #  @param controler The controler been used by PLCOpenEditor (default: None).
       
   626     #  @param fileOpen The filepath to open if no controler defined (default: None).
       
   627     #  @param debug The filepath to open if no controler defined (default: False).
       
   628     def __init__(self, parent, enable_debug = False):
       
   629         self.Controler = None
       
   630         self.EnableDebug = enable_debug
       
   631         
       
   632         self._init_ctrls(parent)
       
   633         
       
   634         # Define Tree item icon list
       
   635         self.TreeImageList = wx.ImageList(16, 16)
       
   636         self.TreeImageDict = {}
       
   637         
       
   638         # Icons for languages
       
   639         for language in LANGUAGES:
       
   640             self.TreeImageDict[language]=self.TreeImageList.Add(wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%language)))
       
   641             
       
   642         # Icons for other items
       
   643         for imgname, itemtype in [
       
   644             #editables
       
   645             ("PROJECT",        ITEM_PROJECT),
       
   646             #("POU",            ITEM_POU),
       
   647             #("VARIABLE",       ITEM_VARIABLE),
       
   648             ("TRANSITION",     ITEM_TRANSITION),
       
   649             ("ACTION",         ITEM_ACTION),
       
   650             ("CONFIGURATION",  ITEM_CONFIGURATION),
       
   651             ("RESOURCE",       ITEM_RESOURCE),
       
   652             ("DATATYPE",       ITEM_DATATYPE),
       
   653             # uneditables
       
   654             ("DATATYPES",      ITEM_DATATYPES),
       
   655             ("FUNCTION",       ITEM_FUNCTION),
       
   656             ("FUNCTIONBLOCK",  ITEM_FUNCTIONBLOCK),
       
   657             ("PROGRAM",        ITEM_PROGRAM),
       
   658             ("VAR_LOCAL",      ITEM_VAR_LOCAL),
       
   659             ("VAR_LOCAL",      ITEM_VAR_GLOBAL),
       
   660             ("VAR_LOCAL",      ITEM_VAR_EXTERNAL),
       
   661             ("VAR_LOCAL",      ITEM_VAR_TEMP),
       
   662             ("VAR_INPUT",      ITEM_VAR_INPUT),
       
   663             ("VAR_OUTPUT",     ITEM_VAR_OUTPUT),
       
   664             ("VAR_INOUT",      ITEM_VAR_INOUT),
       
   665             ("TRANSITIONS",    ITEM_TRANSITIONS),
       
   666             ("ACTIONS",        ITEM_ACTIONS),
       
   667             ("CONFIGURATIONS", ITEM_CONFIGURATIONS),
       
   668             ("RESOURCES",      ITEM_RESOURCES),
       
   669             ("PROPERTIES",     ITEM_PROPERTIES)]:
       
   670             self.TreeImageDict[itemtype]=self.TreeImageList.Add(wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%imgname)))
       
   671         
       
   672         # Assign icon list to TreeCtrls
       
   673         self.TypesTree.SetImageList(self.TreeImageList)
       
   674         self.InstancesTree.SetImageList(self.TreeImageList)
       
   675         
       
   676         self.CurrentToolBar = []
       
   677         self.CurrentLanguage = ""
       
   678         self.SelectedItem = None
       
   679         self.Errors = []
       
   680         self.DrawingMode = FREEDRAWING_MODE
       
   681         #self.DrawingMode = DRIVENDRAWING_MODE
       
   682         if USE_AUI:
       
   683             self.AuiTabCtrl = []
       
   684         
       
   685         # Initialize Printing configuring elements
       
   686         self.PrintData = wx.PrintData()
       
   687         self.PrintData.SetPaperId(wx.PAPER_A4)
       
   688         self.PrintData.SetPrintMode(wx.PRINT_MODE_PRINTER)
       
   689         self.PageSetupData = wx.PageSetupDialogData(self.PrintData)
       
   690         self.PageSetupData.SetMarginTopLeft(wx.Point(10, 15))
       
   691         self.PageSetupData.SetMarginBottomRight(wx.Point(10, 20))
       
   692         
       
   693         self.SetRefreshFunctions()
       
   694         
       
   695         self.Maximize()
       
   696         
       
   697 
       
   698 #-------------------------------------------------------------------------------
       
   699 #                               General Functions
       
   700 #-------------------------------------------------------------------------------
       
   701 
       
   702     def SetRefreshFunctions(self):
       
   703         self.RefreshFunctions = {
       
   704             TITLE : self.RefreshTitle,
       
   705             TOOLBAR : self.RefreshToolBar,
       
   706             FILEMENU : self.RefreshFileMenu,
       
   707             EDITMENU : self.RefreshEditMenu,
       
   708             DISPLAYMENU : self.RefreshDisplayMenu,
       
   709             TYPESTREE : self.RefreshTypesTree,
       
   710             INSTANCESTREE : self.RefreshInstancesTree, 
       
   711             LIBRARYTREE : self.RefreshLibraryTree,
       
   712             SCALING : self.RefreshScaling}
       
   713 
       
   714     ## Call PLCOpenEditor refresh functions.
       
   715     #  @param elements List of elements to refresh.
       
   716     def _Refresh(self, *elements):
       
   717         for element in elements:
       
   718             self.RefreshFunctions[element]()
       
   719 
       
   720     ## Callback function when AUINotebook Page closed with CloseButton
       
   721     #  @param event AUINotebook Event.
       
   722     def OnPageClose(self, event):
       
   723         # Get Selected Tab
       
   724         selected = event.GetSelection()
       
   725         if selected >= 0:
       
   726             # Remove corresponding VariablePanel
       
   727             window = self.TabsOpened.GetPage(selected)
       
   728             if not window.IsDebugging():
       
   729                 self.VariablePanelIndexer.RemoveVariablePanel(window.GetTagName())
       
   730             # Refresh Tab selection
       
   731             if self.TabsOpened.GetPageCount() > 0:
       
   732                 new_index = min(selected, self.TabsOpened.GetPageCount() - 1)
       
   733                 self.TabsOpened.SetSelection(new_index)
       
   734                 window = self.TabsOpened.GetPage(selected)
       
   735                 if not window.IsDebugging():
       
   736                     self.VariablePanelIndexer.ChangeVariablePanel(window.GetTagName())
       
   737             # Refresh all window elements that have changed
       
   738             self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU)
       
   739         wx.CallAfter(self.RefreshTabCtrlEvent)
       
   740         event.Skip()
       
   741 
       
   742     def GetCopyBuffer(self):
       
   743         data = None
       
   744         if wx.TheClipboard.IsOpened() or wx.TheClipboard.Open():
       
   745             dataobj = wx.TextDataObject()
       
   746             if wx.TheClipboard.GetData(dataobj):
       
   747                 data = dataobj.GetText()
       
   748         if wx.TheClipboard.IsOpened():
       
   749             wx.TheClipboard.Close()
       
   750         return data
       
   751         
       
   752     def SetCopyBuffer(self, text):
       
   753         if wx.TheClipboard.IsOpened() or wx.TheClipboard.Open():
       
   754             data = wx.TextDataObject()
       
   755             data.SetText(text)
       
   756             wx.TheClipboard.SetData(data)
       
   757             wx.TheClipboard.Flush()
       
   758         if wx.TheClipboard.IsOpened():
       
   759             wx.TheClipboard.Close()
       
   760         self.RefreshEditMenu()
       
   761 
       
   762     def GetDrawingMode(self):
       
   763         return self.DrawingMode
       
   764 
       
   765     def RefreshScaling(self):
       
   766         for i in xrange(self.TabsOpened.GetPageCount()):
       
   767             editor = self.TabsOpened.GetPage(i)
       
   768             editor.RefreshScaling()
       
   769 
       
   770     def ShowProperties(self):
       
   771         old_values = self.Controler.GetProjectProperties()
       
   772         dialog = ProjectDialog(self)
       
   773         dialog.SetValues(old_values)
       
   774         if dialog.ShowModal() == wx.ID_OK:
       
   775             new_values = dialog.GetValues()
       
   776             new_values["creationDateTime"] = old_values["creationDateTime"]
       
   777             if new_values != old_values:
       
   778                 self.Controler.SetProjectProperties(None, new_values)
       
   779                 self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, 
       
   780                               TYPESTREE, INSTANCESTREE, SCALING)
       
   781         dialog.Destroy()
       
   782 
       
   783 #-------------------------------------------------------------------------------
       
   784 #                            Notebook Unified Functions
       
   785 #-------------------------------------------------------------------------------
       
   786 
       
   787     ## Function that generate bitmap for
       
   788     # for wx.aui.AUINotebook.
       
   789     #  @param window Panel to display in tab.
       
   790     #  @param text title for the tab ctrl.
       
   791     def GenerateBitmap(self, icon1_name, icon2_name = None):
       
   792         # Find index of bitmap if already created
       
   793         index = self.TabsImageListIndexes.get((icon1_name, icon2_name), None)
       
   794         # Return index or bitmap if found
       
   795         if index is not None:
       
   796             if USE_AUI:
       
   797                 return self.TabsImageList.GetBitmap(index)
       
   798             else:
       
   799                 return index
       
   800         if icon2_name is None:
       
   801             # Bitmap with only one icon
       
   802             bitmap = wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%icon1_name))
       
   803         else:
       
   804             # Bitmap with two icon
       
   805             icon1 = wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%icon1_name))
       
   806             icon2 = wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%icon2_name))
       
   807             
       
   808             # Calculate bitmap size
       
   809             width = icon1.GetWidth() + icon2.GetWidth() - 1
       
   810             height = max(icon1.GetHeight(), icon2.GetHeight())
       
   811             # Create bitmap with both icons
       
   812             bitmap = wx.EmptyBitmap(width, height)
       
   813             dc = wx.MemoryDC()
       
   814             dc.SelectObject(bitmap)
       
   815             dc.Clear()
       
   816             dc.DrawBitmap(icon1, 0, 0)
       
   817             dc.DrawBitmap(icon2, icon1.GetWidth() - 1, 0)
       
   818             dc.Destroy()
       
   819             
       
   820             # Store bitmap in ImageList
       
   821             index = self.TabsImageList.Add(bitmap)
       
   822             # Save bitmap index in ImageList in dictionary
       
   823             self.TabsImageListIndexes[(icon1_name, icon2_name)] = index
       
   824         if USE_AUI:
       
   825             return bitmap
       
   826         else:
       
   827             return index
       
   828     
       
   829     ## Function that add a tab in Notebook, calling refresh for tab DClick event
       
   830     # for wx.aui.AUINotebook.
       
   831     #  @param window Panel to display in tab.
       
   832     #  @param text title for the tab ctrl.
       
   833     def AddPage(self, window, text):
       
   834         self.TabsOpened.AddPage(window, text)
       
   835         self.RefreshTabCtrlEvent()
       
   836     
       
   837     ## Function that fix difference in deleting all tabs between 
       
   838     # wx.Notebook and wx.aui.AUINotebook.
       
   839     def DeleteAllPages(self):
       
   840         if USE_AUI:
       
   841             for idx in xrange(self.TabsOpened.GetPageCount()):
       
   842                 self.TabsOpened.DeletePage(0)
       
   843         else:
       
   844             self.TabsOpened.DeleteAllPages()
       
   845         self.RefreshTabCtrlEvent()
       
   846 
       
   847     ## Function that fix difference in setting picture on tab between 
       
   848     # wx.Notebook and wx.aui.AUINotebook.
       
   849     #  @param idx Tab index.
       
   850     #  @param bitmap wx.Bitmap to define on tab.
       
   851     #  @return True if operation succeeded
       
   852     def SetPageBitmap(self, idx, bitmap):
       
   853         if USE_AUI:
       
   854             return self.TabsOpened.SetPageBitmap(idx, bitmap)
       
   855         else:
       
   856             return self.TabsOpened.SetPageImage(idx, bitmap)
       
   857 
       
   858 #-------------------------------------------------------------------------------
       
   859 #                         Dialog Message Functions
       
   860 #-------------------------------------------------------------------------------
       
   861 
       
   862     ## Function displaying an Error dialog in PLCOpenEditor.
       
   863     #  @param message The message to display.
       
   864     def ShowErrorMessage(self, message):
       
   865         dialog = wx.MessageDialog(self, message, _("Error"), wx.OK|wx.ICON_ERROR)
       
   866         dialog.ShowModal()
       
   867         dialog.Destroy()
       
   868 
       
   869     ## Function displaying an Error dialog in PLCOpenEditor.
       
   870     #  @return False if closing cancelled.
       
   871     def CheckSaveBeforeClosing(self, title=_("Close Project")):
       
   872         if not self.Controler.ProjectIsSaved():
       
   873             dialog = wx.MessageDialog(self, _("There are changes, do you want to save?"), title, wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION)
       
   874             answer = dialog.ShowModal()
       
   875             dialog.Destroy()
       
   876             if answer == wx.ID_YES:
       
   877                 self.SaveProject()
       
   878             elif answer == wx.ID_CANCEL:
       
   879                 return False
       
   880         return True
       
   881 
       
   882 #-------------------------------------------------------------------------------
       
   883 #                            File Menu Functions
       
   884 #-------------------------------------------------------------------------------
       
   885 
       
   886     def RefreshFileMenu(self):
       
   887         pass
       
   888 
       
   889     def ResetView(self):
       
   890         self.DeleteAllPages()
       
   891         self.VariablePanelIndexer.RemoveAllPanels()
       
   892         self.TypesTree.DeleteAllItems()
       
   893         self.InstancesTree.DeleteAllItems()
       
   894         self.LibraryTree.DeleteAllItems()
       
   895         self.Controler = None
       
   896 
       
   897     def OnCloseTabMenu(self, event):
       
   898         selected = self.TabsOpened.GetSelection()
       
   899         if selected >= 0:
       
   900             window = self.TabsOpened.GetPage(selected)
       
   901             if not window.IsDebugging():
       
   902                 self.VariablePanelIndexer.RemoveVariablePanel(window.GetTagName())
       
   903             self.TabsOpened.DeletePage(selected)
       
   904             if self.TabsOpened.GetPageCount() > 0:
       
   905                 new_index = min(selected, self.TabsOpened.GetPageCount() - 1)
       
   906                 self.TabsOpened.SetSelection(new_index)
       
   907                 window = self.TabsOpened.GetPage(new_index)
       
   908                 if not window.IsDebugging():
       
   909                     self.VariablePanelIndexer.ChangeVariablePanel(window.GetTagName())
       
   910             self._Refresh(TOOLBAR, FILEMENU, EDITMENU)
       
   911 
       
   912     def OnPageSetupMenu(self, event):
       
   913         dialog = wx.PageSetupDialog(self, self.PageSetupData)
       
   914         if dialog.ShowModal() == wx.ID_OK:
       
   915             self.PageSetupData = wx.PageSetupDialogData(dialog.GetPageSetupData())
       
   916             self.PrintData = wx.PrintData(self.PageSetupData.GetPrintData())
       
   917         dialog.Destroy()
       
   918 
       
   919     def OnPreviewMenu(self, event):
       
   920         selected = self.TabsOpened.GetSelection()        
       
   921         if selected != -1:
       
   922             window = self.TabsOpened.GetPage(selected)
       
   923             data = wx.PrintDialogData(self.PrintData)
       
   924             properties = self.Controler.GetProjectProperties(window.IsDebugging())
       
   925             page_size = map(int, properties["pageSize"])
       
   926             margins = (self.PageSetupData.GetMarginTopLeft(), self.PageSetupData.GetMarginBottomRight())
       
   927             printout = GraphicPrintout(window, page_size, margins, True)
       
   928             printout2 = GraphicPrintout(window, page_size, margins, True)
       
   929             preview = wx.PrintPreview(printout, printout2, data)
       
   930 
       
   931             if preview.Ok():
       
   932                 preview_frame = wx.PreviewFrame(preview, self, _("Print preview"))
       
   933 
       
   934                 preview_frame.Initialize()
       
   935                 
       
   936                 preview_frame.Show(True)
       
   937 
       
   938     def OnPrintMenu(self, event):
       
   939         selected = self.TabsOpened.GetSelection()        
       
   940         if selected != -1:
       
   941             window = self.TabsOpened.GetPage(selected)
       
   942             dialog_data = wx.PrintDialogData(self.PrintData)
       
   943             dialog_data.SetToPage(1)
       
   944             properties = self.Controler.GetProjectProperties(window.IsDebugging())
       
   945             page_size = map(int, properties["pageSize"])
       
   946             margins = (self.PageSetupData.GetMarginTopLeft(), self.PageSetupData.GetMarginBottomRight())
       
   947             printer = wx.Printer(dialog_data)
       
   948             printout = GraphicPrintout(window, page_size, margins)
       
   949             
       
   950             if not printer.Print(self, printout, True):
       
   951                 self.ShowErrorMessage(_("There was a problem printing.\nPerhaps your current printer is not set correctly?"))
       
   952             printout.Destroy()
       
   953 
       
   954     def OnPropertiesMenu(self, event):
       
   955         self.ShowProperties()
       
   956 
       
   957     def OnQuitMenu(self, event):
       
   958         self.Close()
       
   959 
       
   960 #-------------------------------------------------------------------------------
       
   961 #                            Edit Menu Functions
       
   962 #-------------------------------------------------------------------------------
       
   963 
       
   964     def RefreshEditMenu(self):
       
   965         if self.Controler is not None:
       
   966             undo, redo = self.Controler.GetBufferState()
       
   967             self.EditMenu.Enable(wx.ID_UNDO, undo)
       
   968             self.EditMenu.Enable(wx.ID_REDO, redo)
       
   969             self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, True)
       
   970             self.EditMenu.Check(ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, 
       
   971                             self.Controler.IsProjectBufferEnabled())
       
   972             self.EditMenu.Enable(wx.ID_ADD, True)
       
   973             self.EditMenu.Enable(wx.ID_DELETE, True)
       
   974             if self.TabsOpened.GetPageCount() > 0:
       
   975                 self.EditMenu.Enable(wx.ID_CUT, True)
       
   976                 self.EditMenu.Enable(wx.ID_COPY, True)
       
   977                 if self.GetCopyBuffer() is not None:
       
   978                     self.EditMenu.Enable(wx.ID_PASTE, True)
       
   979                 else:
       
   980                     self.EditMenu.Enable(wx.ID_PASTE, False)
       
   981                 self.EditMenu.Enable(wx.ID_SELECTALL, True)
       
   982             else:
       
   983                 self.EditMenu.Enable(wx.ID_CUT, False)
       
   984                 self.EditMenu.Enable(wx.ID_COPY, False)
       
   985                 self.EditMenu.Enable(wx.ID_PASTE, False)
       
   986                 self.EditMenu.Enable(wx.ID_SELECTALL, False)
       
   987         else:
       
   988             self.EditMenu.Enable(wx.ID_UNDO, False)
       
   989             self.EditMenu.Enable(wx.ID_REDO, False)
       
   990             self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, False)
       
   991             self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, False)
       
   992             self.EditMenu.Enable(wx.ID_CUT, False)
       
   993             self.EditMenu.Enable(wx.ID_COPY, False)
       
   994             self.EditMenu.Enable(wx.ID_PASTE, False)
       
   995             self.EditMenu.Enable(wx.ID_SELECTALL, False)
       
   996             self.EditMenu.Enable(wx.ID_ADD, False)
       
   997             self.EditMenu.Enable(wx.ID_DELETE, False)
       
   998     
       
   999     def CloseTabsWithoutModel(self):
       
  1000         idxs = range(self.TabsOpened.GetPageCount())
       
  1001         idxs.reverse()
       
  1002         for idx in idxs:
       
  1003             window = self.TabsOpened.GetPage(idx)
       
  1004             if not window.IsDebugging():
       
  1005                 tagname = window.GetTagName()
       
  1006                 if self.Controler.GetEditedElement(tagname) is None:
       
  1007                     self.VariablePanelIndexer.RemoveVariablePanel(tagname)
       
  1008                     self.TabsOpened.DeletePage(idx)
       
  1009 
       
  1010     def CloseDebugTabs(self):
       
  1011         if self.EnableDebug:
       
  1012             idxs = range(self.TabsOpened.GetPageCount())
       
  1013             idxs.reverse()
       
  1014             for idx in idxs:
       
  1015                 window = self.TabsOpened.GetPage(idx)
       
  1016                 if window.IsDebugging():
       
  1017                     self.TabsOpened.DeletePage(idx)
       
  1018             self.DebugVariablePanel.ResetGrid()
       
  1019 
       
  1020     def OnUndoMenu(self, event):
       
  1021         self.Controler.LoadPrevious()
       
  1022         self.CloseTabsWithoutModel()
       
  1023         self.RefreshEditor()
       
  1024         self._Refresh(TITLE, EDITMENU, TYPESTREE, INSTANCESTREE, LIBRARYTREE, 
       
  1025                       SCALING)
       
  1026     
       
  1027     def OnRedoMenu(self, event):
       
  1028         self.Controler.LoadNext()
       
  1029         self.CloseTabsWithoutModel()
       
  1030         self.RefreshEditor()
       
  1031         self._Refresh(TITLE, EDITMENU, TYPESTREE, INSTANCESTREE, LIBRARYTREE, 
       
  1032                       SCALING)
       
  1033     
       
  1034     def OnEnableUndoRedoMenu(self, event):
       
  1035         self.Controler.EnableProjectBuffer(event.IsChecked())
       
  1036         self.RefreshEditMenu()
       
  1037 
       
  1038     OnCutMenu = GetShortcutKeyCallbackFunction("Cut")
       
  1039     OnCopyMenu = GetShortcutKeyCallbackFunction("Copy")
       
  1040     OnPasteMenu = GetShortcutKeyCallbackFunction("Paste")
       
  1041 
       
  1042     def OnSelectAllMenu(self, event):
       
  1043         control = self.FindFocus()
       
  1044         if isinstance(control, (Viewer, TextViewer)):
       
  1045             control.SelectAll()
       
  1046         elif isinstance(control, wx.TextCtrl):
       
  1047             control.SetSelection(0, control.GetLastPosition())
       
  1048         elif isinstance(control, wx.ComboBox):
       
  1049             control.SetMark(0, control.GetLastPosition() + 1)
       
  1050     
       
  1051     DeleteFunctions = {
       
  1052         ITEM_DATATYPE: GetDeleteElementFunction(PLCControler.ProjectRemoveDataType, check_function=PLCControler.DataTypeIsUsed),
       
  1053         ITEM_POU: GetDeleteElementFunction(PLCControler.ProjectRemovePou, check_function=PLCControler.PouIsUsed),
       
  1054         ITEM_TRANSITION: GetDeleteElementFunction(PLCControler.ProjectRemovePouTransition, ITEM_POU),
       
  1055         ITEM_ACTION: GetDeleteElementFunction(PLCControler.ProjectRemovePouAction, ITEM_POU),
       
  1056         ITEM_CONFIGURATION: GetDeleteElementFunction(PLCControler.ProjectRemoveConfiguration),
       
  1057         ITEM_RESOURCE: GetDeleteElementFunction(PLCControler.ProjectRemoveConfigurationResource, ITEM_CONFIGURATION)
       
  1058     }
       
  1059     
       
  1060     def OnDeleteMenu(self, event):
       
  1061         window = self.FindFocus()
       
  1062         if window == self.TypesTree or window is None:
       
  1063             selected = self.TypesTree.GetSelection()
       
  1064             if selected.IsOk():
       
  1065                 type = self.TypesTree.GetPyData(selected)
       
  1066                 function = self.DeleteFunctions.get(type, None)
       
  1067                 if function is not None:
       
  1068                     function(self, selected)
       
  1069                     self.CloseTabsWithoutModel()
       
  1070                     self._Refresh(TITLE, TOOLBAR, EDITMENU, TYPESTREE, 
       
  1071                                   INSTANCESTREE, LIBRARYTREE)
       
  1072         elif isinstance(window, (Viewer, TextViewer)):
       
  1073             event = wx.KeyEvent(wx.EVT_CHAR._getEvtType())
       
  1074             event.m_keyCode = wx.WXK_DELETE
       
  1075             window.ProcessEvent(event)
       
  1076 
       
  1077 
       
  1078 #-------------------------------------------------------------------------------
       
  1079 #                             Display Menu Functions
       
  1080 #-------------------------------------------------------------------------------
       
  1081 
       
  1082     def RefreshDisplayMenu(self):
       
  1083         if self.Controler is not None:
       
  1084             if self.TabsOpened.GetPageCount() > 0:
       
  1085                 self.DisplayMenu.Enable(wx.ID_REFRESH, True)
       
  1086                 selected = self.TabsOpened.GetSelection()
       
  1087                 if selected != -1:
       
  1088                     window = self.TabsOpened.GetPage(selected)
       
  1089                     if isinstance(window, Viewer):
       
  1090                         self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, True)
       
  1091                         zoommenu = self.DisplayMenu.FindItemById(wx.ID_ZOOM_FIT).GetSubMenu()
       
  1092                         zoomitem = zoommenu.FindItemByPosition(window.GetScale())
       
  1093                         zoomitem.Check(True)
       
  1094                     else:
       
  1095                         self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, False)
       
  1096                 else:
       
  1097                     self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, False)
       
  1098             else:
       
  1099                 self.DisplayMenu.Enable(wx.ID_REFRESH, False)
       
  1100                 self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, False)
       
  1101             if self.EnableDebug:
       
  1102                 self.DisplayMenu.Enable(wx.ID_CLEAR, True)
       
  1103         else:
       
  1104             self.DisplayMenu.Enable(wx.ID_REFRESH, False)
       
  1105             if self.EnableDebug:
       
  1106                 self.DisplayMenu.Enable(wx.ID_CLEAR, False)
       
  1107             self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, False)
       
  1108         
       
  1109     def OnRefreshMenu(self, event):
       
  1110         self.RefreshEditor()
       
  1111 
       
  1112     def OnClearErrorsMenu(self, event):
       
  1113         self.ClearErrors()
       
  1114 
       
  1115     def GenerateZoomFunction(self, idx):
       
  1116         def ZoomFunction(event):
       
  1117             selected = self.TabsOpened.GetSelection()
       
  1118             if selected != -1:
       
  1119                 window = self.TabsOpened.GetPage(selected)
       
  1120                 window.SetScale(idx)
       
  1121                 window.RefreshVisibleElements()
       
  1122                 window.RefreshScrollBars()
       
  1123             event.Skip()
       
  1124         return ZoomFunction
       
  1125 
       
  1126 
       
  1127 #-------------------------------------------------------------------------------
       
  1128 #                      Project Editor Panels Management Functions
       
  1129 #-------------------------------------------------------------------------------
       
  1130     
       
  1131     def OnPageDragged(self, event):
       
  1132         wx.CallAfter(self.RefreshTabCtrlEvent)
       
  1133         event.Skip()
       
  1134     
       
  1135     def RefreshTabCtrlEvent(self):
       
  1136         if USE_AUI:
       
  1137             auitabctrl = []
       
  1138             for child in self.TabsOpened.GetChildren():
       
  1139                 if isinstance(child, wx.aui.AuiTabCtrl):
       
  1140                     auitabctrl.append(child)
       
  1141                     if child not in self.AuiTabCtrl:
       
  1142                         child.Bind(wx.EVT_LEFT_DCLICK, self.GetTabsOpenedDClickFunction(child))
       
  1143             self.AuiTabCtrl = auitabctrl
       
  1144             if self.TabsOpened.GetPageCount() == 0:
       
  1145                 pane = self.AUIManager.GetPane(self.TabsOpened)
       
  1146                 if pane.IsMaximized():
       
  1147                     self.AUIManager.RestorePane(pane)
       
  1148                 self.AUIManager.Update()
       
  1149     
       
  1150     def OnPouSelectedChanged(self, event):
       
  1151         old_selected = self.TabsOpened.GetSelection()
       
  1152         if old_selected >= 0:
       
  1153             window = self.TabsOpened.GetPage(old_selected)
       
  1154             if not window.IsDebugging():
       
  1155                 window.ResetBuffer()
       
  1156         selected = event.GetSelection()
       
  1157         if selected >= 0:
       
  1158             window = self.TabsOpened.GetPage(selected)
       
  1159             if not window.IsDebugging():
       
  1160                 self.SelectTypesTreeItem(window.GetTagName())
       
  1161             else:
       
  1162                 self.SelectInstancesTreeItem(self.InstancesTree.GetRootItem(), window.GetInstancePath())
       
  1163             window.RefreshView()
       
  1164             if not window.IsDebugging():
       
  1165                 self.VariablePanelIndexer.ChangeVariablePanel(window.GetTagName())
       
  1166             self._Refresh(FILEMENU, EDITMENU, DISPLAYMENU, TOOLBAR)
       
  1167         event.Skip()
       
  1168 
       
  1169     def RefreshEditor(self, variablepanel = True):
       
  1170         selected = self.TabsOpened.GetSelection()
       
  1171         if selected != -1:
       
  1172             window = self.TabsOpened.GetPage(selected)
       
  1173             window.RefreshView()
       
  1174             if not window.IsDebugging() and variablepanel:
       
  1175                 self.RefreshVariablePanel(window.GetTagName())
       
  1176 
       
  1177     def RefreshVariablePanel(self, tagname):
       
  1178         self.VariablePanelIndexer.RefreshVariablePanel(tagname)
       
  1179 
       
  1180     def RefreshEditorNames(self, old_tagname, new_tagname):
       
  1181         for i in xrange(self.TabsOpened.GetPageCount()):
       
  1182             editor = self.TabsOpened.GetPage(i)
       
  1183             if editor.GetTagName() == old_tagname:
       
  1184                 editor.SetTagName(new_tagname)
       
  1185         self.VariablePanelIndexer.UpdateVariablePanelTagName(old_tagname, new_tagname)
       
  1186 
       
  1187     def IsOpened(self, tagname):
       
  1188         for idx in xrange(self.TabsOpened.GetPageCount()):
       
  1189             if self.TabsOpened.GetPage(idx).IsViewing(tagname):
       
  1190                 return idx
       
  1191         return None
       
  1192 
       
  1193     def RefreshPageTitles(self):
       
  1194         for idx in xrange(self.TabsOpened.GetPageCount()):
       
  1195             window = self.TabsOpened.GetPage(idx)
       
  1196             debug = window.IsDebugging()
       
  1197             words = window.GetTagName().split("::")
       
  1198             if words[0] == "P":
       
  1199                 pou_type = self.Controler.GetEditedElementType(window.GetTagName(), debug)[1].upper()
       
  1200                 pou_body_type = self.Controler.GetEditedElementBodyType(window.GetTagName(), debug)
       
  1201                 self.SetPageBitmap(idx, self.GenerateBitmap(pou_type, pou_body_type))
       
  1202             elif words[0] == "T":
       
  1203                 pou_body_type = self.Controler.GetEditedElementBodyType(window.GetTagName(), debug)
       
  1204                 self.SetPageBitmap(idx, self.GenerateBitmap("TRANSITION", pou_body_type))
       
  1205             elif words[0] == "A":
       
  1206                 pou_body_type = self.Controler.GetEditedElementBodyType(window.GetTagName(), debug)
       
  1207                 self.SetPageBitmap(idx, self.GenerateBitmap("ACTION", pou_body_type))
       
  1208             elif words[0] == "C":
       
  1209                 self.SetPageBitmap(idx, self.GenerateBitmap("CONFIGURATION"))
       
  1210             elif words[0] == "R":
       
  1211                 self.SetPageBitmap(idx, self.GenerateBitmap("RESOURCE"))
       
  1212             elif words[0] == "D":
       
  1213                 self.SetPageBitmap(idx, self.GenerateBitmap("DATATYPE"))
       
  1214             if debug:
       
  1215                 text = window.GetInstancePath()
       
  1216                 if len(text) > 15:
       
  1217                     text = "..." + text[-12:]
       
  1218                 self.TabsOpened.SetPageText(idx, text)
       
  1219             else:
       
  1220                 self.TabsOpened.SetPageText(idx, "-".join(words[1:]))
       
  1221 
       
  1222     def GetTabsOpenedDClickFunction(self, tabctrl):
       
  1223         def OnTabsOpenedDClick(event):
       
  1224             pos = event.GetPosition()
       
  1225             if tabctrl.TabHitTest(pos.x, pos.y, None):
       
  1226                 pane = self.AUIManager.GetPane(self.TabsOpened)
       
  1227                 if pane.IsMaximized():
       
  1228                     self.AUIManager.RestorePane(pane)
       
  1229                 else:
       
  1230                     self.AUIManager.MaximizePane(pane)
       
  1231                 self.AUIManager.Update()
       
  1232             event.Skip()
       
  1233         return OnTabsOpenedDClick
       
  1234 
       
  1235 #-------------------------------------------------------------------------------
       
  1236 #                         Types Tree Management Functions
       
  1237 #-------------------------------------------------------------------------------
       
  1238 
       
  1239     def RefreshTypesTree(self):
       
  1240         infos = self.Controler.GetProjectInfos()
       
  1241         root = self.TypesTree.GetRootItem()
       
  1242         if not root.IsOk():
       
  1243             root = self.TypesTree.AddRoot(infos["name"])
       
  1244         self.GenerateTypesTreeBranch(root, infos)
       
  1245         self.TypesTree.Expand(root)
       
  1246 
       
  1247     def ResetSelectedItem(self):
       
  1248         self.SelectedItem = None
       
  1249 
       
  1250     def GenerateTypesTreeBranch(self, root, infos, topology=False):
       
  1251         to_delete = []
       
  1252         item_name = infos["name"]
       
  1253         self.TypesTree.SetItemText(root, _(item_name))
       
  1254         self.TypesTree.SetPyData(root, infos["type"])
       
  1255         if infos.get("tagname", None) in self.Errors:
       
  1256             self.TypesTree.SetItemBackgroundColour(root, wx.Colour(255, 255, 0))
       
  1257             self.TypesTree.SetItemTextColour(root, wx.RED)
       
  1258         else:
       
  1259             self.TypesTree.SetItemBackgroundColour(root, wx.WHITE)
       
  1260             self.TypesTree.SetItemTextColour(root, wx.BLACK)
       
  1261         if infos["type"] == ITEM_POU:
       
  1262             self.TypesTree.SetItemImage(root, self.TreeImageDict[self.Controler.GetPouBodyType(infos["name"])])
       
  1263         else:
       
  1264             self.TypesTree.SetItemImage(root, self.TreeImageDict[infos["type"]])      
       
  1265             
       
  1266         if wx.VERSION >= (2, 6, 0):
       
  1267             item, root_cookie = self.TypesTree.GetFirstChild(root)
       
  1268         else:
       
  1269             item, root_cookie = self.TypesTree.GetFirstChild(root, 0)
       
  1270         for values in infos["values"]:
       
  1271             if not item.IsOk():
       
  1272                 item = self.TypesTree.AppendItem(root, "")
       
  1273                 if wx.Platform != '__WXMSW__':
       
  1274                     item, root_cookie = self.TypesTree.GetNextChild(root, root_cookie)
       
  1275             self.GenerateTypesTreeBranch(item, values)
       
  1276             item, root_cookie = self.TypesTree.GetNextChild(root, root_cookie)
       
  1277         while item.IsOk():
       
  1278             to_delete.append(item)
       
  1279             item, root_cookie = self.TypesTree.GetNextChild(root, root_cookie)
       
  1280         for item in to_delete:
       
  1281             self.TypesTree.Delete(item)
       
  1282 
       
  1283     def SelectTypesTreeItem(self, tagname):
       
  1284         if self.TypesTree is not None:
       
  1285             root = self.TypesTree.GetRootItem()
       
  1286             words = tagname.split("::")
       
  1287             if words[0] == "D":
       
  1288                 return self.RecursiveTypesTreeItemSelection(root, [(words[1], ITEM_DATATYPE)])
       
  1289             elif words[0] == "P":
       
  1290                 return self.RecursiveTypesTreeItemSelection(root, [(words[1], ITEM_POU)])
       
  1291             elif words[0] == "T":
       
  1292                 return self.RecursiveTypesTreeItemSelection(root, [(words[1], ITEM_POU), (words[2], ITEM_TRANSITION)])
       
  1293             elif words[0] == "A":
       
  1294                 return self.RecursiveTypesTreeItemSelection(root, [(words[1], ITEM_POU), (words[2], ITEM_ACTION)])
       
  1295             elif words[0] == "C":
       
  1296                 return self.RecursiveTypesTreeItemSelection(root, [(words[1], ITEM_CONFIGURATION)])
       
  1297             elif words[0] == "R":
       
  1298                 return self.RecursiveTypesTreeItemSelection(root, [(words[1], ITEM_CONFIGURATION), (words[2], ITEM_RESOURCE)])
       
  1299         return False
       
  1300 
       
  1301     def RecursiveTypesTreeItemSelection(self, root, items):
       
  1302         found = False
       
  1303         if self.TypesTree is not None:
       
  1304             if wx.VERSION >= (2, 6, 0):
       
  1305                 item, root_cookie = self.TypesTree.GetFirstChild(root)
       
  1306             else:
       
  1307                 item, root_cookie = self.TypesTree.GetFirstChild(root, 0)
       
  1308             while item.IsOk() and not found:
       
  1309                 if (self.TypesTree.GetItemText(item), self.TypesTree.GetPyData(item)) == items[0]:
       
  1310                     if len(items) == 1:
       
  1311                         self.SelectedItem = item
       
  1312                         self.TypesTree.SelectItem(item)
       
  1313                         wx.CallAfter(self.ResetSelectedItem)
       
  1314                         return True
       
  1315                     else:
       
  1316                         found = self.RecursiveTypesTreeItemSelection(item, items[1:])
       
  1317                 else:
       
  1318                     found = self.RecursiveTypesTreeItemSelection(item, items)
       
  1319                 item, root_cookie = self.TypesTree.GetNextChild(root, root_cookie)
       
  1320         return found
       
  1321 
       
  1322     def OnTypesTreeBeginDrag(self, event):
       
  1323         if wx.Platform == '__WXMSW__':
       
  1324             self.SelectedItem = event.GetItem()
       
  1325         if self.SelectedItem is not None and self.TypesTree.GetPyData(self.SelectedItem) == ITEM_POU:
       
  1326             block_name = self.TypesTree.GetItemText(self.SelectedItem)
       
  1327             block_type = self.Controler.GetPouType(block_name)
       
  1328             if block_type != "program":
       
  1329                 data = wx.TextDataObject(str((block_name, block_type, "")))
       
  1330                 dragSource = wx.DropSource(self.TypesTree)
       
  1331                 dragSource.SetData(data)
       
  1332                 dragSource.DoDragDrop()
       
  1333             self.ResetSelectedItem()
       
  1334 
       
  1335     def OnTypesTreeItemBeginEdit(self, event):
       
  1336         selected = event.GetItem()
       
  1337         if self.TypesTree.GetPyData(selected) in ITEMS_UNEDITABLE:
       
  1338             event.Veto()
       
  1339         else:
       
  1340             event.Skip()
       
  1341 
       
  1342     def OnTypesTreeItemEndEdit(self, event):
       
  1343         message = None
       
  1344         abort = False
       
  1345         new_name = event.GetLabel()
       
  1346         if new_name != "":
       
  1347             if not TestIdentifier(new_name):
       
  1348                 message = _("\"%s\" is not a valid identifier!")%new_name
       
  1349             elif new_name.upper() in IEC_KEYWORDS:
       
  1350                 message = _("\"%s\" is a keyword. It can't be used!")%new_name
       
  1351             else:
       
  1352                 item = event.GetItem()
       
  1353                 old_name = self.TypesTree.GetItemText(item)
       
  1354                 itemtype = self.TypesTree.GetPyData(item)
       
  1355                 if itemtype == ITEM_PROJECT:
       
  1356                     self.Controler.SetProjectProperties(name = new_name)
       
  1357                 elif itemtype == ITEM_DATATYPE:
       
  1358                     if new_name.upper() in [name.upper() for name in self.Controler.GetProjectDataTypeNames() if name != old_name]:
       
  1359                         message = _("\"%s\" data type already exists!")%new_name
       
  1360                         abort = True
       
  1361                     if not abort:
       
  1362                         self.Controler.ChangeDataTypeName(old_name, new_name)
       
  1363                         self.RefreshEditorNames(self.Controler.ComputeDataTypeName(old_name), 
       
  1364                                                 self.Controler.ComputeDataTypeName(new_name))
       
  1365                         self.RefreshPageTitles()
       
  1366                 elif itemtype == ITEM_POU:
       
  1367                     if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames() if name != old_name]:
       
  1368                         message = _("\"%s\" pou already exists!")%new_name
       
  1369                         abort = True
       
  1370                     elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables()]:
       
  1371                         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)
       
  1372                         if messageDialog.ShowModal() == wx.ID_NO:
       
  1373                             abort = True
       
  1374                         messageDialog.Destroy()
       
  1375                     if not abort:
       
  1376                         self.Controler.ChangePouName(old_name, new_name)
       
  1377                         self.RefreshEditorNames(self.Controler.ComputePouName(old_name), 
       
  1378                                                 self.Controler.ComputePouName(new_name))
       
  1379                         self.RefreshLibraryTree()
       
  1380                         self.RefreshPageTitles()
       
  1381                 elif itemtype == ITEM_TRANSITION:
       
  1382                     pou_name = GetParentName(self.TypesTree, item, ITEM_POU)
       
  1383                     if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
       
  1384                         message = _("A POU named \"%s\" already exists!")%new_name
       
  1385                     elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name) if name != old_name]:
       
  1386                         message = _("A variable with \"%s\" as name already exists in this pou!")%new_name
       
  1387                     else:
       
  1388                         self.Controler.ChangePouTransitionName(pou_name, old_name, new_name)
       
  1389                         self.RefreshEditorNames(self.Controler.ComputePouTransitionName(pou_name, old_name), 
       
  1390                                                 self.Controler.ComputePouTransitionName(pou_name, new_name))
       
  1391                         self.RefreshPageTitles()
       
  1392                 elif itemtype == ITEM_ACTION:
       
  1393                     pou_name = GetParentName(self.TypesTree, item, ITEM_POU)
       
  1394                     if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
       
  1395                         message = _("A POU named \"%s\" already exists!")%new_name
       
  1396                     elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name) if name != old_name]:
       
  1397                         message = _("A variable with \"%s\" as name already exists in this pou!")%new_name
       
  1398                     else:
       
  1399                         self.Controler.ChangePouActionName(pou_name, old_name, new_name)
       
  1400                         self.RefreshEditorNames(self.Controler.ComputePouActionName(pou_name, old_name), 
       
  1401                                                 self.Controler.ComputePouActionName(pou_name, new_name))
       
  1402                         self.RefreshPageTitles()
       
  1403                 elif itemtype == ITEM_CONFIGURATION:
       
  1404                     if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames() if name != old_name]:
       
  1405                         message = _("\"%s\" config already exists!")%new_name
       
  1406                         abort = True
       
  1407                     elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
       
  1408                         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)
       
  1409                         if messageDialog.ShowModal() == wx.ID_NO:
       
  1410                             abort = True
       
  1411                         messageDialog.Destroy()
       
  1412                     elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables()]:
       
  1413                         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)
       
  1414                         if messageDialog.ShowModal() == wx.ID_NO:
       
  1415                             abort = True
       
  1416                         messageDialog.Destroy()
       
  1417                     if not abort:
       
  1418                         self.Controler.ChangeConfigurationName(old_name, new_name)
       
  1419                         self.RefreshEditorNames(self.Controler.ComputeConfigurationName(old_name), 
       
  1420                                                 self.Controler.ComputeConfigurationName(new_name))
       
  1421                         self.RefreshPageTitles()
       
  1422                 elif itemtype == ITEM_RESOURCE:
       
  1423                     config_name = GetParentName(self.TypesTree, item, ITEM_CONFIGURATION)
       
  1424                     if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames()]:
       
  1425                         message = _("\"%s\" config already exists!")%new_name
       
  1426                         abort = True
       
  1427                     elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
       
  1428                         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)
       
  1429                         if messageDialog.ShowModal() == wx.ID_NO:
       
  1430                             abort = True
       
  1431                         messageDialog.Destroy()
       
  1432                     elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables()]:
       
  1433                         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)
       
  1434                         if messageDialog.ShowModal() == wx.ID_NO:
       
  1435                             abort = True
       
  1436                         messageDialog.Destroy()
       
  1437                     if not abort:
       
  1438                         self.Controler.ChangeConfigurationResourceName(config_name, old_name, new_name)
       
  1439                         self.RefreshEditorNames(self.Controler.ComputeConfigurationResourceName(config_name, old_name), 
       
  1440                                                 self.Controler.ComputeConfigurationResourceName(config_name, new_name))
       
  1441                         self.RefreshPageTitles()
       
  1442             if message or abort:
       
  1443                 if message:
       
  1444                     self.ShowErrorMessage(message)
       
  1445                 item = event.GetItem()
       
  1446                 wx.CallAfter(self.TypesTree.EditLabel, item)
       
  1447                 event.Veto()
       
  1448             else:
       
  1449                 wx.CallAfter(self.RefreshTypesTree)
       
  1450                 self.RefreshEditor()
       
  1451                 self._Refresh(TITLE, FILEMENU, EDITMENU)
       
  1452                 event.Skip()
       
  1453     
       
  1454     def OnTypesTreeItemActivated(self, event):
       
  1455         selected = event.GetItem()
       
  1456         name = self.TypesTree.GetItemText(selected)
       
  1457         data = self.TypesTree.GetPyData(selected)
       
  1458         if UNEDITABLE_NAMES_DICT.get(name, name) == "Properties":
       
  1459             self.ShowProperties()
       
  1460         if data == ITEM_DATATYPE:
       
  1461             self.EditProjectElement(data, self.Controler.ComputeDataTypeName(name))
       
  1462         elif data == ITEM_POU:
       
  1463             self.EditProjectElement(data, self.Controler.ComputePouName(name))
       
  1464         elif data == ITEM_CONFIGURATION:
       
  1465             self.EditProjectElement(data, self.Controler.ComputeConfigurationName(name))
       
  1466         elif data == ITEM_RESOURCE:
       
  1467             config_name = GetParentName(self.TypesTree, selected, ITEM_CONFIGURATION)
       
  1468             self.EditProjectElement(data, self.Controler.ComputeConfigurationResourceName(config_name, name))
       
  1469         elif data in [ITEM_TRANSITION, ITEM_ACTION]:
       
  1470             pou_name = GetParentName(self.TypesTree, selected, ITEM_POU)
       
  1471             if data == ITEM_TRANSITION:
       
  1472                 tagname = self.Controler.ComputePouTransitionName(pou_name, name)
       
  1473             elif data == ITEM_ACTION:
       
  1474                 tagname = self.Controler.ComputePouActionName(pou_name, name)
       
  1475             self.EditProjectElement(data, tagname)
       
  1476         event.Skip()
       
  1477     
       
  1478     def TypesTreeItemSelect(self, select_item):
       
  1479         name = self.TypesTree.GetItemText(select_item)
       
  1480         data = self.TypesTree.GetPyData(select_item)
       
  1481         if data == ITEM_DATATYPE:
       
  1482             self.EditProjectElement(data, self.Controler.ComputeDataTypeName(name), True)
       
  1483         elif data == ITEM_POU:
       
  1484             self.EditProjectElement(data, self.Controler.ComputePouName(name), True)
       
  1485         elif data == ITEM_CONFIGURATION:
       
  1486             self.EditProjectElement(data, self.Controler.ComputeConfigurationName(name), True)
       
  1487         elif data == ITEM_RESOURCE:
       
  1488             config_name = GetParentName(self.TypesTree, select_item, ITEM_CONFIGURATION)
       
  1489             self.EditProjectElement(data, self.Controler.ComputeConfigurationResourceName(config_name, name), True)
       
  1490         elif data in [ITEM_TRANSITION, ITEM_ACTION]:
       
  1491             pou_name = GetParentName(self.TypesTree, select_item, ITEM_POU)
       
  1492             if data == ITEM_TRANSITION:
       
  1493                 tagname = self.Controler.ComputePouTransitionName(pou_name, name)
       
  1494             elif data == ITEM_ACTION:
       
  1495                 tagname = self.Controler.ComputePouActionName(pou_name, name)
       
  1496             self.EditProjectElement(data, tagname, True)
       
  1497     
       
  1498     def OnTypesTreeLeftUp(self, event):
       
  1499         if self.SelectedItem is not None:
       
  1500             self.TypesTree.SelectItem(self.SelectedItem)
       
  1501             self.TypesTreeItemSelect(self.SelectedItem)
       
  1502             wx.CallAfter(self.ResetSelectedItem)
       
  1503         event.Skip()
       
  1504     
       
  1505     def OnTypesTreeItemSelected(self, event):
       
  1506         self.TypesTreeItemSelect(event.GetItem())
       
  1507         event.Skip()
       
  1508     
       
  1509     def OnTypesTreeItemChanging(self, event):
       
  1510         if self.TypesTree.GetPyData(event.GetItem()) not in ITEMS_UNEDITABLE and self.SelectedItem is None:
       
  1511             self.SelectedItem = event.GetItem()
       
  1512             event.Veto()
       
  1513         else:
       
  1514             event.Skip()
       
  1515     
       
  1516     def EditProjectElement(self, elementtype, tagname, onlyopened = False):
       
  1517         openedidx = self.IsOpened(tagname)
       
  1518         if openedidx is not None:
       
  1519             old_selected = self.TabsOpened.GetSelection()
       
  1520             if old_selected != openedidx:
       
  1521                 if old_selected >= 0:
       
  1522                     self.TabsOpened.GetPage(old_selected).ResetBuffer()
       
  1523                 self.TabsOpened.SetSelection(openedidx)
       
  1524             self.VariablePanelIndexer.ChangeVariablePanel(tagname)
       
  1525             self.RefreshPageTitles()
       
  1526             self._Refresh(FILEMENU, EDITMENU, TOOLBAR)
       
  1527         elif not onlyopened:
       
  1528             if elementtype == ITEM_CONFIGURATION:
       
  1529                 new_window = ConfigurationEditor(self.TabsOpened, tagname, self, self.Controler)
       
  1530                 self.AddPage(new_window, "")
       
  1531                 self.VariablePanelIndexer.AddVariablePanel(tagname, "config")
       
  1532             elif elementtype == ITEM_RESOURCE:
       
  1533                 new_window = ResourceEditor(self.TabsOpened, tagname, self, self.Controler)
       
  1534                 self.AddPage(new_window, "")
       
  1535                 self.VariablePanelIndexer.AddVariablePanel(tagname, "resource")
       
  1536             elif elementtype in [ITEM_POU, ITEM_TRANSITION, ITEM_ACTION]:
       
  1537                 bodytype = self.Controler.GetEditedElementBodyType(tagname)
       
  1538                 if bodytype == "FBD":
       
  1539                     new_window = Viewer(self.TabsOpened, tagname, self, self.Controler)
       
  1540                     new_window.RefreshScaling(False)
       
  1541                 elif bodytype == "LD":
       
  1542                     new_window = LD_Viewer(self.TabsOpened, tagname, self, self.Controler)
       
  1543                     new_window.RefreshScaling(False)
       
  1544                 elif bodytype == "SFC":
       
  1545                     new_window = SFC_Viewer(self.TabsOpened, tagname, self, self.Controler)
       
  1546                     new_window.RefreshScaling(False)
       
  1547                 else:
       
  1548                     new_window = TextViewer(self.TabsOpened, tagname, self, self.Controler)
       
  1549                     new_window.SetTextSyntax(bodytype)
       
  1550                     if bodytype == "IL":
       
  1551                         new_window.SetKeywords(IL_KEYWORDS)
       
  1552                     else:
       
  1553                         new_window.SetKeywords(ST_KEYWORDS)
       
  1554                 self.AddPage(new_window, "")
       
  1555                 words = tagname.split("::")
       
  1556                 self.VariablePanelIndexer.AddVariablePanel(tagname, self.Controler.GetPouType(words[1]))
       
  1557             elif elementtype == ITEM_DATATYPE:
       
  1558                 new_window = DataTypeEditor(self.TabsOpened, tagname, self, self.Controler)
       
  1559                 self.AddPage(new_window, "")
       
  1560             self.VariablePanelIndexer.ChangeVariablePanel(tagname)
       
  1561             openedidx = self.IsOpened(tagname)
       
  1562             old_selected = self.TabsOpened.GetSelection()
       
  1563             if old_selected != openedidx:
       
  1564                 if old_selected >= 0:
       
  1565                     self.TabsOpened.GetPage(old_selected).ResetBuffer()
       
  1566             for i in xrange(self.TabsOpened.GetPageCount()):
       
  1567                 window = self.TabsOpened.GetPage(i)
       
  1568                 if window.GetTagName() == tagname:
       
  1569                     self.TabsOpened.SetSelection(i)
       
  1570                     window.SetFocus()
       
  1571                     self.RefreshPageTitles()
       
  1572                     self._Refresh(FILEMENU, EDITMENU, TOOLBAR)
       
  1573     
       
  1574     def OnTypesTreeRightUp(self, event):
       
  1575         if wx.Platform == '__WXMSW__':
       
  1576             item = event.GetItem()
       
  1577         else:
       
  1578             item, flags = self.TypesTree.HitTest(wx.Point(event.GetX(), event.GetY()))
       
  1579         self.TypesTree.SelectItem(item)
       
  1580         self.TypesTreeItemSelect(item)
       
  1581         name = self.TypesTree.GetItemText(item)
       
  1582         type = self.TypesTree.GetPyData(item)
       
  1583         if type == ITEM_POU:
       
  1584             menu = wx.Menu(title='')
       
  1585             if self.Controler.GetPouBodyType(name) == "SFC":
       
  1586                 new_id = wx.NewId()
       
  1587                 AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Transition"))
       
  1588                 self.Bind(wx.EVT_MENU, self.GenerateAddTransitionFunction(name), id=new_id)
       
  1589                 new_id = wx.NewId()
       
  1590                 AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Action"))
       
  1591                 self.Bind(wx.EVT_MENU, self.GenerateAddActionFunction(name), id=new_id)
       
  1592                 menu.AppendSeparator()
       
  1593 
       
  1594             new_id = wx.NewId()
       
  1595             AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Copy POU"))
       
  1596             self.Bind(wx.EVT_MENU, self.OnCopyPou, id=new_id)
       
  1597 
       
  1598             pou_type = self.Controler.GetPouType(name)
       
  1599             if pou_type in ["function", "functionBlock"]:
       
  1600                 change_menu = wx.Menu(title='')
       
  1601                 if pou_type == "function":
       
  1602                     new_id = wx.NewId()
       
  1603                     AppendMenu(change_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Function Block"))
       
  1604                     self.Bind(wx.EVT_MENU, self.GenerateChangePouTypeFunction(name, "functionBlock"), id=new_id)
       
  1605                 new_id = wx.NewId()
       
  1606                 AppendMenu(change_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Program"))
       
  1607                 self.Bind(wx.EVT_MENU, self.GenerateChangePouTypeFunction(name, "program"), id=new_id)
       
  1608                 menu.AppendMenu(wx.NewId(), _("Change POU Type To"), change_menu)
       
  1609             new_id = wx.NewId()
       
  1610             AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Rename"))
       
  1611             self.Bind(wx.EVT_MENU, self.OnRenamePouMenu, id=new_id)
       
  1612             new_id = wx.NewId()
       
  1613             AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Delete"))
       
  1614             self.Bind(wx.EVT_MENU, self.OnDeleteMenu, id=new_id)
       
  1615             self.PopupMenu(menu)
       
  1616         elif type == ITEM_CONFIGURATION:
       
  1617             menu = wx.Menu(title='')
       
  1618             new_id = wx.NewId()
       
  1619             AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Resource"))
       
  1620             self.Bind(wx.EVT_MENU, self.GenerateAddResourceFunction(name), id=new_id)
       
  1621             new_id = wx.NewId()
       
  1622             AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Delete"))
       
  1623             self.Bind(wx.EVT_MENU, self.OnDeleteMenu, id=new_id)
       
  1624             self.PopupMenu(menu)
       
  1625         elif type in [ITEM_DATATYPE, ITEM_TRANSITION, ITEM_ACTION, ITEM_RESOURCE]:
       
  1626             menu = wx.Menu(title='')
       
  1627             new_id = wx.NewId()
       
  1628             AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Delete"))
       
  1629             self.Bind(wx.EVT_MENU, self.OnDeleteMenu, id=new_id)
       
  1630             self.PopupMenu(menu)
       
  1631         elif type in ITEMS_UNEDITABLE:
       
  1632             name = UNEDITABLE_NAMES_DICT[name]
       
  1633             if name == "Data Types":
       
  1634                 menu = wx.Menu(title='')
       
  1635                 new_id = wx.NewId()
       
  1636                 AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add DataType"))
       
  1637                 self.Bind(wx.EVT_MENU, self.OnAddDataTypeMenu, id=new_id)
       
  1638                 self.PopupMenu(menu)
       
  1639             elif name in ["Functions", "Function Blocks", "Programs"]:
       
  1640                 menu = wx.Menu(title='')
       
  1641 
       
  1642                 new_id = wx.NewId()
       
  1643                 AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add POU"))
       
  1644                 self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction({"Functions" : "function", "Function Blocks" : "functionBlock", "Programs" : "program"}[name]), id=new_id)
       
  1645 
       
  1646                 new_id = wx.NewId()
       
  1647                 AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Paste POU"))
       
  1648                 self.Bind(wx.EVT_MENU, self.OnPastePou, id=new_id)
       
  1649                 if self.GetCopyBuffer() is None:
       
  1650                     menu.Enable(new_id, False)
       
  1651 
       
  1652                 self.PopupMenu(menu)
       
  1653             elif name == "Configurations":
       
  1654                 menu = wx.Menu(title='')
       
  1655                 new_id = wx.NewId()
       
  1656                 AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Configuration"))
       
  1657                 self.Bind(wx.EVT_MENU, self.OnAddConfigurationMenu, id=new_id)
       
  1658                 self.PopupMenu(menu)
       
  1659             elif name == "Transitions":
       
  1660                 menu = wx.Menu(title='')
       
  1661                 new_id = wx.NewId()
       
  1662                 AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Transition"))
       
  1663                 parent = self.TypesTree.GetItemParent(item)
       
  1664                 parent_type = self.TypesTree.GetPyData(parent)
       
  1665                 while parent_type != ITEM_POU:
       
  1666                     parent = self.TypesTree.GetItemParent(parent)
       
  1667                     parent_type = self.TypesTree.GetPyData(parent)
       
  1668                 self.Bind(wx.EVT_MENU, self.GenerateAddTransitionFunction(self.TypesTree.GetItemText(parent)), id=new_id)
       
  1669                 self.PopupMenu(menu)
       
  1670             elif name == "Actions":
       
  1671                 menu = wx.Menu(title='')
       
  1672                 new_id = wx.NewId()
       
  1673                 AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Action"))
       
  1674                 parent = self.TypesTree.GetItemParent(item)
       
  1675                 parent_type = self.TypesTree.GetPyData(parent)
       
  1676                 while parent_type != ITEM_POU:
       
  1677                     parent = self.TypesTree.GetItemParent(parent)
       
  1678                     parent_type = self.TypesTree.GetPyData(parent)
       
  1679                 self.Bind(wx.EVT_MENU, self.GenerateAddActionFunction(self.TypesTree.GetItemText(parent)), id=new_id)
       
  1680                 self.PopupMenu(menu)
       
  1681             elif name == "Resources":
       
  1682                 menu = wx.Menu(title='')
       
  1683                 new_id = wx.NewId()
       
  1684                 AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Resource"))
       
  1685                 parent = self.TypesTree.GetItemParent(item)
       
  1686                 parent_type = self.TypesTree.GetPyData(parent)
       
  1687                 while parent_type != ITEM_CONFIGURATION:
       
  1688                     parent = self.TypesTree.GetItemParent(parent)
       
  1689                     parent_type = self.TypesTree.GetPyData(parent)
       
  1690                 self.Bind(wx.EVT_MENU, self.GenerateAddResourceFunction(self.TypesTree.GetItemText(parent)), id=new_id)
       
  1691                 self.PopupMenu(menu)
       
  1692         event.Skip()
       
  1693 
       
  1694 
       
  1695 #-------------------------------------------------------------------------------
       
  1696 #                         Instances Tree Management Functions
       
  1697 #-------------------------------------------------------------------------------
       
  1698 
       
  1699     def RefreshInstancesTree(self):
       
  1700         infos = self.Controler.GetProjectTopology(self.EnableDebug)
       
  1701         root = self.InstancesTree.GetRootItem()
       
  1702         if not root.IsOk():
       
  1703             root = self.InstancesTree.AddRoot(infos["name"])
       
  1704         self.GenerateInstancesTreeBranch(root, infos)
       
  1705         self.InstancesTree.Expand(root)
       
  1706 
       
  1707     def GenerateInstancesTreeBranch(self, root, infos):
       
  1708         to_delete = []
       
  1709         if infos.get("elmt_type", None) is not None:
       
  1710             self.InstancesTree.SetItemText(root, "%s (%s)"%(infos["name"], infos["elmt_type"]))
       
  1711         else:
       
  1712             self.InstancesTree.SetItemText(root, infos["name"])
       
  1713         self.InstancesTree.SetPyData(root, (infos["type"], infos.get("tagname", None)))
       
  1714         self.InstancesTree.SetItemImage(root, self.TreeImageDict[infos["type"]])
       
  1715             
       
  1716         if wx.VERSION >= (2, 6, 0):
       
  1717             item, root_cookie = self.InstancesTree.GetFirstChild(root)
       
  1718         else:
       
  1719             item, root_cookie = self.InstancesTree.GetFirstChild(root, 0)
       
  1720         for values in infos["values"]:
       
  1721             if not item.IsOk():
       
  1722                 item = self.InstancesTree.AppendItem(root, "")
       
  1723                 if wx.Platform != '__WXMSW__':
       
  1724                     item, root_cookie = self.InstancesTree.GetNextChild(root, root_cookie)
       
  1725             self.GenerateInstancesTreeBranch(item, values)
       
  1726             item, root_cookie = self.InstancesTree.GetNextChild(root, root_cookie)
       
  1727         while item.IsOk():
       
  1728             to_delete.append(item)
       
  1729             item, root_cookie = self.InstancesTree.GetNextChild(root, root_cookie)
       
  1730         for item in to_delete:
       
  1731             self.InstancesTree.Delete(item)
       
  1732 
       
  1733     def OnInstancesTreeBeginDrag(self, event):
       
  1734         if self.Controler.DebugAvailable():
       
  1735             selected_item = event.GetItem()
       
  1736             selected_infos = self.InstancesTree.GetPyData(selected_item)
       
  1737             if selected_item is not None and selected_infos[0] in ITEMS_VARIABLE:
       
  1738                 var_path = self.InstancesTree.GetItemText(selected_item).split(" (")[0]
       
  1739                 parent_item = self.InstancesTree.GetItemParent(selected_item)
       
  1740                 while self.InstancesTree.GetPyData(parent_item)[0] != ITEM_PROJECT:
       
  1741                     parent_name = self.InstancesTree.GetItemText(parent_item).split(" (")[0]
       
  1742                     var_path = "%s.%s"%(parent_name, var_path)
       
  1743                     parent_item = self.InstancesTree.GetItemParent(parent_item)
       
  1744                 data = wx.TextDataObject(str((var_path, "debug")))
       
  1745                 dragSource = wx.DropSource(self.InstancesTree)
       
  1746                 dragSource.SetData(data)
       
  1747                 dragSource.DoDragDrop()
       
  1748             event.Skip()
       
  1749         else:
       
  1750             event.Veto()
       
  1751 
       
  1752     def OnInstancesTreeItemActivated(self, event):
       
  1753         if self.Controler.DebugAvailable():
       
  1754             selected_item = event.GetItem()
       
  1755             selected_infos = self.InstancesTree.GetPyData(selected_item)
       
  1756             if selected_item is not None and selected_infos[0] in [ITEM_FUNCTIONBLOCK, ITEM_PROGRAM, ITEM_TRANSITION, ITEM_ACTION]:
       
  1757                 instance_path = self.InstancesTree.GetItemText(selected_item).split(" (")[0]
       
  1758                 parent_item = self.InstancesTree.GetItemParent(selected_item)
       
  1759                 while self.InstancesTree.GetPyData(parent_item)[0] != ITEM_PROJECT:
       
  1760                     parent_name = self.InstancesTree.GetItemText(parent_item).split(" (")[0]
       
  1761                     instance_path = "%s.%s"%(parent_name, instance_path)
       
  1762                     parent_item = self.InstancesTree.GetItemParent(parent_item)
       
  1763                 openedidx = self.IsOpened(instance_path)
       
  1764                 if openedidx is not None:
       
  1765                     old_selected = self.TabsOpened.GetSelection()
       
  1766                     if old_selected != openedidx:
       
  1767                         if old_selected >= 0:
       
  1768                             self.TabsOpened.GetPage(old_selected).ResetBuffer()
       
  1769                         self.TabsOpened.SetSelection(openedidx)
       
  1770                 elif selected_infos[1] is not None:
       
  1771                     bodytype = self.Controler.GetEditedElementBodyType(selected_infos[1], True)
       
  1772                     if bodytype == "FBD":
       
  1773                         new_window = Viewer(self.TabsOpened, selected_infos[1], self, self.Controler, True, instance_path)
       
  1774                         new_window.RefreshScaling(False)
       
  1775                     elif bodytype == "LD":
       
  1776                         new_window = LD_Viewer(self.TabsOpened, selected_infos[1], self, self.Controler, True, instance_path)
       
  1777                         new_window.RefreshScaling(False)
       
  1778                     elif bodytype == "SFC":
       
  1779                         new_window = SFC_Viewer(self.TabsOpened, selected_infos[1], self, self.Controler, True, instance_path)
       
  1780                         new_window.RefreshScaling(False)
       
  1781                     else:
       
  1782                         new_window = TextViewer(self.TabsOpened, selected_infos[1], self, self.Controler, True, instance_path)
       
  1783                         new_window.SetTextSyntax(bodytype)
       
  1784                         if bodytype == "IL":
       
  1785                             new_window.SetKeywords(IL_KEYWORDS)
       
  1786                         else:
       
  1787                             new_window.SetKeywords(ST_KEYWORDS)
       
  1788                     self.AddPage(new_window, "")
       
  1789                     new_window.SetFocus()
       
  1790                     self.RefreshPageTitles()
       
  1791             if selected_item is not None and selected_infos[0] in ITEMS_VARIABLE:
       
  1792                 var_path, var_type = self.InstancesTree.GetItemText(selected_item).split(" (")
       
  1793                 var_type = var_type.split(")")[0]
       
  1794                 
       
  1795                 if self.Controler.IsOfType(var_type, "ANY_NUM", True) or\
       
  1796                    self.Controler.IsOfType(var_type, "ANY_BIT", True):
       
  1797                     parent_item = self.InstancesTree.GetItemParent(selected_item)
       
  1798                     while self.InstancesTree.GetPyData(parent_item)[0] != ITEM_PROJECT:
       
  1799                         parent_name = self.InstancesTree.GetItemText(parent_item).split(" (")[0]
       
  1800                         var_path = "%s.%s"%(parent_name, var_path)
       
  1801                         parent_item = self.InstancesTree.GetItemParent(parent_item)
       
  1802                     
       
  1803                     self.OpenGraphicViewer(var_path)
       
  1804         event.Skip()
       
  1805 
       
  1806     def OpenGraphicViewer(self, var_path):
       
  1807         new_window = GraphicViewer(self.TabsOpened, self, self.Controler, var_path)
       
  1808         self.AddPage(new_window, "")
       
  1809         new_window.SetFocus()
       
  1810         self.RefreshPageTitles()
       
  1811 
       
  1812     def OnInstancesTreeRightUp(self, event):
       
  1813         if self.Controler.DebugAvailable():
       
  1814             if wx.Platform == '__WXMSW__':
       
  1815                 selected_item = event.GetItem()
       
  1816             else:
       
  1817                 selected_item = self.InstancesTree.GetSelection()
       
  1818             selected_infos = self.InstancesTree.GetPyData(selected_item)
       
  1819             if selected_item is not None and selected_infos[0] in ITEMS_VARIABLE:
       
  1820                 var_path, var_type = self.InstancesTree.GetItemText(selected_item).split(" (")
       
  1821                 var_type = var_type.split(")")[0]
       
  1822                 
       
  1823                 if self.Controler.IsOfType(var_type, "ANY_NUM", True) or\
       
  1824                    self.Controler.IsOfType(var_type, "ANY_BIT", True):
       
  1825                     parent_item = self.InstancesTree.GetItemParent(selected_item)
       
  1826                     while self.InstancesTree.GetPyData(parent_item)[0] != ITEM_PROJECT:
       
  1827                         parent_name = self.InstancesTree.GetItemText(parent_item).split(" (")[0]
       
  1828                         var_path = "%s.%s"%(parent_name, var_path)
       
  1829                         parent_item = self.InstancesTree.GetItemParent(parent_item)
       
  1830                     
       
  1831                     menu = wx.Menu(title='')
       
  1832                     new_id = wx.NewId()
       
  1833                     AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Graphic Panel"))
       
  1834                     self.Bind(wx.EVT_MENU, self.AddVariableGraphicFunction(var_path), id=new_id)
       
  1835                     new_id = wx.NewId()
       
  1836                     AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("CSV Log"))
       
  1837                     self.PopupMenu(menu)
       
  1838         event.Skip()
       
  1839 
       
  1840     def AddVariableGraphicFunction(self, iec_path):
       
  1841         def AddVariableGraphic(event):
       
  1842             self.OpenGraphicViewer(iec_path)
       
  1843             event.Skip()
       
  1844         return AddVariableGraphic
       
  1845 
       
  1846     def SelectInstancesTreeItem(self, root, instancepath):
       
  1847         found = False
       
  1848         if self.InstancesTree is not None:
       
  1849             paths = instancepath.split(".", 1)
       
  1850             if wx.VERSION >= (2, 6, 0):
       
  1851                 item, root_cookie = self.InstancesTree.GetFirstChild(root)
       
  1852             else:
       
  1853                 item, root_cookie = self.InstancesTree.GetFirstChild(root, 0)
       
  1854             while item.IsOk() and not found:
       
  1855                 name = self.InstancesTree.GetItemText(item).split(" (")[0]
       
  1856                 if name == paths[0]:
       
  1857                     if len(paths) == 1:
       
  1858                         self.InstancesTree.SelectItem(item)
       
  1859                         return True
       
  1860                     else:
       
  1861                         found = self.SelectInstancesTreeItem(item, paths[1])
       
  1862                 item, root_cookie = self.InstancesTree.GetNextChild(root, root_cookie)
       
  1863         return found
       
  1864 
       
  1865     def ResetGraphicViewers(self):
       
  1866         for i in xrange(self.TabsOpened.GetPageCount()):
       
  1867             editor = self.TabsOpened.GetPage(i)
       
  1868             if isinstance(editor, GraphicViewer):
       
  1869                 editor.ResetView()
       
  1870 
       
  1871 #-------------------------------------------------------------------------------
       
  1872 #                         Library Tree Management Functions
       
  1873 #-------------------------------------------------------------------------------
       
  1874 
       
  1875     def RefreshLibraryTree(self):
       
  1876         to_delete = []
       
  1877         blocktypes = self.Controler.GetBlockTypes()
       
  1878         root = self.LibraryTree.GetRootItem()
       
  1879         if not root.IsOk():
       
  1880             if wx.Platform == '__WXMSW__':
       
  1881                 root = self.LibraryTree.AddRoot(_("Block Types"))
       
  1882                 self.LibraryTree.SetPyData(root, {"type" : CATEGORY})
       
  1883             else:
       
  1884                 root = self.LibraryTree.AddRoot("")
       
  1885         if wx.VERSION >= (2, 6, 0):
       
  1886             category_item, root_cookie = self.LibraryTree.GetFirstChild(root)
       
  1887         else:
       
  1888             category_item, root_cookie = self.LibraryTree.GetFirstChild(root, 0)
       
  1889         for category in blocktypes:
       
  1890             category_name = category["name"]
       
  1891             if not category_item.IsOk():
       
  1892                 category_item = self.LibraryTree.AppendItem(root, _(category_name))
       
  1893                 if wx.Platform != '__WXMSW__':
       
  1894                     category_item, root_cookie = self.LibraryTree.GetNextChild(root, root_cookie)
       
  1895             else:
       
  1896                 self.LibraryTree.SetItemText(category_item, _(category_name))
       
  1897             self.LibraryTree.SetPyData(category_item, {"type" : CATEGORY})
       
  1898             if wx.VERSION >= (2, 6, 0):
       
  1899                 blocktype_item, category_cookie = self.LibraryTree.GetFirstChild(category_item)
       
  1900             else:
       
  1901                 blocktype_item, category_cookie = self.LibraryTree.GetFirstChild(category_item, 0)        
       
  1902             for blocktype in category["list"]:
       
  1903                 if not blocktype_item.IsOk():
       
  1904                     blocktype_item = self.LibraryTree.AppendItem(category_item, blocktype["name"])
       
  1905                     if wx.Platform != '__WXMSW__':
       
  1906                         blocktype_item, category_cookie = self.LibraryTree.GetNextChild(category_item, category_cookie)
       
  1907                 else:
       
  1908                     self.LibraryTree.SetItemText(blocktype_item, blocktype["name"])
       
  1909                 self.LibraryTree.SetPyData(blocktype_item, {"type" : BLOCK, "block_type" : blocktype["type"], "inputs" : tuple([type for name, type, modifier in blocktype["inputs"]])})
       
  1910                 blocktype_item, category_cookie = self.LibraryTree.GetNextChild(category_item, category_cookie)
       
  1911             while blocktype_item.IsOk():
       
  1912                 to_delete.append(blocktype_item)
       
  1913                 blocktype_item, category_cookie = self.LibraryTree.GetNextChild(category_item, category_cookie)
       
  1914             category_item, root_cookie = self.LibraryTree.GetNextChild(root, root_cookie)
       
  1915         while category_item.IsOk():
       
  1916             to_delete.append(category_item)
       
  1917             category_item, root_cookie = self.LibraryTree.GetNextChild(root, root_cookie)
       
  1918         for item in to_delete:
       
  1919             self.LibraryTree.Delete(item)
       
  1920         if wx.Platform == '__WXMSW__':        
       
  1921             self.LibraryTree.Expand(root)
       
  1922 
       
  1923     def OnLibraryTreeItemSelected(self, event):
       
  1924         selected = event.GetItem()
       
  1925         pydata = self.LibraryTree.GetPyData(selected)
       
  1926         if pydata is not None and pydata["type"] != CATEGORY:
       
  1927             blocktype = self.Controler.GetBlockType(self.LibraryTree.GetItemText(selected), pydata["inputs"])
       
  1928             if blocktype:
       
  1929                 comment = blocktype["comment"]
       
  1930                 self.LibraryComment.SetValue(_(comment) + blocktype.get("usage", ""))
       
  1931             else:
       
  1932                 self.LibraryComment.SetValue("")
       
  1933         else:
       
  1934             self.LibraryComment.SetValue("")
       
  1935         event.Skip()
       
  1936 
       
  1937     def OnLibraryTreeBeginDrag(self, event):
       
  1938         selected = event.GetItem()
       
  1939         pydata = self.LibraryTree.GetPyData(selected)
       
  1940         if pydata is not None and pydata["type"] == BLOCK:
       
  1941             data = wx.TextDataObject(str((self.LibraryTree.GetItemText(selected), 
       
  1942                 pydata["block_type"], "", pydata["inputs"])))
       
  1943             dragSource = wx.DropSource(self.LibraryTree)
       
  1944             dragSource.SetData(data)
       
  1945             dragSource.DoDragDrop()
       
  1946 
       
  1947 #-------------------------------------------------------------------------------
       
  1948 #                          ToolBar Management Functions
       
  1949 #-------------------------------------------------------------------------------
       
  1950 
       
  1951     def ResetToolBar(self):
       
  1952         for item in self.CurrentToolBar:
       
  1953             if wx.VERSION >= (2, 6, 0):
       
  1954                 self.Unbind(wx.EVT_MENU, id=item)
       
  1955             else:
       
  1956                 self.Disconnect(id=item, eventType=wx.wxEVT_COMMAND_MENU_SELECTED) 
       
  1957             
       
  1958             if USE_AUI:
       
  1959                 ToolBar = self.Panes["ToolBar"]
       
  1960             else:
       
  1961                 ToolBar = self.ToolBar
       
  1962             if ToolBar:
       
  1963                 ToolBar.DeleteTool(item)
       
  1964                 ToolBar.Realize()
       
  1965                 if USE_AUI:
       
  1966                     self.AUIManager.GetPane("ToolBar").BestSize(ToolBar.GetBestSize())
       
  1967                     self.AUIManager.Update()
       
  1968 
       
  1969     def RefreshToolBar(self):
       
  1970         selected = self.TabsOpened.GetSelection()
       
  1971         language = None
       
  1972         if selected != -1:
       
  1973             window = self.TabsOpened.GetPage(selected)
       
  1974             if not window.IsDebugging():
       
  1975                 language = self.Controler.GetEditedElementBodyType(window.GetTagName())
       
  1976         if language is not None and language != self.CurrentLanguage:
       
  1977             self.ResetToolBar()
       
  1978             self.CurrentLanguage = language
       
  1979             self.CurrentToolBar = []
       
  1980             if USE_AUI:
       
  1981                 ToolBar = self.Panes["ToolBar"]
       
  1982             else:
       
  1983                 ToolBar = self.ToolBar
       
  1984             if ToolBar:
       
  1985                 for radio, modes, id, method, picture, help in ToolBarItems[language]:
       
  1986                     if modes & self.DrawingMode:
       
  1987                         if radio or self.DrawingMode == FREEDRAWING_MODE:
       
  1988                             ToolBar.AddRadioTool(id, wx.Bitmap(os.path.join(CWD, "Images", picture)), wx.NullBitmap, help)
       
  1989                         else:
       
  1990                             ToolBar.AddSimpleTool(id, wx.Bitmap(os.path.join(CWD, "Images", picture)), help)
       
  1991                         self.Bind(wx.EVT_TOOL, getattr(self, method), id=id)
       
  1992                         self.CurrentToolBar.append(id)
       
  1993                 ToolBar.Realize()
       
  1994                 if USE_AUI:
       
  1995                     self.AUIManager.GetPane("ToolBar").BestSize(ToolBar.GetBestSize())
       
  1996                     self.AUIManager.Update()
       
  1997         elif not language:
       
  1998             self.ResetToolBar()
       
  1999             self.CurrentLanguage = language
       
  2000         self.ResetCurrentMode()
       
  2001 
       
  2002 
       
  2003 #-------------------------------------------------------------------------------
       
  2004 #                           ToolBar Items Functions
       
  2005 #-------------------------------------------------------------------------------
       
  2006 
       
  2007     def ResetCurrentMode(self):
       
  2008         selected = self.TabsOpened.GetSelection()
       
  2009         if selected != -1:
       
  2010             window = self.TabsOpened.GetPage(selected)
       
  2011             window.SetMode(MODE_SELECTION)
       
  2012         if USE_AUI:
       
  2013             ToolBar = self.Panes["ToolBar"]
       
  2014         else:
       
  2015             ToolBar = self.ToolBar
       
  2016         if ToolBar:
       
  2017             ToolBar.ToggleTool(ID_PLCOPENEDITORTOOLBARSELECTION, False)
       
  2018             ToolBar.ToggleTool(ID_PLCOPENEDITORTOOLBARSELECTION, True)
       
  2019         
       
  2020     def ResetToolToggle(self, id):
       
  2021         if USE_AUI:
       
  2022             tool = self.Panes["ToolBar"].FindById(id)
       
  2023         else:
       
  2024             tool = self.ToolBar.FindById(id)
       
  2025         tool.SetToggle(False)
       
  2026 
       
  2027     def OnSelectionTool(self, event):
       
  2028         selected = self.TabsOpened.GetSelection()
       
  2029         if selected != -1:
       
  2030             self.TabsOpened.GetPage(selected).SetMode(MODE_SELECTION)
       
  2031         event.Skip()
       
  2032     
       
  2033     def OnCommentTool(self, event):
       
  2034         self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARCOMMENT)
       
  2035         selected = self.TabsOpened.GetSelection()
       
  2036         if selected != -1:
       
  2037             self.TabsOpened.GetPage(selected).SetMode(MODE_COMMENT)
       
  2038         event.Skip()
       
  2039     
       
  2040     def OnVariableTool(self, event):
       
  2041         self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARVARIABLE)
       
  2042         selected = self.TabsOpened.GetSelection()
       
  2043         if selected != -1:
       
  2044             self.TabsOpened.GetPage(selected).SetMode(MODE_VARIABLE)
       
  2045         event.Skip()
       
  2046     
       
  2047     def OnBlockTool(self, event):
       
  2048         self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARBLOCK)
       
  2049         selected = self.TabsOpened.GetSelection()
       
  2050         if selected != -1:
       
  2051             self.TabsOpened.GetPage(selected).SetMode(MODE_BLOCK)
       
  2052         event.Skip()
       
  2053         
       
  2054     def OnConnectionTool(self, event):
       
  2055         self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARCONNECTION)
       
  2056         selected = self.TabsOpened.GetSelection()
       
  2057         if selected != -1:
       
  2058             self.TabsOpened.GetPage(selected).SetMode(MODE_CONNECTION)
       
  2059         event.Skip()
       
  2060 
       
  2061     def OnPowerRailTool(self, event):
       
  2062         self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARPOWERRAIL)
       
  2063         selected = self.TabsOpened.GetSelection()
       
  2064         if selected != -1:
       
  2065             self.TabsOpened.GetPage(selected).SetMode(MODE_POWERRAIL)
       
  2066         event.Skip()
       
  2067 
       
  2068     def OnRungTool(self, event):
       
  2069         selected = self.TabsOpened.GetSelection()
       
  2070         if selected != -1:
       
  2071             self.TabsOpened.GetPage(selected).AddLadderRung()
       
  2072         event.Skip()
       
  2073     
       
  2074     def OnCoilTool(self, event):
       
  2075         self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARCOIL)
       
  2076         selected = self.TabsOpened.GetSelection()
       
  2077         if selected != -1:
       
  2078             self.TabsOpened.GetPage(selected).SetMode(MODE_COIL)
       
  2079         event.Skip()
       
  2080     
       
  2081     def OnContactTool(self, event):
       
  2082         if self.DrawingMode == FREEDRAWING_MODE:
       
  2083             self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARCONTACT)
       
  2084         selected = self.TabsOpened.GetSelection()
       
  2085         if selected != -1:
       
  2086             if self.DrawingMode == FREEDRAWING_MODE:
       
  2087                 self.TabsOpened.GetPage(selected).SetMode(MODE_CONTACT)
       
  2088             else:
       
  2089                 self.TabsOpened.GetPage(selected).AddLadderContact()
       
  2090         event.Skip()
       
  2091     
       
  2092     def OnBranchTool(self, event): 
       
  2093         selected = self.TabsOpened.GetSelection()
       
  2094         if selected != -1:
       
  2095             self.TabsOpened.GetPage(selected).AddLadderBranch()
       
  2096         event.Skip()    
       
  2097     
       
  2098     def OnInitialStepTool(self, event):
       
  2099         self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARINITIALSTEP)
       
  2100         selected = self.TabsOpened.GetSelection()
       
  2101         if selected != -1:
       
  2102             self.TabsOpened.GetPage(selected).SetMode(MODE_INITIALSTEP)
       
  2103         event.Skip()
       
  2104     
       
  2105     def OnStepTool(self, event):
       
  2106         if self.GetDrawingMode() == FREEDRAWING_MODE:
       
  2107             self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARSTEP)
       
  2108         selected = self.TabsOpened.GetSelection()
       
  2109         if selected != -1:
       
  2110             if self.GetDrawingMode() == FREEDRAWING_MODE:
       
  2111                 self.TabsOpened.GetPage(selected).SetMode(MODE_STEP)
       
  2112             else:
       
  2113                 self.TabsOpened.GetPage(selected).AddStep()
       
  2114         event.Skip()
       
  2115 
       
  2116     def OnActionBlockTool(self, event):
       
  2117         if self.GetDrawingMode() == FREEDRAWING_MODE:
       
  2118             self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARACTIONBLOCK)
       
  2119         selected = self.TabsOpened.GetSelection()
       
  2120         if selected != -1:
       
  2121             if self.GetDrawingMode() == FREEDRAWING_MODE:
       
  2122                 self.TabsOpened.GetPage(selected).SetMode(MODE_ACTION)
       
  2123             else:
       
  2124                 self.TabsOpened.GetPage(selected).AddStepAction()
       
  2125         event.Skip()
       
  2126 
       
  2127     def OnTransitionTool(self, event):
       
  2128         self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARTRANSITION)
       
  2129         selected = self.TabsOpened.GetSelection()
       
  2130         if selected != -1:
       
  2131             self.TabsOpened.GetPage(selected).SetMode(MODE_TRANSITION)
       
  2132         event.Skip()
       
  2133 
       
  2134     def OnDivergenceTool(self, event):
       
  2135         if self.GetDrawingMode() == FREEDRAWING_MODE:
       
  2136             self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARDIVERGENCE)
       
  2137         selected = self.TabsOpened.GetSelection()
       
  2138         if selected != -1:
       
  2139             if self.GetDrawingMode() == FREEDRAWING_MODE:
       
  2140                 self.TabsOpened.GetPage(selected).SetMode(MODE_DIVERGENCE)
       
  2141             else:
       
  2142                 self.TabsOpened.GetPage(selected).AddDivergence()
       
  2143         event.Skip()
       
  2144     
       
  2145     def OnJumpTool(self, event):
       
  2146         if self.GetDrawingMode() == FREEDRAWING_MODE:
       
  2147             self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARJUMP)
       
  2148         selected = self.TabsOpened.GetSelection()
       
  2149         if selected != -1:
       
  2150             if self.GetDrawingMode() == FREEDRAWING_MODE:
       
  2151                 self.TabsOpened.GetPage(selected).SetMode(MODE_JUMP)
       
  2152             else:
       
  2153                 self.TabsOpened.GetPage(selected).AddJump()
       
  2154         event.Skip()
       
  2155 
       
  2156 
       
  2157 #-------------------------------------------------------------------------------
       
  2158 #                         Add Project Elements Functions
       
  2159 #-------------------------------------------------------------------------------
       
  2160 
       
  2161     def OnAddDataTypeMenu(self, event):
       
  2162         dialog = DataTypeDialog(self, _("Add a new data type"), _("Please enter data type name"), "", wx.OK|wx.CANCEL)
       
  2163         dialog.SetDataTypeNames(self.Controler.GetProjectDataTypeNames())
       
  2164         if dialog.ShowModal() == wx.ID_OK:
       
  2165             self.Controler.ProjectAddDataType(dialog.GetValue())
       
  2166             self._Refresh(TITLE, EDITMENU, TYPESTREE)
       
  2167         dialog.Destroy()
       
  2168 
       
  2169     def GenerateAddPouFunction(self, pou_type):
       
  2170         def OnAddPouMenu(event):
       
  2171             dialog = PouDialog(self, pou_type)
       
  2172             dialog.SetPouNames(self.Controler.GetProjectPouNames())
       
  2173             dialog.SetPouElementNames(self.Controler.GetProjectPouVariables())
       
  2174             if dialog.ShowModal() == wx.ID_OK:
       
  2175                 values = dialog.GetValues()
       
  2176                 self.Controler.ProjectAddPou(values["pouName"], values["pouType"], values["language"])
       
  2177                 self._Refresh(TITLE, EDITMENU, TYPESTREE, LIBRARYTREE)
       
  2178             dialog.Destroy()
       
  2179         return OnAddPouMenu
       
  2180 
       
  2181     def GenerateAddTransitionFunction(self, pou_name):
       
  2182         def OnAddTransitionMenu(event):
       
  2183             dialog = PouTransitionDialog(self)
       
  2184             dialog.SetPouNames(self.Controler.GetProjectPouNames())
       
  2185             dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(pou_name))
       
  2186             if dialog.ShowModal() == wx.ID_OK: 
       
  2187                 values = dialog.GetValues()
       
  2188                 self.Controler.ProjectAddPouTransition(pou_name, values["transitionName"], values["language"])
       
  2189                 self._Refresh(TITLE, EDITMENU, TYPESTREE)
       
  2190                 dialog.Destroy()
       
  2191         return OnAddTransitionMenu
       
  2192 
       
  2193     def GenerateAddActionFunction(self, pou_name):
       
  2194         def OnAddActionMenu(event):
       
  2195             dialog = PouActionDialog(self)
       
  2196             dialog.SetPouNames(self.Controler.GetProjectPouNames())
       
  2197             dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(pou_name))
       
  2198             if dialog.ShowModal() == wx.ID_OK:
       
  2199                 values = dialog.GetValues()
       
  2200                 self.Controler.ProjectAddPouAction(pou_name, values["actionName"], values["language"])
       
  2201                 self._Refresh(TITLE, EDITMENU, TYPESTREE)
       
  2202             dialog.Destroy()
       
  2203         return OnAddActionMenu
       
  2204 
       
  2205     def OnAddConfigurationMenu(self, event):
       
  2206         dialog = ConfigurationNameDialog(self, _("Please enter configuration name"), _("Add new configuration"))
       
  2207         dialog.SetPouNames(self.Controler.GetProjectPouNames())
       
  2208         dialog.SetPouElementNames(self.Controler.GetProjectPouVariables())
       
  2209         if dialog.ShowModal() == wx.ID_OK:
       
  2210             value = dialog.GetValue()
       
  2211             self.Controler.ProjectAddConfiguration(value)
       
  2212             self._Refresh(TITLE, EDITMENU, TYPESTREE, INSTANCESTREE)
       
  2213         dialog.Destroy()
       
  2214 
       
  2215     def GenerateAddResourceFunction(self, config_name):
       
  2216         def OnAddResourceMenu(event):
       
  2217             dialog = ResourceNameDialog(self, _("Please enter resource name"), _("Add new resource"))
       
  2218             dialog.SetPouNames(self.Controler.GetProjectPouNames())
       
  2219             dialog.SetPouElementNames(self.Controler.GetProjectPouVariables())
       
  2220             if dialog.ShowModal() == wx.ID_OK:
       
  2221                 value = dialog.GetValue()
       
  2222                 self.Controler.ProjectAddConfigurationResource(config_name, value)
       
  2223                 self._Refresh(TITLE, EDITMENU, TYPESTREE, INSTANCESTREE)
       
  2224             dialog.Destroy()
       
  2225         return OnAddResourceMenu
       
  2226 
       
  2227     def GenerateChangePouTypeFunction(self, name, new_type):
       
  2228         def OnChangePouTypeMenu(event):
       
  2229             selected = self.TypesTree.GetSelection()
       
  2230             if self.TypesTree.GetPyData(selected) == ITEM_POU: 
       
  2231                 self.Controler.ProjectChangePouType(name, new_type)
       
  2232                 self._Refresh(TITLE, TOOLBAR, EDITMENU, TYPESTREE, LIBRARYTREE)
       
  2233         return OnChangePouTypeMenu
       
  2234 
       
  2235     def OnCreatePouFromMenu(self, event):
       
  2236         selected = self.TypesTree.GetSelection()
       
  2237         if self.TypesTree.GetPyData(selected) == ITEM_POU: 
       
  2238             dialog = PouNameDialog(self, _("Please enter POU name"), _("Create a new POU from"), "", wx.OK|wx.CANCEL)
       
  2239             dialog.SetPouNames(self.Controler.GetProjectPouNames())
       
  2240             if dialog.ShowModal() == wx.ID_OK:
       
  2241                 self.Controler.ProjectCreatePouFrom(dialog.GetValue(), self.TypesTree.GetItemText(selected))
       
  2242                 self._Refresh(TITLE, TOOLBAR, EDITMENU, TYPESTREE, LIBRARYTREE)
       
  2243 
       
  2244     def OnCopyPou(self, event):
       
  2245         selected = self.TypesTree.GetSelection()
       
  2246         pou_name = self.TypesTree.GetItemText(selected)
       
  2247         
       
  2248         pou_xml = self.Controler.GetPouXml(pou_name)
       
  2249         if pou_xml is not None:
       
  2250             self.SetCopyBuffer(pou_xml)
       
  2251             self._Refresh(EDITMENU)
       
  2252 
       
  2253     def OnPastePou(self, event):
       
  2254         selected = self.TypesTree.GetSelection()
       
  2255 
       
  2256         pou_type = self.TypesTree.GetItemText(selected)
       
  2257         pou_type = UNEDITABLE_NAMES_DICT[pou_type] # one of 'Functions', 'Function Blocks' or 'Programs'
       
  2258         pou_type = {'Functions': 'function', 'Function Blocks': 'functionBlock', 'Programs': 'program'}[pou_type]
       
  2259 
       
  2260         pou_xml = self.GetCopyBuffer()
       
  2261 
       
  2262         result = self.Controler.PastePou(pou_type, pou_xml)
       
  2263 
       
  2264         if result is not None:
       
  2265             message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR)
       
  2266             message.ShowModal()
       
  2267             message.Destroy()
       
  2268         else:
       
  2269             self._Refresh(TITLE, TOOLBAR, EDITMENU, TYPESTREE, LIBRARYTREE)
       
  2270 
       
  2271 #-------------------------------------------------------------------------------
       
  2272 #                        Remove Project Elements Functions
       
  2273 #-------------------------------------------------------------------------------
       
  2274 
       
  2275     def OnRemoveDataTypeMenu(self, event):
       
  2276         selected = self.TypesTree.GetSelection()
       
  2277         if self.TypesTree.GetPyData(selected) == ITEM_DATATYPE:
       
  2278             name = self.TypesTree.GetItemText(selected)
       
  2279             if not self.Controler.DataTypeIsUsed(name):
       
  2280                 self.Controler.ProjectRemoveDataType(name)
       
  2281                 tagname = self.Controler.ComputeDataTypeName(name)
       
  2282                 idx = self.IsOpened(tagname)
       
  2283                 if idx is not None:
       
  2284                     self.TabsOpened.DeletePage(idx)
       
  2285                 self._Refresh(TITLE, TOOLBAR, EDITMENU, TYPESTREE)
       
  2286             else:
       
  2287                 self.ShowErrorMessage(_("\"%s\" is used by one or more POUs. It can't be removed!"))
       
  2288 
       
  2289     def OnRenamePouMenu(self, event):
       
  2290         selected = self.TypesTree.GetSelection()
       
  2291         if self.TypesTree.GetPyData(selected) == ITEM_POU: 
       
  2292             wx.CallAfter(self.TypesTree.EditLabel, selected)
       
  2293 
       
  2294     def OnRemovePouMenu(self, event):
       
  2295         selected = self.TypesTree.GetSelection()
       
  2296         if self.TypesTree.GetPyData(selected) == ITEM_POU:
       
  2297             name = self.TypesTree.GetItemText(selected)
       
  2298             if not self.Controler.PouIsUsed(name):
       
  2299                 self.Controler.ProjectRemovePou(name)
       
  2300                 tagname = self.Controler.ComputePouName(name)
       
  2301                 idx = self.IsOpened(tagname)
       
  2302                 if idx is not None:
       
  2303                     self.VariablePanelIndexer.RemoveVariablePanel(tagname)
       
  2304                     self.TabsOpened.DeletePage(idx)
       
  2305                 self._Refresh(TITLE, TOOLBAR, EDITMENU, TYPESTREE, INSTANCESTREE, LIBRARYTREE)
       
  2306             else:
       
  2307                 self.ShowErrorMessage(_("\"%s\" is used by one or more POUs. It can't be removed!"))
       
  2308 
       
  2309     def OnRemoveTransitionMenu(self, event):
       
  2310         selected = self.TypesTree.GetSelection()
       
  2311         if self.TypesTree.GetPyData(selected) == ITEM_TRANSITION: 
       
  2312             transition = self.TypesTree.GetItemText(selected)
       
  2313             item = self.TypesTree.GetItemParent(selected)
       
  2314             item_type = self.TypesTree.GetPyData(item)
       
  2315             while item_type != ITEM_POU:
       
  2316                 item = self.TypesTree.GetItemParent(item)
       
  2317                 item_type = self.TypesTree.GetPyData(item)
       
  2318             pou_name = self.TypesTree.GetItemText(item)
       
  2319             self.Controler.ProjectRemovePouTransition(pou_name, transition)
       
  2320             tagname = self.Controler.ComputePouTransitionName(pou_name, transition)
       
  2321             idx = self.IsOpened(tagname)
       
  2322             if idx is not None:
       
  2323                 self.VariablePanelIndexer.RemoveVariablePanel(tagname)
       
  2324                 self.TabsOpened.DeletePage(idx)
       
  2325             self._Refresh(TITLE, EDITMENU, TYPESTREE)
       
  2326 
       
  2327     def OnRemoveActionMenu(self, event):
       
  2328         selected = self.TypesTree.GetSelection()
       
  2329         if self.TypesTree.GetPyData(selected) == ITEM_ACTION: 
       
  2330             action = self.TypesTree.GetItemText(selected)
       
  2331             item = self.TypesTree.GetItemParent(selected)
       
  2332             item_type = self.TypesTree.GetPyData(item)
       
  2333             while item_type != ITEM_POU:
       
  2334                 item = self.TypesTree.GetItemParent(item)
       
  2335                 item_type = self.TypesTree.GetPyData(item)
       
  2336             pou_name = self.TypesTree.GetItemText(item)
       
  2337             self.Controler.ProjectRemovePouAction(pou_name, action)
       
  2338             tagname = self.Controler.ComputePouActionName(pou_name, action)
       
  2339             idx = self.IsOpened(tagname)
       
  2340             if idx is not None:
       
  2341                 self.VariablePanelIndexer.RemoveVariablePanel(tagname)
       
  2342                 self.TabsOpened.DeletePage(idx)
       
  2343             self._Refresh(TITLE, EDITMENU, TYPESTREE)
       
  2344 
       
  2345     def OnRemoveConfigurationMenu(self, event):
       
  2346         selected = self.TypesTree.GetSelection()
       
  2347         if self.TypesTree.GetPyData(selected) == ITEM_CONFIGURATION: 
       
  2348             name = self.TypesTree.GetItemText(selected)
       
  2349             self.Controler.ProjectRemoveConfiguration(name)
       
  2350             tagname = self.Controler.ComputeConfigurationName(name)
       
  2351             idx = self.IsOpened(tagname)
       
  2352             if idx is not None:
       
  2353                 self.VariablePanelIndexer.RemoveVariablePanel(tagname)
       
  2354                 self.TabsOpened.DeletePage(idx)
       
  2355             self._Refresh(TITLE, EDITMENU, TYPESTREE, INSTANCESTREE)
       
  2356 
       
  2357     def OnRemoveResourceMenu(self, event):
       
  2358         selected = self.TypesTree.GetSelection()
       
  2359         if self.TypesTree.GetPyData(selected) == ITEM_RESOURCE:
       
  2360             resource = self.TypesTree.GetItemText(selected)
       
  2361             item = self.TypesTree.GetItemParent(selected)
       
  2362             item_type = self.TypesTree.GetPyData(item)
       
  2363             while item_type != ITEM_CONFIGURATION:
       
  2364                 item = self.TypesTree.GetItemParent(item)
       
  2365                 item_type = self.TypesTree.GetPyData(item)
       
  2366             config_name = self.TypesTree.GetItemText(item)
       
  2367             self.Controler.ProjectRemoveConfigurationResource(config_name, resource)
       
  2368             tagname = self.Controler.ComputeConfigurationResourceName(config_name, selected)
       
  2369             idx = self.IsOpened(tagname)
       
  2370             if idx is not None:
       
  2371                 self.VariablePanelIndexer.RemoveVariablePanel(tagname)
       
  2372                 self.TabsOpened.DeletePage(idx)
       
  2373             self._Refresh(TITLE, EDITMENU, TYPESTREE, INSTANCESTREE)
       
  2374     
       
  2375     def OnPLCOpenEditorMenu(self, event):
       
  2376         wx.MessageBox(_("No documentation available.\nComing soon."))
       
  2377         
       
  2378     def OnPLCOpenMenu(self, event):
       
  2379         open_pdf(os.path.join(CWD, "plcopen", "TC6_XML_V101.pdf"))
       
  2380     
       
  2381     def OnAboutMenu(self, event):
       
  2382         OpenHtmlFrame(self,_("About PLCOpenEditor"), os.path.join(CWD, "doc","about.html"), wx.Size(350, 350))
       
  2383 
       
  2384 
       
  2385 #-------------------------------------------------------------------------------
       
  2386 #                        Errors showing functions
       
  2387 #-------------------------------------------------------------------------------
       
  2388 
       
  2389     def ShowError(self, infos, start, end):
       
  2390         self.EditProjectElement(self.Controler.GetElementType(infos[0]), infos[0])
       
  2391         self.SelectTypesTreeItem(infos[0])
       
  2392         if infos[1] == "name":
       
  2393             self.Errors.append(infos[0])
       
  2394             self.RefreshTypesTree()
       
  2395             self.TypesTree.Unselect()
       
  2396         elif infos[1] == "variable":
       
  2397             self.VariablePanelIndexer.AddVariableError(infos)
       
  2398         else:
       
  2399             selected = self.TabsOpened.GetSelection()
       
  2400             if selected != -1:
       
  2401                 viewer = self.TabsOpened.GetPage(selected)
       
  2402                 viewer.AddShownError(infos[1:], start, end)
       
  2403                 viewer.RefreshView()
       
  2404     
       
  2405     def ClearErrors(self):
       
  2406         self.Errors = []
       
  2407         self.RefreshTypesTree()
       
  2408         self.VariablePanelIndexer.ClearErrors()
       
  2409         for i in xrange(self.TabsOpened.GetPageCount()):
       
  2410             viewer = self.TabsOpened.GetPage(i)
       
  2411             viewer.ClearErrors()
       
  2412 
       
  2413 #-------------------------------------------------------------------------------
       
  2414 #                            PLCOpenEditor Main Class
       
  2415 #-------------------------------------------------------------------------------
       
  2416 
       
  2417 class PLCOpenEditor(IDEFrame):
       
  2418 
       
  2419     # Compatibility function for wx versions < 2.6
       
  2420     if wx.VERSION < (2, 6, 0):
       
  2421         def Bind(self, event, function, id = None):
       
  2422             if id is not None:
       
  2423                 event(self, id, function)
       
  2424             else:
       
  2425                 event(self, function)
       
  2426 
       
  2427     def _init_coll_FileMenu_Items(self, parent):
       
  2428         AppendMenu(parent, help='', id=wx.ID_NEW,
       
  2429               kind=wx.ITEM_NORMAL, text=_(u'New\tCTRL+N'))
       
  2430         AppendMenu(parent, help='', id=wx.ID_OPEN,
       
  2431               kind=wx.ITEM_NORMAL, text=_(u'Open\tCTRL+O'))
       
  2432         AppendMenu(parent, help='', id=wx.ID_CLOSE,
       
  2433               kind=wx.ITEM_NORMAL, text=_(u'Close Tab\tCTRL+W'))
       
  2434         AppendMenu(parent, help='', id=wx.ID_CLOSE_ALL,
       
  2435               kind=wx.ITEM_NORMAL, text=_(u'Close Project'))
       
  2436         parent.AppendSeparator()
       
  2437         AppendMenu(parent, help='', id=wx.ID_SAVE,
       
  2438               kind=wx.ITEM_NORMAL, text=_(u'Save\tCTRL+S'))
       
  2439         AppendMenu(parent, help='', id=wx.ID_SAVEAS,
       
  2440               kind=wx.ITEM_NORMAL, text=_(u'Save As...\tCTRL+SHIFT+S'))
       
  2441         AppendMenu(parent, help='', id=ID_PLCOPENEDITORFILEMENUGENERATE,
       
  2442               kind=wx.ITEM_NORMAL, text=_(u'Generate Program\tCTRL+G'))
       
  2443         parent.AppendSeparator()
       
  2444         AppendMenu(parent, help='', id=wx.ID_PAGE_SETUP,
       
  2445               kind=wx.ITEM_NORMAL, text=_(u'Page Setup'))
       
  2446         AppendMenu(parent, help='', id=wx.ID_PREVIEW,
       
  2447               kind=wx.ITEM_NORMAL, text=_(u'Preview'))
       
  2448         AppendMenu(parent, help='', id=wx.ID_PRINT,
       
  2449               kind=wx.ITEM_NORMAL, text=_(u'Print'))
       
  2450         parent.AppendSeparator()
       
  2451         AppendMenu(parent, help='', id=wx.ID_PROPERTIES,
       
  2452               kind=wx.ITEM_NORMAL, text=_(u'Properties'))
       
  2453         parent.AppendSeparator()
       
  2454         AppendMenu(parent, help='', id=wx.ID_EXIT,
       
  2455               kind=wx.ITEM_NORMAL, text=_(u'Quit\tCTRL+Q'))
       
  2456         
       
  2457         self.Bind(wx.EVT_MENU, self.OnNewProjectMenu, id=wx.ID_NEW)
       
  2458         self.Bind(wx.EVT_MENU, self.OnOpenProjectMenu, id=wx.ID_OPEN)
       
  2459         self.Bind(wx.EVT_MENU, self.OnCloseTabMenu, id=wx.ID_CLOSE)
       
  2460         self.Bind(wx.EVT_MENU, self.OnCloseProjectMenu, id=wx.ID_CLOSE_ALL)
       
  2461         self.Bind(wx.EVT_MENU, self.OnSaveProjectMenu, id=wx.ID_SAVE)
       
  2462         self.Bind(wx.EVT_MENU, self.OnSaveProjectAsMenu, id=wx.ID_SAVEAS)
       
  2463         self.Bind(wx.EVT_MENU, self.OnGenerateProgramMenu,
       
  2464               id=ID_PLCOPENEDITORFILEMENUGENERATE)
       
  2465         self.Bind(wx.EVT_MENU, self.OnPageSetupMenu, id=wx.ID_PAGE_SETUP)
       
  2466         self.Bind(wx.EVT_MENU, self.OnPreviewMenu, id=wx.ID_PREVIEW)
       
  2467         self.Bind(wx.EVT_MENU, self.OnPrintMenu, id=wx.ID_PRINT)
       
  2468         self.Bind(wx.EVT_MENU, self.OnPropertiesMenu, id=wx.ID_PROPERTIES)
       
  2469         self.Bind(wx.EVT_MENU, self.OnQuitMenu, id=wx.ID_EXIT)
       
  2470 
       
  2471     def _init_coll_HelpMenu_Items(self, parent):
       
  2472         AppendMenu(parent, help='', id=wx.ID_HELP, 
       
  2473             kind=wx.ITEM_NORMAL, text=_(u'PLCOpenEditor\tF1'))
       
  2474         #AppendMenu(parent, help='', id=wx.ID_HELP_CONTENTS,
       
  2475         #      kind=wx.ITEM_NORMAL, text=u'PLCOpen\tF2')
       
  2476         #AppendMenu(parent, help='', id=wx.ID_HELP_CONTEXT,
       
  2477         #      kind=wx.ITEM_NORMAL, text=u'IEC 61131-3\tF3')
       
  2478         AppendMenu(parent, help='', id=wx.ID_ABOUT,
       
  2479             kind=wx.ITEM_NORMAL, text=_(u'About'))
       
  2480         self.Bind(wx.EVT_MENU, self.OnPLCOpenEditorMenu, id=wx.ID_HELP)
       
  2481         #self.Bind(wx.EVT_MENU, self.OnPLCOpenMenu, id=wx.ID_HELP_CONTENTS)
       
  2482         self.Bind(wx.EVT_MENU, self.OnAboutMenu, id=wx.ID_ABOUT)
       
  2483 
       
  2484     ## Constructor of the PLCOpenEditor class.
       
  2485     #  @param parent The parent window.
       
  2486     #  @param controler The controler been used by PLCOpenEditor (default: None).
       
  2487     #  @param fileOpen The filepath to open if no controler defined (default: None).
       
  2488     #  @param debug The filepath to open if no controler defined (default: False).
       
  2489     def __init__(self, parent, fileOpen = None):
       
  2490         IDEFrame.__init__(self, parent)
       
  2491         
       
  2492         # Open the filepath if defined
       
  2493         if fileOpen is not None and os.path.isfile(fileOpen):
       
  2494             # Create a new controller
       
  2495             self.Controler = PLCControler()
       
  2496             self.Controler.OpenXMLFile(fileOpen)
       
  2497             self._Refresh(TYPESTREE, INSTANCESTREE, LIBRARYTREE)
       
  2498         
       
  2499         # Define PLCOpenEditor icon
       
  2500         self.SetIcon(wx.Icon(os.path.join(CWD,"Images", "poe.ico"),wx.BITMAP_TYPE_ICO))
       
  2501 
       
  2502         self.Bind(wx.EVT_CLOSE, self.OnCloseFrame)
       
  2503         
       
  2504         self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU)
       
  2505 
       
  2506     def OnCloseFrame(self, event):
       
  2507         if self.Controler is None or self.CheckSaveBeforeClosing(_("Close Application")):
       
  2508             if USE_AUI:
       
  2509                 self.AUIManager.UnInit()
       
  2510             event.Skip()
       
  2511         else:
       
  2512             event.Veto()
       
  2513 
       
  2514     def RefreshTitle(self):
       
  2515         name = _("PLCOpenEditor")
       
  2516         if self.Controler is not None:
       
  2517             self.SetTitle("%s - %s"%(name, self.Controler.GetFilename()))
       
  2518         else:
       
  2519             self.SetTitle(name)
       
  2520 
       
  2521 #-------------------------------------------------------------------------------
       
  2522 #                            File Menu Functions
       
  2523 #-------------------------------------------------------------------------------
       
  2524 
       
  2525     def RefreshFileMenu(self):
       
  2526         if self.Controler is not None:
       
  2527             selected = self.TabsOpened.GetSelection()
       
  2528             if selected >= 0:
       
  2529                 graphic_viewer = isinstance(self.TabsOpened.GetPage(selected), Viewer)
       
  2530             else:
       
  2531                 graphic_viewer = False
       
  2532             if self.TabsOpened.GetPageCount() > 0:
       
  2533                 self.FileMenu.Enable(wx.ID_CLOSE, True)
       
  2534                 if graphic_viewer:
       
  2535                     self.FileMenu.Enable(wx.ID_PREVIEW, True)
       
  2536                     self.FileMenu.Enable(wx.ID_PRINT, True)
       
  2537                 else:
       
  2538                     self.FileMenu.Enable(wx.ID_PREVIEW, False)
       
  2539                     self.FileMenu.Enable(wx.ID_PRINT, False)
       
  2540             else:
       
  2541                 self.FileMenu.Enable(wx.ID_CLOSE, False)
       
  2542                 self.FileMenu.Enable(wx.ID_PREVIEW, False)
       
  2543                 self.FileMenu.Enable(wx.ID_PRINT, False)
       
  2544             self.FileMenu.Enable(wx.ID_PAGE_SETUP, True)
       
  2545             self.FileMenu.Enable(wx.ID_SAVE, True)
       
  2546             self.FileMenu.Enable(wx.ID_PROPERTIES, True)
       
  2547             self.FileMenu.Enable(wx.ID_CLOSE_ALL, True)
       
  2548             self.FileMenu.Enable(wx.ID_SAVEAS, True)
       
  2549             self.FileMenu.Enable(ID_PLCOPENEDITORFILEMENUGENERATE, True)
       
  2550         else:
       
  2551             self.FileMenu.Enable(wx.ID_CLOSE, False)
       
  2552             self.FileMenu.Enable(wx.ID_PAGE_SETUP, False)
       
  2553             self.FileMenu.Enable(wx.ID_PREVIEW, False)
       
  2554             self.FileMenu.Enable(wx.ID_PRINT, False)
       
  2555             self.FileMenu.Enable(wx.ID_SAVE, False)
       
  2556             self.FileMenu.Enable(wx.ID_PROPERTIES, False)
       
  2557             self.FileMenu.Enable(wx.ID_CLOSE_ALL, False)
       
  2558             self.FileMenu.Enable(wx.ID_SAVEAS, False)
       
  2559             self.FileMenu.Enable(ID_PLCOPENEDITORFILEMENUGENERATE, False)
       
  2560 
       
  2561     def OnNewProjectMenu(self, event):
       
  2562         if self.Controler is not None and not self.CheckSaveBeforeClosing():
       
  2563             return
       
  2564         dialog = ProjectDialog(self)
       
  2565         if dialog.ShowModal() == wx.ID_OK:
       
  2566             properties = dialog.GetValues()
       
  2567             self.ResetView()
       
  2568             self.Controler = PLCControler()
       
  2569             self.Controler.CreateNewProject(properties)
       
  2570             self._Refresh(TITLE, FILEMENU, EDITMENU, TYPESTREE, INSTANCESTREE, 
       
  2571                           LIBRARYTREE)
       
  2572 
       
  2573     def OnOpenProjectMenu(self, event):
       
  2574         if self.Controler is not None and not self.CheckSaveBeforeClosing():
       
  2575             return
       
  2576         filepath = ""
       
  2577         if self.Controler is not None:
       
  2578             filepath = self.Controler.GetFilePath()
       
  2579         if filepath != "":
       
  2580             directory = os.path.dirname(filepath)
       
  2581         else:
       
  2582             directory = os.getcwd()
       
  2583         dialog = wx.FileDialog(self, _("Choose a file"), directory, "",  _("PLCOpen files (*.xml)|*.xml|All files|*.*"), wx.OPEN)
       
  2584         if dialog.ShowModal() == wx.ID_OK:
       
  2585             filepath = dialog.GetPath()
       
  2586             if os.path.isfile(filepath):
       
  2587                 self.ResetView()
       
  2588                 self.Controler = PLCControler()
       
  2589                 self.Controler.OpenXMLFile(filepath)
       
  2590                 self._Refresh(TYPESTREE, INSTANCESTREE, LIBRARYTREE)
       
  2591             self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU)
       
  2592         dialog.Destroy()
       
  2593     
       
  2594     def OnCloseProjectMenu(self, event):
       
  2595         if not self.CheckSaveBeforeClosing():
       
  2596             return
       
  2597         self.ResetView()
       
  2598         self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU)
       
  2599 
       
  2600     def OnSaveProjectMenu(self, event):
       
  2601         self.SaveProject()
       
  2602 
       
  2603     def OnSaveProjectAsMenu(self, event):
       
  2604         self.SaveProjectAs()
       
  2605 
       
  2606     def OnGenerateProgramMenu(self, event):
       
  2607         dialog = wx.FileDialog(self, _("Choose a file"), os.getcwd(), self.Controler.GetProgramFilePath(),  _("ST files (*.st)|*.st|All files|*.*"), wx.SAVE|wx.CHANGE_DIR)
       
  2608         if dialog.ShowModal() == wx.ID_OK:
       
  2609             filepath = dialog.GetPath()
       
  2610             message_text = ""
       
  2611             header, icon = _("Done"), wx.ICON_INFORMATION
       
  2612             if os.path.isdir(os.path.dirname(filepath)):
       
  2613                 program, errors, warnings = self.Controler.GenerateProgram(filepath)
       
  2614                 message_text += "".join([_("warning: %s\n") for warning in warnings])
       
  2615                 if len(errors) > 0:
       
  2616                     message_text += "".join([_("error: %s\n") for warning in warnings])
       
  2617                     message_text += _("Can't generate program to file %s!")%filepath
       
  2618                     header, icon = _("Error"), wx.ICON_ERROR
       
  2619                 else:
       
  2620                     message_text += _("Program was successfully generated!")
       
  2621             else:
       
  2622                 message_text += _("\"%s\" is not a valid folder!")%os.path.dirname(filepath)
       
  2623                 header, icon = _("Error"), wx.ICON_ERROR
       
  2624             message = wx.MessageDialog(self, message_text, header, wx.OK|icon)
       
  2625             message.ShowModal()
       
  2626             message.Destroy()
       
  2627         dialog.Destroy()
       
  2628 
       
  2629     def SaveProject(self):
       
  2630         result = self.Controler.SaveXMLFile()
       
  2631         if not result:
       
  2632             self.SaveProjectAs()
       
  2633         else:
       
  2634             self.RefreshTitle()
       
  2635     
       
  2636     def SaveProjectAs(self):
       
  2637         filepath = self.Controler.GetFilePath()
       
  2638         if filepath != "":
       
  2639             directory, filename = os.path.split(filepath)
       
  2640         else:
       
  2641             directory, filename = os.getcwd(), "%(projectName)s.xml"%self.Controler.GetProjectProperties()
       
  2642         dialog = wx.FileDialog(self, _("Choose a file"), directory, filename,  _("PLCOpen files (*.xml)|*.xml|All files|*.*"), wx.SAVE|wx.OVERWRITE_PROMPT)
       
  2643         if dialog.ShowModal() == wx.ID_OK:
       
  2644             filepath = dialog.GetPath()
       
  2645             if os.path.isdir(os.path.dirname(filepath)):
       
  2646                 result = self.Controler.SaveXMLFile(filepath)
       
  2647                 if not result:
       
  2648                     self.ShowErrorMessage(_("Can't save project to file %s!")%filepath)
       
  2649             else:
       
  2650                 self.ShowErrorMessage(_("\"%s\" is not a valid folder!")%os.path.dirname(filepath))
       
  2651             self.RefreshTitle()
       
  2652         dialog.Destroy()
       
  2653 
       
  2654 #-------------------------------------------------------------------------------
       
  2655 #                            Create Project Dialog
       
  2656 #-------------------------------------------------------------------------------
       
  2657 
       
  2658 [ID_SCALINGPANEL, ID_SCALINGPANELXSCALE, 
       
  2659  ID_SCALINGPANELYSCALE, ID_SCALINGPANELSTATICTEXT1, 
       
  2660  ID_SCALINGPANELSTATICTEXT2, 
       
  2661 ] = [wx.NewId() for _init_ctrls in range(5)]
       
  2662 
       
  2663 class ScalingPanel(wx.Panel):
       
  2664     
       
  2665     def _init_coll_ScalingPanelSizer_Items(self, parent):
       
  2666         parent.AddWindow(self.staticText1, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP|wx.LEFT)
       
  2667         parent.AddWindow(self.XScale, 0, border=10, flag=wx.GROW|wx.TOP|wx.RIGHT)
       
  2668         parent.AddWindow(self.staticText2, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.BOTTOM|wx.LEFT)
       
  2669         parent.AddWindow(self.YScale, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.RIGHT)
       
  2670 
       
  2671     def _init_coll_ScalingPanelSizer_Growables(self, parent):
       
  2672         parent.AddGrowableCol(1)
       
  2673 
       
  2674     def _init_sizers(self):
       
  2675         self.ScalingPanelSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=5)
       
  2676         
       
  2677         self._init_coll_ScalingPanelSizer_Items(self.ScalingPanelSizer)
       
  2678         self._init_coll_ScalingPanelSizer_Growables(self.ScalingPanelSizer)
       
  2679 
       
  2680         self.SetSizer(self.ScalingPanelSizer)
       
  2681 
       
  2682     def _init_ctrls(self, prnt):
       
  2683         wx.Panel.__init__(self, id=ID_SCALINGPANEL,
       
  2684               name='ScalingPanel', parent=prnt, pos=wx.Point(0, 0),
       
  2685               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
  2686         
       
  2687         self.staticText1 = wx.StaticText(id=ID_SCALINGPANELSTATICTEXT1,
       
  2688               label=_('X Scale:'), name='staticText1', parent=self,
       
  2689               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2690         
       
  2691         self.XScale = wx.SpinCtrl(id=ID_SCALINGPANELXSCALE,
       
  2692               name='XScale', parent=self, pos=wx.Point(0, 0),
       
  2693               size=wx.Size(0, 24), style=0, min=0, max=2**16)
       
  2694         
       
  2695         self.staticText2 = wx.StaticText(id=ID_SCALINGPANELSTATICTEXT2,
       
  2696               label=_('Y Scale:'), name='staticText2', parent=self,
       
  2697               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2698         
       
  2699         self.YScale = wx.SpinCtrl(id=ID_SCALINGPANELYSCALE,
       
  2700               name='YScale', parent=self, pos=wx.Point(0, 0),
       
  2701               size=wx.Size(0, 24), style=0, min=0, max=2**16)
       
  2702         
       
  2703         self._init_sizers()
       
  2704         
       
  2705     def __init__(self, parent):
       
  2706         self._init_ctrls(parent)
       
  2707 
       
  2708     def SetScaling(self, x, y):
       
  2709         self.XScale.SetValue(x)
       
  2710         self.YScale.SetValue(y)
       
  2711         
       
  2712     def GetScaling(self):
       
  2713         return self.XScale.GetValue(), self.YScale.GetValue()
       
  2714 
       
  2715 [ID_PROJECTDIALOG, ID_PROJECTDIALOGMAINNOTEBOOK, 
       
  2716  ID_PROJECTDIALOGPROJECTPANEL, ID_PROJECTDIALOGAUTHORPANEL, 
       
  2717  ID_PROJECTDIALOGGRAPHICSPANEL, ID_PROJECTDIALOGMISCELLANEOUSPANEL, 
       
  2718  ID_PROJECTDIALOGPROJECTNAME, ID_PROJECTDIALOGPROJECTVERSION, 
       
  2719  ID_PROJECTDIALOGPRODUCTNAME, ID_PROJECTDIALOGPRODUCTVERSION, 
       
  2720  ID_PROJECTDIALOGPRODUCTRELEASE, ID_PROJECTDIALOGCOMPANYNAME, 
       
  2721  ID_PROJECTDIALOGCOMPANYURL, ID_PROJECTDIALOGAUTHORNAME, 
       
  2722  ID_PROJECTDIALOGORGANIZATION, ID_PROJECTDIALOGLANGUAGE, 
       
  2723  ID_PROJECTDIALOGCONTENTDESCRIPTION, ID_PROJECTDIALOGSCALINGNOTEBOOK, 
       
  2724  ID_PROJECTDIALOGPAGEWIDTH, ID_PROJECTDIALOGPAGEHEIGHT, 
       
  2725  ID_PROJECTDIALOGSTATICTEXT1, ID_PROJECTDIALOGSTATICTEXT2, 
       
  2726  ID_PROJECTDIALOGSTATICTEXT3, ID_PROJECTDIALOGSTATICTEXT4, 
       
  2727  ID_PROJECTDIALOGSTATICTEXT5, ID_PROJECTDIALOGSTATICTEXT6, 
       
  2728  ID_PROJECTDIALOGSTATICTEXT7, ID_PROJECTDIALOGSTATICTEXT8, 
       
  2729  ID_PROJECTDIALOGSTATICTEXT9, ID_PROJECTDIALOGSTATICTEXT10, 
       
  2730  ID_PROJECTDIALOGSTATICTEXT11, ID_PROJECTDIALOGSTATICTEXT12, 
       
  2731  ID_PROJECTDIALOGSTATICTEXT13, ID_PROJECTDIALOGSTATICTEXT14, 
       
  2732  ID_PROJECTDIALOGSTATICTEXT15, 
       
  2733 ] = [wx.NewId() for _init_ctrls in range(35)]
       
  2734 
       
  2735 class ProjectDialog(wx.Dialog):
       
  2736     if wx.VERSION < (2, 6, 0):
       
  2737         def Bind(self, event, function, id = None):
       
  2738             if id is not None:
       
  2739                 event(self, id, function)
       
  2740             else:
       
  2741                 event(self, function)
       
  2742                 
       
  2743     def _init_coll_flexGridSizer1_Items(self, parent):
       
  2744         parent.AddSizer(self.MainNotebook, 0, border=0, flag=wx.GROW)
       
  2745         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
       
  2746         
       
  2747     def _init_coll_flexGridSizer1_Growables(self, parent):
       
  2748         parent.AddGrowableCol(0)
       
  2749         parent.AddGrowableRow(0)
       
  2750     
       
  2751     def _init_coll_ProjectPanelSizer_Items(self, parent):
       
  2752         parent.AddWindow(self.staticText1, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP|wx.LEFT)
       
  2753         parent.AddWindow(self.ProjectName, 0, border=10, flag=wx.GROW|wx.TOP|wx.RIGHT)
       
  2754         parent.AddWindow(self.staticText2, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT)
       
  2755         parent.AddWindow(self.ProjectVersion, 0, border=10, flag=wx.GROW|wx.RIGHT)
       
  2756         parent.AddWindow(self.staticText3, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT)
       
  2757         parent.AddWindow(self.ProductName, 0, border=10, flag=wx.GROW|wx.RIGHT)
       
  2758         parent.AddWindow(self.staticText4, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT)
       
  2759         parent.AddWindow(self.ProductVersion, 0, border=10, flag=wx.GROW|wx.RIGHT)
       
  2760         parent.AddWindow(self.staticText5, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.BOTTOM|wx.LEFT)
       
  2761         parent.AddWindow(self.ProductRelease, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.RIGHT)
       
  2762         
       
  2763     def _init_coll_ProjectPanelSizer_Growables(self, parent):
       
  2764         parent.AddGrowableCol(1)
       
  2765 
       
  2766     def _init_coll_AuthorPanelSizer_Items(self, parent):
       
  2767         parent.AddWindow(self.staticText6, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP|wx.LEFT)
       
  2768         parent.AddWindow(self.CompanyName, 0, border=10, flag=wx.GROW|wx.TOP|wx.RIGHT)
       
  2769         parent.AddWindow(self.staticText7, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT)
       
  2770         parent.AddWindow(self.CompanyURL, 0, border=10, flag=wx.GROW|wx.RIGHT)
       
  2771         parent.AddWindow(self.staticText8, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT)
       
  2772         parent.AddWindow(self.AuthorName, 0, border=10, flag=wx.GROW|wx.RIGHT)
       
  2773         parent.AddWindow(self.staticText9, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.BOTTOM|wx.LEFT)
       
  2774         parent.AddWindow(self.Organization, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.RIGHT)
       
  2775     
       
  2776     def _init_coll_AuthorPanelSizer_Growables(self, parent):
       
  2777         parent.AddGrowableCol(1)
       
  2778     
       
  2779     def _init_coll_GraphicsPanelSizer_Items(self, parent):
       
  2780         parent.AddWindow(self.staticText12, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP|wx.LEFT|wx.RIGHT)
       
  2781         parent.AddSizer(self.GraphicsPageSizeSizer, 0, border=10, flag=wx.GROW|wx.LEFT|wx.RIGHT)
       
  2782         parent.AddWindow(self.staticText15, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT)
       
  2783         parent.AddWindow(self.ScalingNotebook, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.LEFT|wx.RIGHT)
       
  2784         
       
  2785     def _init_coll_GraphicsPanelSizer_Growables(self, parent):
       
  2786         parent.AddGrowableCol(0)
       
  2787         parent.AddGrowableRow(3)
       
  2788     
       
  2789     def _init_coll_GraphicsPageSizeSizer_Items(self, parent):
       
  2790         parent.AddWindow(self.staticText13, 0, border=12, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT)
       
  2791         parent.AddWindow(self.PageWidth, 0, border=0, flag=wx.GROW)
       
  2792         parent.AddWindow(self.staticText14, 0, border=12, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT)
       
  2793         parent.AddWindow(self.PageHeight, 0, border=0, flag=wx.GROW)
       
  2794     
       
  2795     def _init_coll_GraphicsPageSizeSizer_Growables(self, parent):
       
  2796         parent.AddGrowableCol(1)
       
  2797     
       
  2798     def _init_coll_MiscellaneousPanelSizer_Items(self, parent):
       
  2799         parent.AddWindow(self.staticText10, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP|wx.LEFT)
       
  2800         parent.AddWindow(self.Language, 0, border=10, flag=wx.GROW|wx.TOP|wx.RIGHT)
       
  2801         parent.AddWindow(self.staticText11, 0, border=10, flag=wx.BOTTOM|wx.LEFT)
       
  2802         parent.AddWindow(self.ContentDescription, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.RIGHT)
       
  2803         
       
  2804     def _init_coll_MiscellaneousPanelSizer_Growables(self, parent):
       
  2805         parent.AddGrowableCol(1)
       
  2806         parent.AddGrowableRow(1)
       
  2807         
       
  2808     def _init_sizers(self):
       
  2809         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
       
  2810         self.ProjectPanelSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=5, vgap=15)
       
  2811         self.AuthorPanelSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=4, vgap=15)
       
  2812         self.GraphicsPanelSizer = wx.FlexGridSizer(cols=1, hgap=5, rows=4, vgap=5)
       
  2813         self.GraphicsPageSizeSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=5)
       
  2814         self.MiscellaneousPanelSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=15)
       
  2815 
       
  2816         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
  2817         self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1)
       
  2818         self._init_coll_ProjectPanelSizer_Items(self.ProjectPanelSizer)
       
  2819         self._init_coll_ProjectPanelSizer_Growables(self.ProjectPanelSizer)
       
  2820         self._init_coll_AuthorPanelSizer_Items(self.AuthorPanelSizer)
       
  2821         self._init_coll_AuthorPanelSizer_Growables(self.AuthorPanelSizer)
       
  2822         self._init_coll_GraphicsPanelSizer_Items(self.GraphicsPanelSizer)
       
  2823         self._init_coll_GraphicsPanelSizer_Growables(self.GraphicsPanelSizer)
       
  2824         self._init_coll_GraphicsPageSizeSizer_Items(self.GraphicsPageSizeSizer)
       
  2825         self._init_coll_GraphicsPageSizeSizer_Growables(self.GraphicsPageSizeSizer)
       
  2826         self._init_coll_MiscellaneousPanelSizer_Items(self.MiscellaneousPanelSizer)
       
  2827         self._init_coll_MiscellaneousPanelSizer_Growables(self.MiscellaneousPanelSizer)
       
  2828 
       
  2829         self.SetSizer(self.flexGridSizer1)
       
  2830         self.ProjectPanel.SetSizer(self.ProjectPanelSizer)
       
  2831         self.AuthorPanel.SetSizer(self.AuthorPanelSizer)
       
  2832         self.GraphicsPanel.SetSizer(self.GraphicsPanelSizer)
       
  2833         self.MiscellaneousPanel.SetSizer(self.MiscellaneousPanelSizer)
       
  2834 
       
  2835     def _init_ctrls(self, prnt):
       
  2836         wx.Dialog.__init__(self, id=ID_PROJECTDIALOG,
       
  2837               name='ProjectDialog', parent=prnt, pos=wx.Point(376, 223),
       
  2838               size=wx.Size(500, 350), style=wx.DEFAULT_DIALOG_STYLE,
       
  2839               title=_('Project properties'))
       
  2840         self.SetClientSize(wx.Size(500, 350))
       
  2841 
       
  2842         self.MainNotebook = wx.Notebook(id=ID_PROJECTDIALOGMAINNOTEBOOK,
       
  2843                   name='MainNotebook', parent=self, pos=wx.Point(0,
       
  2844                   0), size=wx.Size(0, 0), style=0)
       
  2845 
       
  2846         # Project Panel elements
       
  2847 
       
  2848         self.ProjectPanel = wx.Panel(id=ID_PROJECTDIALOGPROJECTPANEL,
       
  2849               name='ProjectPanel', parent=self.MainNotebook, pos=wx.Point(0, 0),
       
  2850               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
  2851 
       
  2852         self.staticText1 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT1,
       
  2853               label=_('Project Name (required):'), name='staticText1', parent=self.ProjectPanel,
       
  2854               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2855 
       
  2856         self.ProjectName = wx.TextCtrl(id=ID_PROJECTDIALOGPROJECTNAME,
       
  2857               name='ProjectName', parent=self.ProjectPanel, pos=wx.Point(0, 0), 
       
  2858               size=wx.Size(0, 24), style=0)
       
  2859 
       
  2860         self.staticText2 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT2,
       
  2861               label=_('Project Version (optional):'), name='staticText2', parent=self.ProjectPanel,
       
  2862               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2863 
       
  2864         self.ProjectVersion = wx.TextCtrl(id=ID_PROJECTDIALOGPROJECTVERSION,
       
  2865               name='ProjectVersion', parent=self.ProjectPanel, pos=wx.Point(0, 0), 
       
  2866               size=wx.Size(0, 24), style=0)
       
  2867 
       
  2868         self.staticText3 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT3,
       
  2869               label=_('Product Name (required):'), name='staticText3', parent=self.ProjectPanel,
       
  2870               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2871 
       
  2872         self.ProductName = wx.TextCtrl(id=ID_PROJECTDIALOGPRODUCTNAME,
       
  2873               name='ProductName', parent=self.ProjectPanel, pos=wx.Point(0, 0),
       
  2874               size=wx.Size(0, 24), style=0)
       
  2875 
       
  2876         self.staticText4 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT4,
       
  2877               label=_('Product Version (required):'), name='staticText4', parent=self.ProjectPanel,
       
  2878               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2879 
       
  2880         self.ProductVersion = wx.TextCtrl(id=ID_PROJECTDIALOGPRODUCTVERSION,
       
  2881               name='ProductVersion', parent=self.ProjectPanel, pos=wx.Point(0, 0),
       
  2882               size=wx.Size(0, 24), style=0)
       
  2883 
       
  2884         self.staticText5 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT5,
       
  2885               label=_('Product Release (optional):'), name='staticText5', parent=self.ProjectPanel,
       
  2886               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2887 
       
  2888         self.ProductRelease = wx.TextCtrl(id=ID_PROJECTDIALOGPRODUCTRELEASE,
       
  2889               name='ProductRelease', parent=self.ProjectPanel, pos=wx.Point(0, 0),
       
  2890               size=wx.Size(0, 24), style=0)
       
  2891 
       
  2892         self.MainNotebook.AddPage(self.ProjectPanel, _("Project"))
       
  2893         
       
  2894         # Author Panel elements
       
  2895 
       
  2896         self.AuthorPanel = wx.Panel(id=ID_PROJECTDIALOGAUTHORPANEL,
       
  2897               name='AuthorPanel', parent=self.MainNotebook, pos=wx.Point(0, 0),
       
  2898               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
  2899 
       
  2900         self.staticText6 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT6,
       
  2901               label=_('Company Name (required):'), name='staticText6', parent=self.AuthorPanel,
       
  2902               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2903 
       
  2904         self.CompanyName = wx.TextCtrl(id=ID_PROJECTDIALOGCOMPANYNAME,
       
  2905               name='CompanyName', parent=self.AuthorPanel, pos=wx.Point(0, 0),
       
  2906               size=wx.Size(0, 24), style=0)
       
  2907 
       
  2908         self.staticText7 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT7,
       
  2909               label=_('Company URL (optional):'), name='staticText7', parent=self.AuthorPanel,
       
  2910               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2911 
       
  2912         self.CompanyURL = wx.TextCtrl(id=ID_PROJECTDIALOGCOMPANYURL,
       
  2913               name='CompanyURL', parent=self.AuthorPanel, pos=wx.Point(0, 0),
       
  2914               size=wx.Size(0, 24), style=0)
       
  2915 
       
  2916         self.staticText8 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT8,
       
  2917               label=_('Author Name (optional):'), name='staticText8', parent=self.AuthorPanel,
       
  2918               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2919 
       
  2920         self.AuthorName = wx.TextCtrl(id=ID_PROJECTDIALOGAUTHORNAME,
       
  2921               name='AuthorName', parent=self.AuthorPanel, pos=wx.Point(0, 0),
       
  2922               size=wx.Size(0, 24), style=0)
       
  2923 
       
  2924         self.staticText9 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT9,
       
  2925               label=_('Organization (optional):'), name='staticText9', parent=self.AuthorPanel,
       
  2926               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2927 
       
  2928         self.Organization = wx.TextCtrl(id=ID_PROJECTDIALOGORGANIZATION,
       
  2929               name='Organization', parent=self.AuthorPanel, pos=wx.Point(0, 0),
       
  2930               size=wx.Size(0, 24), style=0)
       
  2931 
       
  2932         self.MainNotebook.AddPage(self.AuthorPanel, _("Author"))
       
  2933 
       
  2934         # Graphics Panel elements
       
  2935 
       
  2936         self.GraphicsPanel = wx.Panel(id=ID_PROJECTDIALOGGRAPHICSPANEL,
       
  2937               name='GraphicsPanel', parent=self.MainNotebook, pos=wx.Point(0, 0),
       
  2938               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
  2939 
       
  2940         self.staticText12 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT12,
       
  2941               label=_('Page Size (optional):'), name='staticText12', parent=self.GraphicsPanel,
       
  2942               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2943 
       
  2944         self.staticText13 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT13,
       
  2945               label=_('Width:'), name='staticText13', parent=self.GraphicsPanel,
       
  2946               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2947         
       
  2948         self.PageWidth = wx.SpinCtrl(id=ID_PROJECTDIALOGPAGEWIDTH,
       
  2949               name='PageWidth', parent=self.GraphicsPanel, pos=wx.Point(0, 0),
       
  2950               size=wx.Size(0, 24), style=0, min=0, max=2**16)
       
  2951 
       
  2952         self.staticText14 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT14,
       
  2953               label=_('Height:'), name='staticText14', parent=self.GraphicsPanel,
       
  2954               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2955         
       
  2956         self.PageHeight = wx.SpinCtrl(id=ID_PROJECTDIALOGPAGEHEIGHT,
       
  2957               name='PageHeight', parent=self.GraphicsPanel, pos=wx.Point(0, 0),
       
  2958               size=wx.Size(0, 24), style=0, min=0, max=2**16)
       
  2959         
       
  2960         self.staticText15 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT15,
       
  2961               label=_('Scaling:'), name='staticText15', parent=self.GraphicsPanel,
       
  2962               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2963         
       
  2964         self.ScalingNotebook = wx.Notebook(id=ID_PROJECTDIALOGSCALINGNOTEBOOK,
       
  2965               name='ScalingNotebook', parent=self.GraphicsPanel, pos=wx.Point(0,
       
  2966               0), size=wx.Size(0, 0), style=0)
       
  2967         
       
  2968         self.Scalings = {}
       
  2969         for language, translation in [("FBD",_("FBD")), ("LD",_("LD")), ("SFC",_("SFC"))]:
       
  2970             window = ScalingPanel(self.ScalingNotebook)
       
  2971             self.Scalings[language] = window
       
  2972             self.ScalingNotebook.AddPage(window, translation)
       
  2973         
       
  2974         self.MainNotebook.AddPage(self.GraphicsPanel, _("Graphics"))
       
  2975 
       
  2976         # Miscellaneous Panel elements
       
  2977 
       
  2978         self.MiscellaneousPanel = wx.Panel(id=ID_PROJECTDIALOGMISCELLANEOUSPANEL,
       
  2979               name='MiscellaneousPanel', parent=self.MainNotebook, pos=wx.Point(0, 0),
       
  2980               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
  2981 
       
  2982         self.staticText10 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT10,
       
  2983               label=_('Language (optional):'), name='staticText10', parent=self.MiscellaneousPanel,
       
  2984               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2985 
       
  2986         self.Language = wx.ComboBox(id=ID_PROJECTDIALOGLANGUAGE,
       
  2987               name='Language', parent=self.MiscellaneousPanel, pos=wx.Point(0, 0),
       
  2988               size=wx.Size(0, 28), style=wx.CB_READONLY)
       
  2989 
       
  2990         self.staticText11 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT11,
       
  2991               label=_('Content Description (optional):'), name='staticText11', parent=self.MiscellaneousPanel,
       
  2992               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2993 
       
  2994         self.ContentDescription = wx.TextCtrl(id=ID_PROJECTDIALOGCONTENTDESCRIPTION,
       
  2995               name='ContentDescription', parent=self.MiscellaneousPanel, pos=wx.Point(0, 0),
       
  2996               size=wx.Size(0, 24), style=wx.TE_MULTILINE)
       
  2997 
       
  2998         self.MainNotebook.AddPage(self.MiscellaneousPanel, _("Miscellaneous"))
       
  2999 
       
  3000         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
       
  3001         self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())
       
  3002         
       
  3003         self._init_sizers()
       
  3004 
       
  3005     def __init__(self, parent):
       
  3006         self._init_ctrls(parent)
       
  3007         
       
  3008         languages = ["", "en-US", "fr-FR", "zh-CN"]
       
  3009         
       
  3010         for language in languages:
       
  3011             self.Language.Append(language)
       
  3012         
       
  3013     def OnOK(self, event):
       
  3014         error = []
       
  3015         if self.ProjectName.GetValue() == "":
       
  3016             error.append("Project Name")
       
  3017         if self.CompanyName.GetValue() == "":
       
  3018             error.append("Company Name")
       
  3019         if self.ProductName.GetValue() == "":
       
  3020             error.append("Product Name")
       
  3021         if self.ProductVersion.GetValue() == "":
       
  3022             error.append("Product Version")
       
  3023         if len(error) > 0:
       
  3024             text = ""
       
  3025             for i, item in enumerate(error):
       
  3026                 if i == 0:
       
  3027                     text += item
       
  3028                 elif i == len(error) - 1:
       
  3029                     text += " and %s"%item
       
  3030                 else:
       
  3031                     text += ", %s"%item
       
  3032             message = wx.MessageDialog(self, _("Form isn't complete. %s must be filled!")%text, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3033             message.ShowModal()
       
  3034             message.Destroy()
       
  3035         else:
       
  3036             self.EndModal(wx.ID_OK)
       
  3037 
       
  3038     def SetValues(self, values):
       
  3039         for item, value in values.items():
       
  3040             if item == "projectName":
       
  3041                 self.ProjectName.SetValue(value)
       
  3042             elif item == "projectVersion":
       
  3043                 self.ProjectVersion.SetValue(value)
       
  3044             elif item == "productName":
       
  3045                 self.ProductName.SetValue(value)
       
  3046             elif item == "productVersion":
       
  3047                 self.ProductVersion.SetValue(value)
       
  3048             elif item == "productRelease":
       
  3049                 self.ProductRelease.SetValue(value)
       
  3050             elif item == "companyName":
       
  3051                 self.CompanyName.SetValue(value)
       
  3052             elif item == "companyURL":
       
  3053                 self.CompanyURL.SetValue(value)
       
  3054             elif item == "authorName":
       
  3055                 self.AuthorName.SetValue(value)
       
  3056             elif item == "organization":
       
  3057                 self.Organization.SetValue(value)
       
  3058             elif item == "language":
       
  3059                 self.Language.SetStringSelection(value)
       
  3060             elif item == "contentDescription":
       
  3061                 self.ContentDescription.SetValue(value)
       
  3062             elif item == "pageSize":
       
  3063                 self.PageWidth.SetValue(value[0])
       
  3064                 self.PageHeight.SetValue(value[1])
       
  3065             elif item == "scaling":
       
  3066                 for language, (x, y) in value.items():
       
  3067                     if language in self.Scalings:
       
  3068                         self.Scalings[language].SetScaling(x, y)
       
  3069     
       
  3070     def GetValues(self):
       
  3071         values = {}
       
  3072         values["projectName"] = self.ProjectName.GetValue()
       
  3073         if self.ProjectVersion.GetValue() != "":
       
  3074             values["projectVersion"] = self.ProjectVersion.GetValue()
       
  3075         values["productName"] = self.ProductName.GetValue()
       
  3076         values["productVersion"] = self.ProductVersion.GetValue()
       
  3077         if self.ProductRelease.GetValue() != "":
       
  3078             values["productRelease"] = self.ProductRelease.GetValue()
       
  3079         values["companyName"] = self.CompanyName.GetValue()
       
  3080         if self.CompanyURL.GetValue() != "":
       
  3081             values["companyURL"] = self.CompanyURL.GetValue()
       
  3082         if self.AuthorName.GetValue() != "":
       
  3083             values["authorName"] = self.AuthorName.GetValue()
       
  3084         if self.Organization.GetValue() != "":
       
  3085             values["organization"] = self.Organization.GetValue()
       
  3086         if self.Language.GetStringSelection() != "":
       
  3087             values["language"] = self.Language.GetStringSelection()
       
  3088         if self.ProductRelease.GetValue() != "":
       
  3089             values["contentDescription"] = self.ContentDescription.GetValue()
       
  3090         values["pageSize"] = (self.PageWidth.GetValue(), self.PageHeight.GetValue())
       
  3091         values["scaling"] = {}
       
  3092         for language in ["FBD", "LD", "SFC"]:
       
  3093             values["scaling"][language] = self.Scalings[language].GetScaling()
       
  3094         return values
       
  3095 
       
  3096 #-------------------------------------------------------------------------------
       
  3097 #                          Edit Step Name Dialog
       
  3098 #-------------------------------------------------------------------------------
       
  3099 
       
  3100 class DataTypeDialog(wx.TextEntryDialog):
       
  3101 
       
  3102     if wx.VERSION < (2, 6, 0):
       
  3103         def Bind(self, event, function, id = None):
       
  3104             if id is not None:
       
  3105                 event(self, id, function)
       
  3106             else:
       
  3107                 event(self, function)
       
  3108     
       
  3109     def __init__(self, parent, message, caption = _("Please enter text"), defaultValue = "", 
       
  3110                        style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition):
       
  3111         wx.TextEntryDialog.__init__(self, parent, message, caption, defaultValue, style, pos)
       
  3112         
       
  3113         self.DataTypeNames = []
       
  3114         if wx.VERSION >= (2, 8, 0):
       
  3115             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(2).GetSizer().GetItem(1).GetSizer().GetAffirmativeButton().GetId())
       
  3116         elif wx.VERSION >= (2, 6, 0):
       
  3117             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetAffirmativeButton().GetId())
       
  3118         else:
       
  3119             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId())
       
  3120     
       
  3121     def OnOK(self, event):
       
  3122         datatype_name = self.GetSizer().GetItem(1).GetWindow().GetValue()
       
  3123         if datatype_name == "":
       
  3124             message = wx.MessageDialog(self, _("You must type a name!"), _("Error"), wx.OK|wx.ICON_ERROR)
       
  3125             message.ShowModal()
       
  3126             message.Destroy()
       
  3127         elif not TestIdentifier(datatype_name):
       
  3128             message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%datatype_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3129             message.ShowModal()
       
  3130             message.Destroy()
       
  3131         elif datatype_name.upper() in IEC_KEYWORDS:
       
  3132             message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%datatype_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3133             message.ShowModal()
       
  3134             message.Destroy()
       
  3135         elif datatype_name.upper() in self.DataTypeNames:
       
  3136             message = wx.MessageDialog(self, _("\"%s\" data type already exists!")%datatype_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3137             message.ShowModal()
       
  3138             message.Destroy()
       
  3139         else:
       
  3140             self.EndModal(wx.ID_OK)
       
  3141 
       
  3142     def SetDataTypeNames(self, datatype_names):
       
  3143         self.DataTypeNames = [datatype_name.upper() for datatype_name in datatype_names]
       
  3144 
       
  3145     def GetValue(self):
       
  3146         return self.GetSizer().GetItem(1).GetWindow().GetValue()
       
  3147 
       
  3148 #-------------------------------------------------------------------------------
       
  3149 #                            Create Pou Dialog
       
  3150 #-------------------------------------------------------------------------------
       
  3151 
       
  3152 [ID_POUDIALOG, ID_POUDIALOGPOUNAME, 
       
  3153  ID_POUDIALOGPOUTYPE, ID_POUDIALOGLANGUAGE, ID_POUDIALOGSTATICTEXT1,
       
  3154  ID_POUDIALOGSTATICTEXT2, ID_POUDIALOGSTATICTEXT3, 
       
  3155 ] = [wx.NewId() for _init_ctrls in range(7)]
       
  3156 
       
  3157 def GetTransitionLanguages():
       
  3158     _ = lambda x : x
       
  3159     return [_("IL"), _("ST"), _("LD"), _("FBD")]
       
  3160 TRANSITION_LANGUAGES_DICT = dict([(_(language), language) for language in GetTransitionLanguages()])
       
  3161 
       
  3162 def GetPouTypes():
       
  3163     _ = lambda x : x
       
  3164     return [_("function"), _("functionBlock"), _("program")]
       
  3165 POU_TYPES_DICT = dict([(_(pou_type), pou_type) for pou_type in GetPouTypes()])
       
  3166 
       
  3167 def GetPouLanguages():
       
  3168     _ = lambda x : x
       
  3169     return [_("IL"), _("ST"), _("LD"), _("FBD"), _("SFC")]
       
  3170 POU_LANGUAGES_DICT = dict([(_(language), language) for language in GetPouLanguages()])
       
  3171 
       
  3172 class PouDialog(wx.Dialog):
       
  3173     if wx.VERSION < (2, 6, 0):
       
  3174         def Bind(self, event, function, id = None):
       
  3175             if id is not None:
       
  3176                 event(self, id, function)
       
  3177             else:
       
  3178                 event(self, function)
       
  3179     
       
  3180     def _init_coll_flexGridSizer1_Items(self, parent):
       
  3181         parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
       
  3182         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
       
  3183         
       
  3184     def _init_coll_flexGridSizer1_Growables(self, parent):
       
  3185         parent.AddGrowableCol(0)
       
  3186         parent.AddGrowableRow(0)
       
  3187     
       
  3188     def _init_coll_MainSizer_Items(self, parent):
       
  3189         parent.AddWindow(self.staticText1, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP)
       
  3190         parent.AddWindow(self.PouName, 0, border=0, flag=wx.GROW)
       
  3191         parent.AddWindow(self.staticText2, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP)
       
  3192         parent.AddWindow(self.PouType, 0, border=0, flag=wx.GROW)
       
  3193         parent.AddWindow(self.staticText3, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP)
       
  3194         parent.AddWindow(self.Language, 0, border=0, flag=wx.GROW)
       
  3195         
       
  3196     def _init_coll_MainSizer_Growables(self, parent):
       
  3197         parent.AddGrowableCol(1)
       
  3198         
       
  3199     def _init_sizers(self):
       
  3200         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
       
  3201         self.MainSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=3, vgap=15)
       
  3202 
       
  3203         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
  3204         self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1)
       
  3205         self._init_coll_MainSizer_Items(self.MainSizer)
       
  3206         self._init_coll_MainSizer_Growables(self.MainSizer)
       
  3207 
       
  3208         self.SetSizer(self.flexGridSizer1)
       
  3209         
       
  3210     def _init_ctrls(self, prnt):
       
  3211         wx.Dialog.__init__(self, id=ID_POUDIALOG,
       
  3212               name='PouDialog', parent=prnt, pos=wx.Point(376, 223),
       
  3213               size=wx.Size(300, 200), style=wx.DEFAULT_DIALOG_STYLE,
       
  3214               title=_('Create a new POU'))
       
  3215         self.SetClientSize(wx.Size(300, 200))
       
  3216 
       
  3217         self.staticText1 = wx.StaticText(id=ID_POUDIALOGSTATICTEXT1,
       
  3218               label=_('POU Name:'), name='staticText1', parent=self,
       
  3219               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  3220 
       
  3221         self.PouName = wx.TextCtrl(id=ID_POUDIALOGPOUNAME,
       
  3222               name='POUName', parent=self, pos=wx.Point(0, 0), 
       
  3223               size=wx.Size(0, 24), style=0)
       
  3224 
       
  3225         self.staticText2 = wx.StaticText(id=ID_POUDIALOGSTATICTEXT2,
       
  3226               label=_('POU Type:'), name='staticText2', parent=self,
       
  3227               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  3228 
       
  3229         self.PouType = wx.ComboBox(id=ID_POUDIALOGPOUTYPE,
       
  3230               name='POUType', parent=self, pos=wx.Point(0, 0),
       
  3231               size=wx.Size(0, 28), style=wx.CB_READONLY)
       
  3232         self.Bind(wx.EVT_COMBOBOX, self.OnTypeChanged, id=ID_POUDIALOGPOUTYPE)
       
  3233 
       
  3234         self.staticText3 = wx.StaticText(id=ID_POUDIALOGSTATICTEXT3,
       
  3235               label=_('Language:'), name='staticText3', parent=self,
       
  3236               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  3237 
       
  3238         self.Language = wx.ComboBox(id=ID_POUDIALOGLANGUAGE,
       
  3239               name='Language', parent=self, pos=wx.Point(0, 0),
       
  3240               size=wx.Size(0, 28), style=wx.CB_READONLY)
       
  3241         
       
  3242         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
       
  3243         self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())
       
  3244             
       
  3245         self._init_sizers()
       
  3246 
       
  3247     def __init__(self, parent, pou_type = None):
       
  3248         self._init_ctrls(parent)
       
  3249         
       
  3250         for option in GetPouTypes():
       
  3251             self.PouType.Append(_(option))
       
  3252         if pou_type is not None:
       
  3253             self.PouType.SetStringSelection(_(pou_type))
       
  3254         self.RefreshLanguage()
       
  3255 
       
  3256         self.PouNames = []
       
  3257         self.PouElementNames = []
       
  3258 
       
  3259     def OnOK(self, event):
       
  3260         error = []
       
  3261         pou_name = self.PouName.GetValue()
       
  3262         if pou_name == "":
       
  3263             error.append(_("POU Name"))
       
  3264         if self.PouType.GetSelection() == -1:
       
  3265             error.append(_("POU Type"))
       
  3266         if self.Language.GetSelection() == -1:
       
  3267             error.append(_("Language"))
       
  3268         if len(error) > 0:
       
  3269             text = ""
       
  3270             for i, item in enumerate(error):
       
  3271                 if i == 0:
       
  3272                     text += item
       
  3273                 elif i == len(error) - 1:
       
  3274                     text += _(" and %s")%item
       
  3275                 else:
       
  3276                     text += _(", %s")%item 
       
  3277             message = wx.MessageDialog(self, _("Form isn't complete. %s must be filled!")%text, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3278             message.ShowModal()
       
  3279             message.Destroy()
       
  3280         elif not TestIdentifier(pou_name):
       
  3281             message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%pou_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3282             message.ShowModal()
       
  3283             message.Destroy()
       
  3284         elif pou_name.upper() in IEC_KEYWORDS:
       
  3285             message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%pou_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3286             message.ShowModal()
       
  3287             message.Destroy()
       
  3288         elif pou_name.upper() in self.PouNames:
       
  3289             message = wx.MessageDialog(self, _("\"%s\" pou already exists!")%pou_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3290             message.ShowModal()
       
  3291             message.Destroy()
       
  3292         elif pou_name.upper() in self.PouElementNames:
       
  3293             message = wx.MessageDialog(self, _("A POU has an element named \"%s\". This could cause a conflict. Do you wish to continue?")%pou_name, _("Warning"), wx.YES_NO|wx.ICON_EXCLAMATION)
       
  3294             result = message.ShowModal()
       
  3295             message.Destroy()
       
  3296             if result == wx.ID_YES:
       
  3297                 self.EndModal(wx.ID_OK)
       
  3298         else:
       
  3299             self.EndModal(wx.ID_OK)
       
  3300 
       
  3301     def RefreshLanguage(self):
       
  3302         selection = POU_LANGUAGES_DICT.get(self.Language.GetStringSelection(), "")
       
  3303         self.Language.Clear()
       
  3304         for language in GetPouLanguages():
       
  3305             if language != "SFC" or POU_TYPES_DICT[self.PouType.GetStringSelection()] != "function":
       
  3306                 self.Language.Append(language)
       
  3307         if self.Language.FindString(_(selection)) != wx.NOT_FOUND:
       
  3308             self.Language.SetStringSelection(_(selection))
       
  3309 
       
  3310     def OnTypeChanged(self, event):
       
  3311         self.RefreshLanguage()
       
  3312         event.Skip()
       
  3313 
       
  3314     def SetPouNames(self, pou_names):
       
  3315         self.PouNames = [pou_name.upper() for pou_name in pou_names]
       
  3316 
       
  3317     def SetPouElementNames(self, element_names):
       
  3318         self.PouElementNames = [element_name.upper() for element_name in element_names]
       
  3319 
       
  3320     def SetValues(self, values):
       
  3321         for item, value in values.items():
       
  3322             if item == "pouName":
       
  3323                 self.PouName.SetValue(value)
       
  3324             elif item == "pouType":
       
  3325                 self.PouType.SetStringSelection(_(value))
       
  3326             elif item == "language":
       
  3327                 self.Language.SetStringSelection(_(POU_LANGUAGES_DICT))
       
  3328                 
       
  3329     def GetValues(self):
       
  3330         values = {}
       
  3331         values["pouName"] = self.PouName.GetValue()
       
  3332         values["pouType"] = POU_TYPES_DICT[self.PouType.GetStringSelection()]
       
  3333         values["language"] = POU_LANGUAGES_DICT[self.Language.GetStringSelection()]
       
  3334         return values
       
  3335 
       
  3336 
       
  3337 #-------------------------------------------------------------------------------
       
  3338 #                          Create Pou Transition Dialog
       
  3339 #-------------------------------------------------------------------------------
       
  3340 
       
  3341 [ID_POUTRANSITIONDIALOG, ID_POUTRANSITIONDIALOGTRANSITIONNAME, 
       
  3342  ID_POUTRANSITIONDIALOGLANGUAGE, ID_POUTRANSITIONDIALOGSTATICTEXT1, 
       
  3343  ID_POUTRANSITIONDIALOGSTATICTEXT2,
       
  3344 ] = [wx.NewId() for _init_ctrls in range(5)]
       
  3345 
       
  3346 def GetTransitionLanguages():
       
  3347     _ = lambda x : x
       
  3348     return [_("IL"), _("ST"), _("LD"), _("FBD")]
       
  3349 TRANSITION_LANGUAGES_DICT = dict([(_(language), language) for language in GetTransitionLanguages()])
       
  3350 
       
  3351 class PouTransitionDialog(wx.Dialog):
       
  3352     if wx.VERSION < (2, 6, 0):
       
  3353         def Bind(self, event, function, id = None):
       
  3354             if id is not None:
       
  3355                 event(self, id, function)
       
  3356             else:
       
  3357                 event(self, function)
       
  3358     
       
  3359     def _init_coll_flexGridSizer1_Items(self, parent):
       
  3360         parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
       
  3361         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
       
  3362         
       
  3363     def _init_coll_flexGridSizer1_Growables(self, parent):
       
  3364         parent.AddGrowableCol(0)
       
  3365         parent.AddGrowableRow(0)
       
  3366     
       
  3367     def _init_coll_MainSizer_Items(self, parent):
       
  3368         parent.AddWindow(self.staticText1, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP)
       
  3369         parent.AddWindow(self.TransitionName, 0, border=0, flag=wx.GROW)
       
  3370         parent.AddWindow(self.staticText2, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP)
       
  3371         parent.AddWindow(self.Language, 0, border=0, flag=wx.GROW)
       
  3372         
       
  3373     def _init_coll_MainSizer_Growables(self, parent):
       
  3374         parent.AddGrowableCol(1)
       
  3375         
       
  3376     def _init_sizers(self):
       
  3377         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
       
  3378         self.MainSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=15)
       
  3379 
       
  3380         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
  3381         self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1)
       
  3382         self._init_coll_MainSizer_Items(self.MainSizer)
       
  3383         self._init_coll_MainSizer_Growables(self.MainSizer)
       
  3384 
       
  3385         self.SetSizer(self.flexGridSizer1)
       
  3386 
       
  3387     def _init_ctrls(self, prnt):
       
  3388         wx.Dialog.__init__(self, id=ID_POUTRANSITIONDIALOG,
       
  3389               name='PouTransitionDialog', parent=prnt, pos=wx.Point(376, 223),
       
  3390               size=wx.Size(350, 200), style=wx.DEFAULT_DIALOG_STYLE,
       
  3391               title=_('Create a new transition'))
       
  3392         self.SetClientSize(wx.Size(350, 160))
       
  3393 
       
  3394         self.staticText1 = wx.StaticText(id=ID_POUTRANSITIONDIALOGSTATICTEXT1,
       
  3395               label=_('Transition Name:'), name='staticText1', parent=self,
       
  3396               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  3397 
       
  3398         self.TransitionName = wx.TextCtrl(id=ID_POUTRANSITIONDIALOGTRANSITIONNAME,
       
  3399               name='TransitionName', parent=self, pos=wx.Point(0, 0),
       
  3400               size=wx.Size(0, 24), style=0)
       
  3401 
       
  3402         self.staticText2 = wx.StaticText(id=ID_POUTRANSITIONDIALOGSTATICTEXT2,
       
  3403               label=_('Language:'), name='staticText2', parent=self,
       
  3404               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  3405 
       
  3406         self.Language = wx.ComboBox(id=ID_POUTRANSITIONDIALOGLANGUAGE,
       
  3407               name='Language', parent=self, pos=wx.Point(0, 0),
       
  3408               size=wx.Size(0, 28), style=wx.CB_READONLY)
       
  3409         
       
  3410         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
       
  3411         self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())
       
  3412         
       
  3413         self._init_sizers()
       
  3414 
       
  3415     def __init__(self, parent):
       
  3416         self._init_ctrls(parent)
       
  3417         
       
  3418         for language in GetTransitionLanguages():
       
  3419             self.Language.Append(_(language))
       
  3420             
       
  3421         self.PouNames = []
       
  3422         self.PouElementNames = []
       
  3423         
       
  3424     def OnOK(self, event):
       
  3425         error = []
       
  3426         transition_name = self.TransitionName.GetValue()
       
  3427         if self.TransitionName.GetValue() == "":
       
  3428             error.append(_("Transition Name"))
       
  3429         if self.Language.GetSelection() == -1:
       
  3430             error.append(_("Language"))
       
  3431         if len(error) > 0:
       
  3432             text = ""
       
  3433             for i, item in enumerate(error):
       
  3434                 if i == 0:
       
  3435                     text += item
       
  3436                 elif i == len(error) - 1:
       
  3437                     text += _(" and %s")%item
       
  3438                 else:
       
  3439                     text += _(", %s")%item 
       
  3440             message = wx.MessageDialog(self, _("Form isn't complete. %s must be filled!")%text, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3441             message.ShowModal()
       
  3442             message.Destroy()
       
  3443         elif not TestIdentifier(transition_name):
       
  3444             message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%transition_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3445             message.ShowModal()
       
  3446             message.Destroy()
       
  3447         elif transition_name.upper() in IEC_KEYWORDS:
       
  3448             message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%transition_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3449             message.ShowModal()
       
  3450             message.Destroy()
       
  3451         elif transition_name.upper() in self.PouNames:
       
  3452             message = wx.MessageDialog(self, _("A POU named \"%s\" already exists!")%transition_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3453             message.ShowModal()
       
  3454             message.Destroy()
       
  3455         elif transition_name.upper() in self.PouElementNames:
       
  3456             message = wx.MessageDialog(self, _("\"%s\" element for this pou already exists!")%transition_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3457             message.ShowModal()
       
  3458             message.Destroy()
       
  3459         else:
       
  3460             self.EndModal(wx.ID_OK)
       
  3461     
       
  3462     def SetPouNames(self, pou_names):
       
  3463         self.PouNames = [pou_name.upper() for pou_name in pou_names]
       
  3464     
       
  3465     def SetPouElementNames(self, pou_names):
       
  3466         self.PouElementNames = [pou_name.upper() for pou_name in pou_names]
       
  3467     
       
  3468     def SetValues(self, values):
       
  3469         for item, value in values.items():
       
  3470             if item == "transitionName":
       
  3471                 self.TransitionName.SetValue(value)
       
  3472             elif item == "language":
       
  3473                 self.Language.SetSelection(_(value))
       
  3474                 
       
  3475     def GetValues(self):
       
  3476         values = {}
       
  3477         values["transitionName"] = self.TransitionName.GetValue()
       
  3478         values["language"] = TRANSITION_LANGUAGES_DICT[self.Language.GetStringSelection()]
       
  3479         return values
       
  3480 
       
  3481 #-------------------------------------------------------------------------------
       
  3482 #                          Create Pou Action Dialog
       
  3483 #-------------------------------------------------------------------------------
       
  3484 
       
  3485 [ID_POUACTIONDIALOG, ID_POUACTIONDIALOGACTIONNAME, 
       
  3486  ID_POUACTIONDIALOGLANGUAGE, ID_POUACTIONDIALOGSTATICTEXT1, 
       
  3487  ID_POUACTIONDIALOGSTATICTEXT2, 
       
  3488 ] = [wx.NewId() for _init_ctrls in range(5)]
       
  3489 
       
  3490 def GetActionLanguages():
       
  3491     _ = lambda x : x
       
  3492     return [_("IL"), _("ST"), _("LD"), _("FBD")]
       
  3493 ACTION_LANGUAGES_DICT = dict([(_(language), language) for language in GetActionLanguages()])
       
  3494 
       
  3495 class PouActionDialog(wx.Dialog):
       
  3496     if wx.VERSION < (2, 6, 0):
       
  3497         def Bind(self, event, function, id = None):
       
  3498             if id is not None:
       
  3499                 event(self, id, function)
       
  3500             else:
       
  3501                 event(self, function)
       
  3502     
       
  3503     def _init_coll_flexGridSizer1_Items(self, parent):
       
  3504         parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
       
  3505         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
       
  3506         
       
  3507     def _init_coll_flexGridSizer1_Growables(self, parent):
       
  3508         parent.AddGrowableCol(0)
       
  3509         parent.AddGrowableRow(0)
       
  3510     
       
  3511     def _init_coll_MainSizer_Items(self, parent):
       
  3512         parent.AddWindow(self.staticText1, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP)
       
  3513         parent.AddWindow(self.ActionName, 0, border=0, flag=wx.GROW)
       
  3514         parent.AddWindow(self.staticText2, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP)
       
  3515         parent.AddWindow(self.Language, 0, border=0, flag=wx.GROW)
       
  3516         
       
  3517     def _init_coll_MainSizer_Growables(self, parent):
       
  3518         parent.AddGrowableCol(1)
       
  3519         
       
  3520     def _init_sizers(self):
       
  3521         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
       
  3522         self.MainSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=15)
       
  3523 
       
  3524         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
  3525         self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1)
       
  3526         self._init_coll_MainSizer_Items(self.MainSizer)
       
  3527         self._init_coll_MainSizer_Growables(self.MainSizer)
       
  3528 
       
  3529         self.SetSizer(self.flexGridSizer1)
       
  3530 
       
  3531     def _init_ctrls(self, prnt):
       
  3532         wx.Dialog.__init__(self, id=ID_POUACTIONDIALOG,
       
  3533               name='PouActionDialog', parent=prnt, pos=wx.Point(376, 223),
       
  3534               size=wx.Size(320, 200), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER,
       
  3535               title=_('Create a new action'))
       
  3536         self.SetClientSize(wx.Size(320, 160))
       
  3537 
       
  3538         self.staticText1 = wx.StaticText(id=ID_POUACTIONDIALOGSTATICTEXT1,
       
  3539               label=_('Action Name:'), name='staticText1', parent=self,
       
  3540               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  3541 
       
  3542         self.ActionName = wx.TextCtrl(id=ID_POUACTIONDIALOGACTIONNAME,
       
  3543               name='ActionName', parent=self, pos=wx.Point(0, 0),
       
  3544               size=wx.Size(0, 24), style=0)
       
  3545 
       
  3546         self.staticText2 = wx.StaticText(id=ID_POUACTIONDIALOGSTATICTEXT2,
       
  3547               label=_('Language:'), name='staticText2', parent=self,
       
  3548               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  3549 
       
  3550         self.Language = wx.ComboBox(id=ID_POUACTIONDIALOGLANGUAGE,
       
  3551               name='Language', parent=self, pos=wx.Point(0, 0),
       
  3552               size=wx.Size(0, 28), style=wx.CB_READONLY)
       
  3553         
       
  3554         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
       
  3555         self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())
       
  3556         
       
  3557         self._init_sizers()
       
  3558 
       
  3559     def __init__(self, parent):
       
  3560         self._init_ctrls(parent)
       
  3561         
       
  3562         for option in GetActionLanguages():
       
  3563             self.Language.Append(_(option))
       
  3564         
       
  3565         self.PouNames = []
       
  3566         self.PouElementNames = []
       
  3567     
       
  3568     def OnOK(self, event):
       
  3569         error = []
       
  3570         action_name = self.ActionName.GetValue()
       
  3571         if action_name == "":
       
  3572             error.append(_("Action Name"))
       
  3573         if self.Language.GetSelection() == -1:
       
  3574             error.append(_("Language"))
       
  3575         if len(error) > 0:
       
  3576             text = ""
       
  3577             for i, item in enumerate(error):
       
  3578                 if i == 0:
       
  3579                     text += item
       
  3580                 elif i == len(error) - 1:
       
  3581                     text += _(" and %s")%item
       
  3582                 else:
       
  3583                     text += _(", %s")%item 
       
  3584             message = wx.MessageDialog(self, _("Form isn't complete. %s must be filled!")%text, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3585             message.ShowModal()
       
  3586             message.Destroy()
       
  3587         elif not TestIdentifier(action_name):
       
  3588             message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%action_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3589             message.ShowModal()
       
  3590             message.Destroy()
       
  3591         elif action_name.upper() in IEC_KEYWORDS:
       
  3592             message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%action_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3593             message.ShowModal()
       
  3594             message.Destroy()
       
  3595         elif action_name.upper() in self.PouNames:
       
  3596             message = wx.MessageDialog(self, _("A POU named \"%s\" already exists!")%action_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3597             message.ShowModal()
       
  3598             message.Destroy()
       
  3599         elif action_name.upper() in self.PouElementNames:
       
  3600             message = wx.MessageDialog(self, _("\"%s\" element for this pou already exists!")%action_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3601             message.ShowModal()
       
  3602             message.Destroy()
       
  3603         else:
       
  3604             self.EndModal(wx.ID_OK)
       
  3605     
       
  3606     def SetPouNames(self, pou_names):
       
  3607         self.PouNames = [pou_name.upper() for pou_name in pou_names]
       
  3608         
       
  3609     def SetPouElementNames(self, element_names):
       
  3610         self.PouElementNames = [element_name.upper() for element_name in element_names]
       
  3611         
       
  3612     def SetValues(self, values):
       
  3613         for item, value in values.items():
       
  3614             if item == "actionName":
       
  3615                 self.ActionName.SetValue(value)
       
  3616             elif item == "language":
       
  3617                 self.Language.SetStringSelection(_(value))
       
  3618                 
       
  3619     def GetValues(self):
       
  3620         values = {}
       
  3621         values["actionName"] = self.ActionName.GetValue()
       
  3622         values["language"] = ACTION_LANGUAGES_DICT[self.Language.GetStringSelection()]
       
  3623         return values
       
  3624 
       
  3625 #-------------------------------------------------------------------------------
       
  3626 #                          Configuration Name Dialog
       
  3627 #-------------------------------------------------------------------------------
       
  3628 
       
  3629 class ConfigurationNameDialog(wx.TextEntryDialog):
       
  3630 
       
  3631     if wx.VERSION < (2, 6, 0):
       
  3632         def Bind(self, event, function, id = None):
       
  3633             if id is not None:
       
  3634                 event(self, id, function)
       
  3635             else:
       
  3636                 event(self, function)
       
  3637 
       
  3638     def __init__(self, parent, message, caption = _("Please enter configuration name"), defaultValue = "", 
       
  3639                        style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition):
       
  3640         wx.TextEntryDialog.__init__(self, parent, message, caption, defaultValue, style, pos)
       
  3641         
       
  3642         self.PouNames = []
       
  3643         self.PouElementNames = []
       
  3644         
       
  3645         if wx.VERSION >= (2, 8, 0):
       
  3646             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(2).GetSizer().GetItem(1).GetSizer().GetAffirmativeButton().GetId())
       
  3647         elif wx.VERSION >= (2, 6, 0):
       
  3648             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetAffirmativeButton().GetId())
       
  3649         else:
       
  3650             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId())
       
  3651     
       
  3652     def OnOK(self, event):
       
  3653         config_name = self.GetSizer().GetItem(1).GetWindow().GetValue()
       
  3654         if config_name == "":
       
  3655             message = wx.MessageDialog(self, _("You must type a name!"), _("Error"), wx.OK|wx.ICON_ERROR)
       
  3656             message.ShowModal()
       
  3657             message.Destroy()
       
  3658         elif not TestIdentifier(config_name):
       
  3659             message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%config_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3660             message.ShowModal()
       
  3661             message.Destroy()
       
  3662         elif config_name.upper() in IEC_KEYWORDS:
       
  3663             message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%config_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3664             message.ShowModal()
       
  3665             message.Destroy()
       
  3666         elif config_name.upper() in self.PouNames:
       
  3667             message = wx.MessageDialog(self, _("A POU named \"%s\" already exists!")%config_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3668             message.ShowModal()
       
  3669             message.Destroy()
       
  3670         elif config_name.upper() in self.PouElementNames:
       
  3671             message = wx.MessageDialog(self, _("A POU has an element named \"%s\". This could cause a conflict. Do you wish to continue?")%config_name, _("Warning"), wx.YES_NO|wx.ICON_EXCLAMATION)
       
  3672             result = message.ShowModal()
       
  3673             message.Destroy()
       
  3674             if result == wx.ID_YES:
       
  3675                 self.EndModal(wx.ID_OK)
       
  3676         else:
       
  3677             self.EndModal(wx.ID_OK)
       
  3678 
       
  3679     def SetPouNames(self, pou_names):
       
  3680         self.PouNames = [pou_name.upper() for pou_name in pou_names]
       
  3681     
       
  3682     def SetPouElementNames(self, pou_names):
       
  3683         self.PouElementNames = [pou_name.upper() for pou_name in pou_names]
       
  3684     
       
  3685     def GetValue(self):
       
  3686         return self.GetSizer().GetItem(1).GetWindow().GetValue()
       
  3687 
       
  3688 #-------------------------------------------------------------------------------
       
  3689 #                          Resource Name Dialog
       
  3690 #-------------------------------------------------------------------------------
       
  3691 
       
  3692 class ResourceNameDialog(wx.TextEntryDialog):
       
  3693 
       
  3694     if wx.VERSION < (2, 6, 0):
       
  3695         def Bind(self, event, function, id = None):
       
  3696             if id is not None:
       
  3697                 event(self, id, function)
       
  3698             else:
       
  3699                 event(self, function)
       
  3700 
       
  3701     def __init__(self, parent, message, caption = _("Please enter resource name"), defaultValue = "", 
       
  3702                        style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition):
       
  3703         wx.TextEntryDialog.__init__(self, parent, message, caption, defaultValue, style, pos)
       
  3704         
       
  3705         self.PouNames = []
       
  3706         self.PouElementNames = []
       
  3707         
       
  3708         if wx.VERSION >= (2, 8, 0):
       
  3709             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(2).GetSizer().GetItem(1).GetSizer().GetAffirmativeButton().GetId())
       
  3710         elif wx.VERSION >= (2, 6, 0):
       
  3711             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetAffirmativeButton().GetId())
       
  3712         else:
       
  3713             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId())
       
  3714 
       
  3715     def OnOK(self, event):
       
  3716         resource_name = self.GetSizer().GetItem(1).GetWindow().GetValue()
       
  3717         if resource_name == "":
       
  3718             message = wx.MessageDialog(self, _("You must type a name!"), _("Error"), wx.OK|wx.ICON_ERROR)
       
  3719             message.ShowModal()
       
  3720             message.Destroy()
       
  3721         elif not TestIdentifier(resource_name):
       
  3722             message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%resource_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3723             message.ShowModal()
       
  3724             message.Destroy()
       
  3725         elif resource_name.upper() in IEC_KEYWORDS:
       
  3726             message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%resource_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3727             message.ShowModal()
       
  3728             message.Destroy()
       
  3729         elif resource_name.upper() in self.PouNames:
       
  3730             message = wx.MessageDialog(self, _("A POU named \"%s\" already exists!")%resource_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3731             message.ShowModal()
       
  3732             message.Destroy()
       
  3733         elif resource_name.upper() in self.PouElementNames:
       
  3734             message = wx.MessageDialog(self, _("A POU has an element named \"%s\". This could cause a conflict. Do you wish to continue?")%resource_name, _("Warning"), wx.YES_NO|wx.ICON_EXCLAMATION)
       
  3735             result = message.ShowModal()
       
  3736             message.Destroy()
       
  3737             if result == wx.ID_YES:
       
  3738                 self.EndModal(wx.ID_OK)
       
  3739         else:
       
  3740             self.EndModal(wx.ID_OK)
       
  3741 
       
  3742     def SetPouNames(self, pou_names):
       
  3743         self.PouNames = [pou_name.upper() for pou_name in pou_names]
       
  3744     
       
  3745     def SetPouElementNames(self, pou_names):
       
  3746         self.PouElementNames = [pou_name.upper() for pou_name in pou_names]
       
  3747     
       
  3748     def GetValue(self):
       
  3749         return self.GetSizer().GetItem(1).GetWindow().GetValue()
       
  3750 
       
  3751 #-------------------------------------------------------------------------------
       
  3752 #                            Variables Editor Panel
       
  3753 #-------------------------------------------------------------------------------
       
  3754 
       
  3755 class VariablePanelIndexer(wx.Panel):
       
  3756     
       
  3757     def _init_sizers(self):
       
  3758         self.MainSizer = wx.BoxSizer(wx.HORIZONTAL)
       
  3759         
       
  3760         self.SetSizer(self.MainSizer)
       
  3761     
       
  3762     def _init_ctrls(self, prnt):
       
  3763         wx.Panel.__init__(self, id=wx.NewId(),
       
  3764               name='VariablePanelIndexer', parent=prnt, pos=wx.Point(0, 0),
       
  3765               size=wx.Size(0, 300), style=wx.TAB_TRAVERSAL)
       
  3766         
       
  3767         self._init_sizers()
       
  3768     
       
  3769     def __init__(self, parent, window):
       
  3770         self._init_ctrls(parent)
       
  3771         
       
  3772         self.ParentWindow = window
       
  3773         
       
  3774         self.VariablePanelList = {}
       
  3775         self.CurrentPanel = None
       
  3776         
       
  3777     def AddVariablePanel(self, tagname, element_type):
       
  3778         new_panel = VariablePanel(self, self.ParentWindow, self.ParentWindow.Controler, element_type)
       
  3779         new_panel.SetTagName(tagname)
       
  3780         new_panel.Hide()
       
  3781         new_panel.RefreshView()
       
  3782         self.MainSizer.AddWindow(new_panel, 1, border=0, flag=wx.GROW)
       
  3783         self.VariablePanelList[tagname] = new_panel
       
  3784         
       
  3785     def RemoveVariablePanel(self, tagname):
       
  3786         if tagname in self.VariablePanelList:
       
  3787             panel = self.VariablePanelList.pop(tagname)
       
  3788             self.MainSizer.Remove(panel)
       
  3789             panel.Destroy()
       
  3790             if self.CurrentPanel == tagname:
       
  3791                 self.CurrentPanel = None
       
  3792     
       
  3793     def RemoveAllPanels(self):
       
  3794         for tagname in self.VariablePanelList.keys():
       
  3795             self.RemoveVariablePanel(tagname)
       
  3796     
       
  3797     def UpdateVariablePanelTagName(self, old_tagname, new_tagname):
       
  3798         if old_tagname in self.VariablePanelList:
       
  3799             self.VariablePanelList[new_tagname] = self.VariablePanelList.pop(old_tagname)
       
  3800             if self.CurrentPanel == old_tagname:
       
  3801                 self.CurrentPanel = new_tagname
       
  3802                 
       
  3803     def ChangeVariablePanel(self, tagname):
       
  3804         if tagname in self.VariablePanelList:
       
  3805             if tagname != self.CurrentPanel:
       
  3806                 if self.CurrentPanel is not None:
       
  3807                     self.VariablePanelList[self.CurrentPanel].Hide()
       
  3808                 self.CurrentPanel = tagname
       
  3809                 self.VariablePanelList[self.CurrentPanel].RefreshView()
       
  3810                 self.VariablePanelList[self.CurrentPanel].Show()
       
  3811                 self.MainSizer.Layout()
       
  3812         else:
       
  3813             if self.CurrentPanel is not None:
       
  3814                 self.VariablePanelList[self.CurrentPanel].Hide()
       
  3815             self.CurrentPanel = None
       
  3816             self.MainSizer.Layout()
       
  3817 
       
  3818     def RefreshVariablePanel(self, tagname):
       
  3819         if tagname in self.VariablePanelList:
       
  3820             self.VariablePanelList[self.CurrentPanel].RefreshView()
       
  3821 
       
  3822     def AddVariableError(self, infos):
       
  3823         self.ChangeVariablePanel(infos[0])
       
  3824         if self.CurrentPanel is not None:
       
  3825             self.VariablePanelList[self.CurrentPanel].AddVariableError(infos[2:])
       
  3826 
       
  3827     def ClearErrors(self):
       
  3828         for panel in self.VariablePanelList.values():
       
  3829             panel.ClearErrors()
       
  3830 
       
  3831 #-------------------------------------------------------------------------------
       
  3832 #                            Debug Variables Panel
       
  3833 #-------------------------------------------------------------------------------
       
  3834 
       
  3835 def GetDebugVariablesTableColnames():
       
  3836     _ = lambda x : x
       
  3837     return [_("Variable"), _("Value")]
       
  3838 
       
  3839 class VariableTableItem(DebugDataConsumer):
       
  3840     
       
  3841     def __init__(self, parent, variable, value):
       
  3842         DebugDataConsumer.__init__(self)
       
  3843         self.Parent = parent
       
  3844         self.Variable = variable
       
  3845         self.Value = value
       
  3846     
       
  3847     def __del__(self):
       
  3848         self.Parent = None
       
  3849     
       
  3850     def SetVariable(self, variable):
       
  3851         if self.Parent and self.Variable != variable:
       
  3852             self.Variable = variable
       
  3853             self.Parent.RefreshGrid()
       
  3854     
       
  3855     def GetVariable(self):
       
  3856         return self.Variable
       
  3857     
       
  3858     def SetValue(self, value):
       
  3859         if self.Value != value:
       
  3860             self.Value = value
       
  3861             self.Parent.HasNewData = True
       
  3862             
       
  3863     def GetValue(self):
       
  3864         return self.Value
       
  3865 
       
  3866 class DebugVariableTable(wx.grid.PyGridTableBase):
       
  3867     
       
  3868     """
       
  3869     A custom wx.grid.Grid Table using user supplied data
       
  3870     """
       
  3871     def __init__(self, parent, data, colnames):
       
  3872         # The base class must be initialized *first*
       
  3873         wx.grid.PyGridTableBase.__init__(self)
       
  3874         self.data = data
       
  3875         self.colnames = colnames
       
  3876         self.Parent = parent
       
  3877         # XXX
       
  3878         # we need to store the row length and collength to
       
  3879         # see if the table has changed size
       
  3880         self._rows = self.GetNumberRows()
       
  3881         self._cols = self.GetNumberCols()
       
  3882     
       
  3883     def GetNumberCols(self):
       
  3884         return len(self.colnames)
       
  3885         
       
  3886     def GetNumberRows(self):
       
  3887         return len(self.data)
       
  3888 
       
  3889     def GetColLabelValue(self, col, translate=True):
       
  3890         if col < len(self.colnames):
       
  3891             if translate:
       
  3892                 return _(self.colnames[col])
       
  3893             return self.colnames[col]
       
  3894 
       
  3895     def GetRowLabelValues(self, row, translate=True):
       
  3896         return row
       
  3897 
       
  3898     def GetValue(self, row, col):
       
  3899         if row < self.GetNumberRows():
       
  3900             return self.GetValueByName(row, self.GetColLabelValue(col, False))
       
  3901         return ""
       
  3902     
       
  3903     def SetValue(self, row, col, value):
       
  3904         if col < len(self.colnames):
       
  3905             self.SetValueByName(row, self.GetColLabelValue(col, False), value)
       
  3906             
       
  3907     def GetValueByName(self, row, colname):
       
  3908         if row < self.GetNumberRows():
       
  3909             if colname == "Variable":
       
  3910                 return self.data[row].GetVariable()
       
  3911             elif colname == "Value":
       
  3912                 return self.data[row].GetValue()
       
  3913         return ""
       
  3914 
       
  3915     def SetValueByName(self, row, colname, value):
       
  3916         if row < self.GetNumberRows():
       
  3917             if colname == "Variable":
       
  3918                 self.data[row].SetVariable(value)
       
  3919             elif colname == "Value":
       
  3920                 self.data[row].SetValue(value)
       
  3921     
       
  3922     def ResetView(self, grid):
       
  3923         """
       
  3924         (wx.grid.Grid) -> Reset the grid view.   Call this to
       
  3925         update the grid if rows and columns have been added or deleted
       
  3926         """
       
  3927         grid.BeginBatch()
       
  3928         for current, new, delmsg, addmsg in [
       
  3929             (self._rows, self.GetNumberRows(), wx.grid.GRIDTABLE_NOTIFY_ROWS_DELETED, wx.grid.GRIDTABLE_NOTIFY_ROWS_APPENDED),
       
  3930             (self._cols, self.GetNumberCols(), wx.grid.GRIDTABLE_NOTIFY_COLS_DELETED, wx.grid.GRIDTABLE_NOTIFY_COLS_APPENDED),
       
  3931         ]:
       
  3932             if new < current:
       
  3933                 msg = wx.grid.GridTableMessage(self,delmsg,new,current-new)
       
  3934                 grid.ProcessTableMessage(msg)
       
  3935             elif new > current:
       
  3936                 msg = wx.grid.GridTableMessage(self,addmsg,new-current)
       
  3937                 grid.ProcessTableMessage(msg)
       
  3938                 self.UpdateValues(grid)
       
  3939         grid.EndBatch()
       
  3940 
       
  3941         self._rows = self.GetNumberRows()
       
  3942         self._cols = self.GetNumberCols()
       
  3943         # update the column rendering scheme
       
  3944         self._updateColAttrs(grid)
       
  3945 
       
  3946         # update the scrollbars and the displayed part of the grid
       
  3947         grid.AdjustScrollbars()
       
  3948         grid.ForceRefresh()
       
  3949 
       
  3950     def UpdateValues(self, grid):
       
  3951         """Update all displayed values"""
       
  3952         # This sends an event to the grid table to update all of the values
       
  3953         msg = wx.grid.GridTableMessage(self, wx.grid.GRIDTABLE_REQUEST_VIEW_GET_VALUES)
       
  3954         grid.ProcessTableMessage(msg)
       
  3955 
       
  3956     def _updateColAttrs(self, grid):
       
  3957         """
       
  3958         wx.grid.Grid -> update the column attributes to add the
       
  3959         appropriate renderer given the column name.
       
  3960 
       
  3961         Otherwise default to the default renderer.
       
  3962         """
       
  3963         
       
  3964         for row in range(self.GetNumberRows()):
       
  3965             for col in range(self.GetNumberCols()):
       
  3966                 grid.SetReadOnly(row, col, True)
       
  3967                 
       
  3968     def SetData(self, data):
       
  3969         self.data = data
       
  3970     
       
  3971     def GetData(self):
       
  3972         return self.data
       
  3973     
       
  3974     def AppendItem(self, data):
       
  3975         self.data.append(data)
       
  3976     
       
  3977     def InsertItem(self, idx, data):
       
  3978         self.data.insert(idx, data)
       
  3979     
       
  3980     def RemoveItem(self, idx):
       
  3981         self.data.pop(idx)
       
  3982     
       
  3983     def MoveItem(self, idx, new_idx):
       
  3984         self.data.insert(new_idx, self.data.pop(idx))
       
  3985         
       
  3986     def GetItem(self, idx):
       
  3987         return self.data[idx]
       
  3988 
       
  3989     def Empty(self):
       
  3990         self.data = []
       
  3991     
       
  3992 class DebugVariableDropTarget(wx.TextDropTarget):
       
  3993     
       
  3994     def __init__(self, parent):
       
  3995         wx.TextDropTarget.__init__(self)
       
  3996         self.ParentWindow = parent
       
  3997     
       
  3998     def OnDropText(self, x, y, data):
       
  3999         x, y = self.ParentWindow.VariablesGrid.CalcUnscrolledPosition(x, y)
       
  4000         row = self.ParentWindow.VariablesGrid.YToRow(y - self.ParentWindow.VariablesGrid.GetColLabelSize())
       
  4001         if row == wx.NOT_FOUND:
       
  4002             row = self.ParentWindow.Table.GetNumberRows()
       
  4003         message = None
       
  4004         try:
       
  4005             values = eval(data)
       
  4006         except:
       
  4007             message = _("Invalid value \"%s\" for debug variable")%data
       
  4008             values = None
       
  4009         if not isinstance(values, TupleType):
       
  4010             message = _("Invalid value \"%s\" for debug variable")%data
       
  4011             values = None
       
  4012         if values is not None and values[1] == "debug":
       
  4013             self.ParentWindow.InsertValue(row, values[0])
       
  4014         if message is not None:
       
  4015             wx.CallAfter(self.ShowMessage, message)
       
  4016             
       
  4017     def ShowMessage(self, message):
       
  4018         message = wx.MessageDialog(self.ParentWindow, message, _("Error"), wx.OK|wx.ICON_ERROR)
       
  4019         message.ShowModal()
       
  4020         message.Destroy()
       
  4021 
       
  4022 [ID_DEBUGVARIABLEPANEL, ID_DEBUGVARIABLEPANELVARIABLESGRID, 
       
  4023  ID_DEBUGVARIABLEPANELUPBUTTON, ID_DEBUGVARIABLEPANELDOWNBUTTON, 
       
  4024  ID_DEBUGVARIABLEPANELDELETEBUTTON,
       
  4025 ] = [wx.NewId() for _init_ctrls in range(5)]
       
  4026 
       
  4027 class DebugVariablePanel(wx.Panel, DebugViewer):
       
  4028     
       
  4029     if wx.VERSION < (2, 6, 0):
       
  4030         def Bind(self, event, function, id = None):
       
  4031             if id is not None:
       
  4032                 event(self, id, function)
       
  4033             else:
       
  4034                 event(self, function)
       
  4035     
       
  4036     def _init_coll_MainSizer_Items(self, parent):
       
  4037         parent.AddSizer(self.ButtonPanelSizer, 0, border=5, flag=wx.ALIGN_RIGHT|wx.ALL)
       
  4038         parent.AddWindow(self.VariablesGrid, 0, border=0, flag=wx.GROW)
       
  4039     
       
  4040     def _init_coll_MainSizer_Growables(self, parent):
       
  4041         parent.AddGrowableCol(0)
       
  4042         parent.AddGrowableRow(1)
       
  4043     
       
  4044     def _init_coll_ButtonPanelSizer_Items(self, parent):
       
  4045         parent.AddWindow(self.UpButton, 0, border=5, flag=wx.RIGHT)
       
  4046         parent.AddWindow(self.DownButton, 0, border=5, flag=wx.RIGHT)
       
  4047         parent.AddWindow(self.DeleteButton, 0, border=0, flag=0)
       
  4048         
       
  4049     def _init_sizers(self):
       
  4050         self.MainSizer = wx.FlexGridSizer(cols=1, hgap=10, rows=2, vgap=0)
       
  4051         self.ButtonPanelSizer = wx.BoxSizer(wx.HORIZONTAL)
       
  4052         
       
  4053         self._init_coll_MainSizer_Items(self.MainSizer)
       
  4054         self._init_coll_MainSizer_Growables(self.MainSizer)
       
  4055         self._init_coll_ButtonPanelSizer_Items(self.ButtonPanelSizer)
       
  4056         
       
  4057         self.SetSizer(self.MainSizer)
       
  4058         
       
  4059     def _init_ctrls(self, prnt):
       
  4060         wx.Panel.__init__(self, id=ID_DEBUGVARIABLEPANEL,
       
  4061               name='DebugVariablePanel', parent=prnt, pos=wx.Point(0, 0),
       
  4062               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
  4063 
       
  4064         self.VariablesGrid = wx.grid.Grid(id=ID_DEBUGVARIABLEPANELVARIABLESGRID,
       
  4065               name='VariablesGrid', parent=self, pos=wx.Point(0, 0), 
       
  4066               size=wx.Size(0, 150), style=wx.VSCROLL)
       
  4067         self.VariablesGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False,
       
  4068               'Sans'))
       
  4069         self.VariablesGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL,
       
  4070               False, 'Sans'))
       
  4071         self.VariablesGrid.SetSelectionBackground(wx.WHITE)
       
  4072         self.VariablesGrid.SetSelectionForeground(wx.BLACK)
       
  4073         self.VariablesGrid.SetDropTarget(DebugVariableDropTarget(self))
       
  4074         
       
  4075         self.UpButton = wx.Button(id=ID_DEBUGVARIABLEPANELUPBUTTON, label='^',
       
  4076               name='UpButton', parent=self, pos=wx.Point(0, 0),
       
  4077               size=wx.Size(32, 32), style=0)
       
  4078         self.Bind(wx.EVT_BUTTON, self.OnUpButton, id=ID_DEBUGVARIABLEPANELUPBUTTON)
       
  4079         
       
  4080         self.DownButton = wx.Button(id=ID_DEBUGVARIABLEPANELDOWNBUTTON, label='v',
       
  4081               name='DownButton', parent=self, pos=wx.Point(0, 0),
       
  4082               size=wx.Size(32, 32), style=0)
       
  4083         self.Bind(wx.EVT_BUTTON, self.OnDownButton, id=ID_DEBUGVARIABLEPANELDOWNBUTTON)
       
  4084         
       
  4085         self.DeleteButton = wx.Button(id=ID_DEBUGVARIABLEPANELDELETEBUTTON, label=_('Delete'),
       
  4086               name='DeleteButton', parent=self, pos=wx.Point(0, 0),
       
  4087               size=wx.DefaultSize, style=0)
       
  4088         self.Bind(wx.EVT_BUTTON, self.OnDeleteButton, id=ID_DEBUGVARIABLEPANELDELETEBUTTON)
       
  4089         
       
  4090         self._init_sizers()
       
  4091     
       
  4092     def __init__(self, parent, producer):
       
  4093         self._init_ctrls(parent)
       
  4094         DebugViewer.__init__(self, producer, True)
       
  4095         self.HasNewData = False
       
  4096         
       
  4097         self.Table = DebugVariableTable(self, [], GetDebugVariablesTableColnames())
       
  4098         self.VariablesGrid.SetTable(self.Table)
       
  4099         self.VariablesGrid.SetRowLabelSize(0)
       
  4100         
       
  4101         for col in range(self.Table.GetNumberCols()):
       
  4102             attr = wx.grid.GridCellAttr()
       
  4103             attr.SetAlignment(wx.ALIGN_RIGHT, wx.ALIGN_CENTER)
       
  4104             self.VariablesGrid.SetColAttr(col, attr)
       
  4105             self.VariablesGrid.SetColSize(col, 100)
       
  4106         
       
  4107         self.Table.ResetView(self.VariablesGrid)
       
  4108     
       
  4109     def RefreshNewData(self):
       
  4110         if self.HasNewData:
       
  4111             self.HasNewData = False
       
  4112             self.RefreshGrid()
       
  4113         DebugViewer.RefreshNewData(self)
       
  4114     
       
  4115     def RefreshGrid(self):
       
  4116         self.Freeze()
       
  4117         self.Table.ResetView(self.VariablesGrid)
       
  4118         self.Thaw()
       
  4119     
       
  4120     def ResetGrid(self):
       
  4121         self.DeleteDataConsumers()
       
  4122         self.Table.Empty()
       
  4123         self.Freeze()
       
  4124         self.Table.ResetView(self.VariablesGrid)
       
  4125         self.Thaw()
       
  4126     
       
  4127     def OnDeleteButton(self, event):
       
  4128         idx = self.VariablesGrid.GetGridCursorRow()
       
  4129         item = self.Table.GetItem(idx)
       
  4130         self.RemoveDataConsumer(item)
       
  4131         self.Table.RemoveItem(idx)
       
  4132         self.RefreshGrid()
       
  4133         event.Skip()
       
  4134 
       
  4135     def OnUpButton(self, event):
       
  4136         self.MoveValue(self.VariablesGrid.GetGridCursorRow(), -1)
       
  4137         event.Skip()
       
  4138 
       
  4139     def OnDownButton(self, event):
       
  4140         self.MoveValue(self.VariablesGrid.GetGridCursorRow(), 1)
       
  4141         event.Skip()
       
  4142 
       
  4143     def InsertValue(self, idx, iec_path):
       
  4144         for item in self.Table.GetData():
       
  4145             if iec_path == item.GetVariable():
       
  4146                 return
       
  4147         item = VariableTableItem(self, iec_path, "")
       
  4148         result = self.AddDataConsumer(iec_path.upper(), item)
       
  4149         if result is not None:
       
  4150             self.Table.InsertItem(idx, item)
       
  4151             self.RefreshGrid()
       
  4152 
       
  4153     def MoveValue(self, idx, move):
       
  4154         new_idx = max(0, min(idx + move, self.Table.GetNumberRows() - 1))
       
  4155         if new_idx != idx:
       
  4156             self.Table.MoveItem(idx, new_idx)
       
  4157             self.RefreshGrid()
       
  4158             self.VariablesGrid.SetGridCursor(new_idx, self.VariablesGrid.GetGridCursorCol())
       
  4159     
       
  4160 #-------------------------------------------------------------------------------
       
  4161 #                               Viewer Printout
       
  4162 #-------------------------------------------------------------------------------
       
  4163 
       
  4164 UPPER_DIV = lambda x, y: (x / y) + {True : 0, False : 1}[(x % y) == 0]
       
  4165 
       
  4166 class GraphicPrintout(wx.Printout):
       
  4167     def __init__(self, viewer, page_size, margins, preview = False):
       
  4168         wx.Printout.__init__(self)
       
  4169         self.Viewer = viewer
       
  4170         self.PageSize = page_size
       
  4171         if self.PageSize[0] == 0 or self.PageSize[1] == 0:
       
  4172             self.PageSize = (1050, 1485)
       
  4173         self.Preview = preview
       
  4174         self.Margins = margins
       
  4175         self.FontSize = 5
       
  4176         self.TextMargin = 3
       
  4177         
       
  4178         maxx, maxy = viewer.GetMaxSize()
       
  4179         self.PageGrid = (UPPER_DIV(maxx, self.PageSize[0]), 
       
  4180                          UPPER_DIV(maxy, self.PageSize[1]))
       
  4181         
       
  4182     def GetPageNumber(self):
       
  4183         return self.PageGrid[0] * self.PageGrid[1]
       
  4184     
       
  4185     def HasPage(self, page):
       
  4186         return page <= self.GetPageNumber()
       
  4187         
       
  4188     def GetPageInfo(self):
       
  4189         page_number = self.GetPageNumber()
       
  4190         return (1, page_number, 1, page_number)
       
  4191 
       
  4192     def OnBeginDocument(self, startPage, endPage):
       
  4193         dc = self.GetDC()
       
  4194         if not self.Preview and isinstance(dc, wx.PostScriptDC):
       
  4195             dc.SetResolution(720)
       
  4196         super(GraphicPrintout, self).OnBeginDocument(startPage, endPage)
       
  4197 
       
  4198     def OnPrintPage(self, page):
       
  4199         dc = self.GetDC()
       
  4200         dc.SetUserScale(1.0, 1.0)
       
  4201         dc.SetDeviceOrigin(0, 0)
       
  4202         dc.printing = not self.Preview
       
  4203         
       
  4204         # Get the size of the DC in pixels
       
  4205         ppiPrinterX, ppiPrinterY = self.GetPPIPrinter()
       
  4206         ppiScreenX, ppiScreenY = self.GetPPIScreen()
       
  4207         pw, ph = self.GetPageSizePixels()
       
  4208         dw, dh = dc.GetSizeTuple()
       
  4209         Xscale = (float(dw) * float(ppiPrinterX)) / (float(pw) * 25.4)
       
  4210         Yscale = (float(dh) * float(ppiPrinterY)) / (float(ph) * 25.4)
       
  4211         
       
  4212         fontsize = self.FontSize * Yscale
       
  4213         text_margin = self.TextMargin * Yscale
       
  4214         
       
  4215         margin_left = self.Margins[0].x * Xscale
       
  4216         margin_top = self.Margins[0].y * Yscale
       
  4217         area_width = dw - self.Margins[1].x * Xscale - margin_left
       
  4218         area_height = dh - self.Margins[1].y * Yscale - margin_top
       
  4219         
       
  4220         dc.SetPen(wx.BLACK_PEN)
       
  4221         dc.SetBrush(wx.TRANSPARENT_BRUSH)    
       
  4222         dc.DrawRectangle(margin_left, margin_top, area_width, area_height)
       
  4223         
       
  4224         dc.SetFont(wx.Font(fontsize, wx.DEFAULT, wx.NORMAL, wx.NORMAL))
       
  4225         dc.SetTextForeground(wx.BLACK)
       
  4226         block_name = " - ".join(self.Viewer.GetTagName().split("::")[1:])
       
  4227         text_width, text_height = dc.GetTextExtent(block_name)
       
  4228         dc.DrawText(block_name, margin_left, margin_top - text_height - self.TextMargin)
       
  4229         dc.DrawText(_("Page: %d") % page, margin_left, margin_top + area_height + self.TextMargin)
       
  4230         
       
  4231         # Calculate the position on the DC for centering the graphic
       
  4232         posX = area_width * ((page - 1) % self.PageGrid[0])
       
  4233         posY = area_height * ((page - 1) / self.PageGrid[0])
       
  4234 
       
  4235         scaleX = float(area_width) / float(self.PageSize[0])
       
  4236         scaleY = float(area_height) / float(self.PageSize[1])
       
  4237         scale = min(scaleX, scaleY)
       
  4238 
       
  4239         # Set the scale and origin
       
  4240         dc.SetDeviceOrigin(-posX + margin_left, -posY + margin_top)
       
  4241         dc.SetClippingRegion(posX, posY, self.PageSize[0] * scale, self.PageSize[1] * scale)
       
  4242         dc.SetUserScale(scale, scale)
       
  4243         
       
  4244         #-------------------------------------------
       
  4245         
       
  4246         self.Viewer.DoDrawing(dc, True)
       
  4247         
       
  4248         return True
       
  4249 
       
  4250 #-------------------------------------------------------------------------------
       
  4251 #                               Exception Handler
       
  4252 #-------------------------------------------------------------------------------
       
  4253 
       
  4254 Max_Traceback_List_Size = 20
       
  4255 
       
  4256 def Display_Exception_Dialog(e_type,e_value,e_tb):
       
  4257     trcbck_lst = []
       
  4258     for i,line in enumerate(traceback.extract_tb(e_tb)):
       
  4259         trcbck = " " + str(i+1) + _(". ")
       
  4260         if line[0].find(os.getcwd()) == -1:
       
  4261             trcbck += _("file : ") + str(line[0]) + _(",   ")
       
  4262         else:
       
  4263             trcbck += _("file : ") + str(line[0][len(os.getcwd()):]) + _(",   ")
       
  4264         trcbck += _("line : ") + str(line[1]) + _(",   ") + _("function : ") + str(line[2])
       
  4265         trcbck_lst.append(trcbck)
       
  4266         
       
  4267     # Allow clicking....
       
  4268     cap = wx.Window_GetCapture()
       
  4269     if cap:
       
  4270         cap.ReleaseMouse()
       
  4271 
       
  4272     dlg = wx.SingleChoiceDialog(None, 
       
  4273         _("""
       
  4274 An error has occurred.
       
  4275 
       
  4276 Click OK to save an error report.
       
  4277 
       
  4278 Please contact LOLITech at:
       
  4279 +33 (0)3 29 57 60 42
       
  4280 bugs_PLCOpenEditor@lolitech.fr
       
  4281 
       
  4282 
       
  4283 Error:
       
  4284 """) +
       
  4285         str(e_type) + _(" : ") + str(e_value), 
       
  4286         _("Error"),
       
  4287         trcbck_lst)
       
  4288     try:
       
  4289         res = (dlg.ShowModal() == wx.ID_OK)
       
  4290     finally:
       
  4291         dlg.Destroy()
       
  4292 
       
  4293     return res
       
  4294 
       
  4295 def Display_Error_Dialog(e_value):
       
  4296     message = wx.MessageDialog(None, str(e_value), _("Error"), wx.OK|wx.ICON_ERROR)
       
  4297     message.ShowModal()
       
  4298     message.Destroy()
       
  4299 
       
  4300 def get_last_traceback(tb):
       
  4301     while tb.tb_next:
       
  4302         tb = tb.tb_next
       
  4303     return tb
       
  4304 
       
  4305 
       
  4306 def format_namespace(d, indent='    '):
       
  4307     return '\n'.join(['%s%s: %s' % (indent, k, repr(v)[:10000]) for k, v in d.iteritems()])
       
  4308 
       
  4309 
       
  4310 ignored_exceptions = [] # a problem with a line in a module is only reported once per session
       
  4311 
       
  4312 def AddExceptHook(path, app_version='[No version]'):#, ignored_exceptions=[]):
       
  4313     
       
  4314     def handle_exception(e_type, e_value, e_traceback):
       
  4315         traceback.print_exception(e_type, e_value, e_traceback) # this is very helpful when there's an exception in the rest of this func
       
  4316         last_tb = get_last_traceback(e_traceback)
       
  4317         ex = (last_tb.tb_frame.f_code.co_filename, last_tb.tb_frame.f_lineno)
       
  4318         if str(e_value).startswith("!!!"):
       
  4319             Display_Error_Dialog(e_value)
       
  4320         elif ex not in ignored_exceptions:
       
  4321             result = Display_Exception_Dialog(e_type,e_value,e_traceback)
       
  4322             if result:
       
  4323                 ignored_exceptions.append(ex)
       
  4324                 info = {
       
  4325                     'app-title' : wx.GetApp().GetAppName(), # app_title
       
  4326                     'app-version' : app_version,
       
  4327                     'wx-version' : wx.VERSION_STRING,
       
  4328                     'wx-platform' : wx.Platform,
       
  4329                     'python-version' : platform.python_version(), #sys.version.split()[0],
       
  4330                     'platform' : platform.platform(),
       
  4331                     'e-type' : e_type,
       
  4332                     'e-value' : e_value,
       
  4333                     'date' : time.ctime(),
       
  4334                     'cwd' : os.getcwd(),
       
  4335                     }
       
  4336                 if e_traceback:
       
  4337                     info['traceback'] = ''.join(traceback.format_tb(e_traceback)) + '%s: %s' % (e_type, e_value)
       
  4338                     last_tb = get_last_traceback(e_traceback)
       
  4339                     exception_locals = last_tb.tb_frame.f_locals # the locals at the level of the stack trace where the exception actually occurred
       
  4340                     info['locals'] = format_namespace(exception_locals)
       
  4341                     if 'self' in exception_locals:
       
  4342                         info['self'] = format_namespace(exception_locals['self'].__dict__)
       
  4343                 
       
  4344                 output = open(path+os.sep+"bug_report_"+info['date'].replace(':','-').replace(' ','_')+".txt",'w')
       
  4345                 lst = info.keys()
       
  4346                 lst.sort()
       
  4347                 for a in lst:
       
  4348                     output.write(a+":\n"+str(info[a])+"\n\n")
       
  4349 
       
  4350     #sys.excepthook = lambda *args: wx.CallAfter(handle_exception, *args)
       
  4351     sys.excepthook = handle_exception
       
  4352 
       
  4353 if __name__ == '__main__':
       
  4354     wx.InitAllImageHandlers()
       
  4355     
       
  4356     # Install a exception handle for bug reports
       
  4357     AddExceptHook(os.getcwd(),__version__)
       
  4358     
       
  4359     frame = PLCOpenEditor(None, fileOpen=fileOpen)
       
  4360 
       
  4361     frame.Show()
       
  4362     app.MainLoop()
       
  4363