diff --git a/src/calibre/gui2/actions/delete.py b/src/calibre/gui2/actions/delete.py index 6eb45e3123..538af5a3aa 100644 --- a/src/calibre/gui2/actions/delete.py +++ b/src/calibre/gui2/actions/delete.py @@ -121,15 +121,17 @@ class DeleteAction(InterfaceActionWithLibraryDrop): for action in list(self.delete_menu.actions())[1:]: action.setEnabled(enabled) - def _get_selected_formats(self, msg, ids, exclude=False, single=False): + def _get_selected_formats(self, msg, ids, exclude=False, single=False, add_cover=False): from calibre.gui2.dialogs.select_formats import SelectFormats c = Counter() db = self.gui.library_view.model().db - for x in ids: - fmts_ = db.formats(x, index_is_id=True, verify_formats=False) + for book_id in ids: + fmts_ = db.formats(book_id, index_is_id=True, verify_formats=False) if fmts_: for x in frozenset(x.lower() for x in fmts_.split(',')): c[x] += 1 + if add_cover and db.new_api.field_for('cover', book_id, default_value=False): + c['..cover..'] += 1 d = SelectFormats(c, msg, parent=self.gui, exclude=exclude, single=single) if d.exec() != QDialog.DialogCode.Accepted: diff --git a/src/calibre/gui2/actions/save_to_disk.py b/src/calibre/gui2/actions/save_to_disk.py index 038ccd8ca2..39bddad3e3 100644 --- a/src/calibre/gui2/actions/save_to_disk.py +++ b/src/calibre/gui2/actions/save_to_disk.py @@ -63,10 +63,11 @@ class SaveToDiskAction(InterfaceAction): return fmts = rb._get_selected_formats( _('Choose format to save to disk'), ids, - single=True) + single=True, add_cover=True) if not fmts: return - self.save_to_disk(False, False, list(fmts)[0]) + fmt = list(fmts)[0] + self.save_to_disk(False, False, fmt) def save_to_single_dir(self, checked): self.save_to_disk(checked, True) @@ -107,7 +108,10 @@ class SaveToDiskAction(InterfaceAction): opts.to_lowercase = False opts.save_cover = False opts.write_opf = False + opts.save_extra_files = False opts.template = opts.send_template + elif single_format == '..cover..': + opts.save_cover = True opts.single_dir = single_dir if write_opf is not None: opts.write_opf = write_opf diff --git a/src/calibre/gui2/dialogs/select_formats.py b/src/calibre/gui2/dialogs/select_formats.py index 49ec4fd96b..b23a5d8498 100644 --- a/src/calibre/gui2/dialogs/select_formats.py +++ b/src/calibre/gui2/dialogs/select_formats.py @@ -27,12 +27,20 @@ class Formats(QAbstractListModel): if role == Qt.ItemDataRole.DisplayRole: fmt = self.fmts[row] count = self.counts[fmt] - return ('%s [%d]'%(fmt.upper(), count)) + if fmt == '..cover..': + fmt = _('Book cover') + else: + fmt = fmt.upper() + return f'{fmt} [{count}]' if role == Qt.ItemDataRole.DecorationRole: return (self.fi.icon_from_ext(self.fmts[row].lower())) if role == Qt.ItemDataRole.ToolTipRole: fmt = self.fmts[row] count = self.counts[fmt] + if fmt == '..cover..': + if count == 1: + return _('There is only one book with a cover') + return _('There are {} books with a cover').format(count) return _('There is one book with the {} format').format(fmt.upper()) if count == 1 else _( 'There are {count} books with the {fmt} format').format( count=count, fmt=fmt.upper()) diff --git a/src/calibre/gui2/save.py b/src/calibre/gui2/save.py index b21dde9b93..3649b1abb3 100644 --- a/src/calibre/gui2/save.py +++ b/src/calibre/gui2/save.py @@ -213,11 +213,14 @@ class Saver(QObject): base_path = os.path.join(self.root, *components) base_dir = os.path.dirname(base_path) if self.opts.formats and self.opts.formats != 'all': - asked_formats = {x.lower().strip() for x in self.opts.formats.split(',')} - fmts = asked_formats.intersection(fmts) - if not fmts: - self.errors[book_id].append(('critical', _('Requested formats not available'))) - return + if self.opts.formats == '..cover..': + fmts = set() + else: + asked_formats = {x.lower().strip() for x in self.opts.formats.split(',')} + fmts = asked_formats.intersection(fmts) + if not fmts: + self.errors[book_id].append(('critical', _('Requested formats not available'))) + return extra_files = {} if self.opts.save_extra_files: