[kupfer] Allow loading custom icons from plugins



commit 2a693217f61bae239e57ee82a383bc2387768caa
Author: Ulrik Sverdrup <ulrik sverdrup gmail com>
Date:   Mon Feb 8 02:08:20 2010 +0100

    Allow loading custom icons from plugins
    
    Plugins (as Python packages, a directory with at least an __init__.py
    file) may contain custom icons.
    
    Plugins should define a file "icon-list" inside the package, which on
    each line defines icons to be loaded by the plugin.
    
    Each line has the format:
    ICON_NAME<TAB>FILENAME
    
    Where FILENAME is the icon's filename (directly in the package), and
    ICON_NAME is the name the icon will use in Kupfer.
    
    Icons should preferably be SVG icons.

 kupfer/core/plugins.py |   48 +++++++++++++++++++++++++++++++++++++++++++++---
 kupfer/icons.py        |   12 ++++++++++++
 2 files changed, 57 insertions(+), 3 deletions(-)
---
diff --git a/kupfer/core/plugins.py b/kupfer/core/plugins.py
index e2cdd60..131190d 100644
--- a/kupfer/core/plugins.py
+++ b/kupfer/core/plugins.py
@@ -1,6 +1,9 @@
 import os
+import pkgutil
+
 import sys
 from kupfer import pretty, config
+from kupfer import icons
 from kupfer.core import settings
 
 sources_attribute = "__kupfer_sources__"
@@ -23,7 +26,6 @@ def get_plugin_ids():
 	"""Enumerate possible plugin ids;
 	return a sequence of possible plugin ids, not
 	guaranteed to be plugins"""
-	import pkgutil
 	from kupfer import plugin
 
 	def is_plugname(plug):
@@ -175,8 +177,6 @@ def _import_plugin_fake(modpath, error=None):
 
 	@error: If applicable, a tuple of exception info
 	"""
-	import pkgutil
-
 	loader = pkgutil.get_loader(modpath)
 	if not loader:
 		return None
@@ -339,10 +339,52 @@ def is_plugin_loaded(plugin_name):
 	return (plugin_name in _imported_plugins and
 			not getattr(_imported_plugins[plugin_name], "is_fake_plugin", None))
 
+def _loader_hook(modpath):
+	modname = ".".join(modpath)
+	loader = pkgutil.find_loader(modname)
+	if not loader:
+		raise ImportError("No loader found for %s" % modname)
+	if not loader.is_package(modname):
+		raise ImportError("Is not a package")
+	return loader
+
+PLUGIN_ICON_FILE = "icon-list"
+
+def _load_icons(plugin_name):
+	try:
+		loader = _staged_import(plugin_name, _loader_hook)
+	except ImportError, exc:
+		return
+	try:
+		filename = loader.filename
+	except AttributeError:
+		# Special case for zipimport
+		filename = os.path.join(loader.archive, loader.prefix, plugin_name)
+	try:
+		icon_file = loader.get_data(os.path.join(filename, PLUGIN_ICON_FILE))
+	except IOError, exc:
+		pretty.print_error(__name__, type(exc).__name__, exc)
+		return
+
+	for line in icon_file.splitlines():
+		# ignore '#'-comments
+		if line.startswith("#") or not line.strip():
+			continue
+		icon_name, basename = (i.strip() for i in line.split("\t", 1))
+		sizes = (24, 96)
+		icon_path = os.path.join(filename, basename)
+		icon_data = loader.get_data(icon_path)
+		if not icon_data:
+			pretty.print_info(__name__, "Icon", basename, icon_path,"not found")
+			continue
+		icons.load_plugin_icon(plugin_name, icon_name, icon_data)
+
+
 def initialize_plugin(plugin_name):
 	"""Initialize plugin.
 	Find settings attribute if defined, and initialize it
 	"""
+	_load_icons(plugin_name)
 	settings_dict = get_plugin_attribute(plugin_name, settings_attribute)
 	if not settings_dict:
 		return
diff --git a/kupfer/icons.py b/kupfer/icons.py
index b5a7a6e..fa343d7 100644
--- a/kupfer/icons.py
+++ b/kupfer/icons.py
@@ -42,6 +42,18 @@ def load_kupfer_icons(sched=None):
 
 scheduler.GetScheduler().connect("load", load_kupfer_icons)
 
+def load_plugin_icon(plugin_name, icon_name, icon_data):
+	"Load icon from @icon_data into the name @icon_name"
+	for size in (24, 96):
+		ploader = gtk.gdk.PixbufLoader()
+		ploader.set_size(size, size)
+		ploader.write(icon_data)
+		ploader.close()
+		pixbuf = ploader.get_pixbuf()
+		gtk.icon_theme_add_builtin_icon(icon_name, size, pixbuf)
+		pretty.print_debug(__name__, "Loading icon", icon_name, "at", size,
+				"for", plugin_name)
+
 def get_icon(key, icon_size):
 	"""
 	try retrieve icon in cache



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]