mirror of
https://github.com/ankitects/anki.git
synced 2025-12-13 23:00:58 -05:00
update fields on focus change
This commit is contained in:
parent
96e88468b7
commit
a61d8d916a
9 changed files with 84 additions and 150 deletions
|
|
@ -34,8 +34,6 @@ class AddCards(QDialog):
|
|||
self.editor = ui.facteditor.FactEditor(self,
|
||||
self.dialog.fieldsArea,
|
||||
self.parent.deck)
|
||||
self.editor.onFactValid = self.onValid
|
||||
self.editor.onFactInvalid = self.onInvalid
|
||||
|
||||
def addChooser(self):
|
||||
self.modelChooser = ui.modelchooser.ModelChooser(self,
|
||||
|
|
@ -48,7 +46,7 @@ class AddCards(QDialog):
|
|||
QDesktopServices.openUrl(QUrl(ankiqt.appWiki + "AddFacts"))
|
||||
|
||||
def addButtons(self):
|
||||
self.addButton = QPushButton(_("&Add cards"))
|
||||
self.addButton = QPushButton(_("&Add"))
|
||||
self.dialog.buttonBox.addButton(self.addButton,
|
||||
QDialogButtonBox.ActionRole)
|
||||
self.addButton.setShortcut(_("Ctrl+Return"))
|
||||
|
|
@ -81,15 +79,20 @@ class AddCards(QDialog):
|
|||
# set the new fact
|
||||
self.editor.setFact(fact, check=True)
|
||||
|
||||
def onValid(self, fact):
|
||||
self.addButton.setEnabled(True)
|
||||
|
||||
def onInvalid(self, fact):
|
||||
self.addButton.setEnabled(False)
|
||||
|
||||
def addCards(self):
|
||||
# make sure updated
|
||||
w = self.editor.focusedEdit()
|
||||
self.addButton.setFocus()
|
||||
fact = self.editor.fact
|
||||
cards = self.parent.deck.addFact(fact)
|
||||
try:
|
||||
cards = self.parent.deck.addFact(fact)
|
||||
except FactInvalidError:
|
||||
ui.utils.showInfo(_(
|
||||
"Some fields are missing or not unique."),
|
||||
parent=self, help="AddItems#AddError")
|
||||
if w:
|
||||
w.setFocus()
|
||||
return
|
||||
if not cards:
|
||||
ui.utils.showWarning(_("""\
|
||||
The input you have provided would make an empty
|
||||
|
|
|
|||
|
|
@ -361,7 +361,7 @@ class EditDeck(QDialog):
|
|||
self.updateSearch()
|
||||
|
||||
def updateFilterLabel(self):
|
||||
self.setWindowTitle(_("Anki - Edit Deck (%(cur)d "
|
||||
self.setWindowTitle(_("Anki - Edit Items (%(cur)d "
|
||||
"of %(tot)d cards shown)") %
|
||||
{"cur": len(self.model.cards),
|
||||
"tot": self.deck.cardCount()})
|
||||
|
|
@ -501,11 +501,15 @@ where id in (%s)""" % ",".join([
|
|||
self.dialog.tableView.setEnabled(True)
|
||||
self.dialog.searchGroup.setEnabled(True)
|
||||
self.dialog.sortGroup.setEnabled(True)
|
||||
self.dialog.actionGroup.setEnabled(True)
|
||||
self.dialog.cardInfoGroup.setEnabled(True)
|
||||
|
||||
def onFactInvalid(self, fact):
|
||||
self.dialog.tableView.setEnabled(False)
|
||||
self.dialog.searchGroup.setEnabled(False)
|
||||
self.dialog.sortGroup.setEnabled(False)
|
||||
self.dialog.actionGroup.setEnabled(False)
|
||||
self.dialog.cardInfoGroup.setEnabled(False)
|
||||
|
||||
def rowChanged(self, current, previous):
|
||||
self.currentRow = current
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ class FactEditor(object):
|
|||
self.fact = None
|
||||
self.fontChanged = False
|
||||
self.setupFields()
|
||||
self.checkTimer = None
|
||||
self.onChange = None
|
||||
self.onFactValid = None
|
||||
self.onFactInvalid = None
|
||||
|
|
@ -169,7 +168,6 @@ class FactEditor(object):
|
|||
|
||||
self.fieldsFrame = None
|
||||
self.widget.setLayout(self.fieldsBox)
|
||||
self.updatingFields = False
|
||||
|
||||
def _makeGrid(self):
|
||||
"Rebuild the grid to avoid trigging QT bugs."
|
||||
|
|
@ -202,25 +200,19 @@ class FactEditor(object):
|
|||
self.fieldsGrid.addWidget(w, n, 1)
|
||||
self.fields[field.name] = (field, w)
|
||||
# catch changes
|
||||
w.connect(w, SIGNAL("textChanged()"),
|
||||
lambda f=field, w=w: self.fieldChanged(f, w))
|
||||
w.connect(w, SIGNAL("lostFocus"),
|
||||
lambda f=field, w=w: self.lostFocus(f, w))
|
||||
w.connect(w, SIGNAL("currentCharFormatChanged(QTextCharFormat)"),
|
||||
lambda w=w: self.formatChanged(w))
|
||||
n += 1
|
||||
# tags
|
||||
self.fieldsGrid.addWidget(QLabel(_("Tags")), n, 0)
|
||||
self.tags = ui.tagedit.TagEdit(self.parent)
|
||||
self.tags.connect(self.tags, SIGNAL("textChanged(QString)"),
|
||||
self.tags.connect(self.tags, SIGNAL("lostFocus"),
|
||||
self.onTagChange)
|
||||
# update available tags
|
||||
self.tags.setDeck(self.deck)
|
||||
self.fieldsGrid.addWidget(self.tags, n, 1)
|
||||
# status warning
|
||||
n += 1
|
||||
self.warning = QLabel()
|
||||
self.warning.setFixedHeight(20)
|
||||
self.warning.setOpenExternalLinks(True)
|
||||
self.fieldsGrid.addWidget(self.warning, n, 1)
|
||||
# update fields
|
||||
self.updateFields(check)
|
||||
self.parent.setUpdatesEnabled(True)
|
||||
|
|
@ -236,7 +228,6 @@ class FactEditor(object):
|
|||
|
||||
def updateFields(self, check=True, font=True):
|
||||
"Update field text (if changed) and font/colours."
|
||||
self.updatingFields = True
|
||||
# text
|
||||
for (name, (field, w)) in self.fields.items():
|
||||
new = self.fact[name]
|
||||
|
|
@ -261,13 +252,10 @@ class FactEditor(object):
|
|||
self.tags.blockSignals(True)
|
||||
self.tags.setText(self.fact.tags)
|
||||
self.tags.blockSignals(False)
|
||||
self.updatingFields = False
|
||||
if check:
|
||||
self.checkValid()
|
||||
|
||||
def fieldChanged(self, field, widget):
|
||||
if self.updatingFields:
|
||||
return
|
||||
def lostFocus(self, field, widget):
|
||||
value = tidyHTML(unicode(widget.toHtml()))
|
||||
if value and not value.strip():
|
||||
widget.setText("")
|
||||
|
|
@ -278,24 +266,11 @@ class FactEditor(object):
|
|||
self.fact.onKeyPress(field, value)
|
||||
# the keypress handler may have changed something, so update all
|
||||
self.updateFields(font=False)
|
||||
self.checkValid()
|
||||
if self.onChange:
|
||||
self.onChange(field)
|
||||
self.scheduleCheck()
|
||||
self.formatChanged(None)
|
||||
|
||||
def scheduleCheck(self):
|
||||
if not self.deck:
|
||||
return
|
||||
interval = 200
|
||||
if self.checkTimer:
|
||||
self.checkTimer.setInterval(interval)
|
||||
else:
|
||||
self.checkTimer = QTimer(self.parent)
|
||||
self.checkTimer.setSingleShot(True)
|
||||
self.checkTimer.start(interval)
|
||||
self.parent.connect(self.checkTimer, SIGNAL("timeout()"),
|
||||
self.checkValid)
|
||||
|
||||
def checkValid(self):
|
||||
empty = []
|
||||
dupe = []
|
||||
|
|
@ -313,7 +288,6 @@ class FactEditor(object):
|
|||
else:
|
||||
p.setColor(QPalette.Base, QColor("#ffffff"))
|
||||
self.fields[field.name][1].setPalette(p)
|
||||
self.checkTimer = None
|
||||
# call relevant hooks
|
||||
invalid = len(empty+dupe)
|
||||
if self.factState != "valid" and not invalid:
|
||||
|
|
@ -324,20 +298,9 @@ class FactEditor(object):
|
|||
if self.onFactInvalid:
|
||||
self.onFactInvalid(self.fact)
|
||||
self.factState = "invalid"
|
||||
if invalid:
|
||||
self.warning.setText(_(
|
||||
"Some fields are "
|
||||
"<a href=http://ichi2.net/anki/wiki/Key_Terms_and_Concepts"
|
||||
"#head-6ba367d55922a618ab147debfbac98635d1a4dc2>missing</a>"
|
||||
" or not "
|
||||
"<a href=http://ichi2.net/anki/wiki/Key_Terms_and_Concepts"
|
||||
"#head-0c33560cb828fde1c19af1cd260388457b57812a>unique</a>."))
|
||||
else:
|
||||
self.warning.setText(_("All fields valid"))
|
||||
|
||||
def onTagChange(self, text):
|
||||
if not self.updatingFields:
|
||||
self.fact.tags = unicode(text)
|
||||
def onTagChange(self):
|
||||
self.fact.tags = unicode(self.tags.text())
|
||||
if self.onChange:
|
||||
self.onChange(None)
|
||||
self.fact.setModified(textChanged=True)
|
||||
|
|
@ -503,11 +466,15 @@ class FactEdit(QTextEdit):
|
|||
html = re.sub("\s\s+", " ", html).strip()
|
||||
return html
|
||||
|
||||
def leaveEvent(self, evt):
|
||||
QTextEdit.leaveEvent(self, evt)
|
||||
|
||||
def focusOutEvent(self, evt):
|
||||
QTextEdit.focusOutEvent(self, evt)
|
||||
self.parent.lastFocusedEdit = self
|
||||
self.parent.resetFormatButtons()
|
||||
self.parent.disableButtons()
|
||||
self.emit(SIGNAL("lostFocus"))
|
||||
|
||||
# this shouldn't be necessary if/when we move away from kakasi
|
||||
def mouseDoubleClickEvent(self, evt):
|
||||
|
|
|
|||
|
|
@ -166,7 +166,8 @@ class ModelProperties(QDialog):
|
|||
return
|
||||
if len(self.m.fieldModels) < 2:
|
||||
ui.utils.showInfo(
|
||||
_("Please add a new field first."))
|
||||
_("Please add a new field first."),
|
||||
parent=self)
|
||||
return
|
||||
field = self.m.fieldModels[row]
|
||||
count = self.deck.fieldModelUseCount(field)
|
||||
|
|
|
|||
|
|
@ -34,6 +34,10 @@ class TagEdit(QLineEdit):
|
|||
else:
|
||||
QLineEdit.keyPressEvent(self, evt)
|
||||
|
||||
def focusOutEvent(self, evt):
|
||||
QLineEdit.focusOutEvent(self, evt)
|
||||
self.emit(SIGNAL("lostFocus"))
|
||||
|
||||
class TagCompleter(QCompleter):
|
||||
|
||||
def __init__(self, *args):
|
||||
|
|
|
|||
|
|
@ -7,17 +7,31 @@ from PyQt4.QtCore import *
|
|||
import re, os
|
||||
import ankiqt
|
||||
|
||||
def openLink(link):
|
||||
QDesktopServices.openUrl(QUrl(link))
|
||||
|
||||
def openWikiLink(page):
|
||||
openLink(ankiqt.appWiki + page)
|
||||
|
||||
def showWarning(text, parent=None):
|
||||
"Show a small warning with an OK button."
|
||||
if not parent:
|
||||
parent = ankiqt.mw
|
||||
QMessageBox.warning(parent, "Anki", text)
|
||||
|
||||
def showInfo(text, parent=None):
|
||||
def showInfo(text, parent=None, help=""):
|
||||
"Show a small info window with an OK button."
|
||||
if not parent:
|
||||
parent = ankiqt.mw
|
||||
QMessageBox.information(parent, "Anki", text)
|
||||
sb = QMessageBox.Ok
|
||||
if help:
|
||||
sb |= QMessageBox.Help
|
||||
while 1:
|
||||
ret = QMessageBox.information(parent, "Anki", text, sb)
|
||||
if ret == QMessageBox.Help:
|
||||
openWikiLink(help)
|
||||
else:
|
||||
break
|
||||
|
||||
def askUser(text, parent=None):
|
||||
"Show a yes/no question. Return true if yes."
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<string>Anki - Add Cards</string>
|
||||
<string>Anki - Add Items</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="spacing" >
|
||||
|
|
|
|||
|
|
@ -13,25 +13,17 @@
|
|||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<string>Anki - Edit Deck</string>
|
||||
<string>Anki - Edit Items</string>
|
||||
</property>
|
||||
<property name="windowIcon" >
|
||||
<iconset resource="../icons.qrc" >:/icons/view_text.png</iconset>
|
||||
<iconset resource="../icons.qrc" >
|
||||
<normaloff>:/icons/view_text.png</normaloff>:/icons/view_text.png</iconset>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="spacing" >
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="leftMargin" >
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="topMargin" >
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="rightMargin" >
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="bottomMargin" >
|
||||
<property name="margin" >
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item>
|
||||
|
|
@ -39,16 +31,7 @@
|
|||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
|
|
@ -72,16 +55,7 @@
|
|||
<property name="spacing" >
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="leftMargin" >
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="topMargin" >
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="rightMargin" >
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="bottomMargin" >
|
||||
<property name="margin" >
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item>
|
||||
|
|
@ -113,16 +87,7 @@
|
|||
<property name="spacing" >
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="leftMargin" >
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="topMargin" >
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="rightMargin" >
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="bottomMargin" >
|
||||
<property name="margin" >
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item>
|
||||
|
|
@ -132,7 +97,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox" >
|
||||
<widget class="QGroupBox" name="actionGroup" >
|
||||
<property name="title" >
|
||||
<string>Actions on selected..</string>
|
||||
</property>
|
||||
|
|
@ -140,16 +105,7 @@
|
|||
<property name="spacing" >
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="leftMargin" >
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="topMargin" >
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="rightMargin" >
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="bottomMargin" >
|
||||
<property name="margin" >
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item>
|
||||
|
|
@ -158,7 +114,8 @@
|
|||
<string>Facts..</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="../icons.qrc" >:/icons/Anki_Fact.png</iconset>
|
||||
<iconset resource="../icons.qrc" >
|
||||
<normaloff>:/icons/Anki_Fact.png</normaloff>:/icons/Anki_Fact.png</iconset>
|
||||
</property>
|
||||
<property name="autoDefault" >
|
||||
<bool>false</bool>
|
||||
|
|
@ -171,7 +128,8 @@
|
|||
<string>Cards..</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="../icons.qrc" >:/icons/Anki_Card.png</iconset>
|
||||
<iconset resource="../icons.qrc" >
|
||||
<normaloff>:/icons/Anki_Card.png</normaloff>:/icons/Anki_Card.png</iconset>
|
||||
</property>
|
||||
<property name="autoDefault" >
|
||||
<bool>false</bool>
|
||||
|
|
@ -237,36 +195,15 @@
|
|||
<property name="spacing" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QGridLayout" >
|
||||
<property name="leftMargin" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="horizontalSpacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="verticalSpacing" >
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="1" >
|
||||
|
|
@ -310,7 +247,8 @@
|
|||
</layout>
|
||||
<action name="action_Delete_card" >
|
||||
<property name="icon" >
|
||||
<iconset resource="../icons.qrc" >:/icons/editdelete.png</iconset>
|
||||
<iconset resource="../icons.qrc" >
|
||||
<normaloff>:/icons/editdelete.png</normaloff>:/icons/editdelete.png</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Toggle Delete</string>
|
||||
|
|
@ -318,7 +256,8 @@
|
|||
</action>
|
||||
<action name="actionAdd_fact_tag" >
|
||||
<property name="icon" >
|
||||
<iconset resource="../icons.qrc" >:/icons/Anki_Add_Tag.png</iconset>
|
||||
<iconset resource="../icons.qrc" >
|
||||
<normaloff>:/icons/Anki_Add_Tag.png</normaloff>:/icons/Anki_Add_Tag.png</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Add Tag..</string>
|
||||
|
|
@ -326,7 +265,8 @@
|
|||
</action>
|
||||
<action name="actionAdd_card_tag" >
|
||||
<property name="icon" >
|
||||
<iconset resource="../icons.qrc" >:/icons/Anki_Add_Tag.png</iconset>
|
||||
<iconset resource="../icons.qrc" >
|
||||
<normaloff>:/icons/Anki_Add_Tag.png</normaloff>:/icons/Anki_Add_Tag.png</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Add Tag..</string>
|
||||
|
|
@ -334,7 +274,8 @@
|
|||
</action>
|
||||
<action name="actionDelete_fact_tag" >
|
||||
<property name="icon" >
|
||||
<iconset resource="../icons.qrc" >:/icons/Anki_Del_Tag.png</iconset>
|
||||
<iconset resource="../icons.qrc" >
|
||||
<normaloff>:/icons/Anki_Del_Tag.png</normaloff>:/icons/Anki_Del_Tag.png</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Delete Tag..</string>
|
||||
|
|
@ -342,7 +283,8 @@
|
|||
</action>
|
||||
<action name="actionDelete_card_tag" >
|
||||
<property name="icon" >
|
||||
<iconset resource="../icons.qrc" >:/icons/Anki_Del_Tag.png</iconset>
|
||||
<iconset resource="../icons.qrc" >
|
||||
<normaloff>:/icons/Anki_Del_Tag.png</normaloff>:/icons/Anki_Del_Tag.png</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Delete Tag..</string>
|
||||
|
|
@ -350,7 +292,8 @@
|
|||
</action>
|
||||
<action name="actionAdd_Missing_Cards" >
|
||||
<property name="icon" >
|
||||
<iconset resource="../icons.qrc" >:/icons/Anki_Card.png</iconset>
|
||||
<iconset resource="../icons.qrc" >
|
||||
<normaloff>:/icons/Anki_Card.png</normaloff>:/icons/Anki_Card.png</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Add Missing Active Cards</string>
|
||||
|
|
@ -358,7 +301,8 @@
|
|||
</action>
|
||||
<action name="actionDelete_Fact" >
|
||||
<property name="icon" >
|
||||
<iconset resource="../icons.qrc" >:/icons/editdelete.png</iconset>
|
||||
<iconset resource="../icons.qrc" >
|
||||
<normaloff>:/icons/editdelete.png</normaloff>:/icons/editdelete.png</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Toggle Delete</string>
|
||||
|
|
|
|||
|
|
@ -622,10 +622,7 @@
|
|||
<normaloff>:/icons/list-add.png</normaloff>:/icons/list-add.png</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>&Add Facts..</string>
|
||||
</property>
|
||||
<property name="toolTip" >
|
||||
<string>Add Cards</string>
|
||||
<string>&Add Items..</string>
|
||||
</property>
|
||||
<property name="shortcut" >
|
||||
<string>Ctrl+A</string>
|
||||
|
|
@ -637,7 +634,7 @@
|
|||
<normaloff>:/icons/view_text.png</normaloff>:/icons/view_text.png</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>&Edit Facts..</string>
|
||||
<string>&Edit Items..</string>
|
||||
</property>
|
||||
<property name="shortcut" >
|
||||
<string>Ctrl+E</string>
|
||||
|
|
|
|||
Loading…
Reference in a new issue