implement bury/suspend undo

This commit is contained in:
Damien Elmes 2021-03-04 21:40:59 +10:00
parent b466f0ce90
commit 41779c1aad
9 changed files with 82 additions and 62 deletions

View file

@ -1262,9 +1262,9 @@ where id in %s"""
self.editor.saveNow(self._onSuspend)
def _onSuspend(self) -> None:
sus = not self.isSuspended()
want_suspend = not self.isSuspended()
c = self.selectedCards()
if sus:
if want_suspend:
self.col.sched.suspend_cards(c)
else:
self.col.sched.unsuspend_cards(c)

View file

@ -292,10 +292,10 @@ class Reviewer:
("Ctrl+3", lambda: self.setFlag(3)),
("Ctrl+4", lambda: self.setFlag(4)),
("*", self.onMark),
("=", self.onBuryNote),
("-", self.onBuryCard),
("!", self.onSuspend),
("@", self.onSuspendCard),
("=", self.bury_current_note),
("-", self.bury_current_card),
("!", self.suspend_current_note),
("@", self.suspend_current_card),
("Ctrl+Delete", self.onDelete),
("Ctrl+Shift+D", self.on_set_due),
("v", self.onReplayRecorded),
@ -727,11 +727,11 @@ time = %(time)d;
],
],
[tr(TR.STUDYING_MARK_NOTE), "*", self.onMark],
[tr(TR.STUDYING_BURY_CARD), "-", self.onBuryCard],
[tr(TR.STUDYING_BURY_NOTE), "=", self.onBuryNote],
[tr(TR.STUDYING_BURY_CARD), "-", self.bury_current_card],
[tr(TR.STUDYING_BURY_NOTE), "=", self.bury_current_note],
[tr(TR.ACTIONS_SET_DUE_DATE), "Ctrl+Shift+D", self.on_set_due],
[tr(TR.ACTIONS_SUSPEND_CARD), "@", self.onSuspendCard],
[tr(TR.STUDYING_SUSPEND_NOTE), "!", self.onSuspend],
[tr(TR.ACTIONS_SUSPEND_CARD), "@", self.suspend_current_card],
[tr(TR.STUDYING_SUSPEND_NOTE), "!", self.suspend_current_note],
[tr(TR.STUDYING_DELETE_NOTE), "Ctrl+Delete", self.onDelete],
[tr(TR.ACTIONS_OPTIONS), "O", self.onOptions],
None,
@ -808,17 +808,25 @@ time = %(time)d;
on_done=self.mw.reset,
)
def onSuspend(self) -> None:
self.mw.checkpoint(tr(TR.STUDYING_SUSPEND))
def suspend_current_note(self) -> None:
self.mw.col.sched.suspend_cards([c.id for c in self.card.note().cards()])
self.mw.reset()
tooltip(tr(TR.STUDYING_NOTE_SUSPENDED))
self.mw.reset()
def onSuspendCard(self) -> None:
self.mw.checkpoint(tr(TR.STUDYING_SUSPEND))
def suspend_current_card(self) -> None:
self.mw.col.sched.suspend_cards([self.card.id])
tooltip(tr(TR.STUDYING_CARD_SUSPENDED))
self.mw.reset()
tooltip(tr(TR.STUDYING_CARD_SUSPENDED))
def bury_current_card(self) -> None:
self.mw.col.sched.bury_cards([self.card.id])
self.mw.reset()
tooltip(tr(TR.STUDYING_CARD_BURIED))
def bury_current_note(self) -> None:
self.mw.col.sched.bury_note(self.card.note())
self.mw.reset()
tooltip(tr(TR.STUDYING_NOTE_BURIED))
def onDelete(self) -> None:
# need to check state because the shortcut is global to the main
@ -831,18 +839,6 @@ time = %(time)d;
self.mw.reset()
tooltip(tr(TR.STUDYING_NOTE_AND_ITS_CARD_DELETED, count=cnt))
def onBuryCard(self) -> None:
self.mw.checkpoint(tr(TR.STUDYING_BURY))
self.mw.col.sched.bury_cards([self.card.id])
self.mw.reset()
tooltip(tr(TR.STUDYING_CARD_BURIED))
def onBuryNote(self) -> None:
self.mw.checkpoint(tr(TR.STUDYING_BURY))
self.mw.col.sched.bury_note(self.card.note())
self.mw.reset()
tooltip(tr(TR.STUDYING_NOTE_BURIED))
def onRecordVoice(self) -> None:
def after_record(path: str) -> None:
self._recordedAudio = path
@ -855,3 +851,10 @@ time = %(time)d;
tooltip(tr(TR.STUDYING_YOU_HAVENT_RECORDED_YOUR_VOICE_YET))
return
av_player.play_file(self._recordedAudio)
# legacy
onBuryCard = bury_current_card
onBuryNote = bury_current_note
onSuspend = suspend_current_note
onSuspendCard = suspend_current_card

View file

@ -707,7 +707,7 @@ impl BackendService for Backend {
fn clear_card_queues(&self, _input: pb::Empty) -> BackendResult<pb::Empty> {
self.with_col(|col| {
col.clear_queues();
col.clear_study_queues();
Ok(().into())
})
}

View file

@ -1,6 +1,8 @@
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
mod op;
use crate::i18n::I18n;
use crate::log::Logger;
use crate::types::Usn;
@ -11,6 +13,7 @@ use crate::{
undo::UndoManager,
};
use crate::{err::Result, scheduler::queue::CardQueues};
pub use op::CollectionOp;
use std::{collections::HashMap, path::PathBuf, sync::Arc};
pub fn open_collection<P: Into<PathBuf>>(
@ -78,12 +81,6 @@ pub struct Collection {
pub(crate) state: CollectionState,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum CollectionOp {
UpdateCard,
AnswerCard,
}
impl Collection {
/// Execute the provided closure in a transaction, rolling back if
/// an error is returned.

View file

@ -0,0 +1,25 @@
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
use crate::prelude::*;
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum CollectionOp {
UpdateCard,
AnswerCard,
Bury,
Suspend,
}
impl Collection {
pub fn describe_collection_op(&self, op: CollectionOp) -> String {
let key = match op {
CollectionOp::UpdateCard => todo!(),
CollectionOp::AnswerCard => TR::UndoAnswerCard,
CollectionOp::Bury => TR::StudyingBury,
CollectionOp::Suspend => TR::StudyingSuspend,
};
self.i18n.tr(key).to_string()
}
}

View file

@ -66,7 +66,7 @@ mod test {
col.storage.update_card(&card)?;
// fail it, which should cause it to be marked as a leech
col.clear_queues();
col.clear_study_queues();
let queued = col.next_card()?.unwrap();
dbg!(&queued);
col.answer_card(&CardAnswer {

View file

@ -12,7 +12,10 @@ use crate::{
};
use super::timing::SchedTimingToday;
use pb::unbury_cards_in_current_deck_in::Mode as UnburyDeckMode;
use pb::{
bury_or_suspend_cards_in::Mode as BuryOrSuspendMode,
unbury_cards_in_current_deck_in::Mode as UnburyDeckMode,
};
impl Card {
/// True if card was buried/suspended prior to the call.
@ -86,20 +89,16 @@ impl Collection {
/// Bury/suspend cards in search table, and clear it.
/// Marks the cards as modified.
fn bury_or_suspend_searched_cards(
&mut self,
mode: pb::bury_or_suspend_cards_in::Mode,
) -> Result<()> {
use pb::bury_or_suspend_cards_in::Mode;
fn bury_or_suspend_searched_cards(&mut self, mode: BuryOrSuspendMode) -> Result<()> {
let usn = self.usn()?;
let sched = self.scheduler_version();
for original in self.storage.all_searched_cards()? {
let mut card = original.clone();
let desired_queue = match mode {
Mode::Suspend => CardQueue::Suspended,
Mode::BurySched => CardQueue::SchedBuried,
Mode::BuryUser => {
BuryOrSuspendMode::Suspend => CardQueue::Suspended,
BuryOrSuspendMode::BurySched => CardQueue::SchedBuried,
BuryOrSuspendMode::BuryUser => {
if sched == SchedulerVersion::V1 {
// v1 scheduler only had one bury type
CardQueue::SchedBuried
@ -124,9 +123,14 @@ impl Collection {
pub fn bury_or_suspend_cards(
&mut self,
cids: &[CardID],
mode: pb::bury_or_suspend_cards_in::Mode,
mode: BuryOrSuspendMode,
) -> Result<()> {
self.transact(None, |col| {
let op = match mode {
BuryOrSuspendMode::Suspend => CollectionOp::Suspend,
BuryOrSuspendMode::BurySched | BuryOrSuspendMode::BuryUser => CollectionOp::Bury,
};
self.transact(Some(op), |col| {
col.clear_study_queues();
col.storage.set_search_table_to_card_ids(cids, false)?;
col.bury_or_suspend_searched_cards(mode)
})
@ -139,10 +143,9 @@ impl Collection {
include_new: bool,
include_reviews: bool,
) -> Result<()> {
use pb::bury_or_suspend_cards_in::Mode;
self.storage
.search_siblings_for_bury(cid, nid, include_new, include_reviews)?;
self.bury_or_suspend_searched_cards(Mode::BurySched)
self.bury_or_suspend_searched_cards(BuryOrSuspendMode::BurySched)
}
}

View file

@ -132,11 +132,12 @@ impl Collection {
}
}
pub(crate) fn clear_queues(&mut self) {
// clearing the queue will remove any undone reviews from the undo queue,
// causing problems if we then try to redo them
self.state.undo.clear_redo();
pub(crate) fn clear_study_queues(&mut self) {
self.state.card_queues = None;
// clearing the queue will remove any undone reviews from the undo queue,
// causing problems if we then try to redo them, so we need to clear the
// redo queue as well
self.state.undo.clear_redo();
}
pub(crate) fn update_queues_after_answering_card(

View file

@ -2,7 +2,6 @@
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
use crate::backend_proto as pb;
use crate::i18n::TR;
use crate::{
collection::{Collection, CollectionOp},
err::Result,
@ -145,14 +144,6 @@ impl Collection {
self.state.undo.save(item)
}
pub fn describe_collection_op(&self, op: CollectionOp) -> String {
match op {
CollectionOp::UpdateCard => todo!(),
CollectionOp::AnswerCard => self.i18n.tr(TR::UndoAnswerCard),
}
.to_string()
}
pub fn undo_status(&self) -> pb::UndoStatus {
pb::UndoStatus {
undo: self