WebBrowser: added single application mode.

Sun, 09 Dec 2018 16:39:35 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sun, 09 Dec 2018 16:39:35 +0100
changeset 6623
c0882a599e18
parent 6622
3dfcbe478fd3
child 6624
9718755def80

WebBrowser: added single application mode.

WebBrowser/WebBrowserSingleApplication.py file | annotate | diff | comparison | revisions
WebBrowser/WebBrowserWindow.py file | annotate | diff | comparison | revisions
changelog file | annotate | diff | comparison | revisions
eric6.e4p file | annotate | diff | comparison | revisions
eric6_browser.py file | annotate | diff | comparison | revisions
--- /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__':

eric ide

mercurial