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/audioengine.h"
38 #include "ardour/filesystem_paths.h"
39 #include "ardour/recent_sessions.h"
40 #include "ardour/session.h"
41 #include "ardour/session_state_utils.h"
42 #include "ardour/template_utils.h"
43 #include "ardour/filename_extensions.h"
45 #include "ardour_ui.h"
48 #include "engine_dialog.h"
57 using namespace ARDOUR;
59 ArdourStartup* ArdourStartup::the_startup = 0;
61 static string poor_mans_glob (string path)
64 replace_all (copy, "~", Glib::get_home_dir());
68 ArdourStartup::ArdourStartup (bool require_new, const std::string& session_name, const std::string& session_path, const std::string& template_name)
69 : _response (RESPONSE_OK)
70 , config_modified (false)
71 , new_only (require_new)
72 , default_dir_chooser (0)
73 , ic_new_session_button (_("Create a new session"))
74 , ic_existing_session_button (_("Open an existing session"))
75 , monitor_via_hardware_button (string_compose (_("Use an external mixer or the hardware mixer of your audio interface.\n"
76 "%1 will play NO role in monitoring"), PROGRAM_NAME))
77 , monitor_via_ardour_button (string_compose (_("Ask %1 to play back material as it is being recorded"), PROGRAM_NAME))
79 , new_folder_chooser (FILE_CHOOSER_ACTION_SELECT_FOLDER)
80 , more_new_session_options_button (_("I'd like more options for this session"))
81 , _output_limit_count_adj (1, 0, 100, 1, 10, 0)
82 , _input_limit_count_adj (1, 0, 100, 1, 10, 0)
83 , _master_bus_channel_count_adj (2, 0, 100, 1, 10, 0)
84 , audio_page_index (-1)
85 , new_user_page_index (-1)
86 , default_folder_page_index (-1)
87 , monitoring_page_index (-1)
88 , session_page_index (-1)
89 , initial_choice_index (-1)
90 , final_page_index (-1)
91 , session_options_page_index (-1)
92 , _existing_session_chooser_used (false)
94 new_user = !Glib::file_test (been_here_before_path(), Glib::FILE_TEST_EXISTS);
95 need_audio_setup = AudioEngine::instance()->setup_required ();
96 need_session_info = (session_name.empty() || require_new);
98 _provided_session_name = session_name;
99 _provided_session_path = session_path;
101 if (need_audio_setup || need_session_info || new_user) {
103 use_template_button.set_group (session_template_group);
104 use_session_as_template_button.set_group (session_template_group);
106 set_keep_above (true);
107 set_position (WIN_POS_CENTER);
108 set_border_width (12);
110 if ((icon_pixbuf = ::get_icon ("ardour_icon_48px")) == 0) {
111 throw failed_constructor();
114 list<Glib::RefPtr<Gdk::Pixbuf> > window_icons;
115 Glib::RefPtr<Gdk::Pixbuf> icon;
117 if ((icon = ::get_icon ("ardour_icon_16px")) != 0) {
118 window_icons.push_back (icon);
120 if ((icon = ::get_icon ("ardour_icon_22px")) != 0) {
121 window_icons.push_back (icon);
123 if ((icon = ::get_icon ("ardour_icon_32px")) != 0) {
124 window_icons.push_back (icon);
126 if ((icon = ::get_icon ("ardour_icon_48px")) != 0) {
127 window_icons.push_back (icon);
129 if (!window_icons.empty ()) {
130 set_default_icon_list (window_icons);
134 setup_prerelease_page ();
138 setup_new_user_page ();
139 setup_first_time_config_page ();
140 setup_monitoring_choice_page ();
141 setup_monitor_section_choice_page ();
143 if (need_audio_setup) {
147 ic_new_session_button.set_active (true); // always create new session on first run
151 if (need_audio_setup) {
155 setup_initial_choice_page ();
158 setup_session_page ();
159 setup_more_options_page ();
171 if (!template_name.empty()) {
172 use_template_button.set_active (false);
173 load_template_override = template_name;
180 ArdourStartup::~ArdourStartup ()
185 ArdourStartup::ready_without_display () const
187 return !new_user && !need_audio_setup && !need_session_info;
191 ArdourStartup::setup_prerelease_page ()
193 VBox* vbox = manage (new VBox);
194 Label* label = manage (new Label);
195 label->set_markup (string_compose (_("<b>Welcome to this BETA release of Ardour %1</b>\n\n\
196 Ardour %1 has been released for Linux but because of the lack of testers,\n\
197 it is still at the beta stage on OS X. So, a few guidelines:\n\
199 1) Please do <b>NOT</b> use this software with the expectation that it is stable or reliable\n\
200 though it may be so, depending on your workflow.\n\
201 2) <b>Please do NOT use the forums at ardour.org to report issues</b>.\n\
202 3) Please <b>DO</b> use the bugtracker at http://tracker.ardour.org/ to report issues\n\
203 making sure to note the product version number as %1-beta.\n\
204 4) Please <b>DO</b> use the ardour-users mailing list to discuss ideas and pass on comments.\n\
205 5) Please <b>DO</b> join us on IRC for real time discussions about ardour3. You\n\
206 can get there directly from Ardour via the Help->Chat menu option.\n\
208 Full information on all the above can be found on the support page at\n\
210 http://ardour.org/support\n\
213 vbox->set_border_width (12);
214 vbox->pack_start (*label, false, false, 12);
218 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
219 set_page_title (*vbox, _("This is a BETA RELEASE"));
220 set_page_complete (*vbox, true);
224 ArdourStartup::use_session_template ()
226 if (!load_template_override.empty()) {
230 if (use_template_button.get_active()) {
231 return template_chooser.get_active_row_number() > 0;
233 return !session_template_chooser.get_filename().empty();
238 ArdourStartup::session_template_name ()
240 if (!load_template_override.empty()) {
241 string the_path (ARDOUR::user_template_directory());
242 return Glib::build_filename (the_path, load_template_override + ARDOUR::template_suffix);
245 if (ic_existing_session_button.get_active()) {
249 if (use_template_button.get_active()) {
250 TreeModel::iterator iter = template_chooser.get_active ();
251 TreeModel::Row row = (*iter);
252 string s = row[session_template_columns.path];
255 return session_template_chooser.get_filename();
261 ArdourStartup::session_name (bool& should_be_new)
263 if (ready_without_display()) {
264 return _provided_session_name;
267 if (ic_new_session_button.get_active()) {
268 should_be_new = true;
269 string val = new_name_entry.get_text ();
270 strip_whitespace_edges (val);
272 } else if (_existing_session_chooser_used) {
273 /* existing session chosen from file chooser */
274 should_be_new = false;
275 return existing_session_chooser.get_filename ();
277 /* existing session chosen from recent list */
278 should_be_new = false;
280 TreeIter iter = recent_session_display.get_selection()->get_selected();
283 return (*iter)[recent_session_columns.visible_name];
291 ArdourStartup::session_folder ()
293 if (ready_without_display()) {
294 return _provided_session_path;
297 if (ic_new_session_button.get_active()) {
298 std::string legal_session_folder_name = legalize_for_path (new_name_entry.get_text());
299 return Glib::build_filename (new_folder_chooser.get_current_folder(), legal_session_folder_name);
300 } else if (_existing_session_chooser_used) {
301 /* existing session chosen from file chooser */
302 return existing_session_chooser.get_current_folder ();
304 /* existing session chosen from recent list */
305 TreeIter iter = recent_session_display.get_selection()->get_selected();
308 return (*iter)[recent_session_columns.fullpath];
315 ArdourStartup::setup_audio_page ()
317 engine_dialog = manage (new EngineControl);
319 engine_dialog->set_border_width (12);
321 engine_dialog->show_all ();
323 audio_page_index = append_page (*engine_dialog);
324 set_page_type (*engine_dialog, ASSISTANT_PAGE_CONTENT);
325 set_page_title (*engine_dialog, _("Audio / MIDI Setup"));
327 /* the default parameters should work, so the page is potentially complete */
329 set_page_complete (*engine_dialog, true);
333 ArdourStartup::setup_new_user_page ()
335 Label* foomatic = manage (new Label);
337 foomatic->set_markup (string_compose (_("\
338 <span size=\"larger\">%1 is a digital audio workstation. You can use it to \
339 record, edit and mix multi-track audio. You can produce your \
340 own CDs, mix video soundtracks, or experiment with new \
341 ideas about music and sound. \
343 There are a few things that need to be configured before you start \
344 using the program.</span> \
346 foomatic->set_justify (JUSTIFY_FILL);
347 foomatic->set_line_wrap ();
349 HBox* hbox = manage (new HBox);
350 HBox* vbox = manage (new HBox);
352 vbox->set_border_width (24);
354 hbox->pack_start (*foomatic, true, true);
355 vbox->pack_start (*hbox, true, true);
361 new_user_page_index = append_page (*vbox);
362 set_page_type (*vbox, ASSISTANT_PAGE_INTRO);
363 set_page_title (*vbox, string_compose (_("Welcome to %1"), PROGRAM_NAME));
364 set_page_header_image (*vbox, icon_pixbuf);
365 set_page_complete (*vbox, true);
369 ArdourStartup::default_dir_changed ()
371 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
372 // make new session folder chooser point to the new default
373 new_folder_chooser.set_current_folder (Config->get_default_session_parent_dir());
378 ArdourStartup::config_changed ()
380 config_modified = true;
384 ArdourStartup::setup_first_time_config_page ()
386 default_dir_chooser = manage (new FileChooserButton (string_compose (_("Default folder for %1 sessions"), PROGRAM_NAME),
387 FILE_CHOOSER_ACTION_SELECT_FOLDER));
388 Gtk::Label* txt = manage (new Label);
389 HBox* hbox = manage (new HBox);
390 VBox* vbox = manage (new VBox);
392 txt->set_markup (string_compose (_("\
393 Each project that you work on with %1 has its own folder.\n\
394 These can require a lot of disk space if you are recording audio.\n\
396 Where would you like new %1 sessions to be stored by default?\n\n\
397 <i>(You can put new sessions anywhere, this is just a default)</i>"), PROGRAM_NAME));
398 txt->set_alignment (0.0, 0.0);
400 vbox->set_spacing (18);
401 vbox->set_border_width (24);
403 hbox->pack_start (*default_dir_chooser, false, true, 8);
404 vbox->pack_start (*txt, false, false);
405 vbox->pack_start (*hbox, false, true);
407 default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
408 default_dir_chooser->signal_current_folder_changed().connect (sigc::mem_fun (*this, &ArdourStartup::default_dir_changed));
409 default_dir_chooser->show ();
413 default_folder_page_index = append_page (*vbox);
414 set_page_title (*vbox, _("Default folder for new sessions"));
415 set_page_header_image (*vbox, icon_pixbuf);
416 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
418 /* user can just skip all these settings if they want to */
420 set_page_complete (*vbox, true);
424 ArdourStartup::setup_monitoring_choice_page ()
426 mon_vbox.set_spacing (18);
427 mon_vbox.set_border_width (24);
429 HBox* hbox = manage (new HBox);
430 VBox* vbox = manage (new VBox);
431 /* first button will be on by default */
432 RadioButton::Group g (monitor_via_ardour_button.get_group());
433 monitor_via_hardware_button.set_group (g);
435 monitor_label.set_markup(_("\
436 While recording instruments or vocals, you probably want to listen to the\n\
437 signal as well as record it. This is called \"monitoring\". There are\n\
438 different ways to do this depending on the equipment you have and the\n\
439 configuration of that equipment. The two most common are presented here.\n\
440 Please choose whichever one is right for your setup.\n\n\
441 <i>(You can change this preference at any time, via the Preferences dialog)</i>\n\n\
442 <i>If you do not understand what this is about, just accept the default.</i>"));
443 monitor_label.set_alignment (0.0, 0.0);
445 vbox->set_spacing (6);
447 vbox->pack_start (monitor_via_hardware_button, false, true);
448 vbox->pack_start (monitor_via_ardour_button, false, true);
449 hbox->pack_start (*vbox, true, true, 8);
450 mon_vbox.pack_start (monitor_label, false, false);
451 mon_vbox.pack_start (*hbox, false, false);
453 mon_vbox.show_all ();
455 monitoring_page_index = append_page (mon_vbox);
456 set_page_title (mon_vbox, _("Monitoring Choices"));
457 set_page_header_image (mon_vbox, icon_pixbuf);
459 /* user could just click on "Forward" if default
463 set_page_complete (mon_vbox, true);
467 ArdourStartup::setup_monitor_section_choice_page ()
469 mon_sec_vbox.set_spacing (18);
470 mon_sec_vbox.set_border_width (24);
472 HBox* hbox = manage (new HBox);
473 VBox* main_vbox = manage (new VBox);
475 Label* l = manage (new Label);
477 main_vbox->set_spacing (32);
479 no_monitor_section_button.set_label (_("Use a Master bus directly"));
480 l->set_alignment (0.0, 1.0);
481 l->set_markup(_("Connect the Master bus directly to your hardware outputs. This is preferable for simple usage."));
483 vbox = manage (new VBox);
484 vbox->set_spacing (6);
485 vbox->pack_start (no_monitor_section_button, false, true);
486 vbox->pack_start (*l, false, true);
488 main_vbox->pack_start (*vbox, false, false);
490 use_monitor_section_button.set_label (_("Use an additional Monitor bus"));
491 l = manage (new Label);
492 l->set_alignment (0.0, 1.0);
493 l->set_text (_("Use a Monitor bus between Master bus and hardware outputs for \n\
494 greater control in monitoring without affecting the mix."));
496 vbox = manage (new VBox);
497 vbox->set_spacing (6);
498 vbox->pack_start (use_monitor_section_button, false, true);
499 vbox->pack_start (*l, false, true);
501 main_vbox->pack_start (*vbox, false, false);
503 RadioButton::Group g (use_monitor_section_button.get_group());
504 no_monitor_section_button.set_group (g);
506 if (Config->get_use_monitor_bus()) {
507 use_monitor_section_button.set_active (true);
509 no_monitor_section_button.set_active (true);
512 use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
513 no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
515 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\
516 <i>If you do not understand what this is about, just accept the default.</i>"));
517 monitor_section_label.set_alignment (0.0, 0.0);
519 hbox->pack_start (*main_vbox, true, true, 8);
520 mon_sec_vbox.pack_start (*hbox, false, false);
521 mon_sec_vbox.pack_start (monitor_section_label, false, false);
523 mon_sec_vbox.show_all ();
525 monitor_section_page_index = append_page (mon_sec_vbox);
526 set_page_title (mon_sec_vbox, _("Monitor Section"));
527 set_page_header_image (mon_sec_vbox, icon_pixbuf);
529 /* user could just click on "Forward" if default
533 set_page_complete (mon_sec_vbox, true);
537 ArdourStartup::setup_initial_choice_page ()
539 ic_vbox.set_spacing (6);
540 ic_vbox.set_border_width (24);
542 RadioButton::Group g (ic_new_session_button.get_group());
543 ic_existing_session_button.set_group (g);
545 HBox* centering_hbox = manage (new HBox);
546 VBox* centering_vbox = manage (new VBox);
548 centering_vbox->set_spacing (6);
550 centering_vbox->pack_start (ic_new_session_button, false, true);
551 centering_vbox->pack_start (ic_existing_session_button, false, true);
553 if (ARDOUR_UI::instance()->announce_string() != "" ) {
555 Gtk::Frame *info_frame = manage(new Gtk::Frame);
556 info_frame->set_shadow_type(SHADOW_ETCHED_OUT);
557 centering_vbox->pack_start (*info_frame, false, false, 20);
559 Box *info_box = manage (new VBox);
560 info_box->set_border_width (12);
561 info_box->set_spacing (6);
562 info_box->set_name("mixbus_info_box");
564 info_box->pack_start (info_scroller_label, false, false);
566 info_frame->add (*info_box);
567 info_frame->show_all();
569 info_scroller_count = 0;
570 info_scroller_connection = Glib::signal_timeout().connect (mem_fun(*this, &ArdourStartup::info_scroller_update), 50);
572 Gtk::Button *updates_button = manage (new Gtk::Button (_("Check the website for more...")));
574 updates_button->signal_clicked().connect (mem_fun(*this, &ArdourStartup::updates_button_clicked) );
575 ARDOUR_UI::instance()->tooltips().set_tip (*updates_button, _("Click to open the program website in your web browser"));
577 info_box->pack_start (*updates_button, false, false);
580 ic_new_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
581 ic_new_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
583 ic_existing_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
584 ic_existing_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
586 centering_hbox->pack_start (*centering_vbox, true, true);
588 ic_vbox.pack_start (*centering_hbox, true, true);
592 initial_choice_index = append_page (ic_vbox);
593 set_page_title (ic_vbox, string_compose("%1 %2", PROGRAM_NAME, VERSIONSTRING));
594 set_page_header_image (ic_vbox, icon_pixbuf);
596 /* user could just click on "Forward" if default
600 set_page_complete (ic_vbox, true);
604 ArdourStartup::initial_button_clicked (GdkEventButton* ev)
606 if (ev->type == GDK_2BUTTON_PRESS && session_page_index != -1) {
607 set_current_page(session_page_index);
614 ArdourStartup::initial_button_activated ()
616 if (session_page_index != -1) {
617 set_current_page(session_page_index);
622 ArdourStartup::setup_session_page ()
624 session_vbox.set_border_width (24);
626 session_vbox.pack_start (session_hbox, true, true);
627 session_vbox.show_all ();
629 session_page_index = append_page (session_vbox);
630 /* initial setting */
631 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
635 ArdourStartup::setup_final_page ()
637 final_page.set_text (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
639 final_page_index = append_page (final_page);
640 set_page_complete (final_page, true);
641 set_page_header_image (final_page, icon_pixbuf);
642 set_page_type (final_page, ASSISTANT_PAGE_CONFIRM);
646 ArdourStartup::on_cancel ()
648 _response = RESPONSE_CANCEL;
653 ArdourStartup::on_delete_event (GdkEventAny*)
655 _response = RESPONSE_CLOSE;
661 ArdourStartup::on_apply ()
664 if (engine_dialog->setup_engine (true)) {
665 set_current_page (audio_page_index);
670 if (config_modified) {
672 if (default_dir_chooser) {
673 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
676 if (monitor_via_hardware_button.get_active()) {
677 Config->set_monitoring_model (ExternalMonitoring);
678 } else if (monitor_via_ardour_button.get_active()) {
679 Config->set_monitoring_model (SoftwareMonitoring);
682 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
684 Config->save_state ();
689 /* "touch" the been-here-before path now we've successfully
690 made it through the first time setup (at least)
692 ofstream fout (been_here_before_path().c_str());
696 _response = RESPONSE_OK;
701 ArdourStartup::on_prepare (Gtk::Widget* page)
703 if (page == &session_vbox) {
705 if (ic_new_session_button.get_active()) {
706 /* new session requested */
707 setup_new_session_page ();
709 /* existing session requested */
710 setup_existing_session_page ();
714 /* HACK HACK HACK ... change the "Apply" button label
718 Gtk::Widget* tl = session_vbox.get_toplevel();
720 if ((win = dynamic_cast<Gtk::Window*>(tl)) != 0) {
721 /* ::get_default_widget() is not wrapped in gtkmm */
722 Gtk::Widget* def = wrap (gtk_window_get_default_widget (win->gobj()));
724 if ((button = dynamic_cast<Gtk::Button*>(def)) != 0) {
725 if (more_new_session_options_button.get_active()) {
726 button->set_label (_("Forward"));
728 button->set_label (_("Open"));
736 ArdourStartup::populate_session_templates ()
738 vector<TemplateInfo> templates;
740 find_session_templates (templates);
742 template_model->clear ();
744 for (vector<TemplateInfo>::iterator x = templates.begin(); x != templates.end(); ++x) {
747 row = *(template_model->append ());
749 row[session_template_columns.name] = (*x).name;
750 row[session_template_columns.path] = (*x).path;
755 ArdourStartup::setup_new_session_page ()
757 if (!session_hbox.get_children().empty()) {
758 session_hbox.remove (**session_hbox.get_children().begin());
761 session_new_vbox.set_spacing (18);
763 if (session_new_vbox.get_children().empty()) {
764 VBox *vbox1 = manage (new VBox);
765 HBox* hbox1 = manage (new HBox);
766 Label* label1 = manage (new Label);
768 vbox1->set_spacing (6);
770 hbox1->set_spacing (6);
771 hbox1->pack_start (*label1, false, false);
772 hbox1->pack_start (new_name_entry, true, true);
774 label1->set_text (_("Session name:"));
777 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
778 new_name_entry.set_text (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
779 /* name provided - they can move right along */
780 set_page_complete (session_vbox, true);
783 new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_changed));
784 new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &ArdourStartup::move_along_now));
786 vbox1->pack_start (*hbox1, true, true);
790 HBox* hbox2 = manage (new HBox);
791 Label* label2 = manage (new Label);
793 hbox2->set_spacing (6);
794 hbox2->pack_start (*label2, false, false);
795 hbox2->pack_start (new_folder_chooser, true, true);
797 label2->set_text (_("Create session folder in:"));
799 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
800 new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
801 } else if (ARDOUR_UI::instance()->session_loaded) {
802 // point the new session file chooser at the parent directory of the current session
803 string session_parent_dir = Glib::path_get_dirname(ARDOUR_UI::instance()->the_session()->path());
804 string::size_type last_dir_sep = session_parent_dir.rfind(G_DIR_SEPARATOR);
805 session_parent_dir = session_parent_dir.substr(0, last_dir_sep);
806 new_folder_chooser.set_current_folder (session_parent_dir);
807 string default_session_folder = poor_mans_glob (Config->get_default_session_parent_dir());
810 /* add_shortcut_folder throws an exception if the folder being added already has a shortcut */
811 new_folder_chooser.add_shortcut_folder (default_session_folder);
813 catch (Glib::Error & e) {
814 std::cerr << "new_folder_chooser.add_shortcut_folder (" << default_session_folder << ") threw Glib::Error " << e.what() << std::endl;
817 new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
819 new_folder_chooser.show ();
820 new_folder_chooser.set_title (_("Select folder for session"));
823 new_folder_chooser.add_shortcut_folder ("/Volumes");
826 vbox1->pack_start (*hbox2, false, false);
828 session_new_vbox.pack_start (*vbox1, false, false);
832 VBox *vbox2 = manage (new VBox);
833 HBox* hbox3 = manage (new HBox);
834 Label* label3 = manage (new Label);
835 template_model = ListStore::create (session_template_columns);
836 populate_session_templates ();
838 vbox2->set_spacing (6);
840 label3->set_markup (_("<b>Options</b>"));
841 label3->set_alignment (0.0, 0.0);
843 vbox2->pack_start (*label3, false, true);
845 VBox *vbox3 = manage (new VBox);
847 vbox3->set_spacing (6);
849 if (!template_model->children().empty()) {
851 HBox* hbox4a = manage (new HBox);
852 use_template_button.set_label (_("Use this template"));
854 TreeModel::Row row = *template_model->prepend ();
855 row[session_template_columns.name] = (_("no template"));
856 row[session_template_columns.path] = string();
858 hbox4a->set_spacing (6);
859 hbox4a->pack_start (use_template_button, false, false);
860 hbox4a->pack_start (template_chooser, true, true);
862 template_chooser.set_model (template_model);
864 Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
865 text_renderer->property_editable() = false;
867 template_chooser.pack_start (*text_renderer);
868 template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
869 template_chooser.set_active (0);
871 use_template_button.show();
872 template_chooser.show ();
874 vbox3->pack_start (*hbox4a, false, false);
880 session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
882 HBox* hbox4b = manage (new HBox);
883 use_session_as_template_button.set_label (_("Use an existing session as a template:"));
885 hbox4b->set_spacing (6);
886 hbox4b->pack_start (use_session_as_template_button, false, false);
887 hbox4b->pack_start (session_template_chooser, true, true);
889 use_session_as_template_button.show ();
890 session_template_chooser.show ();
892 Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
893 session_filter->add_pattern (X_("*.ardour"));
894 session_template_chooser.set_filter (*session_filter);
895 session_template_chooser.set_title (_("Select template"));
897 vbox3->pack_start (*hbox4b, false, false);
902 HBox* hbox5 = manage (new HBox);
904 hbox5->set_spacing (6);
905 hbox5->pack_start (more_new_session_options_button, false, false);
907 more_new_session_options_button.show ();
908 more_new_session_options_button.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::more_new_session_options_button_clicked));
910 vbox3->pack_start (*hbox5, false, false);
911 hbox3->pack_start (*vbox3, true, true, 8);
912 vbox2->pack_start (*hbox3, false, false);
916 session_new_vbox.pack_start (*vbox2, false, false);
919 session_new_vbox.show_all ();
920 session_hbox.pack_start (session_new_vbox, true, true);
921 set_page_title (session_vbox, _("New Session"));
922 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
924 if (more_new_session_options_button.get_active()) {
925 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
927 session_hbox.show_all();
931 ArdourStartup::new_name_changed ()
933 if (!new_name_entry.get_text().empty()) {
934 set_page_complete (session_vbox, true);
936 set_page_complete (session_vbox, false);
941 ArdourStartup::redisplay_recent_sessions ()
943 std::vector<std::string> session_directories;
944 RecentSessionsSorter cmp;
946 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
947 recent_session_model->clear ();
949 ARDOUR::RecentSessions rs;
950 ARDOUR::read_recent_sessions (rs);
953 recent_session_display.set_model (recent_session_model);
957 // sort them alphabetically
958 sort (rs.begin(), rs.end(), cmp);
960 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
961 session_directories.push_back ((*i).second);
964 int session_snapshot_count = 0;
966 for (vector<std::string>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
968 std::vector<std::string> state_file_paths;
970 // now get available states for this session
972 get_state_files_in_directory (*i, state_file_paths);
974 vector<string*>* states;
975 vector<const gchar*> item;
976 string fullpath = *i;
978 /* remove any trailing / */
980 if (fullpath[fullpath.length()-1] == '/') {
981 fullpath = fullpath.substr (0, fullpath.length()-1);
984 /* check whether session still exists */
985 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
986 /* session doesn't exist */
990 /* now get available states for this session */
992 if ((states = Session::possible_states (fullpath)) == 0) {
997 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
999 Gtk::TreeModel::Row row = *(recent_session_model->append());
1001 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
1002 row[recent_session_columns.fullpath] = fullpath;
1003 row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
1005 ++session_snapshot_count;
1007 if (state_file_names.size() > 1) {
1011 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
1012 i2 != state_file_names.end(); ++i2) {
1014 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
1016 child_row[recent_session_columns.visible_name] = *i2;
1017 child_row[recent_session_columns.fullpath] = fullpath;
1018 child_row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
1019 ++session_snapshot_count;
1024 recent_session_display.set_tooltip_column(1); // recent_session_columns.tip
1025 recent_session_display.set_model (recent_session_model);
1026 return session_snapshot_count;
1027 // return rs.size();
1031 ArdourStartup::recent_session_row_selected ()
1033 if (recent_session_display.get_selection()->count_selected_rows() > 0) {
1034 set_page_complete (session_vbox, true);
1036 set_page_complete (session_vbox, false);
1041 ArdourStartup::setup_existing_session_page ()
1043 recent_session_model = TreeStore::create (recent_session_columns);
1044 redisplay_recent_sessions ();
1046 if (!session_hbox.get_children().empty()) {
1047 session_hbox.remove (**session_hbox.get_children().begin());
1050 if (session_existing_vbox.get_children().empty()) {
1052 recent_session_display.set_model (recent_session_model);
1053 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1054 recent_session_display.set_headers_visible (false);
1055 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
1057 recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::recent_session_row_selected));
1059 recent_scroller.add (recent_session_display);
1060 recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1061 recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
1063 recent_session_display.show();
1065 recent_scroller.show();
1066 int cnt = redisplay_recent_sessions ();
1067 recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ArdourStartup::recent_row_activated));
1070 recent_scroller.set_size_request (-1, 300);
1073 session_existing_vbox.set_spacing (8);
1074 session_existing_vbox.pack_start (recent_scroller, true, true);
1076 existing_session_chooser.set_title (_("Select session file"));
1077 existing_session_chooser.signal_file_set().connect (sigc::mem_fun (*this, &ArdourStartup::existing_session_selected));
1078 existing_session_chooser.set_current_folder(poor_mans_glob (Config->get_default_session_parent_dir()));
1080 FileFilter session_filter;
1081 session_filter.add_pattern ("*.ardour");
1082 session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
1083 existing_session_chooser.add_filter (session_filter);
1084 existing_session_chooser.set_filter (session_filter);
1087 existing_session_chooser.add_shortcut_folder ("/Volumes");
1090 HBox* hbox = manage (new HBox);
1091 hbox->set_spacing (4);
1092 hbox->pack_start (*manage (new Label (_("Browse:"))), PACK_SHRINK);
1093 hbox->pack_start (existing_session_chooser);
1094 session_existing_vbox.pack_start (*hbox, false, false);
1098 session_existing_vbox.show_all ();
1099 session_hbox.pack_start (session_existing_vbox, true, true);
1101 set_page_title (session_vbox, _("Select a session"));
1102 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1103 session_hbox.show_all();
1107 ArdourStartup::more_new_session_options_button_clicked ()
1109 if (more_new_session_options_button.get_active()) {
1110 more_options_vbox.show_all ();
1111 set_page_type (more_options_vbox, ASSISTANT_PAGE_CONFIRM);
1112 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
1114 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1115 more_options_vbox.hide ();
1120 ArdourStartup::setup_more_options_page ()
1122 more_options_vbox.set_border_width (24);
1124 _output_limit_count.set_adjustment (_output_limit_count_adj);
1125 _input_limit_count.set_adjustment (_input_limit_count_adj);
1126 _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
1128 chan_count_label_1.set_text (_("channels"));
1129 chan_count_label_3.set_text (_("channels"));
1130 chan_count_label_4.set_text (_("channels"));
1132 chan_count_label_1.set_alignment(0,0.5);
1133 chan_count_label_1.set_padding(0,0);
1134 chan_count_label_1.set_line_wrap(false);
1136 chan_count_label_3.set_alignment(0,0.5);
1137 chan_count_label_3.set_padding(0,0);
1138 chan_count_label_3.set_line_wrap(false);
1140 chan_count_label_4.set_alignment(0,0.5);
1141 chan_count_label_4.set_padding(0,0);
1142 chan_count_label_4.set_line_wrap(false);
1144 bus_label.set_markup (_("<b>Busses</b>"));
1145 input_label.set_markup (_("<b>Inputs</b>"));
1146 output_label.set_markup (_("<b>Outputs</b>"));
1148 _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
1149 _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1150 _master_bus_channel_count.set_numeric(true);
1151 _master_bus_channel_count.set_digits(0);
1152 _master_bus_channel_count.set_wrap(false);
1154 _create_master_bus.set_label (_("Create master bus"));
1155 _create_master_bus.set_flags(Gtk::CAN_FOCUS);
1156 _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
1157 _create_master_bus.set_mode(true);
1158 _create_master_bus.set_active(true);
1159 _create_master_bus.set_border_width(0);
1161 advanced_table.set_row_spacings(0);
1162 advanced_table.set_col_spacings(0);
1164 _connect_inputs.set_label (_("Automatically connect to physical inputs"));
1165 _connect_inputs.set_flags(Gtk::CAN_FOCUS);
1166 _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
1167 _connect_inputs.set_mode(true);
1168 _connect_inputs.set_active(Config->get_input_auto_connect() != ManualConnect);
1169 _connect_inputs.set_border_width(0);
1171 _limit_input_ports.set_label (_("Use only"));
1172 _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
1173 _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
1174 _limit_input_ports.set_mode(true);
1175 _limit_input_ports.set_sensitive(true);
1176 _limit_input_ports.set_border_width(0);
1178 _input_limit_count.set_flags(Gtk::CAN_FOCUS);
1179 _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1180 _input_limit_count.set_numeric(true);
1181 _input_limit_count.set_digits(0);
1182 _input_limit_count.set_wrap(false);
1183 _input_limit_count.set_sensitive(false);
1185 bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
1187 bus_label.set_alignment(0, 0.5);
1188 bus_label.set_padding(0,0);
1189 bus_label.set_line_wrap(false);
1190 bus_label.set_selectable(false);
1191 bus_label.set_use_markup(true);
1192 bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
1193 bus_frame.set_label_align(0,0.5);
1194 bus_frame.add(bus_hbox);
1195 bus_frame.set_label_widget(bus_label);
1197 bus_table.set_row_spacings (0);
1198 bus_table.set_col_spacings (0);
1199 bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1200 bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1201 bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
1203 input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
1204 input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
1205 input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
1206 input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
1207 input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
1208 input_table.set_row_spacings(0);
1209 input_table.set_col_spacings(0);
1210 input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
1212 input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
1214 input_label.set_alignment(0, 0.5);
1215 input_label.set_padding(0,0);
1216 input_label.set_line_wrap(false);
1217 input_label.set_selectable(false);
1218 input_label.set_use_markup(true);
1219 input_frame.set_shadow_type(Gtk::SHADOW_NONE);
1220 input_frame.set_label_align(0,0.5);
1221 input_frame.add(input_hbox);
1222 input_frame.set_label_widget(input_label);
1224 _connect_outputs.set_label (_("Automatically connect outputs"));
1225 _connect_outputs.set_flags(Gtk::CAN_FOCUS);
1226 _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
1227 _connect_outputs.set_mode(true);
1228 _connect_outputs.set_active(Config->get_output_auto_connect() != ManualConnect);
1229 _connect_outputs.set_border_width(0);
1230 _limit_output_ports.set_label (_("Use only"));
1231 _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
1232 _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
1233 _limit_output_ports.set_mode(true);
1234 _limit_output_ports.set_sensitive(true);
1235 _limit_output_ports.set_border_width(0);
1236 _output_limit_count.set_flags(Gtk::CAN_FOCUS);
1237 _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1238 _output_limit_count.set_numeric(false);
1239 _output_limit_count.set_digits(0);
1240 _output_limit_count.set_wrap(false);
1241 _output_limit_count.set_sensitive(false);
1242 output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
1243 output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
1244 output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
1246 _connect_outputs_to_master.set_label (_("... to master bus"));
1247 _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
1248 _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
1249 _connect_outputs_to_master.set_mode(true);
1250 _connect_outputs_to_master.set_active(Config->get_output_auto_connect() == AutoConnectMaster);
1251 _connect_outputs_to_master.set_border_width(0);
1253 _connect_outputs_to_master.set_group (connect_outputs_group);
1254 _connect_outputs_to_physical.set_group (connect_outputs_group);
1256 _connect_outputs_to_physical.set_label (_("... to physical outputs"));
1257 _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
1258 _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
1259 _connect_outputs_to_physical.set_mode(true);
1260 _connect_outputs_to_physical.set_active(Config->get_output_auto_connect() == AutoConnectPhysical);
1261 _connect_outputs_to_physical.set_border_width(0);
1263 output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
1264 output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
1265 output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
1266 output_vbox.set_border_width(6);
1268 output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
1270 output_vbox.pack_start(output_conn_vbox);
1271 output_vbox.pack_start(output_port_vbox);
1273 output_label.set_alignment(0, 0.5);
1274 output_label.set_padding(0,0);
1275 output_label.set_line_wrap(false);
1276 output_label.set_selectable(false);
1277 output_label.set_use_markup(true);
1278 output_frame.set_shadow_type(Gtk::SHADOW_NONE);
1279 output_frame.set_label_align(0,0.5);
1281 output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
1283 output_frame.add(output_hbox);
1284 output_frame.set_label_widget(output_label);
1286 more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
1287 more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
1288 more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
1289 more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
1293 _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
1294 _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
1295 _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
1296 _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
1297 _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
1299 /* note that more_options_vbox is "visible" by default even
1300 * though it may not be displayed to the user, this is so the dialog
1303 more_options_vbox.show_all ();
1305 session_options_page_index = append_page (more_options_vbox);
1306 set_page_title (more_options_vbox, _("Advanced Session Options"));
1307 set_page_complete (more_options_vbox, true);
1311 ArdourStartup::create_master_bus() const
1313 return _create_master_bus.get_active();
1317 ArdourStartup::master_channel_count() const
1319 return _master_bus_channel_count.get_value_as_int();
1323 ArdourStartup::connect_inputs() const
1325 return _connect_inputs.get_active();
1329 ArdourStartup::limit_inputs_used_for_connection() const
1331 return _limit_input_ports.get_active();
1335 ArdourStartup::input_limit_count() const
1337 return _input_limit_count.get_value_as_int();
1341 ArdourStartup::connect_outputs() const
1343 return _connect_outputs.get_active();
1347 ArdourStartup::limit_outputs_used_for_connection() const
1349 return _limit_output_ports.get_active();
1353 ArdourStartup::output_limit_count() const
1355 return _output_limit_count.get_value_as_int();
1359 ArdourStartup::connect_outs_to_master() const
1361 return _connect_outputs_to_master.get_active();
1365 ArdourStartup::connect_outs_to_physical() const
1367 return _connect_outputs_to_physical.get_active();
1371 ArdourStartup::connect_inputs_clicked ()
1373 _limit_input_ports.set_sensitive(_connect_inputs.get_active());
1375 if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
1376 _input_limit_count.set_sensitive(true);
1378 _input_limit_count.set_sensitive(false);
1383 ArdourStartup::connect_outputs_clicked ()
1385 bool const co = _connect_outputs.get_active ();
1386 _limit_output_ports.set_sensitive(co);
1387 _connect_outputs_to_master.set_sensitive(co);
1388 _connect_outputs_to_physical.set_sensitive(co);
1390 if (co && _limit_output_ports.get_active()) {
1391 _output_limit_count.set_sensitive(true);
1393 _output_limit_count.set_sensitive(false);
1398 ArdourStartup::limit_inputs_clicked ()
1400 _input_limit_count.set_sensitive(_limit_input_ports.get_active());
1404 ArdourStartup::limit_outputs_clicked ()
1406 _output_limit_count.set_sensitive(_limit_output_ports.get_active());
1410 ArdourStartup::master_bus_button_clicked ()
1412 bool const yn = _create_master_bus.get_active();
1414 _master_bus_channel_count.set_sensitive(yn);
1415 _connect_outputs_to_master.set_sensitive(yn);
1419 ArdourStartup::move_along_now ()
1421 gint cur = get_current_page ();
1423 if (cur == session_page_index) {
1424 if (more_new_session_options_button.get_active()) {
1425 set_current_page (session_options_page_index);
1433 ArdourStartup::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
1435 set_page_complete (session_vbox, true);
1440 ArdourStartup::existing_session_selected ()
1442 _existing_session_chooser_used = true;
1444 set_page_complete (session_vbox, true);
1449 ArdourStartup::been_here_before_path () const
1451 // XXXX use more specific version so we can catch upgrades
1452 return Glib::build_filename (user_config_directory (), ".a3");
1456 ArdourStartup::updates_button_clicked ()
1458 //now open a browser window so user can see more
1459 PBD::open_uri (Config->get_updates_url());
1463 ArdourStartup::info_scroller_update()
1465 info_scroller_count++;
1468 snprintf (buf, std::min(info_scroller_count,sizeof(buf)-1), "%s", ARDOUR_UI::instance()->announce_string().c_str() );
1469 buf[info_scroller_count] = 0;
1470 info_scroller_label.set_text (buf);
1471 info_scroller_label.show();
1473 if (info_scroller_count > ARDOUR_UI::instance()->announce_string().length()) {
1474 info_scroller_connection.disconnect();