mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 08:46:37 -04:00
primarily work on browser
This commit is contained in:
parent
6f4e0d6ef9
commit
23411c2872
9 changed files with 67 additions and 172 deletions
|
@ -201,9 +201,9 @@ class DataModel(QAbstractTableModel):
|
|||
type = self.columnType(col)
|
||||
c = self.getCard(index)
|
||||
if type == "question":
|
||||
return self.question()
|
||||
return self.question(c)
|
||||
elif type == "answer":
|
||||
return self.answer()
|
||||
return self.answer(c)
|
||||
elif type == "noteFld":
|
||||
f = c.note()
|
||||
return self.formatQA(f.fields[self.col.models.sortIdx(f.model())])
|
||||
|
@ -234,10 +234,10 @@ class DataModel(QAbstractTableModel):
|
|||
elif type == "noteGroup":
|
||||
return self.browser.mw.col.groups.name(c.note().gid)
|
||||
|
||||
def question(self):
|
||||
def question(self, c):
|
||||
return self.formatQA(c.a())
|
||||
|
||||
def answer(self):
|
||||
def answer(self, c):
|
||||
return self.formatQA(c.a())
|
||||
|
||||
def formatQA(self, txt):
|
||||
|
@ -332,8 +332,7 @@ class Browser(QMainWindow):
|
|||
self.onSearch()
|
||||
|
||||
def setupToolbar(self):
|
||||
self.form.toolBar.setIconSize(QSize(self.mw.pm.profile['iconSize'],
|
||||
self.mw.pm.profile['iconSize']))
|
||||
self.form.toolBar.setIconSize(QSize(32, 32))
|
||||
self.form.toolBar.toggleViewAction().setText(_("Toggle Toolbar"))
|
||||
|
||||
def setupMenus(self):
|
||||
|
@ -341,13 +340,12 @@ class Browser(QMainWindow):
|
|||
c = self.connect; f = self.form; s = SIGNAL("triggered()")
|
||||
c(f.actionAddItems, s, self.mw.onAddCard)
|
||||
c(f.actionDelete, s, self.deleteCards)
|
||||
c(f.actionSetGroup, s, self.setGroup)
|
||||
#c(f.actionSetGroup, s, self.setGroup)
|
||||
c(f.actionAddTag, s, self.addTags)
|
||||
c(f.actionDeleteTag, s, self.deleteTags)
|
||||
c(f.actionReposition, s, self.reposition)
|
||||
c(f.actionReschedule, s, self.reschedule)
|
||||
c(f.actionCram, s, self.cram)
|
||||
c(f.actionAddCards, s, self.genCards)
|
||||
c(f.actionChangeModel, s, self.onChangeModel)
|
||||
c(f.actionToggleSuspend, SIGNAL("triggered(bool)"), self.onSuspend)
|
||||
c(f.actionToggleMark, SIGNAL("triggered(bool)"), self.onMark)
|
||||
|
@ -662,7 +660,7 @@ class Browser(QMainWindow):
|
|||
mitem.addChild(titem)
|
||||
|
||||
def _groupTree(self, root):
|
||||
grps = self.col.sched.groupTree()
|
||||
grps = self.col.sched.deckDueTree()
|
||||
def fillGroups(root, grps, head=""):
|
||||
for g in grps:
|
||||
item = self.CallbackItem(
|
||||
|
@ -725,6 +723,8 @@ class Browser(QMainWindow):
|
|||
extra += self.cardStats.makeLine(
|
||||
_("Reviews"), "<a href=revlog>%d</a>" % self.card.reps)
|
||||
rep = rep.replace("</table>", extra)
|
||||
self.form.cardLabel.setMaximumWidth(250)
|
||||
self.form.cardLabel.setWordWrap(True)
|
||||
self.form.cardLabel.setText(rep)
|
||||
|
||||
def onCardLink(self, url):
|
||||
|
@ -750,7 +750,7 @@ class Browser(QMainWindow):
|
|||
d = QDialog(self)
|
||||
l = QVBoxLayout()
|
||||
l.setMargin(0)
|
||||
w = AnkiWebView(self.mw)
|
||||
w = AnkiWebView()
|
||||
l.addWidget(w)
|
||||
w.stdHtml(data)
|
||||
bb = QDialogButtonBox(QDialogButtonBox.Close)
|
||||
|
|
|
@ -10,7 +10,6 @@ from aqt.utils import saveGeom, restoreGeom, getBase, mungeQA, \
|
|||
saveSplitter, restoreSplitter, showInfo, askUser, getOnlyText, \
|
||||
showWarning, openHelp
|
||||
from anki.utils import isMac, isWin
|
||||
import aqt.templates
|
||||
|
||||
# raise Exception("Remember to disallow media&latex refs in edit.")
|
||||
|
||||
|
@ -106,21 +105,21 @@ Please create a new card first."""))
|
|||
help = QPushButton(_("Help"))
|
||||
help.setAutoDefault(False)
|
||||
l.addWidget(help)
|
||||
c(l, SIGNAL("clicked()"), self.onHelp)
|
||||
c(help, SIGNAL("clicked()"), self.onHelp)
|
||||
l.addStretch()
|
||||
rename = QPushButton(_("Rename"))
|
||||
rename.setAutoDefault(False)
|
||||
l.addWidget(rename)
|
||||
c(l, SIGNAL("clicked()"), self.onRename)
|
||||
c(rename, SIGNAL("clicked()"), self.onRename)
|
||||
repos = QPushButton(_("Reposition"))
|
||||
repos.setAutoDefault(False)
|
||||
l.addWidget(repos)
|
||||
c(l, SIGNAL("clicked()"), self.onReorder)
|
||||
c(repos, SIGNAL("clicked()"), self.onReorder)
|
||||
l.addStretch()
|
||||
close = QPushButton(_("Close"))
|
||||
close.setAutoDefault(False)
|
||||
l.addWidget(close)
|
||||
c(l, SIGNAL("clicked()"), self.accept)
|
||||
c(close, SIGNAL("clicked()"), self.accept)
|
||||
|
||||
# Cards
|
||||
##########################################################################
|
||||
|
@ -158,16 +157,19 @@ Please create a new card first."""))
|
|||
c = self.card
|
||||
styles = "\n.cloze { font-weight: bold; color: blue; }"
|
||||
html = '<html><body id=card><style>%s</style>%s</body></html>'
|
||||
ti = self.maybeTextInput
|
||||
self.tab['pform'].front.setHtml(
|
||||
html % (styles, mungeQA(c.q(reload=True))))
|
||||
html % (styles, ti(mungeQA(c.q(reload=True)))))
|
||||
self.tab['pform'].back.setHtml(
|
||||
html % (styles, mungeQA(c.a())))
|
||||
html % (styles, ti(mungeQA(c.a()), 'a')))
|
||||
|
||||
def maybeTextInput(self):
|
||||
return "text input"
|
||||
if self.card.template()['typeAns'] is not None:
|
||||
return "<center><input type=text></center>"
|
||||
return ""
|
||||
def maybeTextInput(self, txt, type='q'):
|
||||
if type == 'q':
|
||||
repl = "<center><input type=text value='%s'></center>" % _(
|
||||
"(text is typed in here)")
|
||||
else:
|
||||
repl = _("(typing comparison appears here)")
|
||||
return re.sub("\[\[type:.+?\]\]", repl, txt)
|
||||
|
||||
# Card operations
|
||||
######################################################################
|
||||
|
|
|
@ -28,7 +28,7 @@ _html = """
|
|||
.field {
|
||||
border: 1px solid #aaa; background:#fff; color:#000; padding: 5px;
|
||||
}
|
||||
.fname { font-size: 14px; vertical-align: middle; padding-right: 5px; }
|
||||
.fname { font-size: 12px; vertical-align: middle; padding-right: 5px; }
|
||||
img { max-width: 150; max-height: 150; }
|
||||
body { margin: 5px; }
|
||||
</style><script>
|
||||
|
@ -309,10 +309,10 @@ class Editor(object):
|
|||
from aqt.clayout import CardLayout
|
||||
self.saveNow()
|
||||
if self.card:
|
||||
type = 1; ord = self.card.ord
|
||||
ord = self.card.ord
|
||||
else:
|
||||
type = 0; ord = 0
|
||||
CardLayout(self.mw, self.note, type=type, ord=ord, parent=self.widget)
|
||||
ord = 0
|
||||
CardLayout(self.mw, self.note, ord=ord, parent=self.widget)
|
||||
self.loadNote()
|
||||
|
||||
# JS->Python bridge
|
||||
|
@ -397,7 +397,7 @@ class Editor(object):
|
|||
self.web.setFocus()
|
||||
|
||||
def fonts(self):
|
||||
return [(f['font'], f['esize'])
|
||||
return [(f['font'], f['size'])
|
||||
for f in self.note.model()['flds']]
|
||||
|
||||
def saveNow(self):
|
||||
|
@ -411,17 +411,14 @@ class Editor(object):
|
|||
|
||||
def checkValid(self):
|
||||
cols = []
|
||||
self.dupe = None
|
||||
for c, p in enumerate(self.note.problems()):
|
||||
if not p:
|
||||
cols.append("#fff")
|
||||
elif p == "unique":
|
||||
cols.append("#fcc")
|
||||
self.dupe = c
|
||||
else:
|
||||
cols.append("#ffc")
|
||||
err = None
|
||||
for f in self.note.fields:
|
||||
cols.append("#fff")
|
||||
err = self.note.dupeOrEmpty()
|
||||
if err:
|
||||
cols[0] = "#fcc"
|
||||
self.web.eval("setBackgrounds(%s);" % simplejson.dumps(cols))
|
||||
if self.dupe is not None:
|
||||
if err == 2:
|
||||
self.web.eval("showDupes();")
|
||||
else:
|
||||
self.web.eval("hideDupes();")
|
||||
|
@ -496,11 +493,11 @@ class Editor(object):
|
|||
if self.addMode:
|
||||
self.group.setCol(self.mw.col)
|
||||
self.tags.setText(self.note.stringTags().strip())
|
||||
if getattr(self.note, 'gid', None):
|
||||
gid = self.note.gid
|
||||
if getattr(self.note, 'did', None):
|
||||
did = self.note.did
|
||||
else:
|
||||
gid = self.note.model().conf['gid']
|
||||
self.group.setText(self.mw.col.groups.name(gid))
|
||||
did = self.note.model()['did']
|
||||
self.group.setText(self.mw.col.decks.name(did))
|
||||
|
||||
def saveTagsAndGroup(self):
|
||||
if not self.note:
|
||||
|
@ -508,9 +505,9 @@ class Editor(object):
|
|||
self.note.tags = self.mw.col.tags.split(unicode(self.tags.text()))
|
||||
if self.addMode:
|
||||
# save group and tags to model
|
||||
self.note.gid = self.mw.col.groups.id(unicode(self.group.text()))
|
||||
self.note.did = self.mw.col.decks.id(unicode(self.group.text()))
|
||||
m = self.note.model()
|
||||
m['gid'] = self.note.gid
|
||||
m['did'] = self.note.did
|
||||
m['tags'] = self.note.tags
|
||||
self.mw.col.models.save(m)
|
||||
self.note.flush()
|
||||
|
@ -771,7 +768,7 @@ class Editor(object):
|
|||
class EditorWebView(AnkiWebView):
|
||||
|
||||
def __init__(self, parent, editor):
|
||||
AnkiWebView.__init__(self, parent)
|
||||
AnkiWebView.__init__(self)
|
||||
self.editor = editor
|
||||
self.errtxt = _("An error occured while opening %s")
|
||||
self.strip = self.editor.mw.pm.profile['stripHTML']
|
||||
|
|
|
@ -5,7 +5,6 @@ from aqt.qt import *
|
|||
import re
|
||||
from anki.consts import *
|
||||
import aqt
|
||||
from anki.sound import playFromText, clearAudioQueue
|
||||
from aqt.utils import saveGeom, restoreGeom, getBase, mungeQA, \
|
||||
saveSplitter, restoreSplitter, showInfo, askUser, getText, \
|
||||
openHelp
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
from aqt.qt import *
|
||||
from operator import itemgetter
|
||||
from aqt.utils import showInfo, askUser, getText, maybeHideClose
|
||||
import aqt.modelchooser, aqt.clayout
|
||||
|
||||
|
@ -10,7 +11,8 @@ class Models(QDialog):
|
|||
self.mw = mw
|
||||
self.parent = parent or mw
|
||||
QDialog.__init__(self, self.parent, Qt.Window)
|
||||
self.deck = mw.col
|
||||
self.col = mw.col
|
||||
self.mm = self.col.models
|
||||
self.mw.checkpoint(_("Models"))
|
||||
self.form = aqt.forms.models.Ui_Dialog()
|
||||
self.form.setupUi(self)
|
||||
|
@ -27,9 +29,6 @@ class Models(QDialog):
|
|||
c = self.connect; f = self.form; box = f.buttonBox
|
||||
s = SIGNAL("clicked()")
|
||||
t = QDialogButtonBox.ActionRole
|
||||
b = box.addButton(_("Layout..."), t)
|
||||
c(b, s, self.onLayout)
|
||||
b.setDefault(True)
|
||||
b = box.addButton(_("Add"), t)
|
||||
c(b, s, self.onAdd)
|
||||
b = box.addButton(_("Rename"), t)
|
||||
|
@ -55,8 +54,8 @@ class Models(QDialog):
|
|||
row = self.form.modelsList.currentRow()
|
||||
if row == -1:
|
||||
row = 0
|
||||
mids = self.deck.db.list("select id from models order by name")
|
||||
self.models = [self.deck.getModel(mid) for mid in mids]
|
||||
self.models = self.col.models.all()
|
||||
self.models.sort(key=itemgetter("name"))
|
||||
self.form.modelsList.clear()
|
||||
for m in self.models:
|
||||
item = QListWidgetItem(_("%(name)s [%(notes)d notes]") % dict(
|
||||
|
@ -73,28 +72,28 @@ class Models(QDialog):
|
|||
def onAdd(self):
|
||||
m = aqt.modelchooser.AddModel(self.mw, self).get()
|
||||
if m:
|
||||
self.deck.addModel(m)
|
||||
self.col.addModel(m)
|
||||
self.updateModelsList()
|
||||
|
||||
def onLayout(self):
|
||||
# set to current
|
||||
# # see if there's an available note
|
||||
dummy = False
|
||||
id = self.deck.db.scalar(
|
||||
id = self.col.db.scalar(
|
||||
"select id from notes where mid = ?", self.model.id)
|
||||
if id:
|
||||
note = self.deck.getNote(id)
|
||||
note = self.col.getNote(id)
|
||||
else:
|
||||
# generate a dummy one
|
||||
self.deck.conf['currentModelId'] = self.model.id
|
||||
note = self.deck.newNote()
|
||||
self.col.conf['currentModelId'] = self.model.id
|
||||
note = self.col.newNote()
|
||||
for f in note.keys():
|
||||
note[f] = f
|
||||
self.deck.addNote(note)
|
||||
self.col.addNote(note)
|
||||
dummy = True
|
||||
aqt.clayout.CardLayout(self.mw, note, type=2, parent=self)
|
||||
if dummy:
|
||||
self.deck._delNotes([note.id])
|
||||
self.col._delNotes([note.id])
|
||||
|
||||
def onDelete(self):
|
||||
if len(self.models) < 2:
|
||||
|
@ -105,7 +104,7 @@ class Models(QDialog):
|
|||
_("Delete this model and all its cards?"),
|
||||
parent=self):
|
||||
return
|
||||
self.deck.delModel(self.model.id)
|
||||
self.col.delModel(self.model.id)
|
||||
self.model = None
|
||||
self.updateModelsList()
|
||||
|
||||
|
|
|
@ -364,6 +364,8 @@ div#filler {
|
|||
|
||||
def typeAns(self):
|
||||
"None if answer typing disabled."
|
||||
print "typeAns()"
|
||||
return False
|
||||
self.card.template()['typeAns']
|
||||
|
||||
def typeAnsInput(self):
|
||||
|
|
|
@ -9,7 +9,7 @@ class TagEdit(QLineEdit):
|
|||
# 0 = tags, 1 = groups
|
||||
def __init__(self, parent, type=0):
|
||||
QLineEdit.__init__(self, parent)
|
||||
self.deck = None
|
||||
self.col = None
|
||||
self.model = QStringListModel()
|
||||
self.type = type
|
||||
if type == 0:
|
||||
|
@ -20,13 +20,13 @@ class TagEdit(QLineEdit):
|
|||
self.completer.setCaseSensitivity(Qt.CaseInsensitive)
|
||||
self.setCompleter(self.completer)
|
||||
|
||||
def setDeck(self, deck):
|
||||
"Set the current deck, updating list of available tags."
|
||||
self.deck = deck
|
||||
def setCol(self, col):
|
||||
"Set the current col, updating list of available tags."
|
||||
self.col = col
|
||||
if self.type == 0:
|
||||
l = sorted(self.deck.tags.all())
|
||||
l = sorted(self.col.tags.all())
|
||||
else:
|
||||
l = self.deck.groups.all()
|
||||
l = self.col.groups.all()
|
||||
self.model.setStringList(l)
|
||||
|
||||
def addTags(self, tags):
|
||||
|
@ -50,7 +50,7 @@ class TagCompleter(QCompleter):
|
|||
def splitPath(self, str):
|
||||
str = unicode(str).strip()
|
||||
str = re.sub(" +", " ", str)
|
||||
self.tags = self.parent.deck.tags.split(str)
|
||||
self.tags = self.parent.col.tags.split(str)
|
||||
self.tags.append(u"")
|
||||
p = self.edit.cursorPosition()
|
||||
self.cursor = str.count(" ", 0, p)
|
||||
|
|
105
aqt/templates.py
105
aqt/templates.py
|
@ -1,105 +0,0 @@
|
|||
# Copyright: Damien Elmes <anki@ichi2.net>
|
||||
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
from aqt.qt import *
|
||||
import aqt
|
||||
from aqt.utils import saveGeom, restoreGeom, askUser, getText
|
||||
|
||||
class Templates(QDialog):
|
||||
|
||||
def __init__(self, mw, model, parent=None):
|
||||
self.parent = parent or mw
|
||||
QDialog.__init__(self, self.parent, Qt.Window)
|
||||
self.mw = aqt.mw
|
||||
self.model = model
|
||||
self.form = aqt.forms.templates.Ui_Dialog()
|
||||
self.form.setupUi(self)
|
||||
self.setWindowTitle(_("%s Templates") % self.model.name)
|
||||
self.setupTemplates()
|
||||
self.updateTemplates()
|
||||
self.exec_()
|
||||
|
||||
# Templates
|
||||
##########################################################################
|
||||
|
||||
def setupTemplates(self):
|
||||
f = self.form; c = self.connect; s = SIGNAL("clicked()")
|
||||
c(f.templateList, SIGNAL("currentRowChanged(int)"),
|
||||
self.templateRowChanged)
|
||||
c(f.templateList, SIGNAL("itemDoubleClicked(QListWidgetItem*)"),
|
||||
self.renameTemplate)
|
||||
c(f.templateAdd, s, self.addTemplate)
|
||||
c(f.templateDelete, s, self.deleteTemplate)
|
||||
c(f.templateUp, s, self.moveTemplateUp)
|
||||
c(f.templateDown, s, self.moveTemplateDown)
|
||||
|
||||
def renameTemplate(self, item):
|
||||
txt = getText(_("New name?"), default=self.template['name'])
|
||||
if txt[0]:
|
||||
self.template['name'] = txt[0]
|
||||
|
||||
def updateTemplates(self, row = None):
|
||||
row = self.form.templateList.currentRow() or 0
|
||||
if row == -1:
|
||||
row = 0
|
||||
self.form.templateList.clear()
|
||||
for template in self.model.templates:
|
||||
item = QListWidgetItem(template['name'])
|
||||
self.form.templateList.addItem(item)
|
||||
count = self.form.templateList.count()
|
||||
self.form.templateList.setCurrentRow(row)
|
||||
|
||||
def templateRowChanged(self):
|
||||
self.template = self.model.templates[self.form.templateList.currentRow()]
|
||||
self.enableTemplateMoveButtons()
|
||||
|
||||
def enableTemplateMoveButtons(self):
|
||||
f = self.form
|
||||
row = f.templateList.currentRow()
|
||||
f.templateUp.setEnabled(row >= 1)
|
||||
f.templateDown.setEnabled(row < (f.templateList.count() - 1))
|
||||
|
||||
def addTemplate(self):
|
||||
templates = len(self.model.templates)
|
||||
t = self.model.newTemplate()
|
||||
t['name'] = _("Template %d") % (templates+1)
|
||||
fields = self.model.fields
|
||||
t['qfmt'] = "{{%s}}" % fields[0]['name']
|
||||
if len(fields) > 1:
|
||||
t['afmt'] = "{{%s}}" % fields[1]['name']
|
||||
else:
|
||||
t['afmt'] = ""
|
||||
self.model.addTemplate(t)
|
||||
self.updateTemplates()
|
||||
|
||||
def deleteTemplate(self):
|
||||
if len (self.model.templates) < 2:
|
||||
ui.utils.showWarning(
|
||||
_("Please add a new template first."),
|
||||
parent=self)
|
||||
return
|
||||
if not askUser(
|
||||
_("Delete this template and all cards that use it?")):
|
||||
return
|
||||
self.model.delTemplate(self.template)
|
||||
self.updateTemplates()
|
||||
|
||||
def moveTemplateUp(self):
|
||||
row = self.form.templateList.currentRow()
|
||||
if row == 0:
|
||||
return
|
||||
self.mw.progress.start()
|
||||
self.model.moveTemplate(self.template, row-1)
|
||||
self.mw.progress.finish()
|
||||
self.updateTemplates()
|
||||
self.form.templateList.setCurrentRow(row-1)
|
||||
|
||||
def moveTemplateDown(self):
|
||||
row = self.form.templateList.currentRow()
|
||||
if row == len(self.model.templates) - 1:
|
||||
return
|
||||
self.mw.progress.start()
|
||||
self.model.moveTemplate(self.template, row+1)
|
||||
self.mw.progress.finish()
|
||||
self.updateTemplates()
|
||||
self.form.templateList.setCurrentRow(row+1)
|
|
@ -2,7 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
import os, cPickle, ctypes
|
||||
import os, cPickle, ctypes, shutil
|
||||
from aqt.qt import *
|
||||
from anki.utils import isMac, isWin
|
||||
from anki import Collection
|
||||
|
@ -132,6 +132,7 @@ carefully, as a lot has changed since the previous Anki version."""))
|
|||
def isComplete(self):
|
||||
return False
|
||||
def initializePage(self):
|
||||
self.setCommitPage(True)
|
||||
self.setTitle(_("Upgrading"))
|
||||
self.label = l = QLabel()
|
||||
l.setTextInteractionFlags(Qt.TextSelectableByMouse)
|
||||
|
|
Loading…
Reference in a new issue