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