# -*- 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 from dataclasses import dataclass from typing import Optional import aqt from anki.lang import _ from aqt import gui_hooks from aqt.qt import QUrl from aqt.sound import av_player from aqt.theme import theme_manager from aqt.toolbar import BottomBar from aqt.utils import askUserDialog, openLink, shortcut, tooltip class OverviewBottomBar: def __init__(self, overview: Overview): self.overview = overview @dataclass class OverviewContent: """Stores sections of HTML content that the overview will be populated with. Attributes: deck {str} -- Plain text deck name shareLink {str} -- HTML of the share link section desc {str} -- HTML of the deck description section table {str} -- HTML of the deck stats table section """ deck: str shareLink: str desc: str table: str 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, self) self.mw.setStateShortcuts(self._shortcutKeys()) self.refresh() def refresh(self): self.mw.col.reset() self._renderPage() self._renderBottom() self.mw.web.setFocus() gui_hooks.overview_did_refresh(self) # 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" or url == "customStudy": 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 = 'Reviews and Updates' else: shareLink = "" table_text = self._table() if not table_text: # deck is finished self._show_finished_screen() return content = OverviewContent( deck=deck["name"], shareLink=shareLink, desc=self._desc(deck), table=self._table(), ) gui_hooks.overview_will_render_content(self, content) self.web.stdHtml( self._body % content.__dict__, css=["overview.css"], js=["jquery.js", "overview.js"], context=self, ) def _show_finished_screen(self): self.web.set_open_links_externally(False) if theme_manager.night_mode: extra = "#night" else: extra = "" self.web.hide_while_preserving_layout() self.web.load(QUrl(f"{self.mw.serverURL()}_anki/congrats.html" + extra)) self.web.inject_dynamic_style_and_show() 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 "
" if deck["dyn"]: dyn = "dyn" else: dyn = "" return '
| %s |