Edit Book: When dragging and dropping files to re-order them in the file browser, fix the final order being dependent on the order the files were selected in. Fixes #1440598 [Edit Book: Inverted order of files after drag and drop](https://bugs.launchpad.net/calibre/+bug/1440598)

This commit is contained in:
Kovid Goyal 2015-04-06 11:59:03 +05:30
parent a73d813da4
commit c9cf3066e8

View File

@ -155,6 +155,7 @@ class FileList(QTreeWidget):
def __init__(self, parent=None): def __init__(self, parent=None):
QTreeWidget.__init__(self, parent) QTreeWidget.__init__(self, parent)
self.ordered_selected_indexes = False
pi = plugins['progress_indicator'][0] pi = plugins['progress_indicator'][0]
if hasattr(pi, 'set_no_activate_on_click'): if hasattr(pi, 'set_no_activate_on_click'):
pi.set_no_activate_on_click(self) pi.set_no_activate_on_click(self)
@ -556,23 +557,38 @@ class FileList(QTreeWidget):
b.setValue(b.minimum()) b.setValue(b.minimum())
QTimer.singleShot(0, lambda : b.setValue(b.maximum())) QTimer.singleShot(0, lambda : b.setValue(b.maximum()))
def __enter__(self):
self.ordered_selected_indexes = True
def __exit__(self, *args):
self.ordered_selected_indexes = False
def selectedIndexes(self):
ans = QTreeWidget.selectedIndexes(self)
if self.ordered_selected_indexes:
# The reverse is needed because Qt's implementation of dropEvent
# reverses the selectedIndexes when dropping.
ans = list(sorted(ans, key=lambda idx:idx.row(), reverse=True))
return ans
def dropEvent(self, event): def dropEvent(self, event):
text = self.categories['text'] with self:
pre_drop_order = {text.child(i):i for i in xrange(text.childCount())} text = self.categories['text']
super(FileList, self).dropEvent(event) pre_drop_order = {text.child(i):i for i in xrange(text.childCount())}
current_order = {text.child(i):i for i in xrange(text.childCount())} super(FileList, self).dropEvent(event)
if current_order != pre_drop_order: current_order = {text.child(i):i for i in xrange(text.childCount())}
order = [] if current_order != pre_drop_order:
for child in (text.child(i) for i in xrange(text.childCount())): order = []
name = unicode(child.data(0, NAME_ROLE) or '') for child in (text.child(i) for i in xrange(text.childCount())):
linear = bool(child.data(0, LINEAR_ROLE)) name = unicode(child.data(0, NAME_ROLE) or '')
order.append([name, linear]) linear = bool(child.data(0, LINEAR_ROLE))
# Ensure that all non-linear items are at the end, any non-linear order.append([name, linear])
# items not at the end will be made linear # Ensure that all non-linear items are at the end, any non-linear
for i, (name, linear) in tuple(enumerate(order)): # items not at the end will be made linear
if not linear and i < len(order) - 1 and order[i+1][1]: for i, (name, linear) in tuple(enumerate(order)):
order[i][1] = True if not linear and i < len(order) - 1 and order[i+1][1]:
self.reorder_spine.emit(order) order[i][1] = True
self.reorder_spine.emit(order)
def item_double_clicked(self, item, column): def item_double_clicked(self, item, column):
category = unicode(item.data(0, CATEGORY_ROLE) or '') category = unicode(item.data(0, CATEGORY_ROLE) or '')