Replace use of PBD::sys::path in ardour/template_utils.h
[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 #endif
23
24 #include <fstream>
25 #include <algorithm>
26
27 #include <gtkmm/main.h>
28 #include <gtkmm/filechooser.h>
29
30 #include "pbd/failed_constructor.h"
31 #include "pbd/file_utils.h"
32 #include "pbd/filesystem.h"
33 #include "pbd/replace_all.h"
34 #include "pbd/whitespace.h"
35
36 #include "ardour/filesystem_paths.h"
37 #include "ardour/recent_sessions.h"
38 #include "ardour/session.h"
39 #include "ardour/session_state_utils.h"
40 #include "ardour/template_utils.h"
41 #include "ardour/filename_extensions.h"
42
43 #include "ardour_ui.h"
44 #include "startup.h"
45 #include "opts.h"
46 #include "engine_dialog.h"
47 #include "i18n.h"
48 #include "utils.h"
49
50 using namespace std;
51 using namespace Gtk;
52 using namespace Gdk;
53 using namespace Glib;
54 using namespace PBD;
55 using namespace ARDOUR;
56
57 ArdourStartup* ArdourStartup::the_startup = 0;
58
59 static string poor_mans_glob (string path)
60 {
61         string copy = path;
62         replace_all (copy, "~", Glib::get_home_dir());
63         return copy;
64 }
65
66
67 ArdourStartup::ArdourStartup ()
68         : _response (RESPONSE_OK)
69         , ic_new_session_button (_("Create a new session"))
70         , ic_existing_session_button (_("Open an existing session"))
71         , monitor_via_hardware_button (_("Use an external mixer or the hardware mixer of your audio interface.\n\
72 Ardour will play NO role in monitoring"))
73         , monitor_via_ardour_button (string_compose (_("Ask %1 to play back material as it is being recorded"), PROGRAM_NAME))
74         , new_folder_chooser (FILE_CHOOSER_ACTION_SELECT_FOLDER)
75         , more_new_session_options_button (_("I'd like more options for this session"))
76         , _output_limit_count_adj (1, 0, 100, 1, 10, 0)
77         , _input_limit_count_adj (1, 0, 100, 1, 10, 0)
78         , _master_bus_channel_count_adj (2, 0, 100, 1, 10, 0)
79         , _existing_session_chooser_used (false)
80 {
81         audio_page_index = -1;
82         initial_choice_index = -1;
83         new_user_page_index = -1;
84         default_folder_page_index = -1;
85         monitoring_page_index = -1;
86         session_page_index = -1;
87         final_page_index = -1;
88         session_options_page_index = -1;
89         new_only = false;
90
91         engine_dialog = 0;
92         config_modified = false;
93         default_dir_chooser = 0;
94
95         use_template_button.set_group (session_template_group);
96         use_session_as_template_button.set_group (session_template_group);
97
98         set_keep_above (true);
99         set_resizable (false);
100         set_position (WIN_POS_CENTER);
101         set_border_width (12);
102
103         if ((icon_pixbuf = ::get_icon ("ardour_icon_48px")) == 0) {
104                 throw failed_constructor();
105         }
106
107         list<Glib::RefPtr<Gdk::Pixbuf> > window_icons;
108         Glib::RefPtr<Gdk::Pixbuf> icon;
109
110         if ((icon = ::get_icon ("ardour_icon_16px")) != 0) {
111                 window_icons.push_back (icon);
112         }
113         if ((icon = ::get_icon ("ardour_icon_22px")) != 0) {
114                 window_icons.push_back (icon);
115         }
116         if ((icon = ::get_icon ("ardour_icon_32px")) != 0) {
117                 window_icons.push_back (icon);
118         }
119         if ((icon = ::get_icon ("ardour_icon_48px")) != 0) {
120                 window_icons.push_back (icon);
121         }
122         if (!window_icons.empty ()) {
123                 set_default_icon_list (window_icons);
124         }
125
126         new_user = !exists (been_here_before_path ());
127
128         bool need_audio_setup = !EngineControl::engine_running();
129
130         // setup_prerelease_page ();
131
132         if (new_user) {
133
134                 /* Create the config directory so that we have somewhere to put the
135                    been_here_before file.
136                 */
137                 try {
138                         sys::create_directories (user_config_directory ());
139                 }
140                 catch (const sys::filesystem_error& ex) {
141                         error << "Could not create user configuration directory" << endmsg;
142                 }
143                 
144                 setup_new_user_page ();
145                 setup_first_time_config_page ();
146                 setup_monitoring_choice_page ();
147                 setup_monitor_section_choice_page ();
148
149                 if (need_audio_setup) {
150                         setup_audio_page ();
151                 }
152
153                 ic_new_session_button.set_active (true); // always create new session on first run
154
155         } else {
156
157                 if (need_audio_setup) {
158                         setup_audio_page ();
159                 }
160
161                 setup_initial_choice_page ();
162         }
163
164         setup_session_page ();
165         setup_more_options_page ();
166
167         if (new_user) {
168                 setup_final_page ();
169         }
170
171         the_startup = this;
172 }
173
174 ArdourStartup::~ArdourStartup ()
175 {
176 }
177
178 void
179 ArdourStartup::setup_prerelease_page ()
180 {
181         VBox* vbox = manage (new VBox);
182         Label* label = manage (new Label);
183         label->set_markup (_("<b>Welcome to this BETA release of Ardour 3.0</b>\n\n\
184 There are still several issues and bugs to be worked on,\n\
185 as well as general workflow improvements, before this can be considered\n\
186 release software. So, a few guidelines:\n\
187 \n\
188 1) Please do <b>NOT</b> use this software with the expectation that it is stable or reliable\n\
189    though it may be so, depending on your workflow.\n\
190 2) Please see http://ardour.org/a3_features for a guide to new features.\n\
191 3) <b>Please do NOT use the forums at ardour.org to report issues</b>.\n\
192 4) Please <b>DO</b> use the bugtracker at http://tracker.ardour.org/ to report issues\n\
193    making sure to note the product version number as 3.0-beta.\n\
194 5) Please <b>DO</b> use the ardour-users mailing list to discuss ideas and pass on comments.\n\
195 6) Please <b>DO</b> join us on IRC for real time discussions about ardour3. You\n\
196    can get there directly from Ardour via the Help->Chat menu option.\n\
197 \n\
198 Full information on all the above can be found on the support page at\n\
199 \n\
200                 http://ardour.org/support\n\
201 "));
202
203         vbox->set_border_width (12);
204         vbox->pack_start (*label, false, false, 12);
205         vbox->show_all ();
206
207         append_page (*vbox);
208         set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
209         set_page_title (*vbox, _("This is a BETA RELEASE"));
210         set_page_complete (*vbox, true);
211 }
212
213 void
214 ArdourStartup::set_new_only (bool yn)
215 {
216         new_only = yn;
217
218         if (new_only) {
219                 ic_vbox.hide ();
220         } else {
221                 ic_vbox.show ();
222         }
223 }
224
225 void
226 ArdourStartup::set_load_template (string load_template)
227 {
228         use_template_button.set_active (false);
229         load_template_override = load_template;
230 }
231
232 bool
233 ArdourStartup::use_session_template ()
234 {
235         if (!load_template_override.empty()) {
236                 return true;
237         }
238
239         if (use_template_button.get_active()) {
240                 return template_chooser.get_active_row_number() > 0;
241         } else {
242                 return !session_template_chooser.get_filename().empty();
243         }
244 }
245
246 std::string
247 ArdourStartup::session_template_name ()
248 {
249         if (!load_template_override.empty()) {
250                 string the_path(ARDOUR::user_template_directory());
251                 return Glib::build_filename (the_path, load_template_override + ARDOUR::template_suffix);
252         }
253
254         if (ic_existing_session_button.get_active()) {
255                 return string();
256         }
257
258         if (use_template_button.get_active()) {
259                 TreeModel::iterator iter = template_chooser.get_active ();
260                 TreeModel::Row row = (*iter);
261                 string s = row[session_template_columns.path];
262                 return s;
263         } else {
264                 return session_template_chooser.get_filename();
265
266         }
267 }
268
269 std::string
270 ArdourStartup::session_name (bool& should_be_new)
271 {
272         if (ic_new_session_button.get_active()) {
273                 should_be_new = true;
274                 string val = new_name_entry.get_text ();
275                 strip_whitespace_edges (val);
276                 return val;
277         } else if (_existing_session_chooser_used) {
278                 /* existing session chosen from file chooser */
279                 should_be_new = false;
280                 return existing_session_chooser.get_filename ();
281         } else {
282                 /* existing session chosen from recent list */
283                 should_be_new = false;
284
285                 TreeIter iter = recent_session_display.get_selection()->get_selected();
286
287                 if (iter) {
288                         return (*iter)[recent_session_columns.visible_name];
289                 }
290
291                 return "";
292         }
293 }
294
295 std::string
296 ArdourStartup::session_folder ()
297 {
298         if (ic_new_session_button.get_active()) {
299                 std::string legal_session_folder_name = legalize_for_path (new_name_entry.get_text());
300                 return Glib::build_filename (new_folder_chooser.get_current_folder(), legal_session_folder_name);
301         } else if (_existing_session_chooser_used) {
302                 /* existing session chosen from file chooser */
303                 return existing_session_chooser.get_current_folder ();
304         } else {
305                 /* existing session chosen from recent list */
306                 TreeIter iter = recent_session_display.get_selection()->get_selected();
307
308                 if (iter) {
309                         return (*iter)[recent_session_columns.fullpath];
310                 }
311                 return "";
312         }
313 }
314
315 void
316 ArdourStartup::setup_audio_page ()
317 {
318         engine_dialog = manage (new EngineControl);
319
320         engine_dialog->set_border_width (12);
321
322         engine_dialog->show_all ();
323
324         audio_page_index = append_page (*engine_dialog);
325         set_page_type (*engine_dialog, ASSISTANT_PAGE_CONTENT);
326         set_page_title (*engine_dialog, _("Audio / MIDI Setup"));
327
328         /* the default parameters should work, so the page is potentially complete */
329
330         set_page_complete (*engine_dialog, true);
331 }
332
333 void
334 ArdourStartup::setup_new_user_page ()
335 {
336         Label* foomatic = manage (new Label);
337
338         foomatic->set_markup (string_compose (_("\
339 <span size=\"larger\">%1 is a digital audio workstation. You can use it to \
340 record, edit and mix multi-track audio. You can produce your \
341 own CDs, mix video soundtracks, or experiment with new \
342 ideas about music and sound. \
343 \n\n\
344 There are a few things that need to be configured before you start \
345 using the program.</span> \
346 "), PROGRAM_NAME));
347         foomatic->set_justify (JUSTIFY_FILL);
348         foomatic->set_line_wrap ();
349
350         HBox* hbox = manage (new HBox);
351         HBox* vbox = manage (new HBox);
352
353         vbox->set_border_width (24);
354
355         hbox->pack_start (*foomatic, true, true);
356         vbox->pack_start (*hbox, true, true);
357
358         foomatic->show ();
359         hbox->show ();
360         vbox->show ();
361
362         new_user_page_index = append_page (*vbox);
363         set_page_type (*vbox, ASSISTANT_PAGE_INTRO);
364         set_page_title (*vbox, string_compose (_("Welcome to %1"), PROGRAM_NAME));
365         set_page_header_image (*vbox, icon_pixbuf);
366         set_page_complete (*vbox, true);
367 }
368
369 void
370 ArdourStartup::default_dir_changed ()
371 {
372         Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
373         // make new session folder chooser point to the new default
374         new_folder_chooser.set_current_folder (Config->get_default_session_parent_dir());       
375         config_changed ();
376 }
377
378 void
379 ArdourStartup::config_changed ()
380 {
381         config_modified = true;
382 }
383
384 void
385 ArdourStartup::setup_first_time_config_page ()
386 {
387         default_dir_chooser = manage (new FileChooserButton (string_compose (_("Default folder for %1 sessions"), PROGRAM_NAME),
388                                                              FILE_CHOOSER_ACTION_SELECT_FOLDER));
389         Gtk::Label* txt = manage (new Label);
390         HBox* hbox = manage (new HBox);
391         VBox* vbox = manage (new VBox);
392
393         txt->set_markup (string_compose (_("\
394 Each project that you work on with %1 has its own folder.\n\
395 These can require a lot of disk space if you are recording audio.\n\
396 \n\
397 Where would you like new %1 sessions to be stored by default?\n\n\
398 <i>(You can put new sessions anywhere, this is just a default)</i>"), PROGRAM_NAME));
399         txt->set_alignment (0.0, 0.0);
400
401         vbox->set_spacing (18);
402         vbox->set_border_width (24);
403
404         hbox->pack_start (*default_dir_chooser, false, true, 8);
405         vbox->pack_start (*txt, false, false);
406         vbox->pack_start (*hbox, false, true);
407
408         default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
409         default_dir_chooser->signal_current_folder_changed().connect (sigc::mem_fun (*this, &ArdourStartup::default_dir_changed));
410         default_dir_chooser->show ();
411
412         vbox->show_all ();
413
414         default_folder_page_index = append_page (*vbox);
415         set_page_title (*vbox, _("Default folder for new sessions"));
416         set_page_header_image (*vbox, icon_pixbuf);
417         set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
418
419         /* user can just skip all these settings if they want to */
420
421         set_page_complete (*vbox, true);
422 }
423
424 void
425 ArdourStartup::setup_monitoring_choice_page ()
426 {
427         mon_vbox.set_spacing (18);
428         mon_vbox.set_border_width (24);
429
430         HBox* hbox = manage (new HBox);
431         VBox* vbox = manage (new VBox);
432         RadioButton::Group g (monitor_via_hardware_button.get_group());
433         monitor_via_ardour_button.set_group (g);
434
435         monitor_label.set_markup(_("\
436 While recording instruments or vocals, you probably want to listen to the\n\
437 signal as well as record it. This is called \"monitoring\". There are\n\
438 different ways to do this depending on the equipment you have and the\n\
439 configuration of that equipment. The two most common are presented here.\n\
440 Please choose whichever one is right for your setup.\n\n\
441 <i>(You can change this preference at any time, via the Preferences dialog)</i>\n\n\
442 <i>If you do not understand what this is about, just accept the default.</i>"));
443         monitor_label.set_alignment (0.0, 0.0);
444
445         vbox->set_spacing (6);
446
447         vbox->pack_start (monitor_via_hardware_button, false, true);
448         vbox->pack_start (monitor_via_ardour_button, false, true);
449         hbox->pack_start (*vbox, true, true, 8);
450         mon_vbox.pack_start (monitor_label, false, false);
451         mon_vbox.pack_start (*hbox, false, false);
452
453         mon_vbox.show_all ();
454
455         monitoring_page_index = append_page (mon_vbox);
456         set_page_title (mon_vbox, _("Monitoring Choices"));
457         set_page_header_image (mon_vbox, icon_pixbuf);
458
459         /* user could just click on "Forward" if default
460          * choice is correct.
461          */
462
463         set_page_complete (mon_vbox, true);
464 }
465
466 void
467 ArdourStartup::setup_monitor_section_choice_page ()
468 {
469         mon_sec_vbox.set_spacing (18);
470         mon_sec_vbox.set_border_width (24);
471
472         HBox* hbox = manage (new HBox);
473         VBox* main_vbox = manage (new VBox);
474         VBox* vbox;
475         Label* l = manage (new Label);
476
477         main_vbox->set_spacing (32);
478
479         no_monitor_section_button.set_label (_("Use a Master bus directly"));
480         l->set_alignment (0.0, 1.0);
481         l->set_markup(_("Connect the Master bus directly to your hardware outputs. This is preferable for simple usage."));
482
483         vbox = manage (new VBox);
484         vbox->set_spacing (6);
485         vbox->pack_start (no_monitor_section_button, false, true);
486         vbox->pack_start (*l, false, true);
487
488         main_vbox->pack_start (*vbox, false, false);
489
490         use_monitor_section_button.set_label (_("Use an additional Monitor bus"));
491         l = manage (new Label);
492         l->set_alignment (0.0, 1.0);
493         l->set_text (_("Use a Monitor bus between Master bus and hardware outputs for \n\
494 greater control in monitoring without affecting the mix."));
495
496         vbox = manage (new VBox);
497         vbox->set_spacing (6);
498         vbox->pack_start (use_monitor_section_button, false, true);
499         vbox->pack_start (*l, false, true);
500
501         main_vbox->pack_start (*vbox, false, false);
502
503         RadioButton::Group g (use_monitor_section_button.get_group());
504         no_monitor_section_button.set_group (g);
505
506         if (Config->get_use_monitor_bus()) {
507                 use_monitor_section_button.set_active (true);
508         } else {
509                 no_monitor_section_button.set_active (true);
510         }
511
512         use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
513         no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
514
515         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\
516 <i>If you do not understand what this is about, just accept the default.</i>"));
517         monitor_section_label.set_alignment (0.0, 0.0);
518
519         hbox->pack_start (*main_vbox, true, true, 8);
520         mon_sec_vbox.pack_start (*hbox, false, false);
521         mon_sec_vbox.pack_start (monitor_section_label, false, false);
522
523         mon_sec_vbox.show_all ();
524
525         monitor_section_page_index = append_page (mon_sec_vbox);
526         set_page_title (mon_sec_vbox, _("Monitor Section"));
527         set_page_header_image (mon_sec_vbox, icon_pixbuf);
528
529         /* user could just click on "Forward" if default
530          * choice is correct.
531          */
532
533         set_page_complete (mon_sec_vbox, true);
534 }
535
536 void
537 ArdourStartup::setup_initial_choice_page ()
538 {
539         ic_vbox.set_spacing (6);
540         ic_vbox.set_border_width (24);
541
542         RadioButton::Group g (ic_new_session_button.get_group());
543         ic_existing_session_button.set_group (g);
544
545         HBox* centering_hbox = manage (new HBox);
546         VBox* centering_vbox = manage (new VBox);
547
548         centering_vbox->set_spacing (6);
549
550         centering_vbox->pack_start (ic_new_session_button, false, true);
551         centering_vbox->pack_start (ic_existing_session_button, false, true);
552
553         ic_new_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
554         ic_new_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
555
556         ic_existing_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
557         ic_existing_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
558
559         centering_hbox->pack_start (*centering_vbox, true, true);
560
561         ic_vbox.pack_start (*centering_hbox, true, true);
562
563         ic_vbox.show_all ();
564
565         initial_choice_index = append_page (ic_vbox);
566         set_page_title (ic_vbox, _("What would you like to do ?"));
567         set_page_header_image (ic_vbox, icon_pixbuf);
568
569         /* user could just click on "Forward" if default
570          * choice is correct.
571          */
572
573         set_page_complete (ic_vbox, true);
574 }
575
576 bool
577 ArdourStartup::initial_button_clicked (GdkEventButton* ev)
578 {
579         if (ev->type == GDK_2BUTTON_PRESS && session_page_index != -1) {
580                 set_current_page(session_page_index);
581         }
582
583         return false;
584 }
585
586 void
587 ArdourStartup::initial_button_activated ()
588 {
589         if (session_page_index != -1) {
590                 set_current_page(session_page_index);
591         }
592 }
593
594 void
595 ArdourStartup::setup_session_page ()
596 {
597         session_vbox.set_border_width (24);
598
599         session_vbox.pack_start (session_hbox, true, true);
600         session_vbox.show_all ();
601
602         session_page_index = append_page (session_vbox);
603         /* initial setting */
604         set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
605 }
606
607 void
608 ArdourStartup::setup_final_page ()
609 {
610         final_page.set_text (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
611         final_page.show ();
612         final_page_index = append_page (final_page);
613         set_page_complete (final_page, true);
614         set_page_header_image (final_page, icon_pixbuf);
615         set_page_type (final_page, ASSISTANT_PAGE_CONFIRM);
616 }
617
618 void
619 ArdourStartup::on_cancel ()
620 {
621         _response = RESPONSE_CANCEL;
622         gtk_main_quit ();
623 }
624
625 bool
626 ArdourStartup::on_delete_event (GdkEventAny*)
627 {
628         _response = RESPONSE_CLOSE;
629         gtk_main_quit ();
630         return true;
631 }
632
633 void
634 ArdourStartup::on_apply ()
635 {
636         if (engine_dialog) {
637                 engine_dialog->setup_engine ();
638         }
639
640         if (config_modified) {
641
642                 if (default_dir_chooser) {
643                         Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
644                 }
645
646                 if (monitor_via_hardware_button.get_active()) {
647                         Config->set_monitoring_model (ExternalMonitoring);
648                 } else if (monitor_via_ardour_button.get_active()) {
649                         Config->set_monitoring_model (SoftwareMonitoring);
650                 }
651
652                 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
653
654                 /* "touch" the been-here-before path now that we're about to save Config */
655                 ofstream fout (been_here_before_path().to_string().c_str());
656                 
657                 Config->save_state ();
658         }
659
660         _response = RESPONSE_OK;
661         gtk_main_quit ();
662 }
663
664 void
665 ArdourStartup::on_prepare (Gtk::Widget* page)
666 {
667         if (page == &session_vbox) {
668
669                 if (ic_new_session_button.get_active()) {
670                         /* new session requested */
671                         setup_new_session_page ();
672                 } else {
673                         /* existing session requested */
674                         setup_existing_session_page ();
675
676                 }
677
678                 /* HACK HACK HACK ... change the "Apply" button label
679                    to say "Open"
680                 */
681
682                 Gtk::Widget* tl = session_vbox.get_toplevel();
683                 Gtk::Window* win;
684                 if ((win = dynamic_cast<Gtk::Window*>(tl)) != 0) {
685                         /* ::get_default_widget() is not wrapped in gtkmm */
686                         Gtk::Widget* def = wrap (gtk_window_get_default_widget (win->gobj()));
687                         Gtk::Button* button;
688                         if ((button = dynamic_cast<Gtk::Button*>(def)) != 0) {
689                                 if (more_new_session_options_button.get_active()) {
690                                         button->set_label (_("Forward"));
691                                 }else{
692                                         button->set_label (_("Open"));
693                                 }
694                         }
695                 }
696         }
697 }
698
699 void
700 ArdourStartup::populate_session_templates ()
701 {
702         vector<TemplateInfo> templates;
703
704         find_session_templates (templates);
705
706         template_model->clear ();
707
708         for (vector<TemplateInfo>::iterator x = templates.begin(); x != templates.end(); ++x) {
709                 TreeModel::Row row;
710
711                 row = *(template_model->append ());
712
713                 row[session_template_columns.name] = (*x).name;
714                 row[session_template_columns.path] = (*x).path;
715         }
716 }
717
718 static bool
719 lost_name_entry_focus (GdkEventFocus*)
720 {
721         // cerr << "lost focus\n";
722         return false;
723 }
724
725 void
726 ArdourStartup::setup_new_session_page ()
727 {
728         if (!session_hbox.get_children().empty()) {
729                 session_hbox.remove (**session_hbox.get_children().begin());
730         }
731
732         session_new_vbox.set_spacing (18);
733
734         if (session_new_vbox.get_children().empty()) {
735                 VBox *vbox1 = manage (new VBox);
736                 HBox* hbox1 = manage (new HBox);
737                 Label* label1 = manage (new Label);
738
739                 vbox1->set_spacing (6);
740
741                 hbox1->set_spacing (6);
742                 hbox1->pack_start (*label1, false, false);
743                 hbox1->pack_start (new_name_entry, true, true);
744
745                 label1->set_text (_("Session name:"));
746
747
748                 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
749                         new_name_entry.set_text  (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
750                         /* name provided - they can move right along */
751                         set_page_complete (session_vbox, true);
752                 }
753
754                 new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_changed));
755                 new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &ArdourStartup::move_along_now));
756
757                 vbox1->pack_start (*hbox1, true, true);
758
759                 /* --- */
760
761                 HBox* hbox2 = manage (new HBox);
762                 Label* label2 = manage (new Label);
763
764                 hbox2->set_spacing (6);
765                 hbox2->pack_start (*label2, false, false);
766                 hbox2->pack_start (new_folder_chooser, true, true);
767
768                 label2->set_text (_("Create session folder in:"));
769
770                 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
771                         new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
772                 } else if (ARDOUR_UI::instance()->session_loaded) {
773                         // point the new session file chooser at the parent directory of the current session
774                         string session_parent_dir = Glib::path_get_dirname(ARDOUR_UI::instance()->the_session()->path());
775                         string::size_type last_dir_sep = session_parent_dir.rfind(G_DIR_SEPARATOR);
776                         session_parent_dir = session_parent_dir.substr(0, last_dir_sep);
777                         new_folder_chooser.set_current_folder (session_parent_dir);
778                         new_folder_chooser.add_shortcut_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
779                 } else {
780                         new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
781                 }
782                 new_folder_chooser.set_title (_("Select folder for session"));
783
784 #ifdef GTKOSX
785                 new_folder_chooser.add_shortcut_folder ("/Volumes");
786 #endif
787
788                 vbox1->pack_start (*hbox2, false, false);
789
790                 session_new_vbox.pack_start (*vbox1, false, false);
791
792                 /* --- */
793
794                 VBox *vbox2 = manage (new VBox);
795                 HBox* hbox3 = manage (new HBox);
796                 Label* label3 = manage (new Label);
797                 template_model = ListStore::create (session_template_columns);
798                 populate_session_templates ();
799
800                 vbox2->set_spacing (6);
801
802                 label3->set_markup (_("<b>Options</b>"));
803                 label3->set_alignment (0.0, 0.0);
804
805                 vbox2->pack_start (*label3, false, true);
806
807                 VBox *vbox3 = manage (new VBox);
808
809                 vbox3->set_spacing (6);
810
811                 if (!template_model->children().empty()) {
812
813                         HBox* hbox4a = manage (new HBox);
814                         use_template_button.set_label (_("Use this template"));
815
816                         TreeModel::Row row = *template_model->prepend ();
817                         row[session_template_columns.name] = (_("no template"));
818                         row[session_template_columns.path] = string();
819
820                         hbox4a->set_spacing (6);
821                         hbox4a->pack_start (use_template_button, false, false);
822                         hbox4a->pack_start (template_chooser, true, true);
823
824                         template_chooser.set_model (template_model);
825
826                         Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
827                         text_renderer->property_editable() = false;
828
829                         template_chooser.pack_start (*text_renderer);
830                         template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
831                         template_chooser.set_active (0);
832
833                         use_template_button.show();
834                         template_chooser.show ();
835
836                         vbox3->pack_start (*hbox4a, false, false);
837                 }
838
839                 /* --- */
840
841                 if (!new_user) {
842                         session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
843
844                         HBox* hbox4b = manage (new HBox);
845                         use_session_as_template_button.set_label (_("Use an existing session as a template:"));
846
847                         hbox4b->set_spacing (6);
848                         hbox4b->pack_start (use_session_as_template_button, false, false);
849                         hbox4b->pack_start (session_template_chooser, true, true);
850
851                         use_session_as_template_button.show ();
852                         session_template_chooser.show ();
853
854                         Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
855                         session_filter->add_pattern (X_("*.ardour"));
856                         session_template_chooser.set_filter (*session_filter);
857                         session_template_chooser.set_title (_("Select template"));
858
859                         vbox3->pack_start (*hbox4b, false, false);
860                 }
861
862                 /* --- */
863
864                 HBox* hbox5 = manage (new HBox);
865
866                 hbox5->set_spacing (6);
867                 hbox5->pack_start (more_new_session_options_button, false, false);
868
869                 more_new_session_options_button.show ();
870                 more_new_session_options_button.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::more_new_session_options_button_clicked));
871
872                 vbox3->pack_start (*hbox5, false, false);
873                 hbox3->pack_start (*vbox3, true, true, 8);
874                 vbox2->pack_start (*hbox3, false, false);
875
876                 /* --- */
877
878                 session_new_vbox.pack_start (*vbox2, false, false);
879         }
880
881         session_new_vbox.show_all ();
882         session_hbox.pack_start (session_new_vbox, true, true);
883         set_page_title (session_vbox, _("New Session"));
884         set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
885
886         if (more_new_session_options_button.get_active()) {
887                 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
888         }
889
890         new_name_entry.signal_map().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_mapped));
891         new_name_entry.signal_focus_out_event().connect (sigc::ptr_fun (lost_name_entry_focus));
892 }
893
894 void
895 ArdourStartup::new_name_mapped ()
896 {
897         // cerr << "Grab new name focus\n";
898         new_name_entry.grab_focus ();
899 }
900
901 void
902 ArdourStartup::new_name_changed ()
903 {
904         if (!new_name_entry.get_text().empty()) {
905                 set_page_complete (session_vbox, true);
906         } else {
907                 set_page_complete (session_vbox, false);
908         }
909 }
910
911 int
912 ArdourStartup::redisplay_recent_sessions ()
913 {
914         std::vector<sys::path> session_directories;
915         RecentSessionsSorter cmp;
916
917         recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
918         recent_session_model->clear ();
919
920         ARDOUR::RecentSessions rs;
921         ARDOUR::read_recent_sessions (rs);
922
923         if (rs.empty()) {
924                 recent_session_display.set_model (recent_session_model);
925                 return 0;
926         }
927         //
928         // sort them alphabetically
929         sort (rs.begin(), rs.end(), cmp);
930
931         for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
932                 session_directories.push_back ((*i).second);
933         }
934
935         for (vector<sys::path>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
936         {
937                 std::vector<std::string> state_file_paths;
938
939                 // now get available states for this session
940
941                 get_state_files_in_directory ((*i).to_string (), state_file_paths);
942
943                 vector<string*>* states;
944                 vector<const gchar*> item;
945                 string fullpath = (*i).to_string();
946
947                 /* remove any trailing / */
948
949                 if (fullpath[fullpath.length()-1] == '/') {
950                         fullpath = fullpath.substr (0, fullpath.length()-1);
951                 }
952
953                 /* check whether session still exists */
954                 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
955                         /* session doesn't exist */
956                         continue;
957                 }
958
959                 /* now get available states for this session */
960
961                 if ((states = Session::possible_states (fullpath)) == 0) {
962                         /* no state file? */
963                         continue;
964                 }
965
966                 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
967
968                 Gtk::TreeModel::Row row = *(recent_session_model->append());
969
970                 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
971                 row[recent_session_columns.fullpath] = fullpath;
972
973                 if (state_file_names.size() > 1) {
974
975                         // add the children
976
977                         for (std::vector<std::string>::iterator i2 = state_file_names.begin();
978                                         i2 != state_file_names.end(); ++i2)
979                         {
980
981                                 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
982
983                                 child_row[recent_session_columns.visible_name] = *i2;
984                                 child_row[recent_session_columns.fullpath] = fullpath;
985                         }
986                 }
987         }
988
989         recent_session_display.set_tooltip_column(1); // recent_session_columns.fullpath 
990         recent_session_display.set_model (recent_session_model);
991         return rs.size();
992 }
993
994 void
995 ArdourStartup::recent_session_row_selected ()
996 {
997         if (recent_session_display.get_selection()->count_selected_rows() > 0) {
998                 set_page_complete (session_vbox, true);
999         } else {
1000                 set_page_complete (session_vbox, false);
1001         }
1002 }
1003
1004 void
1005 ArdourStartup::setup_existing_session_page ()
1006 {
1007         recent_session_model = TreeStore::create (recent_session_columns);
1008         redisplay_recent_sessions ();
1009
1010         if (!session_hbox.get_children().empty()) {
1011                 session_hbox.remove (**session_hbox.get_children().begin());
1012         }
1013
1014         if (session_existing_vbox.get_children().empty()) {
1015
1016                 recent_session_display.set_model (recent_session_model);
1017                 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1018                 recent_session_display.set_headers_visible (false);
1019                 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
1020
1021                 recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::recent_session_row_selected));
1022
1023                 recent_scroller.add (recent_session_display);
1024                 recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1025                 recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
1026
1027                 recent_session_display.show();
1028
1029                 recent_scroller.show();
1030                 int cnt = redisplay_recent_sessions ();
1031                 recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ArdourStartup::recent_row_activated));
1032
1033                 if (cnt > 4) {
1034                         recent_scroller.set_size_request (-1, 300);
1035                 }
1036
1037                 session_existing_vbox.set_spacing (8);
1038                 session_existing_vbox.pack_start (recent_scroller, true, true);
1039
1040                 existing_session_chooser.set_title (_("Select session file"));
1041                 existing_session_chooser.signal_file_set().connect (sigc::mem_fun (*this, &ArdourStartup::existing_session_selected));
1042                 existing_session_chooser.set_current_folder(poor_mans_glob (Config->get_default_session_parent_dir()));
1043
1044                 FileFilter session_filter;
1045                 session_filter.add_pattern ("*.ardour");
1046                 session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
1047                 existing_session_chooser.add_filter (session_filter);
1048                 existing_session_chooser.set_filter (session_filter);
1049                 
1050 #ifdef GTKOSX
1051                 existing_session_chooser.add_shortcut_folder ("/Volumes");
1052 #endif
1053
1054                 HBox* hbox = manage (new HBox);
1055                 hbox->set_spacing (4);
1056                 hbox->pack_start (*manage (new Label (_("Browse:"))), PACK_SHRINK);
1057                 hbox->pack_start (existing_session_chooser);
1058                 session_existing_vbox.pack_start (*hbox, false, false);
1059                 hbox->show_all ();
1060         }
1061
1062         session_existing_vbox.show_all ();
1063         session_hbox.pack_start (session_existing_vbox, true, true);
1064
1065         set_page_title (session_vbox, _("Select a session"));
1066         set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1067 }
1068
1069 void
1070 ArdourStartup::more_new_session_options_button_clicked ()
1071 {
1072         if (more_new_session_options_button.get_active()) {
1073                 more_options_vbox.show_all ();
1074                 set_page_type (more_options_vbox, ASSISTANT_PAGE_CONFIRM);
1075                 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
1076         } else {
1077                 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1078                 more_options_vbox.hide ();
1079         }
1080 }
1081
1082 void
1083 ArdourStartup::setup_more_options_page ()
1084 {
1085         more_options_vbox.set_border_width (24);
1086
1087         _output_limit_count.set_adjustment (_output_limit_count_adj);
1088         _input_limit_count.set_adjustment (_input_limit_count_adj);
1089         _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
1090
1091         chan_count_label_1.set_text (_("channels"));
1092         chan_count_label_3.set_text (_("channels"));
1093         chan_count_label_4.set_text (_("channels"));
1094
1095         chan_count_label_1.set_alignment(0,0.5);
1096         chan_count_label_1.set_padding(0,0);
1097         chan_count_label_1.set_line_wrap(false);
1098
1099         chan_count_label_3.set_alignment(0,0.5);
1100         chan_count_label_3.set_padding(0,0);
1101         chan_count_label_3.set_line_wrap(false);
1102
1103         chan_count_label_4.set_alignment(0,0.5);
1104         chan_count_label_4.set_padding(0,0);
1105         chan_count_label_4.set_line_wrap(false);
1106
1107         bus_label.set_markup (_("<b>Busses</b>"));
1108         input_label.set_markup (_("<b>Inputs</b>"));
1109         output_label.set_markup (_("<b>Outputs</b>"));
1110
1111         _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
1112         _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1113         _master_bus_channel_count.set_numeric(true);
1114         _master_bus_channel_count.set_digits(0);
1115         _master_bus_channel_count.set_wrap(false);
1116
1117         _create_master_bus.set_label (_("Create master bus"));
1118         _create_master_bus.set_flags(Gtk::CAN_FOCUS);
1119         _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
1120         _create_master_bus.set_mode(true);
1121         _create_master_bus.set_active(true);
1122         _create_master_bus.set_border_width(0);
1123
1124         advanced_table.set_row_spacings(0);
1125         advanced_table.set_col_spacings(0);
1126
1127         _connect_inputs.set_label (_("Automatically connect to physical_inputs"));
1128         _connect_inputs.set_flags(Gtk::CAN_FOCUS);
1129         _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
1130         _connect_inputs.set_mode(true);
1131         _connect_inputs.set_active(Config->get_input_auto_connect() != ManualConnect);
1132         _connect_inputs.set_border_width(0);
1133
1134         _limit_input_ports.set_label (_("Use only"));
1135         _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
1136         _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
1137         _limit_input_ports.set_mode(true);
1138         _limit_input_ports.set_sensitive(true);
1139         _limit_input_ports.set_border_width(0);
1140
1141         _input_limit_count.set_flags(Gtk::CAN_FOCUS);
1142         _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1143         _input_limit_count.set_numeric(true);
1144         _input_limit_count.set_digits(0);
1145         _input_limit_count.set_wrap(false);
1146         _input_limit_count.set_sensitive(false);
1147
1148         bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
1149
1150         bus_label.set_alignment(0, 0.5);
1151         bus_label.set_padding(0,0);
1152         bus_label.set_line_wrap(false);
1153         bus_label.set_selectable(false);
1154         bus_label.set_use_markup(true);
1155         bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
1156         bus_frame.set_label_align(0,0.5);
1157         bus_frame.add(bus_hbox);
1158         bus_frame.set_label_widget(bus_label);
1159
1160         bus_table.set_row_spacings (0);
1161         bus_table.set_col_spacings (0);
1162         bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1163         bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1164         bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
1165
1166         input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
1167         input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
1168         input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
1169         input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
1170         input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
1171         input_table.set_row_spacings(0);
1172         input_table.set_col_spacings(0);
1173         input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
1174
1175         input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
1176
1177         input_label.set_alignment(0, 0.5);
1178         input_label.set_padding(0,0);
1179         input_label.set_line_wrap(false);
1180         input_label.set_selectable(false);
1181         input_label.set_use_markup(true);
1182         input_frame.set_shadow_type(Gtk::SHADOW_NONE);
1183         input_frame.set_label_align(0,0.5);
1184         input_frame.add(input_hbox);
1185         input_frame.set_label_widget(input_label);
1186
1187         _connect_outputs.set_label (_("Automatically connect outputs"));
1188         _connect_outputs.set_flags(Gtk::CAN_FOCUS);
1189         _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
1190         _connect_outputs.set_mode(true);
1191         _connect_outputs.set_active(Config->get_output_auto_connect() != ManualConnect);
1192         _connect_outputs.set_border_width(0);
1193         _limit_output_ports.set_label (_("Use only"));
1194         _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
1195         _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
1196         _limit_output_ports.set_mode(true);
1197         _limit_output_ports.set_sensitive(true);
1198         _limit_output_ports.set_border_width(0);
1199         _output_limit_count.set_flags(Gtk::CAN_FOCUS);
1200         _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1201         _output_limit_count.set_numeric(false);
1202         _output_limit_count.set_digits(0);
1203         _output_limit_count.set_wrap(false);
1204         _output_limit_count.set_sensitive(false);
1205         output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
1206         output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
1207         output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
1208
1209         _connect_outputs_to_master.set_label (_("... to master bus"));
1210         _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
1211         _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
1212         _connect_outputs_to_master.set_mode(true);
1213         _connect_outputs_to_master.set_active(Config->get_output_auto_connect() == AutoConnectMaster);
1214         _connect_outputs_to_master.set_border_width(0);
1215
1216         _connect_outputs_to_master.set_group (connect_outputs_group);
1217         _connect_outputs_to_physical.set_group (connect_outputs_group);
1218
1219         _connect_outputs_to_physical.set_label (_("... to physical outputs"));
1220         _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
1221         _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
1222         _connect_outputs_to_physical.set_mode(true);
1223         _connect_outputs_to_physical.set_active(Config->get_output_auto_connect() == AutoConnectPhysical);
1224         _connect_outputs_to_physical.set_border_width(0);
1225
1226         output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
1227         output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
1228         output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
1229         output_vbox.set_border_width(6);
1230
1231         output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
1232
1233         output_vbox.pack_start(output_conn_vbox);
1234         output_vbox.pack_start(output_port_vbox);
1235
1236         output_label.set_alignment(0, 0.5);
1237         output_label.set_padding(0,0);
1238         output_label.set_line_wrap(false);
1239         output_label.set_selectable(false);
1240         output_label.set_use_markup(true);
1241         output_frame.set_shadow_type(Gtk::SHADOW_NONE);
1242         output_frame.set_label_align(0,0.5);
1243
1244         output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
1245
1246         output_frame.add(output_hbox);
1247         output_frame.set_label_widget(output_label);
1248
1249         more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
1250         more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
1251         more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
1252         more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
1253
1254         /* signals */
1255
1256         _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
1257         _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
1258         _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
1259         _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
1260         _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
1261
1262         /* note that more_options_vbox is NOT visible by
1263          * default. this is entirely by design - this page
1264          * should be skipped unless explicitly requested.
1265          */
1266
1267         session_options_page_index = append_page (more_options_vbox);
1268         set_page_title (more_options_vbox, _("Advanced Session Options"));
1269         set_page_complete (more_options_vbox, true);
1270 }
1271
1272 bool
1273 ArdourStartup::create_master_bus() const
1274 {
1275         return _create_master_bus.get_active();
1276 }
1277
1278 int
1279 ArdourStartup::master_channel_count() const
1280 {
1281         return _master_bus_channel_count.get_value_as_int();
1282 }
1283
1284 bool
1285 ArdourStartup::connect_inputs() const
1286 {
1287         return _connect_inputs.get_active();
1288 }
1289
1290 bool
1291 ArdourStartup::limit_inputs_used_for_connection() const
1292 {
1293         return _limit_input_ports.get_active();
1294 }
1295
1296 int
1297 ArdourStartup::input_limit_count() const
1298 {
1299         return _input_limit_count.get_value_as_int();
1300 }
1301
1302 bool
1303 ArdourStartup::connect_outputs() const
1304 {
1305         return _connect_outputs.get_active();
1306 }
1307
1308 bool
1309 ArdourStartup::limit_outputs_used_for_connection() const
1310 {
1311         return _limit_output_ports.get_active();
1312 }
1313
1314 int
1315 ArdourStartup::output_limit_count() const
1316 {
1317         return _output_limit_count.get_value_as_int();
1318 }
1319
1320 bool
1321 ArdourStartup::connect_outs_to_master() const
1322 {
1323         return _connect_outputs_to_master.get_active();
1324 }
1325
1326 bool
1327 ArdourStartup::connect_outs_to_physical() const
1328 {
1329         return _connect_outputs_to_physical.get_active();
1330 }
1331
1332 void
1333 ArdourStartup::connect_inputs_clicked ()
1334 {
1335         _limit_input_ports.set_sensitive(_connect_inputs.get_active());
1336
1337         if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
1338                 _input_limit_count.set_sensitive(true);
1339         } else {
1340                 _input_limit_count.set_sensitive(false);
1341         }
1342 }
1343
1344 void
1345 ArdourStartup::connect_outputs_clicked ()
1346 {
1347         _limit_output_ports.set_sensitive(_connect_outputs.get_active());
1348
1349         if (_connect_outputs.get_active() && _limit_output_ports.get_active()) {
1350                 _output_limit_count.set_sensitive(true);
1351         } else {
1352                 _output_limit_count.set_sensitive(false);
1353         }
1354 }
1355
1356 void
1357 ArdourStartup::limit_inputs_clicked ()
1358 {
1359         _input_limit_count.set_sensitive(_limit_input_ports.get_active());
1360 }
1361
1362 void
1363 ArdourStartup::limit_outputs_clicked ()
1364 {
1365         _output_limit_count.set_sensitive(_limit_output_ports.get_active());
1366 }
1367
1368 void
1369 ArdourStartup::master_bus_button_clicked ()
1370 {
1371         bool yn = _create_master_bus.get_active();
1372
1373         _master_bus_channel_count.set_sensitive(yn);
1374 }
1375
1376 void
1377 ArdourStartup::move_along_now ()
1378 {
1379         gint cur = get_current_page ();
1380
1381         if (cur == session_page_index) {
1382                 if (more_new_session_options_button.get_active()) {
1383                         set_current_page (session_options_page_index);
1384                 } else {
1385                         on_apply ();
1386                 }
1387         }
1388 }
1389
1390 void
1391 ArdourStartup::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
1392 {
1393         set_page_complete (session_vbox, true);
1394         move_along_now ();
1395 }
1396
1397 void
1398 ArdourStartup::existing_session_selected ()
1399 {
1400         _existing_session_chooser_used = true;
1401
1402         set_page_complete (session_vbox, true);
1403         move_along_now ();
1404 }
1405
1406 sys::path
1407 ArdourStartup::been_here_before_path () const
1408 {
1409         sys::path b = user_config_directory();
1410         b /= ".a3"; // XXXX use more specific version so we can catch upgrades
1411         return b;
1412 }
1413