Fix some compilation warnings
[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                 Config->save_state ();
688
689         }
690
691         {
692                 /* "touch" the been-here-before path now we've successfully
693                    made it through the first time setup (at least)
694                 */
695                 ofstream fout (been_here_before_path().c_str());
696
697         }
698                 
699         _response = RESPONSE_OK;
700         gtk_main_quit ();
701 }
702
703 void
704 ArdourStartup::on_prepare (Gtk::Widget* page)
705 {
706         if (page == &session_vbox) {
707
708                 if (ic_new_session_button.get_active()) {
709                         /* new session requested */
710                         setup_new_session_page ();
711                 } else {
712                         /* existing session requested */
713                         setup_existing_session_page ();
714
715                 }
716
717                 /* HACK HACK HACK ... change the "Apply" button label
718                    to say "Open"
719                 */
720
721                 Gtk::Widget* tl = session_vbox.get_toplevel();
722                 Gtk::Window* win;
723                 if ((win = dynamic_cast<Gtk::Window*>(tl)) != 0) {
724                         /* ::get_default_widget() is not wrapped in gtkmm */
725                         Gtk::Widget* def = wrap (gtk_window_get_default_widget (win->gobj()));
726                         Gtk::Button* button;
727                         if ((button = dynamic_cast<Gtk::Button*>(def)) != 0) {
728                                 if (more_new_session_options_button.get_active()) {
729                                         button->set_label (_("Forward"));
730                                 }else{
731                                         button->set_label (_("Open"));
732                                 }
733                         }
734                 }
735         }
736 }
737
738 void
739 ArdourStartup::populate_session_templates ()
740 {
741         vector<TemplateInfo> templates;
742
743         find_session_templates (templates);
744
745         template_model->clear ();
746
747         for (vector<TemplateInfo>::iterator x = templates.begin(); x != templates.end(); ++x) {
748                 TreeModel::Row row;
749
750                 row = *(template_model->append ());
751
752                 row[session_template_columns.name] = (*x).name;
753                 row[session_template_columns.path] = (*x).path;
754         }
755 }
756
757 void
758 ArdourStartup::setup_new_session_page ()
759 {
760         if (!session_hbox.get_children().empty()) {
761                 session_hbox.remove (**session_hbox.get_children().begin());
762         }
763
764         session_new_vbox.set_spacing (18);
765
766         if (session_new_vbox.get_children().empty()) {
767                 VBox *vbox1 = manage (new VBox);
768                 HBox* hbox1 = manage (new HBox);
769                 Label* label1 = manage (new Label);
770
771                 vbox1->set_spacing (6);
772
773                 hbox1->set_spacing (6);
774                 hbox1->pack_start (*label1, false, false);
775                 hbox1->pack_start (new_name_entry, true, true);
776
777                 label1->set_text (_("Session name:"));
778
779
780                 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
781                         new_name_entry.set_text  (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
782                         /* name provided - they can move right along */
783                         set_page_complete (session_vbox, true);
784                 }
785
786                 new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_changed));
787                 new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &ArdourStartup::move_along_now));
788
789                 vbox1->pack_start (*hbox1, true, true);
790
791                 /* --- */
792
793                 HBox* hbox2 = manage (new HBox);
794                 Label* label2 = manage (new Label);
795
796                 hbox2->set_spacing (6);
797                 hbox2->pack_start (*label2, false, false);
798                 hbox2->pack_start (new_folder_chooser, true, true);
799
800                 label2->set_text (_("Create session folder in:"));
801
802                 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
803                         new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
804                 } else if (ARDOUR_UI::instance()->session_loaded) {
805                         // point the new session file chooser at the parent directory of the current session
806                         string session_parent_dir = Glib::path_get_dirname(ARDOUR_UI::instance()->the_session()->path());
807                         string::size_type last_dir_sep = session_parent_dir.rfind(G_DIR_SEPARATOR);
808                         session_parent_dir = session_parent_dir.substr(0, last_dir_sep);
809                         new_folder_chooser.set_current_folder (session_parent_dir);
810                         new_folder_chooser.add_shortcut_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
811                 } else {
812                         new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
813                 }
814                 new_folder_chooser.show ();
815                 new_folder_chooser.set_title (_("Select folder for session"));
816
817 #ifdef __APPLE__
818                 new_folder_chooser.add_shortcut_folder ("/Volumes");
819 #endif
820
821                 vbox1->pack_start (*hbox2, false, false);
822                 
823                 session_new_vbox.pack_start (*vbox1, false, false);
824
825                 /* --- */
826
827                 VBox *vbox2 = manage (new VBox);
828                 HBox* hbox3 = manage (new HBox);
829                 Label* label3 = manage (new Label);
830                 template_model = ListStore::create (session_template_columns);
831                 populate_session_templates ();
832
833                 vbox2->set_spacing (6);
834
835                 label3->set_markup (_("<b>Options</b>"));
836                 label3->set_alignment (0.0, 0.0);
837
838                 vbox2->pack_start (*label3, false, true);
839
840                 VBox *vbox3 = manage (new VBox);
841
842                 vbox3->set_spacing (6);
843
844                 if (!template_model->children().empty()) {
845
846                         HBox* hbox4a = manage (new HBox);
847                         use_template_button.set_label (_("Use this template"));
848
849                         TreeModel::Row row = *template_model->prepend ();
850                         row[session_template_columns.name] = (_("no template"));
851                         row[session_template_columns.path] = string();
852
853                         hbox4a->set_spacing (6);
854                         hbox4a->pack_start (use_template_button, false, false);
855                         hbox4a->pack_start (template_chooser, true, true);
856
857                         template_chooser.set_model (template_model);
858
859                         Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
860                         text_renderer->property_editable() = false;
861
862                         template_chooser.pack_start (*text_renderer);
863                         template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
864                         template_chooser.set_active (0);
865
866                         use_template_button.show();
867                         template_chooser.show ();
868
869                         vbox3->pack_start (*hbox4a, false, false);
870                 }
871
872                 /* --- */
873
874                 if (!new_user) {
875                         session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
876
877                         HBox* hbox4b = manage (new HBox);
878                         use_session_as_template_button.set_label (_("Use an existing session as a template:"));
879
880                         hbox4b->set_spacing (6);
881                         hbox4b->pack_start (use_session_as_template_button, false, false);
882                         hbox4b->pack_start (session_template_chooser, true, true);
883
884                         use_session_as_template_button.show ();
885                         session_template_chooser.show ();
886
887                         Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
888                         session_filter->add_pattern (X_("*.ardour"));
889                         session_template_chooser.set_filter (*session_filter);
890                         session_template_chooser.set_title (_("Select template"));
891
892                         vbox3->pack_start (*hbox4b, false, false);
893                 }
894
895                 /* --- */
896
897                 HBox* hbox5 = manage (new HBox);
898
899                 hbox5->set_spacing (6);
900                 hbox5->pack_start (more_new_session_options_button, false, false);
901
902                 more_new_session_options_button.show ();
903                 more_new_session_options_button.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::more_new_session_options_button_clicked));
904
905                 vbox3->pack_start (*hbox5, false, false);
906                 hbox3->pack_start (*vbox3, true, true, 8);
907                 vbox2->pack_start (*hbox3, false, false);
908
909                 /* --- */
910
911                 session_new_vbox.pack_start (*vbox2, false, false);
912         }
913
914         session_new_vbox.show_all ();
915         session_hbox.pack_start (session_new_vbox, true, true);
916         set_page_title (session_vbox, _("New Session"));
917         set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
918
919         if (more_new_session_options_button.get_active()) {
920                 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
921         }
922 }
923
924 void
925 ArdourStartup::new_name_changed ()
926 {
927         if (!new_name_entry.get_text().empty()) {
928                 set_page_complete (session_vbox, true);
929         } else {
930                 set_page_complete (session_vbox, false);
931         }
932 }
933
934 int
935 ArdourStartup::redisplay_recent_sessions ()
936 {
937         std::vector<std::string> session_directories;
938         RecentSessionsSorter cmp;
939
940         recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
941         recent_session_model->clear ();
942
943         ARDOUR::RecentSessions rs;
944         ARDOUR::read_recent_sessions (rs);
945
946         if (rs.empty()) {
947                 recent_session_display.set_model (recent_session_model);
948                 return 0;
949         }
950         //
951         // sort them alphabetically
952         sort (rs.begin(), rs.end(), cmp);
953
954         for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
955                 session_directories.push_back ((*i).second);
956         }
957         
958         int session_snapshot_count = 0;
959
960         for (vector<std::string>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
961         {
962                 std::vector<std::string> state_file_paths;
963
964                 // now get available states for this session
965
966                 get_state_files_in_directory (*i, state_file_paths);
967
968                 vector<string*>* states;
969                 vector<const gchar*> item;
970                 string fullpath = *i;
971
972                 /* remove any trailing / */
973
974                 if (fullpath[fullpath.length()-1] == '/') {
975                         fullpath = fullpath.substr (0, fullpath.length()-1);
976                 }
977
978                 /* check whether session still exists */
979                 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
980                         /* session doesn't exist */
981                         continue;
982                 }
983
984                 /* now get available states for this session */
985
986                 if ((states = Session::possible_states (fullpath)) == 0) {
987                         /* no state file? */
988                         continue;
989                 }
990
991                 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
992
993                 Gtk::TreeModel::Row row = *(recent_session_model->append());
994
995                 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
996                 row[recent_session_columns.fullpath] = fullpath;
997                 row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
998                 
999                 ++session_snapshot_count;
1000
1001                 if (state_file_names.size() > 1) {
1002
1003                         // add the children
1004
1005                         for (std::vector<std::string>::iterator i2 = state_file_names.begin();
1006                                         i2 != state_file_names.end(); ++i2) {
1007
1008                                 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
1009
1010                                 child_row[recent_session_columns.visible_name] = *i2;
1011                                 child_row[recent_session_columns.fullpath] = fullpath;
1012                                 child_row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
1013                                 ++session_snapshot_count;
1014                         }
1015                 }
1016         }
1017
1018         recent_session_display.set_tooltip_column(1); // recent_session_columns.tip 
1019         recent_session_display.set_model (recent_session_model);
1020         return session_snapshot_count;
1021         // return rs.size();
1022 }
1023
1024 void
1025 ArdourStartup::recent_session_row_selected ()
1026 {
1027         if (recent_session_display.get_selection()->count_selected_rows() > 0) {
1028                 set_page_complete (session_vbox, true);
1029         } else {
1030                 set_page_complete (session_vbox, false);
1031         }
1032 }
1033
1034 void
1035 ArdourStartup::setup_existing_session_page ()
1036 {
1037         recent_session_model = TreeStore::create (recent_session_columns);
1038         redisplay_recent_sessions ();
1039
1040         if (!session_hbox.get_children().empty()) {
1041                 session_hbox.remove (**session_hbox.get_children().begin());
1042         }
1043
1044         if (session_existing_vbox.get_children().empty()) {
1045
1046                 recent_session_display.set_model (recent_session_model);
1047                 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1048                 recent_session_display.set_headers_visible (false);
1049                 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
1050
1051                 recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::recent_session_row_selected));
1052
1053                 recent_scroller.add (recent_session_display);
1054                 recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1055                 recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
1056
1057                 recent_session_display.show();
1058
1059                 recent_scroller.show();
1060                 int cnt = redisplay_recent_sessions ();
1061                 recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ArdourStartup::recent_row_activated));
1062
1063                 if (cnt > 4) {
1064                         recent_scroller.set_size_request (-1, 300);
1065                 }
1066
1067                 session_existing_vbox.set_spacing (8);
1068                 session_existing_vbox.pack_start (recent_scroller, true, true);
1069
1070                 existing_session_chooser.set_title (_("Select session file"));
1071                 existing_session_chooser.signal_file_set().connect (sigc::mem_fun (*this, &ArdourStartup::existing_session_selected));
1072                 existing_session_chooser.set_current_folder(poor_mans_glob (Config->get_default_session_parent_dir()));
1073
1074                 FileFilter session_filter;
1075                 session_filter.add_pattern ("*.ardour");
1076                 session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
1077                 existing_session_chooser.add_filter (session_filter);
1078                 existing_session_chooser.set_filter (session_filter);
1079                 
1080 #ifdef GTKOSX
1081                 existing_session_chooser.add_shortcut_folder ("/Volumes");
1082 #endif
1083
1084                 HBox* hbox = manage (new HBox);
1085                 hbox->set_spacing (4);
1086                 hbox->pack_start (*manage (new Label (_("Browse:"))), PACK_SHRINK);
1087                 hbox->pack_start (existing_session_chooser);
1088                 session_existing_vbox.pack_start (*hbox, false, false);
1089                 hbox->show_all ();
1090         }
1091
1092         session_existing_vbox.show_all ();
1093         session_hbox.pack_start (session_existing_vbox, true, true);
1094
1095         set_page_title (session_vbox, _("Select a session"));
1096         set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1097 }
1098
1099 void
1100 ArdourStartup::more_new_session_options_button_clicked ()
1101 {
1102         if (more_new_session_options_button.get_active()) {
1103                 more_options_vbox.show_all ();
1104                 set_page_type (more_options_vbox, ASSISTANT_PAGE_CONFIRM);
1105                 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
1106         } else {
1107                 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1108                 more_options_vbox.hide ();
1109         }
1110 }
1111
1112 void
1113 ArdourStartup::setup_more_options_page ()
1114 {
1115         more_options_vbox.set_border_width (24);
1116
1117         _output_limit_count.set_adjustment (_output_limit_count_adj);
1118         _input_limit_count.set_adjustment (_input_limit_count_adj);
1119         _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
1120
1121         chan_count_label_1.set_text (_("channels"));
1122         chan_count_label_3.set_text (_("channels"));
1123         chan_count_label_4.set_text (_("channels"));
1124
1125         chan_count_label_1.set_alignment(0,0.5);
1126         chan_count_label_1.set_padding(0,0);
1127         chan_count_label_1.set_line_wrap(false);
1128
1129         chan_count_label_3.set_alignment(0,0.5);
1130         chan_count_label_3.set_padding(0,0);
1131         chan_count_label_3.set_line_wrap(false);
1132
1133         chan_count_label_4.set_alignment(0,0.5);
1134         chan_count_label_4.set_padding(0,0);
1135         chan_count_label_4.set_line_wrap(false);
1136
1137         bus_label.set_markup (_("<b>Busses</b>"));
1138         input_label.set_markup (_("<b>Inputs</b>"));
1139         output_label.set_markup (_("<b>Outputs</b>"));
1140
1141         _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
1142         _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1143         _master_bus_channel_count.set_numeric(true);
1144         _master_bus_channel_count.set_digits(0);
1145         _master_bus_channel_count.set_wrap(false);
1146
1147         _create_master_bus.set_label (_("Create master bus"));
1148         _create_master_bus.set_flags(Gtk::CAN_FOCUS);
1149         _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
1150         _create_master_bus.set_mode(true);
1151         _create_master_bus.set_active(true);
1152         _create_master_bus.set_border_width(0);
1153
1154         advanced_table.set_row_spacings(0);
1155         advanced_table.set_col_spacings(0);
1156
1157         _connect_inputs.set_label (_("Automatically connect to physical inputs"));
1158         _connect_inputs.set_flags(Gtk::CAN_FOCUS);
1159         _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
1160         _connect_inputs.set_mode(true);
1161         _connect_inputs.set_active(Config->get_input_auto_connect() != ManualConnect);
1162         _connect_inputs.set_border_width(0);
1163
1164         _limit_input_ports.set_label (_("Use only"));
1165         _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
1166         _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
1167         _limit_input_ports.set_mode(true);
1168         _limit_input_ports.set_sensitive(true);
1169         _limit_input_ports.set_border_width(0);
1170
1171         _input_limit_count.set_flags(Gtk::CAN_FOCUS);
1172         _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1173         _input_limit_count.set_numeric(true);
1174         _input_limit_count.set_digits(0);
1175         _input_limit_count.set_wrap(false);
1176         _input_limit_count.set_sensitive(false);
1177
1178         bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
1179
1180         bus_label.set_alignment(0, 0.5);
1181         bus_label.set_padding(0,0);
1182         bus_label.set_line_wrap(false);
1183         bus_label.set_selectable(false);
1184         bus_label.set_use_markup(true);
1185         bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
1186         bus_frame.set_label_align(0,0.5);
1187         bus_frame.add(bus_hbox);
1188         bus_frame.set_label_widget(bus_label);
1189
1190         bus_table.set_row_spacings (0);
1191         bus_table.set_col_spacings (0);
1192         bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1193         bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1194         bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
1195
1196         input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
1197         input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
1198         input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
1199         input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
1200         input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
1201         input_table.set_row_spacings(0);
1202         input_table.set_col_spacings(0);
1203         input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
1204
1205         input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
1206
1207         input_label.set_alignment(0, 0.5);
1208         input_label.set_padding(0,0);
1209         input_label.set_line_wrap(false);
1210         input_label.set_selectable(false);
1211         input_label.set_use_markup(true);
1212         input_frame.set_shadow_type(Gtk::SHADOW_NONE);
1213         input_frame.set_label_align(0,0.5);
1214         input_frame.add(input_hbox);
1215         input_frame.set_label_widget(input_label);
1216
1217         _connect_outputs.set_label (_("Automatically connect outputs"));
1218         _connect_outputs.set_flags(Gtk::CAN_FOCUS);
1219         _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
1220         _connect_outputs.set_mode(true);
1221         _connect_outputs.set_active(Config->get_output_auto_connect() != ManualConnect);
1222         _connect_outputs.set_border_width(0);
1223         _limit_output_ports.set_label (_("Use only"));
1224         _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
1225         _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
1226         _limit_output_ports.set_mode(true);
1227         _limit_output_ports.set_sensitive(true);
1228         _limit_output_ports.set_border_width(0);
1229         _output_limit_count.set_flags(Gtk::CAN_FOCUS);
1230         _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1231         _output_limit_count.set_numeric(false);
1232         _output_limit_count.set_digits(0);
1233         _output_limit_count.set_wrap(false);
1234         _output_limit_count.set_sensitive(false);
1235         output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
1236         output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
1237         output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
1238
1239         _connect_outputs_to_master.set_label (_("... to master bus"));
1240         _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
1241         _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
1242         _connect_outputs_to_master.set_mode(true);
1243         _connect_outputs_to_master.set_active(Config->get_output_auto_connect() == AutoConnectMaster);
1244         _connect_outputs_to_master.set_border_width(0);
1245
1246         _connect_outputs_to_master.set_group (connect_outputs_group);
1247         _connect_outputs_to_physical.set_group (connect_outputs_group);
1248
1249         _connect_outputs_to_physical.set_label (_("... to physical outputs"));
1250         _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
1251         _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
1252         _connect_outputs_to_physical.set_mode(true);
1253         _connect_outputs_to_physical.set_active(Config->get_output_auto_connect() == AutoConnectPhysical);
1254         _connect_outputs_to_physical.set_border_width(0);
1255
1256         output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
1257         output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
1258         output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
1259         output_vbox.set_border_width(6);
1260
1261         output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
1262
1263         output_vbox.pack_start(output_conn_vbox);
1264         output_vbox.pack_start(output_port_vbox);
1265
1266         output_label.set_alignment(0, 0.5);
1267         output_label.set_padding(0,0);
1268         output_label.set_line_wrap(false);
1269         output_label.set_selectable(false);
1270         output_label.set_use_markup(true);
1271         output_frame.set_shadow_type(Gtk::SHADOW_NONE);
1272         output_frame.set_label_align(0,0.5);
1273
1274         output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
1275
1276         output_frame.add(output_hbox);
1277         output_frame.set_label_widget(output_label);
1278
1279         more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
1280         more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
1281         more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
1282         more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
1283
1284         /* signals */
1285
1286         _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
1287         _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
1288         _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
1289         _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
1290         _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
1291
1292         /* note that more_options_vbox is "visible" by default even
1293          * though it may not be displayed to the user, this is so the dialog
1294          * doesn't resize.
1295          */
1296         more_options_vbox.show_all ();
1297
1298         session_options_page_index = append_page (more_options_vbox);
1299         set_page_title (more_options_vbox, _("Advanced Session Options"));
1300         set_page_complete (more_options_vbox, true);
1301 }
1302
1303 bool
1304 ArdourStartup::create_master_bus() const
1305 {
1306         return _create_master_bus.get_active();
1307 }
1308
1309 int
1310 ArdourStartup::master_channel_count() const
1311 {
1312         return _master_bus_channel_count.get_value_as_int();
1313 }
1314
1315 bool
1316 ArdourStartup::connect_inputs() const
1317 {
1318         return _connect_inputs.get_active();
1319 }
1320
1321 bool
1322 ArdourStartup::limit_inputs_used_for_connection() const
1323 {
1324         return _limit_input_ports.get_active();
1325 }
1326
1327 int
1328 ArdourStartup::input_limit_count() const
1329 {
1330         return _input_limit_count.get_value_as_int();
1331 }
1332
1333 bool
1334 ArdourStartup::connect_outputs() const
1335 {
1336         return _connect_outputs.get_active();
1337 }
1338
1339 bool
1340 ArdourStartup::limit_outputs_used_for_connection() const
1341 {
1342         return _limit_output_ports.get_active();
1343 }
1344
1345 int
1346 ArdourStartup::output_limit_count() const
1347 {
1348         return _output_limit_count.get_value_as_int();
1349 }
1350
1351 bool
1352 ArdourStartup::connect_outs_to_master() const
1353 {
1354         return _connect_outputs_to_master.get_active();
1355 }
1356
1357 bool
1358 ArdourStartup::connect_outs_to_physical() const
1359 {
1360         return _connect_outputs_to_physical.get_active();
1361 }
1362
1363 void
1364 ArdourStartup::connect_inputs_clicked ()
1365 {
1366         _limit_input_ports.set_sensitive(_connect_inputs.get_active());
1367
1368         if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
1369                 _input_limit_count.set_sensitive(true);
1370         } else {
1371                 _input_limit_count.set_sensitive(false);
1372         }
1373 }
1374
1375 void
1376 ArdourStartup::connect_outputs_clicked ()
1377 {
1378         bool const co = _connect_outputs.get_active ();
1379         _limit_output_ports.set_sensitive(co);
1380         _connect_outputs_to_master.set_sensitive(co);
1381         _connect_outputs_to_physical.set_sensitive(co);
1382
1383         if (co && _limit_output_ports.get_active()) {
1384                 _output_limit_count.set_sensitive(true);
1385         } else {
1386                 _output_limit_count.set_sensitive(false);
1387         }
1388 }
1389
1390 void
1391 ArdourStartup::limit_inputs_clicked ()
1392 {
1393         _input_limit_count.set_sensitive(_limit_input_ports.get_active());
1394 }
1395
1396 void
1397 ArdourStartup::limit_outputs_clicked ()
1398 {
1399         _output_limit_count.set_sensitive(_limit_output_ports.get_active());
1400 }
1401
1402 void
1403 ArdourStartup::master_bus_button_clicked ()
1404 {
1405         bool const yn = _create_master_bus.get_active();
1406
1407         _master_bus_channel_count.set_sensitive(yn);
1408         _connect_outputs_to_master.set_sensitive(yn);
1409 }
1410
1411 void
1412 ArdourStartup::move_along_now ()
1413 {
1414         gint cur = get_current_page ();
1415
1416         if (cur == session_page_index) {
1417                 if (more_new_session_options_button.get_active()) {
1418                         set_current_page (session_options_page_index);
1419                 } else {
1420                         on_apply ();
1421                 }
1422         }
1423 }
1424
1425 void
1426 ArdourStartup::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
1427 {
1428         set_page_complete (session_vbox, true);
1429         move_along_now ();
1430 }
1431
1432 void
1433 ArdourStartup::existing_session_selected ()
1434 {
1435         _existing_session_chooser_used = true;
1436
1437         set_page_complete (session_vbox, true);
1438         move_along_now ();
1439 }
1440
1441 std::string
1442 ArdourStartup::been_here_before_path () const
1443 {
1444         // XXXX use more specific version so we can catch upgrades
1445         return Glib::build_filename (user_config_directory (), ".a3");
1446 }
1447
1448 void
1449 ArdourStartup::updates_button_clicked ()
1450 {
1451         //now open a browser window so user can see more
1452         PBD::open_uri (Config->get_updates_url());
1453 }
1454
1455 bool
1456 ArdourStartup::info_scroller_update()
1457 {
1458         info_scroller_count++;
1459
1460         char buf[512];
1461         snprintf (buf, std::min(info_scroller_count,sizeof(buf)-1), "%s", ARDOUR_UI::instance()->announce_string().c_str() );
1462         buf[info_scroller_count] = 0;
1463         info_scroller_label.set_text (buf);
1464         info_scroller_label.show();
1465
1466         if (info_scroller_count > ARDOUR_UI::instance()->announce_string().length()) {
1467                 info_scroller_connection.disconnect();
1468         }
1469
1470         return true;
1471 }