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 cerr << "Setting defaultDIR session dir to [" << Config->get_default_session_parent_dir() << "]\n";
409 default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
410 default_dir_chooser->signal_current_folder_changed().connect (sigc::mem_fun (*this, &ArdourStartup::default_dir_changed));
411 default_dir_chooser->show ();
415 default_folder_page_index = append_page (*vbox);
416 set_page_title (*vbox, _("Default folder for new sessions"));
417 set_page_header_image (*vbox, icon_pixbuf);
418 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
420 /* user can just skip all these settings if they want to */
422 set_page_complete (*vbox, true);
426 ArdourStartup::setup_monitoring_choice_page ()
428 mon_vbox.set_spacing (18);
429 mon_vbox.set_border_width (24);
431 HBox* hbox = manage (new HBox);
432 VBox* vbox = manage (new VBox);
433 /* first button will be on by default */
434 RadioButton::Group g (monitor_via_ardour_button.get_group());
435 monitor_via_hardware_button.set_group (g);
437 monitor_label.set_markup(_("\
438 While recording instruments or vocals, you probably want to listen to the\n\
439 signal as well as record it. This is called \"monitoring\". There are\n\
440 different ways to do this depending on the equipment you have and the\n\
441 configuration of that equipment. The two most common are presented here.\n\
442 Please choose whichever one is right for your setup.\n\n\
443 <i>(You can change this preference at any time, via the Preferences dialog)</i>\n\n\
444 <i>If you do not understand what this is about, just accept the default.</i>"));
445 monitor_label.set_alignment (0.0, 0.0);
447 vbox->set_spacing (6);
449 vbox->pack_start (monitor_via_hardware_button, false, true);
450 vbox->pack_start (monitor_via_ardour_button, false, true);
451 hbox->pack_start (*vbox, true, true, 8);
452 mon_vbox.pack_start (monitor_label, false, false);
453 mon_vbox.pack_start (*hbox, false, false);
455 mon_vbox.show_all ();
457 monitoring_page_index = append_page (mon_vbox);
458 set_page_title (mon_vbox, _("Monitoring Choices"));
459 set_page_header_image (mon_vbox, icon_pixbuf);
461 /* user could just click on "Forward" if default
465 set_page_complete (mon_vbox, true);
469 ArdourStartup::setup_monitor_section_choice_page ()
471 mon_sec_vbox.set_spacing (18);
472 mon_sec_vbox.set_border_width (24);
474 HBox* hbox = manage (new HBox);
475 VBox* main_vbox = manage (new VBox);
477 Label* l = manage (new Label);
479 main_vbox->set_spacing (32);
481 no_monitor_section_button.set_label (_("Use a Master bus directly"));
482 l->set_alignment (0.0, 1.0);
483 l->set_markup(_("Connect the Master bus directly to your hardware outputs. This is preferable for simple usage."));
485 vbox = manage (new VBox);
486 vbox->set_spacing (6);
487 vbox->pack_start (no_monitor_section_button, false, true);
488 vbox->pack_start (*l, false, true);
490 main_vbox->pack_start (*vbox, false, false);
492 use_monitor_section_button.set_label (_("Use an additional Monitor bus"));
493 l = manage (new Label);
494 l->set_alignment (0.0, 1.0);
495 l->set_text (_("Use a Monitor bus between Master bus and hardware outputs for \n\
496 greater control in monitoring without affecting the mix."));
498 vbox = manage (new VBox);
499 vbox->set_spacing (6);
500 vbox->pack_start (use_monitor_section_button, false, true);
501 vbox->pack_start (*l, false, true);
503 main_vbox->pack_start (*vbox, false, false);
505 RadioButton::Group g (use_monitor_section_button.get_group());
506 no_monitor_section_button.set_group (g);
508 if (Config->get_use_monitor_bus()) {
509 use_monitor_section_button.set_active (true);
511 no_monitor_section_button.set_active (true);
514 use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
515 no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
517 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\
518 <i>If you do not understand what this is about, just accept the default.</i>"));
519 monitor_section_label.set_alignment (0.0, 0.0);
521 hbox->pack_start (*main_vbox, true, true, 8);
522 mon_sec_vbox.pack_start (*hbox, false, false);
523 mon_sec_vbox.pack_start (monitor_section_label, false, false);
525 mon_sec_vbox.show_all ();
527 monitor_section_page_index = append_page (mon_sec_vbox);
528 set_page_title (mon_sec_vbox, _("Monitor Section"));
529 set_page_header_image (mon_sec_vbox, icon_pixbuf);
531 /* user could just click on "Forward" if default
535 set_page_complete (mon_sec_vbox, true);
539 ArdourStartup::setup_initial_choice_page ()
541 ic_vbox.set_spacing (6);
542 ic_vbox.set_border_width (24);
544 RadioButton::Group g (ic_new_session_button.get_group());
545 ic_existing_session_button.set_group (g);
547 HBox* centering_hbox = manage (new HBox);
548 VBox* centering_vbox = manage (new VBox);
550 centering_vbox->set_spacing (6);
552 centering_vbox->pack_start (ic_new_session_button, false, true);
553 centering_vbox->pack_start (ic_existing_session_button, false, true);
555 if (ARDOUR_UI::instance()->announce_string() != "" ) {
557 Gtk::Frame *info_frame = manage(new Gtk::Frame);
558 info_frame->set_shadow_type(SHADOW_ETCHED_OUT);
559 centering_vbox->pack_start (*info_frame, false, false, 20);
561 Box *info_box = manage (new VBox);
562 info_box->set_border_width (12);
563 info_box->set_spacing (6);
564 info_box->set_name("mixbus_info_box");
566 info_box->pack_start (info_scroller_label, false, false);
568 info_frame->add (*info_box);
569 info_frame->show_all();
571 info_scroller_count = 0;
572 info_scroller_connection = Glib::signal_timeout().connect (mem_fun(*this, &ArdourStartup::info_scroller_update), 50);
574 Gtk::Button *updates_button = manage (new Gtk::Button (_("Check the website for more...")));
576 updates_button->signal_clicked().connect (mem_fun(*this, &ArdourStartup::updates_button_clicked) );
577 ARDOUR_UI::instance()->tooltips().set_tip (*updates_button, _("Click to open the program website in your web browser"));
579 info_box->pack_start (*updates_button, false, false);
582 ic_new_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
583 ic_new_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
585 ic_existing_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
586 ic_existing_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
588 centering_hbox->pack_start (*centering_vbox, true, true);
590 ic_vbox.pack_start (*centering_hbox, true, true);
594 initial_choice_index = append_page (ic_vbox);
595 set_page_title (ic_vbox, string_compose("%1 %2", PROGRAM_NAME, VERSIONSTRING));
596 set_page_header_image (ic_vbox, icon_pixbuf);
598 /* user could just click on "Forward" if default
602 set_page_complete (ic_vbox, true);
606 ArdourStartup::initial_button_clicked (GdkEventButton* ev)
608 if (ev->type == GDK_2BUTTON_PRESS && session_page_index != -1) {
609 set_current_page(session_page_index);
616 ArdourStartup::initial_button_activated ()
618 if (session_page_index != -1) {
619 set_current_page(session_page_index);
624 ArdourStartup::setup_session_page ()
626 session_vbox.set_border_width (24);
628 session_vbox.pack_start (session_hbox, true, true);
629 session_vbox.show_all ();
631 session_page_index = append_page (session_vbox);
632 /* initial setting */
633 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
637 ArdourStartup::setup_final_page ()
639 final_page.set_text (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
641 final_page_index = append_page (final_page);
642 set_page_complete (final_page, true);
643 set_page_header_image (final_page, icon_pixbuf);
644 set_page_type (final_page, ASSISTANT_PAGE_CONFIRM);
648 ArdourStartup::on_cancel ()
650 _response = RESPONSE_CANCEL;
655 ArdourStartup::on_delete_event (GdkEventAny*)
657 _response = RESPONSE_CLOSE;
663 ArdourStartup::on_apply ()
665 cerr << "apply, engine = " << engine_dialog << endl;
667 cerr << "Set up engine\n";
668 if (engine_dialog->setup_engine (true)) {
669 set_current_page (audio_page_index);
674 if (config_modified) {
676 if (default_dir_chooser) {
677 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
680 if (monitor_via_hardware_button.get_active()) {
681 Config->set_monitoring_model (ExternalMonitoring);
682 } else if (monitor_via_ardour_button.get_active()) {
683 Config->set_monitoring_model (SoftwareMonitoring);
686 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
688 Config->save_state ();
693 /* "touch" the been-here-before path now we've successfully
694 made it through the first time setup (at least)
696 ofstream fout (been_here_before_path().c_str());
700 _response = RESPONSE_OK;
705 ArdourStartup::on_prepare (Gtk::Widget* page)
707 if (page == &session_vbox) {
709 if (ic_new_session_button.get_active()) {
710 /* new session requested */
711 setup_new_session_page ();
713 /* existing session requested */
714 setup_existing_session_page ();
718 /* HACK HACK HACK ... change the "Apply" button label
722 Gtk::Widget* tl = session_vbox.get_toplevel();
724 if ((win = dynamic_cast<Gtk::Window*>(tl)) != 0) {
725 /* ::get_default_widget() is not wrapped in gtkmm */
726 Gtk::Widget* def = wrap (gtk_window_get_default_widget (win->gobj()));
728 if ((button = dynamic_cast<Gtk::Button*>(def)) != 0) {
729 if (more_new_session_options_button.get_active()) {
730 button->set_label (_("Forward"));
732 button->set_label (_("Open"));
740 ArdourStartup::populate_session_templates ()
742 vector<TemplateInfo> templates;
744 find_session_templates (templates);
746 template_model->clear ();
748 for (vector<TemplateInfo>::iterator x = templates.begin(); x != templates.end(); ++x) {
751 row = *(template_model->append ());
753 row[session_template_columns.name] = (*x).name;
754 row[session_template_columns.path] = (*x).path;
759 ArdourStartup::setup_new_session_page ()
761 if (!session_hbox.get_children().empty()) {
762 session_hbox.remove (**session_hbox.get_children().begin());
765 session_new_vbox.set_spacing (18);
767 if (session_new_vbox.get_children().empty()) {
768 VBox *vbox1 = manage (new VBox);
769 HBox* hbox1 = manage (new HBox);
770 Label* label1 = manage (new Label);
772 vbox1->set_spacing (6);
774 hbox1->set_spacing (6);
775 hbox1->pack_start (*label1, false, false);
776 hbox1->pack_start (new_name_entry, true, true);
778 label1->set_text (_("Session name:"));
781 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
782 new_name_entry.set_text (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
783 /* name provided - they can move right along */
784 set_page_complete (session_vbox, true);
787 new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_changed));
788 new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &ArdourStartup::move_along_now));
790 vbox1->pack_start (*hbox1, true, true);
794 HBox* hbox2 = manage (new HBox);
795 Label* label2 = manage (new Label);
797 hbox2->set_spacing (6);
798 hbox2->pack_start (*label2, false, false);
799 hbox2->pack_start (new_folder_chooser, true, true);
801 label2->set_text (_("Create session folder in:"));
803 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
804 new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
805 } else if (ARDOUR_UI::instance()->session_loaded) {
806 // point the new session file chooser at the parent directory of the current session
807 string session_parent_dir = Glib::path_get_dirname(ARDOUR_UI::instance()->the_session()->path());
808 string::size_type last_dir_sep = session_parent_dir.rfind(G_DIR_SEPARATOR);
809 session_parent_dir = session_parent_dir.substr(0, last_dir_sep);
810 new_folder_chooser.set_current_folder (session_parent_dir);
811 string default_session_folder = poor_mans_glob (Config->get_default_session_parent_dir());
814 /* add_shortcut_folder throws an exception if the folder being added already has a shortcut */
815 new_folder_chooser.add_shortcut_folder (default_session_folder);
817 catch (Glib::Error & e) {
818 std::cerr << "new_folder_chooser.add_shortcut_folder (" << default_session_folder << ") threw Glib::Error " << e.what() << std::endl;
821 new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
823 new_folder_chooser.show ();
824 new_folder_chooser.set_title (_("Select folder for session"));
827 new_folder_chooser.add_shortcut_folder ("/Volumes");
830 vbox1->pack_start (*hbox2, false, false);
832 session_new_vbox.pack_start (*vbox1, false, false);
836 VBox *vbox2 = manage (new VBox);
837 HBox* hbox3 = manage (new HBox);
838 Label* label3 = manage (new Label);
839 template_model = ListStore::create (session_template_columns);
840 populate_session_templates ();
842 vbox2->set_spacing (6);
844 label3->set_markup (_("<b>Options</b>"));
845 label3->set_alignment (0.0, 0.0);
847 vbox2->pack_start (*label3, false, true);
849 VBox *vbox3 = manage (new VBox);
851 vbox3->set_spacing (6);
853 if (!template_model->children().empty()) {
855 HBox* hbox4a = manage (new HBox);
856 use_template_button.set_label (_("Use this template"));
858 TreeModel::Row row = *template_model->prepend ();
859 row[session_template_columns.name] = (_("no template"));
860 row[session_template_columns.path] = string();
862 hbox4a->set_spacing (6);
863 hbox4a->pack_start (use_template_button, false, false);
864 hbox4a->pack_start (template_chooser, true, true);
866 template_chooser.set_model (template_model);
868 Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
869 text_renderer->property_editable() = false;
871 template_chooser.pack_start (*text_renderer);
872 template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
873 template_chooser.set_active (0);
875 use_template_button.show();
876 template_chooser.show ();
878 vbox3->pack_start (*hbox4a, false, false);
884 session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
886 HBox* hbox4b = manage (new HBox);
887 use_session_as_template_button.set_label (_("Use an existing session as a template:"));
889 hbox4b->set_spacing (6);
890 hbox4b->pack_start (use_session_as_template_button, false, false);
891 hbox4b->pack_start (session_template_chooser, true, true);
893 use_session_as_template_button.show ();
894 session_template_chooser.show ();
896 Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
897 session_filter->add_pattern (X_("*.ardour"));
898 session_template_chooser.set_filter (*session_filter);
899 session_template_chooser.set_title (_("Select template"));
901 vbox3->pack_start (*hbox4b, false, false);
906 HBox* hbox5 = manage (new HBox);
908 hbox5->set_spacing (6);
909 hbox5->pack_start (more_new_session_options_button, false, false);
911 more_new_session_options_button.show ();
912 more_new_session_options_button.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::more_new_session_options_button_clicked));
914 vbox3->pack_start (*hbox5, false, false);
915 hbox3->pack_start (*vbox3, true, true, 8);
916 vbox2->pack_start (*hbox3, false, false);
920 session_new_vbox.pack_start (*vbox2, false, false);
923 session_new_vbox.show_all ();
924 session_hbox.pack_start (session_new_vbox, true, true);
925 set_page_title (session_vbox, _("New Session"));
926 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
928 if (more_new_session_options_button.get_active()) {
929 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
931 session_hbox.show_all();
935 ArdourStartup::new_name_changed ()
937 if (!new_name_entry.get_text().empty()) {
938 set_page_complete (session_vbox, true);
940 set_page_complete (session_vbox, false);
945 ArdourStartup::redisplay_recent_sessions ()
947 std::vector<std::string> session_directories;
948 RecentSessionsSorter cmp;
950 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
951 recent_session_model->clear ();
953 ARDOUR::RecentSessions rs;
954 ARDOUR::read_recent_sessions (rs);
957 recent_session_display.set_model (recent_session_model);
961 // sort them alphabetically
962 sort (rs.begin(), rs.end(), cmp);
964 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
965 session_directories.push_back ((*i).second);
968 int session_snapshot_count = 0;
970 for (vector<std::string>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
972 std::vector<std::string> state_file_paths;
974 // now get available states for this session
976 get_state_files_in_directory (*i, state_file_paths);
978 vector<string*>* states;
979 vector<const gchar*> item;
980 string fullpath = *i;
982 /* remove any trailing / */
984 if (fullpath[fullpath.length()-1] == '/') {
985 fullpath = fullpath.substr (0, fullpath.length()-1);
988 /* check whether session still exists */
989 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
990 /* session doesn't exist */
994 /* now get available states for this session */
996 if ((states = Session::possible_states (fullpath)) == 0) {
1001 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
1003 Gtk::TreeModel::Row row = *(recent_session_model->append());
1005 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
1006 row[recent_session_columns.fullpath] = fullpath;
1007 row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
1009 ++session_snapshot_count;
1011 if (state_file_names.size() > 1) {
1015 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
1016 i2 != state_file_names.end(); ++i2) {
1018 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
1020 child_row[recent_session_columns.visible_name] = *i2;
1021 child_row[recent_session_columns.fullpath] = fullpath;
1022 child_row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
1023 ++session_snapshot_count;
1028 recent_session_display.set_tooltip_column(1); // recent_session_columns.tip
1029 recent_session_display.set_model (recent_session_model);
1030 return session_snapshot_count;
1031 // return rs.size();
1035 ArdourStartup::recent_session_row_selected ()
1037 if (recent_session_display.get_selection()->count_selected_rows() > 0) {
1038 set_page_complete (session_vbox, true);
1040 set_page_complete (session_vbox, false);
1045 ArdourStartup::setup_existing_session_page ()
1047 recent_session_model = TreeStore::create (recent_session_columns);
1048 redisplay_recent_sessions ();
1050 if (!session_hbox.get_children().empty()) {
1051 session_hbox.remove (**session_hbox.get_children().begin());
1054 if (session_existing_vbox.get_children().empty()) {
1056 recent_session_display.set_model (recent_session_model);
1057 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1058 recent_session_display.set_headers_visible (false);
1059 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
1061 recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::recent_session_row_selected));
1063 recent_scroller.add (recent_session_display);
1064 recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1065 recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
1067 recent_session_display.show();
1069 recent_scroller.show();
1070 int cnt = redisplay_recent_sessions ();
1071 recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ArdourStartup::recent_row_activated));
1074 recent_scroller.set_size_request (-1, 300);
1077 session_existing_vbox.set_spacing (8);
1078 session_existing_vbox.pack_start (recent_scroller, true, true);
1080 existing_session_chooser.set_title (_("Select session file"));
1081 existing_session_chooser.signal_file_set().connect (sigc::mem_fun (*this, &ArdourStartup::existing_session_selected));
1082 existing_session_chooser.set_current_folder(poor_mans_glob (Config->get_default_session_parent_dir()));
1084 FileFilter session_filter;
1085 session_filter.add_pattern ("*.ardour");
1086 session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
1087 existing_session_chooser.add_filter (session_filter);
1088 existing_session_chooser.set_filter (session_filter);
1091 existing_session_chooser.add_shortcut_folder ("/Volumes");
1094 HBox* hbox = manage (new HBox);
1095 hbox->set_spacing (4);
1096 hbox->pack_start (*manage (new Label (_("Browse:"))), PACK_SHRINK);
1097 hbox->pack_start (existing_session_chooser);
1098 session_existing_vbox.pack_start (*hbox, false, false);
1102 session_existing_vbox.show_all ();
1103 session_hbox.pack_start (session_existing_vbox, true, true);
1105 set_page_title (session_vbox, _("Select a session"));
1106 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1107 session_hbox.show_all();
1111 ArdourStartup::more_new_session_options_button_clicked ()
1113 if (more_new_session_options_button.get_active()) {
1114 more_options_vbox.show_all ();
1115 set_page_type (more_options_vbox, ASSISTANT_PAGE_CONFIRM);
1116 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
1118 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1119 more_options_vbox.hide ();
1124 ArdourStartup::setup_more_options_page ()
1126 more_options_vbox.set_border_width (24);
1128 _output_limit_count.set_adjustment (_output_limit_count_adj);
1129 _input_limit_count.set_adjustment (_input_limit_count_adj);
1130 _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
1132 chan_count_label_1.set_text (_("channels"));
1133 chan_count_label_3.set_text (_("channels"));
1134 chan_count_label_4.set_text (_("channels"));
1136 chan_count_label_1.set_alignment(0,0.5);
1137 chan_count_label_1.set_padding(0,0);
1138 chan_count_label_1.set_line_wrap(false);
1140 chan_count_label_3.set_alignment(0,0.5);
1141 chan_count_label_3.set_padding(0,0);
1142 chan_count_label_3.set_line_wrap(false);
1144 chan_count_label_4.set_alignment(0,0.5);
1145 chan_count_label_4.set_padding(0,0);
1146 chan_count_label_4.set_line_wrap(false);
1148 bus_label.set_markup (_("<b>Busses</b>"));
1149 input_label.set_markup (_("<b>Inputs</b>"));
1150 output_label.set_markup (_("<b>Outputs</b>"));
1152 _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
1153 _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1154 _master_bus_channel_count.set_numeric(true);
1155 _master_bus_channel_count.set_digits(0);
1156 _master_bus_channel_count.set_wrap(false);
1158 _create_master_bus.set_label (_("Create master bus"));
1159 _create_master_bus.set_flags(Gtk::CAN_FOCUS);
1160 _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
1161 _create_master_bus.set_mode(true);
1162 _create_master_bus.set_active(true);
1163 _create_master_bus.set_border_width(0);
1165 advanced_table.set_row_spacings(0);
1166 advanced_table.set_col_spacings(0);
1168 _connect_inputs.set_label (_("Automatically connect to physical inputs"));
1169 _connect_inputs.set_flags(Gtk::CAN_FOCUS);
1170 _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
1171 _connect_inputs.set_mode(true);
1172 _connect_inputs.set_active(Config->get_input_auto_connect() != ManualConnect);
1173 _connect_inputs.set_border_width(0);
1175 _limit_input_ports.set_label (_("Use only"));
1176 _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
1177 _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
1178 _limit_input_ports.set_mode(true);
1179 _limit_input_ports.set_sensitive(true);
1180 _limit_input_ports.set_border_width(0);
1182 _input_limit_count.set_flags(Gtk::CAN_FOCUS);
1183 _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1184 _input_limit_count.set_numeric(true);
1185 _input_limit_count.set_digits(0);
1186 _input_limit_count.set_wrap(false);
1187 _input_limit_count.set_sensitive(false);
1189 bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
1191 bus_label.set_alignment(0, 0.5);
1192 bus_label.set_padding(0,0);
1193 bus_label.set_line_wrap(false);
1194 bus_label.set_selectable(false);
1195 bus_label.set_use_markup(true);
1196 bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
1197 bus_frame.set_label_align(0,0.5);
1198 bus_frame.add(bus_hbox);
1199 bus_frame.set_label_widget(bus_label);
1201 bus_table.set_row_spacings (0);
1202 bus_table.set_col_spacings (0);
1203 bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1204 bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1205 bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
1207 input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
1208 input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
1209 input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
1210 input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
1211 input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
1212 input_table.set_row_spacings(0);
1213 input_table.set_col_spacings(0);
1214 input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
1216 input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
1218 input_label.set_alignment(0, 0.5);
1219 input_label.set_padding(0,0);
1220 input_label.set_line_wrap(false);
1221 input_label.set_selectable(false);
1222 input_label.set_use_markup(true);
1223 input_frame.set_shadow_type(Gtk::SHADOW_NONE);
1224 input_frame.set_label_align(0,0.5);
1225 input_frame.add(input_hbox);
1226 input_frame.set_label_widget(input_label);
1228 _connect_outputs.set_label (_("Automatically connect outputs"));
1229 _connect_outputs.set_flags(Gtk::CAN_FOCUS);
1230 _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
1231 _connect_outputs.set_mode(true);
1232 _connect_outputs.set_active(Config->get_output_auto_connect() != ManualConnect);
1233 _connect_outputs.set_border_width(0);
1234 _limit_output_ports.set_label (_("Use only"));
1235 _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
1236 _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
1237 _limit_output_ports.set_mode(true);
1238 _limit_output_ports.set_sensitive(true);
1239 _limit_output_ports.set_border_width(0);
1240 _output_limit_count.set_flags(Gtk::CAN_FOCUS);
1241 _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1242 _output_limit_count.set_numeric(false);
1243 _output_limit_count.set_digits(0);
1244 _output_limit_count.set_wrap(false);
1245 _output_limit_count.set_sensitive(false);
1246 output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
1247 output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
1248 output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
1250 _connect_outputs_to_master.set_label (_("... to master bus"));
1251 _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
1252 _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
1253 _connect_outputs_to_master.set_mode(true);
1254 _connect_outputs_to_master.set_active(Config->get_output_auto_connect() == AutoConnectMaster);
1255 _connect_outputs_to_master.set_border_width(0);
1257 _connect_outputs_to_master.set_group (connect_outputs_group);
1258 _connect_outputs_to_physical.set_group (connect_outputs_group);
1260 _connect_outputs_to_physical.set_label (_("... to physical outputs"));
1261 _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
1262 _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
1263 _connect_outputs_to_physical.set_mode(true);
1264 _connect_outputs_to_physical.set_active(Config->get_output_auto_connect() == AutoConnectPhysical);
1265 _connect_outputs_to_physical.set_border_width(0);
1267 output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
1268 output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
1269 output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
1270 output_vbox.set_border_width(6);
1272 output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
1274 output_vbox.pack_start(output_conn_vbox);
1275 output_vbox.pack_start(output_port_vbox);
1277 output_label.set_alignment(0, 0.5);
1278 output_label.set_padding(0,0);
1279 output_label.set_line_wrap(false);
1280 output_label.set_selectable(false);
1281 output_label.set_use_markup(true);
1282 output_frame.set_shadow_type(Gtk::SHADOW_NONE);
1283 output_frame.set_label_align(0,0.5);
1285 output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
1287 output_frame.add(output_hbox);
1288 output_frame.set_label_widget(output_label);
1290 more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
1291 more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
1292 more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
1293 more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
1297 _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
1298 _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
1299 _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
1300 _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
1301 _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
1303 /* note that more_options_vbox is "visible" by default even
1304 * though it may not be displayed to the user, this is so the dialog
1307 more_options_vbox.show_all ();
1309 session_options_page_index = append_page (more_options_vbox);
1310 set_page_title (more_options_vbox, _("Advanced Session Options"));
1311 set_page_complete (more_options_vbox, true);
1315 ArdourStartup::create_master_bus() const
1317 return _create_master_bus.get_active();
1321 ArdourStartup::master_channel_count() const
1323 return _master_bus_channel_count.get_value_as_int();
1327 ArdourStartup::connect_inputs() const
1329 return _connect_inputs.get_active();
1333 ArdourStartup::limit_inputs_used_for_connection() const
1335 return _limit_input_ports.get_active();
1339 ArdourStartup::input_limit_count() const
1341 return _input_limit_count.get_value_as_int();
1345 ArdourStartup::connect_outputs() const
1347 return _connect_outputs.get_active();
1351 ArdourStartup::limit_outputs_used_for_connection() const
1353 return _limit_output_ports.get_active();
1357 ArdourStartup::output_limit_count() const
1359 return _output_limit_count.get_value_as_int();
1363 ArdourStartup::connect_outs_to_master() const
1365 return _connect_outputs_to_master.get_active();
1369 ArdourStartup::connect_outs_to_physical() const
1371 return _connect_outputs_to_physical.get_active();
1375 ArdourStartup::connect_inputs_clicked ()
1377 _limit_input_ports.set_sensitive(_connect_inputs.get_active());
1379 if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
1380 _input_limit_count.set_sensitive(true);
1382 _input_limit_count.set_sensitive(false);
1387 ArdourStartup::connect_outputs_clicked ()
1389 bool const co = _connect_outputs.get_active ();
1390 _limit_output_ports.set_sensitive(co);
1391 _connect_outputs_to_master.set_sensitive(co);
1392 _connect_outputs_to_physical.set_sensitive(co);
1394 if (co && _limit_output_ports.get_active()) {
1395 _output_limit_count.set_sensitive(true);
1397 _output_limit_count.set_sensitive(false);
1402 ArdourStartup::limit_inputs_clicked ()
1404 _input_limit_count.set_sensitive(_limit_input_ports.get_active());
1408 ArdourStartup::limit_outputs_clicked ()
1410 _output_limit_count.set_sensitive(_limit_output_ports.get_active());
1414 ArdourStartup::master_bus_button_clicked ()
1416 bool const yn = _create_master_bus.get_active();
1418 _master_bus_channel_count.set_sensitive(yn);
1419 _connect_outputs_to_master.set_sensitive(yn);
1423 ArdourStartup::move_along_now ()
1425 gint cur = get_current_page ();
1427 if (cur == session_page_index) {
1428 if (more_new_session_options_button.get_active()) {
1429 set_current_page (session_options_page_index);
1437 ArdourStartup::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
1439 set_page_complete (session_vbox, true);
1444 ArdourStartup::existing_session_selected ()
1446 _existing_session_chooser_used = true;
1448 set_page_complete (session_vbox, true);
1453 ArdourStartup::been_here_before_path () const
1455 // XXXX use more specific version so we can catch upgrades
1456 return Glib::build_filename (user_config_directory (), ".a3");
1460 ArdourStartup::updates_button_clicked ()
1462 //now open a browser window so user can see more
1463 PBD::open_uri (Config->get_updates_url());
1467 ArdourStartup::info_scroller_update()
1469 info_scroller_count++;
1472 snprintf (buf, std::min(info_scroller_count,sizeof(buf)-1), "%s", ARDOUR_UI::instance()->announce_string().c_str() );
1473 buf[info_scroller_count] = 0;
1474 info_scroller_label.set_text (buf);
1475 info_scroller_label.show();
1477 if (info_scroller_count > ARDOUR_UI::instance()->announce_string().length()) {
1478 info_scroller_connection.disconnect();