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