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 (string_compose (_("<b>Welcome to this BETA release of Ardour %1</b>\n\n\
195 Ardour %1 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 %1-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 string default_session_folder = poor_mans_glob (Config->get_default_session_parent_dir());
811 /* add_shortcut_folder throws an exception if the folder being added already has a shortcut */
812 new_folder_chooser.add_shortcut_folder (default_session_folder);
814 catch (Glib::Error & e) {
815 std::cerr << "new_folder_chooser.add_shortcut_folder (" << default_session_folder << ") threw Glib::Error " << e.what() << std::endl;
818 new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
820 new_folder_chooser.show ();
821 new_folder_chooser.set_title (_("Select folder for session"));
824 new_folder_chooser.add_shortcut_folder ("/Volumes");
827 vbox1->pack_start (*hbox2, false, false);
829 session_new_vbox.pack_start (*vbox1, false, false);
833 VBox *vbox2 = manage (new VBox);
834 HBox* hbox3 = manage (new HBox);
835 Label* label3 = manage (new Label);
836 template_model = ListStore::create (session_template_columns);
837 populate_session_templates ();
839 vbox2->set_spacing (6);
841 label3->set_markup (_("<b>Options</b>"));
842 label3->set_alignment (0.0, 0.0);
844 vbox2->pack_start (*label3, false, true);
846 VBox *vbox3 = manage (new VBox);
848 vbox3->set_spacing (6);
850 if (!template_model->children().empty()) {
852 HBox* hbox4a = manage (new HBox);
853 use_template_button.set_label (_("Use this template"));
855 TreeModel::Row row = *template_model->prepend ();
856 row[session_template_columns.name] = (_("no template"));
857 row[session_template_columns.path] = string();
859 hbox4a->set_spacing (6);
860 hbox4a->pack_start (use_template_button, false, false);
861 hbox4a->pack_start (template_chooser, true, true);
863 template_chooser.set_model (template_model);
865 Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
866 text_renderer->property_editable() = false;
868 template_chooser.pack_start (*text_renderer);
869 template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
870 template_chooser.set_active (0);
872 use_template_button.show();
873 template_chooser.show ();
875 vbox3->pack_start (*hbox4a, false, false);
881 session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
883 HBox* hbox4b = manage (new HBox);
884 use_session_as_template_button.set_label (_("Use an existing session as a template:"));
886 hbox4b->set_spacing (6);
887 hbox4b->pack_start (use_session_as_template_button, false, false);
888 hbox4b->pack_start (session_template_chooser, true, true);
890 use_session_as_template_button.show ();
891 session_template_chooser.show ();
893 Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
894 session_filter->add_pattern (X_("*.ardour"));
895 session_template_chooser.set_filter (*session_filter);
896 session_template_chooser.set_title (_("Select template"));
898 vbox3->pack_start (*hbox4b, false, false);
903 HBox* hbox5 = manage (new HBox);
905 hbox5->set_spacing (6);
906 hbox5->pack_start (more_new_session_options_button, false, false);
908 more_new_session_options_button.show ();
909 more_new_session_options_button.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::more_new_session_options_button_clicked));
911 vbox3->pack_start (*hbox5, false, false);
912 hbox3->pack_start (*vbox3, true, true, 8);
913 vbox2->pack_start (*hbox3, false, false);
917 session_new_vbox.pack_start (*vbox2, false, false);
920 session_new_vbox.show_all ();
921 session_hbox.pack_start (session_new_vbox, true, true);
922 set_page_title (session_vbox, _("New Session"));
923 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
925 if (more_new_session_options_button.get_active()) {
926 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
928 session_hbox.show_all();
932 ArdourStartup::new_name_changed ()
934 if (!new_name_entry.get_text().empty()) {
935 set_page_complete (session_vbox, true);
937 set_page_complete (session_vbox, false);
942 ArdourStartup::redisplay_recent_sessions ()
944 std::vector<std::string> session_directories;
945 RecentSessionsSorter cmp;
947 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
948 recent_session_model->clear ();
950 ARDOUR::RecentSessions rs;
951 ARDOUR::read_recent_sessions (rs);
954 recent_session_display.set_model (recent_session_model);
958 // sort them alphabetically
959 sort (rs.begin(), rs.end(), cmp);
961 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
962 session_directories.push_back ((*i).second);
965 int session_snapshot_count = 0;
967 for (vector<std::string>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
969 std::vector<std::string> state_file_paths;
971 // now get available states for this session
973 get_state_files_in_directory (*i, state_file_paths);
975 vector<string*>* states;
976 vector<const gchar*> item;
977 string fullpath = *i;
979 /* remove any trailing / */
981 if (fullpath[fullpath.length()-1] == '/') {
982 fullpath = fullpath.substr (0, fullpath.length()-1);
985 /* check whether session still exists */
986 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
987 /* session doesn't exist */
991 /* now get available states for this session */
993 if ((states = Session::possible_states (fullpath)) == 0) {
998 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
1000 Gtk::TreeModel::Row row = *(recent_session_model->append());
1002 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
1003 row[recent_session_columns.fullpath] = fullpath;
1004 row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
1006 ++session_snapshot_count;
1008 if (state_file_names.size() > 1) {
1012 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
1013 i2 != state_file_names.end(); ++i2) {
1015 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
1017 child_row[recent_session_columns.visible_name] = *i2;
1018 child_row[recent_session_columns.fullpath] = fullpath;
1019 child_row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
1020 ++session_snapshot_count;
1025 recent_session_display.set_tooltip_column(1); // recent_session_columns.tip
1026 recent_session_display.set_model (recent_session_model);
1027 return session_snapshot_count;
1028 // return rs.size();
1032 ArdourStartup::recent_session_row_selected ()
1034 if (recent_session_display.get_selection()->count_selected_rows() > 0) {
1035 set_page_complete (session_vbox, true);
1037 set_page_complete (session_vbox, false);
1042 ArdourStartup::setup_existing_session_page ()
1044 recent_session_model = TreeStore::create (recent_session_columns);
1045 redisplay_recent_sessions ();
1047 if (!session_hbox.get_children().empty()) {
1048 session_hbox.remove (**session_hbox.get_children().begin());
1051 if (session_existing_vbox.get_children().empty()) {
1053 recent_session_display.set_model (recent_session_model);
1054 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1055 recent_session_display.set_headers_visible (false);
1056 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
1058 recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::recent_session_row_selected));
1060 recent_scroller.add (recent_session_display);
1061 recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1062 recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
1064 recent_session_display.show();
1066 recent_scroller.show();
1067 int cnt = redisplay_recent_sessions ();
1068 recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ArdourStartup::recent_row_activated));
1071 recent_scroller.set_size_request (-1, 300);
1074 session_existing_vbox.set_spacing (8);
1075 session_existing_vbox.pack_start (recent_scroller, true, true);
1077 existing_session_chooser.set_title (_("Select session file"));
1078 existing_session_chooser.signal_file_set().connect (sigc::mem_fun (*this, &ArdourStartup::existing_session_selected));
1079 existing_session_chooser.set_current_folder(poor_mans_glob (Config->get_default_session_parent_dir()));
1081 FileFilter session_filter;
1082 session_filter.add_pattern ("*.ardour");
1083 session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
1084 existing_session_chooser.add_filter (session_filter);
1085 existing_session_chooser.set_filter (session_filter);
1088 existing_session_chooser.add_shortcut_folder ("/Volumes");
1091 HBox* hbox = manage (new HBox);
1092 hbox->set_spacing (4);
1093 hbox->pack_start (*manage (new Label (_("Browse:"))), PACK_SHRINK);
1094 hbox->pack_start (existing_session_chooser);
1095 session_existing_vbox.pack_start (*hbox, false, false);
1099 session_existing_vbox.show_all ();
1100 session_hbox.pack_start (session_existing_vbox, true, true);
1102 set_page_title (session_vbox, _("Select a session"));
1103 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1104 session_hbox.show_all();
1108 ArdourStartup::more_new_session_options_button_clicked ()
1110 if (more_new_session_options_button.get_active()) {
1111 more_options_vbox.show_all ();
1112 set_page_type (more_options_vbox, ASSISTANT_PAGE_CONFIRM);
1113 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
1115 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1116 more_options_vbox.hide ();
1121 ArdourStartup::setup_more_options_page ()
1123 more_options_vbox.set_border_width (24);
1125 _output_limit_count.set_adjustment (_output_limit_count_adj);
1126 _input_limit_count.set_adjustment (_input_limit_count_adj);
1127 _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
1129 chan_count_label_1.set_text (_("channels"));
1130 chan_count_label_3.set_text (_("channels"));
1131 chan_count_label_4.set_text (_("channels"));
1133 chan_count_label_1.set_alignment(0,0.5);
1134 chan_count_label_1.set_padding(0,0);
1135 chan_count_label_1.set_line_wrap(false);
1137 chan_count_label_3.set_alignment(0,0.5);
1138 chan_count_label_3.set_padding(0,0);
1139 chan_count_label_3.set_line_wrap(false);
1141 chan_count_label_4.set_alignment(0,0.5);
1142 chan_count_label_4.set_padding(0,0);
1143 chan_count_label_4.set_line_wrap(false);
1145 bus_label.set_markup (_("<b>Busses</b>"));
1146 input_label.set_markup (_("<b>Inputs</b>"));
1147 output_label.set_markup (_("<b>Outputs</b>"));
1149 _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
1150 _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1151 _master_bus_channel_count.set_numeric(true);
1152 _master_bus_channel_count.set_digits(0);
1153 _master_bus_channel_count.set_wrap(false);
1155 _create_master_bus.set_label (_("Create master bus"));
1156 _create_master_bus.set_flags(Gtk::CAN_FOCUS);
1157 _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
1158 _create_master_bus.set_mode(true);
1159 _create_master_bus.set_active(true);
1160 _create_master_bus.set_border_width(0);
1162 advanced_table.set_row_spacings(0);
1163 advanced_table.set_col_spacings(0);
1165 _connect_inputs.set_label (_("Automatically connect to physical inputs"));
1166 _connect_inputs.set_flags(Gtk::CAN_FOCUS);
1167 _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
1168 _connect_inputs.set_mode(true);
1169 _connect_inputs.set_active(Config->get_input_auto_connect() != ManualConnect);
1170 _connect_inputs.set_border_width(0);
1172 _limit_input_ports.set_label (_("Use only"));
1173 _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
1174 _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
1175 _limit_input_ports.set_mode(true);
1176 _limit_input_ports.set_sensitive(true);
1177 _limit_input_ports.set_border_width(0);
1179 _input_limit_count.set_flags(Gtk::CAN_FOCUS);
1180 _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1181 _input_limit_count.set_numeric(true);
1182 _input_limit_count.set_digits(0);
1183 _input_limit_count.set_wrap(false);
1184 _input_limit_count.set_sensitive(false);
1186 bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
1188 bus_label.set_alignment(0, 0.5);
1189 bus_label.set_padding(0,0);
1190 bus_label.set_line_wrap(false);
1191 bus_label.set_selectable(false);
1192 bus_label.set_use_markup(true);
1193 bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
1194 bus_frame.set_label_align(0,0.5);
1195 bus_frame.add(bus_hbox);
1196 bus_frame.set_label_widget(bus_label);
1198 bus_table.set_row_spacings (0);
1199 bus_table.set_col_spacings (0);
1200 bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1201 bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1202 bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
1204 input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
1205 input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
1206 input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
1207 input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
1208 input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
1209 input_table.set_row_spacings(0);
1210 input_table.set_col_spacings(0);
1211 input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
1213 input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
1215 input_label.set_alignment(0, 0.5);
1216 input_label.set_padding(0,0);
1217 input_label.set_line_wrap(false);
1218 input_label.set_selectable(false);
1219 input_label.set_use_markup(true);
1220 input_frame.set_shadow_type(Gtk::SHADOW_NONE);
1221 input_frame.set_label_align(0,0.5);
1222 input_frame.add(input_hbox);
1223 input_frame.set_label_widget(input_label);
1225 _connect_outputs.set_label (_("Automatically connect outputs"));
1226 _connect_outputs.set_flags(Gtk::CAN_FOCUS);
1227 _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
1228 _connect_outputs.set_mode(true);
1229 _connect_outputs.set_active(Config->get_output_auto_connect() != ManualConnect);
1230 _connect_outputs.set_border_width(0);
1231 _limit_output_ports.set_label (_("Use only"));
1232 _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
1233 _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
1234 _limit_output_ports.set_mode(true);
1235 _limit_output_ports.set_sensitive(true);
1236 _limit_output_ports.set_border_width(0);
1237 _output_limit_count.set_flags(Gtk::CAN_FOCUS);
1238 _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1239 _output_limit_count.set_numeric(false);
1240 _output_limit_count.set_digits(0);
1241 _output_limit_count.set_wrap(false);
1242 _output_limit_count.set_sensitive(false);
1243 output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
1244 output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
1245 output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
1247 _connect_outputs_to_master.set_label (_("... to master bus"));
1248 _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
1249 _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
1250 _connect_outputs_to_master.set_mode(true);
1251 _connect_outputs_to_master.set_active(Config->get_output_auto_connect() == AutoConnectMaster);
1252 _connect_outputs_to_master.set_border_width(0);
1254 _connect_outputs_to_master.set_group (connect_outputs_group);
1255 _connect_outputs_to_physical.set_group (connect_outputs_group);
1257 _connect_outputs_to_physical.set_label (_("... to physical outputs"));
1258 _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
1259 _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
1260 _connect_outputs_to_physical.set_mode(true);
1261 _connect_outputs_to_physical.set_active(Config->get_output_auto_connect() == AutoConnectPhysical);
1262 _connect_outputs_to_physical.set_border_width(0);
1264 output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
1265 output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
1266 output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
1267 output_vbox.set_border_width(6);
1269 output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
1271 output_vbox.pack_start(output_conn_vbox);
1272 output_vbox.pack_start(output_port_vbox);
1274 output_label.set_alignment(0, 0.5);
1275 output_label.set_padding(0,0);
1276 output_label.set_line_wrap(false);
1277 output_label.set_selectable(false);
1278 output_label.set_use_markup(true);
1279 output_frame.set_shadow_type(Gtk::SHADOW_NONE);
1280 output_frame.set_label_align(0,0.5);
1282 output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
1284 output_frame.add(output_hbox);
1285 output_frame.set_label_widget(output_label);
1287 more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
1288 more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
1289 more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
1290 more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
1294 _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
1295 _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
1296 _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
1297 _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
1298 _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
1300 /* note that more_options_vbox is "visible" by default even
1301 * though it may not be displayed to the user, this is so the dialog
1304 more_options_vbox.show_all ();
1306 session_options_page_index = append_page (more_options_vbox);
1307 set_page_title (more_options_vbox, _("Advanced Session Options"));
1308 set_page_complete (more_options_vbox, true);
1312 ArdourStartup::create_master_bus() const
1314 return _create_master_bus.get_active();
1318 ArdourStartup::master_channel_count() const
1320 return _master_bus_channel_count.get_value_as_int();
1324 ArdourStartup::connect_inputs() const
1326 return _connect_inputs.get_active();
1330 ArdourStartup::limit_inputs_used_for_connection() const
1332 return _limit_input_ports.get_active();
1336 ArdourStartup::input_limit_count() const
1338 return _input_limit_count.get_value_as_int();
1342 ArdourStartup::connect_outputs() const
1344 return _connect_outputs.get_active();
1348 ArdourStartup::limit_outputs_used_for_connection() const
1350 return _limit_output_ports.get_active();
1354 ArdourStartup::output_limit_count() const
1356 return _output_limit_count.get_value_as_int();
1360 ArdourStartup::connect_outs_to_master() const
1362 return _connect_outputs_to_master.get_active();
1366 ArdourStartup::connect_outs_to_physical() const
1368 return _connect_outputs_to_physical.get_active();
1372 ArdourStartup::connect_inputs_clicked ()
1374 _limit_input_ports.set_sensitive(_connect_inputs.get_active());
1376 if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
1377 _input_limit_count.set_sensitive(true);
1379 _input_limit_count.set_sensitive(false);
1384 ArdourStartup::connect_outputs_clicked ()
1386 bool const co = _connect_outputs.get_active ();
1387 _limit_output_ports.set_sensitive(co);
1388 _connect_outputs_to_master.set_sensitive(co);
1389 _connect_outputs_to_physical.set_sensitive(co);
1391 if (co && _limit_output_ports.get_active()) {
1392 _output_limit_count.set_sensitive(true);
1394 _output_limit_count.set_sensitive(false);
1399 ArdourStartup::limit_inputs_clicked ()
1401 _input_limit_count.set_sensitive(_limit_input_ports.get_active());
1405 ArdourStartup::limit_outputs_clicked ()
1407 _output_limit_count.set_sensitive(_limit_output_ports.get_active());
1411 ArdourStartup::master_bus_button_clicked ()
1413 bool const yn = _create_master_bus.get_active();
1415 _master_bus_channel_count.set_sensitive(yn);
1416 _connect_outputs_to_master.set_sensitive(yn);
1420 ArdourStartup::move_along_now ()
1422 gint cur = get_current_page ();
1424 if (cur == session_page_index) {
1425 if (more_new_session_options_button.get_active()) {
1426 set_current_page (session_options_page_index);
1434 ArdourStartup::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
1436 set_page_complete (session_vbox, true);
1441 ArdourStartup::existing_session_selected ()
1443 _existing_session_chooser_used = true;
1445 set_page_complete (session_vbox, true);
1450 ArdourStartup::been_here_before_path () const
1452 // XXXX use more specific version so we can catch upgrades
1453 return Glib::build_filename (user_config_directory (), ".a3");
1457 ArdourStartup::updates_button_clicked ()
1459 //now open a browser window so user can see more
1460 PBD::open_uri (Config->get_updates_url());
1464 ArdourStartup::info_scroller_update()
1466 info_scroller_count++;
1469 snprintf (buf, std::min(info_scroller_count,sizeof(buf)-1), "%s", ARDOUR_UI::instance()->announce_string().c_str() );
1470 buf[info_scroller_count] = 0;
1471 info_scroller_label.set_text (buf);
1472 info_scroller_label.show();
1474 if (info_scroller_count > ARDOUR_UI::instance()->announce_string().length()) {
1475 info_scroller_connection.disconnect();