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
+