mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
Add support for tagging + protecting fields
This commit is contained in:
parent
64e40033e0
commit
1e37c806e5
5 changed files with 32 additions and 9 deletions
|
@ -20,3 +20,4 @@ fields-name-invalid-letter = The field name should not contain :, ", { "{" } or
|
||||||
# If enabled, the field is not included when searching for 'text', 're:text' and so on,
|
# If enabled, the field is not included when searching for 'text', 're:text' and so on,
|
||||||
# but is when searching for a specific field, eg 'field:text'.
|
# but is when searching for a specific field, eg 'field:text'.
|
||||||
fields-exclude-from-search = Exclude from unqualified searches (slower)
|
fields-exclude-from-search = Exclude from unqualified searches (slower)
|
||||||
|
fields-field-is-required = This is a required field, and can not be deleted.
|
||||||
|
|
|
@ -87,6 +87,9 @@ message Notetype {
|
||||||
bool exclude_from_search = 8;
|
bool exclude_from_search = 8;
|
||||||
// used for merging notetypes on import (Anki 23.10)
|
// used for merging notetypes on import (Anki 23.10)
|
||||||
optional int64 id = 9;
|
optional int64 id = 9;
|
||||||
|
// Can be used to uniquely identify required fields.
|
||||||
|
optional uint32 tag = 10;
|
||||||
|
bool prevent_deletion = 11;
|
||||||
|
|
||||||
bytes other = 255;
|
bytes other = 255;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ from aqt.utils import (
|
||||||
disable_help_button,
|
disable_help_button,
|
||||||
getOnlyText,
|
getOnlyText,
|
||||||
openHelp,
|
openHelp,
|
||||||
showWarning,
|
show_warning,
|
||||||
tooltip,
|
tooltip,
|
||||||
tr,
|
tr,
|
||||||
)
|
)
|
||||||
|
@ -128,17 +128,17 @@ class FieldDialog(QDialog):
|
||||||
if not txt:
|
if not txt:
|
||||||
return None
|
return None
|
||||||
if txt[0] in "#^/":
|
if txt[0] in "#^/":
|
||||||
showWarning(tr.fields_name_first_letter_not_valid())
|
show_warning(tr.fields_name_first_letter_not_valid())
|
||||||
return None
|
return None
|
||||||
for letter in """:{"}""":
|
for letter in """:{"}""":
|
||||||
if letter in txt:
|
if letter in txt:
|
||||||
showWarning(tr.fields_name_invalid_letter())
|
show_warning(tr.fields_name_invalid_letter())
|
||||||
return None
|
return None
|
||||||
for f in self.model["flds"]:
|
for f in self.model["flds"]:
|
||||||
if ignoreOrd is not None and f["ord"] == ignoreOrd:
|
if ignoreOrd is not None and f["ord"] == ignoreOrd:
|
||||||
continue
|
continue
|
||||||
if f["name"] == txt:
|
if f["name"] == txt:
|
||||||
showWarning(tr.fields_that_field_name_is_already_used())
|
show_warning(tr.fields_that_field_name_is_already_used())
|
||||||
return None
|
return None
|
||||||
return txt
|
return txt
|
||||||
|
|
||||||
|
@ -174,7 +174,11 @@ class FieldDialog(QDialog):
|
||||||
|
|
||||||
def onDelete(self) -> None:
|
def onDelete(self) -> None:
|
||||||
if len(self.model["flds"]) < 2:
|
if len(self.model["flds"]) < 2:
|
||||||
showWarning(tr.fields_notes_require_at_least_one_field())
|
show_warning(tr.fields_notes_require_at_least_one_field())
|
||||||
|
return
|
||||||
|
field = self.model["flds"][self.form.fieldList.currentRow()]
|
||||||
|
if field["preventDeletion"]:
|
||||||
|
show_warning(tr.fields_field_is_required())
|
||||||
return
|
return
|
||||||
count = self.mm.use_count(self.model)
|
count = self.mm.use_count(self.model)
|
||||||
c = tr.browsing_note_count(count=count)
|
c = tr.browsing_note_count(count=count)
|
||||||
|
@ -182,9 +186,8 @@ class FieldDialog(QDialog):
|
||||||
return
|
return
|
||||||
if not self.change_tracker.mark_schema():
|
if not self.change_tracker.mark_schema():
|
||||||
return
|
return
|
||||||
f = self.model["flds"][self.form.fieldList.currentRow()]
|
self.mm.remove_field(self.model, field)
|
||||||
self.mm.remove_field(self.model, f)
|
gui_hooks.fields_did_delete_field(self, field)
|
||||||
gui_hooks.fields_did_delete_field(self, f)
|
|
||||||
|
|
||||||
self.fillFields()
|
self.fillFields()
|
||||||
self.form.fieldList.setCurrentRow(0)
|
self.form.fieldList.setCurrentRow(0)
|
||||||
|
|
|
@ -47,6 +47,8 @@ impl NoteField {
|
||||||
description: "".into(),
|
description: "".into(),
|
||||||
collapsed: false,
|
collapsed: false,
|
||||||
exclude_from_search: false,
|
exclude_from_search: false,
|
||||||
|
tag: None,
|
||||||
|
prevent_deletion: false,
|
||||||
other: vec![],
|
other: vec![],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -239,7 +239,7 @@ pub struct NoteFieldSchema11 {
|
||||||
pub(crate) font: String,
|
pub(crate) font: String,
|
||||||
pub(crate) size: u16,
|
pub(crate) size: u16,
|
||||||
|
|
||||||
// This was not in schema 11, but needs to be listed here so that the setting is not lost
|
// These were not in schema 11, but need to be listed here so that the setting is not lost
|
||||||
// on downgrade/upgrade.
|
// on downgrade/upgrade.
|
||||||
#[serde(default, deserialize_with = "default_on_invalid")]
|
#[serde(default, deserialize_with = "default_on_invalid")]
|
||||||
pub(crate) description: String,
|
pub(crate) description: String,
|
||||||
|
@ -256,6 +256,12 @@ pub struct NoteFieldSchema11 {
|
||||||
#[serde(default, deserialize_with = "default_on_invalid")]
|
#[serde(default, deserialize_with = "default_on_invalid")]
|
||||||
pub(crate) id: Option<i64>,
|
pub(crate) id: Option<i64>,
|
||||||
|
|
||||||
|
#[serde(default, deserialize_with = "default_on_invalid")]
|
||||||
|
pub(crate) tag: Option<u32>,
|
||||||
|
|
||||||
|
#[serde(default, deserialize_with = "default_on_invalid")]
|
||||||
|
pub(crate) prevent_deletion: bool,
|
||||||
|
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub(crate) other: HashMap<String, Value>,
|
pub(crate) other: HashMap<String, Value>,
|
||||||
}
|
}
|
||||||
|
@ -274,6 +280,8 @@ impl Default for NoteFieldSchema11 {
|
||||||
collapsed: false,
|
collapsed: false,
|
||||||
exclude_from_search: false,
|
exclude_from_search: false,
|
||||||
id: None,
|
id: None,
|
||||||
|
tag: None,
|
||||||
|
prevent_deletion: false,
|
||||||
other: Default::default(),
|
other: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -294,6 +302,8 @@ impl From<NoteFieldSchema11> for NoteField {
|
||||||
collapsed: f.collapsed,
|
collapsed: f.collapsed,
|
||||||
exclude_from_search: f.exclude_from_search,
|
exclude_from_search: f.exclude_from_search,
|
||||||
id: f.id,
|
id: f.id,
|
||||||
|
tag: f.tag,
|
||||||
|
prevent_deletion: f.prevent_deletion,
|
||||||
other: other_to_bytes(&f.other),
|
other: other_to_bytes(&f.other),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -315,6 +325,8 @@ impl From<NoteField> for NoteFieldSchema11 {
|
||||||
collapsed: conf.collapsed,
|
collapsed: conf.collapsed,
|
||||||
exclude_from_search: conf.exclude_from_search,
|
exclude_from_search: conf.exclude_from_search,
|
||||||
id: conf.id,
|
id: conf.id,
|
||||||
|
tag: conf.tag,
|
||||||
|
prevent_deletion: conf.prevent_deletion,
|
||||||
other: parse_other_fields(&conf.other, &RESERVED_FIELD_KEYS),
|
other: parse_other_fields(&conf.other, &RESERVED_FIELD_KEYS),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -332,6 +344,8 @@ static RESERVED_FIELD_KEYS: Set<&'static str> = phf_set! {
|
||||||
"description",
|
"description",
|
||||||
"excludeFromSearch",
|
"excludeFromSearch",
|
||||||
"id",
|
"id",
|
||||||
|
"tag",
|
||||||
|
"preventDeletion",
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
|
||||||
|
|
Loading…
Reference in a new issue