Wed, 19 Sep 2018 19:50:10 +0200
EricSchemeHandler, QtHelpSchemeHandler: ensure, that data is loaded in the main thread.
--- a/Documentation/Help/source.qhp Tue Sep 18 19:23:07 2018 +0200 +++ b/Documentation/Help/source.qhp Wed Sep 19 19:50:10 2018 +0200 @@ -13630,6 +13630,7 @@ <keyword name="QtHelpSchemeHandler.requestStarted" id="QtHelpSchemeHandler.requestStarted" ref="eric6.WebBrowser.Network.QtHelpSchemeHandler.html#QtHelpSchemeHandler.requestStarted" /> <keyword name="QtHelpSchemeReply" id="QtHelpSchemeReply" ref="eric6.WebBrowser.Network.QtHelpSchemeHandler.html#QtHelpSchemeReply" /> <keyword name="QtHelpSchemeReply (Constructor)" id="QtHelpSchemeReply (Constructor)" ref="eric6.WebBrowser.Network.QtHelpSchemeHandler.html#QtHelpSchemeReply.__init__" /> + <keyword name="QtHelpSchemeReply.__loadQtHelpPage" id="QtHelpSchemeReply.__loadQtHelpPage" ref="eric6.WebBrowser.Network.QtHelpSchemeHandler.html#QtHelpSchemeReply.__loadQtHelpPage" /> <keyword name="QtHelpSchemeReply.__mimeFromUrl" id="QtHelpSchemeReply.__mimeFromUrl" ref="eric6.WebBrowser.Network.QtHelpSchemeHandler.html#QtHelpSchemeReply.__mimeFromUrl" /> <keyword name="QtHelpSchemeReply.bytesAvailable" id="QtHelpSchemeReply.bytesAvailable" ref="eric6.WebBrowser.Network.QtHelpSchemeHandler.html#QtHelpSchemeReply.bytesAvailable" /> <keyword name="QtHelpSchemeReply.close" id="QtHelpSchemeReply.close" ref="eric6.WebBrowser.Network.QtHelpSchemeHandler.html#QtHelpSchemeReply.close" />
--- a/Documentation/Source/eric6.WebBrowser.Network.QtHelpSchemeHandler.html Tue Sep 18 19:23:07 2018 +0200 +++ b/Documentation/Source/eric6.WebBrowser.Network.QtHelpSchemeHandler.html Wed Sep 19 19:50:10 2018 +0200 @@ -138,6 +138,9 @@ <td><a href="#QtHelpSchemeReply.__init__">QtHelpSchemeReply</a></td> <td>Constructor</td> </tr><tr> +<td><a href="#QtHelpSchemeReply.__loadQtHelpPage">__loadQtHelpPage</a></td> +<td>Private method to load the requested QtHelp page.</td> +</tr><tr> <td><a href="#QtHelpSchemeReply.__mimeFromUrl">__mimeFromUrl</a></td> <td>Private method to guess the mime type given an URL.</td> </tr><tr> @@ -174,6 +177,16 @@ <dd> reference to the parent object </dd> +</dl><a NAME="QtHelpSchemeReply.__loadQtHelpPage" ID="QtHelpSchemeReply.__loadQtHelpPage"></a> +<h4>QtHelpSchemeReply.__loadQtHelpPage</h4> +<b>__loadQtHelpPage</b>(<i>url</i>) +<p> + Private method to load the requested QtHelp page. +</p><dl> +<dt><i>url</i> (QUrl)</dt> +<dd> +URL of the requested page +</dd> </dl><a NAME="QtHelpSchemeReply.__mimeFromUrl" ID="QtHelpSchemeReply.__mimeFromUrl"></a> <h4>QtHelpSchemeReply.__mimeFromUrl</h4> <b>__mimeFromUrl</b>(<i>url</i>)
--- a/WebBrowser/Network/EricSchemeHandler.py Tue Sep 18 19:23:07 2018 +0200 +++ b/WebBrowser/Network/EricSchemeHandler.py Wed Sep 19 19:50:10 2018 +0200 @@ -10,7 +10,7 @@ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSignal, QByteArray, QBuffer, QIODevice, \ - QTextStream, QUrlQuery + QUrlQuery, QMutex, QMutexLocker, QTimer from PyQt5.QtWidgets import qApp from PyQt5.QtWebEngineCore import QWebEngineUrlSchemeHandler @@ -89,13 +89,12 @@ self.__loaded = False self.__job = job + self.__mutex = QMutex() self.__pageName = self.__job.requestUrl().path() self.__buffer = QBuffer() - self.open(QIODevice.ReadOnly) - self.__buffer.open(QIODevice.ReadWrite) - self.__loadPage() + QTimer.singleShot(0, self.__loadPage) def __loadPage(self): """ @@ -104,18 +103,23 @@ if self.__loaded: return - stream = QTextStream(self.__buffer) - stream.setCodec("utf-8") - if self.__pageName == "adblock": - stream << self.__adBlockPage() + contents = self.__adBlockPage() elif self.__pageName in ["home", "start", "startpage"]: - stream << self.__startPage() + contents = self.__startPage() elif self.__pageName == "speeddial": - stream << self.__speedDialPage() + contents = self.__speedDialPage() + else: + contents = "" - stream.flush() - self.__buffer.reset() + lock = QMutexLocker(self.__mutex) + self.__buffer.setData(contents.encode("utf-8")) + self.__buffer.open(QIODevice.ReadOnly) + lock.unlock() + + self.open(QIODevice.ReadOnly) + self.readyRead.emit() + self.__loaded = True def bytesAvailable(self): @@ -125,6 +129,7 @@ @return number of available bytes @rtype int """ + lock = QMutexLocker(self.__mutex) # __IGNORE_WARNING__ return self.__buffer.bytesAvailable() def readData(self, maxlen): @@ -134,6 +139,7 @@ @param maxlen maximum number of bytes to read (integer) @return string containing the data (bytes) """ + lock = QMutexLocker(self.__mutex) # __IGNORE_WARNING__ return self.__buffer.read(maxlen) def close(self):
--- a/WebBrowser/Network/QtHelpSchemeHandler.py Tue Sep 18 19:23:07 2018 +0200 +++ b/WebBrowser/Network/QtHelpSchemeHandler.py Wed Sep 19 19:50:10 2018 +0200 @@ -12,7 +12,8 @@ import mimetypes import os -from PyQt5.QtCore import pyqtSignal, QByteArray, QIODevice, QBuffer +from PyQt5.QtCore import pyqtSignal, QByteArray, QIODevice, QBuffer, QTimer, \ + QMutex, QMutexLocker from PyQt5.QtWebEngineCore import QWebEngineUrlSchemeHandler, \ QWebEngineUrlRequestJob @@ -118,19 +119,24 @@ """ super(QtHelpSchemeReply, self).__init__(parent) - url = job.requestUrl() - strUrl = url.toString() + self.__job = job + self.__engine = engine + self.__mutex = QMutex() self.__buffer = QBuffer() + # determine mimetype + url = self.__job.requestUrl() + strUrl = url.toString() + # For some reason the url to load maybe wrong (passed from web engine) # though the css file and the references inside should work that way. # One possible problem might be that the css is loaded at the same # level as the html, thus a path inside the css like # (../images/foo.png) might cd out of the virtual folder - if not engine.findFile(url).isValid(): + if not self.__engine.findFile(url).isValid(): if strUrl.startswith(QtDocPath): - newUrl = job.requestUrl() + newUrl = self.__job.requestUrl() if not newUrl.path().startswith("/qdoc/"): newUrl.setPath("/qdoc" + newUrl.path()) url = newUrl @@ -141,8 +147,18 @@ # do our own (limited) guessing self.__mimeType = self.__mimeFromUrl(url) - if engine.findFile(url).isValid(): - data = engine.fileData(url) + QTimer.singleShot(0, lambda: self.__loadQtHelpPage(url)) + + def __loadQtHelpPage(self, url): + """ + Private method to load the requested QtHelp page. + + @param url URL of the requested page + @type QUrl + """ + + if self.__engine.findFile(url).isValid(): + data = self.__engine.fileData(url) else: data = QByteArray(self.tr( """<html>""" @@ -150,12 +166,16 @@ """<body><div align="center"><br><br>""" """<h1>The page could not be found</h1><br>""" """<h3>'{0}'</h3></div></body>""" - """</html>""").format(strUrl) + """</html>""").format(url.toString()) .encode("utf-8")) + lock = QMutexLocker(self.__mutex) self.__buffer.setData(data) self.__buffer.open(QIODevice.ReadOnly) + lock.unlock() + self.open(QIODevice.ReadOnly) + self.readyRead.emit() def bytesAvailable(self): """ @@ -164,6 +184,7 @@ @return number of available bytes @rtype int """ + lock = QMutexLocker(self.__mutex) # __IGNORE_WARNING__ return self.__buffer.bytesAvailable() def readData(self, maxlen): @@ -173,6 +194,7 @@ @param maxlen maximum number of bytes to read (integer) @return string containing the data (bytes) """ + lock = QMutexLocker(self.__mutex) # __IGNORE_WARNING__ return self.__buffer.read(maxlen) def close(self):