Find File Dialog

Sun, 17 Jan 2021 16:21:57 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sun, 17 Jan 2021 16:21:57 +0100
changeset 7992
0d1e35a10a0b
parent 7990
3b865f4b7dff
child 7993
0304d4bce902

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

docs/changelog file | annotate | diff | comparison | revisions
eric6/Project/Project.py file | annotate | diff | comparison | revisions
eric6/UI/FindFileDialog.py file | annotate | diff | comparison | revisions
eric6/UI/FindFileDialog.ui file | annotate | diff | comparison | revisions
--- 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>

eric ide

mercurial