import os import shutil import tkinter as tk from tkinter import ttk try: import send2trash SEND2TRASH_AVAILABLE = True except ImportError: SEND2TRASH_AVAILABLE = False from shared_libs.message import MessageDialog class FileOperationsManager: def __init__(self, dialog): self.dialog = dialog def delete_selected_item(self, event=None): """Deletes or moves the selected item to trash based on settings.""" if not self.dialog.selected_file or not os.path.exists(self.dialog.selected_file): return use_trash = self.dialog.settings.get( "use_trash", False) and SEND2TRASH_AVAILABLE confirm = self.dialog.settings.get("confirm_delete", False) action_text = "in den Papierkorb verschieben" if use_trash else "endgültig löschen" item_name = os.path.basename(self.dialog.selected_file) if not confirm: dialog = MessageDialog( master=self.dialog, title="Bestätigung erforderlich", text=f"Möchten Sie '{item_name}' wirklich {action_text}?", message_type="question" ) if not dialog.show(): return try: if use_trash: send2trash.send2trash(self.dialog.selected_file) else: if os.path.isdir(self.dialog.selected_file): shutil.rmtree(self.dialog.selected_file) else: os.remove(self.dialog.selected_file) self.dialog.view_manager.populate_files() self.dialog.widget_manager.search_status_label.config( text=f"'{item_name}' wurde erfolgreich entfernt.") except Exception as e: MessageDialog( master=self.dialog, title="Fehler", text=f"Fehler beim Entfernen von '{item_name}':\n{e}", message_type="error" ).show() def create_new_folder(self): self._create_new_item(is_folder=True) def create_new_file(self): self._create_new_item(is_folder=False) def _create_new_item(self, is_folder): base_name = "Neuer Ordner" if is_folder else "Neues Dokument.txt" new_name = self._get_unique_name(base_name) new_path = os.path.join(self.dialog.current_dir, new_name) try: if is_folder: os.mkdir(new_path) else: open(new_path, 'a').close() self.dialog.view_manager.populate_files(item_to_rename=new_name) except Exception as e: self.dialog.widget_manager.search_status_label.config( text=f"Fehler beim Erstellen: {e}") def _get_unique_name(self, base_name): name, ext = os.path.splitext(base_name) counter = 1 new_name = base_name while os.path.exists(os.path.join(self.dialog.current_dir, new_name)): counter += 1 new_name = f"{name} {counter}{ext}" return new_name def _copy_to_clipboard(self, data): self.dialog.clipboard_clear() self.dialog.clipboard_append(data) self.dialog.widget_manager.search_status_label.config( text=f"'{self.dialog.shorten_text(data, 50)}' in Zwischenablage kopiert.") def _show_context_menu(self, event, item_path): if not item_path: return "break" if hasattr(self.dialog, 'context_menu') and self.dialog.context_menu.winfo_exists(): self.dialog.context_menu.destroy() self.dialog.context_menu = tk.Menu(self.dialog, tearoff=0, background=self.dialog.style_manager.header, foreground=self.dialog.style_manager.color_foreground, activebackground=self.dialog.style_manager.selection_color, activeforeground=self.dialog.style_manager.color_foreground, relief='flat', borderwidth=0) self.dialog.context_menu.add_command(label="Dateiname in Zwischenablage", command=lambda: self._copy_to_clipboard(os.path.basename(item_path))) self.dialog.context_menu.add_command( label="Pfad in Zwischenablage", command=lambda: self._copy_to_clipboard(item_path)) self.dialog.context_menu.add_separator() self.dialog.context_menu.add_command( label="Speicherort öffnen", command=lambda: self._open_file_location_from_context(item_path)) self.dialog.context_menu.tk_popup(event.x_root, event.y_root) return "break" def _open_file_location_from_context(self, file_path): directory = os.path.dirname(file_path) filename = os.path.basename(file_path) if self.dialog.search_mode: self.dialog.search_manager.hide_search_bar() self.dialog.navigation_manager.navigate_to(directory) self.dialog.after(100, lambda: self.dialog.view_manager._select_file_in_view(filename)) def on_rename_request(self, event, item_path=None, item_frame=None): if self.dialog.view_mode.get() == "list": if not self.dialog.tree.selection(): return item_id = self.dialog.tree.selection()[0] item_path = os.path.join( self.dialog.current_dir, self.dialog.tree.item(item_id, "text").strip()) self.start_rename(item_id, item_path) else: # icon view if item_path and item_frame: self.start_rename(item_frame, item_path) def start_rename(self, item_widget, item_path): if self.dialog.view_mode.get() == "icons": self._start_rename_icon_view(item_widget, item_path) else: # list view self._start_rename_list_view(item_widget) # item_widget is item_id def _start_rename_icon_view(self, item_frame, item_path): for child in item_frame.winfo_children(): child.destroy() entry = ttk.Entry(item_frame) entry.insert(0, os.path.basename(item_path)) entry.select_range(0, tk.END) entry.pack(fill="x", expand=True, padx=5, pady=5) entry.focus_set() def finish_rename(event): new_name = entry.get() new_path = os.path.join(self.dialog.current_dir, new_name) if new_name and new_path != item_path: if os.path.exists(new_path): self.dialog.widget_manager.search_status_label.config( text=f"'{new_name}' existiert bereits.") self.dialog.view_manager.populate_files( item_to_select=os.path.basename(item_path)) return try: os.rename(item_path, new_path) self.dialog.view_manager.populate_files(item_to_select=new_name) except Exception as e: self.dialog.widget_manager.search_status_label.config( text=f"Fehler beim Umbenennen: {e}") self.dialog.view_manager.populate_files() else: self.dialog.populate_files(item_to_select=os.path.basename(item_path)) def cancel_rename(event): self.dialog.view_manager.populate_files() entry.bind("", finish_rename) entry.bind("", finish_rename) entry.bind("", cancel_rename) def _start_rename_list_view(self, item_id): self.dialog.tree.see(item_id) self.dialog.tree.update_idletasks() bbox = self.dialog.tree.bbox(item_id, column="#0") if not bbox: return x, y, width, height = bbox entry = ttk.Entry(self.dialog.tree) entry_width = self.dialog.tree.column("#0", "width") entry.place(x=x, y=y, width=entry_width, height=height) item_text = self.dialog.tree.item(item_id, "text").strip() entry.insert(0, item_text) entry.select_range(0, tk.END) entry.focus_set() def finish_rename(event): new_name = entry.get() old_path = os.path.join(self.dialog.current_dir, item_text) new_path = os.path.join(self.dialog.current_dir, new_name) if new_name and new_path != old_path: if os.path.exists(new_path): self.dialog.widget_manager.search_status_label.config( text=f"'{new_name}' existiert bereits.") self.dialog.view_manager.populate_files(item_to_select=item_text) else: try: os.rename(old_path, new_path) self.dialog.view_manager.populate_files(item_to_select=new_name) except Exception as e: self.dialog.widget_manager.search_status_label.config( text=f"Fehler beim Umbenennen: {e}") self.dialog.view_manager.populate_files() else: self.dialog.populate_files(item_to_select=item_text) entry.destroy() def cancel_rename(event): entry.destroy() entry.bind("", finish_rename) entry.bind("", finish_rename) entry.bind("", cancel_rename)