eric6/QScintilla/SearchReplaceWidget.py

changeset 8129
52c76e6cb35b
parent 7923
91e843545d9a
child 8130
5fe4ff181b68
--- a/eric6/QScintilla/SearchReplaceWidget.py	Mon Feb 22 19:15:06 2021 +0100
+++ b/eric6/QScintilla/SearchReplaceWidget.py	Mon Feb 22 19:30:16 2021 +0100
@@ -7,7 +7,10 @@
 Module implementing the search and replace widget.
 """
 
+import re
+
 from PyQt5.QtCore import pyqtSignal, Qt, pyqtSlot, QEvent
+from PyQt5.QtGui import QColor, QPalette
 from PyQt5.QtWidgets import (
     QWidget, QHBoxLayout, QToolButton, QScrollArea, QSizePolicy, QFrame
 )
@@ -131,6 +134,8 @@
             UI.PixmapCache.getIcon("1leftarrow"))
         self.ui.findNextButton.setIcon(
             UI.PixmapCache.getIcon("1rightarrow"))
+        self.ui.extendButton.setIcon(
+            UI.PixmapCache.getIcon("2rightarrow"))
         
         if replace:
             self.ui.replaceButton.setIcon(
@@ -149,6 +154,16 @@
             self.ui.replacetextCombo.lineEdit().returnPressed.connect(
                 self.on_replaceButton_clicked)
         
+        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)
+        
         # define actions
         self.findNextAct = E5Action(
             self.tr('Find Next'),
@@ -324,27 +339,154 @@
         
         return startLine, startIndex, endLine, endIndex
     
+    @pyqtSlot(str)
     def on_findtextCombo_editTextChanged(self, txt):
         """
         Private slot to enable/disable the find buttons.
         
-        @param txt text of the find text combo (string)
+        @param txt text of the find text combo
+        @type str
+        """
+        enable = bool(txt)
+        
+        self.__setFindNextEnabled(enable)
+        self.__setFindPrevEnabled(enable)
+        self.ui.extendButton.setEnabled(enable)
+        if self.__replace:
+            self.__setReplaceSelectionEnabled(False)
+            self.__setReplaceAndSearchEnabled(False)
+            self.__setReplaceAllEnabled(enable)
+    
+    @pyqtSlot(str)
+    def __quickSearch(self, txt):
+        """
+        Private slot to search for the entered text while typing.
+        
+        @param txt text of the search edit
+        @type str
         """
+        aw = self.__viewmanager.activeWindow()
+        aw.hideFindIndicator()
+        if Preferences.getEditor("QuickSearchMarkersEnabled"):
+            self.__quickSearchMarkOccurrences(txt)
+        
+        lineFrom, indexFrom, lineTo, indexTo = aw.getSelection()
+        posixMode = (Preferences.getEditor("SearchRegexpMode") == 0 and
+                     self.ui.regexpCheckBox.isChecked())
+        cxx11Mode = (Preferences.getEditor("SearchRegexpMode") == 1 and
+                     self.ui.regexpCheckBox.isChecked())
+        ok = aw.findFirst(
+            txt,
+            self.ui.regexpCheckBox.isChecked(),
+            self.ui.caseCheckBox.isChecked(),
+            self.ui.wordCheckBox.isChecked(),
+            self.ui.wrapCheckBox.isChecked(),
+            not self.__findBackwards,
+            lineFrom, indexFrom,
+            posix=posixMode,
+            cxx11=cxx11Mode
+        )
+        if ok:
+            sline, sindex, eline, eindex = aw.getSelection()
+            aw.showFindIndicator(sline, sindex, eline, eindex)
+        
         if not txt:
-            self.__setFindNextEnabled(False)
-            self.__setFindPrevEnabled(False)
-            if self.__replace:
-                self.__setReplaceSelectionEnabled(False)
-                self.__setReplaceAndSearchEnabled(False)
-                self.__setReplaceAllEnabled(False)
+            ok = True   # reset the color in case of an empty text
+        
+        self.__setSearchEditColors(ok)
+    
+    def __quickSearchMarkOccurrences(self, txt):
+        """
+        Private method to mark all occurrences of the search text.
+        
+        @param txt text to search for (string)
+        """
+        aw = self.__viewmanager.activeWindow()
+        
+        lineFrom = 0
+        indexFrom = 0
+        lineTo = -1
+        indexTo = -1
+        
+        aw.clearSearchIndicators()
+        posixMode = (Preferences.getEditor("SearchRegexpMode") == 0 and
+                     self.ui.regexpCheckBox.isChecked())
+        cxx11Mode = (Preferences.getEditor("SearchRegexpMode") == 1 and
+                     self.ui.regexpCheckBox.isChecked())
+        ok = aw.findFirstTarget(
+            txt,
+            self.ui.regexpCheckBox.isChecked(),
+            self.ui.caseCheckBox.isChecked(),
+            self.ui.wordCheckBox.isChecked(),
+            lineFrom, indexFrom, lineTo, indexTo,
+            posix=posixMode,
+            cxx11=cxx11Mode
+        )
+        while ok:
+            tgtPos, tgtLen = aw.getFoundTarget()
+            aw.setSearchIndicator(tgtPos, tgtLen)
+            ok = aw.findNextTarget()
+    
+    def __setSearchEditColors(self, ok):
+        """
+        Private method to set the search edit colors.
+        
+        @param ok flag indicating a match
+        @type bool
+        """
+        if not ok:
+            palette = self.ui.findtextCombo.lineEdit().palette()
+            palette.setColor(QPalette.Base, QColor("red"))
+            palette.setColor(QPalette.Text, QColor("white"))
+            self.ui.findtextCombo.lineEdit().setPalette(palette)
         else:
-            self.__setFindNextEnabled(True)
-            self.__setFindPrevEnabled(True)
-            if self.__replace:
-                self.__setReplaceSelectionEnabled(False)
-                self.__setReplaceAndSearchEnabled(False)
-                self.__setReplaceAllEnabled(True)
-
+            palette = self.ui.findtextCombo.lineEdit().palette()
+            palette.setColor(
+                QPalette.Base,
+                self.ui.findtextCombo.palette().color(QPalette.Base))
+            palette.setColor(
+                QPalette.Text,
+                self.ui.findtextCombo.palette().color(QPalette.Text))
+            self.ui.findtextCombo.lineEdit().setPalette(palette)
+    
+    @pyqtSlot()
+    def on_extendButton_clicked(self):
+        """
+        Private slot to handle the quicksearch extend action.
+        """
+        aw = self.__viewmanager.activeWindow()
+        if aw is None:
+            return
+        
+        txt = self.ui.findtextCombo.currentText()
+        if not txt:
+            return
+        
+        line, index = aw.getCursorPosition()
+        text = aw.text(line)
+        
+        rx = re.compile(r'[^\w_]')
+        match = rx.search(text, index)
+        if match:
+            end = match.start()
+            if end > index:
+                ext = text[index:end]
+                txt += ext
+                self.ui.findtextCombo.setEditText(txt)
+                self.ui.findtextCombo.lineEdit().selectAll()
+                self.__quickSearch(txt)
+    
+    @pyqtSlot(bool)
+    def __updateQuickSearchMarkers(self, on):
+        """
+        Private slot to handle the selection of the various check boxes.
+        
+        @param on status of the check box (ignored)
+        @type bool
+        """
+        txt = self.ui.findtextCombo.currentText()
+        self.__quickSearch(txt)
+    
     @pyqtSlot()
     def on_findNextButton_clicked(self):
         """
@@ -376,6 +518,7 @@
         self.searchListChanged.emit()
         
         ok = self.__findNextPrev(txt, False)
+        self.__setSearchEditColors(ok)
         if ok:
             if self.__replace:
                 self.__setReplaceSelectionEnabled(True)
@@ -413,6 +556,7 @@
         self.searchListChanged.emit()
         
         ok = self.__findNextPrev(txt, True)
+        self.__setSearchEditColors(ok)
         if ok:
             if self.__replace:
                 self.__setReplaceSelectionEnabled(True)
@@ -716,6 +860,7 @@
         """
         self.__replace = False
         
+        self.__setSearchEditColors(True)
         self.ui.findtextCombo.clear()
         self.ui.findtextCombo.addItems(self.findHistory)
         self.ui.findtextCombo.setEditText(text)
@@ -831,6 +976,7 @@
         
         if searchNext:
             ok = self.__findNextPrev(ftxt, self.__findBackwards)
+            self.__setSearchEditColors(ok)
             
             if not ok:
                 self.__setReplaceSelectionEnabled(False)
@@ -841,6 +987,7 @@
         else:
             self.__setReplaceSelectionEnabled(False)
             self.__setReplaceAndSearchEnabled(False)
+            self.__setSearchEditColors(True)
         
         self.__finding = False
     
@@ -1003,6 +1150,7 @@
         """
         self.__replace = True
         
+        self.__setSearchEditColors(True)
         self.ui.findtextCombo.clear()
         self.ui.findtextCombo.addItems(self.findHistory)
         self.ui.findtextCombo.setEditText(text)

eric ide

mercurial