From f96e03875a7ffd6991e57032e5ee452b2bf6bfa0 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Wed, 16 Mar 2011 04:52:21 +0900 Subject: [PATCH] more deck browser work - add a separate toolbar for the deck browser - add a message when there are no decks - change the progress handler not to lock the UI immediately, which causes flicker - ensure the webview is focused after stdHtml() --- aqt/deckbrowser.py | 84 +++++++++++++++++++++++++++++----------------- aqt/main.py | 13 +++---- aqt/progress.py | 26 ++++++++++---- aqt/webview.py | 2 ++ designer/main.ui | 23 +++++++++++++ 5 files changed, 104 insertions(+), 44 deletions(-) diff --git a/aqt/deckbrowser.py b/aqt/deckbrowser.py index 709ef8b75..e38aa5c7c 100644 --- a/aqt/deckbrowser.py +++ b/aqt/deckbrowser.py @@ -27,14 +27,11 @@ a.opts { font-size: 80%; padding: 2; background-color: #ccc; border-radius: 2px; _body = """
-

%s

+

%(title)s

-%s +%(rows)s
-

-%s -

-Click a deck to open it, or press the number/letter next to it. +%(extra)s

""" @@ -45,11 +42,16 @@ class DeckBrowser(object): self.web = mw.web self._browserLastRefreshed = 0 self._decks = [] + mw.connect(mw.form.actionRefreshDeckBrowser, SIGNAL("activated()"), + self.refresh) addHook("deckClosing", self.onClose) - def show(self): - self.web.setLinkHandler(self._linkHandler) - self.mw.setKeyHandler(self._keyHandler) + def show(self, _init=True): + if _init: + self.web.setLinkHandler(self._linkHandler) + self.mw.setKeyHandler(self._keyHandler) + self._setupToolbar() + # refresh or reorder if (time.time() - self._browserLastRefreshed > self.mw.config['deckBrowserRefreshPeriod']): t = time.time() @@ -57,23 +59,8 @@ class DeckBrowser(object): print "check decks", time.time() - t else: self._reorderDecks() - if self._decks: - buf = "" - max=len(self._decks)-1 - for c, deck in enumerate(self._decks): - buf += self._deckRow(c, max, deck) - self.web.stdHtml(_body%(_("Decks"), buf, self._summary()), _css) - else: - buf = ("""\ -
- -Welcome to Anki! Click 'Download' to get started. You can return here -later by using File>Close. - -
-""") - # FIXME: ensure deck open button is focused - + # show + self._renderPage() def onClose(self, deck): print "onClose" @@ -90,6 +77,24 @@ later by using File>Close. d['time'] = self.deck._dailyStats.reviewTime d['reps'] = self.deck._dailyStats.reps + # Toolbar + ########################################################################## + + def _setupToolbar(self): + frm = self.mw.form + tb = frm.toolBar + tb.clear() + tb.addAction(frm.actionDownloadSharedDeck) + tb.addAction(frm.actionNew) + tb.addAction(frm.actionOpen) + tb.addAction(frm.actionImport) + tb.addAction(frm.actionOpenOnline) + tb.addAction(frm.actionRefreshDeckBrowser) + tb.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) + # reshow so osx recalculates sizes + tb.hide() + tb.show() + # Event handlers ########################################################################## @@ -117,6 +122,27 @@ later by using File>Close. # HTML generation ########################################################################## + def _renderPage(self): + if self._decks: + buf = "" + max=len(self._decks)-1 + for c, deck in enumerate(self._decks): + buf += self._deckRow(c, max, deck) + self.web.stdHtml(_body%dict( + title=_("Decks"), + rows=buf, + extra="

%s

%s" % ( + self._summary(), + _("Click a deck to open, or type a number."))), + _css) + else: + self.web.stdHtml(_body%dict( + title=_("Welcome!"), + rows="%s"%_( + "Click Download to get started."), + extra=""), + _css) + def _deckRow(self, c, max, deck): buf = "" ok = deck['state'] == 'ok' @@ -207,10 +233,6 @@ later by using File>Close. a.connect(a, SIGNAL("activated()"), lambda n=n: self._deleteRow(n)) m.exec_(QCursor.pos()) - def _buttons(self): - # refresh = QPushButton(_("Refresh")) - return "" - def _hideRow(self, c): if aqt.utils.askUser(_("""\ Hide %s from the list? You can File>Open it again later.""") % @@ -303,4 +325,4 @@ not be touched.""") % self._decks[c]['name']): def refresh(self): self._browserLastRefreshed = 0 - self.show() + self.show(_init=False) diff --git a/aqt/main.py b/aqt/main.py index f3bb64b38..0e6939e5a 100755 --- a/aqt/main.py +++ b/aqt/main.py @@ -95,8 +95,6 @@ class AnkiQt(QMainWindow): self.deck = None self.currentCard = None self.lastCard = None - # perhaps we want a separate toolbar instead? - self.form.toolBar.hide() self.disableDeckMenuItems() self.closeAllDeckWindows() self.deckBrowser.show() @@ -1406,8 +1404,7 @@ learnt today") # Toolbar ########################################################################## - def setupToolbar(self): - mw = self.form + def setupReviewToolbar(self): mw.toolBar.addAction(mw.actionAddcards) mw.toolBar.addAction(mw.actionEditCurrent) mw.toolBar.addAction(mw.actionEditLayout) @@ -1417,8 +1414,12 @@ learnt today") mw.toolBar.addAction(mw.actionMarkCard) mw.toolBar.addAction(mw.actionRepeatAudio) mw.toolBar.addAction(mw.actionClose) - mw.toolBar.setIconSize(QSize(self.config['iconSize'], - self.config['iconSize'])) + + def setupToolbar(self): + mw = self.form + mw.toolBar.setIconSize(QSize(24, 24)) + #mw.toolBar.setIconSize(QSize(self.config['iconSize'], + # self.config['iconSize'])) toggle = mw.toolBar.toggleViewAction() toggle.setText(_("Toggle Toolbar")) self.connect(toggle, SIGNAL("triggered()"), diff --git a/aqt/progress.py b/aqt/progress.py index 4db1a0e35..48cdb4870 100644 --- a/aqt/progress.py +++ b/aqt/progress.py @@ -71,9 +71,6 @@ class ProgressManager(object): self._levels += 1 if self._levels > 1: return - # disable UI - self.mw.app.setOverrideCursor(QCursor(Qt.WaitCursor)) - self.mw.setEnabled(False) # setup window parent = parent or self.app.activeWindow() or self.mw label = label or _("Processing...") @@ -96,6 +93,7 @@ class ProgressManager(object): self._max = max self._firstTime = time.time() self._lastTime = time.time() + self._disabled = False def update(self, label=None, value=None, process=True): #print self._min, self._counter, self._max, label, time.time() - self._lastTime @@ -113,8 +111,7 @@ class ProgressManager(object): self._levels -= 1 if self._levels == 0: self._win.cancel() - self.app.restoreOverrideCursor() - self.mw.setEnabled(True) + self._enableUI() def clear(self): "Restore the interface after an error." @@ -123,7 +120,22 @@ class ProgressManager(object): self.finishProgress() def _maybeShow(self): - if not self._shown and (time.time() - self._firstTime) > 2: - print "show2" + delta = time.time() - self._firstTime + # if more than 500ms have passed, disable the UI so the user doesn't + # try to click again. We don't do it immediately to avoid flicker. + if not self._disabled and delta > 0.5: + self._disableUI() + # if more than 2 seconds have passed, show a progress dialog + if not self._shown and delta > 2: self._shown = True self._win.show() + + def _disableUI(self): + self._disabled = True + self.mw.app.setOverrideCursor(QCursor(Qt.WaitCursor)) + self.mw.setEnabled(False) + + def _enableUI(self): + self._disabled = False + self.app.restoreOverrideCursor() + self.mw.setEnabled(True) diff --git a/aqt/webview.py b/aqt/webview.py index e77a2562b..a43a8df84 100644 --- a/aqt/webview.py +++ b/aqt/webview.py @@ -68,6 +68,8 @@ class AnkiWebView(QWebView): self.setHtml(""" %s""" % (css, body), loadCB) + # ensure we're focused + self.setFocus() def setBridge(self, bridge): self._bridge.setBridge(bridge) def eval(self, js): diff --git a/designer/main.ui b/designer/main.ui index e041cee15..92988d235 100644 --- a/designer/main.ui +++ b/designer/main.ui @@ -664,17 +664,31 @@ + + + :/icons/document-open-remote.png:/icons/document-open-remote.png + Personal Deck... + + AnkiWeb + Download a deck that you synced from another computer + + + :/icons/download.png:/icons/download.png + Shared Deck... + + Download + Download a deck that people have shared publicly @@ -749,6 +763,15 @@ Localize Media + + + + :/icons/edit-redo.png:/icons/edit-redo.png + + + Refresh + +