--- a/src/eric7/UI/FindFileWidget.py Tue Nov 19 16:08:15 2024 +0100 +++ b/src/eric7/UI/FindFileWidget.py Thu Nov 21 17:12:21 2024 +0100 @@ -93,6 +93,7 @@ self.escapeToolButton.setIcon(EricPixmapCache.getIcon("esc-code")) self.regexpToolButton.setIcon(EricPixmapCache.getIcon("regexp")) self.filtersConfigButton.setIcon(EricPixmapCache.getIcon("edit")) + self.excludeFiltersConfigButton.setIcon(EricPixmapCache.getIcon("edit")) self.dirPicker.setMode(EricPathPickerModes.DIRECTORY_MODE) self.dirPicker.setInsertPolicy(QComboBox.InsertPolicy.InsertAtTop) @@ -152,9 +153,18 @@ ) ) - self.__populateFiltersSelector() + self.__populateFilterSelectors() self.populateFileCategories() + self.excludeFilterCheckBox.setChecked( + EricUtilities.toBool( + Preferences.getSettings().value("FindFileWidget/ExcludeFilter", False) + ) + ) + self.excludeFilterComboBox.setCurrentText( + Preferences.getSettings().value("FindFileWidget/ExcludeFilterName", "") + ) + # ensure the file type tab is the current one self.fileOptionsWidget.setCurrentWidget(self.fileTypeTab) @@ -177,17 +187,22 @@ self.__replaceMode = True self.__toggleReplaceMode() - def __populateFiltersSelector(self): + def __populateFilterSelectors(self): """ Private method to (re-)populate the file filters selector. """ currentFilter = self.filterComboBox.currentText() self.filterComboBox.clear() + currentExcludeFilter = self.excludeFilterComboBox.currentText() + self.excludeFilterComboBox.clear() + # add standard entries self.filterComboBox.addItem("") self.filterComboBox.addItem(self.tr("All Files"), ["*"]) + self.excludeFilterComboBox.addItem("") + # add configured entries # FileFilters is a dictionary with the filter name as key and # a list of file name patterns as value @@ -202,6 +217,19 @@ ), self.__filters[fileFilter], ) + # ExcludeFileFilters is a dictionary with the filter name as key and + # a list of file name patterns as value + self.__excludeFilters = json.loads( + Preferences.getSettings().value("FindFileWidget/ExcludeFileFilters", "{}") + # noqa: M613 + ) + for fileFilter in sorted(self.__excludeFilters): + self.excludeFilterComboBox.addItem( + self.tr("{0} ({1})").format( + fileFilter, " ".join(self.__excludeFilters[fileFilter]) + ), + self.__excludeFilters[fileFilter], + ) # reselect the current entry index = self.filterComboBox.findText(currentFilter) @@ -209,6 +237,11 @@ index = 0 self.filterComboBox.setCurrentIndex(index) + index = self.excludeFilterComboBox.findText(currentExcludeFilter) + if index == -1: + index = 0 + self.excludeFilterComboBox.setCurrentIndex(index) + def populateFileCategories(self): """ Public method to populate the search file categories list. @@ -418,7 +451,22 @@ Preferences.getSettings().setValue( "FindFileWidget/FileFilters", json.dumps(filters) ) - self.__populateFiltersSelector() + self.__populateFilterSelectors() + + @pyqtSlot() + def on_excludeFiltersConfigButton_clicked(self): + """ + Private slot to edit the list of defined exclude file filter entries. + """ + from .FindFileFiltersEditDialog import FindFileFiltersEditDialog + + dlg = FindFileFiltersEditDialog(self.__excludeFilters, parent=self) + if dlg.exec() == QDialog.DialogCode.Accepted: + filters = dlg.getFilters() + Preferences.getSettings().setValue( + "FindFileWidget/ExcludeFileFilters", json.dumps(filters) + ) + self.__populateFilterSelectors() @pyqtSlot(str) def on_findtextCombo_editTextChanged(self, text): @@ -492,6 +540,23 @@ self.__enableFindButton() @pyqtSlot() + def on_excludeFilterCheckBox_clicked(self): + """ + Private slot to handle the selection of the exclude file filter check box. + """ + self.__enableFindButton() + + @pyqtSlot(int) + def on_excludeFilterComboBox_currentIndexChanged(self, index): + """ + Private slot to handle the selection of an exclude file filter. + + @param index index of the selected entry + @type int + """ + self.__enableFindButton() + + @pyqtSlot() def __enableFindButton(self): """ Private slot called to enable the find button. @@ -510,6 +575,10 @@ and self.filterComboBox.currentText() == "" ) or (self.projectButton.isChecked() and not self.__project.isOpen()) + or ( + self.excludeFilterCheckBox.isChecked() + and self.excludeFilterComboBox.currentText() == "" + ) ): self.findButton.setEnabled(False) else: @@ -559,6 +628,8 @@ return self.__cancelSearch = False + filterRe = None + excludeFilterRe = None if self.filterCheckBox.isChecked(): fileFilter = self.filterComboBox.currentData() @@ -567,6 +638,13 @@ ) filterRe = re.compile(fileFilterPattern) + if self.excludeFilterCheckBox.isChecked(): + excludeFileFilter = self.excludeFilterComboBox.currentData() + excludeFileFilterPattern = "|".join( + self.__buildReFileFilter(filter) for filter in excludeFileFilter + ) + excludeFilterRe = re.compile(excludeFileFilterPattern) + if self.projectButton.isChecked(): if self.filterCheckBox.isChecked(): files = [ @@ -633,6 +711,7 @@ files = self.__getFileList( os.path.abspath(self.dirPicker.currentText()), filterRe, + None, excludeHiddenDirs=self.excludeHiddenCheckBox.isChecked(), excludeHiddenFiles=self.excludeHiddenCheckBox.isChecked(), ) @@ -641,6 +720,9 @@ vm.checkAllDirty() files = vm.getOpenFilenames() + if excludeFilterRe: + files = [f for f in files if not excludeFilterRe.match(os.path.basename(f))] + self.findList.clear() self.findProgressLabel.setPath("") self.findProgress.setValue(0) @@ -686,6 +768,12 @@ Preferences.getSettings().setValue( "FindFileWidget/ExcludeHidden", self.excludeHiddenCheckBox.isChecked() ) + Preferences.getSettings().setValue( + "FindFileWidget/ExcludeFilter", self.excludeFilterCheckBox.isChecked() + ) + Preferences.getSettings().setValue( + "FindFileWidget/ExcludeFilterName", self.excludeFilterComboBox.currentText() + ) if self.__replaceMode: replTxt = self.replacetextCombo.currentText() @@ -895,7 +983,7 @@ for f in filenames if ( not (excludeHiddenFiles and f.startswith(".")) - and re.match(filterRe, f) + and (filterRe and filterRe.match(f)) ) ] )