anki/qt/aqt/overview.py
Damien Elmes 7dcbc7efec basic night mode support
Forces the Fusion theme when running night mode, so we don't need
to work around platform themes that don't respond to the defined
palette.

Feedback/suggestions on the chosen colours welcome - _vars.scss is the
file to change if you want to experiment with adjustments.
2020-01-23 17:27:07 +10:00

249 lines
7.5 KiB
Python

# -*- coding: utf-8 -*-
# Copyright: Ankitects Pty Ltd and contributors
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
from __future__ import annotations
import aqt
from anki.lang import _
from aqt.sound import av_player
from aqt.toolbar import BottomBar
from aqt.utils import askUserDialog, openLink, shortcut, tooltip
class Overview:
"Deck overview."
def __init__(self, mw: aqt.AnkiQt) -> None:
self.mw = mw
self.web = mw.web
self.bottom = BottomBar(mw, mw.bottomWeb)
def show(self):
av_player.stop_and_clear_queue()
self.web.set_bridge_command(self._linkHandler, "overview")
self.mw.setStateShortcuts(self._shortcutKeys())
self.refresh()
def refresh(self):
self.mw.col.reset()
self._renderPage()
self._renderBottom()
self.mw.web.setFocus()
# Handlers
############################################################
def _linkHandler(self, url):
if url == "study":
self.mw.col.startTimebox()
self.mw.moveToState("review")
if self.mw.state == "overview":
tooltip(_("No cards are due yet."))
elif url == "anki":
print("anki menu")
elif url == "opts":
self.mw.onDeckConf()
elif url == "cram":
deck = self.mw.col.decks.current()
self.mw.onCram("'deck:%s'" % deck["name"])
elif url == "refresh":
self.mw.col.sched.rebuildDyn()
self.mw.reset()
elif url == "empty":
self.mw.col.sched.emptyDyn(self.mw.col.decks.selected())
self.mw.reset()
elif url == "decks":
self.mw.moveToState("deckBrowser")
elif url == "review":
openLink(aqt.appShared + "info/%s?v=%s" % (self.sid, self.sidVer))
elif url == "studymore":
self.onStudyMore()
elif url == "unbury":
self.onUnbury()
elif url.lower().startswith("http"):
openLink(url)
return False
def _shortcutKeys(self):
return [
("o", self.mw.onDeckConf),
("r", self.onRebuildKey),
("e", self.onEmptyKey),
("c", self.onCustomStudyKey),
("u", self.onUnbury),
]
def _filteredDeck(self):
return self.mw.col.decks.current()["dyn"]
def onRebuildKey(self):
if self._filteredDeck():
self.mw.col.sched.rebuildDyn()
self.mw.reset()
def onEmptyKey(self):
if self._filteredDeck():
self.mw.col.sched.emptyDyn(self.mw.col.decks.selected())
self.mw.reset()
def onCustomStudyKey(self):
if not self._filteredDeck():
self.onStudyMore()
def onUnbury(self):
if self.mw.col.schedVer() == 1:
self.mw.col.sched.unburyCardsForDeck()
self.mw.reset()
return
sibs = self.mw.col.sched.haveBuriedSiblings()
man = self.mw.col.sched.haveManuallyBuried()
if sibs and man:
opts = [
_("Manually Buried Cards"),
_("Buried Siblings"),
_("All Buried Cards"),
_("Cancel"),
]
diag = askUserDialog(_("What would you like to unbury?"), opts)
diag.setDefault(0)
ret = diag.run()
if ret == opts[0]:
self.mw.col.sched.unburyCardsForDeck(type="manual")
elif ret == opts[1]:
self.mw.col.sched.unburyCardsForDeck(type="siblings")
elif ret == opts[2]:
self.mw.col.sched.unburyCardsForDeck(type="all")
else:
self.mw.col.sched.unburyCardsForDeck(type="all")
self.mw.reset()
# HTML
############################################################
def _renderPage(self):
but = self.mw.button
deck = self.mw.col.decks.current()
self.sid = deck.get("sharedFrom")
if self.sid:
self.sidVer = deck.get("ver", None)
shareLink = '<a class=smallLink href="review">Reviews and Updates</a>'
else:
shareLink = ""
self.web.stdHtml(
self._body
% dict(
deck=deck["name"],
shareLink=shareLink,
desc=self._desc(deck),
table=self._table(),
),
css=["overview.css"],
js=["jquery.js", "overview.js"],
)
def _desc(self, deck):
if deck["dyn"]:
desc = _(
"""\
This is a special deck for studying outside of the normal schedule."""
)
desc += " " + _(
"""\
Cards will be automatically returned to their original decks after you review \
them."""
)
desc += " " + _(
"""\
Deleting this deck from the deck list will return all remaining cards \
to their original deck."""
)
else:
desc = deck.get("desc", "")
if not desc:
return "<p>"
if deck["dyn"]:
dyn = "dyn"
else:
dyn = ""
return '<div class="descfont descmid description %s">%s</div>' % (dyn, desc)
def _table(self):
counts = list(self.mw.col.sched.counts())
finished = not sum(counts)
if self.mw.col.schedVer() == 1:
for n in range(len(counts)):
if counts[n] >= 1000:
counts[n] = "1000+"
but = self.mw.button
if finished:
return '<div style="white-space: pre-wrap;">%s</div>' % (
self.mw.col.sched.finishedMsg()
)
else:
return """
<table width=400 cellpadding=5>
<tr><td align=center valign=top>
<table cellspacing=5>
<tr><td>%s:</td><td><b><span class=new-count>%s</span></b></td></tr>
<tr><td>%s:</td><td><b><font class=learn-count>%s</span></b></td></tr>
<tr><td>%s:</td><td><b><span class=review-count>%s</span></b></td></tr>
</table>
</td><td align=center>
%s</td></tr></table>""" % (
_("New"),
counts[0],
_("Learning"),
counts[1],
_("To Review"),
counts[2],
but("study", _("Study Now"), id="study", extra=" autofocus"),
)
_body = """
<center>
<h3>%(deck)s</h3>
%(shareLink)s
%(desc)s
%(table)s
</center>
"""
# Bottom area
######################################################################
def _renderBottom(self):
links = [
["O", "opts", _("Options")],
]
if self.mw.col.decks.current()["dyn"]:
links.append(["R", "refresh", _("Rebuild")])
links.append(["E", "empty", _("Empty")])
else:
links.append(["C", "studymore", _("Custom Study")])
# links.append(["F", "cram", _("Filter/Cram")])
if self.mw.col.sched.haveBuried():
links.append(["U", "unbury", _("Unbury")])
buf = ""
for b in links:
if b[0]:
b[0] = _("Shortcut key: %s") % shortcut(b[0])
buf += """
<button title="%s" onclick='pycmd("%s")'>%s</button>""" % tuple(
b
)
self.bottom.draw(buf)
self.bottom.web.set_bridge_command(self._linkHandler, "overview_bottom")
# Studying more
######################################################################
def onStudyMore(self):
import aqt.customstudy
aqt.customstudy.CustomStudy(self.mw)