Thu, 29 Jun 2017 19:21:52 +0200
Continued implementing session support for the new web browser.
--- a/Preferences/__init__.py Thu Jun 29 18:51:03 2017 +0200 +++ b/Preferences/__init__.py Thu Jun 29 19:21:52 2017 +0200 @@ -1103,6 +1103,9 @@ # Flash Cookie Manager: identical to helpDefaults # PIM: identical to helpDefaults # VirusTotal: identical to helpDefaults + # Sessions + "SessionAutoSave": True, + "SessionAutoSaveInterval": 15, # interval in seconds } if QWebEngineSettings: webBrowserDefaults["HelpViewerType"] = 1 # eric browser @@ -2870,6 +2873,7 @@ "MinimumFontSize", "MinimumLogicalFontSize", "DiskCacheSize", "AcceptCookies", "KeepCookiesUntil", "AdBlockUpdatePeriod", "TabManagerGroupByType", + "SessionAutoSaveInterval", ]: return int(prefClass.settings.value( "WebBrowser/" + key, prefClass.webBrowserDefaults[key])) @@ -2893,6 +2897,7 @@ "PrintElementBackgrounds", "AllowRunningInsecureContent", "SpellCheckEnabled", "ShowToolbars", "MenuBarVisible", "BookmarksToolBarVisible", "StatusBarVisible", + "SessionAutoSave", ]: return toBool(prefClass.settings.value( "WebBrowser/" + key, prefClass.webBrowserDefaults[key]))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebBrowser/Session/SessionManager.py Thu Jun 29 19:21:52 2017 +0200 @@ -0,0 +1,116 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2017 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing the session manager. +""" + +from __future__ import unicode_literals + +import os +import json + +from PyQt5.QtCore import pyqtSlot, QObject, QTimer, QDir + +import Utilities +import Preferences + + +class SessionManager(QObject): + """ + Class implementing the session manager. + """ + def __init__(self, parent=None): + """ + Constructor + + @param parent reference to the parent object + @type QObject + """ + super(SessionManager, self).__init__(parent) + + sessionsDir = QDir(self.getSessionsDirectory()) + if not sessionsDir.exists(): + sessionsDir.mkpath(self.getSessionsDirectory()) + + 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): + """ + Public method to get the directory sessions are stored in. + + @return name of the sessions directory + @rtype str + """ + return os.path.join(Utilities.getConfigDir(), + "web_browser", "sessions") + + def defaultSessionFile(self): + """ + Public method to get the name of the default session file. + + @return name of the default session file + @rtype str + """ + return os.path.join(self.getSessionsDirectory(), "session.json") + + def __initSessionSaveTimer(self): + """ + Private slot to initialize the auto save timer. + """ + self.__autoSaveInterval = Preferences.getWebBrowser( + "SessionAutoSaveInterval") * 1000 + + if Preferences.getWebBrowser("SessionAutoSave"): + if not self.__autoSaveTimer.isActive(): + self.__autoSaveTimer.start(self.__autoSaveInterval) + else: + self.__autoSaveTimer.stop() + + @pyqtSlot() + def __autoSaveSession(self): + """ + Private slot to save the current session state. + """ + from WebBrowser.WebBrowserWindow import WebBrowserWindow + + if not WebBrowserWindow.isPrivate(): + self.writeCurrentSession(self.defaultSessionFile()) + + self.__autoSaveTimer.start(self.__autoSaveInterval) + + def writeCurrentSession(self, sessionFileName): + """ + Public method to write the current session to the given file name. + + @param sessionFileName file name of the session + @type str + """ + from WebBrowser.WebBrowserWindow import WebBrowserWindow + + sessionData = {"Windows": []} + + for window in WebBrowserWindow.mainWindows(): + data = window.tabWidget().getSessionData() + + # add window geometry + geometry = window.saveGeometry() + data["WindowGeometry"] = bytes(geometry.toBase64()).decode("ascii") + + sessionData["Windows"].append(data) + + sessionFile = open(sessionFileName, "w") + json.dump(sessionData, sessionFile, indent=2) + sessionFile.close()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebBrowser/Session/__init__.py Thu Jun 29 19:21:52 2017 +0200 @@ -0,0 +1,8 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2017 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Package implementing the session related functionality. +"""
--- a/WebBrowser/WebBrowserPage.py Thu Jun 29 18:51:03 2017 +0200 +++ b/WebBrowser/WebBrowserPage.py Thu Jun 29 19:21:52 2017 +0200 @@ -405,9 +405,40 @@ sessionData["History"] = str( historyArray.toBase64(QByteArray.Base64UrlEncoding), encoding="ascii") + sessionData["HistoryIndex"] = self.history().currentItemIndex() return sessionData + def loadFromSessionData(self, sessionData): + """ + Public method to load the session data. + + @param sessionData dictionary containing the session data as + generated by getSessionData() + @type dict + """ + # 1. page history + if "History" in sessionData: + historyArray = QByteArray.fromBase64( + sessionData["History"].encode("ascii"), + QByteArray.Base64UrlEncoding) + stream = QDataStream(historyArray, QIODevice.ReadOnly) + stream >> self.history() + + if "HistoryIndex" in sessionData: + item = self.history().itemAt(sessionData["HistoryIndex"]) + if item is not None: + self.history().goToItem(item) + + # 2. zoom factor + if "ZoomFactor" in sessionData: + self.setZoomFactor(sessionData["ZoomFactor"]) + + # 3. scroll position + if "ScrollPosition" in sessionData: + scrollPos = sessionData["ScrollPosition"] + self.scrollTo(QPointF(scrollPos["x"], scrollPos["y"])) + ################################################## ## Methods below implement compatibility functions ##################################################
--- a/WebBrowser/WebBrowserTabWidget.py Thu Jun 29 18:51:03 2017 +0200 +++ b/WebBrowser/WebBrowserTabWidget.py Thu Jun 29 19:21:52 2017 +0200 @@ -1183,3 +1183,49 @@ """ self.__closedTabsButton.setEnabled(avail) self.__restoreClosedTabAct.setEnabled(avail) + + #################################################### + ## Methods below implement session related functions + #################################################### + + def getSessionData(self): + """ + Public method to populate the session data. + + @return dictionary containing the session data + @rtype dict + """ + sessionData = {} + + # 1. current index + sessionData["CurrentTabIndex"] = self.currentIndex() + + # 2. tab data + sessionData["Tabs"] = [] + for index in range(self.count()): + browser = self.widget(index) + data = browser.page().getSessionData() + sessionData["Tabs"].append(data) + + return sessionData + + def loadFromSessionData(self, sessionData): + """ + Public method to load the session data. + + @param sessionData dictionary containing the session data as + generated by getSessionData() + @type dict + """ + tabCount = self.count() + + # 1. load tab data + if "Tabs" in sessionData: + for data in sessionData["Tabs"]: + browser = self.newBrowser() + browser.page().loadFromSessionData(data) + + # 2. set tab index + if "CurrentTabIndex" in sessionData: + index = tabCount + sessionData["CurrentTabIndex"] + self.setCurrentIndex(index)
--- a/WebBrowser/WebBrowserWindow.py Thu Jun 29 18:51:03 2017 +0200 +++ b/WebBrowser/WebBrowserWindow.py Thu Jun 29 19:21:52 2017 +0200 @@ -107,6 +107,7 @@ _imageSearchEngine = None _autoScroller = None _tabManager = None + _sessionManager = None def __init__(self, home, path, parent, name, fromEric=False, initShortcutsOnly=False, searchWord=None, @@ -427,6 +428,8 @@ self.__hideNavigationTimer.setSingleShot(True) self.__hideNavigationTimer.timeout.connect(self.__hideNavigation) + self.sessionManager() + QTimer.singleShot(0, syncMgr.loadSettings) def __del__(self): @@ -3083,6 +3086,8 @@ self.virustotalDomainReportAct.setEnabled(True) self.__javaScriptIcon.preferencesChanged() + + self.sessionManager().preferencesChanged() def masterPasswordChanged(self, oldPassword, newPassword): """ @@ -4648,3 +4653,21 @@ cls._webProfile.scripts().insert(script) return cls._webProfile + + #################################################### + ## Methods below implement session related functions + #################################################### + + @classmethod + def sessionManager(cls): + """ + Class method to get a reference to the session manager. + + @return reference to the session manager + @rtype SessionManager + """ + if cls._sessionManager is None and not cls._isPrivate: + from .Session.SessionManager import SessionManager + cls._sessionManager = SessionManager() + + return cls._sessionManager
--- a/eric6.e4p Thu Jun 29 18:51:03 2017 +0200 +++ b/eric6.e4p Thu Jun 29 19:21:52 2017 +0200 @@ -1405,6 +1405,8 @@ <Source>WebBrowser/QtHelp/QtHelpFiltersDialog.py</Source> <Source>WebBrowser/QtHelp/__init__.py</Source> <Source>WebBrowser/SearchWidget.py</Source> + <Source>WebBrowser/Session/SessionManager.py</Source> + <Source>WebBrowser/Session/__init__.py</Source> <Source>WebBrowser/SiteInfo/SiteInfoDialog.py</Source> <Source>WebBrowser/SiteInfo/__init__.py</Source> <Source>WebBrowser/SpeedDial/Page.py</Source>