Allow aborting an in-progress Copy-to_library action. Fixes #1641458 [[Enhancement] Inability to Cancel Calibre Copy Action](https://bugs.launchpad.net/calibre/+bug/1641458)

This commit is contained in:
Kovid Goyal 2016-11-14 14:29:51 +05:30
parent f4f6e5655a
commit c1c86cee0b

View File

@ -98,6 +98,7 @@ class Worker(Thread): # {{{
def __init__(self, ids, db, loc, progress, done, delete_after, add_duplicates):
Thread.__init__(self)
self.was_canceled = False
self.ids = ids
self.processed = set()
self.db = db
@ -105,6 +106,7 @@ class Worker(Thread): # {{{
self.error = None
self.progress = progress
self.done = done
self.left_after_cancel = 0
self.delete_after = delete_after
self.auto_merged_ids = {}
self.add_duplicates = add_duplicates
@ -112,6 +114,9 @@ class Worker(Thread): # {{{
self.check_for_duplicates = not add_duplicates and (prefs['add_formats_to_existing'] or prefs['check_for_dupes_on_ctl'])
self.failed_books = {}
def cancel_processing(self):
self.was_canceled = True
def run(self):
try:
self.doit()
@ -144,6 +149,9 @@ class Worker(Thread): # {{{
def _doit(self, newdb):
for i, x in enumerate(self.ids):
if self.was_canceled:
self.left_after_cancel = len(self.ids) - i
break
try:
self.do_one(i, x, newdb)
except Exception as err:
@ -480,7 +488,7 @@ class CopyToLibraryAction(InterfaceAction):
aname = _('Moving to') if delete_after else _('Copying to')
dtitle = '%s %s'%(aname, os.path.basename(loc))
self.pd = ProgressDialog(dtitle, min=0, max=len(ids)-1,
parent=self.gui, cancelable=False, icon='lt.png')
parent=self.gui, cancelable=True, icon='lt.png')
def progress(idx, title):
self.pd.set_msg(title)
@ -489,8 +497,19 @@ class CopyToLibraryAction(InterfaceAction):
self.worker = Worker(ids, db, loc, Dispatcher(progress),
Dispatcher(self.pd.accept), delete_after, add_duplicates)
self.worker.start()
self.pd.canceled_signal.connect(self.worker.cancel_processing)
self.pd.exec_()
self.pd.canceled_signal.disconnect()
if self.worker.left_after_cancel:
msg = _('The copying process was interrupted. {} books were copied.').format(len(self.worker.processed))
if delete_after:
msg += ' ' + _('No books were deleted from this library.')
msg += ' ' + _('The best way to resume this operation is to re-copy all the books with the option to'
' "Check for duplicates when Copying to Library" in Preferences->Adding books turned on.')
warning_dialog(self.gui, _('Canceled'), msg, show=True)
return
if self.worker.error is not None:
e, tb = self.worker.error