mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 16:56:36 -04:00
FString -> TR
This commit is contained in:
parent
5392bd8e28
commit
546f4b44fc
7 changed files with 65 additions and 72 deletions
|
@ -11,7 +11,7 @@ use crate::config::SortKind;
|
|||
use crate::deckconf::{DeckConf, DeckConfID};
|
||||
use crate::decks::DeckID;
|
||||
use crate::err::{AnkiError, NetworkErrorKind, Result, SyncErrorKind};
|
||||
use crate::i18n::{tr_args, FString, I18n};
|
||||
use crate::i18n::{tr_args, I18n, TR};
|
||||
use crate::latex::{extract_latex, extract_latex_expanding_clozes, ExtractedLatex};
|
||||
use crate::log::{default_logger, Logger};
|
||||
use crate::media::check::MediaChecker;
|
||||
|
@ -771,7 +771,7 @@ fn progress_to_proto_bytes(progress: Progress, i18n: &I18n) -> Vec<u8> {
|
|||
value: Some(match progress {
|
||||
Progress::MediaSync(p) => pb::progress::Value::MediaSync(media_sync_progress(p, i18n)),
|
||||
Progress::MediaCheck(n) => {
|
||||
let s = i18n.trn(FString::MediaCheckChecked, tr_args!["count"=>n]);
|
||||
let s = i18n.trn(TR::MediaCheckChecked, tr_args!["count"=>n]);
|
||||
pb::progress::Value::MediaCheck(s)
|
||||
}
|
||||
}),
|
||||
|
@ -784,13 +784,13 @@ fn progress_to_proto_bytes(progress: Progress, i18n: &I18n) -> Vec<u8> {
|
|||
|
||||
fn media_sync_progress(p: &MediaSyncProgress, i18n: &I18n) -> pb::MediaSyncProgress {
|
||||
pb::MediaSyncProgress {
|
||||
checked: i18n.trn(FString::SyncMediaCheckedCount, tr_args!["count"=>p.checked]),
|
||||
checked: i18n.trn(TR::SyncMediaCheckedCount, tr_args!["count"=>p.checked]),
|
||||
added: i18n.trn(
|
||||
FString::SyncMediaAddedCount,
|
||||
TR::SyncMediaAddedCount,
|
||||
tr_args!["up"=>p.uploaded_files,"down"=>p.downloaded_files],
|
||||
),
|
||||
removed: i18n.trn(
|
||||
FString::SyncMediaRemovedCount,
|
||||
TR::SyncMediaRemovedCount,
|
||||
tr_args!["up"=>p.uploaded_deletions,"down"=>p.downloaded_deletions],
|
||||
),
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
use crate::i18n::{tr_strs, FString, I18n};
|
||||
use crate::i18n::{tr_strs, I18n, TR};
|
||||
pub use failure::{Error, Fail};
|
||||
use reqwest::StatusCode;
|
||||
use std::io;
|
||||
|
@ -69,21 +69,21 @@ impl AnkiError {
|
|||
AnkiError::SyncError { info, kind } => match kind {
|
||||
SyncErrorKind::ServerMessage => info.into(),
|
||||
SyncErrorKind::Other => info.into(),
|
||||
SyncErrorKind::Conflict => i18n.tr(FString::SyncConflict),
|
||||
SyncErrorKind::ServerError => i18n.tr(FString::SyncServerError),
|
||||
SyncErrorKind::ClientTooOld => i18n.tr(FString::SyncClientTooOld),
|
||||
SyncErrorKind::AuthFailed => i18n.tr(FString::SyncWrongPass),
|
||||
SyncErrorKind::ResyncRequired => i18n.tr(FString::SyncResyncRequired),
|
||||
SyncErrorKind::Conflict => i18n.tr(TR::SyncConflict),
|
||||
SyncErrorKind::ServerError => i18n.tr(TR::SyncServerError),
|
||||
SyncErrorKind::ClientTooOld => i18n.tr(TR::SyncClientTooOld),
|
||||
SyncErrorKind::AuthFailed => i18n.tr(TR::SyncWrongPass),
|
||||
SyncErrorKind::ResyncRequired => i18n.tr(TR::SyncResyncRequired),
|
||||
}
|
||||
.into(),
|
||||
AnkiError::NetworkError { kind, info } => {
|
||||
let summary = match kind {
|
||||
NetworkErrorKind::Offline => i18n.tr(FString::NetworkOffline),
|
||||
NetworkErrorKind::Timeout => i18n.tr(FString::NetworkTimeout),
|
||||
NetworkErrorKind::ProxyAuth => i18n.tr(FString::NetworkProxyAuth),
|
||||
NetworkErrorKind::Other => i18n.tr(FString::NetworkOther),
|
||||
NetworkErrorKind::Offline => i18n.tr(TR::NetworkOffline),
|
||||
NetworkErrorKind::Timeout => i18n.tr(TR::NetworkTimeout),
|
||||
NetworkErrorKind::ProxyAuth => i18n.tr(TR::NetworkProxyAuth),
|
||||
NetworkErrorKind::Other => i18n.tr(TR::NetworkOther),
|
||||
};
|
||||
let details = i18n.trn(FString::NetworkDetails, tr_strs!["details"=>info]);
|
||||
let details = i18n.trn(TR::NetworkDetails, tr_strs!["details"=>info]);
|
||||
format!("{}\n\n{}", summary, details)
|
||||
}
|
||||
AnkiError::TemplateError { info } => {
|
||||
|
|
|
@ -15,10 +15,9 @@ use unic_langid::LanguageIdentifier;
|
|||
mod autogen;
|
||||
use crate::i18n::autogen::FLUENT_KEYS;
|
||||
|
||||
pub use crate::backend_proto::FluentString as TR;
|
||||
pub use fluent::fluent_args as tr_args;
|
||||
|
||||
pub use crate::backend_proto::FluentString as FString;
|
||||
|
||||
/// Helper for creating args with &strs
|
||||
#[macro_export]
|
||||
macro_rules! tr_strs {
|
||||
|
@ -284,13 +283,13 @@ impl I18n {
|
|||
}
|
||||
|
||||
/// Get translation with zero arguments.
|
||||
pub fn tr(&self, key: FString) -> Cow<str> {
|
||||
pub fn tr(&self, key: TR) -> Cow<str> {
|
||||
let key = FLUENT_KEYS[key as usize];
|
||||
self.tr_(key, None)
|
||||
}
|
||||
|
||||
/// Get translation with one or more arguments.
|
||||
pub fn trn(&self, key: FString, args: FluentArgs) -> String {
|
||||
pub fn trn(&self, key: TR, args: FluentArgs) -> String {
|
||||
let key = FLUENT_KEYS[key as usize];
|
||||
self.tr_(key, Some(args)).into()
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
use crate::collection::Collection;
|
||||
use crate::err::{AnkiError, DBErrorKind, Result};
|
||||
use crate::i18n::{tr_args, tr_strs, FString};
|
||||
use crate::i18n::{tr_args, tr_strs, TR};
|
||||
use crate::latex::extract_latex_expanding_clozes;
|
||||
use crate::log::debug;
|
||||
use crate::media::database::MediaDatabaseContext;
|
||||
|
@ -99,41 +99,41 @@ where
|
|||
if output.trash_count > 0 {
|
||||
let megs = (output.trash_bytes as f32) / 1024.0 / 1024.0;
|
||||
buf += &i.trn(
|
||||
FString::MediaCheckTrashCount,
|
||||
TR::MediaCheckTrashCount,
|
||||
tr_args!["count"=>output.trash_count, "megs"=>megs],
|
||||
);
|
||||
buf.push('\n');
|
||||
}
|
||||
|
||||
buf += &i.trn(
|
||||
FString::MediaCheckMissingCount,
|
||||
TR::MediaCheckMissingCount,
|
||||
tr_args!["count"=>output.missing.len()],
|
||||
);
|
||||
buf.push('\n');
|
||||
|
||||
buf += &i.trn(
|
||||
FString::MediaCheckUnusedCount,
|
||||
TR::MediaCheckUnusedCount,
|
||||
tr_args!["count"=>output.unused.len()],
|
||||
);
|
||||
buf.push('\n');
|
||||
|
||||
if !output.renamed.is_empty() {
|
||||
buf += &i.trn(
|
||||
FString::MediaCheckRenamedCount,
|
||||
TR::MediaCheckRenamedCount,
|
||||
tr_args!["count"=>output.renamed.len()],
|
||||
);
|
||||
buf.push('\n');
|
||||
}
|
||||
if !output.oversize.is_empty() {
|
||||
buf += &i.trn(
|
||||
FString::MediaCheckOversizeCount,
|
||||
TR::MediaCheckOversizeCount,
|
||||
tr_args!["count"=>output.oversize.len()],
|
||||
);
|
||||
buf.push('\n');
|
||||
}
|
||||
if !output.dirs.is_empty() {
|
||||
buf += &i.trn(
|
||||
FString::MediaCheckSubfolderCount,
|
||||
TR::MediaCheckSubfolderCount,
|
||||
tr_args!["count"=>output.dirs.len()],
|
||||
);
|
||||
buf.push('\n');
|
||||
|
@ -142,13 +142,10 @@ where
|
|||
buf.push('\n');
|
||||
|
||||
if !output.renamed.is_empty() {
|
||||
buf += &i.tr(FString::MediaCheckRenamedHeader);
|
||||
buf += &i.tr(TR::MediaCheckRenamedHeader);
|
||||
buf.push('\n');
|
||||
for (old, new) in &output.renamed {
|
||||
buf += &i.trn(
|
||||
FString::MediaCheckRenamedFile,
|
||||
tr_strs!["old"=>old,"new"=>new],
|
||||
);
|
||||
buf += &i.trn(TR::MediaCheckRenamedFile, tr_strs!["old"=>old,"new"=>new]);
|
||||
buf.push('\n');
|
||||
}
|
||||
buf.push('\n')
|
||||
|
@ -156,10 +153,10 @@ where
|
|||
|
||||
if !output.oversize.is_empty() {
|
||||
output.oversize.sort();
|
||||
buf += &i.tr(FString::MediaCheckOversizeHeader);
|
||||
buf += &i.tr(TR::MediaCheckOversizeHeader);
|
||||
buf.push('\n');
|
||||
for fname in &output.oversize {
|
||||
buf += &i.trn(FString::MediaCheckOversizeFile, tr_strs!["filename"=>fname]);
|
||||
buf += &i.trn(TR::MediaCheckOversizeFile, tr_strs!["filename"=>fname]);
|
||||
buf.push('\n');
|
||||
}
|
||||
buf.push('\n')
|
||||
|
@ -167,13 +164,10 @@ where
|
|||
|
||||
if !output.dirs.is_empty() {
|
||||
output.dirs.sort();
|
||||
buf += &i.tr(FString::MediaCheckSubfolderHeader);
|
||||
buf += &i.tr(TR::MediaCheckSubfolderHeader);
|
||||
buf.push('\n');
|
||||
for fname in &output.dirs {
|
||||
buf += &i.trn(
|
||||
FString::MediaCheckSubfolderFile,
|
||||
tr_strs!["filename"=>fname],
|
||||
);
|
||||
buf += &i.trn(TR::MediaCheckSubfolderFile, tr_strs!["filename"=>fname]);
|
||||
buf.push('\n');
|
||||
}
|
||||
buf.push('\n')
|
||||
|
@ -181,10 +175,10 @@ where
|
|||
|
||||
if !output.missing.is_empty() {
|
||||
output.missing.sort();
|
||||
buf += &i.tr(FString::MediaCheckMissingHeader);
|
||||
buf += &i.tr(TR::MediaCheckMissingHeader);
|
||||
buf.push('\n');
|
||||
for fname in &output.missing {
|
||||
buf += &i.trn(FString::MediaCheckMissingFile, tr_strs!["filename"=>fname]);
|
||||
buf += &i.trn(TR::MediaCheckMissingFile, tr_strs!["filename"=>fname]);
|
||||
buf.push('\n');
|
||||
}
|
||||
buf.push('\n')
|
||||
|
@ -192,10 +186,10 @@ where
|
|||
|
||||
if !output.unused.is_empty() {
|
||||
output.unused.sort();
|
||||
buf += &i.tr(FString::MediaCheckUnusedHeader);
|
||||
buf += &i.tr(TR::MediaCheckUnusedHeader);
|
||||
buf.push('\n');
|
||||
for fname in &output.unused {
|
||||
buf += &i.trn(FString::MediaCheckUnusedFile, tr_strs!["filename"=>fname]);
|
||||
buf += &i.trn(TR::MediaCheckUnusedFile, tr_strs!["filename"=>fname]);
|
||||
buf.push('\n');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
use crate::i18n::{tr_args, FString, I18n};
|
||||
use crate::i18n::{tr_args, I18n, TR};
|
||||
|
||||
/// Short string like '4d' to place above answer buttons.
|
||||
pub fn answer_button_time(seconds: f32, i18n: &I18n) -> String {
|
||||
let span = Timespan::from_secs(seconds).natural_span();
|
||||
let args = tr_args!["amount" => span.as_rounded_unit()];
|
||||
let key = match span.unit() {
|
||||
TimespanUnit::Seconds => FString::SchedulingAnswerButtonTimeSeconds,
|
||||
TimespanUnit::Minutes => FString::SchedulingAnswerButtonTimeMinutes,
|
||||
TimespanUnit::Hours => FString::SchedulingAnswerButtonTimeHours,
|
||||
TimespanUnit::Days => FString::SchedulingAnswerButtonTimeDays,
|
||||
TimespanUnit::Months => FString::SchedulingAnswerButtonTimeMonths,
|
||||
TimespanUnit::Years => FString::SchedulingAnswerButtonTimeYears,
|
||||
TimespanUnit::Seconds => TR::SchedulingAnswerButtonTimeSeconds,
|
||||
TimespanUnit::Minutes => TR::SchedulingAnswerButtonTimeMinutes,
|
||||
TimespanUnit::Hours => TR::SchedulingAnswerButtonTimeHours,
|
||||
TimespanUnit::Days => TR::SchedulingAnswerButtonTimeDays,
|
||||
TimespanUnit::Months => TR::SchedulingAnswerButtonTimeMonths,
|
||||
TimespanUnit::Years => TR::SchedulingAnswerButtonTimeYears,
|
||||
};
|
||||
i18n.trn(key, args)
|
||||
}
|
||||
|
@ -31,12 +31,12 @@ pub fn time_span(seconds: f32, i18n: &I18n, precise: bool) -> String {
|
|||
};
|
||||
let args = tr_args!["amount" => amount];
|
||||
let key = match span.unit() {
|
||||
TimespanUnit::Seconds => FString::SchedulingTimeSpanSeconds,
|
||||
TimespanUnit::Minutes => FString::SchedulingTimeSpanMinutes,
|
||||
TimespanUnit::Hours => FString::SchedulingTimeSpanHours,
|
||||
TimespanUnit::Days => FString::SchedulingTimeSpanDays,
|
||||
TimespanUnit::Months => FString::SchedulingTimeSpanMonths,
|
||||
TimespanUnit::Years => FString::SchedulingTimeSpanYears,
|
||||
TimespanUnit::Seconds => TR::SchedulingTimeSpanSeconds,
|
||||
TimespanUnit::Minutes => TR::SchedulingTimeSpanMinutes,
|
||||
TimespanUnit::Hours => TR::SchedulingTimeSpanHours,
|
||||
TimespanUnit::Days => TR::SchedulingTimeSpanDays,
|
||||
TimespanUnit::Months => TR::SchedulingTimeSpanMonths,
|
||||
TimespanUnit::Years => TR::SchedulingTimeSpanYears,
|
||||
};
|
||||
i18n.trn(key, args)
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ pub fn studied_today(cards: usize, secs: f32, i18n: &I18n) -> String {
|
|||
};
|
||||
let args = tr_args!["amount" => amount, "unit" => unit,
|
||||
"cards" => cards, "secs-per-card" => secs_per];
|
||||
i18n.trn(FString::StatisticsStudiedToday, args)
|
||||
i18n.trn(TR::StatisticsStudiedToday, args)
|
||||
}
|
||||
|
||||
// fixme: this doesn't belong here
|
||||
|
@ -70,8 +70,8 @@ pub fn learning_congrats(remaining: usize, next_due: f32, i18n: &I18n) -> String
|
|||
let remaining_args = tr_args!["remaining" => remaining];
|
||||
format!(
|
||||
"{} {}",
|
||||
i18n.trn(FString::SchedulingNextLearnDue, next_args),
|
||||
i18n.trn(FString::SchedulingLearnRemaining, remaining_args)
|
||||
i18n.trn(TR::SchedulingNextLearnDue, next_args),
|
||||
i18n.trn(TR::SchedulingLearnRemaining, remaining_args)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ use super::SqliteStorage;
|
|||
use crate::{
|
||||
deckconf::{DeckConf, DeckConfID},
|
||||
err::Result,
|
||||
i18n::{FString, I18n},
|
||||
i18n::{I18n, TR},
|
||||
};
|
||||
use rusqlite::{params, NO_PARAMS};
|
||||
use std::collections::HashMap;
|
||||
|
@ -75,7 +75,7 @@ impl SqliteStorage {
|
|||
pub(super) fn add_default_deck_config(&self, i18n: &I18n) -> Result<()> {
|
||||
let mut conf = DeckConf::default();
|
||||
conf.id.0 = 1;
|
||||
conf.name = i18n.tr(FString::DeckConfigDefaultName).into();
|
||||
conf.name = i18n.tr(TR::DeckConfigDefaultName).into();
|
||||
self.add_deck_conf(&mut conf)
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
use crate::err::{AnkiError, Result, TemplateError};
|
||||
use crate::i18n::{tr_strs, FString, I18n};
|
||||
use crate::i18n::{tr_strs, I18n, TR};
|
||||
use crate::template_filters::apply_filters;
|
||||
use lazy_static::lazy_static;
|
||||
use nom::branch::alt;
|
||||
|
@ -196,12 +196,12 @@ fn parse_inner<'a, I: Iterator<Item = TemplateResult<Token<'a>>>>(
|
|||
|
||||
fn template_error_to_anki_error(err: TemplateError, q_side: bool, i18n: &I18n) -> AnkiError {
|
||||
let header = i18n.tr(if q_side {
|
||||
FString::CardTemplateRenderingFrontSideProblem
|
||||
TR::CardTemplateRenderingFrontSideProblem
|
||||
} else {
|
||||
FString::CardTemplateRenderingBackSideProblem
|
||||
TR::CardTemplateRenderingBackSideProblem
|
||||
});
|
||||
let details = localized_template_error(i18n, err);
|
||||
let more_info = i18n.tr(FString::CardTemplateRenderingMoreInfo);
|
||||
let more_info = i18n.tr(TR::CardTemplateRenderingMoreInfo);
|
||||
let info = format!(
|
||||
"{}<br>{}<br><a href='{}'>{}</a>",
|
||||
header, details, TEMPLATE_ERROR_LINK, more_info
|
||||
|
@ -213,11 +213,11 @@ fn template_error_to_anki_error(err: TemplateError, q_side: bool, i18n: &I18n) -
|
|||
fn localized_template_error(i18n: &I18n, err: TemplateError) -> String {
|
||||
match err {
|
||||
TemplateError::NoClosingBrackets(tag) => i18n.trn(
|
||||
FString::CardTemplateRenderingNoClosingBrackets,
|
||||
TR::CardTemplateRenderingNoClosingBrackets,
|
||||
tr_strs!("tag"=>tag, "missing"=>"}}"),
|
||||
),
|
||||
TemplateError::ConditionalNotClosed(tag) => i18n.trn(
|
||||
FString::CardTemplateRenderingConditionalNotClosed,
|
||||
TR::CardTemplateRenderingConditionalNotClosed,
|
||||
tr_strs!("missing"=>format!("{{{{/{}}}}}", tag)),
|
||||
),
|
||||
TemplateError::ConditionalNotOpen {
|
||||
|
@ -226,14 +226,14 @@ fn localized_template_error(i18n: &I18n, err: TemplateError) -> String {
|
|||
} => {
|
||||
if let Some(open) = currently_open {
|
||||
i18n.trn(
|
||||
FString::CardTemplateRenderingWrongConditionalClosed,
|
||||
TR::CardTemplateRenderingWrongConditionalClosed,
|
||||
tr_strs!(
|
||||
"found"=>format!("{{{{/{}}}}}", closed),
|
||||
"expected"=>format!("{{{{/{}}}}}", open)),
|
||||
)
|
||||
} else {
|
||||
i18n.trn(
|
||||
FString::CardTemplateRenderingConditionalNotOpen,
|
||||
TR::CardTemplateRenderingConditionalNotOpen,
|
||||
tr_strs!(
|
||||
"found"=>format!("{{{{/{}}}}}", closed),
|
||||
"missing1"=>format!("{{{{#{}}}}}", closed),
|
||||
|
@ -243,7 +243,7 @@ fn localized_template_error(i18n: &I18n, err: TemplateError) -> String {
|
|||
}
|
||||
}
|
||||
TemplateError::FieldNotFound { field, filters } => i18n.trn(
|
||||
FString::CardTemplateRenderingNoSuchField,
|
||||
TR::CardTemplateRenderingNoSuchField,
|
||||
tr_strs!(
|
||||
"found"=>format!("{{{{{}{}}}}}", filters, field),
|
||||
"field"=>field),
|
||||
|
@ -509,9 +509,9 @@ pub fn render_card(
|
|||
if !qtmpl.renders_with_fields(context.nonempty_fields) {
|
||||
let info = format!(
|
||||
"{}<br><a href='{}'>{}</a>",
|
||||
i18n.tr(FString::CardTemplateRenderingEmptyFront),
|
||||
i18n.tr(TR::CardTemplateRenderingEmptyFront),
|
||||
TEMPLATE_BLANK_LINK,
|
||||
i18n.tr(FString::CardTemplateRenderingMoreInfo)
|
||||
i18n.tr(TR::CardTemplateRenderingMoreInfo)
|
||||
);
|
||||
return Err(AnkiError::TemplateError { info });
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue