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 , monitor_via_hardware_button (_("Use an external mixer or the hardware mixer of your audio interface.\n\
69 Ardour will play NO role in monitoring"))
70 , monitor_via_ardour_button (string_compose (_("Ask %1 to play back material as it is being recorded"), PROGRAM_NAME))
71 , new_folder_chooser (FILE_CHOOSER_ACTION_SELECT_FOLDER)
72 , more_new_session_options_button (_("I'd like more options for this session"))
73 , _output_limit_count_adj (1, 0, 100, 1, 10, 0)
74 , _input_limit_count_adj (1, 0, 100, 1, 10, 0)
75 , _master_bus_channel_count_adj (2, 0, 100, 1, 10, 0)
76 , _existing_session_chooser_used (false)
78 audio_page_index = -1;
79 initial_choice_index = -1;
80 new_user_page_index = -1;
81 default_folder_page_index = -1;
82 monitoring_page_index = -1;
83 new_session_page_index = -1;
84 final_page_index = -1;
85 session_options_page_index = -1;
89 config_modified = false;
90 default_dir_chooser = 0;
92 use_template_button.set_group (session_template_group);
93 use_session_as_template_button.set_group (session_template_group);
95 set_keep_above (true);
96 set_resizable (false);
97 set_position (WIN_POS_CENTER);
98 set_border_width (12);
100 if ((icon_pixbuf = ::get_icon ("ardour_icon_48px")) == 0) {
101 throw failed_constructor();
104 list<Glib::RefPtr<Gdk::Pixbuf> > window_icons;
105 Glib::RefPtr<Gdk::Pixbuf> icon;
107 if ((icon = ::get_icon ("ardour_icon_16px")) != 0) {
108 window_icons.push_back (icon);
110 if ((icon = ::get_icon ("ardour_icon_22px")) != 0) {
111 window_icons.push_back (icon);
113 if ((icon = ::get_icon ("ardour_icon_32px")) != 0) {
114 window_icons.push_back (icon);
116 if ((icon = ::get_icon ("ardour_icon_48px")) != 0) {
117 window_icons.push_back (icon);
119 if (!window_icons.empty ()) {
120 set_default_icon_list (window_icons);
123 new_user = !exists (been_here_before_path ());
125 bool need_audio_setup = !EngineControl::engine_running();
127 setup_prerelease_page ();
131 /* Create the config directory so that we have somewhere to put the
132 been_here_before file.
135 sys::create_directories (user_config_directory ());
137 catch (const sys::filesystem_error& ex) {
138 error << "Could not create user configuration directory" << endmsg;
141 setup_new_user_page ();
142 setup_first_time_config_page ();
143 setup_monitoring_choice_page ();
144 setup_monitor_section_choice_page ();
146 if (need_audio_setup) {
152 if (need_audio_setup) {
156 setup_initial_choice_page ();
159 setup_new_session_page ();
160 setup_more_options_page ();
169 ArdourStartup::~ArdourStartup ()
174 ArdourStartup::setup_prerelease_page ()
176 VBox* vbox = manage (new VBox);
177 Label* label = manage (new Label);
178 label->set_markup (_("<b>Welcome to this BETA release of Ardour 3.0</b>\n\n\
179 There are still several issues and bugs to be worked on,\n\
180 as well as general workflow improvements, before this can be considered\n\
181 release software. So, a few guidelines:\n\
183 1) Please do <b>NOT</b> use this software with the expectation that it is stable or reliable\n\
184 though it may be so, depending on your workflow.\n\
185 2) Please see http://ardour.org/a3_features for a guide to new features.\n\
186 3) <b>Please do NOT use the forums at ardour.org to report issues</b>.\n\
187 4) Please <b>DO</b> use the bugtracker at http://tracker.ardour.org/ to report issues\n\
188 making sure to note the product version number as 3.0-beta.\n\
189 5) Please <b>DO</b> use the ardour-users mailing list to discuss ideas and pass on comments.\n\
190 6) Please <b>DO</b> join us on IRC for real time discussions about ardour3. You\n\
191 can get there directly from Ardour via the Help->Chat menu option.\n\
193 Full information on all the above can be found on the support page at\n\
195 http://ardour.org/support\n\
198 vbox->set_border_width (12);
199 vbox->pack_start (*label, false, false, 12);
203 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
204 set_page_title (*vbox, _("This is a BETA RELEASE"));
205 set_page_complete (*vbox, true);
209 ArdourStartup::set_new_only (bool yn)
221 ArdourStartup::set_load_template (string load_template)
223 use_template_button.set_active (false);
224 load_template_override = load_template;
228 ArdourStartup::use_session_template ()
230 if (!load_template_override.empty()) {
234 if (use_template_button.get_active()) {
235 return template_chooser.get_active_row_number() > 0;
237 return !session_template_chooser.get_filename().empty();
242 ArdourStartup::session_template_name ()
244 if (!load_template_override.empty()) {
245 string the_path = (ARDOUR::user_template_directory()/ (load_template_override + ".template")).to_string();
249 if (use_template_button.get_active()) {
250 TreeModel::iterator iter = template_chooser.get_active ();
251 TreeModel::Row row = (*iter);
252 string s = row[session_template_columns.path];
255 return session_template_chooser.get_filename();
261 ArdourStartup::session_name (bool& should_be_new)
263 if (ic_new_session_button.get_active()) {
264 should_be_new = true;
265 string val = new_name_entry.get_text ();
266 strip_whitespace_edges (val);
268 } else if (_existing_session_chooser_used) {
269 /* existing session chosen from file chooser */
270 should_be_new = false;
271 return existing_session_chooser.get_filename ();
273 /* existing session chosen from recent list */
274 should_be_new = false;
276 TreeIter iter = recent_session_display.get_selection()->get_selected();
279 return (*iter)[recent_session_columns.visible_name];
287 ArdourStartup::session_folder ()
289 if (ic_new_session_button.get_active()) {
290 std::string legal_session_folder_name = legalize_for_path (new_name_entry.get_text());
291 return Glib::build_filename (new_folder_chooser.get_current_folder(), legal_session_folder_name);
292 } else if (_existing_session_chooser_used) {
293 /* existing session chosen from file chooser */
294 return existing_session_chooser.get_current_folder ();
296 /* existing session chosen from recent list */
297 TreeIter iter = recent_session_display.get_selection()->get_selected();
300 return (*iter)[recent_session_columns.fullpath];
307 ArdourStartup::setup_audio_page ()
309 engine_dialog = manage (new EngineControl);
311 engine_dialog->set_border_width (12);
313 engine_dialog->show_all ();
315 audio_page_index = append_page (*engine_dialog);
316 set_page_type (*engine_dialog, ASSISTANT_PAGE_CONTENT);
317 set_page_title (*engine_dialog, _("Audio / MIDI Setup"));
319 /* the default parameters should work, so the page is potentially complete */
321 set_page_complete (*engine_dialog, true);
325 ArdourStartup::setup_new_user_page ()
327 Label* foomatic = manage (new Label);
329 foomatic->set_markup (string_compose (_("\
330 <span size=\"larger\">%1 is a digital audio workstation. You can use it to \
331 record, edit and mix multi-track audio. You can produce your \
332 own CDs, mix video soundtracks, or experiment with new \
333 ideas about music and sound. \
335 There are a few things that need to be configured before you start \
336 using the program.</span> \
338 foomatic->set_justify (JUSTIFY_FILL);
339 foomatic->set_line_wrap ();
341 HBox* hbox = manage (new HBox);
342 HBox* vbox = manage (new HBox);
344 vbox->set_border_width (24);
346 hbox->pack_start (*foomatic, true, true);
347 vbox->pack_start (*hbox, true, true);
353 new_user_page_index = append_page (*vbox);
354 set_page_type (*vbox, ASSISTANT_PAGE_INTRO);
355 set_page_title (*vbox, string_compose (_("Welcome to %1"), PROGRAM_NAME));
356 set_page_header_image (*vbox, icon_pixbuf);
357 set_page_complete (*vbox, true);
361 ArdourStartup::default_dir_changed ()
363 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
368 ArdourStartup::config_changed ()
370 config_modified = true;
374 ArdourStartup::setup_first_time_config_page ()
376 default_dir_chooser = manage (new FileChooserButton (string_compose (_("Default folder for %1 sessions"), PROGRAM_NAME),
377 FILE_CHOOSER_ACTION_SELECT_FOLDER));
378 Gtk::Label* txt = manage (new Label);
379 HBox* hbox = manage (new HBox);
380 VBox* vbox = manage (new VBox);
382 txt->set_markup (string_compose (_("\
383 Each project that you work on with %1 has its own folder.\n\
384 These can require a lot of disk space if you are recording audio.\n\
386 Where would you like new %1 sessions to be stored by default?\n\n\
387 <i>(You can put new sessions anywhere, this is just a default)</i>"), PROGRAM_NAME));
388 txt->set_alignment (0.0, 0.0);
390 vbox->set_spacing (18);
391 vbox->set_border_width (24);
393 hbox->pack_start (*default_dir_chooser, false, true, 8);
394 vbox->pack_start (*txt, false, false);
395 vbox->pack_start (*hbox, false, true);
397 default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
398 default_dir_chooser->signal_current_folder_changed().connect (sigc::mem_fun (*this, &ArdourStartup::default_dir_changed));
399 default_dir_chooser->show ();
403 default_folder_page_index = append_page (*vbox);
404 set_page_title (*vbox, _("Default folder for new sessions"));
405 set_page_header_image (*vbox, icon_pixbuf);
406 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
408 /* user can just skip all these settings if they want to */
410 set_page_complete (*vbox, true);
414 ArdourStartup::setup_monitoring_choice_page ()
416 mon_vbox.set_spacing (18);
417 mon_vbox.set_border_width (24);
419 HBox* hbox = manage (new HBox);
420 VBox* vbox = manage (new VBox);
421 RadioButton::Group g (monitor_via_hardware_button.get_group());
422 monitor_via_ardour_button.set_group (g);
424 monitor_label.set_markup(_("\
425 While recording instruments or vocals, you probably want to listen to the\n\
426 signal as well as record it. This is called \"monitoring\". There are\n\
427 different ways to do this depending on the equipment you have and the\n\
428 configuration of that equipment. The two most common are presented here.\n\
429 Please choose whichever one is right for your setup.\n\n\
430 <i>(You can change this preference at any time, via the Preferences dialog)</i>\n\n\
431 <i>If you do not understand what this is about, just accept the default.</i>"));
432 monitor_label.set_alignment (0.0, 0.0);
434 vbox->set_spacing (6);
436 vbox->pack_start (monitor_via_hardware_button, false, true);
437 vbox->pack_start (monitor_via_ardour_button, false, true);
438 hbox->pack_start (*vbox, true, true, 8);
439 mon_vbox.pack_start (monitor_label, false, false);
440 mon_vbox.pack_start (*hbox, false, false);
442 mon_vbox.show_all ();
444 monitoring_page_index = append_page (mon_vbox);
445 set_page_title (mon_vbox, _("Monitoring Choices"));
446 set_page_header_image (mon_vbox, icon_pixbuf);
448 /* user could just click on "Forward" if default
452 set_page_complete (mon_vbox, true);
456 ArdourStartup::setup_monitor_section_choice_page ()
458 mon_sec_vbox.set_spacing (18);
459 mon_sec_vbox.set_border_width (24);
461 HBox* hbox = manage (new HBox);
462 VBox* main_vbox = manage (new VBox);
464 Label* l = manage (new Label);
466 main_vbox->set_spacing (32);
468 no_monitor_section_button.set_label (_("Use a Master bus directly"));
469 l->set_alignment (0.0, 1.0);
470 l->set_markup(_("Connect the Master bus directly to your hardware outputs. This is preferable for simple usage."));
472 vbox = manage (new VBox);
473 vbox->set_spacing (6);
474 vbox->pack_start (no_monitor_section_button, false, true);
475 vbox->pack_start (*l, false, true);
477 main_vbox->pack_start (*vbox, false, false);
479 use_monitor_section_button.set_label (_("Use an additional Monitor bus"));
480 l = manage (new Label);
481 l->set_alignment (0.0, 1.0);
482 l->set_text (_("Use a Monitor bus between Master bus and hardware outputs for \n\
483 greater control in monitoring without affecting the mix."));
485 vbox = manage (new VBox);
486 vbox->set_spacing (6);
487 vbox->pack_start (use_monitor_section_button, false, true);
488 vbox->pack_start (*l, false, true);
490 main_vbox->pack_start (*vbox, false, false);
492 RadioButton::Group g (use_monitor_section_button.get_group());
493 no_monitor_section_button.set_group (g);
495 if (Config->get_use_monitor_bus()) {
496 use_monitor_section_button.set_active (true);
498 no_monitor_section_button.set_active (true);
501 use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
502 no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
504 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\
505 <i>If you do not understand what this is about, just accept the default.</i>"));
506 monitor_section_label.set_alignment (0.0, 0.0);
508 hbox->pack_start (*main_vbox, true, true, 8);
509 mon_sec_vbox.pack_start (*hbox, false, false);
510 mon_sec_vbox.pack_start (monitor_section_label, false, false);
512 mon_sec_vbox.show_all ();
514 monitor_section_page_index = append_page (mon_sec_vbox);
515 set_page_title (mon_sec_vbox, _("Monitor Section"));
516 set_page_header_image (mon_sec_vbox, icon_pixbuf);
518 /* user could just click on "Forward" if default
522 set_page_complete (mon_sec_vbox, true);
526 ArdourStartup::setup_initial_choice_page ()
528 initial_choice_index = append_page (ic_vbox);
529 set_page_title (ic_vbox, _("What would you like to do ?"));
530 set_page_header_image (ic_vbox, icon_pixbuf);
532 ic_vbox.set_spacing (6);
533 ic_vbox.set_border_width (24);
535 HBox* centering_hbox = manage (new HBox);
536 VBox* centering_vbox = manage (new VBox);
538 centering_vbox->set_spacing (6);
540 ic_new_session_button.set_active (true);
541 centering_vbox->pack_start (ic_new_session_button, false, true);
543 Gtk::Label* l = manage (new Label);
544 l->set_markup (_("<b>Open a recent session</b>"));
545 l->set_alignment (0.0, 0.5);
546 centering_vbox->pack_start (*l, true, true);
548 recent_session_model = TreeStore::create (recent_session_columns);
549 redisplay_recent_sessions ();
551 if (!new_session_hbox.get_children().empty()) {
552 new_session_hbox.remove (**new_session_hbox.get_children().begin());
555 if (session_existing_vbox.get_children().empty()) {
557 recent_session_display.set_model (recent_session_model);
558 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
559 recent_session_display.set_headers_visible (false);
560 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
562 recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::recent_session_row_selected));
564 recent_scroller.add (recent_session_display);
565 recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
566 recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
568 recent_session_display.show();
570 recent_scroller.show();
571 int cnt = redisplay_recent_sessions ();
572 recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ArdourStartup::recent_row_activated));
575 recent_scroller.set_size_request (-1, 300);
578 centering_vbox->pack_start (recent_scroller, true, true);
580 l = manage (new Label);
581 l->set_markup (_("<b>Browse for existing sessions</b>"));
582 l->set_alignment (0.0, 0.5);
583 centering_vbox->pack_start (*l, true, true);
585 existing_session_chooser.set_title (_("Select session file"));
586 existing_session_chooser.signal_file_set().connect (sigc::mem_fun (*this, &ArdourStartup::existing_session_selected));
589 existing_session_chooser.add_shortcut_folder ("/Volumes");
592 centering_vbox->pack_start (existing_session_chooser, true, true);
595 ic_new_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_press), false);
596 ic_new_session_button.signal_clicked().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked));
597 ic_new_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
599 centering_hbox->pack_start (*centering_vbox, true, true);
601 ic_vbox.pack_start (*centering_hbox, true, true);
605 /* user could just click on "Forward" if default
609 set_page_complete (ic_vbox, true);
613 ArdourStartup::initial_button_clicked ()
615 if (ic_new_session_button.get_active ()) {
616 recent_session_display.get_selection()->unselect_all ();
621 ArdourStartup::initial_button_press (GdkEventButton *event)
623 if (event && event->type == GDK_2BUTTON_PRESS && new_session_page_index != -1) {
624 ic_new_session_button.set_active (true);
625 recent_session_display.get_selection()->unselect_all ();
626 set_current_page (new_session_page_index);
634 ArdourStartup::initial_button_activated ()
636 recent_session_display.get_selection()->unselect_all ();
637 set_current_page (new_session_page_index);
641 ArdourStartup::setup_final_page ()
643 final_page.set_text (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
645 final_page_index = append_page (final_page);
646 set_page_complete (final_page, true);
647 set_page_header_image (final_page, icon_pixbuf);
648 set_page_type (final_page, ASSISTANT_PAGE_CONFIRM);
652 ArdourStartup::on_cancel ()
654 _response = RESPONSE_CANCEL;
659 ArdourStartup::on_delete_event (GdkEventAny*)
661 _response = RESPONSE_CLOSE;
667 ArdourStartup::on_apply ()
670 engine_dialog->setup_engine ();
673 if (config_modified) {
675 if (default_dir_chooser) {
676 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
679 if (monitor_via_hardware_button.get_active()) {
680 Config->set_monitoring_model (ExternalMonitoring);
681 } else if (monitor_via_ardour_button.get_active()) {
682 Config->set_monitoring_model (SoftwareMonitoring);
685 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
687 /* "touch" the been-here-before path now that we're about to save Config */
688 ofstream fout (been_here_before_path().to_string().c_str());
690 Config->save_state ();
693 _response = RESPONSE_OK;
698 ArdourStartup::on_prepare (Gtk::Widget* page)
700 if (page == &new_session_vbox) {
702 if (recent_session_display.get_selection()->count_selected_rows() > 0) {
703 /* row selected, use it */
704 set_page_type (new_session_vbox, ASSISTANT_PAGE_CONFIRM);
708 /* HACK HACK HACK ... change the "Apply" button label
712 Gtk::Widget* tl = new_session_vbox.get_toplevel();
714 if ((win = dynamic_cast<Gtk::Window*>(tl)) != 0) {
715 /* ::get_default_widget() is not wrapped in gtkmm */
716 Gtk::Widget* def = wrap (gtk_window_get_default_widget (win->gobj()));
718 if ((button = dynamic_cast<Gtk::Button*>(def)) != 0) {
719 if (more_new_session_options_button.get_active()) {
720 button->set_label (_("Forward"));
722 button->set_label (_("Open"));
730 ArdourStartup::populate_session_templates ()
732 vector<TemplateInfo> templates;
734 find_session_templates (templates);
736 template_model->clear ();
738 for (vector<TemplateInfo>::iterator x = templates.begin(); x != templates.end(); ++x) {
741 row = *(template_model->append ());
743 row[session_template_columns.name] = (*x).name;
744 row[session_template_columns.path] = (*x).path;
749 lost_name_entry_focus (GdkEventFocus*)
751 cerr << "lost focus\n";
756 ArdourStartup::setup_new_session_page ()
758 if (!new_session_hbox.get_children().empty()) {
759 new_session_hbox.remove (**new_session_hbox.get_children().begin());
762 session_new_vbox.set_spacing (18);
763 new_session_hbox.pack_start (session_new_vbox, true, true);
764 new_session_vbox.pack_start (new_session_hbox, true, true);
765 new_session_page_index = append_page (new_session_vbox);
766 /* initial setting */
767 set_page_type (new_session_vbox, ASSISTANT_PAGE_CONFIRM);
768 set_page_title (new_session_vbox, _("New Session"));
770 if (session_new_vbox.get_children().empty()) {
771 VBox *vbox1 = manage (new VBox);
772 HBox* hbox1 = manage (new HBox);
773 Label* label1 = manage (new Label);
775 vbox1->set_spacing (6);
777 hbox1->set_spacing (6);
778 hbox1->pack_start (*label1, false, false);
779 hbox1->pack_start (new_name_entry, true, true);
781 label1->set_text (_("Session name:"));
783 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
784 new_name_entry.set_text (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
785 /* name provided - they can move right along */
786 set_page_complete (new_session_vbox, true);
789 new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_changed));
790 new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &ArdourStartup::move_along_now));
792 vbox1->pack_start (*hbox1, true, true);
796 HBox* hbox2 = manage (new HBox);
797 Label* label2 = manage (new Label);
799 hbox2->set_spacing (6);
800 hbox2->pack_start (*label2, false, false);
801 hbox2->pack_start (new_folder_chooser, true, true);
803 label2->set_text (_("Create session folder in:"));
805 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
806 new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
808 new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
810 new_folder_chooser.set_title (_("Select folder for session"));
813 new_folder_chooser.add_shortcut_folder ("/Volumes");
816 vbox1->pack_start (*hbox2, false, false);
818 session_new_vbox.pack_start (*vbox1, false, false);
822 VBox *vbox2 = manage (new VBox);
823 HBox* hbox3 = manage (new HBox);
824 Label* label3 = manage (new Label);
825 template_model = ListStore::create (session_template_columns);
826 populate_session_templates ();
828 vbox2->set_spacing (6);
830 label3->set_markup (_("<b>Options</b>"));
831 label3->set_alignment (0.0, 0.0);
833 vbox2->pack_start (*label3, false, true);
835 VBox *vbox3 = manage (new VBox);
837 vbox3->set_spacing (6);
839 if (!template_model->children().empty()) {
841 HBox* hbox4a = manage (new HBox);
842 use_template_button.set_label (_("Use this template"));
844 TreeModel::Row row = *template_model->prepend ();
845 row[session_template_columns.name] = (_("no template"));
846 row[session_template_columns.path] = string();
848 hbox4a->set_spacing (6);
849 hbox4a->pack_start (use_template_button, false, false);
850 hbox4a->pack_start (template_chooser, true, true);
852 template_chooser.set_model (template_model);
854 Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
855 text_renderer->property_editable() = false;
857 template_chooser.pack_start (*text_renderer);
858 template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
859 template_chooser.set_active (0);
861 use_template_button.show();
862 template_chooser.show ();
864 vbox3->pack_start (*hbox4a, false, false);
870 session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
872 HBox* hbox4b = manage (new HBox);
873 use_session_as_template_button.set_label (_("Use an existing session as a template:"));
875 hbox4b->set_spacing (6);
876 hbox4b->pack_start (use_session_as_template_button, false, false);
877 hbox4b->pack_start (session_template_chooser, true, true);
879 use_session_as_template_button.show ();
880 session_template_chooser.show ();
882 Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
883 session_filter->add_pattern (X_("*.ardour"));
884 session_template_chooser.set_filter (*session_filter);
885 session_template_chooser.set_title (_("Select template"));
887 vbox3->pack_start (*hbox4b, false, false);
892 HBox* hbox5 = manage (new HBox);
894 hbox5->set_spacing (6);
895 hbox5->pack_start (more_new_session_options_button, false, false);
897 more_new_session_options_button.show ();
898 more_new_session_options_button.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::more_new_session_options_button_clicked));
900 vbox3->pack_start (*hbox5, false, false);
901 hbox3->pack_start (*vbox3, true, true, 8);
902 vbox2->pack_start (*hbox3, false, false);
906 session_new_vbox.pack_start (*vbox2, false, false);
909 session_new_vbox.show_all ();
911 new_session_vbox.set_border_width (24);
912 new_session_vbox.show_all ();
914 if (more_new_session_options_button.get_active()) {
915 set_page_type (new_session_vbox, ASSISTANT_PAGE_CONTENT);
918 new_name_entry.signal_map().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_mapped));
919 new_name_entry.signal_focus_out_event().connect (sigc::ptr_fun (lost_name_entry_focus));
923 ArdourStartup::new_name_mapped ()
925 cerr << "Grab new name focus\n";
926 new_name_entry.grab_focus ();
930 ArdourStartup::new_name_changed ()
932 if (!new_name_entry.get_text().empty()) {
933 set_page_complete (new_session_vbox, true);
935 set_page_complete (new_session_vbox, false);
940 ArdourStartup::redisplay_recent_sessions ()
942 std::vector<sys::path> session_directories;
943 RecentSessionsSorter cmp;
945 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
946 recent_session_model->clear ();
948 ARDOUR::RecentSessions rs;
949 ARDOUR::read_recent_sessions (rs);
952 recent_session_display.set_model (recent_session_model);
956 // sort them alphabetically
957 sort (rs.begin(), rs.end(), cmp);
959 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
960 session_directories.push_back ((*i).second);
963 for (vector<sys::path>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
965 std::vector<sys::path> state_file_paths;
967 // now get available states for this session
969 get_state_files_in_directory (*i, state_file_paths);
971 vector<string*>* states;
972 vector<const gchar*> item;
973 string fullpath = (*i).to_string();
975 /* remove any trailing / */
977 if (fullpath[fullpath.length()-1] == '/') {
978 fullpath = fullpath.substr (0, fullpath.length()-1);
981 /* check whether session still exists */
982 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
983 /* session doesn't exist */
987 /* now get available states for this session */
989 if ((states = Session::possible_states (fullpath)) == 0) {
994 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
996 Gtk::TreeModel::Row row = *(recent_session_model->append());
998 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
999 row[recent_session_columns.fullpath] = fullpath;
1001 if (state_file_names.size() > 1) {
1005 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
1006 i2 != state_file_names.end(); ++i2)
1009 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
1011 child_row[recent_session_columns.visible_name] = *i2;
1012 child_row[recent_session_columns.fullpath] = fullpath;
1017 recent_session_display.set_tooltip_column(1); // recent_session_columns.fullpath
1018 recent_session_display.set_model (recent_session_model);
1023 ArdourStartup::recent_session_row_selected ()
1025 if (recent_session_display.get_selection()->count_selected_rows() > 0) {
1026 ic_new_session_button.set_active (false);
1028 ic_new_session_button.set_active (true);
1033 ArdourStartup::more_new_session_options_button_clicked ()
1035 if (more_new_session_options_button.get_active()) {
1036 more_options_vbox.show_all ();
1037 set_page_type (more_options_vbox, ASSISTANT_PAGE_CONFIRM);
1038 set_page_type (new_session_vbox, ASSISTANT_PAGE_CONTENT);
1040 set_page_type (new_session_vbox, ASSISTANT_PAGE_CONFIRM);
1041 more_options_vbox.hide ();
1046 ArdourStartup::setup_more_options_page ()
1048 more_options_vbox.set_border_width (24);
1050 _output_limit_count.set_adjustment (_output_limit_count_adj);
1051 _input_limit_count.set_adjustment (_input_limit_count_adj);
1052 _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
1054 chan_count_label_1.set_text (_("channels"));
1055 chan_count_label_3.set_text (_("channels"));
1056 chan_count_label_4.set_text (_("channels"));
1058 chan_count_label_1.set_alignment(0,0.5);
1059 chan_count_label_1.set_padding(0,0);
1060 chan_count_label_1.set_line_wrap(false);
1062 chan_count_label_3.set_alignment(0,0.5);
1063 chan_count_label_3.set_padding(0,0);
1064 chan_count_label_3.set_line_wrap(false);
1066 chan_count_label_4.set_alignment(0,0.5);
1067 chan_count_label_4.set_padding(0,0);
1068 chan_count_label_4.set_line_wrap(false);
1070 bus_label.set_markup (_("<b>Busses</b>"));
1071 input_label.set_markup (_("<b>Inputs</b>"));
1072 output_label.set_markup (_("<b>Outputs</b>"));
1074 _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
1075 _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1076 _master_bus_channel_count.set_numeric(true);
1077 _master_bus_channel_count.set_digits(0);
1078 _master_bus_channel_count.set_wrap(false);
1080 _create_master_bus.set_label (_("Create master bus"));
1081 _create_master_bus.set_flags(Gtk::CAN_FOCUS);
1082 _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
1083 _create_master_bus.set_mode(true);
1084 _create_master_bus.set_active(true);
1085 _create_master_bus.set_border_width(0);
1087 advanced_table.set_row_spacings(0);
1088 advanced_table.set_col_spacings(0);
1090 _connect_inputs.set_label (_("Automatically connect to physical_inputs"));
1091 _connect_inputs.set_flags(Gtk::CAN_FOCUS);
1092 _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
1093 _connect_inputs.set_mode(true);
1094 _connect_inputs.set_active(Config->get_input_auto_connect() != ManualConnect);
1095 _connect_inputs.set_border_width(0);
1097 _limit_input_ports.set_label (_("Use only"));
1098 _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
1099 _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
1100 _limit_input_ports.set_mode(true);
1101 _limit_input_ports.set_sensitive(true);
1102 _limit_input_ports.set_border_width(0);
1104 _input_limit_count.set_flags(Gtk::CAN_FOCUS);
1105 _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1106 _input_limit_count.set_numeric(true);
1107 _input_limit_count.set_digits(0);
1108 _input_limit_count.set_wrap(false);
1109 _input_limit_count.set_sensitive(false);
1111 bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
1113 bus_label.set_alignment(0, 0.5);
1114 bus_label.set_padding(0,0);
1115 bus_label.set_line_wrap(false);
1116 bus_label.set_selectable(false);
1117 bus_label.set_use_markup(true);
1118 bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
1119 bus_frame.set_label_align(0,0.5);
1120 bus_frame.add(bus_hbox);
1121 bus_frame.set_label_widget(bus_label);
1123 bus_table.set_row_spacings (0);
1124 bus_table.set_col_spacings (0);
1125 bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1126 bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1127 bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
1129 input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
1130 input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
1131 input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
1132 input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
1133 input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
1134 input_table.set_row_spacings(0);
1135 input_table.set_col_spacings(0);
1136 input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
1138 input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
1140 input_label.set_alignment(0, 0.5);
1141 input_label.set_padding(0,0);
1142 input_label.set_line_wrap(false);
1143 input_label.set_selectable(false);
1144 input_label.set_use_markup(true);
1145 input_frame.set_shadow_type(Gtk::SHADOW_NONE);
1146 input_frame.set_label_align(0,0.5);
1147 input_frame.add(input_hbox);
1148 input_frame.set_label_widget(input_label);
1150 _connect_outputs.set_label (_("Automatically connect outputs"));
1151 _connect_outputs.set_flags(Gtk::CAN_FOCUS);
1152 _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
1153 _connect_outputs.set_mode(true);
1154 _connect_outputs.set_active(Config->get_output_auto_connect() != ManualConnect);
1155 _connect_outputs.set_border_width(0);
1156 _limit_output_ports.set_label (_("Use only"));
1157 _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
1158 _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
1159 _limit_output_ports.set_mode(true);
1160 _limit_output_ports.set_sensitive(true);
1161 _limit_output_ports.set_border_width(0);
1162 _output_limit_count.set_flags(Gtk::CAN_FOCUS);
1163 _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1164 _output_limit_count.set_numeric(false);
1165 _output_limit_count.set_digits(0);
1166 _output_limit_count.set_wrap(false);
1167 _output_limit_count.set_sensitive(false);
1168 output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
1169 output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
1170 output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
1172 _connect_outputs_to_master.set_label (_("... to master bus"));
1173 _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
1174 _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
1175 _connect_outputs_to_master.set_mode(true);
1176 _connect_outputs_to_master.set_active(Config->get_output_auto_connect() == AutoConnectMaster);
1177 _connect_outputs_to_master.set_border_width(0);
1179 _connect_outputs_to_master.set_group (connect_outputs_group);
1180 _connect_outputs_to_physical.set_group (connect_outputs_group);
1182 _connect_outputs_to_physical.set_label (_("... to physical outputs"));
1183 _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
1184 _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
1185 _connect_outputs_to_physical.set_mode(true);
1186 _connect_outputs_to_physical.set_active(Config->get_output_auto_connect() == AutoConnectPhysical);
1187 _connect_outputs_to_physical.set_border_width(0);
1189 output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
1190 output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
1191 output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
1192 output_vbox.set_border_width(6);
1194 output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
1196 output_vbox.pack_start(output_conn_vbox);
1197 output_vbox.pack_start(output_port_vbox);
1199 output_label.set_alignment(0, 0.5);
1200 output_label.set_padding(0,0);
1201 output_label.set_line_wrap(false);
1202 output_label.set_selectable(false);
1203 output_label.set_use_markup(true);
1204 output_frame.set_shadow_type(Gtk::SHADOW_NONE);
1205 output_frame.set_label_align(0,0.5);
1207 output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
1209 output_frame.add(output_hbox);
1210 output_frame.set_label_widget(output_label);
1212 more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
1213 more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
1214 more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
1215 more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
1219 _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
1220 _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
1221 _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
1222 _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
1223 _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
1225 /* note that more_options_vbox is NOT visible by
1226 * default. this is entirely by design - this page
1227 * should be skipped unless explicitly requested.
1230 session_options_page_index = append_page (more_options_vbox);
1231 set_page_title (more_options_vbox, _("Advanced Session Options"));
1232 set_page_complete (more_options_vbox, true);
1236 ArdourStartup::create_master_bus() const
1238 return _create_master_bus.get_active();
1242 ArdourStartup::master_channel_count() const
1244 return _master_bus_channel_count.get_value_as_int();
1248 ArdourStartup::connect_inputs() const
1250 return _connect_inputs.get_active();
1254 ArdourStartup::limit_inputs_used_for_connection() const
1256 return _limit_input_ports.get_active();
1260 ArdourStartup::input_limit_count() const
1262 return _input_limit_count.get_value_as_int();
1266 ArdourStartup::connect_outputs() const
1268 return _connect_outputs.get_active();
1272 ArdourStartup::limit_outputs_used_for_connection() const
1274 return _limit_output_ports.get_active();
1278 ArdourStartup::output_limit_count() const
1280 return _output_limit_count.get_value_as_int();
1284 ArdourStartup::connect_outs_to_master() const
1286 return _connect_outputs_to_master.get_active();
1290 ArdourStartup::connect_outs_to_physical() const
1292 return _connect_outputs_to_physical.get_active();
1296 ArdourStartup::connect_inputs_clicked ()
1298 _limit_input_ports.set_sensitive(_connect_inputs.get_active());
1300 if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
1301 _input_limit_count.set_sensitive(true);
1303 _input_limit_count.set_sensitive(false);
1308 ArdourStartup::connect_outputs_clicked ()
1310 _limit_output_ports.set_sensitive(_connect_outputs.get_active());
1312 if (_connect_outputs.get_active() && _limit_output_ports.get_active()) {
1313 _output_limit_count.set_sensitive(true);
1315 _output_limit_count.set_sensitive(false);
1320 ArdourStartup::limit_inputs_clicked ()
1322 _input_limit_count.set_sensitive(_limit_input_ports.get_active());
1326 ArdourStartup::limit_outputs_clicked ()
1328 _output_limit_count.set_sensitive(_limit_output_ports.get_active());
1332 ArdourStartup::master_bus_button_clicked ()
1334 bool yn = _create_master_bus.get_active();
1336 _master_bus_channel_count.set_sensitive(yn);
1340 ArdourStartup::move_along_now ()
1342 gint cur = get_current_page ();
1344 if (cur == new_session_page_index) {
1345 if (more_new_session_options_button.get_active()) {
1346 set_current_page (session_options_page_index);
1354 ArdourStartup::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
1356 ic_new_session_button.set_active (false);
1357 set_page_type (ic_vbox, ASSISTANT_PAGE_CONFIRM);
1362 ArdourStartup::existing_session_selected ()
1364 ic_new_session_button.set_active (false);
1365 _existing_session_chooser_used = true;
1366 set_page_type (ic_vbox, ASSISTANT_PAGE_CONFIRM);
1371 ArdourStartup::been_here_before_path () const
1373 sys::path b = user_config_directory();
1374 b /= ".a3"; // XXXX use more specific version so we can catch upgrades