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
17 _warned_import
= False
18 _warned_connect
= False
22 """Returns ROX-Session's Settings dbus/xxmlrpc interface.
24 Called automatically if and when necessary
26 return rox
.session
.get_settings()
29 """Get GConf connection.
31 Some of the options have corresponding gconf entries; this gets
32 the gconf client connection. It will be called automatically if
38 client
= gconf
.client_get_default ()
39 client
.add_dir ("/desktop/gnome/interface",
40 gconf
.CLIENT_PRELOAD_NONE
)
45 class Settings(OptionGroup
):
46 """A group of options associated with the dbus interface. """
48 program
= os
.path
.basename(rox
.app_dir
) # For dialog box title
50 def __init__(self
, bus
= None, client
= None):
53 bus: ROX-Session's dbus interface. Omit to use default
54 client: gconf client connection. Omit to use default
58 self
.bus
= bus
or get_xsettings()
62 map(apply, self
.callbacks
)
64 option
.has_changed
= False
69 class Setting(Option
):
70 def __init__(self
, name
, default
, settings
, garbage
= False,
74 name: Option name as sent in dbus message.
75 default: Default value.
76 settings: The group of Settings this one belongs to.
77 garbage: Font and theme changes cause (some versions of?) GTK to
78 update all windows even if they're supposed to have been
79 destroyed. If we've just closed a dialog eg font selection (or
80 menu?), this can cause a crash, so this option forces a garbage
81 collection to make sure there is no stale reference.
82 gconf_key: Optional gconf setting key. If it begins with / it
83 will be treated as the absolute path, otherwise it will
84 have /desktop/gnome/interface/ prepended.
87 self
.default
= default
88 self
.settings
= settings
89 settings
.options
[name
] = self
90 self
.garbage
= garbage
92 if gconf_key
and gconf_key
[0] != '/':
93 gconf_key
= "/desktop/gnome/interface/" + gconf_key
94 self
.gconf_key
= gconf_key
96 type, value
= settings
.bus
.GetSetting(name
)
97 except: #XXX: dbus.DBusException:
100 self
._set
(value
, notify
= False)
102 def make_gconf_value(self
):
103 """Returns value ready to be converted to a GConfValue.
105 Override if necessary. Return a bool, int or string
106 (so the name is slightly misleading).
108 if type(self
.default
) is str:
109 return str(self
.value
)
111 return self
.int_value
113 def pre_notify_hook(self
):
114 """Called just before notifying dbus the standard way.
116 Override to perform additional operations and return True
117 if you want to prevent normal notification.
118 Won't be called if there's no bus.
122 def post_notify_hook(self
):
123 """Called just after notifying dbus the standard way.
125 Override to perform additional operations.
126 Won't be called if there's no bus, but otherwise will be called
127 even if pre_notif_hook() returns True.
131 def _set(self
, value
, notify
= True):
132 Option
._set
(self
, value
)
133 if not notify
: return
135 # This is a separate function because it used to be called via a
136 # GObject idle timeout instead of immediately. But that seems to be
137 # more of a hinrance than a help.
143 if not self
.settings
.bus
is None:
144 if not self
.pre_notify_hook():
145 if type(self
.default
) is str:
146 self
.settings
.bus
.SetString(self
.name
, self
.value
)
148 self
.settings
.bus
.SetInt(self
.name
, self
.int_value
)
149 self
.post_notify_hook()
152 if not self
.settings
.client
:
153 self
.settings
.client
= get_gconf()
154 if self
.settings
.client
:
155 val
= self
.make_gconf_value()
156 # Unfortunately GConfClient.set can't coerce builtin
157 # types to GConfValues
158 if type(val
) is bool:
159 self
.settings
.client
.set_bool(self
.gconf_key
, val
)
160 elif type(val
) is int:
161 self
.settings
.client
.set_int(self
.gconf_key
, val
)
163 self
.settings
.client
.set_string(self
.gconf_key
, val
)
168 gobject
.idle_add(set)
172 class BoolSetting(Setting
):
173 """Bool setting for GConf/D-Bus
175 Option doesn't distinguish between int and bool, but gconf does,
176 so use this for bool options.
178 def __init__(self
, name
, default
, settings
, theme
, gconf_key
= None):
179 Setting
.__init
__(self
, name
, default
, settings
, theme
, gconf_key
)
180 def make_gconf_value(self
):
181 return self
.int_value
!= 0
184 if __name__
=='__main__':
185 setobj
=get_xsettings()
186 print 'object=', setobj
188 print '%s = %s' % (v
, setobj
.GetSetting(v
))
190 print '%s = %s' % (v
, setobj
.GetSetting(v
))
192 print 'All: ', setobj
.Enumerate()
193 print 'ROX: ', setobj
.Enumerate('ROX/*')