From e4b2729e78112945d4ebcdc08ad8080d86035a54 Mon Sep 17 00:00:00 2001
From: Kovid Goyal
Date: Thu, 12 Aug 2010 19:39:49 -0600
Subject: [PATCH] Edit metadata migrated
---
src/calibre/customize/builtins.py | 6 +-
src/calibre/gui2/actions/__init__.py | 8 +-
src/calibre/gui2/actions/add.py | 2 +-
src/calibre/gui2/actions/edit_metadata.py | 90 +++++++++++++++++------
src/calibre/gui2/actions/view.py | 7 +-
src/calibre/gui2/init.py | 7 +-
src/calibre/gui2/layout.py | 39 ----------
src/calibre/gui2/ui.py | 2 -
8 files changed, 88 insertions(+), 73 deletions(-)
diff --git a/src/calibre/customize/builtins.py b/src/calibre/customize/builtins.py
index 8232a163e7..bdb76a6066 100644
--- a/src/calibre/customize/builtins.py
+++ b/src/calibre/customize/builtins.py
@@ -597,5 +597,9 @@ class ActionDelete(InterfaceActionBase):
name = 'Remove Books'
actual_plugin = 'calibre.gui2.actions.delete:DeleteAction'
+class ActionEditMetadata(InterfaceActionBase):
+ name = 'Edit Metadata'
+ actual_plugin = 'calibre.gui2.actions.delete:EditMetadataAction'
+
plugins += [ActionAdd, ActionFetchAnnotations, ActionGenerateCatalog,
- ActionConvert, ActionDelete]
+ ActionConvert, ActionDelete, ActionEditMetadata]
diff --git a/src/calibre/gui2/actions/__init__.py b/src/calibre/gui2/actions/__init__.py
index b198a69214..4798828074 100644
--- a/src/calibre/gui2/actions/__init__.py
+++ b/src/calibre/gui2/actions/__init__.py
@@ -34,8 +34,10 @@ class InterfaceAction(QObject):
self.create_action()
self.genesis()
- def create_action(self):
- text, icon, tooltip, shortcut = self.action_spec
+ def create_action(self, spec=None, attr='qaction'):
+ if spec is None:
+ spec = self.action_spec
+ text, icon, tooltip, shortcut = spec
if icon is not None:
action = QAction(QIcon(I(icon)), text, self.gui)
else:
@@ -47,7 +49,7 @@ class InterfaceAction(QObject):
action.setAutoRepeat(False)
if shortcut:
action.setShortcut(shortcut)
- self.qaction = action
+ setattr(self, attr, action)
def genesis(self):
pass
diff --git a/src/calibre/gui2/actions/add.py b/src/calibre/gui2/actions/add.py
index 668af0957e..9aa78298dc 100644
--- a/src/calibre/gui2/actions/add.py
+++ b/src/calibre/gui2/actions/add.py
@@ -90,7 +90,7 @@ class AddAction(InterfaceAction):
mi.isbn = x
ids.add(self.gui.library_view.model().db.import_book(mi, []))
self.gui.library_view.model().books_added(len(isbns))
- self.gui.do_download_metadata(ids)
+ self.gui.iactions['Edit Metadata'].do_download_metadata(ids)
def files_dropped(self, paths):
diff --git a/src/calibre/gui2/actions/edit_metadata.py b/src/calibre/gui2/actions/edit_metadata.py
index e4b2145da0..05b4bdf7fc 100644
--- a/src/calibre/gui2/actions/edit_metadata.py
+++ b/src/calibre/gui2/actions/edit_metadata.py
@@ -6,20 +6,64 @@ __copyright__ = '2010, Kovid Goyal '
__docformat__ = 'restructuredtext en'
import os
+from functools import partial
-from PyQt4.Qt import Qt, QTimer
+from PyQt4.Qt import Qt, QTimer, QMenu
from calibre.gui2 import error_dialog, config, warning_dialog
from calibre.gui2.dialogs.metadata_single import MetadataSingleDialog
from calibre.gui2.dialogs.metadata_bulk import MetadataBulkDialog
from calibre.gui2.dialogs.confirm_delete import confirm
from calibre.gui2.dialogs.tag_list_editor import TagListEditor
+from calibre.gui2.actions import InterfaceAction
-class EditMetadataAction(object):
+class EditMetadataAction(InterfaceAction):
+
+ name = 'Edit Metadata'
+ action_spec = (_('Edit metadata'), 'edit_input.svg', None, _('E'))
+
+ def genesis(self):
+ self.create_action(spec=(_('Merge book records'), 'merge_books.svg',
+ None, _('M')), attr='action_merge')
+ md = QMenu()
+ md.addAction(_('Edit metadata individually'),
+ partial(self.edit_metadata, False, bulk=False))
+ md.addSeparator()
+ md.addAction(_('Edit metadata in bulk'),
+ partial(self.edit_metadata, False, bulk=True))
+ md.addSeparator()
+ md.addAction(_('Download metadata and covers'),
+ partial(self.download_metadata, False, covers=True),
+ Qt.ControlModifier+Qt.Key_D)
+ md.addAction(_('Download only metadata'),
+ partial(self.download_metadata, False, covers=False))
+ md.addAction(_('Download only covers'),
+ partial(self.download_metadata, False, covers=True,
+ set_metadata=False, set_social_metadata=False))
+ md.addAction(_('Download only social metadata'),
+ partial(self.download_metadata, False, covers=False,
+ set_metadata=False, set_social_metadata=True))
+ self.metadata_menu = md
+
+ mb = QMenu()
+ mb.addAction(_('Merge into first selected book - delete others'),
+ self.merge_books)
+ mb.addSeparator()
+ mb.addAction(_('Merge into first selected book - keep others'),
+ partial(self.merge_books, safe_merge=True))
+ self.merge_menu = mb
+ self.action_merge.setMenu(mb)
+ md.addSeparator()
+ md.addAction(self.action_merge)
+
+ self.qaction.triggered.connect(self.edit_metadata)
+ self.qaction.setMenu(md)
+ self.action_merge.triggered.connect(self.merge_books)
def location_selected(self, loc):
enabled = loc == 'library'
self.qaction.setEnabled(enabled)
+ self.action_merge.setEnabled(enabled)
def download_metadata(self, checked, covers=True, set_metadata=True,
set_social_metadata=None):
@@ -51,9 +95,9 @@ class EditMetadataAction(object):
x = _('social metadata')
else:
x = _('covers') if covers and not set_metadata else _('metadata')
- self.progress_indicator.start(
+ self.gui.progress_indicator.start(
_('Downloading %s for %d book(s)')%(x, len(ids)))
- self._book_metadata_download_check = QTimer(self)
+ self._book_metadata_download_check = QTimer(self.gui)
self._book_metadata_download_check.timeout.connect(self.book_metadata_download_check,
type=Qt.QueuedConnection)
self._book_metadata_download_check.start(100)
@@ -62,15 +106,15 @@ class EditMetadataAction(object):
if self._download_book_metadata.is_alive():
return
self._book_metadata_download_check.stop()
- self.progress_indicator.stop()
+ self.gui.progress_indicator.stop()
cr = self.gui.library_view.currentIndex().row()
x = self._download_book_metadata
self._download_book_metadata = None
if x.exception is None:
self.gui.library_view.model().refresh_ids(
x.updated, cr)
- if self.cover_flow:
- self.cover_flow.dataChanged()
+ if self.gui.cover_flow:
+ self.gui.cover_flow.dataChanged()
if x.failures:
details = ['%s: %s'%(title, reason) for title,
reason in x.failures.values()]
@@ -102,22 +146,22 @@ class EditMetadataAction(object):
self.gui.library_view.model().refresh_ids([id])
for row in rows:
- self._metadata_view_id = self.gui.library_view.model().db.id(row.row())
- d = MetadataSingleDialog(self, row.row(),
+ self.gui.iactions['View'].metadata_view_id = self.gui.library_view.model().db.id(row.row())
+ d = MetadataSingleDialog(self.gui, row.row(),
self.gui.library_view.model().db,
accepted_callback=accepted,
cancel_all=rows.index(row) < len(rows)-1)
- d.view_format.connect(self.metadata_view_format)
+ d.view_format.connect(self.gui.iactions['View'].metadata_view_format)
d.exec_()
if d.cancel_all:
break
if rows:
current = self.gui.library_view.currentIndex()
m = self.gui.library_view.model()
- if self.cover_flow:
- self.cover_flow.dataChanged()
+ if self.gui.cover_flow:
+ self.gui.cover_flow.dataChanged()
m.current_changed(current, previous)
- self.tags_view.recount()
+ self.gui.tags_view.recount()
def edit_bulk_metadata(self, checked):
'''
@@ -130,20 +174,20 @@ class EditMetadataAction(object):
_('No books selected'))
d.exec_()
return
- if MetadataBulkDialog(self, rows,
+ if MetadataBulkDialog(self.gui, rows,
self.gui.library_view.model().db).changed:
self.gui.library_view.model().resort(reset=False)
self.gui.library_view.model().research()
- self.tags_view.recount()
- if self.cover_flow:
- self.cover_flow.dataChanged()
+ self.gui.tags_view.recount()
+ if self.gui.cover_flow:
+ self.gui.cover_flow.dataChanged()
# Merge books {{{
def merge_books(self, safe_merge=False):
'''
Merge selected books in library.
'''
- if self.stack.currentIndex() != 0:
+ if self.gui.stack.currentIndex() != 0:
return
rows = self.gui.library_view.selectionModel().selectedRows()
if not rows or len(rows) == 0:
@@ -161,7 +205,7 @@ class EditMetadataAction(object):
'The second and subsequently selected books will not '
'be deleted or changed.
'
'Please confirm you want to proceed.')
- +'
', 'merge_books_safe', self):
+ +'', 'merge_books_safe', self.gui):
return
self.add_formats(dest_id, src_books)
self.merge_metadata(dest_id, src_ids)
@@ -175,12 +219,12 @@ class EditMetadataAction(object):
'and any duplicate formats in the second and subsequently selected books '
'will be permanently deleted from your computer.
'
'Are you sure you want to proceed?')
- +'', 'merge_books', self):
+ +'', 'merge_books', self.gui):
return
if len(rows)>5:
if not confirm(''+_('You are about to merge more than 5 books. '
'Are you sure you want to proceed?')
- +'
', 'merge_too_many_books', self):
+ +'', 'merge_too_many_books', self.gui):
return
self.add_formats(dest_id, src_books)
self.merge_metadata(dest_id, src_ids)
@@ -299,7 +343,7 @@ class EditMetadataAction(object):
model = view.model()
result = model.get_collections_with_ids()
compare = (lambda x,y:cmp(x.lower(), y.lower()))
- d = TagListEditor(self, tag_to_match=None, data=result, compare=compare)
+ d = TagListEditor(self.gui, tag_to_match=None, data=result, compare=compare)
d.exec_()
if d.result() == d.Accepted:
to_rename = d.to_rename # dict of new text to old ids
@@ -309,7 +353,7 @@ class EditMetadataAction(object):
model.rename_collection(old_id, new_name=unicode(text))
for item in to_delete:
model.delete_collection_using_id(item)
- self.upload_collections(model.db, view=view, oncard=oncard)
+ self.gui.upload_collections(model.db, view=view, oncard=oncard)
view.reset()
diff --git a/src/calibre/gui2/actions/view.py b/src/calibre/gui2/actions/view.py
index bdad55d142..4a6e545da6 100644
--- a/src/calibre/gui2/actions/view.py
+++ b/src/calibre/gui2/actions/view.py
@@ -18,6 +18,11 @@ from calibre.ptempfile import PersistentTemporaryFile
class ViewAction(object):
+ name = 'View'
+
+ def genesis(self):
+ self.metadata_view_id = None
+
def location_selected(self, loc):
enabled = loc == 'library'
for action in list(self.view_menu.actions())[1:]:
@@ -36,7 +41,7 @@ class ViewAction(object):
def metadata_view_format(self, fmt):
fmt_path = self.gui.library_view.model().db.\
- format_abspath(self._metadata_view_id,
+ format_abspath(self.metadata_view_id,
fmt, index_is_id=True)
if fmt_path:
self._view_file(fmt_path)
diff --git a/src/calibre/gui2/init.py b/src/calibre/gui2/init.py
index 7f8ad2d23c..359ea7465c 100644
--- a/src/calibre/gui2/init.py
+++ b/src/calibre/gui2/init.py
@@ -66,8 +66,9 @@ class LibraryViewMixin(object): # {{{
add_to_library = (_('Add books to library'),
self.iactions['Add Books'].add_books_from_device)
+ edc = self.iactions['Edit Metadata'].edit_device_collections
edit_device_collections = (_('Manage collections'),
- partial(self.edit_device_collections, oncard=None))
+ partial(edc, oncard=None))
self.memory_view.set_context_menu(None, None, None,
self.action_view, self.action_save, None, None,
self.action_del, None,
@@ -75,7 +76,7 @@ class LibraryViewMixin(object): # {{{
edit_device_collections=edit_device_collections)
edit_device_collections = (_('Manage collections'),
- partial(self.edit_device_collections, oncard='carda'))
+ partial(edc, oncard='carda'))
self.card_a_view.set_context_menu(None, None, None,
self.action_view, self.action_save, None, None,
self.action_del, None,
@@ -83,7 +84,7 @@ class LibraryViewMixin(object): # {{{
edit_device_collections=edit_device_collections)
edit_device_collections = (_('Manage collections'),
- partial(self.edit_device_collections, oncard='cardb'))
+ partial(edc, oncard='cardb'))
self.card_b_view.set_context_menu(None, None, None,
self.action_view, self.action_save, None, None,
self.action_del, None,
diff --git a/src/calibre/gui2/layout.py b/src/calibre/gui2/layout.py
index 74da5f53d3..582818a593 100644
--- a/src/calibre/gui2/layout.py
+++ b/src/calibre/gui2/layout.py
@@ -459,10 +459,6 @@ class MainWindowMixin(object):
setattr(self, 'action_'+name, action)
all_actions.append(action)
- ac(0, 0, 0, 'add', _('Add books'), 'add_book.svg', _('A'))
- ac(1, 1, 0, 'edit', _('Edit metadata'), 'edit_input.svg', _('E'))
- ac(2, 2, 3, 'convert', _('Convert books'), 'convert.svg', _('C'))
- ac(3, 3, 0, 'view', _('View'), 'view.svg', _('V'))
ac(-1, 4, 0, 'sync', _('Send to device'), 'sync.svg')
ac(5, 5, 3, 'choose_library', _('%d books')%0, 'lt.png',
tooltip=_('Choose calibre library to work with'))
@@ -473,7 +469,6 @@ class MainWindowMixin(object):
ac(10, 10, 3, 'help', _('Help'), 'help.svg', _('F1'), _("Browse the calibre User Manual"))
ac(11, 11, 0, 'preferences', _('Preferences'), 'config.svg', _('Ctrl+P'))
- ac(-1, -1, 0, 'merge', _('Merge book records'), 'merge_books.svg', _('M'))
ac(-1, -1, 0, 'open_containing_folder', _('Open containing folder'),
'document_open.svg')
ac(-1, -1, 0, 'show_book_details', _('Show book details'),
@@ -497,39 +492,6 @@ class MainWindowMixin(object):
self.action_conn_share.setMenu(self.share_conn_menu)
self.action_help.triggered.connect(self.show_help)
- md = QMenu()
- md.addAction(_('Edit metadata individually'),
- partial(self.edit_metadata, False, bulk=False))
- md.addSeparator()
- md.addAction(_('Edit metadata in bulk'),
- partial(self.edit_metadata, False, bulk=True))
- md.addSeparator()
- md.addAction(_('Download metadata and covers'),
- partial(self.download_metadata, False, covers=True),
- Qt.ControlModifier+Qt.Key_D)
- md.addAction(_('Download only metadata'),
- partial(self.download_metadata, False, covers=False))
- md.addAction(_('Download only covers'),
- partial(self.download_metadata, False, covers=True,
- set_metadata=False, set_social_metadata=False))
- md.addAction(_('Download only social metadata'),
- partial(self.download_metadata, False, covers=False,
- set_metadata=False, set_social_metadata=True))
- self.metadata_menu = md
-
- mb = QMenu()
- mb.addAction(_('Merge into first selected book - delete others'),
- self.merge_books)
- mb.addSeparator()
- mb.addAction(_('Merge into first selected book - keep others'),
- partial(self.merge_books, safe_merge=True))
- self.merge_menu = mb
- self.action_merge.setMenu(mb)
- md.addSeparator()
- md.addAction(self.action_merge)
-
- self.action_edit.triggered.connect(self.edit_metadata)
- self.action_merge.triggered.connect(self.merge_books)
self.action_save.triggered.connect(self.save_to_disk)
self.save_menu = QMenu()
@@ -566,7 +528,6 @@ class MainWindowMixin(object):
self.action_sync.triggered.connect(
self._sync_action_triggered)
- self.action_edit.setMenu(md)
self.action_save.setMenu(self.save_menu)
diff --git a/src/calibre/gui2/ui.py b/src/calibre/gui2/ui.py
index df0c9091b5..80165ec515 100644
--- a/src/calibre/gui2/ui.py
+++ b/src/calibre/gui2/ui.py
@@ -439,12 +439,10 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, # {{{
for action in self.iactions.values():
action.location_selected(location)
if location == 'library':
- self.action_merge.setEnabled(True)
self.action_open_containing_folder.setEnabled(True)
self.action_sync.setEnabled(True)
self.search_restriction.setEnabled(True)
else:
- self.action_merge.setEnabled(False)
self.action_open_containing_folder.setEnabled(False)
self.action_sync.setEnabled(False)
self.search_restriction.setEnabled(False)