mirror of
https://github.com/ankitects/anki.git
synced 2025-11-12 07:37:11 -05:00
card template section implemented
This commit is contained in:
parent
35a5569038
commit
63b015fba5
4 changed files with 426 additions and 344 deletions
|
|
@ -613,6 +613,9 @@ class EditDeck(QMainWindow):
|
|||
self.dialog.actionRedo.setEnabled(True)
|
||||
else:
|
||||
self.dialog.actionRedo.setEnabled(False)
|
||||
if type=="all":
|
||||
self.updateAfterCardChange()
|
||||
else:
|
||||
# update list
|
||||
if self.currentRow and self.model.cards:
|
||||
self.model.updateCard(self.currentRow)
|
||||
|
|
@ -763,6 +766,7 @@ class EditDeck(QMainWindow):
|
|||
return
|
||||
fact = self.currentCard.fact
|
||||
self.editor.setFact(fact, True)
|
||||
self.editor.card = self.currentCard
|
||||
self.showCardInfo(self.currentCard)
|
||||
self.onEvent()
|
||||
self.updateToggles()
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
from PyQt4.QtGui import *
|
||||
from PyQt4.QtCore import *
|
||||
from PyQt4.QtWebKit import QWebPage, QWebView
|
||||
import sys, re
|
||||
import ankiqt.forms
|
||||
import anki
|
||||
|
|
@ -10,304 +11,250 @@ from anki.models import *
|
|||
from anki.facts import *
|
||||
from anki.fonts import toCanonicalFont
|
||||
from anki.cards import Card
|
||||
from ankiqt.ui.utils import saveGeom, restoreGeom
|
||||
from anki.sound import playFromText, clearAudioQueue
|
||||
from ankiqt.ui.utils import saveGeom, restoreGeom, getBase, mungeQA
|
||||
from anki.hooks import runFilter
|
||||
from ankiqt import ui
|
||||
|
||||
class CardLayout(QDialog):
|
||||
|
||||
def __init__(self, parent, fact, card=None):
|
||||
QDialog.__init__(self, parent) #, Qt.Window)
|
||||
self.parent = parent
|
||||
def __init__(self, factedit, fact, card=None):
|
||||
self.parent = factedit.parent
|
||||
QDialog.__init__(self, self.parent)
|
||||
self.factedit = factedit
|
||||
self.mw = ankiqt.mw
|
||||
self.deck = self.mw.deck
|
||||
self.fact = fact
|
||||
self.model = fact.model
|
||||
self.card = card or self.model.cardModels[0]
|
||||
self.card = card
|
||||
self.ignoreUpdate = False
|
||||
self.needFormatRebuild = False
|
||||
self.plastiqueStyle = None
|
||||
if (sys.platform.startswith("darwin") or
|
||||
sys.platform.startswith("win32")):
|
||||
self.plastiqueStyle = QStyleFactory.create("plastique")
|
||||
|
||||
if self.card:
|
||||
# limited to an existing card
|
||||
self.cards = [self.card]
|
||||
else:
|
||||
# active & possible
|
||||
self.cards = self.deck.previewFact(self.fact)
|
||||
if not self.cards:
|
||||
ui.utils.showInfo(_(
|
||||
"Please enter some text first."),
|
||||
parent=self.parent)
|
||||
return
|
||||
self.form = ankiqt.forms.clayout.Ui_Dialog()
|
||||
self.form.setupUi(self)
|
||||
# self.connect(self.form.helpButton, SIGNAL("clicked()"),
|
||||
# self.onHelp)
|
||||
|
||||
# self.setupChooser()
|
||||
self.setupCards()
|
||||
# self.setupFields()
|
||||
# self.setupButtons()
|
||||
restoreGeom(self, "CardLayout")
|
||||
self.exec_()
|
||||
|
||||
# Cards & Preview
|
||||
##########################################################################
|
||||
|
||||
def setupCards(self):
|
||||
self.connect(self.form.cardList, SIGNAL("activated(int)"),
|
||||
self.cardChanged)
|
||||
self.connect(self.form.cardQuestion, SIGNAL("textChanged()"),
|
||||
lambda: self.formatChanged("question"))
|
||||
self.connect(self.form.cardAnswer, SIGNAL("textChanged()"),
|
||||
lambda: self.formatChanged("answer"))
|
||||
self.connect(self.form.alignment,
|
||||
SIGNAL("activated(int)"),
|
||||
self.saveCard)
|
||||
self.connect(self.form.background,
|
||||
SIGNAL("clicked()"),
|
||||
lambda w=self.form.background:\
|
||||
self.chooseColour(w))
|
||||
self.chooseColour(w, "card"))
|
||||
self.connect(self.form.questionInAnswer,
|
||||
SIGNAL("clicked()"), self.saveCard)
|
||||
self.connect(self.form.allowEmptyAnswer,
|
||||
SIGNAL("clicked()"), self.saveCard)
|
||||
self.connect(self.form.typeAnswer, SIGNAL("activated(int)"),
|
||||
self.saveCard)
|
||||
self.connect(self.form.flipButton, SIGNAL("clicked()"),
|
||||
self.onFlip)
|
||||
def linkClicked(self, url):
|
||||
QDesktopServices.openUrl(QUrl(url))
|
||||
self.form.preview.page().setLinkDelegationPolicy(
|
||||
QWebPage.DelegateExternalLinks)
|
||||
self.connect(self.form.preview,
|
||||
SIGNAL("linkClicked(QUrl)"),
|
||||
linkClicked)
|
||||
if self.plastiqueStyle:
|
||||
self.form.background.setStyle(self.plastiqueStyle)
|
||||
self.drawCards()
|
||||
|
||||
|
||||
def formatToScreen(self, fmt):
|
||||
fmt = fmt.replace("<br>", "<br>\n")
|
||||
fmt = re.sub("%\((.+?)\)s", "{{\\1}}", fmt)
|
||||
return fmt
|
||||
|
||||
def screenToFormat(self, fmt):
|
||||
fmt = fmt.replace("<br>\n", "<br>")
|
||||
fmt = re.sub("{{(.+?)}}", "%(\\1)s", fmt)
|
||||
return fmt
|
||||
|
||||
def saveCurrentCard(self):
|
||||
if not self.currentCard:
|
||||
return
|
||||
card = self.currentCard
|
||||
newname = unicode(self.form.cardName.text())
|
||||
if not newname:
|
||||
newname = _("Card-%d") % (self.model.cardModels.index(card) + 1)
|
||||
self.updateField(card, 'name', newname)
|
||||
s = unicode(self.form.cardQuestion.toPlainText())
|
||||
changed = self.updateField(card, 'qformat', self.screenToFormat(s))
|
||||
s = unicode(self.form.cardAnswer.toPlainText())
|
||||
changed2 = self.updateField(card, 'aformat', self.screenToFormat(s))
|
||||
self.needRebuild = self.needRebuild or changed or changed2
|
||||
self.updateField(card, 'questionInAnswer', self.form.questionInAnswer.isChecked())
|
||||
self.updateField(card, 'allowEmptyAnswer', self.form.allowEmptyAnswer.isChecked())
|
||||
idx = self.form.typeAnswer.currentIndex()
|
||||
if not idx:
|
||||
self.updateField(card, 'typeAnswer', u"")
|
||||
else:
|
||||
self.updateField(card, 'typeAnswer', self.fieldNames[idx-1])
|
||||
self.ignoreCardUpdate = True
|
||||
self.updateCards()
|
||||
self.ignoreCardUpdate = False
|
||||
|
||||
def updateField(self, obj, field, value):
|
||||
if getattr(obj, field) != value:
|
||||
setattr(obj, field, value)
|
||||
self.model.setModified()
|
||||
self.deck.setModified()
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
|
||||
def drawCards(self):
|
||||
self.form.cardList.clear()
|
||||
self.form.cardList.addItems(
|
||||
QStringList([c.name for c in self.model.cardModels]))
|
||||
self.form.alignment.clear()
|
||||
self.form.alignment.addItems(
|
||||
QStringList(alignmentLabels().values()))
|
||||
self.cardChanged(0)
|
||||
self.fillCardList()
|
||||
|
||||
def cardChanged(self, idx):
|
||||
self.card = self.model.cardModels[idx]
|
||||
self.readCard()
|
||||
self.drawQuestionAndAnswer()
|
||||
def formatToScreen(self, fmt):
|
||||
fmt = re.sub("%\((.+?)\)s", "{{\\1}}", fmt)
|
||||
fmt = fmt.replace("}}<br>", "}}\n")
|
||||
return fmt
|
||||
|
||||
def screenToFormat(self, fmt):
|
||||
fmt = fmt.replace("}}\n", "}}<br>")
|
||||
fmt = re.sub("{{(.+?)}}", "%(\\1)s", fmt)
|
||||
return fmt
|
||||
|
||||
# def realCardModel(self, card):
|
||||
# # get on disk representation from detached object
|
||||
# for cm in self.fact.model.cardModels:
|
||||
# if cm.id == card.cardModelId:
|
||||
# return cm
|
||||
|
||||
def formatChanged(self, type):
|
||||
if self.updatingCards:
|
||||
return
|
||||
if type == "question":
|
||||
text = unicode(self.form.cardQuestion.toPlainText())
|
||||
text = self.screenToFormat(text)
|
||||
#self.realCardModel(self.card).qformat = text
|
||||
self.card.cardModel.qformat = text
|
||||
else:
|
||||
text = unicode(self.form.cardAnswer.toPlainText())
|
||||
text = self.screenToFormat(text)
|
||||
self.card.cardModel.aformat = text
|
||||
self.fact.model.setModified()
|
||||
self.deck.flushMod()
|
||||
d = {}
|
||||
for f in self.fact.model.fieldModels:
|
||||
d[f.name] = (f.id, self.fact[f.name])
|
||||
for card in self.cards:
|
||||
qa = formatQA(None, self.fact.modelId, d, card.splitTags(), card.cardModel)
|
||||
card.question = qa['question']
|
||||
card.answer = qa['answer']
|
||||
card.setModified()
|
||||
self.deck.setModified()
|
||||
self.needFormatRebuild = True
|
||||
self.renderPreview()
|
||||
|
||||
def onFlip(self):
|
||||
q = unicode(self.form.cardQuestion.toPlainText())
|
||||
a = unicode(self.form.cardAnswer.toPlainText())
|
||||
self.form.cardAnswer.setPlainText(q)
|
||||
self.form.cardQuestion.setPlainText(a)
|
||||
|
||||
def readCard(self):
|
||||
card = self.card
|
||||
card = self.card.cardModel
|
||||
self.form.background.setPalette(QPalette(QColor(
|
||||
getattr(card, "lastFontColour"))))
|
||||
self.updatingCards = True
|
||||
self.form.cardQuestion.setPlainText(self.formatToScreen(card.qformat))
|
||||
self.form.cardAnswer.setPlainText(self.formatToScreen(card.aformat))
|
||||
self.form.questionInAnswer.setChecked(card.questionInAnswer)
|
||||
self.form.allowEmptyAnswer.setChecked(card.allowEmptyAnswer)
|
||||
self.form.typeAnswer.clear()
|
||||
self.fieldNames = self.deck.s.column0("""
|
||||
self.typeFieldNames = self.deck.s.column0("""
|
||||
select fieldModels.name as n from fieldModels, cardModels
|
||||
where cardModels.modelId = fieldModels.modelId
|
||||
and cardModels.id = :id
|
||||
order by n""", id=card.id)
|
||||
s = [_("Don't ask me to type in the answer")]
|
||||
s += [_("Compare with field '%s'") % f for f in self.fieldNames]
|
||||
s += [_("Compare with field '%s'") % f for f in self.typeFieldNames]
|
||||
self.form.typeAnswer.insertItems(0, QStringList(s))
|
||||
try:
|
||||
idx = self.fieldNames.index(card.typeAnswer)
|
||||
idx = self.typeFieldNames.index(card.typeAnswer)
|
||||
except ValueError:
|
||||
idx = -1
|
||||
self.form.typeAnswer.setCurrentIndex(idx + 1)
|
||||
self.updatingCards = False
|
||||
|
||||
# def updateField(self, obj, field, value):
|
||||
# if getattr(obj, field) != value:
|
||||
# setattr(obj, field, value)
|
||||
# self.model.setModified()
|
||||
# self.deck.setModified()
|
||||
# return True
|
||||
# return False
|
||||
|
||||
def fillCardList(self):
|
||||
self.form.cardList.clear()
|
||||
self.form.cardList.addItems(
|
||||
QStringList([c.cardModel.name for c in self.cards]))
|
||||
if [self.card] == self.cards:
|
||||
self.form.cardList.setEnabled(False)
|
||||
self.form.editTemplates.setEnabled(False)
|
||||
self.cardChanged(0)
|
||||
|
||||
def cardChanged(self, idx):
|
||||
self.card = self.cards[idx]
|
||||
self.readCard()
|
||||
self.renderPreview()
|
||||
|
||||
def saveCard(self):
|
||||
if not self.card:
|
||||
if self.updatingCards:
|
||||
return
|
||||
self.card.questionAlign = self.form.align.currentIndex()
|
||||
setattr(self.card, "lastFontColour", unicode(
|
||||
self.form.backgroundColour.palette().window().color().name()))
|
||||
self.card.model.setModified()
|
||||
self.deck.setModified()
|
||||
|
||||
self.drawQuestionAndAnswer()
|
||||
|
||||
def cwidget(self, name, type):
|
||||
"Return a card widget."
|
||||
return getattr(self.form, type + name)
|
||||
|
||||
def setupFields(self):
|
||||
self.connect(self.form.fieldList, SIGNAL("currentRowChanged(int)"),
|
||||
self.fieldChanged)
|
||||
for type in ("quiz", "edit"):
|
||||
self.connect(self.fwidget("fontFamily", type),
|
||||
SIGNAL("currentFontChanged(QFont)"),
|
||||
self.saveField)
|
||||
self.connect(self.fwidget("fontSize", type),
|
||||
SIGNAL("valueChanged(int)"),
|
||||
self.saveField)
|
||||
self.connect(self.fwidget("useFamily", type),
|
||||
SIGNAL("stateChanged(int)"),
|
||||
self.saveField)
|
||||
self.connect(self.fwidget("useSize", type),
|
||||
SIGNAL("stateChanged(int)"),
|
||||
self.saveField)
|
||||
if type == "quiz":
|
||||
self.connect(self.fwidget("useColour", type),
|
||||
SIGNAL("stateChanged(int)"),
|
||||
self.saveField)
|
||||
w = self.fwidget("fontColour", type)
|
||||
if self.plastiqueStyle:
|
||||
w.setStyle(self.plastiqueStyle)
|
||||
self.connect(w,
|
||||
SIGNAL("clicked()"),
|
||||
lambda w=w: self.chooseColour(w))
|
||||
elif type == "edit":
|
||||
self.connect(self.form.rtl,
|
||||
SIGNAL("stateChanged(int)"),
|
||||
self.saveField)
|
||||
self.currentField = None
|
||||
self.drawFields()
|
||||
|
||||
def drawFields(self):
|
||||
self.form.fieldList.clear()
|
||||
n = 1
|
||||
self.ignoreUpdate = True
|
||||
for field in self.model.fieldModels:
|
||||
item = QListWidgetItem(
|
||||
_("Field %(num)d: %(name)s") % {
|
||||
'num': n,
|
||||
'name': field.name,
|
||||
})
|
||||
self.form.fieldList.addItem(item)
|
||||
n += 1
|
||||
self.form.fieldList.setCurrentRow(0)
|
||||
self.fieldChanged(0)
|
||||
self.ignoreUpdate = False
|
||||
|
||||
def fwidget(self, name, type):
|
||||
"Return a field widget."
|
||||
if type == "edit":
|
||||
return getattr(self.form, name+"Edit")
|
||||
card = self.card.cardModel
|
||||
card.questionAlign = self.form.alignment.currentIndex()
|
||||
card.lastFontColour = unicode(
|
||||
self.form.background.palette().window().color().name())
|
||||
card.questionInAnswer = self.form.questionInAnswer.isChecked()
|
||||
card.allowEmptyAnswer = self.form.allowEmptyAnswer.isChecked()
|
||||
idx = self.form.typeAnswer.currentIndex()
|
||||
if not idx:
|
||||
card.typeAnswer = u""
|
||||
else:
|
||||
return getattr(self.form, name)
|
||||
|
||||
def fieldChanged(self, idx):
|
||||
self.saveField()
|
||||
self.currentField = None
|
||||
field = self.model.fieldModels[idx]
|
||||
for type in ("quiz", "edit"):
|
||||
# family
|
||||
if getattr(field, type + 'FontFamily'):
|
||||
self.fwidget("useFamily", type).setCheckState(Qt.Checked)
|
||||
self.fwidget("fontFamily", type).setCurrentFont(QFont(
|
||||
getattr(field, type + 'FontFamily')))
|
||||
self.fwidget("fontFamily", type).setEnabled(True)
|
||||
else:
|
||||
self.fwidget("useFamily", type).setCheckState(Qt.Unchecked)
|
||||
self.fwidget("fontFamily", type).setEnabled(False)
|
||||
# size
|
||||
if getattr(field, type + 'FontSize'):
|
||||
self.fwidget("useSize", type).setCheckState(Qt.Checked)
|
||||
self.fwidget("fontSize", type).setValue(
|
||||
getattr(field, type + 'FontSize'))
|
||||
self.fwidget("fontSize", type).setEnabled(True)
|
||||
else:
|
||||
self.fwidget("useSize", type).setCheckState(Qt.Unchecked)
|
||||
self.fwidget("fontSize", type).setEnabled(False)
|
||||
if type == "quiz":
|
||||
# colour
|
||||
if getattr(field, type + 'FontColour'):
|
||||
self.fwidget("useColour", type).setCheckState(Qt.Checked)
|
||||
self.fwidget("fontColour", type).setPalette(QPalette(QColor(
|
||||
getattr(field, type + 'FontColour'))))
|
||||
self.fwidget("fontColour", type).setEnabled(True)
|
||||
else:
|
||||
self.fwidget("useColour", type).setCheckState(Qt.Unchecked)
|
||||
self.fwidget("fontColour", type).setEnabled(False)
|
||||
elif type == "edit":
|
||||
self.form.rtl.setChecked(not not field.features)
|
||||
self.currentField = field
|
||||
|
||||
def saveField(self, *args):
|
||||
if self.ignoreUpdate:
|
||||
return
|
||||
field = self.currentField
|
||||
if not field:
|
||||
return
|
||||
for type in ("quiz", "edit"):
|
||||
# family
|
||||
if self.fwidget("useFamily", type).isChecked():
|
||||
setattr(field, type + 'FontFamily', toCanonicalFont(unicode(
|
||||
self.fwidget("fontFamily", type).currentFont().family())))
|
||||
else:
|
||||
setattr(field, type + 'FontFamily', None)
|
||||
# size
|
||||
if self.fwidget("useSize", type).isChecked():
|
||||
setattr(field, type + 'FontSize',
|
||||
int(self.fwidget("fontSize", type).value()))
|
||||
else:
|
||||
setattr(field, type + 'FontSize', None)
|
||||
# colour
|
||||
if type == "quiz":
|
||||
if self.fwidget("useColour", type).isChecked():
|
||||
w = self.fwidget("fontColour", type)
|
||||
c = w.palette().window().color()
|
||||
setattr(field, type + 'FontColour', str(c.name()))
|
||||
else:
|
||||
setattr(field, type + 'FontColour', None)
|
||||
elif type == "edit":
|
||||
if self.form.rtl.isChecked():
|
||||
field.features = u"rtl"
|
||||
else:
|
||||
field.features = u""
|
||||
field.model.setModified()
|
||||
card.typeAnswer = self.typeFieldNames[idx-1]
|
||||
card.model.setModified()
|
||||
self.deck.flushMod()
|
||||
self.drawQuestionAndAnswer()
|
||||
self.renderPreview()
|
||||
|
||||
def chooseColour(self, button):
|
||||
def chooseColour(self, button, type="field"):
|
||||
new = QColorDialog.getColor(button.palette().window().color(), self)
|
||||
if new.isValid():
|
||||
button.setPalette(QPalette(new))
|
||||
if type == "field":
|
||||
self.saveField()
|
||||
else:
|
||||
self.saveCard()
|
||||
|
||||
def drawQuestionAndAnswer(self):
|
||||
print "draw qa"
|
||||
def renderPreview(self):
|
||||
if self.card:
|
||||
c = self.card
|
||||
else:
|
||||
# we'll need to generate one
|
||||
cards = self.deck.previewFact(self.fact)
|
||||
if not cards:
|
||||
ui.utils.showInfo(_("No cards to preview."),
|
||||
parent=parent)
|
||||
return
|
||||
self.deck.flushMod()
|
||||
f = self.deck.newFact()
|
||||
f.tags = u""
|
||||
for field in f.fields:
|
||||
f[field.name] = field.name
|
||||
f.model = self.model
|
||||
c = Card(f, self.card)
|
||||
t = "<body><br><center>" + c.htmlQuestion() + "</center></body>"
|
||||
bg = "body { background-color: %s; }\n" % self.card.lastFontColour
|
||||
self.form.question.setText(
|
||||
"<style>\n" + bg + self.deck.rebuildCSS() + "</style>\n" + t)
|
||||
t = "<body><br><center>" + c.htmlAnswer() + "</center></body>"
|
||||
self.form.answer.setText(
|
||||
"<style>\n" + bg + self.deck.rebuildCSS() + "</style>\n" + t)
|
||||
self.mw.updateViews(self.mw.state)
|
||||
|
||||
pass
|
||||
styles = (self.deck.rebuildCSS() +
|
||||
("\nhtml { background: %s }" % c.cardModel.lastFontColour) +
|
||||
"\ndiv { white-space: pre-wrap; }")
|
||||
styles = runFilter("addStyles", styles, c)
|
||||
self.form.preview.setHtml(
|
||||
('<html><head>%s</head><body>' % getBase(self.deck, c)) +
|
||||
"<style>" + styles + "</style>" +
|
||||
runFilter("drawQuestion", mungeQA(self.deck, c.htmlQuestion()),
|
||||
c) +
|
||||
"<hr>" +
|
||||
runFilter("drawAnswer", mungeQA(self.deck, c.htmlAnswer()),
|
||||
c)
|
||||
+ "</body></html>")
|
||||
clearAudioQueue()
|
||||
playFromText(c.question)
|
||||
playFromText(c.answer)
|
||||
|
||||
def reject(self):
|
||||
if self.needFormatRebuild:
|
||||
# need to generate q/a templates
|
||||
self.deck.startProgress()
|
||||
self.deck.updateProgress(_("Applying template..."))
|
||||
self.deck.updateCardsFromModel(self.fact.model)
|
||||
self.deck.finishProgress()
|
||||
if self.factedit.onChange:
|
||||
self.factedit.onChange("all")
|
||||
else:
|
||||
self.mw.reset()
|
||||
saveGeom(self, "CardLayout")
|
||||
QDialog.reject(self)
|
||||
|
||||
|
|
@ -318,6 +265,135 @@ order by n""", id=card.id)
|
|||
# Fields
|
||||
##########################################################################
|
||||
|
||||
# def setupFields(self):
|
||||
# self.connect(self.form.fieldList, SIGNAL("currentRowChanged(int)"),
|
||||
# self.fieldChanged)
|
||||
# for type in ("quiz", "edit"):
|
||||
# self.connect(self.fwidget("fontFamily", type),
|
||||
# SIGNAL("currentFontChanged(QFont)"),
|
||||
# self.saveField)
|
||||
# self.connect(self.fwidget("fontSize", type),
|
||||
# SIGNAL("valueChanged(int)"),
|
||||
# self.saveField)
|
||||
# self.connect(self.fwidget("useFamily", type),
|
||||
# SIGNAL("stateChanged(int)"),
|
||||
# self.saveField)
|
||||
# self.connect(self.fwidget("useSize", type),
|
||||
# SIGNAL("stateChanged(int)"),
|
||||
# self.saveField)
|
||||
# if type == "quiz":
|
||||
# self.connect(self.fwidget("useColour", type),
|
||||
# SIGNAL("stateChanged(int)"),
|
||||
# self.saveField)
|
||||
# w = self.fwidget("fontColour", type)
|
||||
# if self.plastiqueStyle:
|
||||
# w.setStyle(self.plastiqueStyle)
|
||||
# self.connect(w,
|
||||
# SIGNAL("clicked()"),
|
||||
# lambda w=w: self.chooseColour(w))
|
||||
# elif type == "edit":
|
||||
# self.connect(self.form.rtl,
|
||||
# SIGNAL("stateChanged(int)"),
|
||||
# self.saveField)
|
||||
# self.currentField = None
|
||||
# self.drawFields()
|
||||
|
||||
# def drawFields(self):
|
||||
# self.form.fieldList.clear()
|
||||
# n = 1
|
||||
# self.ignoreUpdate = True
|
||||
# for field in self.model.fieldModels:
|
||||
# item = QListWidgetItem(
|
||||
# _("Field %(num)d: %(name)s") % {
|
||||
# 'num': n,
|
||||
# 'name': field.name,
|
||||
# })
|
||||
# self.form.fieldList.addItem(item)
|
||||
# n += 1
|
||||
# self.form.fieldList.setCurrentRow(0)
|
||||
# self.fieldChanged(0)
|
||||
# self.ignoreUpdate = False
|
||||
|
||||
# def fwidget(self, name, type):
|
||||
# "Return a field widget."
|
||||
# if type == "edit":
|
||||
# return getattr(self.form, name+"Edit")
|
||||
# else:
|
||||
# return getattr(self.form, name)
|
||||
|
||||
# def fieldChanged(self, idx):
|
||||
# self.saveField()
|
||||
# self.currentField = None
|
||||
# field = self.model.fieldModels[idx]
|
||||
# for type in ("quiz", "edit"):
|
||||
# # family
|
||||
# if getattr(field, type + 'FontFamily'):
|
||||
# self.fwidget("useFamily", type).setCheckState(Qt.Checked)
|
||||
# self.fwidget("fontFamily", type).setCurrentFont(QFont(
|
||||
# getattr(field, type + 'FontFamily')))
|
||||
# self.fwidget("fontFamily", type).setEnabled(True)
|
||||
# else:
|
||||
# self.fwidget("useFamily", type).setCheckState(Qt.Unchecked)
|
||||
# self.fwidget("fontFamily", type).setEnabled(False)
|
||||
# # size
|
||||
# if getattr(field, type + 'FontSize'):
|
||||
# self.fwidget("useSize", type).setCheckState(Qt.Checked)
|
||||
# self.fwidget("fontSize", type).setValue(
|
||||
# getattr(field, type + 'FontSize'))
|
||||
# self.fwidget("fontSize", type).setEnabled(True)
|
||||
# else:
|
||||
# self.fwidget("useSize", type).setCheckState(Qt.Unchecked)
|
||||
# self.fwidget("fontSize", type).setEnabled(False)
|
||||
# if type == "quiz":
|
||||
# # colour
|
||||
# if getattr(field, type + 'FontColour'):
|
||||
# self.fwidget("useColour", type).setCheckState(Qt.Checked)
|
||||
# self.fwidget("fontColour", type).setPalette(QPalette(QColor(
|
||||
# getattr(field, type + 'FontColour'))))
|
||||
# self.fwidget("fontColour", type).setEnabled(True)
|
||||
# else:
|
||||
# self.fwidget("useColour", type).setCheckState(Qt.Unchecked)
|
||||
# self.fwidget("fontColour", type).setEnabled(False)
|
||||
# elif type == "edit":
|
||||
# self.form.rtl.setChecked(not not field.features)
|
||||
# self.currentField = field
|
||||
|
||||
# def saveField(self, *args):
|
||||
# if self.ignoreUpdate:
|
||||
# return
|
||||
# field = self.currentField
|
||||
# if not field:
|
||||
# return
|
||||
# for type in ("quiz", "edit"):
|
||||
# # family
|
||||
# if self.fwidget("useFamily", type).isChecked():
|
||||
# setattr(field, type + 'FontFamily', toCanonicalFont(unicode(
|
||||
# self.fwidget("fontFamily", type).currentFont().family())))
|
||||
# else:
|
||||
# setattr(field, type + 'FontFamily', None)
|
||||
# # size
|
||||
# if self.fwidget("useSize", type).isChecked():
|
||||
# setattr(field, type + 'FontSize',
|
||||
# int(self.fwidget("fontSize", type).value()))
|
||||
# else:
|
||||
# setattr(field, type + 'FontSize', None)
|
||||
# # colour
|
||||
# if type == "quiz":
|
||||
# if self.fwidget("useColour", type).isChecked():
|
||||
# w = self.fwidget("fontColour", type)
|
||||
# c = w.palette().window().color()
|
||||
# setattr(field, type + 'FontColour', str(c.name()))
|
||||
# else:
|
||||
# setattr(field, type + 'FontColour', None)
|
||||
# elif type == "edit":
|
||||
# if self.form.rtl.isChecked():
|
||||
# field.features = u"rtl"
|
||||
# else:
|
||||
# field.features = u""
|
||||
# field.model.setModified()
|
||||
# self.deck.flushMod()
|
||||
# self.drawQuestionAndAnswer()
|
||||
|
||||
# def setupFields(self):
|
||||
# self.fieldOrdinalUpdatedIds = []
|
||||
# self.ignoreFieldUpdate = False
|
||||
|
|
@ -495,60 +571,17 @@ order by n""", id=card.id)
|
|||
# self.model.setModified()
|
||||
# self.deck.setModified()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# class PreviewDialog(QDialog):
|
||||
|
||||
# def __init__(self, parent, deck, fact, *args):
|
||||
# QDialog.__init__(self, parent, *args)
|
||||
# self.deck = deck
|
||||
# self.fact = fact
|
||||
# cards = self.deck.previewFact(self.fact)
|
||||
# if not cards:
|
||||
# ui.utils.showInfo(_("No cards to preview."),
|
||||
# parent=parent)
|
||||
# return
|
||||
# self.cards = cards
|
||||
# self.currentCard = 0
|
||||
# self.form = ankiqt.forms.previewcards.Ui_Dialog()
|
||||
# self.form.setupUi(self)
|
||||
# self.form.webView.page().setLinkDelegationPolicy(
|
||||
# QWebPage.DelegateExternalLinks)
|
||||
# self.connect(self.form.webView,
|
||||
# SIGNAL("linkClicked(QUrl)"),
|
||||
# self.linkClicked)
|
||||
# self.form.comboBox.addItems(QStringList(
|
||||
# [c.cardModel.name for c in self.cards]))
|
||||
# self.connect(self.form.comboBox, SIGNAL("activated(int)"),
|
||||
# self.onChange)
|
||||
# self.updateCard()
|
||||
# restoreGeom(self, "preview")
|
||||
# self.exec_()
|
||||
|
||||
# def linkClicked(self, url):
|
||||
# QDesktopServices.openUrl(QUrl(url))
|
||||
|
||||
# def updateCard(self):
|
||||
# c = self.cards[self.currentCard]
|
||||
# styles = (self.deck.css +
|
||||
# ("\nhtml { background: %s }" % c.cardModel.lastFontColour) +
|
||||
# "\ndiv { white-space: pre-wrap; }")
|
||||
# styles = runFilter("addStyles", styles, c)
|
||||
# self.form.webView.setHtml(
|
||||
# ('<html><head>%s</head><body>' % getBase(self.deck, c)) +
|
||||
# "<style>" + styles + "</style>" +
|
||||
# runFilter("drawQuestion", mungeQA(self.deck, c.htmlQuestion()),
|
||||
# c) +
|
||||
# "<br><br><hr><br><br>" +
|
||||
# runFilter("drawAnswer", mungeQA(self.deck, c.htmlAnswer()),
|
||||
# c)
|
||||
# + "</body></html>")
|
||||
# clearAudioQueue()
|
||||
# playFromText(c.question)
|
||||
# playFromText(c.answer)
|
||||
|
||||
# def onChange(self, idx):
|
||||
# self.currentCard = idx
|
||||
# self.updateCard()
|
||||
|
||||
# def reject(self):
|
||||
# saveGeom(self, "preview")
|
||||
# QDialog.reject(self)
|
||||
|
|
|
|||
|
|
@ -8,12 +8,11 @@ from PyQt4.QtSvg import *
|
|||
from PyQt4.QtWebKit import QWebPage
|
||||
import re, os, sys, tempfile, urllib2, ctypes
|
||||
from anki.utils import stripHTML, tidyHTML, canonifyTags
|
||||
from anki.sound import playFromText, clearAudioQueue
|
||||
from ankiqt.ui.sound import getAudio
|
||||
import anki.sound
|
||||
from ankiqt import ui
|
||||
import ankiqt
|
||||
from ankiqt.ui.utils import mungeQA, saveGeom, restoreGeom, getBase
|
||||
from ankiqt.ui.utils import mungeQA, saveGeom, restoreGeom
|
||||
from anki.hooks import addHook, removeHook, runHook, runFilter
|
||||
from sqlalchemy.exceptions import InvalidRequestError
|
||||
|
||||
|
|
@ -121,15 +120,15 @@ class FactEditor(object):
|
|||
self.fieldsBox.addLayout(self.iconsBox2)
|
||||
# card layout
|
||||
self.iconsBox.addItem(QSpacerItem(20,1, QSizePolicy.Expanding))
|
||||
self.clayout = QPushButton("&Edit Card")
|
||||
self.clayout = QPushButton("Card Layout")
|
||||
self.clayout.connect(self.clayout, SIGNAL("clicked()"), self.onCardLayout)
|
||||
self.clayout.setSizePolicy(QSizePolicy.Preferred,QSizePolicy.Preferred)
|
||||
self.clayout.setFixedHeight(20)
|
||||
# self.clayout.setFixedWidth(48)
|
||||
self.clayout.setIcon(QIcon(":/icons/edit.png"))
|
||||
#self.clayout.setIconSize(QSize(32,32))
|
||||
#self.clayout.setToolTip(_("Bold text (Ctrl+b)"))
|
||||
#self.clayout.setShortcut(_("Ctrl+b"))
|
||||
self.clayout.setToolTip(_("Edit how cards are displayed (F2)"))
|
||||
self.clayout.setShortcut(_("F2"))
|
||||
self.clayout.setFocusPolicy(Qt.NoFocus)
|
||||
self.iconsBox.addWidget(self.clayout)
|
||||
self.clayout.setStyle(self.plastiqueStyle)
|
||||
|
|
@ -489,13 +488,11 @@ class FactEditor(object):
|
|||
# apply fonts
|
||||
font = QFont()
|
||||
# family
|
||||
family = (field.fieldModel.editFontFamily or
|
||||
field.fieldModel.quizFontFamily)
|
||||
family = field.fieldModel.quizFontFamily
|
||||
if family:
|
||||
font.setFamily(family)
|
||||
# size
|
||||
size = (field.fieldModel.editFontSize or
|
||||
field.fieldModel.quizFontSize)
|
||||
size = field.fieldModel.editFontSize
|
||||
if size:
|
||||
font.setPixelSize(size)
|
||||
w.setFont(font)
|
||||
|
|
@ -806,7 +803,7 @@ class FactEditor(object):
|
|||
|
||||
def onCardLayout(self):
|
||||
self.saveFields()
|
||||
ui.clayout.CardLayout(self.parent, self.fact, self.card)
|
||||
ui.clayout.CardLayout(self, self.fact, self.card)
|
||||
|
||||
# FIXME: in some future version, we should use a different delimiter, as
|
||||
# [sound] et al conflicts
|
||||
|
|
|
|||
|
|
@ -6,59 +6,21 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>640</width>
|
||||
<height>464</height>
|
||||
<width>619</width>
|
||||
<height>458</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
<string>Card Layout</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="1" rowspan="3">
|
||||
<widget class="QGroupBox" name="previewGroup">
|
||||
<property name="title">
|
||||
<string>Preview</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="_3">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QTextEdit" name="preview">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close|QDialogButtonBox::Help</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>2</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
|
|
@ -82,7 +44,7 @@
|
|||
<widget class="QTextEdit" name="cardQuestion">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<horstretch>2</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
|
|
@ -172,12 +134,13 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="flipLabel">
|
||||
<widget class="QPushButton" name="flipButton">
|
||||
<property name="text">
|
||||
<string>&nbsp;&nbsp;&nbsp;<a href="#">(flip)</a></string>
|
||||
<string>Flip</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
<property name="icon">
|
||||
<iconset resource="../icons.qrc">
|
||||
<normaloff>:/icons/multisynk.png</normaloff>:/icons/multisynk.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -527,10 +490,95 @@
|
|||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close|QDialogButtonBox::Help</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="previewGroup">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Preview</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="_3">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWebView" name="preview">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="url">
|
||||
<url>
|
||||
<string>about:blank</string>
|
||||
</url>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QWebView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>QtWebKit/QWebView</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>tabWidget</tabstop>
|
||||
<tabstop>cardList</tabstop>
|
||||
<tabstop>editTemplates</tabstop>
|
||||
<tabstop>cardQuestion</tabstop>
|
||||
<tabstop>flipButton</tabstop>
|
||||
<tabstop>cardAnswer</tabstop>
|
||||
<tabstop>alignment</tabstop>
|
||||
<tabstop>background</tabstop>
|
||||
<tabstop>typeAnswer</tabstop>
|
||||
<tabstop>questionInAnswer</tabstop>
|
||||
<tabstop>allowEmptyAnswer</tabstop>
|
||||
<tabstop>buttonBox</tabstop>
|
||||
<tabstop>fieldList</tabstop>
|
||||
<tabstop>fieldAdd</tabstop>
|
||||
<tabstop>fieldUp</tabstop>
|
||||
<tabstop>fieldDown</tabstop>
|
||||
<tabstop>fieldDelete</tabstop>
|
||||
<tabstop>fieldName</tabstop>
|
||||
<tabstop>fontFamily</tabstop>
|
||||
<tabstop>fontSize</tabstop>
|
||||
<tabstop>fontSizeEdit</tabstop>
|
||||
<tabstop>fontColour</tabstop>
|
||||
<tabstop>fieldUnique</tabstop>
|
||||
<tabstop>fieldRequired</tabstop>
|
||||
<tabstop>numeric</tabstop>
|
||||
<tabstop>rtl</tabstop>
|
||||
<tabstop>preview</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../icons.qrc"/>
|
||||
</resources>
|
||||
|
|
|
|||
Loading…
Reference in a new issue