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