When running multiple delete from device jobs, fix the device view sometimes marking the wrong books as being deleted, after the first delete job completes. Fixes #927972 (Wrong books are marked (visually) for deletion from device when deleting multiple times)

This commit is contained in:
Kovid Goyal 2012-02-08 15:35:31 +05:30
parent b0d13adba7
commit 1ab1a847bd

View File

@ -1073,19 +1073,40 @@ class DeviceBooksModel(BooksModel): # {{{
self.book_in_library = None self.book_in_library = None
def mark_for_deletion(self, job, rows, rows_are_ids=False): def mark_for_deletion(self, job, rows, rows_are_ids=False):
db_indices = rows if rows_are_ids else self.indices(rows)
db_items = [self.db[i] for i in db_indices if -1 < i < len(self.db)]
self.marked_for_deletion[job] = db_items
if rows_are_ids: if rows_are_ids:
self.marked_for_deletion[job] = rows
self.reset() self.reset()
else: else:
self.marked_for_deletion[job] = self.indices(rows)
for row in rows: for row in rows:
indices = self.row_indices(row) indices = self.row_indices(row)
self.dataChanged.emit(indices[0], indices[-1]) self.dataChanged.emit(indices[0], indices[-1])
def find_item_in_db(self, item):
idx = None
try:
idx = self.db.index(item)
except:
path = getattr(item, 'path', None)
if path:
for i, x in enumerate(self.db):
if getattr(x, 'path', None) == path:
idx = i
break
return idx
def deletion_done(self, job, succeeded=True): def deletion_done(self, job, succeeded=True):
if not self.marked_for_deletion.has_key(job): db_items = self.marked_for_deletion.pop(job, [])
return rows = []
rows = self.marked_for_deletion.pop(job) for item in db_items:
idx = self.find_item_in_db(item)
if idx is not None:
try:
rows.append(self.map.index(idx))
except ValueError:
pass
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))
@ -1096,11 +1117,18 @@ class DeviceBooksModel(BooksModel): # {{{
self.resort(False) self.resort(False)
self.research(True) self.research(True)
def indices_to_be_deleted(self): def is_row_marked_for_deletion(self, row):
ans = [] try:
for v in self.marked_for_deletion.values(): item = self.db[self.map[row]]
ans.extend(v) except IndexError:
return ans return False
path = getattr(item, 'path', None)
for items in self.marked_for_deletion.itervalues():
for x in items:
if x is item or (path and path == getattr(x, 'path', None)):
return True
return False
def clear_ondevice(self, db_ids, to_what=None): def clear_ondevice(self, db_ids, to_what=None):
for data in self.db: for data in self.db:
@ -1112,8 +1140,8 @@ class DeviceBooksModel(BooksModel): # {{{
self.reset() self.reset()
def flags(self, index): def flags(self, index):
if self.map[index.row()] in self.indices_to_be_deleted(): if self.is_row_marked_for_deletion(index.row()):
return Qt.ItemIsUserCheckable # Can't figure out how to get the disabled flag in python return Qt.NoItemFlags
flags = QAbstractTableModel.flags(self, index) flags = QAbstractTableModel.flags(self, index)
if index.isValid(): if index.isValid():
cname = self.column_map[index.column()] cname = self.column_map[index.column()]
@ -1347,7 +1375,7 @@ class DeviceBooksModel(BooksModel): # {{{
elif DEBUG and cname == 'inlibrary': elif DEBUG and cname == 'inlibrary':
return QVariant(self.db[self.map[row]].in_library) return QVariant(self.db[self.map[row]].in_library)
elif role == Qt.ToolTipRole and index.isValid(): elif role == Qt.ToolTipRole and index.isValid():
if self.map[row] in self.indices_to_be_deleted(): if self.is_row_marked_for_deletion(row):
return QVariant(_('Marked for deletion')) return QVariant(_('Marked for deletion'))
if cname in ['title', 'authors'] or (cname == 'collections' and \ if cname in ['title', 'authors'] or (cname == 'collections' and \
self.db.supports_collections()): self.db.supports_collections()):