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