1import os
2from gi.repository import Gio
3from caribou.settings.setting_types import *
4
5class SettingsManager(object):
6    def __init__(self, settings):
7        self.groups = settings
8        self._gsettings = Gio.Settings(settings.schema_id)
9        self._gsettings.connect("changed", self._gsettings_changed_cb)
10        self._settings_map = {}
11        self._map_settings(self.groups)
12
13        self._setup_settings()
14
15    def __getattr__(self, name):
16        try:
17            return self._settings_map[name]
18        except KeyError:
19            raise AttributeError("no setting named '%s'" % name)
20
21    def _map_settings(self, setting):
22        if setting.name in self._settings_map:
23            raise ValueError("more than one setting has the name '%s'" % setting.name)
24        self._settings_map[setting.name] = setting
25
26        for s in setting:
27            self._map_settings(s)
28
29    def _setup_settings(self):
30        for setting in list(self._settings_map.values()):
31            if isinstance(setting, SettingsGroup):
32                continue
33            setting.value = \
34                self._gsettings.get_value(setting.gsettings_key).unpack()
35
36            self._change_dependant_sensitivity(setting)
37
38            setting.connect('value-changed', self._on_value_changed)
39
40    def _change_dependant_sensitivity(self, setting):
41        for name in setting.insensitive_when_false:
42            self._settings_map[name].sensitive = setting.is_true
43        for name in setting.insensitive_when_true:
44            self._settings_map[name].sensitive = not setting.is_true
45        if setting.allowed:
46            index = [a for a, b in setting.allowed].index(setting.value)
47            for i, child in enumerate(setting.children):
48                child.sensitive = i == index
49
50    def _on_value_changed(self, setting, value):
51        if value != \
52                self._gsettings.get_value(setting.gsettings_key).unpack():
53            self._gsettings.set_value(setting.gsettings_key, setting.gvariant)
54            self._change_dependant_sensitivity(setting)
55
56    def _gsettings_changed_cb(self, gsettings, key):
57        setting = getattr(self, key.replace('-', '_'))
58        new_value = gsettings.get_value(key).unpack()
59        if setting.value != new_value:
60            setting.hush = True
61            setting.value = new_value
62            setting.hush = False
63
64    def __call__(self):
65        return self
66