1 """ROX-Session settings with D-Bus and optional Gnome (gconf) setting
3 Setting and Settings are derived from ROX-Lib's Option and OptionGroup
4 respectively. A Setting sends a dbus message to ROX-Session when changed.
6 Use get_xsettings to get the dbus interface, then create a Settings object
7 with it to pass to each Setting.
11 from rox
.options
import OptionGroup
, Option
12 from rox
import OptionsBox
18 _warned_import
= False
19 _warned_connect
= False
23 """Returns ROX-Session's Settings dbus/xxmlrpc interface.
25 Called automatically if and when necessary
27 return rox
.session
.get_settings()
30 """Get GConf connection.
32 Some of the options have corresponding gconf entries; this gets
33 the gconf client connection. It will be called automatically if
39 client
= gconf
.client_get_default ()
40 client
.add_dir ("/desktop/gnome/interface",
41 gconf
.CLIENT_PRELOAD_NONE
)
46 class Settings(OptionGroup
):
47 """A group of options associated with the dbus interface. """
49 program
= os
.path
.basename(rox
.app_dir
) # For dialog box title
51 def __init__(self
, bus
= None, client
= None):
54 bus: ROX-Session's dbus interface. Omit to use default
55 client: gconf client connection. Omit to use default
59 self
.bus
= bus
or get_xsettings()
63 map(apply, self
.callbacks
)
65 option
.has_changed
= False
70 class Setting(Option
):
71 def __init__(self
, name
, default
, settings
, garbage
= False,
75 name: Option name as sent in dbus message.
76 default: Default value.
77 settings: The group of Settings this one belongs to.
78 garbage: Font and theme changes cause (some versions of?) GTK to
79 update all windows even if they're supposed to have been
80 destroyed. If we've just closed a dialog eg font selection (or
81 menu?), this can cause a crash, so this option forces a garbage
82 collection to make sure there is no stale reference.
83 gconf_key: Optional gconf setting key. If it begins with / it
84 will be treated as the absolute path, otherwise it will
85 have /desktop/gnome/interface/ prepended.
88 self
.default
= default
89 self
.settings
= settings
90 settings
.options
[name
] = self
91 self
.garbage
= garbage
93 if gconf_key
and gconf_key
[0] != '/':
94 gconf_key
= "/desktop/gnome/interface/" + gconf_key
95 self
.gconf_key
= gconf_key
97 type, value
= settings
.bus
.GetSetting(name
)
98 except: #XXX: dbus.DBusException:
101 self
._set
(value
, notify
= False)
103 def make_gconf_value(self
):
104 """Returns value ready to be converted to a GConfValue.
106 Override if necessary. Return a bool, int or string
107 (so the name is slightly misleading).
109 if type(self
.default
) is str:
110 return str(self
.value
)
112 return self
.int_value
114 def pre_notify_hook(self
):
115 """Called just before notifying dbus the standard way.
117 Override to perform additional operations and return True
118 if you want to prevent normal notification.
119 Won't be called if there's no bus.
123 def post_notify_hook(self
):
124 """Called just after notifying dbus the standard way.
126 Override to perform additional operations.
127 Won't be called if there's no bus, but otherwise will be called
128 even if pre_notif_hook() returns True.
132 def _set(self
, value
, notify
= True):
133 Option
._set
(self
, value
)
134 if not notify
: return
136 # This is a separate function because it used to be called via a
137 # GObject idle timeout instead of immediately. But that seems to be
138 # more of a hinrance than a help.
144 if not self
.settings
.bus
is None:
145 if not self
.pre_notify_hook():
146 if type(self
.default
) is str:
147 self
.settings
.bus
.SetString(self
.name
, self
.value
)
149 self
.settings
.bus
.SetInt(self
.name
, self
.int_value
)
150 self
.post_notify_hook()
153 if not self
.settings
.client
:
154 self
.settings
.client
= get_gconf()
155 if self
.settings
.client
:
156 val
= self
.make_gconf_value()
157 # Unfortunately GConfClient.set can't coerce builtin
158 # types to GConfValues
159 if type(val
) is bool:
160 self
.settings
.client
.set_bool(self
.gconf_key
, val
)
161 elif type(val
) is int:
162 self
.settings
.client
.set_int(self
.gconf_key
, val
)
164 self
.settings
.client
.set_string(self
.gconf_key
, val
)
169 gobject
.idle_add(set)
173 class BoolSetting(Setting
):
174 """Bool setting for GConf/D-Bus
176 Option doesn't distinguish between int and bool, but gconf does,
177 so use this for bool options.
179 def __init__(self
, name
, default
, settings
, theme
, gconf_key
= None):
180 Setting
.__init
__(self
, name
, default
, settings
, theme
, gconf_key
)
181 def make_gconf_value(self
):
182 return self
.int_value
!= 0
185 if __name__
=='__main__':
186 setobj
=get_xsettings()
187 print 'object=', setobj
189 print '%s = %s' % (v
, setobj
.GetSetting(v
))
191 print '%s = %s' % (v
, setobj
.GetSetting(v
))