diff --git a/aqt/browser.py b/aqt/browser.py index 7a9f91e89..421f4e063 100644 --- a/aqt/browser.py +++ b/aqt/browser.py @@ -15,6 +15,7 @@ from anki.errors import * from anki.db import * from anki.hooks import runHook, addHook, removeHook from aqt.webview import AnkiWebView +from aqt.toolbar import Toolbar COLOUR_SUSPENDED1 = "#ffffcc" COLOUR_SUSPENDED2 = "#ffffaa" @@ -304,15 +305,14 @@ class Browser(QMainWindow): self.lastFilter = "" self.form = aqt.forms.browser.Ui_Dialog() self.form.setupUi(self) - self.setUnifiedTitleAndToolBarOnMac(True) - restoreGeom(self, "editor", 38) + #self.setUnifiedTitleAndToolBarOnMac(True) + restoreGeom(self, "editor", 0) restoreState(self, "editor") restoreSplitter(self.form.splitter_2, "editor2") restoreSplitter(self.form.splitter, "editor3") self.form.splitter_2.setChildrenCollapsible(False) self.form.splitter.setChildrenCollapsible(False) self.setupColumns() - self.setupToolbar() self.setupTable() self.setupMenus() self.setupSearch() @@ -320,7 +320,8 @@ class Browser(QMainWindow): self.setupHeaders() self.setupHooks() self.setupEditor() - self.setupCardInfo() + self.setupToolbar() + #self.setupCardInfo() self.updateFont() self.onUndoState(self.mw.form.actionUndo.isEnabled()) self.form.searchEdit.setFocus() @@ -330,8 +331,10 @@ class Browser(QMainWindow): self.onSearch() def setupToolbar(self): - self.form.toolBar.setIconSize(QSize(24, 24)) - self.form.toolBar.toggleViewAction().setText(_("Toggle Toolbar")) + self.toolbarWeb = AnkiWebView() + self.toolbarWeb.setFixedHeight(34) + self.toolbar = BrowserToolbar(self.mw, self.toolbarWeb, self) + self.form.verticalLayout_3.insertWidget(0, self.toolbarWeb) def setupMenus(self): # actions @@ -491,7 +494,7 @@ class Browser(QMainWindow): def onRowChanged(self, current, previous): "Update current note and hide/show editor." show = self.model.cards and self.updateTitle() == 1 - self.form.splitter_2.widget(1).setShown(not not show) + self.form.splitter.widget(1).setShown(not not show) if not show: self.editor.setNote(None) else: @@ -500,7 +503,7 @@ class Browser(QMainWindow): self.editor.setNote(self.card.note()) self.editor.card = self.card self.showCardInfo(self.card) - self.updateToggles() + self.toolbar.draw() def refreshCurrentCard(self, note): self.model.refreshNote(note) @@ -690,6 +693,7 @@ class Browser(QMainWindow): self.onCardLink) def showCardInfo(self, card): + return self.cardStats.card = self.card rep = self.cardStats.report() rep = "" + rep @@ -858,10 +862,10 @@ where id in %s""" % ids2str(sf)) self.model.endReset() self.mw.requireReset() - # Group change + # Deck change ###################################################################### - def setGroup(self, initial=False): + def setDeck(self, initial=False): d = QDialog(self) d.setWindowModality(Qt.WindowModal) frm = aqt.forms.setgroup.Ui_Dialog() @@ -870,7 +874,7 @@ where id in %s""" % ids2str(sf)) te = TagEdit(d, type=1) frm.groupBox.layout().insertWidget(0, te) te.setCol(self.col) - d.connect(d, SIGNAL("accepted()"), lambda: self.onSetGroup(frm, te)) + d.connect(d, SIGNAL("accepted()"), lambda: self._onSetDeck(frm, te)) self.setTabOrder(frm.setCur, te) self.setTabOrder(te, frm.setInitial) if initial: @@ -878,22 +882,22 @@ where id in %s""" % ids2str(sf)) d.show() te.setFocus() - def onSetGroup(self, frm, te): + def _onSetDeck(self, frm, te): self.model.beginReset() - self.mw.checkpoint(_("Set Group")) + self.mw.checkpoint(_("Set Deck")) mod = intTime() if frm.setCur.isChecked(): - gid = self.col.groups.id(unicode(te.text())) + did = self.col.decks.id(unicode(te.text())) self.col.db.execute( - "update cards set mod=?, gid=? where id in " + ids2str( - self.selectedCards()), mod, gid) + "update cards set mod=?, did=? where id in " + ids2str( + self.selectedCards()), mod, did) if frm.setInitial.isChecked(): self.col.db.execute( - "update notes set mod=?, gid=? where id in " + ids2str( - self.selectedNotes()), mod, gid) + "update notes set mod=?, did=? where id in " + ids2str( + self.selectedNotes()), mod, did) else: self.col.db.execute(""" -update cards set mod=?, gid=(select gid from notes where id = cards.nid) +update cards set mod=?, did=(select did from notes where id = cards.nid) where id in %s""" % ids2str(self.selectedCards()), mod) self.onSearch(reset=False) self.mw.requireReset() @@ -932,14 +936,12 @@ where id in %s""" % ids2str(self.selectedCards()), mod) # Suspending and marking ###################################################################### - def updateToggles(self): - self.form.actionToggleSuspend.setChecked(self.isSuspended()) - self.form.actionToggleMark.setChecked(self.isMarked()) - def isSuspended(self): return not not (self.card and self.card.queue == -1) - def onSuspend(self, sus): + def onSuspend(self, sus=None): + if sus is None: + sus = not self.isSuspended() # focus lost hook may not have chance to fire self.editor.saveNow() c = self.selectedCards() @@ -953,7 +955,9 @@ where id in %s""" % ids2str(self.selectedCards()), mod) def isMarked(self): return not not (self.card and self.card.note().hasTag("Marked")) - def onMark(self, mark): + def onMark(self, mark=None): + if mark is None: + mark = not self.isMarked() if mark: self.addTags(tags="marked", label=False) else: @@ -1397,3 +1401,69 @@ Are you sure you want to continue?""")): def onHelp(self): openHelp("Browser#ChangeModel") + +# Toolbar +###################################################################### + +class BrowserToolbar(Toolbar): + always = [ + ["setDeck", "Move to Deck"], + ["addTags", "Add Tags"], + ["remTags", "Remove Tags"], + ] + + singleOnly = [ + ["info", "Info"], + ] + + rightIcons = [ + ["mark", "qrc:/icons/star16.png"], + ["pause", "qrc:/icons/star_off16.png"], + ] + + def __init__(self, mw, web, browser): + self.browser = browser + Toolbar.__init__(self, mw, web) + + def draw(self): + single = self.browser.editor.note + mark = self.browser.isMarked() + pause = self.browser.isSuspended() + links = self.always[:] + if single: + links += self.singleOnly + self.centerLinks = links + def borderImg(link, icon, on): + if on: + fmt = '''\ + +''' + else: + fmt = '''\ +''' + return fmt % (link, icon) + right = "" + right += borderImg("mark", "star16", mark) + right += borderImg("pause", "pause16", pause) + self.web.stdHtml(self._body % ( + 'Browser ▾', + self._centerLinks(), + right), self._css, focus=False) + + # Link handling + ###################################################################### + + def _linkHandler(self, l): + if l == "anki": + self.showMenu() + elif l == "setDeck": + self.browser.setDeck() + elif l == "addTags": + self.browser.addTags() + elif l == "remTags": + self.browser.deleteTags() + # icons + elif l == "mark": + self.browser.onMark() + elif l == "pause": + self.browser.onSuspend() diff --git a/aqt/editor.py b/aqt/editor.py index 040d0fa45..25318d515 100644 --- a/aqt/editor.py +++ b/aqt/editor.py @@ -426,7 +426,6 @@ class Editor(object): def showDupes(self): contents = self.note.fields[0] - print "conts", `self.note.fields` browser = aqt.dialogs.open("Browser", self.mw) browser.form.searchEdit.setText( "'model:%s' '%s'" % (self.note.model()['name'], contents)) diff --git a/aqt/main.py b/aqt/main.py index dddf41178..e46303607 100755 --- a/aqt/main.py +++ b/aqt/main.py @@ -322,10 +322,12 @@ title="%s">%s''' % ( tweb.setFocusPolicy(Qt.WheelFocus) tweb.setFixedHeight(32) self.toolbar = aqt.toolbar.Toolbar(self, tweb) + self.toolbar.draw() # main area self.web = aqt.webview.AnkiWebView() self.web.setObjectName("mainText") self.web.setFocusPolicy(Qt.WheelFocus) + self.web.setMinimumWidth(400) # add in a layout self.mainLayout = QVBoxLayout() self.mainLayout.setContentsMargins(0,0,0,0) @@ -527,17 +529,21 @@ Debug info:\n%s""") % traceback.format_exc(), help="DeckErrors") # Dockable widgets ########################################################################## - def addDockable(self, title, w): - dock = QDockWidget(title, self) + def addDockable(self, title, w, target=None): + target = target or self + dock = QDockWidget(title, target) dock.setObjectName(title) dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) dock.setFeatures(QDockWidget.DockWidgetClosable) dock.setWidget(w) - self.addDockWidget(Qt.RightDockWidgetArea, dock) + if target.width() < 600: + target.resize(QSize(600, target.height())) + target.addDockWidget(Qt.RightDockWidgetArea, dock) return dock - def rmDockable(self, dock): - self.removeDockWidget(dock) + def rmDockable(self, dock, target=None): + target = target or self + target.removeDockWidget(dock) # Marking, suspending and deleting ########################################################################## diff --git a/aqt/stats.py b/aqt/stats.py index 3cc77c49f..ad14a21b5 100644 --- a/aqt/stats.py +++ b/aqt/stats.py @@ -23,8 +23,10 @@ class CardStats(object): def show(self): if not self.shown: - self.web = AnkiWebView() - self.web.setMaximumWidth(400) + class ThinAnkiWebView(AnkiWebView): + def sizeHint(self): + return QSize(200, 100) + self.web = ThinAnkiWebView() self.shown = self.mw.addDockable(_("Card Info"), self.web) self.shown.connect(self.shown, SIGNAL("visibilityChanged(bool)"), self._visChange) diff --git a/aqt/tagedit.py b/aqt/tagedit.py index b2da32913..66edb2b6b 100644 --- a/aqt/tagedit.py +++ b/aqt/tagedit.py @@ -6,7 +6,7 @@ import re, sys class TagEdit(QLineEdit): - # 0 = tags, 1 = groups + # 0 = tags, 1 = decks def __init__(self, parent, type=0): QLineEdit.__init__(self, parent) self.col = None @@ -26,7 +26,7 @@ class TagEdit(QLineEdit): if self.type == 0: l = sorted(self.col.tags.all()) else: - l = self.col.groups.all() + l = sorted(self.col.decks.allNames()) 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.col.tags.split(str) + self.tags = self.edit.col.tags.split(str) self.tags.append(u"") p = self.edit.cursorPosition() self.cursor = str.count(" ", 0, p) diff --git a/aqt/toolbar.py b/aqt/toolbar.py index d748f9b5a..b40310d3c 100644 --- a/aqt/toolbar.py +++ b/aqt/toolbar.py @@ -13,11 +13,13 @@ class Toolbar(object): self.web.page().mainFrame().setScrollBarPolicy( Qt.Vertical, Qt.ScrollBarAlwaysOff) self.web.setLinkHandler(self._linkHandler) - self.draw() def draw(self): - body = self._body % (self._centerLinks(), self._rightIcons()) - self.web.stdHtml(body, self._css) + self.web.stdHtml(self._body % ( + 'Anki ▾', + self._centerLinks(), + self._rightIcons()), + self._css, focus=False) # Available links ###################################################################### @@ -38,6 +40,7 @@ class Toolbar(object): buf = "" for ln, name in self.centerLinks: buf += '%s' % (ln, _(name)) + buf += " "*3 return buf def _rightIcons(self): @@ -72,9 +75,9 @@ class Toolbar(object): _body = """ - + - + """ diff --git a/aqt/utils.py b/aqt/utils.py index 5a4f53904..a3a25e2ef 100644 --- a/aqt/utils.py +++ b/aqt/utils.py @@ -208,7 +208,7 @@ def chooseList(prompt, choices, startrow=0, parent=None): def getTag(parent, deck, question, tags="user", **kwargs): from aqt.tagedit import TagEdit te = TagEdit(parent) - te.setDeck(deck) + te.setCol(deck) return getText(question, parent, edit=te, **kwargs) # File handling diff --git a/aqt/webview.py b/aqt/webview.py index 0e13f3cc0..16ee77a2c 100644 --- a/aqt/webview.py +++ b/aqt/webview.py @@ -83,7 +83,7 @@ class AnkiWebView(QWebView): if loadCB: self._loadFinishedCB = loadCB QWebView.setHtml(self, html) - def stdHtml(self, body, css="", bodyID="", loadCB=None): + def stdHtml(self, body, css="", bodyID="", loadCB=None, focus=True): self.setHtml(""" @@ -91,7 +91,8 @@ class AnkiWebView(QWebView): %s""" % ( css, anki.js.all, bodyID, body), loadCB) # ensure we're focused - self.setFocus() + if focus: + self.setFocus() def setBridge(self, bridge): self._bridge.setBridge(bridge) def eval(self, js): diff --git a/designer/browser.ui b/designer/browser.ui index b4eff13ce..2c129f7e2 100644 --- a/designer/browser.ui +++ b/designer/browser.ui @@ -6,10 +6,16 @@ 0 0 - 524 - 382 + 610 + 430 + + + 400 + 0 + + Browser @@ -19,34 +25,40 @@ + + 0 + 0 - Qt::Vertical + Qt::Horizontal + + + + 0 + 0 + + + + QFrame::NoFrame + + + false + + + + 1 + + + - Qt::Horizontal + Qt::Vertical - - - - 1 - 0 - - - - false - - - - 1 - - - @@ -98,7 +110,7 @@ - 4 + 0 4 @@ -142,58 +154,48 @@ - - - - - 0 - - - 0 - - - 1 - - - 0 - - - 0 - - - - - 0 - - - - - - 7 - 0 - - - - - 50 - 50 - - - - - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - 6 - - - - - - + + + + 0 + + + 0 + + + 1 + + + 0 + + + 0 + + + + + 0 + + + + + + 0 + 0 + + + + + 50 + 50 + + + + + + + + @@ -204,7 +206,7 @@ 0 0 - 524 + 610 22 @@ -274,37 +276,6 @@ - - - toolBar - - - - 24 - 24 - - - - Qt::ToolButtonIconOnly - - - TopToolBarArea - - - false - - - - - - - - - - - - - diff --git a/designer/icons.qrc b/designer/icons.qrc index cfde582db..81b4057e7 100644 --- a/designer/icons.qrc +++ b/designer/icons.qrc @@ -117,5 +117,9 @@ icons/stock_new_template_green.png icons/stock_new_template_red.png icons/stock_group.png + icons/star16.png + icons/star_off16.png + icons/pause16.png + icons/pause_off16.png diff --git a/designer/icons/pause16.png b/designer/icons/pause16.png new file mode 100644 index 000000000..1ece3cbbd Binary files /dev/null and b/designer/icons/pause16.png differ diff --git a/designer/icons/pause_off16.png b/designer/icons/pause_off16.png new file mode 100644 index 000000000..81ae20367 Binary files /dev/null and b/designer/icons/pause_off16.png differ diff --git a/designer/icons/star16.png b/designer/icons/star16.png new file mode 100644 index 000000000..1b42d54e7 Binary files /dev/null and b/designer/icons/star16.png differ diff --git a/designer/icons/star_off16.png b/designer/icons/star_off16.png new file mode 100644 index 000000000..0458a3b97 Binary files /dev/null and b/designer/icons/star_off16.png differ diff --git a/designer/main.ui b/designer/main.ui index 877751f04..a00aca18e 100644 --- a/designer/main.ui +++ b/designer/main.ui @@ -16,6 +16,12 @@ 0 + + + 400 + 0 + + Anki