use aux var when retrieving last deck for notetype

The adding case was already covered by defaults_for_adding(), but we
the code was using the old variable when adding new cards to an existing
note.
This commit is contained in:
Damien Elmes 2021-04-29 18:48:22 +10:00
parent b160c2d85c
commit 610f0b5254
10 changed files with 34 additions and 52 deletions

View File

@ -77,7 +77,8 @@ def test_gendeck():
assert note.cards()[0].did == 1
# set the model to a new default col
newId = col.decks.id("new")
cloze["did"] = newId
# fixme: dedicated API for this
col.set_config(f"_nt_{cloze['id']}_lastDeck", newId)
col.models.save(cloze, updateReqs=False)
# a newly generated card should share the first card's col
note["Text"] += "{{c2::two}}"

View File

@ -466,7 +466,8 @@ message Notetype {
Kind kind = 1;
uint32 sort_field_idx = 2;
string css = 3;
int64 target_deck_id = 4; // moved into config var
/// This is now stored separately; retrieve with DefaultsForAdding()
int64 target_deck_id_unused = 4;
string latex_pre = 5;
string latex_post = 6;
bool latex_svg = 7;

View File

@ -256,7 +256,9 @@ impl Collection {
note.notetype_id = nt.id;
// write note, updating tags and generating missing cards
let ctx = genctx.get_or_insert_with(|| CardGenContext::new(&nt, usn));
let ctx = genctx.get_or_insert_with(|| {
CardGenContext::new(&nt, self.get_last_deck_added_to_for_notetype(nt.id), usn)
});
self.update_note_inner_generating_cards(&ctx, &mut note, &original, false, norm)?;
}
}

View File

@ -74,7 +74,8 @@ impl Collection {
let nt = col
.get_notetype(note.notetype_id)?
.ok_or_else(|| AnkiError::invalid_input("missing note type"))?;
let ctx = CardGenContext::new(&nt, col.usn()?);
let last_deck = col.get_last_deck_added_to_for_notetype(note.notetype_id);
let ctx = CardGenContext::new(&nt, last_deck, col.usn()?);
let norm = col.get_bool(BoolKey::NormalizeNoteText);
col.add_note_inner(&ctx, note, did, norm)
})
@ -383,7 +384,8 @@ impl Collection {
let nt = self
.get_notetype(note.notetype_id)?
.ok_or_else(|| AnkiError::invalid_input("missing note type"))?;
let ctx = CardGenContext::new(&nt, self.usn()?);
let last_deck = self.get_last_deck_added_to_for_notetype(note.notetype_id);
let ctx = CardGenContext::new(&nt, last_deck, self.usn()?);
let norm = self.get_bool(BoolKey::NormalizeNoteText);
self.update_note_inner_generating_cards(&ctx, note, &existing_note, true, norm)?;
Ok(())
@ -484,7 +486,13 @@ impl Collection {
}
if out.generate_cards {
let ctx = genctx.get_or_insert_with(|| CardGenContext::new(&nt, usn));
let ctx = genctx.get_or_insert_with(|| {
CardGenContext::new(
&nt,
self.get_last_deck_added_to_for_notetype(nt.id),
usn,
)
});
self.update_note_inner_generating_cards(
&ctx,
&mut note,

View File

@ -8,16 +8,8 @@ use rand::{rngs::StdRng, Rng, SeedableRng};
use super::Notetype;
use crate::{
card::{Card, CardId},
cloze::add_cloze_numbers_in_string,
collection::Collection,
deckconfig::{DeckConfig, DeckConfigId},
decks::DeckId,
error::{AnkiError, Result},
notes::{Note, NoteId},
notetype::NotetypeKind,
cloze::add_cloze_numbers_in_string, notetype::NotetypeKind, prelude::*,
template::ParsedTemplate,
types::Usn,
};
/// Info about an existing card required when generating new cards
@ -49,6 +41,8 @@ pub(crate) struct SingleCardGenContext {
pub(crate) struct CardGenContext<'a> {
pub usn: Usn,
pub notetype: &'a Notetype,
/// The last deck that was added to with this note type
pub last_deck: Option<DeckId>,
cards: Vec<SingleCardGenContext>,
}
@ -60,9 +54,10 @@ pub(crate) struct CardGenCache {
}
impl CardGenContext<'_> {
pub(crate) fn new(nt: &Notetype, usn: Usn) -> CardGenContext<'_> {
pub(crate) fn new(nt: &Notetype, last_deck: Option<DeckId>, usn: Usn) -> CardGenContext<'_> {
CardGenContext {
usn,
last_deck,
notetype: &nt,
cards: nt
.templates
@ -233,13 +228,7 @@ impl Collection {
note: &Note,
) -> Result<()> {
let existing = self.storage.existing_cards_for_note(note.id)?;
self.generate_cards_for_note(
ctx,
note,
&existing,
Some(ctx.notetype.target_deck_id()),
&mut Default::default(),
)
self.generate_cards_for_note(ctx, note, &existing, ctx.last_deck, &mut Default::default())
}
fn generate_cards_for_note(

View File

@ -17,7 +17,8 @@ pub struct EmptyCardsForNote {
impl Collection {
fn empty_cards_for_notetype(&self, nt: &Notetype) -> Result<Vec<EmptyCardsForNote>> {
let ctx = CardGenContext::new(nt, self.usn()?);
let last_deck = self.get_last_deck_added_to_for_notetype(nt.id);
let ctx = CardGenContext::new(nt, last_deck, self.usn()?);
let existing_cards = self.storage.existing_cards_for_notetype(nt.id)?;
let by_note = group_generated_cards_by_note(existing_cards);
let mut out = Vec::with_capacity(by_note.len());

View File

@ -35,16 +35,11 @@ pub use crate::backend_proto::{
Notetype as NotetypeProto,
};
use crate::{
collection::Collection,
decks::DeckId,
define_newtype,
error::{AnkiError, Result, TemplateSaveError},
notes::Note,
error::TemplateSaveError,
prelude::*,
template::{FieldRequirements, ParsedTemplate},
text::ensure_string_in_nfc,
timestamp::TimestampSecs,
types::Usn,
};
define_newtype!(NotetypeId, i64);
@ -99,10 +94,6 @@ impl Notetype {
template.ok_or(AnkiError::NotFound)
}
pub fn target_deck_id(&self) -> DeckId {
DeckId(self.config.target_deck_id)
}
}
impl Collection {
@ -320,14 +311,6 @@ impl Notetype {
self.templates.push(CardTemplate::new(name, qfmt, afmt));
}
pub(crate) fn prepare_for_adding(&mut self) -> Result<()> {
// defaults to 0
if self.config.target_deck_id == 0 {
self.config.target_deck_id = 1;
}
self.prepare_for_update(None)
}
pub(crate) fn prepare_for_update(&mut self, existing: Option<&Notetype>) -> Result<()> {
if self.fields.is_empty() {
return Err(AnkiError::invalid_input("1 field required"));
@ -489,7 +472,7 @@ impl Collection {
}
pub(crate) fn add_notetype_inner(&mut self, nt: &mut Notetype, usn: Usn) -> Result<()> {
nt.prepare_for_adding()?;
nt.prepare_for_update(None)?;
self.ensure_notetype_name_unique(nt, usn)?;
self.storage.add_new_notetype(nt)
}

View File

@ -98,7 +98,7 @@ impl From<NotetypeSchema11> for Notetype {
kind: nt.kind as i32,
sort_field_idx: nt.sortf as u32,
css: nt.css,
target_deck_id: nt.did.unwrap_or(DeckId(0)).0,
target_deck_id_unused: nt.did.unwrap_or(DeckId(0)).0,
latex_pre: nt.latex_pre,
latex_post: nt.latex_post,
latex_svg: nt.latexsvg,
@ -148,10 +148,10 @@ impl From<Notetype> for NotetypeSchema11 {
mtime: p.mtime_secs,
usn: p.usn,
sortf: c.sort_field_idx as u16,
did: if c.target_deck_id == 0 {
did: if c.target_deck_id_unused == 0 {
None
} else {
Some(DeckId(c.target_deck_id))
Some(DeckId(c.target_deck_id_unused))
},
tmpls: p.templates.into_iter().map(Into::into).collect(),
flds: p.fields.into_iter().map(Into::into).collect(),

View File

@ -127,7 +127,8 @@ impl Collection {
.move_cards_for_repositioned_templates(nt.id, &changes.moved)?;
}
let ctx = CardGenContext::new(nt, self.usn()?);
let last_deck = self.get_last_deck_added_to_for_notetype(nt.id);
let ctx = CardGenContext::new(nt, last_deck, self.usn()?);
self.generate_cards_for_notetype(&ctx)?;
Ok(())

View File

@ -15,6 +15,7 @@ use crate::{
impl SqliteStorage {
pub(crate) fn add_stock_notetypes(&self, tr: &I18n) -> Result<()> {
for (idx, mut nt) in all_stock_notetypes(tr).into_iter().enumerate() {
nt.prepare_for_update(None)?;
self.add_new_notetype(&mut nt)?;
if idx == Kind::Basic as usize {
self.set_config_entry(&ConfigEntry::boxed(
@ -63,7 +64,6 @@ pub(crate) fn basic(tr: &I18n) -> Notetype {
fieldref(back),
),
);
nt.prepare_for_adding().unwrap();
nt
}
@ -79,7 +79,6 @@ pub(crate) fn basic_typing(tr: &I18n) -> Notetype {
fieldref(front),
back
);
nt.prepare_for_adding().unwrap();
nt
}
@ -97,7 +96,6 @@ pub(crate) fn basic_forward_reverse(tr: &I18n) -> Notetype {
fieldref(front),
),
);
nt.prepare_for_adding().unwrap();
nt
}
@ -108,7 +106,6 @@ pub(crate) fn basic_optional_reverse(tr: &I18n) -> Notetype {
nt.add_field(addrev.as_ref());
let tmpl = &mut nt.templates[1].config;
tmpl.q_format = format!("{{{{#{}}}}}{}{{{{/{}}}}}", addrev, tmpl.q_format, addrev);
nt.prepare_for_adding().unwrap();
nt
}
@ -134,6 +131,5 @@ pub(crate) fn cloze(tr: &I18n) -> Notetype {
color: lightblue;
}
";
nt.prepare_for_adding().unwrap();
nt
}