diff --git a/__pycache__/custom_file_dialog.cpython-312.pyc b/__pycache__/custom_file_dialog.cpython-312.pyc index fd9f668..3cc7c5a 100644 Binary files a/__pycache__/custom_file_dialog.cpython-312.pyc and b/__pycache__/custom_file_dialog.cpython-312.pyc differ diff --git a/custom_file_dialog.py b/custom_file_dialog.py index 70c3299..6d873fd 100644 --- a/custom_file_dialog.py +++ b/custom_file_dialog.py @@ -331,38 +331,56 @@ class CustomFileDialog(tk.Toplevel): try: all_files = [] is_recursive = self.settings.get("recursive_search", True) + search_hidden = self.settings.get("search_hidden_files", False) + search_term_lower = search_term.lower() + for search_dir in search_dirs: if not (self.search_thread and self.search_thread.is_alive()): break if not os.path.exists(search_dir): continue - cmd = ['find', '.', search_dir, '-iname', f'*{search_term}*'] - if not is_recursive: - cmd.insert(3, '-maxdepth') - cmd.insert(4, '1') - - self.search_process = subprocess.Popen( - cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, - text=True, preexec_fn=os.setsid - ) - stdout, _ = self.search_process.communicate() - if self.search_process.returncode == 0: - all_files.extend([line for line in stdout.strip().split('\n') if line and os.path.exists(line)]) + is_home_search = os.path.abspath(search_dir) == home_dir + follow_links = is_recursive and is_home_search if is_recursive: - break + for root, dirs, files in os.walk(search_dir, followlinks=follow_links): + if not (self.search_thread and self.search_thread.is_alive()): + raise InterruptedError("Search cancelled by user") + + if not search_hidden: + # Exclude hidden directories from traversal + dirs[:] = [d for d in dirs if not d.startswith('.')] + # Exclude hidden files from results + files = [f for f in files if not f.startswith('.')] + + for name in files + dirs: + if search_term_lower in name.lower(): + all_files.append(os.path.join(root, name)) + else: # Non-recursive search + for name in os.listdir(search_dir): + if not (self.search_thread and self.search_thread.is_alive()): + raise InterruptedError("Search cancelled by user") + + if not search_hidden and name.startswith('.'): + continue + + if search_term_lower in name.lower(): + all_files.append(os.path.join(search_dir, name)) + + if is_recursive: + break # Only search the first directory recursively if not (self.search_thread and self.search_thread.is_alive()): - raise subprocess.SubprocessError("Search cancelled by user") + raise InterruptedError("Search cancelled by user") seen = set() unique_files = [x for x in all_files if not (x in seen or seen.add(x))] - search_hidden = self.settings.get("search_hidden_files", False) + + # Final filtering based on file type self.search_results = [ p for p in unique_files - if (search_hidden or not any(part.startswith('.') for part in p.split(os.sep))) and - (self._matches_filetype(os.path.basename(p)) or os.path.isdir(p)) + if self._matches_filetype(os.path.basename(p)) or os.path.isdir(p) ] def update_ui(): @@ -377,8 +395,8 @@ class CustomFileDialog(tk.Toplevel): text=f"Keine Ergebnisse für '{search_term}'.") self.after(0, update_ui) - except Exception as e: - if isinstance(e, subprocess.SubprocessError): + except (Exception, InterruptedError) as e: + if isinstance(e, (InterruptedError, subprocess.SubprocessError)): self.after(0, lambda: self.widget_manager.search_status_label.config(text="Suche abgebrochen.")) else: self.after(0, lambda: MessageDialog(