From 4a3a104c4c04767fe74d0938f6ebc88c7c6989a7 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 17 Nov 2015 20:46:59 +0530 Subject: [PATCH] Cover browser: Allow customizing the text that appears under the covers with a template in Preferences->Look & Feel->Cover browser --- src/calibre/db/backend.py | 1 + src/calibre/gui2/cover_flow.py | 35 ++++++++-- src/calibre/gui2/preferences/look_feel.py | 10 +++ src/calibre/gui2/preferences/look_feel.ui | 78 +++++++++++++++-------- 4 files changed, 91 insertions(+), 33 deletions(-) diff --git a/src/calibre/db/backend.py b/src/calibre/db/backend.py index 0cd0833c69..abe0d12b11 100644 --- a/src/calibre/db/backend.py +++ b/src/calibre/db/backend.py @@ -442,6 +442,7 @@ class DB(object): defs['virt_libs_hidden'] = defs['virt_libs_order'] = () defs['update_all_last_mod_dates_on_start'] = False defs['field_under_covers_in_grid'] = 'title' + defs['cover_browser_title_template'] = '{title}' # Migrate the bool tristate tweak defs['bools_are_tristate'] = \ diff --git a/src/calibre/gui2/cover_flow.py b/src/calibre/gui2/cover_flow.py index ab5baf9b06..eacd5b5e10 100644 --- a/src/calibre/gui2/cover_flow.py +++ b/src/calibre/gui2/cover_flow.py @@ -84,18 +84,41 @@ if pictureflow is not None: self.is_cover_browser_visible = is_cover_browser_visible self.model.modelReset.connect(self.reset, type=Qt.QueuedConnection) self.ignore_image_requests = True + self.template_inited = False + + def init_template(self, db): + self.template_cache = {} + self.template_error_reported = False + self.template = db.pref('cover_browser_title_template', '{title}') + self.template_is_title = self.template == '{title}' def count(self): return self.model.count() def caption(self, index): + if self.ignore_image_requests: + return '' + ans = '' try: - ans = self.model.title(index) - if not ans: - ans = '' - ans = ans.replace('&', '&&') - except: - ans = '' + db = self.model.db.new_api + if not self.template_inited: + self.init_template(db) + if self.template_is_title: + ans = self.model.title(index) + else: + book_id = self.model.id(index) + mi = db.get_proxy_metadata(book_id) + try: + ans = mi.formatter.safe_format(self.template, mi, _('TEMPLATE ERROR'), mi, template_cache=self.template_cache) + except Exception: + if not self.template_error_reported: + self.template_error_reported = True + import traceback + traceback.print_exc() + ans = '' + ans = (ans or '').replace('&', '&&') + except Exception: + return '' return ans def subtitle(self, index): diff --git a/src/calibre/gui2/preferences/look_feel.py b/src/calibre/gui2/preferences/look_feel.py index 308877e0c0..0afd1afb7f 100644 --- a/src/calibre/gui2/preferences/look_feel.py +++ b/src/calibre/gui2/preferences/look_feel.py @@ -16,6 +16,7 @@ from PyQt5.Qt import ( QWidget, QSizePolicy, QBrush, QPixmap, QSize, QPushButton, QVBoxLayout) from calibre import human_readable +from calibre.gui2.dialogs.template_dialog import TemplateDialog from calibre.gui2.preferences import ConfigWidgetBase, test_widget, CommaSeparatedList from calibre.gui2.preferences.look_feel_ui import Ui_Form from calibre.gui2 import config, gprefs, qt_app, open_local_file, question_dialog @@ -170,10 +171,12 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): r('cover_flow_queue_length', config, restart_required=True) r('cover_browser_reflections', gprefs) r('show_rating_in_cover_browser', gprefs) + r('cover_browser_title_template', db.prefs) r('emblem_size', gprefs) r('emblem_position', gprefs, choices=[ (_('Left'), 'left'), (_('Top'), 'top'), (_('Right'), 'right'), (_('Bottom'), 'bottom')]) r('book_list_extra_row_spacing', gprefs) + self.cover_browser_title_template_button.clicked.connect(self.edit_cb_title_template) def get_esc_lang(l): if l == 'en': @@ -335,6 +338,12 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.opt_cover_grid_width.setValue(0) self.opt_cover_grid_height.setValue(0) + def edit_cb_title_template(self): + t = TemplateDialog(self, self.opt_cover_browser_title_template.text(), fm=self.gui.current_db.field_metadata) + t.setWindowTitle(_('Edit template for caption')) + if t.exec_(): + self.opt_cover_browser_title_template.setText(t.rule[1]) + def initialize(self): ConfigWidgetBase.initialize(self) font = gprefs['font'] @@ -501,6 +510,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): gui.library_view.refresh_book_details() gui.cover_flow.setShowReflections(gprefs['cover_browser_reflections']) gui.cover_flow.setPreserveAspectRatio(gprefs['cb_preserve_aspect_ratio']) + gui.cover_flow.template_inited = False gui.library_view.refresh_row_sizing() gui.grid_view.refresh_settings() diff --git a/src/calibre/gui2/preferences/look_feel.ui b/src/calibre/gui2/preferences/look_feel.ui index 2021331a47..754f7d4cc5 100644 --- a/src/calibre/gui2/preferences/look_feel.ui +++ b/src/calibre/gui2/preferences/look_feel.ui @@ -940,10 +940,10 @@ if you never want subcategories Cover Browser - - - - Show cover &browser in a separate window (needs restart) + + + + The template used to generate the text below the covers. Uses the same syntax as save templates. Defaults to just the book title. @@ -957,7 +957,7 @@ if you never want subcategories - + Qt::Vertical @@ -970,37 +970,48 @@ if you never want subcategories - + + + + Show book &rating in cover browser + + + + + + + &Template for caption: + + + opt_cover_browser_title_template + + + + + + + Template editor + + + + - + When showing cover browser in separate window, show it &fullscreen - - - - margin-left: 1.5em - + + - You can press the %s keys to toggle full screen mode. - - - true + Show cover &browser in a separate window (needs restart) - - - - Show &reflections in the cover browser - - - - + Show covers in their original aspect ratio instead of resizing @@ -1011,10 +1022,23 @@ them to all have the same width and height - - + + - Show book &rating in cover browser + Show &reflections in the cover browser + + + + + + + margin-left: 1.5em + + + You can press the %s keys to toggle full screen mode. + + + true