src/eric7/UI/FindFileWidget.py

branch
eric7
changeset 10492
53eac4c7d10b
parent 10486
157f119cd10d
child 10494
8db0328580d7
--- a/src/eric7/UI/FindFileWidget.py	Mon Jan 08 11:50:27 2024 +0100
+++ b/src/eric7/UI/FindFileWidget.py	Wed Jan 10 09:42:15 2024 +0100
@@ -7,6 +7,7 @@
 Module implementing a dialog to search for text in files.
 """
 
+import json
 import os
 import re
 import time
@@ -83,12 +84,15 @@
         super().__init__(parent)
         self.setupUi(self)
 
+        self.__project = project
+
         self.layout().setContentsMargins(0, 3, 0, 0)
 
         self.caseToolButton.setIcon(EricPixmapCache.getIcon("caseSensitive"))
         self.wordToolButton.setIcon(EricPixmapCache.getIcon("wholeWord"))
         self.escapeToolButton.setIcon(EricPixmapCache.getIcon("esc-code"))
         self.regexpToolButton.setIcon(EricPixmapCache.getIcon("regexp"))
+        self.filtersConfigButton.setIcon(EricPixmapCache.getIcon("edit"))
 
         self.dirPicker.setMode(EricPathPickerModes.DIRECTORY_MODE)
         self.dirPicker.setInsertPolicy(QComboBox.InsertPolicy.InsertAtTop)
@@ -148,8 +152,7 @@
             )
         )
 
-        self.__project = project
-
+        self.__populateFiltersSelector()
         self.populateFileCategories()
 
         # ensure the file type tab is the current one
@@ -174,6 +177,32 @@
         self.__replaceMode = True
         self.__toggleReplaceMode()
 
+    def __populateFiltersSelector(self):
+        """
+        Private method to (re-)populate the file filters selector.
+        """
+        currentFilter = self.filterComboBox.currentText()
+        self.filterComboBox.clear()
+
+        # add standard entries
+        self.filterComboBox.addItem("")
+        self.filterComboBox.addItem(self.tr("All Files"), "*")
+
+        # add configured entries
+        # filters is a dictionary with the filter text as key and the pattern as value
+        self.__filters = json.loads(
+            Preferences.getSettings().value("FindFileWidget/FileFilters", "{}")
+            # noqa: M613
+        )
+        for fileFilter in sorted(self.__filters):
+            self.filterComboBox.addItem(fileFilter, self.__filters[filter])
+
+        # reselect the current entry
+        index = self.filterComboBox.findText(currentFilter)
+        if index == -1:
+            index = 0
+        self.filterComboBox.setCurrentIndex(index)
+
     def populateFileCategories(self):
         """
         Public method to populate the search file categories list.
@@ -370,6 +399,21 @@
             # only one of regexp or escape can be selected
             self.escapeToolButton.setChecked(False)
 
+    @pyqtSlot()
+    def on_filtersConfigButton_clicked(self):
+        """
+        Private slot to edit the list of defined file filter entries.
+        """
+        from .FindFileFiltersEditDialog import FindFileFiltersEditDialog
+
+        dlg = FindFileFiltersEditDialog(self.__filters, self)
+        if dlg.exec() == QDialog.DialogCode.Accepted:
+            filters = dlg.getFilters()
+            Preferences.getSettings().setValue(
+                "FindFileWidget/FileFilters", json.dumps(filters)
+            )
+            self.__populateFiltersSelector()
+
     @pyqtSlot(str)
     def on_findtextCombo_editTextChanged(self, text):
         """
@@ -431,13 +475,13 @@
         """
         self.__enableFindButton()
 
-    @pyqtSlot(str)
-    def on_filterEdit_textEdited(self, text):
+    @pyqtSlot(int)
+    def on_filterComboBox_currentIndexChanged(self, index):
         """
-        Private slot to handle the textChanged signal of the file filter edit.
+        Private slot to handle the selection of a file filter.
 
-        @param text (ignored)
-        @type str
+        @param index index of the selected entry
+        @type int
         """
         self.__enableFindButton()
 
@@ -455,7 +499,11 @@
                     or not os.path.exists(os.path.abspath(self.dirPicker.currentText()))
                 )
             )
-            or (self.filterCheckBox.isChecked() and self.filterEdit.text() == "")
+            or (
+                self.filterCheckBox.isChecked()
+                and self.filterComboBox.currentText() == ""
+            )
+            or (self.projectButton.isChecked() and not self.__project.isOpen())
         ):
             self.findButton.setEnabled(False)
         else:
@@ -472,6 +520,20 @@
         """
         return txt.rstrip("\n\r")
 
+    def __buildReFileFilter(self, fileFilter):
+        """
+        Private method to convert a file filter expression into a valid re search
+        pattern.
+
+        @param fileFilter file filter expression
+        @type str
+        @return re search pattern with dot, question mark and star converted
+        @rtype str
+        """
+        return "^{0}$".format(
+            fileFilter.strip().replace(".", r"\.").replace("*", ".*").replace("?", ".")
+        )
+
     @pyqtSlot()
     def __stopSearch(self):
         """
@@ -493,10 +555,9 @@
         self.__cancelSearch = False
 
         if self.filterCheckBox.isChecked():
-            fileFilter = self.filterEdit.text()
+            fileFilter = self.filterComboBox.currentData()
             fileFilterList = [
-                "^{0}$".format(filter.replace(".", r"\.").replace("*", ".*"))
-                for filter in fileFilter.split(";")
+                self.__buildReFileFilter(filter) for filter in fileFilter.split(";")
             ]
             filterRe = re.compile("|".join(fileFilterList))
 
@@ -529,9 +590,7 @@
                         if itm.checkState() == Qt.CheckState.Checked:
                             filters.extend(
                                 [
-                                    "^{0}$".format(
-                                        assoc.replace(".", r"\.").replace("*", ".*")
-                                    )
+                                    self.__buildReFileFilter(assoc)
                                     for assoc in self.__project.getFiletypeAssociations(
                                         itm.data(Qt.ItemDataRole.UserRole)
                                     )
@@ -545,9 +604,7 @@
                             if fileType == "SOURCES":
                                 filters.extend(
                                     [
-                                        "^{0}$".format(
-                                            assoc.replace(".", r"\.").replace("*", ".*")
-                                        )
+                                        self.__buildReFileFilter(assoc)
                                         for assoc in Preferences.getEditorLexerAssocs()
                                         if assoc
                                         not in self.__project.getFileCategoryExtension(
@@ -558,9 +615,7 @@
                             else:
                                 filters.extend(
                                     [
-                                        "^{0}$".format(
-                                            ext.replace(".", r"\.").replace("*", ".*")
-                                        )
+                                        self.__buildReFileFilter(ext)
                                         for ext in self.__project.getFileCategoryExtension(
                                             # __IGNORE_WARNING__
                                             fileType

eric ide

mercurial