src/eric7/WebBrowser/WebBrowserWindow.py

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

eric ide

mercurial