syncing with upstream
[ardour.git] / libs / pbd / pbd / configuration_variable.h
1 /*
2     Copyright (C) 2000-2007 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #ifndef __libpbd_configuration_variable_h__
21 #define __libpbd_configuration_variable_h__
22
23 #include <iostream>
24 #include <sstream>
25 #include <string>
26
27 #include "pbd/xml++.h"
28 #include "pbd/convert.h"
29 #include "pbd/libpbd_visibility.h"
30
31 namespace PBD {
32
33 class LIBPBD_API ConfigVariableBase {
34   public:
35
36         ConfigVariableBase (std::string str) : _name (str) {}
37         virtual ~ConfigVariableBase() {}
38
39         std::string name () const { return _name; }
40         void add_to_node (XMLNode&);
41         bool set_from_node (XMLNode const &);
42
43         virtual std::string get_as_string () const = 0;
44         virtual void set_from_string (std::string const &) = 0;
45
46   protected:
47         std::string _name;
48
49         void notify ();
50         void miss ();
51 };
52
53 template<class T>
54 class /*LIBPBD_API*/ ConfigVariable : public ConfigVariableBase
55 {
56   public:
57
58         ConfigVariable (std::string str) : ConfigVariableBase (str) {}
59         ConfigVariable (std::string str, T val) : ConfigVariableBase (str), value (val) {}
60
61         T get() const {
62                 return value;
63         }
64
65         std::string get_as_string () const {
66                 std::ostringstream ss;
67                 ss << value;
68                 return ss.str ();
69         }
70
71         virtual bool set (T val) {
72                 if (val == value) {
73                         miss ();
74                         return false;
75                 }
76                 value = val;
77                 notify ();
78                 return true;
79         }
80
81         virtual void set_from_string (std::string const & s) {
82                 std::stringstream ss;
83                 ss << s;
84                 ss >> value;
85         }
86
87   protected:
88         virtual T get_for_save() { return value; }
89         T value;
90 };
91
92 /** Specialisation of ConfigVariable to deal with float (-inf etc) */
93 template<> LIBPBD_API void
94 ConfigVariable<float>::set_from_string (std::string const & s);
95
96 /** Specialisation of ConfigVariable for std::string to cope with whitespace properly */
97 template<>
98 class /*LIBPBD_API*/ ConfigVariable<std::string> : public ConfigVariableBase
99 {
100   public:
101
102         ConfigVariable (std::string str) : ConfigVariableBase (str) {}
103         ConfigVariable (std::string str, std::string val) : ConfigVariableBase (str), value (val) {}
104
105         std::string get() const {
106                 return value;
107         }
108
109         std::string get_as_string () const {
110                 return value;
111         }
112
113         virtual bool set (std::string val) {
114                 if (val == value) {
115                         miss ();
116                         return false;
117                 }
118                 value = val;
119                 notify ();
120                 return true;
121         }
122
123         virtual void set_from_string (std::string const & s) {
124                 value = s;
125         }
126
127   protected:
128         virtual std::string get_for_save() { return value; }
129         std::string value;
130 };
131
132 template<>
133 class /*LIBPBD_API*/ ConfigVariable<bool> : public ConfigVariableBase
134 {
135   public:
136
137         ConfigVariable (std::string str) : ConfigVariableBase (str), value (false) {}
138         ConfigVariable (std::string str, bool val) : ConfigVariableBase (str), value (val) {}
139
140         bool get() const {
141                 return value;
142         }
143
144         std::string get_as_string () const {
145                 std::ostringstream ss;
146                 ss << value;
147                 return ss.str ();
148         }
149
150         virtual bool set (bool val) {
151                 if (val == value) {
152                         miss ();
153                         return false;
154                 }
155                 value = val;
156                 notify ();
157                 return true;
158         }
159
160         void set_from_string (std::string const & s) {
161                 value = PBD::string_is_affirmative (s);
162         }
163
164   protected:
165         virtual bool get_for_save() { return value; }
166         bool value;
167 };
168
169 template<class T>
170 class /*LIBPBD_API*/ ConfigVariableWithMutation : public ConfigVariable<T>
171 {
172   public:
173         ConfigVariableWithMutation (std::string name, T val, T (*m)(T))
174                 : ConfigVariable<T> (name, m (val)), unmutated_value (val), mutator (m) {}
175
176         bool set (T val) {
177                 if (unmutated_value != val) {
178                         unmutated_value = val;
179                         return ConfigVariable<T>::set (mutator (val));
180                 }
181                 return false;
182         }
183
184         void set_from_string (std::string const & s) {
185                 T v;
186                 std::stringstream ss;
187                 ss << s;
188                 ss >> v;
189                 set (v);
190         }
191
192   protected:
193         virtual T get_for_save() { return unmutated_value; }
194         T unmutated_value;
195         T (*mutator)(T);
196 };
197
198 template<>
199 class /*LIBPBD_API*/ ConfigVariableWithMutation<std::string> : public ConfigVariable<std::string>
200 {
201   public:
202         ConfigVariableWithMutation (std::string name, std::string val, std::string (*m)(std::string))
203                 : ConfigVariable<std::string> (name, val), mutator (m) {}
204
205         bool set (std::string val) {
206                 if (unmutated_value != val) {
207                         unmutated_value = val;
208                         return ConfigVariable<std::string>::set (mutator (val));
209                 }
210                 return false;
211         }
212
213         void set_from_string (std::string const & s) {
214                 set (s);
215         }
216
217   protected:
218         virtual std::string get_for_save() { return unmutated_value; }
219         std::string unmutated_value;
220         std::string (*mutator)(std::string);
221 };
222
223 }
224
225 #endif /* __libpbd_configuration_variable_h__ */