[kupfer: 51/67] alternatives: Use notifications on changes, update preferences window
- From: Ulrik Sverdrup <usverdrup src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [kupfer: 51/67] alternatives: Use notifications on changes, update preferences window
- Date: Sat, 19 Mar 2011 01:02:01 +0000 (UTC)
commit c97d880d2e46698d6dcfc859b5e49c9b324cb0d4
Author: Ulrik Sverdrup <ulrik sverdrup gmail com>
Date: Sat Mar 19 01:53:38 2011 +0100
alternatives: Use notifications on changes, update preferences window
kupfer/core/settings.py | 39 +++++++++++++++++++++
kupfer/desktop_launch.py | 8 ++--
kupfer/plugin/core/__init__.py | 4 ++-
kupfer/plugin/core/terminals.py | 46 +++++++++++++++++++++++++
kupfer/plugin_support.py | 58 ++++++++++++++++++++++++--------
kupfer/terminal.py | 70 +++------------------------------------
kupfer/ui/preferences.py | 48 +++++++++++++++++++-------
kupfer/utils.py | 16 +++++----
8 files changed, 185 insertions(+), 104 deletions(-)
---
diff --git a/kupfer/core/settings.py b/kupfer/core/settings.py
index 9f8a545..b81c50a 100644
--- a/kupfer/core/settings.py
+++ b/kupfer/core/settings.py
@@ -47,6 +47,8 @@ class SettingsController (gobject.GObject, pretty.OutputMixin):
self._defaults_path = None
self._config = self._read_config()
self._save_timer = scheduler.Timer(True)
+ self._alternatives = {}
+ self._alternative_validators = {}
def _update_config_save_timer(self):
self._save_timer.set(60, self._save_config)
@@ -378,6 +380,38 @@ class SettingsController (gobject.GObject, pretty.OutputMixin):
def set_preferred_tool(self, tool_id, value):
return self._set_config("Tools", tool_id, value)
+ ## Alternatives section
+ ## Provide alternatives for each category
+ ## for example the category "terminal"
+ def get_valid_alternative_ids(self, category_key):
+ """
+ Get a list of (id_, name) tuples for the given @category_key
+ """
+ validator = self._alternative_validators[category_key]
+ for (id_, alternative) in self._alternatives[category_key].iteritems():
+ name = alternative["name"]
+ if not validator or validator(alternative):
+ yield (id_, name)
+
+ def get_all_alternatives(self, category_key):
+ return self._alternatives[category_key]
+
+ def get_preferred_alternative(self, category_key):
+ """
+ Get preferred alternative dict for @category_key
+ """
+ tool_id = self.get_preferred_tool(category_key)
+ alternatives = self._alternatives[category_key]
+ alt = alternatives.get(tool_id)
+ if not alt:
+ self.output_debug("Warning, no configuration for", category_key)
+ return alt or next(alternatives.itervalues(), None)
+
+ def _update_alternatives(self, category_key, alternatives, validator):
+ self._alternatives[category_key] = alternatives
+ self._alternative_validators[category_key] = validator
+ self.emit("alternatives-changed", category_key)
+
# Section, Key, Value
gobject.signal_new("value-changed", SettingsController, gobject.SIGNAL_RUN_LAST,
@@ -394,6 +428,11 @@ gobject.signal_new("plugin-toplevel-changed", SettingsController,
gobject.SIGNAL_RUN_LAST, gobject.TYPE_BOOLEAN,
(gobject.TYPE_STRING, gobject.TYPE_INT))
+# Arguments: Alternative-category
+gobject.signal_new("alternatives-changed", SettingsController,
+ gobject.SIGNAL_RUN_LAST, gobject.TYPE_BOOLEAN,
+ (gobject.TYPE_STRING, ))
+
_settings_controller = None
def GetSettingsController():
global _settings_controller
diff --git a/kupfer/desktop_launch.py b/kupfer/desktop_launch.py
index 6df1a5b..965a7d9 100644
--- a/kupfer/desktop_launch.py
+++ b/kupfer/desktop_launch.py
@@ -305,14 +305,14 @@ def launch_app_info(app_info, gfiles=[], in_terminal=None, timestamp=None,
in_terminal = desktop_info["Terminal"]
if in_terminal:
term = terminal.get_configured_terminal()
- notify = notify or term.startup_notify
+ notify = notify or term["startup_notify"]
for argv, gfiles in launch_records:
if in_terminal:
term = terminal.get_configured_terminal()
- targv = list(term.argv)
- if term.exearg:
- targv.append(term.exearg)
+ targv = list(term["argv"])
+ if term["exearg"]:
+ targv.append(term["exearg"])
argv = targv + argv
ret = spawn_app(app_info, argv, gfiles, workdir, notify,
timestamp=timestamp, launch_cb=launch_cb)
diff --git a/kupfer/plugin/core/__init__.py b/kupfer/plugin/core/__init__.py
index c8f5df9..bc8a951 100644
--- a/kupfer/plugin/core/__init__.py
+++ b/kupfer/plugin/core/__init__.py
@@ -22,6 +22,7 @@ from kupfer import commandexec
from kupfer import interface
from kupfer import pretty
from kupfer import task
+from kupfer import plugin_support
def _is_debug():
@@ -40,7 +41,8 @@ def register_subplugin(module):
globals()[attr] += object_names
globals().update((sym, getattr(module, sym)) for sym in object_names)
-from kupfer.plugin.core import contents, selection, text, internal, commands
+from kupfer.plugin.core import (contents, selection, text, internal, commands,
+ terminals)
register_subplugin(contents)
register_subplugin(selection)
diff --git a/kupfer/plugin/core/terminals.py b/kupfer/plugin/core/terminals.py
new file mode 100644
index 0000000..3e1c9ca
--- /dev/null
+++ b/kupfer/plugin/core/terminals.py
@@ -0,0 +1,46 @@
+from kupfer import plugin_support
+
+plugin_support.register_alternative(__name__, 'terminal', 'gnome-terminal',
+ **{
+ 'name': _("GNOME Terminal"),
+ 'argv': ['gnome-terminal'],
+ 'exearg': '-x',
+ 'desktopid': "gnome-terminal.desktop",
+ 'startup_notify': True,
+ })
+
+plugin_support.register_alternative(__name__, 'terminal', 'xfce4-terminal',
+ **{
+ 'name': _("XFCE Terminal"),
+ 'argv': ['xfce4-terminal'],
+ 'exearg': '-x',
+ 'desktopid': "xfce4-terminal.desktop",
+ 'startup_notify': True,
+ })
+
+plugin_support.register_alternative(__name__, 'terminal', 'lxterminal',
+ **{
+ 'name': _("LXTerminal"),
+ 'argv': ['lxterminal'],
+ 'exearg': '-e',
+ 'desktopid': "lxterminal.desktop",
+ 'startup_notify': False,
+ })
+
+plugin_support.register_alternative(__name__, 'terminal', 'xterm',
+ **{
+ 'name': _("X Terminal"),
+ 'argv': ['xterm'],
+ 'exearg': '-e',
+ 'desktopid': "xterm.desktop",
+ 'startup_notify': False,
+ })
+
+plugin_support.register_alternative(__name__, 'terminal', 'urxvt',
+ **{
+ 'name': _("Urxvt"),
+ 'argv': ['urxvt'],
+ 'exearg': '-e',
+ 'desktopid': "urxvt.desktop",
+ 'startup_notify': False,
+ })
diff --git a/kupfer/plugin_support.py b/kupfer/plugin_support.py
index 11d1e5b..a6ed9e9 100644
--- a/kupfer/plugin_support.py
+++ b/kupfer/plugin_support.py
@@ -1,3 +1,5 @@
+import os
+
import gobject
try:
@@ -184,24 +186,44 @@ if not keyring:
def _plugin_configuration_error(plugin, err):
pretty.print_error(__name__, err)
+
+def _is_valid_terminal(term_dict):
+ if len(term_dict["argv"]) < 1:
+ return False
+ exe = term_dict["argv"][0]
+ # iterate over $PATH directories
+ PATH = os.environ.get("PATH") or os.defpath
+ for execdir in PATH.split(os.pathsep):
+ exepath = os.path.join(execdir, exe)
+ if os.access(exepath, os.R_OK|os.X_OK) and os.path.isfile(exepath):
+ return True
+
_available_alternatives = {
"terminal": {
- "constructor": terminal.Terminal,
- "registrator": terminal.register_terminal,
- "unregistrator": terminal.unregister_terminal,
- "key": "terminal",
+ "filter": _is_valid_terminal,
+ "required_keys": {
+ 'name': unicode,
+ 'argv': list,
+ 'exearg': str,
+ 'desktopid': str,
+ 'startup_notify': bool,
+ },
+ },
}
+
+_alternatives = {
+ "terminal": {},
}
-def register_alternative(caller, category_key, id_, *arguments, **kwargs):
+
+def register_alternative(caller, category_key, id_, **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.
+ @kwargs are the keyed arguments for the alternative constructor
Returns True with success
"""
@@ -215,17 +237,20 @@ def register_alternative(caller, category_key, id_, *arguments, **kwargs):
return
alt = _available_alternatives[category_key]
id_ = caller + "." + id_
- try:
- alt_obj = alt["constructor"](*arguments)
- alt["registrator"](id_, alt_obj)
- except Exception as exc:
+ kw_set = set(kwargs)
+ req_set = set(alt["required_keys"])
+ if not req_set.issubset(kw_set):
_plugin_configuration_error(caller,
"Configuration error for alternative '%s':" % category_key)
- _plugin_configuration_error(caller, exc)
+ _plugin_configuration_error(caller, "Missing keys: %s" %
+ (req_set - kw_set))
return
+ _alternatives[category_key][id_] = kwargs
pretty.print_debug(__name__,
"Registered alternative %s.%s from %s" % (category_key, id_, caller))
-
+ setctl = settings.GetSettingsController()
+ setctl._update_alternatives(category_key, _alternatives[category_key],
+ alt["filter"])
return True
def unregister_alternative(caller, category_key, id_):
@@ -242,11 +267,16 @@ def unregister_alternative(caller, category_key, id_):
alt = _available_alternatives[category_key]
id_ = caller + "." + id_
try:
- alt["unregistrator"](id_)
+ del _alternatives[category_key][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))
+ setctl = settings.GetSettingsController()
+ setctl._update_alternatives(category_key, _alternatives[category_key],
+ alt["filter"])
return True
+
+
diff --git a/kupfer/terminal.py b/kupfer/terminal.py
index a6c5fef..d7d076a 100644
--- a/kupfer/terminal.py
+++ b/kupfer/terminal.py
@@ -1,77 +1,17 @@
-import os
-
-_TERMINALS = {}
-
-class Terminal (object):
- """
- @id_ should be unique and if possible the
- application id
- """
- def __init__(self, name, argv, exearg, id_, startup_notify=False):
- self.name = unicode(name)
- self.argv = list(argv)
- self.exearg = str(exearg)
- self.startup_notify = bool(startup_notify)
- self.app_id = str(id_)
- def __unicode__(self):
- return self.name
- def get_id(self):
- return self.app_id
-
-def register_terminal(id_, terminal_description):
- """Register @terminal_description (can be used by plugins)"""
- _TERMINALS[id_] = terminal_description
-
-def unregister_terminal(terminal_id):
- _TERMINALS.pop(terminal_id, None)
+from kupfer.core import settings
def is_known_terminal_executable(exearg):
- "Return True if @exearg is a known terminal"
- for term in _TERMINALS.itervalues():
- if exearg == term.argv[0]:
+ setctl = settings.GetSettingsController()
+ for id_, term in setctl.get_all_alternatives('terminal').iteritems():
+ if exearg == term["argv"][0]:
return True
return False
-def get_valid_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 (id_, unicode(term))
- break
def get_configured_terminal():
"""
Return the configured Terminal object
"""
- from kupfer.core import settings
setctl = settings.GetSettingsController()
- id_ = setctl.get_preferred_tool('terminal')
- return _TERMINALS.get(id_) or _TERMINALS["default"]
-
-# Insert default terminals
-
-register_terminal("gnome-terminal",
- Terminal(_("GNOME Terminal"), ["gnome-terminal"],
- "-x", "gnome-terminal.desktop", True))
-
-register_terminal("xfce4-terminal",
- Terminal(_("XFCE Terminal"), ["xfce4-terminal"],
- "-x", "xfce4-terminal.desktop", True))
-
-register_terminal("urxvt",
- Terminal(_("Urxvt"), ["urxvt"],
- "-e", "urxvt.desktop", False))
-
-register_terminal("lxterminal",
- Terminal(_("LXTerminal"), ["lxterminal"],
- "-e", "lxterminal.desktop", False))
-
-register_terminal("default",
- Terminal(_("X Terminal"), ["xterm"],
- "-e", "xterm.desktop", False))
-
+ return setctl.get_preferred_alternative('terminal')
diff --git a/kupfer/ui/preferences.py b/kupfer/ui/preferences.py
index 8c1472d..2528190 100644
--- a/kupfer/ui/preferences.py
+++ b/kupfer/ui/preferences.py
@@ -127,17 +127,11 @@ class PreferencesWindowController (pretty.OutputMixin):
terminal_combobox.pack_start(terminal_combobox_cell, True)
terminal_combobox.add_attribute(terminal_combobox_cell, 'text', 0)
- term_id = setctl.get_preferred_tool('terminal')
- # fill in the available terminals
- terminals = utils.locale_sort(terminal.get_valid_terminals(),
- key=lambda t:t[1])
- term_iter = None
- 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)
+ self._update_terminal_combobox(terminal_combobox,
+ terminal_combobox_store)
+ self.terminal_combobox = terminal_combobox
+ self.terminal_combobox_store = terminal_combobox_store
+ setctl.connect("alternatives-changed", self._on_alternatives_changed)
# Plugin List
columns = [
@@ -766,8 +760,36 @@ class PreferencesWindowController (pretty.OutputMixin):
def on_terminal_combobox_changed(self, widget):
setctl = settings.GetSettingsController()
itr = widget.get_active_iter()
- term_id = widget.get_model().get_value(itr, 1)
- setctl.set_preferred_tool('terminal', term_id)
+ if itr:
+ term_id = widget.get_model().get_value(itr, 1)
+ setctl.set_preferred_tool('terminal', term_id)
+
+ def _update_terminal_combobox(self, combobox, combobox_store):
+ """
+ Terminals changed
+ """
+ print "_update_terminal_combobox"
+ combobox_store.clear()
+ setctl = settings.GetSettingsController()
+ term_id = setctl.get_preferred_tool('terminal')
+ print term_id
+ # fill in the available terminals
+ terminals = utils.locale_sort(
+ setctl.get_valid_alternative_ids('terminal'), key=lambda t:t[1])
+ term_iter = None
+ for (id_, name) in terminals:
+ _it = combobox_store.append((name, id_))
+ if id_ == term_id:
+ term_iter = _it
+ # Update selection
+ term_iter = term_iter or combobox_store.get_iter_first()
+ combobox.set_active_iter(term_iter)
+
+ def _on_alternatives_changed(self, setctl, category_key):
+ if category_key == 'terminal':
+ self._update_terminal_combobox(
+ self.terminal_combobox,
+ self.terminal_combobox_store)
def show(self):
self.window.present()
diff --git a/kupfer/utils.py b/kupfer/utils.py
index 50b25c3..6dba507 100644
--- a/kupfer/utils.py
+++ b/kupfer/utils.py
@@ -182,17 +182,19 @@ class AsyncCommand (object):
def spawn_terminal(workdir=None):
term = terminal.get_configured_terminal()
- notify = term.startup_notify
- desktop_launch.spawn_app_id(term.app_id, term.argv, workdir, notify)
+ notify = term["startup_notify"]
+ app_id = term["desktopid"]
+ argv = term["argv"]
+ desktop_launch.spawn_app_id(app_id, argv, workdir, notify)
def spawn_in_terminal(argv, workdir=None):
term = terminal.get_configured_terminal()
- notify = term.startup_notify
- _argv = list(term.argv)
- if term.exearg:
- _argv.append(term.exearg)
+ notify = term["startup_notify"]
+ _argv = list(term["argv"])
+ if term["exearg"]:
+ _argv.append(term["exearg"])
_argv.extend(argv)
- desktop_launch.spawn_app_id(term.app_id, _argv , workdir, notify)
+ desktop_launch.spawn_app_id(term["desktopid"], _argv , workdir, notify)
def spawn_async_notify_as(app_id, argv):
"""
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]