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
*\#
*~
/icons_rc.py
ankiqt/forms
/docs/manual.html
/docs/docbook-xsl.css
/docs/manual.xml
/aqt/forms

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:
- a recent Python (2.4 should be fine)
- python-qt/pyqt 4.4+
- sqlalchemy 0.4.3+
- simplejson 1.7.3+
- pysqlite2 1.3+ or python2.5
- Python 2.4+
- Python-Qt/PyQt 4.4+
- SimpleJSON 1.7.3+
- PySQLite 1.3+ or Python2.5
- Beautiful Soup
For graph generation:
@ -24,35 +24,11 @@ For audio recording support:
- pyaudio
- lame
For importing SuperMemo XML and exporting text files:
- python-beautifulsoup
Running / Installation
-------------------------------------
To run from the directory you've untarred it to,
$ ./anki
If you want to install it system wide,
$ (cd libanki && sudo python setup.py install)
$ sudo python setup.py install
$ anki
<todo>
For more information and the latest version, please see the website at:
http://ichi2.net/anki/
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
http://ankisrs.net/

View file

@ -8,8 +8,10 @@ $ git clone https://github.com/dae/ankiqt.git
$ cd ankiqt
$ ./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
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 ..
$ 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
#
# hack because py2app barfs on a try block
#
import pkg_resources
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()
import aqt
aqt.run()

View file

@ -14,6 +14,7 @@ appIssueTracker="http://code.google.com/p/anki/issues/list"
appForum="http://groups.google.com/group/ankisrs/topics"
appReleaseNotes="http://ankisrs.net/changes.html"
appDonate="http://ankisrs.net/support/"
mw = None # will be set in init
modDir=os.path.dirname(os.path.abspath(__file__))
runningDir=os.path.split(modDir)[0]
@ -22,8 +23,52 @@ if hasattr(sys, "frozen"):
sys.path.append(modDir)
modDir = os.path.dirname(sys.argv[0])
# we bundle icons_rc as part of the anki source
sys.path.append(os.path.dirname(__file__))
# Dialog manager
##########################################################################
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
##########################################################################
@ -137,9 +182,8 @@ def run():
sys.exit(1)
import forms
import ui
ui.splash = SplashScreen(3)
splash = SplashScreen(3)
import anki
if anki.version != appVersion:
@ -157,8 +201,8 @@ def run():
(opts, args) = parser.parse_args(sys.argv[1:])
# configuration
import ankiqt.config
conf = ankiqt.config.Config(
import aqt.config
conf = aqt.config.Config(
unicode(os.path.abspath(opts.config), sys.getfilesystemencoding()))
# qt translations
@ -180,11 +224,12 @@ def run():
app.setStyle("plastique")
# load main window
ui.importAll()
ui.dialogs.registerDialogs()
ui.splash.update()
import aqt.main
#ui.importAll()
#ui.dialogs.registerDialogs()
splash.update()
mw = ui.main.AnkiQt(app, conf, args)
mw = aqt.main.AnkiQt(app, conf, args, splash)
app.exec_()

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -4,9 +4,9 @@
from PyQt4.QtGui 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
from ankiqt.ui.utils import saveGeom, restoreGeom, showInfo
from aqt.ui.utils import saveGeom, restoreGeom, showInfo
from anki.utils import fmtTimeSpan
URL = "http://ankiweb.net/file/"
@ -29,7 +29,7 @@ class GetShared(QDialog):
def __init__(self, parent, type):
QDialog.__init__(self, parent, Qt.Window)
self.parent = parent
self.form = ankiqt.forms.getshared.Ui_Dialog()
aqt.form = ankiqt.forms.getshared.Ui_Dialog()
self.form.setupUi(self)
self.ok = True
self.conErrMsg = _("""\

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -6,7 +6,7 @@ from PyQt4.QtCore import *
import time
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):
"Record and return filename"

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -10,8 +10,7 @@ from anki.utils import stripHTML
from anki.hooks import runHook, runFilter
import types, time, re, os, urllib, sys, difflib
import unicodedata as ucd
from ankiqt import ui
from ankiqt.ui.utils import mungeQA, getBase
from aqt.utils import mungeQA, getBase
from anki.utils import fmtTimeSpan
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