From 3362ca06a33e1a2633f794786a52019443099052 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Tue, 29 Nov 2011 17:46:32 +0900 Subject: [PATCH] move card info into separate diag --- aqt/browser.py | 107 ++++++++++++++++++++-------------------- aqt/fields.py | 2 + aqt/main.py | 12 +++-- aqt/reviewer.py | 2 +- aqt/stats.py | 2 +- designer/icons.qrc | 1 + designer/icons/info.png | Bin 0 -> 3096 bytes designer/setgroup.ui | 6 +-- 8 files changed, 70 insertions(+), 62 deletions(-) create mode 100644 designer/icons/info.png diff --git a/aqt/browser.py b/aqt/browser.py index 421f4e063..5d963e6d4 100644 --- a/aqt/browser.py +++ b/aqt/browser.py @@ -232,6 +232,8 @@ class DataModel(QAbstractTableModel): return "%d%%" % (c.factor/10) elif type == "deck": return self.browser.mw.col.decks.name(c.did) + elif type == "ndeck": + return self.browser.mw.col.decks.name(c.note().did) def question(self, c): return self.formatQA(c.a()) @@ -250,7 +252,7 @@ class DataModel(QAbstractTableModel): def nextDue(self, c, index): if c.queue == 0: - return str(c.due) + return _("(new)") # str(c.due) elif c.queue == 1: date = c.due elif c.queue == 2: @@ -312,6 +314,7 @@ class Browser(QMainWindow): restoreSplitter(self.form.splitter, "editor3") self.form.splitter_2.setChildrenCollapsible(False) self.form.splitter.setChildrenCollapsible(False) + self.card = None self.setupColumns() self.setupTable() self.setupMenus() @@ -321,7 +324,6 @@ class Browser(QMainWindow): self.setupHooks() self.setupEditor() self.setupToolbar() - #self.setupCardInfo() self.updateFont() self.onUndoState(self.mw.form.actionUndo.isEnabled()) self.form.searchEdit.setFocus() @@ -405,7 +407,8 @@ class Browser(QMainWindow): ('question', _("Question")), ('answer', _("Answer")), ('template', _("Card")), - ('deck', _("Deck")), + ('deck', _("Card Deck")), + ('ndeck', _("Note Deck")), ('noteFld', _("Sort Field")), ('noteCrt', _("Created")), ('noteMod', _("Edited")), @@ -502,7 +505,6 @@ class Browser(QMainWindow): self.form.tableView.selectionModel().currentIndex()) self.editor.setNote(self.card.note()) self.editor.card = self.card - self.showCardInfo(self.card) self.toolbar.draw() def refreshCurrentCard(self, note): @@ -681,35 +683,40 @@ class Browser(QMainWindow): fillGroups(item, g[4], g[0]+"::") fillGroups(root, grps) - # Card info + # Info ###################################################################### - def setupCardInfo(self): - from anki.stats import CardStats - self.card = None - self.cardStats = CardStats(self.col, None) - self.connect(self.form.cardLabel, - SIGNAL("linkActivated(const QString&)"), - self.onCardLink) + def showCardInfo(self): + if not self.card: + return + info, cs = self._cardInfoData() + reps = self._revlogData(cs) + d = QDialog(self) + l = QVBoxLayout() + l.setMargin(0) + w = AnkiWebView() + l.addWidget(w) + w.stdHtml(info + "

" + reps) + bb = QDialogButtonBox(QDialogButtonBox.Close) + l.addWidget(bb) + bb.connect(bb, SIGNAL("rejected()"), d, SLOT("reject()")) + d.setLayout(l) + d.setWindowModality(Qt.WindowModal) + d.resize(500, 400) + restoreGeom(d, "revlog") + d.exec_() + saveGeom(d, "revlog") - def showCardInfo(self, card): - return - self.cardStats.card = self.card - rep = self.cardStats.report() + def _cardInfoData(self): + from anki.stats import CardStats + cs = CardStats(self.col, self.card) + rep = cs.report() rep = "" + rep m = self.card.model() - # add sort field - sortf = m['flds'][self.mw.col.models.sortIdx(m)]['name'] - extra = self.cardStats.makeLine( - _("Sort Field"), "%s" % sortf) - # and revlog - if self.card.reps: - extra += self.cardStats.makeLine( - _("Reviews"), "%d" % self.card.reps) - rep = rep.replace("", extra) - self.form.cardLabel.setMaximumWidth(200) - self.form.cardLabel.setWordWrap(True) - self.form.cardLabel.setText(rep) + rep = """ +

%s
""" % rep + return rep, cs def onCardLink(self, url): if url == "sort": @@ -748,14 +755,17 @@ class Browser(QMainWindow): d.exec_() saveGeom(d, "revlog") - def _revlogData(self): + def _revlogData(self, cs): + entries = self.mw.col.db.all( + "select id/1000.0, ease, ivl, factor, time/1000.0, type " + "from revlog where cid = ?", self.card.id) + if not entries: + return "" s = "" % _("Date") s += ("" * 5) % ( _("Type"), _("Ease"), _("Interval"), _("Factor"), _("Time")) cnt = 0 - for (date, ease, ivl, factor, taken, type) in self.mw.col.db.execute( - "select id/1000.0, ease, ivl, factor, time/1000.0, type " - "from revlog where cid = ?", self.card.id): + for (date, ease, ivl, factor, taken, type) in reversed(entries): cnt += 1 s += "" % time.strftime(_("%Y-%m-%d @ %H:%M"), time.localtime(date)) @@ -780,19 +790,17 @@ class Browser(QMainWindow): elif ivl > 0: ivl = fmtTimeSpan(ivl*86400, short=True) else: - ivl = self.cardStats.time(-ivl) + ivl = cs.time(-ivl) s += ("" * 5) % ( tstr, ease, ivl, "%d%%" % (factor/10) if factor else "", - self.cardStats.time(taken)) + "" + cs.time(taken)) + "" s += "
%s%s
%s%s
" if cnt != self.card.reps: - s += "

" + _("""\ -Note: Review count does not match the history. This can happen \ -if your cards were reviewed in early Anki versions, if statistics \ -were lost in a sync conflict, or the deck was imported from \ -another program.""") + s += '

' + _("""\ +Note: Some of the history is missing. For more information, \ +please see the browser documentation.""") + "
" return s # Menu helpers @@ -1412,15 +1420,6 @@ class BrowserToolbar(Toolbar): ["remTags", "Remove Tags"], ] - singleOnly = [ - ["info", "Info"], - ] - - rightIcons = [ - ["mark", "qrc:/icons/star16.png"], - ["pause", "qrc:/icons/star_off16.png"], - ] - def __init__(self, mw, web, browser): self.browser = browser Toolbar.__init__(self, mw, web) @@ -1430,8 +1429,6 @@ class BrowserToolbar(Toolbar): mark = self.browser.isMarked() pause = self.browser.isSuspended() links = self.always[:] - if single: - links += self.singleOnly self.centerLinks = links def borderImg(link, icon, on): if on: @@ -1443,10 +1440,12 @@ class BrowserToolbar(Toolbar): ''' return fmt % (link, icon) right = "" - right += borderImg("mark", "star16", mark) - right += borderImg("pause", "pause16", pause) + if self.browser.card: + right += borderImg("info", "info", False) + right += borderImg("mark", "star16", mark) + right += borderImg("pause", "pause16", pause) self.web.stdHtml(self._body % ( - 'Browser ▾', + ' '*20, #Browser ▾', self._centerLinks(), right), self._css, focus=False) @@ -1462,6 +1461,8 @@ class BrowserToolbar(Toolbar): self.browser.addTags() elif l == "remTags": self.browser.deleteTags() + elif l == "info": + self.browser.showCardInfo() # icons elif l == "mark": self.browser.onMark() diff --git a/aqt/fields.py b/aqt/fields.py index bd6bdba54..83e317353 100644 --- a/aqt/fields.py +++ b/aqt/fields.py @@ -15,6 +15,8 @@ import aqt.templates # need to strip the field management code out of this +# - add sort field + class CardLayout(QDialog): def __init__(self, mw, note, ord=0, parent=None): diff --git a/aqt/main.py b/aqt/main.py index e46303607..b922378e4 100755 --- a/aqt/main.py +++ b/aqt/main.py @@ -529,19 +529,23 @@ Debug info:\n%s""") % traceback.format_exc(), help="DeckErrors") # Dockable widgets ########################################################################## - def addDockable(self, title, w, target=None): + def addDockable(self, title, w, target=None, startDocked=True): target = target or self dock = QDockWidget(title, target) dock.setObjectName(title) dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) - dock.setFeatures(QDockWidget.DockWidgetClosable) + dock.setFeatures(QDockWidget.AllDockWidgetFeatures) dock.setWidget(w) if target.width() < 600: target.resize(QSize(600, target.height())) - target.addDockWidget(Qt.RightDockWidgetArea, dock) + if startDocked: + target.addDockWidget(Qt.NoDockWidgetArea, dock) + else: + dock.setFloating(True) + dock.show() return dock - def rmDockable(self, dock, target=None): + def remDockable(self, dock, target=None): target = target or self target.removeDockWidget(dock) diff --git a/aqt/reviewer.py b/aqt/reviewer.py index 0d3b5a70a..b04eb6362 100644 --- a/aqt/reviewer.py +++ b/aqt/reviewer.py @@ -319,7 +319,7 @@ div.ansbuttxt { position: relative; top: 25%; } -body { margin:1em; } +body { margin:1.5em; } #easebuts { bottom: 1em; diff --git a/aqt/stats.py b/aqt/stats.py index ad14a21b5..4d425839a 100644 --- a/aqt/stats.py +++ b/aqt/stats.py @@ -34,7 +34,7 @@ class CardStats(object): def hide(self): if self.shown: - self.mw.rmDockable(self.shown) + self.mw.remDockable(self.shown) self.shown = None def _visChange(self, vis): diff --git a/designer/icons.qrc b/designer/icons.qrc index 81b4057e7..a2e4f6cb3 100644 --- a/designer/icons.qrc +++ b/designer/icons.qrc @@ -121,5 +121,6 @@ icons/star_off16.png icons/pause16.png icons/pause_off16.png + icons/info.png diff --git a/designer/icons/info.png b/designer/icons/info.png new file mode 100644 index 0000000000000000000000000000000000000000..882bdb2f9980a8a2df8ff685136a68ecab861d6e GIT binary patch literal 3096 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 m+a?_hTYaeK-@X#4R>K!X4W=ho<~hOu0000 - Set current group to: + Move card(s) to deck: true @@ -33,7 +33,7 @@ - Set initial group too + Move notes too @@ -43,7 +43,7 @@ - Reset to initial group + Move card(s) to their note's deck