ElyDoc, ElyTable, ElyShow (LibreOfficeKit), ElyPDF (MuPDF), ElyTree (Git), ElyMark (Milkdown and CodeMirror in CEF). ElyMail and ElyAgent follow.
220 lines
6.7 KiB
Rust
220 lines
6.7 KiB
Rust
use ely_gpui_component::i18n::I18n;
|
||
|
||
mod analysis;
|
||
mod calc;
|
||
mod data;
|
||
mod doc;
|
||
mod mark;
|
||
mod motion;
|
||
mod office;
|
||
mod output;
|
||
mod pdf;
|
||
mod play;
|
||
mod refs;
|
||
mod secure;
|
||
mod settings;
|
||
mod show;
|
||
mod table;
|
||
mod tools;
|
||
mod tree;
|
||
mod tree_ops;
|
||
mod tree_places;
|
||
mod web;
|
||
use gpui::{App, SharedString};
|
||
|
||
const EN: &[(&str, &str)] = &[
|
||
("menu.app.quit", "Quit {app}"),
|
||
("menu.app.switch", "Open Ely App"),
|
||
("toast.open", "Open"),
|
||
("toast.open_failed", "The file did not open: {error}"),
|
||
("menu.app.switch_failed", "{app} did not open: {error}"),
|
||
("menu.file", "File"),
|
||
("menu.insert", "Insert"),
|
||
("command.file.new", "New"),
|
||
("command.file.open", "Open…"),
|
||
("command.file.save", "Save"),
|
||
("command.file.save_as", "Save As…"),
|
||
("command.file.rename", "Rename…"),
|
||
("command.file.export", "Export…"),
|
||
("command.file.print", "Print…"),
|
||
("command.blocked.no_document", "No open document"),
|
||
("palette.group.file", "File"),
|
||
("gallery.ready", "Ready"),
|
||
("gallery.nav", "Navigation"),
|
||
("gallery.inbox", "Inbox"),
|
||
("gallery.archive", "Archive"),
|
||
("gallery.props", "Properties"),
|
||
("gallery.content", "Content"),
|
||
("gallery.mixed", "Mixed"),
|
||
("gallery.content_of", "Content of {page}"),
|
||
("gallery.rename", "Rename…"),
|
||
("gallery.delete", "Delete…"),
|
||
("gallery.group.selection", "Selection"),
|
||
("gallery.row.format", "Format"),
|
||
("gallery.row.pages", "Pages"),
|
||
("gallery.empty.pages", "No pages"),
|
||
("gallery.task.done", "Export done"),
|
||
("gallery.task.cancelled", "Export cancelled"),
|
||
("gallery.task.progress", "Export {state} · Cancel"),
|
||
("gallery.task.retry", "{error} · Retry"),
|
||
("gallery.error.disk_full", "The disk is full"),
|
||
("gallery.rename.title", "Rename Page"),
|
||
("gallery.rename.submit", "Rename"),
|
||
("gallery.rename.empty", "A page needs a name"),
|
||
("gallery.rename.placeholder", "Page name"),
|
||
(
|
||
"gallery.rename.failed",
|
||
"The disk is full; the name was not saved",
|
||
),
|
||
("gallery.delete.title", "Delete {title}?"),
|
||
(
|
||
"gallery.delete.message",
|
||
"{title} and its items are gone for good.",
|
||
),
|
||
("gallery.delete.confirm", "Delete Page"),
|
||
];
|
||
|
||
const ZH_CN: &[(&str, &str)] = &[
|
||
("menu.app.quit", "退出 {app}"),
|
||
("menu.app.switch", "打开 Ely 应用"),
|
||
("toast.open", "打开"),
|
||
("toast.open_failed", "文件没能打开:{error}"),
|
||
("menu.app.switch_failed", "{app} 没能打开:{error}"),
|
||
("menu.file", "文件"),
|
||
("menu.insert", "插入"),
|
||
("command.file.new", "新建"),
|
||
("command.file.open", "打开…"),
|
||
("command.file.save", "保存"),
|
||
("command.file.save_as", "另存为…"),
|
||
("command.file.rename", "重命名…"),
|
||
("command.file.export", "导出…"),
|
||
("command.file.print", "打印…"),
|
||
("command.blocked.no_document", "没有打开的文档"),
|
||
("palette.group.file", "文件"),
|
||
("gallery.ready", "就绪"),
|
||
("gallery.nav", "导航"),
|
||
("gallery.inbox", "收件箱"),
|
||
("gallery.archive", "归档"),
|
||
("gallery.props", "属性"),
|
||
("gallery.content", "内容"),
|
||
("gallery.mixed", "混合"),
|
||
("gallery.content_of", "{page}的内容"),
|
||
("gallery.rename", "重命名…"),
|
||
("gallery.delete", "删除…"),
|
||
("gallery.group.selection", "所选"),
|
||
("gallery.row.format", "格式"),
|
||
("gallery.row.pages", "页数"),
|
||
("gallery.empty.pages", "没有页面"),
|
||
("gallery.task.done", "导出完成"),
|
||
("gallery.task.cancelled", "导出已取消"),
|
||
("gallery.task.progress", "导出 {state} · 取消"),
|
||
("gallery.task.retry", "{error} · 重试"),
|
||
("gallery.error.disk_full", "磁盘已满"),
|
||
("gallery.rename.title", "重命名页面"),
|
||
("gallery.rename.submit", "重命名"),
|
||
("gallery.rename.empty", "页面需要名称"),
|
||
("gallery.rename.placeholder", "页面名称"),
|
||
("gallery.rename.failed", "磁盘已满,名称未保存"),
|
||
("gallery.delete.title", "删除{title}?"),
|
||
("gallery.delete.message", "{title}及其内容将被永久删除。"),
|
||
("gallery.delete.confirm", "删除页面"),
|
||
];
|
||
|
||
/// zh-* maps to zh-CN; anything else to en-US.
|
||
pub fn resolve(tag: &str) -> &'static str {
|
||
if tag.to_ascii_lowercase().starts_with("zh") {
|
||
"zh-CN"
|
||
} else {
|
||
"en-US"
|
||
}
|
||
}
|
||
|
||
/// Installs the catalogs and resolves the locale.
|
||
pub fn install(cx: &mut App) {
|
||
let tag = locale_tag(cx);
|
||
let locale = resolve(&tag);
|
||
log::info!("i18n: locale {tag} -> {locale}");
|
||
let en: Vec<_> = EN
|
||
.iter()
|
||
.chain(office::EN)
|
||
.chain(doc::EN)
|
||
.chain(refs::EN)
|
||
.chain(tools::EN)
|
||
.chain(table::EN)
|
||
.chain(calc::EN)
|
||
.chain(data::EN)
|
||
.chain(analysis::EN)
|
||
.chain(output::EN)
|
||
.chain(show::EN)
|
||
.chain(motion::EN)
|
||
.chain(play::EN)
|
||
.chain(pdf::EN)
|
||
.chain(secure::EN)
|
||
.chain(tree::EN)
|
||
.chain(tree_ops::EN)
|
||
.chain(tree_places::EN)
|
||
.chain(web::EN)
|
||
.chain(mark::EN)
|
||
.chain(settings::EN)
|
||
.copied()
|
||
.collect();
|
||
let zh: Vec<_> = ZH_CN
|
||
.iter()
|
||
.chain(office::ZH_CN)
|
||
.chain(doc::ZH_CN)
|
||
.chain(refs::ZH_CN)
|
||
.chain(tools::ZH_CN)
|
||
.chain(table::ZH_CN)
|
||
.chain(calc::ZH_CN)
|
||
.chain(data::ZH_CN)
|
||
.chain(analysis::ZH_CN)
|
||
.chain(output::ZH_CN)
|
||
.chain(show::ZH_CN)
|
||
.chain(motion::ZH_CN)
|
||
.chain(play::ZH_CN)
|
||
.chain(pdf::ZH_CN)
|
||
.chain(secure::ZH_CN)
|
||
.chain(tree::ZH_CN)
|
||
.chain(tree_ops::ZH_CN)
|
||
.chain(tree_places::ZH_CN)
|
||
.chain(web::ZH_CN)
|
||
.chain(mark::ZH_CN)
|
||
.chain(settings::ZH_CN)
|
||
.copied()
|
||
.collect();
|
||
cx.set_global(
|
||
I18n::new(locale)
|
||
.catalog("en-US", &en)
|
||
.catalog("zh-CN", &zh),
|
||
);
|
||
}
|
||
|
||
/// `ELY_LOCALE`, then the language setting, then the system's.
|
||
fn locale_tag(cx: &App) -> String {
|
||
use ely_platform::settings::{Language, word};
|
||
match crate::settings::current(cx).language {
|
||
Language::System => ely_platform::locale::system(),
|
||
_ if ely_platform::env::value("ELY_LOCALE").is_some() => ely_platform::locale::system(),
|
||
chosen => word(&Language::ALL, &chosen).into(),
|
||
}
|
||
}
|
||
|
||
pub fn text(cx: &App, key: &str, args: &[(&str, &str)]) -> SharedString {
|
||
cx.global::<I18n>().text(key, args)
|
||
}
|
||
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use super::resolve;
|
||
|
||
#[test]
|
||
fn zh_variants_pick_zh_cn_others_pick_en() {
|
||
for tag in ["zh-CN", "zh-Hans", "zh", "ZH-TW"] {
|
||
assert_eq!(resolve(tag), "zh-CN", "{tag}");
|
||
}
|
||
for tag in ["en", "en-US", "fr", "ja", "", "x9!"] {
|
||
assert_eq!(resolve(tag), "en-US", "{tag}");
|
||
}
|
||
}
|
||
}
|