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