pointer's variables are config vars
[dana/openbox.git] / python / config.py
1 # Openbox's config system. Please use the defined functions instead of
2 # accessing the internal data structures directly, for the sake of us all.
3
4 def add(modulename, name, friendlyname, description, type, default,
5         **keywords):
6     """Add a variable to the configuration system.
7
8     Add a variable to the configuration system for a module.
9     modulename - The name of the module, e.g. 'focus'
10     name - The name of the variable, e.g. 'my_variable'
11     friendlyname - The user-friendly name of the variable, e.g. 'My Variable'
12     description - The detailed destription of the variable, e.g. 'Does Things'
13     type - The type of the variable, one of:
14              - 'boolean'
15              - 'enum'
16              - 'integer'
17              - 'string'
18              - 'file'
19              - 'function'
20              - 'object'
21     default - The default value for the variable, e.g. 300
22     keywords - Extra keyword=value pairs to further define the variable. These
23                can be:
24                  - For 'enum' types:
25                      - options : A list of possible options for the variable.
26                                  This *must* be set for all enum variables.
27                  - For 'integer' types:
28                      - min : The minimum value for the variable.
29                      - max : The maximum value for the variable.
30     """
31     modulename = str(modulename).lower()
32     name = str(name).lower()
33     friendlyname = str(friendlyname)
34     description = str(description)
35     type = str(type).lower()
36
37     # make sure the sub-dicts exist
38     try:
39         _settings[modulename]
40         try:
41             _settings[modulename][name]
42         except KeyError:
43             _settings[modulename][name] = {}
44     except KeyError:
45         _settings[modulename] = {}
46         _settings[modulename][name] = {}
47
48     # add the keywords first as they are used for the tests in set()
49     for key,value in zip(keywords.keys(), keywords.values()):
50         _settings[modulename][name][key] = value
51
52     _settings[modulename][name]['name'] = friendlyname
53     _settings[modulename][name]['description'] = description
54     _settings[modulename][name]['type'] = type
55     _settings[modulename][name]['default'] = default
56
57     # put it through the tests
58     try:
59         set(modulename, name, default)
60     except:
61         del _settings[modulename][name]
62         import sys
63         raise sys.exc_info()[0], sys.exc_info()[1] # re-raise it
64
65 def set(modulename, name, value):
66     """Set a variable's value.
67
68     Sets the value for a variable of the specified module.
69     modulename - The name of the module, e.g. 'focus'
70     name - The name of the variable, e.g. 'my_variable'
71     value - The new value for the variable.
72     """
73     modulename = str(modulename).lower()
74     name = str(name).lower()
75
76     # proper value checking for 'boolean's
77     if _settings[modulename][name]['type'] == 'boolean':
78         if not (value == 0 or value == 1):
79             raise ValueError, 'Attempted to set ' + name + ' to a value of '+\
80                   str(value) + ' but boolean variables can only contain 0 or'+\
81                   ' 1.'
82
83     # proper value checking for 'enum's
84     elif _settings[modulename][name]['type'] == 'enum':
85         options = _settings[modulename][name]['options']
86         if not value in options:
87             raise ValueError, 'Attempted to set ' + name + ' to a value of '+\
88                   str(value) + ' but this is not one of the possible values '+\
89                   'for this enum variable. Possible values are: ' +\
90                   str(options) + "."
91
92     # min/max checking for 'integer's
93     elif _settings[modulename][name]['type'] == 'integer':
94         try:
95             min = _settings[modulename][name]['min']
96             if value < min:
97                 raise ValueError, 'Attempted to set ' + name + ' to a value '+\
98                       ' of ' + str(value) + ' but it has a minimum value ' +\
99                       ' of ' + str(min) + '.'
100         except KeyError: pass
101         try:
102             max = _settings[modulename][name]['max']
103             if value > max:
104                 raise ValueError, 'Attempted to set ' + name + ' to a value '+\
105                       ' of ' + str(value) + ' but it has a maximum value ' +\
106                       ' of ' + str(min) + '.'
107         except KeyError: pass
108     
109     _settings[modulename][name]['value'] = value
110
111 def reset(modulename, name):
112     """Reset a variable to its default value.
113
114     Resets the value for a variable in the specified module back to its
115     original (default) value.
116     modulename - The name of the module, e.g. 'focus'
117     name - The name of the variable, e.g. 'my_variable'
118     """
119     modulename = str(modulename).lower()
120     name = str(name).lower()
121     _settings[modulename][name]['value'] = \
122                                  _settings[modulename][name]['default']
123
124 def get(modulename, name):
125     """Returns the value of a variable.
126
127     Returns the current value for a variable in the specified module.
128     modulename - The name of the module, e.g. 'focus'
129     name - The name of the variable, e.g. 'my variable'
130     """
131     modulename = str(modulename).lower()
132     name = str(name).lower()
133     return _settings[modulename][name]['value']
134
135 #---------------------------- Internals ---------------------------
136
137 """The main configuration dictionary, which holds sub-dictionaries for each
138    module.
139
140    The format for entries in here like this (for a string):
141    _settings['modulename']['varname']['name'] = 'Text Label'
142    _settings['modulename']['varname']['description'] = 'Does this'
143    _settings['modulename']['varname']['type'] = 'string'
144    _settings['modulename']['varname']['default'] = 'Foo'
145    _settings['modulename']['varname']['value'] = 'Foo'
146                              # 'value' should always be initialized to the same
147                              # value as the 'default' field!
148
149    Here's an example of an enum:
150    _settings['modulename']['varname']['name'] = 'My Enum Variable'
151    _settings['modulename']['varname']['description'] = 'Does Enum-like things.'
152    _settings['modulename']['varname']['type'] = 'enum'
153    _settings['modulename']['varname']['default'] = \
154      _settings['modulename']['varname']['value'] = [ 'Blue', 'Green', 'Pink' ]
155
156    And Here's an example of an integer with bounds:
157    _settings['modulename']['varname']['name'] = 'A Bounded Integer'
158    _settings['modulename']['varname']['description'] = 'A fierce party animal!'
159    _settings['modulename']['varname']['type'] = 'integer'
160    _settings['modulename']['varname']['default'] = \
161      _settings['modulename']['varname']['value'] = 0
162    _settings['modulename']['varname']['min'] = 0
163    _settings['modulename']['varname']['max'] = 49
164
165    Hopefully you get the idea.
166    """
167 _settings = {}
168
169 """Valid values for a variable's type."""
170 _types = [ 'boolean', # Boolean types can only hold a value of 0 or 1.
171            
172            'enum',    # Enum types hold a value from a list of possible values.
173                       # An 'options' field *must* be provided for enums,
174                       # containing a list of possible values for the variable.
175
176            'integer', # Integer types hold a single number, as well as a 'min'
177                       # and 'max' property.
178                       # If the 'min' or 'max' is ignore then bounds checking
179                       # will not be performed in that direction.
180
181            'string',  # String types hold a text string.
182
183            'file',    # File types hold a file object.
184
185            'function',# Function types hold any callable object.
186
187            'object'   # Object types can hold any python object.
188            ];
189
190 print "Loaded config.py"