2 Copyright (C) 2010 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "gtk2ardour-config.h"
27 #include <gtkmm/main.h>
28 #include <gtkmm/filechooser.h>
30 #include "pbd/failed_constructor.h"
31 #include "pbd/file_utils.h"
32 #include "pbd/replace_all.h"
33 #include "pbd/whitespace.h"
34 #include "pbd/stacktrace.h"
36 #include "ardour/filesystem_paths.h"
37 #include "ardour/recent_sessions.h"
38 #include "ardour/session.h"
39 #include "ardour/session_state_utils.h"
40 #include "ardour/template_utils.h"
41 #include "ardour/filename_extensions.h"
43 #include "ardour_ui.h"
46 #include "engine_dialog.h"
55 using namespace ARDOUR;
57 ArdourStartup* ArdourStartup::the_startup = 0;
59 static string poor_mans_glob (string path)
62 replace_all (copy, "~", Glib::get_home_dir());
66 static void show_me (Gtk::FileChooserButton* fcb)
68 cerr << " Current folder of " << fcb << " changed to " << fcb->get_current_folder() << endl;
72 ArdourStartup::ArdourStartup (bool require_new, const std::string& session_name, const std::string& session_path, const std::string& template_name)
73 : _response (RESPONSE_OK)
74 , config_modified (false)
75 , new_only (require_new)
76 , default_dir_chooser (0)
77 , ic_new_session_button (_("Create a new session"))
78 , ic_existing_session_button (_("Open an existing session"))
79 , monitor_via_hardware_button (_("Use an external mixer or the hardware mixer of your audio interface.\n\
80 Ardour will play NO role in monitoring"))
81 , monitor_via_ardour_button (string_compose (_("Ask %1 to play back material as it is being recorded"), PROGRAM_NAME))
83 , new_folder_chooser (FILE_CHOOSER_ACTION_SELECT_FOLDER)
84 , more_new_session_options_button (_("I'd like more options for this session"))
85 , _output_limit_count_adj (1, 0, 100, 1, 10, 0)
86 , _input_limit_count_adj (1, 0, 100, 1, 10, 0)
87 , _master_bus_channel_count_adj (2, 0, 100, 1, 10, 0)
88 , audio_page_index (-1)
89 , new_user_page_index (-1)
90 , default_folder_page_index (-1)
91 , monitoring_page_index (-1)
92 , session_page_index (-1)
93 , initial_choice_index (-1)
94 , final_page_index (-1)
95 , session_options_page_index (-1)
96 , _existing_session_chooser_used (false)
98 new_user = !Glib::file_test (been_here_before_path(), Glib::FILE_TEST_EXISTS);
99 need_audio_setup = EngineControl::need_setup ();
100 need_session_info = (session_name.empty() || require_new);
102 new_folder_chooser.signal_current_folder_changed().connect (sigc::bind (sigc::ptr_fun (show_me), &new_folder_chooser));
104 _provided_session_name = session_name;
105 _provided_session_path = session_path;
107 if (need_audio_setup || need_session_info || new_user) {
109 use_template_button.set_group (session_template_group);
110 use_session_as_template_button.set_group (session_template_group);
112 set_keep_above (true);
113 set_position (WIN_POS_CENTER);
114 set_border_width (12);
116 if ((icon_pixbuf = ::get_icon ("ardour_icon_48px")) == 0) {
117 throw failed_constructor();
120 list<Glib::RefPtr<Gdk::Pixbuf> > window_icons;
121 Glib::RefPtr<Gdk::Pixbuf> icon;
123 if ((icon = ::get_icon ("ardour_icon_16px")) != 0) {
124 window_icons.push_back (icon);
126 if ((icon = ::get_icon ("ardour_icon_22px")) != 0) {
127 window_icons.push_back (icon);
129 if ((icon = ::get_icon ("ardour_icon_32px")) != 0) {
130 window_icons.push_back (icon);
132 if ((icon = ::get_icon ("ardour_icon_48px")) != 0) {
133 window_icons.push_back (icon);
135 if (!window_icons.empty ()) {
136 set_default_icon_list (window_icons);
139 set_type_hint(Gdk::WINDOW_TYPE_HINT_DIALOG);
141 // setup_prerelease_page ();
145 setup_new_user_page ();
146 setup_first_time_config_page ();
147 setup_monitoring_choice_page ();
148 setup_monitor_section_choice_page ();
150 if (need_audio_setup) {
154 ic_new_session_button.set_active (true); // always create new session on first run
158 if (need_audio_setup) {
162 setup_initial_choice_page ();
165 setup_session_page ();
166 setup_more_options_page ();
178 if (!template_name.empty()) {
179 use_template_button.set_active (false);
180 load_template_override = template_name;
187 ArdourStartup::~ArdourStartup ()
192 ArdourStartup::ready_without_display () const
194 return !new_user && !need_audio_setup && !need_session_info;
198 ArdourStartup::setup_prerelease_page ()
200 VBox* vbox = manage (new VBox);
201 Label* label = manage (new Label);
202 label->set_markup (_("<b>Welcome to this BETA release of Ardour 3.0</b>\n\n\
203 There are still several issues and bugs to be worked on,\n\
204 as well as general workflow improvements, before this can be considered\n\
205 release software. So, a few guidelines:\n\
207 1) Please do <b>NOT</b> use this software with the expectation that it is stable or reliable\n\
208 though it may be so, depending on your workflow.\n\
209 2) Please see http://ardour.org/a3_features for a guide to new features.\n\
210 3) <b>Please do NOT use the forums at ardour.org to report issues</b>.\n\
211 4) Please <b>DO</b> use the bugtracker at http://tracker.ardour.org/ to report issues\n\
212 making sure to note the product version number as 3.0-beta.\n\
213 5) Please <b>DO</b> use the ardour-users mailing list to discuss ideas and pass on comments.\n\
214 6) Please <b>DO</b> join us on IRC for real time discussions about ardour3. You\n\
215 can get there directly from Ardour via the Help->Chat menu option.\n\
217 Full information on all the above can be found on the support page at\n\
219 http://ardour.org/support\n\
222 vbox->set_border_width (12);
223 vbox->pack_start (*label, false, false, 12);
227 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
228 set_page_title (*vbox, _("This is a BETA RELEASE"));
229 set_page_complete (*vbox, true);
233 ArdourStartup::use_session_template ()
235 if (!load_template_override.empty()) {
239 if (use_template_button.get_active()) {
240 return template_chooser.get_active_row_number() > 0;
242 return !session_template_chooser.get_filename().empty();
247 ArdourStartup::session_template_name ()
249 if (!load_template_override.empty()) {
250 string the_path (ARDOUR::user_template_directory());
251 return Glib::build_filename (the_path, load_template_override + ARDOUR::template_suffix);
254 if (ic_existing_session_button.get_active()) {
258 if (use_template_button.get_active()) {
259 TreeModel::iterator iter = template_chooser.get_active ();
260 TreeModel::Row row = (*iter);
261 string s = row[session_template_columns.path];
264 return session_template_chooser.get_filename();
270 ArdourStartup::session_name (bool& should_be_new)
272 if (ready_without_display()) {
273 return _provided_session_name;
276 if (ic_new_session_button.get_active()) {
277 should_be_new = true;
278 string val = new_name_entry.get_text ();
279 strip_whitespace_edges (val);
281 } else if (_existing_session_chooser_used) {
282 /* existing session chosen from file chooser */
283 should_be_new = false;
284 return existing_session_chooser.get_filename ();
286 /* existing session chosen from recent list */
287 should_be_new = false;
289 TreeIter iter = recent_session_display.get_selection()->get_selected();
292 return (*iter)[recent_session_columns.visible_name];
300 ArdourStartup::session_folder ()
302 if (ready_without_display()) {
303 return _provided_session_path;
306 if (ic_new_session_button.get_active()) {
307 std::string legal_session_folder_name = legalize_for_path (new_name_entry.get_text());
308 return Glib::build_filename (new_folder_chooser.get_current_folder(), legal_session_folder_name);
309 } else if (_existing_session_chooser_used) {
310 /* existing session chosen from file chooser */
311 return existing_session_chooser.get_current_folder ();
313 /* existing session chosen from recent list */
314 TreeIter iter = recent_session_display.get_selection()->get_selected();
317 return (*iter)[recent_session_columns.fullpath];
324 ArdourStartup::setup_audio_page ()
326 engine_dialog = manage (new EngineControl);
328 engine_dialog->set_border_width (12);
330 engine_dialog->show_all ();
332 audio_page_index = append_page (*engine_dialog);
333 set_page_type (*engine_dialog, ASSISTANT_PAGE_CONTENT);
334 set_page_title (*engine_dialog, _("Audio / MIDI Setup"));
336 /* the default parameters should work, so the page is potentially complete */
338 set_page_complete (*engine_dialog, true);
342 ArdourStartup::setup_new_user_page ()
344 Label* foomatic = manage (new Label);
346 foomatic->set_markup (string_compose (_("\
347 <span size=\"larger\">%1 is a digital audio workstation. You can use it to \
348 record, edit and mix multi-track audio. You can produce your \
349 own CDs, mix video soundtracks, or experiment with new \
350 ideas about music and sound. \
352 There are a few things that need to be configured before you start \
353 using the program.</span> \
355 foomatic->set_justify (JUSTIFY_FILL);
356 foomatic->set_line_wrap ();
358 HBox* hbox = manage (new HBox);
359 HBox* vbox = manage (new HBox);
361 vbox->set_border_width (24);
363 hbox->pack_start (*foomatic, true, true);
364 vbox->pack_start (*hbox, true, true);
370 new_user_page_index = append_page (*vbox);
371 set_page_type (*vbox, ASSISTANT_PAGE_INTRO);
372 set_page_title (*vbox, string_compose (_("Welcome to %1"), PROGRAM_NAME));
373 set_page_header_image (*vbox, icon_pixbuf);
374 set_page_complete (*vbox, true);
378 ArdourStartup::default_dir_changed ()
380 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
381 // make new session folder chooser point to the new default
382 new_folder_chooser.set_current_folder (Config->get_default_session_parent_dir());
387 ArdourStartup::config_changed ()
389 config_modified = true;
393 ArdourStartup::setup_first_time_config_page ()
395 default_dir_chooser = manage (new FileChooserButton (string_compose (_("Default folder for %1 sessions"), PROGRAM_NAME),
396 FILE_CHOOSER_ACTION_SELECT_FOLDER));
397 Gtk::Label* txt = manage (new Label);
398 HBox* hbox = manage (new HBox);
399 VBox* vbox = manage (new VBox);
401 txt->set_markup (string_compose (_("\
402 Each project that you work on with %1 has its own folder.\n\
403 These can require a lot of disk space if you are recording audio.\n\
405 Where would you like new %1 sessions to be stored by default?\n\n\
406 <i>(You can put new sessions anywhere, this is just a default)</i>"), PROGRAM_NAME));
407 txt->set_alignment (0.0, 0.0);
409 vbox->set_spacing (18);
410 vbox->set_border_width (24);
412 hbox->pack_start (*default_dir_chooser, false, true, 8);
413 vbox->pack_start (*txt, false, false);
414 vbox->pack_start (*hbox, false, true);
416 default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
417 default_dir_chooser->signal_current_folder_changed().connect (sigc::mem_fun (*this, &ArdourStartup::default_dir_changed));
418 default_dir_chooser->show ();
422 default_folder_page_index = append_page (*vbox);
423 set_page_title (*vbox, _("Default folder for new sessions"));
424 set_page_header_image (*vbox, icon_pixbuf);
425 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
427 /* user can just skip all these settings if they want to */
429 set_page_complete (*vbox, true);
433 ArdourStartup::setup_monitoring_choice_page ()
435 mon_vbox.set_spacing (18);
436 mon_vbox.set_border_width (24);
438 HBox* hbox = manage (new HBox);
439 VBox* vbox = manage (new VBox);
440 /* first button will be on by default */
441 RadioButton::Group g (monitor_via_ardour_button.get_group());
442 monitor_via_hardware_button.set_group (g);
444 monitor_label.set_markup(_("\
445 While recording instruments or vocals, you probably want to listen to the\n\
446 signal as well as record it. This is called \"monitoring\". There are\n\
447 different ways to do this depending on the equipment you have and the\n\
448 configuration of that equipment. The two most common are presented here.\n\
449 Please choose whichever one is right for your setup.\n\n\
450 <i>(You can change this preference at any time, via the Preferences dialog)</i>\n\n\
451 <i>If you do not understand what this is about, just accept the default.</i>"));
452 monitor_label.set_alignment (0.0, 0.0);
454 vbox->set_spacing (6);
456 vbox->pack_start (monitor_via_hardware_button, false, true);
457 vbox->pack_start (monitor_via_ardour_button, false, true);
458 hbox->pack_start (*vbox, true, true, 8);
459 mon_vbox.pack_start (monitor_label, false, false);
460 mon_vbox.pack_start (*hbox, false, false);
462 mon_vbox.show_all ();
464 monitoring_page_index = append_page (mon_vbox);
465 set_page_title (mon_vbox, _("Monitoring Choices"));
466 set_page_header_image (mon_vbox, icon_pixbuf);
468 /* user could just click on "Forward" if default
472 set_page_complete (mon_vbox, true);
476 ArdourStartup::setup_monitor_section_choice_page ()
478 mon_sec_vbox.set_spacing (18);
479 mon_sec_vbox.set_border_width (24);
481 HBox* hbox = manage (new HBox);
482 VBox* main_vbox = manage (new VBox);
484 Label* l = manage (new Label);
486 main_vbox->set_spacing (32);
488 no_monitor_section_button.set_label (_("Use a Master bus directly"));
489 l->set_alignment (0.0, 1.0);
490 l->set_markup(_("Connect the Master bus directly to your hardware outputs. This is preferable for simple usage."));
492 vbox = manage (new VBox);
493 vbox->set_spacing (6);
494 vbox->pack_start (no_monitor_section_button, false, true);
495 vbox->pack_start (*l, false, true);
497 main_vbox->pack_start (*vbox, false, false);
499 use_monitor_section_button.set_label (_("Use an additional Monitor bus"));
500 l = manage (new Label);
501 l->set_alignment (0.0, 1.0);
502 l->set_text (_("Use a Monitor bus between Master bus and hardware outputs for \n\
503 greater control in monitoring without affecting the mix."));
505 vbox = manage (new VBox);
506 vbox->set_spacing (6);
507 vbox->pack_start (use_monitor_section_button, false, true);
508 vbox->pack_start (*l, false, true);
510 main_vbox->pack_start (*vbox, false, false);
512 RadioButton::Group g (use_monitor_section_button.get_group());
513 no_monitor_section_button.set_group (g);
515 if (Config->get_use_monitor_bus()) {
516 use_monitor_section_button.set_active (true);
518 no_monitor_section_button.set_active (true);
521 use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
522 no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
524 monitor_section_label.set_markup(_("<i>You can change this preference at any time via the Preferences dialog.\nYou can also add or remove the monitor section to/from any session.</i>\n\n\
525 <i>If you do not understand what this is about, just accept the default.</i>"));
526 monitor_section_label.set_alignment (0.0, 0.0);
528 hbox->pack_start (*main_vbox, true, true, 8);
529 mon_sec_vbox.pack_start (*hbox, false, false);
530 mon_sec_vbox.pack_start (monitor_section_label, false, false);
532 mon_sec_vbox.show_all ();
534 monitor_section_page_index = append_page (mon_sec_vbox);
535 set_page_title (mon_sec_vbox, _("Monitor Section"));
536 set_page_header_image (mon_sec_vbox, icon_pixbuf);
538 /* user could just click on "Forward" if default
542 set_page_complete (mon_sec_vbox, true);
546 ArdourStartup::setup_initial_choice_page ()
548 ic_vbox.set_spacing (6);
549 ic_vbox.set_border_width (24);
551 RadioButton::Group g (ic_new_session_button.get_group());
552 ic_existing_session_button.set_group (g);
554 HBox* centering_hbox = manage (new HBox);
555 VBox* centering_vbox = manage (new VBox);
557 centering_vbox->set_spacing (6);
559 centering_vbox->pack_start (ic_new_session_button, false, true);
560 centering_vbox->pack_start (ic_existing_session_button, false, true);
562 ic_new_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
563 ic_new_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
565 ic_existing_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
566 ic_existing_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
568 centering_hbox->pack_start (*centering_vbox, true, true);
570 ic_vbox.pack_start (*centering_hbox, true, true);
574 initial_choice_index = append_page (ic_vbox);
575 set_page_title (ic_vbox, _("What would you like to do ?"));
576 set_page_header_image (ic_vbox, icon_pixbuf);
578 /* user could just click on "Forward" if default
582 set_page_complete (ic_vbox, true);
586 ArdourStartup::initial_button_clicked (GdkEventButton* ev)
588 if (ev->type == GDK_2BUTTON_PRESS && session_page_index != -1) {
589 set_current_page(session_page_index);
596 ArdourStartup::initial_button_activated ()
598 if (session_page_index != -1) {
599 set_current_page(session_page_index);
604 ArdourStartup::setup_session_page ()
606 session_vbox.set_border_width (24);
608 session_vbox.pack_start (session_hbox, true, true);
609 session_vbox.show_all ();
611 session_page_index = append_page (session_vbox);
612 /* initial setting */
613 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
617 ArdourStartup::setup_final_page ()
619 final_page.set_text (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
621 final_page_index = append_page (final_page);
622 set_page_complete (final_page, true);
623 set_page_header_image (final_page, icon_pixbuf);
624 set_page_type (final_page, ASSISTANT_PAGE_CONFIRM);
628 ArdourStartup::on_cancel ()
630 _response = RESPONSE_CANCEL;
635 ArdourStartup::on_delete_event (GdkEventAny*)
637 _response = RESPONSE_CLOSE;
643 ArdourStartup::on_apply ()
646 if (engine_dialog->setup_engine ()) {
647 set_current_page (audio_page_index);
652 if (config_modified) {
654 if (default_dir_chooser) {
655 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
658 if (monitor_via_hardware_button.get_active()) {
659 Config->set_monitoring_model (ExternalMonitoring);
660 } else if (monitor_via_ardour_button.get_active()) {
661 Config->set_monitoring_model (SoftwareMonitoring);
664 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
666 /* "touch" the been-here-before path now that we're about to save Config */
667 ofstream fout (been_here_before_path().c_str());
669 Config->save_state ();
672 _response = RESPONSE_OK;
677 ArdourStartup::on_prepare (Gtk::Widget* page)
679 if (page == &session_vbox) {
681 if (ic_new_session_button.get_active()) {
682 /* new session requested */
683 setup_new_session_page ();
685 /* existing session requested */
686 setup_existing_session_page ();
690 /* HACK HACK HACK ... change the "Apply" button label
694 Gtk::Widget* tl = session_vbox.get_toplevel();
696 if ((win = dynamic_cast<Gtk::Window*>(tl)) != 0) {
697 /* ::get_default_widget() is not wrapped in gtkmm */
698 Gtk::Widget* def = wrap (gtk_window_get_default_widget (win->gobj()));
700 if ((button = dynamic_cast<Gtk::Button*>(def)) != 0) {
701 if (more_new_session_options_button.get_active()) {
702 button->set_label (_("Forward"));
704 button->set_label (_("Open"));
712 ArdourStartup::populate_session_templates ()
714 vector<TemplateInfo> templates;
716 find_session_templates (templates);
718 template_model->clear ();
720 for (vector<TemplateInfo>::iterator x = templates.begin(); x != templates.end(); ++x) {
723 row = *(template_model->append ());
725 row[session_template_columns.name] = (*x).name;
726 row[session_template_columns.path] = (*x).path;
731 ArdourStartup::setup_new_session_page ()
733 if (!session_hbox.get_children().empty()) {
734 session_hbox.remove (**session_hbox.get_children().begin());
737 session_new_vbox.set_spacing (18);
739 if (session_new_vbox.get_children().empty()) {
740 VBox *vbox1 = manage (new VBox);
741 HBox* hbox1 = manage (new HBox);
742 Label* label1 = manage (new Label);
744 vbox1->set_spacing (6);
746 hbox1->set_spacing (6);
747 hbox1->pack_start (*label1, false, false);
748 hbox1->pack_start (new_name_entry, true, true);
750 label1->set_text (_("Session name:"));
753 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
754 new_name_entry.set_text (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
755 /* name provided - they can move right along */
756 set_page_complete (session_vbox, true);
759 new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_changed));
760 new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &ArdourStartup::move_along_now));
762 vbox1->pack_start (*hbox1, true, true);
766 HBox* hbox2 = manage (new HBox);
767 Label* label2 = manage (new Label);
769 hbox2->set_spacing (6);
770 hbox2->pack_start (*label2, false, false);
771 hbox2->pack_start (new_folder_chooser, true, true);
773 label2->set_text (_("Create session folder in:"));
775 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
776 new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
777 } else if (ARDOUR_UI::instance()->session_loaded) {
778 // point the new session file chooser at the parent directory of the current session
779 string session_parent_dir = Glib::path_get_dirname(ARDOUR_UI::instance()->the_session()->path());
780 string::size_type last_dir_sep = session_parent_dir.rfind(G_DIR_SEPARATOR);
781 session_parent_dir = session_parent_dir.substr(0, last_dir_sep);
782 new_folder_chooser.set_current_folder (session_parent_dir);
783 new_folder_chooser.add_shortcut_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
785 new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
787 new_folder_chooser.set_title (_("Select folder for session"));
790 new_folder_chooser.add_shortcut_folder ("/Volumes");
793 vbox1->pack_start (*hbox2, false, false);
795 session_new_vbox.pack_start (*vbox1, false, false);
799 VBox *vbox2 = manage (new VBox);
800 HBox* hbox3 = manage (new HBox);
801 Label* label3 = manage (new Label);
802 template_model = ListStore::create (session_template_columns);
803 populate_session_templates ();
805 vbox2->set_spacing (6);
807 label3->set_markup (_("<b>Options</b>"));
808 label3->set_alignment (0.0, 0.0);
810 vbox2->pack_start (*label3, false, true);
812 VBox *vbox3 = manage (new VBox);
814 vbox3->set_spacing (6);
816 if (!template_model->children().empty()) {
818 HBox* hbox4a = manage (new HBox);
819 use_template_button.set_label (_("Use this template"));
821 TreeModel::Row row = *template_model->prepend ();
822 row[session_template_columns.name] = (_("no template"));
823 row[session_template_columns.path] = string();
825 hbox4a->set_spacing (6);
826 hbox4a->pack_start (use_template_button, false, false);
827 hbox4a->pack_start (template_chooser, true, true);
829 template_chooser.set_model (template_model);
831 Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
832 text_renderer->property_editable() = false;
834 template_chooser.pack_start (*text_renderer);
835 template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
836 template_chooser.set_active (0);
838 use_template_button.show();
839 template_chooser.show ();
841 vbox3->pack_start (*hbox4a, false, false);
847 session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
849 HBox* hbox4b = manage (new HBox);
850 use_session_as_template_button.set_label (_("Use an existing session as a template:"));
852 hbox4b->set_spacing (6);
853 hbox4b->pack_start (use_session_as_template_button, false, false);
854 hbox4b->pack_start (session_template_chooser, true, true);
856 use_session_as_template_button.show ();
857 session_template_chooser.show ();
859 Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
860 session_filter->add_pattern (X_("*.ardour"));
861 session_template_chooser.set_filter (*session_filter);
862 session_template_chooser.set_title (_("Select template"));
864 vbox3->pack_start (*hbox4b, false, false);
869 HBox* hbox5 = manage (new HBox);
871 hbox5->set_spacing (6);
872 hbox5->pack_start (more_new_session_options_button, false, false);
874 more_new_session_options_button.show ();
875 more_new_session_options_button.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::more_new_session_options_button_clicked));
877 vbox3->pack_start (*hbox5, false, false);
878 hbox3->pack_start (*vbox3, true, true, 8);
879 vbox2->pack_start (*hbox3, false, false);
883 session_new_vbox.pack_start (*vbox2, false, false);
886 session_new_vbox.show_all ();
887 session_hbox.pack_start (session_new_vbox, true, true);
888 set_page_title (session_vbox, _("New Session"));
889 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
891 if (more_new_session_options_button.get_active()) {
892 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
897 ArdourStartup::new_name_changed ()
899 if (!new_name_entry.get_text().empty()) {
900 set_page_complete (session_vbox, true);
902 set_page_complete (session_vbox, false);
907 ArdourStartup::redisplay_recent_sessions ()
909 std::vector<std::string> session_directories;
910 RecentSessionsSorter cmp;
912 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
913 recent_session_model->clear ();
915 ARDOUR::RecentSessions rs;
916 ARDOUR::read_recent_sessions (rs);
919 recent_session_display.set_model (recent_session_model);
923 // sort them alphabetically
924 sort (rs.begin(), rs.end(), cmp);
926 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
927 session_directories.push_back ((*i).second);
930 int session_snapshot_count = 0;
932 for (vector<std::string>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
934 std::vector<std::string> state_file_paths;
936 // now get available states for this session
938 get_state_files_in_directory (*i, state_file_paths);
940 vector<string*>* states;
941 vector<const gchar*> item;
942 string fullpath = *i;
944 /* remove any trailing / */
946 if (fullpath[fullpath.length()-1] == '/') {
947 fullpath = fullpath.substr (0, fullpath.length()-1);
950 /* check whether session still exists */
951 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
952 /* session doesn't exist */
956 /* now get available states for this session */
958 if ((states = Session::possible_states (fullpath)) == 0) {
963 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
965 Gtk::TreeModel::Row row = *(recent_session_model->append());
967 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
968 row[recent_session_columns.fullpath] = fullpath;
970 ++session_snapshot_count;
972 if (state_file_names.size() > 1) {
976 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
977 i2 != state_file_names.end(); ++i2)
980 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
982 child_row[recent_session_columns.visible_name] = *i2;
983 child_row[recent_session_columns.fullpath] = fullpath;
984 ++session_snapshot_count;
989 recent_session_display.set_tooltip_column(1); // recent_session_columns.fullpath
990 recent_session_display.set_model (recent_session_model);
991 return session_snapshot_count;
996 ArdourStartup::recent_session_row_selected ()
998 if (recent_session_display.get_selection()->count_selected_rows() > 0) {
999 set_page_complete (session_vbox, true);
1001 set_page_complete (session_vbox, false);
1006 ArdourStartup::setup_existing_session_page ()
1008 recent_session_model = TreeStore::create (recent_session_columns);
1009 redisplay_recent_sessions ();
1011 if (!session_hbox.get_children().empty()) {
1012 session_hbox.remove (**session_hbox.get_children().begin());
1015 if (session_existing_vbox.get_children().empty()) {
1017 recent_session_display.set_model (recent_session_model);
1018 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1019 recent_session_display.set_headers_visible (false);
1020 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
1022 recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::recent_session_row_selected));
1024 recent_scroller.add (recent_session_display);
1025 recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1026 recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
1028 recent_session_display.show();
1030 recent_scroller.show();
1031 int cnt = redisplay_recent_sessions ();
1032 recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ArdourStartup::recent_row_activated));
1035 recent_scroller.set_size_request (-1, 300);
1038 session_existing_vbox.set_spacing (8);
1039 session_existing_vbox.pack_start (recent_scroller, true, true);
1041 existing_session_chooser.set_title (_("Select session file"));
1042 existing_session_chooser.signal_file_set().connect (sigc::mem_fun (*this, &ArdourStartup::existing_session_selected));
1043 existing_session_chooser.set_current_folder(poor_mans_glob (Config->get_default_session_parent_dir()));
1045 FileFilter session_filter;
1046 session_filter.add_pattern ("*.ardour");
1047 session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
1048 existing_session_chooser.add_filter (session_filter);
1049 existing_session_chooser.set_filter (session_filter);
1052 existing_session_chooser.add_shortcut_folder ("/Volumes");
1055 HBox* hbox = manage (new HBox);
1056 hbox->set_spacing (4);
1057 hbox->pack_start (*manage (new Label (_("Browse:"))), PACK_SHRINK);
1058 hbox->pack_start (existing_session_chooser);
1059 session_existing_vbox.pack_start (*hbox, false, false);
1063 session_existing_vbox.show_all ();
1064 session_hbox.pack_start (session_existing_vbox, true, true);
1066 set_page_title (session_vbox, _("Select a session"));
1067 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1071 ArdourStartup::more_new_session_options_button_clicked ()
1073 if (more_new_session_options_button.get_active()) {
1074 more_options_vbox.show_all ();
1075 set_page_type (more_options_vbox, ASSISTANT_PAGE_CONFIRM);
1076 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
1078 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1079 more_options_vbox.hide ();
1084 ArdourStartup::setup_more_options_page ()
1086 more_options_vbox.set_border_width (24);
1088 _output_limit_count.set_adjustment (_output_limit_count_adj);
1089 _input_limit_count.set_adjustment (_input_limit_count_adj);
1090 _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
1092 chan_count_label_1.set_text (_("channels"));
1093 chan_count_label_3.set_text (_("channels"));
1094 chan_count_label_4.set_text (_("channels"));
1096 chan_count_label_1.set_alignment(0,0.5);
1097 chan_count_label_1.set_padding(0,0);
1098 chan_count_label_1.set_line_wrap(false);
1100 chan_count_label_3.set_alignment(0,0.5);
1101 chan_count_label_3.set_padding(0,0);
1102 chan_count_label_3.set_line_wrap(false);
1104 chan_count_label_4.set_alignment(0,0.5);
1105 chan_count_label_4.set_padding(0,0);
1106 chan_count_label_4.set_line_wrap(false);
1108 bus_label.set_markup (_("<b>Busses</b>"));
1109 input_label.set_markup (_("<b>Inputs</b>"));
1110 output_label.set_markup (_("<b>Outputs</b>"));
1112 _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
1113 _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1114 _master_bus_channel_count.set_numeric(true);
1115 _master_bus_channel_count.set_digits(0);
1116 _master_bus_channel_count.set_wrap(false);
1118 _create_master_bus.set_label (_("Create master bus"));
1119 _create_master_bus.set_flags(Gtk::CAN_FOCUS);
1120 _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
1121 _create_master_bus.set_mode(true);
1122 _create_master_bus.set_active(true);
1123 _create_master_bus.set_border_width(0);
1125 advanced_table.set_row_spacings(0);
1126 advanced_table.set_col_spacings(0);
1128 _connect_inputs.set_label (_("Automatically connect to physical inputs"));
1129 _connect_inputs.set_flags(Gtk::CAN_FOCUS);
1130 _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
1131 _connect_inputs.set_mode(true);
1132 _connect_inputs.set_active(Config->get_input_auto_connect() != ManualConnect);
1133 _connect_inputs.set_border_width(0);
1135 _limit_input_ports.set_label (_("Use only"));
1136 _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
1137 _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
1138 _limit_input_ports.set_mode(true);
1139 _limit_input_ports.set_sensitive(true);
1140 _limit_input_ports.set_border_width(0);
1142 _input_limit_count.set_flags(Gtk::CAN_FOCUS);
1143 _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1144 _input_limit_count.set_numeric(true);
1145 _input_limit_count.set_digits(0);
1146 _input_limit_count.set_wrap(false);
1147 _input_limit_count.set_sensitive(false);
1149 bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
1151 bus_label.set_alignment(0, 0.5);
1152 bus_label.set_padding(0,0);
1153 bus_label.set_line_wrap(false);
1154 bus_label.set_selectable(false);
1155 bus_label.set_use_markup(true);
1156 bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
1157 bus_frame.set_label_align(0,0.5);
1158 bus_frame.add(bus_hbox);
1159 bus_frame.set_label_widget(bus_label);
1161 bus_table.set_row_spacings (0);
1162 bus_table.set_col_spacings (0);
1163 bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1164 bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1165 bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
1167 input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
1168 input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
1169 input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
1170 input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
1171 input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
1172 input_table.set_row_spacings(0);
1173 input_table.set_col_spacings(0);
1174 input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
1176 input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
1178 input_label.set_alignment(0, 0.5);
1179 input_label.set_padding(0,0);
1180 input_label.set_line_wrap(false);
1181 input_label.set_selectable(false);
1182 input_label.set_use_markup(true);
1183 input_frame.set_shadow_type(Gtk::SHADOW_NONE);
1184 input_frame.set_label_align(0,0.5);
1185 input_frame.add(input_hbox);
1186 input_frame.set_label_widget(input_label);
1188 _connect_outputs.set_label (_("Automatically connect outputs"));
1189 _connect_outputs.set_flags(Gtk::CAN_FOCUS);
1190 _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
1191 _connect_outputs.set_mode(true);
1192 _connect_outputs.set_active(Config->get_output_auto_connect() != ManualConnect);
1193 _connect_outputs.set_border_width(0);
1194 _limit_output_ports.set_label (_("Use only"));
1195 _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
1196 _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
1197 _limit_output_ports.set_mode(true);
1198 _limit_output_ports.set_sensitive(true);
1199 _limit_output_ports.set_border_width(0);
1200 _output_limit_count.set_flags(Gtk::CAN_FOCUS);
1201 _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1202 _output_limit_count.set_numeric(false);
1203 _output_limit_count.set_digits(0);
1204 _output_limit_count.set_wrap(false);
1205 _output_limit_count.set_sensitive(false);
1206 output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
1207 output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
1208 output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
1210 _connect_outputs_to_master.set_label (_("... to master bus"));
1211 _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
1212 _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
1213 _connect_outputs_to_master.set_mode(true);
1214 _connect_outputs_to_master.set_active(Config->get_output_auto_connect() == AutoConnectMaster);
1215 _connect_outputs_to_master.set_border_width(0);
1217 _connect_outputs_to_master.set_group (connect_outputs_group);
1218 _connect_outputs_to_physical.set_group (connect_outputs_group);
1220 _connect_outputs_to_physical.set_label (_("... to physical outputs"));
1221 _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
1222 _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
1223 _connect_outputs_to_physical.set_mode(true);
1224 _connect_outputs_to_physical.set_active(Config->get_output_auto_connect() == AutoConnectPhysical);
1225 _connect_outputs_to_physical.set_border_width(0);
1227 output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
1228 output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
1229 output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
1230 output_vbox.set_border_width(6);
1232 output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
1234 output_vbox.pack_start(output_conn_vbox);
1235 output_vbox.pack_start(output_port_vbox);
1237 output_label.set_alignment(0, 0.5);
1238 output_label.set_padding(0,0);
1239 output_label.set_line_wrap(false);
1240 output_label.set_selectable(false);
1241 output_label.set_use_markup(true);
1242 output_frame.set_shadow_type(Gtk::SHADOW_NONE);
1243 output_frame.set_label_align(0,0.5);
1245 output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
1247 output_frame.add(output_hbox);
1248 output_frame.set_label_widget(output_label);
1250 more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
1251 more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
1252 more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
1253 more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
1257 _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
1258 _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
1259 _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
1260 _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
1261 _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
1263 /* note that more_options_vbox is "visible" by default even
1264 * though it may not be displayed to the user, this is so the dialog
1267 more_options_vbox.show_all ();
1269 session_options_page_index = append_page (more_options_vbox);
1270 set_page_title (more_options_vbox, _("Advanced Session Options"));
1271 set_page_complete (more_options_vbox, true);
1275 ArdourStartup::create_master_bus() const
1277 return _create_master_bus.get_active();
1281 ArdourStartup::master_channel_count() const
1283 return _master_bus_channel_count.get_value_as_int();
1287 ArdourStartup::connect_inputs() const
1289 return _connect_inputs.get_active();
1293 ArdourStartup::limit_inputs_used_for_connection() const
1295 return _limit_input_ports.get_active();
1299 ArdourStartup::input_limit_count() const
1301 return _input_limit_count.get_value_as_int();
1305 ArdourStartup::connect_outputs() const
1307 return _connect_outputs.get_active();
1311 ArdourStartup::limit_outputs_used_for_connection() const
1313 return _limit_output_ports.get_active();
1317 ArdourStartup::output_limit_count() const
1319 return _output_limit_count.get_value_as_int();
1323 ArdourStartup::connect_outs_to_master() const
1325 return _connect_outputs_to_master.get_active();
1329 ArdourStartup::connect_outs_to_physical() const
1331 return _connect_outputs_to_physical.get_active();
1335 ArdourStartup::connect_inputs_clicked ()
1337 _limit_input_ports.set_sensitive(_connect_inputs.get_active());
1339 if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
1340 _input_limit_count.set_sensitive(true);
1342 _input_limit_count.set_sensitive(false);
1347 ArdourStartup::connect_outputs_clicked ()
1349 bool const co = _connect_outputs.get_active ();
1350 _limit_output_ports.set_sensitive(co);
1351 _connect_outputs_to_master.set_sensitive(co);
1352 _connect_outputs_to_physical.set_sensitive(co);
1354 if (co && _limit_output_ports.get_active()) {
1355 _output_limit_count.set_sensitive(true);
1357 _output_limit_count.set_sensitive(false);
1362 ArdourStartup::limit_inputs_clicked ()
1364 _input_limit_count.set_sensitive(_limit_input_ports.get_active());
1368 ArdourStartup::limit_outputs_clicked ()
1370 _output_limit_count.set_sensitive(_limit_output_ports.get_active());
1374 ArdourStartup::master_bus_button_clicked ()
1376 bool const yn = _create_master_bus.get_active();
1378 _master_bus_channel_count.set_sensitive(yn);
1379 _connect_outputs_to_master.set_sensitive(yn);
1383 ArdourStartup::move_along_now ()
1385 gint cur = get_current_page ();
1387 if (cur == session_page_index) {
1388 if (more_new_session_options_button.get_active()) {
1389 set_current_page (session_options_page_index);
1397 ArdourStartup::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
1399 set_page_complete (session_vbox, true);
1404 ArdourStartup::existing_session_selected ()
1406 _existing_session_chooser_used = true;
1408 set_page_complete (session_vbox, true);
1413 ArdourStartup::been_here_before_path () const
1415 // XXXX use more specific version so we can catch upgrades
1416 return Glib::build_filename (user_config_directory (), ".a3");