diff --git a/aqt/reviewer.py b/aqt/reviewer.py
index 16b7b8622..72b35762e 100644
--- a/aqt/reviewer.py
+++ b/aqt/reviewer.py
@@ -12,6 +12,8 @@ from anki.sound import playFromText, clearAudioQueue
from aqt.utils import mungeQA, getBase
import aqt
+# fixme: space is scrolling instead of showing the current answer
+
class Reviewer(object):
"Manage reviews. Maintains a separate state."
@@ -21,6 +23,7 @@ class Reviewer(object):
self.card = None
self.cardQueue = []
self.state = None
+ self._setupStatus()
def show(self):
self.mw.setKeyHandler(self._keyHandler)
@@ -40,11 +43,13 @@ class Reviewer(object):
clearAudioQueue()
if c:
self.mw.enableCardMenuItems()
+ self._showStatus()
self._maybeEnableSound()
#self.updateMarkAction()
self.state = "question"
self._showQuestion()
else:
+ self._hideStatus()
self.mw.disableCardMenuItems()
if self.mw.deck.cardCount():
self._showCongrats()
@@ -430,3 +435,87 @@ div#filler {
self.state = "empty"
self.switchToWelcomeScreen()
self.disableCardMenuItems()
+
+ # Status bar
+ ##########################################################################
+
+ def _setupStatus(self):
+ self._statusWidgets = []
+ sb = self.mw.form.statusbar
+ def addWgt(w, stretch=0):
+ w.setShown(False)
+ sb.addWidget(w, stretch)
+ self._statusWidgets.append(w)
+ def vertSep():
+ spacer = QFrame()
+ spacer.setFrameStyle(QFrame.VLine)
+ spacer.setFrameShadow(QFrame.Plain)
+ spacer.setStyleSheet("* { color: #888; }")
+ return spacer
+ # left spacer
+ space = QWidget()
+ addWgt(space, 1)
+ # remaining
+ self.remText = QLabel()
+ addWgt(self.remText, 0)
+ # progress
+ addWgt(vertSep())
+ class QClickableProgress(QProgressBar):
+ url = "http://ichi2.net/anki/wiki/ProgressBars"
+ def mouseReleaseEvent(self, evt):
+ QDesktopServices.openUrl(QUrl(self.url))
+ progressBarSize = (50, 14)
+ self.progressBar = QClickableProgress()
+ self.progressBar.setFixedSize(*progressBarSize)
+ self.progressBar.setMaximum(100)
+ self.progressBar.setTextVisible(False)
+ if QApplication.instance().style().objectName() != "plastique":
+ self.plastiqueStyle = QStyleFactory.create("plastique")
+ self.progressBar.setStyle(self.plastiqueStyle)
+ addWgt(self.progressBar, 0)
+
+ def _showStatus(self):
+ self._showStatusWidgets(True)
+ self._updateRemaining()
+ self._updateProgress()
+
+ def _hideStatus(self):
+ self._showStatusWidgets(False)
+
+ def _showStatusWidgets(self, shown=True):
+ for w in self._statusWidgets:
+ w.setShown(shown)
+ self.mw.form.statusbar.hideOrShow()
+
+ # fixme: only show progress for reviews, and only when revs due?
+ # fixme: learn cards are appearing too soon
+ # fixme: learn cards not appearing after 30 secs
+ def _updateRemaining(self):
+ counts = list(self.mw.deck.sched.counts())
+ idx = self.mw.deck.sched.countIdx(self.card)
+ counts[idx] = "%s" % (counts[idx]+1)
+ buf = _("N:%s L:%s R:%s") % tuple(counts)
+ space = " " * 2
+ ctxt = '%s' % counts[0]
+ ctxt += space + '%s' % counts[1]
+ ctxt += space + '%s' % counts[2]
+ buf = _("Remaining: %s") % ctxt
+ self.remText.setText(buf)
+
+ def _updateProgress(self):
+ p = QPalette()
+ p.setColor(QPalette.Base, QColor("black"))
+ p.setColor(QPalette.Button, QColor("black"))
+ perc = 50
+ if perc == 0:
+ p.setColor(QPalette.Highlight, QColor("black"))
+ elif perc < 50:
+ p.setColor(QPalette.Highlight, QColor("#ee0000"))
+ elif perc < 65:
+ p.setColor(QPalette.Highlight, QColor("#ee7700"))
+ elif perc < 75:
+ p.setColor(QPalette.Highlight, QColor("#eeee00"))
+ else:
+ p.setColor(QPalette.Highlight, QColor("#00ee00"))
+ self.progressBar.setPalette(p)
+ self.progressBar.setValue(perc)
diff --git a/aqt/status.py b/aqt/status.py
deleted file mode 100644
index 64b728844..000000000
--- a/aqt/status.py
+++ /dev/null
@@ -1,274 +0,0 @@
-# Copyright: Damien Elmes
-# License: GNU GPL, version 3 or later; http://www.gnu.org/copyleft/gpl.html
-
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
-import anki
-import sys, time
-from anki.hooks import addHook
-
-class QClickableLabel(QLabel):
- url = "http://ichi2.net/anki/wiki/TheTimerAndShortQuestions"
- def mouseReleaseEvent(self, evt):
- QDesktopServices.openUrl(QUrl(self.url))
-
-class QClickableProgress(QProgressBar):
- url = "http://ichi2.net/anki/wiki/ProgressBars"
- def mouseReleaseEvent(self, evt):
- QDesktopServices.openUrl(QUrl(self.url))
-
-# Status bar
-##########################################################################
-
-class StatusView(object):
- "Manage the status bar as we transition through various states."
-
- warnTime = 10
-
- def __init__(self, parent):
- return
- self.main = parent
- self.statusbar = parent.mainWin.statusbar
- self.shown = []
- self.hideBorders()
- self.setState("deckBrowser")
- self.timer = None
- self.timerFlashStart = 0
- self.thinkingTimer = QTimer(parent)
- print "show timer"
- self.thinkingTimer.start(1000)
- parent.connect(self.thinkingTimer, SIGNAL("timeout()"),
- self.drawTimer)
- self.countTimer = QTimer(parent)
- self.countTimer.start(60000)
- parent.connect(self.countTimer, SIGNAL("timeout()"),
- self.updateCount)
- addHook("showQuestion", self.flashTimer)
-
- # State control
- ##########################################################################
-
- def setState(self, state):
- "Change to STATE, and update the display."
- self.state = state
- if self.state == "initial":
- self.showDeckStatus()
- elif self.state == "deckBrowser":
- self.hideDeckStatus()
- elif self.state in ("showQuestion",
- "deckFinished",
- "deckEmpty",
- "studyScreen"):
- self.redraw()
- self.showOrHideToolbar(self.state)
-
- def showOrHideToolbar(self, state):
- if (not self.main.config['showProgress'] and
- state in ("showQuestion", "showAnswer")):
- shown = False
- else:
- shown = True
- self.progressBar.setShown(shown)
- self.etaText.setShown(shown)
- self.remText.setShown(shown)
- self.sep1.setShown(shown)
- self.sep2.setShown(shown)
- # timer has a separate option
- if not self.main.config['showTimer']:
- shown = False
- self.timer.setShown(shown)
- self.sep3.setShown(shown)
- self.statusbar.hideOrShow()
-
- # Setup and teardown
- ##########################################################################
-
- def vertSep(self):
- spacer = QFrame()
- spacer.setFrameStyle(QFrame.VLine)
- spacer.setFrameShadow(QFrame.Plain)
- return spacer
-
- def showDeckStatus(self):
- if self.shown:
- return
- progressBarSize = (50, 14)
- # small spacer
- self.initialSpace = QWidget()
- self.addWidget(self.initialSpace, 1)
- # remaining & eta
- self.remText = QLabel()
- self.addWidget(self.remText, 0)
- self.sep1 = self.vertSep()
- self.addWidget(self.sep1, 0)
- self.etaText = QLabel()
- self.etaText.setToolTip(_(
- "Estimated time
"
- "This is how long it will take to complete the current mode "
- "at your current pace."))
- self.addWidget(self.etaText, 0)
- # progress&retention
- self.sep2 = self.vertSep()
- self.addWidget(self.sep2, 0)
- self.progressBar = QClickableProgress()
- self.progressBar.setFixedSize(*progressBarSize)
- self.progressBar.setMaximum(100)
- self.progressBar.setTextVisible(False)
- if QApplication.instance().style().objectName() != "plastique":
- self.plastiqueStyle = QStyleFactory.create("plastique")
- self.progressBar.setStyle(self.plastiqueStyle)
- self.addWidget(self.progressBar, 0)
- # timer
- self.sep3 = self.vertSep()
- self.addWidget(self.sep3, 0)
- self.timer = QClickableLabel()
- self.timer.setText("00:00")
- self.addWidget(self.timer)
-
- def addWidget(self, w, stretch=0):
- self.statusbar.addWidget(w, stretch)
- self.shown.append(w)
-
- def hideDeckStatus(self):
- for w in self.shown:
- self.statusbar.removeWidget(w)
- w.setParent(None)
- self.shown = []
-
- def hideBorders(self):
- "Remove the ugly borders QT places on status bar widgets."
- self.statusbar.setStyleSheet("::item { border: 0; }")
-
- # Updating
- ##########################################################################
-
- def redraw(self):
- p = QPalette()
- stats = {
- 'failed': self.main.deck.failedSoonCount,
- 'new': self.main.deck.newCount,
- 'rev': self.main.deck.revCount,
- 'new2': self.main.deck.newAvail
- }
- remStr = _("Remaining: ")
- if self.state == "deckFinished":
- remStr += "0"
- elif self.state == "deckEmpty":
- remStr += "0"
- else:
- # remaining string, bolded depending on current card
- if sys.platform.startswith("linux"):
- s = " "
- else:
- s = " "
- if not self.main.currentCard:
- remStr += "%(failed1)s" + s + "%(rev1)s" + s + "%(new1)s"
- else:
- t = self.main.deck.cardQueue(self.main.currentCard)
- if t == 0:
- remStr += ("%(failed1)s" + s +
- "%(rev1)s" + s + "%(new1)s")
- elif t == 1:
- remStr += ("%(failed1)s" + s + "%(rev1)s" + s +
- "%(new1)s")
- else:
- remStr += ("%(failed1)s" + s + "%(rev1)s" + s +
- "%(new1)s")
- stats['failed1'] = '%s' % stats['failed']
- stats['rev1'] = '%s' % stats['rev']
- stats['new1'] = '%s' % stats['new']
- self.remText.setText(remStr % stats)
- self.remText.setToolTip("" +_(
- "Remaining cards") + "
" +
- ngettext("There is %d failed card due soon.", \
- "There are %d failed cards due soon.", \
- stats['failed']) % stats['failed'] + "
" +
- ngettext("There is %d card awaiting review.",
- "There are %d cards awaiting review.", \
- stats['rev']) % stats['rev'] + "
" +
- ngettext("There is %d new card due today.", \
- "There are %d new cards due today.",\
- stats['new']) % stats['new'] + "
" +
- ngettext("There is %d new card in total.", \
- "There are %d new cards in total.",\
- stats['new2']) % stats['new2'])
- # eta
- print "need eta"
- self.etaText.setText(_("ETA: %(timeLeft)s")) # % stats)
- # retention & progress bars
- p.setColor(QPalette.Base, QColor("black"))
- p.setColor(QPalette.Button, QColor("black"))
- print "need yes total%"
- self.setProgressColour(p, 50) #stats['dYesTotal%'])
- self.progressBar.setPalette(p)
- self.progressBar.setValue(50)
- # tooltips
- self.progressBar.setToolTip(
- _("The percentage of correct answers this session."))
- if self.main.config['showTimer']:
- self.drawTimer()
- self.timer.setToolTip(_("""
-Time
-Anki tracks how long you spend looking at a card.
-This time is used to calculate the ETA, but not used
-for scheduling.
-You should aim to answer each question within
-10 seconds. Click the timer to learn more."""))
-
- def setProgressColour(self, palette, perc):
- if perc == 0:
- palette.setColor(QPalette.Highlight, QColor("black"))
- elif perc < 50:
- palette.setColor(QPalette.Highlight, QColor("#ee0000"))
- elif perc < 65:
- palette.setColor(QPalette.Highlight, QColor("#ee7700"))
- elif perc < 75:
- palette.setColor(QPalette.Highlight, QColor("#eeee00"))
- else:
- palette.setColor(QPalette.Highlight, QColor("#00ee00"))
-
- def drawTimer(self):
- if self.main.inDbHandler:
- return
- if not self.main.config['showTimer']:
- return
- if not self.timer:
- return
- if self.main.deck and self.main.state in ("showQuestion", "showAnswer"):
- if self.main.currentCard:
- if time.time() - self.timerFlashStart < 1:
- return
- if not self.main.config['showCardTimer']:
- return
- t = self.main.currentCard.userTime()
- self.setTimer('%02d:%02d' % (t/60, t%60))
- return
- self.setTimer("00:00")
-
- def flashTimer(self):
- if not (self.main.deck.sessionStartTime and
- self.main.deck.sessionTimeLimit): # or self.main.deck.reviewEarly:
- return
- t = time.time() - self.main.deck.sessionStartTime
- t = self.main.deck.sessionTimeLimit - t
- if t < 0:
- t = 0
- self.setTimer('%02d:%02d' %
- (t/60, t%60))
- self.timerFlashStart = time.time()
-
- def updateCount(self):
- if self.main.inDbHandler:
- return
- if not self.main.deck:
- return
- if self.state in ("deckFinished", "studyScreen"):
- self.main.deck.updateCutoff()
- self.main.deck.reset()
- self.redraw()
- self.main.updateTitleBar()
- if self.state == "studyScreen":
- self.main.updateStudyStats()
-
- def setTimer(self, txt):
- self.timer.setText("" + txt + " ")