mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 16:56:36 -04:00
start work on an overview; add flot to resources
This commit is contained in:
parent
81d29fedd5
commit
c9c7b8c25b
6 changed files with 154 additions and 37 deletions
|
@ -11,35 +11,6 @@ from anki.utils import fmtTimeSpan
|
|||
from anki.hooks import addHook
|
||||
import aqt
|
||||
|
||||
_css = """
|
||||
body { background-color: #eee; }
|
||||
#outer { margin-top: 1em; }
|
||||
.sub { color: #555; }
|
||||
hr { margin:5 0 5 0; border:0; height:1px; background-color:#ddd; }
|
||||
a:hover { background-color: #aaa; }
|
||||
a.deck { color: #000; text-decoration: none; font-size: 100%; }
|
||||
.num { text-align: right; padding: 0 5 0 5; }
|
||||
a.opts { font-size: 80%; padding: 3; background-color: #ccc;
|
||||
border-radius: 2px; color: #000; }
|
||||
td.opts { text-align: right; white-space: nowrap; }
|
||||
td.menu { text-align: center; }
|
||||
a { font-size: 80%; text-decoration: none; }
|
||||
h1 { margin-bottom: 0.2em; }
|
||||
"""
|
||||
|
||||
_body = """
|
||||
<center>
|
||||
<div id="outer">
|
||||
<h1>%(title)s</h1>
|
||||
%(tb)s
|
||||
<p>
|
||||
<table cellspacing=0 cellpadding=0 width=90%%>
|
||||
%(rows)s
|
||||
</table>
|
||||
%(extra)s
|
||||
</div>
|
||||
"""
|
||||
|
||||
class DeckBrowser(object):
|
||||
"Display a list of remembered decks."
|
||||
|
||||
|
@ -147,28 +118,50 @@ class DeckBrowser(object):
|
|||
# HTML generation
|
||||
##########################################################################
|
||||
|
||||
_css = """
|
||||
.sub { color: #555; }
|
||||
a.deck { color: #000; text-decoration: none; font-size: 100%; }
|
||||
.num { text-align: right; padding: 0 5 0 5; }
|
||||
td.opts { text-align: right; white-space: nowrap; }
|
||||
td.menu { text-align: center; }
|
||||
a { font-size: 80%; }
|
||||
"""
|
||||
|
||||
_body = """
|
||||
<center>
|
||||
<h1>%(title)s</h1>
|
||||
%(tb)s
|
||||
<p>
|
||||
<table cellspacing=0 cellpadding=0 width=90%%>
|
||||
%(rows)s
|
||||
</table>
|
||||
%(extra)s
|
||||
</center>
|
||||
"""
|
||||
|
||||
def _renderPage(self):
|
||||
if self._decks:
|
||||
buf = ""
|
||||
css = self.mw._sharedCSS + self._css
|
||||
max=len(self._decks)-1
|
||||
for c, deck in enumerate(self._decks):
|
||||
buf += self._deckRow(c, max, deck)
|
||||
self.web.stdHtml(_body%dict(
|
||||
self.web.stdHtml(self._body%dict(
|
||||
title=_("Decks"),
|
||||
rows=buf,
|
||||
tb=self._toolbar(),
|
||||
extra="<p>%s<p>%s" % (
|
||||
self._summary(),
|
||||
_("Click a deck to open it, or type a number."))),
|
||||
_css)
|
||||
css)
|
||||
else:
|
||||
self.web.stdHtml(_body%dict(
|
||||
self.web.stdHtml(self._body%dict(
|
||||
title=_("Welcome!"),
|
||||
rows="<tr><td align=center>%s</td></tr>"%_(
|
||||
"Click <b>Download</b> to get started."),
|
||||
extra="",
|
||||
tb=self._toolbar()),
|
||||
_css)
|
||||
css)
|
||||
|
||||
def _deckRow(self, c, max, deck):
|
||||
buf = "<tr>"
|
||||
|
@ -212,7 +205,7 @@ class DeckBrowser(object):
|
|||
# no counts
|
||||
buf += "<td colspan=2></td>"
|
||||
# options
|
||||
buf += "<td class=opts><a class=opts href='opts:%d'>%s▼</a></td>" % (
|
||||
buf += "<td class=opts><a class=but href='opts:%d'>%s▼</a></td>" % (
|
||||
c, "Options")
|
||||
buf += "</tr>"
|
||||
if c != max:
|
||||
|
|
11
aqt/main.py
11
aqt/main.py
|
@ -81,6 +81,17 @@ class AnkiQt(QMainWindow):
|
|||
self.setupEditor()
|
||||
self.setupStudyScreen()
|
||||
|
||||
_sharedCSS = """
|
||||
body { background-color: #eee; margin-top: 1em; }
|
||||
a:hover { background-color: #aaa; }
|
||||
a.but { font-size: 80%; padding: 3; background-color: #ccc;
|
||||
border-radius: 2px; color: #000; margin: 0 5 0 5; text-decoration:
|
||||
none; display: inline-block; }
|
||||
h1 { margin-bottom: 0.2em; }
|
||||
hr { margin:5 0 5 0; border:0; height:1px; background-color:#ddd; }
|
||||
"""
|
||||
#a { text-decoration: none; }
|
||||
|
||||
# State machine
|
||||
##########################################################################
|
||||
|
||||
|
|
112
aqt/reviewer.py
112
aqt/reviewer.py
|
@ -2,10 +2,11 @@
|
|||
# Copyright: Damien Elmes <anki@ichi2.net>
|
||||
# License: GNU GPL, version 3 or later; http://www.gnu.org/copyleft/gpl.html
|
||||
|
||||
import time, os, stat, shutil, difflib
|
||||
import time, os, stat, shutil, difflib, simplejson
|
||||
import unicodedata as ucd
|
||||
from PyQt4.QtCore import *
|
||||
from PyQt4.QtGui import *
|
||||
from anki.consts import NEW_CARDS_RANDOM
|
||||
from anki.utils import fmtTimeSpan, stripHTML
|
||||
from anki.hooks import addHook, runHook, runFilter
|
||||
from anki.sound import playFromText
|
||||
|
@ -30,11 +31,118 @@ class Reviewer(object):
|
|||
self._setupToolbar()
|
||||
self._reset()
|
||||
|
||||
# Overview state
|
||||
##########################################################################
|
||||
|
||||
_overviewBody = """
|
||||
<center>
|
||||
<h1>%(title)s</h1>
|
||||
%(table)s
|
||||
<hr>
|
||||
<div id="placeholder" style="width:350px; height:100px;"></div>
|
||||
<span class=sub>%(fcsub)s</span>
|
||||
<hr>
|
||||
%(opts)s
|
||||
</center>
|
||||
|
||||
<script id="source" language="javascript" type="text/javascript">
|
||||
$(function () {
|
||||
var d = %(fcdata)s;
|
||||
$.plot($("#placeholder"), [
|
||||
{ data: d, bars: { show: true, barWidth: 0.8 } }
|
||||
], {
|
||||
xaxis: { ticks: [[0.5, "Today"]] }
|
||||
});
|
||||
});
|
||||
</script>
|
||||
"""
|
||||
|
||||
_overviewCSS = """
|
||||
.due { text-align: right; color: green; }
|
||||
.new { text-align: right; color: blue; }
|
||||
.sub { font-size: 80%; color: #555; }
|
||||
"""
|
||||
|
||||
def _overview(self):
|
||||
css = self.mw._sharedCSS + self._overviewCSS
|
||||
self.web.stdHtml(self._overviewBody % dict(
|
||||
title=_("Overview"),
|
||||
table=self._overviewTable(),
|
||||
fcsub=_("Due over next two weeks"),
|
||||
fcdata=self._ovForecast(),
|
||||
opts=self._ovOpts(),
|
||||
), css)
|
||||
|
||||
def _overviewTable(self):
|
||||
counts = self._ovCounts()
|
||||
def but(link, name):
|
||||
return '<a class=but href="%s">%s</a>' % (link, name)
|
||||
buf = "<table cellspacing=0 cellpadding=3 width=400>"
|
||||
buf += "<tr><th></th><th align=right>%s</th>" % _("Due")
|
||||
buf += "<th align=right>%s</th><th></th></tr>" % _("New")
|
||||
line = "<tr><td><b>%s</b></td><td class=due>%s</td>"
|
||||
line += "<td class=new>%s</td><td align=right>%s</td></tr>"
|
||||
buf += line % (
|
||||
"<a href=chgrp>%s</a>" % _("Selected Groups"),
|
||||
counts[0], counts[1],
|
||||
but("studysel", _("Study")) +
|
||||
but("cramsel", _("Cram")))
|
||||
buf += line % (
|
||||
_("Whole Deck"),
|
||||
counts[2], counts[3],
|
||||
but("studyall", _("Study")) +
|
||||
but("cramall", _("Cram")))
|
||||
buf += "</table>"
|
||||
return buf
|
||||
|
||||
def _ovCounts(self):
|
||||
oldNew = self.mw.deck.qconf['newGroups']
|
||||
oldRev = self.mw.deck.qconf['revGroups']
|
||||
if not oldNew and not oldRev:
|
||||
# everything is enabled, no extra work to work to do
|
||||
self.mw.deck.reset()
|
||||
allcnt = self.mw.deck.sched.counts()
|
||||
else:
|
||||
# need to reset to find all cards
|
||||
self.mw.deck.qconf['newGroups'] = []
|
||||
self.mw.deck.qconf['revGroups'] = []
|
||||
self.mw.deck.reset()
|
||||
allcnt = self.mw.deck.sched.counts()
|
||||
self.mw.deck.qconf['newGroups'] = oldNew
|
||||
self.mw.deck.qconf['revGroups'] = oldRev
|
||||
self.mw.deck.reset()
|
||||
selcnt = self.mw.deck.sched.counts()
|
||||
return [
|
||||
selcnt[1] + selcnt[2],
|
||||
selcnt[0],
|
||||
allcnt[1] + allcnt[2],
|
||||
allcnt[0],
|
||||
]
|
||||
|
||||
def _ovForecast(self):
|
||||
return simplejson.dumps(tuple(
|
||||
enumerate(self.mw.deck.sched.dueForecast(14))))
|
||||
|
||||
def _ovOpts(self):
|
||||
if self.mw.deck.qconf['newCardOrder'] == NEW_CARDS_RANDOM:
|
||||
ord = _("random")
|
||||
else:
|
||||
ord = _("order added")
|
||||
buf = """
|
||||
<table width=400>
|
||||
<tr><td><b>%s</b></td><td align=center>%s</td><td align=right rowspan=2>%s</td></tr>
|
||||
<tr><td><b>%s</b></td><td align=center>%s</td></tr>
|
||||
</table>""" % (
|
||||
_("New cards per day"), self.mw.deck.qconf['newPerDay'],
|
||||
'<a href=opts class=but>%s</a>' % _("Study Options"),
|
||||
_("New card order"), ord)
|
||||
return buf
|
||||
|
||||
# State control
|
||||
##########################################################################
|
||||
|
||||
def _reset(self):
|
||||
self.web.stdHtml("")
|
||||
self._overview()
|
||||
|
||||
def setState(self, state):
|
||||
"Change to STATE, and update the display."
|
||||
|
|
|
@ -66,7 +66,10 @@ class AnkiWebView(QWebView):
|
|||
QWebView.setHtml(self, html)
|
||||
def stdHtml(self, body, css="", loadCB=None):
|
||||
self.setHtml("""
|
||||
<html><head><style>%s</style><script src="qrc:/jquery.min.js"></script></head>
|
||||
<html><head><style>%s</style>
|
||||
<script src="qrc:/jquery.min.js"></script>
|
||||
<script src="qrc:/jquery.flot.min.js"></script>
|
||||
</head>
|
||||
<body>%s</body></html>""" % (css, body), loadCB)
|
||||
# ensure we're focused
|
||||
self.setFocus()
|
||||
|
|
|
@ -95,5 +95,6 @@
|
|||
<file>icons/view-pim-news.png</file>
|
||||
<file>icons/view_text.png</file>
|
||||
<file>jquery.min.js</file>
|
||||
<file>jquery.flot.min.js</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
1
designer/jquery.flot.min.js
vendored
Normal file
1
designer/jquery.flot.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue