266a7e2a278c0d5146f287afc6fd75be02e26ec4
[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 #include "pbd/openuri.h"
36
37 #include "ardour/audioengine.h"
38 #include "ardour/filesystem_paths.h"
39 #include "ardour/recent_sessions.h"
40 #include "ardour/session.h"
41 #include "ardour/session_state_utils.h"
42 #include "ardour/template_utils.h"
43 #include "ardour/filename_extensions.h"
44
45 #include "ardour_ui.h"
46 #include "startup.h"
47 #include "opts.h"
48 #include "engine_dialog.h"
49 #include "i18n.h"
50 #include "utils.h"
51
52 using namespace std;
53 using namespace Gtk;
54 using namespace Gdk;
55 using namespace Glib;
56 using namespace PBD;
57 using namespace ARDOUR;
58
59 ArdourStartup* ArdourStartup::the_startup = 0;
60
61 static string poor_mans_glob (string path)
62 {
63         string copy = path;
64         replace_all (copy, "~", Glib::get_home_dir());
65         return copy;
66 }
67
68 ArdourStartup::ArdourStartup (bool require_new, const std::string& session_name, const std::string& session_path, const std::string& template_name)
69         : _response (RESPONSE_OK)
70         , config_modified (false)
71         , new_only (require_new)
72         , default_dir_chooser (0)
73         , ic_new_session_button (_("Create a new session"))
74         , ic_existing_session_button (_("Open an existing session"))
75         , monitor_via_hardware_button (string_compose (_("Use an external mixer or the hardware mixer of your audio interface.\n"
76                                                          "%1 will play NO role in monitoring"), PROGRAM_NAME))
77         , monitor_via_ardour_button (string_compose (_("Ask %1 to play back material as it is being recorded"), PROGRAM_NAME))
78         , new_folder_chooser (FILE_CHOOSER_ACTION_SELECT_FOLDER)
79         , more_new_session_options_button (_("I'd like more options for this session"))
80         , _output_limit_count_adj (1, 0, 100, 1, 10, 0)
81         , _input_limit_count_adj (1, 0, 100, 1, 10, 0)
82         , _master_bus_channel_count_adj (2, 0, 100, 1, 10, 0)
83         , audio_page_index (-1)
84         , new_user_page_index (-1)
85         , default_folder_page_index (-1)
86         , monitoring_page_index (-1)
87         , session_page_index (-1)
88         , initial_choice_index (-1)
89         , final_page_index (-1)
90         , session_options_page_index (-1)
91         , _existing_session_chooser_used (false)
92 {
93         new_user = !Glib::file_test (been_here_before_path(), Glib::FILE_TEST_EXISTS);
94         need_session_info = (session_name.empty() || require_new);
95
96         _provided_session_name = session_name;
97         _provided_session_path = session_path;
98         
99         if (need_session_info || new_user) {
100
101                 use_template_button.set_group (session_template_group);
102                 use_session_as_template_button.set_group (session_template_group);
103                 
104                 set_keep_above (true);
105                 set_position (WIN_POS_CENTER);
106                 set_border_width (12);
107                 
108                 if ((icon_pixbuf = ::get_icon ("ardour_icon_48px")) == 0) {
109                         throw failed_constructor();
110                 }
111                 
112                 list<Glib::RefPtr<Gdk::Pixbuf> > window_icons;
113                 Glib::RefPtr<Gdk::Pixbuf> icon;
114                 
115                 if ((icon = ::get_icon ("ardour_icon_16px")) != 0) {
116                         window_icons.push_back (icon);
117                 }
118                 if ((icon = ::get_icon ("ardour_icon_22px")) != 0) {
119                         window_icons.push_back (icon);
120                 }
121                 if ((icon = ::get_icon ("ardour_icon_32px")) != 0) {
122                         window_icons.push_back (icon);
123                 }
124                 if ((icon = ::get_icon ("ardour_icon_48px")) != 0) {
125                         window_icons.push_back (icon);
126                 }
127                 if (!window_icons.empty ()) {
128                         set_default_icon_list (window_icons);
129                 }
130
131 #ifdef __APPLE__
132                 setup_prerelease_page ();
133 #endif
134                 if (new_user) {
135                         
136                         setup_new_user_page ();
137                         setup_first_time_config_page ();
138                         setup_monitoring_choice_page ();
139                         setup_monitor_section_choice_page ();
140                         
141                         ic_new_session_button.set_active (true); // always create new session on first run
142                         
143                 } else {
144                         
145                         setup_initial_choice_page ();
146                 }
147
148                 setup_session_page ();
149                 setup_more_options_page ();
150                 
151                 if (new_user) {
152                         setup_final_page ();
153                 }
154
155                 if (new_only) {
156                         ic_vbox.hide ();
157                 } else {
158                         ic_vbox.show ();
159                 }
160
161                 if (!template_name.empty()) {
162                         use_template_button.set_active (false);
163                         load_template_override = template_name;
164                 }
165         }
166
167         the_startup = this;
168 }
169
170 ArdourStartup::~ArdourStartup ()
171 {
172 }
173
174 bool
175 ArdourStartup::ready_without_display () const
176 {
177         return !new_user && !need_session_info;
178 }
179
180 void
181 ArdourStartup::setup_prerelease_page ()
182 {
183         VBox* vbox = manage (new VBox);
184         Label* label = manage (new Label);
185         label->set_markup (string_compose (_("<b>Welcome to this BETA release of Ardour %1</b>\n\n\
186 Ardour %1 has been released for Linux but because of the lack of testers,\n\
187 it is still at the beta stage on OS X. So, a few guidelines:\n\
188 \n\
189 1) Please do <b>NOT</b> use this software with the expectation that it is stable or reliable\n\
190    though it may be so, depending on your workflow.\n\
191 2) <b>Please do NOT use the forums at ardour.org to report issues</b>.\n\
192 3) Please <b>DO</b> use the bugtracker at http://tracker.ardour.org/ to report issues\n\
193    making sure to note the product version number as %1-beta.\n\
194 4) Please <b>DO</b> use the ardour-users mailing list to discuss ideas and pass on comments.\n\
195 5) Please <b>DO</b> join us on IRC for real time discussions about ardour3. You\n\
196    can get there directly from Ardour via the Help->Chat menu option.\n\
197 \n\
198 Full information on all the above can be found on the support page at\n\
199 \n\
200                 http://ardour.org/support\n\
201 "), VERSIONSTRING));
202
203         vbox->set_border_width (12);
204         vbox->pack_start (*label, false, false, 12);
205         vbox->show_all ();
206         
207         append_page (*vbox);
208         set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
209         set_page_title (*vbox, _("This is a BETA RELEASE"));
210         set_page_complete (*vbox, true);
211 }
212
213 bool
214 ArdourStartup::use_session_template ()
215 {
216         if (!load_template_override.empty()) {
217                 return true;
218         }
219
220         if (use_template_button.get_active()) {
221                 return template_chooser.get_active_row_number() > 0;
222         } else {
223                 return !session_template_chooser.get_filename().empty();
224         }
225 }
226
227 std::string
228 ArdourStartup::session_template_name ()
229 {
230         if (!load_template_override.empty()) {
231                 string the_path (ARDOUR::user_template_directory());
232                 return Glib::build_filename (the_path, load_template_override + ARDOUR::template_suffix);
233         }
234
235         if (ic_existing_session_button.get_active()) {
236                 return string();
237         }
238
239         if (use_template_button.get_active()) {
240                 TreeModel::iterator iter = template_chooser.get_active ();
241                 TreeModel::Row row = (*iter);
242                 string s = row[session_template_columns.path];
243                 return s;
244         } else {
245                 return session_template_chooser.get_filename();
246
247         }
248 }
249
250 std::string
251 ArdourStartup::session_name (bool& should_be_new)
252 {
253         if (ready_without_display()) {
254                 return _provided_session_name;
255         }
256
257         if (ic_new_session_button.get_active()) {
258                 should_be_new = true;
259                 string val = new_name_entry.get_text ();
260                 strip_whitespace_edges (val);
261                 return val;
262         } else if (_existing_session_chooser_used) {
263                 /* existing session chosen from file chooser */
264                 should_be_new = false;
265                 return existing_session_chooser.get_filename ();
266         } else {
267                 /* existing session chosen from recent list */
268                 should_be_new = false;
269
270                 TreeIter iter = recent_session_display.get_selection()->get_selected();
271
272                 if (iter) {
273                         return (*iter)[recent_session_columns.visible_name];
274                 }
275
276                 return "";
277         }
278 }
279
280 std::string
281 ArdourStartup::session_folder ()
282 {
283         if (ready_without_display()) {
284                 return _provided_session_path;
285         }
286
287         if (ic_new_session_button.get_active()) {
288                 std::string legal_session_folder_name = legalize_for_path (new_name_entry.get_text());
289                 return Glib::build_filename (new_folder_chooser.get_current_folder(), legal_session_folder_name);
290         } else if (_existing_session_chooser_used) {
291                 /* existing session chosen from file chooser */
292                 return existing_session_chooser.get_current_folder ();
293         } else {
294                 /* existing session chosen from recent list */
295                 TreeIter iter = recent_session_display.get_selection()->get_selected();
296
297                 if (iter) {
298                         return (*iter)[recent_session_columns.fullpath];
299                 }
300                 return "";
301         }
302 }
303
304 void
305 ArdourStartup::setup_new_user_page ()
306 {
307         Label* foomatic = manage (new Label);
308
309         foomatic->set_markup (string_compose (_("\
310 <span size=\"larger\">%1 is a digital audio workstation. You can use it to \
311 record, edit and mix multi-track audio. You can produce your \
312 own CDs, mix video soundtracks, or experiment with new \
313 ideas about music and sound. \
314 \n\n\
315 There are a few things that need to be configured before you start \
316 using the program.</span> \
317 "), PROGRAM_NAME));
318         foomatic->set_justify (JUSTIFY_FILL);
319         foomatic->set_line_wrap ();
320
321         HBox* hbox = manage (new HBox);
322         HBox* vbox = manage (new HBox);
323
324         vbox->set_border_width (24);
325
326         hbox->pack_start (*foomatic, true, true);
327         vbox->pack_start (*hbox, true, true);
328
329         foomatic->show ();
330         hbox->show ();
331         vbox->show ();
332
333         new_user_page_index = append_page (*vbox);
334         set_page_type (*vbox, ASSISTANT_PAGE_INTRO);
335         set_page_title (*vbox, string_compose (_("Welcome to %1"), PROGRAM_NAME));
336         set_page_header_image (*vbox, icon_pixbuf);
337         set_page_complete (*vbox, true);
338 }
339
340 void
341 ArdourStartup::default_dir_changed ()
342 {
343         Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
344         // make new session folder chooser point to the new default
345         new_folder_chooser.set_current_folder (Config->get_default_session_parent_dir());       
346         config_changed ();
347 }
348
349 void
350 ArdourStartup::config_changed ()
351 {
352         config_modified = true;
353 }
354
355 void
356 ArdourStartup::setup_first_time_config_page ()
357 {
358         default_dir_chooser = manage (new FileChooserButton (string_compose (_("Default folder for %1 sessions"), PROGRAM_NAME),
359                                                              FILE_CHOOSER_ACTION_SELECT_FOLDER));
360         Gtk::Label* txt = manage (new Label);
361         HBox* hbox = manage (new HBox);
362         VBox* vbox = manage (new VBox);
363
364         txt->set_markup (string_compose (_("\
365 Each project that you work on with %1 has its own folder.\n\
366 These can require a lot of disk space if you are recording audio.\n\
367 \n\
368 Where would you like new %1 sessions to be stored by default?\n\n\
369 <i>(You can put new sessions anywhere, this is just a default)</i>"), PROGRAM_NAME));
370         txt->set_alignment (0.0, 0.0);
371
372         vbox->set_spacing (18);
373         vbox->set_border_width (24);
374
375         hbox->pack_start (*default_dir_chooser, false, true, 8);
376         vbox->pack_start (*txt, false, false);
377         vbox->pack_start (*hbox, false, true);
378
379         default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
380         default_dir_chooser->signal_current_folder_changed().connect (sigc::mem_fun (*this, &ArdourStartup::default_dir_changed));
381         default_dir_chooser->show ();
382
383         vbox->show_all ();
384
385         default_folder_page_index = append_page (*vbox);
386         set_page_title (*vbox, _("Default folder for new sessions"));
387         set_page_header_image (*vbox, icon_pixbuf);
388         set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
389
390         /* user can just skip all these settings if they want to */
391
392         set_page_complete (*vbox, true);
393 }
394
395 void
396 ArdourStartup::setup_monitoring_choice_page ()
397 {
398         mon_vbox.set_spacing (18);
399         mon_vbox.set_border_width (24);
400
401         HBox* hbox = manage (new HBox);
402         VBox* vbox = manage (new VBox);
403         /* first button will be on by default */
404         RadioButton::Group g (monitor_via_ardour_button.get_group());
405         monitor_via_hardware_button.set_group (g);
406
407         monitor_label.set_markup(_("\
408 While recording instruments or vocals, you probably want to listen to the\n\
409 signal as well as record it. This is called \"monitoring\". There are\n\
410 different ways to do this depending on the equipment you have and the\n\
411 configuration of that equipment. The two most common are presented here.\n\
412 Please choose whichever one is right for your setup.\n\n\
413 <i>(You can change this preference at any time, via the Preferences dialog)</i>\n\n\
414 <i>If you do not understand what this is about, just accept the default.</i>"));
415         monitor_label.set_alignment (0.0, 0.0);
416
417         vbox->set_spacing (6);
418
419         vbox->pack_start (monitor_via_hardware_button, false, true);
420         vbox->pack_start (monitor_via_ardour_button, false, true);
421         hbox->pack_start (*vbox, true, true, 8);
422         mon_vbox.pack_start (monitor_label, false, false);
423         mon_vbox.pack_start (*hbox, false, false);
424
425         mon_vbox.show_all ();
426
427         monitoring_page_index = append_page (mon_vbox);
428         set_page_title (mon_vbox, _("Monitoring Choices"));
429         set_page_header_image (mon_vbox, icon_pixbuf);
430
431         /* user could just click on "Forward" if default
432          * choice is correct.
433          */
434
435         set_page_complete (mon_vbox, true);
436 }
437
438 void
439 ArdourStartup::setup_monitor_section_choice_page ()
440 {
441         mon_sec_vbox.set_spacing (18);
442         mon_sec_vbox.set_border_width (24);
443
444         HBox* hbox = manage (new HBox);
445         VBox* main_vbox = manage (new VBox);
446         VBox* vbox;
447         Label* l = manage (new Label);
448
449         main_vbox->set_spacing (32);
450
451         no_monitor_section_button.set_label (_("Use a Master bus directly"));
452         l->set_alignment (0.0, 1.0);
453         l->set_markup(_("Connect the Master bus directly to your hardware outputs. This is preferable for simple usage."));
454
455         vbox = manage (new VBox);
456         vbox->set_spacing (6);
457         vbox->pack_start (no_monitor_section_button, false, true);
458         vbox->pack_start (*l, false, true);
459
460         main_vbox->pack_start (*vbox, false, false);
461
462         use_monitor_section_button.set_label (_("Use an additional Monitor bus"));
463         l = manage (new Label);
464         l->set_alignment (0.0, 1.0);
465         l->set_text (_("Use a Monitor bus between Master bus and hardware outputs for \n\
466 greater control in monitoring without affecting the mix."));
467
468         vbox = manage (new VBox);
469         vbox->set_spacing (6);
470         vbox->pack_start (use_monitor_section_button, false, true);
471         vbox->pack_start (*l, false, true);
472
473         main_vbox->pack_start (*vbox, false, false);
474
475         RadioButton::Group g (use_monitor_section_button.get_group());
476         no_monitor_section_button.set_group (g);
477
478         if (Config->get_use_monitor_bus()) {
479                 use_monitor_section_button.set_active (true);
480         } else {
481                 no_monitor_section_button.set_active (true);
482         }
483
484         use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
485         no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
486
487         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\
488 <i>If you do not understand what this is about, just accept the default.</i>"));
489         monitor_section_label.set_alignment (0.0, 0.0);
490
491         hbox->pack_start (*main_vbox, true, true, 8);
492         mon_sec_vbox.pack_start (*hbox, false, false);
493         mon_sec_vbox.pack_start (monitor_section_label, false, false);
494
495         mon_sec_vbox.show_all ();
496
497         monitor_section_page_index = append_page (mon_sec_vbox);
498         set_page_title (mon_sec_vbox, _("Monitor Section"));
499         set_page_header_image (mon_sec_vbox, icon_pixbuf);
500
501         /* user could just click on "Forward" if default
502          * choice is correct.
503          */
504
505         set_page_complete (mon_sec_vbox, true);
506 }
507
508 void
509 ArdourStartup::setup_initial_choice_page ()
510 {
511         ic_vbox.set_spacing (6);
512         ic_vbox.set_border_width (24);
513
514         RadioButton::Group g (ic_new_session_button.get_group());
515         ic_existing_session_button.set_group (g);
516
517         HBox* centering_hbox = manage (new HBox);
518         VBox* centering_vbox = manage (new VBox);
519
520         centering_vbox->set_spacing (6);
521
522         centering_vbox->pack_start (ic_new_session_button, false, true);
523         centering_vbox->pack_start (ic_existing_session_button, false, true);
524         
525         if (ARDOUR_UI::instance()->announce_string() != "" ) {
526
527                 Gtk::Frame *info_frame = manage(new Gtk::Frame);
528                 info_frame->set_shadow_type(SHADOW_ETCHED_OUT);
529                 centering_vbox->pack_start (*info_frame, false, false, 20);
530
531                 Box *info_box = manage (new VBox);
532                 info_box->set_border_width (12);
533                 info_box->set_spacing (6);
534                 info_box->set_name("mixbus_info_box");
535
536                 info_box->pack_start (info_scroller_label, false, false);
537
538                 info_frame->add (*info_box);
539                 info_frame->show_all();
540
541                 info_scroller_count = 0;
542                 info_scroller_connection = Glib::signal_timeout().connect (mem_fun(*this, &ArdourStartup::info_scroller_update), 50);
543
544                 Gtk::Button *updates_button = manage (new Gtk::Button (_("Check the website for more...")));
545
546                 updates_button->signal_clicked().connect (mem_fun(*this, &ArdourStartup::updates_button_clicked) );
547                 ARDOUR_UI::instance()->tooltips().set_tip (*updates_button, _("Click to open the program website in your web browser"));
548
549                 info_box->pack_start (*updates_button, false, false);
550         }
551         
552         ic_new_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
553         ic_new_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
554
555         ic_existing_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
556         ic_existing_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
557
558         centering_hbox->pack_start (*centering_vbox, true, true);
559
560         ic_vbox.pack_start (*centering_hbox, true, true);
561
562         ic_vbox.show_all ();
563
564         initial_choice_index = append_page (ic_vbox);
565         set_page_title (ic_vbox, string_compose("%1 %2", PROGRAM_NAME, VERSIONSTRING));
566         set_page_header_image (ic_vbox, icon_pixbuf);
567
568         /* user could just click on "Forward" if default
569          * choice is correct.
570          */
571
572         set_page_complete (ic_vbox, true);
573 }
574
575 bool
576 ArdourStartup::initial_button_clicked (GdkEventButton* ev)
577 {
578         if (ev->type == GDK_2BUTTON_PRESS && session_page_index != -1) {
579                 set_current_page(session_page_index);
580         }
581
582         return false;
583 }
584
585 void
586 ArdourStartup::initial_button_activated ()
587 {
588         if (session_page_index != -1) {
589                 set_current_page(session_page_index);
590         }
591 }
592
593 void
594 ArdourStartup::setup_session_page ()
595 {
596         session_vbox.set_border_width (24);
597
598         session_vbox.pack_start (session_hbox, true, true);
599         session_vbox.show_all ();
600
601         session_page_index = append_page (session_vbox);
602         /* initial setting */
603         set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
604 }
605
606 void
607 ArdourStartup::setup_final_page ()
608 {
609         final_page.set_text (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
610         final_page.show ();
611         final_page_index = append_page (final_page);
612         set_page_complete (final_page, true);
613         set_page_header_image (final_page, icon_pixbuf);
614         set_page_type (final_page, ASSISTANT_PAGE_CONFIRM);
615 }
616
617 void
618 ArdourStartup::on_cancel ()
619 {
620         _response = RESPONSE_CANCEL;
621         gtk_main_quit ();
622 }
623
624 bool
625 ArdourStartup::on_delete_event (GdkEventAny*)
626 {
627         _response = RESPONSE_CLOSE;
628         gtk_main_quit ();
629         return true;
630 }
631
632 void
633 ArdourStartup::on_apply ()
634 {
635         if (config_modified) {
636
637                 if (default_dir_chooser) {
638                         Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
639                 }
640
641                 if (monitor_via_hardware_button.get_active()) {
642                         Config->set_monitoring_model (ExternalMonitoring);
643                 } else if (monitor_via_ardour_button.get_active()) {
644                         Config->set_monitoring_model (SoftwareMonitoring);
645                 }
646
647                 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
648
649                 Config->save_state ();
650
651         }
652
653         {
654                 /* "touch" the been-here-before path now we've successfully
655                    made it through the first time setup (at least)
656                 */
657                 ofstream fout (been_here_before_path().c_str());
658
659         }
660                 
661         _response = RESPONSE_OK;
662         gtk_main_quit ();
663 }
664
665 void
666 ArdourStartup::on_prepare (Gtk::Widget* page)
667 {
668         if (page == &session_vbox) {
669
670                 if (ic_new_session_button.get_active()) {
671                         /* new session requested */
672                         setup_new_session_page ();
673                 } else {
674                         /* existing session requested */
675                         setup_existing_session_page ();
676
677                 }
678
679                 /* HACK HACK HACK ... change the "Apply" button label
680                    to say "Open"
681                 */
682
683                 Gtk::Widget* tl = session_vbox.get_toplevel();
684                 Gtk::Window* win;
685                 if ((win = dynamic_cast<Gtk::Window*>(tl)) != 0) {
686                         /* ::get_default_widget() is not wrapped in gtkmm */
687                         Gtk::Widget* def = wrap (gtk_window_get_default_widget (win->gobj()));
688                         Gtk::Button* button;
689                         if ((button = dynamic_cast<Gtk::Button*>(def)) != 0) {
690                                 if (more_new_session_options_button.get_active()) {
691                                         button->set_label (_("Forward"));
692                                 }else{
693                                         button->set_label (_("Open"));
694                                 }
695                         }
696                 }
697         }
698 }
699
700 void
701 ArdourStartup::populate_session_templates ()
702 {
703         vector<TemplateInfo> templates;
704
705         find_session_templates (templates);
706
707         template_model->clear ();
708
709         for (vector<TemplateInfo>::iterator x = templates.begin(); x != templates.end(); ++x) {
710                 TreeModel::Row row;
711
712                 row = *(template_model->append ());
713
714                 row[session_template_columns.name] = (*x).name;
715                 row[session_template_columns.path] = (*x).path;
716         }
717 }
718
719 void
720 ArdourStartup::setup_new_session_page ()
721 {
722         if (!session_hbox.get_children().empty()) {
723                 session_hbox.remove (**session_hbox.get_children().begin());
724         }
725
726         session_new_vbox.set_spacing (18);
727
728         if (session_new_vbox.get_children().empty()) {
729                 VBox *vbox1 = manage (new VBox);
730                 HBox* hbox1 = manage (new HBox);
731                 Label* label1 = manage (new Label);
732
733                 vbox1->set_spacing (6);
734
735                 hbox1->set_spacing (6);
736                 hbox1->pack_start (*label1, false, false);
737                 hbox1->pack_start (new_name_entry, true, true);
738
739                 label1->set_text (_("Session name:"));
740
741
742                 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
743                         new_name_entry.set_text  (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
744                         /* name provided - they can move right along */
745                         set_page_complete (session_vbox, true);
746                 }
747
748                 new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_changed));
749                 new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &ArdourStartup::move_along_now));
750
751                 vbox1->pack_start (*hbox1, true, true);
752
753                 /* --- */
754
755                 HBox* hbox2 = manage (new HBox);
756                 Label* label2 = manage (new Label);
757
758                 hbox2->set_spacing (6);
759                 hbox2->pack_start (*label2, false, false);
760                 hbox2->pack_start (new_folder_chooser, true, true);
761
762                 label2->set_text (_("Create session folder in:"));
763
764                 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
765                         new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
766                 } else if (ARDOUR_UI::instance()->session_loaded) {
767                         // point the new session file chooser at the parent directory of the current session
768                         string session_parent_dir = Glib::path_get_dirname(ARDOUR_UI::instance()->the_session()->path());
769                         string::size_type last_dir_sep = session_parent_dir.rfind(G_DIR_SEPARATOR);
770                         session_parent_dir = session_parent_dir.substr(0, last_dir_sep);
771                         new_folder_chooser.set_current_folder (session_parent_dir);
772                         string default_session_folder = poor_mans_glob (Config->get_default_session_parent_dir());
773
774                         try {
775                                 /* add_shortcut_folder throws an exception if the folder being added already has a shortcut */
776                                 new_folder_chooser.add_shortcut_folder (default_session_folder);
777                         }
778                         catch (Glib::Error & e) {
779                                 std::cerr << "new_folder_chooser.add_shortcut_folder (" << default_session_folder << ") threw Glib::Error " << e.what() << std::endl;
780                         }
781                 } else {
782                         new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
783                 }
784                 new_folder_chooser.show ();
785                 new_folder_chooser.set_title (_("Select folder for session"));
786
787 #ifdef __APPLE__
788                 new_folder_chooser.add_shortcut_folder ("/Volumes");
789 #endif
790
791                 vbox1->pack_start (*hbox2, false, false);
792                 
793                 session_new_vbox.pack_start (*vbox1, false, false);
794
795                 /* --- */
796
797                 VBox *vbox2 = manage (new VBox);
798                 HBox* hbox3 = manage (new HBox);
799                 Label* label3 = manage (new Label);
800                 template_model = ListStore::create (session_template_columns);
801                 populate_session_templates ();
802
803                 vbox2->set_spacing (6);
804
805                 label3->set_markup (_("<b>Options</b>"));
806                 label3->set_alignment (0.0, 0.0);
807
808                 vbox2->pack_start (*label3, false, true);
809
810                 VBox *vbox3 = manage (new VBox);
811
812                 vbox3->set_spacing (6);
813
814                 if (!template_model->children().empty()) {
815
816                         HBox* hbox4a = manage (new HBox);
817                         use_template_button.set_label (_("Use this template"));
818
819                         TreeModel::Row row = *template_model->prepend ();
820                         row[session_template_columns.name] = (_("no template"));
821                         row[session_template_columns.path] = string();
822
823                         hbox4a->set_spacing (6);
824                         hbox4a->pack_start (use_template_button, false, false);
825                         hbox4a->pack_start (template_chooser, true, true);
826
827                         template_chooser.set_model (template_model);
828
829                         Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
830                         text_renderer->property_editable() = false;
831
832                         template_chooser.pack_start (*text_renderer);
833                         template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
834                         template_chooser.set_active (0);
835
836                         use_template_button.show();
837                         template_chooser.show ();
838
839                         vbox3->pack_start (*hbox4a, false, false);
840                 }
841
842                 /* --- */
843
844                 if (!new_user) {
845                         session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
846
847                         HBox* hbox4b = manage (new HBox);
848                         use_session_as_template_button.set_label (_("Use an existing session as a template:"));
849
850                         hbox4b->set_spacing (6);
851                         hbox4b->pack_start (use_session_as_template_button, false, false);
852                         hbox4b->pack_start (session_template_chooser, true, true);
853
854                         use_session_as_template_button.show ();
855                         session_template_chooser.show ();
856
857                         Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
858                         session_filter->add_pattern (X_("*.ardour"));
859                         session_template_chooser.set_filter (*session_filter);
860                         session_template_chooser.set_title (_("Select template"));
861
862                         vbox3->pack_start (*hbox4b, false, false);
863                 }
864
865                 /* --- */
866
867                 HBox* hbox5 = manage (new HBox);
868
869                 hbox5->set_spacing (6);
870                 hbox5->pack_start (more_new_session_options_button, false, false);
871
872                 more_new_session_options_button.show ();
873                 more_new_session_options_button.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::more_new_session_options_button_clicked));
874
875                 vbox3->pack_start (*hbox5, false, false);
876                 hbox3->pack_start (*vbox3, true, true, 8);
877                 vbox2->pack_start (*hbox3, false, false);
878
879                 /* --- */
880
881                 session_new_vbox.pack_start (*vbox2, false, false);
882         }
883
884         session_new_vbox.show_all ();
885         session_hbox.pack_start (session_new_vbox, true, true);
886         set_page_title (session_vbox, _("New Session"));
887         set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
888
889         if (more_new_session_options_button.get_active()) {
890                 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
891         }
892         session_hbox.show_all();
893 }
894
895 void
896 ArdourStartup::new_name_changed ()
897 {
898         if (!new_name_entry.get_text().empty()) {
899                 set_page_complete (session_vbox, true);
900         } else {
901                 set_page_complete (session_vbox, false);
902         }
903 }
904
905 int
906 ArdourStartup::redisplay_recent_sessions ()
907 {
908         std::vector<std::string> session_directories;
909         RecentSessionsSorter cmp;
910
911         recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
912         recent_session_model->clear ();
913
914         ARDOUR::RecentSessions rs;
915         ARDOUR::read_recent_sessions (rs);
916
917         if (rs.empty()) {
918                 recent_session_display.set_model (recent_session_model);
919                 return 0;
920         }
921         //
922         // sort them alphabetically
923         sort (rs.begin(), rs.end(), cmp);
924
925         for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
926                 session_directories.push_back ((*i).second);
927         }
928         
929         int session_snapshot_count = 0;
930
931         for (vector<std::string>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
932         {
933                 std::vector<std::string> state_file_paths;
934
935                 // now get available states for this session
936
937                 get_state_files_in_directory (*i, state_file_paths);
938
939                 vector<string*>* states;
940                 vector<const gchar*> item;
941                 string fullpath = *i;
942
943                 /* remove any trailing / */
944
945                 if (fullpath[fullpath.length()-1] == '/') {
946                         fullpath = fullpath.substr (0, fullpath.length()-1);
947                 }
948
949                 /* check whether session still exists */
950                 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
951                         /* session doesn't exist */
952                         continue;
953                 }
954
955                 /* now get available states for this session */
956
957                 if ((states = Session::possible_states (fullpath)) == 0) {
958                         /* no state file? */
959                         continue;
960                 }
961
962                 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
963
964                 Gtk::TreeModel::Row row = *(recent_session_model->append());
965
966                 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
967                 row[recent_session_columns.fullpath] = fullpath;
968                 row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
969                 
970                 ++session_snapshot_count;
971
972                 if (state_file_names.size() > 1) {
973
974                         // add the children
975
976                         for (std::vector<std::string>::iterator i2 = state_file_names.begin();
977                                         i2 != state_file_names.end(); ++i2) {
978
979                                 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
980
981                                 child_row[recent_session_columns.visible_name] = *i2;
982                                 child_row[recent_session_columns.fullpath] = fullpath;
983                                 child_row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
984                                 ++session_snapshot_count;
985                         }
986                 }
987         }
988
989         recent_session_display.set_tooltip_column(1); // recent_session_columns.tip 
990         recent_session_display.set_model (recent_session_model);
991         return session_snapshot_count;
992         // return rs.size();
993 }
994
995 void
996 ArdourStartup::recent_session_row_selected ()
997 {
998         if (recent_session_display.get_selection()->count_selected_rows() > 0) {
999                 set_page_complete (session_vbox, true);
1000         } else {
1001                 set_page_complete (session_vbox, false);
1002         }
1003 }
1004
1005 void
1006 ArdourStartup::setup_existing_session_page ()
1007 {
1008         recent_session_model = TreeStore::create (recent_session_columns);
1009         redisplay_recent_sessions ();
1010
1011         if (!session_hbox.get_children().empty()) {
1012                 session_hbox.remove (**session_hbox.get_children().begin());
1013         }
1014
1015         if (session_existing_vbox.get_children().empty()) {
1016
1017                 recent_session_display.set_model (recent_session_model);
1018                 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1019                 recent_session_display.set_headers_visible (false);
1020                 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
1021
1022                 recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::recent_session_row_selected));
1023
1024                 recent_scroller.add (recent_session_display);
1025                 recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1026                 recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
1027
1028                 recent_session_display.show();
1029
1030                 recent_scroller.show();
1031                 int cnt = redisplay_recent_sessions ();
1032                 recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ArdourStartup::recent_row_activated));
1033
1034                 if (cnt > 4) {
1035                         recent_scroller.set_size_request (-1, 300);
1036                 }
1037
1038                 session_existing_vbox.set_spacing (8);
1039                 session_existing_vbox.pack_start (recent_scroller, true, true);
1040
1041                 existing_session_chooser.set_title (_("Select session file"));
1042                 existing_session_chooser.signal_file_set().connect (sigc::mem_fun (*this, &ArdourStartup::existing_session_selected));
1043                 existing_session_chooser.set_current_folder(poor_mans_glob (Config->get_default_session_parent_dir()));
1044
1045                 FileFilter session_filter;
1046                 session_filter.add_pattern ("*.ardour");
1047                 session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
1048                 existing_session_chooser.add_filter (session_filter);
1049                 existing_session_chooser.set_filter (session_filter);
1050                 
1051 #ifdef GTKOSX
1052                 existing_session_chooser.add_shortcut_folder ("/Volumes");
1053 #endif
1054
1055                 HBox* hbox = manage (new HBox);
1056                 hbox->set_spacing (4);
1057                 hbox->pack_start (*manage (new Label (_("Browse:"))), PACK_SHRINK);
1058                 hbox->pack_start (existing_session_chooser);
1059                 session_existing_vbox.pack_start (*hbox, false, false);
1060                 hbox->show_all ();
1061         }
1062
1063         session_existing_vbox.show_all ();
1064         session_hbox.pack_start (session_existing_vbox, true, true);
1065
1066         set_page_title (session_vbox, _("Select a session"));
1067         set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1068         session_hbox.show_all();
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 }
1419
1420 void
1421 ArdourStartup::updates_button_clicked ()
1422 {
1423         //now open a browser window so user can see more
1424         PBD::open_uri (Config->get_updates_url());
1425 }
1426
1427 bool
1428 ArdourStartup::info_scroller_update()
1429 {
1430         info_scroller_count++;
1431
1432         char buf[512];
1433         snprintf (buf, std::min(info_scroller_count,sizeof(buf)-1), "%s", ARDOUR_UI::instance()->announce_string().c_str() );
1434         buf[info_scroller_count] = 0;
1435         info_scroller_label.set_text (buf);
1436         info_scroller_label.show();
1437
1438         if (info_scroller_count > ARDOUR_UI::instance()->announce_string().length()) {
1439                 info_scroller_connection.disconnect();
1440         }
1441
1442         return true;
1443 }