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> </td><td>%s</td></tr>'% 37 (var, FORMAT_ARG_DESCS[var])) 38 rows.append('<tr><td>%s </td><td> </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