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