[kupfer: 50/67] Introduce 'alternatives' that plugins may register



commit d3c3eb95cbb8eb1100c4150790c1777579375104
Author: Ulrik Sverdrup <ulrik sverdrup gmail com>
Date:   Sat Mar 19 01:53:38 2011 +0100

    Introduce 'alternatives' that plugins may register
    
    Alternatives are mutually exclusive features, for example which
    terminal emulator to use. Kupfer pre-registers categories (for example
    'terminal' is a category) and plugins can provide alternatives within
    this category. The user must configure _one_ preference within the
    category.

 data/defaults.cfg        |    2 +-
 kupfer/plugin_support.py |   72 ++++++++++++++++++++++++++++++++++++++++++++++
 kupfer/terminal.py       |   46 ++++++++++++++++-------------
 kupfer/ui/preferences.py |    9 +++--
 4 files changed, 103 insertions(+), 26 deletions(-)
---
diff --git a/data/defaults.cfg b/data/defaults.cfg
index 006ad09..647649e 100644
--- a/data/defaults.cfg
+++ b/data/defaults.cfg
@@ -27,7 +27,7 @@ switch_to_source = <Control>s
 toggle_text_mode_quick = <Control>period
 
 [Tools]
-terminal = gnome-terminal.desktop
+terminal = gnome-terminal
 
 
 # Catalog: The sources of the plugin are included
diff --git a/kupfer/plugin_support.py b/kupfer/plugin_support.py
index c8501b5..11d1e5b 100644
--- a/kupfer/plugin_support.py
+++ b/kupfer/plugin_support.py
@@ -9,11 +9,13 @@ except ImportError:
 from kupfer import pretty
 from kupfer import config
 from kupfer.core import settings
+from kupfer import terminal
 
 __all__ = [
 	"UserNamePassword",
 	"PluginSettings",
 	"check_dbus_connection",
+	"check_keyring_support",
 ]
 
 def _is_core_setting(key):
@@ -178,3 +180,73 @@ if not keyring:
 	class UserNamePassword (object):
 		pass
 
+
+def _plugin_configuration_error(plugin, err):
+	pretty.print_error(__name__, err)
+
+_available_alternatives = {
+	"terminal": {
+		"constructor": terminal.Terminal,
+		"registrator": terminal.register_terminal,
+		"unregistrator": terminal.unregister_terminal,
+		"key": "terminal",
+	}
+}
+
+def register_alternative(caller, category_key, id_, *arguments, **kwargs):
+	"""
+	Register a new alternative for the category @category_key
+
+	@caller: Must be the caller's plugin id (Plugin __name__ variable)
+
+	@id_ is a string identifier for the object to register
+	All the @arguments are passed to the alternative constructor
+	All @kwargs are ignored at the moment.
+
+	Returns True with success
+	"""
+	caller = str(caller)
+	category_key = str(category_key)
+	id_ = str(id_)
+
+	if category_key not in _available_alternatives:
+		_plugin_configuration_error(caller,
+				"Category '%s' does not exist" % category_key)
+		return
+	alt = _available_alternatives[category_key]
+	id_ = caller + "." + id_
+	try:
+		alt_obj = alt["constructor"](*arguments)
+		alt["registrator"](id_, alt_obj)
+	except Exception as exc:
+		_plugin_configuration_error(caller,
+			"Configuration error for alternative '%s':" % category_key)
+		_plugin_configuration_error(caller, exc)
+		return
+	pretty.print_debug(__name__,
+		"Registered alternative %s.%s from %s" % (category_key, id_, caller))
+
+	return True
+
+def unregister_alternative(caller, category_key, id_):
+	"""
+	Remove the alternative for category @category_key
+	"""
+	caller = str(caller)
+	category_key = str(category_key)
+	id_ = str(id_)
+	if category_key not in _available_alternatives:
+		_plugin_configuration_error(caller,
+				"Category '%s' does not exist" % category_key)
+		return
+	alt = _available_alternatives[category_key]
+	id_ = caller + "." + id_
+	try:
+		alt["unregistrator"](id_)
+	except KeyError:
+		_plugin_configuration_error(caller,
+				"Alternative '%s' does not exist" % (id_, ))
+		return
+	pretty.print_debug(__name__,
+		"Unregistered alternative %s.%s from %s" % (category_key, id_, caller))
+	return True
diff --git a/kupfer/terminal.py b/kupfer/terminal.py
index 470df87..a6c5fef 100644
--- a/kupfer/terminal.py
+++ b/kupfer/terminal.py
@@ -1,6 +1,6 @@
 import os
 
-_TERMINALS = []
+_TERMINALS = {}
 
 class Terminal (object):
 	"""
@@ -18,28 +18,29 @@ class Terminal (object):
 	def get_id(self):
 		return self.app_id
 
-def register_terminal(terminal_description):
+def register_terminal(id_, terminal_description):
 	"""Register @terminal_description (can be used by plugins)"""
-	_TERMINALS.append(terminal_description)
+	_TERMINALS[id_] = terminal_description
 
 def unregister_terminal(terminal_id):
-	_TERMINALS[:] = [t for t in _TERMINALS if t.app_id != terminal_id]
+	_TERMINALS.pop(terminal_id, None)
 
 def is_known_terminal_executable(exearg):
 	"Return True if @exearg is a known terminal"
-	for term in _TERMINALS:
+	for term in _TERMINALS.itervalues():
 		if exearg == term.argv[0]:
 			return True
 	return False
 
 def get_valid_terminals():
-	for term in _TERMINALS:
+	""" Yield (identifier, unicode name) tuples """
+	for id_, term in _TERMINALS.iteritems():
 		# iterate over $PATH directories
 		PATH = os.environ.get("PATH") or os.defpath
 		for execdir in PATH.split(os.pathsep):
 			exepath = os.path.join(execdir, term.argv[0])
 			if os.access(exepath, os.R_OK|os.X_OK) and os.path.isfile(exepath):
-				yield term
+				yield (id_, unicode(term))
 				break
 
 def get_configured_terminal():
@@ -49,25 +50,28 @@ def get_configured_terminal():
 	from kupfer.core import settings
 	setctl = settings.GetSettingsController()
 	id_ = setctl.get_preferred_tool('terminal')
-	for term in _TERMINALS:
-		if term.app_id == id_:
-			return term
-	return _TERMINALS[0]
+	return _TERMINALS.get(id_) or _TERMINALS["default"]
 
 # Insert default terminals
 
-register_terminal(Terminal(_("GNOME Terminal"), ["gnome-terminal"],
-                             "-x", "gnome-terminal.desktop", True))
+register_terminal("gnome-terminal",
+                  Terminal(_("GNOME Terminal"), ["gnome-terminal"],
+                  "-x", "gnome-terminal.desktop", True))
 
-register_terminal(Terminal(_("XFCE Terminal"), ["xfce4-terminal"],
-                             "-x", "xfce4-terminal.desktop", True))
+register_terminal("xfce4-terminal",
+                  Terminal(_("XFCE Terminal"), ["xfce4-terminal"],
+                  "-x", "xfce4-terminal.desktop", True))
 
-register_terminal(Terminal(_("Urxvt"), ["urxvt"],
-                             "-e", "urxvt.desktop", False))
+register_terminal("urxvt",
+                  Terminal(_("Urxvt"), ["urxvt"],
+                  "-e", "urxvt.desktop", False))
 
-register_terminal(Terminal(_("LXTerminal"), ["lxterminal"],
-                             "-e", "lxterminal.desktop", False))
+register_terminal("lxterminal",
+                  Terminal(_("LXTerminal"), ["lxterminal"],
+                  "-e", "lxterminal.desktop", False))
+
+register_terminal("default",
+                  Terminal(_("X Terminal"), ["xterm"],
+                  "-e", "xterm.desktop", False))
 
-register_terminal(Terminal(_("X Terminal"), ["xterm"],
-                             "-e", "xterm.desktop", False))
 
diff --git a/kupfer/ui/preferences.py b/kupfer/ui/preferences.py
index 740da7d..8c1472d 100644
--- a/kupfer/ui/preferences.py
+++ b/kupfer/ui/preferences.py
@@ -129,11 +129,12 @@ class PreferencesWindowController (pretty.OutputMixin):
 
 		term_id = setctl.get_preferred_tool('terminal')
 		# fill in the available terminals
-		terminals = utils.locale_sort(terminal.get_valid_terminals())
+		terminals = utils.locale_sort(terminal.get_valid_terminals(),
+		                              key=lambda t:t[1])
 		term_iter = None
-		for term in terminals:
-			_it = terminal_combobox_store.append((unicode(term), term.get_id()))
-			if term.get_id() == term_id:
+		for (id_, name) in terminals:
+			_it = terminal_combobox_store.append((name, id_))
+			if id_ == term_id:
 				term_iter = _it
 		term_iter = term_iter or terminal_combobox_store.get_iter_first()
 		terminal_combobox.set_active_iter(term_iter)



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