mirror of
https://github.com/ankitects/anki.git
synced 2025-09-20 15:02:21 -04:00
Merge branch 'master' of git://ichi2.net/ankiqt
This commit is contained in:
commit
ef7235bbbf
10 changed files with 122 additions and 72 deletions
|
@ -26,13 +26,13 @@ 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.
|
||||
Alex Fraser, Andreas Klauer, Andrew Wright, Bananeweizen, Bernhard
|
||||
Ibertsberger, Christian Rusche, David Smith, Dave Druelinger, Emmanuel Jarri,
|
||||
Frank Harper, H. Mijail, 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})
|
||||
|
|
|
@ -14,11 +14,35 @@ class ActiveTagsChooser(QDialog):
|
|||
self.parent = parent
|
||||
self.dialog = ankiqt.forms.activetags.Ui_Dialog()
|
||||
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.onHelp)
|
||||
self.rebuildTagList()
|
||||
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):
|
||||
self.tags = self.parent.deck.allTags()
|
||||
self.items = []
|
||||
|
|
|
@ -135,7 +135,7 @@ question or answer on all cards."""), parent=self)
|
|||
# start a new fact
|
||||
f = self.parent.deck.newFact()
|
||||
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
|
||||
self.editor.tags.addTags(parseTags(self.parent.deck.lastTags))
|
||||
self.maybeSave()
|
||||
|
|
|
@ -320,6 +320,10 @@ class EditDeck(QMainWindow):
|
|||
if self.parent.currentCard:
|
||||
self.currentCard = self.parent.currentCard
|
||||
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):
|
||||
for i, thisCard in enumerate(model.cards):
|
||||
|
@ -402,7 +406,8 @@ class EditDeck(QMainWindow):
|
|||
self.sortKey = ("field", self.sortFields[idx-9])
|
||||
self.rebuildSortIndex(self.sortKey)
|
||||
self.sortIndex = idx
|
||||
self.deck.setVar('sortIndex', idx)
|
||||
if self.deck.getInt('sortIndex') != idx:
|
||||
self.deck.setVar('sortIndex', idx)
|
||||
self.model.sortKey = self.sortKey
|
||||
self.model.updateHeader()
|
||||
if refresh:
|
||||
|
|
|
@ -28,6 +28,8 @@ class DeckProperties(QDialog):
|
|||
self.origMod = self.d.modified
|
||||
self.dialog = ankiqt.forms.deckproperties.Ui_DeckProperties()
|
||||
self.dialog.setupUi(self)
|
||||
self.dialog.buttonBox.button(QDialogButtonBox.Help).setAutoDefault(False)
|
||||
self.dialog.buttonBox.button(QDialogButtonBox.Close).setAutoDefault(False)
|
||||
self.readData()
|
||||
self.connect(self.dialog.modelsAdd, SIGNAL("clicked()"), self.onAdd)
|
||||
self.connect(self.dialog.modelsEdit, SIGNAL("clicked()"), self.onEdit)
|
||||
|
|
|
@ -47,7 +47,7 @@ class FactEditor(object):
|
|||
addHook("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."
|
||||
self.fact = fact
|
||||
self.factState = None
|
||||
|
@ -63,6 +63,8 @@ class FactEditor(object):
|
|||
else:
|
||||
self.loadFields(check)
|
||||
self.widget.show()
|
||||
if scroll:
|
||||
self.fieldsScroll.ensureVisible(0, 0)
|
||||
if not noFocus:
|
||||
# update focus to first field
|
||||
self.fields[self.fact.fields[0].name][1].setFocus()
|
||||
|
@ -109,6 +111,16 @@ class FactEditor(object):
|
|||
self.fieldsScroll.setFrameStyle(0)
|
||||
self.fieldsScroll.setFocusPolicy(Qt.NoFocus)
|
||||
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.addItem(QSpacerItem(20,1, QSizePolicy.Expanding))
|
||||
self.iconsBox2.setMargin(0)
|
||||
|
@ -323,7 +335,7 @@ class FactEditor(object):
|
|||
self.latexMathEnv.setStyle(self.plastiqueStyle)
|
||||
# html
|
||||
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.htmlEdit.connect(self.htmlEdit, SIGNAL("clicked()"),
|
||||
self.onHtmlEdit)
|
||||
|
@ -357,20 +369,25 @@ class FactEditor(object):
|
|||
fields = self.fact.fields
|
||||
self.fields = {}
|
||||
self.widgets = {}
|
||||
self.labels = []
|
||||
n = 0
|
||||
first = True
|
||||
last = None
|
||||
for field in fields:
|
||||
# label
|
||||
l = QLabel(field.name)
|
||||
self.labels.append(l)
|
||||
self.fieldsGrid.addWidget(l, n, 0)
|
||||
# edit widget
|
||||
w = FactEdit(self)
|
||||
last = w
|
||||
w.setTabChangesFocus(True)
|
||||
w.setAcceptRichText(True)
|
||||
w.setMinimumSize(20, 60)
|
||||
w.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||
w.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||
w.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||
runHook("makeField", w, field)
|
||||
self.fieldsGrid.addWidget(w, n, 1)
|
||||
self.fields[field.name] = (field, w)
|
||||
self.widgets[w] = field
|
||||
|
@ -385,18 +402,14 @@ class FactEditor(object):
|
|||
self.focusTarget = w
|
||||
first = False
|
||||
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
|
||||
self.tags.setDeck(self.deck)
|
||||
self.fieldsGrid.addWidget(self.tags, n, 1)
|
||||
# update fields
|
||||
self.loadFields(check)
|
||||
self.parent.setUpdatesEnabled(True)
|
||||
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):
|
||||
if self.fact is None:
|
||||
|
@ -454,7 +467,6 @@ class FactEditor(object):
|
|||
modified = True
|
||||
if modified:
|
||||
self.fact.setModified(textChanged=True)
|
||||
self.deck.updateFactTags([self.fact.id])
|
||||
self.deck.setModified()
|
||||
self.deck.setUndoEnd(n)
|
||||
|
||||
|
@ -481,8 +493,13 @@ class FactEditor(object):
|
|||
self.onChangeTimer)
|
||||
|
||||
def onChangeTimer(self):
|
||||
from ankiqt import mw
|
||||
interval = 250
|
||||
if not self.fact:
|
||||
return
|
||||
if mw.inDbHandler:
|
||||
self.changeTimer.start(interval)
|
||||
return
|
||||
self.saveFields()
|
||||
self.checkValid()
|
||||
if self.onChange:
|
||||
|
|
|
@ -31,6 +31,8 @@ config = ankiqt.config
|
|||
class AnkiQt(QMainWindow):
|
||||
def __init__(self, app, config, args):
|
||||
QMainWindow.__init__(self)
|
||||
self.errorOccurred = False
|
||||
self.inDbHandler = False
|
||||
if sys.platform.startswith("darwin"):
|
||||
qt_mac_set_menubar_icons(False)
|
||||
ankiqt.mw = self
|
||||
|
@ -69,7 +71,6 @@ class AnkiQt(QMainWindow):
|
|||
self.moveToState("auto")
|
||||
# check for updates
|
||||
ui.splash.update()
|
||||
self.errorOccurred = False
|
||||
self.setupErrorHandler()
|
||||
self.setupMisc()
|
||||
self.loadPlugins()
|
||||
|
@ -248,6 +249,12 @@ Please do not file a bug report with Anki.<br><br>""")
|
|||
if self.deck.isEmpty():
|
||||
return self.moveToState("deckEmpty")
|
||||
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:
|
||||
self.currentCard = self.deck.getCard()
|
||||
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
|
||||
# due yet, give up
|
||||
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()
|
||||
return self.moveToState("showQuestion")
|
||||
else:
|
||||
|
@ -282,6 +283,7 @@ Please do not file a bug report with Anki.<br><br>""")
|
|||
# make sure the buttons aren't focused
|
||||
self.mainWin.congratsLabel.setFocus()
|
||||
elif state == "showQuestion":
|
||||
self.reviewingStarted = True
|
||||
if self.deck.mediaDir():
|
||||
os.chdir(self.deck.mediaDir())
|
||||
self.showAnswerButton()
|
||||
|
@ -429,6 +431,8 @@ new:
|
|||
|
||||
def refreshStatus(self):
|
||||
"If triggered when the deck is finished, reset state."
|
||||
if self.inDbHandler:
|
||||
return
|
||||
if self.state == "deckFinished":
|
||||
# don't try refresh if the deck is closed during a sync
|
||||
if self.deck:
|
||||
|
@ -553,6 +557,7 @@ new:
|
|||
|
||||
def loadDeck(self, deckPath, sync=True, interactive=True, uprecent=True):
|
||||
"Load a deck and update the user interface. Maybe sync."
|
||||
self.reviewingStarted = False
|
||||
# return True on success
|
||||
try:
|
||||
self.pauseViews()
|
||||
|
@ -729,7 +734,6 @@ To upgrade an old deck, download Anki 0.9.8.7."""))
|
|||
return True
|
||||
|
||||
def inMainWindow(self):
|
||||
return True
|
||||
return self.app.activeWindow() == self
|
||||
|
||||
def onNew(self, initial=False, path=None):
|
||||
|
@ -1099,17 +1103,16 @@ day = :d""", d=yesterday)
|
|||
<td>%s</td></tr></table>""" % (stats1, stats2))
|
||||
|
||||
def showStudyScreen(self):
|
||||
initial = self.deck.sessionStartTime == 0
|
||||
self.mainWin.optionsButton.setChecked(self.config['showStudyOptions'])
|
||||
self.mainWin.optionsBox.setShown(self.config['showStudyOptions'])
|
||||
self.switchToStudyScreen()
|
||||
self.updateStudyStats()
|
||||
# start reviewing button
|
||||
self.mainWin.buttonStack.hide()
|
||||
if initial:
|
||||
self.mainWin.startReviewingButton.setText(_("Start &Reviewing"))
|
||||
else:
|
||||
if self.reviewingStarted:
|
||||
self.mainWin.startReviewingButton.setText(_("Continue &Reviewing"))
|
||||
else:
|
||||
self.mainWin.startReviewingButton.setText(_("Start &Reviewing"))
|
||||
self.mainWin.startReviewingButton.setFocus()
|
||||
self.connect(self.mainWin.startReviewingButton,
|
||||
SIGNAL("clicked()"),
|
||||
|
@ -1336,6 +1339,8 @@ day = :d""", d=yesterday)
|
|||
|
||||
def onDelete(self):
|
||||
undo = _("Delete")
|
||||
if self.state == "editCurrent":
|
||||
self.moveToState("saveEdit")
|
||||
self.deck.setUndoStart(undo)
|
||||
self.deck.deleteCard(self.currentCard.id)
|
||||
self.reset()
|
||||
|
@ -2152,7 +2157,9 @@ it to your friends.
|
|||
if self.mainThread != QThread.currentThread():
|
||||
return
|
||||
self.setBusy()
|
||||
self.inDbHandler = True
|
||||
self.app.processEvents()
|
||||
self.inDbHandler = False
|
||||
|
||||
def onDbFinished(self):
|
||||
if self.mainThread != QThread.currentThread():
|
||||
|
@ -2162,11 +2169,13 @@ it to your friends.
|
|||
|
||||
def setBusy(self):
|
||||
if not self.busyCursor:
|
||||
self.setEnabled(False)
|
||||
self.app.setOverrideCursor(QCursor(Qt.WaitCursor))
|
||||
self.busyCursor = True
|
||||
|
||||
def unsetBusy(self):
|
||||
if self.busyCursor:
|
||||
self.setEnabled(True)
|
||||
self.app.restoreOverrideCursor()
|
||||
self.busyCursor = None
|
||||
|
||||
|
|
|
@ -252,6 +252,8 @@ You should aim to answer each question within<br>
|
|||
palette.setColor(QPalette.Highlight, QColor("#00ee00"))
|
||||
|
||||
def drawTimer(self):
|
||||
if self.main.inDbHandler:
|
||||
return
|
||||
if not self.main.config['showTimer']:
|
||||
return
|
||||
if not self.timer:
|
||||
|
@ -280,6 +282,8 @@ You should aim to answer each question within<br>
|
|||
self.timerFlashStart = time.time()
|
||||
|
||||
def updateCount(self):
|
||||
if self.main.inDbHandler:
|
||||
return
|
||||
if not self.main.deck:
|
||||
return
|
||||
if self.state in ("showQuestion", "showAnswer", "studyScreen"):
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>248</width>
|
||||
<height>268</height>
|
||||
<width>369</width>
|
||||
<height>393</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
|
@ -16,26 +16,30 @@
|
|||
<item>
|
||||
<widget class="QLabel" name="label" >
|
||||
<property name="text" >
|
||||
<string><h1>Select tags to suspend</h1></string>
|
||||
<string>Select tags to suspend. Deselect to unsuspend.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="list" >
|
||||
<property name="selectionMode" >
|
||||
<enum>QAbstractItemView::MultiSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox" >
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons" >
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2" >
|
||||
<item>
|
||||
<widget class="QListWidget" name="list" >
|
||||
<property name="selectionMode" >
|
||||
<enum>QAbstractItemView::MultiSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox" >
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="standardButtons" >
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
|
|
@ -25,14 +25,6 @@
|
|||
<number>0</number>
|
||||
</property>
|
||||
<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" >
|
||||
<string>Models && Priorities</string>
|
||||
</attribute>
|
||||
|
@ -139,6 +131,9 @@
|
|||
<property name="text" >
|
||||
<string>&Add</string>
|
||||
</property>
|
||||
<property name="autoDefault" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
@ -146,6 +141,9 @@
|
|||
<property name="text" >
|
||||
<string>&Edit</string>
|
||||
</property>
|
||||
<property name="autoDefault" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
@ -153,6 +151,9 @@
|
|||
<property name="text" >
|
||||
<string>&Delete</string>
|
||||
</property>
|
||||
<property name="autoDefault" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -160,14 +161,6 @@
|
|||
</layout>
|
||||
</widget>
|
||||
<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" >
|
||||
<string>Synchronisation</string>
|
||||
</attribute>
|
||||
|
@ -300,14 +293,6 @@ p, li { white-space: pre-wrap; }
|
|||
</layout>
|
||||
</widget>
|
||||
<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" >
|
||||
<string>Advanced</string>
|
||||
</attribute>
|
||||
|
|
Loading…
Reference in a new issue