feat: User-Interface I18n System (#728)
**What is the goal of this PR?** This PR introduces Internationalization (i18n) support, enabling users to switch the UI language dynamically. **What changes are included?** - Core Logic: Added I18n class (`lib/I18n/I18n.h/cpp`) to manage language state and string retrieval. - Data Structures: - `lib/I18n/I18nStrings.h/cpp`: Static string arrays for each supported language. - `lib/I18n/I18nKeys.h`: Enum definitions for type-safe string access. - `lib/I18n/translations.csv`: single source of truth. - Documentation: Added `docs/i18n.md` detailing the workflow for developers and translators. - New Settings activity: `src/activities/settings/LanguageSelectActivity.h/cpp` This implementation (building on concepts from #505) prioritizes performance and memory efficiency. The core approach is to store all localized strings for each language in dedicated arrays and access them via enums. This provides O(1) access with zero runtime overhead, and avoids the heap allocations, hashing, and collision handling required by `std::map` or `std::unordered_map`. The main trade-off is that enums and string arrays must remain perfectly synchronized—any mismatch would result in incorrect strings being displayed in the UI. To eliminate this risk, I added a Python script that automatically generates `I18nStrings.h/.cpp` and `I18nKeys.h` from a CSV file, which will serve as the single source of truth for all translations. The full design and workflow are documented in `docs/i18n.md`. - [x] Python script `generate_i18n.py` to auto-generate C++ files from CSV - [x] Populate translations.csv with initial translations. Currently available translations: English, Español, Français, Deutsch, Čeština, Português (Brasil), Русский, Svenska. Thanks, community! **Status:** EDIT: ready to be merged. As a proof of concept, the SPANISH strings currently mirror the English ones, but are fully uppercased. --- Did you use AI tools to help write this code? _**< PARTIALLY >**_ I used AI for the black work of replacing strings with I18n references across the project, and for generating the documentation. EDIT: also some help with merging changes from master. --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: yeyeto2788 <juanernestobiondi@gmail.com>
This commit is contained in:
317
lib/I18n/translations/french.yaml
Normal file
317
lib/I18n/translations/french.yaml
Normal file
@@ -0,0 +1,317 @@
|
||||
_language_name: "Français"
|
||||
_language_code: "FRENCH"
|
||||
_order: "2"
|
||||
|
||||
STR_CROSSPOINT: "CrossPoint"
|
||||
STR_BOOTING: "DÉMARRAGE EN COURS"
|
||||
STR_SLEEPING: "VEILLE"
|
||||
STR_ENTERING_SLEEP: "Mise en veille…"
|
||||
STR_BROWSE_FILES: "Fichiers"
|
||||
STR_FILE_TRANSFER: "Transfert"
|
||||
STR_SETTINGS_TITLE: "Réglages"
|
||||
STR_CALIBRE_LIBRARY: "Bibliothèque Calibre"
|
||||
STR_CONTINUE_READING: "Continuer la lecture"
|
||||
STR_NO_OPEN_BOOK: "Aucun livre ouvert"
|
||||
STR_START_READING: "Lisez votre premier livre ci-dessous"
|
||||
STR_BOOKS: "Livres"
|
||||
STR_NO_BOOKS_FOUND: "Dossier vide"
|
||||
STR_SELECT_CHAPTER: "Choix du chapitre"
|
||||
STR_NO_CHAPTERS: "Aucun chapitre"
|
||||
STR_END_OF_BOOK: "Fin du livre"
|
||||
STR_EMPTY_CHAPTER: "Chapitre vide"
|
||||
STR_INDEXING: "Indexation en cours…"
|
||||
STR_MEMORY_ERROR: "Erreur de mémoire"
|
||||
STR_PAGE_LOAD_ERROR: "Erreur de chargement"
|
||||
STR_EMPTY_FILE: "Fichier vide"
|
||||
STR_OUT_OF_BOUNDS: "Dépassement de mémoire"
|
||||
STR_LOADING: "Chargement…"
|
||||
STR_LOAD_XTC_FAILED: "Erreur de chargement du fichier XTC"
|
||||
STR_LOAD_TXT_FAILED: "Erreur de chargement du fichier TXT"
|
||||
STR_LOAD_EPUB_FAILED: "Erreur de chargement du fichier EPUB"
|
||||
STR_SD_CARD_ERROR: "Carte mémoire absente"
|
||||
STR_WIFI_NETWORKS: "Réseaux WiFi"
|
||||
STR_NO_NETWORKS: "Aucun réseau"
|
||||
STR_NETWORKS_FOUND: "%zu réseaux"
|
||||
STR_SCANNING: "Recherche de réseaux en cours…"
|
||||
STR_CONNECTING: "Connexion en cours…"
|
||||
STR_CONNECTED: "Connecté !"
|
||||
STR_CONNECTION_FAILED: "Échec de la connexion"
|
||||
STR_CONNECTION_TIMEOUT: "Délai de connexion dépassé"
|
||||
STR_FORGET_NETWORK: "Oublier ce réseau ?"
|
||||
STR_SAVE_PASSWORD: "Enregistrer le mot de passe ?"
|
||||
STR_REMOVE_PASSWORD: "Supprimer le mot de passe enregistré ?"
|
||||
STR_PRESS_OK_SCAN: "Appuyez sur OK pour détecter à nouveau"
|
||||
STR_PRESS_ANY_CONTINUE: "Appuyez sur une touche pour continuer"
|
||||
STR_SELECT_HINT: "GAUCHE/DROITE: Sélectionner | OK: Valider"
|
||||
STR_HOW_CONNECT: "Comment voulez-vous vous connecter ?"
|
||||
STR_JOIN_NETWORK: "Connexion à un réseau"
|
||||
STR_CREATE_HOTSPOT: "Créer un point d’accès"
|
||||
STR_JOIN_DESC: "Se connecter à un réseau WiFi existant"
|
||||
STR_HOTSPOT_DESC: "Créer un réseau WiFi accessible depuis d’autres appareils"
|
||||
STR_STARTING_HOTSPOT: "Création du point d’accès en cours…"
|
||||
STR_HOTSPOT_MODE: "Mode point d’accès"
|
||||
STR_CONNECT_WIFI_HINT: "Connectez un appareil à ce réseau WiFi"
|
||||
STR_OPEN_URL_HINT: "Ouvrez cette URL dans votre navigateur"
|
||||
STR_OR_HTTP_PREFIX: "ou http://"
|
||||
STR_SCAN_QR_HINT: "ou scannez le QR code avec votre téléphone"
|
||||
STR_CALIBRE_WIRELESS: "Connexion à Calibre sans fil"
|
||||
STR_CALIBRE_WEB_URL: "URL Web Calibre"
|
||||
STR_CONNECT_WIRELESS: "Se connecter comme appareil sans fil"
|
||||
STR_NETWORK_LEGEND: "* = Sécurisé | + = Sauvegardé"
|
||||
STR_MAC_ADDRESS: "Adresse MAC :"
|
||||
STR_CHECKING_WIFI: "Vérification du réseau WiFi..."
|
||||
STR_ENTER_WIFI_PASSWORD: "Entrez le mot de passe WiFi"
|
||||
STR_ENTER_TEXT: "Entrez le texte"
|
||||
STR_TO_PREFIX: "à "
|
||||
STR_CALIBRE_DISCOVERING: "Recherche de Calibre en cours…"
|
||||
STR_CALIBRE_CONNECTING_TO: "Connexion à "
|
||||
STR_CALIBRE_CONNECTED_TO: "Connecté à "
|
||||
STR_CALIBRE_WAITING_COMMANDS: "En attente de commandes…"
|
||||
STR_CONNECTION_FAILED_RETRYING: "(Échec de la connexion, nouvelle tentative)"
|
||||
STR_CALIBRE_DISCONNECTED: "Calibre déconnecté"
|
||||
STR_CALIBRE_WAITING_TRANSFER: "En attente de transfert…"
|
||||
STR_CALIBRE_TRANSFER_HINT: "Si le transfert échoue, activez\\n’Ignorer l’espace libre’ dans les\\nparamètres du plugin SmartDevice de Calibre."
|
||||
STR_CALIBRE_RECEIVING: "Réception : "
|
||||
STR_CALIBRE_RECEIVED: "Reçus : "
|
||||
STR_CALIBRE_WAITING_MORE: "En attente de données supplémentaires…"
|
||||
STR_CALIBRE_FAILED_CREATE_FILE: "Échec de la création du fichier"
|
||||
STR_CALIBRE_PASSWORD_REQUIRED: "Mot de passe requis"
|
||||
STR_CALIBRE_TRANSFER_INTERRUPTED: "Transfert interrompu"
|
||||
STR_CALIBRE_INSTRUCTION_1: "1) Installer le plugin CrossPoint Reader"
|
||||
STR_CALIBRE_INSTRUCTION_2: "2) Se connecter au même réseau WiFi"
|
||||
STR_CALIBRE_INSTRUCTION_3: "3) Dans Calibre : ‘Envoyer vers l’appareil’"
|
||||
STR_CALIBRE_INSTRUCTION_4: "“Gardez cet écran ouvert pendant le transfert”"
|
||||
STR_CAT_DISPLAY: "Affichage"
|
||||
STR_CAT_READER: "Lecteur"
|
||||
STR_CAT_CONTROLS: "Commandes"
|
||||
STR_CAT_SYSTEM: "Système"
|
||||
STR_SLEEP_SCREEN: "Écran de veille"
|
||||
STR_SLEEP_COVER_MODE: "Mode d’image de l’écran de veille"
|
||||
STR_STATUS_BAR: "Barre d’état"
|
||||
STR_HIDE_BATTERY: "Masquer % batterie"
|
||||
STR_EXTRA_SPACING: "Espacement des paragraphes"
|
||||
STR_TEXT_AA: "Lissage du texte"
|
||||
STR_SHORT_PWR_BTN: "Appui court bout. alim."
|
||||
STR_ORIENTATION: "Orientation de lecture"
|
||||
STR_FRONT_BTN_LAYOUT: "Disposition des boutons avant"
|
||||
STR_SIDE_BTN_LAYOUT: "Disposition des boutons latéraux"
|
||||
STR_LONG_PRESS_SKIP: "Appui long pour saut de chapitre"
|
||||
STR_FONT_FAMILY: "Police de caractères du lecteur"
|
||||
STR_EXT_READER_FONT: "Police externe"
|
||||
STR_EXT_CHINESE_FONT: "Police du lecteur"
|
||||
STR_EXT_UI_FONT: "Police de l’interface"
|
||||
STR_FONT_SIZE: "Taille du texte de l’interface"
|
||||
STR_LINE_SPACING: "Espacement des lignes"
|
||||
STR_ASCII_LETTER_SPACING: "Espacement des lettres ASCII"
|
||||
STR_ASCII_DIGIT_SPACING: "Espacement des chiffres ASCII"
|
||||
STR_CJK_SPACING: "Espacement CJK"
|
||||
STR_COLOR_MODE: "Mode couleur"
|
||||
STR_SCREEN_MARGIN: "Marges du lecteur"
|
||||
STR_PARA_ALIGNMENT: "Alignement des paragraphes"
|
||||
STR_HYPHENATION: "Césure"
|
||||
STR_TIME_TO_SLEEP: "Mise en veille automatique"
|
||||
STR_REFRESH_FREQ: "Fréquence de rafraîchissement"
|
||||
STR_CALIBRE_SETTINGS: "Réglages Calibre"
|
||||
STR_KOREADER_SYNC: "Synchronisation KOReader"
|
||||
STR_CHECK_UPDATES: "Mise à jour"
|
||||
STR_LANGUAGE: "Langue"
|
||||
STR_SELECT_WALLPAPER: "Fond d’écran"
|
||||
STR_CLEAR_READING_CACHE: "Vider le cache de lecture"
|
||||
STR_CALIBRE: "Calibre"
|
||||
STR_USERNAME: "Nom d’utilisateur"
|
||||
STR_PASSWORD: "Mot de passe"
|
||||
STR_SYNC_SERVER_URL: "URL du serveur"
|
||||
STR_DOCUMENT_MATCHING: "Correspondance"
|
||||
STR_AUTHENTICATE: "Se connecter"
|
||||
STR_KOREADER_USERNAME: "Nom d’utilisateur"
|
||||
STR_KOREADER_PASSWORD: "Mot de passe"
|
||||
STR_FILENAME: "Nom de fichier"
|
||||
STR_BINARY: "Binaire"
|
||||
STR_SET_CREDENTIALS_FIRST: "Identifiants manquants"
|
||||
STR_WIFI_CONN_FAILED: "Échec de connexion WiFi"
|
||||
STR_AUTHENTICATING: "Connexion en cours…"
|
||||
STR_AUTH_SUCCESS: "Connexion réussie !"
|
||||
STR_KOREADER_AUTH: "Auth KOReader"
|
||||
STR_SYNC_READY: "Synchronisation KOReader prête"
|
||||
STR_AUTH_FAILED: "Échec de la connexion"
|
||||
STR_DONE: "OK"
|
||||
STR_CLEAR_CACHE_WARNING_1: "Le cache de votre bibliothèque sera entièrement vidé"
|
||||
STR_CLEAR_CACHE_WARNING_2: "Votre progression de lecture sera perdue !"
|
||||
STR_CLEAR_CACHE_WARNING_3: "Les livres devront être réindexés"
|
||||
STR_CLEAR_CACHE_WARNING_4: "à leur prochaine ouverture."
|
||||
STR_CLEARING_CACHE: "Suppression du cache…"
|
||||
STR_CACHE_CLEARED: "Cache supprimé"
|
||||
STR_ITEMS_REMOVED: "éléments supprimés"
|
||||
STR_FAILED_LOWER: "ont échoué"
|
||||
STR_CLEAR_CACHE_FAILED: "Échec de la suppression du cache"
|
||||
STR_CHECK_SERIAL_OUTPUT: "Vérifiez la console série pour plus de détails"
|
||||
STR_DARK: "Sombre"
|
||||
STR_LIGHT: "Clair"
|
||||
STR_CUSTOM: "Custom"
|
||||
STR_COVER: "Couverture"
|
||||
STR_NONE_OPT: "Aucun"
|
||||
STR_FIT: "Ajusté"
|
||||
STR_CROP: "Rogné"
|
||||
STR_NO_PROGRESS: "Sans progression"
|
||||
STR_FULL_OPT: "Complète"
|
||||
STR_NEVER: "Jamais"
|
||||
STR_IN_READER: "Dans le lecteur"
|
||||
STR_ALWAYS: "Toujours"
|
||||
STR_IGNORE: "Ignorer"
|
||||
STR_SLEEP: "Mise en veille"
|
||||
STR_PAGE_TURN: "Page suivante"
|
||||
STR_PORTRAIT: "Portrait"
|
||||
STR_LANDSCAPE_CW: "Paysage"
|
||||
STR_INVERTED: "Inversé"
|
||||
STR_LANDSCAPE_CCW: "Paysage inversé"
|
||||
STR_FRONT_LAYOUT_BCLR: "Ret, OK, Gauche, Droite"
|
||||
STR_FRONT_LAYOUT_LRBC: "Gauche, Droite, Ret, OK"
|
||||
STR_FRONT_LAYOUT_LBCR: "Gauche, Ret, OK, Droite"
|
||||
STR_PREV_NEXT: "Prec/Suiv"
|
||||
STR_NEXT_PREV: "Suiv/Prec"
|
||||
STR_BOOKERLY: "Bookerly"
|
||||
STR_NOTO_SANS: "Noto Sans"
|
||||
STR_OPEN_DYSLEXIC: "Open Dyslexic"
|
||||
STR_SMALL: "Petite"
|
||||
STR_MEDIUM: "Moyenne"
|
||||
STR_LARGE: "Grande"
|
||||
STR_X_LARGE: "T Grande"
|
||||
STR_TIGHT: "Serré"
|
||||
STR_NORMAL: "Normal"
|
||||
STR_WIDE: "Large"
|
||||
STR_JUSTIFY: "Justifier"
|
||||
STR_ALIGN_LEFT: "Gauche"
|
||||
STR_CENTER: "Centre"
|
||||
STR_ALIGN_RIGHT: "Droite"
|
||||
STR_MIN_1: "1 min"
|
||||
STR_MIN_5: "5 min"
|
||||
STR_MIN_10: "10 min"
|
||||
STR_MIN_15: "15 min"
|
||||
STR_MIN_30: "30 min"
|
||||
STR_PAGES_1: "1 page"
|
||||
STR_PAGES_5: "5 pages"
|
||||
STR_PAGES_10: "10 pages"
|
||||
STR_PAGES_15: "15 pages"
|
||||
STR_PAGES_30: "30 pages"
|
||||
STR_UPDATE: "Mise à jour"
|
||||
STR_CHECKING_UPDATE: "Recherche de mises à jour en cours…"
|
||||
STR_NEW_UPDATE: "Nouvelle mise à jour disponible !"
|
||||
STR_CURRENT_VERSION: "Version actuelle :"
|
||||
STR_NEW_VERSION: "Nouvelle version : "
|
||||
STR_UPDATING: "Mise à jour en cours…"
|
||||
STR_NO_UPDATE: "Aucune mise à jour disponible"
|
||||
STR_UPDATE_FAILED: "Échec de la mise à jour"
|
||||
STR_UPDATE_COMPLETE: "Mise à jour effectuée"
|
||||
STR_POWER_ON_HINT: "Maintenir le bouton d’alimentation pour redémarrer"
|
||||
STR_EXTERNAL_FONT: "Police externe"
|
||||
STR_BUILTIN_DISABLED: "Intégrée (désactivée)"
|
||||
STR_NO_ENTRIES: "Aucune entrée trouvée"
|
||||
STR_DOWNLOADING: "Téléchargement en cours…"
|
||||
STR_DOWNLOAD_FAILED: "Échec du téléchargement"
|
||||
STR_ERROR_MSG: "Erreur : "
|
||||
STR_UNNAMED: "Sans titre"
|
||||
STR_NO_SERVER_URL: "Aucune URL serveur configurée"
|
||||
STR_FETCH_FEED_FAILED: "Échec du téléchargement du flux"
|
||||
STR_PARSE_FEED_FAILED: "Échec de l’analyse du flux"
|
||||
STR_NETWORK_PREFIX: "Réseau : "
|
||||
STR_IP_ADDRESS_PREFIX: "Adresse IP : "
|
||||
STR_SCAN_QR_WIFI_HINT: "or scan QR code with your phone to connect to Wifi."
|
||||
STR_ERROR_GENERAL_FAILURE: "Erreur : Échec général"
|
||||
STR_ERROR_NETWORK_NOT_FOUND: "Erreur : Réseau introuvable"
|
||||
STR_ERROR_CONNECTION_TIMEOUT: "Erreur : Délai de connexion dépassé"
|
||||
STR_SD_CARD: "Carte SD"
|
||||
STR_BACK: "« Retour"
|
||||
STR_EXIT: "« Sortie"
|
||||
STR_HOME: "« Accueil"
|
||||
STR_SAVE: "« Sauver"
|
||||
STR_SELECT: "OK"
|
||||
STR_TOGGLE: "Modifier"
|
||||
STR_CONFIRM: "Confirmer"
|
||||
STR_CANCEL: "Annuler"
|
||||
STR_CONNECT: "OK"
|
||||
STR_OPEN: "Ouvrir"
|
||||
STR_DOWNLOAD: "Télécharger"
|
||||
STR_RETRY: "Réessayer"
|
||||
STR_YES: "Oui"
|
||||
STR_NO: "Non"
|
||||
STR_STATE_ON: "ON"
|
||||
STR_STATE_OFF: "OFF"
|
||||
STR_SET: "Défini"
|
||||
STR_NOT_SET: "Non défini"
|
||||
STR_DIR_LEFT: "Gauche"
|
||||
STR_DIR_RIGHT: "Droite"
|
||||
STR_DIR_UP: "Haut"
|
||||
STR_DIR_DOWN: "Bas"
|
||||
STR_CAPS_ON: "MAJ"
|
||||
STR_CAPS_OFF: "maj"
|
||||
STR_OK_BUTTON: "OK"
|
||||
STR_ON_MARKER: "[ON]"
|
||||
STR_SLEEP_COVER_FILTER: "Filtre affichage veille"
|
||||
STR_FILTER_CONTRAST: "Contraste"
|
||||
STR_STATUS_BAR_FULL_PERCENT: "Complète + %"
|
||||
STR_STATUS_BAR_FULL_BOOK: "Complète + barre livre"
|
||||
STR_STATUS_BAR_BOOK_ONLY: "Barre livre"
|
||||
STR_STATUS_BAR_FULL_CHAPTER: "Complète + barre chapitre"
|
||||
STR_UI_THEME: "Thème de l’interface"
|
||||
STR_THEME_CLASSIC: "Classique"
|
||||
STR_THEME_LYRA: "Lyra"
|
||||
STR_SUNLIGHT_FADING_FIX: "Amélioration de la lisibilité au soleil"
|
||||
STR_REMAP_FRONT_BUTTONS: "Réassigner les boutons avant"
|
||||
STR_OPDS_BROWSER: "Navigateur OPDS"
|
||||
STR_COVER_CUSTOM: "Couverture + Custom"
|
||||
STR_RECENTS: "Récents"
|
||||
STR_MENU_RECENT_BOOKS: "Livres récents"
|
||||
STR_NO_RECENT_BOOKS: "Aucun livre récent"
|
||||
STR_CALIBRE_DESC: "Utiliser les transferts sans fil Calibre"
|
||||
STR_FORGET_AND_REMOVE: "Oublier le réseau et supprimer le mot de passe enregistré ?"
|
||||
STR_FORGET_BUTTON: "Oublier le réseau"
|
||||
STR_CALIBRE_STARTING: "Démarrage de Calibre..."
|
||||
STR_CALIBRE_SETUP: "Configuration"
|
||||
STR_CALIBRE_STATUS: "Statut"
|
||||
STR_CLEAR_BUTTON: "Effacer"
|
||||
STR_DEFAULT_VALUE: "Défaut"
|
||||
STR_REMAP_PROMPT: "Appuyez sur un bouton avant pour chaque rôle"
|
||||
STR_UNASSIGNED: "Non assigné"
|
||||
STR_ALREADY_ASSIGNED: "Déjà assigné"
|
||||
STR_REMAP_RESET_HINT: "Bouton latéral haut : Réinitialiser"
|
||||
STR_REMAP_CANCEL_HINT: "Bouton latéral bas : Annuler le réglage"
|
||||
STR_HW_BACK_LABEL: "Retour (1er bouton)"
|
||||
STR_HW_CONFIRM_LABEL: "OK (2ème bouton)"
|
||||
STR_HW_LEFT_LABEL: "Gauche (3ème bouton)"
|
||||
STR_HW_RIGHT_LABEL: "Droite (4ème bouton)"
|
||||
STR_GO_TO_PERCENT: "Aller à %"
|
||||
STR_GO_HOME_BUTTON: "Aller à l’accueil"
|
||||
STR_SYNC_PROGRESS: "Synchroniser la progression"
|
||||
STR_DELETE_CACHE: "Supprimer le cache du livre"
|
||||
STR_CHAPTER_PREFIX: "Chapitre : "
|
||||
STR_PAGES_SEPARATOR: " pages | "
|
||||
STR_BOOK_PREFIX: "Livre : "
|
||||
STR_KBD_SHIFT: "maj"
|
||||
STR_KBD_SHIFT_CAPS: "MAJ"
|
||||
STR_KBD_LOCK: "VERR MAJ"
|
||||
STR_CALIBRE_URL_HINT: "Pour Calibre, ajoutez /opds à l’URL"
|
||||
STR_PERCENT_STEP_HINT: "Gauche/Droite : 1% Haut/Bas : 10%"
|
||||
STR_SYNCING_TIME: "Synchronisation de l’heure…"
|
||||
STR_CALC_HASH: "Calcul du hash du document…"
|
||||
STR_HASH_FAILED: "Échec du calcul du hash du document"
|
||||
STR_FETCH_PROGRESS: "Téléchargement de la progression…"
|
||||
STR_UPLOAD_PROGRESS: "Envoi de la progression…"
|
||||
STR_NO_CREDENTIALS_MSG: "Aucun identifiant configuré"
|
||||
STR_KOREADER_SETUP_HINT: "Configurez le compte KOReader dans les réglages"
|
||||
STR_PROGRESS_FOUND: "Progression trouvée !"
|
||||
STR_REMOTE_LABEL: "En ligne :"
|
||||
STR_LOCAL_LABEL: "Locale :"
|
||||
STR_PAGE_OVERALL_FORMAT: "Page %d, %.2f%% au total"
|
||||
STR_PAGE_TOTAL_OVERALL_FORMAT: "Page %d/%d, %.2f%% au total"
|
||||
STR_DEVICE_FROM_FORMAT: " De : %s"
|
||||
STR_APPLY_REMOTE: "Appliquer la progression en ligne"
|
||||
STR_UPLOAD_LOCAL: "Envoyer la progression locale"
|
||||
STR_NO_REMOTE_MSG: "Aucune progression en ligne trouvée"
|
||||
STR_UPLOAD_PROMPT: "Envoyer la position actuelle ?"
|
||||
STR_UPLOAD_SUCCESS: "Progression envoyée !"
|
||||
STR_SYNC_FAILED_MSG: "Échec de la synchronisation"
|
||||
STR_SECTION_PREFIX: "Section "
|
||||
STR_UPLOAD: "Envoi"
|
||||
STR_BOOK_S_STYLE: "Style du livre"
|
||||
STR_EMBEDDED_STYLE: "Style intégré"
|
||||
STR_OPDS_SERVER_URL: "URL du serveur OPDS"
|
||||
Reference in New Issue
Block a user