From ed07a147f90ca8a5cbd22abea770db6e796f4acc Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Fri, 13 Jan 2017 17:36:26 +1000 Subject: [PATCH] support for saving stats to a pdf --- anki/stats.py | 44 +++++++++++++++++++++++++------------------- aqt/stats.py | 33 ++++++++++++--------------------- 2 files changed, 37 insertions(+), 40 deletions(-) diff --git a/anki/stats.py b/anki/stats.py index 2e12b2fd1..7d53b937c 100644 --- a/anki/stats.py +++ b/anki/stats.py @@ -113,23 +113,29 @@ class CollectionStats(object): self.type = type from .statsbg import bg txt = self.css % bg - txt += self.todayStats() - txt += self.dueGraph() - txt += self.repsGraph() - txt += self.introductionGraph() - txt += self.ivlGraph() - txt += self.hourGraph() - txt += self.easeGraph() - txt += self.cardGraph() - txt += self.footer() + txt += self._section(self.todayStats()) + txt += self._section(self.dueGraph()) + txt += self.repsGraphs() + txt += self._section(self.introductionGraph()) + txt += self._section(self.ivlGraph()) + txt += self._section(self.hourGraph()) + txt += self._section(self.easeGraph()) + txt += self._section(self.cardGraph()) + txt += self._section(self.footer()) return "
%s
" % ( anki.js.jquery+anki.js.plot, txt) + def _section(self, txt): + return "
%s
" % txt + css = """ """ @@ -297,19 +303,19 @@ group by day order by day""" % (self._limit(), lim), return txt - def repsGraph(self): + def repsGraphs(self): if self.type == 0: days = 30; chunk = 1 elif self.type == 1: days = 52; chunk = 7 else: days = None; chunk = 30 - return self._repsGraph(self._done(days, chunk), + return self._repsGraphs(self._done(days, chunk), days, _("Review Count"), _("Review Time")) - def _repsGraph(self, data, days, reptitle, timetitle): + def _repsGraphs(self, data, days, reptitle, timetitle): if not data: return "" d = data @@ -328,13 +334,13 @@ group by day order by day""" % (self._limit(), lim), (4, colRelearn, _("Relearn")), (1, colLearn, _("Learn")), (5, colCram, _("Cram")))) - txt = self._title( + txt1 = self._title( reptitle, _("The number of questions you have answered.")) - txt += plot("reps", repdata, ylabel=_("Answers"), ylabel2=_( + txt1 += plot("reps", repdata, ylabel=_("Answers"), ylabel2=_( "Cumulative Answers")) (daysStud, fstDay) = self._daysStudied() rep, tot = self._ansInfo(repsum, daysStud, fstDay, _("reviews")) - txt += rep + txt1 += rep # time (timdata, timsum) = self._splitRepData(d, ( (8, colMature, _("Mature")), @@ -348,12 +354,12 @@ group by day order by day""" % (self._limit(), lim), else: t = _("Hours") convHours = True - txt += self._title(timetitle, _("The time taken to answer the questions.")) - txt += plot("time", timdata, ylabel=t, ylabel2=_("Cumulative %s") % t) + txt2 = self._title(timetitle, _("The time taken to answer the questions.")) + txt2 += plot("time", timdata, ylabel=t, ylabel2=_("Cumulative %s") % t) rep, tot2 = self._ansInfo( timsum, daysStud, fstDay, _("minutes"), convHours, total=tot) - txt += rep - return txt + txt2 += rep + return self._section(txt1) + self._section(txt2) def _ansInfo(self, totd, studied, first, unit, convHours=False, total=None): if not totd: diff --git a/aqt/stats.py b/aqt/stats.py index 2e39dd3f3..7ddaa5755 100644 --- a/aqt/stats.py +++ b/aqt/stats.py @@ -4,7 +4,8 @@ from aqt.qt import * import os, time -from aqt.utils import saveGeom, restoreGeom, maybeHideClose, showInfo, addCloseShortcut +from aqt.utils import saveGeom, restoreGeom, maybeHideClose, addCloseShortcut, \ + tooltip import aqt # Deck Stats @@ -25,9 +26,9 @@ class DeckStats(QDialog): f = self.form f.setupUi(self) restoreGeom(self, self.name) - b = f.buttonBox.addButton(_("Save Image"), + b = f.buttonBox.addButton(_("Save PDF"), QDialogButtonBox.ActionRole) - b.clicked.connect(self.browser) + b.clicked.connect(self.saveImage) b.setAutoDefault(False) f.groups.clicked.connect(lambda: self.changeScope("deck")) f.groups.setShortcut("g") @@ -39,14 +40,13 @@ class DeckStats(QDialog): addCloseShortcut(self) self.refresh() self.show() - print("fixme: save image support in deck stats") def reject(self): saveGeom(self, self.name) QDialog.reject(self) - def browser(self): - name = time.strftime("-%Y-%m-%d@%H-%M-%S.png", + def _imagePath(self): + name = time.strftime("-%Y-%m-%d@%H-%M-%S.pdf", time.localtime(time.time())) name = "anki-"+_("stats")+name desktopPath = QStandardPaths.writableLocation( @@ -54,21 +54,12 @@ class DeckStats(QDialog): if not os.path.exists(desktopPath): os.mkdir(desktopPath) path = os.path.join(desktopPath, name) - p = self.form.web.page() - oldsize = p.viewportSize() - p.setViewportSize(p.mainFrame().contentsSize()) - image = QImage(p.viewportSize(), QImage.Format_ARGB32) - painter = QPainter(image) - p.mainFrame().render(painter) - painter.end() - isOK = image.save(path, "png") - if isOK: - showInfo(_("An image was saved to your desktop.")) - else: - showInfo(_("""\ -Anki could not save the image. Please check that you have permission to write \ -to your desktop.""")) - p.setViewportSize(oldsize) + return path + + def saveImage(self): + path = self._imagePath() + self.form.web.page().printToPdf(path) + tooltip(_("A PDF file was saved to your desktop.")) def changePeriod(self, n): self.period = n