rework resetting and selection code

- now properly call begin/endresetmodel()
- restore not just the current card, but the whole selection
- do so in the model, for all operations like new searches, resorts, etc
This commit is contained in:
Damien Elmes 2011-04-12 22:54:44 +09:00
parent 598b22e18b
commit f97e096672

View file

@ -37,7 +37,7 @@ class DeckModel(QAbstractTableModel):
self.deck = browser.deck self.deck = browser.deck
self.sortKey = None self.sortKey = None
self.activeCols = self.deck.conf.get( self.activeCols = self.deck.conf.get(
"activeCols", ["factFld", "answer", "cardDue", "cardEase"]) "activeCols", ["factFld", "template", "cardDue", "cardEase"])
self.cards = [] self.cards = []
self.cardObjs = {} self.cardObjs = {}
@ -97,18 +97,67 @@ class DeckModel(QAbstractTableModel):
# Filtering # Filtering
###################################################################### ######################################################################
def showMatching(self, force=True): def search(self, txt):
self.browser.mw.progress.start() self.beginReset()
t = time.time() t = time.time()
self.cards = self.deck.findCards(self.searchStr.strip()) self.cards = self.deck.findCards(txt)
print "fetch cards in %dms" % ((time.time() - t)*1000) print "fetch cards in %dms" % ((time.time() - t)*1000)
self.browser.mw.progress.finish() self.endReset()
self.reset()
# fixme: merge into reset(), fix titlebar flicker def beginReset(self):
def refresh(self): self.browser.mw.progress.start()
self.saveSelection()
self.beginResetModel()
self.cardObjs = {} self.cardObjs = {}
self.emit(SIGNAL("layoutChanged()"))
def endReset(self):
t = time.time()
self.endResetModel()
print "end", time.time() - t; t = time.time()
self.restoreSelection()
print "sel", time.time() - t; t = time.time()
self.browser.mw.progress.finish()
def reverse(self):
self.beginReset()
self.cards.reverse()
self.endReset()
def saveSelection(self):
self.selectedCards = dict(
[(id, True) for id in self.browser.selectedCards()])
self.focusedCard = getattr(self.browser, 'card', None)
def restoreSelection(self):
if not self.cards:
return
sm = self.browser.form.tableView.selectionModel()
sm.clear()
# restore selection
items = QItemSelection()
focused = None
first = None
for row, id in enumerate(self.cards):
if id in self.selectedCards:
idx = self.index(row, 0)
items.select(idx, idx)
if not first:
first = idx
# note idx of focused card
if self.focusedCard and self.focusedCard.id == id:
focused = idx
# avoid further comparisons
self.focusedCard = None
# and focus previously focused or first in selection
focus = focused or first
tv = self.browser.form.tableView
if focus:
tv.selectRow(focus.row())
tv.scrollTo(focus, tv.PositionAtCenter)
sm.select(items, QItemSelectionModel.SelectCurrent |
QItemSelectionModel.Rows)
else:
tv.selectRow(0)
# Column data # Column data
###################################################################### ######################################################################
@ -243,7 +292,6 @@ class Browser(QMainWindow):
self.setupCardInfo() self.setupCardInfo()
self.updateFont() self.updateFont()
self.form.searchEdit.setFocus() self.form.searchEdit.setFocus()
self.updateFilterLabel()
self.show() self.show()
self.form.searchEdit.setText("is:recent") self.form.searchEdit.setText("is:recent")
self.form.searchEdit.selectAll() self.form.searchEdit.selectAll()
@ -297,7 +345,6 @@ class Browser(QMainWindow):
self.mw.config['editFontSize'])) self.mw.config['editFontSize']))
self.form.tableView.verticalHeader().setDefaultSectionSize( self.form.tableView.verticalHeader().setDefaultSectionSize(
self.mw.config['editLineSize']) self.mw.config['editLineSize'])
self.model.reset()
def closeEvent(self, evt): def closeEvent(self, evt):
saveSplitter(self.form.splitter_2, "editor2") saveSplitter(self.form.splitter_2, "editor2")
@ -347,27 +394,17 @@ class Browser(QMainWindow):
self.onSearch) self.onSearch)
self.setTabOrder(self.form.searchEdit, self.form.tableView) self.setTabOrder(self.form.searchEdit, self.form.tableView)
def onSearch(self, force=True): def onSearch(self):
# fixme: txt = unicode(self.form.searchEdit.text()).strip()
# if self.mw.inDbHandler: self.model.search(txt)
# return self.updateTitle()
self.model.searchStr = unicode(self.form.searchEdit.text()) show = not not self.model.cards
self.model.showMatching(force) self.form.cardLabel.setShown(show)
self.updateFilterLabel() self.form.fieldsArea.setShown(show)
self.filterTimer = None if not show:
if self.model.cards:
self.form.cardLabel.show()
self.form.fieldsArea.show()
else:
self.form.cardLabel.hide()
self.form.fieldsArea.hide()
if not self.focusCard():
if self.model.cards:
self.form.tableView.selectRow(0)
if not self.model.cards:
self.editor.setFact(None) self.editor.setFact(None)
def updateFilterLabel(self): def updateTitle(self):
selected = len(self.form.tableView.selectionModel().selectedRows()) selected = len(self.form.tableView.selectionModel().selectedRows())
self.setWindowTitle(ngettext("Browser (%(cur)d " self.setWindowTitle(ngettext("Browser (%(cur)d "
"of %(tot)d card shown; %(sel)s)", "Browser (%(cur)d " "of %(tot)d card shown; %(sel)s)", "Browser (%(cur)d "
@ -389,7 +426,7 @@ class Browser(QMainWindow):
self.form.tableView.selectionModel() self.form.tableView.selectionModel()
self.connect(self.form.tableView.selectionModel(), self.connect(self.form.tableView.selectionModel(),
SIGNAL("selectionChanged(QItemSelection,QItemSelection)"), SIGNAL("selectionChanged(QItemSelection,QItemSelection)"),
self.updateFilterLabel) self.updateTitle)
self.form.tableView.setItemDelegate(StatusDelegate(self, self.model)) self.form.tableView.setItemDelegate(StatusDelegate(self, self.model))
def rowChanged(self, current, previous): def rowChanged(self, current, previous):
@ -410,23 +447,6 @@ class Browser(QMainWindow):
except: except:
return -1 return -1
def focusCard(self):
if self.card:
try:
self.card.id
except:
return False
row = self.cardRow()
if row >= 0:
sm = self.form.tableView.selectionModel()
sm.clear()
self.form.tableView.selectRow(row)
self.form.tableView.scrollTo(
self.model.index(row,0),
self.form.tableView.PositionAtCenter)
return True
return False
# Headers & sorting # Headers & sorting
###################################################################### ######################################################################
@ -444,9 +464,9 @@ class Browser(QMainWindow):
hh.setContextMenuPolicy(Qt.CustomContextMenu) hh.setContextMenuPolicy(Qt.CustomContextMenu)
hh.connect(hh, SIGNAL("customContextMenuRequested(QPoint)"), hh.connect(hh, SIGNAL("customContextMenuRequested(QPoint)"),
self.onHeaderContext) self.onHeaderContext)
self.setSortIndicator()
hh.connect(hh, SIGNAL("sortIndicatorChanged(int, Qt::SortOrder)"), hh.connect(hh, SIGNAL("sortIndicatorChanged(int, Qt::SortOrder)"),
self.onSortChanged) self.onSortChanged)
self.setSortIndicator()
def onSortChanged(self, idx, ord): def onSortChanged(self, idx, ord):
type = self.model.activeCols[idx] type = self.model.activeCols[idx]
@ -458,16 +478,12 @@ class Browser(QMainWindow):
if type not in ("question", "answer", "factFld"): if type not in ("question", "answer", "factFld"):
ord = not ord ord = not ord
self.deck.conf['sortBackwards'] = ord self.deck.conf['sortBackwards'] = ord
self.model.showMatching() self.onSearch()
# fixme: we do this in various locations
self.updateFilterLabel()
self.focusCard()
else: else:
if self.deck.conf['sortBackwards'] != ord: if self.deck.conf['sortBackwards'] != ord:
self.deck.conf['sortBackwards'] = ord self.deck.conf['sortBackwards'] = ord
self.model.cards.reverse() self.model.reverse()
self.setSortIndicator() self.setSortIndicator()
self.model.reset()
def setSortIndicator(self): def setSortIndicator(self):
hh = self.form.tableView.horizontalHeader() hh = self.form.tableView.horizontalHeader()
@ -480,7 +496,9 @@ class Browser(QMainWindow):
ord = Qt.DescendingOrder ord = Qt.DescendingOrder
else: else:
ord = Qt.AscendingOrder ord = Qt.AscendingOrder
hh.blockSignals(True)
hh.setSortIndicator(idx, ord) hh.setSortIndicator(idx, ord)
hh.blockSignals(False)
hh.setSortIndicatorShown(True) hh.setSortIndicatorShown(True)
def onHeaderContext(self, pos): def onHeaderContext(self, pos):
@ -509,7 +527,6 @@ class Browser(QMainWindow):
hh.setResizeMode(c, QHeaderView.Stretch) hh.setResizeMode(c, QHeaderView.Stretch)
else: else:
hh.setResizeMode(c, QHeaderView.Interactive) hh.setResizeMode(c, QHeaderView.Interactive)
self.model.reset()
# Filter tree # Filter tree
###################################################################### ######################################################################
@ -661,7 +678,7 @@ class Browser(QMainWindow):
###################################################################### ######################################################################
def selectedCards(self): def selectedCards(self):
return [self.model.cards[idx.row()][0] for idx in return [self.model.cards[idx.row()] for idx in
self.form.tableView.selectionModel().selectedRows()] self.form.tableView.selectionModel().selectedRows()]
def selectedFacts(self): def selectedFacts(self):
@ -680,7 +697,7 @@ where id in (%s)""" % ",".join([
"Refresh info like stats on current card, and rebuild mw queue." "Refresh info like stats on current card, and rebuild mw queue."
self.currentRow = self.form.tableView.currentIndex() self.currentRow = self.form.tableView.currentIndex()
self.rowChanged(self.currentRow, None) self.rowChanged(self.currentRow, None)
self.model.refresh() self.model.reset()
self.mw.reset() self.mw.reset()
# Menu options # Menu options
@ -757,7 +774,7 @@ where id in (%s)""" % ",".join([
self.deck.suspendCards(self.selectedCards()) self.deck.suspendCards(self.selectedCards())
self.mw.reset() self.mw.reset()
self.deck.setUndoEnd(n) self.deck.setUndoEnd(n)
self.model.refresh() self.model.reset()
self.updateAfterCardChange() self.updateAfterCardChange()
def _onUnsuspend(self): def _onUnsuspend(self):
@ -766,7 +783,7 @@ where id in (%s)""" % ",".join([
self.deck.unsuspendCards(self.selectedCards()) self.deck.unsuspendCards(self.selectedCards())
self.mw.reset() self.mw.reset()
self.deck.setUndoEnd(n) self.deck.setUndoEnd(n)
self.model.refresh() self.model.reset()
self.updateAfterCardChange() self.updateAfterCardChange()
def isMarked(self): def isMarked(self):
@ -887,7 +904,7 @@ where id in %s""" % ids2str(sf))
self.deck.updateProgress() self.deck.updateProgress()
sm.blockSignals(False) sm.blockSignals(False)
self.deck.finishProgress() self.deck.finishProgress()
self.updateFilterLabel() self.updateTitle()
self.updateAfterCardChange() self.updateAfterCardChange()
def invertSelection(self): def invertSelection(self):