mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 16:56:36 -04:00
Merge branch 'master' of git://ichi2.net/ankiqt
Conflicts: ankiqt/locale/ankiqt_sv_SE.po
This commit is contained in:
commit
5266233c01
48 changed files with 14973 additions and 6446 deletions
2
README
2
README
|
@ -20,7 +20,7 @@ For audio playing support:
|
||||||
|
|
||||||
For audio recording support:
|
For audio recording support:
|
||||||
|
|
||||||
- sox
|
- sox 14.1+
|
||||||
- pyaudio
|
- pyaudio
|
||||||
- lame
|
- lame
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ from PyQt4.QtCore import *
|
||||||
from PyQt4.QtGui import *
|
from PyQt4.QtGui import *
|
||||||
|
|
||||||
appName="Anki"
|
appName="Anki"
|
||||||
appVersion="0.9.9.6"
|
appVersion="0.9.9.7"
|
||||||
appWebsite="http://ichi2.net/anki/download/"
|
appWebsite="http://ichi2.net/anki/download/"
|
||||||
appWiki="http://ichi2.net/anki/wiki/"
|
appWiki="http://ichi2.net/anki/wiki/"
|
||||||
appHelpSite="http://ichi2.net/anki/wiki/AnkiWiki"
|
appHelpSite="http://ichi2.net/anki/wiki/AnkiWiki"
|
||||||
|
@ -36,8 +36,23 @@ class SplashScreen(object):
|
||||||
self.splash = QSplashScreen(self.pixmap)
|
self.splash = QSplashScreen(self.pixmap)
|
||||||
self.prog = QProgressBar(self.splash)
|
self.prog = QProgressBar(self.splash)
|
||||||
self.prog.setMaximum(max)
|
self.prog.setMaximum(max)
|
||||||
self.prog.setGeometry(self.splash.width()/10, 8*self.splash.height()/10,
|
if QApplication.instance().style().objectName() != "plastique":
|
||||||
8*self.splash.width()/10, self.splash.height()/10)
|
self.style = QStyleFactory.create("plastique")
|
||||||
|
self.prog.setStyle(self.style)
|
||||||
|
self.prog.setStyleSheet("""* {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #061824;
|
||||||
|
margin:0px;
|
||||||
|
border:0px;
|
||||||
|
padding: 0px;
|
||||||
|
text-align: center;}
|
||||||
|
*::chunk {
|
||||||
|
color: #13486c;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
x = 8
|
||||||
|
self.prog.setGeometry(self.splash.width()/10, 8.85*self.splash.height()/10,
|
||||||
|
x*self.splash.width()/10, self.splash.height()/10)
|
||||||
self.splash.show()
|
self.splash.show()
|
||||||
self.val = 1
|
self.val = 1
|
||||||
|
|
||||||
|
@ -93,7 +108,7 @@ def run():
|
||||||
if anki.version != appVersion:
|
if anki.version != appVersion:
|
||||||
print "You have libanki %s, but this is ankiqt %s" % (
|
print "You have libanki %s, but this is ankiqt %s" % (
|
||||||
anki.version, appVersion)
|
anki.version, appVersion)
|
||||||
print "\nPlease install the latest libanki."
|
print "\nPlease ensure versions match."
|
||||||
return
|
return
|
||||||
|
|
||||||
# parse args
|
# parse args
|
||||||
|
|
|
@ -57,6 +57,7 @@ class Config(dict):
|
||||||
'saveAfterAddingNum': 1,
|
'saveAfterAddingNum': 1,
|
||||||
'saveOnClose': True,
|
'saveOnClose': True,
|
||||||
'mainWindowGeom': None,
|
'mainWindowGeom': None,
|
||||||
|
'mainWindowState': None,
|
||||||
'suppressUpdate': False,
|
'suppressUpdate': False,
|
||||||
'suppressEstimates': False,
|
'suppressEstimates': False,
|
||||||
'showLastCardInterval': False,
|
'showLastCardInterval': False,
|
||||||
|
@ -84,6 +85,7 @@ class Config(dict):
|
||||||
'editLineSize': 20,
|
'editLineSize': 20,
|
||||||
'factEditorAdvanced': False,
|
'factEditorAdvanced': False,
|
||||||
'typeAnswerFontSize': 20,
|
'typeAnswerFontSize': 20,
|
||||||
|
'showProgress': True,
|
||||||
'recentColours': ["#000000", "#0000ff"],
|
'recentColours': ["#000000", "#0000ff"],
|
||||||
}
|
}
|
||||||
for (k,v) in fields.items():
|
for (k,v) in fields.items():
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
2893
ankiqt/locale/ankiqt_ee_EE.po
Normal file
2893
ankiqt/locale/ankiqt_ee_EE.po
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
2845
ankiqt/locale/ankiqt_zh_CN.po
Normal file
2845
ankiqt/locale/ankiqt_zh_CN.po
Normal file
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
|
@ -13,7 +13,6 @@ def importAll():
|
||||||
import exporting
|
import exporting
|
||||||
import facteditor
|
import facteditor
|
||||||
import help
|
import help
|
||||||
import importing
|
|
||||||
import lookup
|
import lookup
|
||||||
import modelchooser
|
import modelchooser
|
||||||
import modelproperties
|
import modelproperties
|
||||||
|
@ -26,6 +25,7 @@ def importAll():
|
||||||
import update
|
import update
|
||||||
import utils
|
import utils
|
||||||
import view
|
import view
|
||||||
|
import getshared
|
||||||
|
|
||||||
class DialogManager(object):
|
class DialogManager(object):
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# Copyright: Damien Elmes <anki@ichi2.net>
|
# Copyright: Damien Elmes <anki@ichi2.net>
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
# 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 *
|
||||||
|
@ -10,12 +11,31 @@ def show(parent):
|
||||||
abt = ankiqt.forms.about.Ui_About()
|
abt = ankiqt.forms.about.Ui_About()
|
||||||
abt.setupUi(dialog)
|
abt.setupUi(dialog)
|
||||||
abt.label.setText(_("""
|
abt.label.setText(_("""
|
||||||
<h1>Anki</h1>
|
<center><img src=":/icons/anki-logo-thin.png"></center>
|
||||||
<img src=":/icons/anki.png">
|
|
||||||
<p>
|
<p>
|
||||||
<span>Anki is a spaced repetition flashcard program designed to maximise your
|
Anki is a friendly, intelligent spaced learning system. It's free and open
|
||||||
memory potential.<p/>It's free and licensed under the GPL.<p/>
|
source.<p>
|
||||||
Version %s<br>
|
Version %(ver)s<br>
|
||||||
<a href="http://ichi2.net/anki/">Visit website</a></span>
|
<a href="http://ichi2.net/anki/">Visit website</a></span>
|
||||||
""") % appVersion)
|
<p>
|
||||||
|
Written by Damien Elmes, with patches, translation, testing and design from:<p>%(cont)s
|
||||||
|
<p>
|
||||||
|
If you have contributed and are not on this list, please get in touch.
|
||||||
|
<p>
|
||||||
|
A big thanks to all the people who have provided suggestions, bug reports and
|
||||||
|
donations.""") % {
|
||||||
|
'cont': u"""
|
||||||
|
|
||||||
|
Alex Fraser, Andreas Klauer, Bananeweizen, Bernhard Ibertsberger, Christian
|
||||||
|
Rusche, David Smith, Dave Druelinger, Emmanuel Jarri, Frank Harper, Ian Lewis,
|
||||||
|
Iroiro, Jin Eun-Deok, Jo Nakashima, Krause Chr, LaC, Laurent Steffan, Marco
|
||||||
|
Giancotti, Mark Wilbur, Meelis Vasser, Michael Penkov, Michal Čadil, Nathanael
|
||||||
|
Law, Nick Cook, Niklas Laxström, Pcsl88, Piotr Kubowicz, Richard Colley,
|
||||||
|
Samson Melamed, Susanna Björverud, Timm Preetz, Timo Paulssen, Victor Suba,
|
||||||
|
and Xtru.
|
||||||
|
|
||||||
|
""",
|
||||||
|
'ver': appVersion})
|
||||||
|
dialog.show()
|
||||||
|
dialog.adjustSize()
|
||||||
dialog.exec_()
|
dialog.exec_()
|
||||||
|
|
|
@ -24,11 +24,19 @@ class ActiveTagsChooser(QDialog):
|
||||||
self.items = []
|
self.items = []
|
||||||
self.suspended = {}
|
self.suspended = {}
|
||||||
for t in parseTags(self.parent.deck.suspended):
|
for t in parseTags(self.parent.deck.suspended):
|
||||||
|
if t == "Suspended":
|
||||||
|
continue
|
||||||
self.suspended[t] = 1
|
self.suspended[t] = 1
|
||||||
if t not in self.tags:
|
if t not in self.tags:
|
||||||
self.tags.append(t)
|
self.tags.append(t)
|
||||||
self.tags.sort()
|
self.tags.sort()
|
||||||
|
try:
|
||||||
|
self.tags.remove("Suspended")
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
for t in self.tags:
|
for t in self.tags:
|
||||||
|
if t == "Suspended":
|
||||||
|
continue
|
||||||
item = QListWidgetItem(t, self.dialog.list)
|
item = QListWidgetItem(t, self.dialog.list)
|
||||||
self.dialog.list.addItem(item)
|
self.dialog.list.addItem(item)
|
||||||
self.items.append(item)
|
self.items.append(item)
|
||||||
|
|
|
@ -56,7 +56,6 @@ class AddCards(QDialog):
|
||||||
self.addButton.setToolTip(_("Add (shortcut: command+return)"))
|
self.addButton.setToolTip(_("Add (shortcut: command+return)"))
|
||||||
else:
|
else:
|
||||||
self.addButton.setToolTip(_("Add (shortcut: ctrl+return)"))
|
self.addButton.setToolTip(_("Add (shortcut: ctrl+return)"))
|
||||||
self.addButton.setAutoDefault(False)
|
|
||||||
s = QShortcut(QKeySequence(_("Ctrl+Enter")), self)
|
s = QShortcut(QKeySequence(_("Ctrl+Enter")), self)
|
||||||
s.connect(s, SIGNAL("activated()"), self.addButton, SLOT("click()"))
|
s.connect(s, SIGNAL("activated()"), self.addButton, SLOT("click()"))
|
||||||
self.connect(self.addButton, SIGNAL("clicked()"), self.addCards)
|
self.connect(self.addButton, SIGNAL("clicked()"), self.addCards)
|
||||||
|
@ -95,6 +94,7 @@ class AddCards(QDialog):
|
||||||
fact.tags = self.parent.deck.lastTags
|
fact.tags = self.parent.deck.lastTags
|
||||||
# set the new fact
|
# set the new fact
|
||||||
self.editor.setFact(fact, check=True)
|
self.editor.setFact(fact, check=True)
|
||||||
|
self.setTabOrder(self.editor.tags, self.addButton)
|
||||||
|
|
||||||
def addCards(self):
|
def addCards(self):
|
||||||
# make sure updated
|
# make sure updated
|
||||||
|
@ -131,6 +131,14 @@ question or answer on all cards."""), parent=self)
|
||||||
self.editor.tags.addTags(parseTags(self.parent.deck.lastTags))
|
self.editor.tags.addTags(parseTags(self.parent.deck.lastTags))
|
||||||
self.maybeSave()
|
self.maybeSave()
|
||||||
|
|
||||||
|
def keyPressEvent(self, evt):
|
||||||
|
"Show answer on RET or register answer."
|
||||||
|
if (evt.key() in (Qt.Key_Enter, Qt.Key_Return)
|
||||||
|
and self.editor.tags.hasFocus()):
|
||||||
|
evt.accept()
|
||||||
|
return
|
||||||
|
return QDialog.keyPressEvent(self, evt)
|
||||||
|
|
||||||
def closeEvent(self, evt):
|
def closeEvent(self, evt):
|
||||||
if self.onClose():
|
if self.onClose():
|
||||||
evt.accept()
|
evt.accept()
|
||||||
|
|
|
@ -106,11 +106,12 @@ class DeckModel(QAbstractTableModel):
|
||||||
d = {'str': [],
|
d = {'str': [],
|
||||||
'tag': [],
|
'tag': [],
|
||||||
}
|
}
|
||||||
for elem in search.split():
|
if search:
|
||||||
if len(elem) > 2 and elem.startswith("t:"):
|
for elem in search.split():
|
||||||
d['tag'].append(elem[2:])
|
if len(elem) > 2 and elem.startswith("t:"):
|
||||||
else:
|
d['tag'].append(elem[2:])
|
||||||
d['str'].append(elem)
|
else:
|
||||||
|
d['str'].append(elem)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
def showMatching(self):
|
def showMatching(self):
|
||||||
|
@ -189,8 +190,8 @@ class DeckModel(QAbstractTableModel):
|
||||||
self.cards[index.row()] = self.deck.s.first("""
|
self.cards[index.row()] = self.deck.s.first("""
|
||||||
select id, question, answer, due, reps, factId, created, modified,
|
select id, question, answer, due, reps, factId, created, modified,
|
||||||
interval, factor from cards where id = :id""", id=self.cards[index.row()][0])
|
interval, factor from cards where id = :id""", id=self.cards[index.row()][0])
|
||||||
self.emit(SIGNAL("dataChanged(QModelIndex,QModelIndex)"),
|
#self.emit(SIGNAL("dataChanged(QModelIndex,QModelIndex)"),
|
||||||
index, self.index(index.row(), 1))
|
# index, self.index(index.row(), 1))
|
||||||
except IndexError:
|
except IndexError:
|
||||||
# called after search changed
|
# called after search changed
|
||||||
pass
|
pass
|
||||||
|
@ -259,12 +260,12 @@ class DeckModel(QAbstractTableModel):
|
||||||
self.columns[-1][0] = k
|
self.columns[-1][0] = k
|
||||||
|
|
||||||
def createdColumn(self, index):
|
def createdColumn(self, index):
|
||||||
return fmtTimeSpan(
|
return time.strftime("%Y-%m-%d", time.localtime(
|
||||||
time.time() - self.cards[index.row()][CARD_CREATED]) + " ago"
|
self.cards[index.row()][CARD_CREATED]))
|
||||||
|
|
||||||
def modifiedColumn(self, index):
|
def modifiedColumn(self, index):
|
||||||
return fmtTimeSpan(
|
return time.strftime("%Y-%m-%d", time.localtime(
|
||||||
time.time() - self.cards[index.row()][CARD_MODIFIED]) + " ago"
|
self.cards[index.row()][CARD_MODIFIED]))
|
||||||
|
|
||||||
def intervalColumn(self, index):
|
def intervalColumn(self, index):
|
||||||
return fmtTimeSpan(
|
return fmtTimeSpan(
|
||||||
|
@ -279,7 +280,7 @@ class DeckModel(QAbstractTableModel):
|
||||||
class EditDeck(QMainWindow):
|
class EditDeck(QMainWindow):
|
||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
QDialog.__init__(self, parent, Qt.Window)
|
QMainWindow.__init__(self, parent)
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.deck = self.parent.deck
|
self.deck = self.parent.deck
|
||||||
self.config = parent.config
|
self.config = parent.config
|
||||||
|
@ -354,8 +355,8 @@ class EditDeck(QMainWindow):
|
||||||
self.dialog.tagList.setFixedWidth(130)
|
self.dialog.tagList.setFixedWidth(130)
|
||||||
self.dialog.tagList.clear()
|
self.dialog.tagList.clear()
|
||||||
self.dialog.tagList.addItems(QStringList(
|
self.dialog.tagList.addItems(QStringList(
|
||||||
[_('All cards'), _('No tags')] + self.alltags))
|
[_('<Tag filter>'), _('No tags')] + self.alltags))
|
||||||
self.dialog.tagList.view().setFixedWidth(300)
|
self.dialog.tagList.view().setFixedWidth(200)
|
||||||
|
|
||||||
def drawSort(self):
|
def drawSort(self):
|
||||||
self.sortList = [
|
self.sortList = [
|
||||||
|
@ -515,12 +516,12 @@ class EditDeck(QMainWindow):
|
||||||
if not sys.platform.startswith("win32"):
|
if not sys.platform.startswith("win32"):
|
||||||
self.dialog.tableView.verticalHeader().hide()
|
self.dialog.tableView.verticalHeader().hide()
|
||||||
self.dialog.tableView.horizontalHeader().show()
|
self.dialog.tableView.horizontalHeader().show()
|
||||||
for i in range(2):
|
|
||||||
self.dialog.tableView.horizontalHeader().setResizeMode(i, QHeaderView.Stretch)
|
|
||||||
self.dialog.tableView.horizontalHeader().setResizeMode(2, QHeaderView.Interactive)
|
|
||||||
restoreHeader(self.dialog.tableView.horizontalHeader(), "editor")
|
restoreHeader(self.dialog.tableView.horizontalHeader(), "editor")
|
||||||
self.dialog.tableView.verticalHeader().setDefaultSectionSize(
|
self.dialog.tableView.verticalHeader().setDefaultSectionSize(
|
||||||
self.parent.config['editLineSize'])
|
self.parent.config['editLineSize'])
|
||||||
|
for i in range(2):
|
||||||
|
self.dialog.tableView.horizontalHeader().setResizeMode(i, QHeaderView.Stretch)
|
||||||
|
self.dialog.tableView.horizontalHeader().setResizeMode(2, QHeaderView.Interactive)
|
||||||
|
|
||||||
def setupMenus(self):
|
def setupMenus(self):
|
||||||
# actions
|
# actions
|
||||||
|
@ -723,18 +724,28 @@ where id in %s""" % ids2str(sf))
|
||||||
_("Can only operate on one model at a time."),
|
_("Can only operate on one model at a time."),
|
||||||
parent=self)
|
parent=self)
|
||||||
return
|
return
|
||||||
|
# get cards to enable
|
||||||
cms = [x.id for x in self.deck.s.query(Fact).get(sf[0]).\
|
cms = [x.id for x in self.deck.s.query(Fact).get(sf[0]).\
|
||||||
model.cardModels]
|
model.cardModels]
|
||||||
d = AddCardChooser(self, cms)
|
d = AddCardChooser(self, cms)
|
||||||
if not d.exec_():
|
if not d.exec_():
|
||||||
return
|
return
|
||||||
|
# for each fact id, generate
|
||||||
n = _("Generate Cards")
|
n = _("Generate Cards")
|
||||||
|
self.parent.setProgressParent(self)
|
||||||
|
self.deck.startProgress()
|
||||||
self.deck.setUndoStart(n)
|
self.deck.setUndoStart(n)
|
||||||
for id in sf:
|
facts = self.deck.s.query(Fact).filter(
|
||||||
self.deck.addCards(self.deck.s.query(Fact).get(id),
|
text("id in %s" % ids2str(sf))).order_by(Fact.created).all()
|
||||||
d.selectedCms)
|
self.deck.updateProgress(_("Generating Cards..."))
|
||||||
|
for c, fact in enumerate(facts):
|
||||||
|
self.deck.addCards(fact, d.selectedCms)
|
||||||
|
if c % 50 == 0:
|
||||||
|
self.deck.updateProgress()
|
||||||
self.deck.flushMod()
|
self.deck.flushMod()
|
||||||
self.deck.updateAllPriorities()
|
self.deck.updateAllPriorities()
|
||||||
|
self.deck.finishProgress()
|
||||||
|
self.parent.setProgressParent(None)
|
||||||
self.deck.setUndoEnd(n)
|
self.deck.setUndoEnd(n)
|
||||||
self.updateSearch()
|
self.updateSearch()
|
||||||
self.updateAfterCardChange()
|
self.updateAfterCardChange()
|
||||||
|
@ -811,14 +822,25 @@ where id in %s""" % ids2str(sf))
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
def onFindReplace(self):
|
def onFindReplace(self):
|
||||||
|
sf = self.selectedFacts()
|
||||||
|
if not sf:
|
||||||
|
return
|
||||||
|
mods = self.deck.s.column0("""
|
||||||
|
select distinct modelId from facts
|
||||||
|
where id in %s""" % ids2str(sf))
|
||||||
|
if not len(mods) == 1:
|
||||||
|
ui.utils.showInfo(
|
||||||
|
_("Can only operate on one model at a time."),
|
||||||
|
parent=self)
|
||||||
|
return
|
||||||
d = QDialog(self)
|
d = QDialog(self)
|
||||||
frm = ankiqt.forms.findreplace.Ui_Dialog()
|
frm = ankiqt.forms.findreplace.Ui_Dialog()
|
||||||
frm.setupUi(d)
|
frm.setupUi(d)
|
||||||
|
fields = sorted(self.currentCard.fact.model.fieldModels, key=attrgetter("name"))
|
||||||
|
frm.field.addItems(QStringList(
|
||||||
|
[_("All Fields")] + [f.name for f in fields]))
|
||||||
self.connect(frm.buttonBox, SIGNAL("helpRequested()"),
|
self.connect(frm.buttonBox, SIGNAL("helpRequested()"),
|
||||||
self.onFindReplaceHelp)
|
self.onFindReplaceHelp)
|
||||||
frm.type.insertItems(0, [
|
|
||||||
_("Fields"),
|
|
||||||
_("Tags")])
|
|
||||||
if not d.exec_():
|
if not d.exec_():
|
||||||
return
|
return
|
||||||
n = _("Find and Replace")
|
n = _("Find and Replace")
|
||||||
|
@ -826,17 +848,20 @@ where id in %s""" % ids2str(sf))
|
||||||
self.deck.startProgress(2)
|
self.deck.startProgress(2)
|
||||||
self.deck.updateProgress(_("Replacing..."))
|
self.deck.updateProgress(_("Replacing..."))
|
||||||
self.deck.setUndoStart(n)
|
self.deck.setUndoStart(n)
|
||||||
sf = self.selectedFacts()
|
|
||||||
self.deck.updateProgress()
|
self.deck.updateProgress()
|
||||||
changed = None
|
changed = None
|
||||||
try:
|
try:
|
||||||
changed = self.deck.findReplace(self.selectedFacts(),
|
if frm.field.currentIndex() == 0:
|
||||||
unicode(frm.find.text()),
|
field = None
|
||||||
unicode(frm.replace.text()),
|
else:
|
||||||
frm.type.currentIndex(),
|
field = fields[frm.field.currentIndex()-1].id
|
||||||
frm.re.isChecked())
|
changed = self.deck.findReplace(sf,
|
||||||
|
unicode(frm.find.text()),
|
||||||
|
unicode(frm.replace.text()),
|
||||||
|
frm.re.isChecked(),
|
||||||
|
field)
|
||||||
except sre_constants.error:
|
except sre_constants.error:
|
||||||
ui.utils.showInfo(_("Invalid regexp."),
|
ui.utils.showInfo(_("Invalid regular expression."),
|
||||||
parent=self)
|
parent=self)
|
||||||
self.deck.setUndoEnd(n)
|
self.deck.setUndoEnd(n)
|
||||||
self.deck.finishProgress()
|
self.deck.finishProgress()
|
||||||
|
@ -850,7 +875,6 @@ where id in %s""" % ids2str(sf))
|
||||||
'b': len(sf),
|
'b': len(sf),
|
||||||
}, parent=self)
|
}, parent=self)
|
||||||
|
|
||||||
|
|
||||||
def onFindReplaceHelp(self):
|
def onFindReplaceHelp(self):
|
||||||
QDesktopServices.openUrl(QUrl(ankiqt.appWiki +
|
QDesktopServices.openUrl(QUrl(ankiqt.appWiki +
|
||||||
"Editor#FindReplace"))
|
"Editor#FindReplace"))
|
||||||
|
@ -861,18 +885,21 @@ where id in %s""" % ids2str(sf))
|
||||||
def onFirstCard(self):
|
def onFirstCard(self):
|
||||||
if not self.model.cards:
|
if not self.model.cards:
|
||||||
return
|
return
|
||||||
|
self.editor.saveFieldsNow()
|
||||||
self.dialog.tableView.selectionModel().clear()
|
self.dialog.tableView.selectionModel().clear()
|
||||||
self.dialog.tableView.selectRow(0)
|
self.dialog.tableView.selectRow(0)
|
||||||
|
|
||||||
def onLastCard(self):
|
def onLastCard(self):
|
||||||
if not self.model.cards:
|
if not self.model.cards:
|
||||||
return
|
return
|
||||||
|
self.editor.saveFieldsNow()
|
||||||
self.dialog.tableView.selectionModel().clear()
|
self.dialog.tableView.selectionModel().clear()
|
||||||
self.dialog.tableView.selectRow(len(self.model.cards) - 1)
|
self.dialog.tableView.selectRow(len(self.model.cards) - 1)
|
||||||
|
|
||||||
def onPreviousCard(self):
|
def onPreviousCard(self):
|
||||||
if not self.model.cards:
|
if not self.model.cards:
|
||||||
return
|
return
|
||||||
|
self.editor.saveFieldsNow()
|
||||||
row = self.dialog.tableView.currentIndex().row()
|
row = self.dialog.tableView.currentIndex().row()
|
||||||
row = max(0, row - 1)
|
row = max(0, row - 1)
|
||||||
self.dialog.tableView.selectionModel().clear()
|
self.dialog.tableView.selectionModel().clear()
|
||||||
|
@ -881,6 +908,7 @@ where id in %s""" % ids2str(sf))
|
||||||
def onNextCard(self):
|
def onNextCard(self):
|
||||||
if not self.model.cards:
|
if not self.model.cards:
|
||||||
return
|
return
|
||||||
|
self.editor.saveFieldsNow()
|
||||||
row = self.dialog.tableView.currentIndex().row()
|
row = self.dialog.tableView.currentIndex().row()
|
||||||
row = min(len(self.model.cards) - 1, row + 1)
|
row = min(len(self.model.cards) - 1, row + 1)
|
||||||
self.dialog.tableView.selectionModel().clear()
|
self.dialog.tableView.selectionModel().clear()
|
||||||
|
|
|
@ -243,6 +243,7 @@ class DeckProperties(QDialog):
|
||||||
*60*60 + time.timezone)
|
*60*60 + time.timezone)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
was = self.d.modified
|
||||||
self.updateField(self.d, 'collapseTime',
|
self.updateField(self.d, 'collapseTime',
|
||||||
self.dialog.collapse.isChecked() and 1 or 0)
|
self.dialog.collapse.isChecked() and 1 or 0)
|
||||||
self.updateField(self.d,
|
self.updateField(self.d,
|
||||||
|
@ -257,6 +258,7 @@ class DeckProperties(QDialog):
|
||||||
self.updateField(self.d,
|
self.updateField(self.d,
|
||||||
"suspended",
|
"suspended",
|
||||||
unicode(self.dialog.postponing.text()))
|
unicode(self.dialog.postponing.text()))
|
||||||
|
prioritiesChanged = was != self.d.modified
|
||||||
# sources
|
# sources
|
||||||
d = {}
|
d = {}
|
||||||
d.update(self.sources)
|
d.update(self.sources)
|
||||||
|
@ -289,8 +291,8 @@ insert into sources values
|
||||||
self.d.setModified()
|
self.d.setModified()
|
||||||
# mark deck dirty and close
|
# mark deck dirty and close
|
||||||
if self.origMod != self.d.modified:
|
if self.origMod != self.d.modified:
|
||||||
self.d.updateCardTags()
|
if prioritiesChanged:
|
||||||
self.d.updateAllPriorities()
|
self.d.updateAllPriorities()
|
||||||
ankiqt.mw.reset()
|
ankiqt.mw.reset()
|
||||||
self.d.setUndoEnd(n)
|
self.d.setUndoEnd(n)
|
||||||
self.d.finishProgress()
|
self.d.finishProgress()
|
||||||
|
|
|
@ -4,10 +4,20 @@
|
||||||
from PyQt4.QtGui import *
|
from PyQt4.QtGui import *
|
||||||
from PyQt4.QtCore import *
|
from PyQt4.QtCore import *
|
||||||
import anki, ankiqt
|
import anki, ankiqt
|
||||||
from anki.exporting import exporters
|
from anki.exporting import exporters as exporters_
|
||||||
from anki.utils import parseTags
|
from anki.utils import parseTags
|
||||||
from ankiqt import ui
|
from ankiqt import ui
|
||||||
|
|
||||||
|
class PackagedAnkiExporter(object):
|
||||||
|
def __init__(self, *args):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def exporters():
|
||||||
|
l = list(exporters_())
|
||||||
|
l.insert(1, (_("Packaged Anki Deck (*.zip)"),
|
||||||
|
PackagedAnkiExporter))
|
||||||
|
return l
|
||||||
|
|
||||||
class ExportDialog(QDialog):
|
class ExportDialog(QDialog):
|
||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
|
@ -35,7 +45,7 @@ class ExportDialog(QDialog):
|
||||||
self.setTabOrder(self.tags,
|
self.setTabOrder(self.tags,
|
||||||
self.dialog.includeScheduling)
|
self.dialog.includeScheduling)
|
||||||
# save button
|
# save button
|
||||||
b = QPushButton(_("Export to..."))
|
b = QPushButton(_("Export..."))
|
||||||
self.dialog.buttonBox.addButton(b, QDialogButtonBox.AcceptRole)
|
self.dialog.buttonBox.addButton(b, QDialogButtonBox.AcceptRole)
|
||||||
|
|
||||||
def exporterChanged(self, idx):
|
def exporterChanged(self, idx):
|
||||||
|
@ -50,6 +60,9 @@ class ExportDialog(QDialog):
|
||||||
self.dialog.includeTags.hide()
|
self.dialog.includeTags.hide()
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
|
if isinstance(self.exporter, PackagedAnkiExporter):
|
||||||
|
self.parent.onShare(parseTags(unicode(self.tags.text())))
|
||||||
|
return QDialog.accept(self)
|
||||||
file = ui.utils.getSaveFile(self, _("Choose file to export to"), "export",
|
file = ui.utils.getSaveFile(self, _("Choose file to export to"), "export",
|
||||||
self.exporter.key, self.exporter.ext)
|
self.exporter.key, self.exporter.ext)
|
||||||
self.hide()
|
self.hide()
|
||||||
|
|
|
@ -14,6 +14,7 @@ from ankiqt import ui
|
||||||
import ankiqt
|
import ankiqt
|
||||||
from ankiqt.ui.utils import mungeQA, saveGeom, restoreGeom
|
from ankiqt.ui.utils import mungeQA, saveGeom, restoreGeom
|
||||||
from anki.hooks import addHook
|
from anki.hooks import addHook
|
||||||
|
from sqlalchemy.exceptions import InvalidRequestError
|
||||||
|
|
||||||
clozeColour = "#0000ff"
|
clozeColour = "#0000ff"
|
||||||
|
|
||||||
|
@ -38,6 +39,7 @@ class FactEditor(object):
|
||||||
self.changeTimer = None
|
self.changeTimer = None
|
||||||
self.lastCloze = None
|
self.lastCloze = None
|
||||||
addHook("deckClosed", self.deckClosedHook)
|
addHook("deckClosed", self.deckClosedHook)
|
||||||
|
addHook("guiReset", self.refresh)
|
||||||
|
|
||||||
def setFact(self, fact, noFocus=False, check=False):
|
def setFact(self, fact, noFocus=False, check=False):
|
||||||
"Make FACT the current fact."
|
"Make FACT the current fact."
|
||||||
|
@ -63,6 +65,15 @@ class FactEditor(object):
|
||||||
if self.deck.mediaDir(create=False):
|
if self.deck.mediaDir(create=False):
|
||||||
self.initMedia()
|
self.initMedia()
|
||||||
|
|
||||||
|
def refresh(self):
|
||||||
|
if self.fact:
|
||||||
|
try:
|
||||||
|
self.deck.s.refresh(self.fact)
|
||||||
|
except InvalidRequestError:
|
||||||
|
# not attached to session yet, add cards dialog will handle
|
||||||
|
return
|
||||||
|
self.setFact(self.fact, check=True)
|
||||||
|
|
||||||
def focusFirst(self):
|
def focusFirst(self):
|
||||||
if self.focusTarget:
|
if self.focusTarget:
|
||||||
self.focusTarget.setFocus()
|
self.focusTarget.setFocus()
|
||||||
|
@ -253,12 +264,12 @@ class FactEditor(object):
|
||||||
self.preview.setStyle(self.plastiqueStyle)
|
self.preview.setStyle(self.plastiqueStyle)
|
||||||
# cloze
|
# cloze
|
||||||
self.cloze = QPushButton(self.widget)
|
self.cloze = QPushButton(self.widget)
|
||||||
self.clozeSC = QShortcut(QKeySequence(_("F6")), self.widget)
|
self.clozeSC = QShortcut(QKeySequence(_("F9")), self.widget)
|
||||||
self.cloze.connect(self.cloze, SIGNAL("clicked()"),
|
self.cloze.connect(self.cloze, SIGNAL("clicked()"),
|
||||||
self.onCloze)
|
self.onCloze)
|
||||||
self.cloze.connect(self.clozeSC, SIGNAL("activated()"),
|
self.cloze.connect(self.clozeSC, SIGNAL("activated()"),
|
||||||
self.onCloze)
|
self.onCloze)
|
||||||
self.cloze.setToolTip(_("Cloze (F6)"))
|
self.cloze.setToolTip(_("Cloze (F9)"))
|
||||||
#self.cloze.setIcon(QIcon(":/icons/document-cloze.png"))
|
#self.cloze.setIcon(QIcon(":/icons/document-cloze.png"))
|
||||||
self.cloze.setFixedWidth(30)
|
self.cloze.setFixedWidth(30)
|
||||||
self.cloze.setFixedHeight(26)
|
self.cloze.setFixedHeight(26)
|
||||||
|
@ -306,12 +317,12 @@ class FactEditor(object):
|
||||||
self.latexMathEnv.setStyle(self.plastiqueStyle)
|
self.latexMathEnv.setStyle(self.plastiqueStyle)
|
||||||
# html
|
# html
|
||||||
self.htmlEdit = QPushButton(self.widget)
|
self.htmlEdit = QPushButton(self.widget)
|
||||||
self.htmlEdit.setToolTip(_("HTML Editor (F9)"))
|
self.htmlEdit.setToolTip(_("HTML Editor"))
|
||||||
self.htmlEditSC = QShortcut(QKeySequence(_("F9")), self.widget)
|
self.htmlEditSC = QShortcut(QKeySequence(_("Ctrl+F9")), self.widget)
|
||||||
self.htmlEdit.connect(self.htmlEdit, SIGNAL("clicked()"),
|
self.htmlEdit.connect(self.htmlEdit, SIGNAL("clicked()"),
|
||||||
self.onHtmlEdit)
|
self.onHtmlEdit)
|
||||||
self.htmlEdit.connect(self.htmlEditSC, SIGNAL("activated()"),
|
self.htmlEdit.connect(self.htmlEditSC, SIGNAL("activated()"),
|
||||||
self.onHtmlEdit)
|
self.onHtmlEdit)
|
||||||
self.htmlEdit.setIcon(QIcon(":/icons/text-xml.png"))
|
self.htmlEdit.setIcon(QIcon(":/icons/text-xml.png"))
|
||||||
self.htmlEdit.setFocusPolicy(Qt.NoFocus)
|
self.htmlEdit.setFocusPolicy(Qt.NoFocus)
|
||||||
self.htmlEdit.setEnabled(False)
|
self.htmlEdit.setEnabled(False)
|
||||||
|
@ -679,17 +690,24 @@ class FactEditor(object):
|
||||||
src = self.focusedEdit()
|
src = self.focusedEdit()
|
||||||
if not src:
|
if not src:
|
||||||
return
|
return
|
||||||
|
re1 = "\[.+?(:(.+?))?\]"
|
||||||
|
re2 = "\[(.+?)(:.+?)?\]"
|
||||||
# add brackets because selected?
|
# add brackets because selected?
|
||||||
cursor = src.textCursor()
|
cursor = src.textCursor()
|
||||||
|
oldSrc = None
|
||||||
if cursor.hasSelection():
|
if cursor.hasSelection():
|
||||||
|
oldSrc = src.toHtml()
|
||||||
s = cursor.selectionStart()
|
s = cursor.selectionStart()
|
||||||
e = cursor.selectionEnd()
|
e = cursor.selectionEnd()
|
||||||
cursor.setPosition(e)
|
cursor.setPosition(e)
|
||||||
cursor.insertText("]")
|
cursor.insertText("]]")
|
||||||
cursor.setPosition(s)
|
cursor.setPosition(s)
|
||||||
cursor.insertText("[")
|
cursor.insertText("[[")
|
||||||
|
re1 = "\[" + re1 + "\]"
|
||||||
|
re2 = "\[" + re2 + "\]"
|
||||||
dst = None
|
dst = None
|
||||||
for (name, (field, w)) in self.fields.items():
|
for field in self.fact.fields:
|
||||||
|
w = self.fields[field.name][1]
|
||||||
if w.hasFocus():
|
if w.hasFocus():
|
||||||
dst = False
|
dst = False
|
||||||
continue
|
continue
|
||||||
|
@ -697,11 +715,12 @@ class FactEditor(object):
|
||||||
dst = w
|
dst = w
|
||||||
break
|
break
|
||||||
if not dst:
|
if not dst:
|
||||||
dst = self.fields.values()[0][1]
|
dst = self.fields[self.fact.fields[0].name][1]
|
||||||
if dst == w:
|
if dst == w:
|
||||||
return
|
return
|
||||||
# check if there's alredy something there
|
# check if there's alredy something there
|
||||||
oldSrc = src.toHtml()
|
if not oldSrc:
|
||||||
|
oldSrc = src.toHtml()
|
||||||
oldDst = dst.toHtml()
|
oldDst = dst.toHtml()
|
||||||
if unicode(dst.toPlainText()):
|
if unicode(dst.toPlainText()):
|
||||||
if (self.lastCloze and
|
if (self.lastCloze and
|
||||||
|
@ -729,10 +748,9 @@ class FactEditor(object):
|
||||||
exp = match.group(2)
|
exp = match.group(2)
|
||||||
return '<font color="%s"><b>[...%s]</b></font>' % (
|
return '<font color="%s"><b>[...%s]</b></font>' % (
|
||||||
clozeColour, exp)
|
clozeColour, exp)
|
||||||
new = re.sub("\[.+?(:(.+?))?\]", repl, s)
|
new = re.sub(re1, repl, s)
|
||||||
old = re.sub("\[(.+?)(:.+?)?\]", '<font color="%s"><b>\\1</b></font>'
|
old = re.sub(re2, '<font color="%s"><b>\\1</b></font>'
|
||||||
% clozeColour, s)
|
% clozeColour, s)
|
||||||
oldSrc = unicode(src.toHtml())
|
|
||||||
src.setHtml(new)
|
src.setHtml(new)
|
||||||
dst.setHtml(old)
|
dst.setHtml(old)
|
||||||
self.lastCloze = (oldSrc, unicode(src.toHtml()),
|
self.lastCloze = (oldSrc, unicode(src.toHtml()),
|
||||||
|
|
227
ankiqt/ui/getshared.py
Normal file
227
ankiqt/ui/getshared.py
Normal file
|
@ -0,0 +1,227 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright: Damien Elmes <anki@ichi2.net>
|
||||||
|
# License: GNU GPL, version 3 or later; http://www.gnu.org/copyleft/gpl.html
|
||||||
|
|
||||||
|
from PyQt4.QtGui import *
|
||||||
|
from PyQt4.QtCore import *
|
||||||
|
from PyQt4.QtNetwork import *
|
||||||
|
import ankiqt, simplejson, time, cStringIO, zipfile, tempfile, os, re
|
||||||
|
from ankiqt.ui.utils import saveGeom, restoreGeom, showInfo
|
||||||
|
from anki.utils import fmtTimeSpan
|
||||||
|
|
||||||
|
R_ID = 0
|
||||||
|
R_USERNAME = 1
|
||||||
|
R_TITLE = 2
|
||||||
|
R_DESCRIPTION = 3
|
||||||
|
R_TAGS = 4
|
||||||
|
R_VERSION = 5
|
||||||
|
R_FACTS = 6
|
||||||
|
R_SIZE = 7
|
||||||
|
R_COUNT = 8
|
||||||
|
R_MODIFIED = 9
|
||||||
|
R_FNAME = 10
|
||||||
|
|
||||||
|
class GetShared(QDialog):
|
||||||
|
|
||||||
|
def __init__(self, parent, type):
|
||||||
|
QDialog.__init__(self, parent, Qt.Window)
|
||||||
|
self.parent = parent
|
||||||
|
self.form = ankiqt.forms.getshared.Ui_Dialog()
|
||||||
|
self.form.setupUi(self)
|
||||||
|
restoreGeom(self, "getshared")
|
||||||
|
self.setupTable()
|
||||||
|
self.onChangeType(type)
|
||||||
|
self.ok = False
|
||||||
|
if type == 0:
|
||||||
|
self.setWindowTitle(_("Download Shared Deck"))
|
||||||
|
else:
|
||||||
|
self.setWindowTitle(_("Download Shared Plugin"))
|
||||||
|
self.exec_()
|
||||||
|
|
||||||
|
def setupTable(self):
|
||||||
|
self.connect(
|
||||||
|
self.form.table, SIGNAL("currentCellChanged(int,int,int,int)"),
|
||||||
|
self.onCellChanged)
|
||||||
|
self.form.table.verticalHeader().setDefaultSectionSize(
|
||||||
|
self.parent.config['editLineSize'])
|
||||||
|
self.connect(self.form.search, SIGNAL("textChanged(QString)"),
|
||||||
|
self.limit)
|
||||||
|
|
||||||
|
def fetchData(self):
|
||||||
|
h = QHttp(self)
|
||||||
|
h.connect(h, SIGNAL("requestFinished(int,bool)"), self.onReqFin)
|
||||||
|
h.setHost("anki.ichi2.net")
|
||||||
|
#h.setHost("localhost", 8001)
|
||||||
|
self.conId = h.get("/file/search?t=%d" % self.type)
|
||||||
|
self.http = h
|
||||||
|
self.parent.setProgressParent(self)
|
||||||
|
self.parent.startProgress()
|
||||||
|
|
||||||
|
def onReqFin(self, id, err):
|
||||||
|
"List fetched."
|
||||||
|
if id != self.conId:
|
||||||
|
return
|
||||||
|
self.parent.finishProgress()
|
||||||
|
self.parent.setProgressParent(None)
|
||||||
|
if err:
|
||||||
|
showInfo(_("Unable to connect to server."), parent=self)
|
||||||
|
self.close()
|
||||||
|
return
|
||||||
|
data = self.http.readAll()
|
||||||
|
self.allList = simplejson.loads(unicode(data))
|
||||||
|
self.typeChanged()
|
||||||
|
self.limit()
|
||||||
|
|
||||||
|
def limit(self, txt=""):
|
||||||
|
if not txt:
|
||||||
|
self.curList = self.allList
|
||||||
|
else:
|
||||||
|
txt = unicode(txt).lower()
|
||||||
|
self.curList = [
|
||||||
|
l for l in self.allList
|
||||||
|
if (txt in l[R_TITLE].lower() or
|
||||||
|
txt in l[R_DESCRIPTION].lower() or
|
||||||
|
txt in l[R_TAGS].lower())]
|
||||||
|
self.redraw()
|
||||||
|
|
||||||
|
def redraw(self):
|
||||||
|
self.form.table.setSortingEnabled(False)
|
||||||
|
self.form.table.setRowCount(len(self.curList))
|
||||||
|
self.items = {}
|
||||||
|
if self.type == 0:
|
||||||
|
cols = (R_TITLE, R_FACTS, R_COUNT)
|
||||||
|
else:
|
||||||
|
cols = (R_TITLE, R_COUNT)
|
||||||
|
for rc, r in enumerate(self.curList):
|
||||||
|
for cc, c in enumerate(cols):
|
||||||
|
if c == R_FACTS or c == R_COUNT:
|
||||||
|
txt = unicode("%15d" % r[c])
|
||||||
|
else:
|
||||||
|
txt = unicode(r[c])
|
||||||
|
item = QTableWidgetItem(txt)
|
||||||
|
item.setFlags(item.flags() & ~Qt.ItemIsEditable)
|
||||||
|
self.items[item] = r
|
||||||
|
self.form.table.setItem(rc, cc, item)
|
||||||
|
self.form.table.setSortingEnabled(True)
|
||||||
|
if self.type == 0:
|
||||||
|
self.form.table.sortItems(2, Qt.DescendingOrder)
|
||||||
|
else:
|
||||||
|
self.form.table.sortItems(1, Qt.DescendingOrder)
|
||||||
|
self.form.table.selectRow(0)
|
||||||
|
|
||||||
|
def onCellChanged(self, row, col, x, y):
|
||||||
|
ci = self.form.table.currentItem()
|
||||||
|
if not ci:
|
||||||
|
self.form.bottomLabel.setText(_("Nothing selected."))
|
||||||
|
return
|
||||||
|
r = self.items[ci]
|
||||||
|
self.curRow = r
|
||||||
|
self.form.bottomLabel.setText(_("""\
|
||||||
|
<b>Title</b>: %(title)s<br>
|
||||||
|
<b>Tags</b>: %(tags)s<br>
|
||||||
|
<b>Size</b>: %(size)0.2fKB<br>
|
||||||
|
<b>Uploader</b>: %(author)s<br>
|
||||||
|
<b>Downloads</b>: %(count)s<br>
|
||||||
|
<b>Description</b>:<br>%(description)s""") % {
|
||||||
|
'title': r[R_TITLE],
|
||||||
|
'tags': r[R_TAGS],
|
||||||
|
'size': r[R_SIZE] / 1024.0,
|
||||||
|
'author': r[R_USERNAME],
|
||||||
|
'count': r[R_COUNT],
|
||||||
|
'description': r[R_DESCRIPTION].replace("\n", "<br>"),
|
||||||
|
})
|
||||||
|
self.form.scrollAreaWidgetContents.adjustSize()
|
||||||
|
self.form.scrollArea.setWidget(self.form.scrollAreaWidgetContents)
|
||||||
|
|
||||||
|
def onChangeType(self, type):
|
||||||
|
self.type = type
|
||||||
|
self.fetchData()
|
||||||
|
|
||||||
|
def typeChanged(self):
|
||||||
|
self.form.table.clear()
|
||||||
|
if self.type == 0:
|
||||||
|
self.form.table.setColumnCount(3)
|
||||||
|
self.form.table.setHorizontalHeaderLabels([
|
||||||
|
_("Title"), _("Facts"), _("Downloads")])
|
||||||
|
else:
|
||||||
|
self.form.table.setColumnCount(2)
|
||||||
|
self.form.table.setHorizontalHeaderLabels([
|
||||||
|
_("Title"), _("Downloads")])
|
||||||
|
self.form.table.horizontalHeader().setResizeMode(
|
||||||
|
0, QHeaderView.Stretch)
|
||||||
|
self.form.table.verticalHeader().hide()
|
||||||
|
self.form.table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||||
|
|
||||||
|
def accept(self):
|
||||||
|
h = QHttp(self)
|
||||||
|
h.connect(h, SIGNAL("requestFinished(int,bool)"), self.onReqFin2)
|
||||||
|
h.setHost("anki.ichi2.net")
|
||||||
|
#h.setHost("localhost", 8001)
|
||||||
|
self.conId = h.get("/file/get?id=%d" % self.curRow[R_ID])
|
||||||
|
self.http = h
|
||||||
|
self.parent.setProgressParent(self)
|
||||||
|
self.parent.startProgress()
|
||||||
|
|
||||||
|
def onReqFin2(self, id, err):
|
||||||
|
"File fetched."
|
||||||
|
if id != self.conId:
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
self.parent.finishProgress()
|
||||||
|
self.parent.setProgressParent(None)
|
||||||
|
if err:
|
||||||
|
showInfo(_("Unable to connect to server."), parent=self)
|
||||||
|
self.close()
|
||||||
|
return
|
||||||
|
data = self.http.readAll()
|
||||||
|
ext = os.path.splitext(self.curRow[R_FNAME])[1]
|
||||||
|
if ext == ".zip":
|
||||||
|
f = cStringIO.StringIO()
|
||||||
|
f.write(data)
|
||||||
|
z = zipfile.ZipFile(f)
|
||||||
|
else:
|
||||||
|
z = None
|
||||||
|
tit = self.curRow[R_TITLE]
|
||||||
|
tit = re.sub("[^][A-Za-z0-9 ()\-]", "", tit)
|
||||||
|
tit = tit[0:40]
|
||||||
|
if self.type == 0:
|
||||||
|
# deck
|
||||||
|
dd = self.parent.documentDir
|
||||||
|
p = os.path.join(dd, tit + ".anki")
|
||||||
|
if os.path.exists(p):
|
||||||
|
tit += "%d" % time.time()
|
||||||
|
for l in z.namelist():
|
||||||
|
if l == "shared.anki":
|
||||||
|
dpath = os.path.join(dd, tit + ".anki")
|
||||||
|
open(dpath, "wb").write(z.read(l))
|
||||||
|
elif l.startswith("shared.media/"):
|
||||||
|
try:
|
||||||
|
os.mkdir(os.path.join(dd, tit + ".media"))
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
open(os.path.join(dd, tit + ".media",
|
||||||
|
os.path.basename(l)),"wb").write(z.read(l))
|
||||||
|
self.parent.loadDeck(dpath)
|
||||||
|
self.ok = True
|
||||||
|
else:
|
||||||
|
pd = self.parent.pluginsFolder()
|
||||||
|
if z:
|
||||||
|
for l in z.infolist():
|
||||||
|
if not l.file_size:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
os.makedirs(os.path.join(
|
||||||
|
pd, os.path.dirname(l.filename)))
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
open(os.path.join(pd, l.filename), "wb").\
|
||||||
|
write(z.read(l.filename))
|
||||||
|
else:
|
||||||
|
open(os.path.join(pd, tit + ext), "wb").write(data)
|
||||||
|
self.ok = True
|
||||||
|
showInfo(_("Plugin downloaded. Please restart Anki."),
|
||||||
|
parent=self)
|
||||||
|
return
|
||||||
|
finally:
|
||||||
|
QDialog.accept(self)
|
||||||
|
|
|
@ -41,7 +41,8 @@ class HelpArea(object):
|
||||||
|
|
||||||
def showText(self, text, py={}):
|
def showText(self, text, py={}):
|
||||||
if "hide" in self.handlers:
|
if "hide" in self.handlers:
|
||||||
self.handlers["hide"]()
|
if self.handlers['hide'] != py.get('hide'):
|
||||||
|
self.handlers["hide"]()
|
||||||
self.show()
|
self.show()
|
||||||
self.buffer = text
|
self.buffer = text
|
||||||
self.addHider()
|
self.addHider()
|
||||||
|
|
|
@ -132,7 +132,7 @@ class ImportDialog(QDialog):
|
||||||
self.parent.deck.finishProgress()
|
self.parent.deck.finishProgress()
|
||||||
self.parent.deck.setUndoEnd(n)
|
self.parent.deck.setUndoEnd(n)
|
||||||
txt = (
|
txt = (
|
||||||
_("Importing complete. %(num)d cards imported from %(file)s.\n") %
|
_("Importing complete. %(num)d facts imported from %(file)s.\n") %
|
||||||
{"num": self.importer.total, "file": os.path.basename(self.file)})
|
{"num": self.importer.total, "file": os.path.basename(self.file)})
|
||||||
txt += _("Click the close button or import another file.\n\n")
|
txt += _("Click the close button or import another file.\n\n")
|
||||||
if self.importer.log:
|
if self.importer.log:
|
||||||
|
|
|
@ -6,8 +6,8 @@ from PyQt4.QtGui import *
|
||||||
from PyQt4.QtCore import *
|
from PyQt4.QtCore import *
|
||||||
from PyQt4.QtWebKit import QWebPage
|
from PyQt4.QtWebKit import QWebPage
|
||||||
|
|
||||||
import os, sys, re, types, gettext, stat, traceback
|
import os, sys, re, types, gettext, stat, traceback, inspect
|
||||||
import shutil, time, glob, tempfile, datetime
|
import shutil, time, glob, tempfile, datetime, zipfile, locale
|
||||||
|
|
||||||
from PyQt4.QtCore import *
|
from PyQt4.QtCore import *
|
||||||
from PyQt4.QtGui import *
|
from PyQt4.QtGui import *
|
||||||
|
@ -49,8 +49,6 @@ class AnkiQt(QMainWindow):
|
||||||
self.setupTray()
|
self.setupTray()
|
||||||
self.connectMenuActions()
|
self.connectMenuActions()
|
||||||
ui.splash.update()
|
ui.splash.update()
|
||||||
if self.config['mainWindowGeom']:
|
|
||||||
self.restoreGeometry(self.config['mainWindowGeom'])
|
|
||||||
self.setupViews()
|
self.setupViews()
|
||||||
self.setupEditor()
|
self.setupEditor()
|
||||||
self.setupStudyScreen()
|
self.setupStudyScreen()
|
||||||
|
@ -58,6 +56,9 @@ class AnkiQt(QMainWindow):
|
||||||
self.setupAnchors()
|
self.setupAnchors()
|
||||||
self.setupToolbar()
|
self.setupToolbar()
|
||||||
self.setupProgressInfo()
|
self.setupProgressInfo()
|
||||||
|
if self.config['mainWindowState']:
|
||||||
|
self.restoreGeometry(self.config['mainWindowGeom'])
|
||||||
|
self.restoreState(self.config['mainWindowState'])
|
||||||
if sys.platform.startswith("darwin"):
|
if sys.platform.startswith("darwin"):
|
||||||
self.setUnifiedTitleAndToolBarOnMac(True)
|
self.setUnifiedTitleAndToolBarOnMac(True)
|
||||||
pass
|
pass
|
||||||
|
@ -68,10 +69,11 @@ class AnkiQt(QMainWindow):
|
||||||
self.moveToState("auto")
|
self.moveToState("auto")
|
||||||
# check for updates
|
# check for updates
|
||||||
ui.splash.update()
|
ui.splash.update()
|
||||||
self.setupAutoUpdate()
|
self.errorOccurred = False
|
||||||
self.setupErrorHandler()
|
self.setupErrorHandler()
|
||||||
self.setupMisc()
|
self.setupMisc()
|
||||||
self.loadPlugins()
|
self.loadPlugins()
|
||||||
|
self.setupAutoUpdate()
|
||||||
self.rebuildPluginsMenu()
|
self.rebuildPluginsMenu()
|
||||||
# run after-init hook
|
# run after-init hook
|
||||||
try:
|
try:
|
||||||
|
@ -82,6 +84,9 @@ class AnkiQt(QMainWindow):
|
||||||
ui.splash.update()
|
ui.splash.update()
|
||||||
ui.splash.finish(self)
|
ui.splash.finish(self)
|
||||||
self.show()
|
self.show()
|
||||||
|
if (self.deck and self.config['syncOnLoad'] and
|
||||||
|
self.deck.syncName):
|
||||||
|
self.syncDeck(interactive=False)
|
||||||
|
|
||||||
def setupMainWindow(self):
|
def setupMainWindow(self):
|
||||||
# main window
|
# main window
|
||||||
|
@ -142,9 +147,11 @@ class AnkiQt(QMainWindow):
|
||||||
# hack for matplotlib errors on osx
|
# hack for matplotlib errors on osx
|
||||||
self.pool = ""
|
self.pool = ""
|
||||||
stdText = _("""\
|
stdText = _("""\
|
||||||
An error occurred.<br>
|
An error occurred. Please:<p>
|
||||||
Please run <b>Tools > Advanced > Check DB</b>.<br>
|
<ol>
|
||||||
<br>
|
<li><b>Restart Anki</b>.
|
||||||
|
<li><b>Tools > Advanced > Check DB</b>.
|
||||||
|
</ol>
|
||||||
If it does not fix the problem, please copy the following<br>
|
If it does not fix the problem, please copy the following<br>
|
||||||
into a bug report:<br><br>
|
into a bug report:<br><br>
|
||||||
""")
|
""")
|
||||||
|
@ -156,6 +163,7 @@ Please do not file a bug report with Anki.<br><br>""")
|
||||||
else:
|
else:
|
||||||
txt = stdText
|
txt = stdText
|
||||||
if self.pool:
|
if self.pool:
|
||||||
|
self.parent.errorOccurred = True
|
||||||
ui.utils.showText(txt + self.pool[0:10000].replace(
|
ui.utils.showText(txt + self.pool[0:10000].replace(
|
||||||
"\n", "<br>"))
|
"\n", "<br>"))
|
||||||
self.pool = ""
|
self.pool = ""
|
||||||
|
@ -197,6 +205,7 @@ Please do not file a bug report with Anki.<br><br>""")
|
||||||
if count:
|
if count:
|
||||||
self.deck.rebuildCounts()
|
self.deck.rebuildCounts()
|
||||||
self.deck.rebuildQueue()
|
self.deck.rebuildQueue()
|
||||||
|
runHook("guiReset")
|
||||||
self.moveToState("initial")
|
self.moveToState("initial")
|
||||||
|
|
||||||
def moveToState(self, state):
|
def moveToState(self, state):
|
||||||
|
@ -349,12 +358,12 @@ Please do not file a bug report with Anki.<br><br>""")
|
||||||
"Reschedule current card and move back to getQuestion state."
|
"Reschedule current card and move back to getQuestion state."
|
||||||
if self.state != "showAnswer":
|
if self.state != "showAnswer":
|
||||||
return
|
return
|
||||||
# remove card from session before updating it
|
# force refresh of card then remove from session as we update in pure sql
|
||||||
try:
|
self.deck.s.refresh(self.currentCard)
|
||||||
self.deck.s.expunge(self.currentCard)
|
self.deck.s.refresh(self.currentCard.fact)
|
||||||
except:
|
self.deck.s.refresh(self.currentCard.cardModel)
|
||||||
# session has been reset
|
self.deck.s.expunge(self.currentCard)
|
||||||
pass
|
# answer
|
||||||
self.deck.answerCard(self.currentCard, quality)
|
self.deck.answerCard(self.currentCard, quality)
|
||||||
self.lastScheduledTime = anki.utils.fmtTimeSpan(
|
self.lastScheduledTime = anki.utils.fmtTimeSpan(
|
||||||
self.currentCard.due - time.time())
|
self.currentCard.due - time.time())
|
||||||
|
@ -611,10 +620,10 @@ To upgrade an old deck, download Anki 0.9.8.7."""))
|
||||||
# try a command line argument if available
|
# try a command line argument if available
|
||||||
if args:
|
if args:
|
||||||
f = unicode(args[0], sys.getfilesystemencoding())
|
f = unicode(args[0], sys.getfilesystemencoding())
|
||||||
return self.loadDeck(f)
|
return self.loadDeck(f, sync=False)
|
||||||
# try recent deck paths
|
# try recent deck paths
|
||||||
for path in self.config['recentDeckPaths']:
|
for path in self.config['recentDeckPaths']:
|
||||||
r = self.loadDeck(path, interactive=False)
|
r = self.loadDeck(path, interactive=False, sync=False)
|
||||||
if r:
|
if r:
|
||||||
return r
|
return r
|
||||||
self.onNew(initial=True)
|
self.onNew(initial=True)
|
||||||
|
@ -626,50 +635,10 @@ To upgrade an old deck, download Anki 0.9.8.7."""))
|
||||||
latest = self.config['recentDeckPaths'][0]
|
latest = self.config['recentDeckPaths'][0]
|
||||||
defaultDir = os.path.dirname(latest)
|
defaultDir = os.path.dirname(latest)
|
||||||
else:
|
else:
|
||||||
if save:
|
defaultDir = unicode(os.path.expanduser("~/"),
|
||||||
defaultDir = unicode(os.path.expanduser("~/"),
|
sys.getfilesystemencoding())
|
||||||
sys.getfilesystemencoding())
|
|
||||||
else:
|
|
||||||
samples = self.getSamplesDir()
|
|
||||||
if samples:
|
|
||||||
return samples
|
|
||||||
return defaultDir
|
return defaultDir
|
||||||
|
|
||||||
def getSamplesDir(self):
|
|
||||||
path = os.path.join(ankiqt.runningDir, "libanki")
|
|
||||||
if not os.path.exists(path):
|
|
||||||
path = os.path.join(
|
|
||||||
os.path.join(ankiqt.runningDir, ".."), "libanki")
|
|
||||||
if not os.path.exists(path):
|
|
||||||
path = ankiqt.runningDir
|
|
||||||
if sys.platform.startswith("win32"):
|
|
||||||
path = os.path.split(
|
|
||||||
os.path.split(ankiqt.runningDir)[0])[0]
|
|
||||||
elif sys.platform.startswith("darwin"):
|
|
||||||
path = ankiqt.runningDir + "/../../.."
|
|
||||||
path = os.path.join(path, "samples")
|
|
||||||
path = os.path.normpath(path)
|
|
||||||
if os.path.exists(path):
|
|
||||||
if sys.platform.startswith("darwin"):
|
|
||||||
return self.openMacSamplesDir(path)
|
|
||||||
return path
|
|
||||||
return ""
|
|
||||||
|
|
||||||
def openMacSamplesDir(self, path):
|
|
||||||
# some versions of macosx don't allow the open dialog to point inside
|
|
||||||
# a .App file, it seems - so we copy the files onto the desktop.
|
|
||||||
newDir = os.path.expanduser("~/Documents/Anki 0.9 Sample Decks")
|
|
||||||
import shutil
|
|
||||||
if os.path.exists(newDir):
|
|
||||||
files = os.listdir(path)
|
|
||||||
for file in files:
|
|
||||||
loc = os.path.join(path, file)
|
|
||||||
if not os.path.exists(os.path.join(newDir, file)):
|
|
||||||
shutil.copy2(loc, newDir)
|
|
||||||
return newDir
|
|
||||||
shutil.copytree(path, newDir)
|
|
||||||
return newDir
|
|
||||||
|
|
||||||
def updateRecentFiles(self, path):
|
def updateRecentFiles(self, path):
|
||||||
"Add the current deck to the list of recent files."
|
"Add the current deck to the list of recent files."
|
||||||
path = os.path.normpath(path)
|
path = os.path.normpath(path)
|
||||||
|
@ -761,6 +730,7 @@ To upgrade an old deck, download Anki 0.9.8.7."""))
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def inMainWindow(self):
|
def inMainWindow(self):
|
||||||
|
return True
|
||||||
return self.app.activeWindow() == self
|
return self.app.activeWindow() == self
|
||||||
|
|
||||||
def onNew(self, initial=False, path=None):
|
def onNew(self, initial=False, path=None):
|
||||||
|
@ -826,23 +796,27 @@ To upgrade an old deck, download Anki 0.9.8.7."""))
|
||||||
self.deck = None
|
self.deck = None
|
||||||
self.moveToState("initial")
|
self.moveToState("initial")
|
||||||
|
|
||||||
def onOpen(self, samples=False):
|
def onGetSharedDeck(self):
|
||||||
|
if not self.inMainWindow(): return
|
||||||
|
if not self.saveAndClose(hideWelcome=True): return
|
||||||
|
s = ui.getshared.GetShared(self, 0)
|
||||||
|
if not s.ok:
|
||||||
|
self.deck = None
|
||||||
|
self.moveToState("initial")
|
||||||
|
|
||||||
|
def onGetSharedPlugin(self):
|
||||||
|
if not self.inMainWindow(): return
|
||||||
|
ui.getshared.GetShared(self, 1)
|
||||||
|
|
||||||
|
def onOpen(self):
|
||||||
if not self.inMainWindow(): return
|
if not self.inMainWindow(): return
|
||||||
key = _("Deck files (*.anki)")
|
key = _("Deck files (*.anki)")
|
||||||
if samples: defaultDir = self.getSamplesDir()
|
defaultDir = self.getDefaultDir()
|
||||||
else: defaultDir = self.getDefaultDir()
|
|
||||||
file = QFileDialog.getOpenFileName(self, _("Open deck"),
|
file = QFileDialog.getOpenFileName(self, _("Open deck"),
|
||||||
defaultDir, key)
|
defaultDir, key)
|
||||||
file = unicode(file)
|
file = unicode(file)
|
||||||
if not file:
|
if not file:
|
||||||
return False
|
return False
|
||||||
if samples:
|
|
||||||
# we need to copy into a writeable location
|
|
||||||
d = unicode(
|
|
||||||
os.path.join(self.documentDir, os.path.basename(file)))
|
|
||||||
if not os.path.exists(d):
|
|
||||||
shutil.copy(file, d)
|
|
||||||
file = d
|
|
||||||
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:
|
||||||
|
@ -853,9 +827,6 @@ To upgrade an old deck, download Anki 0.9.8.7."""))
|
||||||
self.updateRecentFiles(file)
|
self.updateRecentFiles(file)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def onOpenSamples(self):
|
|
||||||
self.onOpen(samples=True)
|
|
||||||
|
|
||||||
def onUnsavedTimer(self):
|
def onUnsavedTimer(self):
|
||||||
QToolTip.showText(
|
QToolTip.showText(
|
||||||
self.mainWin.statusbar.mapToGlobal(QPoint(0, -100)),
|
self.mainWin.statusbar.mapToGlobal(QPoint(0, -100)),
|
||||||
|
@ -925,6 +896,7 @@ your deck."""))
|
||||||
runHook("quit")
|
runHook("quit")
|
||||||
self.help.hide()
|
self.help.hide()
|
||||||
self.config['mainWindowGeom'] = self.saveGeometry()
|
self.config['mainWindowGeom'] = self.saveGeometry()
|
||||||
|
self.config['mainWindowState'] = self.saveState()
|
||||||
# save config
|
# save config
|
||||||
try:
|
try:
|
||||||
self.config.save()
|
self.config.save()
|
||||||
|
@ -950,14 +922,12 @@ your deck."""))
|
||||||
def onWelcomeAnchor(self, str):
|
def onWelcomeAnchor(self, str):
|
||||||
if str == "new":
|
if str == "new":
|
||||||
self.onNew()
|
self.onNew()
|
||||||
elif str == "sample":
|
|
||||||
self.onOpenSamples()
|
|
||||||
elif str == "open":
|
elif str == "open":
|
||||||
self.onOpen()
|
self.onOpen()
|
||||||
|
elif str == "sample":
|
||||||
|
self.onGetSharedDeck()
|
||||||
elif str == "openrem":
|
elif str == "openrem":
|
||||||
self.onOpenOnline()
|
self.onOpenOnline()
|
||||||
elif str == "more":
|
|
||||||
self.onGetMoreDecks()
|
|
||||||
if str == "addfacts":
|
if str == "addfacts":
|
||||||
if not self.deck:
|
if not self.deck:
|
||||||
self.onNew()
|
self.onNew()
|
||||||
|
@ -1175,7 +1145,6 @@ day = :d""", d=yesterday)
|
||||||
self.deck.newCardSpacing = self.mainWin.newCardScheduling.currentIndex()
|
self.deck.newCardSpacing = self.mainWin.newCardScheduling.currentIndex()
|
||||||
self.deck.revCardOrder = self.mainWin.revCardOrder.currentIndex()
|
self.deck.revCardOrder = self.mainWin.revCardOrder.currentIndex()
|
||||||
self.deck.setFailedCardPolicy(self.mainWin.failedCardsOption.currentIndex())
|
self.deck.setFailedCardPolicy(self.mainWin.failedCardsOption.currentIndex())
|
||||||
self.deck.updateDynamicIndices()
|
|
||||||
self.deck.startSession()
|
self.deck.startSession()
|
||||||
self.deck.flushMod()
|
self.deck.flushMod()
|
||||||
self.moveToState("getQuestion")
|
self.moveToState("getQuestion")
|
||||||
|
@ -1401,13 +1370,11 @@ day = :d""", d=yesterday)
|
||||||
def onActiveTags(self):
|
def onActiveTags(self):
|
||||||
ui.activetags.show(self)
|
ui.activetags.show(self)
|
||||||
|
|
||||||
def onGetMoreDecks(self):
|
|
||||||
QDesktopServices.openUrl(QUrl(ankiqt.appMoreDecks))
|
|
||||||
|
|
||||||
# Importing & exporting
|
# Importing & exporting
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
def onImport(self):
|
def onImport(self):
|
||||||
|
import ui.importing
|
||||||
if self.deck is None:
|
if self.deck is None:
|
||||||
self.onNew()
|
self.onNew()
|
||||||
ui.importing.ImportDialog(self)
|
ui.importing.ImportDialog(self)
|
||||||
|
@ -1415,9 +1382,20 @@ day = :d""", d=yesterday)
|
||||||
def onExport(self):
|
def onExport(self):
|
||||||
ui.exporting.ExportDialog(self)
|
ui.exporting.ExportDialog(self)
|
||||||
|
|
||||||
# Cramming
|
# Cramming & Sharing
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
|
def _copyToTmpDeck(self, name="cram.anki", tags=""):
|
||||||
|
ndir = tempfile.mkdtemp(prefix="anki")
|
||||||
|
path = os.path.join(ndir, name)
|
||||||
|
from anki.exporting import AnkiExporter
|
||||||
|
e = AnkiExporter(self.deck)
|
||||||
|
if tags:
|
||||||
|
e.limitTags = parseTags(tags)
|
||||||
|
path = unicode(path, sys.getfilesystemencoding())
|
||||||
|
e.exportInto(path)
|
||||||
|
return (e, path)
|
||||||
|
|
||||||
def onCram(self):
|
def onCram(self):
|
||||||
if self.deck.name() == "cram":
|
if self.deck.name() == "cram":
|
||||||
ui.utils.showInfo(
|
ui.utils.showInfo(
|
||||||
|
@ -1431,14 +1409,7 @@ day = :d""", d=yesterday)
|
||||||
return
|
return
|
||||||
s = unicode(s)
|
s = unicode(s)
|
||||||
# open tmp deck
|
# open tmp deck
|
||||||
ndir = tempfile.mkdtemp(prefix="anki")
|
(e, path) = self._copyToTmpDeck(tags=s)
|
||||||
path = os.path.join(ndir, "cram.anki")
|
|
||||||
from anki.exporting import AnkiExporter
|
|
||||||
e = AnkiExporter(self.deck)
|
|
||||||
if s:
|
|
||||||
e.limitTags = parseTags(s)
|
|
||||||
path = unicode(path, sys.getfilesystemencoding())
|
|
||||||
e.exportInto(path)
|
|
||||||
if not e.exportedCards:
|
if not e.exportedCards:
|
||||||
ui.utils.showInfo(_("No cards matched the provided tags."))
|
ui.utils.showInfo(_("No cards matched the provided tags."))
|
||||||
return
|
return
|
||||||
|
@ -1482,6 +1453,80 @@ day = :d""", d=yesterday)
|
||||||
self.reset()
|
self.reset()
|
||||||
p.finish()
|
p.finish()
|
||||||
|
|
||||||
|
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."))
|
||||||
|
return
|
||||||
|
self.deck.startProgress()
|
||||||
|
self.deck.updateProgress()
|
||||||
|
d = DeckStorage.Deck(path)
|
||||||
|
# reset scheduling to defaults
|
||||||
|
d.newCardsPerDay = 20
|
||||||
|
d.delay0 = 600
|
||||||
|
d.delay1 = 600
|
||||||
|
d.delay2 = 0
|
||||||
|
d.hardIntervalMin = 0.333
|
||||||
|
d.hardIntervalMax = 0.5
|
||||||
|
d.midIntervalMin = 3.0
|
||||||
|
d.midIntervalMax = 5.0
|
||||||
|
d.easyIntervalMin = 7.0
|
||||||
|
d.easyIntervalMax = 9.0
|
||||||
|
d.syncName = None
|
||||||
|
d.suspended = u"Suspended"
|
||||||
|
self.deck.updateProgress()
|
||||||
|
d.updateAllPriorities()
|
||||||
|
d.utcOffset = -1
|
||||||
|
d.flushMod()
|
||||||
|
d.save()
|
||||||
|
self.deck.updateProgress()
|
||||||
|
# remove indices
|
||||||
|
indices = d.s.column0(
|
||||||
|
"select name from sqlite_master where type = 'index' "
|
||||||
|
"and sql != ''")
|
||||||
|
for i in indices:
|
||||||
|
d.s.statement("drop index %s" % i)
|
||||||
|
# and q/a cache
|
||||||
|
d.s.statement("update cards set question = '', answer = ''")
|
||||||
|
self.deck.updateProgress()
|
||||||
|
d.s.statement("vacuum")
|
||||||
|
self.deck.updateProgress()
|
||||||
|
nfacts = d.factCount
|
||||||
|
mdir = d.mediaDir()
|
||||||
|
d.close()
|
||||||
|
dir = os.path.dirname(path)
|
||||||
|
zippath = os.path.join(dir, "shared-%d.zip" % time.time())
|
||||||
|
# zip it up
|
||||||
|
zip = zipfile.ZipFile(zippath, "w", zipfile.ZIP_DEFLATED)
|
||||||
|
zip.writestr("facts", str(nfacts))
|
||||||
|
readmep = os.path.join(dir, "README.html")
|
||||||
|
readme = open(readmep, "w")
|
||||||
|
readme.write('''\
|
||||||
|
<html><body>
|
||||||
|
This is an exported packaged deck created by Anki.<p>
|
||||||
|
|
||||||
|
To share this deck with other people, upload it to
|
||||||
|
<a href="http://anki.ichi2.net/file/upload">
|
||||||
|
http://anki.ichi2.net/file/upload</a>, or email
|
||||||
|
it to your friends.
|
||||||
|
</body></html>''')
|
||||||
|
readme.close()
|
||||||
|
zip.write(readmep, "README.txt")
|
||||||
|
zip.write(path, "shared.anki")
|
||||||
|
if mdir:
|
||||||
|
for f in os.listdir(mdir):
|
||||||
|
zip.write(os.path.join(mdir, f),
|
||||||
|
str(os.path.join("shared.media/", f)))
|
||||||
|
shutil.rmtree(mdir)
|
||||||
|
self.deck.updateProgress()
|
||||||
|
zip.close()
|
||||||
|
os.chdir(pwd)
|
||||||
|
os.unlink(path)
|
||||||
|
self.deck.finishProgress()
|
||||||
|
self.onOpenPluginFolder(dir)
|
||||||
|
|
||||||
# Reviewing and learning ahead
|
# Reviewing and learning ahead
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
|
@ -1498,6 +1543,7 @@ day = :d""", d=yesterday)
|
||||||
|
|
||||||
def setLang(self):
|
def setLang(self):
|
||||||
"Set the user interface language."
|
"Set the user interface language."
|
||||||
|
locale.setlocale(locale.LC_ALL, '')
|
||||||
languageDir=os.path.join(ankiqt.modDir, "locale")
|
languageDir=os.path.join(ankiqt.modDir, "locale")
|
||||||
self.languageTrans = gettext.translation('ankiqt', languageDir,
|
self.languageTrans = gettext.translation('ankiqt', languageDir,
|
||||||
languages=[self.config["interfaceLang"]],
|
languages=[self.config["interfaceLang"]],
|
||||||
|
@ -1698,10 +1744,12 @@ day = :d""", d=yesterday)
|
||||||
s = SIGNAL("triggered()")
|
s = SIGNAL("triggered()")
|
||||||
self.connect(m.actionNew, s, self.onNew)
|
self.connect(m.actionNew, s, self.onNew)
|
||||||
self.connect(m.actionOpenOnline, s, self.onOpenOnline)
|
self.connect(m.actionOpenOnline, s, self.onOpenOnline)
|
||||||
|
self.connect(m.actionDownloadSharedDeck, s, self.onGetSharedDeck)
|
||||||
|
self.connect(m.actionDownloadSharedPlugin, s, self.onGetSharedPlugin)
|
||||||
self.connect(m.actionOpen, s, self.onOpen)
|
self.connect(m.actionOpen, s, self.onOpen)
|
||||||
self.connect(m.actionOpenSamples, s, self.onOpenSamples)
|
|
||||||
self.connect(m.actionSave, s, self.onSave)
|
self.connect(m.actionSave, s, self.onSave)
|
||||||
self.connect(m.actionSaveAs, s, self.onSaveAs)
|
self.connect(m.actionSaveAs, s, self.onSaveAs)
|
||||||
|
self.connect(m.actionShare, s, self.onShare)
|
||||||
self.connect(m.actionClose, s, self.onClose)
|
self.connect(m.actionClose, s, self.onClose)
|
||||||
self.connect(m.actionExit, s, self, SLOT("close()"))
|
self.connect(m.actionExit, s, self, SLOT("close()"))
|
||||||
self.connect(m.actionSyncdeck, s, self.syncDeck)
|
self.connect(m.actionSyncdeck, s, self.syncDeck)
|
||||||
|
@ -1742,7 +1790,6 @@ day = :d""", d=yesterday)
|
||||||
self.connect(m.actionDisableAllPlugins, s, self.onDisableAllPlugins)
|
self.connect(m.actionDisableAllPlugins, s, self.onDisableAllPlugins)
|
||||||
self.connect(m.actionActiveTags, s, self.onActiveTags)
|
self.connect(m.actionActiveTags, s, self.onActiveTags)
|
||||||
self.connect(m.actionReleaseNotes, s, self.onReleaseNotes)
|
self.connect(m.actionReleaseNotes, s, self.onReleaseNotes)
|
||||||
self.connect(m.actionGetMoreDecks, s, self.onGetMoreDecks)
|
|
||||||
self.connect(m.actionCacheLatex, s, self.onCacheLatex)
|
self.connect(m.actionCacheLatex, s, self.onCacheLatex)
|
||||||
self.connect(m.actionUncacheLatex, s, self.onUncacheLatex)
|
self.connect(m.actionUncacheLatex, s, self.onUncacheLatex)
|
||||||
self.connect(m.actionStudyOptions, s, self.onStudyOptions)
|
self.connect(m.actionStudyOptions, s, self.onStudyOptions)
|
||||||
|
@ -1835,7 +1882,13 @@ day = :d""", d=yesterday)
|
||||||
self.mainWin.menu_Lookup.menuAction().setVisible(True)
|
self.mainWin.menu_Lookup.menuAction().setVisible(True)
|
||||||
else:
|
else:
|
||||||
self.mainWin.menu_Lookup.menuAction().setVisible(False)
|
self.mainWin.menu_Lookup.menuAction().setVisible(False)
|
||||||
|
enable = False
|
||||||
self.mainWin.menu_Lookup.setEnabled(enable)
|
self.mainWin.menu_Lookup.setEnabled(enable)
|
||||||
|
self.mainWin.actionLookup_es.setEnabled(enable)
|
||||||
|
self.mainWin.actionLookup_esk.setEnabled(enable)
|
||||||
|
self.mainWin.actionLookup_expr.setEnabled(enable)
|
||||||
|
self.mainWin.actionLookup_mean.setEnabled(enable)
|
||||||
|
self.mainWin.actionLookup_as.setEnabled(enable)
|
||||||
|
|
||||||
def maybeEnableUndo(self):
|
def maybeEnableUndo(self):
|
||||||
if self.deck and self.deck.undoAvailable():
|
if self.deck and self.deck.undoAvailable():
|
||||||
|
@ -1904,6 +1957,7 @@ day = :d""", d=yesterday)
|
||||||
sys.path.insert(0, plugdir)
|
sys.path.insert(0, plugdir)
|
||||||
plugins = self.enabledPlugins()
|
plugins = self.enabledPlugins()
|
||||||
plugins.sort()
|
plugins.sort()
|
||||||
|
self.registeredPlugins = {}
|
||||||
for plugin in plugins:
|
for plugin in plugins:
|
||||||
try:
|
try:
|
||||||
nopy = plugin.replace(".py", "")
|
nopy = plugin.replace(".py", "")
|
||||||
|
@ -1911,6 +1965,7 @@ day = :d""", d=yesterday)
|
||||||
except:
|
except:
|
||||||
print "Error in %s" % plugin
|
print "Error in %s" % plugin
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
self.checkForUpdatedPlugins()
|
||||||
|
|
||||||
def rebuildPluginsMenu(self):
|
def rebuildPluginsMenu(self):
|
||||||
if getattr(self, "pluginActions", None) is None:
|
if getattr(self, "pluginActions", None) is None:
|
||||||
|
@ -1922,6 +1977,8 @@ day = :d""", d=yesterday)
|
||||||
for fname in all:
|
for fname in all:
|
||||||
enabled = fname.endswith(".py")
|
enabled = fname.endswith(".py")
|
||||||
p = re.sub("\.py(\.off)?", "", fname)
|
p = re.sub("\.py(\.off)?", "", fname)
|
||||||
|
if p+".py" in self.registeredPlugins:
|
||||||
|
p = self.registeredPlugins[p+".py"]['name']
|
||||||
a = QAction(p, self)
|
a = QAction(p, self)
|
||||||
a.setCheckable(True)
|
a.setCheckable(True)
|
||||||
a.setChecked(enabled)
|
a.setChecked(enabled)
|
||||||
|
@ -1942,13 +1999,16 @@ day = :d""", d=yesterday)
|
||||||
return [p for p in os.listdir(self.pluginsFolder())
|
return [p for p in os.listdir(self.pluginsFolder())
|
||||||
if p.endswith(".py.off") or p.endswith(".py")]
|
if p.endswith(".py.off") or p.endswith(".py")]
|
||||||
|
|
||||||
def onOpenPluginFolder(self):
|
def onOpenPluginFolder(self, path=None):
|
||||||
|
if path is None:
|
||||||
|
path = self.pluginsFolder()
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
# reuse our process handling code from latex
|
# reuse our process handling code from latex
|
||||||
anki.latex.call(["explorer", self.pluginsFolder().encode(
|
anki.latex.call(["explorer", path.encode(
|
||||||
sys.getfilesystemencoding())])
|
sys.getfilesystemencoding())],
|
||||||
|
wait=False)
|
||||||
else:
|
else:
|
||||||
QDesktopServices.openUrl(QUrl("file://" + self.pluginsFolder()))
|
QDesktopServices.openUrl(QUrl("file://" + path))
|
||||||
|
|
||||||
def onGetPlugins(self):
|
def onGetPlugins(self):
|
||||||
QDesktopServices.openUrl(QUrl("http://ichi2.net/anki/wiki/Plugins"))
|
QDesktopServices.openUrl(QUrl("http://ichi2.net/anki/wiki/Plugins"))
|
||||||
|
@ -1980,6 +2040,14 @@ day = :d""", d=yesterday)
|
||||||
self.enablePlugin(plugin)
|
self.enablePlugin(plugin)
|
||||||
self.rebuildPluginsMenu()
|
self.rebuildPluginsMenu()
|
||||||
|
|
||||||
|
def registerPlugin(self, name, updateId):
|
||||||
|
src = os.path.basename(inspect.getfile(inspect.currentframe(1)))
|
||||||
|
self.registeredPlugins[src] = {'name': name,
|
||||||
|
'id': updateId}
|
||||||
|
|
||||||
|
def checkForUpdatedPlugins(self):
|
||||||
|
pass
|
||||||
|
|
||||||
# Font localisation
|
# Font localisation
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
|
@ -2011,9 +2079,9 @@ day = :d""", d=yesterday)
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
def setupProgressInfo(self):
|
def setupProgressInfo(self):
|
||||||
addHook("startProgress", self.onStartProgress)
|
addHook("startProgress", self.startProgress)
|
||||||
addHook("updateProgress", self.onUpdateProgress)
|
addHook("updateProgress", self.updateProgress)
|
||||||
addHook("finishProgress", self.onFinishProgress)
|
addHook("finishProgress", self.finishProgress)
|
||||||
addHook("dbProgress", self.onDbProgress)
|
addHook("dbProgress", self.onDbProgress)
|
||||||
addHook("dbFinished", self.onDbFinished)
|
addHook("dbFinished", self.onDbFinished)
|
||||||
self.progressParent = None
|
self.progressParent = None
|
||||||
|
@ -2024,7 +2092,7 @@ day = :d""", d=yesterday)
|
||||||
def setProgressParent(self, parent):
|
def setProgressParent(self, parent):
|
||||||
self.progressParent = parent
|
self.progressParent = parent
|
||||||
|
|
||||||
def onStartProgress(self, max=100, min=0, title=None):
|
def startProgress(self, max=0, min=0, title=None):
|
||||||
if self.mainThread != QThread.currentThread():
|
if self.mainThread != QThread.currentThread():
|
||||||
return
|
return
|
||||||
self.setBusy()
|
self.setBusy()
|
||||||
|
@ -2034,14 +2102,14 @@ day = :d""", d=yesterday)
|
||||||
p = ui.utils.ProgressWin(parent, max, min, title)
|
p = ui.utils.ProgressWin(parent, max, min, title)
|
||||||
self.progressWins.append(p)
|
self.progressWins.append(p)
|
||||||
|
|
||||||
def onUpdateProgress(self, label=None, value=None):
|
def updateProgress(self, label=None, value=None):
|
||||||
if self.mainThread != QThread.currentThread():
|
if self.mainThread != QThread.currentThread():
|
||||||
return
|
return
|
||||||
if self.progressWins:
|
if self.progressWins:
|
||||||
self.progressWins[-1].update(label, value)
|
self.progressWins[-1].update(label, value)
|
||||||
self.app.processEvents()
|
self.app.processEvents()
|
||||||
|
|
||||||
def onFinishProgress(self):
|
def finishProgress(self):
|
||||||
if self.mainThread != QThread.currentThread():
|
if self.mainThread != QThread.currentThread():
|
||||||
return
|
return
|
||||||
if self.progressWins:
|
if self.progressWins:
|
||||||
|
@ -2077,6 +2145,10 @@ day = :d""", d=yesterday)
|
||||||
|
|
||||||
def onCheckDB(self):
|
def onCheckDB(self):
|
||||||
"True if no problems"
|
"True if no problems"
|
||||||
|
if self.errorOccurred:
|
||||||
|
ui.utils.showWarning(_(
|
||||||
|
"Please restart Anki before checking the DB."))
|
||||||
|
return
|
||||||
if not ui.utils.askUser(_("""\
|
if not ui.utils.askUser(_("""\
|
||||||
This operation will find and fix some common problems.<br>
|
This operation will find and fix some common problems.<br>
|
||||||
<br>
|
<br>
|
||||||
|
@ -2098,7 +2170,7 @@ Proceed?""")):
|
||||||
|
|
||||||
def onOptimizeDB(self):
|
def onOptimizeDB(self):
|
||||||
size = self.deck.optimize()
|
size = self.deck.optimize()
|
||||||
ui.utils.showInfo("Database optimized.\nShrunk by %dKB" % (size/1024.0))
|
ui.utils.showInfo(_("Database optimized.\nShrunk by %dKB") % (size/1024.0))
|
||||||
|
|
||||||
def onCheckMediaDB(self):
|
def onCheckMediaDB(self):
|
||||||
mb = QMessageBox(self)
|
mb = QMessageBox(self)
|
||||||
|
|
|
@ -492,7 +492,7 @@ order by n""", id=card.id)
|
||||||
self.deck.setModified()
|
self.deck.setModified()
|
||||||
# if changed, reset deck
|
# if changed, reset deck
|
||||||
if self.origModTime != self.deck.modified:
|
if self.origModTime != self.deck.modified:
|
||||||
self.deck.updateCardTags()
|
self.deck.updateTagsForModel(self.m)
|
||||||
ankiqt.mw.reset()
|
ankiqt.mw.reset()
|
||||||
if self.onFinish:
|
if self.onFinish:
|
||||||
self.onFinish()
|
self.onFinish()
|
||||||
|
|
|
@ -28,8 +28,10 @@ class Preferences(QDialog):
|
||||||
self.supportedLanguages = [
|
self.supportedLanguages = [
|
||||||
(_("English"), "en_US"),
|
(_("English"), "en_US"),
|
||||||
(_("Brazillian Portuguese"), "pt_BR"),
|
(_("Brazillian Portuguese"), "pt_BR"),
|
||||||
(_("Chinese Traditional"), "zh_TW"),
|
(_("Chinese - Simplified"), "zh_CN"),
|
||||||
|
(_("Chinese - Traditional"), "zh_TW"),
|
||||||
(_("Czech"), "cs_CZ"),
|
(_("Czech"), "cs_CZ"),
|
||||||
|
(_("Estonian"), "ee_EE"),
|
||||||
(_("Finnish"), "fi_FI"),
|
(_("Finnish"), "fi_FI"),
|
||||||
(_("French"), "fr_FR"),
|
(_("French"), "fr_FR"),
|
||||||
(_("German"), "de_DE"),
|
(_("German"), "de_DE"),
|
||||||
|
@ -111,6 +113,7 @@ class Preferences(QDialog):
|
||||||
self.dialog.splitQA.setChecked(self.config['splitQA'])
|
self.dialog.splitQA.setChecked(self.config['splitQA'])
|
||||||
self.dialog.addZeroSpace.setChecked(self.config['addZeroSpace'])
|
self.dialog.addZeroSpace.setChecked(self.config['addZeroSpace'])
|
||||||
self.dialog.alternativeTheme.setChecked(self.config['alternativeTheme'])
|
self.dialog.alternativeTheme.setChecked(self.config['alternativeTheme'])
|
||||||
|
self.dialog.showProgress.setChecked(self.config['showProgress'])
|
||||||
|
|
||||||
def updateAdvanced(self):
|
def updateAdvanced(self):
|
||||||
self.config['showTrayIcon'] = self.dialog.showTray.isChecked()
|
self.config['showTrayIcon'] = self.dialog.showTray.isChecked()
|
||||||
|
@ -121,6 +124,7 @@ class Preferences(QDialog):
|
||||||
self.config['splitQA'] = self.dialog.splitQA.isChecked()
|
self.config['splitQA'] = self.dialog.splitQA.isChecked()
|
||||||
self.config['addZeroSpace'] = self.dialog.addZeroSpace.isChecked()
|
self.config['addZeroSpace'] = self.dialog.addZeroSpace.isChecked()
|
||||||
self.config['alternativeTheme'] = self.dialog.alternativeTheme.isChecked()
|
self.config['alternativeTheme'] = self.dialog.alternativeTheme.isChecked()
|
||||||
|
self.config['showProgress'] = self.dialog.showProgress.isChecked()
|
||||||
|
|
||||||
def codeToIndex(self, code):
|
def codeToIndex(self, code):
|
||||||
n = 0
|
n = 0
|
||||||
|
|
|
@ -74,7 +74,8 @@ class StatusView(object):
|
||||||
# remaining & eta
|
# remaining & eta
|
||||||
self.remText = QLabel()
|
self.remText = QLabel()
|
||||||
self.addWidget(self.remText, 0)
|
self.addWidget(self.remText, 0)
|
||||||
self.addWidget(self.vertSep(), 0)
|
sep1 = self.vertSep()
|
||||||
|
self.addWidget(sep1, 0)
|
||||||
self.etaText = QLabel()
|
self.etaText = QLabel()
|
||||||
self.etaText.setToolTip(_(
|
self.etaText.setToolTip(_(
|
||||||
"<h1>Estimated time</h1>"
|
"<h1>Estimated time</h1>"
|
||||||
|
@ -82,7 +83,8 @@ class StatusView(object):
|
||||||
"at your current pace."))
|
"at your current pace."))
|
||||||
self.addWidget(self.etaText, 0)
|
self.addWidget(self.etaText, 0)
|
||||||
# progress&retention
|
# progress&retention
|
||||||
self.addWidget(self.vertSep(), 0)
|
sep2 = self.vertSep()
|
||||||
|
self.addWidget(sep2, 0)
|
||||||
vbox = QVBoxLayout()
|
vbox = QVBoxLayout()
|
||||||
vbox.setSpacing(0)
|
vbox.setSpacing(0)
|
||||||
vbox.setMargin(0)
|
vbox.setMargin(0)
|
||||||
|
@ -105,13 +107,23 @@ class StatusView(object):
|
||||||
self.retentionBar.setStyle(self.plastiqueStyle)
|
self.retentionBar.setStyle(self.plastiqueStyle)
|
||||||
self.addWidget(self.combinedBar, 0)
|
self.addWidget(self.combinedBar, 0)
|
||||||
# timer
|
# timer
|
||||||
self.addWidget(self.vertSep(), 0)
|
sep3 = self.vertSep()
|
||||||
|
self.addWidget(sep3, 0)
|
||||||
self.timer = QClickableLabel()
|
self.timer = QClickableLabel()
|
||||||
self.timer.setText("00:00")
|
self.timer.setText("00:00")
|
||||||
self.addWidget(self.timer)
|
self.addWidget(self.timer)
|
||||||
self.redraw()
|
self.redraw()
|
||||||
if not self.main.config['showTimer']:
|
if not self.main.config['showTimer']:
|
||||||
self.timer.setShown(False)
|
self.timer.setShown(False)
|
||||||
|
if not self.main.config['showProgress']:
|
||||||
|
self.progressBar.hide()
|
||||||
|
self.retentionBar.hide()
|
||||||
|
self.timer.hide()
|
||||||
|
self.etaText.hide()
|
||||||
|
self.remText.hide()
|
||||||
|
sep1.hide()
|
||||||
|
sep2.hide()
|
||||||
|
sep3.hide()
|
||||||
|
|
||||||
def addWidget(self, w, stretch=0):
|
def addWidget(self, w, stretch=0):
|
||||||
self.statusbar.addWidget(w, stretch)
|
self.statusbar.addWidget(w, stretch)
|
||||||
|
@ -164,7 +176,7 @@ class StatusView(object):
|
||||||
"There are <b>%(rev)d</b> cards awaiting review.<br>"
|
"There are <b>%(rev)d</b> cards awaiting review.<br>"
|
||||||
"There are <b>%(new)d</b> new cards due today.<br><br>"
|
"There are <b>%(new)d</b> new cards due today.<br><br>"
|
||||||
"There are <b>%(new2)d</b> new cards in total.<br>"
|
"There are <b>%(new2)d</b> new cards in total.<br>"
|
||||||
"There are <b>%(spaced)d</b> spaced cards.") % stats)
|
"There are <b>%(spaced)d</b> delayed cards.") % stats)
|
||||||
# eta
|
# eta
|
||||||
self.etaText.setText(_("ETA: <b>%(timeLeft)s</b>") % stats)
|
self.etaText.setText(_("ETA: <b>%(timeLeft)s</b>") % stats)
|
||||||
# retention & progress bars
|
# retention & progress bars
|
||||||
|
@ -177,31 +189,27 @@ class StatusView(object):
|
||||||
self.progressBar.setPalette(p)
|
self.progressBar.setPalette(p)
|
||||||
self.progressBar.setValue(stats['dYesTotal%'])
|
self.progressBar.setValue(stats['dYesTotal%'])
|
||||||
# tooltips
|
# tooltips
|
||||||
stats['avgTime'] = anki.utils.fmtTimeSpan(stats['dAverageTime'], point=2)
|
tip = "<h1>" + _("Performance") + "</h1>"
|
||||||
stats['revTime'] = anki.utils.fmtTimeSpan(stats['dReviewTime'], point=2)
|
tip += _("""The top bar shows your performance today. The bottom bar shows your<br>
|
||||||
tip = _("""<h1>Performance</h1>
|
|
||||||
The top bar shows your performance today. The bottom bar shows your<br>
|
|
||||||
performance on cards scheduled for 21 days or more. The bottom bar should<br>
|
performance on cards scheduled for 21 days or more. The bottom bar should<br>
|
||||||
generally be between 80-95%% - lower and you're forgetting mature cards<br>
|
generally be between 80-95% - lower and you're forgetting mature cards<br>
|
||||||
too often, higher and you're spending too much time reviewing.
|
too often, higher and you're spending too much time reviewing.""")
|
||||||
<h2>Reviews today</h2>
|
tip += "<h2>" + _("Reviews today") + "</h2>"
|
||||||
<b>Correct today: %(dYesTotal%)0.1f%%
|
tip += "<b>" + _("Correct today: ") + anki.utils.fmtPercentage(stats['dYesTotal%'], point=1)
|
||||||
(%(dYesTotal)d of %(dTotal)d)</b><br>
|
tip += " (" + _("%(partOf)d of %(totalSum)d") % {'partOf' : stats['dYesTotal'], 'totalSum' : stats['dTotal'] } + ")</b><br>"
|
||||||
Average time per answer: %(avgTime)s<br>
|
tip += _("Average time per answer: ") + anki.utils.fmtTimeSpan(stats['dAverageTime'], point=2) +"<br>"
|
||||||
Total review time: %(revTime)s""") % stats
|
tip += _("Total review time: ") + anki.utils.fmtTimeSpan(stats['dReviewTime'], point=2)
|
||||||
stats['avgTime'] = anki.utils.fmtTimeSpan(stats['gAverageTime'], point=2)
|
tip += "<h2>" + _("All Reviews") + "</h2>"
|
||||||
stats['revTime'] = anki.utils.fmtTimeSpan(stats['gReviewTime'], point=2)
|
tip += "<b>" + _("Correct over a month: ") + anki.utils.fmtPercentage(stats['gMatureYes%'], point=1)
|
||||||
tip += _("""<h2>All Reviews</h2>
|
tip += " (" + _("%(partOf)d of %(totalSum)d") % {'partOf' : stats['gMatureYes'], 'totalSum' : stats['gMatureTotal'] } + ")</b><br>"
|
||||||
<b>Correct over a month: %(gMatureYes%)0.1f%%
|
tip += _("Average time per answer: ") + anki.utils.fmtTimeSpan(stats['gAverageTime'], point=2) +"<br>"
|
||||||
(%(gMatureYes)d of %(gMatureTotal)d)</b><br>
|
tip += _("Total review time: ") + anki.utils.fmtTimeSpan(stats['gReviewTime'], point=2) +"<br>"
|
||||||
Average time per answer: %(avgTime)s<br>
|
tip += _("Correct under a month: ") + anki.utils.fmtPercentage(stats['gYoungYes%'], point=1)
|
||||||
Total review time: %(revTime)s<br>
|
tip += " (" + _("%(partOf)d of %(totalSum)d") % {'partOf' : stats['gYoungYes'], 'totalSum' : stats['gYoungTotal'] } + ")</b><br>"
|
||||||
Correct under a month: %(gYoungYes%)0.1f%%
|
tip += _("Correct first time: ") + anki.utils.fmtPercentage(stats['gNewYes%'], point=1)
|
||||||
(%(gYoungYes)d of %(gYoungTotal)d)<br>
|
tip += " (" + _("%(partOf)d of %(totalSum)d") % {'partOf' : stats['gNewYes'], 'totalSum' : stats['gNewTotal'] } + ")</b><br>"
|
||||||
Correct first time: %(gNewYes%)0.1f%%
|
tip += _("Total correct: ") + anki.utils.fmtPercentage(stats['gYesTotal%'], point=1)
|
||||||
(%(gNewYes)d of %(gNewTotal)d)<br>
|
tip += " (" + _("%(partOf)d of %(totalSum)d") % {'partOf' : stats['gYesTotal'], 'totalSum' : stats['gTotal'] } + ")</b><br>"
|
||||||
Total correct: %(gYesTotal%)0.1f%%
|
|
||||||
(%(gYesTotal)d of %(gTotal)d)""") % stats
|
|
||||||
self.combinedBar.setToolTip(tip)
|
self.combinedBar.setToolTip(tip)
|
||||||
if self.main.config['showTimer']:
|
if self.main.config['showTimer']:
|
||||||
self.drawTimer()
|
self.drawTimer()
|
||||||
|
|
|
@ -52,7 +52,9 @@ class Sync(QThread):
|
||||||
else:
|
else:
|
||||||
msg=_("""\
|
msg=_("""\
|
||||||
Syncing failed. Please try again in a few minutes.
|
Syncing failed. Please try again in a few minutes.
|
||||||
If the problem persists, please report it on the forum.""")
|
If the problem persists, please report it on the forum.
|
||||||
|
|
||||||
|
Error: %s""" % `error`)
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
def connect(self, *args):
|
def connect(self, *args):
|
||||||
|
|
|
@ -56,7 +56,7 @@ class View(object):
|
||||||
self.haveTop = (self.main.lastCard and (
|
self.haveTop = (self.main.lastCard and (
|
||||||
self.main.config['showLastCardContent'] or
|
self.main.config['showLastCardContent'] or
|
||||||
self.main.config['showLastCardInterval'])) or (
|
self.main.config['showLastCardInterval'])) or (
|
||||||
self.main.currentCard and self.main.currentCard.due > time.time())
|
self.needFutureWarning())
|
||||||
self.drawRule = (self.main.config['qaDivider'] and
|
self.drawRule = (self.main.config['qaDivider'] and
|
||||||
self.main.currentCard and
|
self.main.currentCard and
|
||||||
not self.main.currentCard.cardModel.questionInAnswer)
|
not self.main.currentCard.cardModel.questionInAnswer)
|
||||||
|
@ -204,13 +204,18 @@ class View(object):
|
||||||
self.drawLastCard()
|
self.drawLastCard()
|
||||||
self.buffer += "</center>"
|
self.buffer += "</center>"
|
||||||
|
|
||||||
def drawFutureWarning(self):
|
def needFutureWarning(self):
|
||||||
if not self.main.currentCard:
|
if not self.main.currentCard:
|
||||||
return
|
return
|
||||||
if self.main.currentCard.due <= time.time():
|
if self.main.currentCard.due <= time.time():
|
||||||
return
|
return
|
||||||
if self.main.currentCard.due - time.time() <= self.main.deck.delay0:
|
if self.main.currentCard.due - time.time() <= self.main.deck.delay0:
|
||||||
return
|
return
|
||||||
|
return True
|
||||||
|
|
||||||
|
def drawFutureWarning(self):
|
||||||
|
if not self.needFutureWarning():
|
||||||
|
return
|
||||||
self.write("<span style='color: %s'>" % futureWarningColour +
|
self.write("<span style='color: %s'>" % futureWarningColour +
|
||||||
_("This card was due in %s.") % fmtTimeSpan(
|
_("This card was due in %s.") % fmtTimeSpan(
|
||||||
self.main.currentCard.due - time.time()) +
|
self.main.currentCard.due - time.time()) +
|
||||||
|
@ -247,8 +252,8 @@ class View(object):
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
def drawWelcomeMessage(self):
|
def drawWelcomeMessage(self):
|
||||||
self.main.mainWin.welcomeText.setText(_("""\
|
self.main.mainWin.welcomeText.setText("""\
|
||||||
<h1>Welcome to Anki!</h1>
|
<h1>%(welcome)s</h1>
|
||||||
<p>
|
<p>
|
||||||
<table>
|
<table>
|
||||||
|
|
||||||
|
@ -256,8 +261,8 @@ class View(object):
|
||||||
<td width=50>
|
<td width=50>
|
||||||
<a href="welcome:addfacts"><img src=":/icons/list-add.png"></a>
|
<a href="welcome:addfacts"><img src=":/icons/list-add.png"></a>
|
||||||
</td>
|
</td>
|
||||||
<td valign=middle><h1><a href="welcome:addfacts">Add material</a></h1>
|
<td valign=middle><h1><a href="welcome:addfacts">%(add)s</a></h1>
|
||||||
Start adding your own material.</td>
|
%(start)s</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
|
@ -269,31 +274,30 @@ Start adding your own material.</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="welcome:open"><img src=":/icons/document-open.png"></a>
|
<a href="welcome:open"><img src=":/icons/document-open.png"></a>
|
||||||
</td>
|
</td>
|
||||||
<td valign=middle><h2><a href="welcome:open">Open Local Deck</a></h2></td>
|
<td valign=middle><h2><a href="welcome:open">%(local)s</a></h2></td>
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<a href="welcome:openrem"><img src=":/icons/document-open-remote.png"></a>
|
|
||||||
</td>
|
|
||||||
<td valign=middle><h2><a href="welcome:openrem">Open Online Deck</a></h2></td>
|
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td width=50>
|
<td width=50>
|
||||||
<a href="welcome:sample"><img src=":/icons/anki.png"></a>
|
<a href="welcome:sample"><img src=":/icons/anki.png"></a>
|
||||||
</td>
|
</td>
|
||||||
<td valign=middle><h2><a href="welcome:sample">Open Sample Deck</a></h2></td>
|
<td valign=middle><h2><a href="welcome:sample">%(dl_shared)s</a></h2></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td width=50>
|
<td>
|
||||||
<a href="welcome:more"><img src=":/icons/khtml_kget.png"></a>
|
<a href="welcome:openrem"><img src=":/icons/document-open-remote.png"></a>
|
||||||
</td>
|
</td>
|
||||||
<td valign=middle><h2><a href="welcome:more">Get More Decks</a></h2></td>
|
<td valign=middle><h2><a href="welcome:openrem">%(dl_personal)s</a></h2></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
</table>"""))
|
</table>""" % \
|
||||||
|
{"welcome":_("Welcome to Anki!"),
|
||||||
|
"add":_("Add material"),
|
||||||
|
"start":_("Start adding your own material."),
|
||||||
|
"local":_("Open Local Deck"),
|
||||||
|
"dl_shared":_("Download Shared Deck"),
|
||||||
|
"dl_personal":_("Download Personal Deck")})
|
||||||
|
|
||||||
def drawDeckFinishedMessage(self):
|
def drawDeckFinishedMessage(self):
|
||||||
"Tell the user the deck is finished."
|
"Tell the user the deck is finished."
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>224</width>
|
<width>410</width>
|
||||||
<height>310</height>
|
<height>447</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy" >
|
<property name="sizePolicy" >
|
||||||
|
|
|
@ -13,6 +13,14 @@
|
||||||
<string>Edit Items</string>
|
<string>Edit Items</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="centralwidget" >
|
<widget class="QWidget" name="centralwidget" >
|
||||||
|
<property name="geometry" >
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>23</y>
|
||||||
|
<width>599</width>
|
||||||
|
<height>439</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout" >
|
<layout class="QVBoxLayout" name="verticalLayout" >
|
||||||
<property name="spacing" >
|
<property name="spacing" >
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
|
@ -162,7 +170,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>599</width>
|
<width>599</width>
|
||||||
<height>25</height>
|
<height>23</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QMenu" name="menuEdit" >
|
<widget class="QMenu" name="menuEdit" >
|
||||||
|
@ -226,7 +234,7 @@
|
||||||
<string>Delete</string>
|
<string>Delete</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="shortcut" >
|
<property name="shortcut" >
|
||||||
<string>Del</string>
|
<string>Ctrl+Del</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionAddTag" >
|
<action name="actionAddTag" >
|
||||||
|
|
|
@ -300,8 +300,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>960</width>
|
<width>348</width>
|
||||||
<height>480</height>
|
<height>317</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<attribute name="title" >
|
<attribute name="title" >
|
||||||
|
@ -556,6 +556,9 @@
|
||||||
<property name="text" >
|
<property name="text" >
|
||||||
<string>Close</string>
|
<string>Close</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="autoDefault" >
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
@ -613,6 +616,31 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<tabstops>
|
<tabstops>
|
||||||
|
<tabstop>tabWidget</tabstop>
|
||||||
|
<tabstop>cardList</tabstop>
|
||||||
|
<tabstop>questionFont</tabstop>
|
||||||
|
<tabstop>questionSize</tabstop>
|
||||||
|
<tabstop>questionColour</tabstop>
|
||||||
|
<tabstop>questionAlign</tabstop>
|
||||||
|
<tabstop>answerFont</tabstop>
|
||||||
|
<tabstop>answerSize</tabstop>
|
||||||
|
<tabstop>answerColour</tabstop>
|
||||||
|
<tabstop>answerAlign</tabstop>
|
||||||
|
<tabstop>backgroundColour</tabstop>
|
||||||
|
<tabstop>fieldList</tabstop>
|
||||||
|
<tabstop>useFamily</tabstop>
|
||||||
|
<tabstop>fontFamily</tabstop>
|
||||||
|
<tabstop>useSize</tabstop>
|
||||||
|
<tabstop>fontSize</tabstop>
|
||||||
|
<tabstop>useColour</tabstop>
|
||||||
|
<tabstop>fontColour</tabstop>
|
||||||
|
<tabstop>useFamilyEdit</tabstop>
|
||||||
|
<tabstop>fontFamilyEdit</tabstop>
|
||||||
|
<tabstop>useSizeEdit</tabstop>
|
||||||
|
<tabstop>fontSizeEdit</tabstop>
|
||||||
|
<tabstop>helpButton</tabstop>
|
||||||
|
<tabstop>preview</tabstop>
|
||||||
|
<tabstop>closeButton</tabstop>
|
||||||
<tabstop>question</tabstop>
|
<tabstop>question</tabstop>
|
||||||
<tabstop>answer</tabstop>
|
<tabstop>answer</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
|
|
|
@ -58,6 +58,19 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer" >
|
||||||
|
<property name="orientation" >
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0" >
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QDialogButtonBox" name="buttonBox" >
|
<widget class="QDialogButtonBox" name="buttonBox" >
|
||||||
<property name="orientation" >
|
<property name="orientation" >
|
||||||
|
|
|
@ -18,32 +18,22 @@
|
||||||
<item row="0" column="0" >
|
<item row="0" column="0" >
|
||||||
<widget class="QLabel" name="label" >
|
<widget class="QLabel" name="label" >
|
||||||
<property name="text" >
|
<property name="text" >
|
||||||
<string>Find</string>
|
<string><b>Find</b>:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1" >
|
<item row="0" column="1" >
|
||||||
<widget class="QLineEdit" name="find" />
|
<widget class="QLineEdit" name="find" />
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0" >
|
<item row="2" column="0" >
|
||||||
<widget class="QLabel" name="label_2" >
|
<widget class="QLabel" name="label_2" >
|
||||||
<property name="text" >
|
<property name="text" >
|
||||||
<string>Replace</string>
|
<string><b>Replace With</b>:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1" >
|
|
||||||
<widget class="QLineEdit" name="replace" />
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1" >
|
<item row="2" column="1" >
|
||||||
<widget class="QComboBox" name="type" />
|
<widget class="QLineEdit" name="replace" />
|
||||||
</item>
|
|
||||||
<item row="2" column="0" >
|
|
||||||
<widget class="QLabel" name="label_3" >
|
|
||||||
<property name="text" >
|
|
||||||
<string>Search</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1" >
|
<item row="3" column="1" >
|
||||||
<widget class="QCheckBox" name="re" >
|
<widget class="QCheckBox" name="re" >
|
||||||
|
@ -52,6 +42,16 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="0" >
|
||||||
|
<widget class="QLabel" name="label_3" >
|
||||||
|
<property name="text" >
|
||||||
|
<string><b>In</b>:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1" >
|
||||||
|
<widget class="QComboBox" name="field" />
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
@ -81,8 +81,8 @@
|
||||||
</widget>
|
</widget>
|
||||||
<tabstops>
|
<tabstops>
|
||||||
<tabstop>find</tabstop>
|
<tabstop>find</tabstop>
|
||||||
|
<tabstop>field</tabstop>
|
||||||
<tabstop>replace</tabstop>
|
<tabstop>replace</tabstop>
|
||||||
<tabstop>type</tabstop>
|
|
||||||
<tabstop>re</tabstop>
|
<tabstop>re</tabstop>
|
||||||
<tabstop>buttonBox</tabstop>
|
<tabstop>buttonBox</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
|
@ -95,8 +95,8 @@
|
||||||
<slot>accept()</slot>
|
<slot>accept()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel" >
|
<hint type="sourcelabel" >
|
||||||
<x>252</x>
|
<x>256</x>
|
||||||
<y>127</y>
|
<y>154</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel" >
|
<hint type="destinationlabel" >
|
||||||
<x>157</x>
|
<x>157</x>
|
||||||
|
@ -111,8 +111,8 @@
|
||||||
<slot>reject()</slot>
|
<slot>reject()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel" >
|
<hint type="sourcelabel" >
|
||||||
<x>286</x>
|
<x>290</x>
|
||||||
<y>127</y>
|
<y>154</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel" >
|
<hint type="destinationlabel" >
|
||||||
<x>286</x>
|
<x>286</x>
|
||||||
|
|
133
designer/getshared.ui
Normal file
133
designer/getshared.ui
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
<ui version="4.0" >
|
||||||
|
<class>Dialog</class>
|
||||||
|
<widget class="QDialog" name="Dialog" >
|
||||||
|
<property name="geometry" >
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>517</width>
|
||||||
|
<height>411</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout" >
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout" >
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="searchLabel" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Search:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="search" />
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSplitter" name="splitter" >
|
||||||
|
<property name="orientation" >
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<widget class="QTableWidget" name="table" />
|
||||||
|
<widget class="QScrollArea" name="scrollArea" >
|
||||||
|
<property name="frameShape" >
|
||||||
|
<enum>QFrame::StyledPanel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow" >
|
||||||
|
<enum>QFrame::Plain</enum>
|
||||||
|
</property>
|
||||||
|
<property name="verticalScrollBarPolicy" >
|
||||||
|
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||||
|
</property>
|
||||||
|
<property name="horizontalScrollBarPolicy" >
|
||||||
|
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="scrollAreaWidgetContents" >
|
||||||
|
<property name="geometry" >
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>494</width>
|
||||||
|
<height>54</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy" >
|
||||||
|
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2" >
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="bottomLabel" >
|
||||||
|
<property name="maximumSize" >
|
||||||
|
<size>
|
||||||
|
<width>430</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text" >
|
||||||
|
<string>Loading...</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap" >
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags" >
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox" >
|
||||||
|
<property name="orientation" >
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons" >
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>Dialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel" >
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel" >
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>Dialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel" >
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel" >
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
131
designer/main.ui
131
designer/main.ui
|
@ -6,7 +6,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>723</width>
|
<width>723</width>
|
||||||
<height>504</height>
|
<height>513</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy" >
|
<property name="sizePolicy" >
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>69</y>
|
<y>69</y>
|
||||||
<width>723</width>
|
<width>723</width>
|
||||||
<height>415</height>
|
<height>424</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy" >
|
<property name="sizePolicy" >
|
||||||
|
@ -145,8 +145,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>422</width>
|
<width>100</width>
|
||||||
<height>57</height>
|
<height>30</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout" >
|
<layout class="QVBoxLayout" name="verticalLayout" >
|
||||||
|
@ -224,8 +224,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>422</width>
|
<width>100</width>
|
||||||
<height>57</height>
|
<height>30</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3" >
|
<layout class="QVBoxLayout" name="verticalLayout_3" >
|
||||||
|
@ -371,8 +371,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>422</width>
|
<width>100</width>
|
||||||
<height>57</height>
|
<height>30</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -397,7 +397,7 @@
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex" >
|
<property name="currentIndex" >
|
||||||
<number>0</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="blankPage" >
|
<widget class="QWidget" name="blankPage" >
|
||||||
<property name="geometry" >
|
<property name="geometry" >
|
||||||
|
@ -405,7 +405,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>446</width>
|
<width>446</width>
|
||||||
<height>358</height>
|
<height>367</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -415,7 +415,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>446</width>
|
<width>446</width>
|
||||||
<height>358</height>
|
<height>367</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_5" >
|
<layout class="QVBoxLayout" name="verticalLayout_5" >
|
||||||
|
@ -440,7 +440,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>446</width>
|
<width>446</width>
|
||||||
<height>358</height>
|
<height>367</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2" >
|
<layout class="QVBoxLayout" name="verticalLayout_2" >
|
||||||
|
@ -478,7 +478,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>446</width>
|
<width>446</width>
|
||||||
<height>358</height>
|
<height>367</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_4" >
|
<layout class="QVBoxLayout" name="verticalLayout_4" >
|
||||||
|
@ -530,7 +530,7 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="optionsLabel" >
|
<widget class="QLabel" name="optionsLabel" >
|
||||||
<property name="text" >
|
<property name="text" >
|
||||||
<string>xxx</string>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="textInteractionFlags" >
|
<property name="textInteractionFlags" >
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
@ -736,6 +736,12 @@
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="minimumSize" >
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>26</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="text" >
|
<property name="text" >
|
||||||
<string>Review</string>
|
<string>Review</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -743,10 +749,22 @@
|
||||||
<iconset resource="../icons.qrc" >
|
<iconset resource="../icons.qrc" >
|
||||||
<normaloff>:/icons/player-time.png</normaloff>:/icons/player-time.png</iconset>
|
<normaloff>:/icons/player-time.png</normaloff>:/icons/player-time.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="autoDefault" >
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="default" >
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1" >
|
<item row="0" column="1" >
|
||||||
<widget class="QPushButton" name="optionsButton" >
|
<widget class="QPushButton" name="optionsButton" >
|
||||||
|
<property name="minimumSize" >
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>26</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="text" >
|
<property name="text" >
|
||||||
<string>More>></string>
|
<string>More>></string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -763,6 +781,12 @@
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="2" >
|
<item row="0" column="2" >
|
||||||
<widget class="QPushButton" name="optionsHelpButton" >
|
<widget class="QPushButton" name="optionsHelpButton" >
|
||||||
|
<property name="minimumSize" >
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>26</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="text" >
|
<property name="text" >
|
||||||
<string>Help</string>
|
<string>Help</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -813,7 +837,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>446</width>
|
<width>446</width>
|
||||||
<height>358</height>
|
<height>367</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_8" >
|
<layout class="QVBoxLayout" name="verticalLayout_8" >
|
||||||
|
@ -878,7 +902,7 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="congratsLabel" >
|
<widget class="QLabel" name="congratsLabel" >
|
||||||
<property name="text" >
|
<property name="text" >
|
||||||
<string>xxx</string>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="margin" >
|
<property name="margin" >
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
|
@ -1174,7 +1198,6 @@
|
||||||
<addaction name="actionReportbug" />
|
<addaction name="actionReportbug" />
|
||||||
<addaction name="actionForum" />
|
<addaction name="actionForum" />
|
||||||
<addaction name="actionReleaseNotes" />
|
<addaction name="actionReleaseNotes" />
|
||||||
<addaction name="actionGetMoreDecks" />
|
|
||||||
<addaction name="separator" />
|
<addaction name="separator" />
|
||||||
<addaction name="actionDonate" />
|
<addaction name="actionDonate" />
|
||||||
<addaction name="actionAbout" />
|
<addaction name="actionAbout" />
|
||||||
|
@ -1208,10 +1231,23 @@
|
||||||
<normaloff>:/icons/document-open-recent.png</normaloff>:/icons/document-open-recent.png</iconset>
|
<normaloff>:/icons/document-open-recent.png</normaloff>:/icons/document-open-recent.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QMenu" name="menuDownload" >
|
||||||
|
<property name="title" >
|
||||||
|
<string>&Download...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon" >
|
||||||
|
<iconset resource="../icons.qrc" >
|
||||||
|
<normaloff>:/icons/document-open-remote.png</normaloff>:/icons/document-open-remote.png</iconset>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionOpenOnline" />
|
||||||
|
<addaction name="separator" />
|
||||||
|
<addaction name="actionDownloadSharedDeck" />
|
||||||
|
<addaction name="actionDownloadSharedPlugin" />
|
||||||
|
</widget>
|
||||||
<addaction name="actionNew" />
|
<addaction name="actionNew" />
|
||||||
<addaction name="actionOpen" />
|
<addaction name="actionOpen" />
|
||||||
<addaction name="menuOpenRecent" />
|
<addaction name="menuOpenRecent" />
|
||||||
<addaction name="actionOpenOnline" />
|
<addaction name="menuDownload" />
|
||||||
<addaction name="actionImport" />
|
<addaction name="actionImport" />
|
||||||
<addaction name="separator" />
|
<addaction name="separator" />
|
||||||
<addaction name="actionSave" />
|
<addaction name="actionSave" />
|
||||||
|
@ -1288,7 +1324,6 @@
|
||||||
<addaction name="actionDisableAllPlugins" />
|
<addaction name="actionDisableAllPlugins" />
|
||||||
<addaction name="separator" />
|
<addaction name="separator" />
|
||||||
</widget>
|
</widget>
|
||||||
<addaction name="actionGetPlugins" />
|
|
||||||
<addaction name="actionOpenPluginFolder" />
|
<addaction name="actionOpenPluginFolder" />
|
||||||
<addaction name="separator" />
|
<addaction name="separator" />
|
||||||
<addaction name="menuStartup" />
|
<addaction name="menuStartup" />
|
||||||
|
@ -1313,7 +1348,7 @@
|
||||||
<property name="geometry" >
|
<property name="geometry" >
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>484</y>
|
<y>493</y>
|
||||||
<width>723</width>
|
<width>723</width>
|
||||||
<height>20</height>
|
<height>20</height>
|
||||||
</rect>
|
</rect>
|
||||||
|
@ -1427,6 +1462,9 @@
|
||||||
<property name="shortcut" >
|
<property name="shortcut" >
|
||||||
<string>Ctrl+S</string>
|
<string>Ctrl+S</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="shortcutContext" >
|
||||||
|
<enum>Qt::ApplicationShortcut</enum>
|
||||||
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionSyncdeck" >
|
<action name="actionSyncdeck" >
|
||||||
<property name="icon" >
|
<property name="icon" >
|
||||||
|
@ -1762,15 +1800,6 @@
|
||||||
<string>Check Media Database...</string>
|
<string>Check Media Database...</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionOpenOnline" >
|
|
||||||
<property name="icon" >
|
|
||||||
<iconset resource="../icons.qrc" >
|
|
||||||
<normaloff>:/icons/document-open-remote.png</normaloff>:/icons/document-open-remote.png</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="text" >
|
|
||||||
<string>Open On&line...</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionCram" >
|
<action name="actionCram" >
|
||||||
<property name="icon" >
|
<property name="icon" >
|
||||||
<iconset resource="../icons.qrc" >
|
<iconset resource="../icons.qrc" >
|
||||||
|
@ -1823,15 +1852,6 @@
|
||||||
<string>Active &Tags...</string>
|
<string>Active &Tags...</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionGetMoreDecks" >
|
|
||||||
<property name="icon" >
|
|
||||||
<iconset resource="../icons.qrc" >
|
|
||||||
<normaloff>:/icons/download.png</normaloff>:/icons/download.png</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="text" >
|
|
||||||
<string>&Get More Decks...</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionEditCurrent" >
|
<action name="actionEditCurrent" >
|
||||||
<property name="icon" >
|
<property name="icon" >
|
||||||
<iconset resource="../icons.qrc" >
|
<iconset resource="../icons.qrc" >
|
||||||
|
@ -1861,6 +1881,9 @@
|
||||||
<property name="text" >
|
<property name="text" >
|
||||||
<string>&Delete Card</string>
|
<string>&Delete Card</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="shortcut" >
|
||||||
|
<string>Ctrl+Del</string>
|
||||||
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="action_Delete_Fact" >
|
<action name="action_Delete_Fact" >
|
||||||
<property name="text" >
|
<property name="text" >
|
||||||
|
@ -1904,6 +1927,34 @@
|
||||||
<string>&Record Noise Profile...</string>
|
<string>&Record Noise Profile...</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionGetShared" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Get Shared...</string>
|
||||||
|
</property>
|
||||||
|
<property name="statusTip" >
|
||||||
|
<string>Open a pre-made deck or plugin</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionShare" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Share...</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionOpenOnline" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Personal Deck</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionDownloadSharedDeck" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Shared Deck</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionDownloadSharedPlugin" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Shared Plugin</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<tabstops>
|
<tabstops>
|
||||||
<tabstop>newPerDay</tabstop>
|
<tabstop>newPerDay</tabstop>
|
||||||
|
@ -1921,11 +1972,11 @@
|
||||||
<tabstop>help</tabstop>
|
<tabstop>help</tabstop>
|
||||||
<tabstop>welcomeText</tabstop>
|
<tabstop>welcomeText</tabstop>
|
||||||
<tabstop>showAnswerButton</tabstop>
|
<tabstop>showAnswerButton</tabstop>
|
||||||
<tabstop>saveEditorButton</tabstop>
|
|
||||||
<tabstop>easeButton2</tabstop>
|
|
||||||
<tabstop>easeButton1</tabstop>
|
<tabstop>easeButton1</tabstop>
|
||||||
|
<tabstop>easeButton2</tabstop>
|
||||||
<tabstop>easeButton3</tabstop>
|
<tabstop>easeButton3</tabstop>
|
||||||
<tabstop>easeButton4</tabstop>
|
<tabstop>easeButton4</tabstop>
|
||||||
|
<tabstop>saveEditorButton</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../icons.qrc" />
|
<include location="../icons.qrc" />
|
||||||
|
|
|
@ -97,6 +97,13 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="showProgress" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Show information in status bar</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer" >
|
<spacer name="verticalSpacer" >
|
||||||
<property name="orientation" >
|
<property name="orientation" >
|
||||||
|
@ -110,6 +117,16 @@
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_3" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Some settings will take effect after you restart Anki.</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment" >
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="tab_2" >
|
<widget class="QWidget" name="tab_2" >
|
||||||
|
@ -318,7 +335,7 @@
|
||||||
<item row="2" column="0" >
|
<item row="2" column="0" >
|
||||||
<widget class="QLabel" name="label_6" >
|
<widget class="QLabel" name="label_6" >
|
||||||
<property name="text" >
|
<property name="text" >
|
||||||
<string><h1>Advanced settings</h1>Some settings require a restart.</string>
|
<string><h1>Advanced settings</h1></string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -388,6 +405,16 @@
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_8" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Some settings will take effect after you restart Anki.</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment" >
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -411,6 +438,7 @@
|
||||||
<tabstop>showDivider</tabstop>
|
<tabstop>showDivider</tabstop>
|
||||||
<tabstop>splitQA</tabstop>
|
<tabstop>splitQA</tabstop>
|
||||||
<tabstop>showEstimates</tabstop>
|
<tabstop>showEstimates</tabstop>
|
||||||
|
<tabstop>showProgress</tabstop>
|
||||||
<tabstop>saveWhenClosing</tabstop>
|
<tabstop>saveWhenClosing</tabstop>
|
||||||
<tabstop>saveAfterEvery</tabstop>
|
<tabstop>saveAfterEvery</tabstop>
|
||||||
<tabstop>saveAfterEveryNum</tabstop>
|
<tabstop>saveAfterEveryNum</tabstop>
|
||||||
|
@ -422,7 +450,9 @@
|
||||||
<tabstop>syncOnClose</tabstop>
|
<tabstop>syncOnClose</tabstop>
|
||||||
<tabstop>alternativeTheme</tabstop>
|
<tabstop>alternativeTheme</tabstop>
|
||||||
<tabstop>showTimer</tabstop>
|
<tabstop>showTimer</tabstop>
|
||||||
|
<tabstop>showTray</tabstop>
|
||||||
<tabstop>showStudyOptions</tabstop>
|
<tabstop>showStudyOptions</tabstop>
|
||||||
|
<tabstop>addZeroSpace</tabstop>
|
||||||
<tabstop>buttonBox</tabstop>
|
<tabstop>buttonBox</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources/>
|
<resources/>
|
||||||
|
|
134
designer/share.ui
Normal file
134
designer/share.ui
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
<ui version="4.0" >
|
||||||
|
<class>Dialog</class>
|
||||||
|
<widget class="QDialog" name="Dialog" >
|
||||||
|
<property name="geometry" >
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>517</width>
|
||||||
|
<height>411</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle" >
|
||||||
|
<string>Get Shared Decks/Plugins</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout" >
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout" >
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="searchLabel" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Search:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="search" />
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Type:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="type" />
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSplitter" name="splitter" >
|
||||||
|
<property name="orientation" >
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<widget class="QTableWidget" name="table" />
|
||||||
|
<widget class="QScrollArea" name="scrollArea" >
|
||||||
|
<property name="frameShape" >
|
||||||
|
<enum>QFrame::StyledPanel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow" >
|
||||||
|
<enum>QFrame::Plain</enum>
|
||||||
|
</property>
|
||||||
|
<property name="verticalScrollBarPolicy" >
|
||||||
|
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||||
|
</property>
|
||||||
|
<property name="horizontalScrollBarPolicy" >
|
||||||
|
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="scrollAreaWidgetContents" >
|
||||||
|
<property name="geometry" >
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>494</width>
|
||||||
|
<height>54</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy" >
|
||||||
|
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2" >
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="bottomLabel" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox" >
|
||||||
|
<property name="orientation" >
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons" >
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>Dialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel" >
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel" >
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>Dialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel" >
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel" >
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
|
@ -1,5 +1,6 @@
|
||||||
<RCC>
|
<RCC>
|
||||||
<qresource prefix="/" >
|
<qresource prefix="/" >
|
||||||
|
<file>icons/anki-logo-thin.png</file>
|
||||||
<file>icons/anki-logo.png</file>
|
<file>icons/anki-logo.png</file>
|
||||||
<file>icons/download.png</file>
|
<file>icons/download.png</file>
|
||||||
<file>icons/preferences-plugin.png</file>
|
<file>icons/preferences-plugin.png</file>
|
||||||
|
|
BIN
icons/anki-logo-thin.png
Normal file
BIN
icons/anki-logo-thin.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.1 KiB |
Binary file not shown.
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 6.6 KiB |
|
@ -45,7 +45,6 @@ DATA_FILES = [
|
||||||
'ankiqt/ankiqt/locale',
|
'ankiqt/ankiqt/locale',
|
||||||
'kakasi',
|
'kakasi',
|
||||||
#'audio',
|
#'audio',
|
||||||
'libanki/samples',
|
|
||||||
'ankiqt/imageformats',
|
'ankiqt/imageformats',
|
||||||
'libanki/anki/features/chinese/unihan.db',
|
'libanki/anki/features/chinese/unihan.db',
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in a new issue