farewell NSD, we loved you sometimes, almost never
[ardour.git] / gtk2_ardour / startup.cc
1 #include <fstream>
2 #include <algorithm>
3
4 #include <gtkmm/main.h>
5 #include <gtkmm/filechooser.h>
6
7 #include "pbd/failed_constructor.h"
8 #include "pbd/file_utils.h"
9 #include "pbd/filesystem.h"
10
11 #include "ardour/filesystem_paths.h"
12 #include "ardour/recent_sessions.h"
13 #include "ardour/session.h"
14 #include "ardour/session_state_utils.h"
15 #include "ardour/template_utils.h"
16
17 #include "startup.h"
18 #include "engine_dialog.h"
19 #include "i18n.h"
20
21 using namespace std;
22 using namespace Gtk;
23 using namespace Gdk;
24 using namespace Glib;
25 using namespace PBD;
26 using namespace ARDOUR;
27
28 ArdourStartup* ArdourStartup::the_startup = 0;
29
30 ArdourStartup::ArdourStartup ()
31         : applying (false)
32         , ic_new_session_button (_("Open a new session"))
33         , ic_existing_session_button (_("Open an existing session"))
34         , more_new_session_options_button (_("I'd like more options for this session"))
35         , monitor_via_hardware_button (_("Use an external mixer or the hardware mixer of your audio interface.\n\
36 Ardour will play NO role in monitoring"))
37         , monitor_via_ardour_button (_("Ask Ardour to playback material as it is being recorded"))
38         , new_folder_chooser (FILE_CHOOSER_ACTION_SELECT_FOLDER)
39         , _output_limit_count_adj (1, 0, 100, 1, 10, 0)
40         , _input_limit_count_adj (1, 0, 100, 1, 10, 0)
41         , _control_bus_channel_count_adj (2, 0, 100, 1, 10, 0)
42         , _master_bus_channel_count_adj (2, 0, 100, 1, 10, 0)
43
44 {
45         audio_page_index = -1;
46         initial_choice_index = -1;
47         new_user_page_index = -1;
48         default_folder_page_index = -1;
49         monitoring_page_index = -1;
50         session_page_index = -1;
51         final_page_index = -1;
52         session_options_page_index = -1;
53
54         engine_dialog = 0;
55         config_modified = false;
56         default_dir_chooser = 0;
57
58         set_keep_above (true);
59         set_position (WIN_POS_CENTER);
60
61         sys::path icon_file;
62
63         if (!find_file_in_search_path (ardour_search_path() + system_data_search_path(), "ardour_icon_48px.png", icon_file)) {
64                 throw failed_constructor();
65         }
66
67         try {
68                 icon_pixbuf = Gdk::Pixbuf::create_from_file (icon_file.to_string());
69         }
70
71         catch (...) {
72                 throw failed_constructor();
73         }
74
75         sys::path been_here_before = user_config_directory();
76         been_here_before /= ".a3"; // XXXX use more specific version so we can catch upgrades
77         bool new_user = !exists (been_here_before);
78         bool need_audio_setup = !EngineControl::engine_running();
79
80         if (new_user) {
81                 /* "touch" the file */
82                 ofstream fout (been_here_before.to_string().c_str());
83                 setup_new_user_page ();
84                 setup_first_time_config_page ();
85                 setup_monitoring_choice_page ();
86
87                 if (need_audio_setup) {
88                         setup_audio_page ();
89                 }
90
91         } else {
92
93                 if (need_audio_setup) {
94                         setup_audio_page ();
95                 }
96
97                 setup_initial_choice_page ();
98         }
99
100         setup_session_page ();
101         setup_more_options_page ();
102
103         if (new_user) {
104                 setup_final_page ();
105         }
106
107         the_startup = this;
108 }
109
110 ArdourStartup::~ArdourStartup ()
111 {
112 }
113
114 Glib::ustring
115 ArdourStartup::session_name (bool& should_be_new)
116 {
117         if (ic_new_session_button.get_active()) {
118                 should_be_new = true;
119                 return new_name_entry.get_text ();
120         } else {
121                 should_be_new = false;
122
123                 TreeIter iter = recent_session_display.get_selection()->get_selected();
124                 
125                 if (iter) {
126                         return (*iter)[recent_session_columns.visible_name];
127                 }
128
129                 return "";
130         }
131 }
132
133 Glib::ustring
134 ArdourStartup::session_folder ()
135 {
136         if (ic_new_session_button.get_active()) {
137                 return new_folder_chooser.get_current_folder();
138         } else {
139                 TreeIter iter = recent_session_display.get_selection()->get_selected();
140
141                 if (iter) {
142                         return (*iter)[recent_session_columns.fullpath];
143                 } 
144                 return "";
145         }
146 }
147
148 void
149 ArdourStartup::setup_audio_page ()
150 {
151         engine_dialog = manage (new EngineControl);
152
153         engine_dialog->show_all ();
154
155         audio_page_index = append_page (*engine_dialog);
156         set_page_type (*engine_dialog, ASSISTANT_PAGE_CONTENT);
157         set_page_title (*engine_dialog, _("Audio Setup"));
158         
159         /* the default parameters should work, so the page is potentially complete */
160
161         set_page_complete (*engine_dialog, true);
162 }
163
164 void
165 ArdourStartup::setup_new_user_page ()
166 {
167         Label* foomatic = manage (new Label);
168
169         foomatic->set_markup (_("\
170 <span size=\"larger\">Ardour is a digital audio workstation. You can use it to\n\
171 record, edit and mix multi-track audio. You can produce your\n\
172 own CDs, mix video soundtracks, or just experiment with new\n\
173 ideas about music and sound.\n\
174 \n\
175 There are a few things that need to configured before you start\n\
176 using the program.</span>\
177 "));
178         
179         HBox* hbox = manage (new HBox);
180         HBox* vbox = manage (new HBox);
181
182         hbox->set_border_width (12);
183         vbox->set_border_width (12);
184
185         hbox->pack_start (*foomatic, false, true);
186         vbox->pack_start (*hbox, false, true);
187
188         foomatic->show ();
189         hbox->show ();
190         vbox->show ();
191
192         new_user_page_index = append_page (*vbox);
193         set_page_type (*vbox, ASSISTANT_PAGE_INTRO);
194         set_page_title (*vbox, _("Welcome to Ardour"));
195         set_page_header_image (*vbox, icon_pixbuf);
196         set_page_complete (*vbox, true);
197 }
198
199 void
200 ArdourStartup::default_dir_changed ()
201 {
202         Config->set_default_session_parent_dir (default_dir_chooser->get_current_folder());
203         config_modified = true;
204 }
205
206 void
207 ArdourStartup::setup_first_time_config_page ()
208 {
209         default_dir_chooser = manage (new FileChooserButton (_("Default folder for Ardour sessions"), 
210                                                              FILE_CHOOSER_ACTION_SELECT_FOLDER));
211         Gtk::Label* txt = manage (new Label);
212         HBox* hbox1 = manage (new HBox);
213         VBox* vbox = manage (new VBox);
214         
215         txt->set_markup (_("\
216 Each project that you work on with Ardour has its own folder.\n\
217 These can require a lot of disk space if you are recording audio.\n\
218 \n\
219 Where would you like new Ardour sessions to be stored by default?\n\
220 <i>(You can put new sessions anywhere - this is just a default)</i>"));
221
222         hbox1->set_border_width (6);
223         vbox->set_border_width (6);
224
225         hbox1->pack_start (*default_dir_chooser, false, true);
226         vbox->pack_start (*txt, false, true);
227         vbox->pack_start (*hbox1, false, true);
228
229         string def = Config->get_default_session_parent_dir();
230
231         /* XXX really need glob here */
232
233         if (def == "~") {
234                 def = Glib::get_home_dir();
235         }
236         default_dir_chooser->set_current_folder (def);
237         default_dir_chooser->signal_current_folder_changed().connect (mem_fun (*this, &ArdourStartup::default_dir_changed));
238         default_dir_chooser->show ();
239
240         txt->show ();
241         hbox1->show ();
242         vbox->show ();
243
244         default_folder_page_index = append_page (*vbox);
245         set_page_title (*vbox, _("Default folder for new sessions"));
246         set_page_header_image (*vbox, icon_pixbuf);
247         set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
248
249         /* user can just skip all these settings if they want to */
250
251         set_page_complete (*vbox, true);
252 }
253
254 void
255 ArdourStartup::setup_monitoring_choice_page ()
256 {
257         mon_vbox.set_spacing (6);
258         mon_vbox.set_border_width (6);
259         
260         RadioButton::Group g (monitor_via_hardware_button.get_group());
261         monitor_via_ardour_button.set_group (g);
262
263         monitor_label.set_markup("\
264 While recording instruments or vocals, you probably want to listen to the\n\
265 signal as well as record it. This is called \"monitoring\". There are\n\
266 different ways to do this depending on the equipment you have and the\n\
267 configuration of that equipment. The two most common are presented here.\n\
268 Please choose whichever one is right for your setup.\n\n\
269 <i>You can change this preference at any time, via the Options menu</i>");
270
271         mon_vbox.pack_start (monitor_label, false, false);
272         mon_vbox.pack_start (monitor_via_hardware_button, false, false);
273         mon_vbox.pack_start (monitor_via_ardour_button, false, false);
274
275         mon_vbox.show ();
276         monitor_label.show ();
277         monitor_via_ardour_button.show ();
278         monitor_via_hardware_button.show ();
279
280         monitoring_page_index = append_page (mon_vbox);
281         set_page_title (mon_vbox, _("Monitoring Choices"));
282         set_page_header_image (mon_vbox, icon_pixbuf);
283
284         /* user could just click on "Forward" if default
285          * choice is correct.
286          */
287
288         set_page_complete (mon_vbox, true);
289 }
290
291 void
292 ArdourStartup::setup_initial_choice_page ()
293 {
294         ic_vbox.set_spacing (6);
295         ic_vbox.set_border_width (6);
296
297         RadioButton::Group g (ic_new_session_button.get_group());
298         ic_existing_session_button.set_group (g);
299
300         HBox* centering_hbox = manage (new HBox);
301         VBox* centering_vbox = manage (new VBox);
302         
303         centering_vbox->pack_start (ic_new_session_button, false, true);
304         centering_vbox->pack_start (ic_existing_session_button, false, true);
305         centering_vbox->show ();
306
307         centering_hbox->pack_start (*centering_vbox, true, true);
308         centering_hbox->show ();
309
310         ic_vbox.pack_start (*centering_hbox, true, true);
311
312         ic_new_session_button.show ();
313         ic_existing_session_button.show ();
314         ic_vbox.show ();
315
316         initial_choice_index = append_page (ic_vbox);
317         set_page_title (ic_vbox, _("What would you like to do?"));
318         set_page_header_image (ic_vbox, icon_pixbuf);
319
320         /* user could just click on "Forward" if default
321          * choice is correct.
322          */
323
324         set_page_complete (ic_vbox, true);
325 }
326
327 void
328 ArdourStartup::setup_session_page ()
329 {
330         session_hbox.set_border_width (12);
331         session_vbox.set_border_width (12);
332
333         session_vbox.pack_start (session_hbox, true, true);
334         session_vbox.show ();
335         session_hbox.show ();
336
337         session_page_index = append_page (session_vbox);
338         /* initial setting */
339         set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
340 }
341
342 void
343 ArdourStartup::setup_final_page ()
344 {
345         final_page.set_text ("Ardour is ready for use");
346         final_page.show ();
347         final_page_index = append_page (final_page);
348         set_page_complete (final_page, true);
349         set_page_header_image (final_page, icon_pixbuf);
350         set_page_type (final_page, ASSISTANT_PAGE_CONFIRM);
351 }
352
353 void
354 ArdourStartup::on_cancel ()
355 {
356         exit (1);
357 }
358
359 void
360 ArdourStartup::on_close ()
361 {
362         if (!applying) {
363                 exit (1);
364         }
365 }
366
367 void
368 ArdourStartup::on_apply ()
369 {
370         applying = true;
371
372         // XXX do stuff and then ....
373
374         if (engine_dialog) {
375                 engine_dialog->setup_engine ();
376         }
377
378         if (config_modified) {
379
380                 if (default_dir_chooser) {
381                         Config->set_default_session_parent_dir (default_dir_chooser->get_current_folder());
382                 }
383                 
384                 if (monitor_via_hardware_button.get_active()) {
385                         Config->set_monitoring_model (ExternalMonitoring);
386                 } else if (monitor_via_ardour_button.get_active()) {
387                         Config->set_monitoring_model (SoftwareMonitoring);
388                 }
389                 
390                 Config->save_state ();
391         }
392
393         gtk_main_quit ();
394 }
395
396 void
397 ArdourStartup::on_prepare (Gtk::Widget* page)
398 {
399         if (page == &session_vbox) {
400                 
401                 if (ic_new_session_button.get_active()) {
402                         /* new session requested */
403                         setup_new_session_page ();
404                 } else {
405                         /* existing session requested */
406                         setup_existing_session_page ();
407                 }
408         } 
409 }
410
411 void
412 ArdourStartup::setup_new_session_page ()
413 {
414         if (!session_hbox.get_children().empty()) {
415                 session_hbox.remove (**session_hbox.get_children().begin());
416         }
417
418         if (session_new_vbox.get_children().empty()) {
419                 
420                 HBox* hbox1 = manage (new HBox);
421                 Label* label1 = manage (new Label);
422                 
423                 hbox1->set_spacing (6);
424                 hbox1->pack_start (*label1, false, false);
425                 hbox1->pack_start (new_name_entry, true, true);
426                 
427                 label1->set_text (_("Session name:"));
428                 
429                 hbox1->show();
430                 label1->show();
431                 new_name_entry.show ();
432                 
433                 new_name_entry.signal_changed().connect (mem_fun (*this, &ArdourStartup::new_name_changed));
434                 new_name_entry.signal_activate().connect (mem_fun (*this, &ArdourStartup::move_along_now));
435                 
436                 HBox* hbox2 = manage (new HBox);
437                 Label* label2 = manage (new Label);
438                 
439                 hbox2->set_spacing (6);
440                 hbox2->pack_start (*label2, false, false);
441                 hbox2->pack_start (new_folder_chooser, true, true);
442                 
443                 label2->set_text (_("Create session folder in:"));
444                 
445                 string def = Config->get_default_session_parent_dir();
446                 
447                 /* XXX really need glob here */
448                 
449                 if (def == "~") {
450                         def = Glib::get_home_dir();
451                 }
452
453                 new_folder_chooser.set_current_folder (def);
454                 new_folder_chooser.set_title (_("Select folder for session"));
455                 
456                 hbox2->show();
457                 label2->show();
458                 new_folder_chooser.show ();
459                 
460                 if (is_directory (user_template_directory ())) {
461                         session_template_chooser.set_current_folder (user_template_directory().to_string());
462                 } else if (is_directory (system_template_directory ())) {
463                         session_template_chooser.set_current_folder (system_template_directory().to_string());
464                 } else {
465                         /* hmm, no templates ... what to do? */
466                 }
467                 
468                 if (is_directory (system_template_directory ())) {
469                         session_template_chooser.add_shortcut_folder (system_template_directory().to_string());
470                 }
471                 
472                 HBox* hbox3 = manage (new HBox);
473                 Label* label3 = manage (new Label);
474                 
475                 hbox3->set_spacing (6);
476                 hbox3->pack_start (*label3, false, false);
477                 hbox3->pack_start (session_template_chooser, true, true);
478                 
479                 label3->set_text (_("Use this template:"));
480                 
481                 hbox3->show ();
482                 label3->show ();
483                 session_template_chooser.show ();
484                 
485                 Gtk::FileFilter* template_filter = manage (new (Gtk::FileFilter));
486                 template_filter->add_pattern(X_("*.template"));
487                 session_template_chooser.set_filter (*template_filter);
488                 session_template_chooser.set_title (_("Select template"));
489                 
490                 
491                 HBox* hbox4 = manage (new HBox);
492         
493                 hbox4->set_spacing (6);
494                 hbox4->pack_start (more_new_session_options_button, false, false);
495                 
496                 hbox4->show ();
497                 more_new_session_options_button.show ();
498                 more_new_session_options_button.signal_clicked().connect (mem_fun (*this, &ArdourStartup::more_new_session_options_button_clicked));
499                 session_new_vbox.set_spacing (12);
500         
501                 session_new_vbox.pack_start (*hbox1, false, false);
502                 session_new_vbox.pack_start (*hbox2, false, false);
503                 session_new_vbox.pack_start (*hbox3, false, false);
504                 session_new_vbox.pack_start (*hbox4, false, false);
505         }
506
507         session_new_vbox.show ();
508         session_hbox.pack_start (session_new_vbox, false, false);
509         set_page_title (session_vbox, _("New Session"));
510         set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
511
512         new_name_entry.grab_focus ();
513 }
514
515 void
516 ArdourStartup::new_name_changed ()
517 {
518         if (!new_name_entry.get_text().empty()) {
519                 set_page_complete (session_vbox, true);
520         } else {
521                 set_page_complete (session_vbox, false);
522         }
523 }
524
525 void
526 ArdourStartup::redisplay_recent_sessions ()
527 {
528         std::vector<sys::path> session_directories;
529         RecentSessionsSorter cmp;
530         
531         recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
532         recent_session_model->clear ();
533
534         ARDOUR::RecentSessions rs;
535         ARDOUR::read_recent_sessions (rs);
536
537         if (rs.empty()) {
538                 recent_session_display.set_model (recent_session_model);
539                 return;
540         }
541         //
542         // sort them alphabetically
543         sort (rs.begin(), rs.end(), cmp);
544         
545         for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
546                 session_directories.push_back ((*i).second);
547         }
548         
549         for (vector<sys::path>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
550         {
551                 std::vector<sys::path> state_file_paths;
552
553                 // now get available states for this session
554
555                 get_state_files_in_directory (*i, state_file_paths);
556
557                 vector<string*>* states;
558                 vector<const gchar*> item;
559                 string fullpath = (*i).to_string();
560                 
561                 /* remove any trailing / */
562
563                 if (fullpath[fullpath.length()-1] == '/') {
564                         fullpath = fullpath.substr (0, fullpath.length()-1);
565                 }
566
567                 /* check whether session still exists */
568                 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
569                         /* session doesn't exist */
570                         continue;
571                 }               
572                 
573                 /* now get available states for this session */
574
575                 if ((states = Session::possible_states (fullpath)) == 0) {
576                         /* no state file? */
577                         continue;
578                 }
579           
580                 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
581
582                 Gtk::TreeModel::Row row = *(recent_session_model->append());
583
584                 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
585                 row[recent_session_columns.fullpath] = fullpath;
586                 
587                 if (state_file_names.size() > 1) {
588
589                         // add the children
590
591                         for (std::vector<std::string>::iterator i2 = state_file_names.begin();
592                                         i2 != state_file_names.end(); ++i2)
593                         {
594
595                                 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
596
597                                 child_row[recent_session_columns.visible_name] = *i2;
598                                 child_row[recent_session_columns.fullpath] = fullpath;
599                         }
600                 }
601         }
602
603         recent_session_display.set_model (recent_session_model);
604 }
605
606 void
607 ArdourStartup::recent_session_row_selected ()
608 {
609         if (recent_session_display.get_selection()->count_selected_rows() > 0) {
610                 set_page_complete (session_vbox, true);
611         } else {
612                 set_page_complete (session_vbox, false);
613         }
614 }
615
616 void
617 ArdourStartup::setup_existing_session_page ()
618 {
619         if (!session_hbox.get_children().empty()) {
620                 session_hbox.remove (**session_hbox.get_children().begin());
621         }
622
623         if (recent_scroller.get_children().empty()) {
624
625                 recent_session_model = TreeStore::create (recent_session_columns);
626                 recent_session_display.set_model (recent_session_model);
627                 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
628                 recent_session_display.set_headers_visible (false);
629                 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
630                 
631                 recent_session_display.get_selection()->signal_changed().connect (mem_fun (*this, &ArdourStartup::recent_session_row_selected));
632                 
633                 recent_scroller.add (recent_session_display);
634                 recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
635                 
636                 recent_session_display.show();
637         }
638
639         recent_scroller.show();
640         redisplay_recent_sessions ();
641         recent_session_display.signal_row_activated().connect (mem_fun (*this, &ArdourStartup::recent_row_activated));
642
643         session_hbox.pack_start (recent_scroller, true, true);
644         set_page_title (session_vbox, _("Select a session"));
645         set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
646 }
647
648 void
649 ArdourStartup::more_new_session_options_button_clicked ()
650 {
651         if (more_new_session_options_button.get_active()) {
652                 more_options_vbox.show_all ();
653                 set_page_type (more_options_vbox, ASSISTANT_PAGE_CONFIRM);
654                 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
655         } else {
656                 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
657                 more_options_vbox.hide ();
658         }
659 }
660
661 void
662 ArdourStartup::setup_more_options_page ()
663 {
664         more_options_vbox.set_border_width (12);
665
666         _output_limit_count.set_adjustment (_output_limit_count_adj);
667         _input_limit_count.set_adjustment (_input_limit_count_adj);
668         _control_bus_channel_count.set_adjustment (_control_bus_channel_count_adj);
669         _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
670         
671         chan_count_label_1.set_text (_("channels"));
672         chan_count_label_2.set_text (_("channels"));
673         chan_count_label_3.set_text (_("channels"));
674         chan_count_label_4.set_text (_("channels"));
675
676         chan_count_label_1.set_alignment(0,0.5);
677         chan_count_label_1.set_padding(0,0);
678         chan_count_label_1.set_line_wrap(false);
679
680         chan_count_label_2.set_alignment(0,0.5);
681         chan_count_label_2.set_padding(0,0);
682         chan_count_label_2.set_line_wrap(false);
683
684         chan_count_label_3.set_alignment(0,0.5);
685         chan_count_label_3.set_padding(0,0);
686         chan_count_label_3.set_line_wrap(false);
687
688         chan_count_label_4.set_alignment(0,0.5);
689         chan_count_label_4.set_padding(0,0);
690         chan_count_label_4.set_line_wrap(false);
691
692         bus_label.set_markup (_("<b>Busses</b>"));
693         input_label.set_markup (_("<b>Inputs</b>"));
694         output_label.set_markup (_("<b>Outputs</b>"));
695
696         _create_control_bus.set_label (_("Create monitor bus"));
697         _create_control_bus.set_flags(Gtk::CAN_FOCUS);
698         _create_control_bus.set_relief(Gtk::RELIEF_NORMAL);
699         _create_control_bus.set_mode(true);
700         _create_control_bus.set_active(false);
701         _create_control_bus.set_border_width(0);
702
703         _control_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
704         _control_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
705         _control_bus_channel_count.set_numeric(true);
706         _control_bus_channel_count.set_digits(0);
707         _control_bus_channel_count.set_wrap(false);
708         _control_bus_channel_count.set_sensitive(false);
709
710         _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
711         _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
712         _master_bus_channel_count.set_numeric(true);
713         _master_bus_channel_count.set_digits(0);
714         _master_bus_channel_count.set_wrap(false);
715
716         _create_master_bus.set_label (_("Create master bus"));
717         _create_master_bus.set_flags(Gtk::CAN_FOCUS);
718         _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
719         _create_master_bus.set_mode(true);
720         _create_master_bus.set_active(true);
721         _create_master_bus.set_border_width(0);
722
723         advanced_table.set_row_spacings(0);
724         advanced_table.set_col_spacings(0);
725         
726         _connect_inputs.set_label (_("Automatically connect to physical_inputs"));
727         _connect_inputs.set_flags(Gtk::CAN_FOCUS);
728         _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
729         _connect_inputs.set_mode(true);
730         _connect_inputs.set_active(true);
731         _connect_inputs.set_border_width(0);
732         
733         _limit_input_ports.set_label (_("Use only"));
734         _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
735         _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
736         _limit_input_ports.set_mode(true);
737         _limit_input_ports.set_sensitive(true);
738         _limit_input_ports.set_border_width(0);
739
740         _input_limit_count.set_flags(Gtk::CAN_FOCUS);
741         _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
742         _input_limit_count.set_numeric(true);
743         _input_limit_count.set_digits(0);
744         _input_limit_count.set_wrap(false);
745         _input_limit_count.set_sensitive(false);
746
747         bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
748
749         bus_label.set_alignment(0, 0.5);
750         bus_label.set_padding(0,0);
751         bus_label.set_line_wrap(false);
752         bus_label.set_selectable(false);
753         bus_label.set_use_markup(true);
754         bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
755         bus_frame.set_label_align(0,0.5);
756         bus_frame.add(bus_hbox);
757         bus_frame.set_label_widget(bus_label);
758         
759         bus_table.set_row_spacings (0);
760         bus_table.set_col_spacings (0);
761         bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
762         bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
763         bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
764         bus_table.attach (_create_control_bus, 0, 1, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
765         bus_table.attach (_control_bus_channel_count, 1, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
766         bus_table.attach (chan_count_label_2, 2, 3, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
767
768         input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
769         input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
770         input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
771         input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
772         input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
773         input_table.set_row_spacings(0);
774         input_table.set_col_spacings(0);
775         input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
776
777         input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
778
779         input_label.set_alignment(0, 0.5);
780         input_label.set_padding(0,0);
781         input_label.set_line_wrap(false);
782         input_label.set_selectable(false);
783         input_label.set_use_markup(true);
784         input_frame.set_shadow_type(Gtk::SHADOW_NONE);
785         input_frame.set_label_align(0,0.5);
786         input_frame.add(input_hbox);
787         input_frame.set_label_widget(input_label);
788
789         _connect_outputs.set_label (_("Automatically connect outputs"));
790         _connect_outputs.set_flags(Gtk::CAN_FOCUS);
791         _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
792         _connect_outputs.set_mode(true);
793         _connect_outputs.set_active(true);
794         _connect_outputs.set_border_width(0);
795         _limit_output_ports.set_label (_("Use only"));
796         _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
797         _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
798         _limit_output_ports.set_mode(true);
799         _limit_output_ports.set_sensitive(true);
800         _limit_output_ports.set_border_width(0);
801         _output_limit_count.set_flags(Gtk::CAN_FOCUS);
802         _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
803         _output_limit_count.set_numeric(false);
804         _output_limit_count.set_digits(0);
805         _output_limit_count.set_wrap(false);
806         _output_limit_count.set_sensitive(false);
807         output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
808         output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
809         output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
810
811         _connect_outputs_to_master.set_label (_("... to master bus"));
812         _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
813         _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
814         _connect_outputs_to_master.set_mode(true);
815         _connect_outputs_to_master.set_active(false);
816         _connect_outputs_to_master.set_border_width(0);
817
818         _connect_outputs_to_master.set_group (connect_outputs_group);
819         _connect_outputs_to_physical.set_group (connect_outputs_group);
820
821         _connect_outputs_to_physical.set_label (_("... to physical outputs"));
822         _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
823         _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
824         _connect_outputs_to_physical.set_mode(true);
825         _connect_outputs_to_physical.set_active(false);
826         _connect_outputs_to_physical.set_border_width(0);
827
828         output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
829         output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
830         output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
831         output_vbox.set_border_width(6);
832
833         output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
834
835         output_vbox.pack_start(output_conn_vbox);
836         output_vbox.pack_start(output_port_vbox);
837
838         output_label.set_alignment(0, 0.5);
839         output_label.set_padding(0,0);
840         output_label.set_line_wrap(false);
841         output_label.set_selectable(false);
842         output_label.set_use_markup(true);
843         output_frame.set_shadow_type(Gtk::SHADOW_NONE);
844         output_frame.set_label_align(0,0.5);
845
846         output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
847
848         output_frame.add(output_hbox);
849         output_frame.set_label_widget(output_label);
850
851         more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
852         more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
853         more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
854         more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
855
856         /* signals */
857
858         _connect_inputs.signal_clicked().connect (mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
859         _connect_outputs.signal_clicked().connect (mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
860         _limit_input_ports.signal_clicked().connect (mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
861         _limit_output_ports.signal_clicked().connect (mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
862         _create_master_bus.signal_clicked().connect (mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
863         _create_control_bus.signal_clicked().connect (mem_fun (*this, &ArdourStartup::monitor_bus_button_clicked));
864
865         /* note that more_options_vbox is NOT visible by
866          * default. this is entirely by design - this page
867          * should be skipped unless explicitly requested.
868          */
869         
870         session_options_page_index = append_page (more_options_vbox);
871         set_page_title (more_options_vbox, _("Advanced Session Options"));
872         set_page_complete (more_options_vbox, true);
873 }
874
875 bool
876 ArdourStartup::create_master_bus() const
877 {
878         return _create_master_bus.get_active();
879 }
880
881 int
882 ArdourStartup::master_channel_count() const
883 {
884         return _master_bus_channel_count.get_value_as_int();
885 }
886
887 bool
888 ArdourStartup::create_control_bus() const
889 {
890         return _create_control_bus.get_active();
891 }
892
893 int
894 ArdourStartup::control_channel_count() const
895 {
896         return _control_bus_channel_count.get_value_as_int();
897 }
898
899 bool
900 ArdourStartup::connect_inputs() const
901 {
902         return _connect_inputs.get_active();
903 }
904
905 bool
906 ArdourStartup::limit_inputs_used_for_connection() const
907 {
908         return _limit_input_ports.get_active();
909 }
910
911 int
912 ArdourStartup::input_limit_count() const
913 {
914         return _input_limit_count.get_value_as_int();
915 }
916
917 bool
918 ArdourStartup::connect_outputs() const
919 {
920         return _connect_outputs.get_active();
921 }
922
923 bool
924 ArdourStartup::limit_outputs_used_for_connection() const
925 {
926         return _limit_output_ports.get_active();
927 }
928
929 int
930 ArdourStartup::output_limit_count() const
931 {
932         return _output_limit_count.get_value_as_int();
933 }
934
935 bool
936 ArdourStartup::connect_outs_to_master() const
937 {
938         return _connect_outputs_to_master.get_active();
939 }
940
941 bool
942 ArdourStartup::connect_outs_to_physical() const
943 {
944         return _connect_outputs_to_physical.get_active();
945 }
946
947 void
948 ArdourStartup::connect_inputs_clicked ()
949 {
950         _limit_input_ports.set_sensitive(_connect_inputs.get_active());
951
952         if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
953                 _input_limit_count.set_sensitive(true);
954         } else {
955                 _input_limit_count.set_sensitive(false);
956         }
957 }
958
959 void
960 ArdourStartup::connect_outputs_clicked ()
961 {
962         _limit_output_ports.set_sensitive(_connect_outputs.get_active());
963
964         if (_connect_outputs.get_active() && _limit_output_ports.get_active()) {
965                 _output_limit_count.set_sensitive(true);
966         } else {
967                 _output_limit_count.set_sensitive(false);
968         }
969 }
970
971 void
972 ArdourStartup::limit_inputs_clicked ()
973 {
974         _input_limit_count.set_sensitive(_limit_input_ports.get_active());
975 }
976
977 void
978 ArdourStartup::limit_outputs_clicked ()
979 {
980         _output_limit_count.set_sensitive(_limit_output_ports.get_active());
981 }
982
983 void
984 ArdourStartup::master_bus_button_clicked ()
985 {
986         _master_bus_channel_count.set_sensitive(_create_master_bus.get_active());
987 }
988
989 void
990 ArdourStartup::monitor_bus_button_clicked ()
991 {
992         _control_bus_channel_count.set_sensitive(_create_control_bus.get_active());
993 }
994
995 void
996 ArdourStartup::move_along_now ()
997 {
998         gint cur = get_current_page ();
999
1000         if (cur == session_page_index) {
1001                 if (more_new_session_options_button.get_active()) {
1002                         set_current_page (session_options_page_index);
1003                 } else {
1004                         on_apply ();
1005                 }
1006         }
1007 }
1008
1009 void
1010 ArdourStartup::recent_row_activated (const Gtk::TreePath& path, Gtk::TreeViewColumn* col)
1011 {
1012         set_page_complete (session_vbox, true);
1013         move_along_now ();
1014 }