beremiz

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