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,
|
QFont, QFontDatabase, QFontInfo, QFontMetrics, QGuiApplication, QIcon, QIODevice,
|
||||||
QLocale, QNetworkProxyFactory, QObject, QPalette, QResource, QSettings,
|
QLocale, QNetworkProxyFactory, QObject, QPalette, QResource, QSettings,
|
||||||
QSocketNotifier, QStringListModel, Qt, QThread, QTimer, QTranslator,
|
QSocketNotifier, QStringListModel, Qt, QThread, QTimer, QTranslator,
|
||||||
QUrl, pyqtSignal
|
QUrl, pyqtSignal, pyqtSlot
|
||||||
)
|
)
|
||||||
from threading import Lock, RLock
|
from threading import Lock, RLock
|
||||||
|
|
||||||
@ -1161,6 +1161,10 @@ class Application(QApplication):
|
|||||||
def is_dark_theme(self):
|
def is_dark_theme(self):
|
||||||
return self.palette_manager.is_dark_theme
|
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):
|
def safe_restore_geometry(self, widget, geom):
|
||||||
# See https://bugreports.qt.io/browse/QTBUG-77385
|
# See https://bugreports.qt.io/browse/QTBUG-77385
|
||||||
if not geom:
|
if not geom:
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from functools import lru_cache
|
|
||||||
from qt.core import (
|
from qt.core import (
|
||||||
QAbstractNativeEventFilter, QApplication, QColor, QIcon, QPalette, QSettings,
|
QAbstractNativeEventFilter, QApplication, QColor, QIcon, QPalette, QSettings,
|
||||||
QStyle, Qt, QTimer, pyqtSlot, QObject, QDataStream, QByteArray, QIODeviceBase
|
QStyle, Qt, QTimer, pyqtSlot, QObject, QDataStream, QByteArray, QIODeviceBase
|
||||||
@ -135,7 +134,7 @@ def dark_palette():
|
|||||||
return p
|
return p
|
||||||
|
|
||||||
|
|
||||||
def light_palette():
|
def light_palette(): # {{{
|
||||||
# generated by serializing the light palette on my Linux system
|
# generated by serializing the light palette on my Linux system
|
||||||
self = QPalette()
|
self = QPalette()
|
||||||
self.setColor(QPalette.ColorGroup.Active, QPalette.ColorRole.WindowText, QColor(0, 0, 0, 255))
|
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.PlaceholderText, QColor(0, 0, 0, 128))
|
||||||
self.setColor(QPalette.ColorGroup.Current, QPalette.ColorRole.NoRole, QColor(0, 0, 0, 255))
|
self.setColor(QPalette.ColorGroup.Current, QPalette.ColorRole.NoRole, QColor(0, 0, 0, 255))
|
||||||
return self
|
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):
|
class PaletteManager(QObject):
|
||||||
@ -301,52 +334,15 @@ class PaletteManager(QObject):
|
|||||||
self.load_calibre_style()
|
self.load_calibre_style()
|
||||||
self.on_palette_change()
|
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):
|
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
|
transient_scroller = 0
|
||||||
if ismacos:
|
if ismacos:
|
||||||
from calibre_extensions.cocoa import transient_scroller
|
from calibre_extensions.cocoa import transient_scroller
|
||||||
@ -354,7 +350,6 @@ class PaletteManager(QObject):
|
|||||||
app = QApplication.instance()
|
app = QApplication.instance()
|
||||||
from calibre_extensions.progress_indicator import CalibreStyle
|
from calibre_extensions.progress_indicator import CalibreStyle
|
||||||
self.calibre_style = style = CalibreStyle(transient_scroller)
|
self.calibre_style = style = CalibreStyle(transient_scroller)
|
||||||
style.set_icon_map(icon_map)
|
|
||||||
app.setStyle(style)
|
app.setStyle(style)
|
||||||
|
|
||||||
def on_palette_change(self):
|
def on_palette_change(self):
|
||||||
|
@ -118,7 +118,7 @@ dpiScaled(qreal value) {
|
|||||||
#endif
|
#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"));
|
setObjectName(QString("calibre"));
|
||||||
desktop_environment = detectDesktopEnvironment();
|
desktop_environment = detectDesktopEnvironment();
|
||||||
button_layout = static_cast<QDialogButtonBox::ButtonLayout>(QProxyStyle::styleHint(SH_DialogButtonLayout));
|
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;
|
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 {
|
int CalibreStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const {
|
||||||
switch (hint) {
|
switch (hint) {
|
||||||
case SH_DialogButtonBox_ButtonsHaveIcons:
|
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 {
|
QIcon CalibreStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption * option, const QWidget * widget) const {
|
||||||
if (icon_map.contains(standardIcon)) {
|
QIcon ret;
|
||||||
QString q = icon_map.value(standardIcon);
|
QMetaObject::invokeMethod(QApplication::instance(), "get_qt_standard_icon", Q_RETURN_ARG(QIcon, ret), Q_ARG(int, standardIcon));
|
||||||
if (q.contains('.')) return QIcon(q);
|
if (!ret.isNull()) return ret;
|
||||||
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;
|
|
||||||
}
|
|
||||||
return QProxyStyle::standardIcon(standardIcon, option, widget);
|
return QProxyStyle::standardIcon(standardIcon, option, widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,14 +91,12 @@ private:
|
|||||||
|
|
||||||
class CalibreStyle : public QProxyStyle {
|
class CalibreStyle : public QProxyStyle {
|
||||||
protected:
|
protected:
|
||||||
QHash<unsigned long, QString> icon_map;
|
|
||||||
QByteArray desktop_environment;
|
QByteArray desktop_environment;
|
||||||
QDialogButtonBox::ButtonLayout button_layout;
|
QDialogButtonBox::ButtonLayout button_layout;
|
||||||
int transient_scroller;
|
int transient_scroller;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CalibreStyle(int transient_scroller);
|
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 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 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;
|
virtual int pixelMetric(PixelMetric metric, const QStyleOption * option = 0, const QWidget * widget = 0) const;
|
||||||
|
@ -18,19 +18,6 @@ class CalibreStyle : QProxyStyle {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
CalibreStyle(int transient_scroller);
|
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