Merge branch 'master' of git://ichi2.net/ankiqt

This commit is contained in:
Susanna Björverud 2009-04-27 20:09:44 +02:00
commit 9de5ceaeff
12 changed files with 124 additions and 62 deletions

View file

@ -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()

View file

@ -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

View file

@ -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)

View file

@ -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):

View file

@ -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()

View file

@ -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'])

View file

@ -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())

View file

@ -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):

View file

@ -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)

View file

@ -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>

View file

@ -514,7 +514,7 @@
</size> </size>
</property> </property>
<property name="text" > <property name="text" >
<string>&lt;b>Session limit (mins):&lt;/b></string> <string>&lt;b>Limit minutes per session to:&lt;/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>&lt;b>New cards per day:&lt;/b></string> <string>&lt;b>Limit new cards per day to:&lt;/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>&lt;b>Session limit (reps):</string> <string>&lt;b>Limit repetitions per session to:&lt;/b></string>
</property> </property>
<property name="margin" > <property name="margin" >
<number>4</number> <number>4</number>

View file

@ -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 = {