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"
36 #include "ardour/filesystem_paths.h"
37 #include "ardour/recent_sessions.h"
38 #include "ardour/session.h"
39 #include "ardour/session_state_utils.h"
40 #include "ardour/template_utils.h"
41 #include "ardour/filename_extensions.h"
43 #include "ardour_ui.h"
46 #include "engine_dialog.h"
55 using namespace ARDOUR;
57 ArdourStartup* ArdourStartup::the_startup = 0;
59 static string poor_mans_glob (string path)
62 replace_all (copy, "~", Glib::get_home_dir());
66 ArdourStartup::ArdourStartup (bool require_new, const std::string& session_name, const std::string& session_path, const std::string& template_name)
67 : _response (RESPONSE_OK)
68 , config_modified (false)
69 , new_only (require_new)
70 , default_dir_chooser (0)
71 , ic_new_session_button (_("Create a new session"))
72 , ic_existing_session_button (_("Open an existing session"))
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))
77 , new_folder_chooser (FILE_CHOOSER_ACTION_SELECT_FOLDER)
78 , more_new_session_options_button (_("I'd like more options for this session"))
79 , _output_limit_count_adj (1, 0, 100, 1, 10, 0)
80 , _input_limit_count_adj (1, 0, 100, 1, 10, 0)
81 , _master_bus_channel_count_adj (2, 0, 100, 1, 10, 0)
82 , audio_page_index (-1)
83 , new_user_page_index (-1)
84 , default_folder_page_index (-1)
85 , monitoring_page_index (-1)
86 , session_page_index (-1)
87 , initial_choice_index (-1)
88 , final_page_index (-1)
89 , session_options_page_index (-1)
90 , _existing_session_chooser_used (false)
92 new_user = !Glib::file_test (been_here_before_path(), Glib::FILE_TEST_EXISTS);
93 need_audio_setup = EngineControl::need_setup ();
94 need_session_info = (session_name.empty() || require_new);
96 _provided_session_name = session_name;
97 _provided_session_path = session_path;
99 if (need_audio_setup || need_session_info || new_user) {
101 use_template_button.set_group (session_template_group);
102 use_session_as_template_button.set_group (session_template_group);
104 set_keep_above (true);
105 set_position (WIN_POS_CENTER);
106 set_border_width (12);
108 if ((icon_pixbuf = ::get_icon ("ardour_icon_48px")) == 0) {
109 throw failed_constructor();
112 list<Glib::RefPtr<Gdk::Pixbuf> > window_icons;
113 Glib::RefPtr<Gdk::Pixbuf> icon;
115 if ((icon = ::get_icon ("ardour_icon_16px")) != 0) {
116 window_icons.push_back (icon);
118 if ((icon = ::get_icon ("ardour_icon_22px")) != 0) {
119 window_icons.push_back (icon);
121 if ((icon = ::get_icon ("ardour_icon_32px")) != 0) {
122 window_icons.push_back (icon);
124 if ((icon = ::get_icon ("ardour_icon_48px")) != 0) {
125 window_icons.push_back (icon);
127 if (!window_icons.empty ()) {
128 set_default_icon_list (window_icons);
131 set_type_hint(Gdk::WINDOW_TYPE_HINT_DIALOG);
134 setup_prerelease_page ();
138 setup_new_user_page ();
139 setup_first_time_config_page ();
140 setup_monitoring_choice_page ();
141 setup_monitor_section_choice_page ();
143 if (need_audio_setup) {
147 ic_new_session_button.set_active (true); // always create new session on first run
151 if (need_audio_setup) {
155 setup_initial_choice_page ();
158 setup_session_page ();
159 setup_more_options_page ();
171 if (!template_name.empty()) {
172 use_template_button.set_active (false);
173 load_template_override = template_name;
180 ArdourStartup::~ArdourStartup ()
185 ArdourStartup::ready_without_display () const
187 return !new_user && !need_audio_setup && !need_session_info;
191 ArdourStartup::setup_prerelease_page ()
193 VBox* vbox = manage (new VBox);
194 Label* label = manage (new Label);
195 label->set_markup (_("<b>Welcome to this BETA release of Ardour 3.0</b>\n\n\
196 Ardour 3.0 has been released for Linux but because of the lack of testers,\n\
197 it is still at the beta stage on OS X. So, a few guidelines:\n\
199 1) Please do <b>NOT</b> use this software with the expectation that it is stable or reliable\n\
200 though it may be so, depending on your workflow.\n\
201 3) <b>Please do NOT use the forums at ardour.org to report issues</b>.\n\
202 4) Please <b>DO</b> use the bugtracker at http://tracker.ardour.org/ to report issues\n\
203 making sure to note the product version number as 3.0-beta.\n\
204 5) Please <b>DO</b> use the ardour-users mailing list to discuss ideas and pass on comments.\n\
205 6) Please <b>DO</b> join us on IRC for real time discussions about ardour3. You\n\
206 can get there directly from Ardour via the Help->Chat menu option.\n\
208 Full information on all the above can be found on the support page at\n\
210 http://ardour.org/support\n\
213 vbox->set_border_width (12);
214 vbox->pack_start (*label, false, false, 12);
218 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
219 set_page_title (*vbox, _("This is a BETA RELEASE"));
220 set_page_complete (*vbox, true);
224 ArdourStartup::use_session_template ()
226 if (!load_template_override.empty()) {
230 if (use_template_button.get_active()) {
231 return template_chooser.get_active_row_number() > 0;
233 return !session_template_chooser.get_filename().empty();
238 ArdourStartup::session_template_name ()
240 if (!load_template_override.empty()) {
241 string the_path (ARDOUR::user_template_directory());
242 return Glib::build_filename (the_path, load_template_override + ARDOUR::template_suffix);
245 if (ic_existing_session_button.get_active()) {
249 if (use_template_button.get_active()) {
250 TreeModel::iterator iter = template_chooser.get_active ();
251 TreeModel::Row row = (*iter);
252 string s = row[session_template_columns.path];
255 return session_template_chooser.get_filename();
261 ArdourStartup::session_name (bool& should_be_new)
263 if (ready_without_display()) {
264 return _provided_session_name;
267 if (ic_new_session_button.get_active()) {
268 should_be_new = true;
269 string val = new_name_entry.get_text ();
270 strip_whitespace_edges (val);
272 } else if (_existing_session_chooser_used) {
273 /* existing session chosen from file chooser */
274 should_be_new = false;
275 return existing_session_chooser.get_filename ();
277 /* existing session chosen from recent list */
278 should_be_new = false;
280 TreeIter iter = recent_session_display.get_selection()->get_selected();
283 return (*iter)[recent_session_columns.visible_name];
291 ArdourStartup::session_folder ()
293 if (ready_without_display()) {
294 return _provided_session_path;
297 if (ic_new_session_button.get_active()) {
298 std::string legal_session_folder_name = legalize_for_path (new_name_entry.get_text());
299 return Glib::build_filename (new_folder_chooser.get_current_folder(), legal_session_folder_name);
300 } else if (_existing_session_chooser_used) {
301 /* existing session chosen from file chooser */
302 return existing_session_chooser.get_current_folder ();
304 /* existing session chosen from recent list */
305 TreeIter iter = recent_session_display.get_selection()->get_selected();
308 return (*iter)[recent_session_columns.fullpath];
315 ArdourStartup::setup_audio_page ()
317 engine_dialog = manage (new EngineControl);
319 engine_dialog->set_border_width (12);
321 engine_dialog->show_all ();
323 audio_page_index = append_page (*engine_dialog);
324 set_page_type (*engine_dialog, ASSISTANT_PAGE_CONTENT);
325 set_page_title (*engine_dialog, _("Audio / MIDI Setup"));
327 /* the default parameters should work, so the page is potentially complete */
329 set_page_complete (*engine_dialog, true);
333 ArdourStartup::setup_new_user_page ()
335 Label* foomatic = manage (new Label);
337 foomatic->set_markup (string_compose (_("\
338 <span size=\"larger\">%1 is a digital audio workstation. You can use it to \
339 record, edit and mix multi-track audio. You can produce your \
340 own CDs, mix video soundtracks, or experiment with new \
341 ideas about music and sound. \
343 There are a few things that need to be configured before you start \
344 using the program.</span> \
346 foomatic->set_justify (JUSTIFY_FILL);
347 foomatic->set_line_wrap ();
349 HBox* hbox = manage (new HBox);
350 HBox* vbox = manage (new HBox);
352 vbox->set_border_width (24);
354 hbox->pack_start (*foomatic, true, true);
355 vbox->pack_start (*hbox, true, true);
361 new_user_page_index = append_page (*vbox);
362 set_page_type (*vbox, ASSISTANT_PAGE_INTRO);
363 set_page_title (*vbox, string_compose (_("Welcome to %1"), PROGRAM_NAME));
364 set_page_header_image (*vbox, icon_pixbuf);
365 set_page_complete (*vbox, true);
369 ArdourStartup::default_dir_changed ()
371 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
372 // make new session folder chooser point to the new default
373 new_folder_chooser.set_current_folder (Config->get_default_session_parent_dir());
378 ArdourStartup::config_changed ()
380 config_modified = true;
384 ArdourStartup::setup_first_time_config_page ()
386 default_dir_chooser = manage (new FileChooserButton (string_compose (_("Default folder for %1 sessions"), PROGRAM_NAME),
387 FILE_CHOOSER_ACTION_SELECT_FOLDER));
388 Gtk::Label* txt = manage (new Label);
389 HBox* hbox = manage (new HBox);
390 VBox* vbox = manage (new VBox);
392 txt->set_markup (string_compose (_("\
393 Each project that you work on with %1 has its own folder.\n\
394 These can require a lot of disk space if you are recording audio.\n\
396 Where would you like new %1 sessions to be stored by default?\n\n\
397 <i>(You can put new sessions anywhere, this is just a default)</i>"), PROGRAM_NAME));
398 txt->set_alignment (0.0, 0.0);
400 vbox->set_spacing (18);
401 vbox->set_border_width (24);
403 hbox->pack_start (*default_dir_chooser, false, true, 8);
404 vbox->pack_start (*txt, false, false);
405 vbox->pack_start (*hbox, false, true);
407 cerr << "Setting defaultDIR session dir to [" << Config->get_default_session_parent_dir() << "]\n";
409 default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
410 default_dir_chooser->signal_current_folder_changed().connect (sigc::mem_fun (*this, &ArdourStartup::default_dir_changed));
411 default_dir_chooser->show ();
415 default_folder_page_index = append_page (*vbox);
416 set_page_title (*vbox, _("Default folder for new sessions"));
417 set_page_header_image (*vbox, icon_pixbuf);
418 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
420 /* user can just skip all these settings if they want to */
422 set_page_complete (*vbox, true);
426 ArdourStartup::setup_monitoring_choice_page ()
428 mon_vbox.set_spacing (18);
429 mon_vbox.set_border_width (24);
431 HBox* hbox = manage (new HBox);
432 VBox* vbox = manage (new VBox);
433 /* first button will be on by default */
434 RadioButton::Group g (monitor_via_ardour_button.get_group());
435 monitor_via_hardware_button.set_group (g);
437 monitor_label.set_markup(_("\
438 While recording instruments or vocals, you probably want to listen to the\n\
439 signal as well as record it. This is called \"monitoring\". There are\n\
440 different ways to do this depending on the equipment you have and the\n\
441 configuration of that equipment. The two most common are presented here.\n\
442 Please choose whichever one is right for your setup.\n\n\
443 <i>(You can change this preference at any time, via the Preferences dialog)</i>\n\n\
444 <i>If you do not understand what this is about, just accept the default.</i>"));
445 monitor_label.set_alignment (0.0, 0.0);
447 vbox->set_spacing (6);
449 vbox->pack_start (monitor_via_hardware_button, false, true);
450 vbox->pack_start (monitor_via_ardour_button, false, true);
451 hbox->pack_start (*vbox, true, true, 8);
452 mon_vbox.pack_start (monitor_label, false, false);
453 mon_vbox.pack_start (*hbox, false, false);
455 mon_vbox.show_all ();
457 monitoring_page_index = append_page (mon_vbox);
458 set_page_title (mon_vbox, _("Monitoring Choices"));
459 set_page_header_image (mon_vbox, icon_pixbuf);
461 /* user could just click on "Forward" if default
465 set_page_complete (mon_vbox, true);
469 ArdourStartup::setup_monitor_section_choice_page ()
471 mon_sec_vbox.set_spacing (18);
472 mon_sec_vbox.set_border_width (24);
474 HBox* hbox = manage (new HBox);
475 VBox* main_vbox = manage (new VBox);
477 Label* l = manage (new Label);
479 main_vbox->set_spacing (32);
481 no_monitor_section_button.set_label (_("Use a Master bus directly"));
482 l->set_alignment (0.0, 1.0);
483 l->set_markup(_("Connect the Master bus directly to your hardware outputs. This is preferable for simple usage."));
485 vbox = manage (new VBox);
486 vbox->set_spacing (6);
487 vbox->pack_start (no_monitor_section_button, false, true);
488 vbox->pack_start (*l, false, true);
490 main_vbox->pack_start (*vbox, false, false);
492 use_monitor_section_button.set_label (_("Use an additional Monitor bus"));
493 l = manage (new Label);
494 l->set_alignment (0.0, 1.0);
495 l->set_text (_("Use a Monitor bus between Master bus and hardware outputs for \n\
496 greater control in monitoring without affecting the mix."));
498 vbox = manage (new VBox);
499 vbox->set_spacing (6);
500 vbox->pack_start (use_monitor_section_button, false, true);
501 vbox->pack_start (*l, false, true);
503 main_vbox->pack_start (*vbox, false, false);
505 RadioButton::Group g (use_monitor_section_button.get_group());
506 no_monitor_section_button.set_group (g);
508 if (Config->get_use_monitor_bus()) {
509 use_monitor_section_button.set_active (true);
511 no_monitor_section_button.set_active (true);
514 use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
515 no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
517 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\
518 <i>If you do not understand what this is about, just accept the default.</i>"));
519 monitor_section_label.set_alignment (0.0, 0.0);
521 hbox->pack_start (*main_vbox, true, true, 8);
522 mon_sec_vbox.pack_start (*hbox, false, false);
523 mon_sec_vbox.pack_start (monitor_section_label, false, false);
525 mon_sec_vbox.show_all ();
527 monitor_section_page_index = append_page (mon_sec_vbox);
528 set_page_title (mon_sec_vbox, _("Monitor Section"));
529 set_page_header_image (mon_sec_vbox, icon_pixbuf);
531 /* user could just click on "Forward" if default
535 set_page_complete (mon_sec_vbox, true);
539 ArdourStartup::setup_initial_choice_page ()
541 ic_vbox.set_spacing (6);
542 ic_vbox.set_border_width (24);
544 RadioButton::Group g (ic_new_session_button.get_group());
545 ic_existing_session_button.set_group (g);
547 HBox* centering_hbox = manage (new HBox);
548 VBox* centering_vbox = manage (new VBox);
550 centering_vbox->set_spacing (6);
552 centering_vbox->pack_start (ic_new_session_button, false, true);
553 centering_vbox->pack_start (ic_existing_session_button, false, true);
555 ic_new_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
556 ic_new_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
558 ic_existing_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
559 ic_existing_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
561 centering_hbox->pack_start (*centering_vbox, true, true);
563 ic_vbox.pack_start (*centering_hbox, true, true);
567 initial_choice_index = append_page (ic_vbox);
568 set_page_title (ic_vbox, _("What would you like to do ?"));
569 set_page_header_image (ic_vbox, icon_pixbuf);
571 /* user could just click on "Forward" if default
575 set_page_complete (ic_vbox, true);
579 ArdourStartup::initial_button_clicked (GdkEventButton* ev)
581 if (ev->type == GDK_2BUTTON_PRESS && session_page_index != -1) {
582 set_current_page(session_page_index);
589 ArdourStartup::initial_button_activated ()
591 if (session_page_index != -1) {
592 set_current_page(session_page_index);
597 ArdourStartup::setup_session_page ()
599 session_vbox.set_border_width (24);
601 session_vbox.pack_start (session_hbox, true, true);
602 session_vbox.show_all ();
604 session_page_index = append_page (session_vbox);
605 /* initial setting */
606 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
610 ArdourStartup::setup_final_page ()
612 final_page.set_text (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
614 final_page_index = append_page (final_page);
615 set_page_complete (final_page, true);
616 set_page_header_image (final_page, icon_pixbuf);
617 set_page_type (final_page, ASSISTANT_PAGE_CONFIRM);
621 ArdourStartup::on_cancel ()
623 _response = RESPONSE_CANCEL;
628 ArdourStartup::on_delete_event (GdkEventAny*)
630 _response = RESPONSE_CLOSE;
636 ArdourStartup::on_apply ()
639 if (engine_dialog->setup_engine ()) {
640 set_current_page (audio_page_index);
645 if (config_modified) {
647 if (default_dir_chooser) {
648 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
651 if (monitor_via_hardware_button.get_active()) {
652 Config->set_monitoring_model (ExternalMonitoring);
653 } else if (monitor_via_ardour_button.get_active()) {
654 Config->set_monitoring_model (SoftwareMonitoring);
657 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
659 /* "touch" the been-here-before path now that we're about to save Config */
660 ofstream fout (been_here_before_path().c_str());
662 Config->save_state ();
665 _response = RESPONSE_OK;
670 ArdourStartup::on_prepare (Gtk::Widget* page)
672 if (page == &session_vbox) {
674 if (ic_new_session_button.get_active()) {
675 /* new session requested */
676 setup_new_session_page ();
678 /* existing session requested */
679 setup_existing_session_page ();
683 /* HACK HACK HACK ... change the "Apply" button label
687 Gtk::Widget* tl = session_vbox.get_toplevel();
689 if ((win = dynamic_cast<Gtk::Window*>(tl)) != 0) {
690 /* ::get_default_widget() is not wrapped in gtkmm */
691 Gtk::Widget* def = wrap (gtk_window_get_default_widget (win->gobj()));
693 if ((button = dynamic_cast<Gtk::Button*>(def)) != 0) {
694 if (more_new_session_options_button.get_active()) {
695 button->set_label (_("Forward"));
697 button->set_label (_("Open"));
705 ArdourStartup::populate_session_templates ()
707 vector<TemplateInfo> templates;
709 find_session_templates (templates);
711 template_model->clear ();
713 for (vector<TemplateInfo>::iterator x = templates.begin(); x != templates.end(); ++x) {
716 row = *(template_model->append ());
718 row[session_template_columns.name] = (*x).name;
719 row[session_template_columns.path] = (*x).path;
724 showmecf (GtkWidget* fc)
726 printf ("current folder just changed to %s\n", gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER(fc)));
727 printf ("current filename is currently %s\n", gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(fc)));
728 printf ("widget name is %s\n", gtk_widget_get_name (fc));
732 showmefs (GtkWidget * fcb)
734 printf ("file set, currently %s\n", gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(fcb)));
738 ArdourStartup::setup_new_session_page ()
740 g_signal_connect (G_OBJECT(new_folder_chooser.gobj()), "current-folder-changed", G_CALLBACK (showmecf), G_OBJECT(new_folder_chooser.gobj()));
741 g_signal_connect (G_OBJECT(new_folder_chooser.gobj()), "file-set", G_CALLBACK (showmefs), G_OBJECT(new_folder_chooser.gobj()));
743 if (!session_hbox.get_children().empty()) {
744 session_hbox.remove (**session_hbox.get_children().begin());
747 session_new_vbox.set_spacing (18);
749 if (session_new_vbox.get_children().empty()) {
750 VBox *vbox1 = manage (new VBox);
751 HBox* hbox1 = manage (new HBox);
752 Label* label1 = manage (new Label);
754 vbox1->set_spacing (6);
756 hbox1->set_spacing (6);
757 hbox1->pack_start (*label1, false, false);
758 hbox1->pack_start (new_name_entry, true, true);
760 label1->set_text (_("Session name:"));
763 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
764 new_name_entry.set_text (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
765 /* name provided - they can move right along */
766 set_page_complete (session_vbox, true);
769 new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_changed));
770 new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &ArdourStartup::move_along_now));
772 vbox1->pack_start (*hbox1, true, true);
776 HBox* hbox2 = manage (new HBox);
777 Label* label2 = manage (new Label);
779 hbox2->set_spacing (6);
780 hbox2->pack_start (*label2, false, false);
781 hbox2->pack_start (new_folder_chooser, true, true);
783 label2->set_text (_("Create session folder in:"));
785 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
786 new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
787 } else if (ARDOUR_UI::instance()->session_loaded) {
788 // point the new session file chooser at the parent directory of the current session
789 string session_parent_dir = Glib::path_get_dirname(ARDOUR_UI::instance()->the_session()->path());
790 string::size_type last_dir_sep = session_parent_dir.rfind(G_DIR_SEPARATOR);
791 session_parent_dir = session_parent_dir.substr(0, last_dir_sep);
792 new_folder_chooser.set_current_folder (session_parent_dir);
793 new_folder_chooser.add_shortcut_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
795 //new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
796 new_folder_chooser.set_current_folder ("/usr/local");
798 new_folder_chooser.show ();
799 new_folder_chooser.set_title (_("Select folder for session"));
802 new_folder_chooser.add_shortcut_folder ("/Volumes");
805 vbox1->pack_start (*hbox2, false, false);
807 session_new_vbox.pack_start (*vbox1, false, false);
811 VBox *vbox2 = manage (new VBox);
812 HBox* hbox3 = manage (new HBox);
813 Label* label3 = manage (new Label);
814 template_model = ListStore::create (session_template_columns);
815 populate_session_templates ();
817 vbox2->set_spacing (6);
819 label3->set_markup (_("<b>Options</b>"));
820 label3->set_alignment (0.0, 0.0);
822 vbox2->pack_start (*label3, false, true);
824 VBox *vbox3 = manage (new VBox);
826 vbox3->set_spacing (6);
828 if (!template_model->children().empty()) {
830 HBox* hbox4a = manage (new HBox);
831 use_template_button.set_label (_("Use this template"));
833 TreeModel::Row row = *template_model->prepend ();
834 row[session_template_columns.name] = (_("no template"));
835 row[session_template_columns.path] = string();
837 hbox4a->set_spacing (6);
838 hbox4a->pack_start (use_template_button, false, false);
839 hbox4a->pack_start (template_chooser, true, true);
841 template_chooser.set_model (template_model);
843 Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
844 text_renderer->property_editable() = false;
846 template_chooser.pack_start (*text_renderer);
847 template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
848 template_chooser.set_active (0);
850 use_template_button.show();
851 template_chooser.show ();
853 vbox3->pack_start (*hbox4a, false, false);
859 session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
861 HBox* hbox4b = manage (new HBox);
862 use_session_as_template_button.set_label (_("Use an existing session as a template:"));
864 hbox4b->set_spacing (6);
865 hbox4b->pack_start (use_session_as_template_button, false, false);
866 hbox4b->pack_start (session_template_chooser, true, true);
868 use_session_as_template_button.show ();
869 session_template_chooser.show ();
871 Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
872 session_filter->add_pattern (X_("*.ardour"));
873 session_template_chooser.set_filter (*session_filter);
874 session_template_chooser.set_title (_("Select template"));
876 vbox3->pack_start (*hbox4b, false, false);
881 HBox* hbox5 = manage (new HBox);
883 hbox5->set_spacing (6);
884 hbox5->pack_start (more_new_session_options_button, false, false);
886 more_new_session_options_button.show ();
887 more_new_session_options_button.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::more_new_session_options_button_clicked));
889 vbox3->pack_start (*hbox5, false, false);
890 hbox3->pack_start (*vbox3, true, true, 8);
891 vbox2->pack_start (*hbox3, false, false);
895 session_new_vbox.pack_start (*vbox2, false, false);
898 session_new_vbox.show_all ();
899 session_hbox.pack_start (session_new_vbox, true, true);
900 set_page_title (session_vbox, _("New Session"));
901 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
903 if (more_new_session_options_button.get_active()) {
904 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
909 ArdourStartup::new_name_changed ()
911 if (!new_name_entry.get_text().empty()) {
912 set_page_complete (session_vbox, true);
914 set_page_complete (session_vbox, false);
919 ArdourStartup::redisplay_recent_sessions ()
921 std::vector<std::string> session_directories;
922 RecentSessionsSorter cmp;
924 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
925 recent_session_model->clear ();
927 ARDOUR::RecentSessions rs;
928 ARDOUR::read_recent_sessions (rs);
931 recent_session_display.set_model (recent_session_model);
935 // sort them alphabetically
936 sort (rs.begin(), rs.end(), cmp);
938 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
939 session_directories.push_back ((*i).second);
942 int session_snapshot_count = 0;
944 for (vector<std::string>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
946 std::vector<std::string> state_file_paths;
948 // now get available states for this session
950 get_state_files_in_directory (*i, state_file_paths);
952 vector<string*>* states;
953 vector<const gchar*> item;
954 string fullpath = *i;
956 /* remove any trailing / */
958 if (fullpath[fullpath.length()-1] == '/') {
959 fullpath = fullpath.substr (0, fullpath.length()-1);
962 /* check whether session still exists */
963 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
964 /* session doesn't exist */
968 /* now get available states for this session */
970 if ((states = Session::possible_states (fullpath)) == 0) {
975 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
977 Gtk::TreeModel::Row row = *(recent_session_model->append());
979 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
980 row[recent_session_columns.fullpath] = fullpath;
981 row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
983 ++session_snapshot_count;
985 if (state_file_names.size() > 1) {
989 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
990 i2 != state_file_names.end(); ++i2) {
992 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
994 child_row[recent_session_columns.visible_name] = *i2;
995 child_row[recent_session_columns.fullpath] = fullpath;
996 child_row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
997 ++session_snapshot_count;
1002 recent_session_display.set_tooltip_column(1); // recent_session_columns.tip
1003 recent_session_display.set_model (recent_session_model);
1004 return session_snapshot_count;
1005 // return rs.size();
1009 ArdourStartup::recent_session_row_selected ()
1011 if (recent_session_display.get_selection()->count_selected_rows() > 0) {
1012 set_page_complete (session_vbox, true);
1014 set_page_complete (session_vbox, false);
1019 ArdourStartup::setup_existing_session_page ()
1021 recent_session_model = TreeStore::create (recent_session_columns);
1022 redisplay_recent_sessions ();
1024 if (!session_hbox.get_children().empty()) {
1025 session_hbox.remove (**session_hbox.get_children().begin());
1028 if (session_existing_vbox.get_children().empty()) {
1030 recent_session_display.set_model (recent_session_model);
1031 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1032 recent_session_display.set_headers_visible (false);
1033 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
1035 recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::recent_session_row_selected));
1037 recent_scroller.add (recent_session_display);
1038 recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1039 recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
1041 recent_session_display.show();
1043 recent_scroller.show();
1044 int cnt = redisplay_recent_sessions ();
1045 recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ArdourStartup::recent_row_activated));
1048 recent_scroller.set_size_request (-1, 300);
1051 session_existing_vbox.set_spacing (8);
1052 session_existing_vbox.pack_start (recent_scroller, true, true);
1054 existing_session_chooser.set_title (_("Select session file"));
1055 existing_session_chooser.signal_file_set().connect (sigc::mem_fun (*this, &ArdourStartup::existing_session_selected));
1056 existing_session_chooser.set_current_folder(poor_mans_glob (Config->get_default_session_parent_dir()));
1058 FileFilter session_filter;
1059 session_filter.add_pattern ("*.ardour");
1060 session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
1061 existing_session_chooser.add_filter (session_filter);
1062 existing_session_chooser.set_filter (session_filter);
1065 existing_session_chooser.add_shortcut_folder ("/Volumes");
1068 HBox* hbox = manage (new HBox);
1069 hbox->set_spacing (4);
1070 hbox->pack_start (*manage (new Label (_("Browse:"))), PACK_SHRINK);
1071 hbox->pack_start (existing_session_chooser);
1072 session_existing_vbox.pack_start (*hbox, false, false);
1076 session_existing_vbox.show_all ();
1077 session_hbox.pack_start (session_existing_vbox, true, true);
1079 set_page_title (session_vbox, _("Select a session"));
1080 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1084 ArdourStartup::more_new_session_options_button_clicked ()
1086 if (more_new_session_options_button.get_active()) {
1087 more_options_vbox.show_all ();
1088 set_page_type (more_options_vbox, ASSISTANT_PAGE_CONFIRM);
1089 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
1091 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1092 more_options_vbox.hide ();
1097 ArdourStartup::setup_more_options_page ()
1099 more_options_vbox.set_border_width (24);
1101 _output_limit_count.set_adjustment (_output_limit_count_adj);
1102 _input_limit_count.set_adjustment (_input_limit_count_adj);
1103 _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
1105 chan_count_label_1.set_text (_("channels"));
1106 chan_count_label_3.set_text (_("channels"));
1107 chan_count_label_4.set_text (_("channels"));
1109 chan_count_label_1.set_alignment(0,0.5);
1110 chan_count_label_1.set_padding(0,0);
1111 chan_count_label_1.set_line_wrap(false);
1113 chan_count_label_3.set_alignment(0,0.5);
1114 chan_count_label_3.set_padding(0,0);
1115 chan_count_label_3.set_line_wrap(false);
1117 chan_count_label_4.set_alignment(0,0.5);
1118 chan_count_label_4.set_padding(0,0);
1119 chan_count_label_4.set_line_wrap(false);
1121 bus_label.set_markup (_("<b>Busses</b>"));
1122 input_label.set_markup (_("<b>Inputs</b>"));
1123 output_label.set_markup (_("<b>Outputs</b>"));
1125 _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
1126 _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1127 _master_bus_channel_count.set_numeric(true);
1128 _master_bus_channel_count.set_digits(0);
1129 _master_bus_channel_count.set_wrap(false);
1131 _create_master_bus.set_label (_("Create master bus"));
1132 _create_master_bus.set_flags(Gtk::CAN_FOCUS);
1133 _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
1134 _create_master_bus.set_mode(true);
1135 _create_master_bus.set_active(true);
1136 _create_master_bus.set_border_width(0);
1138 advanced_table.set_row_spacings(0);
1139 advanced_table.set_col_spacings(0);
1141 _connect_inputs.set_label (_("Automatically connect to physical inputs"));
1142 _connect_inputs.set_flags(Gtk::CAN_FOCUS);
1143 _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
1144 _connect_inputs.set_mode(true);
1145 _connect_inputs.set_active(Config->get_input_auto_connect() != ManualConnect);
1146 _connect_inputs.set_border_width(0);
1148 _limit_input_ports.set_label (_("Use only"));
1149 _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
1150 _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
1151 _limit_input_ports.set_mode(true);
1152 _limit_input_ports.set_sensitive(true);
1153 _limit_input_ports.set_border_width(0);
1155 _input_limit_count.set_flags(Gtk::CAN_FOCUS);
1156 _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1157 _input_limit_count.set_numeric(true);
1158 _input_limit_count.set_digits(0);
1159 _input_limit_count.set_wrap(false);
1160 _input_limit_count.set_sensitive(false);
1162 bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
1164 bus_label.set_alignment(0, 0.5);
1165 bus_label.set_padding(0,0);
1166 bus_label.set_line_wrap(false);
1167 bus_label.set_selectable(false);
1168 bus_label.set_use_markup(true);
1169 bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
1170 bus_frame.set_label_align(0,0.5);
1171 bus_frame.add(bus_hbox);
1172 bus_frame.set_label_widget(bus_label);
1174 bus_table.set_row_spacings (0);
1175 bus_table.set_col_spacings (0);
1176 bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1177 bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1178 bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
1180 input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
1181 input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
1182 input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
1183 input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
1184 input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
1185 input_table.set_row_spacings(0);
1186 input_table.set_col_spacings(0);
1187 input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
1189 input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
1191 input_label.set_alignment(0, 0.5);
1192 input_label.set_padding(0,0);
1193 input_label.set_line_wrap(false);
1194 input_label.set_selectable(false);
1195 input_label.set_use_markup(true);
1196 input_frame.set_shadow_type(Gtk::SHADOW_NONE);
1197 input_frame.set_label_align(0,0.5);
1198 input_frame.add(input_hbox);
1199 input_frame.set_label_widget(input_label);
1201 _connect_outputs.set_label (_("Automatically connect outputs"));
1202 _connect_outputs.set_flags(Gtk::CAN_FOCUS);
1203 _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
1204 _connect_outputs.set_mode(true);
1205 _connect_outputs.set_active(Config->get_output_auto_connect() != ManualConnect);
1206 _connect_outputs.set_border_width(0);
1207 _limit_output_ports.set_label (_("Use only"));
1208 _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
1209 _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
1210 _limit_output_ports.set_mode(true);
1211 _limit_output_ports.set_sensitive(true);
1212 _limit_output_ports.set_border_width(0);
1213 _output_limit_count.set_flags(Gtk::CAN_FOCUS);
1214 _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1215 _output_limit_count.set_numeric(false);
1216 _output_limit_count.set_digits(0);
1217 _output_limit_count.set_wrap(false);
1218 _output_limit_count.set_sensitive(false);
1219 output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
1220 output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
1221 output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
1223 _connect_outputs_to_master.set_label (_("... to master bus"));
1224 _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
1225 _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
1226 _connect_outputs_to_master.set_mode(true);
1227 _connect_outputs_to_master.set_active(Config->get_output_auto_connect() == AutoConnectMaster);
1228 _connect_outputs_to_master.set_border_width(0);
1230 _connect_outputs_to_master.set_group (connect_outputs_group);
1231 _connect_outputs_to_physical.set_group (connect_outputs_group);
1233 _connect_outputs_to_physical.set_label (_("... to physical outputs"));
1234 _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
1235 _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
1236 _connect_outputs_to_physical.set_mode(true);
1237 _connect_outputs_to_physical.set_active(Config->get_output_auto_connect() == AutoConnectPhysical);
1238 _connect_outputs_to_physical.set_border_width(0);
1240 output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
1241 output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
1242 output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
1243 output_vbox.set_border_width(6);
1245 output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
1247 output_vbox.pack_start(output_conn_vbox);
1248 output_vbox.pack_start(output_port_vbox);
1250 output_label.set_alignment(0, 0.5);
1251 output_label.set_padding(0,0);
1252 output_label.set_line_wrap(false);
1253 output_label.set_selectable(false);
1254 output_label.set_use_markup(true);
1255 output_frame.set_shadow_type(Gtk::SHADOW_NONE);
1256 output_frame.set_label_align(0,0.5);
1258 output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
1260 output_frame.add(output_hbox);
1261 output_frame.set_label_widget(output_label);
1263 more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
1264 more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
1265 more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
1266 more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
1270 _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
1271 _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
1272 _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
1273 _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
1274 _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
1276 /* note that more_options_vbox is "visible" by default even
1277 * though it may not be displayed to the user, this is so the dialog
1280 more_options_vbox.show_all ();
1282 session_options_page_index = append_page (more_options_vbox);
1283 set_page_title (more_options_vbox, _("Advanced Session Options"));
1284 set_page_complete (more_options_vbox, true);
1288 ArdourStartup::create_master_bus() const
1290 return _create_master_bus.get_active();
1294 ArdourStartup::master_channel_count() const
1296 return _master_bus_channel_count.get_value_as_int();
1300 ArdourStartup::connect_inputs() const
1302 return _connect_inputs.get_active();
1306 ArdourStartup::limit_inputs_used_for_connection() const
1308 return _limit_input_ports.get_active();
1312 ArdourStartup::input_limit_count() const
1314 return _input_limit_count.get_value_as_int();
1318 ArdourStartup::connect_outputs() const
1320 return _connect_outputs.get_active();
1324 ArdourStartup::limit_outputs_used_for_connection() const
1326 return _limit_output_ports.get_active();
1330 ArdourStartup::output_limit_count() const
1332 return _output_limit_count.get_value_as_int();
1336 ArdourStartup::connect_outs_to_master() const
1338 return _connect_outputs_to_master.get_active();
1342 ArdourStartup::connect_outs_to_physical() const
1344 return _connect_outputs_to_physical.get_active();
1348 ArdourStartup::connect_inputs_clicked ()
1350 _limit_input_ports.set_sensitive(_connect_inputs.get_active());
1352 if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
1353 _input_limit_count.set_sensitive(true);
1355 _input_limit_count.set_sensitive(false);
1360 ArdourStartup::connect_outputs_clicked ()
1362 bool const co = _connect_outputs.get_active ();
1363 _limit_output_ports.set_sensitive(co);
1364 _connect_outputs_to_master.set_sensitive(co);
1365 _connect_outputs_to_physical.set_sensitive(co);
1367 if (co && _limit_output_ports.get_active()) {
1368 _output_limit_count.set_sensitive(true);
1370 _output_limit_count.set_sensitive(false);
1375 ArdourStartup::limit_inputs_clicked ()
1377 _input_limit_count.set_sensitive(_limit_input_ports.get_active());
1381 ArdourStartup::limit_outputs_clicked ()
1383 _output_limit_count.set_sensitive(_limit_output_ports.get_active());
1387 ArdourStartup::master_bus_button_clicked ()
1389 bool const yn = _create_master_bus.get_active();
1391 _master_bus_channel_count.set_sensitive(yn);
1392 _connect_outputs_to_master.set_sensitive(yn);
1396 ArdourStartup::move_along_now ()
1398 gint cur = get_current_page ();
1400 if (cur == session_page_index) {
1401 if (more_new_session_options_button.get_active()) {
1402 set_current_page (session_options_page_index);
1410 ArdourStartup::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
1412 set_page_complete (session_vbox, true);
1417 ArdourStartup::existing_session_selected ()
1419 _existing_session_chooser_used = true;
1421 set_page_complete (session_vbox, true);
1426 ArdourStartup::been_here_before_path () const
1428 // XXXX use more specific version so we can catch upgrades
1429 return Glib::build_filename (user_config_directory (), ".a3");