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/filesystem.h"
33 #include "pbd/replace_all.h"
34 #include "pbd/whitespace.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"
44 #include "engine_dialog.h"
53 using namespace ARDOUR;
55 ArdourStartup* ArdourStartup::the_startup = 0;
57 static string poor_mans_glob (string path)
60 replace_all (copy, "~", Glib::get_home_dir());
65 ArdourStartup::ArdourStartup ()
66 : _response (RESPONSE_OK)
67 , ic_new_session_button (_("Create a new session"))
68 , ic_existing_session_button (_("Open an existing session"))
69 , monitor_via_hardware_button (_("Use an external mixer or the hardware mixer of your audio interface.\n\
70 Ardour will play NO role in monitoring"))
71 , monitor_via_ardour_button (string_compose (_("Ask %1 to play back material as it is being recorded"), PROGRAM_NAME))
72 , new_folder_chooser (FILE_CHOOSER_ACTION_SELECT_FOLDER)
73 , more_new_session_options_button (_("I'd like more options for this session"))
74 , _output_limit_count_adj (1, 0, 100, 1, 10, 0)
75 , _input_limit_count_adj (1, 0, 100, 1, 10, 0)
76 , _master_bus_channel_count_adj (2, 0, 100, 1, 10, 0)
77 , _existing_session_chooser_used (false)
79 audio_page_index = -1;
80 initial_choice_index = -1;
81 new_user_page_index = -1;
82 default_folder_page_index = -1;
83 monitoring_page_index = -1;
84 new_session_page_index = -1;
85 final_page_index = -1;
86 session_options_page_index = -1;
90 config_modified = false;
91 default_dir_chooser = 0;
93 use_template_button.set_group (session_template_group);
94 use_session_as_template_button.set_group (session_template_group);
96 set_keep_above (true);
97 set_resizable (false);
98 set_position (WIN_POS_CENTER);
99 set_border_width (12);
101 if ((icon_pixbuf = ::get_icon ("ardour_icon_48px")) == 0) {
102 throw failed_constructor();
105 list<Glib::RefPtr<Gdk::Pixbuf> > window_icons;
106 Glib::RefPtr<Gdk::Pixbuf> icon;
108 if ((icon = ::get_icon ("ardour_icon_16px")) != 0) {
109 window_icons.push_back (icon);
111 if ((icon = ::get_icon ("ardour_icon_22px")) != 0) {
112 window_icons.push_back (icon);
114 if ((icon = ::get_icon ("ardour_icon_32px")) != 0) {
115 window_icons.push_back (icon);
117 if ((icon = ::get_icon ("ardour_icon_48px")) != 0) {
118 window_icons.push_back (icon);
120 if (!window_icons.empty ()) {
121 set_default_icon_list (window_icons);
124 new_user = !exists (been_here_before_path ());
126 bool need_audio_setup = !EngineControl::engine_running();
128 setup_prerelease_page ();
132 /* Create the config directory so that we have somewhere to put the
133 been_here_before file.
136 sys::create_directories (user_config_directory ());
138 catch (const sys::filesystem_error& ex) {
139 error << "Could not create user configuration directory" << endmsg;
142 setup_new_user_page ();
143 setup_first_time_config_page ();
144 setup_monitoring_choice_page ();
145 setup_monitor_section_choice_page ();
147 if (need_audio_setup) {
153 if (need_audio_setup) {
157 setup_initial_choice_page ();
160 setup_new_session_page ();
161 setup_more_options_page ();
170 ArdourStartup::~ArdourStartup ()
175 ArdourStartup::setup_prerelease_page ()
177 VBox* vbox = manage (new VBox);
178 Label* label = manage (new Label);
179 label->set_markup (_("<b>Welcome to this BETA release of Ardour 3.0</b>\n\n\
180 There are still several issues and bugs to be worked on,\n\
181 as well as general workflow improvements, before this can be considered\n\
182 release software. So, a few guidelines:\n\
184 1) Please do <b>NOT</b> use this software with the expectation that it is stable or reliable\n\
185 though it may be so, depending on your workflow.\n\
186 2) Please see http://ardour.org/a3_features for a guide to new features.\n\
187 3) <b>Please do NOT use the forums at ardour.org to report issues</b>.\n\
188 4) Please <b>DO</b> use the bugtracker at http://tracker.ardour.org/ to report issues\n\
189 making sure to note the product version number as 3.0-beta.\n\
190 5) Please <b>DO</b> use the ardour-users mailing list to discuss ideas and pass on comments.\n\
191 6) Please <b>DO</b> join us on IRC for real time discussions about ardour3. You\n\
192 can get there directly from Ardour via the Help->Chat menu option.\n\
194 Full information on all the above can be found on the support page at\n\
196 http://ardour.org/support\n\
199 vbox->set_border_width (12);
200 vbox->pack_start (*label, false, false, 12);
204 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
205 set_page_title (*vbox, _("This is a BETA RELEASE"));
206 set_page_complete (*vbox, true);
210 ArdourStartup::set_new_only (bool yn)
222 ArdourStartup::set_load_template (string load_template)
224 use_template_button.set_active (false);
225 load_template_override = load_template;
229 ArdourStartup::use_session_template ()
231 if (!load_template_override.empty()) {
235 if (use_template_button.get_active()) {
236 return template_chooser.get_active_row_number() > 0;
238 return !session_template_chooser.get_filename().empty();
243 ArdourStartup::session_template_name ()
245 if (!load_template_override.empty()) {
246 string the_path = (ARDOUR::user_template_directory()/ (load_template_override + ".template")).to_string();
250 if (ic_existing_session_button.get_active()) {
254 if (use_template_button.get_active()) {
255 TreeModel::iterator iter = template_chooser.get_active ();
256 TreeModel::Row row = (*iter);
257 string s = row[session_template_columns.path];
260 return session_template_chooser.get_filename();
266 ArdourStartup::session_name (bool& should_be_new)
268 if (ic_new_session_button.get_active()) {
269 should_be_new = true;
270 string val = new_name_entry.get_text ();
271 strip_whitespace_edges (val);
273 } else if (_existing_session_chooser_used) {
274 /* existing session chosen from file chooser */
275 should_be_new = false;
276 return existing_session_chooser.get_filename ();
278 /* existing session chosen from recent list */
279 should_be_new = false;
281 TreeIter iter = recent_session_display.get_selection()->get_selected();
284 return (*iter)[recent_session_columns.visible_name];
292 ArdourStartup::session_folder ()
294 if (ic_new_session_button.get_active()) {
295 std::string legal_session_folder_name = legalize_for_path (new_name_entry.get_text());
296 return Glib::build_filename (new_folder_chooser.get_current_folder(), legal_session_folder_name);
297 } else if (_existing_session_chooser_used) {
298 /* existing session chosen from file chooser */
299 return existing_session_chooser.get_current_folder ();
301 /* existing session chosen from recent list */
302 TreeIter iter = recent_session_display.get_selection()->get_selected();
305 return (*iter)[recent_session_columns.fullpath];
312 ArdourStartup::setup_audio_page ()
314 engine_dialog = manage (new EngineControl);
316 engine_dialog->set_border_width (12);
318 engine_dialog->show_all ();
320 audio_page_index = append_page (*engine_dialog);
321 set_page_type (*engine_dialog, ASSISTANT_PAGE_CONTENT);
322 set_page_title (*engine_dialog, _("Audio / MIDI Setup"));
324 /* the default parameters should work, so the page is potentially complete */
326 set_page_complete (*engine_dialog, true);
330 ArdourStartup::setup_new_user_page ()
332 Label* foomatic = manage (new Label);
334 foomatic->set_markup (string_compose (_("\
335 <span size=\"larger\">%1 is a digital audio workstation. You can use it to \
336 record, edit and mix multi-track audio. You can produce your \
337 own CDs, mix video soundtracks, or experiment with new \
338 ideas about music and sound. \
340 There are a few things that need to be configured before you start \
341 using the program.</span> \
343 foomatic->set_justify (JUSTIFY_FILL);
344 foomatic->set_line_wrap ();
346 HBox* hbox = manage (new HBox);
347 HBox* vbox = manage (new HBox);
349 vbox->set_border_width (24);
351 hbox->pack_start (*foomatic, true, true);
352 vbox->pack_start (*hbox, true, true);
358 new_user_page_index = append_page (*vbox);
359 set_page_type (*vbox, ASSISTANT_PAGE_INTRO);
360 set_page_title (*vbox, string_compose (_("Welcome to %1"), PROGRAM_NAME));
361 set_page_header_image (*vbox, icon_pixbuf);
362 set_page_complete (*vbox, true);
366 ArdourStartup::default_dir_changed ()
368 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
373 ArdourStartup::config_changed ()
375 config_modified = true;
379 ArdourStartup::setup_first_time_config_page ()
381 default_dir_chooser = manage (new FileChooserButton (string_compose (_("Default folder for %1 sessions"), PROGRAM_NAME),
382 FILE_CHOOSER_ACTION_SELECT_FOLDER));
383 Gtk::Label* txt = manage (new Label);
384 HBox* hbox = manage (new HBox);
385 VBox* vbox = manage (new VBox);
387 txt->set_markup (string_compose (_("\
388 Each project that you work on with %1 has its own folder.\n\
389 These can require a lot of disk space if you are recording audio.\n\
391 Where would you like new %1 sessions to be stored by default?\n\n\
392 <i>(You can put new sessions anywhere, this is just a default)</i>"), PROGRAM_NAME));
393 txt->set_alignment (0.0, 0.0);
395 vbox->set_spacing (18);
396 vbox->set_border_width (24);
398 hbox->pack_start (*default_dir_chooser, false, true, 8);
399 vbox->pack_start (*txt, false, false);
400 vbox->pack_start (*hbox, false, true);
402 default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
403 default_dir_chooser->signal_current_folder_changed().connect (sigc::mem_fun (*this, &ArdourStartup::default_dir_changed));
404 default_dir_chooser->show ();
408 default_folder_page_index = append_page (*vbox);
409 set_page_title (*vbox, _("Default folder for new sessions"));
410 set_page_header_image (*vbox, icon_pixbuf);
411 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
413 /* user can just skip all these settings if they want to */
415 set_page_complete (*vbox, true);
419 ArdourStartup::setup_monitoring_choice_page ()
421 mon_vbox.set_spacing (18);
422 mon_vbox.set_border_width (24);
424 HBox* hbox = manage (new HBox);
425 VBox* vbox = manage (new VBox);
426 RadioButton::Group g (monitor_via_hardware_button.get_group());
427 monitor_via_ardour_button.set_group (g);
429 monitor_label.set_markup(_("\
430 While recording instruments or vocals, you probably want to listen to the\n\
431 signal as well as record it. This is called \"monitoring\". There are\n\
432 different ways to do this depending on the equipment you have and the\n\
433 configuration of that equipment. The two most common are presented here.\n\
434 Please choose whichever one is right for your setup.\n\n\
435 <i>(You can change this preference at any time, via the Preferences dialog)</i>\n\n\
436 <i>If you do not understand what this is about, just accept the default.</i>"));
437 monitor_label.set_alignment (0.0, 0.0);
439 vbox->set_spacing (6);
441 vbox->pack_start (monitor_via_hardware_button, false, true);
442 vbox->pack_start (monitor_via_ardour_button, false, true);
443 hbox->pack_start (*vbox, true, true, 8);
444 mon_vbox.pack_start (monitor_label, false, false);
445 mon_vbox.pack_start (*hbox, false, false);
447 mon_vbox.show_all ();
449 monitoring_page_index = append_page (mon_vbox);
450 set_page_title (mon_vbox, _("Monitoring Choices"));
451 set_page_header_image (mon_vbox, icon_pixbuf);
453 /* user could just click on "Forward" if default
457 set_page_complete (mon_vbox, true);
461 ArdourStartup::setup_monitor_section_choice_page ()
463 mon_sec_vbox.set_spacing (18);
464 mon_sec_vbox.set_border_width (24);
466 HBox* hbox = manage (new HBox);
467 VBox* main_vbox = manage (new VBox);
469 Label* l = manage (new Label);
471 main_vbox->set_spacing (32);
473 no_monitor_section_button.set_label (_("Use a Master bus directly"));
474 l->set_alignment (0.0, 1.0);
475 l->set_markup(_("Connect the Master bus directly to your hardware outputs. This is preferable for simple usage."));
477 vbox = manage (new VBox);
478 vbox->set_spacing (6);
479 vbox->pack_start (no_monitor_section_button, false, true);
480 vbox->pack_start (*l, false, true);
482 main_vbox->pack_start (*vbox, false, false);
484 use_monitor_section_button.set_label (_("Use an additional Monitor bus"));
485 l = manage (new Label);
486 l->set_alignment (0.0, 1.0);
487 l->set_text (_("Use a Monitor bus between Master bus and hardware outputs for \n\
488 greater control in monitoring without affecting the mix."));
490 vbox = manage (new VBox);
491 vbox->set_spacing (6);
492 vbox->pack_start (use_monitor_section_button, false, true);
493 vbox->pack_start (*l, false, true);
495 main_vbox->pack_start (*vbox, false, false);
497 RadioButton::Group g (use_monitor_section_button.get_group());
498 no_monitor_section_button.set_group (g);
500 if (Config->get_use_monitor_bus()) {
501 use_monitor_section_button.set_active (true);
503 no_monitor_section_button.set_active (true);
506 use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
507 no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
509 monitor_section_label.set_markup(_("<i>You can change this preference at any time, via the Preferences dialog). You can also add or remove the monitor section to/from any session.</i>\n\n\
510 <i>If you do not understand what this is about, just accept the default.</i>"));
511 monitor_section_label.set_alignment (0.0, 0.0);
513 hbox->pack_start (*main_vbox, true, true, 8);
514 mon_sec_vbox.pack_start (*hbox, false, false);
515 mon_sec_vbox.pack_start (monitor_section_label, false, false);
517 mon_sec_vbox.show_all ();
519 monitor_section_page_index = append_page (mon_sec_vbox);
520 set_page_title (mon_sec_vbox, _("Monitor Section"));
521 set_page_header_image (mon_sec_vbox, icon_pixbuf);
523 /* user could just click on "Forward" if default
527 set_page_complete (mon_sec_vbox, true);
531 ArdourStartup::setup_initial_choice_page ()
533 initial_choice_index = append_page (ic_vbox);
534 set_page_title (ic_vbox, _("What would you like to do ?"));
535 set_page_header_image (ic_vbox, icon_pixbuf);
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 recent_session_model = TreeStore::create (recent_session_columns);
552 redisplay_recent_sessions ();
554 if (!new_session_hbox.get_children().empty()) {
555 new_session_hbox.remove (**new_session_hbox.get_children().begin());
558 if (session_existing_vbox.get_children().empty()) {
560 recent_session_display.set_model (recent_session_model);
561 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
562 recent_session_display.set_headers_visible (false);
563 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
565 recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::recent_session_row_selected));
567 recent_scroller.add (recent_session_display);
568 recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
569 recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
571 recent_session_display.show();
573 recent_scroller.show();
574 int cnt = redisplay_recent_sessions ();
575 recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ArdourStartup::recent_row_activated));
578 recent_scroller.set_size_request (-1, 300);
581 centering_vbox->pack_start (recent_scroller, true, true);
583 existing_session_chooser.set_title (_("Select session file"));
584 existing_session_chooser.signal_file_set().connect (sigc::mem_fun (*this, &ArdourStartup::existing_session_selected));
587 existing_session_chooser.add_shortcut_folder ("/Volumes");
590 HBox* hbox = manage (new HBox);
591 hbox->set_spacing (4);
592 hbox->pack_start (*manage (new Label (_("Browse:"))), PACK_SHRINK);
593 hbox->pack_start (existing_session_chooser);
594 centering_vbox->pack_start (*hbox, false, false);
598 ic_new_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_press), false);
599 ic_new_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
601 ic_existing_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_press), false);
602 ic_existing_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
604 centering_hbox->pack_start (*centering_vbox, true, true);
606 ic_vbox.pack_start (*centering_hbox, true, true);
610 /* user could just click on "Forward" if default
614 set_page_complete (ic_vbox, true);
618 ArdourStartup::initial_button_press (GdkEventButton *event)
620 if (event && event->type == GDK_2BUTTON_PRESS && new_session_page_index != -1) {
621 set_current_page (new_session_page_index);
629 ArdourStartup::initial_button_activated ()
631 set_current_page (new_session_page_index);
635 ArdourStartup::setup_final_page ()
637 final_page.set_text (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
639 final_page_index = append_page (final_page);
640 set_page_complete (final_page, true);
641 set_page_header_image (final_page, icon_pixbuf);
642 set_page_type (final_page, ASSISTANT_PAGE_CONFIRM);
646 ArdourStartup::on_cancel ()
648 _response = RESPONSE_CANCEL;
653 ArdourStartup::on_delete_event (GdkEventAny*)
655 _response = RESPONSE_CLOSE;
661 ArdourStartup::on_apply ()
664 engine_dialog->setup_engine ();
667 if (config_modified) {
669 if (default_dir_chooser) {
670 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
673 if (monitor_via_hardware_button.get_active()) {
674 Config->set_monitoring_model (ExternalMonitoring);
675 } else if (monitor_via_ardour_button.get_active()) {
676 Config->set_monitoring_model (SoftwareMonitoring);
679 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
681 /* "touch" the been-here-before path now that we're about to save Config */
682 ofstream fout (been_here_before_path().to_string().c_str());
684 Config->save_state ();
687 _response = RESPONSE_OK;
692 ArdourStartup::on_prepare (Gtk::Widget* page)
694 if (page == &new_session_vbox) {
696 /* HACK HACK HACK ... change the "Apply" button label
700 Gtk::Widget* tl = new_session_vbox.get_toplevel();
702 if ((win = dynamic_cast<Gtk::Window*>(tl)) != 0) {
703 /* ::get_default_widget() is not wrapped in gtkmm */
704 Gtk::Widget* def = wrap (gtk_window_get_default_widget (win->gobj()));
706 if ((button = dynamic_cast<Gtk::Button*>(def)) != 0) {
707 if (more_new_session_options_button.get_active()) {
708 button->set_label (_("Forward"));
710 button->set_label (_("Open"));
718 ArdourStartup::populate_session_templates ()
720 vector<TemplateInfo> templates;
722 find_session_templates (templates);
724 template_model->clear ();
726 for (vector<TemplateInfo>::iterator x = templates.begin(); x != templates.end(); ++x) {
729 row = *(template_model->append ());
731 row[session_template_columns.name] = (*x).name;
732 row[session_template_columns.path] = (*x).path;
737 lost_name_entry_focus (GdkEventFocus*)
739 cerr << "lost focus\n";
744 ArdourStartup::setup_new_session_page ()
746 if (!new_session_hbox.get_children().empty()) {
747 new_session_hbox.remove (**new_session_hbox.get_children().begin());
750 session_new_vbox.set_spacing (18);
752 if (session_new_vbox.get_children().empty()) {
753 VBox *vbox1 = manage (new VBox);
754 HBox* hbox1 = manage (new HBox);
755 Label* label1 = manage (new Label);
757 vbox1->set_spacing (6);
759 hbox1->set_spacing (6);
760 hbox1->pack_start (*label1, false, false);
761 hbox1->pack_start (new_name_entry, true, true);
763 label1->set_text (_("Session name:"));
765 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
766 new_name_entry.set_text (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
767 /* name provided - they can move right along */
768 set_page_complete (new_session_vbox, true);
771 new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_changed));
772 new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &ArdourStartup::move_along_now));
774 vbox1->pack_start (*hbox1, true, true);
778 HBox* hbox2 = manage (new HBox);
779 Label* label2 = manage (new Label);
781 hbox2->set_spacing (6);
782 hbox2->pack_start (*label2, false, false);
783 hbox2->pack_start (new_folder_chooser, true, true);
785 label2->set_text (_("Create session folder in:"));
787 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
788 new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
790 new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
792 new_folder_chooser.set_title (_("Select folder for session"));
795 new_folder_chooser.add_shortcut_folder ("/Volumes");
798 vbox1->pack_start (*hbox2, false, false);
800 session_new_vbox.pack_start (*vbox1, false, false);
804 VBox *vbox2 = manage (new VBox);
805 HBox* hbox3 = manage (new HBox);
806 Label* label3 = manage (new Label);
807 template_model = ListStore::create (session_template_columns);
808 populate_session_templates ();
810 vbox2->set_spacing (6);
812 label3->set_markup (_("<b>Options</b>"));
813 label3->set_alignment (0.0, 0.0);
815 vbox2->pack_start (*label3, false, true);
817 VBox *vbox3 = manage (new VBox);
819 vbox3->set_spacing (6);
821 if (!template_model->children().empty()) {
823 HBox* hbox4a = manage (new HBox);
824 use_template_button.set_label (_("Use this template"));
826 TreeModel::Row row = *template_model->prepend ();
827 row[session_template_columns.name] = (_("no template"));
828 row[session_template_columns.path] = string();
830 hbox4a->set_spacing (6);
831 hbox4a->pack_start (use_template_button, false, false);
832 hbox4a->pack_start (template_chooser, true, true);
834 template_chooser.set_model (template_model);
836 Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
837 text_renderer->property_editable() = false;
839 template_chooser.pack_start (*text_renderer);
840 template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
841 template_chooser.set_active (0);
843 use_template_button.show();
844 template_chooser.show ();
846 vbox3->pack_start (*hbox4a, false, false);
852 session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
854 HBox* hbox4b = manage (new HBox);
855 use_session_as_template_button.set_label (_("Use an existing session as a template:"));
857 hbox4b->set_spacing (6);
858 hbox4b->pack_start (use_session_as_template_button, false, false);
859 hbox4b->pack_start (session_template_chooser, true, true);
861 use_session_as_template_button.show ();
862 session_template_chooser.show ();
864 Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
865 session_filter->add_pattern (X_("*.ardour"));
866 session_template_chooser.set_filter (*session_filter);
867 session_template_chooser.set_title (_("Select template"));
869 vbox3->pack_start (*hbox4b, false, false);
874 HBox* hbox5 = manage (new HBox);
876 hbox5->set_spacing (6);
877 hbox5->pack_start (more_new_session_options_button, false, false);
879 more_new_session_options_button.show ();
880 more_new_session_options_button.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::more_new_session_options_button_clicked));
882 vbox3->pack_start (*hbox5, false, false);
883 hbox3->pack_start (*vbox3, true, true, 8);
884 vbox2->pack_start (*hbox3, false, false);
888 session_new_vbox.pack_start (*vbox2, false, false);
891 session_new_vbox.show_all ();
892 new_session_hbox.pack_start (session_new_vbox, true, true);
894 new_session_vbox.set_border_width (24);
895 new_session_vbox.pack_start (new_session_hbox, true, true);
896 new_session_vbox.show_all ();
897 new_session_page_index = append_page (new_session_vbox);
898 /* initial setting */
899 set_page_type (new_session_vbox, ASSISTANT_PAGE_CONFIRM);
900 set_page_title (new_session_vbox, _("New Session"));
902 if (more_new_session_options_button.get_active()) {
903 set_page_type (new_session_vbox, ASSISTANT_PAGE_CONTENT);
906 new_name_entry.signal_map().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_mapped));
907 new_name_entry.signal_focus_out_event().connect (sigc::ptr_fun (lost_name_entry_focus));
911 ArdourStartup::new_name_mapped ()
913 cerr << "Grab new name focus\n";
914 new_name_entry.grab_focus ();
918 ArdourStartup::new_name_changed ()
920 if (!new_name_entry.get_text().empty()) {
921 set_page_complete (new_session_vbox, true);
923 set_page_complete (new_session_vbox, false);
928 ArdourStartup::redisplay_recent_sessions ()
930 std::vector<sys::path> session_directories;
931 RecentSessionsSorter cmp;
933 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
934 recent_session_model->clear ();
936 ARDOUR::RecentSessions rs;
937 ARDOUR::read_recent_sessions (rs);
940 recent_session_display.set_model (recent_session_model);
944 // sort them alphabetically
945 sort (rs.begin(), rs.end(), cmp);
947 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
948 session_directories.push_back ((*i).second);
951 for (vector<sys::path>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
953 std::vector<sys::path> state_file_paths;
955 // now get available states for this session
957 get_state_files_in_directory (*i, state_file_paths);
959 vector<string*>* states;
960 vector<const gchar*> item;
961 string fullpath = (*i).to_string();
963 /* remove any trailing / */
965 if (fullpath[fullpath.length()-1] == '/') {
966 fullpath = fullpath.substr (0, fullpath.length()-1);
969 /* check whether session still exists */
970 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
971 /* session doesn't exist */
975 /* now get available states for this session */
977 if ((states = Session::possible_states (fullpath)) == 0) {
982 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
984 Gtk::TreeModel::Row row = *(recent_session_model->append());
986 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
987 row[recent_session_columns.fullpath] = fullpath;
989 if (state_file_names.size() > 1) {
993 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
994 i2 != state_file_names.end(); ++i2)
997 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
999 child_row[recent_session_columns.visible_name] = *i2;
1000 child_row[recent_session_columns.fullpath] = fullpath;
1005 recent_session_display.set_model (recent_session_model);
1010 ArdourStartup::recent_session_row_selected ()
1012 if (recent_session_display.get_selection()->count_selected_rows() > 0) {
1013 set_page_complete (ic_vbox, true);
1015 set_page_complete (ic_vbox, false);
1020 ArdourStartup::more_new_session_options_button_clicked ()
1022 if (more_new_session_options_button.get_active()) {
1023 more_options_vbox.show_all ();
1024 set_page_type (more_options_vbox, ASSISTANT_PAGE_CONFIRM);
1025 set_page_type (new_session_vbox, ASSISTANT_PAGE_CONTENT);
1027 set_page_type (new_session_vbox, ASSISTANT_PAGE_CONFIRM);
1028 more_options_vbox.hide ();
1033 ArdourStartup::setup_more_options_page ()
1035 more_options_vbox.set_border_width (24);
1037 _output_limit_count.set_adjustment (_output_limit_count_adj);
1038 _input_limit_count.set_adjustment (_input_limit_count_adj);
1039 _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
1041 chan_count_label_1.set_text (_("channels"));
1042 chan_count_label_3.set_text (_("channels"));
1043 chan_count_label_4.set_text (_("channels"));
1045 chan_count_label_1.set_alignment(0,0.5);
1046 chan_count_label_1.set_padding(0,0);
1047 chan_count_label_1.set_line_wrap(false);
1049 chan_count_label_3.set_alignment(0,0.5);
1050 chan_count_label_3.set_padding(0,0);
1051 chan_count_label_3.set_line_wrap(false);
1053 chan_count_label_4.set_alignment(0,0.5);
1054 chan_count_label_4.set_padding(0,0);
1055 chan_count_label_4.set_line_wrap(false);
1057 bus_label.set_markup (_("<b>Busses</b>"));
1058 input_label.set_markup (_("<b>Inputs</b>"));
1059 output_label.set_markup (_("<b>Outputs</b>"));
1061 _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
1062 _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1063 _master_bus_channel_count.set_numeric(true);
1064 _master_bus_channel_count.set_digits(0);
1065 _master_bus_channel_count.set_wrap(false);
1067 _create_master_bus.set_label (_("Create master bus"));
1068 _create_master_bus.set_flags(Gtk::CAN_FOCUS);
1069 _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
1070 _create_master_bus.set_mode(true);
1071 _create_master_bus.set_active(true);
1072 _create_master_bus.set_border_width(0);
1074 advanced_table.set_row_spacings(0);
1075 advanced_table.set_col_spacings(0);
1077 _connect_inputs.set_label (_("Automatically connect to physical_inputs"));
1078 _connect_inputs.set_flags(Gtk::CAN_FOCUS);
1079 _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
1080 _connect_inputs.set_mode(true);
1081 _connect_inputs.set_active(Config->get_input_auto_connect() != ManualConnect);
1082 _connect_inputs.set_border_width(0);
1084 _limit_input_ports.set_label (_("Use only"));
1085 _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
1086 _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
1087 _limit_input_ports.set_mode(true);
1088 _limit_input_ports.set_sensitive(true);
1089 _limit_input_ports.set_border_width(0);
1091 _input_limit_count.set_flags(Gtk::CAN_FOCUS);
1092 _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1093 _input_limit_count.set_numeric(true);
1094 _input_limit_count.set_digits(0);
1095 _input_limit_count.set_wrap(false);
1096 _input_limit_count.set_sensitive(false);
1098 bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
1100 bus_label.set_alignment(0, 0.5);
1101 bus_label.set_padding(0,0);
1102 bus_label.set_line_wrap(false);
1103 bus_label.set_selectable(false);
1104 bus_label.set_use_markup(true);
1105 bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
1106 bus_frame.set_label_align(0,0.5);
1107 bus_frame.add(bus_hbox);
1108 bus_frame.set_label_widget(bus_label);
1110 bus_table.set_row_spacings (0);
1111 bus_table.set_col_spacings (0);
1112 bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1113 bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1114 bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
1116 input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
1117 input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
1118 input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
1119 input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
1120 input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
1121 input_table.set_row_spacings(0);
1122 input_table.set_col_spacings(0);
1123 input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
1125 input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
1127 input_label.set_alignment(0, 0.5);
1128 input_label.set_padding(0,0);
1129 input_label.set_line_wrap(false);
1130 input_label.set_selectable(false);
1131 input_label.set_use_markup(true);
1132 input_frame.set_shadow_type(Gtk::SHADOW_NONE);
1133 input_frame.set_label_align(0,0.5);
1134 input_frame.add(input_hbox);
1135 input_frame.set_label_widget(input_label);
1137 _connect_outputs.set_label (_("Automatically connect outputs"));
1138 _connect_outputs.set_flags(Gtk::CAN_FOCUS);
1139 _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
1140 _connect_outputs.set_mode(true);
1141 _connect_outputs.set_active(Config->get_output_auto_connect() != ManualConnect);
1142 _connect_outputs.set_border_width(0);
1143 _limit_output_ports.set_label (_("Use only"));
1144 _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
1145 _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
1146 _limit_output_ports.set_mode(true);
1147 _limit_output_ports.set_sensitive(true);
1148 _limit_output_ports.set_border_width(0);
1149 _output_limit_count.set_flags(Gtk::CAN_FOCUS);
1150 _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1151 _output_limit_count.set_numeric(false);
1152 _output_limit_count.set_digits(0);
1153 _output_limit_count.set_wrap(false);
1154 _output_limit_count.set_sensitive(false);
1155 output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
1156 output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
1157 output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
1159 _connect_outputs_to_master.set_label (_("... to master bus"));
1160 _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
1161 _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
1162 _connect_outputs_to_master.set_mode(true);
1163 _connect_outputs_to_master.set_active(Config->get_output_auto_connect() == AutoConnectMaster);
1164 _connect_outputs_to_master.set_border_width(0);
1166 _connect_outputs_to_master.set_group (connect_outputs_group);
1167 _connect_outputs_to_physical.set_group (connect_outputs_group);
1169 _connect_outputs_to_physical.set_label (_("... to physical outputs"));
1170 _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
1171 _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
1172 _connect_outputs_to_physical.set_mode(true);
1173 _connect_outputs_to_physical.set_active(Config->get_output_auto_connect() == AutoConnectPhysical);
1174 _connect_outputs_to_physical.set_border_width(0);
1176 output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
1177 output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
1178 output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
1179 output_vbox.set_border_width(6);
1181 output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
1183 output_vbox.pack_start(output_conn_vbox);
1184 output_vbox.pack_start(output_port_vbox);
1186 output_label.set_alignment(0, 0.5);
1187 output_label.set_padding(0,0);
1188 output_label.set_line_wrap(false);
1189 output_label.set_selectable(false);
1190 output_label.set_use_markup(true);
1191 output_frame.set_shadow_type(Gtk::SHADOW_NONE);
1192 output_frame.set_label_align(0,0.5);
1194 output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
1196 output_frame.add(output_hbox);
1197 output_frame.set_label_widget(output_label);
1199 more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
1200 more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
1201 more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
1202 more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
1206 _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
1207 _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
1208 _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
1209 _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
1210 _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
1212 /* note that more_options_vbox is NOT visible by
1213 * default. this is entirely by design - this page
1214 * should be skipped unless explicitly requested.
1217 session_options_page_index = append_page (more_options_vbox);
1218 set_page_title (more_options_vbox, _("Advanced Session Options"));
1219 set_page_complete (more_options_vbox, true);
1223 ArdourStartup::create_master_bus() const
1225 return _create_master_bus.get_active();
1229 ArdourStartup::master_channel_count() const
1231 return _master_bus_channel_count.get_value_as_int();
1235 ArdourStartup::connect_inputs() const
1237 return _connect_inputs.get_active();
1241 ArdourStartup::limit_inputs_used_for_connection() const
1243 return _limit_input_ports.get_active();
1247 ArdourStartup::input_limit_count() const
1249 return _input_limit_count.get_value_as_int();
1253 ArdourStartup::connect_outputs() const
1255 return _connect_outputs.get_active();
1259 ArdourStartup::limit_outputs_used_for_connection() const
1261 return _limit_output_ports.get_active();
1265 ArdourStartup::output_limit_count() const
1267 return _output_limit_count.get_value_as_int();
1271 ArdourStartup::connect_outs_to_master() const
1273 return _connect_outputs_to_master.get_active();
1277 ArdourStartup::connect_outs_to_physical() const
1279 return _connect_outputs_to_physical.get_active();
1283 ArdourStartup::connect_inputs_clicked ()
1285 _limit_input_ports.set_sensitive(_connect_inputs.get_active());
1287 if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
1288 _input_limit_count.set_sensitive(true);
1290 _input_limit_count.set_sensitive(false);
1295 ArdourStartup::connect_outputs_clicked ()
1297 _limit_output_ports.set_sensitive(_connect_outputs.get_active());
1299 if (_connect_outputs.get_active() && _limit_output_ports.get_active()) {
1300 _output_limit_count.set_sensitive(true);
1302 _output_limit_count.set_sensitive(false);
1307 ArdourStartup::limit_inputs_clicked ()
1309 _input_limit_count.set_sensitive(_limit_input_ports.get_active());
1313 ArdourStartup::limit_outputs_clicked ()
1315 _output_limit_count.set_sensitive(_limit_output_ports.get_active());
1319 ArdourStartup::master_bus_button_clicked ()
1321 bool yn = _create_master_bus.get_active();
1323 _master_bus_channel_count.set_sensitive(yn);
1327 ArdourStartup::move_along_now ()
1329 gint cur = get_current_page ();
1331 if (cur == new_session_page_index) {
1332 if (more_new_session_options_button.get_active()) {
1333 set_current_page (session_options_page_index);
1341 ArdourStartup::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
1343 ic_existing_session_button.set_active (true);
1344 ic_new_session_button.set_active (false);
1345 set_page_type (ic_vbox, ASSISTANT_PAGE_CONFIRM);
1346 set_page_complete (ic_vbox, true);
1351 ArdourStartup::existing_session_selected ()
1353 ic_new_session_button.set_active (false);
1354 ic_existing_session_button.set_active (true);
1355 _existing_session_chooser_used = true;
1356 set_page_type (ic_vbox, ASSISTANT_PAGE_CONFIRM);
1357 set_page_complete (ic_vbox, true);
1362 ArdourStartup::been_here_before_path () const
1364 sys::path b = user_config_directory();
1365 b /= ".a3"; // XXXX use more specific version so we can catch upgrades