diff --git a/src/calibre/gui2/actions/delete.py b/src/calibre/gui2/actions/delete.py
index a0f49a7e9a..24dd1d3e5c 100644
--- a/src/calibre/gui2/actions/delete.py
+++ b/src/calibre/gui2/actions/delete.py
@@ -12,6 +12,7 @@
from calibre.gui2 import error_dialog
from calibre.gui2.dialogs.delete_matching_from_device import DeleteMatchingFromDeviceDialog
from calibre.gui2.dialogs.confirm_delete import confirm
+from calibre.gui2.dialogs.confirm_delete_location import confirm_location
from calibre.gui2.actions import InterfaceAction
single_shot = partial(QTimer.singleShot, 10)
@@ -223,7 +224,31 @@ def delete_books(self, *args):
rows = view.selectionModel().selectedRows()
if not rows or len(rows) == 0:
return
+ # Library view is visible.
if self.gui.stack.currentIndex() == 0:
+ # Ask the user if they want to delete the book from the library or device if it is in both.
+ if self.gui.device_manager.is_device_connected:
+ on_device = False
+ on_device_ids = self._get_selected_ids()
+ for id in on_device_ids:
+ res = self.gui.book_on_device(id)
+ if res[0] or res[1] or res[2]:
+ on_device = True
+ if on_device:
+ break
+ if on_device:
+ loc = confirm_location('
' + _('Some of the selected books are on the attached device. '
+ 'Where do you want the selected files deleted from?'),
+ self.gui)
+ if not loc:
+ return
+ elif loc == 'dev':
+ self.remove_matching_books_from_device()
+ return
+ elif loc == 'both':
+ self.remove_matching_books_from_device()
+ # The following will run if the selected books are not on a connected device.
+ # The user has selected to delete from the library or the device and library.
if not confirm('
'+_('The selected books will be '
'permanently deleted and the files '
'removed from your calibre library. Are you sure?')
@@ -239,7 +264,7 @@ def delete_books(self, *args):
else:
self.__md = MultiDeleter(self.gui, rows,
partial(self.library_ids_deleted, current_row=row))
-
+ # Device view is visible.
else:
if not confirm('
'+_('The selected books will be '
'permanently deleted '
diff --git a/src/calibre/gui2/dialogs/confirm_delete_location.py b/src/calibre/gui2/dialogs/confirm_delete_location.py
new file mode 100644
index 0000000000..b976b936b8
--- /dev/null
+++ b/src/calibre/gui2/dialogs/confirm_delete_location.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+__license__ = 'GPL v3'
+__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' \
+ '2010, John Schember '
+__docformat__ = 'restructuredtext en'
+
+from functools import partial
+
+from calibre.gui2.dialogs.confirm_delete_location_ui import Ui_Dialog
+from PyQt4.Qt import QDialog, Qt, QPixmap, QIcon
+
+class Dialog(QDialog, Ui_Dialog):
+
+ def __init__(self, msg, name, parent):
+ QDialog.__init__(self, parent)
+ self.setupUi(self)
+
+ self.loc = None
+ self.msg.setText(msg)
+ self.name = name
+ self.buttonBox.setFocus(Qt.OtherFocusReason)
+ self.button_lib.clicked.connect(partial(self.set_loc, 'lib'))
+ self.button_device.clicked.connect(partial(self.set_loc, 'dev'))
+ self.button_both.clicked.connect(partial(self.set_loc, 'both'))
+
+ def set_loc(self, loc):
+ self.loc = loc
+ self.accept()
+
+ def choice(self):
+ return self.loc
+
+ def break_cycles(self):
+ for x in ('lib', 'device', 'both'):
+ b = getattr(self, 'button_'+x)
+ try:
+ b.clicked.disconnect()
+ except:
+ pass
+
+
+def confirm_location(msg, name, parent=None, pixmap='dialog_warning.png'):
+ d = Dialog(msg, name, parent)
+ d.label.setPixmap(QPixmap(I(pixmap)))
+ d.setWindowIcon(QIcon(I(pixmap)))
+ d.resize(d.sizeHint())
+ ret = d.exec_()
+ d.break_cycles()
+ if ret == d.Accepted:
+ return d.choice()
+ return None
diff --git a/src/calibre/gui2/dialogs/confirm_delete_location.ui b/src/calibre/gui2/dialogs/confirm_delete_location.ui
new file mode 100644
index 0000000000..9d70388627
--- /dev/null
+++ b/src/calibre/gui2/dialogs/confirm_delete_location.ui
@@ -0,0 +1,116 @@
+
+
+ Dialog
+
+
+
+ 0
+ 0
+ 459
+ 300
+
+
+
+ Where do you want to delete from?
+
+
+
+ :/images/dialog_warning.png:/images/dialog_warning.png
+
+
+ -
+
+
-
+
+
+ :/images/dialog_warning.png
+
+
+
+ -
+
+
+
+
+
+ true
+
+
+
+
+
+ -
+
+
-
+
+
+ Library
+
+
+
+ -
+
+
+ Device
+
+
+
+ -
+
+
+ Library and Device
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Cancel
+
+
+
+
+
+
+
+
+
+
+
+
+ buttonBox
+ accepted()
+ Dialog
+ accept()
+
+
+ 248
+ 254
+
+
+ 157
+ 274
+
+
+
+
+ buttonBox
+ rejected()
+ Dialog
+ reject()
+
+
+ 316
+ 260
+
+
+ 286
+ 274
+
+
+
+
+
diff --git a/src/calibre/gui2/library/views.py b/src/calibre/gui2/library/views.py
index 0e0cc0eec2..a6285c6656 100644
--- a/src/calibre/gui2/library/views.py
+++ b/src/calibre/gui2/library/views.py
@@ -123,8 +123,8 @@ def column_header_context_handler(self, action=None, column=None):
elif action == 'show':
h.setSectionHidden(idx, False)
if h.sectionSize(idx) < 3:
- sz = h.sectionSizeHint(idx)
- h.resizeSection(idx, sz)
+ sz = h.sectionSizeHint(idx)
+ h.resizeSection(idx, sz)
elif action == 'ascending':
self.sortByColumn(idx, Qt.AscendingOrder)
elif action == 'descending':