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