Sun, 09 Dec 2018 16:39:35 +0100
WebBrowser: added single application mode.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebBrowser/WebBrowserSingleApplication.py Sun Dec 09 16:39:35 2018 +0100 @@ -0,0 +1,134 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2018 Detlev Offenbach <detlev@die-offenbachs.de> +# + + +""" +Module implementing the single application server and client for the web +browser. +""" + +from __future__ import unicode_literals + +from PyQt5.QtCore import pyqtSignal + +from Toolbox.SingleApplication import SingleApplicationClient, \ + SingleApplicationServer + +import Globals + +########################################################################### +## define some module global stuff +########################################################################### + +SAFile = "eric6_browser" + +# define the protocol tokens +SALoadUrl = 'LoadUrl' +SASearch = 'Search' + + +class WebBrowserSingleApplicationServer(SingleApplicationServer): + """ + Class implementing the single application server embedded within the + Web Browser. + + @signal loadUrl(str) emitted to load a URL + @signal search(str) emitted to search for a given word + """ + loadUrl = pyqtSignal(str) + search = pyqtSignal(str) + + def __init__(self): + """ + Constructor + """ + SingleApplicationServer.__init__(self, SAFile) + + def handleCommand(self, command, arguments): + """ + Public slot to handle the command sent by the client. + + @param command command sent by the client + @type str + @param arguments list of command arguments + @type list of str + """ + if command == SALoadUrl: + self.__saLoadUrl(arguments[0]) + + elif command == SASearch: + self.__saSearch(arguments[0]) + + def __saLoadUrl(self, url): + """ + Private method to load an URL. + + @param url URL to be loaded + @type str + """ + self.loadUrl.emit(url) + + def __saSearch(self, word): + """ + Private method to search for a given word. + + @param word word to be searched for + @type str + """ + self.search.emit(word) + + +class WebBrowserSingleApplicationClient(SingleApplicationClient): + """ + Class implementing the single application client of the Translations + Previewer. + """ + def __init__(self): + """ + Constructor + """ + SingleApplicationClient.__init__(self, SAFile) + + def processArgs(self, args): + """ + Public method to process the command line args passed to the UI. + + @param args list of files to open + """ + # no args, return + if args is None: + return + + if Globals.isWindowsPlatform(): + argChars = ('-', '/') + else: + argChars = ('-', ) + + for arg in args: + if arg.startswith("--search="): + self.__search(arg.replace("--search=", "")) + elif not arg.startswith(argChars): + # it is an URL + self.__loadUrl(arg) + + self.disconnect() + + def __loadUrl(self, url): + """ + Private method to send an URL to be loaded. + + @param url URL to be loaded + @type str + """ + self.sendCommand(SALoadUrl, [url]) + + def __search(self, word): + """ + Private method to send a word to search for. + + @param word to to be searched for + @type str + """ + self.sendCommand(SASearch, [word])
--- a/WebBrowser/WebBrowserWindow.py Sun Dec 09 15:24:39 2018 +0100 +++ b/WebBrowser/WebBrowserWindow.py Sun Dec 09 16:39:35 2018 +0100 @@ -59,6 +59,8 @@ from .ZoomManager import ZoomManager +from .WebBrowserSingleApplication import WebBrowserSingleApplicationServer + from eric6config import getConfig @@ -117,7 +119,7 @@ def __init__(self, home, path, parent, name, fromEric=False, initShortcutsOnly=False, searchWord=None, private=False, qthelp=False, settingsDir="", - restoreSession=False): + restoreSession=False, single=False): """ Constructor @@ -145,6 +147,8 @@ @type str @keyparam restoreSession flag indicating a restore session action @type bool + @param single flag indicating to start in single application mode + @type bool """ self.__hideNavigationTimer = None @@ -357,7 +361,8 @@ syncMgr.syncError.connect(self.statusBar().showMessage) restoreSessionData = {} - if WebBrowserWindow._performingStartup and not home: + if WebBrowserWindow._performingStartup and not home and \ + not WebBrowserWindow.isPrivate(): startupBehavior = Preferences.getWebBrowser("StartupBehavior") if not private and startupBehavior in [3, 4]: if startupBehavior == 3: @@ -383,7 +388,7 @@ home = "eric:speeddial" if not restoreSession: - self.__tabWidget.newBrowser(home) + self.__tabWidget.newBrowser(QUrl.fromUserInput(home)) self.__tabWidget.currentBrowser().setFocus() WebBrowserWindow._performingStartup = False @@ -465,6 +470,13 @@ self.__toolbarStates = self.saveState() + if single: + self.SAServer = WebBrowserSingleApplicationServer() + self.SAServer.loadUrl.connect(self.__saLoadUrl) + self.SAServer.search.connect(self.__saSearchWord) + else: + self.SAServer = None + self.__hideNavigationTimer = QTimer(self) self.__hideNavigationTimer.setInterval(1000) self.__hideNavigationTimer.setSingleShot(True) @@ -472,11 +484,12 @@ self.__forcedClose = False - if restoreSessionData: + if restoreSessionData and not WebBrowserWindow.isPrivate(): self.sessionManager().restoreSessionFromData( self, restoreSessionData) - self.sessionManager().activateTimer() + if not WebBrowserWindow.isPrivate(): + self.sessionManager().activateTimer() QTimer.singleShot(0, syncMgr.loadSettings) @@ -2839,7 +2852,8 @@ if not self.__fromEric: if not WebBrowserWindow._performingShutdown and \ - len(WebBrowserWindow.BrowserWindows) == 1: + len(WebBrowserWindow.BrowserWindows) == 1 and \ + not WebBrowserWindow.isPrivate(): # shut down the session manager in case the last window is # about to be closed self.sessionManager().shutdown() @@ -2953,7 +2967,8 @@ WebBrowserWindow._performingShutdown = True - self.sessionManager().shutdown() + if not WebBrowserWindow.isPrivate(): + self.sessionManager().shutdown() if WebBrowserWindow._downloadManager is not None: self.downloadManager().shutdown() @@ -3305,7 +3320,8 @@ self.__javaScriptIcon.preferencesChanged() - self.sessionManager().preferencesChanged() + if not WebBrowserWindow.isPrivate(): + self.sessionManager().preferencesChanged() def masterPasswordChanged(self, oldPassword, newPassword, local=False): """ @@ -4992,3 +5008,31 @@ Private slot to show the safe browsing management dialog. """ self.safeBrowsingManager().showSafeBrowsingDialog() + + ############################################################### + ## Methods below implement single application related functions + ############################################################### + + @pyqtSlot(str) + def __saLoadUrl(self, urlStr): + """ + Private slot to load an URL received via the single application + protocol. + + @param urlStr URL to be loaded + @type str + """ + url = QUrl.fromUserInput(urlStr) + self.__linkActivated(url) + + @pyqtSlot(str) + def __saSearchWord(self, word): + """ + Private slot to search for the given word. + + @param word word to be searched for + @type str + """ + if WebBrowserWindow._useQtHelp: + self.__searchWord = word + self.__searchForWord()
--- a/changelog Sun Dec 09 15:24:39 2018 +0100 +++ b/changelog Sun Dec 09 16:39:35 2018 +0100 @@ -7,6 +7,8 @@ if it has one defined - Project Resources Browser -- added support for some resource compiler options +- Web Browser (NG): + -- added single application mode Version 18.12: - bug fixes
--- a/eric6.e4p Sun Dec 09 15:24:39 2018 +0100 +++ b/eric6.e4p Sun Dec 09 16:39:35 2018 +0100 @@ -1626,6 +1626,7 @@ <Source>WebBrowser/WebBrowserJavaScriptConsole.py</Source> <Source>WebBrowser/WebBrowserLanguagesDialog.py</Source> <Source>WebBrowser/WebBrowserPage.py</Source> + <Source>WebBrowser/WebBrowserSingleApplication.py</Source> <Source>WebBrowser/WebBrowserSnap.py</Source> <Source>WebBrowser/WebBrowserTabBar.py</Source> <Source>WebBrowser/WebBrowserTabWidget.py</Source>
--- a/eric6_browser.py Sun Dec 09 15:24:39 2018 +0100 +++ b/eric6_browser.py Sun Dec 09 16:39:35 2018 +0100 @@ -90,8 +90,13 @@ import Globals from Globals import AppInfo +from E5Gui.E5Application import E5Application + from Toolbox import Startup +from WebBrowser.WebBrowserSingleApplication import \ + WebBrowserSingleApplicationClient + def createMainWidget(argv): """ @@ -105,6 +110,7 @@ searchWord = None private = False qthelp = False + single = False for arg in reversed(argv): if arg.startswith("--search="): @@ -116,6 +122,9 @@ elif arg == "--qthelp": qthelp = True argv.remove(arg) + elif arg == "--single": + single = True + argv.remove(arg) elif arg.startswith("--"): argv.remove(arg) @@ -126,7 +135,8 @@ browser = WebBrowserWindow(home, '.', None, 'web_browser', searchWord=searchWord, private=private, - settingsDir=SettingsDir, qthelp=qthelp) + settingsDir=SettingsDir, qthelp=qthelp, + single=single) return browser @@ -142,6 +152,7 @@ ("--search=word", "search for the given word"), ("--settings=settingsDir", "use the given directory to store the settings files"), + ("--single", "start the browser as a single application"), ] appinfo = AppInfo.makeAppInfo(sys.argv, "eric6 Web Browser", @@ -152,10 +163,27 @@ if not Globals.checkBlacklistedVersions(): sys.exit(100) + + # set the library paths for plugins + Startup.setLibraryPaths() + + app = E5Application(sys.argv) + if not "--private" in sys.argv: + client = WebBrowserSingleApplicationClient() + res = client.connect() + if res > 0: + if len(sys.argv) > 1: + client.processArgs(sys.argv[1:]) + sys.exit(0) + elif res < 0: + print("eric6_trpreviewer: {0}".format(client.errstr())) + sys.exit(res) + res = Startup.simpleAppStartup(sys.argv, appinfo, createMainWidget, - installErrorHandler=True) + installErrorHandler=True, + app=app) sys.exit(res) if __name__ == '__main__':