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 _existing_session_chooser_used = false;
648 recent_session_display.get_selection()->unselect_all ();
649 set_current_page (new_session_page_index);
653 ArdourStartup::setup_final_page ()
655 final_page.set_text (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
657 final_page_index = append_page (final_page);
658 set_page_complete (final_page, true);
659 set_page_header_image (final_page, icon_pixbuf);
660 set_page_type (final_page, ASSISTANT_PAGE_CONFIRM);
664 ArdourStartup::on_cancel ()
666 _response = RESPONSE_CANCEL;
671 ArdourStartup::on_prepare (Gtk::Widget* page)
673 if (page == &session_new_vbox) {
675 /* if the user already defined a name by using the recent
676 * session list or browsing to an existing session
680 bool expect_new_ignored;
682 if (!session_name (expect_new_ignored).empty()) {
689 ArdourStartup::on_delete_event (GdkEventAny*)
691 _response = RESPONSE_CLOSE;
697 ArdourStartup::on_apply ()
699 if (config_modified) {
701 if (default_dir_chooser) {
702 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
705 if (monitor_via_hardware_button.get_active()) {
706 Config->set_monitoring_model (ExternalMonitoring);
707 } else if (monitor_via_ardour_button.get_active()) {
708 Config->set_monitoring_model (SoftwareMonitoring);
711 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
713 Config->save_state ();
718 /* "touch" the been-here-before path now we've successfully
719 made it through the first time setup (at least)
721 ofstream fout (been_here_before_path().c_str());
725 _response = RESPONSE_OK;
730 ArdourStartup::populate_session_templates ()
732 vector<TemplateInfo> templates;
734 find_session_templates (templates);
736 template_model->clear ();
738 for (vector<TemplateInfo>::iterator x = templates.begin(); x != templates.end(); ++x) {
741 row = *(template_model->append ());
743 row[session_template_columns.name] = (*x).name;
744 row[session_template_columns.path] = (*x).path;
749 ArdourStartup::setup_new_session_page ()
751 session_new_vbox.set_border_width (12);
752 session_new_vbox.set_spacing (18);
754 VBox *vbox1 = manage (new VBox);
755 HBox* hbox1 = manage (new HBox);
756 Label* label1 = manage (new Label);
758 vbox1->set_spacing (6);
760 hbox1->set_spacing (6);
761 hbox1->pack_start (*label1, false, false);
762 hbox1->pack_start (new_name_entry, true, true);
764 label1->set_text (_("Session name:"));
767 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
768 new_name_entry.set_text (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
769 /* name provided - they can move right along */
770 set_page_complete (session_new_vbox, true);
773 new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_changed));
774 new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &ArdourStartup::move_along_now));
776 vbox1->pack_start (*hbox1, true, true);
780 HBox* hbox2 = manage (new HBox);
781 Label* label2 = manage (new Label);
783 hbox2->set_spacing (6);
784 hbox2->pack_start (*label2, false, false);
785 hbox2->pack_start (new_folder_chooser, true, true);
787 label2->set_text (_("Create session folder in:"));
789 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
790 new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
791 } else if (ARDOUR_UI::instance()->session_loaded) {
792 // point the new session file chooser at the parent directory of the current session
793 string session_parent_dir = Glib::path_get_dirname(ARDOUR_UI::instance()->the_session()->path());
794 string::size_type last_dir_sep = session_parent_dir.rfind(G_DIR_SEPARATOR);
795 session_parent_dir = session_parent_dir.substr(0, last_dir_sep);
796 new_folder_chooser.set_current_folder (session_parent_dir);
797 string default_session_folder = poor_mans_glob (Config->get_default_session_parent_dir());
800 /* add_shortcut_folder throws an exception if the folder being added already has a shortcut */
801 new_folder_chooser.add_shortcut_folder (default_session_folder);
803 catch (Glib::Error & e) {
804 std::cerr << "new_folder_chooser.add_shortcut_folder (" << default_session_folder << ") threw Glib::Error " << e.what() << std::endl;
807 new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
809 new_folder_chooser.show ();
810 new_folder_chooser.set_title (_("Select folder for session"));
813 new_folder_chooser.add_shortcut_folder ("/Volumes");
816 vbox1->pack_start (*hbox2, false, false);
818 session_new_vbox.pack_start (*vbox1, false, false);
822 VBox *vbox2 = manage (new VBox);
823 HBox* hbox3 = manage (new HBox);
824 template_model = ListStore::create (session_template_columns);
826 vbox2->set_spacing (6);
828 VBox *vbox3 = manage (new VBox);
830 vbox3->set_spacing (6);
832 /* we may want to hide this and show it at various
833 times depending on the existence of templates.
835 template_chooser.set_no_show_all (true);
836 use_template_button.set_no_show_all (true);
838 HBox* hbox4a = manage (new HBox);
839 use_template_button.set_label (_("Use this template"));
841 TreeModel::Row row = *template_model->prepend ();
842 row[session_template_columns.name] = (_("no template"));
843 row[session_template_columns.path] = string();
845 hbox4a->set_spacing (6);
846 hbox4a->pack_start (use_template_button, false, false);
847 hbox4a->pack_start (template_chooser, true, true);
849 template_chooser.set_model (template_model);
851 Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
852 text_renderer->property_editable() = false;
854 template_chooser.pack_start (*text_renderer);
855 template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
856 template_chooser.set_active (0);
858 vbox3->pack_start (*hbox4a, false, false);
863 session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
865 HBox* hbox4b = manage (new HBox);
866 use_session_as_template_button.set_label (_("Use an existing session as a template:"));
868 hbox4b->set_spacing (6);
869 hbox4b->pack_start (use_session_as_template_button, false, false);
870 hbox4b->pack_start (session_template_chooser, true, true);
872 use_session_as_template_button.show ();
873 session_template_chooser.show ();
875 Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
876 session_filter->add_pattern (X_("*.ardour"));
877 session_template_chooser.set_filter (*session_filter);
878 session_template_chooser.set_title (_("Select template"));
880 vbox3->pack_start (*hbox4b, false, false);
885 HBox* hbox5 = manage (new HBox);
887 hbox5->set_spacing (6);
888 hbox5->pack_start (more_new_session_options_button, false, false);
890 setup_more_options_box ();
891 more_new_session_options_button.add (more_options_vbox);
893 vbox3->pack_start (*hbox5, false, false);
894 hbox3->pack_start (*vbox3, true, true, 8);
895 vbox2->pack_start (*hbox3, false, false);
899 session_new_vbox.pack_start (*vbox2, false, false);
900 session_new_vbox.show_all ();
902 new_session_page_index = append_page (session_new_vbox);
903 set_page_type (session_new_vbox, ASSISTANT_PAGE_CONTENT);
904 set_page_title (session_new_vbox, _("New Session"));
906 set_page_type (session_new_vbox, ASSISTANT_PAGE_CONFIRM);
910 ArdourStartup::new_name_changed ()
912 if (!new_name_entry.get_text().empty()) {
914 set_page_complete (session_new_vbox, true);
916 set_page_complete (session_new_vbox, false);
921 ArdourStartup::redisplay_recent_sessions ()
923 std::vector<std::string> session_directories;
924 RecentSessionsSorter cmp;
926 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
927 recent_session_model->clear ();
929 ARDOUR::RecentSessions rs;
930 ARDOUR::read_recent_sessions (rs);
933 recent_session_display.set_model (recent_session_model);
937 // sort them alphabetically
938 sort (rs.begin(), rs.end(), cmp);
940 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
941 session_directories.push_back ((*i).second);
944 int session_snapshot_count = 0;
946 for (vector<std::string>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
948 std::vector<std::string> state_file_paths;
950 // now get available states for this session
952 get_state_files_in_directory (*i, state_file_paths);
954 vector<string*>* states;
955 vector<const gchar*> item;
956 string fullpath = *i;
958 /* remove any trailing / */
960 if (fullpath[fullpath.length()-1] == '/') {
961 fullpath = fullpath.substr (0, fullpath.length()-1);
964 /* check whether session still exists */
965 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
966 /* session doesn't exist */
970 /* now get available states for this session */
972 if ((states = Session::possible_states (fullpath)) == 0) {
977 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
979 Gtk::TreeModel::Row row = *(recent_session_model->append());
981 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
982 row[recent_session_columns.fullpath] = fullpath;
983 row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
985 ++session_snapshot_count;
987 if (state_file_names.size() > 1) {
991 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
992 i2 != state_file_names.end(); ++i2) {
994 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
996 child_row[recent_session_columns.visible_name] = *i2;
997 child_row[recent_session_columns.fullpath] = fullpath;
998 child_row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
999 ++session_snapshot_count;
1004 recent_session_display.set_tooltip_column(1); // recent_session_columns.tip
1005 recent_session_display.set_model (recent_session_model);
1006 return session_snapshot_count;
1007 // return rs.size();
1011 ArdourStartup::recent_session_row_selected ()
1013 if (recent_session_display.get_selection()->count_selected_rows() > 0) {
1014 set_page_complete (ic_vbox, true);
1015 session_selected ();
1017 set_page_complete (ic_vbox, false);
1022 ArdourStartup::setup_more_options_box ()
1024 more_options_vbox.set_border_width (24);
1026 _output_limit_count.set_adjustment (_output_limit_count_adj);
1027 _input_limit_count.set_adjustment (_input_limit_count_adj);
1028 _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
1030 chan_count_label_1.set_text (_("channels"));
1031 chan_count_label_3.set_text (_("channels"));
1032 chan_count_label_4.set_text (_("channels"));
1034 chan_count_label_1.set_alignment(0,0.5);
1035 chan_count_label_1.set_padding(0,0);
1036 chan_count_label_1.set_line_wrap(false);
1038 chan_count_label_3.set_alignment(0,0.5);
1039 chan_count_label_3.set_padding(0,0);
1040 chan_count_label_3.set_line_wrap(false);
1042 chan_count_label_4.set_alignment(0,0.5);
1043 chan_count_label_4.set_padding(0,0);
1044 chan_count_label_4.set_line_wrap(false);
1046 bus_label.set_markup (_("<b>Busses</b>"));
1047 input_label.set_markup (_("<b>Inputs</b>"));
1048 output_label.set_markup (_("<b>Outputs</b>"));
1050 _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
1051 _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1052 _master_bus_channel_count.set_numeric(true);
1053 _master_bus_channel_count.set_digits(0);
1054 _master_bus_channel_count.set_wrap(false);
1056 _create_master_bus.set_label (_("Create master bus"));
1057 _create_master_bus.set_flags(Gtk::CAN_FOCUS);
1058 _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
1059 _create_master_bus.set_mode(true);
1060 _create_master_bus.set_active(true);
1061 _create_master_bus.set_border_width(0);
1063 advanced_table.set_row_spacings(0);
1064 advanced_table.set_col_spacings(0);
1066 _connect_inputs.set_label (_("Automatically connect to physical inputs"));
1067 _connect_inputs.set_flags(Gtk::CAN_FOCUS);
1068 _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
1069 _connect_inputs.set_mode(true);
1070 _connect_inputs.set_active(Config->get_input_auto_connect() != ManualConnect);
1071 _connect_inputs.set_border_width(0);
1073 _limit_input_ports.set_label (_("Use only"));
1074 _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
1075 _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
1076 _limit_input_ports.set_mode(true);
1077 _limit_input_ports.set_sensitive(true);
1078 _limit_input_ports.set_border_width(0);
1080 _input_limit_count.set_flags(Gtk::CAN_FOCUS);
1081 _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1082 _input_limit_count.set_numeric(true);
1083 _input_limit_count.set_digits(0);
1084 _input_limit_count.set_wrap(false);
1085 _input_limit_count.set_sensitive(false);
1087 bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
1089 bus_label.set_alignment(0, 0.5);
1090 bus_label.set_padding(0,0);
1091 bus_label.set_line_wrap(false);
1092 bus_label.set_selectable(false);
1093 bus_label.set_use_markup(true);
1094 bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
1095 bus_frame.set_label_align(0,0.5);
1096 bus_frame.add(bus_hbox);
1097 bus_frame.set_label_widget(bus_label);
1099 bus_table.set_row_spacings (0);
1100 bus_table.set_col_spacings (0);
1101 bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1102 bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1103 bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
1105 input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
1106 input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
1107 input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
1108 input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
1109 input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
1110 input_table.set_row_spacings(0);
1111 input_table.set_col_spacings(0);
1112 input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
1114 input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
1116 input_label.set_alignment(0, 0.5);
1117 input_label.set_padding(0,0);
1118 input_label.set_line_wrap(false);
1119 input_label.set_selectable(false);
1120 input_label.set_use_markup(true);
1121 input_frame.set_shadow_type(Gtk::SHADOW_NONE);
1122 input_frame.set_label_align(0,0.5);
1123 input_frame.add(input_hbox);
1124 input_frame.set_label_widget(input_label);
1126 _connect_outputs.set_label (_("Automatically connect outputs"));
1127 _connect_outputs.set_flags(Gtk::CAN_FOCUS);
1128 _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
1129 _connect_outputs.set_mode(true);
1130 _connect_outputs.set_active(Config->get_output_auto_connect() != ManualConnect);
1131 _connect_outputs.set_border_width(0);
1132 _limit_output_ports.set_label (_("Use only"));
1133 _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
1134 _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
1135 _limit_output_ports.set_mode(true);
1136 _limit_output_ports.set_sensitive(true);
1137 _limit_output_ports.set_border_width(0);
1138 _output_limit_count.set_flags(Gtk::CAN_FOCUS);
1139 _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1140 _output_limit_count.set_numeric(false);
1141 _output_limit_count.set_digits(0);
1142 _output_limit_count.set_wrap(false);
1143 _output_limit_count.set_sensitive(false);
1144 output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
1145 output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
1146 output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
1148 _connect_outputs_to_master.set_label (_("... to master bus"));
1149 _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
1150 _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
1151 _connect_outputs_to_master.set_mode(true);
1152 _connect_outputs_to_master.set_active(Config->get_output_auto_connect() == AutoConnectMaster);
1153 _connect_outputs_to_master.set_border_width(0);
1155 _connect_outputs_to_master.set_group (connect_outputs_group);
1156 _connect_outputs_to_physical.set_group (connect_outputs_group);
1158 _connect_outputs_to_physical.set_label (_("... to physical outputs"));
1159 _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
1160 _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
1161 _connect_outputs_to_physical.set_mode(true);
1162 _connect_outputs_to_physical.set_active(Config->get_output_auto_connect() == AutoConnectPhysical);
1163 _connect_outputs_to_physical.set_border_width(0);
1165 output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
1166 output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
1167 output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
1168 output_vbox.set_border_width(6);
1170 output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
1172 output_vbox.pack_start(output_conn_vbox);
1173 output_vbox.pack_start(output_port_vbox);
1175 output_label.set_alignment(0, 0.5);
1176 output_label.set_padding(0,0);
1177 output_label.set_line_wrap(false);
1178 output_label.set_selectable(false);
1179 output_label.set_use_markup(true);
1180 output_frame.set_shadow_type(Gtk::SHADOW_NONE);
1181 output_frame.set_label_align(0,0.5);
1183 output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
1185 output_frame.add(output_hbox);
1186 output_frame.set_label_widget(output_label);
1188 more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
1189 more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
1190 more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
1191 more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
1195 _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
1196 _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
1197 _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
1198 _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
1199 _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
1201 /* note that more_options_vbox is "visible" by default even
1202 * though it may not be displayed to the user, this is so the dialog
1205 more_options_vbox.show_all ();
1209 ArdourStartup::create_master_bus() const
1211 return _create_master_bus.get_active();
1215 ArdourStartup::master_channel_count() const
1217 return _master_bus_channel_count.get_value_as_int();
1221 ArdourStartup::connect_inputs() const
1223 return _connect_inputs.get_active();
1227 ArdourStartup::limit_inputs_used_for_connection() const
1229 return _limit_input_ports.get_active();
1233 ArdourStartup::input_limit_count() const
1235 return _input_limit_count.get_value_as_int();
1239 ArdourStartup::connect_outputs() const
1241 return _connect_outputs.get_active();
1245 ArdourStartup::limit_outputs_used_for_connection() const
1247 return _limit_output_ports.get_active();
1251 ArdourStartup::output_limit_count() const
1253 return _output_limit_count.get_value_as_int();
1257 ArdourStartup::connect_outs_to_master() const
1259 return _connect_outputs_to_master.get_active();
1263 ArdourStartup::connect_outs_to_physical() const
1265 return _connect_outputs_to_physical.get_active();
1269 ArdourStartup::connect_inputs_clicked ()
1271 _limit_input_ports.set_sensitive(_connect_inputs.get_active());
1273 if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
1274 _input_limit_count.set_sensitive(true);
1276 _input_limit_count.set_sensitive(false);
1281 ArdourStartup::connect_outputs_clicked ()
1283 bool const co = _connect_outputs.get_active ();
1284 _limit_output_ports.set_sensitive(co);
1285 _connect_outputs_to_master.set_sensitive(co);
1286 _connect_outputs_to_physical.set_sensitive(co);
1288 if (co && _limit_output_ports.get_active()) {
1289 _output_limit_count.set_sensitive(true);
1291 _output_limit_count.set_sensitive(false);
1296 ArdourStartup::limit_inputs_clicked ()
1298 _input_limit_count.set_sensitive(_limit_input_ports.get_active());
1302 ArdourStartup::limit_outputs_clicked ()
1304 _output_limit_count.set_sensitive(_limit_output_ports.get_active());
1308 ArdourStartup::master_bus_button_clicked ()
1310 bool const yn = _create_master_bus.get_active();
1312 _master_bus_channel_count.set_sensitive(yn);
1313 _connect_outputs_to_master.set_sensitive(yn);
1317 ArdourStartup::move_along_now ()
1323 ArdourStartup::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
1325 set_page_complete (ic_vbox, true);
1330 ArdourStartup::existing_session_selected ()
1332 _existing_session_chooser_used = true;
1334 session_selected ();
1335 set_page_complete (ic_vbox, true);
1340 ArdourStartup::been_here_before_path () const
1342 // XXXX use more specific version so we can catch upgrades
1343 return Glib::build_filename (user_config_directory (), ".a3");
1347 ArdourStartup::updates_button_clicked ()
1349 //now open a browser window so user can see more
1350 PBD::open_uri (Config->get_updates_url());
1354 ArdourStartup::info_scroller_update()
1356 info_scroller_count++;
1359 snprintf (buf, std::min(info_scroller_count,sizeof(buf)-1), "%s", ARDOUR_UI::instance()->announce_string().c_str() );
1360 buf[info_scroller_count] = 0;
1361 info_scroller_label.set_text (buf);
1362 info_scroller_label.show();
1364 if (info_scroller_count > ARDOUR_UI::instance()->announce_string().length()) {
1365 info_scroller_connection.disconnect();
1372 ArdourStartup::on_map ()
1374 Gtk::Assistant::on_map ();
1376 redisplay_recent_sessions ();
1377 populate_session_templates ();
1379 if (!template_model->children().empty()) {
1380 use_template_button.show();
1381 template_chooser.show ();
1383 use_template_button.hide();
1384 template_chooser.hide ();