Merged with trunk R708
[ardour.git] / libs / ardour / ardour / configuration_variable.h
1 #ifndef __ardour_configuration_variable_h__
2 #define __ardour_configuration_variable_h__
3
4 #include <sstream>
5 #include <ostream>
6
7 #include <pbd/xml++.h>
8
9 namespace ARDOUR {
10
11 class ConfigVariableBase {
12   public:
13         ConfigVariableBase (std::string str) : _name (str), _is_user (false) {}
14         virtual ~ConfigVariableBase() {}
15
16         std::string name() const { return _name; }
17         bool is_user() const { return _is_user; }
18         void set_is_user (bool yn) { _is_user = yn; }
19         
20         virtual void add_to_node (XMLNode& node) = 0;
21         virtual bool set_from_node (const XMLNode& node) = 0;
22
23   protected:
24         std::string _name;
25         bool _is_user;
26 };
27
28 template<class T>
29 class ConfigVariable : public ConfigVariableBase
30 {
31   public:
32         ConfigVariable (std::string str) : ConfigVariableBase (str) {}
33         ConfigVariable (std::string str, T val) : ConfigVariableBase (str), value (val) {}
34
35         virtual void set (T val) {
36                 value = val;
37         }
38
39         T get() const {
40                 return value;
41         }
42
43         void add_to_node (XMLNode& node) {
44                 std::stringstream ss;
45                 ss << value;
46                 XMLNode* child = new XMLNode ("Option");
47                 child->add_property ("name", _name);
48                 child->add_property ("value", ss.str());
49                 node.add_child_nocopy (*child);
50         }
51
52         bool set_from_node (const XMLNode& node) {
53                 const XMLProperty* prop;
54                 XMLNodeList nlist;
55                 XMLNodeConstIterator niter;
56                 XMLNode* child;
57
58                 nlist = node.children();
59                 
60                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
61                         
62                         child = *niter;
63                         
64                         if (child->name() == "Option") {
65                                 if ((prop = child->property ("name")) != 0) {
66                                         if (prop->value() == _name) {
67                                                 if ((prop = child->property ("value")) != 0) {
68                                                         std::stringstream ss;
69                                                         ss << prop->value();
70                                                         ss >> value;
71                                                         return true;
72                                                 }
73                                         }
74                                 }
75                         }
76                 }
77
78                 return false;
79         }
80
81   protected:
82         virtual T get_for_save() { return value; }
83         T value;
84 };
85
86 template<class T>
87 class ConfigVariableWithMutation : public ConfigVariable<T>
88 {
89   public:
90         ConfigVariableWithMutation (std::string name, T val, T (*m)(T)) 
91                 : ConfigVariable<T> (name, val), mutator (m) {}
92
93         void set (T val) {
94                 unmutated_value = val;
95                 ConfigVariable<T>::set (mutator (val));
96         }
97
98   protected:
99         virtual T get_for_save() { return unmutated_value; }
100         T unmutated_value;
101         T (*mutator)(T);
102 };
103
104 }
105
106 #endif /* __ardour_configuration_variable_h__ */