1# -*- coding: utf-8 -*- 2 3# Copyright (c) 2002 - 2021 Detlev Offenbach <detlev@die-offenbachs.de> 4# 5 6""" 7Module implementing the web browser main window. 8""" 9 10import os 11import shutil 12import sys 13import functools 14import contextlib 15 16from PyQt5.QtCore import ( 17 pyqtSlot, pyqtSignal, Qt, QByteArray, QSize, QTimer, QUrl, QProcess, 18 QEvent, QFileInfo 19) 20from PyQt5.QtGui import QDesktopServices, QKeySequence, QFont, QFontMetrics 21from PyQt5.QtWidgets import ( 22 QWidget, QVBoxLayout, QSizePolicy, QDockWidget, QComboBox, QLabel, QMenu, 23 QLineEdit, QApplication, QWhatsThis, QDialog, QHBoxLayout, QProgressBar, 24 QInputDialog, QAction 25) 26from PyQt5.QtWebEngineWidgets import ( 27 QWebEngineSettings, QWebEnginePage, QWebEngineProfile, QWebEngineScript 28) 29try: 30 from PyQt5.QtHelp import QHelpEngine, QHelpEngineCore, QHelpSearchQuery 31 QTHELP_AVAILABLE = True 32except ImportError: 33 QTHELP_AVAILABLE = False 34 35from E5Gui.E5Action import E5Action 36from E5Gui import E5MessageBox, E5FileDialog, E5ErrorMessage 37from E5Gui.E5MainWindow import E5MainWindow 38from E5Gui.E5Application import e5App 39from E5Gui.E5ZoomWidget import E5ZoomWidget 40from E5Gui.E5OverrideCursor import E5OverrideCursor 41 42import Preferences 43from Preferences import Shortcuts 44 45import Utilities 46import Globals 47 48import UI.PixmapCache 49import UI.Config 50from UI.Info import Version 51from UI.NotificationWidget import NotificationTypes 52 53from .Tools import Scripts, WebBrowserTools, WebIconProvider 54 55from .ZoomManager import ZoomManager 56 57from .WebBrowserSingleApplication import WebBrowserSingleApplicationServer 58 59from eric6config import getConfig 60 61 62class WebBrowserWindow(E5MainWindow): 63 """ 64 Class implementing the web browser main window. 65 66 @signal webBrowserWindowOpened(window) emitted after a new web browser 67 window was opened 68 @signal webBrowserWindowClosed(window) emitted after the window was 69 requested to close 70 @signal webBrowserOpened(browser) emitted after a new web browser tab was 71 created 72 @signal webBrowserClosed(browser) emitted after a web browser tab was 73 closed 74 """ 75 webBrowserWindowClosed = pyqtSignal(E5MainWindow) 76 webBrowserWindowOpened = pyqtSignal(E5MainWindow) 77 webBrowserOpened = pyqtSignal(QWidget) 78 webBrowserClosed = pyqtSignal(QWidget) 79 80 BrowserWindows = [] 81 82 _useQtHelp = QTHELP_AVAILABLE 83 _isPrivate = False 84 85 _webProfile = None 86 _networkManager = None 87 _cookieJar = None 88 _helpEngine = None 89 _bookmarksManager = None 90 _historyManager = None 91 _passwordManager = None 92 _adblockManager = None 93 _downloadManager = None 94 _feedsManager = None 95 _userAgentsManager = None 96 _syncManager = None 97 _speedDial = None 98 _personalInformationManager = None 99 _greaseMonkeyManager = None 100 _notification = None 101 _featurePermissionManager = None 102 _imageSearchEngine = None 103 _autoScroller = None 104 _tabManager = None 105 _sessionManager = None 106 _safeBrowsingManager = None 107 _protocolHandlerManager = None 108 109 _performingStartup = True 110 _performingShutdown = False 111 _lastActiveWindow = None 112 113 def __init__(self, home, path, parent, name, 114 searchWord=None, private=False, qthelp=False, settingsDir="", 115 restoreSession=False, single=False, saname=""): 116 """ 117 Constructor 118 119 @param home the URL to be shown 120 @type str 121 @param path the path of the working dir (usually '.') 122 @type str 123 @param parent parent widget of this window 124 @type QWidget 125 @param name name of this window 126 @type str 127 @param searchWord word to search for 128 @type str 129 @param private flag indicating a private browsing window 130 @type bool 131 @param qthelp flag indicating to enable the QtHelp support 132 @type bool 133 @param settingsDir directory to be used for the settings files 134 @type str 135 @param restoreSession flag indicating a restore session action 136 @type bool 137 @param single flag indicating to start in single application mode 138 @type bool 139 @param saname name to be used for the single application server 140 @type str 141 """ 142 self.__hideNavigationTimer = None 143 144 super().__init__(parent) 145 self.setObjectName(name) 146 if private: 147 self.setWindowTitle(self.tr("eric Web Browser (Private Mode)")) 148 else: 149 self.setWindowTitle(self.tr("eric Web Browser")) 150 151 self.__settingsDir = settingsDir 152 self.setWindowIcon(UI.PixmapCache.getIcon("ericWeb")) 153 154 self.__mHistory = [] 155 self.__lastConfigurationPageName = "" 156 157 WebBrowserWindow._isPrivate = private 158 159 self.__shortcutsDialog = None 160 161 self.__eventMouseButtons = Qt.MouseButton.NoButton 162 self.__eventKeyboardModifiers = Qt.KeyboardModifier.NoModifier 163 164 WebBrowserWindow.setUseQtHelp(qthelp or bool(searchWord)) 165 166 self.webProfile(private) 167 self.networkManager() 168 169 self.__htmlFullScreen = False 170 self.__windowStates = Qt.WindowState.WindowNoState 171 self.__isClosing = False 172 173 from .SearchWidget import SearchWidget 174 from .QtHelp.HelpTocWidget import HelpTocWidget 175 from .QtHelp.HelpIndexWidget import HelpIndexWidget 176 from .QtHelp.HelpSearchWidget import HelpSearchWidget 177 from .WebBrowserView import WebBrowserView 178 from .WebBrowserTabWidget import WebBrowserTabWidget 179 from .AdBlock.AdBlockIcon import AdBlockIcon 180 from .StatusBar.JavaScriptIcon import JavaScriptIcon 181 from .StatusBar.ImagesIcon import ImagesIcon 182 from .VirusTotal.VirusTotalApi import VirusTotalAPI 183 from .Navigation.NavigationBar import NavigationBar 184 from .Navigation.NavigationContainer import NavigationContainer 185 from .Bookmarks.BookmarksToolBar import BookmarksToolBar 186 187 self.setStyle(Preferences.getUI("Style"), 188 Preferences.getUI("StyleSheet")) 189 190 # initialize some SSL stuff 191 from E5Network.E5SslUtilities import initSSL 192 initSSL() 193 194 if WebBrowserWindow._useQtHelp: 195 self.__helpEngine = QHelpEngine( 196 WebBrowserWindow.getQtHelpCollectionFileName(), 197 self) 198 self.__removeOldDocumentation() 199 self.__helpEngine.warning.connect(self.__warning) 200 else: 201 self.__helpEngine = None 202 self.__helpInstaller = None 203 204 self.__zoomWidget = E5ZoomWidget( 205 UI.PixmapCache.getPixmap("zoomOut"), 206 UI.PixmapCache.getPixmap("zoomIn"), 207 UI.PixmapCache.getPixmap("zoomReset"), self) 208 self.statusBar().addPermanentWidget(self.__zoomWidget) 209 self.__zoomWidget.setMapping( 210 WebBrowserView.ZoomLevels, WebBrowserView.ZoomLevelDefault) 211 self.__zoomWidget.valueChanged.connect(self.__zoomValueChanged) 212 213 self.__tabWidget = WebBrowserTabWidget(self) 214 self.__tabWidget.currentChanged[int].connect(self.__currentChanged) 215 self.__tabWidget.titleChanged.connect(self.__titleChanged) 216 self.__tabWidget.showMessage.connect(self.statusBar().showMessage) 217 self.__tabWidget.browserZoomValueChanged.connect( 218 self.__zoomWidget.setValue) 219 self.__tabWidget.browserClosed.connect(self.webBrowserClosed) 220 self.__tabWidget.browserOpened.connect(self.webBrowserOpened) 221 222 self.__searchWidget = SearchWidget(self, self) 223 224 self.__setIconDatabasePath() 225 226 bookmarksModel = self.bookmarksManager().bookmarksModel() 227 self.__bookmarksToolBar = BookmarksToolBar(self, bookmarksModel, 228 self) 229 self.__bookmarksToolBar.setIconSize(UI.Config.ToolBarIconSize) 230 self.__bookmarksToolBar.openUrl.connect(self.openUrl) 231 self.__bookmarksToolBar.newTab.connect(self.openUrlNewTab) 232 self.__bookmarksToolBar.newWindow.connect(self.openUrlNewWindow) 233 234 self.__navigationBar = NavigationBar(self) 235 236 self.__navigationContainer = NavigationContainer(self) 237 self.__navigationContainer.addWidget(self.__navigationBar) 238 self.__navigationContainer.addWidget(self.__bookmarksToolBar) 239 240 centralWidget = QWidget() 241 layout = QVBoxLayout() 242 layout.setContentsMargins(1, 1, 1, 1) 243 layout.setSpacing(0) 244 layout.addWidget(self.__navigationContainer) 245 layout.addWidget(self.__tabWidget) 246 layout.addWidget(self.__searchWidget) 247 self.__tabWidget.setSizePolicy( 248 QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Expanding) 249 centralWidget.setLayout(layout) 250 self.setCentralWidget(centralWidget) 251 self.__searchWidget.hide() 252 253 if WebBrowserWindow._useQtHelp: 254 # setup the TOC widget 255 self.__tocWindow = HelpTocWidget(self.__helpEngine) 256 self.__tocDock = QDockWidget(self.tr("Contents"), self) 257 self.__tocDock.setObjectName("TocWindow") 258 self.__tocDock.setWidget(self.__tocWindow) 259 self.addDockWidget(Qt.DockWidgetArea.LeftDockWidgetArea, 260 self.__tocDock) 261 262 # setup the index widget 263 self.__indexWindow = HelpIndexWidget(self.__helpEngine) 264 self.__indexDock = QDockWidget(self.tr("Index"), self) 265 self.__indexDock.setObjectName("IndexWindow") 266 self.__indexDock.setWidget(self.__indexWindow) 267 self.addDockWidget(Qt.DockWidgetArea.LeftDockWidgetArea, 268 self.__indexDock) 269 270 # setup the search widget 271 self.__searchWord = searchWord 272 self.__indexing = False 273 self.__indexingProgress = None 274 self.__searchEngine = self.__helpEngine.searchEngine() 275 self.__searchEngine.indexingStarted.connect( 276 self.__indexingStarted) 277 self.__searchEngine.indexingFinished.connect( 278 self.__indexingFinished) 279 self.__searchWindow = HelpSearchWidget(self.__searchEngine) 280 self.__searchDock = QDockWidget(self.tr("Search"), self) 281 self.__searchDock.setObjectName("SearchWindow") 282 self.__searchDock.setWidget(self.__searchWindow) 283 self.addDockWidget(Qt.DockWidgetArea.LeftDockWidgetArea, 284 self.__searchDock) 285 286 # JavaScript Console window 287 from .WebBrowserJavaScriptConsole import WebBrowserJavaScriptConsole 288 self.__javascriptConsole = WebBrowserJavaScriptConsole(self) 289 self.__javascriptConsoleDock = QDockWidget( 290 self.tr("JavaScript Console")) 291 self.__javascriptConsoleDock.setObjectName("JavascriptConsole") 292 self.__javascriptConsoleDock.setAllowedAreas( 293 Qt.DockWidgetArea.BottomDockWidgetArea | 294 Qt.DockWidgetArea.TopDockWidgetArea) 295 self.__javascriptConsoleDock.setWidget(self.__javascriptConsole) 296 self.addDockWidget(Qt.DockWidgetArea.BottomDockWidgetArea, 297 self.__javascriptConsoleDock) 298 299 g = ( 300 Preferences.getGeometry("WebBrowserGeometry") 301 if Preferences.getWebBrowser("SaveGeometry") else 302 QByteArray() 303 ) 304 if g.isEmpty(): 305 s = QSize(800, 800) 306 self.resize(s) 307 else: 308 self.restoreGeometry(g) 309 310 WebBrowserWindow.BrowserWindows.append(self) 311 312 self.__initWebEngineSettings() 313 314 # initialize some of our class objects 315 self.passwordManager() 316 self.historyManager() 317 self.greaseMonkeyManager() 318 self.protocolHandlerManager() 319 320 # initialize the actions 321 self.__initActions() 322 323 # initialize the menus 324 self.__initMenus() 325 self.__initSuperMenu() 326 if Preferences.getWebBrowser("MenuBarVisible"): 327 self.__navigationBar.superMenuButton().hide() 328 else: 329 self.menuBar().hide() 330 331 # save references to toolbars in order to hide them 332 # when going full screen 333 self.__toolbars = {} 334 # initialize toolbars 335 if Preferences.getWebBrowser("ShowToolbars"): 336 self.__initToolbars() 337 self.__bookmarksToolBar.setVisible( 338 Preferences.getWebBrowser("BookmarksToolBarVisible")) 339 340 syncMgr = self.syncManager() 341 syncMgr.syncMessage.connect(self.statusBar().showMessage) 342 syncMgr.syncError.connect(self.statusBar().showMessage) 343 344 restoreSessionData = {} 345 if ( 346 WebBrowserWindow._performingStartup and 347 not home and 348 not WebBrowserWindow.isPrivate() 349 ): 350 startupBehavior = Preferences.getWebBrowser("StartupBehavior") 351 if not private and startupBehavior in [3, 4]: 352 if startupBehavior == 3: 353 # restore last session 354 restoreSessionFile = ( 355 self.sessionManager().lastActiveSessionFile() 356 ) 357 elif startupBehavior == 4: 358 # select session 359 restoreSessionFile = self.sessionManager().selectSession() 360 sessionData = self.sessionManager().readSessionFromFile( 361 restoreSessionFile) 362 if self.sessionManager().isValidSession(sessionData): 363 restoreSessionData = sessionData 364 restoreSession = True 365 else: 366 if Preferences.getWebBrowser("StartupBehavior") == 0: 367 home = "about:blank" 368 elif Preferences.getWebBrowser("StartupBehavior") == 1: 369 home = Preferences.getWebBrowser("HomePage") 370 elif Preferences.getWebBrowser("StartupBehavior") == 2: 371 home = "eric:speeddial" 372 373 if not restoreSession: 374 self.__tabWidget.newBrowser(QUrl.fromUserInput(home)) 375 self.__tabWidget.currentBrowser().setFocus() 376 WebBrowserWindow._performingStartup = False 377 378 self.__imagesIcon = ImagesIcon(self) 379 self.statusBar().addPermanentWidget(self.__imagesIcon) 380 self.__javaScriptIcon = JavaScriptIcon(self) 381 self.statusBar().addPermanentWidget(self.__javaScriptIcon) 382 383 self.__adBlockIcon = AdBlockIcon(self) 384 self.statusBar().addPermanentWidget(self.__adBlockIcon) 385 self.__adBlockIcon.setEnabled( 386 Preferences.getWebBrowser("AdBlockEnabled")) 387 self.__tabWidget.currentChanged[int].connect( 388 self.__adBlockIcon.currentChanged) 389 self.__tabWidget.sourceChanged.connect( 390 self.__adBlockIcon.sourceChanged) 391 392 self.__tabManagerIcon = self.tabManager().createStatusBarIcon() 393 self.statusBar().addPermanentWidget(self.__tabManagerIcon) 394 395 if not Preferences.getWebBrowser("StatusBarVisible"): 396 self.statusBar().hide() 397 398 if len(WebBrowserWindow.BrowserWindows): 399 QDesktopServices.setUrlHandler( 400 "http", WebBrowserWindow.BrowserWindows[0].urlHandler) 401 QDesktopServices.setUrlHandler( 402 "https", WebBrowserWindow.BrowserWindows[0].urlHandler) 403 404 # setup connections 405 self.__activating = False 406 if WebBrowserWindow._useQtHelp: 407 # TOC window 408 self.__tocWindow.escapePressed.connect( 409 self.__activateCurrentBrowser) 410 self.__tocWindow.openUrl.connect(self.openUrl) 411 self.__tocWindow.newTab.connect(self.openUrlNewTab) 412 self.__tocWindow.newBackgroundTab.connect( 413 self.openUrlNewBackgroundTab) 414 self.__tocWindow.newWindow.connect(self.openUrlNewWindow) 415 416 # index window 417 self.__indexWindow.escapePressed.connect( 418 self.__activateCurrentBrowser) 419 self.__indexWindow.openUrl.connect(self.openUrl) 420 self.__indexWindow.newTab.connect(self.openUrlNewTab) 421 self.__indexWindow.newBackgroundTab.connect( 422 self.openUrlNewBackgroundTab) 423 self.__indexWindow.newWindow.connect(self.openUrlNewWindow) 424 425 # search window 426 self.__searchWindow.escapePressed.connect( 427 self.__activateCurrentBrowser) 428 self.__searchWindow.openUrl.connect(self.openUrl) 429 self.__searchWindow.newTab.connect(self.openUrlNewTab) 430 self.__searchWindow.newBackgroundTab.connect( 431 self.openUrlNewBackgroundTab) 432 self.__searchWindow.newWindow.connect(self.openUrlNewWindow) 433 434 state = Preferences.getWebBrowser("WebBrowserState") 435 self.restoreState(state) 436 437 self.__initHelpDb() 438 439 self.__virusTotal = VirusTotalAPI(self) 440 self.__virusTotal.submitUrlError.connect( 441 self.__virusTotalSubmitUrlError) 442 self.__virusTotal.urlScanReport.connect( 443 self.__virusTotalUrlScanReport) 444 self.__virusTotal.fileScanReport.connect( 445 self.__virusTotalFileScanReport) 446 447 e5App().focusChanged.connect(self.__appFocusChanged) 448 449 self.__toolbarStates = self.saveState() 450 451 if single: 452 self.SAServer = WebBrowserSingleApplicationServer(saname) 453 self.SAServer.loadUrl.connect(self.__saLoadUrl) 454 self.SAServer.newTab.connect(self.__saNewTab) 455 self.SAServer.search.connect(self.__saSearchWord) 456 self.SAServer.shutdown.connect(self.shutdown) 457 else: 458 self.SAServer = None 459 460 self.__hideNavigationTimer = QTimer(self) 461 self.__hideNavigationTimer.setInterval(1000) 462 self.__hideNavigationTimer.setSingleShot(True) 463 self.__hideNavigationTimer.timeout.connect(self.__hideNavigation) 464 465 self.__forcedClose = False 466 467 if restoreSessionData and not WebBrowserWindow.isPrivate(): 468 self.sessionManager().restoreSessionFromData( 469 self, restoreSessionData) 470 471 if not WebBrowserWindow.isPrivate(): 472 self.sessionManager().activateTimer() 473 474 QTimer.singleShot(0, syncMgr.loadSettings) 475 476 if WebBrowserWindow._useQtHelp: 477 QTimer.singleShot(50, self.__lookForNewDocumentation) 478 if self.__searchWord is not None: 479 QTimer.singleShot(0, self.__searchForWord) 480 481 def __del__(self): 482 """ 483 Special method called during object destruction. 484 485 Note: This empty variant seems to get rid of the Qt message 486 'Warning: QBasicTimer::start: QBasicTimer can only be used with 487 threads started with QThread' 488 """ 489 pass 490 491 def tabWidget(self): 492 """ 493 Public method to get a reference to the tab widget. 494 495 @return reference to the tab widget 496 @rtype WebBrowserTabWidget 497 """ 498 return self.__tabWidget 499 500 def __setIconDatabasePath(self, enable=True): 501 """ 502 Private method to set the favicons path. 503 504 @param enable flag indicating to enabled icon storage (boolean) 505 """ 506 if enable: 507 iconDatabasePath = os.path.join(Utilities.getConfigDir(), 508 "web_browser", "favicons") 509 if not os.path.exists(iconDatabasePath): 510 os.makedirs(iconDatabasePath) 511 else: 512 iconDatabasePath = "" # setting an empty path disables it 513 514 WebIconProvider.instance().setIconDatabasePath(iconDatabasePath) 515 516 def __initWebEngineSettings(self): 517 """ 518 Private method to set the global web settings. 519 """ 520 settings = self.webSettings() 521 522 settings.setFontFamily( 523 QWebEngineSettings.FontFamily.StandardFont, 524 Preferences.getWebBrowser("StandardFontFamily")) 525 settings.setFontFamily( 526 QWebEngineSettings.FontFamily.FixedFont, 527 Preferences.getWebBrowser("FixedFontFamily")) 528 settings.setFontFamily( 529 QWebEngineSettings.FontFamily.SerifFont, 530 Preferences.getWebBrowser("SerifFontFamily")) 531 settings.setFontFamily( 532 QWebEngineSettings.FontFamily.SansSerifFont, 533 Preferences.getWebBrowser("SansSerifFontFamily")) 534 settings.setFontFamily( 535 QWebEngineSettings.FontFamily.CursiveFont, 536 Preferences.getWebBrowser("CursiveFontFamily")) 537 settings.setFontFamily( 538 QWebEngineSettings.FontFamily.FantasyFont, 539 Preferences.getWebBrowser("FantasyFontFamily")) 540 541 settings.setFontSize( 542 QWebEngineSettings.FontSize.DefaultFontSize, 543 Preferences.getWebBrowser("DefaultFontSize")) 544 settings.setFontSize( 545 QWebEngineSettings.FontSize.DefaultFixedFontSize, 546 Preferences.getWebBrowser("DefaultFixedFontSize")) 547 settings.setFontSize( 548 QWebEngineSettings.FontSize.MinimumFontSize, 549 Preferences.getWebBrowser("MinimumFontSize")) 550 settings.setFontSize( 551 QWebEngineSettings.FontSize.MinimumLogicalFontSize, 552 Preferences.getWebBrowser("MinimumLogicalFontSize")) 553 554 styleSheet = Preferences.getWebBrowser("UserStyleSheet") 555 self.__setUserStyleSheet(styleSheet) 556 557 settings.setAttribute( 558 QWebEngineSettings.WebAttribute.AutoLoadImages, 559 Preferences.getWebBrowser("AutoLoadImages")) 560 settings.setAttribute( 561 QWebEngineSettings.WebAttribute.JavascriptEnabled, 562 Preferences.getWebBrowser("JavaScriptEnabled")) 563 # JavaScript is needed for the web browser functionality 564 settings.setAttribute( 565 QWebEngineSettings.WebAttribute.JavascriptCanOpenWindows, 566 Preferences.getWebBrowser("JavaScriptCanOpenWindows")) 567 settings.setAttribute( 568 QWebEngineSettings.WebAttribute.JavascriptCanAccessClipboard, 569 Preferences.getWebBrowser("JavaScriptCanAccessClipboard")) 570 settings.setAttribute( 571 QWebEngineSettings.WebAttribute.PluginsEnabled, 572 Preferences.getWebBrowser("PluginsEnabled")) 573 574 if self.isPrivate(): 575 settings.setAttribute( 576 QWebEngineSettings.WebAttribute.LocalStorageEnabled, False) 577 else: 578 settings.setAttribute( 579 QWebEngineSettings.WebAttribute.LocalStorageEnabled, 580 Preferences.getWebBrowser("LocalStorageEnabled")) 581 settings.setDefaultTextEncoding( 582 Preferences.getWebBrowser("DefaultTextEncoding")) 583 584 settings.setAttribute( 585 QWebEngineSettings.WebAttribute.SpatialNavigationEnabled, 586 Preferences.getWebBrowser("SpatialNavigationEnabled")) 587 settings.setAttribute( 588 QWebEngineSettings.WebAttribute.LinksIncludedInFocusChain, 589 Preferences.getWebBrowser("LinksIncludedInFocusChain")) 590 settings.setAttribute( 591 QWebEngineSettings.WebAttribute.LocalContentCanAccessRemoteUrls, 592 Preferences.getWebBrowser("LocalContentCanAccessRemoteUrls")) 593 settings.setAttribute( 594 QWebEngineSettings.WebAttribute.LocalContentCanAccessFileUrls, 595 Preferences.getWebBrowser("LocalContentCanAccessFileUrls")) 596 settings.setAttribute( 597 QWebEngineSettings.WebAttribute.XSSAuditingEnabled, 598 Preferences.getWebBrowser("XSSAuditingEnabled")) 599 settings.setAttribute( 600 QWebEngineSettings.WebAttribute.ScrollAnimatorEnabled, 601 Preferences.getWebBrowser("ScrollAnimatorEnabled")) 602 settings.setAttribute( 603 QWebEngineSettings.WebAttribute.ErrorPageEnabled, 604 Preferences.getWebBrowser("ErrorPageEnabled")) 605 settings.setAttribute( 606 QWebEngineSettings.WebAttribute.FullScreenSupportEnabled, 607 Preferences.getWebBrowser("FullScreenSupportEnabled")) 608 settings.setAttribute( 609 QWebEngineSettings.WebAttribute.ScreenCaptureEnabled, 610 Preferences.getWebBrowser("ScreenCaptureEnabled")) 611 settings.setAttribute( 612 QWebEngineSettings.WebAttribute.WebGLEnabled, 613 Preferences.getWebBrowser("WebGLEnabled")) 614 settings.setAttribute( 615 QWebEngineSettings.WebAttribute.FocusOnNavigationEnabled, 616 Preferences.getWebBrowser("FocusOnNavigationEnabled")) 617 settings.setAttribute( 618 QWebEngineSettings.WebAttribute.PrintElementBackgrounds, 619 Preferences.getWebBrowser("PrintElementBackgrounds")) 620 settings.setAttribute( 621 QWebEngineSettings.WebAttribute.AllowRunningInsecureContent, 622 Preferences.getWebBrowser("AllowRunningInsecureContent")) 623 settings.setAttribute( 624 QWebEngineSettings.WebAttribute.AllowGeolocationOnInsecureOrigins, 625 Preferences.getWebBrowser("AllowGeolocationOnInsecureOrigins")) 626 settings.setAttribute( 627 QWebEngineSettings.WebAttribute 628 .AllowWindowActivationFromJavaScript, 629 Preferences.getWebBrowser( 630 "AllowWindowActivationFromJavaScript")) 631 settings.setAttribute( 632 QWebEngineSettings.WebAttribute.ShowScrollBars, 633 Preferences.getWebBrowser("ShowScrollBars")) 634 settings.setAttribute( 635 QWebEngineSettings.WebAttribute.PlaybackRequiresUserGesture, 636 Preferences.getWebBrowser( 637 "PlaybackRequiresUserGesture")) 638 settings.setAttribute( 639 QWebEngineSettings.WebAttribute.JavascriptCanPaste, 640 Preferences.getWebBrowser( 641 "JavaScriptCanPaste")) 642 settings.setAttribute( 643 QWebEngineSettings.WebAttribute.WebRTCPublicInterfacesOnly, 644 Preferences.getWebBrowser( 645 "WebRTCPublicInterfacesOnly")) 646 settings.setAttribute( 647 QWebEngineSettings.WebAttribute.DnsPrefetchEnabled, 648 Preferences.getWebBrowser( 649 "DnsPrefetchEnabled")) 650 651 with contextlib.suppress(AttributeError, KeyError): 652 # Qt 5.13 653 settings.setAttribute( 654 QWebEngineSettings.WebAttribute.PdfViewerEnabled, 655 Preferences.getWebBrowser( 656 "PdfViewerEnabled")) 657 658 def __initActions(self): 659 """ 660 Private method to define the user interface actions. 661 """ 662 # list of all actions 663 self.__actions = [] 664 665 self.newTabAct = E5Action( 666 self.tr('New Tab'), 667 UI.PixmapCache.getIcon("tabNew"), 668 self.tr('&New Tab'), 669 QKeySequence(self.tr("Ctrl+T", "File|New Tab")), 670 0, self, 'webbrowser_file_new_tab') 671 self.newTabAct.setStatusTip(self.tr('Open a new web browser tab')) 672 self.newTabAct.setWhatsThis(self.tr( 673 """<b>New Tab</b>""" 674 """<p>This opens a new web browser tab.</p>""" 675 )) 676 self.newTabAct.triggered.connect(self.newTab) 677 self.__actions.append(self.newTabAct) 678 679 self.newAct = E5Action( 680 self.tr('New Window'), 681 UI.PixmapCache.getIcon("newWindow"), 682 self.tr('New &Window'), 683 QKeySequence(self.tr("Ctrl+N", "File|New Window")), 684 0, self, 'webbrowser_file_new_window') 685 self.newAct.setStatusTip(self.tr('Open a new web browser window')) 686 self.newAct.setWhatsThis(self.tr( 687 """<b>New Window</b>""" 688 """<p>This opens a new web browser window in the current""" 689 """ privacy mode.</p>""" 690 )) 691 self.newAct.triggered.connect(self.newWindow) 692 self.__actions.append(self.newAct) 693 694 self.newPrivateAct = E5Action( 695 self.tr('New Private Window'), 696 UI.PixmapCache.getIcon("privateMode"), 697 self.tr('New &Private Window'), 698 QKeySequence(self.tr("Ctrl+Shift+P", "File|New Private Window")), 699 0, self, 'webbrowser_file_new_private_window') 700 self.newPrivateAct.setStatusTip(self.tr( 701 'Open a new private web browser window')) 702 self.newPrivateAct.setWhatsThis(self.tr( 703 """<b>New Private Window</b>""" 704 """<p>This opens a new private web browser window by starting""" 705 """ a new web browser instance in private mode.</p>""" 706 )) 707 self.newPrivateAct.triggered.connect(self.newPrivateWindow) 708 self.__actions.append(self.newPrivateAct) 709 710 self.openAct = E5Action( 711 self.tr('Open File'), 712 UI.PixmapCache.getIcon("open"), 713 self.tr('&Open File'), 714 QKeySequence(self.tr("Ctrl+O", "File|Open")), 715 0, self, 'webbrowser_file_open') 716 self.openAct.setStatusTip(self.tr('Open a file for display')) 717 self.openAct.setWhatsThis(self.tr( 718 """<b>Open File</b>""" 719 """<p>This opens a new file for display.""" 720 """ It pops up a file selection dialog.</p>""" 721 )) 722 self.openAct.triggered.connect(self.__openFile) 723 self.__actions.append(self.openAct) 724 725 self.openTabAct = E5Action( 726 self.tr('Open File in New Tab'), 727 UI.PixmapCache.getIcon("openNewTab"), 728 self.tr('Open File in New &Tab'), 729 QKeySequence(self.tr("Shift+Ctrl+O", "File|Open in new tab")), 730 0, self, 'webbrowser_file_open_tab') 731 self.openTabAct.setStatusTip( 732 self.tr('Open a file for display in a new tab')) 733 self.openTabAct.setWhatsThis(self.tr( 734 """<b>Open File in New Tab</b>""" 735 """<p>This opens a new file for display in a new tab.""" 736 """ It pops up a file selection dialog.</p>""" 737 )) 738 self.openTabAct.triggered.connect(self.__openFileNewTab) 739 self.__actions.append(self.openTabAct) 740 741 if hasattr(QWebEnginePage, "SavePage"): 742 self.saveAsAct = E5Action( 743 self.tr('Save As'), 744 UI.PixmapCache.getIcon("fileSaveAs"), 745 self.tr('&Save As...'), 746 QKeySequence(self.tr("Shift+Ctrl+S", "File|Save As")), 747 0, self, 'webbrowser_file_save_as') 748 self.saveAsAct.setStatusTip( 749 self.tr('Save the current page to disk')) 750 self.saveAsAct.setWhatsThis(self.tr( 751 """<b>Save As...</b>""" 752 """<p>Saves the current page to disk.</p>""" 753 )) 754 self.saveAsAct.triggered.connect(self.__savePageAs) 755 self.__actions.append(self.saveAsAct) 756 else: 757 self.saveAsAct = None 758 759 self.saveVisiblePageScreenAct = E5Action( 760 self.tr('Save Page Screen'), 761 UI.PixmapCache.getIcon("fileSavePixmap"), 762 self.tr('Save Page Screen...'), 763 0, 0, self, 'webbrowser_file_save_visible_page_screen') 764 self.saveVisiblePageScreenAct.setStatusTip( 765 self.tr('Save the visible part of the current page as a' 766 ' screen shot')) 767 self.saveVisiblePageScreenAct.setWhatsThis(self.tr( 768 """<b>Save Page Screen...</b>""" 769 """<p>Saves the visible part of the current page as a""" 770 """ screen shot.</p>""" 771 )) 772 self.saveVisiblePageScreenAct.triggered.connect( 773 self.__saveVisiblePageScreen) 774 self.__actions.append(self.saveVisiblePageScreenAct) 775 776 bookmarksManager = self.bookmarksManager() 777 self.importBookmarksAct = E5Action( 778 self.tr('Import Bookmarks'), 779 self.tr('&Import Bookmarks...'), 780 0, 0, self, 'webbrowser_file_import_bookmarks') 781 self.importBookmarksAct.setStatusTip( 782 self.tr('Import bookmarks from other browsers')) 783 self.importBookmarksAct.setWhatsThis(self.tr( 784 """<b>Import Bookmarks</b>""" 785 """<p>Import bookmarks from other browsers.</p>""" 786 )) 787 self.importBookmarksAct.triggered.connect( 788 bookmarksManager.importBookmarks) 789 self.__actions.append(self.importBookmarksAct) 790 791 self.exportBookmarksAct = E5Action( 792 self.tr('Export Bookmarks'), 793 self.tr('&Export Bookmarks...'), 794 0, 0, self, 'webbrowser_file_export_bookmarks') 795 self.exportBookmarksAct.setStatusTip( 796 self.tr('Export the bookmarks into a file')) 797 self.exportBookmarksAct.setWhatsThis(self.tr( 798 """<b>Export Bookmarks</b>""" 799 """<p>Export the bookmarks into a file.</p>""" 800 )) 801 self.exportBookmarksAct.triggered.connect( 802 bookmarksManager.exportBookmarks) 803 self.__actions.append(self.exportBookmarksAct) 804 805 self.printAct = E5Action( 806 self.tr('Print'), 807 UI.PixmapCache.getIcon("print"), 808 self.tr('&Print'), 809 QKeySequence(self.tr("Ctrl+P", "File|Print")), 810 0, self, 'webbrowser_file_print') 811 self.printAct.setStatusTip(self.tr('Print the displayed help')) 812 self.printAct.setWhatsThis(self.tr( 813 """<b>Print</b>""" 814 """<p>Print the displayed help text.</p>""" 815 )) 816 self.printAct.triggered.connect(self.__tabWidget.printBrowser) 817 self.__actions.append(self.printAct) 818 819 self.printPdfAct = E5Action( 820 self.tr('Print as PDF'), 821 UI.PixmapCache.getIcon("printPdf"), 822 self.tr('Print as PDF'), 823 0, 0, self, 'webbrowser_file_print_pdf') 824 self.printPdfAct.setStatusTip(self.tr( 825 'Print the displayed help as PDF')) 826 self.printPdfAct.setWhatsThis(self.tr( 827 """<b>Print as PDF</b>""" 828 """<p>Print the displayed help text as a PDF file.</p>""" 829 )) 830 self.printPdfAct.triggered.connect( 831 self.__tabWidget.printBrowserPdf) 832 self.__actions.append(self.printPdfAct) 833 834 self.printPreviewAct = E5Action( 835 self.tr('Print Preview'), 836 UI.PixmapCache.getIcon("printPreview"), 837 self.tr('Print Preview'), 838 0, 0, self, 'webbrowser_file_print_preview') 839 self.printPreviewAct.setStatusTip(self.tr( 840 'Print preview of the displayed help')) 841 self.printPreviewAct.setWhatsThis(self.tr( 842 """<b>Print Preview</b>""" 843 """<p>Print preview of the displayed help text.</p>""" 844 )) 845 self.printPreviewAct.triggered.connect( 846 self.__tabWidget.printPreviewBrowser) 847 self.__actions.append(self.printPreviewAct) 848 849 self.sendPageLinkAct = E5Action( 850 self.tr('Send Page Link'), 851 UI.PixmapCache.getIcon("mailSend"), 852 self.tr('Send Page Link'), 853 0, 0, self, 'webbrowser_send_page_link') 854 self.sendPageLinkAct.setStatusTip(self.tr( 855 'Send the link of the current page via email')) 856 self.sendPageLinkAct.setWhatsThis(self.tr( 857 """<b>Send Page Link</b>""" 858 """<p>Send the link of the current page via email.</p>""" 859 )) 860 self.sendPageLinkAct.triggered.connect(self.__sendPageLink) 861 self.__actions.append(self.sendPageLinkAct) 862 863 self.closeAct = E5Action( 864 self.tr('Close'), 865 UI.PixmapCache.getIcon("close"), 866 self.tr('&Close'), 867 QKeySequence(self.tr("Ctrl+W", "File|Close")), 868 0, self, 'webbrowser_file_close') 869 self.closeAct.setStatusTip(self.tr( 870 'Close the current help window')) 871 self.closeAct.setWhatsThis(self.tr( 872 """<b>Close</b>""" 873 """<p>Closes the current web browser window.</p>""" 874 )) 875 self.closeAct.triggered.connect(self.__tabWidget.closeBrowser) 876 self.__actions.append(self.closeAct) 877 878 self.closeAllAct = E5Action( 879 self.tr('Close All'), 880 self.tr('Close &All'), 881 0, 0, self, 'webbrowser_file_close_all') 882 self.closeAllAct.setStatusTip(self.tr('Close all help windows')) 883 self.closeAllAct.setWhatsThis(self.tr( 884 """<b>Close All</b>""" 885 """<p>Closes all web browser windows except the first one.</p>""" 886 )) 887 self.closeAllAct.triggered.connect( 888 self.__tabWidget.closeAllBrowsers) 889 self.__actions.append(self.closeAllAct) 890 891 self.exitAct = E5Action( 892 self.tr('Quit'), 893 UI.PixmapCache.getIcon("exit"), 894 self.tr('&Quit'), 895 QKeySequence(self.tr("Ctrl+Q", "File|Quit")), 896 0, self, 'webbrowser_file_quit') 897 self.exitAct.setStatusTip(self.tr('Quit the eric Web Browser')) 898 self.exitAct.setWhatsThis(self.tr( 899 """<b>Quit</b>""" 900 """<p>Quit the eric Web Browser.</p>""" 901 )) 902 self.exitAct.triggered.connect(self.shutdown) 903 self.__actions.append(self.exitAct) 904 905 self.backAct = E5Action( 906 self.tr('Backward'), 907 UI.PixmapCache.getIcon("back"), 908 self.tr('&Backward'), 909 QKeySequence(self.tr("Alt+Left", "Go|Backward")), 910 0, self, 'webbrowser_go_backward') 911 self.backAct.setStatusTip(self.tr('Move one screen backward')) 912 self.backAct.setWhatsThis(self.tr( 913 """<b>Backward</b>""" 914 """<p>Moves one screen backward. If none is""" 915 """ available, this action is disabled.</p>""" 916 )) 917 self.backAct.triggered.connect(self.__backward) 918 self.__actions.append(self.backAct) 919 920 self.forwardAct = E5Action( 921 self.tr('Forward'), 922 UI.PixmapCache.getIcon("forward"), 923 self.tr('&Forward'), 924 QKeySequence(self.tr("Alt+Right", "Go|Forward")), 925 0, self, 'webbrowser_go_foreward') 926 self.forwardAct.setStatusTip(self.tr( 927 'Move one screen forward')) 928 self.forwardAct.setWhatsThis(self.tr( 929 """<b>Forward</b>""" 930 """<p>Moves one screen forward. If none is""" 931 """ available, this action is disabled.</p>""" 932 )) 933 self.forwardAct.triggered.connect(self.__forward) 934 self.__actions.append(self.forwardAct) 935 936 self.homeAct = E5Action( 937 self.tr('Home'), 938 UI.PixmapCache.getIcon("home"), 939 self.tr('&Home'), 940 QKeySequence(self.tr("Ctrl+Home", "Go|Home")), 941 0, self, 'webbrowser_go_home') 942 self.homeAct.setStatusTip(self.tr( 943 'Move to the initial screen')) 944 self.homeAct.setWhatsThis(self.tr( 945 """<b>Home</b>""" 946 """<p>Moves to the initial screen.</p>""" 947 )) 948 self.homeAct.triggered.connect(self.__home) 949 self.__actions.append(self.homeAct) 950 951 self.reloadAct = E5Action( 952 self.tr('Reload'), 953 UI.PixmapCache.getIcon("reload"), 954 self.tr('&Reload'), 955 QKeySequence(self.tr("Ctrl+R", "Go|Reload")), 956 QKeySequence(self.tr("F5", "Go|Reload")), 957 self, 'webbrowser_go_reload') 958 self.reloadAct.setStatusTip(self.tr( 959 'Reload the current screen')) 960 self.reloadAct.setWhatsThis(self.tr( 961 """<b>Reload</b>""" 962 """<p>Reloads the current screen.</p>""" 963 )) 964 self.reloadAct.triggered.connect(self.__reload) 965 self.__actions.append(self.reloadAct) 966 967 self.stopAct = E5Action( 968 self.tr('Stop'), 969 UI.PixmapCache.getIcon("stopLoading"), 970 self.tr('&Stop'), 971 QKeySequence(self.tr("Ctrl+.", "Go|Stop")), 972 QKeySequence(self.tr("Esc", "Go|Stop")), 973 self, 'webbrowser_go_stop') 974 self.stopAct.setStatusTip(self.tr('Stop loading')) 975 self.stopAct.setWhatsThis(self.tr( 976 """<b>Stop</b>""" 977 """<p>Stops loading of the current tab.</p>""" 978 )) 979 self.stopAct.triggered.connect(self.__stopLoading) 980 self.__actions.append(self.stopAct) 981 982 self.copyAct = E5Action( 983 self.tr('Copy'), 984 UI.PixmapCache.getIcon("editCopy"), 985 self.tr('&Copy'), 986 QKeySequence(self.tr("Ctrl+C", "Edit|Copy")), 987 0, self, 'webbrowser_edit_copy') 988 self.copyAct.setStatusTip(self.tr('Copy the selected text')) 989 self.copyAct.setWhatsThis(self.tr( 990 """<b>Copy</b>""" 991 """<p>Copy the selected text to the clipboard.</p>""" 992 )) 993 self.copyAct.triggered.connect(self.__copy) 994 self.__actions.append(self.copyAct) 995 996 self.cutAct = E5Action( 997 self.tr('Cut'), 998 UI.PixmapCache.getIcon("editCut"), 999 self.tr('Cu&t'), 1000 QKeySequence(self.tr("Ctrl+X", "Edit|Cut")), 1001 0, self, 'webbrowser_edit_cut') 1002 self.cutAct.setStatusTip(self.tr('Cut the selected text')) 1003 self.cutAct.setWhatsThis(self.tr( 1004 """<b>Cut</b>""" 1005 """<p>Cut the selected text to the clipboard.</p>""" 1006 )) 1007 self.cutAct.triggered.connect(self.__cut) 1008 self.__actions.append(self.cutAct) 1009 1010 self.pasteAct = E5Action( 1011 self.tr('Paste'), 1012 UI.PixmapCache.getIcon("editPaste"), 1013 self.tr('&Paste'), 1014 QKeySequence(self.tr("Ctrl+V", "Edit|Paste")), 1015 0, self, 'webbrowser_edit_paste') 1016 self.pasteAct.setStatusTip(self.tr('Paste text from the clipboard')) 1017 self.pasteAct.setWhatsThis(self.tr( 1018 """<b>Paste</b>""" 1019 """<p>Paste some text from the clipboard.</p>""" 1020 )) 1021 self.pasteAct.triggered.connect(self.__paste) 1022 self.__actions.append(self.pasteAct) 1023 1024 self.undoAct = E5Action( 1025 self.tr('Undo'), 1026 UI.PixmapCache.getIcon("editUndo"), 1027 self.tr('&Undo'), 1028 QKeySequence(self.tr("Ctrl+Z", "Edit|Undo")), 1029 0, self, 'webbrowser_edit_undo') 1030 self.undoAct.setStatusTip(self.tr('Undo the last edit action')) 1031 self.undoAct.setWhatsThis(self.tr( 1032 """<b>Undo</b>""" 1033 """<p>Undo the last edit action.</p>""" 1034 )) 1035 self.undoAct.triggered.connect(self.__undo) 1036 self.__actions.append(self.undoAct) 1037 1038 self.redoAct = E5Action( 1039 self.tr('Redo'), 1040 UI.PixmapCache.getIcon("editRedo"), 1041 self.tr('&Redo'), 1042 QKeySequence(self.tr("Ctrl+Shift+Z", "Edit|Redo")), 1043 0, self, 'webbrowser_edit_redo') 1044 self.redoAct.setStatusTip(self.tr('Redo the last edit action')) 1045 self.redoAct.setWhatsThis(self.tr( 1046 """<b>Redo</b>""" 1047 """<p>Redo the last edit action.</p>""" 1048 )) 1049 self.redoAct.triggered.connect(self.__redo) 1050 self.__actions.append(self.redoAct) 1051 1052 self.selectAllAct = E5Action( 1053 self.tr('Select All'), 1054 UI.PixmapCache.getIcon("editSelectAll"), 1055 self.tr('&Select All'), 1056 QKeySequence(self.tr("Ctrl+A", "Edit|Select All")), 1057 0, self, 'webbrowser_edit_select_all') 1058 self.selectAllAct.setStatusTip(self.tr('Select all text')) 1059 self.selectAllAct.setWhatsThis(self.tr( 1060 """<b>Select All</b>""" 1061 """<p>Select all text of the current browser.</p>""" 1062 )) 1063 self.selectAllAct.triggered.connect(self.__selectAll) 1064 self.__actions.append(self.selectAllAct) 1065 1066 self.unselectAct = E5Action( 1067 self.tr('Unselect'), 1068 self.tr('Unselect'), 1069 QKeySequence(self.tr("Alt+Ctrl+A", "Edit|Unselect")), 1070 0, self, 'webbrowser_edit_unselect') 1071 self.unselectAct.setStatusTip(self.tr('Clear current selection')) 1072 self.unselectAct.setWhatsThis(self.tr( 1073 """<b>Unselect</b>""" 1074 """<p>Clear the selection of the current browser.</p>""" 1075 )) 1076 self.unselectAct.triggered.connect(self.__unselect) 1077 self.__actions.append(self.unselectAct) 1078 1079 self.findAct = E5Action( 1080 self.tr('Find...'), 1081 UI.PixmapCache.getIcon("find"), 1082 self.tr('&Find...'), 1083 QKeySequence(self.tr("Ctrl+F", "Edit|Find")), 1084 0, self, 'webbrowser_edit_find') 1085 self.findAct.setStatusTip(self.tr('Find text in page')) 1086 self.findAct.setWhatsThis(self.tr( 1087 """<b>Find</b>""" 1088 """<p>Find text in the current page.</p>""" 1089 )) 1090 self.findAct.triggered.connect(self.__find) 1091 self.__actions.append(self.findAct) 1092 1093 self.findNextAct = E5Action( 1094 self.tr('Find next'), 1095 UI.PixmapCache.getIcon("findNext"), 1096 self.tr('Find &next'), 1097 QKeySequence(self.tr("F3", "Edit|Find next")), 1098 0, self, 'webbrowser_edit_find_next') 1099 self.findNextAct.setStatusTip(self.tr( 1100 'Find next occurrence of text in page')) 1101 self.findNextAct.setWhatsThis(self.tr( 1102 """<b>Find next</b>""" 1103 """<p>Find the next occurrence of text in the current page.</p>""" 1104 )) 1105 self.findNextAct.triggered.connect(self.__searchWidget.findNext) 1106 self.__actions.append(self.findNextAct) 1107 1108 self.findPrevAct = E5Action( 1109 self.tr('Find previous'), 1110 UI.PixmapCache.getIcon("findPrev"), 1111 self.tr('Find &previous'), 1112 QKeySequence(self.tr("Shift+F3", "Edit|Find previous")), 1113 0, self, 'webbrowser_edit_find_previous') 1114 self.findPrevAct.setStatusTip( 1115 self.tr('Find previous occurrence of text in page')) 1116 self.findPrevAct.setWhatsThis(self.tr( 1117 """<b>Find previous</b>""" 1118 """<p>Find the previous occurrence of text in the current""" 1119 """ page.</p>""" 1120 )) 1121 self.findPrevAct.triggered.connect( 1122 self.__searchWidget.findPrevious) 1123 self.__actions.append(self.findPrevAct) 1124 1125 self.bookmarksManageAct = E5Action( 1126 self.tr('Manage Bookmarks'), 1127 self.tr('&Manage Bookmarks...'), 1128 QKeySequence(self.tr("Ctrl+Shift+B", "Help|Manage bookmarks")), 1129 0, self, 'webbrowser_bookmarks_manage') 1130 self.bookmarksManageAct.setStatusTip(self.tr( 1131 'Open a dialog to manage the bookmarks.')) 1132 self.bookmarksManageAct.setWhatsThis(self.tr( 1133 """<b>Manage Bookmarks...</b>""" 1134 """<p>Open a dialog to manage the bookmarks.</p>""" 1135 )) 1136 self.bookmarksManageAct.triggered.connect( 1137 self.__showBookmarksDialog) 1138 self.__actions.append(self.bookmarksManageAct) 1139 1140 self.bookmarksAddAct = E5Action( 1141 self.tr('Add Bookmark'), 1142 UI.PixmapCache.getIcon("addBookmark"), 1143 self.tr('Add &Bookmark...'), 1144 QKeySequence(self.tr("Ctrl+D", "Help|Add bookmark")), 1145 0, self, 'webbrowser_bookmark_add') 1146 self.bookmarksAddAct.setIconVisibleInMenu(False) 1147 self.bookmarksAddAct.setStatusTip(self.tr( 1148 'Open a dialog to add a bookmark.')) 1149 self.bookmarksAddAct.setWhatsThis(self.tr( 1150 """<b>Add Bookmark</b>""" 1151 """<p>Open a dialog to add the current URL as a bookmark.</p>""" 1152 )) 1153 self.bookmarksAddAct.triggered.connect(self.__addBookmark) 1154 self.__actions.append(self.bookmarksAddAct) 1155 1156 self.bookmarksAddFolderAct = E5Action( 1157 self.tr('Add Folder'), 1158 self.tr('Add &Folder...'), 1159 0, 0, self, 'webbrowser_bookmark_show_all') 1160 self.bookmarksAddFolderAct.setStatusTip(self.tr( 1161 'Open a dialog to add a new bookmarks folder.')) 1162 self.bookmarksAddFolderAct.setWhatsThis(self.tr( 1163 """<b>Add Folder...</b>""" 1164 """<p>Open a dialog to add a new bookmarks folder.</p>""" 1165 )) 1166 self.bookmarksAddFolderAct.triggered.connect( 1167 self.__addBookmarkFolder) 1168 self.__actions.append(self.bookmarksAddFolderAct) 1169 1170 self.bookmarksAllTabsAct = E5Action( 1171 self.tr('Bookmark All Tabs'), 1172 self.tr('Bookmark All Tabs...'), 1173 0, 0, self, 'webbrowser_bookmark_all_tabs') 1174 self.bookmarksAllTabsAct.setStatusTip(self.tr( 1175 'Bookmark all open tabs.')) 1176 self.bookmarksAllTabsAct.setWhatsThis(self.tr( 1177 """<b>Bookmark All Tabs...</b>""" 1178 """<p>Open a dialog to add a new bookmarks folder for""" 1179 """ all open tabs.</p>""" 1180 )) 1181 self.bookmarksAllTabsAct.triggered.connect(self.bookmarkAll) 1182 self.__actions.append(self.bookmarksAllTabsAct) 1183 1184 self.whatsThisAct = E5Action( 1185 self.tr('What\'s This?'), 1186 UI.PixmapCache.getIcon("whatsThis"), 1187 self.tr('&What\'s This?'), 1188 QKeySequence(self.tr("Shift+F1", "Help|What's This?'")), 1189 0, self, 'webbrowser_help_whats_this') 1190 self.whatsThisAct.setStatusTip(self.tr('Context sensitive help')) 1191 self.whatsThisAct.setWhatsThis(self.tr( 1192 """<b>Display context sensitive help</b>""" 1193 """<p>In What's This? mode, the mouse cursor shows an arrow""" 1194 """ with a question mark, and you can click on the interface""" 1195 """ elements to get a short description of what they do and how""" 1196 """ to use them. In dialogs, this feature can be accessed using""" 1197 """ the context help button in the titlebar.</p>""" 1198 )) 1199 self.whatsThisAct.triggered.connect(self.__whatsThis) 1200 self.__actions.append(self.whatsThisAct) 1201 1202 self.aboutAct = E5Action( 1203 self.tr('About'), 1204 self.tr('&About'), 1205 0, 0, self, 'webbrowser_help_about') 1206 self.aboutAct.setStatusTip(self.tr( 1207 'Display information about this software')) 1208 self.aboutAct.setWhatsThis(self.tr( 1209 """<b>About</b>""" 1210 """<p>Display some information about this software.</p>""" 1211 )) 1212 self.aboutAct.triggered.connect(self.__about) 1213 self.__actions.append(self.aboutAct) 1214 1215 self.aboutQtAct = E5Action( 1216 self.tr('About Qt'), 1217 self.tr('About &Qt'), 1218 0, 0, self, 'webbrowser_help_about_qt') 1219 self.aboutQtAct.setStatusTip( 1220 self.tr('Display information about the Qt toolkit')) 1221 self.aboutQtAct.setWhatsThis(self.tr( 1222 """<b>About Qt</b>""" 1223 """<p>Display some information about the Qt toolkit.</p>""" 1224 )) 1225 self.aboutQtAct.triggered.connect(self.__aboutQt) 1226 self.__actions.append(self.aboutQtAct) 1227 1228 self.zoomInAct = E5Action( 1229 self.tr('Zoom in'), 1230 UI.PixmapCache.getIcon("zoomIn"), 1231 self.tr('Zoom &in'), 1232 QKeySequence(self.tr("Ctrl++", "View|Zoom in")), 1233 QKeySequence(self.tr("Zoom In", "View|Zoom in")), 1234 self, 'webbrowser_view_zoom_in') 1235 self.zoomInAct.setStatusTip(self.tr('Zoom in on the web page')) 1236 self.zoomInAct.setWhatsThis(self.tr( 1237 """<b>Zoom in</b>""" 1238 """<p>Zoom in on the web page.""" 1239 """ This makes the web page bigger.</p>""" 1240 )) 1241 self.zoomInAct.triggered.connect(self.__zoomIn) 1242 self.__actions.append(self.zoomInAct) 1243 1244 self.zoomOutAct = E5Action( 1245 self.tr('Zoom out'), 1246 UI.PixmapCache.getIcon("zoomOut"), 1247 self.tr('Zoom &out'), 1248 QKeySequence(self.tr("Ctrl+-", "View|Zoom out")), 1249 QKeySequence(self.tr("Zoom Out", "View|Zoom out")), 1250 self, 'webbrowser_view_zoom_out') 1251 self.zoomOutAct.setStatusTip(self.tr('Zoom out on the web page')) 1252 self.zoomOutAct.setWhatsThis(self.tr( 1253 """<b>Zoom out</b>""" 1254 """<p>Zoom out on the web page.""" 1255 """ This makes the web page smaller.</p>""" 1256 )) 1257 self.zoomOutAct.triggered.connect(self.__zoomOut) 1258 self.__actions.append(self.zoomOutAct) 1259 1260 self.zoomResetAct = E5Action( 1261 self.tr('Zoom reset'), 1262 UI.PixmapCache.getIcon("zoomReset"), 1263 self.tr('Zoom &reset'), 1264 QKeySequence(self.tr("Ctrl+0", "View|Zoom reset")), 1265 0, self, 'webbrowser_view_zoom_reset') 1266 self.zoomResetAct.setStatusTip(self.tr( 1267 'Reset the zoom of the web page')) 1268 self.zoomResetAct.setWhatsThis(self.tr( 1269 """<b>Zoom reset</b>""" 1270 """<p>Reset the zoom of the web page. """ 1271 """This sets the zoom factor to 100%.</p>""" 1272 )) 1273 self.zoomResetAct.triggered.connect(self.__zoomReset) 1274 self.__actions.append(self.zoomResetAct) 1275 1276 self.pageSourceAct = E5Action( 1277 self.tr('Show page source'), 1278 self.tr('Show page source'), 1279 QKeySequence(self.tr('Ctrl+U')), 0, 1280 self, 'webbrowser_show_page_source') 1281 self.pageSourceAct.setStatusTip(self.tr( 1282 'Show the page source in an editor')) 1283 self.pageSourceAct.setWhatsThis(self.tr( 1284 """<b>Show page source</b>""" 1285 """<p>Show the page source in an editor.</p>""" 1286 )) 1287 self.pageSourceAct.triggered.connect(self.__showPageSource) 1288 self.__actions.append(self.pageSourceAct) 1289 self.addAction(self.pageSourceAct) 1290 1291 self.fullScreenAct = E5Action( 1292 self.tr('Full Screen'), 1293 UI.PixmapCache.getIcon("windowFullscreen"), 1294 self.tr('&Full Screen'), 1295 0, 0, 1296 self, 'webbrowser_view_full_screen') 1297 if Globals.isMacPlatform(): 1298 self.fullScreenAct.setShortcut( 1299 QKeySequence(self.tr("Meta+Ctrl+F"))) 1300 else: 1301 self.fullScreenAct.setShortcut(QKeySequence(self.tr('F11'))) 1302 self.fullScreenAct.triggered.connect(self.toggleFullScreen) 1303 self.__actions.append(self.fullScreenAct) 1304 self.addAction(self.fullScreenAct) 1305 1306 self.nextTabAct = E5Action( 1307 self.tr('Show next tab'), 1308 self.tr('Show next tab'), 1309 QKeySequence(self.tr('Ctrl+Alt+Tab')), 0, 1310 self, 'webbrowser_view_next_tab') 1311 self.nextTabAct.triggered.connect(self.__nextTab) 1312 self.__actions.append(self.nextTabAct) 1313 self.addAction(self.nextTabAct) 1314 1315 self.prevTabAct = E5Action( 1316 self.tr('Show previous tab'), 1317 self.tr('Show previous tab'), 1318 QKeySequence(self.tr('Shift+Ctrl+Alt+Tab')), 0, 1319 self, 'webbrowser_view_previous_tab') 1320 self.prevTabAct.triggered.connect(self.__prevTab) 1321 self.__actions.append(self.prevTabAct) 1322 self.addAction(self.prevTabAct) 1323 1324 self.switchTabAct = E5Action( 1325 self.tr('Switch between tabs'), 1326 self.tr('Switch between tabs'), 1327 QKeySequence(self.tr('Ctrl+1')), 0, 1328 self, 'webbrowser_switch_tabs') 1329 self.switchTabAct.triggered.connect(self.__switchTab) 1330 self.__actions.append(self.switchTabAct) 1331 self.addAction(self.switchTabAct) 1332 1333 self.prefAct = E5Action( 1334 self.tr('Preferences'), 1335 UI.PixmapCache.getIcon("configure"), 1336 self.tr('&Preferences...'), 0, 0, self, 'webbrowser_preferences') 1337 self.prefAct.setStatusTip(self.tr( 1338 'Set the prefered configuration')) 1339 self.prefAct.setWhatsThis(self.tr( 1340 """<b>Preferences</b>""" 1341 """<p>Set the configuration items of the application""" 1342 """ with your prefered values.</p>""" 1343 )) 1344 self.prefAct.triggered.connect(self.__showPreferences) 1345 self.__actions.append(self.prefAct) 1346 1347 self.acceptedLanguagesAct = E5Action( 1348 self.tr('Languages'), 1349 UI.PixmapCache.getIcon("flag"), 1350 self.tr('&Languages...'), 0, 0, 1351 self, 'webbrowser_accepted_languages') 1352 self.acceptedLanguagesAct.setStatusTip(self.tr( 1353 'Configure the accepted languages for web pages')) 1354 self.acceptedLanguagesAct.setWhatsThis(self.tr( 1355 """<b>Languages</b>""" 1356 """<p>Configure the accepted languages for web pages.</p>""" 1357 )) 1358 self.acceptedLanguagesAct.triggered.connect( 1359 self.__showAcceptedLanguages) 1360 self.__actions.append(self.acceptedLanguagesAct) 1361 1362 self.cookiesAct = E5Action( 1363 self.tr('Cookies'), 1364 UI.PixmapCache.getIcon("cookie"), 1365 self.tr('C&ookies...'), 0, 0, self, 'webbrowser_cookies') 1366 self.cookiesAct.setStatusTip(self.tr( 1367 'Configure cookies handling')) 1368 self.cookiesAct.setWhatsThis(self.tr( 1369 """<b>Cookies</b>""" 1370 """<p>Configure cookies handling.</p>""" 1371 )) 1372 self.cookiesAct.triggered.connect( 1373 self.__showCookiesConfiguration) 1374 self.__actions.append(self.cookiesAct) 1375 1376 self.personalDataAct = E5Action( 1377 self.tr('Personal Information'), 1378 UI.PixmapCache.getIcon("pim"), 1379 self.tr('Personal Information...'), 1380 0, 0, 1381 self, 'webbrowser_personal_information') 1382 self.personalDataAct.setStatusTip(self.tr( 1383 'Configure personal information for completing form fields')) 1384 self.personalDataAct.setWhatsThis(self.tr( 1385 """<b>Personal Information...</b>""" 1386 """<p>Opens a dialog to configure the personal information""" 1387 """ used for completing form fields.</p>""" 1388 )) 1389 self.personalDataAct.triggered.connect( 1390 self.__showPersonalInformationDialog) 1391 self.__actions.append(self.personalDataAct) 1392 1393 self.greaseMonkeyAct = E5Action( 1394 self.tr('GreaseMonkey Scripts'), 1395 UI.PixmapCache.getIcon("greaseMonkey"), 1396 self.tr('GreaseMonkey Scripts...'), 1397 0, 0, 1398 self, 'webbrowser_greasemonkey') 1399 self.greaseMonkeyAct.setStatusTip(self.tr( 1400 'Configure the GreaseMonkey Scripts')) 1401 self.greaseMonkeyAct.setWhatsThis(self.tr( 1402 """<b>GreaseMonkey Scripts...</b>""" 1403 """<p>Opens a dialog to configure the available GreaseMonkey""" 1404 """ Scripts.</p>""" 1405 )) 1406 self.greaseMonkeyAct.triggered.connect( 1407 self.__showGreaseMonkeyConfigDialog) 1408 self.__actions.append(self.greaseMonkeyAct) 1409 1410 self.editMessageFilterAct = E5Action( 1411 self.tr('Edit Message Filters'), 1412 UI.PixmapCache.getIcon("warning"), 1413 self.tr('Edit Message Filters...'), 0, 0, self, 1414 'webbrowser_manage_message_filters') 1415 self.editMessageFilterAct.setStatusTip(self.tr( 1416 'Edit the message filters used to suppress unwanted messages')) 1417 self.editMessageFilterAct.setWhatsThis(self.tr( 1418 """<b>Edit Message Filters</b>""" 1419 """<p>Opens a dialog to edit the message filters used to""" 1420 """ suppress unwanted messages been shown in an error""" 1421 """ window.</p>""" 1422 )) 1423 self.editMessageFilterAct.triggered.connect( 1424 E5ErrorMessage.editMessageFilters) 1425 self.__actions.append(self.editMessageFilterAct) 1426 1427 self.featurePermissionAct = E5Action( 1428 self.tr('Edit HTML5 Feature Permissions'), 1429 UI.PixmapCache.getIcon("featurePermission"), 1430 self.tr('Edit HTML5 Feature Permissions...'), 0, 0, self, 1431 'webbrowser_edit_feature_permissions') 1432 self.featurePermissionAct.setStatusTip(self.tr( 1433 'Edit the remembered HTML5 feature permissions')) 1434 self.featurePermissionAct.setWhatsThis(self.tr( 1435 """<b>Edit HTML5 Feature Permissions</b>""" 1436 """<p>Opens a dialog to edit the remembered HTML5""" 1437 """ feature permissions.</p>""" 1438 )) 1439 self.featurePermissionAct.triggered.connect( 1440 self.__showFeaturePermissionDialog) 1441 self.__actions.append(self.featurePermissionAct) 1442 1443 if WebBrowserWindow._useQtHelp: 1444 self.syncTocAct = E5Action( 1445 self.tr('Sync with Table of Contents'), 1446 UI.PixmapCache.getIcon("syncToc"), 1447 self.tr('Sync with Table of Contents'), 1448 0, 0, self, 'webbrowser_sync_toc') 1449 self.syncTocAct.setStatusTip(self.tr( 1450 'Synchronizes the table of contents with current page')) 1451 self.syncTocAct.setWhatsThis(self.tr( 1452 """<b>Sync with Table of Contents</b>""" 1453 """<p>Synchronizes the table of contents with current""" 1454 """ page.</p>""" 1455 )) 1456 self.syncTocAct.triggered.connect(self.__syncTOC) 1457 self.__actions.append(self.syncTocAct) 1458 1459 self.showTocAct = E5Action( 1460 self.tr('Table of Contents'), 1461 self.tr('Table of Contents'), 1462 0, 0, self, 'webbrowser_show_toc') 1463 self.showTocAct.setStatusTip(self.tr( 1464 'Shows the table of contents window')) 1465 self.showTocAct.setWhatsThis(self.tr( 1466 """<b>Table of Contents</b>""" 1467 """<p>Shows the table of contents window.</p>""" 1468 )) 1469 self.showTocAct.triggered.connect(self.__showTocWindow) 1470 self.__actions.append(self.showTocAct) 1471 1472 self.showIndexAct = E5Action( 1473 self.tr('Index'), 1474 self.tr('Index'), 1475 0, 0, self, 'webbrowser_show_index') 1476 self.showIndexAct.setStatusTip(self.tr( 1477 'Shows the index window')) 1478 self.showIndexAct.setWhatsThis(self.tr( 1479 """<b>Index</b>""" 1480 """<p>Shows the index window.</p>""" 1481 )) 1482 self.showIndexAct.triggered.connect(self.__showIndexWindow) 1483 self.__actions.append(self.showIndexAct) 1484 1485 self.showSearchAct = E5Action( 1486 self.tr('Search'), 1487 self.tr('Search'), 1488 0, 0, self, 'webbrowser_show_search') 1489 self.showSearchAct.setStatusTip(self.tr( 1490 'Shows the search window')) 1491 self.showSearchAct.setWhatsThis(self.tr( 1492 """<b>Search</b>""" 1493 """<p>Shows the search window.</p>""" 1494 )) 1495 self.showSearchAct.triggered.connect( 1496 self.__showSearchWindow) 1497 self.__actions.append(self.showSearchAct) 1498 1499 self.manageQtHelpDocsAct = E5Action( 1500 self.tr('Manage QtHelp Documents'), 1501 self.tr('Manage QtHelp &Documents'), 1502 0, 0, self, 'webbrowser_qthelp_documents') 1503 self.manageQtHelpDocsAct.setStatusTip(self.tr( 1504 'Shows a dialog to manage the QtHelp documentation set')) 1505 self.manageQtHelpDocsAct.setWhatsThis(self.tr( 1506 """<b>Manage QtHelp Documents</b>""" 1507 """<p>Shows a dialog to manage the QtHelp documentation""" 1508 """ set.</p>""" 1509 )) 1510 self.manageQtHelpDocsAct.triggered.connect( 1511 self.__manageQtHelpDocumentation) 1512 self.__actions.append(self.manageQtHelpDocsAct) 1513 1514 self.reindexDocumentationAct = E5Action( 1515 self.tr('Reindex Documentation'), 1516 self.tr('&Reindex Documentation'), 1517 0, 0, self, 'webbrowser_qthelp_reindex') 1518 self.reindexDocumentationAct.setStatusTip(self.tr( 1519 'Reindexes the documentation set')) 1520 self.reindexDocumentationAct.setWhatsThis(self.tr( 1521 """<b>Reindex Documentation</b>""" 1522 """<p>Reindexes the documentation set.</p>""" 1523 )) 1524 self.reindexDocumentationAct.triggered.connect( 1525 self.__searchEngine.reindexDocumentation) 1526 self.__actions.append(self.reindexDocumentationAct) 1527 1528 self.clearPrivateDataAct = E5Action( 1529 self.tr('Clear private data'), 1530 UI.PixmapCache.getIcon("clearPrivateData"), 1531 self.tr('Clear private data'), 1532 0, 0, 1533 self, 'webbrowser_clear_private_data') 1534 self.clearPrivateDataAct.setStatusTip(self.tr( 1535 'Clear private data')) 1536 self.clearPrivateDataAct.setWhatsThis(self.tr( 1537 """<b>Clear private data</b>""" 1538 """<p>Clears the private data like browsing history, search""" 1539 """ history or the favicons database.</p>""" 1540 )) 1541 self.clearPrivateDataAct.triggered.connect( 1542 self.__clearPrivateData) 1543 self.__actions.append(self.clearPrivateDataAct) 1544 1545 self.clearIconsAct = E5Action( 1546 self.tr('Clear icons database'), 1547 self.tr('Clear &icons database'), 1548 0, 0, 1549 self, 'webbrowser_clear_icons_db') 1550 self.clearIconsAct.setStatusTip(self.tr( 1551 'Clear the database of favicons')) 1552 self.clearIconsAct.setWhatsThis(self.tr( 1553 """<b>Clear icons database</b>""" 1554 """<p>Clears the database of favicons of previously visited""" 1555 """ URLs.</p>""" 1556 )) 1557 self.clearIconsAct.triggered.connect(self.__clearIconsDatabase) 1558 self.__actions.append(self.clearIconsAct) 1559 1560 self.manageIconsAct = E5Action( 1561 self.tr('Manage saved Favicons'), 1562 UI.PixmapCache.getIcon("icons"), 1563 self.tr('Manage saved Favicons'), 1564 0, 0, 1565 self, 'webbrowser_manage_icons_db') 1566 self.manageIconsAct.setStatusTip(self.tr( 1567 'Show a dialog to manage the saved favicons')) 1568 self.manageIconsAct.setWhatsThis(self.tr( 1569 """<b>Manage saved Favicons</b>""" 1570 """<p>This shows a dialog to manage the saved favicons of""" 1571 """ previously visited URLs.</p>""" 1572 )) 1573 self.manageIconsAct.triggered.connect(self.__showWebIconsDialog) 1574 self.__actions.append(self.manageIconsAct) 1575 1576 self.searchEnginesAct = E5Action( 1577 self.tr('Configure Search Engines'), 1578 self.tr('Configure Search &Engines...'), 1579 0, 0, 1580 self, 'webbrowser_search_engines') 1581 self.searchEnginesAct.setStatusTip(self.tr( 1582 'Configure the available search engines')) 1583 self.searchEnginesAct.setWhatsThis(self.tr( 1584 """<b>Configure Search Engines...</b>""" 1585 """<p>Opens a dialog to configure the available search""" 1586 """ engines.</p>""" 1587 )) 1588 self.searchEnginesAct.triggered.connect( 1589 self.__showEnginesConfigurationDialog) 1590 self.__actions.append(self.searchEnginesAct) 1591 1592 self.passwordsAct = E5Action( 1593 self.tr('Manage Saved Passwords'), 1594 UI.PixmapCache.getIcon("passwords"), 1595 self.tr('Manage Saved Passwords...'), 1596 0, 0, 1597 self, 'webbrowser_manage_passwords') 1598 self.passwordsAct.setStatusTip(self.tr( 1599 'Manage the saved passwords')) 1600 self.passwordsAct.setWhatsThis(self.tr( 1601 """<b>Manage Saved Passwords...</b>""" 1602 """<p>Opens a dialog to manage the saved passwords.</p>""" 1603 )) 1604 self.passwordsAct.triggered.connect(self.__showPasswordsDialog) 1605 self.__actions.append(self.passwordsAct) 1606 1607 self.adblockAct = E5Action( 1608 self.tr('Ad Block'), 1609 UI.PixmapCache.getIcon("adBlockPlus"), 1610 self.tr('&Ad Block...'), 1611 0, 0, 1612 self, 'webbrowser_adblock') 1613 self.adblockAct.setStatusTip(self.tr( 1614 'Configure AdBlock subscriptions and rules')) 1615 self.adblockAct.setWhatsThis(self.tr( 1616 """<b>Ad Block...</b>""" 1617 """<p>Opens a dialog to configure AdBlock subscriptions and""" 1618 """ rules.</p>""" 1619 )) 1620 self.adblockAct.triggered.connect(self.__showAdBlockDialog) 1621 self.__actions.append(self.adblockAct) 1622 1623 self.certificateErrorsAct = E5Action( 1624 self.tr('Manage SSL Certificate Errors'), 1625 UI.PixmapCache.getIcon("certificates"), 1626 self.tr('Manage SSL Certificate Errors...'), 1627 0, 0, 1628 self, 'webbrowser_manage_certificate_errors') 1629 self.certificateErrorsAct.setStatusTip(self.tr( 1630 'Manage the accepted SSL certificate Errors')) 1631 self.certificateErrorsAct.setWhatsThis(self.tr( 1632 """<b>Manage SSL Certificate Errors...</b>""" 1633 """<p>Opens a dialog to manage the accepted SSL""" 1634 """ certificate errors.</p>""" 1635 )) 1636 self.certificateErrorsAct.triggered.connect( 1637 self.__showCertificateErrorsDialog) 1638 self.__actions.append(self.certificateErrorsAct) 1639 1640 self.safeBrowsingAct = E5Action( 1641 self.tr('Manage Safe Browsing'), 1642 UI.PixmapCache.getIcon("safeBrowsing"), 1643 self.tr('Manage Safe Browsing...'), 0, 0, self, 1644 'webbrowser_manage_safe_browsing') 1645 self.safeBrowsingAct.setStatusTip(self.tr( 1646 'Configure Safe Browsing and manage local cache')) 1647 self.safeBrowsingAct.setWhatsThis(self.tr( 1648 """<b>Manage Safe Browsing</b>""" 1649 """<p>This opens a dialog to configure Safe Browsing and""" 1650 """ to manage the local cache.</p>""" 1651 )) 1652 self.safeBrowsingAct.triggered.connect( 1653 self.__showSafeBrowsingDialog) 1654 self.__actions.append(self.safeBrowsingAct) 1655 1656 self.showDownloadManagerAct = E5Action( 1657 self.tr('Downloads'), 1658 self.tr('Downloads'), 1659 0, 0, self, 'webbrowser_show_downloads') 1660 self.showDownloadManagerAct.setStatusTip(self.tr( 1661 'Shows the downloads window')) 1662 self.showDownloadManagerAct.setWhatsThis(self.tr( 1663 """<b>Downloads</b>""" 1664 """<p>Shows the downloads window.</p>""" 1665 )) 1666 self.showDownloadManagerAct.triggered.connect( 1667 self.__showDownloadsWindow) 1668 self.__actions.append(self.showDownloadManagerAct) 1669 1670 self.feedsManagerAct = E5Action( 1671 self.tr('RSS Feeds Dialog'), 1672 UI.PixmapCache.getIcon("rss22"), 1673 self.tr('&RSS Feeds Dialog...'), 1674 QKeySequence(self.tr("Ctrl+Shift+F", "Help|RSS Feeds Dialog")), 1675 0, self, 'webbrowser_rss_feeds') 1676 self.feedsManagerAct.setStatusTip(self.tr( 1677 'Open a dialog showing the configured RSS feeds.')) 1678 self.feedsManagerAct.setWhatsThis(self.tr( 1679 """<b>RSS Feeds Dialog...</b>""" 1680 """<p>Open a dialog to show the configured RSS feeds.""" 1681 """ It can be used to mange the feeds and to show their""" 1682 """ contents.</p>""" 1683 )) 1684 self.feedsManagerAct.triggered.connect(self.__showFeedsManager) 1685 self.__actions.append(self.feedsManagerAct) 1686 1687 self.siteInfoAct = E5Action( 1688 self.tr('Siteinfo Dialog'), 1689 UI.PixmapCache.getIcon("helpAbout"), 1690 self.tr('&Siteinfo Dialog...'), 1691 QKeySequence(self.tr("Ctrl+Shift+I", "Help|Siteinfo Dialog")), 1692 0, self, 'webbrowser_siteinfo') 1693 self.siteInfoAct.setStatusTip(self.tr( 1694 'Open a dialog showing some information about the current site.')) 1695 self.siteInfoAct.setWhatsThis(self.tr( 1696 """<b>Siteinfo Dialog...</b>""" 1697 """<p>Opens a dialog showing some information about the current""" 1698 """ site.</p>""" 1699 )) 1700 self.siteInfoAct.triggered.connect(self.__showSiteinfoDialog) 1701 self.__actions.append(self.siteInfoAct) 1702 1703 self.userAgentManagerAct = E5Action( 1704 self.tr('Manage User Agent Settings'), 1705 self.tr('Manage &User Agent Settings'), 1706 0, 0, self, 'webbrowser_user_agent_settings') 1707 self.userAgentManagerAct.setStatusTip(self.tr( 1708 'Shows a dialog to manage the User Agent settings')) 1709 self.userAgentManagerAct.setWhatsThis(self.tr( 1710 """<b>Manage User Agent Settings</b>""" 1711 """<p>Shows a dialog to manage the User Agent settings.</p>""" 1712 )) 1713 self.userAgentManagerAct.triggered.connect( 1714 self.__showUserAgentsDialog) 1715 self.__actions.append(self.userAgentManagerAct) 1716 1717 self.synchronizationAct = E5Action( 1718 self.tr('Synchronize data'), 1719 UI.PixmapCache.getIcon("sync"), 1720 self.tr('&Synchronize Data...'), 1721 0, 0, self, 'webbrowser_synchronize_data') 1722 self.synchronizationAct.setStatusTip(self.tr( 1723 'Shows a dialog to synchronize data via the network')) 1724 self.synchronizationAct.setWhatsThis(self.tr( 1725 """<b>Synchronize Data...</b>""" 1726 """<p>This shows a dialog to synchronize data via the""" 1727 """ network.</p>""" 1728 )) 1729 self.synchronizationAct.triggered.connect( 1730 self.__showSyncDialog) 1731 self.__actions.append(self.synchronizationAct) 1732 1733 self.zoomValuesAct = E5Action( 1734 self.tr('Manage Saved Zoom Values'), 1735 UI.PixmapCache.getIcon("zoomReset"), 1736 self.tr('Manage Saved Zoom Values...'), 1737 0, 0, 1738 self, 'webbrowser_manage_zoom_values') 1739 self.zoomValuesAct.setStatusTip(self.tr( 1740 'Manage the saved zoom values')) 1741 self.zoomValuesAct.setWhatsThis(self.tr( 1742 """<b>Manage Saved Zoom Values...</b>""" 1743 """<p>Opens a dialog to manage the saved zoom values.</p>""" 1744 )) 1745 self.zoomValuesAct.triggered.connect(self.__showZoomValuesDialog) 1746 self.__actions.append(self.zoomValuesAct) 1747 1748 self.showJavaScriptConsoleAct = E5Action( 1749 self.tr('JavaScript Console'), 1750 self.tr('JavaScript Console'), 1751 0, 0, self, 'webbrowser_show_javascript_console') 1752 self.showJavaScriptConsoleAct.setStatusTip(self.tr( 1753 'Toggle the JavaScript console window')) 1754 self.showJavaScriptConsoleAct.setWhatsThis(self.tr( 1755 """<b>JavaScript Console</b>""" 1756 """<p>This toggles the JavaScript console window.</p>""" 1757 )) 1758 self.showJavaScriptConsoleAct.triggered.connect( 1759 self.__toggleJavaScriptConsole) 1760 self.__actions.append(self.showJavaScriptConsoleAct) 1761 1762 self.showTabManagerAct = E5Action( 1763 self.tr('Tab Manager'), 1764 self.tr('Tab Manager'), 1765 0, 0, self, 'webbrowser_show_tab_manager') 1766 self.showTabManagerAct.setStatusTip(self.tr( 1767 'Shows the tab manager window')) 1768 self.showTabManagerAct.setWhatsThis(self.tr( 1769 """<b>Tab Manager</b>""" 1770 """<p>Shows the tab manager window.</p>""" 1771 )) 1772 self.showTabManagerAct.triggered.connect( 1773 lambda: self.__showTabManager(self.showTabManagerAct)) 1774 self.__actions.append(self.showTabManagerAct) 1775 1776 self.showSessionsManagerAct = E5Action( 1777 self.tr('Session Manager'), 1778 self.tr('Session Manager...'), 1779 0, 0, self, 'webbrowser_show_session_manager') 1780 self.showSessionsManagerAct.setStatusTip(self.tr( 1781 'Shows the session manager window')) 1782 self.showSessionsManagerAct.setWhatsThis(self.tr( 1783 """<b>Session Manager</b>""" 1784 """<p>Shows the session manager window.</p>""" 1785 )) 1786 self.showSessionsManagerAct.triggered.connect( 1787 self.__showSessionManagerDialog) 1788 self.__actions.append(self.showSessionsManagerAct) 1789 1790 self.virustotalScanCurrentAct = E5Action( 1791 self.tr("Scan current site"), 1792 UI.PixmapCache.getIcon("virustotal"), 1793 self.tr("Scan current site"), 1794 0, 0, 1795 self, 'webbrowser_virustotal_scan_site') 1796 self.virustotalScanCurrentAct.triggered.connect( 1797 self.__virusTotalScanCurrentSite) 1798 self.__actions.append(self.virustotalScanCurrentAct) 1799 1800 self.virustotalIpReportAct = E5Action( 1801 self.tr("IP Address Report"), 1802 UI.PixmapCache.getIcon("virustotal"), 1803 self.tr("IP Address Report"), 1804 0, 0, 1805 self, 'webbrowser_virustotal_ip_report') 1806 self.virustotalIpReportAct.triggered.connect( 1807 self.__virusTotalIpAddressReport) 1808 self.__actions.append(self.virustotalIpReportAct) 1809 1810 self.virustotalDomainReportAct = E5Action( 1811 self.tr("Domain Report"), 1812 UI.PixmapCache.getIcon("virustotal"), 1813 self.tr("Domain Report"), 1814 0, 0, 1815 self, 'webbrowser_virustotal_domain_report') 1816 self.virustotalDomainReportAct.triggered.connect( 1817 self.__virusTotalDomainReport) 1818 self.__actions.append(self.virustotalDomainReportAct) 1819 1820 if ( 1821 not Preferences.getWebBrowser("VirusTotalEnabled") or 1822 Preferences.getWebBrowser("VirusTotalServiceKey") == "" 1823 ): 1824 self.virustotalScanCurrentAct.setEnabled(False) 1825 self.virustotalIpReportAct.setEnabled(False) 1826 self.virustotalDomainReportAct.setEnabled(False) 1827 1828 self.shortcutsAct = E5Action( 1829 self.tr('Keyboard Shortcuts'), 1830 UI.PixmapCache.getIcon("configureShortcuts"), 1831 self.tr('Keyboard &Shortcuts...'), 1832 0, 0, 1833 self, 'webbrowser_keyboard_shortcuts') 1834 self.shortcutsAct.setStatusTip(self.tr( 1835 'Set the keyboard shortcuts')) 1836 self.shortcutsAct.setWhatsThis(self.tr( 1837 """<b>Keyboard Shortcuts</b>""" 1838 """<p>Set the keyboard shortcuts of the application""" 1839 """ with your prefered values.</p>""" 1840 )) 1841 self.shortcutsAct.triggered.connect(self.__configShortcuts) 1842 self.__actions.append(self.shortcutsAct) 1843 1844 self.exportShortcutsAct = E5Action( 1845 self.tr('Export Keyboard Shortcuts'), 1846 UI.PixmapCache.getIcon("exportShortcuts"), 1847 self.tr('&Export Keyboard Shortcuts...'), 1848 0, 0, self, 'export_keyboard_shortcuts') 1849 self.exportShortcutsAct.setStatusTip(self.tr( 1850 'Export the keyboard shortcuts')) 1851 self.exportShortcutsAct.setWhatsThis(self.tr( 1852 """<b>Export Keyboard Shortcuts</b>""" 1853 """<p>Export the keyboard shortcuts of the application.</p>""" 1854 )) 1855 self.exportShortcutsAct.triggered.connect(self.__exportShortcuts) 1856 self.__actions.append(self.exportShortcutsAct) 1857 1858 self.importShortcutsAct = E5Action( 1859 self.tr('Import Keyboard Shortcuts'), 1860 UI.PixmapCache.getIcon("importShortcuts"), 1861 self.tr('&Import Keyboard Shortcuts...'), 1862 0, 0, self, 'import_keyboard_shortcuts') 1863 self.importShortcutsAct.setStatusTip(self.tr( 1864 'Import the keyboard shortcuts')) 1865 self.importShortcutsAct.setWhatsThis(self.tr( 1866 """<b>Import Keyboard Shortcuts</b>""" 1867 """<p>Import the keyboard shortcuts of the application.</p>""" 1868 )) 1869 self.importShortcutsAct.triggered.connect(self.__importShortcuts) 1870 self.__actions.append(self.importShortcutsAct) 1871 1872 self.showProtocolHandlerManagerAct = E5Action( 1873 self.tr('Protocol Handler Manager'), 1874 self.tr('Protocol Handler Manager...'), 1875 0, 0, self, 'webbrowser_show_protocol_handler_manager') 1876 self.showProtocolHandlerManagerAct.setStatusTip(self.tr( 1877 'Shows the protocol handler manager window')) 1878 self.showProtocolHandlerManagerAct.setWhatsThis(self.tr( 1879 """<b>Protocol Handler Manager</b>""" 1880 """<p>Shows the protocol handler manager window.</p>""" 1881 )) 1882 self.showProtocolHandlerManagerAct.triggered.connect( 1883 self.__showProtocolHandlerManagerDialog) 1884 self.__actions.append(self.showProtocolHandlerManagerAct) 1885 1886 self.backAct.setEnabled(False) 1887 self.forwardAct.setEnabled(False) 1888 1889 # now read the keyboard shortcuts for the actions 1890 Shortcuts.readShortcuts(helpViewer=self) 1891 1892 def getActions(self): 1893 """ 1894 Public method to get a list of all actions. 1895 1896 @return list of all actions (list of E5Action) 1897 """ 1898 return self.__actions[:] 1899 1900 def getActionsCategory(self): 1901 """ 1902 Public method to get the category of the defined actions. 1903 1904 @return category of the actions 1905 @rtype str 1906 """ 1907 return "WebBrowser" 1908 1909 def __initMenus(self): 1910 """ 1911 Private method to create the menus. 1912 """ 1913 mb = self.menuBar() 1914 1915 menu = mb.addMenu(self.tr('&File')) 1916 menu.addAction(self.newTabAct) 1917 menu.addAction(self.newAct) 1918 menu.addAction(self.newPrivateAct) 1919 menu.addAction(self.openAct) 1920 menu.addAction(self.openTabAct) 1921 menu.addSeparator() 1922 if not self.isPrivate(): 1923 sessionsMenu = menu.addMenu(self.tr("Sessions")) 1924 sessionsMenu.aboutToShow.connect( 1925 lambda: self.sessionManager().aboutToShowSessionsMenu( 1926 sessionsMenu)) 1927 menu.addAction(self.showSessionsManagerAct) 1928 menu.addSeparator() 1929 if self.saveAsAct is not None: 1930 menu.addAction(self.saveAsAct) 1931 menu.addAction(self.saveVisiblePageScreenAct) 1932 menu.addSeparator() 1933 if self.printPreviewAct: 1934 menu.addAction(self.printPreviewAct) 1935 if self.printAct: 1936 menu.addAction(self.printAct) 1937 if self.printPdfAct: 1938 menu.addAction(self.printPdfAct) 1939 menu.addAction(self.sendPageLinkAct) 1940 menu.addSeparator() 1941 menu.addAction(self.closeAct) 1942 menu.addAction(self.closeAllAct) 1943 menu.addSeparator() 1944 menu.addAction(self.exitAct) 1945 self.addActions(menu.actions()) 1946 1947 menu = mb.addMenu(self.tr('&Edit')) 1948 menu.addAction(self.undoAct) 1949 menu.addAction(self.redoAct) 1950 menu.addSeparator() 1951 menu.addAction(self.copyAct) 1952 menu.addAction(self.cutAct) 1953 menu.addAction(self.pasteAct) 1954 menu.addSeparator() 1955 menu.addAction(self.selectAllAct) 1956 menu.addAction(self.unselectAct) 1957 menu.addSeparator() 1958 menu.addAction(self.findAct) 1959 menu.addAction(self.findNextAct) 1960 menu.addAction(self.findPrevAct) 1961 self.addActions(menu.actions()) 1962 1963 menu = mb.addMenu(self.tr('&View')) 1964 menu.addAction(self.stopAct) 1965 menu.addAction(self.reloadAct) 1966 if WebBrowserWindow._useQtHelp: 1967 menu.addSeparator() 1968 menu.addAction(self.syncTocAct) 1969 menu.addSeparator() 1970 menu.addAction(self.zoomInAct) 1971 menu.addAction(self.zoomResetAct) 1972 menu.addAction(self.zoomOutAct) 1973 menu.addSeparator() 1974 self.__textEncodingMenu = menu.addMenu( 1975 self.tr("Text Encoding")) 1976 self.__textEncodingMenu.aboutToShow.connect( 1977 self.__aboutToShowTextEncodingMenu) 1978 self.__textEncodingMenu.triggered.connect(self.__setTextEncoding) 1979 menu.addSeparator() 1980 menu.addAction(self.pageSourceAct) 1981 menu.addAction(self.fullScreenAct) 1982 self.addActions(menu.actions()) 1983 1984 from .History.HistoryMenu import HistoryMenu 1985 self.historyMenu = HistoryMenu(self, self.__tabWidget) 1986 self.historyMenu.setTitle(self.tr('H&istory')) 1987 self.historyMenu.openUrl.connect(self.openUrl) 1988 self.historyMenu.newTab.connect(self.openUrlNewTab) 1989 self.historyMenu.newBackgroundTab.connect(self.openUrlNewBackgroundTab) 1990 self.historyMenu.newWindow.connect(self.openUrlNewWindow) 1991 self.historyMenu.newPrivateWindow.connect(self.openUrlNewPrivateWindow) 1992 mb.addMenu(self.historyMenu) 1993 1994 historyActions = [] 1995 historyActions.append(self.backAct) 1996 historyActions.append(self.forwardAct) 1997 historyActions.append(self.homeAct) 1998 self.historyMenu.setInitialActions(historyActions) 1999 self.addActions(historyActions) 2000 2001 from .Bookmarks.BookmarksMenu import BookmarksMenuBarMenu 2002 self.bookmarksMenu = BookmarksMenuBarMenu(self) 2003 self.bookmarksMenu.setTitle(self.tr('&Bookmarks')) 2004 self.bookmarksMenu.openUrl.connect(self.openUrl) 2005 self.bookmarksMenu.newTab.connect(self.openUrlNewTab) 2006 self.bookmarksMenu.newWindow.connect(self.openUrlNewWindow) 2007 mb.addMenu(self.bookmarksMenu) 2008 2009 bookmarksActions = [] 2010 bookmarksActions.append(self.bookmarksManageAct) 2011 bookmarksActions.append(self.bookmarksAddAct) 2012 bookmarksActions.append(self.bookmarksAllTabsAct) 2013 bookmarksActions.append(self.bookmarksAddFolderAct) 2014 bookmarksActions.append("--SEPARATOR--") 2015 bookmarksActions.append(self.importBookmarksAct) 2016 bookmarksActions.append(self.exportBookmarksAct) 2017 self.bookmarksMenu.setInitialActions(bookmarksActions) 2018 2019 menu = mb.addMenu(self.tr('&Settings')) 2020 menu.addAction(self.prefAct) 2021 menu.addSeparator() 2022 menu.addAction(self.shortcutsAct) 2023 menu.addAction(self.exportShortcutsAct) 2024 menu.addAction(self.importShortcutsAct) 2025 menu.addSeparator() 2026 menu.addAction(self.acceptedLanguagesAct) 2027 menu.addAction(self.cookiesAct) 2028 menu.addAction(self.personalDataAct) 2029 menu.addAction(self.greaseMonkeyAct) 2030 menu.addAction(self.featurePermissionAct) 2031 menu.addSeparator() 2032 menu.addAction(self.editMessageFilterAct) 2033 menu.addSeparator() 2034 menu.addAction(self.searchEnginesAct) 2035 menu.addSeparator() 2036 menu.addAction(self.passwordsAct) 2037 menu.addAction(self.certificateErrorsAct) 2038 menu.addSeparator() 2039 menu.addAction(self.zoomValuesAct) 2040 menu.addAction(self.manageIconsAct) 2041 menu.addSeparator() 2042 menu.addAction(self.adblockAct) 2043 menu.addSeparator() 2044 menu.addAction(self.safeBrowsingAct) 2045 menu.addSeparator() 2046 self.__settingsMenu = menu 2047 self.__settingsMenu.aboutToShow.connect( 2048 self.__aboutToShowSettingsMenu) 2049 2050 from .UserAgent.UserAgentMenu import UserAgentMenu 2051 self.__userAgentMenu = UserAgentMenu(self.tr("Global User Agent")) 2052 menu.addMenu(self.__userAgentMenu) 2053 menu.addAction(self.userAgentManagerAct) 2054 menu.addSeparator() 2055 2056 if WebBrowserWindow._useQtHelp: 2057 menu.addAction(self.manageQtHelpDocsAct) 2058 menu.addAction(self.reindexDocumentationAct) 2059 menu.addSeparator() 2060 menu.addAction(self.clearPrivateDataAct) 2061 menu.addAction(self.clearIconsAct) 2062 2063 menu = mb.addMenu(self.tr("&Tools")) 2064 menu.addAction(self.feedsManagerAct) 2065 menu.addAction(self.siteInfoAct) 2066 menu.addSeparator() 2067 menu.addAction(self.synchronizationAct) 2068 menu.addSeparator() 2069 vtMenu = menu.addMenu(UI.PixmapCache.getIcon("virustotal"), 2070 self.tr("&VirusTotal")) 2071 vtMenu.addAction(self.virustotalScanCurrentAct) 2072 vtMenu.addAction(self.virustotalIpReportAct) 2073 vtMenu.addAction(self.virustotalDomainReportAct) 2074 2075 menu = mb.addMenu(self.tr("&Windows")) 2076 menu.addAction(self.showDownloadManagerAct) 2077 menu.addAction(self.showJavaScriptConsoleAct) 2078 menu.addAction(self.showTabManagerAct) 2079 menu.addAction(self.showProtocolHandlerManagerAct) 2080 if WebBrowserWindow._useQtHelp: 2081 menu.addSection(self.tr("QtHelp")) 2082 menu.addAction(self.showTocAct) 2083 menu.addAction(self.showIndexAct) 2084 menu.addAction(self.showSearchAct) 2085 menu.addSeparator() 2086 self.__toolbarsMenu = menu.addMenu(self.tr("&Toolbars")) 2087 self.__toolbarsMenu.aboutToShow.connect(self.__showToolbarsMenu) 2088 self.__toolbarsMenu.triggered.connect(self.__TBMenuTriggered) 2089 2090 mb.addSeparator() 2091 2092 menu = mb.addMenu(self.tr('&Help')) 2093 menu.addAction(self.aboutAct) 2094 menu.addAction(self.aboutQtAct) 2095 menu.addSeparator() 2096 menu.addAction(self.whatsThisAct) 2097 self.addActions(menu.actions()) 2098 2099 def __initSuperMenu(self): 2100 """ 2101 Private method to create the super menu and attach it to the super 2102 menu button. 2103 """ 2104 self.__superMenu = QMenu(self) 2105 2106 self.__superMenu.addAction(self.newTabAct) 2107 self.__superMenu.addAction(self.newAct) 2108 self.__superMenu.addAction(self.newPrivateAct) 2109 self.__superMenu.addAction(self.openAct) 2110 self.__superMenu.addAction(self.openTabAct) 2111 self.__superMenu.addSeparator() 2112 2113 if not self.isPrivate(): 2114 sessionsMenu = self.__superMenu.addMenu(self.tr("Sessions")) 2115 sessionsMenu.aboutToShow.connect( 2116 lambda: self.sessionManager().aboutToShowSessionsMenu( 2117 sessionsMenu)) 2118 self.__superMenu.addAction(self.showSessionsManagerAct) 2119 self.__superMenu.addSeparator() 2120 2121 menu = self.__superMenu.addMenu(self.tr("Save")) 2122 if self.saveAsAct: 2123 menu.addAction(self.saveAsAct) 2124 menu.addAction(self.saveVisiblePageScreenAct) 2125 2126 if self.printPreviewAct or self.printAct or self.printPdfAct: 2127 menu = self.__superMenu.addMenu(self.tr("Print")) 2128 if self.printPreviewAct: 2129 menu.addAction(self.printPreviewAct) 2130 if self.printAct: 2131 menu.addAction(self.printAct) 2132 if self.printPdfAct: 2133 menu.addAction(self.printPdfAct) 2134 2135 self.__superMenu.addAction(self.sendPageLinkAct) 2136 self.__superMenu.addSeparator() 2137 self.__superMenu.addAction(self.selectAllAct) 2138 self.__superMenu.addAction(self.findAct) 2139 self.__superMenu.addSeparator() 2140 act = self.__superMenu.addAction(UI.PixmapCache.getIcon("history"), 2141 self.tr("Show All History...")) 2142 act.triggered.connect(self.historyMenu.showHistoryDialog) 2143 self.__superMenu.addAction(self.bookmarksManageAct) 2144 self.__superMenu.addSeparator() 2145 self.__superMenu.addAction(self.prefAct) 2146 2147 menu = self.__superMenu.addMenu(self.tr('Settings')) 2148 menu.addAction(self.shortcutsAct) 2149 menu.addAction(self.exportShortcutsAct) 2150 menu.addAction(self.importShortcutsAct) 2151 menu.addSeparator() 2152 menu.addAction(self.acceptedLanguagesAct) 2153 menu.addAction(self.cookiesAct) 2154 menu.addAction(self.personalDataAct) 2155 menu.addAction(self.greaseMonkeyAct) 2156 menu.addAction(self.featurePermissionAct) 2157 menu.addSeparator() 2158 menu.addAction(self.editMessageFilterAct) 2159 menu.addSeparator() 2160 menu.addAction(self.searchEnginesAct) 2161 menu.addSeparator() 2162 menu.addAction(self.passwordsAct) 2163 menu.addAction(self.certificateErrorsAct) 2164 menu.addSeparator() 2165 menu.addAction(self.zoomValuesAct) 2166 menu.addAction(self.manageIconsAct) 2167 menu.addSeparator() 2168 menu.addAction(self.adblockAct) 2169 menu.addSeparator() 2170 menu.addAction(self.safeBrowsingAct) 2171 menu.addSeparator() 2172 menu.addMenu(self.__userAgentMenu) 2173 menu.addAction(self.userAgentManagerAct) 2174 menu.addSeparator() 2175 if WebBrowserWindow._useQtHelp: 2176 menu.addAction(self.manageQtHelpDocsAct) 2177 menu.addAction(self.reindexDocumentationAct) 2178 menu.addSeparator() 2179 menu.addAction(self.clearPrivateDataAct) 2180 menu.addAction(self.clearIconsAct) 2181 menu.aboutToShow.connect( 2182 self.__aboutToShowSettingsMenu) 2183 2184 self.__superMenu.addSeparator() 2185 2186 menu = self.__superMenu.addMenu(self.tr('&View')) 2187 menu.addMenu(self.__toolbarsMenu) 2188 windowsMenu = menu.addMenu(self.tr("&Windows")) 2189 windowsMenu.addAction(self.showDownloadManagerAct) 2190 windowsMenu.addAction(self.showJavaScriptConsoleAct) 2191 windowsMenu.addAction(self.showTabManagerAct) 2192 windowsMenu.addAction(self.showProtocolHandlerManagerAct) 2193 if WebBrowserWindow._useQtHelp: 2194 windowsMenu.addSection(self.tr("QtHelp")) 2195 windowsMenu.addAction(self.showTocAct) 2196 windowsMenu.addAction(self.showIndexAct) 2197 windowsMenu.addAction(self.showSearchAct) 2198 menu.addSeparator() 2199 menu.addAction(self.stopAct) 2200 menu.addAction(self.reloadAct) 2201 if WebBrowserWindow._useQtHelp: 2202 menu.addSeparator() 2203 menu.addAction(self.syncTocAct) 2204 menu.addSeparator() 2205 menu.addAction(self.zoomInAct) 2206 menu.addAction(self.zoomResetAct) 2207 menu.addAction(self.zoomOutAct) 2208 menu.addSeparator() 2209 menu.addMenu(self.__textEncodingMenu) 2210 menu.addSeparator() 2211 menu.addAction(self.pageSourceAct) 2212 menu.addAction(self.fullScreenAct) 2213 2214 self.__superMenu.addMenu(self.historyMenu) 2215 self.__superMenu.addMenu(self.bookmarksMenu) 2216 2217 menu = self.__superMenu.addMenu(self.tr("&Tools")) 2218 menu.addAction(self.feedsManagerAct) 2219 menu.addAction(self.siteInfoAct) 2220 menu.addSeparator() 2221 menu.addAction(self.synchronizationAct) 2222 menu.addSeparator() 2223 vtMenu = menu.addMenu(UI.PixmapCache.getIcon("virustotal"), 2224 self.tr("&VirusTotal")) 2225 vtMenu.addAction(self.virustotalScanCurrentAct) 2226 vtMenu.addAction(self.virustotalIpReportAct) 2227 vtMenu.addAction(self.virustotalDomainReportAct) 2228 2229 self.__superMenu.addSeparator() 2230 self.__superMenu.addAction(self.aboutAct) 2231 self.__superMenu.addAction(self.aboutQtAct) 2232 self.__superMenu.addSeparator() 2233 self.__superMenu.addAction(self.exitAct) 2234 2235 self.__navigationBar.superMenuButton().setMenu(self.__superMenu) 2236 2237 def __initToolbars(self): 2238 """ 2239 Private method to create the toolbars. 2240 """ 2241 filetb = self.addToolBar(self.tr("File")) 2242 filetb.setObjectName("FileToolBar") 2243 filetb.setIconSize(UI.Config.ToolBarIconSize) 2244 filetb.addAction(self.newTabAct) 2245 filetb.addAction(self.newAct) 2246 filetb.addAction(self.newPrivateAct) 2247 filetb.addAction(self.openAct) 2248 filetb.addAction(self.openTabAct) 2249 filetb.addSeparator() 2250 if self.saveAsAct is not None: 2251 filetb.addAction(self.saveAsAct) 2252 filetb.addAction(self.saveVisiblePageScreenAct) 2253 filetb.addSeparator() 2254 if self.printPreviewAct: 2255 filetb.addAction(self.printPreviewAct) 2256 if self.printAct: 2257 filetb.addAction(self.printAct) 2258 if self.printPdfAct: 2259 filetb.addAction(self.printPdfAct) 2260 if self.printPreviewAct or self.printAct or self.printPdfAct: 2261 filetb.addSeparator() 2262 filetb.addAction(self.closeAct) 2263 filetb.addAction(self.exitAct) 2264 self.__toolbars["file"] = (filetb.windowTitle(), filetb) 2265 2266 edittb = self.addToolBar(self.tr("Edit")) 2267 edittb.setObjectName("EditToolBar") 2268 edittb.setIconSize(UI.Config.ToolBarIconSize) 2269 edittb.addAction(self.undoAct) 2270 edittb.addAction(self.redoAct) 2271 edittb.addSeparator() 2272 edittb.addAction(self.copyAct) 2273 edittb.addAction(self.cutAct) 2274 edittb.addAction(self.pasteAct) 2275 edittb.addSeparator() 2276 edittb.addAction(self.selectAllAct) 2277 self.__toolbars["edit"] = (edittb.windowTitle(), edittb) 2278 2279 viewtb = self.addToolBar(self.tr("View")) 2280 viewtb.setObjectName("ViewToolBar") 2281 viewtb.setIconSize(UI.Config.ToolBarIconSize) 2282 viewtb.addAction(self.zoomInAct) 2283 viewtb.addAction(self.zoomResetAct) 2284 viewtb.addAction(self.zoomOutAct) 2285 viewtb.addSeparator() 2286 viewtb.addAction(self.fullScreenAct) 2287 self.__toolbars["view"] = (viewtb.windowTitle(), viewtb) 2288 2289 findtb = self.addToolBar(self.tr("Find")) 2290 findtb.setObjectName("FindToolBar") 2291 findtb.setIconSize(UI.Config.ToolBarIconSize) 2292 findtb.addAction(self.findAct) 2293 findtb.addAction(self.findNextAct) 2294 findtb.addAction(self.findPrevAct) 2295 self.__toolbars["find"] = (findtb.windowTitle(), findtb) 2296 2297 if WebBrowserWindow._useQtHelp: 2298 filtertb = self.addToolBar(self.tr("Filter")) 2299 filtertb.setObjectName("FilterToolBar") 2300 self.filterCombo = QComboBox() 2301 try: 2302 comboWidth = QFontMetrics(QFont()).horizontalAdvance( 2303 "ComboBoxWithEnoughWidth") 2304 except AttributeError: 2305 comboWidth = QFontMetrics(QFont()).width( 2306 "ComboBoxWithEnoughWidth") 2307 self.filterCombo.setMinimumWidth(comboWidth) 2308 filtertb.addWidget(QLabel(self.tr("Filtered by: "))) 2309 filtertb.addWidget(self.filterCombo) 2310 self.__helpEngine.setupFinished.connect(self.__setupFilterCombo) 2311 self.filterCombo.activated[int].connect( 2312 self.__filterQtHelpDocumentation) 2313 self.__setupFilterCombo() 2314 self.__toolbars["filter"] = (filtertb.windowTitle(), filtertb) 2315 2316 settingstb = self.addToolBar(self.tr("Settings")) 2317 settingstb.setObjectName("SettingsToolBar") 2318 settingstb.setIconSize(UI.Config.ToolBarIconSize) 2319 settingstb.addAction(self.prefAct) 2320 settingstb.addAction(self.shortcutsAct) 2321 settingstb.addAction(self.acceptedLanguagesAct) 2322 settingstb.addAction(self.cookiesAct) 2323 settingstb.addAction(self.personalDataAct) 2324 settingstb.addAction(self.greaseMonkeyAct) 2325 settingstb.addAction(self.featurePermissionAct) 2326 self.__toolbars["settings"] = (settingstb.windowTitle(), settingstb) 2327 2328 toolstb = self.addToolBar(self.tr("Tools")) 2329 toolstb.setObjectName("ToolsToolBar") 2330 toolstb.setIconSize(UI.Config.ToolBarIconSize) 2331 toolstb.addAction(self.feedsManagerAct) 2332 toolstb.addAction(self.siteInfoAct) 2333 toolstb.addSeparator() 2334 toolstb.addAction(self.synchronizationAct) 2335 self.__toolbars["tools"] = (toolstb.windowTitle(), toolstb) 2336 2337 helptb = self.addToolBar(self.tr("Help")) 2338 helptb.setObjectName("HelpToolBar") 2339 helptb.setIconSize(UI.Config.ToolBarIconSize) 2340 helptb.addAction(self.whatsThisAct) 2341 self.__toolbars["help"] = (helptb.windowTitle(), helptb) 2342 2343 self.addToolBarBreak() 2344 vttb = self.addToolBar(self.tr("VirusTotal")) 2345 vttb.setObjectName("VirusTotalToolBar") 2346 vttb.setIconSize(UI.Config.ToolBarIconSize) 2347 vttb.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) 2348 vttb.addAction(self.virustotalScanCurrentAct) 2349 vttb.addAction(self.virustotalIpReportAct) 2350 vttb.addAction(self.virustotalDomainReportAct) 2351 self.__toolbars["virustotal"] = (vttb.windowTitle(), vttb) 2352 2353 def __nextTab(self): 2354 """ 2355 Private slot used to show the next tab. 2356 """ 2357 fwidget = QApplication.focusWidget() 2358 while fwidget and not hasattr(fwidget, 'nextTab'): 2359 fwidget = fwidget.parent() 2360 if fwidget: 2361 fwidget.nextTab() 2362 2363 def __prevTab(self): 2364 """ 2365 Private slot used to show the previous tab. 2366 """ 2367 fwidget = QApplication.focusWidget() 2368 while fwidget and not hasattr(fwidget, 'prevTab'): 2369 fwidget = fwidget.parent() 2370 if fwidget: 2371 fwidget.prevTab() 2372 2373 def __switchTab(self): 2374 """ 2375 Private slot used to switch between the current and the previous 2376 current tab. 2377 """ 2378 fwidget = QApplication.focusWidget() 2379 while fwidget and not hasattr(fwidget, 'switchTab'): 2380 fwidget = fwidget.parent() 2381 if fwidget: 2382 fwidget.switchTab() 2383 2384 def __whatsThis(self): 2385 """ 2386 Private slot called in to enter Whats This mode. 2387 """ 2388 QWhatsThis.enterWhatsThisMode() 2389 2390 def __titleChanged(self, browser, title): 2391 """ 2392 Private slot called to handle a change of a browser's title. 2393 2394 @param browser reference to the browser (WebBrowserView) 2395 @param title new title (string) 2396 """ 2397 self.historyManager().updateHistoryEntry( 2398 browser.url().toString(), title) 2399 2400 @pyqtSlot() 2401 def newTab(self, link=None, addNextTo=None, background=False): 2402 """ 2403 Public slot called to open a new web browser tab. 2404 2405 @param link file to be displayed in the new window (string or QUrl) 2406 @param addNextTo reference to the browser to open the tab after 2407 (WebBrowserView) 2408 @param background flag indicating to open the tab in the 2409 background (bool) 2410 @return reference to the new browser 2411 @rtype WebBrowserView 2412 """ 2413 if addNextTo: 2414 return self.__tabWidget.newBrowserAfter( 2415 addNextTo, link, background=background) 2416 else: 2417 return self.__tabWidget.newBrowser(link, background=background) 2418 2419 @pyqtSlot() 2420 def newWindow(self, link=None, restoreSession=False): 2421 """ 2422 Public slot called to open a new web browser window. 2423 2424 @param link URL to be displayed in the new window 2425 @type str or QUrl 2426 @param restoreSession flag indicating a restore session action 2427 @type bool 2428 @return reference to the new window 2429 @rtype WebBrowserWindow 2430 """ 2431 if link is None: 2432 linkName = "" 2433 elif isinstance(link, QUrl): 2434 linkName = link.toString() 2435 else: 2436 linkName = link 2437 h = WebBrowserWindow(linkName, ".", self.parent(), "webbrowser", 2438 private=self.isPrivate(), 2439 restoreSession=restoreSession) 2440 h.show() 2441 2442 self.webBrowserWindowOpened.emit(h) 2443 2444 return h 2445 2446 @pyqtSlot() 2447 def newPrivateWindow(self, link=None): 2448 """ 2449 Public slot called to open a new private web browser window. 2450 2451 @param link URL to be displayed in the new window 2452 @type str or QUrl 2453 """ 2454 if link is None: 2455 linkName = "" 2456 elif isinstance(link, QUrl): 2457 linkName = link.toString() 2458 else: 2459 linkName = link 2460 2461 applPath = os.path.join(getConfig("ericDir"), "eric6_browser.py") 2462 args = [] 2463 args.append(applPath) 2464 args.append("--config={0}".format(Utilities.getConfigDir())) 2465 if self.__settingsDir: 2466 args.append("--settings={0}".format(self.__settingsDir)) 2467 args.append("--private") 2468 if linkName: 2469 args.append(linkName) 2470 2471 if ( 2472 not os.path.isfile(applPath) or 2473 not QProcess.startDetached(sys.executable, args) 2474 ): 2475 E5MessageBox.critical( 2476 self, 2477 self.tr('New Private Window'), 2478 self.tr( 2479 '<p>Could not start the process.<br>' 2480 'Ensure that it is available as <b>{0}</b>.</p>' 2481 ).format(applPath), 2482 self.tr('OK')) 2483 2484 def __openFile(self): 2485 """ 2486 Private slot called to open a file. 2487 """ 2488 fn = E5FileDialog.getOpenFileName( 2489 self, 2490 self.tr("Open File"), 2491 "", 2492 self.tr("HTML Files (*.html *.htm *.mhtml *.mht);;" 2493 "PDF Files (*.pdf);;" 2494 "CHM Files (*.chm);;" 2495 "All Files (*)" 2496 )) 2497 if fn: 2498 if Utilities.isWindowsPlatform(): 2499 url = "file:///" + Utilities.fromNativeSeparators(fn) 2500 else: 2501 url = "file://" + fn 2502 self.currentBrowser().setSource(QUrl(url)) 2503 2504 def __openFileNewTab(self): 2505 """ 2506 Private slot called to open a file in a new tab. 2507 """ 2508 fn = E5FileDialog.getOpenFileName( 2509 self, 2510 self.tr("Open File"), 2511 "", 2512 self.tr("HTML Files (*.html *.htm *.mhtml *.mht);;" 2513 "PDF Files (*.pdf);;" 2514 "CHM Files (*.chm);;" 2515 "All Files (*)" 2516 )) 2517 if fn: 2518 if Utilities.isWindowsPlatform(): 2519 url = "file:///" + Utilities.fromNativeSeparators(fn) 2520 else: 2521 url = "file://" + fn 2522 self.newTab(url) 2523 2524 def __savePageAs(self): 2525 """ 2526 Private slot to save the current page. 2527 """ 2528 browser = self.currentBrowser() 2529 if browser is not None: 2530 browser.saveAs() 2531 2532 @pyqtSlot() 2533 def __saveVisiblePageScreen(self): 2534 """ 2535 Private slot to save the visible part of the current page as a screen 2536 shot. 2537 """ 2538 from .PageScreenDialog import PageScreenDialog 2539 self.__pageScreen = PageScreenDialog(self.currentBrowser()) 2540 self.__pageScreen.show() 2541 2542 def __about(self): 2543 """ 2544 Private slot to show the about information. 2545 """ 2546 chromeVersion, webengineVersion = ( 2547 WebBrowserTools.getWebEngineVersions() 2548 ) 2549 E5MessageBox.about( 2550 self, 2551 self.tr("eric Web Browser"), 2552 self.tr( 2553 """<b>eric Web Browser - {0}</b>""" 2554 """<p>The eric Web Browser is a combined help file and HTML""" 2555 """ browser. It is part of the eric development""" 2556 """ toolset.</p>""" 2557 """<p>It is based on QtWebEngine {1} and Chrome {2}.</p>""" 2558 ).format(Version, webengineVersion, chromeVersion)) 2559 2560 def __aboutQt(self): 2561 """ 2562 Private slot to show info about Qt. 2563 """ 2564 E5MessageBox.aboutQt(self, self.tr("eric Web Browser")) 2565 2566 def setBackwardAvailable(self, b): 2567 """ 2568 Public slot called when backward references are available. 2569 2570 @param b flag indicating availability of the backwards action (boolean) 2571 """ 2572 self.backAct.setEnabled(b) 2573 self.__navigationBar.backButton().setEnabled(b) 2574 2575 def setForwardAvailable(self, b): 2576 """ 2577 Public slot called when forward references are available. 2578 2579 @param b flag indicating the availability of the forwards action 2580 (boolean) 2581 """ 2582 self.forwardAct.setEnabled(b) 2583 self.__navigationBar.forwardButton().setEnabled(b) 2584 2585 def setLoadingActions(self, b): 2586 """ 2587 Public slot to set the loading dependent actions. 2588 2589 @param b flag indicating the loading state to consider (boolean) 2590 """ 2591 self.reloadAct.setEnabled(not b) 2592 self.stopAct.setEnabled(b) 2593 2594 self.__navigationBar.reloadStopButton().setLoading(b) 2595 2596 def __addBookmark(self): 2597 """ 2598 Private slot called to add the displayed file to the bookmarks. 2599 """ 2600 from .WebBrowserPage import WebBrowserPage 2601 2602 view = self.currentBrowser() 2603 view.addBookmark() 2604 urlStr = bytes(view.url().toEncoded()).decode() 2605 title = view.title() 2606 2607 script = Scripts.getAllMetaAttributes() 2608 view.page().runJavaScript( 2609 script, 2610 WebBrowserPage.SafeJsWorld, 2611 lambda res: self.__addBookmarkCallback(urlStr, title, res)) 2612 2613 def __addBookmarkCallback(self, url, title, res): 2614 """ 2615 Private callback method of __addBookmark(). 2616 2617 @param url URL for the bookmark 2618 @type str 2619 @param title title for the bookmark 2620 @type str 2621 @param res result of the JavaScript 2622 @type list 2623 """ 2624 description = "" 2625 for meta in res: 2626 if meta["name"] == "description": 2627 description = meta["content"] 2628 2629 from .Bookmarks.AddBookmarkDialog import AddBookmarkDialog 2630 dlg = AddBookmarkDialog() 2631 dlg.setUrl(url) 2632 dlg.setTitle(title) 2633 dlg.setDescription(description) 2634 menu = self.bookmarksManager().menu() 2635 idx = self.bookmarksManager().bookmarksModel().nodeIndex(menu) 2636 dlg.setCurrentIndex(idx) 2637 dlg.exec() 2638 2639 def __addBookmarkFolder(self): 2640 """ 2641 Private slot to add a new bookmarks folder. 2642 """ 2643 from .Bookmarks.AddBookmarkDialog import AddBookmarkDialog 2644 dlg = AddBookmarkDialog() 2645 menu = self.bookmarksManager().menu() 2646 idx = self.bookmarksManager().bookmarksModel().nodeIndex(menu) 2647 dlg.setCurrentIndex(idx) 2648 dlg.setFolder(True) 2649 dlg.exec() 2650 2651 def __showBookmarksDialog(self): 2652 """ 2653 Private slot to show the bookmarks dialog. 2654 """ 2655 from .Bookmarks.BookmarksDialog import BookmarksDialog 2656 self.__bookmarksDialog = BookmarksDialog(self) 2657 self.__bookmarksDialog.openUrl.connect(self.openUrl) 2658 self.__bookmarksDialog.newTab.connect(self.openUrlNewTab) 2659 self.__bookmarksDialog.newBackgroundTab.connect( 2660 self.openUrlNewBackgroundTab) 2661 self.__bookmarksDialog.show() 2662 2663 def bookmarkAll(self): 2664 """ 2665 Public slot to bookmark all open tabs. 2666 """ 2667 from .WebBrowserPage import WebBrowserPage 2668 from .Bookmarks.AddBookmarkDialog import AddBookmarkDialog 2669 2670 dlg = AddBookmarkDialog() 2671 dlg.setFolder(True) 2672 dlg.setTitle(self.tr("Saved Tabs")) 2673 dlg.exec() 2674 2675 folder = dlg.addedNode() 2676 if folder is None: 2677 return 2678 2679 for view in self.__tabWidget.browsers(): 2680 urlStr = bytes(view.url().toEncoded()).decode() 2681 title = view.title() 2682 2683 script = Scripts.getAllMetaAttributes() 2684 view.page().runJavaScript( 2685 script, 2686 WebBrowserPage.SafeJsWorld, 2687 functools.partial(self.__bookmarkAllCallback, 2688 folder, urlStr, title)) 2689 2690 def __bookmarkAllCallback(self, folder, url, title, res): 2691 """ 2692 Private callback method of __addBookmark(). 2693 2694 @param folder reference to the bookmarks folder 2695 @type BookmarkNode 2696 @param url URL for the bookmark 2697 @type str 2698 @param title title for the bookmark 2699 @type str 2700 @param res result of the JavaScript 2701 @type list 2702 """ 2703 description = "" 2704 for meta in res: 2705 if meta["name"] == "description": 2706 description = meta["content"] 2707 2708 from .Bookmarks.BookmarkNode import BookmarkNode 2709 bookmark = BookmarkNode(BookmarkNode.Bookmark) 2710 bookmark.url = url 2711 bookmark.title = title 2712 bookmark.desc = description 2713 2714 self.bookmarksManager().addBookmark(folder, bookmark) 2715 2716 def __find(self): 2717 """ 2718 Private slot to handle the find action. 2719 2720 It opens the search dialog in order to perform the various 2721 search actions and to collect the various search info. 2722 """ 2723 self.__searchWidget.showFind() 2724 2725 def forceClose(self): 2726 """ 2727 Public method to force closing the window. 2728 """ 2729 self.__forcedClose = True 2730 self.close() 2731 2732 def closeEvent(self, e): 2733 """ 2734 Protected event handler for the close event. 2735 2736 @param e the close event (QCloseEvent) 2737 <br />This event is simply accepted after the history has been 2738 saved and all window references have been deleted. 2739 """ 2740 res = self.__shutdownWindow() 2741 2742 if res: 2743 e.accept() 2744 self.webBrowserWindowClosed.emit(self) 2745 else: 2746 e.ignore() 2747 2748 def isClosing(self): 2749 """ 2750 Public method to test, if the window is closing. 2751 2752 @return flag indicating that the window is closing 2753 @rtype bool 2754 """ 2755 return self.__isClosing 2756 2757 def __shutdownWindow(self): 2758 """ 2759 Private method to shut down a web browser window. 2760 2761 @return flag indicating successful shutdown (boolean) 2762 """ 2763 if ( 2764 not WebBrowserWindow._performingShutdown and 2765 not self.__forcedClose and 2766 not self.__tabWidget.shallShutDown() 2767 ): 2768 return False 2769 2770 self.__isClosing = True 2771 2772 if ( 2773 not WebBrowserWindow._performingShutdown and 2774 len(WebBrowserWindow.BrowserWindows) == 1 and 2775 not WebBrowserWindow.isPrivate() 2776 ): 2777 # shut down the session manager in case the last window is 2778 # about to be closed 2779 self.sessionManager().shutdown() 2780 2781 self.__bookmarksToolBar.setModel(None) 2782 2783 self.__virusTotal.close() 2784 2785 self.__navigationBar.searchEdit().openSearchManager().close() 2786 2787 if WebBrowserWindow._useQtHelp: 2788 self.__searchEngine.cancelIndexing() 2789 self.__searchEngine.cancelSearching() 2790 2791 if self.__helpInstaller: 2792 self.__helpInstaller.stop() 2793 2794 self.__navigationBar.searchEdit().saveSearches() 2795 2796 self.__tabWidget.closeAllBrowsers(shutdown=True) 2797 2798 state = self.saveState() 2799 Preferences.setWebBrowser("WebBrowserState", state) 2800 2801 if Preferences.getWebBrowser("SaveGeometry"): 2802 if not self.isFullScreen(): 2803 Preferences.setGeometry("WebBrowserGeometry", 2804 self.saveGeometry()) 2805 else: 2806 Preferences.setGeometry("WebBrowserGeometry", QByteArray()) 2807 2808 with contextlib.suppress(ValueError): 2809 browserIndex = WebBrowserWindow.BrowserWindows.index(self) 2810 if len(WebBrowserWindow.BrowserWindows) and browserIndex == 0: 2811 if len(WebBrowserWindow.BrowserWindows) > 1: 2812 # first window will be deleted 2813 QDesktopServices.setUrlHandler( 2814 "http", 2815 WebBrowserWindow.BrowserWindows[1].urlHandler) 2816 QDesktopServices.setUrlHandler( 2817 "https", 2818 WebBrowserWindow.BrowserWindows[1].urlHandler) 2819 else: 2820 QDesktopServices.unsetUrlHandler("http") 2821 QDesktopServices.unsetUrlHandler("https") 2822 if len(WebBrowserWindow.BrowserWindows) > 0: 2823 del WebBrowserWindow.BrowserWindows[browserIndex] 2824 2825 Preferences.syncPreferences() 2826 if ( 2827 not WebBrowserWindow._performingShutdown and 2828 len(WebBrowserWindow.BrowserWindows) == 0 2829 ): 2830 # shut down the browser in case the last window was 2831 # simply closed 2832 self.shutdown() 2833 2834 return True 2835 2836 def __shallShutDown(self): 2837 """ 2838 Private method to check, if the application should be shut down. 2839 2840 @return flag indicating a shut down 2841 @rtype bool 2842 """ 2843 if Preferences.getWebBrowser("WarnOnMultipleClose"): 2844 windowCount = len(WebBrowserWindow.BrowserWindows) 2845 tabCount = 0 2846 for browser in WebBrowserWindow.BrowserWindows: 2847 tabCount += browser.tabWidget().count() 2848 2849 if windowCount > 1 or tabCount > 1: 2850 mb = E5MessageBox.E5MessageBox( 2851 E5MessageBox.Information, 2852 self.tr("Are you sure you want to close the web browser?"), 2853 self.tr("""Are you sure you want to close the web""" 2854 """ browser?\n""" 2855 """You have {0} windows with {1} tabs open.""") 2856 .format(windowCount, tabCount), 2857 modal=True, 2858 parent=self) 2859 quitButton = mb.addButton( 2860 self.tr("&Quit"), E5MessageBox.AcceptRole) 2861 quitButton.setIcon(UI.PixmapCache.getIcon("exit")) 2862 mb.addButton(E5MessageBox.Cancel) 2863 mb.exec() 2864 return mb.clickedButton() == quitButton 2865 2866 return True 2867 2868 def shutdown(self): 2869 """ 2870 Public method to shut down the web browser. 2871 2872 @return flag indicating successful shutdown (boolean) 2873 """ 2874 if not self.__shallShutDown(): 2875 return False 2876 2877 if ( 2878 WebBrowserWindow._downloadManager is not None and 2879 not self.downloadManager().allowQuit() 2880 ): 2881 return False 2882 2883 WebBrowserWindow._performingShutdown = True 2884 2885 if not WebBrowserWindow.isPrivate(): 2886 self.sessionManager().shutdown() 2887 2888 if WebBrowserWindow._downloadManager is not None: 2889 self.downloadManager().shutdown() 2890 2891 self.cookieJar().close() 2892 2893 self.bookmarksManager().close() 2894 2895 self.historyManager().close() 2896 2897 self.passwordManager().close() 2898 2899 self.adBlockManager().close() 2900 2901 self.userAgentsManager().close() 2902 2903 self.speedDial().close() 2904 2905 self.syncManager().close() 2906 2907 ZoomManager.instance().close() 2908 2909 WebIconProvider.instance().close() 2910 2911 if len(WebBrowserWindow.BrowserWindows) == 1: 2912 # it is the last window 2913 self.tabManager().close() 2914 2915 self.networkManager().shutdown() 2916 2917 if WebBrowserWindow._safeBrowsingManager: 2918 self.safeBrowsingManager().close() 2919 2920 for browser in WebBrowserWindow.BrowserWindows: 2921 if browser != self: 2922 browser.close() 2923 self.close() 2924 2925 return True 2926 2927 def __backward(self): 2928 """ 2929 Private slot called to handle the backward action. 2930 """ 2931 self.currentBrowser().backward() 2932 2933 def __forward(self): 2934 """ 2935 Private slot called to handle the forward action. 2936 """ 2937 self.currentBrowser().forward() 2938 2939 def __home(self): 2940 """ 2941 Private slot called to handle the home action. 2942 """ 2943 self.currentBrowser().home() 2944 2945 def __reload(self): 2946 """ 2947 Private slot called to handle the reload action. 2948 """ 2949 self.currentBrowser().reloadBypassingCache() 2950 2951 def __stopLoading(self): 2952 """ 2953 Private slot called to handle loading of the current page. 2954 """ 2955 self.currentBrowser().stop() 2956 2957 def __zoomValueChanged(self, value): 2958 """ 2959 Private slot to handle value changes of the zoom widget. 2960 2961 @param value zoom value (integer) 2962 """ 2963 self.currentBrowser().setZoomValue(value) 2964 2965 def __zoomIn(self): 2966 """ 2967 Private slot called to handle the zoom in action. 2968 """ 2969 self.currentBrowser().zoomIn() 2970 self.__zoomWidget.setValue(self.currentBrowser().zoomValue()) 2971 2972 def __zoomOut(self): 2973 """ 2974 Private slot called to handle the zoom out action. 2975 """ 2976 self.currentBrowser().zoomOut() 2977 self.__zoomWidget.setValue(self.currentBrowser().zoomValue()) 2978 2979 def __zoomReset(self): 2980 """ 2981 Private slot called to handle the zoom reset action. 2982 """ 2983 self.currentBrowser().zoomReset() 2984 self.__zoomWidget.setValue(self.currentBrowser().zoomValue()) 2985 2986 def toggleFullScreen(self): 2987 """ 2988 Public slot called to toggle the full screen mode. 2989 """ 2990 if self.__htmlFullScreen: 2991 self.currentBrowser().triggerPageAction( 2992 QWebEnginePage.WebAction.ExitFullScreen) 2993 return 2994 2995 if self.isFullScreen(): 2996 # switch back to normal 2997 self.showNormal() 2998 else: 2999 # switch to full screen 3000 self.showFullScreen() 3001 3002 def enterHtmlFullScreen(self): 3003 """ 3004 Public method to switch to full screen initiated by the 3005 HTML page. 3006 """ 3007 self.showFullScreen() 3008 self.__htmlFullScreen = True 3009 3010 def isFullScreenNavigationVisible(self): 3011 """ 3012 Public method to check, if full screen navigation is active. 3013 3014 @return flag indicating visibility of the navigation container in full 3015 screen mode 3016 @rtype bool 3017 """ 3018 return self.isFullScreen() and self.__navigationContainer.isVisible() 3019 3020 def showFullScreenNavigation(self): 3021 """ 3022 Public slot to show full screen navigation. 3023 """ 3024 if self.__htmlFullScreen: 3025 return 3026 3027 if self.__hideNavigationTimer.isActive(): 3028 self.__hideNavigationTimer.stop() 3029 3030 self.__navigationContainer.show() 3031 self.__tabWidget.tabBar().show() 3032 3033 def hideFullScreenNavigation(self): 3034 """ 3035 Public slot to hide full screen navigation. 3036 """ 3037 if not self.__hideNavigationTimer.isActive(): 3038 self.__hideNavigationTimer.start() 3039 3040 def __hideNavigation(self): 3041 """ 3042 Private slot to hide full screen navigation by timer. 3043 """ 3044 browser = self.currentBrowser() 3045 mouseInBrowser = browser and browser.underMouse() 3046 3047 if self.isFullScreen() and mouseInBrowser: 3048 self.__navigationContainer.hide() 3049 self.__tabWidget.tabBar().hide() 3050 3051 def __copy(self): 3052 """ 3053 Private slot called to handle the copy action. 3054 """ 3055 self.currentBrowser().copy() 3056 3057 def __cut(self): 3058 """ 3059 Private slot called to handle the cut action. 3060 """ 3061 self.currentBrowser().cut() 3062 3063 def __paste(self): 3064 """ 3065 Private slot called to handle the paste action. 3066 """ 3067 self.currentBrowser().paste() 3068 3069 def __undo(self): 3070 """ 3071 Private slot to handle the undo action. 3072 """ 3073 self.currentBrowser().undo() 3074 3075 def __redo(self): 3076 """ 3077 Private slot to handle the redo action. 3078 """ 3079 self.currentBrowser().redo() 3080 3081 def __selectAll(self): 3082 """ 3083 Private slot to handle the select all action. 3084 """ 3085 self.currentBrowser().selectAll() 3086 3087 def __unselect(self): 3088 """ 3089 Private slot to clear the selection of the current browser. 3090 """ 3091 self.currentBrowser().unselect() 3092 3093 @classmethod 3094 def isPrivate(cls): 3095 """ 3096 Class method to check the private browsing mode. 3097 3098 @return flag indicating private browsing mode 3099 @rtype bool 3100 """ 3101 return cls._isPrivate 3102 3103 def closeCurrentBrowser(self): 3104 """ 3105 Public method to close the current web browser. 3106 """ 3107 self.__tabWidget.closeBrowser() 3108 3109 def closeBrowser(self, browser): 3110 """ 3111 Public method to close the given browser. 3112 3113 @param browser reference to the web browser view to be closed 3114 @type WebBrowserView 3115 """ 3116 self.__tabWidget.closeBrowserView(browser) 3117 3118 def currentBrowser(self): 3119 """ 3120 Public method to get a reference to the current web browser. 3121 3122 @return reference to the current help browser (WebBrowserView) 3123 """ 3124 return self.__tabWidget.currentBrowser() 3125 3126 def browserAt(self, index): 3127 """ 3128 Public method to get a reference to the web browser with the given 3129 index. 3130 3131 @param index index of the browser to get (integer) 3132 @return reference to the indexed web browser (WebBrowserView) 3133 """ 3134 return self.__tabWidget.browserAt(index) 3135 3136 def browsers(self): 3137 """ 3138 Public method to get a list of references to all web browsers. 3139 3140 @return list of references to web browsers (list of WebBrowserView) 3141 """ 3142 return self.__tabWidget.browsers() 3143 3144 def __currentChanged(self, index): 3145 """ 3146 Private slot to handle the currentChanged signal. 3147 3148 @param index index of the current tab (integer) 3149 """ 3150 if index > -1: 3151 cb = self.currentBrowser() 3152 if cb is not None: 3153 self.setForwardAvailable(cb.isForwardAvailable()) 3154 self.setBackwardAvailable(cb.isBackwardAvailable()) 3155 self.setLoadingActions(cb.isLoading()) 3156 3157 # set value of zoom widget 3158 self.__zoomWidget.setValue(cb.zoomValue()) 3159 3160 def __showPreferences(self): 3161 """ 3162 Private slot to set the preferences. 3163 """ 3164 from Preferences.ConfigurationDialog import ( 3165 ConfigurationDialog, ConfigurationMode 3166 ) 3167 dlg = ConfigurationDialog( 3168 self, 'Configuration', True, fromEric=False, 3169 displayMode=ConfigurationMode.WEBBROWSERMODE) 3170 dlg.preferencesChanged.connect(self.preferencesChanged) 3171 dlg.masterPasswordChanged.connect( 3172 lambda old, new: self.masterPasswordChanged(old, new, local=True)) 3173 dlg.show() 3174 if self.__lastConfigurationPageName: 3175 dlg.showConfigurationPageByName(self.__lastConfigurationPageName) 3176 else: 3177 dlg.showConfigurationPageByName("empty") 3178 dlg.exec() 3179 QApplication.processEvents() 3180 if dlg.result() == QDialog.DialogCode.Accepted: 3181 dlg.setPreferences() 3182 Preferences.syncPreferences() 3183 self.preferencesChanged() 3184 self.__lastConfigurationPageName = dlg.getConfigurationPageName() 3185 3186 def preferencesChanged(self): 3187 """ 3188 Public slot to handle a change of preferences. 3189 """ 3190 self.setStyle(Preferences.getUI("Style"), 3191 Preferences.getUI("StyleSheet")) 3192 3193 self.__initWebEngineSettings() 3194 3195 self.networkManager().preferencesChanged() 3196 3197 self.historyManager().preferencesChanged() 3198 3199 self.__tabWidget.preferencesChanged() 3200 3201 self.__navigationBar.searchEdit().preferencesChanged() 3202 3203 self.autoScroller().preferencesChanged() 3204 3205 profile = self.webProfile() 3206 if not self.isPrivate(): 3207 if Preferences.getWebBrowser("DiskCacheEnabled"): 3208 profile.setHttpCacheType( 3209 QWebEngineProfile.HttpCacheType.DiskHttpCache) 3210 profile.setHttpCacheMaximumSize( 3211 Preferences.getWebBrowser("DiskCacheSize") * 1024 * 1024) 3212 else: 3213 profile.setHttpCacheType( 3214 QWebEngineProfile.HttpCacheType.MemoryHttpCache) 3215 profile.setHttpCacheMaximumSize(0) 3216 3217 with contextlib.suppress(AttributeError): 3218 profile.setSpellCheckEnabled( 3219 Preferences.getWebBrowser("SpellCheckEnabled")) 3220 profile.setSpellCheckLanguages( 3221 Preferences.getWebBrowser("SpellCheckLanguages")) 3222 3223 self.__virusTotal.preferencesChanged() 3224 if ( 3225 not Preferences.getWebBrowser("VirusTotalEnabled") or 3226 Preferences.getWebBrowser("VirusTotalServiceKey") == "" 3227 ): 3228 self.virustotalScanCurrentAct.setEnabled(False) 3229 self.virustotalIpReportAct.setEnabled(False) 3230 self.virustotalDomainReportAct.setEnabled(False) 3231 else: 3232 self.virustotalScanCurrentAct.setEnabled(True) 3233 self.virustotalIpReportAct.setEnabled(True) 3234 self.virustotalDomainReportAct.setEnabled(True) 3235 3236 self.__javaScriptIcon.preferencesChanged() 3237 3238 if not WebBrowserWindow.isPrivate(): 3239 self.sessionManager().preferencesChanged() 3240 3241 def masterPasswordChanged(self, oldPassword, newPassword, local=False): 3242 """ 3243 Public slot to handle the change of the master password. 3244 3245 @param oldPassword current master password 3246 @type str 3247 @param newPassword new master password 3248 @type str 3249 @param local flag indicating being called from the local configuration 3250 dialog 3251 @type bool 3252 """ 3253 self.passwordManager().masterPasswordChanged(oldPassword, newPassword) 3254 if local: 3255 # we were called from our local configuration dialog 3256 Preferences.convertPasswords(oldPassword, newPassword) 3257 Utilities.crypto.changeRememberedMaster(newPassword) 3258 3259 def __showAcceptedLanguages(self): 3260 """ 3261 Private slot to configure the accepted languages for web pages. 3262 """ 3263 from .WebBrowserLanguagesDialog import WebBrowserLanguagesDialog 3264 dlg = WebBrowserLanguagesDialog(self) 3265 dlg.exec() 3266 self.networkManager().languagesChanged() 3267 3268 def __showCookiesConfiguration(self): 3269 """ 3270 Private slot to configure the cookies handling. 3271 """ 3272 from .CookieJar.CookiesConfigurationDialog import ( 3273 CookiesConfigurationDialog 3274 ) 3275 dlg = CookiesConfigurationDialog(self) 3276 dlg.exec() 3277 3278 @classmethod 3279 def setUseQtHelp(cls, use): 3280 """ 3281 Class method to set the QtHelp usage. 3282 3283 @param use flag indicating usage (boolean) 3284 """ 3285 if use: 3286 cls._useQtHelp = use and QTHELP_AVAILABLE 3287 else: 3288 cls._useQtHelp = False 3289 3290 @classmethod 3291 def helpEngine(cls): 3292 """ 3293 Class method to get a reference to the help engine. 3294 3295 @return reference to the help engine (QHelpEngine) 3296 """ 3297 if cls._useQtHelp: 3298 if cls._helpEngine is None: 3299 cls._helpEngine = QHelpEngine( 3300 WebBrowserWindow.getQtHelpCollectionFileName()) 3301 return cls._helpEngine 3302 else: 3303 return None 3304 3305 @classmethod 3306 def getQtHelpCollectionFileName(cls): 3307 """ 3308 Class method to determine the name of the QtHelp collection file. 3309 3310 @return path of the QtHelp collection file 3311 @rtype str 3312 """ 3313 qthelpDir = os.path.join(Utilities.getConfigDir(), "qthelp") 3314 if not os.path.exists(qthelpDir): 3315 os.makedirs(qthelpDir) 3316 return os.path.join(qthelpDir, "eric6help.qhc") 3317 3318 @classmethod 3319 def networkManager(cls): 3320 """ 3321 Class method to get a reference to the network manager object. 3322 3323 @return reference to the network access manager (NetworkManager) 3324 """ 3325 if cls._networkManager is None: 3326 from .Network.NetworkManager import NetworkManager 3327 cls._networkManager = NetworkManager(cls.helpEngine()) 3328 3329 return cls._networkManager 3330 3331 @classmethod 3332 def cookieJar(cls): 3333 """ 3334 Class method to get a reference to the cookie jar. 3335 3336 @return reference to the cookie jar (CookieJar) 3337 """ 3338 if cls._cookieJar is None: 3339 from .CookieJar.CookieJar import CookieJar 3340 cls._cookieJar = CookieJar() 3341 3342 return cls._cookieJar 3343 3344 def __clearIconsDatabase(self): 3345 """ 3346 Private slot to clear the favicons databse. 3347 """ 3348 WebIconProvider.instance().clear() 3349 3350 def __showWebIconsDialog(self): 3351 """ 3352 Private slot to show a dialog to manage the favicons database. 3353 """ 3354 WebIconProvider.instance().showWebIconDialog() 3355 3356 @pyqtSlot(QUrl) 3357 def urlHandler(self, url): 3358 """ 3359 Public slot used as desktop URL handler. 3360 3361 @param url URL to be handled 3362 @type QUrl 3363 """ 3364 self.__linkActivated(url) 3365 3366 @pyqtSlot(QUrl) 3367 def __linkActivated(self, url): 3368 """ 3369 Private slot to handle the selection of a link. 3370 3371 @param url URL to be shown 3372 @type QUrl 3373 """ 3374 if not self.__activating: 3375 self.__activating = True 3376 cb = self.currentBrowser() 3377 if cb is None: 3378 self.newTab(url) 3379 else: 3380 cb.setUrl(url) 3381 self.__activating = False 3382 3383 def __activateCurrentBrowser(self): 3384 """ 3385 Private slot to activate the current browser. 3386 """ 3387 self.currentBrowser().setFocus() 3388 3389 def __syncTOC(self): 3390 """ 3391 Private slot to synchronize the TOC with the currently shown page. 3392 """ 3393 if WebBrowserWindow._useQtHelp: 3394 with E5OverrideCursor(): 3395 url = self.currentBrowser().source() 3396 self.__showTocWindow() 3397 if not self.__tocWindow.syncToContent(url): 3398 self.statusBar().showMessage( 3399 self.tr("Could not find an associated content."), 5000) 3400 3401 def __showTocWindow(self): 3402 """ 3403 Private method to show the table of contents window. 3404 """ 3405 if WebBrowserWindow._useQtHelp: 3406 self.__activateDock(self.__tocWindow) 3407 3408 def __showIndexWindow(self): 3409 """ 3410 Private method to show the index window. 3411 """ 3412 if WebBrowserWindow._useQtHelp: 3413 self.__activateDock(self.__indexWindow) 3414 3415 def __showSearchWindow(self): 3416 """ 3417 Private method to show the search window. 3418 """ 3419 if WebBrowserWindow._useQtHelp: 3420 self.__activateDock(self.__searchWindow) 3421 3422 def __activateDock(self, widget): 3423 """ 3424 Private method to activate the dock widget of the given widget. 3425 3426 @param widget reference to the widget to be activated (QWidget) 3427 """ 3428 widget.parent().show() 3429 widget.parent().raise_() 3430 widget.setFocus() 3431 3432 def __setupFilterCombo(self): 3433 """ 3434 Private slot to setup the filter combo box. 3435 """ 3436 if WebBrowserWindow._useQtHelp: 3437 curFilter = self.filterCombo.currentText() 3438 if not curFilter: 3439 curFilter = self.__helpEngine.currentFilter() 3440 self.filterCombo.clear() 3441 self.filterCombo.addItems(self.__helpEngine.customFilters()) 3442 idx = self.filterCombo.findText(curFilter) 3443 if idx < 0: 3444 idx = 0 3445 self.filterCombo.setCurrentIndex(idx) 3446 3447 def __filterQtHelpDocumentation(self, index): 3448 """ 3449 Private slot to filter the QtHelp documentation. 3450 3451 @param index index of the selected entry 3452 @type int 3453 """ 3454 customFilter = self.filterCombo.itemText(index) 3455 if self.__helpEngine: 3456 self.__helpEngine.setCurrentFilter(customFilter) 3457 3458 def __manageQtHelpDocumentation(self): 3459 """ 3460 Private slot to manage the QtHelp documentation database. 3461 """ 3462 if WebBrowserWindow._useQtHelp: 3463 from .QtHelp.QtHelpDocumentationDialog import ( 3464 QtHelpDocumentationDialog 3465 ) 3466 dlg = QtHelpDocumentationDialog(self.__helpEngine, self) 3467 dlg.exec() 3468 if dlg.hasDocumentationChanges(): 3469 for i in sorted(dlg.getTabsToClose(), reverse=True): 3470 self.__tabWidget.closeBrowserAt(i) 3471 self.__searchEngine.reindexDocumentation() 3472 3473 def getSourceFileList(self): 3474 """ 3475 Public method to get a list of all opened source files. 3476 3477 @return dictionary with tab id as key and host/namespace as value 3478 """ 3479 return self.__tabWidget.getSourceFileList() 3480 3481 def __indexingStarted(self): 3482 """ 3483 Private slot to handle the start of the indexing process. 3484 """ 3485 if WebBrowserWindow._useQtHelp: 3486 self.__indexing = True 3487 if self.__indexingProgress is None: 3488 self.__indexingProgress = QWidget() 3489 layout = QHBoxLayout(self.__indexingProgress) 3490 layout.setContentsMargins(0, 0, 0, 0) 3491 sizePolicy = QSizePolicy(QSizePolicy.Policy.Preferred, 3492 QSizePolicy.Policy.Maximum) 3493 3494 label = QLabel(self.tr("Updating search index")) 3495 label.setSizePolicy(sizePolicy) 3496 layout.addWidget(label) 3497 3498 progressBar = QProgressBar() 3499 progressBar.setRange(0, 0) 3500 progressBar.setTextVisible(False) 3501 progressBar.setFixedHeight(16) 3502 progressBar.setSizePolicy(sizePolicy) 3503 layout.addWidget(progressBar) 3504 3505 self.statusBar().insertPermanentWidget( 3506 0, self.__indexingProgress) 3507 3508 def __indexingFinished(self): 3509 """ 3510 Private slot to handle the start of the indexing process. 3511 """ 3512 if WebBrowserWindow._useQtHelp: 3513 self.statusBar().removeWidget(self.__indexingProgress) 3514 self.__indexingProgress = None 3515 self.__indexing = False 3516 if self.__searchWord is not None: 3517 self.__searchForWord() 3518 3519 def __searchForWord(self): 3520 """ 3521 Private slot to search for a word. 3522 """ 3523 if ( 3524 WebBrowserWindow._useQtHelp and 3525 not self.__indexing and 3526 self.__searchWord is not None 3527 ): 3528 self.__searchDock.show() 3529 self.__searchDock.raise_() 3530 query = QHelpSearchQuery(QHelpSearchQuery.FieldName.DEFAULT, 3531 [self.__searchWord]) 3532 self.__searchEngine.search([query]) 3533 self.__searchWord = None 3534 3535 def search(self, word): 3536 """ 3537 Public method to search for a word. 3538 3539 @param word word to search for (string) 3540 """ 3541 if WebBrowserWindow._useQtHelp: 3542 self.__searchWord = word 3543 self.__searchForWord() 3544 3545 def __removeOldDocumentation(self): 3546 """ 3547 Private slot to remove non-existing documentation from the help engine. 3548 """ 3549 if WebBrowserWindow._useQtHelp: 3550 for namespace in self.__helpEngine.registeredDocumentations(): 3551 docFile = self.__helpEngine.documentationFileName(namespace) 3552 if not os.path.exists(docFile): 3553 self.__helpEngine.unregisterDocumentation(namespace) 3554 3555 def __lookForNewDocumentation(self): 3556 """ 3557 Private slot to look for new documentation to be loaded into the 3558 help database. 3559 """ 3560 if WebBrowserWindow._useQtHelp: 3561 from .QtHelp.HelpDocsInstaller import HelpDocsInstaller 3562 self.__helpInstaller = HelpDocsInstaller( 3563 self.__helpEngine.collectionFile()) 3564 self.__helpInstaller.errorMessage.connect( 3565 self.__showInstallationError) 3566 self.__helpInstaller.docsInstalled.connect(self.__docsInstalled) 3567 3568 self.statusBar().showMessage( 3569 self.tr("Looking for Documentation...")) 3570 self.__helpInstaller.installDocs() 3571 3572 def __showInstallationError(self, message): 3573 """ 3574 Private slot to show installation errors. 3575 3576 @param message message to be shown (string) 3577 """ 3578 E5MessageBox.warning( 3579 self, 3580 self.tr("eric Web Browser"), 3581 message) 3582 3583 def __docsInstalled(self, installed): 3584 """ 3585 Private slot handling the end of documentation installation. 3586 3587 @param installed flag indicating that documents were installed 3588 (boolean) 3589 """ 3590 if WebBrowserWindow._useQtHelp: 3591 self.statusBar().clearMessage() 3592 3593 def __initHelpDb(self): 3594 """ 3595 Private slot to initialize the documentation database. 3596 """ 3597 if WebBrowserWindow._useQtHelp: 3598 unfiltered = self.tr("Unfiltered") 3599 if unfiltered not in self.__helpEngine.customFilters(): 3600 hc = QHelpEngineCore(self.__helpEngine.collectionFile()) 3601 hc.addCustomFilter(unfiltered, []) 3602 hc = None 3603 del hc 3604 3605 self.__helpEngine.blockSignals(True) 3606 self.__helpEngine.setCurrentFilter(unfiltered) 3607 self.__helpEngine.blockSignals(False) 3608 3609 def __warning(self, msg): 3610 """ 3611 Private slot handling warnings from the help engine. 3612 3613 @param msg message sent by the help engine (string) 3614 """ 3615 E5MessageBox.warning( 3616 self, 3617 self.tr("Help Engine"), msg) 3618 3619 def __aboutToShowSettingsMenu(self): 3620 """ 3621 Private slot to show the Settings menu. 3622 """ 3623 self.editMessageFilterAct.setEnabled( 3624 E5ErrorMessage.messageHandlerInstalled()) 3625 3626 def __clearPrivateData(self): 3627 """ 3628 Private slot to clear the private data. 3629 """ 3630 from .WebBrowserClearPrivateDataDialog import ( 3631 WebBrowserClearPrivateDataDialog 3632 ) 3633 dlg = WebBrowserClearPrivateDataDialog(self) 3634 if dlg.exec() == QDialog.DialogCode.Accepted: 3635 # browsing history, search history, favicons, disk cache, cookies, 3636 # passwords, web databases, downloads, zoom values, SSL error 3637 # exceptions, history period 3638 (history, searches, favicons, cache, cookies, 3639 passwords, databases, downloads, zoomValues, 3640 sslExceptions, historyPeriod) = dlg.getData() 3641 if history: 3642 self.historyManager().clear(historyPeriod) 3643 self.__tabWidget.clearClosedTabsList() 3644 self.webProfile().clearAllVisitedLinks() 3645 if searches: 3646 self.__navigationBar.searchEdit().clear() 3647 if downloads: 3648 self.downloadManager().cleanup() 3649 self.downloadManager().hide() 3650 if favicons: 3651 self.__clearIconsDatabase() 3652 if cache: 3653 try: 3654 self.webProfile().clearHttpCache() 3655 except AttributeError: 3656 cachePath = self.webProfile().cachePath() 3657 if cachePath: 3658 shutil.rmtree(cachePath) 3659 if cookies: 3660 self.cookieJar().clear() 3661 self.webProfile().cookieStore().deleteAllCookies() 3662 if passwords: 3663 self.passwordManager().clear() 3664 if zoomValues: 3665 ZoomManager.instance().clear() 3666 if sslExceptions: 3667 self.networkManager().clearSslExceptions() 3668 3669 def __showEnginesConfigurationDialog(self): 3670 """ 3671 Private slot to show the search engines configuration dialog. 3672 """ 3673 from .OpenSearch.OpenSearchDialog import OpenSearchDialog 3674 3675 dlg = OpenSearchDialog(self) 3676 dlg.exec() 3677 3678 def searchEnginesAction(self): 3679 """ 3680 Public method to get a reference to the search engines configuration 3681 action. 3682 3683 @return reference to the search engines configuration action (QAction) 3684 """ 3685 return self.searchEnginesAct 3686 3687 def __showPasswordsDialog(self): 3688 """ 3689 Private slot to show the passwords management dialog. 3690 """ 3691 from .Passwords.PasswordsDialog import PasswordsDialog 3692 3693 dlg = PasswordsDialog(self) 3694 dlg.exec() 3695 3696 def __showCertificateErrorsDialog(self): 3697 """ 3698 Private slot to show the certificate errors management dialog. 3699 """ 3700 self.networkManager().showSslErrorExceptionsDialog() 3701 3702 def __showAdBlockDialog(self): 3703 """ 3704 Private slot to show the AdBlock configuration dialog. 3705 """ 3706 self.adBlockManager().showDialog() 3707 3708 def __showPersonalInformationDialog(self): 3709 """ 3710 Private slot to show the Personal Information configuration dialog. 3711 """ 3712 self.personalInformationManager().showConfigurationDialog() 3713 3714 def __showGreaseMonkeyConfigDialog(self): 3715 """ 3716 Private slot to show the GreaseMonkey scripts configuration dialog. 3717 """ 3718 self.greaseMonkeyManager().showConfigurationDialog() 3719 3720 def __showFeaturePermissionDialog(self): 3721 """ 3722 Private slot to show the feature permission dialog. 3723 """ 3724 self.featurePermissionManager().showFeaturePermissionsDialog() 3725 3726 def __showZoomValuesDialog(self): 3727 """ 3728 Private slot to show the zoom values management dialog. 3729 """ 3730 from .ZoomManager.ZoomValuesDialog import ZoomValuesDialog 3731 3732 dlg = ZoomValuesDialog(self) 3733 dlg.exec() 3734 3735 def __showDownloadsWindow(self): 3736 """ 3737 Private slot to show the downloads dialog. 3738 """ 3739 self.downloadManager().show() 3740 3741 def __showPageSource(self): 3742 """ 3743 Private slot to show the source of the current page in an editor. 3744 """ 3745 self.currentBrowser().page().toHtml(self.__showPageSourceCallback) 3746 3747 def __showPageSourceCallback(self, src): 3748 """ 3749 Private method to show the source of the current page in an editor. 3750 3751 @param src source of the web page 3752 @type str 3753 """ 3754 from QScintilla.MiniEditor import MiniEditor 3755 editor = MiniEditor(parent=self) 3756 editor.setText(src, "Html") 3757 editor.setLanguage("dummy.html") 3758 editor.show() 3759 3760 def __toggleJavaScriptConsole(self): 3761 """ 3762 Private slot to toggle the JavaScript console. 3763 """ 3764 if self.__javascriptConsoleDock.isVisible(): 3765 self.__javascriptConsoleDock.hide() 3766 else: 3767 self.__javascriptConsoleDock.show() 3768 3769 def javascriptConsole(self): 3770 """ 3771 Public method to get a reference to the JavaScript console widget. 3772 3773 @return reference to the JavaScript console 3774 @rtype WebBrowserJavaScriptConsole 3775 """ 3776 return self.__javascriptConsole 3777 3778 @classmethod 3779 def icon(cls, url): 3780 """ 3781 Class method to get the icon for an URL. 3782 3783 @param url URL to get icon for (QUrl) 3784 @return icon for the URL (QIcon) 3785 """ 3786 return WebIconProvider.instance().iconForUrl(url) 3787 3788 @classmethod 3789 def bookmarksManager(cls): 3790 """ 3791 Class method to get a reference to the bookmarks manager. 3792 3793 @return reference to the bookmarks manager (BookmarksManager) 3794 """ 3795 if cls._bookmarksManager is None: 3796 from .Bookmarks.BookmarksManager import BookmarksManager 3797 cls._bookmarksManager = BookmarksManager() 3798 3799 return cls._bookmarksManager 3800 3801 def openUrl(self, url, title=None): 3802 """ 3803 Public slot to load a URL in the current tab. 3804 3805 @param url URL to be opened (QUrl) 3806 @param title title of the bookmark (string) 3807 """ 3808 self.__linkActivated(url) 3809 3810 def openUrlNewTab(self, url, title=None): 3811 """ 3812 Public slot to load a URL in a new tab. 3813 3814 @param url URL to be opened (QUrl) 3815 @param title title of the bookmark (string) 3816 """ 3817 self.newTab(url) 3818 3819 def openUrlNewBackgroundTab(self, url, title=None): 3820 """ 3821 Public slot to load a URL in a new background tab. 3822 3823 @param url URL to be opened (QUrl) 3824 @param title title of the bookmark (string) 3825 """ 3826 self.newTab(url, background=True) 3827 3828 def openUrlNewWindow(self, url, title=None): 3829 """ 3830 Public slot to load a URL in a new window. 3831 3832 @param url URL to be opened (QUrl) 3833 @param title title of the bookmark (string) 3834 """ 3835 self.newWindow(url) 3836 3837 def openUrlNewPrivateWindow(self, url, title=None): 3838 """ 3839 Public slot to load a URL in a new private window. 3840 3841 @param url URL to be opened (QUrl) 3842 @param title title of the bookmark (string) 3843 """ 3844 self.newPrivateWindow(url) 3845 3846 def __sendPageLink(self): 3847 """ 3848 Private slot to send the link of the current page via email. 3849 """ 3850 url = self.currentBrowser().url() 3851 if not url.isEmpty(): 3852 urlStr = url.toString() 3853 QDesktopServices.openUrl(QUrl("mailto:?body=" + urlStr)) 3854 3855 @classmethod 3856 def historyManager(cls): 3857 """ 3858 Class method to get a reference to the history manager. 3859 3860 @return reference to the history manager (HistoryManager) 3861 """ 3862 if cls._historyManager is None: 3863 from .History.HistoryManager import HistoryManager 3864 cls._historyManager = HistoryManager() 3865 3866 return cls._historyManager 3867 3868 @classmethod 3869 def passwordManager(cls): 3870 """ 3871 Class method to get a reference to the password manager. 3872 3873 @return reference to the password manager (PasswordManager) 3874 """ 3875 if cls._passwordManager is None: 3876 from .Passwords.PasswordManager import PasswordManager 3877 cls._passwordManager = PasswordManager() 3878 3879 return cls._passwordManager 3880 3881 @classmethod 3882 def adBlockManager(cls): 3883 """ 3884 Class method to get a reference to the AdBlock manager. 3885 3886 @return reference to the AdBlock manager (AdBlockManager) 3887 """ 3888 if cls._adblockManager is None: 3889 from .AdBlock.AdBlockManager import AdBlockManager 3890 cls._adblockManager = AdBlockManager() 3891 3892 return cls._adblockManager 3893 3894 def adBlockIcon(self): 3895 """ 3896 Public method to get a reference to the AdBlock icon. 3897 3898 @return reference to the AdBlock icon (AdBlockIcon) 3899 """ 3900 return self.__adBlockIcon 3901 3902 @classmethod 3903 def downloadManager(cls): 3904 """ 3905 Class method to get a reference to the download manager. 3906 3907 @return reference to the download manager (DownloadManager) 3908 """ 3909 if cls._downloadManager is None: 3910 from .Download.DownloadManager import DownloadManager 3911 cls._downloadManager = DownloadManager() 3912 3913 return cls._downloadManager 3914 3915 @classmethod 3916 def personalInformationManager(cls): 3917 """ 3918 Class method to get a reference to the personal information manager. 3919 3920 @return reference to the personal information manager 3921 (PersonalInformationManager) 3922 """ 3923 if cls._personalInformationManager is None: 3924 from .PersonalInformationManager import PersonalInformationManager 3925 cls._personalInformationManager = ( 3926 PersonalInformationManager.PersonalInformationManager() 3927 ) 3928 3929 return cls._personalInformationManager 3930 3931 @classmethod 3932 def greaseMonkeyManager(cls): 3933 """ 3934 Class method to get a reference to the GreaseMonkey manager. 3935 3936 @return reference to the GreaseMonkey manager (GreaseMonkeyManager) 3937 """ 3938 if cls._greaseMonkeyManager is None: 3939 from .GreaseMonkey.GreaseMonkeyManager import GreaseMonkeyManager 3940 cls._greaseMonkeyManager = GreaseMonkeyManager() 3941 3942 return cls._greaseMonkeyManager 3943 3944 @classmethod 3945 def featurePermissionManager(cls): 3946 """ 3947 Class method to get a reference to the feature permission manager. 3948 3949 @return reference to the feature permission manager 3950 @rtype FeaturePermissionManager 3951 """ 3952 if cls._featurePermissionManager is None: 3953 from .FeaturePermissions.FeaturePermissionManager import ( 3954 FeaturePermissionManager 3955 ) 3956 cls._featurePermissionManager = FeaturePermissionManager() 3957 3958 return cls._featurePermissionManager 3959 3960 @classmethod 3961 def imageSearchEngine(cls): 3962 """ 3963 Class method to get a reference to the image search engine. 3964 3965 @return reference to the image finder object 3966 @rtype ImageSearchEngine 3967 """ 3968 if cls._imageSearchEngine is None: 3969 from .ImageSearch.ImageSearchEngine import ( 3970 ImageSearchEngine 3971 ) 3972 cls._imageSearchEngine = ImageSearchEngine() 3973 3974 return cls._imageSearchEngine 3975 3976 @classmethod 3977 def autoScroller(cls): 3978 """ 3979 Class method to get a reference to the auto scroller. 3980 3981 @return reference to the auto scroller object 3982 @rtype AutoScroller 3983 """ 3984 if cls._autoScroller is None: 3985 from .AutoScroll.AutoScroller import AutoScroller 3986 cls._autoScroller = AutoScroller() 3987 3988 return cls._autoScroller 3989 3990 @classmethod 3991 def tabManager(cls): 3992 """ 3993 Class method to get a reference to the tab manager widget. 3994 3995 @return reference to the tab manager widget 3996 @rtype TabManagerWidget 3997 """ 3998 if cls._tabManager is None: 3999 from .TabManager.TabManagerWidget import TabManagerWidget 4000 cls._tabManager = TabManagerWidget(cls.mainWindow()) 4001 4002 # do the connections 4003 for window in cls.mainWindows(): 4004 cls._tabManager.mainWindowCreated(window, False) 4005 4006 cls._tabManager.delayedRefreshTree() 4007 4008 return cls._tabManager 4009 4010 def __showTabManager(self, act): 4011 """ 4012 Private method to show the tab manager window. 4013 4014 @param act reference to the act that triggered 4015 @type QAction 4016 """ 4017 self.tabManager().raiseTabManager(act) 4018 4019 @classmethod 4020 def mainWindow(cls): 4021 """ 4022 Class method to get a reference to the main window. 4023 4024 @return reference to the main window (WebBrowserWindow) 4025 """ 4026 if cls.BrowserWindows: 4027 return cls.BrowserWindows[0] 4028 else: 4029 return None 4030 4031 @classmethod 4032 def mainWindows(cls): 4033 """ 4034 Class method to get references to all main windows. 4035 4036 @return references to all main window (list of WebBrowserWindow) 4037 """ 4038 return cls.BrowserWindows 4039 4040 @pyqtSlot() 4041 def __appFocusChanged(self): 4042 """ 4043 Private slot to handle a change of the focus. 4044 """ 4045 focusWindow = e5App().activeWindow() 4046 if isinstance(focusWindow, WebBrowserWindow): 4047 WebBrowserWindow._lastActiveWindow = focusWindow 4048 4049 @classmethod 4050 def getWindow(cls): 4051 """ 4052 Class method to get a reference to the most recent active 4053 web browser window. 4054 4055 @return reference to most recent web browser window 4056 @rtype WebBrowserWindow 4057 """ 4058 if cls._lastActiveWindow: 4059 return cls._lastActiveWindow 4060 4061 return cls.mainWindow() 4062 4063 def openSearchManager(self): 4064 """ 4065 Public method to get a reference to the opensearch manager object. 4066 4067 @return reference to the opensearch manager object (OpenSearchManager) 4068 """ 4069 return self.__navigationBar.searchEdit().openSearchManager() 4070 4071 def __createTextEncodingAction(self, codec, defaultCodec, parentMenu, 4072 name=None): 4073 """ 4074 Private method to create an action for the text encoding menu. 4075 4076 @param codec name of the codec to create an action for 4077 @type str 4078 @param defaultCodec name of the default codec 4079 @type str 4080 @param parentMenu reference to the parent menu 4081 @type QMenu 4082 @param name name for the action 4083 @type str 4084 """ 4085 act = QAction(name, parentMenu) if name else QAction(codec, parentMenu) 4086 act.setData(codec) 4087 act.setCheckable(True) 4088 if defaultCodec == codec: 4089 act.setChecked(True) 4090 4091 parentMenu.addAction(act) 4092 4093 def __createTextEncodingSubmenu(self, title, codecNames, parentMenu): 4094 """ 4095 Private method to create a text encoding sub menu. 4096 4097 @param title title of the menu 4098 @type str 4099 @param codecNames list of codec names for the menu 4100 @type list of str 4101 @param parentMenu reference to the parent menu 4102 @type QMenu 4103 """ 4104 if codecNames: 4105 defaultCodec = self.webSettings().defaultTextEncoding().lower() 4106 4107 menu = QMenu(title, parentMenu) 4108 for codec in codecNames: 4109 self.__createTextEncodingAction(codec, defaultCodec, menu) 4110 4111 parentMenu.addMenu(menu) 4112 4113 def __aboutToShowTextEncodingMenu(self): 4114 """ 4115 Private slot to populate the text encoding menu. 4116 """ 4117 self.__textEncodingMenu.clear() 4118 4119 defaultTextEncoding = self.webSettings().defaultTextEncoding().lower() 4120 currentCodec = ( 4121 defaultTextEncoding 4122 if defaultTextEncoding in Utilities.supportedCodecs else 4123 "" 4124 ) 4125 4126 isoCodecs = [] 4127 winCodecs = [] 4128 uniCodecs = [] 4129 cpCodecs = [] 4130 macCodecs = [] 4131 otherCodecs = [] 4132 4133 for codec in sorted(Utilities.supportedCodecs): 4134 if codec.startswith(("iso-", "latin")): 4135 isoCodecs.append(codec) 4136 elif codec.startswith(("windows-")): 4137 winCodecs.append(codec) 4138 elif codec.startswith("utf-"): 4139 uniCodecs.append(codec) 4140 elif codec.startswith("cp"): 4141 cpCodecs.append(codec) 4142 elif codec.startswith("mac-"): 4143 macCodecs.append(codec) 4144 else: 4145 otherCodecs.append(codec) 4146 4147 self.__createTextEncodingAction( 4148 "", currentCodec, self.__textEncodingMenu, name=self.tr("System")) 4149 self.__textEncodingMenu.addSeparator() 4150 self.__createTextEncodingSubmenu(self.tr("ISO"), isoCodecs, 4151 self.__textEncodingMenu) 4152 self.__createTextEncodingSubmenu(self.tr("Unicode"), uniCodecs, 4153 self.__textEncodingMenu) 4154 self.__createTextEncodingSubmenu(self.tr("Windows"), winCodecs, 4155 self.__textEncodingMenu) 4156 self.__createTextEncodingSubmenu(self.tr("IBM"), cpCodecs, 4157 self.__textEncodingMenu) 4158 self.__createTextEncodingSubmenu(self.tr("Apple"), macCodecs, 4159 self.__textEncodingMenu) 4160 self.__createTextEncodingSubmenu(self.tr("Other"), otherCodecs, 4161 self.__textEncodingMenu) 4162 4163 def __setTextEncoding(self, act): 4164 """ 4165 Private slot to set the selected text encoding as the default for 4166 this session. 4167 4168 @param act reference to the selected action (QAction) 4169 """ 4170 codec = act.data() 4171 if codec == "": 4172 self.webSettings().setDefaultTextEncoding("") 4173 else: 4174 self.webSettings().setDefaultTextEncoding(codec) 4175 4176 def __populateToolbarsMenu(self, menu): 4177 """ 4178 Private method to populate the toolbars menu. 4179 4180 @param menu reference to the menu to be populated 4181 @type QMenu 4182 """ 4183 menu.clear() 4184 4185 act = menu.addAction(self.tr("Menu Bar")) 4186 act.setCheckable(True) 4187 act.setChecked(not self.menuBar().isHidden()) 4188 act.setData("menubar") 4189 4190 act = menu.addAction(self.tr("Bookmarks")) 4191 act.setCheckable(True) 4192 act.setChecked(not self.__bookmarksToolBar.isHidden()) 4193 act.setData("bookmarks") 4194 4195 act = menu.addAction(self.tr("Status Bar")) 4196 act.setCheckable(True) 4197 act.setChecked(not self.statusBar().isHidden()) 4198 act.setData("statusbar") 4199 4200 if Preferences.getWebBrowser("ShowToolbars"): 4201 menu.addSeparator() 4202 for name, (text, tb) in sorted(self.__toolbars.items(), 4203 key=lambda t: t[1][0]): 4204 act = menu.addAction(text) 4205 act.setCheckable(True) 4206 act.setChecked(not tb.isHidden()) 4207 act.setData(name) 4208 menu.addSeparator() 4209 act = menu.addAction(self.tr("&Show all")) 4210 act.setData("__SHOW__") 4211 act = menu.addAction(self.tr("&Hide all")) 4212 act.setData("__HIDE__") 4213 4214 def createPopupMenu(self): 4215 """ 4216 Public method to create the toolbars menu for Qt. 4217 4218 @return toolbars menu 4219 @rtype QMenu 4220 """ 4221 menu = QMenu(self) 4222 menu.triggered.connect(self.__TBMenuTriggered) 4223 4224 self.__populateToolbarsMenu(menu) 4225 4226 return menu 4227 4228 def __showToolbarsMenu(self): 4229 """ 4230 Private slot to display the Toolbars menu. 4231 """ 4232 self.__populateToolbarsMenu(self.__toolbarsMenu) 4233 4234 def __TBMenuTriggered(self, act): 4235 """ 4236 Private method to handle the toggle of a toolbar via the Window-> 4237 Toolbars submenu or the toolbars popup menu. 4238 4239 @param act reference to the action that was triggered 4240 @type QAction 4241 """ 4242 name = act.data() 4243 if name: 4244 if name == "bookmarks": 4245 # special handling of bookmarks toolbar 4246 self.__setBookmarksToolbarVisibility(act.isChecked()) 4247 4248 elif name == "menubar": 4249 # special treatment of the menu bar 4250 self.__setMenuBarVisibility(act.isChecked()) 4251 4252 elif name == "statusbar": 4253 # special treatment of the status bar 4254 self.__setStatusBarVisible(act.isChecked()) 4255 4256 elif name == "__SHOW__": 4257 for _text, tb in list(self.__toolbars.values()): 4258 tb.show() 4259 4260 elif name == "__HIDE__": 4261 for _text, tb in list(self.__toolbars.values()): 4262 tb.hide() 4263 4264 else: 4265 tb = self.__toolbars[name][1] 4266 if act.isChecked(): 4267 tb.show() 4268 else: 4269 tb.hide() 4270 4271 def __setBookmarksToolbarVisibility(self, visible): 4272 """ 4273 Private method to set the visibility of the bookmarks toolbar. 4274 4275 @param visible flag indicating the toolbar visibility 4276 @type bool 4277 """ 4278 if visible: 4279 self.__bookmarksToolBar.show() 4280 else: 4281 self.__bookmarksToolBar.hide() 4282 4283 # save state for next invokation 4284 Preferences.setWebBrowser("BookmarksToolBarVisible", visible) 4285 4286 def __setMenuBarVisibility(self, visible): 4287 """ 4288 Private method to set the visibility of the menu bar. 4289 4290 @param visible flag indicating the menu bar visibility 4291 @type bool 4292 """ 4293 if visible: 4294 self.menuBar().show() 4295 self.__navigationBar.superMenuButton().hide() 4296 else: 4297 self.menuBar().hide() 4298 self.__navigationBar.superMenuButton().show() 4299 4300 Preferences.setWebBrowser("MenuBarVisible", visible) 4301 4302 def __setStatusBarVisible(self, visible): 4303 """ 4304 Private method to set the visibility of the status bar. 4305 4306 @param visible flag indicating the status bar visibility 4307 @type bool 4308 """ 4309 self.statusBar().setVisible(visible) 4310 4311 Preferences.setWebBrowser("StatusBarVisible", visible) 4312 4313 def eventMouseButtons(self): 4314 """ 4315 Public method to get the last recorded mouse buttons. 4316 4317 @return mouse buttons (Qt.MouseButtons) 4318 """ 4319 return self.__eventMouseButtons 4320 4321 def eventKeyboardModifiers(self): 4322 """ 4323 Public method to get the last recorded keyboard modifiers. 4324 4325 @return keyboard modifiers (Qt.KeyboardModifiers) 4326 """ 4327 return self.__eventKeyboardModifiers 4328 4329 def setEventMouseButtons(self, buttons): 4330 """ 4331 Public method to record mouse buttons. 4332 4333 @param buttons mouse buttons to record (Qt.MouseButtons) 4334 """ 4335 self.__eventMouseButtons = buttons 4336 4337 def setEventKeyboardModifiers(self, modifiers): 4338 """ 4339 Public method to record keyboard modifiers. 4340 4341 @param modifiers keyboard modifiers to record (Qt.KeyboardModifiers) 4342 """ 4343 self.__eventKeyboardModifiers = modifiers 4344 4345 def mousePressEvent(self, evt): 4346 """ 4347 Protected method called by a mouse press event. 4348 4349 @param evt reference to the mouse event (QMouseEvent) 4350 """ 4351 if evt.button() == Qt.MouseButton.XButton1: 4352 self.currentBrowser().triggerPageAction( 4353 QWebEnginePage.WebAction.Back) 4354 elif evt.button() == Qt.MouseButton.XButton2: 4355 self.currentBrowser().triggerPageAction( 4356 QWebEnginePage.WebAction.Forward) 4357 else: 4358 super().mousePressEvent(evt) 4359 4360 @classmethod 4361 def feedsManager(cls): 4362 """ 4363 Class method to get a reference to the RSS feeds manager. 4364 4365 @return reference to the RSS feeds manager (FeedsManager) 4366 """ 4367 if cls._feedsManager is None: 4368 from .Feeds.FeedsManager import FeedsManager 4369 cls._feedsManager = FeedsManager() 4370 4371 return cls._feedsManager 4372 4373 def __showFeedsManager(self): 4374 """ 4375 Private slot to show the feeds manager dialog. 4376 """ 4377 feedsManager = self.feedsManager() 4378 feedsManager.openUrl.connect(self.openUrl) 4379 feedsManager.newTab.connect(self.openUrlNewTab) 4380 feedsManager.newBackgroundTab.connect(self.openUrlNewBackgroundTab) 4381 feedsManager.newWindow.connect(self.openUrlNewWindow) 4382 feedsManager.newPrivateWindow.connect(self.openUrlNewPrivateWindow) 4383 feedsManager.rejected.connect( 4384 lambda: self.__feedsManagerClosed(feedsManager)) 4385 feedsManager.show() 4386 4387 def __feedsManagerClosed(self, feedsManager): 4388 """ 4389 Private slot to handle closing the feeds manager dialog. 4390 4391 @param feedsManager reference to the feeds manager object 4392 @type FeedsManager 4393 """ 4394 feedsManager.openUrl.disconnect(self.openUrl) 4395 feedsManager.newTab.disconnect(self.openUrlNewTab) 4396 feedsManager.newBackgroundTab.disconnect(self.openUrlNewBackgroundTab) 4397 feedsManager.newWindow.disconnect(self.openUrlNewWindow) 4398 feedsManager.newPrivateWindow.disconnect(self.openUrlNewPrivateWindow) 4399 feedsManager.rejected.disconnect() 4400 4401 def __showSiteinfoDialog(self): 4402 """ 4403 Private slot to show the site info dialog. 4404 """ 4405 from .SiteInfo.SiteInfoDialog import SiteInfoDialog 4406 self.__siteinfoDialog = SiteInfoDialog(self.currentBrowser(), self) 4407 self.__siteinfoDialog.show() 4408 4409 @classmethod 4410 def userAgentsManager(cls): 4411 """ 4412 Class method to get a reference to the user agents manager. 4413 4414 @return reference to the user agents manager (UserAgentManager) 4415 """ 4416 if cls._userAgentsManager is None: 4417 from .UserAgent.UserAgentManager import UserAgentManager 4418 cls._userAgentsManager = UserAgentManager() 4419 4420 return cls._userAgentsManager 4421 4422 def __showUserAgentsDialog(self): 4423 """ 4424 Private slot to show the user agents management dialog. 4425 """ 4426 from .UserAgent.UserAgentsDialog import UserAgentsDialog 4427 4428 dlg = UserAgentsDialog(self) 4429 dlg.exec() 4430 4431 @classmethod 4432 def syncManager(cls): 4433 """ 4434 Class method to get a reference to the data synchronization manager. 4435 4436 @return reference to the data synchronization manager (SyncManager) 4437 """ 4438 if cls._syncManager is None: 4439 from .Sync.SyncManager import SyncManager 4440 cls._syncManager = SyncManager() 4441 4442 return cls._syncManager 4443 4444 def __showSyncDialog(self): 4445 """ 4446 Private slot to show the synchronization dialog. 4447 """ 4448 self.syncManager().showSyncDialog() 4449 4450 @classmethod 4451 def speedDial(cls): 4452 """ 4453 Class method to get a reference to the speed dial. 4454 4455 @return reference to the speed dial (SpeedDial) 4456 """ 4457 if cls._speedDial is None: 4458 from .SpeedDial.SpeedDial import SpeedDial 4459 cls._speedDial = SpeedDial() 4460 4461 return cls._speedDial 4462 4463 def keyPressEvent(self, evt): 4464 """ 4465 Protected method to handle key presses. 4466 4467 @param evt reference to the key press event (QKeyEvent) 4468 """ 4469 number = -1 4470 key = evt.key() 4471 4472 if key == Qt.Key.Key_1: 4473 number = 1 4474 elif key == Qt.Key.Key_2: 4475 number = 2 4476 elif key == Qt.Key.Key_3: 4477 number = 3 4478 elif key == Qt.Key.Key_4: 4479 number = 4 4480 elif key == Qt.Key.Key_5: 4481 number = 5 4482 elif key == Qt.Key.Key_6: 4483 number = 6 4484 elif key == Qt.Key.Key_7: 4485 number = 7 4486 elif key == Qt.Key.Key_8: 4487 number = 8 4488 elif key == Qt.Key.Key_9: 4489 number = 9 4490 elif key == Qt.Key.Key_0: 4491 number = 10 4492 4493 if number != -1: 4494 if evt.modifiers() == Qt.KeyboardModifiers( 4495 Qt.KeyboardModifier.AltModifier 4496 ): 4497 if number == 10: 4498 number = self.__tabWidget.count() 4499 self.__tabWidget.setCurrentIndex(number - 1) 4500 return 4501 4502 if evt.modifiers() == Qt.KeyboardModifiers( 4503 Qt.KeyboardModifier.MetaModifier 4504 ): 4505 url = self.speedDial().urlForShortcut(number - 1) 4506 if url.isValid(): 4507 self.__linkActivated(url) 4508 return 4509 4510 super().keyPressEvent(evt) 4511 4512 def event(self, evt): 4513 """ 4514 Public method handling events. 4515 4516 @param evt reference to the event 4517 @type QEvent 4518 @return flag indicating a handled event 4519 @rtype bool 4520 """ 4521 if evt.type() == QEvent.Type.WindowStateChange: 4522 if ( 4523 not bool(evt.oldState() & Qt.WindowState.WindowFullScreen) and 4524 bool(self.windowState() & Qt.WindowState.WindowFullScreen) 4525 ): 4526 # enter full screen mode 4527 self.__windowStates = evt.oldState() 4528 self.__toolbarStates = self.saveState() 4529 self.menuBar().hide() 4530 self.statusBar().hide() 4531 self.__searchWidget.hide() 4532 self.__tabWidget.tabBar().hide() 4533 if Preferences.getWebBrowser("ShowToolbars"): 4534 for _title, toolbar in self.__toolbars.values(): 4535 if toolbar is not self.__bookmarksToolBar: 4536 toolbar.hide() 4537 self.__navigationBar.exitFullScreenButton().setVisible(True) 4538 self.__navigationContainer.hide() 4539 4540 elif ( 4541 bool(evt.oldState() & Qt.WindowState.WindowFullScreen) and 4542 not bool(self.windowState() & Qt.WindowState.WindowFullScreen) 4543 ): 4544 # leave full screen mode 4545 self.setWindowState(self.__windowStates) 4546 self.__htmlFullScreen = False 4547 if Preferences.getWebBrowser("MenuBarVisible"): 4548 self.menuBar().show() 4549 if Preferences.getWebBrowser("StatusBarVisible"): 4550 self.statusBar().show() 4551 self.restoreState(self.__toolbarStates) 4552 self.__tabWidget.tabBar().show() 4553 self.__navigationBar.exitFullScreenButton().setVisible(False) 4554 self.__navigationContainer.show() 4555 4556 if self.__hideNavigationTimer: 4557 self.__hideNavigationTimer.stop() 4558 4559 return super().event(evt) 4560 4561 ########################################################################### 4562 ## Interface to VirusTotal below ## 4563 ########################################################################### 4564 4565 def __virusTotalScanCurrentSite(self): 4566 """ 4567 Private slot to ask VirusTotal for a scan of the URL of the current 4568 browser. 4569 """ 4570 cb = self.currentBrowser() 4571 if cb is not None: 4572 url = cb.url() 4573 if url.scheme() in ["http", "https", "ftp"]: 4574 self.requestVirusTotalScan(url) 4575 4576 def requestVirusTotalScan(self, url): 4577 """ 4578 Public method to submit a request to scan an URL by VirusTotal. 4579 4580 @param url URL to be scanned (QUrl) 4581 """ 4582 self.__virusTotal.submitUrl(url) 4583 4584 def __virusTotalSubmitUrlError(self, msg): 4585 """ 4586 Private slot to handle an URL scan submission error. 4587 4588 @param msg error message (str) 4589 """ 4590 E5MessageBox.critical( 4591 self, 4592 self.tr("VirusTotal Scan"), 4593 self.tr("""<p>The VirusTotal scan could not be""" 4594 """ scheduled.<p>\n<p>Reason: {0}</p>""").format(msg)) 4595 4596 def __virusTotalUrlScanReport(self, url): 4597 """ 4598 Private slot to initiate the display of the URL scan report page. 4599 4600 @param url URL of the URL scan report page (string) 4601 """ 4602 self.newTab(url) 4603 4604 def __virusTotalFileScanReport(self, url): 4605 """ 4606 Private slot to initiate the display of the file scan report page. 4607 4608 @param url URL of the file scan report page (string) 4609 """ 4610 self.newTab(url) 4611 4612 def __virusTotalIpAddressReport(self): 4613 """ 4614 Private slot to retrieve an IP address report. 4615 """ 4616 ip, ok = QInputDialog.getText( 4617 self, 4618 self.tr("IP Address Report"), 4619 self.tr("Enter a valid IPv4 address in dotted quad notation:"), 4620 QLineEdit.EchoMode.Normal) 4621 if ok and ip: 4622 if ip.count(".") == 3: 4623 self.__virusTotal.getIpAddressReport(ip) 4624 else: 4625 E5MessageBox.information( 4626 self, 4627 self.tr("IP Address Report"), 4628 self.tr("""The given IP address is not in dotted quad""" 4629 """ notation.""")) 4630 4631 def __virusTotalDomainReport(self): 4632 """ 4633 Private slot to retrieve a domain report. 4634 """ 4635 domain, ok = QInputDialog.getText( 4636 self, 4637 self.tr("Domain Report"), 4638 self.tr("Enter a valid domain name:"), 4639 QLineEdit.EchoMode.Normal) 4640 if ok and domain: 4641 self.__virusTotal.getDomainReport(domain) 4642 4643 ########################################################################### 4644 ## Style sheet handling below ## 4645 ########################################################################### 4646 4647 def reloadUserStyleSheet(self): 4648 """ 4649 Public method to reload the user style sheet. 4650 """ 4651 styleSheet = Preferences.getWebBrowser("UserStyleSheet") 4652 self.__setUserStyleSheet(styleSheet) 4653 4654 def __setUserStyleSheet(self, styleSheetFile): 4655 """ 4656 Private method to set a user style sheet. 4657 4658 @param styleSheetFile name of the user style sheet file (string) 4659 """ 4660 name = "_eric_userstylesheet" 4661 userStyle = "" 4662 4663 userStyle += ( 4664 WebBrowserTools.readAllFileContents(styleSheetFile) 4665 .replace("\n", "") 4666 ) 4667 4668 oldScript = self.webProfile().scripts().findScript(name) 4669 if not oldScript.isNull(): 4670 self.webProfile().scripts().remove(oldScript) 4671 4672 if userStyle: 4673 from .WebBrowserPage import WebBrowserPage 4674 4675 script = QWebEngineScript() 4676 script.setName(name) 4677 script.setInjectionPoint( 4678 QWebEngineScript.InjectionPoint.DocumentCreation) 4679 script.setWorldId(WebBrowserPage.SafeJsWorld) 4680 script.setRunsOnSubFrames(True) 4681 script.setSourceCode(Scripts.setStyleSheet(userStyle)) 4682 self.webProfile().scripts().insert(script) 4683 4684 ########################################## 4685 ## Support for desktop notifications below 4686 ########################################## 4687 4688 @classmethod 4689 def showNotification(cls, icon, heading, text, 4690 kind=NotificationTypes.INFORMATION, timeout=None): 4691 """ 4692 Class method to show a desktop notification. 4693 4694 @param icon icon to be shown in the notification 4695 @type QPixmap 4696 @param heading heading of the notification 4697 @type str 4698 @param text text of the notification 4699 @type str 4700 @param kind kind of notification to be shown 4701 @type NotificationTypes 4702 @param timeout time in seconds the notification should be shown 4703 (None = use configured timeout, 0 = indefinitely) 4704 @type int 4705 """ 4706 if cls._notification is None: 4707 from UI.NotificationWidget import NotificationWidget 4708 cls._notification = NotificationWidget() 4709 4710 if timeout is None: 4711 timeout = Preferences.getUI("NotificationTimeout") 4712 cls._notification.showNotification( 4713 icon, heading, text, kind=kind, timeout=timeout) 4714 4715 ###################################### 4716 ## Support for global status bar below 4717 ###################################### 4718 4719 @classmethod 4720 def globalStatusBar(cls): 4721 """ 4722 Class method to get a reference to a global status bar. 4723 4724 The global status bar is the status bar of the main window. If 4725 no such window exists and the web browser was called from the eric IDE, 4726 the status bar of the IDE is returned. 4727 4728 @return reference to the global status bar 4729 @rtype QStatusBar 4730 """ 4731 if cls.BrowserWindows: 4732 return cls.BrowserWindows[0].statusBar() 4733 else: 4734 return None 4735 4736 ################################### 4737 ## Support for download files below 4738 ################################### 4739 4740 @classmethod 4741 def downloadRequested(cls, download): 4742 """ 4743 Class method to handle a download request. 4744 4745 @param download reference to the download data 4746 @type QWebEngineDownloadItem 4747 """ 4748 cls.downloadManager().download(download) 4749 4750 ######################################## 4751 ## Support for web engine profiles below 4752 ######################################## 4753 4754 @classmethod 4755 def webProfile(cls, private=False): 4756 """ 4757 Class method handling the web engine profile. 4758 4759 @param private flag indicating the privacy mode 4760 @type bool 4761 @return reference to the web profile object 4762 @rtype QWebEngineProfile 4763 """ 4764 if cls._webProfile is None: 4765 if private: 4766 cls._webProfile = QWebEngineProfile() 4767 else: 4768 cls._webProfile = QWebEngineProfile.defaultProfile() 4769 cls._webProfile.downloadRequested.connect( 4770 cls.downloadRequested) 4771 4772 # add the default user agent string 4773 userAgent = cls._webProfile.httpUserAgent() 4774 cls._webProfile.defaultUserAgent = userAgent 4775 4776 if not private: 4777 if Preferences.getWebBrowser("DiskCacheEnabled"): 4778 cls._webProfile.setHttpCacheType( 4779 QWebEngineProfile.HttpCacheType.DiskHttpCache) 4780 cls._webProfile.setHttpCacheMaximumSize( 4781 Preferences.getWebBrowser("DiskCacheSize") * 4782 1024 * 1024) 4783 cls._webProfile.setCachePath(os.path.join( 4784 Utilities.getConfigDir(), "web_browser")) 4785 else: 4786 cls._webProfile.setHttpCacheType( 4787 QWebEngineProfile.HttpCacheType.MemoryHttpCache) 4788 cls._webProfile.setHttpCacheMaximumSize(0) 4789 cls._webProfile.setPersistentStoragePath(os.path.join( 4790 Utilities.getConfigDir(), "web_browser", 4791 "persistentstorage")) 4792 cls._webProfile.setPersistentCookiesPolicy( 4793 QWebEngineProfile.PersistentCookiesPolicy 4794 .AllowPersistentCookies) 4795 4796 with contextlib.suppress(AttributeError): 4797 cls._webProfile.setSpellCheckEnabled( 4798 Preferences.getWebBrowser("SpellCheckEnabled")) 4799 cls._webProfile.setSpellCheckLanguages( 4800 Preferences.getWebBrowser("SpellCheckLanguages")) 4801 4802 # Setup QWebChannel user scripts 4803 from .WebBrowserPage import WebBrowserPage 4804 4805 # WebChannel for SafeJsWorld 4806 script = QWebEngineScript() 4807 script.setName("_eric_webchannel") 4808 script.setInjectionPoint( 4809 QWebEngineScript.InjectionPoint.DocumentCreation) 4810 script.setWorldId(WebBrowserPage.SafeJsWorld) 4811 script.setRunsOnSubFrames(True) 4812 script.setSourceCode(Scripts.setupWebChannel(script.worldId())) 4813 cls._webProfile.scripts().insert(script) 4814 4815 # WebChannel for UnsafeJsWorld 4816 script2 = QWebEngineScript() 4817 script2.setName("_eric_webchannel2") 4818 script2.setInjectionPoint( 4819 QWebEngineScript.InjectionPoint.DocumentCreation) 4820 script2.setWorldId(WebBrowserPage.UnsafeJsWorld) 4821 script2.setRunsOnSubFrames(True) 4822 script2.setSourceCode(Scripts.setupWebChannel(script2.worldId())) 4823 cls._webProfile.scripts().insert(script2) 4824 4825 # document.window object addons 4826 script3 = QWebEngineScript() 4827 script3.setName("_eric_window_object") 4828 script3.setInjectionPoint( 4829 QWebEngineScript.InjectionPoint.DocumentCreation) 4830 script3.setWorldId(WebBrowserPage.UnsafeJsWorld) 4831 script3.setRunsOnSubFrames(True) 4832 script3.setSourceCode(Scripts.setupWindowObject()) 4833 cls._webProfile.scripts().insert(script3) 4834 4835 return cls._webProfile 4836 4837 @classmethod 4838 def webSettings(cls): 4839 """ 4840 Class method to get the web settings of the current profile. 4841 4842 @return web settings of the current profile 4843 @rtype QWebEngineSettings 4844 """ 4845 return cls.webProfile().settings() 4846 4847 #################################################### 4848 ## Methods below implement session related functions 4849 #################################################### 4850 4851 @classmethod 4852 def sessionManager(cls): 4853 """ 4854 Class method to get a reference to the session manager. 4855 4856 @return reference to the session manager 4857 @rtype SessionManager 4858 """ 4859 if cls._sessionManager is None and not cls._isPrivate: 4860 from .Session.SessionManager import SessionManager 4861 cls._sessionManager = SessionManager() 4862 4863 return cls._sessionManager 4864 4865 def __showSessionManagerDialog(self): 4866 """ 4867 Private slot to show the session manager dialog. 4868 """ 4869 self.sessionManager().showSessionManagerDialog() 4870 4871 ########################################################## 4872 ## Methods below implement safe browsing related functions 4873 ########################################################## 4874 4875 @classmethod 4876 def safeBrowsingManager(cls): 4877 """ 4878 Class method to get a reference to the safe browsing interface. 4879 4880 @return reference to the safe browsing manager 4881 @rtype SafeBrowsingManager 4882 """ 4883 if cls._safeBrowsingManager is None: 4884 from .SafeBrowsing.SafeBrowsingManager import SafeBrowsingManager 4885 cls._safeBrowsingManager = SafeBrowsingManager() 4886 4887 return cls._safeBrowsingManager 4888 4889 def __showSafeBrowsingDialog(self): 4890 """ 4891 Private slot to show the safe browsing management dialog. 4892 """ 4893 self.safeBrowsingManager().showSafeBrowsingDialog() 4894 4895 ############################################################# 4896 ## Methods below implement protocol handler related functions 4897 ############################################################# 4898 4899 @classmethod 4900 def protocolHandlerManager(cls): 4901 """ 4902 Class method to get a reference to the protocol handler manager. 4903 4904 @return reference to the protocol handler manager 4905 @rtype ProtocolHandlerManager 4906 """ 4907 if cls._protocolHandlerManager is None: 4908 from .Network.ProtocolHandlerManager import ProtocolHandlerManager 4909 cls._protocolHandlerManager = ProtocolHandlerManager() 4910 4911 return cls._protocolHandlerManager 4912 4913 def __showProtocolHandlerManagerDialog(self): 4914 """ 4915 Private slot to show the protocol handler manager dialog. 4916 """ 4917 self.protocolHandlerManager().showProtocolHandlerManagerDialog() 4918 4919 ############################################################### 4920 ## Methods below implement single application related functions 4921 ############################################################### 4922 4923 @pyqtSlot(str) 4924 def __saLoadUrl(self, urlStr): 4925 """ 4926 Private slot to load an URL received via the single application 4927 protocol. 4928 4929 @param urlStr URL to be loaded 4930 @type str 4931 """ 4932 url = QUrl.fromUserInput(urlStr) 4933 self.__linkActivated(url) 4934 4935 self.raise_() 4936 self.activateWindow() 4937 4938 @pyqtSlot(str) 4939 def __saNewTab(self, urlStr): 4940 """ 4941 Private slot to load an URL received via the single application 4942 protocol in a new tab. 4943 4944 @param urlStr URL to be loaded 4945 @type str 4946 """ 4947 url = QUrl.fromUserInput(urlStr) 4948 self.newTab(url) 4949 4950 self.raise_() 4951 self.activateWindow() 4952 4953 @pyqtSlot(str) 4954 def __saSearchWord(self, word): 4955 """ 4956 Private slot to search for the given word. 4957 4958 @param word word to be searched for 4959 @type str 4960 """ 4961 if WebBrowserWindow._useQtHelp: 4962 self.__searchWord = word 4963 self.__searchForWord() 4964 4965 self.raise_() 4966 self.activateWindow() 4967 4968 ###################################################### 4969 ## Methods below implement shortcuts related functions 4970 ###################################################### 4971 4972 def __configShortcuts(self): 4973 """ 4974 Private slot to configure the keyboard shortcuts. 4975 """ 4976 if self.__shortcutsDialog is None: 4977 from Preferences.ShortcutsDialog import ShortcutsDialog 4978 self.__shortcutsDialog = ShortcutsDialog(self) 4979 self.__shortcutsDialog.populate(helpViewer=self) 4980 self.__shortcutsDialog.show() 4981 4982 def __exportShortcuts(self): 4983 """ 4984 Private slot to export the keyboard shortcuts. 4985 """ 4986 fn, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( 4987 None, 4988 self.tr("Export Keyboard Shortcuts"), 4989 "", 4990 self.tr("Keyboard Shortcuts File (*.ekj);;" 4991 "XML Keyboard Shortcuts File (*.e4k)"), 4992 "", 4993 E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) 4994 4995 if not fn: 4996 return 4997 4998 ext = QFileInfo(fn).suffix() 4999 if not ext: 5000 ex = selectedFilter.split("(*")[1].split(")")[0] 5001 if ex: 5002 fn += ex 5003 5004 ok = ( 5005 E5MessageBox.yesNo( 5006 self, 5007 self.tr("Export Keyboard Shortcuts"), 5008 self.tr("""<p>The keyboard shortcuts file <b>{0}</b> exists""" 5009 """ already. Overwrite it?</p>""").format(fn)) 5010 if os.path.exists(fn) else 5011 True 5012 ) 5013 5014 if ok: 5015 from Preferences import Shortcuts 5016 Shortcuts.exportShortcuts(fn, helpViewer=self) 5017 5018 def __importShortcuts(self): 5019 """ 5020 Private slot to import the keyboard shortcuts. 5021 """ 5022 fn = E5FileDialog.getOpenFileName( 5023 None, 5024 self.tr("Import Keyboard Shortcuts"), 5025 "", 5026 self.tr("Keyboard Shortcuts File (*.ekj);;" 5027 "XML Keyboard shortcut file (*.e4k)")) 5028 5029 if fn: 5030 from Preferences import Shortcuts 5031 Shortcuts.importShortcuts(fn, helpViewer=self) 5032