From d1cbb86178e5e37f44d26eca9dfa0ed3e93cbfe4 Mon Sep 17 00:00:00 2001 From: Matthias Metelka <62722460+kleinerpirat@users.noreply.github.com> Date: Thu, 18 Aug 2022 04:30:18 +0200 Subject: [PATCH] Default input setting in fields dialog (#1987) * Introduce field setting to use plain text editor by default * Remove leftover function from #1476 * Use boolean instead of string * Simplify clear_other_field_duplicates * Convert plain text key to camelCase * Move HTML item below the existing checkbox, instead of to the right (dae) Showing it on the right is more space efficient, but feels a bit cluttered IMHO. --- ftl/core/fields.ftl | 1 + proto/anki/notetypes.proto | 1 + qt/aqt/editor.py | 14 +++++- qt/aqt/fields.py | 5 +++ qt/aqt/forms/fields.ui | 76 ++++++++++++++++++-------------- rslib/src/notetype/fields.rs | 1 + rslib/src/notetype/schema11.rs | 9 +++- ts/components/WithTooltip.svelte | 11 ----- ts/editor/EditorField.svelte | 1 + ts/editor/NoteEditor.svelte | 16 ++++--- 10 files changed, 84 insertions(+), 51 deletions(-) diff --git a/ftl/core/fields.ftl b/ftl/core/fields.ftl index 3f8b3581f..dfcb6f3f0 100644 --- a/ftl/core/fields.ftl +++ b/ftl/core/fields.ftl @@ -10,6 +10,7 @@ fields-font = Font: fields-new-position-1 = New position (1...{ $val }): fields-notes-require-at-least-one-field = Notes require at least one field. fields-reverse-text-direction-rtl = Reverse text direction (RTL) +fields-html-by-default = Use HTML editor by default fields-size = Size: fields-sort-by-this-field-in-the = Sort by this field in the browser fields-that-field-name-is-already-used = That field name is already used. diff --git a/proto/anki/notetypes.proto b/proto/anki/notetypes.proto index 6bd9d37ab..ff9f0ee0c 100644 --- a/proto/anki/notetypes.proto +++ b/proto/anki/notetypes.proto @@ -72,6 +72,7 @@ message Notetype { string font_name = 3; uint32 font_size = 4; string description = 5; + bool plain_text = 6; bytes other = 255; } diff --git a/qt/aqt/editor.py b/qt/aqt/editor.py index 35e6c9688..1fcc086bf 100644 --- a/qt/aqt/editor.py +++ b/qt/aqt/editor.py @@ -501,6 +501,7 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too ] flds = self.note.note_type()["flds"] + plain_texts = [fld.get("plainText", False) for fld in flds] descriptions = [fld.get("description", "") for fld in flds] self.widget.show() @@ -521,8 +522,19 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too text_color = self.mw.pm.profile.get("lastTextColor", "#00f") highlight_color = self.mw.pm.profile.get("lastHighlightColor", "#00f") - js = "setFields({}); setDescriptions({}); setFonts({}); focusField({}); setNoteId({}); setColorButtons({}); setTags({}); setMathjaxEnabled({});".format( + js = """ + setFields({}); + setPlainTexts({}); + setDescriptions({}); + setFonts({}); + focusField({}); + setNoteId({}); + setColorButtons({}); + setTags({}); + setMathjaxEnabled({}); + """.format( json.dumps(data), + json.dumps(plain_texts), json.dumps(descriptions), json.dumps(self.fonts()), json.dumps(focusTo), diff --git a/qt/aqt/fields.py b/qt/aqt/fields.py index a3c25f938..7bbddfe7b 100644 --- a/qt/aqt/fields.py +++ b/qt/aqt/fields.py @@ -243,6 +243,7 @@ class FieldDialog(QDialog): f.fontSize.setValue(fld["size"]) f.sortField.setChecked(self.model["sortf"] == fld["ord"]) f.rtl.setChecked(fld["rtl"]) + f.plainTextByDefault.setChecked(fld["plainText"]) f.fieldDescription.setText(fld.get("description", "")) def saveField(self) -> None: @@ -264,6 +265,10 @@ class FieldDialog(QDialog): if fld["rtl"] != rtl: fld["rtl"] = rtl self.change_tracker.mark_basic() + plain_text = f.plainTextByDefault.isChecked() + if fld["plainText"] != plain_text: + fld["plainText"] = plain_text + self.change_tracker.mark_basic() desc = f.fieldDescription.text() if fld.get("description", "") != desc: fld["description"] = desc diff --git a/qt/aqt/forms/fields.ui b/qt/aqt/forms/fields.ui index 81f3ce3e0..cb2a04b1b 100644 --- a/qt/aqt/forms/fields.ui +++ b/qt/aqt/forms/fields.ui @@ -6,8 +6,8 @@ 0 0 - 586 - 376 + 598 + 378 @@ -84,13 +84,6 @@ - - - - fields_editing_font - - - @@ -98,13 +91,27 @@ - - - - 5 + + + + + 0 + 25 + - - 300 + + + + + + fields_editing_font + + + + + + + fields_description_placeholder @@ -115,13 +122,6 @@ - - - - fields_sort_by_this_field_in_the - - - @@ -135,20 +135,30 @@ - - - - - 0 - 25 - + + + + 5 + + + 300 - - - - fields_description_placeholder + + + + fields_sort_by_this_field_in_the + + + + + + + true + + + fields_html_by_default diff --git a/rslib/src/notetype/fields.rs b/rslib/src/notetype/fields.rs index 1b126f0cf..ca1908e3d 100644 --- a/rslib/src/notetype/fields.rs +++ b/rslib/src/notetype/fields.rs @@ -42,6 +42,7 @@ impl NoteField { config: NoteFieldConfig { sticky: false, rtl: false, + plain_text: false, font_name: "Arial".into(), font_size: 20, description: "".into(), diff --git a/rslib/src/notetype/schema11.rs b/rslib/src/notetype/schema11.rs index 5db53d56b..0fab7e560 100644 --- a/rslib/src/notetype/schema11.rs +++ b/rslib/src/notetype/schema11.rs @@ -161,7 +161,7 @@ impl From for NotetypeSchema11 { /// See [crate::deckconfig::schema11::clear_other_duplicates()]. fn clear_other_field_duplicates(other: &mut HashMap) { - for key in &["description"] { + for key in &["description", "plainText"] { other.remove(*key); } } @@ -195,6 +195,7 @@ impl From for CardRequirementSchema11 { } #[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] pub struct NoteFieldSchema11 { pub(crate) name: String, pub(crate) ord: Option, @@ -211,6 +212,9 @@ pub struct NoteFieldSchema11 { #[serde(default, deserialize_with = "default_on_invalid")] pub(crate) description: String, + #[serde(default, deserialize_with = "default_on_invalid")] + pub(crate) plain_text: bool, + #[serde(flatten)] pub(crate) other: HashMap, } @@ -222,6 +226,7 @@ impl Default for NoteFieldSchema11 { ord: None, sticky: false, rtl: false, + plain_text: false, font: "Arial".to_string(), size: 20, description: String::new(), @@ -238,6 +243,7 @@ impl From for NoteField { config: NoteFieldConfig { sticky: f.sticky, rtl: f.rtl, + plain_text: f.plain_text, font_name: f.font, font_size: f.size as u32, description: f.description, @@ -259,6 +265,7 @@ impl From for NoteFieldSchema11 { ord: p.ord.map(|o| o as u16), sticky: conf.sticky, rtl: conf.rtl, + plain_text: conf.plain_text, font: conf.font_name, size: conf.font_size as u16, description: conf.description, diff --git a/ts/components/WithTooltip.svelte b/ts/components/WithTooltip.svelte index 6adbb7c11..6ad68a673 100644 --- a/ts/components/WithTooltip.svelte +++ b/ts/components/WithTooltip.svelte @@ -38,17 +38,6 @@ } onDestroy(() => tooltipObject?.dispose()); - - // hack to update field description tooltips - let previousTooltip: string = tooltip; - $: if (tooltip !== previousTooltip) { - previousTooltip = tooltip; - if (tooltipObject !== undefined) { - const element: HTMLElement = tooltipObject["_element"]; - tooltipObject.dispose(); - createTooltip(element); - } - } diff --git a/ts/editor/EditorField.svelte b/ts/editor/EditorField.svelte index 447460e10..23588ffb6 100644 --- a/ts/editor/EditorField.svelte +++ b/ts/editor/EditorField.svelte @@ -12,6 +12,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html fontFamily: string; fontSize: number; direction: "ltr" | "rtl"; + plainText: boolean; description: string; } diff --git a/ts/editor/NoteEditor.svelte b/ts/editor/NoteEditor.svelte index 5cbb02321..29ea40f07 100644 --- a/ts/editor/NoteEditor.svelte +++ b/ts/editor/NoteEditor.svelte @@ -109,6 +109,15 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html fieldNames = newFieldNames; } + let plainTexts: boolean[] = []; + let richTextsHidden: boolean[] = []; + let plainTextsHidden: boolean[] = []; + + export function setPlainTexts(fs: boolean[]): void { + richTextsHidden = plainTexts = fs; + plainTextsHidden = Array.from(fs, (v) => !v); + } + function setMathjaxEnabled(enabled: boolean): void { mathjaxConfig.enabled = enabled; } @@ -119,15 +128,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html } let fonts: [string, number, boolean][] = []; - let richTextsHidden: boolean[] = []; - let plainTextsHidden: boolean[] = []; const fields = clearableArray(); export function setFonts(fs: [string, number, boolean][]): void { fonts = fs; - - richTextsHidden = fonts.map((_, index) => richTextsHidden[index] ?? false); - plainTextsHidden = fonts.map((_, index) => plainTextsHidden[index] ?? true); } export function focusField(index: number | null): void { @@ -175,6 +179,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html $: fieldsData = fieldNames.map((name, index) => ({ name, + plainText: plainTexts[index], description: fieldDescriptions[index], fontFamily: quoteFontFamily(fonts[index][0]), fontSize: fonts[index][1], @@ -244,6 +249,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html Object.assign(globalThis, { setFields, + setPlainTexts, setDescriptions, setFonts, focusField,