From 371f731e30890e5472513da316a48a302f6e85fa Mon Sep 17 00:00:00 2001 From: Matthias Metelka <62722460+kleinerpirat@users.noreply.github.com> Date: Sat, 6 Nov 2021 00:42:48 +0100 Subject: [PATCH] Editor Field Descriptions (#1476) * Add description input to fields dialog QLineEdit seems like the best option, as it saves space and motivates users to keep their descriptions concise. * Add setDescriptions to note initialization script Went for the extra function instead of including it in setFields to prevent potential add-on breakages. * Add tooltip next to field name if description is set * Refactor code according to suggestions Set default tooltip placement to right instead of bottom Use .get() for fld["description"] Fix tab order in fields dialog Swap out abbreviation "desc" for full length name to keep consistency * Update Protobuf and Rust for description Add description to notetypes.proto and schema11 Co-authored-by: RumovZ * Fix tooltips not updating with description Remove redundant variable tooltipOptions Update previousTooltip within reactive function * Move LabelDescription out of LabelName Co-authored-by: Henrik Giesel * Decrease icon size and fix alignment Co-Authored-By: Henrik Giesel * the new key needs to be cleared from fields, not the notetype itself Co-authored-by: RumovZ Co-authored-by: Henrik Giesel Co-authored-by: Damien Elmes --- ftl/core/fields.ftl | 2 + proto/anki/notetypes.proto | 1 + qt/aqt/editor.py | 7 +++- qt/aqt/fields.py | 5 +++ qt/aqt/forms/fields.ui | 62 ++++++++++++++++++++----------- rslib/src/notetype/fields.rs | 1 + rslib/src/notetype/schema11.rs | 21 ++++++++++- ts/components/WithTooltip.svelte | 10 ++++- ts/editor/EditorField.svelte | 11 +++++- ts/editor/LabelDescription.svelte | 39 +++++++++++++++++++ ts/editor/LabelName.svelte | 5 ++- ts/editor/OldEditorAdapter.svelte | 6 +++ ts/editor/icons.ts | 2 + ts/editor/index.ts | 1 + 14 files changed, 147 insertions(+), 26 deletions(-) create mode 100644 ts/editor/LabelDescription.svelte diff --git a/ftl/core/fields.ftl b/ftl/core/fields.ftl index e986a358e..20ebdaf13 100644 --- a/ftl/core/fields.ftl +++ b/ftl/core/fields.ftl @@ -3,6 +3,8 @@ fields-delete-field-from = Delete field from { $val }? fields-editing-font = Editing Font fields-field = Field: fields-field-name = Field name: +fields-description = Description +fields-description-placeholder = Tooltip to show next to the field's name in the editing screen fields-fields-for = Fields for { $val } fields-font = Font: fields-new-position-1 = New position (1...{ $val }): diff --git a/proto/anki/notetypes.proto b/proto/anki/notetypes.proto index cf86686da..2b8dc9146 100644 --- a/proto/anki/notetypes.proto +++ b/proto/anki/notetypes.proto @@ -68,6 +68,7 @@ message Notetype { bool rtl = 2; string font_name = 3; uint32 font_size = 4; + string description = 5; bytes other = 255; } diff --git a/qt/aqt/editor.py b/qt/aqt/editor.py index eb2e179c8..1f2fec9dc 100644 --- a/qt/aqt/editor.py +++ b/qt/aqt/editor.py @@ -460,6 +460,10 @@ noteEditorPromise.then(noteEditor => noteEditor.toolbar.toolbar.appendGroup({{ (fld, self.mw.col.media.escape_media_filenames(val)) for fld, val in self.note.items() ] + + flds = self.note.note_type()["flds"] + descriptions = [fld.get("description", "") for fld in flds] + self.widget.show() note_fields_status = self.note.fields_check() @@ -478,8 +482,9 @@ noteEditorPromise.then(noteEditor => noteEditor.toolbar.toolbar.appendGroup({{ text_color = self.mw.pm.profile.get("lastTextColor", "#00f") highlight_color = self.mw.pm.profile.get("lastHighlightColor", "#00f") - js = "setFields({}); setFonts({}); focusField({}); setNoteId({}); setColorButtons({}); setTags({}); ".format( + js = "setFields({}); setDescriptions({}); setFonts({}); focusField({}); setNoteId({}); setColorButtons({}); setTags({}); ".format( json.dumps(data), + json.dumps(descriptions), json.dumps(self.fonts()), json.dumps(focusTo), json.dumps(self.note.id), diff --git a/qt/aqt/fields.py b/qt/aqt/fields.py index 00155a79b..6c3e6a9d7 100644 --- a/qt/aqt/fields.py +++ b/qt/aqt/fields.py @@ -214,6 +214,7 @@ class FieldDialog(QDialog): f.fontSize.setValue(fld["size"]) f.sortField.setChecked(self.model["sortf"] == fld["ord"]) f.rtl.setChecked(fld["rtl"]) + f.fieldDescription.setText(fld.get("description", "")) def saveField(self) -> None: # not initialized yet? @@ -234,6 +235,10 @@ class FieldDialog(QDialog): if fld["rtl"] != rtl: fld["rtl"] = rtl self.change_tracker.mark_basic() + desc = f.fieldDescription.text() + if fld.get("description", "") != desc: + fld["description"] = desc + self.change_tracker.mark_basic() def reject(self) -> None: if self.change_tracker.changed(): diff --git a/qt/aqt/forms/fields.ui b/qt/aqt/forms/fields.ui index c68a300f7..81f3ce3e0 100644 --- a/qt/aqt/forms/fields.ui +++ b/qt/aqt/forms/fields.ui @@ -6,8 +6,8 @@ 0 0 - 483 - 352 + 586 + 376 @@ -84,17 +84,21 @@ - - - - - 0 - 25 - + + + + fields_editing_font - + + + + fields_reverse_text_direction_rtl + + + + 5 @@ -104,31 +108,47 @@ - - + + actions_options - + fields_sort_by_this_field_in_the - - + + + + + 0 + 0 + + - fields_reverse_text_direction_rtl + fields_description - - - - fields_editing_font + + + + + 0 + 25 + + + + + + + + fields_description_placeholder @@ -152,11 +172,11 @@ fieldDelete fieldRename fieldPosition + fieldDescription fontFamily fontSize sortField rtl - buttonBox diff --git a/rslib/src/notetype/fields.rs b/rslib/src/notetype/fields.rs index edfd69804..866afb0e1 100644 --- a/rslib/src/notetype/fields.rs +++ b/rslib/src/notetype/fields.rs @@ -44,6 +44,7 @@ impl NoteField { rtl: false, font_name: "Arial".into(), font_size: 20, + description: "".into(), other: vec![], }, } diff --git a/rslib/src/notetype/schema11.rs b/rslib/src/notetype/schema11.rs index 962adfa4f..0b6053fe7 100644 --- a/rslib/src/notetype/schema11.rs +++ b/rslib/src/notetype/schema11.rs @@ -165,6 +165,13 @@ impl From for NotetypeSchema11 { } } +fn clear_other_field_duplicates(other: &mut HashMap) { + // see `clear_other_duplicates()` in `deckconfig/schema11.rs` + for key in &["description"] { + other.remove(*key); + } +} + impl From for CardRequirement { fn from(r: CardRequirementSchema11) -> Self { CardRequirement { @@ -203,6 +210,13 @@ pub struct NoteFieldSchema11 { pub(crate) rtl: bool, pub(crate) font: String, pub(crate) size: u16, + + // This was not in schema 11, but needs to be listed here so that the setting is not lost + // on downgrade/upgrade. + // NOTE: if adding new ones, make sure to update clear_other_field_duplicates() + #[serde(default, deserialize_with = "default_on_invalid")] + pub(crate) description: String, + #[serde(flatten)] pub(crate) other: HashMap, } @@ -216,6 +230,7 @@ impl Default for NoteFieldSchema11 { rtl: false, font: "Arial".to_string(), size: 20, + description: String::new(), other: Default::default(), } } @@ -231,6 +246,7 @@ impl From for NoteField { rtl: f.rtl, font_name: f.font, font_size: f.size as u32, + description: f.description, other: other_to_bytes(&f.other), }, } @@ -242,6 +258,8 @@ impl From for NoteField { impl From for NoteFieldSchema11 { fn from(p: NoteField) -> Self { let conf = p.config; + let mut other = bytes_to_other(&conf.other); + clear_other_field_duplicates(&mut other); NoteFieldSchema11 { name: p.name, ord: p.ord.map(|o| o as u16), @@ -249,7 +267,8 @@ impl From for NoteFieldSchema11 { rtl: conf.rtl, font: conf.font_name, size: conf.font_size as u16, - other: bytes_to_other(&conf.other), + description: conf.description, + other, } } } diff --git a/ts/components/WithTooltip.svelte b/ts/components/WithTooltip.svelte index dadc8fa51..27dc2273c 100644 --- a/ts/components/WithTooltip.svelte +++ b/ts/components/WithTooltip.svelte @@ -26,7 +26,6 @@ export let hideDelay = 0; let tooltipObject: Tooltip; - function createTooltip(element: HTMLElement): void { element.title = tooltip; tooltipObject = new Tooltip(element, { @@ -39,6 +38,15 @@ } onDestroy(() => tooltipObject?.dispose()); + + // hack to update field description tooltips + let previousTooltip: string = tooltip; + $: if (tooltip !== previousTooltip) { + previousTooltip = tooltip; + let element: HTMLElement = tooltipObject["_element"]; + tooltipObject.dispose(); + createTooltip(element); + } diff --git a/ts/editor/EditorField.svelte b/ts/editor/EditorField.svelte index be5d7800d..81aff62a2 100644 --- a/ts/editor/EditorField.svelte +++ b/ts/editor/EditorField.svelte @@ -9,6 +9,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html export interface FieldData { name: string; + description: string; fontFamily: string; fontSize: number; direction: "ltr" | "rtl"; @@ -29,6 +30,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html + + + + createTooltip(event.detail.span)} + > + {@html descriptionIcon} + + + + + diff --git a/ts/editor/LabelName.svelte b/ts/editor/LabelName.svelte index 04a572364..527acdbda 100644 --- a/ts/editor/LabelName.svelte +++ b/ts/editor/LabelName.svelte @@ -2,7 +2,10 @@ Copyright: Ankitects Pty Ltd and contributors License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html --> - + + + +