allow ardour button to handle focused keyboard events
[ardour.git] / gtk2_ardour / ui_config.cc
1 /*
2     Copyright (C) 1999-2006 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 #include <unistd.h>
21 #include <cstdlib>
22 #include <cstdio> /* for snprintf, grrr */
23
24 #include <glibmm/miscutils.h>
25
26 #include "pbd/failed_constructor.h"
27 #include "pbd/xml++.h"
28 #include "pbd/file_utils.h"
29 #include "pbd/error.h"
30
31 #include "gtkmm2ext/rgb_macros.h"
32
33 #include "ardour/filesystem_paths.h"
34
35 #include "ui_config.h"
36
37 #include "i18n.h"
38
39 using namespace std;
40 using namespace PBD;
41 using namespace ARDOUR;
42
43 UIConfiguration::UIConfiguration ()
44         :
45 #undef  UI_CONFIG_VARIABLE
46 #undef  CANVAS_VARIABLE
47 #define UI_CONFIG_VARIABLE(Type,var,name,val) var (name,val),
48 #define CANVAS_VARIABLE(var,name) var (name),
49 #define CANVAS_STRING_VARIABLE(var,name) var (name),
50 #include "ui_config_vars.h"
51 #include "canvas_vars.h"
52 #undef  UI_CONFIG_VARIABLE
53 #undef  CANVAS_VARIABLE
54 #undef  CANVAS_STRING_VARIABLE
55         _dirty (false)
56 {
57         load_state();
58 }
59
60 UIConfiguration::~UIConfiguration ()
61 {
62 }
63
64 void
65 UIConfiguration::map_parameters (boost::function<void (std::string)>& functor)
66 {
67 #undef  UI_CONFIG_VARIABLE
68 #define UI_CONFIG_VARIABLE(Type,var,Name,value) functor (Name);
69 #include "ui_config_vars.h"
70 #undef  UI_CONFIG_VARIABLE
71 }
72
73 int
74 UIConfiguration::load_defaults ()
75 {
76         int found = 0;
77
78         std::string default_ui_rc_file;
79         std::string rcfile;
80
81         if (getenv ("ARDOUR_SAE")) {
82                 rcfile = "ardour3_ui_sae.conf";
83         } else {
84                 rcfile = "ardour3_ui_default.conf";
85         }
86
87         if (find_file_in_search_path (ardour_config_search_path(), rcfile, default_ui_rc_file) ) {
88                 XMLTree tree;
89                 found = 1;
90
91                 string rcfile = default_ui_rc_file;
92
93                 info << string_compose (_("Loading default ui configuration file %1"), rcfile) << endl;
94
95                 if (!tree.read (rcfile.c_str())) {
96                         error << string_compose(_("cannot read default ui configuration file \"%1\""), rcfile) << endmsg;
97                         return -1;
98                 }
99
100                 if (set_state (*tree.root(), Stateful::loading_state_version)) {
101                         error << string_compose(_("default ui configuration file \"%1\" not loaded successfully."), rcfile) << endmsg;
102                         return -1;
103                 }
104
105                 _dirty = false;
106         }
107
108         return found;
109 }
110
111 int
112 UIConfiguration::load_state ()
113 {
114         bool found = false;
115
116         std::string default_ui_rc_file;
117
118         if ( find_file_in_search_path (ardour_config_search_path(), "ardour3_ui_default.conf", default_ui_rc_file)) {
119                 XMLTree tree;
120                 found = true;
121
122                 string rcfile = default_ui_rc_file;
123
124                 info << string_compose (_("Loading default ui configuration file %1"), rcfile) << endl;
125
126                 if (!tree.read (rcfile.c_str())) {
127                         error << string_compose(_("cannot read default ui configuration file \"%1\""), rcfile) << endmsg;
128                         return -1;
129                 }
130
131                 if (set_state (*tree.root(), Stateful::loading_state_version)) {
132                         error << string_compose(_("default ui configuration file \"%1\" not loaded successfully."), rcfile) << endmsg;
133                         return -1;
134                 }
135         }
136
137         std::string user_ui_rc_file;
138
139         if (find_file_in_search_path (ardour_config_search_path(), "ardour3_ui.conf", user_ui_rc_file)) {
140                 XMLTree tree;
141                 found = true;
142
143                 string rcfile = user_ui_rc_file;
144
145                 info << string_compose (_("Loading user ui configuration file %1"), rcfile) << endmsg;
146
147                 if (!tree.read (rcfile)) {
148                         error << string_compose(_("cannot read ui configuration file \"%1\""), rcfile) << endmsg;
149                         return -1;
150                 }
151
152                 if (set_state (*tree.root(), Stateful::loading_state_version)) {
153                         error << string_compose(_("user ui configuration file \"%1\" not loaded successfully."), rcfile) << endmsg;
154                         return -1;
155                 }
156
157                 _dirty = false;
158         }
159
160         if (!found)
161                 error << _("could not find any ui configuration file, canvas will look broken.") << endmsg;
162
163         pack_canvasvars();
164
165         return 0;
166 }
167
168 int
169 UIConfiguration::save_state()
170 {
171         XMLTree tree;
172
173         std::string rcfile(user_config_directory());
174         rcfile = Glib::build_filename (rcfile, "ardour3_ui.conf");
175
176         // this test seems bogus?
177         if (rcfile.length()) {
178                 tree.set_root (&get_state());
179                 if (!tree.write (rcfile.c_str())){
180                         error << string_compose (_("Config file %1 not saved"), rcfile) << endmsg;
181                         return -1;
182                 }
183         }
184
185         _dirty = false;
186
187         return 0;
188 }
189
190 XMLNode&
191 UIConfiguration::get_state ()
192 {
193         XMLNode* root;
194         LocaleGuard lg (X_("POSIX"));
195
196         root = new XMLNode("Ardour");
197
198         root->add_child_nocopy (get_variables ("UI"));
199         root->add_child_nocopy (get_variables ("Canvas"));
200
201         if (_extra_xml) {
202                 root->add_child_copy (*_extra_xml);
203         }
204
205         return *root;
206 }
207
208 XMLNode&
209 UIConfiguration::get_variables (std::string which_node)
210 {
211         XMLNode* node;
212         LocaleGuard lg (X_("POSIX"));
213
214         node = new XMLNode(which_node);
215
216 #undef  UI_CONFIG_VARIABLE
217 #undef  CANVAS_VARIABLE
218 #define UI_CONFIG_VARIABLE(Type,var,Name,value) if (node->name() == "UI") { var.add_to_node (*node); }
219 #define CANVAS_VARIABLE(var,Name) if (node->name() == "Canvas") { var.add_to_node (*node); }
220 #define CANVAS_STRING_VARIABLE(var,Name) if (node->name() == "Canvas") { var.add_to_node (*node); }
221 #include "ui_config_vars.h"
222 #include "canvas_vars.h"
223 #undef  UI_CONFIG_VARIABLE
224 #undef  CANVAS_VARIABLE
225 #undef  CANVAS_STRING_VARIABLE
226
227         return *node;
228 }
229
230 int
231 UIConfiguration::set_state (const XMLNode& root, int /*version*/)
232 {
233         if (root.name() != "Ardour") {
234                 return -1;
235         }
236
237         Stateful::save_extra_xml (root);
238
239         XMLNodeList nlist = root.children();
240         XMLNodeConstIterator niter;
241         XMLNode *node;
242
243         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
244
245                 node = *niter;
246
247                 if (node->name() == "Canvas" ||  node->name() == "UI") {
248                         set_variables (*node);
249
250                 }
251         }
252
253         return 0;
254 }
255
256 void
257 UIConfiguration::set_variables (const XMLNode& node)
258 {
259 #undef  UI_CONFIG_VARIABLE
260 #undef  CANVAS_VARIABLE
261 #define UI_CONFIG_VARIABLE(Type,var,name,val) \
262          if (var.set_from_node (node)) { \
263                  ParameterChanged (name); \
264                  }
265 #define CANVAS_VARIABLE(var,name) \
266          if (var.set_from_node (node)) { \
267                  ParameterChanged (name); \
268                  }
269 #define CANVAS_STRING_VARIABLE(var,name)        \
270          if (var.set_from_node (node)) { \
271                  ParameterChanged (name); \
272                  }
273 #include "ui_config_vars.h"
274 #include "canvas_vars.h"
275 #undef  UI_CONFIG_VARIABLE
276 #undef  CANVAS_VARIABLE
277 #undef  CANVAS_STRING_VARIABLE
278 }
279
280 void
281 UIConfiguration::pack_canvasvars ()
282 {
283 #undef  CANVAS_VARIABLE
284 #define CANVAS_VARIABLE(var,name) canvas_colors.insert (std::pair<std::string,ColorVariable<uint32_t>* >(name,&var));
285 #define CANVAS_STRING_VARIABLE(var,name) 
286 #include "canvas_vars.h"
287 #undef  CANVAS_VARIABLE
288 #undef  CANVAS_STRING_VARIABLE
289 }
290
291 uint32_t
292 UIConfiguration::color_by_name (const std::string& name)
293 {
294         map<std::string,ColorVariable<uint32_t>* >::iterator i = canvas_colors.find (name);
295
296         if (i != canvas_colors.end()) {
297                 return i->second->get();
298         }
299
300         // cerr << string_compose (_("Color %1 not found"), name) << endl;
301         return RGBA_TO_UINT (g_random_int()%256,g_random_int()%256,g_random_int()%256,0xff);
302 }
303
304 void
305 UIConfiguration::set_dirty ()
306 {
307         _dirty = true;
308 }
309
310 bool
311 UIConfiguration::dirty () const
312 {
313         return _dirty;
314 }