WebBrowser/WebBrowserPage.py

Sat, 02 Apr 2016 19:44:09 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sat, 02 Apr 2016 19:44:09 +0200
branch
QtWebEngine
changeset 4910
e97af1181efd
parent 4906
939ff20f712d
child 4913
e16573640cb8
permissions
-rw-r--r--

Continued porting the web browser.

- some code cleanup

# -*- coding: utf-8 -*-

# Copyright (c) 2008 - 2016 Detlev Offenbach <detlev@die-offenbachs.de>
#


"""
Module implementing the helpbrowser using QWebView.
"""

from __future__ import unicode_literals
try:
    str = unicode       # __IGNORE_EXCEPTION__
except NameError:
    pass

from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject, QT_TRANSLATE_NOOP, \
    QUrl, QBuffer, QIODevice, QFileInfo, Qt, QTimer, QEvent, \
    QRect, QFile, QPoint, QByteArray, QEventLoop, qVersion
from PyQt5.QtGui import QDesktopServices, QClipboard, QMouseEvent, QColor, \
    QPalette
from PyQt5.QtWidgets import qApp, QStyle, QMenu, QApplication, QInputDialog, \
    QLineEdit, QLabel, QToolTip, QFrame, QDialog
from PyQt5.QtPrintSupport import QPrinter, QPrintDialog
from PyQt5.QtWebEngineWidgets import QWebEnginePage
from PyQt5.QtWebChannel import QWebChannel
from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest
import sip

from E5Gui import E5MessageBox, E5FileDialog

import WebBrowser
from WebBrowser.WebBrowserWindow import WebBrowserWindow

from .JavaScript.ExternalJsObject import ExternalJsObject

from .Tools.WebHitTestResult import WebHitTestResult
from .Tools import Scripts

import Preferences
import UI.PixmapCache
import Globals
##
##try:
##    from PyQt5.QtNetwork import QSslCertificate
##    SSL_AVAILABLE = True
##except ImportError:
##    SSL_AVAILABLE = False


class WebBrowserPage(QWebEnginePage):
    """
    Class implementing an enhanced web page.
    """
##    _webPluginFactory = None
##    
    def __init__(self, parent=None):
        """
        Constructor
        
        @param parent parent widget of this window (QWidget)
        """
        super(WebBrowserPage, self).__init__(
            WebBrowserWindow.webProfile(), parent)
        
        self.__setupWebChannel()
        
##        self.setPluginFactory(self.webPluginFactory())
##        
##        self.__lastRequest = None
##        self.__lastRequestType = QWebPage.NavigationTypeOther
##        
##        from .Network.NetworkAccessManagerProxy import \
##            NetworkAccessManagerProxy
##        self.__proxy = NetworkAccessManagerProxy(self)
##        self.__proxy.setWebPage(self)
##        self.__proxy.setPrimaryNetworkAccessManager(
##            WebBrowserWindow.networkManager())
##        self.setNetworkAccessManager(self.__proxy)
##        
##        self.__sslConfiguration = None
##        self.__proxy.finished.connect(self.__managerFinished)
##        
##        self.__adBlockedEntries = []
##        self.loadStarted.connect(self.__loadStarted)
        self.featurePermissionRequested.connect(
            self.__featurePermissionRequested)
        
        self.authenticationRequired.connect(
            WebBrowserWindow.networkManager().authentication)
        
        self.proxyAuthenticationRequired.connect(
            WebBrowserWindow.networkManager().proxyAuthentication)
        
        self.fullScreenRequested.connect(self.__fullScreenRequested)
    
    def acceptNavigationRequest(self, url, type_, isMainFrame):
        """
        Public method to determine, if a request may be accepted.
        
        @param url URL to navigate to
        @type QUrl
        @param type_ type of the navigation request
        @type QWebEnginePage.NavigationType
        @param isMainFrame flag indicating, that the request originated from
            the main frame
        @type bool
        @return flag indicating acceptance
        @rtype bool
        """
        scheme = url.scheme()
        if scheme == "mailto":
            QDesktopServices.openUrl(url)
            return False
        
        # AdBlock
        if url.scheme() == "abp":
            if WebBrowserWindow.adBlockManager().addSubscriptionFromUrl(url):
                return False
        
        return QWebEnginePage.acceptNavigationRequest(self, url, type_,
                                                      isMainFrame)
    
    @classmethod
    def userAgent(cls, resolveEmpty=False):
        """
        Class method to get the global user agent setting.
        
        @param resolveEmpty flag indicating to resolve an empty
            user agent (boolean)
        @return user agent string (string)
        """
        agent = Preferences.getWebBrowser("UserAgent")
        if agent == "" and resolveEmpty:
            agent = cls.userAgentForUrl(QUrl())
        return agent
    
    @classmethod
    def setUserAgent(cls, agent):
        """
        Class method to set the global user agent string.
        
        @param agent new current user agent string (string)
        """
        Preferences.setWebBrowser("UserAgent", agent)
    
    @classmethod
    def userAgentForUrl(cls, url):
        """
        Class method to determine the user agent for the given URL.
        
        @param url URL to determine user agent for (QUrl)
        @return user agent string (string)
        """
        agent = WebBrowserWindow.userAgentsManager().userAgentForUrl(url)
        if agent == "":
            # no agent string specified for the given host -> use global one
            agent = Preferences.getWebBrowser("UserAgent")
            if agent == "":
                # no global agent string specified -> use default one
                agent = WebBrowserWindow.webProfile().httpUserAgent()
        return agent
    
##    @classmethod
##    def webPluginFactory(cls):
##        """
##        Class method to get a reference to the web plug-in factory
##        instance.
##        
##        @return reference to the web plug-in factory instance (WebPluginFactory
##        """
##        if cls._webPluginFactory is None:
##            from .WebPlugins.WebPluginFactory import WebPluginFactory
##            cls._webPluginFactory = WebPluginFactory()
##        
##        return cls._webPluginFactory
##    
##    def event(self, evt):
##        """
##        Public method implementing the event handler.
##        
##        @param evt reference to the event (QEvent)
##        @return flag indicating that the event was handled (boolean)
##        """
##        if evt.type() == QEvent.Leave:
##            # Fake a mouse move event just outside of the widget to trigger
##            # the WebKit event handler's mouseMoved function. This implements
##            # the interesting mouse-out behavior like invalidating scrollbars.
##            fakeEvent = QMouseEvent(QEvent.MouseMove, QPoint(0, -1),
##                                    Qt.NoButton, Qt.NoButton, Qt.NoModifier)
##            return super(HelpWebPage, self).event(fakeEvent)
##        
##        return super(HelpWebPage, self).event(evt)
    
    def __featurePermissionRequested(self, url, feature):
        """
        Private slot handling a feature permission request.
        
        @param url url requesting the feature
        @type QUrl
        @param feature requested feature
        @type QWebEnginePage.Feature
        """
        manager = WebBrowserWindow.featurePermissionManager()
        manager.requestFeaturePermission(self, url, feature)
    
    def execJavaScript(self, script):
        """
        Public method to execute a JavaScript function synchroneously.
        
        @param script JavaScript script source to be executed
        @type str
        @return result of the script
        @rtype depending upon script result
        """
        loop = QEventLoop()
        resultDict = {"res": None}
        QTimer.singleShot(500, loop.quit);
        
        def resultCallback(res, resDict=resultDict):
            if loop and loop.isRunning():
                resDict["res"] = res
                loop.quit()
        
        self.runJavaScript(script, resultCallback)
        
        loop.exec_()
        return resultDict["res"]
    
    def scroll(self, x, y):
        """
        Public method to scroll by the given amount of pixels.
        
        @param x horizontal scroll value
        @type int
        @param y vertical scroll value
        @type int
        """
        self.runJavaScript(
            "window.scrollTo(window.scrollX + {0}, window.scrollY + {1})"
            .format(x, y)
        )
    
    def hitTestContent(self, pos):
        """
        Public method to test the content at a specified position.
        
        @param pos position to execute the test at
        @type QPoint
        @return test result object
        @rtype WebHitTestResult
        """
        return WebHitTestResult(self, pos)
    
    def __setupWebChannel(self):
        """
        Private method to setup a web channel to our external object.
        """
        oldChannel = self.webChannel()
        newChannel = QWebChannel(self)
        newChannel.registerObject("eric_object", ExternalJsObject(self))
        self.setWebChannel(newChannel)
        
        if oldChannel:
            del oldChannel.registeredObjects["eric_object"]
            del oldChannel
    
    def certificateError(self, error):
        """
        Public method to handle SSL certificate errors.
        
        @param error object containing the certificate error information
        @type QWebEngineCertificateError
        @return flag indicating to ignore this error
        @rtype bool
        """
        return WebBrowserWindow.networkManager().certificateError(
            error, self.view())
    
    def __fullScreenRequested(self, request):
        """
        Private slot handling a full screen request.
        """
        self.view().requestFullScreen(request.toggleOn())
        
        accepted = request.toggleOn() == self.view().isFullScreen()
        
        if accepted:
            request.accept()
        else:
            request.reject()
    
    ##############################################
    ## Methods below deal with JavaScript messages
    ##############################################
    
    def javaScriptConsoleMessage(self, level, message, lineNumber,  sourceId):
        """
        Public method to show a console message.
        
        @param level severity
        @type QWebEnginePage.JavaScriptConsoleMessageLevel
        @param message message to be shown
        @type str
        @param lineNumber line number of an error
        @type int
        @param sourceId source URL causing the error
        @type str
        """
        self.view().mainWindow().javascriptConsole().javaScriptConsoleMessage(
            level, message, lineNumber,  sourceId)

eric ide

mercurial