2 Copyright (C) 2010 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "gtk2ardour-config.h"
27 #include <gtkmm/main.h>
28 #include <gtkmm/filechooser.h>
30 #include "pbd/failed_constructor.h"
31 #include "pbd/file_utils.h"
32 #include "pbd/replace_all.h"
33 #include "pbd/whitespace.h"
34 #include "pbd/stacktrace.h"
35 #include "pbd/openuri.h"
37 #include "ardour/filesystem_paths.h"
38 #include "ardour/recent_sessions.h"
39 #include "ardour/session.h"
40 #include "ardour/session_state_utils.h"
41 #include "ardour/template_utils.h"
42 #include "ardour/filename_extensions.h"
44 #include "ardour_ui.h"
47 #include "engine_dialog.h"
56 using namespace ARDOUR;
58 ArdourStartup* ArdourStartup::the_startup = 0;
60 static string poor_mans_glob (string path)
63 replace_all (copy, "~", Glib::get_home_dir());
67 ArdourStartup::ArdourStartup (bool require_new, const std::string& session_name, const std::string& session_path, const std::string& template_name)
68 : _response (RESPONSE_OK)
69 , config_modified (false)
70 , new_only (require_new)
71 , default_dir_chooser (0)
72 , ic_new_session_button (_("Create a new session"))
73 , ic_existing_session_button (_("Open an existing session"))
74 , monitor_via_hardware_button (string_compose (_("Use an external mixer or the hardware mixer of your audio interface.\n"
75 "%1 will play NO role in monitoring"), PROGRAM_NAME))
76 , monitor_via_ardour_button (string_compose (_("Ask %1 to play back material as it is being recorded"), PROGRAM_NAME))
78 , new_folder_chooser (FILE_CHOOSER_ACTION_SELECT_FOLDER)
79 , more_new_session_options_button (_("I'd like more options for this session"))
80 , _output_limit_count_adj (1, 0, 100, 1, 10, 0)
81 , _input_limit_count_adj (1, 0, 100, 1, 10, 0)
82 , _master_bus_channel_count_adj (2, 0, 100, 1, 10, 0)
83 , audio_page_index (-1)
84 , new_user_page_index (-1)
85 , default_folder_page_index (-1)
86 , monitoring_page_index (-1)
87 , session_page_index (-1)
88 , initial_choice_index (-1)
89 , final_page_index (-1)
90 , session_options_page_index (-1)
91 , _existing_session_chooser_used (false)
93 new_user = !Glib::file_test (been_here_before_path(), Glib::FILE_TEST_EXISTS);
94 need_audio_setup = EngineControl::need_setup ();
95 need_session_info = (session_name.empty() || require_new);
97 _provided_session_name = session_name;
98 _provided_session_path = session_path;
100 if (need_audio_setup || need_session_info || new_user) {
102 use_template_button.set_group (session_template_group);
103 use_session_as_template_button.set_group (session_template_group);
105 set_keep_above (true);
106 set_position (WIN_POS_CENTER);
107 set_border_width (12);
109 if ((icon_pixbuf = ::get_icon ("ardour_icon_48px")) == 0) {
110 throw failed_constructor();
113 list<Glib::RefPtr<Gdk::Pixbuf> > window_icons;
114 Glib::RefPtr<Gdk::Pixbuf> icon;
116 if ((icon = ::get_icon ("ardour_icon_16px")) != 0) {
117 window_icons.push_back (icon);
119 if ((icon = ::get_icon ("ardour_icon_22px")) != 0) {
120 window_icons.push_back (icon);
122 if ((icon = ::get_icon ("ardour_icon_32px")) != 0) {
123 window_icons.push_back (icon);
125 if ((icon = ::get_icon ("ardour_icon_48px")) != 0) {
126 window_icons.push_back (icon);
128 if (!window_icons.empty ()) {
129 set_default_icon_list (window_icons);
132 set_type_hint(Gdk::WINDOW_TYPE_HINT_DIALOG);
135 setup_prerelease_page ();
139 setup_new_user_page ();
140 setup_first_time_config_page ();
141 setup_monitoring_choice_page ();
142 setup_monitor_section_choice_page ();
144 if (need_audio_setup) {
148 ic_new_session_button.set_active (true); // always create new session on first run
152 if (need_audio_setup) {
156 setup_initial_choice_page ();
159 setup_session_page ();
160 setup_more_options_page ();
172 if (!template_name.empty()) {
173 use_template_button.set_active (false);
174 load_template_override = template_name;
181 ArdourStartup::~ArdourStartup ()
186 ArdourStartup::ready_without_display () const
188 return !new_user && !need_audio_setup && !need_session_info;
192 ArdourStartup::setup_prerelease_page ()
194 VBox* vbox = manage (new VBox);
195 Label* label = manage (new Label);
196 label->set_markup (_("<b>Welcome to this BETA release of Ardour 3.0</b>\n\n\
197 Ardour 3.0 has been released for Linux but because of the lack of testers,\n\
198 it is still at the beta stage on OS X. So, a few guidelines:\n\
200 1) Please do <b>NOT</b> use this software with the expectation that it is stable or reliable\n\
201 though it may be so, depending on your workflow.\n\
202 3) <b>Please do NOT use the forums at ardour.org to report issues</b>.\n\
203 4) Please <b>DO</b> use the bugtracker at http://tracker.ardour.org/ to report issues\n\
204 making sure to note the product version number as 3.0-beta.\n\
205 5) Please <b>DO</b> use the ardour-users mailing list to discuss ideas and pass on comments.\n\
206 6) Please <b>DO</b> join us on IRC for real time discussions about ardour3. You\n\
207 can get there directly from Ardour via the Help->Chat menu option.\n\
209 Full information on all the above can be found on the support page at\n\
211 http://ardour.org/support\n\
214 vbox->set_border_width (12);
215 vbox->pack_start (*label, false, false, 12);
219 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
220 set_page_title (*vbox, _("This is a BETA RELEASE"));
221 set_page_complete (*vbox, true);
225 ArdourStartup::use_session_template ()
227 if (!load_template_override.empty()) {
231 if (use_template_button.get_active()) {
232 return template_chooser.get_active_row_number() > 0;
234 return !session_template_chooser.get_filename().empty();
239 ArdourStartup::session_template_name ()
241 if (!load_template_override.empty()) {
242 string the_path (ARDOUR::user_template_directory());
243 return Glib::build_filename (the_path, load_template_override + ARDOUR::template_suffix);
246 if (ic_existing_session_button.get_active()) {
250 if (use_template_button.get_active()) {
251 TreeModel::iterator iter = template_chooser.get_active ();
252 TreeModel::Row row = (*iter);
253 string s = row[session_template_columns.path];
256 return session_template_chooser.get_filename();
262 ArdourStartup::session_name (bool& should_be_new)
264 if (ready_without_display()) {
265 return _provided_session_name;
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 (ready_without_display()) {
295 return _provided_session_path;
298 if (ic_new_session_button.get_active()) {
299 std::string legal_session_folder_name = legalize_for_path (new_name_entry.get_text());
300 return Glib::build_filename (new_folder_chooser.get_current_folder(), legal_session_folder_name);
301 } else if (_existing_session_chooser_used) {
302 /* existing session chosen from file chooser */
303 return existing_session_chooser.get_current_folder ();
305 /* existing session chosen from recent list */
306 TreeIter iter = recent_session_display.get_selection()->get_selected();
309 return (*iter)[recent_session_columns.fullpath];
316 ArdourStartup::setup_audio_page ()
318 engine_dialog = manage (new EngineControl);
320 engine_dialog->set_border_width (12);
322 engine_dialog->show_all ();
324 audio_page_index = append_page (*engine_dialog);
325 set_page_type (*engine_dialog, ASSISTANT_PAGE_CONTENT);
326 set_page_title (*engine_dialog, _("Audio / MIDI Setup"));
328 /* the default parameters should work, so the page is potentially complete */
330 set_page_complete (*engine_dialog, true);
334 ArdourStartup::setup_new_user_page ()
336 Label* foomatic = manage (new Label);
338 foomatic->set_markup (string_compose (_("\
339 <span size=\"larger\">%1 is a digital audio workstation. You can use it to \
340 record, edit and mix multi-track audio. You can produce your \
341 own CDs, mix video soundtracks, or experiment with new \
342 ideas about music and sound. \
344 There are a few things that need to be configured before you start \
345 using the program.</span> \
347 foomatic->set_justify (JUSTIFY_FILL);
348 foomatic->set_line_wrap ();
350 HBox* hbox = manage (new HBox);
351 HBox* vbox = manage (new HBox);
353 vbox->set_border_width (24);
355 hbox->pack_start (*foomatic, true, true);
356 vbox->pack_start (*hbox, true, true);
362 new_user_page_index = append_page (*vbox);
363 set_page_type (*vbox, ASSISTANT_PAGE_INTRO);
364 set_page_title (*vbox, string_compose (_("Welcome to %1"), PROGRAM_NAME));
365 set_page_header_image (*vbox, icon_pixbuf);
366 set_page_complete (*vbox, true);
370 ArdourStartup::default_dir_changed ()
372 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
373 // make new session folder chooser point to the new default
374 new_folder_chooser.set_current_folder (Config->get_default_session_parent_dir());
379 ArdourStartup::config_changed ()
381 config_modified = true;
385 ArdourStartup::setup_first_time_config_page ()
387 default_dir_chooser = manage (new FileChooserButton (string_compose (_("Default folder for %1 sessions"), PROGRAM_NAME),
388 FILE_CHOOSER_ACTION_SELECT_FOLDER));
389 Gtk::Label* txt = manage (new Label);
390 HBox* hbox = manage (new HBox);
391 VBox* vbox = manage (new VBox);
393 txt->set_markup (string_compose (_("\
394 Each project that you work on with %1 has its own folder.\n\
395 These can require a lot of disk space if you are recording audio.\n\
397 Where would you like new %1 sessions to be stored by default?\n\n\
398 <i>(You can put new sessions anywhere, this is just a default)</i>"), PROGRAM_NAME));
399 txt->set_alignment (0.0, 0.0);
401 vbox->set_spacing (18);
402 vbox->set_border_width (24);
404 hbox->pack_start (*default_dir_chooser, false, true, 8);
405 vbox->pack_start (*txt, false, false);
406 vbox->pack_start (*hbox, false, true);
408 cerr << "Setting defaultDIR session dir to [" << Config->get_default_session_parent_dir() << "]\n";
410 default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
411 default_dir_chooser->signal_current_folder_changed().connect (sigc::mem_fun (*this, &ArdourStartup::default_dir_changed));
412 default_dir_chooser->show ();
416 default_folder_page_index = append_page (*vbox);
417 set_page_title (*vbox, _("Default folder for new sessions"));
418 set_page_header_image (*vbox, icon_pixbuf);
419 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
421 /* user can just skip all these settings if they want to */
423 set_page_complete (*vbox, true);
427 ArdourStartup::setup_monitoring_choice_page ()
429 mon_vbox.set_spacing (18);
430 mon_vbox.set_border_width (24);
432 HBox* hbox = manage (new HBox);
433 VBox* vbox = manage (new VBox);
434 /* first button will be on by default */
435 RadioButton::Group g (monitor_via_ardour_button.get_group());
436 monitor_via_hardware_button.set_group (g);
438 monitor_label.set_markup(_("\
439 While recording instruments or vocals, you probably want to listen to the\n\
440 signal as well as record it. This is called \"monitoring\". There are\n\
441 different ways to do this depending on the equipment you have and the\n\
442 configuration of that equipment. The two most common are presented here.\n\
443 Please choose whichever one is right for your setup.\n\n\
444 <i>(You can change this preference at any time, via the Preferences dialog)</i>\n\n\
445 <i>If you do not understand what this is about, just accept the default.</i>"));
446 monitor_label.set_alignment (0.0, 0.0);
448 vbox->set_spacing (6);
450 vbox->pack_start (monitor_via_hardware_button, false, true);
451 vbox->pack_start (monitor_via_ardour_button, false, true);
452 hbox->pack_start (*vbox, true, true, 8);
453 mon_vbox.pack_start (monitor_label, false, false);
454 mon_vbox.pack_start (*hbox, false, false);
456 mon_vbox.show_all ();
458 monitoring_page_index = append_page (mon_vbox);
459 set_page_title (mon_vbox, _("Monitoring Choices"));
460 set_page_header_image (mon_vbox, icon_pixbuf);
462 /* user could just click on "Forward" if default
466 set_page_complete (mon_vbox, true);
470 ArdourStartup::setup_monitor_section_choice_page ()
472 mon_sec_vbox.set_spacing (18);
473 mon_sec_vbox.set_border_width (24);
475 HBox* hbox = manage (new HBox);
476 VBox* main_vbox = manage (new VBox);
478 Label* l = manage (new Label);
480 main_vbox->set_spacing (32);
482 no_monitor_section_button.set_label (_("Use a Master bus directly"));
483 l->set_alignment (0.0, 1.0);
484 l->set_markup(_("Connect the Master bus directly to your hardware outputs. This is preferable for simple usage."));
486 vbox = manage (new VBox);
487 vbox->set_spacing (6);
488 vbox->pack_start (no_monitor_section_button, false, true);
489 vbox->pack_start (*l, false, true);
491 main_vbox->pack_start (*vbox, false, false);
493 use_monitor_section_button.set_label (_("Use an additional Monitor bus"));
494 l = manage (new Label);
495 l->set_alignment (0.0, 1.0);
496 l->set_text (_("Use a Monitor bus between Master bus and hardware outputs for \n\
497 greater control in monitoring without affecting the mix."));
499 vbox = manage (new VBox);
500 vbox->set_spacing (6);
501 vbox->pack_start (use_monitor_section_button, false, true);
502 vbox->pack_start (*l, false, true);
504 main_vbox->pack_start (*vbox, false, false);
506 RadioButton::Group g (use_monitor_section_button.get_group());
507 no_monitor_section_button.set_group (g);
509 if (Config->get_use_monitor_bus()) {
510 use_monitor_section_button.set_active (true);
512 no_monitor_section_button.set_active (true);
515 use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
516 no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
518 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\
519 <i>If you do not understand what this is about, just accept the default.</i>"));
520 monitor_section_label.set_alignment (0.0, 0.0);
522 hbox->pack_start (*main_vbox, true, true, 8);
523 mon_sec_vbox.pack_start (*hbox, false, false);
524 mon_sec_vbox.pack_start (monitor_section_label, false, false);
526 mon_sec_vbox.show_all ();
528 monitor_section_page_index = append_page (mon_sec_vbox);
529 set_page_title (mon_sec_vbox, _("Monitor Section"));
530 set_page_header_image (mon_sec_vbox, icon_pixbuf);
532 /* user could just click on "Forward" if default
536 set_page_complete (mon_sec_vbox, true);
540 ArdourStartup::setup_initial_choice_page ()
542 ic_vbox.set_spacing (6);
543 ic_vbox.set_border_width (24);
545 RadioButton::Group g (ic_new_session_button.get_group());
546 ic_existing_session_button.set_group (g);
548 HBox* centering_hbox = manage (new HBox);
549 VBox* centering_vbox = manage (new VBox);
551 centering_vbox->set_spacing (6);
553 centering_vbox->pack_start (ic_new_session_button, false, true);
554 centering_vbox->pack_start (ic_existing_session_button, false, true);
556 if (ARDOUR_UI::instance()->announce_string() != "" ) {
558 Gtk::Frame *info_frame = manage(new Gtk::Frame);
559 info_frame->set_shadow_type(SHADOW_ETCHED_OUT);
560 centering_vbox->pack_start (*info_frame, false, false, 20);
562 Box *info_box = manage (new VBox);
563 info_box->set_border_width (12);
564 info_box->set_spacing (6);
565 info_box->set_name("mixbus_info_box");
567 info_box->pack_start (info_scroller_label, false, false);
569 info_frame->add (*info_box);
570 info_frame->show_all();
572 info_scroller_count = 0;
573 info_scroller_connection = Glib::signal_timeout().connect (mem_fun(*this, &ArdourStartup::info_scroller_update), 50);
575 Gtk::Button *updates_button = manage (new Gtk::Button (_("Check the website for more...")));
577 updates_button->signal_clicked().connect (mem_fun(*this, &ArdourStartup::updates_button_clicked) );
578 ARDOUR_UI::instance()->tooltips().set_tip (*updates_button, _("Click to open the program website in your web browser"));
580 info_box->pack_start (*updates_button, false, false);
583 ic_new_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
584 ic_new_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
586 ic_existing_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
587 ic_existing_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
589 centering_hbox->pack_start (*centering_vbox, true, true);
591 ic_vbox.pack_start (*centering_hbox, true, true);
595 initial_choice_index = append_page (ic_vbox);
596 set_page_title (ic_vbox, _("What would you like to do ?"));
597 set_page_header_image (ic_vbox, icon_pixbuf);
599 /* user could just click on "Forward" if default
603 set_page_complete (ic_vbox, true);
607 ArdourStartup::initial_button_clicked (GdkEventButton* ev)
609 if (ev->type == GDK_2BUTTON_PRESS && session_page_index != -1) {
610 set_current_page(session_page_index);
617 ArdourStartup::initial_button_activated ()
619 if (session_page_index != -1) {
620 set_current_page(session_page_index);
625 ArdourStartup::setup_session_page ()
627 session_vbox.set_border_width (24);
629 session_vbox.pack_start (session_hbox, true, true);
630 session_vbox.show_all ();
632 session_page_index = append_page (session_vbox);
633 /* initial setting */
634 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
638 ArdourStartup::setup_final_page ()
640 final_page.set_text (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
642 final_page_index = append_page (final_page);
643 set_page_complete (final_page, true);
644 set_page_header_image (final_page, icon_pixbuf);
645 set_page_type (final_page, ASSISTANT_PAGE_CONFIRM);
649 ArdourStartup::on_cancel ()
651 _response = RESPONSE_CANCEL;
656 ArdourStartup::on_delete_event (GdkEventAny*)
658 _response = RESPONSE_CLOSE;
664 ArdourStartup::on_apply ()
667 if (engine_dialog->setup_engine ()) {
668 set_current_page (audio_page_index);
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 Config->save_state ();
692 /* "touch" the been-here-before path now we've successfully
693 made it through the first time setup (at least)
695 ofstream fout (been_here_before_path().c_str());
699 _response = RESPONSE_OK;
704 ArdourStartup::on_prepare (Gtk::Widget* page)
706 if (page == &session_vbox) {
708 if (ic_new_session_button.get_active()) {
709 /* new session requested */
710 setup_new_session_page ();
712 /* existing session requested */
713 setup_existing_session_page ();
717 /* HACK HACK HACK ... change the "Apply" button label
721 Gtk::Widget* tl = session_vbox.get_toplevel();
723 if ((win = dynamic_cast<Gtk::Window*>(tl)) != 0) {
724 /* ::get_default_widget() is not wrapped in gtkmm */
725 Gtk::Widget* def = wrap (gtk_window_get_default_widget (win->gobj()));
727 if ((button = dynamic_cast<Gtk::Button*>(def)) != 0) {
728 if (more_new_session_options_button.get_active()) {
729 button->set_label (_("Forward"));
731 button->set_label (_("Open"));
739 ArdourStartup::populate_session_templates ()
741 vector<TemplateInfo> templates;
743 find_session_templates (templates);
745 template_model->clear ();
747 for (vector<TemplateInfo>::iterator x = templates.begin(); x != templates.end(); ++x) {
750 row = *(template_model->append ());
752 row[session_template_columns.name] = (*x).name;
753 row[session_template_columns.path] = (*x).path;
758 ArdourStartup::setup_new_session_page ()
760 if (!session_hbox.get_children().empty()) {
761 session_hbox.remove (**session_hbox.get_children().begin());
764 session_new_vbox.set_spacing (18);
766 if (session_new_vbox.get_children().empty()) {
767 VBox *vbox1 = manage (new VBox);
768 HBox* hbox1 = manage (new HBox);
769 Label* label1 = manage (new Label);
771 vbox1->set_spacing (6);
773 hbox1->set_spacing (6);
774 hbox1->pack_start (*label1, false, false);
775 hbox1->pack_start (new_name_entry, true, true);
777 label1->set_text (_("Session name:"));
780 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
781 new_name_entry.set_text (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
782 /* name provided - they can move right along */
783 set_page_complete (session_vbox, true);
786 new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_changed));
787 new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &ArdourStartup::move_along_now));
789 vbox1->pack_start (*hbox1, true, true);
793 HBox* hbox2 = manage (new HBox);
794 Label* label2 = manage (new Label);
796 hbox2->set_spacing (6);
797 hbox2->pack_start (*label2, false, false);
798 hbox2->pack_start (new_folder_chooser, true, true);
800 label2->set_text (_("Create session folder in:"));
802 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
803 new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
804 } else if (ARDOUR_UI::instance()->session_loaded) {
805 // point the new session file chooser at the parent directory of the current session
806 string session_parent_dir = Glib::path_get_dirname(ARDOUR_UI::instance()->the_session()->path());
807 string::size_type last_dir_sep = session_parent_dir.rfind(G_DIR_SEPARATOR);
808 session_parent_dir = session_parent_dir.substr(0, last_dir_sep);
809 new_folder_chooser.set_current_folder (session_parent_dir);
810 new_folder_chooser.add_shortcut_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
812 new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
814 new_folder_chooser.show ();
815 new_folder_chooser.set_title (_("Select folder for session"));
818 new_folder_chooser.add_shortcut_folder ("/Volumes");
821 vbox1->pack_start (*hbox2, false, false);
823 session_new_vbox.pack_start (*vbox1, false, false);
827 VBox *vbox2 = manage (new VBox);
828 HBox* hbox3 = manage (new HBox);
829 Label* label3 = manage (new Label);
830 template_model = ListStore::create (session_template_columns);
831 populate_session_templates ();
833 vbox2->set_spacing (6);
835 label3->set_markup (_("<b>Options</b>"));
836 label3->set_alignment (0.0, 0.0);
838 vbox2->pack_start (*label3, false, true);
840 VBox *vbox3 = manage (new VBox);
842 vbox3->set_spacing (6);
844 if (!template_model->children().empty()) {
846 HBox* hbox4a = manage (new HBox);
847 use_template_button.set_label (_("Use this template"));
849 TreeModel::Row row = *template_model->prepend ();
850 row[session_template_columns.name] = (_("no template"));
851 row[session_template_columns.path] = string();
853 hbox4a->set_spacing (6);
854 hbox4a->pack_start (use_template_button, false, false);
855 hbox4a->pack_start (template_chooser, true, true);
857 template_chooser.set_model (template_model);
859 Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
860 text_renderer->property_editable() = false;
862 template_chooser.pack_start (*text_renderer);
863 template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
864 template_chooser.set_active (0);
866 use_template_button.show();
867 template_chooser.show ();
869 vbox3->pack_start (*hbox4a, false, false);
875 session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
877 HBox* hbox4b = manage (new HBox);
878 use_session_as_template_button.set_label (_("Use an existing session as a template:"));
880 hbox4b->set_spacing (6);
881 hbox4b->pack_start (use_session_as_template_button, false, false);
882 hbox4b->pack_start (session_template_chooser, true, true);
884 use_session_as_template_button.show ();
885 session_template_chooser.show ();
887 Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
888 session_filter->add_pattern (X_("*.ardour"));
889 session_template_chooser.set_filter (*session_filter);
890 session_template_chooser.set_title (_("Select template"));
892 vbox3->pack_start (*hbox4b, false, false);
897 HBox* hbox5 = manage (new HBox);
899 hbox5->set_spacing (6);
900 hbox5->pack_start (more_new_session_options_button, false, false);
902 more_new_session_options_button.show ();
903 more_new_session_options_button.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::more_new_session_options_button_clicked));
905 vbox3->pack_start (*hbox5, false, false);
906 hbox3->pack_start (*vbox3, true, true, 8);
907 vbox2->pack_start (*hbox3, false, false);
911 session_new_vbox.pack_start (*vbox2, false, false);
914 session_new_vbox.show_all ();
915 session_hbox.pack_start (session_new_vbox, true, true);
916 set_page_title (session_vbox, _("New Session"));
917 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
919 if (more_new_session_options_button.get_active()) {
920 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
925 ArdourStartup::new_name_changed ()
927 if (!new_name_entry.get_text().empty()) {
928 set_page_complete (session_vbox, true);
930 set_page_complete (session_vbox, false);
935 ArdourStartup::redisplay_recent_sessions ()
937 std::vector<std::string> session_directories;
938 RecentSessionsSorter cmp;
940 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
941 recent_session_model->clear ();
943 ARDOUR::RecentSessions rs;
944 ARDOUR::read_recent_sessions (rs);
947 recent_session_display.set_model (recent_session_model);
951 // sort them alphabetically
952 sort (rs.begin(), rs.end(), cmp);
954 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
955 session_directories.push_back ((*i).second);
958 int session_snapshot_count = 0;
960 for (vector<std::string>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
962 std::vector<std::string> state_file_paths;
964 // now get available states for this session
966 get_state_files_in_directory (*i, state_file_paths);
968 vector<string*>* states;
969 vector<const gchar*> item;
970 string fullpath = *i;
972 /* remove any trailing / */
974 if (fullpath[fullpath.length()-1] == '/') {
975 fullpath = fullpath.substr (0, fullpath.length()-1);
978 /* check whether session still exists */
979 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
980 /* session doesn't exist */
984 /* now get available states for this session */
986 if ((states = Session::possible_states (fullpath)) == 0) {
991 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
993 Gtk::TreeModel::Row row = *(recent_session_model->append());
995 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
996 row[recent_session_columns.fullpath] = fullpath;
997 row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
999 ++session_snapshot_count;
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) {
1008 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
1010 child_row[recent_session_columns.visible_name] = *i2;
1011 child_row[recent_session_columns.fullpath] = fullpath;
1012 child_row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
1013 ++session_snapshot_count;
1018 recent_session_display.set_tooltip_column(1); // recent_session_columns.tip
1019 recent_session_display.set_model (recent_session_model);
1020 return session_snapshot_count;
1021 // return rs.size();
1025 ArdourStartup::recent_session_row_selected ()
1027 if (recent_session_display.get_selection()->count_selected_rows() > 0) {
1028 set_page_complete (session_vbox, true);
1030 set_page_complete (session_vbox, false);
1035 ArdourStartup::setup_existing_session_page ()
1037 recent_session_model = TreeStore::create (recent_session_columns);
1038 redisplay_recent_sessions ();
1040 if (!session_hbox.get_children().empty()) {
1041 session_hbox.remove (**session_hbox.get_children().begin());
1044 if (session_existing_vbox.get_children().empty()) {
1046 recent_session_display.set_model (recent_session_model);
1047 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1048 recent_session_display.set_headers_visible (false);
1049 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
1051 recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::recent_session_row_selected));
1053 recent_scroller.add (recent_session_display);
1054 recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1055 recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
1057 recent_session_display.show();
1059 recent_scroller.show();
1060 int cnt = redisplay_recent_sessions ();
1061 recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ArdourStartup::recent_row_activated));
1064 recent_scroller.set_size_request (-1, 300);
1067 session_existing_vbox.set_spacing (8);
1068 session_existing_vbox.pack_start (recent_scroller, true, true);
1070 existing_session_chooser.set_title (_("Select session file"));
1071 existing_session_chooser.signal_file_set().connect (sigc::mem_fun (*this, &ArdourStartup::existing_session_selected));
1072 existing_session_chooser.set_current_folder(poor_mans_glob (Config->get_default_session_parent_dir()));
1074 FileFilter session_filter;
1075 session_filter.add_pattern ("*.ardour");
1076 session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
1077 existing_session_chooser.add_filter (session_filter);
1078 existing_session_chooser.set_filter (session_filter);
1081 existing_session_chooser.add_shortcut_folder ("/Volumes");
1084 HBox* hbox = manage (new HBox);
1085 hbox->set_spacing (4);
1086 hbox->pack_start (*manage (new Label (_("Browse:"))), PACK_SHRINK);
1087 hbox->pack_start (existing_session_chooser);
1088 session_existing_vbox.pack_start (*hbox, false, false);
1092 session_existing_vbox.show_all ();
1093 session_hbox.pack_start (session_existing_vbox, true, true);
1095 set_page_title (session_vbox, _("Select a session"));
1096 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1100 ArdourStartup::more_new_session_options_button_clicked ()
1102 if (more_new_session_options_button.get_active()) {
1103 more_options_vbox.show_all ();
1104 set_page_type (more_options_vbox, ASSISTANT_PAGE_CONFIRM);
1105 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
1107 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1108 more_options_vbox.hide ();
1113 ArdourStartup::setup_more_options_page ()
1115 more_options_vbox.set_border_width (24);
1117 _output_limit_count.set_adjustment (_output_limit_count_adj);
1118 _input_limit_count.set_adjustment (_input_limit_count_adj);
1119 _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
1121 chan_count_label_1.set_text (_("channels"));
1122 chan_count_label_3.set_text (_("channels"));
1123 chan_count_label_4.set_text (_("channels"));
1125 chan_count_label_1.set_alignment(0,0.5);
1126 chan_count_label_1.set_padding(0,0);
1127 chan_count_label_1.set_line_wrap(false);
1129 chan_count_label_3.set_alignment(0,0.5);
1130 chan_count_label_3.set_padding(0,0);
1131 chan_count_label_3.set_line_wrap(false);
1133 chan_count_label_4.set_alignment(0,0.5);
1134 chan_count_label_4.set_padding(0,0);
1135 chan_count_label_4.set_line_wrap(false);
1137 bus_label.set_markup (_("<b>Busses</b>"));
1138 input_label.set_markup (_("<b>Inputs</b>"));
1139 output_label.set_markup (_("<b>Outputs</b>"));
1141 _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
1142 _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1143 _master_bus_channel_count.set_numeric(true);
1144 _master_bus_channel_count.set_digits(0);
1145 _master_bus_channel_count.set_wrap(false);
1147 _create_master_bus.set_label (_("Create master bus"));
1148 _create_master_bus.set_flags(Gtk::CAN_FOCUS);
1149 _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
1150 _create_master_bus.set_mode(true);
1151 _create_master_bus.set_active(true);
1152 _create_master_bus.set_border_width(0);
1154 advanced_table.set_row_spacings(0);
1155 advanced_table.set_col_spacings(0);
1157 _connect_inputs.set_label (_("Automatically connect to physical inputs"));
1158 _connect_inputs.set_flags(Gtk::CAN_FOCUS);
1159 _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
1160 _connect_inputs.set_mode(true);
1161 _connect_inputs.set_active(Config->get_input_auto_connect() != ManualConnect);
1162 _connect_inputs.set_border_width(0);
1164 _limit_input_ports.set_label (_("Use only"));
1165 _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
1166 _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
1167 _limit_input_ports.set_mode(true);
1168 _limit_input_ports.set_sensitive(true);
1169 _limit_input_ports.set_border_width(0);
1171 _input_limit_count.set_flags(Gtk::CAN_FOCUS);
1172 _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1173 _input_limit_count.set_numeric(true);
1174 _input_limit_count.set_digits(0);
1175 _input_limit_count.set_wrap(false);
1176 _input_limit_count.set_sensitive(false);
1178 bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
1180 bus_label.set_alignment(0, 0.5);
1181 bus_label.set_padding(0,0);
1182 bus_label.set_line_wrap(false);
1183 bus_label.set_selectable(false);
1184 bus_label.set_use_markup(true);
1185 bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
1186 bus_frame.set_label_align(0,0.5);
1187 bus_frame.add(bus_hbox);
1188 bus_frame.set_label_widget(bus_label);
1190 bus_table.set_row_spacings (0);
1191 bus_table.set_col_spacings (0);
1192 bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1193 bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1194 bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
1196 input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
1197 input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
1198 input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
1199 input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
1200 input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
1201 input_table.set_row_spacings(0);
1202 input_table.set_col_spacings(0);
1203 input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
1205 input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
1207 input_label.set_alignment(0, 0.5);
1208 input_label.set_padding(0,0);
1209 input_label.set_line_wrap(false);
1210 input_label.set_selectable(false);
1211 input_label.set_use_markup(true);
1212 input_frame.set_shadow_type(Gtk::SHADOW_NONE);
1213 input_frame.set_label_align(0,0.5);
1214 input_frame.add(input_hbox);
1215 input_frame.set_label_widget(input_label);
1217 _connect_outputs.set_label (_("Automatically connect outputs"));
1218 _connect_outputs.set_flags(Gtk::CAN_FOCUS);
1219 _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
1220 _connect_outputs.set_mode(true);
1221 _connect_outputs.set_active(Config->get_output_auto_connect() != ManualConnect);
1222 _connect_outputs.set_border_width(0);
1223 _limit_output_ports.set_label (_("Use only"));
1224 _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
1225 _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
1226 _limit_output_ports.set_mode(true);
1227 _limit_output_ports.set_sensitive(true);
1228 _limit_output_ports.set_border_width(0);
1229 _output_limit_count.set_flags(Gtk::CAN_FOCUS);
1230 _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1231 _output_limit_count.set_numeric(false);
1232 _output_limit_count.set_digits(0);
1233 _output_limit_count.set_wrap(false);
1234 _output_limit_count.set_sensitive(false);
1235 output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
1236 output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
1237 output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
1239 _connect_outputs_to_master.set_label (_("... to master bus"));
1240 _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
1241 _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
1242 _connect_outputs_to_master.set_mode(true);
1243 _connect_outputs_to_master.set_active(Config->get_output_auto_connect() == AutoConnectMaster);
1244 _connect_outputs_to_master.set_border_width(0);
1246 _connect_outputs_to_master.set_group (connect_outputs_group);
1247 _connect_outputs_to_physical.set_group (connect_outputs_group);
1249 _connect_outputs_to_physical.set_label (_("... to physical outputs"));
1250 _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
1251 _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
1252 _connect_outputs_to_physical.set_mode(true);
1253 _connect_outputs_to_physical.set_active(Config->get_output_auto_connect() == AutoConnectPhysical);
1254 _connect_outputs_to_physical.set_border_width(0);
1256 output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
1257 output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
1258 output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
1259 output_vbox.set_border_width(6);
1261 output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
1263 output_vbox.pack_start(output_conn_vbox);
1264 output_vbox.pack_start(output_port_vbox);
1266 output_label.set_alignment(0, 0.5);
1267 output_label.set_padding(0,0);
1268 output_label.set_line_wrap(false);
1269 output_label.set_selectable(false);
1270 output_label.set_use_markup(true);
1271 output_frame.set_shadow_type(Gtk::SHADOW_NONE);
1272 output_frame.set_label_align(0,0.5);
1274 output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
1276 output_frame.add(output_hbox);
1277 output_frame.set_label_widget(output_label);
1279 more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
1280 more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
1281 more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
1282 more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
1286 _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
1287 _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
1288 _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
1289 _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
1290 _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
1292 /* note that more_options_vbox is "visible" by default even
1293 * though it may not be displayed to the user, this is so the dialog
1296 more_options_vbox.show_all ();
1298 session_options_page_index = append_page (more_options_vbox);
1299 set_page_title (more_options_vbox, _("Advanced Session Options"));
1300 set_page_complete (more_options_vbox, true);
1304 ArdourStartup::create_master_bus() const
1306 return _create_master_bus.get_active();
1310 ArdourStartup::master_channel_count() const
1312 return _master_bus_channel_count.get_value_as_int();
1316 ArdourStartup::connect_inputs() const
1318 return _connect_inputs.get_active();
1322 ArdourStartup::limit_inputs_used_for_connection() const
1324 return _limit_input_ports.get_active();
1328 ArdourStartup::input_limit_count() const
1330 return _input_limit_count.get_value_as_int();
1334 ArdourStartup::connect_outputs() const
1336 return _connect_outputs.get_active();
1340 ArdourStartup::limit_outputs_used_for_connection() const
1342 return _limit_output_ports.get_active();
1346 ArdourStartup::output_limit_count() const
1348 return _output_limit_count.get_value_as_int();
1352 ArdourStartup::connect_outs_to_master() const
1354 return _connect_outputs_to_master.get_active();
1358 ArdourStartup::connect_outs_to_physical() const
1360 return _connect_outputs_to_physical.get_active();
1364 ArdourStartup::connect_inputs_clicked ()
1366 _limit_input_ports.set_sensitive(_connect_inputs.get_active());
1368 if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
1369 _input_limit_count.set_sensitive(true);
1371 _input_limit_count.set_sensitive(false);
1376 ArdourStartup::connect_outputs_clicked ()
1378 bool const co = _connect_outputs.get_active ();
1379 _limit_output_ports.set_sensitive(co);
1380 _connect_outputs_to_master.set_sensitive(co);
1381 _connect_outputs_to_physical.set_sensitive(co);
1383 if (co && _limit_output_ports.get_active()) {
1384 _output_limit_count.set_sensitive(true);
1386 _output_limit_count.set_sensitive(false);
1391 ArdourStartup::limit_inputs_clicked ()
1393 _input_limit_count.set_sensitive(_limit_input_ports.get_active());
1397 ArdourStartup::limit_outputs_clicked ()
1399 _output_limit_count.set_sensitive(_limit_output_ports.get_active());
1403 ArdourStartup::master_bus_button_clicked ()
1405 bool const yn = _create_master_bus.get_active();
1407 _master_bus_channel_count.set_sensitive(yn);
1408 _connect_outputs_to_master.set_sensitive(yn);
1412 ArdourStartup::move_along_now ()
1414 gint cur = get_current_page ();
1416 if (cur == session_page_index) {
1417 if (more_new_session_options_button.get_active()) {
1418 set_current_page (session_options_page_index);
1426 ArdourStartup::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
1428 set_page_complete (session_vbox, true);
1433 ArdourStartup::existing_session_selected ()
1435 _existing_session_chooser_used = true;
1437 set_page_complete (session_vbox, true);
1442 ArdourStartup::been_here_before_path () const
1444 // XXXX use more specific version so we can catch upgrades
1445 return Glib::build_filename (user_config_directory (), ".a3");
1449 ArdourStartup::updates_button_clicked ()
1451 //now open a browser window so user can see more
1452 PBD::open_uri (Config->get_updates_url());
1456 ArdourStartup::info_scroller_update()
1458 info_scroller_count++;
1461 snprintf (buf, std::min(info_scroller_count,sizeof(buf)-1), "%s", ARDOUR_UI::instance()->announce_string().c_str() );
1462 buf[info_scroller_count] = NULL;
1463 info_scroller_label.set_text (buf);
1464 info_scroller_label.show();
1466 if (info_scroller_count > ARDOUR_UI::instance()->announce_string().length()) {
1467 info_scroller_connection.disconnect();