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 (_("I'd like more options for this session"))
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 setup_more_options_page ();
151 if (!template_name.empty()) {
152 use_template_button.set_active (false);
153 load_template_override = template_name;
160 ArdourStartup::~ArdourStartup ()
165 ArdourStartup::ready_without_display () const
167 return !new_user && !need_session_info;
171 ArdourStartup::setup_prerelease_page ()
173 VBox* vbox = manage (new VBox);
174 Label* label = manage (new Label);
175 label->set_markup (string_compose (_("<b>Welcome to this BETA release of Ardour %1</b>\n\n\
176 Ardour %1 has been released for Linux but because of the lack of testers,\n\
177 it is still at the beta stage on OS X. So, a few guidelines:\n\
179 1) Please do <b>NOT</b> use this software with the expectation that it is stable or reliable\n\
180 though it may be so, depending on your workflow.\n\
181 2) <b>Please do NOT use the forums at ardour.org to report issues</b>.\n\
182 3) Please <b>DO</b> use the bugtracker at http://tracker.ardour.org/ to report issues\n\
183 making sure to note the product version number as %1-beta.\n\
184 4) Please <b>DO</b> use the ardour-users mailing list to discuss ideas and pass on comments.\n\
185 5) Please <b>DO</b> join us on IRC for real time discussions about ardour3. You\n\
186 can get there directly from Ardour via the Help->Chat menu option.\n\
188 Full information on all the above can be found on the support page at\n\
190 http://ardour.org/support\n\
193 vbox->set_border_width (12);
194 vbox->pack_start (*label, false, false, 12);
198 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
199 set_page_title (*vbox, _("This is a BETA RELEASE"));
200 set_page_complete (*vbox, true);
204 ArdourStartup::use_session_template ()
206 if (!load_template_override.empty()) {
210 if (use_template_button.get_active()) {
211 return template_chooser.get_active_row_number() > 0;
213 return !session_template_chooser.get_filename().empty();
218 ArdourStartup::session_template_name ()
220 if (!load_template_override.empty()) {
221 string the_path (ARDOUR::user_template_directory());
222 return Glib::build_filename (the_path, load_template_override + ARDOUR::template_suffix);
225 if (use_template_button.get_active()) {
226 TreeModel::iterator iter = template_chooser.get_active ();
227 TreeModel::Row row = (*iter);
228 string s = row[session_template_columns.path];
231 return session_template_chooser.get_filename();
237 ArdourStartup::session_name (bool& should_be_new)
239 if (ready_without_display()) {
240 return _provided_session_name;
243 /* Try recent session selection */
245 TreeIter iter = recent_session_display.get_selection()->get_selected();
248 should_be_new = false;
249 return (*iter)[recent_session_columns.visible_name];
252 if (_existing_session_chooser_used) {
253 /* existing session chosen from file chooser */
254 should_be_new = false;
255 return existing_session_chooser.get_filename ();
257 should_be_new = true;
258 string val = new_name_entry.get_text ();
259 strip_whitespace_edges (val);
265 ArdourStartup::session_folder ()
267 if (ready_without_display()) {
268 return _provided_session_path;
271 /* Try recent session selection */
273 TreeIter iter = recent_session_display.get_selection()->get_selected();
276 return (*iter)[recent_session_columns.fullpath];
279 if (_existing_session_chooser_used) {
280 /* existing session chosen from file chooser */
281 return existing_session_chooser.get_current_folder ();
283 std::string legal_session_folder_name = legalize_for_path (new_name_entry.get_text());
284 return Glib::build_filename (new_folder_chooser.get_current_folder(), legal_session_folder_name);
289 ArdourStartup::setup_new_user_page ()
291 Label* foomatic = manage (new Label);
293 foomatic->set_markup (string_compose (_("\
294 <span size=\"larger\">%1 is a digital audio workstation. You can use it to \
295 record, edit and mix multi-track audio. You can produce your \
296 own CDs, mix video soundtracks, or experiment with new \
297 ideas about music and sound. \
299 There are a few things that need to be configured before you start \
300 using the program.</span> \
302 foomatic->set_justify (JUSTIFY_FILL);
303 foomatic->set_line_wrap ();
305 HBox* hbox = manage (new HBox);
306 HBox* vbox = manage (new HBox);
308 vbox->set_border_width (24);
310 hbox->pack_start (*foomatic, true, true);
311 vbox->pack_start (*hbox, true, true);
317 new_user_page_index = append_page (*vbox);
318 set_page_type (*vbox, ASSISTANT_PAGE_INTRO);
319 set_page_title (*vbox, string_compose (_("Welcome to %1"), PROGRAM_NAME));
320 set_page_header_image (*vbox, icon_pixbuf);
321 set_page_complete (*vbox, true);
325 ArdourStartup::default_dir_changed ()
327 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
328 // make new session folder chooser point to the new default
329 new_folder_chooser.set_current_folder (Config->get_default_session_parent_dir());
334 ArdourStartup::config_changed ()
336 config_modified = true;
340 ArdourStartup::setup_first_time_config_page ()
342 default_dir_chooser = manage (new FileChooserButton (string_compose (_("Default folder for %1 sessions"), PROGRAM_NAME),
343 FILE_CHOOSER_ACTION_SELECT_FOLDER));
344 Gtk::Label* txt = manage (new Label);
345 HBox* hbox = manage (new HBox);
346 VBox* vbox = manage (new VBox);
348 txt->set_markup (string_compose (_("\
349 Each project that you work on with %1 has its own folder.\n\
350 These can require a lot of disk space if you are recording audio.\n\
352 Where would you like new %1 sessions to be stored by default?\n\n\
353 <i>(You can put new sessions anywhere, this is just a default)</i>"), PROGRAM_NAME));
354 txt->set_alignment (0.0, 0.0);
356 vbox->set_spacing (18);
357 vbox->set_border_width (24);
359 hbox->pack_start (*default_dir_chooser, false, true, 8);
360 vbox->pack_start (*txt, false, false);
361 vbox->pack_start (*hbox, false, true);
363 default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
364 default_dir_chooser->signal_current_folder_changed().connect (sigc::mem_fun (*this, &ArdourStartup::default_dir_changed));
365 default_dir_chooser->show ();
369 default_folder_page_index = append_page (*vbox);
370 set_page_title (*vbox, _("Default folder for new sessions"));
371 set_page_header_image (*vbox, icon_pixbuf);
372 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
374 /* user can just skip all these settings if they want to */
376 set_page_complete (*vbox, true);
380 ArdourStartup::setup_monitoring_choice_page ()
382 mon_vbox.set_spacing (18);
383 mon_vbox.set_border_width (24);
385 HBox* hbox = manage (new HBox);
386 VBox* vbox = manage (new VBox);
387 /* first button will be on by default */
388 RadioButton::Group g (monitor_via_ardour_button.get_group());
389 monitor_via_hardware_button.set_group (g);
391 monitor_label.set_markup(_("\
392 While recording instruments or vocals, you probably want to listen to the\n\
393 signal as well as record it. This is called \"monitoring\". There are\n\
394 different ways to do this depending on the equipment you have and the\n\
395 configuration of that equipment. The two most common are presented here.\n\
396 Please choose whichever one is right for your setup.\n\n\
397 <i>(You can change this preference at any time, via the Preferences dialog)</i>\n\n\
398 <i>If you do not understand what this is about, just accept the default.</i>"));
399 monitor_label.set_alignment (0.0, 0.0);
401 vbox->set_spacing (6);
403 vbox->pack_start (monitor_via_hardware_button, false, true);
404 vbox->pack_start (monitor_via_ardour_button, false, true);
405 hbox->pack_start (*vbox, true, true, 8);
406 mon_vbox.pack_start (monitor_label, false, false);
407 mon_vbox.pack_start (*hbox, false, false);
409 mon_vbox.show_all ();
411 monitoring_page_index = append_page (mon_vbox);
412 set_page_title (mon_vbox, _("Monitoring Choices"));
413 set_page_header_image (mon_vbox, icon_pixbuf);
415 /* user could just click on "Forward" if default
419 set_page_complete (mon_vbox, true);
423 ArdourStartup::setup_monitor_section_choice_page ()
425 mon_sec_vbox.set_spacing (18);
426 mon_sec_vbox.set_border_width (24);
428 HBox* hbox = manage (new HBox);
429 VBox* main_vbox = manage (new VBox);
431 Label* l = manage (new Label);
433 main_vbox->set_spacing (32);
435 no_monitor_section_button.set_label (_("Use a Master bus directly"));
436 l->set_alignment (0.0, 1.0);
437 l->set_markup(_("Connect the Master bus directly to your hardware outputs. This is preferable for simple usage."));
439 vbox = manage (new VBox);
440 vbox->set_spacing (6);
441 vbox->pack_start (no_monitor_section_button, false, true);
442 vbox->pack_start (*l, false, true);
444 main_vbox->pack_start (*vbox, false, false);
446 use_monitor_section_button.set_label (_("Use an additional Monitor bus"));
447 l = manage (new Label);
448 l->set_alignment (0.0, 1.0);
449 l->set_text (_("Use a Monitor bus between Master bus and hardware outputs for \n\
450 greater control in monitoring without affecting the mix."));
452 vbox = manage (new VBox);
453 vbox->set_spacing (6);
454 vbox->pack_start (use_monitor_section_button, false, true);
455 vbox->pack_start (*l, false, true);
457 main_vbox->pack_start (*vbox, false, false);
459 RadioButton::Group g (use_monitor_section_button.get_group());
460 no_monitor_section_button.set_group (g);
462 if (Config->get_use_monitor_bus()) {
463 use_monitor_section_button.set_active (true);
465 no_monitor_section_button.set_active (true);
468 use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
469 no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
471 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\
472 <i>If you do not understand what this is about, just accept the default.</i>"));
473 monitor_section_label.set_alignment (0.0, 0.0);
475 hbox->pack_start (*main_vbox, true, true, 8);
476 mon_sec_vbox.pack_start (*hbox, false, false);
477 mon_sec_vbox.pack_start (monitor_section_label, false, false);
479 mon_sec_vbox.show_all ();
481 monitor_section_page_index = append_page (mon_sec_vbox);
482 set_page_title (mon_sec_vbox, _("Monitor Section"));
483 set_page_header_image (mon_sec_vbox, icon_pixbuf);
485 /* user could just click on "Forward" if default
489 set_page_complete (mon_sec_vbox, true);
493 ArdourStartup::setup_initial_choice_page ()
495 ic_vbox.set_spacing (6);
496 ic_vbox.set_border_width (24);
498 /* append the page early because the recent session display will cause
499 calls to set_page_complete() on this page.
502 initial_choice_index = append_page (ic_vbox);
503 set_page_title (ic_vbox, string_compose("%1 %2", PROGRAM_NAME, VERSIONSTRING));
504 set_page_header_image (ic_vbox, icon_pixbuf);
507 HBox* centering_hbox = manage (new HBox);
508 VBox* centering_vbox = manage (new VBox);
510 centering_vbox->set_spacing (6);
512 Label* new_label = manage (new Label);
513 new_label->set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", _("Create a new session")));
514 new_label->set_alignment (0, 0.5);
516 ic_new_session_button.set_label (_("Configure the new session ..."));
517 ic_new_session_button.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::new_session_button_clicked));
519 centering_vbox->pack_start (*new_label, false, false, 12);
520 centering_vbox->pack_start (ic_new_session_button, false, true);
522 /* Possible update message */
524 if (ARDOUR_UI::instance()->announce_string() != "" ) {
526 Gtk::Frame *info_frame = manage(new Gtk::Frame);
527 info_frame->set_shadow_type(SHADOW_ETCHED_OUT);
528 centering_vbox->pack_start (*info_frame, false, false, 20);
530 Box *info_box = manage (new VBox);
531 info_box->set_border_width (12);
532 info_box->set_spacing (6);
533 info_box->set_name("mixbus_info_box");
535 info_box->pack_start (info_scroller_label, false, false);
537 info_frame->add (*info_box);
538 info_frame->show_all();
540 info_scroller_count = 0;
541 info_scroller_connection = Glib::signal_timeout().connect (mem_fun(*this, &ArdourStartup::info_scroller_update), 50);
543 Gtk::Button *updates_button = manage (new Gtk::Button (_("Check the website for more...")));
545 updates_button->signal_clicked().connect (mem_fun(*this, &ArdourStartup::updates_button_clicked) );
546 ARDOUR_UI::instance()->tooltips().set_tip (*updates_button, _("Click to open the program website in your web browser"));
548 info_box->pack_start (*updates_button, false, false);
551 ARDOUR::RecentSessions rs;
552 ARDOUR::read_recent_sessions (rs);
556 /* recent session scroller */
558 Label* load_label = manage (new Label);
559 load_label->set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", _("Load a recent session")));
560 load_label->set_alignment (0, 0.5);
562 centering_vbox->pack_start (*load_label, false, false, 12);
564 recent_session_model = TreeStore::create (recent_session_columns);
565 redisplay_recent_sessions ();
567 recent_session_display.set_model (recent_session_model);
568 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
569 recent_session_display.set_headers_visible (false);
570 recent_session_display.get_selection()->set_mode (SELECTION_SINGLE);
572 recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::recent_session_row_selected));
574 recent_scroller.add (recent_session_display);
575 recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
576 recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
578 recent_session_display.show();
580 recent_scroller.show();
581 recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ArdourStartup::recent_row_activated));
583 int cnt = redisplay_recent_sessions ();
585 recent_scroller.set_size_request (-1, 300);
588 centering_vbox->pack_start (recent_scroller, false, true);
593 existing_session_chooser.set_title (_("Select session file"));
594 existing_session_chooser.signal_file_set().connect (sigc::mem_fun (*this, &ArdourStartup::existing_session_selected));
595 existing_session_chooser.set_current_folder(poor_mans_glob (Config->get_default_session_parent_dir()));
597 FileFilter session_filter;
598 session_filter.add_pattern ("*.ardour");
599 session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
600 existing_session_chooser.add_filter (session_filter);
601 existing_session_chooser.set_filter (session_filter);
604 existing_session_chooser.add_shortcut_folder ("/Volumes");
607 Label* browse_label = manage (new Label);
608 browse_label->set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", _("Browse for other sessions")));
609 browse_label->set_alignment (0, 0.5);
611 centering_vbox->pack_start (*browse_label, false, false, 12);
612 centering_vbox->pack_start (existing_session_chooser, false, false);
616 centering_hbox->pack_start (*centering_vbox, true, true);
617 ic_vbox.pack_start (*centering_hbox, true, true);
620 /* user could just click on "Forward" if default
624 set_page_complete (ic_vbox, true);
628 ArdourStartup::session_selected ()
630 /* HACK HACK HACK ... change the "Apply" button label
634 Gtk::Widget* tl = ic_vbox.get_toplevel();
636 if ((win = dynamic_cast<Gtk::Window*>(tl)) != 0) {
637 /* ::get_default_widget() is not wrapped in gtkmm */
638 Gtk::Widget* def = wrap (gtk_window_get_default_widget (win->gobj()));
640 if ((button = dynamic_cast<Gtk::Button*>(def)) != 0) {
641 if (more_new_session_options_button.get_active()) {
642 button->set_label (_("Next"));
644 button->set_label (_("Open"));
651 ArdourStartup::new_session_button_clicked ()
653 set_current_page (new_session_page_index);
657 ArdourStartup::setup_final_page ()
659 final_page.set_text (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
661 final_page_index = append_page (final_page);
662 set_page_complete (final_page, true);
663 set_page_header_image (final_page, icon_pixbuf);
664 set_page_type (final_page, ASSISTANT_PAGE_CONFIRM);
668 ArdourStartup::on_cancel ()
670 _response = RESPONSE_CANCEL;
675 ArdourStartup::on_prepare (Gtk::Widget* page)
677 if (page == &session_new_vbox) {
679 /* if the user already defined a name by using the recent
680 * session list or browsing to an existing session
684 bool expect_new_ignored;
686 if (!session_name (expect_new_ignored).empty()) {
693 ArdourStartup::on_delete_event (GdkEventAny*)
695 _response = RESPONSE_CLOSE;
701 ArdourStartup::on_apply ()
703 if (config_modified) {
705 if (default_dir_chooser) {
706 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
709 if (monitor_via_hardware_button.get_active()) {
710 Config->set_monitoring_model (ExternalMonitoring);
711 } else if (monitor_via_ardour_button.get_active()) {
712 Config->set_monitoring_model (SoftwareMonitoring);
715 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
717 Config->save_state ();
722 /* "touch" the been-here-before path now we've successfully
723 made it through the first time setup (at least)
725 ofstream fout (been_here_before_path().c_str());
729 _response = RESPONSE_OK;
734 ArdourStartup::populate_session_templates ()
736 vector<TemplateInfo> templates;
738 find_session_templates (templates);
740 template_model->clear ();
742 for (vector<TemplateInfo>::iterator x = templates.begin(); x != templates.end(); ++x) {
745 row = *(template_model->append ());
747 row[session_template_columns.name] = (*x).name;
748 row[session_template_columns.path] = (*x).path;
753 ArdourStartup::setup_new_session_page ()
755 session_new_vbox.set_border_width (12);
756 session_new_vbox.set_spacing (18);
758 if (session_new_vbox.get_children().empty()) {
759 VBox *vbox1 = manage (new VBox);
760 HBox* hbox1 = manage (new HBox);
761 Label* label1 = manage (new Label);
763 vbox1->set_spacing (6);
765 hbox1->set_spacing (6);
766 hbox1->pack_start (*label1, false, false);
767 hbox1->pack_start (new_name_entry, true, true);
769 label1->set_text (_("Session name:"));
772 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
773 new_name_entry.set_text (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
774 /* name provided - they can move right along */
775 set_page_complete (session_new_vbox, true);
778 new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_changed));
779 new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &ArdourStartup::move_along_now));
781 vbox1->pack_start (*hbox1, true, true);
785 HBox* hbox2 = manage (new HBox);
786 Label* label2 = manage (new Label);
788 hbox2->set_spacing (6);
789 hbox2->pack_start (*label2, false, false);
790 hbox2->pack_start (new_folder_chooser, true, true);
792 label2->set_text (_("Create session folder in:"));
794 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
795 new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
796 } else if (ARDOUR_UI::instance()->session_loaded) {
797 // point the new session file chooser at the parent directory of the current session
798 string session_parent_dir = Glib::path_get_dirname(ARDOUR_UI::instance()->the_session()->path());
799 string::size_type last_dir_sep = session_parent_dir.rfind(G_DIR_SEPARATOR);
800 session_parent_dir = session_parent_dir.substr(0, last_dir_sep);
801 new_folder_chooser.set_current_folder (session_parent_dir);
802 string default_session_folder = poor_mans_glob (Config->get_default_session_parent_dir());
805 /* add_shortcut_folder throws an exception if the folder being added already has a shortcut */
806 new_folder_chooser.add_shortcut_folder (default_session_folder);
808 catch (Glib::Error & e) {
809 std::cerr << "new_folder_chooser.add_shortcut_folder (" << default_session_folder << ") threw Glib::Error " << e.what() << std::endl;
812 new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
814 new_folder_chooser.show ();
815 new_folder_chooser.set_title (_("Select folder for session"));
818 new_folder_chooser.add_shortcut_folder ("/Volumes");
821 vbox1->pack_start (*hbox2, false, false);
823 session_new_vbox.pack_start (*vbox1, false, false);
827 VBox *vbox2 = manage (new VBox);
828 HBox* hbox3 = manage (new HBox);
829 Label* label3 = manage (new Label);
830 template_model = ListStore::create (session_template_columns);
831 populate_session_templates ();
833 vbox2->set_spacing (6);
835 label3->set_markup (_("<b>Options</b>"));
836 label3->set_alignment (0.0, 0.0);
838 vbox2->pack_start (*label3, false, true);
840 VBox *vbox3 = manage (new VBox);
842 vbox3->set_spacing (6);
844 if (!template_model->children().empty()) {
846 HBox* hbox4a = manage (new HBox);
847 use_template_button.set_label (_("Use this template"));
849 TreeModel::Row row = *template_model->prepend ();
850 row[session_template_columns.name] = (_("no template"));
851 row[session_template_columns.path] = string();
853 hbox4a->set_spacing (6);
854 hbox4a->pack_start (use_template_button, false, false);
855 hbox4a->pack_start (template_chooser, true, true);
857 template_chooser.set_model (template_model);
859 Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
860 text_renderer->property_editable() = false;
862 template_chooser.pack_start (*text_renderer);
863 template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
864 template_chooser.set_active (0);
866 use_template_button.show();
867 template_chooser.show ();
869 vbox3->pack_start (*hbox4a, false, false);
875 session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
877 HBox* hbox4b = manage (new HBox);
878 use_session_as_template_button.set_label (_("Use an existing session as a template:"));
880 hbox4b->set_spacing (6);
881 hbox4b->pack_start (use_session_as_template_button, false, false);
882 hbox4b->pack_start (session_template_chooser, true, true);
884 use_session_as_template_button.show ();
885 session_template_chooser.show ();
887 Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
888 session_filter->add_pattern (X_("*.ardour"));
889 session_template_chooser.set_filter (*session_filter);
890 session_template_chooser.set_title (_("Select template"));
892 vbox3->pack_start (*hbox4b, false, false);
897 HBox* hbox5 = manage (new HBox);
899 hbox5->set_spacing (6);
900 hbox5->pack_start (more_new_session_options_button, false, false);
902 more_new_session_options_button.show ();
903 more_new_session_options_button.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::more_new_session_options_button_clicked));
905 vbox3->pack_start (*hbox5, false, false);
906 hbox3->pack_start (*vbox3, true, true, 8);
907 vbox2->pack_start (*hbox3, false, false);
911 session_new_vbox.pack_start (*vbox2, false, false);
914 session_new_vbox.show_all ();
916 new_session_page_index = append_page (session_new_vbox);
917 set_page_type (session_new_vbox, ASSISTANT_PAGE_CONTENT);
918 set_page_title (session_new_vbox, _("New Session"));
920 if (more_new_session_options_button.get_active()) {
921 set_page_type (session_new_vbox, ASSISTANT_PAGE_CONTENT);
923 set_page_type (session_new_vbox, ASSISTANT_PAGE_CONFIRM);
928 ArdourStartup::new_name_changed ()
930 if (!new_name_entry.get_text().empty()) {
932 set_page_complete (session_new_vbox, true);
934 set_page_complete (session_new_vbox, false);
939 ArdourStartup::redisplay_recent_sessions ()
941 std::vector<std::string> session_directories;
942 RecentSessionsSorter cmp;
944 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
945 recent_session_model->clear ();
947 ARDOUR::RecentSessions rs;
948 ARDOUR::read_recent_sessions (rs);
951 recent_session_display.set_model (recent_session_model);
955 // sort them alphabetically
956 sort (rs.begin(), rs.end(), cmp);
958 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
959 session_directories.push_back ((*i).second);
962 int session_snapshot_count = 0;
964 for (vector<std::string>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
966 std::vector<std::string> state_file_paths;
968 // now get available states for this session
970 get_state_files_in_directory (*i, state_file_paths);
972 vector<string*>* states;
973 vector<const gchar*> item;
974 string fullpath = *i;
976 /* remove any trailing / */
978 if (fullpath[fullpath.length()-1] == '/') {
979 fullpath = fullpath.substr (0, fullpath.length()-1);
982 /* check whether session still exists */
983 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
984 /* session doesn't exist */
988 /* now get available states for this session */
990 if ((states = Session::possible_states (fullpath)) == 0) {
995 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
997 Gtk::TreeModel::Row row = *(recent_session_model->append());
999 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
1000 row[recent_session_columns.fullpath] = fullpath;
1001 row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
1003 ++session_snapshot_count;
1005 if (state_file_names.size() > 1) {
1009 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
1010 i2 != state_file_names.end(); ++i2) {
1012 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
1014 child_row[recent_session_columns.visible_name] = *i2;
1015 child_row[recent_session_columns.fullpath] = fullpath;
1016 child_row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
1017 ++session_snapshot_count;
1022 recent_session_display.set_tooltip_column(1); // recent_session_columns.tip
1023 recent_session_display.set_model (recent_session_model);
1024 return session_snapshot_count;
1025 // return rs.size();
1029 ArdourStartup::recent_session_row_selected ()
1031 if (recent_session_display.get_selection()->count_selected_rows() > 0) {
1032 set_page_complete (ic_vbox, true);
1033 session_selected ();
1035 set_page_complete (ic_vbox, false);
1040 ArdourStartup::more_new_session_options_button_clicked ()
1042 if (more_new_session_options_button.get_active()) {
1043 more_options_vbox.show_all ();
1044 set_page_type (more_options_vbox, ASSISTANT_PAGE_CONFIRM);
1045 set_page_type (session_new_vbox, ASSISTANT_PAGE_CONTENT);
1047 set_page_type (session_new_vbox, ASSISTANT_PAGE_CONFIRM);
1048 more_options_vbox.hide ();
1053 ArdourStartup::setup_more_options_page ()
1055 more_options_vbox.set_border_width (24);
1057 _output_limit_count.set_adjustment (_output_limit_count_adj);
1058 _input_limit_count.set_adjustment (_input_limit_count_adj);
1059 _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
1061 chan_count_label_1.set_text (_("channels"));
1062 chan_count_label_3.set_text (_("channels"));
1063 chan_count_label_4.set_text (_("channels"));
1065 chan_count_label_1.set_alignment(0,0.5);
1066 chan_count_label_1.set_padding(0,0);
1067 chan_count_label_1.set_line_wrap(false);
1069 chan_count_label_3.set_alignment(0,0.5);
1070 chan_count_label_3.set_padding(0,0);
1071 chan_count_label_3.set_line_wrap(false);
1073 chan_count_label_4.set_alignment(0,0.5);
1074 chan_count_label_4.set_padding(0,0);
1075 chan_count_label_4.set_line_wrap(false);
1077 bus_label.set_markup (_("<b>Busses</b>"));
1078 input_label.set_markup (_("<b>Inputs</b>"));
1079 output_label.set_markup (_("<b>Outputs</b>"));
1081 _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
1082 _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1083 _master_bus_channel_count.set_numeric(true);
1084 _master_bus_channel_count.set_digits(0);
1085 _master_bus_channel_count.set_wrap(false);
1087 _create_master_bus.set_label (_("Create master bus"));
1088 _create_master_bus.set_flags(Gtk::CAN_FOCUS);
1089 _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
1090 _create_master_bus.set_mode(true);
1091 _create_master_bus.set_active(true);
1092 _create_master_bus.set_border_width(0);
1094 advanced_table.set_row_spacings(0);
1095 advanced_table.set_col_spacings(0);
1097 _connect_inputs.set_label (_("Automatically connect to physical inputs"));
1098 _connect_inputs.set_flags(Gtk::CAN_FOCUS);
1099 _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
1100 _connect_inputs.set_mode(true);
1101 _connect_inputs.set_active(Config->get_input_auto_connect() != ManualConnect);
1102 _connect_inputs.set_border_width(0);
1104 _limit_input_ports.set_label (_("Use only"));
1105 _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
1106 _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
1107 _limit_input_ports.set_mode(true);
1108 _limit_input_ports.set_sensitive(true);
1109 _limit_input_ports.set_border_width(0);
1111 _input_limit_count.set_flags(Gtk::CAN_FOCUS);
1112 _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1113 _input_limit_count.set_numeric(true);
1114 _input_limit_count.set_digits(0);
1115 _input_limit_count.set_wrap(false);
1116 _input_limit_count.set_sensitive(false);
1118 bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
1120 bus_label.set_alignment(0, 0.5);
1121 bus_label.set_padding(0,0);
1122 bus_label.set_line_wrap(false);
1123 bus_label.set_selectable(false);
1124 bus_label.set_use_markup(true);
1125 bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
1126 bus_frame.set_label_align(0,0.5);
1127 bus_frame.add(bus_hbox);
1128 bus_frame.set_label_widget(bus_label);
1130 bus_table.set_row_spacings (0);
1131 bus_table.set_col_spacings (0);
1132 bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1133 bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1134 bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
1136 input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
1137 input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
1138 input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
1139 input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
1140 input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
1141 input_table.set_row_spacings(0);
1142 input_table.set_col_spacings(0);
1143 input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
1145 input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
1147 input_label.set_alignment(0, 0.5);
1148 input_label.set_padding(0,0);
1149 input_label.set_line_wrap(false);
1150 input_label.set_selectable(false);
1151 input_label.set_use_markup(true);
1152 input_frame.set_shadow_type(Gtk::SHADOW_NONE);
1153 input_frame.set_label_align(0,0.5);
1154 input_frame.add(input_hbox);
1155 input_frame.set_label_widget(input_label);
1157 _connect_outputs.set_label (_("Automatically connect outputs"));
1158 _connect_outputs.set_flags(Gtk::CAN_FOCUS);
1159 _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
1160 _connect_outputs.set_mode(true);
1161 _connect_outputs.set_active(Config->get_output_auto_connect() != ManualConnect);
1162 _connect_outputs.set_border_width(0);
1163 _limit_output_ports.set_label (_("Use only"));
1164 _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
1165 _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
1166 _limit_output_ports.set_mode(true);
1167 _limit_output_ports.set_sensitive(true);
1168 _limit_output_ports.set_border_width(0);
1169 _output_limit_count.set_flags(Gtk::CAN_FOCUS);
1170 _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1171 _output_limit_count.set_numeric(false);
1172 _output_limit_count.set_digits(0);
1173 _output_limit_count.set_wrap(false);
1174 _output_limit_count.set_sensitive(false);
1175 output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
1176 output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
1177 output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
1179 _connect_outputs_to_master.set_label (_("... to master bus"));
1180 _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
1181 _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
1182 _connect_outputs_to_master.set_mode(true);
1183 _connect_outputs_to_master.set_active(Config->get_output_auto_connect() == AutoConnectMaster);
1184 _connect_outputs_to_master.set_border_width(0);
1186 _connect_outputs_to_master.set_group (connect_outputs_group);
1187 _connect_outputs_to_physical.set_group (connect_outputs_group);
1189 _connect_outputs_to_physical.set_label (_("... to physical outputs"));
1190 _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
1191 _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
1192 _connect_outputs_to_physical.set_mode(true);
1193 _connect_outputs_to_physical.set_active(Config->get_output_auto_connect() == AutoConnectPhysical);
1194 _connect_outputs_to_physical.set_border_width(0);
1196 output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
1197 output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
1198 output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
1199 output_vbox.set_border_width(6);
1201 output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
1203 output_vbox.pack_start(output_conn_vbox);
1204 output_vbox.pack_start(output_port_vbox);
1206 output_label.set_alignment(0, 0.5);
1207 output_label.set_padding(0,0);
1208 output_label.set_line_wrap(false);
1209 output_label.set_selectable(false);
1210 output_label.set_use_markup(true);
1211 output_frame.set_shadow_type(Gtk::SHADOW_NONE);
1212 output_frame.set_label_align(0,0.5);
1214 output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
1216 output_frame.add(output_hbox);
1217 output_frame.set_label_widget(output_label);
1219 more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
1220 more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
1221 more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
1222 more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
1226 _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
1227 _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
1228 _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
1229 _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
1230 _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
1232 /* note that more_options_vbox is "visible" by default even
1233 * though it may not be displayed to the user, this is so the dialog
1236 more_options_vbox.show_all ();
1238 session_options_page_index = append_page (more_options_vbox);
1239 set_page_title (more_options_vbox, _("Advanced Session Options"));
1240 set_page_complete (more_options_vbox, true);
1244 ArdourStartup::create_master_bus() const
1246 return _create_master_bus.get_active();
1250 ArdourStartup::master_channel_count() const
1252 return _master_bus_channel_count.get_value_as_int();
1256 ArdourStartup::connect_inputs() const
1258 return _connect_inputs.get_active();
1262 ArdourStartup::limit_inputs_used_for_connection() const
1264 return _limit_input_ports.get_active();
1268 ArdourStartup::input_limit_count() const
1270 return _input_limit_count.get_value_as_int();
1274 ArdourStartup::connect_outputs() const
1276 return _connect_outputs.get_active();
1280 ArdourStartup::limit_outputs_used_for_connection() const
1282 return _limit_output_ports.get_active();
1286 ArdourStartup::output_limit_count() const
1288 return _output_limit_count.get_value_as_int();
1292 ArdourStartup::connect_outs_to_master() const
1294 return _connect_outputs_to_master.get_active();
1298 ArdourStartup::connect_outs_to_physical() const
1300 return _connect_outputs_to_physical.get_active();
1304 ArdourStartup::connect_inputs_clicked ()
1306 _limit_input_ports.set_sensitive(_connect_inputs.get_active());
1308 if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
1309 _input_limit_count.set_sensitive(true);
1311 _input_limit_count.set_sensitive(false);
1316 ArdourStartup::connect_outputs_clicked ()
1318 bool const co = _connect_outputs.get_active ();
1319 _limit_output_ports.set_sensitive(co);
1320 _connect_outputs_to_master.set_sensitive(co);
1321 _connect_outputs_to_physical.set_sensitive(co);
1323 if (co && _limit_output_ports.get_active()) {
1324 _output_limit_count.set_sensitive(true);
1326 _output_limit_count.set_sensitive(false);
1331 ArdourStartup::limit_inputs_clicked ()
1333 _input_limit_count.set_sensitive(_limit_input_ports.get_active());
1337 ArdourStartup::limit_outputs_clicked ()
1339 _output_limit_count.set_sensitive(_limit_output_ports.get_active());
1343 ArdourStartup::master_bus_button_clicked ()
1345 bool const yn = _create_master_bus.get_active();
1347 _master_bus_channel_count.set_sensitive(yn);
1348 _connect_outputs_to_master.set_sensitive(yn);
1352 ArdourStartup::move_along_now ()
1354 gint cur = get_current_page ();
1356 if (cur == new_session_page_index) {
1357 if (more_new_session_options_button.get_active()) {
1358 set_current_page (session_options_page_index);
1368 ArdourStartup::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
1370 set_page_complete (ic_vbox, true);
1375 ArdourStartup::existing_session_selected ()
1377 _existing_session_chooser_used = true;
1379 session_selected ();
1380 set_page_complete (ic_vbox, true);
1385 ArdourStartup::been_here_before_path () const
1387 // XXXX use more specific version so we can catch upgrades
1388 return Glib::build_filename (user_config_directory (), ".a3");
1392 ArdourStartup::updates_button_clicked ()
1394 //now open a browser window so user can see more
1395 PBD::open_uri (Config->get_updates_url());
1399 ArdourStartup::info_scroller_update()
1401 info_scroller_count++;
1404 snprintf (buf, std::min(info_scroller_count,sizeof(buf)-1), "%s", ARDOUR_UI::instance()->announce_string().c_str() );
1405 buf[info_scroller_count] = 0;
1406 info_scroller_label.set_text (buf);
1407 info_scroller_label.show();
1409 if (info_scroller_count > ARDOUR_UI::instance()->announce_string().length()) {
1410 info_scroller_connection.disconnect();