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