diff --git a/rslib/src/dbcheck.rs b/rslib/src/dbcheck.rs index b0bf876d7..be96029b0 100644 --- a/rslib/src/dbcheck.rs +++ b/rslib/src/dbcheck.rs @@ -5,6 +5,7 @@ use std::collections::HashSet; use std::sync::Arc; use anki_i18n::I18n; +use anki_proto::notetypes::stock_notetype::OriginalStockKind; use itertools::Itertools; use tracing::debug; @@ -233,7 +234,7 @@ impl Collection { for (ntid, group) in &nids_by_notetype.into_iter().group_by(|tup| tup.0) { debug!("check notetype: {}", ntid); let mut group = group.peekable(); - let nt = match self.get_notetype(ntid)? { + let mut nt = match self.get_notetype(ntid)? { None => { let first_note = self.storage.get_note(group.peek().unwrap().1)?.unwrap(); out.notetypes_recovered += 1; @@ -242,6 +243,8 @@ impl Collection { Some(nt) => nt, }; + self.add_missing_field_tags(Arc::make_mut(&mut nt))?; + let mut genctx = None; for (_, nid) in group { progress.increment(|p| { @@ -427,6 +430,30 @@ impl Collection { } Ok(num_invalid_ids) } + fn add_missing_field_tags(&mut self, nt: &mut Notetype) -> Result<()> { + // we only try to fix I/O, as the other notetypes have been in circulation too + // long, and there's too much of a risk that the user has reordered the fields + // already. We could try to match on field name in the future though. + let usn = self.usn()?; + if let OriginalStockKind::ImageOcclusion = nt.config.original_stock_kind() { + let mut changed = false; + if nt.fields.len() >= 5 { + for i in 0..5 { + let conf = &mut nt.fields[i].config; + if !conf.prevent_deletion { + changed = true; + conf.prevent_deletion = true; + conf.tag = Some(i as u32); + } + } + } + if changed { + nt.set_modified(usn); + self.add_or_update_notetype_with_existing_id_inner(nt, None, usn, true)?; + } + } + Ok(()) + } } #[cfg(test)] diff --git a/rslib/src/notetype/stock.rs b/rslib/src/notetype/stock.rs index 71f1308f8..c06cd8e90 100644 --- a/rslib/src/notetype/stock.rs +++ b/rslib/src/notetype/stock.rs @@ -2,11 +2,11 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html use anki_i18n::I18n; -use anki_proto::notetypes::ClozeField; use anki_proto::notetypes::notetype::config::Kind as NotetypeKind; use anki_proto::notetypes::stock_notetype::Kind; pub(crate) use anki_proto::notetypes::stock_notetype::Kind as StockKind; use anki_proto::notetypes::stock_notetype::OriginalStockKind; +use anki_proto::notetypes::ClozeField; use super::NotetypeConfig; use crate::config::ConfigEntry;