Fix unnecessary const violation.
[ardour.git] / gtk2_ardour / startup.cc
1 /*
2     Copyright (C) 2010 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 #ifdef WAF_BUILD
21 #include "gtk2ardour-config.h"
22 #include "gtk2ardour-version.h"
23 #endif
24
25 #include <fstream>
26 #include <algorithm>
27
28 #include <gtkmm/main.h>
29 #include <gtkmm/filechooser.h>
30
31 #include "pbd/failed_constructor.h"
32 #include "pbd/file_utils.h"
33 #include "pbd/replace_all.h"
34 #include "pbd/whitespace.h"
35 #include "pbd/stacktrace.h"
36 #include "pbd/openuri.h"
37
38 #include "ardour/audioengine.h"
39 #include "ardour/filesystem_paths.h"
40 #include "ardour/recent_sessions.h"
41 #include "ardour/session.h"
42 #include "ardour/session_state_utils.h"
43 #include "ardour/template_utils.h"
44 #include "ardour/filename_extensions.h"
45
46 #include "ardour_ui.h"
47 #include "startup.h"
48 #include "opts.h"
49 #include "engine_dialog.h"
50 #include "i18n.h"
51 #include "utils.h"
52
53 using namespace std;
54 using namespace Gtk;
55 using namespace Gdk;
56 using namespace Glib;
57 using namespace PBD;
58 using namespace ARDOUR;
59 using namespace ARDOUR_UI_UTILS;
60
61 ArdourStartup* ArdourStartup::the_startup = 0;
62
63 static string poor_mans_glob (string path)
64 {
65         string copy = path;
66         replace_all (copy, "~", Glib::get_home_dir());
67         return copy;
68 }
69
70 ArdourStartup::ArdourStartup ()
71         : _response (RESPONSE_OK)
72         , config_modified (false)
73         , default_dir_chooser (0)
74         , monitor_via_hardware_button (string_compose (_("Use an external mixer or the hardware mixer of your audio interface.\n"
75                                                          "%1 will play NO role in monitoring"), PROGRAM_NAME))
76         , monitor_via_ardour_button (string_compose (_("Ask %1 to play back material as it is being recorded"), PROGRAM_NAME))
77         , audio_page_index (-1)
78         , new_user_page_index (-1)
79         , default_folder_page_index (-1)
80         , monitoring_page_index (-1)
81         , final_page_index (-1)
82 {
83         set_keep_above (true);
84         set_position (WIN_POS_CENTER);
85         set_border_width (12);
86         
87         if ((icon_pixbuf = ::get_icon ("ardour_icon_48px")) == 0) {
88                 throw failed_constructor();
89         }
90         
91         list<Glib::RefPtr<Gdk::Pixbuf> > window_icons;
92         Glib::RefPtr<Gdk::Pixbuf> icon;
93         
94         if ((icon = ::get_icon ("ardour_icon_16px")) != 0) {
95                 window_icons.push_back (icon);
96         }
97         if ((icon = ::get_icon ("ardour_icon_22px")) != 0) {
98                 window_icons.push_back (icon);
99         }
100         if ((icon = ::get_icon ("ardour_icon_32px")) != 0) {
101                 window_icons.push_back (icon);
102         }
103         if ((icon = ::get_icon ("ardour_icon_48px")) != 0) {
104                 window_icons.push_back (icon);
105         }
106         if (!window_icons.empty ()) {
107                 set_default_icon_list (window_icons);
108         }
109         
110 #ifdef __APPLE__
111         setup_prerelease_page ();
112 #endif
113         
114         setup_new_user_page ();
115         setup_first_time_config_page ();
116         setup_monitoring_choice_page ();
117         setup_monitor_section_choice_page ();
118         setup_final_page ();
119
120         the_startup = this;
121 }
122
123 ArdourStartup::~ArdourStartup ()
124 {
125 }
126
127 bool
128 ArdourStartup::required ()
129 {
130         return !Glib::file_test (been_here_before_path(), Glib::FILE_TEST_EXISTS);
131 }
132
133 std::string
134 ArdourStartup::been_here_before_path ()
135 {
136         // XXXX use more specific version so we can catch upgrades
137         return Glib::build_filename (user_config_directory (), ".a3");
138 }
139
140 void
141 ArdourStartup::setup_prerelease_page ()
142 {
143         VBox* vbox = manage (new VBox);
144         Label* label = manage (new Label);
145         label->set_markup (string_compose (_("<b>Welcome to this BETA release of Ardour %1</b>\n\n\
146 Ardour %1 has been released for Linux but because of the lack of testers,\n\
147 it is still at the beta stage on OS X. So, a few guidelines:\n\
148 \n\
149 1) Please do <b>NOT</b> use this software with the expectation that it is stable or reliable\n\
150    though it may be so, depending on your workflow.\n\
151 2) <b>Please do NOT use the forums at ardour.org to report issues</b>.\n\
152 3) Please <b>DO</b> use the bugtracker at http://tracker.ardour.org/ to report issues\n\
153    making sure to note the product version number as %1-beta.\n\
154 4) Please <b>DO</b> use the ardour-users mailing list to discuss ideas and pass on comments.\n\
155 5) Please <b>DO</b> join us on IRC for real time discussions about ardour3. You\n\
156    can get there directly from Ardour via the Help->Chat menu option.\n\
157 \n\
158 Full information on all the above can be found on the support page at\n\
159 \n\
160                 http://ardour.org/support\n\
161 "), VERSIONSTRING));
162
163         vbox->set_border_width (12);
164         vbox->pack_start (*label, false, false, 12);
165         vbox->show_all ();
166         
167         append_page (*vbox);
168         set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
169         set_page_title (*vbox, _("This is a BETA RELEASE"));
170         set_page_complete (*vbox, true);
171 }
172
173 void
174 ArdourStartup::setup_new_user_page ()
175 {
176         Label* foomatic = manage (new Label);
177
178         foomatic->set_markup (string_compose (_("\
179 <span size=\"larger\">%1 is a digital audio workstation. You can use it to \
180 record, edit and mix multi-track audio. You can produce your \
181 own CDs, mix video soundtracks, or experiment with new \
182 ideas about music and sound. \
183 \n\n\
184 There are a few things that need to be configured before you start \
185 using the program.</span> \
186 "), PROGRAM_NAME));
187         foomatic->set_justify (JUSTIFY_FILL);
188         foomatic->set_line_wrap ();
189
190         HBox* hbox = manage (new HBox);
191         HBox* vbox = manage (new HBox);
192
193         vbox->set_border_width (24);
194
195         hbox->pack_start (*foomatic, true, true);
196         vbox->pack_start (*hbox, true, true);
197
198         foomatic->show ();
199         hbox->show ();
200         vbox->show ();
201
202         new_user_page_index = append_page (*vbox);
203         set_page_type (*vbox, ASSISTANT_PAGE_INTRO);
204         set_page_title (*vbox, string_compose (_("Welcome to %1"), PROGRAM_NAME));
205         set_page_header_image (*vbox, icon_pixbuf);
206         set_page_complete (*vbox, true);
207 }
208
209 void
210 ArdourStartup::default_dir_changed ()
211 {
212         Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
213         // make new session folder chooser point to the new default
214         new_folder_chooser.set_current_folder (Config->get_default_session_parent_dir());       
215         config_changed ();
216 }
217
218 void
219 ArdourStartup::config_changed ()
220 {
221         config_modified = true;
222 }
223
224 void
225 ArdourStartup::setup_first_time_config_page ()
226 {
227         default_dir_chooser = manage (new FileChooserButton (string_compose (_("Default folder for %1 sessions"), PROGRAM_NAME),
228                                                              FILE_CHOOSER_ACTION_SELECT_FOLDER));
229         Gtk::Label* txt = manage (new Label);
230         HBox* hbox = manage (new HBox);
231         VBox* vbox = manage (new VBox);
232
233         txt->set_markup (string_compose (_("\
234 Each project that you work on with %1 has its own folder.\n\
235 These can require a lot of disk space if you are recording audio.\n\
236 \n\
237 Where would you like new %1 sessions to be stored by default?\n\n\
238 <i>(You can put new sessions anywhere, this is just a default)</i>"), PROGRAM_NAME));
239         txt->set_alignment (0.0, 0.0);
240
241         vbox->set_spacing (18);
242         vbox->set_border_width (24);
243
244         hbox->pack_start (*default_dir_chooser, false, true, 8);
245         vbox->pack_start (*txt, false, false);
246         vbox->pack_start (*hbox, false, true);
247
248         cerr << "set default folder to " << poor_mans_glob (Config->get_default_session_parent_dir()) << endl;
249         default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
250         default_dir_chooser->signal_current_folder_changed().connect (sigc::mem_fun (*this, &ArdourStartup::default_dir_changed));
251         default_dir_chooser->show ();
252
253         vbox->show_all ();
254
255         default_folder_page_index = append_page (*vbox);
256         set_page_title (*vbox, _("Default folder for new sessions"));
257         set_page_header_image (*vbox, icon_pixbuf);
258         set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
259
260         /* user can just skip all these settings if they want to */
261
262         set_page_complete (*vbox, true);
263 }
264
265 void
266 ArdourStartup::setup_monitoring_choice_page ()
267 {
268         mon_vbox.set_spacing (18);
269         mon_vbox.set_border_width (24);
270
271         HBox* hbox = manage (new HBox);
272         VBox* vbox = manage (new VBox);
273         /* first button will be on by default */
274         RadioButton::Group g (monitor_via_ardour_button.get_group());
275         monitor_via_hardware_button.set_group (g);
276
277         monitor_label.set_markup(_("\
278 While recording instruments or vocals, you probably want to listen to the\n\
279 signal as well as record it. This is called \"monitoring\". There are\n\
280 different ways to do this depending on the equipment you have and the\n\
281 configuration of that equipment. The two most common are presented here.\n\
282 Please choose whichever one is right for your setup.\n\n\
283 <i>(You can change this preference at any time, via the Preferences dialog)</i>\n\n\
284 <i>If you do not understand what this is about, just accept the default.</i>"));
285         monitor_label.set_alignment (0.0, 0.0);
286
287         vbox->set_spacing (6);
288
289         vbox->pack_start (monitor_via_hardware_button, false, true);
290         vbox->pack_start (monitor_via_ardour_button, false, true);
291         hbox->pack_start (*vbox, true, true, 8);
292         mon_vbox.pack_start (monitor_label, false, false);
293         mon_vbox.pack_start (*hbox, false, false);
294
295         mon_vbox.show_all ();
296
297         monitoring_page_index = append_page (mon_vbox);
298         set_page_title (mon_vbox, _("Monitoring Choices"));
299         set_page_header_image (mon_vbox, icon_pixbuf);
300
301         /* user could just click on "Forward" if default
302          * choice is correct.
303          */
304
305         set_page_complete (mon_vbox, true);
306 }
307
308 void
309 ArdourStartup::setup_monitor_section_choice_page ()
310 {
311         mon_sec_vbox.set_spacing (18);
312         mon_sec_vbox.set_border_width (24);
313
314         HBox* hbox = manage (new HBox);
315         VBox* main_vbox = manage (new VBox);
316         VBox* vbox;
317         Label* l = manage (new Label);
318
319         main_vbox->set_spacing (32);
320
321         no_monitor_section_button.set_label (_("Use a Master bus directly"));
322         l->set_alignment (0.0, 1.0);
323         l->set_markup(_("Connect the Master bus directly to your hardware outputs. This is preferable for simple usage."));
324
325         vbox = manage (new VBox);
326         vbox->set_spacing (6);
327         vbox->pack_start (no_monitor_section_button, false, true);
328         vbox->pack_start (*l, false, true);
329
330         main_vbox->pack_start (*vbox, false, false);
331
332         use_monitor_section_button.set_label (_("Use an additional Monitor bus"));
333         l = manage (new Label);
334         l->set_alignment (0.0, 1.0);
335         l->set_text (_("Use a Monitor bus between Master bus and hardware outputs for \n\
336 greater control in monitoring without affecting the mix."));
337
338         vbox = manage (new VBox);
339         vbox->set_spacing (6);
340         vbox->pack_start (use_monitor_section_button, false, true);
341         vbox->pack_start (*l, false, true);
342
343         main_vbox->pack_start (*vbox, false, false);
344
345         RadioButton::Group g (use_monitor_section_button.get_group());
346         no_monitor_section_button.set_group (g);
347
348         if (Config->get_use_monitor_bus()) {
349                 use_monitor_section_button.set_active (true);
350         } else {
351                 no_monitor_section_button.set_active (true);
352         }
353
354         use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
355         no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
356
357         monitor_section_label.set_markup(_("<i>You can change this preference at any time via the Preferences dialog.\nYou can also add or remove the monitor section to/from any session.</i>\n\n\
358 <i>If you do not understand what this is about, just accept the default.</i>"));
359         monitor_section_label.set_alignment (0.0, 0.0);
360
361         hbox->pack_start (*main_vbox, true, true, 8);
362         mon_sec_vbox.pack_start (*hbox, false, false);
363         mon_sec_vbox.pack_start (monitor_section_label, false, false);
364
365         mon_sec_vbox.show_all ();
366
367         monitor_section_page_index = append_page (mon_sec_vbox);
368         set_page_title (mon_sec_vbox, _("Monitor Section"));
369         set_page_header_image (mon_sec_vbox, icon_pixbuf);
370
371         /* user could just click on "Forward" if default
372          * choice is correct.
373          */
374
375         set_page_complete (mon_sec_vbox, true);
376 }
377
378 void
379 ArdourStartup::setup_final_page ()
380 {
381         string msg = string_compose (_("%1 is ready for use"), PROGRAM_NAME);
382         
383         final_page.set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", msg));
384         final_page.show ();
385         final_page_index = append_page (final_page);
386         set_page_complete (final_page, true);
387         set_page_header_image (final_page, icon_pixbuf);
388         set_page_type (final_page, ASSISTANT_PAGE_CONFIRM);
389 }
390
391 void
392 ArdourStartup::on_cancel ()
393 {
394         _response = RESPONSE_CANCEL;
395         gtk_main_quit ();
396 }
397
398 bool
399 ArdourStartup::on_delete_event (GdkEventAny*)
400 {
401         _response = RESPONSE_CLOSE;
402         gtk_main_quit ();
403         return true;
404 }
405
406 void
407 ArdourStartup::on_apply ()
408 {
409         if (config_modified) {
410
411                 if (default_dir_chooser) {
412                         Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
413                 }
414
415                 if (monitor_via_hardware_button.get_active()) {
416                         Config->set_monitoring_model (ExternalMonitoring);
417                 } else if (monitor_via_ardour_button.get_active()) {
418                         Config->set_monitoring_model (SoftwareMonitoring);
419                 }
420
421                 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
422
423                 Config->save_state ();
424
425         }
426
427         {
428                 /* "touch" the been-here-before path now we've successfully
429                    made it through the first time setup (at least)
430                 */
431                 ofstream fout (been_here_before_path().c_str());
432
433         }
434                 
435         _response = RESPONSE_OK;
436         gtk_main_quit ();
437 }
438
439
440 void
441 ArdourStartup::move_along_now ()
442 {
443         on_apply ();
444 }
445
446
447