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