-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcommon_icons.py
More file actions
159 lines (138 loc) · 5.46 KB
/
Copy pathcommon_icons.py
File metadata and controls
159 lines (138 loc) · 5.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#!/usr/bin/env python
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
from __future__ import (unicode_literals, division, absolute_import,
print_function)
__license__ = 'GPL v3'
__copyright__ = '2022, Grant Drake'
import os
# calibre Python 3 compatibility.
import six
try:
from qt.core import (QIcon, QPixmap, QApplication)
except ImportError:
from PyQt5.Qt import (QIcon, QPixmap, QApplication)
from calibre.constants import iswindows
from calibre.constants import numeric_version as calibre_version
from calibre.utils.config import config_dir
# ----------------------------------------------
# Global resources / state
# ----------------------------------------------
# Global definition of our plugin name. Used for common functions that require this.
plugin_name = None
# Global definition of our plugin resources. Used to share between the xxxAction and xxxBase
# classes if you need any zip images to be displayed on the configuration dialog.
plugin_icon_resources = {}
def set_plugin_icon_resources(name, resources):
'''
Set our global store of plugin name and icon resources for sharing between
the InterfaceAction class which reads them and the ConfigWidget
if needed for use on the customization dialog for this plugin.
'''
global plugin_icon_resources, plugin_name
plugin_name = name
plugin_icon_resources = resources
# ----------------------------------------------
# Icon Management functions
# ----------------------------------------------
def is_dark_theme():
"""Check if dark theme is active based on application palette"""
app = QApplication.instance()
if not app:
return False
palette = app.palette()
# Compare text vs window color to determine if it's a dark theme
window_color = palette.color(palette.Window)
text_color = palette.color(palette.WindowText)
return text_color.lightness() > window_color.lightness()
def get_themed_icon_name(icon_name):
"""Get theme-specific icon name by adding _dark or _light suffix"""
if not icon_name or not icon_name.startswith('images/'):
return icon_name
# Remove .png extension if present
base_name = icon_name[:-4] if icon_name.endswith('.png') else icon_name
theme_suffix = '_dark' if is_dark_theme() else '_light'
return f"{base_name}{theme_suffix}.png"
def get_icon_6_2_plus(icon_name):
'''
Retrieve a QIcon for the named image from
1. Calibre's image cache
2. resources/images
3. the icon theme
4. the plugin zip
Only plugin zip has images/ in the image name for backward compatibility.
'''
icon = None
if icon_name:
# Try theme-specific version first
themed_name = get_themed_icon_name(icon_name)
icon = QIcon.ic(themed_name)
if not icon or icon.isNull():
icon = get_icons(themed_name.replace('images/',''), plugin_name,
print_tracebacks_for_missing_resources=False)
if not icon or icon.isNull():
icon = get_icons(themed_name, plugin_name,
print_tracebacks_for_missing_resources=False)
if not icon:
icon = QIcon()
return icon
def get_icon_old(icon_name):
'''
Retrieve a QIcon for the named image from the zip file if it exists,
or if not then from Calibre's image cache.
'''
if icon_name:
# Try theme-specific version first
themed_name = get_themed_icon_name(icon_name)
pixmap = get_pixmap(themed_name)
if pixmap is not None:
return QIcon(pixmap)
# Fallback to original name
pixmap = get_pixmap(icon_name)
if pixmap is None:
# Look in Calibre's cache for the icon
return QIcon(I(icon_name))
else:
return QIcon(pixmap)
return QIcon()
def get_pixmap(icon_name):
'''
Retrieve a QPixmap for the named image
Any icons belonging to the plugin must be prefixed with 'images/'
'''
global plugin_icon_resources, plugin_name
if not icon_name.startswith('images/'):
# We know this is definitely not an icon belonging to this plugin
pixmap = QPixmap()
pixmap.load(I(icon_name))
return pixmap
# Check to see whether the icon exists as a Calibre resource
# This will enable skinning if the user stores icons within a folder like:
# ...\AppData\Roaming\calibre\resources\images\Plugin Name\
if plugin_name:
local_images_dir = get_local_images_dir(plugin_name)
local_image_path = os.path.join(local_images_dir, icon_name.replace('images/', ''))
if os.path.exists(local_image_path):
pixmap = QPixmap()
pixmap.load(local_image_path)
return pixmap
# As we did not find an icon elsewhere, look within our zip resources
if icon_name in plugin_icon_resources:
pixmap = QPixmap()
pixmap.loadFromData(plugin_icon_resources[icon_name])
return pixmap
return None
def get_local_images_dir(subfolder=None):
'''
Returns a path to the user's local resources/images folder
If a subfolder name parameter is specified, appends this to the path
'''
images_dir = os.path.join(config_dir, 'resources/images')
if subfolder:
images_dir = os.path.join(images_dir, subfolder)
if iswindows:
images_dir = os.path.normpath(images_dir)
return images_dir
if calibre_version >= (6,2,0):
get_icon = get_icon_6_2_plus
else:
get_icon = get_icon_old