Support themeing for plugin icons

This commit is contained in:
Kovid Goyal 2022-01-11 20:14:54 +05:30
parent 3650033173
commit 8a33f48874
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 47 additions and 27 deletions

View File

@ -138,15 +138,23 @@ Getting resources from the plugin ZIP file
calibre's plugin loading system defines a couple of built-in functions that allow you to conveniently get files from the plugin ZIP file.
**get_resources(name_or_list_of_names)**
This function should be called with a list of paths to files inside the ZIP file. For example to access the file icon.png in
the folder images in the ZIP file, you would use: ``images/icon.png``. Always use a forward slash as the path separator,
even on Windows. When you pass in a single name, the function will return the raw bytes of that file or None if the name
was not found in the ZIP file. If you pass in more than one name then it returns a dict mapping the names to bytes.
If a name is not found, it will not be present in the returned dict.
This function should be called with a list of paths to files inside the
ZIP file. For example to access the file :file:`icon.png` in the folder
images in the ZIP file, you would use: ``images/icon.png``. Always use
a forward slash as the path separator, even on Windows. When you pass
in a single name, the function will return the raw bytes of that file
or None if the name was not found in the ZIP file. If you pass in more
than one name then it returns a dict mapping the names to bytes. If a
name is not found, it will not be present in the returned dict.
**get_icons(name_or_list_of_names, plugin_name='')**
A wrapper for get_resources() that creates QIcon objects
from the raw bytes returned by get_resources. If a name is not found
in the ZIP file the corresponding QIcon will be null. In order to
support icon theme-ing, pass in the human friendly name of your plugin
as ``plugin_name``. If the user is using an icon theme with icons for
you plugin, they will be loaded preferentially.
**get_icons(name_or_list_of_names)**
A convenience wrapper for get_resources() that creates QIcon objects from the raw bytes returned by get_resources.
If a name is not found in the ZIP file the corresponding QIcon will be null.
Enabling user configuration of your plugin
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -57,38 +57,50 @@ def get_resources(zfp, name_or_list_of_names):
return ans
def get_icons(zfp, name_or_list_of_names):
def get_icons(zfp, name_or_list_of_names, plugin_name=''):
'''
Load icons from the plugin zip file
:param name_or_list_of_names: List of paths to resources in the zip file using / as
separator, or a single path
:param plugin_name: The human friendly name of the plugin, used to load icons from
the current theme, if present.
:return: A dictionary of the form ``{name : QIcon}``. Any names
that were not found in the zip file will be null QIcons.
If a single path is passed in the return value will
be A QIcon.
'''
from qt.core import QIcon, QPixmap
names = name_or_list_of_names
ans = get_resources(zfp, names)
if isinstance(names, string_or_bytes):
names = [names]
if ans is None:
ans = {}
if isinstance(ans, string_or_bytes):
ans = dict([(names[0], ans)])
ans = {}
namelist = [name_or_list_of_names] if isinstance(name_or_list_of_names, string_or_bytes) else name_or_list_of_names
failed = set()
if plugin_name:
for name in namelist:
q = QIcon.ic(f'{plugin_name}/{name}')
if q.isNull():
failed.add(name)
else:
ans[name] = q
else:
failed = set(namelist)
if failed:
from_zfp = get_resources(zfp, list(failed))
if from_zfp is None:
from_zfp = {}
elif isinstance(from_zfp, string_or_bytes):
from_zfp = {namelist[0]: from_zfp}
ians = {}
for name in names:
p = QPixmap()
raw = ans.get(name, None)
if raw:
p.loadFromData(raw)
ians[name] = QIcon(p)
if len(names) == 1:
ians = ians.pop(names[0])
return ians
for name in failed:
p = QPixmap()
raw = from_zfp.get(name)
if raw:
p.loadFromData(raw)
ans[name] = QIcon(p)
if len(namelist) == 1 and ans:
ans = ans.pop(namelist[0])
return ans
_translations_cache = {}