From fb9a2dc68e26293f0a51d8c3dd609d9daead8023 Mon Sep 17 00:00:00 2001 From: Valentin Bernard Date: Sun, 14 Dec 2025 19:22:06 +0100 Subject: [PATCH 1/4] Join the "delete" and "download" menus in one. --- src/window.py | 100 ++++++++++++-------------------------------------- 1 file changed, 24 insertions(+), 76 deletions(-) diff --git a/src/window.py b/src/window.py index 12e34d8..cc07560 100644 --- a/src/window.py +++ b/src/window.py @@ -113,8 +113,7 @@ def __init__(self, **kwargs): self._setup_lang_chooser() lang_name = self.lang_chooser.get_selected_item().get_string() - self.lang_code = self.lang_map.get(lang_name, "en") - # print ('Sprachkodex am Beginn ', self.lang_code) + self.lang_code = self.lang_map.get(lang_name) def show_wait_dialog(self): self.wait_dialog = Gtk.Dialog( @@ -171,7 +170,7 @@ def _setup_lang_chooser(self): # Aktuelle Sprache auswählen lang_name = self.lang_chooser.get_selected_item().get_string() - self.lang_code = self.lang_map.get(lang_name, "en") + self.lang_code = self.lang_map.get(lang_name) self._update_voice_chooser(self.lang_code) # print ('gewählte Sprache ', lang_name) # Signal wieder verbinden @@ -179,20 +178,15 @@ def _setup_lang_chooser(self): def _on_lang_changed(self, dropdown, _): lang_name = self.lang_chooser.get_selected_item().get_string() - # print ('neue Sprache angeklickt', lang_name) - self.lang_code = self.lang_map.get(lang_name, "en") + self.lang_code = self.lang_map.get(lang_name) self._update_voice_chooser(self.lang_code) def _on_voice_changed(self, dropdown, _): selected = dropdown.get_selected() - model = dropdown.get_model() - # print ('$$$$$$$$$$$$$ in on voice changed ', model) - if selected == model.get_n_items() - 2: # vorletzte Zeile ausgewählt + n_items = dropdown.get_model().get_n_items() + if selected == n_items - 1: # letzte Zeile ausgewählt if self.lang_code != "eo": - self._show_voice_download_dialog() - elif selected == model.get_n_items() - 1: # letzte Zeile ausgewählt - if self.lang_code != "eo": - self._show_voice_delete_dialog() + self._show_voice_manage_dialog() def _update_voice_chooser(self, lang_code): """Aktualisiert die Dropdown-Auswahl""" @@ -206,13 +200,12 @@ def _update_voice_chooser(self, lang_code): # print ('Namen der Stimme voice[name] = ', voice['name']) if lang_code != "eo": # für Esperanto gibt es aktuell keine Stimmen - model.append(_("Download Voice…")) - model.append(_("Delete Voice…")) + model.append(_("Manage Voices…")) self.voice_chooser.set_model(model) self.voice_chooser.set_selected(0) # stellt Auswahlfenster auf die erste Zeile - def _show_voice_download_dialog(self): + def _show_voice_manage_dialog(self): dialog = Adw.Window( transient_for=self, modal=True, @@ -227,7 +220,7 @@ def _show_voice_download_dialog(self): # Custom HeaderBar ohne doppelte Titelleiste header_bar = Adw.HeaderBar() - title = Adw.WindowTitle(title=_("Download Voices")) + title = Adw.WindowTitle(title=_("Manage Voices")) header_bar.set_title_widget(title) main_box.append(header_bar) @@ -239,16 +232,28 @@ def _show_voice_download_dialog(self): available_voices = self._fetch_available_voices() installed_voices = self.voicemanager.get_installed_voices(self.lang_code) installed_ids = {v['id'] for v in installed_voices} - # Fortschrittsanzeigen Dictionary self.download_progress = {} for voice in available_voices: - if voice['id'] not in installed_ids: - row = Adw.ActionRow(title=voice['name'], + + row = Adw.ActionRow(title=voice['name'], margin_start=12, margin_end=12) + if voice['id'] in installed_ids: + + # Get the path + path = next(item["path"] for item in installed_voices if item["id"] == voice['id']) + print(path) + + # Löschen-Button + btn = Gtk.Button(label=_("Delete"), + css_classes=["suggested-action"]) + btn.connect('clicked', self._delete_voice, + voice['id'], path , dialog) + + else: # Fortschrittsbalken progress = Gtk.ProgressBar( show_text=True, @@ -262,68 +267,11 @@ def _show_voice_download_dialog(self): css_classes=["suggested-action"]) btn.connect('clicked', self._on_voice_selected, voice['id'], voice['model_url'], voice['config_url'], dialog) - - # Layout row.add_suffix(progress) - row.add_suffix(btn) - listbox.append(row) - - if listbox.get_first_child() is None: - row = Adw.ActionRow(_title="All voices are already installed") - listbox.append(row) - - scrolled.set_child(listbox) - main_box.append(scrolled) - dialog.set_content(main_box) - dialog.present() - - def _show_voice_delete_dialog(self): - dialog = Adw.Window( - transient_for=self, - modal=True, - title="", # Leerer Titel verhindert doppelte Anzeige - default_width=500, - default_height=300, - deletable=True # X-Button aktivieren - ) - - # Hauptcontainer mit HeaderBar - main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0) - - # Custom HeaderBar ohne doppelte Titelleiste - header_bar = Adw.HeaderBar() - title = Adw.WindowTitle(title=_("Remove Voices")) - header_bar.set_title_widget(title) - main_box.append(header_bar) - - # Scrollbereich für die Liste - scrolled = Gtk.ScrolledWindow(vexpand=True) - listbox = Gtk.ListBox(selection_mode=Gtk.SelectionMode.NONE) - - # installierte Stimmen anzeigen - installed_voices = self.voicemanager.get_installed_voices(self.lang_code) - installed_ids = {v['id'] for v in installed_voices} - - for voice in installed_voices: - row = Adw.ActionRow(title=voice['name'], - margin_start=12, - margin_end=12) - - # Löschen-Button - btn = Gtk.Button(label=_("Delete"), - css_classes=["suggested-action"]) - btn.connect('clicked', self._delete_voice, - voice['id'], voice['path'], dialog) - - # Layout row.add_suffix(btn) listbox.append(row) - if listbox.get_first_child() is None: - row = Adw.ActionRow(title=_("There are no installed voices for this language")) - listbox.append(row) - scrolled.set_child(listbox) main_box.append(scrolled) dialog.set_content(main_box) From c1ce496a7bc0498352bd88335a71a204582f7c80 Mon Sep 17 00:00:00 2001 From: Valentin Bernard Date: Sun, 14 Dec 2025 20:09:50 +0100 Subject: [PATCH 2/4] print remove --- src/window.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/window.py b/src/window.py index cc07560..94ad53a 100644 --- a/src/window.py +++ b/src/window.py @@ -245,7 +245,6 @@ def _show_voice_manage_dialog(self): # Get the path path = next(item["path"] for item in installed_voices if item["id"] == voice['id']) - print(path) # Löschen-Button btn = Gtk.Button(label=_("Delete"), From 9df8e44597cc41d6cf2824274f53872d7d84cb84 Mon Sep 17 00:00:00 2001 From: Valentin Bernard Date: Sun, 14 Dec 2025 20:13:32 +0100 Subject: [PATCH 3/4] WIP: UI file for the voice manager. --- src/voice_manager.ui | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/voice_manager.ui diff --git a/src/voice_manager.ui b/src/voice_manager.ui new file mode 100644 index 0000000..174fcf6 --- /dev/null +++ b/src/voice_manager.ui @@ -0,0 +1,44 @@ + + + + + + + 500 + 300 + true + true + + + + vertical + + + + + + + Manage Voices + + + + + + + + + true + + + + none + + + + + + + + + + From e44ea25bb3582f906e43709c7ffbc8c1f80c6e46 Mon Sep 17 00:00:00 2001 From: Valentin Bernard Date: Thu, 18 Dec 2025 19:03:03 +0100 Subject: [PATCH 4/4] Quotes --- src/window.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/window.py b/src/window.py index 94ad53a..ca901ce 100644 --- a/src/window.py +++ b/src/window.py @@ -244,7 +244,7 @@ def _show_voice_manage_dialog(self): if voice['id'] in installed_ids: # Get the path - path = next(item["path"] for item in installed_voices if item["id"] == voice['id']) + path = next(item['path'] for item in installed_voices if item['id'] == voice['id']) # Löschen-Button btn = Gtk.Button(label=_("Delete"),