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