refactor file layout

- ankiqt->aqt
- move all the files in ui into the top level
- move icons_rc.py into aqt/forms, and the qrc into designer/
- remove setuptools
This commit is contained in:
Damien Elmes 2011-03-13 20:52:02 +09:00
parent b4a794dcb3
commit 103871a5b1
137 changed files with 329 additions and 423 deletions

6
.gitignore vendored
View file

@ -2,8 +2,4 @@
*.pyc *.pyc
*\# *\#
*~ *~
/icons_rc.py /aqt/forms
ankiqt/forms
/docs/manual.html
/docs/docbook-xsl.css
/docs/manual.xml

View file

@ -1 +0,0 @@
Please see Help>About in Anki.

38
README
View file

@ -3,11 +3,11 @@ Anki
Prerequisites for Linux/FreeBSD/etc: Prerequisites for Linux/FreeBSD/etc:
- a recent Python (2.4 should be fine) - Python 2.4+
- python-qt/pyqt 4.4+ - Python-Qt/PyQt 4.4+
- sqlalchemy 0.4.3+ - SimpleJSON 1.7.3+
- simplejson 1.7.3+ - PySQLite 1.3+ or Python2.5
- pysqlite2 1.3+ or python2.5 - Beautiful Soup
For graph generation: For graph generation:
@ -24,35 +24,11 @@ For audio recording support:
- pyaudio - pyaudio
- lame - lame
For importing SuperMemo XML and exporting text files:
- python-beautifulsoup
Running / Installation Running / Installation
------------------------------------- -------------------------------------
To run from the directory you've untarred it to, <todo>
$ ./anki
If you want to install it system wide,
$ (cd libanki && sudo python setup.py install)
$ sudo python setup.py install
$ anki
For more information and the latest version, please see the website at: For more information and the latest version, please see the website at:
http://ichi2.net/anki/ http://ankisrs.net/
Notes
-------------------------------------
There is a known issue with pysqlite 2.5.2-2.5.5 and older versions of
sqlalchemy. Either downgrade pysqlite to 2.5.1, or upgrade sqlalchemy to
0.5.3.
If you are unable to find pyqt 4.4+ in your distro and you run Ubuntu, you can
get it by adding the following to your /etc/sources.list:
deb http://ppa.launchpad.net/kubuntu-members-kde4/ubuntu hardy main

View file

@ -8,8 +8,10 @@ $ git clone https://github.com/dae/ankiqt.git
$ cd ankiqt $ cd ankiqt
$ ./tools/build_ui.sh $ ./tools/build_ui.sh
Make sure you rebuild the UI every time you update the sources.
The translations are stored in a bazaar repo for integration with launchpad's The translations are stored in a bazaar repo for integration with launchpad's
translation services. If you want to use a language other than English, edit translation services. If you want to use a language other than English:
$ cd .. $ cd ..
$ mv libanki lib $ mv libanki lib

View file

@ -1 +0,0 @@
../icons_rc.py

View file

@ -1,72 +0,0 @@
# Copyright: Damien Elmes <anki@ichi2.net>
# License: GNU GPL, version 3 or later; http://www.gnu.org/copyleft/gpl.html
def importAll():
# a hack
import main
import about
import activetags
import addcards
import cardlist
import deckproperties
import importing
import clayout
import exporting
import facteditor
import help
import modelchooser
import modelproperties
import preferences
import status
import sync
import tagedit
import tray
import unsaved
import update
import utils
import view
import getshared
class DialogManager(object):
def __init__(self):
self.modelessDialogs = {}
def registerDialog(self, name, klass):
self.modelessDialogs[name] = (klass, None)
def open(self, name, obj):
self.modelessDialogs[name] = (
self.modelessDialogs[name][0], obj)
def close(self, name):
self.modelessDialogs[name] = (
self.modelessDialogs[name][0], None)
def get(self, name, *args):
(klass, obj) = self.modelessDialogs[name]
if obj:
obj.activateWindow()
obj.raise_()
return obj
else:
return klass(*args)
def closeAll(self):
for (n, (klass, obj)) in self.modelessDialogs.items():
if obj:
obj.forceClose = True
obj.close()
self.close(n)
# since we load the graphs dynamically, we need a proxy for this
def graphProxy(self, *args):
import graphs
return graphs.intervalGraph(*args)
def registerDialogs(self):
self.registerDialog("AddCards", addcards.AddCards)
self.registerDialog("CardList", cardlist.EditDeck)
self.registerDialog("Graphs", self.graphProxy)
dialogs = DialogManager()

View file

@ -1,17 +1,5 @@
#!/usr/bin/env python #!/usr/bin/env python
#
# hack because py2app barfs on a try block # hack because py2app barfs on a try block
#
import pkg_resources import aqt
aqt.run()
import os, sys
modDir=os.path.dirname(os.path.abspath(__file__))
runningDir=os.path.split(modDir)[0]
# set up paths for local development
sys.path.insert(0, os.path.join(runningDir, "libanki"))
sys.path.insert(0, os.path.join(os.path.join(runningDir, ".."), "libanki"))
import ankiqt
ankiqt.run()

View file

@ -14,6 +14,7 @@ appIssueTracker="http://code.google.com/p/anki/issues/list"
appForum="http://groups.google.com/group/ankisrs/topics" appForum="http://groups.google.com/group/ankisrs/topics"
appReleaseNotes="http://ankisrs.net/changes.html" appReleaseNotes="http://ankisrs.net/changes.html"
appDonate="http://ankisrs.net/support/" appDonate="http://ankisrs.net/support/"
mw = None # will be set in init
modDir=os.path.dirname(os.path.abspath(__file__)) modDir=os.path.dirname(os.path.abspath(__file__))
runningDir=os.path.split(modDir)[0] runningDir=os.path.split(modDir)[0]
@ -22,8 +23,52 @@ if hasattr(sys, "frozen"):
sys.path.append(modDir) sys.path.append(modDir)
modDir = os.path.dirname(sys.argv[0]) modDir = os.path.dirname(sys.argv[0])
# we bundle icons_rc as part of the anki source # Dialog manager
sys.path.append(os.path.dirname(__file__)) ##########################################################################
class DialogManager(object):
def __init__(self):
self.modelessDialogs = {}
def registerDialog(self, name, klass):
self.modelessDialogs[name] = (klass, None)
def open(self, name, obj):
self.modelessDialogs[name] = (
self.modelessDialogs[name][0], obj)
def close(self, name):
self.modelessDialogs[name] = (
self.modelessDialogs[name][0], None)
def get(self, name, *args):
(klass, obj) = self.modelessDialogs[name]
if obj:
obj.activateWindow()
obj.raise_()
return obj
else:
return klass(*args)
def closeAll(self):
for (n, (klass, obj)) in self.modelessDialogs.items():
if obj:
obj.forceClose = True
obj.close()
self.close(n)
# since we load the graphs dynamically, we need a proxy for this
def graphProxy(self, *args):
import graphs
return graphs.intervalGraph(*args)
def registerDialogs(self):
self.registerDialog("AddCards", addcards.AddCards)
self.registerDialog("CardList", cardlist.EditDeck)
self.registerDialog("Graphs", self.graphProxy)
dialogs = DialogManager()
# App initialisation # App initialisation
########################################################################## ##########################################################################
@ -137,9 +182,8 @@ def run():
sys.exit(1) sys.exit(1)
import forms import forms
import ui
ui.splash = SplashScreen(3) splash = SplashScreen(3)
import anki import anki
if anki.version != appVersion: if anki.version != appVersion:
@ -157,8 +201,8 @@ def run():
(opts, args) = parser.parse_args(sys.argv[1:]) (opts, args) = parser.parse_args(sys.argv[1:])
# configuration # configuration
import ankiqt.config import aqt.config
conf = ankiqt.config.Config( conf = aqt.config.Config(
unicode(os.path.abspath(opts.config), sys.getfilesystemencoding())) unicode(os.path.abspath(opts.config), sys.getfilesystemencoding()))
# qt translations # qt translations
@ -180,11 +224,12 @@ def run():
app.setStyle("plastique") app.setStyle("plastique")
# load main window # load main window
ui.importAll() import aqt.main
ui.dialogs.registerDialogs() #ui.importAll()
ui.splash.update() #ui.dialogs.registerDialogs()
splash.update()
mw = ui.main.AnkiQt(app, conf, args) mw = aqt.main.AnkiQt(app, conf, args, splash)
app.exec_() app.exec_()

View file

@ -3,12 +3,12 @@
# License: GNU GPL, version 3 or later; http://www.gnu.org/copyleft/gpl.html # License: GNU GPL, version 3 or later; http://www.gnu.org/copyleft/gpl.html
from PyQt4.QtGui import * from PyQt4.QtGui import *
import ankiqt.forms import aqt.forms
from ankiqt import appVersion from aqt import appVersion
def show(parent): def show(parent):
dialog = QDialog(parent) dialog = QDialog(parent)
abt = ankiqt.forms.about.Ui_About() abt = aqt.forms.about.Ui_About()
abt.setupUi(dialog) abt.setupUi(dialog)
abouttext = "<center><img src=':/icons/anki-logo-thin.png'></center>" abouttext = "<center><img src=':/icons/anki-logo-thin.png'></center>"
abouttext += '<p>' + _("Anki is a friendly, intelligent spaced learning \ abouttext += '<p>' + _("Anki is a friendly, intelligent spaced learning \

View file

@ -3,9 +3,9 @@
from PyQt4.QtGui import * from PyQt4.QtGui import *
from PyQt4.QtCore import * from PyQt4.QtCore import *
import ankiqt import aqt
from anki.utils import parseTags, joinTags, canonifyTags from anki.utils import parseTags, joinTags, canonifyTags
from ankiqt.ui.utils import saveGeom, restoreGeom from aqt.ui.utils import saveGeom, restoreGeom
class ActiveTagsChooser(QDialog): class ActiveTagsChooser(QDialog):
@ -13,7 +13,7 @@ class ActiveTagsChooser(QDialog):
QDialog.__init__(self, parent, Qt.Window) QDialog.__init__(self, parent, Qt.Window)
self.parent = parent self.parent = parent
self.deck = self.parent.deck self.deck = self.parent.deck
self.dialog = ankiqt.forms.activetags.Ui_Dialog() self.dialog = aqt.forms.activetags.Ui_Dialog()
self.dialog.setupUi(self) self.dialog.setupUi(self)
if type == "new": if type == "new":
self.active = "newActive" self.active = "newActive"
@ -129,7 +129,7 @@ class ActiveTagsChooser(QDialog):
QDialog.accept(self) QDialog.accept(self)
def onHelp(self): def onHelp(self):
QDesktopServices.openUrl(QUrl(ankiqt.appWiki + QDesktopServices.openUrl(QUrl(aqt.appWiki +
"SelectiveStudy")) "SelectiveStudy"))
def show(parent, type): def show(parent, type):

View file

@ -4,13 +4,13 @@
from PyQt4.QtGui import * from PyQt4.QtGui import *
from PyQt4.QtCore import * from PyQt4.QtCore import *
import sys, re import sys, re
import ankiqt.forms import aqt.forms
import anki import anki
from anki.facts import Fact from anki.facts import Fact
from anki.errors import * from anki.errors import *
from anki.utils import stripHTML, parseTags from anki.utils import stripHTML, parseTags
from ankiqt.ui.utils import saveGeom, restoreGeom, saveSplitter, restoreSplitter from aqt.ui.utils import saveGeom, restoreGeom, saveSplitter, restoreSplitter
from ankiqt import ui from aqt import ui
from anki.sound import clearAudioQueue from anki.sound import clearAudioQueue
from anki.hooks import addHook, removeHook from anki.hooks import addHook, removeHook
@ -31,7 +31,7 @@ class AddCards(QDialog):
self.parent = parent self.parent = parent
ui.utils.applyStyles(self) ui.utils.applyStyles(self)
self.config = parent.config self.config = parent.config
self.dialog = ankiqt.forms.addcards.Ui_AddCards() self.dialog = aqt.forms.addcards.Ui_AddCards()
self.dialog.setupUi(self) self.dialog.setupUi(self)
self.setWindowTitle(_("Add Items - %s") % parent.deck.name()) self.setWindowTitle(_("Add Items - %s") % parent.deck.name())
self.setupEditor() self.setupEditor()
@ -63,7 +63,7 @@ class AddCards(QDialog):
self.dialog.modelArea.setLayout(self.modelChooser) self.dialog.modelArea.setLayout(self.modelChooser)
def helpRequested(self): def helpRequested(self):
QDesktopServices.openUrl(QUrl(ankiqt.appWiki + "AddItems")) QDesktopServices.openUrl(QUrl(aqt.appWiki + "AddItems"))
def addButtons(self): def addButtons(self):
self.addButton = QPushButton(_("Add")) self.addButton = QPushButton(_("Add"))

View file

@ -8,12 +8,12 @@ from PyQt4.QtCore import *
from PyQt4.QtWebKit import QWebPage from PyQt4.QtWebKit import QWebPage
import time, types, sys, re import time, types, sys, re
from operator import attrgetter, itemgetter from operator import attrgetter, itemgetter
import anki, anki.utils, ankiqt.forms import anki, anki.utils, aqt.forms
from ankiqt import ui from aqt import ui
from anki.utils import fmtTimeSpan, parseTags, hasTag, addTags, delTags, \ from anki.utils import fmtTimeSpan, parseTags, hasTag, addTags, delTags, \
stripHTMLAlt, ids2str stripHTMLAlt, ids2str
from ankiqt.ui.utils import saveGeom, restoreGeom, saveSplitter, restoreSplitter from aqt.ui.utils import saveGeom, restoreGeom, saveSplitter, restoreSplitter
from ankiqt.ui.utils import saveHeader, restoreHeader, saveState, \ from aqt.ui.utils import saveHeader, restoreHeader, saveState, \
restoreState, applyStyles restoreState, applyStyles
from anki.errors import * from anki.errors import *
from anki.db import * from anki.db import *
@ -356,7 +356,7 @@ class EditDeck(QMainWindow):
self.origModTime = parent.deck.modified self.origModTime = parent.deck.modified
self.currentRow = None self.currentRow = None
self.lastFilter = "" self.lastFilter = ""
self.dialog = ankiqt.forms.cardlist.Ui_MainWindow() self.dialog = aqt.forms.cardlist.Ui_MainWindow()
self.dialog.setupUi(self) self.dialog.setupUi(self)
self.setUnifiedTitleAndToolBarOnMac(True) self.setUnifiedTitleAndToolBarOnMac(True)
restoreGeom(self, "editor", 38) restoreGeom(self, "editor", 38)
@ -919,7 +919,7 @@ where id in (%s)""" % ",".join([
def reschedule(self): def reschedule(self):
n = _("Reschedule") n = _("Reschedule")
d = QDialog(self) d = QDialog(self)
frm = ankiqt.forms.reschedule.Ui_Dialog() frm = aqt.forms.reschedule.Ui_Dialog()
frm.setupUi(d) frm.setupUi(d)
if not d.exec_(): if not d.exec_():
return return
@ -1066,7 +1066,7 @@ where id in %s""" % ids2str(sf))
def onFont(self): def onFont(self):
d = QDialog(self) d = QDialog(self)
frm = ankiqt.forms.editfont.Ui_Dialog() frm = aqt.forms.editfont.Ui_Dialog()
frm.setupUi(d) frm.setupUi(d)
frm.fontCombo.setCurrentFont(QFont( frm.fontCombo.setCurrentFont(QFont(
self.parent.config['editFontFamily'])) self.parent.config['editFontFamily']))
@ -1097,7 +1097,7 @@ where id in %s""" % ids2str(sf))
parent=self) parent=self)
return return
d = QDialog(self) d = QDialog(self)
frm = ankiqt.forms.findreplace.Ui_Dialog() frm = aqt.forms.findreplace.Ui_Dialog()
frm.setupUi(d) frm.setupUi(d)
fields = sorted(self.currentCard.fact.model.fieldModels, key=attrgetter("name")) fields = sorted(self.currentCard.fact.model.fieldModels, key=attrgetter("name"))
frm.field.addItems(QStringList( frm.field.addItems(QStringList(
@ -1139,14 +1139,14 @@ where id in %s""" % ids2str(sf))
}, parent=self) }, parent=self)
def onFindReplaceHelp(self): def onFindReplaceHelp(self):
QDesktopServices.openUrl(QUrl(ankiqt.appWiki + QDesktopServices.openUrl(QUrl(aqt.appWiki +
"Browser#FindReplace")) "Browser#FindReplace"))
# Edit: finding dupes # Edit: finding dupes
###################################################################### ######################################################################
def onFindDupes(self): def onFindDupes(self):
win = QDialog(self) win = QDialog(self)
dialog = ankiqt.forms.finddupes.Ui_Dialog() aqt = ankiqt.forms.finddupes.Ui_Dialog()
dialog.setupUi(win) dialog.setupUi(win)
restoreGeom(win, "findDupes") restoreGeom(win, "findDupes")
fields = sorted(self.currentCard.fact.model.fieldModels, key=attrgetter("name")) fields = sorted(self.currentCard.fact.model.fieldModels, key=attrgetter("name"))
@ -1272,7 +1272,7 @@ select fm.id, fm.name from fieldmodels fm""")
###################################################################### ######################################################################
def onHelp(self): def onHelp(self):
QDesktopServices.openUrl(QUrl(ankiqt.appWiki + "Browser")) QDesktopServices.openUrl(QUrl(aqt.appWiki + "Browser"))
# Generate card dialog # Generate card dialog
###################################################################### ######################################################################
@ -1283,7 +1283,7 @@ class AddCardChooser(QDialog):
QDialog.__init__(self, parent, Qt.Window) QDialog.__init__(self, parent, Qt.Window)
self.parent = parent self.parent = parent
self.cms = cms self.cms = cms
self.dialog = ankiqt.forms.addcardmodels.Ui_Dialog() self.dialog = aqt.forms.addcardmodels.Ui_Dialog()
self.dialog.setupUi(self) self.dialog.setupUi(self)
self.connect(self.dialog.buttonBox, SIGNAL("helpRequested()"), self.connect(self.dialog.buttonBox, SIGNAL("helpRequested()"),
self.onHelp) self.onHelp)
@ -1317,7 +1317,7 @@ order by ordinal""" % ids2str(self.cms))
QDialog.accept(self) QDialog.accept(self)
def onHelp(self): def onHelp(self):
QDesktopServices.openUrl(QUrl(ankiqt.appWiki + QDesktopServices.openUrl(QUrl(aqt.appWiki +
"Browser#GenerateCards")) "Browser#GenerateCards"))
# Change model dialog # Change model dialog
@ -1331,7 +1331,7 @@ class ChangeModelDialog(QDialog):
self.origModel = self.parent.deck.currentModel self.origModel = self.parent.deck.currentModel
self.oldModel = oldModel self.oldModel = oldModel
self.oldTemplate = oldTemplate self.oldTemplate = oldTemplate
self.form = ankiqt.forms.changemodel.Ui_Dialog() self.form = aqt.forms.changemodel.Ui_Dialog()
self.form.setupUi(self) self.form.setupUi(self)
# maps # maps
self.fieldMapWidget = None self.fieldMapWidget = None
@ -1478,5 +1478,5 @@ Are you sure you want to continue?"""), parent=self):
return QDialog.accept(self) return QDialog.accept(self)
def onHelp(self): def onHelp(self):
QDesktopServices.openUrl(QUrl(ankiqt.appWiki + QDesktopServices.openUrl(QUrl(aqt.appWiki +
"Browser#ChangeModel")) "Browser#ChangeModel"))

View file

@ -5,16 +5,16 @@ from PyQt4.QtGui import *
from PyQt4.QtCore import * from PyQt4.QtCore import *
from PyQt4.QtWebKit import QWebPage, QWebView from PyQt4.QtWebKit import QWebPage, QWebView
import sys, re import sys, re
import ankiqt.forms import aqt.forms
import anki import anki
from anki.models import * from anki.models import *
from anki.facts import * from anki.facts import *
from anki.cards import Card from anki.cards import Card
from anki.sound import playFromText, clearAudioQueue from anki.sound import playFromText, clearAudioQueue
from ankiqt.ui.utils import saveGeom, restoreGeom, getBase, mungeQA, \ from aqt.ui.utils import saveGeom, restoreGeom, getBase, mungeQA, \
saveSplitter, restoreSplitter saveSplitter, restoreSplitter
from anki.hooks import runFilter from anki.hooks import runFilter
from ankiqt import ui from aqt import ui
class ResizingTextEdit(QTextEdit): class ResizingTextEdit(QTextEdit):
def sizeHint(self): def sizeHint(self):
@ -25,7 +25,7 @@ class CardLayout(QDialog):
def __init__(self, parent, factedit, factOrModel, card=None): def __init__(self, parent, factedit, factOrModel, card=None):
self.parent = parent self.parent = parent
QDialog.__init__(self, parent, Qt.Window) QDialog.__init__(self, parent, Qt.Window)
self.mw = ankiqt.mw self.mw = aqt.mw
self.deck = self.mw.deck self.deck = self.mw.deck
self.factedit = factedit self.factedit = factedit
self.card = card self.card = card
@ -69,7 +69,7 @@ class CardLayout(QDialog):
"Please enter some text first."), "Please enter some text first."),
parent=self.parent) parent=self.parent)
return return
self.form = ankiqt.forms.clayout.Ui_Dialog() self.form = aqt.forms.clayout.Ui_Dialog()
self.form.setupUi(self) self.form.setupUi(self)
restoreSplitter(self.form.splitter, "clayout") restoreSplitter(self.form.splitter, "clayout")
if type == 0: if type == 0:
@ -325,7 +325,7 @@ order by n""", id=card.id)
QDialog.reject(self) QDialog.reject(self)
def onHelp(self): def onHelp(self):
QDesktopServices.openUrl(QUrl(ankiqt.appWiki + QDesktopServices.openUrl(QUrl(aqt.appWiki +
"CardLayout")) "CardLayout"))
# Fields # Fields

View file

@ -4,14 +4,14 @@
from PyQt4.QtGui import * from PyQt4.QtGui import *
from PyQt4.QtCore import * from PyQt4.QtCore import *
import sys, re, time import sys, re, time
import ankiqt.forms import aqt.forms
import anki import anki
from ankiqt import ui from aqt import ui
from anki.utils import parseTags from anki.utils import parseTags
from anki.deck import newCardOrderLabels, newCardSchedulingLabels from anki.deck import newCardOrderLabels, newCardSchedulingLabels
from anki.deck import revCardOrderLabels from anki.deck import revCardOrderLabels
from anki.utils import hexifyID, dehexifyID from anki.utils import hexifyID, dehexifyID
import ankiqt import aqt
class DeckProperties(QDialog): class DeckProperties(QDialog):
@ -21,7 +21,7 @@ class DeckProperties(QDialog):
self.d = deck self.d = deck
self.onFinish = onFinish self.onFinish = onFinish
self.origMod = self.d.modified self.origMod = self.d.modified
self.dialog = ankiqt.forms.deckproperties.Ui_DeckProperties() self.dialog = aqt.forms.deckproperties.Ui_DeckProperties()
self.dialog.setupUi(self) self.dialog.setupUi(self)
self.dialog.buttonBox.button(QDialogButtonBox.Help).setAutoDefault(False) self.dialog.buttonBox.button(QDialogButtonBox.Help).setAutoDefault(False)
self.dialog.buttonBox.button(QDialogButtonBox.Close).setAutoDefault(False) self.dialog.buttonBox.button(QDialogButtonBox.Close).setAutoDefault(False)
@ -84,8 +84,8 @@ class DeckProperties(QDialog):
self.dialog.modelsList.addItem(item) self.dialog.modelsList.addItem(item)
cm = self.d.currentModel cm = self.d.currentModel
try: try:
if ankiqt.mw.currentCard: if aqt.mw.currentCard:
cm = ankiqt.mw.currentCard.fact.model cm = aqt.mw.currentCard.fact.model
except: except:
# model has been deleted # model has been deleted
pass pass
@ -133,7 +133,7 @@ class DeckProperties(QDialog):
self.d.deleteModel(model) self.d.deleteModel(model)
self.updateModelsList() self.updateModelsList()
self.dialog.modelsList.setCurrentRow(row) self.dialog.modelsList.setCurrentRow(row)
ankiqt.mw.reset() aqt.mw.reset()
def selectedModel(self): def selectedModel(self):
row = self.dialog.modelsList.currentRow() row = self.dialog.modelsList.currentRow()
@ -147,7 +147,7 @@ class DeckProperties(QDialog):
self.d.setModified() self.d.setModified()
def helpRequested(self): def helpRequested(self):
QDesktopServices.openUrl(QUrl(ankiqt.appWiki + QDesktopServices.openUrl(QUrl(aqt.appWiki +
"DeckProperties")) "DeckProperties"))
def reject(self): def reject(self):
@ -230,12 +230,12 @@ class DeckProperties(QDialog):
self.d.setVar('perDay', self.dialog.perDay.isChecked()) self.d.setVar('perDay', self.dialog.perDay.isChecked())
# mark deck dirty and close # mark deck dirty and close
if self.origMod != self.d.modified: if self.origMod != self.d.modified:
ankiqt.mw.deck.updateCutoff() aqt.mw.deck.updateCutoff()
ankiqt.mw.reset() aqt.mw.reset()
self.d.setUndoEnd(n) self.d.setUndoEnd(n)
self.d.finishProgress() self.d.finishProgress()
if self.onFinish: if self.onFinish:
self.onFinish() self.onFinish()
QDialog.reject(self) QDialog.reject(self)
if needSync: if needSync:
ankiqt.mw.syncDeck(interactive=-1) aqt.mw.syncDeck(interactive=-1)

View file

@ -3,10 +3,10 @@
from PyQt4.QtGui import * from PyQt4.QtGui import *
from PyQt4.QtCore import * from PyQt4.QtCore import *
import anki, ankiqt import anki, aqt
from anki.exporting import exporters as exporters_ from anki.exporting import exporters as exporters_
from anki.utils import parseTags from anki.utils import parseTags
from ankiqt import ui from aqt import ui
class PackagedAnkiExporter(object): class PackagedAnkiExporter(object):
def __init__(self, *args): def __init__(self, *args):
@ -24,7 +24,7 @@ class ExportDialog(QDialog):
QDialog.__init__(self, parent, Qt.Window) QDialog.__init__(self, parent, Qt.Window)
self.parent = parent self.parent = parent
self.deck = parent.deck self.deck = parent.deck
self.dialog = ankiqt.forms.exporting.Ui_ExportDialog() self.dialog = aqt.forms.exporting.Ui_ExportDialog()
self.dialog.setupUi(self) self.dialog.setupUi(self)
self.exporter = None self.exporter = None
self.setup() self.setup()

View file

@ -8,11 +8,10 @@ from PyQt4.QtSvg import *
from PyQt4.QtWebKit import QWebPage from PyQt4.QtWebKit import QWebPage
import re, os, sys, tempfile, urllib2, ctypes import re, os, sys, tempfile, urllib2, ctypes
from anki.utils import stripHTML, tidyHTML, canonifyTags, fieldChecksum from anki.utils import stripHTML, tidyHTML, canonifyTags, fieldChecksum
from ankiqt.ui.sound import getAudio from aqt.sound import getAudio
import anki.sound import anki.sound
from ankiqt import ui import aqt
import ankiqt from aqt.utils import mungeQA, saveGeom, restoreGeom
from ankiqt.ui.utils import mungeQA, saveGeom, restoreGeom
from anki.hooks import addHook, removeHook, runHook, runFilter from anki.hooks import addHook, removeHook, runHook, runFilter
from sqlalchemy.exceptions import InvalidRequestError from sqlalchemy.exceptions import InvalidRequestError
@ -144,7 +143,8 @@ class FactEditor(object):
self.tagsBox = QHBoxLayout() self.tagsBox = QHBoxLayout()
self.tagsLabel = QLabel(_("Tags")) self.tagsLabel = QLabel(_("Tags"))
self.tagsBox.addWidget(self.tagsLabel) self.tagsBox.addWidget(self.tagsLabel)
self.tags = ui.tagedit.TagEdit(self.parent) import aqt.tagedit
self.tags = aqt.tagedit.TagEdit(self.parent)
self.tags.connect(self.tags, SIGNAL("lostFocus"), self.tags.connect(self.tags, SIGNAL("lostFocus"),
self.onTagChange) self.onTagChange)
self.tagsBox.addWidget(self.tags) self.tagsBox.addWidget(self.tags)
@ -337,7 +337,7 @@ class FactEditor(object):
self.fieldsFrame = None self.fieldsFrame = None
self.widget.setLayout(self.fieldsBox) self.widget.setLayout(self.fieldsBox)
# show advanced buttons? # show advanced buttons?
if not ankiqt.mw.config['factEditorAdvanced']: if not aqt.mw.config['factEditorAdvanced']:
self.onMore(False) self.onMore(False)
def _makeGrid(self): def _makeGrid(self):
@ -476,7 +476,7 @@ class FactEditor(object):
return modified return modified
def onFocusLost(self, widget): def onFocusLost(self, widget):
from ankiqt import mw from aqt import mw
if not self.fact: if not self.fact:
# editor or deck closed # editor or deck closed
return return
@ -488,7 +488,7 @@ class FactEditor(object):
self.fact.setModified(textChanged=True, deck=self.deck) self.fact.setModified(textChanged=True, deck=self.deck)
self.loadFields(font=False) self.loadFields(font=False)
if modified and self.resetOnEdit: if modified and self.resetOnEdit:
ankiqt.mw.reset(runHooks=False) aqt.mw.reset(runHooks=False)
def onTextChanged(self): def onTextChanged(self):
interval = 250 interval = 250
@ -503,7 +503,7 @@ class FactEditor(object):
self.onChangeTimer) self.onChangeTimer)
def onChangeTimer(self): def onChangeTimer(self):
from ankiqt import mw from aqt import mw
interval = 250 interval = 250
if not self.fact: if not self.fact:
return return
@ -591,7 +591,7 @@ class FactEditor(object):
self.fact.setModified(textChanged=True, deck=self.deck) self.fact.setModified(textChanged=True, deck=self.deck)
self.deck.flushMod() self.deck.flushMod()
if self.resetOnEdit: if self.resetOnEdit:
ankiqt.mw.reset(runHooks=False) aqt.mw.reset(runHooks=False)
if self.onChange: if self.onChange:
self.onChange('tag') self.onChange('tag')
@ -665,7 +665,7 @@ class FactEditor(object):
txtcol) txtcol)
def colourChanged(self): def colourChanged(self):
recent = ankiqt.mw.config['recentColours'] recent = aqt.mw.config['recentColours']
self._updateForegroundButton(recent[-1]) self._updateForegroundButton(recent[-1])
def onForeground(self): def onForeground(self):
@ -683,7 +683,7 @@ class FactEditor(object):
self.colourChoose = QShortcut(QKeySequence("F6"), p) self.colourChoose = QShortcut(QKeySequence("F6"), p)
p.connect(self.colourChoose, SIGNAL("activated()"), p.connect(self.colourChoose, SIGNAL("activated()"),
self.onChooseColourKey) self.onChooseColourKey)
for n, c in enumerate(reversed(ankiqt.mw.config['recentColours'])): for n, c in enumerate(reversed(aqt.mw.config['recentColours'])):
col = QToolButton() col = QToolButton()
col.setAutoRaise(True) col.setAutoRaise(True)
col.setFixedWidth(64) col.setFixedWidth(64)
@ -717,7 +717,7 @@ class FactEditor(object):
p.show() p.show()
def onRemoveColour(self, colour): def onRemoveColour(self, colour):
recent = ankiqt.mw.config['recentColours'] recent = aqt.mw.config['recentColours']
recent.remove(colour) recent.remove(colour)
if not recent: if not recent:
recent.append("#000000") recent.append("#000000")
@ -739,7 +739,7 @@ class FactEditor(object):
pass pass
def onChooseColour(self, colour): def onChooseColour(self, colour):
recent = ankiqt.mw.config['recentColours'] recent = aqt.mw.config['recentColours']
recent.remove(colour) recent.remove(colour)
recent.append(colour) recent.append(colour)
w = self.lastFocusedEdit w = self.lastFocusedEdit
@ -751,7 +751,7 @@ class FactEditor(object):
def onNewColour(self): def onNewColour(self):
new = QColorDialog.getColor(Qt.white, self.parent) new = QColorDialog.getColor(Qt.white, self.parent)
self.parent.raise_() self.parent.raise_()
recent = ankiqt.mw.config['recentColours'] recent = aqt.mw.config['recentColours']
if new.isValid(): if new.isValid():
txtcol = unicode(new.name()) txtcol = unicode(new.name())
if txtcol not in recent: if txtcol not in recent:
@ -795,7 +795,7 @@ class FactEditor(object):
def onMore(self, toggle=None): def onMore(self, toggle=None):
if toggle is None: if toggle is None:
toggle = not self.latex.isVisible() toggle = not self.latex.isVisible()
ankiqt.mw.config['factEditorAdvanced'] = toggle aqt.mw.config['factEditorAdvanced'] = toggle
self.latex.setShown(toggle) self.latex.setShown(toggle)
self.latexEqn.setShown(toggle) self.latexEqn.setShown(toggle)
self.latexMathEnv.setShown(toggle) self.latexMathEnv.setShown(toggle)
@ -884,13 +884,13 @@ class FactEditor(object):
def onHtmlEdit(self): def onHtmlEdit(self):
def helpRequested(): def helpRequested():
QDesktopServices.openUrl(QUrl(ankiqt.appWiki + QDesktopServices.openUrl(QUrl(aqt.appWiki +
"HtmlEditor")) "HtmlEditor"))
w = self.focusedEdit() w = self.focusedEdit()
if w: if w:
self.saveFields() self.saveFields()
d = QDialog(self.parent) d = QDialog(self.parent)
form = ankiqt.forms.edithtml.Ui_Dialog() form = aqt.forms.edithtml.Ui_Dialog()
form.setupUi(d) form.setupUi(d)
d.connect(form.buttonBox, SIGNAL("helpRequested()"), d.connect(form.buttonBox, SIGNAL("helpRequested()"),
helpRequested) helpRequested)
@ -972,7 +972,7 @@ class FactEditor(object):
w.insertHtml('[sound:%s]' % path) w.insertHtml('[sound:%s]' % path)
def maybeDelete(self, new, old): def maybeDelete(self, new, old):
if not ankiqt.mw.config['deleteMedia']: if not aqt.mw.config['deleteMedia']:
return return
if new == os.path.basename(old): if new == os.path.basename(old):
return return
@ -1022,7 +1022,7 @@ class FactEdit(QTextEdit):
if source.hasHtml() and "qrichtext" in unicode(source.html()): if source.hasHtml() and "qrichtext" in unicode(source.html()):
self.insertHtml(source.html()) self.insertHtml(source.html())
return True return True
if source.hasText() and (ankiqt.mw.config['stripHTML'] or if source.hasText() and (aqt.mw.config['stripHTML'] or
not source.hasHtml()): not source.hasHtml()):
txt = unicode(source.text()) txt = unicode(source.text())
l = txt.lower() l = txt.lower()
@ -1086,7 +1086,7 @@ class FactEdit(QTextEdit):
def _retrieveURL(self, url): def _retrieveURL(self, url):
req = urllib2.Request(url, None, { req = urllib2.Request(url, None, {
'User-Agent': 'Mozilla/5.0 (compatible; Anki/%s)' % 'User-Agent': 'Mozilla/5.0 (compatible; Anki/%s)' %
ankiqt.appVersion }) aqt.appVersion })
filecontents = urllib2.urlopen(req).read() filecontents = urllib2.urlopen(req).read()
path = os.path.join(self.tmpDir(), os.path.basename(url)) path = os.path.join(self.tmpDir(), os.path.basename(url))
file = open(path, "wb") file = open(path, "wb")
@ -1101,7 +1101,7 @@ class FactEdit(QTextEdit):
def simplifyHTML(self, html): def simplifyHTML(self, html):
"Remove all style information and P tags." "Remove all style information and P tags."
if not ankiqt.mw.config['stripHTML']: if not aqt.mw.config['stripHTML']:
return html return html
html = re.sub("\n", " ", html) html = re.sub("\n", " ", html)
html = re.sub("<br ?/?>", "\n", html) html = re.sub("<br ?/?>", "\n", html)
@ -1117,7 +1117,7 @@ class FactEdit(QTextEdit):
self.parent.lastFocusedEdit = self self.parent.lastFocusedEdit = self
self.parent.resetFormatButtons() self.parent.resetFormatButtons()
self.parent.disableButtons() self.parent.disableButtons()
if ankiqt.mw.config['preserveKeyboard'] and sys.platform.startswith("win32"): if aqt.mw.config['preserveKeyboard'] and sys.platform.startswith("win32"):
self._ownLayout = GetKeyboardLayout(0) self._ownLayout = GetKeyboardLayout(0)
ActivateKeyboardLayout(self._programLayout, 0) ActivateKeyboardLayout(self._programLayout, 0)
self.emit(SIGNAL("lostFocus")) self.emit(SIGNAL("lostFocus"))
@ -1137,7 +1137,7 @@ class FactEdit(QTextEdit):
QTextEdit.focusInEvent(self, evt) QTextEdit.focusInEvent(self, evt)
self.parent.formatChanged(None) self.parent.formatChanged(None)
self.parent.enableButtons() self.parent.enableButtons()
if ankiqt.mw.config['preserveKeyboard'] and sys.platform.startswith("win32"): if aqt.mw.config['preserveKeyboard'] and sys.platform.startswith("win32"):
self._programLayout = GetKeyboardLayout(0) self._programLayout = GetKeyboardLayout(0)
if self._ownLayout == None: if self._ownLayout == None:
self._ownLayout = self._programLayout self._ownLayout = self._programLayout

View file

@ -4,9 +4,9 @@
from PyQt4.QtGui import * from PyQt4.QtGui import *
from PyQt4.QtCore import * from PyQt4.QtCore import *
import ankiqt, simplejson, time, cStringIO, zipfile, tempfile, os, re, gzip import aqt, simplejson, time, cStringIO, zipfile, tempfile, os, re, gzip
import traceback, urllib2, socket, cgi import traceback, urllib2, socket, cgi
from ankiqt.ui.utils import saveGeom, restoreGeom, showInfo from aqt.ui.utils import saveGeom, restoreGeom, showInfo
from anki.utils import fmtTimeSpan from anki.utils import fmtTimeSpan
URL = "http://ankiweb.net/file/" URL = "http://ankiweb.net/file/"
@ -29,7 +29,7 @@ class GetShared(QDialog):
def __init__(self, parent, type): def __init__(self, parent, type):
QDialog.__init__(self, parent, Qt.Window) QDialog.__init__(self, parent, Qt.Window)
self.parent = parent self.parent = parent
self.form = ankiqt.forms.getshared.Ui_Dialog() aqt.form = ankiqt.forms.getshared.Ui_Dialog()
self.form.setupUi(self) self.form.setupUi(self)
self.ok = True self.ok = True
self.conErrMsg = _("""\ self.conErrMsg = _("""\

View file

@ -5,9 +5,9 @@ from PyQt4.QtGui import *
from PyQt4.QtCore import * from PyQt4.QtCore import *
import sys import sys
import anki, anki.graphs, anki.utils import anki, anki.graphs, anki.utils
from ankiqt import ui from aqt import ui
from ankiqt.ui.utils import saveGeom, restoreGeom from aqt.ui.utils import saveGeom, restoreGeom
import ankiqt import aqt
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib import rc from matplotlib import rc
@ -277,7 +277,7 @@ class GraphWindow(object):
m.exec_(self.showhide.mapToGlobal(QPoint(0,0))) m.exec_(self.showhide.mapToGlobal(QPoint(0,0)))
def onHelp(self): def onHelp(self):
QDesktopServices.openUrl(QUrl(ankiqt.appWiki + "Graphs")) QDesktopServices.openUrl(QUrl(aqt.appWiki + "Graphs"))
def onRefresh(self): def onRefresh(self):
self.deck.startProgress(len(self.widgets)) self.deck.startProgress(len(self.widgets))

View file

@ -4,7 +4,7 @@
import sys import sys
from PyQt4.QtGui import * from PyQt4.QtGui import *
from PyQt4.QtCore import * from PyQt4.QtCore import *
import ankiqt.forms import aqt.forms
from anki.hooks import runHook from anki.hooks import runHook
# Hideable help area widget # Hideable help area widget

View file

@ -6,17 +6,17 @@ from PyQt4.QtGui import *
from PyQt4.QtCore import * from PyQt4.QtCore import *
import anki import anki
import anki.importing as importing import anki.importing as importing
from ankiqt.ui.utils import getOnlyText from aqt.ui.utils import getOnlyText
from anki.errors import * from anki.errors import *
import ankiqt.forms import aqt.forms
from ankiqt import ui from aqt import ui
class ChangeMap(QDialog): class ChangeMap(QDialog):
def __init__(self, parent, model, current): def __init__(self, parent, model, current):
QDialog.__init__(self, parent, Qt.Window) QDialog.__init__(self, parent, Qt.Window)
self.parent = parent self.parent = parent
self.model = model self.model = model
self.dialog = ankiqt.forms.changemap.Ui_ChangeMap() self.dialog = aqt.forms.changemap.Ui_ChangeMap()
self.dialog.setupUi(self) self.dialog.setupUi(self)
n = 0 n = 0
setCurrent = False setCurrent = False
@ -55,7 +55,7 @@ class UpdateMap(QDialog):
QDialog.__init__(self, parent, Qt.Window) QDialog.__init__(self, parent, Qt.Window)
self.parent = parent self.parent = parent
self.fieldModels = fieldModels self.fieldModels = fieldModels
self.dialog = ankiqt.forms.importup.Ui_Dialog() self.dialog = aqt.forms.importup.Ui_Dialog()
self.dialog.setupUi(self) self.dialog.setupUi(self)
self.connect(self.dialog.buttonBox.button(QDialogButtonBox.Help), self.connect(self.dialog.buttonBox.button(QDialogButtonBox.Help),
SIGNAL("clicked()"), self.helpRequested) SIGNAL("clicked()"), self.helpRequested)
@ -66,7 +66,7 @@ class UpdateMap(QDialog):
self.exec_() self.exec_()
def helpRequested(self): def helpRequested(self):
QDesktopServices.openUrl(QUrl(ankiqt.appWiki + "FileImport")) QDesktopServices.openUrl(QUrl(aqt.appWiki + "FileImport"))
def accept(self): def accept(self):
self.updateKey = ( self.updateKey = (
@ -79,7 +79,7 @@ class ImportDialog(QDialog):
def __init__(self, parent): def __init__(self, parent):
QDialog.__init__(self, parent, Qt.Window) QDialog.__init__(self, parent, Qt.Window)
self.parent = parent self.parent = parent
self.dialog = ankiqt.forms.importing.Ui_ImportDialog() self.dialog = aqt.forms.importing.Ui_ImportDialog()
self.dialog.setupUi(self) self.dialog.setupUi(self)
self.connect(self.dialog.buttonBox.button(QDialogButtonBox.Help), self.connect(self.dialog.buttonBox.button(QDialogButtonBox.Help),
SIGNAL("clicked()"), self.helpRequested) SIGNAL("clicked()"), self.helpRequested)
@ -312,4 +312,4 @@ you can enter it here. Use \\t to represent tab."""),
QDialog.reject(self) QDialog.reject(self)
def helpRequested(self): def helpRequested(self):
QDesktopServices.openUrl(QUrl(ankiqt.appWiki + "FileImport")) QDesktopServices.openUrl(QUrl(aqt.appWiki + "FileImport"))

View file

@ -11,6 +11,7 @@ from PyQt4.QtGui import *
from PyQt4.QtWebKit import QWebPage from PyQt4.QtWebKit import QWebPage
from PyQt4 import pyqtconfig from PyQt4 import pyqtconfig
QtConfig = pyqtconfig.Configuration() QtConfig = pyqtconfig.Configuration()
from anki import Deck from anki import Deck
from anki.errors import * from anki.errors import *
from anki.sound import hasSound, playFromText, clearAudioQueue, stripSounds from anki.sound import hasSound, playFromText, clearAudioQueue, stripSounds
@ -20,16 +21,18 @@ from anki.stdmodels import BasicModel
from anki.hooks import runHook, addHook, removeHook, _hooks, wrap from anki.hooks import runHook, addHook, removeHook, _hooks, wrap
from anki.deck import newCardOrderLabels, newCardSchedulingLabels from anki.deck import newCardOrderLabels, newCardSchedulingLabels
from anki.deck import revCardOrderLabels, failedCardOptionLabels from anki.deck import revCardOrderLabels, failedCardOptionLabels
from ankiqt.ui.utils import saveGeom, restoreGeom, saveState, restoreState
import anki.lang import anki.lang
import anki.deck import anki.deck
import ankiqt
ui = ankiqt.ui import aqt, aqt.utils, aqt.view, aqt.help, aqt.status, aqt.facteditor
config = ankiqt.config from aqt.utils import saveGeom, restoreGeom, showInfo, showWarning, \
saveState, restoreState
config = aqt.config
class AnkiQt(QMainWindow): class AnkiQt(QMainWindow):
def __init__(self, app, config, args): def __init__(self, app, config, args, splash):
QMainWindow.__init__(self) QMainWindow.__init__(self)
self.splash = splash
try: try:
self.errorOccurred = False self.errorOccurred = False
self.inDbHandler = False self.inDbHandler = False
@ -39,7 +42,7 @@ class AnkiQt(QMainWindow):
elif sys.platform.startswith("win32"): elif sys.platform.startswith("win32"):
# make sure they're picked up on bundle # make sure they're picked up on bundle
from ctypes import windll, wintypes from ctypes import windll, wintypes
ankiqt.mw = self aqt.mw = self
self.app = app self.app = app
self.config = config self.config = config
self.deck = None self.deck = None
@ -59,7 +62,7 @@ class AnkiQt(QMainWindow):
self.setupTray() self.setupTray()
self.setupSync() self.setupSync()
self.connectMenuActions() self.connectMenuActions()
ui.splash.update() splash.update()
self.setupViews() self.setupViews()
self.setupEditor() self.setupEditor()
self.setupStudyScreen() self.setupStudyScreen()
@ -74,7 +77,7 @@ class AnkiQt(QMainWindow):
else: else:
self.resize(500, 500) self.resize(500, 500)
# load deck # load deck
ui.splash.update() splash.update()
self.setupErrorHandler() self.setupErrorHandler()
self.setupMisc() self.setupMisc()
# check if we've been updated # check if we've been updated
@ -82,19 +85,19 @@ class AnkiQt(QMainWindow):
# could be new user, or upgrade from older version # could be new user, or upgrade from older version
# which didn't have version variable # which didn't have version variable
self.appUpdated = "first" self.appUpdated = "first"
elif self.config['version'] != ankiqt.appVersion: elif self.config['version'] != aqt.appVersion:
self.appUpdated = self.config['version'] self.appUpdated = self.config['version']
else: else:
self.appUpdated = False self.appUpdated = False
if self.appUpdated: if self.appUpdated:
self.config['version'] = ankiqt.appVersion self.config['version'] = aqt.appVersion
# plugins might be looking at this # plugins might be looking at this
self.state = "noDeck" self.state = "noDeck"
self.loadPlugins() self.loadPlugins()
self.setupAutoUpdate() self.setupAutoUpdate()
self.rebuildPluginsMenu() self.rebuildPluginsMenu()
# plugins loaded, now show interface # plugins loaded, now show interface
ui.splash.finish(self) splash.finish(self)
self.show() self.show()
# program open sync # program open sync
if self.config['syncOnProgramOpen']: if self.config['syncOnProgramOpen']:
@ -114,15 +117,14 @@ class AnkiQt(QMainWindow):
try: try:
runHook('init') runHook('init')
except: except:
ui.utils.showWarning( aqt.utils.showWarning(
_("Broken plugin:\n\n%s") % _("Broken plugin:\n\n%s") %
unicode(traceback.format_exc(), "utf-8", "replace")) unicode(traceback.format_exc(), "utf-8", "replace"))
# activate & raise is useful when run from the command line on osx # activate & raise is useful when run from the command line on osx
self.activateWindow() self.activateWindow()
self.raise_() self.raise_()
except: except:
ui.utils.showInfo("Error during startup:\n%s" % showInfo("Error during startup:\n%s" % traceback.format_exc())
traceback.format_exc())
sys.exit(1) sys.exit(1)
def onSigInt(self, signum, frame): def onSigInt(self, signum, frame):
@ -133,13 +135,13 @@ class AnkiQt(QMainWindow):
def setupMainWindow(self): def setupMainWindow(self):
# main window # main window
self.mainWin = ankiqt.forms.main.Ui_MainWindow() self.mainWin = aqt.forms.main.Ui_MainWindow()
self.mainWin.setupUi(self) self.mainWin.setupUi(self)
self.mainWin.mainText = ui.view.AnkiWebView(self.mainWin.mainTextFrame) self.mainWin.mainText = aqt.view.AnkiWebView(self.mainWin.mainTextFrame)
self.mainWin.mainText.setObjectName("mainText") self.mainWin.mainText.setObjectName("mainText")
self.mainWin.mainText.setFocusPolicy(Qt.ClickFocus) self.mainWin.mainText.setFocusPolicy(Qt.ClickFocus)
self.mainWin.mainStack.addWidget(self.mainWin.mainText) self.mainWin.mainStack.addWidget(self.mainWin.mainText)
self.help = ui.help.HelpArea(self.mainWin.helpFrame, self.config, self) self.help = aqt.help.HelpArea(self.mainWin.helpFrame, self.config, self)
self.connect(self.mainWin.mainText.pageAction(QWebPage.Reload), self.connect(self.mainWin.mainText.pageAction(QWebPage.Reload),
SIGNAL("triggered()"), SIGNAL("triggered()"),
self.onReload) self.onReload)
@ -171,7 +173,7 @@ class AnkiQt(QMainWindow):
# decks may be opened in a sync thread # decks may be opened in a sync thread
sys.stderr.write(msg + "\n") sys.stderr.write(msg + "\n")
else: else:
ui.utils.showInfo(msg) showInfo(msg)
def setNotice(self, str=""): def setNotice(self, str=""):
if str: if str:
@ -181,14 +183,15 @@ class AnkiQt(QMainWindow):
self.mainWin.noticeFrame.setShown(False) self.mainWin.noticeFrame.setShown(False)
def setupViews(self): def setupViews(self):
self.bodyView = ui.view.View(self, self.mainWin.mainText, self.bodyView = aqt.view.View(self, self.mainWin.mainText,
self.mainWin.mainTextFrame) self.mainWin.mainTextFrame)
self.addView(self.bodyView) self.addView(self.bodyView)
self.statusView = ui.status.StatusView(self) self.statusView = aqt.status.StatusView(self)
self.addView(self.statusView) self.addView(self.statusView)
def setupTray(self): def setupTray(self):
self.trayIcon = ui.tray.AnkiTrayIcon(self) import aqt.tray
self.trayIcon = aqt.tray.AnkiTrayIcon(self)
def setupErrorHandler(self): def setupErrorHandler(self):
class ErrorPipe(object): class ErrorPipe(object):
@ -235,14 +238,13 @@ class AnkiQt(QMainWindow):
# hack for matplotlib errors on osx # hack for matplotlib errors on osx
return return
if "Audio player not found" in error: if "Audio player not found" in error:
ui.utils.showInfo( showInfo(_("Couldn't play sound. Please install mplayer."))
_("Couldn't play sound. Please install mplayer."))
return return
if "ERR-0100" in error: if "ERR-0100" in error:
ui.utils.showInfo(error) showInfo(error)
return return
if "ERR-0101" in error: if "ERR-0101" in error:
ui.utils.showInfo(error) showInfo(error)
return return
stdText = _("""\ stdText = _("""\
@ -280,7 +282,7 @@ Please do not file a bug report with Anki.<br>""")
self.clearProgress() self.clearProgress()
def closeAllDeckWindows(self): def closeAllDeckWindows(self):
ui.dialogs.closeAll() aqt.dialogs.closeAll()
self.help.hide() self.help.hide()
# State machine # State machine
@ -728,11 +730,11 @@ counts are %d %d %d
except Exception, e: except Exception, e:
if hasattr(e, 'data') and e.data.get('type') == 'inuse': if hasattr(e, 'data') and e.data.get('type') == 'inuse':
if interactive: if interactive:
ui.utils.showWarning(_("Deck is already open.")) aqt.utils.showWarning(_("Deck is already open."))
else: else:
return return
else: else:
ui.utils.showCritical(_("""\ aqt.utils.showCritical(_("""\
File is corrupt or not an Anki database. Click help for more info.\n File is corrupt or not an Anki database. Click help for more info.\n
Debug info:\n%s""") % traceback.format_exc(), help="DeckErrors") Debug info:\n%s""") % traceback.format_exc(), help="DeckErrors")
self.moveToState("noDeck") self.moveToState("noDeck")
@ -749,7 +751,7 @@ Debug info:\n%s""") % traceback.format_exc(), help="DeckErrors")
self.moveToState("initial") self.moveToState("initial")
except: except:
traceback.print_exc() traceback.print_exc()
if ui.utils.askUser(_( if aqt.utils.askUser(_(
"An error occurred while trying to build the queue.\n" "An error occurred while trying to build the queue.\n"
"Would you like to try check the deck for errors?\n" "Would you like to try check the deck for errors?\n"
"This may take some time.")): "This may take some time.")):
@ -758,7 +760,7 @@ Debug info:\n%s""") % traceback.format_exc(), help="DeckErrors")
try: try:
self.reset() self.reset()
except: except:
ui.utils.showWarning( aqt.utils.showWarning(
_("Unable to recover. Deck load failed.")) _("Unable to recover. Deck load failed."))
self.deck = None self.deck = None
else: else:
@ -867,11 +869,11 @@ Debug info:\n%s""") % traceback.format_exc(), help="DeckErrors")
not self.config['syncOnLoad'])): not self.config['syncOnLoad'])):
# backed in memory or autosave/sync off, must confirm # backed in memory or autosave/sync off, must confirm
while 1: while 1:
res = ui.unsaved.ask(parent) res = aqt.unsaved.ask(parent)
if res == ui.unsaved.save: if res == aqt.unsaved.save:
if self.save(required=True): if self.save(required=True):
break break
elif res == ui.unsaved.cancel: elif res == aqt.unsaved.cancel:
self.hideWelcome = False self.hideWelcome = False
return False return False
else: else:
@ -919,7 +921,7 @@ Debug info:\n%s""") % traceback.format_exc(), help="DeckErrors")
if not prompt: if not prompt:
prompt = _("Please give your deck a name:") prompt = _("Please give your deck a name:")
while 1: while 1:
name = ui.utils.getOnlyText( name = aqt.utils.getOnlyText(
prompt, default=name, title=_("New Deck")) prompt, default=name, title=_("New Deck"))
if not name: if not name:
self.moveToState("noDeck") self.moveToState("noDeck")
@ -927,7 +929,7 @@ Debug info:\n%s""") % traceback.format_exc(), help="DeckErrors")
found = False found = False
for c in bad: for c in bad:
if c in name: if c in name:
ui.utils.showInfo( showInfo(
_("Sorry, '%s' can't be used in deck names.") % c) _("Sorry, '%s' can't be used in deck names.") % c)
found = True found = True
break break
@ -938,7 +940,7 @@ Debug info:\n%s""") % traceback.format_exc(), help="DeckErrors")
break break
path = os.path.join(self.documentDir, name) path = os.path.join(self.documentDir, name)
if os.path.exists(path): if os.path.exists(path):
if ui.utils.askUser(_("That deck already exists. Overwrite?"), if aqt.utils.askUser(_("That deck already exists. Overwrite?"),
defaultno=True): defaultno=True):
os.unlink(path) os.unlink(path)
else: else:
@ -1007,12 +1009,12 @@ Debug info:\n%s""") % traceback.format_exc(), help="DeckErrors")
def onGetSharedDeck(self): def onGetSharedDeck(self):
if not self.inMainWindow(): return if not self.inMainWindow(): return
ui.getshared.GetShared(self, 0) aqt.getshared.GetShared(self, 0)
self.browserLastRefreshed = 0 self.browserLastRefreshed = 0
def onGetSharedPlugin(self): def onGetSharedPlugin(self):
if not self.inMainWindow(): return if not self.inMainWindow(): return
ui.getshared.GetShared(self, 1) aqt.getshared.GetShared(self, 1)
def onOpen(self): def onOpen(self):
if not self.inMainWindow(): return if not self.inMainWindow(): return
@ -1026,7 +1028,7 @@ Debug info:\n%s""") % traceback.format_exc(), help="DeckErrors")
ret = self.loadDeck(file, interactive=True) ret = self.loadDeck(file, interactive=True)
if not ret: if not ret:
if ret is None: if ret is None:
ui.utils.showWarning(_("Unable to load file.")) aqt.utils.showWarning(_("Unable to load file."))
self.deck = None self.deck = None
return False return False
else: else:
@ -1124,7 +1126,7 @@ your deck."""))
return self.onSave() return self.onSave()
if os.path.exists(file): if os.path.exists(file):
# check for existence after extension # check for existence after extension
if not ui.utils.askUser( if not aqt.utils.askUser(
"This file exists. Are you sure you want to overwrite it?"): "This file exists. Are you sure you want to overwrite it?"):
return return
self.closeAllDeckWindows() self.closeAllDeckWindows()
@ -1173,7 +1175,7 @@ your deck."""))
self.startProgress(max=len(self.config['recentDeckPaths']), self.startProgress(max=len(self.config['recentDeckPaths']),
immediate=True) immediate=True)
for c, d in enumerate(self.config['recentDeckPaths']): for c, d in enumerate(self.config['recentDeckPaths']):
if ui.splash.finished: if self.splash.finished:
self.updateProgress(_("Checking deck %(x)d of %(y)d...") % { self.updateProgress(_("Checking deck %(x)d of %(y)d...") % {
'x': c+1, 'y': len(self.config['recentDeckPaths'])}) 'x': c+1, 'y': len(self.config['recentDeckPaths'])})
if not os.path.exists(d): if not os.path.exists(d):
@ -1206,7 +1208,7 @@ your deck."""))
for d in toRemove: for d in toRemove:
self.config['recentDeckPaths'].remove(d) self.config['recentDeckPaths'].remove(d)
self.config.save() self.config.save()
if ui.splash.finished: if self.splash.finished:
self.finishProgress() self.finishProgress()
self.browserLastRefreshed = time.time() self.browserLastRefreshed = time.time()
self.reorderBrowserDecks() self.reorderBrowserDecks()
@ -1398,7 +1400,7 @@ later by using File>Close.
self.switchToDecksScreen() self.switchToDecksScreen()
def onDeckBrowserForget(self, c): def onDeckBrowserForget(self, c):
if ui.utils.askUser(_("""\ if aqt.utils.askUser(_("""\
Hide %s from the list? You can File>Open it again later.""") % Hide %s from the list? You can File>Open it again later.""") %
self.browserDecks[c]['name']): self.browserDecks[c]['name']):
self.config['recentDeckPaths'].remove(self.browserDecks[c]['path']) self.config['recentDeckPaths'].remove(self.browserDecks[c]['path'])
@ -1407,7 +1409,7 @@ Hide %s from the list? You can File>Open it again later.""") %
def onDeckBrowserDelete(self, c): def onDeckBrowserDelete(self, c):
deck = self.browserDecks[c]['path'] deck = self.browserDecks[c]['path']
if ui.utils.askUser(_("""\ if aqt.utils.askUser(_("""\
Delete %s? If this deck is synchronized the online version will \ Delete %s? If this deck is synchronized the online version will \
not be touched.""") % not be touched.""") %
self.browserDecks[c]['name']): self.browserDecks[c]['name']):
@ -1442,7 +1444,7 @@ not be touched.""") %
try: try:
self.config.save() self.config.save()
except (IOError, OSError), e: except (IOError, OSError), e:
ui.utils.showWarning(_("Anki was unable to save your " aqt.utils.showWarning(_("Anki was unable to save your "
"configuration file:\n%s" % e)) "configuration file:\n%s" % e))
def closeEvent(self, event): def closeEvent(self, event):
@ -1503,7 +1505,7 @@ not be touched.""") %
########################################################################## ##########################################################################
def setupEditor(self): def setupEditor(self):
self.editor = ui.facteditor.FactEditor( self.editor = aqt.facteditor.FactEditor(
self, self.mainWin.fieldsArea, self.deck) self, self.mainWin.fieldsArea, self.deck)
self.editor.clayout.setShortcut("") self.editor.clayout.setShortcut("")
self.editor.onFactValid = self.onFactValid self.editor.onFactValid = self.onFactValid
@ -1540,7 +1542,7 @@ not be touched.""") %
self.connect(self.mainWin.optionsHelpButton, self.connect(self.mainWin.optionsHelpButton,
SIGNAL("clicked()"), SIGNAL("clicked()"),
lambda: QDesktopServices.openUrl(QUrl( lambda: QDesktopServices.openUrl(QUrl(
ankiqt.appWiki + "StudyOptions"))) aqt.appWiki + "StudyOptions")))
self.connect(self.mainWin.minuteLimit, self.connect(self.mainWin.minuteLimit,
SIGNAL("textChanged(QString)"), self.onMinuteLimitChanged) SIGNAL("textChanged(QString)"), self.onMinuteLimitChanged)
self.connect(self.mainWin.questionLimit, self.connect(self.mainWin.questionLimit,
@ -1562,10 +1564,10 @@ not be touched.""") %
self.mainWin.tabWidget.setCurrentIndex(self.config['studyOptionsScreen']) self.mainWin.tabWidget.setCurrentIndex(self.config['studyOptionsScreen'])
def onNewCategoriesClicked(self): def onNewCategoriesClicked(self):
ui.activetags.show(self, "new") aqt.activetags.show(self, "new")
def onRevCategoriesClicked(self): def onRevCategoriesClicked(self):
ui.activetags.show(self, "rev") aqt.activetags.show(self, "rev")
def onFailedMaxChanged(self): def onFailedMaxChanged(self):
try: try:
@ -1868,20 +1870,20 @@ learnt today")
import anki.graphs import anki.graphs
if anki.graphs.graphsAvailable(): if anki.graphs.graphsAvailable():
try: try:
ui.dialogs.get("Graphs", self, self.deck) aqt.dialogs.get("Graphs", self, self.deck)
except (ImportError, ValueError): except (ImportError, ValueError):
traceback.print_exc() traceback.print_exc()
if sys.platform.startswith("win32"): if sys.platform.startswith("win32"):
ui.utils.showInfo( showInfo(
_("To display graphs, Anki needs a .dll file which\n" _("To display graphs, Anki needs a .dll file which\n"
"you don't have. Please install:\n") + "you don't have. Please install:\n") +
"http://www.dll-files.com/dllindex/dll-files.shtml?msvcp71") "http://www.dll-files.com/dllindex/dll-files.shtml?msvcp71")
else: else:
ui.utils.showInfo(_( showInfo(_(
"Your version of Matplotlib is broken.\n" "Your version of Matplotlib is broken.\n"
"Please see http://ichi2.net/anki/wiki/MatplotlibBroken")) "Please see http://ichi2.net/anki/wiki/MatplotlibBroken"))
else: else:
ui.utils.showInfo(_("Please install python-matplotlib to access graphs.")) showInfo(_("Please install python-matplotlib to access graphs."))
# Marking, suspending and undoing # Marking, suspending and undoing
########################################################################## ##########################################################################
@ -1936,38 +1938,38 @@ learnt today")
########################################################################## ##########################################################################
def onAddCard(self): def onAddCard(self):
ui.dialogs.get("AddCards", self) aqt.dialogs.get("AddCards", self)
def onEditDeck(self): def onEditDeck(self):
ui.dialogs.get("CardList", self) aqt.dialogs.get("CardList", self)
def onEditCurrent(self): def onEditCurrent(self):
self.moveToState("editCurrentFact") self.moveToState("editCurrentFact")
def onCardLayout(self): def onCardLayout(self):
ui.clayout.CardLayout(self, 0, self.currentCard.fact, aqt.clayout.CardLayout(self, 0, self.currentCard.fact,
card=self.currentCard) card=self.currentCard)
def onDeckProperties(self): def onDeckProperties(self):
self.deckProperties = ui.deckproperties.DeckProperties(self, self.deck) self.deckProperties = aqt.deckproperties.DeckProperties(self, self.deck)
def onPrefs(self): def onPrefs(self):
ui.preferences.Preferences(self, self.config) aqt.preferences.Preferences(self, self.config)
def onReportBug(self): def onReportBug(self):
QDesktopServices.openUrl(QUrl(ankiqt.appIssueTracker)) QDesktopServices.openUrl(QUrl(aqt.appIssueTracker))
def onForum(self): def onForum(self):
QDesktopServices.openUrl(QUrl(ankiqt.appForum)) QDesktopServices.openUrl(QUrl(aqt.appForum))
def onReleaseNotes(self): def onReleaseNotes(self):
QDesktopServices.openUrl(QUrl(ankiqt.appReleaseNotes)) QDesktopServices.openUrl(QUrl(aqt.appReleaseNotes))
def onAbout(self): def onAbout(self):
ui.about.show(self) aqt.about.show(self)
def onDonate(self): def onDonate(self):
QDesktopServices.openUrl(QUrl(ankiqt.appDonate)) QDesktopServices.openUrl(QUrl(aqt.appDonate))
# Importing & exporting # Importing & exporting
########################################################################## ##########################################################################
@ -1982,10 +1984,10 @@ Please give your deck a name:"""))
if not self.deck: if not self.deck:
return return
if self.deck.path: if self.deck.path:
ui.importing.ImportDialog(self) aqt.importing.ImportDialog(self)
def onExport(self): def onExport(self):
ui.exporting.ExportDialog(self) aqt.exporting.ExportDialog(self)
# Cramming & Sharing # Cramming & Sharing
########################################################################## ##########################################################################
@ -2005,9 +2007,9 @@ Please give your deck a name:"""))
return (e, path) return (e, path)
def onCram(self, cardIds=[]): def onCram(self, cardIds=[]):
te = ui.tagedit.TagEdit(self) te = aqt.tagedit.TagEdit(self)
te.setDeck(self.deck, "all") te.setDeck(self.deck, "all")
diag = ui.utils.GetTextDialog( diag = aqt.utils.GetTextDialog(
self, _("Tags to cram:"), help="CramMode", edit=te) self, _("Tags to cram:"), help="CramMode", edit=te)
l = diag.layout() l = diag.layout()
g = QGroupBox(_("Review Mode")) g = QGroupBox(_("Review Mode"))
@ -2045,14 +2047,14 @@ Please give your deck a name:"""))
self.deck.getCard() # so scheduler will reset if empty self.deck.getCard() # so scheduler will reset if empty
self.moveToState("initial") self.moveToState("initial")
if not self.deck.finishScheduler: if not self.deck.finishScheduler:
ui.utils.showInfo(_("No cards matched the provided tags.")) showInfo(_("No cards matched the provided tags."))
def onShare(self, tags): def onShare(self, tags):
pwd = os.getcwd() pwd = os.getcwd()
# open tmp deck # open tmp deck
(e, path) = self._copyToTmpDeck(name="shared.anki", tags=tags) (e, path) = self._copyToTmpDeck(name="shared.anki", tags=tags)
if not e.exportedCards: if not e.exportedCards:
ui.utils.showInfo(_("No cards matched the provided tags.")) showInfo(_("No cards matched the provided tags."))
return return
self.deck.startProgress() self.deck.startProgress()
self.deck.updateProgress() self.deck.updateProgress()
@ -2145,8 +2147,8 @@ it to your friends.
locale.setlocale(locale.LC_ALL, '') locale.setlocale(locale.LC_ALL, '')
except: except:
pass pass
languageDir=os.path.join(ankiqt.modDir, "locale") languageDir=os.path.join(aqt.modDir, "locale")
self.languageTrans = gettext.translation('ankiqt', languageDir, self.languageTrans = gettext.translation('aqt', languageDir,
languages=[self.config["interfaceLang"]], languages=[self.config["interfaceLang"]],
fallback=True) fallback=True)
self.installTranslation() self.installTranslation()
@ -2197,7 +2199,7 @@ it to your friends.
if interactive: if interactive:
if (not self.config['mediaLocation'] if (not self.config['mediaLocation']
and self.deck.db.scalar("select 1 from media limit 1")): and self.deck.db.scalar("select 1 from media limit 1")):
ui.utils.showInfo(_("""\ showInfo(_("""\
Syncing sounds and images requires a free file synchronization service like \ Syncing sounds and images requires a free file synchronization service like \
DropBox. Click help to learn more, and OK to continue syncing."""), DropBox. Click help to learn more, and OK to continue syncing."""),
help="SyncingMedia") help="SyncingMedia")
@ -2212,7 +2214,7 @@ DropBox. Click help to learn more, and OK to continue syncing."""),
self.syncDecks = self.decksToSync() self.syncDecks = self.decksToSync()
if not self.syncDecks: if not self.syncDecks:
if interactive: if interactive:
ui.utils.showInfo(_("""\ showInfo(_("""\
Please open a deck and run File>Sync. After you do this once, the deck \ Please open a deck and run File>Sync. After you do this once, the deck \
will sync automatically from then on.""")) will sync automatically from then on."""))
return return
@ -2235,7 +2237,7 @@ will sync automatically from then on."""))
self.state = "nostate" self.state = "nostate"
import gc; gc.collect() import gc; gc.collect()
self.mainWin.welcomeText.setText(u"") self.mainWin.welcomeText.setText(u"")
self.syncThread = ui.sync.Sync(self, u, p, interactive, onlyMerge) self.syncThread = aqt.sync.Sync(self, u, p, interactive, onlyMerge)
self.connect(self.syncThread, SIGNAL("setStatus"), self.setSyncStatus) self.connect(self.syncThread, SIGNAL("setStatus"), self.setSyncStatus)
self.connect(self.syncThread, SIGNAL("showWarning"), self.showSyncWarning) self.connect(self.syncThread, SIGNAL("showWarning"), self.showSyncWarning)
self.connect(self.syncThread, SIGNAL("moveToState"), self.moveToState) self.connect(self.syncThread, SIGNAL("moveToState"), self.moveToState)
@ -2271,7 +2273,7 @@ will sync automatically from then on."""))
return ok return ok
def onConflict(self, deckName): def onConflict(self, deckName):
diag = ui.utils.askUserDialog(_("""\ diag = aqt.utils.askUserDialog(_("""\
<b>%s</b> has been changed on both <b>%s</b> has been changed on both
the local and remote side. What do the local and remote side. What do
you want to do?""" % deckName), you want to do?""" % deckName),
@ -2288,7 +2290,7 @@ you want to do?""" % deckName),
self.syncThread.conflictResolution = "cancel" self.syncThread.conflictResolution = "cancel"
def onClobber(self, deckName): def onClobber(self, deckName):
diag = ui.utils.askUserDialog(_("""\ diag = aqt.utils.askUserDialog(_("""\
You are about to upload <b>%s</b> You are about to upload <b>%s</b>
to AnkiOnline. This will overwrite to AnkiOnline. This will overwrite
the online copy of this deck. the online copy of this deck.
@ -2351,13 +2353,13 @@ Are you sure?""" % deckName),
self.syncFinished = True self.syncFinished = True
def selectSyncDeck(self, decks): def selectSyncDeck(self, decks):
name = ui.sync.DeckChooser(self, decks).getName() name = aqt.sync.DeckChooser(self, decks).getName()
self.syncName = name self.syncName = name
if name: if name:
# name chosen # name chosen
p = os.path.join(self.documentDir, name + ".anki") p = os.path.join(self.documentDir, name + ".anki")
if os.path.exists(p): if os.path.exists(p):
d = ui.utils.askUserDialog(_("""\ d = aqt.utils.askUserDialog(_("""\
This deck already exists on your computer. Overwrite the local copy?"""), This deck already exists on your computer. Overwrite the local copy?"""),
["Overwrite", "Cancel"]) ["Overwrite", "Cancel"])
d.setDefault(1) d.setDefault(1)
@ -2383,7 +2385,7 @@ This deck already exists on your computer. Overwrite the local copy?"""),
self.mainWin.welcomeText.append("<font size=+2>" + text + "</font>") self.mainWin.welcomeText.append("<font size=+2>" + text + "</font>")
def syncClockOff(self, diff): def syncClockOff(self, diff):
ui.utils.showWarning( aqt.utils.showWarning(
_("The time or date on your computer is not correct.\n") + _("The time or date on your computer is not correct.\n") +
ngettext("It is off by %d second.\n\n", ngettext("It is off by %d second.\n\n",
"It is off by %d seconds.\n\n", diff) % diff + "It is off by %d seconds.\n\n", diff) % diff +
@ -2393,11 +2395,11 @@ This deck already exists on your computer. Overwrite the local copy?"""),
self.onSyncFinished() self.onSyncFinished()
def showSyncWarning(self, text): def showSyncWarning(self, text):
ui.utils.showWarning(text, self) aqt.utils.showWarning(text, self)
self.setStatus("") self.setStatus("")
def badUserPass(self): def badUserPass(self):
ui.preferences.Preferences(self, self.config).dialog.tabWidget.\ aqt.preferences.Preferences(self, self.config).dialog.tabWidget.\
setCurrentIndex(1) setCurrentIndex(1)
def openSyncProgress(self): def openSyncProgress(self):
@ -2422,7 +2424,7 @@ This deck already exists on your computer. Overwrite the local copy?"""),
self.syncProgressDialog.setLabelText("Downloading %s..." % fname) self.syncProgressDialog.setLabelText("Downloading %s..." % fname)
def bulkSyncFailed(self): def bulkSyncFailed(self):
ui.utils.showWarning(_( aqt.utils.showWarning(_(
"Failed to upload media. Please run 'check media db'."), self) "Failed to upload media. Please run 'check media db'."), self)
def fullSyncStarted(self, max): def fullSyncStarted(self, max):
@ -2531,7 +2533,7 @@ This deck already exists on your computer. Overwrite the local copy?"""),
def updateTitleBar(self): def updateTitleBar(self):
"Display the current deck and card count in the titlebar." "Display the current deck and card count in the titlebar."
title=ankiqt.appName title=aqt.appName
if self.deck != None: if self.deck != None:
deckpath = self.deck.name() deckpath = self.deck.name()
if self.deck.modifiedSinceSave(): if self.deck.modifiedSinceSave():
@ -2552,7 +2554,7 @@ This deck already exists on your computer. Overwrite the local copy?"""),
self.mainWin.statusbar.showMessage(text, timeout) self.mainWin.statusbar.showMessage(text, timeout)
def onStartHere(self): def onStartHere(self):
QDesktopServices.openUrl(QUrl(ankiqt.appHelpSite)) QDesktopServices.openUrl(QUrl(aqt.appHelpSite))
def updateMarkAction(self): def updateMarkAction(self):
self.mainWin.actionMarkCard.blockSignals(True) self.mainWin.actionMarkCard.blockSignals(True)
@ -2608,7 +2610,8 @@ This deck already exists on your computer. Overwrite the local copy?"""),
########################################################################## ##########################################################################
def setupAutoUpdate(self): def setupAutoUpdate(self):
self.autoUpdate = ui.update.LatestVersionFinder(self) import aqt.update
self.autoUpdate = aqt.update.LatestVersionFinder(self)
self.connect(self.autoUpdate, SIGNAL("newVerAvail"), self.newVerAvail) self.connect(self.autoUpdate, SIGNAL("newVerAvail"), self.newVerAvail)
self.connect(self.autoUpdate, SIGNAL("newMsg"), self.newMsg) self.connect(self.autoUpdate, SIGNAL("newMsg"), self.newMsg)
self.connect(self.autoUpdate, SIGNAL("clockIsOff"), self.clockIsOff) self.connect(self.autoUpdate, SIGNAL("clockIsOff"), self.clockIsOff)
@ -2616,17 +2619,17 @@ This deck already exists on your computer. Overwrite the local copy?"""),
def newVerAvail(self, data): def newVerAvail(self, data):
if self.config['suppressUpdate'] < data['latestVersion']: if self.config['suppressUpdate'] < data['latestVersion']:
ui.update.askAndUpdate(self, data) aqt.update.askAndUpdate(self, data)
def newMsg(self, data): def newMsg(self, data):
ui.update.showMessages(self, data) aqt.update.showMessages(self, data)
def clockIsOff(self, diff): def clockIsOff(self, diff):
if diff < 0: if diff < 0:
ret = _("late") ret = _("late")
else: else:
ret = _("early") ret = _("early")
ui.utils.showWarning( aqt.utils.showWarning(
_("The time or date on your computer is not correct.\n") + _("The time or date on your computer is not correct.\n") +
ngettext("It is %(sec)d second %(type)s.\n", ngettext("It is %(sec)d second %(type)s.\n",
"It is %(sec)d seconds %(type)s.\n", abs(diff)) "It is %(sec)d seconds %(type)s.\n", abs(diff))
@ -2714,7 +2717,7 @@ to work with this version of Anki."""))
if os.path.exists(new): if os.path.exists(new):
os.unlink(new) os.unlink(new)
os.rename(path, new) os.rename(path, new)
ui.utils.showInfo(p[1]) showInfo(p[1])
def rebuildPluginsMenu(self): def rebuildPluginsMenu(self):
if getattr(self, "pluginActions", None) is None: if getattr(self, "pluginActions", None) is None:
@ -2819,7 +2822,7 @@ to work with this version of Anki."""))
########################################################################## ##########################################################################
def setupStyle(self): def setupStyle(self):
ui.utils.applyStyles(self) aqt.utils.applyStyles(self)
# Sounds # Sounds
########################################################################## ##########################################################################
@ -2842,7 +2845,7 @@ to work with this version of Anki."""))
playFromText(self.currentCard.answer) playFromText(self.currentCard.answer)
def onRecordNoiseProfile(self): def onRecordNoiseProfile(self):
from ankiqt.ui.sound import recordNoiseProfile from aqt.sound import recordNoiseProfile
recordNoiseProfile(self) recordNoiseProfile(self)
# Progress info # Progress info
@ -2869,7 +2872,7 @@ to work with this version of Anki."""))
self.setBusy() self.setBusy()
if not self.progressWins: if not self.progressWins:
parent = self.progressParent or self.app.activeWindow() or self parent = self.progressParent or self.app.activeWindow() or self
p = ui.utils.ProgressWin(parent, max, min, title, immediate) p = aqt.utils.ProgressWin(parent, max, min, title, immediate)
else: else:
p = None p = None
self.progressWins.append(p) self.progressWins.append(p)
@ -2995,7 +2998,7 @@ to work with this version of Anki."""))
def dropboxFolder(self): def dropboxFolder(self):
try: try:
import ankiqt.ui.dropbox as db import aqt.dropbox as db
p = db.getPath() p = db.getPath()
except: except:
if sys.platform.startswith("win32"): if sys.platform.startswith("win32"):
@ -3013,14 +3016,14 @@ to work with this version of Anki."""))
open(os.path.join( open(os.path.join(
deck.mediaPrefix, "right-click-me.txt"), "w").write("") deck.mediaPrefix, "right-click-me.txt"), "w").write("")
# tell user what to do # tell user what to do
ui.utils.showInfo(_("""\ showInfo(_("""\
A file called right-click-me.txt has been placed in DropBox's public folder. \ A file called right-click-me.txt has been placed in DropBox's public folder. \
After clicking OK, this folder will appear. Please right click on the file (\ After clicking OK, this folder will appear. Please right click on the file (\
command+click on a Mac), choose DropBox>Copy Public Link, and paste the \ command+click on a Mac), choose DropBox>Copy Public Link, and paste the \
link into Anki.""")) link into Anki."""))
# open folder and text prompt # open folder and text prompt
self.onOpenPluginFolder(deck.mediaPrefix) self.onOpenPluginFolder(deck.mediaPrefix)
txt = ui.utils.getText(_("Paste path here:"), parent=self) txt = aqt.utils.getText(_("Paste path here:"), parent=self)
if txt[0]: if txt[0]:
fail = False fail = False
if not txt[0].lower().startswith("http"): if not txt[0].lower().startswith("http"):
@ -3028,7 +3031,7 @@ link into Anki."""))
if not txt[0].lower().endswith("right-click-me.txt"): if not txt[0].lower().endswith("right-click-me.txt"):
fail = True fail = True
if fail: if fail:
ui.utils.showInfo(_("""\ showInfo(_("""\
That doesn't appear to be a public link. You'll be asked again when the deck \ That doesn't appear to be a public link. You'll be asked again when the deck \
is next loaded.""")) is next loaded."""))
else: else:
@ -3045,10 +3048,10 @@ is next loaded."""))
def onCheckDB(self): def onCheckDB(self):
"True if no problems" "True if no problems"
if self.errorOccurred: if self.errorOccurred:
ui.utils.showWarning(_( aqt.utils.showWarning(_(
"Please restart Anki before checking the DB.")) "Please restart Anki before checking the DB."))
return return
if not ui.utils.askUser(_("""\ if not aqt.utils.askUser(_("""\
This operation will find and fix some common problems.<br> This operation will find and fix some common problems.<br>
<br> <br>
On the next sync, all cards will be sent to the server.<br> On the next sync, all cards will be sent to the server.<br>
@ -3119,12 +3122,12 @@ doubt."""))
report += "\n" + "\n".join(unused) report += "\n" + "\n".join(unused)
if not report: if not report:
report = _("No unused or missing files found.") report = _("No unused or missing files found.")
ui.utils.showText(report, parent=self, type="text") aqt.utils.showText(report, parent=self, type="text")
def onDownloadMissingMedia(self): def onDownloadMissingMedia(self):
res = downloadMissing(self.deck) res = downloadMissing(self.deck)
if res is None: if res is None:
ui.utils.showInfo(_("No media URL defined for this deck."), showInfo(_("No media URL defined for this deck."),
help="MediaSupport") help="MediaSupport")
return return
if res[0] == True: if res[0] == True:
@ -3135,10 +3138,10 @@ doubt."""))
msg += "\n" + ngettext("%d missing.", "%d missing.", missing) % missing msg += "\n" + ngettext("%d missing.", "%d missing.", missing) % missing
else: else:
msg = _("Unable to download %s\nDownload aborted.") % res[1] msg = _("Unable to download %s\nDownload aborted.") % res[1]
ui.utils.showInfo(msg) showInfo(msg)
def onLocalizeMedia(self): def onLocalizeMedia(self):
if not ui.utils.askUser(_("""\ if not aqt.utils.askUser(_("""\
This will look for remote images and sounds on your cards, download them to \ This will look for remote images and sounds on your cards, download them to \
your media folder, and convert the links to local ones. \ your media folder, and convert the links to local ones. \
It can take a long time. Proceed?""")): It can take a long time. Proceed?""")):
@ -3149,7 +3152,7 @@ It can take a long time. Proceed?""")):
"%d successfully downloaded.", count) % count "%d successfully downloaded.", count) % count
if len(res[1]): if len(res[1]):
msg += "\n\n" + _("Couldn't find:") + "\n" + "\n".join(res[1]) msg += "\n\n" + _("Couldn't find:") + "\n" + "\n".join(res[1])
ui.utils.showText(msg, parent=self, type="text") aqt.utils.showText(msg, parent=self, type="text")
def addHook(self, *args): def addHook(self, *args):
addHook(*args) addHook(*args)

View file

@ -7,8 +7,8 @@ from operator import attrgetter
import anki, sys import anki, sys
from anki import stdmodels from anki import stdmodels
from anki.models import * from anki.models import *
from ankiqt import ui from aqt import ui
import ankiqt.forms import aqt.forms
from anki.hooks import addHook, removeHook from anki.hooks import addHook, removeHook
class ModelChooser(QHBoxLayout): class ModelChooser(QHBoxLayout):
@ -74,7 +74,7 @@ class ModelChooser(QHBoxLayout):
def onModelEdited(self): def onModelEdited(self):
# hack # hack
from ankiqt import mw from aqt import mw
self.deck = mw.deck self.deck = mw.deck
self.drawModels() self.drawModels()
self.changed(self.deck.currentModel) self.changed(self.deck.currentModel)
@ -169,7 +169,7 @@ class AddModel(QDialog):
self.main = main self.main = main
self.model = None self.model = None
self.deck = deck self.deck = deck
self.dialog = ankiqt.forms.addmodel.Ui_AddModel() self.dialog = aqt.forms.addmodel.Ui_AddModel()
self.dialog.setupUi(self) self.dialog.setupUi(self)
self.models = [] self.models = []
names = stdmodels.models.keys() names = stdmodels.models.keys()
@ -205,5 +205,5 @@ class AddModel(QDialog):
QDialog.accept(self) QDialog.accept(self)
def onHelp(self): def onHelp(self):
QDesktopServices.openUrl(QUrl(ankiqt.appWiki + QDesktopServices.openUrl(QUrl(aqt.appWiki +
"AddModel")) "AddModel"))

View file

@ -4,9 +4,9 @@
from PyQt4.QtGui import * from PyQt4.QtGui import *
from PyQt4.QtCore import * from PyQt4.QtCore import *
import sys, re import sys, re
import ankiqt.forms import aqt.forms
import anki import anki
from ankiqt import ui from aqt import ui
class ModelProperties(QDialog): class ModelProperties(QDialog):
@ -20,7 +20,7 @@ class ModelProperties(QDialog):
self.m = model self.m = model
self.needRebuild = False self.needRebuild = False
self.onFinish = onFinish self.onFinish = onFinish
self.dialog = ankiqt.forms.modelproperties.Ui_ModelProperties() self.dialog = aqt.forms.modelproperties.Ui_ModelProperties()
self.dialog.setupUi(self) self.dialog.setupUi(self)
self.connect(self.dialog.buttonBox, SIGNAL("helpRequested()"), self.connect(self.dialog.buttonBox, SIGNAL("helpRequested()"),
self.helpRequested) self.helpRequested)
@ -252,7 +252,7 @@ class ModelProperties(QDialog):
self.ignoreCardUpdate = False self.ignoreCardUpdate = False
def helpRequested(self): def helpRequested(self):
QDesktopServices.openUrl(QUrl(ankiqt.appWiki + QDesktopServices.openUrl(QUrl(aqt.appWiki +
"ModelProperties")) "ModelProperties"))
# Cleanup # Cleanup
@ -282,7 +282,7 @@ class ModelProperties(QDialog):
self.deck.updateCardsFromModel(self.m) self.deck.updateCardsFromModel(self.m)
reset = True reset = True
if reset: if reset:
ankiqt.mw.reset() aqt.mw.reset()
if self.onFinish: if self.onFinish:
self.onFinish() self.onFinish()
self.deck.setUndoEnd(self.undoName) self.deck.setUndoEnd(self.undoName)

View file

@ -7,8 +7,8 @@ from PyQt4.QtGui import *
from PyQt4.QtCore import * from PyQt4.QtCore import *
import anki, anki.utils import anki, anki.utils
from anki.facts import Fact from anki.facts import Fact
from ankiqt import ui from aqt import ui
import ankiqt.forms import aqt.forms
tabs = ("Display", tabs = ("Display",
"Network", "Network",
@ -23,7 +23,7 @@ class Preferences(QDialog):
self.parent = parent self.parent = parent
self.config = copy.copy(self.origConfig) self.config = copy.copy(self.origConfig)
self.origInterfaceLang = self.config['interfaceLang'] self.origInterfaceLang = self.config['interfaceLang']
self.dialog = ankiqt.forms.preferences.Ui_Preferences() self.dialog = aqt.forms.preferences.Ui_Preferences()
self.dialog.setupUi(self) self.dialog.setupUi(self)
self.needDeckClose = False self.needDeckClose = False
self.supportedLanguages = [ self.supportedLanguages = [
@ -258,6 +258,6 @@ class Preferences(QDialog):
def helpRequested(self): def helpRequested(self):
idx = self.dialog.tabWidget.currentIndex() idx = self.dialog.tabWidget.currentIndex()
QDesktopServices.openUrl(QUrl(ankiqt.appWiki + QDesktopServices.openUrl(QUrl(aqt.appWiki +
"Preferences#" + "Preferences#" +
tabs[idx])) tabs[idx]))

View file

@ -6,7 +6,7 @@ from PyQt4.QtCore import *
import time import time
from anki.sound import Recorder, play, generateNoiseProfile from anki.sound import Recorder, play, generateNoiseProfile
from ankiqt.ui.utils import saveGeom, restoreGeom from aqt.utils import saveGeom, restoreGeom
def getAudio(parent, string="", encode=True): def getAudio(parent, string="", encode=True):
"Record and return filename" "Record and return filename"

View file

@ -5,7 +5,6 @@ from PyQt4.QtGui import *
from PyQt4.QtCore import * from PyQt4.QtCore import *
import anki import anki
import sys, time import sys, time
from ankiqt import ui
from anki.hooks import addHook from anki.hooks import addHook
class QClickableLabel(QLabel): class QClickableLabel(QLabel):

View file

@ -4,14 +4,14 @@
from PyQt4.QtGui import * from PyQt4.QtGui import *
from PyQt4.QtCore import * from PyQt4.QtCore import *
import os, types, socket, time, traceback import os, types, socket, time, traceback
import ankiqt import aqt
import anki import anki
from anki.sync import SyncClient, HttpSyncServerProxy, copyLocalMedia from anki.sync import SyncClient, HttpSyncServerProxy, copyLocalMedia
from anki.sync import SYNC_HOST, SYNC_PORT from anki.sync import SYNC_HOST, SYNC_PORT
from anki.errors import * from anki.errors import *
from anki import Deck from anki import Deck
from anki.db import sqlite from anki.db import sqlite
import ankiqt.forms import aqt.forms
from anki.hooks import addHook, removeHook from anki.hooks import addHook, removeHook
# Synchronising a deck with a public server # Synchronising a deck with a public server
@ -100,7 +100,7 @@ sync was aborted. Please report this error.""")
if not self.proxy: if not self.proxy:
self.setStatus(_("Connecting..."), 0) self.setStatus(_("Connecting..."), 0)
proxy = HttpSyncServerProxy(self.user, self.pwd) proxy = HttpSyncServerProxy(self.user, self.pwd)
proxy.connect("ankiqt-" + ankiqt.appVersion) proxy.connect("aqt-" + ankiqt.appVersion)
self.proxy = proxy self.proxy = proxy
# check clock # check clock
if proxy.timediff > 300: if proxy.timediff > 300:
@ -297,7 +297,7 @@ class DeckChooser(QDialog):
QDialog.__init__(self, parent, Qt.Window) QDialog.__init__(self, parent, Qt.Window)
self.parent = parent self.parent = parent
self.decks = decks self.decks = decks
self.dialog = ankiqt.forms.syncdeck.Ui_DeckChooser() self.dialog = aqt.forms.syncdeck.Ui_DeckChooser()
self.dialog.setupUi(self) self.dialog.setupUi(self)
self.dialog.topLabel.setText(_("<h1>Download Personal Deck</h1>")) self.dialog.topLabel.setText(_("<h1>Download Personal Deck</h1>"))
self.decks.sort() self.decks.sort()

View file

@ -2,7 +2,7 @@
# License: GNU GPL, version 3 or later; http://www.gnu.org/copyleft/gpl.html # License: GNU GPL, version 3 or later; http://www.gnu.org/copyleft/gpl.html
from PyQt4.QtGui import * from PyQt4.QtGui import *
import ankiqt.forms import aqt.forms
save = QMessageBox.Save save = QMessageBox.Save
discard = QMessageBox.Discard discard = QMessageBox.Discard

View file

@ -5,7 +5,7 @@ from PyQt4.QtCore import *
from PyQt4.QtGui import * from PyQt4.QtGui import *
import urllib, urllib2, os, sys, time, httplib import urllib, urllib2, os, sys, time, httplib
import anki, anki.utils, anki.lang, anki.stats import anki, anki.utils, anki.lang, anki.stats
import ankiqt import aqt
import simplejson, platform import simplejson, platform
baseUrl = "http://anki.ichi2.net/update/" baseUrl = "http://anki.ichi2.net/update/"
@ -19,7 +19,7 @@ class LatestVersionFinder(QThread):
self.config = main.config self.config = main.config
plat=sys.platform plat=sys.platform
pver=platform.platform() pver=platform.platform()
d = {"ver": ankiqt.appVersion, d = {"ver": aqt.appVersion,
"pver": pver, "pver": pver,
"plat": plat, "plat": plat,
"id": self.config['id'], "id": self.config['id'],
@ -44,7 +44,7 @@ class LatestVersionFinder(QThread):
return return
if resp['msg']: if resp['msg']:
self.emit(SIGNAL("newMsg"), resp) self.emit(SIGNAL("newMsg"), resp)
if resp['latestVersion'] > ankiqt.appVersion: if resp['latestVersion'] > aqt.appVersion:
self.emit(SIGNAL("newVerAvail"), resp) self.emit(SIGNAL("newVerAvail"), resp)
diff = resp['currentTime'] - time.time() diff = resp['currentTime'] - time.time()
# a fairly liberal time check - sync is more strict # a fairly liberal time check - sync is more strict
@ -67,8 +67,8 @@ def askAndUpdate(parent, version=None):
# ignore this update # ignore this update
parent.config['suppressUpdate'] = version parent.config['suppressUpdate'] = version
elif ret == QMessageBox.Yes: elif ret == QMessageBox.Yes:
QDesktopServices.openUrl(QUrl(ankiqt.appWebsite)) QDesktopServices.openUrl(QUrl(aqt.appWebsite))
def showMessages(main, data): def showMessages(main, data):
ankiqt.ui.utils.showText(data['msg'], main, type="html") aqt.ui.utils.showText(data['msg'], main, type="html")
main.config['lastMsg'] = data['msgId'] main.config['lastMsg'] = data['msgId']

View file

@ -5,16 +5,15 @@ from PyQt4.QtGui import *
from PyQt4.QtCore import * from PyQt4.QtCore import *
from anki.sound import playFromText, stripSounds from anki.sound import playFromText, stripSounds
from ankiqt import ui
import re, os, sys, urllib, time import re, os, sys, urllib, time
import ankiqt import aqt
def openLink(link): def openLink(link):
QDesktopServices.openUrl(QUrl(link)) QDesktopServices.openUrl(QUrl(link))
def openWikiLink(page): def openWikiLink(page):
openLink(ankiqt.appWiki + page) openLink(aqt.appWiki + page)
def showWarning(text, parent=None, help=""): def showWarning(text, parent=None, help=""):
"Show a small warning with an OK button." "Show a small warning with an OK button."
@ -27,7 +26,7 @@ def showCritical(text, parent=None, help=""):
def showInfo(text, parent=None, help="", func=None): def showInfo(text, parent=None, help="", func=None):
"Show a small info window with an OK button." "Show a small info window with an OK button."
if not parent: if not parent:
parent = ankiqt.mw parent = aqt.mw
if not func: if not func:
func = QMessageBox.information func = QMessageBox.information
sb = QMessageBox.Ok sb = QMessageBox.Ok
@ -42,7 +41,7 @@ def showInfo(text, parent=None, help="", func=None):
def showText(txt, parent=None, type="text"): def showText(txt, parent=None, type="text"):
if not parent: if not parent:
parent = ankiqt.mw parent = aqt.mw
diag = QDialog(parent) diag = QDialog(parent)
diag.setWindowTitle("Anki") diag.setWindowTitle("Anki")
layout = QVBoxLayout(diag) layout = QVBoxLayout(diag)
@ -64,7 +63,7 @@ def showText(txt, parent=None, type="text"):
def askUser(text, parent=None, help="", defaultno=False): def askUser(text, parent=None, help="", defaultno=False):
"Show a yes/no question. Return true if yes." "Show a yes/no question. Return true if yes."
if not parent: if not parent:
parent = ankiqt.mw parent = aqt.mw
sb = QMessageBox.Yes | QMessageBox.No sb = QMessageBox.Yes | QMessageBox.No
if help: if help:
sb |= QMessageBox.Help sb |= QMessageBox.Help
@ -115,7 +114,7 @@ class ButtonedDialog(QMessageBox):
def askUserDialog(text, buttons, parent=None, help=""): def askUserDialog(text, buttons, parent=None, help=""):
if not parent: if not parent:
parent = ankiqt.mw parent = aqt.mw
diag = ButtonedDialog(text, buttons, parent, help) diag = ButtonedDialog(text, buttons, parent, help)
return diag return diag
@ -158,11 +157,11 @@ class GetTextDialog(QDialog):
return QDialog.reject(self) return QDialog.reject(self)
def helpRequested(self): def helpRequested(self):
QDesktopServices.openUrl(QUrl(ankiqt.appWiki + self.help)) QDesktopServices.openUrl(QUrl(aqt.appWiki + self.help))
def getText(prompt, parent=None, help=None, edit=None, default=u"", title="Anki"): def getText(prompt, parent=None, help=None, edit=None, default=u"", title="Anki"):
if not parent: if not parent:
parent = ankiqt.mw parent = aqt.mw
d = GetTextDialog(parent, prompt, help=help, edit=edit, d = GetTextDialog(parent, prompt, help=help, edit=edit,
default=default, title=title) default=default, title=title)
ret = d.exec_() ret = d.exec_()
@ -176,7 +175,8 @@ def getOnlyText(*args, **kwargs):
return u"" return u""
def getTag(parent, deck, question, tags="user", **kwargs): def getTag(parent, deck, question, tags="user", **kwargs):
te = ui.tagedit.TagEdit(parent) from aqt.tagedit import TagEdit
te = TagEdit(parent)
te.setDeck(deck, tags) te.setDeck(deck, tags)
return getText(question, parent, edit=te, **kwargs) return getText(question, parent, edit=te, **kwargs)
@ -184,17 +184,17 @@ def getFile(parent, title, dir, key):
"Ask the user for a file. Use DIR as config variable." "Ask the user for a file. Use DIR as config variable."
dirkey = dir+"Directory" dirkey = dir+"Directory"
file = unicode(QFileDialog.getOpenFileName( file = unicode(QFileDialog.getOpenFileName(
parent, title, ankiqt.mw.config.get(dirkey, ""), key)) parent, title, aqt.mw.config.get(dirkey, ""), key))
if file: if file:
dir = os.path.dirname(file) dir = os.path.dirname(file)
ankiqt.mw.config[dirkey] = dir aqt.mw.config[dirkey] = dir
return file return file
def getSaveFile(parent, title, dir, key, ext): def getSaveFile(parent, title, dir, key, ext):
"Ask the user for a file to save. Use DIR as config variable." "Ask the user for a file to save. Use DIR as config variable."
dirkey = dir+"Directory" dirkey = dir+"Directory"
file = unicode(QFileDialog.getSaveFileName( file = unicode(QFileDialog.getSaveFileName(
parent, title, ankiqt.mw.config.get(dirkey, ""), key, parent, title, aqt.mw.config.get(dirkey, ""), key,
None, QFileDialog.DontConfirmOverwrite)) None, QFileDialog.DontConfirmOverwrite))
if file: if file:
# add extension # add extension
@ -202,7 +202,7 @@ def getSaveFile(parent, title, dir, key, ext):
file += ext file += ext
# save new default # save new default
dir = os.path.dirname(file) dir = os.path.dirname(file)
ankiqt.mw.config[dirkey] = dir aqt.mw.config[dirkey] = dir
# check if it exists # check if it exists
if os.path.exists(file): if os.path.exists(file):
if not askUser( if not askUser(
@ -213,14 +213,14 @@ def getSaveFile(parent, title, dir, key, ext):
def saveGeom(widget, key): def saveGeom(widget, key):
key += "Geom" key += "Geom"
ankiqt.mw.config[key] = widget.saveGeometry() aqt.mw.config[key] = widget.saveGeometry()
def restoreGeom(widget, key, offset=None): def restoreGeom(widget, key, offset=None):
key += "Geom" key += "Geom"
if ankiqt.mw.config.get(key): if aqt.mw.config.get(key):
widget.restoreGeometry(ankiqt.mw.config[key]) widget.restoreGeometry(aqt.mw.config[key])
if sys.platform.startswith("darwin") and offset: if sys.platform.startswith("darwin") and offset:
from ankiqt.ui.main import QtConfig as q from aqt.main import QtConfig as q
minor = (q.qt_version & 0x00ff00) >> 8 minor = (q.qt_version & 0x00ff00) >> 8
if minor > 6: if minor > 6:
# bug in osx toolkit # bug in osx toolkit
@ -229,30 +229,30 @@ def restoreGeom(widget, key, offset=None):
def saveState(widget, key): def saveState(widget, key):
key += "State" key += "State"
ankiqt.mw.config[key] = widget.saveState() aqt.mw.config[key] = widget.saveState()
def restoreState(widget, key): def restoreState(widget, key):
key += "State" key += "State"
if ankiqt.mw.config.get(key): if aqt.mw.config.get(key):
widget.restoreState(ankiqt.mw.config[key]) widget.restoreState(aqt.mw.config[key])
def saveSplitter(widget, key): def saveSplitter(widget, key):
key += "Splitter" key += "Splitter"
ankiqt.mw.config[key] = widget.saveState() aqt.mw.config[key] = widget.saveState()
def restoreSplitter(widget, key): def restoreSplitter(widget, key):
key += "Splitter" key += "Splitter"
if ankiqt.mw.config.get(key): if aqt.mw.config.get(key):
widget.restoreState(ankiqt.mw.config[key]) widget.restoreState(aqt.mw.config[key])
def saveHeader(widget, key): def saveHeader(widget, key):
key += "Header" key += "Header"
ankiqt.mw.config[key] = widget.saveState() aqt.mw.config[key] = widget.saveState()
def restoreHeader(widget, key): def restoreHeader(widget, key):
key += "Header" key += "Header"
if ankiqt.mw.config.get(key): if aqt.mw.config.get(key):
widget.restoreState(ankiqt.mw.config[key]) widget.restoreState(aqt.mw.config[key])
def mungeQA(deck, txt): def mungeQA(deck, txt):
txt = stripSounds(txt) txt = stripSounds(txt)
@ -262,7 +262,7 @@ def mungeQA(deck, txt):
def applyStyles(widget): def applyStyles(widget):
try: try:
styleFile = open(os.path.join(ankiqt.mw.config.configPath, styleFile = open(os.path.join(aqt.mw.config.configPath,
"style.css")) "style.css"))
widget.setStyleSheet(styleFile.read()) widget.setStyleSheet(styleFile.read())
except (IOError, OSError): except (IOError, OSError):

View file

@ -10,8 +10,7 @@ from anki.utils import stripHTML
from anki.hooks import runHook, runFilter from anki.hooks import runHook, runFilter
import types, time, re, os, urllib, sys, difflib import types, time, re, os, urllib, sys, difflib
import unicodedata as ucd import unicodedata as ucd
from ankiqt import ui from aqt.utils import mungeQA, getBase
from ankiqt.ui.utils import mungeQA, getBase
from anki.utils import fmtTimeSpan from anki.utils import fmtTimeSpan
from PyQt4.QtWebKit import QWebPage, QWebView from PyQt4.QtWebKit import QWebPage, QWebView

1
designer/icons/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/.directory

View file

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 2 KiB

View file

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

View file

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

View file

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View file

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View file

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

Before

Width:  |  Height:  |  Size: 1,006 B

After

Width:  |  Height:  |  Size: 1,006 B

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

Before

Width:  |  Height:  |  Size: 927 B

After

Width:  |  Height:  |  Size: 927 B

View file

Before

Width:  |  Height:  |  Size: 7 KiB

After

Width:  |  Height:  |  Size: 7 KiB

View file

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View file

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 2 KiB

View file

Before

Width:  |  Height:  |  Size: 496 B

After

Width:  |  Height:  |  Size: 496 B

View file

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 2 KiB

View file

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

Before

Width:  |  Height:  |  Size: 205 B

After

Width:  |  Height:  |  Size: 205 B

View file

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

View file

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View file

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Some files were not shown because too many files have changed in this diff Show more