PLCOpenEditor.py
changeset 440 e183bffc05f0
parent 438 eebcf66f2d5a
parent 439 c7e0254be378
child 444 865a33108ea0
equal deleted inserted replaced
438:eebcf66f2d5a 440:e183bffc05f0
     1 #!/usr/bin/env python
     1 (binary file text/x-python, hash: b44c0975cfce47c7a2c8339d9d185fc586dc4e31)
     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):
       
   872         if not self.Controler.ProjectIsSaved():
       
   873             dialog = wx.MessageDialog(self, _("There are changes, do you want to save?"), _("Close Application"), 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         event.Skip()
       
   912 
       
   913     def OnPageSetupMenu(self, event):
       
   914         dialog = wx.PageSetupDialog(self, self.PageSetupData)
       
   915         if dialog.ShowModal() == wx.ID_OK:
       
   916             self.PageSetupData = wx.PageSetupDialogData(dialog.GetPageSetupData())
       
   917             self.PrintData = wx.PrintData(self.PageSetupData.GetPrintData())
       
   918         dialog.Destroy()
       
   919         event.Skip()
       
   920 
       
   921     def OnPreviewMenu(self, event):
       
   922         selected = self.TabsOpened.GetSelection()        
       
   923         if selected != -1:
       
   924             window = self.TabsOpened.GetPage(selected)
       
   925             data = wx.PrintDialogData(self.PrintData)
       
   926             properties = self.Controler.GetProjectProperties(window.IsDebugging())
       
   927             page_size = map(int, properties["pageSize"])
       
   928             margins = (self.PageSetupData.GetMarginTopLeft(), self.PageSetupData.GetMarginBottomRight())
       
   929             printout = GraphicPrintout(window, page_size, margins, True)
       
   930             printout2 = GraphicPrintout(window, page_size, margins, True)
       
   931             preview = wx.PrintPreview(printout, printout2, data)
       
   932 
       
   933             if preview.Ok():
       
   934                 preview_frame = wx.PreviewFrame(preview, self, _("Print preview"))
       
   935 
       
   936                 preview_frame.Initialize()
       
   937                 
       
   938                 preview_frame.Show(True)
       
   939         event.Skip()
       
   940 
       
   941     def OnPrintMenu(self, event):
       
   942         selected = self.TabsOpened.GetSelection()        
       
   943         if selected != -1:
       
   944             window = self.TabsOpened.GetPage(selected)
       
   945             dialog_data = wx.PrintDialogData(self.PrintData)
       
   946             dialog_data.SetToPage(1)
       
   947             properties = self.Controler.GetProjectProperties(window.IsDebugging())
       
   948             page_size = map(int, properties["pageSize"])
       
   949             margins = (self.PageSetupData.GetMarginTopLeft(), self.PageSetupData.GetMarginBottomRight())
       
   950             printer = wx.Printer(dialog_data)
       
   951             printout = GraphicPrintout(window, page_size, margins)
       
   952             
       
   953             if not printer.Print(self, printout, True):
       
   954                 self.ShowErrorMessage(_("There was a problem printing.\nPerhaps your current printer is not set correctly?"))
       
   955             printout.Destroy()
       
   956         event.Skip()
       
   957 
       
   958     def OnPropertiesMenu(self, event):
       
   959         self.ShowProperties()
       
   960         event.Skip()
       
   961 
       
   962     def OnQuitMenu(self, event):
       
   963         self.Close()
       
   964         # don't call event.Skip() here or it will attempt to close the
       
   965         # frame twice for some reason
       
   966 
       
   967 #-------------------------------------------------------------------------------
       
   968 #                            Edit Menu Functions
       
   969 #-------------------------------------------------------------------------------
       
   970 
       
   971     def RefreshEditMenu(self):
       
   972         if self.Controler is not None:
       
   973             undo, redo = self.Controler.GetBufferState()
       
   974             self.EditMenu.Enable(wx.ID_UNDO, undo)
       
   975             self.EditMenu.Enable(wx.ID_REDO, redo)
       
   976             self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, True)
       
   977             self.EditMenu.Check(ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, 
       
   978                             self.Controler.IsProjectBufferEnabled())
       
   979             self.EditMenu.Enable(wx.ID_ADD, True)
       
   980             self.EditMenu.Enable(wx.ID_DELETE, True)
       
   981             if self.TabsOpened.GetPageCount() > 0:
       
   982                 self.EditMenu.Enable(wx.ID_CUT, True)
       
   983                 self.EditMenu.Enable(wx.ID_COPY, True)
       
   984                 if self.GetCopyBuffer() is not None:
       
   985                     self.EditMenu.Enable(wx.ID_PASTE, True)
       
   986                 else:
       
   987                     self.EditMenu.Enable(wx.ID_PASTE, False)
       
   988                 self.EditMenu.Enable(wx.ID_SELECTALL, True)
       
   989             else:
       
   990                 self.EditMenu.Enable(wx.ID_CUT, False)
       
   991                 self.EditMenu.Enable(wx.ID_COPY, False)
       
   992                 self.EditMenu.Enable(wx.ID_PASTE, False)
       
   993                 self.EditMenu.Enable(wx.ID_SELECTALL, False)
       
   994         else:
       
   995             self.EditMenu.Enable(wx.ID_UNDO, False)
       
   996             self.EditMenu.Enable(wx.ID_REDO, False)
       
   997             self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, False)
       
   998             self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, False)
       
   999             self.EditMenu.Enable(wx.ID_CUT, False)
       
  1000             self.EditMenu.Enable(wx.ID_COPY, False)
       
  1001             self.EditMenu.Enable(wx.ID_PASTE, False)
       
  1002             self.EditMenu.Enable(wx.ID_SELECTALL, False)
       
  1003             self.EditMenu.Enable(wx.ID_ADD, False)
       
  1004             self.EditMenu.Enable(wx.ID_DELETE, False)
       
  1005     
       
  1006     def CloseTabsWithoutModel(self):
       
  1007         idxs = range(self.TabsOpened.GetPageCount())
       
  1008         idxs.reverse()
       
  1009         for idx in idxs:
       
  1010             window = self.TabsOpened.GetPage(idx)
       
  1011             if not window.IsDebugging():
       
  1012                 tagname = window.GetTagName()
       
  1013                 if self.Controler.GetEditedElement(tagname) is None:
       
  1014                     self.VariablePanelIndexer.RemoveVariablePanel(tagname)
       
  1015                     self.TabsOpened.DeletePage(idx)
       
  1016 
       
  1017     def CloseDebugTabs(self):
       
  1018         if self.EnableDebug:
       
  1019             idxs = range(self.TabsOpened.GetPageCount())
       
  1020             idxs.reverse()
       
  1021             for idx in idxs:
       
  1022                 window = self.TabsOpened.GetPage(idx)
       
  1023                 if window.IsDebugging():
       
  1024                     self.TabsOpened.DeletePage(idx)
       
  1025             self.DebugVariablePanel.ResetGrid()
       
  1026 
       
  1027     def OnUndoMenu(self, event):
       
  1028         self.Controler.LoadPrevious()
       
  1029         self.CloseTabsWithoutModel()
       
  1030         self.RefreshEditor()
       
  1031         self._Refresh(TITLE, EDITMENU, TYPESTREE, INSTANCESTREE, LIBRARYTREE, 
       
  1032                       SCALING)
       
  1033         event.Skip()
       
  1034     
       
  1035     def OnRedoMenu(self, event):
       
  1036         self.Controler.LoadNext()
       
  1037         self.CloseTabsWithoutModel()
       
  1038         self.RefreshEditor()
       
  1039         self._Refresh(TITLE, EDITMENU, TYPESTREE, INSTANCESTREE, LIBRARYTREE, 
       
  1040                       SCALING)
       
  1041         event.Skip()
       
  1042     
       
  1043     def OnEnableUndoRedoMenu(self, event):
       
  1044         self.Controler.EnableProjectBuffer(event.IsChecked())
       
  1045         self.RefreshEditMenu()
       
  1046         event.Skip()
       
  1047 
       
  1048     OnCutMenu = GetShortcutKeyCallbackFunction("Cut")
       
  1049     OnCopyMenu = GetShortcutKeyCallbackFunction("Copy")
       
  1050     OnPasteMenu = GetShortcutKeyCallbackFunction("Paste")
       
  1051 
       
  1052     def OnSelectAllMenu(self, event):
       
  1053         control = self.FindFocus()
       
  1054         if isinstance(control, (Viewer, TextViewer)):
       
  1055             control.SelectAll()
       
  1056         elif isinstance(control, wx.TextCtrl):
       
  1057             control.SetSelection(0, control.GetLastPosition())
       
  1058         elif isinstance(control, wx.ComboBox):
       
  1059             control.SetMark(0, control.GetLastPosition() + 1)
       
  1060         event.Skip()
       
  1061     
       
  1062     DeleteFunctions = {
       
  1063         ITEM_DATATYPE: GetDeleteElementFunction(PLCControler.ProjectRemoveDataType, check_function=PLCControler.DataTypeIsUsed),
       
  1064         ITEM_POU: GetDeleteElementFunction(PLCControler.ProjectRemovePou, check_function=PLCControler.PouIsUsed),
       
  1065         ITEM_TRANSITION: GetDeleteElementFunction(PLCControler.ProjectRemovePouTransition, ITEM_POU),
       
  1066         ITEM_ACTION: GetDeleteElementFunction(PLCControler.ProjectRemovePouAction, ITEM_POU),
       
  1067         ITEM_CONFIGURATION: GetDeleteElementFunction(PLCControler.ProjectRemoveConfiguration),
       
  1068         ITEM_RESOURCE: GetDeleteElementFunction(PLCControler.ProjectRemoveConfigurationResource, ITEM_CONFIGURATION)
       
  1069     }
       
  1070     
       
  1071     def OnDeleteMenu(self, event):
       
  1072         window = self.FindFocus()
       
  1073         if window == self.TypesTree or window is None:
       
  1074             selected = self.TypesTree.GetSelection()
       
  1075             if selected.IsOk():
       
  1076                 type = self.TypesTree.GetPyData(selected)
       
  1077                 function = self.DeleteFunctions.get(type, None)
       
  1078                 if function is not None:
       
  1079                     function(self, selected)
       
  1080                     self.CloseTabsWithoutModel()
       
  1081                     self._Refresh(TITLE, TOOLBAR, EDITMENU, TYPESTREE, 
       
  1082                                   INSTANCESTREE, LIBRARYTREE)
       
  1083         elif isinstance(window, (Viewer, TextViewer)):
       
  1084             event = wx.KeyEvent(wx.EVT_CHAR._getEvtType())
       
  1085             event.m_keyCode = wx.WXK_DELETE
       
  1086             window.ProcessEvent(event)
       
  1087         event.Skip()
       
  1088 
       
  1089 
       
  1090 #-------------------------------------------------------------------------------
       
  1091 #                             Display Menu Functions
       
  1092 #-------------------------------------------------------------------------------
       
  1093 
       
  1094     def RefreshDisplayMenu(self):
       
  1095         if self.Controler is not None:
       
  1096             if self.TabsOpened.GetPageCount() > 0:
       
  1097                 self.DisplayMenu.Enable(wx.ID_REFRESH, True)
       
  1098                 selected = self.TabsOpened.GetSelection()
       
  1099                 if selected != -1:
       
  1100                     window = self.TabsOpened.GetPage(selected)
       
  1101                     if isinstance(window, Viewer):
       
  1102                         self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, True)
       
  1103                         zoommenu = self.DisplayMenu.FindItemById(wx.ID_ZOOM_FIT).GetSubMenu()
       
  1104                         zoomitem = zoommenu.FindItemByPosition(window.GetScale())
       
  1105                         zoomitem.Check(True)
       
  1106                     else:
       
  1107                         self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, False)
       
  1108                 else:
       
  1109                     self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, False)
       
  1110             else:
       
  1111                 self.DisplayMenu.Enable(wx.ID_REFRESH, False)
       
  1112                 self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, False)
       
  1113             if self.EnableDebug:
       
  1114                 self.DisplayMenu.Enable(wx.ID_CLEAR, True)
       
  1115         else:
       
  1116             self.DisplayMenu.Enable(wx.ID_REFRESH, False)
       
  1117             if self.EnableDebug:
       
  1118                 self.DisplayMenu.Enable(wx.ID_CLEAR, False)
       
  1119             self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, False)
       
  1120         
       
  1121     def OnRefreshMenu(self, event):
       
  1122         self.RefreshEditor()
       
  1123         event.Skip()
       
  1124 
       
  1125     def OnClearErrorsMenu(self, event):
       
  1126         self.ClearErrors()
       
  1127         event.Skip()
       
  1128 
       
  1129     def GenerateZoomFunction(self, idx):
       
  1130         def ZoomFunction(event):
       
  1131             selected = self.TabsOpened.GetSelection()
       
  1132             if selected != -1:
       
  1133                 window = self.TabsOpened.GetPage(selected)
       
  1134                 window.SetScale(idx)
       
  1135                 window.RefreshVisibleElements()
       
  1136                 window.RefreshScrollBars()
       
  1137             event.Skip()
       
  1138         return ZoomFunction
       
  1139 
       
  1140 
       
  1141 #-------------------------------------------------------------------------------
       
  1142 #                      Project Editor Panels Management Functions
       
  1143 #-------------------------------------------------------------------------------
       
  1144     
       
  1145     def OnPageDragged(self, event):
       
  1146         wx.CallAfter(self.RefreshTabCtrlEvent)
       
  1147         event.Skip()
       
  1148     
       
  1149     def RefreshTabCtrlEvent(self):
       
  1150         if USE_AUI:
       
  1151             auitabctrl = []
       
  1152             for child in self.TabsOpened.GetChildren():
       
  1153                 if isinstance(child, wx.aui.AuiTabCtrl):
       
  1154                     auitabctrl.append(child)
       
  1155                     if child not in self.AuiTabCtrl:
       
  1156                         child.Bind(wx.EVT_LEFT_DCLICK, self.GetTabsOpenedDClickFunction(child))
       
  1157             self.AuiTabCtrl = auitabctrl
       
  1158             if self.TabsOpened.GetPageCount() == 0:
       
  1159                 pane = self.AUIManager.GetPane(self.TabsOpened)
       
  1160                 if pane.IsMaximized():
       
  1161                     self.AUIManager.RestorePane(pane)
       
  1162                 self.AUIManager.Update()
       
  1163     
       
  1164     def OnPouSelectedChanged(self, event):
       
  1165         old_selected = self.TabsOpened.GetSelection()
       
  1166         if old_selected >= 0:
       
  1167             window = self.TabsOpened.GetPage(old_selected)
       
  1168             if not window.IsDebugging():
       
  1169                 window.ResetBuffer()
       
  1170         selected = event.GetSelection()
       
  1171         if selected >= 0:
       
  1172             window = self.TabsOpened.GetPage(selected)
       
  1173             if not window.IsDebugging():
       
  1174                 self.SelectTypesTreeItem(window.GetTagName())
       
  1175             else:
       
  1176                 self.SelectInstancesTreeItem(self.InstancesTree.GetRootItem(), window.GetInstancePath())
       
  1177             window.RefreshView()
       
  1178             if not window.IsDebugging():
       
  1179                 self.VariablePanelIndexer.ChangeVariablePanel(window.GetTagName())
       
  1180             self._Refresh(FILEMENU, EDITMENU, DISPLAYMENU, TOOLBAR)
       
  1181         event.Skip()
       
  1182 
       
  1183     def RefreshEditor(self, variablepanel = True):
       
  1184         selected = self.TabsOpened.GetSelection()
       
  1185         if selected != -1:
       
  1186             window = self.TabsOpened.GetPage(selected)
       
  1187             window.RefreshView()
       
  1188             if not window.IsDebugging() and variablepanel:
       
  1189                 self.RefreshVariablePanel(window.GetTagName())
       
  1190 
       
  1191     def RefreshVariablePanel(self, tagname):
       
  1192         self.VariablePanelIndexer.RefreshVariablePanel(tagname)
       
  1193 
       
  1194     def RefreshEditorNames(self, old_tagname, new_tagname):
       
  1195         for i in xrange(self.TabsOpened.GetPageCount()):
       
  1196             editor = self.TabsOpened.GetPage(i)
       
  1197             if editor.GetTagName() == old_tagname:
       
  1198                 editor.SetTagName(new_tagname)
       
  1199         self.VariablePanelIndexer.UpdateVariablePanelTagName(old_tagname, new_tagname)
       
  1200 
       
  1201     def IsOpened(self, tagname):
       
  1202         for idx in xrange(self.TabsOpened.GetPageCount()):
       
  1203             if self.TabsOpened.GetPage(idx).IsViewing(tagname):
       
  1204                 return idx
       
  1205         return None
       
  1206 
       
  1207     def RefreshPageTitles(self):
       
  1208         for idx in xrange(self.TabsOpened.GetPageCount()):
       
  1209             window = self.TabsOpened.GetPage(idx)
       
  1210             debug = window.IsDebugging()
       
  1211             words = window.GetTagName().split("::")
       
  1212             if words[0] == "P":
       
  1213                 pou_type = self.Controler.GetEditedElementType(window.GetTagName(), debug)[1].upper()
       
  1214                 pou_body_type = self.Controler.GetEditedElementBodyType(window.GetTagName(), debug)
       
  1215                 self.SetPageBitmap(idx, self.GenerateBitmap(pou_type, pou_body_type))
       
  1216             elif words[0] == "T":
       
  1217                 pou_body_type = self.Controler.GetEditedElementBodyType(window.GetTagName(), debug)
       
  1218                 self.SetPageBitmap(idx, self.GenerateBitmap("TRANSITION", pou_body_type))
       
  1219             elif words[0] == "A":
       
  1220                 pou_body_type = self.Controler.GetEditedElementBodyType(window.GetTagName(), debug)
       
  1221                 self.SetPageBitmap(idx, self.GenerateBitmap("ACTION", pou_body_type))
       
  1222             elif words[0] == "C":
       
  1223                 self.SetPageBitmap(idx, self.GenerateBitmap("CONFIGURATION"))
       
  1224             elif words[0] == "R":
       
  1225                 self.SetPageBitmap(idx, self.GenerateBitmap("RESOURCE"))
       
  1226             elif words[0] == "D":
       
  1227                 self.SetPageBitmap(idx, self.GenerateBitmap("DATATYPE"))
       
  1228             if debug:
       
  1229                 text = window.GetInstancePath()
       
  1230                 if len(text) > 15:
       
  1231                     text = "..." + text[-12:]
       
  1232                 self.TabsOpened.SetPageText(idx, text)
       
  1233             else:
       
  1234                 self.TabsOpened.SetPageText(idx, "-".join(words[1:]))
       
  1235 
       
  1236     def GetTabsOpenedDClickFunction(self, tabctrl):
       
  1237         def OnTabsOpenedDClick(event):
       
  1238             pos = event.GetPosition()
       
  1239             if tabctrl.TabHitTest(pos.x, pos.y, None):
       
  1240                 pane = self.AUIManager.GetPane(self.TabsOpened)
       
  1241                 if pane.IsMaximized():
       
  1242                     self.AUIManager.RestorePane(pane)
       
  1243                 else:
       
  1244                     self.AUIManager.MaximizePane(pane)
       
  1245                 self.AUIManager.Update()
       
  1246             event.Skip()
       
  1247         return OnTabsOpenedDClick
       
  1248 
       
  1249 #-------------------------------------------------------------------------------
       
  1250 #                         Types Tree Management Functions
       
  1251 #-------------------------------------------------------------------------------
       
  1252 
       
  1253     def RefreshTypesTree(self):
       
  1254         infos = self.Controler.GetProjectInfos()
       
  1255         root = self.TypesTree.GetRootItem()
       
  1256         if not root.IsOk():
       
  1257             root = self.TypesTree.AddRoot(infos["name"])
       
  1258         self.GenerateTypesTreeBranch(root, infos)
       
  1259         self.TypesTree.Expand(root)
       
  1260 
       
  1261     def ResetSelectedItem(self):
       
  1262         self.SelectedItem = None
       
  1263 
       
  1264     def GenerateTypesTreeBranch(self, root, infos, topology=False):
       
  1265         to_delete = []
       
  1266         item_name = infos["name"]
       
  1267         self.TypesTree.SetItemText(root, _(item_name))
       
  1268         self.TypesTree.SetPyData(root, infos["type"])
       
  1269         if infos.get("tagname", None) in self.Errors:
       
  1270             self.TypesTree.SetItemBackgroundColour(root, wx.Colour(255, 255, 0))
       
  1271             self.TypesTree.SetItemTextColour(root, wx.RED)
       
  1272         else:
       
  1273             self.TypesTree.SetItemBackgroundColour(root, wx.WHITE)
       
  1274             self.TypesTree.SetItemTextColour(root, wx.BLACK)
       
  1275         if infos["type"] == ITEM_POU:
       
  1276             self.TypesTree.SetItemImage(root, self.TreeImageDict[self.Controler.GetPouBodyType(infos["name"])])
       
  1277         else:
       
  1278             self.TypesTree.SetItemImage(root, self.TreeImageDict[infos["type"]])      
       
  1279             
       
  1280         if wx.VERSION >= (2, 6, 0):
       
  1281             item, root_cookie = self.TypesTree.GetFirstChild(root)
       
  1282         else:
       
  1283             item, root_cookie = self.TypesTree.GetFirstChild(root, 0)
       
  1284         for values in infos["values"]:
       
  1285             if not item.IsOk():
       
  1286                 item = self.TypesTree.AppendItem(root, "")
       
  1287                 if wx.Platform != '__WXMSW__':
       
  1288                     item, root_cookie = self.TypesTree.GetNextChild(root, root_cookie)
       
  1289             self.GenerateTypesTreeBranch(item, values)
       
  1290             item, root_cookie = self.TypesTree.GetNextChild(root, root_cookie)
       
  1291         while item.IsOk():
       
  1292             to_delete.append(item)
       
  1293             item, root_cookie = self.TypesTree.GetNextChild(root, root_cookie)
       
  1294         for item in to_delete:
       
  1295             self.TypesTree.Delete(item)
       
  1296 
       
  1297     def SelectTypesTreeItem(self, tagname):
       
  1298         if self.TypesTree is not None:
       
  1299             root = self.TypesTree.GetRootItem()
       
  1300             words = tagname.split("::")
       
  1301             if words[0] == "D":
       
  1302                 return self.RecursiveTypesTreeItemSelection(root, [(words[1], ITEM_DATATYPE)])
       
  1303             elif words[0] == "P":
       
  1304                 return self.RecursiveTypesTreeItemSelection(root, [(words[1], ITEM_POU)])
       
  1305             elif words[0] == "T":
       
  1306                 return self.RecursiveTypesTreeItemSelection(root, [(words[1], ITEM_POU), (words[2], ITEM_TRANSITION)])
       
  1307             elif words[0] == "A":
       
  1308                 return self.RecursiveTypesTreeItemSelection(root, [(words[1], ITEM_POU), (words[2], ITEM_ACTION)])
       
  1309             elif words[0] == "C":
       
  1310                 return self.RecursiveTypesTreeItemSelection(root, [(words[1], ITEM_CONFIGURATION)])
       
  1311             elif words[0] == "R":
       
  1312                 return self.RecursiveTypesTreeItemSelection(root, [(words[1], ITEM_CONFIGURATION), (words[2], ITEM_RESOURCE)])
       
  1313         return False
       
  1314 
       
  1315     def RecursiveTypesTreeItemSelection(self, root, items):
       
  1316         found = False
       
  1317         if self.TypesTree is not None:
       
  1318             if wx.VERSION >= (2, 6, 0):
       
  1319                 item, root_cookie = self.TypesTree.GetFirstChild(root)
       
  1320             else:
       
  1321                 item, root_cookie = self.TypesTree.GetFirstChild(root, 0)
       
  1322             while item.IsOk() and not found:
       
  1323                 if (self.TypesTree.GetItemText(item), self.TypesTree.GetPyData(item)) == items[0]:
       
  1324                     if len(items) == 1:
       
  1325                         self.SelectedItem = item
       
  1326                         self.TypesTree.SelectItem(item)
       
  1327                         wx.CallAfter(self.ResetSelectedItem)
       
  1328                         return True
       
  1329                     else:
       
  1330                         found = self.RecursiveTypesTreeItemSelection(item, items[1:])
       
  1331                 else:
       
  1332                     found = self.RecursiveTypesTreeItemSelection(item, items)
       
  1333                 item, root_cookie = self.TypesTree.GetNextChild(root, root_cookie)
       
  1334         return found
       
  1335 
       
  1336     def OnTypesTreeBeginDrag(self, event):
       
  1337         if wx.Platform == '__WXMSW__':
       
  1338             self.SelectedItem = event.GetItem()
       
  1339         if self.SelectedItem is not None and self.TypesTree.GetPyData(self.SelectedItem) == ITEM_POU:
       
  1340             block_name = self.TypesTree.GetItemText(self.SelectedItem)
       
  1341             block_type = self.Controler.GetPouType(block_name)
       
  1342             if block_type != "program":
       
  1343                 data = wx.TextDataObject(str((block_name, block_type, "")))
       
  1344                 dragSource = wx.DropSource(self.TypesTree)
       
  1345                 dragSource.SetData(data)
       
  1346                 dragSource.DoDragDrop()
       
  1347             self.ResetSelectedItem()
       
  1348 
       
  1349     def OnTypesTreeItemBeginEdit(self, event):
       
  1350         selected = event.GetItem()
       
  1351         if self.TypesTree.GetPyData(selected) in ITEMS_UNEDITABLE:
       
  1352             event.Veto()
       
  1353         else:
       
  1354             event.Skip()
       
  1355 
       
  1356     def OnTypesTreeItemEndEdit(self, event):
       
  1357         message = None
       
  1358         abort = False
       
  1359         new_name = event.GetLabel()
       
  1360         if new_name != "":
       
  1361             if not TestIdentifier(new_name):
       
  1362                 message = _("\"%s\" is not a valid identifier!")%new_name
       
  1363             elif new_name.upper() in IEC_KEYWORDS:
       
  1364                 message = _("\"%s\" is a keyword. It can't be used!")%new_name
       
  1365             else:
       
  1366                 item = event.GetItem()
       
  1367                 old_name = self.TypesTree.GetItemText(item)
       
  1368                 itemtype = self.TypesTree.GetPyData(item)
       
  1369                 if itemtype == ITEM_PROJECT:
       
  1370                     self.Controler.SetProjectProperties(name = new_name)
       
  1371                 elif itemtype == ITEM_DATATYPE:
       
  1372                     if new_name.upper() in [name.upper() for name in self.Controler.GetProjectDataTypeNames() if name != old_name]:
       
  1373                         message = _("\"%s\" data type already exists!")%new_name
       
  1374                         abort = True
       
  1375                     if not abort:
       
  1376                         self.Controler.ChangeDataTypeName(old_name, new_name)
       
  1377                         self.RefreshEditorNames(self.Controler.ComputeDataTypeName(old_name), 
       
  1378                                                 self.Controler.ComputeDataTypeName(new_name))
       
  1379                         self.RefreshPageTitles()
       
  1380                 elif itemtype == ITEM_POU:
       
  1381                     if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames() if name != old_name]:
       
  1382                         message = _("\"%s\" pou already exists!")%new_name
       
  1383                         abort = True
       
  1384                     elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables()]:
       
  1385                         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)
       
  1386                         if messageDialog.ShowModal() == wx.ID_NO:
       
  1387                             abort = True
       
  1388                         messageDialog.Destroy()
       
  1389                     if not abort:
       
  1390                         self.Controler.ChangePouName(old_name, new_name)
       
  1391                         self.RefreshEditorNames(self.Controler.ComputePouName(old_name), 
       
  1392                                                 self.Controler.ComputePouName(new_name))
       
  1393                         self.RefreshLibraryTree()
       
  1394                         self.RefreshPageTitles()
       
  1395                 elif itemtype == ITEM_TRANSITION:
       
  1396                     pou_name = GetParentName(self.TypesTree, item, ITEM_POU)
       
  1397                     if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
       
  1398                         message = _("A POU named \"%s\" already exists!")%new_name
       
  1399                     elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name) if name != old_name]:
       
  1400                         message = _("A variable with \"%s\" as name already exists in this pou!")%new_name
       
  1401                     else:
       
  1402                         self.Controler.ChangePouTransitionName(pou_name, old_name, new_name)
       
  1403                         self.RefreshEditorNames(self.Controler.ComputePouTransitionName(pou_name, old_name), 
       
  1404                                                 self.Controler.ComputePouTransitionName(pou_name, new_name))
       
  1405                         self.RefreshPageTitles()
       
  1406                 elif itemtype == ITEM_ACTION:
       
  1407                     pou_name = GetParentName(self.TypesTree, item, ITEM_POU)
       
  1408                     if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
       
  1409                         message = _("A POU named \"%s\" already exists!")%new_name
       
  1410                     elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name) if name != old_name]:
       
  1411                         message = _("A variable with \"%s\" as name already exists in this pou!")%new_name
       
  1412                     else:
       
  1413                         self.Controler.ChangePouActionName(pou_name, old_name, new_name)
       
  1414                         self.RefreshEditorNames(self.Controler.ComputePouActionName(pou_name, old_name), 
       
  1415                                                 self.Controler.ComputePouActionName(pou_name, new_name))
       
  1416                         self.RefreshPageTitles()
       
  1417                 elif itemtype == ITEM_CONFIGURATION:
       
  1418                     if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames() if name != old_name]:
       
  1419                         message = _("\"%s\" config already exists!")%new_name
       
  1420                         abort = True
       
  1421                     elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
       
  1422                         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)
       
  1423                         if messageDialog.ShowModal() == wx.ID_NO:
       
  1424                             abort = True
       
  1425                         messageDialog.Destroy()
       
  1426                     elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables()]:
       
  1427                         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)
       
  1428                         if messageDialog.ShowModal() == wx.ID_NO:
       
  1429                             abort = True
       
  1430                         messageDialog.Destroy()
       
  1431                     if not abort:
       
  1432                         self.Controler.ChangeConfigurationName(old_name, new_name)
       
  1433                         self.RefreshEditorNames(self.Controler.ComputeConfigurationName(old_name), 
       
  1434                                                 self.Controler.ComputeConfigurationName(new_name))
       
  1435                         self.RefreshPageTitles()
       
  1436                 elif itemtype == ITEM_RESOURCE:
       
  1437                     config_name = GetParentName(self.TypesTree, item, ITEM_CONFIGURATION)
       
  1438                     if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames()]:
       
  1439                         message = _("\"%s\" config already exists!")%new_name
       
  1440                         abort = True
       
  1441                     elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
       
  1442                         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)
       
  1443                         if messageDialog.ShowModal() == wx.ID_NO:
       
  1444                             abort = True
       
  1445                         messageDialog.Destroy()
       
  1446                     elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables()]:
       
  1447                         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)
       
  1448                         if messageDialog.ShowModal() == wx.ID_NO:
       
  1449                             abort = True
       
  1450                         messageDialog.Destroy()
       
  1451                     if not abort:
       
  1452                         self.Controler.ChangeConfigurationResourceName(config_name, old_name, new_name)
       
  1453                         self.RefreshEditorNames(self.Controler.ComputeConfigurationResourceName(config_name, old_name), 
       
  1454                                                 self.Controler.ComputeConfigurationResourceName(config_name, new_name))
       
  1455                         self.RefreshPageTitles()
       
  1456             if message or abort:
       
  1457                 if message:
       
  1458                     self.ShowErrorMessage(message)
       
  1459                 item = event.GetItem()
       
  1460                 wx.CallAfter(self.TypesTree.EditLabel, item)
       
  1461                 event.Veto()
       
  1462             else:
       
  1463                 wx.CallAfter(self.RefreshTypesTree)
       
  1464                 self.RefreshEditor()
       
  1465                 self._Refresh(TITLE, FILEMENU, EDITMENU)
       
  1466                 event.Skip()
       
  1467     
       
  1468     def OnTypesTreeItemActivated(self, event):
       
  1469         selected = event.GetItem()
       
  1470         name = self.TypesTree.GetItemText(selected)
       
  1471         data = self.TypesTree.GetPyData(selected)
       
  1472         if UNEDITABLE_NAMES_DICT.get(name, name) == "Properties":
       
  1473             self.ShowProperties()
       
  1474         if data == ITEM_DATATYPE:
       
  1475             self.EditProjectElement(data, self.Controler.ComputeDataTypeName(name))
       
  1476         elif data == ITEM_POU:
       
  1477             self.EditProjectElement(data, self.Controler.ComputePouName(name))
       
  1478         elif data == ITEM_CONFIGURATION:
       
  1479             self.EditProjectElement(data, self.Controler.ComputeConfigurationName(name))
       
  1480         elif data == ITEM_RESOURCE:
       
  1481             config_name = GetParentName(self.TypesTree, selected, ITEM_CONFIGURATION)
       
  1482             self.EditProjectElement(data, self.Controler.ComputeConfigurationResourceName(config_name, name))
       
  1483         elif data in [ITEM_TRANSITION, ITEM_ACTION]:
       
  1484             pou_name = GetParentName(self.TypesTree, selected, ITEM_POU)
       
  1485             if data == ITEM_TRANSITION:
       
  1486                 tagname = self.Controler.ComputePouTransitionName(pou_name, name)
       
  1487             elif data == ITEM_ACTION:
       
  1488                 tagname = self.Controler.ComputePouActionName(pou_name, name)
       
  1489             self.EditProjectElement(data, tagname)
       
  1490         event.Skip()
       
  1491     
       
  1492     def TypesTreeItemSelect(self, select_item):
       
  1493         name = self.TypesTree.GetItemText(select_item)
       
  1494         data = self.TypesTree.GetPyData(select_item)
       
  1495         if data == ITEM_DATATYPE:
       
  1496             self.EditProjectElement(data, self.Controler.ComputeDataTypeName(name), True)
       
  1497         elif data == ITEM_POU:
       
  1498             self.EditProjectElement(data, self.Controler.ComputePouName(name), True)
       
  1499         elif data == ITEM_CONFIGURATION:
       
  1500             self.EditProjectElement(data, self.Controler.ComputeConfigurationName(name), True)
       
  1501         elif data == ITEM_RESOURCE:
       
  1502             config_name = GetParentName(self.TypesTree, select_item, ITEM_CONFIGURATION)
       
  1503             self.EditProjectElement(data, self.Controler.ComputeConfigurationResourceName(config_name, name), True)
       
  1504         elif data in [ITEM_TRANSITION, ITEM_ACTION]:
       
  1505             pou_name = GetParentName(self.TypesTree, select_item, ITEM_POU)
       
  1506             if data == ITEM_TRANSITION:
       
  1507                 tagname = self.Controler.ComputePouTransitionName(pou_name, name)
       
  1508             elif data == ITEM_ACTION:
       
  1509                 tagname = self.Controler.ComputePouActionName(pou_name, name)
       
  1510             self.EditProjectElement(data, tagname, True)
       
  1511     
       
  1512     def OnTypesTreeLeftUp(self, event):
       
  1513         if self.SelectedItem is not None:
       
  1514             self.TypesTree.SelectItem(self.SelectedItem)
       
  1515             self.TypesTreeItemSelect(self.SelectedItem)
       
  1516             wx.CallAfter(self.ResetSelectedItem)
       
  1517         event.Skip()
       
  1518     
       
  1519     def OnTypesTreeItemSelected(self, event):
       
  1520         self.TypesTreeItemSelect(event.GetItem())
       
  1521         event.Skip()
       
  1522     
       
  1523     def OnTypesTreeItemChanging(self, event):
       
  1524         if self.TypesTree.GetPyData(event.GetItem()) not in ITEMS_UNEDITABLE and self.SelectedItem is None:
       
  1525             self.SelectedItem = event.GetItem()
       
  1526             event.Veto()
       
  1527         else:
       
  1528             event.Skip()
       
  1529     
       
  1530     def EditProjectElement(self, elementtype, tagname, onlyopened = False):
       
  1531         openedidx = self.IsOpened(tagname)
       
  1532         if openedidx is not None:
       
  1533             old_selected = self.TabsOpened.GetSelection()
       
  1534             if old_selected != openedidx:
       
  1535                 if old_selected >= 0:
       
  1536                     self.TabsOpened.GetPage(old_selected).ResetBuffer()
       
  1537                 self.TabsOpened.SetSelection(openedidx)
       
  1538             self.VariablePanelIndexer.ChangeVariablePanel(tagname)
       
  1539             self.RefreshPageTitles()
       
  1540             self._Refresh(FILEMENU, EDITMENU, TOOLBAR)
       
  1541         elif not onlyopened:
       
  1542             if elementtype == ITEM_CONFIGURATION:
       
  1543                 new_window = ConfigurationEditor(self.TabsOpened, tagname, self, self.Controler)
       
  1544                 self.AddPage(new_window, "")
       
  1545                 self.VariablePanelIndexer.AddVariablePanel(tagname, "config")
       
  1546             elif elementtype == ITEM_RESOURCE:
       
  1547                 new_window = ResourceEditor(self.TabsOpened, tagname, self, self.Controler)
       
  1548                 self.AddPage(new_window, "")
       
  1549                 self.VariablePanelIndexer.AddVariablePanel(tagname, "resource")
       
  1550             elif elementtype in [ITEM_POU, ITEM_TRANSITION, ITEM_ACTION]:
       
  1551                 bodytype = self.Controler.GetEditedElementBodyType(tagname)
       
  1552                 if bodytype == "FBD":
       
  1553                     new_window = Viewer(self.TabsOpened, tagname, self, self.Controler)
       
  1554                     new_window.RefreshScaling(False)
       
  1555                 elif bodytype == "LD":
       
  1556                     new_window = LD_Viewer(self.TabsOpened, tagname, self, self.Controler)
       
  1557                     new_window.RefreshScaling(False)
       
  1558                 elif bodytype == "SFC":
       
  1559                     new_window = SFC_Viewer(self.TabsOpened, tagname, self, self.Controler)
       
  1560                     new_window.RefreshScaling(False)
       
  1561                 else:
       
  1562                     new_window = TextViewer(self.TabsOpened, tagname, self, self.Controler)
       
  1563                     new_window.SetTextSyntax(bodytype)
       
  1564                     if bodytype == "IL":
       
  1565                         new_window.SetKeywords(IL_KEYWORDS)
       
  1566                     else:
       
  1567                         new_window.SetKeywords(ST_KEYWORDS)
       
  1568                 self.AddPage(new_window, "")
       
  1569                 words = tagname.split("::")
       
  1570                 self.VariablePanelIndexer.AddVariablePanel(tagname, self.Controler.GetPouType(words[1]))
       
  1571             elif elementtype == ITEM_DATATYPE:
       
  1572                 new_window = DataTypeEditor(self.TabsOpened, tagname, self, self.Controler)
       
  1573                 self.AddPage(new_window, "")
       
  1574             self.VariablePanelIndexer.ChangeVariablePanel(tagname)
       
  1575             openedidx = self.IsOpened(tagname)
       
  1576             old_selected = self.TabsOpened.GetSelection()
       
  1577             if old_selected != openedidx:
       
  1578                 if old_selected >= 0:
       
  1579                     self.TabsOpened.GetPage(old_selected).ResetBuffer()
       
  1580             for i in xrange(self.TabsOpened.GetPageCount()):
       
  1581                 window = self.TabsOpened.GetPage(i)
       
  1582                 if window.GetTagName() == tagname:
       
  1583                     self.TabsOpened.SetSelection(i)
       
  1584                     window.SetFocus()
       
  1585                     self.RefreshPageTitles()
       
  1586                     self._Refresh(FILEMENU, EDITMENU, TOOLBAR)
       
  1587     
       
  1588     def OnTypesTreeRightUp(self, event):
       
  1589         if wx.Platform == '__WXMSW__':
       
  1590             item = event.GetItem()
       
  1591             self.TypesTree.SelectItem(item)
       
  1592         else:
       
  1593             item = self.TypesTree.GetSelection()
       
  1594         name = self.TypesTree.GetItemText(item)
       
  1595         type = self.TypesTree.GetPyData(item)
       
  1596         if type == ITEM_POU:
       
  1597             menu = wx.Menu(title='')
       
  1598             if self.Controler.GetPouBodyType(name) == "SFC":
       
  1599                 new_id = wx.NewId()
       
  1600                 AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Transition"))
       
  1601                 self.Bind(wx.EVT_MENU, self.GenerateAddTransitionFunction(name), id=new_id)
       
  1602                 new_id = wx.NewId()
       
  1603                 AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Action"))
       
  1604                 self.Bind(wx.EVT_MENU, self.GenerateAddActionFunction(name), id=new_id)
       
  1605                 menu.AppendSeparator()
       
  1606 
       
  1607             new_id = wx.NewId()
       
  1608             AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Create a new POU from"))
       
  1609             self.Bind(wx.EVT_MENU, self.OnCreatePouFromMenu, id=new_id)
       
  1610 
       
  1611             AppendMenu(menu, help='', id=wx.ID_COPY, kind=wx.ITEM_NORMAL, text=_("Copy"))
       
  1612             self.Bind(wx.EVT_MENU, self.OnCopyPou, id=wx.ID_COPY)
       
  1613 
       
  1614             pou_type = self.Controler.GetPouType(name)
       
  1615             if pou_type in ["function", "functionBlock"]:
       
  1616                 change_menu = wx.Menu(title='')
       
  1617                 if pou_type == "function":
       
  1618                     new_id = wx.NewId()
       
  1619                     AppendMenu(change_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Function Block"))
       
  1620                     self.Bind(wx.EVT_MENU, self.GenerateChangePouTypeFunction(name, "functionBlock"), id=new_id)
       
  1621                 new_id = wx.NewId()
       
  1622                 AppendMenu(change_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Program"))
       
  1623                 self.Bind(wx.EVT_MENU, self.GenerateChangePouTypeFunction(name, "program"), id=new_id)
       
  1624                 menu.AppendMenu(wx.NewId(), _("Change POU Type To"), change_menu)
       
  1625             new_id = wx.NewId()
       
  1626             AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Rename"))
       
  1627             self.Bind(wx.EVT_MENU, self.OnRenamePouMenu, id=new_id)
       
  1628             new_id = wx.NewId()
       
  1629             AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Delete"))
       
  1630             self.Bind(wx.EVT_MENU, self.OnDeleteMenu, id=new_id)
       
  1631             self.PopupMenu(menu)
       
  1632         elif type == ITEM_CONFIGURATION:
       
  1633             menu = wx.Menu(title='')
       
  1634             new_id = wx.NewId()
       
  1635             AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Resource"))
       
  1636             self.Bind(wx.EVT_MENU, self.GenerateAddResourceFunction(name), id=new_id)
       
  1637             new_id = wx.NewId()
       
  1638             AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Delete"))
       
  1639             self.Bind(wx.EVT_MENU, self.OnDeleteMenu, id=new_id)
       
  1640             self.PopupMenu(menu)
       
  1641         elif type in [ITEM_DATATYPE, ITEM_TRANSITION, ITEM_ACTION, ITEM_RESOURCE]:
       
  1642             menu = wx.Menu(title='')
       
  1643             new_id = wx.NewId()
       
  1644             AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Delete"))
       
  1645             self.Bind(wx.EVT_MENU, self.OnDeleteMenu, id=new_id)
       
  1646             self.PopupMenu(menu)
       
  1647         elif type in ITEMS_UNEDITABLE:
       
  1648             name = UNEDITABLE_NAMES_DICT[name]
       
  1649             if name == "Data Types":
       
  1650                 menu = wx.Menu(title='')
       
  1651                 new_id = wx.NewId()
       
  1652                 AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add DataType"))
       
  1653                 self.Bind(wx.EVT_MENU, self.OnAddDataTypeMenu, id=new_id)
       
  1654                 self.PopupMenu(menu)
       
  1655             elif name in ["Functions", "Function Blocks", "Programs"]:
       
  1656                 menu = wx.Menu(title='')
       
  1657 
       
  1658                 new_id = wx.NewId()
       
  1659                 AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Pou"))
       
  1660                 self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction({"Functions" : "function", "Function Blocks" : "functionBlock", "Programs" : "program"}[name]), id=new_id)
       
  1661 
       
  1662                 AppendMenu(menu, help='', id=wx.ID_PASTE, kind=wx.ITEM_NORMAL, text=_("Paste"))
       
  1663                 self.Bind(wx.EVT_MENU, self.OnPastePou, id=wx.ID_PASTE)
       
  1664 
       
  1665                 if self.GetCopyBuffer() is None:
       
  1666                     menu.Enable(wx.ID_PASTE, False)
       
  1667 
       
  1668                 self.PopupMenu(menu)
       
  1669             elif name == "Configurations":
       
  1670                 menu = wx.Menu(title='')
       
  1671                 new_id = wx.NewId()
       
  1672                 AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Configuration"))
       
  1673                 self.Bind(wx.EVT_MENU, self.OnAddConfigurationMenu, id=new_id)
       
  1674                 self.PopupMenu(menu)
       
  1675             elif name == "Transitions":
       
  1676                 menu = wx.Menu(title='')
       
  1677                 new_id = wx.NewId()
       
  1678                 AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Transition"))
       
  1679                 parent = self.TypesTree.GetItemParent(item)
       
  1680                 parent_type = self.TypesTree.GetPyData(parent)
       
  1681                 while parent_type != ITEM_POU:
       
  1682                     parent = self.TypesTree.GetItemParent(parent)
       
  1683                     parent_type = self.TypesTree.GetPyData(parent)
       
  1684                 self.Bind(wx.EVT_MENU, self.GenerateAddTransitionFunction(self.TypesTree.GetItemText(parent)), id=new_id)
       
  1685                 self.PopupMenu(menu)
       
  1686             elif name == "Actions":
       
  1687                 menu = wx.Menu(title='')
       
  1688                 new_id = wx.NewId()
       
  1689                 AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Action"))
       
  1690                 parent = self.TypesTree.GetItemParent(item)
       
  1691                 parent_type = self.TypesTree.GetPyData(parent)
       
  1692                 while parent_type != ITEM_POU:
       
  1693                     parent = self.TypesTree.GetItemParent(parent)
       
  1694                     parent_type = self.TypesTree.GetPyData(parent)
       
  1695                 self.Bind(wx.EVT_MENU, self.GenerateAddActionFunction(self.TypesTree.GetItemText(parent)), id=new_id)
       
  1696                 self.PopupMenu(menu)
       
  1697             elif name == "Resources":
       
  1698                 menu = wx.Menu(title='')
       
  1699                 new_id = wx.NewId()
       
  1700                 AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Resource"))
       
  1701                 parent = self.TypesTree.GetItemParent(item)
       
  1702                 parent_type = self.TypesTree.GetPyData(parent)
       
  1703                 while parent_type != ITEM_CONFIGURATION:
       
  1704                     parent = self.TypesTree.GetItemParent(parent)
       
  1705                     parent_type = self.TypesTree.GetPyData(parent)
       
  1706                 self.Bind(wx.EVT_MENU, self.GenerateAddResourceFunction(self.TypesTree.GetItemText(parent)), id=new_id)
       
  1707                 self.PopupMenu(menu)
       
  1708         event.Skip()
       
  1709 
       
  1710 
       
  1711 #-------------------------------------------------------------------------------
       
  1712 #                         Instances Tree Management Functions
       
  1713 #-------------------------------------------------------------------------------
       
  1714 
       
  1715     def RefreshInstancesTree(self):
       
  1716         infos = self.Controler.GetProjectTopology(self.EnableDebug)
       
  1717         root = self.InstancesTree.GetRootItem()
       
  1718         if not root.IsOk():
       
  1719             root = self.InstancesTree.AddRoot(infos["name"])
       
  1720         self.GenerateInstancesTreeBranch(root, infos)
       
  1721         self.InstancesTree.Expand(root)
       
  1722 
       
  1723     def GenerateInstancesTreeBranch(self, root, infos):
       
  1724         to_delete = []
       
  1725         if infos.get("elmt_type", None) is not None:
       
  1726             self.InstancesTree.SetItemText(root, "%s (%s)"%(infos["name"], infos["elmt_type"]))
       
  1727         else:
       
  1728             self.InstancesTree.SetItemText(root, infos["name"])
       
  1729         self.InstancesTree.SetPyData(root, (infos["type"], infos.get("tagname", None)))
       
  1730         self.InstancesTree.SetItemImage(root, self.TreeImageDict[infos["type"]])
       
  1731             
       
  1732         if wx.VERSION >= (2, 6, 0):
       
  1733             item, root_cookie = self.InstancesTree.GetFirstChild(root)
       
  1734         else:
       
  1735             item, root_cookie = self.InstancesTree.GetFirstChild(root, 0)
       
  1736         for values in infos["values"]:
       
  1737             if not item.IsOk():
       
  1738                 item = self.InstancesTree.AppendItem(root, "")
       
  1739                 if wx.Platform != '__WXMSW__':
       
  1740                     item, root_cookie = self.InstancesTree.GetNextChild(root, root_cookie)
       
  1741             self.GenerateInstancesTreeBranch(item, values)
       
  1742             item, root_cookie = self.InstancesTree.GetNextChild(root, root_cookie)
       
  1743         while item.IsOk():
       
  1744             to_delete.append(item)
       
  1745             item, root_cookie = self.InstancesTree.GetNextChild(root, root_cookie)
       
  1746         for item in to_delete:
       
  1747             self.InstancesTree.Delete(item)
       
  1748 
       
  1749     def OnInstancesTreeBeginDrag(self, event):
       
  1750         if self.Controler.DebugAvailable():
       
  1751             selected_item = event.GetItem()
       
  1752             selected_infos = self.InstancesTree.GetPyData(selected_item)
       
  1753             if selected_item is not None and selected_infos[0] in ITEMS_VARIABLE:
       
  1754                 var_path = self.InstancesTree.GetItemText(selected_item).split(" (")[0]
       
  1755                 parent_item = self.InstancesTree.GetItemParent(selected_item)
       
  1756                 while self.InstancesTree.GetPyData(parent_item)[0] != ITEM_PROJECT:
       
  1757                     parent_name = self.InstancesTree.GetItemText(parent_item).split(" (")[0]
       
  1758                     var_path = "%s.%s"%(parent_name, var_path)
       
  1759                     parent_item = self.InstancesTree.GetItemParent(parent_item)
       
  1760                 data = wx.TextDataObject(str((var_path, "debug")))
       
  1761                 dragSource = wx.DropSource(self.InstancesTree)
       
  1762                 dragSource.SetData(data)
       
  1763                 dragSource.DoDragDrop()
       
  1764             event.Skip()
       
  1765         else:
       
  1766             event.Veto()
       
  1767 
       
  1768     def OnInstancesTreeItemActivated(self, event):
       
  1769         if self.Controler.DebugAvailable():
       
  1770             selected_item = event.GetItem()
       
  1771             selected_infos = self.InstancesTree.GetPyData(selected_item)
       
  1772             if selected_item is not None and selected_infos[0] in [ITEM_FUNCTIONBLOCK, ITEM_PROGRAM, ITEM_TRANSITION, ITEM_ACTION]:
       
  1773                 instance_path = self.InstancesTree.GetItemText(selected_item).split(" (")[0]
       
  1774                 parent_item = self.InstancesTree.GetItemParent(selected_item)
       
  1775                 while self.InstancesTree.GetPyData(parent_item)[0] != ITEM_PROJECT:
       
  1776                     parent_name = self.InstancesTree.GetItemText(parent_item).split(" (")[0]
       
  1777                     instance_path = "%s.%s"%(parent_name, instance_path)
       
  1778                     parent_item = self.InstancesTree.GetItemParent(parent_item)
       
  1779                 openedidx = self.IsOpened(instance_path)
       
  1780                 if openedidx is not None:
       
  1781                     old_selected = self.TabsOpened.GetSelection()
       
  1782                     if old_selected != openedidx:
       
  1783                         if old_selected >= 0:
       
  1784                             self.TabsOpened.GetPage(old_selected).ResetBuffer()
       
  1785                         self.TabsOpened.SetSelection(openedidx)
       
  1786                 elif selected_infos[1] is not None:
       
  1787                     bodytype = self.Controler.GetEditedElementBodyType(selected_infos[1], True)
       
  1788                     if bodytype == "FBD":
       
  1789                         new_window = Viewer(self.TabsOpened, selected_infos[1], self, self.Controler, True, instance_path)
       
  1790                         new_window.RefreshScaling(False)
       
  1791                     elif bodytype == "LD":
       
  1792                         new_window = LD_Viewer(self.TabsOpened, selected_infos[1], self, self.Controler, True, instance_path)
       
  1793                         new_window.RefreshScaling(False)
       
  1794                     elif bodytype == "SFC":
       
  1795                         new_window = SFC_Viewer(self.TabsOpened, selected_infos[1], self, self.Controler, True, instance_path)
       
  1796                         new_window.RefreshScaling(False)
       
  1797                     else:
       
  1798                         new_window = TextViewer(self.TabsOpened, selected_infos[1], self, self.Controler, True, instance_path)
       
  1799                         new_window.SetTextSyntax(bodytype)
       
  1800                         if bodytype == "IL":
       
  1801                             new_window.SetKeywords(IL_KEYWORDS)
       
  1802                         else:
       
  1803                             new_window.SetKeywords(ST_KEYWORDS)
       
  1804                     self.AddPage(new_window, "")
       
  1805                     new_window.SetFocus()
       
  1806                     self.RefreshPageTitles()
       
  1807             if selected_item is not None and selected_infos[0] in ITEMS_VARIABLE:
       
  1808                 var_path, var_type = self.InstancesTree.GetItemText(selected_item).split(" (")
       
  1809                 var_type = var_type.split(")")[0]
       
  1810                 
       
  1811                 if self.Controler.IsOfType(var_type, "ANY_NUM", True) or\
       
  1812                    self.Controler.IsOfType(var_type, "ANY_BIT", True):
       
  1813                     parent_item = self.InstancesTree.GetItemParent(selected_item)
       
  1814                     while self.InstancesTree.GetPyData(parent_item)[0] != ITEM_PROJECT:
       
  1815                         parent_name = self.InstancesTree.GetItemText(parent_item).split(" (")[0]
       
  1816                         var_path = "%s.%s"%(parent_name, var_path)
       
  1817                         parent_item = self.InstancesTree.GetItemParent(parent_item)
       
  1818                     
       
  1819                     self.OpenGraphicViewer(var_path)
       
  1820         event.Skip()
       
  1821 
       
  1822     def OpenGraphicViewer(self, var_path):
       
  1823         new_window = GraphicViewer(self.TabsOpened, self, self.Controler, var_path)
       
  1824         self.AddPage(new_window, "")
       
  1825         new_window.SetFocus()
       
  1826         self.RefreshPageTitles()
       
  1827 
       
  1828     def OnInstancesTreeRightUp(self, event):
       
  1829         if self.Controler.DebugAvailable():
       
  1830             if wx.Platform == '__WXMSW__':
       
  1831                 selected_item = event.GetItem()
       
  1832             else:
       
  1833                 selected_item = self.InstancesTree.GetSelection()
       
  1834             selected_infos = self.InstancesTree.GetPyData(selected_item)
       
  1835             if selected_item is not None and selected_infos[0] in ITEMS_VARIABLE:
       
  1836                 var_path, var_type = self.InstancesTree.GetItemText(selected_item).split(" (")
       
  1837                 var_type = var_type.split(")")[0]
       
  1838                 
       
  1839                 if self.Controler.IsOfType(var_type, "ANY_NUM", True) or\
       
  1840                    self.Controler.IsOfType(var_type, "ANY_BIT", True):
       
  1841                     parent_item = self.InstancesTree.GetItemParent(selected_item)
       
  1842                     while self.InstancesTree.GetPyData(parent_item)[0] != ITEM_PROJECT:
       
  1843                         parent_name = self.InstancesTree.GetItemText(parent_item).split(" (")[0]
       
  1844                         var_path = "%s.%s"%(parent_name, var_path)
       
  1845                         parent_item = self.InstancesTree.GetItemParent(parent_item)
       
  1846                     
       
  1847                     menu = wx.Menu(title='')
       
  1848                     new_id = wx.NewId()
       
  1849                     AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Graphic Panel"))
       
  1850                     self.Bind(wx.EVT_MENU, self.AddVariableGraphicFunction(var_path), id=new_id)
       
  1851                     new_id = wx.NewId()
       
  1852                     AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("CSV Log"))
       
  1853                     self.PopupMenu(menu)
       
  1854         event.Skip()
       
  1855 
       
  1856     def AddVariableGraphicFunction(self, iec_path):
       
  1857         def AddVariableGraphic(event):
       
  1858             self.OpenGraphicViewer(iec_path)
       
  1859             event.Skip()
       
  1860         return AddVariableGraphic
       
  1861 
       
  1862     def SelectInstancesTreeItem(self, root, instancepath):
       
  1863         found = False
       
  1864         if self.InstancesTree is not None:
       
  1865             paths = instancepath.split(".", 1)
       
  1866             if wx.VERSION >= (2, 6, 0):
       
  1867                 item, root_cookie = self.InstancesTree.GetFirstChild(root)
       
  1868             else:
       
  1869                 item, root_cookie = self.InstancesTree.GetFirstChild(root, 0)
       
  1870             while item.IsOk() and not found:
       
  1871                 name = self.InstancesTree.GetItemText(item).split(" (")[0]
       
  1872                 if name == paths[0]:
       
  1873                     if len(paths) == 1:
       
  1874                         self.InstancesTree.SelectItem(item)
       
  1875                         return True
       
  1876                     else:
       
  1877                         found = self.SelectInstancesTreeItem(item, paths[1])
       
  1878                 item, root_cookie = self.InstancesTree.GetNextChild(root, root_cookie)
       
  1879         return found
       
  1880 
       
  1881     def ResetGraphicViewers(self):
       
  1882         for i in xrange(self.TabsOpened.GetPageCount()):
       
  1883             editor = self.TabsOpened.GetPage(i)
       
  1884             if isinstance(editor, GraphicViewer):
       
  1885                 editor.ResetView()
       
  1886 
       
  1887 #-------------------------------------------------------------------------------
       
  1888 #                         Library Tree Management Functions
       
  1889 #-------------------------------------------------------------------------------
       
  1890 
       
  1891     def RefreshLibraryTree(self):
       
  1892         to_delete = []
       
  1893         blocktypes = self.Controler.GetBlockTypes()
       
  1894         root = self.LibraryTree.GetRootItem()
       
  1895         if not root.IsOk():
       
  1896             if wx.Platform == '__WXMSW__':
       
  1897                 root = self.LibraryTree.AddRoot(_("Block Types"))
       
  1898                 self.LibraryTree.SetPyData(root, {"type" : CATEGORY})
       
  1899             else:
       
  1900                 root = self.LibraryTree.AddRoot("")
       
  1901         if wx.VERSION >= (2, 6, 0):
       
  1902             category_item, root_cookie = self.LibraryTree.GetFirstChild(root)
       
  1903         else:
       
  1904             category_item, root_cookie = self.LibraryTree.GetFirstChild(root, 0)
       
  1905         for category in blocktypes:
       
  1906             category_name = category["name"]
       
  1907             if not category_item.IsOk():
       
  1908                 category_item = self.LibraryTree.AppendItem(root, _(category_name))
       
  1909                 if wx.Platform != '__WXMSW__':
       
  1910                     category_item, root_cookie = self.LibraryTree.GetNextChild(root, root_cookie)
       
  1911             else:
       
  1912                 self.LibraryTree.SetItemText(category_item, _(category_name))
       
  1913             self.LibraryTree.SetPyData(category_item, {"type" : CATEGORY})
       
  1914             if wx.VERSION >= (2, 6, 0):
       
  1915                 blocktype_item, category_cookie = self.LibraryTree.GetFirstChild(category_item)
       
  1916             else:
       
  1917                 blocktype_item, category_cookie = self.LibraryTree.GetFirstChild(category_item, 0)        
       
  1918             for blocktype in category["list"]:
       
  1919                 if not blocktype_item.IsOk():
       
  1920                     blocktype_item = self.LibraryTree.AppendItem(category_item, blocktype["name"])
       
  1921                     if wx.Platform != '__WXMSW__':
       
  1922                         blocktype_item, category_cookie = self.LibraryTree.GetNextChild(category_item, category_cookie)
       
  1923                 else:
       
  1924                     self.LibraryTree.SetItemText(blocktype_item, blocktype["name"])
       
  1925                 self.LibraryTree.SetPyData(blocktype_item, {"type" : BLOCK, "block_type" : blocktype["type"], "inputs" : tuple([type for name, type, modifier in blocktype["inputs"]])})
       
  1926                 blocktype_item, category_cookie = self.LibraryTree.GetNextChild(category_item, category_cookie)
       
  1927             while blocktype_item.IsOk():
       
  1928                 to_delete.append(blocktype_item)
       
  1929                 blocktype_item, category_cookie = self.LibraryTree.GetNextChild(category_item, category_cookie)
       
  1930             category_item, root_cookie = self.LibraryTree.GetNextChild(root, root_cookie)
       
  1931         while category_item.IsOk():
       
  1932             to_delete.append(category_item)
       
  1933             category_item, root_cookie = self.LibraryTree.GetNextChild(root, root_cookie)
       
  1934         for item in to_delete:
       
  1935             self.LibraryTree.Delete(item)
       
  1936         if wx.Platform == '__WXMSW__':        
       
  1937             self.LibraryTree.Expand(root)
       
  1938 
       
  1939     def OnLibraryTreeItemSelected(self, event):
       
  1940         selected = event.GetItem()
       
  1941         pydata = self.LibraryTree.GetPyData(selected)
       
  1942         if pydata is not None and pydata["type"] != CATEGORY:
       
  1943             blocktype = self.Controler.GetBlockType(self.LibraryTree.GetItemText(selected), pydata["inputs"])
       
  1944             if blocktype:
       
  1945                 comment = blocktype["comment"]
       
  1946                 self.LibraryComment.SetValue(_(comment) + blocktype.get("usage", ""))
       
  1947             else:
       
  1948                 self.LibraryComment.SetValue("")
       
  1949         else:
       
  1950             self.LibraryComment.SetValue("")
       
  1951         event.Skip()
       
  1952 
       
  1953     def OnLibraryTreeBeginDrag(self, event):
       
  1954         selected = event.GetItem()
       
  1955         pydata = self.LibraryTree.GetPyData(selected)
       
  1956         if pydata is not None and pydata["type"] == BLOCK:
       
  1957             data = wx.TextDataObject(str((self.LibraryTree.GetItemText(selected), 
       
  1958                 pydata["block_type"], "", pydata["inputs"])))
       
  1959             dragSource = wx.DropSource(self.LibraryTree)
       
  1960             dragSource.SetData(data)
       
  1961             dragSource.DoDragDrop()
       
  1962 
       
  1963 #-------------------------------------------------------------------------------
       
  1964 #                          ToolBar Management Functions
       
  1965 #-------------------------------------------------------------------------------
       
  1966 
       
  1967     def ResetToolBar(self):
       
  1968         for item in self.CurrentToolBar:
       
  1969             if wx.VERSION >= (2, 6, 0):
       
  1970                 self.Unbind(wx.EVT_MENU, id=item)
       
  1971             else:
       
  1972                 self.Disconnect(id=item, eventType=wx.wxEVT_COMMAND_MENU_SELECTED) 
       
  1973             
       
  1974             if USE_AUI:
       
  1975                 ToolBar = self.Panes["ToolBar"]
       
  1976             else:
       
  1977                 ToolBar = self.ToolBar
       
  1978             if ToolBar:
       
  1979                 ToolBar.DeleteTool(item)
       
  1980                 ToolBar.Realize()
       
  1981                 if USE_AUI:
       
  1982                     self.AUIManager.GetPane("ToolBar").BestSize(ToolBar.GetBestSize())
       
  1983                     self.AUIManager.Update()
       
  1984 
       
  1985     def RefreshToolBar(self):
       
  1986         selected = self.TabsOpened.GetSelection()
       
  1987         language = None
       
  1988         if selected != -1:
       
  1989             window = self.TabsOpened.GetPage(selected)
       
  1990             if not window.IsDebugging():
       
  1991                 language = self.Controler.GetEditedElementBodyType(window.GetTagName())
       
  1992         if language is not None and language != self.CurrentLanguage:
       
  1993             self.ResetToolBar()
       
  1994             self.CurrentLanguage = language
       
  1995             self.CurrentToolBar = []
       
  1996             if USE_AUI:
       
  1997                 ToolBar = self.Panes["ToolBar"]
       
  1998             else:
       
  1999                 ToolBar = self.ToolBar
       
  2000             if ToolBar:
       
  2001                 for radio, modes, id, method, picture, help in ToolBarItems[language]:
       
  2002                     if modes & self.DrawingMode:
       
  2003                         if radio or self.DrawingMode == FREEDRAWING_MODE:
       
  2004                             ToolBar.AddRadioTool(id, wx.Bitmap(os.path.join(CWD, "Images", picture)), wx.NullBitmap, help)
       
  2005                         else:
       
  2006                             ToolBar.AddSimpleTool(id, wx.Bitmap(os.path.join(CWD, "Images", picture)), help)
       
  2007                         self.Bind(wx.EVT_TOOL, getattr(self, method), id=id)
       
  2008                         self.CurrentToolBar.append(id)
       
  2009                 ToolBar.Realize()
       
  2010                 if USE_AUI:
       
  2011                     self.AUIManager.GetPane("ToolBar").BestSize(ToolBar.GetBestSize())
       
  2012                     self.AUIManager.Update()
       
  2013         elif not language:
       
  2014             self.ResetToolBar()
       
  2015             self.CurrentLanguage = language
       
  2016         self.ResetCurrentMode()
       
  2017 
       
  2018 
       
  2019 #-------------------------------------------------------------------------------
       
  2020 #                           ToolBar Items Functions
       
  2021 #-------------------------------------------------------------------------------
       
  2022 
       
  2023     def ResetCurrentMode(self):
       
  2024         selected = self.TabsOpened.GetSelection()
       
  2025         if selected != -1:
       
  2026             window = self.TabsOpened.GetPage(selected)
       
  2027             window.SetMode(MODE_SELECTION)
       
  2028         if USE_AUI:
       
  2029             ToolBar = self.Panes["ToolBar"]
       
  2030         else:
       
  2031             ToolBar = self.ToolBar
       
  2032         if ToolBar:
       
  2033             ToolBar.ToggleTool(ID_PLCOPENEDITORTOOLBARSELECTION, False)
       
  2034             ToolBar.ToggleTool(ID_PLCOPENEDITORTOOLBARSELECTION, True)
       
  2035         
       
  2036     def ResetToolToggle(self, id):
       
  2037         if USE_AUI:
       
  2038             tool = self.Panes["ToolBar"].FindById(id)
       
  2039         else:
       
  2040             tool = self.ToolBar.FindById(id)
       
  2041         tool.SetToggle(False)
       
  2042 
       
  2043     def OnSelectionTool(self, event):
       
  2044         selected = self.TabsOpened.GetSelection()
       
  2045         if selected != -1:
       
  2046             self.TabsOpened.GetPage(selected).SetMode(MODE_SELECTION)
       
  2047         event.Skip()
       
  2048     
       
  2049     def OnCommentTool(self, event):
       
  2050         self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARCOMMENT)
       
  2051         selected = self.TabsOpened.GetSelection()
       
  2052         if selected != -1:
       
  2053             self.TabsOpened.GetPage(selected).SetMode(MODE_COMMENT)
       
  2054         event.Skip()
       
  2055     
       
  2056     def OnVariableTool(self, event):
       
  2057         self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARVARIABLE)
       
  2058         selected = self.TabsOpened.GetSelection()
       
  2059         if selected != -1:
       
  2060             self.TabsOpened.GetPage(selected).SetMode(MODE_VARIABLE)
       
  2061         event.Skip()
       
  2062     
       
  2063     def OnBlockTool(self, event):
       
  2064         self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARBLOCK)
       
  2065         selected = self.TabsOpened.GetSelection()
       
  2066         if selected != -1:
       
  2067             self.TabsOpened.GetPage(selected).SetMode(MODE_BLOCK)
       
  2068         event.Skip()
       
  2069         
       
  2070     def OnConnectionTool(self, event):
       
  2071         self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARCONNECTION)
       
  2072         selected = self.TabsOpened.GetSelection()
       
  2073         if selected != -1:
       
  2074             self.TabsOpened.GetPage(selected).SetMode(MODE_CONNECTION)
       
  2075         event.Skip()
       
  2076 
       
  2077     def OnPowerRailTool(self, event):
       
  2078         self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARPOWERRAIL)
       
  2079         selected = self.TabsOpened.GetSelection()
       
  2080         if selected != -1:
       
  2081             self.TabsOpened.GetPage(selected).SetMode(MODE_POWERRAIL)
       
  2082         event.Skip()
       
  2083 
       
  2084     def OnRungTool(self, event):
       
  2085         selected = self.TabsOpened.GetSelection()
       
  2086         if selected != -1:
       
  2087             self.TabsOpened.GetPage(selected).AddLadderRung()
       
  2088         event.Skip()
       
  2089     
       
  2090     def OnCoilTool(self, event):
       
  2091         self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARCOIL)
       
  2092         selected = self.TabsOpened.GetSelection()
       
  2093         if selected != -1:
       
  2094             self.TabsOpened.GetPage(selected).SetMode(MODE_COIL)
       
  2095         event.Skip()
       
  2096     
       
  2097     def OnContactTool(self, event):
       
  2098         if self.DrawingMode == FREEDRAWING_MODE:
       
  2099             self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARCONTACT)
       
  2100         selected = self.TabsOpened.GetSelection()
       
  2101         if selected != -1:
       
  2102             if self.DrawingMode == FREEDRAWING_MODE:
       
  2103                 self.TabsOpened.GetPage(selected).SetMode(MODE_CONTACT)
       
  2104             else:
       
  2105                 self.TabsOpened.GetPage(selected).AddLadderContact()
       
  2106         event.Skip()
       
  2107     
       
  2108     def OnBranchTool(self, event): 
       
  2109         selected = self.TabsOpened.GetSelection()
       
  2110         if selected != -1:
       
  2111             self.TabsOpened.GetPage(selected).AddLadderBranch()
       
  2112         event.Skip()    
       
  2113     
       
  2114     def OnInitialStepTool(self, event):
       
  2115         self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARINITIALSTEP)
       
  2116         selected = self.TabsOpened.GetSelection()
       
  2117         if selected != -1:
       
  2118             self.TabsOpened.GetPage(selected).SetMode(MODE_INITIALSTEP)
       
  2119         event.Skip()
       
  2120     
       
  2121     def OnStepTool(self, event):
       
  2122         if self.GetDrawingMode() == FREEDRAWING_MODE:
       
  2123             self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARSTEP)
       
  2124         selected = self.TabsOpened.GetSelection()
       
  2125         if selected != -1:
       
  2126             if self.GetDrawingMode() == FREEDRAWING_MODE:
       
  2127                 self.TabsOpened.GetPage(selected).SetMode(MODE_STEP)
       
  2128             else:
       
  2129                 self.TabsOpened.GetPage(selected).AddStep()
       
  2130         event.Skip()
       
  2131 
       
  2132     def OnActionBlockTool(self, event):
       
  2133         if self.GetDrawingMode() == FREEDRAWING_MODE:
       
  2134             self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARACTIONBLOCK)
       
  2135         selected = self.TabsOpened.GetSelection()
       
  2136         if selected != -1:
       
  2137             if self.GetDrawingMode() == FREEDRAWING_MODE:
       
  2138                 self.TabsOpened.GetPage(selected).SetMode(MODE_ACTION)
       
  2139             else:
       
  2140                 self.TabsOpened.GetPage(selected).AddStepAction()
       
  2141         event.Skip()
       
  2142 
       
  2143     def OnTransitionTool(self, event):
       
  2144         self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARTRANSITION)
       
  2145         selected = self.TabsOpened.GetSelection()
       
  2146         if selected != -1:
       
  2147             self.TabsOpened.GetPage(selected).SetMode(MODE_TRANSITION)
       
  2148         event.Skip()
       
  2149 
       
  2150     def OnDivergenceTool(self, event):
       
  2151         if self.GetDrawingMode() == FREEDRAWING_MODE:
       
  2152             self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARDIVERGENCE)
       
  2153         selected = self.TabsOpened.GetSelection()
       
  2154         if selected != -1:
       
  2155             if self.GetDrawingMode() == FREEDRAWING_MODE:
       
  2156                 self.TabsOpened.GetPage(selected).SetMode(MODE_DIVERGENCE)
       
  2157             else:
       
  2158                 self.TabsOpened.GetPage(selected).AddDivergence()
       
  2159         event.Skip()
       
  2160     
       
  2161     def OnJumpTool(self, event):
       
  2162         if self.GetDrawingMode() == FREEDRAWING_MODE:
       
  2163             self.ResetToolToggle(ID_PLCOPENEDITORTOOLBARJUMP)
       
  2164         selected = self.TabsOpened.GetSelection()
       
  2165         if selected != -1:
       
  2166             if self.GetDrawingMode() == FREEDRAWING_MODE:
       
  2167                 self.TabsOpened.GetPage(selected).SetMode(MODE_JUMP)
       
  2168             else:
       
  2169                 self.TabsOpened.GetPage(selected).AddJump()
       
  2170         event.Skip()
       
  2171 
       
  2172 
       
  2173 #-------------------------------------------------------------------------------
       
  2174 #                         Add Project Elements Functions
       
  2175 #-------------------------------------------------------------------------------
       
  2176 
       
  2177     def OnAddDataTypeMenu(self, event):
       
  2178         dialog = DataTypeDialog(self, _("Add a new data type"), _("Please enter data type name"), "", wx.OK|wx.CANCEL)
       
  2179         dialog.SetDataTypeNames(self.Controler.GetProjectDataTypeNames())
       
  2180         if dialog.ShowModal() == wx.ID_OK:
       
  2181             self.Controler.ProjectAddDataType(dialog.GetValue())
       
  2182             self._Refresh(TITLE, EDITMENU, TYPESTREE)
       
  2183         dialog.Destroy()
       
  2184         event.Skip()
       
  2185 
       
  2186     def GenerateAddPouFunction(self, pou_type):
       
  2187         def OnAddPouMenu(event):
       
  2188             dialog = PouDialog(self, pou_type)
       
  2189             dialog.SetPouNames(self.Controler.GetProjectPouNames())
       
  2190             dialog.SetPouElementNames(self.Controler.GetProjectPouVariables())
       
  2191             if dialog.ShowModal() == wx.ID_OK:
       
  2192                 values = dialog.GetValues()
       
  2193                 self.Controler.ProjectAddPou(values["pouName"], values["pouType"], values["language"])
       
  2194                 self._Refresh(TITLE, EDITMENU, TYPESTREE, LIBRARYTREE)
       
  2195             dialog.Destroy()
       
  2196             event.Skip()
       
  2197         return OnAddPouMenu
       
  2198 
       
  2199     def GenerateAddTransitionFunction(self, pou_name):
       
  2200         def OnAddTransitionMenu(event):
       
  2201             dialog = PouTransitionDialog(self)
       
  2202             dialog.SetPouNames(self.Controler.GetProjectPouNames())
       
  2203             dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(pou_name))
       
  2204             if dialog.ShowModal() == wx.ID_OK: 
       
  2205                 values = dialog.GetValues()
       
  2206                 self.Controler.ProjectAddPouTransition(pou_name, values["transitionName"], values["language"])
       
  2207                 self._Refresh(TITLE, EDITMENU, TYPESTREE)
       
  2208                 dialog.Destroy()
       
  2209             event.Skip()
       
  2210         return OnAddTransitionMenu
       
  2211 
       
  2212     def GenerateAddActionFunction(self, pou_name):
       
  2213         def OnAddActionMenu(event):
       
  2214             dialog = PouActionDialog(self)
       
  2215             dialog.SetPouNames(self.Controler.GetProjectPouNames())
       
  2216             dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(pou_name))
       
  2217             if dialog.ShowModal() == wx.ID_OK:
       
  2218                 values = dialog.GetValues()
       
  2219                 self.Controler.ProjectAddPouAction(pou_name, values["actionName"], values["language"])
       
  2220                 self._Refresh(TITLE, EDITMENU, TYPESTREE)
       
  2221             dialog.Destroy()
       
  2222             event.Skip()
       
  2223         return OnAddActionMenu
       
  2224 
       
  2225     def OnAddConfigurationMenu(self, event):
       
  2226         dialog = ConfigurationNameDialog(self, _("Please enter configuration name"), _("Add new configuration"))
       
  2227         dialog.SetPouNames(self.Controler.GetProjectPouNames())
       
  2228         dialog.SetPouElementNames(self.Controler.GetProjectPouVariables())
       
  2229         if dialog.ShowModal() == wx.ID_OK:
       
  2230             value = dialog.GetValue()
       
  2231             self.Controler.ProjectAddConfiguration(value)
       
  2232             self._Refresh(TITLE, EDITMENU, TYPESTREE, INSTANCESTREE)
       
  2233         dialog.Destroy()
       
  2234         event.Skip()
       
  2235 
       
  2236     def GenerateAddResourceFunction(self, config_name):
       
  2237         def OnAddResourceMenu(event):
       
  2238             dialog = ResourceNameDialog(self, _("Please enter resource name"), _("Add new resource"))
       
  2239             dialog.SetPouNames(self.Controler.GetProjectPouNames())
       
  2240             dialog.SetPouElementNames(self.Controler.GetProjectPouVariables())
       
  2241             if dialog.ShowModal() == wx.ID_OK:
       
  2242                 value = dialog.GetValue()
       
  2243                 self.Controler.ProjectAddConfigurationResource(config_name, value)
       
  2244                 self._Refresh(TITLE, EDITMENU, TYPESTREE, INSTANCESTREE)
       
  2245             dialog.Destroy()
       
  2246             event.Skip()
       
  2247         return OnAddResourceMenu
       
  2248 
       
  2249     def GenerateChangePouTypeFunction(self, name, new_type):
       
  2250         def OnChangePouTypeMenu(event):
       
  2251             selected = self.TypesTree.GetSelection()
       
  2252             if self.TypesTree.GetPyData(selected) == ITEM_POU: 
       
  2253                 self.Controler.ProjectChangePouType(name, new_type)
       
  2254                 self._Refresh(TITLE, TOOLBAR, EDITMENU, TYPESTREE, LIBRARYTREE)
       
  2255             event.Skip()
       
  2256         return OnChangePouTypeMenu
       
  2257 
       
  2258     def OnCreatePouFromMenu(self, event):
       
  2259         selected = self.TypesTree.GetSelection()
       
  2260         if self.TypesTree.GetPyData(selected) == ITEM_POU: 
       
  2261             dialog = PouNameDialog(self, _("Please enter POU name"), _("Create a new POU from"), "", wx.OK|wx.CANCEL)
       
  2262             dialog.SetPouNames(self.Controler.GetProjectPouNames())
       
  2263             if dialog.ShowModal() == wx.ID_OK:
       
  2264                 self.Controler.ProjectCreatePouFrom(dialog.GetValue(), self.TypesTree.GetItemText(selected))
       
  2265                 self._Refresh(TITLE, TOOLBAR, EDITMENU, TYPESTREE, LIBRARYTREE)
       
  2266         event.Skip()
       
  2267 
       
  2268     def OnCopyPou(self, event):
       
  2269         selected = self.TypesTree.GetSelection()
       
  2270 
       
  2271         pou_name = self.TypesTree.GetItemText(selected)
       
  2272         pou = self.Controler.Project.getpou(pou_name)
       
  2273 
       
  2274         pou_xml = pou.generateXMLText('pou', 0)
       
  2275         self.SetCopyBuffer(pou_xml)
       
  2276 
       
  2277     def OnPastePou(self, event):
       
  2278         selected = self.TypesTree.GetSelection()
       
  2279 
       
  2280         pou_type = self.TypesTree.GetItemText(selected)
       
  2281         pou_type = UNEDITABLE_NAMES_DICT[pou_type] # one of 'Functions', 'Function Blocks' or 'Programs'
       
  2282         pou_type = {'Functions': 'function', 'Function Blocks': 'functionBlock', 'Programs': 'program'}[pou_type]
       
  2283 
       
  2284         pou_xml = self.GetCopyBuffer()
       
  2285 
       
  2286         result = self.Controler.PastePou(pou_type, pou_xml)
       
  2287 
       
  2288         if result is not None:
       
  2289             message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR)
       
  2290             message.ShowModal()
       
  2291             message.Destroy()
       
  2292         else:
       
  2293             self.RefreshTitle()
       
  2294             self.RefreshEditMenu()
       
  2295             self.RefreshTypesTree()
       
  2296             self.RefreshLibraryTree()
       
  2297             self.RefreshToolBar()
       
  2298 
       
  2299 #-------------------------------------------------------------------------------
       
  2300 #                        Remove Project Elements Functions
       
  2301 #-------------------------------------------------------------------------------
       
  2302 
       
  2303     def OnRemoveDataTypeMenu(self, event):
       
  2304         selected = self.TypesTree.GetSelection()
       
  2305         if self.TypesTree.GetPyData(selected) == ITEM_DATATYPE:
       
  2306             name = self.TypesTree.GetItemText(selected)
       
  2307             if not self.Controler.DataTypeIsUsed(name):
       
  2308                 self.Controler.ProjectRemoveDataType(name)
       
  2309                 tagname = self.Controler.ComputeDataTypeName(name)
       
  2310                 idx = self.IsOpened(tagname)
       
  2311                 if idx is not None:
       
  2312                     self.TabsOpened.DeletePage(idx)
       
  2313                 self._Refresh(TITLE, TOOLBAR, EDITMENU, TYPESTREE)
       
  2314             else:
       
  2315                 self.ShowErrorMessage(_("\"%s\" is used by one or more POUs. It can't be removed!"))
       
  2316         event.Skip()
       
  2317 
       
  2318     def OnRenamePouMenu(self, event):
       
  2319         selected = self.TypesTree.GetSelection()
       
  2320         if self.TypesTree.GetPyData(selected) == ITEM_POU: 
       
  2321             wx.CallAfter(self.TypesTree.EditLabel, selected)
       
  2322         event.Skip()
       
  2323 
       
  2324     def OnRemovePouMenu(self, event):
       
  2325         selected = self.TypesTree.GetSelection()
       
  2326         if self.TypesTree.GetPyData(selected) == ITEM_POU:
       
  2327             name = self.TypesTree.GetItemText(selected)
       
  2328             if not self.Controler.PouIsUsed(name):
       
  2329                 self.Controler.ProjectRemovePou(name)
       
  2330                 tagname = self.Controler.ComputePouName(name)
       
  2331                 idx = self.IsOpened(tagname)
       
  2332                 if idx is not None:
       
  2333                     self.VariablePanelIndexer.RemoveVariablePanel(tagname)
       
  2334                     self.TabsOpened.DeletePage(idx)
       
  2335                 self._Refresh(TITLE, TOOLBAR, EDITMENU, TYPESTREE, INSTANCESTREE, LIBRARYTREE)
       
  2336             else:
       
  2337                 self.ShowErrorMessage(_("\"%s\" is used by one or more POUs. It can't be removed!"))
       
  2338         event.Skip()
       
  2339 
       
  2340     def OnRemoveTransitionMenu(self, event):
       
  2341         selected = self.TypesTree.GetSelection()
       
  2342         if self.TypesTree.GetPyData(selected) == ITEM_TRANSITION: 
       
  2343             transition = self.TypesTree.GetItemText(selected)
       
  2344             item = self.TypesTree.GetItemParent(selected)
       
  2345             item_type = self.TypesTree.GetPyData(item)
       
  2346             while item_type != ITEM_POU:
       
  2347                 item = self.TypesTree.GetItemParent(item)
       
  2348                 item_type = self.TypesTree.GetPyData(item)
       
  2349             pou_name = self.TypesTree.GetItemText(item)
       
  2350             self.Controler.ProjectRemovePouTransition(pou_name, transition)
       
  2351             tagname = self.Controler.ComputePouTransitionName(pou_name, transition)
       
  2352             idx = self.IsOpened(tagname)
       
  2353             if idx is not None:
       
  2354                 self.VariablePanelIndexer.RemoveVariablePanel(tagname)
       
  2355                 self.TabsOpened.DeletePage(idx)
       
  2356             self._Refresh(TITLE, EDITMENU, TYPESTREE)
       
  2357         event.Skip()
       
  2358 
       
  2359     def OnRemoveActionMenu(self, event):
       
  2360         selected = self.TypesTree.GetSelection()
       
  2361         if self.TypesTree.GetPyData(selected) == ITEM_ACTION: 
       
  2362             action = self.TypesTree.GetItemText(selected)
       
  2363             item = self.TypesTree.GetItemParent(selected)
       
  2364             item_type = self.TypesTree.GetPyData(item)
       
  2365             while item_type != ITEM_POU:
       
  2366                 item = self.TypesTree.GetItemParent(item)
       
  2367                 item_type = self.TypesTree.GetPyData(item)
       
  2368             pou_name = self.TypesTree.GetItemText(item)
       
  2369             self.Controler.ProjectRemovePouAction(pou_name, action)
       
  2370             tagname = self.Controler.ComputePouActionName(pou_name, action)
       
  2371             idx = self.IsOpened(tagname)
       
  2372             if idx is not None:
       
  2373                 self.VariablePanelIndexer.RemoveVariablePanel(tagname)
       
  2374                 self.TabsOpened.DeletePage(idx)
       
  2375             self._Refresh(TITLE, EDITMENU, TYPESTREE)
       
  2376         event.Skip()
       
  2377 
       
  2378     def OnRemoveConfigurationMenu(self, event):
       
  2379         selected = self.TypesTree.GetSelection()
       
  2380         if self.TypesTree.GetPyData(selected) == ITEM_CONFIGURATION: 
       
  2381             name = self.TypesTree.GetItemText(selected)
       
  2382             self.Controler.ProjectRemoveConfiguration(name)
       
  2383             tagname = self.Controler.ComputeConfigurationName(name)
       
  2384             idx = self.IsOpened(tagname)
       
  2385             if idx is not None:
       
  2386                 self.VariablePanelIndexer.RemoveVariablePanel(tagname)
       
  2387                 self.TabsOpened.DeletePage(idx)
       
  2388             self._Refresh(TITLE, EDITMENU, TYPESTREE, INSTANCESTREE)
       
  2389         event.Skip()
       
  2390 
       
  2391     def OnRemoveResourceMenu(self, event):
       
  2392         selected = self.TypesTree.GetSelection()
       
  2393         if self.TypesTree.GetPyData(selected) == ITEM_RESOURCE:
       
  2394             resource = self.TypesTree.GetItemText(selected)
       
  2395             item = self.TypesTree.GetItemParent(selected)
       
  2396             item_type = self.TypesTree.GetPyData(item)
       
  2397             while item_type != ITEM_CONFIGURATION:
       
  2398                 item = self.TypesTree.GetItemParent(item)
       
  2399                 item_type = self.TypesTree.GetPyData(item)
       
  2400             config_name = self.TypesTree.GetItemText(item)
       
  2401             self.Controler.ProjectRemoveConfigurationResource(config_name, resource)
       
  2402             tagname = self.Controler.ComputeConfigurationResourceName(config_name, selected)
       
  2403             idx = self.IsOpened(tagname)
       
  2404             if idx is not None:
       
  2405                 self.VariablePanelIndexer.RemoveVariablePanel(tagname)
       
  2406                 self.TabsOpened.DeletePage(idx)
       
  2407             self._Refresh(TITLE, EDITMENU, TYPESTREE, INSTANCESTREE)
       
  2408         event.Skip()
       
  2409     
       
  2410     def OnPLCOpenEditorMenu(self, event):
       
  2411         wx.MessageBox(_("No documentation available.\nComing soon."))
       
  2412         #event.Skip()
       
  2413         
       
  2414     def OnPLCOpenMenu(self, event):
       
  2415         open_pdf(os.path.join(CWD, "plcopen", "TC6_XML_V101.pdf"))
       
  2416         event.Skip()
       
  2417     
       
  2418     def OnAboutMenu(self, event):
       
  2419         OpenHtmlFrame(self,_("About PLCOpenEditor"), os.path.join(CWD, "doc","about.html"), wx.Size(350, 350))
       
  2420         event.Skip()
       
  2421 
       
  2422 
       
  2423 #-------------------------------------------------------------------------------
       
  2424 #                        Errors showing functions
       
  2425 #-------------------------------------------------------------------------------
       
  2426 
       
  2427     def ShowError(self, infos, start, end):
       
  2428         self.EditProjectElement(self.Controler.GetElementType(infos[0]), infos[0])
       
  2429         self.SelectTypesTreeItem(infos[0])
       
  2430         if infos[1] == "name":
       
  2431             self.Errors.append(infos[0])
       
  2432             self.RefreshTypesTree()
       
  2433             self.TypesTree.Unselect()
       
  2434         elif infos[1] == "variable":
       
  2435             self.VariablePanelIndexer.AddVariableError(infos)
       
  2436         else:
       
  2437             selected = self.TabsOpened.GetSelection()
       
  2438             if selected != -1:
       
  2439                 viewer = self.TabsOpened.GetPage(selected)
       
  2440                 viewer.AddShownError(infos[1:], start, end)
       
  2441                 viewer.RefreshView()
       
  2442     
       
  2443     def ClearErrors(self):
       
  2444         self.Errors = []
       
  2445         self.RefreshTypesTree()
       
  2446         self.VariablePanelIndexer.ClearErrors()
       
  2447         for i in xrange(self.TabsOpened.GetPageCount()):
       
  2448             viewer = self.TabsOpened.GetPage(i)
       
  2449             viewer.ClearErrors()
       
  2450 
       
  2451 #-------------------------------------------------------------------------------
       
  2452 #                            PLCOpenEditor Main Class
       
  2453 #-------------------------------------------------------------------------------
       
  2454 
       
  2455 class PLCOpenEditor(IDEFrame):
       
  2456 
       
  2457     # Compatibility function for wx versions < 2.6
       
  2458     if wx.VERSION < (2, 6, 0):
       
  2459         def Bind(self, event, function, id = None):
       
  2460             if id is not None:
       
  2461                 event(self, id, function)
       
  2462             else:
       
  2463                 event(self, function)
       
  2464 
       
  2465     def _init_coll_FileMenu_Items(self, parent):
       
  2466         AppendMenu(parent, help='', id=wx.ID_NEW,
       
  2467               kind=wx.ITEM_NORMAL, text=_(u'New\tCTRL+N'))
       
  2468         AppendMenu(parent, help='', id=wx.ID_OPEN,
       
  2469               kind=wx.ITEM_NORMAL, text=_(u'Open\tCTRL+O'))
       
  2470         AppendMenu(parent, help='', id=wx.ID_CLOSE,
       
  2471               kind=wx.ITEM_NORMAL, text=_(u'Close Tab\tCTRL+W'))
       
  2472         AppendMenu(parent, help='', id=wx.ID_CLOSE_ALL,
       
  2473               kind=wx.ITEM_NORMAL, text=_(u'Close Project'))
       
  2474         parent.AppendSeparator()
       
  2475         AppendMenu(parent, help='', id=wx.ID_SAVE,
       
  2476               kind=wx.ITEM_NORMAL, text=_(u'Save\tCTRL+S'))
       
  2477         AppendMenu(parent, help='', id=wx.ID_SAVEAS,
       
  2478               kind=wx.ITEM_NORMAL, text=_(u'Save As...\tCTRL+SHIFT+S'))
       
  2479         AppendMenu(parent, help='', id=ID_PLCOPENEDITORFILEMENUGENERATE,
       
  2480               kind=wx.ITEM_NORMAL, text=_(u'Generate Program\tCTRL+G'))
       
  2481         parent.AppendSeparator()
       
  2482         AppendMenu(parent, help='', id=wx.ID_PAGE_SETUP,
       
  2483               kind=wx.ITEM_NORMAL, text=_(u'Page Setup'))
       
  2484         AppendMenu(parent, help='', id=wx.ID_PREVIEW,
       
  2485               kind=wx.ITEM_NORMAL, text=_(u'Preview'))
       
  2486         AppendMenu(parent, help='', id=wx.ID_PRINT,
       
  2487               kind=wx.ITEM_NORMAL, text=_(u'Print'))
       
  2488         parent.AppendSeparator()
       
  2489         AppendMenu(parent, help='', id=wx.ID_PROPERTIES,
       
  2490               kind=wx.ITEM_NORMAL, text=_(u'Properties'))
       
  2491         parent.AppendSeparator()
       
  2492         AppendMenu(parent, help='', id=wx.ID_EXIT,
       
  2493               kind=wx.ITEM_NORMAL, text=_(u'Quit\tCTRL+Q'))
       
  2494         
       
  2495         self.Bind(wx.EVT_MENU, self.OnNewProjectMenu, id=wx.ID_NEW)
       
  2496         self.Bind(wx.EVT_MENU, self.OnOpenProjectMenu, id=wx.ID_OPEN)
       
  2497         self.Bind(wx.EVT_MENU, self.OnCloseTabMenu, id=wx.ID_CLOSE)
       
  2498         self.Bind(wx.EVT_MENU, self.OnCloseProjectMenu, id=wx.ID_CLOSE_ALL)
       
  2499         self.Bind(wx.EVT_MENU, self.OnSaveProjectMenu, id=wx.ID_SAVE)
       
  2500         self.Bind(wx.EVT_MENU, self.OnSaveProjectAsMenu, id=wx.ID_SAVEAS)
       
  2501         self.Bind(wx.EVT_MENU, self.OnGenerateProgramMenu,
       
  2502               id=ID_PLCOPENEDITORFILEMENUGENERATE)
       
  2503         self.Bind(wx.EVT_MENU, self.OnPageSetupMenu, id=wx.ID_PAGE_SETUP)
       
  2504         self.Bind(wx.EVT_MENU, self.OnPreviewMenu, id=wx.ID_PREVIEW)
       
  2505         self.Bind(wx.EVT_MENU, self.OnPrintMenu, id=wx.ID_PRINT)
       
  2506         self.Bind(wx.EVT_MENU, self.OnPropertiesMenu, id=wx.ID_PROPERTIES)
       
  2507         self.Bind(wx.EVT_MENU, self.OnQuitMenu, id=wx.ID_EXIT)
       
  2508 
       
  2509     def _init_coll_HelpMenu_Items(self, parent):
       
  2510         AppendMenu(parent, help='', id=wx.ID_HELP, 
       
  2511             kind=wx.ITEM_NORMAL, text=_(u'PLCOpenEditor\tF1'))
       
  2512         #AppendMenu(parent, help='', id=wx.ID_HELP_CONTENTS,
       
  2513         #      kind=wx.ITEM_NORMAL, text=u'PLCOpen\tF2')
       
  2514         #AppendMenu(parent, help='', id=wx.ID_HELP_CONTEXT,
       
  2515         #      kind=wx.ITEM_NORMAL, text=u'IEC 61131-3\tF3')
       
  2516         AppendMenu(parent, help='', id=wx.ID_ABOUT,
       
  2517             kind=wx.ITEM_NORMAL, text=_(u'About'))
       
  2518         self.Bind(wx.EVT_MENU, self.OnPLCOpenEditorMenu, id=wx.ID_HELP)
       
  2519         #self.Bind(wx.EVT_MENU, self.OnPLCOpenMenu, id=wx.ID_HELP_CONTENTS)
       
  2520         self.Bind(wx.EVT_MENU, self.OnAboutMenu, id=wx.ID_ABOUT)
       
  2521 
       
  2522     ## Constructor of the PLCOpenEditor class.
       
  2523     #  @param parent The parent window.
       
  2524     #  @param controler The controler been used by PLCOpenEditor (default: None).
       
  2525     #  @param fileOpen The filepath to open if no controler defined (default: None).
       
  2526     #  @param debug The filepath to open if no controler defined (default: False).
       
  2527     def __init__(self, parent, fileOpen = None):
       
  2528         IDEFrame.__init__(self, parent)
       
  2529         
       
  2530         # Open the filepath if defined
       
  2531         if fileOpen is not None and os.path.isfile(fileOpen):
       
  2532             # Create a new controller
       
  2533             self.Controler = PLCControler()
       
  2534             self.Controler.OpenXMLFile(fileOpen)
       
  2535             self._Refresh(TYPESTREE, INSTANCESTREE, LIBRARYTREE)
       
  2536         
       
  2537         # Define PLCOpenEditor icon
       
  2538         self.SetIcon(wx.Icon(os.path.join(CWD,"Images", "poe.ico"),wx.BITMAP_TYPE_ICO))
       
  2539 
       
  2540         self.Bind(wx.EVT_CLOSE, self.OnCloseFrame)
       
  2541         
       
  2542         self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU)
       
  2543 
       
  2544     def OnCloseFrame(self, event):
       
  2545         if self.Controler is None or self.CheckSaveBeforeClosing():
       
  2546             if USE_AUI:
       
  2547                 self.AUIManager.UnInit()
       
  2548             event.Skip()
       
  2549         else:
       
  2550             event.Veto()
       
  2551 
       
  2552     def RefreshTitle(self):
       
  2553         name = _("PLCOpenEditor")
       
  2554         if self.Controler is not None:
       
  2555             self.SetTitle("%s - %s"%(name, self.Controler.GetFilename()))
       
  2556         else:
       
  2557             self.SetTitle(name)
       
  2558 
       
  2559 #-------------------------------------------------------------------------------
       
  2560 #                            File Menu Functions
       
  2561 #-------------------------------------------------------------------------------
       
  2562 
       
  2563     def RefreshFileMenu(self):
       
  2564         if self.Controler is not None:
       
  2565             selected = self.TabsOpened.GetSelection()
       
  2566             if selected >= 0:
       
  2567                 graphic_viewer = isinstance(self.TabsOpened.GetPage(selected), Viewer)
       
  2568             else:
       
  2569                 graphic_viewer = False
       
  2570             if self.TabsOpened.GetPageCount() > 0:
       
  2571                 self.FileMenu.Enable(wx.ID_CLOSE, True)
       
  2572                 if graphic_viewer:
       
  2573                     self.FileMenu.Enable(wx.ID_PREVIEW, True)
       
  2574                     self.FileMenu.Enable(wx.ID_PRINT, True)
       
  2575                 else:
       
  2576                     self.FileMenu.Enable(wx.ID_PREVIEW, False)
       
  2577                     self.FileMenu.Enable(wx.ID_PRINT, False)
       
  2578             else:
       
  2579                 self.FileMenu.Enable(wx.ID_CLOSE, False)
       
  2580                 self.FileMenu.Enable(wx.ID_PREVIEW, False)
       
  2581                 self.FileMenu.Enable(wx.ID_PRINT, False)
       
  2582             self.FileMenu.Enable(wx.ID_PAGE_SETUP, True)
       
  2583             self.FileMenu.Enable(wx.ID_SAVE, True)
       
  2584             self.FileMenu.Enable(wx.ID_PROPERTIES, True)
       
  2585             self.FileMenu.Enable(wx.ID_CLOSE_ALL, True)
       
  2586             self.FileMenu.Enable(wx.ID_SAVEAS, True)
       
  2587             self.FileMenu.Enable(ID_PLCOPENEDITORFILEMENUGENERATE, True)
       
  2588         else:
       
  2589             self.FileMenu.Enable(wx.ID_CLOSE, False)
       
  2590             self.FileMenu.Enable(wx.ID_PAGE_SETUP, False)
       
  2591             self.FileMenu.Enable(wx.ID_PREVIEW, False)
       
  2592             self.FileMenu.Enable(wx.ID_PRINT, False)
       
  2593             self.FileMenu.Enable(wx.ID_SAVE, False)
       
  2594             self.FileMenu.Enable(wx.ID_PROPERTIES, False)
       
  2595             self.FileMenu.Enable(wx.ID_CLOSE_ALL, False)
       
  2596             self.FileMenu.Enable(wx.ID_SAVEAS, False)
       
  2597             self.FileMenu.Enable(ID_PLCOPENEDITORFILEMENUGENERATE, False)
       
  2598 
       
  2599     def OnNewProjectMenu(self, event):
       
  2600         if self.Controler is not None and not self.CheckSaveBeforeClosing():
       
  2601             return
       
  2602         dialog = ProjectDialog(self)
       
  2603         if dialog.ShowModal() == wx.ID_OK:
       
  2604             properties = dialog.GetValues()
       
  2605             self.ResetView()
       
  2606             self.Controler = PLCControler()
       
  2607             self.Controler.CreateNewProject(properties)
       
  2608             self._Refresh(TITLE, FILEMENU, EDITMENU, TYPESTREE, INSTANCESTREE, 
       
  2609                           LIBRARYTREE)
       
  2610         event.Skip()
       
  2611 
       
  2612     def OnOpenProjectMenu(self, event):
       
  2613         if self.Controler is not None and not self.CheckSaveBeforeClosing():
       
  2614             return
       
  2615         filepath = ""
       
  2616         if self.Controler is not None:
       
  2617             filepath = self.Controler.GetFilePath()
       
  2618         if filepath != "":
       
  2619             directory = os.path.dirname(filepath)
       
  2620         else:
       
  2621             directory = os.getcwd()
       
  2622         dialog = wx.FileDialog(self, _("Choose a file"), directory, "",  _("PLCOpen files (*.xml)|*.xml|All files|*.*"), wx.OPEN)
       
  2623         if dialog.ShowModal() == wx.ID_OK:
       
  2624             filepath = dialog.GetPath()
       
  2625             if os.path.isfile(filepath):
       
  2626                 self.ResetView()
       
  2627                 self.Controler = PLCControler()
       
  2628                 self.Controler.OpenXMLFile(filepath)
       
  2629                 self._Refresh(TYPESTREE, INSTANCESTREE, LIBRARYTREE)
       
  2630             self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU)
       
  2631         dialog.Destroy()
       
  2632         event.Skip()
       
  2633     
       
  2634     def OnCloseProjectMenu(self, event):
       
  2635         if not self.CheckSaveBeforeClosing():
       
  2636             return
       
  2637         self.ResetView()
       
  2638         self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU)
       
  2639         event.Skip()
       
  2640 
       
  2641     def OnSaveProjectMenu(self, event):
       
  2642         self.SaveProject()
       
  2643         event.Skip()
       
  2644 
       
  2645     def OnSaveProjectAsMenu(self, event):
       
  2646         self.SaveProjectAs()
       
  2647         event.Skip()
       
  2648 
       
  2649     def OnGenerateProgramMenu(self, event):
       
  2650         dialog = wx.FileDialog(self, _("Choose a file"), os.getcwd(), self.Controler.GetProgramFilePath(),  _("ST files (*.st)|*.st|All files|*.*"), wx.SAVE|wx.CHANGE_DIR)
       
  2651         if dialog.ShowModal() == wx.ID_OK:
       
  2652             filepath = dialog.GetPath()
       
  2653             message_text = ""
       
  2654             header, icon = _("Done"), wx.ICON_INFORMATION
       
  2655             if os.path.isdir(os.path.dirname(filepath)):
       
  2656                 program, errors, warnings = self.Controler.GenerateProgram(filepath)
       
  2657                 message_text += "".join([_("warning: %s\n") for warning in warnings])
       
  2658                 if len(errors) > 0:
       
  2659                     message_text += "".join([_("error: %s\n") for warning in warnings])
       
  2660                     message_text += _("Can't generate program to file %s!")%filepath
       
  2661                     header, icon = _("Error"), wx.ICON_ERROR
       
  2662                 else:
       
  2663                     message_text += _("Program was successfully generated!")
       
  2664             else:
       
  2665                 message_text += _("\"%s\" is not a valid folder!")%os.path.dirname(filepath)
       
  2666                 header, icon = _("Error"), wx.ICON_ERROR
       
  2667             message = wx.MessageDialog(self, message_text, header, wx.OK|icon)
       
  2668             message.ShowModal()
       
  2669             message.Destroy()
       
  2670         dialog.Destroy()
       
  2671         event.Skip()
       
  2672 
       
  2673     def SaveProject(self):
       
  2674         result = self.Controler.SaveXMLFile()
       
  2675         if not result:
       
  2676             self.SaveProjectAs()
       
  2677         else:
       
  2678             self.RefreshTitle()
       
  2679     
       
  2680     def SaveProjectAs(self):
       
  2681         filepath = self.Controler.GetFilePath()
       
  2682         if filepath != "":
       
  2683             directory, filename = os.path.split(filepath)
       
  2684         else:
       
  2685             directory, filename = os.getcwd(), "%(projectName)s.xml"%self.Controler.GetProjectProperties()
       
  2686         dialog = wx.FileDialog(self, _("Choose a file"), directory, filename,  _("PLCOpen files (*.xml)|*.xml|All files|*.*"), wx.SAVE|wx.OVERWRITE_PROMPT)
       
  2687         if dialog.ShowModal() == wx.ID_OK:
       
  2688             filepath = dialog.GetPath()
       
  2689             if os.path.isdir(os.path.dirname(filepath)):
       
  2690                 result = self.Controler.SaveXMLFile(filepath)
       
  2691                 if not result:
       
  2692                     self.ShowErrorMessage(_("Can't save project to file %s!")%filepath)
       
  2693             else:
       
  2694                 self.ShowErrorMessage(_("\"%s\" is not a valid folder!")%os.path.dirname(filepath))
       
  2695             self.RefreshTitle()
       
  2696         dialog.Destroy()
       
  2697 
       
  2698 #-------------------------------------------------------------------------------
       
  2699 #                            Create Project Dialog
       
  2700 #-------------------------------------------------------------------------------
       
  2701 
       
  2702 [ID_SCALINGPANEL, ID_SCALINGPANELXSCALE, 
       
  2703  ID_SCALINGPANELYSCALE, ID_SCALINGPANELSTATICTEXT1, 
       
  2704  ID_SCALINGPANELSTATICTEXT2, 
       
  2705 ] = [wx.NewId() for _init_ctrls in range(5)]
       
  2706 
       
  2707 class ScalingPanel(wx.Panel):
       
  2708     
       
  2709     def _init_coll_ScalingPanelSizer_Items(self, parent):
       
  2710         parent.AddWindow(self.staticText1, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP|wx.LEFT)
       
  2711         parent.AddWindow(self.XScale, 0, border=10, flag=wx.GROW|wx.TOP|wx.RIGHT)
       
  2712         parent.AddWindow(self.staticText2, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.BOTTOM|wx.LEFT)
       
  2713         parent.AddWindow(self.YScale, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.RIGHT)
       
  2714 
       
  2715     def _init_coll_ScalingPanelSizer_Growables(self, parent):
       
  2716         parent.AddGrowableCol(1)
       
  2717 
       
  2718     def _init_sizers(self):
       
  2719         self.ScalingPanelSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=5)
       
  2720         
       
  2721         self._init_coll_ScalingPanelSizer_Items(self.ScalingPanelSizer)
       
  2722         self._init_coll_ScalingPanelSizer_Growables(self.ScalingPanelSizer)
       
  2723 
       
  2724         self.SetSizer(self.ScalingPanelSizer)
       
  2725 
       
  2726     def _init_ctrls(self, prnt):
       
  2727         wx.Panel.__init__(self, id=ID_SCALINGPANEL,
       
  2728               name='ScalingPanel', parent=prnt, pos=wx.Point(0, 0),
       
  2729               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
  2730         
       
  2731         self.staticText1 = wx.StaticText(id=ID_SCALINGPANELSTATICTEXT1,
       
  2732               label=_('X Scale:'), name='staticText1', parent=self,
       
  2733               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2734         
       
  2735         self.XScale = wx.SpinCtrl(id=ID_SCALINGPANELXSCALE,
       
  2736               name='XScale', parent=self, pos=wx.Point(0, 0),
       
  2737               size=wx.Size(0, 24), style=0, min=0, max=2**16)
       
  2738         
       
  2739         self.staticText2 = wx.StaticText(id=ID_SCALINGPANELSTATICTEXT2,
       
  2740               label=_('Y Scale:'), name='staticText2', parent=self,
       
  2741               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2742         
       
  2743         self.YScale = wx.SpinCtrl(id=ID_SCALINGPANELYSCALE,
       
  2744               name='YScale', parent=self, pos=wx.Point(0, 0),
       
  2745               size=wx.Size(0, 24), style=0, min=0, max=2**16)
       
  2746         
       
  2747         self._init_sizers()
       
  2748         
       
  2749     def __init__(self, parent):
       
  2750         self._init_ctrls(parent)
       
  2751 
       
  2752     def SetScaling(self, x, y):
       
  2753         self.XScale.SetValue(x)
       
  2754         self.YScale.SetValue(y)
       
  2755         
       
  2756     def GetScaling(self):
       
  2757         return self.XScale.GetValue(), self.YScale.GetValue()
       
  2758 
       
  2759 [ID_PROJECTDIALOG, ID_PROJECTDIALOGMAINNOTEBOOK, 
       
  2760  ID_PROJECTDIALOGPROJECTPANEL, ID_PROJECTDIALOGAUTHORPANEL, 
       
  2761  ID_PROJECTDIALOGGRAPHICSPANEL, ID_PROJECTDIALOGMISCELLANEOUSPANEL, 
       
  2762  ID_PROJECTDIALOGPROJECTNAME, ID_PROJECTDIALOGPROJECTVERSION, 
       
  2763  ID_PROJECTDIALOGPRODUCTNAME, ID_PROJECTDIALOGPRODUCTVERSION, 
       
  2764  ID_PROJECTDIALOGPRODUCTRELEASE, ID_PROJECTDIALOGCOMPANYNAME, 
       
  2765  ID_PROJECTDIALOGCOMPANYURL, ID_PROJECTDIALOGAUTHORNAME, 
       
  2766  ID_PROJECTDIALOGORGANIZATION, ID_PROJECTDIALOGLANGUAGE, 
       
  2767  ID_PROJECTDIALOGCONTENTDESCRIPTION, ID_PROJECTDIALOGSCALINGNOTEBOOK, 
       
  2768  ID_PROJECTDIALOGPAGEWIDTH, ID_PROJECTDIALOGPAGEHEIGHT, 
       
  2769  ID_PROJECTDIALOGSTATICTEXT1, ID_PROJECTDIALOGSTATICTEXT2, 
       
  2770  ID_PROJECTDIALOGSTATICTEXT3, ID_PROJECTDIALOGSTATICTEXT4, 
       
  2771  ID_PROJECTDIALOGSTATICTEXT5, ID_PROJECTDIALOGSTATICTEXT6, 
       
  2772  ID_PROJECTDIALOGSTATICTEXT7, ID_PROJECTDIALOGSTATICTEXT8, 
       
  2773  ID_PROJECTDIALOGSTATICTEXT9, ID_PROJECTDIALOGSTATICTEXT10, 
       
  2774  ID_PROJECTDIALOGSTATICTEXT11, ID_PROJECTDIALOGSTATICTEXT12, 
       
  2775  ID_PROJECTDIALOGSTATICTEXT13, ID_PROJECTDIALOGSTATICTEXT14, 
       
  2776  ID_PROJECTDIALOGSTATICTEXT15, 
       
  2777 ] = [wx.NewId() for _init_ctrls in range(35)]
       
  2778 
       
  2779 class ProjectDialog(wx.Dialog):
       
  2780     if wx.VERSION < (2, 6, 0):
       
  2781         def Bind(self, event, function, id = None):
       
  2782             if id is not None:
       
  2783                 event(self, id, function)
       
  2784             else:
       
  2785                 event(self, function)
       
  2786                 
       
  2787     def _init_coll_flexGridSizer1_Items(self, parent):
       
  2788         parent.AddSizer(self.MainNotebook, 0, border=0, flag=wx.GROW)
       
  2789         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
       
  2790         
       
  2791     def _init_coll_flexGridSizer1_Growables(self, parent):
       
  2792         parent.AddGrowableCol(0)
       
  2793         parent.AddGrowableRow(0)
       
  2794     
       
  2795     def _init_coll_ProjectPanelSizer_Items(self, parent):
       
  2796         parent.AddWindow(self.staticText1, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP|wx.LEFT)
       
  2797         parent.AddWindow(self.ProjectName, 0, border=10, flag=wx.GROW|wx.TOP|wx.RIGHT)
       
  2798         parent.AddWindow(self.staticText2, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT)
       
  2799         parent.AddWindow(self.ProjectVersion, 0, border=10, flag=wx.GROW|wx.RIGHT)
       
  2800         parent.AddWindow(self.staticText3, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT)
       
  2801         parent.AddWindow(self.ProductName, 0, border=10, flag=wx.GROW|wx.RIGHT)
       
  2802         parent.AddWindow(self.staticText4, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT)
       
  2803         parent.AddWindow(self.ProductVersion, 0, border=10, flag=wx.GROW|wx.RIGHT)
       
  2804         parent.AddWindow(self.staticText5, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.BOTTOM|wx.LEFT)
       
  2805         parent.AddWindow(self.ProductRelease, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.RIGHT)
       
  2806         
       
  2807     def _init_coll_ProjectPanelSizer_Growables(self, parent):
       
  2808         parent.AddGrowableCol(1)
       
  2809 
       
  2810     def _init_coll_AuthorPanelSizer_Items(self, parent):
       
  2811         parent.AddWindow(self.staticText6, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP|wx.LEFT)
       
  2812         parent.AddWindow(self.CompanyName, 0, border=10, flag=wx.GROW|wx.TOP|wx.RIGHT)
       
  2813         parent.AddWindow(self.staticText7, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT)
       
  2814         parent.AddWindow(self.CompanyURL, 0, border=10, flag=wx.GROW|wx.RIGHT)
       
  2815         parent.AddWindow(self.staticText8, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT)
       
  2816         parent.AddWindow(self.AuthorName, 0, border=10, flag=wx.GROW|wx.RIGHT)
       
  2817         parent.AddWindow(self.staticText9, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.BOTTOM|wx.LEFT)
       
  2818         parent.AddWindow(self.Organization, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.RIGHT)
       
  2819     
       
  2820     def _init_coll_AuthorPanelSizer_Growables(self, parent):
       
  2821         parent.AddGrowableCol(1)
       
  2822     
       
  2823     def _init_coll_GraphicsPanelSizer_Items(self, parent):
       
  2824         parent.AddWindow(self.staticText12, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP|wx.LEFT|wx.RIGHT)
       
  2825         parent.AddSizer(self.GraphicsPageSizeSizer, 0, border=10, flag=wx.GROW|wx.LEFT|wx.RIGHT)
       
  2826         parent.AddWindow(self.staticText15, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT)
       
  2827         parent.AddWindow(self.ScalingNotebook, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.LEFT|wx.RIGHT)
       
  2828         
       
  2829     def _init_coll_GraphicsPanelSizer_Growables(self, parent):
       
  2830         parent.AddGrowableCol(0)
       
  2831         parent.AddGrowableRow(3)
       
  2832     
       
  2833     def _init_coll_GraphicsPageSizeSizer_Items(self, parent):
       
  2834         parent.AddWindow(self.staticText13, 0, border=12, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT)
       
  2835         parent.AddWindow(self.PageWidth, 0, border=0, flag=wx.GROW)
       
  2836         parent.AddWindow(self.staticText14, 0, border=12, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT)
       
  2837         parent.AddWindow(self.PageHeight, 0, border=0, flag=wx.GROW)
       
  2838     
       
  2839     def _init_coll_GraphicsPageSizeSizer_Growables(self, parent):
       
  2840         parent.AddGrowableCol(1)
       
  2841     
       
  2842     def _init_coll_MiscellaneousPanelSizer_Items(self, parent):
       
  2843         parent.AddWindow(self.staticText10, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP|wx.LEFT)
       
  2844         parent.AddWindow(self.Language, 0, border=10, flag=wx.GROW|wx.TOP|wx.RIGHT)
       
  2845         parent.AddWindow(self.staticText11, 0, border=10, flag=wx.BOTTOM|wx.LEFT)
       
  2846         parent.AddWindow(self.ContentDescription, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.RIGHT)
       
  2847         
       
  2848     def _init_coll_MiscellaneousPanelSizer_Growables(self, parent):
       
  2849         parent.AddGrowableCol(1)
       
  2850         parent.AddGrowableRow(1)
       
  2851         
       
  2852     def _init_sizers(self):
       
  2853         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
       
  2854         self.ProjectPanelSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=5, vgap=15)
       
  2855         self.AuthorPanelSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=4, vgap=15)
       
  2856         self.GraphicsPanelSizer = wx.FlexGridSizer(cols=1, hgap=5, rows=4, vgap=5)
       
  2857         self.GraphicsPageSizeSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=5)
       
  2858         self.MiscellaneousPanelSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=15)
       
  2859 
       
  2860         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
  2861         self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1)
       
  2862         self._init_coll_ProjectPanelSizer_Items(self.ProjectPanelSizer)
       
  2863         self._init_coll_ProjectPanelSizer_Growables(self.ProjectPanelSizer)
       
  2864         self._init_coll_AuthorPanelSizer_Items(self.AuthorPanelSizer)
       
  2865         self._init_coll_AuthorPanelSizer_Growables(self.AuthorPanelSizer)
       
  2866         self._init_coll_GraphicsPanelSizer_Items(self.GraphicsPanelSizer)
       
  2867         self._init_coll_GraphicsPanelSizer_Growables(self.GraphicsPanelSizer)
       
  2868         self._init_coll_GraphicsPageSizeSizer_Items(self.GraphicsPageSizeSizer)
       
  2869         self._init_coll_GraphicsPageSizeSizer_Growables(self.GraphicsPageSizeSizer)
       
  2870         self._init_coll_MiscellaneousPanelSizer_Items(self.MiscellaneousPanelSizer)
       
  2871         self._init_coll_MiscellaneousPanelSizer_Growables(self.MiscellaneousPanelSizer)
       
  2872 
       
  2873         self.SetSizer(self.flexGridSizer1)
       
  2874         self.ProjectPanel.SetSizer(self.ProjectPanelSizer)
       
  2875         self.AuthorPanel.SetSizer(self.AuthorPanelSizer)
       
  2876         self.GraphicsPanel.SetSizer(self.GraphicsPanelSizer)
       
  2877         self.MiscellaneousPanel.SetSizer(self.MiscellaneousPanelSizer)
       
  2878 
       
  2879     def _init_ctrls(self, prnt):
       
  2880         wx.Dialog.__init__(self, id=ID_PROJECTDIALOG,
       
  2881               name='ProjectDialog', parent=prnt, pos=wx.Point(376, 223),
       
  2882               size=wx.Size(500, 350), style=wx.DEFAULT_DIALOG_STYLE,
       
  2883               title=_('Project properties'))
       
  2884         self.SetClientSize(wx.Size(500, 350))
       
  2885 
       
  2886         self.MainNotebook = wx.Notebook(id=ID_PROJECTDIALOGMAINNOTEBOOK,
       
  2887                   name='MainNotebook', parent=self, pos=wx.Point(0,
       
  2888                   0), size=wx.Size(0, 0), style=0)
       
  2889 
       
  2890         # Project Panel elements
       
  2891 
       
  2892         self.ProjectPanel = wx.Panel(id=ID_PROJECTDIALOGPROJECTPANEL,
       
  2893               name='ProjectPanel', parent=self.MainNotebook, pos=wx.Point(0, 0),
       
  2894               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
  2895 
       
  2896         self.staticText1 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT1,
       
  2897               label=_('Project Name (required):'), name='staticText1', parent=self.ProjectPanel,
       
  2898               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2899 
       
  2900         self.ProjectName = wx.TextCtrl(id=ID_PROJECTDIALOGPROJECTNAME,
       
  2901               name='ProjectName', parent=self.ProjectPanel, pos=wx.Point(0, 0), 
       
  2902               size=wx.Size(0, 24), style=0)
       
  2903 
       
  2904         self.staticText2 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT2,
       
  2905               label=_('Project Version (optional):'), name='staticText2', parent=self.ProjectPanel,
       
  2906               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2907 
       
  2908         self.ProjectVersion = wx.TextCtrl(id=ID_PROJECTDIALOGPROJECTVERSION,
       
  2909               name='ProjectVersion', parent=self.ProjectPanel, pos=wx.Point(0, 0), 
       
  2910               size=wx.Size(0, 24), style=0)
       
  2911 
       
  2912         self.staticText3 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT3,
       
  2913               label=_('Product Name (required):'), name='staticText3', parent=self.ProjectPanel,
       
  2914               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2915 
       
  2916         self.ProductName = wx.TextCtrl(id=ID_PROJECTDIALOGPRODUCTNAME,
       
  2917               name='ProductName', parent=self.ProjectPanel, pos=wx.Point(0, 0),
       
  2918               size=wx.Size(0, 24), style=0)
       
  2919 
       
  2920         self.staticText4 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT4,
       
  2921               label=_('Product Version (required):'), name='staticText4', parent=self.ProjectPanel,
       
  2922               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2923 
       
  2924         self.ProductVersion = wx.TextCtrl(id=ID_PROJECTDIALOGPRODUCTVERSION,
       
  2925               name='ProductVersion', parent=self.ProjectPanel, pos=wx.Point(0, 0),
       
  2926               size=wx.Size(0, 24), style=0)
       
  2927 
       
  2928         self.staticText5 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT5,
       
  2929               label=_('Product Release (optional):'), name='staticText5', parent=self.ProjectPanel,
       
  2930               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2931 
       
  2932         self.ProductRelease = wx.TextCtrl(id=ID_PROJECTDIALOGPRODUCTRELEASE,
       
  2933               name='ProductRelease', parent=self.ProjectPanel, pos=wx.Point(0, 0),
       
  2934               size=wx.Size(0, 24), style=0)
       
  2935 
       
  2936         self.MainNotebook.AddPage(self.ProjectPanel, _("Project"))
       
  2937         
       
  2938         # Author Panel elements
       
  2939 
       
  2940         self.AuthorPanel = wx.Panel(id=ID_PROJECTDIALOGAUTHORPANEL,
       
  2941               name='AuthorPanel', parent=self.MainNotebook, pos=wx.Point(0, 0),
       
  2942               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
  2943 
       
  2944         self.staticText6 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT6,
       
  2945               label=_('Company Name (required):'), name='staticText6', parent=self.AuthorPanel,
       
  2946               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2947 
       
  2948         self.CompanyName = wx.TextCtrl(id=ID_PROJECTDIALOGCOMPANYNAME,
       
  2949               name='CompanyName', parent=self.AuthorPanel, pos=wx.Point(0, 0),
       
  2950               size=wx.Size(0, 24), style=0)
       
  2951 
       
  2952         self.staticText7 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT7,
       
  2953               label=_('Company URL (optional):'), name='staticText7', parent=self.AuthorPanel,
       
  2954               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2955 
       
  2956         self.CompanyURL = wx.TextCtrl(id=ID_PROJECTDIALOGCOMPANYURL,
       
  2957               name='CompanyURL', parent=self.AuthorPanel, pos=wx.Point(0, 0),
       
  2958               size=wx.Size(0, 24), style=0)
       
  2959 
       
  2960         self.staticText8 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT8,
       
  2961               label=_('Author Name (optional):'), name='staticText8', parent=self.AuthorPanel,
       
  2962               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2963 
       
  2964         self.AuthorName = wx.TextCtrl(id=ID_PROJECTDIALOGAUTHORNAME,
       
  2965               name='AuthorName', parent=self.AuthorPanel, pos=wx.Point(0, 0),
       
  2966               size=wx.Size(0, 24), style=0)
       
  2967 
       
  2968         self.staticText9 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT9,
       
  2969               label=_('Organization (optional):'), name='staticText9', parent=self.AuthorPanel,
       
  2970               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2971 
       
  2972         self.Organization = wx.TextCtrl(id=ID_PROJECTDIALOGORGANIZATION,
       
  2973               name='Organization', parent=self.AuthorPanel, pos=wx.Point(0, 0),
       
  2974               size=wx.Size(0, 24), style=0)
       
  2975 
       
  2976         self.MainNotebook.AddPage(self.AuthorPanel, _("Author"))
       
  2977 
       
  2978         # Graphics Panel elements
       
  2979 
       
  2980         self.GraphicsPanel = wx.Panel(id=ID_PROJECTDIALOGGRAPHICSPANEL,
       
  2981               name='GraphicsPanel', parent=self.MainNotebook, pos=wx.Point(0, 0),
       
  2982               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
  2983 
       
  2984         self.staticText12 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT12,
       
  2985               label=_('Page Size (optional):'), name='staticText12', parent=self.GraphicsPanel,
       
  2986               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2987 
       
  2988         self.staticText13 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT13,
       
  2989               label=_('Width:'), name='staticText13', parent=self.GraphicsPanel,
       
  2990               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2991         
       
  2992         self.PageWidth = wx.SpinCtrl(id=ID_PROJECTDIALOGPAGEWIDTH,
       
  2993               name='PageWidth', parent=self.GraphicsPanel, pos=wx.Point(0, 0),
       
  2994               size=wx.Size(0, 24), style=0, min=0, max=2**16)
       
  2995 
       
  2996         self.staticText14 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT14,
       
  2997               label=_('Height:'), name='staticText14', parent=self.GraphicsPanel,
       
  2998               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  2999         
       
  3000         self.PageHeight = wx.SpinCtrl(id=ID_PROJECTDIALOGPAGEHEIGHT,
       
  3001               name='PageHeight', parent=self.GraphicsPanel, pos=wx.Point(0, 0),
       
  3002               size=wx.Size(0, 24), style=0, min=0, max=2**16)
       
  3003         
       
  3004         self.staticText15 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT15,
       
  3005               label=_('Scaling:'), name='staticText15', parent=self.GraphicsPanel,
       
  3006               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  3007         
       
  3008         self.ScalingNotebook = wx.Notebook(id=ID_PROJECTDIALOGSCALINGNOTEBOOK,
       
  3009               name='ScalingNotebook', parent=self.GraphicsPanel, pos=wx.Point(0,
       
  3010               0), size=wx.Size(0, 0), style=0)
       
  3011         
       
  3012         self.Scalings = {}
       
  3013         for language, translation in [("FBD",_("FBD")), ("LD",_("LD")), ("SFC",_("SFC"))]:
       
  3014             window = ScalingPanel(self.ScalingNotebook)
       
  3015             self.Scalings[language] = window
       
  3016             self.ScalingNotebook.AddPage(window, translation)
       
  3017         
       
  3018         self.MainNotebook.AddPage(self.GraphicsPanel, _("Graphics"))
       
  3019 
       
  3020         # Miscellaneous Panel elements
       
  3021 
       
  3022         self.MiscellaneousPanel = wx.Panel(id=ID_PROJECTDIALOGMISCELLANEOUSPANEL,
       
  3023               name='MiscellaneousPanel', parent=self.MainNotebook, pos=wx.Point(0, 0),
       
  3024               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
  3025 
       
  3026         self.staticText10 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT10,
       
  3027               label=_('Language (optional):'), name='staticText10', parent=self.MiscellaneousPanel,
       
  3028               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  3029 
       
  3030         self.Language = wx.ComboBox(id=ID_PROJECTDIALOGLANGUAGE,
       
  3031               name='Language', parent=self.MiscellaneousPanel, pos=wx.Point(0, 0),
       
  3032               size=wx.Size(0, 28), style=wx.CB_READONLY)
       
  3033 
       
  3034         self.staticText11 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT11,
       
  3035               label=_('Content Description (optional):'), name='staticText11', parent=self.MiscellaneousPanel,
       
  3036               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  3037 
       
  3038         self.ContentDescription = wx.TextCtrl(id=ID_PROJECTDIALOGCONTENTDESCRIPTION,
       
  3039               name='ContentDescription', parent=self.MiscellaneousPanel, pos=wx.Point(0, 0),
       
  3040               size=wx.Size(0, 24), style=wx.TE_MULTILINE)
       
  3041 
       
  3042         self.MainNotebook.AddPage(self.MiscellaneousPanel, _("Miscellaneous"))
       
  3043 
       
  3044         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
       
  3045         self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())
       
  3046         
       
  3047         self._init_sizers()
       
  3048 
       
  3049     def __init__(self, parent):
       
  3050         self._init_ctrls(parent)
       
  3051         
       
  3052         languages = ["", "en-US", "fr-FR", "zh-CN"]
       
  3053         
       
  3054         for language in languages:
       
  3055             self.Language.Append(language)
       
  3056         
       
  3057     def OnOK(self, event):
       
  3058         error = []
       
  3059         if self.ProjectName.GetValue() == "":
       
  3060             error.append("Project Name")
       
  3061         if self.CompanyName.GetValue() == "":
       
  3062             error.append("Company Name")
       
  3063         if self.ProductName.GetValue() == "":
       
  3064             error.append("Product Name")
       
  3065         if self.ProductVersion.GetValue() == "":
       
  3066             error.append("Product Version")
       
  3067         if len(error) > 0:
       
  3068             text = ""
       
  3069             for i, item in enumerate(error):
       
  3070                 if i == 0:
       
  3071                     text += item
       
  3072                 elif i == len(error) - 1:
       
  3073                     text += " and %s"%item
       
  3074                 else:
       
  3075                     text += ", %s"%item
       
  3076             message = wx.MessageDialog(self, _("Form isn't complete. %s must be filled!")%text, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3077             message.ShowModal()
       
  3078             message.Destroy()
       
  3079         else:
       
  3080             self.EndModal(wx.ID_OK)
       
  3081 
       
  3082     def SetValues(self, values):
       
  3083         for item, value in values.items():
       
  3084             if item == "projectName":
       
  3085                 self.ProjectName.SetValue(value)
       
  3086             elif item == "projectVersion":
       
  3087                 self.ProjectVersion.SetValue(value)
       
  3088             elif item == "productName":
       
  3089                 self.ProductName.SetValue(value)
       
  3090             elif item == "productVersion":
       
  3091                 self.ProductVersion.SetValue(value)
       
  3092             elif item == "productRelease":
       
  3093                 self.ProductRelease.SetValue(value)
       
  3094             elif item == "companyName":
       
  3095                 self.CompanyName.SetValue(value)
       
  3096             elif item == "companyURL":
       
  3097                 self.CompanyURL.SetValue(value)
       
  3098             elif item == "authorName":
       
  3099                 self.AuthorName.SetValue(value)
       
  3100             elif item == "organization":
       
  3101                 self.Organization.SetValue(value)
       
  3102             elif item == "language":
       
  3103                 self.Language.SetStringSelection(value)
       
  3104             elif item == "contentDescription":
       
  3105                 self.ContentDescription.SetValue(value)
       
  3106             elif item == "pageSize":
       
  3107                 self.PageWidth.SetValue(value[0])
       
  3108                 self.PageHeight.SetValue(value[1])
       
  3109             elif item == "scaling":
       
  3110                 for language, (x, y) in value.items():
       
  3111                     if language in self.Scalings:
       
  3112                         self.Scalings[language].SetScaling(x, y)
       
  3113     
       
  3114     def GetValues(self):
       
  3115         values = {}
       
  3116         values["projectName"] = self.ProjectName.GetValue()
       
  3117         if self.ProjectVersion.GetValue() != "":
       
  3118             values["projectVersion"] = self.ProjectVersion.GetValue()
       
  3119         values["productName"] = self.ProductName.GetValue()
       
  3120         values["productVersion"] = self.ProductVersion.GetValue()
       
  3121         if self.ProductRelease.GetValue() != "":
       
  3122             values["productRelease"] = self.ProductRelease.GetValue()
       
  3123         values["companyName"] = self.CompanyName.GetValue()
       
  3124         if self.CompanyURL.GetValue() != "":
       
  3125             values["companyURL"] = self.CompanyURL.GetValue()
       
  3126         if self.AuthorName.GetValue() != "":
       
  3127             values["authorName"] = self.AuthorName.GetValue()
       
  3128         if self.Organization.GetValue() != "":
       
  3129             values["organization"] = self.Organization.GetValue()
       
  3130         if self.Language.GetStringSelection() != "":
       
  3131             values["language"] = self.Language.GetStringSelection()
       
  3132         if self.ProductRelease.GetValue() != "":
       
  3133             values["contentDescription"] = self.ContentDescription.GetValue()
       
  3134         values["pageSize"] = (self.PageWidth.GetValue(), self.PageHeight.GetValue())
       
  3135         values["scaling"] = {}
       
  3136         for language in ["FBD", "LD", "SFC"]:
       
  3137             values["scaling"][language] = self.Scalings[language].GetScaling()
       
  3138         return values
       
  3139 
       
  3140 #-------------------------------------------------------------------------------
       
  3141 #                          Edit Step Name Dialog
       
  3142 #-------------------------------------------------------------------------------
       
  3143 
       
  3144 class DataTypeDialog(wx.TextEntryDialog):
       
  3145 
       
  3146     if wx.VERSION < (2, 6, 0):
       
  3147         def Bind(self, event, function, id = None):
       
  3148             if id is not None:
       
  3149                 event(self, id, function)
       
  3150             else:
       
  3151                 event(self, function)
       
  3152     
       
  3153     def __init__(self, parent, message, caption = _("Please enter text"), defaultValue = "", 
       
  3154                        style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition):
       
  3155         wx.TextEntryDialog.__init__(self, parent, message, caption, defaultValue, style, pos)
       
  3156         
       
  3157         self.DataTypeNames = []
       
  3158         if wx.VERSION >= (2, 8, 0):
       
  3159             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(2).GetSizer().GetItem(1).GetSizer().GetAffirmativeButton().GetId())
       
  3160         elif wx.VERSION >= (2, 6, 0):
       
  3161             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetAffirmativeButton().GetId())
       
  3162         else:
       
  3163             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId())
       
  3164     
       
  3165     def OnOK(self, event):
       
  3166         datatype_name = self.GetSizer().GetItem(1).GetWindow().GetValue()
       
  3167         if datatype_name == "":
       
  3168             message = wx.MessageDialog(self, _("You must type a name!"), _("Error"), wx.OK|wx.ICON_ERROR)
       
  3169             message.ShowModal()
       
  3170             message.Destroy()
       
  3171         elif not TestIdentifier(datatype_name):
       
  3172             message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%datatype_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3173             message.ShowModal()
       
  3174             message.Destroy()
       
  3175         elif datatype_name.upper() in IEC_KEYWORDS:
       
  3176             message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%datatype_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3177             message.ShowModal()
       
  3178             message.Destroy()
       
  3179         elif datatype_name.upper() in self.DataTypeNames:
       
  3180             message = wx.MessageDialog(self, _("\"%s\" data type already exists!")%datatype_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3181             message.ShowModal()
       
  3182             message.Destroy()
       
  3183         else:
       
  3184             self.EndModal(wx.ID_OK)
       
  3185 
       
  3186     def SetDataTypeNames(self, datatype_names):
       
  3187         self.DataTypeNames = [datatype_name.upper() for datatype_name in datatype_names]
       
  3188 
       
  3189     def GetValue(self):
       
  3190         return self.GetSizer().GetItem(1).GetWindow().GetValue()
       
  3191 
       
  3192 #-------------------------------------------------------------------------------
       
  3193 #                            Create Pou Dialog
       
  3194 #-------------------------------------------------------------------------------
       
  3195 
       
  3196 [ID_POUDIALOG, ID_POUDIALOGPOUNAME, 
       
  3197  ID_POUDIALOGPOUTYPE, ID_POUDIALOGLANGUAGE, ID_POUDIALOGSTATICTEXT1,
       
  3198  ID_POUDIALOGSTATICTEXT2, ID_POUDIALOGSTATICTEXT3, 
       
  3199 ] = [wx.NewId() for _init_ctrls in range(7)]
       
  3200 
       
  3201 def GetTransitionLanguages():
       
  3202     _ = lambda x : x
       
  3203     return [_("IL"), _("ST"), _("LD"), _("FBD")]
       
  3204 TRANSITION_LANGUAGES_DICT = dict([(_(language), language) for language in GetTransitionLanguages()])
       
  3205 
       
  3206 def GetPouTypes():
       
  3207     _ = lambda x : x
       
  3208     return [_("function"), _("functionBlock"), _("program")]
       
  3209 POU_TYPES_DICT = dict([(_(pou_type), pou_type) for pou_type in GetPouTypes()])
       
  3210 
       
  3211 def GetPouLanguages():
       
  3212     _ = lambda x : x
       
  3213     return [_("IL"), _("ST"), _("LD"), _("FBD"), _("SFC")]
       
  3214 POU_LANGUAGES_DICT = dict([(_(language), language) for language in GetPouLanguages()])
       
  3215 
       
  3216 class PouDialog(wx.Dialog):
       
  3217     if wx.VERSION < (2, 6, 0):
       
  3218         def Bind(self, event, function, id = None):
       
  3219             if id is not None:
       
  3220                 event(self, id, function)
       
  3221             else:
       
  3222                 event(self, function)
       
  3223     
       
  3224     def _init_coll_flexGridSizer1_Items(self, parent):
       
  3225         parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
       
  3226         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
       
  3227         
       
  3228     def _init_coll_flexGridSizer1_Growables(self, parent):
       
  3229         parent.AddGrowableCol(0)
       
  3230         parent.AddGrowableRow(0)
       
  3231     
       
  3232     def _init_coll_MainSizer_Items(self, parent):
       
  3233         parent.AddWindow(self.staticText1, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP)
       
  3234         parent.AddWindow(self.PouName, 0, border=0, flag=wx.GROW)
       
  3235         parent.AddWindow(self.staticText2, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP)
       
  3236         parent.AddWindow(self.PouType, 0, border=0, flag=wx.GROW)
       
  3237         parent.AddWindow(self.staticText3, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP)
       
  3238         parent.AddWindow(self.Language, 0, border=0, flag=wx.GROW)
       
  3239         
       
  3240     def _init_coll_MainSizer_Growables(self, parent):
       
  3241         parent.AddGrowableCol(1)
       
  3242         
       
  3243     def _init_sizers(self):
       
  3244         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
       
  3245         self.MainSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=3, vgap=15)
       
  3246 
       
  3247         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
  3248         self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1)
       
  3249         self._init_coll_MainSizer_Items(self.MainSizer)
       
  3250         self._init_coll_MainSizer_Growables(self.MainSizer)
       
  3251 
       
  3252         self.SetSizer(self.flexGridSizer1)
       
  3253         
       
  3254     def _init_ctrls(self, prnt):
       
  3255         wx.Dialog.__init__(self, id=ID_POUDIALOG,
       
  3256               name='PouDialog', parent=prnt, pos=wx.Point(376, 223),
       
  3257               size=wx.Size(300, 200), style=wx.DEFAULT_DIALOG_STYLE,
       
  3258               title=_('Create a new POU'))
       
  3259         self.SetClientSize(wx.Size(300, 200))
       
  3260 
       
  3261         self.staticText1 = wx.StaticText(id=ID_POUDIALOGSTATICTEXT1,
       
  3262               label=_('POU Name:'), name='staticText1', parent=self,
       
  3263               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  3264 
       
  3265         self.PouName = wx.TextCtrl(id=ID_POUDIALOGPOUNAME,
       
  3266               name='POUName', parent=self, pos=wx.Point(0, 0), 
       
  3267               size=wx.Size(0, 24), style=0)
       
  3268 
       
  3269         self.staticText2 = wx.StaticText(id=ID_POUDIALOGSTATICTEXT2,
       
  3270               label=_('POU Type:'), name='staticText2', parent=self,
       
  3271               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  3272 
       
  3273         self.PouType = wx.ComboBox(id=ID_POUDIALOGPOUTYPE,
       
  3274               name='POUType', parent=self, pos=wx.Point(0, 0),
       
  3275               size=wx.Size(0, 28), style=wx.CB_READONLY)
       
  3276         self.Bind(wx.EVT_COMBOBOX, self.OnTypeChanged, id=ID_POUDIALOGPOUTYPE)
       
  3277 
       
  3278         self.staticText3 = wx.StaticText(id=ID_POUDIALOGSTATICTEXT3,
       
  3279               label=_('Language:'), name='staticText3', parent=self,
       
  3280               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  3281 
       
  3282         self.Language = wx.ComboBox(id=ID_POUDIALOGLANGUAGE,
       
  3283               name='Language', parent=self, pos=wx.Point(0, 0),
       
  3284               size=wx.Size(0, 28), style=wx.CB_READONLY)
       
  3285         
       
  3286         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
       
  3287         self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())
       
  3288             
       
  3289         self._init_sizers()
       
  3290 
       
  3291     def __init__(self, parent, pou_type = None):
       
  3292         self._init_ctrls(parent)
       
  3293         
       
  3294         for option in GetPouTypes():
       
  3295             self.PouType.Append(_(option))
       
  3296         if pou_type is not None:
       
  3297             self.PouType.SetStringSelection(_(pou_type))
       
  3298         self.RefreshLanguage()
       
  3299 
       
  3300         self.PouNames = []
       
  3301         self.PouElementNames = []
       
  3302 
       
  3303     def OnOK(self, event):
       
  3304         error = []
       
  3305         pou_name = self.PouName.GetValue()
       
  3306         if pou_name == "":
       
  3307             error.append(_("POU Name"))
       
  3308         if self.PouType.GetSelection() == -1:
       
  3309             error.append(_("POU Type"))
       
  3310         if self.Language.GetSelection() == -1:
       
  3311             error.append(_("Language"))
       
  3312         if len(error) > 0:
       
  3313             text = ""
       
  3314             for i, item in enumerate(error):
       
  3315                 if i == 0:
       
  3316                     text += item
       
  3317                 elif i == len(error) - 1:
       
  3318                     text += _(" and %s")%item
       
  3319                 else:
       
  3320                     text += _(", %s")%item 
       
  3321             message = wx.MessageDialog(self, _("Form isn't complete. %s must be filled!")%text, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3322             message.ShowModal()
       
  3323             message.Destroy()
       
  3324         elif not TestIdentifier(pou_name):
       
  3325             message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%pou_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3326             message.ShowModal()
       
  3327             message.Destroy()
       
  3328         elif pou_name.upper() in IEC_KEYWORDS:
       
  3329             message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%pou_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3330             message.ShowModal()
       
  3331             message.Destroy()
       
  3332         elif pou_name.upper() in self.PouNames:
       
  3333             message = wx.MessageDialog(self, _("\"%s\" pou already exists!")%pou_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3334             message.ShowModal()
       
  3335             message.Destroy()
       
  3336         elif pou_name.upper() in self.PouElementNames:
       
  3337             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)
       
  3338             result = message.ShowModal()
       
  3339             message.Destroy()
       
  3340             if result == wx.ID_YES:
       
  3341                 self.EndModal(wx.ID_OK)
       
  3342         else:
       
  3343             self.EndModal(wx.ID_OK)
       
  3344 
       
  3345     def RefreshLanguage(self):
       
  3346         selection = POU_LANGUAGES_DICT.get(self.Language.GetStringSelection(), "")
       
  3347         self.Language.Clear()
       
  3348         for language in GetPouLanguages():
       
  3349             if language != "SFC" or POU_TYPES_DICT[self.PouType.GetStringSelection()] != "function":
       
  3350                 self.Language.Append(language)
       
  3351         if self.Language.FindString(_(selection)) != wx.NOT_FOUND:
       
  3352             self.Language.SetStringSelection(_(selection))
       
  3353 
       
  3354     def OnTypeChanged(self, event):
       
  3355         self.RefreshLanguage()
       
  3356         event.Skip()
       
  3357 
       
  3358     def SetPouNames(self, pou_names):
       
  3359         self.PouNames = [pou_name.upper() for pou_name in pou_names]
       
  3360 
       
  3361     def SetPouElementNames(self, element_names):
       
  3362         self.PouElementNames = [element_name.upper() for element_name in element_names]
       
  3363 
       
  3364     def SetValues(self, values):
       
  3365         for item, value in values.items():
       
  3366             if item == "pouName":
       
  3367                 self.PouName.SetValue(value)
       
  3368             elif item == "pouType":
       
  3369                 self.PouType.SetStringSelection(_(value))
       
  3370             elif item == "language":
       
  3371                 self.Language.SetStringSelection(_(POU_LANGUAGES_DICT))
       
  3372                 
       
  3373     def GetValues(self):
       
  3374         values = {}
       
  3375         values["pouName"] = self.PouName.GetValue()
       
  3376         values["pouType"] = POU_TYPES_DICT[self.PouType.GetStringSelection()]
       
  3377         values["language"] = POU_LANGUAGES_DICT[self.Language.GetStringSelection()]
       
  3378         return values
       
  3379 
       
  3380 
       
  3381 #-------------------------------------------------------------------------------
       
  3382 #                          Create Pou Transition Dialog
       
  3383 #-------------------------------------------------------------------------------
       
  3384 
       
  3385 [ID_POUTRANSITIONDIALOG, ID_POUTRANSITIONDIALOGTRANSITIONNAME, 
       
  3386  ID_POUTRANSITIONDIALOGLANGUAGE, ID_POUTRANSITIONDIALOGSTATICTEXT1, 
       
  3387  ID_POUTRANSITIONDIALOGSTATICTEXT2,
       
  3388 ] = [wx.NewId() for _init_ctrls in range(5)]
       
  3389 
       
  3390 def GetTransitionLanguages():
       
  3391     _ = lambda x : x
       
  3392     return [_("IL"), _("ST"), _("LD"), _("FBD")]
       
  3393 TRANSITION_LANGUAGES_DICT = dict([(_(language), language) for language in GetTransitionLanguages()])
       
  3394 
       
  3395 class PouTransitionDialog(wx.Dialog):
       
  3396     if wx.VERSION < (2, 6, 0):
       
  3397         def Bind(self, event, function, id = None):
       
  3398             if id is not None:
       
  3399                 event(self, id, function)
       
  3400             else:
       
  3401                 event(self, function)
       
  3402     
       
  3403     def _init_coll_flexGridSizer1_Items(self, parent):
       
  3404         parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
       
  3405         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
       
  3406         
       
  3407     def _init_coll_flexGridSizer1_Growables(self, parent):
       
  3408         parent.AddGrowableCol(0)
       
  3409         parent.AddGrowableRow(0)
       
  3410     
       
  3411     def _init_coll_MainSizer_Items(self, parent):
       
  3412         parent.AddWindow(self.staticText1, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP)
       
  3413         parent.AddWindow(self.TransitionName, 0, border=0, flag=wx.GROW)
       
  3414         parent.AddWindow(self.staticText2, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP)
       
  3415         parent.AddWindow(self.Language, 0, border=0, flag=wx.GROW)
       
  3416         
       
  3417     def _init_coll_MainSizer_Growables(self, parent):
       
  3418         parent.AddGrowableCol(1)
       
  3419         
       
  3420     def _init_sizers(self):
       
  3421         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
       
  3422         self.MainSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=15)
       
  3423 
       
  3424         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
  3425         self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1)
       
  3426         self._init_coll_MainSizer_Items(self.MainSizer)
       
  3427         self._init_coll_MainSizer_Growables(self.MainSizer)
       
  3428 
       
  3429         self.SetSizer(self.flexGridSizer1)
       
  3430 
       
  3431     def _init_ctrls(self, prnt):
       
  3432         wx.Dialog.__init__(self, id=ID_POUTRANSITIONDIALOG,
       
  3433               name='PouTransitionDialog', parent=prnt, pos=wx.Point(376, 223),
       
  3434               size=wx.Size(350, 200), style=wx.DEFAULT_DIALOG_STYLE,
       
  3435               title=_('Create a new transition'))
       
  3436         self.SetClientSize(wx.Size(350, 160))
       
  3437 
       
  3438         self.staticText1 = wx.StaticText(id=ID_POUTRANSITIONDIALOGSTATICTEXT1,
       
  3439               label=_('Transition Name:'), name='staticText1', parent=self,
       
  3440               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  3441 
       
  3442         self.TransitionName = wx.TextCtrl(id=ID_POUTRANSITIONDIALOGTRANSITIONNAME,
       
  3443               name='TransitionName', parent=self, pos=wx.Point(0, 0),
       
  3444               size=wx.Size(0, 24), style=0)
       
  3445 
       
  3446         self.staticText2 = wx.StaticText(id=ID_POUTRANSITIONDIALOGSTATICTEXT2,
       
  3447               label=_('Language:'), name='staticText2', parent=self,
       
  3448               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  3449 
       
  3450         self.Language = wx.ComboBox(id=ID_POUTRANSITIONDIALOGLANGUAGE,
       
  3451               name='Language', parent=self, pos=wx.Point(0, 0),
       
  3452               size=wx.Size(0, 28), style=wx.CB_READONLY)
       
  3453         
       
  3454         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
       
  3455         self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())
       
  3456         
       
  3457         self._init_sizers()
       
  3458 
       
  3459     def __init__(self, parent):
       
  3460         self._init_ctrls(parent)
       
  3461         
       
  3462         for language in GetTransitionLanguages():
       
  3463             self.Language.Append(_(language))
       
  3464             
       
  3465         self.PouNames = []
       
  3466         self.PouElementNames = []
       
  3467         
       
  3468     def OnOK(self, event):
       
  3469         error = []
       
  3470         transition_name = self.TransitionName.GetValue()
       
  3471         if self.TransitionName.GetValue() == "":
       
  3472             error.append(_("Transition Name"))
       
  3473         if self.Language.GetSelection() == -1:
       
  3474             error.append(_("Language"))
       
  3475         if len(error) > 0:
       
  3476             text = ""
       
  3477             for i, item in enumerate(error):
       
  3478                 if i == 0:
       
  3479                     text += item
       
  3480                 elif i == len(error) - 1:
       
  3481                     text += _(" and %s")%item
       
  3482                 else:
       
  3483                     text += _(", %s")%item 
       
  3484             message = wx.MessageDialog(self, _("Form isn't complete. %s must be filled!")%text, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3485             message.ShowModal()
       
  3486             message.Destroy()
       
  3487         elif not TestIdentifier(transition_name):
       
  3488             message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%transition_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3489             message.ShowModal()
       
  3490             message.Destroy()
       
  3491         elif transition_name.upper() in IEC_KEYWORDS:
       
  3492             message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%transition_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3493             message.ShowModal()
       
  3494             message.Destroy()
       
  3495         elif transition_name.upper() in self.PouNames:
       
  3496             message = wx.MessageDialog(self, _("A POU named \"%s\" already exists!")%transition_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3497             message.ShowModal()
       
  3498             message.Destroy()
       
  3499         elif transition_name.upper() in self.PouElementNames:
       
  3500             message = wx.MessageDialog(self, _("\"%s\" element for this pou already exists!")%transition_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3501             message.ShowModal()
       
  3502             message.Destroy()
       
  3503         else:
       
  3504             self.EndModal(wx.ID_OK)
       
  3505     
       
  3506     def SetPouNames(self, pou_names):
       
  3507         self.PouNames = [pou_name.upper() for pou_name in pou_names]
       
  3508     
       
  3509     def SetPouElementNames(self, pou_names):
       
  3510         self.PouElementNames = [pou_name.upper() for pou_name in pou_names]
       
  3511     
       
  3512     def SetValues(self, values):
       
  3513         for item, value in values.items():
       
  3514             if item == "transitionName":
       
  3515                 self.TransitionName.SetValue(value)
       
  3516             elif item == "language":
       
  3517                 self.Language.SetSelection(_(value))
       
  3518                 
       
  3519     def GetValues(self):
       
  3520         values = {}
       
  3521         values["transitionName"] = self.TransitionName.GetValue()
       
  3522         values["language"] = TRANSITION_LANGUAGES_DICT[self.Language.GetStringSelection()]
       
  3523         return values
       
  3524 
       
  3525 #-------------------------------------------------------------------------------
       
  3526 #                          Create Pou Action Dialog
       
  3527 #-------------------------------------------------------------------------------
       
  3528 
       
  3529 [ID_POUACTIONDIALOG, ID_POUACTIONDIALOGACTIONNAME, 
       
  3530  ID_POUACTIONDIALOGLANGUAGE, ID_POUACTIONDIALOGSTATICTEXT1, 
       
  3531  ID_POUACTIONDIALOGSTATICTEXT2, 
       
  3532 ] = [wx.NewId() for _init_ctrls in range(5)]
       
  3533 
       
  3534 def GetActionLanguages():
       
  3535     _ = lambda x : x
       
  3536     return [_("IL"), _("ST"), _("LD"), _("FBD")]
       
  3537 ACTION_LANGUAGES_DICT = dict([(_(language), language) for language in GetActionLanguages()])
       
  3538 
       
  3539 class PouActionDialog(wx.Dialog):
       
  3540     if wx.VERSION < (2, 6, 0):
       
  3541         def Bind(self, event, function, id = None):
       
  3542             if id is not None:
       
  3543                 event(self, id, function)
       
  3544             else:
       
  3545                 event(self, function)
       
  3546     
       
  3547     def _init_coll_flexGridSizer1_Items(self, parent):
       
  3548         parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
       
  3549         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
       
  3550         
       
  3551     def _init_coll_flexGridSizer1_Growables(self, parent):
       
  3552         parent.AddGrowableCol(0)
       
  3553         parent.AddGrowableRow(0)
       
  3554     
       
  3555     def _init_coll_MainSizer_Items(self, parent):
       
  3556         parent.AddWindow(self.staticText1, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP)
       
  3557         parent.AddWindow(self.ActionName, 0, border=0, flag=wx.GROW)
       
  3558         parent.AddWindow(self.staticText2, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP)
       
  3559         parent.AddWindow(self.Language, 0, border=0, flag=wx.GROW)
       
  3560         
       
  3561     def _init_coll_MainSizer_Growables(self, parent):
       
  3562         parent.AddGrowableCol(1)
       
  3563         
       
  3564     def _init_sizers(self):
       
  3565         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
       
  3566         self.MainSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=15)
       
  3567 
       
  3568         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
  3569         self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1)
       
  3570         self._init_coll_MainSizer_Items(self.MainSizer)
       
  3571         self._init_coll_MainSizer_Growables(self.MainSizer)
       
  3572 
       
  3573         self.SetSizer(self.flexGridSizer1)
       
  3574 
       
  3575     def _init_ctrls(self, prnt):
       
  3576         wx.Dialog.__init__(self, id=ID_POUACTIONDIALOG,
       
  3577               name='PouActionDialog', parent=prnt, pos=wx.Point(376, 223),
       
  3578               size=wx.Size(320, 200), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER,
       
  3579               title=_('Create a new action'))
       
  3580         self.SetClientSize(wx.Size(320, 160))
       
  3581 
       
  3582         self.staticText1 = wx.StaticText(id=ID_POUACTIONDIALOGSTATICTEXT1,
       
  3583               label=_('Action Name:'), name='staticText1', parent=self,
       
  3584               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  3585 
       
  3586         self.ActionName = wx.TextCtrl(id=ID_POUACTIONDIALOGACTIONNAME,
       
  3587               name='ActionName', parent=self, pos=wx.Point(0, 0),
       
  3588               size=wx.Size(0, 24), style=0)
       
  3589 
       
  3590         self.staticText2 = wx.StaticText(id=ID_POUACTIONDIALOGSTATICTEXT2,
       
  3591               label=_('Language:'), name='staticText2', parent=self,
       
  3592               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
  3593 
       
  3594         self.Language = wx.ComboBox(id=ID_POUACTIONDIALOGLANGUAGE,
       
  3595               name='Language', parent=self, pos=wx.Point(0, 0),
       
  3596               size=wx.Size(0, 28), style=wx.CB_READONLY)
       
  3597         
       
  3598         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
       
  3599         self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())
       
  3600         
       
  3601         self._init_sizers()
       
  3602 
       
  3603     def __init__(self, parent):
       
  3604         self._init_ctrls(parent)
       
  3605         
       
  3606         for option in GetActionLanguages():
       
  3607             self.Language.Append(_(option))
       
  3608         
       
  3609         self.PouNames = []
       
  3610         self.PouElementNames = []
       
  3611     
       
  3612     def OnOK(self, event):
       
  3613         error = []
       
  3614         action_name = self.ActionName.GetValue()
       
  3615         if action_name == "":
       
  3616             error.append(_("Action Name"))
       
  3617         if self.Language.GetSelection() == -1:
       
  3618             error.append(_("Language"))
       
  3619         if len(error) > 0:
       
  3620             text = ""
       
  3621             for i, item in enumerate(error):
       
  3622                 if i == 0:
       
  3623                     text += item
       
  3624                 elif i == len(error) - 1:
       
  3625                     text += _(" and %s")%item
       
  3626                 else:
       
  3627                     text += _(", %s")%item 
       
  3628             message = wx.MessageDialog(self, _("Form isn't complete. %s must be filled!")%text, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3629             message.ShowModal()
       
  3630             message.Destroy()
       
  3631         elif not TestIdentifier(action_name):
       
  3632             message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%action_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3633             message.ShowModal()
       
  3634             message.Destroy()
       
  3635         elif action_name.upper() in IEC_KEYWORDS:
       
  3636             message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%action_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3637             message.ShowModal()
       
  3638             message.Destroy()
       
  3639         elif action_name.upper() in self.PouNames:
       
  3640             message = wx.MessageDialog(self, _("A POU named \"%s\" already exists!")%action_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3641             message.ShowModal()
       
  3642             message.Destroy()
       
  3643         elif action_name.upper() in self.PouElementNames:
       
  3644             message = wx.MessageDialog(self, _("\"%s\" element for this pou already exists!")%action_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3645             message.ShowModal()
       
  3646             message.Destroy()
       
  3647         else:
       
  3648             self.EndModal(wx.ID_OK)
       
  3649     
       
  3650     def SetPouNames(self, pou_names):
       
  3651         self.PouNames = [pou_name.upper() for pou_name in pou_names]
       
  3652         
       
  3653     def SetPouElementNames(self, element_names):
       
  3654         self.PouElementNames = [element_name.upper() for element_name in element_names]
       
  3655         
       
  3656     def SetValues(self, values):
       
  3657         for item, value in values.items():
       
  3658             if item == "actionName":
       
  3659                 self.ActionName.SetValue(value)
       
  3660             elif item == "language":
       
  3661                 self.Language.SetStringSelection(_(value))
       
  3662                 
       
  3663     def GetValues(self):
       
  3664         values = {}
       
  3665         values["actionName"] = self.ActionName.GetValue()
       
  3666         values["language"] = ACTION_LANGUAGES_DICT[self.Language.GetStringSelection()]
       
  3667         return values
       
  3668 
       
  3669 #-------------------------------------------------------------------------------
       
  3670 #                          Configuration Name Dialog
       
  3671 #-------------------------------------------------------------------------------
       
  3672 
       
  3673 class ConfigurationNameDialog(wx.TextEntryDialog):
       
  3674 
       
  3675     if wx.VERSION < (2, 6, 0):
       
  3676         def Bind(self, event, function, id = None):
       
  3677             if id is not None:
       
  3678                 event(self, id, function)
       
  3679             else:
       
  3680                 event(self, function)
       
  3681 
       
  3682     def __init__(self, parent, message, caption = _("Please enter configuration name"), defaultValue = "", 
       
  3683                        style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition):
       
  3684         wx.TextEntryDialog.__init__(self, parent, message, caption, defaultValue, style, pos)
       
  3685         
       
  3686         self.PouNames = []
       
  3687         self.PouElementNames = []
       
  3688         
       
  3689         if wx.VERSION >= (2, 8, 0):
       
  3690             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(2).GetSizer().GetItem(1).GetSizer().GetAffirmativeButton().GetId())
       
  3691         elif wx.VERSION >= (2, 6, 0):
       
  3692             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetAffirmativeButton().GetId())
       
  3693         else:
       
  3694             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId())
       
  3695     
       
  3696     def OnOK(self, event):
       
  3697         config_name = self.GetSizer().GetItem(1).GetWindow().GetValue()
       
  3698         if config_name == "":
       
  3699             message = wx.MessageDialog(self, _("You must type a name!"), _("Error"), wx.OK|wx.ICON_ERROR)
       
  3700             message.ShowModal()
       
  3701             message.Destroy()
       
  3702         elif not TestIdentifier(config_name):
       
  3703             message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%config_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3704             message.ShowModal()
       
  3705             message.Destroy()
       
  3706         elif config_name.upper() in IEC_KEYWORDS:
       
  3707             message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%config_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3708             message.ShowModal()
       
  3709             message.Destroy()
       
  3710         elif config_name.upper() in self.PouNames:
       
  3711             message = wx.MessageDialog(self, _("A POU named \"%s\" already exists!")%config_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3712             message.ShowModal()
       
  3713             message.Destroy()
       
  3714         elif config_name.upper() in self.PouElementNames:
       
  3715             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)
       
  3716             result = message.ShowModal()
       
  3717             message.Destroy()
       
  3718             if result == wx.ID_YES:
       
  3719                 self.EndModal(wx.ID_OK)
       
  3720         else:
       
  3721             self.EndModal(wx.ID_OK)
       
  3722 
       
  3723     def SetPouNames(self, pou_names):
       
  3724         self.PouNames = [pou_name.upper() for pou_name in pou_names]
       
  3725     
       
  3726     def SetPouElementNames(self, pou_names):
       
  3727         self.PouElementNames = [pou_name.upper() for pou_name in pou_names]
       
  3728     
       
  3729     def GetValue(self):
       
  3730         return self.GetSizer().GetItem(1).GetWindow().GetValue()
       
  3731 
       
  3732 #-------------------------------------------------------------------------------
       
  3733 #                          Resource Name Dialog
       
  3734 #-------------------------------------------------------------------------------
       
  3735 
       
  3736 class ResourceNameDialog(wx.TextEntryDialog):
       
  3737 
       
  3738     if wx.VERSION < (2, 6, 0):
       
  3739         def Bind(self, event, function, id = None):
       
  3740             if id is not None:
       
  3741                 event(self, id, function)
       
  3742             else:
       
  3743                 event(self, function)
       
  3744 
       
  3745     def __init__(self, parent, message, caption = _("Please enter resource name"), defaultValue = "", 
       
  3746                        style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition):
       
  3747         wx.TextEntryDialog.__init__(self, parent, message, caption, defaultValue, style, pos)
       
  3748         
       
  3749         self.PouNames = []
       
  3750         self.PouElementNames = []
       
  3751         
       
  3752         if wx.VERSION >= (2, 8, 0):
       
  3753             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(2).GetSizer().GetItem(1).GetSizer().GetAffirmativeButton().GetId())
       
  3754         elif wx.VERSION >= (2, 6, 0):
       
  3755             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetAffirmativeButton().GetId())
       
  3756         else:
       
  3757             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId())
       
  3758 
       
  3759     def OnOK(self, event):
       
  3760         resource_name = self.GetSizer().GetItem(1).GetWindow().GetValue()
       
  3761         if resource_name == "":
       
  3762             message = wx.MessageDialog(self, _("You must type a name!"), _("Error"), wx.OK|wx.ICON_ERROR)
       
  3763             message.ShowModal()
       
  3764             message.Destroy()
       
  3765         elif not TestIdentifier(resource_name):
       
  3766             message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%resource_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3767             message.ShowModal()
       
  3768             message.Destroy()
       
  3769         elif resource_name.upper() in IEC_KEYWORDS:
       
  3770             message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%resource_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3771             message.ShowModal()
       
  3772             message.Destroy()
       
  3773         elif resource_name.upper() in self.PouNames:
       
  3774             message = wx.MessageDialog(self, _("A POU named \"%s\" already exists!")%resource_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  3775             message.ShowModal()
       
  3776             message.Destroy()
       
  3777         elif resource_name.upper() in self.PouElementNames:
       
  3778             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)
       
  3779             result = message.ShowModal()
       
  3780             message.Destroy()
       
  3781             if result == wx.ID_YES:
       
  3782                 self.EndModal(wx.ID_OK)
       
  3783         else:
       
  3784             self.EndModal(wx.ID_OK)
       
  3785 
       
  3786     def SetPouNames(self, pou_names):
       
  3787         self.PouNames = [pou_name.upper() for pou_name in pou_names]
       
  3788     
       
  3789     def SetPouElementNames(self, pou_names):
       
  3790         self.PouElementNames = [pou_name.upper() for pou_name in pou_names]
       
  3791     
       
  3792     def GetValue(self):
       
  3793         return self.GetSizer().GetItem(1).GetWindow().GetValue()
       
  3794 
       
  3795 #-------------------------------------------------------------------------------
       
  3796 #                            Variables Editor Panel
       
  3797 #-------------------------------------------------------------------------------
       
  3798 
       
  3799 class VariablePanelIndexer(wx.Panel):
       
  3800     
       
  3801     def _init_sizers(self):
       
  3802         self.MainSizer = wx.BoxSizer(wx.HORIZONTAL)
       
  3803         
       
  3804         self.SetSizer(self.MainSizer)
       
  3805     
       
  3806     def _init_ctrls(self, prnt):
       
  3807         wx.Panel.__init__(self, id=wx.NewId(),
       
  3808               name='VariablePanelIndexer', parent=prnt, pos=wx.Point(0, 0),
       
  3809               size=wx.Size(0, 300), style=wx.TAB_TRAVERSAL)
       
  3810         
       
  3811         self._init_sizers()
       
  3812     
       
  3813     def __init__(self, parent, window):
       
  3814         self._init_ctrls(parent)
       
  3815         
       
  3816         self.ParentWindow = window
       
  3817         
       
  3818         self.VariablePanelList = {}
       
  3819         self.CurrentPanel = None
       
  3820         
       
  3821     def AddVariablePanel(self, tagname, element_type):
       
  3822         new_panel = VariablePanel(self, self.ParentWindow, self.ParentWindow.Controler, element_type)
       
  3823         new_panel.SetTagName(tagname)
       
  3824         new_panel.Hide()
       
  3825         new_panel.RefreshView()
       
  3826         self.MainSizer.AddWindow(new_panel, 1, border=0, flag=wx.GROW)
       
  3827         self.VariablePanelList[tagname] = new_panel
       
  3828         
       
  3829     def RemoveVariablePanel(self, tagname):
       
  3830         if tagname in self.VariablePanelList:
       
  3831             panel = self.VariablePanelList.pop(tagname)
       
  3832             self.MainSizer.Remove(panel)
       
  3833             panel.Destroy()
       
  3834             if self.CurrentPanel == tagname:
       
  3835                 self.CurrentPanel = None
       
  3836     
       
  3837     def RemoveAllPanels(self):
       
  3838         for tagname in self.VariablePanelList.keys():
       
  3839             self.RemoveVariablePanel(tagname)
       
  3840     
       
  3841     def UpdateVariablePanelTagName(self, old_tagname, new_tagname):
       
  3842         if old_tagname in self.VariablePanelList:
       
  3843             self.VariablePanelList[new_tagname] = self.VariablePanelList.pop(old_tagname)
       
  3844             if self.CurrentPanel == old_tagname:
       
  3845                 self.CurrentPanel = new_tagname
       
  3846                 
       
  3847     def ChangeVariablePanel(self, tagname):
       
  3848         if tagname in self.VariablePanelList:
       
  3849             if tagname != self.CurrentPanel:
       
  3850                 if self.CurrentPanel is not None:
       
  3851                     self.VariablePanelList[self.CurrentPanel].Hide()
       
  3852                 self.CurrentPanel = tagname
       
  3853                 self.VariablePanelList[self.CurrentPanel].RefreshView()
       
  3854                 self.VariablePanelList[self.CurrentPanel].Show()
       
  3855                 self.MainSizer.Layout()
       
  3856         else:
       
  3857             if self.CurrentPanel is not None:
       
  3858                 self.VariablePanelList[self.CurrentPanel].Hide()
       
  3859             self.CurrentPanel = None
       
  3860             self.MainSizer.Layout()
       
  3861 
       
  3862     def RefreshVariablePanel(self, tagname):
       
  3863         if tagname in self.VariablePanelList:
       
  3864             self.VariablePanelList[self.CurrentPanel].RefreshView()
       
  3865 
       
  3866     def AddVariableError(self, infos):
       
  3867         self.ChangeVariablePanel(infos[0])
       
  3868         if self.CurrentPanel is not None:
       
  3869             self.VariablePanelList[self.CurrentPanel].AddVariableError(infos[2:])
       
  3870 
       
  3871     def ClearErrors(self):
       
  3872         for panel in self.VariablePanelList.values():
       
  3873             panel.ClearErrors()
       
  3874 
       
  3875 #-------------------------------------------------------------------------------
       
  3876 #                            Debug Variables Panel
       
  3877 #-------------------------------------------------------------------------------
       
  3878 
       
  3879 def GetDebugVariablesTableColnames():
       
  3880     _ = lambda x : x
       
  3881     return [_("Variable"), _("Value")]
       
  3882 
       
  3883 class VariableTableItem(DebugDataConsumer):
       
  3884     
       
  3885     def __init__(self, parent, variable, value):
       
  3886         DebugDataConsumer.__init__(self)
       
  3887         self.Parent = parent
       
  3888         self.Variable = variable
       
  3889         self.Value = value
       
  3890     
       
  3891     def __del__(self):
       
  3892         self.Parent = None
       
  3893     
       
  3894     def SetVariable(self, variable):
       
  3895         if self.Parent and self.Variable != variable:
       
  3896             self.Variable = variable
       
  3897             self.Parent.RefreshGrid()
       
  3898     
       
  3899     def GetVariable(self):
       
  3900         return self.Variable
       
  3901     
       
  3902     def SetValue(self, value):
       
  3903         if self.Value != value:
       
  3904             self.Value = value
       
  3905             self.Parent.HasNewData = True
       
  3906             
       
  3907     def GetValue(self):
       
  3908         return self.Value
       
  3909 
       
  3910 class DebugVariableTable(wx.grid.PyGridTableBase):
       
  3911     
       
  3912     """
       
  3913     A custom wx.grid.Grid Table using user supplied data
       
  3914     """
       
  3915     def __init__(self, parent, data, colnames):
       
  3916         # The base class must be initialized *first*
       
  3917         wx.grid.PyGridTableBase.__init__(self)
       
  3918         self.data = data
       
  3919         self.colnames = colnames
       
  3920         self.Parent = parent
       
  3921         # XXX
       
  3922         # we need to store the row length and collength to
       
  3923         # see if the table has changed size
       
  3924         self._rows = self.GetNumberRows()
       
  3925         self._cols = self.GetNumberCols()
       
  3926     
       
  3927     def GetNumberCols(self):
       
  3928         return len(self.colnames)
       
  3929         
       
  3930     def GetNumberRows(self):
       
  3931         return len(self.data)
       
  3932 
       
  3933     def GetColLabelValue(self, col, translate=True):
       
  3934         if col < len(self.colnames):
       
  3935             if translate:
       
  3936                 return _(self.colnames[col])
       
  3937             return self.colnames[col]
       
  3938 
       
  3939     def GetRowLabelValues(self, row, translate=True):
       
  3940         return row
       
  3941 
       
  3942     def GetValue(self, row, col):
       
  3943         if row < self.GetNumberRows():
       
  3944             return self.GetValueByName(row, self.GetColLabelValue(col, False))
       
  3945         return ""
       
  3946     
       
  3947     def SetValue(self, row, col, value):
       
  3948         if col < len(self.colnames):
       
  3949             self.SetValueByName(row, self.GetColLabelValue(col, False), value)
       
  3950             
       
  3951     def GetValueByName(self, row, colname):
       
  3952         if row < self.GetNumberRows():
       
  3953             if colname == "Variable":
       
  3954                 return self.data[row].GetVariable()
       
  3955             elif colname == "Value":
       
  3956                 return self.data[row].GetValue()
       
  3957         return ""
       
  3958 
       
  3959     def SetValueByName(self, row, colname, value):
       
  3960         if row < self.GetNumberRows():
       
  3961             if colname == "Variable":
       
  3962                 self.data[row].SetVariable(value)
       
  3963             elif colname == "Value":
       
  3964                 self.data[row].SetValue(value)
       
  3965     
       
  3966     def ResetView(self, grid):
       
  3967         """
       
  3968         (wx.grid.Grid) -> Reset the grid view.   Call this to
       
  3969         update the grid if rows and columns have been added or deleted
       
  3970         """
       
  3971         grid.BeginBatch()
       
  3972         for current, new, delmsg, addmsg in [
       
  3973             (self._rows, self.GetNumberRows(), wx.grid.GRIDTABLE_NOTIFY_ROWS_DELETED, wx.grid.GRIDTABLE_NOTIFY_ROWS_APPENDED),
       
  3974             (self._cols, self.GetNumberCols(), wx.grid.GRIDTABLE_NOTIFY_COLS_DELETED, wx.grid.GRIDTABLE_NOTIFY_COLS_APPENDED),
       
  3975         ]:
       
  3976             if new < current:
       
  3977                 msg = wx.grid.GridTableMessage(self,delmsg,new,current-new)
       
  3978                 grid.ProcessTableMessage(msg)
       
  3979             elif new > current:
       
  3980                 msg = wx.grid.GridTableMessage(self,addmsg,new-current)
       
  3981                 grid.ProcessTableMessage(msg)
       
  3982                 self.UpdateValues(grid)
       
  3983         grid.EndBatch()
       
  3984 
       
  3985         self._rows = self.GetNumberRows()
       
  3986         self._cols = self.GetNumberCols()
       
  3987         # update the column rendering scheme
       
  3988         self._updateColAttrs(grid)
       
  3989 
       
  3990         # update the scrollbars and the displayed part of the grid
       
  3991         grid.AdjustScrollbars()
       
  3992         grid.ForceRefresh()
       
  3993 
       
  3994     def UpdateValues(self, grid):
       
  3995         """Update all displayed values"""
       
  3996         # This sends an event to the grid table to update all of the values
       
  3997         msg = wx.grid.GridTableMessage(self, wx.grid.GRIDTABLE_REQUEST_VIEW_GET_VALUES)
       
  3998         grid.ProcessTableMessage(msg)
       
  3999 
       
  4000     def _updateColAttrs(self, grid):
       
  4001         """
       
  4002         wx.grid.Grid -> update the column attributes to add the
       
  4003         appropriate renderer given the column name.
       
  4004 
       
  4005         Otherwise default to the default renderer.
       
  4006         """
       
  4007         
       
  4008         for row in range(self.GetNumberRows()):
       
  4009             for col in range(self.GetNumberCols()):
       
  4010                 grid.SetReadOnly(row, col, True)
       
  4011                 
       
  4012     def SetData(self, data):
       
  4013         self.data = data
       
  4014     
       
  4015     def GetData(self):
       
  4016         return self.data
       
  4017     
       
  4018     def AppendItem(self, data):
       
  4019         self.data.append(data)
       
  4020     
       
  4021     def InsertItem(self, idx, data):
       
  4022         self.data.insert(idx, data)
       
  4023     
       
  4024     def RemoveItem(self, idx):
       
  4025         self.data.pop(idx)
       
  4026     
       
  4027     def MoveItem(self, idx, new_idx):
       
  4028         self.data.insert(new_idx, self.data.pop(idx))
       
  4029         
       
  4030     def GetItem(self, idx):
       
  4031         return self.data[idx]
       
  4032 
       
  4033     def Empty(self):
       
  4034         self.data = []
       
  4035     
       
  4036 class DebugVariableDropTarget(wx.TextDropTarget):
       
  4037     
       
  4038     def __init__(self, parent):
       
  4039         wx.TextDropTarget.__init__(self)
       
  4040         self.ParentWindow = parent
       
  4041     
       
  4042     def OnDropText(self, x, y, data):
       
  4043         x, y = self.ParentWindow.VariablesGrid.CalcUnscrolledPosition(x, y)
       
  4044         row = self.ParentWindow.VariablesGrid.YToRow(y - self.ParentWindow.VariablesGrid.GetColLabelSize())
       
  4045         if row == wx.NOT_FOUND:
       
  4046             row = self.ParentWindow.Table.GetNumberRows()
       
  4047         message = None
       
  4048         try:
       
  4049             values = eval(data)
       
  4050         except:
       
  4051             message = _("Invalid value \"%s\" for debug variable")%data
       
  4052             values = None
       
  4053         if not isinstance(values, TupleType):
       
  4054             message = _("Invalid value \"%s\" for debug variable")%data
       
  4055             values = None
       
  4056         if values is not None and values[1] == "debug":
       
  4057             self.ParentWindow.InsertValue(row, values[0])
       
  4058         if message is not None:
       
  4059             wx.CallAfter(self.ShowMessage, message)
       
  4060             
       
  4061     def ShowMessage(self, message):
       
  4062         message = wx.MessageDialog(self.ParentWindow, message, _("Error"), wx.OK|wx.ICON_ERROR)
       
  4063         message.ShowModal()
       
  4064         message.Destroy()
       
  4065 
       
  4066 [ID_DEBUGVARIABLEPANEL, ID_DEBUGVARIABLEPANELVARIABLESGRID, 
       
  4067  ID_DEBUGVARIABLEPANELUPBUTTON, ID_DEBUGVARIABLEPANELDOWNBUTTON, 
       
  4068  ID_DEBUGVARIABLEPANELDELETEBUTTON,
       
  4069 ] = [wx.NewId() for _init_ctrls in range(5)]
       
  4070 
       
  4071 class DebugVariablePanel(wx.Panel, DebugViewer):
       
  4072     
       
  4073     if wx.VERSION < (2, 6, 0):
       
  4074         def Bind(self, event, function, id = None):
       
  4075             if id is not None:
       
  4076                 event(self, id, function)
       
  4077             else:
       
  4078                 event(self, function)
       
  4079     
       
  4080     def _init_coll_MainSizer_Items(self, parent):
       
  4081         parent.AddSizer(self.ButtonPanelSizer, 0, border=5, flag=wx.ALIGN_RIGHT|wx.ALL)
       
  4082         parent.AddWindow(self.VariablesGrid, 0, border=0, flag=wx.GROW)
       
  4083     
       
  4084     def _init_coll_MainSizer_Growables(self, parent):
       
  4085         parent.AddGrowableCol(0)
       
  4086         parent.AddGrowableRow(1)
       
  4087     
       
  4088     def _init_coll_ButtonPanelSizer_Items(self, parent):
       
  4089         parent.AddWindow(self.UpButton, 0, border=5, flag=wx.RIGHT)
       
  4090         parent.AddWindow(self.DownButton, 0, border=5, flag=wx.RIGHT)
       
  4091         parent.AddWindow(self.DeleteButton, 0, border=0, flag=0)
       
  4092         
       
  4093     def _init_sizers(self):
       
  4094         self.MainSizer = wx.FlexGridSizer(cols=1, hgap=10, rows=2, vgap=0)
       
  4095         self.ButtonPanelSizer = wx.BoxSizer(wx.HORIZONTAL)
       
  4096         
       
  4097         self._init_coll_MainSizer_Items(self.MainSizer)
       
  4098         self._init_coll_MainSizer_Growables(self.MainSizer)
       
  4099         self._init_coll_ButtonPanelSizer_Items(self.ButtonPanelSizer)
       
  4100         
       
  4101         self.SetSizer(self.MainSizer)
       
  4102         
       
  4103     def _init_ctrls(self, prnt):
       
  4104         wx.Panel.__init__(self, id=ID_DEBUGVARIABLEPANEL,
       
  4105               name='DebugVariablePanel', parent=prnt, pos=wx.Point(0, 0),
       
  4106               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
  4107 
       
  4108         self.VariablesGrid = wx.grid.Grid(id=ID_DEBUGVARIABLEPANELVARIABLESGRID,
       
  4109               name='VariablesGrid', parent=self, pos=wx.Point(0, 0), 
       
  4110               size=wx.Size(0, 150), style=wx.VSCROLL)
       
  4111         self.VariablesGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False,
       
  4112               'Sans'))
       
  4113         self.VariablesGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL,
       
  4114               False, 'Sans'))
       
  4115         self.VariablesGrid.SetSelectionBackground(wx.WHITE)
       
  4116         self.VariablesGrid.SetSelectionForeground(wx.BLACK)
       
  4117         self.VariablesGrid.SetDropTarget(DebugVariableDropTarget(self))
       
  4118         
       
  4119         self.UpButton = wx.Button(id=ID_DEBUGVARIABLEPANELUPBUTTON, label='^',
       
  4120               name='UpButton', parent=self, pos=wx.Point(0, 0),
       
  4121               size=wx.Size(32, 32), style=0)
       
  4122         self.Bind(wx.EVT_BUTTON, self.OnUpButton, id=ID_DEBUGVARIABLEPANELUPBUTTON)
       
  4123         
       
  4124         self.DownButton = wx.Button(id=ID_DEBUGVARIABLEPANELDOWNBUTTON, label='v',
       
  4125               name='DownButton', parent=self, pos=wx.Point(0, 0),
       
  4126               size=wx.Size(32, 32), style=0)
       
  4127         self.Bind(wx.EVT_BUTTON, self.OnDownButton, id=ID_DEBUGVARIABLEPANELDOWNBUTTON)
       
  4128         
       
  4129         self.DeleteButton = wx.Button(id=ID_DEBUGVARIABLEPANELDELETEBUTTON, label=_('Delete'),
       
  4130               name='DeleteButton', parent=self, pos=wx.Point(0, 0),
       
  4131               size=wx.DefaultSize, style=0)
       
  4132         self.Bind(wx.EVT_BUTTON, self.OnDeleteButton, id=ID_DEBUGVARIABLEPANELDELETEBUTTON)
       
  4133         
       
  4134         self._init_sizers()
       
  4135     
       
  4136     def __init__(self, parent, producer):
       
  4137         self._init_ctrls(parent)
       
  4138         DebugViewer.__init__(self, producer, True)
       
  4139         self.HasNewData = False
       
  4140         
       
  4141         self.Table = DebugVariableTable(self, [], GetDebugVariablesTableColnames())
       
  4142         self.VariablesGrid.SetTable(self.Table)
       
  4143         self.VariablesGrid.SetRowLabelSize(0)
       
  4144         
       
  4145         for col in range(self.Table.GetNumberCols()):
       
  4146             attr = wx.grid.GridCellAttr()
       
  4147             attr.SetAlignment(wx.ALIGN_RIGHT, wx.ALIGN_CENTER)
       
  4148             self.VariablesGrid.SetColAttr(col, attr)
       
  4149             self.VariablesGrid.SetColSize(col, 100)
       
  4150         
       
  4151         self.Table.ResetView(self.VariablesGrid)
       
  4152     
       
  4153     def RefreshNewData(self):
       
  4154         if self.HasNewData:
       
  4155             self.HasNewData = False
       
  4156             self.RefreshGrid()
       
  4157         DebugViewer.RefreshNewData(self)
       
  4158     
       
  4159     def RefreshGrid(self):
       
  4160         self.Freeze()
       
  4161         self.Table.ResetView(self.VariablesGrid)
       
  4162         self.Thaw()
       
  4163     
       
  4164     def ResetGrid(self):
       
  4165         self.DeleteDataConsumers()
       
  4166         self.Table.Empty()
       
  4167         self.Freeze()
       
  4168         self.Table.ResetView(self.VariablesGrid)
       
  4169         self.Thaw()
       
  4170     
       
  4171     def OnDeleteButton(self, event):
       
  4172         idx = self.VariablesGrid.GetGridCursorRow()
       
  4173         item = self.Table.GetItem(idx)
       
  4174         self.RemoveDataConsumer(item)
       
  4175         self.Table.RemoveItem(idx)
       
  4176         self.RefreshGrid()
       
  4177         event.Skip()
       
  4178 
       
  4179     def OnUpButton(self, event):
       
  4180         self.MoveValue(self.VariablesGrid.GetGridCursorRow(), -1)
       
  4181         event.Skip()
       
  4182 
       
  4183     def OnDownButton(self, event):
       
  4184         self.MoveValue(self.VariablesGrid.GetGridCursorRow(), 1)
       
  4185         event.Skip()
       
  4186 
       
  4187     def InsertValue(self, idx, iec_path):
       
  4188         for item in self.Table.GetData():
       
  4189             if iec_path == item.GetVariable():
       
  4190                 return
       
  4191         item = VariableTableItem(self, iec_path, "")
       
  4192         result = self.AddDataConsumer(iec_path.upper(), item)
       
  4193         if result is not None:
       
  4194             self.Table.InsertItem(idx, item)
       
  4195             self.RefreshGrid()
       
  4196 
       
  4197     def MoveValue(self, idx, move):
       
  4198         new_idx = max(0, min(idx + move, self.Table.GetNumberRows() - 1))
       
  4199         if new_idx != idx:
       
  4200             self.Table.MoveItem(idx, new_idx)
       
  4201             self.RefreshGrid()
       
  4202             self.VariablesGrid.SetGridCursor(new_idx, self.VariablesGrid.GetGridCursorCol())
       
  4203     
       
  4204 #-------------------------------------------------------------------------------
       
  4205 #                               Viewer Printout
       
  4206 #-------------------------------------------------------------------------------
       
  4207 
       
  4208 UPPER_DIV = lambda x, y: (x / y) + {True : 0, False : 1}[(x % y) == 0]
       
  4209 
       
  4210 class GraphicPrintout(wx.Printout):
       
  4211     def __init__(self, viewer, page_size, margins, preview = False):
       
  4212         wx.Printout.__init__(self)
       
  4213         self.Viewer = viewer
       
  4214         self.PageSize = page_size
       
  4215         if self.PageSize[0] == 0 or self.PageSize[1] == 0:
       
  4216             self.PageSize = (1050, 1485)
       
  4217         self.Preview = preview
       
  4218         self.Margins = margins
       
  4219         self.FontSize = 5
       
  4220         self.TextMargin = 3
       
  4221         
       
  4222         maxx, maxy = viewer.GetMaxSize()
       
  4223         self.PageGrid = (UPPER_DIV(maxx, self.PageSize[0]), 
       
  4224                          UPPER_DIV(maxy, self.PageSize[1]))
       
  4225         
       
  4226     def GetPageNumber(self):
       
  4227         return self.PageGrid[0] * self.PageGrid[1]
       
  4228     
       
  4229     def HasPage(self, page):
       
  4230         return page <= self.GetPageNumber()
       
  4231         
       
  4232     def GetPageInfo(self):
       
  4233         page_number = self.GetPageNumber()
       
  4234         return (1, page_number, 1, page_number)
       
  4235 
       
  4236     def OnBeginDocument(self, startPage, endPage):
       
  4237         dc = self.GetDC()
       
  4238         if not self.Preview and isinstance(dc, wx.PostScriptDC):
       
  4239             dc.SetResolution(720)
       
  4240         super(GraphicPrintout, self).OnBeginDocument(startPage, endPage)
       
  4241 
       
  4242     def OnPrintPage(self, page):
       
  4243         dc = self.GetDC()
       
  4244         dc.SetUserScale(1.0, 1.0)
       
  4245         dc.SetDeviceOrigin(0, 0)
       
  4246         dc.printing = not self.Preview
       
  4247         
       
  4248         # Get the size of the DC in pixels
       
  4249         ppiPrinterX, ppiPrinterY = self.GetPPIPrinter()
       
  4250         ppiScreenX, ppiScreenY = self.GetPPIScreen()
       
  4251         pw, ph = self.GetPageSizePixels()
       
  4252         dw, dh = dc.GetSizeTuple()
       
  4253         Xscale = (float(dw) * float(ppiPrinterX)) / (float(pw) * 25.4)
       
  4254         Yscale = (float(dh) * float(ppiPrinterY)) / (float(ph) * 25.4)
       
  4255         
       
  4256         fontsize = self.FontSize * Yscale
       
  4257         text_margin = self.TextMargin * Yscale
       
  4258         
       
  4259         margin_left = self.Margins[0].x * Xscale
       
  4260         margin_top = self.Margins[0].y * Yscale
       
  4261         area_width = dw - self.Margins[1].x * Xscale - margin_left
       
  4262         area_height = dh - self.Margins[1].y * Yscale - margin_top
       
  4263         
       
  4264         dc.SetPen(wx.BLACK_PEN)
       
  4265         dc.SetBrush(wx.TRANSPARENT_BRUSH)    
       
  4266         dc.DrawRectangle(margin_left, margin_top, area_width, area_height)
       
  4267         
       
  4268         dc.SetFont(wx.Font(fontsize, wx.DEFAULT, wx.NORMAL, wx.NORMAL))
       
  4269         dc.SetTextForeground(wx.BLACK)
       
  4270         block_name = " - ".join(self.Viewer.GetTagName().split("::")[1:])
       
  4271         text_width, text_height = dc.GetTextExtent(block_name)
       
  4272         dc.DrawText(block_name, margin_left, margin_top - text_height - self.TextMargin)
       
  4273         dc.DrawText(_("Page: %d") % page, margin_left, margin_top + area_height + self.TextMargin)
       
  4274         
       
  4275         # Calculate the position on the DC for centering the graphic
       
  4276         posX = area_width * ((page - 1) % self.PageGrid[0])
       
  4277         posY = area_height * ((page - 1) / self.PageGrid[0])
       
  4278 
       
  4279         scaleX = float(area_width) / float(self.PageSize[0])
       
  4280         scaleY = float(area_height) / float(self.PageSize[1])
       
  4281         scale = min(scaleX, scaleY)
       
  4282 
       
  4283         # Set the scale and origin
       
  4284         dc.SetDeviceOrigin(-posX + margin_left, -posY + margin_top)
       
  4285         dc.SetClippingRegion(posX, posY, self.PageSize[0] * scale, self.PageSize[1] * scale)
       
  4286         dc.SetUserScale(scale, scale)
       
  4287         
       
  4288         #-------------------------------------------
       
  4289         
       
  4290         self.Viewer.DoDrawing(dc, True)
       
  4291         
       
  4292         return True
       
  4293 
       
  4294 #-------------------------------------------------------------------------------
       
  4295 #                               Exception Handler
       
  4296 #-------------------------------------------------------------------------------
       
  4297 
       
  4298 Max_Traceback_List_Size = 20
       
  4299 
       
  4300 def Display_Exception_Dialog(e_type,e_value,e_tb):
       
  4301     trcbck_lst = []
       
  4302     for i,line in enumerate(traceback.extract_tb(e_tb)):
       
  4303         trcbck = " " + str(i+1) + _(". ")
       
  4304         if line[0].find(os.getcwd()) == -1:
       
  4305             trcbck += _("file : ") + str(line[0]) + _(",   ")
       
  4306         else:
       
  4307             trcbck += _("file : ") + str(line[0][len(os.getcwd()):]) + _(",   ")
       
  4308         trcbck += _("line : ") + str(line[1]) + _(",   ") + _("function : ") + str(line[2])
       
  4309         trcbck_lst.append(trcbck)
       
  4310         
       
  4311     # Allow clicking....
       
  4312     cap = wx.Window_GetCapture()
       
  4313     if cap:
       
  4314         cap.ReleaseMouse()
       
  4315 
       
  4316     dlg = wx.SingleChoiceDialog(None, 
       
  4317         _("""
       
  4318 An error has occurred.
       
  4319 
       
  4320 Click OK to save an error report.
       
  4321 
       
  4322 Please contact LOLITech at:
       
  4323 +33 (0)3 29 57 60 42
       
  4324 bugs_PLCOpenEditor@lolitech.fr
       
  4325 
       
  4326 
       
  4327 Error:
       
  4328 """) +
       
  4329         str(e_type) + _(" : ") + str(e_value), 
       
  4330         _("Error"),
       
  4331         trcbck_lst)
       
  4332     try:
       
  4333         res = (dlg.ShowModal() == wx.ID_OK)
       
  4334     finally:
       
  4335         dlg.Destroy()
       
  4336 
       
  4337     return res
       
  4338 
       
  4339 def Display_Error_Dialog(e_value):
       
  4340     message = wx.MessageDialog(None, str(e_value), _("Error"), wx.OK|wx.ICON_ERROR)
       
  4341     message.ShowModal()
       
  4342     message.Destroy()
       
  4343 
       
  4344 def get_last_traceback(tb):
       
  4345     while tb.tb_next:
       
  4346         tb = tb.tb_next
       
  4347     return tb
       
  4348 
       
  4349 
       
  4350 def format_namespace(d, indent='    '):
       
  4351     return '\n'.join(['%s%s: %s' % (indent, k, repr(v)[:10000]) for k, v in d.iteritems()])
       
  4352 
       
  4353 
       
  4354 ignored_exceptions = [] # a problem with a line in a module is only reported once per session
       
  4355 
       
  4356 def AddExceptHook(path, app_version='[No version]'):#, ignored_exceptions=[]):
       
  4357     
       
  4358     def handle_exception(e_type, e_value, e_traceback):
       
  4359         traceback.print_exception(e_type, e_value, e_traceback) # this is very helpful when there's an exception in the rest of this func
       
  4360         last_tb = get_last_traceback(e_traceback)
       
  4361         ex = (last_tb.tb_frame.f_code.co_filename, last_tb.tb_frame.f_lineno)
       
  4362         if str(e_value).startswith("!!!"):
       
  4363             Display_Error_Dialog(e_value)
       
  4364         elif ex not in ignored_exceptions:
       
  4365             result = Display_Exception_Dialog(e_type,e_value,e_traceback)
       
  4366             if result:
       
  4367                 ignored_exceptions.append(ex)
       
  4368                 info = {
       
  4369                     'app-title' : wx.GetApp().GetAppName(), # app_title
       
  4370                     'app-version' : app_version,
       
  4371                     'wx-version' : wx.VERSION_STRING,
       
  4372                     'wx-platform' : wx.Platform,
       
  4373                     'python-version' : platform.python_version(), #sys.version.split()[0],
       
  4374                     'platform' : platform.platform(),
       
  4375                     'e-type' : e_type,
       
  4376                     'e-value' : e_value,
       
  4377                     'date' : time.ctime(),
       
  4378                     'cwd' : os.getcwd(),
       
  4379                     }
       
  4380                 if e_traceback:
       
  4381                     info['traceback'] = ''.join(traceback.format_tb(e_traceback)) + '%s: %s' % (e_type, e_value)
       
  4382                     last_tb = get_last_traceback(e_traceback)
       
  4383                     exception_locals = last_tb.tb_frame.f_locals # the locals at the level of the stack trace where the exception actually occurred
       
  4384                     info['locals'] = format_namespace(exception_locals)
       
  4385                     if 'self' in exception_locals:
       
  4386                         info['self'] = format_namespace(exception_locals['self'].__dict__)
       
  4387                 
       
  4388                 output = open(path+os.sep+"bug_report_"+info['date'].replace(':','-').replace(' ','_')+".txt",'w')
       
  4389                 lst = info.keys()
       
  4390                 lst.sort()
       
  4391                 for a in lst:
       
  4392                     output.write(a+":\n"+str(info[a])+"\n\n")
       
  4393 
       
  4394     #sys.excepthook = lambda *args: wx.CallAfter(handle_exception, *args)
       
  4395     sys.excepthook = handle_exception
       
  4396 
       
  4397 if __name__ == '__main__':
       
  4398     wx.InitAllImageHandlers()
       
  4399     
       
  4400     # Install a exception handle for bug reports
       
  4401     AddExceptHook(os.getcwd(),__version__)
       
  4402     
       
  4403     frame = PLCOpenEditor(None, fileOpen=fileOpen)
       
  4404 
       
  4405     frame.Show()
       
  4406     app.MainLoop()
       
  4407