mirror of
https://github.com/ankitects/anki.git
synced 2025-09-25 01:06:35 -04:00
store the ordinals in templates/fields
this makes it more convenient to pass around templates/fields without having to instrument them with their position in the list
This commit is contained in:
parent
e6a8f7f619
commit
d5cce19b56
3 changed files with 41 additions and 37 deletions
39
anki/deck.py
39
anki/deck.py
|
@ -217,10 +217,10 @@ qconf=?, conf=?, data=?""",
|
||||||
def findTemplates(self, fact, checkActive=True):
|
def findTemplates(self, fact, checkActive=True):
|
||||||
"Return active, non-empty templates."
|
"Return active, non-empty templates."
|
||||||
ok = []
|
ok = []
|
||||||
for c, template in enumerate(fact.model.templates):
|
for template in fact.model.templates:
|
||||||
if template['actv'] or not checkActive:
|
if template['actv'] or not checkActive:
|
||||||
# [cid, fid, mid, gid, ord, tags, flds, data]
|
# [cid, fid, mid, gid, ord, tags, flds, data]
|
||||||
data = [1, 1, fact.model.id, 1, c,
|
data = [1, 1, fact.model.id, 1, template['ord'],
|
||||||
"", fact.joinedFields(), ""]
|
"", fact.joinedFields(), ""]
|
||||||
now = self._renderQA(fact.model, "", data)
|
now = self._renderQA(fact.model, "", data)
|
||||||
data[6] = "\x1f".join([""]*len(fact._fields))
|
data[6] = "\x1f".join([""]*len(fact._fields))
|
||||||
|
@ -230,21 +230,19 @@ qconf=?, conf=?, data=?""",
|
||||||
if not template['emptyAns']:
|
if not template['emptyAns']:
|
||||||
if now['a'] == empty['a']:
|
if now['a'] == empty['a']:
|
||||||
continue
|
continue
|
||||||
# add ordinal
|
|
||||||
template['ord'] = c
|
|
||||||
ok.append(template)
|
ok.append(template)
|
||||||
return ok
|
return ok
|
||||||
|
|
||||||
def addCards(self, fact, tids):
|
def genCards(self, fact, templates):
|
||||||
|
"Generate cards for templates if cards not empty."
|
||||||
|
# templates should have .ord set
|
||||||
ids = []
|
ids = []
|
||||||
for template in self.findTemplates(fact, False):
|
for template in self.findTemplates(fact, False):
|
||||||
if template.id not in tids:
|
if template not in templates:
|
||||||
continue
|
continue
|
||||||
if self.db.scalar("""
|
if not self.db.scalar(
|
||||||
select count(id) from cards
|
"select 1 from cards where fid = ? and ord = ?",
|
||||||
where fid = :fid and tid = :cmid""",
|
fact.id, template.ord):
|
||||||
fid=fact.id, cmid=template.id) == 0:
|
|
||||||
# enough for 10 card models assuming 0.00001 timer precision
|
|
||||||
card = anki.cards.Card(
|
card = anki.cards.Card(
|
||||||
fact, template,
|
fact, template,
|
||||||
fact.created+0.0001*template.ord)
|
fact.created+0.0001*template.ord)
|
||||||
|
@ -257,19 +255,6 @@ where fid = :fid and tid = :cmid""",
|
||||||
self.setMod()
|
self.setMod()
|
||||||
return ids
|
return ids
|
||||||
|
|
||||||
def factIsInvalid(self, fact):
|
|
||||||
"True if existing fact is invalid. Returns the error."
|
|
||||||
try:
|
|
||||||
fact.assertValid()
|
|
||||||
fact.assertUnique(self.db)
|
|
||||||
except FactInvalidError, e:
|
|
||||||
return e
|
|
||||||
|
|
||||||
def factUseCount(self, fid):
|
|
||||||
"Return number of cards referencing a given fact id."
|
|
||||||
return self.db.scalar("select count(id) from cards where fid = :id",
|
|
||||||
id=fid)
|
|
||||||
|
|
||||||
def _deleteFacts(self, ids):
|
def _deleteFacts(self, ids):
|
||||||
"Bulk delete facts by ID. Don't call this directly."
|
"Bulk delete facts by ID. Don't call this directly."
|
||||||
if not ids:
|
if not ids:
|
||||||
|
@ -478,9 +463,9 @@ select id from cards where fid in (select id from facts where mid = ?)""",
|
||||||
fields = splitFields(flds)
|
fields = splitFields(flds)
|
||||||
model = mods[mid]
|
model = mods[mid]
|
||||||
if csum:
|
if csum:
|
||||||
for c, f in enumerate(model.fields):
|
for f in model.fields:
|
||||||
if f['uniq'] and fields[c]:
|
if f['uniq'] and fields[f['ord']]:
|
||||||
r.append((fid, mid, fieldChecksum(fields[c])))
|
r.append((fid, mid, fieldChecksum(fields[f['ord']])))
|
||||||
r2.append((stripHTML(fields[model.sortIdx()])[
|
r2.append((stripHTML(fields[model.sortIdx()])[
|
||||||
:SORT_FIELD_LEN], fid))
|
:SORT_FIELD_LEN], fid))
|
||||||
if csum:
|
if csum:
|
||||||
|
|
|
@ -16,6 +16,7 @@ defaultConf = {
|
||||||
|
|
||||||
defaultField = {
|
defaultField = {
|
||||||
'name': "",
|
'name': "",
|
||||||
|
'ord': None,
|
||||||
'rtl': False,
|
'rtl': False,
|
||||||
'req': False,
|
'req': False,
|
||||||
'uniq': False,
|
'uniq': False,
|
||||||
|
@ -28,6 +29,7 @@ defaultField = {
|
||||||
|
|
||||||
defaultTemplate = {
|
defaultTemplate = {
|
||||||
'name': "",
|
'name': "",
|
||||||
|
'ord': None,
|
||||||
'actv': True,
|
'actv': True,
|
||||||
'qfmt': "",
|
'qfmt': "",
|
||||||
'afmt': "",
|
'afmt': "",
|
||||||
|
@ -101,14 +103,14 @@ insert or replace into models values (?, ?, ?, ?, ?, ?, ?)""",
|
||||||
return ""
|
return ""
|
||||||
# fields
|
# fields
|
||||||
css = "".join([self._fieldCSS(
|
css = "".join([self._fieldCSS(
|
||||||
".fm%s.%s" % (hexifyID(self.id), hexifyID(c)),
|
".fm%s.%s" % (hexifyID(self.id), hexifyID(f['ord'])),
|
||||||
(f['font'], f['qsize'], f['qcol'], f['rtl'], f['pre']))
|
(f['font'], f['qsize'], f['qcol'], f['rtl'], f['pre']))
|
||||||
for c, f in enumerate(self.fields)])
|
for f in self.fields])
|
||||||
# templates
|
# templates
|
||||||
css += "".join(["#cm%s-%s {text-align:%s;background:%s}\n" % (
|
css += "".join(["#cm%s-%s {text-align:%s;background:%s}\n" % (
|
||||||
hexifyID(self.id), hexifyID(c),
|
hexifyID(self.id), hexifyID(t['ord']),
|
||||||
("center", "left", "right")[t['align']], t['bg'])
|
("center", "left", "right")[t['align']], t['bg'])
|
||||||
for c, t in enumerate(self.templates)])
|
for t in self.templates])
|
||||||
return css
|
return css
|
||||||
|
|
||||||
def _rewriteFont(self, font):
|
def _rewriteFont(self, font):
|
||||||
|
@ -136,8 +138,8 @@ insert or replace into models values (?, ?, ?, ?, ?, ?, ?)""",
|
||||||
##################################################
|
##################################################
|
||||||
|
|
||||||
def fieldMap(self):
|
def fieldMap(self):
|
||||||
"Mapping of field name -> (ord, conf)."
|
"Mapping of field name -> (ord, field)."
|
||||||
return dict([(f['name'], (c, f)) for c, f in enumerate(self.fields)])
|
return dict([(f['name'], (f['ord'], f)) for f in self.fields])
|
||||||
|
|
||||||
def sortIdx(self):
|
def sortIdx(self):
|
||||||
return self.conf['sortf']
|
return self.conf['sortf']
|
||||||
|
@ -152,6 +154,7 @@ insert or replace into models values (?, ?, ?, ?, ?, ?, ?)""",
|
||||||
|
|
||||||
def addField(self, field):
|
def addField(self, field):
|
||||||
self.fields.append(field)
|
self.fields.append(field)
|
||||||
|
self._updateFieldOrds()
|
||||||
self.flush()
|
self.flush()
|
||||||
def add(fields):
|
def add(fields):
|
||||||
fields.append("")
|
fields.append("")
|
||||||
|
@ -161,7 +164,7 @@ insert or replace into models values (?, ?, ?, ?, ?, ?, ?)""",
|
||||||
def delField(self, field):
|
def delField(self, field):
|
||||||
idx = self.fields.index(field)
|
idx = self.fields.index(field)
|
||||||
self.fields.remove(field)
|
self.fields.remove(field)
|
||||||
self.flush()
|
self._updateFieldOrds()
|
||||||
def delete(fields):
|
def delete(fields):
|
||||||
del fields[idx]
|
del fields[idx]
|
||||||
return fields
|
return fields
|
||||||
|
@ -169,6 +172,7 @@ insert or replace into models values (?, ?, ?, ?, ?, ?, ?)""",
|
||||||
if idx == self.sortIdx():
|
if idx == self.sortIdx():
|
||||||
# need to rebuild
|
# need to rebuild
|
||||||
self.deck.updateFieldCache(self.fids(), csum=False)
|
self.deck.updateFieldCache(self.fids(), csum=False)
|
||||||
|
# flushes
|
||||||
self.renameField(field, None)
|
self.renameField(field, None)
|
||||||
|
|
||||||
def moveField(self, field, idx):
|
def moveField(self, field, idx):
|
||||||
|
@ -177,6 +181,7 @@ insert or replace into models values (?, ?, ?, ?, ?, ?, ?)""",
|
||||||
return
|
return
|
||||||
self.fields.remove(field)
|
self.fields.remove(field)
|
||||||
self.fields.insert(idx, field)
|
self.fields.insert(idx, field)
|
||||||
|
self._updateFieldOrds()
|
||||||
self.flush()
|
self.flush()
|
||||||
def move(fields, oldidx=oldidx):
|
def move(fields, oldidx=oldidx):
|
||||||
val = fields[oldidx]
|
val = fields[oldidx]
|
||||||
|
@ -200,6 +205,10 @@ insert or replace into models values (?, ?, ?, ?, ?, ?, ?)""",
|
||||||
field['name'] = newName
|
field['name'] = newName
|
||||||
self.flush()
|
self.flush()
|
||||||
|
|
||||||
|
def _updateFieldOrds(self):
|
||||||
|
for c, f in enumerate(self.fields):
|
||||||
|
f['ord'] = c
|
||||||
|
|
||||||
def _transformFields(self, fn):
|
def _transformFields(self, fn):
|
||||||
self.deck.startProgress()
|
self.deck.startProgress()
|
||||||
self.deck.modSchema()
|
self.deck.modSchema()
|
||||||
|
@ -219,6 +228,8 @@ insert or replace into models values (?, ?, ?, ?, ?, ?, ?)""",
|
||||||
def addTemplate(self, template):
|
def addTemplate(self, template):
|
||||||
self.deck.modSchema()
|
self.deck.modSchema()
|
||||||
self.templates.append(template)
|
self.templates.append(template)
|
||||||
|
self._updateTemplOrds()
|
||||||
|
self.flush()
|
||||||
|
|
||||||
def delTemplate(self, template):
|
def delTemplate(self, template):
|
||||||
self.deck.modSchema()
|
self.deck.modSchema()
|
||||||
|
@ -232,8 +243,13 @@ select c.id from cards c, facts f where c.fid=f.id and mid = ? and ord = ?""",
|
||||||
update cards set ord = ord - 1 where fid in (select id from facts
|
update cards set ord = ord - 1 where fid in (select id from facts
|
||||||
where mid = ?) and ord > ?""", self.id, ord)
|
where mid = ?) and ord > ?""", self.id, ord)
|
||||||
self.templates.remove(template)
|
self.templates.remove(template)
|
||||||
|
self._updateTemplOrds()
|
||||||
self.flush()
|
self.flush()
|
||||||
|
|
||||||
|
def _updateTemplOrds(self):
|
||||||
|
for c, t in enumerate(self.templates):
|
||||||
|
t['ord'] = c
|
||||||
|
|
||||||
# Model changing
|
# Model changing
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
|
|
|
@ -454,11 +454,15 @@ questionAlign, lastFontColour, allowEmptyAnswer, typeAnswer from cardModels"""):
|
||||||
db.execute("drop table cardModels")
|
db.execute("drop table cardModels")
|
||||||
return mods
|
return mods
|
||||||
|
|
||||||
def _rewriteModelIds(deck):
|
def _fixupModels(deck):
|
||||||
# rewrite model/template/field ids
|
# rewrite model/template/field ids
|
||||||
models = deck.models()
|
models = deck.models()
|
||||||
deck.db.execute("delete from models")
|
deck.db.execute("delete from models")
|
||||||
for c, m in enumerate(models.values()):
|
for c, m in enumerate(models.values()):
|
||||||
|
# update ordinals
|
||||||
|
m._updateFieldOrds()
|
||||||
|
m._updateTemplOrds()
|
||||||
|
# rewrite id
|
||||||
old = m.id
|
old = m.id
|
||||||
m.id = c+1
|
m.id = c+1
|
||||||
m.flush()
|
m.flush()
|
||||||
|
@ -467,8 +471,7 @@ def _rewriteModelIds(deck):
|
||||||
def _postSchemaUpgrade(deck):
|
def _postSchemaUpgrade(deck):
|
||||||
"Handle the rest of the upgrade to 2.0."
|
"Handle the rest of the upgrade to 2.0."
|
||||||
import anki.deck
|
import anki.deck
|
||||||
# fix up model/template ids
|
_fixupModels(deck)
|
||||||
_rewriteModelIds(deck)
|
|
||||||
# update uniq cache
|
# update uniq cache
|
||||||
deck.updateFieldCache(deck.db.list("select id from facts"))
|
deck.updateFieldCache(deck.db.list("select id from facts"))
|
||||||
# remove old views
|
# remove old views
|
||||||
|
|
Loading…
Reference in a new issue