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