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"
22 #include "gtk2ardour-version.h"
28 #include "pbd/gstdio_compat.h"
30 #include <gtkmm/main.h>
31 #include <gtkmm/filechooser.h>
33 #include "pbd/failed_constructor.h"
34 #include "pbd/scoped_file_descriptor.h"
35 #include "pbd/file_utils.h"
36 #include "pbd/replace_all.h"
37 #include "pbd/whitespace.h"
38 #include "pbd/stacktrace.h"
39 #include "pbd/openuri.h"
41 #include "ardour/audioengine.h"
42 #include "ardour/filesystem_paths.h"
43 #include "ardour/filename_extensions.h"
44 #include "ardour/plugin_manager.h"
45 #include "ardour/recent_sessions.h"
46 #include "ardour/session.h"
47 #include "ardour/session_state_utils.h"
48 #include "ardour/template_utils.h"
49 #include "ardour/profile.h"
53 #include "engine_dialog.h"
62 using namespace ARDOUR;
63 using namespace ARDOUR_UI_UTILS;
65 ArdourStartup* ArdourStartup::the_startup = 0;
67 ArdourStartup::ArdourStartup ()
68 : _response (RESPONSE_OK)
69 , config_modified (false)
70 , default_dir_chooser (0)
71 , monitor_via_hardware_button (string_compose (_("Use an external mixer or the hardware mixer of your audio interface.\n"
72 "%1 will play NO role in monitoring"), PROGRAM_NAME))
73 , monitor_via_ardour_button (string_compose (_("Ask %1 to play back material as it is being recorded"), PROGRAM_NAME))
74 , audio_page_index (-1)
75 , new_user_page_index (-1)
76 , default_folder_page_index (-1)
77 , monitoring_page_index (-1)
78 , final_page_index (-1)
80 set_position (WIN_POS_CENTER);
81 set_border_width (12);
83 if (! (icon_pixbuf = ::get_icon (PROGRAM_NAME "-icon_48px"))) {
84 throw failed_constructor();
87 list<Glib::RefPtr<Gdk::Pixbuf> > window_icons;
88 Glib::RefPtr<Gdk::Pixbuf> icon;
90 if ((icon = ::get_icon (PROGRAM_NAME "-icon_16px"))) {
91 window_icons.push_back (icon);
93 if ((icon = ::get_icon (PROGRAM_NAME "-icon_22px"))) {
94 window_icons.push_back (icon);
96 if ((icon = ::get_icon (PROGRAM_NAME "-icon_32px"))) {
97 window_icons.push_back (icon);
99 if ((icon = ::get_icon (PROGRAM_NAME "-icon_48px"))) {
100 window_icons.push_back (icon);
102 if (!window_icons.empty ()) {
103 set_default_icon_list (window_icons);
106 setup_new_user_page ();
107 setup_first_time_config_page ();
108 setup_monitoring_choice_page ();
109 setup_monitor_section_choice_page ();
115 ArdourStartup::~ArdourStartup ()
120 ArdourStartup::required ()
122 if (Glib::file_test (ARDOUR::been_here_before_path (), Glib::FILE_TEST_EXISTS)) {
130 ArdourStartup::setup_new_user_page ()
132 Label* foomatic = manage (new Label);
134 foomatic->set_markup (string_compose (_("\
135 <span size=\"larger\">%1 is a digital audio workstation. You can use it to \
136 record, edit and mix multi-track audio. You can produce your \
137 own CDs, mix video soundtracks, or experiment with new \
138 ideas about music and sound. \
140 There are a few things that need to be configured before you start \
141 using the program.</span> \
143 foomatic->set_justify (JUSTIFY_FILL);
144 foomatic->set_line_wrap ();
146 HBox* hbox = manage (new HBox);
147 HBox* vbox = manage (new HBox);
149 vbox->set_border_width (24);
151 hbox->pack_start (*foomatic, true, true);
152 vbox->pack_start (*hbox, true, true);
158 new_user_page_index = append_page (*vbox);
159 set_page_type (*vbox, ASSISTANT_PAGE_INTRO);
160 set_page_title (*vbox, string_compose (_("Welcome to %1"), PROGRAM_NAME));
161 set_page_header_image (*vbox, icon_pixbuf);
162 set_page_complete (*vbox, true);
166 ArdourStartup::default_dir_changed ()
168 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
169 // make new session folder chooser point to the new default
170 new_folder_chooser.set_current_folder (Config->get_default_session_parent_dir());
175 ArdourStartup::config_changed ()
177 config_modified = true;
181 ArdourStartup::setup_first_time_config_page ()
183 default_dir_chooser = manage (new FileChooserButton (string_compose (_("Default folder for %1 sessions"), PROGRAM_NAME),
184 FILE_CHOOSER_ACTION_SELECT_FOLDER));
185 Gtk::Label* txt = manage (new Label);
186 HBox* hbox = manage (new HBox);
187 VBox* vbox = manage (new VBox);
189 txt->set_markup (string_compose (_("\
190 Each project that you work on with %1 has its own folder.\n\
191 These can require a lot of disk space if you are recording audio.\n\
193 Where would you like new %1 sessions to be stored by default?\n\n\
194 <i>(You can put new sessions anywhere, this is just a default)</i>"), PROGRAM_NAME));
195 txt->set_alignment (0.0, 0.0);
197 vbox->set_spacing (18);
198 vbox->set_border_width (24);
200 hbox->pack_start (*default_dir_chooser, false, true, 8);
201 vbox->pack_start (*txt, false, false);
202 vbox->pack_start (*hbox, false, true);
204 cerr << "set default folder to " << poor_mans_glob (Config->get_default_session_parent_dir()) << endl;
205 default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
206 default_dir_chooser->signal_current_folder_changed().connect (sigc::mem_fun (*this, &ArdourStartup::default_dir_changed));
207 default_dir_chooser->show ();
211 default_folder_page_index = append_page (*vbox);
212 set_page_title (*vbox, _("Default folder for new sessions"));
213 set_page_header_image (*vbox, icon_pixbuf);
214 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
216 /* user can just skip all these settings if they want to */
218 set_page_complete (*vbox, true);
222 ArdourStartup::setup_monitoring_choice_page ()
224 mon_vbox.set_spacing (18);
225 mon_vbox.set_border_width (24);
227 HBox* hbox = manage (new HBox);
228 VBox* vbox = manage (new VBox);
229 /* first button will be on by default */
230 RadioButton::Group g (monitor_via_ardour_button.get_group());
231 monitor_via_hardware_button.set_group (g);
233 monitor_label.set_markup(_("\
234 While recording instruments or vocals, you probably want to listen to the\n\
235 signal as well as record it. This is called \"monitoring\". There are\n\
236 different ways to do this depending on the equipment you have and the\n\
237 configuration of that equipment. The two most common are presented here.\n\
238 Please choose whichever one is right for your setup.\n\n\
239 <i>(You can change this preference at any time, via the Preferences dialog)</i>\n\n\
240 <i>If you do not understand what this is about, just accept the default.</i>"));
241 monitor_label.set_alignment (0.0, 0.0);
243 vbox->set_spacing (6);
245 vbox->pack_start (monitor_via_hardware_button, false, true);
246 vbox->pack_start (monitor_via_ardour_button, false, true);
247 hbox->pack_start (*vbox, true, true, 8);
248 mon_vbox.pack_start (monitor_label, false, false);
249 mon_vbox.pack_start (*hbox, false, false);
251 mon_vbox.show_all ();
253 monitoring_page_index = append_page (mon_vbox);
254 set_page_title (mon_vbox, _("Monitoring Choices"));
255 set_page_header_image (mon_vbox, icon_pixbuf);
257 monitor_via_hardware_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
258 monitor_via_ardour_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
260 /* user could just click on "Forward" if default
264 set_page_complete (mon_vbox, true);
268 ArdourStartup::setup_monitor_section_choice_page ()
270 mon_sec_vbox.set_spacing (18);
271 mon_sec_vbox.set_border_width (24);
273 HBox* hbox = manage (new HBox);
274 VBox* main_vbox = manage (new VBox);
276 Label* l = manage (new Label);
278 main_vbox->set_spacing (32);
280 no_monitor_section_button.set_label (_("Use a Master bus directly"));
281 l->set_alignment (0.0, 1.0);
282 l->set_markup(_("Connect the Master bus directly to your hardware outputs. This is preferable for simple usage."));
284 vbox = manage (new VBox);
285 vbox->set_spacing (6);
286 vbox->pack_start (no_monitor_section_button, false, true);
287 vbox->pack_start (*l, false, true);
289 main_vbox->pack_start (*vbox, false, false);
291 use_monitor_section_button.set_label (_("Use an additional Monitor bus"));
292 l = manage (new Label);
293 l->set_alignment (0.0, 1.0);
294 l->set_text (_("Use a Monitor bus between Master bus and hardware outputs for \n\
295 greater control in monitoring without affecting the mix."));
297 vbox = manage (new VBox);
298 vbox->set_spacing (6);
299 vbox->pack_start (use_monitor_section_button, false, true);
300 vbox->pack_start (*l, false, true);
302 main_vbox->pack_start (*vbox, false, false);
304 RadioButton::Group g (use_monitor_section_button.get_group());
305 no_monitor_section_button.set_group (g);
307 if (Config->get_use_monitor_bus()) {
308 use_monitor_section_button.set_active (true);
310 no_monitor_section_button.set_active (true);
313 use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
314 no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
316 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\
317 <i>If you do not understand what this is about, just accept the default.</i>"));
318 monitor_section_label.set_alignment (0.0, 0.0);
320 hbox->pack_start (*main_vbox, true, true, 8);
321 mon_sec_vbox.pack_start (*hbox, false, false);
322 mon_sec_vbox.pack_start (monitor_section_label, false, false);
324 mon_sec_vbox.show_all ();
326 monitor_section_page_index = append_page (mon_sec_vbox);
327 set_page_title (mon_sec_vbox, _("Monitor Section"));
328 set_page_header_image (mon_sec_vbox, icon_pixbuf);
330 /* user could just click on "Forward" if default
334 set_page_complete (mon_sec_vbox, true);
338 ArdourStartup::setup_final_page ()
340 string msg = string_compose (_("%1 is ready for use"), PROGRAM_NAME);
342 plugin_disco_button.signal_clicked().connect (sigc::mem_fun(*this, &ArdourStartup::discover_plugins));
343 plugin_disco_button.set_label (_("Scan for Plugins"));
344 plugin_disco_button.show ();
346 Gtk::Label* final_label = manage (new Label);
347 final_label->set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", msg));
348 final_label->show ();
350 VBox* vbox = manage (new VBox);
351 vbox->pack_start (*final_label, true, true);
352 if (!Profile->get_mixbus()) {
353 vbox->pack_start (plugin_disco_button, true, false);
357 final_page_index = append_page (*vbox);
358 set_page_complete (*vbox, true);
359 set_page_header_image (*vbox, icon_pixbuf);
360 set_page_type (*vbox, ASSISTANT_PAGE_CONFIRM);
364 ArdourStartup::discover_plugins () {
365 plugin_disco_button.set_sensitive (false);
366 PluginManager::instance().refresh();
370 ArdourStartup::on_cancel ()
372 _response = RESPONSE_CANCEL;
377 ArdourStartup::on_delete_event (GdkEventAny*)
379 _response = RESPONSE_CLOSE;
385 ArdourStartup::on_apply ()
387 /* file-chooser button does not emit 'current_folder_changed' signal
388 * when a folder from the dropdown or the sidebar is chosen.
389 * -> explicitly poll for the dir as suggested by the gtk documentation.
391 if (default_dir_chooser && default_dir_chooser->get_filename() != Config->get_default_session_parent_dir ()) {
392 config_modified = true;
395 if (config_modified) {
397 if (default_dir_chooser) {
398 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
401 if (monitor_via_hardware_button.get_active()) {
402 Config->set_monitoring_model (ExternalMonitoring);
403 } else if (monitor_via_ardour_button.get_active()) {
404 Config->set_monitoring_model (SoftwareMonitoring);
407 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
409 Config->save_state ();
414 /* "touch" the been-here-before path now we've successfully
415 made it through the first time setup (at least)
417 PBD::ScopedFileDescriptor fout (g_open (been_here_before_path ().c_str(), O_CREAT|O_TRUNC|O_RDWR, 0666));
421 _response = RESPONSE_OK;
427 ArdourStartup::move_along_now ()