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> # Copyright: Damien Elmes <anki@ichi2.net>
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import sre_constants, cgi import sre_constants
from aqt.qt import * import cgi
import time, re import time
import re
from operator import itemgetter 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 anki.utils import fmtTimeSpan, ids2str, stripHTMLMedia, isWin, intTime, isMac
from aqt.utils import saveGeom, restoreGeom, saveSplitter, restoreSplitter, \ from aqt.utils import saveGeom, restoreGeom, saveSplitter, restoreSplitter, \
saveHeader, restoreHeader, saveState, restoreState, applyStyles, getTag, \ 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 anki.hooks import runHook, addHook, remHook
from aqt.webview import AnkiWebView from aqt.webview import AnkiWebView
from aqt.toolbar import Toolbar from aqt.toolbar import Toolbar
from anki.consts import * from anki.consts import *
from anki.sound import playFromText, clearAudioQueue
COLOUR_SUSPENDED = "#FFFFB2" COLOUR_SUSPENDED = "#FFFFB2"
COLOUR_MARKED = "#D9B2E9" COLOUR_MARKED = "#D9B2E9"
@ -334,6 +339,7 @@ class Browser(QMainWindow):
self.mw = mw self.mw = mw
self.col = self.mw.col self.col = self.mw.col
self.lastFilter = "" self.lastFilter = ""
self._previewWindow = None
self.form = aqt.forms.browser.Ui_Dialog() self.form = aqt.forms.browser.Ui_Dialog()
self.form.setupUi(self) self.form.setupUi(self)
restoreGeom(self, "editor", 0) restoreGeom(self, "editor", 0)
@ -376,6 +382,7 @@ class Browser(QMainWindow):
c(f.actionChangeModel, s, self.onChangeModel) c(f.actionChangeModel, s, self.onChangeModel)
# edit # edit
c(f.actionUndo, s, self.mw.onUndo) c(f.actionUndo, s, self.mw.onUndo)
c(f.previewButton, SIGNAL("clicked()"), self.onTogglePreview)
c(f.actionInvertSelection, s, self.invertSelection) c(f.actionInvertSelection, s, self.invertSelection)
c(f.actionSelectNotes, s, self.selectNotes) c(f.actionSelectNotes, s, self.selectNotes)
c(f.actionFindReplace, s, self.onFindReplace) c(f.actionFindReplace, s, self.onFindReplace)
@ -565,20 +572,27 @@ class Browser(QMainWindow):
self.form.splitter.widget(1).setVisible(not not show) self.form.splitter.widget(1).setVisible(not not show)
if not show: if not show:
self.editor.setNote(None) self.editor.setNote(None)
self.card = None
else: else:
self.card = self.model.getCard( self.card = self.model.getCard(
self.form.tableView.selectionModel().currentIndex()) self.form.tableView.selectionModel().currentIndex())
self.editor.setNote(self.card.note(reload=True)) self.editor.setNote(self.card.note(reload=True))
self.editor.card = self.card self.editor.card = self.card
self._renderPreview(True)
self.toolbar.draw() self.toolbar.draw()
def refreshCurrentCard(self, note): def refreshCurrentCard(self, note):
self.model.refreshNote(note) self.model.refreshNote(note)
self._renderPreview(False)
def refreshCurrentCardFilter(self, flag, note, fidx): def refreshCurrentCardFilter(self, flag, note, fidx):
self.refreshCurrentCard(note) self.refreshCurrentCard(note)
return flag return flag
def currentRow(self):
idx = self.form.tableView.selectionModel().currentIndex()
return idx.row()
# Headers & sorting # Headers & sorting
###################################################################### ######################################################################
@ -942,6 +956,105 @@ where id in %s""" % ids2str(sf))
self.close() self.close()
self.mw.onCram(self.selectedCards()) 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 # Card deletion
###################################################################### ######################################################################

View File

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

View File

@ -96,13 +96,6 @@
<property name="rightMargin"> <property name="rightMargin">
<number>0</number> <number>0</number>
</property> </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"> <item row="0" column="0">
<widget class="QComboBox" name="searchEdit"> <widget class="QComboBox" name="searchEdit">
<property name="sizePolicy"> <property name="sizePolicy">
@ -119,6 +112,26 @@
</property> </property>
</widget> </widget>
</item> </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> </layout>
</item> </item>
<item> <item>