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