merge
authormjsousa
Fri, 06 Jun 2014 18:30:49 +0100
changeset 1470 f65ab5ff91d1
parent 1469 86797748c2a2 (current diff)
parent 1414 8a3998d10b81 (diff)
child 1471 3eda8d8f622d
merge
py_ext/plc_python.c
--- a/Beremiz.py	Mon May 26 14:44:03 2014 +0100
+++ b/Beremiz.py	Fri Jun 06 18:30:49 2014 +0100
@@ -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	Mon May 26 14:44:03 2014 +0100
+++ b/IDEFrame.py	Fri Jun 06 18:30:49 2014 +0100
@@ -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
 
--- a/PLCControler.py	Mon May 26 14:44:03 2014 +0100
+++ b/PLCControler.py	Fri Jun 06 18:30:49 2014 +0100
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 
 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
-#based on the plcopen standard. 
+#based on the plcopen standard.
 #
 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
 #
@@ -57,7 +57,7 @@
                     ITEM_RESOURCES,
                     ITEM_PROPERTIES
                    ] = range(8, 17)
- 
+
 ITEMS_VARIABLE = [ITEM_VAR_LOCAL,
                   ITEM_VAR_GLOBAL,
                   ITEM_VAR_EXTERNAL,
@@ -92,12 +92,12 @@
 
 def GetUneditableNames():
     _ = lambda x:x
-    return [_("User-defined POUs"), _("Functions"), _("Function Blocks"), 
-            _("Programs"), _("Data Types"), _("Transitions"), _("Actions"), 
+    return [_("User-defined POUs"), _("Functions"), _("Function Blocks"),
+            _("Programs"), _("Data Types"), _("Transitions"), _("Actions"),
             _("Configurations"), _("Resources"), _("Properties")]
 UNEDITABLE_NAMES = GetUneditableNames()
-[USER_DEFINED_POUS, FUNCTIONS, FUNCTION_BLOCKS, PROGRAMS, 
- DATA_TYPES, TRANSITIONS, ACTIONS, CONFIGURATIONS, 
+[USER_DEFINED_POUS, FUNCTIONS, FUNCTION_BLOCKS, PROGRAMS,
+ DATA_TYPES, TRANSITIONS, ACTIONS, CONFIGURATIONS,
  RESOURCES, PROPERTIES] = UNEDITABLE_NAMES
 
 #-------------------------------------------------------------------------------
@@ -133,7 +133,7 @@
 _BoolValue = lambda x: x in ["true", "0"]
 
 def _translate_args(translations, args):
-    return [translate(arg[0]) if len(arg) > 0 else None 
+    return [translate(arg[0]) if len(arg) > 0 else None
             for translate, arg in
             zip(translations, args)]
 
@@ -142,7 +142,7 @@
 #-------------------------------------------------------------------------------
 
 class _VariableInfos(object):
-    __slots__ = ["Name", "Class", "Option", "Location", "InitialValue", 
+    __slots__ = ["Name", "Class", "Option", "Location", "InitialValue",
                  "Edit", "Documentation", "Type", "Tree", "Number"]
     def __init__(self, *args):
         for attr, value in zip(self.__slots__, args):
@@ -151,39 +151,39 @@
         return _VariableInfos(*[getattr(self, attr) for attr in self.__slots__])
 
 class VariablesInfosFactory:
-    
+
     def __init__(self, variables):
         self.Variables = variables
         self.TreeStack = []
         self.Type = None
         self.Dimensions = None
-    
+
     def SetType(self, context, *args):
         self.Type = args[0][0]
-        
+
     def GetType(self):
         if len(self.Dimensions) > 0:
             return ("array", self.Type, self.Dimensions)
         return self.Type
-    
+
     def GetTree(self):
         return (self.TreeStack.pop(-1), self.Dimensions)
-    
+
     def AddDimension(self, context, *args):
         self.Dimensions.append(tuple(
             _translate_args([_StringValue] * 2, args)))
-    
+
     def AddTree(self, context, *args):
         self.TreeStack.append([])
         self.Dimensions = []
-    
+
     def AddVarToTree(self, context, *args):
         var = (args[0][0], self.Type, self.GetTree())
         self.TreeStack[-1].append(var)
-    
+
     def AddVariable(self, context, *args):
         self.Variables.append(_VariableInfos(*(_translate_args(
-            [_StringValue] * 5 + [_BoolValue] + [_StringValue], args) + 
+            [_StringValue] * 5 + [_BoolValue] + [_StringValue], args) +
             [self.GetType(), self.GetTree()])))
 
 #-------------------------------------------------------------------------------
@@ -199,15 +199,15 @@
         "program": ITEM_PROGRAM}.get(value)
     if class_type is not None:
         return class_type
-    
+
     pou_type = POU_TYPES.get(value)
     if pou_type is not None:
         return pou_type
-    
+
     var_type = VAR_CLASS_INFOS.get(value)
     if var_type is not None:
         return var_type[1]
-    
+
     return None
 
 class _VariablesTreeItemInfos(object):
@@ -219,24 +219,24 @@
         return _VariableTreeItem(*[getattr(self, attr) for attr in self.__slots__])
 
 class VariablesTreeInfosFactory:
-    
+
     def __init__(self):
         self.Root = None
-    
+
     def GetRoot(self):
         return self.Root
-    
+
     def SetRoot(self, context, *args):
         self.Root = _VariablesTreeItemInfos(
             *([''] + _translate_args(
-                [class_extraction, _StringValue] + [_BoolValue] * 2, 
+                [class_extraction, _StringValue] + [_BoolValue] * 2,
                 args) + [[]]))
 
     def AddVariable(self, context, *args):
         if self.Root is not None:
             self.Root.variables.append(_VariablesTreeItemInfos(
                 *(_translate_args(
-                    [_StringValue, class_extraction, _StringValue] + 
+                    [_StringValue, class_extraction, _StringValue] +
                     [_BoolValue] * 2, args) + [[]])))
 
 #-------------------------------------------------------------------------------
@@ -244,10 +244,10 @@
 #-------------------------------------------------------------------------------
 
 class InstancesPathFactory:
-    
+
     def __init__(self, instances):
         self.Instances = instances
-        
+
     def AddInstance(self, context, *args):
         self.Instances.append(args[0][0])
 
@@ -260,13 +260,13 @@
     def __init__(self, controller):
         self.Controller = controller
         self.TagName = None
-    
+
     def GetTagName(self):
         return self.TagName
-    
+
     def ConfigTagName(self, context, *args):
         self.TagName = self.Controller.ComputeConfigurationName(args[0][0])
-        
+
     def ResourceTagName(self, context, *args):
         self.TagName = self.Controller.ComputeConfigurationResourceName(args[0][0], args[1][0])
 
@@ -285,15 +285,15 @@
 
 _Point = namedtuple("Point", ["x", "y"])
 
-_BlockInstanceInfos = namedtuple("BlockInstanceInfos", 
+_BlockInstanceInfos = namedtuple("BlockInstanceInfos",
     ["type", "id", "x", "y", "width", "height", "specific_values", "inputs", "outputs"])
 
 _BlockSpecificValues = (
-    namedtuple("BlockSpecificValues", 
+    namedtuple("BlockSpecificValues",
                ["name", "execution_order"]),
     [_StringValue, int])
 _VariableSpecificValues = (
-    namedtuple("VariableSpecificValues", 
+    namedtuple("VariableSpecificValues",
                ["name", "value_type", "execution_order"]),
     [_StringValue, _StringValue, int])
 _ConnectionSpecificValues = (
@@ -305,7 +305,7 @@
     [int])
 
 _LDElementSpecificValues = (
-    namedtuple("LDElementSpecificValues", 
+    namedtuple("LDElementSpecificValues",
                ["name", "negated", "edge", "storage", "execution_order"]),
     [_StringValue, _BoolValue, _StringValue, _StringValue, int])
 
@@ -330,7 +330,7 @@
         namedtuple("StepSpecificValues", ["name", "initial", "action"]),
         [_StringValue, _BoolValue, lambda x: x]),
     "transition": (
-        namedtuple("TransitionSpecificValues", 
+        namedtuple("TransitionSpecificValues",
                    ["priority", "condition_type", "condition", "connection"]),
         [int, _StringValue, _StringValue, lambda x: x]),
     "selectionDivergence": _DivergenceSpecificValues,
@@ -360,24 +360,24 @@
         return _ActionInfos(*[getattr(self, attr) for attr in self.__slots__])
 
 class BlockInstanceFactory:
-    
+
     def __init__(self, block_instances):
         self.BlockInstances = block_instances
         self.CurrentInstance = None
         self.SpecificValues = None
         self.CurrentConnection = None
         self.CurrentLink = None
-    
+
     def SetSpecificValues(self, context, *args):
         self.SpecificValues = list(args)
         self.CurrentInstance = None
         self.CurrentConnection = None
         self.CurrentLink = None
-    
+
     def AddBlockInstance(self, context, *args):
         specific_values_tuple, specific_values_translation = \
             _SpecificValuesTuples.get(args[0][0], _BlockSpecificValues)
-        
+
         if (args[0][0] == "step" and len(self.SpecificValues) < 3 or
             args[0][0] == "transition" and len(self.SpecificValues) < 4):
             self.SpecificValues.append([None])
@@ -386,21 +386,21 @@
         specific_values = specific_values_tuple(*_translate_args(
             specific_values_translation, self.SpecificValues))
         self.SpecificValues = None
-        
+
         self.CurrentInstance = _BlockInstanceInfos(
-            *(_translate_args([_StringValue, int] + [float] * 4, args) + 
+            *(_translate_args([_StringValue, int] + [float] * 4, args) +
               [specific_values, [], []]))
-        
+
         self.BlockInstances[self.CurrentInstance.id] = self.CurrentInstance
-        
+
     def AddInstanceConnection(self, context, *args):
         connection_args = _translate_args(
             [_StringValue] * 2 + [_BoolValue, _StringValue] + [float] * 2, args)
-        
+
         self.CurrentConnection = _InstanceConnectionInfos(
             *(connection_args[1:4] + [
                 _Point(*connection_args[4:6]), []]))
-        
+
         if self.CurrentInstance is not None:
             if connection_args[0] == "input":
                 self.CurrentInstance.inputs.append(self.CurrentConnection)
@@ -408,22 +408,22 @@
                 self.CurrentInstance.outputs.append(self.CurrentConnection)
         else:
             self.SpecificValues.append([self.CurrentConnection])
-    
+
     def AddConnectionLink(self, context, *args):
         self.CurrentLink = _ConnectionLinkInfos(
             *(_translate_args([int, _StringValue], args) + [[]]))
         self.CurrentConnection.links.append(self.CurrentLink)
-    
+
     def AddLinkPoint(self, context, *args):
         self.CurrentLink.points.append(_Point(
             *_translate_args([float] * 2, args)))
-    
+
     def AddAction(self, context, *args):
         if len(self.SpecificValues) == 0:
             self.SpecificValues.append([[]])
         translated_args = _translate_args([_StringValue] * 5, args)
         self.SpecificValues[0][0].append(_ActionInfos(*translated_args))
-    
+
 pou_block_instances_xslt = etree.parse(
     os.path.join(ScriptDirectory, "plcopen", "pou_block_instances.xslt"))
 
@@ -461,7 +461,7 @@
             self.LastSave = 0
         else:
             self.LastSave = -1
-    
+
     # Add a new state in buffer
     def Buffering(self, currentstate):
         self.CurrentIndex = (self.CurrentIndex + 1) % UNDO_BUFFER_LENGTH
@@ -474,29 +474,29 @@
                 self.LastSave = -1
             self.MinIndex = (self.MinIndex + 1) % UNDO_BUFFER_LENGTH
         self.MinIndex = max(self.MinIndex, 0)
-    
+
     # Return current state of buffer
     def Current(self):
         return self.Buffer[self.CurrentIndex]
-    
+
     # Change current state to previous in buffer and return new current state
     def Previous(self):
         if self.CurrentIndex != self.MinIndex:
             self.CurrentIndex = (self.CurrentIndex - 1) % UNDO_BUFFER_LENGTH
             return self.Buffer[self.CurrentIndex]
         return None
-    
+
     # Change current state to next in buffer and return new current state
     def Next(self):
         if self.CurrentIndex != self.MaxIndex:
             self.CurrentIndex = (self.CurrentIndex + 1) % UNDO_BUFFER_LENGTH
             return self.Buffer[self.CurrentIndex]
         return None
-    
+
     # Return True if current state is the first in buffer
     def IsFirst(self):
         return self.CurrentIndex == self.MinIndex
-    
+
     # Return True if current state is the last in buffer
     def IsLast(self):
         return self.CurrentIndex == self.MaxIndex
@@ -504,7 +504,7 @@
     # Note that current state is saved
     def CurrentSaved(self):
         self.LastSave = self.CurrentIndex
-        
+
     # Return True if current state is saved
     def IsCurrentSaved(self):
         return self.LastSave == self.CurrentIndex
@@ -518,12 +518,12 @@
 Class which controls the operations made on the plcopen model and answers to view requests
 """
 class PLCControler:
-    
+
     # Create a new PLCControler
     def __init__(self):
         self.LastNewIndex = 0
         self.Reset()
-    
+
     # Reset PLCControler internal variables
     def Reset(self):
         self.Project = None
@@ -541,7 +541,7 @@
         self.TotalTypesDict = StdBlckDct.copy()
         self.TotalTypes = StdBlckLst[:]
         self.ProgramFilePath = ""
-            
+
     def GetQualifierTypes(self):
         return QualifierList
 
@@ -567,7 +567,7 @@
         self.Project.setfileHeader(properties)
         self.Project.setcontentHeader(properties)
         self.SetFilePath("")
-        
+
         # Initialize the project buffer
         self.CreateProjectBuffer(False)
         self.ProgramChunks = []
@@ -575,28 +575,28 @@
         self.NextCompiledProject = self.Copy(self.Project)
         self.CurrentCompiledProject = None
         self.Buffering = False
-    
+
     # Return project data type names
     def GetProjectDataTypeNames(self, debug = False):
         project = self.GetProject(debug)
         if project is not None:
             return [datatype.getname() for datatype in project.getdataTypes()]
         return []
-    
+
     # Return project pou names
     def GetProjectPouNames(self, debug = False):
         project = self.GetProject(debug)
         if project is not None:
             return [pou.getname() for pou in project.getpous()]
         return []
-    
+
     # Return project pou names
     def GetProjectConfigNames(self, debug = False):
         project = self.GetProject(debug)
         if project is not None:
             return [config.getname() for config in project.getconfigurations()]
         return []
-    
+
     # Return project pou variable names
     def GetProjectPouVariableNames(self, pou_name = None, debug = False):
         variables = []
@@ -610,15 +610,15 @@
                     for action in pou.getactionList():
                         variables.append(action.getname())
         return variables
-    
+
     # Return file path if project is an open file
     def GetFilePath(self):
         return self.FilePath
-    
+
     # Return file path if project is an open file
     def GetProgramFilePath(self):
         return self.ProgramFilePath
-    
+
     # Return file name and point out if file is up to date
     def GetFilename(self):
         if self.Project is not None:
@@ -627,7 +627,7 @@
             else:
                 return "~%s~"%self.FileName
         return ""
-    
+
     # Change file path and save file name or create a default one if file path not defined
     def SetFilePath(self, filepath):
         self.FilePath = filepath
@@ -636,7 +636,7 @@
             self.FileName = _("Unnamed%d")%self.LastNewIndex
         else:
             self.FileName = os.path.splitext(os.path.basename(filepath))[0]
-    
+
     # Change project properties
     def SetProjectProperties(self, name = None, properties = None, buffer = True):
         if self.Project is not None:
@@ -647,14 +647,14 @@
                 self.Project.setcontentHeader(properties)
             if buffer and (name is not None or properties is not None):
                 self.BufferProject()
-    
+
     # Return project name
     def GetProjectName(self, debug=False):
         project = self.GetProject(debug)
         if project is not None:
             return project.getname()
         return None
-    
+
     # Return project properties
     def GetProjectProperties(self, debug = False):
         project = self.GetProject(debug)
@@ -663,7 +663,7 @@
             properties.update(project.getcontentHeader())
             return properties
         return None
-    
+
     # Return project informations
     def GetProjectInfos(self, debug = False):
         project = self.GetProject(debug)
@@ -671,7 +671,7 @@
             infos = {"name": project.getname(), "type": ITEM_PROJECT}
             datatypes = {"name": DATA_TYPES, "type": ITEM_DATATYPES, "values":[]}
             for datatype in project.getdataTypes():
-                datatypes["values"].append({"name": datatype.getname(), "type": ITEM_DATATYPE, 
+                datatypes["values"].append({"name": datatype.getname(), "type": ITEM_DATATYPE,
                     "tagname": self.ComputeDataTypeName(datatype.getname()), "values": []})
             pou_types = {"function": {"name": FUNCTIONS, "type": ITEM_FUNCTION, "values":[]},
                          "functionBlock": {"name": FUNCTION_BLOCKS, "type": ITEM_FUNCTIONBLOCK, "values":[]},
@@ -684,14 +684,14 @@
                 if pou.getbodyType() == "SFC":
                     transitions = []
                     for transition in pou.gettransitionList():
-                        transitions.append({"name": transition.getname(), "type": ITEM_TRANSITION, 
-                            "tagname": self.ComputePouTransitionName(pou.getname(), transition.getname()), 
+                        transitions.append({"name": transition.getname(), "type": ITEM_TRANSITION,
+                            "tagname": self.ComputePouTransitionName(pou.getname(), transition.getname()),
                             "values": []})
                     pou_values.append({"name": TRANSITIONS, "type": ITEM_TRANSITIONS, "values": transitions})
                     actions = []
                     for action in pou.getactionList():
-                        actions.append({"name": action.getname(), "type": ITEM_ACTION, 
-                            "tagname": self.ComputePouActionName(pou.getname(), action.getname()), 
+                        actions.append({"name": action.getname(), "type": ITEM_ACTION,
+                            "tagname": self.ComputePouActionName(pou.getname(), action.getname()),
                             "values": []})
                     pou_values.append({"name": ACTIONS, "type": ITEM_ACTIONS, "values": actions})
                 if pou_type in pou_types:
@@ -700,19 +700,19 @@
             configurations = {"name": CONFIGURATIONS, "type": ITEM_CONFIGURATIONS, "values": []}
             for config in project.getconfigurations():
                 config_name = config.getname()
-                config_infos = {"name": config_name, "type": ITEM_CONFIGURATION, 
-                    "tagname": self.ComputeConfigurationName(config.getname()), 
+                config_infos = {"name": config_name, "type": ITEM_CONFIGURATION,
+                    "tagname": self.ComputeConfigurationName(config.getname()),
                     "values": []}
                 resources = {"name": RESOURCES, "type": ITEM_RESOURCES, "values": []}
                 for resource in config.getresource():
                     resource_name = resource.getname()
-                    resource_infos = {"name": resource_name, "type": ITEM_RESOURCE, 
-                        "tagname": self.ComputeConfigurationResourceName(config.getname(), resource.getname()), 
+                    resource_infos = {"name": resource_name, "type": ITEM_RESOURCE,
+                        "tagname": self.ComputeConfigurationResourceName(config.getname(), resource.getname()),
                         "values": []}
                     resources["values"].append(resource_infos)
                 config_infos["values"] = [resources]
                 configurations["values"].append(config_infos)
-            infos["values"] = [datatypes, pou_types["function"], pou_types["functionBlock"], 
+            infos["values"] = [datatypes, pou_types["function"], pou_types["functionBlock"],
                                pou_types["program"], configurations]
             return infos
         return None
@@ -722,17 +722,17 @@
         project = self.GetProject(debug)
         if project is not None:
             factory = VariablesTreeInfosFactory()
-            
+
             parser = etree.XMLParser()
             parser.resolvers.add(LibraryResolver(self, debug))
-            
+
             pou_variable_xslt_tree = etree.XSLT(
                 etree.parse(
                     os.path.join(ScriptDirectory, "plcopen", "pou_variables.xslt"),
-                    parser), 
+                    parser),
                 extensions = {("pou_vars_ns", name): getattr(factory, name)
                               for name in ["SetRoot", "AddVariable"]})
-            
+
             obj = None
             words = tagname.split("::")
             if words[0] == "P":
@@ -742,7 +742,7 @@
             if obj is not None:
                 pou_variable_xslt_tree(obj)
                 return factory.GetRoot()
-            
+
         return None
 
     def GetInstanceList(self, root, name, debug = False):
@@ -750,22 +750,22 @@
         project = self.GetProject(debug)
         if project is not None:
             factory = InstancesPathFactory(instances)
-            
+
             parser = etree.XMLParser()
             parser.resolvers.add(LibraryResolver(self, debug))
-            
+
             instances_path_xslt_tree = etree.XSLT(
                 etree.parse(
                     os.path.join(ScriptDirectory, "plcopen", "instances_path.xslt"),
-                    parser), 
+                    parser),
                 extensions = {
                     ("instances_ns", "AddInstance"): factory.AddInstance})
-            
-            instances_path_xslt_tree(root, 
+
+            instances_path_xslt_tree(root,
                 instance_type=etree.XSLT.strparam(name))
-            
+
         return instances
-        
+
     def SearchPouInstances(self, tagname, debug = False):
         project = self.GetProject(debug)
         if project is not None:
@@ -781,28 +781,28 @@
                         for instance in self.SearchPouInstances(
                             self.ComputePouName(words[1]), debug)]
         return []
-    
+
     def GetPouInstanceTagName(self, instance_path, debug = False):
         project = self.GetProject(debug)
         factory = InstanceTagName(self)
-        
+
         parser = etree.XMLParser()
         parser.resolvers.add(LibraryResolver(self, debug))
-        
+
         instance_tagname_xslt_tree = etree.XSLT(
             etree.parse(
                 os.path.join(ScriptDirectory, "plcopen", "instance_tagname.xslt"),
-                parser), 
+                parser),
             extensions = {("instance_tagname_ns", name): getattr(factory, name)
                           for name in ["ConfigTagName", "ResourceTagName",
-                                       "PouTagName", "ActionTagName", 
+                                       "PouTagName", "ActionTagName",
                                        "TransitionTagName"]})
-        
-        instance_tagname_xslt_tree(project, 
+
+        instance_tagname_xslt_tree(project,
             instance_path=etree.XSLT.strparam(instance_path))
-        
+
         return factory.GetTagName()
-    
+
     def GetInstanceInfos(self, instance_path, debug = False):
         tagname = self.GetPouInstanceTagName(instance_path)
         if tagname is not None:
@@ -818,7 +818,7 @@
                     if var_infos.name == var_name:
                         return var_infos
         return None
-    
+
     # Return if data type given by name is used by another data type or pou
     def DataTypeIsUsed(self, name, debug = False):
         project = self.GetProject(debug)
@@ -887,11 +887,11 @@
                 return infos
             row, col = next_row, next_col
         return infos
-        
+
 #-------------------------------------------------------------------------------
 #                        Project Pous management functions
 #-------------------------------------------------------------------------------
-    
+
     # Add a Data Type to Project
     def ProjectAddDataType(self, datatype_name=None):
         if self.Project is not None:
@@ -902,13 +902,13 @@
             self.BufferProject()
             return self.ComputeDataTypeName(datatype_name)
         return None
-        
+
     # Remove a Data Type from project
     def ProjectRemoveDataType(self, datatype_name):
         if self.Project is not None:
             self.Project.removedataType(datatype_name)
             self.BufferProject()
-    
+
     # Add a Pou to Project
     def ProjectAddPou(self, pou_name, pou_type, body_type):
         if self.Project is not None:
@@ -919,21 +919,21 @@
             self.BufferProject()
             return self.ComputePouName(pou_name)
         return None
-    
+
     def ProjectChangePouType(self, name, pou_type):
         if self.Project is not None:
             pou = self.Project.getpou(name)
             if pou is not None:
                 pou.setpouType(pou_type)
                 self.BufferProject()
-                
+
     def GetPouXml(self, pou_name):
         if self.Project is not None:
             pou = self.Project.getpou(pou_name)
             if pou is not None:
                 return pou.tostring()
         return None
-    
+
     def PastePou(self, pou_type, pou_xml):
         '''
         Adds the POU defined by 'pou_xml' to the current project with type 'pou_type'
@@ -944,21 +944,21 @@
             error = ""
         if error is not None:
             return _("Couldn't paste non-POU object.")
-        
+
         name = new_pou.getname()
-        
+
         idx = 0
         new_name = name
-        while self.Project.getpou(new_name):
+        while self.Project.getpou(new_name) is not None:
             # a POU with that name already exists.
             # make a new name and test if a POU with that name exists.
             # append an incrementing numeric suffix to the POU name.
             idx += 1
             new_name = "%s%d" % (name, idx)
-            
+
         # we've found a name that does not already exist, use it
         new_pou.setname(new_name)
-        
+
         if pou_type is not None:
             orig_type = new_pou.getpouType()
 
@@ -968,12 +968,12 @@
             if orig_type == 'functionBlock' and pou_type == 'function' or \
                orig_type == 'program' and pou_type in ['function', 'functionBlock']:
                 return _('''%s "%s" can't be pasted as a %s.''') % (orig_type, name, pou_type)
-            
+
             new_pou.setpouType(pou_type)
 
-        self.Project.insertpou(-1, new_pou)
+        self.Project.insertpou(0, new_pou)
         self.BufferProject()
-        
+
         return self.ComputePouName(new_name),
 
     # Remove a Pou from project
@@ -981,7 +981,7 @@
         if self.Project is not None:
             self.Project.removepou(pou_name)
             self.BufferProject()
-    
+
     # Return the name of the configuration if only one exist
     def GetProjectMainConfigurationName(self):
         if self.Project is not None:
@@ -990,7 +990,7 @@
             if len(configurations) == 1:
                 return configurations[0].getname()
         return None
-                
+
     # Add a configuration to Project
     def ProjectAddConfiguration(self, config_name=None):
         if self.Project is not None:
@@ -1000,13 +1000,13 @@
             self.BufferProject()
             return self.ComputeConfigurationName(config_name)
         return None
-    
+
     # Remove a configuration from project
     def ProjectRemoveConfiguration(self, config_name):
         if self.Project is not None:
             self.Project.removeconfiguration(config_name)
             self.BufferProject()
-    
+
     # Add a resource to a configuration of the Project
     def ProjectAddConfigurationResource(self, config_name, resource_name=None):
         if self.Project is not None:
@@ -1016,13 +1016,13 @@
             self.BufferProject()
             return self.ComputeConfigurationResourceName(config_name, resource_name)
         return None
-    
+
     # Remove a resource from a configuration of the project
     def ProjectRemoveConfigurationResource(self, config_name, resource_name):
         if self.Project is not None:
             self.Project.removeconfigurationResource(config_name, resource_name)
             self.BufferProject()
-    
+
     # Add a Transition to a Project Pou
     def ProjectAddPouTransition(self, pou_name, transition_name, transition_type):
         if self.Project is not None:
@@ -1032,7 +1032,7 @@
                 self.BufferProject()
                 return self.ComputePouTransitionName(pou_name, transition_name)
         return None
-    
+
     # Remove a Transition from a Project Pou
     def ProjectRemovePouTransition(self, pou_name, transition_name):
         # Search if the pou removed is currently opened
@@ -1041,7 +1041,7 @@
             if pou is not None:
                 pou.removetransition(transition_name)
                 self.BufferProject()
-    
+
     # Add an Action to a Project Pou
     def ProjectAddPouAction(self, pou_name, action_name, action_type):
         if self.Project is not None:
@@ -1051,7 +1051,7 @@
                 self.BufferProject()
                 return self.ComputePouActionName(pou_name, action_name)
         return None
-    
+
     # Remove an Action from a Project Pou
     def ProjectRemovePouAction(self, pou_name, action_name):
         # Search if the pou removed is currently opened
@@ -1060,7 +1060,7 @@
             if pou is not None:
                 pou.removeaction(action_name)
                 self.BufferProject()
-    
+
     # Change the name of a pou
     def ChangeDataTypeName(self, old_name, new_name):
         if self.Project is not None:
@@ -1070,7 +1070,7 @@
                 datatype.setname(new_name)
                 self.Project.updateElementName(old_name, new_name)
                 self.BufferProject()
-    
+
     # Change the name of a pou
     def ChangePouName(self, old_name, new_name):
         if self.Project is not None:
@@ -1080,7 +1080,7 @@
                 pou.setname(new_name)
                 self.Project.updateElementName(old_name, new_name)
                 self.BufferProject()
-    
+
     # Change the name of a pou transition
     def ChangePouTransitionName(self, pou_name, old_name, new_name):
         if self.Project is not None:
@@ -1092,7 +1092,7 @@
                     transition.setname(new_name)
                     pou.updateElementName(old_name, new_name)
                     self.BufferProject()
-    
+
     # Change the name of a pou action
     def ChangePouActionName(self, pou_name, old_name, new_name):
         if self.Project is not None:
@@ -1104,7 +1104,7 @@
                     action.setname(new_name)
                     pou.updateElementName(old_name, new_name)
                     self.BufferProject()
-    
+
     # Change the name of a pou variable
     def ChangePouVariableName(self, pou_name, old_name, new_name):
         if self.Project is not None:
@@ -1116,7 +1116,7 @@
                         if var.getname() == old_name:
                             var.setname(new_name)
                 self.BufferProject()
-        
+
     # Change the name of a configuration
     def ChangeConfigurationName(self, old_name, new_name):
         if self.Project is not None:
@@ -1125,7 +1125,7 @@
             if configuration is not None:
                 configuration.setname(new_name)
                 self.BufferProject()
-    
+
     # Change the name of a configuration resource
     def ChangeConfigurationResourceName(self, config_name, old_name, new_name):
         if self.Project is not None:
@@ -1134,7 +1134,7 @@
             if resource is not None:
                 resource.setname(new_name)
                 self.BufferProject()
-    
+
     # Return the description of the pou given by its name
     def GetPouDescription(self, name, debug = False):
         project = self.GetProject(debug)
@@ -1144,7 +1144,7 @@
             if pou is not None:
                 return pou.getdescription()
         return ""
-    
+
     # Return the description of the pou given by its name
     def SetPouDescription(self, name, description, debug = False):
         project = self.GetProject(debug)
@@ -1154,7 +1154,7 @@
             if pou is not None:
                 pou.setdescription(description)
                 self.BufferProject()
-    
+
     # Return the type of the pou given by its name
     def GetPouType(self, name, debug = False):
         project = self.GetProject(debug)
@@ -1164,7 +1164,7 @@
             if pou is not None:
                 return pou.getpouType()
         return None
-    
+
     # Return pous with SFC language
     def GetSFCPous(self, debug = False):
         list = []
@@ -1174,7 +1174,7 @@
                 if pou.getBodyType() == "SFC":
                     list.append(pou.getname())
         return list
-    
+
     # Return the body language of the pou given by its name
     def GetPouBodyType(self, name, debug = False):
         project = self.GetProject(debug)
@@ -1184,7 +1184,7 @@
             if pou is not None:
                 return pou.getbodyType()
         return None
-    
+
     # Return the actions of a pou
     def GetPouTransitions(self, pou_name, debug = False):
         transitions = []
@@ -1196,7 +1196,7 @@
                 for transition in pou.gettransitionList():
                     transitions.append(transition.getname())
         return transitions
-    
+
     # Return the body language of the transition given by its name
     def GetTransitionBodyType(self, pou_name, pou_transition, debug = False):
         project = self.GetProject(debug)
@@ -1209,7 +1209,7 @@
                 if transition is not None:
                     return transition.getbodyType()
         return None
-    
+
     # Return the actions of a pou
     def GetPouActions(self, pou_name, debug = False):
         actions = []
@@ -1221,7 +1221,7 @@
                 for action in pou.getactionList():
                     actions.append(action.getname())
         return actions
-    
+
     # Return the body language of the pou given by its name
     def GetActionBodyType(self, pou_name, pou_action, debug = False):
         project = self.GetProject(debug)
@@ -1233,18 +1233,18 @@
                 if action is not None:
                     return action.getbodyType()
         return None
-    
+
     # Extract varlists from a list of vars
     def ExtractVarLists(self, vars):
         varlist_list = []
         current_varlist = None
         current_type = None
         for var in vars:
-            next_type = (var.Class, 
-                         var.Option, 
-                         var.Location in ["", None] or 
-                         # When declaring globals, located 
-                         # and not located variables are 
+            next_type = (var.Class,
+                         var.Option,
+                         var.Location in ["", None] or
+                         # When declaring globals, located
+                         # and not located variables are
                          # in the same declaration block
                          var.Class == "Global")
             if current_type != next_type:
@@ -1264,7 +1264,7 @@
             # Create variable and change its properties
             tempvar = PLCOpenParser.CreateElement("variable", "varListPlain")
             tempvar.setname(var.Name)
-            
+
             var_type = PLCOpenParser.CreateElement("type", "variable")
             if isinstance(var.Type, TupleType):
                 if var.Type[0] == "array":
@@ -1317,28 +1317,28 @@
             # Add variable to varList
             current_varlist.appendvariable(tempvar)
         return varlist_list
-    
+
     def GetVariableDictionary(self, object_with_vars, tree=False, debug=False):
         variables = []
         factory = VariablesInfosFactory(variables)
-        
+
         parser = etree.XMLParser()
         parser.resolvers.add(LibraryResolver(self, debug))
-        
+
         variables_infos_xslt_tree = etree.XSLT(
             etree.parse(
                 os.path.join(ScriptDirectory, "plcopen", "variables_infos.xslt"),
-                parser), 
+                parser),
             extensions = {("var_infos_ns", name): getattr(factory, name)
                 for name in ["SetType", "AddDimension", "AddTree",
                              "AddVarToTree", "AddVariable"]})
         variables_infos_xslt_tree(object_with_vars,
             tree=etree.XSLT.strparam(str(tree)))
-        
+
         return variables
-            
+
     # Add a global var to configuration to configuration
-    def AddConfigurationGlobalVar(self, config_name, var_type, var_name, 
+    def AddConfigurationGlobalVar(self, config_name, var_type, var_name,
                                            location="", description=""):
         if self.Project is not None:
             # Found the configuration corresponding to name
@@ -1346,7 +1346,7 @@
             if configuration is not None:
                 # Set configuration global vars
                 configuration.addglobalVar(
-                    self.GetVarTypeObject(var_type), 
+                    self.GetVarTypeObject(var_type),
                     var_name, location, description)
 
     # Replace the configuration globalvars by those given
@@ -1359,7 +1359,7 @@
                 configuration.setglobalVars([
                     varlist for vartype, varlist
                     in self.ExtractVarLists(vars)])
-    
+
     # Return the configuration globalvars
     def GetConfigurationGlobalVars(self, name, debug = False):
         project = self.GetProject(debug)
@@ -1369,7 +1369,7 @@
             if configuration is not None:
                 # Extract variables defined in configuration
                 return self.GetVariableDictionary(configuration, debug)
-        
+
         return []
 
     # Return configuration variable names
@@ -1381,7 +1381,7 @@
                 if config_name is None or config_name == configuration.getname():
                     variables.extend(
                         [var.getname() for var in reduce(
-                            lambda x, y: x + y, [varlist.getvariable() 
+                            lambda x, y: x + y, [varlist.getvariable()
                                 for varlist in configuration.globalVars],
                             [])])
         return variables
@@ -1396,7 +1396,7 @@
                 resource.setglobalVars([
                     varlist for vartype, varlist
                     in self.ExtractVarLists(vars)])
-    
+
     # Return the resource globalvars
     def GetConfigurationResourceGlobalVars(self, config_name, name, debug = False):
         project = self.GetProject(debug)
@@ -1406,11 +1406,11 @@
             if resource is not None:
                 # Extract variables defined in configuration
                 return self.GetVariableDictionary(resource, debug)
-        
+
         return []
-    
+
     # Return resource variable names
-    def GetConfigurationResourceVariableNames(self, 
+    def GetConfigurationResourceVariableNames(self,
                 config_name = None, resource_name = None, debug = False):
         variables = []
         project = self.GetProject(debug)
@@ -1421,7 +1421,7 @@
                         if resource_name is None or resource.getname() == resource_name:
                             variables.extend(
                                 [var.getname() for var in reduce(
-                                    lambda x, y: x + y, [varlist.getvariable() 
+                                    lambda x, y: x + y, [varlist.getvariable()
                                         for varlist in resource.globalVars],
                                     [])])
         return variables
@@ -1445,7 +1445,7 @@
                     pou.interface = PLCOpenParser.CreateElement("interface", "pou")
                 # Set Pou interface
                 pou.setvars([varlist for varlist_type, varlist in self.ExtractVarLists(vars)])
-                
+
     # Replace the return type of the pou given by its name (only for functions)
     def SetPouInterfaceReturnType(self, name, return_type):
         if self.Project is not None:
@@ -1468,16 +1468,16 @@
                     derived_type = PLCOpenParser.CreateElement("derived", "dataType")
                     derived_type.setname(return_type)
                     return_type.setcontent(derived_type)
-                
+
     def UpdateProjectUsedPous(self, old_name, new_name):
         if self.Project is not None:
             self.Project.updateElementName(old_name, new_name)
-    
+
     def UpdateEditedElementUsedVariable(self, tagname, old_name, new_name):
         pou = self.GetEditedElement(tagname)
         if pou is not None:
             pou.updateElementName(old_name, new_name)
-    
+
     # Return the return type of the given pou
     def GetPouInterfaceReturnType(self, pou, tree=False, debug=False):
         # Verify that the pou has an interface
@@ -1486,23 +1486,23 @@
             return_type = pou.interface.getreturnType()
             if return_type is not None:
                 factory = VariablesInfosFactory([])
-        
+
                 parser = etree.XMLParser()
                 parser.resolvers.add(LibraryResolver(self))
-                
+
                 return_type_infos_xslt_tree = etree.XSLT(
                     etree.parse(
                         os.path.join(ScriptDirectory, "plcopen", "variables_infos.xslt"),
-                        parser), 
+                        parser),
                     extensions = {("var_infos_ns", name): getattr(factory, name)
-                                  for name in ["SetType", "AddDimension", 
+                                  for name in ["SetType", "AddDimension",
                                                "AddTree", "AddVarToTree"]})
                 return_type_infos_xslt_tree(return_type,
                     tree=etree.XSLT.strparam(str(tree)))
                 if tree:
                     return [factory.GetType(), factory.GetTree()]
                 return factory.GetType()
-        
+
         if tree:
             return [None, ([], [])]
         return None
@@ -1519,7 +1519,7 @@
             for desc in cat["list"]:
                 BlkLst = self.TotalTypesDict.setdefault(desc["name"],[])
                 BlkLst.append((section["name"], desc))
-        
+
     # Function that clear the confnode list
     def ClearConfNodeTypes(self):
         self.ConfNodeTypes = []
@@ -1529,11 +1529,11 @@
     def GetConfNodeDataTypes(self, exclude = None, only_locatables = False):
         return [{"name": _("%s Data Types") % confnodetypes["name"],
                  "list": [
-                    datatype.getname() 
+                    datatype.getname()
                     for datatype in confnodetypes["types"].getdataTypes()
                     if not only_locatables or self.IsLocatableDataType(datatype, debug)]}
                 for confnodetypes in self.ConfNodeTypes]
-    
+
     def GetVariableLocationTree(self):
         return []
 
@@ -1545,7 +1545,7 @@
         for var_name, var_type, var_initial in self.GetConfNodeGlobalInstances():
             tempvar = PLCOpenParser.CreateElement("variable", "globalVars")
             tempvar.setname(var_name)
-            
+
             tempvartype = PLCOpenParser.CreateElement("type", "variable")
             if var_type in self.GetBaseTypes():
                 tempvartype.setcontent(PLCOpenParser.CreateElement(
@@ -1557,12 +1557,12 @@
                 tempderivedtype.setname(var_type)
                 tempvartype.setcontent(tempderivedtype)
             tempvar.settype(tempvartype)
-            
+
             if var_initial != "":
                 value = PLCOpenParser.CreateElement("initialValue", "variable")
                 value.setvalue(var_initial)
                 tempvar.setinitialValue(value)
-            
+
             global_vars.append(tempvar)
         return global_vars
 
@@ -1592,11 +1592,11 @@
                 blocktype_infos = blocktype.getblockInfos()
                 if inputs in [None, "undefined"]:
                     return blocktype_infos
-            
-                if inputs == tuple([var_type 
+
+                if inputs == tuple([var_type
                     for name, var_type, modifier in blocktype_infos["inputs"]]):
                     return blocktype_infos
-        
+
         return None
 
     # Return Block types checking for recursion
@@ -1610,18 +1610,18 @@
             if words[0] in ["P","T","A"]:
                 name = words[1]
                 pou_type = self.GetPouType(name, debug)
-            filter = (["function"] 
-                      if pou_type == "function" or words[0] == "T" 
+            filter = (["function"]
+                      if pou_type == "function" or words[0] == "T"
                       else ["functionBlock", "function"])
             blocktypes = [
                 {"name": category["name"],
                  "list": [block for block in category["list"]
                           if block["type"] in filter]}
                 for category in self.TotalTypes]
-            blocktypes.append({"name" : USER_DEFINED_POUS, 
+            blocktypes.append({"name" : USER_DEFINED_POUS,
                 "list": [pou.getblockInfos()
                          for pou in project.getpous(name, filter)
-                         if (name is None or 
+                         if (name is None or
                              len(self.GetInstanceList(pou, name, debug)) == 0)]})
             return blocktypes
         return self.TotalTypes
@@ -1641,7 +1641,7 @@
         if project is not None:
             blocktypes.extend([pou.getname()
                 for pou in project.getpous(name, ["functionBlock"])
-                if (name is None or 
+                if (name is None or
                     len(self.GetInstanceList(pou, name, debug)) == 0)])
         return blocktypes
 
@@ -1672,10 +1672,10 @@
             if words[0] in ["D"]:
                 name = words[1]
             datatypes.extend([
-                datatype.getname() 
+                datatype.getname()
                 for datatype in project.getdataTypes(name)
                 if (not only_locatables or self.IsLocatableDataType(datatype, debug))
-                    and (name is None or 
+                    and (name is None or
                          len(self.GetInstanceList(datatype, name, debug)) == 0)])
         if confnodetypes:
             for category in self.GetConfNodeDataTypes(name, only_locatables):
@@ -1730,14 +1730,14 @@
     def GetBaseType(self, typename, debug = False):
         if TypeHierarchy.has_key(typename):
             return typename
-        
+
         datatype = self.GetDataType(typename, debug)
         if datatype is not None:
             basetype = self.GetDataTypeBaseType(datatype)
             if basetype is not None:
                 return self.GetBaseType(basetype, debug)
             return typename
-        
+
         return None
 
     def GetBaseTypes(self):
@@ -1751,19 +1751,19 @@
     def IsOfType(self, typename, reference, debug = False):
         if reference is None or typename == reference:
             return True
-        
+
         basetype = TypeHierarchy.get(typename)
         if basetype is not None:
             return self.IsOfType(basetype, reference)
-        
+
         datatype = self.GetDataType(typename, debug)
         if datatype is not None:
             basetype = self.GetDataTypeBaseType(datatype)
             if basetype is not None:
                 return self.IsOfType(basetype, reference, debug)
-        
+
         return False
-    
+
     def IsEndType(self, typename):
         if typename is not None:
             return not typename.startswith("ANY")
@@ -1781,16 +1781,16 @@
             if array_base_type.getLocalTag() == "derived":
                 return self.IsLocatableType(array_base_type.getname(), debug)
         return True
-        
+
     def IsLocatableType(self, typename, debug = False):
         if isinstance(typename, TupleType) or self.GetBlockType(typename) is not None:
             return False
-        
+
         datatype = self.GetDataType(typename, debug)
         if datatype is not None:
             return self.IsLocatableDataType(datatype)
         return True
-    
+
     def IsEnumeratedType(self, typename, debug = False):
         if isinstance(typename, TupleType):
             typename = typename[1]
@@ -1822,7 +1822,7 @@
     def IsNumType(self, typename, debug = False):
         return self.IsOfType(typename, "ANY_NUM", debug) or\
                self.IsOfType(typename, "ANY_BIT", debug)
-            
+
     def GetDataTypeRange(self, typename, debug = False):
         range = DataTypeRange.get(typename)
         if range is not None:
@@ -1837,7 +1837,7 @@
             elif basetype_content_type == "derived":
                 return self.GetDataTypeRange(basetype_content.getname(), debug)
         return None
-    
+
     # Return Subrange types
     def GetSubrangeBaseTypes(self, exclude, debug = False):
         subrange_basetypes = DataTypeRange.keys()
@@ -1851,7 +1851,7 @@
                 [datatype.getname() for datatype in confnodetype["types"].getdataTypes()
                  if self.IsSubrangeType(datatype.getname(), exclude, debug)])
         return subrange_basetypes
-    
+
     # Return Enumerated Values
     def GetEnumeratedDataValues(self, typename = None, debug = False):
         values = []
@@ -1861,7 +1861,7 @@
                 basetype_content = datatype_obj.baseType.getcontent()
                 basetype_content_type = basetype_content.getLocalTag()
                 if basetype_content_type == "enum":
-                    return [value.getname() 
+                    return [value.getname()
                             for value in basetype_content.xpath(
                                 "ppx:values/ppx:value",
                                 namespaces=PLCOpenParser.NSMAP)]
@@ -1878,19 +1878,19 @@
 #-------------------------------------------------------------------------------
 #                   Project Element tag name computation functions
 #-------------------------------------------------------------------------------
-    
+
     # Compute a data type name
     def ComputeDataTypeName(self, datatype):
         return "D::%s" % datatype
-    
+
     # Compute a pou name
     def ComputePouName(self, pou):
         return "P::%s" % pou
-    
+
     # Compute a pou transition name
     def ComputePouTransitionName(self, pou, transition):
         return "T::%s::%s" % (pou, transition)
-    
+
     # Compute a pou action name
     def ComputePouActionName(self, pou, action):
         return "A::%s::%s" % (pou, action)
@@ -1905,7 +1905,7 @@
 
     def GetElementType(self, tagname):
         words = tagname.split("::")
-        return {"D" : ITEM_DATATYPE, "P" : ITEM_POU, 
+        return {"D" : ITEM_DATATYPE, "P" : ITEM_POU,
                 "T" : ITEM_TRANSITION, "A" : ITEM_ACTION,
                 "C" : ITEM_CONFIGURATION, "R" : ITEM_RESOURCE}[words[0]]
 
@@ -1963,7 +1963,7 @@
                                 dimensions.append((dimension.getlower(), dimension.getupper()))
                             base_type = element_type.baseType.getcontent()
                             base_type_type = element_type.getLocalTag()
-                            element_infos["Type"] = ("array", 
+                            element_infos["Type"] = ("array",
                                 base_type.getname()
                                 if base_type_type == "derived"
                                 else base_type_type.upper(), dimensions)
@@ -1981,14 +1981,14 @@
                     infos["base_type"] = (basetype_content.getname()
                         if basetype_content_type == "derived"
                         else basetype_content_type.upper())
-                
+
                 if datatype.initialValue is not None:
                     infos["initial"] = str(datatype.initialValue.getvalue())
                 else:
                     infos["initial"] = ""
                 return infos
         return None
-    
+
     # Change the data type informations
     def SetDataTypeInfos(self, tagname, infos):
         words = tagname.split("::")
@@ -2006,7 +2006,7 @@
                     datatype.baseType.setcontent(derived_datatype)
             elif infos["type"] == "Subrange":
                 subrange = PLCOpenParser.CreateElement(
-                    "subrangeUnsigned" 
+                    "subrangeUnsigned"
                     if infos["base_type"] in GetSubTypes("ANY_UINT")
                     else "subrangeSigned", "dataType")
                 datatype.baseType.setcontent(subrange)
@@ -2106,7 +2106,7 @@
             else:
                 datatype.initialValue = None
             self.BufferProject()
-    
+
 #-------------------------------------------------------------------------------
 #                       Project opened Pous management functions
 #-------------------------------------------------------------------------------
@@ -2132,7 +2132,7 @@
             elif words[0] == 'R':
                 return project.getconfigurationResource(words[1], words[2])
         return None
-    
+
     # Return edited element name
     def GetEditedElementName(self, tagname):
         words = tagname.split("::")
@@ -2141,7 +2141,7 @@
         else:
             return words[2]
         return None
-    
+
     # Return edited element name and type
     def GetEditedElementType(self, tagname, debug = False):
         words = tagname.split("::")
@@ -2183,14 +2183,14 @@
         elif words[0] == 'T':
             return "BOOL"
         return None
-    
+
     # Change the edited element text
     def SetEditedElementText(self, tagname, text):
         if self.Project is not None:
             element = self.GetEditedElement(tagname)
             if element is not None:
                 element.settext(text)
-    
+
     # Return the edited element text
     def GetEditedElementText(self, tagname, debug = False):
         element = self.GetEditedElement(tagname, debug)
@@ -2236,13 +2236,13 @@
         if element is not None:
             return element.tostring()
         return ""
-        
+
     def GetEditedElementInstancesCopy(self, tagname, blocks_id = None, wires = None, debug = False):
         element = self.GetEditedElement(tagname, debug)
         text = ""
         if element is not None:
-            wires = dict([(wire, True) 
-                          for wire in wires 
+            wires = dict([(wire, True)
+                          for wire in wires
                           if wire[0] in blocks_id and wire[1] in blocks_id])
             copy_body = PLCOpenParser.CreateElement("body", "pou")
             element.append(copy_body)
@@ -2257,20 +2257,20 @@
                     text += instance_copy.tostring()
             element.remove(copy_body)
         return text
-    
+
     def GenerateNewName(self, tagname, name, format, start_idx=0, exclude={}, debug=False):
         names = exclude.copy()
         if tagname is not None:
-            names.update(dict([(varname.upper(), True) 
+            names.update(dict([(varname.upper(), True)
                                for varname in self.GetEditedElementVariables(tagname, debug)]))
             words = tagname.split("::")
             if words[0] in ["P","T","A"]:
                 element = self.GetEditedElement(tagname, debug)
                 if element is not None and element.getbodyType() not in ["ST", "IL"]:
                     for instance in element.getinstances():
-                        if isinstance(instance, 
-                            (PLCOpenParser.GetElementClass("step", "sfcObjects"), 
-                             PLCOpenParser.GetElementClass("connector", "commonObjects"), 
+                        if isinstance(instance,
+                            (PLCOpenParser.GetElementClass("step", "sfcObjects"),
+                             PLCOpenParser.GetElementClass("connector", "commonObjects"),
                              PLCOpenParser.GetElementClass("continuation", "commonObjects"))):
                             names[instance.getname().upper()] = True
         else:
@@ -2290,37 +2290,37 @@
                     names[config.getname().upper()] = True
                     for resource in config.getresource():
                         names[resource.getname().upper()] = True
-            
+
         i = start_idx
         while name is None or names.get(name.upper(), False):
             name = (format%i)
             i += 1
         return name
-    
+
     def PasteEditedElementInstances(self, tagname, text, new_pos, middle=False, debug=False):
         element = self.GetEditedElement(tagname, debug)
         element_name, element_type = self.GetEditedElementType(tagname, debug)
         if element is not None:
             bodytype = element.getbodyType()
-            
+
             # Get edited element type scaling
             scaling = None
             project = self.GetProject(debug)
             if project is not None:
                 properties = project.getcontentHeader()
                 scaling = properties["scaling"][bodytype]
-            
+
             # Get ids already by all the instances in edited element
             used_id = dict([(instance.getlocalId(), True) for instance in element.getinstances()])
             new_id = {}
-            
+
             try:
                 instances, error = LoadPouInstances(text.encode("utf-8"), bodytype)
             except:
                 instances, error = [], ""
             if error is not None or len(instances) == 0:
                 return _("Invalid plcopen element(s)!!!")
-            
+
             exclude = {}
             for instance in instances:
                 element.addinstance(instance)
@@ -2332,25 +2332,25 @@
                     if blocktype_infos["type"] != "function" and blockname is not None:
                         if element_type == "function":
                             return _("FunctionBlock \"%s\" can't be pasted in a Function!!!")%blocktype
-                        blockname = self.GenerateNewName(tagname, 
-                                                         blockname, 
-                                                         "%s%%d"%blocktype, 
+                        blockname = self.GenerateNewName(tagname,
+                                                         blockname,
+                                                         "%s%%d"%blocktype,
                                                          debug=debug)
                         exclude[blockname] = True
                         instance.setinstanceName(blockname)
                         self.AddEditedElementPouVar(tagname, blocktype, blockname)
                 elif instance_type == "step":
-                    stepname = self.GenerateNewName(tagname, 
-                                                    instance.getname(), 
-                                                    "Step%d", 
-                                                    exclude=exclude, 
+                    stepname = self.GenerateNewName(tagname,
+                                                    instance.getname(),
+                                                    "Step%d",
+                                                    exclude=exclude,
                                                     debug=debug)
                     exclude[stepname] = True
                     instance.setname(stepname)
                 localid = instance.getlocalId()
                 if not used_id.has_key(localid):
                     new_id[localid] = True
-            
+
             idx = 1
             translate_id = {}
             bbox = rect()
@@ -2363,7 +2363,7 @@
                     new_id[idx] = True
                     instance.setlocalId(idx)
                     translate_id[localId] = idx
-            
+
             x, y, width, height = bbox.bounding_box()
             if middle:
                 new_pos[0] -= width / 2
@@ -2385,43 +2385,43 @@
             else:
                 new_pos = (max(30, new_pos[0]), max(30, new_pos[1]))
             diff = (int(new_pos[0] - x), int(new_pos[1] - y))
-            
+
             connections = {}
             for instance in instances:
                 connections.update(instance.updateConnectionsId(translate_id))
                 if getattr(instance, "setexecutionOrderId", None) is not None:
                     instance.setexecutionOrderId(0)
                 instance.translate(*diff)
-            
+
             return new_id, connections
-    
+
     def GetEditedElementInstancesInfos(self, tagname, debug = False):
         element_instances = OrderedDict()
         element = self.GetEditedElement(tagname, debug)
         if element is not None:
             factory = BlockInstanceFactory(element_instances)
-            
+
             pou_block_instances_xslt_tree = etree.XSLT(
-                pou_block_instances_xslt, 
+                pou_block_instances_xslt,
                 extensions = {
                     ("pou_block_instances_ns", name): getattr(factory, name)
                     for name in ["AddBlockInstance", "SetSpecificValues",
                                  "AddInstanceConnection", "AddConnectionLink",
                                  "AddLinkPoint", "AddAction"]})
-        
+
             pou_block_instances_xslt_tree(element)
         return element_instances
-    
+
     def ClearEditedElementExecutionOrder(self, tagname):
         element = self.GetEditedElement(tagname)
         if element is not None:
             element.resetexecutionOrder()
-    
+
     def ResetEditedElementExecutionOrder(self, tagname):
         element = self.GetEditedElement(tagname)
         if element is not None:
             element.compileexecutionOrder()
-    
+
     def SetConnectionWires(self, connection, connector):
         wires = connector.GetWires()
         idx = 0
@@ -2443,7 +2443,7 @@
                 else:
                     connection.setconnectionParameter(idx, None)
                 idx += 1
-    
+
     def GetVarTypeObject(self, var_type):
         var_type_obj = PLCOpenParser.CreateElement("type", "variable")
         if not var_type.startswith("ANY") and TypeHierarchy.get(var_type):
@@ -2455,7 +2455,7 @@
             derived_type.setname(var_type)
             var_type_obj.setcontent(derived_type)
         return var_type_obj
-    
+
     def AddEditedElementPouVar(self, tagname, var_type, name,**args):
         if self.Project is not None:
             words = tagname.split("::")
@@ -2463,9 +2463,9 @@
                 pou = self.Project.getpou(words[1])
                 if pou is not None:
                     pou.addpouLocalVar(
-                        self.GetVarTypeObject(var_type), 
+                        self.GetVarTypeObject(var_type),
                         name, **args)
-    
+
     def AddEditedElementPouExternalVar(self, tagname, var_type, name):
         if self.Project is not None:
             words = tagname.split("::")
@@ -2474,7 +2474,7 @@
                 if pou is not None:
                     pou.addpouExternalVar(
                         self.GetVarTypeObject(var_type), name)
-            
+
     def ChangeEditedElementPouVar(self, tagname, old_type, old_name, new_type, new_name):
         if self.Project is not None:
             words = tagname.split("::")
@@ -2482,7 +2482,7 @@
                 pou = self.Project.getpou(words[1])
                 if pou is not None:
                     pou.changepouVar(old_type, old_name, new_type, new_name)
-    
+
     def RemoveEditedElementPouVar(self, tagname, type, name):
         if self.Project is not None:
             words = tagname.split("::")
@@ -2490,7 +2490,7 @@
                 pou = self.Project.getpou(words[1])
                 if pou is not None:
                     pou.removepouVar(type, name)
-    
+
     def AddEditedElementBlock(self, tagname, id, blocktype, blockname = None):
         element = self.GetEditedElement(tagname)
         if element is not None:
@@ -2502,13 +2502,13 @@
                 block.setinstanceName(blockname)
                 self.AddEditedElementPouVar(tagname, blocktype, blockname)
             element.addinstance(block)
-    
+
     def SetEditedElementBlockInfos(self, tagname, id, infos):
         element = self.GetEditedElement(tagname)
         if element is not None:
             block = element.getinstance(id)
             if block is None:
-                return 
+                return
             old_name = block.getinstanceName()
             old_type = block.gettypeName()
             new_name = infos.get("name", old_name)
@@ -2571,7 +2571,7 @@
                         variable.addconnectionPointOut()
                         variable.connectionPointOut.setrelPositionXY(position.x, position.y)
             block.tostring()
-        
+
     def AddEditedElementVariable(self, tagname, id, var_type):
         element = self.GetEditedElement(tagname)
         if element is not None:
@@ -2581,13 +2581,13 @@
                  INOUT: "inOutVariable"}[var_type], "fbdObjects")
             variable.setlocalId(id)
             element.addinstance(variable)
-        
+
     def SetEditedElementVariableInfos(self, tagname, id, infos):
         element = self.GetEditedElement(tagname)
         if element is not None:
             variable = element.getinstance(id)
             if variable is None:
-                return 
+                return
             for param, value in infos.items():
                 if param == "name":
                     variable.setexpression(value)
@@ -2634,7 +2634,7 @@
                  CONTINUATION: "continuation"}[connection_type], "commonObjects")
             connection.setlocalId(id)
             element.addinstance(connection)
-        
+
     def SetEditedElementConnectionInfos(self, tagname, id, infos):
         element = self.GetEditedElement(tagname)
         if element is not None:
@@ -2643,7 +2643,7 @@
                 return
             for param, value in infos.items():
                 if param == "name":
-                    connection.setname(value)    
+                    connection.setname(value)
                 elif param == "height":
                     connection.setheight(value)
                 elif param == "width":
@@ -2668,7 +2668,7 @@
             comment = PLCOpenParser.CreateElement("comment", "commonObjects")
             comment.setlocalId(id)
             element.addinstance(comment)
-    
+
     def SetEditedElementCommentInfos(self, tagname, id, infos):
         element = self.GetEditedElement(tagname)
         if element is not None:
@@ -2693,7 +2693,7 @@
                  RIGHTRAIL: "rightPowerRail"}[powerrail_type], "ldObjects")
             powerrail.setlocalId(id)
             element.addinstance(powerrail)
-    
+
     def SetEditedElementPowerRailInfos(self, tagname, id, infos):
         element = self.GetEditedElement(tagname)
         if element is not None:
@@ -2725,7 +2725,7 @@
                             powerrail.appendconnectionPointIn(connection)
                             connection.setrelPositionXY(position.x, position.y)
                             self.SetConnectionWires(connection, connector)
-                            
+
     def AddEditedElementContact(self, tagname, id):
         element = self.GetEditedElement(tagname)
         if element is not None:
@@ -2821,7 +2821,7 @@
             step = PLCOpenParser.CreateElement("step", "sfcObjects")
             step.setlocalId(id)
             element.addinstance(step)
-    
+
     def SetEditedElementStepInfos(self, tagname, id, infos):
         element = self.GetEditedElement(tagname)
         if element is not None:
@@ -2864,14 +2864,14 @@
                         step.connectionPointOutAction.setrelPositionXY(position.x, position.y)
                     else:
                         step.deleteconnectionPointOutAction()
-    
+
     def AddEditedElementTransition(self, tagname, id):
         element = self.GetEditedElement(tagname)
         if element is not None:
             transition = PLCOpenParser.CreateElement("transition", "sfcObjects")
             transition.setlocalId(id)
             element.addinstance(transition)
-    
+
     def SetEditedElementTransitionInfos(self, tagname, id, infos):
         element = self.GetEditedElement(tagname)
         if element is not None:
@@ -2907,7 +2907,7 @@
                 elif infos.get("type", None) == "connection" and param == "connection" and value:
                     transition.setconditionContent("connection", None)
                     self.SetConnectionWires(transition.condition.content, value)
-    
+
     def AddEditedElementDivergence(self, tagname, id, divergence_type):
         element = self.GetEditedElement(tagname)
         if element is not None:
@@ -2919,19 +2919,19 @@
                     divergence_type), "sfcObjects")
             divergence.setlocalId(id)
             element.addinstance(divergence)
-    
+
     DivergenceTypes = [
-        (divergence_type, 
+        (divergence_type,
          PLCOpenParser.GetElementClass(divergence_type, "sfcObjects"))
         for divergence_type in ["selectionDivergence", "simultaneousDivergence",
                                 "selectionConvergence", "simultaneousConvergence"]]
-    
+
     def GetDivergenceType(self, divergence):
         for divergence_type, divergence_class in self.DivergenceTypes:
             if isinstance(divergence, divergence_class):
                 return divergence_type
         return None
-    
+
     def SetEditedElementDivergenceInfos(self, tagname, id, infos):
         element = self.GetEditedElement(tagname)
         if element is not None:
@@ -2975,14 +2975,14 @@
                             connection = PLCOpenParser.CreateElement("connectionPointOut", divergence_type)
                             divergence.appendconnectionPointOut(connection)
                             connection.setrelPositionXY(position.x, position.y)
-                            
+
     def AddEditedElementJump(self, tagname, id):
         element = self.GetEditedElement(tagname)
         if element is not None:
             jump = PLCOpenParser.CreateElement("jumpStep", "sfcObjects")
             jump.setlocalId(id)
             element.addinstance(jump)
-    
+
     def SetEditedElementJumpInfos(self, tagname, id, infos):
         element = self.GetEditedElement(tagname)
         if element is not None:
@@ -3005,14 +3005,14 @@
                     jump.addconnectionPointIn()
                     jump.connectionPointIn.setrelPositionXY(position.x, position.y)
                     self.SetConnectionWires(jump.connectionPointIn, value)
- 
+
     def AddEditedElementActionBlock(self, tagname, id):
         element = self.GetEditedElement(tagname)
         if element is not None:
             actionBlock = PLCOpenParser.CreateElement("actionBlock", "commonObjects")
             actionBlock.setlocalId(id)
             element.addinstance(actionBlock)
-    
+
     def SetEditedElementActionBlockInfos(self, tagname, id, infos):
         element = self.GetEditedElement(tagname)
         if element is not None:
@@ -3035,7 +3035,7 @@
                     actionBlock.addconnectionPointIn()
                     actionBlock.connectionPointIn.setrelPositionXY(position.x, position.y)
                     self.SetConnectionWires(actionBlock.connectionPointIn, value)
-    
+
     def RemoveEditedElementInstance(self, tagname, id):
         element = self.GetEditedElement(tagname)
         if element is not None:
@@ -3162,19 +3162,19 @@
         self.Buffering = False
         self.CurrentElementEditing = None
         return error
-        
+
     def SaveXMLFile(self, filepath = None):
         if not filepath and self.FilePath == "":
             return False
         else:
             contentheader = {"modificationDateTime": datetime.datetime(*localtime()[:6])}
             self.Project.setcontentHeader(contentheader)
-            
+
             if filepath:
                 SaveProject(self.Project, filepath)
             else:
                 SaveProject(self.Project, self.FilePath)
-            
+
             self.MarkProjectAsSaved()
             if filepath:
                 self.SetFilePath(filepath)
@@ -3233,7 +3233,7 @@
             self.Buffering = True
         else:
             self.ProjectSaved = False
-        
+
     def EndBuffering(self):
         if self.ProjectBuffer is not None and self.Buffering:
             self.ProjectBuffer.Buffering(PLCOpenParser.Dumps(self.Project))
@@ -3245,7 +3245,7 @@
             self.ProjectBuffer.CurrentSaved()
         else:
             self.ProjectSaved = True
-    
+
     # Return if project is saved
     def ProjectIsSaved(self):
         if self.ProjectBuffer is not None:
@@ -3257,11 +3257,11 @@
         self.EndBuffering()
         if self.ProjectBuffer is not None:
             self.Project = PLCOpenParser.Loads(self.ProjectBuffer.Previous())
-    
+
     def LoadNext(self):
         if self.ProjectBuffer is not None:
             self.Project = PLCOpenParser.Loads(self.ProjectBuffer.Next())
-    
+
     def GetBufferState(self):
         if self.ProjectBuffer is not None:
             first = self.ProjectBuffer.IsFirst() and not self.Buffering
--- a/ProjectController.py	Mon May 26 14:44:03 2014 +0100
+++ b/ProjectController.py	Fri Jun 06 18:30:49 2014 +0100
@@ -1,5 +1,5 @@
 """
-Beremiz Project Controller 
+Beremiz Project Controller
 """
 import os,sys,traceback
 import time
@@ -63,14 +63,14 @@
 
 class ProjectController(ConfigTreeNode, PLCControler):
     """
-    This class define Root object of the confnode tree. 
+    This class define Root object of the confnode tree.
     It is responsible of :
     - Managing project directory
     - Building project
     - Handling PLCOpenEditor controler and view
     - Loading user confnodes and instanciante them as children
     - ...
-    
+
     """
 
     # For root object, available Children Types are modules of the confnode packages.
@@ -87,15 +87,15 @@
                 """+targets.GetTargetChoices()+"""
                 </xsd:choice>
               </xsd:complexType>
-            </xsd:element>
-            <xsd:element name="Libraries" minOccurs="0">"""+(("""
+            </xsd:element>"""+(("""
+            <xsd:element name="Libraries" minOccurs="0">
               <xsd:complexType>
               """+"\n".join(['<xsd:attribute name='+
                              '"Enable_'+ libname + '_Library" '+
-                             'type="xsd:boolean" use="optional" default="true"/>' 
+                             'type="xsd:boolean" use="optional" default="true"/>'
                              for libname,lib in features.libraries])+"""
-              </xsd:complexType>""") if len(features.libraries)>0 else '<xsd:complexType/>') + """
-            </xsd:element>
+              </xsd:complexType>
+            </xsd:element>""") if len(features.libraries)>0 else '') + """
           </xsd:sequence>
           <xsd:attribute name="URI_location" type="xsd:string" use="optional" default=""/>
           <xsd:attribute name="Disable_Extensions" type="xsd:boolean" use="optional" default="false"/>
@@ -104,7 +104,7 @@
     </xsd:schema>
     """
     EditorType = ProjectNodeEditor
-    
+
     def __init__(self, frame, logger):
         PLCControler.__init__(self)
 
@@ -115,10 +115,10 @@
         self.DebugValuesBuffers = []
         self.DebugTicks = []
         self.SetAppFrame(frame, logger)
-        
+
         self.iec2c_path = os.path.join(base_folder, "matiec", "iec2c"+(".exe" if wx.Platform == '__WXMSW__' else ""))
         self.ieclib_path = os.path.join(base_folder, "matiec", "lib")
-        
+
         # Setup debug information
         self.IECdebug_datas = {}
         self.IECdebug_lock = Lock()
@@ -147,7 +147,7 @@
         if self.DebugTimer:
             self.DebugTimer.cancel()
         self.KillDebugThread()
-    
+
     def LoadLibraries(self):
         self.Libraries = []
         TypeStack=[]
@@ -156,7 +156,7 @@
                 Lib = GetClassImporter(clsname)()(self, libname, TypeStack)
                 TypeStack.append(Lib.GetTypes())
                 self.Libraries.append(Lib)
-    
+
     def SetAppFrame(self, frame, logger):
         self.AppFrame = frame
         self.logger = logger
@@ -164,23 +164,23 @@
         if self.DispatchDebugValuesTimer is not None:
             self.DispatchDebugValuesTimer.Stop()
         self.DispatchDebugValuesTimer = None
-        
+
         if frame is not None:
-            
+
             # Timer to pull PLC status
             self.StatusTimer = wx.Timer(self.AppFrame, -1)
-            self.AppFrame.Bind(wx.EVT_TIMER, 
+            self.AppFrame.Bind(wx.EVT_TIMER,
                 self.PullPLCStatusProc, self.StatusTimer)
 
             if self._connector is not None:
                 frame.LogViewer.SetLogSource(self._connector)
                 self.StatusTimer.Start(milliseconds=500, oneShot=False)
-            
+
             # Timer to dispatch debug values to consumers
             self.DispatchDebugValuesTimer = wx.Timer(self.AppFrame, -1)
-            self.AppFrame.Bind(wx.EVT_TIMER, 
+            self.AppFrame.Bind(wx.EVT_TIMER,
                 self.DispatchDebugValuesProc, self.DispatchDebugValuesTimer)
-            
+
             self.RefreshConfNodesBlockLists()
 
     def ResetAppFrame(self, logger):
@@ -188,7 +188,7 @@
             self.AppFrame.Unbind(wx.EVT_TIMER, self.StatusTimer)
             self.StatusTimer = None
             self.AppFrame = None
-        
+
         self.logger = logger
 
     def CTNName(self):
@@ -205,16 +205,16 @@
 
     def GetIECLibPath(self):
         return self.ieclib_path
-    
+
     def GetIEC2cPath(self):
         return self.iec2c_path
-    
+
     def GetCurrentLocation(self):
         return ()
 
     def GetCurrentName(self):
         return ""
-    
+
     def _GetCurrentName(self):
         return ""
 
@@ -223,10 +223,10 @@
 
     def GetProjectName(self):
         return os.path.split(self.ProjectPath)[1]
-    
+
     def GetIconName(self):
         return "PROJECT"
-    
+
     def GetDefaultTargetName(self):
         if wx.Platform == '__WXMSW__':
             return "Win32"
@@ -242,15 +242,15 @@
             target_name = self.GetDefaultTargetName()
             target.setcontent(self.Parser.CreateElement(target_name, "TargetType"))
         return target
-    
+
     def GetParamsAttributes(self, path = None):
         params = ConfigTreeNode.GetParamsAttributes(self, path)
         if params[0]["name"] == "BeremizRoot":
             for child in params[0]["children"]:
                 if child["name"] == "TargetType" and child["value"] == '':
-                    child.update(self.GetTarget().getElementInfos("TargetType")) 
+                    child.update(self.GetTarget().getElementInfos("TargetType"))
         return params
-        
+
     def SetParamsAttribute(self, path, value):
         if path.startswith("BeremizRoot.TargetType.") and self.BeremizRoot.getTargetType().getcontent() is None:
             self.BeremizRoot.setTargetType(self.GetTarget())
@@ -258,15 +258,15 @@
         if path.startswith("BeremizRoot.Libraries."):
             wx.CallAfter(self.RefreshConfNodesBlockLists)
         return res
-        
+
     # helper func to check project path write permission
     def CheckProjectPathPerm(self, dosave=True):
         if CheckPathPerm(self.ProjectPath):
             return True
         if self.AppFrame is not None:
-            dialog = wx.MessageDialog(self.AppFrame, 
+            dialog = wx.MessageDialog(self.AppFrame,
                         _('You must have permission to work on the project\nWork on a project copy ?'),
-                        _('Error'), 
+                        _('Error'),
                         wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
             answer = dialog.ShowModal()
             dialog.Destroy()
@@ -277,7 +277,7 @@
                     self.AppFrame.RefreshPageTitles()
                     return True
         return False
-    
+
     def _getProjectFilesPath(self, project_path=None):
         if project_path is not None:
             return os.path.join(project_path, "project_files")
@@ -285,7 +285,7 @@
         if not os.path.exists(projectfiles_path):
             os.mkdir(projectfiles_path)
         return projectfiles_path
-    
+
     def AddProjectDefaultConfiguration(self, config_name="config", res_name="resource1"):
         self.ProjectAddConfiguration(config_name)
         self.ProjectAddConfigurationResource(config_name, res_name)
@@ -299,7 +299,7 @@
         # Verify that chosen folder is empty
         if not os.path.isdir(ProjectPath) or len(os.listdir(ProjectPath)) > 0:
             return _("Chosen folder isn't empty. You can't use it for a new project!")
-        
+
         # Create PLCOpen program
         self.CreateNewProject(
             {"projectName": _("Unnamed"),
@@ -308,7 +308,7 @@
              "companyName": _("Unknown"),
              "creationDateTime": datetime(*localtime()[:6])})
         self.AddProjectDefaultConfiguration()
-        
+
         # Change XSD into class members
         self._AddParamsMembers()
         self.Children = {}
@@ -320,7 +320,7 @@
         # this will create files base XML files
         self.SaveProject()
         return None
-        
+
     def LoadProject(self, ProjectPath, BuildPath=None):
         """
         Load a project contained in a folder
@@ -357,30 +357,30 @@
             #Load and init all the children
             self.LoadChildren()
         self.RefreshConfNodesBlockLists()
-        
+
         if os.path.exists(self._getBuildPath()):
             self.EnableMethod("_Clean", True)
 
         if os.path.isfile(self._getIECcodepath()):
             self.ShowMethod("_showIECcode", True)
-        
+
         self.UpdateMethodsFromPLCStatus()
-        
+
         return None
-    
+
     def RecursiveConfNodeInfos(self, confnode):
         values = []
         for CTNChild in confnode.IECSortedChildren():
             values.append(
                 {"name": "%s: %s" % (CTNChild.GetFullIEC_Channel(),
-                                     CTNChild.CTNName()), 
+                                     CTNChild.CTNName()),
                  "tagname": CTNChild.CTNFullName(),
-                 "type": ITEM_CONFNODE, 
+                 "type": ITEM_CONFNODE,
                  "confnode": CTNChild,
                  "icon": CTNChild.GetIconName(),
                  "values": self.RecursiveConfNodeInfos(CTNChild)})
         return values
-    
+
     def GetProjectInfos(self):
         infos = PLCControler.GetProjectInfos(self)
         configurations = infos["values"].pop(-1)
@@ -394,23 +394,23 @@
             infos["values"].append(resources)
         infos["values"].extend(self.RecursiveConfNodeInfos(self))
         return infos
-    
+
     def CloseProject(self):
         self.ClearChildren()
         self.ResetAppFrame(None)
-        
+
     def SaveProject(self, from_project_path=None):
         if self.CheckProjectPathPerm(False):
             if from_project_path is not None:
                 old_projectfiles_path = self._getProjectFilesPath(from_project_path)
                 if os.path.isdir(old_projectfiles_path):
-                    shutil.copytree(old_projectfiles_path, 
+                    shutil.copytree(old_projectfiles_path,
                                     self._getProjectFilesPath(self.ProjectPath))
             self.SaveXMLFile(os.path.join(self.ProjectPath, 'plc.xml'))
             result = self.CTNRequestSave(from_project_path)
             if result:
                 self.logger.write_error(result)
-    
+
     def SaveProjectAs(self):
         # Ask user to choose a path with write permissions
         if wx.Platform == '__WXMSW__':
@@ -444,12 +444,12 @@
         LocatedCCodeAndFlags=[]
         Extras=[]
         for lib in self.Libraries:
-            res=lib.Generate_C(buildpath,self._VariablesList,LibIECCflags)  
+            res=lib.Generate_C(buildpath,self._VariablesList,LibIECCflags)
             LocatedCCodeAndFlags.append(res[:2])
             if len(res)>2:
                 Extras.extend(res[2:])
         return map(list,zip(*LocatedCCodeAndFlags))+[tuple(Extras)]
-    
+
     # Update PLCOpenEditor ConfNode Block types from loaded confnodes
     def RefreshConfNodesBlockLists(self):
         if getattr(self, "Children", None) is not None:
@@ -458,7 +458,7 @@
         if self.AppFrame is not None:
             self.AppFrame.RefreshLibraryPanel()
             self.AppFrame.RefreshEditor()
-    
+
     # Update a PLCOpenEditor Pou variable location
     def UpdateProjectVariableLocation(self, old_leading, new_leading):
         self.Project.updateElementAddress(old_leading, new_leading)
@@ -469,13 +469,13 @@
             self.AppFrame.RefreshFileMenu()
             self.AppFrame.RefreshEditMenu()
             wx.CallAfter(self.AppFrame.RefreshEditor)
-    
+
     def GetVariableLocationTree(self):
         '''
         This function is meant to be overridden by confnodes.
 
         It should returns an list of dictionaries
-        
+
         - IEC_type is an IEC type like BOOL/BYTE/SINT/...
         - location is a string of this variable's location, like "%IX0.0.0"
         '''
@@ -483,13 +483,13 @@
         for child in self.IECSortedChildren():
             children.append(child.GetVariableLocationTree())
         return children
-    
+
     def ConfNodePath(self):
         return os.path.split(__file__)[0]
-    
+
     def CTNPath(self, CTNName=None):
         return self.ProjectPath
-    
+
     def ConfNodeXmlFilePath(self, CTNName=None):
         return os.path.join(self.CTNPath(CTNName), "beremiz.xml")
 
@@ -515,26 +515,26 @@
         # Create a build path in temp folder
         else:
             self.DefaultBuildPath = os.path.join(tempfile.mkdtemp(), os.path.basename(self.ProjectPath), "build")
-            
+
         if not os.path.exists(self.DefaultBuildPath):
             os.makedirs(self.DefaultBuildPath)
         return self.DefaultBuildPath
-    
+
     def _getExtraFilesPath(self):
         return os.path.join(self._getBuildPath(), "extra_files")
 
     def _getIECcodepath(self):
         # define name for IEC code file
         return os.path.join(self._getBuildPath(), "plc.st")
-    
+
     def _getIECgeneratedcodepath(self):
         # define name for IEC generated code file
         return os.path.join(self._getBuildPath(), "generated_plc.st")
-    
+
     def _getIECrawcodepath(self):
         # define name for IEC raw code file
         return os.path.join(self.CTNPath(), "raw_plc.st")
-    
+
     def GetLocations(self):
         locations = []
         filepath = os.path.join(self._getBuildPath(),"LOCATED_VARIABLES.h")
@@ -546,24 +546,29 @@
             # This regular expression parses the lines genereated by IEC2C
             LOCATED_MODEL = re.compile("__LOCATED_VAR\((?P<IEC_TYPE>[A-Z]*),(?P<NAME>[_A-Za-z0-9]*),(?P<DIR>[QMI])(?:,(?P<SIZE>[XBWDL]))?,(?P<LOC>[,0-9]*)\)")
             for line in lines:
-                # If line match RE, 
+                # If line match RE,
                 result = LOCATED_MODEL.match(line)
                 if result:
                     # Get the resulting dict
                     resdict = result.groupdict()
                     # rewrite string for variadic location as a tuple of integers
                     resdict['LOC'] = tuple(map(int,resdict['LOC'].split(',')))
-                    # set located size to 'X' if not given 
+                    # set located size to 'X' if not given
                     if not resdict['SIZE']:
                         resdict['SIZE'] = 'X'
                     # finally store into located variable list
                     locations.append(resdict)
         return locations
-    
+
     def GetConfNodeGlobalInstances(self):
         return self._GlobalInstances()
-    
+
     def _Generate_SoftPLC(self):
+        if self._Generate_PLC_ST():
+            return self._Compile_ST_to_SoftPLC()
+        return False
+
+    def _Generate_PLC_ST(self):
         """
         Generate SoftPLC ST/IL/SFC code out of PLCOpenEditor controller, and compile it with IEC2C
         @param buildpath: path where files should be created
@@ -571,9 +576,8 @@
 
         # Update PLCOpenEditor ConfNode Block types before generate ST code
         self.RefreshConfNodesBlockLists()
-        
+
         self.logger.write(_("Generating SoftPLC IEC-61131 ST/IL/SFC code...\n"))
-        buildpath = self._getBuildPath()
         # ask PLCOpenEditor controller to write ST/IL/SFC code file
         program, errors, warnings = self.GenerateProgram(self._getIECgeneratedcodepath())
         if len(warnings) > 0:
@@ -599,22 +603,25 @@
         plc_file = open(self._getIECcodepath(), "a")
         plc_file.write(open(self._getIECgeneratedcodepath(), "r").read())
         plc_file.close()
-
+        return True
+
+    def _Compile_ST_to_SoftPLC(self):
         self.logger.write(_("Compiling IEC Program into C code...\n"))
+        buildpath = self._getBuildPath()
 
         # Now compile IEC code into many C files
-        # files are listed to stdout, and errors to stderr. 
+        # files are listed to stdout, and errors to stderr.
         status, result, err_result = ProcessLogger(
                self.logger,
                "\"%s\" -f -I \"%s\" -T \"%s\" \"%s\""%(
                          self.iec2c_path,
-                         self.ieclib_path, 
+                         self.ieclib_path,
                          buildpath,
                          self._getIECcodepath()),
                no_stdout=True, no_stderr=True).spin()
         if status:
             # Failed !
-            
+
             # parse iec2c's error message. if it contains a line number,
             # then print those lines from the generated IEC file.
             for err_line in err_result.split('\n'):
@@ -624,7 +631,7 @@
                 if m_result is not None:
                     first_line, first_column, last_line, last_column, error = m_result.groups()
                     first_line, last_line = int(first_line), int(last_line)
-                    
+
                     last_section = None
                     f = open(self._getIECcodepath())
 
@@ -640,10 +647,10 @@
                             self.logger.write_warning("%04d: %s" % (i, line))
 
                     f.close()
-            
+
             self.logger.write_error(_("Error : IEC to C compiler returned %d\n")%status)
             return False
-        
+
         # Now extract C files of stdout
         C_files = [ fname for fname in result.splitlines() if fname[-2:]==".c" or fname[-2:]==".C" ]
         # remove those that are not to be compiled because included by others
@@ -679,7 +686,7 @@
         targetname = self.GetTarget().getcontent().getLocalTag()
         targetclass = targets.GetBuilder(targetname)
 
-        # if target already 
+        # if target already
         if self._builder is None or not isinstance(self._builder,targetclass):
             # Get classname instance
             self._builder = targetclass(self)
@@ -703,20 +710,20 @@
     #                C CODE GENERATION METHODS
     #
     #######################################################################
-    
+
     def CTNGenerate_C(self, buildpath, locations):
         """
-        Return C code generated by iec2c compiler 
+        Return C code generated by iec2c compiler
         when _generate_softPLC have been called
         @param locations: ignored
         @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
         """
 
-        return ([(C_file_name, self.plcCFLAGS) 
-                for C_file_name in self.PLCGeneratedCFiles ], 
+        return ([(C_file_name, self.plcCFLAGS)
+                for C_file_name in self.PLCGeneratedCFiles ],
                "", # no ldflags
                False) # do not expose retreive/publish calls
-    
+
     def ResetIECProgramsAndVariables(self):
         """
         Reset variable and program list that are parsed from
@@ -743,7 +750,7 @@
                 self._ProgramList = []
                 self._VariablesList = []
                 self._IECPathToIdx = {}
-                
+
                 # Separate sections
                 ListGroup = []
                 for line in open(csvfile,'r').xreadlines():
@@ -754,7 +761,7 @@
                     elif len(strippedline) > 0 and len(ListGroup) > 0:
                         # append to this section
                         ListGroup[-1].append(strippedline)
-        
+
                 # first section contains programs
                 for line in ListGroup[0]:
                     # Split and Maps each field to dictionnary entries
@@ -763,7 +770,7 @@
                     attrs["C_path"] = '__'.join(attrs["C_path"].split(".",2)[1:])
                     # Push this dictionnary into result.
                     self._ProgramList.append(attrs)
-        
+
                 # second section contains all variables
                 config_FBs = {}
                 for line in ListGroup[1]:
@@ -776,7 +783,7 @@
                         if config_FB:
                             parts = [config_FB] + parts[2:]
                             attrs["C_path"] = '.'.join(parts)
-                        else: 
+                        else:
                             attrs["C_path"] = '__'.join(parts[1:])
                     else:
                         attrs["C_path"] = '__'.join(parts)
@@ -788,11 +795,11 @@
                     IEC_path=attrs["IEC_path"]
                     Idx=int(attrs["num"])
                     self._IECPathToIdx[IEC_path]=(Idx, attrs["type"])
-                
+
                 # third section contains ticktime
                 if len(ListGroup) > 2:
-                    self._Ticktime = int(ListGroup[2][0]) 
-                
+                    self._Ticktime = int(ListGroup[2][0])
+
             except Exception,e:
                 self.logger.write_error(_("Cannot open/parse VARIABLES.csv!\n"))
                 self.logger.write_error(traceback.format_exc())
@@ -818,7 +825,7 @@
                "MEM":"extern __IEC_%(type)s_p %(C_path)s;",
                "OUT":"extern __IEC_%(type)s_p %(C_path)s;",
                "VAR":"extern __IEC_%(type)s_t %(C_path)s;",
-               "FB":"extern %(type)s %(C_path)s;"}[v["vartype"]]%v 
+               "FB":"extern %(type)s %(C_path)s;"}[v["vartype"]]%v
                for v in self._VariablesList if v["C_path"].find('.')<0]),
            "for_each_variable_do_code":"\n".join([
                {"EXT":"    (*fp)((void*)&(%(C_path)s),%(type)s_P_ENUM);\n",
@@ -836,9 +843,9 @@
                 "OUT":"        return %(type)s_O_ENUM;\n",
                 "VAR":"        return %(type)s_ENUM;\n"}[v["vartype"]]%v
                 for v in self._VariablesList if v["vartype"] != "FB" and v["type"] in DebugTypesSize ])}
-        
+
         return debug_code
-        
+
     def Generate_plc_main(self):
         """
         Use confnodes layout given in LocationCFilesAndCFLAGS to
@@ -848,7 +855,7 @@
         # in retreive, publish, init, cleanup
         locstrs = map(lambda x:"_".join(map(str,x)),
            [loc for loc,Cfiles,DoCalls in self.LocationCFilesAndCFLAGS if loc and DoCalls])
-        
+
         # Generate main, based on template
         if not self.BeremizRoot.getDisable_Extensions():
             plc_main_code = targets.GetCode("plc_main_head") % {
@@ -882,7 +889,7 @@
         plc_main_code += targets.GetCode("plc_main_tail")
         return plc_main_code
 
-        
+
     def _Build(self):
         """
         Method called by user to (re)build SoftPLC and confnode tree
@@ -890,7 +897,7 @@
         if self.AppFrame is not None:
             self.AppFrame.ClearErrors()
         self._CloseView(self._IECCodeView)
-        
+
         buildpath = self._getBuildPath()
 
         # Eventually create build dir
@@ -908,21 +915,52 @@
 
         # If IEC code gen fail, bail out.
         if not IECGenRes:
-            self.logger.write_error(_("IEC-61131-3 code generation failed !\n"))
+            self.logger.write_error(_("PLC code generation failed !\n"))
             self.ResetBuildMD5()
             return False
 
         # Reset variable and program list that are parsed from
         # CSV file generated by IEC2C compiler.
         self.ResetIECProgramsAndVariables()
-        
+
+        # Collect platform specific C code
+        # Code and other files from extension
+        if not self._Generate_runtime():
+            return False
+
+        # Get current or fresh builder
+        builder = self.GetBuilder()
+        if builder is None:
+            self.logger.write_error(_("Fatal : cannot get builder.\n"))
+            self.ResetBuildMD5()
+            return False
+
+        # Build
+        try:
+            if not builder.build() :
+                self.logger.write_error(_("C Build failed.\n"))
+                return False
+        except Exception, exc:
+            self.logger.write_error(_("C Build crashed !\n"))
+            self.logger.write_error(traceback.format_exc())
+            self.ResetBuildMD5()
+            return False
+
+        self.logger.write(_("Successfully built.\n"))
+        # Update GUI status about need for transfer
+        self.CompareLocalAndRemotePLC()
+        return True
+
+    def _Generate_runtime(self):
+        buildpath = self._getBuildPath()
+
         # Generate C code and compilation params from confnode hierarchy
         try:
             CTNLocationCFilesAndCFLAGS, CTNLDFLAGS, CTNExtraFiles = self._Generate_C(
-                buildpath, 
+                buildpath,
                 self.PLCGeneratedLocatedVars)
         except Exception, exc:
-            self.logger.write_error(_("Runtime extensions C code generation failed !\n"))
+            self.logger.write_error(_("Runtime IO extensions C code generation failed !\n"))
             self.logger.write_error(traceback.format_exc())
             self.ResetBuildMD5()
             return False
@@ -931,7 +969,7 @@
         try:
             LibCFilesAndCFLAGS, LibLDFLAGS, LibExtraFiles = self.GetLibrariesCCode(buildpath)
         except Exception, exc:
-            self.logger.write_error(_("Runtime extensions C code generation failed !\n"))
+            self.logger.write_error(_("Runtime library extensions C code generation failed !\n"))
             self.logger.write_error(traceback.format_exc())
             self.ResetBuildMD5()
             return False
@@ -939,7 +977,7 @@
         self.LocationCFilesAndCFLAGS =  CTNLocationCFilesAndCFLAGS + LibCFilesAndCFLAGS
         self.LDFLAGS = CTNLDFLAGS + LibLDFLAGS
         ExtraFiles = CTNExtraFiles + LibExtraFiles
-        
+
         # Get temporary directory path
         extrafilespath = self._getExtraFilesPath()
         # Remove old directory
@@ -953,7 +991,7 @@
             open(fpath, "wb").write(fobject.read())
         # Now we can forget ExtraFiles (will close files object)
         del ExtraFiles
-        
+
         # Header file for extensions
         open(os.path.join(buildpath,"beremiz.h"), "w").write(targets.GetHeader())
 
@@ -978,32 +1016,9 @@
                 self.logger.write_error(traceback.format_exc())
                 self.ResetBuildMD5()
                 return False
-
         self.logger.write(_("C code generated successfully.\n"))
-
-        # Get current or fresh builder
-        builder = self.GetBuilder()
-        if builder is None:
-            self.logger.write_error(_("Fatal : cannot get builder.\n"))
-            self.ResetBuildMD5()
-            return False
-
-        # Build
-        try:
-            if not builder.build() :
-                self.logger.write_error(_("C Build failed.\n"))
-                return False
-        except Exception, exc:
-            self.logger.write_error(_("C Build crashed !\n"))
-            self.logger.write_error(traceback.format_exc())
-            self.ResetBuildMD5()
-            return False
-
-        self.logger.write(_("Successfully built.\n"))
-        # Update GUI status about need for transfer
-        self.CompareLocalAndRemotePLC()
         return True
-    
+
     def ShowError(self, logger, from_location, to_location):
         chunk_infos = self.GetChunkInfos(from_location, to_location)
         for infos, (start_row, start_col) in chunk_infos:
@@ -1011,7 +1026,7 @@
             end = (to_location[0] - start_row, to_location[1] - start_col)
             if self.AppFrame is not None:
                 self.AppFrame.ShowError(infos, start, end)
-    
+
     _IECCodeView = None
     def _showIECcode(self):
         self._OpenView("IEC code")
@@ -1019,20 +1034,20 @@
     _IECRawCodeView = None
     def _editIECrawcode(self):
         self._OpenView("IEC raw code")
-    
+
     _ProjectFilesView = None
     def _OpenProjectFiles(self):
         self._OpenView("Project Files")
-    
+
     _FileEditors = {}
     def _OpenFileEditor(self, filepath):
         self._OpenView(filepath)
-    
+
     def _OpenView(self, name=None, onlyopened=False):
         if name == "IEC code":
             if self._IECCodeView is None:
                 plc_file = self._getIECcodepath()
-            
+
                 self._IECCodeView = IECCodeViewer(self.AppFrame.TabsOpened, "", self.AppFrame, None, instancepath=name)
                 self._IECCodeView.SetTextSyntax("ALL")
                 self._IECCodeView.SetKeywords(IEC_KEYWORDS)
@@ -1043,78 +1058,78 @@
                 self._IECCodeView.SetText(text = text)
                 self._IECCodeView.SetIcon(GetBitmap("ST"))
                 setattr(self._IECCodeView, "_OnClose", self.OnCloseEditor)
-            
+
             if self._IECCodeView is not None:
                 self.AppFrame.EditProjectElement(self._IECCodeView, name)
-            
+
             return self._IECCodeView
-        
+
         elif name == "IEC raw code":
             if self._IECRawCodeView is None:
                 controler = MiniTextControler(self._getIECrawcodepath(), self)
-                
+
                 self._IECRawCodeView = IECCodeViewer(self.AppFrame.TabsOpened, "", self.AppFrame, controler, instancepath=name)
                 self._IECRawCodeView.SetTextSyntax("ALL")
                 self._IECRawCodeView.SetKeywords(IEC_KEYWORDS)
                 self._IECRawCodeView.RefreshView()
                 self._IECRawCodeView.SetIcon(GetBitmap("ST"))
                 setattr(self._IECRawCodeView, "_OnClose", self.OnCloseEditor)
-            
+
             if self._IECRawCodeView is not None:
                 self.AppFrame.EditProjectElement(self._IECRawCodeView, name)
-            
+
             return self._IECRawCodeView
-        
+
         elif name == "Project Files":
             if self._ProjectFilesView is None:
                 self._ProjectFilesView = FileManagementPanel(self.AppFrame.TabsOpened, self, name, self._getProjectFilesPath(), True)
-                
+
                 extensions = []
                 for extension, name, editor in features.file_editors:
                     if extension not in extensions:
                         extensions.append(extension)
-                self._ProjectFilesView.SetEditableFileExtensions(extensions) 
-                
+                self._ProjectFilesView.SetEditableFileExtensions(extensions)
+
             if self._ProjectFilesView is not None:
                 self.AppFrame.EditProjectElement(self._ProjectFilesView, name)
-            
+
             return self._ProjectFilesView
-        
+
         elif name is not None and name.find("::") != -1:
             filepath, editor_name = name.split("::")
             if not self._FileEditors.has_key(filepath):
                 if os.path.isfile(filepath):
                     file_extension = os.path.splitext(filepath)[1]
-                        
+
                     editors = dict([(edit_name, edit_class)
                                     for extension, edit_name, edit_class in features.file_editors
                                     if extension == file_extension])
-                    
+
                     if editor_name == "":
                         if len(editors) == 1:
                             editor_name = editors.keys()[0]
                         elif len(editors) > 0:
                             names = editors.keys()
-                            dialog = wx.SingleChoiceDialog(self.AppFrame, 
-                                  _("Select an editor:"), _("Editor selection"), 
+                            dialog = wx.SingleChoiceDialog(self.AppFrame,
+                                  _("Select an editor:"), _("Editor selection"),
                                   names, wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL)
                             if dialog.ShowModal() == wx.ID_OK:
                                 editor_name = names[dialog.GetSelection()]
                             dialog.Destroy()
-                        
+
                     if editor_name != "":
                         name = "::".join([filepath, editor_name])
-                        
+
                         editor = editors[editor_name]()
                         self._FileEditors[filepath] = editor(self.AppFrame.TabsOpened, self, name, self.AppFrame)
                         self._FileEditors[filepath].SetIcon(GetBitmap("FILE"))
                         if isinstance(self._FileEditors[filepath], DebugViewer):
                             self._FileEditors[filepath].SetDataProducer(self)
-            
+
             if self._FileEditors.has_key(filepath):
                 editor = self._FileEditors[filepath]
                 self.AppFrame.EditProjectElement(editor, editor.GetTagName())
-                
+
             return self._FileEditors.get(filepath)
         else:
             return ConfigTreeNode._OpenView(self, self.CTNName(), onlyopened)
@@ -1147,7 +1162,7 @@
         if log_count:
             if self.AppFrame is not None:
                 self.AppFrame.LogViewer.SetLogCounters(log_count)
-    
+
     def UpdateMethodsFromPLCStatus(self):
         status = None
         if self._connector is not None:
@@ -1184,16 +1199,16 @@
                     self.AppFrame.ConnectionStatusBar.SetStatusText(
                         _("Connected to URI: %s") % self.BeremizRoot.getURI_location().strip(), 1)
                     self.AppFrame.ConnectionStatusBar.SetStatusText(_(status), 2)
-                
+
     def PullPLCStatusProc(self, event):
         self.UpdateMethodsFromPLCStatus()
-        
+
     def SnapshotAndResetDebugValuesBuffers(self):
-        buffers, self.DebugValuesBuffers = (self.DebugValuesBuffers, 
+        buffers, self.DebugValuesBuffers = (self.DebugValuesBuffers,
             [list() for iec_path in self.TracedIECPath])
         ticks, self.DebugTicks = self.DebugTicks, []
         return ticks, buffers
-    
+
     def RegisterDebugVarToConnector(self):
         self.DebugTimer=None
         Idxs = []
@@ -1208,10 +1223,10 @@
                     # This variable is not needed anymore!
                     IECPathsToPop.append(IECPath)
                 elif IECPath != "__tick__":
-                    # Convert 
+                    # Convert
                     Idx, IEC_Type = self._IECPathToIdx.get(IECPath,(None,None))
                     if Idx is not None:
-                        if IEC_Type in DebugTypesSize: 
+                        if IEC_Type in DebugTypesSize:
                             Idxs.append((Idx, IEC_Type, fvalue, IECPath))
                         else:
                             self.logger.write_warning(_("Debug: Unsupported type to debug '%s'\n")%IEC_Type)
@@ -1229,14 +1244,14 @@
                 self._connector.SetTraceVariablesList([])
             self.SnapshotAndResetDebugValuesBuffers()
             self.IECdebug_lock.release()
-    
+
     def IsPLCStarted(self):
         return self.previous_plcstate == "Started"
-    
+
     def ReArmDebugRegisterTimer(self):
         if self.DebugTimer is not None:
             self.DebugTimer.cancel()
-        
+
         # Prevent to call RegisterDebugVarToConnector when PLC is not started
         # If an output location var is forced it's leads to segmentation fault in runtime
         # Links between PLC located variables and real variables are not ready
@@ -1250,16 +1265,16 @@
     def GetDebugIECVariableType(self, IECPath):
         Idx, IEC_Type = self._IECPathToIdx.get(IECPath,(None,None))
         return IEC_Type
-        
+
     def SubscribeDebugIECVariable(self, IECPath, callableobj, buffer_list=False, *args, **kwargs):
         """
         Dispatching use a dictionnary linking IEC variable paths
-        to a WeakKeyDictionary linking 
+        to a WeakKeyDictionary linking
         weakly referenced callables to optionnal args
         """
         if IECPath != "__tick__" and not self._IECPathToIdx.has_key(IECPath):
             return None
-        
+
         self.IECdebug_lock.acquire()
         # If no entry exist, create a new one with a fresh WeakKeyDictionary
         IECdebug_data = self.IECdebug_datas.get(IECPath, None)
@@ -1273,13 +1288,13 @@
             self.IECdebug_datas[IECPath] = IECdebug_data
         else:
             IECdebug_data[4] |= buffer_list
-        
+
         IECdebug_data[0][callableobj]=(buffer_list, args, kwargs)
 
         self.IECdebug_lock.release()
-        
+
         self.ReArmDebugRegisterTimer()
-        
+
         return IECdebug_data[1]
 
     def UnsubscribeDebugIECVariable(self, IECPath, callableobj):
@@ -1292,7 +1307,7 @@
             else:
                 IECdebug_data[4] = reduce(
                     lambda x, y: x|y,
-                    [buffer_list for buffer_list,args,kwargs 
+                    [buffer_list for buffer_list,args,kwargs
                      in IECdebug_data[0].itervalues()],
                     False)
         self.IECdebug_lock.release()
@@ -1309,33 +1324,33 @@
     def ForceDebugIECVariable(self, IECPath, fvalue):
         if not self.IECdebug_datas.has_key(IECPath):
             return
-        
+
         self.IECdebug_lock.acquire()
-        
+
         # If no entry exist, create a new one with a fresh WeakKeyDictionary
         IECdebug_data = self.IECdebug_datas.get(IECPath, None)
         IECdebug_data[2] = "Forced"
         IECdebug_data[3] = fvalue
-        
+
         self.IECdebug_lock.release()
-        
+
         self.ReArmDebugRegisterTimer()
-    
+
     def ReleaseDebugIECVariable(self, IECPath):
         if not self.IECdebug_datas.has_key(IECPath):
             return
-        
+
         self.IECdebug_lock.acquire()
-        
+
         # If no entry exist, create a new one with a fresh WeakKeyDictionary
         IECdebug_data = self.IECdebug_datas.get(IECPath, None)
         IECdebug_data[2] = "Registered"
         IECdebug_data[3] = None
-        
+
         self.IECdebug_lock.release()
-        
+
         self.ReArmDebugRegisterTimer()
-    
+
     def CallWeakcallables(self, IECPath, function_name, *cargs):
         data_tuple = self.IECdebug_datas.get(IECPath, None)
         if data_tuple is not None:
@@ -1415,7 +1430,7 @@
                     self.CallWeakcallables(IECPath, "NewValues", debug_ticks, values)
             if len(debug_ticks) > 0:
                 self.CallWeakcallables("__tick__", "NewDataAvailable", debug_ticks)
-        
+
         delay = time.time() - start_time
         next_refresh = max(REFRESH_PERIOD - delay, 0.2 * delay)
         if self.DispatchDebugValuesTimer is not None and self.DebugThread is not None:
@@ -1437,7 +1452,7 @@
         if self.DispatchDebugValuesTimer is not None:
             self.DispatchDebugValuesTimer.Stop()
 
-    def _connect_debug(self): 
+    def _connect_debug(self):
         self.previous_plcstate = None
         if self.AppFrame:
             self.AppFrame.ResetGraphicViewers()
@@ -1448,7 +1463,7 @@
         if self.DebugThread is None:
             self.DebugThread = Thread(target=self.DebugThreadProc)
             self.DebugThread.start()
-    
+
     def _Run(self):
         """
         Start PLC
@@ -1460,7 +1475,7 @@
         else:
             self.logger.write_error(_("Couldn't start PLC !\n"))
         wx.CallAfter(self.UpdateMethodsFromPLCStatus)
-       
+
     def _Stop(self):
         """
         Stop PLC
@@ -1470,7 +1485,7 @@
 
         # debugthread should die on his own
         #self.KillDebugThread()
-        
+
         wx.CallAfter(self.UpdateMethodsFromPLCStatus)
 
     def _SetConnector(self, connector, update_status=True):
@@ -1493,7 +1508,7 @@
         if self._connector is not None:
             self.logger.write_error(_("Already connected. Please disconnect\n"))
             return
-        
+
         # Get connector uri
         uri = self.\
               BeremizRoot.\
@@ -1512,7 +1527,7 @@
                 self.logger.write_error(_("Local service discovery failed!\n"))
                 self.logger.write_error(traceback.format_exc())
                 uri = None
-            
+
             # Nothing choosed or cancel button
             if uri is None or answer == wx.ID_CANCEL:
                 self.logger.write_error(_("Connection canceled!\n"))
@@ -1529,7 +1544,7 @@
                     self.AppFrame.RefreshFileMenu()
                     self.AppFrame.RefreshEditMenu()
                     self.AppFrame.RefreshPageTitles()
-                           
+
         # Get connector from uri
         try:
             self._SetConnector(connectors.ConnectorFactory(uri, self))
@@ -1547,7 +1562,7 @@
             self.ShowMethod("_Transfer", True)
 
             self.CompareLocalAndRemotePLC()
-            
+
             # Init with actual PLC status and print it
             self.UpdateMethodsFromPLCStatus()
             if self.previous_plcstate is not None:
@@ -1556,7 +1571,7 @@
                 status = ""
 
             #self.logger.write(_("PLC is %s\n")%status)
-            
+
             if self.previous_plcstate in ["Started","Stopped"]:
                 if self.DebugAvailable() and self.GetIECProgramsAndVariables():
                     self.logger.write(_("Debugger ready\n"))
@@ -1590,12 +1605,12 @@
 
     def _Disconnect(self):
         self._SetConnector(None)
-        
+
     def _Transfer(self):
-        # Get the last build PLC's 
+        # Get the last build PLC's
         MD5 = self.GetLastBuildMD5()
-        
-        # Check if md5 file is empty : ask user to build PLC 
+
+        # Check if md5 file is empty : ask user to build PLC
         if MD5 is None :
             self.logger.write_error(_("Failed : Must build before transfer.\n"))
             return False
@@ -1609,12 +1624,12 @@
         extrafiles = []
         for extrafilespath in [self._getExtraFilesPath(),
                                self._getProjectFilesPath()]:
-        
+
             extrafiles.extend(
-                     [(name, open(os.path.join(extrafilespath, name), 
+                     [(name, open(os.path.join(extrafilespath, name),
                                   'rb').read()) \
                       for name in os.listdir(extrafilespath)])
-        
+
         # Send PLC on target
         builder = self.GetBuilder()
         if builder is not None:
--- a/controls/VariablePanel.py	Mon May 26 14:44:03 2014 +0100
+++ b/controls/VariablePanel.py	Fri Jun 06 18:30:49 2014 +0100
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 
 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
-#based on the plcopen standard. 
+#based on the plcopen standard.
 #
 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
 #
@@ -30,7 +30,7 @@
 import wx.grid
 import wx.lib.buttons
 
-from plcopen.structures import LOCATIONDATATYPES, TestIdentifier, IEC_KEYWORDS
+from plcopen.structures import LOCATIONDATATYPES, TestIdentifier, IEC_KEYWORDS, DefaultType
 from graphics.GraphicCommons import REFRESH_HIGHLIGHT_PERIOD, ERROR_HIGHLIGHT
 from dialogs.ArrayTypeDialog import ArrayTypeDialog
 from CustomGrid import CustomGrid
@@ -43,13 +43,7 @@
 #                                 Helpers
 #-------------------------------------------------------------------------------
 
-def AppendMenu(parent, help, id, kind, text):
-    if wx.VERSION >= (2, 6, 0):
-        parent.Append(help=help, id=id, kind=kind, text=text)
-    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)
 
@@ -73,8 +67,8 @@
 
 def GetFilterChoiceTransfer():
     _ = lambda x : x
-    return {_("All"): _("All"), _("Interface"): _("Interface"), 
-            _("   Input"): _("Input"), _("   Output"): _("Output"), _("   InOut"): _("InOut"), 
+    return {_("All"): _("All"), _("Interface"): _("Interface"),
+            _("   Input"): _("Input"), _("   Output"): _("Output"), _("   InOut"): _("InOut"),
             _("   External"): _("External"), _("Variables"): _("Variables"), _("   Local"): _("Local"),
             _("   Temp"): _("Temp"), _("Global"): _("Global")}#, _("Access") : _("Access")}
 VARIABLE_CHOICES_DICT = dict([(_(_class), _class) for _class in GetFilterChoiceTransfer().iterkeys()])
@@ -97,7 +91,7 @@
 #-------------------------------------------------------------------------------
 
 class VariableTable(CustomTable):
-    
+
     """
     A custom wx.grid.Grid Table using user supplied data
     """
@@ -105,7 +99,7 @@
         # The base class must be initialized *first*
         CustomTable.__init__(self, parent, data, colnames)
         self.old_value = None
-    
+
     def GetValueByName(self, row, colname):
         if row < self.GetNumberRows():
             return getattr(self.data[row], colname)
@@ -113,7 +107,7 @@
     def SetValueByName(self, row, colname, value):
         if row < self.GetNumberRows():
             setattr(self.data[row], colname, value)
-    
+
     def GetValue(self, row, col):
         if row < self.GetNumberRows():
             if col == 0:
@@ -130,7 +124,7 @@
             if colname in ["Class", "Option"]:
                 return _(value)
             return value
-    
+
     def SetValue(self, row, col, value):
         if col < len(self.colnames):
             colname = self.GetColLabelValue(col, False)
@@ -209,10 +203,10 @@
                                 editor.SetParameters(",".join([_(choice) for choice in self.Parent.ClassList if choice not in excluded]))
                     elif colname != "Documentation":
                         grid.SetReadOnly(row, col, True)
-                
+
                 grid.SetCellEditor(row, col, editor)
                 grid.SetCellRenderer(row, col, renderer)
-                
+
                 if colname == "Location" and LOCATION_MODEL.match(self.GetValueByName(row, colname)) is None:
                     highlight_colours = ERROR_HIGHLIGHT
                 else:
@@ -223,23 +217,23 @@
 
 #-------------------------------------------------------------------------------
 #                         Variable Panel Drop Target
-#-------------------------------------------------------------------------------   
+#-------------------------------------------------------------------------------
 
 class VariableDropTarget(wx.TextDropTarget):
     '''
     This allows dragging a variable location from somewhere to the Location
     column of a variable row.
-    
+
     The drag source should be a TextDataObject containing a Python tuple like:
         ('%ID0.0.0', 'location', 'REAL')
-    
+
     c_ext/CFileEditor.py has an example of this (you can drag a C extension
     variable to the Location column of the variable panel).
     '''
     def __init__(self, parent):
         wx.TextDropTarget.__init__(self)
         self.ParentWindow = parent
-    
+
     def OnDropText(self, x, y, data):
         self.ParentWindow.ParentWindow.Select()
         x, y = self.ParentWindow.VariablesGrid.CalcUnscrolledPosition(x, y)
@@ -248,7 +242,7 @@
         message = None
         element_type = self.ParentWindow.ElementType
         try:
-            values = eval(data)    
+            values = eval(data)
         except:
             message = _("Invalid value \"%s\" for variable grid element")%data
             values = None
@@ -267,12 +261,12 @@
                         location = values[0]
                         variable_type = self.ParentWindow.Table.GetValueByName(row, "Type")
                         base_type = self.ParentWindow.Controler.GetBaseType(variable_type)
-                        
+
                         if values[2] is not None:
                             base_location_type = self.ParentWindow.Controler.GetBaseType(values[2])
                             if values[2] != variable_type and base_type != base_location_type:
                                 message = _("Incompatible data types between \"%s\" and \"%s\"")%(values[2], variable_type)
-                        
+
                         if message is None:
                             if not location.startswith("%"):
                                 if location[0].isdigit() and base_type != "BOOL":
@@ -282,9 +276,9 @@
                                 elif base_type not in LOCATIONDATATYPES[location[0]]:
                                     message = _("Incompatible size of data between \"%s\" and \"%s\"")%(location, variable_type)
                                 else:
-                                    dialog = wx.SingleChoiceDialog(self.ParentWindow.ParentWindow.ParentWindow, 
-                                          _("Select a variable class:"), _("Variable class"), 
-                                          ["Input", "Output", "Memory"], 
+                                    dialog = wx.SingleChoiceDialog(self.ParentWindow.ParentWindow.ParentWindow,
+                                          _("Select a variable class:"), _("Variable class"),
+                                          ["Input", "Output", "Memory"],
                                           wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL)
                                     if dialog.ShowModal() == wx.ID_OK:
                                         selected = dialog.GetSelection()
@@ -299,7 +293,7 @@
                                         location = "%Q" + location
                                     else:
                                         location = "%M" + location
-                                        
+
                             if message is None:
                                 self.ParentWindow.Table.SetValue(row, col, location)
                                 self.ParentWindow.Table.ResetView(self.ParentWindow.VariablesGrid)
@@ -311,7 +305,7 @@
                         self.ParentWindow.Table.SetValue(row, col, values[0])
                         self.ParentWindow.Table.ResetView(self.ParentWindow.VariablesGrid)
                         self.ParentWindow.SaveValues()
-            elif (element_type not in ["config", "resource", "function"] and values[1] == "Global" and 
+            elif (element_type not in ["config", "resource", "function"] and values[1] == "Global" and
                   self.ParentWindow.Filter in ["All", "Interface", "External"] or
                   element_type != "function" and values[1] == "location"):
                 if values[1] == "location":
@@ -319,11 +313,11 @@
                 else:
                     var_name = values[0]
                 tagname = self.ParentWindow.GetTagName()
-                if var_name.upper() in [name.upper() 
+                if var_name.upper() in [name.upper()
                         for name in self.ParentWindow.Controler.\
                             GetProjectPouNames(self.ParentWindow.Debug)]:
                     message = _("\"%s\" pou already exists!")%var_name
-                elif not var_name.upper() in [name.upper() 
+                elif not var_name.upper() in [name.upper()
                         for name in self.ParentWindow.Controler.\
                             GetEditedElementVariables(tagname, self.ParentWindow.Debug)]:
                     var_infos = self.ParentWindow.DefaultValue.copy()
@@ -332,9 +326,9 @@
                     if values[1] == "location":
                         location = values[0]
                         if not location.startswith("%"):
-                            dialog = wx.SingleChoiceDialog(self.ParentWindow.ParentWindow.ParentWindow, 
-                                  _("Select a variable class:"), _("Variable class"), 
-                                  ["Input", "Output", "Memory"], 
+                            dialog = wx.SingleChoiceDialog(self.ParentWindow.ParentWindow.ParentWindow,
+                                  _("Select a variable class:"), _("Variable class"),
+                                  ["Input", "Output", "Memory"],
                                   wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL)
                             if dialog.ShowModal() == wx.ID_OK:
                                 selected = dialog.GetSelection()
@@ -354,7 +348,7 @@
                                                                 self.ParentWindow.Debug)
                             if len(configs) == 0:
                                 return
-                            if not var_name.upper() in [name.upper() 
+                            if not var_name.upper() in [name.upper()
                                 for name in self.ParentWindow.Controler.\
                                     GetConfigurationVariableNames(configs[0])]:
                                 self.ParentWindow.Controler.AddConfigurationGlobalVar(
@@ -372,10 +366,10 @@
                     self.ParentWindow.Values.append(var_infos)
                     self.ParentWindow.SaveValues()
                     self.ParentWindow.RefreshValues()
-        
+
         if message is not None:
             wx.CallAfter(self.ShowMessage, message)
-    
+
     def ShowMessage(self, message):
         message = wx.MessageDialog(self.ParentWindow, message, _("Error"), wx.OK|wx.ICON_ERROR)
         message.ShowModal()
@@ -383,85 +377,85 @@
 
 #-------------------------------------------------------------------------------
 #                               Variable Panel
-#-------------------------------------------------------------------------------   
+#-------------------------------------------------------------------------------
 
 class VariablePanel(wx.Panel):
-    
+
     def __init__(self, parent, window, controler, element_type, debug=False):
         wx.Panel.__init__(self, parent, style=wx.TAB_TRAVERSAL)
-        
+
         self.MainSizer = wx.FlexGridSizer(cols=1, hgap=10, rows=2, vgap=0)
         self.MainSizer.AddGrowableCol(0)
         self.MainSizer.AddGrowableRow(1)
-        
+
         controls_sizer = wx.FlexGridSizer(cols=10, hgap=5, rows=1, vgap=5)
         controls_sizer.AddGrowableCol(5)
         controls_sizer.AddGrowableRow(0)
         self.MainSizer.AddSizer(controls_sizer, border=5, flag=wx.GROW|wx.ALL)
-        
+
         self.ReturnTypeLabel = wx.StaticText(self, label=_('Return Type:'))
         controls_sizer.AddWindow(self.ReturnTypeLabel, flag=wx.ALIGN_CENTER_VERTICAL)
-        
+
         self.ReturnType = wx.ComboBox(self,
               size=wx.Size(145, -1), style=wx.CB_READONLY)
         self.Bind(wx.EVT_COMBOBOX, self.OnReturnTypeChanged, self.ReturnType)
         controls_sizer.AddWindow(self.ReturnType)
-        
+
         self.DescriptionLabel = wx.StaticText(self, label=_('Description:'))
         controls_sizer.AddWindow(self.DescriptionLabel, flag=wx.ALIGN_CENTER_VERTICAL)
-        
+
         self.Description = wx.TextCtrl(self,
               size=wx.Size(250, -1), style=wx.TE_PROCESS_ENTER)
         self.Bind(wx.EVT_TEXT_ENTER, self.OnDescriptionChanged, self.Description)
         self.Description.Bind(wx.EVT_KILL_FOCUS, self.OnDescriptionChanged)
-        controls_sizer.AddWindow(self.Description) 
-        
+        controls_sizer.AddWindow(self.Description)
+
         class_filter_label = wx.StaticText(self, label=_('Class Filter:'))
         controls_sizer.AddWindow(class_filter_label, flag=wx.ALIGN_CENTER_VERTICAL)
-        
-        self.ClassFilter = wx.ComboBox(self, 
+
+        self.ClassFilter = wx.ComboBox(self,
               size=wx.Size(145, -1), style=wx.CB_READONLY)
         self.Bind(wx.EVT_COMBOBOX, self.OnClassFilter, self.ClassFilter)
         controls_sizer.AddWindow(self.ClassFilter)
-        
+
         for name, bitmap, help in [
                 ("AddButton", "add_element", _("Add variable")),
                 ("DeleteButton", "remove_element", _("Remove variable")),
                 ("UpButton", "up", _("Move variable up")),
                 ("DownButton", "down", _("Move variable down"))]:
-            button = wx.lib.buttons.GenBitmapButton(self, bitmap=GetBitmap(bitmap), 
+            button = wx.lib.buttons.GenBitmapButton(self, bitmap=GetBitmap(bitmap),
                   size=wx.Size(28, 28), style=wx.NO_BORDER)
             button.SetToolTipString(help)
             setattr(self, name, button)
             controls_sizer.AddWindow(button)
-        
+
         self.VariablesGrid = CustomGrid(self, style=wx.VSCROLL)
         self.VariablesGrid.SetDropTarget(VariableDropTarget(self))
-        self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, 
+        self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE,
               self.OnVariablesGridCellChange)
-        self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, 
+        self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK,
               self.OnVariablesGridCellLeftClick)
-        self.VariablesGrid.Bind(wx.grid.EVT_GRID_EDITOR_SHOWN, 
+        self.VariablesGrid.Bind(wx.grid.EVT_GRID_EDITOR_SHOWN,
               self.OnVariablesGridEditorShown)
         self.MainSizer.AddWindow(self.VariablesGrid, flag=wx.GROW)
-        
+
         self.SetSizer(self.MainSizer)
-        
+
         self.ParentWindow = window
         self.Controler = controler
         self.ElementType = element_type
         self.Debug = debug
-        
+
         self.RefreshHighlightsTimer = wx.Timer(self, -1)
-        self.Bind(wx.EVT_TIMER, self.OnRefreshHighlightsTimer, 
+        self.Bind(wx.EVT_TIMER, self.OnRefreshHighlightsTimer,
               self.RefreshHighlightsTimer)
-        
+
         self.Filter = "All"
         self.FilterChoices = []
         self.FilterChoiceTransfer = GetFilterChoiceTransfer()
-        
-        self.DefaultValue = _VariableInfos("", "", "", "", "", True, "", "INT", ([], []), 0)
-        
+
+        self.DefaultValue = _VariableInfos("", "", "", "", "", True, "", DefaultType, ([], []), 0)
+
         if element_type in ["config", "resource"]:
             self.DefaultTypes = {"All" : "Global"}
         else:
@@ -481,7 +475,7 @@
 
             # these condense the ColAlignements list
             l = wx.ALIGN_LEFT
-            c = wx.ALIGN_CENTER 
+            c = wx.ALIGN_CENTER
 
             #                      Num  Name    Class   Type    Loc     Init    Option   Doc
             self.ColSizes       = [40,  80,     70,     80,     80,     80,     100,     80]
@@ -502,15 +496,15 @@
 
             # these condense the ColAlignements list
             l = wx.ALIGN_LEFT
-            c = wx.ALIGN_CENTER 
+            c = wx.ALIGN_CENTER
 
             #                      Num  Name    Class   Type    Init    Option   Doc
             self.ColSizes       = [40,  80,     70,     80,     80,     100,     160]
             self.ColAlignements = [c,   l,      l,      l,      l,      l,       l]
-            
+
         self.ElementType = element_type
         self.BodyType = None
-        
+
         for choice in self.FilterChoices:
             self.ClassFilter.Append(_(choice))
 
@@ -526,11 +520,11 @@
                                        "Up": self.UpButton,
                                        "Down": self.DownButton})
         self.VariablesGrid.SetEditable(not self.Debug)
-        
+
         def _AddVariable(new_row):
             if new_row > 0:
                 row_content = self.Values[new_row - 1].copy()
-                
+
                 result = VARIABLE_NAME_SUFFIX_MODEL.search(row_content.Name)
                 if result is not None:
                     name = row_content.Name[:result.start(1)]
@@ -546,8 +540,8 @@
                 row_content = None
                 start_idx = 0
                 name = "LocalVar"
-                
-            if row_content is not None and row_content.Edit: 
+
+            if row_content is not None and row_content.Edit:
                 row_content = self.Values[new_row - 1].copy()
             else:
                 row_content = self.DefaultValue.copy()
@@ -555,10 +549,10 @@
                     row_content.Class = self.DefaultTypes[self.Filter]
                 else:
                     row_content.Class = self.Filter
-            
+
             row_content.Name = self.Controler.GenerateNewName(
                     self.TagName, None, name + "%d", start_idx)
-            
+
             if self.Filter == "All" and len(self.Values) > 0:
                 self.Values.insert(new_row, row_content)
             else:
@@ -568,7 +562,7 @@
             self.RefreshValues()
             return new_row
         setattr(self.VariablesGrid, "_AddRow", _AddVariable)
-        
+
         def _DeleteVariable(row):
             if self.Table.GetValueByName(row, "Edit"):
                 self.Values.remove(self.Table.GetRow(row))
@@ -577,7 +571,7 @@
                     self.ParentWindow.RefreshView(variablepanel = False)
                 self.RefreshValues()
         setattr(self.VariablesGrid, "_DeleteRow", _DeleteVariable)
-            
+
         def _MoveVariable(row, move):
             if self.Filter == "All":
                 new_row = max(0, min(row + move, len(self.Values) - 1))
@@ -588,7 +582,7 @@
                 return new_row
             return row
         setattr(self.VariablesGrid, "_MoveRow", _MoveVariable)
-        
+
         def _RefreshButtons():
             if self:
                 table_length = len(self.Table.data)
@@ -603,7 +597,7 @@
                 self.UpButton.Enable(not self.Debug and (table_length > 0 and row > 0 and self.Filter == "All"))
                 self.DownButton.Enable(not self.Debug and (table_length > 0 and row < table_length - 1 and self.Filter == "All"))
         setattr(self.VariablesGrid, "RefreshButtons", _RefreshButtons)
-        
+
         self.VariablesGrid.SetRowLabelSize(0)
         for col in range(self.Table.GetNumberCols()):
             attr = wx.grid.GridCellAttr()
@@ -611,29 +605,29 @@
             self.VariablesGrid.SetColAttr(col, attr)
             self.VariablesGrid.SetColMinimalWidth(col, self.ColSizes[col])
             self.VariablesGrid.AutoSizeColumn(col, False)
-    
+
     def __del__(self):
         self.RefreshHighlightsTimer.Stop()
-    
+
     def SetTagName(self, tagname):
         self.TagName = tagname
         self.BodyType = self.Controler.GetEditedElementBodyType(self.TagName)
-    
+
     def GetTagName(self):
         return self.TagName
-    
+
     def IsFunctionBlockType(self, name):
-        if (isinstance(name, TupleType) or 
+        if (isinstance(name, TupleType) or
             self.ElementType != "function" and self.BodyType in ["ST", "IL"]):
             return False
         else:
             return self.Controler.GetBlockType(name, debug=self.Debug) is not None
-    
+
     def RefreshView(self):
         self.PouNames = self.Controler.GetProjectPouNames(self.Debug)
         returnType = None
         description = None
-        
+
         words = self.TagName.split("::")
         if self.ElementType == "config":
             self.Values = self.Controler.GetConfigurationGlobalVars(words[1], self.Debug)
@@ -647,7 +641,7 @@
                 returnType = self.Controler.GetEditedElementInterfaceReturnType(self.TagName, debug=self.Debug)
             description = self.Controler.GetPouDescription(words[1])
             self.Values = self.Controler.GetEditedElementInterfaceVars(self.TagName, debug=self.Debug)
-        
+
         if returnType is not None:
             self.ReturnType.SetStringSelection(returnType)
             self.ReturnType.Enable(not self.Debug)
@@ -657,7 +651,7 @@
             self.ReturnType.Enable(False)
             self.ReturnTypeLabel.Hide()
             self.ReturnType.Hide()
-        
+
         if description is not None:
             self.Description.SetValue(description)
             self.Description.Enable(not self.Debug)
@@ -667,11 +661,11 @@
             self.Description.Enable(False)
             self.DescriptionLabel.Hide()
             self.Description.Hide()
-        
+
         self.RefreshValues()
         self.VariablesGrid.RefreshButtons()
         self.MainSizer.Layout()
-    
+
     def OnReturnTypeChanged(self, event):
         words = self.TagName.split("::")
         self.Controler.SetPouInterfaceReturnType(words[1], self.ReturnType.GetStringSelection())
@@ -679,7 +673,7 @@
         self.ParentWindow.RefreshView(variablepanel = False)
         self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
         event.Skip()
-    
+
     def OnDescriptionChanged(self, event):
         words = self.TagName.split("::")
         old_description = self.Controler.GetPouDescription(words[1])
@@ -688,7 +682,7 @@
             self.Controler.SetPouDescription(words[1], new_description)
             self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
         event.Skip()
-    
+
     def OnClassFilter(self, event):
         self.Filter = self.FilterChoiceTransfer[VARIABLE_CHOICES_DICT[self.ClassFilter.GetStringSelection()]]
         self.RefreshTypeList()
@@ -711,7 +705,7 @@
         colname = self.Table.GetColLabelValue(col, False)
         value = self.Table.GetValue(row, col)
         message = None
-        
+
         if colname == "Name" and value != "":
             if not TestIdentifier(value):
                 message = _("\"%s\" is not a valid identifier!") % value
@@ -735,7 +729,7 @@
                 wx.CallAfter(self.ParentWindow.RefreshView, False)
             elif colname == "Location":
                 wx.CallAfter(self.ParentWindow.RefreshView)
-            
+
         if message is not None:
             dialog = wx.MessageDialog(self, message, _("Error"), wx.OK|wx.ICON_ERROR)
             dialog.ShowModal()
@@ -743,64 +737,77 @@
             event.Veto()
         else:
             event.Skip()
-    
-    def OnVariablesGridEditorShown(self, event):
-        row, col = event.GetRow(), event.GetCol() 
-
-        label_value = self.Table.GetColLabelValue(col, False)
-        if label_value == "Type":
-            type_menu = wx.Menu(title='')   # the root menu
-
+
+    def BuildStdIECTypesMenu(self,type_menu):
             # build a submenu containing standard IEC types
             base_menu = wx.Menu(title='')
             for base_type in self.Controler.GetBaseTypes():
                 new_id = wx.NewId()
-                AppendMenu(base_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=base_type)
+                base_menu.Append(help='', id=new_id, kind=wx.ITEM_NORMAL, text=base_type)
                 self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(base_type), id=new_id)
 
             type_menu.AppendMenu(wx.NewId(), _("Base Types"), base_menu)
 
+    def BuildUserTypesMenu(self,type_menu):
             # build a submenu containing user-defined types
             datatype_menu = wx.Menu(title='')
             datatypes = self.Controler.GetDataTypes(basetypes = False, confnodetypes = False)
             for datatype in datatypes:
                 new_id = wx.NewId()
-                AppendMenu(datatype_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=datatype)
+                datatype_menu.Append(help='', id=new_id, kind=wx.ITEM_NORMAL, text=datatype)
                 self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(datatype), id=new_id)
 
             type_menu.AppendMenu(wx.NewId(), _("User Data Types"), datatype_menu)
-            
-            for category in self.Controler.GetConfNodeDataTypes():
-               
-               if len(category["list"]) > 0:
-                   # build a submenu containing confnode types
-                   confnode_datatype_menu = wx.Menu(title='')
-                   for datatype in category["list"]:
-                       new_id = wx.NewId()
-                       AppendMenu(confnode_datatype_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=datatype)
-                       self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(datatype), id=new_id)
-                   
-                   type_menu.AppendMenu(wx.NewId(), category["name"], confnode_datatype_menu)
-
-            # build a submenu containing function block types
-            bodytype = self.Controler.GetEditedElementBodyType(self.TagName)
-            pouname, poutype = self.Controler.GetEditedElementType(self.TagName)
+
+    def BuildLibsTypesMenu(self, type_menu):
+        for category in self.Controler.GetConfNodeDataTypes():
+            if len(category["list"]) > 0:
+                # build a submenu containing confnode types
+                confnode_datatype_menu = wx.Menu(title='')
+                for datatype in category["list"]:
+                    new_id = wx.NewId()
+                    confnode_datatype_menu.Append(help='', id=new_id, kind=wx.ITEM_NORMAL, text=datatype)
+                    self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(datatype), id=new_id)
+
+                type_menu.AppendMenu(wx.NewId(), category["name"], confnode_datatype_menu)
+
+    def BuildProjectTypesMenu(self, type_menu, classtype):
+        # build a submenu containing function block types
+        bodytype = self.Controler.GetEditedElementBodyType(self.TagName)
+        pouname, poutype = self.Controler.GetEditedElementType(self.TagName)
+        if classtype in ["Input", "Output", "InOut", "External", "Global"] or \
+        poutype != "function" and bodytype in ["ST", "IL"]:
+            functionblock_menu = wx.Menu(title='')
+            fbtypes = self.Controler.GetFunctionBlockTypes(self.TagName)
+            for functionblock_type in fbtypes:
+                new_id = wx.NewId()
+                functionblock_menu.Append(help='', id=new_id, kind=wx.ITEM_NORMAL, text=functionblock_type)
+                self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(functionblock_type), id=new_id)
+
+            type_menu.AppendMenu(wx.NewId(), _("Function Block Types"), functionblock_menu)
+
+    def BuildArrayTypesMenu(self, type_menu):
+        new_id = wx.NewId()
+        type_menu.Append(help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Array"))
+        self.Bind(wx.EVT_MENU, self.VariableArrayTypeFunction, id=new_id)
+
+    def OnVariablesGridEditorShown(self, event):
+        row, col = event.GetRow(), event.GetCol()
+
+        label_value = self.Table.GetColLabelValue(col, False)
+        if label_value == "Type":
             classtype = self.Table.GetValueByName(row, "Class")
-            
-            new_id = wx.NewId()
-            AppendMenu(type_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Array"))
-            self.Bind(wx.EVT_MENU, self.VariableArrayTypeFunction, id=new_id)
-            
-            if classtype in ["Input", "Output", "InOut", "External", "Global"] or \
-            poutype != "function" and bodytype in ["ST", "IL"]:
-                functionblock_menu = wx.Menu(title='')
-                fbtypes = self.Controler.GetFunctionBlockTypes(self.TagName)
-                for functionblock_type in fbtypes:
-                    new_id = wx.NewId()
-                    AppendMenu(functionblock_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=functionblock_type)
-                    self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(functionblock_type), id=new_id)
-
-                type_menu.AppendMenu(wx.NewId(), _("Function Block Types"), functionblock_menu)
+            type_menu = wx.Menu(title='')   # the root menu
+
+            self.BuildStdIECTypesMenu(type_menu)
+
+            self.BuildUserTypesMenu(type_menu)
+
+            self.BuildLibsTypesMenu(type_menu)
+
+            self.BuildProjectTypesMenu(type_menu,classtype)
+
+            self.BuildArrayTypesMenu(type_menu)
 
             rect = self.VariablesGrid.BlockToDeviceRect((row, col), (row, col))
             corner_x = rect.x + rect.width
@@ -812,7 +819,7 @@
             event.Veto()
         else:
             event.Skip()
-    
+
     def GetVariableTypeFunction(self, base_type):
         def VariableTypeFunction(event):
             row = self.VariablesGrid.GetGridCursorRow()
@@ -823,11 +830,11 @@
             self.Controler.BufferProject()
             self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
         return VariableTypeFunction
-    
+
     def VariableArrayTypeFunction(self, event):
         row = self.VariablesGrid.GetGridCursorRow()
-        dialog = ArrayTypeDialog(self, 
-                                 self.Controler.GetDataTypes(self.TagName), 
+        dialog = ArrayTypeDialog(self,
+                                 self.Controler.GetDataTypes(self.TagName),
                                  self.Table.GetValueByName(row, "Type"))
         if dialog.ShowModal() == wx.ID_OK:
             self.Table.SetValueByName(row, "Type", dialog.GetValue())
@@ -837,7 +844,7 @@
             self.Controler.BufferProject()
             self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
         dialog.Destroy()
-    
+
     def OnVariablesGridCellLeftClick(self, event):
         row = event.GetRow()
         if not self.Debug and (event.GetCol() == 0 and self.Table.GetValueByName(row, "Edit")):
@@ -849,7 +856,7 @@
             dragSource.SetData(data)
             dragSource.DoDragDrop()
         event.Skip()
-    
+
     def RefreshValues(self):
         data = []
         for num, variable in enumerate(self.Values):
@@ -858,7 +865,7 @@
                 data.append(variable)
         self.Table.SetData(data)
         self.Table.ResetView(self.VariablesGrid)
-            
+
     def SaveValues(self, buffer = True):
         words = self.TagName.split("::")
         if self.ElementType == "config":
@@ -871,7 +878,7 @@
             self.Controler.SetPouInterfaceVars(words[1], self.Values)
         if buffer:
             self.Controler.BufferProject()
-            self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)            
+            self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
 
 #-------------------------------------------------------------------------------
 #                        Highlights showing functions
--- a/editors/CodeFileEditor.py	Mon May 26 14:44:03 2014 +0100
+++ b/editors/CodeFileEditor.py	Fri Jun 06 18:30:49 2014 +0100
@@ -6,7 +6,7 @@
 import wx.lib.buttons
 
 from plcopen.plcopen import TestTextElement
-from plcopen.structures import TestIdentifier, IEC_KEYWORDS
+from plcopen.structures import TestIdentifier, IEC_KEYWORDS, DefaultType
 from controls import CustomGrid, CustomTable
 from editors.ConfTreeNodeEditor import ConfTreeNodeEditor
 from util.BitmapLibrary import GetBitmap
@@ -14,7 +14,7 @@
 from controls.VariablePanel import VARIABLE_NAME_SUFFIX_MODEL
 from graphics.GraphicCommons import ERROR_HIGHLIGHT, SEARCH_RESULT_HIGHLIGHT, REFRESH_HIGHLIGHT_PERIOD
 
-[STC_CODE_ERROR, STC_CODE_SEARCH_RESULT, 
+[STC_CODE_ERROR, STC_CODE_SEARCH_RESULT,
  STC_CODE_SECTION] = range(15, 18)
 
 HIGHLIGHT_TYPES = {
@@ -25,14 +25,14 @@
 EDGE_COLUMN = 80
 
 class CodeEditor(CustomStyledTextCtrl):
-    
+
     KEYWORDS = []
     COMMENT_HEADER = ""
 
     def __init__(self, parent, window, controler):
-        CustomStyledTextCtrl.__init__(self, parent, -1, wx.DefaultPosition, 
+        CustomStyledTextCtrl.__init__(self, parent, -1, wx.DefaultPosition,
                  wx.Size(-1, 300), 0)
-        
+
         self.SetMarginType(1, stc.STC_MARGIN_NUMBER)
         self.SetMarginWidth(1, 25)
 
@@ -41,7 +41,7 @@
         self.SetMargins(0,0)
 
         self.SetViewWhiteSpace(False)
-        
+
         self.SetEdgeMode(stc.STC_EDGE_BACKGROUND)
         self.SetEdgeColumn(EDGE_COLUMN)
 
@@ -59,7 +59,7 @@
         self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND,     stc.STC_MARK_BOXPLUSCONNECTED,  "white", "#808080")
         self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_BOXMINUSCONNECTED, "white", "#808080")
         self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_TCORNER,           "white", "#808080")
-        
+
         self.Bind(stc.EVT_STC_UPDATEUI, self.OnUpdateUI)
         self.Bind(stc.EVT_STC_MARGINCLICK, self.OnMarginClick)
         self.Bind(wx.EVT_KEY_DOWN, self.OnKeyPressed)
@@ -78,33 +78,33 @@
         self.StyleSetSpec(stc.STC_STYLE_CONTROLCHAR, "face:%(mono)s" % faces)
         self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT,  "fore:#FFFFFF,back:#0000FF,bold")
         self.StyleSetSpec(stc.STC_STYLE_BRACEBAD,    "fore:#000000,back:#FF0000,bold")
-        
+
         # Highlighting styles
         self.StyleSetSpec(STC_CODE_ERROR, 'fore:#FF0000,back:#FFFF00,size:%(size)d' % faces)
         self.StyleSetSpec(STC_CODE_SEARCH_RESULT, 'fore:#FFFFFF,back:#FFA500,size:%(size)d' % faces)
-        
+
         # Section style
         self.StyleSetSpec(STC_CODE_SECTION, 'fore:#808080,size:%(size)d')
         self.StyleSetChangeable(STC_CODE_SECTION, False)
-        
+
         # Indentation size
         self.SetTabWidth(4)
         self.SetUseTabs(0)
-        
+
         self.SetCodeLexer()
         self.SetKeyWords(0, " ".join(self.KEYWORDS))
-        
+
         self.Controler = controler
         self.ParentWindow = window
-        
+
         self.DisableEvents = True
         self.CurrentAction = None
-        
+
         self.ResetSearchResults()
-        
+
         self.RefreshHighlightsTimer = wx.Timer(self, -1)
         self.Bind(wx.EVT_TIMER, self.OnRefreshHighlightsTimer, self.RefreshHighlightsTimer)
-        
+
         self.SectionsComments = {}
         for section in self.Controler.SECTIONS_NAMES:
             section_comment = " %s section " % (section)
@@ -112,11 +112,11 @@
             section_comment = self.COMMENT_HEADER * (len_headers / 2) + \
                               section_comment + \
                               self.COMMENT_HEADER * (len_headers - len_headers / 2)
-            
+
             self.SectionsComments[section] = {
                  "comment": section_comment,
             }
-            
+
         for i, section in enumerate(self.Controler.SECTIONS_NAMES):
             section_infos = self.SectionsComments[section]
             if i + 1 < len(self.Controler.SECTIONS_NAMES):
@@ -125,24 +125,24 @@
             else:
                 section_end = "$"
             section_infos["pattern"] = re.compile(
-                section_infos["comment"] + "(.*)" + 
+                section_infos["comment"] + "(.*)" +
                 section_end, re.DOTALL)
-            
+
         self.SetModEventMask(wx.stc.STC_MOD_BEFOREINSERT|wx.stc.STC_MOD_BEFOREDELETE)
 
         self.Bind(wx.stc.EVT_STC_DO_DROP, self.OnDoDrop)
         self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
         self.Bind(wx.stc.EVT_STC_MODIFIED, self.OnModification)
-    
+
     def SetCodeLexer(self):
         pass
-    
+
     def ResetSearchResults(self):
         self.Highlights = []
         self.SearchParams = None
         self.SearchResults = None
         self.CurrentFindHighlight = None
-    
+
     def OnModification(self, event):
         if not self.DisableEvents:
             mod_type = event.GetModificationType()
@@ -165,7 +165,7 @@
                     wx.CallAfter(self.RefreshModel)
         wx.CallAfter(self.RefreshSectionStyling)
         event.Skip()
-    
+
     def OnDoDrop(self, event):
         try:
             values = eval(event.GetDragText())
@@ -192,7 +192,7 @@
             self.ParentWindow.RefreshFileMenu()
             self.ParentWindow.RefreshEditMenu()
             self.ParentWindow.RefreshPageTitles()
-    
+
     def StartBuffering(self):
         self.Controler.StartBuffering()
         if self.ParentWindow is not None:
@@ -200,7 +200,7 @@
             self.ParentWindow.RefreshFileMenu()
             self.ParentWindow.RefreshEditMenu()
             self.ParentWindow.RefreshPageTitles()
-    
+
     def ResetBuffer(self):
         if self.CurrentAction != None:
             self.Controler.EndBuffering()
@@ -240,18 +240,18 @@
                 self.GotoPos(old_cursor_pos)
             self.EmptyUndoBuffer()
         self.DisableEvents = False
-        
+
         self.RefreshSectionStyling()
-        
+
         self.ShowHighlights()
-        
+
     def RefreshSectionStyling(self):
         self.Colourise(0, -1)
-        
+
         text = self.GetText()
         for line in xrange(self.GetLineCount()):
             self.SetLineState(line, 0)
-        
+
         for section in self.Controler.SECTIONS_NAMES:
             section_comments = self.SectionsComments[section]
             start_pos = text.find(section_comments["comment"])
@@ -259,7 +259,7 @@
             self.StartStyling(start_pos, 0xff)
             self.SetStyling(end_pos - start_pos, STC_CODE_SECTION)
             self.SetLineState(self.LineFromPosition(start_pos), 1)
-            
+
         self.StartStyling(end_pos, 0x00)
         self.SetStyling(len(self.GetText()) - end_pos, stc.STC_STYLE_DEFAULT)
 
@@ -278,7 +278,7 @@
                 parts[section] = ""
         self.Controler.SetTextParts(parts)
         self.ResetSearchResults()
-    
+
     def OnKeyPressed(self, event):
         if self.CallTipActive():
             self.CallTipCancel()
@@ -286,14 +286,14 @@
         current_pos = self.GetCurrentPos()
         selected = self.GetSelection()
         text_selected = selected[0] != selected[1]
-        
+
         # Test if caret is before Windows like new line
         text = self.GetText()
         if current_pos < len(text) and ord(text[current_pos]) == 13:
             newline_size = 2
         else:
             newline_size = 1
-        
+
         # Disable to type any character in section header lines
         if (self.GetLineState(self.LineFromPosition(current_pos)) and
             not text_selected and
@@ -301,7 +301,7 @@
                 wx.WXK_RETURN,
                 wx.WXK_NUMPAD_ENTER]):
             return
-        
+
         # Disable to delete line between code and header lines
         elif (self.GetCurLine()[0].strip() != "" and not text_selected and
               (key == wx.WXK_BACK and
@@ -309,7 +309,7 @@
                key in [wx.WXK_DELETE, wx.WXK_NUMPAD_DELETE] and
                self.GetLineState(self.LineFromPosition(min(len(text), current_pos + newline_size))))):
             return
-        
+
         elif key == 32 and event.ControlDown():
             pos = self.GetCurrentPos()
 
@@ -319,7 +319,7 @@
             # Code completion
             else:
                 self.AutoCompSetIgnoreCase(False)  # so this needs to match
-                
+
                 keywords = self.KEYWORDS + [var["Name"]
                                             for var in self.Controler.GetVariables()]
                 keywords.sort()
@@ -361,11 +361,11 @@
             self.BraceBadLight(braceAtCaret)
         else:
             self.BraceHighlight(braceAtCaret, braceOpposite)
-        
+
         selected_text = self.GetSelectedText()
         if selected_text:
             self.ParentWindow.SetCopyBuffer(selected_text, True)
-    
+
     def OnMarginClick(self, event):
         # fold and unfold as needed
         if evt.GetMargin() == 2:
@@ -464,11 +464,11 @@
         self.DisableEvents = False
         self.RefreshModel()
         self.RefreshBuffer()
-    
+
     def Copy(self):
         self.CmdKeyExecute(wx.stc.STC_CMD_COPY)
         self.ParentWindow.RefreshEditMenu()
-    
+
     def Paste(self):
         self.ResetBuffer()
         self.DisableEvents = True
@@ -480,21 +480,21 @@
     def Find(self, direction, search_params):
         if self.SearchParams != search_params:
             self.ClearHighlights(SEARCH_RESULT_HIGHLIGHT)
-            
+
             self.SearchParams = search_params
             criteria = {
-                "raw_pattern": search_params["find_pattern"], 
+                "raw_pattern": search_params["find_pattern"],
                 "pattern": re.compile(search_params["find_pattern"]),
                 "case_sensitive": search_params["case_sensitive"],
                 "regular_expression": search_params["regular_expression"],
                 "filter": "all"}
-            
+
             self.SearchResults = [
                 (start, end, SEARCH_RESULT_HIGHLIGHT)
-                for start, end, text in 
+                for start, end, text in
                 TestTextElement(self.GetText(), criteria)]
             self.CurrentFindHighlight = None
-        
+
         if len(self.SearchResults) > 0:
             if self.CurrentFindHighlight is not None:
                 old_idx = self.SearchResults.index(self.CurrentFindHighlight)
@@ -522,9 +522,9 @@
                         break
                 if self.CurrentFindHighlight is not None:
                     self.AddHighlight(*self.CurrentFindHighlight)
-            
+
             self.ScrollToLine(self.CurrentFindHighlight[0][0])
-            
+
         else:
             if self.CurrentFindHighlight is not None:
                 self.RemoveHighlight(*self.CurrentFindHighlight)
@@ -557,11 +557,11 @@
 
     def RemoveHighlight(self, start, end, highlight_type):
         highlight_type = HIGHLIGHT_TYPES.get(highlight_type, None)
-        if (highlight_type is not None and 
+        if (highlight_type is not None and
             (start, end, highlight_type) in self.Highlights):
             self.Highlights.remove((start, end, highlight_type))
             self.RefreshHighlightsTimer.Start(int(REFRESH_HIGHLIGHT_PERIOD * 1000), oneShot=True)
-    
+
     def ShowHighlights(self):
         for start, end, highlight_type in self.Highlights:
             if start[0] == 0:
@@ -583,14 +583,14 @@
 #-------------------------------------------------------------------------------
 
 class VariablesTable(CustomTable):
-    
+
     def GetValue(self, row, col):
         if row < self.GetNumberRows():
             if col == 0:
                 return row + 1
             else:
                 return str(self.data[row].get(self.GetColLabelValue(col, False), ""))
-    
+
     def _updateColAttrs(self, grid):
         """
         wxGrid -> update the column attributes to add the
@@ -598,7 +598,7 @@
 
         Otherwise default to the default renderer.
         """
-        
+
         typelist = None
         accesslist = None
         for row in range(self.GetNumberRows()):
@@ -606,7 +606,7 @@
                 editor = None
                 renderer = None
                 colname = self.GetColLabelValue(col, False)
-                
+
                 if colname in ["Name", "Initial"]:
                     editor = wx.grid.GridCellTextEditor()
                 elif colname == "Class":
@@ -616,49 +616,49 @@
                     pass
                 else:
                     grid.SetReadOnly(row, col, True)
-                
+
                 grid.SetCellEditor(row, col, editor)
                 grid.SetCellRenderer(row, col, renderer)
-                
+
                 grid.SetCellBackgroundColour(row, col, wx.WHITE)
             self.ResizeRow(grid, row)
 
 
 class VariablesEditor(wx.Panel):
-    
+
     def __init__(self, parent, window, controler):
         wx.Panel.__init__(self, parent, style=wx.TAB_TRAVERSAL)
-        
+
         main_sizer = wx.FlexGridSizer(cols=2, hgap=0, rows=1, vgap=4)
         main_sizer.AddGrowableCol(1)
         main_sizer.AddGrowableRow(0)
-        
+
         controls_sizer = wx.BoxSizer(wx.VERTICAL)
         main_sizer.AddSizer(controls_sizer, border=5, flag=wx.ALL)
-        
+
         for name, bitmap, help in [
                 ("AddVariableButton", "add_element", _("Add variable")),
                 ("DeleteVariableButton", "remove_element", _("Remove variable")),
                 ("UpVariableButton", "up", _("Move variable up")),
                 ("DownVariableButton", "down", _("Move variable down"))]:
-            button = wx.lib.buttons.GenBitmapButton(self, bitmap=GetBitmap(bitmap), 
+            button = wx.lib.buttons.GenBitmapButton(self, bitmap=GetBitmap(bitmap),
                   size=wx.Size(28, 28), style=wx.NO_BORDER)
             button.SetToolTipString(help)
             setattr(self, name, button)
             controls_sizer.AddWindow(button, border=5, flag=wx.BOTTOM)
-        
+
         self.VariablesGrid = CustomGrid(self, style=wx.VSCROLL)
         self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnVariablesGridCellChange)
         self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.OnVariablesGridCellLeftClick)
         self.VariablesGrid.Bind(wx.grid.EVT_GRID_EDITOR_SHOWN, self.OnVariablesGridEditorShown)
         main_sizer.AddWindow(self.VariablesGrid, flag=wx.GROW)
-        
+
         self.SetSizer(main_sizer)
-                
+
         self.ParentWindow = window
         self.Controler = controler
-        
-        self.VariablesDefaultValue = {"Name" : "", "Type" : "INT", "Initial": ""}
+
+        self.VariablesDefaultValue = {"Name" : "", "Type" : DefaultType, "Initial": ""}
         self.Table = VariablesTable(self, [], ["#", "Name", "Type", "Initial"])
         self.ColAlignements = [wx.ALIGN_RIGHT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT]
         self.ColSizes = [40, 200, 150, 150]
@@ -667,7 +667,7 @@
                                        "Delete": self.DeleteVariableButton,
                                        "Up": self.UpVariableButton,
                                        "Down": self.DownVariableButton})
-        
+
         def _AddVariable(new_row):
             if new_row > 0:
                 row_content = self.Table.data[new_row - 1].copy()
@@ -691,13 +691,13 @@
             self.RefreshView()
             return new_row
         setattr(self.VariablesGrid, "_AddRow", _AddVariable)
-        
+
         def _DeleteVariable(row):
             self.Table.RemoveRow(row)
             self.RefreshModel()
             self.RefreshView()
         setattr(self.VariablesGrid, "_DeleteRow", _DeleteVariable)
-        
+
         def _MoveVariable(row, move):
             new_row = self.Table.MoveRow(row, move)
             if new_row != row:
@@ -705,7 +705,7 @@
                 self.RefreshView()
             return new_row
         setattr(self.VariablesGrid, "_MoveRow", _MoveVariable)
-        
+
         self.VariablesGrid.SetRowLabelSize(0)
         for col in range(self.Table.GetNumberCols()):
             attr = wx.grid.GridCellAttr()
@@ -717,7 +717,7 @@
     def RefreshModel(self):
         self.Controler.SetVariables(self.Table.GetData())
         self.RefreshBuffer()
-        
+
     # Buffer the last model state
     def RefreshBuffer(self):
         self.Controler.BufferCodeFile()
@@ -730,23 +730,23 @@
         self.Table.SetData(self.Controler.GetVariables())
         self.Table.ResetView(self.VariablesGrid)
         self.VariablesGrid.RefreshButtons()
-    
+
     def DoGetBestSize(self):
         return self.ParentWindow.GetPanelBestSize()
-    
+
     def OnVariablesGridCellChange(self, event):
         row, col = event.GetRow(), event.GetCol()
         colname = self.Table.GetColLabelValue(col, False)
         value = self.Table.GetValue(row, col)
         message = None
-        
+
         if colname == "Name" and value != "":
             if not TestIdentifier(value):
                 message = _("\"%s\" is not a valid identifier!") % value
             elif value.upper() in IEC_KEYWORDS:
                 message = _("\"%s\" is a keyword. It can't be used!") % value
-            elif value.upper() in [var["Name"].upper() 
-                                   for var_row, var in enumerate(self.Table.data) 
+            elif value.upper() in [var["Name"].upper()
+                                   for var_row, var in enumerate(self.Table.data)
                                    if var_row != row]:
                 message = _("A variable with \"%s\" as name already exists!") % value
             else:
@@ -755,7 +755,7 @@
         else:
             self.RefreshModel()
             wx.CallAfter(self.RefreshView)
-        
+
         if message is not None:
             dialog = wx.MessageDialog(self, message, _("Error"), wx.OK|wx.ICON_ERROR)
             dialog.ShowModal()
@@ -765,7 +765,7 @@
             event.Skip()
 
     def OnVariablesGridEditorShown(self, event):
-        row, col = event.GetRow(), event.GetCol() 
+        row, col = event.GetRow(), event.GetCol()
         if self.Table.GetColLabelValue(col, False) == "Type":
             type_menu = wx.Menu(title='')
             base_menu = wx.Menu(title='')
@@ -781,7 +781,7 @@
                 self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(datatype), id=new_id)
             type_menu.AppendMenu(wx.NewId(), "User Data Types", datatype_menu)
             rect = self.VariablesGrid.BlockToDeviceRect((row, col), (row, col))
-            
+
             self.VariablesGrid.PopupMenuXY(type_menu, rect.x + rect.width, rect.y + self.VariablesGrid.GetColLabelSize())
             type_menu.Destroy()
             event.Veto()
@@ -803,64 +803,64 @@
             row = event.GetRow()
             data_type = self.Table.GetValueByName(row, "Type")
             var_name = self.Table.GetValueByName(row, "Name")
-            data = wx.TextDataObject(str((var_name, "Global", data_type, 
+            data = wx.TextDataObject(str((var_name, "Global", data_type,
                     self.Controler.GetCurrentLocation())))
             dragSource = wx.DropSource(self.VariablesGrid)
             dragSource.SetData(data)
             dragSource.DoDragDrop()
             return
         event.Skip()
-    
+
 
 #-------------------------------------------------------------------------------
 #                          CodeFileEditor Main Frame Class
 #-------------------------------------------------------------------------------
 
 class CodeFileEditor(ConfTreeNodeEditor):
-    
+
     CONFNODEEDITOR_TABS = []
     CODE_EDITOR = None
-    
+
     def _create_CodePanel(self, prnt):
         self.CodeEditorPanel = wx.SplitterWindow(prnt)
         self.CodeEditorPanel.SetMinimumPaneSize(1)
-        
-        self.VariablesPanel = VariablesEditor(self.CodeEditorPanel, 
+
+        self.VariablesPanel = VariablesEditor(self.CodeEditorPanel,
                 self.ParentWindow, self.Controler)
-        
+
         if self.CODE_EDITOR is not None:
-            self.CodeEditor = self.CODE_EDITOR(self.CodeEditorPanel, 
+            self.CodeEditor = self.CODE_EDITOR(self.CodeEditorPanel,
                         self.ParentWindow, self.Controler)
-            
-            self.CodeEditorPanel.SplitHorizontally(self.VariablesPanel, 
+
+            self.CodeEditorPanel.SplitHorizontally(self.VariablesPanel,
                     self.CodeEditor, 150)
         else:
             self.CodeEditorPanel.Initialize(self.VariablesPanel)
-        
+
         return self.CodeEditorPanel
-    
+
     def __init__(self, parent, controler, window):
         ConfTreeNodeEditor.__init__(self, parent, controler, window)
-        
+
         wx.CallAfter(self.CodeEditorPanel.SetSashPosition, 150)
-    
+
     def GetBufferState(self):
         return self.Controler.GetBufferState()
-        
+
     def Undo(self):
         self.Controler.LoadPrevious()
         self.RefreshView()
-            
+
     def Redo(self):
         self.Controler.LoadNext()
         self.RefreshView()
-    
+
     def RefreshView(self):
         ConfTreeNodeEditor.RefreshView(self)
-        
+
         self.VariablesPanel.RefreshView()
         self.CodeEditor.RefreshView()
-    
+
     def Find(self, direction, search_params):
         self.CodeEditor.Find(direction, search_params)
-        
\ No newline at end of file
+
--- a/editors/DataTypeEditor.py	Mon May 26 14:44:03 2014 +0100
+++ b/editors/DataTypeEditor.py	Fri Jun 06 18:30:49 2014 +0100
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 
 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
-#based on the plcopen standard. 
+#based on the plcopen standard.
 #
 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
 #
@@ -29,7 +29,7 @@
 import wx.grid
 import wx.lib.buttons
 
-from plcopen.structures import IEC_KEYWORDS, TestIdentifier
+from plcopen.structures import IEC_KEYWORDS, TestIdentifier, DefaultType
 from graphics.GraphicCommons import REFRESH_HIGHLIGHT_PERIOD
 from controls import CustomEditableListBox, CustomGrid, CustomTable
 from dialogs import ArrayTypeDialog
@@ -59,7 +59,7 @@
 #-------------------------------------------------------------------------------
 
 class ElementsTable(CustomTable):
-    
+
     """
     A custom wx.grid.Grid Table using user supplied data
     """
@@ -67,7 +67,7 @@
         # The base class must be initialized *first*
         CustomTable.__init__(self, parent, data, colnames)
         self.old_value = None
-        
+
     def GetValue(self, row, col):
         if row < self.GetNumberRows():
             if col == 0:
@@ -78,17 +78,17 @@
                 if value[0] == "array":
                     return "ARRAY [%s] OF %s" % (",".join(map(lambda x : "..".join(x), value[2])), value[1])
             return str(value)
-    
+
     def SetValue(self, row, col, value):
         if col < len(self.colnames):
             colname = self.GetColLabelValue(col, False)
             if colname == "Name":
                 self.old_value = self.data[row][colname]
             self.data[row][colname] = value
-    
+
     def GetOldValue(self):
         return self.old_value
-    
+
     def _updateColAttrs(self, grid):
         """
         wx.grid.Grid -> update the column attributes to add the
@@ -96,7 +96,7 @@
 
         Otherwise default to the default renderer.
         """
-        
+
         for row in range(self.GetNumberRows()):
             row_highlights = self.Highlights.get(row, {})
             for col in range(self.GetNumberCols()):
@@ -115,15 +115,15 @@
                         editor = wx.grid.GridCellTextEditor()
                 else:
                     grid.SetReadOnly(row, col, True)
-                
+
                 grid.SetCellEditor(row, col, editor)
                 grid.SetCellRenderer(row, col, renderer)
-                
+
                 highlight_colours = row_highlights.get(colname.lower(), [(wx.WHITE, wx.BLACK)])[-1]
                 grid.SetCellBackgroundColour(row, col, highlight_colours[0])
                 grid.SetCellTextColour(row, col, highlight_colours[1])
             self.ResizeRow(grid, row)
-    
+
     def AddHighlight(self, infos, highlight_type):
         row_highlights = self.Highlights.setdefault(infos[0], {})
         if infos[1] == "initial":
@@ -137,216 +137,216 @@
 #-------------------------------------------------------------------------------
 
 class DataTypeEditor(EditorPanel):
-    
+
     def _init_Editor(self, parent):
         self.Editor = wx.Panel(parent, style=wx.SUNKEN_BORDER)
-        
+
         self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
         self.MainSizer.AddGrowableCol(0)
         self.MainSizer.AddGrowableRow(1)
-        
+
         top_sizer = wx.BoxSizer(wx.HORIZONTAL)
-        self.MainSizer.AddSizer(top_sizer, border=5, 
+        self.MainSizer.AddSizer(top_sizer, border=5,
               flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
-        
+
         derivation_type_label = wx.StaticText(self.Editor, label=_('Derivation Type:'))
-        top_sizer.AddWindow(derivation_type_label, border=5, 
+        top_sizer.AddWindow(derivation_type_label, border=5,
               flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT)
-        
+
         self.DerivationType = wx.ComboBox(self.Editor,
               size=wx.Size(200, -1), style=wx.CB_READONLY)
         self.Bind(wx.EVT_COMBOBOX, self.OnDerivationTypeChanged, self.DerivationType)
         top_sizer.AddWindow(self.DerivationType, border=5, flag=wx.GROW|wx.RIGHT)
-        
+
         typeinfos_staticbox = wx.StaticBox(self.Editor, label=_('Type infos:'))
         typeinfos_sizer = wx.StaticBoxSizer(typeinfos_staticbox, wx.HORIZONTAL)
-        self.MainSizer.AddSizer(typeinfos_sizer, border=5, 
+        self.MainSizer.AddSizer(typeinfos_sizer, border=5,
               flag=wx.GROW|wx.BOTTOM|wx.LEFT|wx.RIGHT)
-        
+
         # Panel for Directly derived data types
 
         self.DirectlyPanel = wx.Panel(self.Editor, style=wx.TAB_TRAVERSAL)
         typeinfos_sizer.AddWindow(self.DirectlyPanel, 1)
-        
+
         directly_panel_sizer = wx.BoxSizer(wx.HORIZONTAL)
-        
-        directly_basetype_label = wx.StaticText(self.DirectlyPanel, 
+
+        directly_basetype_label = wx.StaticText(self.DirectlyPanel,
               label=_('Base Type:'))
-        directly_panel_sizer.AddWindow(directly_basetype_label, 1, border=5, 
+        directly_panel_sizer.AddWindow(directly_basetype_label, 1, border=5,
               flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL)
-        
+
         self.DirectlyBaseType = wx.ComboBox(self.DirectlyPanel, style=wx.CB_READONLY)
         self.Bind(wx.EVT_COMBOBOX, self.OnInfosChanged, self.DirectlyBaseType)
-        directly_panel_sizer.AddWindow(self.DirectlyBaseType, 1, border=5, 
+        directly_panel_sizer.AddWindow(self.DirectlyBaseType, 1, border=5,
               flag=wx.GROW|wx.ALL)
-        
+
         directly_initialvalue_label = wx.StaticText(self.DirectlyPanel,
               label=_('Initial Value:'))
-        directly_panel_sizer.AddWindow(directly_initialvalue_label, 1, border=5, 
+        directly_panel_sizer.AddWindow(directly_initialvalue_label, 1, border=5,
               flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL)
-        
-        self.DirectlyInitialValue = wx.TextCtrl(self.DirectlyPanel, 
+
+        self.DirectlyInitialValue = wx.TextCtrl(self.DirectlyPanel,
               style=wx.TE_PROCESS_ENTER|wx.TE_RICH)
         self.Bind(wx.EVT_TEXT_ENTER, self.OnReturnKeyPressed, self.DirectlyInitialValue)
-        directly_panel_sizer.AddWindow(self.DirectlyInitialValue, 1, border=5, 
+        directly_panel_sizer.AddWindow(self.DirectlyInitialValue, 1, border=5,
               flag=wx.ALL)
-        
+
         self.DirectlyPanel.SetSizer(directly_panel_sizer)
-        
+
         # Panel for Subrange data types
 
         self.SubrangePanel = wx.Panel(self.Editor, style=wx.TAB_TRAVERSAL)
         typeinfos_sizer.AddWindow(self.SubrangePanel, 1)
-        
+
         subrange_panel_sizer = wx.GridSizer(cols=4, hgap=5, rows=3, vgap=0)
-        
+
         subrange_basetype_label = wx.StaticText(self.SubrangePanel,
               label=_('Base Type:'))
-        subrange_panel_sizer.AddWindow(subrange_basetype_label, 1, border=5, 
+        subrange_panel_sizer.AddWindow(subrange_basetype_label, 1, border=5,
               flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL)
-        
+
         self.SubrangeBaseType = wx.ComboBox(self.SubrangePanel, style=wx.CB_READONLY)
-        self.Bind(wx.EVT_COMBOBOX, self.OnSubrangeBaseTypeChanged, 
+        self.Bind(wx.EVT_COMBOBOX, self.OnSubrangeBaseTypeChanged,
               self.SubrangeBaseType)
-        subrange_panel_sizer.AddWindow(self.SubrangeBaseType, 1, border=5, 
+        subrange_panel_sizer.AddWindow(self.SubrangeBaseType, 1, border=5,
               flag=wx.GROW|wx.ALL)
-        
+
         subrange_initialvalue_label = wx.StaticText(self.SubrangePanel,
               label=_('Initial Value:'))
-        subrange_panel_sizer.AddWindow(subrange_initialvalue_label, 1, border=5, 
+        subrange_panel_sizer.AddWindow(subrange_initialvalue_label, 1, border=5,
               flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL)
-        
-        self.SubrangeInitialValue = wx.SpinCtrl(self.SubrangePanel, 
+
+        self.SubrangeInitialValue = wx.SpinCtrl(self.SubrangePanel,
               style=wx.TAB_TRAVERSAL)
         self.Bind(wx.EVT_SPINCTRL, self.OnInfosChanged, self.SubrangeInitialValue)
-        subrange_panel_sizer.AddWindow(self.SubrangeInitialValue, 1, border=5, 
+        subrange_panel_sizer.AddWindow(self.SubrangeInitialValue, 1, border=5,
               flag=wx.GROW|wx.ALL)
-        
+
         subrange_minimum_label = wx.StaticText(self.SubrangePanel, label=_('Minimum:'))
-        subrange_panel_sizer.AddWindow(subrange_minimum_label, 1, border=5, 
+        subrange_panel_sizer.AddWindow(subrange_minimum_label, 1, border=5,
               flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL)
-        
+
         self.SubrangeMinimum = wx.SpinCtrl(self.SubrangePanel, style=wx.TAB_TRAVERSAL)
         self.Bind(wx.EVT_SPINCTRL, self.OnSubrangeMinimumChanged, self.SubrangeMinimum)
-        subrange_panel_sizer.AddWindow(self.SubrangeMinimum, 1, border=5, 
+        subrange_panel_sizer.AddWindow(self.SubrangeMinimum, 1, border=5,
               flag=wx.GROW|wx.ALL)
-        
+
         for i in xrange(2):
             subrange_panel_sizer.AddWindow(wx.Size(0, 0), 1)
-        
+
         subrange_maximum_label = wx.StaticText(self.SubrangePanel,
               label=_('Maximum:'))
-        subrange_panel_sizer.AddWindow(subrange_maximum_label, 1, border=5, 
+        subrange_panel_sizer.AddWindow(subrange_maximum_label, 1, border=5,
               flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL)
-        
+
         self.SubrangeMaximum = wx.SpinCtrl(self.SubrangePanel, style=wx.TAB_TRAVERSAL)
         self.Bind(wx.EVT_SPINCTRL, self.OnSubrangeMaximumChanged, self.SubrangeMaximum)
-        
-        subrange_panel_sizer.AddWindow(self.SubrangeMaximum, 1, border=5, 
+
+        subrange_panel_sizer.AddWindow(self.SubrangeMaximum, 1, border=5,
               flag=wx.GROW|wx.ALL)
-        
+
         self.SubrangePanel.SetSizer(subrange_panel_sizer)
-        
+
         # Panel for Enumerated data types
-        
+
         self.EnumeratedPanel = wx.Panel(self.Editor, style=wx.TAB_TRAVERSAL)
         typeinfos_sizer.AddWindow(self.EnumeratedPanel, 1)
-        
+
         enumerated_panel_sizer = wx.BoxSizer(wx.HORIZONTAL)
-        
-        self.EnumeratedValues = CustomEditableListBox(self.EnumeratedPanel, 
-              label=_("Values:"), style=wx.gizmos.EL_ALLOW_NEW| 
-                                        wx.gizmos.EL_ALLOW_EDIT| 
+
+        self.EnumeratedValues = CustomEditableListBox(self.EnumeratedPanel,
+              label=_("Values:"), style=wx.gizmos.EL_ALLOW_NEW|
+                                        wx.gizmos.EL_ALLOW_EDIT|
                                         wx.gizmos.EL_ALLOW_DELETE)
         setattr(self.EnumeratedValues, "_OnLabelEndEdit", self.OnEnumeratedValueEndEdit)
         for func in ["_OnAddButton", "_OnDelButton", "_OnUpButton", "_OnDownButton"]:
             setattr(self.EnumeratedValues, func, self.OnEnumeratedValuesChanged)
-        enumerated_panel_sizer.AddWindow(self.EnumeratedValues, 1, border=5, 
+        enumerated_panel_sizer.AddWindow(self.EnumeratedValues, 1, border=5,
               flag=wx.GROW|wx.ALL)
-        
+
         enumerated_panel_rightsizer = wx.BoxSizer(wx.HORIZONTAL)
         enumerated_panel_sizer.AddSizer(enumerated_panel_rightsizer, 1)
-        
+
         enumerated_initialvalue_label = wx.StaticText(self.EnumeratedPanel,
               label=_('Initial Value:'))
-        enumerated_panel_rightsizer.AddWindow(enumerated_initialvalue_label, 1, 
+        enumerated_panel_rightsizer.AddWindow(enumerated_initialvalue_label, 1,
               border=5, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL)
-        
-        self.EnumeratedInitialValue = wx.ComboBox(self.EnumeratedPanel, 
+
+        self.EnumeratedInitialValue = wx.ComboBox(self.EnumeratedPanel,
               style=wx.CB_READONLY)
         self.Bind(wx.EVT_COMBOBOX, self.OnInfosChanged, self.EnumeratedInitialValue)
-        enumerated_panel_rightsizer.AddWindow(self.EnumeratedInitialValue, 1, 
+        enumerated_panel_rightsizer.AddWindow(self.EnumeratedInitialValue, 1,
               border=5, flag=wx.ALL)
-        
+
         self.EnumeratedPanel.SetSizer(enumerated_panel_sizer)
-        
+
         # Panel for Array data types
 
         self.ArrayPanel = wx.Panel(self.Editor, style=wx.TAB_TRAVERSAL)
         typeinfos_sizer.AddWindow(self.ArrayPanel, 1)
-        
+
         array_panel_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=0)
         array_panel_sizer.AddGrowableCol(0)
         array_panel_sizer.AddGrowableCol(1)
         array_panel_sizer.AddGrowableRow(1)
-        
+
         array_panel_leftSizer = wx.BoxSizer(wx.HORIZONTAL)
         array_panel_sizer.AddSizer(array_panel_leftSizer, flag=wx.GROW)
-        
+
         array_basetype_label = wx.StaticText(self.ArrayPanel, label=_('Base Type:'))
-        array_panel_leftSizer.AddWindow(array_basetype_label, 1, border=5, 
+        array_panel_leftSizer.AddWindow(array_basetype_label, 1, border=5,
               flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL)
-        
+
         self.ArrayBaseType = wx.ComboBox(self.ArrayPanel, style=wx.CB_READONLY)
         self.Bind(wx.EVT_COMBOBOX, self.OnInfosChanged, self.ArrayBaseType)
-        array_panel_leftSizer.AddWindow(self.ArrayBaseType, 1, border=5, 
+        array_panel_leftSizer.AddWindow(self.ArrayBaseType, 1, border=5,
               flag=wx.GROW|wx.ALL)
-    
+
         array_panel_rightsizer = wx.BoxSizer(wx.HORIZONTAL)
         array_panel_sizer.AddSizer(array_panel_rightsizer, flag=wx.GROW)
-        
+
         array_initialvalue_label = wx.StaticText(self.ArrayPanel,
               label=_('Initial Value:'))
-        array_panel_rightsizer.AddWindow(array_initialvalue_label, 1, border=5, 
+        array_panel_rightsizer.AddWindow(array_initialvalue_label, 1, border=5,
               flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL)
-        
+
         self.ArrayInitialValue = wx.TextCtrl(self.ArrayPanel,
               style=wx.TE_PROCESS_ENTER|wx.TE_RICH)
         self.Bind(wx.EVT_TEXT_ENTER, self.OnReturnKeyPressed, self.ArrayInitialValue)
-        array_panel_rightsizer.AddWindow(self.ArrayInitialValue, 1, border=5, 
-              flag=wx.ALL)        
-        
-        self.ArrayDimensions = CustomEditableListBox(self.ArrayPanel, 
+        array_panel_rightsizer.AddWindow(self.ArrayInitialValue, 1, border=5,
+              flag=wx.ALL)
+
+        self.ArrayDimensions = CustomEditableListBox(self.ArrayPanel,
               label=_("Dimensions:"), style=wx.gizmos.EL_ALLOW_NEW|
                                             wx.gizmos.EL_ALLOW_EDIT|
                                             wx.gizmos.EL_ALLOW_DELETE)
-        for func in ["_OnLabelEndEdit", "_OnAddButton", "_OnDelButton", 
+        for func in ["_OnLabelEndEdit", "_OnAddButton", "_OnDelButton",
                      "_OnUpButton", "_OnDownButton"]:
             setattr(self.ArrayDimensions, func, self.OnDimensionsChanged)
-        array_panel_sizer.AddWindow(self.ArrayDimensions, 0, border=5, 
+        array_panel_sizer.AddWindow(self.ArrayDimensions, 0, border=5,
               flag=wx.GROW|wx.ALL)
-        
+
         self.ArrayPanel.SetSizer(array_panel_sizer)
-        
+
         # Panel for Structure data types
-        
+
         self.StructurePanel = wx.Panel(self.Editor, style=wx.TAB_TRAVERSAL)
         typeinfos_sizer.AddWindow(self.StructurePanel, 1)
-        
+
         structure_panel_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
         structure_panel_sizer.AddGrowableCol(0)
         structure_panel_sizer.AddGrowableRow(1)
-        
+
         structure_button_sizer = wx.FlexGridSizer(cols=5, hgap=5, rows=1, vgap=0)
         structure_button_sizer.AddGrowableCol(0)
         structure_button_sizer.AddGrowableRow(0)
-        structure_panel_sizer.AddSizer(structure_button_sizer, 0, border=5, 
+        structure_panel_sizer.AddSizer(structure_button_sizer, 0, border=5,
               flag=wx.ALL|wx.GROW)
-        
+
         structure_elements_label = wx.StaticText(self.StructurePanel,
               label=_('Elements :'))
         structure_button_sizer.AddWindow(structure_elements_label, flag=wx.ALIGN_BOTTOM)
-        
+
         for name, bitmap, help in [
                 ("StructureAddButton", "add_element", _("Add element")),
                 ("StructureDeleteButton", "remove_element", _("Remove element")),
@@ -357,46 +357,46 @@
             button.SetToolTipString(help)
             setattr(self, name, button)
             structure_button_sizer.AddWindow(button)
-        
-        self.StructureElementsGrid = CustomGrid(self.StructurePanel, 
+
+        self.StructureElementsGrid = CustomGrid(self.StructurePanel,
               size=wx.Size(0, 150), style=wx.VSCROLL)
-        self.StructureElementsGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, 
+        self.StructureElementsGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE,
               self.OnStructureElementsGridCellChange)
-        self.StructureElementsGrid.Bind(wx.grid.EVT_GRID_EDITOR_SHOWN, 
+        self.StructureElementsGrid.Bind(wx.grid.EVT_GRID_EDITOR_SHOWN,
               self.OnStructureElementsGridEditorShown)
         structure_panel_sizer.AddWindow(self.StructureElementsGrid, flag=wx.GROW)
-        
+
         self.StructurePanel.SetSizer(structure_panel_sizer)
-        
+
         self.Editor.SetSizer(self.MainSizer)
-        
+
     def __init__(self, parent, tagname, window, controler):
         EditorPanel.__init__(self, parent, tagname, window, controler)
-        
-        self.StructureElementDefaultValue = {"Name" : "", "Type" : "INT", "Initial Value" : ""}
+
+        self.StructureElementDefaultValue = {"Name" : "", "Type" : DefaultType, "Initial Value" : ""}
         self.StructureElementsTable = ElementsTable(self, [], GetElementsTableColnames())
         self.StructureColSizes = [40, 150, 100, 250]
         self.StructureColAlignements = [wx.ALIGN_CENTER, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT]
-        
+
         self.StructureElementsGrid.SetTable(self.StructureElementsTable)
         self.StructureElementsGrid.SetButtons({"Add": self.StructureAddButton,
                                                "Delete": self.StructureDeleteButton,
                                                "Up": self.StructureUpButton,
                                                "Down": self.StructureDownButton})
-        
+
         def _AddStructureElement(new_row):
             self.StructureElementsTable.InsertRow(new_row, self.StructureElementDefaultValue.copy())
             self.RefreshTypeInfos()
             self.StructureElementsTable.ResetView(self.StructureElementsGrid)
             return new_row
         setattr(self.StructureElementsGrid, "_AddRow", _AddStructureElement)
-        
+
         def _DeleteStructureElement(row):
             self.StructureElementsTable.RemoveRow(row)
             self.RefreshTypeInfos()
             self.StructureElementsTable.ResetView(self.StructureElementsGrid)
         setattr(self.StructureElementsGrid, "_DeleteRow", _DeleteStructureElement)
-            
+
         def _MoveStructureElement(row, move):
             new_row = self.StructureElementsTable.MoveRow(row, move)
             if new_row != row:
@@ -404,7 +404,7 @@
                 self.StructureElementsTable.ResetView(self.StructureElementsGrid)
             return new_row
         setattr(self.StructureElementsGrid, "_MoveRow", _MoveStructureElement)
-        
+
         self.StructureElementsGrid.SetRowLabelSize(0)
         for col in range(self.StructureElementsTable.GetNumberCols()):
             attr = wx.grid.GridCellAttr()
@@ -413,7 +413,7 @@
             self.StructureElementsGrid.SetColMinimalWidth(col, self.StructureColSizes[col])
             self.StructureElementsGrid.AutoSizeColumn(col, False)
         self.StructureElementsGrid.RefreshButtons()
-        
+
         for datatype in GetDatatypeTypes():
             self.DerivationType.Append(_(datatype))
         self.SubrangePanel.Hide()
@@ -423,7 +423,7 @@
         self.CurrentPanel = "Directly"
         self.Highlights = []
         self.Initializing = False
-        
+
         self.HighlightControls = {
             ("Directly", "base"): self.DirectlyBaseType,
             ("Directly", "initial"): self.DirectlyInitialValue,
@@ -437,27 +437,27 @@
             ("Array", "base"): self.ArrayBaseType,
             ("Array", "range"): self.ArrayDimensions,
         }
-        
+
         self.RefreshHighlightsTimer = wx.Timer(self, -1)
         self.Bind(wx.EVT_TIMER, self.OnRefreshHighlightsTimer, self.RefreshHighlightsTimer)
-        
+
     def __del__(self):
         self.RefreshHighlightsTimer.Stop()
-    
+
     def GetBufferState(self):
         return self.Controler.GetBufferState()
-        
+
     def Undo(self):
         self.Controler.LoadPrevious()
         self.ParentWindow.CloseTabsWithoutModel()
-            
+
     def Redo(self):
         self.Controler.LoadNext()
         self.ParentWindow.CloseTabsWithoutModel()
-    
+
     def HasNoModel(self):
         return self.Controler.GetEditedElement(self.TagName) is None
-        
+
     def RefreshView(self):
         self.Initializing = True
         self.DirectlyBaseType.Clear()
@@ -504,7 +504,7 @@
         self.StructureElementsTable.ResetView(self.StructureElementsGrid)
         self.StructureElementsGrid.RefreshButtons()
         self.Initializing = False
-    
+
     def OnDerivationTypeChanged(self, event):
         wx.CallAfter(self.RefreshDisplayedInfos)
         wx.CallAfter(self.RefreshTypeInfos)
@@ -512,7 +512,7 @@
 
     def OnReturnKeyPressed(self, event):
         self.RefreshTypeInfos()
-        
+
     def OnInfosChanged(self, event):
         self.RefreshTypeInfos()
         event.Skip()
@@ -563,12 +563,12 @@
                 event.Skip()
         else:
             event.Skip()
-    
+
     def OnEnumeratedValuesChanged(self, event):
         wx.CallAfter(self.RefreshEnumeratedValues)
         wx.CallAfter(self.RefreshTypeInfos)
         event.Skip()
-    
+
     def OnStructureElementsGridCellChange(self, event):
         row, col = event.GetRow(), event.GetCol()
         colname = self.StructureElementsTable.GetColLabelValue(col, False)
@@ -606,34 +606,34 @@
             self.RefreshTypeInfos()
             wx.CallAfter(self.StructureElementsTable.ResetView, self.StructureElementsGrid)
             event.Skip()
-    
+
     def OnStructureElementsGridSelectCell(self, event):
         wx.CallAfter(self.RefreshStructureButtons)
         event.Skip()
-    
+
     def OnStructureElementsGridEditorShown(self, event):
-        row, col = event.GetRow(), event.GetCol() 
+        row, col = event.GetRow(), event.GetCol()
         if self.StructureElementsTable.GetColLabelValue(col, False) == "Type":
             type_menu = wx.Menu(title='')
-            
+
             base_menu = wx.Menu(title='')
             for base_type in self.Controler.GetBaseTypes():
                 new_id = wx.NewId()
                 AppendMenu(base_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=base_type)
                 self.Bind(wx.EVT_MENU, self.GetElementTypeFunction(base_type), id=new_id)
             type_menu.AppendMenu(wx.NewId(), _("Base Types"), base_menu)
-            
+
             datatype_menu = wx.Menu(title='')
             for datatype in self.Controler.GetDataTypes(self.TagName, False):
                 new_id = wx.NewId()
                 AppendMenu(datatype_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=datatype)
                 self.Bind(wx.EVT_MENU, self.GetElementTypeFunction(datatype), id=new_id)
             type_menu.AppendMenu(wx.NewId(), _("User Data Types"), datatype_menu)
-            
+
             new_id = wx.NewId()
             AppendMenu(type_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Array"))
             self.Bind(wx.EVT_MENU, self.ElementArrayTypeFunction, id=new_id)
-            
+
 ##            functionblock_menu = wx.Menu(title='')
 ##            bodytype = self.Controler.GetEditedElementBodyType(self.TagName)
 ##            pouname, poutype = self.Controler.GetEditedElementType(self.TagName)
@@ -661,8 +661,8 @@
 
     def ElementArrayTypeFunction(self, event):
         row = self.StructureElementsGrid.GetGridCursorRow()
-        dialog = ArrayTypeDialog(self, 
-                                 self.Controler.GetDataTypes(self.TagName), 
+        dialog = ArrayTypeDialog(self,
+                                 self.Controler.GetDataTypes(self.TagName),
                                  self.StructureElementsTable.GetValueByName(row, "Type"))
         if dialog.ShowModal() == wx.ID_OK:
             self.StructureElementsTable.SetValueByName(row, "Type", dialog.GetValue())
--- a/editors/TextViewer.py	Mon May 26 14:44:03 2014 +0100
+++ b/editors/TextViewer.py	Fri Jun 06 18:30:49 2014 +0100
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 
 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
-#based on the plcopen standard. 
+#based on the plcopen standard.
 #
 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
 #
@@ -45,8 +45,8 @@
     LETTERS.append(chr(ord('a') + i))
     LETTERS.append(chr(ord('A') + i))
 
-[STC_PLC_WORD, STC_PLC_COMMENT, STC_PLC_NUMBER, STC_PLC_STRING, 
- STC_PLC_VARIABLE, STC_PLC_PARAMETER, STC_PLC_FUNCTION, STC_PLC_JUMP, 
+[STC_PLC_WORD, STC_PLC_COMMENT, STC_PLC_NUMBER, STC_PLC_STRING,
+ STC_PLC_VARIABLE, STC_PLC_PARAMETER, STC_PLC_FUNCTION, STC_PLC_JUMP,
  STC_PLC_ERROR, STC_PLC_SEARCH_RESULT] = range(10)
 [SPACE, WORD, NUMBER, STRING, WSTRING, COMMENT, PRAGMA, DPRAGMA] = range(8)
 
@@ -70,35 +70,35 @@
     return reduce(lambda x, y: x or y, map(lambda x: line.startswith(x), symbols), False)
 
 class TextViewer(EditorPanel):
-    
+
     ID = ID_TEXTVIEWER
-    
+
     if wx.VERSION < (2, 6, 0):
         def Bind(self, event, function, id = None):
             if id is not None:
                 event(self, id, function)
             else:
                 event(self, function)
-    
+
     def _init_Editor(self, prnt):
-        self.Editor = CustomStyledTextCtrl(id=ID_TEXTVIEWERTEXTCTRL, 
+        self.Editor = CustomStyledTextCtrl(id=ID_TEXTVIEWERTEXTCTRL,
                 parent=prnt, name="TextViewer", size=wx.Size(0, 0), style=0)
         self.Editor.ParentWindow = self
-        
+
         self.Editor.CmdKeyAssign(ord('+'), wx.stc.STC_SCMOD_CTRL, wx.stc.STC_CMD_ZOOMIN)
         self.Editor.CmdKeyAssign(ord('-'), wx.stc.STC_SCMOD_CTRL, wx.stc.STC_CMD_ZOOMOUT)
-        
+
         self.Editor.SetViewWhiteSpace(False)
-        
+
         self.Editor.SetLexer(wx.stc.STC_LEX_CONTAINER)
-        
+
         # Global default styles for all languages
         self.Editor.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" % faces)
         self.Editor.StyleClearAll()  # Reset all to be like the default
-        
+
         self.Editor.StyleSetSpec(wx.stc.STC_STYLE_LINENUMBER,  "back:#C0C0C0,size:%(size)d" % faces)
         self.Editor.SetSelBackground(1, "#E0E0E0")
-        
+
         # Highlighting styles
         self.Editor.StyleSetSpec(STC_PLC_WORD, "fore:#00007F,bold,size:%(size)d" % faces)
         self.Editor.StyleSetSpec(STC_PLC_VARIABLE, "fore:#7F0000,size:%(size)d" % faces)
@@ -110,18 +110,18 @@
         self.Editor.StyleSetSpec(STC_PLC_JUMP, "fore:#FF7FFF,size:%(size)d" % faces)
         self.Editor.StyleSetSpec(STC_PLC_ERROR, "fore:#FF0000,back:#FFFF00,size:%(size)d" % faces)
         self.Editor.StyleSetSpec(STC_PLC_SEARCH_RESULT, "fore:#FFFFFF,back:#FFA500,size:%(size)d" % faces)
-        
+
         # Indicators styles
         self.Editor.IndicatorSetStyle(0, wx.stc.STC_INDIC_SQUIGGLE)
         if self.ParentWindow is not None and self.Controler is not None:
             self.Editor.IndicatorSetForeground(0, wx.RED)
         else:
             self.Editor.IndicatorSetForeground(0, wx.WHITE)
-        
+
         # Line numbers in the margin
         self.Editor.SetMarginType(1, wx.stc.STC_MARGIN_NUMBER)
         self.Editor.SetMarginWidth(1, 50)
-        
+
         # Folding
         self.Editor.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEROPEN,    wx.stc.STC_MARK_BOXMINUS,          "white", "#808080")
         self.Editor.MarkerDefine(wx.stc.STC_MARKNUM_FOLDER,        wx.stc.STC_MARK_BOXPLUS,           "white", "#808080")
@@ -130,11 +130,11 @@
         self.Editor.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEREND,     wx.stc.STC_MARK_BOXPLUSCONNECTED,  "white", "#808080")
         self.Editor.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEROPENMID, wx.stc.STC_MARK_BOXMINUSCONNECTED, "white", "#808080")
         self.Editor.MarkerDefine(wx.stc.STC_MARKNUM_FOLDERMIDTAIL, wx.stc.STC_MARK_TCORNER,           "white", "#808080")
-        
+
         # Indentation size
         self.Editor.SetTabWidth(2)
         self.Editor.SetUseTabs(0)
-        
+
         self.Editor.SetModEventMask(wx.stc.STC_MOD_BEFOREINSERT|
                                     wx.stc.STC_MOD_BEFOREDELETE|
                                     wx.stc.STC_PERFORMED_USER)
@@ -147,13 +147,13 @@
             self.Editor.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
             self.Bind(wx.stc.EVT_STC_DO_DROP, self.OnDoDrop, id=ID_TEXTVIEWERTEXTCTRL)
             self.Bind(wx.stc.EVT_STC_MODIFIED, self.OnModification, id=ID_TEXTVIEWERTEXTCTRL)
-        
+
     def __init__(self, parent, tagname, window, controler, debug = False, instancepath = ""):
         if tagname != "" and controler is not None:
             self.VARIABLE_PANEL_TYPE = controler.GetPouType(tagname.split("::")[1])
-        
+
         EditorPanel.__init__(self, parent, tagname, window, controler, debug)
-        
+
         self.Keywords = []
         self.Variables = {}
         self.Functions = {}
@@ -163,62 +163,62 @@
         self.DisableEvents = True
         self.TextSyntax = None
         self.CurrentAction = None
-        
+
         self.InstancePath = instancepath
         self.ContextStack = []
         self.CallStack = []
-        
+
         self.ResetSearchResults()
-        
+
         self.RefreshHighlightsTimer = wx.Timer(self, -1)
         self.Bind(wx.EVT_TIMER, self.OnRefreshHighlightsTimer, self.RefreshHighlightsTimer)
-        
+
     def __del__(self):
         self.RefreshHighlightsTimer.Stop()
-    
+
     def GetTitle(self):
         if self.Debug or self.TagName == "":
             if len(self.InstancePath) > 15:
                 return "..." + self.InstancePath[-12:]
             return self.InstancePath
         return EditorPanel.GetTitle(self)
-    
+
     def GetInstancePath(self):
         return self.InstancePath
-    
+
     def IsViewing(self, tagname):
         if self.Debug or self.TagName == "":
             return self.InstancePath == tagname
         else:
             return self.TagName == tagname
-    
+
     def GetText(self):
         return self.Editor.GetText()
-    
+
     def SetText(self, text):
         self.Editor.SetText(text)
-    
+
     def SelectAll(self):
         self.Editor.SelectAll()
-    
+
     def Colourise(self, start, end):
         self.Editor.Colourise(start, end)
-    
+
     def StartStyling(self, pos, mask):
         self.Editor.StartStyling(pos, mask)
-    
+
     def SetStyling(self, length, style):
         self.Editor.SetStyling(length, style)
-    
+
     def GetCurrentPos(self):
         return self.Editor.GetCurrentPos()
-    
+
     def ResetSearchResults(self):
         self.Highlights = []
         self.SearchParams = None
         self.SearchResults = None
         self.CurrentFindHighlight = None
-    
+
     def OnModification(self, event):
         if not self.DisableEvents:
             mod_type = event.GetModificationType()
@@ -239,7 +239,7 @@
                 self.CurrentAction = ("Delete", event.GetPosition())
                 wx.CallAfter(self.RefreshModel)
         event.Skip()
-    
+
     def OnDoDrop(self, event):
         try:
             values = eval(event.GetDragText())
@@ -256,7 +256,7 @@
                     blockinputs = values[3]
                 else:
                     blockinputs = None
-                if values[1] != "function": 
+                if values[1] != "function":
                     if blockname == "":
                         dialog = wx.TextEntryDialog(self.ParentWindow, "Block name", "Please enter a block name", "", wx.OK|wx.CANCEL|wx.CENTRE)
                         if dialog.ShowModal() == wx.ID_OK:
@@ -291,9 +291,9 @@
                     else:
                         location = values[0]
                         if not location.startswith("%"):
-                            dialog = wx.SingleChoiceDialog(self.ParentWindow, 
-                                  _("Select a variable class:"), _("Variable class"), 
-                                  ["Input", "Output", "Memory"], 
+                            dialog = wx.SingleChoiceDialog(self.ParentWindow,
+                                  _("Select a variable class:"), _("Variable class"),
+                                  ["Input", "Output", "Memory"],
                                   wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL)
                             if dialog.ShowModal() == wx.ID_OK:
                                 selected = dialog.GetSelection()
@@ -314,13 +314,30 @@
                         else:
                             var_type = LOCATIONDATATYPES.get(location[2], ["BOOL"])[0]
                         self.Controler.AddEditedElementPouVar(self.TagName,
-                            var_type, var_name, 
+                            var_type, var_name,
                             location=location, description=values[4])
                         self.RefreshVariablePanel()
                         self.RefreshVariableTree()
                         event.SetDragText(var_name)
                 else:
                     event.SetDragText("")
+            elif values[1] == "NamedConstant":
+                pou_name, pou_type = self.Controler.GetEditedElementType(self.TagName, self.Debug)
+                if pou_type == "program":
+                    initval = values[0]
+                    var_name = values[3]
+                    if var_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]:
+                        message = _("\"%s\" pou already exists!")%var_name
+                    else:
+                        var_type = values[2]
+                        if not var_name.upper() in [name.upper() for name in self.Controler.GetEditedElementVariables(self.TagName, self.Debug)]:
+                            self.Controler.AddEditedElementPouVar(self.TagName,
+                                                                  var_type,
+                                                                  var_name,
+                                                                  description=values[4], initval=initval)
+                            self.RefreshVariablePanel()
+                            self.RefreshVariableTree()
+                        event.SetDragText(var_name)
             elif values[1] == "Global":
                 var_name = values[0]
                 if var_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]:
@@ -345,7 +362,7 @@
                 dialog.Destroy()
                 event.SetDragText("")
         event.Skip()
-    
+
     def SetTextSyntax(self, syntax):
         self.TextSyntax = syntax
         if syntax in ["ST", "ALL"]:
@@ -362,16 +379,16 @@
         else:
             self.BlockStartKeywords = []
             self.BlockEndKeywords = []
-    
+
     def SetKeywords(self, keywords):
         self.Keywords = [keyword.upper() for keyword in keywords]
         self.Colourise(0, -1)
-    
+
     def RefreshJumpList(self):
         if self.TextSyntax != "IL":
             self.Jumps = [jump.upper() for jump in LABEL_MODEL.findall(self.GetText())]
             self.Colourise(0, -1)
-    
+
     # Buffer the last model state
     def RefreshBuffer(self):
         self.Controler.BufferProject()
@@ -379,42 +396,42 @@
             self.ParentWindow.RefreshTitle()
             self.ParentWindow.RefreshFileMenu()
             self.ParentWindow.RefreshEditMenu()
-    
+
     def StartBuffering(self):
         self.Controler.StartBuffering()
         if self.ParentWindow:
             self.ParentWindow.RefreshTitle()
             self.ParentWindow.RefreshFileMenu()
             self.ParentWindow.RefreshEditMenu()
-    
+
     def ResetBuffer(self):
         if self.CurrentAction != None:
             self.Controler.EndBuffering()
             self.CurrentAction = None
-    
+
     def GetBufferState(self):
         if not self.Debug and self.TextSyntax != "ALL":
             return self.Controler.GetBufferState()
         return False, False
-    
+
     def Undo(self):
         if not self.Debug and self.TextSyntax != "ALL":
             self.Controler.LoadPrevious()
             self.ParentWindow.CloseTabsWithoutModel()
-            
+
     def Redo(self):
         if not self.Debug and self.TextSyntax != "ALL":
             self.Controler.LoadNext()
             self.ParentWindow.CloseTabsWithoutModel()
-        
+
     def HasNoModel(self):
         if not self.Debug and self.TextSyntax != "ALL":
             return self.Controler.GetEditedElement(self.TagName) is None
         return False
-    
+
     def RefreshView(self, variablepanel=True):
         EditorPanel.RefreshView(self, variablepanel)
-        
+
         if self.Controler is not None:
             self.ResetBuffer()
             self.DisableEvents = True
@@ -434,12 +451,12 @@
                 self.RefreshJumpList()
                 self.Editor.EmptyUndoBuffer()
             self.DisableEvents = False
-            
+
             self.RefreshVariableTree()
-            
+
             self.TypeNames = [typename.upper() for typename in self.Controler.GetDataTypes(self.TagName, True, self.Debug)]
             self.EnumeratedValues = [value.upper() for value in self.Controler.GetEnumeratedDataValues()]
-            
+
             self.Functions = {}
             for category in self.Controler.GetBlockTypes(self.TagName, self.Debug):
                 for blocktype in category["list"]:
@@ -455,13 +472,13 @@
                         else:
                             self.Functions[blockname] = {"interface": interface,
                                                          "extensible": blocktype["extensible"]}
-        
+
         self.Colourise(0, -1)
-            
+
     def RefreshVariableTree(self):
         words = self.TagName.split("::")
         self.Variables = self.GenerateVariableTree(
-            [(variable.Name, variable.Type, variable.Tree) 
+            [(variable.Name, variable.Type, variable.Tree)
              for variable in self.Controler.GetEditedElementInterfaceVars(
                 self.TagName, True, self.Debug)])
         if self.Controler.GetEditedElementType(self.TagName, self.Debug)[1] == "function" or words[0] == "T" and self.TextSyntax == "IL":
@@ -470,22 +487,22 @@
                 self.Variables[words[-1].upper()] = self.GenerateVariableTree(var_tree)
             else:
                 self.Variables[words[-1].upper()] = {}
-    
+
     def GenerateVariableTree(self, list):
         tree = {}
         for var_name, var_type, (var_tree, var_dimension) in list:
             tree[var_name.upper()] = self.GenerateVariableTree(var_tree)
         return tree
-    
+
     def IsValidVariable(self, name, context):
         return context is not None and context.get(name, None) is not None
 
     def IsCallParameter(self, name, call):
         if call is not None:
-            return (call["interface"].get(name.upper(), None) is not None or 
+            return (call["interface"].get(name.upper(), None) is not None or
                     call["extensible"] and EXTENSIBLE_PARAMETER.match(name.upper()) is not None)
         return False
-    
+
     def RefreshLineFolding(self, line_number):
         if self.TextSyntax in ["ST", "ALL"]:
             level = wx.stc.STC_FOLDLEVELBASE + self.Editor.GetLineIndentation(line_number)
@@ -497,7 +514,7 @@
                     else:
                         level = self.Editor.GetFoldLevel(line_number - 1) & wx.stc.STC_FOLDLEVELNUMBERMASK
                 if level != wx.stc.STC_FOLDLEVELBASE:
-                    level |=  wx.stc.STC_FOLDLEVELWHITEFLAG 
+                    level |=  wx.stc.STC_FOLDLEVELWHITEFLAG
             elif LineStartswith(line, self.BlockStartKeywords):
                 level |= wx.stc.STC_FOLDLEVELHEADERFLAG
             elif LineStartswith(line, self.BlockEndKeywords):
@@ -506,7 +523,7 @@
                 else:
                     level = self.Editor.GetFoldLevel(line_number - 1) & wx.stc.STC_FOLDLEVELNUMBERMASK
             self.Editor.SetFoldLevel(line_number, level)
-    
+
     def OnStyleNeeded(self, event):
         self.TextChanged = True
         line_number = self.Editor.LineFromPosition(self.Editor.GetEndStyled())
@@ -517,10 +534,10 @@
         self.RefreshLineFolding(line_number)
         end_pos = event.GetPosition()
         self.StartStyling(start_pos, 0xff)
-        
+
         current_context = self.Variables
         current_call = None
-        
+
         current_pos = last_styled_pos
         state = SPACE
         line = ""
@@ -642,7 +659,7 @@
                     elif self.IsCallParameter(word, current_call):
                         self.SetStyling(current_pos - last_styled_pos, STC_PLC_PARAMETER)
                     elif word in self.Functions:
-                        self.SetStyling(current_pos - last_styled_pos, STC_PLC_FUNCTION)    
+                        self.SetStyling(current_pos - last_styled_pos, STC_PLC_FUNCTION)
                     elif self.TextSyntax == "IL" and word in self.Jumps:
                         self.SetStyling(current_pos - last_styled_pos, STC_PLC_JUMP)
                     elif word in self.EnumeratedValues:
@@ -670,7 +687,7 @@
                         if char == '[' and current_context is not None:
                             self.ContextStack.append(current_context.get(word, None))
                         current_context = self.Variables
-                    
+
                     word = ""
                     last_styled_pos = current_pos
                     state = SPACE
@@ -717,20 +734,20 @@
             self.SetStyling(current_pos - start_pos, 31)
         self.ShowHighlights(start_pos, end_pos)
         event.Skip()
-    
+
     def OnMarginClick(self, event):
         if event.GetMargin() == 2:
             line = self.Editor.LineFromPosition(event.GetPosition())
             if self.Editor.GetFoldLevel(line) & wx.stc.STC_FOLDLEVELHEADERFLAG:
                 self.Editor.ToggleFold(line)
         event.Skip()
-    
+
     def OnUpdateUI(self, event):
         selected = self.Editor.GetSelectedText()
         if self.ParentWindow and selected != "":
             self.ParentWindow.SetCopyBuffer(selected, True)
         event.Skip()
-    
+
     def Cut(self):
         self.ResetBuffer()
         self.DisableEvents = True
@@ -738,12 +755,12 @@
         self.DisableEvents = False
         self.RefreshModel()
         self.RefreshBuffer()
-    
+
     def Copy(self):
         self.Editor.CmdKeyExecute(wx.stc.STC_CMD_COPY)
         if self.ParentWindow:
             self.ParentWindow.RefreshEditMenu()
-    
+
     def Paste(self):
         self.ResetBuffer()
         self.DisableEvents = True
@@ -751,28 +768,28 @@
         self.DisableEvents = False
         self.RefreshModel()
         self.RefreshBuffer()
-    
+
     def Search(self, criteria):
         return self.Controler.SearchInPou(self.TagName, criteria, self.Debug)
-    
+
     def Find(self, direction, search_params):
         if self.SearchParams != search_params:
             self.ClearHighlights(SEARCH_RESULT_HIGHLIGHT)
-            
+
             self.SearchParams = search_params
             criteria = {
-                "raw_pattern": search_params["find_pattern"], 
+                "raw_pattern": search_params["find_pattern"],
                 "pattern": re.compile(search_params["find_pattern"]),
                 "case_sensitive": search_params["case_sensitive"],
                 "regular_expression": search_params["regular_expression"],
                 "filter": "all"}
-            
+
             self.SearchResults = [
                 (infos[1:], start, end, SEARCH_RESULT_HIGHLIGHT)
-                for infos, start, end, text in 
+                for infos, start, end, text in
                 self.Search(criteria)]
             self.CurrentFindHighlight = None
-        
+
         if len(self.SearchResults) > 0:
             if self.CurrentFindHighlight is not None:
                 old_idx = self.SearchResults.index(self.CurrentFindHighlight)
@@ -787,24 +804,24 @@
             else:
                 self.CurrentFindHighlight = self.SearchResults[0]
                 self.AddHighlight(*self.CurrentFindHighlight)
-            
+
         else:
             if self.CurrentFindHighlight is not None:
                 self.RemoveHighlight(*self.CurrentFindHighlight)
             self.CurrentFindHighlight = None
-    
+
     def RefreshModel(self):
         self.RefreshJumpList()
         self.Controler.SetEditedElementText(self.TagName, self.GetText())
         self.ResetSearchResults()
-    
+
     def OnKeyDown(self, event):
         key = event.GetKeyCode()
         if self.Controler is not None:
-        
+
             if self.Editor.CallTipActive():
                 self.Editor.CallTipCancel()
-            
+
             key_handled = False
 
             line = self.Editor.GetCurrentLine()
@@ -814,15 +831,15 @@
                 start_pos = self.Editor.GetLineEndPosition(line - 1) + 1
             end_pos = self.GetCurrentPos()
             lineText = self.Editor.GetTextRange(start_pos, end_pos).replace("\t", " ")
-            
+
             # Code completion
             if key == wx.WXK_SPACE and event.ControlDown():
-                
+
                 words = lineText.split(" ")
                 words = [word for i, word in enumerate(words) if word != '' or i == len(words) - 1]
-                            
+
                 kw = []
-                
+
                 if self.TextSyntax == "IL":
                     if len(words) == 1:
                         kw = self.Keywords
@@ -875,7 +892,7 @@
 
     def ClearHighlights(self, highlight_type=None):
         EditorPanel.ClearHighlights(self, highlight_type)
-        
+
         if highlight_type is None:
             self.Highlights = []
         else:
@@ -886,7 +903,7 @@
 
     def AddHighlight(self, infos, start, end, highlight_type):
         EditorPanel.AddHighlight(self, infos, start, end, highlight_type)
-        
+
         highlight_type = HIGHLIGHT_TYPES.get(highlight_type, None)
         if infos[0] == "body" and highlight_type is not None:
             self.Highlights.append((infos[1], start, end, highlight_type))
@@ -895,13 +912,13 @@
 
     def RemoveHighlight(self, infos, start, end, highlight_type):
         EditorPanel.RemoveHighlight(self, infos, start, end, highlight_type)
-        
+
         highlight_type = HIGHLIGHT_TYPES.get(highlight_type, None)
-        if (infos[0] == "body" and highlight_type is not None and 
+        if (infos[0] == "body" and highlight_type is not None and
             (infos[1], start, end, highlight_type) in self.Highlights):
             self.Highlights.remove((infos[1], start, end, highlight_type))
             self.RefreshHighlightsTimer.Start(int(REFRESH_HIGHLIGHT_PERIOD * 1000), oneShot=True)
-    
+
     def ShowHighlights(self, start_pos, end_pos):
         for indent, start, end, highlight_type in self.Highlights:
             if start[0] == 0:
@@ -917,4 +934,4 @@
                 self.SetStyling(highlight_end_pos - highlight_start_pos, highlight_type)
                 self.StartStyling(highlight_start_pos, 0x00)
                 self.SetStyling(len(self.Editor.GetText()) - highlight_end_pos, wx.stc.STC_STYLE_DEFAULT)
-                
+
--- a/plcopen/definitions.py	Mon May 26 14:44:03 2014 +0100
+++ b/plcopen/definitions.py	Fri Jun 06 18:30:49 2014 +0100
@@ -12,7 +12,7 @@
                      "B" : ["SINT", "USINT", "BYTE", "STRING"],
                      "W" : ["INT", "UINT", "WORD", "WSTRING"],
                      "D" : ["DINT", "UDINT", "REAL", "DWORD"],
-                     "L" : ["LINT", "ULINT", "LREAL", "LWORD"]} 
+                     "L" : ["LINT", "ULINT", "LREAL", "LWORD"]}
 
 #-------------------------------------------------------------------------------
 #                        Function Block Types definitions
@@ -105,6 +105,8 @@
     #("WSTRING", "ANY_STRING") # TODO
 ]
 
+DefaultType = "DINT"
+
 DataTypeRange_list = [
     ("SINT", (-2**7, 2**7 - 1)),
     ("INT", (-2**15, 2**15 - 1)),
--- a/py_ext/plc_python.c	Mon May 26 14:44:03 2014 +0100
+++ b/py_ext/plc_python.c	Fri Jun 06 18:30:49 2014 +0100
@@ -119,7 +119,7 @@
 			/*printf("__PythonEvalFB pop %%d - %%*s\n",Current_PLC_EvalFB, data__->BUFFER.len, data__->BUFFER.body);*/
 		}else if(poll){
 			/* when in polling, no answer == ack down */
-		    __SET_VAR(data__->, ACK., 0);
+		    __SET_VAR(data__->, ACK,, 0);
 		}
 		/* got the order to act ?*/
 		if(__GET_VAR(data__->TRIGGED) == 1 &&
--- a/util/ProcessLogger.py	Mon May 26 14:44:03 2014 +0100
+++ b/util/ProcessLogger.py	Fri Jun 06 18:30:49 2014 +0100
@@ -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
 #
@@ -31,7 +31,7 @@
 if os.name == 'posix':
     from signal import SIGTERM, SIGKILL
 
-    
+
 class outputThread(Thread):
     """
     Thread is used to print the output of a command to the stdout
@@ -66,10 +66,10 @@
                 err = self.retval
             self.finished = True
             self.endcallback(self.Proc.pid, err)
-        
+
 class ProcessLogger:
-    def __init__(self, logger, Command, finish_callback = None, 
-                 no_stdout = False, no_stderr = False, no_gui = True, 
+    def __init__(self, logger, Command, finish_callback = None,
+                 no_stdout = False, no_stderr = False, no_gui = True,
                  timeout = None, outlimit = None, errlimit = None,
                  endlog = None, keyword = None, kill_it = False, cwd = None):
         self.logger = logger
@@ -86,10 +86,10 @@
         else:
             self.Command = Command
             self.Command_str = subprocess.list2cmdline(self.Command)
-        
+
         self.Command = map(lambda x: x.encode(sys.getfilesystemencoding()),
                            self.Command)
-        
+
         self.finish_callback = finish_callback
         self.no_stdout = no_stdout
         self.no_stderr = no_stderr
@@ -105,27 +105,27 @@
         self.kill_it = kill_it
         self.finishsem = Semaphore(0)
         self.endlock = Lock()
-        
+
         popenargs= {
                "cwd":os.getcwd() if cwd is None else cwd,
-               "stdin":subprocess.PIPE, 
-               "stdout":subprocess.PIPE, 
+               "stdin":subprocess.PIPE,
+               "stdout":subprocess.PIPE,
                "stderr":subprocess.PIPE}
-        
+
         if no_gui == True and wx.Platform == '__WXMSW__':
             self.startupinfo = subprocess.STARTUPINFO()
             self.startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
             popenargs["startupinfo"] = self.startupinfo
         elif wx.Platform == '__WXGTK__':
             popenargs["shell"] = False
-        
+
         self.Proc = subprocess.Popen( self.Command, **popenargs )
 
         self.outt = outputThread(
                       self.Proc,
                       self.Proc.stdout,
                       self.output,
-                      self.finish) 
+                      self.finish)
         self.outt.start()
 
         self.errt = outputThread(
@@ -147,7 +147,7 @@
             self.logger.write(v)
         if (self.keyword and v.find(self.keyword)!=-1) or (self.outlimit and self.outlen > self.outlimit):
             self.endlog()
-            
+
     def errors(self,v):
         self.errdata.append(v)
         self.errlen += 1
@@ -195,7 +195,7 @@
             if not self.outt.finished and self.kill_it:
                self.kill()
 
-        
+
     def spin(self):
         self.finishsem.acquire()
         return [self.exitcode, "".join(self.outdata), "".join(self.errdata)]