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

This commit is contained in:
Susanna Björverud 2009-04-18 11:16:34 +02:00
commit ef7235bbbf
10 changed files with 122 additions and 72 deletions

View file

@ -26,13 +26,13 @@ A big thanks to all the people who have provided suggestions, bug reports and
donations.""") % { donations.""") % {
'cont': u""" 'cont': u"""
Alex Fraser, Andreas Klauer, Bananeweizen, Bernhard Ibertsberger, Christian Alex Fraser, Andreas Klauer, Andrew Wright, Bananeweizen, Bernhard
Rusche, David Smith, Dave Druelinger, Emmanuel Jarri, Frank Harper, Ian Lewis, Ibertsberger, Christian Rusche, David Smith, Dave Druelinger, Emmanuel Jarri,
Iroiro, Jin Eun-Deok, Jo Nakashima, Krause Chr, LaC, Laurent Steffan, Marco Frank Harper, H. Mijail, Ian Lewis, Iroiro, Jin Eun-Deok, Jo Nakashima, Krause
Giancotti, Mark Wilbur, Meelis Vasser, Michael Penkov, Michal Čadil, Nathanael Chr, LaC, Laurent Steffan, Marco Giancotti, Mark Wilbur, Meelis Vasser,
Law, Nick Cook, Niklas Laxström, Pcsl88, Piotr Kubowicz, Richard Colley, Michael Penkov, Michal Čadil, Nathanael Law, Nick Cook, Niklas Laxström,
Samson Melamed, Susanna Björverud, Timm Preetz, Timo Paulssen, Victor Suba, Pcsl88, Piotr Kubowicz, Richard Colley, Samson Melamed, Susanna Björverud,
and Xtru. Timm Preetz, Timo Paulssen, Victor Suba, and Xtru.
""", """,
'ver': appVersion}) 'ver': appVersion})

View file

@ -14,11 +14,35 @@ class ActiveTagsChooser(QDialog):
self.parent = parent self.parent = parent
self.dialog = ankiqt.forms.activetags.Ui_Dialog() self.dialog = ankiqt.forms.activetags.Ui_Dialog()
self.dialog.setupUi(self) self.dialog.setupUi(self)
self.selectAll = QPushButton(_("Select All"))
self.connect(self.selectAll, SIGNAL("clicked()"), self.onSelectAll)
self.dialog.buttonBox.addButton(self.selectAll,
QDialogButtonBox.ActionRole)
self.selectNone = QPushButton(_("Select None"))
self.connect(self.selectNone, SIGNAL("clicked()"), self.onSelectNone)
self.dialog.buttonBox.addButton(self.selectNone,
QDialogButtonBox.ActionRole)
self.invert = QPushButton(_("Invert"))
self.connect(self.invert, SIGNAL("clicked()"), self.onInvert)
self.dialog.buttonBox.addButton(self.invert,
QDialogButtonBox.ActionRole)
self.connect(self.dialog.buttonBox, SIGNAL("helpRequested()"), self.connect(self.dialog.buttonBox, SIGNAL("helpRequested()"),
self.onHelp) self.onHelp)
self.rebuildTagList() self.rebuildTagList()
restoreGeom(self, "activeTags") restoreGeom(self, "activeTags")
def onSelectAll(self):
self.dialog.list.selectAll()
def onSelectNone(self):
self.dialog.list.clearSelection()
def onInvert(self):
sm = self.dialog.list.selectionModel()
sel = sm.selection()
self.dialog.list.selectAll()
sm.select(sel, QItemSelectionModel.Deselect)
def rebuildTagList(self): def rebuildTagList(self):
self.tags = self.parent.deck.allTags() self.tags = self.parent.deck.allTags()
self.items = [] self.items = []

View file

@ -135,7 +135,7 @@ question or answer on all cards."""), parent=self)
# start a new fact # start a new fact
f = self.parent.deck.newFact() f = self.parent.deck.newFact()
f.tags = self.parent.deck.lastTags f.tags = self.parent.deck.lastTags
self.editor.setFact(f, check=True) self.editor.setFact(f, check=True, scroll=True)
# let completer know our extra tags # let completer know our extra tags
self.editor.tags.addTags(parseTags(self.parent.deck.lastTags)) self.editor.tags.addTags(parseTags(self.parent.deck.lastTags))
self.maybeSave() self.maybeSave()

View file

@ -320,6 +320,10 @@ class EditDeck(QMainWindow):
if self.parent.currentCard: if self.parent.currentCard:
self.currentCard = self.parent.currentCard self.currentCard = self.parent.currentCard
self.focusCurrentCard() self.focusCurrentCard()
if sys.platform.startswith("darwin"):
self.macCloseShortcut = QShortcut(QKeySequence("Ctrl+w"), self)
self.connect(self.macCloseShortcut, SIGNAL("activated()"),
self.close)
def findCardInDeckModel(self, model, card): def findCardInDeckModel(self, model, card):
for i, thisCard in enumerate(model.cards): for i, thisCard in enumerate(model.cards):
@ -402,6 +406,7 @@ class EditDeck(QMainWindow):
self.sortKey = ("field", self.sortFields[idx-9]) self.sortKey = ("field", self.sortFields[idx-9])
self.rebuildSortIndex(self.sortKey) self.rebuildSortIndex(self.sortKey)
self.sortIndex = idx self.sortIndex = idx
if self.deck.getInt('sortIndex') != idx:
self.deck.setVar('sortIndex', idx) self.deck.setVar('sortIndex', idx)
self.model.sortKey = self.sortKey self.model.sortKey = self.sortKey
self.model.updateHeader() self.model.updateHeader()

View file

@ -28,6 +28,8 @@ class DeckProperties(QDialog):
self.origMod = self.d.modified self.origMod = self.d.modified
self.dialog = ankiqt.forms.deckproperties.Ui_DeckProperties() self.dialog = ankiqt.forms.deckproperties.Ui_DeckProperties()
self.dialog.setupUi(self) self.dialog.setupUi(self)
self.dialog.buttonBox.button(QDialogButtonBox.Help).setAutoDefault(False)
self.dialog.buttonBox.button(QDialogButtonBox.Close).setAutoDefault(False)
self.readData() self.readData()
self.connect(self.dialog.modelsAdd, SIGNAL("clicked()"), self.onAdd) self.connect(self.dialog.modelsAdd, SIGNAL("clicked()"), self.onAdd)
self.connect(self.dialog.modelsEdit, SIGNAL("clicked()"), self.onEdit) self.connect(self.dialog.modelsEdit, SIGNAL("clicked()"), self.onEdit)

View file

@ -47,7 +47,7 @@ class FactEditor(object):
addHook("colourChanged", self.colourChanged) addHook("colourChanged", self.colourChanged)
removeHook("colourChanged", self.colourChanged) removeHook("colourChanged", self.colourChanged)
def setFact(self, fact, noFocus=False, check=False): def setFact(self, fact, noFocus=False, check=False, scroll=False):
"Make FACT the current fact." "Make FACT the current fact."
self.fact = fact self.fact = fact
self.factState = None self.factState = None
@ -63,6 +63,8 @@ class FactEditor(object):
else: else:
self.loadFields(check) self.loadFields(check)
self.widget.show() self.widget.show()
if scroll:
self.fieldsScroll.ensureVisible(0, 0)
if not noFocus: if not noFocus:
# update focus to first field # update focus to first field
self.fields[self.fact.fields[0].name][1].setFocus() self.fields[self.fact.fields[0].name][1].setFocus()
@ -109,6 +111,16 @@ class FactEditor(object):
self.fieldsScroll.setFrameStyle(0) self.fieldsScroll.setFrameStyle(0)
self.fieldsScroll.setFocusPolicy(Qt.NoFocus) self.fieldsScroll.setFocusPolicy(Qt.NoFocus)
self.fieldsBox.addWidget(self.fieldsScroll) self.fieldsBox.addWidget(self.fieldsScroll)
# tags
self.tagsBox = QHBoxLayout()
self.tagsLabel = QLabel(_("Tags"))
self.tagsBox.addWidget(self.tagsLabel)
self.tags = ui.tagedit.TagEdit(self.parent)
self.tags.connect(self.tags, SIGNAL("lostFocus"),
self.onTagChange)
self.tagsBox.addWidget(self.tags)
self.fieldsBox.addLayout(self.tagsBox)
# icons
self.iconsBox.setMargin(0) self.iconsBox.setMargin(0)
self.iconsBox.addItem(QSpacerItem(20,1, QSizePolicy.Expanding)) self.iconsBox.addItem(QSpacerItem(20,1, QSizePolicy.Expanding))
self.iconsBox2.setMargin(0) self.iconsBox2.setMargin(0)
@ -323,7 +335,7 @@ 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")) self.htmlEdit.setToolTip(_("HTML Editor (Ctrl+F9)"))
self.htmlEditSC = QShortcut(QKeySequence(_("Ctrl+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)
@ -357,20 +369,25 @@ class FactEditor(object):
fields = self.fact.fields fields = self.fact.fields
self.fields = {} self.fields = {}
self.widgets = {} self.widgets = {}
self.labels = []
n = 0 n = 0
first = True first = True
last = None
for field in fields: for field in fields:
# label # label
l = QLabel(field.name) l = QLabel(field.name)
self.labels.append(l)
self.fieldsGrid.addWidget(l, n, 0) self.fieldsGrid.addWidget(l, n, 0)
# edit widget # edit widget
w = FactEdit(self) w = FactEdit(self)
last = w
w.setTabChangesFocus(True) w.setTabChangesFocus(True)
w.setAcceptRichText(True) w.setAcceptRichText(True)
w.setMinimumSize(20, 60) w.setMinimumSize(20, 60)
w.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) w.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
w.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) w.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
w.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) w.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
runHook("makeField", w, field)
self.fieldsGrid.addWidget(w, n, 1) self.fieldsGrid.addWidget(w, n, 1)
self.fields[field.name] = (field, w) self.fields[field.name] = (field, w)
self.widgets[w] = field self.widgets[w] = field
@ -385,18 +402,14 @@ class FactEditor(object):
self.focusTarget = w self.focusTarget = w
first = False first = False
n += 1 n += 1
# tags
self.fieldsGrid.addWidget(QLabel(_("Tags")), n, 0)
self.tags = ui.tagedit.TagEdit(self.parent)
self.tags.connect(self.tags, SIGNAL("lostFocus"),
self.onTagChange)
# update available tags # update available tags
self.tags.setDeck(self.deck) self.tags.setDeck(self.deck)
self.fieldsGrid.addWidget(self.tags, n, 1)
# update fields # update fields
self.loadFields(check) self.loadFields(check)
self.parent.setUpdatesEnabled(True) self.parent.setUpdatesEnabled(True)
self.fieldsScroll.setWidget(self.fieldsFrame) self.fieldsScroll.setWidget(self.fieldsFrame)
self.tagsLabel.setFixedWidth(max(*[l.width() for l in self.labels]))
self.parent.setTabOrder(last, self.tags)
def needToRedraw(self): def needToRedraw(self):
if self.fact is None: if self.fact is None:
@ -454,7 +467,6 @@ class FactEditor(object):
modified = True modified = True
if modified: if modified:
self.fact.setModified(textChanged=True) self.fact.setModified(textChanged=True)
self.deck.updateFactTags([self.fact.id])
self.deck.setModified() self.deck.setModified()
self.deck.setUndoEnd(n) self.deck.setUndoEnd(n)
@ -481,8 +493,13 @@ class FactEditor(object):
self.onChangeTimer) self.onChangeTimer)
def onChangeTimer(self): def onChangeTimer(self):
from ankiqt import mw
interval = 250
if not self.fact: if not self.fact:
return return
if mw.inDbHandler:
self.changeTimer.start(interval)
return
self.saveFields() self.saveFields()
self.checkValid() self.checkValid()
if self.onChange: if self.onChange:

View file

@ -31,6 +31,8 @@ config = ankiqt.config
class AnkiQt(QMainWindow): class AnkiQt(QMainWindow):
def __init__(self, app, config, args): def __init__(self, app, config, args):
QMainWindow.__init__(self) QMainWindow.__init__(self)
self.errorOccurred = False
self.inDbHandler = False
if sys.platform.startswith("darwin"): if sys.platform.startswith("darwin"):
qt_mac_set_menubar_icons(False) qt_mac_set_menubar_icons(False)
ankiqt.mw = self ankiqt.mw = self
@ -69,7 +71,6 @@ class AnkiQt(QMainWindow):
self.moveToState("auto") self.moveToState("auto")
# check for updates # check for updates
ui.splash.update() ui.splash.update()
self.errorOccurred = False
self.setupErrorHandler() self.setupErrorHandler()
self.setupMisc() self.setupMisc()
self.loadPlugins() self.loadPlugins()
@ -248,6 +249,12 @@ Please do not file a bug report with Anki.<br><br>""")
if self.deck.isEmpty(): if self.deck.isEmpty():
return self.moveToState("deckEmpty") return self.moveToState("deckEmpty")
else: else:
if not self.deck.reviewEarly:
if (self.config['showStudyScreen'] and
not self.deck.sessionStartTime):
return self.moveToState("studyScreen")
if self.deck.sessionLimitReached():
return self.moveToState("studyScreen")
if not self.currentCard: if not self.currentCard:
self.currentCard = self.deck.getCard() self.currentCard = self.deck.getCard()
if self.currentCard: if self.currentCard:
@ -257,12 +264,6 @@ Please do not file a bug report with Anki.<br><br>""")
# if the same card is being shown and it's not # if the same card is being shown and it's not
# due yet, give up # due yet, give up
return self.moveToState("deckFinished") return self.moveToState("deckFinished")
if not self.deck.reviewEarly:
if (self.config['showStudyScreen'] and
not self.deck.sessionStartTime):
return self.moveToState("studyScreen")
if self.deck.sessionLimitReached():
return self.moveToState("studyScreen")
self.enableCardMenuItems() self.enableCardMenuItems()
return self.moveToState("showQuestion") return self.moveToState("showQuestion")
else: else:
@ -282,6 +283,7 @@ Please do not file a bug report with Anki.<br><br>""")
# make sure the buttons aren't focused # make sure the buttons aren't focused
self.mainWin.congratsLabel.setFocus() self.mainWin.congratsLabel.setFocus()
elif state == "showQuestion": elif state == "showQuestion":
self.reviewingStarted = True
if self.deck.mediaDir(): if self.deck.mediaDir():
os.chdir(self.deck.mediaDir()) os.chdir(self.deck.mediaDir())
self.showAnswerButton() self.showAnswerButton()
@ -429,6 +431,8 @@ new:
def refreshStatus(self): def refreshStatus(self):
"If triggered when the deck is finished, reset state." "If triggered when the deck is finished, reset state."
if self.inDbHandler:
return
if self.state == "deckFinished": if self.state == "deckFinished":
# don't try refresh if the deck is closed during a sync # don't try refresh if the deck is closed during a sync
if self.deck: if self.deck:
@ -553,6 +557,7 @@ new:
def loadDeck(self, deckPath, sync=True, interactive=True, uprecent=True): def loadDeck(self, deckPath, sync=True, interactive=True, uprecent=True):
"Load a deck and update the user interface. Maybe sync." "Load a deck and update the user interface. Maybe sync."
self.reviewingStarted = False
# return True on success # return True on success
try: try:
self.pauseViews() self.pauseViews()
@ -729,7 +734,6 @@ 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):
@ -1099,17 +1103,16 @@ day = :d""", d=yesterday)
<td>%s</td></tr></table>""" % (stats1, stats2)) <td>%s</td></tr></table>""" % (stats1, stats2))
def showStudyScreen(self): def showStudyScreen(self):
initial = self.deck.sessionStartTime == 0
self.mainWin.optionsButton.setChecked(self.config['showStudyOptions']) self.mainWin.optionsButton.setChecked(self.config['showStudyOptions'])
self.mainWin.optionsBox.setShown(self.config['showStudyOptions']) self.mainWin.optionsBox.setShown(self.config['showStudyOptions'])
self.switchToStudyScreen() self.switchToStudyScreen()
self.updateStudyStats() self.updateStudyStats()
# start reviewing button # start reviewing button
self.mainWin.buttonStack.hide() self.mainWin.buttonStack.hide()
if initial: if self.reviewingStarted:
self.mainWin.startReviewingButton.setText(_("Start &Reviewing"))
else:
self.mainWin.startReviewingButton.setText(_("Continue &Reviewing")) self.mainWin.startReviewingButton.setText(_("Continue &Reviewing"))
else:
self.mainWin.startReviewingButton.setText(_("Start &Reviewing"))
self.mainWin.startReviewingButton.setFocus() self.mainWin.startReviewingButton.setFocus()
self.connect(self.mainWin.startReviewingButton, self.connect(self.mainWin.startReviewingButton,
SIGNAL("clicked()"), SIGNAL("clicked()"),
@ -1336,6 +1339,8 @@ day = :d""", d=yesterday)
def onDelete(self): def onDelete(self):
undo = _("Delete") undo = _("Delete")
if self.state == "editCurrent":
self.moveToState("saveEdit")
self.deck.setUndoStart(undo) self.deck.setUndoStart(undo)
self.deck.deleteCard(self.currentCard.id) self.deck.deleteCard(self.currentCard.id)
self.reset() self.reset()
@ -2152,7 +2157,9 @@ it to your friends.
if self.mainThread != QThread.currentThread(): if self.mainThread != QThread.currentThread():
return return
self.setBusy() self.setBusy()
self.inDbHandler = True
self.app.processEvents() self.app.processEvents()
self.inDbHandler = False
def onDbFinished(self): def onDbFinished(self):
if self.mainThread != QThread.currentThread(): if self.mainThread != QThread.currentThread():
@ -2162,11 +2169,13 @@ it to your friends.
def setBusy(self): def setBusy(self):
if not self.busyCursor: if not self.busyCursor:
self.setEnabled(False)
self.app.setOverrideCursor(QCursor(Qt.WaitCursor)) self.app.setOverrideCursor(QCursor(Qt.WaitCursor))
self.busyCursor = True self.busyCursor = True
def unsetBusy(self): def unsetBusy(self):
if self.busyCursor: if self.busyCursor:
self.setEnabled(True)
self.app.restoreOverrideCursor() self.app.restoreOverrideCursor()
self.busyCursor = None self.busyCursor = None

View file

@ -252,6 +252,8 @@ You should aim to answer each question within<br>
palette.setColor(QPalette.Highlight, QColor("#00ee00")) palette.setColor(QPalette.Highlight, QColor("#00ee00"))
def drawTimer(self): def drawTimer(self):
if self.main.inDbHandler:
return
if not self.main.config['showTimer']: if not self.main.config['showTimer']:
return return
if not self.timer: if not self.timer:
@ -280,6 +282,8 @@ You should aim to answer each question within<br>
self.timerFlashStart = time.time() self.timerFlashStart = time.time()
def updateCount(self): def updateCount(self):
if self.main.inDbHandler:
return
if not self.main.deck: if not self.main.deck:
return return
if self.state in ("showQuestion", "showAnswer", "studyScreen"): if self.state in ("showQuestion", "showAnswer", "studyScreen"):

View file

@ -5,8 +5,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>248</width> <width>369</width>
<height>268</height> <height>393</height>
</rect> </rect>
</property> </property>
<property name="windowTitle" > <property name="windowTitle" >
@ -16,10 +16,12 @@
<item> <item>
<widget class="QLabel" name="label" > <widget class="QLabel" name="label" >
<property name="text" > <property name="text" >
<string>&lt;h1>Select tags to suspend&lt;/h1></string> <string>Select tags to suspend. Deselect to unsuspend.</string>
</property> </property>
</widget> </widget>
</item> </item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2" >
<item> <item>
<widget class="QListWidget" name="list" > <widget class="QListWidget" name="list" >
<property name="selectionMode" > <property name="selectionMode" >
@ -30,7 +32,7 @@
<item> <item>
<widget class="QDialogButtonBox" name="buttonBox" > <widget class="QDialogButtonBox" name="buttonBox" >
<property name="orientation" > <property name="orientation" >
<enum>Qt::Horizontal</enum> <enum>Qt::Vertical</enum>
</property> </property>
<property name="standardButtons" > <property name="standardButtons" >
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok</set> <set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok</set>
@ -38,6 +40,8 @@
</widget> </widget>
</item> </item>
</layout> </layout>
</item>
</layout>
</widget> </widget>
<resources/> <resources/>
<connections> <connections>

View file

@ -25,14 +25,6 @@
<number>0</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="tab_2" > <widget class="QWidget" name="tab_2" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>410</width>
<height>334</height>
</rect>
</property>
<attribute name="title" > <attribute name="title" >
<string>Models &amp;&amp; Priorities</string> <string>Models &amp;&amp; Priorities</string>
</attribute> </attribute>
@ -139,6 +131,9 @@
<property name="text" > <property name="text" >
<string>&amp;Add</string> <string>&amp;Add</string>
</property> </property>
<property name="autoDefault" >
<bool>false</bool>
</property>
</widget> </widget>
</item> </item>
<item> <item>
@ -146,6 +141,9 @@
<property name="text" > <property name="text" >
<string>&amp;Edit</string> <string>&amp;Edit</string>
</property> </property>
<property name="autoDefault" >
<bool>false</bool>
</property>
</widget> </widget>
</item> </item>
<item> <item>
@ -153,6 +151,9 @@
<property name="text" > <property name="text" >
<string>&amp;Delete</string> <string>&amp;Delete</string>
</property> </property>
<property name="autoDefault" >
<bool>false</bool>
</property>
</widget> </widget>
</item> </item>
</layout> </layout>
@ -160,14 +161,6 @@
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tab_5" > <widget class="QWidget" name="tab_5" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>375</width>
<height>334</height>
</rect>
</property>
<attribute name="title" > <attribute name="title" >
<string>Synchronisation</string> <string>Synchronisation</string>
</attribute> </attribute>
@ -300,14 +293,6 @@ p, li { white-space: pre-wrap; }
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tab_4" > <widget class="QWidget" name="tab_4" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>346</width>
<height>356</height>
</rect>
</property>
<attribute name="title" > <attribute name="title" >
<string>Advanced</string> <string>Advanced</string>
</attribute> </attribute>