Files
wordcraft/crates/engine/src/prefs.rs
T

134 lines
6.3 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
use serde::{Deserialize, Serialize};
/// Editing preferences that persist between runs (the front end saves and restores them).
/// File › Options sets most of them (`file.options`).
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(default, rename_all = "camelCase")]
pub struct Prefs {
/// Word Count includes text boxes, footnotes and endnotes (Word's default).
pub count_notes: bool,
/// Track Changes Options: what markup shows and how revisions are drawn (per user, as in
/// Word).
pub markup: wordcraft_layout::display::MarkupOptions,
/// File › Print / Export: Print Markup. PDFs, prints and page images show comments in
/// balloons beside each page and tracked changes as marked up; HTML, Markdown and text
/// copies end with the comments (`file.printMarkup`).
pub print_markup: bool,
/// Language › Detect language automatically (per user, as in Word).
pub detect_language: bool,
/// Set Proofing Language › Set As Default: overrides the interface language for future
/// blank documents and plain text. Older preferences keep following the interface.
#[serde(deserialize_with = "lenient_default_language")]
pub default_language: Option<String>,
/// Typing over a selection replaces it; off, the typed text goes in front of it.
pub typing_replaces_selection: bool,
/// The Insert key switches overtype on and off.
pub insert_key_overtype: bool,
/// Overtype: typed characters replace the ones after the caret.
pub overtype: bool,
/// The unit rulers and dialogs show lengths in, when the user chose one (File › Options ›
/// Advanced › Measurement units); `None` follows the region ([`Session::units`]). Saved under
/// a new key; an older `units` value other than inches (the old default) carries over on load.
#[serde(rename = "measurementUnits")]
pub units: Option<wordcraft_geom::Unit>,
/// The region the user chose for new documents, units and the decimal separator (a locale
/// tag like `pl-PL`, File › Options › Advanced › Region); `None` follows the system.
pub region: Option<String>,
/// A folder searched for Hunspell dictionaries before the system locations (File › Options ›
/// Language, #1063): an app started from Finder or the Dock doesn't see
/// `WORDCRAFT_DICTIONARIES`. `None` searches the system locations only.
pub dictionaries_folder: Option<String>,
/// The user templates folder File › New lists personal templates from and Save as Word
/// Template starts in (File › Options › Advanced › File locations, #2852). `None`: the app's
/// own `Templates` folder in its settings folder.
pub user_templates_folder: Option<String>,
/// Formatting marks shown even while Show/Hide ¶ is off.
pub marks: wordcraft_layout::display::FormattingMarks,
/// Mark grammar errors as you type (with Check spelling as you type on).
pub mark_grammar: bool,
/// Check spelling as you type (File › Options › Proofing). The live value is
/// `ViewState::proofing`; this is the copy that is saved and restored (#1792).
pub check_spelling: bool,
/// Read Mode's Page Color. The live value is `ViewState::read_page_color`.
#[serde(deserialize_with = "lenient_read_page_color")]
pub read_page_color: crate::cmd::view::ReadPageColor,
pub ignore_uppercase: bool,
pub ignore_numbers: bool,
pub ignore_internet: bool,
/// AutoCorrect Options: replacements, capitalization and AutoFormat As You Type (per user, as
/// in Word). A damaged saved value reads as the defaults.
#[serde(deserialize_with = "crate::cmd::tools::lenient_autocorrect")]
pub autocorrect: crate::cmd::tools::AutoCorrectPrefs,
}
impl Default for Prefs {
fn default() -> Self {
Prefs {
count_notes: true,
markup: Default::default(),
print_markup: false,
typing_replaces_selection: true,
insert_key_overtype: false,
overtype: false,
units: Default::default(),
region: None,
dictionaries_folder: None,
user_templates_folder: None,
marks: Default::default(),
mark_grammar: true,
check_spelling: true,
read_page_color: Default::default(),
ignore_uppercase: true,
ignore_numbers: true,
ignore_internet: true,
detect_language: true,
default_language: None,
autocorrect: Default::default(),
}
}
}
impl Prefs {
/// What the spelling check skips.
pub fn spelling(&self) -> wordcraft_proof::Options {
wordcraft_proof::Options {
ignore_uppercase: self.ignore_uppercase,
ignore_numbers: self.ignore_numbers,
ignore_internet: self.ignore_internet,
}
}
}
/// Ignore malformed saved language tags without discarding the other preferences.
fn lenient_default_language<'de, D: serde::Deserializer<'de>>(d: D) -> Result<Option<String>, D::Error> {
let value = serde_json::Value::deserialize(d)?;
Ok(value.as_str().and_then(wordcraft_proof::lang::normalize_tag))
}
/// Ignore an invalid saved Page Color without discarding other preferences.
fn lenient_read_page_color<'de, D: serde::Deserializer<'de>>(d: D) -> Result<crate::cmd::view::ReadPageColor, D::Error> {
let value = serde_json::Value::deserialize(d)?;
Ok(serde_json::from_value(value).unwrap_or_default())
}
#[cfg(test)]
mod tests {
use super::Prefs;
use crate::cmd::view::ReadPageColor;
#[test]
fn read_page_color_loads_from_old_and_damaged_prefs() {
let old: Prefs = serde_json::from_str(r#"{"checkSpelling":false}"#).unwrap();
assert_eq!(old.read_page_color, ReadPageColor::None);
assert!(!old.check_spelling);
for bad in [r#"{"readPageColor":"unknown","checkSpelling":false}"#, r#"{"readPageColor":42,"checkSpelling":false}"#] {
let prefs: Prefs = serde_json::from_str(bad).unwrap();
assert_eq!(prefs.read_page_color, ReadPageColor::None);
assert!(!prefs.check_spelling);
}
let saved: Prefs = serde_json::from_str(r#"{"readPageColor":"sepia"}"#).unwrap();
assert_eq!(saved.read_page_color, ReadPageColor::Sepia);
assert_eq!(serde_json::to_value(saved).unwrap()["readPageColor"], "sepia");
}
}