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