field section implemented

This commit is contained in:
Damien Elmes 2010-11-30 02:17:36 +09:00
parent 63b015fba5
commit b98e302c70
4 changed files with 208 additions and 322 deletions

View file

@ -118,7 +118,7 @@ class AddCards(QDialog):
else: else:
fact.tags = self.parent.deck.lastTags fact.tags = self.parent.deck.lastTags
# set the new fact # set the new fact
self.editor.setFact(fact, check=True) self.editor.setFact(fact, check=True, forceRedraw=True)
self.setTabOrder(self.editor.tags, self.addButton) self.setTabOrder(self.editor.tags, self.addButton)
self.setTabOrder(self.addButton, self.closeButton) self.setTabOrder(self.addButton, self.closeButton)
self.setTabOrder(self.closeButton, self.helpButton) self.setTabOrder(self.closeButton, self.helpButton)

View file

@ -16,6 +16,10 @@ from ankiqt.ui.utils import saveGeom, restoreGeom, getBase, mungeQA
from anki.hooks import runFilter from anki.hooks import runFilter
from ankiqt import ui from ankiqt import ui
class ResizingTextEdit(QTextEdit):
def sizeHint(self):
return QSize(200, 800)
class CardLayout(QDialog): class CardLayout(QDialog):
def __init__(self, factedit, fact, card=None): def __init__(self, factedit, fact, card=None):
@ -27,13 +31,10 @@ class CardLayout(QDialog):
self.fact = fact self.fact = fact
self.model = fact.model self.model = fact.model
self.card = card self.card = card
self.ignoreUpdate = False
self.needFormatRebuild = False
self.plastiqueStyle = None self.plastiqueStyle = None
if (sys.platform.startswith("darwin") or if (sys.platform.startswith("darwin") or
sys.platform.startswith("win32")): sys.platform.startswith("win32")):
self.plastiqueStyle = QStyleFactory.create("plastique") self.plastiqueStyle = QStyleFactory.create("plastique")
if self.card: if self.card:
# limited to an existing card # limited to an existing card
self.cards = [self.card] self.cards = [self.card]
@ -51,7 +52,7 @@ class CardLayout(QDialog):
# self.onHelp) # self.onHelp)
self.setupCards() self.setupCards()
# self.setupFields() self.setupFields()
restoreGeom(self, "CardLayout") restoreGeom(self, "CardLayout")
self.exec_() self.exec_()
@ -59,6 +60,19 @@ class CardLayout(QDialog):
########################################################################## ##########################################################################
def setupCards(self): def setupCards(self):
self.needFormatRebuild = False
self.updatingCards = False
# replace with more appropriate size hints
for e in ("cardQuestion", "cardAnswer"):
w = getattr(self.form, e)
idx = self.form.templateLayout.indexOf(w)
r = self.form.templateLayout.getItemPosition(idx)
self.form.templateLayout.removeWidget(w)
w.hide()
w.deleteLater()
w = ResizingTextEdit(self)
setattr(self.form, e, w)
self.form.templateLayout.addWidget(w, r[0], r[1])
self.connect(self.form.cardList, SIGNAL("activated(int)"), self.connect(self.form.cardList, SIGNAL("activated(int)"),
self.cardChanged) self.cardChanged)
self.connect(self.form.cardQuestion, SIGNAL("textChanged()"), self.connect(self.form.cardQuestion, SIGNAL("textChanged()"),
@ -245,16 +259,27 @@ order by n""", id=card.id)
playFromText(c.answer) playFromText(c.answer)
def reject(self): def reject(self):
modified = False
self.deck.startProgress()
self.deck.updateProgress(_("Applying changes..."))
if self.needFormatRebuild: if self.needFormatRebuild:
# need to generate q/a templates # need to generate q/a templates
self.deck.startProgress()
self.deck.updateProgress(_("Applying template..."))
self.deck.updateCardsFromModel(self.fact.model) self.deck.updateCardsFromModel(self.fact.model)
self.deck.finishProgress() self.deck.finishProgress()
modified = True
if len(self.fieldOrdinalUpdatedIds) > 0:
self.deck.rebuildFieldOrdinals(self.model.id, self.fieldOrdinalUpdatedIds)
modified = True
if self.needFieldRebuild:
modified = True
if modified:
self.fact.model.setModified()
self.deck.flushMod()
if self.factedit.onChange: if self.factedit.onChange:
self.factedit.onChange("all") self.factedit.onChange("all")
else: else:
self.mw.reset() self.mw.reset()
self.deck.finishProgress()
saveGeom(self, "CardLayout") saveGeom(self, "CardLayout")
QDialog.reject(self) QDialog.reject(self)
@ -265,323 +290,183 @@ order by n""", id=card.id)
# Fields # Fields
########################################################################## ##########################################################################
# def setupFields(self): def setupFields(self):
# self.connect(self.form.fieldList, SIGNAL("currentRowChanged(int)"), self.fieldOrdinalUpdatedIds = []
# self.fieldChanged) self.updatingFields = False
# for type in ("quiz", "edit"): self.needFieldRebuild = False
# self.connect(self.fwidget("fontFamily", type), self.fillFieldList()
# SIGNAL("currentFontChanged(QFont)"), self.fieldChanged(0)
# self.saveField) self.readField()
# self.connect(self.fwidget("fontSize", type), self.connect(self.form.fieldList, SIGNAL("currentRowChanged(int)"),
# SIGNAL("valueChanged(int)"), self.fieldChanged)
# self.saveField) self.connect(self.form.fieldAdd, SIGNAL("clicked()"),
# self.connect(self.fwidget("useFamily", type), self.addField)
# SIGNAL("stateChanged(int)"), self.connect(self.form.fieldDelete, SIGNAL("clicked()"),
# self.saveField) self.deleteField)
# self.connect(self.fwidget("useSize", type), self.connect(self.form.fieldUp, SIGNAL("clicked()"),
# SIGNAL("stateChanged(int)"), self.moveFieldUp)
# self.saveField) self.connect(self.form.fieldDown, SIGNAL("clicked()"),
# if type == "quiz": self.moveFieldDown)
# self.connect(self.fwidget("useColour", type), self.connect(self.form.fieldName, SIGNAL("lostFocus()"),
# SIGNAL("stateChanged(int)"), self.fillFieldList)
# self.saveField) self.connect(self.form.fontFamily, SIGNAL("currentFontChanged(QFont)"),
# w = self.fwidget("fontColour", type) self.saveField)
# if self.plastiqueStyle: self.connect(self.form.fontSize, SIGNAL("valueChanged(int)"),
# w.setStyle(self.plastiqueStyle) self.saveField)
# self.connect(w, self.connect(self.form.fontSizeEdit, SIGNAL("valueChanged(int)"),
# SIGNAL("clicked()"), self.saveField)
# lambda w=w: self.chooseColour(w)) self.connect(self.form.fieldName, SIGNAL("textEdited(QString)"),
# elif type == "edit": self.saveField)
# self.connect(self.form.rtl, w = self.form.fontColour
# SIGNAL("stateChanged(int)"), if self.plastiqueStyle:
# self.saveField) w.setStyle(self.plastiqueStyle)
# self.currentField = None self.connect(w, SIGNAL("clicked()"),
# self.drawFields() lambda w=w: self.chooseColour(w))
self.connect(self.form.rtl,
SIGNAL("stateChanged(int)"),
self.saveField)
# def drawFields(self): def fieldChanged(self, idx):
# self.form.fieldList.clear() if self.updatingFields:
# n = 1 return
# self.ignoreUpdate = True self.field = self.model.fieldModels[idx]
# for field in self.model.fieldModels: self.readField()
# item = QListWidgetItem( self.enableFieldMoveButtons()
# _("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): def readField(self):
# "Return a field widget." field = self.field
# if type == "edit": self.form.fieldName.setText(field.name)
# return getattr(self.form, name+"Edit") self.form.fieldUnique.setChecked(field.unique)
# else: self.form.fieldRequired.setChecked(field.required)
# return getattr(self.form, name) self.form.numeric.setChecked(field.numeric)
if field.quizFontFamily:
self.form.fontFamily.setCurrentFont(QFont(
field.quizFontFamily))
self.form.fontSize.setValue(field.quizFontSize or 20)
self.form.fontSizeEdit.setValue(field.editFontSize or 20)
self.form.fontColour.setPalette(QPalette(QColor(
field.quizFontColour or "#000000")))
self.form.rtl.setChecked(not not field.features)
# def fieldChanged(self, idx): def saveField(self, *args):
# self.saveField() self.needFieldRebuild = True
# self.currentField = None if self.updatingFields:
# field = self.model.fieldModels[idx] return
# for type in ("quiz", "edit"): field = self.field
# # family name = unicode(self.form.fieldName.text()) or _("Field")
# if getattr(field, type + 'FontFamily'): if field.name != name:
# self.fwidget("useFamily", type).setCheckState(Qt.Checked) self.deck.renameFieldModel(self.model, field, name)
# self.fwidget("fontFamily", type).setCurrentFont(QFont( # the card models will have been updated
# getattr(field, type + 'FontFamily'))) self.readCard()
# self.fwidget("fontFamily", type).setEnabled(True) field.unique = self.form.fieldUnique.isChecked()
# else: field.required = self.form.fieldRequired.isChecked()
# self.fwidget("useFamily", type).setCheckState(Qt.Unchecked) field.numeric = self.form.numeric.isChecked()
# self.fwidget("fontFamily", type).setEnabled(False) field.quizFontFamily = toCanonicalFont(unicode(
# # size self.form.fontFamily.currentFont().family()))
# if getattr(field, type + 'FontSize'): field.quizFontSize = int(self.form.fontSize.value())
# self.fwidget("useSize", type).setCheckState(Qt.Checked) field.editFontSize = int(self.form.fontSizeEdit.value())
# self.fwidget("fontSize", type).setValue( field.quizFontColour = str(
# getattr(field, type + 'FontSize')) self.form.fontColour.palette().window().color().name())
# self.fwidget("fontSize", type).setEnabled(True) if self.form.rtl.isChecked():
# else: field.features = u"rtl"
# self.fwidget("useSize", type).setCheckState(Qt.Unchecked) else:
# self.fwidget("fontSize", type).setEnabled(False) field.features = u""
# if type == "quiz": field.model.setModified()
# # colour self.deck.flushMod()
# if getattr(field, type + 'FontColour'): self.renderPreview()
# self.fwidget("useColour", type).setCheckState(Qt.Checked) self.fillFieldList()
# 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): def fillFieldList(self, row = None):
# if self.ignoreUpdate: oldRow = self.form.fieldList.currentRow()
# return if oldRow == -1:
# field = self.currentField oldRow = 0
# if not field: self.form.fieldList.clear()
# return n = 1
# for type in ("quiz", "edit"): for field in self.model.fieldModels:
# # family label = field.name
# if self.fwidget("useFamily", type).isChecked(): item = QListWidgetItem(label)
# setattr(field, type + 'FontFamily', toCanonicalFont(unicode( self.form.fieldList.addItem(item)
# self.fwidget("fontFamily", type).currentFont().family()))) n += 1
# else: count = self.form.fieldList.count()
# setattr(field, type + 'FontFamily', None) if row != None:
# # size self.form.fieldList.setCurrentRow(row)
# if self.fwidget("useSize", type).isChecked(): else:
# setattr(field, type + 'FontSize', while (count > 0 and oldRow > (count - 1)):
# int(self.fwidget("fontSize", type).value())) oldRow -= 1
# else: self.form.fieldList.setCurrentRow(oldRow)
# setattr(field, type + 'FontSize', None) self.enableFieldMoveButtons()
# # 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): def enableFieldMoveButtons(self):
# self.fieldOrdinalUpdatedIds = [] row = self.form.fieldList.currentRow()
# self.ignoreFieldUpdate = False if row < 1:
# self.currentField = None self.form.fieldUp.setEnabled(False)
# self.updateFields() else:
# self.readCurrentField() self.form.fieldUp.setEnabled(True)
# self.connect(self.form.fieldList, SIGNAL("currentRowChanged(int)"), if row == -1 or row >= (self.form.fieldList.count() - 1):
# self.fieldRowChanged) self.form.fieldDown.setEnabled(False)
# self.connect(self.form.tabWidget, SIGNAL("currentChanged(int)"), else:
# self.fieldRowChanged) self.form.fieldDown.setEnabled(True)
# self.connect(self.form.fieldAdd, SIGNAL("clicked()"),
# self.addField)
# self.connect(self.form.fieldDelete, SIGNAL("clicked()"),
# self.deleteField)
# self.connect(self.form.fieldUp, SIGNAL("clicked()"),
# self.moveFieldUp)
# self.connect(self.form.fieldDown, SIGNAL("clicked()"),
# self.moveFieldDown)
# self.connect(self.form.fieldName, SIGNAL("lostFocus()"),
# self.updateFields)
# def updateFields(self, row = None): def addField(self):
# oldRow = self.form.fieldList.currentRow() f = FieldModel(required=False, unique=False)
# if oldRow == -1: f.name = _("Field %d") % (len(self.model.fieldModels) + 1)
# oldRow = 0 self.deck.addFieldModel(self.model, f)
# self.form.fieldList.clear() self.fillFieldList()
# n = 1 self.form.fieldList.setCurrentRow(len(self.model.fieldModels)-1)
# for field in self.model.fieldModels: self.form.fieldName.setFocus()
# label = _("Field %(num)d: %(name)s [%(cards)s non-empty]") % { self.form.fieldName.selectAll()
# 'num': n,
# 'name': field.name,
# 'cards': self.deck.fieldModelUseCount(field)
# }
# item = QListWidgetItem(label)
# self.form.fieldList.addItem(item)
# n += 1
# count = self.form.fieldList.count()
# if row != None:
# self.form.fieldList.setCurrentRow(row)
# else:
# while (count > 0 and oldRow > (count - 1)):
# oldRow -= 1
# self.form.fieldList.setCurrentRow(oldRow)
# self.enableFieldMoveButtons()
# def fieldRowChanged(self): def deleteField(self):
# if self.ignoreFieldUpdate: row = self.form.fieldList.currentRow()
# return if row == -1:
# self.saveCurrentField() return
# self.readCurrentField() if len(self.model.fieldModels) < 2:
ui.utils.showInfo(
_("Please add a new field first."),
parent=self)
return
field = self.model.fieldModels[row]
count = self.deck.fieldModelUseCount(field)
if count:
if not ui.utils.askUser(
_("This field is used by %d cards. If you delete it,\n"
"all information in this field will be lost.\n"
"\nReally delete this field?") % count,
parent=self):
return
self.deck.deleteFieldModel(self.model, field)
self.fillFieldList()
# need to update q/a format
self.readCard()
# def readCurrentField(self): def moveFieldUp(self):
# if not len(self.model.fieldModels): row = self.form.fieldList.currentRow()
# self.form.fieldEditBox.hide() if row == -1:
# self.form.fieldUp.setEnabled(False) return
# self.form.fieldDown.setEnabled(False) if row == 0:
# return return
# else: field = self.model.fieldModels[row]
# self.form.fieldEditBox.show() tField = self.model.fieldModels[row - 1]
# self.currentField = self.model.fieldModels[self.form.fieldList.currentRow()] self.model.fieldModels.remove(field)
# field = self.currentField self.model.fieldModels.insert(row - 1, field)
# self.form.fieldName.setText(field.name) if field.id not in self.fieldOrdinalUpdatedIds:
# self.form.fieldUnique.setChecked(field.unique) self.fieldOrdinalUpdatedIds.append(field.id)
# self.form.fieldRequired.setChecked(field.required) if tField.id not in self.fieldOrdinalUpdatedIds:
# self.form.numeric.setChecked(field.numeric) self.fieldOrdinalUpdatedIds.append(tField.id)
self.fillFieldList(row - 1)
# def enableFieldMoveButtons(self):
# row = self.form.fieldList.currentRow()
# if row < 1:
# self.form.fieldUp.setEnabled(False)
# else:
# self.form.fieldUp.setEnabled(True)
# if row == -1 or row >= (self.form.fieldList.count() - 1):
# self.form.fieldDown.setEnabled(False)
# else:
# self.form.fieldDown.setEnabled(True)
# def saveCurrentField(self):
# if not self.currentField:
# return
# field = self.currentField
# name = unicode(self.form.fieldName.text()).strip()
# # renames
# if not name:
# name = _("Field %d") % (self.model.fieldModels.index(field) + 1)
# if name != field.name:
# self.deck.renameFieldModel(self.m, field, name)
# # the card models will have been updated
# self.readCurrentCard()
# # unique, required, numeric
# self.updateField(field, 'unique',
# self.form.fieldUnique.checkState() == Qt.Checked)
# self.updateField(field, 'required',
# self.form.fieldRequired.checkState() == Qt.Checked)
# self.updateField(field, 'numeric',
# self.form.numeric.checkState() == Qt.Checked)
# self.ignoreFieldUpdate = True
# self.updateFields()
# self.ignoreFieldUpdate = False
# def addField(self):
# f = FieldModel(required=False, unique=False)
# f.name = _("Field %d") % (len(self.model.fieldModels) + 1)
# self.deck.addFieldModel(self.m, f)
# self.updateFields()
# self.form.fieldList.setCurrentRow(len(self.model.fieldModels)-1)
# self.form.fieldName.setFocus()
# self.form.fieldName.selectAll()
# def deleteField(self):
# row = self.form.fieldList.currentRow()
# if row == -1:
# return
# if len(self.model.fieldModels) < 2:
# ui.utils.showInfo(
# _("Please add a new field first."),
# parent=self)
# return
# field = self.model.fieldModels[row]
# count = self.deck.fieldModelUseCount(field)
# if count:
# if not ui.utils.askUser(
# _("This field is used by %d cards. If you delete it,\n"
# "all information in this field will be lost.\n"
# "\nReally delete this field?") % count,
# parent=self):
# return
# self.deck.deleteFieldModel(self.m, field)
# self.currentField = None
# self.updateFields()
# # need to update q/a format
# self.readCurrentCard()
# def moveFieldUp(self):
# row = self.form.fieldList.currentRow()
# if row == -1:
# return
# if row == 0:
# return
# field = self.model.fieldModels[row]
# tField = self.model.fieldModels[row - 1]
# self.model.fieldModels.remove(field)
# self.model.fieldModels.insert(row - 1, field)
# if field.id not in self.fieldOrdinalUpdatedIds:
# self.fieldOrdinalUpdatedIds.append(field.id)
# if tField.id not in self.fieldOrdinalUpdatedIds:
# self.fieldOrdinalUpdatedIds.append(tField.id)
# self.ignoreFieldUpdate = True
# self.updateFields(row - 1)
# self.ignoreFieldUpdate = False
# def moveFieldDown(self):
# row = self.form.fieldList.currentRow()
# if row == -1:
# return
# if row == len(self.model.fieldModels) - 1:
# return
# field = self.model.fieldModels[row]
# tField = self.model.fieldModels[row + 1]
# self.model.fieldModels.remove(field)
# self.model.fieldModels.insert(row + 1, field)
# if field.id not in self.fieldOrdinalUpdatedIds:
# self.fieldOrdinalUpdatedIds.append(field.id)
# if tField.id not in self.fieldOrdinalUpdatedIds:
# self.fieldOrdinalUpdatedIds.append(tField.id)
# self.ignoreFieldUpdate = True
# self.updateFields(row + 1)
# self.ignoreFieldUpdate = False
# rebuild ordinals if changed
# if len(self.fieldOrdinalUpdatedIds) > 0:
# self.deck.rebuildFieldOrdinals(self.model.id, self.fieldOrdinalUpdatedIds)
# self.model.setModified()
# self.deck.setModified()
# class PreviewDialog(QDialog):
# cards = self.deck.previewFact(self.fact)
# if not cards:
# ui.utils.showInfo(_("No cards to preview."),
# parent=parent)
# return
def moveFieldDown(self):
row = self.form.fieldList.currentRow()
if row == -1:
return
if row == len(self.model.fieldModels) - 1:
return
field = self.model.fieldModels[row]
tField = self.model.fieldModels[row + 1]
self.model.fieldModels.remove(field)
self.model.fieldModels.insert(row + 1, field)
if field.id not in self.fieldOrdinalUpdatedIds:
self.fieldOrdinalUpdatedIds.append(field.id)
if tField.id not in self.fieldOrdinalUpdatedIds:
self.fieldOrdinalUpdatedIds.append(tField.id)
self.fillFieldList(row + 1)

View file

@ -58,14 +58,15 @@ class FactEditor(object):
removeHook("guiReset", self.refresh) removeHook("guiReset", self.refresh)
removeHook("colourChanged", self.colourChanged) removeHook("colourChanged", self.colourChanged)
def setFact(self, fact, noFocus=False, check=False, scroll=False): def setFact(self, fact, noFocus=False, check=False, scroll=False,
forceRedraw=False):
"Make FACT the current fact." "Make FACT the current fact."
self.fact = fact self.fact = fact
self.factState = None self.factState = None
if self.changeTimer: if self.changeTimer:
self.changeTimer.stop() self.changeTimer.stop()
self.changeTimer = None self.changeTimer = None
if self.needToRedraw(): if self.needToRedraw() or forceRedraw:
if self.fact: if self.fact:
self.drawFields(noFocus, check) self.drawFields(noFocus, check)
else: else:
@ -91,7 +92,7 @@ class FactEditor(object):
except InvalidRequestError: except InvalidRequestError:
# not attached to session yet, add cards dialog will handle # not attached to session yet, add cards dialog will handle
return return
self.setFact(self.fact, check=True) self.setFact(self.fact, check=True, forceRedraw=True)
def focusFirst(self): def focusFirst(self):
if self.focusTarget: if self.focusTarget:

View file

@ -33,7 +33,7 @@
</attribute> </attribute>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
<layout class="QGridLayout" name="_6"> <layout class="QGridLayout" name="templateLayout">
<property name="margin"> <property name="margin">
<number>0</number> <number>0</number>
</property> </property>