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"
51 #include "gtkmm2ext/utils.h"
55 #include "engine_dialog.h"
64 using namespace ARDOUR;
65 using namespace ARDOUR_UI_UTILS;
67 ArdourStartup* ArdourStartup::the_startup = 0;
69 ArdourStartup::ArdourStartup ()
70 : _response (RESPONSE_OK)
71 , config_modified (false)
72 , default_dir_chooser (0)
73 , monitor_via_hardware_button (string_compose (_("Use an external mixer or the hardware mixer of your audio interface.\n"
74 "%1 will play NO role in monitoring"), PROGRAM_NAME))
75 , monitor_via_ardour_button (string_compose (_("Ask %1 to play back material as it is being recorded"), PROGRAM_NAME))
76 , audio_page_index (-1)
77 , new_user_page_index (-1)
78 , default_folder_page_index (-1)
79 , monitoring_page_index (-1)
80 , final_page_index (-1)
82 set_position (WIN_POS_CENTER);
83 set_border_width (12);
85 if (! (icon_pixbuf = ::get_icon (PROGRAM_NAME "-icon_48px"))) {
86 throw failed_constructor();
89 list<Glib::RefPtr<Gdk::Pixbuf> > window_icons;
90 Glib::RefPtr<Gdk::Pixbuf> icon;
92 if ((icon = ::get_icon (PROGRAM_NAME "-icon_16px"))) {
93 window_icons.push_back (icon);
95 if ((icon = ::get_icon (PROGRAM_NAME "-icon_22px"))) {
96 window_icons.push_back (icon);
98 if ((icon = ::get_icon (PROGRAM_NAME "-icon_32px"))) {
99 window_icons.push_back (icon);
101 if ((icon = ::get_icon (PROGRAM_NAME "-icon_48px"))) {
102 window_icons.push_back (icon);
104 if (!window_icons.empty ()) {
105 set_default_icon_list (window_icons);
108 setup_new_user_page ();
109 setup_first_time_config_page ();
110 setup_monitoring_choice_page ();
111 setup_monitor_section_choice_page ();
117 ArdourStartup::~ArdourStartup ()
122 ArdourStartup::required ()
124 if (Glib::file_test (ARDOUR::been_here_before_path (), Glib::FILE_TEST_EXISTS)) {
132 ArdourStartup::setup_new_user_page ()
134 Label* foomatic = manage (new Label);
136 foomatic->set_markup (string_compose (_("\
137 <span size=\"larger\">%1 is a digital audio workstation. You can use it to \
138 record, edit and mix multi-track audio. You can produce your \
139 own CDs, mix video soundtracks, or experiment with new \
140 ideas about music and sound. \
142 There are a few things that need to be configured before you start \
143 using the program.</span> \
145 foomatic->set_justify (JUSTIFY_FILL);
146 foomatic->set_line_wrap ();
148 HBox* hbox = manage (new HBox);
149 HBox* vbox = manage (new HBox);
151 vbox->set_border_width (24);
153 hbox->pack_start (*foomatic, true, true);
154 vbox->pack_start (*hbox, true, true);
160 new_user_page_index = append_page (*vbox);
161 set_page_type (*vbox, ASSISTANT_PAGE_INTRO);
162 set_page_title (*vbox, string_compose (_("Welcome to %1"), PROGRAM_NAME));
163 set_page_header_image (*vbox, icon_pixbuf);
164 set_page_complete (*vbox, true);
168 ArdourStartup::default_dir_changed ()
170 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
171 // make new session folder chooser point to the new default
172 new_folder_chooser.set_current_folder (Config->get_default_session_parent_dir());
177 ArdourStartup::config_changed ()
179 config_modified = true;
183 ArdourStartup::setup_first_time_config_page ()
185 default_dir_chooser = manage (new FileChooserButton (string_compose (_("Default folder for %1 sessions"), PROGRAM_NAME),
186 FILE_CHOOSER_ACTION_SELECT_FOLDER));
187 Gtk::Label* txt = manage (new Label);
188 HBox* hbox = manage (new HBox);
189 VBox* vbox = manage (new VBox);
191 txt->set_markup (string_compose (_("\
192 Each project that you work on with %1 has its own folder.\n\
193 These can require a lot of disk space if you are recording audio.\n\
195 Where would you like new %1 sessions to be stored by default?\n\n\
196 <i>(You can put new sessions anywhere, this is just a default)</i>"), PROGRAM_NAME));
197 txt->set_alignment (0.0, 0.0);
199 vbox->set_spacing (18);
200 vbox->set_border_width (24);
202 hbox->pack_start (*default_dir_chooser, false, true, 8);
203 vbox->pack_start (*txt, false, false);
204 vbox->pack_start (*hbox, false, true);
206 cerr << "set default folder to " << poor_mans_glob (Config->get_default_session_parent_dir()) << endl;
207 Gtkmm2ext::add_volume_shortcuts (*default_dir_chooser);
208 default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
209 default_dir_chooser->signal_current_folder_changed().connect (sigc::mem_fun (*this, &ArdourStartup::default_dir_changed));
210 default_dir_chooser->show ();
214 default_folder_page_index = append_page (*vbox);
215 set_page_title (*vbox, _("Default folder for new sessions"));
216 set_page_header_image (*vbox, icon_pixbuf);
217 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
219 /* user can just skip all these settings if they want to */
221 set_page_complete (*vbox, true);
225 ArdourStartup::setup_monitoring_choice_page ()
227 mon_vbox.set_spacing (18);
228 mon_vbox.set_border_width (24);
230 HBox* hbox = manage (new HBox);
231 VBox* vbox = manage (new VBox);
232 /* first button will be on by default */
233 RadioButton::Group g (monitor_via_ardour_button.get_group());
234 monitor_via_hardware_button.set_group (g);
236 monitor_label.set_markup(_("\
237 While recording instruments or vocals, you probably want to listen to the\n\
238 signal as well as record it. This is called \"monitoring\". There are\n\
239 different ways to do this depending on the equipment you have and the\n\
240 configuration of that equipment. The two most common are presented here.\n\
241 Please choose whichever one is right for your setup.\n\n\
242 <i>(You can change this preference at any time, via the Preferences dialog)</i>\n\n\
243 <i>If you do not understand what this is about, just accept the default.</i>"));
244 monitor_label.set_alignment (0.0, 0.0);
246 vbox->set_spacing (6);
248 vbox->pack_start (monitor_via_hardware_button, false, true);
249 vbox->pack_start (monitor_via_ardour_button, false, true);
250 hbox->pack_start (*vbox, true, true, 8);
251 mon_vbox.pack_start (monitor_label, false, false);
252 mon_vbox.pack_start (*hbox, false, false);
254 mon_vbox.show_all ();
256 monitoring_page_index = append_page (mon_vbox);
257 set_page_title (mon_vbox, _("Monitoring Choices"));
258 set_page_header_image (mon_vbox, icon_pixbuf);
260 monitor_via_hardware_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
261 monitor_via_ardour_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
263 /* user could just click on "Forward" if default
267 set_page_complete (mon_vbox, true);
271 ArdourStartup::setup_monitor_section_choice_page ()
273 mon_sec_vbox.set_spacing (18);
274 mon_sec_vbox.set_border_width (24);
276 HBox* hbox = manage (new HBox);
277 VBox* main_vbox = manage (new VBox);
279 Label* l = manage (new Label);
281 main_vbox->set_spacing (32);
283 no_monitor_section_button.set_label (_("Use a Master bus directly"));
284 l->set_alignment (0.0, 1.0);
285 l->set_markup(_("Connect the Master bus directly to your hardware outputs. This is preferable for simple usage."));
287 vbox = manage (new VBox);
288 vbox->set_spacing (6);
289 vbox->pack_start (no_monitor_section_button, false, true);
290 vbox->pack_start (*l, false, true);
292 main_vbox->pack_start (*vbox, false, false);
294 use_monitor_section_button.set_label (_("Use an additional Monitor bus"));
295 l = manage (new Label);
296 l->set_alignment (0.0, 1.0);
297 l->set_text (_("Use a Monitor bus between Master bus and hardware outputs for \n\
298 greater control in monitoring without affecting the mix."));
300 vbox = manage (new VBox);
301 vbox->set_spacing (6);
302 vbox->pack_start (use_monitor_section_button, false, true);
303 vbox->pack_start (*l, false, true);
305 main_vbox->pack_start (*vbox, false, false);
307 RadioButton::Group g (use_monitor_section_button.get_group());
308 no_monitor_section_button.set_group (g);
310 if (Config->get_use_monitor_bus()) {
311 use_monitor_section_button.set_active (true);
313 no_monitor_section_button.set_active (true);
316 use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
317 no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
319 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\
320 <i>If you do not understand what this is about, just accept the default.</i>"));
321 monitor_section_label.set_alignment (0.0, 0.0);
323 hbox->pack_start (*main_vbox, true, true, 8);
324 mon_sec_vbox.pack_start (*hbox, false, false);
325 mon_sec_vbox.pack_start (monitor_section_label, false, false);
327 mon_sec_vbox.show_all ();
329 monitor_section_page_index = append_page (mon_sec_vbox);
330 set_page_title (mon_sec_vbox, _("Monitor Section"));
331 set_page_header_image (mon_sec_vbox, icon_pixbuf);
333 /* user could just click on "Forward" if default
337 set_page_complete (mon_sec_vbox, true);
341 ArdourStartup::setup_final_page ()
343 string msg = string_compose (_("%1 is ready for use"), PROGRAM_NAME);
345 plugin_disco_button.signal_clicked().connect (sigc::mem_fun(*this, &ArdourStartup::discover_plugins));
346 plugin_disco_button.set_label (_("Scan for Plugins"));
347 plugin_disco_button.show ();
349 Gtk::Label* final_label = manage (new Label);
350 final_label->set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", msg));
351 final_label->show ();
353 VBox* vbox = manage (new VBox);
354 vbox->pack_start (*final_label, true, true);
355 if (!Profile->get_mixbus()) {
356 vbox->pack_start (plugin_disco_button, true, false);
360 final_page_index = append_page (*vbox);
361 set_page_complete (*vbox, true);
362 set_page_header_image (*vbox, icon_pixbuf);
363 set_page_type (*vbox, ASSISTANT_PAGE_CONFIRM);
367 ArdourStartup::discover_plugins () {
368 plugin_disco_button.set_sensitive (false);
369 PluginManager::instance().refresh();
373 ArdourStartup::on_cancel ()
375 _response = RESPONSE_CANCEL;
380 ArdourStartup::on_delete_event (GdkEventAny*)
382 _response = RESPONSE_CLOSE;
388 ArdourStartup::on_apply ()
390 /* file-chooser button does not emit 'current_folder_changed' signal
391 * when a folder from the dropdown or the sidebar is chosen.
392 * -> explicitly poll for the dir as suggested by the gtk documentation.
394 if (default_dir_chooser && default_dir_chooser->get_filename() != Config->get_default_session_parent_dir ()) {
395 config_modified = true;
398 if (config_modified) {
400 if (default_dir_chooser) {
401 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
404 if (monitor_via_hardware_button.get_active()) {
405 Config->set_monitoring_model (ExternalMonitoring);
406 } else if (monitor_via_ardour_button.get_active()) {
407 Config->set_monitoring_model (SoftwareMonitoring);
410 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
412 Config->save_state ();
417 /* "touch" the been-here-before path now we've successfully
418 made it through the first time setup (at least)
420 PBD::ScopedFileDescriptor fout (g_open (been_here_before_path ().c_str(), O_CREAT|O_TRUNC|O_RDWR, 0666));
424 _response = RESPONSE_OK;
430 ArdourStartup::move_along_now ()