From db84a6aaf8308665b4decf3235f53e42eaebc6f0 Mon Sep 17 00:00:00 2001 From: admin Date: Mon, 31 Aug 2026 17:07:45 +0000 Subject: [PATCH] v0.3.1: q/Escape beenden wieder, Rename-Crash und ".."-Aktionen gefixt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Screen-Bindings lösen Actions im Screen-Namespace auf. "quit" traf daher ins Leere, weil Screen.action_quit nicht existiert – die Taste wurde still verworfen. Bindings auf "app.quit" umgestellt (q im Browser, Escape im Verbindungsdialog). - RenameScreen._ok rief do_rename() auf sich selbst statt auf den darunter liegenden BrowserScreen (AttributeError). Reihenfolge korrigiert: erst pop_screen(), dann do_rename(). - RenameScreen mit Escape abbrechbar. - Neuer Helfer _selected_entry() blendet den ".."-Navigationseintrag aus. Download, Upload, Löschen und Umbenennen operierten sonst auf "↑ ..". --- ftptui/__init__.py | 2 +- ftptui/app.py | 26 +++++++++++++++++++------- pyproject.toml | 2 +- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/ftptui/__init__.py b/ftptui/__init__.py index 30cf32e..8861e2a 100644 --- a/ftptui/__init__.py +++ b/ftptui/__init__.py @@ -1,3 +1,3 @@ """ftptui - Interaktiver FTP/SFTP-Client als Terminal-User-Interface.""" -__version__ = "0.3.0" +__version__ = "0.3.1" diff --git a/ftptui/app.py b/ftptui/app.py index cb3a257..a4f952d 100644 --- a/ftptui/app.py +++ b/ftptui/app.py @@ -92,7 +92,7 @@ class FileTable(DataTable): class ConnectionScreen(Screen): """Startbildschirm zur Eingabe der Verbindungsdaten (Terminal-Look).""" - BINDINGS = [Binding("escape", "quit", "Beenden")] + BINDINGS = [Binding("escape", "app.quit", "Beenden")] def compose(self) -> ComposeResult: yield Header(show_clock=True) @@ -205,7 +205,7 @@ class BrowserScreen(Screen): """Total-Commander-artiger Datei-Browser zwischen lokal & entfernt.""" BINDINGS = [ - Binding("q", "quit", "Beenden"), + Binding("q", "app.quit", "Beenden"), Binding("enter", "open", "Öffnen"), Binding("tab", "focus_next", "Panele wechseln"), Binding("l", "download", "Herunterladen"), @@ -356,6 +356,13 @@ class BrowserScreen(Screen): cell = table.get_row_at(row)[0] return cell.plain if isinstance(cell, Text) else str(cell) + def _selected_entry(self, table: FileTable) -> str | None: + """Wie `_selected`, ignoriert aber den ``..``-Navigationseintrag.""" + sel = self._selected(table) + if not sel or sel.startswith("↑"): + return None + return sel + @on(DataTable.RowSelected, "#local_table") def _local_selected(self, event: DataTable.RowSelected) -> None: self._open("local") @@ -404,7 +411,7 @@ class BrowserScreen(Screen): self._update_info() def action_download(self) -> None: - sel = self._selected(self.table_remote) + sel = self._selected_entry(self.table_remote) if not sel: return name = sel[:-1] if sel.endswith("/") else sel @@ -420,7 +427,7 @@ class BrowserScreen(Screen): self._refresh_local() def action_upload(self) -> None: - sel = self._selected(self.table_local) + sel = self._selected_entry(self.table_local) if not sel: return name = sel[:-1] if sel.endswith("/") else sel @@ -479,7 +486,7 @@ class BrowserScreen(Screen): def action_delete(self) -> None: table = self._focused_table() - sel = self._selected(table) + sel = self._selected_entry(table) if not sel: return remote = table is not self.table_local @@ -504,7 +511,7 @@ class BrowserScreen(Screen): def action_rename(self) -> None: table = self._focused_table() - sel = self._selected(table) + sel = self._selected_entry(table) if not sel: return self._rename_target = sel @@ -535,6 +542,11 @@ class BrowserScreen(Screen): class RenameScreen(Screen): """Eingabebildschirm zum Umbenennen.""" + BINDINGS = [Binding("escape", "cancel", "Abbrechen")] + + def action_cancel(self) -> None: + self.app.pop_screen() + def compose(self) -> ComposeResult: yield Static("Neuer Name:", classes="field") yield Input(id="newname", placeholder="neuer-name", classes="input") @@ -547,8 +559,8 @@ class RenameScreen(Screen): @on(Button.Pressed, "#ok") def _ok(self) -> None: name = self.query_one("#newname", Input).value.strip() - self.app.screen.do_rename(name if name else "unbenannt") self.app.pop_screen() + self.app.screen.do_rename(name if name else "unbenannt") @on(Button.Pressed, "#cancel") def _cancel(self) -> None: diff --git a/pyproject.toml b/pyproject.toml index 7ffaab1..f72162c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "ftptui" -version = "0.3.0" +version = "0.3.1" description = "Interaktiver FTP/SFTP-Client als Terminal-User-Interface in Python" readme = "README.md" requires-python = ">=3.10"