browser tweaks

This commit is contained in:
Damien Elmes 2011-11-28 21:19:39 +09:00
parent 23411c2872
commit 10234be4e9
6 changed files with 38 additions and 149 deletions

View file

@ -31,7 +31,7 @@ De Pooter, Susanna Björverud, Tacutu, Timm Preetz, Timo Paulssen, Ursus, Victor
Suba, and Xtru. Suba, and Xtru.
<p> <p>
Anki icon by Alex Fraser (CC GNU GPL)<br> Anki icon by Alex Fraser (CC GNU GPL)<br>
Deck icon by Laurent Baumann (CC BY-NC-SA 3.0)<br> Deck icon: Be Box Icons (free for non-commercial use)<br>
Deck browser icons from:<br> Deck browser icons from:<br>
http://led24.de/iconset<br> http://led24.de/iconset<br>
http://p.yusukekamiyamane.com/<br> http://p.yusukekamiyamane.com/<br>

View file

@ -327,7 +327,7 @@ class Browser(QMainWindow):
self.onUndoState(self.mw.form.actionUndo.isEnabled()) self.onUndoState(self.mw.form.actionUndo.isEnabled())
self.form.searchEdit.setFocus() self.form.searchEdit.setFocus()
self.show() self.show()
self.form.searchEdit.setText("is:recent") self.form.searchEdit.setText("deck:current is:recent")
self.form.searchEdit.selectAll() self.form.searchEdit.selectAll()
self.onSearch() self.onSearch()
@ -465,7 +465,7 @@ class Browser(QMainWindow):
cur) % { cur) % {
"cur": cur, "cur": cur,
"sel": ngettext("%d selected", "%d selected", selected) % selected "sel": ngettext("%d selected", "%d selected", selected) % selected
} + " - " + self.col.name()) })
return selected return selected
def onReset(self): def onReset(self):
@ -613,8 +613,7 @@ class Browser(QMainWindow):
self.form.tree.clear() self.form.tree.clear()
root = self.form.tree.invisibleRootItem() root = self.form.tree.invisibleRootItem()
self._systemTagTree(root) self._systemTagTree(root)
self._modelTree(root) self._decksTree(root)
self._groupTree(root)
self._userTagTree(root) self._userTagTree(root)
self.form.tree.expandToDepth(0) self.form.tree.expandToDepth(0)
self.form.tree.setIndentation(15) self.form.tree.setIndentation(15)
@ -646,49 +645,21 @@ class Browser(QMainWindow):
self.form.searchEdit.setText(txt) self.form.searchEdit.setText(txt)
self.onSearch() self.onSearch()
def _modelTree(self, root):
for m in sorted(self.col.models.all(), key=itemgetter("name")):
mitem = self.CallbackItem(
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['tmpls']:
titem = self.CallbackItem(
t['name'], lambda m=m, t=t: self.setFilter(
"model", m['name'], "card", t['name']))
titem.setIcon(0, QIcon(":/icons/stock_new_template.png"))
mitem.addChild(titem)
def _groupTree(self, root):
grps = self.col.sched.deckDueTree()
def fillGroups(root, grps, head=""):
for g in grps:
item = self.CallbackItem(
g[0], lambda g=g: self.setFilter(
"group", head+g[0]))
item.setIcon(0, QIcon(":/icons/stock_group.png"))
root.addChild(item)
fillGroups(item, g[4], g[0]+"::")
fillGroups(root, grps)
def _systemTagTree(self, root): def _systemTagTree(self, root):
tags = ( tags = (
(_("All cards"), "stock_new_template", ""), (_("All cards"), "stock_new_template", ""),
(_("New"), "stock_new_template_blue.png", "is:new"), (_("Current Deck"), "stock_new_template", "deck:current"),
(_("Learning"), "stock_new_template_red.png", "is:lrn"), (_("New"), "plus-circle.png", "is:new"),
(_("Review"), "stock_new_template_green.png", "is:rev"), (_("Learning"), "stock_new_template_red.png", "is:learn"),
(_("Review"), "clock-icon.png", "is:review"),
(_("Marked"), "rating.png", "tag:marked"), (_("Marked"), "rating.png", "tag:marked"),
(_("Suspended"), "media-playback-pause.png", "is:suspended"), (_("Suspended"), "media-playback-pause.png", "is:suspended"),
(_("Leech"), "emblem-important.png", "tag:leech"), (_("Leech"), "emblem-important.png", "tag:leech"))
(_("Due"), "stock_new_template_green.png", "is:due"))
for name, icon, cmd in tags: for name, icon, cmd in tags:
item = self.CallbackItem( item = self.CallbackItem(
name, lambda c=cmd: self.setFilter(c)) name, lambda c=cmd: self.setFilter(c))
item.setIcon(0, QIcon(":/icons/" + icon)) item.setIcon(0, QIcon(":/icons/" + icon))
root.addChild(item) root.addChild(item)
item = self.CallbackItem(_("Refresh list"), self.buildTree)
item.setIcon(0, QIcon(":/icons/multisynk.png"))
root.addChild(item)
return root return root
def _userTagTree(self, root): def _userTagTree(self, root):
@ -698,6 +669,18 @@ class Browser(QMainWindow):
item.setIcon(0, QIcon(":/icons/anki-tag.png")) item.setIcon(0, QIcon(":/icons/anki-tag.png"))
root.addChild(item) root.addChild(item)
def _decksTree(self, root):
grps = self.col.sched.deckDueTree()
def fillGroups(root, grps, head=""):
for g in grps:
item = self.CallbackItem(
g[0], lambda g=g: self.setFilter(
"deck", head+g[0]))
item.setIcon(0, QIcon(":/icons/stock_group.png"))
root.addChild(item)
fillGroups(item, g[4], g[0]+"::")
fillGroups(root, grps)
# Card info # Card info
###################################################################### ######################################################################
@ -1243,76 +1226,6 @@ select fm.id, fm.name from fieldmodels fm""")
def onCardList(self): def onCardList(self):
self.form.tableView.setFocus() self.form.tableView.setFocus()
# Generate cards
######################################################################
class GenCards(QDialog):
def __init__(self, browser, nids):
QDialog.__init__(self, browser)
self.browser = browser
self.nids = nids
self.form = aqt.forms.gencards.Ui_Dialog()
self.form.setupUi(self)
self.setWindowModality(Qt.WindowModal)
self.connect(self.form.buttonBox, SIGNAL("helpRequested()"),
self.onHelp)
restoreGeom(self, "addCardModels")
self.getSelection()
def getSelection(self):
# get cards to enable
f = self.browser.col.getNote(self.nids[0])
self.model = f.model()
self.items = []
for t in self.model.templates:
item = QListWidgetItem(t['name'], self.form.list)
self.form.list.addItem(item)
self.items.append(item)
idx = self.form.list.indexFromItem(item)
if t['actv']:
mode = QItemSelectionModel.Select
else:
mode = QItemSelectionModel.Deselect
self.form.list.selectionModel().select(idx, mode)
self.exec_()
def accept(self):
tplates = []
unused = []
for i, item in enumerate(self.items):
idx = self.form.list.indexFromItem(item)
if self.form.list.selectionModel().isSelected(idx):
tplates.append(self.model.templates[i])
else:
unused.append(self.model.templates[i]['ord'])
if not self.form.deleteUnsel.isChecked():
unused = None
self.genCards(tplates, unused)
saveGeom(self, "addCardModels")
QDialog.accept(self)
def genCards(self, tplates, unused):
mw = self.browser.mw
mw.checkpoint(_("Generate Cards"))
mw.progress.start()
for c, nid in enumerate(self.nids):
f = mw.col.getNote(nid)
mw.col.genCards(f, tplates)
if c % 100 == 0:
mw.progress.update()
if unused:
cids = mw.col.db.list("""
select id from cards where nid in %s and ord in %s""" % (
ids2str(self.nids), ids2str(unused)))
mw.col.remCards(cids)
mw.progress.finish()
mw.requireReset()
self.browser.onSearch()
def onHelp(self):
openHelp("Browser#GenerateCards")
# Change model dialog # Change model dialog
###################################################################### ######################################################################

View file

@ -18,7 +18,7 @@ import anki.js
# is focused, which is not good when the user is tabbing through the dialog # is focused, which is not good when the user is tabbing through the dialog
# fixme: set rtl in div css # fixme: set rtl in div css
# fixme: commit from tag/group area causes error # fixme: commit from tag area causes error
pics = ("jpg", "jpeg", "png", "tif", "tiff", "gif") pics = ("jpg", "jpeg", "png", "tif", "tiff", "gif")
audio = ("wav", "mp3", "ogg", "flac") audio = ("wav", "mp3", "ogg", "flac")
@ -29,6 +29,7 @@ _html = """
border: 1px solid #aaa; background:#fff; color:#000; padding: 5px; border: 1px solid #aaa; background:#fff; color:#000; padding: 5px;
} }
.fname { font-size: 12px; vertical-align: middle; padding-right: 5px; } .fname { font-size: 12px; vertical-align: middle; padding-right: 5px; }
#dupes { font-size: 12px; }
img { max-width: 150; max-height: 150; } img { max-width: 150; max-height: 150; }
body { margin: 5px; } body { margin: 5px; }
</style><script> </style><script>
@ -204,7 +205,7 @@ class Editor(object):
self.setupOuter() self.setupOuter()
self.setupButtons() self.setupButtons()
self.setupWeb() self.setupWeb()
self.setupTagsAndGroup() self.setupTags()
self.setupKeyboard() self.setupKeyboard()
# Initial setup # Initial setup
@ -375,7 +376,7 @@ class Editor(object):
self.web.setHtml(_html % (getBase(self.mw.col), anki.js.all, self.web.setHtml(_html % (getBase(self.mw.col), anki.js.all,
_("Show Duplicates")), _("Show Duplicates")),
loadCB=self._loadFinished) loadCB=self._loadFinished)
self.updateTagsAndGroup() self.updateTags()
self.updateKeyboard() self.updateKeyboard()
elif hide: elif hide:
self.widget.hide() self.widget.hide()
@ -407,7 +408,7 @@ class Editor(object):
self._keepButtons = True self._keepButtons = True
self.web.eval("saveField('blur');") self.web.eval("saveField('blur');")
self._keepButtons = False self._keepButtons = False
self.saveTagsAndGroup() self.saveTags()
def checkValid(self): def checkValid(self):
cols = [] cols = []
@ -424,10 +425,11 @@ class Editor(object):
self.web.eval("hideDupes();") self.web.eval("hideDupes();")
def showDupes(self): def showDupes(self):
contents = self.note.fields[self.dupe] contents = self.note.fields[0]
print "conts", `self.note.fields`
browser = aqt.dialogs.open("Browser", self.mw) browser = aqt.dialogs.open("Browser", self.mw)
browser.form.searchEdit.setText( browser.form.searchEdit.setText(
"'model:%s' '%s'" % (self.note.model().name, contents)) "'model:%s' '%s'" % (self.note.model()['name'], contents))
browser.onSearch() browser.onSearch()
def fieldsAreBlank(self): def fieldsAreBlank(self):
@ -455,71 +457,43 @@ class Editor(object):
form.textEdit.toPlainText()) form.textEdit.toPlainText())
self.loadNote(self.currentField) self.loadNote(self.currentField)
# Tag and group handling # Tag handling
###################################################################### ######################################################################
def setupTagsAndGroup(self): def setupTags(self):
import aqt.tagedit import aqt.tagedit
g = QGroupBox(self.widget) g = QGroupBox(self.widget)
g.setFlat(True) g.setFlat(True)
tb = QGridLayout() tb = QGridLayout()
tb.setSpacing(12) tb.setSpacing(12)
tb.setMargin(6) tb.setMargin(6)
# group
l = QLabel(_("Initial Group"))
tb.addWidget(l, 0, 0)
if not self.addMode:
self.group = QPushButton()
self.group.connect(self.group, SIGNAL("clicked()"),
self.changeGroup)
else:
self.group = aqt.tagedit.TagEdit(self.widget, type=1)
self.group.connect(self.group, SIGNAL("lostFocus"),
self.saveTagsAndGroup)
tb.addWidget(self.group, 0, 1)
# tags # tags
l = QLabel(_("Tags")) l = QLabel(_("Tags"))
tb.addWidget(l, 0, 2) tb.addWidget(l, 0, 2)
self.tags = aqt.tagedit.TagEdit(self.widget) self.tags = aqt.tagedit.TagEdit(self.widget)
self.tags.connect(self.tags, SIGNAL("lostFocus"), self.tags.connect(self.tags, SIGNAL("lostFocus"),
self.saveTagsAndGroup) self.saveTags)
tb.addWidget(self.tags, 0, 3) tb.addWidget(self.tags, 0, 3)
g.setLayout(tb) g.setLayout(tb)
self.outerLayout.addWidget(g) self.outerLayout.addWidget(g)
def updateTagsAndGroup(self): def updateTags(self):
if self.tags.col != self.mw.col: if self.tags.col != self.mw.col:
self.tags.setCol(self.mw.col) self.tags.setCol(self.mw.col)
if self.addMode:
self.group.setCol(self.mw.col)
self.tags.setText(self.note.stringTags().strip()) self.tags.setText(self.note.stringTags().strip())
if getattr(self.note, 'did', None):
did = self.note.did
else:
did = self.note.model()['did']
self.group.setText(self.mw.col.decks.name(did))
def saveTagsAndGroup(self): def saveTags(self):
if not self.note: if not self.note:
return return
self.note.tags = self.mw.col.tags.split(unicode(self.tags.text())) self.note.tags = self.mw.col.tags.split(unicode(self.tags.text()))
if self.addMode: if self.addMode:
# save group and tags to model # save group and tags to model
self.note.did = self.mw.col.decks.id(unicode(self.group.text()))
m = self.note.model() m = self.note.model()
m['did'] = self.note.did m['did'] = self.note.did
m['tags'] = self.note.tags m['tags'] = self.note.tags
self.mw.col.models.save(m) self.mw.col.models.save(m)
self.note.flush() self.note.flush()
runHook("tagsAndGroupUpdated", self.note) runHook("tagsUpdated", self.note)
def changeGroup(self):
id = self.note.id
runHook("closeEditCurrent")
browser = aqt.dialogs.open("Browser", self.mw)
browser.form.searchEdit.setText("nid:%d" % id)
browser.onSearch()
browser.setGroup(True)
# Format buttons # Format buttons
###################################################################### ######################################################################

View file

@ -162,6 +162,8 @@ $(".ansbut").focus();
# fixme: timer # fixme: timer
self.state = "question" self.state = "question"
c = self.card c = self.card
# mod the card so it shows up in the recently modified list
self.card.flush()
q = c.q() q = c.q()
a = c.a() a = c.a()
if self.mw.pm.profile['autoplay']: if self.mw.pm.profile['autoplay']:

View file

@ -561,7 +561,7 @@
<action name="actionSetDeck"> <action name="actionSetDeck">
<property name="icon"> <property name="icon">
<iconset resource="icons.qrc"> <iconset resource="icons.qrc">
<normaloff>:/icons/graphite_smooth_folder_noncommercial.png</normaloff>:/icons/graphite_smooth_folder_noncommercial.png</iconset> <normaloff>:/icons/stock_group.png</normaloff>:/icons/stock_group.png</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Move to Deck...</string> <string>Move to Deck...</string>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 586 B

After

Width:  |  Height:  |  Size: 4.4 KiB