From a65259b1c8392959d9b06c9fc297a4d14d57f6d0 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 22 Feb 2024 09:18:43 +0530 Subject: [PATCH] Add a toolbar button to quick switch profiles --- src/calibre/gui2/viewer/toolbars.py | 45 +++++++++++++++++++++++++---- src/calibre/gui2/viewer/web_view.py | 4 +++ src/pyj/viewer-main.pyj | 13 ++++++++- 3 files changed, 56 insertions(+), 6 deletions(-) diff --git a/src/calibre/gui2/viewer/toolbars.py b/src/calibre/gui2/viewer/toolbars.py index b61f6d35e4..3fe1c1493f 100644 --- a/src/calibre/gui2/viewer/toolbars.py +++ b/src/calibre/gui2/viewer/toolbars.py @@ -6,8 +6,8 @@ import os from functools import partial from qt.core import ( QAbstractItemView, QAction, QDialog, QDialogButtonBox, QGroupBox, QHBoxLayout, - QIcon, QKeySequence, QLabel, QListWidget, QListWidgetItem, QMenu, Qt, QToolBar, - QToolButton, QVBoxLayout, pyqtSignal, + QIcon, QInputDialog, QKeySequence, QLabel, QListWidget, QListWidgetItem, QMenu, Qt, + QToolBar, QToolButton, QVBoxLayout, pyqtSignal, ) from qt.webengine import QWebEnginePage @@ -41,6 +41,7 @@ def all_actions(): if not hasattr(all_actions, 'ans'): amap = { 'color_scheme': Action('format-fill-color.png', _('Switch color scheme')), + 'profiles': Action('auto-reload.png', _('Apply settings from a saved profile')), 'back': Action('back.png', _('Back'), 'back'), 'forward': Action('forward.png', _('Forward'), 'forward'), 'open': Action('document_open.png', _('Open e-book')), @@ -215,6 +216,10 @@ class ActionsToolBar(ToolBar): self.color_scheme_menu = m = QMenu(self) a.setMenu(m) m.aboutToShow.connect(self.populate_color_scheme_menu) + self.profiles_action = a = QAction(aa.profiles.icon, aa.profiles.text, self) + self.profiles_menu = m = QMenu(self) + a.setMenu(m) + m.aboutToShow.connect(self.populate_profiles_menu) self.add_actions() @@ -237,9 +242,10 @@ class ActionsToolBar(ToolBar): self.addAction(getattr(self, f'{x}_action')) except AttributeError: pass - w = self.widgetForAction(self.color_scheme_action) - if w: - w.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup) + for x in (self.color_scheme_action, self.profiles_action): + w = self.widgetForAction(x) + if w: + w.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup) def update_mode_action(self): mode = get_session_pref('read_mode', default='paged', group=None) @@ -338,6 +344,35 @@ class ActionsToolBar(ToolBar): def on_view_created(self, data): self.default_color_schemes = data['default_color_schemes'] + def populate_profiles_menu(self): + from calibre.gui2.viewer.config import load_viewer_profiles + m = self.profiles_menu + m.clear() + self.profiles = load_viewer_profiles('viewer:') + self.profiles['__default__'] = {} + def a(name, display_name=''): + a = m.addAction(display_name or name) + a.setObjectName(f'profile-switch-action:{name}') + a.triggered.connect(self.profile_switch_triggered) + a('__default__', _('Restore settings to defaults')) + m.addSeparator() + for profile_name in sorted(self.profiles, key=lambda x: x.lower()): + if profile_name == '__default__': + continue + a(profile_name) + m.addSeparator() + m.addAction(_('Save current settings as a profile')).triggered.connect(self.save_profile) + + def profile_switch_triggered(self): + key = self.sender().objectName().partition(':')[-1] + profile = self.profiles[key] + self.web_view.profile_op('apply-profile', key, profile) + + def save_profile(self): + name, ok = QInputDialog.getText(self, _('Enter name of profile to create'), _('&Name of profile')) + if ok: + self.web_view.profile_op('request-save', name, {}) + def populate_color_scheme_menu(self): m = self.color_scheme_menu m.clear() diff --git a/src/calibre/gui2/viewer/web_view.py b/src/calibre/gui2/viewer/web_view.py index 78ace21757..86160761e0 100644 --- a/src/calibre/gui2/viewer/web_view.py +++ b/src/calibre/gui2/viewer/web_view.py @@ -577,6 +577,10 @@ class WebView(RestartingWebEngineView): elif which == 'save-profile': save_viewer_profile(profile_name, settings, 'viewer:') self.execute_when_ready('profile_response', 'save-profile', profile_name) + elif which == 'apply-profile': + self.execute_when_ready('profile_response', 'apply-profile', settings) + elif which == 'request-save': + self.execute_when_ready('profile_response', 'request-save', profile_name) def link_hovered(self, url): if url == 'javascript:void(0)': diff --git a/src/pyj/viewer-main.pyj b/src/pyj/viewer-main.pyj index d203304e0d..4fddef9538 100644 --- a/src/pyj/viewer-main.pyj +++ b/src/pyj/viewer-main.pyj @@ -24,7 +24,9 @@ from read_book.iframe import main as iframe_main from read_book.open_book import remove_recently_opened from read_book.prefs.head_foot import set_time_formatter from read_book.view import View -from session import local_storage, session_defaults, default_interface_data +from session import ( + apply_reader_profile, default_interface_data, local_storage, session_defaults, settings_for_reader_profile +) from utils import debounce, encode_query_with_path, parse_url_params from viewer.constants import FAKE_HOST, FAKE_PROTOCOL @@ -82,6 +84,15 @@ def profile_response(which, x): elif which is 'save-profile': profiles_callbacks.saved() profiles_callbacks.saved = None + elif which is 'apply-profile': + sd = get_session_data() + apply_reader_profile(sd, x) + if view: + view.preferences_changed() + elif which is 'request-save': + sd = get_session_data() + settings = settings_for_reader_profile(sd) + save_profile(x, settings, def(): pass;) def get_all_profiles(proceed):