add ease buttons

This commit is contained in:
Damien Elmes 2011-03-23 09:43:01 +09:00
parent e48e268ee5
commit c09070df26
2 changed files with 126 additions and 144 deletions

View file

@ -352,58 +352,17 @@ Please do not file a bug report with Anki.<br>""")
else: else:
evt.ignore() evt.ignore()
def reviewKeyHandler(self, evt): # to port
if evt.key() in (Qt.Key_Up,Qt.Key_Down,Qt.Key_Left,Qt.Key_Right, # elif self.state == "studyScreen":
Qt.Key_PageUp,Qt.Key_PageDown): # if evt.key() in (Qt.Key_Enter,
mf = self.bodyView.body.page().currentFrame() # Qt.Key_Return):
if evt.key() == Qt.Key_Up: # evt.accept()
mf.evaluateJavaScript("window.scrollBy(0,-20)") # return self.onStartReview()
elif evt.key() == Qt.Key_Down: # elif self.state == "editCurrentFact":
mf.evaluateJavaScript("window.scrollBy(0,20)") # if evt.key() == Qt.Key_Escape:
elif evt.key() == Qt.Key_Left: # evt.accept()
mf.evaluateJavaScript("window.scrollBy(-20,0)") # return self.moveToState("saveEdit")
elif evt.key() == Qt.Key_Right: # evt.ignore()
mf.evaluateJavaScript("window.scrollBy(20,0)")
elif evt.key() == Qt.Key_PageUp:
mf.evaluateJavaScript("window.scrollBy(0,-%d)" %
int(0.9*self.bodyView.body.size().
height()))
elif evt.key() == Qt.Key_PageDown:
mf.evaluateJavaScript("window.scrollBy(0,%d)" %
int(0.9*self.bodyView.body.size().
height()))
evt.accept()
return
if self.state == "showQuestion":
if evt.key() in (Qt.Key_Enter,
Qt.Key_Return):
evt.accept()
return self.form.showAnswerButton.click()
elif evt.key() == Qt.Key_Space and not (
self.currentCard.cardModel.typeAnswer):
evt.accept()
return self.form.showAnswerButton.click()
elif self.state == "showAnswer":
if evt.key() == Qt.Key_Space:
key = str(self.defaultEaseButton())
else:
key = unicode(evt.text())
if key and key >= "1" and key <= "4":
# user entered a quality setting
num=int(key)
evt.accept()
return getattr(self.form, "easeButton%d" %
num).animateClick()
elif self.state == "studyScreen":
if evt.key() in (Qt.Key_Enter,
Qt.Key_Return):
evt.accept()
return self.onStartReview()
elif self.state == "editCurrentFact":
if evt.key() == Qt.Key_Escape:
evt.accept()
return self.moveToState("saveEdit")
evt.ignore()
def cardAnswered(self, quality): def cardAnswered(self, quality):
"Reschedule current card and move back to getQuestion state." "Reschedule current card and move back to getQuestion state."

View file

@ -20,10 +20,11 @@ class Reviewer(object):
self.web = mw.web self.web = mw.web
self.card = None self.card = None
self.cardQueue = [] self.cardQueue = []
# self.main.connect(self.body, SIGNAL("loadFinished(bool)"), self.state = None
# self.onLoadFinished)
def show(self): def show(self):
self.mw.setKeyHandler(self._keyHandler)
self.web.setLinkHandler(self._linkHandler)
self._getCard() self._getCard()
# Fetching a card # Fetching a card
@ -41,6 +42,7 @@ class Reviewer(object):
self.mw.enableCardMenuItems() self.mw.enableCardMenuItems()
self._maybeEnableSound() self._maybeEnableSound()
#self.updateMarkAction() #self.updateMarkAction()
self.state = "question"
self._showQuestion() self._showQuestion()
else: else:
self.mw.disableCardMenuItems() self.mw.disableCardMenuItems()
@ -77,6 +79,28 @@ div.ansbut {
position: relative; top: 25%; position: relative; top: 25%;
} }
#easebuts {
bottom: 1em;
height: 55px;
left: 50%;
margin-left: -125px;
position: fixed;
width: 250px;
font-size: 100%;
display: none;
}
.easebut {
width: 60px;
font-size: 100%;
}
.time {
background: #eee;
padding: 5px;
border-radius: 10px;
}
div#filler { div#filler {
height: 30px; height: 30px;
} }
@ -93,7 +117,7 @@ div#filler {
css = runFilter("addStyles", css) css = runFilter("addStyles", css)
return css return css
# Showing the question # Showing the question (and preparing answer)
########################################################################## ##########################################################################
_revHtml = """ _revHtml = """
@ -103,15 +127,14 @@ div#filler {
<span id="answer" /> <span id="answer" />
%(a)s %(a)s
</td></tr></table> </td></tr></table>
%(buts)s
%(but)s
<script> <script>
function showans () { function showans () {
$(".inv").removeClass('inv'); $(".inv").removeClass('inv');
location.hash = "answer"; location.hash = "answer";
$(".ansbut").hide();
$("#easebuts").show();
}; };
$(document).ready(function () { $(document).ready(function () {
$(".ansbut").focus(); $(".ansbut").focus();
}); });
@ -119,9 +142,11 @@ $(".ansbut").focus();
""" """
def _showQuestion(self): def _showQuestion(self):
self.state = "question"
# fixme: timeboxing # fixme: timeboxing
# fixme: q/a separation # fixme: q/a separation
# fixme: prevent audio from repeating # fixme: prevent audio from repeating
# fixme: include placeholder for type answer result
c = self.card c = self.card
# original question with sounds # original question with sounds
q = c.q() q = c.q()
@ -130,118 +155,110 @@ $(".ansbut").focus();
self.mw.config['autoplaySounds']): self.mw.config['autoplaySounds']):
playFromText(q) playFromText(q)
# render # render
# buf = self.typeAnsResult()
buf = self._revHtml % dict( buf = self._revHtml % dict(
q=mungeQA(q), q=mungeQA(q),
a=mungeQA(a) + '<div id=filler></div>', a=mungeQA(a) + '<div id=filler></div>',
but=self._questionButtons()) buts=self._reviewButtons())
buf = self.mw.deck.media.escapeImages(buf)
self.web.stdHtml(buf, self._styles(), bodyClass=c.cssClass()) self.web.stdHtml(buf, self._styles(), bodyClass=c.cssClass())
runHook('showQuestion') runHook('showQuestion')
# Question buttons
##########################################################################
def _questionButtons(self):
buf = self.typeAnsInput()
# make sure to focus
buf += """
<a id=ansbut class="but ansbut" href=ans onclick="showans();">
<div class=ansbut>%s</div>
</a>
""" % _("Show Answer")
return buf
# Showing the answer # Showing the answer
########################################################################## ##########################################################################
def _showAnswer(self): def _showAnswer(self):
self.state = "answer"
c = self.card
a = c.a() a = c.a()
if self.mw.config['autoplaySounds']: if self.mw.config['autoplaySounds']:
playFromText(a) playFromText(a)
# render # render
runHook('showQuestion') runHook('showQuestion')
# buf = self.typeAnsResult() # Review buttons
# self.write(self.center('<span id=answer />'
# + mungeQA(a)))
def onLoadFinished(self, bool):
if self.state == "showAnswer":
if self.main.config['scrollToAnswer']:
mf = self.body.page().mainFrame()
mf.evaluateJavaScript("location.hash = 'answer'")
# Answer buttons
########################################################################## ##########################################################################
def _reviewButtons(self):
# type answer area
buf = self.typeAnsInput()
# show answer button
buf += """
<a id=ansbut class="but ansbut" href=ans onclick="showans();">
<div class=ansbut>%s</div>
</a>
""" % _("Show Answer")
# ease buttons
buf += self._answerButtons()
return buf
def _answerButtons(self): def _answerButtons(self):
# attach to mw.cardAnswered() if self.card.queue == 2:
self.updateEaseButtons() labels = (_("Again"), _("Hard"), _("Good"), _("Easy"))
self.form.buttonStack.setCurrentIndex(1) green = 2
self.form.buttonStack.show()
self.form.buttonStack.setLayoutDirection(Qt.LeftToRight)
if self.learningButtons():
self.form.easeButton2.setText(_("Good"))
self.form.easeButton3.setText(_("Easy"))
self.form.easeButton4.setText(_("Very Easy"))
else: else:
self.form.easeButton2.setText(_("Hard")) labels = (_("Again"), _("Good"), _("Easy"))
self.form.easeButton3.setText(_("Good")) green = 1
self.form.easeButton4.setText(_("Easy")) times = []
getattr(self.form, "easeButton%d" % self.defaultEaseButton()).\ buttons = []
setFocus() def but(label, i):
return '''
<a class="but easebut" href=ease%d>%s</a>''' % (i, label)
for i in range(0, len(labels)):
times.append(self._buttonTime(i, green))
buttons.append(but(labels[i], i+1))
buf = ("<table><tr><td align=center>" +
"</td><td align=center>".join(times) + "</td></tr>")
buf += "<tr><td>" + "</td><td>".join(buttons) + "</td></tr></table>"
return "<div id=easebuts>" + buf + "</div>"
return buf
def learningButtons(self): def _buttonTime(self, i, green):
return not self.currentCard.successive if self.mw.config['suppressEstimates']:
return ""
txt = self.mw.deck.sched.nextIvlStr(self.card, i+1, True)
if i == 0:
txt = '<span style="color: #700">%s</span>' % txt
elif i == green:
txt = '<span style="color: #070">%s</span>' % txt
txt = '<span class=time>%s</span>' % txt
return txt
def defaultEaseButton(self): # Handlers
if not self.currentCard.successive: ############################################################
return 2
else:
return 3
def updateEaseButtons(self): def _keyHandler(self, evt):
nextInts = {} if self.state == "question":
for i in range(1, 5): if evt.key() in (Qt.Key_Enter,
l = getattr(self.form, "easeLabel%d" % i) Qt.Key_Return):
if self.config['suppressEstimates']: evt.accept()
l.setText("") return self.web.eval("showans();")
elif i == 1: elif evt.key() == Qt.Key_Space and not self.typeAns():
txt = _("Soon") evt.accept()
if self.config['colourTimes']: return self.web.eval("showans();")
txt = '<span style="color: #700"><b>%s</b></span>' % txt elif self.state == "answer":
l.setText(txt) # if evt.key() == Qt.Key_Space:
else: # key = str(self.defaultEaseButton())
txt = self.deck.nextIntervalStr( # else:
self.currentCard, i) # key = unicode(evt.text())
txt = "<b>" + txt + "</b>" # if key and key >= "1" and key <= "4":
if i == self.defaultEaseButton() and self.config['colourTimes']: # # user entered a quality setting
txt = '<span style="color: #070">' + txt + '</span>' # num=int(key)
l.setText(txt) # evt.accept()
# return getattr(self.form, "easeButton%d" %
# num).animateClick()
pass
evt.ignore()
def _linkHandler(self, url):
print "link", url
if url == "ans":
self._showAnswer()
# Font properties & output # Font properties & output
########################################################################## ##########################################################################
def flush(self):
"Write the current HTML buffer to the screen."
self.buffer = self.addStyles() + self.buffer
# hook for user css
runHook("preFlushHook")
self.buffer = '''<html><head>%s</head><body>%s</body></html>''' % (
getBase(self.main.deck, self.card), self.buffer)
#print self.buffer.encode("utf-8")
b = self.buffer
# Feeding webkit unicode can result in it not finding images, so on
# linux/osx we percent escape the image paths as utf8. On Windows the
# problem is more complicated - if we percent-escape as utf8 it fixes
# some images but breaks others. When filenames are normalized by
# dropbox they become unreadable if we escape them.
if not sys.platform.startswith("win32") and self.main.deck:
# and self.main.config['mediaLocation'] == "dropbox"):
b = self.main.deck.media.escapeImages(b)
self.body.setHtml(b)
def write(self, text): def write(self, text):
if type(text) != types.UnicodeType: if type(text) != types.UnicodeType:
text = unicode(text, "utf-8") text = unicode(text, "utf-8")
@ -287,6 +304,10 @@ $(".ansbut").focus();
# else: # else:
# return QLineEdit.keyPressEvent(self, evt) # return QLineEdit.keyPressEvent(self, evt)
def typeAns(self):
"True if current card has answer typing enabled."
return self.card.template()['typeAns']
def typeAnsInput(self): def typeAnsInput(self):
return "" return ""
if self.card.cardModel.typeAnswer: if self.card.cardModel.typeAnswer:
@ -372,6 +393,7 @@ $(".ansbut").focus();
########################################################################## ##########################################################################
def _showCongrats(self): def _showCongrats(self):
self.state = "congrats"
self.card = None self.card = None
self.deck.db.flush() self.deck.db.flush()
self.hideButtons() self.hideButtons()
@ -394,5 +416,6 @@ $(".ansbut").focus();
########################################################################## ##########################################################################
def _showEmpty(self): def _showEmpty(self):
self.state = "empty"
self.switchToWelcomeScreen() self.switchToWelcomeScreen()
self.disableCardMenuItems() self.disableCardMenuItems()