mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Add button to edit metadata single to configure metadata downloading
This commit is contained in:
parent
ecf79847f9
commit
e5da008e24
@ -284,7 +284,8 @@ class Amazon(Source):
|
|||||||
|
|
||||||
capabilities = frozenset(['identify', 'cover'])
|
capabilities = frozenset(['identify', 'cover'])
|
||||||
touched_fields = frozenset(['title', 'authors', 'identifier:amazon',
|
touched_fields = frozenset(['title', 'authors', 'identifier:amazon',
|
||||||
'identifier:isbn', 'rating', 'comments', 'publisher', 'pubdate'])
|
'identifier:isbn', 'rating', 'comments', 'publisher', 'pubdate',
|
||||||
|
'language'])
|
||||||
has_html_comments = True
|
has_html_comments = True
|
||||||
supports_gzip_transfer_encoding = True
|
supports_gzip_transfer_encoding = True
|
||||||
|
|
||||||
|
@ -166,6 +166,11 @@ class MetadataSingleDialogBase(ResizableDialog):
|
|||||||
font.setBold(True)
|
font.setBold(True)
|
||||||
self.fetch_metadata_button.setFont(font)
|
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:
|
if d.cover_pixmap is not None:
|
||||||
self.cover.current_val = pixmap_to_data(d.cover_pixmap)
|
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):
|
def download_cover(self, *args):
|
||||||
from calibre.gui2.metadata.single_download import CoverFetch
|
from calibre.gui2.metadata.single_download import CoverFetch
|
||||||
d = CoverFetch(self.cover.pixmap(), self)
|
d = CoverFetch(self.cover.pixmap(), self)
|
||||||
@ -451,7 +462,8 @@ class MetadataSingleDialog(MetadataSingleDialogBase): # {{{
|
|||||||
|
|
||||||
sto = QWidget.setTabOrder
|
sto = QWidget.setTabOrder
|
||||||
sto(self.button_box, self.fetch_metadata_button)
|
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'):
|
def create_row(row, one, two, three, col=1, icon='forward.png'):
|
||||||
ql = BuddyLabel(one)
|
ql = BuddyLabel(one)
|
||||||
@ -530,7 +542,8 @@ class MetadataSingleDialog(MetadataSingleDialogBase): # {{{
|
|||||||
self.tabs[0].spc_two = QSpacerItem(10, 10, QSizePolicy.Expanding,
|
self.tabs[0].spc_two = QSpacerItem(10, 10, QSizePolicy.Expanding,
|
||||||
QSizePolicy.Expanding)
|
QSizePolicy.Expanding)
|
||||||
l.addItem(self.tabs[0].spc_two, 8, 0, 1, 3)
|
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)
|
self.tabs[0].gb2 = gb = QGroupBox(_('Co&mments'), self)
|
||||||
gb.l = l = QVBoxLayout()
|
gb.l = l = QVBoxLayout()
|
||||||
|
@ -7,8 +7,9 @@ __docformat__ = 'restructuredtext en'
|
|||||||
|
|
||||||
import textwrap
|
import textwrap
|
||||||
|
|
||||||
from PyQt4.Qt import QWidget, pyqtSignal, QCheckBox, QAbstractSpinBox, \
|
from PyQt4.Qt import (QWidget, pyqtSignal, QCheckBox, QAbstractSpinBox,
|
||||||
QLineEdit, QComboBox, QVariant, Qt
|
QLineEdit, QComboBox, QVariant, Qt, QIcon, QDialog, QVBoxLayout,
|
||||||
|
QDialogButtonBox)
|
||||||
|
|
||||||
from calibre.customize.ui import preferences_plugins
|
from calibre.customize.ui import preferences_plugins
|
||||||
from calibre.utils.config import ConfigProxy
|
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' %
|
'No Preferences Plugin with category: %s and name: %s found' %
|
||||||
(category, name))
|
(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():
|
def init_gui():
|
||||||
from calibre.gui2.ui import Main
|
from calibre.gui2.ui import Main
|
||||||
@ -298,21 +306,24 @@ def init_gui():
|
|||||||
gui.initialize(db.library_path, db, None, actions, show_gui=False)
|
gui.initialize(db.library_path, db, None, actions, show_gui=False)
|
||||||
return gui
|
return gui
|
||||||
|
|
||||||
def test_widget(category, name, gui=None):
|
def show_config_widget(category, name, gui=None, show_restart_msg=False,
|
||||||
from PyQt4.Qt import QDialog, QVBoxLayout, QDialogButtonBox
|
parent=None, never_shutdown=False):
|
||||||
class Dialog(QDialog):
|
'''
|
||||||
def set_widget(self, w): self.w = w
|
Show the preferences plugin identified by category and name
|
||||||
def accept(self):
|
|
||||||
try:
|
|
||||||
self.restart_required = self.w.commit()
|
|
||||||
except AbortCommit:
|
|
||||||
return
|
|
||||||
QDialog.accept(self)
|
|
||||||
|
|
||||||
|
: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)
|
pl = get_plugin(category, name)
|
||||||
d = Dialog()
|
d = ConfigDialog(parent)
|
||||||
d.resize(750, 550)
|
d.resize(750, 550)
|
||||||
d.setWindowTitle(category + " - " + name)
|
d.setWindowTitle(_('Configure ') + name)
|
||||||
|
d.setWindowIcon(QIcon(I('config.png')))
|
||||||
bb = QDialogButtonBox(d)
|
bb = QDialogButtonBox(d)
|
||||||
bb.setStandardButtons(bb.Apply|bb.Cancel|bb.RestoreDefaults)
|
bb.setStandardButtons(bb.Apply|bb.Cancel|bb.RestoreDefaults)
|
||||||
bb.accepted.connect(d.accept)
|
bb.accepted.connect(d.accept)
|
||||||
@ -335,11 +346,18 @@ def test_widget(category, name, gui=None):
|
|||||||
w.genesis(gui)
|
w.genesis(gui)
|
||||||
w.initialize()
|
w.initialize()
|
||||||
d.exec_()
|
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
|
from calibre.gui2 import warning_dialog
|
||||||
warning_dialog(gui, 'Restart required', 'Restart required', show=True)
|
warning_dialog(gui, 'Restart required', 'Restart required', show=True)
|
||||||
if mygui:
|
if mygui and not never_shutdown:
|
||||||
gui.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():
|
def test_all():
|
||||||
from PyQt4.Qt import QApplication
|
from PyQt4.Qt import QApplication
|
||||||
|
@ -15,7 +15,7 @@ from calibre.gui2.preferences import ConfigWidgetBase, test_widget
|
|||||||
from calibre.gui2.preferences.metadata_sources_ui import Ui_Form
|
from calibre.gui2.preferences.metadata_sources_ui import Ui_Form
|
||||||
from calibre.ebooks.metadata.sources.base import msprefs
|
from calibre.ebooks.metadata.sources.base import msprefs
|
||||||
from calibre.customize.ui import (all_metadata_plugins, is_disabled,
|
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
|
from calibre.gui2 import NONE
|
||||||
|
|
||||||
class SourcesModel(QAbstractTableModel): # {{{
|
class SourcesModel(QAbstractTableModel): # {{{
|
||||||
@ -116,11 +116,11 @@ class SourcesModel(QAbstractTableModel): # {{{
|
|||||||
self.cover_overrides = {}
|
self.cover_overrides = {}
|
||||||
|
|
||||||
def restore_defaults(self):
|
def restore_defaults(self):
|
||||||
del msprefs['cover_priorities']
|
self.enabled_overrides = dict([(p, (Qt.Unchecked if p.name in
|
||||||
self.enabled_overrides = {}
|
default_disabled_plugins else Qt.Checked)) for p in self.plugins])
|
||||||
self.cover_overrides = {}
|
self.cover_overrides = dict([(p,
|
||||||
for plugin in self.plugins:
|
msprefs.defaults['cover_priorities'].get(p.name, 1))
|
||||||
restore_plugin_state_to_default(plugin)
|
for p in self.plugins])
|
||||||
self.reset()
|
self.reset()
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
@ -131,6 +131,18 @@ class FieldsModel(QAbstractListModel): # {{{
|
|||||||
QAbstractTableModel.__init__(self, parent)
|
QAbstractTableModel.__init__(self, parent)
|
||||||
|
|
||||||
self.fields = []
|
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):
|
def rowCount(self, parent=None):
|
||||||
return len(self.fields)
|
return len(self.fields)
|
||||||
@ -141,10 +153,54 @@ class FieldsModel(QAbstractListModel): # {{{
|
|||||||
fields |= p.touched_fields
|
fields |= p.touched_fields
|
||||||
self.fields = []
|
self.fields = []
|
||||||
for x in 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.append(x)
|
||||||
|
self.fields.sort(key=lambda x:self.descs.get(x, x))
|
||||||
self.reset()
|
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)
|
ConfigWidgetBase.initialize(self)
|
||||||
self.sources_model.initialize()
|
self.sources_model.initialize()
|
||||||
self.sources_view.resizeColumnsToContents()
|
self.sources_view.resizeColumnsToContents()
|
||||||
|
self.fields_model.initialize()
|
||||||
|
|
||||||
def restore_defaults(self):
|
def restore_defaults(self):
|
||||||
ConfigWidgetBase.restore_defaults(self)
|
ConfigWidgetBase.restore_defaults(self)
|
||||||
self.sources_model.restore_defaults()
|
self.sources_model.restore_defaults()
|
||||||
|
self.fields_model.restore_defaults()
|
||||||
self.changed_signal.emit()
|
self.changed_signal.emit()
|
||||||
|
|
||||||
def commit(self):
|
def commit(self):
|
||||||
self.sources_model.commit()
|
self.sources_model.commit()
|
||||||
|
self.fields_model.commit()
|
||||||
return ConfigWidgetBase.commit(self)
|
return ConfigWidgetBase.commit(self)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
@ -73,6 +73,9 @@
|
|||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>If you uncheck any fields, metadata for those fields will not be downloaded</string>
|
<string>If you uncheck any fields, metadata for those fields will not be downloaded</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::NoSelection</enum>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user