From a83b65039863ad2dfbb5a1ffcbf2667aa5238b33 Mon Sep 17 00:00:00 2001 From: Elias Projahn Date: Mon, 2 Nov 2020 00:52:04 +0100 Subject: [PATCH] Add translation infrastructure and German translation --- .gitignore | 1 + Cargo.toml | 1 + po/LINGUAS | 1 + po/POTFILES | 0 po/POTFILES.in | 61 ++++++ po/de.po | 342 ++++++++++++++++++++++++++++++ po/musicus.pot | 336 +++++++++++++++++++++++++++++ res/ui/part_editor.ui | 2 +- src/config.rs.in | 1 + src/dialogs/part_editor.rs | 3 +- src/dialogs/performance_editor.rs | 7 +- src/dialogs/preferences.rs | 31 +-- src/dialogs/recording_selector.rs | 18 +- src/dialogs/tracks_editor.rs | 7 +- src/main.rs | 5 + src/meson.build | 18 ++ src/screens/ensemble_screen.rs | 10 +- src/screens/person_screen.rs | 9 +- src/screens/recording_screen.rs | 9 +- src/screens/work_screen.rs | 7 +- src/widgets/person_list.rs | 3 +- src/widgets/poe_list.rs | 3 +- src/window.rs | 10 +- 23 files changed, 834 insertions(+), 51 deletions(-) delete mode 100644 po/POTFILES create mode 100644 po/POTFILES.in create mode 100644 po/de.po create mode 100644 po/musicus.pot create mode 100644 src/config.rs.in diff --git a/.gitignore b/.gitignore index e00ffca..41f19f5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ /build /builddir /flatpak +/src/config.rs /src/resources.rs /target Cargo.lock diff --git a/Cargo.toml b/Cargo.toml index e0af27a..9ee79bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ diesel = { version = "1.4.5", features = ["sqlite"] } diesel_migrations = "1.4.0" futures = "0.3.6" futures-channel = "0.3.5" +gettext-rs = "0.5.0" gio = "0.9.1" glib = "0.10.2" gtk = { version = "0.9.2", features = ["v3_24"] } diff --git a/po/LINGUAS b/po/LINGUAS index e69de29..c42e816 100644 --- a/po/LINGUAS +++ b/po/LINGUAS @@ -0,0 +1 @@ +de \ No newline at end of file diff --git a/po/POTFILES b/po/POTFILES deleted file mode 100644 index e69de29..0000000 diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 0000000..ce138a3 --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,61 @@ +res/ui/ensemble_editor.ui +res/ui/ensemble_screen.ui +res/ui/ensemble_selector.ui +res/ui/instrument_editor.ui +res/ui/instrument_selector.ui +res/ui/part_editor.ui +res/ui/performance_editor.ui +res/ui/person_editor.ui +res/ui/person_list.ui +res/ui/person_screen.ui +res/ui/person_selector.ui +res/ui/poe_list.ui +res/ui/preferences.ui +res/ui/recording_editor.ui +res/ui/recording_screen.ui +res/ui/recording_selector_screen.ui +res/ui/recording_selector.ui +res/ui/section_editor.ui +res/ui/track_editor.ui +res/ui/tracks_editor.ui +res/ui/window.ui +res/ui/work_editor.ui +res/ui/work_screen.ui +res/ui/work_selector.ui + +src/database/database.rs +src/database/models.rs +src/database/mod.rs +src/database/schema.rs +src/database/tables.rs +src/dialogs/ensemble_editor.rs +src/dialogs/ensemble_selector.rs +src/dialogs/instrument_editor.rs +src/dialogs/instrument_selector.rs +src/dialogs/mod.rs +src/dialogs/part_editor.rs +src/dialogs/performance_editor.rs +src/dialogs/person_editor.rs +src/dialogs/person_selector.rs +src/dialogs/preferences.rs +src/dialogs/recording_editor.rs +src/dialogs/recording_selector.rs +src/dialogs/section_editor.rs +src/dialogs/track_editor.rs +src/dialogs/tracks_editor.rs +src/dialogs/work_editor.rs +src/dialogs/work_selector.rs +src/screens/ensemble_screen.rs +src/screens/mod.rs +src/screens/person_screen.rs +src/screens/recording_screen.rs +src/screens/work_screen.rs +src/widgets/list.rs +src/widgets/mod.rs +src/widgets/navigator.rs +src/widgets/person_list.rs +src/widgets/poe_list.rs +src/widgets/selector_row.rs +src/backend.rs +src/main.rs +src/window.rs \ No newline at end of file diff --git a/po/de.po b/po/de.po new file mode 100644 index 0000000..ac583d4 --- /dev/null +++ b/po/de.po @@ -0,0 +1,342 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-11-02 00:33+0100\n" +"PO-Revision-Date: 2020-11-02 00:44+0100\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.4.1\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: res/ui/ensemble_editor.ui:22 res/ui/instrument_editor.ui:22 +msgid "Name" +msgstr "Name" + +#: res/ui/ensemble_editor.ui:46 res/ui/performance_editor.ui:155 +#: res/ui/performance_editor.ui:186 +msgid "Ensemble" +msgstr "Ensemble" + +#: res/ui/ensemble_editor.ui:49 res/ui/instrument_editor.ui:49 +#: res/ui/part_editor.ui:241 res/ui/performance_editor.ui:219 +#: res/ui/person_editor.ui:72 res/ui/recording_editor.ui:225 +#: res/ui/section_editor.ui:49 res/ui/track_editor.ui:45 +#: res/ui/tracks_editor.ui:268 res/ui/work_editor.ui:389 +msgid "Cancel" +msgstr "Abbrechen" + +#: res/ui/ensemble_editor.ui:57 res/ui/instrument_editor.ui:57 +#: res/ui/part_editor.ui:249 res/ui/performance_editor.ui:227 +#: res/ui/person_editor.ui:80 res/ui/recording_editor.ui:233 +#: res/ui/section_editor.ui:57 res/ui/track_editor.ui:53 +#: res/ui/tracks_editor.ui:253 res/ui/work_editor.ui:397 +msgid "Save" +msgstr "Speichern" + +#: res/ui/ensemble_screen.ui:90 res/ui/work_screen.ui:90 +msgid "Search recordings …" +msgstr "Aufnahmen durchsuchen …" + +#: res/ui/ensemble_screen.ui:143 res/ui/person_screen.ui:188 +#: res/ui/work_screen.ui:143 +msgid "Recordings" +msgstr "Aufnahmen" + +#: res/ui/ensemble_screen.ui:191 res/ui/work_screen.ui:191 +#: src/dialogs/recording_selector.rs:218 src/screens/ensemble_screen.rs:76 +#: src/screens/person_screen.rs:94 src/screens/work_screen.rs:77 +msgid "No recordings found." +msgstr "Keine Aufnahmen gefunden." + +#: res/ui/ensemble_selector.ui:52 +msgid "No ensembles found." +msgstr "Keine Ensembles gefunden." + +#: res/ui/ensemble_selector.ui:72 +msgid "Select ensemble" +msgstr "Ensemble auswählen" + +#: res/ui/instrument_editor.ui:46 +msgid "Instrument" +msgstr "Instrument" + +#: res/ui/instrument_selector.ui:52 +msgid "No instruments found." +msgstr "Keine Instrumente gefunden." + +#: res/ui/instrument_selector.ui:72 +msgid "Select instrument" +msgstr "Instrument auswählen" + +#: res/ui/part_editor.ui:29 res/ui/work_editor.ui:48 +msgid "Composer" +msgstr "Komponist" + +#: res/ui/part_editor.ui:52 res/ui/section_editor.ui:22 +#: res/ui/work_editor.ui:70 +msgid "Title" +msgstr "Titel" + +#: res/ui/part_editor.ui:75 res/ui/performance_editor.ui:45 +#: res/ui/performance_editor.ui:129 res/ui/performance_editor.ui:173 +#: res/ui/recording_editor.ui:47 res/ui/tracks_editor.ui:49 +#: res/ui/work_editor.ui:34 src/dialogs/part_editor.rs:99 +#: src/dialogs/performance_editor.rs:112 src/dialogs/performance_editor.rs:122 +#: src/dialogs/performance_editor.rs:136 +msgid "Select …" +msgstr "Auswählen …" + +#: res/ui/part_editor.ui:119 res/ui/recording_editor.ui:84 +#: res/ui/work_editor.ui:83 +msgid "Overview" +msgstr "Überblick" + +#: res/ui/part_editor.ui:150 res/ui/work_editor.ui:114 +msgid "No instruments added." +msgstr "Keine Instrumente hinzugefügt" + +#: res/ui/part_editor.ui:225 res/ui/work_editor.ui:189 +msgid "Instruments" +msgstr "Instrumente" + +#: res/ui/part_editor.ui:238 +msgid "Work part" +msgstr "Werkabschnitt" + +#: res/ui/performance_editor.ui:22 +msgid "Role" +msgstr "Rolle" + +#: res/ui/performance_editor.ui:87 +msgid "Type" +msgstr "Typ" + +#: res/ui/performance_editor.ui:110 res/ui/performance_editor.ui:142 +#: res/ui/person_editor.ui:69 +msgid "Person" +msgstr "Person" + +#: res/ui/performance_editor.ui:216 +msgid "Performance" +msgstr "Auftritt" + +#: res/ui/person_editor.ui:22 +msgid "First name" +msgstr "Vorname" + +#: res/ui/person_editor.ui:45 +msgid "Last name" +msgstr "Nachname" + +#: res/ui/person_list.ui:28 res/ui/work_selector.ui:69 +msgid "Search persons …" +msgstr "Personen durchsuchen …" + +#: res/ui/person_screen.ui:90 +msgid "Search works and recordings …" +msgstr "Werke und Aufnahmen durchsuchen …" + +#: res/ui/person_screen.ui:143 +msgid "Works" +msgstr "Werke" + +#: res/ui/person_screen.ui:236 +msgid "No works or recordings found." +msgstr "Keine Werke oder Aufnahmen gefunden." + +#: res/ui/person_selector.ui:19 +msgid "Select person" +msgstr "Person auswählen" + +#: res/ui/poe_list.ui:28 +msgid "Search persons and ensembles …" +msgstr "Personen und Ensembles durchsuchen …" + +#: res/ui/preferences.ui:14 +msgid "General" +msgstr "Allgemein" + +#: res/ui/preferences.ui:19 +msgid "Music library" +msgstr "Musikbibliothek" + +#: res/ui/preferences.ui:25 +msgid "Music library folder" +msgstr "Ordner der Musikbibliothek" + +#: res/ui/preferences.ui:27 +msgid "None selected" +msgstr "Keiner ausgewählt" + +#: res/ui/preferences.ui:30 +msgid "Select" +msgstr "Auswählen" + +#: res/ui/recording_editor.ui:29 +msgid "Comment" +msgstr "Kommentar" + +#: res/ui/recording_editor.ui:71 res/ui/tracks_editor.ui:65 +#: res/ui/work_editor.ui:386 +msgid "Work" +msgstr "Werk" + +#: res/ui/recording_editor.ui:115 +msgid "No performers added." +msgstr "Keine Interpreten hinzugefügt." + +#: res/ui/recording_editor.ui:209 res/ui/tracks_editor.ui:83 +msgid "Performers" +msgstr "Interpreten" + +#: res/ui/recording_editor.ui:222 res/ui/tracks_editor.ui:24 +msgid "Recording" +msgstr "Aufnahme" + +#: res/ui/recording_screen.ui:96 res/ui/tracks_editor.ui:250 +msgid "Tracks" +msgstr "Tracks" + +#: res/ui/recording_selector.ui:15 +msgid "Select a recording" +msgstr "Aufnahme auswählen" + +#: res/ui/recording_selector.ui:28 res/ui/work_selector.ui:180 +msgid "Select a composer on the left." +msgstr "Wählen Sie einen Komponisten aus." + +#: res/ui/recording_selector.ui:72 res/ui/recording_selector.ui:187 +#: src/dialogs/recording_selector.rs:112 src/screens/person_screen.rs:68 +msgid "No works found." +msgstr "Keine Werke gefunden." + +#: res/ui/section_editor.ui:46 +msgid "Work section" +msgstr "Werkteil" + +#: res/ui/track_editor.ui:29 +msgid "Select a recording of a work with multiple parts." +msgstr "Wählen Sie eine Aufnahme eines mehrteiligen Werks aus." + +#: res/ui/track_editor.ui:42 +msgid "Track" +msgstr "Track" + +#: res/ui/window.ui:15 res/ui/window.ui:104 res/ui/window.ui:206 +msgid "Musicus" +msgstr "Musicus" + +#: res/ui/window.ui:51 res/ui/window.ui:141 +msgid "Welcome to Musicus!" +msgstr "Willkommen bei Musicus!" + +#: res/ui/window.ui:67 +msgid "" +"Get startet by selecting something from the sidebar or adding new things to " +"your library using the button in the top left corner." +msgstr "" +"Legen Sie los, indem Sie etwas in der Seitenleiste auswählen oder fügen Sie " +"mit dem Knopf oben links neue Aufnahmen zu Ihrer Musikbibliothek hinzu." + +#: res/ui/window.ui:157 +msgid "" +"Get startet by selecting the folder containing your music files! Musicus " +"will create a new database there or open one that already exists." +msgstr "" +"Wählen Sie als Erstes den Ordner aus, worin sich Ihre Musik befindet. " +"Musicus wird dort eine neue Datenbank anlegen oder eine bereits " +"existierende öffnen." + +#: res/ui/window.ui:170 +msgid "Select folder" +msgstr "Ordner auswählen" + +#: res/ui/window.ui:320 +msgid "Preferences" +msgstr "Einstellungen" + +#: res/ui/work_editor.ui:221 +msgid "No work parts added." +msgstr "Keine Werkabschnitte hinzugefügt." + +#: res/ui/work_editor.ui:373 +msgid "Structure" +msgstr "Struktur" + +#: res/ui/work_selector.ui:113 src/widgets/person_list.rs:37 +msgid "No persons found." +msgstr "Keine Personen gefunden." + +#: res/ui/work_selector.ui:167 +msgid "Select work" +msgstr "Werk auswählen" + +#: res/ui/work_selector.ui:268 +msgid "Search works …" +msgstr "Werke durchsuchen …" + +#: src/dialogs/preferences.rs:30 src/window.rs:56 +msgid "Select music library folder" +msgstr "Ordner der Musikbibliothek auswählen" + +#: src/dialogs/tracks_editor.rs:57 src/screens/recording_screen.rs:61 +msgid "Unknown" +msgstr "Unbekannt" + +#: src/dialogs/tracks_editor.rs:78 +msgid "Add some tracks." +msgstr "Fügen Sie Tracks hinzu." + +#: src/dialogs/tracks_editor.rs:145 +msgid "Select audio files" +msgstr "Audiodateien auswählen" + +#: src/screens/ensemble_screen.rs:35 +msgid "Edit ensemble" +msgstr "Ensemble bearbeiten" + +#: src/screens/ensemble_screen.rs:41 +msgid "Delete ensemble" +msgstr "Ensemble löschen" + +#: src/screens/person_screen.rs:39 +msgid "Edit person" +msgstr "Person bearbeiten" + +#: src/screens/person_screen.rs:45 +msgid "Delete person" +msgstr "Person löschen" + +#: src/screens/recording_screen.rs:34 +msgid "Edit recording" +msgstr "Aufnahme bearbeiten" + +#: src/screens/recording_screen.rs:40 +msgid "Delete recording" +msgstr "Aufnahme löschen" + +#: src/screens/recording_screen.rs:82 +msgid "No tracks found." +msgstr "Keine Tracks gefunden." + +#: src/screens/work_screen.rs:36 +msgid "Edit work" +msgstr "Werk bearbeiten" + +#: src/screens/work_screen.rs:42 +msgid "Delete work" +msgstr "Werk löschen" + +#: src/widgets/poe_list.rs:52 +msgid "No persons or ensembles found." +msgstr "Keine Personen oder Ensembles gefunden." diff --git a/po/musicus.pot b/po/musicus.pot new file mode 100644 index 0000000..c6a984e --- /dev/null +++ b/po/musicus.pot @@ -0,0 +1,336 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the musicus package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: musicus\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-11-02 00:33+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: res/ui/ensemble_editor.ui:22 res/ui/instrument_editor.ui:22 +msgid "Name" +msgstr "" + +#: res/ui/ensemble_editor.ui:46 res/ui/performance_editor.ui:155 +#: res/ui/performance_editor.ui:186 +msgid "Ensemble" +msgstr "" + +#: res/ui/ensemble_editor.ui:49 res/ui/instrument_editor.ui:49 +#: res/ui/part_editor.ui:241 res/ui/performance_editor.ui:219 +#: res/ui/person_editor.ui:72 res/ui/recording_editor.ui:225 +#: res/ui/section_editor.ui:49 res/ui/track_editor.ui:45 +#: res/ui/tracks_editor.ui:268 res/ui/work_editor.ui:389 +msgid "Cancel" +msgstr "" + +#: res/ui/ensemble_editor.ui:57 res/ui/instrument_editor.ui:57 +#: res/ui/part_editor.ui:249 res/ui/performance_editor.ui:227 +#: res/ui/person_editor.ui:80 res/ui/recording_editor.ui:233 +#: res/ui/section_editor.ui:57 res/ui/track_editor.ui:53 +#: res/ui/tracks_editor.ui:253 res/ui/work_editor.ui:397 +msgid "Save" +msgstr "" + +#: res/ui/ensemble_screen.ui:90 res/ui/work_screen.ui:90 +msgid "Search recordings …" +msgstr "" + +#: res/ui/ensemble_screen.ui:143 res/ui/person_screen.ui:188 +#: res/ui/work_screen.ui:143 +msgid "Recordings" +msgstr "" + +#: res/ui/ensemble_screen.ui:191 res/ui/work_screen.ui:191 +#: src/dialogs/recording_selector.rs:218 src/screens/ensemble_screen.rs:76 +#: src/screens/person_screen.rs:94 src/screens/work_screen.rs:77 +msgid "No recordings found." +msgstr "" + +#: res/ui/ensemble_selector.ui:52 +msgid "No ensembles found." +msgstr "" + +#: res/ui/ensemble_selector.ui:72 +msgid "Select ensemble" +msgstr "" + +#: res/ui/instrument_editor.ui:46 +msgid "Instrument" +msgstr "" + +#: res/ui/instrument_selector.ui:52 +msgid "No instruments found." +msgstr "" + +#: res/ui/instrument_selector.ui:72 +msgid "Select instrument" +msgstr "" + +#: res/ui/part_editor.ui:29 res/ui/work_editor.ui:48 +msgid "Composer" +msgstr "" + +#: res/ui/part_editor.ui:52 res/ui/section_editor.ui:22 +#: res/ui/work_editor.ui:70 +msgid "Title" +msgstr "" + +#: res/ui/part_editor.ui:75 res/ui/performance_editor.ui:45 +#: res/ui/performance_editor.ui:129 res/ui/performance_editor.ui:173 +#: res/ui/recording_editor.ui:47 res/ui/tracks_editor.ui:49 +#: res/ui/work_editor.ui:34 src/dialogs/part_editor.rs:99 +#: src/dialogs/performance_editor.rs:112 src/dialogs/performance_editor.rs:122 +#: src/dialogs/performance_editor.rs:136 +msgid "Select …" +msgstr "" + +#: res/ui/part_editor.ui:119 res/ui/recording_editor.ui:84 +#: res/ui/work_editor.ui:83 +msgid "Overview" +msgstr "" + +#: res/ui/part_editor.ui:150 res/ui/work_editor.ui:114 +msgid "No instruments added." +msgstr "" + +#: res/ui/part_editor.ui:225 res/ui/work_editor.ui:189 +msgid "Instruments" +msgstr "" + +#: res/ui/part_editor.ui:238 +msgid "Work part" +msgstr "" + +#: res/ui/performance_editor.ui:22 +msgid "Role" +msgstr "" + +#: res/ui/performance_editor.ui:87 +msgid "Type" +msgstr "" + +#: res/ui/performance_editor.ui:110 res/ui/performance_editor.ui:142 +#: res/ui/person_editor.ui:69 +msgid "Person" +msgstr "" + +#: res/ui/performance_editor.ui:216 +msgid "Performance" +msgstr "" + +#: res/ui/person_editor.ui:22 +msgid "First name" +msgstr "" + +#: res/ui/person_editor.ui:45 +msgid "Last name" +msgstr "" + +#: res/ui/person_list.ui:28 res/ui/work_selector.ui:69 +msgid "Search persons …" +msgstr "" + +#: res/ui/person_screen.ui:90 +msgid "Search works and recordings …" +msgstr "" + +#: res/ui/person_screen.ui:143 +msgid "Works" +msgstr "" + +#: res/ui/person_screen.ui:236 +msgid "No works or recordings found." +msgstr "" + +#: res/ui/person_selector.ui:19 +msgid "Select person" +msgstr "" + +#: res/ui/poe_list.ui:28 +msgid "Search persons and ensembles …" +msgstr "" + +#: res/ui/preferences.ui:14 +msgid "General" +msgstr "" + +#: res/ui/preferences.ui:19 +msgid "Music library" +msgstr "" + +#: res/ui/preferences.ui:25 +msgid "Music library folder" +msgstr "" + +#: res/ui/preferences.ui:27 +msgid "None selected" +msgstr "" + +#: res/ui/preferences.ui:30 +msgid "Select" +msgstr "" + +#: res/ui/recording_editor.ui:29 +msgid "Comment" +msgstr "" + +#: res/ui/recording_editor.ui:71 res/ui/tracks_editor.ui:65 +#: res/ui/work_editor.ui:386 +msgid "Work" +msgstr "" + +#: res/ui/recording_editor.ui:115 +msgid "No performers added." +msgstr "" + +#: res/ui/recording_editor.ui:209 res/ui/tracks_editor.ui:83 +msgid "Performers" +msgstr "" + +#: res/ui/recording_editor.ui:222 res/ui/tracks_editor.ui:24 +msgid "Recording" +msgstr "" + +#: res/ui/recording_screen.ui:96 res/ui/tracks_editor.ui:250 +msgid "Tracks" +msgstr "" + +#: res/ui/recording_selector.ui:15 +msgid "Select a recording" +msgstr "" + +#: res/ui/recording_selector.ui:28 res/ui/work_selector.ui:180 +msgid "Select a composer on the left." +msgstr "" + +#: res/ui/recording_selector.ui:72 res/ui/recording_selector.ui:187 +#: src/dialogs/recording_selector.rs:112 src/screens/person_screen.rs:68 +msgid "No works found." +msgstr "" + +#: res/ui/section_editor.ui:46 +msgid "Work section" +msgstr "" + +#: res/ui/track_editor.ui:29 +msgid "Select a recording of a work with multiple parts." +msgstr "" + +#: res/ui/track_editor.ui:42 +msgid "Track" +msgstr "" + +#: res/ui/window.ui:15 res/ui/window.ui:104 res/ui/window.ui:206 +msgid "Musicus" +msgstr "" + +#: res/ui/window.ui:51 res/ui/window.ui:141 +msgid "Welcome to Musicus!" +msgstr "" + +#: res/ui/window.ui:67 +msgid "" +"Get startet by selecting something from the sidebar or adding new things to " +"your library using the button in the top left corner." +msgstr "" + +#: res/ui/window.ui:157 +msgid "" +"Get startet by selecting the folder containing your music files! Musicus " +"will create a new database there or open one that already exists." +msgstr "" + +#: res/ui/window.ui:170 +msgid "Select folder" +msgstr "" + +#: res/ui/window.ui:320 +msgid "Preferences" +msgstr "" + +#: res/ui/work_editor.ui:221 +msgid "No work parts added." +msgstr "" + +#: res/ui/work_editor.ui:373 +msgid "Structure" +msgstr "" + +#: res/ui/work_selector.ui:113 src/widgets/person_list.rs:37 +msgid "No persons found." +msgstr "" + +#: res/ui/work_selector.ui:167 +msgid "Select work" +msgstr "" + +#: res/ui/work_selector.ui:268 +msgid "Search works …" +msgstr "" + +#: src/dialogs/preferences.rs:30 src/window.rs:56 +msgid "Select music library folder" +msgstr "" + +#: src/dialogs/tracks_editor.rs:57 src/screens/recording_screen.rs:61 +msgid "Unknown" +msgstr "" + +#: src/dialogs/tracks_editor.rs:78 +msgid "Add some tracks." +msgstr "" + +#: src/dialogs/tracks_editor.rs:145 +msgid "Select audio files" +msgstr "" + +#: src/screens/ensemble_screen.rs:35 +msgid "Edit ensemble" +msgstr "" + +#: src/screens/ensemble_screen.rs:41 +msgid "Delete ensemble" +msgstr "" + +#: src/screens/person_screen.rs:39 +msgid "Edit person" +msgstr "" + +#: src/screens/person_screen.rs:45 +msgid "Delete person" +msgstr "" + +#: src/screens/recording_screen.rs:34 +msgid "Edit recording" +msgstr "" + +#: src/screens/recording_screen.rs:40 +msgid "Delete recording" +msgstr "" + +#: src/screens/recording_screen.rs:82 +msgid "No tracks found." +msgstr "" + +#: src/screens/work_screen.rs:36 +msgid "Edit work" +msgstr "" + +#: src/screens/work_screen.rs:42 +msgid "Delete work" +msgstr "" + +#: src/widgets/poe_list.rs:52 +msgid "No persons or ensembles found." +msgstr "" diff --git a/res/ui/part_editor.ui b/res/ui/part_editor.ui index 80506f4..10c372f 100644 --- a/res/ui/part_editor.ui +++ b/res/ui/part_editor.ui @@ -72,7 +72,7 @@ True False start - Auswählen … + Select … diff --git a/src/config.rs.in b/src/config.rs.in new file mode 100644 index 0000000..9a3de2e --- /dev/null +++ b/src/config.rs.in @@ -0,0 +1 @@ +pub static LOCALEDIR: &str = @LOCALEDIR@; \ No newline at end of file diff --git a/src/dialogs/part_editor.rs b/src/dialogs/part_editor.rs index dcbd841..37f0e09 100644 --- a/src/dialogs/part_editor.rs +++ b/src/dialogs/part_editor.rs @@ -2,6 +2,7 @@ use super::{InstrumentSelector, PersonSelector}; use crate::backend::*; use crate::database::*; use crate::widgets::*; +use gettextrs::gettext; use glib::clone; use gtk::prelude::*; use gtk_macros::get_widget; @@ -95,7 +96,7 @@ impl PartEditor { reset_composer_button.connect_clicked(clone!(@strong result => move |_| { result.composer.replace(None); - result.composer_label.set_text("Select …"); + result.composer_label.set_text(&gettext("Select …")); })); add_instrument_button.connect_clicked(clone!(@strong result => move |_| { diff --git a/src/dialogs/performance_editor.rs b/src/dialogs/performance_editor.rs index 4431ac1..c7d0d96 100644 --- a/src/dialogs/performance_editor.rs +++ b/src/dialogs/performance_editor.rs @@ -1,6 +1,7 @@ use super::*; use crate::backend::Backend; use crate::database::*; +use gettextrs::gettext; use glib::clone; use gtk::prelude::*; use gtk_macros::get_widget; @@ -108,7 +109,7 @@ where result.person.replace(Some(person.clone())); result.person_label.set_text(&person.name_fl()); result.ensemble.replace(None); - result.ensemble_label.set_text("Select …"); + result.ensemble_label.set_text(&gettext("Select …")); result.save_button.set_sensitive(true); })).show(); })); @@ -118,7 +119,7 @@ where result.ensemble.replace(Some(ensemble.clone())); result.ensemble_label.set_text(&ensemble.name); result.person.replace(None); - result.person_label.set_text("Select …"); + result.person_label.set_text(&gettext("Select …")); result.save_button.set_sensitive(true); })).show(); })); @@ -132,7 +133,7 @@ where reset_role_button.connect_clicked(clone!(@strong result => move |_| { result.role.replace(None); - result.role_label.set_text("Select …"); + result.role_label.set_text(&gettext("Select …")); })); result.window.set_transient_for(Some(parent)); diff --git a/src/dialogs/preferences.rs b/src/dialogs/preferences.rs index 965b040..ccd3c7d 100644 --- a/src/dialogs/preferences.rs +++ b/src/dialogs/preferences.rs @@ -1,4 +1,5 @@ use crate::backend::Backend; +use gettextrs::gettext; use glib::clone; use gtk::prelude::*; use gtk_macros::get_widget; @@ -23,21 +24,25 @@ impl Preferences { music_library_path_row.set_subtitle(Some(path.to_str().unwrap())); } - select_music_library_path_button.connect_clicked(clone!(@strong window, @strong backend, @strong music_library_path_row => move |_| { - let dialog = gtk::FileChooserNative::new(Some("Select music library folder"), Some(&window), gtk::FileChooserAction::SelectFolder, None, None); + select_music_library_path_button.connect_clicked( + clone!(@strong window, @strong backend, @strong music_library_path_row => move |_| { + let dialog = gtk::FileChooserNative::new( + Some(&gettext("Select music library folder")), + Some(&window), gtk::FileChooserAction::SelectFolder,None, None); - if let gtk::ResponseType::Accept = dialog.run() { - if let Some(path) = dialog.get_filename() { - music_library_path_row.set_subtitle(Some(path.to_str().unwrap())); - - let context = glib::MainContext::default(); - let backend = backend.clone(); - context.spawn_local(async move { - backend.set_music_library_path(path).await.unwrap(); - }); + if let gtk::ResponseType::Accept = dialog.run() { + if let Some(path) = dialog.get_filename() { + music_library_path_row.set_subtitle(Some(path.to_str().unwrap())); + + let context = glib::MainContext::default(); + let backend = backend.clone(); + context.spawn_local(async move { + backend.set_music_library_path(path).await.unwrap(); + }); + } } - } - })); + }), + ); Self { window } } diff --git a/src/dialogs/recording_selector.rs b/src/dialogs/recording_selector.rs index a23aa72..dcf30dd 100644 --- a/src/dialogs/recording_selector.rs +++ b/src/dialogs/recording_selector.rs @@ -2,6 +2,7 @@ use super::*; use crate::backend::Backend; use crate::database::*; use crate::widgets::*; +use gettextrs::gettext; use gio::prelude::*; use glib::clone; use gtk::prelude::*; @@ -25,8 +26,7 @@ impl RecordingSelector { P: IsA, F: Fn(RecordingDescription) -> () + 'static, { - let builder = - gtk::Builder::from_resource("/de/johrpan/musicus/ui/recording_selector.ui"); + let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/recording_selector.ui"); get_widget!(builder, gtk::Window, window); get_widget!(builder, libhandy::Leaflet, leaflet); @@ -92,9 +92,8 @@ struct RecordingSelectorPersonScreen { impl RecordingSelectorPersonScreen { pub fn new(backend: Rc, selector: Rc, person: Person) -> Rc { - let builder = gtk::Builder::from_resource( - "/de/johrpan/musicus/ui/recording_selector_screen.ui", - ); + let builder = + gtk::Builder::from_resource("/de/johrpan/musicus/ui/recording_selector_screen.ui"); get_widget!(builder, gtk::Box, widget); get_widget!(builder, libhandy::HeaderBar, header); @@ -110,7 +109,7 @@ impl RecordingSelectorPersonScreen { label.upcast() }, |_| true, - "No works found.", + &gettext("No works found."), ); stack.add_named(&work_list.widget, "content"); @@ -186,9 +185,8 @@ impl RecordingSelectorWorkScreen { selector: Rc, work: WorkDescription, ) -> Rc { - let builder = gtk::Builder::from_resource( - "/de/johrpan/musicus/ui/recording_selector_screen.ui", - ); + let builder = + gtk::Builder::from_resource("/de/johrpan/musicus/ui/recording_selector_screen.ui"); get_widget!(builder, gtk::Box, widget); get_widget!(builder, libhandy::HeaderBar, header); @@ -217,7 +215,7 @@ impl RecordingSelectorWorkScreen { vbox.upcast() }, |_| true, - "No recordings found.", + &gettext("No recordings found."), ); stack.add_named(&recording_list.widget, "content"); diff --git a/src/dialogs/tracks_editor.rs b/src/dialogs/tracks_editor.rs index ba44528..f950212 100644 --- a/src/dialogs/tracks_editor.rs +++ b/src/dialogs/tracks_editor.rs @@ -2,6 +2,7 @@ use super::*; use crate::backend::*; use crate::database::*; use crate::widgets::*; +use gettextrs::gettext; use glib::clone; use gtk::prelude::*; use gtk_macros::get_widget; @@ -53,7 +54,7 @@ impl TracksEditor { } let title = if title_parts.is_empty() { - String::from("Unknown") + gettext("Unknown") } else { title_parts.join(", ") }; @@ -74,7 +75,7 @@ impl TracksEditor { vbox.upcast() }), |_| true, - "Add some tracks.", + &gettext("Add some tracks."), ); let autofill_parts = Rc::new(clone!(@strong recording, @strong tracks, @strong track_list => move || { @@ -141,7 +142,7 @@ impl TracksEditor { add_track_button.connect_clicked(clone!(@strong window, @strong tracks, @strong track_list, @strong autofill_parts => move |_| { let music_library_path = backend.get_music_library_path().unwrap(); - let dialog = gtk::FileChooserNative::new(Some("Select audio files"), Some(&window), gtk::FileChooserAction::Open, None, None); + let dialog = gtk::FileChooserNative::new(Some(&gettext("Select audio files")), Some(&window), gtk::FileChooserAction::Open, None, None); dialog.set_select_multiple(true); dialog.set_current_folder(&music_library_path); diff --git a/src/main.rs b/src/main.rs index a7b359e..5dd64d2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,7 @@ use glib::clone; use std::cell::RefCell; use std::rc::Rc; +mod config; mod backend; mod database; mod dialogs; @@ -23,6 +24,10 @@ use window::Window; mod resources; fn main() { + gettextrs::setlocale(gettextrs::LocaleCategory::LcAll, ""); + gettextrs::bindtextdomain("musicus", config::LOCALEDIR); + gettextrs::textdomain("musicus"); + gtk::init().expect("Failed to initialize GTK!"); libhandy::init(); resources::init().expect("Failed to initialize resources!"); diff --git a/src/meson.build b/src/meson.build index 7355386..275424e 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,3 +1,21 @@ +prefix = get_option('prefix') +localedir = join_paths(prefix, get_option('localedir')) + +global_conf = configuration_data() +global_conf.set_quoted('LOCALEDIR', localedir) +config_rs = configure_file( + input: 'config.rs.in', + output: 'config.rs', + configuration: global_conf +) + +run_command( + 'cp', + config_rs, + meson.current_source_dir(), + check: true +) + resource_conf = configuration_data() resource_conf.set_quoted('RESOURCEFILE', resources.full_path()) resource_rs = configure_file( diff --git a/src/screens/ensemble_screen.rs b/src/screens/ensemble_screen.rs index bafdf88..4808868 100644 --- a/src/screens/ensemble_screen.rs +++ b/src/screens/ensemble_screen.rs @@ -2,6 +2,7 @@ use super::*; use crate::backend::*; use crate::database::*; use crate::widgets::*; +use gettextrs::gettext; use glib::clone; use gtk::prelude::*; use gtk_macros::get_widget; @@ -19,8 +20,7 @@ pub struct EnsembleScreen { impl EnsembleScreen { pub fn new(backend: Rc, ensemble: Ensemble) -> Rc { - let builder = - gtk::Builder::from_resource("/de/johrpan/musicus/ui/ensemble_screen.ui"); + let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/ensemble_screen.ui"); get_widget!(builder, gtk::Box, widget); get_widget!(builder, libhandy::HeaderBar, header); @@ -32,13 +32,13 @@ impl EnsembleScreen { header.set_title(Some(&ensemble.name)); - let edit_menu_item = gio::MenuItem::new(Some("Edit ensemble"), None); + let edit_menu_item = gio::MenuItem::new(Some(&gettext("Edit ensemble")), None); edit_menu_item.set_action_and_target_value( Some("win.edit-ensemble"), Some(&glib::Variant::from(ensemble.id)), ); - let delete_menu_item = gio::MenuItem::new(Some("Delete ensemble"), None); + let delete_menu_item = gio::MenuItem::new(Some(&gettext("Delete ensemble")), None); delete_menu_item.set_action_and_target_value( Some("win.delete-ensemble"), Some(&glib::Variant::from(ensemble.id)), @@ -73,7 +73,7 @@ impl EnsembleScreen { let text = recording.work.get_title() + &recording.get_performers(); search.is_empty() || text.contains(&search) }), - "No recordings found.", + &gettext("No recordings found."), ); recording_frame.add(&recording_list.widget.clone()); diff --git a/src/screens/person_screen.rs b/src/screens/person_screen.rs index a26c3e9..dee7fb9 100644 --- a/src/screens/person_screen.rs +++ b/src/screens/person_screen.rs @@ -2,6 +2,7 @@ use super::*; use crate::backend::*; use crate::database::*; use crate::widgets::*; +use gettextrs::gettext; use glib::clone; use gtk::prelude::*; use gtk_macros::get_widget; @@ -35,13 +36,13 @@ impl PersonScreen { header.set_title(Some(&person.name_fl())); - let edit_menu_item = gio::MenuItem::new(Some("Edit person"), None); + let edit_menu_item = gio::MenuItem::new(Some(&gettext("Edit person")), None); edit_menu_item.set_action_and_target_value( Some("win.edit-person"), Some(&glib::Variant::from(person.id)), ); - let delete_menu_item = gio::MenuItem::new(Some("Delete person"), None); + let delete_menu_item = gio::MenuItem::new(Some(&gettext("Delete person")), None); delete_menu_item.set_action_and_target_value( Some("win.delete-person"), Some(&glib::Variant::from(person.id)), @@ -64,7 +65,7 @@ impl PersonScreen { let title = work.title.to_lowercase(); search.is_empty() || title.contains(&search) }), - "No works found.", + &gettext("No works found."), ); let recording_list = List::new( @@ -90,7 +91,7 @@ impl PersonScreen { let text = recording.work.get_title() + &recording.get_performers(); search.is_empty() || text.contains(&search) }), - "No recordings found.", + &gettext("No recordings found."), ); work_frame.add(&work_list.widget); diff --git a/src/screens/recording_screen.rs b/src/screens/recording_screen.rs index c5124e4..c67d491 100644 --- a/src/screens/recording_screen.rs +++ b/src/screens/recording_screen.rs @@ -1,6 +1,7 @@ use crate::backend::*; use crate::database::*; use crate::widgets::*; +use gettextrs::gettext; use glib::clone; use gtk::prelude::*; use gtk_macros::get_widget; @@ -30,13 +31,13 @@ impl RecordingScreen { header.set_title(Some(&recording.work.get_title())); header.set_subtitle(Some(&recording.get_performers())); - let edit_menu_item = gio::MenuItem::new(Some("Edit recording"), None); + let edit_menu_item = gio::MenuItem::new(Some(&gettext("Edit recording")), None); edit_menu_item.set_action_and_target_value( Some("win.edit-recording"), Some(&glib::Variant::from(recording.id)), ); - let delete_menu_item = gio::MenuItem::new(Some("Delete recording"), None); + let delete_menu_item = gio::MenuItem::new(Some(&gettext("Delete recording")), None); delete_menu_item.set_action_and_target_value( Some("win.delete-recording"), Some(&glib::Variant::from(recording.id)), @@ -57,7 +58,7 @@ impl RecordingScreen { } let title = if title_parts.is_empty() { - String::from("Unknown") + gettext("Unknown") } else { title_parts.join(", ") }; @@ -78,7 +79,7 @@ impl RecordingScreen { vbox.upcast() }), |_| true, - "No tracks found.", + &gettext("No tracks found."), ); frame.add(&list.widget); diff --git a/src/screens/work_screen.rs b/src/screens/work_screen.rs index 90e6bcb..932383c 100644 --- a/src/screens/work_screen.rs +++ b/src/screens/work_screen.rs @@ -2,6 +2,7 @@ use super::*; use crate::backend::*; use crate::database::*; use crate::widgets::*; +use gettextrs::gettext; use glib::clone; use gtk::prelude::*; use gtk_macros::get_widget; @@ -32,13 +33,13 @@ impl WorkScreen { header.set_title(Some(&work.title)); header.set_subtitle(Some(&work.composer.name_fl())); - let edit_menu_item = gio::MenuItem::new(Some("Edit work"), None); + let edit_menu_item = gio::MenuItem::new(Some(&gettext("Edit work")), None); edit_menu_item.set_action_and_target_value( Some("win.edit-work"), Some(&glib::Variant::from(work.id)), ); - let delete_menu_item = gio::MenuItem::new(Some("Delete work"), None); + let delete_menu_item = gio::MenuItem::new(Some(&gettext("Delete work")), None); delete_menu_item.set_action_and_target_value( Some("win.delete-work"), Some(&glib::Variant::from(work.id)), @@ -73,7 +74,7 @@ impl WorkScreen { let text = recording.work.get_title() + &recording.get_performers(); search.is_empty() || text.contains(&search) }), - "No recordings found.", + &gettext("No recordings found."), ); recording_frame.add(&recording_list.widget); diff --git a/src/widgets/person_list.rs b/src/widgets/person_list.rs index 5c49bcd..3a5bd79 100644 --- a/src/widgets/person_list.rs +++ b/src/widgets/person_list.rs @@ -1,6 +1,7 @@ use super::*; use crate::backend::Backend; use crate::database::*; +use gettextrs::gettext; use glib::clone; use gtk::prelude::*; use gtk_macros::get_widget; @@ -33,7 +34,7 @@ impl PersonList { let name = person.name_fl().to_lowercase(); search.is_empty() || name.contains(&search) }), - "No persons found.", + &gettext("No persons found."), ); scrolled_window.add(&list.widget); diff --git a/src/widgets/poe_list.rs b/src/widgets/poe_list.rs index 99b3579..317eda2 100644 --- a/src/widgets/poe_list.rs +++ b/src/widgets/poe_list.rs @@ -1,6 +1,7 @@ use super::*; use crate::backend::Backend; use crate::database::*; +use gettextrs::gettext; use glib::clone; use gtk::prelude::*; use gtk_macros::get_widget; @@ -48,7 +49,7 @@ impl PoeList { let title = poe.get_title().to_lowercase(); search.is_empty() || title.contains(&search) }), - "No persons or ensembles found.", + &gettext("No persons or ensembles found."), ); scrolled_window.add(&list.widget); diff --git a/src/window.rs b/src/window.rs index eb7d942..bec7bbf 100644 --- a/src/window.rs +++ b/src/window.rs @@ -3,6 +3,7 @@ use crate::dialogs::*; use crate::screens::*; use crate::widgets::*; use futures::prelude::*; +use gettextrs::gettext; use gio::prelude::*; use glib::clone; use gtk::prelude::*; @@ -51,10 +52,15 @@ impl Window { result.window.set_application(Some(app)); select_music_library_path_button.connect_clicked(clone!(@strong result => move |_| { - let dialog = gtk::FileChooserNative::new(Some("Select music library folder"), Some(&result.window), gtk::FileChooserAction::SelectFolder, None, None); + let dialog = gtk::FileChooserNative::new( + Some(&gettext("Select music library folder")), + Some(&result.window), + gtk::FileChooserAction::SelectFolder, + None, + None); if let gtk::ResponseType::Accept = dialog.run() { - if let Some(path) = dialog.get_filename() { + if let Some(path) = dialog.get_filename() { let context = glib::MainContext::default(); let backend = result.backend.clone(); context.spawn_local(async move {