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"
35 #include "ardour/filesystem_paths.h"
36 #include "ardour/recent_sessions.h"
37 #include "ardour/session.h"
38 #include "ardour/session_state_utils.h"
39 #include "ardour/template_utils.h"
40 #include "ardour/filename_extensions.h"
42 #include "ardour_ui.h"
45 #include "engine_dialog.h"
54 using namespace ARDOUR;
56 ArdourStartup* ArdourStartup::the_startup = 0;
58 static string poor_mans_glob (string path)
61 replace_all (copy, "~", Glib::get_home_dir());
66 ArdourStartup::ArdourStartup (bool require_new, const std::string& session_name, const std::string& session_path, const std::string& template_name)
67 : _response (RESPONSE_OK)
68 , config_modified (false)
69 , new_only (require_new)
70 , default_dir_chooser (0)
71 , ic_new_session_button (_("Create a new session"))
72 , ic_existing_session_button (_("Open an existing session"))
73 , monitor_via_hardware_button (_("Use an external mixer or the hardware mixer of your audio interface.\n\
74 Ardour will play NO role in monitoring"))
75 , monitor_via_ardour_button (string_compose (_("Ask %1 to play back material as it is being recorded"), PROGRAM_NAME))
77 , new_folder_chooser (FILE_CHOOSER_ACTION_SELECT_FOLDER)
78 , more_new_session_options_button (_("I'd like more options for this session"))
79 , _output_limit_count_adj (1, 0, 100, 1, 10, 0)
80 , _input_limit_count_adj (1, 0, 100, 1, 10, 0)
81 , _master_bus_channel_count_adj (2, 0, 100, 1, 10, 0)
82 , audio_page_index (-1)
83 , new_user_page_index (-1)
84 , default_folder_page_index (-1)
85 , monitoring_page_index (-1)
86 , session_page_index (-1)
87 , initial_choice_index (-1)
88 , final_page_index (-1)
89 , session_options_page_index (-1)
90 , _existing_session_chooser_used (false)
92 new_user = !Glib::file_test (been_here_before_path(), Glib::FILE_TEST_EXISTS);
93 need_audio_setup = EngineControl::need_setup ();
94 need_session_info = (session_name.empty() || require_new);
96 _provided_session_name = session_name;
97 _provided_session_path = session_path;
99 if (need_audio_setup || need_session_info || new_user) {
101 use_template_button.set_group (session_template_group);
102 use_session_as_template_button.set_group (session_template_group);
104 set_keep_above (true);
105 set_position (WIN_POS_CENTER);
106 set_border_width (12);
108 if ((icon_pixbuf = ::get_icon ("ardour_icon_48px")) == 0) {
109 throw failed_constructor();
112 list<Glib::RefPtr<Gdk::Pixbuf> > window_icons;
113 Glib::RefPtr<Gdk::Pixbuf> icon;
115 if ((icon = ::get_icon ("ardour_icon_16px")) != 0) {
116 window_icons.push_back (icon);
118 if ((icon = ::get_icon ("ardour_icon_22px")) != 0) {
119 window_icons.push_back (icon);
121 if ((icon = ::get_icon ("ardour_icon_32px")) != 0) {
122 window_icons.push_back (icon);
124 if ((icon = ::get_icon ("ardour_icon_48px")) != 0) {
125 window_icons.push_back (icon);
127 if (!window_icons.empty ()) {
128 set_default_icon_list (window_icons);
131 // setup_prerelease_page ();
135 setup_new_user_page ();
136 setup_first_time_config_page ();
137 setup_monitoring_choice_page ();
138 setup_monitor_section_choice_page ();
140 if (need_audio_setup) {
144 ic_new_session_button.set_active (true); // always create new session on first run
148 if (need_audio_setup) {
152 setup_initial_choice_page ();
155 setup_session_page ();
156 setup_more_options_page ();
168 if (!template_name.empty()) {
169 use_template_button.set_active (false);
170 load_template_override = template_name;
177 ArdourStartup::~ArdourStartup ()
182 ArdourStartup::ready_without_display () const
184 return !new_user && !need_audio_setup && !need_session_info;
188 ArdourStartup::setup_prerelease_page ()
190 VBox* vbox = manage (new VBox);
191 Label* label = manage (new Label);
192 label->set_markup (_("<b>Welcome to this BETA release of Ardour 3.0</b>\n\n\
193 There are still several issues and bugs to be worked on,\n\
194 as well as general workflow improvements, before this can be considered\n\
195 release software. So, a few guidelines:\n\
197 1) Please do <b>NOT</b> use this software with the expectation that it is stable or reliable\n\
198 though it may be so, depending on your workflow.\n\
199 2) Please see http://ardour.org/a3_features for a guide to new features.\n\
200 3) <b>Please do NOT use the forums at ardour.org to report issues</b>.\n\
201 4) Please <b>DO</b> use the bugtracker at http://tracker.ardour.org/ to report issues\n\
202 making sure to note the product version number as 3.0-beta.\n\
203 5) Please <b>DO</b> use the ardour-users mailing list to discuss ideas and pass on comments.\n\
204 6) Please <b>DO</b> join us on IRC for real time discussions about ardour3. You\n\
205 can get there directly from Ardour via the Help->Chat menu option.\n\
207 Full information on all the above can be found on the support page at\n\
209 http://ardour.org/support\n\
212 vbox->set_border_width (12);
213 vbox->pack_start (*label, false, false, 12);
217 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
218 set_page_title (*vbox, _("This is a BETA RELEASE"));
219 set_page_complete (*vbox, true);
223 ArdourStartup::use_session_template ()
225 if (!load_template_override.empty()) {
229 if (use_template_button.get_active()) {
230 return template_chooser.get_active_row_number() > 0;
232 return !session_template_chooser.get_filename().empty();
237 ArdourStartup::session_template_name ()
239 if (!load_template_override.empty()) {
240 string the_path (ARDOUR::user_template_directory());
241 return Glib::build_filename (the_path, load_template_override + ARDOUR::template_suffix);
244 if (ic_existing_session_button.get_active()) {
248 if (use_template_button.get_active()) {
249 TreeModel::iterator iter = template_chooser.get_active ();
250 TreeModel::Row row = (*iter);
251 string s = row[session_template_columns.path];
254 return session_template_chooser.get_filename();
260 ArdourStartup::session_name (bool& should_be_new)
262 if (ready_without_display()) {
263 return _provided_session_name;
266 if (ic_new_session_button.get_active()) {
267 should_be_new = true;
268 string val = new_name_entry.get_text ();
269 strip_whitespace_edges (val);
271 } else if (_existing_session_chooser_used) {
272 /* existing session chosen from file chooser */
273 should_be_new = false;
274 return existing_session_chooser.get_filename ();
276 /* existing session chosen from recent list */
277 should_be_new = false;
279 TreeIter iter = recent_session_display.get_selection()->get_selected();
282 return (*iter)[recent_session_columns.visible_name];
290 ArdourStartup::session_folder ()
292 if (ready_without_display()) {
293 return _provided_session_path;
296 if (ic_new_session_button.get_active()) {
297 std::string legal_session_folder_name = legalize_for_path (new_name_entry.get_text());
298 return Glib::build_filename (new_folder_chooser.get_current_folder(), legal_session_folder_name);
299 } else if (_existing_session_chooser_used) {
300 /* existing session chosen from file chooser */
301 return existing_session_chooser.get_current_folder ();
303 /* existing session chosen from recent list */
304 TreeIter iter = recent_session_display.get_selection()->get_selected();
307 return (*iter)[recent_session_columns.fullpath];
314 ArdourStartup::setup_audio_page ()
316 engine_dialog = manage (new EngineControl);
318 engine_dialog->set_border_width (12);
320 engine_dialog->show_all ();
322 audio_page_index = append_page (*engine_dialog);
323 set_page_type (*engine_dialog, ASSISTANT_PAGE_CONTENT);
324 set_page_title (*engine_dialog, _("Audio / MIDI Setup"));
326 /* the default parameters should work, so the page is potentially complete */
328 set_page_complete (*engine_dialog, true);
332 ArdourStartup::setup_new_user_page ()
334 Label* foomatic = manage (new Label);
336 foomatic->set_markup (string_compose (_("\
337 <span size=\"larger\">%1 is a digital audio workstation. You can use it to \
338 record, edit and mix multi-track audio. You can produce your \
339 own CDs, mix video soundtracks, or experiment with new \
340 ideas about music and sound. \
342 There are a few things that need to be configured before you start \
343 using the program.</span> \
345 foomatic->set_justify (JUSTIFY_FILL);
346 foomatic->set_line_wrap ();
348 HBox* hbox = manage (new HBox);
349 HBox* vbox = manage (new HBox);
351 vbox->set_border_width (24);
353 hbox->pack_start (*foomatic, true, true);
354 vbox->pack_start (*hbox, true, true);
360 new_user_page_index = append_page (*vbox);
361 set_page_type (*vbox, ASSISTANT_PAGE_INTRO);
362 set_page_title (*vbox, string_compose (_("Welcome to %1"), PROGRAM_NAME));
363 set_page_header_image (*vbox, icon_pixbuf);
364 set_page_complete (*vbox, true);
368 ArdourStartup::default_dir_changed ()
370 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
371 // make new session folder chooser point to the new default
372 new_folder_chooser.set_current_folder (Config->get_default_session_parent_dir());
377 ArdourStartup::config_changed ()
379 config_modified = true;
383 ArdourStartup::setup_first_time_config_page ()
385 default_dir_chooser = manage (new FileChooserButton (string_compose (_("Default folder for %1 sessions"), PROGRAM_NAME),
386 FILE_CHOOSER_ACTION_SELECT_FOLDER));
387 Gtk::Label* txt = manage (new Label);
388 HBox* hbox = manage (new HBox);
389 VBox* vbox = manage (new VBox);
391 txt->set_markup (string_compose (_("\
392 Each project that you work on with %1 has its own folder.\n\
393 These can require a lot of disk space if you are recording audio.\n\
395 Where would you like new %1 sessions to be stored by default?\n\n\
396 <i>(You can put new sessions anywhere, this is just a default)</i>"), PROGRAM_NAME));
397 txt->set_alignment (0.0, 0.0);
399 vbox->set_spacing (18);
400 vbox->set_border_width (24);
402 hbox->pack_start (*default_dir_chooser, false, true, 8);
403 vbox->pack_start (*txt, false, false);
404 vbox->pack_start (*hbox, false, true);
406 default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
407 default_dir_chooser->signal_current_folder_changed().connect (sigc::mem_fun (*this, &ArdourStartup::default_dir_changed));
408 default_dir_chooser->show ();
412 default_folder_page_index = append_page (*vbox);
413 set_page_title (*vbox, _("Default folder for new sessions"));
414 set_page_header_image (*vbox, icon_pixbuf);
415 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
417 /* user can just skip all these settings if they want to */
419 set_page_complete (*vbox, true);
423 ArdourStartup::setup_monitoring_choice_page ()
425 mon_vbox.set_spacing (18);
426 mon_vbox.set_border_width (24);
428 HBox* hbox = manage (new HBox);
429 VBox* vbox = manage (new VBox);
430 RadioButton::Group g (monitor_via_hardware_button.get_group());
431 monitor_via_ardour_button.set_group (g);
433 monitor_label.set_markup(_("\
434 While recording instruments or vocals, you probably want to listen to the\n\
435 signal as well as record it. This is called \"monitoring\". There are\n\
436 different ways to do this depending on the equipment you have and the\n\
437 configuration of that equipment. The two most common are presented here.\n\
438 Please choose whichever one is right for your setup.\n\n\
439 <i>(You can change this preference at any time, via the Preferences dialog)</i>\n\n\
440 <i>If you do not understand what this is about, just accept the default.</i>"));
441 monitor_label.set_alignment (0.0, 0.0);
443 vbox->set_spacing (6);
445 vbox->pack_start (monitor_via_hardware_button, false, true);
446 vbox->pack_start (monitor_via_ardour_button, false, true);
447 hbox->pack_start (*vbox, true, true, 8);
448 mon_vbox.pack_start (monitor_label, false, false);
449 mon_vbox.pack_start (*hbox, false, false);
451 mon_vbox.show_all ();
453 monitoring_page_index = append_page (mon_vbox);
454 set_page_title (mon_vbox, _("Monitoring Choices"));
455 set_page_header_image (mon_vbox, icon_pixbuf);
457 /* user could just click on "Forward" if default
461 set_page_complete (mon_vbox, true);
465 ArdourStartup::setup_monitor_section_choice_page ()
467 mon_sec_vbox.set_spacing (18);
468 mon_sec_vbox.set_border_width (24);
470 HBox* hbox = manage (new HBox);
471 VBox* main_vbox = manage (new VBox);
473 Label* l = manage (new Label);
475 main_vbox->set_spacing (32);
477 no_monitor_section_button.set_label (_("Use a Master bus directly"));
478 l->set_alignment (0.0, 1.0);
479 l->set_markup(_("Connect the Master bus directly to your hardware outputs. This is preferable for simple usage."));
481 vbox = manage (new VBox);
482 vbox->set_spacing (6);
483 vbox->pack_start (no_monitor_section_button, false, true);
484 vbox->pack_start (*l, false, true);
486 main_vbox->pack_start (*vbox, false, false);
488 use_monitor_section_button.set_label (_("Use an additional Monitor bus"));
489 l = manage (new Label);
490 l->set_alignment (0.0, 1.0);
491 l->set_text (_("Use a Monitor bus between Master bus and hardware outputs for \n\
492 greater control in monitoring without affecting the mix."));
494 vbox = manage (new VBox);
495 vbox->set_spacing (6);
496 vbox->pack_start (use_monitor_section_button, false, true);
497 vbox->pack_start (*l, false, true);
499 main_vbox->pack_start (*vbox, false, false);
501 RadioButton::Group g (use_monitor_section_button.get_group());
502 no_monitor_section_button.set_group (g);
504 if (Config->get_use_monitor_bus()) {
505 use_monitor_section_button.set_active (true);
507 no_monitor_section_button.set_active (true);
510 use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
511 no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
513 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\
514 <i>If you do not understand what this is about, just accept the default.</i>"));
515 monitor_section_label.set_alignment (0.0, 0.0);
517 hbox->pack_start (*main_vbox, true, true, 8);
518 mon_sec_vbox.pack_start (*hbox, false, false);
519 mon_sec_vbox.pack_start (monitor_section_label, false, false);
521 mon_sec_vbox.show_all ();
523 monitor_section_page_index = append_page (mon_sec_vbox);
524 set_page_title (mon_sec_vbox, _("Monitor Section"));
525 set_page_header_image (mon_sec_vbox, icon_pixbuf);
527 /* user could just click on "Forward" if default
531 set_page_complete (mon_sec_vbox, true);
535 ArdourStartup::setup_initial_choice_page ()
537 ic_vbox.set_spacing (6);
538 ic_vbox.set_border_width (24);
540 RadioButton::Group g (ic_new_session_button.get_group());
541 ic_existing_session_button.set_group (g);
543 HBox* centering_hbox = manage (new HBox);
544 VBox* centering_vbox = manage (new VBox);
546 centering_vbox->set_spacing (6);
548 centering_vbox->pack_start (ic_new_session_button, false, true);
549 centering_vbox->pack_start (ic_existing_session_button, false, true);
551 ic_new_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
552 ic_new_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
554 ic_existing_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
555 ic_existing_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
557 centering_hbox->pack_start (*centering_vbox, true, true);
559 ic_vbox.pack_start (*centering_hbox, true, true);
563 initial_choice_index = append_page (ic_vbox);
564 set_page_title (ic_vbox, _("What would you like to do ?"));
565 set_page_header_image (ic_vbox, icon_pixbuf);
567 /* user could just click on "Forward" if default
571 set_page_complete (ic_vbox, true);
575 ArdourStartup::initial_button_clicked (GdkEventButton* ev)
577 if (ev->type == GDK_2BUTTON_PRESS && session_page_index != -1) {
578 set_current_page(session_page_index);
585 ArdourStartup::initial_button_activated ()
587 if (session_page_index != -1) {
588 set_current_page(session_page_index);
593 ArdourStartup::setup_session_page ()
595 session_vbox.set_border_width (24);
597 session_vbox.pack_start (session_hbox, true, true);
598 session_vbox.show_all ();
600 session_page_index = append_page (session_vbox);
601 /* initial setting */
602 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
606 ArdourStartup::setup_final_page ()
608 final_page.set_text (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
610 final_page_index = append_page (final_page);
611 set_page_complete (final_page, true);
612 set_page_header_image (final_page, icon_pixbuf);
613 set_page_type (final_page, ASSISTANT_PAGE_CONFIRM);
617 ArdourStartup::on_cancel ()
619 _response = RESPONSE_CANCEL;
624 ArdourStartup::on_delete_event (GdkEventAny*)
626 _response = RESPONSE_CLOSE;
632 ArdourStartup::on_apply ()
635 if (engine_dialog->setup_engine ()) {
636 set_current_page (audio_page_index);
641 if (config_modified) {
643 if (default_dir_chooser) {
644 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
647 if (monitor_via_hardware_button.get_active()) {
648 Config->set_monitoring_model (ExternalMonitoring);
649 } else if (monitor_via_ardour_button.get_active()) {
650 Config->set_monitoring_model (SoftwareMonitoring);
653 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
655 /* "touch" the been-here-before path now that we're about to save Config */
656 ofstream fout (been_here_before_path().c_str());
658 Config->save_state ();
661 _response = RESPONSE_OK;
666 ArdourStartup::on_prepare (Gtk::Widget* page)
668 if (page == &session_vbox) {
670 if (ic_new_session_button.get_active()) {
671 /* new session requested */
672 setup_new_session_page ();
674 /* existing session requested */
675 setup_existing_session_page ();
679 /* HACK HACK HACK ... change the "Apply" button label
683 Gtk::Widget* tl = session_vbox.get_toplevel();
685 if ((win = dynamic_cast<Gtk::Window*>(tl)) != 0) {
686 /* ::get_default_widget() is not wrapped in gtkmm */
687 Gtk::Widget* def = wrap (gtk_window_get_default_widget (win->gobj()));
689 if ((button = dynamic_cast<Gtk::Button*>(def)) != 0) {
690 if (more_new_session_options_button.get_active()) {
691 button->set_label (_("Forward"));
693 button->set_label (_("Open"));
701 ArdourStartup::populate_session_templates ()
703 vector<TemplateInfo> templates;
705 find_session_templates (templates);
707 template_model->clear ();
709 for (vector<TemplateInfo>::iterator x = templates.begin(); x != templates.end(); ++x) {
712 row = *(template_model->append ());
714 row[session_template_columns.name] = (*x).name;
715 row[session_template_columns.path] = (*x).path;
720 lost_name_entry_focus (GdkEventFocus*)
722 // cerr << "lost focus\n";
727 ArdourStartup::setup_new_session_page ()
729 if (!session_hbox.get_children().empty()) {
730 session_hbox.remove (**session_hbox.get_children().begin());
733 session_new_vbox.set_spacing (18);
735 if (session_new_vbox.get_children().empty()) {
736 VBox *vbox1 = manage (new VBox);
737 HBox* hbox1 = manage (new HBox);
738 Label* label1 = manage (new Label);
740 vbox1->set_spacing (6);
742 hbox1->set_spacing (6);
743 hbox1->pack_start (*label1, false, false);
744 hbox1->pack_start (new_name_entry, true, true);
746 label1->set_text (_("Session name:"));
749 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
750 new_name_entry.set_text (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
751 /* name provided - they can move right along */
752 set_page_complete (session_vbox, true);
755 new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_changed));
756 new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &ArdourStartup::move_along_now));
758 vbox1->pack_start (*hbox1, true, true);
762 HBox* hbox2 = manage (new HBox);
763 Label* label2 = manage (new Label);
765 hbox2->set_spacing (6);
766 hbox2->pack_start (*label2, false, false);
767 hbox2->pack_start (new_folder_chooser, true, true);
769 label2->set_text (_("Create session folder in:"));
771 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
772 new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
773 } else if (ARDOUR_UI::instance()->session_loaded) {
774 // point the new session file chooser at the parent directory of the current session
775 string session_parent_dir = Glib::path_get_dirname(ARDOUR_UI::instance()->the_session()->path());
776 string::size_type last_dir_sep = session_parent_dir.rfind(G_DIR_SEPARATOR);
777 session_parent_dir = session_parent_dir.substr(0, last_dir_sep);
778 new_folder_chooser.set_current_folder (session_parent_dir);
779 new_folder_chooser.add_shortcut_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
781 new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
783 new_folder_chooser.set_title (_("Select folder for session"));
786 new_folder_chooser.add_shortcut_folder ("/Volumes");
789 vbox1->pack_start (*hbox2, false, false);
791 session_new_vbox.pack_start (*vbox1, false, false);
795 VBox *vbox2 = manage (new VBox);
796 HBox* hbox3 = manage (new HBox);
797 Label* label3 = manage (new Label);
798 template_model = ListStore::create (session_template_columns);
799 populate_session_templates ();
801 vbox2->set_spacing (6);
803 label3->set_markup (_("<b>Options</b>"));
804 label3->set_alignment (0.0, 0.0);
806 vbox2->pack_start (*label3, false, true);
808 VBox *vbox3 = manage (new VBox);
810 vbox3->set_spacing (6);
812 if (!template_model->children().empty()) {
814 HBox* hbox4a = manage (new HBox);
815 use_template_button.set_label (_("Use this template"));
817 TreeModel::Row row = *template_model->prepend ();
818 row[session_template_columns.name] = (_("no template"));
819 row[session_template_columns.path] = string();
821 hbox4a->set_spacing (6);
822 hbox4a->pack_start (use_template_button, false, false);
823 hbox4a->pack_start (template_chooser, true, true);
825 template_chooser.set_model (template_model);
827 Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
828 text_renderer->property_editable() = false;
830 template_chooser.pack_start (*text_renderer);
831 template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
832 template_chooser.set_active (0);
834 use_template_button.show();
835 template_chooser.show ();
837 vbox3->pack_start (*hbox4a, false, false);
843 session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
845 HBox* hbox4b = manage (new HBox);
846 use_session_as_template_button.set_label (_("Use an existing session as a template:"));
848 hbox4b->set_spacing (6);
849 hbox4b->pack_start (use_session_as_template_button, false, false);
850 hbox4b->pack_start (session_template_chooser, true, true);
852 use_session_as_template_button.show ();
853 session_template_chooser.show ();
855 Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
856 session_filter->add_pattern (X_("*.ardour"));
857 session_template_chooser.set_filter (*session_filter);
858 session_template_chooser.set_title (_("Select template"));
860 vbox3->pack_start (*hbox4b, false, false);
865 HBox* hbox5 = manage (new HBox);
867 hbox5->set_spacing (6);
868 hbox5->pack_start (more_new_session_options_button, false, false);
870 more_new_session_options_button.show ();
871 more_new_session_options_button.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::more_new_session_options_button_clicked));
873 vbox3->pack_start (*hbox5, false, false);
874 hbox3->pack_start (*vbox3, true, true, 8);
875 vbox2->pack_start (*hbox3, false, false);
879 session_new_vbox.pack_start (*vbox2, false, false);
882 session_new_vbox.show_all ();
883 session_hbox.pack_start (session_new_vbox, true, true);
884 set_page_title (session_vbox, _("New Session"));
885 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
887 if (more_new_session_options_button.get_active()) {
888 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
891 new_name_entry.signal_map().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_mapped));
892 new_name_entry.signal_focus_out_event().connect (sigc::ptr_fun (lost_name_entry_focus));
896 ArdourStartup::new_name_mapped ()
898 // cerr << "Grab new name focus\n";
899 new_name_entry.grab_focus ();
903 ArdourStartup::new_name_changed ()
905 if (!new_name_entry.get_text().empty()) {
906 set_page_complete (session_vbox, true);
908 set_page_complete (session_vbox, false);
913 ArdourStartup::redisplay_recent_sessions ()
915 std::vector<std::string> session_directories;
916 RecentSessionsSorter cmp;
918 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
919 recent_session_model->clear ();
921 ARDOUR::RecentSessions rs;
922 ARDOUR::read_recent_sessions (rs);
925 recent_session_display.set_model (recent_session_model);
929 // sort them alphabetically
930 sort (rs.begin(), rs.end(), cmp);
932 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
933 session_directories.push_back ((*i).second);
936 int session_snapshot_count = 0;
938 for (vector<std::string>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
940 std::vector<std::string> state_file_paths;
942 // now get available states for this session
944 get_state_files_in_directory (*i, state_file_paths);
946 vector<string*>* states;
947 vector<const gchar*> item;
948 string fullpath = *i;
950 /* remove any trailing / */
952 if (fullpath[fullpath.length()-1] == '/') {
953 fullpath = fullpath.substr (0, fullpath.length()-1);
956 /* check whether session still exists */
957 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
958 /* session doesn't exist */
962 /* now get available states for this session */
964 if ((states = Session::possible_states (fullpath)) == 0) {
969 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
971 Gtk::TreeModel::Row row = *(recent_session_model->append());
973 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
974 row[recent_session_columns.fullpath] = fullpath;
976 ++session_snapshot_count;
978 if (state_file_names.size() > 1) {
982 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
983 i2 != state_file_names.end(); ++i2)
986 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
988 child_row[recent_session_columns.visible_name] = *i2;
989 child_row[recent_session_columns.fullpath] = fullpath;
990 ++session_snapshot_count;
995 recent_session_display.set_tooltip_column(1); // recent_session_columns.fullpath
996 recent_session_display.set_model (recent_session_model);
997 return session_snapshot_count;
1002 ArdourStartup::recent_session_row_selected ()
1004 if (recent_session_display.get_selection()->count_selected_rows() > 0) {
1005 set_page_complete (session_vbox, true);
1007 set_page_complete (session_vbox, false);
1012 ArdourStartup::setup_existing_session_page ()
1014 recent_session_model = TreeStore::create (recent_session_columns);
1015 redisplay_recent_sessions ();
1017 if (!session_hbox.get_children().empty()) {
1018 session_hbox.remove (**session_hbox.get_children().begin());
1021 if (session_existing_vbox.get_children().empty()) {
1023 recent_session_display.set_model (recent_session_model);
1024 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1025 recent_session_display.set_headers_visible (false);
1026 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
1028 recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::recent_session_row_selected));
1030 recent_scroller.add (recent_session_display);
1031 recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1032 recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
1034 recent_session_display.show();
1036 recent_scroller.show();
1037 int cnt = redisplay_recent_sessions ();
1038 recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ArdourStartup::recent_row_activated));
1041 recent_scroller.set_size_request (-1, 300);
1044 session_existing_vbox.set_spacing (8);
1045 session_existing_vbox.pack_start (recent_scroller, true, true);
1047 existing_session_chooser.set_title (_("Select session file"));
1048 existing_session_chooser.signal_file_set().connect (sigc::mem_fun (*this, &ArdourStartup::existing_session_selected));
1049 existing_session_chooser.set_current_folder(poor_mans_glob (Config->get_default_session_parent_dir()));
1051 FileFilter session_filter;
1052 session_filter.add_pattern ("*.ardour");
1053 session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
1054 existing_session_chooser.add_filter (session_filter);
1055 existing_session_chooser.set_filter (session_filter);
1058 existing_session_chooser.add_shortcut_folder ("/Volumes");
1061 HBox* hbox = manage (new HBox);
1062 hbox->set_spacing (4);
1063 hbox->pack_start (*manage (new Label (_("Browse:"))), PACK_SHRINK);
1064 hbox->pack_start (existing_session_chooser);
1065 session_existing_vbox.pack_start (*hbox, false, false);
1069 session_existing_vbox.show_all ();
1070 session_hbox.pack_start (session_existing_vbox, true, true);
1072 set_page_title (session_vbox, _("Select a session"));
1073 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1077 ArdourStartup::more_new_session_options_button_clicked ()
1079 if (more_new_session_options_button.get_active()) {
1080 more_options_vbox.show_all ();
1081 set_page_type (more_options_vbox, ASSISTANT_PAGE_CONFIRM);
1082 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
1084 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1085 more_options_vbox.hide ();
1090 ArdourStartup::setup_more_options_page ()
1092 more_options_vbox.set_border_width (24);
1094 _output_limit_count.set_adjustment (_output_limit_count_adj);
1095 _input_limit_count.set_adjustment (_input_limit_count_adj);
1096 _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
1098 chan_count_label_1.set_text (_("channels"));
1099 chan_count_label_3.set_text (_("channels"));
1100 chan_count_label_4.set_text (_("channels"));
1102 chan_count_label_1.set_alignment(0,0.5);
1103 chan_count_label_1.set_padding(0,0);
1104 chan_count_label_1.set_line_wrap(false);
1106 chan_count_label_3.set_alignment(0,0.5);
1107 chan_count_label_3.set_padding(0,0);
1108 chan_count_label_3.set_line_wrap(false);
1110 chan_count_label_4.set_alignment(0,0.5);
1111 chan_count_label_4.set_padding(0,0);
1112 chan_count_label_4.set_line_wrap(false);
1114 bus_label.set_markup (_("<b>Busses</b>"));
1115 input_label.set_markup (_("<b>Inputs</b>"));
1116 output_label.set_markup (_("<b>Outputs</b>"));
1118 _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
1119 _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1120 _master_bus_channel_count.set_numeric(true);
1121 _master_bus_channel_count.set_digits(0);
1122 _master_bus_channel_count.set_wrap(false);
1124 _create_master_bus.set_label (_("Create master bus"));
1125 _create_master_bus.set_flags(Gtk::CAN_FOCUS);
1126 _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
1127 _create_master_bus.set_mode(true);
1128 _create_master_bus.set_active(true);
1129 _create_master_bus.set_border_width(0);
1131 advanced_table.set_row_spacings(0);
1132 advanced_table.set_col_spacings(0);
1134 _connect_inputs.set_label (_("Automatically connect to physical inputs"));
1135 _connect_inputs.set_flags(Gtk::CAN_FOCUS);
1136 _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
1137 _connect_inputs.set_mode(true);
1138 _connect_inputs.set_active(Config->get_input_auto_connect() != ManualConnect);
1139 _connect_inputs.set_border_width(0);
1141 _limit_input_ports.set_label (_("Use only"));
1142 _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
1143 _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
1144 _limit_input_ports.set_mode(true);
1145 _limit_input_ports.set_sensitive(true);
1146 _limit_input_ports.set_border_width(0);
1148 _input_limit_count.set_flags(Gtk::CAN_FOCUS);
1149 _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1150 _input_limit_count.set_numeric(true);
1151 _input_limit_count.set_digits(0);
1152 _input_limit_count.set_wrap(false);
1153 _input_limit_count.set_sensitive(false);
1155 bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
1157 bus_label.set_alignment(0, 0.5);
1158 bus_label.set_padding(0,0);
1159 bus_label.set_line_wrap(false);
1160 bus_label.set_selectable(false);
1161 bus_label.set_use_markup(true);
1162 bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
1163 bus_frame.set_label_align(0,0.5);
1164 bus_frame.add(bus_hbox);
1165 bus_frame.set_label_widget(bus_label);
1167 bus_table.set_row_spacings (0);
1168 bus_table.set_col_spacings (0);
1169 bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1170 bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1171 bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
1173 input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
1174 input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
1175 input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
1176 input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
1177 input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
1178 input_table.set_row_spacings(0);
1179 input_table.set_col_spacings(0);
1180 input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
1182 input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
1184 input_label.set_alignment(0, 0.5);
1185 input_label.set_padding(0,0);
1186 input_label.set_line_wrap(false);
1187 input_label.set_selectable(false);
1188 input_label.set_use_markup(true);
1189 input_frame.set_shadow_type(Gtk::SHADOW_NONE);
1190 input_frame.set_label_align(0,0.5);
1191 input_frame.add(input_hbox);
1192 input_frame.set_label_widget(input_label);
1194 _connect_outputs.set_label (_("Automatically connect outputs"));
1195 _connect_outputs.set_flags(Gtk::CAN_FOCUS);
1196 _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
1197 _connect_outputs.set_mode(true);
1198 _connect_outputs.set_active(Config->get_output_auto_connect() != ManualConnect);
1199 _connect_outputs.set_border_width(0);
1200 _limit_output_ports.set_label (_("Use only"));
1201 _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
1202 _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
1203 _limit_output_ports.set_mode(true);
1204 _limit_output_ports.set_sensitive(true);
1205 _limit_output_ports.set_border_width(0);
1206 _output_limit_count.set_flags(Gtk::CAN_FOCUS);
1207 _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1208 _output_limit_count.set_numeric(false);
1209 _output_limit_count.set_digits(0);
1210 _output_limit_count.set_wrap(false);
1211 _output_limit_count.set_sensitive(false);
1212 output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
1213 output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
1214 output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
1216 _connect_outputs_to_master.set_label (_("... to master bus"));
1217 _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
1218 _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
1219 _connect_outputs_to_master.set_mode(true);
1220 _connect_outputs_to_master.set_active(Config->get_output_auto_connect() == AutoConnectMaster);
1221 _connect_outputs_to_master.set_border_width(0);
1223 _connect_outputs_to_master.set_group (connect_outputs_group);
1224 _connect_outputs_to_physical.set_group (connect_outputs_group);
1226 _connect_outputs_to_physical.set_label (_("... to physical outputs"));
1227 _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
1228 _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
1229 _connect_outputs_to_physical.set_mode(true);
1230 _connect_outputs_to_physical.set_active(Config->get_output_auto_connect() == AutoConnectPhysical);
1231 _connect_outputs_to_physical.set_border_width(0);
1233 output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
1234 output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
1235 output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
1236 output_vbox.set_border_width(6);
1238 output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
1240 output_vbox.pack_start(output_conn_vbox);
1241 output_vbox.pack_start(output_port_vbox);
1243 output_label.set_alignment(0, 0.5);
1244 output_label.set_padding(0,0);
1245 output_label.set_line_wrap(false);
1246 output_label.set_selectable(false);
1247 output_label.set_use_markup(true);
1248 output_frame.set_shadow_type(Gtk::SHADOW_NONE);
1249 output_frame.set_label_align(0,0.5);
1251 output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
1253 output_frame.add(output_hbox);
1254 output_frame.set_label_widget(output_label);
1256 more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
1257 more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
1258 more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
1259 more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
1263 _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
1264 _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
1265 _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
1266 _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
1267 _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
1269 /* note that more_options_vbox is "visible" by default even
1270 * though it may not be displayed to the user, this is so the dialog
1273 more_options_vbox.show_all ();
1275 session_options_page_index = append_page (more_options_vbox);
1276 set_page_title (more_options_vbox, _("Advanced Session Options"));
1277 set_page_complete (more_options_vbox, true);
1281 ArdourStartup::create_master_bus() const
1283 return _create_master_bus.get_active();
1287 ArdourStartup::master_channel_count() const
1289 return _master_bus_channel_count.get_value_as_int();
1293 ArdourStartup::connect_inputs() const
1295 return _connect_inputs.get_active();
1299 ArdourStartup::limit_inputs_used_for_connection() const
1301 return _limit_input_ports.get_active();
1305 ArdourStartup::input_limit_count() const
1307 return _input_limit_count.get_value_as_int();
1311 ArdourStartup::connect_outputs() const
1313 return _connect_outputs.get_active();
1317 ArdourStartup::limit_outputs_used_for_connection() const
1319 return _limit_output_ports.get_active();
1323 ArdourStartup::output_limit_count() const
1325 return _output_limit_count.get_value_as_int();
1329 ArdourStartup::connect_outs_to_master() const
1331 return _connect_outputs_to_master.get_active();
1335 ArdourStartup::connect_outs_to_physical() const
1337 return _connect_outputs_to_physical.get_active();
1341 ArdourStartup::connect_inputs_clicked ()
1343 _limit_input_ports.set_sensitive(_connect_inputs.get_active());
1345 if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
1346 _input_limit_count.set_sensitive(true);
1348 _input_limit_count.set_sensitive(false);
1353 ArdourStartup::connect_outputs_clicked ()
1355 bool const co = _connect_outputs.get_active ();
1356 _limit_output_ports.set_sensitive(co);
1357 _connect_outputs_to_master.set_sensitive(co);
1358 _connect_outputs_to_physical.set_sensitive(co);
1360 if (co && _limit_output_ports.get_active()) {
1361 _output_limit_count.set_sensitive(true);
1363 _output_limit_count.set_sensitive(false);
1368 ArdourStartup::limit_inputs_clicked ()
1370 _input_limit_count.set_sensitive(_limit_input_ports.get_active());
1374 ArdourStartup::limit_outputs_clicked ()
1376 _output_limit_count.set_sensitive(_limit_output_ports.get_active());
1380 ArdourStartup::master_bus_button_clicked ()
1382 bool const yn = _create_master_bus.get_active();
1384 _master_bus_channel_count.set_sensitive(yn);
1385 _connect_outputs_to_master.set_sensitive(yn);
1389 ArdourStartup::move_along_now ()
1391 gint cur = get_current_page ();
1393 if (cur == session_page_index) {
1394 if (more_new_session_options_button.get_active()) {
1395 set_current_page (session_options_page_index);
1403 ArdourStartup::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
1405 set_page_complete (session_vbox, true);
1410 ArdourStartup::existing_session_selected ()
1412 _existing_session_chooser_used = true;
1414 set_page_complete (session_vbox, true);
1419 ArdourStartup::been_here_before_path () const
1421 // XXXX use more specific version so we can catch upgrades
1422 return Glib::build_filename (user_config_directory (), ".a3");