mirror of
https://github.com/ankitects/anki.git
synced 2025-09-20 06:52:21 -04:00
add undo/redo to editor, focus current card, del
This commit is contained in:
parent
30e106b4e6
commit
fd14b3f2dd
5 changed files with 94 additions and 20 deletions
|
@ -92,6 +92,8 @@ class AddCards(QDialog):
|
||||||
# make sure updated
|
# make sure updated
|
||||||
self.editor.saveFieldsNow()
|
self.editor.saveFieldsNow()
|
||||||
fact = self.editor.fact
|
fact = self.editor.fact
|
||||||
|
n = _("Add")
|
||||||
|
self.parent.deck.setUndoStart(n)
|
||||||
try:
|
try:
|
||||||
cards = self.parent.deck.addFact(fact)
|
cards = self.parent.deck.addFact(fact)
|
||||||
except FactInvalidError:
|
except FactInvalidError:
|
||||||
|
@ -109,6 +111,7 @@ question or answer on all cards. Can't proceed."""), parent=self)
|
||||||
# we're guaranteed that all fields will exist now
|
# we're guaranteed that all fields will exist now
|
||||||
"str": stripHTML(fact[fact.fields[0].name]),
|
"str": stripHTML(fact[fact.fields[0].name]),
|
||||||
})
|
})
|
||||||
|
self.parent.deck.setUndoEnd(n)
|
||||||
self.parent.updateTitleBar()
|
self.parent.updateTitleBar()
|
||||||
# start a new fact
|
# start a new fact
|
||||||
f = self.parent.deck.newFact()
|
f = self.parent.deck.newFact()
|
||||||
|
|
|
@ -223,7 +223,7 @@ class EditDeck(QMainWindow):
|
||||||
self.updateFilterLabel()
|
self.updateFilterLabel()
|
||||||
restoreGeom(self, "editor")
|
restoreGeom(self, "editor")
|
||||||
self.show()
|
self.show()
|
||||||
self.selectLastCard()
|
self.updateSearch()
|
||||||
|
|
||||||
def findCardInDeckModel(self, model, card):
|
def findCardInDeckModel(self, model, card):
|
||||||
for i, thisCard in enumerate(model.cards):
|
for i, thisCard in enumerate(model.cards):
|
||||||
|
@ -231,18 +231,6 @@ class EditDeck(QMainWindow):
|
||||||
return i
|
return i
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
def selectLastCard(self):
|
|
||||||
"Show the row corresponding to the current card."
|
|
||||||
self.updateSearch()
|
|
||||||
if self.parent.currentCard:
|
|
||||||
currentCardIndex = self.findCardInDeckModel(
|
|
||||||
self.model, self.parent.currentCard)
|
|
||||||
if currentCardIndex >= 0:
|
|
||||||
self.dialog.tableView.selectRow(currentCardIndex)
|
|
||||||
self.dialog.tableView.scrollTo(
|
|
||||||
self.model.index(currentCardIndex,0),
|
|
||||||
self.dialog.tableView.PositionAtTop)
|
|
||||||
|
|
||||||
def setupFilter(self):
|
def setupFilter(self):
|
||||||
self.filterTimer = None
|
self.filterTimer = None
|
||||||
self.currentTag = None
|
self.currentTag = None
|
||||||
|
@ -318,6 +306,8 @@ class EditDeck(QMainWindow):
|
||||||
if refresh:
|
if refresh:
|
||||||
self.model.showMatching()
|
self.model.showMatching()
|
||||||
self.updateFilterLabel()
|
self.updateFilterLabel()
|
||||||
|
self.onEvent()
|
||||||
|
self.focusCurrentCard()
|
||||||
|
|
||||||
def tagChanged(self, idx):
|
def tagChanged(self, idx):
|
||||||
if idx == 0:
|
if idx == 0:
|
||||||
|
@ -339,6 +329,20 @@ class EditDeck(QMainWindow):
|
||||||
{"cur": len(self.model.cards),
|
{"cur": len(self.model.cards),
|
||||||
"tot": self.deck.cardCount})
|
"tot": self.deck.cardCount})
|
||||||
|
|
||||||
|
def onEvent(self):
|
||||||
|
if self.deck.undoAvailable():
|
||||||
|
self.dialog.actionUndo.setText(_("Undo %s") %
|
||||||
|
self.deck.undoName())
|
||||||
|
self.dialog.actionUndo.setEnabled(True)
|
||||||
|
else:
|
||||||
|
self.dialog.actionUndo.setEnabled(False)
|
||||||
|
if self.deck.redoAvailable():
|
||||||
|
self.dialog.actionRedo.setText(_("Redo %s") %
|
||||||
|
self.deck.redoName())
|
||||||
|
self.dialog.actionRedo.setEnabled(True)
|
||||||
|
else:
|
||||||
|
self.dialog.actionRedo.setEnabled(False)
|
||||||
|
|
||||||
def filterTextChanged(self):
|
def filterTextChanged(self):
|
||||||
interval = 500
|
interval = 500
|
||||||
if self.filterTimer:
|
if self.filterTimer:
|
||||||
|
@ -359,6 +363,7 @@ class EditDeck(QMainWindow):
|
||||||
self.model.tag = self.currentTag
|
self.model.tag = self.currentTag
|
||||||
self.model.showMatching()
|
self.model.showMatching()
|
||||||
self.updateFilterLabel()
|
self.updateFilterLabel()
|
||||||
|
self.onEvent()
|
||||||
self.filterTimer = None
|
self.filterTimer = None
|
||||||
if self.model.cards:
|
if self.model.cards:
|
||||||
self.dialog.cardInfoGroup.show()
|
self.dialog.cardInfoGroup.show()
|
||||||
|
@ -369,6 +374,17 @@ class EditDeck(QMainWindow):
|
||||||
else:
|
else:
|
||||||
self.dialog.cardInfoGroup.hide()
|
self.dialog.cardInfoGroup.hide()
|
||||||
self.dialog.fieldsArea.hide()
|
self.dialog.fieldsArea.hide()
|
||||||
|
self.focusCurrentCard()
|
||||||
|
|
||||||
|
def focusCurrentCard(self):
|
||||||
|
if self.parent.currentCard:
|
||||||
|
currentCardIndex = self.findCardInDeckModel(
|
||||||
|
self.model, self.parent.currentCard)
|
||||||
|
if currentCardIndex >= 0:
|
||||||
|
self.dialog.tableView.selectRow(currentCardIndex)
|
||||||
|
self.dialog.tableView.scrollTo(
|
||||||
|
self.model.index(currentCardIndex,0),
|
||||||
|
self.dialog.tableView.PositionAtTop)
|
||||||
|
|
||||||
def setupHeaders(self):
|
def setupHeaders(self):
|
||||||
if not sys.platform.startswith("win32"):
|
if not sys.platform.startswith("win32"):
|
||||||
|
@ -385,6 +401,8 @@ class EditDeck(QMainWindow):
|
||||||
self.connect(self.dialog.actionAddCards, SIGNAL("triggered()"), self.addCards)
|
self.connect(self.dialog.actionAddCards, SIGNAL("triggered()"), self.addCards)
|
||||||
self.connect(self.dialog.actionResetProgress, SIGNAL("triggered()"), self.resetProgress)
|
self.connect(self.dialog.actionResetProgress, SIGNAL("triggered()"), self.resetProgress)
|
||||||
self.connect(self.dialog.actionSelectFacts, SIGNAL("triggered()"), self.selectFacts)
|
self.connect(self.dialog.actionSelectFacts, SIGNAL("triggered()"), self.selectFacts)
|
||||||
|
self.connect(self.dialog.actionUndo, SIGNAL("triggered()"), self.onUndo)
|
||||||
|
self.connect(self.dialog.actionRedo, SIGNAL("triggered()"), self.onRedo)
|
||||||
self.parent.runHook('editor.setupMenus', self)
|
self.parent.runHook('editor.setupMenus', self)
|
||||||
|
|
||||||
def onClose(self):
|
def onClose(self):
|
||||||
|
@ -422,6 +440,7 @@ class EditDeck(QMainWindow):
|
||||||
self.factValid = True
|
self.factValid = True
|
||||||
self.editor.onFactValid = self.onFactValid
|
self.editor.onFactValid = self.onFactValid
|
||||||
self.editor.onFactInvalid = self.onFactInvalid
|
self.editor.onFactInvalid = self.onFactInvalid
|
||||||
|
self.editor.onChange = self.onEvent
|
||||||
self.connect(self.dialog.tableView.selectionModel(),
|
self.connect(self.dialog.tableView.selectionModel(),
|
||||||
SIGNAL("currentRowChanged(QModelIndex, QModelIndex)"),
|
SIGNAL("currentRowChanged(QModelIndex, QModelIndex)"),
|
||||||
self.rowChanged)
|
self.rowChanged)
|
||||||
|
@ -453,6 +472,7 @@ class EditDeck(QMainWindow):
|
||||||
fact = self.currentCard.fact
|
fact = self.currentCard.fact
|
||||||
self.editor.setFact(fact, True)
|
self.editor.setFact(fact, True)
|
||||||
self.showCardInfo(self.currentCard)
|
self.showCardInfo(self.currentCard)
|
||||||
|
self.onEvent()
|
||||||
|
|
||||||
def setupCardInfo(self):
|
def setupCardInfo(self):
|
||||||
self.currentCard = None
|
self.currentCard = None
|
||||||
|
@ -501,16 +521,27 @@ where id in (%s)""" % ",".join([
|
||||||
|
|
||||||
def addTags(self):
|
def addTags(self):
|
||||||
tags = ui.utils.getOnlyText(_("Enter tag(s) to add:"), self)
|
tags = ui.utils.getOnlyText(_("Enter tag(s) to add:"), self)
|
||||||
if tags: self.deck.addTags(self.selectedFacts(), tags)
|
if tags:
|
||||||
|
n = _("Add Tags")
|
||||||
|
self.deck.setUndoStart(n)
|
||||||
|
self.deck.addTags(self.selectedFacts(), tags)
|
||||||
|
self.deck.setUndoEnd(n)
|
||||||
self.updateAfterCardChange()
|
self.updateAfterCardChange()
|
||||||
|
|
||||||
def deleteTags(self):
|
def deleteTags(self):
|
||||||
tags = ui.utils.getOnlyText(_("Enter tag(s) to delete:"), self)
|
tags = ui.utils.getOnlyText(_("Enter tag(s) to delete:"), self)
|
||||||
if tags: self.deck.deleteTags(self.selectedFacts(), tags)
|
if tags:
|
||||||
|
n = _("Delete Tags")
|
||||||
|
self.deck.setUndoStart(n)
|
||||||
|
self.deck.deleteTags(self.selectedFacts(), tags)
|
||||||
|
self.deck.setUndoEnd(n)
|
||||||
self.updateAfterCardChange()
|
self.updateAfterCardChange()
|
||||||
|
|
||||||
def resetProgress(self):
|
def resetProgress(self):
|
||||||
|
n = _("Reset Progress")
|
||||||
|
self.deck.setUndoStart(n)
|
||||||
self.deck.resetCards(self.selectedCards())
|
self.deck.resetCards(self.selectedCards())
|
||||||
|
self.deck.setUndoEnd(n)
|
||||||
self.updateAfterCardChange(reset=True)
|
self.updateAfterCardChange(reset=True)
|
||||||
|
|
||||||
def addCards(self):
|
def addCards(self):
|
||||||
|
@ -522,10 +553,13 @@ where id in (%s)""" % ",".join([
|
||||||
d = AddCardChooser(self, cms)
|
d = AddCardChooser(self, cms)
|
||||||
if not d.exec_():
|
if not d.exec_():
|
||||||
return
|
return
|
||||||
|
n = _("Add Cards")
|
||||||
|
self.deck.setUndoStart(n)
|
||||||
for id in sf:
|
for id in sf:
|
||||||
self.deck.addCards(self.deck.s.query(Fact).get(id),
|
self.deck.addCards(self.deck.s.query(Fact).get(id),
|
||||||
d.selectedCms)
|
d.selectedCms)
|
||||||
self.deck.flushMod()
|
self.deck.flushMod()
|
||||||
|
self.deck.setUndoEnd(n)
|
||||||
self.updateSearch()
|
self.updateSearch()
|
||||||
|
|
||||||
def selectFacts(self):
|
def selectFacts(self):
|
||||||
|
@ -536,6 +570,17 @@ where id in (%s)""" % ",".join([
|
||||||
sm.select(self.model.index(i, 0),
|
sm.select(self.model.index(i, 0),
|
||||||
QItemSelectionModel.Select | QItemSelectionModel.Rows)
|
QItemSelectionModel.Select | QItemSelectionModel.Rows)
|
||||||
|
|
||||||
|
# Undo/Redo
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
def onUndo(self):
|
||||||
|
self.deck.undo()
|
||||||
|
self.updateSearch()
|
||||||
|
|
||||||
|
def onRedo(self):
|
||||||
|
self.deck.redo()
|
||||||
|
self.updateSearch()
|
||||||
|
|
||||||
class AddCardChooser(QDialog):
|
class AddCardChooser(QDialog):
|
||||||
|
|
||||||
def __init__(self, parent, cms):
|
def __init__(self, parent, cms):
|
||||||
|
|
|
@ -47,6 +47,7 @@ class FactEditor(object):
|
||||||
# update focus to first field
|
# update focus to first field
|
||||||
self.fields[self.fact.fields[0].name][1].setFocus()
|
self.fields[self.fact.fields[0].name][1].setFocus()
|
||||||
self.fontChanged = False
|
self.fontChanged = False
|
||||||
|
self.deck.setUndoBarrier()
|
||||||
|
|
||||||
def initMedia(self):
|
def initMedia(self):
|
||||||
os.chdir(self.deck.mediaDir(create=True))
|
os.chdir(self.deck.mediaDir(create=True))
|
||||||
|
@ -297,6 +298,8 @@ class FactEditor(object):
|
||||||
def saveFields(self):
|
def saveFields(self):
|
||||||
"Save field text into fact."
|
"Save field text into fact."
|
||||||
modified = False
|
modified = False
|
||||||
|
n = _("Edit")
|
||||||
|
self.deck.setUndoStart(n, merge=True)
|
||||||
for (w, f) in self.widgets.items():
|
for (w, f) in self.widgets.items():
|
||||||
v = tidyHTML(unicode(w.toHtml())).strip()
|
v = tidyHTML(unicode(w.toHtml())).strip()
|
||||||
if self.fact[f.name] != v:
|
if self.fact[f.name] != v:
|
||||||
|
@ -305,6 +308,7 @@ class FactEditor(object):
|
||||||
if modified:
|
if modified:
|
||||||
self.fact.setModified(textChanged=True)
|
self.fact.setModified(textChanged=True)
|
||||||
self.deck.setModified()
|
self.deck.setModified()
|
||||||
|
self.deck.setUndoEnd(n)
|
||||||
|
|
||||||
def onFocusLost(self, widget):
|
def onFocusLost(self, widget):
|
||||||
self.saveFields()
|
self.saveFields()
|
||||||
|
|
|
@ -230,6 +230,7 @@ An error occurred. Please copy the following message into a bug report.\n\n""" +
|
||||||
elif state == "editCurrentFact":
|
elif state == "editCurrentFact":
|
||||||
if self.lastState == "editCurrentFact":
|
if self.lastState == "editCurrentFact":
|
||||||
return self.moveToState("saveEdit")
|
return self.moveToState("saveEdit")
|
||||||
|
self.deck.s.flush()
|
||||||
self.showEditor()
|
self.showEditor()
|
||||||
elif state == "saveEdit":
|
elif state == "saveEdit":
|
||||||
self.editor.saveFieldsNow()
|
self.editor.saveFieldsNow()
|
||||||
|
@ -1382,15 +1383,15 @@ To upgrade an old deck, download Anki 0.9.8.7."""))
|
||||||
self.mainWin.actionEditCurrent.setEnabled(True)
|
self.mainWin.actionEditCurrent.setEnabled(True)
|
||||||
|
|
||||||
def maybeEnableUndo(self):
|
def maybeEnableUndo(self):
|
||||||
if self.deck and self.deck.undoStack:
|
if self.deck and self.deck.undoAvailable():
|
||||||
self.mainWin.actionUndo.setText(_("Undo %s") %
|
self.mainWin.actionUndo.setText(_("Undo %s") %
|
||||||
self.deck.undoStack[-1][0])
|
self.deck.undoName())
|
||||||
self.mainWin.actionUndo.setEnabled(True)
|
self.mainWin.actionUndo.setEnabled(True)
|
||||||
else:
|
else:
|
||||||
self.mainWin.actionUndo.setEnabled(False)
|
self.mainWin.actionUndo.setEnabled(False)
|
||||||
if self.deck and self.deck.redoStack:
|
if self.deck and self.deck.redoAvailable():
|
||||||
self.mainWin.actionRedo.setText(_("Redo %s") %
|
self.mainWin.actionRedo.setText(_("Redo %s") %
|
||||||
self.deck.redoStack[-1][0])
|
self.deck.redoName())
|
||||||
self.mainWin.actionRedo.setEnabled(True)
|
self.mainWin.actionRedo.setEnabled(True)
|
||||||
else:
|
else:
|
||||||
self.mainWin.actionRedo.setEnabled(False)
|
self.mainWin.actionRedo.setEnabled(False)
|
||||||
|
|
|
@ -187,6 +187,9 @@
|
||||||
<property name="title" >
|
<property name="title" >
|
||||||
<string>&Edit</string>
|
<string>&Edit</string>
|
||||||
</property>
|
</property>
|
||||||
|
<addaction name="actionUndo" />
|
||||||
|
<addaction name="actionRedo" />
|
||||||
|
<addaction name="separator" />
|
||||||
<addaction name="actionSelectAll" />
|
<addaction name="actionSelectAll" />
|
||||||
<addaction name="actionSelectFacts" />
|
<addaction name="actionSelectFacts" />
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -214,7 +217,7 @@
|
||||||
<string>Delete</string>
|
<string>Delete</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="shortcut" >
|
<property name="shortcut" >
|
||||||
<string>Ctrl+Del</string>
|
<string>Del</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionAddTag" >
|
<action name="actionAddTag" >
|
||||||
|
@ -266,6 +269,24 @@
|
||||||
<string>Select &Facts</string>
|
<string>Select &Facts</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionUndo" >
|
||||||
|
<property name="icon" >
|
||||||
|
<iconset resource="../icons.qrc" >
|
||||||
|
<normaloff>:/icons/edit-undo.png</normaloff>:/icons/edit-undo.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text" >
|
||||||
|
<string>&Undo</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionRedo" >
|
||||||
|
<property name="icon" >
|
||||||
|
<iconset resource="../icons.qrc" >
|
||||||
|
<normaloff>:/icons/edit-redo.png</normaloff>:/icons/edit-redo.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text" >
|
||||||
|
<string>&Redo</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../icons.qrc" />
|
<include location="../icons.qrc" />
|
||||||
|
|
Loading…
Reference in a new issue