--- a/src/eric7/WebBrowser/WebBrowserWebSearchWidget.py Wed Jul 13 11:16:20 2022 +0200 +++ b/src/eric7/WebBrowser/WebBrowserWebSearchWidget.py Wed Jul 13 14:55:47 2022 +0200 @@ -8,9 +8,7 @@ """ from PyQt6.QtCore import pyqtSignal, QUrl, QModelIndex, QTimer, Qt -from PyQt6.QtGui import ( - QStandardItem, QStandardItemModel, QFont, QIcon, QPixmap -) +from PyQt6.QtGui import QStandardItem, QStandardItemModel, QFont, QIcon, QPixmap from PyQt6.QtWidgets import QMenu, QCompleter from PyQt6.QtWebEngineCore import QWebEnginePage @@ -26,75 +24,74 @@ class WebBrowserWebSearchWidget(EricClearableLineEdit): """ Class implementing a web search widget for the web browser. - + @signal search(QUrl) emitted when the search should be done """ + search = pyqtSignal(QUrl) - + def __init__(self, mainWindow, parent=None): """ Constructor - + @param mainWindow reference to the browser main window @type WebBrowserWindow @param parent reference to the parent widget @type QWidget """ super().__init__(parent) - + from EricWidgets.EricLineEditButton import EricLineEditButton from .OpenSearch.OpenSearchManager import OpenSearchManager self.__mw = mainWindow - + self.__openSearchManager = OpenSearchManager(self) self.__openSearchManager.currentEngineChanged.connect( - self.__currentEngineChanged) + self.__currentEngineChanged + ) self.__currentEngine = "" - + self.__enginesMenu = QMenu(self) - self.__enginesMenu.triggered.connect( - self.__handleEnginesMenuActionTriggered) - + self.__enginesMenu.triggered.connect(self.__handleEnginesMenuActionTriggered) + self.__engineButton = EricLineEditButton(self) self.__engineButton.setMenu(self.__enginesMenu) self.addWidget(self.__engineButton, EricLineEditSide.LEFT) - + self.__searchButton = EricLineEditButton(self) self.__searchButton.setIcon(UI.PixmapCache.getIcon("webSearch")) self.addWidget(self.__searchButton, EricLineEditSide.LEFT) - + self.__model = QStandardItemModel(self) self.__completer = QCompleter() self.__completer.setModel(self.__model) self.__completer.setCompletionMode( - QCompleter.CompletionMode.UnfilteredPopupCompletion) + QCompleter.CompletionMode.UnfilteredPopupCompletion + ) self.__completer.setWidget(self) - + self.__searchButton.clicked.connect(self.__searchButtonClicked) self.textEdited.connect(self.__textEdited) self.returnPressed.connect(self.__searchNow) - self.__completer.activated[QModelIndex].connect( - self.__completerActivated) - self.__completer.highlighted[QModelIndex].connect( - self.__completerHighlighted) + self.__completer.activated[QModelIndex].connect(self.__completerActivated) + self.__completer.highlighted[QModelIndex].connect(self.__completerHighlighted) self.__enginesMenu.aboutToShow.connect(self.__showEnginesMenu) - + self.__suggestionsItem = None self.__suggestions = [] self.__suggestTimer = None - self.__suggestionsEnabled = Preferences.getWebBrowser( - "WebSearchSuggestions") - + self.__suggestionsEnabled = Preferences.getWebBrowser("WebSearchSuggestions") + self.__recentSearchesItem = None self.__recentSearches = [] self.__maxSavedSearches = 10 - + self.__engine = None self.__loadSearches() self.__setupCompleterMenu() self.__currentEngineChanged() - + def __searchNow(self): """ Private slot to perform the web search. @@ -102,117 +99,116 @@ searchText = self.text() if not searchText: return - + import WebBrowser.WebBrowserWindow + if WebBrowser.WebBrowserWindow.WebBrowserWindow.isPrivate(): return - + if searchText in self.__recentSearches: self.__recentSearches.remove(searchText) self.__recentSearches.insert(0, searchText) if len(self.__recentSearches) > self.__maxSavedSearches: - self.__recentSearches = self.__recentSearches[ - :self.__maxSavedSearches] + self.__recentSearches = self.__recentSearches[: self.__maxSavedSearches] self.__setupCompleterMenu() - + self.__mw.currentBrowser().setFocus() self.__mw.currentBrowser().load( - self.__openSearchManager.currentEngine().searchUrl(searchText)) - + self.__openSearchManager.currentEngine().searchUrl(searchText) + ) + def __setupCompleterMenu(self): """ Private method to create the completer menu. """ - if ( - not self.__suggestions or - (self.__model.rowCount() > 0 and - self.__model.item(0) != self.__suggestionsItem) + if not self.__suggestions or ( + self.__model.rowCount() > 0 + and self.__model.item(0) != self.__suggestionsItem ): self.__model.clear() self.__suggestionsItem = None else: self.__model.removeRows(1, self.__model.rowCount() - 1) - + boldFont = QFont() boldFont.setBold(True) - + if self.__suggestions: if self.__model.rowCount() == 0: if not self.__suggestionsItem: - self.__suggestionsItem = QStandardItem( - self.tr("Suggestions")) + self.__suggestionsItem = QStandardItem(self.tr("Suggestions")) self.__suggestionsItem.setFont(boldFont) self.__model.appendRow(self.__suggestionsItem) - + for suggestion in self.__suggestions: self.__model.appendRow(QStandardItem(suggestion)) - + if not self.__recentSearches: - self.__recentSearchesItem = QStandardItem( - self.tr("No Recent Searches")) + self.__recentSearchesItem = QStandardItem(self.tr("No Recent Searches")) self.__recentSearchesItem.setFont(boldFont) self.__model.appendRow(self.__recentSearchesItem) else: - self.__recentSearchesItem = QStandardItem( - self.tr("Recent Searches")) + self.__recentSearchesItem = QStandardItem(self.tr("Recent Searches")) self.__recentSearchesItem.setFont(boldFont) self.__model.appendRow(self.__recentSearchesItem) for recentSearch in self.__recentSearches: self.__model.appendRow(QStandardItem(recentSearch)) - + view = self.__completer.popup() - view.setFixedHeight(view.sizeHintForRow(0) * self.__model.rowCount() + - view.frameWidth() * 2) - + view.setFixedHeight( + view.sizeHintForRow(0) * self.__model.rowCount() + view.frameWidth() * 2 + ) + self.__searchButton.setEnabled( - bool(self.__recentSearches or self.__suggestions)) - + bool(self.__recentSearches or self.__suggestions) + ) + def __completerActivated(self, index): """ Private slot handling the selection of an entry from the completer. - + @param index index of the item (QModelIndex) """ if ( - self.__suggestionsItem and - self.__suggestionsItem.index().row() == index.row() + self.__suggestionsItem + and self.__suggestionsItem.index().row() == index.row() ): return - + if ( - self.__recentSearchesItem and - self.__recentSearchesItem.index().row() == index.row() + self.__recentSearchesItem + and self.__recentSearchesItem.index().row() == index.row() ): return - + self.__searchNow() - + def __completerHighlighted(self, index): """ Private slot handling the highlighting of an entry of the completer. - + @param index index of the item (QModelIndex) @return flah indicating a successful highlighting (boolean) """ if ( - self.__suggestionsItem and - self.__suggestionsItem.index().row() == index.row() + self.__suggestionsItem + and self.__suggestionsItem.index().row() == index.row() ): return False - + if ( - self.__recentSearchesItem and - self.__recentSearchesItem.index().row() == index.row() + self.__recentSearchesItem + and self.__recentSearchesItem.index().row() == index.row() ): return False - + self.setText(index.data()) return True - + def __textEdited(self, txt): """ Private slot to handle changes of the search text. - + @param txt search text (string) """ if self.__suggestionsEnabled: @@ -225,7 +221,7 @@ else: self.__completer.setCompletionPrefix(txt) self.__completer.complete() - + def __getSuggestions(self): """ Private slot to get search suggestions from the configured search @@ -233,47 +229,49 @@ """ searchText = self.text() if searchText: - self.__openSearchManager.currentEngine().requestSuggestions( - searchText) - + self.__openSearchManager.currentEngine().requestSuggestions(searchText) + def __newSuggestions(self, suggestions): """ Private slot to receive a new list of suggestions. - + @param suggestions list of suggestions (list of strings) """ self.__suggestions = suggestions self.__setupCompleterMenu() self.__completer.complete() - + def __showEnginesMenu(self): """ Private slot to handle the display of the engines menu. """ self.__enginesMenu.clear() - + from .OpenSearch.OpenSearchEngineAction import OpenSearchEngineAction + engineNames = self.__openSearchManager.allEnginesNames() for engineName in engineNames: engine = self.__openSearchManager.engine(engineName) action = OpenSearchEngineAction(engine, self.__enginesMenu) action.setData(engineName) self.__enginesMenu.addAction(action) - + if self.__openSearchManager.currentEngineName() == engineName: action.setCheckable(True) action.setChecked(True) - + cb = self.__mw.currentBrowser() from .Tools import Scripts + script = Scripts.getOpenSearchLinks() cb.page().runJavaScript( - script, WebBrowserPage.SafeJsWorld, self.__showEnginesMenuCallback) - + script, WebBrowserPage.SafeJsWorld, self.__showEnginesMenuCallback + ) + def __showEnginesMenuCallback(self, res): """ Private method handling the open search links callback. - + @param res result of the JavaScript @type list of dict """ @@ -287,24 +285,24 @@ continue if not title: title = cb.title() - + action = self.__enginesMenu.addAction( - self.tr("Add '{0}'").format(title)) + self.tr("Add '{0}'").format(title) + ) action.setData(url) action.setIcon(cb.icon()) - + self.__enginesMenu.addSeparator() self.__enginesMenu.addAction(self.__mw.searchEnginesAction()) - + if self.__recentSearches: - act = self.__enginesMenu.addAction( - self.tr("Clear Recent Searches")) + act = self.__enginesMenu.addAction(self.tr("Clear Recent Searches")) act.setData("@@CLEAR@@") - + def __handleEnginesMenuActionTriggered(self, action): """ Private slot to handle an action of the menu being triggered. - + @param action reference to the action that triggered @type QAction """ @@ -318,14 +316,14 @@ self.clear() else: self.__openSearchManager.setCurrentEngineName(actData) - + def __searchButtonClicked(self): """ Private slot to show the search menu via the search button. """ self.__setupCompleterMenu() self.__completer.complete() - + def clear(self): """ Public method to clear all private data. @@ -334,40 +332,40 @@ self.__setupCompleterMenu() super().clear() self.clearFocus() - + def preferencesChanged(self): """ Public method to handle the change of preferences. """ - self.__suggestionsEnabled = Preferences.getWebBrowser( - "WebSearchSuggestions") + self.__suggestionsEnabled = Preferences.getWebBrowser("WebSearchSuggestions") if not self.__suggestionsEnabled: self.__suggestions = [] self.__setupCompleterMenu() - + def saveSearches(self): """ Public method to save the recently performed web searches. """ Preferences.getSettings().setValue( - 'WebBrowser/WebSearches', self.__recentSearches) - + "WebBrowser/WebSearches", self.__recentSearches + ) + def __loadSearches(self): """ Private method to load the recently performed web searches. """ - searches = Preferences.getSettings().value('WebBrowser/WebSearches') + searches = Preferences.getSettings().value("WebBrowser/WebSearches") if searches is not None: self.__recentSearches = searches - + def openSearchManager(self): """ Public method to get a reference to the opensearch manager object. - + @return reference to the opensearch manager object (OpenSearchManager) """ return self.__openSearchManager - + def __currentEngineChanged(self): """ Private slot to track a change of the current search engine. @@ -377,39 +375,41 @@ oldEngine.imageChanged.disconnect(self.__engineImageChanged) if self.__suggestionsEnabled: oldEngine.suggestions.disconnect(self.__newSuggestions) - + newEngine = self.__openSearchManager.currentEngine() if newEngine.networkAccessManager() is None: newEngine.setNetworkAccessManager(self.__mw.networkManager()) newEngine.imageChanged.connect(self.__engineImageChanged) if self.__suggestionsEnabled: newEngine.suggestions.connect(self.__newSuggestions) - + self.setPlaceholderText(self.__openSearchManager.currentEngineName()) self.__currentEngine = self.__openSearchManager.currentEngineName() - self.__engineButton.setIcon(QIcon(QPixmap.fromImage( - self.__openSearchManager.currentEngine().image()))) + self.__engineButton.setIcon( + QIcon(QPixmap.fromImage(self.__openSearchManager.currentEngine().image())) + ) self.__suggestions = [] self.__setupCompleterMenu() - + def __engineImageChanged(self): """ Private slot to handle a change of the current search engine icon. """ - self.__engineButton.setIcon(QIcon(QPixmap.fromImage( - self.__openSearchManager.currentEngine().image()))) - + self.__engineButton.setIcon( + QIcon(QPixmap.fromImage(self.__openSearchManager.currentEngine().image())) + ) + def mousePressEvent(self, evt): """ Protected method called by a mouse press event. - + @param evt reference to the mouse event (QMouseEvent) """ if evt.button() == Qt.MouseButton.XButton1: - self.__mw.currentBrowser().triggerPageAction( - QWebEnginePage.WebAction.Back) + self.__mw.currentBrowser().triggerPageAction(QWebEnginePage.WebAction.Back) elif evt.button() == Qt.MouseButton.XButton2: self.__mw.currentBrowser().triggerPageAction( - QWebEnginePage.WebAction.Forward) + QWebEnginePage.WebAction.Forward + ) else: super().mousePressEvent(evt)