diff --git a/proto/anki/config.proto b/proto/anki/config.proto index 66294543a..867c62f80 100644 --- a/proto/anki/config.proto +++ b/proto/anki/config.proto @@ -47,6 +47,8 @@ message ConfigKey { RESTORE_POSITION_REVIEWER = 20; RESET_COUNTS_BROWSER = 21; RESET_COUNTS_REVIEWER = 22; + RANDOM_ORDER_REPOSITION = 23; + SHIFT_POSITION_OF_EXISTING_CARDS = 24; } enum String { SET_DUE_BROWSER = 0; diff --git a/proto/anki/scheduler.proto b/proto/anki/scheduler.proto index 8f90088d3..6fd2cda57 100644 --- a/proto/anki/scheduler.proto +++ b/proto/anki/scheduler.proto @@ -44,6 +44,7 @@ service SchedulerService { rpc CustomStudy(CustomStudyRequest) returns (collection.OpChanges); rpc CustomStudyDefaults(CustomStudyDefaultsRequest) returns (CustomStudyDefaultsResponse); + rpc RepositionDefaults(generic.Empty) returns (RepositionDefaultsResponse); } message SchedulingState { @@ -297,3 +298,8 @@ message CustomStudyDefaultsResponse { uint32 available_new_in_children = 6; uint32 available_review_in_children = 7; } + +message RepositionDefaultsResponse { + bool random = 1; + bool shift = 2; +} diff --git a/pylib/anki/scheduler/base.py b/pylib/anki/scheduler/base.py index a5d63f829..d99425f31 100644 --- a/pylib/anki/scheduler/base.py +++ b/pylib/anki/scheduler/base.py @@ -19,7 +19,7 @@ CustomStudyDefaults = scheduler_pb2.CustomStudyDefaultsResponse ScheduleCardsAsNew = scheduler_pb2.ScheduleCardsAsNewRequest ScheduleCardsAsNewDefaults = scheduler_pb2.ScheduleCardsAsNewDefaultsResponse FilteredDeckForUpdate = decks_pb2.FilteredDeckForUpdate - +RepositionDefaults = scheduler_pb2.RepositionDefaultsResponse from typing import Sequence @@ -239,6 +239,9 @@ class SchedulerBase(DeprecatedNamesMixin): shift_existing=shift_existing, ) + def reposition_defaults(self) -> RepositionDefaults: + return self.col._backend.reposition_defaults() + def randomize_cards(self, did: DeckId) -> None: self.col._backend.sort_deck(deck_id=did, randomize=True) diff --git a/qt/aqt/operations/scheduling.py b/qt/aqt/operations/scheduling.py index b921dd680..c30fdecb8 100644 --- a/qt/aqt/operations/scheduling.py +++ b/qt/aqt/operations/scheduling.py @@ -105,7 +105,9 @@ def forget_cards( def reposition_new_cards_dialog( - *, parent: QWidget, card_ids: Sequence[CardId] + *, + parent: QWidget, + card_ids: Sequence[CardId], ) -> CollectionOp[OpChangesWithCount] | None: from aqt import mw @@ -120,24 +122,29 @@ def reposition_new_cards_dialog( min_position = max(min_position or 0, 0) max_position = max_position or 0 - d = QDialog(parent) - disable_help_button(d) - d.setWindowModality(Qt.WindowModality.WindowModal) - frm = aqt.forms.reposition.Ui_Dialog() - frm.setupUi(d) + dialog = QDialog(parent) + disable_help_button(dialog) + dialog.setWindowModality(Qt.WindowModality.WindowModal) + form = aqt.forms.reposition.Ui_Dialog() + form.setupUi(dialog) txt = tr.browsing_queue_top(val=min_position) txt += "\n" + tr.browsing_queue_bottom(val=max_position) - frm.label.setText(txt) + form.label.setText(txt) - frm.start.selectAll() - if not d.exec(): + form.start.selectAll() + + defaults = mw.col.sched.reposition_defaults() + form.randomize.setChecked(defaults.random) + form.shift.setChecked(defaults.shift) + + if not dialog.exec(): return None - start = frm.start.value() - step = frm.step.value() - randomize = frm.randomize.isChecked() - shift = frm.shift.isChecked() + start = form.start.value() + step = form.step.value() + randomize = form.randomize.isChecked() + shift = form.shift.isChecked() return reposition_new_cards( parent=parent, diff --git a/rslib/src/backend/config.rs b/rslib/src/backend/config.rs index 9949c66b7..7c89562c5 100644 --- a/rslib/src/backend/config.rs +++ b/rslib/src/backend/config.rs @@ -36,6 +36,8 @@ impl From for BoolKey { BoolKeyProto::RestorePositionReviewer => BoolKey::RestorePositionReviewer, BoolKeyProto::ResetCountsBrowser => BoolKey::ResetCountsBrowser, BoolKeyProto::ResetCountsReviewer => BoolKey::ResetCountsReviewer, + BoolKeyProto::RandomOrderReposition => BoolKey::RandomOrderReposition, + BoolKeyProto::ShiftPositionOfExistingCards => BoolKey::ShiftPositionOfExistingCards, } } } diff --git a/rslib/src/backend/scheduler/mod.rs b/rslib/src/backend/scheduler/mod.rs index e8cfc0730..dceb6cd19 100644 --- a/rslib/src/backend/scheduler/mod.rs +++ b/rslib/src/backend/scheduler/mod.rs @@ -157,6 +157,10 @@ impl SchedulerService for Backend { }) } + fn reposition_defaults(&self, _input: pb::Empty) -> Result { + self.with_col(|col| Ok(col.reposition_defaults())) + } + fn sort_deck(&self, input: pb::SortDeckRequest) -> Result { self.with_col(|col| { col.sort_deck_legacy(input.deck_id.into(), input.randomize) diff --git a/rslib/src/config/bool.rs b/rslib/src/config/bool.rs index 3820e4095..d62c6a2f2 100644 --- a/rslib/src/config/bool.rs +++ b/rslib/src/config/bool.rs @@ -31,6 +31,8 @@ pub enum BoolKey { RestorePositionReviewer, ResetCountsBrowser, ResetCountsReviewer, + RandomOrderReposition, + ShiftPositionOfExistingCards, #[strum(to_string = "normalize_note_text")] NormalizeNoteText, diff --git a/rslib/src/scheduler/new.rs b/rslib/src/scheduler/new.rs index 734ec49ef..6eacff19c 100644 --- a/rslib/src/scheduler/new.rs +++ b/rslib/src/scheduler/new.rs @@ -6,7 +6,7 @@ use std::collections::{HashMap, HashSet}; use rand::seq::SliceRandom; pub use crate::pb::scheduler::{ - schedule_cards_as_new_request::Context as ScheduleAsNewContext, + schedule_cards_as_new_request::Context as ScheduleAsNewContext, RepositionDefaultsResponse, ScheduleCardsAsNewDefaultsResponse, }; use crate::{ @@ -212,6 +212,11 @@ impl Collection { ) -> Result> { let usn = self.usn()?; self.transact(Op::SortCards, |col| { + col.set_config_bool_inner( + BoolKey::RandomOrderReposition, + order == NewCardDueOrder::Random, + )?; + col.set_config_bool_inner(BoolKey::ShiftPositionOfExistingCards, shift)?; col.sort_cards_inner(cids, starting_from, step, order, shift, usn) }) } @@ -244,6 +249,13 @@ impl Collection { Ok(count) } + pub fn reposition_defaults(&self) -> RepositionDefaultsResponse { + RepositionDefaultsResponse { + random: self.get_config_bool(BoolKey::RandomOrderReposition), + shift: self.get_config_bool(BoolKey::ShiftPositionOfExistingCards), + } + } + /// This is handled by update_deck_configs() now; this function has been kept around /// for now to support the old deck config screen. pub fn sort_deck_legacy(&mut self, deck: DeckId, random: bool) -> Result> {