Skip to content

Commit 704b5e5

Browse files
committed
Rework reschedule tool
The old rescheduling dialog's two options have been split into two separate menu items, "Forget", and "Set Due Date" For cards that are not review cards, "Set Due Date" behaves like the old reschedule option, changing the cards into a review card, and and setting both the interval and due date to the provided number of days. When "Set Due Date" is applied to a review card, it no longer resets the card's interval. Instead, it looks at how much the provided number of days will change the original interval, and adjusts the interval by that amount, so that cards that are answered earlier receive a smaller next interval, and cards that are answered after a longer delay receive a bonus. For example, imagine a card was answered on day 5, and given an interval of 10 days, so it has a due date of day 15. - if on day 10 the due date is changed to day 12 (today+2), the card is being scheduled 3 days earlier than it was supposed to be, so the interval will be adjusted to 7 days. - and if on day 10 the due date is changed to day 20, the interval will be changed from 10 days to 15 days. There is no separate option to reset the interval of a review card, but it can be accomplished by forgetting the card(s), and then setting the desired due date. Other notes: - Added the action to the review screen as well. - Set the shortcut to Ctrl+Shift+D, and changed the existing Delete Tags shortcut to Ctrl+Alt+Shift+A.
1 parent c91a378 commit 704b5e5

24 files changed

+359
-336
lines changed

ftl/core/actions.ftl

+1
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,4 @@ actions-search = Search
3333
actions-shortcut-key = Shortcut key: { $val }
3434
actions-suspend-card = Suspend Card
3535
actions-set-due-date = Set Due Date
36+
actions-forget = Forget

ftl/core/browsing.ftl

-2
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,6 @@ browsing-optional-filter = Optional filter:
6666
browsing-override-back-template = Override back template:
6767
browsing-override-font = Override font:
6868
browsing-override-front-template = Override front template:
69-
browsing-place-at-end-of-new-card = Place at end of new card queue
70-
browsing-place-in-review-queue-with-interval = Place in review queue with interval between:
7169
browsing-please-give-your-filter-a-name = Please give your filter a name:
7270
browsing-please-select-cards-from-only-one = Please select cards from only one note type.
7371
browsing-preview-selected-card = Preview Selected Card ({ $val })

ftl/core/scheduling.ftl

+16
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,19 @@ scheduling-deck-updated =
143143
[one] { $count } deck updated.
144144
*[other] { $count } decks updated.
145145
}
146+
scheduling-set-due-date-prompt =
147+
{ $cards ->
148+
[one] Show card in how many days?
149+
*[other] Show cards in how many days? (eg 1, or 1..7)
150+
}
151+
scheduling-set-due-date-changed-cards =
152+
{ $cards ->
153+
[one] Changed card's due date.
154+
*[other] Changed due date of { $cards } cards.
155+
}
156+
scheduling-set-due-date-invalid-input = Expected a number or range (eg 1, or 1..7)
157+
scheduling-forgot-cards =
158+
{ $cards ->
159+
[one] { $cards } card placed at the end of the new card queue.
160+
*[other] { $cards } cards placed at the end of the new card queue.
161+
}

ftl/qt/qt-accel.ftl

+2-1
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ qt-accel-notes = &Notes
2424
qt-accel-open-addons-folder = &Open Add-ons Folder...
2525
qt-accel-preferences = &Preferences...
2626
qt-accel-previous-card = &Previous Card
27-
qt-accel-reschedule = &Reschedule...
2827
qt-accel-select-all = Select &All
2928
qt-accel-select-notes = Select &Notes
3029
qt-accel-support-anki = &Support Anki...
3130
qt-accel-switch-profile = &Switch Profile
3231
qt-accel-tools = &Tools
3332
qt-accel-undo = &Undo
33+
qt-accel-set-due-date = Set &Due Date...
34+
qt-accel-forget = &Forget

pylib/anki/schedv2.py

+10-9
Original file line numberDiff line numberDiff line change
@@ -1397,20 +1397,17 @@ def _burySiblings(self, card: Card) -> None:
13971397
if toBury:
13981398
self.bury_cards(toBury, manual=False)
13991399

1400-
# Resetting
1400+
# Resetting/rescheduling
14011401
##########################################################################
14021402

14031403
def schedule_cards_as_new(self, card_ids: List[int]) -> None:
14041404
"Put cards at the end of the new queue."
14051405
self.col._backend.schedule_cards_as_new(card_ids=card_ids, log=True)
14061406

1407-
def schedule_cards_as_reviews(
1408-
self, card_ids: List[int], min_interval: int, max_interval: int
1409-
) -> None:
1410-
"Make cards review cards, with a new interval randomly selected from range."
1411-
self.col._backend.schedule_cards_as_reviews(
1412-
card_ids=card_ids, min_interval=min_interval, max_interval=max_interval
1413-
)
1407+
def set_due_date(self, card_ids: List[int], days: str) -> None:
1408+
"""Set cards to be due in `days`, turning them into review cards if necessary.
1409+
`days` can be of the form '5' or '5..7'"""
1410+
self.col._backend.set_due_date(card_ids=card_ids, days=days)
14141411

14151412
def resetCards(self, ids: List[int]) -> None:
14161413
"Completely reset cards for export."
@@ -1430,8 +1427,12 @@ def resetCards(self, ids: List[int]) -> None:
14301427

14311428
# legacy
14321429

1430+
def reschedCards(
1431+
self, card_ids: List[int], min_interval: int, max_interval: int
1432+
) -> None:
1433+
self.set_due_date(card_ids, f"{min_interval}..{max_interval}")
1434+
14331435
forgetCards = schedule_cards_as_new
1434-
reschedCards = schedule_cards_as_reviews
14351436

14361437
# Repositioning new cards
14371438
##########################################################################

pylib/tests/test_schedv1.py

-17
Original file line numberDiff line numberDiff line change
@@ -1077,23 +1077,6 @@ def test_forget():
10771077
assert col.sched.counts() == (1, 0, 0)
10781078

10791079

1080-
def test_resched():
1081-
col = getEmptyCol()
1082-
note = col.newNote()
1083-
note["Front"] = "one"
1084-
col.addNote(note)
1085-
c = note.cards()[0]
1086-
col.sched.reschedCards([c.id], 0, 0)
1087-
c.load()
1088-
assert c.due == col.sched.today
1089-
assert c.ivl == 1
1090-
assert c.queue == CARD_TYPE_REV and c.type == QUEUE_TYPE_REV
1091-
col.sched.reschedCards([c.id], 1, 1)
1092-
c.load()
1093-
assert c.due == col.sched.today + 1
1094-
assert c.ivl == +1
1095-
1096-
10971080
def test_norelearn():
10981081
col = getEmptyCol()
10991082
# add a note

pylib/tests/test_schedv2.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -1124,10 +1124,17 @@ def test_resched():
11241124
assert c.due == col.sched.today
11251125
assert c.ivl == 1
11261126
assert c.queue == QUEUE_TYPE_REV and c.type == CARD_TYPE_REV
1127+
# make it due tomorrow, which increases its interval by a day
11271128
col.sched.reschedCards([c.id], 1, 1)
11281129
c.load()
11291130
assert c.due == col.sched.today + 1
1130-
assert c.ivl == +1
1131+
assert c.ivl == 2
1132+
# but if it was new, that would not happen
1133+
col.sched.forgetCards([c.id])
1134+
col.sched.reschedCards([c.id], 1, 1)
1135+
c.load()
1136+
assert c.due == col.sched.today + 1
1137+
assert c.ivl == 1
11311138

11321139

11331140
def test_norelearn():

qt/aqt/browser.py

+27-24
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from aqt.previewer import BrowserPreviewer as PreviewDialog
2929
from aqt.previewer import Previewer
3030
from aqt.qt import *
31+
from aqt.scheduling import forget_cards, set_due_date_dialog
3132
from aqt.sidebar import SidebarSearchBar, SidebarTreeView
3233
from aqt.theme import theme_manager
3334
from aqt.utils import (
@@ -503,7 +504,8 @@ def setupMenus(self) -> None:
503504
qconnect(f.actionChange_Deck.triggered, self.setDeck)
504505
qconnect(f.action_Info.triggered, self.showCardInfo)
505506
qconnect(f.actionReposition.triggered, self.reposition)
506-
qconnect(f.actionReschedule.triggered, self.reschedule)
507+
qconnect(f.action_set_due_date.triggered, self.set_due_date)
508+
qconnect(f.action_forget.triggered, self.forget_cards)
507509
qconnect(f.actionToggle_Suspend.triggered, self.onSuspend)
508510
qconnect(f.actionRed_Flag.triggered, lambda: self.onSetFlag(1))
509511
qconnect(f.actionOrange_Flag.triggered, lambda: self.onSetFlag(2))
@@ -1384,32 +1386,33 @@ def _reposition(self) -> None:
13841386
self.mw.requireReset(reason=ResetReason.BrowserReposition, context=self)
13851387
self.model.endReset()
13861388

1387-
# Rescheduling
1389+
# Scheduling
13881390
######################################################################
13891391

1390-
def reschedule(self) -> None:
1391-
self.editor.saveNow(self._reschedule)
1392-
1393-
def _reschedule(self) -> None:
1394-
d = QDialog(self)
1395-
disable_help_button(d)
1396-
d.setWindowModality(Qt.WindowModal)
1397-
frm = aqt.forms.reschedule.Ui_Dialog()
1398-
frm.setupUi(d)
1399-
if not d.exec_():
1400-
return
1401-
self.model.beginReset()
1402-
self.mw.checkpoint(tr(TR.BROWSING_RESCHEDULE))
1403-
if frm.asNew.isChecked():
1404-
self.col.sched.forgetCards(self.selectedCards())
1405-
else:
1406-
fmin = frm.min.value()
1407-
fmax = frm.max.value()
1408-
fmax = max(fmin, fmax)
1409-
self.col.sched.reschedCards(self.selectedCards(), fmin, fmax)
1410-
self.search()
1392+
def _after_schedule(self) -> None:
1393+
self.model.reset()
14111394
self.mw.requireReset(reason=ResetReason.BrowserReschedule, context=self)
1412-
self.model.endReset()
1395+
1396+
def set_due_date(self) -> None:
1397+
self.editor.saveNow(
1398+
lambda: set_due_date_dialog(
1399+
mw=self.mw,
1400+
parent=self,
1401+
card_ids=self.selectedCards(),
1402+
default="0",
1403+
on_done=self._after_schedule,
1404+
)
1405+
)
1406+
1407+
def forget_cards(self) -> None:
1408+
self.editor.saveNow(
1409+
lambda: forget_cards(
1410+
mw=self.mw,
1411+
parent=self,
1412+
card_ids=self.selectedCards(),
1413+
on_done=self._after_schedule,
1414+
)
1415+
)
14131416

14141417
# Edit: selection
14151418
######################################################################

qt/aqt/forms/__init__.py

-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
from . import profiles
3333
from . import progress
3434
from . import reposition
35-
from . import reschedule
3635
from . import setgroup
3736
from . import setlang
3837
from . import stats

qt/aqt/forms/browser.ui

+16-10
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,8 @@
262262
</widget>
263263
<addaction name="actionChange_Deck"/>
264264
<addaction name="separator"/>
265-
<addaction name="actionReschedule"/>
265+
<addaction name="action_set_due_date"/>
266+
<addaction name="action_forget"/>
266267
<addaction name="actionReposition"/>
267268
<addaction name="separator"/>
268269
<addaction name="actionToggle_Suspend"/>
@@ -298,14 +299,6 @@
298299
<addaction name="menuJump"/>
299300
<addaction name="menu_Help"/>
300301
</widget>
301-
<action name="actionReschedule">
302-
<property name="text">
303-
<string>QT_ACCEL_RESCHEDULE</string>
304-
</property>
305-
<property name="shortcut">
306-
<string notr="true">Ctrl+Alt+R</string>
307-
</property>
308-
</action>
309302
<action name="actionSelectAll">
310303
<property name="text">
311304
<string>QT_ACCEL_SELECT_ALL</string>
@@ -465,7 +458,7 @@
465458
<string>BROWSING_REMOVE_TAGS</string>
466459
</property>
467460
<property name="shortcut">
468-
<string notr="true">Ctrl+Shift+D</string>
461+
<string notr="true">Ctrl+Alt+Shift+A</string>
469462
</property>
470463
</action>
471464
<action name="actionToggle_Suspend">
@@ -586,6 +579,19 @@
586579
<string notr="true">Ctrl+G</string>
587580
</property>
588581
</action>
582+
<action name="action_set_due_date">
583+
<property name="text">
584+
<string>QT_ACCEL_SET_DUE_DATE</string>
585+
</property>
586+
<property name="shortcut">
587+
<string notr="true">Ctrl+Shift+D</string>
588+
</property>
589+
</action>
590+
<action name="action_forget">
591+
<property name="text">
592+
<string>QT_ACCEL_FORGET</string>
593+
</property>
594+
</action>
589595
</widget>
590596
<resources>
591597
<include location="icons.qrc"/>

qt/aqt/forms/build_ui.py

-30
Original file line numberDiff line numberDiff line change
@@ -18,33 +18,3 @@
1818

1919
with open(py_file, "w") as file:
2020
file.write(outdata)
21-
22-
# init=aqt/forms/__init__.py
23-
# temp=aqt/forms/scratch
24-
# rm -f $init $temp
25-
# echo "# This file auto-generated by build_ui.sh. Don't edit." > $init
26-
# echo "__all__ = [" >> $init
27-
28-
# echo "Generating forms.."
29-
# for i in designer/*.ui
30-
# do
31-
# base=$(basename $i .ui)
32-
# py="aqt/forms/${base}.py"
33-
# echo " \"$base\"," >> $init
34-
# echo "from . import $base" >> $temp
35-
# if [ $i -nt $py ]; then
36-
# echo " * "$py
37-
# pyuic5 --from-imports $i -o $py.tmp
38-
# (cat <<EOF; tail -n +3 $py.tmp) | perl -p -e 's/(QtGui\.QApplication\.)?_?translate\(".*?", /_(/; s/, None.*/))/' > $py
39-
# # -*- coding: utf-8 -*-
40-
# # pylint: disable=unsubscriptable-object,unused-import
41-
# # EOF
42-
# rm $py.tmp
43-
# fi
44-
# done
45-
# echo "]" >> $init
46-
# cat $temp >> $init
47-
# rm $temp
48-
49-
# echo "Building resources.."
50-
# pyrcc5 designer/icons.qrc -o aqt/forms/icons_rc.py

0 commit comments

Comments
 (0)