From dfaecefed0caed16e6ea22c9be04f86e937e3738 Mon Sep 17 00:00:00 2001 From: Jim Miller Date: Wed, 26 Sep 2018 11:22:01 -0500 Subject: [PATCH] Add view/edit context-menu to formats in editmetadata. --- src/calibre/gui2/actions/edit_metadata.py | 5 ++ src/calibre/gui2/actions/tweak_epub.py | 10 ++++ src/calibre/gui2/metadata/basic_widgets.py | 65 ++++++++++++++++++---- src/calibre/gui2/metadata/single.py | 27 ++++++++- 4 files changed, 94 insertions(+), 13 deletions(-) diff --git a/src/calibre/gui2/actions/edit_metadata.py b/src/calibre/gui2/actions/edit_metadata.py index 79c4fbceff..bcd6f7ef82 100644 --- a/src/calibre/gui2/actions/edit_metadata.py +++ b/src/calibre/gui2/actions/edit_metadata.py @@ -418,6 +418,7 @@ class EditMetadataAction(InterfaceAction): db = self.gui.library_view.model().db changed, rows_to_refresh = edit_metadata(db, row_list, current_row, parent=self.gui, view_slot=self.view_format_callback, + edit_slot=self.edit_format_callback, set_current_callback=self.set_current_callback, editing_multiple=editing_multiple) return changed, rows_to_refresh @@ -435,6 +436,10 @@ class EditMetadataAction(InterfaceAction): db = self.gui.library_view.model().db view.view_format(db.row(id_), fmt) + def edit_format_callback(self, id_, fmt): + edit = self.gui.iactions['Tweak ePub'] + edit.ebook_edit_format(id_, fmt) + def edit_bulk_metadata(self, checked): ''' Edit metadata of selected books in library in bulk. diff --git a/src/calibre/gui2/actions/tweak_epub.py b/src/calibre/gui2/actions/tweak_epub.py index 344ed02205..6650b891b2 100755 --- a/src/calibre/gui2/actions/tweak_epub.py +++ b/src/calibre/gui2/actions/tweak_epub.py @@ -126,6 +126,16 @@ class TweakEpubAction(InterfaceAction): tweakable_fmts = {fmts[0]} fmt = tuple(tweakable_fmts)[0] + self.ebook_edit_format(book_id, fmt) + + def ebook_edit_format(self, book_id, fmt): + ''' + Also called from edit_metadata formats list. In that context, + SUPPORTED check was already done. + ''' + db = self.gui.library_view.model().db + from calibre.gui2.tweak_book import tprefs + tprefs.refresh() # In case they were changed in a Tweak Book process path = db.new_api.format_abspath(book_id, fmt) if path is None: return error_dialog(self.gui, _('File missing'), _( diff --git a/src/calibre/gui2/metadata/basic_widgets.py b/src/calibre/gui2/metadata/basic_widgets.py index bdd5380633..d618cae0d0 100644 --- a/src/calibre/gui2/metadata/basic_widgets.py +++ b/src/calibre/gui2/metadata/basic_widgets.py @@ -40,6 +40,7 @@ from calibre.utils.icu import strcmp from calibre.ptempfile import PersistentTemporaryFile, SpooledTemporaryFile from calibre.gui2.languages import LanguagesEdit as LE from calibre.db import SPOOL_SIZE +from calibre.ebooks.oeb.polish.main import SUPPORTED as EDIT_SUPPORTED OK_COLOR = 'rgba(0, 255, 0, 12%)' ERR_COLOR = 'rgba(255, 0, 0, 12%)' @@ -760,7 +761,6 @@ class Format(QListWidgetItem): self.setToolTip(text) self.setStatusTip(text) - class OrigAction(QAction): restore_fmt = pyqtSignal(object) @@ -773,27 +773,67 @@ class OrigAction(QAction): def _triggered(self): self.restore_fmt.emit(self.fmt) +class ViewAction(QAction): + + view_fmt = pyqtSignal(object) + + def __init__(self, item, parent): + self.item = item + QAction.__init__(self, _('View')+' '+item.ext.upper(), parent) + self.triggered.connect(self._triggered) + + def _triggered(self): + self.view_fmt.emit(self.item) + +class EditAction(QAction): + + edit_fmt = pyqtSignal(object) + + def __init__(self, item, parent): + self.item = item + QAction.__init__(self, _('Edit')+' '+item.ext.upper(), parent) + self.triggered.connect(self._triggered) + + def _triggered(self): + self.edit_fmt.emit(self.item) class FormatList(_FormatList): restore_fmt = pyqtSignal(object) + view_fmt = pyqtSignal(object) + edit_fmt = pyqtSignal(object) def __init__(self, parent): _FormatList.__init__(self, parent) self.setContextMenuPolicy(Qt.DefaultContextMenu) def contextMenuEvent(self, event): + item = self.itemFromIndex(self.currentIndex()) originals = [self.item(x).ext.upper() for x in range(self.count())] originals = [x for x in originals if x.startswith('ORIGINAL_')] - if not originals: - return - self.cm = cm = QMenu(self) - for fmt in originals: - action = OrigAction(fmt, cm) - action.restore_fmt.connect(self.restore_fmt) - cm.addAction(action) - cm.popup(event.globalPos()) - event.accept() + + if item or originals: + self.cm = cm = QMenu(self) + + if item: + action = ViewAction(item, cm) + action.view_fmt.connect(self.view_fmt) + cm.addAction(action) + + if item.ext.upper() in EDIT_SUPPORTED: + action = EditAction(item, cm) + action.edit_fmt.connect(self.edit_fmt) + cm.addAction(action) + + if item and originals: + cm.addSeparator() + + for fmt in originals: + action = OrigAction(fmt, cm) + action.restore_fmt.connect(self.restore_fmt) + cm.addAction(action) + cm.popup(event.globalPos()) + event.accept() def remove_format(self, fmt): for i in range(self.count()): @@ -855,6 +895,8 @@ class FormatsManager(QWidget): self.formats.setAcceptDrops(True) self.formats.formats_dropped.connect(self.formats_dropped) self.formats.restore_fmt.connect(self.restore_fmt) + self.formats.view_fmt.connect(self.show_format) + self.formats.edit_fmt.connect(self.edit_format) self.formats.delete_format.connect(self.remove_format) self.formats.itemDoubleClicked.connect(self.show_format) self.formats.setDragDropMode(self.formats.DropOnly) @@ -984,6 +1026,9 @@ class FormatsManager(QWidget): def show_format(self, item, *args): self.dialog.do_view_format(item.path, item.ext) + def edit_format(self, item, *args): + self.dialog.do_edit_format(item.path, item.ext) + def get_selected_format(self): row = self.formats.currentRow() fmt = self.formats.item(row) diff --git a/src/calibre/gui2/metadata/single.py b/src/calibre/gui2/metadata/single.py index 6020a671e5..fce54737c0 100644 --- a/src/calibre/gui2/metadata/single.py +++ b/src/calibre/gui2/metadata/single.py @@ -51,6 +51,7 @@ class ScrollArea(QScrollArea): class MetadataSingleDialogBase(QDialog): view_format = pyqtSignal(object, object) + edit_format = pyqtSignal(object, object) cc_two_column = tweaks['metadata_single_use_2_cols_for_custom_fields'] one_line_comments_toolbar = False use_toolbutton_for_config_metadata = True @@ -352,6 +353,23 @@ class MetadataSingleDialogBase(QDialog): else: self.view_format.emit(self.book_id, fmt) + def do_edit_format(self, path, fmt): + if self.was_data_edited: + from calibre.gui2.tweak_book import tprefs + tprefs.refresh() # In case they were changed in a Tweak Book process + from calibre.gui2 import question_dialog + if tprefs['update_metadata_from_calibre'] and question_dialog( + self, _('Save Changed Metadata?'), + _("You've changed the metadata for this book." + " Edit book is set to update embedded metadata when opened." + " You need to save your changes for them to be included."), + yes_text=_('&Save'), no_text=_("&Don't Save"), + yes_icon='dot_green.png', no_icon='dot_red.png', + default_yes=False, skip_dialog_name='edit-metadata-save-before-edit-format'): + if self.apply_changes(): + self.was_data_edited = False + self.edit_format.emit(self.book_id, fmt) + def copy_fmt(self, fmt, f): self.db.copy_format_to(self.book_id, fmt, f, index_is_id=True) @@ -644,12 +662,14 @@ class MetadataSingleDialogBase(QDialog): traceback.print_exc() # Dialog use methods {{{ - def start(self, row_list, current_row, view_slot=None, + def start(self, row_list, current_row, view_slot=None, edit_slot=None, set_current_callback=None): self.row_list = row_list self.current_row = current_row if view_slot is not None: self.view_format.connect(view_slot) + if edit_slot is not None: + self.edit_format.connect(edit_slot) self.set_current_callback = set_current_callback self.do_one(apply_changes=False) ret = self.exec_() @@ -706,6 +726,7 @@ class MetadataSingleDialogBase(QDialog): except: pass # Fails if view format was never connected disconnect(self.view_format) + disconnect(self.edit_format) for b in ('next_button', 'prev_button'): x = getattr(self, b, None) if x is not None: @@ -1164,14 +1185,14 @@ editors = {'default': MetadataSingleDialog, 'alt1': MetadataSingleDialogAlt1, 'alt2': MetadataSingleDialogAlt2} -def edit_metadata(db, row_list, current_row, parent=None, view_slot=None, +def edit_metadata(db, row_list, current_row, parent=None, view_slot=None, edit_slot=None, set_current_callback=None, editing_multiple=False): cls = gprefs.get('edit_metadata_single_layout', '') if cls not in editors: cls = 'default' d = editors[cls](db, parent, editing_multiple=editing_multiple) try: - d.start(row_list, current_row, view_slot=view_slot, + d.start(row_list, current_row, view_slot=view_slot, edit_slot=edit_slot, set_current_callback=set_current_callback) return d.changed, d.rows_to_refresh finally: