From 62c8a0dcfb18d49d66e81535d64fb75c480d5b9f Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 10 Jan 2022 14:36:46 +0530 Subject: [PATCH] Function to compile icon dir into themes resource --- src/calibre/constants.py | 1 + src/calibre/gui2/__init__.py | 8 ++--- src/calibre/gui2/rcc/__init__.py | 61 +++++++++++++++++++++++++++++++- 3 files changed, 64 insertions(+), 6 deletions(-) diff --git a/src/calibre/constants.py b/src/calibre/constants.py index 5257c92d0a..57ac19d153 100644 --- a/src/calibre/constants.py +++ b/src/calibre/constants.py @@ -69,6 +69,7 @@ builtin_decorations = { 'wavy': {'text-decoration-style': 'wavy', 'text-decoration-color': 'red', 'text-decoration-line': 'underline'}, 'strikeout': {'text-decoration-line': 'line-through', 'text-decoration-color': 'red'}, } +icons_subdirs = ('devices', 'plugins', 'mimetypes') _osx_ver = None diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index f6b5937867..9e428ca18f 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -23,8 +23,9 @@ from threading import Lock, RLock import calibre.gui2.pyqt6_compat as pqc from calibre import as_unicode, prints from calibre.constants import ( - DEBUG, __appname__ as APP_UID, __version__, config_dir, is_running_from_develop, - isbsd, isfrozen, islinux, ismacos, iswindows, isxp, plugins_loc + DEBUG, __appname__ as APP_UID, __version__, config_dir, icons_subdirs, + is_running_from_develop, isbsd, isfrozen, islinux, ismacos, iswindows, isxp, + plugins_loc ) from calibre.ebooks.metadata import MetaInformation from calibre.gui2.linux_file_dialogs import ( @@ -47,9 +48,6 @@ except AttributeError: NO_URL_FORMATTING = getattr(QUrl, 'None') -icons_subdirs = ('devices', 'plugins', 'mimetypes') - - def set_icon_paths(): paths = [] for main_dir in (os.path.join(config_dir, 'resources', 'images'), os.path.dirname(I(icons_subdirs[0], allow_user_override=False))): diff --git a/src/calibre/gui2/rcc/__init__.py b/src/calibre/gui2/rcc/__init__.py index b4e214d950..4b92d8f6f3 100644 --- a/src/calibre/gui2/rcc/__init__.py +++ b/src/calibre/gui2/rcc/__init__.py @@ -4,8 +4,11 @@ import os import sys +import tempfile +from posixpath import normpath from qt.core import QFile, QIODevice +from calibre.constants import icons_subdirs from calibre_extensions import rcc_backend @@ -13,7 +16,7 @@ def compile_qrc(output_path, *qrc_file_paths): rcc = rcc_backend.RCCResourceLibrary() err_device = QFile() if not err_device.open(sys.stderr.fileno(), QIODevice.OpenModeFlag.WriteOnly | QIODevice.OpenModeFlag.Text): - raise ValueError('Failed to open stderr for writing') + raise ValueError('Failed to open STDERR for writing') if not qrc_file_paths: raise TypeError('Must specify at least one .qrc file') rcc.setInputFiles(list(qrc_file_paths)) @@ -27,3 +30,59 @@ def compile_qrc(output_path, *qrc_file_paths): if not ok: os.remove(output_path) raise ValueError('Failed to write output') + + +def index_theme(name, inherits=''): + min_sz, sz, max_sz = 16, 128, 512 + lines = ['[Icon Theme]', f'Name={name}', 'Comment=Icons for calibre'] + if inherits: + lines.append(f'Inherits={inherits}') + lines.append('') + subdirs = ['images'] + [f'images/{x}' for x in icons_subdirs] + for sb in subdirs: + lines += [f'[{sb}]', f'Size={sz}', f'MinSize={min_sz}', f'MaxSize={max_sz}', ''] + return '\n'.join(lines) + + +def compile_icon_dir_as_themes(path_to_dir, output_path, theme_name='calibre-default', inherits='', prefix='/icons'): + with tempfile.TemporaryDirectory(dir=path_to_dir) as tdir, open(os.path.join(tdir, 'icons.qrc'), 'w') as qrc: + print('', file=qrc) + print(f' ', file=qrc) + + def file(name): + print(f' {normpath(name)}', file=qrc) + + for q in (theme_name, theme_name + '-dark', theme_name + '-light'): + os.mkdir(os.path.join(tdir, q)) + for sd in ['images'] + [f'images/{x}' for x in icons_subdirs]: + os.makedirs(os.path.join(tdir, q, sd)) + with open(os.path.join(tdir, theme_name, 'index.theme'), 'w') as f: + f.write(index_theme(theme_name, inherits)) + file(f'{theme_name}/index.theme') + for q in (theme_name + '-dark', theme_name + '-light'): + with open(os.path.join(tdir, q, 'index.theme'), 'w') as f: + f.write(index_theme(q, inherits=theme_name)) + file(f'{q}/index.theme') + + for sdir in ('.',) + icons_subdirs: + s = os.path.join(path_to_dir, sdir) + for x in os.listdir(s): + base, ext = os.path.splitext(x) + if ext.lower() not in ('.png',): + continue + theme_dir = theme_name + dest_name = x + if base.endswith('-for-dark-theme'): + theme_dir += '-dark' + dest_name = x.replace('-for-dark-theme', '') + elif base.endswith('-for-light-theme'): + theme_dir += '-light' + dest_name = x.replace('-for-light-theme', '') + dest = theme_dir, 'images', sdir, dest_name + os.link(os.path.join(s, x), os.path.join(tdir, *dest)) + file('/'.join(dest)) + print(' ', file=qrc) + print('', file=qrc) + qrc.close() + # input(tdir) + compile_qrc(output_path, qrc.name)