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 <gtkmm/main.h>
29 #include <gtkmm/filechooser.h>
31 #include "pbd/failed_constructor.h"
32 #include "pbd/file_utils.h"
33 #include "pbd/replace_all.h"
34 #include "pbd/whitespace.h"
35 #include "pbd/stacktrace.h"
36 #include "pbd/openuri.h"
38 #include "ardour/audioengine.h"
39 #include "ardour/filesystem_paths.h"
40 #include "ardour/filename_extensions.h"
41 #include "ardour/plugin_manager.h"
42 #include "ardour/recent_sessions.h"
43 #include "ardour/session.h"
44 #include "ardour/session_state_utils.h"
45 #include "ardour/template_utils.h"
47 #include "ardour_ui.h"
50 #include "engine_dialog.h"
59 using namespace ARDOUR;
60 using namespace ARDOUR_UI_UTILS;
62 ArdourStartup* ArdourStartup::the_startup = 0;
64 ArdourStartup::ArdourStartup ()
65 : _response (RESPONSE_OK)
66 , config_modified (false)
67 , default_dir_chooser (0)
68 , monitor_via_hardware_button (string_compose (_("Use an external mixer or the hardware mixer of your audio interface.\n"
69 "%1 will play NO role in monitoring"), PROGRAM_NAME))
70 , monitor_via_ardour_button (string_compose (_("Ask %1 to play back material as it is being recorded"), PROGRAM_NAME))
71 , audio_page_index (-1)
72 , new_user_page_index (-1)
73 , default_folder_page_index (-1)
74 , monitoring_page_index (-1)
75 , final_page_index (-1)
77 set_position (WIN_POS_CENTER);
78 set_border_width (12);
80 if ((icon_pixbuf = ::get_icon ("ardour_icon_48px")) == 0) {
81 throw failed_constructor();
84 list<Glib::RefPtr<Gdk::Pixbuf> > window_icons;
85 Glib::RefPtr<Gdk::Pixbuf> icon;
87 if ((icon = ::get_icon ("ardour_icon_16px")) != 0) {
88 window_icons.push_back (icon);
90 if ((icon = ::get_icon ("ardour_icon_22px")) != 0) {
91 window_icons.push_back (icon);
93 if ((icon = ::get_icon ("ardour_icon_32px")) != 0) {
94 window_icons.push_back (icon);
96 if ((icon = ::get_icon ("ardour_icon_48px")) != 0) {
97 window_icons.push_back (icon);
99 if (!window_icons.empty ()) {
100 set_default_icon_list (window_icons);
103 setup_new_user_page ();
104 setup_first_time_config_page ();
105 setup_monitoring_choice_page ();
106 setup_monitor_section_choice_page ();
112 ArdourStartup::~ArdourStartup ()
117 ArdourStartup::required ()
119 /* look for a "been here before" file for this version or earlier
123 const int current_version = atoi (PROGRAM_VERSION);
125 for (int v = current_version; v != 0; --v) {
126 if (Glib::file_test (ARDOUR::been_here_before_path (v), Glib::FILE_TEST_EXISTS)) {
127 if (v != current_version) {
128 /* older version exists, create the current one */
129 ofstream fout (been_here_before_path (current_version).c_str());
139 ArdourStartup::setup_new_user_page ()
141 Label* foomatic = manage (new Label);
143 foomatic->set_markup (string_compose (_("\
144 <span size=\"larger\">%1 is a digital audio workstation. You can use it to \
145 record, edit and mix multi-track audio. You can produce your \
146 own CDs, mix video soundtracks, or experiment with new \
147 ideas about music and sound. \
149 There are a few things that need to be configured before you start \
150 using the program.</span> \
152 foomatic->set_justify (JUSTIFY_FILL);
153 foomatic->set_line_wrap ();
155 HBox* hbox = manage (new HBox);
156 HBox* vbox = manage (new HBox);
158 vbox->set_border_width (24);
160 hbox->pack_start (*foomatic, true, true);
161 vbox->pack_start (*hbox, true, true);
167 new_user_page_index = append_page (*vbox);
168 set_page_type (*vbox, ASSISTANT_PAGE_INTRO);
169 set_page_title (*vbox, string_compose (_("Welcome to %1"), PROGRAM_NAME));
170 set_page_header_image (*vbox, icon_pixbuf);
171 set_page_complete (*vbox, true);
175 ArdourStartup::default_dir_changed ()
177 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
178 // make new session folder chooser point to the new default
179 new_folder_chooser.set_current_folder (Config->get_default_session_parent_dir());
184 ArdourStartup::config_changed ()
186 config_modified = true;
190 ArdourStartup::setup_first_time_config_page ()
192 default_dir_chooser = manage (new FileChooserButton (string_compose (_("Default folder for %1 sessions"), PROGRAM_NAME),
193 FILE_CHOOSER_ACTION_SELECT_FOLDER));
194 Gtk::Label* txt = manage (new Label);
195 HBox* hbox = manage (new HBox);
196 VBox* vbox = manage (new VBox);
198 txt->set_markup (string_compose (_("\
199 Each project that you work on with %1 has its own folder.\n\
200 These can require a lot of disk space if you are recording audio.\n\
202 Where would you like new %1 sessions to be stored by default?\n\n\
203 <i>(You can put new sessions anywhere, this is just a default)</i>"), PROGRAM_NAME));
204 txt->set_alignment (0.0, 0.0);
206 vbox->set_spacing (18);
207 vbox->set_border_width (24);
209 hbox->pack_start (*default_dir_chooser, false, true, 8);
210 vbox->pack_start (*txt, false, false);
211 vbox->pack_start (*hbox, false, true);
213 cerr << "set default folder to " << poor_mans_glob (Config->get_default_session_parent_dir()) << endl;
214 default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
215 default_dir_chooser->signal_current_folder_changed().connect (sigc::mem_fun (*this, &ArdourStartup::default_dir_changed));
216 default_dir_chooser->show ();
220 default_folder_page_index = append_page (*vbox);
221 set_page_title (*vbox, _("Default folder for new sessions"));
222 set_page_header_image (*vbox, icon_pixbuf);
223 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
225 /* user can just skip all these settings if they want to */
227 set_page_complete (*vbox, true);
231 ArdourStartup::setup_monitoring_choice_page ()
233 mon_vbox.set_spacing (18);
234 mon_vbox.set_border_width (24);
236 HBox* hbox = manage (new HBox);
237 VBox* vbox = manage (new VBox);
238 /* first button will be on by default */
239 RadioButton::Group g (monitor_via_ardour_button.get_group());
240 monitor_via_hardware_button.set_group (g);
242 monitor_label.set_markup(_("\
243 While recording instruments or vocals, you probably want to listen to the\n\
244 signal as well as record it. This is called \"monitoring\". There are\n\
245 different ways to do this depending on the equipment you have and the\n\
246 configuration of that equipment. The two most common are presented here.\n\
247 Please choose whichever one is right for your setup.\n\n\
248 <i>(You can change this preference at any time, via the Preferences dialog)</i>\n\n\
249 <i>If you do not understand what this is about, just accept the default.</i>"));
250 monitor_label.set_alignment (0.0, 0.0);
252 vbox->set_spacing (6);
254 vbox->pack_start (monitor_via_hardware_button, false, true);
255 vbox->pack_start (monitor_via_ardour_button, false, true);
256 hbox->pack_start (*vbox, true, true, 8);
257 mon_vbox.pack_start (monitor_label, false, false);
258 mon_vbox.pack_start (*hbox, false, false);
260 mon_vbox.show_all ();
262 monitoring_page_index = append_page (mon_vbox);
263 set_page_title (mon_vbox, _("Monitoring Choices"));
264 set_page_header_image (mon_vbox, icon_pixbuf);
266 /* user could just click on "Forward" if default
270 set_page_complete (mon_vbox, true);
274 ArdourStartup::setup_monitor_section_choice_page ()
276 mon_sec_vbox.set_spacing (18);
277 mon_sec_vbox.set_border_width (24);
279 HBox* hbox = manage (new HBox);
280 VBox* main_vbox = manage (new VBox);
282 Label* l = manage (new Label);
284 main_vbox->set_spacing (32);
286 no_monitor_section_button.set_label (_("Use a Master bus directly"));
287 l->set_alignment (0.0, 1.0);
288 l->set_markup(_("Connect the Master bus directly to your hardware outputs. This is preferable for simple usage."));
290 vbox = manage (new VBox);
291 vbox->set_spacing (6);
292 vbox->pack_start (no_monitor_section_button, false, true);
293 vbox->pack_start (*l, false, true);
295 main_vbox->pack_start (*vbox, false, false);
297 use_monitor_section_button.set_label (_("Use an additional Monitor bus"));
298 l = manage (new Label);
299 l->set_alignment (0.0, 1.0);
300 l->set_text (_("Use a Monitor bus between Master bus and hardware outputs for \n\
301 greater control in monitoring without affecting the mix."));
303 vbox = manage (new VBox);
304 vbox->set_spacing (6);
305 vbox->pack_start (use_monitor_section_button, false, true);
306 vbox->pack_start (*l, false, true);
308 main_vbox->pack_start (*vbox, false, false);
310 RadioButton::Group g (use_monitor_section_button.get_group());
311 no_monitor_section_button.set_group (g);
313 if (Config->get_use_monitor_bus()) {
314 use_monitor_section_button.set_active (true);
316 no_monitor_section_button.set_active (true);
319 use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
320 no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
322 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\
323 <i>If you do not understand what this is about, just accept the default.</i>"));
324 monitor_section_label.set_alignment (0.0, 0.0);
326 hbox->pack_start (*main_vbox, true, true, 8);
327 mon_sec_vbox.pack_start (*hbox, false, false);
328 mon_sec_vbox.pack_start (monitor_section_label, false, false);
330 mon_sec_vbox.show_all ();
332 monitor_section_page_index = append_page (mon_sec_vbox);
333 set_page_title (mon_sec_vbox, _("Monitor Section"));
334 set_page_header_image (mon_sec_vbox, icon_pixbuf);
336 /* user could just click on "Forward" if default
340 set_page_complete (mon_sec_vbox, true);
344 ArdourStartup::setup_final_page ()
346 string msg = string_compose (_("%1 is ready for use"), PROGRAM_NAME);
348 plugin_disco_button.signal_clicked().connect (sigc::mem_fun(*this, &ArdourStartup::discover_plugins));
349 plugin_disco_button.set_label (_("Scan for Plugins"));
350 plugin_disco_button.show ();
352 Gtk::Label* final_label = manage (new Label);
353 final_label->set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", msg));
354 final_label->show ();
356 VBox* vbox = manage (new VBox);
357 vbox->pack_start (*final_label, true, true);
358 vbox->pack_start (plugin_disco_button, true, false);
361 final_page_index = append_page (*vbox);
362 set_page_complete (*vbox, true);
363 set_page_header_image (*vbox, icon_pixbuf);
364 set_page_type (*vbox, ASSISTANT_PAGE_CONFIRM);
368 ArdourStartup::discover_plugins () {
369 plugin_disco_button.set_sensitive (false);
370 PluginManager::instance().refresh();
374 ArdourStartup::on_cancel ()
376 _response = RESPONSE_CANCEL;
381 ArdourStartup::on_delete_event (GdkEventAny*)
383 _response = RESPONSE_CLOSE;
389 ArdourStartup::on_apply ()
391 /* file-chooser button does not emit 'current_folder_changed' signal
392 * when a folder from the dropdown or the sidebar is chosen.
393 * -> explicitly poll for the dir as suggested by the gtk documentation.
395 if (default_dir_chooser && default_dir_chooser->get_filename() != Config->get_default_session_parent_dir ()) {
396 config_modified = true;
399 if (config_modified) {
401 if (default_dir_chooser) {
402 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
405 if (monitor_via_hardware_button.get_active()) {
406 Config->set_monitoring_model (ExternalMonitoring);
407 } else if (monitor_via_ardour_button.get_active()) {
408 Config->set_monitoring_model (SoftwareMonitoring);
411 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
413 Config->save_state ();
418 /* "touch" the been-here-before path now we've successfully
419 made it through the first time setup (at least)
421 ofstream fout (been_here_before_path().c_str());
425 _response = RESPONSE_OK;
431 ArdourStartup::move_along_now ()