9 |
9 |
10 import os |
10 import os |
11 import shutil |
11 import shutil |
12 import sys |
12 import sys |
13 import functools |
13 import functools |
|
14 import contextlib |
14 |
15 |
15 from PyQt5.QtCore import ( |
16 from PyQt5.QtCore import ( |
16 pyqtSlot, pyqtSignal, Qt, QByteArray, QSize, QTimer, QUrl, QProcess, |
17 pyqtSlot, pyqtSignal, Qt, QByteArray, QSize, QTimer, QUrl, QProcess, |
17 QEvent, QFileInfo |
18 QEvent, QFileInfo |
18 ) |
19 ) |
138 @param saname name to be used for the single application server |
139 @param saname name to be used for the single application server |
139 @type str |
140 @type str |
140 """ |
141 """ |
141 self.__hideNavigationTimer = None |
142 self.__hideNavigationTimer = None |
142 |
143 |
143 super(WebBrowserWindow, self).__init__(parent) |
144 super().__init__(parent) |
144 self.setObjectName(name) |
145 self.setObjectName(name) |
145 if private: |
146 if private: |
146 self.setWindowTitle(self.tr("eric Web Browser (Private Mode)")) |
147 self.setWindowTitle(self.tr("eric Web Browser (Private Mode)")) |
147 else: |
148 else: |
148 self.setWindowTitle(self.tr("eric Web Browser")) |
149 self.setWindowTitle(self.tr("eric Web Browser")) |
293 Qt.DockWidgetArea.TopDockWidgetArea) |
294 Qt.DockWidgetArea.TopDockWidgetArea) |
294 self.__javascriptConsoleDock.setWidget(self.__javascriptConsole) |
295 self.__javascriptConsoleDock.setWidget(self.__javascriptConsole) |
295 self.addDockWidget(Qt.DockWidgetArea.BottomDockWidgetArea, |
296 self.addDockWidget(Qt.DockWidgetArea.BottomDockWidgetArea, |
296 self.__javascriptConsoleDock) |
297 self.__javascriptConsoleDock) |
297 |
298 |
298 if Preferences.getWebBrowser("SaveGeometry"): |
299 g = ( |
299 g = Preferences.getGeometry("WebBrowserGeometry") |
300 Preferences.getGeometry("WebBrowserGeometry") |
300 else: |
301 if Preferences.getWebBrowser("SaveGeometry") else |
301 g = QByteArray() |
302 QByteArray() |
|
303 ) |
302 if g.isEmpty(): |
304 if g.isEmpty(): |
303 s = QSize(800, 800) |
305 s = QSize(800, 800) |
304 self.resize(s) |
306 self.resize(s) |
305 else: |
307 else: |
306 self.restoreGeometry(g) |
308 self.restoreGeometry(g) |
644 settings.setAttribute( |
646 settings.setAttribute( |
645 QWebEngineSettings.WebAttribute.DnsPrefetchEnabled, |
647 QWebEngineSettings.WebAttribute.DnsPrefetchEnabled, |
646 Preferences.getWebBrowser( |
648 Preferences.getWebBrowser( |
647 "DnsPrefetchEnabled")) |
649 "DnsPrefetchEnabled")) |
648 |
650 |
649 try: |
651 with contextlib.suppress(AttributeError, KeyError): |
650 # Qt 5.13 |
652 # Qt 5.13 |
651 settings.setAttribute( |
653 settings.setAttribute( |
652 QWebEngineSettings.WebAttribute.PdfViewerEnabled, |
654 QWebEngineSettings.WebAttribute.PdfViewerEnabled, |
653 Preferences.getWebBrowser( |
655 Preferences.getWebBrowser( |
654 "PdfViewerEnabled")) |
656 "PdfViewerEnabled")) |
655 except (AttributeError, KeyError): |
|
656 pass |
|
657 |
657 |
658 def __initActions(self): |
658 def __initActions(self): |
659 """ |
659 """ |
660 Private method to define the user interface actions. |
660 Private method to define the user interface actions. |
661 """ |
661 """ |
2758 """ |
2758 """ |
2759 Private method to shut down a web browser window. |
2759 Private method to shut down a web browser window. |
2760 |
2760 |
2761 @return flag indicating successful shutdown (boolean) |
2761 @return flag indicating successful shutdown (boolean) |
2762 """ |
2762 """ |
2763 if not WebBrowserWindow._performingShutdown and not self.__forcedClose: |
2763 if ( |
2764 if not self.__tabWidget.shallShutDown(): |
2764 not WebBrowserWindow._performingShutdown and |
2765 return False |
2765 not self.__forcedClose and |
|
2766 not self.__tabWidget.shallShutDown() |
|
2767 ): |
|
2768 return False |
2766 |
2769 |
2767 self.__isClosing = True |
2770 self.__isClosing = True |
2768 |
2771 |
2769 if ( |
2772 if ( |
2770 not WebBrowserWindow._performingShutdown and |
2773 not WebBrowserWindow._performingShutdown and |
2800 Preferences.setGeometry("WebBrowserGeometry", |
2803 Preferences.setGeometry("WebBrowserGeometry", |
2801 self.saveGeometry()) |
2804 self.saveGeometry()) |
2802 else: |
2805 else: |
2803 Preferences.setGeometry("WebBrowserGeometry", QByteArray()) |
2806 Preferences.setGeometry("WebBrowserGeometry", QByteArray()) |
2804 |
2807 |
2805 try: |
2808 with contextlib.suppress(ValueError): |
2806 browserIndex = WebBrowserWindow.BrowserWindows.index(self) |
2809 browserIndex = WebBrowserWindow.BrowserWindows.index(self) |
2807 if len(WebBrowserWindow.BrowserWindows): |
2810 if len(WebBrowserWindow.BrowserWindows) and browserIndex == 0: |
2808 if browserIndex == 0: |
2811 if len(WebBrowserWindow.BrowserWindows) > 1: |
2809 if len(WebBrowserWindow.BrowserWindows) > 1: |
2812 # first window will be deleted |
2810 # first window will be deleted |
2813 QDesktopServices.setUrlHandler( |
2811 QDesktopServices.setUrlHandler( |
2814 "http", |
2812 "http", |
2815 WebBrowserWindow.BrowserWindows[1].urlHandler) |
2813 WebBrowserWindow.BrowserWindows[1].urlHandler) |
2816 QDesktopServices.setUrlHandler( |
2814 QDesktopServices.setUrlHandler( |
2817 "https", |
2815 "https", |
2818 WebBrowserWindow.BrowserWindows[1].urlHandler) |
2816 WebBrowserWindow.BrowserWindows[1].urlHandler) |
2819 else: |
2817 else: |
2820 QDesktopServices.unsetUrlHandler("http") |
2818 QDesktopServices.unsetUrlHandler("http") |
2821 QDesktopServices.unsetUrlHandler("https") |
2819 QDesktopServices.unsetUrlHandler("https") |
|
2820 if len(WebBrowserWindow.BrowserWindows) > 0: |
2822 if len(WebBrowserWindow.BrowserWindows) > 0: |
2821 del WebBrowserWindow.BrowserWindows[browserIndex] |
2823 del WebBrowserWindow.BrowserWindows[browserIndex] |
2822 except ValueError: |
|
2823 pass |
|
2824 |
2824 |
2825 Preferences.syncPreferences() |
2825 Preferences.syncPreferences() |
2826 if ( |
2826 if ( |
2827 not WebBrowserWindow._performingShutdown and |
2827 not WebBrowserWindow._performingShutdown and |
2828 len(WebBrowserWindow.BrowserWindows) == 0 |
2828 len(WebBrowserWindow.BrowserWindows) == 0 |
3159 |
3159 |
3160 def __showPreferences(self): |
3160 def __showPreferences(self): |
3161 """ |
3161 """ |
3162 Private slot to set the preferences. |
3162 Private slot to set the preferences. |
3163 """ |
3163 """ |
3164 from Preferences.ConfigurationDialog import ConfigurationDialog |
3164 from Preferences.ConfigurationDialog import ( |
|
3165 ConfigurationDialog, ConfigurationMode |
|
3166 ) |
3165 dlg = ConfigurationDialog( |
3167 dlg = ConfigurationDialog( |
3166 self, 'Configuration', True, fromEric=False, |
3168 self, 'Configuration', True, fromEric=False, |
3167 displayMode=ConfigurationDialog.WebBrowserMode) |
3169 displayMode=ConfigurationMode.WEBBROWSERMODE) |
3168 dlg.preferencesChanged.connect(self.preferencesChanged) |
3170 dlg.preferencesChanged.connect(self.preferencesChanged) |
3169 dlg.masterPasswordChanged.connect( |
3171 dlg.masterPasswordChanged.connect( |
3170 lambda old, new: self.masterPasswordChanged(old, new, local=True)) |
3172 lambda old, new: self.masterPasswordChanged(old, new, local=True)) |
3171 dlg.show() |
3173 dlg.show() |
3172 if self.__lastConfigurationPageName: |
3174 if self.__lastConfigurationPageName: |
3210 else: |
3212 else: |
3211 profile.setHttpCacheType( |
3213 profile.setHttpCacheType( |
3212 QWebEngineProfile.HttpCacheType.MemoryHttpCache) |
3214 QWebEngineProfile.HttpCacheType.MemoryHttpCache) |
3213 profile.setHttpCacheMaximumSize(0) |
3215 profile.setHttpCacheMaximumSize(0) |
3214 |
3216 |
3215 try: |
3217 with contextlib.suppress(AttributeError): |
3216 profile.setSpellCheckEnabled( |
3218 profile.setSpellCheckEnabled( |
3217 Preferences.getWebBrowser("SpellCheckEnabled")) |
3219 Preferences.getWebBrowser("SpellCheckEnabled")) |
3218 profile.setSpellCheckLanguages( |
3220 profile.setSpellCheckLanguages( |
3219 Preferences.getWebBrowser("SpellCheckLanguages")) |
3221 Preferences.getWebBrowser("SpellCheckLanguages")) |
3220 except AttributeError: |
|
3221 # not yet supported |
|
3222 pass |
|
3223 |
3222 |
3224 self.__virusTotal.preferencesChanged() |
3223 self.__virusTotal.preferencesChanged() |
3225 if ( |
3224 if ( |
3226 not Preferences.getWebBrowser("VirusTotalEnabled") or |
3225 not Preferences.getWebBrowser("VirusTotalEnabled") or |
3227 Preferences.getWebBrowser("VirusTotalServiceKey") == "" |
3226 Preferences.getWebBrowser("VirusTotalServiceKey") == "" |
4081 @param parentMenu reference to the parent menu |
4080 @param parentMenu reference to the parent menu |
4082 @type QMenu |
4081 @type QMenu |
4083 @param name name for the action |
4082 @param name name for the action |
4084 @type str |
4083 @type str |
4085 """ |
4084 """ |
4086 if name: |
4085 act = QAction(name, parentMenu) if name else QAction(codec, parentMenu) |
4087 act = QAction(name, parentMenu) |
|
4088 else: |
|
4089 act = QAction(codec, parentMenu) |
|
4090 act.setData(codec) |
4086 act.setData(codec) |
4091 act.setCheckable(True) |
4087 act.setCheckable(True) |
4092 if defaultCodec == codec: |
4088 if defaultCodec == codec: |
4093 act.setChecked(True) |
4089 act.setChecked(True) |
4094 |
4090 |
4356 QWebEnginePage.WebAction.Back) |
4353 QWebEnginePage.WebAction.Back) |
4357 elif evt.button() == Qt.MouseButton.XButton2: |
4354 elif evt.button() == Qt.MouseButton.XButton2: |
4358 self.currentBrowser().triggerPageAction( |
4355 self.currentBrowser().triggerPageAction( |
4359 QWebEnginePage.WebAction.Forward) |
4356 QWebEnginePage.WebAction.Forward) |
4360 else: |
4357 else: |
4361 super(WebBrowserWindow, self).mousePressEvent(evt) |
4358 super().mousePressEvent(evt) |
4362 |
4359 |
4363 @classmethod |
4360 @classmethod |
4364 def feedsManager(cls): |
4361 def feedsManager(cls): |
4365 """ |
4362 """ |
4366 Class method to get a reference to the RSS feeds manager. |
4363 Class method to get a reference to the RSS feeds manager. |
4508 url = self.speedDial().urlForShortcut(number - 1) |
4505 url = self.speedDial().urlForShortcut(number - 1) |
4509 if url.isValid(): |
4506 if url.isValid(): |
4510 self.__linkActivated(url) |
4507 self.__linkActivated(url) |
4511 return |
4508 return |
4512 |
4509 |
4513 super(WebBrowserWindow, self).keyPressEvent(evt) |
4510 super().keyPressEvent(evt) |
4514 |
4511 |
4515 def event(self, evt): |
4512 def event(self, evt): |
4516 """ |
4513 """ |
4517 Public method handling events. |
4514 Public method handling events. |
4518 |
4515 |
4557 self.__navigationContainer.show() |
4554 self.__navigationContainer.show() |
4558 |
4555 |
4559 if self.__hideNavigationTimer: |
4556 if self.__hideNavigationTimer: |
4560 self.__hideNavigationTimer.stop() |
4557 self.__hideNavigationTimer.stop() |
4561 |
4558 |
4562 return super(WebBrowserWindow, self).event(evt) |
4559 return super().event(evt) |
4563 |
4560 |
4564 ########################################################################### |
4561 ########################################################################### |
4565 ## Interface to VirusTotal below ## |
4562 ## Interface to VirusTotal below ## |
4566 ########################################################################### |
4563 ########################################################################### |
4567 |
4564 |
4688 ## Support for desktop notifications below |
4685 ## Support for desktop notifications below |
4689 ########################################## |
4686 ########################################## |
4690 |
4687 |
4691 @classmethod |
4688 @classmethod |
4692 def showNotification(cls, icon, heading, text, |
4689 def showNotification(cls, icon, heading, text, |
4693 kind=NotificationTypes.Information, timeout=None): |
4690 kind=NotificationTypes.INFORMATION, timeout=None): |
4694 """ |
4691 """ |
4695 Class method to show a desktop notification. |
4692 Class method to show a desktop notification. |
4696 |
4693 |
4697 @param icon icon to be shown in the notification |
4694 @param icon icon to be shown in the notification |
4698 @type QPixmap |
4695 @type QPixmap |
4794 "persistentstorage")) |
4791 "persistentstorage")) |
4795 cls._webProfile.setPersistentCookiesPolicy( |
4792 cls._webProfile.setPersistentCookiesPolicy( |
4796 QWebEngineProfile.PersistentCookiesPolicy |
4793 QWebEngineProfile.PersistentCookiesPolicy |
4797 .AllowPersistentCookies) |
4794 .AllowPersistentCookies) |
4798 |
4795 |
4799 try: |
4796 with contextlib.suppress(AttributeError): |
4800 cls._webProfile.setSpellCheckEnabled( |
4797 cls._webProfile.setSpellCheckEnabled( |
4801 Preferences.getWebBrowser("SpellCheckEnabled")) |
4798 Preferences.getWebBrowser("SpellCheckEnabled")) |
4802 cls._webProfile.setSpellCheckLanguages( |
4799 cls._webProfile.setSpellCheckLanguages( |
4803 Preferences.getWebBrowser("SpellCheckLanguages")) |
4800 Preferences.getWebBrowser("SpellCheckLanguages")) |
4804 except AttributeError: |
|
4805 # not yet supported |
|
4806 pass |
|
4807 |
4801 |
4808 # Setup QWebChannel user scripts |
4802 # Setup QWebChannel user scripts |
4809 from .WebBrowserPage import WebBrowserPage |
4803 from .WebBrowserPage import WebBrowserPage |
4810 |
4804 |
4811 # WebChannel for SafeJsWorld |
4805 # WebChannel for SafeJsWorld |
5005 if not ext: |
4999 if not ext: |
5006 ex = selectedFilter.split("(*")[1].split(")")[0] |
5000 ex = selectedFilter.split("(*")[1].split(")")[0] |
5007 if ex: |
5001 if ex: |
5008 fn += ex |
5002 fn += ex |
5009 |
5003 |
5010 if os.path.exists(fn): |
5004 ok = ( |
5011 ok = E5MessageBox.yesNo( |
5005 E5MessageBox.yesNo( |
5012 self, |
5006 self, |
5013 self.tr("Export Keyboard Shortcuts"), |
5007 self.tr("Export Keyboard Shortcuts"), |
5014 self.tr("""<p>The keyboard shortcuts file <b>{0}</b> exists""" |
5008 self.tr("""<p>The keyboard shortcuts file <b>{0}</b> exists""" |
5015 """ already. Overwrite it?</p>""").format(fn)) |
5009 """ already. Overwrite it?</p>""").format(fn)) |
5016 else: |
5010 if os.path.exists(fn) else |
5017 ok = True |
5011 True |
|
5012 ) |
5018 |
5013 |
5019 if ok: |
5014 if ok: |
5020 from Preferences import Shortcuts |
5015 from Preferences import Shortcuts |
5021 Shortcuts.exportShortcuts(fn, helpViewer=self) |
5016 Shortcuts.exportShortcuts(fn, helpViewer=self) |
5022 |
5017 |