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 , monitor_via_hardware_button (string_compose (_("Use an external mixer or the hardware mixer of your audio interface.\n"
74 "%1 will play NO role in monitoring"), PROGRAM_NAME))
75 , monitor_via_ardour_button (string_compose (_("Ask %1 to play back material as it is being recorded"), PROGRAM_NAME))
76 , new_folder_chooser (FILE_CHOOSER_ACTION_SELECT_FOLDER)
77 , more_new_session_options_button (_("Advanced options ..."))
78 , _output_limit_count_adj (1, 0, 100, 1, 10, 0)
79 , _input_limit_count_adj (1, 0, 100, 1, 10, 0)
80 , _master_bus_channel_count_adj (2, 0, 100, 1, 10, 0)
81 , audio_page_index (-1)
82 , new_user_page_index (-1)
83 , default_folder_page_index (-1)
84 , monitoring_page_index (-1)
85 , new_session_page_index (-1)
86 , initial_choice_index (-1)
87 , final_page_index (-1)
88 , session_options_page_index (-1)
89 , _existing_session_chooser_used (false)
91 new_user = !Glib::file_test (been_here_before_path(), Glib::FILE_TEST_EXISTS);
92 need_session_info = (session_name.empty() || require_new);
94 _provided_session_name = session_name;
95 _provided_session_path = session_path;
97 if (need_session_info || new_user) {
99 use_template_button.set_group (session_template_group);
100 use_session_as_template_button.set_group (session_template_group);
102 set_keep_above (true);
103 set_position (WIN_POS_CENTER);
104 set_border_width (12);
106 if ((icon_pixbuf = ::get_icon ("ardour_icon_48px")) == 0) {
107 throw failed_constructor();
110 list<Glib::RefPtr<Gdk::Pixbuf> > window_icons;
111 Glib::RefPtr<Gdk::Pixbuf> icon;
113 if ((icon = ::get_icon ("ardour_icon_16px")) != 0) {
114 window_icons.push_back (icon);
116 if ((icon = ::get_icon ("ardour_icon_22px")) != 0) {
117 window_icons.push_back (icon);
119 if ((icon = ::get_icon ("ardour_icon_32px")) != 0) {
120 window_icons.push_back (icon);
122 if ((icon = ::get_icon ("ardour_icon_48px")) != 0) {
123 window_icons.push_back (icon);
125 if (!window_icons.empty ()) {
126 set_default_icon_list (window_icons);
130 setup_prerelease_page ();
134 setup_new_user_page ();
135 setup_first_time_config_page ();
136 setup_monitoring_choice_page ();
137 setup_monitor_section_choice_page ();
139 setup_new_session_page ();
144 setup_initial_choice_page ();
146 setup_new_session_page ();
149 if (!template_name.empty()) {
150 use_template_button.set_active (false);
151 load_template_override = template_name;
158 ArdourStartup::~ArdourStartup ()
163 ArdourStartup::ready_without_display () const
165 return !new_user && !need_session_info;
169 ArdourStartup::setup_prerelease_page ()
171 VBox* vbox = manage (new VBox);
172 Label* label = manage (new Label);
173 label->set_markup (string_compose (_("<b>Welcome to this BETA release of Ardour %1</b>\n\n\
174 Ardour %1 has been released for Linux but because of the lack of testers,\n\
175 it is still at the beta stage on OS X. So, a few guidelines:\n\
177 1) Please do <b>NOT</b> use this software with the expectation that it is stable or reliable\n\
178 though it may be so, depending on your workflow.\n\
179 2) <b>Please do NOT use the forums at ardour.org to report issues</b>.\n\
180 3) Please <b>DO</b> use the bugtracker at http://tracker.ardour.org/ to report issues\n\
181 making sure to note the product version number as %1-beta.\n\
182 4) Please <b>DO</b> use the ardour-users mailing list to discuss ideas and pass on comments.\n\
183 5) Please <b>DO</b> join us on IRC for real time discussions about ardour3. You\n\
184 can get there directly from Ardour via the Help->Chat menu option.\n\
186 Full information on all the above can be found on the support page at\n\
188 http://ardour.org/support\n\
191 vbox->set_border_width (12);
192 vbox->pack_start (*label, false, false, 12);
196 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
197 set_page_title (*vbox, _("This is a BETA RELEASE"));
198 set_page_complete (*vbox, true);
202 ArdourStartup::use_session_template ()
204 if (!load_template_override.empty()) {
208 if (use_template_button.get_active()) {
209 return template_chooser.get_active_row_number() > 0;
211 return !session_template_chooser.get_filename().empty();
216 ArdourStartup::session_template_name ()
218 if (!load_template_override.empty()) {
219 string the_path (ARDOUR::user_template_directory());
220 return Glib::build_filename (the_path, load_template_override + ARDOUR::template_suffix);
223 if (use_template_button.get_active()) {
224 TreeModel::iterator iter = template_chooser.get_active ();
225 TreeModel::Row row = (*iter);
226 string s = row[session_template_columns.path];
229 return session_template_chooser.get_filename();
235 ArdourStartup::session_name (bool& should_be_new)
237 if (ready_without_display()) {
238 return _provided_session_name;
241 /* Try recent session selection */
243 TreeIter iter = recent_session_display.get_selection()->get_selected();
246 should_be_new = false;
247 return (*iter)[recent_session_columns.visible_name];
250 if (_existing_session_chooser_used) {
251 /* existing session chosen from file chooser */
252 should_be_new = false;
253 return existing_session_chooser.get_filename ();
255 should_be_new = true;
256 string val = new_name_entry.get_text ();
257 strip_whitespace_edges (val);
263 ArdourStartup::session_folder ()
265 if (ready_without_display()) {
266 return _provided_session_path;
269 /* Try recent session selection */
271 TreeIter iter = recent_session_display.get_selection()->get_selected();
274 return (*iter)[recent_session_columns.fullpath];
277 if (_existing_session_chooser_used) {
278 /* existing session chosen from file chooser */
279 return existing_session_chooser.get_current_folder ();
281 std::string legal_session_folder_name = legalize_for_path (new_name_entry.get_text());
282 return Glib::build_filename (new_folder_chooser.get_current_folder(), legal_session_folder_name);
287 ArdourStartup::setup_new_user_page ()
289 Label* foomatic = manage (new Label);
291 foomatic->set_markup (string_compose (_("\
292 <span size=\"larger\">%1 is a digital audio workstation. You can use it to \
293 record, edit and mix multi-track audio. You can produce your \
294 own CDs, mix video soundtracks, or experiment with new \
295 ideas about music and sound. \
297 There are a few things that need to be configured before you start \
298 using the program.</span> \
300 foomatic->set_justify (JUSTIFY_FILL);
301 foomatic->set_line_wrap ();
303 HBox* hbox = manage (new HBox);
304 HBox* vbox = manage (new HBox);
306 vbox->set_border_width (24);
308 hbox->pack_start (*foomatic, true, true);
309 vbox->pack_start (*hbox, true, true);
315 new_user_page_index = append_page (*vbox);
316 set_page_type (*vbox, ASSISTANT_PAGE_INTRO);
317 set_page_title (*vbox, string_compose (_("Welcome to %1"), PROGRAM_NAME));
318 set_page_header_image (*vbox, icon_pixbuf);
319 set_page_complete (*vbox, true);
323 ArdourStartup::default_dir_changed ()
325 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
326 // make new session folder chooser point to the new default
327 new_folder_chooser.set_current_folder (Config->get_default_session_parent_dir());
332 ArdourStartup::config_changed ()
334 config_modified = true;
338 ArdourStartup::setup_first_time_config_page ()
340 default_dir_chooser = manage (new FileChooserButton (string_compose (_("Default folder for %1 sessions"), PROGRAM_NAME),
341 FILE_CHOOSER_ACTION_SELECT_FOLDER));
342 Gtk::Label* txt = manage (new Label);
343 HBox* hbox = manage (new HBox);
344 VBox* vbox = manage (new VBox);
346 txt->set_markup (string_compose (_("\
347 Each project that you work on with %1 has its own folder.\n\
348 These can require a lot of disk space if you are recording audio.\n\
350 Where would you like new %1 sessions to be stored by default?\n\n\
351 <i>(You can put new sessions anywhere, this is just a default)</i>"), PROGRAM_NAME));
352 txt->set_alignment (0.0, 0.0);
354 vbox->set_spacing (18);
355 vbox->set_border_width (24);
357 hbox->pack_start (*default_dir_chooser, false, true, 8);
358 vbox->pack_start (*txt, false, false);
359 vbox->pack_start (*hbox, false, true);
361 default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
362 default_dir_chooser->signal_current_folder_changed().connect (sigc::mem_fun (*this, &ArdourStartup::default_dir_changed));
363 default_dir_chooser->show ();
367 default_folder_page_index = append_page (*vbox);
368 set_page_title (*vbox, _("Default folder for new sessions"));
369 set_page_header_image (*vbox, icon_pixbuf);
370 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
372 /* user can just skip all these settings if they want to */
374 set_page_complete (*vbox, true);
378 ArdourStartup::setup_monitoring_choice_page ()
380 mon_vbox.set_spacing (18);
381 mon_vbox.set_border_width (24);
383 HBox* hbox = manage (new HBox);
384 VBox* vbox = manage (new VBox);
385 /* first button will be on by default */
386 RadioButton::Group g (monitor_via_ardour_button.get_group());
387 monitor_via_hardware_button.set_group (g);
389 monitor_label.set_markup(_("\
390 While recording instruments or vocals, you probably want to listen to the\n\
391 signal as well as record it. This is called \"monitoring\". There are\n\
392 different ways to do this depending on the equipment you have and the\n\
393 configuration of that equipment. The two most common are presented here.\n\
394 Please choose whichever one is right for your setup.\n\n\
395 <i>(You can change this preference at any time, via the Preferences dialog)</i>\n\n\
396 <i>If you do not understand what this is about, just accept the default.</i>"));
397 monitor_label.set_alignment (0.0, 0.0);
399 vbox->set_spacing (6);
401 vbox->pack_start (monitor_via_hardware_button, false, true);
402 vbox->pack_start (monitor_via_ardour_button, false, true);
403 hbox->pack_start (*vbox, true, true, 8);
404 mon_vbox.pack_start (monitor_label, false, false);
405 mon_vbox.pack_start (*hbox, false, false);
407 mon_vbox.show_all ();
409 monitoring_page_index = append_page (mon_vbox);
410 set_page_title (mon_vbox, _("Monitoring Choices"));
411 set_page_header_image (mon_vbox, icon_pixbuf);
413 /* user could just click on "Forward" if default
417 set_page_complete (mon_vbox, true);
421 ArdourStartup::setup_monitor_section_choice_page ()
423 mon_sec_vbox.set_spacing (18);
424 mon_sec_vbox.set_border_width (24);
426 HBox* hbox = manage (new HBox);
427 VBox* main_vbox = manage (new VBox);
429 Label* l = manage (new Label);
431 main_vbox->set_spacing (32);
433 no_monitor_section_button.set_label (_("Use a Master bus directly"));
434 l->set_alignment (0.0, 1.0);
435 l->set_markup(_("Connect the Master bus directly to your hardware outputs. This is preferable for simple usage."));
437 vbox = manage (new VBox);
438 vbox->set_spacing (6);
439 vbox->pack_start (no_monitor_section_button, false, true);
440 vbox->pack_start (*l, false, true);
442 main_vbox->pack_start (*vbox, false, false);
444 use_monitor_section_button.set_label (_("Use an additional Monitor bus"));
445 l = manage (new Label);
446 l->set_alignment (0.0, 1.0);
447 l->set_text (_("Use a Monitor bus between Master bus and hardware outputs for \n\
448 greater control in monitoring without affecting the mix."));
450 vbox = manage (new VBox);
451 vbox->set_spacing (6);
452 vbox->pack_start (use_monitor_section_button, false, true);
453 vbox->pack_start (*l, false, true);
455 main_vbox->pack_start (*vbox, false, false);
457 RadioButton::Group g (use_monitor_section_button.get_group());
458 no_monitor_section_button.set_group (g);
460 if (Config->get_use_monitor_bus()) {
461 use_monitor_section_button.set_active (true);
463 no_monitor_section_button.set_active (true);
466 use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
467 no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
469 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\
470 <i>If you do not understand what this is about, just accept the default.</i>"));
471 monitor_section_label.set_alignment (0.0, 0.0);
473 hbox->pack_start (*main_vbox, true, true, 8);
474 mon_sec_vbox.pack_start (*hbox, false, false);
475 mon_sec_vbox.pack_start (monitor_section_label, false, false);
477 mon_sec_vbox.show_all ();
479 monitor_section_page_index = append_page (mon_sec_vbox);
480 set_page_title (mon_sec_vbox, _("Monitor Section"));
481 set_page_header_image (mon_sec_vbox, icon_pixbuf);
483 /* user could just click on "Forward" if default
487 set_page_complete (mon_sec_vbox, true);
491 ArdourStartup::setup_initial_choice_page ()
493 ic_vbox.set_spacing (6);
494 ic_vbox.set_border_width (24);
496 /* append the page early because the recent session display will cause
497 calls to set_page_complete() on this page.
500 initial_choice_index = append_page (ic_vbox);
501 set_page_title (ic_vbox, string_compose("%1 %2", PROGRAM_NAME, VERSIONSTRING));
502 set_page_header_image (ic_vbox, icon_pixbuf);
505 HBox* centering_hbox = manage (new HBox);
506 VBox* centering_vbox = manage (new VBox);
508 centering_vbox->set_spacing (6);
510 Label* new_label = manage (new Label);
511 new_label->set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", _("Create a new session")));
512 new_label->set_alignment (0, 0.5);
514 ic_new_session_button.set_label (_("Configure the new session ..."));
515 ic_new_session_button.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::new_session_button_clicked));
517 centering_vbox->pack_start (*new_label, false, false, 12);
518 centering_vbox->pack_start (ic_new_session_button, false, true);
520 /* Possible update message */
522 if (ARDOUR_UI::instance()->announce_string() != "" ) {
524 Gtk::Frame *info_frame = manage(new Gtk::Frame);
525 info_frame->set_shadow_type(SHADOW_ETCHED_OUT);
526 centering_vbox->pack_start (*info_frame, false, false, 20);
528 Box *info_box = manage (new VBox);
529 info_box->set_border_width (12);
530 info_box->set_spacing (6);
531 info_box->set_name("mixbus_info_box");
533 info_box->pack_start (info_scroller_label, false, false);
535 info_frame->add (*info_box);
536 info_frame->show_all();
538 info_scroller_count = 0;
539 info_scroller_connection = Glib::signal_timeout().connect (mem_fun(*this, &ArdourStartup::info_scroller_update), 50);
541 Gtk::Button *updates_button = manage (new Gtk::Button (_("Check the website for more...")));
543 updates_button->signal_clicked().connect (mem_fun(*this, &ArdourStartup::updates_button_clicked) );
544 ARDOUR_UI::instance()->tooltips().set_tip (*updates_button, _("Click to open the program website in your web browser"));
546 info_box->pack_start (*updates_button, false, false);
549 /* recent session scroller */
551 recent_label.set_no_show_all (true);
552 recent_scroller.set_no_show_all (true);
554 recent_label.set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", _("Load a recent session")));
555 recent_label.set_alignment (0, 0.5);
557 recent_session_model = TreeStore::create (recent_session_columns);
559 recent_session_display.set_model (recent_session_model);
560 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
561 recent_session_display.set_headers_visible (false);
562 recent_session_display.get_selection()->set_mode (SELECTION_SINGLE);
564 recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::recent_session_row_selected));
566 recent_scroller.add (recent_session_display);
567 recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
568 recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
570 recent_session_display.show();
571 recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ArdourStartup::recent_row_activated));
573 centering_vbox->pack_start (recent_label, false, false, 12);
574 centering_vbox->pack_start (recent_scroller, false, true);
578 existing_session_chooser.set_title (_("Select session file"));
579 existing_session_chooser.signal_file_set().connect (sigc::mem_fun (*this, &ArdourStartup::existing_session_selected));
580 existing_session_chooser.set_current_folder(poor_mans_glob (Config->get_default_session_parent_dir()));
582 FileFilter session_filter;
583 session_filter.add_pattern ("*.ardour");
584 session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
585 existing_session_chooser.add_filter (session_filter);
586 existing_session_chooser.set_filter (session_filter);
589 existing_session_chooser.add_shortcut_folder ("/Volumes");
592 Label* browse_label = manage (new Label);
593 browse_label->set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", _("Browse for other sessions")));
594 browse_label->set_alignment (0, 0.5);
596 centering_vbox->pack_start (*browse_label, false, false, 12);
597 centering_vbox->pack_start (existing_session_chooser, false, false);
601 centering_hbox->pack_start (*centering_vbox, true, true);
602 ic_vbox.pack_start (*centering_hbox, true, true);
605 /* user could just click on "Forward" if default
609 set_page_complete (ic_vbox, true);
613 ArdourStartup::session_selected ()
615 /* HACK HACK HACK ... change the "Apply" button label
619 Gtk::Widget* tl = ic_vbox.get_toplevel();
621 if ((win = dynamic_cast<Gtk::Window*>(tl)) != 0) {
622 /* ::get_default_widget() is not wrapped in gtkmm */
623 Gtk::Widget* def = wrap (gtk_window_get_default_widget (win->gobj()));
625 if ((button = dynamic_cast<Gtk::Button*>(def)) != 0) {
626 button->set_label (_("Open"));
632 ArdourStartup::new_session_button_clicked ()
634 _existing_session_chooser_used = false;
635 recent_session_display.get_selection()->unselect_all ();
636 set_current_page (new_session_page_index);
640 ArdourStartup::setup_final_page ()
642 final_page.set_text (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
644 final_page_index = append_page (final_page);
645 set_page_complete (final_page, true);
646 set_page_header_image (final_page, icon_pixbuf);
647 set_page_type (final_page, ASSISTANT_PAGE_CONFIRM);
651 ArdourStartup::on_cancel ()
653 _response = RESPONSE_CANCEL;
658 ArdourStartup::on_prepare (Gtk::Widget* page)
660 if (page == &session_new_vbox) {
662 /* if the user already defined a name by using the recent
663 * session list or browsing to an existing session
667 bool expect_new_ignored;
669 if (!session_name (expect_new_ignored).empty()) {
676 ArdourStartup::on_delete_event (GdkEventAny*)
678 _response = RESPONSE_CLOSE;
684 ArdourStartup::on_apply ()
686 if (config_modified) {
688 if (default_dir_chooser) {
689 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
692 if (monitor_via_hardware_button.get_active()) {
693 Config->set_monitoring_model (ExternalMonitoring);
694 } else if (monitor_via_ardour_button.get_active()) {
695 Config->set_monitoring_model (SoftwareMonitoring);
698 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
700 Config->save_state ();
705 /* "touch" the been-here-before path now we've successfully
706 made it through the first time setup (at least)
708 ofstream fout (been_here_before_path().c_str());
712 _response = RESPONSE_OK;
717 ArdourStartup::populate_session_templates ()
719 vector<TemplateInfo> templates;
721 find_session_templates (templates);
723 template_model->clear ();
725 for (vector<TemplateInfo>::iterator x = templates.begin(); x != templates.end(); ++x) {
728 row = *(template_model->append ());
730 row[session_template_columns.name] = (*x).name;
731 row[session_template_columns.path] = (*x).path;
736 ArdourStartup::setup_new_session_page ()
738 session_new_vbox.set_border_width (12);
739 session_new_vbox.set_spacing (18);
741 VBox *vbox1 = manage (new VBox);
742 HBox* hbox1 = manage (new HBox);
743 Label* label1 = manage (new Label);
745 vbox1->set_spacing (6);
747 hbox1->set_spacing (6);
748 hbox1->pack_start (*label1, false, false);
749 hbox1->pack_start (new_name_entry, true, true);
751 label1->set_text (_("Session name:"));
754 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
755 new_name_entry.set_text (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
756 /* name provided - they can move right along */
757 set_page_complete (session_new_vbox, true);
760 new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_changed));
761 new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &ArdourStartup::move_along_now));
763 vbox1->pack_start (*hbox1, true, true);
767 HBox* hbox2 = manage (new HBox);
768 Label* label2 = manage (new Label);
770 hbox2->set_spacing (6);
771 hbox2->pack_start (*label2, false, false);
772 hbox2->pack_start (new_folder_chooser, true, true);
774 label2->set_text (_("Create session folder in:"));
776 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
777 new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
778 } else if (ARDOUR_UI::instance()->session_loaded) {
779 // point the new session file chooser at the parent directory of the current session
780 string session_parent_dir = Glib::path_get_dirname(ARDOUR_UI::instance()->the_session()->path());
781 string::size_type last_dir_sep = session_parent_dir.rfind(G_DIR_SEPARATOR);
782 session_parent_dir = session_parent_dir.substr(0, last_dir_sep);
783 new_folder_chooser.set_current_folder (session_parent_dir);
784 string default_session_folder = poor_mans_glob (Config->get_default_session_parent_dir());
787 /* add_shortcut_folder throws an exception if the folder being added already has a shortcut */
788 new_folder_chooser.add_shortcut_folder (default_session_folder);
790 catch (Glib::Error & e) {
791 std::cerr << "new_folder_chooser.add_shortcut_folder (" << default_session_folder << ") threw Glib::Error " << e.what() << std::endl;
794 new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
796 new_folder_chooser.show ();
797 new_folder_chooser.set_title (_("Select folder for session"));
800 new_folder_chooser.add_shortcut_folder ("/Volumes");
803 vbox1->pack_start (*hbox2, false, false);
805 session_new_vbox.pack_start (*vbox1, false, false);
809 VBox *vbox2 = manage (new VBox);
810 HBox* hbox3 = manage (new HBox);
811 template_model = ListStore::create (session_template_columns);
813 vbox2->set_spacing (6);
815 VBox *vbox3 = manage (new VBox);
817 vbox3->set_spacing (6);
819 /* we may want to hide this and show it at various
820 times depending on the existence of templates.
822 template_chooser.set_no_show_all (true);
823 use_template_button.set_no_show_all (true);
825 HBox* hbox4a = manage (new HBox);
826 use_template_button.set_label (_("Use this template"));
828 TreeModel::Row row = *template_model->prepend ();
829 row[session_template_columns.name] = (_("no template"));
830 row[session_template_columns.path] = string();
832 hbox4a->set_spacing (6);
833 hbox4a->pack_start (use_template_button, false, false);
834 hbox4a->pack_start (template_chooser, true, true);
836 template_chooser.set_model (template_model);
838 Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
839 text_renderer->property_editable() = false;
841 template_chooser.pack_start (*text_renderer);
842 template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
843 template_chooser.set_active (0);
845 vbox3->pack_start (*hbox4a, false, false);
850 session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
852 HBox* hbox4b = manage (new HBox);
853 use_session_as_template_button.set_label (_("Use an existing session as a template:"));
855 hbox4b->set_spacing (6);
856 hbox4b->pack_start (use_session_as_template_button, false, false);
857 hbox4b->pack_start (session_template_chooser, true, true);
859 use_session_as_template_button.show ();
860 session_template_chooser.show ();
862 Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
863 session_filter->add_pattern (X_("*.ardour"));
864 session_template_chooser.set_filter (*session_filter);
865 session_template_chooser.set_title (_("Select template"));
867 vbox3->pack_start (*hbox4b, false, false);
872 HBox* hbox5 = manage (new HBox);
874 hbox5->set_spacing (6);
875 hbox5->pack_start (more_new_session_options_button, false, false);
877 setup_more_options_box ();
878 more_new_session_options_button.add (more_options_vbox);
880 vbox3->pack_start (*hbox5, false, false);
881 hbox3->pack_start (*vbox3, true, true, 8);
882 vbox2->pack_start (*hbox3, false, false);
886 session_new_vbox.pack_start (*vbox2, false, false);
887 session_new_vbox.show_all ();
889 new_session_page_index = append_page (session_new_vbox);
890 set_page_type (session_new_vbox, ASSISTANT_PAGE_CONTENT);
891 set_page_title (session_new_vbox, _("New Session"));
893 set_page_type (session_new_vbox, ASSISTANT_PAGE_CONFIRM);
897 ArdourStartup::new_name_changed ()
899 if (!new_name_entry.get_text().empty()) {
901 set_page_complete (session_new_vbox, true);
903 set_page_complete (session_new_vbox, false);
908 ArdourStartup::redisplay_recent_sessions ()
910 std::vector<std::string> session_directories;
911 RecentSessionsSorter cmp;
913 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
914 recent_session_model->clear ();
916 ARDOUR::RecentSessions rs;
917 ARDOUR::read_recent_sessions (rs);
920 recent_session_display.set_model (recent_session_model);
924 // sort them alphabetically
925 sort (rs.begin(), rs.end(), cmp);
927 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
928 session_directories.push_back ((*i).second);
931 int session_snapshot_count = 0;
933 for (vector<std::string>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
935 std::vector<std::string> state_file_paths;
937 // now get available states for this session
939 get_state_files_in_directory (*i, state_file_paths);
941 vector<string*>* states;
942 vector<const gchar*> item;
943 string fullpath = *i;
945 /* remove any trailing / */
947 if (fullpath[fullpath.length()-1] == '/') {
948 fullpath = fullpath.substr (0, fullpath.length()-1);
951 /* check whether session still exists */
952 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
953 /* session doesn't exist */
957 /* now get available states for this session */
959 if ((states = Session::possible_states (fullpath)) == 0) {
964 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
966 Gtk::TreeModel::Row row = *(recent_session_model->append());
968 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
969 row[recent_session_columns.fullpath] = fullpath;
970 row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
972 ++session_snapshot_count;
974 if (state_file_names.size() > 1) {
978 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
979 i2 != state_file_names.end(); ++i2) {
981 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
983 child_row[recent_session_columns.visible_name] = *i2;
984 child_row[recent_session_columns.fullpath] = fullpath;
985 child_row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
986 ++session_snapshot_count;
991 recent_session_display.set_tooltip_column(1); // recent_session_columns.tip
992 recent_session_display.set_model (recent_session_model);
993 return session_snapshot_count;
998 ArdourStartup::recent_session_row_selected ()
1000 if (recent_session_display.get_selection()->count_selected_rows() > 0) {
1001 set_page_complete (ic_vbox, true);
1002 session_selected ();
1004 set_page_complete (ic_vbox, false);
1009 ArdourStartup::setup_more_options_box ()
1011 more_options_vbox.set_border_width (24);
1013 _output_limit_count.set_adjustment (_output_limit_count_adj);
1014 _input_limit_count.set_adjustment (_input_limit_count_adj);
1015 _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
1017 chan_count_label_1.set_text (_("channels"));
1018 chan_count_label_3.set_text (_("channels"));
1019 chan_count_label_4.set_text (_("channels"));
1021 chan_count_label_1.set_alignment(0,0.5);
1022 chan_count_label_1.set_padding(0,0);
1023 chan_count_label_1.set_line_wrap(false);
1025 chan_count_label_3.set_alignment(0,0.5);
1026 chan_count_label_3.set_padding(0,0);
1027 chan_count_label_3.set_line_wrap(false);
1029 chan_count_label_4.set_alignment(0,0.5);
1030 chan_count_label_4.set_padding(0,0);
1031 chan_count_label_4.set_line_wrap(false);
1033 bus_label.set_markup (_("<b>Busses</b>"));
1034 input_label.set_markup (_("<b>Inputs</b>"));
1035 output_label.set_markup (_("<b>Outputs</b>"));
1037 _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
1038 _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1039 _master_bus_channel_count.set_numeric(true);
1040 _master_bus_channel_count.set_digits(0);
1041 _master_bus_channel_count.set_wrap(false);
1043 _create_master_bus.set_label (_("Create master bus"));
1044 _create_master_bus.set_flags(Gtk::CAN_FOCUS);
1045 _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
1046 _create_master_bus.set_mode(true);
1047 _create_master_bus.set_active(true);
1048 _create_master_bus.set_border_width(0);
1050 advanced_table.set_row_spacings(0);
1051 advanced_table.set_col_spacings(0);
1053 _connect_inputs.set_label (_("Automatically connect to physical inputs"));
1054 _connect_inputs.set_flags(Gtk::CAN_FOCUS);
1055 _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
1056 _connect_inputs.set_mode(true);
1057 _connect_inputs.set_active(Config->get_input_auto_connect() != ManualConnect);
1058 _connect_inputs.set_border_width(0);
1060 _limit_input_ports.set_label (_("Use only"));
1061 _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
1062 _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
1063 _limit_input_ports.set_mode(true);
1064 _limit_input_ports.set_sensitive(true);
1065 _limit_input_ports.set_border_width(0);
1067 _input_limit_count.set_flags(Gtk::CAN_FOCUS);
1068 _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1069 _input_limit_count.set_numeric(true);
1070 _input_limit_count.set_digits(0);
1071 _input_limit_count.set_wrap(false);
1072 _input_limit_count.set_sensitive(false);
1074 bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
1076 bus_label.set_alignment(0, 0.5);
1077 bus_label.set_padding(0,0);
1078 bus_label.set_line_wrap(false);
1079 bus_label.set_selectable(false);
1080 bus_label.set_use_markup(true);
1081 bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
1082 bus_frame.set_label_align(0,0.5);
1083 bus_frame.add(bus_hbox);
1084 bus_frame.set_label_widget(bus_label);
1086 bus_table.set_row_spacings (0);
1087 bus_table.set_col_spacings (0);
1088 bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1089 bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1090 bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
1092 input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
1093 input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
1094 input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
1095 input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
1096 input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
1097 input_table.set_row_spacings(0);
1098 input_table.set_col_spacings(0);
1099 input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
1101 input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
1103 input_label.set_alignment(0, 0.5);
1104 input_label.set_padding(0,0);
1105 input_label.set_line_wrap(false);
1106 input_label.set_selectable(false);
1107 input_label.set_use_markup(true);
1108 input_frame.set_shadow_type(Gtk::SHADOW_NONE);
1109 input_frame.set_label_align(0,0.5);
1110 input_frame.add(input_hbox);
1111 input_frame.set_label_widget(input_label);
1113 _connect_outputs.set_label (_("Automatically connect outputs"));
1114 _connect_outputs.set_flags(Gtk::CAN_FOCUS);
1115 _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
1116 _connect_outputs.set_mode(true);
1117 _connect_outputs.set_active(Config->get_output_auto_connect() != ManualConnect);
1118 _connect_outputs.set_border_width(0);
1119 _limit_output_ports.set_label (_("Use only"));
1120 _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
1121 _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
1122 _limit_output_ports.set_mode(true);
1123 _limit_output_ports.set_sensitive(true);
1124 _limit_output_ports.set_border_width(0);
1125 _output_limit_count.set_flags(Gtk::CAN_FOCUS);
1126 _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1127 _output_limit_count.set_numeric(false);
1128 _output_limit_count.set_digits(0);
1129 _output_limit_count.set_wrap(false);
1130 _output_limit_count.set_sensitive(false);
1131 output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
1132 output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
1133 output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
1135 _connect_outputs_to_master.set_label (_("... to master bus"));
1136 _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
1137 _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
1138 _connect_outputs_to_master.set_mode(true);
1139 _connect_outputs_to_master.set_active(Config->get_output_auto_connect() == AutoConnectMaster);
1140 _connect_outputs_to_master.set_border_width(0);
1142 _connect_outputs_to_master.set_group (connect_outputs_group);
1143 _connect_outputs_to_physical.set_group (connect_outputs_group);
1145 _connect_outputs_to_physical.set_label (_("... to physical outputs"));
1146 _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
1147 _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
1148 _connect_outputs_to_physical.set_mode(true);
1149 _connect_outputs_to_physical.set_active(Config->get_output_auto_connect() == AutoConnectPhysical);
1150 _connect_outputs_to_physical.set_border_width(0);
1152 output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
1153 output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
1154 output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
1155 output_vbox.set_border_width(6);
1157 output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
1159 output_vbox.pack_start(output_conn_vbox);
1160 output_vbox.pack_start(output_port_vbox);
1162 output_label.set_alignment(0, 0.5);
1163 output_label.set_padding(0,0);
1164 output_label.set_line_wrap(false);
1165 output_label.set_selectable(false);
1166 output_label.set_use_markup(true);
1167 output_frame.set_shadow_type(Gtk::SHADOW_NONE);
1168 output_frame.set_label_align(0,0.5);
1170 output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
1172 output_frame.add(output_hbox);
1173 output_frame.set_label_widget(output_label);
1175 more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
1176 more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
1177 more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
1178 more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
1182 _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
1183 _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
1184 _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
1185 _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
1186 _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
1188 /* note that more_options_vbox is "visible" by default even
1189 * though it may not be displayed to the user, this is so the dialog
1192 more_options_vbox.show_all ();
1196 ArdourStartup::create_master_bus() const
1198 return _create_master_bus.get_active();
1202 ArdourStartup::master_channel_count() const
1204 return _master_bus_channel_count.get_value_as_int();
1208 ArdourStartup::connect_inputs() const
1210 return _connect_inputs.get_active();
1214 ArdourStartup::limit_inputs_used_for_connection() const
1216 return _limit_input_ports.get_active();
1220 ArdourStartup::input_limit_count() const
1222 return _input_limit_count.get_value_as_int();
1226 ArdourStartup::connect_outputs() const
1228 return _connect_outputs.get_active();
1232 ArdourStartup::limit_outputs_used_for_connection() const
1234 return _limit_output_ports.get_active();
1238 ArdourStartup::output_limit_count() const
1240 return _output_limit_count.get_value_as_int();
1244 ArdourStartup::connect_outs_to_master() const
1246 return _connect_outputs_to_master.get_active();
1250 ArdourStartup::connect_outs_to_physical() const
1252 return _connect_outputs_to_physical.get_active();
1256 ArdourStartup::connect_inputs_clicked ()
1258 _limit_input_ports.set_sensitive(_connect_inputs.get_active());
1260 if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
1261 _input_limit_count.set_sensitive(true);
1263 _input_limit_count.set_sensitive(false);
1268 ArdourStartup::connect_outputs_clicked ()
1270 bool const co = _connect_outputs.get_active ();
1271 _limit_output_ports.set_sensitive(co);
1272 _connect_outputs_to_master.set_sensitive(co);
1273 _connect_outputs_to_physical.set_sensitive(co);
1275 if (co && _limit_output_ports.get_active()) {
1276 _output_limit_count.set_sensitive(true);
1278 _output_limit_count.set_sensitive(false);
1283 ArdourStartup::limit_inputs_clicked ()
1285 _input_limit_count.set_sensitive(_limit_input_ports.get_active());
1289 ArdourStartup::limit_outputs_clicked ()
1291 _output_limit_count.set_sensitive(_limit_output_ports.get_active());
1295 ArdourStartup::master_bus_button_clicked ()
1297 bool const yn = _create_master_bus.get_active();
1299 _master_bus_channel_count.set_sensitive(yn);
1300 _connect_outputs_to_master.set_sensitive(yn);
1304 ArdourStartup::move_along_now ()
1310 ArdourStartup::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
1312 set_page_complete (ic_vbox, true);
1317 ArdourStartup::existing_session_selected ()
1319 _existing_session_chooser_used = true;
1321 session_selected ();
1322 set_page_complete (ic_vbox, true);
1327 ArdourStartup::been_here_before_path () const
1329 // XXXX use more specific version so we can catch upgrades
1330 return Glib::build_filename (user_config_directory (), ".a3");
1334 ArdourStartup::updates_button_clicked ()
1336 //now open a browser window so user can see more
1337 PBD::open_uri (Config->get_updates_url());
1341 ArdourStartup::info_scroller_update()
1343 info_scroller_count++;
1346 snprintf (buf, std::min(info_scroller_count,sizeof(buf)-1), "%s", ARDOUR_UI::instance()->announce_string().c_str() );
1347 buf[info_scroller_count] = 0;
1348 info_scroller_label.set_text (buf);
1349 info_scroller_label.show();
1351 if (info_scroller_count > ARDOUR_UI::instance()->announce_string().length()) {
1352 info_scroller_connection.disconnect();
1359 ArdourStartup::on_map ()
1361 Gtk::Assistant::on_map ();
1363 populate_session_templates ();
1365 if (!template_model->children().empty()) {
1366 use_template_button.show();
1367 template_chooser.show ();
1369 use_template_button.hide();
1370 template_chooser.hide ();
1373 if (recent_session_model) {
1374 int cnt = redisplay_recent_sessions ();
1376 recent_scroller.show();
1377 recent_label.show ();
1380 recent_scroller.set_size_request (-1, 300);
1383 recent_scroller.hide();
1384 recent_label.hide ();