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