From 1d9f0176a599290968caedd54bad379687cb1abd Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Mon, 11 Apr 2011 21:23:18 +0900 Subject: [PATCH] fix sorting, allow sort changing, catch attempts to modify schema --- aqt/browser.py | 120 +++++++++++++++++++------------------------- aqt/errors.py | 4 +- aqt/main.py | 12 +++++ aqt/utils.py | 19 +++++++ designer/browser.ui | 46 ++++++++++++++++- 5 files changed, 132 insertions(+), 69 deletions(-) diff --git a/aqt/browser.py b/aqt/browser.py index b2618ea1f..c754b8f64 100644 --- a/aqt/browser.py +++ b/aqt/browser.py @@ -15,7 +15,6 @@ from aqt.utils import saveGeom, restoreGeom, saveSplitter, restoreSplitter, \ saveHeader, restoreHeader, saveState, restoreState, applyStyles from anki.errors import * from anki.db import * -from anki.stats import CardStats from anki.hooks import runHook, addHook, removeHook # fixme: notice added tags? @@ -109,7 +108,7 @@ class DeckModel(QAbstractTableModel): def showMatching(self, force=True): self.parent.mw.progress.start() t = time.time() - self.cards = self.deck.findCards(self.searchStr.strip(), "factFld") + self.cards = self.deck.findCards(self.searchStr.strip()) print "fetch cards in %dms" % ((time.time() - t)*1000) self.parent.mw.progress.finish() # if self.deck.getInt('reverseOrder'): @@ -169,7 +168,7 @@ class DeckModel(QAbstractTableModel): else: return self.nextDue(index) - def updateHeader(self): + def onSortChanged(self): if self.sortKey == "created": k = _("Created") elif self.sortKey == "modified": @@ -287,7 +286,7 @@ class Browser(QMainWindow): self.setupHooks() self.setupEditor() self.setupCardInfo() - self.updateSortOrder() + self.updateSortIcon() self.updateFont() self.form.searchEdit.setFocus() self.updateFilterLabel() @@ -389,13 +388,6 @@ class Browser(QMainWindow): self.onSearch) self.setTabOrder(self.form.searchEdit, self.form.tableView) - def reverseOrder(self): - self.deck.setVar("reverseOrder", not self.deck.getInt("reverseOrder")) - self.model.cards.reverse() - self.model.reset() - self.focusCard() - self.updateSortOrder() - def onSearch(self, force=True): # fixme: # if self.mw.inDbHandler: @@ -481,71 +473,41 @@ class Browser(QMainWindow): ###################################################################### def setupSort(self): - self.form.sortBox.setMaxVisibleItems(30) - self.sortIndex = int(self.deck.conf.get("sortIdx", "0")) - self.drawSort() + self.sortTypes = [ + "factFld", + "factCrt", + "factMod", + "cardMod", + "cardDue", + "cardEase", + "cardReps", + "cardLapses", + ] + idx = self.sortTypes.index(self.deck.conf['sortType']) + self.form.sortBox.setCurrentIndex(idx) self.connect(self.form.sortBox, SIGNAL("activated(int)"), self.sortChanged) - self.sortChanged(self.sortIndex, refresh=False) + self.sortChanged(idx, refresh=False) self.connect(self.form.sortOrder, SIGNAL("clicked()"), - self.reverseOrder) + self.toggleSortOrder) - def drawSort(self): - self.sortList = [ - _("Question"), - _("Answer"), - _("Created"), - _("Modified"), - _("Due"), - _("Interval"), - _("Reps"), - _("Ease"), - _("Fact Created"), - _("Lapses"), - _("First Review"), - ] - self.form.sortBox.clear() - self.form.sortBox.addItems(QStringList(self.sortList)) - if self.sortIndex >= len(self.sortList): - self.sortIndex = 0 - self.form.sortBox.setCurrentIndex(self.sortIndex) + def toggleSortOrder(self): + self.deck.conf['sortBackwards'] = not self.deck.conf['sortBackwards'] + self.model.cards.reverse() + self.model.reset() + self.focusCard() + self.updateSortIcon() - def updateSortOrder(self): - if int(self.deck.conf.get("revOrder", "0")): + def updateSortIcon(self): + if self.deck.conf['sortBackwards']: self.form.sortOrder.setIcon(QIcon(":/icons/view-sort-descending.png")) else: self.form.sortOrder.setIcon(QIcon(":/icons/view-sort-ascending.png")) def sortChanged(self, idx, refresh=True): - if idx == 0: - self.sortKey = "question" - elif idx == 1: - self.sortKey = "answer" - elif idx == 2: - self.sortKey = "created" - elif idx == 3: - self.sortKey = "modified" - elif idx == 4: - self.sortKey = "combinedDue" - elif idx == 5: - self.sortKey = "interval" - elif idx == 6: - self.sortKey = "reps" - elif idx == 7: - self.sortKey = "factor" - elif idx == 8: - self.sortKey = "fact" - elif idx == 9: - self.sortKey = "noCount" - elif idx == 10: - self.sortKey = "firstAnswered" - else: - self.sortKey = ("field", self.sortFields[idx-11]) - #self.rebuildSortIndex(self.sortKey) self.sortIndex = idx - self.deck.conf['sortIdx'] = idx - self.model.sortKey = self.sortKey - self.model.updateHeader() + self.deck.conf['sortType'] = self.sortTypes[idx] + self.model.onSortChanged() if refresh: self.model.showMatching() self.updateFilterLabel() @@ -666,13 +628,37 @@ class Browser(QMainWindow): ###################################################################### def setupCardInfo(self): + from anki.stats import CardStats self.card = None self.cardStats = CardStats(self.deck, None) + self.connect(self.form.cardLabel, + SIGNAL("linkActivated(const QString&)"), + self.onChangeSortField) def showCardInfo(self, card): self.cardStats.card = self.card - self.form.cardLabel.setText( - self.cardStats.report()) + rep = self.cardStats.report() + rep = "" + rep + m = self.card.model() + sortf = m.fields[m.sortIdx()]['name'] + rep = rep.replace( + "", + "%s%s" % ( + _("Sort Field"), + "%s" % sortf)) + self.form.cardLabel.setText(rep) + + def onChangeSortField(self): + from aqt.utils import chooseList + m = self.card.model() + fields = [f['name'] for f in m.fields] + idx = chooseList(_("Choose field to sort this model by:"), + fields, m.sortIdx()) + if idx != m.sortIdx(): + self.mw.progress.start() + m.setSortIdx(idx) + self.mw.progress.finish() + self.onSearch() # Menu helpers ###################################################################### diff --git a/aqt/errors.py b/aqt/errors.py index 0b69b847c..9a1767f1b 100644 --- a/aqt/errors.py +++ b/aqt/errors.py @@ -57,6 +57,9 @@ into a bug report:
pluginText = _("""\ An error occurred in a plugin. Please contact the plugin author.
Please do not file a bug report with Anki.
""") + self.mw.progress.clear() + if "abortSchemaMod" in error: + return if "plugin" in error: txt = pluginText else: @@ -64,4 +67,3 @@ Please do not file a bug report with Anki.
""") # show dialog txt = txt + "
" + error + "
" showText(txt, type="html") - self.mw.progress.clear() diff --git a/aqt/main.py b/aqt/main.py index 1513d4cb1..388724d3c 100755 --- a/aqt/main.py +++ b/aqt/main.py @@ -75,6 +75,7 @@ class AnkiQt(QMainWindow): self.setupVersion() self.setupAutoUpdate() self.setupCardStats() + self.setupSchema() # screens self.setupDeckBrowser() self.setupOverview() @@ -895,6 +896,17 @@ Please choose a new deck name:""")) if self.state != "showQuestion": playFromText(self.currentCard.answer) + # Schema modifications + ########################################################################## + + def setupSchema(self): + addHook("modSchema", self.onSchemaMod) + + def onSchemaMod(self, arg): + return askUser(_("""\ +This operation can't be merged when syncing, so the next \ +sync will overwrite any remote changes. Continue?""")) + # Media locations ########################################################################## diff --git a/aqt/utils.py b/aqt/utils.py index f632443dd..ebdbd3781 100644 --- a/aqt/utils.py +++ b/aqt/utils.py @@ -170,6 +170,25 @@ def getOnlyText(*args, **kwargs): else: return u"" +# fixme: these utilities could be combined into a single base class +def chooseList(prompt, choices, startrow=0, parent=None): + if not parent: + parent = aqt.mw.app.activeWindow() + d = QDialog(parent) + l = QVBoxLayout() + d.setLayout(l) + t = QLabel(prompt) + l.addWidget(t) + c = QListWidget() + c.addItems(QStringList(choices)) + c.setCurrentRow(startrow) + l.addWidget(c) + bb = QDialogButtonBox(QDialogButtonBox.Ok) + bb.connect(bb, SIGNAL("accepted()"), d, SLOT("accept()")) + l.addWidget(bb) + d.exec_() + return c.currentRow() + def getTag(parent, deck, question, tags="user", **kwargs): from aqt.tagedit import TagEdit te = TagEdit(parent) diff --git a/designer/browser.ui b/designer/browser.ui index a6e08ec87..02da34b74 100644 --- a/designer/browser.ui +++ b/designer/browser.ui @@ -119,7 +119,48 @@ - + + + + Fields + + + + + Creation date + + + + + Edit date + + + + + Review date + + + + + Due date + + + + + Ease factor + + + + + Review count + + + + + Lapse count + + + @@ -218,6 +259,9 @@ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + true +