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