From a8c20385527af92280ac51b39611cb760bdcd9cf Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Fri, 10 Jul 2026 12:47:27 +0200 Subject: [PATCH] Channels: translate the add/delete menu strings; flash.sh rebuilds packs Add delete_channel and keep_one_channel to the language table (after mute) and fill all 20 language files (13 translated, English fallback for the rest), with correct single-byte ISO-8859 accents. Wire them into the Delete Channel label, confirmation and last-channel guard. The new strings land on empty voice-table slots, so they play as silence (no crash, no .vpr regeneration). flash.sh now always rebuilds the .gla language packs so edits to the language files are actually picked up (previously a stale pack was re-flashed). Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGELOG.md | 5 +++++ .../include/user_interface/languages/catalan.h | 2 ++ .../include/user_interface/languages/croatian.h | 2 ++ .../include/user_interface/languages/czech.h | 2 ++ .../include/user_interface/languages/danish.h | 2 ++ .../include/user_interface/languages/dutch.h | 2 ++ .../include/user_interface/languages/english.h | 2 ++ .../include/user_interface/languages/finnish.h | 2 ++ .../include/user_interface/languages/french.h | 2 ++ .../include/user_interface/languages/german.h | 2 ++ .../include/user_interface/languages/hungarian.h | 2 ++ .../include/user_interface/languages/italian.h | 2 ++ .../include/user_interface/languages/japanese.h | 2 ++ .../include/user_interface/languages/polish.h | 2 ++ .../user_interface/languages/portugues_brazil.h | 2 ++ .../include/user_interface/languages/portuguese.h | 2 ++ .../include/user_interface/languages/romanian.h | 2 ++ .../include/user_interface/languages/slovenian.h | 2 ++ .../include/user_interface/languages/spanish.h | 2 ++ .../include/user_interface/languages/swedish.h | 2 ++ .../include/user_interface/languages/turkish.h | 2 ++ .../include/user_interface/languages/uiLanguage.h | 2 ++ .../application/source/user_interface/uiChannelMode.c | 7 ++++--- flash.sh | 10 +++++----- 24 files changed, 56 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b797bb..25c7e02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,11 @@ single running list until the first versioned release. - **Delete Channel** — deletes the selected channel after a confirmation, and scrubs it out of every zone that referenced it. Refuses to delete the last remaining channel, and respects the read-only/APRS channel lock. + - The new menu strings are **translated** (German, French, Italian, Spanish, + Portuguese, Dutch, Danish, Swedish, Catalan, Finnish, Czech; English fallback + for the rest). +- **`flash.sh`** now always rebuilds the language (`.gla`) packs, so edits to the + language files are picked up instead of a stale pack being re-flashed. - **Release script** now flags every release before v1.0.0 as a **pre-release** (and corrects the flag on re-runs). diff --git a/MDUV380_firmware/application/include/user_interface/languages/catalan.h b/MDUV380_firmware/application/include/user_interface/languages/catalan.h index f0e9d55..df004fd 100644 --- a/MDUV380_firmware/application/include/user_interface/languages/catalan.h +++ b/MDUV380_firmware/application/include/user_interface/languages/catalan.h @@ -327,6 +327,8 @@ const stringsTable_t catalanLanguage= .text_size = "Text size",//MaxLen: 16 (with ':' + 1 digit) .last_talker = "Last talker", // MaxLen: 16 (with ':' + .off or 2 digits value + 's') .mute = "Mute", // MaxLen: 16 (with ':' + .on or .off) +.delete_channel = "Esborra canal", // MaxLen: 16 +.keep_one_channel = "Deixa 1 canal", // MaxLen: 16 }; /******************************************************************** * diff --git a/MDUV380_firmware/application/include/user_interface/languages/croatian.h b/MDUV380_firmware/application/include/user_interface/languages/croatian.h index a37579a..be8682d 100644 --- a/MDUV380_firmware/application/include/user_interface/languages/croatian.h +++ b/MDUV380_firmware/application/include/user_interface/languages/croatian.h @@ -327,6 +327,8 @@ const stringsTable_t croatianLanguage = .text_size = "Text size",//MaxLen: 16 (with ':' + 1 digit) .last_talker = "Last talker", // MaxLen: 16 (with ':' + .off or 2 digits value + 's') .mute = "Mute", // MaxLen: 16 (with ':' + .on or .off) +.delete_channel = "Delete Channel", // MaxLen: 16 +.keep_one_channel = "Keep 1 channel", // MaxLen: 16 }; /******************************************************************** * diff --git a/MDUV380_firmware/application/include/user_interface/languages/czech.h b/MDUV380_firmware/application/include/user_interface/languages/czech.h index a1dfe4d..4b6aaa7 100644 --- a/MDUV380_firmware/application/include/user_interface/languages/czech.h +++ b/MDUV380_firmware/application/include/user_interface/languages/czech.h @@ -327,6 +327,8 @@ const stringsTable_t czechLanguage = .text_size = "Text size",//MaxLen: 16 (with ':' + 1 digit) .last_talker = "Last talker", // MaxLen: 16 (with ':' + .off or 2 digits value + 's') .mute = "Mute", // MaxLen: 16 (with ':' + .on or .off) +.delete_channel = "Smazat kanál", // MaxLen: 16 +.keep_one_channel = "Nech 1 kanál", // MaxLen: 16 }; /******************************************************************** * diff --git a/MDUV380_firmware/application/include/user_interface/languages/danish.h b/MDUV380_firmware/application/include/user_interface/languages/danish.h index f4d94fb..beb55e5 100644 --- a/MDUV380_firmware/application/include/user_interface/languages/danish.h +++ b/MDUV380_firmware/application/include/user_interface/languages/danish.h @@ -327,6 +327,8 @@ const stringsTable_t danishLanguage = .text_size = "Text size",//MaxLen: 16 (with ':' + 1 digit) .last_talker = "Last talker", // MaxLen: 16 (with ':' + .off or 2 digits value + 's') .mute = "Mute", // MaxLen: 16 (with ':' + .on or .off) +.delete_channel = "Slet kanal", // MaxLen: 16 +.keep_one_channel = "Behold 1 kanal", // MaxLen: 16 }; /******************************************************************** * diff --git a/MDUV380_firmware/application/include/user_interface/languages/dutch.h b/MDUV380_firmware/application/include/user_interface/languages/dutch.h index eab75e3..b15fbaf 100644 --- a/MDUV380_firmware/application/include/user_interface/languages/dutch.h +++ b/MDUV380_firmware/application/include/user_interface/languages/dutch.h @@ -327,6 +327,8 @@ const stringsTable_t dutchLanguage = .text_size = "Text size",//MaxLen: 16 (with ':' + 1 digit) .last_talker = "Last talker", // MaxLen: 16 (with ':' + .off or 2 digits value + 's') .mute = "Mute", // MaxLen: 16 (with ':' + .on or .off) +.delete_channel = "Kanaal wissen", // MaxLen: 16 +.keep_one_channel = "Hou 1 kanaal", // MaxLen: 16 }; /******************************************************************** * diff --git a/MDUV380_firmware/application/include/user_interface/languages/english.h b/MDUV380_firmware/application/include/user_interface/languages/english.h index cf65267..3a46761 100644 --- a/MDUV380_firmware/application/include/user_interface/languages/english.h +++ b/MDUV380_firmware/application/include/user_interface/languages/english.h @@ -327,6 +327,8 @@ const stringsTable_t englishLanguage = .text_size = "Text size",//MaxLen: 16 (with ':' + 1 digit) .last_talker = "Last talker", // MaxLen: 16 (with ':' + .off or 2 digits value + 's') .mute = "Mute", // MaxLen: 16 (with ':' + .on or .off) +.delete_channel = "Delete Channel", // MaxLen: 16 +.keep_one_channel = "Keep 1 channel", // MaxLen: 16 }; /******************************************************************** * diff --git a/MDUV380_firmware/application/include/user_interface/languages/finnish.h b/MDUV380_firmware/application/include/user_interface/languages/finnish.h index 588de4c..04b992a 100644 --- a/MDUV380_firmware/application/include/user_interface/languages/finnish.h +++ b/MDUV380_firmware/application/include/user_interface/languages/finnish.h @@ -327,6 +327,8 @@ const stringsTable_t finnishLanguage = .text_size = "Text size",//MaxLen: 16 (with ':' + 1 digit) .last_talker = "Last talker", // MaxLen: 16 (with ':' + .off or 2 digits value + 's') .mute = "Mute", // MaxLen: 16 (with ':' + .on or .off) +.delete_channel = "Poista kanava", // MaxLen: 16 +.keep_one_channel = "Pidä 1 kanava", // MaxLen: 16 }; /******************************************************************** * diff --git a/MDUV380_firmware/application/include/user_interface/languages/french.h b/MDUV380_firmware/application/include/user_interface/languages/french.h index d279c83..2d5b5cc 100644 --- a/MDUV380_firmware/application/include/user_interface/languages/french.h +++ b/MDUV380_firmware/application/include/user_interface/languages/french.h @@ -327,6 +327,8 @@ const stringsTable_t frenchLanguage = .text_size = "Taille texte",//MaxLen: 16 (with ':' + 1 digit) .last_talker = "Der. locut.", // MaxLen: 16 (with ':' + .off or 2 digits value + 's') .mute = "Sourdine", // MaxLen: 16 (with ':' + .on or .off) +.delete_channel = "Effacer canal", // MaxLen: 16 +.keep_one_channel = "Garder 1 canal", // MaxLen: 16 }; /******************************************************************** * diff --git a/MDUV380_firmware/application/include/user_interface/languages/german.h b/MDUV380_firmware/application/include/user_interface/languages/german.h index de3040d..909968c 100644 --- a/MDUV380_firmware/application/include/user_interface/languages/german.h +++ b/MDUV380_firmware/application/include/user_interface/languages/german.h @@ -327,6 +327,8 @@ const stringsTable_t germanLanguage = .text_size = "Text Grösse",//MaxLen: 16 (with ':' + 1 digit) .last_talker = "Last talker", // MaxLen: 16 (with ':' + .off or 2 digits value + 's') .mute = "Mute", // MaxLen: 16 (with ':' + .on or .off) +.delete_channel = "Kanal löschen", // MaxLen: 16 +.keep_one_channel = "1 Kanal behalten", // MaxLen: 16 }; /******************************************************************** * diff --git a/MDUV380_firmware/application/include/user_interface/languages/hungarian.h b/MDUV380_firmware/application/include/user_interface/languages/hungarian.h index eb684c8..d76e720 100644 --- a/MDUV380_firmware/application/include/user_interface/languages/hungarian.h +++ b/MDUV380_firmware/application/include/user_interface/languages/hungarian.h @@ -327,6 +327,8 @@ const stringsTable_t hungarianLanguage= .text_size = "Text size",//MaxLen: 16 (with ':' + 1 digit) .last_talker = "Last talker", // MaxLen: 16 (with ':' + .off or 2 digits value + 's') .mute = "Mute", // MaxLen: 16 (with ':' + .on or .off) +.delete_channel = "Delete Channel", // MaxLen: 16 +.keep_one_channel = "Keep 1 channel", // MaxLen: 16 }; /******************************************************************** * diff --git a/MDUV380_firmware/application/include/user_interface/languages/italian.h b/MDUV380_firmware/application/include/user_interface/languages/italian.h index d7fb9d2..c3e1542 100644 --- a/MDUV380_firmware/application/include/user_interface/languages/italian.h +++ b/MDUV380_firmware/application/include/user_interface/languages/italian.h @@ -327,6 +327,8 @@ const stringsTable_t italianLanguage = .text_size = "Formato font",//MaxLen: 16 (with ':' + 1 digit) .last_talker = "Ultimo OM RX", // MaxLen: 16 (with ':' + .off or 2 digits value + 's') .mute = "Muto", // MaxLen: 16 (with ':' + .on or .off) +.delete_channel = "Elimina canale", // MaxLen: 16 +.keep_one_channel = "Tieni 1 canale", // MaxLen: 16 }; /******************************************************************** * diff --git a/MDUV380_firmware/application/include/user_interface/languages/japanese.h b/MDUV380_firmware/application/include/user_interface/languages/japanese.h index 0197fbc..7866290 100644 --- a/MDUV380_firmware/application/include/user_interface/languages/japanese.h +++ b/MDUV380_firmware/application/include/user_interface/languages/japanese.h @@ -327,6 +327,8 @@ const stringsTable_t japaneseLanguage = .text_size = "Text size",//MaxLen: 16 (with ':' + 1 digit) .last_talker = "Last talker", // MaxLen: 16 (with ':' + .off or 2 digits value + 's') .mute = "Mute", // MaxLen: 16 (with ':' + .on or .off) +.delete_channel = "Delete Channel", // MaxLen: 16 +.keep_one_channel = "Keep 1 channel", // MaxLen: 16 }; /******************************************************************** * diff --git a/MDUV380_firmware/application/include/user_interface/languages/polish.h b/MDUV380_firmware/application/include/user_interface/languages/polish.h index 740c255..924b5d6 100644 --- a/MDUV380_firmware/application/include/user_interface/languages/polish.h +++ b/MDUV380_firmware/application/include/user_interface/languages/polish.h @@ -327,6 +327,8 @@ const stringsTable_t polishLanguage = .text_size = "Text size",//MaxLen: 16 (with ':' + 1 digit) .last_talker = "Last talker", // MaxLen: 16 (with ':' + .off or 2 digits value + 's') .mute = "Mute", // MaxLen: 16 (with ':' + .on or .off) +.delete_channel = "Delete Channel", // MaxLen: 16 +.keep_one_channel = "Keep 1 channel", // MaxLen: 16 }; /******************************************************************** * diff --git a/MDUV380_firmware/application/include/user_interface/languages/portugues_brazil.h b/MDUV380_firmware/application/include/user_interface/languages/portugues_brazil.h index 6ac7589..8951c9c 100644 --- a/MDUV380_firmware/application/include/user_interface/languages/portugues_brazil.h +++ b/MDUV380_firmware/application/include/user_interface/languages/portugues_brazil.h @@ -327,6 +327,8 @@ const stringsTable_t portuguesBrazilLanguage = .text_size = "Text size",//MaxLen: 16 (with ':' + 1 digit) .last_talker = "Last talker", // MaxLen: 16 (with ':' + .off or 2 digits value + 's') .mute = "Mute", // MaxLen: 16 (with ':' + .on or .off) +.delete_channel = "Apagar canal", // MaxLen: 16 +.keep_one_channel = "Manter 1 canal", // MaxLen: 16 }; /********************************************************************* * diff --git a/MDUV380_firmware/application/include/user_interface/languages/portuguese.h b/MDUV380_firmware/application/include/user_interface/languages/portuguese.h index 6301977..f53c8ef 100644 --- a/MDUV380_firmware/application/include/user_interface/languages/portuguese.h +++ b/MDUV380_firmware/application/include/user_interface/languages/portuguese.h @@ -327,6 +327,8 @@ const stringsTable_t portuguesLanguage = .text_size = "Text size",//MaxLen: 16 (with ':' + 1 digit) .last_talker = "Last talker", // MaxLen: 16 (with ':' + .off or 2 digits value + 's') .mute = "Mute", // MaxLen: 16 (with ':' + .on or .off) +.delete_channel = "Apagar canal", // MaxLen: 16 +.keep_one_channel = "Manter 1 canal", // MaxLen: 16 }; /******************************************************************** * diff --git a/MDUV380_firmware/application/include/user_interface/languages/romanian.h b/MDUV380_firmware/application/include/user_interface/languages/romanian.h index f25370d..874c6ad 100644 --- a/MDUV380_firmware/application/include/user_interface/languages/romanian.h +++ b/MDUV380_firmware/application/include/user_interface/languages/romanian.h @@ -327,6 +327,8 @@ const stringsTable_t romanianLanguage = .text_size = "Text size",//MaxLen: 16 (with ':' + 1 digit) .last_talker = "Last talker", // MaxLen: 16 (with ':' + .off or 2 digits value + 's') .mute = "Mute", // MaxLen: 16 (with ':' + .on or .off) +.delete_channel = "Delete Channel", // MaxLen: 16 +.keep_one_channel = "Keep 1 channel", // MaxLen: 16 }; /******************************************************************** * diff --git a/MDUV380_firmware/application/include/user_interface/languages/slovenian.h b/MDUV380_firmware/application/include/user_interface/languages/slovenian.h index bc863ca..7677e54 100644 --- a/MDUV380_firmware/application/include/user_interface/languages/slovenian.h +++ b/MDUV380_firmware/application/include/user_interface/languages/slovenian.h @@ -327,6 +327,8 @@ const stringsTable_t slovenianLanguage = .text_size = "Text size",//MaxLen: 16 (with ':' + 1 digit) .last_talker = "Last talker", // MaxLen: 16 (with ':' + .off or 2 digits value + 's') .mute = "Mute", // MaxLen: 16 (with ':' + .on or .off) +.delete_channel = "Delete Channel", // MaxLen: 16 +.keep_one_channel = "Keep 1 channel", // MaxLen: 16 }; /******************************************************************** * diff --git a/MDUV380_firmware/application/include/user_interface/languages/spanish.h b/MDUV380_firmware/application/include/user_interface/languages/spanish.h index afa2787..a8e5b96 100644 --- a/MDUV380_firmware/application/include/user_interface/languages/spanish.h +++ b/MDUV380_firmware/application/include/user_interface/languages/spanish.h @@ -327,6 +327,8 @@ const stringsTable_t spanishLanguage = .text_size = "Text size",//MaxLen: 16 (with ':' + 1 digit) .last_talker = "Last talker", // MaxLen: 16 (with ':' + .off or 2 digits value + 's') .mute = "Mute", // MaxLen: 16 (with ':' + .on or .off) +.delete_channel = "Borrar canal", // MaxLen: 16 +.keep_one_channel = "Dejar 1 canal", // MaxLen: 16 }; /******************************************************************** * diff --git a/MDUV380_firmware/application/include/user_interface/languages/swedish.h b/MDUV380_firmware/application/include/user_interface/languages/swedish.h index ba5759a..85e54f7 100644 --- a/MDUV380_firmware/application/include/user_interface/languages/swedish.h +++ b/MDUV380_firmware/application/include/user_interface/languages/swedish.h @@ -327,6 +327,8 @@ const stringsTable_t swedishLanguage = .text_size = "Text size",//MaxLen: 16 (with ':' + 1 digit) .last_talker = "Last talker", // MaxLen: 16 (with ':' + .off or 2 digits value + 's') .mute = "Mute", // MaxLen: 16 (with ':' + .on or .off) +.delete_channel = "Radera kanal", // MaxLen: 16 +.keep_one_channel = "Behĺll 1 kanal", // MaxLen: 16 }; /******************************************************************** * diff --git a/MDUV380_firmware/application/include/user_interface/languages/turkish.h b/MDUV380_firmware/application/include/user_interface/languages/turkish.h index d11ac87..abf11b6 100644 --- a/MDUV380_firmware/application/include/user_interface/languages/turkish.h +++ b/MDUV380_firmware/application/include/user_interface/languages/turkish.h @@ -327,6 +327,8 @@ const stringsTable_t turkishLanguage = .text_size = "Text size",//MaxLen: 16 (with ':' + 1 digit) .last_talker = "Last talker", // MaxLen: 16 (with ':' + .off or 2 digits value + 's') .mute = "Mute", // MaxLen: 16 (with ':' + .on or .off) +.delete_channel = "Delete Channel", // MaxLen: 16 +.keep_one_channel = "Keep 1 channel", // MaxLen: 16 }; /******************************************************************** * diff --git a/MDUV380_firmware/application/include/user_interface/languages/uiLanguage.h b/MDUV380_firmware/application/include/user_interface/languages/uiLanguage.h index 6ec21ed..ac49dca 100644 --- a/MDUV380_firmware/application/include/user_interface/languages/uiLanguage.h +++ b/MDUV380_firmware/application/include/user_interface/languages/uiLanguage.h @@ -335,6 +335,8 @@ typedef struct const char text_size[LANGUAGE_TEXTS_LENGTH]; const char last_talker[LANGUAGE_TEXTS_LENGTH]; const char mute[LANGUAGE_TEXTS_LENGTH]; + const char delete_channel[LANGUAGE_TEXTS_LENGTH]; + const char keep_one_channel[LANGUAGE_TEXTS_LENGTH]; } stringsTable_t; #endif // _OPENGD77_UILANGUAGE_H_ diff --git a/MDUV380_firmware/application/source/user_interface/uiChannelMode.c b/MDUV380_firmware/application/source/user_interface/uiChannelMode.c index e7f9709..ffd8d1c 100644 --- a/MDUV380_firmware/application/source/user_interface/uiChannelMode.c +++ b/MDUV380_firmware/application/source/user_interface/uiChannelMode.c @@ -2416,7 +2416,7 @@ static void updateQuickMenuScreen(bool isFirstRun) rightSideConst = currentLanguage->new_channel; break; case CH_SCREEN_QUICK_MENU_DELETE_CHANNEL: - rightSideConst = "Delete Channel"; + rightSideConst = currentLanguage->delete_channel; break; default: buf[0] = 0; @@ -2683,7 +2683,7 @@ static void handleQuickMenuEvent(uiEvent_t *ev) if (inUseCount < 2) { - snprintf(uiDataGlobal.MessageBox.message, MESSAGEBOX_MESSAGE_LEN_MAX, "Cannot delete\nlast channel"); + snprintf(uiDataGlobal.MessageBox.message, MESSAGEBOX_MESSAGE_LEN_MAX, "%s", currentLanguage->keep_one_channel); uiDataGlobal.MessageBox.buttons = #if defined(PLATFORM_MD9600) MESSAGEBOX_BUTTONS_ENT; @@ -2695,12 +2695,13 @@ static void handleQuickMenuEvent(uiEvent_t *ev) return; } - snprintf(uiDataGlobal.MessageBox.message, MESSAGEBOX_MESSAGE_LEN_MAX, "Delete channel?\n%s", currentLanguage->please_confirm); + snprintf(uiDataGlobal.MessageBox.message, MESSAGEBOX_MESSAGE_LEN_MAX, "%s\n%s", currentLanguage->delete_channel, currentLanguage->please_confirm); uiDataGlobal.MessageBox.buttons = MESSAGEBOX_BUTTONS_YESNO; uiDataGlobal.MessageBox.validatorCallback = validateDeleteChannel; menuSystemPushNewMenu(UI_MESSAGE_BOX); voicePromptsInit(); + voicePromptsAppendLanguageString(currentLanguage->delete_channel); voicePromptsAppendLanguageString(currentLanguage->please_confirm); voicePromptsPlay(); return; diff --git a/flash.sh b/flash.sh index db20f9e..691010f 100644 --- a/flash.sh +++ b/flash.sh @@ -58,11 +58,11 @@ done # ---- resolve / build the language file ------------------------------------ LANG_ARGS=() if [[ -n "$LANGUAGE" && "$(lc "$LANGUAGE")" != "none" ]]; then - # Build the .gla files once if they're missing. - if ! ls "$LANG_SRC"/*.gla >/dev/null 2>&1; then - echo "==> Building language (.gla) files..." - ( cd "$LANG_SRC" && gcc -w -I../ -o languages_builder languages_builder.c && ./languages_builder >/dev/null ) - fi + # Always (re)build the .gla language packs so edits to the *.h language files + # are picked up. (They're built from the .h sources by languages_builder; a + # stale pack would otherwise show blank/old strings on the radio.) + echo "==> Building language (.gla) files..." + ( cd "$LANG_SRC" && gcc -w -I../ -o languages_builder languages_builder.c && ./languages_builder >/dev/null ) # Case-insensitive match of the requested name to an actual .gla file. GLA="" for f in "$LANG_SRC"/*.gla; do