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
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 *
|
||||
|
||||
appName="Anki"
|
||||
appVersion="0.9.9.7.5"
|
||||
appVersion="0.9.9.7.6b"
|
||||
appWebsite="http://ichi2.net/anki/download/"
|
||||
appWiki="http://ichi2.net/anki/wiki/"
|
||||
appHelpSite="http://ichi2.net/anki/wiki/AnkiWiki"
|
||||
|
@ -175,5 +175,8 @@ def run():
|
|||
|
||||
app.exec_()
|
||||
|
||||
# ensure we kill any other threads
|
||||
sys.exit(0)
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
|
|
|
@ -9,6 +9,7 @@ def importAll():
|
|||
import addcards
|
||||
import cardlist
|
||||
import deckproperties
|
||||
import importing
|
||||
import displayproperties
|
||||
import exporting
|
||||
import facteditor
|
||||
|
|
|
@ -453,7 +453,7 @@ class EditDeck(QMainWindow):
|
|||
elif idx == 1:
|
||||
self.dialog.filterEdit.setText("tag:none")
|
||||
else:
|
||||
self.dialog.filterEdit.setText("tag:" + self.alltags[idx-2].lower())
|
||||
self.dialog.filterEdit.setText("tag:" + self.alltags[idx-2])
|
||||
self.showFilterNow()
|
||||
self.dialog.tagList.setCurrentIndex(0)
|
||||
|
||||
|
|
|
@ -995,6 +995,11 @@ class FactEdit(QTextEdit):
|
|||
|
||||
# this shouldn't be necessary if/when we move away from kakasi
|
||||
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.setMinimal(True)
|
||||
|
||||
|
@ -1025,8 +1030,7 @@ class FactEdit(QTextEdit):
|
|||
result = r.indexIn(self.toPlainText(), blockoffset)
|
||||
|
||||
if found == "":
|
||||
QTextEdit.mouseDoubleClickEvent(self,evt)
|
||||
return
|
||||
return QTextEdit.mouseDoubleClickEvent(self,evt)
|
||||
self.setPlainText(self.toPlainText().replace(result, r.matchedLength(), found))
|
||||
|
||||
def focusInEvent(self, evt):
|
||||
|
|
|
@ -63,6 +63,7 @@ class GetShared(QDialog):
|
|||
return
|
||||
self.parent.finishProgress()
|
||||
self.parent.setProgressParent(None)
|
||||
self.form.search.setFocus()
|
||||
if err:
|
||||
showInfo(_("Unable to connect to server."), parent=self)
|
||||
self.close()
|
||||
|
@ -108,6 +109,7 @@ class GetShared(QDialog):
|
|||
else:
|
||||
self.form.table.sortItems(1, Qt.DescendingOrder)
|
||||
self.form.table.selectRow(0)
|
||||
self.onCellChanged(None, None, None, None)
|
||||
|
||||
def onCellChanged(self, row, col, x, y):
|
||||
ci = self.form.table.currentItem()
|
||||
|
|
|
@ -126,29 +126,42 @@ class AnkiQt(QMainWindow):
|
|||
self.parent = parent
|
||||
self.timer = None
|
||||
self.pool = ""
|
||||
self.poolUpdated = 0
|
||||
|
||||
def write(self, data):
|
||||
print data.encode("utf-8"),
|
||||
self.pool += data
|
||||
self.updateTimer()
|
||||
self.poolUpdated = time.time()
|
||||
|
||||
def updateTimer(self):
|
||||
interval = 200
|
||||
if not self.timer:
|
||||
self.timer = QTimer(self.parent)
|
||||
self.timer.setSingleShot(True)
|
||||
self.timer.start(interval)
|
||||
self.parent.connect(self.timer,
|
||||
SIGNAL("timeout()"),
|
||||
self.onTimeout)
|
||||
else:
|
||||
self.timer.setInterval(interval)
|
||||
def haveError(self):
|
||||
if self.pool:
|
||||
if (time.time() - self.poolUpdated) > 1:
|
||||
return True
|
||||
|
||||
def onTimeout(self):
|
||||
if "font_manager.py" in self.pool:
|
||||
# hack for matplotlib errors on osx
|
||||
self.pool = ""
|
||||
stdText = _("""\
|
||||
def getError(self):
|
||||
p = 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 = _("""\
|
||||
An error occurred. Please:<p>
|
||||
<ol>
|
||||
<li><b>Restart Anki</b>.
|
||||
|
@ -157,21 +170,16 @@ An error occurred. Please:<p>
|
|||
If it does not fix the problem, please copy the following<br>
|
||||
into a bug report:<br><br>
|
||||
""")
|
||||
pluginText = _("""\
|
||||
pluginText = _("""\
|
||||
An error occurred in a plugin. Please contact the plugin author.<br>
|
||||
Please do not file a bug report with Anki.<br><br>""")
|
||||
if "plugin" in self.pool:
|
||||
txt = pluginText
|
||||
else:
|
||||
txt = stdText
|
||||
if self.pool:
|
||||
self.parent.errorOccurred = True
|
||||
ui.utils.showText(txt + self.pool[0:10000].replace(
|
||||
if "plugin" in error:
|
||||
txt = pluginText
|
||||
else:
|
||||
txt = stdText
|
||||
self.errorOccurred = True
|
||||
ui.utils.showText(txt + error[0:10000].replace(
|
||||
"\n", "<br>"))
|
||||
self.pool = ""
|
||||
self.timer = None
|
||||
pipe = ErrorPipe(self)
|
||||
sys.stderr = pipe
|
||||
|
||||
def closeAllDeckWindows(self):
|
||||
ui.dialogs.closeAll()
|
||||
|
@ -687,7 +695,7 @@ To upgrade an old deck, download Anki 0.9.8.7."""))
|
|||
def onClose(self):
|
||||
if self.inMainWindow():
|
||||
self.saveAndClose(hideWelcome=self.isCramming())
|
||||
if cramming:
|
||||
if self.isCramming():
|
||||
self.loadRecent(0)
|
||||
else:
|
||||
self.app.activeWindow().close()
|
||||
|
@ -1104,6 +1112,33 @@ day = :d""", d=yesterday)
|
|||
<p><table><tr>
|
||||
%s
|
||||
<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):
|
||||
self.mainWin.optionsButton.setChecked(self.config['showStudyOptions'])
|
||||
|
|
|
@ -289,8 +289,8 @@ class ModelProperties(QDialog):
|
|||
self.currentCard = self.m.cardModels[self.dialog.cardList.currentRow()]
|
||||
card = self.currentCard
|
||||
self.dialog.cardName.setText(card.name)
|
||||
self.dialog.cardQuestion.setPlainText(card.qformat.replace("<br>", "\n"))
|
||||
self.dialog.cardAnswer.setPlainText(card.aformat.replace("<br>", "\n"))
|
||||
self.dialog.cardQuestion.setPlainText(card.qformat.replace("<br>", "<br>\n"))
|
||||
self.dialog.cardAnswer.setPlainText(card.aformat.replace("<br>", "<br>\n"))
|
||||
self.dialog.questionInAnswer.setChecked(card.questionInAnswer)
|
||||
self.dialog.allowEmptyAnswer.setChecked(card.allowEmptyAnswer)
|
||||
self.dialog.typeAnswer.clear()
|
||||
|
@ -335,10 +335,10 @@ order by n""", id=card.id)
|
|||
newname = _("Card %d") % (self.m.cardModels.index(card) + 1)
|
||||
self.updateField(card, 'name', newname)
|
||||
s = unicode(self.dialog.cardQuestion.toPlainText())
|
||||
s = s.replace("\n", "<br>")
|
||||
s = s.replace("<br>\n", "<br>")
|
||||
changed = self.updateField(card, 'qformat', s)
|
||||
s = unicode(self.dialog.cardAnswer.toPlainText())
|
||||
s = s.replace("\n", "<br>")
|
||||
s = s.replace("<br>\n", "<br>")
|
||||
changed2 = self.updateField(card, 'aformat', s)
|
||||
changed = changed or changed2
|
||||
self.updateField(card, 'questionInAnswer', self.dialog.questionInAnswer.isChecked())
|
||||
|
|
|
@ -185,24 +185,8 @@ def restoreHeader(widget, key):
|
|||
widget.restoreState(ankiqt.mw.config[key])
|
||||
|
||||
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 = stripSounds(txt)
|
||||
txt = re.sub('img src="(.*?)"', quoteImg, txt)
|
||||
return txt
|
||||
|
||||
class ProgressWin(object):
|
||||
|
|
|
@ -106,6 +106,19 @@ class View(object):
|
|||
self.buffer = self.addStyles() + self.buffer
|
||||
# hook for user css
|
||||
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")
|
||||
self.body.setHtml(self.buffer)
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>517</width>
|
||||
<height>411</height>
|
||||
<width>715</width>
|
||||
<height>598</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" >
|
||||
|
@ -29,8 +29,21 @@
|
|||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</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" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>3</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape" >
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
|
@ -61,9 +74,15 @@
|
|||
<layout class="QVBoxLayout" name="verticalLayout_2" >
|
||||
<item>
|
||||
<widget class="QLabel" name="bottomLabel" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize" >
|
||||
<size>
|
||||
<width>430</width>
|
||||
<width>500</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
|
|
|
@ -514,7 +514,7 @@
|
|||
</size>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string><b>Session limit (mins):</b></string>
|
||||
<string><b>Limit minutes per session to:</b></string>
|
||||
</property>
|
||||
<property name="margin" >
|
||||
<number>4</number>
|
||||
|
@ -546,7 +546,7 @@
|
|||
</size>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string><b>New cards per day:</b></string>
|
||||
<string><b>Limit new cards per day to:</b></string>
|
||||
</property>
|
||||
<property name="margin" >
|
||||
<number>4</number>
|
||||
|
@ -601,7 +601,7 @@
|
|||
<item row="2" column="0" >
|
||||
<widget class="QLabel" name="label" >
|
||||
<property name="text" >
|
||||
<string><b>Session limit (reps):</string>
|
||||
<string><b>Limit repetitions per session to:</b></string>
|
||||
</property>
|
||||
<property name="margin" >
|
||||
<number>4</number>
|
||||
|
|
|
@ -53,7 +53,8 @@ PLIST = dict(
|
|||
CFBundleName = 'Anki',
|
||||
CFBundleDocumentTypes=[dict(CFBundleTypeExtensions=["anki"],
|
||||
CFBundleTypeName="Anki Deck",
|
||||
CFBundleTypeRole="Editor")],
|
||||
CFBundleTypeRole="Editor",
|
||||
CFBundleTypeIconFile="anki.icns")],
|
||||
CFBundleLocalizations = ['en'],
|
||||
)
|
||||
OPTIONS = {
|
||||
|
|
Loading…
Reference in a new issue