diff -r 6411ee48fe91 -r 9487c08b6a23 WebBrowser/WebBrowserView.py --- a/WebBrowser/WebBrowserView.py Thu Jul 06 18:59:43 2017 +0200 +++ b/WebBrowser/WebBrowserView.py Wed Aug 02 13:28:50 2017 +0200 @@ -17,7 +17,8 @@ import os from PyQt5.QtCore import pyqtSignal, QUrl, QFileInfo, Qt, QTimer, QEvent, \ - QPoint, QDateTime, QStandardPaths + QPoint, QPointF, QDateTime, QStandardPaths, QByteArray, QIODevice, \ + QDataStream from PyQt5.QtGui import QDesktopServices, QClipboard, QIcon, \ QContextMenuEvent, QPixmap from PyQt5.QtWidgets import qApp, QStyle, QMenu, QApplication @@ -123,6 +124,8 @@ self.__inspector = None WebInspector.registerView(self) + self.__restoreData = None + if qVersionTuple() >= (5, 8, 0): if self.parentWidget() is not None: self.parentWidget().installEventFilter(self) @@ -1894,3 +1897,155 @@ Private slot to reset all speed dials to the default pages. """ self.__speedDial.resetDials() + + ########################################################################### + ## Methods below implement session related functions + ########################################################################### + + def storeSessionData(self, data): + """ + Public method to store session data to be restored later on. + + @param data dictionary with session data to be restored + @type dict + """ + self.__restoreData = data + + def __showEventSlot(self): + """ + Private slot to perform actions when the view is shown and the event + loop is running. + """ + if self.__restoreData: + sessionData, self.__restoreData = self.__restoreData, None + self.loadFromSessionData(sessionData) + + def showEvent(self, evt): + """ + Protected method to handle show events. + + @param evt reference to the show event object + @type QShowEvent + """ + super(WebBrowserView, self).showEvent(evt) + self.activateSession() + + def activateSession(self): + """ + Public slot to activate a restored session. + """ + if self.__restoreData and not self.__mw.isClosing(): + QTimer.singleShot(0, self.__showEventSlot) + + def getSessionData(self): + """ + Public method to populate the session data. + + @return dictionary containing the session data + @rtype dict + """ + if self.__restoreData: + # page has not been shown yet + return self.__restoreData + + sessionData = {} + page = self.page() + + # 1. zoom factor + sessionData["ZoomFactor"] = page.zoomFactor() + + # 2. scroll position + scrollPos = page.scrollPosition() + sessionData["ScrollPosition"] = { + "x": scrollPos.x(), + "y": scrollPos.y(), + } + + # 3. page history + historyArray = QByteArray() + stream = QDataStream(historyArray, QIODevice.WriteOnly) + stream << page.history() + sessionData["History"] = str( + historyArray.toBase64(QByteArray.Base64UrlEncoding), + encoding="ascii") + sessionData["HistoryIndex"] = page.history().currentItemIndex() + + # 4. current URL and title + sessionData["Url"] = self.url().toString() + sessionData["Title"] = self.title() + + # 5. web icon + iconArray = QByteArray() + stream = QDataStream(iconArray, QIODevice.WriteOnly) + stream << page.icon() + sessionData["Icon"] = str(iconArray.toBase64(), encoding="ascii") + + 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 + """ + page = self.page() + # blank the page + page.setUrl(QUrl("about:blank")) + + # 1. page history + if "History" in sessionData: + historyArray = QByteArray.fromBase64( + sessionData["History"].encode("ascii"), + QByteArray.Base64UrlEncoding) + stream = QDataStream(historyArray, QIODevice.ReadOnly) + stream >> page.history() + + if "HistoryIndex" in sessionData: + item = page.history().itemAt(sessionData["HistoryIndex"]) + if item is not None: + page.history().goToItem(item) + + # 2. zoom factor + if "ZoomFactor" in sessionData: + page.setZoomFactor(sessionData["ZoomFactor"]) + + # 3. scroll position + if "ScrollPosition" in sessionData: + scrollPos = sessionData["ScrollPosition"] + page.scrollTo(QPointF(scrollPos["x"], scrollPos["y"])) + + def extractSessionMetaData(self, sessionData): + """ + Public method to extract some session meta data elements needed by the + tab widget in case of deferred loading. + + @param sessionData dictionary containing the session data as + generated by getSessionData() + @type dict + @return tuple containing the title, URL and web icon + @rtype tuple of (str, str, QIcon) + """ + if "Title" in sessionData: + title = sessionData["Title"] + else: + title = "" + + if "Url" in sessionData: + urlStr = sessionData["Url"] + else: + urlStr = "" + + if "Icon" in sessionData: + iconArray = QByteArray.fromBase64( + sessionData["Icon"].encode("ascii")) + stream = QDataStream(iconArray, QIODevice.ReadOnly) + icon = QIcon() + stream >> icon + else: + from .Tools import WebIconProvider + icon = WebIconProvider.instance().iconForUrl( + QUrl.fromUserInput(urlStr)) + + return title, urlStr, icon