Fixed launch of PLCopenEditor, broken since 611fded24ce4.
authorEdouard Tisserant
Fri, 23 May 2014 18:28:57 +0200
changeset 1408 eb2aa27602b7
parent 1407 cf3d2b53dd68
child 1409 48f5f2a622c8
Fixed launch of PLCopenEditor, broken since 611fded24ce4.
Beremiz.py
IDEFrame.py
--- a/Beremiz.py	Wed May 21 18:43:54 2014 +0200
+++ b/Beremiz.py	Fri May 23 18:28:57 2014 +0200
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 
 #This file is part of Beremiz, a Integrated Development Environment for
-#programming IEC 61131-3 automates supporting plcopen standard and CanFestival. 
+#programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
 #
 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
 #
@@ -43,7 +43,7 @@
     def usage():
         print "\nUsage of Beremiz.py :"
         print "\n   %s [Projectpath] [Buildpath]\n"%sys.argv[0]
-    
+
     try:
         opts, args = getopt.getopt(sys.argv[1:], "hu:e:", ["help", "updatecheck=", "extend="])
     except getopt.GetoptError:
@@ -52,7 +52,7 @@
         sys.exit(2)
 
     extensions=[]
-        
+
     for o, a in opts:
         if o in ("-h", "--help"):
             usage()
@@ -61,7 +61,7 @@
             updateinfo_url = a
         if o in ("-e", "--extend"):
             extensions.append(a)
-    
+
     if len(args) > 2:
         usage()
         sys.exit()
@@ -74,7 +74,7 @@
     else:
         projectOpen = None
         buildpath = None
-    
+
     if os.path.exists("BEREMIZ_DEBUG"):
         __builtin__.__dict__["BMZ_DBG"] = True
     else :
@@ -83,7 +83,7 @@
     app = wx.PySimpleApp(redirect=BMZ_DBG)
     app.SetAppName('beremiz')
     wx.InitAllImageHandlers()
-    
+
     # popup splash
     bmp = wx.Image(Bpath("images", "splash.png")).ConvertToBitmap()
     #splash=AdvancedSplash(None, bitmap=bmp, style=wx.SPLASH_CENTRE_ON_SCREEN, timeout=4000)
@@ -99,8 +99,8 @@
                 import urllib2
                 updateinfo = urllib2.urlopen(updateinfo_url,None).read()
             except :
-                updateinfo = "update info unavailable." 
-                
+                updateinfo = "update info unavailable."
+
         from threading import Thread
         splash.SetText(text=updateinfo)
         wx.Yield()
@@ -222,15 +222,15 @@
                 if style is None : style=self.black_white
                 if style != self.black_white:
                     self.output.StartStyling(self.output.GetLength(), 0xff)
-                
+
                 # Temporary deactivate read only mode on StyledTextCtrl for
-                # adding text. It seems that text modifications, even 
+                # adding text. It seems that text modifications, even
                 # programmatically, are disabled in StyledTextCtrl when read
-                # only is active 
+                # only is active
                 self.output.SetReadOnly(False)
                 self.output.AppendText(s)
                 self.output.SetReadOnly(True)
-                
+
                 if style != self.black_white:
                     self.output.SetStyling(len(s), style)
             self.stack = []
@@ -245,7 +245,7 @@
             if newtime - self.rising_timer > 1:
                 self.risecall(self.output)
             self.rising_timer = newtime
-        
+
     def write_warning(self, s):
         self.write(s,self.red_white)
 
@@ -259,11 +259,11 @@
     def flush(self):
         # Temporary deactivate read only mode on StyledTextCtrl for clearing
         # text. It seems that text modifications, even programmatically, are
-        # disabled in StyledTextCtrl when read only is active 
+        # disabled in StyledTextCtrl when read only is active
         self.output.SetReadOnly(False)
         self.output.SetText("")
         self.output.SetReadOnly(True)
-    
+
     def isatty(self):
         return False
 
@@ -284,13 +284,13 @@
 from util.BitmapLibrary import GetBitmap
 
 class Beremiz(IDEFrame):
-    
+
     def _init_utils(self):
         self.ConfNodeMenu = wx.Menu(title='')
         self.RecentProjectsMenu = wx.Menu(title='')
-        
+
         IDEFrame._init_utils(self)
-        
+
     def _init_coll_FileMenu_Items(self, parent):
         AppendMenu(parent, help='', id=wx.ID_NEW,
               kind=wx.ITEM_NORMAL, text=_(u'New') + '\tCTRL+N')
@@ -316,7 +316,7 @@
         parent.AppendSeparator()
         AppendMenu(parent, help='', id=wx.ID_EXIT,
               kind=wx.ITEM_NORMAL, text=_(u'Quit') + '\tCTRL+Q')
-        
+
         self.Bind(wx.EVT_MENU, self.OnNewProjectMenu, id=wx.ID_NEW)
         self.Bind(wx.EVT_MENU, self.OnOpenProjectMenu, id=wx.ID_OPEN)
         self.Bind(wx.EVT_MENU, self.OnSaveProjectMenu, id=wx.ID_SAVE)
@@ -327,13 +327,13 @@
         self.Bind(wx.EVT_MENU, self.OnPreviewMenu, id=wx.ID_PREVIEW)
         self.Bind(wx.EVT_MENU, self.OnPrintMenu, id=wx.ID_PRINT)
         self.Bind(wx.EVT_MENU, self.OnQuitMenu, id=wx.ID_EXIT)
-        
+
         self.AddToMenuToolBar([(wx.ID_NEW, "new", _(u'New'), None),
                                (wx.ID_OPEN, "open", _(u'Open'), None),
                                (wx.ID_SAVE, "save", _(u'Save'), None),
                                (wx.ID_SAVEAS, "saveas", _(u'Save As...'), None),
                                (wx.ID_PRINT, "print", _(u'Print'), None)])
-    
+
     def _RecursiveAddMenuItems(self, menu, items):
         for name, text, help, children in items:
             new_id = wx.NewId()
@@ -342,20 +342,20 @@
                 menu.AppendMenu(new_id, text, new_menu)
                 self._RecursiveAddMenuItems(new_menu, children)
             else:
-                AppendMenu(menu, help=help, id=new_id, 
+                AppendMenu(menu, help=help, id=new_id,
                        kind=wx.ITEM_NORMAL, text=text)
-                self.Bind(wx.EVT_MENU, self.GetAddConfNodeFunction(name), 
-                          id=new_id)    
-    
+                self.Bind(wx.EVT_MENU, self.GetAddConfNodeFunction(name),
+                          id=new_id)
+
     def _init_coll_AddMenu_Items(self, parent):
         IDEFrame._init_coll_AddMenu_Items(self, parent, False)
         self._RecursiveAddMenuItems(parent, GetAddMenuItems())
-    
+
     def _init_coll_HelpMenu_Items(self, parent):
         parent.Append(help='', id=wx.ID_ABOUT,
               kind=wx.ITEM_NORMAL, text=_(u'About'))
         self.Bind(wx.EVT_MENU, self.OnAboutMenu, id=wx.ID_ABOUT)
-    
+
     def _init_coll_ConnectionStatusBar_Fields(self, parent):
         parent.SetFieldsCount(3)
 
@@ -364,12 +364,12 @@
         parent.SetStatusText(number=2, text='')
 
         parent.SetStatusWidths([-1, 300, 200])
-    
+
     def _init_ctrls(self, prnt):
         IDEFrame._init_ctrls(self, prnt)
-        
+
         self.EditMenuSize = self.EditMenu.GetMenuItemCount()
-        
+
         inspectorID = wx.NewId()
         self.Bind(wx.EVT_MENU, self.OnOpenWidgetInspector, id=inspectorID)
         accels = [wx.AcceleratorEntry(wx.ACCEL_CTRL|wx.ACCEL_ALT, ord('I'), inspectorID)]
@@ -387,9 +387,9 @@
             newid = wx.NewId()
             self.Bind(wx.EVT_MENU, OnMethodGen(self,method), id=newid)
             accels += [wx.AcceleratorEntry(wx.ACCEL_NORMAL, shortcut,newid)]
-        
+
         self.SetAcceleratorTable(wx.AcceleratorTable(accels))
-        
+
         self.LogConsole = CustomStyledTextCtrl(
                   name='LogConsole', parent=self.BottomNoteBook, pos=wx.Point(0, 0),
                   size=wx.Size(0, 0))
@@ -398,32 +398,32 @@
         self.LogConsole.Bind(wx.stc.EVT_STC_UPDATEUI, self.OnLogConsoleUpdateUI)
         self.LogConsole.SetReadOnly(True)
         self.LogConsole.SetWrapMode(wx.stc.STC_WRAP_CHAR)
-        
+
         # Define Log Console styles
         self.LogConsole.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" % faces)
         self.LogConsole.StyleClearAll()
         self.LogConsole.StyleSetSpec(1, "face:%(mono)s,fore:#FF0000,size:%(size)d" % faces)
         self.LogConsole.StyleSetSpec(2, "face:%(mono)s,fore:#FF0000,back:#FFFF00,size:%(size)d" % faces)
-        
+
         # Define Log Console markers
         self.LogConsole.SetMarginSensitive(1, True)
         self.LogConsole.SetMarginType(1, wx.stc.STC_MARGIN_SYMBOL)
         self.LogConsole.MarkerDefine(0, wx.stc.STC_MARK_CIRCLE, "BLACK", "RED")
-        
+
         self.LogConsole.SetModEventMask(wx.stc.STC_MOD_INSERTTEXT)
-        
+
         self.LogConsole.Bind(wx.stc.EVT_STC_MARGINCLICK, self.OnLogConsoleMarginClick)
         self.LogConsole.Bind(wx.stc.EVT_STC_MODIFIED, self.OnLogConsoleModified)
-        
+
         self.MainTabs["LogConsole"] = (self.LogConsole, _("Console"))
         self.BottomNoteBook.AddPage(*self.MainTabs["LogConsole"])
         #self.BottomNoteBook.Split(self.BottomNoteBook.GetPageIndex(self.LogConsole), wx.RIGHT)
-        
+
         self.LogViewer = LogViewer(self.BottomNoteBook, self)
         self.MainTabs["LogViewer"] = (self.LogViewer, _("PLC Log"))
         self.BottomNoteBook.AddPage(*self.MainTabs["LogViewer"])
         #self.BottomNoteBook.Split(self.BottomNoteBook.GetPageIndex(self.LogViewer), wx.RIGHT)
-        
+
         StatusToolBar = wx.ToolBar(self, -1, wx.DefaultPosition, wx.DefaultSize,
                 wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER)
         StatusToolBar.SetToolBitmapSize(wx.Size(25, 25))
@@ -433,27 +433,27 @@
                   Name("StatusToolBar").Caption(_("Status ToolBar")).
                   ToolbarPane().Top().Position(1).
                   LeftDockable(False).RightDockable(False))
-        
+
         self.AUIManager.Update()
-        
+
         self.ConnectionStatusBar = wx.StatusBar(self, style=wx.ST_SIZEGRIP)
         self._init_coll_ConnectionStatusBar_Fields(self.ConnectionStatusBar)
         self.SetStatusBar(self.ConnectionStatusBar)
-        
+
     def __init__(self, parent, projectOpen=None, buildpath=None, ctr=None, debug=True):
         IDEFrame.__init__(self, parent, debug)
         self.Log = LogPseudoFile(self.LogConsole,self.SelectTab)
-        
+
         self.local_runtime = None
         self.runtime_port = None
         self.local_runtime_tmpdir = None
-        
+
         self.LastPanelSelected = None
-        
+
         # Define Tree item icon list
         self.LocationImageList = wx.ImageList(16, 16)
         self.LocationImageDict = {}
-        
+
         # Icons for location items
         for imgname, itemtype in [
             ("CONFIGURATION", LOCATION_CONFNODE),
@@ -463,18 +463,18 @@
             ("VAR_OUTPUT",    LOCATION_VAR_OUTPUT),
             ("VAR_LOCAL",     LOCATION_VAR_MEMORY)]:
             self.LocationImageDict[itemtype] = self.LocationImageList.Add(GetBitmap(imgname))
-        
+
         # Icons for other items
         for imgname, itemtype in [
             ("Extension", ITEM_CONFNODE)]:
             self.TreeImageDict[itemtype] = self.TreeImageList.Add(GetBitmap(imgname))
-        
+
         # Add beremiz's icon in top left corner of the frame
         self.SetIcon(wx.Icon(Bpath("images", "brz.ico"), wx.BITMAP_TYPE_ICO))
-        
+
         if projectOpen is not None:
             projectOpen = DecodeFileSystemPath(projectOpen, False)
-        
+
         if projectOpen is not None and os.path.isdir(projectOpen):
             self.CTR = ProjectController(self, self.Log)
             self.Controler = self.CTR
@@ -498,9 +498,9 @@
                 self._Refresh(PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
         if self.EnableDebug:
             self.DebugVariablePanel.SetDataProducer(self.CTR)
-        
+
         self.Bind(wx.EVT_CLOSE, self.OnCloseFrame)
-        
+
         self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU)
         self.RefreshAll()
         self.LogConsole.SetFocus()
@@ -534,14 +534,14 @@
                 cwd = self.local_runtime_tmpdir)
             self.local_runtime.spin()
         return self.runtime_port
-    
+
     def KillLocalRuntime(self):
         if self.local_runtime is not None:
             # shutdown local runtime
             self.local_runtime.kill(gently=False)
             # clear temp dir
             shutil.rmtree(self.local_runtime_tmpdir)
-            
+
             self.local_runtime = None
 
     def OnOpenWidgetInspector(self, evt):
@@ -569,7 +569,7 @@
         line_idx = self.LogConsole.LineFromPosition(event.GetPosition())
         wx.CallAfter(self.SearchLineForError, self.LogConsole.GetLine(line_idx))
         event.Skip()
-        
+
     def OnLogConsoleModified(self, event):
         line_idx = self.LogConsole.LineFromPosition(event.GetPosition())
         line = self.LogConsole.GetLine(line_idx)
@@ -585,9 +585,9 @@
             if result is not None:
                 first_line, first_column, last_line, last_column, error = result.groups()
                 infos = self.CTR.ShowError(self.Log,
-                                                  (int(first_line), int(first_column)), 
+                                                  (int(first_line), int(first_column)),
                                                   (int(last_line), int(last_column)))
-    
+
     ## Function displaying an Error dialog in PLCOpenEditor.
     #  @return False if closing cancelled.
     def CheckSaveBeforeClosing(self, title=_("Close Project")):
@@ -602,28 +602,28 @@
                 self.CTR.SaveProject()
             elif answer == wx.ID_CANCEL:
                 return False
-        
+
         for idx in xrange(self.TabsOpened.GetPageCount()):
             window = self.TabsOpened.GetPage(idx)
             if not window.CheckSaveBeforeClosing():
                 return False
-        
+
         return True
-    
+
     def GetTabInfos(self, tab):
-        if (isinstance(tab, EditorPanel) and 
-            not isinstance(tab, (Viewer, 
-                                 TextViewer, 
-                                 ResourceEditor, 
-                                 ConfigurationEditor, 
+        if (isinstance(tab, EditorPanel) and
+            not isinstance(tab, (Viewer,
+                                 TextViewer,
+                                 ResourceEditor,
+                                 ConfigurationEditor,
                                  DataTypeEditor))):
             return ("confnode", tab.Controler.CTNFullName(), tab.GetTagName())
-        elif (isinstance(tab, TextViewer) and 
+        elif (isinstance(tab, TextViewer) and
               (tab.Controler is None or isinstance(tab.Controler, MiniTextControler))):
             return ("confnode", None, tab.GetInstancePath())
         else:
             return IDEFrame.GetTabInfos(self, tab)
-    
+
     def LoadTab(self, notebook, page_infos):
         if page_infos[0] == "confnode":
             if page_infos[1] is None:
@@ -633,26 +633,26 @@
             return notebook.GetPageIndex(confnode._OpenView(*page_infos[2:]))
         else:
             return IDEFrame.LoadTab(self, notebook, page_infos)
-    
+
     def OnCloseFrame(self, event):
-        for evt_type in [wx.EVT_SET_FOCUS, 
-                         wx.EVT_KILL_FOCUS, 
+        for evt_type in [wx.EVT_SET_FOCUS,
+                         wx.EVT_KILL_FOCUS,
                          wx.stc.EVT_STC_UPDATEUI]:
             self.LogConsole.Unbind(evt_type)
         if self.CTR is None or self.CheckSaveBeforeClosing(_("Close Application")):
             if self.CTR is not None:
                 self.CTR.KillDebugThread()
             self.KillLocalRuntime()
-            
+
             self.SaveLastState()
-            
+
             event.Skip()
         else:
             event.Veto()
-    
+
     def RefreshFileMenu(self):
         self.RefreshRecentProjectsMenu()
-        
+
         MenuToolBar = self.Panes["MenuToolBar"]
         if self.CTR is not None:
             selected = self.TabsOpened.GetSelection()
@@ -695,17 +695,17 @@
             self.FileMenu.Enable(wx.ID_SAVEAS, False)
             MenuToolBar.EnableTool(wx.ID_SAVEAS, False)
             self.FileMenu.Enable(wx.ID_CLOSE_ALL, False)
-    
+
     def RefreshRecentProjectsMenu(self):
         try:
-            recent_projects = map(DecodeFileSystemPath, 
+            recent_projects = map(DecodeFileSystemPath,
                                   self.GetConfigEntry("RecentProjects", []))
         except:
             recent_projects = []
         self.FileMenu.Enable(ID_FILEMENURECENTPROJECTS, len(recent_projects) > 0)
         for idx, projectpath in enumerate(recent_projects):
             text = u'%d: %s' % (idx + 1, projectpath)
-            
+
             if idx < self.RecentProjectsMenu.GetMenuItemCount():
                 item = self.RecentProjectsMenu.FindItemByPosition(idx)
                 id = item.GetId()
@@ -713,18 +713,18 @@
                 self.Disconnect(id, id, wx.EVT_BUTTON._getEvtType())
             else:
                 id = wx.NewId()
-                AppendMenu(self.RecentProjectsMenu, help='', id=id, 
+                AppendMenu(self.RecentProjectsMenu, help='', id=id,
                            kind=wx.ITEM_NORMAL, text=text)
             self.Bind(wx.EVT_MENU, self.GenerateOpenRecentProjectFunction(projectpath), id=id)
-        
+
     def GenerateOpenRecentProjectFunction(self, projectpath):
         def OpenRecentProject(event):
             if self.CTR is not None and not self.CheckSaveBeforeClosing():
                 return
-            
+
             self.OpenProject(projectpath)
         return OpenRecentProject
-    
+
     def GenerateMenuRecursive(self, items, menu):
         for kind, infos in items:
             if isinstance(kind, ListType):
@@ -739,27 +739,27 @@
                 AppendMenu(menu, help='', id=id, kind=kind, text=text)
                 if callback is not None:
                     self.Bind(wx.EVT_MENU, callback, id=id)
-    
+
     def RefreshEditorToolBar(self):
         IDEFrame.RefreshEditorToolBar(self)
         self.AUIManager.GetPane("EditorToolBar").Position(2)
         self.AUIManager.GetPane("StatusToolBar").Position(1)
         self.AUIManager.Update()
-    
+
     def RefreshStatusToolBar(self):
         StatusToolBar = self.Panes["StatusToolBar"]
         StatusToolBar.ClearTools()
-        
+
         if self.CTR is not None:
-            
+
             for confnode_method in self.CTR.StatusMethods:
                 if "method" in confnode_method and confnode_method.get("shown",True):
                     id = wx.NewId()
-                    StatusToolBar.AddSimpleTool(id, 
-                        GetBitmap(confnode_method.get("bitmap", "Unknown")), 
+                    StatusToolBar.AddSimpleTool(id,
+                        GetBitmap(confnode_method.get("bitmap", "Unknown")),
                         confnode_method["tooltip"])
                     self.Bind(wx.EVT_MENU, self.GetMenuCallBackFunction(confnode_method["method"]), id=id)
-            
+
             StatusToolBar.Realize()
             self.AUIManager.GetPane("StatusToolBar").BestSize(StatusToolBar.GetBestSize()).Show()
         else:
@@ -767,13 +767,13 @@
         self.AUIManager.GetPane("EditorToolBar").Position(2)
         self.AUIManager.GetPane("StatusToolBar").Position(1)
         self.AUIManager.Update()
-    
+
     def RefreshEditMenu(self):
         IDEFrame.RefreshEditMenu(self)
         if self.FindFocus() == self.LogConsole:
             self.EditMenu.Enable(wx.ID_COPY, True)
             self.Panes["MenuToolBar"].EnableTool(wx.ID_COPY, True)
-        
+
         if self.CTR is not None:
             selected = self.TabsOpened.GetSelection()
             if selected >= 0:
@@ -808,28 +808,28 @@
                         self.EditMenu.Delete(item.GetId())
             self.LastPanelSelected = None
         self.MenuBar.UpdateMenus()
-    
+
     def RefreshAll(self):
         self.RefreshStatusToolBar()
-    
+
     def GetMenuCallBackFunction(self, method):
         """ Generate the callbackfunc for a given CTR method"""
         def OnMenu(event):
-            # Disable button to prevent re-entrant call 
+            # Disable button to prevent re-entrant call
             event.GetEventObject().Disable()
             # Call
             getattr(self.CTR, method)()
-            # Re-enable button 
+            # Re-enable button
             event.GetEventObject().Enable()
         return OnMenu
-    
+
     def GetConfigEntry(self, entry_name, default):
         return cPickle.loads(str(self.Config.Read(entry_name, cPickle.dumps(default))))
-    
+
     def ResetConnectionStatusBar(self):
         for field in xrange(self.ConnectionStatusBar.GetFieldsCount()):
             self.ConnectionStatusBar.SetStatusText('', field)
-    
+
     def ResetView(self):
         IDEFrame.ResetView(self)
         self.ConfNodeInfos = {}
@@ -840,10 +840,10 @@
         if self.EnableDebug:
             self.DebugVariablePanel.SetDataProducer(None)
             self.ResetConnectionStatusBar()
-    
+
     def RefreshConfigRecentProjects(self, projectpath):
         try:
-            recent_projects = map(DecodeFileSystemPath, 
+            recent_projects = map(DecodeFileSystemPath,
                                   self.GetConfigEntry("RecentProjects", []))
         except:
             recent_projects = []
@@ -853,24 +853,24 @@
         self.Config.Write("RecentProjects", cPickle.dumps(
             map(EncodeFileSystemPath, recent_projects[:MAX_RECENT_PROJECTS])))
         self.Config.Flush()
-    
+
     def ResetPerspective(self):
         IDEFrame.ResetPerspective(self)
         self.RefreshStatusToolBar()
-    
+
     def OnNewProjectMenu(self, event):
         if self.CTR is not None and not self.CheckSaveBeforeClosing():
             return
-        
+
         try:
             defaultpath = DecodeFileSystemPath(self.Config.Read("lastopenedfolder"))
         except:
             defaultpath = os.path.expanduser("~")
-        
+
         dialog = wx.DirDialog(self , _("Choose a project"), defaultpath)
         if dialog.ShowModal() == wx.ID_OK:
             projectpath = dialog.GetPath()
-            self.Config.Write("lastopenedfolder", 
+            self.Config.Write("lastopenedfolder",
                               EncodeFileSystemPath(os.path.dirname(projectpath)))
             self.Config.Flush()
             self.ResetView()
@@ -892,25 +892,25 @@
             self.RefreshAll()
             self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU)
         dialog.Destroy()
-    
+
     def OnOpenProjectMenu(self, event):
         if self.CTR is not None and not self.CheckSaveBeforeClosing():
             return
-        
+
         try:
             defaultpath = DecodeFileSystemPath(self.Config.Read("lastopenedfolder"))
         except:
             defaultpath = os.path.expanduser("~")
-        
+
         dialog = wx.DirDialog(self , _("Choose a project"), defaultpath, style=wx.DEFAULT_DIALOG_STYLE|
                                                                                wx.RESIZE_BORDER)
         if dialog.ShowModal() == wx.ID_OK:
             self.OpenProject(dialog.GetPath())
         dialog.Destroy()
-    
+
     def OpenProject(self, projectpath):
         if os.path.isdir(projectpath):
-            self.Config.Write("lastopenedfolder", 
+            self.Config.Write("lastopenedfolder",
                               EncodeFileSystemPath(os.path.dirname(projectpath)))
             self.Config.Flush()
             self.ResetView()
@@ -932,15 +932,15 @@
         else:
             self.ShowErrorMessage(_("\"%s\" folder is not a valid Beremiz project\n") % projectpath)
         self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU)
-    
+
     def OnCloseProjectMenu(self, event):
         if self.CTR is not None and not self.CheckSaveBeforeClosing():
             return
-        
+
         self.ResetView()
         self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU)
         self.RefreshAll()
-    
+
     def OnSaveProjectMenu(self, event):
         selected = self.TabsOpened.GetSelection()
         if selected != -1:
@@ -950,7 +950,7 @@
             self.CTR.SaveProject()
             self.RefreshAll()
             self._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES)
-    
+
     def OnSaveProjectAsMenu(self, event):
         selected = self.TabsOpened.GetSelection()
         if selected != -1:
@@ -960,27 +960,27 @@
             self.CTR.SaveProjectAs()
             self.RefreshAll()
             self._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES)
-    
+
     def OnQuitMenu(self, event):
         self.Close()
-        
+
     def OnAboutMenu(self, event):
         OpenHtmlFrame(self,_("About Beremiz"), Bpath("doc", "about.html"), wx.Size(550, 500))
-    
+
     def OnProjectTreeItemBeginEdit(self, event):
         selected = event.GetItem()
         if self.ProjectTree.GetPyData(selected)["type"] == ITEM_CONFNODE:
             event.Veto()
         else:
             IDEFrame.OnProjectTreeItemBeginEdit(self, event)
-    
+
     def OnProjectTreeRightUp(self, event):
         item = event.GetItem()
         item_infos = self.ProjectTree.GetPyData(item)
-        
+
         if item_infos["type"] == ITEM_CONFNODE:
             confnode_menu = wx.Menu(title='')
-            
+
             confnode = item_infos["confnode"]
             if confnode is not None:
                 menu_items = confnode.GetContextualMenuItems()
@@ -998,10 +998,10 @@
             new_id = wx.NewId()
             AppendMenu(confnode_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Delete"))
             self.Bind(wx.EVT_MENU, self.GetDeleteMenuFunction(confnode), id=new_id)
-                
+
             self.PopupMenu(confnode_menu)
             confnode_menu.Destroy()
-            
+
             event.Skip()
         elif item_infos["type"] == ITEM_RESOURCE:
             # prevent last resource to be delted
@@ -1011,7 +1011,7 @@
                 IDEFrame.OnProjectTreeRightUp(self, event)
         else:
             IDEFrame.OnProjectTreeRightUp(self, event)
-    
+
     def OnProjectTreeItemActivated(self, event):
         selected = event.GetItem()
         name = self.ProjectTree.GetItemText(selected)
@@ -1023,7 +1023,7 @@
             self.CTR._OpenView()
         else:
             IDEFrame.OnProjectTreeItemActivated(self, event)
-    
+
     def ProjectTreeItemSelect(self, select_item):
         if select_item is not None and select_item.IsOk():
             name = self.ProjectTree.GetItemText(select_item)
@@ -1034,7 +1034,7 @@
                 self.CTR._OpenView(onlyopened=True)
             else:
                 IDEFrame.ProjectTreeItemSelect(self, select_item)
-    
+
     def SelectProjectTreeItem(self, tagname):
         if self.ProjectTree is not None:
             root = self.ProjectTree.GetRootItem()
@@ -1046,31 +1046,23 @@
                         self.ProjectTree.SelectItem(root)
                         self.ResetSelectedItem()
                     else:
-                        return self.RecursiveProjectTreeItemSelection(root, 
+                        return self.RecursiveProjectTreeItemSelection(root,
                               [(word, ITEM_CONFNODE) for word in tagname.split(".")])
                 elif words[0] == "R":
                     return self.RecursiveProjectTreeItemSelection(root, [(words[2], ITEM_RESOURCE)])
                 elif not os.path.exists(words[0]):
                     IDEFrame.SelectProjectTreeItem(self, tagname)
-            
+
     def GetAddConfNodeFunction(self, name, confnode=None):
         def AddConfNodeMenuFunction(event):
             wx.CallAfter(self.AddConfNode, name, confnode)
         return AddConfNodeMenuFunction
-    
+
     def GetDeleteMenuFunction(self, confnode):
         def DeleteMenuFunction(event):
             wx.CallAfter(self.DeleteConfNode, confnode)
         return DeleteMenuFunction
-    
-    def AddResourceMenu(self, event):
-        config_names = self.CTR.GetProjectConfigNames()
-        if len(config_names) > 0:
-            tagname = self.Controler.ProjectAddConfigurationResource(config_names[0])
-            if tagname is not None:
-                self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL)
-                self.EditProjectElement(ITEM_RESOURCE, tagname)
-        
+
     def AddConfNode(self, ConfNodeType, confnode=None):
         if self.CTR.CheckProjectPathPerm():
             ConfNodeName = "%s_0" % ConfNodeType
@@ -1079,12 +1071,12 @@
             else:
                 self.CTR.CTNAddChild(ConfNodeName, ConfNodeType)
             self._Refresh(TITLE, FILEMENU, PROJECTTREE)
-            
+
     def DeleteConfNode(self, confnode):
         if self.CTR.CheckProjectPathPerm():
-            dialog = wx.MessageDialog(self, 
-                _("Really delete node '%s'?") % confnode.CTNName(), 
-                _("Remove %s node") % confnode.CTNType, 
+            dialog = wx.MessageDialog(self,
+                _("Really delete node '%s'?") % confnode.CTNName(),
+                _("Remove %s node") % confnode.CTNType,
                 wx.YES_NO|wx.NO_DEFAULT)
             if dialog.ShowModal() == wx.ID_YES:
                 confnode.CTNRemove()
@@ -1124,13 +1116,13 @@
             trcbck += "file : " + str(line[0][len(os.getcwd()):]) + ",   "
         trcbck += "line : " + str(line[1]) + ",   " + "function : " + str(line[2])
         trcbck_lst.append(trcbck)
-        
+
     # Allow clicking....
     cap = wx.Window_GetCapture()
     if cap:
         cap.ReleaseMouse()
 
-    dlg = wx.SingleChoiceDialog(None, 
+    dlg = wx.SingleChoiceDialog(None,
         _("""
 An unhandled exception (bug) occured. Bug report saved at :
 (%s)
@@ -1142,7 +1134,7 @@
 
 Traceback:
 """) % bug_report_path +
-        repr(e_type) + " : " + repr(e_value), 
+        repr(e_type) + " : " + repr(e_value),
         _("Error"),
         trcbck_lst)
     try:
@@ -1165,7 +1157,7 @@
 ignored_exceptions = [] # a problem with a line in a module is only reported once per session
 
 def AddExceptHook(path, app_version='[No version]'):#, ignored_exceptions=[]):
-    
+
     def handle_exception(e_type, e_value, e_traceback):
         traceback.print_exception(e_type, e_value, e_traceback) # this is very helpful when there's an exception in the rest of this func
         last_tb = get_last_traceback(e_traceback)
@@ -1198,7 +1190,7 @@
                             info['self'] = format_namespace(exception_locals['self'].__dict__)
                         except :
                             pass
-                
+
                 output = open(bug_report_path,'w')
                 lst = info.keys()
                 lst.sort()
@@ -1225,7 +1217,7 @@
 if __name__ == '__main__':
     # Install a exception handle for bug reports
     AddExceptHook(os.getcwd(),updateinfo_url)
-    
+
     frame = Beremiz(None, projectOpen, buildpath)
     if splash:
         splash.Close()
--- a/IDEFrame.py	Wed May 21 18:43:54 2014 +0200
+++ b/IDEFrame.py	Fri May 23 18:28:57 2014 +0200
@@ -20,27 +20,27 @@
 from util.BitmapLibrary import GetBitmap
 
 # Define PLCOpenEditor controls id
-[ID_PLCOPENEDITOR, ID_PLCOPENEDITORLEFTNOTEBOOK, 
- ID_PLCOPENEDITORBOTTOMNOTEBOOK, ID_PLCOPENEDITORRIGHTNOTEBOOK, 
- ID_PLCOPENEDITORPROJECTTREE, ID_PLCOPENEDITORMAINSPLITTER, 
- ID_PLCOPENEDITORSECONDSPLITTER, ID_PLCOPENEDITORTHIRDSPLITTER, 
- ID_PLCOPENEDITORLIBRARYPANEL, ID_PLCOPENEDITORLIBRARYSEARCHCTRL, 
- ID_PLCOPENEDITORLIBRARYTREE, ID_PLCOPENEDITORLIBRARYCOMMENT, 
- ID_PLCOPENEDITORTABSOPENED, ID_PLCOPENEDITORTABSOPENED, 
- ID_PLCOPENEDITOREDITORMENUTOOLBAR, ID_PLCOPENEDITOREDITORTOOLBAR, 
- ID_PLCOPENEDITORPROJECTPANEL, 
+[ID_PLCOPENEDITOR, ID_PLCOPENEDITORLEFTNOTEBOOK,
+ ID_PLCOPENEDITORBOTTOMNOTEBOOK, ID_PLCOPENEDITORRIGHTNOTEBOOK,
+ ID_PLCOPENEDITORPROJECTTREE, ID_PLCOPENEDITORMAINSPLITTER,
+ ID_PLCOPENEDITORSECONDSPLITTER, ID_PLCOPENEDITORTHIRDSPLITTER,
+ ID_PLCOPENEDITORLIBRARYPANEL, ID_PLCOPENEDITORLIBRARYSEARCHCTRL,
+ ID_PLCOPENEDITORLIBRARYTREE, ID_PLCOPENEDITORLIBRARYCOMMENT,
+ ID_PLCOPENEDITORTABSOPENED, ID_PLCOPENEDITORTABSOPENED,
+ ID_PLCOPENEDITOREDITORMENUTOOLBAR, ID_PLCOPENEDITOREDITORTOOLBAR,
+ ID_PLCOPENEDITORPROJECTPANEL,
 ] = [wx.NewId() for _init_ctrls in range(17)]
 
 # Define PLCOpenEditor EditMenu extra items id
-[ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, ID_PLCOPENEDITOREDITMENUADDDATATYPE, 
- ID_PLCOPENEDITOREDITMENUADDFUNCTION, ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK, 
+[ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, ID_PLCOPENEDITOREDITMENUADDDATATYPE,
+ ID_PLCOPENEDITOREDITMENUADDFUNCTION, ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK,
  ID_PLCOPENEDITOREDITMENUADDPROGRAM, ID_PLCOPENEDITOREDITMENUADDCONFIGURATION,
  ID_PLCOPENEDITOREDITMENUFINDNEXT, ID_PLCOPENEDITOREDITMENUFINDPREVIOUS,
  ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT, ID_PLCOPENEDITOREDITMENUADDRESOURCE
 ] = [wx.NewId() for _init_coll_EditMenu_Items in range(10)]
 
 # Define PLCOpenEditor DisplayMenu extra items id
-[ID_PLCOPENEDITORDISPLAYMENURESETPERSPECTIVE, 
+[ID_PLCOPENEDITORDISPLAYMENURESETPERSPECTIVE,
 ] = [wx.NewId() for _init_coll_DisplayMenu_Items in range(1)]
 
 #-------------------------------------------------------------------------------
@@ -56,12 +56,12 @@
  ID_PLCOPENEDITOREDITORTOOLBARBRANCH, ID_PLCOPENEDITOREDITORTOOLBARINITIALSTEP,
  ID_PLCOPENEDITOREDITORTOOLBARSTEP, ID_PLCOPENEDITOREDITORTOOLBARTRANSITION,
  ID_PLCOPENEDITOREDITORTOOLBARACTIONBLOCK, ID_PLCOPENEDITOREDITORTOOLBARDIVERGENCE,
- ID_PLCOPENEDITOREDITORTOOLBARJUMP, ID_PLCOPENEDITOREDITORTOOLBARMOTION, 
+ ID_PLCOPENEDITOREDITORTOOLBARJUMP, ID_PLCOPENEDITOREDITORTOOLBARMOTION,
 ] = [wx.NewId() for _init_coll_DefaultEditorToolBar_Items in range(18)]
 
 
 
-# Define behaviour of each Toolbar item according to current POU body type 
+# Define behaviour of each Toolbar item according to current POU body type
 # Informations meaning are in this order:
 #  - Item is toggled
 #  - PLCOpenEditor mode where item is displayed (could be more then one)
@@ -82,77 +82,77 @@
              (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
               ID_PLCOPENEDITOREDITORTOOLBARBLOCK, "OnBlockTool",
               "add_block", _("Create a new block")),
-             (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, 
-              ID_PLCOPENEDITOREDITORTOOLBARCONNECTION, "OnConnectionTool", 
+             (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
+              ID_PLCOPENEDITOREDITORTOOLBARCONNECTION, "OnConnectionTool",
               "add_connection", _("Create a new connection"))],
     "LD"  : [(True, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
               ID_PLCOPENEDITOREDITORTOOLBARMOTION, "OnMotionTool",
               "move", _("Move the view")),
-             (True, FREEDRAWING_MODE, 
-              ID_PLCOPENEDITOREDITORTOOLBARCOMMENT, "OnCommentTool", 
+             (True, FREEDRAWING_MODE,
+              ID_PLCOPENEDITOREDITORTOOLBARCOMMENT, "OnCommentTool",
               "add_comment", _("Create a new comment")),
-             (True, FREEDRAWING_MODE, 
-              ID_PLCOPENEDITOREDITORTOOLBARPOWERRAIL, "OnPowerRailTool", 
+             (True, FREEDRAWING_MODE,
+              ID_PLCOPENEDITOREDITORTOOLBARPOWERRAIL, "OnPowerRailTool",
               "add_powerrail", _("Create a new power rail")),
-             (False, DRIVENDRAWING_MODE, 
-              ID_PLCOPENEDITOREDITORTOOLBARRUNG, "OnRungTool", 
+             (False, DRIVENDRAWING_MODE,
+              ID_PLCOPENEDITOREDITORTOOLBARRUNG, "OnRungTool",
               "add_rung", _("Create a new rung")),
-             (True, FREEDRAWING_MODE, 
-              ID_PLCOPENEDITOREDITORTOOLBARCOIL, "OnCoilTool", 
+             (True, FREEDRAWING_MODE,
+              ID_PLCOPENEDITOREDITORTOOLBARCOIL, "OnCoilTool",
               "add_coil", _("Create a new coil")),
-             (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, 
-              ID_PLCOPENEDITOREDITORTOOLBARCONTACT, "OnContactTool", 
+             (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
+              ID_PLCOPENEDITOREDITORTOOLBARCONTACT, "OnContactTool",
               "add_contact", _("Create a new contact")),
-             (False, DRIVENDRAWING_MODE, 
-              ID_PLCOPENEDITOREDITORTOOLBARBRANCH, "OnBranchTool", 
+             (False, DRIVENDRAWING_MODE,
+              ID_PLCOPENEDITOREDITORTOOLBARBRANCH, "OnBranchTool",
               "add_branch", _("Create a new branch")),
-             (True, FREEDRAWING_MODE, 
-              ID_PLCOPENEDITOREDITORTOOLBARVARIABLE, "OnVariableTool", 
+             (True, FREEDRAWING_MODE,
+              ID_PLCOPENEDITOREDITORTOOLBARVARIABLE, "OnVariableTool",
               "add_variable", _("Create a new variable")),
-             (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, 
-              ID_PLCOPENEDITOREDITORTOOLBARBLOCK, "OnBlockTool", 
+             (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
+              ID_PLCOPENEDITOREDITORTOOLBARBLOCK, "OnBlockTool",
               "add_block", _("Create a new block")),
-             (True, FREEDRAWING_MODE, 
-              ID_PLCOPENEDITOREDITORTOOLBARCONNECTION, "OnConnectionTool", 
+             (True, FREEDRAWING_MODE,
+              ID_PLCOPENEDITOREDITORTOOLBARCONNECTION, "OnConnectionTool",
               "add_connection", _("Create a new connection"))],
     "SFC" : [(True, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
               ID_PLCOPENEDITOREDITORTOOLBARMOTION, "OnMotionTool",
               "move", _("Move the view")),
-             (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, 
-              ID_PLCOPENEDITOREDITORTOOLBARCOMMENT, "OnCommentTool", 
+             (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
+              ID_PLCOPENEDITOREDITORTOOLBARCOMMENT, "OnCommentTool",
               "add_comment", _("Create a new comment")),
-             (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, 
-              ID_PLCOPENEDITOREDITORTOOLBARINITIALSTEP, "OnInitialStepTool", 
+             (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
+              ID_PLCOPENEDITOREDITORTOOLBARINITIALSTEP, "OnInitialStepTool",
               "add_initial_step", _("Create a new initial step")),
-             (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, 
-              ID_PLCOPENEDITOREDITORTOOLBARSTEP, "OnStepTool", 
+             (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
+              ID_PLCOPENEDITOREDITORTOOLBARSTEP, "OnStepTool",
               "add_step", _("Create a new step")),
-             (True, FREEDRAWING_MODE, 
-              ID_PLCOPENEDITOREDITORTOOLBARTRANSITION, "OnTransitionTool", 
+             (True, FREEDRAWING_MODE,
+              ID_PLCOPENEDITOREDITORTOOLBARTRANSITION, "OnTransitionTool",
               "add_transition", _("Create a new transition")),
-             (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, 
-              ID_PLCOPENEDITOREDITORTOOLBARACTIONBLOCK, "OnActionBlockTool", 
+             (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
+              ID_PLCOPENEDITOREDITORTOOLBARACTIONBLOCK, "OnActionBlockTool",
               "add_action", _("Create a new action block")),
-             (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, 
-              ID_PLCOPENEDITOREDITORTOOLBARDIVERGENCE, "OnDivergenceTool", 
+             (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
+              ID_PLCOPENEDITOREDITORTOOLBARDIVERGENCE, "OnDivergenceTool",
               "add_divergence", _("Create a new divergence")),
-             (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, 
-              ID_PLCOPENEDITOREDITORTOOLBARJUMP, "OnJumpTool", 
+             (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
+              ID_PLCOPENEDITOREDITORTOOLBARJUMP, "OnJumpTool",
               "add_jump", _("Create a new jump")),
-             (True, FREEDRAWING_MODE, 
-              ID_PLCOPENEDITOREDITORTOOLBARVARIABLE, "OnVariableTool", 
+             (True, FREEDRAWING_MODE,
+              ID_PLCOPENEDITOREDITORTOOLBARVARIABLE, "OnVariableTool",
               "add_variable", _("Create a new variable")),
-             (True, FREEDRAWING_MODE, 
-              ID_PLCOPENEDITOREDITORTOOLBARBLOCK, "OnBlockTool", 
+             (True, FREEDRAWING_MODE,
+              ID_PLCOPENEDITOREDITORTOOLBARBLOCK, "OnBlockTool",
               "add_block", _("Create a new block")),
-             (True, FREEDRAWING_MODE, 
-              ID_PLCOPENEDITOREDITORTOOLBARCONNECTION, "OnConnectionTool", 
+             (True, FREEDRAWING_MODE,
+              ID_PLCOPENEDITOREDITORTOOLBARCONNECTION, "OnConnectionTool",
               "add_connection", _("Create a new connection")),
-             (True, FREEDRAWING_MODE, 
-              ID_PLCOPENEDITOREDITORTOOLBARPOWERRAIL, "OnPowerRailTool", 
+             (True, FREEDRAWING_MODE,
+              ID_PLCOPENEDITOREDITORTOOLBARPOWERRAIL, "OnPowerRailTool",
               "add_powerrail", _("Create a new power rail")),
-             (True, FREEDRAWING_MODE, 
-              ID_PLCOPENEDITOREDITORTOOLBARCONTACT, "OnContactTool", 
+             (True, FREEDRAWING_MODE,
+              ID_PLCOPENEDITOREDITORTOOLBARCONTACT, "OnContactTool",
               "add_contact", _("Create a new contact"))],
     "ST"  : [],
     "IL"  : [],
@@ -185,7 +185,7 @@
     else:
         parent.Append(helpString=help, id=id, kind=kind, item=text)
 
-[TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, PROJECTTREE, 
+[TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, PROJECTTREE,
  POUINSTANCEVARIABLESPANEL, LIBRARYTREE, SCALING, PAGETITLES
 ] = range(10)
 
@@ -225,33 +225,33 @@
             others = [t for t in tabs if t != tab]
             others.sort(lambda x,y: cmp(x["pos"][0], y["pos"][0]))
             for other in others:
-                if (other["pos"][1] == tab["pos"][1] and 
+                if (other["pos"][1] == tab["pos"][1] and
                     other["size"][1] == tab["size"][1] and
                     other["pos"][0] == tab["pos"][0] + tab["size"][0] + TAB_BORDER):
-                    
+
                     tab["size"] = (tab["size"][0] + other["size"][0] + TAB_BORDER, tab["size"][1])
                     tab["pages"].extend(other["pages"])
                     tabs.remove(other)
-                    
+
                     if tab["size"][0] == rect.width:
                         return True
-                    
+
         elif tab["pos"][1] == rect.y:
             others = [t for t in tabs if t != tab]
             others.sort(lambda x,y: cmp(x["pos"][1], y["pos"][1]))
             for other in others:
-                if (other["pos"][0] == tab["pos"][0] and 
+                if (other["pos"][0] == tab["pos"][0] and
                     other["size"][0] == tab["size"][0] and
                     other["pos"][1] == tab["pos"][1] + tab["size"][1] + TAB_BORDER):
-                    
+
                     tab["size"] = (tab["size"][0], tab["size"][1] + other["size"][1] + TAB_BORDER)
                     tab["pages"].extend(other["pages"])
                     tabs.remove(other)
-                    
+
                     if tab["size"][1] == rect.height:
                         return True
     return False
-    
+
 def ComputeTabsLayout(tabs, rect):
     if len(tabs) == 0:
         return tabs
@@ -264,27 +264,27 @@
         if tab["size"][0] == rect.width:
             if tab["pos"][1] == rect.y:
                 split = (wx.TOP, float(tab["size"][1]) / float(rect.height))
-                split_rect = wx.Rect(rect.x, rect.y + tab["size"][1] + TAB_BORDER, 
+                split_rect = wx.Rect(rect.x, rect.y + tab["size"][1] + TAB_BORDER,
                                      rect.width, rect.height - tab["size"][1] - TAB_BORDER)
             elif tab["pos"][1] == rect.height + 1 - tab["size"][1]:
                 split = (wx.BOTTOM, 1.0 - float(tab["size"][1]) / float(rect.height))
-                split_rect = wx.Rect(rect.x, rect.y, 
+                split_rect = wx.Rect(rect.x, rect.y,
                                      rect.width, rect.height - tab["size"][1] - TAB_BORDER)
             break
         elif tab["size"][1] == rect.height:
             if tab["pos"][0] == rect.x:
                 split = (wx.LEFT, float(tab["size"][0]) / float(rect.width))
-                split_rect = wx.Rect(rect.x + tab["size"][0] + TAB_BORDER, rect.y, 
+                split_rect = wx.Rect(rect.x + tab["size"][0] + TAB_BORDER, rect.y,
                                      rect.width - tab["size"][0] - TAB_BORDER, rect.height)
             elif tab["pos"][0] == rect.width + 1 - tab["size"][0]:
                 split = (wx.RIGHT, 1.0 - float(tab["size"][0]) / float(rect.width))
-                split_rect = wx.Rect(rect.x, rect.y, 
+                split_rect = wx.Rect(rect.x, rect.y,
                                      rect.width - tab["size"][0] - TAB_BORDER, rect.height)
             break
     if split != None:
         split_tab = tabs.pop(idx)
         return {"split": split,
-                "tab": split_tab, 
+                "tab": split_tab,
                 "others": ComputeTabsLayout(tabs, split_rect)}
     else:
         if SimplifyTabLayout(tabs, rect):
@@ -298,7 +298,7 @@
 UNEDITABLE_NAMES_DICT = dict([(_(name), name) for name in UNEDITABLE_NAMES])
 
 class IDEFrame(wx.Frame):
-    
+
     # Compatibility function for wx versions < 2.6
     if wx.VERSION < (2, 6, 0):
         def Bind(self, event, function, id = None):
@@ -306,7 +306,7 @@
                 event(self, id, function)
             else:
                 event(self, function)
-    
+
     def _init_coll_MenuBar_Menus(self, parent):
         parent.Append(menu=self.FileMenu, title=_(u'&File'))
         parent.Append(menu=self.EditMenu, title=_(u'&Edit'))
@@ -315,7 +315,7 @@
 
     def _init_coll_FileMenu_Items(self, parent):
         pass
-    
+
     def _init_coll_AddMenu_Items(self, parent, add_config=True):
         AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUADDDATATYPE,
               kind=wx.ITEM_NORMAL, text=_(u'&Data Type'))
@@ -330,7 +330,7 @@
         if add_config:
             AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUADDCONFIGURATION,
                   kind=wx.ITEM_NORMAL, text=_(u'&Configuration'))
-    
+
     def _init_coll_EditMenu_Items(self, parent):
         AppendMenu(parent, help='', id=wx.ID_UNDO,
               kind=wx.ITEM_NORMAL, text=_(u'Undo') + '\tCTRL+Z')
@@ -371,13 +371,13 @@
         self.Bind(wx.EVT_MENU, self.OnCopyMenu, id=wx.ID_COPY)
         self.Bind(wx.EVT_MENU, self.OnPasteMenu, id=wx.ID_PASTE)
         self.Bind(wx.EVT_MENU, self.OnFindMenu, id=wx.ID_FIND)
-        self.Bind(wx.EVT_MENU, self.OnFindNextMenu, 
+        self.Bind(wx.EVT_MENU, self.OnFindNextMenu,
               id=ID_PLCOPENEDITOREDITMENUFINDNEXT)
-        self.Bind(wx.EVT_MENU, self.OnFindPreviousMenu, 
+        self.Bind(wx.EVT_MENU, self.OnFindPreviousMenu,
               id=ID_PLCOPENEDITOREDITMENUFINDPREVIOUS)
-        self.Bind(wx.EVT_MENU, self.OnSearchInProjectMenu, 
+        self.Bind(wx.EVT_MENU, self.OnSearchInProjectMenu,
               id=ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT)
-        self.Bind(wx.EVT_MENU, self.OnSearchInProjectMenu, 
+        self.Bind(wx.EVT_MENU, self.OnSearchInProjectMenu,
               id=ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT)
         self.Bind(wx.EVT_MENU, self.OnAddDataTypeMenu,
               id=ID_PLCOPENEDITOREDITMENUADDDATATYPE)
@@ -387,13 +387,13 @@
               id=ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK)
         self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction("program"),
               id=ID_PLCOPENEDITOREDITMENUADDPROGRAM)
-        self.Bind(wx.EVT_MENU, self.AddResourceMenu, 
+        self.Bind(wx.EVT_MENU, self.AddResourceMenu,
               id=ID_PLCOPENEDITOREDITMENUADDRESOURCE)
         self.Bind(wx.EVT_MENU, self.OnAddConfigurationMenu,
               id=ID_PLCOPENEDITOREDITMENUADDCONFIGURATION)
         self.Bind(wx.EVT_MENU, self.OnSelectAllMenu, id=wx.ID_SELECTALL)
         self.Bind(wx.EVT_MENU, self.OnDeleteMenu, id=wx.ID_DELETE)
-        
+
         self.AddToMenuToolBar([(wx.ID_UNDO, "undo", _(u'Undo'), None),
                                (wx.ID_REDO, "redo", _(u'Redo'), None),
                                None,
@@ -417,16 +417,16 @@
             AppendMenu(zoommenu, help='', id=new_id,
                   kind=wx.ITEM_RADIO, text=str(int(round(value * 100))) + "%")
             self.Bind(wx.EVT_MENU, self.GenerateZoomFunction(idx), id=new_id)
-        
+
         parent.AppendSeparator()
         AppendMenu(parent, help='', id=ID_PLCOPENEDITORDISPLAYMENURESETPERSPECTIVE,
               kind=wx.ITEM_NORMAL, text=_(u'Reset Perspective'))
         self.Bind(wx.EVT_MENU, self.OnResetPerspective, id=ID_PLCOPENEDITORDISPLAYMENURESETPERSPECTIVE)
-        
+
         self.Bind(wx.EVT_MENU, self.OnRefreshMenu, id=wx.ID_REFRESH)
         if self.EnableDebug:
             self.Bind(wx.EVT_MENU, self.OnClearErrorsMenu, id=wx.ID_CLEAR)
-            
+
     def _init_coll_HelpMenu_Items(self, parent):
         pass
 
@@ -437,7 +437,7 @@
         self.EditMenu = wx.Menu(title='')
         self.DisplayMenu = wx.Menu(title='')
         self.HelpMenu = wx.Menu(title='')
-        
+
         self._init_coll_MenuBar_Menus(self.MenuBar)
         self._init_coll_FileMenu_Items(self.FileMenu)
         self._init_coll_EditMenu_Items(self.EditMenu)
@@ -450,49 +450,49 @@
               style=wx.DEFAULT_FRAME_STYLE)
         self.SetClientSize(wx.Size(1000, 600))
         self.Bind(wx.EVT_ACTIVATE, self.OnActivated)
-        
+
         self.TabsImageList = wx.ImageList(31, 16)
         self.TabsImageListIndexes = {}
-        
+
         #-----------------------------------------------------------------------
         #                          Creating main structure
         #-----------------------------------------------------------------------
-        
+
         self.AUIManager = wx.aui.AuiManager(self)
         self.AUIManager.SetDockSizeConstraint(0.5, 0.5)
         self.Panes = {}
-        
+
         self.LeftNoteBook = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORLEFTNOTEBOOK,
               style=wx.aui.AUI_NB_TOP|wx.aui.AUI_NB_TAB_SPLIT|wx.aui.AUI_NB_TAB_MOVE|
                     wx.aui.AUI_NB_SCROLL_BUTTONS|wx.aui.AUI_NB_TAB_EXTERNAL_MOVE)
-        self.LeftNoteBook.Bind(wx.aui.EVT_AUINOTEBOOK_ALLOW_DND, 
+        self.LeftNoteBook.Bind(wx.aui.EVT_AUINOTEBOOK_ALLOW_DND,
                 self.OnAllowNotebookDnD)
-        self.AUIManager.AddPane(self.LeftNoteBook, 
+        self.AUIManager.AddPane(self.LeftNoteBook,
               wx.aui.AuiPaneInfo().Name("ProjectPane").
               Left().Layer(1).
               BestSize(wx.Size(300, 500)).CloseButton(False))
-        
+
         self.BottomNoteBook = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORBOTTOMNOTEBOOK,
               style=wx.aui.AUI_NB_TOP|wx.aui.AUI_NB_TAB_SPLIT|wx.aui.AUI_NB_TAB_MOVE|
                     wx.aui.AUI_NB_SCROLL_BUTTONS|wx.aui.AUI_NB_TAB_EXTERNAL_MOVE)
-        self.BottomNoteBook.Bind(wx.aui.EVT_AUINOTEBOOK_ALLOW_DND, 
+        self.BottomNoteBook.Bind(wx.aui.EVT_AUINOTEBOOK_ALLOW_DND,
                 self.OnAllowNotebookDnD)
-        self.AUIManager.AddPane(self.BottomNoteBook, 
+        self.AUIManager.AddPane(self.BottomNoteBook,
               wx.aui.AuiPaneInfo().Name("ResultPane").
               Bottom().Layer(0).
               BestSize(wx.Size(800, 300)).CloseButton(False))
-        
+
         self.RightNoteBook = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORRIGHTNOTEBOOK,
               style=wx.aui.AUI_NB_TOP|wx.aui.AUI_NB_TAB_SPLIT|wx.aui.AUI_NB_TAB_MOVE|
                     wx.aui.AUI_NB_SCROLL_BUTTONS|wx.aui.AUI_NB_TAB_EXTERNAL_MOVE)
-        self.RightNoteBook.Bind(wx.aui.EVT_AUINOTEBOOK_ALLOW_DND, 
+        self.RightNoteBook.Bind(wx.aui.EVT_AUINOTEBOOK_ALLOW_DND,
                 self.OnAllowNotebookDnD)
-        self.AUIManager.AddPane(self.RightNoteBook, 
+        self.AUIManager.AddPane(self.RightNoteBook,
               wx.aui.AuiPaneInfo().Name("LibraryPane").
               Right().Layer(0).
               BestSize(wx.Size(250, 400)).CloseButton(False))
-        
-        self.TabsOpened = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORTABSOPENED, 
+
+        self.TabsOpened = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORTABSOPENED,
               style=wx.aui.AUI_NB_DEFAULT_STYLE|wx.aui.AUI_NB_WINDOWLIST_BUTTON)
         self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGING,
               self.OnPouSelectedChanging)
@@ -502,21 +502,21 @@
               self.OnPageClose)
         self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_END_DRAG,
               self.OnPageDragged)
-        self.AUIManager.AddPane(self.TabsOpened, 
+        self.AUIManager.AddPane(self.TabsOpened,
               wx.aui.AuiPaneInfo().CentrePane().Name("TabsPane"))
-        
+
         #-----------------------------------------------------------------------
         #                    Creating PLCopen Project Types Tree
         #-----------------------------------------------------------------------
-        
+
         self.MainTabs = {}
-        
+
         self.ProjectPanel = wx.SplitterWindow(id=ID_PLCOPENEDITORPROJECTPANEL,
                   name='ProjectPanel', parent=self.LeftNoteBook, point=wx.Point(0, 0),
                   size=wx.Size(0, 0), style=wx.SP_3D)
-        
+
         self.ProjectTree = CustomTree(id=ID_PLCOPENEDITORPROJECTTREE,
-                  name='ProjectTree', parent=self.ProjectPanel, 
+                  name='ProjectTree', parent=self.ProjectPanel,
                   pos=wx.Point(0, 0), size=wx.Size(0, 0),
                   style=wx.SUNKEN_BORDER,
                   agwStyle=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.TR_EDIT_LABELS)
@@ -539,22 +539,22 @@
         self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnProjectTreeItemActivated,
               id=ID_PLCOPENEDITORPROJECTTREE)
         self.ProjectTree.Bind(wx.EVT_MOTION, self.OnProjectTreeMotion)
-        
+
         #-----------------------------------------------------------------------
         #        Creating PLCopen Project POU Instance Variables Panel
         #-----------------------------------------------------------------------
-        
+
         self.PouInstanceVariablesPanel = PouInstanceVariablesPanel(self.ProjectPanel, self, self.Controler, self.EnableDebug)
-        
+
         self.MainTabs["ProjectPanel"] = (self.ProjectPanel, _("Project"))
         self.LeftNoteBook.AddPage(*self.MainTabs["ProjectPanel"])
-        
+
         self.ProjectPanel.SplitHorizontally(self.ProjectTree, self.PouInstanceVariablesPanel, 300)
-        
+
         #-----------------------------------------------------------------------
         #                            Creating Tool Bar
         #-----------------------------------------------------------------------
-        
+
         MenuToolBar = wx.ToolBar(self, ID_PLCOPENEDITOREDITORMENUTOOLBAR, wx.DefaultPosition, wx.DefaultSize,
                 wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER)
         MenuToolBar.SetToolBitmapSize(wx.Size(25, 25))
@@ -564,11 +564,11 @@
                   Name("MenuToolBar").Caption(_("Menu ToolBar")).
                   ToolbarPane().Top().
                   LeftDockable(False).RightDockable(False))
-        
+
         EditorToolBar = wx.ToolBar(self, ID_PLCOPENEDITOREDITORTOOLBAR, wx.DefaultPosition, wx.DefaultSize,
                 wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER)
         EditorToolBar.SetToolBitmapSize(wx.Size(25, 25))
-        EditorToolBar.AddRadioTool(ID_PLCOPENEDITOREDITORTOOLBARSELECTION, 
+        EditorToolBar.AddRadioTool(ID_PLCOPENEDITOREDITORTOOLBARSELECTION,
               GetBitmap("select"), wx.NullBitmap, _("Select an object"))
         EditorToolBar.Realize()
         self.Panes["EditorToolBar"] = EditorToolBar
@@ -576,39 +576,39 @@
                   Name("EditorToolBar").Caption(_("Editor ToolBar")).
                   ToolbarPane().Top().Position(1).
                   LeftDockable(False).RightDockable(False))
-            
-        self.Bind(wx.EVT_MENU, self.OnSelectionTool, 
+
+        self.Bind(wx.EVT_MENU, self.OnSelectionTool,
               id=ID_PLCOPENEDITOREDITORTOOLBARSELECTION)
-        
+
         #-----------------------------------------------------------------------
         #                            Creating Search Panel
         #-----------------------------------------------------------------------
-        
+
         self.SearchResultPanel = SearchResultPanel(self.BottomNoteBook, self)
         self.MainTabs["SearchResultPanel"] = (self.SearchResultPanel, _("Search"))
         self.BottomNoteBook.AddPage(*self.MainTabs["SearchResultPanel"])
-        
+
         #-----------------------------------------------------------------------
         #                            Creating Library Panel
         #-----------------------------------------------------------------------
-        
+
         self.LibraryPanel = LibraryPanel(self, True)
         self.MainTabs["LibraryPanel"] = (self.LibraryPanel, _("Library"))
         self.RightNoteBook.AddPage(*self.MainTabs["LibraryPanel"])
-                
+
         self._init_utils()
         self.SetMenuBar(self.MenuBar)
-                
+
         if self.EnableDebug:
             self.DebugVariablePanel = DebugVariablePanel(self.RightNoteBook, self.Controler, self)
             self.MainTabs["DebugVariablePanel"] = (self.DebugVariablePanel, _("Debugger"))
             self.RightNoteBook.AddPage(*self.MainTabs["DebugVariablePanel"])
-        
+
         self.AUIManager.Update()
-    
+
         self.FindDialog = FindInPouDialog(self)
         self.FindDialog.Hide()
-    
+
     ## Constructor of the PLCOpenEditor class.
     #  @param parent The parent window.
     #  @param controler The controler been used by PLCOpenEditor (default: None).
@@ -618,17 +618,17 @@
         self.Controler = None
         self.Config = wx.ConfigBase.Get()
         self.EnableDebug = enable_debug
-        
+
         self._init_ctrls(parent)
-        
+
         # Define Tree item icon list
         self.TreeImageList = wx.ImageList(16, 16)
         self.TreeImageDict = {}
-        
+
         # Icons for languages
         for language in LANGUAGES:
             self.TreeImageDict[language] = self.TreeImageList.Add(GetBitmap(language))
-            
+
         # Icons for other items
         for imgname, itemtype in [
             #editables
@@ -658,11 +658,11 @@
             ("RESOURCES",      ITEM_RESOURCES),
             ("PROPERTIES",     ITEM_PROPERTIES)]:
             self.TreeImageDict[itemtype] = self.TreeImageList.Add(GetBitmap(imgname))
-        
+
         # Assign icon list to TreeCtrls
         self.ProjectTree.SetImageList(self.TreeImageList)
         self.PouInstanceVariablesPanel.SetTreeImageList(self.TreeImageList)
-        
+
         self.CurrentEditorToolBar = []
         self.CurrentMenu = None
         self.SelectedItem = None
@@ -672,7 +672,7 @@
         self.DrawingMode = FREEDRAWING_MODE
         #self.DrawingMode = DRIVENDRAWING_MODE
         self.AuiTabCtrl = []
-        
+
         # Save default perspective
         notebooks = {}
         for notebook, entry_name in [(self.LeftNoteBook, "leftnotebook"),
@@ -683,8 +683,8 @@
             "perspective": self.AUIManager.SavePerspective(),
             "notebooks": notebooks,
         }
-        
-        
+
+
         # Initialize Printing configuring elements
         self.PrintData = wx.PrintData()
         self.PrintData.SetPaperId(wx.PAPER_A4)
@@ -692,17 +692,17 @@
         self.PageSetupData = wx.PageSetupDialogData(self.PrintData)
         self.PageSetupData.SetMarginTopLeft(wx.Point(10, 15))
         self.PageSetupData.SetMarginBottomRight(wx.Point(10, 20))
-        
+
         self.SetRefreshFunctions()
         self.SetDeleteFunctions()
-    
+
     def __del__(self):
         self.FindDialog.Destroy()
-    
+
     def Show(self):
         wx.Frame.Show(self)
         wx.CallAfter(self.RestoreLastState)
-    
+
     def OnActivated(self, event):
         if event.GetActive():
             wx.CallAfter(self._Refresh, TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU)
@@ -724,7 +724,7 @@
             if page_ref == tab:
                 return ("main", page_name)
         return None
-    
+
     def SaveTabLayout(self, notebook):
         tabs = []
         for child in notebook.GetChildren():
@@ -744,7 +744,7 @@
         tabs.sort(lambda x, y: cmp(x["pos"], y["pos"]))
         size = notebook.GetSize()
         return ComputeTabsLayout(tabs, wx.Rect(1, 1, size[0] - NOTEBOOK_BORDER, size[1] - NOTEBOOK_BORDER))
-    
+
     def LoadTab(self, notebook, page_infos):
         if page_infos[0] == "main":
             infos = self.MainTabs.get(page_infos[1])
@@ -764,21 +764,21 @@
             if instance_infos is not None:
                 return notebook.GetPageIndex(self.OpenDebugViewer(instance_infos["class"], instance_path, instance_infos["type"]))
         return None
-            
+
     def LoadTabLayout(self, notebook, tabs, mode="all", first_index=None):
         if isinstance(tabs, ListType):
             if len(tabs) == 0:
                 return
             raise ValueError, "Not supported"
-        
+
         if tabs.has_key("split"):
             self.LoadTabLayout(notebook, tabs["others"])
-            
+
             split_dir, split_ratio = tabs["split"]
             first_index = self.LoadTabLayout(notebook, tabs["tab"], mode="first")
             notebook.Split(first_index, split_dir)
             self.LoadTabLayout(notebook, tabs["tab"], mode="others", first_index=first_index)
-            
+
         elif mode == "first":
             return self.LoadTab(notebook, tabs["pages"][0][0])
         else:
@@ -793,39 +793,39 @@
                     selected = page_idx
             if selected is not None:
                 wx.CallAfter(notebook.SetSelection, selected)
-    
+
     def ResetPerspective(self):
         if self.DefaultPerspective is not None:
             self.AUIManager.LoadPerspective(self.DefaultPerspective["perspective"])
-        
+
             for notebook in [self.LeftNoteBook, self.BottomNoteBook, self.RightNoteBook]:
                 for idx in xrange(notebook.GetPageCount()):
                     notebook.RemovePage(0)
-                        
+
             notebooks = self.DefaultPerspective["notebooks"]
             for notebook, entry_name in [(self.LeftNoteBook, "leftnotebook"),
                                          (self.BottomNoteBook, "bottomnotebook"),
                                          (self.RightNoteBook, "rightnotebook")]:
                 self.LoadTabLayout(notebook, notebooks.get(entry_name))
-    
+
             self._Refresh(EDITORTOOLBAR)
-    
+
     def RestoreLastState(self):
         frame_size = None
         if self.Config.HasEntry("framesize"):
             frame_size = cPickle.loads(str(self.Config.Read("framesize")))
-        
+
         if frame_size is None:
             self.Maximize()
         else:
             self.SetClientSize(frame_size)
-        
+
     def SaveLastState(self):
         if not self.IsMaximized():
             self.Config.Write("framesize", cPickle.dumps(self.GetClientSize()))
         elif self.Config.HasEntry("framesize"):
             self.Config.DeleteEntry("framesize")
-        
+
         self.Config.Flush()
 
 #-------------------------------------------------------------------------------
@@ -840,7 +840,7 @@
             EDITMENU : self.RefreshEditMenu,
             DISPLAYMENU : self.RefreshDisplayMenu,
             PROJECTTREE : self.RefreshProjectTree,
-            POUINSTANCEVARIABLESPANEL : self.RefreshPouInstanceVariablesPanel, 
+            POUINSTANCEVARIABLESPANEL : self.RefreshPouInstanceVariablesPanel,
             LIBRARYTREE : self.RefreshLibraryPanel,
             SCALING : self.RefreshScaling,
             PAGETITLES: self.RefreshPageTitles}
@@ -861,9 +861,9 @@
         selected = self.TabsOpened.GetSelection()
         if selected > -1:
             window = self.TabsOpened.GetPage(selected)
-            
+
             if window.CheckSaveBeforeClosing():
-                
+
                 # Refresh all window elements that have changed
                 wx.CallAfter(self._Refresh, TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU)
                 wx.CallAfter(self.RefreshTabCtrlEvent)
@@ -871,7 +871,7 @@
                 event.Skip()
             else:
                 event.Veto()
-        
+
 
     def GetCopyBuffer(self, primary_selection=False):
         data = None
@@ -885,7 +885,7 @@
                 data = dataobj.GetText()
             wx.TheClipboard.Close()
         return data
-        
+
     def SetCopyBuffer(self, text, primary_selection=False):
         if primary_selection and wx.Platform == '__WXMSW__':
             return
@@ -916,14 +916,14 @@
             new_values["creationDateTime"] = old_values["creationDateTime"]
             if new_values != old_values:
                 self.Controler.SetProjectProperties(None, new_values)
-                self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, 
+                self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU,
                               PROJECTTREE, POUINSTANCEVARIABLESPANEL, SCALING)
         dialog.Destroy()
 
 #-------------------------------------------------------------------------------
 #                            Notebook Unified Functions
 #-------------------------------------------------------------------------------
-    
+
     ## Function that add a tab in Notebook, calling refresh for tab DClick event
     # for wx.aui.AUINotebook.
     #  @param window Panel to display in tab.
@@ -931,7 +931,7 @@
     def AddPage(self, window, text):
         self.TabsOpened.AddPage(window, text)
         self.RefreshTabCtrlEvent()
-    
+
     ## Function that add a tab in Notebook, calling refresh for tab DClick event
     # for wx.aui.AUINotebook.
     #  @param window Panel to display in tab.
@@ -941,16 +941,16 @@
             if self.TabsOpened.GetPage(idx) == window:
                 self.TabsOpened.DeletePage(idx)
                 self.RefreshTabCtrlEvent()
-                return 
-        
-    ## Function that fix difference in deleting all tabs between 
+                return
+
+    ## Function that fix difference in deleting all tabs between
     # wx.Notebook and wx.aui.AUINotebook.
     def DeleteAllPages(self):
         for idx in xrange(self.TabsOpened.GetPageCount()):
             self.TabsOpened.DeletePage(0)
         self.RefreshTabCtrlEvent()
 
-    ## Function that fix difference in setting picture on tab between 
+    ## Function that fix difference in setting picture on tab between
     # wx.Notebook and wx.aui.AUINotebook.
     #  @param idx Tab index.
     #  @param bitmap wx.Bitmap to define on tab.
@@ -980,12 +980,12 @@
                 self.SaveProject()
             elif answer == wx.ID_CANCEL:
                 return False
-        
+
         for idx in xrange(self.TabsOpened.GetPageCount()):
             window = self.TabsOpened.GetPage(idx)
             if not window.CheckSaveBeforeClosing():
                 return False
-        
+
         return True
 
 #-------------------------------------------------------------------------------
@@ -1025,7 +1025,7 @@
         dialog.Destroy()
 
     def OnPreviewMenu(self, event):
-        selected = self.TabsOpened.GetSelection()        
+        selected = self.TabsOpened.GetSelection()
         if selected != -1:
             window = self.TabsOpened.GetPage(selected)
             data = wx.PrintDialogData(self.PrintData)
@@ -1040,15 +1040,15 @@
                 preview_frame = wx.PreviewFrame(preview, self, _("Print preview"), style=wx.DEFAULT_FRAME_STYLE|wx.FRAME_FLOAT_ON_PARENT)
 
                 preview_frame.Initialize()
-                
+
                 preview_canvas = preview.GetCanvas()
                 preview_canvas.SetMinSize(preview_canvas.GetVirtualSize())
                 preview_frame.Fit()
-                
+
                 preview_frame.Show(True)
 
     def OnPrintMenu(self, event):
-        selected = self.TabsOpened.GetSelection()        
+        selected = self.TabsOpened.GetSelection()
         if selected != -1:
             window = self.TabsOpened.GetPage(selected)
             dialog_data = wx.PrintDialogData(self.PrintData)
@@ -1058,7 +1058,7 @@
             margins = (self.PageSetupData.GetMarginTopLeft(), self.PageSetupData.GetMarginBottomRight())
             printer = wx.Printer(dialog_data)
             printout = GraphicPrintout(window, page_size, margins)
-            
+
             if not printer.Print(self, printout, True) and printer.GetLastError() != wx.PRINTER_CANCELLED:
                 self.ShowErrorMessage(_("There was a problem printing.\nPerhaps your current printer is not set correctly?"))
             printout.Destroy()
@@ -1087,12 +1087,12 @@
             self.EditMenu.Enable(wx.ID_REDO, redo)
             MenuToolBar.EnableTool(wx.ID_REDO, redo)
             #self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, True)
-            #self.EditMenu.Check(ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, 
+            #self.EditMenu.Check(ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO,
             #                self.Controler.IsProjectBufferEnabled())
             self.EditMenu.Enable(wx.ID_FIND, selected > -1)
-            self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUFINDNEXT, 
+            self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUFINDNEXT,
                   selected > -1 and self.SearchParams is not None)
-            self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUFINDPREVIOUS, 
+            self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUFINDPREVIOUS,
                   selected > -1 and self.SearchParams is not None)
             self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT, True)
             MenuToolBar.EnableTool(ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT, True)
@@ -1138,7 +1138,7 @@
             MenuToolBar.EnableTool(ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT, False)
             self.EditMenu.Enable(wx.ID_ADD, False)
             self.EditMenu.Enable(wx.ID_DELETE, False)
-    
+
     def CloseTabsWithoutModel(self, refresh=True):
         idxs = range(self.TabsOpened.GetPageCount())
         idxs.reverse()
@@ -1156,9 +1156,9 @@
             window.Undo()
         else:
             self.Controler.LoadPrevious()
-        self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE, 
-                      SCALING, PAGETITLES)    
-    
+        self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE,
+                      SCALING, PAGETITLES)
+
     def OnRedoMenu(self, event):
         selected = self.TabsOpened.GetSelection()
         if selected != -1:
@@ -1166,9 +1166,9 @@
             window.Redo()
         else:
             self.Controler.LoadNext()
-        self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE, 
+        self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE,
                       SCALING, PAGETITLES)
-    
+
     def OnEnableUndoRedoMenu(self, event):
         self.Controler.EnableProjectBuffer(event.IsChecked())
         self.RefreshEditMenu()
@@ -1187,14 +1187,14 @@
             control.SetSelection(0, control.GetLastPosition())
         elif isinstance(control, wx.ComboBox):
             control.SetMark(0, control.GetLastPosition() + 1)
-    
+
     def SetDeleteFunctions(self):
         self.DeleteFunctions = {
             ITEM_DATATYPE: GetDeleteElementFunction(
-                    PLCControler.ProjectRemoveDataType, 
+                    PLCControler.ProjectRemoveDataType,
                     check_function=self.CheckDataTypeIsUsedBeforeDeletion),
             ITEM_POU: GetDeleteElementFunction(
-                    PLCControler.ProjectRemovePou, 
+                    PLCControler.ProjectRemovePou,
                     check_function=self.CheckPouIsUsedBeforeDeletion),
             ITEM_TRANSITION: GetDeleteElementFunction(
                     PLCControler.ProjectRemovePouTransition, ITEM_POU),
@@ -1205,7 +1205,7 @@
             ITEM_RESOURCE: GetDeleteElementFunction(
                     PLCControler.ProjectRemoveConfigurationResource, ITEM_CONFIGURATION)
         }
-    
+
     def OnDeleteMenu(self, event):
         window = self.FindFocus()
         if window == self.ProjectTree or window is None:
@@ -1215,7 +1215,7 @@
                 if function is not None:
                     function(self, selected)
                     self.CloseTabsWithoutModel()
-                    self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, PROJECTTREE, 
+                    self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, PROJECTTREE,
                                   POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
         elif isinstance(window, (Viewer, TextViewer)):
             event = wx.KeyEvent(wx.EVT_CHAR._getEvtType())
@@ -1225,18 +1225,18 @@
     def OnFindMenu(self, event):
         if not self.FindDialog.IsShown():
             self.FindDialog.Show()
-    
+
     def CloseFindInPouDialog(self):
         selected = self.TabsOpened.GetSelection()
         if selected == -1 and self.FindDialog.IsShown():
             self.FindDialog.Hide()
-    
+
     def OnFindNextMenu(self, event):
         self.FindInPou(1)
-    
+
     def OnFindPreviousMenu(self, event):
         self.FindInPou(-1)
-    
+
     def FindInPou(self, direction, search_params=None):
         if search_params is not None:
             self.SearchParams = search_params
@@ -1244,7 +1244,7 @@
         if selected != -1:
             window = self.TabsOpened.GetPage(selected)
             window.Find(direction, self.SearchParams)
-    
+
     def OnSearchInProjectMenu(self, event):
         dialog = SearchInProjectDialog(self)
         if dialog.ShowModal() == wx.ID_OK:
@@ -1253,7 +1253,7 @@
             self.ClearSearchResults()
             self.SearchResultPanel.SetSearchResults(criteria, result)
             self.SelectTab(self.SearchResultPanel)
-            
+
 #-------------------------------------------------------------------------------
 #                             Display Menu Functions
 #-------------------------------------------------------------------------------
@@ -1284,7 +1284,7 @@
             if self.EnableDebug:
                 self.DisplayMenu.Enable(wx.ID_CLEAR, False)
             self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, False)
-        
+
     def OnRefreshMenu(self, event):
         self.RefreshEditor()
 
@@ -1308,14 +1308,14 @@
 #-------------------------------------------------------------------------------
 #                      Project Editor Panels Management Functions
 #-------------------------------------------------------------------------------
-    
+
     def OnPageDragged(self, event):
         wx.CallAfter(self.RefreshTabCtrlEvent)
         event.Skip()
-    
+
     def OnAllowNotebookDnD(self, event):
         event.Allow()
-    
+
     def RefreshTabCtrlEvent(self):
         auitabctrl = []
         for child in self.TabsOpened.GetChildren():
@@ -1329,11 +1329,11 @@
             if pane.IsMaximized():
                 self.AUIManager.RestorePane(pane)
             self.AUIManager.Update()
-    
+
     def EnsureTabVisible(self, tab):
         notebook = tab.GetParent()
         notebook.SetSelection(notebook.GetPageIndex(tab))
-    
+
     def OnPouSelectedChanging(self, event):
         selected = self.TabsOpened.GetSelection()
         if selected >= 0:
@@ -1341,7 +1341,7 @@
             if not window.IsDebugging():
                 window.ResetBuffer()
         event.Skip()
-    
+
     def OnPouSelectedChanged(self, event):
         selected = self.TabsOpened.GetSelection()
         if selected >= 0:
@@ -1361,7 +1361,7 @@
                 wx.CallAfter(self.PouInstanceVariablesPanel.SetPouType, tagname, instance_path)
         wx.CallAfter(self._Refresh, FILEMENU, EDITMENU, DISPLAYMENU, EDITORTOOLBAR)
         event.Skip()
-        
+
     def RefreshEditor(self):
         selected = self.TabsOpened.GetSelection()
         if selected >= 0:
@@ -1383,13 +1383,13 @@
                         window = child.GetWindowFromIdx(active_page)
                         window.RefreshView()
             self._Refresh(FILEMENU, EDITMENU, DISPLAYMENU, EDITORTOOLBAR)
-    
+
     def RefreshEditorNames(self, old_tagname, new_tagname):
         for i in xrange(self.TabsOpened.GetPageCount()):
             editor = self.TabsOpened.GetPage(i)
             if editor.GetTagName() == old_tagname:
                 editor.SetTagName(new_tagname)
-    
+
     def IsOpened(self, tagname):
         for idx in xrange(self.TabsOpened.GetPageCount()):
             if self.TabsOpened.GetPage(idx).IsViewing(tagname):
@@ -1429,7 +1429,7 @@
             tagname = item_infos.get("tagname", None)
         else:
             tagname = None
-        
+
         # Refresh treectrl items according to project infos
         infos = self.Controler.GetProjectInfos()
         root = self.ProjectTree.GetRootItem()
@@ -1437,7 +1437,7 @@
             root = self.ProjectTree.AddRoot(infos["name"])
         self.GenerateProjectTreeBranch(root, infos)
         self.ProjectTree.Expand(root)
-        
+
         # Select new item corresponding to previous selected item
         if tagname is not None:
             self.SelectProjectTreeItem(tagname)
@@ -1456,7 +1456,7 @@
         self.ProjectTree.SetItemTextColour(root, highlight_colours[1])
         self.ProjectTree.SetItemExtraImage(root, None)
         if infos["type"] == ITEM_POU:
-            self.ProjectTree.SetItemImage(root, 
+            self.ProjectTree.SetItemImage(root,
                 self.TreeImageDict[self.Controler.GetPouBodyType(infos["name"])])
             if item_alone:
                 self.ProjectTree.SetItemExtraImage(root, self.Controler.GetPouType(infos["name"]))
@@ -1466,8 +1466,8 @@
                 self.TreeImageDict[icon_name] = self.TreeImageList.Add(GetBitmap(icon_name))
             self.ProjectTree.SetItemImage(root, self.TreeImageDict[icon_name])
         elif self.TreeImageDict.has_key(infos["type"]):
-            self.ProjectTree.SetItemImage(root, self.TreeImageDict[infos["type"]])      
-        
+            self.ProjectTree.SetItemImage(root, self.TreeImageDict[infos["type"]])
+
         item, root_cookie = self.ProjectTree.GetFirstChild(root)
         for values in infos["values"]:
             if values["type"] not in ITEMS_UNEDITABLE or len(values["values"]) > 0:
@@ -1522,7 +1522,7 @@
         self.SelectedItem = None
 
     def OnProjectTreeBeginDrag(self, event):
-        selected_item = (self.SelectedItem 
+        selected_item = (self.SelectedItem
                          if self.SelectedItem is not None
                          else event.GetItem())
         if selected_item.IsOk() and self.ProjectTree.GetPyData(selected_item)["type"] == ITEM_POU:
@@ -1563,7 +1563,7 @@
                         abort = True
                     if not abort:
                         self.Controler.ChangeDataTypeName(old_name, new_name)
-                        self.RefreshEditorNames(self.Controler.ComputeDataTypeName(old_name), 
+                        self.RefreshEditorNames(self.Controler.ComputeDataTypeName(old_name),
                                                 self.Controler.ComputeDataTypeName(new_name))
                         self.RefreshPageTitles()
                 elif item_infos["type"] == ITEM_POU:
@@ -1577,7 +1577,7 @@
                         messageDialog.Destroy()
                     if not abort:
                         self.Controler.ChangePouName(old_name, new_name)
-                        self.RefreshEditorNames(self.Controler.ComputePouName(old_name), 
+                        self.RefreshEditorNames(self.Controler.ComputePouName(old_name),
                                                 self.Controler.ComputePouName(new_name))
                         self.RefreshLibraryPanel()
                         self.RefreshPageTitles()
@@ -1589,7 +1589,7 @@
                     else:
                         words = item_infos["tagname"].split("::")
                         self.Controler.ChangePouTransitionName(words[1], old_name, new_name)
-                        self.RefreshEditorNames(self.Controler.ComputePouTransitionName(words[1], old_name), 
+                        self.RefreshEditorNames(self.Controler.ComputePouTransitionName(words[1], old_name),
                                                 self.Controler.ComputePouTransitionName(words[1], new_name))
                         self.RefreshPageTitles()
                 elif item_infos["type"] == ITEM_ACTION:
@@ -1600,7 +1600,7 @@
                     else:
                         words = item_infos["tagname"].split("::")
                         self.Controler.ChangePouActionName(words[1], old_name, new_name)
-                        self.RefreshEditorNames(self.Controler.ComputePouActionName(words[1], old_name), 
+                        self.RefreshEditorNames(self.Controler.ComputePouActionName(words[1], old_name),
                                                 self.Controler.ComputePouActionName(words[1], new_name))
                         self.RefreshPageTitles()
                 elif item_infos["type"] == ITEM_CONFIGURATION:
@@ -1619,7 +1619,7 @@
                         messageDialog.Destroy()
                     if not abort:
                         self.Controler.ChangeConfigurationName(old_name, new_name)
-                        self.RefreshEditorNames(self.Controler.ComputeConfigurationName(old_name), 
+                        self.RefreshEditorNames(self.Controler.ComputeConfigurationName(old_name),
                                                 self.Controler.ComputeConfigurationName(new_name))
                         self.RefreshPageTitles()
                 elif item_infos["type"] == ITEM_RESOURCE:
@@ -1639,7 +1639,7 @@
                     if not abort:
                         words = item_infos["tagname"].split("::")
                         self.Controler.ChangeConfigurationResourceName(words[1], old_name, new_name)
-                        self.RefreshEditorNames(self.Controler.ComputeConfigurationResourceName(words[1], old_name), 
+                        self.RefreshEditorNames(self.Controler.ComputeConfigurationResourceName(words[1], old_name),
                                                 self.Controler.ComputeConfigurationResourceName(words[1], new_name))
                         self.RefreshPageTitles()
             if message or abort:
@@ -1653,7 +1653,7 @@
                 self.RefreshEditor()
                 self._Refresh(TITLE, FILEMENU, EDITMENU)
                 event.Skip()
-    
+
     def OnProjectTreeItemActivated(self, event):
         selected = event.GetItem()
         name = self.ProjectTree.GetItemText(selected)
@@ -1666,7 +1666,7 @@
                                     ITEM_TRANSITION, ITEM_ACTION]:
                 self.EditProjectElement(item_infos["type"], item_infos["tagname"])
             event.Skip()
-    
+
     def ProjectTreeItemSelect(self, select_item):
         if select_item is not None and select_item.IsOk():
             name = self.ProjectTree.GetItemText(select_item)
@@ -1676,14 +1676,14 @@
                                       ITEM_TRANSITION, ITEM_ACTION]:
                 self.EditProjectElement(item_infos["type"], item_infos["tagname"], True)
                 self.PouInstanceVariablesPanel.SetPouType(item_infos["tagname"])
-        
+
     def OnProjectTreeLeftUp(self, event):
         if self.SelectedItem is not None:
             self.ProjectTree.SelectItem(self.SelectedItem)
             self.ProjectTreeItemSelect(self.SelectedItem)
             self.ResetSelectedItem()
         event.Skip()
-    
+
     def OnProjectTreeMotion(self, event):
         if not event.Dragging():
             pt = wx.Point(event.GetX(), event.GetY())
@@ -1693,7 +1693,7 @@
                 if item != self.LastToolTipItem and self.LastToolTipItem is not None:
                     self.ProjectTree.SetToolTip(None)
                     self.LastToolTipItem = None
-                if (self.LastToolTipItem != item and 
+                if (self.LastToolTipItem != item and
                     item_infos["type"] in [ITEM_POU, ITEM_TRANSITION, ITEM_ACTION]):
                     bodytype = self.Controler.GetEditedElementBodyType(
                             item_infos["tagname"])
@@ -1708,21 +1708,21 @@
                     else:
                         block_type = "Action"
                     self.LastToolTipItem = item
-                    wx.CallAfter(self.ProjectTree.SetToolTipString, 
+                    wx.CallAfter(self.ProjectTree.SetToolTipString,
                         "%s : %s : %s" % (
                             block_type, bodytype, item_infos["name"]))
             elif self.LastToolTipItem is not None:
                 self.ProjectTree.SetToolTip(None)
                 self.LastToolTipItem = None
         event.Skip()
-    
+
     def OnProjectTreeItemChanging(self, event):
         if self.ProjectTree.GetPyData(event.GetItem())["type"] not in ITEMS_UNEDITABLE and self.SelectedItem is None:
             self.SelectedItem = event.GetItem()
             event.Veto()
         else:
             event.Skip()
-    
+
     def EditProjectElement(self, element, tagname, onlyopened = False):
         openedidx = self.IsOpened(tagname)
         if openedidx is not None:
@@ -1790,30 +1790,30 @@
                         window.SetFocus()
                 self.RefreshPageTitles()
             return new_window
-    
+
     def OnProjectTreeRightUp(self, event):
         item = event.GetItem()
         self.ProjectTree.SelectItem(item)
         self.ProjectTreeItemSelect(item)
         name = self.ProjectTree.GetItemText(item)
         item_infos = self.ProjectTree.GetPyData(item)
-        
+
         menu = None
         if item_infos["type"] in ITEMS_UNEDITABLE + [ITEM_PROJECT]:
             if item_infos["type"] == ITEM_PROJECT:
                 name = "Project"
             else:
                 name = UNEDITABLE_NAMES_DICT[name]
-            
+
             if name == "Data Types":
                 menu = wx.Menu(title='')
                 new_id = wx.NewId()
                 AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add DataType"))
                 self.Bind(wx.EVT_MENU, self.OnAddDataTypeMenu, id=new_id)
-            
+
             elif name in ["Functions", "Function Blocks", "Programs", "Project"]:
                 menu = wx.Menu(title='')
-                
+
                 if name != "Project":
                     new_id = wx.NewId()
                     AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add POU"))
@@ -1830,7 +1830,7 @@
                 new_id = wx.NewId()
                 AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Configuration"))
                 self.Bind(wx.EVT_MENU, self.OnAddConfigurationMenu, id=new_id)
-            
+
             elif name == "Transitions":
                 menu = wx.Menu(title='')
                 new_id = wx.NewId()
@@ -1841,7 +1841,7 @@
                     parent = self.ProjectTree.GetItemParent(parent)
                     parent_type = self.ProjectTree.GetPyData(parent)["type"]
                 self.Bind(wx.EVT_MENU, self.GenerateAddTransitionFunction(self.ProjectTree.GetItemText(parent)), id=new_id)
-            
+
             elif name == "Actions":
                 menu = wx.Menu(title='')
                 new_id = wx.NewId()
@@ -1852,7 +1852,7 @@
                     parent = self.ProjectTree.GetItemParent(parent)
                     parent_type = self.ProjectTree.GetPyData(parent)["type"]
                 self.Bind(wx.EVT_MENU, self.GenerateAddActionFunction(self.ProjectTree.GetItemText(parent)), id=new_id)
-            
+
             elif name == "Resources":
                 menu = wx.Menu(title='')
                 new_id = wx.NewId()
@@ -1871,7 +1871,7 @@
                     parent_name = self.ProjectTree.GetItemText(parent)
                 if parent_name is not None:
                     self.Bind(wx.EVT_MENU, self.GenerateAddResourceFunction(parent_name), id=new_id)
-            
+
         else:
             if item_infos["type"] == ITEM_POU:
                 menu = wx.Menu(title='')
@@ -1883,11 +1883,11 @@
                     AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Action"))
                     self.Bind(wx.EVT_MENU, self.GenerateAddActionFunction(name), id=new_id)
                     menu.AppendSeparator()
-    
+
                 new_id = wx.NewId()
                 AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Copy POU"))
                 self.Bind(wx.EVT_MENU, self.OnCopyPou, id=new_id)
-    
+
                 pou_type = self.Controler.GetPouType(name)
                 if pou_type in ["function", "functionBlock"]:
                     change_menu = wx.Menu(title='')
@@ -1902,27 +1902,27 @@
                 new_id = wx.NewId()
                 AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Rename"))
                 self.Bind(wx.EVT_MENU, self.OnRenamePouMenu, id=new_id)
-            
+
             elif item_infos["type"] == ITEM_CONFIGURATION:
                 menu = wx.Menu(title='')
                 new_id = wx.NewId()
                 AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Resource"))
                 self.Bind(wx.EVT_MENU, self.GenerateAddResourceFunction(name), id=new_id)
-            
+
             elif item_infos["type"] in [ITEM_DATATYPE, ITEM_TRANSITION, ITEM_ACTION, ITEM_RESOURCE]:
                 menu = wx.Menu(title='')
-                
+
             if menu is not None:
                 new_id = wx.NewId()
                 AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Delete"))
                 self.Bind(wx.EVT_MENU, self.OnDeleteMenu, id=new_id)
-        
+
         if menu is not None:
             self.PopupMenu(menu)
             menu.Destroy()
-        
+
         self.ResetSelectedItem()
-        
+
         event.Skip()
 
 
@@ -1932,7 +1932,7 @@
 
     def GetTreeImage(self, var_class):
         return self.TreeImageDict[var_class]
-    
+
     def RefreshPouInstanceVariablesPanel(self):
         self.PouInstanceVariablesPanel.RefreshView()
 
@@ -1945,11 +1945,11 @@
                 if old_selected >= 0:
                     self.TabsOpened.GetPage(old_selected).ResetBuffer()
                 self.TabsOpened.SetSelection(openedidx)
-        
+
         elif instance_category in ITEMS_VARIABLE:
             if self.Controler.IsNumType(instance_type, True):
                 self.AddDebugVariable(instance_path, True)
-        
+
         else:
             bodytype = self.Controler.GetEditedElementBodyType(instance_type, True)
             if bodytype == "FBD":
@@ -1968,7 +1968,7 @@
                     new_window.SetKeywords(IL_KEYWORDS)
                 else:
                     new_window.SetKeywords(ST_KEYWORDS)
-            
+
             if new_window is not None:
                 if instance_category in [ITEM_FUNCTIONBLOCK, ITEM_PROGRAM]:
                     pou_type = self.Controler.GetEditedElementType(instance_type, True)[1].upper()
@@ -1977,7 +1977,7 @@
                     icon = GetBitmap("TRANSITION", bodytype)
                 elif instance_category == ITEM_ACTION:
                     icon = GetBitmap("ACTION", bodytype)
-        
+
         if new_window is not None:
             new_window.SetIcon(icon)
             self.AddPage(new_window, "")
@@ -2005,19 +2005,19 @@
                 elif editor.IsDebugging():
                     editor.SubscribeAllDataConsumers()
             self.DebugVariablePanel.SubscribeAllDataConsumers()
-    
+
     def AddDebugVariable(self, iec_path, force=False, graph=False):
         if self.EnableDebug:
             self.DebugVariablePanel.InsertValue(iec_path, force=force, graph=graph)
             self.EnsureTabVisible(self.DebugVariablePanel)
-            
+
 #-------------------------------------------------------------------------------
 #                         Library Panel Management Function
 #-------------------------------------------------------------------------------
 
     def RefreshLibraryPanel(self):
         self.LibraryPanel.RefreshTree()
-        
+
 #-------------------------------------------------------------------------------
 #                          ToolBars Management Functions
 #-------------------------------------------------------------------------------
@@ -2039,16 +2039,16 @@
 
     def ResetEditorToolBar(self):
         EditorToolBar = self.Panes["EditorToolBar"]
-        
+
         for item in self.CurrentEditorToolBar:
             if wx.VERSION >= (2, 6, 0):
                 self.Unbind(wx.EVT_MENU, id=item)
             else:
-                self.Disconnect(id=item, eventType=wx.wxEVT_COMMAND_MENU_SELECTED) 
-        
+                self.Disconnect(id=item, eventType=wx.wxEVT_COMMAND_MENU_SELECTED)
+
             if EditorToolBar:
                 EditorToolBar.DeleteTool(item)
-        
+
         if EditorToolBar:
             EditorToolBar.Realize()
             self.AUIManager.GetPane("EditorToolBar").BestSize(EditorToolBar.GetBestSize())
@@ -2102,7 +2102,7 @@
         if EditorToolBar:
             EditorToolBar.ToggleTool(ID_PLCOPENEDITOREDITORTOOLBARSELECTION, False)
             EditorToolBar.ToggleTool(ID_PLCOPENEDITOREDITORTOOLBARSELECTION, True)
-        
+
     def ResetToolToggle(self, id):
         tool = self.Panes["EditorToolBar"].FindById(id)
         tool.SetToggle(False)
@@ -2111,55 +2111,55 @@
         selected = self.TabsOpened.GetSelection()
         if selected != -1:
             self.TabsOpened.GetPage(selected).SetMode(MODE_SELECTION)
-    
+
     def OnMotionTool(self, event):
         selected = self.TabsOpened.GetSelection()
         if selected != -1:
             self.TabsOpened.GetPage(selected).SetMode(MODE_MOTION)
-    
+
     def OnCommentTool(self, event):
         self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARCOMMENT)
         selected = self.TabsOpened.GetSelection()
         if selected != -1:
             self.TabsOpened.GetPage(selected).SetMode(MODE_COMMENT)
-    
+
     def OnVariableTool(self, event):
         self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARVARIABLE)
         selected = self.TabsOpened.GetSelection()
         if selected != -1:
             self.TabsOpened.GetPage(selected).SetMode(MODE_VARIABLE)
-    
+
     def OnBlockTool(self, event):
         self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARBLOCK)
         selected = self.TabsOpened.GetSelection()
         if selected != -1:
             self.TabsOpened.GetPage(selected).SetMode(MODE_BLOCK)
-        
+
     def OnConnectionTool(self, event):
         self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARCONNECTION)
         selected = self.TabsOpened.GetSelection()
         if selected != -1:
             self.TabsOpened.GetPage(selected).SetMode(MODE_CONNECTION)
-    
+
     def OnPowerRailTool(self, event):
         self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARPOWERRAIL)
         selected = self.TabsOpened.GetSelection()
         if selected != -1:
             self.TabsOpened.GetPage(selected).SetMode(MODE_POWERRAIL)
-    
+
     def OnRungTool(self, event):
         selected = self.TabsOpened.GetSelection()
         if selected != -1:
             self.TabsOpened.GetPage(selected).AddLadderRung()
         event.Skip()
-    
+
     def OnCoilTool(self, event):
         self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARCOIL)
         selected = self.TabsOpened.GetSelection()
         if selected != -1:
             self.TabsOpened.GetPage(selected).SetMode(MODE_COIL)
         event.Skip()
-    
+
     def OnContactTool(self, event):
         if self.DrawingMode == FREEDRAWING_MODE:
             self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARCONTACT)
@@ -2169,18 +2169,18 @@
                 self.TabsOpened.GetPage(selected).SetMode(MODE_CONTACT)
             else:
                 self.TabsOpened.GetPage(selected).AddLadderContact()
-    
-    def OnBranchTool(self, event): 
+
+    def OnBranchTool(self, event):
         selected = self.TabsOpened.GetSelection()
         if selected != -1:
             self.TabsOpened.GetPage(selected).AddLadderBranch()
-    
+
     def OnInitialStepTool(self, event):
         self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARINITIALSTEP)
         selected = self.TabsOpened.GetSelection()
         if selected != -1:
             self.TabsOpened.GetPage(selected).SetMode(MODE_INITIALSTEP)
-    
+
     def OnStepTool(self, event):
         if self.GetDrawingMode() == FREEDRAWING_MODE:
             self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARSTEP)
@@ -2190,7 +2190,7 @@
                 self.TabsOpened.GetPage(selected).SetMode(MODE_STEP)
             else:
                 self.TabsOpened.GetPage(selected).AddStep()
-    
+
     def OnActionBlockTool(self, event):
         if self.GetDrawingMode() == FREEDRAWING_MODE:
             self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARACTIONBLOCK)
@@ -2200,13 +2200,13 @@
                 self.TabsOpened.GetPage(selected).SetMode(MODE_ACTION)
             else:
                 self.TabsOpened.GetPage(selected).AddStepAction()
-    
+
     def OnTransitionTool(self, event):
         self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARTRANSITION)
         selected = self.TabsOpened.GetSelection()
         if selected != -1:
             self.TabsOpened.GetPage(selected).SetMode(MODE_TRANSITION)
-    
+
     def OnDivergenceTool(self, event):
         if self.GetDrawingMode() == FREEDRAWING_MODE:
             self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARDIVERGENCE)
@@ -2216,7 +2216,7 @@
                 self.TabsOpened.GetPage(selected).SetMode(MODE_DIVERGENCE)
             else:
                 self.TabsOpened.GetPage(selected).AddDivergence()
-    
+
     def OnJumpTool(self, event):
         if self.GetDrawingMode() == FREEDRAWING_MODE:
             self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARJUMP)
@@ -2226,7 +2226,7 @@
                 self.TabsOpened.GetPage(selected).SetMode(MODE_JUMP)
             else:
                 self.TabsOpened.GetPage(selected).AddJump()
-    
+
 
 #-------------------------------------------------------------------------------
 #                         Add Project Elements Functions
@@ -2237,7 +2237,7 @@
         if tagname is not None:
             self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE)
             self.EditProjectElement(ITEM_DATATYPE, tagname)
-        
+
     def GenerateAddPouFunction(self, pou_type):
         def OnAddPouMenu(event):
             dialog = PouDialog(self, pou_type)
@@ -2259,7 +2259,7 @@
             dialog.SetPouNames(self.Controler.GetProjectPouNames())
             dialog.SetPouElementNames(self.Controler.GetProjectPouVariableNames(pou_name))
             dialog.SetValues({"transitionName": self.Controler.GenerateNewName(None, None, "transition%d")})
-            if dialog.ShowModal() == wx.ID_OK: 
+            if dialog.ShowModal() == wx.ID_OK:
                 values = dialog.GetValues()
                 tagname = self.Controler.ProjectAddPouTransition(pou_name, values["transitionName"], values["language"])
                 if tagname is not None:
@@ -2289,6 +2289,14 @@
             self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL)
             self.EditProjectElement(ITEM_CONFIGURATION, tagname)
 
+    def AddResourceMenu(self, event):
+        config_names = self.Controler.GetProjectConfigNames()
+        if len(config_names) > 0:
+            tagname = self.Controler.ProjectAddConfigurationResource(config_names[0])
+            if tagname is not None:
+                self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL)
+                self.EditProjectElement(ITEM_RESOURCE, tagname)
+
     def GenerateAddResourceFunction(self, config_name):
         def OnAddResourceMenu(event):
             tagname = self.Controler.ProjectAddConfigurationResource(config_name)
@@ -2300,7 +2308,7 @@
     def GenerateChangePouTypeFunction(self, name, new_type):
         def OnChangePouTypeMenu(event):
             selected = self.ProjectTree.GetSelection()
-            if self.ProjectTree.GetPyData(selected)["type"] == ITEM_POU: 
+            if self.ProjectTree.GetPyData(selected)["type"] == ITEM_POU:
                 self.Controler.ProjectChangePouType(name, new_type)
                 self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, PROJECTTREE, LIBRARYTREE)
         return OnChangePouTypeMenu
@@ -2308,7 +2316,7 @@
     def OnCopyPou(self, event):
         selected = self.ProjectTree.GetSelection()
         pou_name = self.ProjectTree.GetItemText(selected)
-        
+
         pou_xml = self.Controler.GetPouXml(pou_name)
         if pou_xml is not None:
             self.SetCopyBuffer(pou_xml)
@@ -2316,14 +2324,14 @@
 
     def OnPastePou(self, event):
         selected = self.ProjectTree.GetSelection()
-        
-        if self.ProjectTree.GetPyData(selected)["type"] != ITEM_PROJECT: 
+
+        if self.ProjectTree.GetPyData(selected)["type"] != ITEM_PROJECT:
             pou_type = self.ProjectTree.GetItemText(selected)
             pou_type = UNEDITABLE_NAMES_DICT[pou_type] # one of 'Functions', 'Function Blocks' or 'Programs'
             pou_type = {'Functions': 'function', 'Function Blocks': 'functionBlock', 'Programs': 'program'}[pou_type]
         else:
             pou_type = None
-        
+
         pou_xml = self.GetCopyBuffer()
 
         result = self.Controler.PastePou(pou_type, pou_xml)
@@ -2341,9 +2349,9 @@
     def CheckElementIsUsedBeforeDeletion(self, check_function, title, name):
         if not check_function(name):
             return True
-        
-        dialog = wx.MessageDialog(self, 
-            _("\"%s\" is used by one or more POUs. Do you wish to continue?") % name, 
+
+        dialog = wx.MessageDialog(self,
+            _("\"%s\" is used by one or more POUs. Do you wish to continue?") % name,
             title, wx.YES_NO|wx.ICON_QUESTION)
         answer = dialog.ShowModal()
         dialog.Destroy()
@@ -2353,12 +2361,12 @@
         return self.CheckElementIsUsedBeforeDeletion(
             self.Controler.DataTypeIsUsed,
             _("Remove Datatype"), name)
-    
+
     def CheckPouIsUsedBeforeDeletion(self, name):
         return self.CheckElementIsUsedBeforeDeletion(
             self.Controler.PouIsUsed,
             _("Remove Pou"), name)
-    
+
     def OnRemoveDataTypeMenu(self, event):
         selected = self.ProjectTree.GetSelection()
         if self.ProjectTree.GetPyData(selected)["type"] == ITEM_DATATYPE:
@@ -2370,10 +2378,10 @@
                 if idx is not None:
                     self.TabsOpened.DeletePage(idx)
                 self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, PROJECTTREE)
-            
+
     def OnRenamePouMenu(self, event):
         selected = self.ProjectTree.GetSelection()
-        if self.ProjectTree.GetPyData(selected)["type"] == ITEM_POU: 
+        if self.ProjectTree.GetPyData(selected)["type"] == ITEM_POU:
             wx.CallAfter(self.ProjectTree.EditLabel, selected)
 
     def OnRemovePouMenu(self, event):
@@ -2391,7 +2399,7 @@
     def OnRemoveTransitionMenu(self, event):
         selected = self.ProjectTree.GetSelection()
         item_infos = self.ProjectTree.GetPyData(selected)
-        if item_infos["type"] == ITEM_TRANSITION: 
+        if item_infos["type"] == ITEM_TRANSITION:
             transition = self.ProjectTree.GetItemText(selected)
             pou_name = item_infos["tagname"].split("::")[1]
             self.Controler.ProjectRemovePouTransition(pou_name, transition)
@@ -2404,7 +2412,7 @@
     def OnRemoveActionMenu(self, event):
         selected = self.ProjectTree.GetSelection()
         item_infos = self.ProjectTree.GetPyData(selected)
-        if item_infos["type"] == ITEM_ACTION: 
+        if item_infos["type"] == ITEM_ACTION:
             action = self.ProjectTree.GetItemText(selected)
             pou_name = item_infos["tagname"].split("::")[1]
             self.Controler.ProjectRemovePouAction(pou_name, action)
@@ -2416,7 +2424,7 @@
 
     def OnRemoveConfigurationMenu(self, event):
         selected = self.ProjectTree.GetSelection()
-        if self.ProjectTree.GetPyData(selected)["type"] == ITEM_CONFIGURATION: 
+        if self.ProjectTree.GetPyData(selected)["type"] == ITEM_CONFIGURATION:
             name = self.ProjectTree.GetItemText(selected)
             self.Controler.ProjectRemoveConfiguration(name)
             tagname = self.Controler.ComputeConfigurationName(name)
@@ -2494,17 +2502,17 @@
         self.Margins = margins
         self.FontSize = 5
         self.TextMargin = 3
-        
+
         maxx, maxy = viewer.GetMaxSize()
-        self.PageGrid = (UPPER_DIV(maxx, self.PageSize[0]), 
+        self.PageGrid = (UPPER_DIV(maxx, self.PageSize[0]),
                          UPPER_DIV(maxy, self.PageSize[1]))
-        
+
     def GetPageNumber(self):
         return self.PageGrid[0] * self.PageGrid[1]
-    
+
     def HasPage(self, page):
         return page <= self.GetPageNumber()
-        
+
     def GetPageInfo(self):
         page_number = self.GetPageNumber()
         return (1, page_number, 1, page_number)
@@ -2520,7 +2528,7 @@
         dc.SetUserScale(1.0, 1.0)
         dc.SetDeviceOrigin(0, 0)
         dc.printing = not self.Preview
-        
+
         # Get the size of the DC in pixels
         ppiPrinterX, ppiPrinterY = self.GetPPIPrinter()
         ppiScreenX, ppiScreenY = self.GetPPIScreen()
@@ -2528,26 +2536,26 @@
         dw, dh = dc.GetSizeTuple()
         Xscale = (float(dw) * float(ppiPrinterX)) / (float(pw) * 25.4)
         Yscale = (float(dh) * float(ppiPrinterY)) / (float(ph) * 25.4)
-        
+
         fontsize = self.FontSize * Yscale
         text_margin = self.TextMargin * Yscale
-        
+
         margin_left = self.Margins[0].x * Xscale
         margin_top = self.Margins[0].y * Yscale
         area_width = dw - self.Margins[1].x * Xscale - margin_left
         area_height = dh - self.Margins[1].y * Yscale - margin_top
-        
+
         dc.SetPen(MiterPen(wx.BLACK))
-        dc.SetBrush(wx.TRANSPARENT_BRUSH)    
+        dc.SetBrush(wx.TRANSPARENT_BRUSH)
         dc.DrawRectangle(margin_left, margin_top, area_width, area_height)
-        
+
         dc.SetFont(wx.Font(fontsize, wx.DEFAULT, wx.NORMAL, wx.NORMAL))
         dc.SetTextForeground(wx.BLACK)
         block_name = " - ".join(self.Viewer.GetTagName().split("::")[1:])
         text_width, text_height = dc.GetTextExtent(block_name)
         dc.DrawText(block_name, margin_left, margin_top - text_height - self.TextMargin)
         dc.DrawText(_("Page: %d") % page, margin_left, margin_top + area_height + self.TextMargin)
-        
+
         # Calculate the position on the DC for centering the graphic
         posX = area_width * ((page - 1) % self.PageGrid[0])
         posY = area_height * ((page - 1) / self.PageGrid[0])
@@ -2560,10 +2568,10 @@
         dc.SetDeviceOrigin(-posX + margin_left, -posY + margin_top)
         dc.SetClippingRegion(posX, posY, self.PageSize[0] * scale, self.PageSize[1] * scale)
         dc.SetUserScale(scale, scale)
-        
+
         #-------------------------------------------
-        
+
         self.Viewer.DoDrawing(dc, True)
-        
+
         return True