fix up file renaming code a little bit
[ArdourMidi.git] / gtk2_ardour / startup.cc
blob9789d6d0f76cfa67311d697db0d6814bd8dc1121
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 , 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 , _master_bus_channel_count_adj (2, 0, 100, 1, 10, 0)
54 audio_page_index = -1;
55 initial_choice_index = -1;
56 new_user_page_index = -1;
57 default_folder_page_index = -1;
58 monitoring_page_index = -1;
59 session_page_index = -1;
60 final_page_index = -1;
61 session_options_page_index = -1;
62 new_only = false;
64 engine_dialog = 0;
65 config_modified = false;
66 default_dir_chooser = 0;
68 use_template_button.set_group (session_template_group);
69 use_session_as_template_button.set_group (session_template_group);
71 set_keep_above (true);
72 set_resizable (false);
73 set_position (WIN_POS_CENTER);
74 set_border_width (12);
76 sys::path icon_file;
78 if (!find_file_in_search_path (ardour_search_path() + system_data_search_path().add_subdirectory_to_paths("icons"), "ardour_icon_48px.png", icon_file)) {
79 throw failed_constructor();
82 try {
83 icon_pixbuf = Gdk::Pixbuf::create_from_file (icon_file.to_string());
86 catch (...) {
87 throw failed_constructor();
90 sys::path been_here_before = user_config_directory();
91 been_here_before /= ".a3"; // XXXX use more specific version so we can catch upgrades
92 new_user = !exists (been_here_before);
94 bool need_audio_setup = !EngineControl::engine_running();
96 if (new_user) {
97 /* "touch" the file */
98 ofstream fout (been_here_before.to_string().c_str());
99 setup_new_user_page ();
100 setup_first_time_config_page ();
101 setup_monitoring_choice_page ();
102 setup_monitor_section_choice_page ();
104 if (need_audio_setup) {
105 setup_audio_page ();
108 } else {
110 if (need_audio_setup) {
111 setup_audio_page ();
114 setup_initial_choice_page ();
117 setup_session_page ();
118 setup_more_options_page ();
120 if (new_user) {
121 setup_final_page ();
124 the_startup = this;
127 ArdourStartup::~ArdourStartup ()
131 void
132 ArdourStartup::set_new_only (bool yn)
134 new_only = yn;
136 if (new_only) {
137 ic_vbox.hide ();
138 } else {
139 ic_vbox.show ();
143 void
144 ArdourStartup::set_load_template( string load_template )
146 use_template_button.set_active( false );
147 load_template_override = load_template;
150 bool
151 ArdourStartup::use_session_template ()
153 if (!load_template_override.empty())
154 return true;
156 if (use_template_button.get_active()) {
157 return template_chooser.get_active_row_number() > 0;
158 } else {
159 return !session_template_chooser.get_filename().empty();
163 Glib::ustring
164 ArdourStartup::session_template_name ()
166 if (!load_template_override.empty()) {
167 string the_path = (ARDOUR::user_template_directory()/ (load_template_override + ".template")).to_string();
168 return the_path;
171 if (ic_existing_session_button.get_active()) {
172 return ustring();
175 if (use_template_button.get_active()) {
176 TreeModel::iterator iter = template_chooser.get_active ();
177 TreeModel::Row row = (*iter);
178 string s = row[session_template_columns.path];
179 return s;
180 } else {
181 return session_template_chooser.get_filename();
186 Glib::ustring
187 ArdourStartup::session_name (bool& should_be_new)
189 if (ic_new_session_button.get_active()) {
190 should_be_new = true;
191 return new_name_entry.get_text ();
192 } else {
193 should_be_new = false;
195 TreeIter iter = recent_session_display.get_selection()->get_selected();
197 if (iter) {
198 return (*iter)[recent_session_columns.visible_name];
201 return "";
205 Glib::ustring
206 ArdourStartup::session_folder ()
208 if (ic_new_session_button.get_active()) {
209 Glib::ustring legal_session_folder_name = legalize_for_path (new_name_entry.get_text());
210 return Glib::build_filename (new_folder_chooser.get_current_folder(), legal_session_folder_name);
211 } else {
212 TreeIter iter = recent_session_display.get_selection()->get_selected();
214 if (iter) {
215 return (*iter)[recent_session_columns.fullpath];
217 return "";
221 void
222 ArdourStartup::setup_audio_page ()
224 engine_dialog = manage (new EngineControl);
226 engine_dialog->set_border_width (12);
228 engine_dialog->show_all ();
230 audio_page_index = append_page (*engine_dialog);
231 set_page_type (*engine_dialog, ASSISTANT_PAGE_CONTENT);
232 set_page_title (*engine_dialog, _("Audio Setup"));
234 /* the default parameters should work, so the page is potentially complete */
236 set_page_complete (*engine_dialog, true);
239 void
240 ArdourStartup::setup_new_user_page ()
242 Label* foomatic = manage (new Label);
244 foomatic->set_markup (string_compose (_("\
245 <span size=\"larger\">%1 is a digital audio workstation. You can use it to\n\
246 record, edit and mix multi-track audio. You can produce your\n\
247 own CDs, mix video soundtracks, or just experiment with new\n\
248 ideas about music and sound.\n\
250 There are a few things that need to configured before you start\n\
251 using the program.</span>\
252 "), PROGRAM_NAME));
254 HBox* hbox = manage (new HBox);
255 HBox* vbox = manage (new HBox);
257 vbox->set_border_width (24);
259 hbox->pack_start (*foomatic, true, true);
260 vbox->pack_start (*hbox, true, true);
262 foomatic->show ();
263 hbox->show ();
264 vbox->show ();
266 new_user_page_index = append_page (*vbox);
267 set_page_type (*vbox, ASSISTANT_PAGE_INTRO);
268 set_page_title (*vbox, _("Welcome to Ardour"));
269 set_page_header_image (*vbox, icon_pixbuf);
270 set_page_complete (*vbox, true);
273 void
274 ArdourStartup::default_dir_changed ()
276 Config->set_default_session_parent_dir (default_dir_chooser->get_current_folder());
277 config_changed ();
280 void
281 ArdourStartup::config_changed ()
283 config_modified = true;
286 void
287 ArdourStartup::setup_first_time_config_page ()
289 default_dir_chooser = manage (new FileChooserButton (string_compose (_("Default folder for %1 sessions"), PROGRAM_NAME),
290 FILE_CHOOSER_ACTION_SELECT_FOLDER));
291 Gtk::Label* txt = manage (new Label);
292 HBox* hbox = manage (new HBox);
293 VBox* vbox = manage (new VBox);
295 txt->set_markup (_("\
296 Each project that you work on with Ardour has its own folder.\n\
297 These can require a lot of disk space if you are recording audio.\n\
299 Where would you like new Ardour sessions to be stored by default?\n\n\
300 <i>(You can put new sessions anywhere, this is just a default)</i>"));
301 txt->set_alignment (0.0, 0.0);
303 vbox->set_spacing (18);
304 vbox->set_border_width (24);
306 hbox->pack_start (*default_dir_chooser, false, true, 8);
307 vbox->pack_start (*txt, false, false);
308 vbox->pack_start (*hbox, false, true);
310 default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
311 default_dir_chooser->signal_current_folder_changed().connect (sigc::mem_fun (*this, &ArdourStartup::default_dir_changed));
312 default_dir_chooser->show ();
314 vbox->show_all ();
316 default_folder_page_index = append_page (*vbox);
317 set_page_title (*vbox, _("Default folder for new sessions"));
318 set_page_header_image (*vbox, icon_pixbuf);
319 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
321 /* user can just skip all these settings if they want to */
323 set_page_complete (*vbox, true);
326 void
327 ArdourStartup::setup_monitoring_choice_page ()
329 mon_vbox.set_spacing (18);
330 mon_vbox.set_border_width (24);
332 HBox* hbox = manage (new HBox);
333 VBox* vbox = manage (new VBox);
334 RadioButton::Group g (monitor_via_hardware_button.get_group());
335 monitor_via_ardour_button.set_group (g);
337 monitor_label.set_markup("\
338 While recording instruments or vocals, you probably want to listen to the\n\
339 signal as well as record it. This is called \"monitoring\". There are\n\
340 different ways to do this depending on the equipment you have and the\n\
341 configuration of that equipment. The two most common are presented here.\n\
342 Please choose whichever one is right for your setup.\n\n\
343 <i>(You can change this preference at any time, via the Preferences dialog)</i>");
344 monitor_label.set_alignment (0.0, 0.0);
346 vbox->set_spacing (6);
348 vbox->pack_start (monitor_via_hardware_button, false, true);
349 vbox->pack_start (monitor_via_ardour_button, false, true);
350 hbox->pack_start (*vbox, true, true, 8);
351 mon_vbox.pack_start (monitor_label, false, false);
352 mon_vbox.pack_start (*hbox, false, false);
354 mon_vbox.show_all ();
356 monitoring_page_index = append_page (mon_vbox);
357 set_page_title (mon_vbox, _("Monitoring Choices"));
358 set_page_header_image (mon_vbox, icon_pixbuf);
360 /* user could just click on "Forward" if default
361 * choice is correct.
364 set_page_complete (mon_vbox, true);
367 void
368 ArdourStartup::setup_monitor_section_choice_page ()
370 mon_sec_vbox.set_spacing (18);
371 mon_sec_vbox.set_border_width (24);
373 HBox* hbox = manage (new HBox);
374 VBox* main_vbox = manage (new VBox);
375 VBox* vbox;
376 Label* l = manage (new Label);
378 main_vbox->set_spacing (32);
380 no_monitor_section_button.set_label (_("Use a Master bus directly"));
381 l->set_alignment (0.0, 1.0);
382 l->set_markup(_("Connect the Master bus directly to your hardware outputs.\n\
383 <i>Preferable for simple use</i>."));
385 vbox = manage (new VBox);
386 vbox->set_spacing (6);
387 vbox->pack_start (no_monitor_section_button, false, true);
388 vbox->pack_start (*l, false, true);
390 main_vbox->pack_start (*vbox, false, false);
392 use_monitor_section_button.set_label (_("Use an additional Monitor bus"));
393 l = manage (new Label);
394 l->set_alignment (0.0, 1.0);
395 l->set_text (_("Use a Monitor bus between Master bus and hardware outputs for \n\
396 greater control in monitoring without affecting the mix."));
398 vbox = manage (new VBox);
399 vbox->set_spacing (6);
400 vbox->pack_start (use_monitor_section_button, false, true);
401 vbox->pack_start (*l, false, true);
403 main_vbox->pack_start (*vbox, false, false);
405 RadioButton::Group g (use_monitor_section_button.get_group());
406 no_monitor_section_button.set_group (g);
408 if (Config->get_use_monitor_bus()) {
409 use_monitor_section_button.set_active (true);
410 } else {
411 no_monitor_section_button.set_active (true);
414 use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
415 no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
417 monitor_section_label.set_markup(_("<i><small>(You can change this preference at any time, via the Preferences dialog)</small></i>"));
418 monitor_section_label.set_alignment (0.0, 0.0);
420 hbox->pack_start (*main_vbox, true, true, 8);
421 mon_sec_vbox.pack_start (*hbox, false, false);
422 mon_sec_vbox.pack_start (monitor_section_label, false, false);
424 mon_sec_vbox.show_all ();
426 monitor_section_page_index = append_page (mon_sec_vbox);
427 set_page_title (mon_sec_vbox, _("Monitor Section"));
428 set_page_header_image (mon_sec_vbox, icon_pixbuf);
430 /* user could just click on "Forward" if default
431 * choice is correct.
434 set_page_complete (mon_sec_vbox, true);
437 void
438 ArdourStartup::setup_initial_choice_page ()
440 ic_vbox.set_spacing (6);
441 ic_vbox.set_border_width (24);
443 RadioButton::Group g (ic_new_session_button.get_group());
444 ic_existing_session_button.set_group (g);
446 HBox* centering_hbox = manage (new HBox);
447 VBox* centering_vbox = manage (new VBox);
449 centering_vbox->set_spacing (6);
451 centering_vbox->pack_start (ic_new_session_button, false, true);
452 centering_vbox->pack_start (ic_existing_session_button, false, true);
454 ic_new_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_press), false);
455 ic_new_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
457 ic_existing_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_press), false);
458 ic_existing_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
460 centering_hbox->pack_start (*centering_vbox, true, true);
462 ic_vbox.pack_start (*centering_hbox, true, true);
464 ic_vbox.show_all ();
466 initial_choice_index = append_page (ic_vbox);
467 set_page_title (ic_vbox, _("What would you like to do ?"));
468 set_page_header_image (ic_vbox, icon_pixbuf);
470 /* user could just click on "Forward" if default
471 * choice is correct.
474 set_page_complete (ic_vbox, true);
477 bool
478 ArdourStartup::initial_button_press (GdkEventButton *event)
480 if (event && event->type == GDK_2BUTTON_PRESS && session_page_index != -1)
482 set_current_page(session_page_index);
483 return true;
484 } else {
485 return false;
489 void
490 ArdourStartup::initial_button_activated ()
492 set_current_page(session_page_index);
495 void
496 ArdourStartup::setup_session_page ()
498 session_vbox.set_border_width (24);
500 session_vbox.pack_start (session_hbox, true, true);
501 session_vbox.show_all ();
503 session_page_index = append_page (session_vbox);
504 /* initial setting */
505 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
508 void
509 ArdourStartup::setup_final_page ()
511 final_page.set_text (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
512 final_page.show ();
513 final_page_index = append_page (final_page);
514 set_page_complete (final_page, true);
515 set_page_header_image (final_page, icon_pixbuf);
516 set_page_type (final_page, ASSISTANT_PAGE_CONFIRM);
519 void
520 ArdourStartup::on_cancel ()
522 _response = RESPONSE_CANCEL;
523 gtk_main_quit ();
526 bool
527 ArdourStartup::on_delete_event (GdkEventAny*)
529 _response = RESPONSE_CLOSE;
530 gtk_main_quit ();
531 return true;
534 void
535 ArdourStartup::on_apply ()
537 if (engine_dialog) {
538 engine_dialog->setup_engine ();
541 if (config_modified) {
543 if (default_dir_chooser) {
544 Config->set_default_session_parent_dir (default_dir_chooser->get_current_folder());
547 if (monitor_via_hardware_button.get_active()) {
548 Config->set_monitoring_model (ExternalMonitoring);
549 } else if (monitor_via_ardour_button.get_active()) {
550 Config->set_monitoring_model (SoftwareMonitoring);
553 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
555 Config->save_state ();
558 _response = RESPONSE_OK;
559 gtk_main_quit ();
562 void
563 ArdourStartup::on_prepare (Gtk::Widget* page)
565 if (page == &session_vbox) {
567 if (ic_new_session_button.get_active()) {
568 /* new session requested */
569 setup_new_session_page ();
570 } else {
571 /* existing session requested */
572 setup_existing_session_page ();
577 void
578 ArdourStartup::populate_session_templates ()
580 vector<TemplateInfo> templates;
582 find_session_templates (templates);
584 template_model->clear ();
586 for (vector<TemplateInfo>::iterator x = templates.begin(); x != templates.end(); ++x) {
587 TreeModel::Row row;
589 row = *(template_model->append ());
591 row[session_template_columns.name] = (*x).name;
592 row[session_template_columns.path] = (*x).path;
596 static bool
597 lost_name_entry_focus (GdkEventFocus* ev)
599 cerr << "lost focus\n";
600 return false;
603 void
604 ArdourStartup::setup_new_session_page ()
606 if (!session_hbox.get_children().empty()) {
607 session_hbox.remove (**session_hbox.get_children().begin());
610 session_new_vbox.set_spacing (18);
612 if (session_new_vbox.get_children().empty()) {
613 VBox *vbox1 = manage (new VBox);
614 HBox* hbox1 = manage (new HBox);
615 Label* label1 = manage (new Label);
617 vbox1->set_spacing (6);
619 hbox1->set_spacing (6);
620 hbox1->pack_start (*label1, false, false);
621 hbox1->pack_start (new_name_entry, true, true);
623 label1->set_text (_("Session name:"));
626 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
627 new_name_entry.set_text (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
628 /* name provided - they can move right along */
629 set_page_complete (session_vbox, true);
632 new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_changed));
633 new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &ArdourStartup::move_along_now));
635 vbox1->pack_start (*hbox1, true, true);
637 /* --- */
639 HBox* hbox2 = manage (new HBox);
640 Label* label2 = manage (new Label);
642 hbox2->set_spacing (6);
643 hbox2->pack_start (*label2, false, false);
644 hbox2->pack_start (new_folder_chooser, true, true);
646 label2->set_text (_("Create session folder in:"));
648 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
649 new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
650 } else {
651 new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
653 new_folder_chooser.set_title (_("Select folder for session"));
655 vbox1->pack_start (*hbox2, false, false);
657 session_new_vbox.pack_start (*vbox1, false, false);
659 /* --- */
661 VBox *vbox2 = manage (new VBox);
662 HBox* hbox3 = manage (new HBox);
663 Label* label3 = manage (new Label);
664 template_model = ListStore::create (session_template_columns);
665 populate_session_templates ();
667 vbox2->set_spacing (6);
669 label3->set_markup (_("<b>Options</b>"));
670 label3->set_alignment (0.0, 0.0);
672 vbox2->pack_start (*label3, false, true);
674 VBox *vbox3 = manage (new VBox);
676 vbox3->set_spacing (6);
678 if (!template_model->children().empty()) {
680 HBox* hbox4a = manage (new HBox);
681 use_template_button.set_label (_("Use this template"));
683 TreeModel::Row row = *template_model->prepend ();
684 row[session_template_columns.name] = (_("no template"));
685 row[session_template_columns.path] = string();
687 hbox4a->set_spacing (6);
688 hbox4a->pack_start (use_template_button, false, false);
689 hbox4a->pack_start (template_chooser, true, true);
691 template_chooser.set_model (template_model);
693 Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
694 text_renderer->property_editable() = false;
696 template_chooser.pack_start (*text_renderer);
697 template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
698 template_chooser.set_active (0);
700 use_template_button.show();
701 template_chooser.show ();
703 vbox3->pack_start (*hbox4a, false, false);
706 /* --- */
708 if (!new_user) {
709 session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
711 HBox* hbox4b = manage (new HBox);
712 use_session_as_template_button.set_label (_("Use an existing session as a template:"));
714 hbox4b->set_spacing (6);
715 hbox4b->pack_start (use_session_as_template_button, false, false);
716 hbox4b->pack_start (session_template_chooser, true, true);
718 use_session_as_template_button.show ();
719 session_template_chooser.show ();
721 Gtk::FileFilter* template_filter = manage (new (Gtk::FileFilter));
722 template_filter->add_pattern(X_("*.template"));
723 session_template_chooser.set_filter (*template_filter);
724 session_template_chooser.set_title (_("Select template"));
726 vbox3->pack_start (*hbox4b, false, false);
729 /* --- */
731 HBox* hbox5 = manage (new HBox);
733 hbox5->set_spacing (6);
734 hbox5->pack_start (more_new_session_options_button, false, false);
736 more_new_session_options_button.show ();
737 more_new_session_options_button.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::more_new_session_options_button_clicked));
739 vbox3->pack_start (*hbox5, false, false);
740 hbox3->pack_start (*vbox3, true, true, 8);
741 vbox2->pack_start (*hbox3, false, false);
743 /* --- */
745 session_new_vbox.pack_start (*vbox2, false, false);
748 session_new_vbox.show_all ();
749 session_hbox.pack_start (session_new_vbox, true, true);
750 set_page_title (session_vbox, _("New Session"));
751 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
753 new_name_entry.signal_map().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_mapped));
754 new_name_entry.signal_focus_out_event().connect (sigc::ptr_fun (lost_name_entry_focus));
757 void
758 ArdourStartup::new_name_mapped ()
760 cerr << "Grab new name focus\n";
761 new_name_entry.grab_focus ();
764 void
765 ArdourStartup::new_name_changed ()
767 if (!new_name_entry.get_text().empty()) {
768 set_page_complete (session_vbox, true);
769 } else {
770 set_page_complete (session_vbox, false);
775 ArdourStartup::redisplay_recent_sessions ()
777 std::vector<sys::path> session_directories;
778 RecentSessionsSorter cmp;
780 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
781 recent_session_model->clear ();
783 ARDOUR::RecentSessions rs;
784 ARDOUR::read_recent_sessions (rs);
786 if (rs.empty()) {
787 recent_session_display.set_model (recent_session_model);
788 return 0;
791 // sort them alphabetically
792 sort (rs.begin(), rs.end(), cmp);
794 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
795 session_directories.push_back ((*i).second);
798 for (vector<sys::path>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
800 std::vector<sys::path> state_file_paths;
802 // now get available states for this session
804 get_state_files_in_directory (*i, state_file_paths);
806 vector<string*>* states;
807 vector<const gchar*> item;
808 string fullpath = (*i).to_string();
810 /* remove any trailing / */
812 if (fullpath[fullpath.length()-1] == '/') {
813 fullpath = fullpath.substr (0, fullpath.length()-1);
816 /* check whether session still exists */
817 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
818 /* session doesn't exist */
819 continue;
822 /* now get available states for this session */
824 if ((states = Session::possible_states (fullpath)) == 0) {
825 /* no state file? */
826 continue;
829 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
831 Gtk::TreeModel::Row row = *(recent_session_model->append());
833 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
834 row[recent_session_columns.fullpath] = fullpath;
836 if (state_file_names.size() > 1) {
838 // add the children
840 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
841 i2 != state_file_names.end(); ++i2)
844 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
846 child_row[recent_session_columns.visible_name] = *i2;
847 child_row[recent_session_columns.fullpath] = fullpath;
852 recent_session_display.set_model (recent_session_model);
853 return rs.size();
856 void
857 ArdourStartup::recent_session_row_selected ()
859 if (recent_session_display.get_selection()->count_selected_rows() > 0) {
860 set_page_complete (session_vbox, true);
861 } else {
862 set_page_complete (session_vbox, false);
866 void
867 ArdourStartup::setup_existing_session_page ()
869 if (!session_hbox.get_children().empty()) {
870 session_hbox.remove (**session_hbox.get_children().begin());
873 if (recent_scroller.get_children().empty()) {
875 recent_session_model = TreeStore::create (recent_session_columns);
876 recent_session_display.set_model (recent_session_model);
877 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
878 recent_session_display.set_headers_visible (false);
879 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
881 recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::recent_session_row_selected));
883 recent_scroller.add (recent_session_display);
884 recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
885 recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
887 recent_session_display.show();
890 recent_scroller.show();
891 int cnt = redisplay_recent_sessions ();
892 recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ArdourStartup::recent_row_activated));
894 if (cnt > 4) {
895 recent_scroller.set_size_request (-1, 300);
898 session_hbox.pack_start (recent_scroller, true, true);
899 set_page_title (session_vbox, _("Select a session"));
900 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
903 void
904 ArdourStartup::more_new_session_options_button_clicked ()
906 if (more_new_session_options_button.get_active()) {
907 more_options_vbox.show_all ();
908 set_page_type (more_options_vbox, ASSISTANT_PAGE_CONFIRM);
909 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
910 } else {
911 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
912 more_options_vbox.hide ();
916 void
917 ArdourStartup::setup_more_options_page ()
919 more_options_vbox.set_border_width (24);
921 _output_limit_count.set_adjustment (_output_limit_count_adj);
922 _input_limit_count.set_adjustment (_input_limit_count_adj);
923 _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
925 chan_count_label_1.set_text (_("channels"));
926 chan_count_label_3.set_text (_("channels"));
927 chan_count_label_4.set_text (_("channels"));
929 chan_count_label_1.set_alignment(0,0.5);
930 chan_count_label_1.set_padding(0,0);
931 chan_count_label_1.set_line_wrap(false);
933 chan_count_label_3.set_alignment(0,0.5);
934 chan_count_label_3.set_padding(0,0);
935 chan_count_label_3.set_line_wrap(false);
937 chan_count_label_4.set_alignment(0,0.5);
938 chan_count_label_4.set_padding(0,0);
939 chan_count_label_4.set_line_wrap(false);
941 bus_label.set_markup (_("<b>Busses</b>"));
942 input_label.set_markup (_("<b>Inputs</b>"));
943 output_label.set_markup (_("<b>Outputs</b>"));
945 _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
946 _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
947 _master_bus_channel_count.set_numeric(true);
948 _master_bus_channel_count.set_digits(0);
949 _master_bus_channel_count.set_wrap(false);
951 _create_master_bus.set_label (_("Create master bus"));
952 _create_master_bus.set_flags(Gtk::CAN_FOCUS);
953 _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
954 _create_master_bus.set_mode(true);
955 _create_master_bus.set_active(true);
956 _create_master_bus.set_border_width(0);
958 advanced_table.set_row_spacings(0);
959 advanced_table.set_col_spacings(0);
961 _connect_inputs.set_label (_("Automatically connect to physical_inputs"));
962 _connect_inputs.set_flags(Gtk::CAN_FOCUS);
963 _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
964 _connect_inputs.set_mode(true);
965 _connect_inputs.set_active(true);
966 _connect_inputs.set_border_width(0);
968 _limit_input_ports.set_label (_("Use only"));
969 _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
970 _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
971 _limit_input_ports.set_mode(true);
972 _limit_input_ports.set_sensitive(true);
973 _limit_input_ports.set_border_width(0);
975 _input_limit_count.set_flags(Gtk::CAN_FOCUS);
976 _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
977 _input_limit_count.set_numeric(true);
978 _input_limit_count.set_digits(0);
979 _input_limit_count.set_wrap(false);
980 _input_limit_count.set_sensitive(false);
982 bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
984 bus_label.set_alignment(0, 0.5);
985 bus_label.set_padding(0,0);
986 bus_label.set_line_wrap(false);
987 bus_label.set_selectable(false);
988 bus_label.set_use_markup(true);
989 bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
990 bus_frame.set_label_align(0,0.5);
991 bus_frame.add(bus_hbox);
992 bus_frame.set_label_widget(bus_label);
994 bus_table.set_row_spacings (0);
995 bus_table.set_col_spacings (0);
996 bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
997 bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
998 bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
1000 input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
1001 input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
1002 input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
1003 input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
1004 input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
1005 input_table.set_row_spacings(0);
1006 input_table.set_col_spacings(0);
1007 input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
1009 input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
1011 input_label.set_alignment(0, 0.5);
1012 input_label.set_padding(0,0);
1013 input_label.set_line_wrap(false);
1014 input_label.set_selectable(false);
1015 input_label.set_use_markup(true);
1016 input_frame.set_shadow_type(Gtk::SHADOW_NONE);
1017 input_frame.set_label_align(0,0.5);
1018 input_frame.add(input_hbox);
1019 input_frame.set_label_widget(input_label);
1021 _connect_outputs.set_label (_("Automatically connect outputs"));
1022 _connect_outputs.set_flags(Gtk::CAN_FOCUS);
1023 _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
1024 _connect_outputs.set_mode(true);
1025 _connect_outputs.set_active(true);
1026 _connect_outputs.set_border_width(0);
1027 _limit_output_ports.set_label (_("Use only"));
1028 _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
1029 _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
1030 _limit_output_ports.set_mode(true);
1031 _limit_output_ports.set_sensitive(true);
1032 _limit_output_ports.set_border_width(0);
1033 _output_limit_count.set_flags(Gtk::CAN_FOCUS);
1034 _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1035 _output_limit_count.set_numeric(false);
1036 _output_limit_count.set_digits(0);
1037 _output_limit_count.set_wrap(false);
1038 _output_limit_count.set_sensitive(false);
1039 output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
1040 output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
1041 output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
1043 _connect_outputs_to_master.set_label (_("... to master bus"));
1044 _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
1045 _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
1046 _connect_outputs_to_master.set_mode(true);
1047 _connect_outputs_to_master.set_active(false);
1048 _connect_outputs_to_master.set_border_width(0);
1050 _connect_outputs_to_master.set_group (connect_outputs_group);
1051 _connect_outputs_to_physical.set_group (connect_outputs_group);
1053 _connect_outputs_to_physical.set_label (_("... to physical outputs"));
1054 _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
1055 _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
1056 _connect_outputs_to_physical.set_mode(true);
1057 _connect_outputs_to_physical.set_active(false);
1058 _connect_outputs_to_physical.set_border_width(0);
1060 output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
1061 output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
1062 output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
1063 output_vbox.set_border_width(6);
1065 output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
1067 output_vbox.pack_start(output_conn_vbox);
1068 output_vbox.pack_start(output_port_vbox);
1070 output_label.set_alignment(0, 0.5);
1071 output_label.set_padding(0,0);
1072 output_label.set_line_wrap(false);
1073 output_label.set_selectable(false);
1074 output_label.set_use_markup(true);
1075 output_frame.set_shadow_type(Gtk::SHADOW_NONE);
1076 output_frame.set_label_align(0,0.5);
1078 output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
1080 output_frame.add(output_hbox);
1081 output_frame.set_label_widget(output_label);
1083 more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
1084 more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
1085 more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
1086 more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
1088 /* signals */
1090 _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
1091 _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
1092 _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
1093 _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
1094 _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
1096 /* note that more_options_vbox is NOT visible by
1097 * default. this is entirely by design - this page
1098 * should be skipped unless explicitly requested.
1101 session_options_page_index = append_page (more_options_vbox);
1102 set_page_title (more_options_vbox, _("Advanced Session Options"));
1103 set_page_complete (more_options_vbox, true);
1106 bool
1107 ArdourStartup::create_master_bus() const
1109 return _create_master_bus.get_active();
1113 ArdourStartup::master_channel_count() const
1115 return _master_bus_channel_count.get_value_as_int();
1118 bool
1119 ArdourStartup::connect_inputs() const
1121 return _connect_inputs.get_active();
1124 bool
1125 ArdourStartup::limit_inputs_used_for_connection() const
1127 return _limit_input_ports.get_active();
1131 ArdourStartup::input_limit_count() const
1133 return _input_limit_count.get_value_as_int();
1136 bool
1137 ArdourStartup::connect_outputs() const
1139 return _connect_outputs.get_active();
1142 bool
1143 ArdourStartup::limit_outputs_used_for_connection() const
1145 return _limit_output_ports.get_active();
1149 ArdourStartup::output_limit_count() const
1151 return _output_limit_count.get_value_as_int();
1154 bool
1155 ArdourStartup::connect_outs_to_master() const
1157 return _connect_outputs_to_master.get_active();
1160 bool
1161 ArdourStartup::connect_outs_to_physical() const
1163 return _connect_outputs_to_physical.get_active();
1166 void
1167 ArdourStartup::connect_inputs_clicked ()
1169 _limit_input_ports.set_sensitive(_connect_inputs.get_active());
1171 if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
1172 _input_limit_count.set_sensitive(true);
1173 } else {
1174 _input_limit_count.set_sensitive(false);
1178 void
1179 ArdourStartup::connect_outputs_clicked ()
1181 _limit_output_ports.set_sensitive(_connect_outputs.get_active());
1183 if (_connect_outputs.get_active() && _limit_output_ports.get_active()) {
1184 _output_limit_count.set_sensitive(true);
1185 } else {
1186 _output_limit_count.set_sensitive(false);
1190 void
1191 ArdourStartup::limit_inputs_clicked ()
1193 _input_limit_count.set_sensitive(_limit_input_ports.get_active());
1196 void
1197 ArdourStartup::limit_outputs_clicked ()
1199 _output_limit_count.set_sensitive(_limit_output_ports.get_active());
1202 void
1203 ArdourStartup::master_bus_button_clicked ()
1205 bool yn = _create_master_bus.get_active();
1207 _master_bus_channel_count.set_sensitive(yn);
1210 void
1211 ArdourStartup::move_along_now ()
1213 gint cur = get_current_page ();
1215 if (cur == session_page_index) {
1216 if (more_new_session_options_button.get_active()) {
1217 set_current_page (session_options_page_index);
1218 } else {
1219 on_apply ();
1224 void
1225 ArdourStartup::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
1227 set_page_complete (session_vbox, true);
1228 move_along_now ();