[kupfer: 1/11] compose: Add keybinding Control+Return to compose Object + Action



commit c647e64d0de70d8007a98e3fbe9949bc7ed59081
Author: Ulrik Sverdrup <ulrik sverdrup gmail com>
Date:   Sun Dec 13 21:01:46 2009 +0100

    compose: Add keybinding Control+Return to compose Object + Action
    
    Composition allow the user to make one Kupfer object out of an
    (Object, Action) pair or an (Object, Action, Indirect Object) tuple.
    
    If we allow the user to create objects out of these combinations, we
    can later add "higher orders" of Kupfer usage, for example -- run
    action at (later) time, add alias or trigger for this action, etc.
    
    At the moment, we only allow to run the composed object, and thus the
    feature does not have much use (yet).

 kupfer/browser.py |    4 ++++
 kupfer/data.py    |   14 ++++++++++++++
 kupfer/objects.py |   36 ++++++++++++++++++++++++++++++++++++
 3 files changed, 54 insertions(+), 0 deletions(-)
---
diff --git a/kupfer/browser.py b/kupfer/browser.py
index 173ca20..dea56f8 100644
--- a/kupfer/browser.py
+++ b/kupfer/browser.py
@@ -856,6 +856,7 @@ class Interface (gobject.GObject):
 			"<Control>t" : "select_selected_text",
 			"<Control>q" : "select_quit",
 			"<Alt>a" : "activate",
+			"<Control>Return": "compose_action",
 		}
 		direct_text_key = gtk.gdk.keyval_from_name("period")
 		init_text_keys = map(gtk.gdk.keyval_from_name, ("slash", "equal"))
@@ -1138,6 +1139,9 @@ class Interface (gobject.GObject):
 	def select_quit(self):
 		self.data_controller.find_object("qpfer:quit")
 
+	def compose_action(self):
+		self.data_controller.compose_selection()
+
 	def _pane_reset(self, controller, pane, item):
 		wid = self._widget_for_pane(pane)
 		if not item:
diff --git a/kupfer/data.py b/kupfer/data.py
index 7210f5f..1907b49 100644
--- a/kupfer/data.py
+++ b/kupfer/data.py
@@ -1079,6 +1079,20 @@ class DataController (gobject.GObject, pretty.OutputMixin):
 		if found and not found == self.source_pane.get_selection():
 			self.emit("pane-reset", SourcePane, search.wrap_rankable(found))
 
+	def compose_selection(self):
+		leaf = self.source_pane.get_selection()
+		action = self.action_pane.get_selection()
+		if leaf is None or action is None:
+			return
+		iobj = self.object_pane.get_selection()
+		if self.mode is SourceActionObjectMode:
+			if iobj is None:
+				return
+		else:
+			iobj = None
+		obj = objects.ComposedLeaf(leaf, action, iobj)
+		self.emit("pane-reset", SourcePane, search.wrap_rankable(obj))
+
 # pane cleared or set with new item
 # pane, item
 gobject.signal_new("pane-reset", DataController, gobject.SIGNAL_RUN_LAST,
diff --git a/kupfer/objects.py b/kupfer/objects.py
index 4f64eda..dc795c6 100644
--- a/kupfer/objects.py
+++ b/kupfer/objects.py
@@ -1111,3 +1111,39 @@ class TextSource (KupferObject):
 		"""A seq of the types of items it provides"""
 		yield Leaf
 
+class ProxyDo (Action):
+	"""A proxy version of Do
+
+	Proxy factory/result/async from a delegate action
+	"""
+	def __init__(self, action):
+		Action.__init__(self, _("Do"))
+		self.action = action
+
+	def activate(self, leaf, obj=None):
+		return leaf.run()
+
+	def is_factory(self):
+		return self.action.is_factory()
+	def has_result(self):
+		return self.action.has_result()
+	def is_async(self):
+		return self.action.is_async()
+
+class ComposedLeaf (RunnableLeaf):
+	def __init__(self, obj, action, iobj=None):
+		object_ = (obj, action, iobj)
+		name = u" â?? ".join([unicode(o) for o in object_ if o is not None])
+		RunnableLeaf.__init__(self, object_, name)
+
+	def get_actions(self):
+		yield ProxyDo(self.object[1])
+
+	def run(self):
+		obj, action, iobj = self.object
+		args = (obj, iobj) if iobj is not None else (obj, )
+		return action.activate(*args)
+
+	def get_gicon(self):
+		return icons.ComposedIcon(self.object[0].get_icon(),
+				self.object[1].get_icon())



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