Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions src/voice_manager.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk" version="4.0"/>
<requires lib="adwaita" version="1"/>

<object class="AdwWindow" id="dialog">
<property name="default-width">500</property>
<property name="default-height">300</property>
<property name="modal">true</property>
<property name="deletable">true</property>

<child>
<object class="GtkBox" id="main_box">
<property name="orientation">vertical</property>

<!-- HeaderBar -->
<child>
<object class="AdwHeaderBar">
<child>
<object class="AdwWindowTitle">
<property name="title" translatable="yes">Manage Voices</property>
</object>
</child>
</object>
</child>

<!-- Scrolled list -->
<child>
<object class="GtkScrolledWindow">
<property name="vexpand">true</property>

<child>
<object class="GtkListBox" id="voice_list">
<property name="selection-mode">none</property>
</object>
</child>

</object>
</child>

</object>
</child>
</object>
</interface>
99 changes: 23 additions & 76 deletions src/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -171,28 +170,23 @@ 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
self.lang_chooser.connect("notify::selected", self._on_lang_changed)

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"""
Expand All @@ -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,
Expand All @@ -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)

Expand All @@ -239,16 +232,27 @@ 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'])

# 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,
Expand All @@ -262,68 +266,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)
Expand Down