diff --git a/src/calibre/gui2/dialogs/template_dialog.py b/src/calibre/gui2/dialogs/template_dialog.py index 60d4025ef9..174056ef80 100644 --- a/src/calibre/gui2/dialogs/template_dialog.py +++ b/src/calibre/gui2/dialogs/template_dialog.py @@ -3,8 +3,11 @@ __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __docformat__ = 'restructuredtext en' __license__ = 'GPL v3' +import json + from PyQt4.Qt import Qt, QDialog, QDialogButtonBox from calibre.gui2.dialogs.template_dialog_ui import Ui_TemplateDialog +from calibre.utils.formatter_functions import formatter_functions class TemplateDialog(QDialog, Ui_TemplateDialog): @@ -17,9 +20,41 @@ class TemplateDialog(QDialog, Ui_TemplateDialog): self.setWindowFlags(self.windowFlags()&(~Qt.WindowContextHelpButtonHint)) self.setWindowIcon(icon) + self.textbox.setTabStopWidth(10) + self.source_code.setTabStopWidth(10) + self.documentation.setReadOnly(True) + self.source_code.setReadOnly(True) + if text is not None: self.textbox.setPlainText(text) - self.textbox.setTabStopWidth(50) self.buttonBox.button(QDialogButtonBox.Ok).setText(_('&OK')) self.buttonBox.button(QDialogButtonBox.Cancel).setText(_('&Cancel')) + try: + with open(P('template-functions.json'), 'rb') as f: + self.builtin_source_dict = json.load(f, encoding='utf-8') + except: + self.builtin_source_dict = {} + + self.funcs = formatter_functions.get_functions() + self.builtins = formatter_functions.get_builtins() + + func_names = sorted(self.funcs) + self.function.clear() + self.function.addItem('') + self.function.addItems(func_names) + self.function.setCurrentIndex(0) + self.function.currentIndexChanged[str].connect(self.function_changed) + + def function_changed(self, toWhat): + name = unicode(toWhat) + self.source_code.clear() + self.documentation.clear() + if name in self.funcs: + self.documentation.setPlainText(self.funcs[name].doc) + if name in self.builtins: + if name in self.builtin_source_dict: + self.source_code.setPlainText(self.builtin_source_dict[name]) + else: + self.source_code.setPlainText(self.funcs[name].program_text) + diff --git a/src/calibre/gui2/dialogs/template_dialog.ui b/src/calibre/gui2/dialogs/template_dialog.ui index a30d6ef273..dd8fb7bd88 100644 --- a/src/calibre/gui2/dialogs/template_dialog.ui +++ b/src/calibre/gui2/dialogs/template_dialog.ui @@ -6,8 +6,8 @@ 0 0 - 500 - 235 + 588 + 546 @@ -19,21 +19,77 @@ Edit Comments - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + Function &name: + + + function + + + + + + + + + + &Documentation: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + documentation + + + + + + + Python &code: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + source_code + + + + + + + + 16777215 + 75 + + + + + + + + + + diff --git a/src/calibre/gui2/preferences/template_functions.py b/src/calibre/gui2/preferences/template_functions.py index 2e16b0f4c3..8ffd65b2b5 100644 --- a/src/calibre/gui2/preferences/template_functions.py +++ b/src/calibre/gui2/preferences/template_functions.py @@ -5,7 +5,7 @@ __license__ = 'GPL v3' __copyright__ = '2010, Kovid Goyal ' __docformat__ = 'restructuredtext en' -import traceback +import json, traceback from calibre.gui2 import error_dialog from calibre.gui2.preferences import ConfigWidgetBase, test_widget @@ -73,6 +73,12 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.textBrowser.setHtml(help_text) def initialize(self): + try: + with open(P('template-functions.json'), 'rb') as f: + self.builtin_source_dict = json.load(f, encoding='utf-8') + except: + self.builtin_source_dict = {} + self.funcs = formatter_functions.get_functions() self.builtins = formatter_functions.get_builtins() @@ -179,8 +185,13 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): func = self.funcs[txt] self.argument_count.setValue(func.arg_count) self.documentation.setText(func.doc) - self.program.setPlainText(func.program_text) if txt in self.builtins: + if hasattr(func, 'program_text'): + self.program.setPlainText(func.program_text) + elif txt in self.builtin_source_dict: + self.program.setPlainText(self.builtin_source_dict[txt]) + else: + self.program.setPlainText(_('function source code not available')) self.documentation.setReadOnly(True) self.argument_count.setReadOnly(True) self.program.setReadOnly(True) diff --git a/src/calibre/library/sqlite.py b/src/calibre/library/sqlite.py index 83f19b8711..622d6b8459 100644 --- a/src/calibre/library/sqlite.py +++ b/src/calibre/library/sqlite.py @@ -100,7 +100,7 @@ class AumSortedConcatenate(object): keys = self.ans.keys() l = len(keys) if l == 0: - return 'Unknown:::Unknown' + return None if l == 1: return self.ans[keys[0]] return ':#:'.join([self.ans[v] for v in sorted(keys)]) diff --git a/src/calibre/utils/date.py b/src/calibre/utils/date.py index f025a0c9bf..2551b90788 100644 --- a/src/calibre/utils/date.py +++ b/src/calibre/utils/date.py @@ -148,6 +148,9 @@ def format_date(dt, format, assume_utc=False, as_utc=False): if len(mo.group(0)) == 2: return '%02d'%(dt.year % 100) return '%04d'%dt.year + if dt == UNDEFINED_DATE: + return '' + format = re.sub('d{1,4}', format_day, format) format = re.sub('M{1,4}', format_month, format) return re.sub('yyyy|yy', format_year, format)