diff -r a375e31bf312 -r c1298e7ffe3a Beremiz.py --- a/Beremiz.py Sun Mar 05 00:38:25 2017 +0000 +++ b/Beremiz.py Fri Mar 24 12:07:47 2017 +0000 @@ -1,27 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of Beremiz, a Integrated Development Environment for -#programming IEC 61131-3 automates supporting plcopen standard and CanFestival. +# This file is part of Beremiz, a Integrated Development Environment for +# programming IEC 61131-3 automates supporting plcopen standard and CanFestival. # -#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# See COPYING file for copyrights details. # -#This library is free software; you can redistribute it and/or -#modify it under the terms of the GNU General Public -#License as published by the Free Software Foundation; either -#version 2.1 of the License, or (at your option) any later version. +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. # -#This library is distributed in the hope that it will be useful, -#but WITHOUT ANY WARRANTY; without even the implied warranty of -#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -#General Public License for more details. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. # -#You should have received a copy of the GNU General Public -#License along with this library; if not, write to the Free Software -#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. updateinfo_url = None @@ -31,18 +30,33 @@ import shutil import random import time +import version from types import ListType beremiz_dir = os.path.dirname(os.path.realpath(__file__)) -import wxversion -wxversion.select('2.8') -import wx +if __name__ == '__main__': + import wxversion + wxversion.select(['2.8', '3.0']) + import wx + from wx.lib.agw.advancedsplash import AdvancedSplash def Bpath(*args): return os.path.join(beremiz_dir,*args) +def ShowSplashScreen(): + bmp = wx.Image(Bpath("images", "splash.png")).ConvertToBitmap() + #splash=AdvancedSplash(None, bitmap=bmp, style=wx.SPLASH_CENTRE_ON_SCREEN, timeout=4000) + splash = AdvancedSplash(None, bitmap=bmp) + + # process all events + # even the events generated by splash themself during showing + for i in range(0,30): + wx.Yield() + time.sleep(0.01); + return splash + if __name__ == '__main__': def usage(): print "\nUsage of Beremiz.py :" @@ -84,18 +98,24 @@ else : __builtin__.__dict__["BMZ_DBG"] = False - app = wx.PySimpleApp(redirect=BMZ_DBG) + if wx.VERSION >= (3, 0, 0): + app = wx.App(redirect=BMZ_DBG) + else: + app = wx.PySimpleApp(redirect=BMZ_DBG) + app.SetAppName('beremiz') - wx.InitAllImageHandlers() + if wx.VERSION < (3, 0, 0): + 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) - splash=AdvancedSplash(None, bitmap=bmp) - wx.Yield() - + splash = ShowSplashScreen() + + # load internatialization files + from util.misc import InstallLocalRessources + InstallLocalRessources(beremiz_dir) + if updateinfo_url is not None: - updateinfo = "Fetching %s" % updateinfo_url + updateinfo = _("Fetching %s") % updateinfo_url # warn for possible updates def updateinfoproc(): global updateinfo @@ -103,7 +123,7 @@ 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) @@ -114,9 +134,6 @@ splash.SetText(text=updateinfo) wx.Yield() - from util.misc import InstallLocalRessources - InstallLocalRessources(beremiz_dir) - # Load extensions for extfilename in extensions: from util.TranslationCatalogs import AddCatalog @@ -142,6 +159,8 @@ from util.ProcessLogger import ProcessLogger from controls.LogViewer import LogViewer from controls.CustomStyledTextCtrl import CustomStyledTextCtrl +from controls import EnhancedStatusBar as esb +from dialogs.AboutDialog import ShowAboutDialog from PLCControler import LOCATION_CONFNODE, LOCATION_MODULE, LOCATION_GROUP, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY, ITEM_PROJECT, ITEM_RESOURCE from ProjectController import ProjectController, GetAddMenuItems, MATIEC_ERROR_MODEL, ITEM_CONFNODE @@ -231,12 +250,14 @@ # adding text. It seems that text modifications, even # programmatically, are disabled in StyledTextCtrl when read # only is active + start_pos = self.output.GetLength() self.output.SetReadOnly(False) self.output.AppendText(s) self.output.SetReadOnly(True) + text_len = self.output.GetLength() - start_pos if style != self.black_white: - self.output.SetStyling(len(s), style) + self.output.SetStyling(text_len, style) self.stack = [] self.lock.release() self.output.Thaw() @@ -377,6 +398,11 @@ inspectorID = wx.NewId() self.Bind(wx.EVT_MENU, self.OnOpenWidgetInspector, id=inspectorID) accels = [wx.AcceleratorEntry(wx.ACCEL_CTRL|wx.ACCEL_ALT, ord('I'), inspectorID)] + + keyID = wx.NewId() + self.Bind(wx.EVT_MENU, self.SwitchFullScrMode, id=keyID) + accels += [wx.AcceleratorEntry(wx.ACCEL_NORMAL, wx.WXK_F12, keyID)] + for method,shortcut in [("Stop", wx.WXK_F4), ("Run", wx.WXK_F5), ("Transfer", wx.WXK_F6), @@ -440,11 +466,28 @@ self.AUIManager.Update() - self.ConnectionStatusBar = wx.StatusBar(self, style=wx.ST_SIZEGRIP) + self.ConnectionStatusBar = esb.EnhancedStatusBar(self, style=wx.ST_SIZEGRIP) self._init_coll_ConnectionStatusBar_Fields(self.ConnectionStatusBar) + self.ProgressStatusBar = wx.Gauge(self.ConnectionStatusBar, -1, range = 100) + self.ConnectionStatusBar.AddWidget(self.ProgressStatusBar, esb.ESB_EXACT_FIT, esb.ESB_EXACT_FIT, 2) + self.ProgressStatusBar.Hide() self.SetStatusBar(self.ConnectionStatusBar) + def __init_execute_path(self): + if os.name == 'nt': + # on windows, desktop shortcut launches Beremiz.py + # with working dir set to mingw/bin. + # then we prefix CWD to PATH in order to ensure that + # commands invoked by build process by default are + # found here. + os.environ["PATH"] = os.getcwd()+';'+os.environ["PATH"] + + def __init__(self, parent, projectOpen=None, buildpath=None, ctr=None, debug=True): + # Add beremiz's icon in top left corner of the frame + self.icon = wx.Icon(Bpath("images", "brz.ico"), wx.BITMAP_TYPE_ICO) + self.__init_execute_path() + IDEFrame.__init__(self, parent, debug) self.Log = LogPseudoFile(self.LogConsole,self.SelectTab) @@ -473,16 +516,13 @@ ("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 - result = self.CTR.LoadProject(projectOpen, buildpath) + result, err = self.CTR.LoadProject(projectOpen, buildpath) if not result: self.LibraryPanel.SetController(self.Controler) self.ProjectTree.Enable(True) @@ -534,7 +574,7 @@ {False : "-x 0", True :"-x 1"}[taskbaricon], self.local_runtime_tmpdir), no_gui=False, - timeout=500, keyword = "working", + timeout=500, keyword = self.local_runtime_tmpdir, cwd = self.local_runtime_tmpdir) self.local_runtime.spin() return self.runtime_port @@ -717,6 +757,11 @@ self.GetConfigEntry("RecentProjects", [])) except: recent_projects = [] + + while self.RecentProjectsMenu.GetMenuItemCount() > len(recent_projects): + item = self.RecentProjectsMenu.FindItemByPosition(0) + self.RecentProjectsMenu.RemoveItem(item) + self.FileMenu.Enable(ID_FILEMENURECENTPROJECTS, len(recent_projects) > 0) for idx, projectpath in enumerate(recent_projects): text = u'%d: %s' % (idx + 1, projectpath) @@ -856,7 +901,7 @@ self.DebugVariablePanel.SetDataProducer(None) self.ResetConnectionStatusBar() - def RefreshConfigRecentProjects(self, projectpath): + def RefreshConfigRecentProjects(self, projectpath, err=False): try: recent_projects = map(DecodeFileSystemPath, self.GetConfigEntry("RecentProjects", [])) @@ -864,7 +909,8 @@ recent_projects = [] if projectpath in recent_projects: recent_projects.remove(projectpath) - recent_projects.insert(0, projectpath) + if not err: + recent_projects.insert(0, projectpath) self.Config.Write("RecentProjects", cPickle.dumps( map(EncodeFileSystemPath, recent_projects[:MAX_RECENT_PROJECTS]))) self.Config.Flush() @@ -931,12 +977,11 @@ self.ResetView() self.CTR = ProjectController(self, self.Log) self.Controler = self.CTR - result = self.CTR.LoadProject(projectpath) + result, err = self.CTR.LoadProject(projectpath) if not result: self.LibraryPanel.SetController(self.Controler) self.ProjectTree.Enable(True) self.PouInstanceVariablesPanel.SetController(self.Controler) - self.RefreshConfigRecentProjects(projectpath) if self.EnableDebug: self.DebugVariablePanel.SetDataProducer(self.CTR) self._Refresh(PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE) @@ -944,8 +989,11 @@ self.ResetView() self.ShowErrorMessage(result) self.RefreshAll() + self.SearchResultPanel.ResetSearchResults() else: self.ShowErrorMessage(_("\"%s\" folder is not a valid Beremiz project\n") % projectpath) + err = True + self.RefreshConfigRecentProjects(projectpath, err) self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU) def OnCloseProjectMenu(self, event): @@ -974,13 +1022,15 @@ if self.CTR is not None: self.CTR.SaveProjectAs() self.RefreshAll() + self.RefreshConfigRecentProjects(self.CTR.ProjectPath) 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)) + info = version.GetAboutDialogInfo() + ShowAboutDialog(self, info) def OnProjectTreeItemBeginEdit(self, event): selected = event.GetItem() @@ -1145,7 +1195,7 @@ Please be kind enough to send this file to: beremiz-devel@lists.sourceforge.net -You should now restart Beremiz. +You should now restart program. Traceback: """) % bug_report_path + @@ -1231,7 +1281,7 @@ if __name__ == '__main__': # Install a exception handle for bug reports - AddExceptHook(os.getcwd(),updateinfo_url) + AddExceptHook(os.getcwd(),version.app_version) frame = Beremiz(None, projectOpen, buildpath) if splash: