mirror of
https://github.com/storytold/filmcraft.git
synced 2026-10-24 10:10:05 -06:00
i18n: Spanish interface language
Add Español next to English and 日本語 (Edit ▸ Language ▸ Español, also in the native menu bar). SPANISH covers every menu, submenu and menu item label (347 entries, Latin American Spanish); names, formats and percentages stay as they are. A new test checks that every entry is a current menu label, so a renamed command cannot leave a dead entry behind. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
771b614ad4
commit
ed535180cb
@@ -92,8 +92,11 @@ pub fn install(app: &FilmcraftApp, ctx: egui::Context) -> (Receiver<String>, Sho
|
||||
}
|
||||
});
|
||||
let update: ShortcutUpdater = Box::new(move |items: &[Item]| {
|
||||
let language = if items.iter().any(|it| it.id == "app.language.japanese" && it.checked == Some(true)) {
|
||||
let checked = |id: &str| items.iter().any(|it| it.id == id && it.checked == Some(true));
|
||||
let language = if checked("app.language.japanese") {
|
||||
filmcraft_ui_egui::i18n::Language::Ja
|
||||
} else if checked("app.language.spanish") {
|
||||
filmcraft_ui_egui::i18n::Language::Es
|
||||
} else {
|
||||
filmcraft_ui_egui::i18n::Language::En
|
||||
};
|
||||
|
||||
+381
-7
@@ -14,15 +14,17 @@ pub enum Language {
|
||||
#[default]
|
||||
En,
|
||||
Ja,
|
||||
Es,
|
||||
}
|
||||
|
||||
impl Language {
|
||||
pub const ALL: [Self; 2] = [Self::En, Self::Ja];
|
||||
pub const ALL: [Self; 3] = [Self::En, Self::Ja, Self::Es];
|
||||
|
||||
pub fn name(self) -> &'static str {
|
||||
match self {
|
||||
Self::En => "English",
|
||||
Self::Ja => "日本語",
|
||||
Self::Es => "Español",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,17 +32,18 @@ impl Language {
|
||||
match code {
|
||||
"en" => Some(Self::En),
|
||||
"ja" => Some(Self::Ja),
|
||||
"es" => Some(Self::Es),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tr(self, text: &str) -> &str {
|
||||
if self == Self::Ja
|
||||
&& let Some((_, japanese)) = JAPANESE.iter().find(|(english, _)| *english == text)
|
||||
{
|
||||
return japanese;
|
||||
}
|
||||
text
|
||||
let table = match self {
|
||||
Self::En => return text,
|
||||
Self::Ja => JAPANESE,
|
||||
Self::Es => SPANISH,
|
||||
};
|
||||
table.iter().find(|(english, _)| *english == text).map_or(text, |(_, translated)| translated)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,6 +123,356 @@ pub fn install_japanese_font(ctx: &egui::Context) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
const SPANISH: &[(&str, &str)] = &[
|
||||
("About FilmCraft", "Acerca de FilmCraft"),
|
||||
("Add Audio Submix Track", "Añadir pista de submezcla de audio"),
|
||||
("Add Caption at Playhead", "Añadir subtítulo en el cabezal"),
|
||||
("Add Chapter Marker…", "Añadir marcador de capítulo…"),
|
||||
("Add Edit", "Añadir edición"),
|
||||
("Add Edit to All Tracks", "Añadir edición a todas las pistas"),
|
||||
("Add Flash Cue Marker…", "Añadir marcador de referencia Flash…"),
|
||||
("Add Frame Hold", "Añadir fotograma congelado"),
|
||||
("Add Guide…", "Añadir guía…"),
|
||||
("Add Marker", "Añadir marcador"),
|
||||
("Add New Caption Track…", "Añadir nueva pista de subtítulos…"),
|
||||
("Add Range Marker", "Añadir marcador de rango"),
|
||||
("Add Range Marker to In and Out", "Añadir marcador de rango de entrada a salida"),
|
||||
("Add Tracks…", "Añadir pistas…"),
|
||||
("Adjustment Layer…", "Capa de ajuste…"),
|
||||
("Align to Selection", "Alinear con la selección"),
|
||||
("Align to Video Frame", "Alinear con el fotograma de video"),
|
||||
("Align to Video Frame as Group", "Alinear con el fotograma de video como grupo"),
|
||||
("All Panels", "Todos los paneles"),
|
||||
("Alpha", "Alfa"),
|
||||
("Appearance", "Apariencia"),
|
||||
("Appearance…", "Apariencia…"),
|
||||
("Apply Audio Transition", "Aplicar transición de audio"),
|
||||
("Apply Default Transitions to Selection", "Aplicar transiciones predeterminadas a la selección"),
|
||||
("Apply Video Transition", "Aplicar transición de video"),
|
||||
("Arrange", "Organizar"),
|
||||
("ArtCraft Website", "Sitio web de ArtCraft"),
|
||||
("Assembly", "Ensamblaje"),
|
||||
("Attach Proxies…", "Adjuntar proxies…"),
|
||||
("Audio Channels…", "Canales de audio…"),
|
||||
("Audio Clip Mixer", "Mezclador de clips de audio"),
|
||||
("Audio Gain…", "Ganancia de audio…"),
|
||||
("Audio Hardware…", "Hardware de audio…"),
|
||||
("Audio In", "Entrada de audio"),
|
||||
("Audio Meters", "Medidores de audio"),
|
||||
("Audio Options", "Opciones de audio"),
|
||||
("Audio Out", "Salida de audio"),
|
||||
("Audio Track Mixer", "Mezclador de pistas de audio"),
|
||||
("Audio Waveform", "Forma de onda de audio"),
|
||||
("Auto Save…", "Guardado automático…"),
|
||||
("Automate to Sequence…", "Automatizar a secuencia…"),
|
||||
("Bars and Tone…", "Barras y tono…"),
|
||||
("Bin", "Bandeja"),
|
||||
("Bin From Selection", "Bandeja a partir de la selección"),
|
||||
("Black Video…", "Video negro…"),
|
||||
("Blue", "Azul"),
|
||||
("Bottom", "Abajo"),
|
||||
("Breakout to Mono", "Separar en mono"),
|
||||
("Bring Forward", "Traer adelante"),
|
||||
("Bring to Front", "Traer al frente"),
|
||||
("Brown", "Marrón"),
|
||||
("Captions", "Subtítulos"),
|
||||
("Captions and Graphics", "Subtítulos y gráficos"),
|
||||
("Captions…", "Subtítulos…"),
|
||||
("Caribbean", "Caribe"),
|
||||
("Center Horizontally", "Centrar horizontalmente"),
|
||||
("Center Vertically", "Centrar verticalmente"),
|
||||
("Cerulean", "Cerúleo"),
|
||||
("Clear", "Borrar"),
|
||||
("Clear Guides", "Borrar guías"),
|
||||
("Clear In", "Borrar entrada"),
|
||||
("Clear In and Out", "Borrar entrada y salida"),
|
||||
("Clear Markers", "Borrar marcadores"),
|
||||
("Clear Out", "Borrar salida"),
|
||||
("Clear Selected Marker", "Borrar marcador seleccionado"),
|
||||
("Close", "Cerrar"),
|
||||
("Close All Other Projects", "Cerrar todos los demás proyectos"),
|
||||
("Close All Projects", "Cerrar todos los proyectos"),
|
||||
("Close Gap", "Cerrar hueco"),
|
||||
("Close Project", "Cerrar proyecto"),
|
||||
("Color Management…", "Gestión del color…"),
|
||||
("Color Matte…", "Mate de color…"),
|
||||
("Comparison View", "Vista de comparación"),
|
||||
("Composite Video", "Video compuesto"),
|
||||
("Consolidate Duplicates", "Consolidar duplicados"),
|
||||
("Copy", "Copiar"),
|
||||
("Copy Paste Includes Sequence Markers", "Copiar y pegar incluye marcadores de secuencia"),
|
||||
("Create Captions from Transcript…", "Crear subtítulos a partir de la transcripción…"),
|
||||
("Create Multi-Camera Source Sequence…", "Crear secuencia de origen multicámara…"),
|
||||
("Create Proxies…", "Crear proxies…"),
|
||||
("Cut", "Cortar"),
|
||||
("Darkest", "Más oscuro"),
|
||||
("Delete Render Files", "Eliminar archivos de procesamiento"),
|
||||
("Delete Render Files In to Out", "Eliminar archivos de procesamiento de entrada a salida"),
|
||||
("Delete Tracks…", "Eliminar pistas…"),
|
||||
("Delete Transcript", "Eliminar transcripción"),
|
||||
("Demo Footage", "Material de demostración"),
|
||||
("Demo Project", "Proyecto de demostración"),
|
||||
("Deselect All", "Deseleccionar todo"),
|
||||
("Detach Proxies", "Separar proxies"),
|
||||
("Display Mode", "Modo de visualización"),
|
||||
("Distribute", "Distribuir"),
|
||||
("Distribute Horizontally", "Distribuir horizontalmente"),
|
||||
("Distribute Space Horizontally", "Distribuir espacio horizontalmente"),
|
||||
("Distribute Space Vertically", "Distribuir espacio verticalmente"),
|
||||
("Distribute Vertically", "Distribuir verticalmente"),
|
||||
("Duplicate", "Duplicar"),
|
||||
("Dynamic Audio Waveforms", "Formas de onda de audio dinámicas"),
|
||||
("Edit", "Edición"),
|
||||
("Edit Offline…", "Editar sin conexión…"),
|
||||
("Edit Original", "Editar original"),
|
||||
("Edit Subclip…", "Editar subclip…"),
|
||||
("Editing", "Edición"),
|
||||
("Effect Controls", "Controles de efectos"),
|
||||
("Effects", "Efectos"),
|
||||
("Ellipse", "Elipse"),
|
||||
("Enable", "Activar"),
|
||||
("Enable Remix", "Activar remezcla"),
|
||||
("Essential Graphics", "Gráficos esenciales"),
|
||||
("Essential Sound", "Sonido esencial"),
|
||||
("Events", "Eventos"),
|
||||
("Export", "Exportar"),
|
||||
("Export As Motion Graphics Template…", "Exportar como plantilla de animación…"),
|
||||
("Extract", "Extraer"),
|
||||
("Extract Audio", "Extraer audio"),
|
||||
("Field Options…", "Opciones de campo…"),
|
||||
("File", "Archivo"),
|
||||
("File…", "Archivo…"),
|
||||
("Fill frame", "Rellenar fotograma"),
|
||||
("FilmCraft Help…", "Ayuda de FilmCraft…"),
|
||||
("FilmCraft on GitHub", "FilmCraft en GitHub"),
|
||||
("FilmCraft on getartcraft.com", "FilmCraft en getartcraft.com"),
|
||||
("Find Next", "Buscar siguiente"),
|
||||
("Find…", "Buscar…"),
|
||||
("Fit", "Ajustar"),
|
||||
("Fit to frame", "Ajustar al fotograma"),
|
||||
("Flatten", "Acoplar"),
|
||||
("Forest", "Bosque"),
|
||||
("Frame Blending", "Fusión de fotogramas"),
|
||||
("Frame Hold Options…", "Opciones de fotograma congelado…"),
|
||||
("Frame Sampling", "Muestreo de fotogramas"),
|
||||
("From Bin", "Desde la bandeja"),
|
||||
("From Source Monitor", "Desde el monitor de origen"),
|
||||
("From Source Monitor, Match Frame", "Desde el monitor de origen, fotograma coincidente"),
|
||||
("From file…", "Desde archivo…"),
|
||||
("Full", "Completa"),
|
||||
("Generate Audio Waveform", "Generar forma de onda de audio"),
|
||||
("Get Media File Properties for", "Obtener propiedades del archivo multimedia de"),
|
||||
("Go to Gap", "Ir al hueco"),
|
||||
("Go to In", "Ir a la entrada"),
|
||||
("Go to Next Caption Segment", "Ir al siguiente segmento de subtítulo"),
|
||||
("Go to Next Marker", "Ir al siguiente marcador"),
|
||||
("Go to Out", "Ir a la salida"),
|
||||
("Go to Previous Caption Segment", "Ir al segmento de subtítulo anterior"),
|
||||
("Go to Previous Marker", "Ir al marcador anterior"),
|
||||
("Go to Split", "Ir a la división"),
|
||||
("Graphics and Titles", "Gráficos y títulos"),
|
||||
("Graphics…", "Gráficos…"),
|
||||
("Green", "Verde"),
|
||||
("Group", "Agrupar"),
|
||||
("Guide Templates", "Plantillas de guías"),
|
||||
("Help", "Ayuda"),
|
||||
("Hide All Caption Tracks", "Ocultar todas las pistas de subtítulos"),
|
||||
("High Quality Playback", "Reproducción de alta calidad"),
|
||||
("History", "Historial"),
|
||||
("Import From", "Importar desde"),
|
||||
("Import Image Sequence…", "Importar secuencia de imágenes…"),
|
||||
("Import from Media Browser", "Importar desde el navegador de medios"),
|
||||
("Import…", "Importar…"),
|
||||
("Info", "Información"),
|
||||
("Ingest Settings…", "Ajustes de ingesta…"),
|
||||
("Insert", "Insertar"),
|
||||
("Insert Frame Hold Segment", "Insertar segmento de fotograma congelado"),
|
||||
("Install Motion Graphics Template…", "Instalar plantilla de animación…"),
|
||||
("Interpret Footage…", "Interpretar material…"),
|
||||
("Join the ArtCraft Discord…", "Únete al Discord de ArtCraft…"),
|
||||
("Keyboard Shortcuts…", "Atajos de teclado…"),
|
||||
("Label", "Etiqueta"),
|
||||
("Labels…", "Etiquetas…"),
|
||||
("Language", "Idioma"),
|
||||
("Lavender", "Lavanda"),
|
||||
("Learning", "Aprendizaje"),
|
||||
("Left", "Izquierda"),
|
||||
("Libraries", "Bibliotecas"),
|
||||
("Lift", "Levantar"),
|
||||
("Light", "Claro"),
|
||||
("Link", "Vincular"),
|
||||
("Link Media…", "Vincular medios…"),
|
||||
("Linked Selection", "Selección vinculada"),
|
||||
("Lock Guides", "Bloquear guías"),
|
||||
("Lumetri Color", "Color Lumetri"),
|
||||
("Lumetri Scopes", "Ámbitos Lumetri"),
|
||||
("Magnification", "Ampliación"),
|
||||
("Make Offline…", "Desconectar…"),
|
||||
("Make Subclip…", "Crear subclip…"),
|
||||
("Make Subsequence", "Crear subsecuencia"),
|
||||
("Manage Guides…", "Gestionar guías…"),
|
||||
("Mark Clip", "Marcar clip"),
|
||||
("Mark In", "Marcar entrada"),
|
||||
("Mark Out", "Marcar salida"),
|
||||
("Mark Selection", "Marcar selección"),
|
||||
("Mark Split", "Marcar división"),
|
||||
("Markers", "Marcadores"),
|
||||
("Match Frame", "Fotograma coincidente"),
|
||||
("Media Analysis & Transcription…", "Análisis y transcripción de medios…"),
|
||||
("Media Browser", "Navegador de medios"),
|
||||
("Media Cache…", "Caché de medios…"),
|
||||
("Media…", "Medios…"),
|
||||
("Medium", "Medio"),
|
||||
("Memory…", "Memoria…"),
|
||||
("Merge Clips…", "Combinar clips…"),
|
||||
("Metadata", "Metadatos"),
|
||||
("Modify", "Modificar"),
|
||||
("Motion Graphics Template…", "Plantilla de animación…"),
|
||||
("Multi-Camera", "Multicámara"),
|
||||
("Multi-Camera View", "Vista multicámara"),
|
||||
("Nest…", "Anidar…"),
|
||||
("New", "Nuevo"),
|
||||
("New Layer", "Nueva capa"),
|
||||
("New Project Panel", "Nuevo panel de proyecto"),
|
||||
("Next in Sequence", "Siguiente en la secuencia"),
|
||||
("Next in Track", "Siguiente en la pista"),
|
||||
("Normalize Mix Track…", "Normalizar pista de mezcla…"),
|
||||
("Offline File…", "Archivo sin conexión…"),
|
||||
("Open Project…", "Abrir proyecto…"),
|
||||
("Optical Flow", "Flujo óptico"),
|
||||
("Overwrite", "Sobrescribir"),
|
||||
("Paste", "Pegar"),
|
||||
("Paste Attributes…", "Pegar atributos…"),
|
||||
("Paste Insert", "Pegar e insertar"),
|
||||
("Paused Resolution", "Resolución en pausa"),
|
||||
("Playback Resolution", "Resolución de reproducción"),
|
||||
("Playback…", "Reproducción…"),
|
||||
("Plugins…", "Complementos…"),
|
||||
("Polygon", "Polígono"),
|
||||
("Preferences", "Preferencias"),
|
||||
("Previous in Sequence", "Anterior en la secuencia"),
|
||||
("Previous in Track", "Anterior en la pista"),
|
||||
("Program", "Programa"),
|
||||
("Progress", "Progreso"),
|
||||
("Project", "Proyecto"),
|
||||
("Project Manager…", "Administrador de proyectos…"),
|
||||
("Project Settings", "Ajustes del proyecto"),
|
||||
("Project…", "Proyecto…"),
|
||||
("Properties", "Propiedades"),
|
||||
("Purple", "Púrpura"),
|
||||
("Reconnect Full Resolution Media…", "Reconectar medios de resolución completa…"),
|
||||
("Recover Unsaved Changes…", "Recuperar cambios no guardados…"),
|
||||
("Rectangle", "Rectángulo"),
|
||||
("Red", "Rojo"),
|
||||
("Redo", "Rehacer"),
|
||||
("Reference Monitor", "Monitor de referencia"),
|
||||
("Remix", "Remezcla"),
|
||||
("Remix Properties…", "Propiedades de remezcla…"),
|
||||
("Remove Attributes…", "Quitar atributos…"),
|
||||
("Remove Filler Words", "Quitar muletillas"),
|
||||
("Remove Pauses", "Quitar pausas"),
|
||||
("Remove Unused", "Quitar no utilizados"),
|
||||
("Rename…", "Cambiar nombre…"),
|
||||
("Render Audio", "Procesar audio"),
|
||||
("Render Effects In to Out", "Procesar efectos de entrada a salida"),
|
||||
("Render In to Out", "Procesar de entrada a salida"),
|
||||
("Render Selection", "Procesar selección"),
|
||||
("Replace Fonts in Projects…", "Reemplazar fuentes en proyectos…"),
|
||||
("Replace With Clip", "Reemplazar con clip"),
|
||||
("Report an Issue…", "Informar de un problema…"),
|
||||
("Reset All Parameters", "Restablecer todos los parámetros"),
|
||||
("Reset Duration", "Restablecer duración"),
|
||||
("Reset to Saved Layout", "Restablecer al diseño guardado"),
|
||||
("Restore Captions from Source Clip", "Restaurar subtítulos del clip de origen"),
|
||||
("Reveal Log Files…", "Mostrar archivos de registro…"),
|
||||
("Reverse Match Frame", "Fotograma coincidente inverso"),
|
||||
("Revert", "Revertir"),
|
||||
("Revert Remix", "Revertir remezcla"),
|
||||
("Review", "Revisión"),
|
||||
("Right", "Derecha"),
|
||||
("Ripple Delete", "Eliminar y cerrar hueco"),
|
||||
("Ripple Sequence Markers", "Desplazar marcadores de secuencia"),
|
||||
("Rose", "Rosa"),
|
||||
("Safe Margins", "Márgenes seguros"),
|
||||
("Save", "Guardar"),
|
||||
("Save All", "Guardar todo"),
|
||||
("Save As…", "Guardar como…"),
|
||||
("Save Guides as Template…", "Guardar guías como plantilla…"),
|
||||
("Save a Copy…", "Guardar una copia…"),
|
||||
("Save as Template…", "Guardar como plantilla…"),
|
||||
("Scale to Frame Size", "Escalar al tamaño del fotograma"),
|
||||
("Scene Edit Detection…", "Detección de cambios de escena…"),
|
||||
("Scratch Disks…", "Discos de memoria virtual…"),
|
||||
("Search Bin", "Bandeja de búsqueda"),
|
||||
("Select", "Seleccionar"),
|
||||
("Select All", "Seleccionar todo"),
|
||||
("Select All Matching", "Seleccionar todos los coincidentes"),
|
||||
("Select Label Group", "Seleccionar grupo de etiquetas"),
|
||||
("Select Next Graphic", "Seleccionar siguiente gráfico"),
|
||||
("Select Next Layer", "Seleccionar siguiente capa"),
|
||||
("Select Previous Graphic", "Seleccionar gráfico anterior"),
|
||||
("Select Previous Layer", "Seleccionar capa anterior"),
|
||||
("Selection Follows Playhead", "La selección sigue al cabezal"),
|
||||
("Selection as FilmCraft Project…", "Selección como proyecto de FilmCraft…"),
|
||||
("Selection…", "Selección…"),
|
||||
("Send Backward", "Enviar atrás"),
|
||||
("Send to Back", "Enviar al fondo"),
|
||||
("Sequence", "Secuencia"),
|
||||
("Sequence From Clip", "Secuencia a partir de clip"),
|
||||
("Sequence Settings…", "Ajustes de secuencia…"),
|
||||
("Sequence…", "Secuencia…"),
|
||||
("Show Active Caption Tracks Only", "Mostrar solo pistas de subtítulos activas"),
|
||||
("Show All Caption Tracks", "Mostrar todas las pistas de subtítulos"),
|
||||
("Show All Marker Colors", "Mostrar todos los colores de marcador"),
|
||||
("Show Guides", "Mostrar guías"),
|
||||
("Show Rulers", "Mostrar reglas"),
|
||||
("Show Through Edits", "Mostrar ediciones pasantes"),
|
||||
("Simplify Sequence…", "Simplificar secuencia…"),
|
||||
("Snap in Program Monitor", "Ajustar en el monitor de programa"),
|
||||
("Snap in Timeline", "Ajustar en la línea de tiempo"),
|
||||
("Source", "Origen"),
|
||||
("Source Settings…", "Ajustes de origen…"),
|
||||
("Speed/Duration…", "Velocidad/duración…"),
|
||||
("Synchronize…", "Sincronizar…"),
|
||||
("System Compatibility Report…", "Informe de compatibilidad del sistema…"),
|
||||
("Tan", "Canela"),
|
||||
("Teal", "Verde azulado"),
|
||||
("Text", "Texto"),
|
||||
("Time Interpolation", "Interpolación de tiempo"),
|
||||
("Timecode", "Código de tiempo"),
|
||||
("Timecode…", "Código de tiempo…"),
|
||||
("Timeline", "Línea de tiempo"),
|
||||
("Timeline…", "Línea de tiempo…"),
|
||||
("Toggle Proxies", "Alternar proxies"),
|
||||
("Tools", "Herramientas"),
|
||||
("Top", "Arriba"),
|
||||
("Transcribe Sequence…", "Transcribir secuencia…"),
|
||||
("Transcribe…", "Transcribir…"),
|
||||
("Transcript", "Transcripción"),
|
||||
("Transparent Video…", "Video transparente…"),
|
||||
("Trim Edit", "Recortar edición"),
|
||||
("Trim…", "Recorte…"),
|
||||
("Undo", "Deshacer"),
|
||||
("Ungroup", "Desagrupar"),
|
||||
("Universal Counting Leader…", "Cuenta atrás universal…"),
|
||||
("Update Metadata…", "Actualizar metadatos…"),
|
||||
("Upgrade Caption to Graphic", "Convertir subtítulo en gráfico"),
|
||||
("Upgrade to Source Graphic", "Convertir en gráfico de origen"),
|
||||
("Vertical Text", "Texto vertical"),
|
||||
("Video In", "Entrada de video"),
|
||||
("Video Options", "Opciones de video"),
|
||||
("Video Out", "Salida de video"),
|
||||
("Video and Audio Waveform Split", "Video y forma de onda de audio divididos"),
|
||||
("View", "Ver"),
|
||||
("Violet", "Violeta"),
|
||||
("Window", "Ventana"),
|
||||
("Workspaces", "Espacios de trabajo"),
|
||||
("Yellow", "Amarillo"),
|
||||
("Zoom In", "Acercar"),
|
||||
("Zoom Out", "Alejar"),
|
||||
("Zoom to Sequence", "Ajustar zoom a la secuencia"),
|
||||
];
|
||||
|
||||
const JAPANESE: &[(&str, &str)] = &[
|
||||
("Clip", "クリップ"),
|
||||
("Sequence", "シーケンス"),
|
||||
@@ -222,10 +575,28 @@ mod tests {
|
||||
assert_eq!(Language::En.tr(en), *en);
|
||||
}
|
||||
assert_eq!(Language::Ja.tr("File"), "ファイル");
|
||||
for (i, (en, es)) in SPANISH.iter().enumerate() {
|
||||
assert!(!es.is_empty());
|
||||
assert!(SPANISH.iter().take(i).all(|(other, _)| en != other));
|
||||
}
|
||||
assert_eq!(Language::Es.tr("File"), "Archivo");
|
||||
assert_eq!(Language::Es.tr("mi video.mp4"), "mi video.mp4");
|
||||
assert_eq!(Language::parse("es"), Some(Language::Es));
|
||||
assert_eq!(Language::Ja.tr("日本語の文書.pdf"), "日本語の文書.pdf");
|
||||
assert_eq!(Language::parse("xx"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spanish_entries_are_menu_labels() {
|
||||
// a renamed command would otherwise leave a dead entry and an untranslated menu item
|
||||
let app = crate::FilmcraftApp::new(filmcraft_engine::Session::default());
|
||||
let items = crate::menus::menu_items(&app);
|
||||
let known = |text: &str| crate::menus::MENUS.contains(&text) || items.iter().any(|it| it.label == text || it.path.iter().any(|p| p == text));
|
||||
for (en, _) in SPANISH {
|
||||
assert!(known(en), "not a menu label: {en}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn language_commands_switch_and_persist_without_a_document() {
|
||||
let mut app = crate::FilmcraftApp::new(filmcraft_engine::Session::default());
|
||||
@@ -235,6 +606,9 @@ mod tests {
|
||||
let saved = serde_json::to_string(&app.ui).unwrap();
|
||||
let restored: crate::state::UiState = serde_json::from_str(&saved).unwrap();
|
||||
assert_eq!(restored.language, Language::Ja);
|
||||
crate::menus::invoke(&mut app, &ctx, "app.language.spanish", serde_json::json!({})).unwrap();
|
||||
assert_eq!(app.ui.language, Language::Es);
|
||||
assert!(crate::menus::menu_items(&app).iter().any(|it| it.id == "app.language.spanish" && it.checked == Some(true)));
|
||||
crate::menus::invoke(&mut app, &ctx, "app.language.english", serde_json::json!({})).unwrap();
|
||||
assert_eq!(app.ui.language, Language::En);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ macro_rules! uic {
|
||||
pub const UI_COMMANDS: &[UiCommand] = &[
|
||||
uic!("app.language.english", "English", ["Edit", "Language"], None),
|
||||
uic!("app.language.japanese", "日本語", ["Edit", "Language"], None),
|
||||
uic!("app.language.spanish", "Español", ["Edit", "Language"], None),
|
||||
uic!("playback.toggle", "Play/Stop", [], Some("Space")),
|
||||
uic!("playback.forward", "Shuttle Right", [], Some("L")),
|
||||
uic!("playback.stop", "Shuttle Stop", [], Some("K")),
|
||||
@@ -146,12 +147,16 @@ pub fn panel_command_id(p: PanelKind) -> String {
|
||||
|
||||
/// Execute a UI or engine command by id.
|
||||
pub fn invoke(app: &mut FilmcraftApp, ctx: &egui::Context, id: &str, params: Value) -> Result<Value, String> {
|
||||
if matches!(id, "app.language.english" | "app.language.japanese") {
|
||||
if matches!(id, "app.language.english" | "app.language.japanese" | "app.language.spanish") {
|
||||
// Japanese needs the craft-fonts (built with CRAFT_FONTS_DIR) or a font installed on the system
|
||||
if id == "app.language.japanese" && !crate::i18n::install_japanese_font(ctx) {
|
||||
return Err("no Japanese font is installed on this system (for example Noto Sans CJK JP); the interface stays in English".into());
|
||||
}
|
||||
app.ui.language = if id == "app.language.japanese" { crate::i18n::Language::Ja } else { crate::i18n::Language::En };
|
||||
app.ui.language = match id {
|
||||
"app.language.japanese" => crate::i18n::Language::Ja,
|
||||
"app.language.spanish" => crate::i18n::Language::Es,
|
||||
_ => crate::i18n::Language::En,
|
||||
};
|
||||
let items = menu_items(app);
|
||||
if let Some(hook) = app.hooks.shortcuts_changed.as_mut() {
|
||||
hook(&items);
|
||||
@@ -401,6 +406,7 @@ pub fn menu_items(app: &FilmcraftApp) -> Vec<MenuItem> {
|
||||
match it.id.as_str() {
|
||||
"app.language.english" => it.checked = Some(app.ui.language == crate::i18n::Language::En),
|
||||
"app.language.japanese" => it.checked = Some(app.ui.language == crate::i18n::Language::Ja),
|
||||
"app.language.spanish" => it.checked = Some(app.ui.language == crate::i18n::Language::Es),
|
||||
_ => {}
|
||||
}
|
||||
if it.id.starts_with("view.") {
|
||||
|
||||
Reference in New Issue
Block a user