fix math bug with numthreads computation
[ardour2.git] / gtk2_ardour / startup.cc
blobd1fce023b220e9e301fd6086fa5b6c8d103ffe49
1 #include <fstream>
2 #include <algorithm>
4 #include <gtkmm/main.h>
5 #include <gtkmm/filechooser.h>
7 #include "pbd/failed_constructor.h"
8 #include "pbd/file_utils.h"
9 #include "pbd/filesystem.h"
10 #include "pbd/replace_all.h"
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"
18 #include "startup.h"
19 #include "opts.h"
20 #include "engine_dialog.h"
21 #include "i18n.h"
23 using namespace std;
24 using namespace Gtk;
25 using namespace Gdk;
26 using namespace Glib;
27 using namespace PBD;
28 using namespace ARDOUR;
30 ArdourStartup* ArdourStartup::the_startup = 0;
32 static string poor_mans_glob (string path)
34 string copy = path;
35 replace_all (copy, "~", Glib::get_home_dir());
36 return copy;
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 (string_compose (_("Ask %1 to playback material as it is being recorded"), PROGRAM_NAME))
47 , use_monitor_section_button (_("Use a monitor bus in new sessions (more complex, more control)"))
48 , no_monitor_section_button (_("Just use the master out bus (simpler, less control)"))
49 , new_folder_chooser (FILE_CHOOSER_ACTION_SELECT_FOLDER)
50 , more_new_session_options_button (_("I'd like more options for this session"))
51 , _output_limit_count_adj (1, 0, 100, 1, 10, 0)
52 , _input_limit_count_adj (1, 0, 100, 1, 10, 0)
53 , _master_bus_channel_count_adj (2, 0, 100, 1, 10, 0)
56 audio_page_index = -1;
57 initial_choice_index = -1;
58 new_user_page_index = -1;
59 default_folder_page_index = -1;
60 monitoring_page_index = -1;
61 session_page_index = -1;
62 final_page_index = -1;
63 session_options_page_index = -1;
64 new_only = false;
66 engine_dialog = 0;
67 config_modified = false;
68 default_dir_chooser = 0;
70 use_template_button.set_group (session_template_group);
71 use_session_as_template_button.set_group (session_template_group);
73 set_keep_above (true);
74 set_resizable (false);
75 set_position (WIN_POS_CENTER);
76 set_border_width (12);
78 sys::path icon_file;
80 if (!find_file_in_search_path (ardour_search_path() + system_data_search_path().add_subdirectory_to_paths("icons"), "ardour_icon_48px.png", icon_file)) {
81 throw failed_constructor();
84 try {
85 icon_pixbuf = Gdk::Pixbuf::create_from_file (icon_file.to_string());
88 catch (...) {
89 throw failed_constructor();
92 sys::path been_here_before = user_config_directory();
93 been_here_before /= ".a3"; // XXXX use more specific version so we can catch upgrades
94 new_user = !exists (been_here_before);
96 bool need_audio_setup = !EngineControl::engine_running();
98 if (new_user) {
99 /* "touch" the file */
100 ofstream fout (been_here_before.to_string().c_str());
101 setup_new_user_page ();
102 setup_first_time_config_page ();
103 setup_monitoring_choice_page ();
104 setup_monitor_section_choice_page ();
106 if (need_audio_setup) {
107 setup_audio_page ();
110 } else {
112 if (need_audio_setup) {
113 setup_audio_page ();
116 setup_initial_choice_page ();
119 setup_session_page ();
120 setup_more_options_page ();
122 if (new_user) {
123 setup_final_page ();
126 the_startup = this;
129 ArdourStartup::~ArdourStartup ()
133 void
134 ArdourStartup::set_new_only (bool yn)
136 new_only = yn;
138 if (new_only) {
139 ic_vbox.hide ();
140 } else {
141 ic_vbox.show ();
145 void
146 ArdourStartup::set_load_template( string load_template )
148 use_template_button.set_active( false );
149 load_template_override = load_template;
152 bool
153 ArdourStartup::use_session_template ()
155 if (!load_template_override.empty())
156 return true;
158 if (use_template_button.get_active()) {
159 return template_chooser.get_active_row_number() > 0;
160 } else {
161 return !session_template_chooser.get_filename().empty();
165 Glib::ustring
166 ArdourStartup::session_template_name ()
168 if (!load_template_override.empty()) {
169 string the_path = (ARDOUR::user_template_directory()/ (load_template_override + ".template")).to_string();
170 return the_path;
173 if (ic_existing_session_button.get_active()) {
174 return ustring();
177 if (use_template_button.get_active()) {
178 TreeModel::iterator iter = template_chooser.get_active ();
179 TreeModel::Row row = (*iter);
180 string s = row[session_template_columns.path];
181 return s;
182 } else {
183 return session_template_chooser.get_filename();
188 Glib::ustring
189 ArdourStartup::session_name (bool& should_be_new)
191 if (ic_new_session_button.get_active()) {
192 should_be_new = true;
193 return new_name_entry.get_text ();
194 } else {
195 should_be_new = false;
197 TreeIter iter = recent_session_display.get_selection()->get_selected();
199 if (iter) {
200 return (*iter)[recent_session_columns.visible_name];
203 return "";
207 Glib::ustring
208 ArdourStartup::session_folder ()
210 if (ic_new_session_button.get_active()) {
211 Glib::ustring legal_session_folder_name = legalize_for_path (new_name_entry.get_text());
212 return Glib::build_filename (new_folder_chooser.get_current_folder(), legal_session_folder_name);
213 } else {
214 TreeIter iter = recent_session_display.get_selection()->get_selected();
216 if (iter) {
217 return (*iter)[recent_session_columns.fullpath];
219 return "";
223 void
224 ArdourStartup::setup_audio_page ()
226 engine_dialog = manage (new EngineControl);
228 engine_dialog->set_border_width (12);
230 engine_dialog->show_all ();
232 audio_page_index = append_page (*engine_dialog);
233 set_page_type (*engine_dialog, ASSISTANT_PAGE_CONTENT);
234 set_page_title (*engine_dialog, _("Audio Setup"));
236 /* the default parameters should work, so the page is potentially complete */
238 set_page_complete (*engine_dialog, true);
241 void
242 ArdourStartup::setup_new_user_page ()
244 Label* foomatic = manage (new Label);
246 foomatic->set_markup (string_compose (_("\
247 <span size=\"larger\">%1 is a digital audio workstation. You can use it to\n\
248 record, edit and mix multi-track audio. You can produce your\n\
249 own CDs, mix video soundtracks, or just experiment with new\n\
250 ideas about music and sound.\n\
252 There are a few things that need to configured before you start\n\
253 using the program.</span>\
254 "), PROGRAM_NAME));
256 HBox* hbox = manage (new HBox);
257 HBox* vbox = manage (new HBox);
259 vbox->set_border_width (24);
261 hbox->pack_start (*foomatic, true, true);
262 vbox->pack_start (*hbox, true, true);
264 foomatic->show ();
265 hbox->show ();
266 vbox->show ();
268 new_user_page_index = append_page (*vbox);
269 set_page_type (*vbox, ASSISTANT_PAGE_INTRO);
270 set_page_title (*vbox, _("Welcome to Ardour"));
271 set_page_header_image (*vbox, icon_pixbuf);
272 set_page_complete (*vbox, true);
275 void
276 ArdourStartup::default_dir_changed ()
278 Config->set_default_session_parent_dir (default_dir_chooser->get_current_folder());
279 config_changed ();
282 void
283 ArdourStartup::config_changed ()
285 config_modified = true;
288 void
289 ArdourStartup::setup_first_time_config_page ()
291 default_dir_chooser = manage (new FileChooserButton (string_compose (_("Default folder for %1 sessions"), PROGRAM_NAME),
292 FILE_CHOOSER_ACTION_SELECT_FOLDER));
293 Gtk::Label* txt = manage (new Label);
294 HBox* hbox = manage (new HBox);
295 VBox* vbox = manage (new VBox);
297 txt->set_markup (_("\
298 Each project that you work on with Ardour has its own folder.\n\
299 These can require a lot of disk space if you are recording audio.\n\
301 Where would you like new Ardour sessions to be stored by default?\n\n\
302 <i>(You can put new sessions anywhere, this is just a default)</i>"));
303 txt->set_alignment (0.0, 0.0);
305 vbox->set_spacing (18);
306 vbox->set_border_width (24);
308 hbox->pack_start (*default_dir_chooser, false, true, 8);
309 vbox->pack_start (*txt, false, false);
310 vbox->pack_start (*hbox, false, true);
312 default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
313 default_dir_chooser->signal_current_folder_changed().connect (sigc::mem_fun (*this, &ArdourStartup::default_dir_changed));
314 default_dir_chooser->show ();
316 vbox->show_all ();
318 default_folder_page_index = append_page (*vbox);
319 set_page_title (*vbox, _("Default folder for new sessions"));
320 set_page_header_image (*vbox, icon_pixbuf);
321 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
323 /* user can just skip all these settings if they want to */
325 set_page_complete (*vbox, true);
328 void
329 ArdourStartup::setup_monitoring_choice_page ()
331 mon_vbox.set_spacing (18);
332 mon_vbox.set_border_width (24);
334 HBox* hbox = manage (new HBox);
335 VBox* vbox = manage (new VBox);
336 RadioButton::Group g (monitor_via_hardware_button.get_group());
337 monitor_via_ardour_button.set_group (g);
339 monitor_label.set_markup("\
340 While recording instruments or vocals, you probably want to listen to the\n\
341 signal as well as record it. This is called \"monitoring\". There are\n\
342 different ways to do this depending on the equipment you have and the\n\
343 configuration of that equipment. The two most common are presented here.\n\
344 Please choose whichever one is right for your setup.\n\n\
345 <i>(You can change this preference at any time, via the Preferences dialog)</i>");
346 monitor_label.set_alignment (0.0, 0.0);
348 vbox->set_spacing (6);
350 vbox->pack_start (monitor_via_hardware_button, false, true);
351 vbox->pack_start (monitor_via_ardour_button, false, true);
352 hbox->pack_start (*vbox, true, true, 8);
353 mon_vbox.pack_start (monitor_label, false, false);
354 mon_vbox.pack_start (*hbox, false, false);
356 mon_vbox.show_all ();
358 monitoring_page_index = append_page (mon_vbox);
359 set_page_title (mon_vbox, _("Monitoring Choices"));
360 set_page_header_image (mon_vbox, icon_pixbuf);
362 /* user could just click on "Forward" if default
363 * choice is correct.
366 set_page_complete (mon_vbox, true);
369 void
370 ArdourStartup::setup_monitor_section_choice_page ()
372 mon_sec_vbox.set_spacing (18);
373 mon_sec_vbox.set_border_width (24);
375 HBox* hbox = manage (new HBox);
376 VBox* vbox = manage (new VBox);
377 RadioButton::Group g (use_monitor_section_button.get_group());
378 no_monitor_section_button.set_group (g);
380 if (Config->get_use_monitor_bus()) {
381 use_monitor_section_button.set_active (true);
382 } else {
383 no_monitor_section_button.set_active (true);
386 use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
387 no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
389 monitor_section_label.set_markup("\
390 When connecting speakers to Ardour, would you prefer to use a monitor bus,\n\
391 which will offer various kinds of control at the last stage of output\n\
392 or would you prefer to just connect directly to the master outs?\n\n\
393 Most home studio users will probably want to start <i>without</i> a monitor bus.\n\
394 Those with experience of traditional mixing consoles may prefer to use one.\n\
395 Please choose whichever one is right for your setup.\n\n\
396 <i>(You can change this preference at any time, via the Preferences dialog)</i>");
397 monitor_section_label.set_alignment (0.0, 0.0);
399 vbox->set_spacing (6);
401 vbox->pack_start (no_monitor_section_button, false, true);
402 vbox->pack_start (use_monitor_section_button, false, true);
403 hbox->pack_start (*vbox, true, true, 8);
404 mon_sec_vbox.pack_start (monitor_section_label, false, false);
405 mon_sec_vbox.pack_start (*hbox, false, false);
407 mon_sec_vbox.show_all ();
409 monitor_section_page_index = append_page (mon_sec_vbox);
410 set_page_title (mon_sec_vbox, _("Monitor Section"));
411 set_page_header_image (mon_sec_vbox, icon_pixbuf);
413 /* user could just click on "Forward" if default
414 * choice is correct.
417 set_page_complete (mon_sec_vbox, true);
420 void
421 ArdourStartup::setup_initial_choice_page ()
423 ic_vbox.set_spacing (6);
424 ic_vbox.set_border_width (24);
426 RadioButton::Group g (ic_new_session_button.get_group());
427 ic_existing_session_button.set_group (g);
429 HBox* centering_hbox = manage (new HBox);
430 VBox* centering_vbox = manage (new VBox);
432 centering_vbox->set_spacing (6);
434 centering_vbox->pack_start (ic_new_session_button, false, true);
435 centering_vbox->pack_start (ic_existing_session_button, false, true);
437 ic_new_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_press), false);
438 ic_new_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
440 ic_existing_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_press), false);
441 ic_existing_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
443 centering_hbox->pack_start (*centering_vbox, true, true);
445 ic_vbox.pack_start (*centering_hbox, true, true);
447 ic_vbox.show_all ();
449 initial_choice_index = append_page (ic_vbox);
450 set_page_title (ic_vbox, _("What would you like to do ?"));
451 set_page_header_image (ic_vbox, icon_pixbuf);
453 /* user could just click on "Forward" if default
454 * choice is correct.
457 set_page_complete (ic_vbox, true);
460 bool
461 ArdourStartup::initial_button_press (GdkEventButton *event)
463 if (event && event->type == GDK_2BUTTON_PRESS && session_page_index != -1)
465 set_current_page(session_page_index);
466 return true;
467 } else {
468 return false;
472 void
473 ArdourStartup::initial_button_activated ()
475 set_current_page(session_page_index);
478 void
479 ArdourStartup::setup_session_page ()
481 session_vbox.set_border_width (24);
483 session_vbox.pack_start (session_hbox, true, true);
484 session_vbox.show_all ();
486 session_page_index = append_page (session_vbox);
487 /* initial setting */
488 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
491 void
492 ArdourStartup::setup_final_page ()
494 final_page.set_text (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
495 final_page.show ();
496 final_page_index = append_page (final_page);
497 set_page_complete (final_page, true);
498 set_page_header_image (final_page, icon_pixbuf);
499 set_page_type (final_page, ASSISTANT_PAGE_CONFIRM);
502 void
503 ArdourStartup::on_cancel ()
505 _response = RESPONSE_CANCEL;
506 gtk_main_quit ();
509 bool
510 ArdourStartup::on_delete_event (GdkEventAny*)
512 _response = RESPONSE_CLOSE;
513 gtk_main_quit ();
514 return true;
517 void
518 ArdourStartup::on_apply ()
520 if (engine_dialog) {
521 engine_dialog->setup_engine ();
524 if (config_modified) {
526 if (default_dir_chooser) {
527 Config->set_default_session_parent_dir (default_dir_chooser->get_current_folder());
530 if (monitor_via_hardware_button.get_active()) {
531 Config->set_monitoring_model (ExternalMonitoring);
532 } else if (monitor_via_ardour_button.get_active()) {
533 Config->set_monitoring_model (SoftwareMonitoring);
536 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
538 Config->save_state ();
541 _response = RESPONSE_OK;
542 gtk_main_quit ();
545 void
546 ArdourStartup::on_prepare (Gtk::Widget* page)
548 if (page == &session_vbox) {
550 if (ic_new_session_button.get_active()) {
551 /* new session requested */
552 setup_new_session_page ();
553 } else {
554 /* existing session requested */
555 setup_existing_session_page ();
560 void
561 ArdourStartup::populate_session_templates ()
563 vector<TemplateInfo> templates;
565 find_session_templates (templates);
567 template_model->clear ();
569 for (vector<TemplateInfo>::iterator x = templates.begin(); x != templates.end(); ++x) {
570 TreeModel::Row row;
572 row = *(template_model->append ());
574 row[session_template_columns.name] = (*x).name;
575 row[session_template_columns.path] = (*x).path;
579 static bool
580 lost_name_entry_focus (GdkEventFocus* ev)
582 cerr << "lost focus\n";
583 return false;
586 void
587 ArdourStartup::setup_new_session_page ()
589 if (!session_hbox.get_children().empty()) {
590 session_hbox.remove (**session_hbox.get_children().begin());
593 session_new_vbox.set_spacing (18);
595 if (session_new_vbox.get_children().empty()) {
596 VBox *vbox1 = manage (new VBox);
597 HBox* hbox1 = manage (new HBox);
598 Label* label1 = manage (new Label);
600 vbox1->set_spacing (6);
602 hbox1->set_spacing (6);
603 hbox1->pack_start (*label1, false, false);
604 hbox1->pack_start (new_name_entry, true, true);
606 label1->set_text (_("Session name:"));
609 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
610 new_name_entry.set_text (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
611 /* name provided - they can move right along */
612 set_page_complete (session_vbox, true);
615 new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_changed));
616 new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &ArdourStartup::move_along_now));
618 vbox1->pack_start (*hbox1, true, true);
620 /* --- */
622 HBox* hbox2 = manage (new HBox);
623 Label* label2 = manage (new Label);
625 hbox2->set_spacing (6);
626 hbox2->pack_start (*label2, false, false);
627 hbox2->pack_start (new_folder_chooser, true, true);
629 label2->set_text (_("Create session folder in:"));
631 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
632 new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
633 } else {
634 new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
636 new_folder_chooser.set_title (_("Select folder for session"));
638 vbox1->pack_start (*hbox2, false, false);
640 session_new_vbox.pack_start (*vbox1, false, false);
642 /* --- */
644 VBox *vbox2 = manage (new VBox);
645 HBox* hbox3 = manage (new HBox);
646 Label* label3 = manage (new Label);
647 template_model = ListStore::create (session_template_columns);
648 populate_session_templates ();
650 vbox2->set_spacing (6);
652 label3->set_markup (_("<b>Options</b>"));
653 label3->set_alignment (0.0, 0.0);
655 vbox2->pack_start (*label3, false, true);
657 VBox *vbox3 = manage (new VBox);
659 vbox3->set_spacing (6);
661 if (!template_model->children().empty()) {
663 HBox* hbox4a = manage (new HBox);
664 use_template_button.set_label (_("Use this template"));
666 TreeModel::Row row = *template_model->prepend ();
667 row[session_template_columns.name] = (_("no template"));
668 row[session_template_columns.path] = string();
670 hbox4a->set_spacing (6);
671 hbox4a->pack_start (use_template_button, false, false);
672 hbox4a->pack_start (template_chooser, true, true);
674 template_chooser.set_model (template_model);
676 Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
677 text_renderer->property_editable() = false;
679 template_chooser.pack_start (*text_renderer);
680 template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
681 template_chooser.set_active (0);
683 use_template_button.show();
684 template_chooser.show ();
686 vbox3->pack_start (*hbox4a, false, false);
689 /* --- */
691 if (!new_user) {
692 session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
694 HBox* hbox4b = manage (new HBox);
695 use_session_as_template_button.set_label (_("Use an existing session as a template:"));
697 hbox4b->set_spacing (6);
698 hbox4b->pack_start (use_session_as_template_button, false, false);
699 hbox4b->pack_start (session_template_chooser, true, true);
701 use_session_as_template_button.show ();
702 session_template_chooser.show ();
704 Gtk::FileFilter* template_filter = manage (new (Gtk::FileFilter));
705 template_filter->add_pattern(X_("*.template"));
706 session_template_chooser.set_filter (*template_filter);
707 session_template_chooser.set_title (_("Select template"));
709 vbox3->pack_start (*hbox4b, false, false);
712 /* --- */
714 HBox* hbox5 = manage (new HBox);
716 hbox5->set_spacing (6);
717 hbox5->pack_start (more_new_session_options_button, false, false);
719 more_new_session_options_button.show ();
720 more_new_session_options_button.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::more_new_session_options_button_clicked));
722 vbox3->pack_start (*hbox5, false, false);
723 hbox3->pack_start (*vbox3, true, true, 8);
724 vbox2->pack_start (*hbox3, false, false);
726 /* --- */
728 session_new_vbox.pack_start (*vbox2, false, false);
731 session_new_vbox.show_all ();
732 session_hbox.pack_start (session_new_vbox, true, true);
733 set_page_title (session_vbox, _("New Session"));
734 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
736 new_name_entry.signal_map().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_mapped));
737 new_name_entry.signal_focus_out_event().connect (sigc::ptr_fun (lost_name_entry_focus));
740 void
741 ArdourStartup::new_name_mapped ()
743 cerr << "Grab new name focus\n";
744 new_name_entry.grab_focus ();
747 void
748 ArdourStartup::new_name_changed ()
750 if (!new_name_entry.get_text().empty()) {
751 set_page_complete (session_vbox, true);
752 } else {
753 set_page_complete (session_vbox, false);
758 ArdourStartup::redisplay_recent_sessions ()
760 std::vector<sys::path> session_directories;
761 RecentSessionsSorter cmp;
763 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
764 recent_session_model->clear ();
766 ARDOUR::RecentSessions rs;
767 ARDOUR::read_recent_sessions (rs);
769 if (rs.empty()) {
770 recent_session_display.set_model (recent_session_model);
771 return 0;
774 // sort them alphabetically
775 sort (rs.begin(), rs.end(), cmp);
777 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
778 session_directories.push_back ((*i).second);
781 for (vector<sys::path>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
783 std::vector<sys::path> state_file_paths;
785 // now get available states for this session
787 get_state_files_in_directory (*i, state_file_paths);
789 vector<string*>* states;
790 vector<const gchar*> item;
791 string fullpath = (*i).to_string();
793 /* remove any trailing / */
795 if (fullpath[fullpath.length()-1] == '/') {
796 fullpath = fullpath.substr (0, fullpath.length()-1);
799 /* check whether session still exists */
800 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
801 /* session doesn't exist */
802 continue;
805 /* now get available states for this session */
807 if ((states = Session::possible_states (fullpath)) == 0) {
808 /* no state file? */
809 continue;
812 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
814 Gtk::TreeModel::Row row = *(recent_session_model->append());
816 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
817 row[recent_session_columns.fullpath] = fullpath;
819 if (state_file_names.size() > 1) {
821 // add the children
823 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
824 i2 != state_file_names.end(); ++i2)
827 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
829 child_row[recent_session_columns.visible_name] = *i2;
830 child_row[recent_session_columns.fullpath] = fullpath;
835 recent_session_display.set_model (recent_session_model);
836 return rs.size();
839 void
840 ArdourStartup::recent_session_row_selected ()
842 if (recent_session_display.get_selection()->count_selected_rows() > 0) {
843 set_page_complete (session_vbox, true);
844 } else {
845 set_page_complete (session_vbox, false);
849 void
850 ArdourStartup::setup_existing_session_page ()
852 if (!session_hbox.get_children().empty()) {
853 session_hbox.remove (**session_hbox.get_children().begin());
856 if (recent_scroller.get_children().empty()) {
858 recent_session_model = TreeStore::create (recent_session_columns);
859 recent_session_display.set_model (recent_session_model);
860 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
861 recent_session_display.set_headers_visible (false);
862 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
864 recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::recent_session_row_selected));
866 recent_scroller.add (recent_session_display);
867 recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
868 recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
870 recent_session_display.show();
873 recent_scroller.show();
874 int cnt = redisplay_recent_sessions ();
875 recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ArdourStartup::recent_row_activated));
877 if (cnt > 4) {
878 recent_scroller.set_size_request (-1, 300);
881 session_hbox.pack_start (recent_scroller, true, true);
882 set_page_title (session_vbox, _("Select a session"));
883 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
886 void
887 ArdourStartup::more_new_session_options_button_clicked ()
889 if (more_new_session_options_button.get_active()) {
890 more_options_vbox.show_all ();
891 set_page_type (more_options_vbox, ASSISTANT_PAGE_CONFIRM);
892 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
893 } else {
894 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
895 more_options_vbox.hide ();
899 void
900 ArdourStartup::setup_more_options_page ()
902 more_options_vbox.set_border_width (24);
904 _output_limit_count.set_adjustment (_output_limit_count_adj);
905 _input_limit_count.set_adjustment (_input_limit_count_adj);
906 _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
908 chan_count_label_1.set_text (_("channels"));
909 chan_count_label_3.set_text (_("channels"));
910 chan_count_label_4.set_text (_("channels"));
912 chan_count_label_1.set_alignment(0,0.5);
913 chan_count_label_1.set_padding(0,0);
914 chan_count_label_1.set_line_wrap(false);
916 chan_count_label_3.set_alignment(0,0.5);
917 chan_count_label_3.set_padding(0,0);
918 chan_count_label_3.set_line_wrap(false);
920 chan_count_label_4.set_alignment(0,0.5);
921 chan_count_label_4.set_padding(0,0);
922 chan_count_label_4.set_line_wrap(false);
924 bus_label.set_markup (_("<b>Busses</b>"));
925 input_label.set_markup (_("<b>Inputs</b>"));
926 output_label.set_markup (_("<b>Outputs</b>"));
928 _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
929 _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
930 _master_bus_channel_count.set_numeric(true);
931 _master_bus_channel_count.set_digits(0);
932 _master_bus_channel_count.set_wrap(false);
934 _create_master_bus.set_label (_("Create master bus"));
935 _create_master_bus.set_flags(Gtk::CAN_FOCUS);
936 _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
937 _create_master_bus.set_mode(true);
938 _create_master_bus.set_active(true);
939 _create_master_bus.set_border_width(0);
941 advanced_table.set_row_spacings(0);
942 advanced_table.set_col_spacings(0);
944 _connect_inputs.set_label (_("Automatically connect to physical_inputs"));
945 _connect_inputs.set_flags(Gtk::CAN_FOCUS);
946 _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
947 _connect_inputs.set_mode(true);
948 _connect_inputs.set_active(true);
949 _connect_inputs.set_border_width(0);
951 _limit_input_ports.set_label (_("Use only"));
952 _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
953 _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
954 _limit_input_ports.set_mode(true);
955 _limit_input_ports.set_sensitive(true);
956 _limit_input_ports.set_border_width(0);
958 _input_limit_count.set_flags(Gtk::CAN_FOCUS);
959 _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
960 _input_limit_count.set_numeric(true);
961 _input_limit_count.set_digits(0);
962 _input_limit_count.set_wrap(false);
963 _input_limit_count.set_sensitive(false);
965 bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
967 bus_label.set_alignment(0, 0.5);
968 bus_label.set_padding(0,0);
969 bus_label.set_line_wrap(false);
970 bus_label.set_selectable(false);
971 bus_label.set_use_markup(true);
972 bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
973 bus_frame.set_label_align(0,0.5);
974 bus_frame.add(bus_hbox);
975 bus_frame.set_label_widget(bus_label);
977 bus_table.set_row_spacings (0);
978 bus_table.set_col_spacings (0);
979 bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
980 bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
981 bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
983 input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
984 input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
985 input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
986 input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
987 input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
988 input_table.set_row_spacings(0);
989 input_table.set_col_spacings(0);
990 input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
992 input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
994 input_label.set_alignment(0, 0.5);
995 input_label.set_padding(0,0);
996 input_label.set_line_wrap(false);
997 input_label.set_selectable(false);
998 input_label.set_use_markup(true);
999 input_frame.set_shadow_type(Gtk::SHADOW_NONE);
1000 input_frame.set_label_align(0,0.5);
1001 input_frame.add(input_hbox);
1002 input_frame.set_label_widget(input_label);
1004 _connect_outputs.set_label (_("Automatically connect outputs"));
1005 _connect_outputs.set_flags(Gtk::CAN_FOCUS);
1006 _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
1007 _connect_outputs.set_mode(true);
1008 _connect_outputs.set_active(true);
1009 _connect_outputs.set_border_width(0);
1010 _limit_output_ports.set_label (_("Use only"));
1011 _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
1012 _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
1013 _limit_output_ports.set_mode(true);
1014 _limit_output_ports.set_sensitive(true);
1015 _limit_output_ports.set_border_width(0);
1016 _output_limit_count.set_flags(Gtk::CAN_FOCUS);
1017 _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1018 _output_limit_count.set_numeric(false);
1019 _output_limit_count.set_digits(0);
1020 _output_limit_count.set_wrap(false);
1021 _output_limit_count.set_sensitive(false);
1022 output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
1023 output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
1024 output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
1026 _connect_outputs_to_master.set_label (_("... to master bus"));
1027 _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
1028 _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
1029 _connect_outputs_to_master.set_mode(true);
1030 _connect_outputs_to_master.set_active(false);
1031 _connect_outputs_to_master.set_border_width(0);
1033 _connect_outputs_to_master.set_group (connect_outputs_group);
1034 _connect_outputs_to_physical.set_group (connect_outputs_group);
1036 _connect_outputs_to_physical.set_label (_("... to physical outputs"));
1037 _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
1038 _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
1039 _connect_outputs_to_physical.set_mode(true);
1040 _connect_outputs_to_physical.set_active(false);
1041 _connect_outputs_to_physical.set_border_width(0);
1043 output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
1044 output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
1045 output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
1046 output_vbox.set_border_width(6);
1048 output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
1050 output_vbox.pack_start(output_conn_vbox);
1051 output_vbox.pack_start(output_port_vbox);
1053 output_label.set_alignment(0, 0.5);
1054 output_label.set_padding(0,0);
1055 output_label.set_line_wrap(false);
1056 output_label.set_selectable(false);
1057 output_label.set_use_markup(true);
1058 output_frame.set_shadow_type(Gtk::SHADOW_NONE);
1059 output_frame.set_label_align(0,0.5);
1061 output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
1063 output_frame.add(output_hbox);
1064 output_frame.set_label_widget(output_label);
1066 more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
1067 more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
1068 more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
1069 more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
1071 /* signals */
1073 _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
1074 _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
1075 _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
1076 _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
1077 _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
1079 /* note that more_options_vbox is NOT visible by
1080 * default. this is entirely by design - this page
1081 * should be skipped unless explicitly requested.
1084 session_options_page_index = append_page (more_options_vbox);
1085 set_page_title (more_options_vbox, _("Advanced Session Options"));
1086 set_page_complete (more_options_vbox, true);
1089 bool
1090 ArdourStartup::create_master_bus() const
1092 return _create_master_bus.get_active();
1096 ArdourStartup::master_channel_count() const
1098 return _master_bus_channel_count.get_value_as_int();
1101 bool
1102 ArdourStartup::connect_inputs() const
1104 return _connect_inputs.get_active();
1107 bool
1108 ArdourStartup::limit_inputs_used_for_connection() const
1110 return _limit_input_ports.get_active();
1114 ArdourStartup::input_limit_count() const
1116 return _input_limit_count.get_value_as_int();
1119 bool
1120 ArdourStartup::connect_outputs() const
1122 return _connect_outputs.get_active();
1125 bool
1126 ArdourStartup::limit_outputs_used_for_connection() const
1128 return _limit_output_ports.get_active();
1132 ArdourStartup::output_limit_count() const
1134 return _output_limit_count.get_value_as_int();
1137 bool
1138 ArdourStartup::connect_outs_to_master() const
1140 return _connect_outputs_to_master.get_active();
1143 bool
1144 ArdourStartup::connect_outs_to_physical() const
1146 return _connect_outputs_to_physical.get_active();
1149 void
1150 ArdourStartup::connect_inputs_clicked ()
1152 _limit_input_ports.set_sensitive(_connect_inputs.get_active());
1154 if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
1155 _input_limit_count.set_sensitive(true);
1156 } else {
1157 _input_limit_count.set_sensitive(false);
1161 void
1162 ArdourStartup::connect_outputs_clicked ()
1164 _limit_output_ports.set_sensitive(_connect_outputs.get_active());
1166 if (_connect_outputs.get_active() && _limit_output_ports.get_active()) {
1167 _output_limit_count.set_sensitive(true);
1168 } else {
1169 _output_limit_count.set_sensitive(false);
1173 void
1174 ArdourStartup::limit_inputs_clicked ()
1176 _input_limit_count.set_sensitive(_limit_input_ports.get_active());
1179 void
1180 ArdourStartup::limit_outputs_clicked ()
1182 _output_limit_count.set_sensitive(_limit_output_ports.get_active());
1185 void
1186 ArdourStartup::master_bus_button_clicked ()
1188 bool yn = _create_master_bus.get_active();
1190 _master_bus_channel_count.set_sensitive(yn);
1193 void
1194 ArdourStartup::move_along_now ()
1196 gint cur = get_current_page ();
1198 if (cur == session_page_index) {
1199 if (more_new_session_options_button.get_active()) {
1200 set_current_page (session_options_page_index);
1201 } else {
1202 on_apply ();
1207 void
1208 ArdourStartup::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
1210 set_page_complete (session_vbox, true);
1211 move_along_now ();