comment fix
[ardour2.git] / gtk2_ardour / startup.cc
blob9b58143746f0d4cd51834959d342da6cea12dd5f
1 /*
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.
20 #ifdef WAF_BUILD
21 #include "gtk2ardour-config.h"
22 #endif
24 #include <fstream>
25 #include <algorithm>
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/filesystem.h"
33 #include "pbd/replace_all.h"
34 #include "pbd/whitespace.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"
42 #include "startup.h"
43 #include "opts.h"
44 #include "engine_dialog.h"
45 #include "i18n.h"
46 #include "utils.h"
48 using namespace std;
49 using namespace Gtk;
50 using namespace Gdk;
51 using namespace Glib;
52 using namespace PBD;
53 using namespace ARDOUR;
55 ArdourStartup* ArdourStartup::the_startup = 0;
57 static string poor_mans_glob (string path)
59 string copy = path;
60 replace_all (copy, "~", Glib::get_home_dir());
61 return copy;
65 ArdourStartup::ArdourStartup ()
66 : _response (RESPONSE_OK)
67 , ic_new_session_button (_("Open a new session"))
68 , ic_existing_session_button (_("Open an existing session"))
69 , monitor_via_hardware_button (_("Use an external mixer or the hardware mixer of your audio interface.\n\
70 Ardour will play NO role in monitoring"))
71 , monitor_via_ardour_button (string_compose (_("Ask %1 to playback material as it is being recorded"), PROGRAM_NAME))
72 , new_folder_chooser (FILE_CHOOSER_ACTION_SELECT_FOLDER)
73 , more_new_session_options_button (_("I'd like more options for this session"))
74 , _output_limit_count_adj (1, 0, 100, 1, 10, 0)
75 , _input_limit_count_adj (1, 0, 100, 1, 10, 0)
76 , _master_bus_channel_count_adj (2, 0, 100, 1, 10, 0)
77 , _existing_session_chooser_used (false)
79 audio_page_index = -1;
80 initial_choice_index = -1;
81 new_user_page_index = -1;
82 default_folder_page_index = -1;
83 monitoring_page_index = -1;
84 session_page_index = -1;
85 final_page_index = -1;
86 session_options_page_index = -1;
87 new_only = false;
89 engine_dialog = 0;
90 config_modified = false;
91 default_dir_chooser = 0;
93 use_template_button.set_group (session_template_group);
94 use_session_as_template_button.set_group (session_template_group);
96 set_keep_above (true);
97 set_resizable (false);
98 set_position (WIN_POS_CENTER);
99 set_border_width (12);
101 if ((icon_pixbuf = ::get_icon ("ardour_icon_48px")) == 0) {
102 throw failed_constructor();
105 sys::path been_here_before = user_config_directory();
106 been_here_before /= ".a3"; // XXXX use more specific version so we can catch upgrades
107 new_user = !exists (been_here_before);
109 bool need_audio_setup = !EngineControl::engine_running();
111 if (new_user) {
112 /* "touch" the file */
113 ofstream fout (been_here_before.to_string().c_str());
114 setup_new_user_page ();
115 setup_first_time_config_page ();
116 setup_monitoring_choice_page ();
117 setup_monitor_section_choice_page ();
119 if (need_audio_setup) {
120 setup_audio_page ();
123 } else {
125 if (need_audio_setup) {
126 setup_audio_page ();
129 setup_initial_choice_page ();
132 setup_session_page ();
133 setup_more_options_page ();
135 if (new_user) {
136 setup_final_page ();
139 the_startup = this;
142 ArdourStartup::~ArdourStartup ()
146 void
147 ArdourStartup::set_new_only (bool yn)
149 new_only = yn;
151 if (new_only) {
152 ic_vbox.hide ();
153 } else {
154 ic_vbox.show ();
158 void
159 ArdourStartup::set_load_template (string load_template)
161 use_template_button.set_active (false);
162 load_template_override = load_template;
165 bool
166 ArdourStartup::use_session_template ()
168 if (!load_template_override.empty()) {
169 return true;
172 if (use_template_button.get_active()) {
173 return template_chooser.get_active_row_number() > 0;
174 } else {
175 return !session_template_chooser.get_filename().empty();
179 std::string
180 ArdourStartup::session_template_name ()
182 if (!load_template_override.empty()) {
183 string the_path = (ARDOUR::user_template_directory()/ (load_template_override + ".template")).to_string();
184 return the_path;
187 if (ic_existing_session_button.get_active()) {
188 return string();
191 if (use_template_button.get_active()) {
192 TreeModel::iterator iter = template_chooser.get_active ();
193 TreeModel::Row row = (*iter);
194 string s = row[session_template_columns.path];
195 return s;
196 } else {
197 return session_template_chooser.get_filename();
202 std::string
203 ArdourStartup::session_name (bool& should_be_new)
205 if (ic_new_session_button.get_active()) {
206 should_be_new = true;
207 string val = new_name_entry.get_text ();
208 strip_whitespace_edges (val);
209 return val;
210 } else if (_existing_session_chooser_used) {
211 /* existing session chosen from file chooser */
212 should_be_new = false;
213 return existing_session_chooser.get_filename ();
214 } else {
215 /* existing session chosen from recent list */
216 should_be_new = false;
218 TreeIter iter = recent_session_display.get_selection()->get_selected();
220 if (iter) {
221 return (*iter)[recent_session_columns.visible_name];
224 return "";
228 std::string
229 ArdourStartup::session_folder ()
231 if (ic_new_session_button.get_active()) {
232 std::string legal_session_folder_name = legalize_for_path (new_name_entry.get_text());
233 return Glib::build_filename (new_folder_chooser.get_current_folder(), legal_session_folder_name);
234 } else if (_existing_session_chooser_used) {
235 /* existing session chosen from file chooser */
236 return existing_session_chooser.get_current_folder ();
237 } else {
238 /* existing session chosen from recent list */
239 TreeIter iter = recent_session_display.get_selection()->get_selected();
241 if (iter) {
242 return (*iter)[recent_session_columns.fullpath];
244 return "";
248 void
249 ArdourStartup::setup_audio_page ()
251 engine_dialog = manage (new EngineControl);
253 engine_dialog->set_border_width (12);
255 engine_dialog->show_all ();
257 audio_page_index = append_page (*engine_dialog);
258 set_page_type (*engine_dialog, ASSISTANT_PAGE_CONTENT);
259 set_page_title (*engine_dialog, _("Audio / MIDI Setup"));
261 /* the default parameters should work, so the page is potentially complete */
263 set_page_complete (*engine_dialog, true);
266 void
267 ArdourStartup::setup_new_user_page ()
269 Label* foomatic = manage (new Label);
271 foomatic->set_markup (string_compose (_("\
272 <span size=\"larger\">%1 is a digital audio workstation. You can use it to\n\
273 record, edit and mix multi-track audio. You can produce your\n\
274 own CDs, mix video soundtracks, or just experiment with new\n\
275 ideas about music and sound.\n\
277 There are a few things that need to configured before you start\n\
278 using the program.</span>\
279 "), PROGRAM_NAME));
281 HBox* hbox = manage (new HBox);
282 HBox* vbox = manage (new HBox);
284 vbox->set_border_width (24);
286 hbox->pack_start (*foomatic, true, true);
287 vbox->pack_start (*hbox, true, true);
289 foomatic->show ();
290 hbox->show ();
291 vbox->show ();
293 new_user_page_index = append_page (*vbox);
294 set_page_type (*vbox, ASSISTANT_PAGE_INTRO);
295 set_page_title (*vbox, string_compose (_("Welcome to %1"), PROGRAM_NAME));
296 set_page_header_image (*vbox, icon_pixbuf);
297 set_page_complete (*vbox, true);
300 void
301 ArdourStartup::default_dir_changed ()
303 Config->set_default_session_parent_dir (default_dir_chooser->get_current_folder());
304 config_changed ();
307 void
308 ArdourStartup::config_changed ()
310 config_modified = true;
313 void
314 ArdourStartup::setup_first_time_config_page ()
316 default_dir_chooser = manage (new FileChooserButton (string_compose (_("Default folder for %1 sessions"), PROGRAM_NAME),
317 FILE_CHOOSER_ACTION_SELECT_FOLDER));
318 Gtk::Label* txt = manage (new Label);
319 HBox* hbox = manage (new HBox);
320 VBox* vbox = manage (new VBox);
322 txt->set_markup (string_compose (_("\
323 Each project that you work on with %1 has its own folder.\n\
324 These can require a lot of disk space if you are recording audio.\n\
326 Where would you like new %1 sessions to be stored by default?\n\n\
327 <i>(You can put new sessions anywhere, this is just a default)</i>"), PROGRAM_NAME));
328 txt->set_alignment (0.0, 0.0);
330 vbox->set_spacing (18);
331 vbox->set_border_width (24);
333 hbox->pack_start (*default_dir_chooser, false, true, 8);
334 vbox->pack_start (*txt, false, false);
335 vbox->pack_start (*hbox, false, true);
337 default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
338 default_dir_chooser->signal_current_folder_changed().connect (sigc::mem_fun (*this, &ArdourStartup::default_dir_changed));
339 default_dir_chooser->show ();
341 vbox->show_all ();
343 default_folder_page_index = append_page (*vbox);
344 set_page_title (*vbox, _("Default folder for new sessions"));
345 set_page_header_image (*vbox, icon_pixbuf);
346 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
348 /* user can just skip all these settings if they want to */
350 set_page_complete (*vbox, true);
353 void
354 ArdourStartup::setup_monitoring_choice_page ()
356 mon_vbox.set_spacing (18);
357 mon_vbox.set_border_width (24);
359 HBox* hbox = manage (new HBox);
360 VBox* vbox = manage (new VBox);
361 RadioButton::Group g (monitor_via_hardware_button.get_group());
362 monitor_via_ardour_button.set_group (g);
364 monitor_label.set_markup(_("\
365 While recording instruments or vocals, you probably want to listen to the\n\
366 signal as well as record it. This is called \"monitoring\". There are\n\
367 different ways to do this depending on the equipment you have and the\n\
368 configuration of that equipment. The two most common are presented here.\n\
369 Please choose whichever one is right for your setup.\n\n\
370 <i>(You can change this preference at any time, via the Preferences dialog)</i>"));
371 monitor_label.set_alignment (0.0, 0.0);
373 vbox->set_spacing (6);
375 vbox->pack_start (monitor_via_hardware_button, false, true);
376 vbox->pack_start (monitor_via_ardour_button, false, true);
377 hbox->pack_start (*vbox, true, true, 8);
378 mon_vbox.pack_start (monitor_label, false, false);
379 mon_vbox.pack_start (*hbox, false, false);
381 mon_vbox.show_all ();
383 monitoring_page_index = append_page (mon_vbox);
384 set_page_title (mon_vbox, _("Monitoring Choices"));
385 set_page_header_image (mon_vbox, icon_pixbuf);
387 /* user could just click on "Forward" if default
388 * choice is correct.
391 set_page_complete (mon_vbox, true);
394 void
395 ArdourStartup::setup_monitor_section_choice_page ()
397 mon_sec_vbox.set_spacing (18);
398 mon_sec_vbox.set_border_width (24);
400 HBox* hbox = manage (new HBox);
401 VBox* main_vbox = manage (new VBox);
402 VBox* vbox;
403 Label* l = manage (new Label);
405 main_vbox->set_spacing (32);
407 no_monitor_section_button.set_label (_("Use a Master bus directly"));
408 l->set_alignment (0.0, 1.0);
409 l->set_markup(_("Connect the Master bus directly to your hardware outputs.\n\
410 <i>Preferable for simple use</i>."));
412 vbox = manage (new VBox);
413 vbox->set_spacing (6);
414 vbox->pack_start (no_monitor_section_button, false, true);
415 vbox->pack_start (*l, false, true);
417 main_vbox->pack_start (*vbox, false, false);
419 use_monitor_section_button.set_label (_("Use an additional Monitor bus"));
420 l = manage (new Label);
421 l->set_alignment (0.0, 1.0);
422 l->set_text (_("Use a Monitor bus between Master bus and hardware outputs for \n\
423 greater control in monitoring without affecting the mix."));
425 vbox = manage (new VBox);
426 vbox->set_spacing (6);
427 vbox->pack_start (use_monitor_section_button, false, true);
428 vbox->pack_start (*l, false, true);
430 main_vbox->pack_start (*vbox, false, false);
432 RadioButton::Group g (use_monitor_section_button.get_group());
433 no_monitor_section_button.set_group (g);
435 if (Config->get_use_monitor_bus()) {
436 use_monitor_section_button.set_active (true);
437 } else {
438 no_monitor_section_button.set_active (true);
441 use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
442 no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
444 monitor_section_label.set_markup(_("<i><small>(You can change this preference at any time, via the Preferences dialog)</small></i>"));
445 monitor_section_label.set_alignment (0.0, 0.0);
447 hbox->pack_start (*main_vbox, true, true, 8);
448 mon_sec_vbox.pack_start (*hbox, false, false);
449 mon_sec_vbox.pack_start (monitor_section_label, false, false);
451 mon_sec_vbox.show_all ();
453 monitor_section_page_index = append_page (mon_sec_vbox);
454 set_page_title (mon_sec_vbox, _("Monitor Section"));
455 set_page_header_image (mon_sec_vbox, icon_pixbuf);
457 /* user could just click on "Forward" if default
458 * choice is correct.
461 set_page_complete (mon_sec_vbox, true);
464 void
465 ArdourStartup::setup_initial_choice_page ()
467 ic_vbox.set_spacing (6);
468 ic_vbox.set_border_width (24);
470 RadioButton::Group g (ic_new_session_button.get_group());
471 ic_existing_session_button.set_group (g);
473 HBox* centering_hbox = manage (new HBox);
474 VBox* centering_vbox = manage (new VBox);
476 centering_vbox->set_spacing (6);
478 centering_vbox->pack_start (ic_new_session_button, false, true);
479 centering_vbox->pack_start (ic_existing_session_button, false, true);
481 ic_new_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_press), false);
482 ic_new_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
484 ic_existing_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_press), false);
485 ic_existing_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
487 centering_hbox->pack_start (*centering_vbox, true, true);
489 ic_vbox.pack_start (*centering_hbox, true, true);
491 ic_vbox.show_all ();
493 initial_choice_index = append_page (ic_vbox);
494 set_page_title (ic_vbox, _("What would you like to do ?"));
495 set_page_header_image (ic_vbox, icon_pixbuf);
497 /* user could just click on "Forward" if default
498 * choice is correct.
501 set_page_complete (ic_vbox, true);
504 bool
505 ArdourStartup::initial_button_press (GdkEventButton *event)
507 if (event && event->type == GDK_2BUTTON_PRESS && session_page_index != -1) {
508 set_current_page(session_page_index);
509 return true;
510 } else {
511 return false;
515 void
516 ArdourStartup::initial_button_activated ()
518 set_current_page(session_page_index);
521 void
522 ArdourStartup::setup_session_page ()
524 session_vbox.set_border_width (24);
526 session_vbox.pack_start (session_hbox, true, true);
527 session_vbox.show_all ();
529 session_page_index = append_page (session_vbox);
530 /* initial setting */
531 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
534 void
535 ArdourStartup::setup_final_page ()
537 final_page.set_text (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
538 final_page.show ();
539 final_page_index = append_page (final_page);
540 set_page_complete (final_page, true);
541 set_page_header_image (final_page, icon_pixbuf);
542 set_page_type (final_page, ASSISTANT_PAGE_CONFIRM);
545 void
546 ArdourStartup::on_cancel ()
548 _response = RESPONSE_CANCEL;
549 gtk_main_quit ();
552 bool
553 ArdourStartup::on_delete_event (GdkEventAny*)
555 _response = RESPONSE_CLOSE;
556 gtk_main_quit ();
557 return true;
560 void
561 ArdourStartup::on_apply ()
563 if (engine_dialog) {
564 engine_dialog->setup_engine ();
567 if (config_modified) {
569 if (default_dir_chooser) {
570 Config->set_default_session_parent_dir (default_dir_chooser->get_current_folder());
573 if (monitor_via_hardware_button.get_active()) {
574 Config->set_monitoring_model (ExternalMonitoring);
575 } else if (monitor_via_ardour_button.get_active()) {
576 Config->set_monitoring_model (SoftwareMonitoring);
579 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
581 Config->save_state ();
584 _response = RESPONSE_OK;
585 gtk_main_quit ();
588 void
589 ArdourStartup::on_prepare (Gtk::Widget* page)
591 if (page == &session_vbox) {
593 if (ic_new_session_button.get_active()) {
594 /* new session requested */
595 setup_new_session_page ();
596 } else {
597 /* existing session requested */
598 setup_existing_session_page ();
603 void
604 ArdourStartup::populate_session_templates ()
606 vector<TemplateInfo> templates;
608 find_session_templates (templates);
610 template_model->clear ();
612 for (vector<TemplateInfo>::iterator x = templates.begin(); x != templates.end(); ++x) {
613 TreeModel::Row row;
615 row = *(template_model->append ());
617 row[session_template_columns.name] = (*x).name;
618 row[session_template_columns.path] = (*x).path;
622 static bool
623 lost_name_entry_focus (GdkEventFocus*)
625 cerr << "lost focus\n";
626 return false;
629 void
630 ArdourStartup::setup_new_session_page ()
632 if (!session_hbox.get_children().empty()) {
633 session_hbox.remove (**session_hbox.get_children().begin());
636 session_new_vbox.set_spacing (18);
638 if (session_new_vbox.get_children().empty()) {
639 VBox *vbox1 = manage (new VBox);
640 HBox* hbox1 = manage (new HBox);
641 Label* label1 = manage (new Label);
643 vbox1->set_spacing (6);
645 hbox1->set_spacing (6);
646 hbox1->pack_start (*label1, false, false);
647 hbox1->pack_start (new_name_entry, true, true);
649 label1->set_text (_("Session name:"));
652 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
653 new_name_entry.set_text (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
654 /* name provided - they can move right along */
655 set_page_complete (session_vbox, true);
658 new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_changed));
659 new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &ArdourStartup::move_along_now));
661 vbox1->pack_start (*hbox1, true, true);
663 /* --- */
665 HBox* hbox2 = manage (new HBox);
666 Label* label2 = manage (new Label);
668 hbox2->set_spacing (6);
669 hbox2->pack_start (*label2, false, false);
670 hbox2->pack_start (new_folder_chooser, true, true);
672 label2->set_text (_("Create session folder in:"));
674 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
675 new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
676 } else {
677 new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
679 new_folder_chooser.set_title (_("Select folder for session"));
681 #ifdef GTKOSX
682 new_folder_chooser.add_shortcut_folder ("/Volumes");
683 #endif
685 vbox1->pack_start (*hbox2, false, false);
687 session_new_vbox.pack_start (*vbox1, false, false);
689 /* --- */
691 VBox *vbox2 = manage (new VBox);
692 HBox* hbox3 = manage (new HBox);
693 Label* label3 = manage (new Label);
694 template_model = ListStore::create (session_template_columns);
695 populate_session_templates ();
697 vbox2->set_spacing (6);
699 label3->set_markup (_("<b>Options</b>"));
700 label3->set_alignment (0.0, 0.0);
702 vbox2->pack_start (*label3, false, true);
704 VBox *vbox3 = manage (new VBox);
706 vbox3->set_spacing (6);
708 if (!template_model->children().empty()) {
710 HBox* hbox4a = manage (new HBox);
711 use_template_button.set_label (_("Use this template"));
713 TreeModel::Row row = *template_model->prepend ();
714 row[session_template_columns.name] = (_("no template"));
715 row[session_template_columns.path] = string();
717 hbox4a->set_spacing (6);
718 hbox4a->pack_start (use_template_button, false, false);
719 hbox4a->pack_start (template_chooser, true, true);
721 template_chooser.set_model (template_model);
723 Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
724 text_renderer->property_editable() = false;
726 template_chooser.pack_start (*text_renderer);
727 template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
728 template_chooser.set_active (0);
730 use_template_button.show();
731 template_chooser.show ();
733 vbox3->pack_start (*hbox4a, false, false);
736 /* --- */
738 if (!new_user) {
739 session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
741 HBox* hbox4b = manage (new HBox);
742 use_session_as_template_button.set_label (_("Use an existing session as a template:"));
744 hbox4b->set_spacing (6);
745 hbox4b->pack_start (use_session_as_template_button, false, false);
746 hbox4b->pack_start (session_template_chooser, true, true);
748 use_session_as_template_button.show ();
749 session_template_chooser.show ();
751 Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
752 session_filter->add_pattern (X_("*.ardour"));
753 session_template_chooser.set_filter (*session_filter);
754 session_template_chooser.set_title (_("Select template"));
756 vbox3->pack_start (*hbox4b, false, false);
759 /* --- */
761 HBox* hbox5 = manage (new HBox);
763 hbox5->set_spacing (6);
764 hbox5->pack_start (more_new_session_options_button, false, false);
766 more_new_session_options_button.show ();
767 more_new_session_options_button.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::more_new_session_options_button_clicked));
769 vbox3->pack_start (*hbox5, false, false);
770 hbox3->pack_start (*vbox3, true, true, 8);
771 vbox2->pack_start (*hbox3, false, false);
773 /* --- */
775 session_new_vbox.pack_start (*vbox2, false, false);
778 session_new_vbox.show_all ();
779 session_hbox.pack_start (session_new_vbox, true, true);
780 set_page_title (session_vbox, _("New Session"));
781 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
783 new_name_entry.signal_map().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_mapped));
784 new_name_entry.signal_focus_out_event().connect (sigc::ptr_fun (lost_name_entry_focus));
787 void
788 ArdourStartup::new_name_mapped ()
790 cerr << "Grab new name focus\n";
791 new_name_entry.grab_focus ();
794 void
795 ArdourStartup::new_name_changed ()
797 if (!new_name_entry.get_text().empty()) {
798 set_page_complete (session_vbox, true);
799 } else {
800 set_page_complete (session_vbox, false);
805 ArdourStartup::redisplay_recent_sessions ()
807 std::vector<sys::path> session_directories;
808 RecentSessionsSorter cmp;
810 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
811 recent_session_model->clear ();
813 ARDOUR::RecentSessions rs;
814 ARDOUR::read_recent_sessions (rs);
816 if (rs.empty()) {
817 recent_session_display.set_model (recent_session_model);
818 return 0;
821 // sort them alphabetically
822 sort (rs.begin(), rs.end(), cmp);
824 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
825 session_directories.push_back ((*i).second);
828 for (vector<sys::path>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
830 std::vector<sys::path> state_file_paths;
832 // now get available states for this session
834 get_state_files_in_directory (*i, state_file_paths);
836 vector<string*>* states;
837 vector<const gchar*> item;
838 string fullpath = (*i).to_string();
840 /* remove any trailing / */
842 if (fullpath[fullpath.length()-1] == '/') {
843 fullpath = fullpath.substr (0, fullpath.length()-1);
846 /* check whether session still exists */
847 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
848 /* session doesn't exist */
849 continue;
852 /* now get available states for this session */
854 if ((states = Session::possible_states (fullpath)) == 0) {
855 /* no state file? */
856 continue;
859 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
861 Gtk::TreeModel::Row row = *(recent_session_model->append());
863 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
864 row[recent_session_columns.fullpath] = fullpath;
866 if (state_file_names.size() > 1) {
868 // add the children
870 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
871 i2 != state_file_names.end(); ++i2)
874 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
876 child_row[recent_session_columns.visible_name] = *i2;
877 child_row[recent_session_columns.fullpath] = fullpath;
882 recent_session_display.set_model (recent_session_model);
883 return rs.size();
886 void
887 ArdourStartup::recent_session_row_selected ()
889 if (recent_session_display.get_selection()->count_selected_rows() > 0) {
890 set_page_complete (session_vbox, true);
891 } else {
892 set_page_complete (session_vbox, false);
896 void
897 ArdourStartup::setup_existing_session_page ()
899 recent_session_model = TreeStore::create (recent_session_columns);
900 redisplay_recent_sessions ();
902 if (!session_hbox.get_children().empty()) {
903 session_hbox.remove (**session_hbox.get_children().begin());
906 if (session_existing_vbox.get_children().empty()) {
908 recent_session_display.set_model (recent_session_model);
909 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
910 recent_session_display.set_headers_visible (false);
911 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
913 recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::recent_session_row_selected));
915 recent_scroller.add (recent_session_display);
916 recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
917 recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
919 recent_session_display.show();
921 recent_scroller.show();
922 int cnt = redisplay_recent_sessions ();
923 recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ArdourStartup::recent_row_activated));
925 if (cnt > 4) {
926 recent_scroller.set_size_request (-1, 300);
929 session_existing_vbox.set_spacing (8);
930 session_existing_vbox.pack_start (recent_scroller, true, true);
932 existing_session_chooser.set_title (_("Select session file"));
933 existing_session_chooser.signal_file_set().connect (sigc::mem_fun (*this, &ArdourStartup::existing_session_selected));
935 #ifdef GTKOSX
936 existing_session_chooser.add_shortcut_folder ("/Volumes");
937 #endif
939 HBox* hbox = manage (new HBox);
940 hbox->set_spacing (4);
941 hbox->pack_start (*manage (new Label (_("Browse:"))), PACK_SHRINK);
942 hbox->pack_start (existing_session_chooser);
943 session_existing_vbox.pack_start (*hbox, false, false);
944 hbox->show_all ();
947 session_existing_vbox.show_all ();
948 session_hbox.pack_start (session_existing_vbox, true, true);
950 set_page_title (session_vbox, _("Select a session"));
951 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
954 void
955 ArdourStartup::more_new_session_options_button_clicked ()
957 if (more_new_session_options_button.get_active()) {
958 more_options_vbox.show_all ();
959 set_page_type (more_options_vbox, ASSISTANT_PAGE_CONFIRM);
960 set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
961 } else {
962 set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
963 more_options_vbox.hide ();
967 void
968 ArdourStartup::setup_more_options_page ()
970 more_options_vbox.set_border_width (24);
972 _output_limit_count.set_adjustment (_output_limit_count_adj);
973 _input_limit_count.set_adjustment (_input_limit_count_adj);
974 _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
976 chan_count_label_1.set_text (_("channels"));
977 chan_count_label_3.set_text (_("channels"));
978 chan_count_label_4.set_text (_("channels"));
980 chan_count_label_1.set_alignment(0,0.5);
981 chan_count_label_1.set_padding(0,0);
982 chan_count_label_1.set_line_wrap(false);
984 chan_count_label_3.set_alignment(0,0.5);
985 chan_count_label_3.set_padding(0,0);
986 chan_count_label_3.set_line_wrap(false);
988 chan_count_label_4.set_alignment(0,0.5);
989 chan_count_label_4.set_padding(0,0);
990 chan_count_label_4.set_line_wrap(false);
992 bus_label.set_markup (_("<b>Busses</b>"));
993 input_label.set_markup (_("<b>Inputs</b>"));
994 output_label.set_markup (_("<b>Outputs</b>"));
996 _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
997 _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
998 _master_bus_channel_count.set_numeric(true);
999 _master_bus_channel_count.set_digits(0);
1000 _master_bus_channel_count.set_wrap(false);
1002 _create_master_bus.set_label (_("Create master bus"));
1003 _create_master_bus.set_flags(Gtk::CAN_FOCUS);
1004 _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
1005 _create_master_bus.set_mode(true);
1006 _create_master_bus.set_active(true);
1007 _create_master_bus.set_border_width(0);
1009 advanced_table.set_row_spacings(0);
1010 advanced_table.set_col_spacings(0);
1012 _connect_inputs.set_label (_("Automatically connect to physical_inputs"));
1013 _connect_inputs.set_flags(Gtk::CAN_FOCUS);
1014 _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
1015 _connect_inputs.set_mode(true);
1016 _connect_inputs.set_active(true);
1017 _connect_inputs.set_border_width(0);
1019 _limit_input_ports.set_label (_("Use only"));
1020 _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
1021 _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
1022 _limit_input_ports.set_mode(true);
1023 _limit_input_ports.set_sensitive(true);
1024 _limit_input_ports.set_border_width(0);
1026 _input_limit_count.set_flags(Gtk::CAN_FOCUS);
1027 _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1028 _input_limit_count.set_numeric(true);
1029 _input_limit_count.set_digits(0);
1030 _input_limit_count.set_wrap(false);
1031 _input_limit_count.set_sensitive(false);
1033 bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
1035 bus_label.set_alignment(0, 0.5);
1036 bus_label.set_padding(0,0);
1037 bus_label.set_line_wrap(false);
1038 bus_label.set_selectable(false);
1039 bus_label.set_use_markup(true);
1040 bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
1041 bus_frame.set_label_align(0,0.5);
1042 bus_frame.add(bus_hbox);
1043 bus_frame.set_label_widget(bus_label);
1045 bus_table.set_row_spacings (0);
1046 bus_table.set_col_spacings (0);
1047 bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1048 bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
1049 bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
1051 input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
1052 input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
1053 input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
1054 input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
1055 input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
1056 input_table.set_row_spacings(0);
1057 input_table.set_col_spacings(0);
1058 input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
1060 input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
1062 input_label.set_alignment(0, 0.5);
1063 input_label.set_padding(0,0);
1064 input_label.set_line_wrap(false);
1065 input_label.set_selectable(false);
1066 input_label.set_use_markup(true);
1067 input_frame.set_shadow_type(Gtk::SHADOW_NONE);
1068 input_frame.set_label_align(0,0.5);
1069 input_frame.add(input_hbox);
1070 input_frame.set_label_widget(input_label);
1072 _connect_outputs.set_label (_("Automatically connect outputs"));
1073 _connect_outputs.set_flags(Gtk::CAN_FOCUS);
1074 _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
1075 _connect_outputs.set_mode(true);
1076 _connect_outputs.set_active(true);
1077 _connect_outputs.set_border_width(0);
1078 _limit_output_ports.set_label (_("Use only"));
1079 _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
1080 _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
1081 _limit_output_ports.set_mode(true);
1082 _limit_output_ports.set_sensitive(true);
1083 _limit_output_ports.set_border_width(0);
1084 _output_limit_count.set_flags(Gtk::CAN_FOCUS);
1085 _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
1086 _output_limit_count.set_numeric(false);
1087 _output_limit_count.set_digits(0);
1088 _output_limit_count.set_wrap(false);
1089 _output_limit_count.set_sensitive(false);
1090 output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
1091 output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
1092 output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
1094 _connect_outputs_to_master.set_label (_("... to master bus"));
1095 _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
1096 _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
1097 _connect_outputs_to_master.set_mode(true);
1098 _connect_outputs_to_master.set_active(false);
1099 _connect_outputs_to_master.set_border_width(0);
1101 _connect_outputs_to_master.set_group (connect_outputs_group);
1102 _connect_outputs_to_physical.set_group (connect_outputs_group);
1104 _connect_outputs_to_physical.set_label (_("... to physical outputs"));
1105 _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
1106 _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
1107 _connect_outputs_to_physical.set_mode(true);
1108 _connect_outputs_to_physical.set_active(false);
1109 _connect_outputs_to_physical.set_border_width(0);
1111 output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
1112 output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
1113 output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
1114 output_vbox.set_border_width(6);
1116 output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
1118 output_vbox.pack_start(output_conn_vbox);
1119 output_vbox.pack_start(output_port_vbox);
1121 output_label.set_alignment(0, 0.5);
1122 output_label.set_padding(0,0);
1123 output_label.set_line_wrap(false);
1124 output_label.set_selectable(false);
1125 output_label.set_use_markup(true);
1126 output_frame.set_shadow_type(Gtk::SHADOW_NONE);
1127 output_frame.set_label_align(0,0.5);
1129 output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
1131 output_frame.add(output_hbox);
1132 output_frame.set_label_widget(output_label);
1134 more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
1135 more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
1136 more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
1137 more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
1139 /* signals */
1141 _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
1142 _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
1143 _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
1144 _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
1145 _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
1147 /* note that more_options_vbox is NOT visible by
1148 * default. this is entirely by design - this page
1149 * should be skipped unless explicitly requested.
1152 session_options_page_index = append_page (more_options_vbox);
1153 set_page_title (more_options_vbox, _("Advanced Session Options"));
1154 set_page_complete (more_options_vbox, true);
1157 bool
1158 ArdourStartup::create_master_bus() const
1160 return _create_master_bus.get_active();
1164 ArdourStartup::master_channel_count() const
1166 return _master_bus_channel_count.get_value_as_int();
1169 bool
1170 ArdourStartup::connect_inputs() const
1172 return _connect_inputs.get_active();
1175 bool
1176 ArdourStartup::limit_inputs_used_for_connection() const
1178 return _limit_input_ports.get_active();
1182 ArdourStartup::input_limit_count() const
1184 return _input_limit_count.get_value_as_int();
1187 bool
1188 ArdourStartup::connect_outputs() const
1190 return _connect_outputs.get_active();
1193 bool
1194 ArdourStartup::limit_outputs_used_for_connection() const
1196 return _limit_output_ports.get_active();
1200 ArdourStartup::output_limit_count() const
1202 return _output_limit_count.get_value_as_int();
1205 bool
1206 ArdourStartup::connect_outs_to_master() const
1208 return _connect_outputs_to_master.get_active();
1211 bool
1212 ArdourStartup::connect_outs_to_physical() const
1214 return _connect_outputs_to_physical.get_active();
1217 void
1218 ArdourStartup::connect_inputs_clicked ()
1220 _limit_input_ports.set_sensitive(_connect_inputs.get_active());
1222 if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
1223 _input_limit_count.set_sensitive(true);
1224 } else {
1225 _input_limit_count.set_sensitive(false);
1229 void
1230 ArdourStartup::connect_outputs_clicked ()
1232 _limit_output_ports.set_sensitive(_connect_outputs.get_active());
1234 if (_connect_outputs.get_active() && _limit_output_ports.get_active()) {
1235 _output_limit_count.set_sensitive(true);
1236 } else {
1237 _output_limit_count.set_sensitive(false);
1241 void
1242 ArdourStartup::limit_inputs_clicked ()
1244 _input_limit_count.set_sensitive(_limit_input_ports.get_active());
1247 void
1248 ArdourStartup::limit_outputs_clicked ()
1250 _output_limit_count.set_sensitive(_limit_output_ports.get_active());
1253 void
1254 ArdourStartup::master_bus_button_clicked ()
1256 bool yn = _create_master_bus.get_active();
1258 _master_bus_channel_count.set_sensitive(yn);
1261 void
1262 ArdourStartup::move_along_now ()
1264 gint cur = get_current_page ();
1266 if (cur == session_page_index) {
1267 if (more_new_session_options_button.get_active()) {
1268 set_current_page (session_options_page_index);
1269 } else {
1270 on_apply ();
1275 void
1276 ArdourStartup::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
1278 set_page_complete (session_vbox, true);
1279 move_along_now ();
1282 void
1283 ArdourStartup::existing_session_selected ()
1285 _existing_session_chooser_used = true;
1287 set_page_complete (session_vbox, true);
1288 move_along_now ();