def create_button_clicked(self): self.changed_signal.emit() name = unicode(self.function_name.currentText()) if name in self.funcs: error_dialog(self.gui, _('Template functions'), _('Name %s already used')%(name,), show=True) return if self.argument_count.value() == 0: box = warning_dialog(self.gui, _('Template functions'), _('Argument count should be -1 or greater than zero. ' 'Setting it to zero means that this function cannot ' 'be used in single function mode.'), det_msg='', show=False) box.bb.setStandardButtons(box.bb.standardButtons() | QDialogButtonBox.Cancel) box.det_msg_toggle.setVisible(False) if not box.exec_(): return try: prog = unicode(self.program.toPlainText()) cls = compile_user_function(name, unicode(self.documentation.toPlainText()), self.argument_count.value(), prog) self.funcs[name] = cls self.build_function_names_box(scroll_to=name) except: error_dialog(self.gui, _('Template functions'), _('Exception while compiling function'), show=True, det_msg=traceback.format_exc())
def st_create_button_clicked(self, use_name=None): self.changed_signal.emit() name = use_name if use_name else str(self.te_name.currentText()) for k, v in formatter_functions().get_functions().items(): if k == name and v.is_python: error_dialog( self.gui, _('Stored templates'), _('The name {} is already used for template function' ).format(name), show=True) try: prog = str(self.te_textbox.toPlainText()) if not prog.startswith('program:'): error_dialog( self.gui, _('Stored templates'), _('The stored template must begin with "program:"'), show=True) cls = compile_user_function( name, str(self.template_editor.new_doc.toPlainText()), 0, prog) self.st_funcs[name] = cls self.st_build_function_names_box(scroll_to=name) except: error_dialog(self.gui, _('Stored templates'), _('Exception while storing template'), show=True, det_msg=traceback.format_exc())
def _eval_program(self, val, prog, column_name): # keep a cache of the lex'ed program under the theory that re-lexing # is much more expensive than the cache lookup. This is certainly true # for more than a few tokens, but it isn't clear for simple programs. if tweaks['compile_gpm_templates']: if column_name is not None and self.template_cache is not None: lprog = self.template_cache.get(column_name, None) if lprog: return lprog.evaluate(self, self.kwargs, self.book, self.locals) lprog = self.lex_scanner.scan(prog) compile_text = ('__funcs__ = formatter_functions().get_functions()\n' 'def evaluate(self, formatter, kwargs, book, locals):\n' ) else: lprog = self.lex_scanner.scan(prog) compile_text = None parser = _CompileParser(val, lprog, self, compile_text) val = parser.program() if parser.compile_text: global compile_counter compile_counter += 1 f = compile_user_function("__A" + str(compile_counter), 'doc', -1, parser.compile_text) self.template_cache[column_name] = f else: if column_name is not None and self.template_cache is not None: lprog = self.template_cache.get(column_name, None) if not lprog: lprog = self.lex_scanner.scan(prog) self.template_cache[column_name] = lprog else: lprog = self.lex_scanner.scan(prog) parser = _Parser(val, lprog, self) val = parser.program() return val
def create_button_clicked(self): self.changed_signal.emit() name = unicode(self.function_name.currentText()) if name in self.funcs: error_dialog(self.gui, _('Template functions'), _('Name %s already used')%(name,), show=True) return if self.argument_count.value() == 0: box = warning_dialog(self.gui, _('Template functions'), _('Argument count should be -1 or greater than zero. ' 'Setting it to zero means that this function cannot ' 'be used in single function mode.'), det_msg = '', show=False) box.bb.setStandardButtons(box.bb.standardButtons() | QDialogButtonBox.Cancel) box.det_msg_toggle.setVisible(False) if not box.exec_(): return try: prog = unicode(self.program.toPlainText()) cls = compile_user_function(name, unicode(self.documentation.toPlainText()), self.argument_count.value(), prog) self.funcs[name] = cls self.build_function_names_box(scroll_to=name) except: error_dialog(self.gui, _('Template functions'), _('Exception while compiling function'), show=True, det_msg=traceback.format_exc())
def initialize(self): try: self.builtin_source_dict = json.loads( P('template-functions.json', data=True, allow_user_override=False).decode('utf-8')) except: traceback.print_exc() self.builtin_source_dict = {} self.funcs = dict( (k, v) for k, v in formatter_functions().get_functions().items() if v.is_python) self.builtins = formatter_functions().get_builtins_and_aliases() self.st_funcs = {} for v in self.db.prefs.get('user_template_functions', []): if not function_pref_is_python(v): self.st_funcs.update( {function_pref_name(v): compile_user_function(*v)}) self.build_function_names_box() self.function_name.currentIndexChanged[native_string_type].connect( self.function_index_changed) self.function_name.editTextChanged.connect(self.function_name_edited) self.argument_count.valueChanged.connect(self.enable_replace_button) self.documentation.textChanged.connect(self.enable_replace_button) self.program.textChanged.connect(self.enable_replace_button) self.create_button.clicked.connect(self.create_button_clicked) self.delete_button.clicked.connect(self.delete_button_clicked) self.create_button.setEnabled(False) self.delete_button.setEnabled(False) self.replace_button.setEnabled(False) self.clear_button.clicked.connect(self.clear_button_clicked) self.replace_button.clicked.connect(self.replace_button_clicked) self.program.setTabStopWidth(20) self.highlighter = PythonHighlighter(self.program.document()) self.st_build_function_names_box() self.template_editor.template_name.currentIndexChanged[ native_string_type].connect(self.st_function_index_changed) self.template_editor.template_name.editTextChanged.connect( self.st_template_name_edited) self.st_create_button.clicked.connect(self.st_create_button_clicked) self.st_delete_button.clicked.connect(self.st_delete_button_clicked) self.st_create_button.setEnabled(False) self.st_delete_button.setEnabled(False) self.st_replace_button.setEnabled(False) self.st_clear_button.clicked.connect(self.st_clear_button_clicked) self.st_replace_button.clicked.connect(self.st_replace_button_clicked) self.st_button_layout.insertSpacing(0, 90) self.template_editor.new_doc.setFixedHeight(50)
def create_button_clicked(self, use_name=None): self.changed_signal.emit() name = use_name if use_name else str(self.function_name.currentText()) if name in self.funcs: error_dialog(self.gui, _('Template functions'), _('Name %s already used') % (name, ), show=True) return if name in { function_pref_name(v) for v in self.db.prefs.get('user_template_functions', []) if not function_pref_is_python(v) }: error_dialog( self.gui, _('Template functions'), _('The name {} is already used for stored template').format( name), show=True) return if self.argument_count.value() == 0: box = warning_dialog( self.gui, _('Template functions'), _('Argument count should be -1 or greater than zero. ' 'Setting it to zero means that this function cannot ' 'be used in single function mode.'), det_msg='', show=False, show_copy_button=False) box.bb.setStandardButtons(box.bb.standardButtons() | QDialogButtonBox.StandardButton.Cancel) box.det_msg_toggle.setVisible(False) if not box.exec(): return try: prog = str(self.program.toPlainText()) cls = compile_user_function(name, str(self.documentation.toPlainText()), self.argument_count.value(), prog) self.funcs[name] = cls self.build_function_names_box(scroll_to=name) except: error_dialog(self.gui, _('Template functions'), _('Exception while compiling function'), show=True, det_msg=traceback.format_exc())
def initialize(self): try: self.builtin_source_dict = json.loads( P('template-functions.json', data=True, allow_user_override=False).decode('utf-8')) except: traceback.print_exc() self.builtin_source_dict = {} self.funcs = { k: v for k, v in formatter_functions().get_functions().items() if v.is_python } self.builtins = formatter_functions().get_builtins_and_aliases() self.st_funcs = {} try: for v in self.db.prefs.get('user_template_functions', []): if not function_pref_is_python(v): self.st_funcs.update( {function_pref_name(v): compile_user_function(*v)}) except: if question_dialog( self, _('Template functions'), _('The template functions saved in the library are corrupt. ' "Do you want to delete them? Answering 'Yes' will delete all " "the functions."), det_msg=traceback.format_exc(), show_copy_button=True): self.db.prefs['user_template_functions'] = [] raise AbortInitialize() self.build_function_names_box() self.function_name.currentIndexChanged[native_string_type].connect( self.function_index_changed) self.function_name.editTextChanged.connect(self.function_name_edited) self.argument_count.valueChanged.connect(self.enable_replace_button) self.documentation.textChanged.connect(self.enable_replace_button) self.program.textChanged.connect(self.enable_replace_button) self.create_button.clicked.connect(self.create_button_clicked) self.delete_button.clicked.connect(self.delete_button_clicked) self.create_button.setEnabled(False) self.delete_button.setEnabled(False) self.replace_button.setEnabled(False) self.clear_button.clicked.connect(self.clear_button_clicked) self.replace_button.clicked.connect(self.replace_button_clicked) self.program.setTabStopWidth(20) self.highlighter = PythonHighlighter(self.program.document()) self.te_textbox = self.template_editor.textbox self.te_name = self.template_editor.template_name self.st_build_function_names_box() self.te_name.currentIndexChanged[native_string_type].connect( self.st_function_index_changed) self.te_name.editTextChanged.connect(self.st_template_name_edited) self.st_create_button.clicked.connect(self.st_create_button_clicked) self.st_delete_button.clicked.connect(self.st_delete_button_clicked) self.st_create_button.setEnabled(False) self.st_delete_button.setEnabled(False) self.st_replace_button.setEnabled(False) self.st_test_template_button.setEnabled(False) self.st_clear_button.clicked.connect(self.st_clear_button_clicked) self.st_test_template_button.clicked.connect(self.st_test_template) self.st_replace_button.clicked.connect(self.st_replace_button_clicked) self.st_current_program_name = '' self.st_current_program_text = '' self.st_previous_text = '' self.st_first_time = False self.st_button_layout.insertSpacing(0, 90) self.template_editor.new_doc.setFixedHeight(50) # get field metadata and selected books view = self.gui.current_view() rows = view.selectionModel().selectedRows() self.mi = [] if rows: db = view.model().db self.fm = db.field_metadata for row in rows: if row.isValid(): self.mi.append( db.new_api.get_proxy_metadata( db.data.index_to_id(row.row()))) self.template_editor.set_mi(self.mi, self.fm)