move advanced new session options into an expander, change some wording
[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         ARDOUR::RecentSessions rs;
550         ARDOUR::read_recent_sessions (rs);
551         
552         if (!rs.empty()) {
553
554                 /* recent session scroller */
555
556                 Label* load_label = manage (new Label);
557                 load_label->set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", _("Load a recent session")));
558                 load_label->set_alignment (0, 0.5);
559
560                 centering_vbox->pack_start (*load_label, false, false, 12);
561
562                 recent_session_model = TreeStore::create (recent_session_columns);
563                 redisplay_recent_sessions ();
564
565                 recent_session_display.set_model (recent_session_model);
566                 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
567                 recent_session_display.set_headers_visible (false);
568                 recent_session_display.get_selection()->set_mode (SELECTION_SINGLE);
569         
570                 recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::recent_session_row_selected));
571         
572                 recent_scroller.add (recent_session_display);
573                 recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
574                 recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
575         
576                 recent_session_display.show();
577         
578                 recent_scroller.show();
579                 recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ArdourStartup::recent_row_activated));
580         
581                 int cnt = redisplay_recent_sessions ();
582                 if (cnt > 4) {
583                         recent_scroller.set_size_request (-1, 300);
584                 }
585         
586                 centering_vbox->pack_start (recent_scroller, false, true);
587         }
588
589         /* Browse button */
590         
591         existing_session_chooser.set_title (_("Select session file"));
592         existing_session_chooser.signal_file_set().connect (sigc::mem_fun (*this, &ArdourStartup::existing_session_selected));
593         existing_session_chooser.set_current_folder(poor_mans_glob (Config->get_default_session_parent_dir()));
594         
595         FileFilter session_filter;
596         session_filter.add_pattern ("*.ardour");
597         session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
598         existing_session_chooser.add_filter (session_filter);
599         existing_session_chooser.set_filter (session_filter);
600         
601 #ifdef GTKOSX
602         existing_session_chooser.add_shortcut_folder ("/Volumes");
603 #endif
604         
605         Label* browse_label = manage (new Label);
606         browse_label->set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", _("Browse for other sessions")));
607         browse_label->set_alignment (0, 0.5);
608         
609         centering_vbox->pack_start (*browse_label, false, false, 12);
610         centering_vbox->pack_start (existing_session_chooser, false, false);
611
612         /* pack it all up */
613
614         centering_hbox->pack_start (*centering_vbox, true, true);
615         ic_vbox.pack_start (*centering_hbox, true, true);
616         ic_vbox.show_all ();
617
618         /* user could just click on "Forward" if default
619          * choice is correct.
620          */
621
622         set_page_complete (ic_vbox, true);
623 }
624
625 void
626 ArdourStartup::session_selected ()
627 {
628         /* HACK HACK HACK ... change the "Apply" button label
629            to say "Open"
630         */
631
632         Gtk::Widget* tl = ic_vbox.get_toplevel();
633         Gtk::Window* win;
634         if ((win = dynamic_cast<Gtk::Window*>(tl)) != 0) {
635                 /* ::get_default_widget() is not wrapped in gtkmm */
636                 Gtk::Widget* def = wrap (gtk_window_get_default_widget (win->gobj()));
637                 Gtk::Button* button;
638                 if ((button = dynamic_cast<Gtk::Button*>(def)) != 0) {
639                         button->set_label (_("Open"));
640                 }
641         }
642 }
643
644 void
645 ArdourStartup::new_session_button_clicked ()
646 {
647         set_current_page (new_session_page_index);
648 }
649
650 void
651 ArdourStartup::setup_final_page ()
652 {
653         final_page.set_text (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
654         final_page.show ();
655         final_page_index = append_page (final_page);
656         set_page_complete (final_page, true);
657         set_page_header_image (final_page, icon_pixbuf);
658         set_page_type (final_page, ASSISTANT_PAGE_CONFIRM);
659 }
660
661 void
662 ArdourStartup::on_cancel ()
663 {
664         _response = RESPONSE_CANCEL;
665         gtk_main_quit ();
666 }
667
668 void
669 ArdourStartup::on_prepare (Gtk::Widget* page)
670 {
671         if (page == &session_new_vbox) {
672
673                 /* if the user already defined a name by using the recent
674                  * session list or browsing to an existing session
675                  * then we are done.
676                  */
677                 
678                 bool expect_new_ignored;
679
680                 if (!session_name (expect_new_ignored).empty()) {
681                         on_apply ();
682                 }
683         }
684 }
685
686 bool
687 ArdourStartup::on_delete_event (GdkEventAny*)
688 {
689         _response = RESPONSE_CLOSE;
690         gtk_main_quit ();
691         return true;
692 }
693
694 void
695 ArdourStartup::on_apply ()
696 {
697         if (config_modified) {
698
699                 if (default_dir_chooser) {
700                         Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
701                 }
702
703                 if (monitor_via_hardware_button.get_active()) {
704                         Config->set_monitoring_model (ExternalMonitoring);
705                 } else if (monitor_via_ardour_button.get_active()) {
706                         Config->set_monitoring_model (SoftwareMonitoring);
707                 }
708
709                 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
710
711                 Config->save_state ();
712
713         }
714
715         {
716                 /* "touch" the been-here-before path now we've successfully
717                    made it through the first time setup (at least)
718                 */
719                 ofstream fout (been_here_before_path().c_str());
720
721         }
722                 
723         _response = RESPONSE_OK;
724         gtk_main_quit ();
725 }
726
727 void
728 ArdourStartup::populate_session_templates ()
729 {
730         vector<TemplateInfo> templates;
731
732         find_session_templates (templates);
733
734         template_model->clear ();
735
736         for (vector<TemplateInfo>::iterator x = templates.begin(); x != templates.end(); ++x) {
737                 TreeModel::Row row;
738
739                 row = *(template_model->append ());
740
741                 row[session_template_columns.name] = (*x).name;
742                 row[session_template_columns.path] = (*x).path;
743         }
744 }
745
746 void
747 ArdourStartup::setup_new_session_page ()
748 {
749         session_new_vbox.set_border_width (12);
750         session_new_vbox.set_spacing (18);
751
752         if (session_new_vbox.get_children().empty()) {
753                 VBox *vbox1 = manage (new VBox);
754                 HBox* hbox1 = manage (new HBox);
755                 Label* label1 = manage (new Label);
756
757                 vbox1->set_spacing (6);
758
759                 hbox1->set_spacing (6);
760                 hbox1->pack_start (*label1, false, false);
761                 hbox1->pack_start (new_name_entry, true, true);
762
763                 label1->set_text (_("Session name:"));
764
765
766                 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
767                         new_name_entry.set_text  (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
768                         /* name provided - they can move right along */
769                         set_page_complete (session_new_vbox, true);
770                 }
771
772                 new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_changed));
773                 new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &ArdourStartup::move_along_now));
774
775                 vbox1->pack_start (*hbox1, true, true);
776
777                 /* --- */
778
779                 HBox* hbox2 = manage (new HBox);
780                 Label* label2 = manage (new Label);
781
782                 hbox2->set_spacing (6);
783                 hbox2->pack_start (*label2, false, false);
784                 hbox2->pack_start (new_folder_chooser, true, true);
785
786                 label2->set_text (_("Create session folder in:"));
787
788                 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
789                         new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
790                 } else if (ARDOUR_UI::instance()->session_loaded) {
791                         // point the new session file chooser at the parent directory of the current session
792                         string session_parent_dir = Glib::path_get_dirname(ARDOUR_UI::instance()->the_session()->path());
793                         string::size_type last_dir_sep = session_parent_dir.rfind(G_DIR_SEPARATOR);
794                         session_parent_dir = session_parent_dir.substr(0, last_dir_sep);
795                         new_folder_chooser.set_current_folder (session_parent_dir);
796                         string default_session_folder = poor_mans_glob (Config->get_default_session_parent_dir());
797
798                         try {
799                                 /* add_shortcut_folder throws an exception if the folder being added already has a shortcut */
800                                 new_folder_chooser.add_shortcut_folder (default_session_folder);
801                         }
802                         catch (Glib::Error & e) {
803                                 std::cerr << "new_folder_chooser.add_shortcut_folder (" << default_session_folder << ") threw Glib::Error " << e.what() << std::endl;
804                         }
805                 } else {
806                         new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
807                 }
808                 new_folder_chooser.show ();
809                 new_folder_chooser.set_title (_("Select folder for session"));
810
811 #ifdef __APPLE__
812                 new_folder_chooser.add_shortcut_folder ("/Volumes");
813 #endif
814
815                 vbox1->pack_start (*hbox2, false, false);
816                 
817                 session_new_vbox.pack_start (*vbox1, false, false);
818
819                 /* --- */
820
821                 VBox *vbox2 = manage (new VBox);
822                 HBox* hbox3 = manage (new HBox);
823                 Label* label3 = manage (new Label);
824                 template_model = ListStore::create (session_template_columns);
825                 populate_session_templates ();
826
827                 vbox2->set_spacing (6);
828
829                 VBox *vbox3 = manage (new VBox);
830
831                 vbox3->set_spacing (6);
832
833                 if (!template_model->children().empty()) {
834
835                         HBox* hbox4a = manage (new HBox);
836                         use_template_button.set_label (_("Use this template"));
837
838                         TreeModel::Row row = *template_model->prepend ();
839                         row[session_template_columns.name] = (_("no template"));
840                         row[session_template_columns.path] = string();
841
842                         hbox4a->set_spacing (6);
843                         hbox4a->pack_start (use_template_button, false, false);
844                         hbox4a->pack_start (template_chooser, true, true);
845
846                         template_chooser.set_model (template_model);
847
848                         Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
849                         text_renderer->property_editable() = false;
850
851                         template_chooser.pack_start (*text_renderer);
852                         template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
853                         template_chooser.set_active (0);
854
855                         use_template_button.show();
856                         template_chooser.show ();
857
858                         vbox3->pack_start (*hbox4a, false, false);
859                 }
860
861                 /* --- */
862
863                 if (!new_user) {
864                         session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
865
866                         HBox* hbox4b = manage (new HBox);
867                         use_session_as_template_button.set_label (_("Use an existing session as a template:"));
868
869                         hbox4b->set_spacing (6);
870                         hbox4b->pack_start (use_session_as_template_button, false, false);
871                         hbox4b->pack_start (session_template_chooser, true, true);
872
873                         use_session_as_template_button.show ();
874                         session_template_chooser.show ();
875
876                         Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
877                         session_filter->add_pattern (X_("*.ardour"));
878                         session_template_chooser.set_filter (*session_filter);
879                         session_template_chooser.set_title (_("Select template"));
880
881                         vbox3->pack_start (*hbox4b, false, false);
882                 }
883
884                 /* --- */
885
886                 HBox* hbox5 = manage (new HBox);
887
888                 hbox5->set_spacing (6);
889                 hbox5->pack_start (more_new_session_options_button, false, false);
890
891                 setup_more_options_box ();
892                 more_new_session_options_button.add (more_options_vbox);
893
894                 vbox3->pack_start (*hbox5, false, false);
895                 hbox3->pack_start (*vbox3, true, true, 8);
896                 vbox2->pack_start (*hbox3, false, false);
897
898                 /* --- */
899
900                 session_new_vbox.pack_start (*vbox2, false, false);
901         }
902
903         session_new_vbox.show_all ();
904
905         new_session_page_index = append_page (session_new_vbox);
906         set_page_type (session_new_vbox, ASSISTANT_PAGE_CONTENT);
907         set_page_title (session_new_vbox, _("New Session"));
908
909         set_page_type (session_new_vbox, ASSISTANT_PAGE_CONFIRM);
910 }
911
912 void
913 ArdourStartup::new_name_changed ()
914 {
915         if (!new_name_entry.get_text().empty()) {
916                 session_selected ();
917                 set_page_complete (session_new_vbox, true);
918         } else {
919                 set_page_complete (session_new_vbox, false);
920         }
921 }
922
923 int
924 ArdourStartup::redisplay_recent_sessions ()
925 {
926         std::vector<std::string> session_directories;
927         RecentSessionsSorter cmp;
928
929         recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
930         recent_session_model->clear ();
931
932         ARDOUR::RecentSessions rs;
933         ARDOUR::read_recent_sessions (rs);
934
935         if (rs.empty()) {
936                 recent_session_display.set_model (recent_session_model);
937                 return 0;
938         }
939         //
940         // sort them alphabetically
941         sort (rs.begin(), rs.end(), cmp);
942
943         for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
944                 session_directories.push_back ((*i).second);
945         }
946         
947         int session_snapshot_count = 0;
948
949         for (vector<std::string>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
950         {
951                 std::vector<std::string> state_file_paths;
952
953                 // now get available states for this session
954
955                 get_state_files_in_directory (*i, state_file_paths);
956
957                 vector<string*>* states;
958                 vector<const gchar*> item;
959                 string fullpath = *i;
960
961                 /* remove any trailing / */
962
963                 if (fullpath[fullpath.length()-1] == '/') {
964                         fullpath = fullpath.substr (0, fullpath.length()-1);
965                 }
966
967                 /* check whether session still exists */
968                 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
969                         /* session doesn't exist */
970                         continue;
971                 }
972
973                 /* now get available states for this session */
974
975                 if ((states = Session::possible_states (fullpath)) == 0) {
976                         /* no state file? */
977                         continue;
978                 }
979
980                 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
981
982                 Gtk::TreeModel::Row row = *(recent_session_model->append());
983
984                 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
985                 row[recent_session_columns.fullpath] = fullpath;
986                 row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
987                 
988                 ++session_snapshot_count;
989
990                 if (state_file_names.size() > 1) {
991
992                         // add the children
993
994                         for (std::vector<std::string>::iterator i2 = state_file_names.begin();
995                                         i2 != state_file_names.end(); ++i2) {
996
997                                 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
998
999                                 child_row[recent_session_columns.visible_name] = *i2;
1000                                 child_row[recent_session_columns.fullpath] = fullpath;
1001                                 child_row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
1002                                 ++session_snapshot_count;
1003                         }
1004                 }
1005         }
1006
1007         recent_session_display.set_tooltip_column(1); // recent_session_columns.tip 
1008         recent_session_display.set_model (recent_session_model);
1009         return session_snapshot_count;
1010         // return rs.size();
1011 }
1012
1013 void
1014 ArdourStartup::recent_session_row_selected ()
1015 {
1016         if (recent_session_display.get_selection()->count_selected_rows() > 0) {
1017                 set_page_complete (ic_vbox, true);
1018                 session_selected ();
1019         } else {
1020                 set_page_complete (ic_vbox, false);
1021         }
1022 }
1023
1024 void
1025 ArdourStartup::setup_more_options_box ()
1026 {
1027         more_options_vbox.set_border_width (24);
1028
1029         _output_limit_count.set_adjustment (_output_limit_count_adj);
1030         _input_limit_count.set_adjustment (_input_limit_count_adj);
1031         _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
1032
1033         chan_count_label_1.set_text (_("channels"));
1034         chan_count_label_3.set_text (_("channels"));
1035         chan_count_label_4.set_text (_("channels"));
1036
1037         chan_count_label_1.set_alignment(0,0.5);
1038         chan_count_label_1.set_padding(0,0);
1039         chan_count_label_1.set_line_wrap(false);
1040
1041         chan_count_label_3.set_alignment(0,0.5);
1042         chan_count_label_3.set_padding(0,0);
1043         chan_count_label_3.set_line_wrap(false);
1044
1045         chan_count_label_4.set_alignment(0,0.5);
1046         chan_count_label_4.set_padding(0,0);
1047         chan_count_label_4.set_line_wrap(false);
1048
1049         bus_label.set_markup (_("<b>Busses</b>"));
1050         input_label.set_markup (_("<b>Inputs</b>"));
1051         output_label.set_markup (_("<b>Outputs</b>"));
1052
1053         _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
1054         _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1055         _master_bus_channel_count.set_numeric(true);
1056         _master_bus_channel_count.set_digits(0);
1057         _master_bus_channel_count.set_wrap(false);
1058
1059         _create_master_bus.set_label (_("Create master bus"));
1060         _create_master_bus.set_flags(Gtk::CAN_FOCUS);
1061         _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
1062         _create_master_bus.set_mode(true);
1063         _create_master_bus.set_active(true);
1064         _create_master_bus.set_border_width(0);
1065
1066         advanced_table.set_row_spacings(0);
1067         advanced_table.set_col_spacings(0);
1068
1069         _connect_inputs.set_label (_("Automatically connect to physical inputs"));
1070         _connect_inputs.set_flags(Gtk::CAN_FOCUS);
1071         _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
1072         _connect_inputs.set_mode(true);
1073         _connect_inputs.set_active(Config->get_input_auto_connect() != ManualConnect);
1074         _connect_inputs.set_border_width(0);
1075
1076         _limit_input_ports.set_label (_("Use only"));
1077         _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
1078         _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
1079         _limit_input_ports.set_mode(true);
1080         _limit_input_ports.set_sensitive(true);
1081         _limit_input_ports.set_border_width(0);
1082
1083         _input_limit_count.set_flags(Gtk::CAN_FOCUS);
1084         _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1085         _input_limit_count.set_numeric(true);
1086         _input_limit_count.set_digits(0);
1087         _input_limit_count.set_wrap(false);
1088         _input_limit_count.set_sensitive(false);
1089
1090         bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
1091
1092         bus_label.set_alignment(0, 0.5);
1093         bus_label.set_padding(0,0);
1094         bus_label.set_line_wrap(false);
1095         bus_label.set_selectable(false);
1096         bus_label.set_use_markup(true);
1097         bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
1098         bus_frame.set_label_align(0,0.5);
1099         bus_frame.add(bus_hbox);
1100         bus_frame.set_label_widget(bus_label);
1101
1102         bus_table.set_row_spacings (0);
1103         bus_table.set_col_spacings (0);
1104         bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1105         bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1106         bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
1107
1108         input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
1109         input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
1110         input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
1111         input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
1112         input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
1113         input_table.set_row_spacings(0);
1114         input_table.set_col_spacings(0);
1115         input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
1116
1117         input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
1118
1119         input_label.set_alignment(0, 0.5);
1120         input_label.set_padding(0,0);
1121         input_label.set_line_wrap(false);
1122         input_label.set_selectable(false);
1123         input_label.set_use_markup(true);
1124         input_frame.set_shadow_type(Gtk::SHADOW_NONE);
1125         input_frame.set_label_align(0,0.5);
1126         input_frame.add(input_hbox);
1127         input_frame.set_label_widget(input_label);
1128
1129         _connect_outputs.set_label (_("Automatically connect outputs"));
1130         _connect_outputs.set_flags(Gtk::CAN_FOCUS);
1131         _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
1132         _connect_outputs.set_mode(true);
1133         _connect_outputs.set_active(Config->get_output_auto_connect() != ManualConnect);
1134         _connect_outputs.set_border_width(0);
1135         _limit_output_ports.set_label (_("Use only"));
1136         _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
1137         _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
1138         _limit_output_ports.set_mode(true);
1139         _limit_output_ports.set_sensitive(true);
1140         _limit_output_ports.set_border_width(0);
1141         _output_limit_count.set_flags(Gtk::CAN_FOCUS);
1142         _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1143         _output_limit_count.set_numeric(false);
1144         _output_limit_count.set_digits(0);
1145         _output_limit_count.set_wrap(false);
1146         _output_limit_count.set_sensitive(false);
1147         output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
1148         output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
1149         output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
1150
1151         _connect_outputs_to_master.set_label (_("... to master bus"));
1152         _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
1153         _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
1154         _connect_outputs_to_master.set_mode(true);
1155         _connect_outputs_to_master.set_active(Config->get_output_auto_connect() == AutoConnectMaster);
1156         _connect_outputs_to_master.set_border_width(0);
1157
1158         _connect_outputs_to_master.set_group (connect_outputs_group);
1159         _connect_outputs_to_physical.set_group (connect_outputs_group);
1160
1161         _connect_outputs_to_physical.set_label (_("... to physical outputs"));
1162         _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
1163         _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
1164         _connect_outputs_to_physical.set_mode(true);
1165         _connect_outputs_to_physical.set_active(Config->get_output_auto_connect() == AutoConnectPhysical);
1166         _connect_outputs_to_physical.set_border_width(0);
1167
1168         output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
1169         output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
1170         output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
1171         output_vbox.set_border_width(6);
1172
1173         output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
1174
1175         output_vbox.pack_start(output_conn_vbox);
1176         output_vbox.pack_start(output_port_vbox);
1177
1178         output_label.set_alignment(0, 0.5);
1179         output_label.set_padding(0,0);
1180         output_label.set_line_wrap(false);
1181         output_label.set_selectable(false);
1182         output_label.set_use_markup(true);
1183         output_frame.set_shadow_type(Gtk::SHADOW_NONE);
1184         output_frame.set_label_align(0,0.5);
1185
1186         output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
1187
1188         output_frame.add(output_hbox);
1189         output_frame.set_label_widget(output_label);
1190
1191         more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
1192         more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
1193         more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
1194         more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
1195
1196         /* signals */
1197
1198         _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
1199         _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
1200         _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
1201         _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
1202         _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
1203
1204         /* note that more_options_vbox is "visible" by default even
1205          * though it may not be displayed to the user, this is so the dialog
1206          * doesn't resize.
1207          */
1208         more_options_vbox.show_all ();
1209 }
1210
1211 bool
1212 ArdourStartup::create_master_bus() const
1213 {
1214         return _create_master_bus.get_active();
1215 }
1216
1217 int
1218 ArdourStartup::master_channel_count() const
1219 {
1220         return _master_bus_channel_count.get_value_as_int();
1221 }
1222
1223 bool
1224 ArdourStartup::connect_inputs() const
1225 {
1226         return _connect_inputs.get_active();
1227 }
1228
1229 bool
1230 ArdourStartup::limit_inputs_used_for_connection() const
1231 {
1232         return _limit_input_ports.get_active();
1233 }
1234
1235 int
1236 ArdourStartup::input_limit_count() const
1237 {
1238         return _input_limit_count.get_value_as_int();
1239 }
1240
1241 bool
1242 ArdourStartup::connect_outputs() const
1243 {
1244         return _connect_outputs.get_active();
1245 }
1246
1247 bool
1248 ArdourStartup::limit_outputs_used_for_connection() const
1249 {
1250         return _limit_output_ports.get_active();
1251 }
1252
1253 int
1254 ArdourStartup::output_limit_count() const
1255 {
1256         return _output_limit_count.get_value_as_int();
1257 }
1258
1259 bool
1260 ArdourStartup::connect_outs_to_master() const
1261 {
1262         return _connect_outputs_to_master.get_active();
1263 }
1264
1265 bool
1266 ArdourStartup::connect_outs_to_physical() const
1267 {
1268         return _connect_outputs_to_physical.get_active();
1269 }
1270
1271 void
1272 ArdourStartup::connect_inputs_clicked ()
1273 {
1274         _limit_input_ports.set_sensitive(_connect_inputs.get_active());
1275
1276         if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
1277                 _input_limit_count.set_sensitive(true);
1278         } else {
1279                 _input_limit_count.set_sensitive(false);
1280         }
1281 }
1282
1283 void
1284 ArdourStartup::connect_outputs_clicked ()
1285 {
1286         bool const co = _connect_outputs.get_active ();
1287         _limit_output_ports.set_sensitive(co);
1288         _connect_outputs_to_master.set_sensitive(co);
1289         _connect_outputs_to_physical.set_sensitive(co);
1290
1291         if (co && _limit_output_ports.get_active()) {
1292                 _output_limit_count.set_sensitive(true);
1293         } else {
1294                 _output_limit_count.set_sensitive(false);
1295         }
1296 }
1297
1298 void
1299 ArdourStartup::limit_inputs_clicked ()
1300 {
1301         _input_limit_count.set_sensitive(_limit_input_ports.get_active());
1302 }
1303
1304 void
1305 ArdourStartup::limit_outputs_clicked ()
1306 {
1307         _output_limit_count.set_sensitive(_limit_output_ports.get_active());
1308 }
1309
1310 void
1311 ArdourStartup::master_bus_button_clicked ()
1312 {
1313         bool const yn = _create_master_bus.get_active();
1314
1315         _master_bus_channel_count.set_sensitive(yn);
1316         _connect_outputs_to_master.set_sensitive(yn);
1317 }
1318
1319 void
1320 ArdourStartup::move_along_now ()
1321 {
1322         on_apply ();
1323 }
1324
1325 void
1326 ArdourStartup::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
1327 {
1328         set_page_complete (ic_vbox, true);
1329         move_along_now ();
1330 }
1331
1332 void
1333 ArdourStartup::existing_session_selected ()
1334 {
1335         _existing_session_chooser_used = true;
1336
1337         session_selected ();
1338         set_page_complete (ic_vbox, true);
1339         move_along_now ();
1340 }
1341
1342 std::string
1343 ArdourStartup::been_here_before_path () const
1344 {
1345         // XXXX use more specific version so we can catch upgrades
1346         return Glib::build_filename (user_config_directory (), ".a3");
1347 }
1348
1349 void
1350 ArdourStartup::updates_button_clicked ()
1351 {
1352         //now open a browser window so user can see more
1353         PBD::open_uri (Config->get_updates_url());
1354 }
1355
1356 bool
1357 ArdourStartup::info_scroller_update()
1358 {
1359         info_scroller_count++;
1360
1361         char buf[512];
1362         snprintf (buf, std::min(info_scroller_count,sizeof(buf)-1), "%s", ARDOUR_UI::instance()->announce_string().c_str() );
1363         buf[info_scroller_count] = 0;
1364         info_scroller_label.set_text (buf);
1365         info_scroller_label.show();
1366
1367         if (info_scroller_count > ARDOUR_UI::instance()->announce_string().length()) {
1368                 info_scroller_connection.disconnect();
1369         }
1370
1371         return true;
1372 }