WebBrowser/Session/SessionManager.py

changeset 5783
44a9f08de394
parent 5782
60874802161b
child 5785
7c7c5f9e4fad
--- a/WebBrowser/Session/SessionManager.py	Sun Jul 02 19:40:39 2017 +0200
+++ b/WebBrowser/Session/SessionManager.py	Mon Jul 03 19:23:54 2017 +0200
@@ -15,7 +15,8 @@
 from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QObject, QTimer, QDir, \
     QFile, QFileInfo, QFileSystemWatcher, QByteArray, QDateTime
 from PyQt5.QtWidgets import QMenu, QAction, QActionGroup, QApplication, \
-    QInputDialog, QLineEdit
+    QInputDialog, QLineEdit, QDialog, QDialogButtonBox, QLabel, QComboBox, \
+    QVBoxLayout
 
 from E5Gui import E5MessageBox
 
@@ -87,17 +88,24 @@
         
         self.__backupSavedSession()
         
-        self.__autoSaveTimer = QTimer()
-        self.__autoSaveTimer.setSingleShot(True)
-        self.__autoSaveTimer.timeout.connect(self.__autoSaveSession)
-        self.__initSessionSaveTimer()
+        self.__autoSaveTimer = None
+        self.__shutdown = False
+    
+    def activateTimer(self):
+        """
+        Public method to activate the session save timer.
+        """
+        if self.__autoSaveTimer is None:
+            self.__autoSaveTimer = QTimer()
+            self.__autoSaveTimer.setSingleShot(True)
+            self.__autoSaveTimer.timeout.connect(self.__autoSaveSession)
+            self.__initSessionSaveTimer()
     
     def preferencesChanged(self):
         """
         Public slot to react upon changes of the settings.
         """
         self.__initSessionSaveTimer()
-        # TODO: implement this
     
     def getSessionsDirectory(self):
         """
@@ -132,6 +140,14 @@
         Public method to perform any shutdown actions.
         """
         self.__autoSaveTimer.stop()
+        if not self.__shutdown:
+            self.__autoSaveSession(startTimer=False)
+        self.__shutdown = True
+    
+    def autoSaveSession(self):
+        """
+        Public method to save the current session state.
+        """
         self.__autoSaveSession(startTimer=False)
     
     def __initSessionSaveTimer(self):
@@ -176,6 +192,7 @@
         
         sessionData = {"Windows": []}
         
+        activeWindow = WebBrowserWindow.getWindow()
         for window in WebBrowserWindow.mainWindows():
             data = window.tabWidget().getSessionData()
             
@@ -184,15 +201,20 @@
             data["WindowGeometry"] = bytes(geometry.toBase64()).decode("ascii")
             
             sessionData["Windows"].append(data)
+            
+            if window is activeWindow:
+                sessionData["CurrentWindowIndex"] = \
+                    len(sessionData["Windows"]) -1
         
         if sessionData["Windows"]:
             sessionFile = open(sessionFileName, "w")
             json.dump(sessionData, sessionFile, indent=2)
             sessionFile.close()
     
-    def __readSessionFromFile(self, sessionFileName):
+    @classmethod
+    def readSessionFromFile(cls, sessionFileName):
         """
-        Private method to read the session data from a file.
+        Class method to read the session data from a file.
         
         @param sessionFileName file name of the session file
         @type str
@@ -203,11 +225,34 @@
             sessionFile = open(sessionFileName, "r")
             sessionData = json.load(sessionFile)
             sessionFile.close()
+            if not cls.isValidSession(sessionData):
+                sessionData = {}
         except (IOError, OSError):
             sessionData = {}
         
         return sessionData
     
+    @classmethod
+    def isValidSession(cls, session):
+        """
+        Class method to check the validity of a session.
+        
+        @param session dictionary containing the session data
+        @type dict
+        @return flag indicating validity
+        @rtype bool
+        """
+        if not session:
+            return False
+        
+        if "Windows" not in session:
+            return False
+        
+        if not session["Windows"]:
+            return False
+        
+        return True
+    
     def __backupSavedSession(self):
         """
         Private method to backup the most recently saved session.
@@ -264,7 +309,7 @@
             ["*.json"], QDir.Files, QDir.Time)
         
         for sessionFileInfo in sessionFilesInfoList:
-            sessionData = self.__readSessionFromFile(
+            sessionData = self.readSessionFromFile(
                 sessionFileInfo.absoluteFilePath())
             if not sessionData or not sessionData["Windows"]:
                 continue
@@ -335,9 +380,9 @@
             path = act.data()
             self.switchToSession(path)
     
-    def __openSession(self, sessionFilePath, flags=0):
+    def openSession(self, sessionFilePath, flags=0):
         """
-        Private method to open a session from a given session file.
+        Public method to open a session from a given session file.
         
         @param sessionFilePath name of the session file to get session from
         @type str
@@ -347,7 +392,7 @@
         if self.__isActive(sessionFilePath):
             return
         
-        sessionData = self.__readSessionFromFile(sessionFilePath)
+        sessionData = self.readSessionFromFile(sessionFilePath)
         if not sessionData or not sessionData["Windows"]:
             return
         
@@ -363,7 +408,7 @@
             window = window.newWindow(restoreSession=True)
             
             # close all existing windows
-            for win in WebBrowserWindow.mainWindows():
+            for win in WebBrowserWindow.mainWindows()[:]:
                 if win is not window:
                     win.forceClose()
             
@@ -373,6 +418,21 @@
                     QFileInfo(sessionFilePath).canonicalFilePath()
                 self.__sessionMetaData = []
         
+        self.restoreSessionFromData(window, sessionData)
+    
+    @classmethod
+    def restoreSessionFromData(cls, window=None, sessionData=None):
+        """
+        Class method to restore a session from a session data dictionary.
+        
+        @param window reference to main window to restore to
+        @type WebBrowserWindow
+        @param sessionData dictionary containing the session data
+        """
+        from WebBrowser.WebBrowserWindow import WebBrowserWindow
+        if window is None:
+            window = WebBrowserWindow.mainWindow()
+        
         QApplication.setOverrideCursor(Qt.WaitCursor)
         # restore session for first window
         data = sessionData["Windows"].pop(0)
@@ -381,6 +441,9 @@
             geometry = QByteArray.fromBase64(
                 data["WindowGeometry"].encode("ascii"))
             window.restoreGeometry(geometry)
+        if Utilities.isWindowsPlatform():
+            window.hide()
+            window.show()
         QApplication.processEvents()
         
         # restore additional windows
@@ -392,12 +455,25 @@
                 geometry = QByteArray.fromBase64(
                     data["WindowGeometry"].encode("ascii"))
                 window.restoreGeometry(geometry)
+            if Utilities.isWindowsPlatform():
+                window.hide()
+                window.show()
             QApplication.processEvents()
         QApplication.restoreOverrideCursor()
+        
+        if "CurrentWindowIndex" in sessionData:
+            currentWindowIndex = sessionData["CurrentWindowIndex"]
+            try:
+                currentWindow = \
+                    WebBrowserWindow.mainWindows()[currentWindowIndex]
+                currentWindow.raise_()
+            except IndexError:
+                # ignore it
+                pass
     
     def renameSession(self, sessionFilePath, flags=0):
         """
-        Public method to rename or clone a session
+        Public method to rename or clone a session.
         
         @param sessionFilePath name of the session file
         @type str
@@ -493,6 +569,8 @@
         
         @param sessionFilePath file name of the session file to replace with
         @type str
+        @return flag indicating success
+        @rtype bool
         """
         from WebBrowser.WebBrowserWindow import WebBrowserWindow
         res = E5MessageBox.yesNo(
@@ -501,7 +579,10 @@
             self.tr("""Are you sure you want to replace the current"""
                     """ session?"""))
         if res:
-            self.__openSession(sessionFilePath, SessionManager.ReplaceSession)
+            self.openSession(sessionFilePath, SessionManager.ReplaceSession)
+            return True
+        else:
+            return False
     
     def switchToSession(self, sessionFilePath):
         """
@@ -509,8 +590,11 @@
         
         @param sessionFilePath file name of the session file to switch to
         @type str
+        @return flag indicating success
+        @rtype bool
         """
-        self.__openSession(sessionFilePath, SessionManager.SwitchSession)
+        self.openSession(sessionFilePath, SessionManager.SwitchSession)
+        return True
     
     def cloneSession(self, sessionFilePath):
         """
@@ -526,7 +610,7 @@
         Public method to delete a session.
         
         @param sessionFilePath file name of the session file to be deleted
-        @type str        
+        @type str
         """
         from WebBrowser.WebBrowserWindow import WebBrowserWindow
         res = E5MessageBox.yesNo(
@@ -586,3 +670,53 @@
         
         dlg = SessionManagerDialog(WebBrowserWindow.getWindow())
         dlg.open()
+    
+    def selectSession(self):
+        """
+        Public method to select a session to be restored.
+        
+        @return name of the session file to be restored
+        @rtype str
+        """
+        from WebBrowser.WebBrowserWindow import WebBrowserWindow
+        
+        self.__fillMetaDataList()
+        
+        if self.__sessionMetaData:
+            # skip, if no session file available
+            dlg = QDialog(WebBrowserWindow.getWindow(),
+                          Qt.WindowStaysOnTopHint)
+            lbl = QLabel(self.tr("Please select the startup session:"))
+            combo = QComboBox(dlg)
+            buttonBox = QDialogButtonBox(
+                QDialogButtonBox.Ok | QDialogButtonBox.Cancel, dlg)
+            buttonBox.accepted.connect(dlg.accept)
+            buttonBox.rejected.connect(dlg.reject)
+            
+            layout = QVBoxLayout()
+            layout.addWidget(lbl)
+            layout.addWidget(combo)
+            layout.addWidget(buttonBox)
+            dlg.setLayout(layout)
+            
+            lastActiveSessionFileInfo = QFileInfo(self.__lastActiveSession)
+            
+            for metaData in self.__sessionMetaData:
+                if QFileInfo(metaData.filePath) != lastActiveSessionFileInfo:
+                    combo.addItem(metaData.name, metaData.filePath)
+                else:
+                    combo.insertItem(
+                        0,
+                        self.tr("{0} (last session)").format(metaData.name),
+                        metaData.filePath
+                    )
+            combo.setCurrentIndex(0)
+            
+            if dlg.exec_() == QDialog.Accepted:
+                session = combo.currentData()
+                if session is None:
+                    self.__lastActiveSession = self.__sessionDefault
+                else:
+                    self.__lastActiveSession = session
+        
+        return self.__lastActiveSession

eric ide

mercurial