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 cerr << "using NFC @ " << &new_folder_chooser << ' ' << new_folder_chooser.get_current_folder() << " file " << new_folder_chooser.get_filename() << endl;
309 return Glib::build_filename (new_folder_chooser.get_current_folder(), legal_session_folder_name);
310 } else if (_existing_session_chooser_used) {
311 /* existing session chosen from file chooser */
312 return existing_session_chooser.get_current_folder ();
314 /* existing session chosen from recent list */
315 TreeIter iter = recent_session_display.get_selection()->get_selected();
318 return (*iter)[recent_session_columns.fullpath];
325 ArdourStartup::setup_audio_page ()
327 engine_dialog = manage (new EngineControl);
329 engine_dialog->set_border_width (12);
331 engine_dialog->show_all ();
333 audio_page_index = append_page (*engine_dialog);
334 set_page_type (*engine_dialog, ASSISTANT_PAGE_CONTENT);
335 set_page_title (*engine_dialog, _("Audio / MIDI Setup"));
337 /* the default parameters should work, so the page is potentially complete */
339 set_page_complete (*engine_dialog, true);
343 ArdourStartup::setup_new_user_page ()
345 Label* foomatic = manage (new Label);
347 foomatic->set_markup (string_compose (_("\
348 <span size=\"larger\">%1 is a digital audio workstation. You can use it to \
349 record, edit and mix multi-track audio. You can produce your \
350 own CDs, mix video soundtracks, or experiment with new \
351 ideas about music and sound. \
353 There are a few things that need to be configured before you start \
354 using the program.</span> \
356 foomatic->set_justify (JUSTIFY_FILL);
357 foomatic->set_line_wrap ();
359 HBox* hbox = manage (new HBox);
360 HBox* vbox = manage (new HBox);
362 vbox->set_border_width (24);
364 hbox->pack_start (*foomatic, true, true);
365 vbox->pack_start (*hbox, true, true);
371 new_user_page_index = append_page (*vbox);
372 set_page_type (*vbox, ASSISTANT_PAGE_INTRO);
373 set_page_title (*vbox, string_compose (_("Welcome to %1"), PROGRAM_NAME));
374 set_page_header_image (*vbox, icon_pixbuf);
375 set_page_complete (*vbox, true);
379 ArdourStartup::default_dir_changed ()
381 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
382 // make new session folder chooser point to the new default
383 new_folder_chooser.set_current_folder (Config->get_default_session_parent_dir());
388 ArdourStartup::config_changed ()
390 config_modified = true;
394 ArdourStartup::setup_first_time_config_page ()
396 default_dir_chooser = manage (new FileChooserButton (string_compose (_("Default folder for %1 sessions"), PROGRAM_NAME),
397 FILE_CHOOSER_ACTION_SELECT_FOLDER));
398 Gtk::Label* txt = manage (new Label);
399 HBox* hbox = manage (new HBox);
400 VBox* vbox = manage (new VBox);
402 txt->set_markup (string_compose (_("\
403 Each project that you work on with %1 has its own folder.\n\
404 These can require a lot of disk space if you are recording audio.\n\
406 Where would you like new %1 sessions to be stored by default?\n\n\
407 <i>(You can put new sessions anywhere, this is just a default)</i>"), PROGRAM_NAME));
408 txt->set_alignment (0.0, 0.0);
410 vbox->set_spacing (18);
411 vbox->set_border_width (24);
413 hbox->pack_start (*default_dir_chooser, false, true, 8);
414 vbox->pack_start (*txt, false, false);
415 vbox->pack_start (*hbox, false, true);
417 default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
418 default_dir_chooser->signal_current_folder_changed().connect (sigc::mem_fun (*this, &ArdourStartup::default_dir_changed));
419 default_dir_chooser->show ();
423 default_folder_page_index = append_page (*vbox);
424 set_page_title (*vbox, _("Default folder for new sessions"));
425 set_page_header_image (*vbox, icon_pixbuf);
426 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
428 /* user can just skip all these settings if they want to */
430 set_page_complete (*vbox, true);
434 ArdourStartup::setup_monitoring_choice_page ()
436 mon_vbox.set_spacing (18);
437 mon_vbox.set_border_width (24);
439 HBox* hbox = manage (new HBox);
440 VBox* vbox = manage (new VBox);
441 /* first button will be on by default */
442 RadioButton::Group g (monitor_via_ardour_button.get_group());
443 monitor_via_hardware_button.set_group (g);
445 monitor_label.set_markup(_("\
446 While recording instruments or vocals, you probably want to listen to the\n\
447 signal as well as record it. This is called \"monitoring\". There are\n\
448 different ways to do this depending on the equipment you have and the\n\
449 configuration of that equipment. The two most common are presented here.\n\
450 Please choose whichever one is right for your setup.\n\n\
451 <i>(You can change this preference at any time, via the Preferences dialog)</i>\n\n\
452 <i>If you do not understand what this is about, just accept the default.</i>"));
453 monitor_label.set_alignment (0.0, 0.0);
455 vbox->set_spacing (6);
457 vbox->pack_start (monitor_via_hardware_button, false, true);
458 vbox->pack_start (monitor_via_ardour_button, false, true);
459 hbox->pack_start (*vbox, true, true, 8);
460 mon_vbox.pack_start (monitor_label, false, false);
461 mon_vbox.pack_start (*hbox, false, false);
463 mon_vbox.show_all ();
465 monitoring_page_index = append_page (mon_vbox);
466 set_page_title (mon_vbox, _("Monitoring Choices"));
467 set_page_header_image (mon_vbox, icon_pixbuf);
469 /* user could just click on "Forward" if default
473 set_page_complete (mon_vbox, true);
477 ArdourStartup::setup_monitor_section_choice_page ()
479 mon_sec_vbox.set_spacing (18);
480 mon_sec_vbox.set_border_width (24);
482 HBox* hbox = manage (new HBox);
483 VBox* main_vbox = manage (new VBox);
485 Label* l = manage (new Label);
487 main_vbox->set_spacing (32);
489 no_monitor_section_button.set_label (_("Use a Master bus directly"));
490 l->set_alignment (0.0, 1.0);
491 l->set_markup(_("Connect the Master bus directly to your hardware outputs. This is preferable for simple usage."));
493 vbox = manage (new VBox);
494 vbox->set_spacing (6);
495 vbox->pack_start (no_monitor_section_button, false, true);
496 vbox->pack_start (*l, false, true);
498 main_vbox->pack_start (*vbox, false, false);
500 use_monitor_section_button.set_label (_("Use an additional Monitor bus"));
501 l = manage (new Label);
502 l->set_alignment (0.0, 1.0);
503 l->set_text (_("Use a Monitor bus between Master bus and hardware outputs for \n\
504 greater control in monitoring without affecting the mix."));
506 vbox = manage (new VBox);
507 vbox->set_spacing (6);
508 vbox->pack_start (use_monitor_section_button, false, true);
509 vbox->pack_start (*l, false, true);
511 main_vbox->pack_start (*vbox, false, false);
513 RadioButton::Group g (use_monitor_section_button.get_group());
514 no_monitor_section_button.set_group (g);
516 if (Config->get_use_monitor_bus()) {
517 use_monitor_section_button.set_active (true);
519 no_monitor_section_button.set_active (true);
522 use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
523 no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
525 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\
526 <i>If you do not understand what this is about, just accept the default.</i>"));
527 monitor_section_label.set_alignment (0.0, 0.0);
529 hbox->pack_start (*main_vbox, true, true, 8);
530 mon_sec_vbox.pack_start (*hbox, false, false);
531 mon_sec_vbox.pack_start (monitor_section_label, false, false);
533 mon_sec_vbox.show_all ();
535 monitor_section_page_index = append_page (mon_sec_vbox);
536 set_page_title (mon_sec_vbox, _("Monitor Section"));
537 set_page_header_image (mon_sec_vbox, icon_pixbuf);
539 /* user could just click on "Forward" if default
543 set_page_complete (mon_sec_vbox, true);
547 ArdourStartup::setup_initial_choice_page ()
549 ic_vbox.set_spacing (6);
550 ic_vbox.set_border_width (24);
552 RadioButton::Group g (ic_new_session_button.get_group());
553 ic_existing_session_button.set_group (g);
555 HBox* centering_hbox = manage (new HBox);
556 VBox* centering_vbox = manage (new VBox);
558 centering_vbox->set_spacing (6);
560 centering_vbox->pack_start (ic_new_session_button, false, true);
561 centering_vbox->pack_start (ic_existing_session_button, false, true);
563 ic_new_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
564 ic_new_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
566 ic_existing_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
567 ic_existing_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
569 centering_hbox->pack_start (*centering_vbox, true, true);
571 ic_vbox.pack_start (*centering_hbox, true, true);
575 initial_choice_index = append_page (ic_vbox);
576 set_page_title (ic_vbox, _("What would you like to do ?"));
577 set_page_header_image (ic_vbox, icon_pixbuf);
579 /* user could just click on "Forward" if default
583 set_page_complete (ic_vbox, true);
587 ArdourStartup::initial_button_clicked (GdkEventButton* ev)
589 if (ev->type == GDK_2BUTTON_PRESS && session_page_index != -1) {
590 set_current_page(session_page_index);
597 ArdourStartup::initial_button_activated ()
599 if (session_page_index != -1) {
600 set_current_page(session_page_index);
605 ArdourStartup::setup_session_page ()
607 session_vbox.set_border_width (24);
609 session_vbox.pack_start (session_hbox, true, true);
610 session_vbox.show_all ();
612 session_page_index = append_page (session_vbox);
613 /* initial setting */
614 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
618 ArdourStartup::setup_final_page ()
620 final_page.set_text (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
622 final_page_index = append_page (final_page);
623 set_page_complete (final_page, true);
624 set_page_header_image (final_page, icon_pixbuf);
625 set_page_type (final_page, ASSISTANT_PAGE_CONFIRM);
629 ArdourStartup::on_cancel ()
631 _response = RESPONSE_CANCEL;
636 ArdourStartup::on_delete_event (GdkEventAny*)
638 _response = RESPONSE_CLOSE;
644 ArdourStartup::on_apply ()
647 if (engine_dialog->setup_engine ()) {
648 set_current_page (audio_page_index);
653 if (config_modified) {
655 if (default_dir_chooser) {
656 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
659 if (monitor_via_hardware_button.get_active()) {
660 Config->set_monitoring_model (ExternalMonitoring);
661 } else if (monitor_via_ardour_button.get_active()) {
662 Config->set_monitoring_model (SoftwareMonitoring);
665 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
667 /* "touch" the been-here-before path now that we're about to save Config */
668 ofstream fout (been_here_before_path().c_str());
670 Config->save_state ();
673 _response = RESPONSE_OK;
678 ArdourStartup::on_prepare (Gtk::Widget* page)
680 if (page == &session_vbox) {
682 if (ic_new_session_button.get_active()) {
683 /* new session requested */
684 setup_new_session_page ();
686 /* existing session requested */
687 setup_existing_session_page ();
691 /* HACK HACK HACK ... change the "Apply" button label
695 Gtk::Widget* tl = session_vbox.get_toplevel();
697 if ((win = dynamic_cast<Gtk::Window*>(tl)) != 0) {
698 /* ::get_default_widget() is not wrapped in gtkmm */
699 Gtk::Widget* def = wrap (gtk_window_get_default_widget (win->gobj()));
701 if ((button = dynamic_cast<Gtk::Button*>(def)) != 0) {
702 if (more_new_session_options_button.get_active()) {
703 button->set_label (_("Forward"));
705 button->set_label (_("Open"));
713 ArdourStartup::populate_session_templates ()
715 vector<TemplateInfo> templates;
717 find_session_templates (templates);
719 template_model->clear ();
721 for (vector<TemplateInfo>::iterator x = templates.begin(); x != templates.end(); ++x) {
724 row = *(template_model->append ());
726 row[session_template_columns.name] = (*x).name;
727 row[session_template_columns.path] = (*x).path;
732 ArdourStartup::setup_new_session_page ()
734 if (!session_hbox.get_children().empty()) {
735 session_hbox.remove (**session_hbox.get_children().begin());
738 session_new_vbox.set_spacing (18);
740 if (session_new_vbox.get_children().empty()) {
741 VBox *vbox1 = manage (new VBox);
742 HBox* hbox1 = manage (new HBox);
743 Label* label1 = manage (new Label);
745 vbox1->set_spacing (6);
747 hbox1->set_spacing (6);
748 hbox1->pack_start (*label1, false, false);
749 hbox1->pack_start (new_name_entry, true, true);
751 label1->set_text (_("Session name:"));
754 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
755 new_name_entry.set_text (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
756 /* name provided - they can move right along */
757 set_page_complete (session_vbox, true);
760 new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_changed));
761 new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &ArdourStartup::move_along_now));
763 vbox1->pack_start (*hbox1, true, true);
767 HBox* hbox2 = manage (new HBox);
768 Label* label2 = manage (new Label);
770 hbox2->set_spacing (6);
771 hbox2->pack_start (*label2, false, false);
772 hbox2->pack_start (new_folder_chooser, true, true);
774 label2->set_text (_("Create session folder in:"));
776 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
777 new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
778 } else if (ARDOUR_UI::instance()->session_loaded) {
779 // point the new session file chooser at the parent directory of the current session
780 string session_parent_dir = Glib::path_get_dirname(ARDOUR_UI::instance()->the_session()->path());
781 string::size_type last_dir_sep = session_parent_dir.rfind(G_DIR_SEPARATOR);
782 session_parent_dir = session_parent_dir.substr(0, last_dir_sep);
783 new_folder_chooser.set_current_folder (session_parent_dir);
784 new_folder_chooser.add_shortcut_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
786 new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
788 new_folder_chooser.set_title (_("Select folder for session"));
791 new_folder_chooser.add_shortcut_folder ("/Volumes");
794 vbox1->pack_start (*hbox2, false, false);
796 session_new_vbox.pack_start (*vbox1, false, false);
800 VBox *vbox2 = manage (new VBox);
801 HBox* hbox3 = manage (new HBox);
802 Label* label3 = manage (new Label);
803 template_model = ListStore::create (session_template_columns);
804 populate_session_templates ();
806 vbox2->set_spacing (6);
808 label3->set_markup (_("<b>Options</b>"));
809 label3->set_alignment (0.0, 0.0);
811 vbox2->pack_start (*label3, false, true);
813 VBox *vbox3 = manage (new VBox);
815 vbox3->set_spacing (6);
817 if (!template_model->children().empty()) {
819 HBox* hbox4a = manage (new HBox);
820 use_template_button.set_label (_("Use this template"));
822 TreeModel::Row row = *template_model->prepend ();
823 row[session_template_columns.name] = (_("no template"));
824 row[session_template_columns.path] = string();
826 hbox4a->set_spacing (6);
827 hbox4a->pack_start (use_template_button, false, false);
828 hbox4a->pack_start (template_chooser, true, true);
830 template_chooser.set_model (template_model);
832 Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
833 text_renderer->property_editable() = false;
835 template_chooser.pack_start (*text_renderer);
836 template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
837 template_chooser.set_active (0);
839 use_template_button.show();
840 template_chooser.show ();
842 vbox3->pack_start (*hbox4a, false, false);
848 session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
850 HBox* hbox4b = manage (new HBox);
851 use_session_as_template_button.set_label (_("Use an existing session as a template:"));
853 hbox4b->set_spacing (6);
854 hbox4b->pack_start (use_session_as_template_button, false, false);
855 hbox4b->pack_start (session_template_chooser, true, true);
857 use_session_as_template_button.show ();
858 session_template_chooser.show ();
860 Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
861 session_filter->add_pattern (X_("*.ardour"));
862 session_template_chooser.set_filter (*session_filter);
863 session_template_chooser.set_title (_("Select template"));
865 vbox3->pack_start (*hbox4b, false, false);
870 HBox* hbox5 = manage (new HBox);
872 hbox5->set_spacing (6);
873 hbox5->pack_start (more_new_session_options_button, false, false);
875 more_new_session_options_button.show ();
876 more_new_session_options_button.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::more_new_session_options_button_clicked));
878 vbox3->pack_start (*hbox5, false, false);
879 hbox3->pack_start (*vbox3, true, true, 8);
880 vbox2->pack_start (*hbox3, false, false);
884 session_new_vbox.pack_start (*vbox2, false, false);
887 session_new_vbox.show_all ();
888 session_hbox.pack_start (session_new_vbox, true, true);
889 set_page_title (session_vbox, _("New Session"));
890 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
892 if (more_new_session_options_button.get_active()) {
893 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
898 ArdourStartup::new_name_changed ()
900 if (!new_name_entry.get_text().empty()) {
901 set_page_complete (session_vbox, true);
903 set_page_complete (session_vbox, false);
908 ArdourStartup::redisplay_recent_sessions ()
910 std::vector<std::string> session_directories;
911 RecentSessionsSorter cmp;
913 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
914 recent_session_model->clear ();
916 ARDOUR::RecentSessions rs;
917 ARDOUR::read_recent_sessions (rs);
920 recent_session_display.set_model (recent_session_model);
924 // sort them alphabetically
925 sort (rs.begin(), rs.end(), cmp);
927 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
928 session_directories.push_back ((*i).second);
931 int session_snapshot_count = 0;
933 for (vector<std::string>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
935 std::vector<std::string> state_file_paths;
937 // now get available states for this session
939 get_state_files_in_directory (*i, state_file_paths);
941 vector<string*>* states;
942 vector<const gchar*> item;
943 string fullpath = *i;
945 /* remove any trailing / */
947 if (fullpath[fullpath.length()-1] == '/') {
948 fullpath = fullpath.substr (0, fullpath.length()-1);
951 /* check whether session still exists */
952 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
953 /* session doesn't exist */
957 /* now get available states for this session */
959 if ((states = Session::possible_states (fullpath)) == 0) {
964 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
966 Gtk::TreeModel::Row row = *(recent_session_model->append());
968 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
969 row[recent_session_columns.fullpath] = fullpath;
971 ++session_snapshot_count;
973 if (state_file_names.size() > 1) {
977 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
978 i2 != state_file_names.end(); ++i2)
981 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
983 child_row[recent_session_columns.visible_name] = *i2;
984 child_row[recent_session_columns.fullpath] = fullpath;
985 ++session_snapshot_count;
990 recent_session_display.set_tooltip_column(1); // recent_session_columns.fullpath
991 recent_session_display.set_model (recent_session_model);
992 return session_snapshot_count;
997 ArdourStartup::recent_session_row_selected ()
999 if (recent_session_display.get_selection()->count_selected_rows() > 0) {
1000 set_page_complete (session_vbox, true);
1002 set_page_complete (session_vbox, false);
1007 ArdourStartup::setup_existing_session_page ()
1009 recent_session_model = TreeStore::create (recent_session_columns);
1010 redisplay_recent_sessions ();
1012 if (!session_hbox.get_children().empty()) {
1013 session_hbox.remove (**session_hbox.get_children().begin());
1016 if (session_existing_vbox.get_children().empty()) {
1018 recent_session_display.set_model (recent_session_model);
1019 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1020 recent_session_display.set_headers_visible (false);
1021 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
1023 recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::recent_session_row_selected));
1025 recent_scroller.add (recent_session_display);
1026 recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1027 recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
1029 recent_session_display.show();
1031 recent_scroller.show();
1032 int cnt = redisplay_recent_sessions ();
1033 recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ArdourStartup::recent_row_activated));
1036 recent_scroller.set_size_request (-1, 300);
1039 session_existing_vbox.set_spacing (8);
1040 session_existing_vbox.pack_start (recent_scroller, true, true);
1042 existing_session_chooser.set_title (_("Select session file"));
1043 existing_session_chooser.signal_file_set().connect (sigc::mem_fun (*this, &ArdourStartup::existing_session_selected));
1044 existing_session_chooser.set_current_folder(poor_mans_glob (Config->get_default_session_parent_dir()));
1046 FileFilter session_filter;
1047 session_filter.add_pattern ("*.ardour");
1048 session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
1049 existing_session_chooser.add_filter (session_filter);
1050 existing_session_chooser.set_filter (session_filter);
1053 existing_session_chooser.add_shortcut_folder ("/Volumes");
1056 HBox* hbox = manage (new HBox);
1057 hbox->set_spacing (4);
1058 hbox->pack_start (*manage (new Label (_("Browse:"))), PACK_SHRINK);
1059 hbox->pack_start (existing_session_chooser);
1060 session_existing_vbox.pack_start (*hbox, false, false);
1064 session_existing_vbox.show_all ();
1065 session_hbox.pack_start (session_existing_vbox, true, true);
1067 set_page_title (session_vbox, _("Select a session"));
1068 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1072 ArdourStartup::more_new_session_options_button_clicked ()
1074 if (more_new_session_options_button.get_active()) {
1075 more_options_vbox.show_all ();
1076 set_page_type (more_options_vbox, ASSISTANT_PAGE_CONFIRM);
1077 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
1079 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1080 more_options_vbox.hide ();
1085 ArdourStartup::setup_more_options_page ()
1087 more_options_vbox.set_border_width (24);
1089 _output_limit_count.set_adjustment (_output_limit_count_adj);
1090 _input_limit_count.set_adjustment (_input_limit_count_adj);
1091 _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
1093 chan_count_label_1.set_text (_("channels"));
1094 chan_count_label_3.set_text (_("channels"));
1095 chan_count_label_4.set_text (_("channels"));
1097 chan_count_label_1.set_alignment(0,0.5);
1098 chan_count_label_1.set_padding(0,0);
1099 chan_count_label_1.set_line_wrap(false);
1101 chan_count_label_3.set_alignment(0,0.5);
1102 chan_count_label_3.set_padding(0,0);
1103 chan_count_label_3.set_line_wrap(false);
1105 chan_count_label_4.set_alignment(0,0.5);
1106 chan_count_label_4.set_padding(0,0);
1107 chan_count_label_4.set_line_wrap(false);
1109 bus_label.set_markup (_("<b>Busses</b>"));
1110 input_label.set_markup (_("<b>Inputs</b>"));
1111 output_label.set_markup (_("<b>Outputs</b>"));
1113 _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
1114 _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1115 _master_bus_channel_count.set_numeric(true);
1116 _master_bus_channel_count.set_digits(0);
1117 _master_bus_channel_count.set_wrap(false);
1119 _create_master_bus.set_label (_("Create master bus"));
1120 _create_master_bus.set_flags(Gtk::CAN_FOCUS);
1121 _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
1122 _create_master_bus.set_mode(true);
1123 _create_master_bus.set_active(true);
1124 _create_master_bus.set_border_width(0);
1126 advanced_table.set_row_spacings(0);
1127 advanced_table.set_col_spacings(0);
1129 _connect_inputs.set_label (_("Automatically connect to physical inputs"));
1130 _connect_inputs.set_flags(Gtk::CAN_FOCUS);
1131 _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
1132 _connect_inputs.set_mode(true);
1133 _connect_inputs.set_active(Config->get_input_auto_connect() != ManualConnect);
1134 _connect_inputs.set_border_width(0);
1136 _limit_input_ports.set_label (_("Use only"));
1137 _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
1138 _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
1139 _limit_input_ports.set_mode(true);
1140 _limit_input_ports.set_sensitive(true);
1141 _limit_input_ports.set_border_width(0);
1143 _input_limit_count.set_flags(Gtk::CAN_FOCUS);
1144 _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1145 _input_limit_count.set_numeric(true);
1146 _input_limit_count.set_digits(0);
1147 _input_limit_count.set_wrap(false);
1148 _input_limit_count.set_sensitive(false);
1150 bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
1152 bus_label.set_alignment(0, 0.5);
1153 bus_label.set_padding(0,0);
1154 bus_label.set_line_wrap(false);
1155 bus_label.set_selectable(false);
1156 bus_label.set_use_markup(true);
1157 bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
1158 bus_frame.set_label_align(0,0.5);
1159 bus_frame.add(bus_hbox);
1160 bus_frame.set_label_widget(bus_label);
1162 bus_table.set_row_spacings (0);
1163 bus_table.set_col_spacings (0);
1164 bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1165 bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1166 bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
1168 input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
1169 input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
1170 input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
1171 input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
1172 input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
1173 input_table.set_row_spacings(0);
1174 input_table.set_col_spacings(0);
1175 input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
1177 input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
1179 input_label.set_alignment(0, 0.5);
1180 input_label.set_padding(0,0);
1181 input_label.set_line_wrap(false);
1182 input_label.set_selectable(false);
1183 input_label.set_use_markup(true);
1184 input_frame.set_shadow_type(Gtk::SHADOW_NONE);
1185 input_frame.set_label_align(0,0.5);
1186 input_frame.add(input_hbox);
1187 input_frame.set_label_widget(input_label);
1189 _connect_outputs.set_label (_("Automatically connect outputs"));
1190 _connect_outputs.set_flags(Gtk::CAN_FOCUS);
1191 _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
1192 _connect_outputs.set_mode(true);
1193 _connect_outputs.set_active(Config->get_output_auto_connect() != ManualConnect);
1194 _connect_outputs.set_border_width(0);
1195 _limit_output_ports.set_label (_("Use only"));
1196 _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
1197 _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
1198 _limit_output_ports.set_mode(true);
1199 _limit_output_ports.set_sensitive(true);
1200 _limit_output_ports.set_border_width(0);
1201 _output_limit_count.set_flags(Gtk::CAN_FOCUS);
1202 _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1203 _output_limit_count.set_numeric(false);
1204 _output_limit_count.set_digits(0);
1205 _output_limit_count.set_wrap(false);
1206 _output_limit_count.set_sensitive(false);
1207 output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
1208 output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
1209 output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
1211 _connect_outputs_to_master.set_label (_("... to master bus"));
1212 _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
1213 _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
1214 _connect_outputs_to_master.set_mode(true);
1215 _connect_outputs_to_master.set_active(Config->get_output_auto_connect() == AutoConnectMaster);
1216 _connect_outputs_to_master.set_border_width(0);
1218 _connect_outputs_to_master.set_group (connect_outputs_group);
1219 _connect_outputs_to_physical.set_group (connect_outputs_group);
1221 _connect_outputs_to_physical.set_label (_("... to physical outputs"));
1222 _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
1223 _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
1224 _connect_outputs_to_physical.set_mode(true);
1225 _connect_outputs_to_physical.set_active(Config->get_output_auto_connect() == AutoConnectPhysical);
1226 _connect_outputs_to_physical.set_border_width(0);
1228 output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
1229 output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
1230 output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
1231 output_vbox.set_border_width(6);
1233 output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
1235 output_vbox.pack_start(output_conn_vbox);
1236 output_vbox.pack_start(output_port_vbox);
1238 output_label.set_alignment(0, 0.5);
1239 output_label.set_padding(0,0);
1240 output_label.set_line_wrap(false);
1241 output_label.set_selectable(false);
1242 output_label.set_use_markup(true);
1243 output_frame.set_shadow_type(Gtk::SHADOW_NONE);
1244 output_frame.set_label_align(0,0.5);
1246 output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
1248 output_frame.add(output_hbox);
1249 output_frame.set_label_widget(output_label);
1251 more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
1252 more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
1253 more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
1254 more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
1258 _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
1259 _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
1260 _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
1261 _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
1262 _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
1264 /* note that more_options_vbox is "visible" by default even
1265 * though it may not be displayed to the user, this is so the dialog
1268 more_options_vbox.show_all ();
1270 session_options_page_index = append_page (more_options_vbox);
1271 set_page_title (more_options_vbox, _("Advanced Session Options"));
1272 set_page_complete (more_options_vbox, true);
1276 ArdourStartup::create_master_bus() const
1278 return _create_master_bus.get_active();
1282 ArdourStartup::master_channel_count() const
1284 return _master_bus_channel_count.get_value_as_int();
1288 ArdourStartup::connect_inputs() const
1290 return _connect_inputs.get_active();
1294 ArdourStartup::limit_inputs_used_for_connection() const
1296 return _limit_input_ports.get_active();
1300 ArdourStartup::input_limit_count() const
1302 return _input_limit_count.get_value_as_int();
1306 ArdourStartup::connect_outputs() const
1308 return _connect_outputs.get_active();
1312 ArdourStartup::limit_outputs_used_for_connection() const
1314 return _limit_output_ports.get_active();
1318 ArdourStartup::output_limit_count() const
1320 return _output_limit_count.get_value_as_int();
1324 ArdourStartup::connect_outs_to_master() const
1326 return _connect_outputs_to_master.get_active();
1330 ArdourStartup::connect_outs_to_physical() const
1332 return _connect_outputs_to_physical.get_active();
1336 ArdourStartup::connect_inputs_clicked ()
1338 _limit_input_ports.set_sensitive(_connect_inputs.get_active());
1340 if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
1341 _input_limit_count.set_sensitive(true);
1343 _input_limit_count.set_sensitive(false);
1348 ArdourStartup::connect_outputs_clicked ()
1350 bool const co = _connect_outputs.get_active ();
1351 _limit_output_ports.set_sensitive(co);
1352 _connect_outputs_to_master.set_sensitive(co);
1353 _connect_outputs_to_physical.set_sensitive(co);
1355 if (co && _limit_output_ports.get_active()) {
1356 _output_limit_count.set_sensitive(true);
1358 _output_limit_count.set_sensitive(false);
1363 ArdourStartup::limit_inputs_clicked ()
1365 _input_limit_count.set_sensitive(_limit_input_ports.get_active());
1369 ArdourStartup::limit_outputs_clicked ()
1371 _output_limit_count.set_sensitive(_limit_output_ports.get_active());
1375 ArdourStartup::master_bus_button_clicked ()
1377 bool const yn = _create_master_bus.get_active();
1379 _master_bus_channel_count.set_sensitive(yn);
1380 _connect_outputs_to_master.set_sensitive(yn);
1384 ArdourStartup::move_along_now ()
1386 gint cur = get_current_page ();
1388 if (cur == session_page_index) {
1389 if (more_new_session_options_button.get_active()) {
1390 set_current_page (session_options_page_index);
1398 ArdourStartup::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
1400 set_page_complete (session_vbox, true);
1405 ArdourStartup::existing_session_selected ()
1407 _existing_session_chooser_used = true;
1409 set_page_complete (session_vbox, true);
1414 ArdourStartup::been_here_before_path () const
1416 // XXXX use more specific version so we can catch upgrades
1417 return Glib::build_filename (user_config_directory (), ".a3");