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"
35 #include "ardour/filesystem_paths.h"
36 #include "ardour/recent_sessions.h"
37 #include "ardour/session.h"
38 #include "ardour/session_state_utils.h"
39 #include "ardour/template_utils.h"
40 #include "ardour/filename_extensions.h"
42 #include "ardour_ui.h"
45 #include "engine_dialog.h"
54 using namespace ARDOUR;
56 ArdourStartup* ArdourStartup::the_startup = 0;
58 static string poor_mans_glob (string path)
61 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 RadioButton::Group g (monitor_via_hardware_button.get_group());
433 monitor_via_ardour_button.set_group (g);
435 monitor_label.set_markup(_("\
436 While recording instruments or vocals, you probably want to listen to the\n\
437 signal as well as record it. This is called \"monitoring\". There are\n\
438 different ways to do this depending on the equipment you have and the\n\
439 configuration of that equipment. The two most common are presented here.\n\
440 Please choose whichever one is right for your setup.\n\n\
441 <i>(You can change this preference at any time, via the Preferences dialog)</i>\n\n\
442 <i>If you do not understand what this is about, just accept the default.</i>"));
443 monitor_label.set_alignment (0.0, 0.0);
445 vbox->set_spacing (6);
447 vbox->pack_start (monitor_via_hardware_button, false, true);
448 vbox->pack_start (monitor_via_ardour_button, false, true);
449 hbox->pack_start (*vbox, true, true, 8);
450 mon_vbox.pack_start (monitor_label, false, false);
451 mon_vbox.pack_start (*hbox, false, false);
453 mon_vbox.show_all ();
455 monitoring_page_index = append_page (mon_vbox);
456 set_page_title (mon_vbox, _("Monitoring Choices"));
457 set_page_header_image (mon_vbox, icon_pixbuf);
459 /* user could just click on "Forward" if default
463 set_page_complete (mon_vbox, true);
467 ArdourStartup::setup_monitor_section_choice_page ()
469 mon_sec_vbox.set_spacing (18);
470 mon_sec_vbox.set_border_width (24);
472 HBox* hbox = manage (new HBox);
473 VBox* main_vbox = manage (new VBox);
475 Label* l = manage (new Label);
477 main_vbox->set_spacing (32);
479 no_monitor_section_button.set_label (_("Use a Master bus directly"));
480 l->set_alignment (0.0, 1.0);
481 l->set_markup(_("Connect the Master bus directly to your hardware outputs. This is preferable for simple usage."));
483 vbox = manage (new VBox);
484 vbox->set_spacing (6);
485 vbox->pack_start (no_monitor_section_button, false, true);
486 vbox->pack_start (*l, false, true);
488 main_vbox->pack_start (*vbox, false, false);
490 use_monitor_section_button.set_label (_("Use an additional Monitor bus"));
491 l = manage (new Label);
492 l->set_alignment (0.0, 1.0);
493 l->set_text (_("Use a Monitor bus between Master bus and hardware outputs for \n\
494 greater control in monitoring without affecting the mix."));
496 vbox = manage (new VBox);
497 vbox->set_spacing (6);
498 vbox->pack_start (use_monitor_section_button, false, true);
499 vbox->pack_start (*l, false, true);
501 main_vbox->pack_start (*vbox, false, false);
503 RadioButton::Group g (use_monitor_section_button.get_group());
504 no_monitor_section_button.set_group (g);
506 if (Config->get_use_monitor_bus()) {
507 use_monitor_section_button.set_active (true);
509 no_monitor_section_button.set_active (true);
512 use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
513 no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
515 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\
516 <i>If you do not understand what this is about, just accept the default.</i>"));
517 monitor_section_label.set_alignment (0.0, 0.0);
519 hbox->pack_start (*main_vbox, true, true, 8);
520 mon_sec_vbox.pack_start (*hbox, false, false);
521 mon_sec_vbox.pack_start (monitor_section_label, false, false);
523 mon_sec_vbox.show_all ();
525 monitor_section_page_index = append_page (mon_sec_vbox);
526 set_page_title (mon_sec_vbox, _("Monitor Section"));
527 set_page_header_image (mon_sec_vbox, icon_pixbuf);
529 /* user could just click on "Forward" if default
533 set_page_complete (mon_sec_vbox, true);
537 ArdourStartup::setup_initial_choice_page ()
539 ic_vbox.set_spacing (6);
540 ic_vbox.set_border_width (24);
542 RadioButton::Group g (ic_new_session_button.get_group());
543 ic_existing_session_button.set_group (g);
545 HBox* centering_hbox = manage (new HBox);
546 VBox* centering_vbox = manage (new VBox);
548 centering_vbox->set_spacing (6);
550 centering_vbox->pack_start (ic_new_session_button, false, true);
551 centering_vbox->pack_start (ic_existing_session_button, false, true);
553 ic_new_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
554 ic_new_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
556 ic_existing_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
557 ic_existing_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
559 centering_hbox->pack_start (*centering_vbox, true, true);
561 ic_vbox.pack_start (*centering_hbox, true, true);
565 initial_choice_index = append_page (ic_vbox);
566 set_page_title (ic_vbox, _("What would you like to do ?"));
567 set_page_header_image (ic_vbox, icon_pixbuf);
569 /* user could just click on "Forward" if default
573 set_page_complete (ic_vbox, true);
577 ArdourStartup::initial_button_clicked (GdkEventButton* ev)
579 if (ev->type == GDK_2BUTTON_PRESS && session_page_index != -1) {
580 set_current_page(session_page_index);
587 ArdourStartup::initial_button_activated ()
589 if (session_page_index != -1) {
590 set_current_page(session_page_index);
595 ArdourStartup::setup_session_page ()
597 session_vbox.set_border_width (24);
599 session_vbox.pack_start (session_hbox, true, true);
600 session_vbox.show_all ();
602 session_page_index = append_page (session_vbox);
603 /* initial setting */
604 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
608 ArdourStartup::setup_final_page ()
610 final_page.set_text (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
612 final_page_index = append_page (final_page);
613 set_page_complete (final_page, true);
614 set_page_header_image (final_page, icon_pixbuf);
615 set_page_type (final_page, ASSISTANT_PAGE_CONFIRM);
619 ArdourStartup::on_cancel ()
621 _response = RESPONSE_CANCEL;
626 ArdourStartup::on_delete_event (GdkEventAny*)
628 _response = RESPONSE_CLOSE;
634 ArdourStartup::on_apply ()
637 if (engine_dialog->setup_engine ()) {
638 set_current_page (audio_page_index);
643 if (config_modified) {
645 if (default_dir_chooser) {
646 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
649 if (monitor_via_hardware_button.get_active()) {
650 Config->set_monitoring_model (ExternalMonitoring);
651 } else if (monitor_via_ardour_button.get_active()) {
652 Config->set_monitoring_model (SoftwareMonitoring);
655 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
657 /* "touch" the been-here-before path now that we're about to save Config */
658 ofstream fout (been_here_before_path().c_str());
660 Config->save_state ();
663 _response = RESPONSE_OK;
668 ArdourStartup::on_prepare (Gtk::Widget* page)
670 if (page == &session_vbox) {
672 if (ic_new_session_button.get_active()) {
673 /* new session requested */
674 setup_new_session_page ();
676 /* existing session requested */
677 setup_existing_session_page ();
681 /* HACK HACK HACK ... change the "Apply" button label
685 Gtk::Widget* tl = session_vbox.get_toplevel();
687 if ((win = dynamic_cast<Gtk::Window*>(tl)) != 0) {
688 /* ::get_default_widget() is not wrapped in gtkmm */
689 Gtk::Widget* def = wrap (gtk_window_get_default_widget (win->gobj()));
691 if ((button = dynamic_cast<Gtk::Button*>(def)) != 0) {
692 if (more_new_session_options_button.get_active()) {
693 button->set_label (_("Forward"));
695 button->set_label (_("Open"));
703 ArdourStartup::populate_session_templates ()
705 vector<TemplateInfo> templates;
707 find_session_templates (templates);
709 template_model->clear ();
711 for (vector<TemplateInfo>::iterator x = templates.begin(); x != templates.end(); ++x) {
714 row = *(template_model->append ());
716 row[session_template_columns.name] = (*x).name;
717 row[session_template_columns.path] = (*x).path;
722 lost_name_entry_focus (GdkEventFocus*)
724 // cerr << "lost focus\n";
729 ArdourStartup::setup_new_session_page ()
731 if (!session_hbox.get_children().empty()) {
732 session_hbox.remove (**session_hbox.get_children().begin());
735 session_new_vbox.set_spacing (18);
737 if (session_new_vbox.get_children().empty()) {
738 VBox *vbox1 = manage (new VBox);
739 HBox* hbox1 = manage (new HBox);
740 Label* label1 = manage (new Label);
742 vbox1->set_spacing (6);
744 hbox1->set_spacing (6);
745 hbox1->pack_start (*label1, false, false);
746 hbox1->pack_start (new_name_entry, true, true);
748 label1->set_text (_("Session name:"));
751 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
752 new_name_entry.set_text (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
753 /* name provided - they can move right along */
754 set_page_complete (session_vbox, true);
757 new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_changed));
758 new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &ArdourStartup::move_along_now));
760 vbox1->pack_start (*hbox1, true, true);
764 HBox* hbox2 = manage (new HBox);
765 Label* label2 = manage (new Label);
767 hbox2->set_spacing (6);
768 hbox2->pack_start (*label2, false, false);
769 hbox2->pack_start (new_folder_chooser, true, true);
771 label2->set_text (_("Create session folder in:"));
773 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
774 new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
775 } else if (ARDOUR_UI::instance()->session_loaded) {
776 // point the new session file chooser at the parent directory of the current session
777 string session_parent_dir = Glib::path_get_dirname(ARDOUR_UI::instance()->the_session()->path());
778 string::size_type last_dir_sep = session_parent_dir.rfind(G_DIR_SEPARATOR);
779 session_parent_dir = session_parent_dir.substr(0, last_dir_sep);
780 new_folder_chooser.set_current_folder (session_parent_dir);
781 new_folder_chooser.add_shortcut_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
783 new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
785 new_folder_chooser.set_title (_("Select folder for session"));
788 new_folder_chooser.add_shortcut_folder ("/Volumes");
791 vbox1->pack_start (*hbox2, false, false);
793 session_new_vbox.pack_start (*vbox1, false, false);
797 VBox *vbox2 = manage (new VBox);
798 HBox* hbox3 = manage (new HBox);
799 Label* label3 = manage (new Label);
800 template_model = ListStore::create (session_template_columns);
801 populate_session_templates ();
803 vbox2->set_spacing (6);
805 label3->set_markup (_("<b>Options</b>"));
806 label3->set_alignment (0.0, 0.0);
808 vbox2->pack_start (*label3, false, true);
810 VBox *vbox3 = manage (new VBox);
812 vbox3->set_spacing (6);
814 if (!template_model->children().empty()) {
816 HBox* hbox4a = manage (new HBox);
817 use_template_button.set_label (_("Use this template"));
819 TreeModel::Row row = *template_model->prepend ();
820 row[session_template_columns.name] = (_("no template"));
821 row[session_template_columns.path] = string();
823 hbox4a->set_spacing (6);
824 hbox4a->pack_start (use_template_button, false, false);
825 hbox4a->pack_start (template_chooser, true, true);
827 template_chooser.set_model (template_model);
829 Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
830 text_renderer->property_editable() = false;
832 template_chooser.pack_start (*text_renderer);
833 template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
834 template_chooser.set_active (0);
836 use_template_button.show();
837 template_chooser.show ();
839 vbox3->pack_start (*hbox4a, false, false);
845 session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
847 HBox* hbox4b = manage (new HBox);
848 use_session_as_template_button.set_label (_("Use an existing session as a template:"));
850 hbox4b->set_spacing (6);
851 hbox4b->pack_start (use_session_as_template_button, false, false);
852 hbox4b->pack_start (session_template_chooser, true, true);
854 use_session_as_template_button.show ();
855 session_template_chooser.show ();
857 Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
858 session_filter->add_pattern (X_("*.ardour"));
859 session_template_chooser.set_filter (*session_filter);
860 session_template_chooser.set_title (_("Select template"));
862 vbox3->pack_start (*hbox4b, false, false);
867 HBox* hbox5 = manage (new HBox);
869 hbox5->set_spacing (6);
870 hbox5->pack_start (more_new_session_options_button, false, false);
872 more_new_session_options_button.show ();
873 more_new_session_options_button.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::more_new_session_options_button_clicked));
875 vbox3->pack_start (*hbox5, false, false);
876 hbox3->pack_start (*vbox3, true, true, 8);
877 vbox2->pack_start (*hbox3, false, false);
881 session_new_vbox.pack_start (*vbox2, false, false);
884 session_new_vbox.show_all ();
885 session_hbox.pack_start (session_new_vbox, true, true);
886 set_page_title (session_vbox, _("New Session"));
887 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
889 if (more_new_session_options_button.get_active()) {
890 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
893 new_name_entry.signal_map().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_mapped));
894 new_name_entry.signal_focus_out_event().connect (sigc::ptr_fun (lost_name_entry_focus));
898 ArdourStartup::new_name_mapped ()
900 // cerr << "Grab new name focus\n";
901 new_name_entry.grab_focus ();
905 ArdourStartup::new_name_changed ()
907 if (!new_name_entry.get_text().empty()) {
908 set_page_complete (session_vbox, true);
910 set_page_complete (session_vbox, false);
915 ArdourStartup::redisplay_recent_sessions ()
917 std::vector<std::string> session_directories;
918 RecentSessionsSorter cmp;
920 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
921 recent_session_model->clear ();
923 ARDOUR::RecentSessions rs;
924 ARDOUR::read_recent_sessions (rs);
927 recent_session_display.set_model (recent_session_model);
931 // sort them alphabetically
932 sort (rs.begin(), rs.end(), cmp);
934 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
935 session_directories.push_back ((*i).second);
938 int session_snapshot_count = 0;
940 for (vector<std::string>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
942 std::vector<std::string> state_file_paths;
944 // now get available states for this session
946 get_state_files_in_directory (*i, state_file_paths);
948 vector<string*>* states;
949 vector<const gchar*> item;
950 string fullpath = *i;
952 /* remove any trailing / */
954 if (fullpath[fullpath.length()-1] == '/') {
955 fullpath = fullpath.substr (0, fullpath.length()-1);
958 /* check whether session still exists */
959 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
960 /* session doesn't exist */
964 /* now get available states for this session */
966 if ((states = Session::possible_states (fullpath)) == 0) {
971 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
973 Gtk::TreeModel::Row row = *(recent_session_model->append());
975 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
976 row[recent_session_columns.fullpath] = fullpath;
978 ++session_snapshot_count;
980 if (state_file_names.size() > 1) {
984 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
985 i2 != state_file_names.end(); ++i2)
988 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
990 child_row[recent_session_columns.visible_name] = *i2;
991 child_row[recent_session_columns.fullpath] = fullpath;
992 ++session_snapshot_count;
997 recent_session_display.set_tooltip_column(1); // recent_session_columns.fullpath
998 recent_session_display.set_model (recent_session_model);
999 return session_snapshot_count;
1000 // return rs.size();
1004 ArdourStartup::recent_session_row_selected ()
1006 if (recent_session_display.get_selection()->count_selected_rows() > 0) {
1007 set_page_complete (session_vbox, true);
1009 set_page_complete (session_vbox, false);
1014 ArdourStartup::setup_existing_session_page ()
1016 recent_session_model = TreeStore::create (recent_session_columns);
1017 redisplay_recent_sessions ();
1019 if (!session_hbox.get_children().empty()) {
1020 session_hbox.remove (**session_hbox.get_children().begin());
1023 if (session_existing_vbox.get_children().empty()) {
1025 recent_session_display.set_model (recent_session_model);
1026 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1027 recent_session_display.set_headers_visible (false);
1028 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
1030 recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::recent_session_row_selected));
1032 recent_scroller.add (recent_session_display);
1033 recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1034 recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
1036 recent_session_display.show();
1038 recent_scroller.show();
1039 int cnt = redisplay_recent_sessions ();
1040 recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ArdourStartup::recent_row_activated));
1043 recent_scroller.set_size_request (-1, 300);
1046 session_existing_vbox.set_spacing (8);
1047 session_existing_vbox.pack_start (recent_scroller, true, true);
1049 existing_session_chooser.set_title (_("Select session file"));
1050 existing_session_chooser.signal_file_set().connect (sigc::mem_fun (*this, &ArdourStartup::existing_session_selected));
1051 existing_session_chooser.set_current_folder(poor_mans_glob (Config->get_default_session_parent_dir()));
1053 FileFilter session_filter;
1054 session_filter.add_pattern ("*.ardour");
1055 session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
1056 existing_session_chooser.add_filter (session_filter);
1057 existing_session_chooser.set_filter (session_filter);
1060 existing_session_chooser.add_shortcut_folder ("/Volumes");
1063 HBox* hbox = manage (new HBox);
1064 hbox->set_spacing (4);
1065 hbox->pack_start (*manage (new Label (_("Browse:"))), PACK_SHRINK);
1066 hbox->pack_start (existing_session_chooser);
1067 session_existing_vbox.pack_start (*hbox, false, false);
1071 session_existing_vbox.show_all ();
1072 session_hbox.pack_start (session_existing_vbox, true, true);
1074 set_page_title (session_vbox, _("Select a session"));
1075 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1079 ArdourStartup::more_new_session_options_button_clicked ()
1081 if (more_new_session_options_button.get_active()) {
1082 more_options_vbox.show_all ();
1083 set_page_type (more_options_vbox, ASSISTANT_PAGE_CONFIRM);
1084 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
1086 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
1087 more_options_vbox.hide ();
1092 ArdourStartup::setup_more_options_page ()
1094 more_options_vbox.set_border_width (24);
1096 _output_limit_count.set_adjustment (_output_limit_count_adj);
1097 _input_limit_count.set_adjustment (_input_limit_count_adj);
1098 _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
1100 chan_count_label_1.set_text (_("channels"));
1101 chan_count_label_3.set_text (_("channels"));
1102 chan_count_label_4.set_text (_("channels"));
1104 chan_count_label_1.set_alignment(0,0.5);
1105 chan_count_label_1.set_padding(0,0);
1106 chan_count_label_1.set_line_wrap(false);
1108 chan_count_label_3.set_alignment(0,0.5);
1109 chan_count_label_3.set_padding(0,0);
1110 chan_count_label_3.set_line_wrap(false);
1112 chan_count_label_4.set_alignment(0,0.5);
1113 chan_count_label_4.set_padding(0,0);
1114 chan_count_label_4.set_line_wrap(false);
1116 bus_label.set_markup (_("<b>Busses</b>"));
1117 input_label.set_markup (_("<b>Inputs</b>"));
1118 output_label.set_markup (_("<b>Outputs</b>"));
1120 _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
1121 _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1122 _master_bus_channel_count.set_numeric(true);
1123 _master_bus_channel_count.set_digits(0);
1124 _master_bus_channel_count.set_wrap(false);
1126 _create_master_bus.set_label (_("Create master bus"));
1127 _create_master_bus.set_flags(Gtk::CAN_FOCUS);
1128 _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
1129 _create_master_bus.set_mode(true);
1130 _create_master_bus.set_active(true);
1131 _create_master_bus.set_border_width(0);
1133 advanced_table.set_row_spacings(0);
1134 advanced_table.set_col_spacings(0);
1136 _connect_inputs.set_label (_("Automatically connect to physical inputs"));
1137 _connect_inputs.set_flags(Gtk::CAN_FOCUS);
1138 _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
1139 _connect_inputs.set_mode(true);
1140 _connect_inputs.set_active(Config->get_input_auto_connect() != ManualConnect);
1141 _connect_inputs.set_border_width(0);
1143 _limit_input_ports.set_label (_("Use only"));
1144 _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
1145 _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
1146 _limit_input_ports.set_mode(true);
1147 _limit_input_ports.set_sensitive(true);
1148 _limit_input_ports.set_border_width(0);
1150 _input_limit_count.set_flags(Gtk::CAN_FOCUS);
1151 _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1152 _input_limit_count.set_numeric(true);
1153 _input_limit_count.set_digits(0);
1154 _input_limit_count.set_wrap(false);
1155 _input_limit_count.set_sensitive(false);
1157 bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
1159 bus_label.set_alignment(0, 0.5);
1160 bus_label.set_padding(0,0);
1161 bus_label.set_line_wrap(false);
1162 bus_label.set_selectable(false);
1163 bus_label.set_use_markup(true);
1164 bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
1165 bus_frame.set_label_align(0,0.5);
1166 bus_frame.add(bus_hbox);
1167 bus_frame.set_label_widget(bus_label);
1169 bus_table.set_row_spacings (0);
1170 bus_table.set_col_spacings (0);
1171 bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1172 bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1173 bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
1175 input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
1176 input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
1177 input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
1178 input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
1179 input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
1180 input_table.set_row_spacings(0);
1181 input_table.set_col_spacings(0);
1182 input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
1184 input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
1186 input_label.set_alignment(0, 0.5);
1187 input_label.set_padding(0,0);
1188 input_label.set_line_wrap(false);
1189 input_label.set_selectable(false);
1190 input_label.set_use_markup(true);
1191 input_frame.set_shadow_type(Gtk::SHADOW_NONE);
1192 input_frame.set_label_align(0,0.5);
1193 input_frame.add(input_hbox);
1194 input_frame.set_label_widget(input_label);
1196 _connect_outputs.set_label (_("Automatically connect outputs"));
1197 _connect_outputs.set_flags(Gtk::CAN_FOCUS);
1198 _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
1199 _connect_outputs.set_mode(true);
1200 _connect_outputs.set_active(Config->get_output_auto_connect() != ManualConnect);
1201 _connect_outputs.set_border_width(0);
1202 _limit_output_ports.set_label (_("Use only"));
1203 _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
1204 _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
1205 _limit_output_ports.set_mode(true);
1206 _limit_output_ports.set_sensitive(true);
1207 _limit_output_ports.set_border_width(0);
1208 _output_limit_count.set_flags(Gtk::CAN_FOCUS);
1209 _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1210 _output_limit_count.set_numeric(false);
1211 _output_limit_count.set_digits(0);
1212 _output_limit_count.set_wrap(false);
1213 _output_limit_count.set_sensitive(false);
1214 output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
1215 output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
1216 output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
1218 _connect_outputs_to_master.set_label (_("... to master bus"));
1219 _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
1220 _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
1221 _connect_outputs_to_master.set_mode(true);
1222 _connect_outputs_to_master.set_active(Config->get_output_auto_connect() == AutoConnectMaster);
1223 _connect_outputs_to_master.set_border_width(0);
1225 _connect_outputs_to_master.set_group (connect_outputs_group);
1226 _connect_outputs_to_physical.set_group (connect_outputs_group);
1228 _connect_outputs_to_physical.set_label (_("... to physical outputs"));
1229 _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
1230 _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
1231 _connect_outputs_to_physical.set_mode(true);
1232 _connect_outputs_to_physical.set_active(Config->get_output_auto_connect() == AutoConnectPhysical);
1233 _connect_outputs_to_physical.set_border_width(0);
1235 output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
1236 output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
1237 output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
1238 output_vbox.set_border_width(6);
1240 output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
1242 output_vbox.pack_start(output_conn_vbox);
1243 output_vbox.pack_start(output_port_vbox);
1245 output_label.set_alignment(0, 0.5);
1246 output_label.set_padding(0,0);
1247 output_label.set_line_wrap(false);
1248 output_label.set_selectable(false);
1249 output_label.set_use_markup(true);
1250 output_frame.set_shadow_type(Gtk::SHADOW_NONE);
1251 output_frame.set_label_align(0,0.5);
1253 output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
1255 output_frame.add(output_hbox);
1256 output_frame.set_label_widget(output_label);
1258 more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
1259 more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
1260 more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
1261 more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
1265 _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
1266 _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
1267 _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
1268 _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
1269 _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
1271 /* note that more_options_vbox is "visible" by default even
1272 * though it may not be displayed to the user, this is so the dialog
1275 more_options_vbox.show_all ();
1277 session_options_page_index = append_page (more_options_vbox);
1278 set_page_title (more_options_vbox, _("Advanced Session Options"));
1279 set_page_complete (more_options_vbox, true);
1283 ArdourStartup::create_master_bus() const
1285 return _create_master_bus.get_active();
1289 ArdourStartup::master_channel_count() const
1291 return _master_bus_channel_count.get_value_as_int();
1295 ArdourStartup::connect_inputs() const
1297 return _connect_inputs.get_active();
1301 ArdourStartup::limit_inputs_used_for_connection() const
1303 return _limit_input_ports.get_active();
1307 ArdourStartup::input_limit_count() const
1309 return _input_limit_count.get_value_as_int();
1313 ArdourStartup::connect_outputs() const
1315 return _connect_outputs.get_active();
1319 ArdourStartup::limit_outputs_used_for_connection() const
1321 return _limit_output_ports.get_active();
1325 ArdourStartup::output_limit_count() const
1327 return _output_limit_count.get_value_as_int();
1331 ArdourStartup::connect_outs_to_master() const
1333 return _connect_outputs_to_master.get_active();
1337 ArdourStartup::connect_outs_to_physical() const
1339 return _connect_outputs_to_physical.get_active();
1343 ArdourStartup::connect_inputs_clicked ()
1345 _limit_input_ports.set_sensitive(_connect_inputs.get_active());
1347 if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
1348 _input_limit_count.set_sensitive(true);
1350 _input_limit_count.set_sensitive(false);
1355 ArdourStartup::connect_outputs_clicked ()
1357 bool const co = _connect_outputs.get_active ();
1358 _limit_output_ports.set_sensitive(co);
1359 _connect_outputs_to_master.set_sensitive(co);
1360 _connect_outputs_to_physical.set_sensitive(co);
1362 if (co && _limit_output_ports.get_active()) {
1363 _output_limit_count.set_sensitive(true);
1365 _output_limit_count.set_sensitive(false);
1370 ArdourStartup::limit_inputs_clicked ()
1372 _input_limit_count.set_sensitive(_limit_input_ports.get_active());
1376 ArdourStartup::limit_outputs_clicked ()
1378 _output_limit_count.set_sensitive(_limit_output_ports.get_active());
1382 ArdourStartup::master_bus_button_clicked ()
1384 bool const yn = _create_master_bus.get_active();
1386 _master_bus_channel_count.set_sensitive(yn);
1387 _connect_outputs_to_master.set_sensitive(yn);
1391 ArdourStartup::move_along_now ()
1393 gint cur = get_current_page ();
1395 if (cur == session_page_index) {
1396 if (more_new_session_options_button.get_active()) {
1397 set_current_page (session_options_page_index);
1405 ArdourStartup::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
1407 set_page_complete (session_vbox, true);
1412 ArdourStartup::existing_session_selected ()
1414 _existing_session_chooser_used = true;
1416 set_page_complete (session_vbox, true);
1421 ArdourStartup::been_here_before_path () const
1423 // XXXX use more specific version so we can catch upgrades
1424 return Glib::build_filename (user_config_directory (), ".a3");