--- a/src/eric7/WebBrowser/WebBrowserTabWidget.py Wed Jul 13 11:16:20 2022 +0200 +++ b/src/eric7/WebBrowser/WebBrowserTabWidget.py Wed Jul 13 14:55:47 2022 +0200 @@ -11,9 +11,7 @@ from PyQt6.QtCore import pyqtSignal, pyqtSlot, Qt, QUrl, QMarginsF from PyQt6.QtGui import QIcon, QPixmap, QPainter, QPageLayout -from PyQt6.QtWidgets import ( - QWidget, QHBoxLayout, QMenu, QToolButton, QDialog -) +from PyQt6.QtWidgets import QWidget, QHBoxLayout, QMenu, QToolButton, QDialog from PyQt6.QtPrintSupport import QPrinter, QPrintDialog, QAbstractPrintDialog from EricWidgets.EricTabWidget import EricTabWidget @@ -36,7 +34,7 @@ def isCupsAvailable(): """ Static method to test the availability of CUPS. - + @return flag indicating the availability of CUPS @rtype bool """ @@ -53,7 +51,7 @@ class WebBrowserTabWidget(EricTabWidget): """ Class implementing the central widget showing the web pages. - + @signal sourceChanged(WebBrowserView, QUrl) emitted after the URL of a browser has changed @signal currentUrlChanged(QUrl) emitted after the URL of the current @@ -67,6 +65,7 @@ @signal browserZoomValueChanged(int) emitted to signal a change of the current browser's zoom level """ + sourceChanged = pyqtSignal(WebBrowserView, QUrl) currentUrlChanged = pyqtSignal(QUrl) titleChanged = pyqtSignal(WebBrowserView, str) @@ -74,164 +73,187 @@ browserOpened = pyqtSignal(QWidget) browserClosed = pyqtSignal(QWidget) browserZoomValueChanged = pyqtSignal(int) - + def __init__(self, parent): """ Constructor - + @param parent reference to the parent widget (QWidget) """ super().__init__(parent, dnd=True) - + from .WebBrowserTabBar import WebBrowserTabBar + self.__tabBar = WebBrowserTabBar(self) self.setCustomTabBar(True, self.__tabBar) - + self.__mainWindow = parent - + self.setUsesScrollButtons(True) self.setDocumentMode(True) self.setElideMode(Qt.TextElideMode.ElideNone) - + from .ClosedTabsManager import ClosedTabsManager + self.__closedTabsManager = ClosedTabsManager(self) - self.__closedTabsManager.closedTabAvailable.connect( - self.__closedTabAvailable) - + self.__closedTabsManager.closedTabAvailable.connect(self.__closedTabAvailable) + from .UrlBar.StackedUrlBar import StackedUrlBar + self.__stackedUrlBar = StackedUrlBar(self) self.__tabBar.tabMoved.connect(self.__stackedUrlBar.moveBar) - + self.__tabContextMenuIndex = -1 self.currentChanged[int].connect(self.__currentChanged) self.setTabContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) self.customTabContextMenuRequested.connect(self.__showContextMenu) - + self.__rightCornerWidget = QWidget(self) self.__rightCornerWidgetLayout = QHBoxLayout(self.__rightCornerWidget) self.__rightCornerWidgetLayout.setContentsMargins(0, 0, 0, 0) self.__rightCornerWidgetLayout.setSpacing(0) - + self.__navigationMenu = QMenu(self) self.__navigationMenu.aboutToShow.connect(self.__showNavigationMenu) self.__navigationMenu.triggered.connect(self.__navigationMenuTriggered) - + self.__navigationButton = QToolButton(self) - self.__navigationButton.setIcon( - UI.PixmapCache.getIcon("1downarrow")) - self.__navigationButton.setToolTip( - self.tr("Show a navigation menu")) + self.__navigationButton.setIcon(UI.PixmapCache.getIcon("1downarrow")) + self.__navigationButton.setToolTip(self.tr("Show a navigation menu")) self.__navigationButton.setPopupMode( - QToolButton.ToolButtonPopupMode.InstantPopup) + QToolButton.ToolButtonPopupMode.InstantPopup + ) self.__navigationButton.setMenu(self.__navigationMenu) self.__navigationButton.setEnabled(False) self.__rightCornerWidgetLayout.addWidget(self.__navigationButton) - + self.__closedTabsMenu = QMenu(self) - self.__closedTabsMenu.aboutToShow.connect( - self.__aboutToShowClosedTabsMenu) - + self.__closedTabsMenu.aboutToShow.connect(self.__aboutToShowClosedTabsMenu) + self.__closedTabsButton = QToolButton(self) self.__closedTabsButton.setIcon(UI.PixmapCache.getIcon("trash")) self.__closedTabsButton.setToolTip( - self.tr("Show a navigation menu for closed tabs")) + self.tr("Show a navigation menu for closed tabs") + ) self.__closedTabsButton.setPopupMode( - QToolButton.ToolButtonPopupMode.InstantPopup) + QToolButton.ToolButtonPopupMode.InstantPopup + ) self.__closedTabsButton.setMenu(self.__closedTabsMenu) self.__closedTabsButton.setEnabled(False) self.__rightCornerWidgetLayout.addWidget(self.__closedTabsButton) - + self.setTabsClosable(True) self.tabCloseRequested.connect(self.closeBrowserAt) - - self.setCornerWidget( - self.__rightCornerWidget, Qt.Corner.TopRightCorner) - + + self.setCornerWidget(self.__rightCornerWidget, Qt.Corner.TopRightCorner) + self.__newTabButton = QToolButton(self) self.__newTabButton.setIcon(UI.PixmapCache.getIcon("plus")) - self.__newTabButton.setToolTip( - self.tr("Open a new web browser tab")) + self.__newTabButton.setToolTip(self.tr("Open a new web browser tab")) self.setCornerWidget(self.__newTabButton, Qt.Corner.TopLeftCorner) self.__newTabButton.clicked.connect(self.__newBrowser) - + self.__initTabContextMenu() - + self.__historyCompleter = None - + def __initTabContextMenu(self): """ Private method to create the tab context menu. """ self.__tabContextMenu = QMenu(self) self.tabContextNewAct = self.__tabContextMenu.addAction( - UI.PixmapCache.getIcon("tabNew"), - self.tr('New Tab'), self.newBrowser) + UI.PixmapCache.getIcon("tabNew"), self.tr("New Tab"), self.newBrowser + ) self.__tabContextMenu.addSeparator() self.leftMenuAct = self.__tabContextMenu.addAction( UI.PixmapCache.getIcon("1leftarrow"), - self.tr('Move Left'), self.__tabContextMenuMoveLeft) + self.tr("Move Left"), + self.__tabContextMenuMoveLeft, + ) self.rightMenuAct = self.__tabContextMenu.addAction( UI.PixmapCache.getIcon("1rightarrow"), - self.tr('Move Right'), self.__tabContextMenuMoveRight) + self.tr("Move Right"), + self.__tabContextMenuMoveRight, + ) self.__tabContextMenu.addSeparator() self.tabContextCloneAct = self.__tabContextMenu.addAction( - self.tr("Duplicate Page"), self.__tabContextMenuClone) + self.tr("Duplicate Page"), self.__tabContextMenuClone + ) self.__tabContextMenu.addSeparator() self.tabContextCloseAct = self.__tabContextMenu.addAction( UI.PixmapCache.getIcon("tabClose"), - self.tr('Close'), self.__tabContextMenuClose) + self.tr("Close"), + self.__tabContextMenuClose, + ) self.tabContextCloseOthersAct = self.__tabContextMenu.addAction( UI.PixmapCache.getIcon("tabCloseOther"), - self.tr("Close Others"), self.__tabContextMenuCloseOthers) - self.__tabContextMenu.addAction( - self.tr('Close All'), self.closeAllBrowsers) + self.tr("Close Others"), + self.__tabContextMenuCloseOthers, + ) + self.__tabContextMenu.addAction(self.tr("Close All"), self.closeAllBrowsers) self.__tabContextMenu.addSeparator() self.__tabContextMenu.addAction( UI.PixmapCache.getIcon("printPreview"), - self.tr('Print Preview'), self.__tabContextMenuPrintPreview) + self.tr("Print Preview"), + self.__tabContextMenuPrintPreview, + ) self.__tabContextMenu.addAction( UI.PixmapCache.getIcon("print"), - self.tr('Print'), self.__tabContextMenuPrint) + self.tr("Print"), + self.__tabContextMenuPrint, + ) self.__tabContextMenu.addAction( UI.PixmapCache.getIcon("printPdf"), - self.tr('Print as PDF'), self.__tabContextMenuPrintPdf) + self.tr("Print as PDF"), + self.__tabContextMenuPrintPdf, + ) self.__tabContextMenu.addSeparator() if hasattr(WebBrowserPage, "isAudioMuted"): self.__audioAct = self.__tabContextMenu.addAction( - "", self.__tabContextMenuAudioMute) + "", self.__tabContextMenuAudioMute + ) self.__tabContextMenu.addSeparator() else: self.__audioAct = None self.__tabContextMenu.addAction( UI.PixmapCache.getIcon("reload"), - self.tr('Reload All'), self.reloadAllBrowsers) + self.tr("Reload All"), + self.reloadAllBrowsers, + ) self.__tabContextMenu.addSeparator() self.__tabContextMenu.addAction( UI.PixmapCache.getIcon("addBookmark"), - self.tr('Bookmark All Tabs'), self.__mainWindow.bookmarkAll) - + self.tr("Bookmark All Tabs"), + self.__mainWindow.bookmarkAll, + ) + self.__tabBackContextMenu = QMenu(self) - self.__tabBackContextMenu.addAction( - self.tr('Close All'), self.closeAllBrowsers) + self.__tabBackContextMenu.addAction(self.tr("Close All"), self.closeAllBrowsers) self.__tabBackContextMenu.addAction( UI.PixmapCache.getIcon("reload"), - self.tr('Reload All'), self.reloadAllBrowsers) + self.tr("Reload All"), + self.reloadAllBrowsers, + ) self.__tabBackContextMenu.addAction( UI.PixmapCache.getIcon("addBookmark"), - self.tr('Bookmark All Tabs'), self.__mainWindow.bookmarkAll) + self.tr("Bookmark All Tabs"), + self.__mainWindow.bookmarkAll, + ) self.__tabBackContextMenu.addSeparator() self.__restoreClosedTabAct = self.__tabBackContextMenu.addAction( - UI.PixmapCache.getIcon("trash"), - self.tr('Restore Closed Tab')) + UI.PixmapCache.getIcon("trash"), self.tr("Restore Closed Tab") + ) self.__restoreClosedTabAct.setEnabled(False) self.__restoreClosedTabAct.setData(0) self.__restoreClosedTabAct.triggered.connect( - lambda: self.restoreClosedTab(self.__restoreClosedTabAct)) - + lambda: self.restoreClosedTab(self.__restoreClosedTabAct) + ) + def __showContextMenu(self, coord, index): """ Private slot to show the tab context menu. - + @param coord the position of the mouse pointer (QPoint) @param index index of the tab the menu is requested for (integer) """ @@ -242,38 +264,31 @@ self.__tabContextMenuIndex = index self.leftMenuAct.setEnabled(index > 0) self.rightMenuAct.setEnabled(index < self.count() - 1) - + self.tabContextCloseOthersAct.setEnabled(self.count() > 1) - + if self.__audioAct is not None: - if ( - self.widget(self.__tabContextMenuIndex).page() - .isAudioMuted() - ): + if self.widget(self.__tabContextMenuIndex).page().isAudioMuted(): self.__audioAct.setText(self.tr("Unmute Tab")) - self.__audioAct.setIcon( - UI.PixmapCache.getIcon("audioVolumeHigh")) + self.__audioAct.setIcon(UI.PixmapCache.getIcon("audioVolumeHigh")) else: self.__audioAct.setText(self.tr("Mute Tab")) - self.__audioAct.setIcon( - UI.PixmapCache.getIcon("audioVolumeMuted")) - + self.__audioAct.setIcon(UI.PixmapCache.getIcon("audioVolumeMuted")) + self.__tabContextMenu.popup(coord) - + def __tabContextMenuMoveLeft(self): """ Private method to move a tab one position to the left. """ - self.moveTab(self.__tabContextMenuIndex, - self.__tabContextMenuIndex - 1) - + self.moveTab(self.__tabContextMenuIndex, self.__tabContextMenuIndex - 1) + def __tabContextMenuMoveRight(self): """ Private method to move a tab one position to the right. """ - self.moveTab(self.__tabContextMenuIndex, - self.__tabContextMenuIndex + 1) - + self.moveTab(self.__tabContextMenuIndex, self.__tabContextMenuIndex + 1) + def __tabContextMenuClone(self): """ Private method to clone the selected tab. @@ -283,48 +298,47 @@ idx = self.currentIndex() if idx < 0 or idx > self.count(): return - + url = self.widget(idx).url() self.newBrowser(url) - + def __tabContextMenuClose(self): """ Private method to close the selected tab. """ self.closeBrowserAt(self.__tabContextMenuIndex) - + def __tabContextMenuCloseOthers(self): """ Private slot to close all other tabs. """ index = self.__tabContextMenuIndex - for i in ( - list(range(self.count() - 1, index, -1)) + - list(range(index - 1, -1, -1)) + for i in list(range(self.count() - 1, index, -1)) + list( + range(index - 1, -1, -1) ): self.closeBrowserAt(i) - + def __tabContextMenuPrint(self): """ Private method to print the selected tab. """ browser = self.widget(self.__tabContextMenuIndex) self.printBrowser(browser) - + def __tabContextMenuPrintPdf(self): """ Private method to print the selected tab as PDF. """ browser = self.widget(self.__tabContextMenuIndex) self.printBrowserPdf(browser) - + def __tabContextMenuPrintPreview(self): """ Private method to show a print preview of the selected tab. """ browser = self.widget(self.__tabContextMenuIndex) self.printPreviewBrowser(browser) - + def __tabContextMenuAudioMute(self): """ Private method to mute or unmute the selected tab. @@ -332,12 +346,12 @@ page = self.widget(self.__tabContextMenuIndex).page() muted = page.isAudioMuted() page.setAudioMuted(not muted) - + @pyqtSlot(bool) def __recentlyAudibleChanged(self, recentlyAudible, page): """ Private slot to react on the audible state of a page. - + @param recentlyAudible flag indicating the new audible state @type bool @param page reference to the web page @@ -346,12 +360,11 @@ browser = page.view() if browser is None: return - + index = self.indexOf(browser) icon = page.icon() - - if page.isAudioMuted() or ( - not page.isAudioMuted() and recentlyAudible): + + if page.isAudioMuted() or (not page.isAudioMuted() and recentlyAudible): pix = QPixmap(32, 32) pix.fill(Qt.GlobalColor.transparent) painter = QPainter(pix) @@ -365,19 +378,20 @@ self.setTabIcon(index, QIcon(pix)) else: self.setTabIcon(index, icon) - + @pyqtSlot() def __newBrowser(self): """ Private slot to open a new browser tab. """ self.newBrowser() - - def newBrowser(self, link=None, position=-1, background=False, - restoreSession=False): + + def newBrowser( + self, link=None, position=-1, background=False, restoreSession=False + ): """ Public method to create a new web browser tab. - + @param link link to be shown @type str or QUrl @param position position to create the new tab at or -1 to add it @@ -397,70 +411,68 @@ linkName = link.toString() else: linkName = link - + from .UrlBar.UrlBar import UrlBar + urlbar = UrlBar(self.__mainWindow, self) if self.__historyCompleter is None: import WebBrowser.WebBrowserWindow from .History.HistoryCompleter import ( - HistoryCompletionModel, HistoryCompleter + HistoryCompletionModel, + HistoryCompleter, ) + + histMgr = WebBrowser.WebBrowserWindow.WebBrowserWindow.historyManager() self.__historyCompletionModel = HistoryCompletionModel(self) - self.__historyCompletionModel.setSourceModel( - WebBrowser.WebBrowserWindow.WebBrowserWindow.historyManager() - .historyFilterModel()) + self.__historyCompletionModel.setSourceModel(histMgr.historyFilterModel()) self.__historyCompleter = HistoryCompleter( - self.__historyCompletionModel, self) + self.__historyCompletionModel, self + ) self.__historyCompleter.activated[str].connect(self.__pathSelected) urlbar.setCompleter(self.__historyCompleter) - urlbar.returnPressed.connect( - lambda: self.__lineEditReturnPressed(urlbar)) + urlbar.returnPressed.connect(lambda: self.__lineEditReturnPressed(urlbar)) if position == -1: self.__stackedUrlBar.addWidget(urlbar) else: self.__stackedUrlBar.insertWidget(position, urlbar) - + browser = WebBrowserView(self.__mainWindow, self) urlbar.setBrowser(browser) - - browser.sourceChanged.connect( - lambda url: self.__sourceChanged(url, browser)) - browser.titleChanged.connect( - lambda title: self.__titleChanged(title, browser)) + + browser.sourceChanged.connect(lambda url: self.__sourceChanged(url, browser)) + browser.titleChanged.connect(lambda title: self.__titleChanged(title, browser)) browser.highlighted.connect(self.showMessage) - browser.backwardAvailable.connect( - self.__mainWindow.setBackwardAvailable) + browser.backwardAvailable.connect(self.__mainWindow.setBackwardAvailable) browser.forwardAvailable.connect(self.__mainWindow.setForwardAvailable) browser.loadProgress.connect( - lambda progress: self.__loadProgress(progress, browser)) - browser.loadFinished.connect( - lambda ok: self.__loadFinished(ok, browser)) - browser.faviconChanged.connect( - lambda: self.__iconChanged(browser)) + lambda progress: self.__loadProgress(progress, browser) + ) + browser.loadFinished.connect(lambda ok: self.__loadFinished(ok, browser)) + browser.faviconChanged.connect(lambda: self.__iconChanged(browser)) browser.search.connect(self.newBrowser) browser.page().windowCloseRequested.connect( - lambda: self.__windowCloseRequested(browser.page())) + lambda: self.__windowCloseRequested(browser.page()) + ) browser.zoomValueChanged.connect(self.browserZoomValueChanged) if hasattr(WebBrowserPage, "recentlyAudibleChanged"): browser.page().recentlyAudibleChanged.connect( - lambda audible: self.__recentlyAudibleChanged( - audible, browser.page())) - browser.page().printRequested.connect( - lambda: self.printBrowser(browser)) + lambda audible: self.__recentlyAudibleChanged(audible, browser.page()) + ) + browser.page().printRequested.connect(lambda: self.printBrowser(browser)) browser.showMessage.connect(self.showMessage) - + index = ( self.addTab(browser, self.tr("...")) - if position == -1 else - self.insertTab(position, browser, self.tr("...")) + if position == -1 + else self.insertTab(position, browser, self.tr("...")) ) if not background: self.setCurrentIndex(index) - + self.__mainWindow.closeAct.setEnabled(True) self.__mainWindow.closeAllAct.setEnabled(True) self.__navigationButton.setEnabled(True) - + if not restoreSession and not linkName: if Preferences.getWebBrowser("NewTabBehavior") == 0: linkName = "about:blank" @@ -468,32 +480,31 @@ linkName = Preferences.getWebBrowser("HomePage") elif Preferences.getWebBrowser("NewTabBehavior") == 2: linkName = "eric:speeddial" - + if linkName == "eric:blank": linkName = "about:blank" - + if linkName: browser.setSource(QUrl(linkName)) if not browser.documentTitle(): self.setTabText( - index, - self.__elide(linkName, Qt.TextElideMode.ElideMiddle) + index, self.__elide(linkName, Qt.TextElideMode.ElideMiddle) ) self.setTabToolTip(index, linkName) else: self.setTabText( - index, - self.__elide(browser.documentTitle().replace("&", "&&"))) + index, self.__elide(browser.documentTitle().replace("&", "&&")) + ) self.setTabToolTip(index, browser.documentTitle()) - + self.browserOpened.emit(browser) - + return browser - + def newBrowserAfter(self, browser, link=None, background=False): """ Public method to create a new web browser tab after a given one. - + @param browser reference to the browser to add after (WebBrowserView) @param link link to be shown (string or QUrl) @param background flag indicating to open the tab in the @@ -503,7 +514,7 @@ """ position = self.indexOf(browser) + 1 if browser else -1 return self.newBrowser(link, position, background) - + def __showNavigationMenu(self): """ Private slot to show the navigation button menu. @@ -511,33 +522,34 @@ self.__navigationMenu.clear() for index in range(self.count()): act = self.__navigationMenu.addAction( - self.tabIcon(index), self.tabText(index)) + self.tabIcon(index), self.tabText(index) + ) act.setData(index) - + def __navigationMenuTriggered(self, act): """ Private slot called to handle the navigation button menu selection. - + @param act reference to the selected action (QAction) """ index = act.data() if index is not None: self.setCurrentIndex(index) - + def __windowCloseRequested(self, page): """ Private slot to handle the windowCloseRequested signal of a browser. - + @param page reference to the web page @type WebBrowserPage """ browser = page.view() if browser is None: return - + index = self.indexOf(browser) self.closeBrowserAt(index) - + def reloadAllBrowsers(self): """ Public slot to reload all browsers. @@ -545,38 +557,38 @@ for index in range(self.count()): browser = self.widget(index) browser and browser.reload() - + @pyqtSlot() def closeBrowser(self): """ Public slot called to handle the close action. """ self.closeBrowserAt(self.currentIndex()) - + def closeAllBrowsers(self, shutdown=False): """ Public slot called to handle the close all action. - + @param shutdown flag indicating a shutdown action @type bool """ for index in range(self.count() - 1, -1, -1): self.closeBrowserAt(index, shutdown=shutdown) - + def closeBrowserView(self, browser): """ Public method to close the given browser. - + @param browser reference to the web browser view to be closed @type WebBrowserView """ index = self.indexOf(browser) self.closeBrowserAt(index) - + def closeBrowserAt(self, index, shutdown=False): """ Public slot to close a browser based on its index. - + @param index index of browser to close @type int @param shutdown flag indicating a shutdown action @@ -585,64 +597,64 @@ browser = self.widget(index) if browser is None: return - + urlbar = self.__stackedUrlBar.widget(index) self.__stackedUrlBar.removeWidget(urlbar) urlbar.deleteLater() del urlbar - + self.__closedTabsManager.recordBrowser(browser, index) - + browser.closeWebInspector() WebInspector.unregisterView(browser) self.removeTab(index) self.browserClosed.emit(browser) browser.deleteLater() del browser - + if self.count() == 0 and not shutdown: self.newBrowser() else: self.currentChanged[int].emit(self.currentIndex()) - + def currentBrowser(self): """ Public method to get a reference to the current browser. - + @return reference to the current browser (WebBrowserView) """ return self.currentWidget() - + def browserAt(self, index): """ Public method to get a reference to the browser with the given index. - + @param index index of the browser to get (integer) @return reference to the indexed browser (WebBrowserView) """ return self.widget(index) - + def browsers(self): """ Public method to get a list of references to all browsers. - + @return list of references to browsers (list of WebBrowserView) """ li = [] for index in range(self.count()): li.append(self.widget(index)) return li - + @pyqtSlot() def printBrowser(self, browser=None): """ Public slot called to print the displayed page. - + @param browser reference to the browser to be printed (WebBrowserView) """ if browser is None: browser = self.currentBrowser() - + printer = QPrinter(mode=QPrinter.PrinterMode.HighResolution) if Preferences.getPrinter("ColorMode"): printer.setColorMode(QPrinter.ColorMode.Color) @@ -652,12 +664,14 @@ printer.setPageOrder(QPrinter.PageOrder.FirstPageFirst) else: printer.setPageOrder(QPrinter.PageOrder.LastPageFirst) - printer.setPageMargins(QMarginsF( - Preferences.getPrinter("LeftMargin") * 10, - Preferences.getPrinter("TopMargin") * 10, - Preferences.getPrinter("RightMargin") * 10, - Preferences.getPrinter("BottomMargin") * 10), - QPageLayout.Unit.Millimeter + printer.setPageMargins( + QMarginsF( + Preferences.getPrinter("LeftMargin") * 10, + Preferences.getPrinter("TopMargin") * 10, + Preferences.getPrinter("RightMargin") * 10, + Preferences.getPrinter("BottomMargin") * 10, + ), + QPageLayout.Unit.Millimeter, ) printerName = Preferences.getPrinter("PrinterName") if printerName: @@ -665,37 +679,38 @@ printer.setResolution(Preferences.getPrinter("Resolution")) documentName = WebBrowserTools.getFileNameFromUrl(browser.url()) printer.setDocName(documentName) - + printDialog = QPrintDialog(printer, self) printDialog.setOptions( - QAbstractPrintDialog.PrintDialogOption.PrintToFile | - QAbstractPrintDialog.PrintDialogOption.PrintShowPageSize + QAbstractPrintDialog.PrintDialogOption.PrintToFile + | QAbstractPrintDialog.PrintDialogOption.PrintShowPageSize ) if not Globals.isWindowsPlatform(): if isCupsAvailable(): printDialog.setOption( - QAbstractPrintDialog.PrintDialogOption.PrintCollateCopies) - printDialog.setOption( - QAbstractPrintDialog.PrintDialogOption.PrintPageRange) + QAbstractPrintDialog.PrintDialogOption.PrintCollateCopies + ) + printDialog.setOption(QAbstractPrintDialog.PrintDialogOption.PrintPageRange) if printDialog.exec() == QDialog.DialogCode.Accepted: browser.page().execPrintPage(printer, 10 * 1000) - + @pyqtSlot() def printBrowserPdf(self, browser=None): """ Public slot called to print the displayed page to PDF. - + @param browser reference to the browser to be printed (HelpBrowser) """ if browser is None: browser = self.currentBrowser() - + name = WebBrowserTools.getFileNameFromUrl(browser.url()) if name: - name = name.rsplit('.', 1)[0] - name += '.pdf' + name = name.rsplit(".", 1)[0] + name += ".pdf" if hasattr(browser.page(), "printToPdf"): from .Tools.PrintToPdfDialog import PrintToPdfDialog + if not name: name = "printout.pdf" dlg = PrintToPdfDialog(name, self) @@ -706,16 +721,20 @@ res = EricMessageBox.warning( self, self.tr("Print to PDF"), - self.tr("""<p>The file <b>{0}</b> exists""" - """ already. Shall it be""" - """ overwritten?</p>""").format(filePath), + self.tr( + """<p>The file <b>{0}</b> exists""" + """ already. Shall it be""" + """ overwritten?</p>""" + ).format(filePath), EricMessageBox.No | EricMessageBox.Yes, - EricMessageBox.No) + EricMessageBox.No, + ) if res == EricMessageBox.No: return browser.page().printToPdf( lambda pdf: self.__pdfGeneratedForSave(filePath, pdf), - pageLayout) + pageLayout, + ) elif Globals.isLinuxPlatform(): printer = QPrinter(mode=QPrinter.PrinterMode.HighResolution) if Preferences.getPrinter("ColorMode"): @@ -729,15 +748,15 @@ if name: printer.setOutputFileName(name) printer.setResolution(Preferences.getPrinter("Resolution")) - + printDialog = QPrintDialog(printer, self) if printDialog.exec() == QDialog.DialogCode.Accepted: browser.render(printer) - + def __pdfGeneratedForSave(self, filePath, pdfData): """ Private slot to save the generated PDF data to a file. - + @param filePath path to save the PDF to @type str @param pdfData generated PDF document @@ -745,7 +764,7 @@ """ if pdfData.size() == 0: return - + try: with open(filePath, "wb") as f: f.write(pdfData) @@ -753,23 +772,25 @@ EricMessageBox.critical( self, self.tr("Print to PDF"), - self.tr("""<p>The PDF could not be written to file <b>{0}""" - """</b>.</p><p><b>Error:</b> {1}</p>""").format( - filePath, str(err)), - EricMessageBox.Ok) - + self.tr( + """<p>The PDF could not be written to file <b>{0}""" + """</b>.</p><p><b>Error:</b> {1}</p>""" + ).format(filePath, str(err)), + EricMessageBox.Ok, + ) + @pyqtSlot() def printPreviewBrowser(self, browser=None): """ Public slot called to show a print preview of the displayed file. - + @param browser reference to the browser to be printed (WebBrowserView) """ from PyQt6.QtPrintSupport import QPrintPreviewDialog - + if browser is None: browser = self.currentBrowser() - + printer = QPrinter(mode=QPrinter.PrinterMode.HighResolution) if Preferences.getPrinter("ColorMode"): printer.setColorMode(QPrinter.ColorMode.Color) @@ -779,28 +800,31 @@ printer.setPageOrder(QPrinter.PageOrder.FirstPageFirst) else: printer.setPageOrder(QPrinter.PageOrder.LastPageFirst) - printer.setPageMargins(QMarginsF( - Preferences.getPrinter("LeftMargin") * 10, - Preferences.getPrinter("TopMargin") * 10, - Preferences.getPrinter("RightMargin") * 10, - Preferences.getPrinter("BottomMargin") * 10), - QPageLayout.Unit.Millimeter + printer.setPageMargins( + QMarginsF( + Preferences.getPrinter("LeftMargin") * 10, + Preferences.getPrinter("TopMargin") * 10, + Preferences.getPrinter("RightMargin") * 10, + Preferences.getPrinter("BottomMargin") * 10, + ), + QPageLayout.Unit.Millimeter, ) printerName = Preferences.getPrinter("PrinterName") if printerName: printer.setPrinterName(printerName) printer.setResolution(Preferences.getPrinter("Resolution")) - + preview = QPrintPreviewDialog(printer, self) preview.resize(800, 750) preview.paintRequested.connect( - lambda p: self.__printPreviewRequested(p, browser)) + lambda p: self.__printPreviewRequested(p, browser) + ) preview.exec() - + def __printPreviewRequested(self, printer, browser): """ Private slot to generate the print preview. - + @param printer reference to the printer object @type QPrinter @param browser reference to the browser to be printed @@ -808,25 +832,25 @@ """ with EricOverrideCursor(): browser.page().execPrintPage(printer, 10 * 1000) - + def __sourceChanged(self, url, browser): """ Private slot to handle a change of a browsers source. - + @param url URL of the new site @type QUrl @param browser reference to the web browser @type WebBrowserView """ self.sourceChanged.emit(browser, url) - + if browser == self.currentBrowser(): self.currentUrlChanged.emit(url) - + def __titleChanged(self, title, browser): """ Private slot to handle a change of a browsers title. - + @param title new title @type str @param browser reference to the web browser @@ -835,16 +859,16 @@ index = self.indexOf(browser) if title == "": title = browser.url().toString() - + self.setTabText(index, self.__elide(title.replace("&", "&&"))) self.setTabToolTip(index, title) - + self.titleChanged.emit(browser, title) - + def __elide(self, txt, mode=Qt.TextElideMode.ElideRight, length=40): """ Private method to elide some text. - + @param txt text to be elided (string) @param mode elide mode (Qt.TextElideMode) @param length amount of characters to be used (integer) @@ -855,27 +879,27 @@ elif mode == Qt.TextElideMode.ElideLeft: return "...{0}".format(txt[-length:]) elif mode == Qt.TextElideMode.ElideMiddle: - return "{0}...{1}".format(txt[:length // 2], txt[-(length // 2):]) + return "{0}...{1}".format(txt[: length // 2], txt[-(length // 2) :]) elif mode == Qt.TextElideMode.ElideRight: return "{0}...".format(txt[:length]) else: # just in case return txt - + def preferencesChanged(self): """ Public slot to handle a change of preferences. """ for browser in self.browsers(): browser.preferencesChanged() - + for urlbar in self.__stackedUrlBar.urlBars(): urlbar.preferencesChanged() - + def __loadFinished(self, ok, browser): """ Private method to handle the loadFinished signal. - + @param ok flag indicating the result @type bool @param browser reference to the web browser @@ -885,14 +909,14 @@ self.showMessage.emit(self.tr("Finished loading")) else: self.showMessage.emit(self.tr("Failed to load")) - + def __loadProgress(self, progress, browser): """ Private method to handle the loadProgress signal. - + Note: This works around wegengine not sending a loadFinished signal for navigation on the same page. - + @param progress load progress in percent @type int @param browser reference to the web browser @@ -909,67 +933,67 @@ self.setTabText(index, self.tr("Loading...")) self.setTabToolTip(index, self.tr("Loading...")) self.showMessage.emit(self.tr("Loading...")) - + self.__mainWindow.setLoadingActions(True) elif progress == 100: import WebBrowser.WebBrowserWindow + self.resetAnimation(index) self.setTabIcon( - index, WebBrowser.WebBrowserWindow.WebBrowserWindow.icon( - browser.url())) + index, WebBrowser.WebBrowserWindow.WebBrowserWindow.icon(browser.url()) + ) self.showMessage.emit(self.tr("Finished loading")) - + self.__mainWindow.setLoadingActions(False) - + def __iconChanged(self, browser): """ Private slot to handle a change of the web site icon. - + @param browser reference to the web browser @type WebBrowserView """ - self.setTabIcon( - self.indexOf(browser), - browser.icon()) + self.setTabIcon(self.indexOf(browser), browser.icon()) self.__mainWindow.bookmarksManager().faviconChanged(browser.url()) - + def getSourceFileList(self): """ Public method to get a list of all opened Qt help files. - + @return dictionary with tab id as key and host/namespace as value """ sourceList = {} for i in range(self.count()): browser = self.widget(i) - if ( - browser is not None and - browser.source().isValid() - ): + if browser is not None and browser.source().isValid(): sourceList[i] = browser.source().host() - + return sourceList - + def shallShutDown(self): """ Public method to check, if the application should be shut down. - + @return flag indicating a shut down (boolean) """ - if self.count() > 1 and Preferences.getWebBrowser( - "WarnOnMultipleClose"): + if self.count() > 1 and Preferences.getWebBrowser("WarnOnMultipleClose"): mb = EricMessageBox.EricMessageBox( EricMessageBox.Information, self.tr("Are you sure you want to close the window?"), - self.tr("""Are you sure you want to close the window?\n""" - """You have %n tab(s) open.""", "", self.count()), + self.tr( + """Are you sure you want to close the window?\n""" + """You have %n tab(s) open.""", + "", + self.count(), + ), modal=True, - parent=self) - quitButton = mb.addButton( - self.tr("&Quit"), EricMessageBox.AcceptRole) + parent=self, + ) + quitButton = mb.addButton(self.tr("&Quit"), EricMessageBox.AcceptRole) quitButton.setIcon(UI.PixmapCache.getIcon("exit")) closeTabButton = mb.addButton( - self.tr("C&lose Current Tab"), EricMessageBox.AcceptRole) + self.tr("C&lose Current Tab"), EricMessageBox.AcceptRole + ) closeTabButton.setIcon(UI.PixmapCache.getIcon("tabClose")) mb.addButton(EricMessageBox.Cancel) mb.exec() @@ -979,30 +1003,30 @@ if mb.clickedButton() == closeTabButton: self.closeBrowser() return False - + return True - + def stackedUrlBar(self): """ Public method to get a reference to the stacked url bar. - + @return reference to the stacked url bar (StackedUrlBar) """ return self.__stackedUrlBar - + def currentUrlBar(self): """ Public method to get a reference to the current url bar. - + @return reference to the current url bar (UrlBar) """ return self.__stackedUrlBar.currentWidget() - + def urlBarForView(self, view): """ Public method to get a reference to the UrlBar associated with the given view. - + @param view reference to the view to get the urlbar for @type WebBrowserView @return reference to the associated urlbar @@ -1011,13 +1035,13 @@ for urlbar in self.__stackedUrlBar.urlBars(): if urlbar.browser() is view: return urlbar - + return None - + def __lineEditReturnPressed(self, edit): """ Private slot to handle the entering of an URL. - + @param edit reference to the line edit @type UrlBar """ @@ -1027,20 +1051,20 @@ else: self.currentBrowser().setSource(url) self.currentBrowser().setFocus() - + def __pathSelected(self, path): """ Private slot called when a URL is selected from the completer. - + @param path path to be shown (string) """ url = self.__guessUrlFromPath(path) self.currentBrowser().setSource(url) - + def __guessUrlFromPath(self, path): """ Private method to guess an URL given a path string. - + @param path path string to guess an URL for (string) @return guessed URL (QUrl) """ @@ -1049,167 +1073,159 @@ url = manager.convertKeywordSearchToUrl(path) if url.isValid(): return url - + try: url = QUrl.fromUserInput(path) except AttributeError: url = QUrl(path) - - if ( - url.scheme() == "about" and - url.path() == "home" - ): + + if url.scheme() == "about" and url.path() == "home": url = QUrl("eric:home") - + if url.scheme() in ["s", "search"]: url = manager.currentEngine().searchUrl(url.path().strip()) - - if ( - url.scheme() != "" and - (url.host() != "" or url.path() != "") - ): + + if url.scheme() != "" and (url.host() != "" or url.path() != ""): return url - + urlString = Preferences.getWebBrowser("DefaultScheme") + path.strip() - url = QUrl.fromEncoded(urlString.encode("utf-8"), - QUrl.ParsingMode.TolerantMode) - + url = QUrl.fromEncoded(urlString.encode("utf-8"), QUrl.ParsingMode.TolerantMode) + return url - + def __currentChanged(self, index): """ Private slot to handle an index change. - + @param index new index (integer) """ self.__stackedUrlBar.setCurrentIndex(index) - + browser = self.browserAt(index) if browser is not None: if browser.url() == "" and browser.hasFocus(): self.__stackedUrlBar.currentWidget.setFocus() elif browser.url() != "": browser.setFocus() - + def restoreClosedTab(self, act): """ Public slot to restore the most recently closed tab. - + @param act reference to the action that triggered @type QAction """ if not self.canRestoreClosedTab(): return - + tab = self.__closedTabsManager.getClosedTabAt(act.data()) - + self.newBrowser(tab.url.toString(), position=tab.position) - + def canRestoreClosedTab(self): """ Public method to check, if closed tabs can be restored. - + @return flag indicating that closed tabs can be restored (boolean) """ return self.__closedTabsManager.isClosedTabAvailable() - + def restoreAllClosedTabs(self): """ Public slot to restore all closed tabs. """ if not self.canRestoreClosedTab(): return - + for tab in self.__closedTabsManager.allClosedTabs(): self.newBrowser(tab.url.toString(), position=tab.position) self.__closedTabsManager.clearList() - + def clearClosedTabsList(self): """ Public slot to clear the list of closed tabs. """ self.__closedTabsManager.clearList() - + def __aboutToShowClosedTabsMenu(self): """ Private slot to populate the closed tabs menu. """ fm = self.__closedTabsMenu.fontMetrics() try: - maxWidth = fm.horizontalAdvance('m') * 40 + maxWidth = fm.horizontalAdvance("m") * 40 except AttributeError: - maxWidth = fm.width('m') * 40 - + maxWidth = fm.width("m") * 40 + self.__closedTabsMenu.clear() for index, tab in enumerate(self.__closedTabsManager.allClosedTabs()): - title = fm.elidedText(tab.title, Qt.TextElideMode.ElideRight, - maxWidth) + title = fm.elidedText(tab.title, Qt.TextElideMode.ElideRight, maxWidth) act = self.__closedTabsMenu.addAction( - self.__mainWindow.icon(tab.url), title) + self.__mainWindow.icon(tab.url), title + ) act.setData(index) act.triggered.connect(lambda: self.restoreClosedTab(act)) self.__closedTabsMenu.addSeparator() self.__closedTabsMenu.addAction( - self.tr("Restore All Closed Tabs"), self.restoreAllClosedTabs) - self.__closedTabsMenu.addAction( - self.tr("Clear List"), self.clearClosedTabsList) - + self.tr("Restore All Closed Tabs"), self.restoreAllClosedTabs + ) + self.__closedTabsMenu.addAction(self.tr("Clear List"), self.clearClosedTabsList) + def closedTabsManager(self): """ Public slot to get a reference to the closed tabs manager. - + @return reference to the closed tabs manager (ClosedTabsManager) """ return self.__closedTabsManager - + def __closedTabAvailable(self, avail): """ Private slot to handle changes of the availability of closed tabs. - + @param avail flag indicating the availability of closed tabs (boolean) """ self.__closedTabsButton.setEnabled(avail) self.__restoreClosedTabAct.setEnabled(avail) - + #################################################### ## Methods below implement session related functions #################################################### - + def getSessionData(self): """ Public method to populate the session data. - + @return dictionary containing the session data @rtype dict """ sessionData = {} - + # 1. current index sessionData["CurrentTabIndex"] = self.currentIndex() - + # 2. tab data sessionData["Tabs"] = [] for index in range(self.count()): browser = self.widget(index) data = browser.getSessionData() sessionData["Tabs"].append(data) - + return sessionData - + def loadFromSessionData(self, sessionData): """ Public method to load the session data. - + @param sessionData dictionary containing the session data as generated by getSessionData() @type dict """ tabCount = self.count() - + # 1. load tab data if "Tabs" in sessionData: - loadTabOnActivate = Preferences.getWebBrowser( - "LoadTabOnActivation") + loadTabOnActivate = Preferences.getWebBrowser("LoadTabOnActivation") for data in sessionData["Tabs"]: browser = self.newBrowser(restoreSession=True) if loadTabOnActivate: @@ -1220,12 +1236,9 @@ self.setTabIcon(index, icon) else: browser.loadFromSessionData(data) - + # 2. set tab index - if ( - "CurrentTabIndex" in sessionData and - sessionData["CurrentTabIndex"] >= 0 - ): + if "CurrentTabIndex" in sessionData and sessionData["CurrentTabIndex"] >= 0: index = tabCount + sessionData["CurrentTabIndex"] self.setCurrentIndex(index) self.browserAt(index).activateSession()