Source

pyqtwidgets / qtwidgets / freedesktop.py

Full commit
# -*- coding: utf-8 -*-

import __main__
import os
from ConfigParser import SafeConfigParser as IniFile

try:
    from elementtree.ElementTree import ElementTree
except ImportError:
    try:
        from xml.etree.ElementTree import ElementTree
    except ImportError:
        ElementTree = None
        
    
__all__ = [
    "find_icon",
    ]

    

application_prefix = os.path.dirname(os.path.abspath(__main__.__file__))


class DesktopEnvironmentBase(object):

    DEFAULT_ICON_SIZE = 22
    DEFAULT_ICON_BUTTON_SIZE = 16
    DEFAULT_ICON_THEME = "hicolor"
    ICON_SEARCH_PATH = [
        os.path.join(application_prefix, "icons"),
        os.path.join(application_prefix, "share", "icons"),
        os.path.expanduser("~/.local/share/icons"),
        "/usr/share/icons",
        "/usr/local/share/icons",
        ]
    ICON_SIZES = [128, 64, 48, 32, 22, 16]
    ICON_CATEGORIES = [
        "actions", 
        "apps",
        "mimetypes", 
        "devices",
        "filesystems", "."
        ]
    ICON_EXTENSIONS = [".png"]


    def __new__(type):
        # Singleton
        if not '_instance' in type.__dict__:
            type._instance = object.__new__(type)
        return type._instance


    def __init__(self):
        self.init()
        self.cache = {}
        self.theme = self.find_theme()


    def init(self):
        pass


    def __repr__(self):
        return "<Desktop %s>" % self.__class__.__name__.upper()


    def find_icon(self, name, max_size=None):
        max_size = max_size or self.DEFAULT_ICON_SIZE
        try:
            return self.cache[(name,max_size)]
        except KeyError:
            pass

        theme_search_list = [ self.theme ]
        for other_theme in [
            self.DEFAULT_ICON_THEME, #"oxygen", "nuvola", "crystalclear", 
            "."]:
            if other_theme not in theme_search_list:
                theme_search_list.append(other_theme)

        for theme in theme_search_list:
            for size in self.ICON_SIZES:
                if size > max_size: continue
                size_size = "%sx%s" % (size, size)
                for category in self.ICON_CATEGORIES:
                    for path in self.ICON_SEARCH_PATH:
                        for ext in self.ICON_EXTENSIONS:
                            filename = os.path.join(
                                path, theme, size_size, category, name+ext)
                            if os.path.exists(filename):
                                self.cache[(name,max_size)] = filename
                                return filename
        self.cache[(name,max_size)] = None



class Kde(DesktopEnvironmentBase):

    DEFAULT_theme = "default.kde"
    ICON_SEARCH_PATH = [
        os.path.expanduser("~/.kde4/share/icons"),
        os.path.expanduser("~/.kde3/share/icons"),
        os.path.expanduser("~/.kde/share/icons"),
        ] + DesktopEnvironmentBase.ICON_SEARCH_PATH

    KDEHOME = os.path.expanduser(os.environ.get("KDEHOME", "~/.kde"))
    if not os.path.exists(KDEHOME):
        KDEHOME = None

    if KDEHOME not in ICON_SEARCH_PATH:
        ICON_SEARCH_PATH.insert(
            0, os.path.join(KDEHOME, "share", "icons"))


    def init(self):
        self.ini_cache = {}


    def kdeini(self, name, section, key, default=None):
        filename = os.path.join(
            self.KDEHOME, "share", "config", name)
        ini = self.ini_cache.get(filename)
        if not ini:
            ini = self.kdeglobals_cfg = IniFile()
            try:
                ini.read([filename])
            except:
                pass
            self.ini_cache[filename] = ini
        try:
            return ini.get(section, key) or default
        except Exception:
            return default


    def kdeglobals(self, section, key, default=None):
        return self.kdeini("kdeglobals", section, key, default)


    def find_theme(self):
        return self.kdeglobals("Icons", "Theme", self.DEFAULT_ICON_THEME)




class Gnome(DesktopEnvironmentBase):
    
    DEFAULT_ICON_THEME = "gnome"
    ICON_SEARCH_PATH = [
        os.path.expanduser("~/.gnome2/share/icons")
        ] + DesktopEnvironmentBase.ICON_SEARCH_PATH


    def init(self):
        self.etree_cache = {}


    def gconf(self, name, key, default=None):
        filename = os.path.expanduser(
            "~/.gconf/desktop/gnome/%s/%%gconf.xml" % name)
        etree = self.etree_cache.get(filename)
        if not etree:
            try:
                etree = ElementTree(file=open(filename))
                self.etree_cache[filename] = etree
                for entry in etree.findall("entry"):
                    if entry.get("name") == key:
                        return entry.find("stringvalue").text
            except Exception:
                pass
        return default


    def find_theme(self):
        return self.gconf("interface", "icon_theme",
                          self.DEFAULT_ICON_THEME)




if os.environ.get("KDE_FULL_SESSION", "false") == "true":
    desktop = Kde()
else:
    desktop = Gnome()

find_icon = desktop.find_icon