andrej@1663: #!/usr/bin/env python andrej@1663: # -*- coding: utf-8 -*- andrej@1663: andrej@1663: # This file is part of Beremiz, a Integrated Development Environment for andrej@1663: # programming IEC 61131-3 automates supporting plcopen standard and CanFestival. andrej@1663: # andrej@1663: # Copyright (C) 2016 - 2017: Andrey Skvortsov andrej@1663: # andrej@1663: # See COPYING file for copyrights details. andrej@1663: # andrej@1663: # This program is free software; you can redistribute it and/or andrej@1663: # modify it under the terms of the GNU General Public License andrej@1663: # as published by the Free Software Foundation; either version 2 andrej@1663: # of the License, or (at your option) any later version. andrej@1663: # andrej@1663: # This program is distributed in the hope that it will be useful, andrej@1663: # but WITHOUT ANY WARRANTY; without even the implied warranty of andrej@1663: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the andrej@1663: # GNU General Public License for more details. andrej@1663: # andrej@1663: # You should have received a copy of the GNU General Public License andrej@1663: # along with this program; if not, write to the Free Software andrej@1663: # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. andrej@1663: andrej@1663: andrej@1732: import os andrej@1732: import sys andrej@1732: import getopt andrej@1872: andrej@1872: import wx edouard@1941: from wx.lib.agw.advancedsplash import AdvancedSplash, AS_NOTIMEOUT, AS_CENTER_ON_SCREEN andrej@1872: andrej@1680: import util.paths as paths andrej@1663: Edouard@1953: andrej@1831: class BeremizIDELauncher(object): andrej@1663: def __init__(self): andrej@1796: self.app = None andrej@1796: self.frame = None andrej@1663: self.updateinfo_url = None andrej@1663: self.extensions = [] andrej@1680: self.app_dir = paths.AbsDir(__file__) andrej@1663: self.projectOpen = None andrej@1663: self.buildpath = None andrej@1663: self.splash = None andrej@1663: self.splashPath = self.Bpath("images", "splash.png") Edouard@1935: self.modules = ["BeremizIDE"] Edouard@1926: self.debug = os.path.exists("BEREMIZ_DEBUG") edouard@1960: self.handle_exception = None edouard@3423: self.logf = None andrej@1663: andrej@1663: def Bpath(self, *args): andrej@1740: return os.path.join(self.app_dir, *args) andrej@1663: andrej@1663: def Usage(self): andrej@1826: print("Usage:") andrej@1826: print("%s [Options] [Projectpath] [Buildpath]" % sys.argv[0]) andrej@1826: print("") andrej@1826: print("Supported options:") andrej@1826: print("-h --help Print this help") andrej@1826: print("-u --updatecheck URL Retrieve update information by checking URL") andrej@1826: print("-e --extend PathToExtension Extend IDE functionality by loading at start additional extensions") edouard@3423: print("-l --log path write content of console tab to given file") andrej@1826: print("") andrej@1826: print("") andrej@1663: andrej@1663: def SetCmdOptions(self): edouard@3423: self.shortCmdOpts = "hu:e:l:" edouard@3423: self.longCmdOpts = ["help", "updatecheck=", "extend=", "log="] andrej@1663: andrej@1663: def ProcessOption(self, o, a): andrej@1663: if o in ("-h", "--help"): andrej@1663: self.Usage() andrej@1663: sys.exit() andrej@1663: if o in ("-u", "--updatecheck"): andrej@1663: self.updateinfo_url = a andrej@1663: if o in ("-e", "--extend"): andrej@1663: self.extensions.append(a) edouard@3423: if o in ("-l", "--log"): edouard@3423: self.logf = open(a, 'a') andrej@1663: andrej@1663: def ProcessCommandLineArgs(self): andrej@1663: self.SetCmdOptions() andrej@1663: try: andrej@1663: opts, args = getopt.getopt(sys.argv[1:], self.shortCmdOpts, self.longCmdOpts) andrej@1663: except getopt.GetoptError: andrej@1663: # print help information and exit: andrej@1663: self.Usage() andrej@1663: sys.exit(2) andrej@1663: andrej@1663: for o, a in opts: andrej@1663: self.ProcessOption(o, a) andrej@1663: andrej@1663: if len(args) > 2: andrej@1663: self.Usage() andrej@1663: sys.exit() andrej@1663: andrej@1663: elif len(args) == 1: andrej@1663: self.projectOpen = args[0] andrej@1663: self.buildpath = None andrej@1663: elif len(args) == 2: andrej@1663: self.projectOpen = args[0] andrej@1663: self.buildpath = args[1] andrej@1663: andrej@1663: def CreateApplication(self): edouard@1941: edouard@3793: BeremizAppType = wx.App Edouard@1953: edouard@1941: class BeremizApp(BeremizAppType): Edouard@1953: def OnInit(_self): # pylint: disable=no-self-argument edouard@1941: self.ShowSplashScreen() edouard@1941: return True edouard@1941: edouard@1941: self.app = BeremizApp(redirect=self.debug) andrej@1663: self.app.SetAppName('beremiz') andrej@1663: Edouard@1947: def ShowSplashScreen(self): Edouard@1947: class Splash(AdvancedSplash): edouard@1976: Painted = False edouard@1977: Edouard@1953: def OnPaint(_self, event): # pylint: disable=no-self-argument Edouard@1947: AdvancedSplash.OnPaint(_self, event) edouard@1976: if not _self.Painted: # trigger app start only once edouard@1976: _self.Painted = True edouard@1976: wx.CallAfter(self.AppStart) Edouard@1947: bmp = wx.Image(self.splashPath).ConvertToBitmap() Edouard@1953: self.splash = Splash(None, Edouard@1953: bitmap=bmp, Edouard@1947: agwStyle=AS_NOTIMEOUT | AS_CENTER_ON_SCREEN) Edouard@1947: andrej@1663: def BackgroundInitialization(self): andrej@1663: self.InitI18n() andrej@1663: self.CheckUpdates() andrej@1663: self.LoadExtensions() andrej@1663: self.ImportModules() andrej@1663: andrej@1663: def InitI18n(self): andrej@1663: from util.misc import InstallLocalRessources andrej@1663: InstallLocalRessources(self.app_dir) andrej@1663: Edouard@1921: def globals(self): Edouard@1921: """ Edouard@1921: allows customizations to specify what globals Edouard@1921: are passed to extensions Edouard@1921: """ Edouard@1921: return globals() Edouard@1921: andrej@1663: def LoadExtensions(self): andrej@1663: for extfilename in self.extensions: andrej@1663: from util.TranslationCatalogs import AddCatalog andrej@1663: from util.BitmapLibrary import AddBitmapFolder andrej@1663: extension_folder = os.path.split(os.path.realpath(extfilename))[0] andrej@1663: sys.path.append(extension_folder) andrej@1663: AddCatalog(os.path.join(extension_folder, "locale")) andrej@1663: AddBitmapFolder(os.path.join(extension_folder, "images")) kinsamanka@3750: exec(compile(open(extfilename, "rb").read(), extfilename, 'exec'), self.globals()) andrej@1663: andrej@1663: def CheckUpdates(self): andrej@1663: if self.updateinfo_url is not None: andrej@1874: self.updateinfo = _("Fetching %s") % self.updateinfo_url andrej@1663: andrej@1663: def updateinfoproc(): andrej@1739: try: kinsamanka@3750: import urllib.request, urllib.error, urllib.parse kinsamanka@3750: self.updateinfo = urllib.request.urlopen(self.updateinfo_url, None).read() andrej@1780: except Exception: andrej@1874: self.updateinfo = _("update info unavailable.") andrej@1663: andrej@1663: from threading import Thread andrej@1874: self.splash.SetText(text=self.updateinfo) andrej@1663: updateinfoThread = Thread(target=updateinfoproc) andrej@1663: updateinfoThread.start() andrej@1663: updateinfoThread.join(2) andrej@1874: self.splash.SetText(text=self.updateinfo) andrej@1663: andrej@1663: def ImportModules(self): Edouard@1924: for modname in self.modules: Edouard@1924: mod = __import__(modname) Edouard@1924: setattr(self, modname, mod) andrej@1663: andrej@1663: def InstallExceptionHandler(self): andrej@1663: import version andrej@1792: import util.ExceptionHandler edouard@3444: self.handle_exception = util.ExceptionHandler.AddExceptHook(version.app_version, logf=self.logf) andrej@1663: Edouard@1924: def CreateUI(self): edouard@3423: self.frame = self.BeremizIDE.Beremiz(None, self.projectOpen, self.buildpath, logf=self.logf) Edouard@1924: Edouard@1924: def CloseSplash(self): andrej@1663: if self.splash: andrej@1663: self.splash.Close() Edouard@1924: Edouard@1924: def ShowUI(self): andrej@1663: self.frame.Show() andrej@1663: andrej@1796: def PreStart(self): andrej@1663: self.ProcessCommandLineArgs() andrej@1663: self.CreateApplication() Edouard@1953: edouard@1941: def AppStart(self): edouard@1941: try: edouard@1941: self.BackgroundInitialization() edouard@1941: self.CreateUI() edouard@1941: self.CloseSplash() edouard@1941: self.ShowUI() edouard@1960: except (KeyboardInterrupt, SystemExit): edouard@1960: raise edouard@1941: except Exception: edouard@1960: if self.handle_exception is not None: edouard@1960: self.handle_exception(*sys.exc_info(), exit=True) edouard@1960: else: edouard@1960: raise andrej@1663: andrej@1796: def MainLoop(self): andrej@1796: self.app.MainLoop() andrej@1796: Edouard@1924: def Start(self): andrej@1796: self.PreStart() edouard@1941: self.InstallExceptionHandler() andrej@1796: self.MainLoop() andrej@1796: andrej@1749: andrej@1663: if __name__ == '__main__': andrej@1663: beremiz = BeremizIDELauncher() andrej@1663: beremiz.Start()