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