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