From e5da008e24bb90d257767098dac84ebfdf0a1558 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 10 Apr 2011 17:12:24 -0600 Subject: [PATCH] Add button to edit metadata single to configure metadata downloading --- src/calibre/ebooks/metadata/sources/amazon.py | 3 +- src/calibre/gui2/metadata/single.py | 17 ++++- src/calibre/gui2/preferences/__init__.py | 52 ++++++++----- .../gui2/preferences/metadata_sources.py | 73 +++++++++++++++++-- .../gui2/preferences/metadata_sources.ui | 3 + 5 files changed, 121 insertions(+), 27 deletions(-) diff --git a/src/calibre/ebooks/metadata/sources/amazon.py b/src/calibre/ebooks/metadata/sources/amazon.py index 2ad5bfbacc..24df68e51d 100644 --- a/src/calibre/ebooks/metadata/sources/amazon.py +++ b/src/calibre/ebooks/metadata/sources/amazon.py @@ -284,7 +284,8 @@ class Amazon(Source): capabilities = frozenset(['identify', 'cover']) touched_fields = frozenset(['title', 'authors', 'identifier:amazon', - 'identifier:isbn', 'rating', 'comments', 'publisher', 'pubdate']) + 'identifier:isbn', 'rating', 'comments', 'publisher', 'pubdate', + 'language']) has_html_comments = True supports_gzip_transfer_encoding = True diff --git a/src/calibre/gui2/metadata/single.py b/src/calibre/gui2/metadata/single.py index 175af291f1..7c9dd00734 100644 --- a/src/calibre/gui2/metadata/single.py +++ b/src/calibre/gui2/metadata/single.py @@ -166,6 +166,11 @@ class MetadataSingleDialogBase(ResizableDialog): font.setBold(True) self.fetch_metadata_button.setFont(font) + self.config_metadata_button = QToolButton(self) + self.config_metadata_button.setIcon(QIcon(I('config.png'))) + self.config_metadata_button.clicked.connect(self.configure_metadata) + self.config_metadata_button.setToolTip( + _('Change how calibre downloads metadata')) # }}} @@ -315,6 +320,12 @@ class MetadataSingleDialogBase(ResizableDialog): if d.cover_pixmap is not None: self.cover.current_val = pixmap_to_data(d.cover_pixmap) + def configure_metadata(self): + from calibre.gui2.preferences import show_config_widget + gui = self.parent() + show_config_widget('Sharing', 'Metadata download', parent=self, + gui=gui, never_shutdown=True) + def download_cover(self, *args): from calibre.gui2.metadata.single_download import CoverFetch d = CoverFetch(self.cover.pixmap(), self) @@ -451,7 +462,8 @@ class MetadataSingleDialog(MetadataSingleDialogBase): # {{{ sto = QWidget.setTabOrder sto(self.button_box, self.fetch_metadata_button) - sto(self.fetch_metadata_button, self.title) + sto(self.fetch_metadata_button, self.config_metadata_button) + sto(self.config_metadata_button, self.title) def create_row(row, one, two, three, col=1, icon='forward.png'): ql = BuddyLabel(one) @@ -530,7 +542,8 @@ class MetadataSingleDialog(MetadataSingleDialogBase): # {{{ self.tabs[0].spc_two = QSpacerItem(10, 10, QSizePolicy.Expanding, QSizePolicy.Expanding) l.addItem(self.tabs[0].spc_two, 8, 0, 1, 3) - l.addWidget(self.fetch_metadata_button, 9, 0, 1, 3) + l.addWidget(self.fetch_metadata_button, 9, 0, 1, 2) + l.addWidget(self.config_metadata_button, 9, 2, 1, 1) self.tabs[0].gb2 = gb = QGroupBox(_('Co&mments'), self) gb.l = l = QVBoxLayout() diff --git a/src/calibre/gui2/preferences/__init__.py b/src/calibre/gui2/preferences/__init__.py index b482429504..1669e24059 100644 --- a/src/calibre/gui2/preferences/__init__.py +++ b/src/calibre/gui2/preferences/__init__.py @@ -7,8 +7,9 @@ __docformat__ = 'restructuredtext en' import textwrap -from PyQt4.Qt import QWidget, pyqtSignal, QCheckBox, QAbstractSpinBox, \ - QLineEdit, QComboBox, QVariant, Qt +from PyQt4.Qt import (QWidget, pyqtSignal, QCheckBox, QAbstractSpinBox, + QLineEdit, QComboBox, QVariant, Qt, QIcon, QDialog, QVBoxLayout, + QDialogButtonBox) from calibre.customize.ui import preferences_plugins from calibre.utils.config import ConfigProxy @@ -284,7 +285,14 @@ def get_plugin(category, name): 'No Preferences Plugin with category: %s and name: %s found' % (category, name)) -# Testing {{{ +class ConfigDialog(QDialog): + def set_widget(self, w): self.w = w + def accept(self): + try: + self.restart_required = self.w.commit() + except AbortCommit: + return + QDialog.accept(self) def init_gui(): from calibre.gui2.ui import Main @@ -298,21 +306,24 @@ def init_gui(): gui.initialize(db.library_path, db, None, actions, show_gui=False) return gui -def test_widget(category, name, gui=None): - from PyQt4.Qt import QDialog, QVBoxLayout, QDialogButtonBox - class Dialog(QDialog): - def set_widget(self, w): self.w = w - def accept(self): - try: - self.restart_required = self.w.commit() - except AbortCommit: - return - QDialog.accept(self) +def show_config_widget(category, name, gui=None, show_restart_msg=False, + parent=None, never_shutdown=False): + ''' + Show the preferences plugin identified by category and name + :param gui: gui instance, if None a hidden gui is created + :param show_restart_msg: If True and the preferences plugin indicates a + restart is required, show a message box telling the user to restart + :param parent: The parent of the displayed dialog + + :return: True iff a restart is required for the changes made by the user to + take effect + ''' pl = get_plugin(category, name) - d = Dialog() + d = ConfigDialog(parent) d.resize(750, 550) - d.setWindowTitle(category + " - " + name) + d.setWindowTitle(_('Configure ') + name) + d.setWindowIcon(QIcon(I('config.png'))) bb = QDialogButtonBox(d) bb.setStandardButtons(bb.Apply|bb.Cancel|bb.RestoreDefaults) bb.accepted.connect(d.accept) @@ -335,11 +346,18 @@ def test_widget(category, name, gui=None): w.genesis(gui) w.initialize() d.exec_() - if getattr(d, 'restart_required', False): + rr = getattr(d, 'restart_required', False) + if show_restart_msg and rr: from calibre.gui2 import warning_dialog warning_dialog(gui, 'Restart required', 'Restart required', show=True) - if mygui: + if mygui and not never_shutdown: gui.shutdown() + return rr + +# Testing {{{ + +def test_widget(category, name, gui=None): + show_config_widget(category, name, gui=gui, show_restart_msg=True) def test_all(): from PyQt4.Qt import QApplication diff --git a/src/calibre/gui2/preferences/metadata_sources.py b/src/calibre/gui2/preferences/metadata_sources.py index 66fd35e038..8324684bc8 100644 --- a/src/calibre/gui2/preferences/metadata_sources.py +++ b/src/calibre/gui2/preferences/metadata_sources.py @@ -15,7 +15,7 @@ from calibre.gui2.preferences import ConfigWidgetBase, test_widget from calibre.gui2.preferences.metadata_sources_ui import Ui_Form from calibre.ebooks.metadata.sources.base import msprefs from calibre.customize.ui import (all_metadata_plugins, is_disabled, - enable_plugin, disable_plugin, restore_plugin_state_to_default) + enable_plugin, disable_plugin, default_disabled_plugins) from calibre.gui2 import NONE class SourcesModel(QAbstractTableModel): # {{{ @@ -116,11 +116,11 @@ class SourcesModel(QAbstractTableModel): # {{{ self.cover_overrides = {} def restore_defaults(self): - del msprefs['cover_priorities'] - self.enabled_overrides = {} - self.cover_overrides = {} - for plugin in self.plugins: - restore_plugin_state_to_default(plugin) + self.enabled_overrides = dict([(p, (Qt.Unchecked if p.name in + default_disabled_plugins else Qt.Checked)) for p in self.plugins]) + self.cover_overrides = dict([(p, + msprefs.defaults['cover_priorities'].get(p.name, 1)) + for p in self.plugins]) self.reset() # }}} @@ -131,6 +131,18 @@ class FieldsModel(QAbstractListModel): # {{{ QAbstractTableModel.__init__(self, parent) self.fields = [] + self.descs = { + 'authors': _('Authors'), + 'comments': _('Comments'), + 'pubdate': _('Published date'), + 'publisher': _('Publisher'), + 'rating' : _('Rating'), + 'tags' : _('Tags'), + 'title': _('Title'), + 'series': _('Series'), + 'language': _('Language'), + } + self.overrides = {} def rowCount(self, parent=None): return len(self.fields) @@ -141,10 +153,54 @@ class FieldsModel(QAbstractListModel): # {{{ fields |= p.touched_fields self.fields = [] for x in fields: - if not x.startswith('identifiers:'): + if not x.startswith('identifier:') and x not in ('series_index',): self.fields.append(x) + self.fields.sort(key=lambda x:self.descs.get(x, x)) self.reset() + def state(self, field, defaults=False): + src = msprefs.defaults if defaults else msprefs + return (Qt.Unchecked if field in src['ignore_fields'] + else Qt.Checked) + + def data(self, index, role): + try: + field = self.fields[index.row()] + except: + return None + if role == Qt.DisplayRole: + return self.descs.get(field, field) + if role == Qt.CheckStateRole: + return self.overrides.get(field, self.state(field)) + return NONE + + def flags(self, index): + ans = QAbstractTableModel.flags(self, index) + return ans | Qt.ItemIsUserCheckable + + def restore_defaults(self): + self.overrides = dict([(f, self.state(f, True)) for f in self.fields]) + self.reset() + + def setData(self, index, val, role): + try: + field = self.fields[index.row()] + except: + return False + ret = False + if role == Qt.CheckStateRole: + val, ok = val.toInt() + if ok: + self.overrides[field] = val + ret = True + if ret: + self.dataChanged.emit(index, index) + return ret + + def commit(self): + val = [k for k, v in self.overrides.iteritems() if v == Qt.Unchecked] + msprefs['ignore_fields'] = val + # }}} @@ -173,14 +229,17 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): ConfigWidgetBase.initialize(self) self.sources_model.initialize() self.sources_view.resizeColumnsToContents() + self.fields_model.initialize() def restore_defaults(self): ConfigWidgetBase.restore_defaults(self) self.sources_model.restore_defaults() + self.fields_model.restore_defaults() self.changed_signal.emit() def commit(self): self.sources_model.commit() + self.fields_model.commit() return ConfigWidgetBase.commit(self) if __name__ == '__main__': diff --git a/src/calibre/gui2/preferences/metadata_sources.ui b/src/calibre/gui2/preferences/metadata_sources.ui index 68ac6352cf..546120f628 100644 --- a/src/calibre/gui2/preferences/metadata_sources.ui +++ b/src/calibre/gui2/preferences/metadata_sources.ui @@ -73,6 +73,9 @@ If you uncheck any fields, metadata for those fields will not be downloaded + + QAbstractItemView::NoSelection +