15 pass |
15 pass |
16 |
16 |
17 import os |
17 import os |
18 |
18 |
19 from PyQt5.QtCore import pyqtSignal, QUrl, QFileInfo, Qt, QTimer, QEvent, \ |
19 from PyQt5.QtCore import pyqtSignal, QUrl, QFileInfo, Qt, QTimer, QEvent, \ |
20 QPoint, QDateTime, qVersion |
20 QPoint, QDateTime, qVersion, QStandardPaths |
21 from PyQt5.QtGui import QDesktopServices, QClipboard, QIcon, \ |
21 from PyQt5.QtGui import QDesktopServices, QClipboard, QIcon, \ |
22 QContextMenuEvent, QPixmap |
22 QContextMenuEvent, QPixmap |
23 from PyQt5.QtWidgets import qApp, QStyle, QMenu, QApplication |
23 from PyQt5.QtWidgets import qApp, QStyle, QMenu, QApplication |
24 from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage |
24 from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage, \ |
|
25 QWebEngineDownloadItem |
25 |
26 |
26 from E5Gui import E5MessageBox |
27 from E5Gui import E5MessageBox, E5FileDialog |
27 |
28 |
28 from WebBrowser.WebBrowserWindow import WebBrowserWindow |
29 from WebBrowser.WebBrowserWindow import WebBrowserWindow |
29 from .WebBrowserPage import WebBrowserPage |
30 from .WebBrowserPage import WebBrowserPage |
30 |
31 |
31 from .Tools.WebIconLoader import WebIconLoader |
32 from .Tools.WebIconLoader import WebIconLoader |
501 @type QMenu |
502 @type QMenu |
502 @param hitTest reference to the hit test object |
503 @param hitTest reference to the hit test object |
503 @type WebHitTestResult |
504 @type WebHitTestResult |
504 """ |
505 """ |
505 # TODO: Qt 5.8 - add support for spell checking |
506 # TODO: Qt 5.8 - add support for spell checking |
|
507 spellCheckActionCount = 0 |
|
508 if qVersion() >= "5.7.0": |
|
509 contextMenuData = self.page().contextMenuData() |
|
510 hitTest.updateWithContextMenuData(contextMenuData) |
|
511 |
|
512 if qVersion() >= "5.8.0" and \ |
|
513 bool(contextMenuData.misspelledWord()): |
|
514 boldFont = menu.font() |
|
515 boldFont.setBold(True) |
|
516 |
|
517 for suggestion in contextMenuData.spellCheckerSuggestions(): |
|
518 act = menu.addAction( |
|
519 suggestion, |
|
520 lambda: self.page().replaceMisspelledWord(suggestion)) |
|
521 act.setFont(boldFont) |
|
522 |
|
523 if bool(menu.actions()): |
|
524 menu.addAction(self.tr("No suggestions")).setEnabled(False) |
|
525 |
|
526 menu.addSeparator() |
|
527 spellCheckActionCount = len(menu.actions()) |
|
528 |
506 if not hitTest.linkUrl().isEmpty() and \ |
529 if not hitTest.linkUrl().isEmpty() and \ |
507 hitTest.linkUrl().scheme() != "javascript": |
530 hitTest.linkUrl().scheme() != "javascript": |
508 self.__createLinkContextMenu(menu, hitTest) |
531 self.__createLinkContextMenu(menu, hitTest) |
509 |
532 |
510 if not hitTest.imageUrl().isEmpty(): |
533 if not hitTest.imageUrl().isEmpty(): |
512 |
535 |
513 if not hitTest.mediaUrl().isEmpty(): |
536 if not hitTest.mediaUrl().isEmpty(): |
514 self.__createMediaContextMenu(menu, hitTest) |
537 self.__createMediaContextMenu(menu, hitTest) |
515 |
538 |
516 if hitTest.isContentEditable(): |
539 if hitTest.isContentEditable(): |
517 menu.addAction(self.__mw.undoAct) |
540 # check, if only spell checker actions were added |
518 menu.addAction(self.__mw.redoAct) |
541 if len(menu.actions()) == spellCheckActionCount: |
519 menu.addSeparator() |
542 menu.addAction(self.__mw.undoAct) |
520 menu.addAction(self.__mw.cutAct) |
543 menu.addAction(self.__mw.redoAct) |
521 menu.addAction(self.__mw.copyAct) |
544 menu.addSeparator() |
522 menu.addAction(self.__mw.pasteAct) |
545 menu.addAction(self.__mw.cutAct) |
523 menu.addSeparator() |
546 menu.addAction(self.__mw.copyAct) |
524 self.__mw.personalInformationManager().createSubMenu( |
547 menu.addAction(self.__mw.pasteAct) |
525 menu, self, hitTest) |
548 menu.addSeparator() |
|
549 self.__mw.personalInformationManager().createSubMenu( |
|
550 menu, self, hitTest) |
526 |
551 |
527 if hitTest.tagName() == "input": |
552 if hitTest.tagName() == "input": |
528 menu.addSeparator() |
553 menu.addSeparator() |
529 act = menu.addAction("") |
554 act = menu.addAction("") |
530 act.setVisible(False) |
555 act.setVisible(False) |
1338 @return flag indicating that the event should be filtered out |
1363 @return flag indicating that the event should be filtered out |
1339 @rtype bool |
1364 @rtype bool |
1340 """ |
1365 """ |
1341 # find the render widget receiving events for the web page |
1366 # find the render widget receiving events for the web page |
1342 if obj is self and evt.type() == QEvent.ChildAdded: |
1367 if obj is self and evt.type() == QEvent.ChildAdded: |
1343 # TODO: Qt 5.8 - check, if this still works on 5.8 (see Qupzilla) |
|
1344 child = evt.child() |
1368 child = evt.child() |
1345 if child and child.inherits( |
1369 if child and child.inherits( |
1346 "QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget"): |
1370 "QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget"): |
1347 self.__rwhvqt = child |
1371 self.__rwhvqt = child |
1348 self.grabGesture(Qt.PinchGesture) |
1372 self.grabGesture(Qt.PinchGesture) |
1613 """ |
1637 """ |
1614 url = self.url() |
1638 url = self.url() |
1615 if url.isEmpty(): |
1639 if url.isEmpty(): |
1616 return |
1640 return |
1617 |
1641 |
1618 # TODO: Qt 5.8 - use QWebEnginePage.save() |
1642 if qVersion() >= "5.8.0": |
1619 self.triggerPageAction(QWebEnginePage.SavePage) |
1643 # since Qt 5.8.0 |
|
1644 fileName, savePageFormat = self.__getSavePageFileNameAndFormat() |
|
1645 if fileName: |
|
1646 self.page().save(fileName, savePageFormat) |
|
1647 else: |
|
1648 self.triggerPageAction(QWebEnginePage.SavePage) |
|
1649 |
|
1650 def __getSavePageFileNameAndFormat(self): |
|
1651 """ |
|
1652 Private method to get the file name to save the page to. |
|
1653 |
|
1654 @return tuple containing the file name to save to and the |
|
1655 save page format |
|
1656 @rtype tuple of (str, QWebEngineDownloadItem.SavePageFormat) |
|
1657 """ |
|
1658 documentLocation = QStandardPaths.writableLocation( |
|
1659 QStandardPaths.DocumentsLocation) |
|
1660 filterList = [ |
|
1661 self.tr("Web Archive (*.mhtml *.mht)"), |
|
1662 self.tr("HTML File (*.html *.htm)"), |
|
1663 self.tr("HTML File with all resources (*.html *.htm)"), |
|
1664 ] |
|
1665 extensionsList = [ |
|
1666 # tuple of extensions for *nix and Windows |
|
1667 # keep in sync with filters list |
|
1668 (".mhtml", ".mht"), |
|
1669 (".html", ".htm"), |
|
1670 (".html", ".htm"), |
|
1671 ] |
|
1672 if self.url().fileName(): |
|
1673 defaultFileName = os.path.join(documentLocation, |
|
1674 self.url().fileName()) |
|
1675 else: |
|
1676 defaultFileName = os.path.join(documentLocation, |
|
1677 self.page().title()) |
|
1678 if Utilities.isWindowsPlatform(): |
|
1679 defaultFileName += ".mht" |
|
1680 else: |
|
1681 defaultFileName += ".mhtml" |
|
1682 |
|
1683 fileName = "" |
|
1684 saveFormat = QWebEngineDownloadItem.MimeHtmlSaveFormat |
|
1685 |
|
1686 fileName, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( |
|
1687 None, |
|
1688 self.tr("Save Web Page"), |
|
1689 defaultFileName, |
|
1690 ";;".join(filterList), |
|
1691 None) |
|
1692 if fileName: |
|
1693 index = filterList.index(selectedFilter) |
|
1694 if index == 0: |
|
1695 saveFormat = QWebEngineDownloadItem.MimeHtmlSaveFormat |
|
1696 elif index == 1: |
|
1697 saveFormat = QWebEngineDownloadItem.SingleHtmlSaveFormat |
|
1698 else: |
|
1699 saveFormat = QWebEngineDownloadItem.CompleteHtmlSaveFormat |
|
1700 |
|
1701 extension = os.path.splitext(fileName)[1] |
|
1702 if not extension: |
|
1703 # add the platform specific default extension |
|
1704 if Utilities.isWindowsPlatform(): |
|
1705 extensionsIndex = 1 |
|
1706 else: |
|
1707 extensionsIndex = 0 |
|
1708 extensions = extensionsList[index] |
|
1709 fileName += extensions[extensionsIndex] |
|
1710 |
|
1711 return fileName, saveFormat |
1620 |
1712 |
1621 ########################################################################### |
1713 ########################################################################### |
1622 ## Miscellaneous methods below |
1714 ## Miscellaneous methods below |
1623 ########################################################################### |
1715 ########################################################################### |
1624 |
1716 |