2 To use the Options system:
4 1. Create an OptionGroup:
5 options = OptionGroup('MyProg', 'Options')
6 You can also use the handy rox.setup_app_options() in most applications.
9 colour = Option('colour', 'red', options)
10 size = Option('size', 3, options)
12 3. Register any callbacks (notification of options changing):
14 if colour.has_changed:
15 print "The colour is now", colour.value
16 options.add_notify(my_callback)
18 4. Notify any changes from defaults:
21 See OptionsBox for editing options. Do not change the value of options
25 from __future__
import generators
30 from xml
.dom
import Node
, minidom
33 """Return all the text directly inside this DOM Node."""
34 return ''.join([text
.nodeValue
for text
in node
.childNodes
35 if text
.nodeType
== Node
.TEXT_NODE
])
38 """An Option stores a single value. Every option is part of exactly one OptionGroup.
40 The read-only attributes value and int_value can be used to get the current setting
41 for the Option. int_value will be -1 if the value is not a valid integer.
43 The has_changed attribute is used during notify() calls to indicate whether this
44 Option's value has changed since the last notify (or option creation).
45 You may set has_changed = 1 right after creating an option if you want to force
46 notification the first time even if the default is used.
48 def __init__(self
, name
, value
, group
= None):
49 """Create a new option with this name and default value.
50 Add to 'group', or to rox.app_options if no group is given.
51 The value cannot be used until the first notify() call to
54 assert rox
.app_options
55 group
= rox
.app_options
57 self
.has_changed
= 0 # ... since last notify/default
58 self
.default_value
= str(value
)
63 self
.group
._register
(self
)
65 def _set(self
, value
):
66 if self
.value
!= value
:
67 self
.value
= str(value
)
70 if self
.value
== 'True':
72 elif self
.value
== 'False':
75 self
.int_value
= int(float(self
.value
))
79 def _to_xml(self
, parent
):
80 doc
= parent
.ownerDocument
81 node
= doc
.createElement('Option')
82 node
.setAttribute('name', self
.name
)
83 node
.appendChild(doc
.createTextNode(self
.value
))
84 parent
.appendChild(node
)
87 return "<Option %s=%s>" % (self
.name
, self
.value
)
90 def __init__(self
, program
, leaf
):
91 "program/leaf is a Choices pair for the saved options."
92 self
.program
= program
94 self
.pending
= {} # Loaded, but not registered
95 self
.options
= {} # Name -> Option
97 self
.too_late_for_registrations
= 0
99 path
= choices
.load(program
, leaf
)
104 doc
= minidom
.parse(path
)
106 root
= doc
.documentElement
107 assert root
.localName
== 'Options'
108 for o
in root
.childNodes
:
109 if o
.nodeType
!= Node
.ELEMENT_NODE
:
111 if o
.localName
!= 'Option':
112 print "Warning: Non Option element", o
114 name
= o
.getAttribute('name')
115 self
.pending
[name
] = data(o
)
117 rox
.report_exception()
119 def _register(self
, option
):
120 """Called by Option.__init__."""
121 assert option
.name
not in self
.options
122 assert not self
.too_late_for_registrations
126 self
.options
[name
] = option
128 if name
in self
.pending
:
129 option
._set
(self
.pending
[name
])
130 del self
.pending
[name
]
133 """Save all option values. Usually called by OptionsBox()."""
134 assert self
.too_late_for_registrations
136 path
= choices
.save(self
.program
, self
.leaf
)
138 return # Saving is disabled
140 from xml
.dom
.minidom
import Document
142 root
= doc
.createElement('Options')
143 doc
.appendChild(root
)
148 stream
= open(path
, 'w')
152 def add_notify(self
, callback
):
153 "Call callback() after one or more options have changed value."
154 assert callback
not in self
.callbacks
156 self
.callbacks
.append(callback
)
158 def remove_notify(self
, callback
):
159 """Remove a callback added with add_notify()."""
160 self
.callbacks
.remove(callback
)
163 """Call this after creating any new options or changing their values."""
164 if not self
.too_late_for_registrations
:
165 self
.too_late_for_registrations
= 1
167 print "Warning: Some options loaded but unused:"
168 for (key
, value
) in self
.pending
.iteritems():
169 print "%s=%s" % (key
, value
)
172 o
._set
(o
.default_value
)
173 map(apply, self
.callbacks
)
175 option
.has_changed
= 0
178 return self
.options
.itervalues()