1#!/usr/local/bin/python3.8
2# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
3
4
5__license__   = 'GPL v3'
6__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
7__docformat__ = 'restructuredtext en'
8
9from qt.core import QWidget, pyqtSignal
10
11from calibre.gui2 import error_dialog, question_dialog
12from calibre.gui2.preferences.save_template_ui import Ui_Form
13from calibre.library.save_to_disk import FORMAT_ARG_DESCS, preprocess_template
14from calibre.utils.formatter import validation_formatter
15from calibre.gui2.dialogs.template_dialog import TemplateDialog
16
17
18class SaveTemplate(QWidget, Ui_Form):
19
20    changed_signal = pyqtSignal()
21
22    def __init__(self, *args):
23        QWidget.__init__(self, *args)
24        Ui_Form.__init__(self)
25        self.setupUi(self)
26        self.orig_help_text = self.help_label.text()
27
28    def initialize(self, name, default, help, field_metadata):
29        variables = sorted(FORMAT_ARG_DESCS.keys())
30        if name == 'send_to_device':
31            self.help_label.setText(self.orig_help_text + ' ' + _(
32                'This setting can be overridden for <b>individual devices</b>,'
33                ' by clicking the device icon and choosing "Configure this device".'))
34        rows = []
35        for var in variables:
36            rows.append('<tr><td>%s</td><td>&nbsp;</td><td>%s</td></tr>'%
37                    (var, FORMAT_ARG_DESCS[var]))
38        rows.append('<tr><td>%s&nbsp;</td><td>&nbsp;</td><td>%s</td></tr>'%(
39            _('Any custom field'),
40            _('The lookup name of any custom field (these names begin with "#").')))
41        table = '<table>%s</table>'%('\n'.join(rows))
42        self.template_variables.setText(table)
43
44        self.field_metadata = field_metadata
45        self.opt_template.initialize(name+'_template_history',
46                default, help)
47        self.opt_template.editTextChanged.connect(self.changed)
48        self.opt_template.currentIndexChanged.connect(self.changed)
49        self.option_name = name
50        self.open_editor.clicked.connect(self.do_open_editor)
51
52    def do_open_editor(self):
53        t = TemplateDialog(self, self.opt_template.text(), fm=self.field_metadata)
54        t.setWindowTitle(_('Edit template'))
55        if t.exec():
56            self.opt_template.set_value(t.rule[1])
57
58    def changed(self, *args):
59        self.changed_signal.emit()
60
61    def validate(self):
62        '''
63        Do a syntax check on the format string. Doing a semantic check
64        (verifying that the fields exist) is not useful in the presence of
65        custom fields, because they may or may not exist.
66        '''
67        tmpl = preprocess_template(self.opt_template.text())
68        try:
69            t = validation_formatter.validate(tmpl)
70            if t.find(validation_formatter._validation_string) < 0:
71                return question_dialog(self, _('Constant template'),
72                    _('The template contains no {fields}, so all '
73                      'books will have the same name. Is this OK?'))
74        except Exception as err:
75            error_dialog(self, _('Invalid template'),
76                    '<p>'+_('The template %s is invalid:')%tmpl +
77                    '<br>'+str(err), show=True)
78            return False
79        return True
80
81    def set_value(self, val):
82        self.opt_template.set_value(val)
83
84    def save_settings(self, config, name):
85        val = str(self.opt_template.text())
86        config.set(name, val)
87        self.opt_template.save_history(self.option_name+'_template_history')
88