From f2a39aad2a6ec45fd071ecdb328936803ad71824 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Sun, 27 Nov 2011 11:25:13 +0900 Subject: [PATCH] move the toolbar into a separate file and make it global --- aqt/about.py | 3 + aqt/deckbrowser.py | 9 +-- aqt/main.py | 22 +++++-- aqt/overview.py | 43 +------------- aqt/reviewer.py | 1 + aqt/toolbar.py | 102 +++++++++++++++++++++++++++++++++ aqt/webview.py | 10 ++-- designer/icons.qrc | 2 + designer/icons/clock-icon.png | Bin 0 -> 831 bytes designer/icons/plus-circle.png | Bin 0 -> 3541 bytes designer/main.ui | 5 -- 11 files changed, 134 insertions(+), 63 deletions(-) create mode 100644 aqt/toolbar.py create mode 100644 designer/icons/clock-icon.png create mode 100644 designer/icons/plus-circle.png diff --git a/aqt/about.py b/aqt/about.py index ccf6e19bd..3755aea85 100644 --- a/aqt/about.py +++ b/aqt/about.py @@ -32,6 +32,9 @@ Suba, and Xtru. Anki icon by Alex Fraser (CC GNU GPL) Deck icon by Laurent Baumann (CC BY-NC-SA 3.0) +Deck browser icons from: +http://led24.de/iconset +http://p.yusukekamiyamane.com/ Other icons under LGPL or public domain. """ diff --git a/aqt/deckbrowser.py b/aqt/deckbrowser.py index f2246c85e..0fb566ecd 100644 --- a/aqt/deckbrowser.py +++ b/aqt/deckbrowser.py @@ -62,7 +62,6 @@ body { margin: 1em; } _body = """
-

%(title)s

%(tree)s
@@ -98,12 +97,10 @@ body { margin: 1em; } return buf def _dueImg(self, due, new): - if due and new: - i = "both" - elif due: - i = "green" + if due: + i = "clock-icon" elif new: - i = "blue" + i = "plus-circle" else: i = "none" return '' % i diff --git a/aqt/main.py b/aqt/main.py index fec4bddfd..6c8263b94 100755 --- a/aqt/main.py +++ b/aqt/main.py @@ -15,7 +15,7 @@ from anki.utils import stripHTML, checksum, isWin, isMac from anki.hooks import runHook, addHook, removeHook import anki.consts -import aqt, aqt.progress, aqt.webview +import aqt, aqt.progress, aqt.webview, aqt.toolbar from aqt.utils import saveGeom, restoreGeom, showInfo, showWarning, \ saveState, restoreState, getOnlyText, askUser, GetTextDialog, \ askUserDialog, applyStyles, getText, showText, showCritical, getFile @@ -182,8 +182,10 @@ Are you sure?"""): restoreState(self, "mainWindow") else: self.resize(500, 400) + # toolbar needs to be retranslated + self.toolbar.draw() + # show and raise window for osx self.show() - # raise window for osx self.activateWindow() self.raise_() # maybe sync @@ -312,14 +314,23 @@ title="%s">%s''' % ( # main window self.form = aqt.forms.main.Ui_MainWindow() self.form.setupUi(self) - self.web = aqt.webview.AnkiWebView(self.form.centralwidget) + # toolbar + tweb = aqt.webview.AnkiWebView() + tweb.setObjectName("toolbarWeb") + tweb.setFocusPolicy(Qt.WheelFocus) + tweb.setFixedHeight(32) + self.toolbar = aqt.toolbar.Toolbar(self, tweb) + # main area + self.web = aqt.webview.AnkiWebView() self.web.setObjectName("mainText") self.web.setFocusPolicy(Qt.WheelFocus) + # add in a layout self.mainLayout = QVBoxLayout() - self.mainLayout.addWidget(self.web) self.mainLayout.setContentsMargins(0,0,0,0) + self.mainLayout.setSpacing(0) + self.mainLayout.addWidget(tweb) + self.mainLayout.addWidget(self.web) self.form.centralwidget.setLayout(self.mainLayout) - addHook("undoEnd", self.maybeEnableUndo) def closeAllWindows(self): aqt.dialogs.closeAll() @@ -607,6 +618,7 @@ Debug info:\n%s""") % traceback.format_exc(), help="DeckErrors") aqt.studyopts.StudyOptions(self) def onOverview(self): + self.col.reset() self.moveToState("overview") def onGroups(self, parent=None): diff --git a/aqt/overview.py b/aqt/overview.py index 39e894e02..91746c3bf 100644 --- a/aqt/overview.py +++ b/aqt/overview.py @@ -67,25 +67,7 @@ class Overview(object): shareLink = 'Reviews and Updates' else: shareLink = "" - header = """ - - - - - -
-""" #% deck['name'] - + header = "" self.web.stdHtml(self._overviewBody % dict( title=_("Overview"), table=tbl, @@ -134,29 +116,6 @@ $(function () { .sub { font-size: 80%; color: #555; } .smallLink { font-size: 12px; } h3 { margin-bottom: 0; } -#headerSpace { height: 22px; } -#header { -z-index: 100; -position: fixed; -height: 22px; -font-size: 12px; -margin:0; -background: -webkit-gradient(linear, left top, left bottom, -from(#ddd), to(#fff)); -border-bottom: 1px solid #ccc; -font-weight: bold; -} -body { margin: 0; } -.deck { } -.hitem { display: inline-block; padding: 4px; padding-right: 6px; -text-decoration: none; color: #000; -} -.hborder { border: 1px solid #ddd; } -.hitem:hover { -background: #333; -color: #fff; -} -.icon { padding-top: 2px; } """ def _overviewTable(self): diff --git a/aqt/reviewer.py b/aqt/reviewer.py index a20dd6e48..f6cd5e54f 100644 --- a/aqt/reviewer.py +++ b/aqt/reviewer.py @@ -526,6 +526,7 @@ div#filler { ########################################################################## def _setupStatus(self): + return self._statusWidgets = [] sb = self.mw.form.statusbar def addWgt(w, stretch=0): diff --git a/aqt/toolbar.py b/aqt/toolbar.py new file mode 100644 index 000000000..d748f9b5a --- /dev/null +++ b/aqt/toolbar.py @@ -0,0 +1,102 @@ +# Copyright: Damien Elmes +# -*- coding: utf-8 -*- +# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html + +from aqt.qt import * +from aqt.webview import AnkiWebView + +class Toolbar(object): + + def __init__(self, mw, web): + self.mw = mw + self.web = web + 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) + + # Available links + ###################################################################### + + centerLinks = [ + ["decks", "Decks"], + ["study", "Study"], + ["add", "Add"], + ["browse", "Browse"], + ] + + rightIcons = [ + ["stats", "qrc:/icons/view-statistics.png"], + ["sync", "qrc:/icons/view-refresh.png"], + ] + + def _centerLinks(self): + buf = "" + for ln, name in self.centerLinks: + buf += '%s' % (ln, _(name)) + return buf + + def _rightIcons(self): + buf = "" + for ln, icon in self.rightIcons: + buf += '' % ( + ln, icon) + return buf + + # Link handling + ###################################################################### + + def _linkHandler(self, l): + if l == "anki": + self.showMenu() + elif l == "decks": + self.mw.moveToState("deckBrowser") + elif l == "study": + self.mw.onOverview() + elif l == "add": + self.mw.onAddCard() + elif l == "browse": + self.mw.onBrowse() + elif l == "stats": + self.mw.onStats() + elif l == "sync": + self.mw.onSync() + + # HTML & CSS + ###################################################################### + + _body = """ + + + + + + +""" + + _css = """ +#header { +font-size: 12px; +margin:0; +background: -webkit-gradient(linear, left top, left bottom, +from(#ddd), to(#fff)); +font-weight: bold; +height: 10px; +margin-bottom: 1px; +border-bottom: 1px solid #aaa; +} + +body { margin: 0; padding: 0; } + +.hitem { display: inline-block; padding: 4px; padding-right: 6px; +text-decoration: none; color: #000; +} +.hitem:hover { +background: #333; +color: #fff; +} +""" diff --git a/aqt/webview.py b/aqt/webview.py index b03a179ed..5016b4b19 100644 --- a/aqt/webview.py +++ b/aqt/webview.py @@ -28,8 +28,8 @@ class Bridge(QObject): class AnkiWebPage(QWebPage): - def __init__(self, parent, jsErr): - QWebPage.__init__(self, parent) + def __init__(self, jsErr): + QWebPage.__init__(self) self._jsErr = jsErr def javaScriptConsoleMessage(self, msg, line, srcID): self._jsErr(msg, line, srcID) @@ -38,11 +38,11 @@ class AnkiWebPage(QWebPage): ########################################################################## class AnkiWebView(QWebView): - def __init__(self, parent): - QWebView.__init__(self, parent) + def __init__(self): + QWebView.__init__(self) self.setObjectName("mainText") self._bridge = Bridge() - self._page = AnkiWebPage(parent, self._jsErr) + self._page = AnkiWebPage(self._jsErr) self._loadFinishedCB = None self.setPage(self._page) self.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks) diff --git a/designer/icons.qrc b/designer/icons.qrc index afc539d1d..a6a9f8855 100644 --- a/designer/icons.qrc +++ b/designer/icons.qrc @@ -3,6 +3,8 @@ icons/blue.png icons/both.png icons/green.png + icons/clock-icon.png + icons/plus-circle.png icons/none.png icons/edit-find 2.png icons/edit-find-replace.png diff --git a/designer/icons/clock-icon.png b/designer/icons/clock-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0d2cab13829ea7cfbdf7e76174eb015c27d24c5e GIT binary patch literal 831 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 P00000NkvXXu0mjfJ - - - true - -