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);
133 setup_prerelease_page ();
137 setup_new_user_page ();
138 setup_first_time_config_page ();
139 setup_monitoring_choice_page ();
140 setup_monitor_section_choice_page ();
142 if (need_audio_setup) {
146 ic_new_session_button.set_active (true); // always create new session on first run
150 if (need_audio_setup) {
154 setup_initial_choice_page ();
157 setup_session_page ();
158 setup_more_options_page ();
170 if (!template_name.empty()) {
171 use_template_button.set_active (false);
172 load_template_override = template_name;
179 ArdourStartup::~ArdourStartup ()
184 ArdourStartup::ready_without_display () const
186 return !new_user && !need_audio_setup && !need_session_info;
190 ArdourStartup::setup_prerelease_page ()
192 VBox* vbox = manage (new VBox);
193 Label* label = manage (new Label);
194 label->set_markup (_("<b>Welcome to this BETA release of Ardour 3.0</b>\n\n\
195 Ardour 3.0 has been released for Linux but because of the lack of testers,\n\
196 it is still at the beta stage on OS X. So, a few guidelines:\n\
198 1) Please do <b>NOT</b> use this software with the expectation that it is stable or reliable\n\
199 though it may be so, depending on your workflow.\n\
200 2) <b>Please do NOT use the forums at ardour.org to report issues</b>.\n\
201 3) Please <b>DO</b> use the bugtracker at http://tracker.ardour.org/ to report issues\n\
202 making sure to note the product version number as 3.0-beta.\n\
203 4) Please <b>DO</b> use the ardour-users mailing list to discuss ideas and pass on comments.\n\
204 5) Please <b>DO</b> join us on IRC for real time discussions about ardour3. You\n\
205 can get there directly from Ardour via the Help->Chat menu option.\n\
207 Full information on all the above can be found on the support page at\n\
209 http://ardour.org/support\n\
212 vbox->set_border_width (12);
213 vbox->pack_start (*label, false, false, 12);
217 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
218 set_page_title (*vbox, _("This is a BETA RELEASE"));
219 set_page_complete (*vbox, true);
223 ArdourStartup::use_session_template ()
225 if (!load_template_override.empty()) {
229 if (use_template_button.get_active()) {
230 return template_chooser.get_active_row_number() > 0;
232 return !session_template_chooser.get_filename().empty();
237 ArdourStartup::session_template_name ()
239 if (!load_template_override.empty()) {
240 string the_path (ARDOUR::user_template_directory());
241 return Glib::build_filename (the_path, load_template_override + ARDOUR::template_suffix);
244 if (ic_existing_session_button.get_active()) {
248 if (use_template_button.get_active()) {
249 TreeModel::iterator iter = template_chooser.get_active ();
250 TreeModel::Row row = (*iter);
251 string s = row[session_template_columns.path];
254 return session_template_chooser.get_filename();
260 ArdourStartup::session_name (bool& should_be_new)
262 if (ready_without_display()) {
263 return _provided_session_name;
266 if (ic_new_session_button.get_active()) {
267 should_be_new = true;
268 string val = new_name_entry.get_text ();
269 strip_whitespace_edges (val);
271 } else if (_existing_session_chooser_used) {
272 /* existing session chosen from file chooser */
273 should_be_new = false;
274 return existing_session_chooser.get_filename ();
276 /* existing session chosen from recent list */
277 should_be_new = false;
279 TreeIter iter = recent_session_display.get_selection()->get_selected();
282 return (*iter)[recent_session_columns.visible_name];
290 ArdourStartup::session_folder ()
292 if (ready_without_display()) {
293 return _provided_session_path;
296 if (ic_new_session_button.get_active()) {
297 std::string legal_session_folder_name = legalize_for_path (new_name_entry.get_text());
298 return Glib::build_filename (new_folder_chooser.get_current_folder(), legal_session_folder_name);
299 } else if (_existing_session_chooser_used) {
300 /* existing session chosen from file chooser */
301 return existing_session_chooser.get_current_folder ();
303 /* existing session chosen from recent list */
304 TreeIter iter = recent_session_display.get_selection()->get_selected();
307 return (*iter)[recent_session_columns.fullpath];
314 ArdourStartup::setup_audio_page ()
316 engine_dialog = manage (new EngineControl);
318 engine_dialog->set_border_width (12);
320 engine_dialog->show_all ();
322 audio_page_index = append_page (*engine_dialog);
323 set_page_type (*engine_dialog, ASSISTANT_PAGE_CONTENT);
324 set_page_title (*engine_dialog, _("Audio / MIDI Setup"));
326 /* the default parameters should work, so the page is potentially complete */
328 set_page_complete (*engine_dialog, true);
332 ArdourStartup::setup_new_user_page ()
334 Label* foomatic = manage (new Label);
336 foomatic->set_markup (string_compose (_("\
337 <span size=\"larger\">%1 is a digital audio workstation. You can use it to \
338 record, edit and mix multi-track audio. You can produce your \
339 own CDs, mix video soundtracks, or experiment with new \
340 ideas about music and sound. \
342 There are a few things that need to be configured before you start \
343 using the program.</span> \
345 foomatic->set_justify (JUSTIFY_FILL);
346 foomatic->set_line_wrap ();
348 HBox* hbox = manage (new HBox);
349 HBox* vbox = manage (new HBox);
351 vbox->set_border_width (24);
353 hbox->pack_start (*foomatic, true, true);
354 vbox->pack_start (*hbox, true, true);
360 new_user_page_index = append_page (*vbox);
361 set_page_type (*vbox, ASSISTANT_PAGE_INTRO);
362 set_page_title (*vbox, string_compose (_("Welcome to %1"), PROGRAM_NAME));
363 set_page_header_image (*vbox, icon_pixbuf);
364 set_page_complete (*vbox, true);
368 ArdourStartup::default_dir_changed ()
370 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
371 // make new session folder chooser point to the new default
372 new_folder_chooser.set_current_folder (Config->get_default_session_parent_dir());
377 ArdourStartup::config_changed ()
379 config_modified = true;
383 ArdourStartup::setup_first_time_config_page ()
385 default_dir_chooser = manage (new FileChooserButton (string_compose (_("Default folder for %1 sessions"), PROGRAM_NAME),
386 FILE_CHOOSER_ACTION_SELECT_FOLDER));
387 Gtk::Label* txt = manage (new Label);
388 HBox* hbox = manage (new HBox);
389 VBox* vbox = manage (new VBox);
391 txt->set_markup (string_compose (_("\
392 Each project that you work on with %1 has its own folder.\n\
393 These can require a lot of disk space if you are recording audio.\n\
395 Where would you like new %1 sessions to be stored by default?\n\n\
396 <i>(You can put new sessions anywhere, this is just a default)</i>"), PROGRAM_NAME));
397 txt->set_alignment (0.0, 0.0);
399 vbox->set_spacing (18);
400 vbox->set_border_width (24);
402 hbox->pack_start (*default_dir_chooser, false, true, 8);
403 vbox->pack_start (*txt, false, false);
404 vbox->pack_start (*hbox, false, true);
406 cerr << "Setting defaultDIR session dir to [" << Config->get_default_session_parent_dir() << "]\n";
408 default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
409 default_dir_chooser->signal_current_folder_changed().connect (sigc::mem_fun (*this, &ArdourStartup::default_dir_changed));
410 default_dir_chooser->show ();
414 default_folder_page_index = append_page (*vbox);
415 set_page_title (*vbox, _("Default folder for new sessions"));
416 set_page_header_image (*vbox, icon_pixbuf);
417 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
419 /* user can just skip all these settings if they want to */
421 set_page_complete (*vbox, true);
425 ArdourStartup::setup_monitoring_choice_page ()
427 mon_vbox.set_spacing (18);
428 mon_vbox.set_border_width (24);
430 HBox* hbox = manage (new HBox);
431 VBox* vbox = manage (new VBox);
432 /* first button will be on by default */
433 RadioButton::Group g (monitor_via_ardour_button.get_group());
434 monitor_via_hardware_button.set_group (g);
436 monitor_label.set_markup(_("\
437 While recording instruments or vocals, you probably want to listen to the\n\
438 signal as well as record it. This is called \"monitoring\". There are\n\
439 different ways to do this depending on the equipment you have and the\n\
440 configuration of that equipment. The two most common are presented here.\n\
441 Please choose whichever one is right for your setup.\n\n\
442 <i>(You can change this preference at any time, via the Preferences dialog)</i>\n\n\
443 <i>If you do not understand what this is about, just accept the default.</i>"));
444 monitor_label.set_alignment (0.0, 0.0);
446 vbox->set_spacing (6);
448 vbox->pack_start (monitor_via_hardware_button, false, true);
449 vbox->pack_start (monitor_via_ardour_button, false, true);
450 hbox->pack_start (*vbox, true, true, 8);
451 mon_vbox.pack_start (monitor_label, false, false);
452 mon_vbox.pack_start (*hbox, false, false);
454 mon_vbox.show_all ();
456 monitoring_page_index = append_page (mon_vbox);
457 set_page_title (mon_vbox, _("Monitoring Choices"));
458 set_page_header_image (mon_vbox, icon_pixbuf);
460 /* user could just click on "Forward" if default
464 set_page_complete (mon_vbox, true);
468 ArdourStartup::setup_monitor_section_choice_page ()
470 mon_sec_vbox.set_spacing (18);
471 mon_sec_vbox.set_border_width (24);
473 HBox* hbox = manage (new HBox);
474 VBox* main_vbox = manage (new VBox);
476 Label* l = manage (new Label);
478 main_vbox->set_spacing (32);
480 no_monitor_section_button.set_label (_("Use a Master bus directly"));
481 l->set_alignment (0.0, 1.0);
482 l->set_markup(_("Connect the Master bus directly to your hardware outputs. This is preferable for simple usage."));
484 vbox = manage (new VBox);
485 vbox->set_spacing (6);
486 vbox->pack_start (no_monitor_section_button, false, true);
487 vbox->pack_start (*l, false, true);
489 main_vbox->pack_start (*vbox, false, false);
491 use_monitor_section_button.set_label (_("Use an additional Monitor bus"));
492 l = manage (new Label);
493 l->set_alignment (0.0, 1.0);
494 l->set_text (_("Use a Monitor bus between Master bus and hardware outputs for \n\
495 greater control in monitoring without affecting the mix."));
497 vbox = manage (new VBox);
498 vbox->set_spacing (6);
499 vbox->pack_start (use_monitor_section_button, false, true);
500 vbox->pack_start (*l, false, true);
502 main_vbox->pack_start (*vbox, false, false);
504 RadioButton::Group g (use_monitor_section_button.get_group());
505 no_monitor_section_button.set_group (g);
507 if (Config->get_use_monitor_bus()) {
508 use_monitor_section_button.set_active (true);
510 no_monitor_section_button.set_active (true);
513 use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
514 no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
516 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\
517 <i>If you do not understand what this is about, just accept the default.</i>"));
518 monitor_section_label.set_alignment (0.0, 0.0);
520 hbox->pack_start (*main_vbox, true, true, 8);
521 mon_sec_vbox.pack_start (*hbox, false, false);
522 mon_sec_vbox.pack_start (monitor_section_label, false, false);
524 mon_sec_vbox.show_all ();
526 monitor_section_page_index = append_page (mon_sec_vbox);
527 set_page_title (mon_sec_vbox, _("Monitor Section"));
528 set_page_header_image (mon_sec_vbox, icon_pixbuf);
530 /* user could just click on "Forward" if default
534 set_page_complete (mon_sec_vbox, true);
538 ArdourStartup::setup_initial_choice_page ()
540 ic_vbox.set_spacing (6);
541 ic_vbox.set_border_width (24);
543 RadioButton::Group g (ic_new_session_button.get_group());
544 ic_existing_session_button.set_group (g);
546 HBox* centering_hbox = manage (new HBox);
547 VBox* centering_vbox = manage (new VBox);
549 centering_vbox->set_spacing (6);
551 centering_vbox->pack_start (ic_new_session_button, false, true);
552 centering_vbox->pack_start (ic_existing_session_button, false, true);
554 if (ARDOUR_UI::instance()->announce_string() != "" ) {
556 Gtk::Frame *info_frame = manage(new Gtk::Frame);
557 info_frame->set_shadow_type(SHADOW_ETCHED_OUT);
558 centering_vbox->pack_start (*info_frame, false, false, 20);
560 Box *info_box = manage (new VBox);
561 info_box->set_border_width (12);
562 info_box->set_spacing (6);
563 info_box->set_name("mixbus_info_box");
565 info_box->pack_start (info_scroller_label, false, false);
567 info_frame->add (*info_box);
568 info_frame->show_all();
570 info_scroller_count = 0;
571 info_scroller_connection = Glib::signal_timeout().connect (mem_fun(*this, &ArdourStartup::info_scroller_update), 50);
573 Gtk::Button *updates_button = manage (new Gtk::Button (_("Check the website for more...")));
575 updates_button->signal_clicked().connect (mem_fun(*this, &ArdourStartup::updates_button_clicked) );
576 ARDOUR_UI::instance()->tooltips().set_tip (*updates_button, _("Click to open the program website in your web browser"));
578 info_box->pack_start (*updates_button, false, false);
581 ic_new_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
582 ic_new_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
584 ic_existing_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
585 ic_existing_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
587 centering_hbox->pack_start (*centering_vbox, true, true);
589 ic_vbox.pack_start (*centering_hbox, true, true);
593 initial_choice_index = append_page (ic_vbox);
594 set_page_title (ic_vbox, string_compose("%1 %2", PROGRAM_NAME, VERSIONSTRING));
595 set_page_header_image (ic_vbox, icon_pixbuf);
597 /* user could just click on "Forward" if default
601 set_page_complete (ic_vbox, true);
605 ArdourStartup::initial_button_clicked (GdkEventButton* ev)
607 if (ev->type == GDK_2BUTTON_PRESS && session_page_index != -1) {
608 set_current_page(session_page_index);
615 ArdourStartup::initial_button_activated ()
617 if (session_page_index != -1) {
618 set_current_page(session_page_index);
623 ArdourStartup::setup_session_page ()
625 session_vbox.set_border_width (24);
627 session_vbox.pack_start (session_hbox, true, true);
628 session_vbox.show_all ();
630 session_page_index = append_page (session_vbox);
631 /* initial setting */
632 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
636 ArdourStartup::setup_final_page ()
638 final_page.set_text (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
640 final_page_index = append_page (final_page);
641 set_page_complete (final_page, true);
642 set_page_header_image (final_page, icon_pixbuf);
643 set_page_type (final_page, ASSISTANT_PAGE_CONFIRM);
647 ArdourStartup::on_cancel ()
649 _response = RESPONSE_CANCEL;
654 ArdourStartup::on_delete_event (GdkEventAny*)
656 _response = RESPONSE_CLOSE;
662 ArdourStartup::on_apply ()
665 if (engine_dialog->setup_engine ()) {
666 set_current_page (audio_page_index);
671 if (config_modified) {
673 if (default_dir_chooser) {
674 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
677 if (monitor_via_hardware_button.get_active()) {
678 Config->set_monitoring_model (ExternalMonitoring);
679 } else if (monitor_via_ardour_button.get_active()) {
680 Config->set_monitoring_model (SoftwareMonitoring);
683 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
685 Config->save_state ();
690 /* "touch" the been-here-before path now we've successfully
691 made it through the first time setup (at least)
693 ofstream fout (been_here_before_path().c_str());
697 _response = RESPONSE_OK;
702 ArdourStartup::on_prepare (Gtk::Widget* page)
704 if (page == &session_vbox) {
706 if (ic_new_session_button.get_active()) {
707 /* new session requested */
708 setup_new_session_page ();
710 /* existing session requested */
711 setup_existing_session_page ();
715 /* HACK HACK HACK ... change the "Apply" button label
719 Gtk::Widget* tl = session_vbox.get_toplevel();
721 if ((win = dynamic_cast<Gtk::Window*>(tl)) != 0) {
722 /* ::get_default_widget() is not wrapped in gtkmm */
723 Gtk::Widget* def = wrap (gtk_window_get_default_widget (win->gobj()));
725 if ((button = dynamic_cast<Gtk::Button*>(def)) != 0) {
726 if (more_new_session_options_button.get_active()) {
727 button->set_label (_("Forward"));
729 button->set_label (_("Open"));
737 ArdourStartup::populate_session_templates ()
739 vector<TemplateInfo> templates;
741 find_session_templates (templates);
743 template_model->clear ();
745 for (vector<TemplateInfo>::iterator x = templates.begin(); x != templates.end(); ++x) {
748 row = *(template_model->append ());
750 row[session_template_columns.name] = (*x).name;
751 row[session_template_columns.path] = (*x).path;
756 ArdourStartup::setup_new_session_page ()
758 if (!session_hbox.get_children().empty()) {
759 session_hbox.remove (**session_hbox.get_children().begin());
762 session_new_vbox.set_spacing (18);
764 if (session_new_vbox.get_children().empty()) {
765 VBox *vbox1 = manage (new VBox);
766 HBox* hbox1 = manage (new HBox);
767 Label* label1 = manage (new Label);
769 vbox1->set_spacing (6);
771 hbox1->set_spacing (6);
772 hbox1->pack_start (*label1, false, false);
773 hbox1->pack_start (new_name_entry, true, true);
775 label1->set_text (_("Session name:"));
778 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
779 new_name_entry.set_text (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
780 /* name provided - they can move right along */
781 set_page_complete (session_vbox, true);
784 new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_changed));
785 new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &ArdourStartup::move_along_now));
787 vbox1->pack_start (*hbox1, true, true);
791 HBox* hbox2 = manage (new HBox);
792 Label* label2 = manage (new Label);
794 hbox2->set_spacing (6);
795 hbox2->pack_start (*label2, false, false);
796 hbox2->pack_start (new_folder_chooser, true, true);
798 label2->set_text (_("Create session folder in:"));
800 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
801 new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
802 } else if (ARDOUR_UI::instance()->session_loaded) {
803 // point the new session file chooser at the parent directory of the current session
804 string session_parent_dir = Glib::path_get_dirname(ARDOUR_UI::instance()->the_session()->path());
805 string::size_type last_dir_sep = session_parent_dir.rfind(G_DIR_SEPARATOR);
806 session_parent_dir = session_parent_dir.substr(0, last_dir_sep);
807 new_folder_chooser.set_current_folder (session_parent_dir);
808 new_folder_chooser.add_shortcut_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
810 new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
812 new_folder_chooser.show ();
813 new_folder_chooser.set_title (_("Select folder for session"));
816 new_folder_chooser.add_shortcut_folder ("/Volumes");
819 vbox1->pack_start (*hbox2, false, false);
821 session_new_vbox.pack_start (*vbox1, false, false);
825 VBox *vbox2 = manage (new VBox);
826 HBox* hbox3 = manage (new HBox);
827 Label* label3 = manage (new Label);
828 template_model = ListStore::create (session_template_columns);
829 populate_session_templates ();
831 vbox2->set_spacing (6);
833 label3->set_markup (_("<b>Options</b>"));
834 label3->set_alignment (0.0, 0.0);
836 vbox2->pack_start (*label3, false, true);
838 VBox *vbox3 = manage (new VBox);
840 vbox3->set_spacing (6);
842 if (!template_model->children().empty()) {
844 HBox* hbox4a = manage (new HBox);
845 use_template_button.set_label (_("Use this template"));
847 TreeModel::Row row = *template_model->prepend ();
848 row[session_template_columns.name] = (_("no template"));
849 row[session_template_columns.path] = string();
851 hbox4a->set_spacing (6);
852 hbox4a->pack_start (use_template_button, false, false);
853 hbox4a->pack_start (template_chooser, true, true);
855 template_chooser.set_model (template_model);
857 Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
858 text_renderer->property_editable() = false;
860 template_chooser.pack_start (*text_renderer);
861 template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
862 template_chooser.set_active (0);
864 use_template_button.show();
865 template_chooser.show ();
867 vbox3->pack_start (*hbox4a, false, false);
873 session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
875 HBox* hbox4b = manage (new HBox);
876 use_session_as_template_button.set_label (_("Use an existing session as a template:"));
878 hbox4b->set_spacing (6);
879 hbox4b->pack_start (use_session_as_template_button, false, false);
880 hbox4b->pack_start (session_template_chooser, true, true);
882 use_session_as_template_button.show ();
883 session_template_chooser.show ();
885 Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
886 session_filter->add_pattern (X_("*.ardour"));
887 session_template_chooser.set_filter (*session_filter);
888 session_template_chooser.set_title (_("Select template"));
890 vbox3->pack_start (*hbox4b, false, false);
895 HBox* hbox5 = manage (new HBox);
897 hbox5->set_spacing (6);
898 hbox5->pack_start (more_new_session_options_button, false, false);
900 more_new_session_options_button.show ();
901 more_new_session_options_button.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::more_new_session_options_button_clicked));
903 vbox3->pack_start (*hbox5, false, false);
904 hbox3->pack_start (*vbox3, true, true, 8);
905 vbox2->pack_start (*hbox3, false, false);
909 session_new_vbox.pack_start (*vbox2, false, false);
912 session_new_vbox.show_all ();
913 session_hbox.pack_start (session_new_vbox, true, true);
914 set_page_title (session_vbox, _("New Session"));
915 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
917 if (more_new_session_options_button.get_active()) {
918 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
923 ArdourStartup::new_name_changed ()
925 if (!new_name_entry.get_text().empty()) {
926 set_page_complete (session_vbox, true);
928 set_page_complete (session_vbox, false);
933 ArdourStartup::redisplay_recent_sessions ()
935 std::vector<std::string> session_directories;
936 RecentSessionsSorter cmp;
938 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
939 recent_session_model->clear ();
941 ARDOUR::RecentSessions rs;
942 ARDOUR::read_recent_sessions (rs);
945 recent_session_display.set_model (recent_session_model);
949 // sort them alphabetically
950 sort (rs.begin(), rs.end(), cmp);
952 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
953 session_directories.push_back ((*i).second);
956 int session_snapshot_count = 0;
958 for (vector<std::string>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
960 std::vector<std::string> state_file_paths;
962 // now get available states for this session
964 get_state_files_in_directory (*i, state_file_paths);
966 vector<string*>* states;
967 vector<const gchar*> item;
968 string fullpath = *i;
970 /* remove any trailing / */
972 if (fullpath[fullpath.length()-1] == '/') {
973 fullpath = fullpath.substr (0, fullpath.length()-1);
976 /* check whether session still exists */
977 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
978 /* session doesn't exist */
982 /* now get available states for this session */
984 if ((states = Session::possible_states (fullpath)) == 0) {
989 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
991 Gtk::TreeModel::Row row = *(recent_session_model->append());
993 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
994 row[recent_session_columns.fullpath] = fullpath;
995 row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
997 ++session_snapshot_count;
999 if (state_file_names.size() > 1) {
1003 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
1004 i2 != state_file_names.end(); ++i2) {
1006 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
1008 child_row[recent_session_columns.visible_name] = *i2;
1009 child_row[recent_session_columns.fullpath] = fullpath;
1010 child_row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
1011 ++session_snapshot_count;
1016 recent_session_display.set_tooltip_column(1); // recent_session_columns.tip
1017 recent_session_display.set_model (recent_session_model);
1018 return session_snapshot_count;
1019 // return rs.size();
1023 ArdourStartup::recent_session_row_selected ()
1025 if (recent_session_display.get_selection()->count_selected_rows() > 0) {
1026 set_page_complete (session_vbox, true);
1028 set_page_complete (session_vbox, false);
1033 ArdourStartup::setup_existing_session_page ()
1035 recent_session_model = TreeStore::create (recent_session_columns);
1036 redisplay_recent_sessions ();
1038 if (!session_hbox.get_children().empty()) {
1039 session_hbox.remove (**session_hbox.get_children().begin());
1042 if (session_existing_vbox.get_children().empty()) {
1044 recent_session_display.set_model (recent_session_model);
1045 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1046 recent_session_display.set_headers_visible (false);
1047 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
1049 recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::recent_session_row_selected));
1051 recent_scroller.add (recent_session_display);
1052 recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1053 recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
1055 recent_session_display.show();
1057 recent_scroller.show();
1058 int cnt = redisplay_recent_sessions ();
1059 recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ArdourStartup::recent_row_activated));
1062 recent_scroller.set_size_request (-1, 300);
1065 session_existing_vbox.set_spacing (8);
1066 session_existing_vbox.pack_start (recent_scroller, true, true);
1068 existing_session_chooser.set_title (_("Select session file"));
1069 existing_session_chooser.signal_file_set().connect (sigc::mem_fun (*this, &ArdourStartup::existing_session_selected));
1070 existing_session_chooser.set_current_folder(poor_mans_glob (Config->get_default_session_parent_dir()));
1072 FileFilter session_filter;
1073 session_filter.add_pattern ("*.ardour");
1074 session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
1075 existing_session_chooser.add_filter (session_filter);
1076 existing_session_chooser.set_filter (session_filter);
1079 existing_session_chooser.add_shortcut_folder ("/Volumes");
1082 HBox* hbox = manage (new HBox);
1083 hbox->set_spacing (4);
1084 hbox->pack_start (*manage (new Label (_("Browse:"))), PACK_SHRINK);
1085 hbox->pack_start (existing_session_chooser);
1086 session_existing_vbox.pack_start (*hbox, false, false);
1090 session_existing_vbox.show_all ();
1091 session_hbox.pack_start (session_existing_vbox, true, true);
1093 set_page_title (session_vbox, _("Select a session"));
1094 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1098 ArdourStartup::more_new_session_options_button_clicked ()
1100 if (more_new_session_options_button.get_active()) {
1101 more_options_vbox.show_all ();
1102 set_page_type (more_options_vbox, ASSISTANT_PAGE_CONFIRM);
1103 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
1105 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1106 more_options_vbox.hide ();
1111 ArdourStartup::setup_more_options_page ()
1113 more_options_vbox.set_border_width (24);
1115 _output_limit_count.set_adjustment (_output_limit_count_adj);
1116 _input_limit_count.set_adjustment (_input_limit_count_adj);
1117 _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
1119 chan_count_label_1.set_text (_("channels"));
1120 chan_count_label_3.set_text (_("channels"));
1121 chan_count_label_4.set_text (_("channels"));
1123 chan_count_label_1.set_alignment(0,0.5);
1124 chan_count_label_1.set_padding(0,0);
1125 chan_count_label_1.set_line_wrap(false);
1127 chan_count_label_3.set_alignment(0,0.5);
1128 chan_count_label_3.set_padding(0,0);
1129 chan_count_label_3.set_line_wrap(false);
1131 chan_count_label_4.set_alignment(0,0.5);
1132 chan_count_label_4.set_padding(0,0);
1133 chan_count_label_4.set_line_wrap(false);
1135 bus_label.set_markup (_("<b>Busses</b>"));
1136 input_label.set_markup (_("<b>Inputs</b>"));
1137 output_label.set_markup (_("<b>Outputs</b>"));
1139 _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
1140 _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1141 _master_bus_channel_count.set_numeric(true);
1142 _master_bus_channel_count.set_digits(0);
1143 _master_bus_channel_count.set_wrap(false);
1145 _create_master_bus.set_label (_("Create master bus"));
1146 _create_master_bus.set_flags(Gtk::CAN_FOCUS);
1147 _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
1148 _create_master_bus.set_mode(true);
1149 _create_master_bus.set_active(true);
1150 _create_master_bus.set_border_width(0);
1152 advanced_table.set_row_spacings(0);
1153 advanced_table.set_col_spacings(0);
1155 _connect_inputs.set_label (_("Automatically connect to physical inputs"));
1156 _connect_inputs.set_flags(Gtk::CAN_FOCUS);
1157 _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
1158 _connect_inputs.set_mode(true);
1159 _connect_inputs.set_active(Config->get_input_auto_connect() != ManualConnect);
1160 _connect_inputs.set_border_width(0);
1162 _limit_input_ports.set_label (_("Use only"));
1163 _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
1164 _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
1165 _limit_input_ports.set_mode(true);
1166 _limit_input_ports.set_sensitive(true);
1167 _limit_input_ports.set_border_width(0);
1169 _input_limit_count.set_flags(Gtk::CAN_FOCUS);
1170 _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1171 _input_limit_count.set_numeric(true);
1172 _input_limit_count.set_digits(0);
1173 _input_limit_count.set_wrap(false);
1174 _input_limit_count.set_sensitive(false);
1176 bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
1178 bus_label.set_alignment(0, 0.5);
1179 bus_label.set_padding(0,0);
1180 bus_label.set_line_wrap(false);
1181 bus_label.set_selectable(false);
1182 bus_label.set_use_markup(true);
1183 bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
1184 bus_frame.set_label_align(0,0.5);
1185 bus_frame.add(bus_hbox);
1186 bus_frame.set_label_widget(bus_label);
1188 bus_table.set_row_spacings (0);
1189 bus_table.set_col_spacings (0);
1190 bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1191 bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1192 bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
1194 input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
1195 input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
1196 input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
1197 input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
1198 input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
1199 input_table.set_row_spacings(0);
1200 input_table.set_col_spacings(0);
1201 input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
1203 input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
1205 input_label.set_alignment(0, 0.5);
1206 input_label.set_padding(0,0);
1207 input_label.set_line_wrap(false);
1208 input_label.set_selectable(false);
1209 input_label.set_use_markup(true);
1210 input_frame.set_shadow_type(Gtk::SHADOW_NONE);
1211 input_frame.set_label_align(0,0.5);
1212 input_frame.add(input_hbox);
1213 input_frame.set_label_widget(input_label);
1215 _connect_outputs.set_label (_("Automatically connect outputs"));
1216 _connect_outputs.set_flags(Gtk::CAN_FOCUS);
1217 _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
1218 _connect_outputs.set_mode(true);
1219 _connect_outputs.set_active(Config->get_output_auto_connect() != ManualConnect);
1220 _connect_outputs.set_border_width(0);
1221 _limit_output_ports.set_label (_("Use only"));
1222 _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
1223 _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
1224 _limit_output_ports.set_mode(true);
1225 _limit_output_ports.set_sensitive(true);
1226 _limit_output_ports.set_border_width(0);
1227 _output_limit_count.set_flags(Gtk::CAN_FOCUS);
1228 _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1229 _output_limit_count.set_numeric(false);
1230 _output_limit_count.set_digits(0);
1231 _output_limit_count.set_wrap(false);
1232 _output_limit_count.set_sensitive(false);
1233 output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
1234 output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
1235 output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
1237 _connect_outputs_to_master.set_label (_("... to master bus"));
1238 _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
1239 _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
1240 _connect_outputs_to_master.set_mode(true);
1241 _connect_outputs_to_master.set_active(Config->get_output_auto_connect() == AutoConnectMaster);
1242 _connect_outputs_to_master.set_border_width(0);
1244 _connect_outputs_to_master.set_group (connect_outputs_group);
1245 _connect_outputs_to_physical.set_group (connect_outputs_group);
1247 _connect_outputs_to_physical.set_label (_("... to physical outputs"));
1248 _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
1249 _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
1250 _connect_outputs_to_physical.set_mode(true);
1251 _connect_outputs_to_physical.set_active(Config->get_output_auto_connect() == AutoConnectPhysical);
1252 _connect_outputs_to_physical.set_border_width(0);
1254 output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
1255 output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
1256 output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
1257 output_vbox.set_border_width(6);
1259 output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
1261 output_vbox.pack_start(output_conn_vbox);
1262 output_vbox.pack_start(output_port_vbox);
1264 output_label.set_alignment(0, 0.5);
1265 output_label.set_padding(0,0);
1266 output_label.set_line_wrap(false);
1267 output_label.set_selectable(false);
1268 output_label.set_use_markup(true);
1269 output_frame.set_shadow_type(Gtk::SHADOW_NONE);
1270 output_frame.set_label_align(0,0.5);
1272 output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
1274 output_frame.add(output_hbox);
1275 output_frame.set_label_widget(output_label);
1277 more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
1278 more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
1279 more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
1280 more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
1284 _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
1285 _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
1286 _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
1287 _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
1288 _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
1290 /* note that more_options_vbox is "visible" by default even
1291 * though it may not be displayed to the user, this is so the dialog
1294 more_options_vbox.show_all ();
1296 session_options_page_index = append_page (more_options_vbox);
1297 set_page_title (more_options_vbox, _("Advanced Session Options"));
1298 set_page_complete (more_options_vbox, true);
1302 ArdourStartup::create_master_bus() const
1304 return _create_master_bus.get_active();
1308 ArdourStartup::master_channel_count() const
1310 return _master_bus_channel_count.get_value_as_int();
1314 ArdourStartup::connect_inputs() const
1316 return _connect_inputs.get_active();
1320 ArdourStartup::limit_inputs_used_for_connection() const
1322 return _limit_input_ports.get_active();
1326 ArdourStartup::input_limit_count() const
1328 return _input_limit_count.get_value_as_int();
1332 ArdourStartup::connect_outputs() const
1334 return _connect_outputs.get_active();
1338 ArdourStartup::limit_outputs_used_for_connection() const
1340 return _limit_output_ports.get_active();
1344 ArdourStartup::output_limit_count() const
1346 return _output_limit_count.get_value_as_int();
1350 ArdourStartup::connect_outs_to_master() const
1352 return _connect_outputs_to_master.get_active();
1356 ArdourStartup::connect_outs_to_physical() const
1358 return _connect_outputs_to_physical.get_active();
1362 ArdourStartup::connect_inputs_clicked ()
1364 _limit_input_ports.set_sensitive(_connect_inputs.get_active());
1366 if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
1367 _input_limit_count.set_sensitive(true);
1369 _input_limit_count.set_sensitive(false);
1374 ArdourStartup::connect_outputs_clicked ()
1376 bool const co = _connect_outputs.get_active ();
1377 _limit_output_ports.set_sensitive(co);
1378 _connect_outputs_to_master.set_sensitive(co);
1379 _connect_outputs_to_physical.set_sensitive(co);
1381 if (co && _limit_output_ports.get_active()) {
1382 _output_limit_count.set_sensitive(true);
1384 _output_limit_count.set_sensitive(false);
1389 ArdourStartup::limit_inputs_clicked ()
1391 _input_limit_count.set_sensitive(_limit_input_ports.get_active());
1395 ArdourStartup::limit_outputs_clicked ()
1397 _output_limit_count.set_sensitive(_limit_output_ports.get_active());
1401 ArdourStartup::master_bus_button_clicked ()
1403 bool const yn = _create_master_bus.get_active();
1405 _master_bus_channel_count.set_sensitive(yn);
1406 _connect_outputs_to_master.set_sensitive(yn);
1410 ArdourStartup::move_along_now ()
1412 gint cur = get_current_page ();
1414 if (cur == session_page_index) {
1415 if (more_new_session_options_button.get_active()) {
1416 set_current_page (session_options_page_index);
1424 ArdourStartup::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
1426 set_page_complete (session_vbox, true);
1431 ArdourStartup::existing_session_selected ()
1433 _existing_session_chooser_used = true;
1435 set_page_complete (session_vbox, true);
1440 ArdourStartup::been_here_before_path () const
1442 // XXXX use more specific version so we can catch upgrades
1443 return Glib::build_filename (user_config_directory (), ".a3");
1447 ArdourStartup::updates_button_clicked ()
1449 //now open a browser window so user can see more
1450 PBD::open_uri (Config->get_updates_url());
1454 ArdourStartup::info_scroller_update()
1456 info_scroller_count++;
1459 snprintf (buf, std::min(info_scroller_count,sizeof(buf)-1), "%s", ARDOUR_UI::instance()->announce_string().c_str() );
1460 buf[info_scroller_count] = 0;
1461 info_scroller_label.set_text (buf);
1462 info_scroller_label.show();
1464 if (info_scroller_count > ARDOUR_UI::instance()->announce_string().length()) {
1465 info_scroller_connection.disconnect();