some initial porting to the latest libanki

This commit is contained in:
Damien Elmes 2011-08-28 15:24:30 +09:00
parent 95d8690d34
commit 18812655ab
10 changed files with 63 additions and 68 deletions

View file

@ -8,7 +8,7 @@ import aqt.forms
import anki
from anki.facts import Fact
from anki.errors import *
from anki.utils import stripHTML, parseTags
from anki.utils import stripHTML
from aqt.utils import saveGeom, restoreGeom, showWarning, askUser, shortcut, \
tooltip
from anki.sound import clearAudioQueue
@ -78,7 +78,7 @@ class AddCards(QDialog):
# FIXME: need to make sure to clean up fact on exit
def setupNewFact(self, set=True):
f = self.mw.deck.newFact()
f.tags = f.model().conf['tags']
f.tags = f.model()['tags']
if set:
self.editor.setFact(f)
return f
@ -86,7 +86,7 @@ class AddCards(QDialog):
def onReset(self, model=None, keep=False):
oldFact = self.editor.fact
fact = self.setupNewFact(set=False)
flds = fact.model().fields
flds = fact.model()['flds']
# copy fields from old fact
if oldFact:
if not keep:
@ -105,7 +105,7 @@ class AddCards(QDialog):
if not fact or not fact.id:
return
# we don't have to worry about cards; just the fact
self.mw.deck._delFacts([fact.id])
self.mw.deck._remFacts([fact.id])
def addHistory(self, fact):
txt = stripHTMLMedia(",".join(fact.fields))[:30]

View file

@ -7,8 +7,7 @@ from aqt.qt import *
import time, types, sys, re
from operator import attrgetter, itemgetter
import anki, anki.utils, aqt.forms
from anki.utils import fmtTimeSpan, parseTags, hasTag, addTags, delTags, \
ids2str, stripHTMLMedia, isWin, intTime
from anki.utils import fmtTimeSpan, ids2str, stripHTMLMedia, isWin, intTime
from aqt.utils import saveGeom, restoreGeom, saveSplitter, restoreSplitter, \
saveHeader, restoreHeader, saveState, restoreState, applyStyles, getTag, \
showInfo, askUser, tooltip
@ -207,13 +206,13 @@ class DeckModel(QAbstractTableModel):
return self.answer()
elif type == "factFld":
f = c.fact()
return self.formatQA(f.fields[f.model().sortIdx()])
return self.formatQA(f.fields[self.deck.models.sortIdx(f.model())])
elif type == "template":
return c.template()['name']
elif type == "cardDue":
return self.nextDue(c, index)
elif type == "factCrt":
return time.strftime("%Y-%m-%d", time.localtime(c.fact().crt))
return time.strftime("%Y-%m-%d", time.localtime(c.fact().id/1000))
elif type == "factMod":
return time.strftime("%Y-%m-%d", time.localtime(c.fact().mod))
elif type == "cardMod":
@ -231,9 +230,9 @@ class DeckModel(QAbstractTableModel):
return _("(new)")
return "%d%%" % (c.factor/10)
elif type == "cardGroup":
return self.browser.mw.deck.groupName(c.gid)
return self.browser.mw.deck.groups.name(c.gid)
elif type == "factGroup":
return self.browser.mw.deck.groupName(c.fact().gid)
return self.browser.mw.deck.groups.name(c.fact().gid)
def question(self):
return self.formatQA(c.a())
@ -650,15 +649,15 @@ class Browser(QMainWindow):
self.onSearch()
def _modelTree(self, root):
for m in sorted(self.deck.models().values(), key=attrgetter("name")):
for m in sorted(self.deck.models.all(), key=itemgetter("name")):
mitem = self.CallbackItem(
m.name, lambda m=m: self.setFilter("model", m.name))
m['name'], lambda m=m: self.setFilter("model", m['name']))
mitem.setIcon(0, QIcon(":/icons/product_design.png"))
root.addChild(mitem)
for t in m.templates:
for t in m['tmpls']:
titem = self.CallbackItem(
t['name'], lambda m=m, t=t: self.setFilter(
"model", m.name, "card", t['name']))
"model", m['name'], "card", t['name']))
titem.setIcon(0, QIcon(":/icons/stock_new_template.png"))
mitem.addChild(titem)
@ -695,7 +694,7 @@ class Browser(QMainWindow):
return root
def _userTagTree(self, root):
for t in self.deck.tagList():
for t in sorted(self.deck.tags.all()):
item = self.CallbackItem(
t, lambda t=t: self.setFilter("tag", t))
item.setIcon(0, QIcon(":/icons/anki-tag.png"))
@ -718,7 +717,7 @@ class Browser(QMainWindow):
rep = "<style>table * { font-size: 12px; }</style>" + rep
m = self.card.model()
# add sort field
sortf = m.fields[m.sortIdx()]['name']
sortf = m['flds'][self.mw.deck.models.sortIdx(m)]['name']
extra = self.cardStats.makeLine(
_("Sort Field"), "<a href=sort>%s</a>" % sortf)
# and revlog
@ -895,7 +894,7 @@ where id in %s""" % ids2str(sf))
self.mw.checkpoint(_("Set Group"))
mod = intTime()
if frm.setCur.isChecked():
gid = self.deck.groupId(unicode(te.text()))
gid = self.deck.groups.id(unicode(te.text()))
self.deck.db.execute(
"update cards set mod=?, gid=? where id in " + ids2str(
self.selectedCards()), mod, gid)
@ -924,7 +923,7 @@ where id in %s""" % ids2str(self.selectedCards()), mod)
if not r:
return
if func is None:
func = self.deck.addTags
func = self.deck.tags.bulkAdd
self.model.beginReset()
if label is None:
label = _("Add Tags")
@ -939,7 +938,7 @@ where id in %s""" % ids2str(self.selectedCards()), mod)
if label is None:
label = _("Delete Tags")
self.addTags(tags, label, _("Enter tags to delete:"),
func=self.deck.delTags)
func=self.deck.tags.bulkRem)
# Suspending and marking
######################################################################

View file

@ -28,10 +28,11 @@ class CardLayout(QDialog):
self.type = type
self.ord = ord
self.deck = self.mw.deck
self.mm = self.mw.deck.models
self.model = fact.model()
self.form = aqt.forms.clayout.Ui_Dialog()
self.form.setupUi(self)
self.setWindowTitle(_("%s Layout") % self.model.name)
self.setWindowTitle(_("%s Layout") % self.model['name'])
self.plastiqueStyle = None
if isMac or isWin:
self.plastiqueStyle = QStyleFactory.create("plastique")
@ -113,7 +114,7 @@ class CardLayout(QDialog):
if self.plastiqueStyle:
f.background.setStyle(self.plastiqueStyle)
f.alignment.addItems(alignmentLabels().values())
self.typeFieldNames = self.model.fieldMap()
self.typeFieldNames = self.mm.fieldMap(self.model)
s = [_("Don't ask me to type in the answer")]
s += [_("Compare with field '%s'") % fi
for fi in self.typeFieldNames.keys()]
@ -161,7 +162,7 @@ class CardLayout(QDialog):
else:
f.typeAnswer.setCurrentIndex(t['typeAns'] + 1)
# model-level, but there's nowhere else to put this
f.clozectx.setChecked(self.model.conf['clozectx'])
f.clozectx.setChecked(self.model['clozectx'])
self.updatingCards = False
def fillCardList(self):
@ -198,7 +199,7 @@ class CardLayout(QDialog):
t['typeAns'] = None
else:
t['typeAns'] = idx-1
self.model.conf['clozectx'] = self.form.clozectx.isChecked()
self.model['clozectx'] = self.form.clozectx.isChecked()
self.renderPreview()
def chooseColour(self, button, type="field"):
@ -214,7 +215,7 @@ class CardLayout(QDialog):
def renderPreview(self):
c = self.card
styles = self.model.genCSS()
styles = self.model['css']
styles += "\n.cloze { font-weight: bold; color: blue; }"
self.form.preview.setHtml(
('<html><head>%s</head><body class="%s">' %
@ -240,13 +241,12 @@ class CardLayout(QDialog):
self.reject()
def reject(self):
self.model.flush()
self.mm.save(self.model)
saveGeom(self, "CardLayout")
saveSplitter(self.form.splitter, "clayout")
self.mw.reset()
return QDialog.reject(self)
self.fact.model.setModified()
modified = False
self.mw.startProgress()
@ -312,7 +312,7 @@ class CardLayout(QDialog):
row = self.form.fieldList.currentRow()
if row == -1:
row = 0
self.field = self.model.fields[row]
self.field = self.model['flds'][row]
self.readField()
self.enableFieldMoveButtons()
@ -355,7 +355,7 @@ class CardLayout(QDialog):
fld['sticky'] = self.form.sticky.isChecked()
self.updatingFields = False
if fld['name'] != name:
self.model.renameField(fld, name)
self.mm.renameField(self.model, fld, name)
# as the field name has changed, we have to regenerate cards
self.cards = self.deck.previewCards(self.fact, self.type)
self.cardChanged(0)
@ -368,7 +368,7 @@ class CardLayout(QDialog):
oldRow = 0
self.form.fieldList.clear()
n = 1
for field in self.model.fields:
for field in self.model['flds']:
label = field['name']
item = QListWidgetItem(label)
self.form.fieldList.addItem(item)
@ -394,11 +394,11 @@ class CardLayout(QDialog):
self.form.fieldDown.setEnabled(True)
def addField(self):
f = self.model.newField()
l = len(self.model.fields)
f = self.mm.newField(self.model)
l = len(self.model['flds'])
f['name'] = _("Field %d") % l
self.mw.progress.start()
self.model.addField(f)
self.mm.addField(self.model, f)
self.mw.progress.finish()
self.reload()
self.form.fieldList.setCurrentRow(l)

View file

@ -4,7 +4,7 @@
from aqt.qt import *
import re, os, sys, urllib2, ctypes, simplejson, traceback
from anki.utils import stripHTML, parseTags, isWin, namedtmp
from anki.utils import stripHTML, isWin, namedtmp
from anki.sound import play
from anki.hooks import runHook
from aqt.sound import getAudio
@ -397,7 +397,7 @@ class Editor(object):
def fonts(self):
return [(f['font'], f['esize'])
for f in self.fact.model().fields]
for f in self.fact.model()['flds']]
def saveNow(self):
"Must call this before adding cards, closing dialog, etc."
@ -499,19 +499,19 @@ class Editor(object):
gid = self.fact.gid
else:
gid = self.fact.model().conf['gid']
self.group.setText(self.mw.deck.groupName(gid))
self.group.setText(self.mw.deck.groups.name(gid))
def saveTagsAndGroup(self):
if not self.fact:
return
self.fact.tags = parseTags(unicode(self.tags.text()))
self.fact.tags = self.mw.deck.tags.split(unicode(self.tags.text()))
if self.addMode:
# save group and tags to model
self.fact.gid = self.mw.deck.groupId(unicode(self.group.text()))
self.fact.gid = self.mw.deck.groups.id(unicode(self.group.text()))
m = self.fact.model()
m.conf['gid'] = self.fact.gid
m.conf['tags'] = self.fact.tags
m.flush()
m['gid'] = self.fact.gid
m['tags'] = self.fact.tags
self.mw.deck.models.save(m)
self.fact.flush()
runHook("tagsAndGroupUpdated", self.fact)

View file

@ -167,21 +167,19 @@ class Groups(QDialog):
if len(gids) == self.gidCount:
# all enabled is same as empty
gids = []
if gids != self.mw.deck.qconf['groups']:
self.mw.deck.qconf['groups'] = gids
if gids != self.mw.deck.conf['groups']:
self.mw.deck.conf['groups'] = gids
self.mw.reset()
QDialog.accept(self)
def _makeItems(self, grps):
self.gidCount = 0
on = {}
if not self.mw.deck.qconf['groups']:
if not self.mw.deck.conf['groups']:
on = None
else:
for gid in self.mw.deck.qconf['groups']:
for gid in self.mw.deck.conf['groups']:
on[gid] = True
self.confMap = dict(self.mw.deck.db.all(
"select g.id, gc.name from groups g, gconf gc where g.gcid=gc.id"))
grey = QBrush(QColor(GREY))
def makeItems(grp, head=""):
branch = QTreeWidgetItem()
@ -197,7 +195,7 @@ class Groups(QDialog):
branch.setCheckState(COLCHECK, Qt.Unchecked)
branch.setText(COLNAME, grp[0])
if gid:
branch.setText(COLOPTS, self.confMap[gid])
branch.setText(COLOPTS, self.mw.deck.groups.name(gid))
branch.setText(COLCOUNT, str(grp[2]))
branch.setText(COLDUE, str(grp[3]))
branch.setText(COLNEW, str(grp[4]))

View file

@ -11,8 +11,7 @@ QtConfig = pyqtconfig.Configuration()
from anki import Deck
from anki.sound import playFromText, clearAudioQueue, stripSounds
from anki.utils import addTags, parseTags, canonifyTags, stripHTML, \
checksum, isWin, isMac
from anki.utils import stripHTML, checksum, isWin, isMac
from anki.hooks import runHook, addHook, removeHook
import anki.consts

View file

@ -2,7 +2,7 @@
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
from aqt.qt import *
from operator import attrgetter
from operator import itemgetter
from anki import stdmodels
from anki.lang import ngettext
from anki.hooks import addHook, removeHook, runHook
@ -91,11 +91,11 @@ class ModelChooser(QHBoxLayout):
def updateModels(self):
self.models.clear()
self._models = sorted(self.deck.models().values(),
key=attrgetter("name"))
self.models.addItems([m.name for m in self._models])
self._models = sorted(self.deck.models.all(),
key=itemgetter("name"))
self.models.addItems([m['name'] for m in self._models])
for c, m in enumerate(self._models):
if m.id == self.deck.conf['currentModelId']:
if m['id'] == str(self.deck.conf['currentModelId']):
self.models.setCurrentIndex(c)
break
@ -106,8 +106,8 @@ class ModelChooser(QHBoxLayout):
for s in self.cardShortcuts:
s.setEnabled(False)
self.cardShortcuts = []
m = self.deck.currentModel()
ts = m.templates
m = self.deck.models.current()
ts = m['tmpls']
active = [t['name'] for t in ts if t['actv']]
txt = ngettext("%d card", "%d cards", len(active)) % len(active)
self.cards.setText(txt)
@ -121,7 +121,7 @@ class ModelChooser(QHBoxLayout):
def onCardChange(self):
m = QMenu(self.widget)
model = self.deck.currentModel()
model = self.deck.models.current()
for template in model.templates:
action = QAction(self.widget)
action.setCheckable(True)
@ -135,7 +135,7 @@ class ModelChooser(QHBoxLayout):
m.exec_(self.cards.mapToGlobal(QPoint(0,0)))
def canDisableTemplate(self):
return len([t for t in self.deck.currentModel().templates
return len([t for t in self.deck.models.current()['tmpls']
if t['actv']]) > 1
def toggleTemplate(self, card):
@ -143,7 +143,7 @@ class ModelChooser(QHBoxLayout):
card['actv'] = True
elif self.canDisableTemplate():
card['actv'] = False
self.deck.currentModel().flush()
self.deck.models.current().flush()
self.updateTemplates()
class AddModel(QDialog):
@ -166,9 +166,9 @@ class AddModel(QDialog):
mids = self.deck.db.list("select id from models order by name")
for m in [self.deck.getModel(mid, False) for mid in mids]:
m.id = None
item = QListWidgetItem(_("Copy: %s") % m.name)
item = QListWidgetItem(_("Copy: %s") % m['name'])
self.dialog.models.addItem(item)
m.name = _("%s copy") % m.name
m['name'] = _("%s copy") % m['name']
self.models.append((False, m))
self.dialog.models.setCurrentRow(0)
# the list widget will swallow the enter key

View file

@ -373,7 +373,7 @@ div#filler {
def _styles(self):
css = self.mw.sharedCSS
css += self.mw.deck.allCSS()
css += self.mw.deck.models.css()
css += self._css
return css

View file

@ -31,7 +31,7 @@ class StudyOptions(QDialog):
def load(self):
f = self.form
d = self.mw.deck
qc = d.qconf
qc = d.conf
f.newPerDay.setValue(qc['newPerDay'])
f.newOrder.setCurrentIndex(qc['newOrder'])
f.newSpread.setCurrentIndex(qc['newSpread'])
@ -48,7 +48,7 @@ class StudyOptions(QDialog):
def accept(self):
f = self.form
d = self.mw.deck
qc = d.qconf
qc = d.conf
old = qc['newOrder']
qc['newOrder'] = f.newOrder.currentIndex()
self.updateNewOrder(old, qc['newOrder'])

View file

@ -2,7 +2,6 @@
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
from aqt.qt import *
from anki.utils import parseTags, canonifyTags, joinTags
import re, sys
class TagEdit(QLineEdit):
@ -25,9 +24,9 @@ class TagEdit(QLineEdit):
"Set the current deck, updating list of available tags."
self.deck = deck
if self.type == 0:
l = self.deck.tagList()
l = sorted(self.deck.tags.all())
else:
l = self.deck.groups()
l = self.deck.groups.all()
self.model.setStringList(l)
def addTags(self, tags):
@ -51,7 +50,7 @@ class TagCompleter(QCompleter):
def splitPath(self, str):
str = unicode(str).strip()
str = re.sub(" +", " ", str)
self.tags = parseTags(str)
self.tags = self.parent.deck.tags.split(str)
self.tags.append(u"")
p = self.edit.cursorPosition()
self.cursor = str.count(" ", 0, p)