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 (_("Use an external mixer or the hardware mixer of your audio interface.\n\
74 Ardour will play NO role in monitoring"))
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);
133 // setup_prerelease_page ();
137 setup_new_user_page ();
138 setup_first_time_config_page ();
139 setup_monitoring_choice_page ();
140 setup_monitor_section_choice_page ();
142 if (need_audio_setup) {
146 ic_new_session_button.set_active (true); // always create new session on first run
150 if (need_audio_setup) {
154 setup_initial_choice_page ();
157 setup_session_page ();
158 setup_more_options_page ();
170 if (!template_name.empty()) {
171 use_template_button.set_active (false);
172 load_template_override = template_name;
179 ArdourStartup::~ArdourStartup ()
184 ArdourStartup::ready_without_display () const
186 return !new_user && !need_audio_setup && !need_session_info;
190 ArdourStartup::setup_prerelease_page ()
192 VBox* vbox = manage (new VBox);
193 Label* label = manage (new Label);
194 label->set_markup (_("<b>Welcome to this BETA release of Ardour 3.0</b>\n\n\
195 There are still several issues and bugs to be worked on,\n\
196 as well as general workflow improvements, before this can be considered\n\
197 release software. 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 2) Please see http://ardour.org/a3_features for a guide to new features.\n\
202 3) <b>Please do NOT use the forums at ardour.org to report issues</b>.\n\
203 4) Please <b>DO</b> use the bugtracker at http://tracker.ardour.org/ to report issues\n\
204 making sure to note the product version number as 3.0-beta.\n\
205 5) Please <b>DO</b> use the ardour-users mailing list to discuss ideas and pass on comments.\n\
206 6) Please <b>DO</b> join us on IRC for real time discussions about ardour3. You\n\
207 can get there directly from Ardour via the Help->Chat menu option.\n\
209 Full information on all the above can be found on the support page at\n\
211 http://ardour.org/support\n\
214 vbox->set_border_width (12);
215 vbox->pack_start (*label, false, false, 12);
219 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
220 set_page_title (*vbox, _("This is a BETA RELEASE"));
221 set_page_complete (*vbox, true);
225 ArdourStartup::use_session_template ()
227 if (!load_template_override.empty()) {
231 if (use_template_button.get_active()) {
232 return template_chooser.get_active_row_number() > 0;
234 return !session_template_chooser.get_filename().empty();
239 ArdourStartup::session_template_name ()
241 if (!load_template_override.empty()) {
242 string the_path (ARDOUR::user_template_directory());
243 return Glib::build_filename (the_path, load_template_override + ARDOUR::template_suffix);
246 if (ic_existing_session_button.get_active()) {
250 if (use_template_button.get_active()) {
251 TreeModel::iterator iter = template_chooser.get_active ();
252 TreeModel::Row row = (*iter);
253 string s = row[session_template_columns.path];
256 return session_template_chooser.get_filename();
262 ArdourStartup::session_name (bool& should_be_new)
264 if (ready_without_display()) {
265 return _provided_session_name;
268 if (ic_new_session_button.get_active()) {
269 should_be_new = true;
270 string val = new_name_entry.get_text ();
271 strip_whitespace_edges (val);
273 } else if (_existing_session_chooser_used) {
274 /* existing session chosen from file chooser */
275 should_be_new = false;
276 return existing_session_chooser.get_filename ();
278 /* existing session chosen from recent list */
279 should_be_new = false;
281 TreeIter iter = recent_session_display.get_selection()->get_selected();
284 return (*iter)[recent_session_columns.visible_name];
292 ArdourStartup::session_folder ()
294 if (ready_without_display()) {
295 return _provided_session_path;
298 if (ic_new_session_button.get_active()) {
299 std::string legal_session_folder_name = legalize_for_path (new_name_entry.get_text());
300 return Glib::build_filename (new_folder_chooser.get_current_folder(), legal_session_folder_name);
301 } else if (_existing_session_chooser_used) {
302 /* existing session chosen from file chooser */
303 return existing_session_chooser.get_current_folder ();
305 /* existing session chosen from recent list */
306 TreeIter iter = recent_session_display.get_selection()->get_selected();
309 return (*iter)[recent_session_columns.fullpath];
316 ArdourStartup::setup_audio_page ()
318 engine_dialog = manage (new EngineControl);
320 engine_dialog->set_border_width (12);
322 engine_dialog->show_all ();
324 audio_page_index = append_page (*engine_dialog);
325 set_page_type (*engine_dialog, ASSISTANT_PAGE_CONTENT);
326 set_page_title (*engine_dialog, _("Audio / MIDI Setup"));
328 /* the default parameters should work, so the page is potentially complete */
330 set_page_complete (*engine_dialog, true);
334 ArdourStartup::setup_new_user_page ()
336 Label* foomatic = manage (new Label);
338 foomatic->set_markup (string_compose (_("\
339 <span size=\"larger\">%1 is a digital audio workstation. You can use it to \
340 record, edit and mix multi-track audio. You can produce your \
341 own CDs, mix video soundtracks, or experiment with new \
342 ideas about music and sound. \
344 There are a few things that need to be configured before you start \
345 using the program.</span> \
347 foomatic->set_justify (JUSTIFY_FILL);
348 foomatic->set_line_wrap ();
350 HBox* hbox = manage (new HBox);
351 HBox* vbox = manage (new HBox);
353 vbox->set_border_width (24);
355 hbox->pack_start (*foomatic, true, true);
356 vbox->pack_start (*hbox, true, true);
362 new_user_page_index = append_page (*vbox);
363 set_page_type (*vbox, ASSISTANT_PAGE_INTRO);
364 set_page_title (*vbox, string_compose (_("Welcome to %1"), PROGRAM_NAME));
365 set_page_header_image (*vbox, icon_pixbuf);
366 set_page_complete (*vbox, true);
370 ArdourStartup::default_dir_changed ()
372 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
373 // make new session folder chooser point to the new default
374 new_folder_chooser.set_current_folder (Config->get_default_session_parent_dir());
379 ArdourStartup::config_changed ()
381 config_modified = true;
385 ArdourStartup::setup_first_time_config_page ()
387 default_dir_chooser = manage (new FileChooserButton (string_compose (_("Default folder for %1 sessions"), PROGRAM_NAME),
388 FILE_CHOOSER_ACTION_SELECT_FOLDER));
389 Gtk::Label* txt = manage (new Label);
390 HBox* hbox = manage (new HBox);
391 VBox* vbox = manage (new VBox);
393 txt->set_markup (string_compose (_("\
394 Each project that you work on with %1 has its own folder.\n\
395 These can require a lot of disk space if you are recording audio.\n\
397 Where would you like new %1 sessions to be stored by default?\n\n\
398 <i>(You can put new sessions anywhere, this is just a default)</i>"), PROGRAM_NAME));
399 txt->set_alignment (0.0, 0.0);
401 vbox->set_spacing (18);
402 vbox->set_border_width (24);
404 hbox->pack_start (*default_dir_chooser, false, true, 8);
405 vbox->pack_start (*txt, false, false);
406 vbox->pack_start (*hbox, false, true);
408 default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
409 default_dir_chooser->signal_current_folder_changed().connect (sigc::mem_fun (*this, &ArdourStartup::default_dir_changed));
410 default_dir_chooser->show ();
414 default_folder_page_index = append_page (*vbox);
415 set_page_title (*vbox, _("Default folder for new sessions"));
416 set_page_header_image (*vbox, icon_pixbuf);
417 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
419 /* user can just skip all these settings if they want to */
421 set_page_complete (*vbox, true);
425 ArdourStartup::setup_monitoring_choice_page ()
427 mon_vbox.set_spacing (18);
428 mon_vbox.set_border_width (24);
430 HBox* hbox = manage (new HBox);
431 VBox* vbox = manage (new VBox);
432 /* first button will be on by default */
433 RadioButton::Group g (monitor_via_ardour_button.get_group());
434 monitor_via_hardware_button.set_group (g);
436 monitor_label.set_markup(_("\
437 While recording instruments or vocals, you probably want to listen to the\n\
438 signal as well as record it. This is called \"monitoring\". There are\n\
439 different ways to do this depending on the equipment you have and the\n\
440 configuration of that equipment. The two most common are presented here.\n\
441 Please choose whichever one is right for your setup.\n\n\
442 <i>(You can change this preference at any time, via the Preferences dialog)</i>\n\n\
443 <i>If you do not understand what this is about, just accept the default.</i>"));
444 monitor_label.set_alignment (0.0, 0.0);
446 vbox->set_spacing (6);
448 vbox->pack_start (monitor_via_hardware_button, false, true);
449 vbox->pack_start (monitor_via_ardour_button, false, true);
450 hbox->pack_start (*vbox, true, true, 8);
451 mon_vbox.pack_start (monitor_label, false, false);
452 mon_vbox.pack_start (*hbox, false, false);
454 mon_vbox.show_all ();
456 monitoring_page_index = append_page (mon_vbox);
457 set_page_title (mon_vbox, _("Monitoring Choices"));
458 set_page_header_image (mon_vbox, icon_pixbuf);
460 /* user could just click on "Forward" if default
464 set_page_complete (mon_vbox, true);
468 ArdourStartup::setup_monitor_section_choice_page ()
470 mon_sec_vbox.set_spacing (18);
471 mon_sec_vbox.set_border_width (24);
473 HBox* hbox = manage (new HBox);
474 VBox* main_vbox = manage (new VBox);
476 Label* l = manage (new Label);
478 main_vbox->set_spacing (32);
480 no_monitor_section_button.set_label (_("Use a Master bus directly"));
481 l->set_alignment (0.0, 1.0);
482 l->set_markup(_("Connect the Master bus directly to your hardware outputs. This is preferable for simple usage."));
484 vbox = manage (new VBox);
485 vbox->set_spacing (6);
486 vbox->pack_start (no_monitor_section_button, false, true);
487 vbox->pack_start (*l, false, true);
489 main_vbox->pack_start (*vbox, false, false);
491 use_monitor_section_button.set_label (_("Use an additional Monitor bus"));
492 l = manage (new Label);
493 l->set_alignment (0.0, 1.0);
494 l->set_text (_("Use a Monitor bus between Master bus and hardware outputs for \n\
495 greater control in monitoring without affecting the mix."));
497 vbox = manage (new VBox);
498 vbox->set_spacing (6);
499 vbox->pack_start (use_monitor_section_button, false, true);
500 vbox->pack_start (*l, false, true);
502 main_vbox->pack_start (*vbox, false, false);
504 RadioButton::Group g (use_monitor_section_button.get_group());
505 no_monitor_section_button.set_group (g);
507 if (Config->get_use_monitor_bus()) {
508 use_monitor_section_button.set_active (true);
510 no_monitor_section_button.set_active (true);
513 use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
514 no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
516 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\
517 <i>If you do not understand what this is about, just accept the default.</i>"));
518 monitor_section_label.set_alignment (0.0, 0.0);
520 hbox->pack_start (*main_vbox, true, true, 8);
521 mon_sec_vbox.pack_start (*hbox, false, false);
522 mon_sec_vbox.pack_start (monitor_section_label, false, false);
524 mon_sec_vbox.show_all ();
526 monitor_section_page_index = append_page (mon_sec_vbox);
527 set_page_title (mon_sec_vbox, _("Monitor Section"));
528 set_page_header_image (mon_sec_vbox, icon_pixbuf);
530 /* user could just click on "Forward" if default
534 set_page_complete (mon_sec_vbox, true);
538 ArdourStartup::setup_initial_choice_page ()
540 ic_vbox.set_spacing (6);
541 ic_vbox.set_border_width (24);
543 RadioButton::Group g (ic_new_session_button.get_group());
544 ic_existing_session_button.set_group (g);
546 HBox* centering_hbox = manage (new HBox);
547 VBox* centering_vbox = manage (new VBox);
549 centering_vbox->set_spacing (6);
551 centering_vbox->pack_start (ic_new_session_button, false, true);
552 centering_vbox->pack_start (ic_existing_session_button, false, true);
554 ic_new_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
555 ic_new_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
557 ic_existing_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
558 ic_existing_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
560 centering_hbox->pack_start (*centering_vbox, true, true);
562 ic_vbox.pack_start (*centering_hbox, true, true);
566 initial_choice_index = append_page (ic_vbox);
567 set_page_title (ic_vbox, _("What would you like to do ?"));
568 set_page_header_image (ic_vbox, icon_pixbuf);
570 /* user could just click on "Forward" if default
574 set_page_complete (ic_vbox, true);
578 ArdourStartup::initial_button_clicked (GdkEventButton* ev)
580 if (ev->type == GDK_2BUTTON_PRESS && session_page_index != -1) {
581 set_current_page(session_page_index);
588 ArdourStartup::initial_button_activated ()
590 if (session_page_index != -1) {
591 set_current_page(session_page_index);
596 ArdourStartup::setup_session_page ()
598 session_vbox.set_border_width (24);
600 session_vbox.pack_start (session_hbox, true, true);
601 session_vbox.show_all ();
603 session_page_index = append_page (session_vbox);
604 /* initial setting */
605 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
609 ArdourStartup::setup_final_page ()
611 final_page.set_text (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
613 final_page_index = append_page (final_page);
614 set_page_complete (final_page, true);
615 set_page_header_image (final_page, icon_pixbuf);
616 set_page_type (final_page, ASSISTANT_PAGE_CONFIRM);
620 ArdourStartup::on_cancel ()
622 _response = RESPONSE_CANCEL;
627 ArdourStartup::on_delete_event (GdkEventAny*)
629 _response = RESPONSE_CLOSE;
635 ArdourStartup::on_apply ()
638 if (engine_dialog->setup_engine ()) {
639 set_current_page (audio_page_index);
644 if (config_modified) {
646 if (default_dir_chooser) {
647 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
650 if (monitor_via_hardware_button.get_active()) {
651 Config->set_monitoring_model (ExternalMonitoring);
652 } else if (monitor_via_ardour_button.get_active()) {
653 Config->set_monitoring_model (SoftwareMonitoring);
656 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
658 /* "touch" the been-here-before path now that we're about to save Config */
659 ofstream fout (been_here_before_path().c_str());
661 Config->save_state ();
664 _response = RESPONSE_OK;
669 ArdourStartup::on_prepare (Gtk::Widget* page)
671 if (page == &session_vbox) {
673 if (ic_new_session_button.get_active()) {
674 /* new session requested */
675 setup_new_session_page ();
677 /* existing session requested */
678 setup_existing_session_page ();
682 /* HACK HACK HACK ... change the "Apply" button label
686 Gtk::Widget* tl = session_vbox.get_toplevel();
688 if ((win = dynamic_cast<Gtk::Window*>(tl)) != 0) {
689 /* ::get_default_widget() is not wrapped in gtkmm */
690 Gtk::Widget* def = wrap (gtk_window_get_default_widget (win->gobj()));
692 if ((button = dynamic_cast<Gtk::Button*>(def)) != 0) {
693 if (more_new_session_options_button.get_active()) {
694 button->set_label (_("Forward"));
696 button->set_label (_("Open"));
704 ArdourStartup::populate_session_templates ()
706 vector<TemplateInfo> templates;
708 find_session_templates (templates);
710 template_model->clear ();
712 for (vector<TemplateInfo>::iterator x = templates.begin(); x != templates.end(); ++x) {
715 row = *(template_model->append ());
717 row[session_template_columns.name] = (*x).name;
718 row[session_template_columns.path] = (*x).path;
723 ArdourStartup::setup_new_session_page ()
725 if (!session_hbox.get_children().empty()) {
726 session_hbox.remove (**session_hbox.get_children().begin());
729 session_new_vbox.set_spacing (18);
731 if (session_new_vbox.get_children().empty()) {
732 VBox *vbox1 = manage (new VBox);
733 HBox* hbox1 = manage (new HBox);
734 Label* label1 = manage (new Label);
736 vbox1->set_spacing (6);
738 hbox1->set_spacing (6);
739 hbox1->pack_start (*label1, false, false);
740 hbox1->pack_start (new_name_entry, true, true);
742 label1->set_text (_("Session name:"));
745 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
746 new_name_entry.set_text (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
747 /* name provided - they can move right along */
748 set_page_complete (session_vbox, true);
751 new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_changed));
752 new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &ArdourStartup::move_along_now));
754 vbox1->pack_start (*hbox1, true, true);
758 HBox* hbox2 = manage (new HBox);
759 Label* label2 = manage (new Label);
761 hbox2->set_spacing (6);
762 hbox2->pack_start (*label2, false, false);
763 hbox2->pack_start (new_folder_chooser, true, true);
765 label2->set_text (_("Create session folder in:"));
767 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
768 new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
769 } else if (ARDOUR_UI::instance()->session_loaded) {
770 // point the new session file chooser at the parent directory of the current session
771 string session_parent_dir = Glib::path_get_dirname(ARDOUR_UI::instance()->the_session()->path());
772 string::size_type last_dir_sep = session_parent_dir.rfind(G_DIR_SEPARATOR);
773 session_parent_dir = session_parent_dir.substr(0, last_dir_sep);
774 new_folder_chooser.set_current_folder (session_parent_dir);
775 new_folder_chooser.add_shortcut_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
777 new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
779 new_folder_chooser.set_title (_("Select folder for session"));
782 new_folder_chooser.add_shortcut_folder ("/Volumes");
785 vbox1->pack_start (*hbox2, false, false);
787 session_new_vbox.pack_start (*vbox1, false, false);
791 VBox *vbox2 = manage (new VBox);
792 HBox* hbox3 = manage (new HBox);
793 Label* label3 = manage (new Label);
794 template_model = ListStore::create (session_template_columns);
795 populate_session_templates ();
797 vbox2->set_spacing (6);
799 label3->set_markup (_("<b>Options</b>"));
800 label3->set_alignment (0.0, 0.0);
802 vbox2->pack_start (*label3, false, true);
804 VBox *vbox3 = manage (new VBox);
806 vbox3->set_spacing (6);
808 if (!template_model->children().empty()) {
810 HBox* hbox4a = manage (new HBox);
811 use_template_button.set_label (_("Use this template"));
813 TreeModel::Row row = *template_model->prepend ();
814 row[session_template_columns.name] = (_("no template"));
815 row[session_template_columns.path] = string();
817 hbox4a->set_spacing (6);
818 hbox4a->pack_start (use_template_button, false, false);
819 hbox4a->pack_start (template_chooser, true, true);
821 template_chooser.set_model (template_model);
823 Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
824 text_renderer->property_editable() = false;
826 template_chooser.pack_start (*text_renderer);
827 template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
828 template_chooser.set_active (0);
830 use_template_button.show();
831 template_chooser.show ();
833 vbox3->pack_start (*hbox4a, false, false);
839 session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
841 HBox* hbox4b = manage (new HBox);
842 use_session_as_template_button.set_label (_("Use an existing session as a template:"));
844 hbox4b->set_spacing (6);
845 hbox4b->pack_start (use_session_as_template_button, false, false);
846 hbox4b->pack_start (session_template_chooser, true, true);
848 use_session_as_template_button.show ();
849 session_template_chooser.show ();
851 Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
852 session_filter->add_pattern (X_("*.ardour"));
853 session_template_chooser.set_filter (*session_filter);
854 session_template_chooser.set_title (_("Select template"));
856 vbox3->pack_start (*hbox4b, false, false);
861 HBox* hbox5 = manage (new HBox);
863 hbox5->set_spacing (6);
864 hbox5->pack_start (more_new_session_options_button, false, false);
866 more_new_session_options_button.show ();
867 more_new_session_options_button.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::more_new_session_options_button_clicked));
869 vbox3->pack_start (*hbox5, false, false);
870 hbox3->pack_start (*vbox3, true, true, 8);
871 vbox2->pack_start (*hbox3, false, false);
875 session_new_vbox.pack_start (*vbox2, false, false);
878 session_new_vbox.show_all ();
879 session_hbox.pack_start (session_new_vbox, true, true);
880 set_page_title (session_vbox, _("New Session"));
881 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
883 if (more_new_session_options_button.get_active()) {
884 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
889 ArdourStartup::new_name_changed ()
891 if (!new_name_entry.get_text().empty()) {
892 set_page_complete (session_vbox, true);
894 set_page_complete (session_vbox, false);
899 ArdourStartup::redisplay_recent_sessions ()
901 std::vector<std::string> session_directories;
902 RecentSessionsSorter cmp;
904 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
905 recent_session_model->clear ();
907 ARDOUR::RecentSessions rs;
908 ARDOUR::read_recent_sessions (rs);
911 recent_session_display.set_model (recent_session_model);
915 // sort them alphabetically
916 sort (rs.begin(), rs.end(), cmp);
918 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
919 session_directories.push_back ((*i).second);
922 int session_snapshot_count = 0;
924 for (vector<std::string>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
926 std::vector<std::string> state_file_paths;
928 // now get available states for this session
930 get_state_files_in_directory (*i, state_file_paths);
932 vector<string*>* states;
933 vector<const gchar*> item;
934 string fullpath = *i;
936 /* remove any trailing / */
938 if (fullpath[fullpath.length()-1] == '/') {
939 fullpath = fullpath.substr (0, fullpath.length()-1);
942 /* check whether session still exists */
943 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
944 /* session doesn't exist */
948 /* now get available states for this session */
950 if ((states = Session::possible_states (fullpath)) == 0) {
955 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
957 Gtk::TreeModel::Row row = *(recent_session_model->append());
959 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
960 row[recent_session_columns.fullpath] = fullpath;
961 row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
963 ++session_snapshot_count;
965 if (state_file_names.size() > 1) {
969 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
970 i2 != state_file_names.end(); ++i2) {
972 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
974 child_row[recent_session_columns.visible_name] = *i2;
975 child_row[recent_session_columns.fullpath] = fullpath;
976 child_row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
977 ++session_snapshot_count;
982 recent_session_display.set_tooltip_column(1); // recent_session_columns.tip
983 recent_session_display.set_model (recent_session_model);
984 return session_snapshot_count;
989 ArdourStartup::recent_session_row_selected ()
991 if (recent_session_display.get_selection()->count_selected_rows() > 0) {
992 set_page_complete (session_vbox, true);
994 set_page_complete (session_vbox, false);
999 ArdourStartup::setup_existing_session_page ()
1001 recent_session_model = TreeStore::create (recent_session_columns);
1002 redisplay_recent_sessions ();
1004 if (!session_hbox.get_children().empty()) {
1005 session_hbox.remove (**session_hbox.get_children().begin());
1008 if (session_existing_vbox.get_children().empty()) {
1010 recent_session_display.set_model (recent_session_model);
1011 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1012 recent_session_display.set_headers_visible (false);
1013 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
1015 recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::recent_session_row_selected));
1017 recent_scroller.add (recent_session_display);
1018 recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1019 recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
1021 recent_session_display.show();
1023 recent_scroller.show();
1024 int cnt = redisplay_recent_sessions ();
1025 recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ArdourStartup::recent_row_activated));
1028 recent_scroller.set_size_request (-1, 300);
1031 session_existing_vbox.set_spacing (8);
1032 session_existing_vbox.pack_start (recent_scroller, true, true);
1034 existing_session_chooser.set_title (_("Select session file"));
1035 existing_session_chooser.signal_file_set().connect (sigc::mem_fun (*this, &ArdourStartup::existing_session_selected));
1036 existing_session_chooser.set_current_folder(poor_mans_glob (Config->get_default_session_parent_dir()));
1038 FileFilter session_filter;
1039 session_filter.add_pattern ("*.ardour");
1040 session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
1041 existing_session_chooser.add_filter (session_filter);
1042 existing_session_chooser.set_filter (session_filter);
1045 existing_session_chooser.add_shortcut_folder ("/Volumes");
1048 HBox* hbox = manage (new HBox);
1049 hbox->set_spacing (4);
1050 hbox->pack_start (*manage (new Label (_("Browse:"))), PACK_SHRINK);
1051 hbox->pack_start (existing_session_chooser);
1052 session_existing_vbox.pack_start (*hbox, false, false);
1056 session_existing_vbox.show_all ();
1057 session_hbox.pack_start (session_existing_vbox, true, true);
1059 set_page_title (session_vbox, _("Select a session"));
1060 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1064 ArdourStartup::more_new_session_options_button_clicked ()
1066 if (more_new_session_options_button.get_active()) {
1067 more_options_vbox.show_all ();
1068 set_page_type (more_options_vbox, ASSISTANT_PAGE_CONFIRM);
1069 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
1071 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1072 more_options_vbox.hide ();
1077 ArdourStartup::setup_more_options_page ()
1079 more_options_vbox.set_border_width (24);
1081 _output_limit_count.set_adjustment (_output_limit_count_adj);
1082 _input_limit_count.set_adjustment (_input_limit_count_adj);
1083 _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
1085 chan_count_label_1.set_text (_("channels"));
1086 chan_count_label_3.set_text (_("channels"));
1087 chan_count_label_4.set_text (_("channels"));
1089 chan_count_label_1.set_alignment(0,0.5);
1090 chan_count_label_1.set_padding(0,0);
1091 chan_count_label_1.set_line_wrap(false);
1093 chan_count_label_3.set_alignment(0,0.5);
1094 chan_count_label_3.set_padding(0,0);
1095 chan_count_label_3.set_line_wrap(false);
1097 chan_count_label_4.set_alignment(0,0.5);
1098 chan_count_label_4.set_padding(0,0);
1099 chan_count_label_4.set_line_wrap(false);
1101 bus_label.set_markup (_("<b>Busses</b>"));
1102 input_label.set_markup (_("<b>Inputs</b>"));
1103 output_label.set_markup (_("<b>Outputs</b>"));
1105 _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
1106 _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1107 _master_bus_channel_count.set_numeric(true);
1108 _master_bus_channel_count.set_digits(0);
1109 _master_bus_channel_count.set_wrap(false);
1111 _create_master_bus.set_label (_("Create master bus"));
1112 _create_master_bus.set_flags(Gtk::CAN_FOCUS);
1113 _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
1114 _create_master_bus.set_mode(true);
1115 _create_master_bus.set_active(true);
1116 _create_master_bus.set_border_width(0);
1118 advanced_table.set_row_spacings(0);
1119 advanced_table.set_col_spacings(0);
1121 _connect_inputs.set_label (_("Automatically connect to physical inputs"));
1122 _connect_inputs.set_flags(Gtk::CAN_FOCUS);
1123 _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
1124 _connect_inputs.set_mode(true);
1125 _connect_inputs.set_active(Config->get_input_auto_connect() != ManualConnect);
1126 _connect_inputs.set_border_width(0);
1128 _limit_input_ports.set_label (_("Use only"));
1129 _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
1130 _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
1131 _limit_input_ports.set_mode(true);
1132 _limit_input_ports.set_sensitive(true);
1133 _limit_input_ports.set_border_width(0);
1135 _input_limit_count.set_flags(Gtk::CAN_FOCUS);
1136 _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1137 _input_limit_count.set_numeric(true);
1138 _input_limit_count.set_digits(0);
1139 _input_limit_count.set_wrap(false);
1140 _input_limit_count.set_sensitive(false);
1142 bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
1144 bus_label.set_alignment(0, 0.5);
1145 bus_label.set_padding(0,0);
1146 bus_label.set_line_wrap(false);
1147 bus_label.set_selectable(false);
1148 bus_label.set_use_markup(true);
1149 bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
1150 bus_frame.set_label_align(0,0.5);
1151 bus_frame.add(bus_hbox);
1152 bus_frame.set_label_widget(bus_label);
1154 bus_table.set_row_spacings (0);
1155 bus_table.set_col_spacings (0);
1156 bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1157 bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1158 bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
1160 input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
1161 input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
1162 input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
1163 input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
1164 input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
1165 input_table.set_row_spacings(0);
1166 input_table.set_col_spacings(0);
1167 input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
1169 input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
1171 input_label.set_alignment(0, 0.5);
1172 input_label.set_padding(0,0);
1173 input_label.set_line_wrap(false);
1174 input_label.set_selectable(false);
1175 input_label.set_use_markup(true);
1176 input_frame.set_shadow_type(Gtk::SHADOW_NONE);
1177 input_frame.set_label_align(0,0.5);
1178 input_frame.add(input_hbox);
1179 input_frame.set_label_widget(input_label);
1181 _connect_outputs.set_label (_("Automatically connect outputs"));
1182 _connect_outputs.set_flags(Gtk::CAN_FOCUS);
1183 _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
1184 _connect_outputs.set_mode(true);
1185 _connect_outputs.set_active(Config->get_output_auto_connect() != ManualConnect);
1186 _connect_outputs.set_border_width(0);
1187 _limit_output_ports.set_label (_("Use only"));
1188 _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
1189 _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
1190 _limit_output_ports.set_mode(true);
1191 _limit_output_ports.set_sensitive(true);
1192 _limit_output_ports.set_border_width(0);
1193 _output_limit_count.set_flags(Gtk::CAN_FOCUS);
1194 _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1195 _output_limit_count.set_numeric(false);
1196 _output_limit_count.set_digits(0);
1197 _output_limit_count.set_wrap(false);
1198 _output_limit_count.set_sensitive(false);
1199 output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
1200 output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
1201 output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
1203 _connect_outputs_to_master.set_label (_("... to master bus"));
1204 _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
1205 _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
1206 _connect_outputs_to_master.set_mode(true);
1207 _connect_outputs_to_master.set_active(Config->get_output_auto_connect() == AutoConnectMaster);
1208 _connect_outputs_to_master.set_border_width(0);
1210 _connect_outputs_to_master.set_group (connect_outputs_group);
1211 _connect_outputs_to_physical.set_group (connect_outputs_group);
1213 _connect_outputs_to_physical.set_label (_("... to physical outputs"));
1214 _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
1215 _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
1216 _connect_outputs_to_physical.set_mode(true);
1217 _connect_outputs_to_physical.set_active(Config->get_output_auto_connect() == AutoConnectPhysical);
1218 _connect_outputs_to_physical.set_border_width(0);
1220 output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
1221 output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
1222 output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
1223 output_vbox.set_border_width(6);
1225 output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
1227 output_vbox.pack_start(output_conn_vbox);
1228 output_vbox.pack_start(output_port_vbox);
1230 output_label.set_alignment(0, 0.5);
1231 output_label.set_padding(0,0);
1232 output_label.set_line_wrap(false);
1233 output_label.set_selectable(false);
1234 output_label.set_use_markup(true);
1235 output_frame.set_shadow_type(Gtk::SHADOW_NONE);
1236 output_frame.set_label_align(0,0.5);
1238 output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
1240 output_frame.add(output_hbox);
1241 output_frame.set_label_widget(output_label);
1243 more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
1244 more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
1245 more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
1246 more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
1250 _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
1251 _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
1252 _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
1253 _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
1254 _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
1256 /* note that more_options_vbox is "visible" by default even
1257 * though it may not be displayed to the user, this is so the dialog
1260 more_options_vbox.show_all ();
1262 session_options_page_index = append_page (more_options_vbox);
1263 set_page_title (more_options_vbox, _("Advanced Session Options"));
1264 set_page_complete (more_options_vbox, true);
1268 ArdourStartup::create_master_bus() const
1270 return _create_master_bus.get_active();
1274 ArdourStartup::master_channel_count() const
1276 return _master_bus_channel_count.get_value_as_int();
1280 ArdourStartup::connect_inputs() const
1282 return _connect_inputs.get_active();
1286 ArdourStartup::limit_inputs_used_for_connection() const
1288 return _limit_input_ports.get_active();
1292 ArdourStartup::input_limit_count() const
1294 return _input_limit_count.get_value_as_int();
1298 ArdourStartup::connect_outputs() const
1300 return _connect_outputs.get_active();
1304 ArdourStartup::limit_outputs_used_for_connection() const
1306 return _limit_output_ports.get_active();
1310 ArdourStartup::output_limit_count() const
1312 return _output_limit_count.get_value_as_int();
1316 ArdourStartup::connect_outs_to_master() const
1318 return _connect_outputs_to_master.get_active();
1322 ArdourStartup::connect_outs_to_physical() const
1324 return _connect_outputs_to_physical.get_active();
1328 ArdourStartup::connect_inputs_clicked ()
1330 _limit_input_ports.set_sensitive(_connect_inputs.get_active());
1332 if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
1333 _input_limit_count.set_sensitive(true);
1335 _input_limit_count.set_sensitive(false);
1340 ArdourStartup::connect_outputs_clicked ()
1342 bool const co = _connect_outputs.get_active ();
1343 _limit_output_ports.set_sensitive(co);
1344 _connect_outputs_to_master.set_sensitive(co);
1345 _connect_outputs_to_physical.set_sensitive(co);
1347 if (co && _limit_output_ports.get_active()) {
1348 _output_limit_count.set_sensitive(true);
1350 _output_limit_count.set_sensitive(false);
1355 ArdourStartup::limit_inputs_clicked ()
1357 _input_limit_count.set_sensitive(_limit_input_ports.get_active());
1361 ArdourStartup::limit_outputs_clicked ()
1363 _output_limit_count.set_sensitive(_limit_output_ports.get_active());
1367 ArdourStartup::master_bus_button_clicked ()
1369 bool const yn = _create_master_bus.get_active();
1371 _master_bus_channel_count.set_sensitive(yn);
1372 _connect_outputs_to_master.set_sensitive(yn);
1376 ArdourStartup::move_along_now ()
1378 gint cur = get_current_page ();
1380 if (cur == session_page_index) {
1381 if (more_new_session_options_button.get_active()) {
1382 set_current_page (session_options_page_index);
1390 ArdourStartup::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
1392 set_page_complete (session_vbox, true);
1397 ArdourStartup::existing_session_selected ()
1399 _existing_session_chooser_used = true;
1401 set_page_complete (session_vbox, true);
1406 ArdourStartup::been_here_before_path () const
1408 // XXXX use more specific version so we can catch upgrades
1409 return Glib::build_filename (user_config_directory (), ".a3");