mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Use QIcon.ic for Qt standard pixmaps as well
DRYer and much simpler code
This commit is contained in:
parent
2584edd461
commit
178e75a58e
@ -16,7 +16,7 @@ from qt.core import (
|
||||
QFont, QFontDatabase, QFontInfo, QFontMetrics, QGuiApplication, QIcon, QIODevice,
|
||||
QLocale, QNetworkProxyFactory, QObject, QPalette, QResource, QSettings,
|
||||
QSocketNotifier, QStringListModel, Qt, QThread, QTimer, QTranslator,
|
||||
QUrl, pyqtSignal
|
||||
QUrl, pyqtSignal, pyqtSlot
|
||||
)
|
||||
from threading import Lock, RLock
|
||||
|
||||
@ -1161,6 +1161,10 @@ class Application(QApplication):
|
||||
def is_dark_theme(self):
|
||||
return self.palette_manager.is_dark_theme
|
||||
|
||||
@pyqtSlot(int, result=QIcon)
|
||||
def get_qt_standard_icon(self, standard_pixmap):
|
||||
return self.palette_manager.get_qt_standard_icon(standard_pixmap)
|
||||
|
||||
def safe_restore_geometry(self, widget, geom):
|
||||
# See https://bugreports.qt.io/browse/QTBUG-77385
|
||||
if not geom:
|
||||
|
@ -4,7 +4,6 @@
|
||||
import os
|
||||
import sys
|
||||
from contextlib import contextmanager
|
||||
from functools import lru_cache
|
||||
from qt.core import (
|
||||
QAbstractNativeEventFilter, QApplication, QColor, QIcon, QPalette, QSettings,
|
||||
QStyle, Qt, QTimer, pyqtSlot, QObject, QDataStream, QByteArray, QIODeviceBase
|
||||
@ -135,7 +134,7 @@ def dark_palette():
|
||||
return p
|
||||
|
||||
|
||||
def light_palette():
|
||||
def light_palette(): # {{{
|
||||
# generated by serializing the light palette on my Linux system
|
||||
self = QPalette()
|
||||
self.setColor(QPalette.ColorGroup.Active, QPalette.ColorRole.WindowText, QColor(0, 0, 0, 255))
|
||||
@ -223,6 +222,40 @@ def light_palette():
|
||||
self.setColor(QPalette.ColorGroup.Current, QPalette.ColorRole.PlaceholderText, QColor(0, 0, 0, 128))
|
||||
self.setColor(QPalette.ColorGroup.Current, QPalette.ColorRole.NoRole, QColor(0, 0, 0, 255))
|
||||
return self
|
||||
# }}}
|
||||
|
||||
|
||||
standard_pixmaps = { # {{{
|
||||
QStyle.StandardPixmap.SP_DialogYesButton: 'ok.png',
|
||||
QStyle.StandardPixmap.SP_DialogNoButton: 'window-close.png',
|
||||
QStyle.StandardPixmap.SP_DialogCloseButton: 'close.png',
|
||||
QStyle.StandardPixmap.SP_DialogOkButton: 'ok.png',
|
||||
QStyle.StandardPixmap.SP_DialogCancelButton: 'window-close.png',
|
||||
QStyle.StandardPixmap.SP_DialogHelpButton: 'help.png',
|
||||
QStyle.StandardPixmap.SP_DialogOpenButton: 'document_open.png',
|
||||
QStyle.StandardPixmap.SP_DialogSaveButton: 'save.png',
|
||||
QStyle.StandardPixmap.SP_DialogApplyButton: 'ok.png',
|
||||
QStyle.StandardPixmap.SP_DialogDiscardButton: 'trash.png',
|
||||
QStyle.StandardPixmap.SP_MessageBoxInformation: 'dialog_information.png',
|
||||
QStyle.StandardPixmap.SP_MessageBoxWarning: 'dialog_warning.png',
|
||||
QStyle.StandardPixmap.SP_MessageBoxCritical: 'dialog_error.png',
|
||||
QStyle.StandardPixmap.SP_MessageBoxQuestion: 'dialog_question.png',
|
||||
QStyle.StandardPixmap.SP_BrowserReload: 'view-refresh.png',
|
||||
QStyle.StandardPixmap.SP_LineEditClearButton: 'clear_left.png',
|
||||
QStyle.StandardPixmap.SP_ToolBarHorizontalExtensionButton: 'v-ellipsis.png',
|
||||
QStyle.StandardPixmap.SP_ToolBarVerticalExtensionButton: 'h-ellipsis.png',
|
||||
QStyle.StandardPixmap.SP_FileDialogBack: 'back.png',
|
||||
QStyle.StandardPixmap.SP_ArrowRight: 'forward.png',
|
||||
QStyle.StandardPixmap.SP_ArrowLeft: 'back.png',
|
||||
QStyle.StandardPixmap.SP_ArrowBack: 'back.png',
|
||||
QStyle.StandardPixmap.SP_ArrowForward: 'forward.png',
|
||||
QStyle.StandardPixmap.SP_ArrowUp: 'arrow-up.png',
|
||||
QStyle.StandardPixmap.SP_ArrowDown: 'arrow-down.png',
|
||||
QStyle.StandardPixmap.SP_FileDialogToParent: 'arrow-up.png',
|
||||
QStyle.StandardPixmap.SP_FileDialogNewFolder: 'tb_folder.png',
|
||||
QStyle.StandardPixmap.SP_FileDialogListView: 'format-list-unordered.png',
|
||||
QStyle.StandardPixmap.SP_FileDialogDetailedView: 'format-list-ordered.png',
|
||||
} # }}}
|
||||
|
||||
|
||||
class PaletteManager(QObject):
|
||||
@ -301,52 +334,15 @@ class PaletteManager(QObject):
|
||||
self.load_calibre_style()
|
||||
self.on_palette_change()
|
||||
|
||||
def get_qt_standard_icon(self, standard_pixmap):
|
||||
from qt.core import QStyle
|
||||
sp = QStyle.StandardPixmap(standard_pixmap)
|
||||
val = standard_pixmaps.get(sp)
|
||||
if val is None:
|
||||
return QIcon()
|
||||
return QIcon.ic(val)
|
||||
|
||||
def load_calibre_style(self):
|
||||
icon_map = self.__icon_map_memory_ = {}
|
||||
user_path = QIcon.ic.override_icon_path
|
||||
if user_path:
|
||||
user_path = os.path.join(user_path, 'images')
|
||||
|
||||
@lru_cache(maxsize=64)
|
||||
def check_for_custom_icon(v):
|
||||
if user_path:
|
||||
q = os.path.join(user_path, v)
|
||||
if os.path.exists(q):
|
||||
return q
|
||||
return v.rpartition('.')[0]
|
||||
|
||||
for k, v in {
|
||||
'DialogYesButton': 'ok.png',
|
||||
'DialogNoButton': 'window-close.png',
|
||||
'DialogCloseButton': 'close.png',
|
||||
'DialogOkButton': 'ok.png',
|
||||
'DialogCancelButton': 'window-close.png',
|
||||
'DialogHelpButton': 'help.png',
|
||||
'DialogOpenButton': 'document_open.png',
|
||||
'DialogSaveButton': 'save.png',
|
||||
'DialogApplyButton': 'ok.png',
|
||||
'DialogDiscardButton': 'trash.png',
|
||||
'MessageBoxInformation': 'dialog_information.png',
|
||||
'MessageBoxWarning': 'dialog_warning.png',
|
||||
'MessageBoxCritical': 'dialog_error.png',
|
||||
'MessageBoxQuestion': 'dialog_question.png',
|
||||
'BrowserReload': 'view-refresh.png',
|
||||
'LineEditClearButton': 'clear_left.png',
|
||||
'ToolBarHorizontalExtensionButton': 'v-ellipsis.png',
|
||||
'ToolBarVerticalExtensionButton': 'h-ellipsis.png',
|
||||
'FileDialogBack': 'back.png',
|
||||
'ArrowRight': 'forward.png',
|
||||
'ArrowLeft': 'back.png',
|
||||
'ArrowBack': 'back.png',
|
||||
'ArrowForward': 'forward.png',
|
||||
'ArrowUp': 'arrow-up.png',
|
||||
'ArrowDown': 'arrow-down.png',
|
||||
'FileDialogToParent': 'arrow-up.png',
|
||||
'FileDialogNewFolder': 'tb_folder.png',
|
||||
'FileDialogListView': 'format-list-unordered.png',
|
||||
'FileDialogDetailedView': 'format-list-ordered.png',
|
||||
}.items():
|
||||
icon_map[getattr(QStyle.StandardPixmap, 'SP_'+k).value] = check_for_custom_icon(v)
|
||||
transient_scroller = 0
|
||||
if ismacos:
|
||||
from calibre_extensions.cocoa import transient_scroller
|
||||
@ -354,7 +350,6 @@ class PaletteManager(QObject):
|
||||
app = QApplication.instance()
|
||||
from calibre_extensions.progress_indicator import CalibreStyle
|
||||
self.calibre_style = style = CalibreStyle(transient_scroller)
|
||||
style.set_icon_map(icon_map)
|
||||
app.setStyle(style)
|
||||
|
||||
def on_palette_change(self):
|
||||
|
@ -118,7 +118,7 @@ dpiScaled(qreal value) {
|
||||
#endif
|
||||
}
|
||||
|
||||
CalibreStyle::CalibreStyle(int transient_scroller) : QProxyStyle(QString::fromUtf8("Fusion")), icon_map(), transient_scroller(transient_scroller) {
|
||||
CalibreStyle::CalibreStyle(int transient_scroller) : QProxyStyle(QString::fromUtf8("Fusion")), transient_scroller(transient_scroller) {
|
||||
setObjectName(QString("calibre"));
|
||||
desktop_environment = detectDesktopEnvironment();
|
||||
button_layout = static_cast<QDialogButtonBox::ButtonLayout>(QProxyStyle::styleHint(SH_DialogButtonLayout));
|
||||
@ -126,10 +126,6 @@ CalibreStyle::CalibreStyle(int transient_scroller) : QProxyStyle(QString::fromUt
|
||||
button_layout = QDialogButtonBox::GnomeLayout;
|
||||
}
|
||||
|
||||
void CalibreStyle::set_icon_map(QHash<unsigned long, QString> &ic) {
|
||||
icon_map = ic;
|
||||
}
|
||||
|
||||
int CalibreStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const {
|
||||
switch (hint) {
|
||||
case SH_DialogButtonBox_ButtonsHaveIcons:
|
||||
@ -157,17 +153,9 @@ int CalibreStyle::styleHint(StyleHint hint, const QStyleOption *option, const QW
|
||||
}
|
||||
|
||||
QIcon CalibreStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption * option, const QWidget * widget) const {
|
||||
if (icon_map.contains(standardIcon)) {
|
||||
QString q = icon_map.value(standardIcon);
|
||||
if (q.contains('.')) return QIcon(q);
|
||||
QIcon ans = QIcon::fromTheme(icon_map.value(standardIcon));
|
||||
if (ans.isNull() && QIcon::themeName().contains("user-any")) {
|
||||
const bool is_dark_theme = QApplication::instance()->property("is_dark_theme").toBool();
|
||||
QIcon q(QString(":/icons/calibre-default-%1/images/%2.png").arg(is_dark_theme ? "dark" : "light").arg(icon_map.value(standardIcon)));
|
||||
if (!q.isNull()) ans = q;
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
QIcon ret;
|
||||
QMetaObject::invokeMethod(QApplication::instance(), "get_qt_standard_icon", Q_RETURN_ARG(QIcon, ret), Q_ARG(int, standardIcon));
|
||||
if (!ret.isNull()) return ret;
|
||||
return QProxyStyle::standardIcon(standardIcon, option, widget);
|
||||
}
|
||||
|
||||
|
@ -91,14 +91,12 @@ private:
|
||||
|
||||
class CalibreStyle : public QProxyStyle {
|
||||
protected:
|
||||
QHash<unsigned long, QString> icon_map;
|
||||
QByteArray desktop_environment;
|
||||
QDialogButtonBox::ButtonLayout button_layout;
|
||||
int transient_scroller;
|
||||
|
||||
public:
|
||||
CalibreStyle(int transient_scroller);
|
||||
void set_icon_map(QHash<unsigned long, QString> &icon_map);
|
||||
virtual int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0, QStyleHintReturn *returnData = 0) const;
|
||||
virtual QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption * option = 0, const QWidget * widget = 0) const;
|
||||
virtual int pixelMetric(PixelMetric metric, const QStyleOption * option = 0, const QWidget * widget = 0) const;
|
||||
|
@ -18,19 +18,6 @@ class CalibreStyle : QProxyStyle {
|
||||
|
||||
public:
|
||||
CalibreStyle(int transient_scroller);
|
||||
|
||||
void set_icon_map(SIP_PYDICT icon_map_);
|
||||
%MethodCode
|
||||
QHash<unsigned long, QString> icon_map;
|
||||
PyObject *key, *value;
|
||||
Py_ssize_t pos = 0;
|
||||
while (PyDict_Next(a0, &pos, &key, &value)) {
|
||||
icon_map.insert(PyLong_AsUnsignedLong(key), QString::fromUtf8(PyUnicode_AsUTF8(value)));
|
||||
}
|
||||
sipCpp->set_icon_map(icon_map);
|
||||
%End
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user