diff -r a56c297bfd61 -r b8005dd4fc9b src/eric7/QScintilla/SearchReplaceWidget.py --- a/src/eric7/QScintilla/SearchReplaceWidget.py Mon Mar 27 22:05:05 2023 +0200 +++ b/src/eric7/QScintilla/SearchReplaceWidget.py Tue Mar 28 10:14:23 2023 +0200 @@ -13,6 +13,7 @@ from PyQt6.QtWidgets import ( QFrame, QHBoxLayout, + QLayout, QScrollArea, QSizePolicy, QToolButton, @@ -25,9 +26,10 @@ from eric7.EricWidgets import EricMessageBox from .Editor import Editor +from .Ui_SearchReplaceWidget import Ui_SearchReplaceWidget -class SearchReplaceWidget(QWidget): +class SearchReplaceWidget(QWidget, Ui_SearchReplaceWidget): """ Class implementing the search and replace widget. @@ -36,54 +38,37 @@ searchListChanged = pyqtSignal() - def __init__(self, replace, vm, parent=None, sliding=False): + def __init__(self, vm, parent=None, sliding=False): """ Constructor - @param replace flag indicating a replace widget is called @param vm reference to the viewmanager object - @param parent parent widget of this widget (QWidget) + @type ViewManager + @param parent parent widget of this widget (defaults to None) + @type QWidget (optional) @param sliding flag indicating the widget is embedded in the - sliding widget (boolean) + sliding widget (defaults to False) + @type bool (optional) """ super().__init__(parent) + self.setupUi(self) self.__viewmanager = vm self.__isMiniEditor = vm is parent - self.__replace = replace self.__sliding = sliding if sliding: self.__topWidget = parent - self.findHistory = vm.getSRHistory("search") - if replace: - from .Ui_ReplaceWidget import Ui_ReplaceWidget # __IGNORE_WARNING_I101__ - - self.replaceHistory = vm.getSRHistory("replace") - self.ui = Ui_ReplaceWidget() - whatsThis = self.tr( - """<b>Find and Replace</b> + self.__findHistory = vm.getSRHistory("search") + self.__replaceHistory = vm.getSRHistory("replace") + whatsThis = self.tr( + """<b>Find and Replace</b> <p>This dialog is used to find some text and replace it with another text. By checking the various checkboxes, the search can be made more specific. The search string might be a regular expression. In a regular expression, special characters interpreted are:</p> """ - ) - else: - from .Ui_SearchWidget import Ui_SearchWidget # __IGNORE_WARNING_I101__ - - self.ui = Ui_SearchWidget() - whatsThis = self.tr( - """<b>Find</b> -<p>This dialog is used to find some text. By checking the various checkboxes, -the search can be made more specific. The search string might be a regular -expression. In a regular expression, special characters interpreted are:</p> -""" - ) - self.ui.setupUi(self) - if not replace: - self.ui.wrapCheckBox.setChecked(True) - + ) whatsThis += self.tr( """<table border="0"> <tr><td><code>.</code></td><td>Matches any character</td></tr> @@ -134,36 +119,35 @@ self.setWhatsThis(whatsThis) # set icons - self.ui.closeButton.setIcon(EricPixmapCache.getIcon("close")) - self.ui.findPrevButton.setIcon(EricPixmapCache.getIcon("1leftarrow")) - self.ui.findNextButton.setIcon(EricPixmapCache.getIcon("1rightarrow")) - self.ui.extendButton.setIcon(EricPixmapCache.getIcon("2rightarrow")) + self.closeButton.setIcon(EricPixmapCache.getIcon("close")) + self.findPrevButton.setIcon(EricPixmapCache.getIcon("1leftarrow")) + self.findNextButton.setIcon(EricPixmapCache.getIcon("1rightarrow")) + self.extendButton.setIcon(EricPixmapCache.getIcon("2rightarrow")) - if replace: - self.ui.replaceButton.setIcon(EricPixmapCache.getIcon("editReplace")) - self.ui.replaceSearchButton.setIcon( - EricPixmapCache.getIcon("editReplaceSearch") - ) - self.ui.replaceAllButton.setIcon(EricPixmapCache.getIcon("editReplaceAll")) + self.replaceButton.setIcon(EricPixmapCache.getIcon("editReplace")) + self.replaceSearchButton.setIcon( + EricPixmapCache.getIcon("editReplaceSearch") + ) + self.replaceAllButton.setIcon(EricPixmapCache.getIcon("editReplaceAll")) # set line edit completers - self.ui.findtextCombo.setCompleter(None) - self.ui.findtextCombo.lineEdit().returnPressed.connect( + self.findtextCombo.setCompleter(None) + self.findtextCombo.lineEdit().returnPressed.connect( self.__findByReturnPressed ) - if replace: - self.ui.replacetextCombo.setCompleter(None) - self.ui.replacetextCombo.lineEdit().returnPressed.connect( - self.on_replaceButton_clicked - ) + self.replacetextCombo.setCompleter(None) + self.replacetextCombo.lineEdit().returnPressed.connect( + self.on_replaceButton_clicked + ) + + self.__currentEditor = None - self.ui.findtextCombo.lineEdit().textEdited.connect(self.__quickSearch) - self.ui.caseCheckBox.toggled.connect(self.__updateQuickSearchMarkers) - self.ui.wordCheckBox.toggled.connect(self.__updateQuickSearchMarkers) - self.ui.regexpCheckBox.toggled.connect(self.__updateQuickSearchMarkers) - self.ui.selectionCheckBox.toggled.connect(self.__updateQuickSearchMarkers) + self.findtextCombo.lineEdit().textEdited.connect(self.__quickSearch) + self.caseCheckBox.toggled.connect(self.__updateQuickSearchMarkers) + self.wordCheckBox.toggled.connect(self.__updateQuickSearchMarkers) + self.regexpCheckBox.toggled.connect(self.__updateQuickSearchMarkers) - self.__findtextComboStyleSheet = self.ui.findtextCombo.styleSheet() + self.__findtextComboStyleSheet = self.findtextCombo.styleSheet() # define actions self.findNextAct = EricAction( @@ -192,65 +176,62 @@ Qt.ShortcutContext.WidgetWithChildrenShortcut ) - if replace: - self.replaceAndSearchAct = EricAction( - self.tr("Replace and Search"), - self.tr("Replace and Search"), - 0, - 0, - self, - "replace_widget_replace_search", - ) - self.replaceAndSearchAct.triggered.connect( - self.on_replaceSearchButton_clicked - ) - self.replaceAndSearchAct.setEnabled(False) - self.replaceAndSearchAct.setShortcutContext( - Qt.ShortcutContext.WidgetWithChildrenShortcut - ) + self.replaceAndSearchAct = EricAction( + self.tr("Replace and Search"), + self.tr("Replace and Search"), + 0, + 0, + self, + "replace_widget_replace_search", + ) + self.replaceAndSearchAct.triggered.connect( + self.on_replaceSearchButton_clicked + ) + self.replaceAndSearchAct.setEnabled(False) + self.replaceAndSearchAct.setShortcutContext( + Qt.ShortcutContext.WidgetWithChildrenShortcut + ) - self.replaceSelectionAct = EricAction( - self.tr("Replace Occurrence"), - self.tr("Replace Occurrence"), - 0, - 0, - self, - "replace_widget_replace_occurrence", - ) - self.replaceSelectionAct.triggered.connect(self.on_replaceButton_clicked) - self.replaceSelectionAct.setEnabled(False) - self.replaceSelectionAct.setShortcutContext( - Qt.ShortcutContext.WidgetWithChildrenShortcut - ) + self.replaceSelectionAct = EricAction( + self.tr("Replace Occurrence"), + self.tr("Replace Occurrence"), + 0, + 0, + self, + "replace_widget_replace_occurrence", + ) + self.replaceSelectionAct.triggered.connect(self.on_replaceButton_clicked) + self.replaceSelectionAct.setEnabled(False) + self.replaceSelectionAct.setShortcutContext( + Qt.ShortcutContext.WidgetWithChildrenShortcut + ) - self.replaceAllAct = EricAction( - self.tr("Replace All"), - self.tr("Replace All"), - 0, - 0, - self, - "replace_widget_replace_all", - ) - self.replaceAllAct.triggered.connect(self.on_replaceAllButton_clicked) - self.replaceAllAct.setEnabled(False) - self.replaceAllAct.setShortcutContext( - Qt.ShortcutContext.WidgetWithChildrenShortcut - ) + self.replaceAllAct = EricAction( + self.tr("Replace All"), + self.tr("Replace All"), + 0, + 0, + self, + "replace_widget_replace_all", + ) + self.replaceAllAct.triggered.connect(self.on_replaceAllButton_clicked) + self.replaceAllAct.setEnabled(False) + self.replaceAllAct.setShortcutContext( + Qt.ShortcutContext.WidgetWithChildrenShortcut + ) self.addAction(self.findNextAct) self.addAction(self.findPrevAct) - if replace: - self.addAction(self.replaceAndSearchAct) - self.addAction(self.replaceSelectionAct) - self.addAction(self.replaceAllAct) + self.addAction(self.replaceAndSearchAct) + self.addAction(self.replaceSelectionAct) + self.addAction(self.replaceAllAct) # disable search and replace buttons and actions self.__setFindNextEnabled(False) self.__setFindPrevEnabled(False) - if replace: - self.__setReplaceAndSearchEnabled(False) - self.__setReplaceSelectionEnabled(False) - self.__setReplaceAllEnabled(False) + self.__setReplaceAndSearchEnabled(False) + self.__setReplaceSelectionEnabled(False) + self.__setReplaceAllEnabled(False) self.adjustSize() @@ -269,16 +250,15 @@ self.findNextAct.setShortcuts(self.__viewmanager.searchNextAct.shortcuts()) self.findPrevAct.setShortcuts(self.__viewmanager.searchPrevAct.shortcuts()) - if self.__replace: - self.replaceAndSearchAct.setShortcuts( - self.__viewmanager.replaceAndSearchAct.shortcuts() - ) - self.replaceSelectionAct.setShortcuts( - self.__viewmanager.replaceSelectionAct.shortcuts() - ) - self.replaceAllAct.setShortcuts( - self.__viewmanager.replaceAllAct.shortcuts() - ) + self.replaceAndSearchAct.setShortcuts( + self.__viewmanager.replaceAndSearchAct.shortcuts() + ) + self.replaceSelectionAct.setShortcuts( + self.__viewmanager.replaceSelectionAct.shortcuts() + ) + self.replaceAllAct.setShortcuts( + self.__viewmanager.replaceAllAct.shortcuts() + ) def __setFindNextEnabled(self, enable): """ @@ -287,7 +267,7 @@ @param enable flag indicating the enable state to be set @type bool """ - self.ui.findNextButton.setEnabled(enable) + self.findNextButton.setEnabled(enable) self.findNextAct.setEnabled(enable) def __setFindPrevEnabled(self, enable): @@ -297,7 +277,7 @@ @param enable flag indicating the enable state to be set @type bool """ - self.ui.findPrevButton.setEnabled(enable) + self.findPrevButton.setEnabled(enable) self.findPrevAct.setEnabled(enable) def __setReplaceAndSearchEnabled(self, enable): @@ -307,7 +287,7 @@ @param enable flag indicating the enable state to be set @type bool """ - self.ui.replaceSearchButton.setEnabled(enable) + self.replaceSearchButton.setEnabled(enable) self.replaceAndSearchAct.setEnabled(enable) def __setReplaceSelectionEnabled(self, enable): @@ -317,7 +297,7 @@ @param enable flag indicating the enable state to be set @type bool """ - self.ui.replaceButton.setEnabled(enable) + self.replaceButton.setEnabled(enable) self.replaceSelectionAct.setEnabled(enable) def __setReplaceAllEnabled(self, enable): @@ -327,14 +307,15 @@ @param enable flag indicating the enable state to be set @type bool """ - self.ui.replaceAllButton.setEnabled(enable) + self.replaceAllButton.setEnabled(enable) self.replaceAllAct.setEnabled(enable) def changeEvent(self, evt): """ Protected method handling state changes. - @param evt event containing the state change (QEvent) + @param evt event containing the state change + @type QEvent """ if evt.type() == QEvent.Type.FontChange: self.adjustSize() @@ -344,9 +325,10 @@ Private method to calculate the current selection boundary. @param selections optional parameter giving the selections to - calculate the boundary for (list of tuples of four integer) + calculate the boundary for (defaults to None) + @type list of tuples of four int @return tuple of start line and index and end line and index - (tuple of four integer) + @rtype tuple (int, int, int, int) """ if selections is None: selections = self.__selections @@ -380,11 +362,10 @@ self.__setFindNextEnabled(enable) self.__setFindPrevEnabled(enable) - self.ui.extendButton.setEnabled(enable) - if self.__replace: - self.__setReplaceSelectionEnabled(False) - self.__setReplaceAndSearchEnabled(False) - self.__setReplaceAllEnabled(enable) + self.extendButton.setEnabled(enable) + self.__setReplaceSelectionEnabled(False) + self.__setReplaceAndSearchEnabled(False) + self.__setReplaceAllEnabled(enable) @pyqtSlot(str) def __quickSearch(self, txt): @@ -400,26 +381,27 @@ if Preferences.getEditor("QuickSearchMarkersEnabled"): self.__quickSearchMarkOccurrences(txt) - if self.ui.selectionCheckBox.isChecked(): + if self.selectionCheckBox.isChecked(): lineFrom, indexFrom, lineTo, indexTo = self.__selectionBoundary() + aw.highlightSearchSelection(lineFrom, indexFrom, lineTo, indexTo) else: lineFrom, indexFrom, lineTo, indexTo = 0, 0, -1, -1 posixMode = ( Preferences.getEditor("SearchRegexpMode") == 0 - and self.ui.regexpCheckBox.isChecked() + and self.regexpCheckBox.isChecked() ) cxx11Mode = ( Preferences.getEditor("SearchRegexpMode") == 1 - and self.ui.regexpCheckBox.isChecked() + and self.regexpCheckBox.isChecked() ) self.__finding = True ok = aw.findFirst( txt, - self.ui.regexpCheckBox.isChecked(), - self.ui.caseCheckBox.isChecked(), - self.ui.wordCheckBox.isChecked(), - self.ui.wrapCheckBox.isChecked(), + self.regexpCheckBox.isChecked(), + self.caseCheckBox.isChecked(), + self.wordCheckBox.isChecked(), + self.wrapCheckBox.isChecked(), not self.__findBackwards, lineFrom, indexFrom, @@ -446,11 +428,12 @@ """ Private method to mark all occurrences of the search text. - @param txt text to search for (string) + @param txt text to search for + @type str """ aw = self.__viewmanager.activeWindow() - if self.ui.selectionCheckBox.isChecked(): + if self.selectionCheckBox.isChecked(): lineFrom, indexFrom, lineTo, indexTo = self.__selectionBoundary() else: lineFrom, indexFrom, lineTo, indexTo = 0, 0, -1, -1 @@ -458,17 +441,17 @@ aw.clearSearchIndicators() posixMode = ( Preferences.getEditor("SearchRegexpMode") == 0 - and self.ui.regexpCheckBox.isChecked() + and self.regexpCheckBox.isChecked() ) cxx11Mode = ( Preferences.getEditor("SearchRegexpMode") == 1 - and self.ui.regexpCheckBox.isChecked() + and self.regexpCheckBox.isChecked() ) ok = aw.findFirstTarget( txt, - self.ui.regexpCheckBox.isChecked(), - self.ui.caseCheckBox.isChecked(), - self.ui.wordCheckBox.isChecked(), + self.regexpCheckBox.isChecked(), + self.caseCheckBox.isChecked(), + self.wordCheckBox.isChecked(), lineFrom, indexFrom, lineTo, @@ -502,29 +485,29 @@ @type bool """ if not ok: - self.ui.findtextCombo.setStyleSheet( + self.findtextCombo.setStyleSheet( "color: #000000; background-color: #ff6666;" ) else: - self.ui.findtextCombo.setStyleSheet(self.__findtextComboStyleSheet) + self.findtextCombo.setStyleSheet(self.__findtextComboStyleSheet) @pyqtSlot() def on_extendButton_clicked(self): """ - Private slot to handle the quicksearch extend action. + Private slot to handle the quick search extend action. """ aw = self.__viewmanager.activeWindow() if aw is None: return - txt = self.ui.findtextCombo.currentText() + txt = self.findtextCombo.currentText() if not txt: return line, index = aw.getCursorPosition() word = aw.getWord(line, index) - self.ui.findtextCombo.setEditText(word) - self.ui.findtextCombo.lineEdit().selectAll() + self.findtextCombo.setEditText(word) + self.findtextCombo.lineEdit().selectAll() self.__quickSearch(word) @pyqtSlot(bool) @@ -535,7 +518,7 @@ @param on status of the check box (ignored) @type bool """ - txt = self.ui.findtextCombo.currentText() + txt = self.findtextCombo.currentText() self.__quickSearch(txt) @pyqtSlot() @@ -545,35 +528,32 @@ """ self.findNext() + @pyqtSlot() def findNext(self): """ Public slot to find the next occurrence of text. """ - if not self.havefound or not self.ui.findtextCombo.currentText(): - if self.__replace: - self.__viewmanager.showReplaceWidget() - else: - self.__viewmanager.showSearchWidget() + if not self.havefound or not self.findtextCombo.currentText(): + self.__viewmanager.showSearchWidget() return self.__findBackwards = False - txt = self.ui.findtextCombo.currentText() + txt = self.findtextCombo.currentText() # This moves any previous occurrence of this statement to the head # of the list and updates the combobox - if txt in self.findHistory: - self.findHistory.remove(txt) - self.findHistory.insert(0, txt) - self.ui.findtextCombo.clear() - self.ui.findtextCombo.addItems(self.findHistory) + if txt in self.__findHistory: + self.__findHistory.remove(txt) + self.__findHistory.insert(0, txt) + self.findtextCombo.clear() + self.findtextCombo.addItems(self.__findHistory) self.searchListChanged.emit() ok = self.__findNextPrev(txt, False) self.__setSearchEditColors(ok) if ok: - if self.__replace: - self.__setReplaceSelectionEnabled(True) - self.__setReplaceAndSearchEnabled(True) + self.__setReplaceSelectionEnabled(True) + self.__setReplaceAndSearchEnabled(True) else: EricMessageBox.information( self, self.windowTitle(), self.tr("'{0}' was not found.").format(txt) @@ -586,37 +566,38 @@ """ self.findPrev() + @pyqtSlot() def findPrev(self): """ Public slot to find the next previous of text. """ - if not self.havefound or not self.ui.findtextCombo.currentText(): + if not self.havefound or not self.findtextCombo.currentText(): self.show(self.__viewmanager.textForFind()) return self.__findBackwards = True - txt = self.ui.findtextCombo.currentText() + txt = self.findtextCombo.currentText() # This moves any previous occurrence of this statement to the head # of the list and updates the combobox - if txt in self.findHistory: - self.findHistory.remove(txt) - self.findHistory.insert(0, txt) - self.ui.findtextCombo.clear() - self.ui.findtextCombo.addItems(self.findHistory) + if txt in self.__findHistory: + self.__findHistory.remove(txt) + self.__findHistory.insert(0, txt) + self.findtextCombo.clear() + self.findtextCombo.addItems(self.__findHistory) self.searchListChanged.emit() ok = self.__findNextPrev(txt, True) self.__setSearchEditColors(ok) if ok: - if self.__replace: - self.__setReplaceSelectionEnabled(True) - self.__setReplaceAndSearchEnabled(True) + self.__setReplaceSelectionEnabled(True) + self.__setReplaceAndSearchEnabled(True) else: EricMessageBox.information( self, self.windowTitle(), self.tr("'{0}' was not found.").format(txt) ) + @pyqtSlot() def __findByReturnPressed(self): """ Private slot to handle the returnPressed signal of the findtext @@ -631,28 +612,29 @@ """ Private method to mark all occurrences of the search text. - @param txt text to search for (string) + @param txt text to search for + @type str """ aw = self.__viewmanager.activeWindow() - if self.ui.selectionCheckBox.isChecked(): + if self.selectionCheckBox.isChecked(): lineFrom, indexFrom, lineTo, indexTo = self.__selectionBoundary() else: lineFrom, indexFrom, lineTo, indexTo = 0, 0, -1, -1 posixMode = ( Preferences.getEditor("SearchRegexpMode") == 0 - and self.ui.regexpCheckBox.isChecked() + and self.regexpCheckBox.isChecked() ) cxx11Mode = ( Preferences.getEditor("SearchRegexpMode") == 1 - and self.ui.regexpCheckBox.isChecked() + and self.regexpCheckBox.isChecked() ) aw.clearSearchIndicators() ok = aw.findFirstTarget( txt, - self.ui.regexpCheckBox.isChecked(), - self.ui.caseCheckBox.isChecked(), - self.ui.wordCheckBox.isChecked(), + self.regexpCheckBox.isChecked(), + self.caseCheckBox.isChecked(), + self.wordCheckBox.isChecked(), lineFrom, indexFrom, lineTo, @@ -686,9 +668,12 @@ """ Private method to find the next occurrence of the search text. - @param txt text to search for (string) - @param backwards flag indicating a backwards search (boolean) - @return flag indicating success (boolean) + @param txt text to search for + @type str + @param backwards flag indicating a backwards search + @type bool + @return flag indicating success + @rtype bool """ self.__finding = True @@ -702,9 +687,11 @@ ok = True lineFrom, indexFrom, lineTo, indexTo = aw.getSelection() boundary = self.__selectionBoundary() + if self.selectionCheckBox.isChecked(): + aw.highlightSearchSelection(*boundary) if backwards: if ( - self.ui.selectionCheckBox.isChecked() + self.selectionCheckBox.isChecked() and (lineFrom, indexFrom, lineTo, indexTo) == boundary ): # initial call @@ -718,7 +705,7 @@ line = lineFrom index = indexFrom if ( - self.ui.selectionCheckBox.isChecked() + self.selectionCheckBox.isChecked() and line == boundary[0] and index >= 0 and index < boundary[1] @@ -727,9 +714,9 @@ if ok and index < 0: line -= 1 - if self.ui.selectionCheckBox.isChecked(): + if self.selectionCheckBox.isChecked(): if line < boundary[0]: - if self.ui.wrapCheckBox.isChecked(): + if self.wrapCheckBox.isChecked(): line, index = boundary[2:] else: ok = False @@ -737,7 +724,7 @@ index = aw.lineLength(line) else: if line < 0: - if self.ui.wrapCheckBox.isChecked(): + if self.wrapCheckBox.isChecked(): line = aw.lines() - 1 index = aw.lineLength(line) else: @@ -746,7 +733,7 @@ index = aw.lineLength(line) else: if ( - self.ui.selectionCheckBox.isChecked() + self.selectionCheckBox.isChecked() and (lineFrom, indexFrom, lineTo, indexTo) == boundary ): # initial call @@ -758,18 +745,18 @@ if ok: posixMode = ( Preferences.getEditor("SearchRegexpMode") == 0 - and self.ui.regexpCheckBox.isChecked() + and self.regexpCheckBox.isChecked() ) cxx11Mode = ( Preferences.getEditor("SearchRegexpMode") == 1 - and self.ui.regexpCheckBox.isChecked() + and self.regexpCheckBox.isChecked() ) ok = aw.findFirst( txt, - self.ui.regexpCheckBox.isChecked(), - self.ui.caseCheckBox.isChecked(), - self.ui.wordCheckBox.isChecked(), - self.ui.wrapCheckBox.isChecked(), + self.regexpCheckBox.isChecked(), + self.caseCheckBox.isChecked(), + self.wordCheckBox.isChecked(), + self.wrapCheckBox.isChecked(), not backwards, line, index, @@ -777,7 +764,7 @@ cxx11=cxx11Mode, ) - if ok and self.ui.selectionCheckBox.isChecked(): + if ok and self.selectionCheckBox.isChecked(): lineFrom, indexFrom, lineTo, indexTo = aw.getSelection() if len(self.__selections) > 1: for sel in self.__selections: @@ -820,10 +807,10 @@ break ok = aw.findFirst( txt, - self.ui.regexpCheckBox.isChecked(), - self.ui.caseCheckBox.isChecked(), - self.ui.wordCheckBox.isChecked(), - self.ui.wrapCheckBox.isChecked(), + self.regexpCheckBox.isChecked(), + self.caseCheckBox.isChecked(), + self.wordCheckBox.isChecked(), + self.wrapCheckBox.isChecked(), not backwards, line, index, @@ -843,7 +830,7 @@ ok = False break if not ok: - if self.ui.wrapCheckBox.isChecked(): + if self.wrapCheckBox.isChecked(): # try it again if backwards: line, index = boundary[2:] @@ -851,10 +838,10 @@ line, index = boundary[:2] ok = aw.findFirst( txt, - self.ui.regexpCheckBox.isChecked(), - self.ui.caseCheckBox.isChecked(), - self.ui.wordCheckBox.isChecked(), - self.ui.wrapCheckBox.isChecked(), + self.regexpCheckBox.isChecked(), + self.caseCheckBox.isChecked(), + self.wordCheckBox.isChecked(), + self.wrapCheckBox.isChecked(), not backwards, line, index, @@ -902,22 +889,31 @@ """ Private method to display this widget in find mode. - @param text text to be shown in the findtext edit (string) + @param text text to be shown in the findtext edit (defaults to "") + @type str (optional) """ - self.__replace = False + # hide the replace related widgets + for widget in ( + self.replaceLabel, + self.replacetextCombo, + self.replaceButton, + self.replaceSearchButton, + self.replaceAllButton + ): + widget.setVisible(False) self.__setSearchEditColors(True) - self.ui.findtextCombo.clear() - self.ui.findtextCombo.addItems(self.findHistory) - self.ui.findtextCombo.setEditText(text) - self.ui.findtextCombo.lineEdit().selectAll() - self.ui.findtextCombo.setFocus() + self.findtextCombo.clear() + self.findtextCombo.addItems(self.__findHistory) + self.findtextCombo.setEditText(text) + self.findtextCombo.lineEdit().selectAll() + self.findtextCombo.setFocus() self.on_findtextCombo_editTextChanged(text) - self.ui.caseCheckBox.setChecked(False) - self.ui.wordCheckBox.setChecked(False) - self.ui.wrapCheckBox.setChecked(True) - self.ui.regexpCheckBox.setChecked(False) + self.caseCheckBox.setChecked(False) + self.wordCheckBox.setChecked(False) + self.wrapCheckBox.setChecked(True) + self.regexpCheckBox.setChecked(False) aw = self.__viewmanager.activeWindow() self.updateSelectionCheckBox(aw) @@ -944,32 +940,42 @@ @param editor reference to the editor @type Editor """ - if not self.__finding and isinstance(editor, Editor): + from .MiniEditor import MiniScintilla + + if not self.__finding and isinstance(editor, (Editor, MiniScintilla)): + if ( + self.__currentEditor is not None + and self.__currentEditor is not editor + ): + self.__currentEditor.clearSearchSelectionHighlight() + self.__currentEditor = editor + if editor.hasSelectedText(): selections = editor.getSelections() line1, index1, line2, index2 = self.__selectionBoundary(selections) if line1 != line2: - self.ui.selectionCheckBox.setEnabled(True) - self.ui.selectionCheckBox.setChecked(True) + self.selectionCheckBox.setEnabled(True) + self.selectionCheckBox.setChecked(True) self.__selections = selections + self.__currentEditor.clearSearchSelectionHighlight() return - self.ui.selectionCheckBox.setEnabled(False) - self.ui.selectionCheckBox.setChecked(False) + self.selectionCheckBox.setEnabled(False) + self.selectionCheckBox.setChecked(False) self.__selections = [] def replace(self): """ Public method to replace the current selection. """ - if self.ui.replaceButton.isEnabled(): + if self.replaceButton.isEnabled(): self.__doReplace(False) def replaceSearch(self): """ Public method to replace the current selection and search again. """ - if self.ui.replaceSearchButton.isEnabled(): + if self.replaceSearchButton.isEnabled(): self.__doReplace(True) @pyqtSlot() @@ -998,21 +1004,21 @@ # Check enabled status due to dual purpose usage of this method if ( - not self.ui.replaceButton.isEnabled() - and not self.ui.replaceSearchButton.isEnabled() + not self.replaceButton.isEnabled() + and not self.replaceSearchButton.isEnabled() ): return - ftxt = self.ui.findtextCombo.currentText() - rtxt = self.ui.replacetextCombo.currentText() + ftxt = self.findtextCombo.currentText() + rtxt = self.replacetextCombo.currentText() # This moves any previous occurrence of this statement to the head # of the list and updates the combobox - if rtxt in self.replaceHistory: - self.replaceHistory.remove(rtxt) - self.replaceHistory.insert(0, rtxt) - self.ui.replacetextCombo.clear() - self.ui.replacetextCombo.addItems(self.replaceHistory) + if rtxt in self.__replaceHistory: + self.__replaceHistory.remove(rtxt) + self.__replaceHistory.insert(0, rtxt) + self.replacetextCombo.clear() + self.replacetextCombo.addItems(self.__replaceHistory) aw = self.__viewmanager.activeWindow() aw.hideFindIndicator() @@ -1041,7 +1047,7 @@ """ Public method to replace all occurrences. """ - if self.ui.replaceAllButton.isEnabled(): + if self.replaceAllButton.isEnabled(): self.on_replaceAllButton_clicked() @pyqtSlot() @@ -1052,45 +1058,46 @@ self.__finding = True replacements = 0 - ftxt = self.ui.findtextCombo.currentText() - rtxt = self.ui.replacetextCombo.currentText() + ftxt = self.findtextCombo.currentText() + rtxt = self.replacetextCombo.currentText() # This moves any previous occurrence of this statement to the head # of the list and updates the combobox - if ftxt in self.findHistory: - self.findHistory.remove(ftxt) - self.findHistory.insert(0, ftxt) - self.ui.findtextCombo.clear() - self.ui.findtextCombo.addItems(self.findHistory) + if ftxt in self.__findHistory: + self.__findHistory.remove(ftxt) + self.__findHistory.insert(0, ftxt) + self.findtextCombo.clear() + self.findtextCombo.addItems(self.__findHistory) - if rtxt in self.replaceHistory: - self.replaceHistory.remove(rtxt) - self.replaceHistory.insert(0, rtxt) - self.ui.replacetextCombo.clear() - self.ui.replacetextCombo.addItems(self.replaceHistory) + if rtxt in self.__replaceHistory: + self.__replaceHistory.remove(rtxt) + self.__replaceHistory.insert(0, rtxt) + self.replacetextCombo.clear() + self.replacetextCombo.addItems(self.__replaceHistory) aw = self.__viewmanager.activeWindow() aw.hideFindIndicator() cline, cindex = aw.getCursorPosition() boundary = self.__selectionBoundary() - if self.ui.selectionCheckBox.isChecked(): + if self.selectionCheckBox.isChecked(): line, index = boundary[:2] + aw.highlightSearchSelection(*boundary) else: line = 0 index = 0 posixMode = ( Preferences.getEditor("SearchRegexpMode") == 0 - and self.ui.regexpCheckBox.isChecked() + and self.regexpCheckBox.isChecked() ) cxx11Mode = ( Preferences.getEditor("SearchRegexpMode") == 1 - and self.ui.regexpCheckBox.isChecked() + and self.regexpCheckBox.isChecked() ) ok = aw.findFirst( ftxt, - self.ui.regexpCheckBox.isChecked(), - self.ui.caseCheckBox.isChecked(), - self.ui.wordCheckBox.isChecked(), + self.regexpCheckBox.isChecked(), + self.caseCheckBox.isChecked(), + self.wordCheckBox.isChecked(), False, True, line, @@ -1099,7 +1106,7 @@ cxx11=cxx11Mode, ) - if ok and self.ui.selectionCheckBox.isChecked(): + if ok and self.selectionCheckBox.isChecked(): lineFrom, indexFrom, lineTo, indexTo = aw.getSelection() if len(self.__selections) > 1: for sel in self.__selections: @@ -1132,9 +1139,9 @@ break ok = aw.findFirst( ftxt, - self.ui.regexpCheckBox.isChecked(), - self.ui.caseCheckBox.isChecked(), - self.ui.wordCheckBox.isChecked(), + self.regexpCheckBox.isChecked(), + self.caseCheckBox.isChecked(), + self.wordCheckBox.isChecked(), False, True, line, @@ -1163,8 +1170,8 @@ found = ok aw.beginUndoAction() - wordWrap = self.ui.wrapCheckBox.isChecked() - self.ui.wrapCheckBox.setChecked(False) + wordWrap = self.wrapCheckBox.isChecked() + self.wrapCheckBox.setChecked(False) while ok: aw.replace(rtxt) replacements += 1 @@ -1172,7 +1179,7 @@ self.__finding = True aw.endUndoAction() if wordWrap: - self.ui.wrapCheckBox.setChecked(True) + self.wrapCheckBox.setChecked(True) self.__setReplaceSelectionEnabled(False) self.__setReplaceAndSearchEnabled(False) @@ -1198,25 +1205,35 @@ """ Private slot to display this widget in replace mode. - @param text text to be shown in the findtext edit + @param text text to be shown in the findtext edit (defaults to "") + @type str (optional) """ - self.__replace = True + # hide the replace related widgets + for widget in ( + self.replaceLabel, + self.replacetextCombo, + self.replaceButton, + self.replaceSearchButton, + self.replaceAllButton + ): + widget.setVisible(True) self.__setSearchEditColors(True) - self.ui.findtextCombo.clear() - self.ui.findtextCombo.addItems(self.findHistory) - self.ui.findtextCombo.setEditText(text) - self.ui.findtextCombo.lineEdit().selectAll() - self.ui.findtextCombo.setFocus() + self.findtextCombo.clear() + self.findtextCombo.addItems(self.__findHistory) + self.findtextCombo.setEditText(text) + self.findtextCombo.lineEdit().selectAll() + self.findtextCombo.setFocus() self.on_findtextCombo_editTextChanged(text) - self.ui.replacetextCombo.clear() - self.ui.replacetextCombo.addItems(self.replaceHistory) - self.ui.replacetextCombo.setEditText("") + self.replacetextCombo.clear() + self.replacetextCombo.addItems(self.__replaceHistory) + self.replacetextCombo.setEditText("") - self.ui.caseCheckBox.setChecked(False) - self.ui.wordCheckBox.setChecked(False) - self.ui.regexpCheckBox.setChecked(False) + self.caseCheckBox.setChecked(False) + self.wordCheckBox.setChecked(False) + self.regexpCheckBox.setChecked(False) + self.wrapCheckBox.setChecked(False) self.havefound = True @@ -1230,17 +1247,23 @@ self.__setShortcuts() - def show(self, text=""): + def show(self, text="", replaceMode=False): """ Public slot to show the widget. - @param text text to be shown in the findtext edit (string) + @param text text to be shown in the findtext edit (defaults to "") + @type str (optional) + @param replaceMode flag indicating to show the widget in 'replace' mode + (defaults to False) + @type bool (optional) """ - if self.__replace: + super().hide() + if replaceMode: self.__showReplace(text) else: self.__showFind(text) super().show() + self.activateWindow() @pyqtSlot() @@ -1251,6 +1274,8 @@ aw = self.__viewmanager.activeWindow() if aw: aw.hideFindIndicator() + self.__currentEditor.clearSearchSelectionHighlight() + self.__currentEditor = None if self.__sliding: self.__topWidget.close() @@ -1261,13 +1286,17 @@ """ Protected slot to handle key press events. - @param event reference to the key press event (QKeyEvent) + @param event reference to the key press event + @type QKeyEvent """ if event.key() == Qt.Key.Key_Escape: aw = self.__viewmanager.activeWindow() if aw: aw.setFocus(Qt.FocusReason.ActiveWindowFocusReason) aw.hideFindIndicator() + if self.__currentEditor is not None: + self.__currentEditor.clearSearchSelectionHighlight() + self.__currentEditor = None event.accept() if self.__sliding: self.__topWidget.close() @@ -1284,17 +1313,21 @@ searchListChanged = pyqtSignal() - def __init__(self, replace, vm, parent=None): + def __init__(self, vm, parent=None): """ Constructor - @param replace flag indicating a replace widget is called @param vm reference to the viewmanager object - @param parent parent widget of this widget (QWidget) + @type ViewManager + @param parent parent widget of this widget (defaults to None) + @type QWidget (optional) """ super().__init__(parent) - self.__searchReplaceWidget = SearchReplaceWidget(replace, vm, self, True) + self.__searchReplaceWidget = SearchReplaceWidget(vm, self, True) + self.__searchReplaceWidget.layout().setSizeConstraint( + QLayout.SizeConstraint.SetMinAndMaxSize + ) self.__layout = QHBoxLayout(self) self.setLayout(self.__layout) @@ -1333,9 +1366,6 @@ self.__layout.addWidget(self.__scroller) self.__layout.addWidget(self.__rightButton) - self.setMaximumHeight(self.__searchReplaceWidget.sizeHint().height()) - self.adjustSize() - self.__searchReplaceWidget.searchListChanged.connect(self.searchListChanged) self.__leftButton.clicked.connect(self.__slideLeft) self.__rightButton.clicked.connect(self.__slideRight) @@ -1344,7 +1374,8 @@ """ Protected method handling state changes. - @param evt event containing the state change (QEvent) + @param evt event containing the state change + @type QEvent """ if evt.type() == QEvent.Type.FontChange: self.setMaximumHeight(self.__searchReplaceWidget.sizeHint().height()) @@ -1394,18 +1425,31 @@ """ Public slot to update the selection check box. - @param editor reference to the editor (Editor) + @param editor reference to the editor + @type Editor """ self.__searchReplaceWidget.updateSelectionCheckBox(editor) - def show(self, text=""): + def show(self, text="", replaceMode=False): """ Public slot to show the widget. - @param text text to be shown in the findtext edit (string) + @param text text to be shown in the findtext edit (defaults to "") + @type str (optional) + @param replaceMode flag indicating to show the widget with replace mode enabled + (defaults to False) + @type bool (optional) """ - self.__searchReplaceWidget.show(text) + self.__searchReplaceWidget.show(text=text, replaceMode=replaceMode) super().show() + + self.__searchReplaceWidget.setMaximumHeight( + self.__searchReplaceWidget.sizeHint().height() + ) + + self.setMaximumHeight(self.__searchReplaceWidget.sizeHint().height()) + self.adjustSize() + self.__enableScrollerButtons() def __slideLeft(self): @@ -1426,7 +1470,8 @@ """ Private method to move the sliding widget. - @param toLeft flag indicating to move to the left (boolean) + @param toLeft flag indicating to move to the left + @type bool """ scrollBar = self.__scroller.horizontalScrollBar() stepSize = scrollBar.singleStep() @@ -1452,7 +1497,8 @@ """ Protected method to handle resize events. - @param evt reference to the resize event (QResizeEvent) + @param evt reference to the resize event + @type QResizeEvent """ self.__enableScrollerButtons()