mirror of
https://github.com/ankitects/anki.git
synced 2025-11-12 15:47:12 -05:00
Merge branch 'master' of git://ichi2.net/ankiqt
This commit is contained in:
commit
9de5ceaeff
12 changed files with 124 additions and 62 deletions
|
|
@ -6,7 +6,7 @@ from PyQt4.QtCore import *
|
||||||
from PyQt4.QtGui import *
|
from PyQt4.QtGui import *
|
||||||
|
|
||||||
appName="Anki"
|
appName="Anki"
|
||||||
appVersion="0.9.9.7.5"
|
appVersion="0.9.9.7.6b"
|
||||||
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"
|
||||||
|
|
@ -175,5 +175,8 @@ def run():
|
||||||
|
|
||||||
app.exec_()
|
app.exec_()
|
||||||
|
|
||||||
|
# ensure we kill any other threads
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
run()
|
run()
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ def importAll():
|
||||||
import addcards
|
import addcards
|
||||||
import cardlist
|
import cardlist
|
||||||
import deckproperties
|
import deckproperties
|
||||||
|
import importing
|
||||||
import displayproperties
|
import displayproperties
|
||||||
import exporting
|
import exporting
|
||||||
import facteditor
|
import facteditor
|
||||||
|
|
|
||||||
|
|
@ -453,7 +453,7 @@ class EditDeck(QMainWindow):
|
||||||
elif idx == 1:
|
elif idx == 1:
|
||||||
self.dialog.filterEdit.setText("tag:none")
|
self.dialog.filterEdit.setText("tag:none")
|
||||||
else:
|
else:
|
||||||
self.dialog.filterEdit.setText("tag:" + self.alltags[idx-2].lower())
|
self.dialog.filterEdit.setText("tag:" + self.alltags[idx-2])
|
||||||
self.showFilterNow()
|
self.showFilterNow()
|
||||||
self.dialog.tagList.setCurrentIndex(0)
|
self.dialog.tagList.setCurrentIndex(0)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -995,6 +995,11 @@ class FactEdit(QTextEdit):
|
||||||
|
|
||||||
# this shouldn't be necessary if/when we move away from kakasi
|
# this shouldn't be necessary if/when we move away from kakasi
|
||||||
def mouseDoubleClickEvent(self, evt):
|
def mouseDoubleClickEvent(self, evt):
|
||||||
|
t = self.parent.fact.model.tags.lower()
|
||||||
|
if (not "japanese" in t and
|
||||||
|
not "mandarin" in t and
|
||||||
|
not "cantonese" in t):
|
||||||
|
return QTextEdit.mouseDoubleClickEvent(self,evt)
|
||||||
r = QRegExp("\\{(.*[|,].*)\\}")
|
r = QRegExp("\\{(.*[|,].*)\\}")
|
||||||
r.setMinimal(True)
|
r.setMinimal(True)
|
||||||
|
|
||||||
|
|
@ -1025,8 +1030,7 @@ class FactEdit(QTextEdit):
|
||||||
result = r.indexIn(self.toPlainText(), blockoffset)
|
result = r.indexIn(self.toPlainText(), blockoffset)
|
||||||
|
|
||||||
if found == "":
|
if found == "":
|
||||||
QTextEdit.mouseDoubleClickEvent(self,evt)
|
return QTextEdit.mouseDoubleClickEvent(self,evt)
|
||||||
return
|
|
||||||
self.setPlainText(self.toPlainText().replace(result, r.matchedLength(), found))
|
self.setPlainText(self.toPlainText().replace(result, r.matchedLength(), found))
|
||||||
|
|
||||||
def focusInEvent(self, evt):
|
def focusInEvent(self, evt):
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ class GetShared(QDialog):
|
||||||
return
|
return
|
||||||
self.parent.finishProgress()
|
self.parent.finishProgress()
|
||||||
self.parent.setProgressParent(None)
|
self.parent.setProgressParent(None)
|
||||||
|
self.form.search.setFocus()
|
||||||
if err:
|
if err:
|
||||||
showInfo(_("Unable to connect to server."), parent=self)
|
showInfo(_("Unable to connect to server."), parent=self)
|
||||||
self.close()
|
self.close()
|
||||||
|
|
@ -108,6 +109,7 @@ class GetShared(QDialog):
|
||||||
else:
|
else:
|
||||||
self.form.table.sortItems(1, Qt.DescendingOrder)
|
self.form.table.sortItems(1, Qt.DescendingOrder)
|
||||||
self.form.table.selectRow(0)
|
self.form.table.selectRow(0)
|
||||||
|
self.onCellChanged(None, None, None, None)
|
||||||
|
|
||||||
def onCellChanged(self, row, col, x, y):
|
def onCellChanged(self, row, col, x, y):
|
||||||
ci = self.form.table.currentItem()
|
ci = self.form.table.currentItem()
|
||||||
|
|
|
||||||
|
|
@ -126,28 +126,41 @@ class AnkiQt(QMainWindow):
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.timer = None
|
self.timer = None
|
||||||
self.pool = ""
|
self.pool = ""
|
||||||
|
self.poolUpdated = 0
|
||||||
|
|
||||||
def write(self, data):
|
def write(self, data):
|
||||||
print data.encode("utf-8"),
|
print data.encode("utf-8"),
|
||||||
self.pool += data
|
self.pool += data
|
||||||
self.updateTimer()
|
self.poolUpdated = time.time()
|
||||||
|
|
||||||
def updateTimer(self):
|
def haveError(self):
|
||||||
interval = 200
|
if self.pool:
|
||||||
if not self.timer:
|
if (time.time() - self.poolUpdated) > 1:
|
||||||
self.timer = QTimer(self.parent)
|
return True
|
||||||
self.timer.setSingleShot(True)
|
|
||||||
self.timer.start(interval)
|
|
||||||
self.parent.connect(self.timer,
|
|
||||||
SIGNAL("timeout()"),
|
|
||||||
self.onTimeout)
|
|
||||||
else:
|
|
||||||
self.timer.setInterval(interval)
|
|
||||||
|
|
||||||
def onTimeout(self):
|
def getError(self):
|
||||||
if "font_manager.py" in self.pool:
|
p = self.pool
|
||||||
# hack for matplotlib errors on osx
|
|
||||||
self.pool = ""
|
self.pool = ""
|
||||||
|
return p
|
||||||
|
|
||||||
|
self.errorPipe = ErrorPipe(self)
|
||||||
|
sys.stderr = self.errorPipe
|
||||||
|
self.errorTimer = QTimer(self)
|
||||||
|
self.errorTimer.start(1000)
|
||||||
|
self.connect(self.errorTimer,
|
||||||
|
SIGNAL("timeout()"),
|
||||||
|
self.onErrorTimer)
|
||||||
|
|
||||||
|
def onErrorTimer(self):
|
||||||
|
if self.errorPipe.haveError():
|
||||||
|
error = self.errorPipe.getError()
|
||||||
|
if "font_manager.py" in error:
|
||||||
|
# hack for matplotlib errors on osx
|
||||||
|
return
|
||||||
|
if "Audio player not found" in error:
|
||||||
|
ui.utils.showInfo(
|
||||||
|
_("Couldn't play sound. Please install mplayer."))
|
||||||
|
return
|
||||||
stdText = _("""\
|
stdText = _("""\
|
||||||
An error occurred. Please:<p>
|
An error occurred. Please:<p>
|
||||||
<ol>
|
<ol>
|
||||||
|
|
@ -160,18 +173,13 @@ into a bug report:<br><br>
|
||||||
pluginText = _("""\
|
pluginText = _("""\
|
||||||
An error occurred in a plugin. Please contact the plugin author.<br>
|
An error occurred in a plugin. Please contact the plugin author.<br>
|
||||||
Please do not file a bug report with Anki.<br><br>""")
|
Please do not file a bug report with Anki.<br><br>""")
|
||||||
if "plugin" in self.pool:
|
if "plugin" in error:
|
||||||
txt = pluginText
|
txt = pluginText
|
||||||
else:
|
else:
|
||||||
txt = stdText
|
txt = stdText
|
||||||
if self.pool:
|
self.errorOccurred = True
|
||||||
self.parent.errorOccurred = True
|
ui.utils.showText(txt + error[0:10000].replace(
|
||||||
ui.utils.showText(txt + self.pool[0:10000].replace(
|
|
||||||
"\n", "<br>"))
|
"\n", "<br>"))
|
||||||
self.pool = ""
|
|
||||||
self.timer = None
|
|
||||||
pipe = ErrorPipe(self)
|
|
||||||
sys.stderr = pipe
|
|
||||||
|
|
||||||
def closeAllDeckWindows(self):
|
def closeAllDeckWindows(self):
|
||||||
ui.dialogs.closeAll()
|
ui.dialogs.closeAll()
|
||||||
|
|
@ -687,7 +695,7 @@ To upgrade an old deck, download Anki 0.9.8.7."""))
|
||||||
def onClose(self):
|
def onClose(self):
|
||||||
if self.inMainWindow():
|
if self.inMainWindow():
|
||||||
self.saveAndClose(hideWelcome=self.isCramming())
|
self.saveAndClose(hideWelcome=self.isCramming())
|
||||||
if cramming:
|
if self.isCramming():
|
||||||
self.loadRecent(0)
|
self.loadRecent(0)
|
||||||
else:
|
else:
|
||||||
self.app.activeWindow().close()
|
self.app.activeWindow().close()
|
||||||
|
|
@ -1104,6 +1112,33 @@ day = :d""", d=yesterday)
|
||||||
<p><table><tr>
|
<p><table><tr>
|
||||||
%s
|
%s
|
||||||
<td>%s</td></tr></table>""" % (stats1, stats2))
|
<td>%s</td></tr></table>""" % (stats1, stats2))
|
||||||
|
self.mainWin.optionsLabel.setToolTip(_("""\
|
||||||
|
<h1>Session Statistics</h1>
|
||||||
|
<dl>
|
||||||
|
<dt><b>Cards/session</b></dt>
|
||||||
|
<dd>The number of cards you studied in the current session (blue) and previous
|
||||||
|
session (black)</dd>
|
||||||
|
</dl>
|
||||||
|
<dl>
|
||||||
|
<dt><b>Cards/day</b></dt>
|
||||||
|
<dd>The number of cards you studied today (blue) and yesterday (black)</dd>
|
||||||
|
</dl>
|
||||||
|
<dl>
|
||||||
|
<dt><b>Time/day</b></dt>
|
||||||
|
<dd>The number of minutes you studied today (blue) and yesterday (black)</dd>
|
||||||
|
</dl>
|
||||||
|
<dl>
|
||||||
|
<dt><b>Reviews due</b></dt>
|
||||||
|
<dd>The number of cards that are waiting to be reviewed today</dd>
|
||||||
|
</dl>
|
||||||
|
<dl>
|
||||||
|
<dt><b>New today</b></dt>
|
||||||
|
<dd>The number of new cards that are waiting to be learnt today</dd>
|
||||||
|
</dl>
|
||||||
|
<dl>
|
||||||
|
<dt><b>New total</b></dt>
|
||||||
|
<dd>The total number of new cards in the deck</dd>
|
||||||
|
</dl>"""))
|
||||||
|
|
||||||
def showStudyScreen(self):
|
def showStudyScreen(self):
|
||||||
self.mainWin.optionsButton.setChecked(self.config['showStudyOptions'])
|
self.mainWin.optionsButton.setChecked(self.config['showStudyOptions'])
|
||||||
|
|
|
||||||
|
|
@ -289,8 +289,8 @@ class ModelProperties(QDialog):
|
||||||
self.currentCard = self.m.cardModels[self.dialog.cardList.currentRow()]
|
self.currentCard = self.m.cardModels[self.dialog.cardList.currentRow()]
|
||||||
card = self.currentCard
|
card = self.currentCard
|
||||||
self.dialog.cardName.setText(card.name)
|
self.dialog.cardName.setText(card.name)
|
||||||
self.dialog.cardQuestion.setPlainText(card.qformat.replace("<br>", "\n"))
|
self.dialog.cardQuestion.setPlainText(card.qformat.replace("<br>", "<br>\n"))
|
||||||
self.dialog.cardAnswer.setPlainText(card.aformat.replace("<br>", "\n"))
|
self.dialog.cardAnswer.setPlainText(card.aformat.replace("<br>", "<br>\n"))
|
||||||
self.dialog.questionInAnswer.setChecked(card.questionInAnswer)
|
self.dialog.questionInAnswer.setChecked(card.questionInAnswer)
|
||||||
self.dialog.allowEmptyAnswer.setChecked(card.allowEmptyAnswer)
|
self.dialog.allowEmptyAnswer.setChecked(card.allowEmptyAnswer)
|
||||||
self.dialog.typeAnswer.clear()
|
self.dialog.typeAnswer.clear()
|
||||||
|
|
@ -335,10 +335,10 @@ order by n""", id=card.id)
|
||||||
newname = _("Card %d") % (self.m.cardModels.index(card) + 1)
|
newname = _("Card %d") % (self.m.cardModels.index(card) + 1)
|
||||||
self.updateField(card, 'name', newname)
|
self.updateField(card, 'name', newname)
|
||||||
s = unicode(self.dialog.cardQuestion.toPlainText())
|
s = unicode(self.dialog.cardQuestion.toPlainText())
|
||||||
s = s.replace("\n", "<br>")
|
s = s.replace("<br>\n", "<br>")
|
||||||
changed = self.updateField(card, 'qformat', s)
|
changed = self.updateField(card, 'qformat', s)
|
||||||
s = unicode(self.dialog.cardAnswer.toPlainText())
|
s = unicode(self.dialog.cardAnswer.toPlainText())
|
||||||
s = s.replace("\n", "<br>")
|
s = s.replace("<br>\n", "<br>")
|
||||||
changed2 = self.updateField(card, 'aformat', s)
|
changed2 = self.updateField(card, 'aformat', s)
|
||||||
changed = changed or changed2
|
changed = changed or changed2
|
||||||
self.updateField(card, 'questionInAnswer', self.dialog.questionInAnswer.isChecked())
|
self.updateField(card, 'questionInAnswer', self.dialog.questionInAnswer.isChecked())
|
||||||
|
|
|
||||||
|
|
@ -185,24 +185,8 @@ def restoreHeader(widget, key):
|
||||||
widget.restoreState(ankiqt.mw.config[key])
|
widget.restoreState(ankiqt.mw.config[key])
|
||||||
|
|
||||||
def mungeQA(deck, txt):
|
def mungeQA(deck, txt):
|
||||||
def quote(match):
|
|
||||||
match = unicode(match.group(1))
|
|
||||||
if match.lower().startswith("http"):
|
|
||||||
src = match
|
|
||||||
else:
|
|
||||||
if sys.platform.startswith("win32"):
|
|
||||||
prefix = u"file:///"
|
|
||||||
else:
|
|
||||||
prefix = u"file://"
|
|
||||||
src = prefix + unicode(
|
|
||||||
urllib.quote(os.path.join(deck.mediaDir(
|
|
||||||
create=True), match).encode("utf-8")), "utf-8")
|
|
||||||
return src
|
|
||||||
def quoteImg(match):
|
|
||||||
return 'img src="%s"' % quote(match)
|
|
||||||
txt = renderLatex(deck, txt)
|
txt = renderLatex(deck, txt)
|
||||||
txt = stripSounds(txt)
|
txt = stripSounds(txt)
|
||||||
txt = re.sub('img src="(.*?)"', quoteImg, txt)
|
|
||||||
return txt
|
return txt
|
||||||
|
|
||||||
class ProgressWin(object):
|
class ProgressWin(object):
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,19 @@ class View(object):
|
||||||
self.buffer = self.addStyles() + self.buffer
|
self.buffer = self.addStyles() + self.buffer
|
||||||
# hook for user css
|
# hook for user css
|
||||||
runHook("preFlushHook")
|
runHook("preFlushHook")
|
||||||
|
if self.main.deck and self.main.deck.mediaDir():
|
||||||
|
if sys.platform.startswith("win32"):
|
||||||
|
prefix = u"file:///"
|
||||||
|
else:
|
||||||
|
prefix = u"file://"
|
||||||
|
base = prefix + unicode(
|
||||||
|
urllib.quote(self.main.deck.mediaDir().encode("utf-8")),
|
||||||
|
"utf-8")
|
||||||
|
base = '<base href="%s/">' % base
|
||||||
|
else:
|
||||||
|
base = ""
|
||||||
|
self.buffer = '''<html><head>%s</head><body>%s</body></html>''' % (
|
||||||
|
base, self.buffer)
|
||||||
#print self.buffer.encode("utf-8")
|
#print self.buffer.encode("utf-8")
|
||||||
self.body.setHtml(self.buffer)
|
self.body.setHtml(self.buffer)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>517</width>
|
<width>715</width>
|
||||||
<height>411</height>
|
<height>598</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout" >
|
<layout class="QVBoxLayout" name="verticalLayout" >
|
||||||
|
|
@ -29,8 +29,21 @@
|
||||||
<property name="orientation" >
|
<property name="orientation" >
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QTableWidget" name="table" />
|
<widget class="QTableWidget" name="table" >
|
||||||
|
<property name="sizePolicy" >
|
||||||
|
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>1</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
<widget class="QScrollArea" name="scrollArea" >
|
<widget class="QScrollArea" name="scrollArea" >
|
||||||
|
<property name="sizePolicy" >
|
||||||
|
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>3</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="frameShape" >
|
<property name="frameShape" >
|
||||||
<enum>QFrame::StyledPanel</enum>
|
<enum>QFrame::StyledPanel</enum>
|
||||||
</property>
|
</property>
|
||||||
|
|
@ -61,9 +74,15 @@
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2" >
|
<layout class="QVBoxLayout" name="verticalLayout_2" >
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="bottomLabel" >
|
<widget class="QLabel" name="bottomLabel" >
|
||||||
|
<property name="sizePolicy" >
|
||||||
|
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="maximumSize" >
|
<property name="maximumSize" >
|
||||||
<size>
|
<size>
|
||||||
<width>430</width>
|
<width>500</width>
|
||||||
<height>16777215</height>
|
<height>16777215</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
|
|
||||||
|
|
@ -514,7 +514,7 @@
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="text" >
|
<property name="text" >
|
||||||
<string><b>Session limit (mins):</b></string>
|
<string><b>Limit minutes per session to:</b></string>
|
||||||
</property>
|
</property>
|
||||||
<property name="margin" >
|
<property name="margin" >
|
||||||
<number>4</number>
|
<number>4</number>
|
||||||
|
|
@ -546,7 +546,7 @@
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="text" >
|
<property name="text" >
|
||||||
<string><b>New cards per day:</b></string>
|
<string><b>Limit new cards per day to:</b></string>
|
||||||
</property>
|
</property>
|
||||||
<property name="margin" >
|
<property name="margin" >
|
||||||
<number>4</number>
|
<number>4</number>
|
||||||
|
|
@ -601,7 +601,7 @@
|
||||||
<item row="2" column="0" >
|
<item row="2" column="0" >
|
||||||
<widget class="QLabel" name="label" >
|
<widget class="QLabel" name="label" >
|
||||||
<property name="text" >
|
<property name="text" >
|
||||||
<string><b>Session limit (reps):</string>
|
<string><b>Limit repetitions per session to:</b></string>
|
||||||
</property>
|
</property>
|
||||||
<property name="margin" >
|
<property name="margin" >
|
||||||
<number>4</number>
|
<number>4</number>
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,8 @@ PLIST = dict(
|
||||||
CFBundleName = 'Anki',
|
CFBundleName = 'Anki',
|
||||||
CFBundleDocumentTypes=[dict(CFBundleTypeExtensions=["anki"],
|
CFBundleDocumentTypes=[dict(CFBundleTypeExtensions=["anki"],
|
||||||
CFBundleTypeName="Anki Deck",
|
CFBundleTypeName="Anki Deck",
|
||||||
CFBundleTypeRole="Editor")],
|
CFBundleTypeRole="Editor",
|
||||||
|
CFBundleTypeIconFile="anki.icns")],
|
||||||
CFBundleLocalizations = ['en'],
|
CFBundleLocalizations = ['en'],
|
||||||
)
|
)
|
||||||
OPTIONS = {
|
OPTIONS = {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue