8 Module implementing the web browser using QWebEngineView. |
8 Module implementing the web browser using QWebEngineView. |
9 """ |
9 """ |
10 |
10 |
11 import os |
11 import os |
12 import functools |
12 import functools |
|
13 import contextlib |
13 |
14 |
14 from PyQt5.QtCore import ( |
15 from PyQt5.QtCore import ( |
15 pyqtSignal, pyqtSlot, Qt, QUrl, QFileInfo, QTimer, QEvent, QPoint, |
16 pyqtSignal, pyqtSlot, Qt, QUrl, QFileInfo, QTimer, QEvent, QPoint, |
16 QPointF, QDateTime, QStandardPaths, QByteArray, QIODevice, QDataStream |
17 QPointF, QDateTime, QStandardPaths, QByteArray, QIODevice, QDataStream |
17 ) |
18 ) |
82 |
83 |
83 @param mainWindow reference to the main window (WebBrowserWindow) |
84 @param mainWindow reference to the main window (WebBrowserWindow) |
84 @param parent parent widget of this window (QWidget) |
85 @param parent parent widget of this window (QWidget) |
85 @param name name of this window (string) |
86 @param name name of this window (string) |
86 """ |
87 """ |
87 super(WebBrowserView, self).__init__(parent) |
88 super().__init__(parent) |
88 self.setObjectName(name) |
89 self.setObjectName(name) |
89 |
90 |
90 self.__rwhvqt = None |
91 self.__rwhvqt = None |
91 self.installEventFilter(self) |
92 self.installEventFilter(self) |
92 |
93 |
147 self.setPage(self.__page) |
148 self.setPage(self.__page) |
148 |
149 |
149 self.__page.safeBrowsingAbort.connect(self.safeBrowsingAbort) |
150 self.__page.safeBrowsingAbort.connect(self.safeBrowsingAbort) |
150 self.__page.safeBrowsingBad.connect(self.safeBrowsingBad) |
151 self.__page.safeBrowsingBad.connect(self.safeBrowsingBad) |
151 self.__page.printPageRequested.connect(self.__printPage) |
152 self.__page.printPageRequested.connect(self.__printPage) |
152 try: |
153 self.__page.quotaRequested.connect(self.__quotaRequested) |
153 self.__page.quotaRequested.connect(self.__quotaRequested) |
154 # The registerProtocolHandlerRequested signal is handled in |
154 # The registerProtocolHandlerRequested signal is handled in |
155 # WebBrowserPage. |
155 # WebBrowserPage. |
156 self.__page.selectClientCertificate.connect( |
156 except AttributeError: |
157 self.__selectClientCertificate) |
157 # pre Qt 5.11 |
158 with contextlib.suppress(AttributeError, ImportError): |
158 pass |
159 #- Qt >= 5.14 |
159 try: |
|
160 self.__page.selectClientCertificate.connect( |
|
161 self.__selectClientCertificate) |
|
162 except AttributeError: |
|
163 # pre Qt 5.12 |
|
164 pass |
|
165 try: |
|
166 from PyQt5.QtWebEngineCore import QWebEngineFindTextResult |
160 from PyQt5.QtWebEngineCore import QWebEngineFindTextResult |
167 # __IGNORE_WARNING__ |
161 # __IGNORE_WARNING__ |
168 |
162 |
169 self.__page.findTextFinished.connect( |
163 self.__page.findTextFinished.connect( |
170 self.__findTextFinished) |
164 self.__findTextFinished) |
171 except (AttributeError, ImportError): |
|
172 # pre Qt 5.14 |
|
173 pass |
|
174 |
165 |
175 def __setRwhvqt(self): |
166 def __setRwhvqt(self): |
176 """ |
167 """ |
177 Private slot to set widget that receives input events. |
168 Private slot to set widget that receives input events. |
178 """ |
169 """ |
222 not self.__page.acceptNavigationRequest( |
213 not self.__page.acceptNavigationRequest( |
223 url, QWebEnginePage.NavigationType.NavigationTypeTyped, True) |
214 url, QWebEnginePage.NavigationType.NavigationTypeTyped, True) |
224 ): |
215 ): |
225 return |
216 return |
226 |
217 |
227 super(WebBrowserView, self).load(url) |
218 super().load(url) |
228 |
219 |
229 if not self.__firstLoad: |
220 if not self.__firstLoad: |
230 self.__firstLoad = True |
221 self.__firstLoad = True |
231 WebInspector.pushView(self) |
222 WebInspector.pushView(self) |
232 |
223 |
1262 |
1253 |
1263 if not searchText: |
1254 if not searchText: |
1264 return |
1255 return |
1265 |
1256 |
1266 engineName = act.data() |
1257 engineName = act.data() |
1267 if engineName: |
1258 engine = ( |
1268 engine = self.__mw.openSearchManager().engine(engineName) |
1259 self.__mw.openSearchManager().engine(engineName) |
1269 else: |
1260 if engineName else |
1270 engine = self.__mw.openSearchManager().currentEngine() |
1261 self.__mw.openSearchManager().currentEngine() |
|
1262 ) |
1271 if engine: |
1263 if engine: |
1272 self.search.emit(engine.searchUrl(searchText)) |
1264 self.search.emit(engine.searchUrl(searchText)) |
1273 |
1265 |
1274 def __addSearchEngine(self): |
1266 def __addSearchEngine(self): |
1275 """ |
1267 """ |
1360 url = QUrl(evt.mimeData().text()) |
1352 url = QUrl(evt.mimeData().text()) |
1361 if url.isValid(): |
1353 if url.isValid(): |
1362 evt.acceptProposedAction() |
1354 evt.acceptProposedAction() |
1363 |
1355 |
1364 if not evt.isAccepted(): |
1356 if not evt.isAccepted(): |
1365 super(WebBrowserView, self).dragMoveEvent(evt) |
1357 super().dragMoveEvent(evt) |
1366 |
1358 |
1367 def dropEvent(self, evt): |
1359 def dropEvent(self, evt): |
1368 """ |
1360 """ |
1369 Protected method called by a drop event. |
1361 Protected method called by a drop event. |
1370 |
1362 |
1371 @param evt reference to the drop event (QDropEvent) |
1363 @param evt reference to the drop event (QDropEvent) |
1372 """ |
1364 """ |
1373 super(WebBrowserView, self).dropEvent(evt) |
1365 super().dropEvent(evt) |
1374 if ( |
1366 if ( |
1375 not evt.isAccepted() and |
1367 not evt.isAccepted() and |
1376 evt.source() != self and |
1368 evt.source() != self and |
1377 evt.possibleActions() & Qt.DropAction.CopyAction |
1369 evt.possibleActions() & Qt.DropAction.CopyAction |
1378 ): |
1370 ): |
1519 """ |
1511 """ |
1520 Protected method called by a key release. |
1512 Protected method called by a key release. |
1521 |
1513 |
1522 @param evt reference to the key event (QKeyEvent) |
1514 @param evt reference to the key event (QKeyEvent) |
1523 """ |
1515 """ |
1524 if evt.key() == Qt.Key.Key_Escape: |
1516 if evt.key() == Qt.Key.Key_Escape and self.isFullScreen(): |
1525 if self.isFullScreen(): |
1517 self.triggerPageAction(QWebEnginePage.WebAction.ExitFullScreen) |
1526 self.triggerPageAction(QWebEnginePage.WebAction.ExitFullScreen) |
1518 evt.accept() |
1527 evt.accept() |
1519 self.requestFullScreen(False) |
1528 self.requestFullScreen(False) |
|
1529 |
1520 |
1530 def _gestureEvent(self, evt): |
1521 def _gestureEvent(self, evt): |
1531 """ |
1522 """ |
1532 Protected method handling gesture events. |
1523 Protected method handling gesture events. |
1533 |
1524 |
1618 QEvent.Type.MouseMove, |
1609 QEvent.Type.MouseMove, |
1619 QEvent.Type.Wheel, |
1610 QEvent.Type.Wheel, |
1620 QEvent.Type.Gesture]: |
1611 QEvent.Type.Gesture]: |
1621 return True |
1612 return True |
1622 |
1613 |
1623 elif evt.type() == QEvent.Type.Hide: |
1614 elif evt.type() == QEvent.Type.Hide and self.isFullScreen(): |
1624 if self.isFullScreen(): |
1615 self.triggerPageAction(QWebEnginePage.WebAction.ExitFullScreen) |
1625 self.triggerPageAction( |
1616 |
1626 QWebEnginePage.WebAction.ExitFullScreen) |
1617 return super().eventFilter(obj, evt) |
1627 |
|
1628 return super(WebBrowserView, self).eventFilter(obj, evt) |
|
1629 |
1618 |
1630 def event(self, evt): |
1619 def event(self, evt): |
1631 """ |
1620 """ |
1632 Public method handling events. |
1621 Public method handling events. |
1633 |
1622 |
1636 """ |
1625 """ |
1637 if evt.type() == QEvent.Type.Gesture: |
1626 if evt.type() == QEvent.Type.Gesture: |
1638 self._gestureEvent(evt) |
1627 self._gestureEvent(evt) |
1639 return True |
1628 return True |
1640 |
1629 |
1641 return super(WebBrowserView, self).event(evt) |
1630 return super().event(evt) |
1642 |
1631 |
1643 def inputWidget(self): |
1632 def inputWidget(self): |
1644 """ |
1633 """ |
1645 Public method to get a reference to the render widget. |
1634 Public method to get a reference to the render widget. |
1646 |
1635 |
1681 self.__siteIcon = QIcon() |
1670 self.__siteIcon = QIcon() |
1682 if self.__siteIconLoader is not None: |
1671 if self.__siteIconLoader is not None: |
1683 self.__siteIconLoader.deleteLater() |
1672 self.__siteIconLoader.deleteLater() |
1684 self.__siteIconLoader = WebIconLoader(url, self) |
1673 self.__siteIconLoader = WebIconLoader(url, self) |
1685 self.__siteIconLoader.iconLoaded.connect(self.__iconLoaded) |
1674 self.__siteIconLoader.iconLoaded.connect(self.__iconLoaded) |
1686 try: |
1675 with contextlib.suppress(AttributeError): |
1687 self.__siteIconLoader.sslConfiguration.connect( |
1676 self.__siteIconLoader.sslConfiguration.connect( |
1688 self.page().setSslConfiguration) |
1677 self.page().setSslConfiguration) |
1689 self.__siteIconLoader.clearSslConfiguration.connect( |
1678 self.__siteIconLoader.clearSslConfiguration.connect( |
1690 self.page().clearSslConfiguration) |
1679 self.page().clearSslConfiguration) |
1691 except AttributeError: |
|
1692 # no SSL available |
|
1693 pass |
|
1694 |
1680 |
1695 def __iconLoaded(self, icon): |
1681 def __iconLoaded(self, icon): |
1696 """ |
1682 """ |
1697 Private slot handling the loaded web site icon. |
1683 Private slot handling the loaded web site icon. |
1698 |
1684 |
2141 Protected method to handle show events. |
2127 Protected method to handle show events. |
2142 |
2128 |
2143 @param evt reference to the show event object |
2129 @param evt reference to the show event object |
2144 @type QShowEvent |
2130 @type QShowEvent |
2145 """ |
2131 """ |
2146 super(WebBrowserView, self).showEvent(evt) |
2132 super().showEvent(evt) |
2147 self.activateSession() |
2133 self.activateSession() |
2148 |
2134 |
2149 def activateSession(self): |
2135 def activateSession(self): |
2150 """ |
2136 """ |
2151 Public slot to activate a restored session. |
2137 Public slot to activate a restored session. |
2241 generated by getSessionData() |
2227 generated by getSessionData() |
2242 @type dict |
2228 @type dict |
2243 @return tuple containing the title, URL and web icon |
2229 @return tuple containing the title, URL and web icon |
2244 @rtype tuple of (str, str, QIcon) |
2230 @rtype tuple of (str, str, QIcon) |
2245 """ |
2231 """ |
2246 if "Title" in sessionData: |
2232 title = sessionData.get("Title", "") |
2247 title = sessionData["Title"] |
2233 urlStr = sessionData.get("Url", "") |
2248 else: |
|
2249 title = "" |
|
2250 |
|
2251 if "Url" in sessionData: |
|
2252 urlStr = sessionData["Url"] |
|
2253 else: |
|
2254 urlStr = "" |
|
2255 |
2234 |
2256 if "Icon" in sessionData: |
2235 if "Icon" in sessionData: |
2257 iconArray = QByteArray.fromBase64( |
2236 iconArray = QByteArray.fromBase64( |
2258 sessionData["Icon"].encode("ascii")) |
2237 sessionData["Icon"].encode("ascii")) |
2259 stream = QDataStream(iconArray, QIODevice.OpenModeFlag.ReadOnly) |
2238 stream = QDataStream(iconArray, QIODevice.OpenModeFlag.ReadOnly) |