1# -*- coding: utf-8 -*- 2 3# Copyright (c) 2004 - 2021 Detlev Offenbach <detlev@die-offenbachs.de> 4# 5 6""" 7Module implementing a pixmap cache for icons. 8""" 9 10import os 11 12from PyQt5.QtCore import Qt, QSize 13from PyQt5.QtGui import QPixmap, QIcon, QPainter 14 15 16class PixmapCache: 17 """ 18 Class implementing a pixmap cache for icons. 19 """ 20 SupportedExtensions = [".svgz", ".svg", ".png"] 21 22 def __init__(self): 23 """ 24 Constructor 25 """ 26 self.pixmapCache = {} 27 self.searchPath = [] 28 29 def getPixmap(self, key, size=None): 30 """ 31 Public method to retrieve a pixmap. 32 33 @param key name of the wanted pixmap 34 @type str 35 @param size requested size 36 @type QSize 37 @return the requested pixmap 38 @rtype QPixmap 39 """ 40 if key: 41 basename, ext = os.path.splitext(key) 42 if size and not size.isEmpty(): 43 key = "{0}_{1}_{2}".format( 44 basename, size.width(), size.height()) 45 else: 46 key = basename 47 48 try: 49 return self.pixmapCache[key] 50 except KeyError: 51 pm = QPixmap() 52 for extension in self.SupportedExtensions: 53 filename = basename + extension 54 if not os.path.isabs(filename): 55 for path in self.searchPath: 56 pm = QPixmap(path + "/" + filename) 57 if not pm.isNull(): 58 break 59 else: 60 pm = QPixmap(filename) 61 if not pm.isNull(): 62 if size and not size.isEmpty(): 63 pm = pm.scaled(size) 64 break 65 else: 66 pm = QPixmap() 67 68 self.pixmapCache[key] = pm 69 return self.pixmapCache[key] 70 71 return QPixmap() 72 73 def addSearchPath(self, path): 74 """ 75 Public method to add a path to the search path. 76 77 @param path path to add 78 @type str 79 """ 80 if path not in self.searchPath: 81 self.searchPath.append(path) 82 83 def removeSearchPath(self, path): 84 """ 85 Public method to remove a path from the search path. 86 87 @param path path to remove 88 @type str 89 """ 90 if path in self.searchPath: 91 self.searchPath.remove(path) 92 93pixCache = PixmapCache() 94 95 96def getPixmap(key, size=None, cache=pixCache): 97 """ 98 Module function to retrieve a pixmap. 99 100 @param key name of the wanted pixmap 101 @type str 102 @param size requested size 103 @type QSize 104 @param cache reference to the pixmap cache object 105 @type PixmapCache 106 @return the requested pixmap 107 @rtype QPixmap 108 """ 109 return cache.getPixmap(key, size=size) 110 111 112def getIcon(key, size=None, cache=pixCache): 113 """ 114 Module function to retrieve an icon. 115 116 @param key name of the wanted pixmap 117 @type str 118 @param size requested size 119 @type QSize 120 @param cache reference to the pixmap cache object 121 @type PixmapCache 122 @return the requested icon 123 @rtype QIcon 124 """ 125 return QIcon(cache.getPixmap(key, size=size)) 126 127 128def getSymlinkIcon(key, size=None, cache=pixCache): 129 """ 130 Module function to retrieve a symbolic link icon. 131 132 @param key name of the wanted pixmap 133 @type str 134 @param size requested size 135 @type QSize 136 @param cache reference to the pixmap cache object 137 @type PixmapCache 138 @return the requested icon 139 @rtype QIcon 140 """ 141 pix1 = QPixmap(cache.getPixmap(key, size=size)) 142 pix2 = cache.getPixmap("symlink") 143 painter = QPainter(pix1) 144 painter.drawPixmap(0, 10, pix2) 145 painter.end() 146 return QIcon(pix1) 147 148 149def getCombinedIcon(keys, size=None, cache=pixCache): 150 """ 151 Module function to retrieve a symbolic link icon. 152 153 @param keys list of names of icons 154 @type list of str 155 @param size requested size of individual icons 156 @type QSize 157 @param cache reference to the pixmap cache object 158 @type PixmapCache 159 @return the requested icon 160 @rtype QIcon 161 """ 162 height = width = 0 163 pixmaps = [] 164 for key in keys: 165 pix = cache.getPixmap(key, size=size) 166 if not pix.isNull(): 167 height = max(height, pix.height()) 168 width = max(width, pix.width()) 169 pixmaps.append(pix) 170 if pixmaps: 171 pix = QPixmap(len(pixmaps) * width, height) 172 pix.fill(Qt.GlobalColor.transparent) 173 painter = QPainter(pix) 174 x = 0 175 for pixmap in pixmaps: 176 painter.drawPixmap(x, 0, pixmap.scaled(QSize(width, height))) 177 x += width 178 painter.end() 179 icon = QIcon(pix) 180 else: 181 icon = QIcon() 182 return icon 183 184 185def addSearchPath(path, cache=pixCache): 186 """ 187 Module function to add a path to the search path. 188 189 @param path path to add 190 @type str 191 @param cache reference to the pixmap cache object 192 @type PixmapCache 193 """ 194 cache.addSearchPath(path) 195 196 197def removeSearchPath(path, cache=pixCache): 198 """ 199 Public method to remove a path from the search path. 200 201 @param path path to remove 202 @type str 203 @param cache reference to the pixmap cache object 204 @type PixmapCache 205 """ 206 cache.removeSearchPath(path) 207