[kupfer: 4/4] Introduce ActionGenerator



commit 5924d6cc193debc072594991e9d6cc0830c6885f
Author: Karol BÄ?dkowski <karol bedkowski gmail com>
Date:   Thu May 6 14:50:33 2010 +0200

    Introduce ActionGenerator
    
    Plugins can provide new "generators" for actions by
    __kupfer_action_generators__ and subclassing ActionGenerator.
    Action generator should return actions objects for given leaf.

 kupfer/core/data.py       |    6 ++++++
 kupfer/core/pluginload.py |    7 ++++++-
 kupfer/core/plugins.py    |    1 +
 kupfer/core/sources.py    |    6 ++++++
 kupfer/obj/base.py        |   17 +++++++++++++++--
 5 files changed, 34 insertions(+), 3 deletions(-)
---
diff --git a/kupfer/core/data.py b/kupfer/core/data.py
index 963a369..10ecb18 100644
--- a/kupfer/core/data.py
+++ b/kupfer/core/data.py
@@ -484,6 +484,11 @@ class DataController (gobject.GObject, pretty.OutputMixin):
 			self.output_debug(typ.__name__)
 			self._list_plugin_objects(decorate_item_types[typ])
 
+	def register_action_generators(self, generators):
+		sc = GetSourceController()
+		for generator in generators:
+			sc.add_action_generator(generator)
+
 	def _list_plugin_objects(self, objs):
 		"Print a list of plugin objects to debug output"
 		for o in objs:
@@ -575,6 +580,7 @@ class DataController (gobject.GObject, pretty.OutputMixin):
 			self.register_text_sources(plugin.text_sources)
 			self.register_action_decorators(plugin.action_decorators)
 			self.register_content_decorators(plugin.content_decorators)
+			self.register_action_generators(plugin.action_generators)
 			return set(plugin.sources)
 		return set()
 
diff --git a/kupfer/core/pluginload.py b/kupfer/core/pluginload.py
index c914352..03fb5e1 100644
--- a/kupfer/core/pluginload.py
+++ b/kupfer/core/pluginload.py
@@ -5,13 +5,14 @@ from kupfer import pretty
 from kupfer.core import plugins
 from kupfer.core.plugins import (load_plugin_sources, sources_attribute,
 		action_decorators_attribute, text_sources_attribute,
-		content_decorators_attribute,
+		content_decorators_attribute, action_generators_attribute,
 		initialize_plugin)
 
 class PluginDescription (object):
 	text_sources = ()
 	action_decorators = ()
 	content_decorators = ()
+	action_generators = ()
 	sources = ()
 
 def load_plugin(plugin_id):
@@ -23,6 +24,7 @@ def load_plugin(plugin_id):
 	text_sources = []
 	action_decorators = []
 	content_decorators = []
+	action_generators = []
 
 	item = plugin_id
 
@@ -32,6 +34,8 @@ def load_plugin(plugin_id):
 	text_sources.extend(load_plugin_sources(item, text_sources_attribute))
 	action_decorators.extend(load_plugin_sources(item,
 		action_decorators_attribute))
+	action_generators.extend(load_plugin_sources(item,
+		action_generators_attribute))
 
 	# Register all Sources as (potential) content decorators
 	content_decorators.extend(load_plugin_sources(item,
@@ -46,6 +50,7 @@ def load_plugin(plugin_id):
 	desc.action_decorators = action_decorators
 	desc.content_decorators = content_decorators
 	desc.sources = sources
+	desc.action_generators = action_generators
 	return desc
 
 @contextlib.contextmanager
diff --git a/kupfer/core/plugins.py b/kupfer/core/plugins.py
index 129767b..e5de73a 100644
--- a/kupfer/core/plugins.py
+++ b/kupfer/core/plugins.py
@@ -11,6 +11,7 @@ text_sources_attribute = "__kupfer_text_sources__"
 content_decorators_attribute = "__kupfer_contents__"
 action_decorators_attribute = "__kupfer_actions__"
 settings_attribute = "__kupfer_settings__"
+action_generators_attribute = "__kupfer_action_generators__"
 
 info_attributes = [
 		"__kupfer_name__",
diff --git a/kupfer/core/sources.py b/kupfer/core/sources.py
index c4d6ff6..6eaec86 100644
--- a/kupfer/core/sources.py
+++ b/kupfer/core/sources.py
@@ -253,6 +253,7 @@ class SourceController (pretty.OutputMixin):
 		self.text_sources = set()
 		self.content_decorators = {}
 		self.action_decorators = {}
+		self.action_generators = []
 		self.loaded_successfully = False
 		self._restored_sources = set()
 		self._pre_root = None
@@ -282,6 +283,8 @@ class SourceController (pretty.OutputMixin):
 			self.action_decorators.setdefault(typ, set()).update(decos[typ])
 		for typ in self.action_decorators:
 			self._disambiguate_actions(self.action_decorators[typ])
+	def add_action_generator(self, agenerator):
+		self.action_generators.append(agenerator)
 	def _disambiguate_actions(self, actions):
 		"""Rename actions by the same name (adding a suffix)"""
 		# FIXME: Disambiguate by plugin name, not python module name
@@ -392,6 +395,9 @@ class SourceController (pretty.OutputMixin):
 			if isinstance(leaf, typ):
 				for act in self.action_decorators[typ]:
 					yield act
+		for agenerator in self.action_generators:
+			for action in agenerator.get_actions_for_leaf(leaf):
+				yield action
 
 	def decorate_object(self, obj, action=None):
 		if hasattr(obj, "has_content"):
diff --git a/kupfer/obj/base.py b/kupfer/obj/base.py
index 55d7669..87f3f48 100644
--- a/kupfer/obj/base.py
+++ b/kupfer/obj/base.py
@@ -150,7 +150,7 @@ class KupferObject (object):
 	def get_gicon(self):
 		"""Return GIcon, if there is one"""
 		return None
-	
+
 	def get_icon_name(self):
 		"""Return icon name. All items should have at least
 		a generic icon name to return.
@@ -185,7 +185,7 @@ class Leaf (KupferObject):
 		super(Leaf, self).__init__(name)
 		self.object = obj
 		self._content_source = None
-	
+
 	def __hash__(self):
 		return hash(unicode(self))
 
@@ -458,3 +458,16 @@ class TextSource (KupferObject):
 		"""A seq of the types of items it provides"""
 		yield Leaf
 
+
+class ActionGenerator (object):
+	"""A "source" for actions
+
+	NOTE: The ActionGenerator should not perform any expensive
+	computation, and not access any slow media (files, network) when
+	returning actions.  Such expensive checks must be performed in
+	each Action's valid_for_item method.
+	"""
+
+	def get_actions_for_leaf(self, leaf):
+		'''Return actions appropriate for given leaf. '''
+		return []



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