anki/qt/aqt/models.py
Damien Elmes 5876866565 tweaking the folder names again
hopefully that's the last of it
2020-01-03 07:48:38 +10:00

222 lines
7.1 KiB
Python

# Copyright: Ankitects Pty Ltd and contributors
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import collections
from operator import itemgetter
import aqt.clayout
from anki import stdmodels
from anki.lang import _, ngettext
from aqt import AnkiQt
from aqt.qt import *
from aqt.utils import (
askUser,
getText,
maybeHideClose,
openHelp,
restoreGeom,
saveGeom,
showInfo,
)
class Models(QDialog):
def __init__(self, mw: AnkiQt, parent=None, fromMain=False):
self.mw = mw
parent = parent or mw
self.fromMain = fromMain
QDialog.__init__(self, parent, Qt.Window)
self.col = mw.col
assert self.col
self.mm = self.col.models
self.mw.checkpoint(_("Note Types"))
self.form = aqt.forms.models.Ui_Dialog()
self.form.setupUi(self)
self.form.buttonBox.helpRequested.connect(lambda: openHelp("notetypes"))
self.setupModels()
restoreGeom(self, "models")
self.exec_()
# Models
##########################################################################
def setupModels(self):
self.model = None
f = self.form
box = f.buttonBox
t = QDialogButtonBox.ActionRole
b = box.addButton(_("Add"), t)
b.clicked.connect(self.onAdd)
b = box.addButton(_("Rename"), t)
b.clicked.connect(self.onRename)
b = box.addButton(_("Delete"), t)
b.clicked.connect(self.onDelete)
if self.fromMain:
b = box.addButton(_("Fields..."), t)
b.clicked.connect(self.onFields)
b = box.addButton(_("Cards..."), t)
b.clicked.connect(self.onCards)
b = box.addButton(_("Options..."), t)
b.clicked.connect(self.onAdvanced)
f.modelsList.currentRowChanged.connect(self.modelChanged)
f.modelsList.itemDoubleClicked.connect(self.onRename)
self.updateModelsList()
f.modelsList.setCurrentRow(0)
maybeHideClose(box)
def onRename(self):
txt = getText(_("New name:"), default=self.model["name"])
if txt[1] and txt[0]:
self.model["name"] = txt[0]
self.mm.save(self.model, updateReqs=False)
self.updateModelsList()
def updateModelsList(self):
row = self.form.modelsList.currentRow()
if row == -1:
row = 0
self.models = self.col.models.all()
self.models.sort(key=itemgetter("name"))
self.form.modelsList.clear()
for m in self.models:
mUse = self.mm.useCount(m)
mUse = ngettext("%d note", "%d notes", mUse) % mUse
item = QListWidgetItem("%s [%s]" % (m["name"], mUse))
self.form.modelsList.addItem(item)
self.form.modelsList.setCurrentRow(row)
def modelChanged(self):
if self.model:
self.saveModel()
idx = self.form.modelsList.currentRow()
self.model = self.models[idx]
def onAdd(self):
m = AddModel(self.mw, self).get()
if m:
txt = getText(_("Name:"), default=m["name"])[0]
if txt:
m["name"] = txt
self.mm.ensureNameUnique(m)
self.mm.save(m)
self.updateModelsList()
def onDelete(self):
if len(self.models) < 2:
showInfo(_("Please add another note type first."), parent=self)
return
if self.mm.useCount(self.model):
msg = _("Delete this note type and all its cards?")
else:
msg = _("Delete this unused note type?")
if not askUser(msg, parent=self):
return
self.mm.rem(self.model)
self.model = None
self.updateModelsList()
def onAdvanced(self):
d = QDialog(self)
frm = aqt.forms.modelopts.Ui_Dialog()
frm.setupUi(d)
frm.latexsvg.setChecked(self.model.get("latexsvg", False))
frm.latexHeader.setText(self.model["latexPre"])
frm.latexFooter.setText(self.model["latexPost"])
d.setWindowTitle(_("Options for %s") % self.model["name"])
frm.buttonBox.helpRequested.connect(lambda: openHelp("latex"))
restoreGeom(d, "modelopts")
d.exec_()
saveGeom(d, "modelopts")
self.model["latexsvg"] = frm.latexsvg.isChecked()
self.model["latexPre"] = str(frm.latexHeader.toPlainText())
self.model["latexPost"] = str(frm.latexFooter.toPlainText())
def saveModel(self):
self.mm.save(self.model, updateReqs=False)
def _tmpNote(self):
self.mm.setCurrent(self.model)
n = self.col.newNote(forDeck=False)
for name in list(n.keys()):
n[name] = "(" + name + ")"
try:
if "{{cloze:Text}}" in self.model["tmpls"][0]["qfmt"]:
n["Text"] = _("This is a {{c1::sample}} cloze deletion.")
except:
# invalid cloze
pass
return n
def onFields(self):
from aqt.fields import FieldDialog
n = self._tmpNote()
FieldDialog(self.mw, n, parent=self)
def onCards(self):
from aqt.clayout import CardLayout
n = self._tmpNote()
CardLayout(self.mw, n, ord=0, parent=self, addMode=True)
# Cleanup
##########################################################################
# need to flush model on change or reject
def reject(self):
self.saveModel()
self.mw.reset()
saveGeom(self, "models")
QDialog.reject(self)
class AddModel(QDialog):
def __init__(self, mw, parent=None):
self.parent = parent or mw
self.mw = mw
self.col = mw.col
QDialog.__init__(self, self.parent, Qt.Window)
self.model = None
self.dialog = aqt.forms.addmodel.Ui_Dialog()
self.dialog.setupUi(self)
# standard models
self.models = []
for (name, func) in stdmodels.models:
if isinstance(name, collections.Callable):
name = name()
item = QListWidgetItem(_("Add: %s") % name)
self.dialog.models.addItem(item)
self.models.append((True, func))
# add copies
for m in sorted(self.col.models.all(), key=itemgetter("name")):
item = QListWidgetItem(_("Clone: %s") % m["name"])
self.dialog.models.addItem(item)
self.models.append((False, m))
self.dialog.models.setCurrentRow(0)
# the list widget will swallow the enter key
s = QShortcut(QKeySequence("Return"), self)
s.activated.connect(self.accept)
# help
self.dialog.buttonBox.helpRequested.connect(self.onHelp)
def get(self):
self.exec_()
return self.model
def reject(self):
QDialog.reject(self)
def accept(self):
(isStd, model) = self.models[self.dialog.models.currentRow()]
if isStd:
# create
self.model = model(self.col)
else:
# add copy to deck
self.model = self.mw.col.models.copy(model)
self.mw.col.models.setCurrent(self.model)
QDialog.accept(self)
def onHelp(self):
openHelp("notetypes")