mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Merge branch 'master' of https://github.com/cbhaley/calibre
Template dialog: Respect the tweak for title/series when editing save to disk and send to device templates. Fixes #2096841 [Export template not working as shown in preview](https://bugs.launchpad.net/calibre/+bug/2096841)
This commit is contained in:
commit
8dc6a4ea9d
@ -488,7 +488,7 @@ class TemplateDialog(QDialog, Ui_TemplateDialog):
|
||||
icon_field_key=None, icon_rule_kind=None, doing_emblem=False,
|
||||
text_is_placeholder=False, dialog_is_st_editor=False,
|
||||
global_vars=None, all_functions=None, builtin_functions=None,
|
||||
python_context_object=None, dialog_number=None,
|
||||
python_context_object=None, dialog_number=None, kwargs=None,
|
||||
formatter=SafeFormat, icon_dir='cc_icons'):
|
||||
# If dialog_number isn't None then we want separate non-modal windows
|
||||
# that don't stay on top of the main dialog. This lets Alt-Tab work to
|
||||
@ -517,6 +517,7 @@ class TemplateDialog(QDialog, Ui_TemplateDialog):
|
||||
self.dialog_is_st_editor = dialog_is_st_editor
|
||||
self.global_vars = global_vars or {}
|
||||
self.python_context_object = python_context_object or PythonTemplateContext()
|
||||
self.kwargs = kwargs
|
||||
|
||||
cols = []
|
||||
self.fm = fm
|
||||
@ -779,7 +780,7 @@ class TemplateDialog(QDialog, Ui_TemplateDialog):
|
||||
tb.setIcon(QIcon.ic('edit_input.png'))
|
||||
tb.setToolTip(_('Open Edit metadata on this book'))
|
||||
tb.clicked.connect(partial(self.metadata_button_clicked, r))
|
||||
tb.setEnabled(mi[r].get('id', -1) >= 0)
|
||||
tb.setEnabled(int(mi[r].get('id', -1)) >= 0)
|
||||
tv.setCellWidget(r, 1, tb)
|
||||
w = QLineEdit(tv)
|
||||
w.setReadOnly(True)
|
||||
@ -1092,12 +1093,11 @@ def evaluate(book, context):
|
||||
else:
|
||||
sys.settrace(None)
|
||||
try:
|
||||
v = self.formatter().safe_format(txt, mi, _('EXCEPTION:'),
|
||||
mi, global_vars=self.global_vars,
|
||||
v = self.formatter().safe_format(txt, self.kwargs[r] if self.kwargs is not None else mi,
|
||||
_('EXCEPTION:'), mi, global_vars=self.global_vars,
|
||||
template_functions=self.all_functions,
|
||||
break_reporter=self.break_reporter if r == break_on_mi else None,
|
||||
python_context_object=self.python_context_object,
|
||||
database=db)
|
||||
python_context_object=self.python_context_object, database=db)
|
||||
w = tv.cellWidget(r, 2)
|
||||
w.setText(v.translate(translate_table))
|
||||
w.setCursorPosition(0)
|
||||
|
@ -10,7 +10,7 @@ from qt.core import QWidget, pyqtSignal
|
||||
from calibre.gui2 import error_dialog, question_dialog
|
||||
from calibre.gui2.dialogs.template_dialog import TemplateDialog
|
||||
from calibre.gui2.preferences.save_template_ui import Ui_Form
|
||||
from calibre.library.save_to_disk import FORMAT_ARG_DESCS, preprocess_template
|
||||
from calibre.library.save_to_disk import FORMAT_ARG_DESCS, Formatter, get_component_metadata, preprocess_template
|
||||
from calibre.utils.formatter import validation_formatter
|
||||
|
||||
|
||||
@ -26,10 +26,14 @@ class SaveTemplate(QWidget, Ui_Form):
|
||||
|
||||
def initialize(self, name, default, help, field_metadata):
|
||||
variables = sorted(FORMAT_ARG_DESCS.keys())
|
||||
help_text = self.orig_help_text
|
||||
if name == 'send_to_device':
|
||||
self.help_label.setText(self.orig_help_text + ' ' + _(
|
||||
help_text = help_text + ' ' + _(
|
||||
'This setting can be overridden for <b>individual devices</b>,'
|
||||
' by clicking the device icon and choosing "Configure this device".'))
|
||||
' by clicking the device icon and choosing "Configure this device".')
|
||||
self.help_label.setText(help_text + ' ' +
|
||||
_('<b>Title and series</b> will have articles moved to the end unless '
|
||||
'you change the tweak "{}"').format('save_template_title_series_sorting'))
|
||||
rows = []
|
||||
for var in variables:
|
||||
rows.append(f'<tr><td>{var}</td><td> </td><td>{FORMAT_ARG_DESCS[var]}</td></tr>')
|
||||
@ -52,13 +56,22 @@ class SaveTemplate(QWidget, Ui_Form):
|
||||
from calibre.gui2.ui import get_gui
|
||||
db = get_gui().current_db
|
||||
view = get_gui().library_view
|
||||
mi = tuple(map(db.new_api.get_proxy_metadata, view.get_selected_ids()[:10]))
|
||||
mi = tuple(map(db.new_api.get_metadata, view.get_selected_ids()[:10]))
|
||||
if not mi:
|
||||
error_dialog(self, _('Must select books'),
|
||||
_('One or more books must be selected so the template '
|
||||
'editor can show the template results'), show=True)
|
||||
return
|
||||
t = TemplateDialog(self, self.opt_template.text(), fm=self.field_metadata, mi=mi)
|
||||
from calibre.library.save_to_disk import config
|
||||
opts = config().parse()
|
||||
if self.option_name == 'save_to_disk':
|
||||
timefmt = opts.timefmt
|
||||
elif self.option_name == 'send_to_device':
|
||||
timefmt = opts.send_timefmt
|
||||
|
||||
template = self.opt_template.text()
|
||||
fmt_args = [get_component_metadata(template, one, one.get('id'), timefmt=timefmt) for one in mi]
|
||||
t = TemplateDialog(self, template, fm=self.field_metadata, kwargs=fmt_args, mi=mi, formatter=Formatter)
|
||||
t.setWindowTitle(_('Edit template'))
|
||||
if t.exec():
|
||||
self.opt_template.set_value(t.rule[1])
|
||||
|
@ -34,6 +34,8 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
self.save_template.initialize('save_to_disk', self.proxy['template'],
|
||||
self.proxy.help('template'),
|
||||
self.gui.library_view.model().db.field_metadata)
|
||||
self.opt_timefmt.setToolTip('<p>' + self.opt_timefmt.toolTip() + '</p><p>' +
|
||||
_('Changes will not appear in the template editor until you press the apply button.') + '</p>')
|
||||
self.save_template.blockSignals(False)
|
||||
|
||||
def restore_defaults(self):
|
||||
|
@ -43,6 +43,9 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
self.send_template.initialize('send_to_device', self.proxy['send_template'],
|
||||
self.proxy.help('send_template'),
|
||||
self.gui.library_view.model().db.field_metadata)
|
||||
self.opt_send_timefmt.setToolTip('<p>' + self.opt_send_timefmt.toolTip() + '</p><p>' +
|
||||
_('Changes will not appear in the template editor until you press the apply button.') + '</p>')
|
||||
|
||||
self.send_template.blockSignals(False)
|
||||
|
||||
def restore_defaults(self):
|
||||
|
@ -172,10 +172,7 @@ class Formatter(TemplateFormatter):
|
||||
return key
|
||||
|
||||
|
||||
def get_components(template, mi, id, timefmt='%b %Y', length=250,
|
||||
sanitize_func=ascii_filename, replace_whitespace=False,
|
||||
to_lowercase=False, safe_format=True, last_has_extension=True,
|
||||
single_dir=False):
|
||||
def get_component_metadata(template, mi, id_, timefmt='%b %Y'):
|
||||
tsorder = tweaks['save_template_title_series_sorting']
|
||||
format_args = FORMAT_ARGS.copy()
|
||||
format_args.update(mi.all_non_none_fields())
|
||||
@ -201,8 +198,6 @@ def get_components(template, mi, id, timefmt='%b %Y', length=250,
|
||||
format_args['series'] = title_sort(mi.series, order=tsorder)
|
||||
if mi.series_index is not None:
|
||||
format_args['series_index'] = mi.format_series_index()
|
||||
else:
|
||||
template = re.sub(r'\{series_index[^}]*?\}', '', template)
|
||||
if mi.rating is not None:
|
||||
format_args['rating'] = mi.format_rating(divide_by=2.0)
|
||||
if mi.identifiers:
|
||||
@ -214,11 +209,13 @@ def get_components(template, mi, id, timefmt='%b %Y', length=250,
|
||||
format_args['timestamp'] = strftime(timefmt, mi.timestamp.timetuple())
|
||||
if not is_date_undefined(mi.pubdate) and hasattr(mi.pubdate, 'timetuple'):
|
||||
format_args['pubdate'] = strftime(timefmt, mi.pubdate.timetuple())
|
||||
else:
|
||||
format_args.pop('pubdate', None)
|
||||
if (hasattr(mi, 'last_modified') and not is_date_undefined(mi.last_modified) and
|
||||
hasattr(mi.last_modified, 'timetuple')):
|
||||
format_args['last_modified'] = strftime(timefmt, mi.last_modified.timetuple())
|
||||
|
||||
format_args['id'] = str(id)
|
||||
format_args['id'] = str(id_)
|
||||
# Now format the custom fields
|
||||
custom_metadata = mi.get_all_user_metadata(make_copy=False)
|
||||
for key in custom_metadata:
|
||||
@ -240,6 +237,13 @@ def get_components(template, mi, id, timefmt='%b %Y', length=250,
|
||||
format_args[key] = str(format_args[key])
|
||||
else:
|
||||
format_args[key] = ''
|
||||
return format_args
|
||||
|
||||
def get_components(template, mi, id_, timefmt='%b %Y', length=250,
|
||||
sanitize_func=ascii_filename, replace_whitespace=False,
|
||||
to_lowercase=False, safe_format=True, last_has_extension=True,
|
||||
single_dir=False):
|
||||
format_args = get_component_metadata(template, mi, id_, timefmt)
|
||||
if safe_format:
|
||||
components = Formatter().safe_format(template, format_args,
|
||||
'G_C-EXCEPTION!', mi)
|
||||
|
Loading…
x
Reference in New Issue
Block a user