Optimization of model manipulation code.

This commit is contained in:
Kovid Goyal 2007-08-07 19:09:32 +00:00
parent 6b7af60e4b
commit 55602e7daf
3 changed files with 52 additions and 57 deletions

View File

@ -109,7 +109,6 @@ class BooksModel(QAbstractTableModel):
self.beginRemoveRows(QModelIndex(), row, row) self.beginRemoveRows(QModelIndex(), row, row)
self.db.delete_book(id) self.db.delete_book(id)
self.endRemoveRows() self.endRemoveRows()
self.emit(SIGNAL('deleted()'))
def search_tokens(self, text): def search_tokens(self, text):
tokens = [] tokens = []
@ -127,28 +126,28 @@ class BooksModel(QAbstractTableModel):
continue continue
return ans return ans
def search(self, text, refinement, reset=True):
def search(self, text, refinement):
tokens = self.search_tokens(text) tokens = self.search_tokens(text)
self.db.filter(tokens, refinement) self.db.filter(tokens, refinement)
self.last_search = text self.last_search = text
self.reset() if reset:
self.reset()
def sort(self, col, order): def sort(self, col, order, reset=True):
if not self.db: if not self.db:
return return
ascending = order == Qt.AscendingOrder ascending = order == Qt.AscendingOrder
self.db.refresh(self.cols[col], ascending) self.db.refresh(self.cols[col], ascending)
self.research() self.research()
self.reset() if reset:
self.reset()
self.sorted_on = (col, order) self.sorted_on = (col, order)
def resort(self): def resort(self, reset=True):
self.sort(*self.sorted_on) self.sort(*self.sorted_on, **dict(reset=reset))
def research(self): def research(self, reset=True):
self.search(self.last_search, False) self.search(self.last_search, False, reset=reset)
def database_needs_migration(self): def database_needs_migration(self):
path = os.path.expanduser('~/library.db') path = os.path.expanduser('~/library.db')
@ -336,30 +335,17 @@ class BooksView(QTableView):
self.setSelectionBehavior(QAbstractItemView.SelectRows) self.setSelectionBehavior(QAbstractItemView.SelectRows)
self.setSortingEnabled(True) self.setSortingEnabled(True)
self.setItemDelegateForColumn(4, LibraryDelegate(self)) self.setItemDelegateForColumn(4, LibraryDelegate(self))
QObject.connect(self._model, SIGNAL('modelReset()'), self.resizeRowsToContents)
QObject.connect(self._model, SIGNAL('deleted()'), self.deleted)
QObject.connect(self._model, SIGNAL('update_current()'), self.update_current)
QObject.connect(self.selectionModel(), SIGNAL('currentRowChanged(QModelIndex, QModelIndex)'), QObject.connect(self.selectionModel(), SIGNAL('currentRowChanged(QModelIndex, QModelIndex)'),
self._model.current_changed) self._model.current_changed)
#self.verticalHeader().setVisible(False) # Adding and removing rows should resize rows to contents
QObject.connect(self.model(), SIGNAL('rowsRemoved(QModelIndex, int, int)'), self.resizeRowsToContents)
QObject.connect(self.model(), SIGNAL('rowsInserted(QModelIndex, int, int)'), self.resizeRowsToContents)
# Resetting the model should resize rows (model is reset after search and sort operations)
QObject.connect(self.model(), SIGNAL('modelReset()'), self.resizeRowsToContents)
def set_database(self, db): def set_database(self, db):
self._model.set_database(db) self._model.set_database(db)
def update_current(self):
'''
Clear selection and update durrent index.
'''
cidx = self.currentIndex()
self.selectionModel().clear()
for idx in self.model().row_indices(cidx):
self.selectionModel().select(idx, QItemSelectionModel.Select)
self.selectionModel().setCurrentIndex(cidx, QItemSelectionModel.NoUpdate)
def deleted(self):
self.resizeRowsToContents()
self.update_current()
def migrate_database(self): def migrate_database(self):
if self._model.database_needs_migration(): if self._model.database_needs_migration():
print 'Migrating database from pre 0.4.0 version' print 'Migrating database from pre 0.4.0 version'
@ -426,15 +412,19 @@ class DeviceBooksModel(BooksModel):
for row in rows: for row in rows:
if not succeeded: if not succeeded:
indices = self.row_indices(self.index(row, 0)) indices = self.row_indices(self.index(row, 0))
self.emit(SIGNAL('dataChanged(QModelIndex, QModelIndex)'), indices[0], indices[-1]) self.emit(SIGNAL('dataChanged(QModelIndex, QModelIndex)'), indices[0], indices[-1])
def path_about_to_be_deleted(self, path):
for row in range(len(self.map)):
if self.db[self.map[row]].path == path:
print row, path
self.beginRemoveRows(QModelIndex(), row, row)
self.map.pop(row)
return
def path_deleted(self):
self.endRemoveRows()
def remap(self):
self.set_database(self.db)
self.resort()
self.research()
self.emit(SIGNAL('update_current()'))
def indices_to_be_deleted(self): def indices_to_be_deleted(self):
ans = [] ans = []
for v in self.marked_for_deletion.values(): for v in self.marked_for_deletion.values():
@ -447,7 +437,7 @@ class DeviceBooksModel(BooksModel):
return BooksModel.flags(self, index) return BooksModel.flags(self, index)
def search(self, text, refinement): def search(self, text, refinement, reset=True):
tokens = self.search_tokens(text) tokens = self.search_tokens(text)
base = self.map if refinement else self.sorted_map base = self.map if refinement else self.sorted_map
result = [] result = []
@ -462,9 +452,10 @@ class DeviceBooksModel(BooksModel):
result.append(i) result.append(i)
self.map = result self.map = result
self.reset() if reset:
self.reset()
def sort(self, col, order): def sort(self, col, order, reset=True):
if not self.db: if not self.db:
return return
descending = order != Qt.AscendingOrder descending = order != Qt.AscendingOrder
@ -496,7 +487,8 @@ class DeviceBooksModel(BooksModel):
self.sorted_map = list(range(len(self.db))) self.sorted_map = list(range(len(self.db)))
self.sorted_map.sort(cmp=fcmp, reverse=descending) self.sorted_map.sort(cmp=fcmp, reverse=descending)
self.sorted_on = (col, order) self.sorted_on = (col, order)
self.reset() if reset:
self.reset()
def columnCount(self, parent): def columnCount(self, parent):
return 4 return 4
@ -600,7 +592,7 @@ class SearchBox(QLineEdit):
def __init__(self, parent): def __init__(self, parent):
QLineEdit.__init__(self, parent) QLineEdit.__init__(self, parent)
self.help_text = 'Search by title, author, publisher, tags and comments' self.help_text = 'Search by title, author, publisher, tags, series and comments'
self.initial_state = True self.initial_state = True
self.default_palette = QApplication.palette(self) self.default_palette = QApplication.palette(self)
self.gray = QPalette(self.default_palette) self.gray = QPalette(self.default_palette)

View File

@ -262,13 +262,13 @@ class Main(QObject, Ui_MainWindow):
files, names, on_card=on_card, files, names, on_card=on_card,
job_extra_description=titles job_extra_description=titles
) )
self.upload_memory[id] = metadata self.upload_memory[id] = (metadata, on_card)
def books_uploaded(self, id, description, result, exception, formatted_traceback): def books_uploaded(self, id, description, result, exception, formatted_traceback):
''' '''
Called once books have been uploaded. Called once books have been uploaded.
''' '''
metadata = self.upload_memory.pop(id) metadata, on_card = self.upload_memory.pop(id)
if exception: if exception:
if isinstance(exception, FreeSpaceError): if isinstance(exception, FreeSpaceError):
where = 'in main memory.' if 'memory' in str(exception) else 'on the storage card.' where = 'in main memory.' if 'memory' in str(exception) else 'on the storage card.'
@ -285,9 +285,9 @@ class Main(QObject, Ui_MainWindow):
self.upload_booklists() self.upload_booklists()
for view in (self.memory_view, self.card_view): view = self.card_view if on_card else self.memory_view
view.model().resort() view.model().resort(reset=False)
view.model().research() view.model().research()
############################################################################ ############################################################################
@ -307,7 +307,7 @@ class Main(QObject, Ui_MainWindow):
view = self.memory_view if self.stack.currentIndex() == 1 else self.card_view view = self.memory_view if self.stack.currentIndex() == 1 else self.card_view
paths = view.model().paths(rows) paths = view.model().paths(rows)
id = self.remove_paths(paths) id = self.remove_paths(paths)
self.delete_memory[id] = paths self.delete_memory[id] = (paths, view.model())
view.model().mark_for_deletion(id, rows) view.model().mark_for_deletion(id, rows)
self.status_bar.showMessage('Deleting books from device.', 1000) self.status_bar.showMessage('Deleting books from device.', 1000)
@ -329,11 +329,12 @@ class Main(QObject, Ui_MainWindow):
self.upload_booklists() self.upload_booklists()
if self.delete_memory.has_key(id): if self.delete_memory.has_key(id):
paths = self.delete_memory.pop(id) paths, model = self.delete_memory.pop(id)
self.device_manager.remove_books_from_metadata(paths, self.booklists()) for path in paths:
model.path_about_to_be_deleted(path)
for view in (self.memory_view, self.card_view): self.device_manager.remove_books_from_metadata((path,), self.booklists())
view.model().remap() model.path_deleted()
############################################################################ ############################################################################
@ -354,7 +355,7 @@ class Main(QObject, Ui_MainWindow):
changed = True changed = True
if changed: if changed:
self.library_view.model().resort() self.library_view.model().resort(reset=False)
self.library_view.model().research() self.library_view.model().research()
def edit_bulk_metadata(self, checked): def edit_bulk_metadata(self, checked):
@ -367,7 +368,7 @@ class Main(QObject, Ui_MainWindow):
d.exec_() d.exec_()
return return
if MetadataBulkDialog(self.window, rows, self.library_view.model().db).changed: if MetadataBulkDialog(self.window, rows, self.library_view.model().db).changed:
self.library_view.model().resort() self.library_view.model().resort(reset=False)
self.library_view.model().research() self.library_view.model().research()
############################################################################ ############################################################################
@ -436,7 +437,6 @@ class Main(QObject, Ui_MainWindow):
view.resize_on_select = False view.resize_on_select = False
self.status_bar.reset_info() self.status_bar.reset_info()
self.current_view().clearSelection() self.current_view().clearSelection()
self.current_view().setCurrentIndex(self.current_view().model().index(0, 0))
def wrap_traceback(self, tb): def wrap_traceback(self, tb):

View File

@ -344,7 +344,10 @@
<iconset resource="images.qrc" >:/images/trash.svg</iconset> <iconset resource="images.qrc" >:/images/trash.svg</iconset>
</property> </property>
<property name="text" > <property name="text" >
<string>Delete books</string> <string>Remove books</string>
</property>
<property name="toolTip" >
<string>Remove books</string>
</property> </property>
<property name="shortcut" > <property name="shortcut" >
<string>Del</string> <string>Del</string>