multies are working now
[tiramisu.git] / src / option.py
index ce06324..d6de739 100644 (file)
@@ -31,49 +31,53 @@ reverse_actions = {'hide': 'show', 'show': 'hide',
 # OptionDescription authorized group_type values
 group_types = ['default', 'family', 'group', 'master']
 # multi types 
+
 class Multi(list):
     "container that support items for the values of list (multi) options" 
-    def __init__(self, lst, config=None, child=None):
+    def __init__(self, lst, config, child):
         self.config = config
         self.child = child
         super(Multi, self).__init__(lst)
         
-    def __getitem__(self, key):
-        value =  super(Multi, self).__getitem__(key)
-        if value is None:
-            return self.child.default_multi
-        else:
-            return value
-                        
     def __setitem__(self, key, value):
-        if value is None:
-            owner = 'default'
-        else:
-            owner = self.config._cfgimpl_owner 
-        oldowner = self.child.getowner(self.config)
-        oldowner[key] = owner        
-        self.child.setowner(self.config, oldowner)
-        if value != None and not self.child._validate(value):
-            raise ConfigError("invalid value {0} "
-                "for option {1}".format(str(value), self.child._name))
-        return super(Multi, self).__setitem__(key, value)
+        return self.setoption(value, key)
 
     def append(self, value):
-        if value is None:
-            owner = 'default'
+        self.setoption(value)
+   
+    def setoption(self, value, key=None):
+        owners = self.child.getowner(self.config)
+        # None is replaced by default_multi
+        if value == None:
+            defval = self.child.getdefault()
+            if key is not None and len(defval) > key:
+                value = defval[key]
+            else:
+                value = self.child.default_multi
+            who = 'default'
         else:
-            owner = self.config._cfgimpl_owner 
+            who = self.config._cfgimpl_owner
+            if not self.child._validate(value):
+                raise ConfigError("invalid value {0} "
+                    "for option {1}".format(str(value), self.child._name))
+        oldvalue = list(self)
         oldowner = self.child.getowner(self.config)
-        oldowner.append(owner)
+        if key is None:
+            ret = super(Multi, self).append(value)
+            oldvalue.append(None)
+            oldowner.append(who)
+        else:
+            ret = super(Multi, self).__setitem__(key, value)
+            oldowner[key] = who
+        self.config._cfgimpl_previous_values[self.child._name] = oldvalue
         self.child.setowner(self.config, oldowner)
-        # changer dans la config la valeur par défaut et le owner
-        if value != None and not self.child._validate(value):
-            raise ConfigError("invalid value {0} "
-                "for option {1}".format(str(value), self.child._name))
-        super(Multi, self).append(value)
-    
-#    def pop(self):
-#        pass 
+        return ret
+        
+    def pop(self, key):
+        oldowner = self.child.getowner(self.config)
+        oldowner.pop(key)
+        self.child.setowner(self.config, oldowner)
+        super(Multi, self).pop(key)
 # ____________________________________________________________
 #
 class Option(HiddenBaseType, DisabledBaseType, ModeBaseType):
@@ -202,7 +206,10 @@ class Option(HiddenBaseType, DisabledBaseType, ModeBaseType):
 #                            raise ConflictConfigError("an option with requires "
 #                             "has not the same length of the others " 
 #                             "in the group : {0}".format(reqname)) 
-        config._cfgimpl_previous_values[name] = config._cfgimpl_values[name] 
+        if type(config._cfgimpl_values[name]) == Multi:
+            config._cfgimpl_previous_values[name] = list(config._cfgimpl_values[name])
+        else:
+            config._cfgimpl_previous_values[name] = config._cfgimpl_values[name] 
         config._cfgimpl_values[name] = value
 
     def getkey(self, value):
@@ -224,10 +231,14 @@ class Option(HiddenBaseType, DisabledBaseType, ModeBaseType):
 class ChoiceOption(Option):
     opt_type = 'string'
     
-    def __init__(self, name, doc, values, default=None, requires=None,
-                 callback=None, callback_params=None, multi=False, 
-                                                           mandatory=False):
+    def __init__(self, name, doc, values, open_values=False, default=None,
+                 requires=None, callback=None, callback_params=None,
+                 multi=False, mandatory=False):
         self.values = values
+        if open_values not in [True, False]:
+            raise ConfigError('Open_values must be a boolean for '
+                              '{0}'.format(name))
+        self.open_values = open_values
         super(ChoiceOption, self).__init__(name, doc, default=default,
                            callback=callback, callback_params=callback_params, 
                            requires=requires, multi=multi, mandatory=mandatory)
@@ -237,7 +248,10 @@ class ChoiceOption(Option):
         super(ChoiceOption, self).setoption(config, value, who)
 
     def _validate(self, value):
-        return value is None or value in self.values
+        if not self.open_values:
+            return value is None or value in self.values
+        else:
+            return True
 
 class BoolOption(Option):
     opt_type = 'bool'