Translation support and initial spanish translation
Added translation support based on the Fractal i18n. To do this I've
added the gettext-rs crate dep. I'm using my own fork because the
official gettext-rs release includes the gettext source files and that
increase the distribution package a lot and for distribution with
flatkap we don't need to build gettext, the lib is in the gnome sdk. So
this gettext-rs fork is the same, but removing the not needed gettext
source files.
The i18n.rs file adds some useful functions to translate strings. These
functions wraps the original gettext and adds more functionality, to be
able to translate compound strings, something that's not supported by
the gettext function.
The 'i18n' function works like the gettext, receives a plain string
without params.
The 'i18n_f' function receives a string with "{}" and a ref to an array
of &str with substitutions for the "{}" in the original string. The
substitution is done by order.
The 'i18n_k' function receives a string with "{named}" and a ref to an
array of (&str, &str) with substitutions for the "{named}" in the
original string. The substitution is done by name, where the first &str
in the tuple is the name and the second the string to use for the
replace.
This mod also include ni18n variants of the three functions for plural
and singular translations.
I've also created the spanish translation.
See #61
https://gitlab.gnome.org/World/podcasts/issues/61
This commit is contained in:
parent
f695ba4605
commit
bea4915317
1
.gitignore
vendored
1
.gitignore
vendored
@ -8,3 +8,4 @@ build/
|
||||
vendor/
|
||||
.criterion/
|
||||
org.gnome.*.json~
|
||||
podcasts-gtk/po/gnome-podcasts.pot
|
||||
|
||||
32
Cargo.lock
generated
32
Cargo.lock
generated
@ -657,6 +657,23 @@ dependencies = [
|
||||
"pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gettext-rs"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/danigm/gettext-rs?branch=no-gettext#db8f12e140f0db5aabafe8dd210c7fc1520a55ff"
|
||||
dependencies = [
|
||||
"gettext-sys 0.19.8 (git+https://github.com/danigm/gettext-rs?branch=no-gettext)",
|
||||
"locale_config 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gettext-sys"
|
||||
version = "0.19.8"
|
||||
source = "git+https://github.com/danigm/gettext-rs?branch=no-gettext#db8f12e140f0db5aabafe8dd210c7fc1520a55ff"
|
||||
dependencies = [
|
||||
"cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gio"
|
||||
version = "0.4.1"
|
||||
@ -1086,6 +1103,17 @@ dependencies = [
|
||||
"vcpkg 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "locale_config"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.3.9"
|
||||
@ -1522,6 +1550,7 @@ dependencies = [
|
||||
"fragile 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gdk 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gdk-pixbuf 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gettext-rs 0.3.0 (git+https://github.com/danigm/gettext-rs?branch=no-gettext)",
|
||||
"gio 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glib 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gstreamer 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2559,6 +2588,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum gdk-pixbuf 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c2d2199eba47ebcb9977ce28179649bdd59305ef465c4e6f9b65aaa41c24e6b5"
|
||||
"checksum gdk-pixbuf-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df6a3b73e04fafc07f5ebc083f1096a773412e627828e1103a55e921f81187d8"
|
||||
"checksum gdk-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3162ff940526ddff71bf1f630facee6b5e05d282d125ba0c4c803842819b80c3"
|
||||
"checksum gettext-rs 0.3.0 (git+https://github.com/danigm/gettext-rs?branch=no-gettext)" = "<none>"
|
||||
"checksum gettext-sys 0.19.8 (git+https://github.com/danigm/gettext-rs?branch=no-gettext)" = "<none>"
|
||||
"checksum gio 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2db9fad8f1b0d4c7338a210a6cbdf081dcc1a3c223718c698c4f313f6c288acb"
|
||||
"checksum gio-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2a57872499171d279f8577ce83837da4cae62b08dd32892236ed67ab7ea61030"
|
||||
"checksum glib 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e0be1b1432e227bcd1a9b28db9dc1474a7e7fd4227e08e16f35304f32d09b61"
|
||||
@ -2597,6 +2628,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1"
|
||||
"checksum libflate 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "7d4b4c7aff5bac19b956f693d0ea0eade8066deb092186ae954fa6ba14daab98"
|
||||
"checksum libsqlite3-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0e9eb7b8e152b6a01be6a4a2917248381875758250dc3df5d46caf9250341dda"
|
||||
"checksum locale_config 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "14fbee0e39bc2dd6a2427c4fdea66e9826cc1fd09b0a0b7550359f5f6efe1dab"
|
||||
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
|
||||
"checksum log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "61bd98ae7f7b754bc53dca7d44b604f733c6bba044ea6f41bc8d89272d8161d2"
|
||||
"checksum loggerv 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ba6b0664956d197c6e0223870c1cd1ec4117aea282b4c0bd5ab01119d31d708d"
|
||||
|
||||
17
README.md
17
README.md
@ -127,6 +127,23 @@ There are also some minor tasks tagged with `TODO:` and `FIXME:` in the source c
|
||||
|
||||
[contribution-guidelines]: https://gitlab.gnome.org/World/podcasts/blob/master/CONTRIBUTING.md
|
||||
|
||||
### Translations
|
||||
|
||||
If you want to add a new language you should update the file
|
||||
`podcasts-gtk/po/LINUGAS` and add the new lang to the list.
|
||||
|
||||
To generate .pot files you should run:
|
||||
|
||||
```
|
||||
ninja -C _build gnome-podcasts-pot
|
||||
```
|
||||
|
||||
To generate .po files you should run:
|
||||
|
||||
```
|
||||
ninja -C _build gnome-podcasts-update-po
|
||||
```
|
||||
|
||||
|
||||
## Overview
|
||||
|
||||
|
||||
@ -15,6 +15,7 @@ podcasts_version_micro = version_array[2].to_int()
|
||||
|
||||
podcasts_prefix = get_option('prefix')
|
||||
podcasts_bindir = join_paths(podcasts_prefix, get_option('bindir'))
|
||||
podcasts_localedir = join_paths(podcasts_prefix, get_option('localedir'))
|
||||
|
||||
podcasts_conf = configuration_data()
|
||||
podcasts_conf.set('BINDIR', podcasts_bindir)
|
||||
@ -23,6 +24,9 @@ datadir = get_option('datadir')
|
||||
icondir = join_paths(datadir, 'icons')
|
||||
subdir('podcasts-gtk/resources')
|
||||
|
||||
i18n = import('i18n')
|
||||
subdir('podcasts-gtk/po')
|
||||
|
||||
cargo = find_program('cargo', required: false)
|
||||
gresource = find_program('glib-compile-resources', required: false)
|
||||
cargo_vendor = find_program('cargo-vendor', required: false)
|
||||
@ -34,7 +38,7 @@ cargo_release = custom_target('cargo-build',
|
||||
output: ['gnome-podcasts'],
|
||||
install: true,
|
||||
install_dir: podcasts_bindir,
|
||||
command: [cargo_script, '@CURRENT_SOURCE_DIR@', '@OUTPUT@'])
|
||||
command: [cargo_script, '@CURRENT_SOURCE_DIR@', '@OUTPUT@', podcasts_localedir])
|
||||
|
||||
run_target('release', command: ['scripts/release.sh',
|
||||
meson.project_name() + '-' + podcasts_version
|
||||
|
||||
@ -28,6 +28,7 @@ reqwest = "0.8.6"
|
||||
serde_json = "1.0.24"
|
||||
# html2text = "0.1.8"
|
||||
html2text = { git = "https://github.com/alatiera/rust-html2text" }
|
||||
gettext-rs = { git = "https://github.com/danigm/gettext-rs", branch = "no-gettext", features = ["gettext-system"] }
|
||||
|
||||
[dependencies.gtk]
|
||||
features = ["v3_22"]
|
||||
|
||||
@ -1,3 +1,7 @@
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
|
||||
fn main() {
|
||||
@ -10,4 +14,20 @@ fn main() {
|
||||
.current_dir("resources")
|
||||
.status()
|
||||
.unwrap();
|
||||
|
||||
// Generating build globals
|
||||
let default_locales = "./podcasts-gtk/po".to_string();
|
||||
let out_dir = env::var("OUT_DIR").unwrap();
|
||||
let localedir = env::var("PODCASTS_LOCALEDIR").unwrap_or(default_locales);
|
||||
let dest_path = Path::new(&out_dir).join("build_globals.rs");
|
||||
let mut f = File::create(&dest_path).unwrap();
|
||||
|
||||
let globals = format!(
|
||||
"
|
||||
pub static LOCALEDIR: &'static str = \"{}\";
|
||||
",
|
||||
localedir
|
||||
);
|
||||
|
||||
f.write_all(&globals.into_bytes()[..]).unwrap();
|
||||
}
|
||||
|
||||
3
podcasts-gtk/po/LINGUAS
Normal file
3
podcasts-gtk/po/LINGUAS
Normal file
@ -0,0 +1,3 @@
|
||||
# please keep this list sorted alphabetically
|
||||
#
|
||||
es
|
||||
48
podcasts-gtk/po/POTFILES.in
Normal file
48
podcasts-gtk/po/POTFILES.in
Normal file
@ -0,0 +1,48 @@
|
||||
# List of source files containing translatable strings.
|
||||
# Please keep this file sorted alphabetically.
|
||||
podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml
|
||||
podcasts-gtk/resources/org.gnome.Podcasts.desktop
|
||||
podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml
|
||||
|
||||
# ui files
|
||||
podcasts-gtk/resources/gtk/shows_child.ui
|
||||
podcasts-gtk/resources/gtk/hamburger.ui
|
||||
podcasts-gtk/resources/gtk/show_widget.ui
|
||||
podcasts-gtk/resources/gtk/help-overlay.ui
|
||||
podcasts-gtk/resources/gtk/shows_view.ui
|
||||
podcasts-gtk/resources/gtk/episode_widget.ui
|
||||
podcasts-gtk/resources/gtk/prefs.ui
|
||||
podcasts-gtk/resources/gtk/home_view.ui
|
||||
podcasts-gtk/resources/gtk/secondary_menu.ui
|
||||
podcasts-gtk/resources/gtk/empty_view.ui
|
||||
podcasts-gtk/resources/gtk/show_menu.ui
|
||||
podcasts-gtk/resources/gtk/player_toolbar.ui
|
||||
podcasts-gtk/resources/gtk/empty_show.ui
|
||||
podcasts-gtk/resources/gtk/headerbar.ui
|
||||
podcasts-gtk/resources/gtk/home_episode.ui
|
||||
podcasts-gtk/resources/gtk/inapp_notif.ui
|
||||
|
||||
# rust files
|
||||
podcasts-gtk/src/manager.rs
|
||||
podcasts-gtk/src/app.rs
|
||||
podcasts-gtk/src/widgets/show_menu.rs
|
||||
podcasts-gtk/src/widgets/appnotif.rs
|
||||
podcasts-gtk/src/widgets/empty.rs
|
||||
podcasts-gtk/src/widgets/mod.rs
|
||||
podcasts-gtk/src/widgets/shows_view.rs
|
||||
podcasts-gtk/src/widgets/home_view.rs
|
||||
podcasts-gtk/src/widgets/show.rs
|
||||
podcasts-gtk/src/widgets/player.rs
|
||||
podcasts-gtk/src/widgets/aboutdialog.rs
|
||||
podcasts-gtk/src/widgets/episode.rs
|
||||
podcasts-gtk/src/headerbar.rs
|
||||
podcasts-gtk/src/static_resource.rs
|
||||
podcasts-gtk/src/utils.rs
|
||||
podcasts-gtk/src/settings.rs
|
||||
podcasts-gtk/src/main.rs
|
||||
podcasts-gtk/src/stacks/content.rs
|
||||
podcasts-gtk/src/stacks/mod.rs
|
||||
podcasts-gtk/src/stacks/home.rs
|
||||
podcasts-gtk/src/stacks/populated.rs
|
||||
podcasts-gtk/src/stacks/show.rs
|
||||
podcasts-gtk/src/prefs.rs
|
||||
432
podcasts-gtk/po/es.po
Normal file
432
podcasts-gtk/po/es.po
Normal file
@ -0,0 +1,432 @@
|
||||
# Spanish translations for gnome-podcasts package.
|
||||
# Copyright (C) 2018 THE gnome-podcasts'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the gnome-podcasts package.
|
||||
# Automatically generated, 2018.
|
||||
# Daniel Garcia Moreno <danigm@wadobo.com>, 2018.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-podcasts\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-08-02 11:42+0200\n"
|
||||
"PO-Revision-Date: 2018-08-02 11:46+0200\n"
|
||||
"Last-Translator: Daniel Garcia Moreno <danigm@wadobo.com>\n"
|
||||
"Language-Team: Español; Castellano <info@wadobo.com>\n"
|
||||
"Language: es\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Gtranslator 2.91.7\n"
|
||||
|
||||
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:15
|
||||
msgid "Top position of the last open main window"
|
||||
msgstr "Posición superior de la última ventana abierta"
|
||||
|
||||
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:19
|
||||
msgid "Left position of the last open main window"
|
||||
msgstr "Posición izquierda de la última ventana abierta"
|
||||
|
||||
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:23
|
||||
msgid "Height of the last open main window"
|
||||
msgstr "Alto de la última ventana abierta"
|
||||
|
||||
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:27
|
||||
msgid "Width of the last open main window"
|
||||
msgstr "Ancho de la última ventana abierta"
|
||||
|
||||
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:31
|
||||
msgid "Maximized state of the last open main window"
|
||||
msgstr "Estado de maximizado de la última ventana abierta"
|
||||
|
||||
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:36
|
||||
msgid "Enable or disable dark theme"
|
||||
msgstr "Activar o desactivar el tema oscuro"
|
||||
|
||||
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:41
|
||||
msgid "Whether to periodically refresh content"
|
||||
msgstr "Si refrescar el contenido periódicamente"
|
||||
|
||||
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:46
|
||||
msgid "How many periods of time to wait between automatic refreshes"
|
||||
msgstr "Cuántos periodos de tiempo a esperar entre refrescos automáticos"
|
||||
|
||||
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:50
|
||||
msgid "What period of time to wait between automatic refreshes"
|
||||
msgstr "Qué periodo de tiempo hay que esperar entre refrescos automáticos"
|
||||
|
||||
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:54
|
||||
msgid "Whether to refresh content after startup"
|
||||
msgstr "Si refrescar el contenido al iniciar"
|
||||
|
||||
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:60
|
||||
msgid "How many periods of time to wait between automatic cleanups"
|
||||
msgstr "Cuántos periodos de tiempo hay que esperar entre limpiados automáticos"
|
||||
|
||||
#: podcasts-gtk/resources/org.gnome.Podcasts.gschema.xml:64
|
||||
msgid "What period of time to wait between automatic cleanups"
|
||||
msgstr "Cuántos periodos de tiempo hay que esperar entre limpiados automáticos"
|
||||
|
||||
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop:3
|
||||
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml:4
|
||||
msgid "Podcasts"
|
||||
msgstr "Podcasts"
|
||||
|
||||
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop:4
|
||||
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml:11
|
||||
msgid "Listen to your favorite podcasts, right from your desktop."
|
||||
msgstr "Escucha tus podcasts favoritos, directamente desde tu escritorio."
|
||||
|
||||
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop:5
|
||||
msgid "org.gnome.Podcasts"
|
||||
msgstr "org.gnome.Podcasts"
|
||||
|
||||
#: podcasts-gtk/resources/org.gnome.Podcasts.desktop:11
|
||||
msgid "Podcast;RSS;"
|
||||
msgstr "Podcast;RSS;"
|
||||
|
||||
#: podcasts-gtk/resources/org.gnome.Podcasts.appdata.xml:9
|
||||
msgid "Podcast app for GNOME"
|
||||
msgstr "Aplicación de Podcast para GNOME"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/hamburger.ui:7
|
||||
msgid "_Check for new episodes"
|
||||
msgstr "_Comprobar si hay nuevos episodios"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/hamburger.ui:12
|
||||
msgid "_Import Shows"
|
||||
msgstr "_Importar programas"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/hamburger.ui:22
|
||||
msgid "_Preferences"
|
||||
msgstr "_Preferencias"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/hamburger.ui:29
|
||||
msgid "_Keyboard Shortcuts"
|
||||
msgstr "Atajos de _teclado"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/hamburger.ui:37
|
||||
msgid "_About"
|
||||
msgstr "_Acerca de"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/show_widget.ui:220
|
||||
msgid "Mark all episodes as listened"
|
||||
msgstr "Marcar todos los episodios como escuchados"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/help-overlay.ui:12
|
||||
msgid "General"
|
||||
msgstr "General"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/help-overlay.ui:18
|
||||
msgctxt "shortcut window"
|
||||
msgid "Check for new episodes"
|
||||
msgstr "Comprobar si hay nuevos episodios"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/help-overlay.ui:25
|
||||
msgctxt "shortcut window"
|
||||
msgid "Preferences"
|
||||
msgstr "Preferencias"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/help-overlay.ui:32
|
||||
msgctxt "shortcut window"
|
||||
msgid "Quit the application"
|
||||
msgstr "Salir de la aplicación"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/episode_widget.ui:55
|
||||
#: podcasts-gtk/resources/gtk/player_toolbar.ui:160
|
||||
msgid "Episode Title"
|
||||
msgstr "Título del episodio"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/episode_widget.ui:78
|
||||
msgid "3 Jan"
|
||||
msgstr "3 Jan"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/episode_widget.ui:95
|
||||
#: podcasts-gtk/resources/gtk/episode_widget.ui:128
|
||||
msgid "·"
|
||||
msgstr "·"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/episode_widget.ui:111
|
||||
msgid "42 min"
|
||||
msgstr "42 min"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/episode_widget.ui:144
|
||||
msgid "0 MB"
|
||||
msgstr "0 MB"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/episode_widget.ui:161
|
||||
msgid "/"
|
||||
msgstr "/"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/episode_widget.ui:178
|
||||
msgid "Calculating episode size..."
|
||||
msgstr "Calculando tamaño del episodio..."
|
||||
|
||||
#: podcasts-gtk/resources/gtk/episode_widget.ui:213
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/episode_widget.ui:231
|
||||
msgid "Download this episode"
|
||||
msgstr "Descargar este episodio"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/episode_widget.ui:255
|
||||
msgid "Play this episode"
|
||||
msgstr "Reproducir este episodio"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/prefs.ui:14
|
||||
msgid "Preferences"
|
||||
msgstr "Preferencias"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/prefs.ui:48
|
||||
msgid "Appearance"
|
||||
msgstr "Aspecto"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/prefs.ui:92
|
||||
msgid "Dark Theme"
|
||||
msgstr "Tema oscuro"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/prefs.ui:138
|
||||
msgid "Delete played episodes"
|
||||
msgstr "Eliminar episodios reproducidos"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/prefs.ui:183
|
||||
msgid "After"
|
||||
msgstr "Después"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/home_view.ui:94
|
||||
msgid "Today"
|
||||
msgstr "Hoy"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/home_view.ui:150
|
||||
msgid "Yesterday"
|
||||
msgstr "Ayer"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/home_view.ui:206
|
||||
msgid "This Week"
|
||||
msgstr "Esta semana"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/home_view.ui:262
|
||||
msgid "This Month"
|
||||
msgstr "Este mes"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/home_view.ui:319
|
||||
msgid "Older"
|
||||
msgstr "Antiguo"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/secondary_menu.ui:7
|
||||
msgid "_Mark all episodes as played"
|
||||
msgstr "_Marcar todos los episodios como reproducidos"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/secondary_menu.ui:11
|
||||
msgid "_Website"
|
||||
msgstr "Página _Web"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/secondary_menu.ui:15
|
||||
msgid "_Unsubscribe"
|
||||
msgstr "_Cancelar suscripción"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/empty_view.ui:66
|
||||
msgid "Get some shows"
|
||||
msgstr "Consigue algún programa"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/empty_view.ui:103
|
||||
msgid "Add new shows via feed URL"
|
||||
msgstr "Añadir nuevo programa a través de canal URL"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/empty_view.ui:132
|
||||
msgid "Import shows from another device"
|
||||
msgstr "Importar programas de otro dispositivo"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/show_menu.ui:23
|
||||
msgid "Open Website"
|
||||
msgstr "Abrir Web"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/show_menu.ui:36
|
||||
msgid "Mark all as played"
|
||||
msgstr "Marcar como reproducido"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/show_menu.ui:61
|
||||
msgid "Unsubscribe"
|
||||
msgstr "Cancelar suscripción"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/player_toolbar.ui:44
|
||||
msgid "Rewind 10 seconds"
|
||||
msgstr "Atrás 10 segundos"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/player_toolbar.ui:59
|
||||
msgid "Play"
|
||||
msgstr "Reproducir"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/player_toolbar.ui:75
|
||||
msgid "Pause"
|
||||
msgstr "Pausa"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/player_toolbar.ui:91
|
||||
msgid "Fast Forward 10 seconds"
|
||||
msgstr "Adelante 10 segundos"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/player_toolbar.ui:141
|
||||
#: podcasts-gtk/resources/gtk/headerbar.ui:247
|
||||
msgid "Show Title"
|
||||
msgstr "Título de Programa"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/player_toolbar.ui:257
|
||||
msgid "Change the Playback speed"
|
||||
msgstr "Cambiar velocidad de reproducción"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/player_toolbar.ui:272
|
||||
#: podcasts-gtk/resources/gtk/player_toolbar.ui:352
|
||||
msgid "1.00x"
|
||||
msgstr "1.00x"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/player_toolbar.ui:316
|
||||
msgid "1.50x"
|
||||
msgstr "1.50x"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/player_toolbar.ui:320
|
||||
msgid "1.5 speed rate"
|
||||
msgstr "velocidad 1.5"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/player_toolbar.ui:334
|
||||
msgid "1.25x"
|
||||
msgstr "1.25x"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/player_toolbar.ui:338
|
||||
msgid "1.25 speed rate"
|
||||
msgstr "velocidad 1.25"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/player_toolbar.ui:356
|
||||
msgid "Normal speed"
|
||||
msgstr "Velocidad normal"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/empty_show.ui:35
|
||||
msgid "This show does not have any episodes"
|
||||
msgstr "Este programa no tiene episodios todavía"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/empty_show.ui:51
|
||||
msgid "If you think this is an Error, Plese consider opening a bug report."
|
||||
msgstr ""
|
||||
"Si crees que esto es un error, por favor, considera abrir un bug report."
|
||||
|
||||
#: podcasts-gtk/resources/gtk/headerbar.ui:35
|
||||
#: podcasts-gtk/resources/gtk/headerbar.ui:155
|
||||
msgid "Add a new feed"
|
||||
msgstr "Añadir un nuevo canal"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/headerbar.ui:56
|
||||
msgid "Enter feed address to add"
|
||||
msgstr "Introduce la dirección del canal a añadir"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/headerbar.ui:92
|
||||
msgid "Add"
|
||||
msgstr "Añadir"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/headerbar.ui:136
|
||||
msgid "You are already subscribed to that feed!"
|
||||
msgstr "¡Ya estás suscrito a este canal!"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/headerbar.ui:176
|
||||
msgid "Back"
|
||||
msgstr "Atrás"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/headerbar.ui:212
|
||||
msgid "Fetching new episodes"
|
||||
msgstr "Obteniendo nuevos episodios"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/inapp_notif.ui:35
|
||||
msgid "An in-app action notification"
|
||||
msgstr "Una notificación de acción in-app"
|
||||
|
||||
#: podcasts-gtk/resources/gtk/inapp_notif.ui:72
|
||||
msgid "Undo"
|
||||
msgstr "Deshacer"
|
||||
|
||||
#: podcasts-gtk/src/widgets/show_menu.rs:141
|
||||
msgid "Marked all episodes as listened"
|
||||
msgstr "Marcar todos los episodios como escuchados"
|
||||
|
||||
#: podcasts-gtk/src/widgets/show_menu.rs:146
|
||||
msgid "Unsubscribed from {}"
|
||||
msgstr "Suscripción cancelada para {}"
|
||||
|
||||
#. sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
|
||||
#: podcasts-gtk/src/widgets/player.rs:300
|
||||
msgid "The media player was unable to execute an action."
|
||||
msgstr "El reproductor no ha podido reproducir una acción."
|
||||
|
||||
#: podcasts-gtk/src/widgets/aboutdialog.rs:26
|
||||
msgid "Podcast Client for the GNOME Desktop."
|
||||
msgstr "Aplicación de Podcast para el escritorio GNOME."
|
||||
|
||||
#: podcasts-gtk/src/widgets/aboutdialog.rs:27
|
||||
msgid "© 2017, 2018 Jordan Petridis"
|
||||
msgstr "© 2017, 2018 Jordan Petridis"
|
||||
|
||||
#: podcasts-gtk/src/widgets/aboutdialog.rs:41
|
||||
msgid "translator-credits"
|
||||
msgstr "\"Daniel García Moreno <danigm@wadobo.com>\""
|
||||
|
||||
#. Set the label and show them.
|
||||
#: podcasts-gtk/src/widgets/episode.rs:128
|
||||
msgid "{} min"
|
||||
msgstr "{} min"
|
||||
|
||||
#: podcasts-gtk/src/headerbar.rs:123
|
||||
msgid "You are already subscribed to this Show"
|
||||
msgstr "Ya estás suscrito a este programa"
|
||||
|
||||
#: podcasts-gtk/src/headerbar.rs:131
|
||||
msgid "Invalid url"
|
||||
msgstr "Url no válida"
|
||||
|
||||
#: podcasts-gtk/src/utils.rs:330
|
||||
msgid "Select the file from which to you want to Import Shows."
|
||||
msgstr "Selecciona el fichero desde el cual quieres importar programas."
|
||||
|
||||
#: podcasts-gtk/src/utils.rs:333
|
||||
msgid "_Import"
|
||||
msgstr "_Importar"
|
||||
|
||||
#: podcasts-gtk/src/utils.rs:342
|
||||
msgid "OPML file"
|
||||
msgstr "fichero OPML"
|
||||
|
||||
#: podcasts-gtk/src/utils.rs:360
|
||||
msgid "Failed to parse the Imported file"
|
||||
msgstr "Fallo al leer el fichero importado"
|
||||
|
||||
#: podcasts-gtk/src/utils.rs:365
|
||||
msgid "Selected File could not be accessed."
|
||||
msgstr "El fichero seleccionado no es accesible."
|
||||
|
||||
#: podcasts-gtk/src/stacks/content.rs:29
|
||||
msgid "New"
|
||||
msgstr "Nuevo"
|
||||
|
||||
#: podcasts-gtk/src/stacks/content.rs:30
|
||||
msgid "Shows"
|
||||
msgstr "Programas"
|
||||
|
||||
#: podcasts-gtk/src/prefs.rs:58
|
||||
msgid "Seconds"
|
||||
msgstr "Segundos"
|
||||
|
||||
#: podcasts-gtk/src/prefs.rs:58
|
||||
msgid "Minutes"
|
||||
msgstr "Minutos"
|
||||
|
||||
#: podcasts-gtk/src/prefs.rs:58
|
||||
msgid "Hours"
|
||||
msgstr "Horas"
|
||||
|
||||
#: podcasts-gtk/src/prefs.rs:59
|
||||
msgid "Days"
|
||||
msgstr "Días"
|
||||
|
||||
#: podcasts-gtk/src/prefs.rs:59
|
||||
msgid "Weeks"
|
||||
msgstr "Semanas"
|
||||
|
||||
#~ msgid "Jordan Petridis and others"
|
||||
#~ msgstr "Jordan Petridis y otros"
|
||||
4
podcasts-gtk/po/meson.build
Normal file
4
podcasts-gtk/po/meson.build
Normal file
@ -0,0 +1,4 @@
|
||||
i18n.gettext(meson.project_name(),
|
||||
args: ['--keyword=i18n', '--keyword=i18n_f', '--keyword=i18n_k',
|
||||
'--keyword=ni18n:1,2', '--keyword=ni18n_f:1,2', '--keyword=ni18n_k:1,2'],
|
||||
preset: 'glib')
|
||||
@ -5,6 +5,8 @@ use glib::{self, Variant};
|
||||
use gtk;
|
||||
use gtk::prelude::*;
|
||||
|
||||
use gettextrs::{bindtextdomain, setlocale, textdomain, LocaleCategory};
|
||||
|
||||
use crossbeam_channel::{unbounded, Receiver, Sender};
|
||||
use fragile::Fragile;
|
||||
use podcasts_data::Show;
|
||||
@ -25,6 +27,8 @@ use std::sync::Arc;
|
||||
|
||||
pub const APP_ID: &str = "org.gnome.Podcasts";
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/build_globals.rs"));
|
||||
|
||||
/// Creates an action named `name` in the action map `T with the handler `F`
|
||||
fn action<T, F>(thing: &T, name: &str, action: F)
|
||||
where
|
||||
@ -304,6 +308,11 @@ impl App {
|
||||
}
|
||||
|
||||
pub fn run() {
|
||||
// Set up the textdomain for gettext
|
||||
setlocale(LocaleCategory::LcAll, "");
|
||||
bindtextdomain("gnome-podcasts", LOCALEDIR);
|
||||
textdomain("gnome-podcasts");
|
||||
|
||||
let application = gtk::Application::new(APP_ID, gio::ApplicationFlags::empty())
|
||||
.expect("Application Initialization failed...");
|
||||
|
||||
|
||||
@ -15,6 +15,8 @@ use utils::{itunes_to_rss, refresh};
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
use i18n::i18n;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
// TODO: Factor out the hamburger menu
|
||||
// TODO: Make a proper state machine for the headerbar states
|
||||
@ -118,7 +120,7 @@ impl AddPopover {
|
||||
} else {
|
||||
self.add.set_sensitive(false);
|
||||
self.result
|
||||
.set_label("You are already subscribed to this Show");
|
||||
.set_label(i18n("You are already subscribed to this Show").as_str());
|
||||
self.result.show();
|
||||
}
|
||||
Ok(())
|
||||
@ -126,7 +128,7 @@ impl AddPopover {
|
||||
Err(err) => {
|
||||
self.add.set_sensitive(false);
|
||||
if !url.is_empty() {
|
||||
self.result.set_label("Invalid url");
|
||||
self.result.set_label(i18n("Invalid url").as_str());
|
||||
self.result.show();
|
||||
error!("Error: {}", err);
|
||||
} else {
|
||||
|
||||
135
podcasts-gtk/src/i18n.rs
Normal file
135
podcasts-gtk/src/i18n.rs
Normal file
@ -0,0 +1,135 @@
|
||||
extern crate gettextrs;
|
||||
extern crate regex;
|
||||
use self::gettextrs::gettext;
|
||||
use self::gettextrs::ngettext;
|
||||
use self::regex::Captures;
|
||||
use self::regex::Regex;
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn freplace(input: String, args: &[&str]) -> String {
|
||||
let mut parts = input.split("{}");
|
||||
let mut output = parts.next().unwrap_or("").to_string();
|
||||
for (p, a) in parts.zip(args.iter()) {
|
||||
output += &(a.to_string() + &p.to_string());
|
||||
}
|
||||
output
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn kreplace(input: String, kwargs: &[(&str, &str)]) -> String {
|
||||
let mut s = input.clone();
|
||||
for (k, v) in kwargs {
|
||||
if let Ok(re) = Regex::new(&format!("\\{{{}\\}}", k)) {
|
||||
s = re
|
||||
.replace_all(&s, |_: &Captures| v.to_string().clone())
|
||||
.to_string();
|
||||
}
|
||||
}
|
||||
|
||||
s
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn i18n(format: &str) -> String {
|
||||
gettext(format)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn i18n_f(format: &str, args: &[&str]) -> String {
|
||||
let s = gettext(format);
|
||||
freplace(s, args)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn i18n_k(format: &str, kwargs: &[(&str, &str)]) -> String {
|
||||
let s = gettext(format);
|
||||
kreplace(s, kwargs)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn ni18n(single: &str, multiple: &str, number: u32) -> String {
|
||||
ngettext(single, multiple, number)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn ni18n_f(single: &str, multiple: &str, number: u32, args: &[&str]) -> String {
|
||||
let s = ngettext(single, multiple, number);
|
||||
freplace(s, args)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn ni18n_k(single: &str, multiple: &str, number: u32, kwargs: &[(&str, &str)]) -> String {
|
||||
let s = ngettext(single, multiple, number);
|
||||
kreplace(s, kwargs)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
#[test]
|
||||
fn test_i18n() {
|
||||
let out = i18n("translate1");
|
||||
assert_eq!(out, "translate1");
|
||||
|
||||
let out = ni18n("translate1", "translate multi", 1);
|
||||
assert_eq!(out, "translate1");
|
||||
let out = ni18n("translate1", "translate multi", 2);
|
||||
assert_eq!(out, "translate multi");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_i18n_f() {
|
||||
let out = i18n_f("{} param", &["one"]);
|
||||
assert_eq!(out, "one param");
|
||||
|
||||
let out = i18n_f("middle {} param", &["one"]);
|
||||
assert_eq!(out, "middle one param");
|
||||
|
||||
let out = i18n_f("end {}", &["one"]);
|
||||
assert_eq!(out, "end one");
|
||||
|
||||
let out = i18n_f("multiple {} and {}", &["one", "two"]);
|
||||
assert_eq!(out, "multiple one and two");
|
||||
|
||||
let out = ni18n_f("singular {} and {}", "plural {} and {}", 2, &["one", "two"]);
|
||||
assert_eq!(out, "plural one and two");
|
||||
let out = ni18n_f("singular {} and {}", "plural {} and {}", 1, &["one", "two"]);
|
||||
assert_eq!(out, "singular one and two");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_i18n_k() {
|
||||
let out = i18n_k("{one} param", &[("one", "one")]);
|
||||
assert_eq!(out, "one param");
|
||||
|
||||
let out = i18n_k("middle {one} param", &[("one", "one")]);
|
||||
assert_eq!(out, "middle one param");
|
||||
|
||||
let out = i18n_k("end {one}", &[("one", "one")]);
|
||||
assert_eq!(out, "end one");
|
||||
|
||||
let out = i18n_k("multiple {one} and {two}", &[("one", "1"), ("two", "two")]);
|
||||
assert_eq!(out, "multiple 1 and two");
|
||||
|
||||
let out = i18n_k("multiple {two} and {one}", &[("one", "1"), ("two", "two")]);
|
||||
assert_eq!(out, "multiple two and 1");
|
||||
|
||||
let out = i18n_k("multiple {one} and {one}", &[("one", "1"), ("two", "two")]);
|
||||
assert_eq!(out, "multiple 1 and 1");
|
||||
|
||||
let out = ni18n_k(
|
||||
"singular {one} and {two}",
|
||||
"plural {one} and {two}",
|
||||
1,
|
||||
&[("one", "1"), ("two", "two")],
|
||||
);
|
||||
assert_eq!(out, "singular 1 and two");
|
||||
let out = ni18n_k(
|
||||
"singular {one} and {two}",
|
||||
"plural {one} and {two}",
|
||||
2,
|
||||
&[("one", "1"), ("two", "two")],
|
||||
);
|
||||
assert_eq!(out, "plural 1 and two");
|
||||
}
|
||||
}
|
||||
@ -73,6 +73,8 @@ extern crate reqwest;
|
||||
extern crate serde_json;
|
||||
extern crate url;
|
||||
|
||||
extern crate gettextrs;
|
||||
|
||||
use log::Level;
|
||||
|
||||
use gtk::prelude::*;
|
||||
@ -108,6 +110,8 @@ mod settings;
|
||||
mod static_resource;
|
||||
mod utils;
|
||||
|
||||
mod i18n;
|
||||
|
||||
use app::App;
|
||||
|
||||
fn main() {
|
||||
|
||||
@ -3,6 +3,8 @@ use gio::{Settings, SettingsExt};
|
||||
use gtk;
|
||||
use gtk::prelude::*;
|
||||
|
||||
use i18n::i18n;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Prefs {
|
||||
dialog: gtk::Window,
|
||||
@ -53,7 +55,13 @@ impl Prefs {
|
||||
let cleanup_p = settings.get_string("cleanup-age-period").unwrap();
|
||||
let mut cleanup_pos = 0;
|
||||
let store = gtk::ListStore::new(&[gtk::Type::String]);
|
||||
for (i, item) in ["Seconds", "Minutes", "Hours", "Days", "Weeks"]
|
||||
for (i, item) in [
|
||||
i18n("Seconds"),
|
||||
i18n("Minutes"),
|
||||
i18n("Hours"),
|
||||
i18n("Days"),
|
||||
i18n("Weeks"),
|
||||
]
|
||||
.iter()
|
||||
.enumerate()
|
||||
{
|
||||
|
||||
@ -10,6 +10,8 @@ use stacks::{HomeStack, ShowStack};
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use i18n::i18n;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Content {
|
||||
stack: gtk::Stack,
|
||||
@ -24,8 +26,8 @@ impl Content {
|
||||
let home = Rc::new(RefCell::new(HomeStack::new(sender.clone())?));
|
||||
let shows = Rc::new(RefCell::new(ShowStack::new(sender.clone())));
|
||||
|
||||
stack.add_titled(&home.borrow().get_stack(), "home", "New");
|
||||
stack.add_titled(&shows.borrow().get_stack(), "shows", "Shows");
|
||||
stack.add_titled(&home.borrow().get_stack(), "home", &i18n("New"));
|
||||
stack.add_titled(&shows.borrow().get_stack(), "shows", &i18n("Shows"));
|
||||
|
||||
let con = Content {
|
||||
stack,
|
||||
|
||||
@ -29,6 +29,8 @@ use std::sync::{Arc, Mutex, RwLock};
|
||||
|
||||
use app::Action;
|
||||
|
||||
use i18n::i18n;
|
||||
|
||||
/// Lazy evaluates and loads widgets to the parent `container` widget.
|
||||
///
|
||||
/// Accepts an `IntoIterator`, `data`, as the source from which each widget
|
||||
@ -325,10 +327,10 @@ pub fn on_import_clicked(window: >k::ApplicationWindow, sender: &Sender<Action
|
||||
// TODO: It might be better to use a FileChooserNative widget.
|
||||
// Create the FileChooser Dialog
|
||||
let dialog = FileChooserNative::new(
|
||||
Some("Select the file from which to you want to Import Shows."),
|
||||
Some(i18n("Select the file from which to you want to Import Shows.").as_str()),
|
||||
Some(window),
|
||||
FileChooserAction::Open,
|
||||
Some("_Import"),
|
||||
Some(i18n("_Import").as_str()),
|
||||
None,
|
||||
);
|
||||
|
||||
@ -337,7 +339,7 @@ pub fn on_import_clicked(window: >k::ApplicationWindow, sender: &Sender<Action
|
||||
|
||||
// Set a filter to show only xml files
|
||||
let filter = FileFilter::new();
|
||||
FileFilterExt::set_name(&filter, Some("OPML file"));
|
||||
FileFilterExt::set_name(&filter, Some(i18n("OPML file").as_str()));
|
||||
filter.add_mime_type("application/xml");
|
||||
filter.add_mime_type("text/xml");
|
||||
dialog.add_filter(&filter);
|
||||
@ -355,12 +357,12 @@ pub fn on_import_clicked(window: >k::ApplicationWindow, sender: &Sender<Action
|
||||
// Refresh the succesfully parsed feeds to index them
|
||||
refresh(Some(sources), sender)
|
||||
} else {
|
||||
let text = String::from("Failed to parse the Imported file");
|
||||
let text = i18n("Failed to parse the Imported file");
|
||||
sender.send(Action::ErrorNotification(text));
|
||||
}
|
||||
}))
|
||||
} else {
|
||||
let text = String::from("Selected File could not be accessed.");
|
||||
let text = i18n("Selected File could not be accessed.");
|
||||
sender.send(Action::ErrorNotification(text));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,8 @@ use app::APP_ID;
|
||||
use gtk;
|
||||
use gtk::prelude::*;
|
||||
|
||||
use i18n::i18n;
|
||||
|
||||
// Totally copied it from fractal.
|
||||
// https://gitlab.gnome.org/danigm/fractal/blob/503e311e22b9d7540089d735b92af8e8f93560c5/fractal-gtk/src/app.rs#L1883-1912
|
||||
/// Given a `window` create and attach an `gtk::AboutDialog` to it.
|
||||
@ -21,8 +23,8 @@ pub fn about_dialog(window: >k::ApplicationWindow) {
|
||||
|
||||
let dialog = gtk::AboutDialog::new();
|
||||
dialog.set_logo_icon_name(APP_ID);
|
||||
dialog.set_comments("Podcast Client for the GNOME Desktop.");
|
||||
dialog.set_copyright("© 2017, 2018 Jordan Petridis");
|
||||
dialog.set_comments(i18n("Podcast Client for the GNOME Desktop.").as_str());
|
||||
dialog.set_copyright(i18n("© 2017, 2018 Jordan Petridis").as_str());
|
||||
dialog.set_license_type(gtk::License::Gpl30);
|
||||
dialog.set_modal(true);
|
||||
// TODO: make it show it fetches the commit hash from which it was built
|
||||
@ -36,6 +38,7 @@ pub fn about_dialog(window: >k::ApplicationWindow) {
|
||||
|
||||
dialog.set_artists(&["Tobias Bernard", "Sam Hewitt"]);
|
||||
dialog.set_authors(authors);
|
||||
dialog.set_translator_credits(i18n("translator-credits").as_str());
|
||||
|
||||
dialog.connect_response(|dlg, _| dlg.destroy());
|
||||
|
||||
|
||||
@ -21,6 +21,8 @@ use std::cell::RefCell;
|
||||
use std::rc::{Rc, Weak};
|
||||
use std::sync::{Arc, Mutex, TryLockError};
|
||||
|
||||
use i18n::i18n_f;
|
||||
|
||||
lazy_static! {
|
||||
static ref SIZE_OPTS: Arc<size_opts::FileSizeOpts> = {
|
||||
// Declare a custom humansize option struct
|
||||
@ -123,7 +125,8 @@ impl InfoLabels {
|
||||
// If the lenght is 1 or more minutes
|
||||
if minutes != 0 {
|
||||
// Set the label and show them.
|
||||
self.duration.set_text(&format!("{} min", minutes));
|
||||
self.duration
|
||||
.set_text(&i18n_f("{} min", &[&minutes.to_string()]));
|
||||
self.duration.show();
|
||||
self.separator1.show();
|
||||
return;
|
||||
|
||||
@ -23,6 +23,8 @@ use std::ops::Deref;
|
||||
use std::path::Path;
|
||||
use std::rc::Rc;
|
||||
|
||||
use i18n::i18n;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum SeekDirection {
|
||||
Backwards,
|
||||
@ -295,7 +297,7 @@ impl PlayerWidget {
|
||||
// Log gst errors.
|
||||
s.player.connect_error(clone!(sender => move |_, _error| {
|
||||
// sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
|
||||
let s = "The media player was unable to execute an action.".into();
|
||||
let s = i18n("The media player was unable to execute an action.");
|
||||
sender.send(Action::ErrorNotification(s));
|
||||
}));
|
||||
|
||||
|
||||
@ -17,6 +17,8 @@ use widgets::appnotif::{InAppNotification, UndoState};
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use i18n::{i18n, i18n_f};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ShowMenu {
|
||||
pub container: gtk::PopoverMenu,
|
||||
@ -136,12 +138,12 @@ pub fn mark_all_notif(pd: Arc<Show>, sender: &Sender<Action>) -> InAppNotificati
|
||||
});
|
||||
|
||||
let undo_callback = clone!(sender => move || sender.send(Action::RefreshWidgetIfSame(id)));
|
||||
let text = "Marked all episodes as listened";
|
||||
InAppNotification::new(text, callback, undo_callback, UndoState::Shown)
|
||||
let text = i18n("Marked all episodes as listened");
|
||||
InAppNotification::new(&text, callback, undo_callback, UndoState::Shown)
|
||||
}
|
||||
|
||||
pub fn remove_show_notif(pd: Arc<Show>, sender: Sender<Action>) -> InAppNotification {
|
||||
let text = format!("Unsubscribed from {}", pd.title());
|
||||
let text = i18n_f("Unsubscribed from {}", &[pd.title()]);
|
||||
|
||||
let res = utils::ignore_show(pd.id());
|
||||
debug_assert!(res.is_ok());
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
export CARGO_HOME=$1/target/cargo-home
|
||||
export RUSTFLAGS="--cfg rayon_unstable"
|
||||
export PODCASTS_LOCALEDIR="$3"
|
||||
|
||||
if [[ $DEBUG = true ]]
|
||||
then
|
||||
|
||||
Loading…
Reference in New Issue
Block a user