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 set_keep_above (true);
100 set_position (WIN_POS_CENTER);
101 set_border_width (12);
103 if ((icon_pixbuf = ::get_icon ("ardour_icon_48px")) == 0) {
104 throw failed_constructor();
107 list<Glib::RefPtr<Gdk::Pixbuf> > window_icons;
108 Glib::RefPtr<Gdk::Pixbuf> icon;
110 if ((icon = ::get_icon ("ardour_icon_16px")) != 0) {
111 window_icons.push_back (icon);
113 if ((icon = ::get_icon ("ardour_icon_22px")) != 0) {
114 window_icons.push_back (icon);
116 if ((icon = ::get_icon ("ardour_icon_32px")) != 0) {
117 window_icons.push_back (icon);
119 if ((icon = ::get_icon ("ardour_icon_48px")) != 0) {
120 window_icons.push_back (icon);
122 if (!window_icons.empty ()) {
123 set_default_icon_list (window_icons);
127 setup_prerelease_page ();
131 setup_new_user_page ();
132 setup_first_time_config_page ();
133 setup_monitoring_choice_page ();
134 setup_monitor_section_choice_page ();
136 setup_new_session_page ();
141 setup_initial_choice_page ();
143 setup_new_session_page ();
146 if (!template_name.empty()) {
147 use_template_button.set_active (false);
148 load_template_override = template_name;
155 ArdourStartup::~ArdourStartup ()
160 ArdourStartup::ready_without_display () const
162 return !new_user && !need_session_info;
166 ArdourStartup::setup_prerelease_page ()
168 VBox* vbox = manage (new VBox);
169 Label* label = manage (new Label);
170 label->set_markup (string_compose (_("<b>Welcome to this BETA release of Ardour %1</b>\n\n\
171 Ardour %1 has been released for Linux but because of the lack of testers,\n\
172 it is still at the beta stage on OS X. So, a few guidelines:\n\
174 1) Please do <b>NOT</b> use this software with the expectation that it is stable or reliable\n\
175 though it may be so, depending on your workflow.\n\
176 2) <b>Please do NOT use the forums at ardour.org to report issues</b>.\n\
177 3) Please <b>DO</b> use the bugtracker at http://tracker.ardour.org/ to report issues\n\
178 making sure to note the product version number as %1-beta.\n\
179 4) Please <b>DO</b> use the ardour-users mailing list to discuss ideas and pass on comments.\n\
180 5) Please <b>DO</b> join us on IRC for real time discussions about ardour3. You\n\
181 can get there directly from Ardour via the Help->Chat menu option.\n\
183 Full information on all the above can be found on the support page at\n\
185 http://ardour.org/support\n\
188 vbox->set_border_width (12);
189 vbox->pack_start (*label, false, false, 12);
193 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
194 set_page_title (*vbox, _("This is a BETA RELEASE"));
195 set_page_complete (*vbox, true);
199 ArdourStartup::use_session_template ()
201 if (!load_template_override.empty()) {
205 if (use_template_button.get_active()) {
206 return template_chooser.get_active_row_number() > 0;
213 ArdourStartup::session_template_name ()
215 if (!load_template_override.empty()) {
216 string the_path (ARDOUR::user_template_directory());
217 return Glib::build_filename (the_path, load_template_override + ARDOUR::template_suffix);
220 if (use_template_button.get_active()) {
221 TreeModel::iterator iter = template_chooser.get_active ();
222 TreeModel::Row row = (*iter);
223 string s = row[session_template_columns.path];
231 ArdourStartup::session_name (bool& should_be_new)
233 if (ready_without_display()) {
234 return _provided_session_name;
237 /* Try recent session selection */
239 TreeIter iter = recent_session_display.get_selection()->get_selected();
242 should_be_new = false;
243 return (*iter)[recent_session_columns.visible_name];
246 if (_existing_session_chooser_used) {
247 /* existing session chosen from file chooser */
248 should_be_new = false;
249 return existing_session_chooser.get_filename ();
251 should_be_new = true;
252 string val = new_name_entry.get_text ();
253 strip_whitespace_edges (val);
259 ArdourStartup::session_folder ()
261 if (ready_without_display()) {
262 return _provided_session_path;
265 /* Try recent session selection */
267 TreeIter iter = recent_session_display.get_selection()->get_selected();
270 return (*iter)[recent_session_columns.fullpath];
273 if (_existing_session_chooser_used) {
274 /* existing session chosen from file chooser */
275 return existing_session_chooser.get_current_folder ();
277 std::string legal_session_folder_name = legalize_for_path (new_name_entry.get_text());
278 return Glib::build_filename (new_folder_chooser.get_current_folder(), legal_session_folder_name);
283 ArdourStartup::setup_new_user_page ()
285 Label* foomatic = manage (new Label);
287 foomatic->set_markup (string_compose (_("\
288 <span size=\"larger\">%1 is a digital audio workstation. You can use it to \
289 record, edit and mix multi-track audio. You can produce your \
290 own CDs, mix video soundtracks, or experiment with new \
291 ideas about music and sound. \
293 There are a few things that need to be configured before you start \
294 using the program.</span> \
296 foomatic->set_justify (JUSTIFY_FILL);
297 foomatic->set_line_wrap ();
299 HBox* hbox = manage (new HBox);
300 HBox* vbox = manage (new HBox);
302 vbox->set_border_width (24);
304 hbox->pack_start (*foomatic, true, true);
305 vbox->pack_start (*hbox, true, true);
311 new_user_page_index = append_page (*vbox);
312 set_page_type (*vbox, ASSISTANT_PAGE_INTRO);
313 set_page_title (*vbox, string_compose (_("Welcome to %1"), PROGRAM_NAME));
314 set_page_header_image (*vbox, icon_pixbuf);
315 set_page_complete (*vbox, true);
319 ArdourStartup::default_dir_changed ()
321 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
322 // make new session folder chooser point to the new default
323 new_folder_chooser.set_current_folder (Config->get_default_session_parent_dir());
328 ArdourStartup::config_changed ()
330 config_modified = true;
334 ArdourStartup::setup_first_time_config_page ()
336 default_dir_chooser = manage (new FileChooserButton (string_compose (_("Default folder for %1 sessions"), PROGRAM_NAME),
337 FILE_CHOOSER_ACTION_SELECT_FOLDER));
338 Gtk::Label* txt = manage (new Label);
339 HBox* hbox = manage (new HBox);
340 VBox* vbox = manage (new VBox);
342 txt->set_markup (string_compose (_("\
343 Each project that you work on with %1 has its own folder.\n\
344 These can require a lot of disk space if you are recording audio.\n\
346 Where would you like new %1 sessions to be stored by default?\n\n\
347 <i>(You can put new sessions anywhere, this is just a default)</i>"), PROGRAM_NAME));
348 txt->set_alignment (0.0, 0.0);
350 vbox->set_spacing (18);
351 vbox->set_border_width (24);
353 hbox->pack_start (*default_dir_chooser, false, true, 8);
354 vbox->pack_start (*txt, false, false);
355 vbox->pack_start (*hbox, false, true);
357 default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
358 default_dir_chooser->signal_current_folder_changed().connect (sigc::mem_fun (*this, &ArdourStartup::default_dir_changed));
359 default_dir_chooser->show ();
363 default_folder_page_index = append_page (*vbox);
364 set_page_title (*vbox, _("Default folder for new sessions"));
365 set_page_header_image (*vbox, icon_pixbuf);
366 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
368 /* user can just skip all these settings if they want to */
370 set_page_complete (*vbox, true);
374 ArdourStartup::setup_monitoring_choice_page ()
376 mon_vbox.set_spacing (18);
377 mon_vbox.set_border_width (24);
379 HBox* hbox = manage (new HBox);
380 VBox* vbox = manage (new VBox);
381 /* first button will be on by default */
382 RadioButton::Group g (monitor_via_ardour_button.get_group());
383 monitor_via_hardware_button.set_group (g);
385 monitor_label.set_markup(_("\
386 While recording instruments or vocals, you probably want to listen to the\n\
387 signal as well as record it. This is called \"monitoring\". There are\n\
388 different ways to do this depending on the equipment you have and the\n\
389 configuration of that equipment. The two most common are presented here.\n\
390 Please choose whichever one is right for your setup.\n\n\
391 <i>(You can change this preference at any time, via the Preferences dialog)</i>\n\n\
392 <i>If you do not understand what this is about, just accept the default.</i>"));
393 monitor_label.set_alignment (0.0, 0.0);
395 vbox->set_spacing (6);
397 vbox->pack_start (monitor_via_hardware_button, false, true);
398 vbox->pack_start (monitor_via_ardour_button, false, true);
399 hbox->pack_start (*vbox, true, true, 8);
400 mon_vbox.pack_start (monitor_label, false, false);
401 mon_vbox.pack_start (*hbox, false, false);
403 mon_vbox.show_all ();
405 monitoring_page_index = append_page (mon_vbox);
406 set_page_title (mon_vbox, _("Monitoring Choices"));
407 set_page_header_image (mon_vbox, icon_pixbuf);
409 /* user could just click on "Forward" if default
413 set_page_complete (mon_vbox, true);
417 ArdourStartup::setup_monitor_section_choice_page ()
419 mon_sec_vbox.set_spacing (18);
420 mon_sec_vbox.set_border_width (24);
422 HBox* hbox = manage (new HBox);
423 VBox* main_vbox = manage (new VBox);
425 Label* l = manage (new Label);
427 main_vbox->set_spacing (32);
429 no_monitor_section_button.set_label (_("Use a Master bus directly"));
430 l->set_alignment (0.0, 1.0);
431 l->set_markup(_("Connect the Master bus directly to your hardware outputs. This is preferable for simple usage."));
433 vbox = manage (new VBox);
434 vbox->set_spacing (6);
435 vbox->pack_start (no_monitor_section_button, false, true);
436 vbox->pack_start (*l, false, true);
438 main_vbox->pack_start (*vbox, false, false);
440 use_monitor_section_button.set_label (_("Use an additional Monitor bus"));
441 l = manage (new Label);
442 l->set_alignment (0.0, 1.0);
443 l->set_text (_("Use a Monitor bus between Master bus and hardware outputs for \n\
444 greater control in monitoring without affecting the mix."));
446 vbox = manage (new VBox);
447 vbox->set_spacing (6);
448 vbox->pack_start (use_monitor_section_button, false, true);
449 vbox->pack_start (*l, false, true);
451 main_vbox->pack_start (*vbox, false, false);
453 RadioButton::Group g (use_monitor_section_button.get_group());
454 no_monitor_section_button.set_group (g);
456 if (Config->get_use_monitor_bus()) {
457 use_monitor_section_button.set_active (true);
459 no_monitor_section_button.set_active (true);
462 use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
463 no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
465 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\
466 <i>If you do not understand what this is about, just accept the default.</i>"));
467 monitor_section_label.set_alignment (0.0, 0.0);
469 hbox->pack_start (*main_vbox, true, true, 8);
470 mon_sec_vbox.pack_start (*hbox, false, false);
471 mon_sec_vbox.pack_start (monitor_section_label, false, false);
473 mon_sec_vbox.show_all ();
475 monitor_section_page_index = append_page (mon_sec_vbox);
476 set_page_title (mon_sec_vbox, _("Monitor Section"));
477 set_page_header_image (mon_sec_vbox, icon_pixbuf);
479 /* user could just click on "Forward" if default
483 set_page_complete (mon_sec_vbox, true);
487 ArdourStartup::setup_initial_choice_page ()
489 ic_vbox.set_spacing (6);
490 ic_vbox.set_border_width (24);
492 /* append the page early because the recent session display will cause
493 calls to set_page_complete() on this page.
496 initial_choice_index = append_page (ic_vbox);
497 set_page_title (ic_vbox, string_compose("%1 %2", PROGRAM_NAME, VERSIONSTRING));
498 set_page_header_image (ic_vbox, icon_pixbuf);
501 HBox* centering_hbox = manage (new HBox);
502 VBox* centering_vbox = manage (new VBox);
504 centering_vbox->set_spacing (6);
506 Label* new_label = manage (new Label);
507 new_label->set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", _("Create a new session")));
508 new_label->set_alignment (0, 0.5);
510 ic_new_session_button.set_label (_("Configure the new session ..."));
511 ic_new_session_button.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::new_session_button_clicked));
513 centering_vbox->pack_start (*new_label, false, false, 12);
514 centering_vbox->pack_start (ic_new_session_button, false, true);
516 /* Possible update message */
518 if (ARDOUR_UI::instance()->announce_string() != "" ) {
520 Gtk::Frame *info_frame = manage(new Gtk::Frame);
521 info_frame->set_shadow_type(SHADOW_ETCHED_OUT);
522 centering_vbox->pack_start (*info_frame, false, false, 20);
524 Box *info_box = manage (new VBox);
525 info_box->set_border_width (12);
526 info_box->set_spacing (6);
527 info_box->set_name("mixbus_info_box");
529 info_box->pack_start (info_scroller_label, false, false);
531 info_frame->add (*info_box);
532 info_frame->show_all();
534 info_scroller_count = 0;
535 info_scroller_connection = Glib::signal_timeout().connect (mem_fun(*this, &ArdourStartup::info_scroller_update), 50);
537 Gtk::Button *updates_button = manage (new Gtk::Button (_("Check the website for more...")));
539 updates_button->signal_clicked().connect (mem_fun(*this, &ArdourStartup::updates_button_clicked) );
540 ARDOUR_UI::instance()->tooltips().set_tip (*updates_button, _("Click to open the program website in your web browser"));
542 info_box->pack_start (*updates_button, false, false);
545 /* recent session scroller */
547 recent_label.set_no_show_all (true);
548 recent_scroller.set_no_show_all (true);
550 recent_label.set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", _("Load a recent session")));
551 recent_label.set_alignment (0, 0.5);
553 recent_session_model = TreeStore::create (recent_session_columns);
555 recent_session_display.set_model (recent_session_model);
556 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
557 recent_session_display.set_headers_visible (false);
558 recent_session_display.get_selection()->set_mode (SELECTION_SINGLE);
560 recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::recent_session_row_selected));
562 recent_scroller.add (recent_session_display);
563 recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
564 recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
566 recent_session_display.show();
567 recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ArdourStartup::recent_row_activated));
569 centering_vbox->pack_start (recent_label, false, false, 12);
570 centering_vbox->pack_start (recent_scroller, false, true);
574 existing_session_chooser.set_title (_("Select session file"));
575 existing_session_chooser.signal_file_set().connect (sigc::mem_fun (*this, &ArdourStartup::existing_session_selected));
576 existing_session_chooser.set_current_folder(poor_mans_glob (Config->get_default_session_parent_dir()));
578 FileFilter session_filter;
579 session_filter.add_pattern ("*.ardour");
580 session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
581 existing_session_chooser.add_filter (session_filter);
582 existing_session_chooser.set_filter (session_filter);
585 existing_session_chooser.add_shortcut_folder ("/Volumes");
588 Label* browse_label = manage (new Label);
589 browse_label->set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", _("Browse for other sessions")));
590 browse_label->set_alignment (0, 0.5);
592 centering_vbox->pack_start (*browse_label, false, false, 12);
593 centering_vbox->pack_start (existing_session_chooser, false, false);
597 centering_hbox->pack_start (*centering_vbox, true, true);
598 ic_vbox.pack_start (*centering_hbox, true, true);
601 /* user could just click on "Forward" if default
605 set_page_complete (ic_vbox, true);
609 ArdourStartup::session_selected ()
611 /* HACK HACK HACK ... change the "Apply" button label
615 Gtk::Widget* tl = ic_vbox.get_toplevel();
617 if ((win = dynamic_cast<Gtk::Window*>(tl)) != 0) {
618 /* ::get_default_widget() is not wrapped in gtkmm */
619 Gtk::Widget* def = wrap (gtk_window_get_default_widget (win->gobj()));
621 if ((button = dynamic_cast<Gtk::Button*>(def)) != 0) {
622 button->set_label (_("Open"));
628 ArdourStartup::new_session_button_clicked ()
630 _existing_session_chooser_used = false;
631 recent_session_display.get_selection()->unselect_all ();
632 set_current_page (new_session_page_index);
636 ArdourStartup::setup_final_page ()
638 final_page.set_text (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
640 final_page_index = append_page (final_page);
641 set_page_complete (final_page, true);
642 set_page_header_image (final_page, icon_pixbuf);
643 set_page_type (final_page, ASSISTANT_PAGE_CONFIRM);
647 ArdourStartup::on_cancel ()
649 _response = RESPONSE_CANCEL;
654 ArdourStartup::on_prepare (Gtk::Widget* page)
656 if (page == &session_new_vbox) {
658 /* if the user already defined a name by using the recent
659 * session list or browsing to an existing session
663 bool expect_new_ignored;
665 if (!session_name (expect_new_ignored).empty()) {
672 ArdourStartup::on_delete_event (GdkEventAny*)
674 _response = RESPONSE_CLOSE;
680 ArdourStartup::on_apply ()
682 if (config_modified) {
684 if (default_dir_chooser) {
685 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
688 if (monitor_via_hardware_button.get_active()) {
689 Config->set_monitoring_model (ExternalMonitoring);
690 } else if (monitor_via_ardour_button.get_active()) {
691 Config->set_monitoring_model (SoftwareMonitoring);
694 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
696 Config->save_state ();
701 /* "touch" the been-here-before path now we've successfully
702 made it through the first time setup (at least)
704 ofstream fout (been_here_before_path().c_str());
708 _response = RESPONSE_OK;
713 ArdourStartup::populate_session_templates ()
715 vector<TemplateInfo> templates;
717 find_session_templates (templates);
719 template_model->clear ();
721 for (vector<TemplateInfo>::iterator x = templates.begin(); x != templates.end(); ++x) {
724 row = *(template_model->append ());
726 row[session_template_columns.name] = (*x).name;
727 row[session_template_columns.path] = (*x).path;
730 if (!templates.empty()) {
731 /* select first row */
732 template_chooser.set_active (0);
737 ArdourStartup::setup_new_session_page ()
739 session_new_vbox.set_border_width (12);
740 session_new_vbox.set_spacing (18);
742 VBox *vbox1 = manage (new VBox);
743 HBox* hbox1 = manage (new HBox);
744 Label* label1 = manage (new Label);
746 vbox1->set_spacing (6);
748 hbox1->set_spacing (6);
749 hbox1->pack_start (*label1, false, false);
750 hbox1->pack_start (new_name_entry, true, true);
752 label1->set_text (_("Session name:"));
755 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
756 new_name_entry.set_text (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
757 /* name provided - they can move right along */
758 set_page_complete (session_new_vbox, true);
761 new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_changed));
762 new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &ArdourStartup::move_along_now));
764 vbox1->pack_start (*hbox1, true, true);
768 HBox* hbox2 = manage (new HBox);
769 Label* label2 = manage (new Label);
771 hbox2->set_spacing (6);
772 hbox2->pack_start (*label2, false, false);
773 hbox2->pack_start (new_folder_chooser, true, true);
775 label2->set_text (_("Create session folder in:"));
777 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
778 new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
779 } else if (ARDOUR_UI::instance()->session_loaded) {
780 // point the new session file chooser at the parent directory of the current session
781 string session_parent_dir = Glib::path_get_dirname(ARDOUR_UI::instance()->the_session()->path());
782 string::size_type last_dir_sep = session_parent_dir.rfind(G_DIR_SEPARATOR);
783 session_parent_dir = session_parent_dir.substr(0, last_dir_sep);
784 new_folder_chooser.set_current_folder (session_parent_dir);
785 string default_session_folder = poor_mans_glob (Config->get_default_session_parent_dir());
788 /* add_shortcut_folder throws an exception if the folder being added already has a shortcut */
789 new_folder_chooser.add_shortcut_folder (default_session_folder);
791 catch (Glib::Error & e) {
792 std::cerr << "new_folder_chooser.add_shortcut_folder (" << default_session_folder << ") threw Glib::Error " << e.what() << std::endl;
795 new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
797 new_folder_chooser.show ();
798 new_folder_chooser.set_title (_("Select folder for session"));
801 new_folder_chooser.add_shortcut_folder ("/Volumes");
804 vbox1->pack_start (*hbox2, false, false);
806 session_new_vbox.pack_start (*vbox1, false, false);
810 VBox *vbox2 = manage (new VBox);
811 HBox* hbox3 = manage (new HBox);
812 template_model = ListStore::create (session_template_columns);
814 vbox2->set_spacing (6);
816 VBox *vbox3 = manage (new VBox);
818 vbox3->set_spacing (6);
820 /* we may want to hide this and show it at various
821 times depending on the existence of templates.
823 template_chooser.set_no_show_all (true);
824 use_template_button.set_no_show_all (true);
826 HBox* hbox4a = manage (new HBox);
827 use_template_button.set_label (_("Use this template"));
829 TreeModel::Row row = *template_model->prepend ();
830 row[session_template_columns.name] = (_("no template"));
831 row[session_template_columns.path] = string();
833 hbox4a->set_spacing (6);
834 hbox4a->pack_start (use_template_button, false, false);
835 hbox4a->pack_start (template_chooser, true, true);
837 template_chooser.set_model (template_model);
839 Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
840 text_renderer->property_editable() = false;
842 template_chooser.pack_start (*text_renderer);
843 template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
844 template_chooser.set_active (0);
846 vbox3->pack_start (*hbox4a, false, false);
850 HBox* hbox5 = manage (new HBox);
852 hbox5->set_spacing (6);
853 hbox5->pack_start (more_new_session_options_button, false, false);
855 setup_more_options_box ();
856 more_new_session_options_button.add (more_options_vbox);
858 vbox3->pack_start (*hbox5, false, false);
859 hbox3->pack_start (*vbox3, true, true, 8);
860 vbox2->pack_start (*hbox3, false, false);
864 session_new_vbox.pack_start (*vbox2, false, false);
865 session_new_vbox.show_all ();
867 new_session_page_index = append_page (session_new_vbox);
868 set_page_type (session_new_vbox, ASSISTANT_PAGE_CONTENT);
869 set_page_title (session_new_vbox, _("New Session"));
871 set_page_type (session_new_vbox, ASSISTANT_PAGE_CONFIRM);
875 ArdourStartup::new_name_changed ()
877 if (!new_name_entry.get_text().empty()) {
879 set_page_complete (session_new_vbox, true);
881 set_page_complete (session_new_vbox, false);
886 ArdourStartup::redisplay_recent_sessions ()
888 std::vector<std::string> session_directories;
889 RecentSessionsSorter cmp;
891 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
892 recent_session_model->clear ();
894 ARDOUR::RecentSessions rs;
895 ARDOUR::read_recent_sessions (rs);
898 recent_session_display.set_model (recent_session_model);
902 // sort them alphabetically
903 sort (rs.begin(), rs.end(), cmp);
905 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
906 session_directories.push_back ((*i).second);
909 int session_snapshot_count = 0;
911 for (vector<std::string>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
913 std::vector<std::string> state_file_paths;
915 // now get available states for this session
917 get_state_files_in_directory (*i, state_file_paths);
919 vector<string*>* states;
920 vector<const gchar*> item;
921 string fullpath = *i;
923 /* remove any trailing / */
925 if (fullpath[fullpath.length()-1] == '/') {
926 fullpath = fullpath.substr (0, fullpath.length()-1);
929 /* check whether session still exists */
930 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
931 /* session doesn't exist */
935 /* now get available states for this session */
937 if ((states = Session::possible_states (fullpath)) == 0) {
942 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
944 Gtk::TreeModel::Row row = *(recent_session_model->append());
946 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
947 row[recent_session_columns.fullpath] = fullpath;
948 row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
950 ++session_snapshot_count;
952 if (state_file_names.size() > 1) {
956 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
957 i2 != state_file_names.end(); ++i2) {
959 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
961 child_row[recent_session_columns.visible_name] = *i2;
962 child_row[recent_session_columns.fullpath] = fullpath;
963 child_row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
964 ++session_snapshot_count;
969 recent_session_display.set_tooltip_column(1); // recent_session_columns.tip
970 recent_session_display.set_model (recent_session_model);
971 return session_snapshot_count;
976 ArdourStartup::recent_session_row_selected ()
978 if (recent_session_display.get_selection()->count_selected_rows() > 0) {
979 set_page_complete (ic_vbox, true);
982 set_page_complete (ic_vbox, false);
987 ArdourStartup::setup_more_options_box ()
989 more_options_vbox.set_border_width (24);
991 _output_limit_count.set_adjustment (_output_limit_count_adj);
992 _input_limit_count.set_adjustment (_input_limit_count_adj);
993 _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
995 chan_count_label_1.set_text (_("channels"));
996 chan_count_label_3.set_text (_("channels"));
997 chan_count_label_4.set_text (_("channels"));
999 chan_count_label_1.set_alignment(0,0.5);
1000 chan_count_label_1.set_padding(0,0);
1001 chan_count_label_1.set_line_wrap(false);
1003 chan_count_label_3.set_alignment(0,0.5);
1004 chan_count_label_3.set_padding(0,0);
1005 chan_count_label_3.set_line_wrap(false);
1007 chan_count_label_4.set_alignment(0,0.5);
1008 chan_count_label_4.set_padding(0,0);
1009 chan_count_label_4.set_line_wrap(false);
1011 bus_label.set_markup (_("<b>Busses</b>"));
1012 input_label.set_markup (_("<b>Inputs</b>"));
1013 output_label.set_markup (_("<b>Outputs</b>"));
1015 _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
1016 _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1017 _master_bus_channel_count.set_numeric(true);
1018 _master_bus_channel_count.set_digits(0);
1019 _master_bus_channel_count.set_wrap(false);
1021 _create_master_bus.set_label (_("Create master bus"));
1022 _create_master_bus.set_flags(Gtk::CAN_FOCUS);
1023 _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
1024 _create_master_bus.set_mode(true);
1025 _create_master_bus.set_active(true);
1026 _create_master_bus.set_border_width(0);
1028 advanced_table.set_row_spacings(0);
1029 advanced_table.set_col_spacings(0);
1031 _connect_inputs.set_label (_("Automatically connect to physical inputs"));
1032 _connect_inputs.set_flags(Gtk::CAN_FOCUS);
1033 _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
1034 _connect_inputs.set_mode(true);
1035 _connect_inputs.set_active(Config->get_input_auto_connect() != ManualConnect);
1036 _connect_inputs.set_border_width(0);
1038 _limit_input_ports.set_label (_("Use only"));
1039 _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
1040 _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
1041 _limit_input_ports.set_mode(true);
1042 _limit_input_ports.set_sensitive(true);
1043 _limit_input_ports.set_border_width(0);
1045 _input_limit_count.set_flags(Gtk::CAN_FOCUS);
1046 _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1047 _input_limit_count.set_numeric(true);
1048 _input_limit_count.set_digits(0);
1049 _input_limit_count.set_wrap(false);
1050 _input_limit_count.set_sensitive(false);
1052 bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
1054 bus_label.set_alignment(0, 0.5);
1055 bus_label.set_padding(0,0);
1056 bus_label.set_line_wrap(false);
1057 bus_label.set_selectable(false);
1058 bus_label.set_use_markup(true);
1059 bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
1060 bus_frame.set_label_align(0,0.5);
1061 bus_frame.add(bus_hbox);
1062 bus_frame.set_label_widget(bus_label);
1064 bus_table.set_row_spacings (0);
1065 bus_table.set_col_spacings (0);
1066 bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1067 bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1068 bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
1070 input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
1071 input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
1072 input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
1073 input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
1074 input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
1075 input_table.set_row_spacings(0);
1076 input_table.set_col_spacings(0);
1077 input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
1079 input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
1081 input_label.set_alignment(0, 0.5);
1082 input_label.set_padding(0,0);
1083 input_label.set_line_wrap(false);
1084 input_label.set_selectable(false);
1085 input_label.set_use_markup(true);
1086 input_frame.set_shadow_type(Gtk::SHADOW_NONE);
1087 input_frame.set_label_align(0,0.5);
1088 input_frame.add(input_hbox);
1089 input_frame.set_label_widget(input_label);
1091 _connect_outputs.set_label (_("Automatically connect outputs"));
1092 _connect_outputs.set_flags(Gtk::CAN_FOCUS);
1093 _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
1094 _connect_outputs.set_mode(true);
1095 _connect_outputs.set_active(Config->get_output_auto_connect() != ManualConnect);
1096 _connect_outputs.set_border_width(0);
1097 _limit_output_ports.set_label (_("Use only"));
1098 _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
1099 _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
1100 _limit_output_ports.set_mode(true);
1101 _limit_output_ports.set_sensitive(true);
1102 _limit_output_ports.set_border_width(0);
1103 _output_limit_count.set_flags(Gtk::CAN_FOCUS);
1104 _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1105 _output_limit_count.set_numeric(false);
1106 _output_limit_count.set_digits(0);
1107 _output_limit_count.set_wrap(false);
1108 _output_limit_count.set_sensitive(false);
1109 output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
1110 output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
1111 output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
1113 _connect_outputs_to_master.set_label (_("... to master bus"));
1114 _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
1115 _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
1116 _connect_outputs_to_master.set_mode(true);
1117 _connect_outputs_to_master.set_active(Config->get_output_auto_connect() == AutoConnectMaster);
1118 _connect_outputs_to_master.set_border_width(0);
1120 _connect_outputs_to_master.set_group (connect_outputs_group);
1121 _connect_outputs_to_physical.set_group (connect_outputs_group);
1123 _connect_outputs_to_physical.set_label (_("... to physical outputs"));
1124 _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
1125 _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
1126 _connect_outputs_to_physical.set_mode(true);
1127 _connect_outputs_to_physical.set_active(Config->get_output_auto_connect() == AutoConnectPhysical);
1128 _connect_outputs_to_physical.set_border_width(0);
1130 output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
1131 output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
1132 output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
1133 output_vbox.set_border_width(6);
1135 output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
1137 output_vbox.pack_start(output_conn_vbox);
1138 output_vbox.pack_start(output_port_vbox);
1140 output_label.set_alignment(0, 0.5);
1141 output_label.set_padding(0,0);
1142 output_label.set_line_wrap(false);
1143 output_label.set_selectable(false);
1144 output_label.set_use_markup(true);
1145 output_frame.set_shadow_type(Gtk::SHADOW_NONE);
1146 output_frame.set_label_align(0,0.5);
1148 output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
1150 output_frame.add(output_hbox);
1151 output_frame.set_label_widget(output_label);
1153 more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
1154 more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
1155 more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
1156 more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
1160 _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
1161 _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
1162 _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
1163 _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
1164 _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
1166 /* note that more_options_vbox is "visible" by default even
1167 * though it may not be displayed to the user, this is so the dialog
1170 more_options_vbox.show_all ();
1174 ArdourStartup::create_master_bus() const
1176 return _create_master_bus.get_active();
1180 ArdourStartup::master_channel_count() const
1182 return _master_bus_channel_count.get_value_as_int();
1186 ArdourStartup::connect_inputs() const
1188 return _connect_inputs.get_active();
1192 ArdourStartup::limit_inputs_used_for_connection() const
1194 return _limit_input_ports.get_active();
1198 ArdourStartup::input_limit_count() const
1200 return _input_limit_count.get_value_as_int();
1204 ArdourStartup::connect_outputs() const
1206 return _connect_outputs.get_active();
1210 ArdourStartup::limit_outputs_used_for_connection() const
1212 return _limit_output_ports.get_active();
1216 ArdourStartup::output_limit_count() const
1218 return _output_limit_count.get_value_as_int();
1222 ArdourStartup::connect_outs_to_master() const
1224 return _connect_outputs_to_master.get_active();
1228 ArdourStartup::connect_outs_to_physical() const
1230 return _connect_outputs_to_physical.get_active();
1234 ArdourStartup::connect_inputs_clicked ()
1236 _limit_input_ports.set_sensitive(_connect_inputs.get_active());
1238 if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
1239 _input_limit_count.set_sensitive(true);
1241 _input_limit_count.set_sensitive(false);
1246 ArdourStartup::connect_outputs_clicked ()
1248 bool const co = _connect_outputs.get_active ();
1249 _limit_output_ports.set_sensitive(co);
1250 _connect_outputs_to_master.set_sensitive(co);
1251 _connect_outputs_to_physical.set_sensitive(co);
1253 if (co && _limit_output_ports.get_active()) {
1254 _output_limit_count.set_sensitive(true);
1256 _output_limit_count.set_sensitive(false);
1261 ArdourStartup::limit_inputs_clicked ()
1263 _input_limit_count.set_sensitive(_limit_input_ports.get_active());
1267 ArdourStartup::limit_outputs_clicked ()
1269 _output_limit_count.set_sensitive(_limit_output_ports.get_active());
1273 ArdourStartup::master_bus_button_clicked ()
1275 bool const yn = _create_master_bus.get_active();
1277 _master_bus_channel_count.set_sensitive(yn);
1278 _connect_outputs_to_master.set_sensitive(yn);
1282 ArdourStartup::move_along_now ()
1288 ArdourStartup::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
1290 set_page_complete (ic_vbox, true);
1295 ArdourStartup::existing_session_selected ()
1297 _existing_session_chooser_used = true;
1299 session_selected ();
1300 set_page_complete (ic_vbox, true);
1305 ArdourStartup::been_here_before_path () const
1307 // XXXX use more specific version so we can catch upgrades
1308 return Glib::build_filename (user_config_directory (), ".a3");
1312 ArdourStartup::updates_button_clicked ()
1314 //now open a browser window so user can see more
1315 PBD::open_uri (Config->get_updates_url());
1319 ArdourStartup::info_scroller_update()
1321 info_scroller_count++;
1324 snprintf (buf, std::min(info_scroller_count,sizeof(buf)-1), "%s", ARDOUR_UI::instance()->announce_string().c_str() );
1325 buf[info_scroller_count] = 0;
1326 info_scroller_label.set_text (buf);
1327 info_scroller_label.show();
1329 if (info_scroller_count > ARDOUR_UI::instance()->announce_string().length()) {
1330 info_scroller_connection.disconnect();
1337 ArdourStartup::on_map ()
1339 Gtk::Assistant::on_map ();
1341 populate_session_templates ();
1343 if (!template_model->children().empty()) {
1344 use_template_button.show();
1345 template_chooser.show ();
1347 use_template_button.hide();
1348 template_chooser.hide ();
1351 if (recent_session_model) {
1352 int cnt = redisplay_recent_sessions ();
1354 recent_scroller.show();
1355 recent_label.show ();
1358 recent_scroller.set_size_request (-1, 300);
1361 recent_scroller.hide();
1362 recent_label.hide ();