merge deck stats and graphs together

This commit is contained in:
Damien Elmes 2011-03-30 21:12:46 +09:00
parent 0ab698154f
commit 7ab89d2637
4 changed files with 209 additions and 121 deletions

View file

@ -526,7 +526,7 @@ Debug info:\n%s""") % traceback.format_exc(), help="DeckErrors")
tb.addAction(frm.actionEditLayout)
tb.addAction(frm.actionEditdeck)
tb.addAction(frm.actionOverview)
tb.addAction(frm.actionGraphs)
tb.addAction(frm.actionStats)
tb.addAction(frm.actionMarkCard)
tb.addAction(frm.actionRepeatAudio)
tb.addAction(frm.actionClose)
@ -651,11 +651,8 @@ Debug info:\n%s""") % traceback.format_exc(), help="DeckErrors")
def onCardStats(self):
self.cardStats.show()
def onDeckStats(self):
aqt.stats.deckStats(self)
def onGraphs(self):
aqt.stats.graphs(self)
def onStats(self):
aqt.stats.DeckStats(self)
def onCardLayout(self):
aqt.clayout.CardLayout(self, 0, self.currentCard.fact,
@ -740,8 +737,7 @@ Please choose a new deck name:"""))
"DeckProperties",
"Undo",
"Export",
"Graphs",
"Dstats",
"Stats",
"Cstats",
"StudyOptions",
"Overview",
@ -765,9 +761,8 @@ Please choose a new deck name:"""))
self.connect(m.actionEditdeck, s, self.onEditDeck)
self.connect(m.actionEditCurrent, s, self.onEditCurrent)
self.connect(m.actionPreferences, s, self.onPrefs)
self.connect(m.actionDstats, s, self.onDeckStats)
self.connect(m.actionStats, s, self.onStats)
self.connect(m.actionCstats, s, self.onCardStats)
self.connect(m.actionGraphs, s, self.onGraphs)
self.connect(m.actionEditLayout, s, self.onCardLayout)
self.connect(m.actionAbout, s, self.onAbout)
self.connect(m.actionImport, s, self.onImport)

View file

@ -8,6 +8,7 @@ import os, tempfile
from aqt.webview import AnkiWebView
from aqt.utils import saveGeom, restoreGeom
from anki.hooks import addHook
import aqt
# Card stats
######################################################################
@ -58,51 +59,44 @@ class CardStats(object):
<style>table { font-size: 12px; } h1 { font-size: 14px; }</style>
</head><body><center>%s</center></body></html>"""%txt)
# Modal dialog that supports dumping to browser (for printing, etc)
# Deck Stats
######################################################################
class PrintableReport(QDialog):
class DeckStats(QDialog):
def __init__(self, mw, type, title, func, css):
self.mw = mw
def __init__(self, mw):
QDialog.__init__(self, mw)
restoreGeom(self, type)
self.type = type
self.setWindowTitle(title)
self.setModal(True)
self.mw.progress.start()
self.web = AnkiWebView(self)
l = QVBoxLayout(self)
l.setContentsMargins(0,0,0,0)
l.addWidget(self.web)
self.css = css
if func:
self.report = func()
self.web.stdHtml(self.report, css=css)
self.box = QDialogButtonBox(QDialogButtonBox.Close)
b = self.box.addButton(_("Save Image"), QDialogButtonBox.ActionRole)
self.mw = mw
self.name = "deckStats"
self.period = 0
self.sel = True
self.form = aqt.forms.stats.Ui_Dialog()
f = self.form
f.setupUi(self)
restoreGeom(self, self.name)
b = f.buttonBox.addButton(_("Save Image"),
QDialogButtonBox.ActionRole)
b.connect(b, SIGNAL("clicked()"), self.browser)
b.setAutoDefault(False)
self.layout = QHBoxLayout()
self.layout.setContentsMargins(0,0,0,0)
self.layout.addWidget(self.box)
l.addLayout(self.layout)
self.setLayout(l)
self.connect(self.box, SIGNAL("rejected()"), self, SLOT("reject()"))
self.mw.progress.finish()
def run(self):
c = self.connect
s = SIGNAL("clicked()")
c(f.groups, s, lambda: self.changeSel(True))
c(f.all, s, lambda: self.changeSel(False))
c(f.month, s, lambda: self.changePeriod(0))
c(f.year, s, lambda: self.changePeriod(1))
c(f.life, s, lambda: self.changePeriod(2))
self.refresh()
self.exec_()
def reject(self):
saveGeom(self, self.type)
saveGeom(self, self.name)
QDialog.reject(self)
def browser(self):
# dump to a temporary file
tmpdir = tempfile.mkdtemp(prefix="anki")
path = os.path.join(tmpdir, "report.png")
p = self.web.page()
p = self.form.web.page()
oldsize = p.viewportSize()
p.setViewportSize(p.mainFrame().contentsSize())
image = QImage(p.viewportSize(), QImage.Format_ARGB32)
@ -113,73 +107,17 @@ class PrintableReport(QDialog):
p.setViewportSize(oldsize)
QDesktopServices.openUrl(QUrl("file://" + path))
# Deck stats
######################################################################
def deckStats(mw):
css=mw.sharedCSS+"""
body { margin: 2em; font-family: arial; }
h1 { font-size: 18px; border-bottom: 1px solid #000; margin-top: 1em;
clear: both; margin-bottom: 0.5em; }
.info {float:right; padding: 10px; max-width: 300px; border-radius: 5px;
background: #ddd; font-size: 14px; }
"""
return PrintableReport(
mw,
"deckstats",
_("Deck Statistics"),
mw.deck.deckStats,
css).run()
# Graphs
######################################################################
class Graphs(PrintableReport):
def __init__(self, *args):
self.period = 0
self.periods = [
_("1 month"),
_("1 year"),
_("deck life")]
PrintableReport.__init__(self, *args)
grp = QGroupBox()
l = QHBoxLayout()
l.setContentsMargins(6,6,6,6)
chk = False
for c, p in enumerate(self.periods):
b = QRadioButton(p)
if not chk:
b.setChecked(True)
chk = True
b.connect(b, SIGNAL("clicked()"), lambda n=c: self.changePeriod(n))
l.addWidget(b)
grp.setLayout(l)
self.layout.insertWidget(0, grp)
self.layout.insertStretch(0, 10)
self.refresh()
def changePeriod(self, n):
self.period = n
self.refresh()
def changeSel(self, sel):
self.sel = sel
self.refresh()
def refresh(self):
self.mw.progress.start(immediate=True)
self.report = self.mw.deck.graphs().report(type=self.period)
self.web.stdHtml(self.report, css=self.css)
self.report = self.mw.deck.graphs().report(
type=self.period, selective=self.sel)
self.form.web.setHtml(self.report)
self.mw.progress.finish()
def graphs(mw):
css=mw.sharedCSS+"""
body { margin: 2em; font-family: arial; background: #eee; }
h1 { font-size: 18px; border-bottom: 1px solid #000; margin-top: 1em;
clear: both; margin-bottom: 0.5em; }
.info {float:right; padding: 10px; max-width: 300px; border-radius: 5px;
background: #ddd; font-size: 14px; }
"""
return Graphs(
mw,
"graphs",
_("Graphs"),
None,
css).run()

View file

@ -113,8 +113,7 @@
<addaction name="actionLocalizeMedia"/>
<addaction name="separator"/>
</widget>
<addaction name="actionGraphs"/>
<addaction name="actionDstats"/>
<addaction name="actionStats"/>
<addaction name="actionCstats"/>
<addaction name="separator"/>
<addaction name="actionRepeatAudio"/>
@ -321,18 +320,6 @@
<enum>QAction::PreferencesRole</enum>
</property>
</action>
<action name="actionDstats">
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/icons/spreadsheet.png</normaloff>:/icons/spreadsheet.png</iconset>
</property>
<property name="text">
<string>&amp;Deck Statistics</string>
</property>
<property name="shortcut">
<string>Shift+D</string>
</property>
</action>
<action name="actionAbout">
<property name="icon">
<iconset resource="icons.qrc">
@ -351,7 +338,7 @@
<normaloff>:/icons/package_games_card.png</normaloff>:/icons/package_games_card.png</iconset>
</property>
<property name="text">
<string>&amp;Card Statistics</string>
<string>&amp;Card Info</string>
</property>
<property name="statusTip">
<string>Show statistics about the current card and last card</string>
@ -387,19 +374,19 @@
<string>Ctrl+I</string>
</property>
</action>
<action name="actionGraphs">
<action name="actionStats">
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/icons/view-statistics.png</normaloff>:/icons/view-statistics.png</iconset>
</property>
<property name="text">
<string>&amp;Graphs...</string>
<string>&amp;Statistics...</string>
</property>
<property name="statusTip">
<string/>
</property>
<property name="shortcut">
<string>Shift+G</string>
<string>Shift+S</string>
</property>
</action>
<action name="actionExport">

168
designer/stats.ui Normal file
View file

@ -0,0 +1,168 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>607</width>
<height>556</height>
</rect>
</property>
<property name="windowTitle">
<string>Statistics</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QWebView" name="web">
<property name="url">
<url>
<string>about:blank</string>
</url>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>8</number>
</property>
<property name="margin">
<number>6</number>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string/>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QRadioButton" name="groups">
<property name="text">
<string>groups</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="all">
<property name="text">
<string>all</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string/>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QRadioButton" name="month">
<property name="text">
<string>1 month</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="year">
<property name="text">
<string>1 year</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="life">
<property name="text">
<string>deck life</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QWebView</class>
<extends>QWidget</extends>
<header>QtWebKit/QWebView</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>