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