From 3dfc2288a5e0bb2093e2e762d54ec498bc580b1a Mon Sep 17 00:00:00 2001 From: Jann Stute Date: Wed, 12 Nov 2025 14:17:02 +0100 Subject: [PATCH 1/2] fix: prevent deadlock when wanted mnemonics conflict --- src/tagstudio/qt/mnemonics.py | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/tagstudio/qt/mnemonics.py b/src/tagstudio/qt/mnemonics.py index d7fd44b68..a5f13bda4 100644 --- a/src/tagstudio/qt/mnemonics.py +++ b/src/tagstudio/qt/mnemonics.py @@ -1,10 +1,13 @@ # Licensed under the GPL-3.0 License. # Created for TagStudio: https://github.com/CyanVoxel/TagStudio +import re - +import structlog from PySide6.QtGui import QAction from PySide6.QtWidgets import QMenu +logger = structlog.get_logger(__name__) + def remove_mnemonic_marker(label: str) -> str: """Remove existing accelerator markers (&) from a label.""" @@ -25,6 +28,31 @@ def remove_mnemonic_marker(label: str) -> str: return result +def get_wanted_mnemonics(text: str) -> list[str]: + matches = re.findall("(?:^|[^&])&([^&])", text) + return matches + + +def sanitise_mnemonics(actions: list[QAction]) -> None: + previous = [] + for action in actions: + text = action.text() + m = get_wanted_mnemonics(text) + + if len(m) == 0: + continue + elif len(m) > 1: + logger.warning("Found multiple wanted mnemonics, removing all", text=text) + action.setText(remove_mnemonic_marker(text)) + continue + elif m[0] in previous: + logger.warning("Removing conflicting mnemonic", text=text) + action.setText(remove_mnemonic_marker(text)) + continue + + previous.append(m[0]) + + # Additional weight for first character in string FIRST_CHARACTER_EXTRA_WEIGHT = 50 # Additional weight for the beginning of a word @@ -97,6 +125,9 @@ def assign_mnemonics(menu: QMenu): # Collect actions actions = [a for a in menu.actions() if not a.isSeparator()] + # sanitise mnemonics to prevent deadlocks + sanitise_mnemonics(actions) + # Sequence map: mnemonic key -> QAction sequence_to_action: dict[str, QAction] = {} From bf832d7d550fb37b1139cdfb20c14eb5835d9f35 Mon Sep 17 00:00:00 2001 From: Jann Stute Date: Wed, 12 Nov 2025 14:34:02 +0100 Subject: [PATCH 2/2] fix: remove invalid mnemonics from translations --- src/tagstudio/resources/translations/es.json | 2 +- src/tagstudio/resources/translations/hu.json | 4 ++-- src/tagstudio/resources/translations/it.json | 2 +- src/tagstudio/resources/translations/nb_NO.json | 4 ++-- src/tagstudio/resources/translations/pl.json | 4 ++-- src/tagstudio/resources/translations/pt.json | 2 +- src/tagstudio/resources/translations/pt_BR.json | 2 +- src/tagstudio/resources/translations/ru.json | 2 +- src/tagstudio/resources/translations/ta.json | 4 ++-- src/tagstudio/resources/translations/tr.json | 2 +- 10 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/tagstudio/resources/translations/es.json b/src/tagstudio/resources/translations/es.json index d162b9500..0f056d3ad 100644 --- a/src/tagstudio/resources/translations/es.json +++ b/src/tagstudio/resources/translations/es.json @@ -223,7 +223,7 @@ "menu.file.open_create_library": "&Abrir/Crear biblioteca", "menu.file.open_library": "Abrir biblioteca", "menu.file.open_recent_library": "Abrir reciente", - "menu.file.refresh_directories": "&Actualizar directorios", + "menu.file.refresh_directories": "Actualizar directorios", "menu.file.save_backup": "&Guardar copia de seguridad de la biblioteca", "menu.file.save_library": "Guardar biblioteca", "menu.help": "&Ayuda", diff --git a/src/tagstudio/resources/translations/hu.json b/src/tagstudio/resources/translations/hu.json index 3241641e7..849e0ed6b 100644 --- a/src/tagstudio/resources/translations/hu.json +++ b/src/tagstudio/resources/translations/hu.json @@ -33,7 +33,7 @@ "drop_import.progress.window_title": "Fájlok importálása", "drop_import.title": "Fájlütközés", "edit.color_manager": "&Színek kezelése", - "edit.copy_fields": "Mezők &másolása", + "edit.copy_fields": "Mezők másolása", "edit.paste_fields": "Mezők &beillesztése", "edit.tag_manager": "Címkék kezelése", "entries.duplicate.merge": "Egyező elemek &egyesítése", @@ -211,7 +211,7 @@ "menu.delete_selected_files_singular": "Fájl {trash_term} &helyezése", "menu.edit": "S&zerkesztés", "menu.edit.ignore_files": "Fájlok és mappák figyelmen kívül hagyása", - "menu.edit.manage_tags": "&Címkék ke&zelése", + "menu.edit.manage_tags": "Címkék kezelése", "menu.edit.new_tag": "Ú&j címke", "menu.file": "&Fájl", "menu.file.clear_recent_libraries": "&Legutóbbi könyvtárak listájának törlése", diff --git a/src/tagstudio/resources/translations/it.json b/src/tagstudio/resources/translations/it.json index af4d82386..8c6d6b8ef 100644 --- a/src/tagstudio/resources/translations/it.json +++ b/src/tagstudio/resources/translations/it.json @@ -220,7 +220,7 @@ "menu.file.open_create_library": "&Apri/Crea Biblioteca", "menu.file.open_library": "Apri Biblioteca", "menu.file.open_recent_library": "Apri Recenti", - "menu.file.refresh_directories": "&Aggiorna Cartelle", + "menu.file.refresh_directories": "Aggiorna Cartelle", "menu.file.save_backup": "&Salva Backup della Biblioteca", "menu.file.save_library": "Salva Biblioteca", "menu.help": "&Aiuto", diff --git a/src/tagstudio/resources/translations/nb_NO.json b/src/tagstudio/resources/translations/nb_NO.json index 35a6f1064..b4fdab36b 100644 --- a/src/tagstudio/resources/translations/nb_NO.json +++ b/src/tagstudio/resources/translations/nb_NO.json @@ -195,7 +195,7 @@ "menu.edit.new_tag": "Ny &Etikett", "menu.file": "Fil", "menu.file.clear_recent_libraries": "Fjern Nylige", - "menu.file.close_library": "&Lukk Bibliotek", + "menu.file.close_library": "Lukk Bibliotek", "menu.file.missing_library.message": "Plasseringen til biblioteket \"{library}\" kan ikke finnes.", "menu.file.missing_library.title": "Manglende Bibliotek", "menu.file.new_library": "Nytt Bibliotek", @@ -212,7 +212,7 @@ "menu.select": "Velg", "menu.settings": "Innstillinger...", "menu.tools": "Verktøy", - "menu.tools.fix_duplicate_files": "Fiks Duplikate &Filer", + "menu.tools.fix_duplicate_files": "Fiks Duplikate Filer", "menu.tools.fix_unlinked_entries": "Fiks &Frakoblede Oppføringer", "menu.view": "&Se", "menu.window": "Vindu", diff --git a/src/tagstudio/resources/translations/pl.json b/src/tagstudio/resources/translations/pl.json index c83c72eaf..854bacf45 100644 --- a/src/tagstudio/resources/translations/pl.json +++ b/src/tagstudio/resources/translations/pl.json @@ -181,14 +181,14 @@ "menu.edit.new_tag": "Nowy &Tag", "menu.file": "&Plik", "menu.file.clear_recent_libraries": "Wyczyść ostatnie", - "menu.file.close_library": "&Zamknij bibliotekę", + "menu.file.close_library": "Zamknij bibliotekę", "menu.file.missing_library.message": "Lokalizacja biblioteki \"{library}\" nie została odnaleziona.", "menu.file.missing_library.title": "Brakująca biblioteka", "menu.file.new_library": "Nowa biblioteka", "menu.file.open_create_library": "&Otwórz/Stwórz bibliotekę", "menu.file.open_library": "Otwórz bibliotekę", "menu.file.open_recent_library": "Otwórz ostatnie", - "menu.file.refresh_directories": "&Odśwież katalogi", + "menu.file.refresh_directories": "Odśwież katalogi", "menu.file.save_backup": "&Zapisz kopię zapasową biblioteki", "menu.file.save_library": "Zapisz bibliotekę", "menu.help": "&Pomoc", diff --git a/src/tagstudio/resources/translations/pt.json b/src/tagstudio/resources/translations/pt.json index cbd27f3a0..c5b3960f9 100644 --- a/src/tagstudio/resources/translations/pt.json +++ b/src/tagstudio/resources/translations/pt.json @@ -181,7 +181,7 @@ "menu.file.open_create_library": "&Abrir/Criar Biblioteca", "menu.file.open_library": "Abrir Biblioteca", "menu.file.open_recent_library": "Abrir Recente", - "menu.file.refresh_directories": "&Atualizar Pastas", + "menu.file.refresh_directories": "Atualizar Pastas", "menu.file.save_backup": "&Gravar Backup da Biblioteca", "menu.file.save_library": "Gravar Biblioteca", "menu.help": "&Ajuda", diff --git a/src/tagstudio/resources/translations/pt_BR.json b/src/tagstudio/resources/translations/pt_BR.json index 41ed96df6..3c548bd9b 100644 --- a/src/tagstudio/resources/translations/pt_BR.json +++ b/src/tagstudio/resources/translations/pt_BR.json @@ -174,7 +174,7 @@ "menu.file.open_create_library": "&Abrir/Criar Biblioteca", "menu.file.open_library": "Abrir Biblioteca", "menu.file.open_recent_library": "Abrir Recente", - "menu.file.refresh_directories": "&Atualizar Pastas", + "menu.file.refresh_directories": "Atualizar Pastas", "menu.file.save_backup": "&Salvar Backup da Biblioteca", "menu.file.save_library": "Salvar Biblioteca", "menu.help": "&Ajuda", diff --git a/src/tagstudio/resources/translations/ru.json b/src/tagstudio/resources/translations/ru.json index 9fa1e9615..55158add7 100644 --- a/src/tagstudio/resources/translations/ru.json +++ b/src/tagstudio/resources/translations/ru.json @@ -195,7 +195,7 @@ "menu.file.open_create_library": "&Открыть/создать библиотеку", "menu.file.open_library": "Открыть библиотеку", "menu.file.open_recent_library": "Открыть последнюю", - "menu.file.refresh_directories": "&Обновить папки", + "menu.file.refresh_directories": "Обновить папки", "menu.file.save_backup": "&Сохранить резервную копию библиотеки", "menu.file.save_library": "Сохранить библиотеку", "menu.help": "&Помощь", diff --git a/src/tagstudio/resources/translations/ta.json b/src/tagstudio/resources/translations/ta.json index 6b57600b3..662aaefb9 100644 --- a/src/tagstudio/resources/translations/ta.json +++ b/src/tagstudio/resources/translations/ta.json @@ -187,7 +187,7 @@ "menu.edit.new_tag": "புதிய & குறிச்சொல்", "menu.file": "கோப்பு (&f)", "menu.file.clear_recent_libraries": "சமீபத்தியதை அழிக்கவும்", - "menu.file.close_library": "& நூலகம் மூடு", + "menu.file.close_library": " நூலகம் மூடு", "menu.file.missing_library.message": "\"{library}\" நூலகத்தின் இருப்பிடத்தைக் கண்டுபிடிக்க முடியாது.", "menu.file.missing_library.title": "நூலகம் இல்லை", "menu.file.new_library": "புதிய நூலகம்", @@ -195,7 +195,7 @@ "menu.file.open_library": "திறந்த நூலகம்", "menu.file.open_recent_library": "அண்மைக் கால திறப்பு", "menu.file.refresh_directories": "கோப்பகத்தை புதுப்பிக்கவும்", - "menu.file.save_backup": "& நூலக காப்புப்பிரதியை சேமிக்கவும்", + "menu.file.save_backup": " நூலக காப்புப்பிரதியை சேமிக்கவும்", "menu.file.save_library": "நூலகத்தை சேமிக்கவும்", "menu.help": "உதவி (&h)", "menu.help.about": "பற்றி", diff --git a/src/tagstudio/resources/translations/tr.json b/src/tagstudio/resources/translations/tr.json index 14f1834f5..ef69546d0 100644 --- a/src/tagstudio/resources/translations/tr.json +++ b/src/tagstudio/resources/translations/tr.json @@ -182,7 +182,7 @@ "menu.edit.new_tag": "Yeni &Etiket", "menu.file": "&Dosya", "menu.file.clear_recent_libraries": "Yakın Geçmişi Temizle", - "menu.file.close_library": "Kütüphaneyi &Kapat", + "menu.file.close_library": "Kütüphaneyi Kapat", "menu.file.new_library": "Yeni Kütüphane", "menu.file.open_create_library": "Kütüphane &Aç/Oluştur", "menu.file.open_library": "Kütüphane Aç",