Sun, 17 Jan 2021 16:21:57 +0100
Find File Dialog
- added option to exclude hidden files and directories
- changed directory tree search logic to derive the file patterns from the project file type associations, if the directory to be searched is a sub-directory of the project
--- a/docs/changelog Sun Jan 17 12:40:19 2021 +0100 +++ b/docs/changelog Sun Jan 17 16:21:57 2021 +0100 @@ -27,6 +27,11 @@ -- added code to enclose the current selection by entering ", ' or a bracket ( (, ), [, ], {, }, <, > ) characters -- extended the exporters to support sub-styles +- Find File Dialog + -- added option to exclude hidden files and directories + -- changed directory tree search logic to derive the file patterns from the + project file type associations, if the directory to be searched is a + sub-directory of the project - User Interface -- added capability to show Qt6 documentation (configurable) - VirtualEnv Manager
--- a/eric6/Project/Project.py Sun Jan 17 12:40:19 2021 +0100 +++ b/eric6/Project/Project.py Sun Jan 17 16:21:57 2021 +0100 @@ -2853,7 +2853,22 @@ dlg.transferData() self.setDirty(True) self.__reorganizeFiles() - + + def getFiletypeAssociations(self, associationType): + """ + Public method to get the list of file type associations for + the given association type. + + @param associationType type of the association (one of FORMS, + INTERFACES, OTHERS, PROTOCOLS, RESOURCES, SOURCES or + TRANSLATIONS) + @type str + @return list of file patterns for the given type + @rtype list of str + """ + return [assoc for assoc in self.pdata["FILETYPES"] + if self.pdata["FILETYPES"][assoc] == associationType] + def __showLexerAssociations(self): """ Private slot to display the lexer association dialog.
--- a/eric6/UI/FindFileDialog.py Sun Jan 17 12:40:19 2021 +0100 +++ b/eric6/UI/FindFileDialog.py Sun Jan 17 16:21:57 2021 +0100 @@ -101,6 +101,11 @@ self.replacetextCombo.addItems(self.replaceHistory) self.dirPicker.addItems(self.dirHistory) + self.excludeHiddenCheckBox.setChecked(Preferences.toBool( + Preferences.Prefs.settings.value( + "FindFileDialog/ExcludeHidden", True) + )) + self.project = project self.findList.headerItem().setText(self.findList.columnCount(), "") @@ -323,10 +328,16 @@ if self.projectButton.isChecked(): if self.filterCheckBox.isChecked(): - files = [self.project.getRelativePath(file) - for file in - self.__getFileList( - self.project.getProjectPath(), filterRe)] + files = [ + self.project.getRelativePath(file) + for file in + self.__getFileList( + self.project.getProjectPath(), + filterRe, + excludeHiddenDirs=self.excludeHiddenCheckBox + .isChecked(), + ) + ] else: files = [] if self.sourcesCheckBox.isChecked(): @@ -342,27 +353,73 @@ elif self.dirButton.isChecked(): if not self.filterCheckBox.isChecked(): filters = [] - if self.sourcesCheckBox.isChecked(): - filters.extend( - ["^{0}$".format( - assoc.replace(".", r"\.").replace("*", ".*")) - for assoc in list( - Preferences.getEditorLexerAssocs().keys()) - if assoc not in self.formsExt + self.interfacesExt + - self.protocolsExt]) - if self.formsCheckBox.isChecked(): - filters.append(self.filterForms) - if self.interfacesCheckBox.isChecked(): - filters.append(self.filterInterfaces) - if self.protocolsCheckBox.isChecked(): - filters.append(self.filterProtocols) - if self.resourcesCheckBox.isChecked(): - filters.append(self.filterResources) + if ( + self.project.isOpen() and + os.path.abspath(self.dirPicker.currentText()).startswith( + self.project.getProjectPath()) + ): + if self.sourcesCheckBox.isChecked(): + filters.extend([ + "^{0}$".format( + assoc.replace(".", r"\.").replace("*", ".*") + ) for assoc in + self.project.getFiletypeAssociations("SOURCES") + ]) + if self.formsCheckBox.isChecked(): + filters.extend([ + "^{0}$".format( + assoc.replace(".", r"\.").replace("*", ".*") + ) for assoc in + self.project.getFiletypeAssociations("FORMS") + ]) + if self.interfacesCheckBox.isChecked(): + filters.extend([ + "^{0}$".format( + assoc.replace(".", r"\.").replace("*", ".*") + ) for assoc in + self.project.getFiletypeAssociations("INTERFACES") + ]) + if self.protocolsCheckBox.isChecked(): + filters.extend([ + "^{0}$".format( + assoc.replace(".", r"\.").replace("*", ".*") + ) for assoc in + self.project.getFiletypeAssociations("PROTOCOLS") + ]) + if self.resourcesCheckBox.isChecked(): + filters.extend([ + "^{0}$".format( + assoc.replace(".", r"\.").replace("*", ".*") + ) for assoc in + self.project.getFiletypeAssociations("RESOURCES") + ]) + else: + if self.sourcesCheckBox.isChecked(): + filters.extend([ + "^{0}$".format( + assoc.replace(".", r"\.").replace("*", ".*")) + for assoc in list( + Preferences.getEditorLexerAssocs().keys()) + if assoc not in + self.formsExt + self.interfacesExt + + self.protocolsExt + self.resourcesExt + ]) + if self.formsCheckBox.isChecked(): + filters.append(self.filterForms) + if self.interfacesCheckBox.isChecked(): + filters.append(self.filterInterfaces) + if self.protocolsCheckBox.isChecked(): + filters.append(self.filterProtocols) + if self.resourcesCheckBox.isChecked(): + filters.append(self.filterResources) filterString = "|".join(filters) filterRe = re.compile(filterString) files = self.__getFileList( os.path.abspath(self.dirPicker.currentText()), - filterRe) + filterRe, + excludeHiddenDirs=self.excludeHiddenCheckBox.isChecked(), + excludeHiddenFiles=self.excludeHiddenCheckBox.isChecked(), + ) elif self.openFilesButton.isChecked(): vm = e5App().getObject("ViewManager") vm.checkAllDirty() @@ -408,6 +465,9 @@ Preferences.Prefs.settings.setValue( "FindFileDialog/SearchHistory", self.searchHistory[:30]) + Preferences.Prefs.settings.setValue( + "FindFileDialog/ExcludeHidden", + self.excludeHiddenCheckBox.isChecked()) if self.__replaceMode: replTxt = self.replacetextCombo.currentText() @@ -561,22 +621,35 @@ else: self.sourceFile.emit(fn, line, "", start, end) - def __getFileList(self, path, filterRe): + def __getFileList(self, path, filterRe, excludeHiddenDirs=False, + excludeHiddenFiles=False): """ Private method to get a list of files to search. - @param path the root directory to search in (string) + @param path the root directory to search in + @type str @param filterRe regular expression defining the filter - criteria (regexp object) - @return list of files to be processed (list of strings) + criteria + @type regexp object + @param excludeHiddenDirs flag indicating to exclude hidden directories + @type bool + @param excludeHiddenFiles flag indicating to exclude hidden files + @type bool + @return list of files to be processed + @rtype list of str """ path = os.path.abspath(path) files = [] - for dirname, _, names in os.walk(path): - files.extend([os.path.join(dirname, f) - for f in names - if re.match(filterRe, f)] - ) + for dirname, dirs, filenames in os.walk(path): + files.extend([ + os.path.join(dirname, f) for f in filenames + if (not (excludeHiddenFiles and f.startswith(".")) and + re.match(filterRe, f)) + ]) + if excludeHiddenDirs: + for d in dirs[:]: + if d .startswith("."): + dirs.remove(d) return files def setSearchDirectory(self, searchDir):
--- a/eric6/UI/FindFileDialog.ui Sun Jan 17 12:40:19 2021 +0100 +++ b/eric6/UI/FindFileDialog.ui Sun Jan 17 16:21:57 2021 +0100 @@ -305,6 +305,19 @@ </widget> </item> <item> + <widget class="QCheckBox" name="excludeHiddenCheckBox"> + <property name="toolTip"> + <string>Select to exclude hidden files and directories when searching a directory tree.</string> + </property> + <property name="text"> + <string>Exclude hidden files and directories</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> <spacer name="verticalSpacer"> <property name="orientation"> <enum>Qt::Vertical</enum> @@ -312,7 +325,7 @@ <property name="sizeHint" stdset="0"> <size> <width>20</width> - <height>40</height> + <height>10</height> </size> </property> </spacer> @@ -355,7 +368,7 @@ <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> - <verstretch>3</verstretch> + <verstretch>5</verstretch> </sizepolicy> </property> <property name="alternatingRowColors"> @@ -432,6 +445,7 @@ <tabstop>dirButton</tabstop> <tabstop>dirPicker</tabstop> <tabstop>openFilesButton</tabstop> + <tabstop>excludeHiddenCheckBox</tabstop> <tabstop>findList</tabstop> <tabstop>replaceButton</tabstop> </tabstops>