preliminary preview support

This commit is contained in:
Damien Elmes 2013-05-03 17:52:46 +09:00
parent 9875e26e06
commit 5951ccb09e
3 changed files with 142 additions and 16 deletions

View File

@ -2,19 +2,24 @@
# Copyright: Damien Elmes <anki@ichi2.net>
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import sre_constants, cgi
from aqt.qt import *
import time, re
import sre_constants
import cgi
import time
import re
from operator import itemgetter
import anki, aqt.forms
from aqt.qt import *
import anki
import aqt.forms
from anki.utils import fmtTimeSpan, ids2str, stripHTMLMedia, isWin, intTime, isMac
from aqt.utils import saveGeom, restoreGeom, saveSplitter, restoreSplitter, \
saveHeader, restoreHeader, saveState, restoreState, applyStyles, getTag, \
showInfo, askUser, tooltip, openHelp, showWarning, shortcut
showInfo, askUser, tooltip, openHelp, showWarning, shortcut, getBase, mungeQA
from anki.hooks import runHook, addHook, remHook
from aqt.webview import AnkiWebView
from aqt.toolbar import Toolbar
from anki.consts import *
from anki.sound import playFromText, clearAudioQueue
COLOUR_SUSPENDED = "#FFFFB2"
COLOUR_MARKED = "#D9B2E9"
@ -334,6 +339,7 @@ class Browser(QMainWindow):
self.mw = mw
self.col = self.mw.col
self.lastFilter = ""
self._previewWindow = None
self.form = aqt.forms.browser.Ui_Dialog()
self.form.setupUi(self)
restoreGeom(self, "editor", 0)
@ -376,6 +382,7 @@ class Browser(QMainWindow):
c(f.actionChangeModel, s, self.onChangeModel)
# edit
c(f.actionUndo, s, self.mw.onUndo)
c(f.previewButton, SIGNAL("clicked()"), self.onTogglePreview)
c(f.actionInvertSelection, s, self.invertSelection)
c(f.actionSelectNotes, s, self.selectNotes)
c(f.actionFindReplace, s, self.onFindReplace)
@ -565,20 +572,27 @@ class Browser(QMainWindow):
self.form.splitter.widget(1).setVisible(not not show)
if not show:
self.editor.setNote(None)
self.card = None
else:
self.card = self.model.getCard(
self.form.tableView.selectionModel().currentIndex())
self.editor.setNote(self.card.note(reload=True))
self.editor.card = self.card
self._renderPreview(True)
self.toolbar.draw()
def refreshCurrentCard(self, note):
self.model.refreshNote(note)
self._renderPreview(False)
def refreshCurrentCardFilter(self, flag, note, fidx):
self.refreshCurrentCard(note)
return flag
def currentRow(self):
idx = self.form.tableView.selectionModel().currentIndex()
return idx.row()
# Headers & sorting
######################################################################
@ -942,6 +956,105 @@ where id in %s""" % ids2str(sf))
self.close()
self.mw.onCram(self.selectedCards())
# Preview
######################################################################
def onTogglePreview(self):
if self._previewWindow:
self._closePreview()
else:
self._openPreview()
def _openPreview(self):
c = self.connect
self._previewWindow = QDialog()
self._previewWindow.setWindowTitle(_("Preview"))
c(self._previewWindow, SIGNAL("finished(int)"), self._onPreviewFinished)
vbox = QVBoxLayout()
vbox.setMargin(0)
self._previewWeb = AnkiWebView()
vbox.addWidget(self._previewWeb)
bbox = QDialogButtonBox()
self._previewPrev = bbox.addButton("<", QDialogButtonBox.ActionRole)
self._previewPrev.setAutoDefault(False)
self._previewPrev.setShortcut(QKeySequence("Left"))
self._previewNext = bbox.addButton(">", QDialogButtonBox.ActionRole)
self._previewNext.setAutoDefault(False)
self._previewNext.setShortcut(QKeySequence("Right"))
c(self._previewPrev, SIGNAL("clicked()"), self._onPreviewPrev)
c(self._previewNext, SIGNAL("clicked()"), self._onPreviewNext)
vbox.addWidget(bbox)
self._previewWindow.setLayout(vbox)
restoreGeom(self._previewWindow, "preview")
self._previewWindow.show()
self._previewState = "question"
self._renderPreview(True)
def _onPreviewFinished(self, ok):
saveGeom(self._previewWindow, "preview")
self.mw.progress.timer(100, self._onClosePreview, False)
self.form.previewButton.setChecked(False)
def _onPreviewPrev(self):
if self._previewState == "question":
self._previewState = "answer"
self._renderPreview()
else:
self.onPreviousCard()
self._updatePreviewButtons()
def _onPreviewNext(self):
if self._previewState == "question":
self._previewState = "answer"
self._renderPreview()
else:
self.onNextCard()
self._updatePreviewButtons()
def _updatePreviewButtons(self):
if not self._previewWindow:
return
canBack = self.currentRow() > 0 or self._previewState == "question"
self._previewPrev.setEnabled(not not (self.card and canBack))
canForward = self.currentRow() < self.model.rowCount(None) - 1 or \
self._previewState == "question"
self._previewNext.setEnabled(not not (self.card and canForward))
def _closePreview(self):
if self._previewWindow:
self._previewWindow.close()
self._onClosePreview()
def _onClosePreview(self):
self._previewWindow = self._previewPrev = self._previewNext = None
def _renderPreview(self, cardChanged=False):
if not self._previewWindow:
return
c = self.card
if not c:
txt = _("(please select 1 card)")
self._previewWeb.stdHtml(txt)
self._updatePreviewButtons()
return
self._updatePreviewButtons()
if cardChanged:
self._previewState = "question"
# need to force reload even if answer
txt = c.q(reload=True)
if self._previewState == "answer":
txt = c.a()
txt = re.sub("\[\[type:[^]]+\]\]", "", txt)
ti = lambda x: x
base = getBase(self.mw.col)
self._previewWeb.stdHtml(
ti(mungeQA(txt)), self.mw.reviewer._styles(),
bodyClass="card card%d" % (c.ord+1), head=base,
js=anki.js.browserSel)
clearAudioQueue()
if self.mw.reviewer.autoplay(c):
playFromText(txt)
# Card deletion
######################################################################

View File

@ -185,7 +185,7 @@ function _typeAnsPress() {
The front of this card is empty. Please run Tools>Maintenance>Empty Cards.""")
else:
q = c.q()
if self._autoplay(c):
if self.autoplay(c):
playFromText(q)
# render & update bottom
q = self._mungeQA(q)
@ -200,9 +200,9 @@ The front of this card is empty. Please run Tools>Maintenance>Empty Cards.""")
# user hook
runHook('showQuestion')
def _autoplay(self, card):
def autoplay(self, card):
return self.mw.col.decks.confForDid(
self.card.odid or self.card.did)['autoplay']
card.odid or card.did)['autoplay']
def _replayq(self, card):
return self.mw.col.decks.confForDid(
@ -223,7 +223,7 @@ The front of this card is empty. Please run Tools>Maintenance>Empty Cards.""")
c = self.card
a = c.a()
# play audio?
if self._autoplay(c):
if self.autoplay(c):
playFromText(a)
# render and update bottom
a = self._mungeQA(a)

View File

@ -96,13 +96,6 @@
<property name="rightMargin">
<number>0</number>
</property>
<item row="0" column="1">
<widget class="QPushButton" name="searchButton">
<property name="text">
<string>Search</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QComboBox" name="searchEdit">
<property name="sizePolicy">
@ -119,6 +112,26 @@
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="searchButton">
<property name="text">
<string>Search</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="previewButton">
<property name="text">
<string>&amp;Preview</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+P</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>