From bdc000d2ecc615410496ee777dc7f7d666e69aa4 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 5 Feb 2024 12:03:56 +0530 Subject: [PATCH] Wire up the color palette preferences into the main preferences GUI --- src/calibre/gui2/__init__.py | 2 +- src/calibre/gui2/dialogs/palette.py | 32 ++- src/calibre/gui2/palette.py | 44 ++-- src/calibre/gui2/preferences/look_feel.py | 12 +- src/calibre/gui2/preferences/look_feel.ui | 280 +++++++++++----------- 5 files changed, 194 insertions(+), 176 deletions(-) diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index 2cc77969ab..55addc814e 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -1144,7 +1144,7 @@ class Application(QApplication): self.file_event_hook = None if override_program_name: args = [override_program_name] + args[1:] - self.palette_manager = PaletteManager(gprefs['color_palette'], gprefs['ui_style'], force_calibre_style, headless) + self.palette_manager = PaletteManager(force_calibre_style, headless) if headless: args.extend(('-platformpluginpath', plugins_loc, '-platform', 'headless')) else: diff --git a/src/calibre/gui2/dialogs/palette.py b/src/calibre/gui2/dialogs/palette.py index ce03d35cdd..ff18f8f267 100644 --- a/src/calibre/gui2/dialogs/palette.py +++ b/src/calibre/gui2/dialogs/palette.py @@ -2,10 +2,11 @@ # License: GPLv3 Copyright: 2024, Kovid Goyal +import textwrap from contextlib import suppress from qt.core import ( - QCheckBox, QDialog, QDialogButtonBox, QHBoxLayout, QLabel, QPalette, QScrollArea, - QSize, QSizePolicy, QTabWidget, QVBoxLayout, QWidget, pyqtSignal, + QCheckBox, QComboBox, QDialog, QHBoxLayout, QIcon, QLabel, QPalette, QPushButton, + QScrollArea, QSize, QSizePolicy, QTabWidget, QVBoxLayout, QWidget, pyqtSignal, ) from calibre.gui2 import Application, gprefs @@ -121,7 +122,8 @@ class PaletteWidget(QWidget): self.mode_name = mode_name self.mode_title = {'dark': _('dark'), 'light': _('light')}[mode_name] self.l = l = QVBoxLayout(self) - self.la = la = QLabel(_('These colors will be used for the calibre interface when calibre is in "{}" mode').format(self.mode_title)) + self.la = la = QLabel(_('These colors will be used for the calibre interface when calibre is in "{}" mode.' + ' You can adjust individual colors below by enabling the "Use a custom color scheme" setting.').format(self.mode_title)) l.addWidget(la) la.setWordWrap(True) self.use_custom = uc = QCheckBox(_('Use a &custom color scheme')) @@ -164,18 +166,38 @@ class PaletteConfig(Dialog): def setup_ui(self): self.l = l = QVBoxLayout(self) + h = QHBoxLayout() + self.la = la = QLabel(_('Color &palette')) + self.palette = p = QComboBox(self) + p.addItem(_('System default'), 'system') + p.addItem(_('Light'), 'light') + p.addItem(_('Dark'), 'dark') + idx = p.findData(gprefs['color_palette']) + p.setCurrentIndex(idx) + la.setBuddy(p) + h.addWidget(la), h.addWidget(p) + tt = textwrap.fill(_( + 'The style of colors to use, either light or dark. By default, the system setting for light/dark is used.' + ' This means that calibre will change from light to dark and vice versa as the system changes colors.' + )) + la.setToolTip(tt), p.setToolTip(tt) + l.addLayout(h) + self.tabs = tabs = QTabWidget(self) l.addWidget(tabs) self.light_tab = lt = PaletteWidget(parent=self) tabs.addTab(lt, _('&Light mode colors')) self.dark_tab = dt = PaletteWidget('dark', parent=self) tabs.addTab(dt, _('&Dark mode colors')) - l.addWidget(self.bb) - b = self.bb.addButton(_('Restore &defaults'), QDialogButtonBox.ButtonRole.ActionRole) + h = QHBoxLayout() + self.rd = b = QPushButton(QIcon.ic('clear_left.png'), _('Restore &defaults')) b.clicked.connect(self.restore_defaults) + h.addWidget(b), h.addStretch(10), h.addWidget(self.bb) + l.addLayout(h) def apply_settings(self): with gprefs: + gprefs['color_palette'] = str(self.palette.currentData()) self.light_tab.apply_settings() self.dark_tab.apply_settings() Application.instance().palette_manager.refresh_palette() diff --git a/src/calibre/gui2/palette.py b/src/calibre/gui2/palette.py index 05b675c09a..2af317a0f5 100644 --- a/src/calibre/gui2/palette.py +++ b/src/calibre/gui2/palette.py @@ -215,13 +215,14 @@ standard_pixmaps = { # {{{ class PaletteManager(QObject): color_palette: str - has_fixed_palette: bool using_calibre_style: bool is_dark_theme: bool - def __init__(self, color_palette, ui_style, force_calibre_style, headless): + def __init__(self, force_calibre_style, headless): + from calibre.gui2 import gprefs super().__init__() - self.color_palette = color_palette + self.color_palette = gprefs['color_palette'] + ui_style = gprefs['ui_style'] self.is_dark_theme = False self.ignore_palette_changes = False @@ -232,13 +233,12 @@ class PaletteManager(QObject): self.using_calibre_style = ui_style != 'system' else: self.using_calibre_style = os.environ.get('CALIBRE_USE_SYSTEM_THEME', '0') == '0' - self.has_fixed_palette = self.color_palette != 'system' and self.using_calibre_style args = [] self.args_to_qt = tuple(args) - if ismacos and not headless and self.has_fixed_palette: + if ismacos and not headless: from calibre_extensions.cocoa import set_appearance - set_appearance(color_palette) + set_appearance(self.color_palette) def initialize(self): app = QApplication.instance() @@ -252,23 +252,9 @@ class PaletteManager(QObject): app = QApplication.instance() system_is_dark = app.styleHints().colorScheme() == Qt.ColorScheme.Dark app.styleHints().colorSchemeChanged.connect(self.color_scheme_changed) - if iswindows: - use_dark_palette = self.color_palette == 'dark' or (self.color_palette == 'system' and system_is_dark) - elif ismacos: - use_dark_palette = self.color_palette == 'dark' - else: - use_dark_palette = self.color_palette == 'dark' or (self.color_palette == 'system' and system_is_dark) - if use_dark_palette: - self.set_dark_mode_palette() - else: - self.set_light_mode_palette() - if self.has_fixed_palette and (self.color_palette == 'dark') != QApplication.instance().palette().is_dark_theme(): - if self.color_palette == 'dark': - self.set_dark_mode_palette() - else: - self.set_light_mode_palette() - if self.has_fixed_palette: - QApplication.instance().setAttribute(Qt.ApplicationAttribute.AA_SetPalette, True) + use_dark_palette = self.color_palette == 'dark' or (self.color_palette == 'system' and system_is_dark) + self.set_dark_mode_palette() if use_dark_palette else self.set_light_mode_palette() + QApplication.instance().setAttribute(Qt.ApplicationAttribute.AA_SetPalette, True) if DEBUG: print('Using calibre Qt style:', self.using_calibre_style, file=sys.stderr) @@ -354,7 +340,7 @@ QTabBar::tab:only-one { def color_scheme_changed(self, new_color_scheme): if DEBUG: print('System Color Scheme changed to:', new_color_scheme, file=sys.stderr) - if self.has_fixed_palette: + if self.color_palette != 'system' or not self.using_calibre_style: return if new_color_scheme == Qt.ColorScheme.Dark: self.set_dark_mode_palette() @@ -384,7 +370,7 @@ QTabBar::tab:only-one { else: if DEBUG: print('ApplicationPaletteChange event received', file=sys.stderr) - if self.has_fixed_palette: + if self.using_calibre_style: pal = dark_palette() if self.color_palette == 'dark' else light_palette() if QApplication.instance().palette().color(QPalette.ColorRole.Window) != pal.color(QPalette.ColorRole.Window): if DEBUG: @@ -393,7 +379,13 @@ QTabBar::tab:only-one { self.on_palette_change() def refresh_palette(self): - is_dark = QApplication.instance().palette().is_dark_theme() + from calibre.gui2 import gprefs + self.color_palette = gprefs['color_palette'] + if ismacos: + from calibre_extensions.cocoa import set_appearance + set_appearance(self.color_palette) + system_is_dark = QApplication.instance().styleHints().colorScheme() == Qt.ColorScheme.Dark + is_dark = self.color_palette == 'dark' or (self.color_palette == 'system' and system_is_dark) pal = dark_palette() if is_dark else light_palette() self.set_palette(pal) self.on_palette_change() diff --git a/src/calibre/gui2/preferences/look_feel.py b/src/calibre/gui2/preferences/look_feel.py index 94ef3bcd90..9fbf058d62 100644 --- a/src/calibre/gui2/preferences/look_feel.py +++ b/src/calibre/gui2/preferences/look_feel.py @@ -580,7 +580,6 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.default_author_link = DefaultAuthorLink(self.default_author_link_container) self.default_author_link.changed_signal.connect(self.changed_signal) r('ui_style', gprefs, restart_required=True, choices=[(_('System default'), 'system'), (_('calibre style'), 'calibre')]) - r('color_palette', gprefs, restart_required=True, choices=[(_('System default'), 'system'), (_('Light'), 'light'), (_('Dark'), 'dark')]) r('book_list_tooltips', gprefs) r('dnd_merge', gprefs) r('wrap_toolbar_text', gprefs, restart_required=True) @@ -840,6 +839,14 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.opt_gui_layout.addItem(_('Narrow'), 'narrow') self.opt_gui_layout.currentIndexChanged.connect(self.changed_signal) set_help_tips(self.opt_gui_layout, config.help('gui_layout')) + self.button_adjust_colors.clicked.connect(self.adjust_colors) + + def adjust_colors(self): + from calibre.gui2.dialogs.palette import PaletteConfig + d = PaletteConfig(self) + if d.exec() == QDialog.DialogCode.Accepted: + d.apply_settings() + self.changed_signal.emit() def initial_tab_changed(self): self.sections_view.setCurrentRow(self.tabWidget.currentIndex()) @@ -907,8 +914,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): def update_color_palette_state(self): if self.ui_style_available: enabled = self.opt_ui_style.currentData() == 'calibre' - self.opt_color_palette.setEnabled(enabled) - self.opt_color_palette_label.setEnabled(enabled) + self.button_adjust_colors.setEnabled(enabled) def export_layout(self, model=None): filename = choose_save_file(self, 'em_import_export_field_list', diff --git a/src/calibre/gui2/preferences/look_feel.ui b/src/calibre/gui2/preferences/look_feel.ui index a3c4173f0b..b06af273b3 100644 --- a/src/calibre/gui2/preferences/look_feel.ui +++ b/src/calibre/gui2/preferences/look_feel.ui @@ -28,38 +28,53 @@ &Main interface - - + + - Show &layout buttons in the status bar + Show &row numbers in the book list - - + + + + Qt::Vertical + + + + 20 + 40 + + + + + + - Enable s&ystem tray icon (needs restart) + User interface &colors: + + + button_adjust_colors - - + + - + &User interface layout: + + + opt_gui_layout - - + + - Change &font (needs restart) + User interface style (&needs restart): - - - - - - Change &icon theme + + opt_ui_style @@ -73,50 +88,24 @@ - - + + - Show the &splash screen at startup + Enable s&ystem tray icon (needs restart) - - - - QComboBox::AdjustToMinimumContentsLengthWithIcon + + + + Disable all animations. Useful if you have a slow/old computer. - - 20 + + Disable &animations - - - - - 250 - 16777215 - - - - QComboBox::AdjustToMinimumContentsLengthWithIcon - - - 20 - - - - - - - px - - - -20 - - - - + @@ -140,71 +129,28 @@ - - + + - &User interface layout: - - - opt_gui_layout + Change &font (needs restart) - - + + - Draw a &grid in the book list + Show &tooltips in the book list - - + + - User interface style (&needs restart): - - - opt_ui_style + - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Disable all animations. Useful if you have a slow/old computer. - - - Disable &animations - - - - - - - Allow using &drag and drop to merge books - - - - - - - Show &row numbers in the book list - - - - + Toolbar @@ -246,13 +192,19 @@ - - - - Disable popup notifications when calibre completes jobs such a conversion, sending to device etc. The notifications are sent via the operating system notification facility, if available. Note that on Windows, you have to enable the system tray icon for notifications to work. + + + + + 250 + 16777215 + - - Disable n&otifications on job completion + + QComboBox::AdjustToMinimumContentsLengthWithIcon + + + 20 @@ -266,29 +218,75 @@ - - + + - Show &tooltips in the book list + Change &icon theme - - - - Color &palette (needs restart): + + + + px - - opt_color_palette + + -20 - - + + + + Allow using &drag and drop to merge books + + + + + + + Show &layout buttons in the status bar + + + + + + + Show the &splash screen at startup + + + + + - <p>The colors to use for the calibre interface. By default the system colors are used. You can change this to force a light or dark color scheme. Note that if this is not set to system default then if the system wide color scheme is changed calibre will not follow it. - -<p>Also, if you set the calibre <i>User interface style</i> to <i>System default</i>, then this setting will not take effect and system colors will always be used. + Disable popup notifications when calibre completes jobs such a conversion, sending to device etc. The notifications are sent via the operating system notification facility, if available. Note that on Windows, you have to enable the system tray icon for notifications to work. + + + Disable n&otifications on job completion + + + + + + + QComboBox::AdjustToMinimumContentsLengthWithIcon + + + 20 + + + + + + + Draw a &grid in the book list + + + + + + + Adjust &colors @@ -821,8 +819,8 @@ A value of zero means calculate automatically. <p>Note: <b>comments</b>-like columns will always - be displayed at the end unless their "Heading position" is - "Show heading to the side".</p> + be displayed at the end unless their "Heading position" is + "Show heading to the side".</p> true @@ -1294,12 +1292,12 @@ structure and you want to use the same column order for each one.</p> - - Show &average ratings - Show the average rating per item indication in the Tag browser + + Show &average ratings + true @@ -1307,12 +1305,12 @@ structure and you want to use the same column order for each one.</p> - - Show &links icons - Show an icon if the item has an attached link + + Show &links icons + true @@ -1339,12 +1337,12 @@ see the counts by hovering your mouse over any item.</p> - - Show &notes icons - Show an icon if the item has an attached note + + Show &notes icons + true @@ -1372,14 +1370,14 @@ box will cause these empty categories to be hidden.</p> - - Place icons on the &right, in columns - If checked the notes and links icons will be placed at the right, after the count and in columns. If unchecked, the icons will be placed immediately after the text, to the left of the count and not in columns. + + Place icons on the &right, in columns + true