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 ARDOUR::RecentSessions rs;
550 ARDOUR::read_recent_sessions (rs);
554 /* recent session scroller */
556 Label* load_label = manage (new Label);
557 load_label->set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", _("Load a recent session")));
558 load_label->set_alignment (0, 0.5);
560 centering_vbox->pack_start (*load_label, false, false, 12);
562 recent_session_model = TreeStore::create (recent_session_columns);
563 redisplay_recent_sessions ();
565 recent_session_display.set_model (recent_session_model);
566 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
567 recent_session_display.set_headers_visible (false);
568 recent_session_display.get_selection()->set_mode (SELECTION_SINGLE);
570 recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::recent_session_row_selected));
572 recent_scroller.add (recent_session_display);
573 recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
574 recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
576 recent_session_display.show();
578 recent_scroller.show();
579 recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ArdourStartup::recent_row_activated));
581 int cnt = redisplay_recent_sessions ();
583 recent_scroller.set_size_request (-1, 300);
586 centering_vbox->pack_start (recent_scroller, false, true);
591 existing_session_chooser.set_title (_("Select session file"));
592 existing_session_chooser.signal_file_set().connect (sigc::mem_fun (*this, &ArdourStartup::existing_session_selected));
593 existing_session_chooser.set_current_folder(poor_mans_glob (Config->get_default_session_parent_dir()));
595 FileFilter session_filter;
596 session_filter.add_pattern ("*.ardour");
597 session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
598 existing_session_chooser.add_filter (session_filter);
599 existing_session_chooser.set_filter (session_filter);
602 existing_session_chooser.add_shortcut_folder ("/Volumes");
605 Label* browse_label = manage (new Label);
606 browse_label->set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", _("Browse for other sessions")));
607 browse_label->set_alignment (0, 0.5);
609 centering_vbox->pack_start (*browse_label, false, false, 12);
610 centering_vbox->pack_start (existing_session_chooser, false, false);
614 centering_hbox->pack_start (*centering_vbox, true, true);
615 ic_vbox.pack_start (*centering_hbox, true, true);
618 /* user could just click on "Forward" if default
622 set_page_complete (ic_vbox, true);
626 ArdourStartup::session_selected ()
628 /* HACK HACK HACK ... change the "Apply" button label
632 Gtk::Widget* tl = ic_vbox.get_toplevel();
634 if ((win = dynamic_cast<Gtk::Window*>(tl)) != 0) {
635 /* ::get_default_widget() is not wrapped in gtkmm */
636 Gtk::Widget* def = wrap (gtk_window_get_default_widget (win->gobj()));
638 if ((button = dynamic_cast<Gtk::Button*>(def)) != 0) {
639 button->set_label (_("Open"));
645 ArdourStartup::new_session_button_clicked ()
647 set_current_page (new_session_page_index);
651 ArdourStartup::setup_final_page ()
653 final_page.set_text (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
655 final_page_index = append_page (final_page);
656 set_page_complete (final_page, true);
657 set_page_header_image (final_page, icon_pixbuf);
658 set_page_type (final_page, ASSISTANT_PAGE_CONFIRM);
662 ArdourStartup::on_cancel ()
664 _response = RESPONSE_CANCEL;
669 ArdourStartup::on_prepare (Gtk::Widget* page)
671 if (page == &session_new_vbox) {
673 /* if the user already defined a name by using the recent
674 * session list or browsing to an existing session
678 bool expect_new_ignored;
680 if (!session_name (expect_new_ignored).empty()) {
687 ArdourStartup::on_delete_event (GdkEventAny*)
689 _response = RESPONSE_CLOSE;
695 ArdourStartup::on_apply ()
697 if (config_modified) {
699 if (default_dir_chooser) {
700 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
703 if (monitor_via_hardware_button.get_active()) {
704 Config->set_monitoring_model (ExternalMonitoring);
705 } else if (monitor_via_ardour_button.get_active()) {
706 Config->set_monitoring_model (SoftwareMonitoring);
709 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
711 Config->save_state ();
716 /* "touch" the been-here-before path now we've successfully
717 made it through the first time setup (at least)
719 ofstream fout (been_here_before_path().c_str());
723 _response = RESPONSE_OK;
728 ArdourStartup::populate_session_templates ()
730 vector<TemplateInfo> templates;
732 find_session_templates (templates);
734 template_model->clear ();
736 for (vector<TemplateInfo>::iterator x = templates.begin(); x != templates.end(); ++x) {
739 row = *(template_model->append ());
741 row[session_template_columns.name] = (*x).name;
742 row[session_template_columns.path] = (*x).path;
747 ArdourStartup::setup_new_session_page ()
749 session_new_vbox.set_border_width (12);
750 session_new_vbox.set_spacing (18);
752 if (session_new_vbox.get_children().empty()) {
753 VBox *vbox1 = manage (new VBox);
754 HBox* hbox1 = manage (new HBox);
755 Label* label1 = manage (new Label);
757 vbox1->set_spacing (6);
759 hbox1->set_spacing (6);
760 hbox1->pack_start (*label1, false, false);
761 hbox1->pack_start (new_name_entry, true, true);
763 label1->set_text (_("Session name:"));
766 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
767 new_name_entry.set_text (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
768 /* name provided - they can move right along */
769 set_page_complete (session_new_vbox, true);
772 new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_changed));
773 new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &ArdourStartup::move_along_now));
775 vbox1->pack_start (*hbox1, true, true);
779 HBox* hbox2 = manage (new HBox);
780 Label* label2 = manage (new Label);
782 hbox2->set_spacing (6);
783 hbox2->pack_start (*label2, false, false);
784 hbox2->pack_start (new_folder_chooser, true, true);
786 label2->set_text (_("Create session folder in:"));
788 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
789 new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
790 } else if (ARDOUR_UI::instance()->session_loaded) {
791 // point the new session file chooser at the parent directory of the current session
792 string session_parent_dir = Glib::path_get_dirname(ARDOUR_UI::instance()->the_session()->path());
793 string::size_type last_dir_sep = session_parent_dir.rfind(G_DIR_SEPARATOR);
794 session_parent_dir = session_parent_dir.substr(0, last_dir_sep);
795 new_folder_chooser.set_current_folder (session_parent_dir);
796 string default_session_folder = poor_mans_glob (Config->get_default_session_parent_dir());
799 /* add_shortcut_folder throws an exception if the folder being added already has a shortcut */
800 new_folder_chooser.add_shortcut_folder (default_session_folder);
802 catch (Glib::Error & e) {
803 std::cerr << "new_folder_chooser.add_shortcut_folder (" << default_session_folder << ") threw Glib::Error " << e.what() << std::endl;
806 new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
808 new_folder_chooser.show ();
809 new_folder_chooser.set_title (_("Select folder for session"));
812 new_folder_chooser.add_shortcut_folder ("/Volumes");
815 vbox1->pack_start (*hbox2, false, false);
817 session_new_vbox.pack_start (*vbox1, false, false);
821 VBox *vbox2 = manage (new VBox);
822 HBox* hbox3 = manage (new HBox);
823 Label* label3 = manage (new Label);
824 template_model = ListStore::create (session_template_columns);
825 populate_session_templates ();
827 vbox2->set_spacing (6);
829 VBox *vbox3 = manage (new VBox);
831 vbox3->set_spacing (6);
833 if (!template_model->children().empty()) {
835 HBox* hbox4a = manage (new HBox);
836 use_template_button.set_label (_("Use this template"));
838 TreeModel::Row row = *template_model->prepend ();
839 row[session_template_columns.name] = (_("no template"));
840 row[session_template_columns.path] = string();
842 hbox4a->set_spacing (6);
843 hbox4a->pack_start (use_template_button, false, false);
844 hbox4a->pack_start (template_chooser, true, true);
846 template_chooser.set_model (template_model);
848 Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
849 text_renderer->property_editable() = false;
851 template_chooser.pack_start (*text_renderer);
852 template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
853 template_chooser.set_active (0);
855 use_template_button.show();
856 template_chooser.show ();
858 vbox3->pack_start (*hbox4a, false, false);
864 session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
866 HBox* hbox4b = manage (new HBox);
867 use_session_as_template_button.set_label (_("Use an existing session as a template:"));
869 hbox4b->set_spacing (6);
870 hbox4b->pack_start (use_session_as_template_button, false, false);
871 hbox4b->pack_start (session_template_chooser, true, true);
873 use_session_as_template_button.show ();
874 session_template_chooser.show ();
876 Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
877 session_filter->add_pattern (X_("*.ardour"));
878 session_template_chooser.set_filter (*session_filter);
879 session_template_chooser.set_title (_("Select template"));
881 vbox3->pack_start (*hbox4b, false, false);
886 HBox* hbox5 = manage (new HBox);
888 hbox5->set_spacing (6);
889 hbox5->pack_start (more_new_session_options_button, false, false);
891 setup_more_options_box ();
892 more_new_session_options_button.add (more_options_vbox);
894 vbox3->pack_start (*hbox5, false, false);
895 hbox3->pack_start (*vbox3, true, true, 8);
896 vbox2->pack_start (*hbox3, false, false);
900 session_new_vbox.pack_start (*vbox2, false, false);
903 session_new_vbox.show_all ();
905 new_session_page_index = append_page (session_new_vbox);
906 set_page_type (session_new_vbox, ASSISTANT_PAGE_CONTENT);
907 set_page_title (session_new_vbox, _("New Session"));
909 set_page_type (session_new_vbox, ASSISTANT_PAGE_CONFIRM);
913 ArdourStartup::new_name_changed ()
915 if (!new_name_entry.get_text().empty()) {
917 set_page_complete (session_new_vbox, true);
919 set_page_complete (session_new_vbox, false);
924 ArdourStartup::redisplay_recent_sessions ()
926 std::vector<std::string> session_directories;
927 RecentSessionsSorter cmp;
929 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
930 recent_session_model->clear ();
932 ARDOUR::RecentSessions rs;
933 ARDOUR::read_recent_sessions (rs);
936 recent_session_display.set_model (recent_session_model);
940 // sort them alphabetically
941 sort (rs.begin(), rs.end(), cmp);
943 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
944 session_directories.push_back ((*i).second);
947 int session_snapshot_count = 0;
949 for (vector<std::string>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
951 std::vector<std::string> state_file_paths;
953 // now get available states for this session
955 get_state_files_in_directory (*i, state_file_paths);
957 vector<string*>* states;
958 vector<const gchar*> item;
959 string fullpath = *i;
961 /* remove any trailing / */
963 if (fullpath[fullpath.length()-1] == '/') {
964 fullpath = fullpath.substr (0, fullpath.length()-1);
967 /* check whether session still exists */
968 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
969 /* session doesn't exist */
973 /* now get available states for this session */
975 if ((states = Session::possible_states (fullpath)) == 0) {
980 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
982 Gtk::TreeModel::Row row = *(recent_session_model->append());
984 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
985 row[recent_session_columns.fullpath] = fullpath;
986 row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
988 ++session_snapshot_count;
990 if (state_file_names.size() > 1) {
994 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
995 i2 != state_file_names.end(); ++i2) {
997 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
999 child_row[recent_session_columns.visible_name] = *i2;
1000 child_row[recent_session_columns.fullpath] = fullpath;
1001 child_row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
1002 ++session_snapshot_count;
1007 recent_session_display.set_tooltip_column(1); // recent_session_columns.tip
1008 recent_session_display.set_model (recent_session_model);
1009 return session_snapshot_count;
1010 // return rs.size();
1014 ArdourStartup::recent_session_row_selected ()
1016 if (recent_session_display.get_selection()->count_selected_rows() > 0) {
1017 set_page_complete (ic_vbox, true);
1018 session_selected ();
1020 set_page_complete (ic_vbox, false);
1025 ArdourStartup::setup_more_options_box ()
1027 more_options_vbox.set_border_width (24);
1029 _output_limit_count.set_adjustment (_output_limit_count_adj);
1030 _input_limit_count.set_adjustment (_input_limit_count_adj);
1031 _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
1033 chan_count_label_1.set_text (_("channels"));
1034 chan_count_label_3.set_text (_("channels"));
1035 chan_count_label_4.set_text (_("channels"));
1037 chan_count_label_1.set_alignment(0,0.5);
1038 chan_count_label_1.set_padding(0,0);
1039 chan_count_label_1.set_line_wrap(false);
1041 chan_count_label_3.set_alignment(0,0.5);
1042 chan_count_label_3.set_padding(0,0);
1043 chan_count_label_3.set_line_wrap(false);
1045 chan_count_label_4.set_alignment(0,0.5);
1046 chan_count_label_4.set_padding(0,0);
1047 chan_count_label_4.set_line_wrap(false);
1049 bus_label.set_markup (_("<b>Busses</b>"));
1050 input_label.set_markup (_("<b>Inputs</b>"));
1051 output_label.set_markup (_("<b>Outputs</b>"));
1053 _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
1054 _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1055 _master_bus_channel_count.set_numeric(true);
1056 _master_bus_channel_count.set_digits(0);
1057 _master_bus_channel_count.set_wrap(false);
1059 _create_master_bus.set_label (_("Create master bus"));
1060 _create_master_bus.set_flags(Gtk::CAN_FOCUS);
1061 _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
1062 _create_master_bus.set_mode(true);
1063 _create_master_bus.set_active(true);
1064 _create_master_bus.set_border_width(0);
1066 advanced_table.set_row_spacings(0);
1067 advanced_table.set_col_spacings(0);
1069 _connect_inputs.set_label (_("Automatically connect to physical inputs"));
1070 _connect_inputs.set_flags(Gtk::CAN_FOCUS);
1071 _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
1072 _connect_inputs.set_mode(true);
1073 _connect_inputs.set_active(Config->get_input_auto_connect() != ManualConnect);
1074 _connect_inputs.set_border_width(0);
1076 _limit_input_ports.set_label (_("Use only"));
1077 _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
1078 _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
1079 _limit_input_ports.set_mode(true);
1080 _limit_input_ports.set_sensitive(true);
1081 _limit_input_ports.set_border_width(0);
1083 _input_limit_count.set_flags(Gtk::CAN_FOCUS);
1084 _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1085 _input_limit_count.set_numeric(true);
1086 _input_limit_count.set_digits(0);
1087 _input_limit_count.set_wrap(false);
1088 _input_limit_count.set_sensitive(false);
1090 bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
1092 bus_label.set_alignment(0, 0.5);
1093 bus_label.set_padding(0,0);
1094 bus_label.set_line_wrap(false);
1095 bus_label.set_selectable(false);
1096 bus_label.set_use_markup(true);
1097 bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
1098 bus_frame.set_label_align(0,0.5);
1099 bus_frame.add(bus_hbox);
1100 bus_frame.set_label_widget(bus_label);
1102 bus_table.set_row_spacings (0);
1103 bus_table.set_col_spacings (0);
1104 bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1105 bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1106 bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
1108 input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
1109 input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
1110 input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
1111 input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
1112 input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
1113 input_table.set_row_spacings(0);
1114 input_table.set_col_spacings(0);
1115 input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
1117 input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
1119 input_label.set_alignment(0, 0.5);
1120 input_label.set_padding(0,0);
1121 input_label.set_line_wrap(false);
1122 input_label.set_selectable(false);
1123 input_label.set_use_markup(true);
1124 input_frame.set_shadow_type(Gtk::SHADOW_NONE);
1125 input_frame.set_label_align(0,0.5);
1126 input_frame.add(input_hbox);
1127 input_frame.set_label_widget(input_label);
1129 _connect_outputs.set_label (_("Automatically connect outputs"));
1130 _connect_outputs.set_flags(Gtk::CAN_FOCUS);
1131 _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
1132 _connect_outputs.set_mode(true);
1133 _connect_outputs.set_active(Config->get_output_auto_connect() != ManualConnect);
1134 _connect_outputs.set_border_width(0);
1135 _limit_output_ports.set_label (_("Use only"));
1136 _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
1137 _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
1138 _limit_output_ports.set_mode(true);
1139 _limit_output_ports.set_sensitive(true);
1140 _limit_output_ports.set_border_width(0);
1141 _output_limit_count.set_flags(Gtk::CAN_FOCUS);
1142 _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1143 _output_limit_count.set_numeric(false);
1144 _output_limit_count.set_digits(0);
1145 _output_limit_count.set_wrap(false);
1146 _output_limit_count.set_sensitive(false);
1147 output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
1148 output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
1149 output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
1151 _connect_outputs_to_master.set_label (_("... to master bus"));
1152 _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
1153 _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
1154 _connect_outputs_to_master.set_mode(true);
1155 _connect_outputs_to_master.set_active(Config->get_output_auto_connect() == AutoConnectMaster);
1156 _connect_outputs_to_master.set_border_width(0);
1158 _connect_outputs_to_master.set_group (connect_outputs_group);
1159 _connect_outputs_to_physical.set_group (connect_outputs_group);
1161 _connect_outputs_to_physical.set_label (_("... to physical outputs"));
1162 _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
1163 _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
1164 _connect_outputs_to_physical.set_mode(true);
1165 _connect_outputs_to_physical.set_active(Config->get_output_auto_connect() == AutoConnectPhysical);
1166 _connect_outputs_to_physical.set_border_width(0);
1168 output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
1169 output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
1170 output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
1171 output_vbox.set_border_width(6);
1173 output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
1175 output_vbox.pack_start(output_conn_vbox);
1176 output_vbox.pack_start(output_port_vbox);
1178 output_label.set_alignment(0, 0.5);
1179 output_label.set_padding(0,0);
1180 output_label.set_line_wrap(false);
1181 output_label.set_selectable(false);
1182 output_label.set_use_markup(true);
1183 output_frame.set_shadow_type(Gtk::SHADOW_NONE);
1184 output_frame.set_label_align(0,0.5);
1186 output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
1188 output_frame.add(output_hbox);
1189 output_frame.set_label_widget(output_label);
1191 more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
1192 more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
1193 more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
1194 more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
1198 _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
1199 _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
1200 _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
1201 _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
1202 _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
1204 /* note that more_options_vbox is "visible" by default even
1205 * though it may not be displayed to the user, this is so the dialog
1208 more_options_vbox.show_all ();
1212 ArdourStartup::create_master_bus() const
1214 return _create_master_bus.get_active();
1218 ArdourStartup::master_channel_count() const
1220 return _master_bus_channel_count.get_value_as_int();
1224 ArdourStartup::connect_inputs() const
1226 return _connect_inputs.get_active();
1230 ArdourStartup::limit_inputs_used_for_connection() const
1232 return _limit_input_ports.get_active();
1236 ArdourStartup::input_limit_count() const
1238 return _input_limit_count.get_value_as_int();
1242 ArdourStartup::connect_outputs() const
1244 return _connect_outputs.get_active();
1248 ArdourStartup::limit_outputs_used_for_connection() const
1250 return _limit_output_ports.get_active();
1254 ArdourStartup::output_limit_count() const
1256 return _output_limit_count.get_value_as_int();
1260 ArdourStartup::connect_outs_to_master() const
1262 return _connect_outputs_to_master.get_active();
1266 ArdourStartup::connect_outs_to_physical() const
1268 return _connect_outputs_to_physical.get_active();
1272 ArdourStartup::connect_inputs_clicked ()
1274 _limit_input_ports.set_sensitive(_connect_inputs.get_active());
1276 if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
1277 _input_limit_count.set_sensitive(true);
1279 _input_limit_count.set_sensitive(false);
1284 ArdourStartup::connect_outputs_clicked ()
1286 bool const co = _connect_outputs.get_active ();
1287 _limit_output_ports.set_sensitive(co);
1288 _connect_outputs_to_master.set_sensitive(co);
1289 _connect_outputs_to_physical.set_sensitive(co);
1291 if (co && _limit_output_ports.get_active()) {
1292 _output_limit_count.set_sensitive(true);
1294 _output_limit_count.set_sensitive(false);
1299 ArdourStartup::limit_inputs_clicked ()
1301 _input_limit_count.set_sensitive(_limit_input_ports.get_active());
1305 ArdourStartup::limit_outputs_clicked ()
1307 _output_limit_count.set_sensitive(_limit_output_ports.get_active());
1311 ArdourStartup::master_bus_button_clicked ()
1313 bool const yn = _create_master_bus.get_active();
1315 _master_bus_channel_count.set_sensitive(yn);
1316 _connect_outputs_to_master.set_sensitive(yn);
1320 ArdourStartup::move_along_now ()
1326 ArdourStartup::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
1328 set_page_complete (ic_vbox, true);
1333 ArdourStartup::existing_session_selected ()
1335 _existing_session_chooser_used = true;
1337 session_selected ();
1338 set_page_complete (ic_vbox, true);
1343 ArdourStartup::been_here_before_path () const
1345 // XXXX use more specific version so we can catch upgrades
1346 return Glib::build_filename (user_config_directory (), ".a3");
1350 ArdourStartup::updates_button_clicked ()
1352 //now open a browser window so user can see more
1353 PBD::open_uri (Config->get_updates_url());
1357 ArdourStartup::info_scroller_update()
1359 info_scroller_count++;
1362 snprintf (buf, std::min(info_scroller_count,sizeof(buf)-1), "%s", ARDOUR_UI::instance()->announce_string().c_str() );
1363 buf[info_scroller_count] = 0;
1364 info_scroller_label.set_text (buf);
1365 info_scroller_label.show();
1367 if (info_scroller_count > ARDOUR_UI::instance()->announce_string().length()) {
1368 info_scroller_connection.disconnect();