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 if (session_new_vbox.get_children().empty()) {
755 VBox *vbox1 = manage (new VBox);
756 HBox* hbox1 = manage (new HBox);
757 Label* label1 = manage (new Label);
759 vbox1->set_spacing (6);
761 hbox1->set_spacing (6);
762 hbox1->pack_start (*label1, false, false);
763 hbox1->pack_start (new_name_entry, true, true);
765 label1->set_text (_("Session name:"));
768 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
769 new_name_entry.set_text (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
770 /* name provided - they can move right along */
771 set_page_complete (session_new_vbox, true);
774 new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_changed));
775 new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &ArdourStartup::move_along_now));
777 vbox1->pack_start (*hbox1, true, true);
781 HBox* hbox2 = manage (new HBox);
782 Label* label2 = manage (new Label);
784 hbox2->set_spacing (6);
785 hbox2->pack_start (*label2, false, false);
786 hbox2->pack_start (new_folder_chooser, true, true);
788 label2->set_text (_("Create session folder in:"));
790 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
791 new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
792 } else if (ARDOUR_UI::instance()->session_loaded) {
793 // point the new session file chooser at the parent directory of the current session
794 string session_parent_dir = Glib::path_get_dirname(ARDOUR_UI::instance()->the_session()->path());
795 string::size_type last_dir_sep = session_parent_dir.rfind(G_DIR_SEPARATOR);
796 session_parent_dir = session_parent_dir.substr(0, last_dir_sep);
797 new_folder_chooser.set_current_folder (session_parent_dir);
798 string default_session_folder = poor_mans_glob (Config->get_default_session_parent_dir());
801 /* add_shortcut_folder throws an exception if the folder being added already has a shortcut */
802 new_folder_chooser.add_shortcut_folder (default_session_folder);
804 catch (Glib::Error & e) {
805 std::cerr << "new_folder_chooser.add_shortcut_folder (" << default_session_folder << ") threw Glib::Error " << e.what() << std::endl;
808 new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
810 new_folder_chooser.show ();
811 new_folder_chooser.set_title (_("Select folder for session"));
814 new_folder_chooser.add_shortcut_folder ("/Volumes");
817 vbox1->pack_start (*hbox2, false, false);
819 session_new_vbox.pack_start (*vbox1, false, false);
823 VBox *vbox2 = manage (new VBox);
824 HBox* hbox3 = manage (new HBox);
825 Label* label3 = manage (new Label);
826 template_model = ListStore::create (session_template_columns);
827 populate_session_templates ();
829 vbox2->set_spacing (6);
831 VBox *vbox3 = manage (new VBox);
833 vbox3->set_spacing (6);
835 if (!template_model->children().empty()) {
837 HBox* hbox4a = manage (new HBox);
838 use_template_button.set_label (_("Use this template"));
840 TreeModel::Row row = *template_model->prepend ();
841 row[session_template_columns.name] = (_("no template"));
842 row[session_template_columns.path] = string();
844 hbox4a->set_spacing (6);
845 hbox4a->pack_start (use_template_button, false, false);
846 hbox4a->pack_start (template_chooser, true, true);
848 template_chooser.set_model (template_model);
850 Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
851 text_renderer->property_editable() = false;
853 template_chooser.pack_start (*text_renderer);
854 template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
855 template_chooser.set_active (0);
857 use_template_button.show();
858 template_chooser.show ();
860 vbox3->pack_start (*hbox4a, false, false);
866 session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
868 HBox* hbox4b = manage (new HBox);
869 use_session_as_template_button.set_label (_("Use an existing session as a template:"));
871 hbox4b->set_spacing (6);
872 hbox4b->pack_start (use_session_as_template_button, false, false);
873 hbox4b->pack_start (session_template_chooser, true, true);
875 use_session_as_template_button.show ();
876 session_template_chooser.show ();
878 Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
879 session_filter->add_pattern (X_("*.ardour"));
880 session_template_chooser.set_filter (*session_filter);
881 session_template_chooser.set_title (_("Select template"));
883 vbox3->pack_start (*hbox4b, false, false);
888 HBox* hbox5 = manage (new HBox);
890 hbox5->set_spacing (6);
891 hbox5->pack_start (more_new_session_options_button, false, false);
893 setup_more_options_box ();
894 more_new_session_options_button.add (more_options_vbox);
896 vbox3->pack_start (*hbox5, false, false);
897 hbox3->pack_start (*vbox3, true, true, 8);
898 vbox2->pack_start (*hbox3, false, false);
902 session_new_vbox.pack_start (*vbox2, false, false);
905 session_new_vbox.show_all ();
907 new_session_page_index = append_page (session_new_vbox);
908 set_page_type (session_new_vbox, ASSISTANT_PAGE_CONTENT);
909 set_page_title (session_new_vbox, _("New Session"));
911 set_page_type (session_new_vbox, ASSISTANT_PAGE_CONFIRM);
915 ArdourStartup::new_name_changed ()
917 if (!new_name_entry.get_text().empty()) {
919 set_page_complete (session_new_vbox, true);
921 set_page_complete (session_new_vbox, false);
926 ArdourStartup::redisplay_recent_sessions ()
928 std::vector<std::string> session_directories;
929 RecentSessionsSorter cmp;
931 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
932 recent_session_model->clear ();
934 ARDOUR::RecentSessions rs;
935 ARDOUR::read_recent_sessions (rs);
938 recent_session_display.set_model (recent_session_model);
942 // sort them alphabetically
943 sort (rs.begin(), rs.end(), cmp);
945 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
946 session_directories.push_back ((*i).second);
949 int session_snapshot_count = 0;
951 for (vector<std::string>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
953 std::vector<std::string> state_file_paths;
955 // now get available states for this session
957 get_state_files_in_directory (*i, state_file_paths);
959 vector<string*>* states;
960 vector<const gchar*> item;
961 string fullpath = *i;
963 /* remove any trailing / */
965 if (fullpath[fullpath.length()-1] == '/') {
966 fullpath = fullpath.substr (0, fullpath.length()-1);
969 /* check whether session still exists */
970 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
971 /* session doesn't exist */
975 /* now get available states for this session */
977 if ((states = Session::possible_states (fullpath)) == 0) {
982 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
984 Gtk::TreeModel::Row row = *(recent_session_model->append());
986 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
987 row[recent_session_columns.fullpath] = fullpath;
988 row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
990 ++session_snapshot_count;
992 if (state_file_names.size() > 1) {
996 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
997 i2 != state_file_names.end(); ++i2) {
999 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
1001 child_row[recent_session_columns.visible_name] = *i2;
1002 child_row[recent_session_columns.fullpath] = fullpath;
1003 child_row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
1004 ++session_snapshot_count;
1009 recent_session_display.set_tooltip_column(1); // recent_session_columns.tip
1010 recent_session_display.set_model (recent_session_model);
1011 return session_snapshot_count;
1012 // return rs.size();
1016 ArdourStartup::recent_session_row_selected ()
1018 if (recent_session_display.get_selection()->count_selected_rows() > 0) {
1019 set_page_complete (ic_vbox, true);
1020 session_selected ();
1022 set_page_complete (ic_vbox, false);
1027 ArdourStartup::setup_more_options_box ()
1029 more_options_vbox.set_border_width (24);
1031 _output_limit_count.set_adjustment (_output_limit_count_adj);
1032 _input_limit_count.set_adjustment (_input_limit_count_adj);
1033 _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
1035 chan_count_label_1.set_text (_("channels"));
1036 chan_count_label_3.set_text (_("channels"));
1037 chan_count_label_4.set_text (_("channels"));
1039 chan_count_label_1.set_alignment(0,0.5);
1040 chan_count_label_1.set_padding(0,0);
1041 chan_count_label_1.set_line_wrap(false);
1043 chan_count_label_3.set_alignment(0,0.5);
1044 chan_count_label_3.set_padding(0,0);
1045 chan_count_label_3.set_line_wrap(false);
1047 chan_count_label_4.set_alignment(0,0.5);
1048 chan_count_label_4.set_padding(0,0);
1049 chan_count_label_4.set_line_wrap(false);
1051 bus_label.set_markup (_("<b>Busses</b>"));
1052 input_label.set_markup (_("<b>Inputs</b>"));
1053 output_label.set_markup (_("<b>Outputs</b>"));
1055 _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
1056 _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1057 _master_bus_channel_count.set_numeric(true);
1058 _master_bus_channel_count.set_digits(0);
1059 _master_bus_channel_count.set_wrap(false);
1061 _create_master_bus.set_label (_("Create master bus"));
1062 _create_master_bus.set_flags(Gtk::CAN_FOCUS);
1063 _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
1064 _create_master_bus.set_mode(true);
1065 _create_master_bus.set_active(true);
1066 _create_master_bus.set_border_width(0);
1068 advanced_table.set_row_spacings(0);
1069 advanced_table.set_col_spacings(0);
1071 _connect_inputs.set_label (_("Automatically connect to physical inputs"));
1072 _connect_inputs.set_flags(Gtk::CAN_FOCUS);
1073 _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
1074 _connect_inputs.set_mode(true);
1075 _connect_inputs.set_active(Config->get_input_auto_connect() != ManualConnect);
1076 _connect_inputs.set_border_width(0);
1078 _limit_input_ports.set_label (_("Use only"));
1079 _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
1080 _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
1081 _limit_input_ports.set_mode(true);
1082 _limit_input_ports.set_sensitive(true);
1083 _limit_input_ports.set_border_width(0);
1085 _input_limit_count.set_flags(Gtk::CAN_FOCUS);
1086 _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1087 _input_limit_count.set_numeric(true);
1088 _input_limit_count.set_digits(0);
1089 _input_limit_count.set_wrap(false);
1090 _input_limit_count.set_sensitive(false);
1092 bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
1094 bus_label.set_alignment(0, 0.5);
1095 bus_label.set_padding(0,0);
1096 bus_label.set_line_wrap(false);
1097 bus_label.set_selectable(false);
1098 bus_label.set_use_markup(true);
1099 bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
1100 bus_frame.set_label_align(0,0.5);
1101 bus_frame.add(bus_hbox);
1102 bus_frame.set_label_widget(bus_label);
1104 bus_table.set_row_spacings (0);
1105 bus_table.set_col_spacings (0);
1106 bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1107 bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1108 bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
1110 input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
1111 input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
1112 input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
1113 input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
1114 input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
1115 input_table.set_row_spacings(0);
1116 input_table.set_col_spacings(0);
1117 input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
1119 input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
1121 input_label.set_alignment(0, 0.5);
1122 input_label.set_padding(0,0);
1123 input_label.set_line_wrap(false);
1124 input_label.set_selectable(false);
1125 input_label.set_use_markup(true);
1126 input_frame.set_shadow_type(Gtk::SHADOW_NONE);
1127 input_frame.set_label_align(0,0.5);
1128 input_frame.add(input_hbox);
1129 input_frame.set_label_widget(input_label);
1131 _connect_outputs.set_label (_("Automatically connect outputs"));
1132 _connect_outputs.set_flags(Gtk::CAN_FOCUS);
1133 _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
1134 _connect_outputs.set_mode(true);
1135 _connect_outputs.set_active(Config->get_output_auto_connect() != ManualConnect);
1136 _connect_outputs.set_border_width(0);
1137 _limit_output_ports.set_label (_("Use only"));
1138 _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
1139 _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
1140 _limit_output_ports.set_mode(true);
1141 _limit_output_ports.set_sensitive(true);
1142 _limit_output_ports.set_border_width(0);
1143 _output_limit_count.set_flags(Gtk::CAN_FOCUS);
1144 _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1145 _output_limit_count.set_numeric(false);
1146 _output_limit_count.set_digits(0);
1147 _output_limit_count.set_wrap(false);
1148 _output_limit_count.set_sensitive(false);
1149 output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
1150 output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
1151 output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
1153 _connect_outputs_to_master.set_label (_("... to master bus"));
1154 _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
1155 _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
1156 _connect_outputs_to_master.set_mode(true);
1157 _connect_outputs_to_master.set_active(Config->get_output_auto_connect() == AutoConnectMaster);
1158 _connect_outputs_to_master.set_border_width(0);
1160 _connect_outputs_to_master.set_group (connect_outputs_group);
1161 _connect_outputs_to_physical.set_group (connect_outputs_group);
1163 _connect_outputs_to_physical.set_label (_("... to physical outputs"));
1164 _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
1165 _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
1166 _connect_outputs_to_physical.set_mode(true);
1167 _connect_outputs_to_physical.set_active(Config->get_output_auto_connect() == AutoConnectPhysical);
1168 _connect_outputs_to_physical.set_border_width(0);
1170 output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
1171 output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
1172 output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
1173 output_vbox.set_border_width(6);
1175 output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
1177 output_vbox.pack_start(output_conn_vbox);
1178 output_vbox.pack_start(output_port_vbox);
1180 output_label.set_alignment(0, 0.5);
1181 output_label.set_padding(0,0);
1182 output_label.set_line_wrap(false);
1183 output_label.set_selectable(false);
1184 output_label.set_use_markup(true);
1185 output_frame.set_shadow_type(Gtk::SHADOW_NONE);
1186 output_frame.set_label_align(0,0.5);
1188 output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
1190 output_frame.add(output_hbox);
1191 output_frame.set_label_widget(output_label);
1193 more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
1194 more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
1195 more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
1196 more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
1200 _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
1201 _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
1202 _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
1203 _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
1204 _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
1206 /* note that more_options_vbox is "visible" by default even
1207 * though it may not be displayed to the user, this is so the dialog
1210 more_options_vbox.show_all ();
1214 ArdourStartup::create_master_bus() const
1216 return _create_master_bus.get_active();
1220 ArdourStartup::master_channel_count() const
1222 return _master_bus_channel_count.get_value_as_int();
1226 ArdourStartup::connect_inputs() const
1228 return _connect_inputs.get_active();
1232 ArdourStartup::limit_inputs_used_for_connection() const
1234 return _limit_input_ports.get_active();
1238 ArdourStartup::input_limit_count() const
1240 return _input_limit_count.get_value_as_int();
1244 ArdourStartup::connect_outputs() const
1246 return _connect_outputs.get_active();
1250 ArdourStartup::limit_outputs_used_for_connection() const
1252 return _limit_output_ports.get_active();
1256 ArdourStartup::output_limit_count() const
1258 return _output_limit_count.get_value_as_int();
1262 ArdourStartup::connect_outs_to_master() const
1264 return _connect_outputs_to_master.get_active();
1268 ArdourStartup::connect_outs_to_physical() const
1270 return _connect_outputs_to_physical.get_active();
1274 ArdourStartup::connect_inputs_clicked ()
1276 _limit_input_ports.set_sensitive(_connect_inputs.get_active());
1278 if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
1279 _input_limit_count.set_sensitive(true);
1281 _input_limit_count.set_sensitive(false);
1286 ArdourStartup::connect_outputs_clicked ()
1288 bool const co = _connect_outputs.get_active ();
1289 _limit_output_ports.set_sensitive(co);
1290 _connect_outputs_to_master.set_sensitive(co);
1291 _connect_outputs_to_physical.set_sensitive(co);
1293 if (co && _limit_output_ports.get_active()) {
1294 _output_limit_count.set_sensitive(true);
1296 _output_limit_count.set_sensitive(false);
1301 ArdourStartup::limit_inputs_clicked ()
1303 _input_limit_count.set_sensitive(_limit_input_ports.get_active());
1307 ArdourStartup::limit_outputs_clicked ()
1309 _output_limit_count.set_sensitive(_limit_output_ports.get_active());
1313 ArdourStartup::master_bus_button_clicked ()
1315 bool const yn = _create_master_bus.get_active();
1317 _master_bus_channel_count.set_sensitive(yn);
1318 _connect_outputs_to_master.set_sensitive(yn);
1322 ArdourStartup::move_along_now ()
1328 ArdourStartup::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
1330 set_page_complete (ic_vbox, true);
1335 ArdourStartup::existing_session_selected ()
1337 _existing_session_chooser_used = true;
1339 session_selected ();
1340 set_page_complete (ic_vbox, true);
1345 ArdourStartup::been_here_before_path () const
1347 // XXXX use more specific version so we can catch upgrades
1348 return Glib::build_filename (user_config_directory (), ".a3");
1352 ArdourStartup::updates_button_clicked ()
1354 //now open a browser window so user can see more
1355 PBD::open_uri (Config->get_updates_url());
1359 ArdourStartup::info_scroller_update()
1361 info_scroller_count++;
1364 snprintf (buf, std::min(info_scroller_count,sizeof(buf)-1), "%s", ARDOUR_UI::instance()->announce_string().c_str() );
1365 buf[info_scroller_count] = 0;
1366 info_scroller_label.set_text (buf);
1367 info_scroller_label.show();
1369 if (info_scroller_count > ARDOUR_UI::instance()->announce_string().length()) {
1370 info_scroller_connection.disconnect();