1import os 2import logging 3from functools import lru_cache 4 5import gi 6gi.require_version('GLib', '2.0') 7gi.require_version('Gtk', '3.0') 8gi.require_version('Gio', '2.0') 9gi.require_version('GdkPixbuf', '2.0') 10 11# pylint: disable=wrong-import-position 12from gi.repository import Gtk, Gio, GLib, GdkPixbuf 13from ulauncher.config import get_data_file 14 15 16icon_theme = Gtk.IconTheme.get_default() 17logger = logging.getLogger(__name__) 18 19 20@lru_cache(maxsize=50) 21def load_image(path, size): 22 """ 23 :param str path: 24 :param int size: 25 26 :rtype: :class:`GtkPixbuf` or :code:`None` 27 :returns: None if :func:`new_from_file_at_size` raises error 28 """ 29 path = os.path.expanduser(path) 30 # pylint: disable=broad-except 31 try: 32 return GdkPixbuf.Pixbuf.new_from_file_at_size(path, size, size) 33 except Exception as e: 34 logger.warning('Could not load image %s. E: %s', path, e) 35 36 37def get_app_icon_pixbuf(icon, icon_size, icon_name): 38 """ 39 :param Gio.Icon icon: 40 :param int icon_size: 41 :param str icon_name: 42 :rtype: :class:`GtkPixbuf` 43 """ 44 pixbuf_icon = None 45 # pylint: disable=broad-except 46 47 if isinstance(icon, Gio.ThemedIcon): 48 try: 49 icon_name = icon.get_names()[0] 50 if not icon_name: 51 return None 52 pixbuf_icon = get_themed_icon_by_name(icon_name, icon_size) 53 except Exception as e: 54 logger.info('Could not load icon for %s. E: %s', icon_name, e) 55 56 elif isinstance(icon, Gio.FileIcon): 57 pixbuf_icon = load_image(icon.get_file().get_path(), icon_size) 58 59 elif isinstance(icon, str): 60 pixbuf_icon = load_image(icon, icon_size) 61 62 if not pixbuf_icon: 63 pixbuf_icon = load_image(get_data_file('media', 'executable-icon.png'), icon_size) 64 65 return pixbuf_icon 66 67 68def get_themed_icon_by_name(icon_name, icon_size): 69 return icon_theme.load_icon(icon_name, icon_size, Gtk.IconLookupFlags.FORCE_SIZE) 70 71 72ULAUNCHER_FILE_ICON_DB = ['3g2', '3gp', 'ai', 'air', 'asf', 'avi', 'bib', 'cls', 'csv', 'deb', 'djvu', 'dmg', 'doc', 73 'docx', 'dwf', 'dwg', 'eps', 'epub', 'exe', 'f77', 'f90', 'f', 'flac', 'flv', 'gif', 'gz', 74 'ico', 'indd', 'iso', 'jpeg', 'jpg', 'log', 'm4a', 'm4v', 'midi', 'mkv', 'mov', 'mp3', 'mp4', 75 'mpeg', 'mpg', 'msi', 'odp', 'ods', 'odt', 'oga', 'ogg', 'ogv', 'pdf', 'png', 'pps', 'ppsx', 76 'ppt', 'pptx', 'psd', 'pub', 'py', 'qt', 'ra', 'ram', 'rar', 'rm', 'rpm', 'rtf', 'rv', 'skp', 77 'spx', 'sql', 'sty', 'tar', 'tex', 'tgz', 'tiff', 'ttf', 'txt', 'vob', 'wav', 'wmv', 'xls', 78 'xlsx', 'xml', 'xpi', 'zip'] 79 80SPECIAL_DIRS = { 81 GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DOWNLOAD): 'folder-download', 82 GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DOCUMENTS): 'folder-documents', 83 GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_MUSIC): 'folder-music', 84 GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_PICTURES): 'folder-pictures', 85 GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_PUBLIC_SHARE): 'folder-publicshare', 86 GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_TEMPLATES): 'folder-templates', 87 GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_VIDEOS): 'folder-videos', 88 GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DESKTOP): 'user-desktop', 89 os.path.expanduser('~'): 'folder-home' 90} 91 92FREEDESKTOP_STANDARD = { 93 'html': 'text-html' 94} 95 96 97def get_file_icon(path, icon_size): 98 """ 99 :param ~ulauncher.utils.Path.Path path: 100 :param int icon_size: 101 """ 102 # pylint: disable=broad-except 103 try: 104 if path.is_dir(): 105 special_dir = SPECIAL_DIRS.get(str(path)) 106 if special_dir: 107 return get_themed_icon_by_name(special_dir, icon_size) 108 return get_themed_icon_by_name('folder', icon_size) 109 110 ext = path.get_ext() 111 if ext in ULAUNCHER_FILE_ICON_DB: 112 return load_image(get_data_file('media', 'fileicons', '%s.png' % ext), icon_size) 113 114 freedesktop = FREEDESKTOP_STANDARD.get(ext) 115 if freedesktop: 116 return get_themed_icon_by_name(freedesktop, icon_size) 117 118 if path.is_exe(): 119 return load_image(get_data_file('media', 'executable-icon.png'), icon_size) 120 except Exception as e: 121 logger.warning('Icon not found %s. %s: %s', path, type(e).__name__, e) 122 123 return load_image(get_data_file('media', 'unknown-file-icon.png'), icon_size) 124