2018b46e15e926ffadfc4d332c2f026775083657
[nepi.git] / src / nepi / core / attributes.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 class AttributesMap(object):
5     """AttributesMap is the base class for every object whose attributes 
6     are going to be manipulated by the end-user in a script or GUI.
7     """
8     def __init__(self):
9         self._attributes = dict()
10
11     @property
12     def attributes(self):
13         return self._attributes.values()
14
15     @property
16     def attributes_name(self):
17         return self._attributes.keys()
18
19     def set_attribute_value(self, name, value):
20         self._attributes[name].value = value
21
22     def set_attribute_readonly(self, name, value):
23         self._attributes[name].readonly = value
24
25     def get_attribute_value(self, name):
26         return self._attributes[name].value
27
28     def get_attribute_help(self, name):
29         return self._attributes[name].help
30
31     def get_attribute_type(self, name):
32         return self._attributes[name].type
33
34     def get_attribute_range(self, name):
35         if not self._attributes[name].range:
36             return (None, None)
37         return self._attributes[name].range
38
39     def get_attribute_allowed(self, name):
40         return self._attributes[name].allowed
41
42     def get_attribute_readonly(self, name):
43         return self._attributes[name].readonly
44
45     def is_attribute_modified(self, name):
46         return self._attributes[name].modified
47
48     def add_attribute(self, name, help, type, value = None, range = None,
49         allowed = None, readonly = False, validation_function = None):
50         if name in self._attributes:
51             raise AttributeError("Attribute %s already exists" % name)
52         attribute = Attribute(name, help, type, value, range, allowed, readonly,
53                 validation_function)
54         self._attributes[name] = attribute
55
56     def del_attribute(self, name):
57         del self._attributes[name]
58
59     def has_attribute(self, name):
60         return name in self._attributes    
61     
62     def destroy(self):
63         self._attributes = dict()
64
65 class Attribute(object):
66     STRING, BOOL, ENUM, DOUBLE, INTEGER = (
67                 "STRING", "BOOL", "ENUM", "DOUBLE", "INTEGER")
68
69     types = [STRING, BOOL, ENUM, DOUBLE, INTEGER]
70
71     def __init__(self, name, help, type, value = None, range = None,
72         allowed = None, readonly = False, validation_function = None):
73         if not type in Attribute.types:
74             raise AttributeError("invalid type %s " % type)
75         self.name = name
76         self._type = type
77         self._help = help
78         self._value = value
79         self._validation_function = validation_function
80         self._readonly = (readonly == True)
81         self._modified = False
82         # range: max and min possible values
83         self._range = range
84         # list of possible values
85         self._allowed = allowed
86
87     @property
88     def type(self):
89         return self._type
90
91     @property
92     def help(self):
93         return self._help
94
95     @property
96     def readonly(self):
97         return self._readonly
98
99     @property
100     def modified(self):
101         return self._modified
102
103     @property
104     def range(self):
105         return self._range
106
107     @property
108     def allowed(self):
109         return self._allowed
110
111     @property
112     def validation_function(self):
113         return self._validation_function
114
115     def get_value(self):
116         return self._value
117
118     def set_value(self, value):
119         if self._is_in_range(value) and \
120                 self._is_in_allowed_values(value) and \
121                 self._is_valid(value):
122             self._value = value
123             self._modified = True
124         else:
125             raise RuntimeError("Invalid value %s for attribute %s" %
126                     (str(value), self.name))
127
128     value = property(get_value, set_value)
129
130     def _is_in_range(self, value):
131         return not self.range or \
132                 (value >= self.range[0] and value <= self.range[1])
133
134     def _is_in_allowed_values(self, value):
135         return not self.allowed or value in self._allowed
136
137     def _is_valid(self, value):
138         return not self._validation_function or self._validation_function(value)
139