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/recent_sessions.h"
41 #include "ardour/session.h"
42 #include "ardour/session_state_utils.h"
43 #include "ardour/template_utils.h"
44 #include "ardour/filename_extensions.h"
46 #include "ardour_ui.h"
49 #include "engine_dialog.h"
58 using namespace ARDOUR;
59 using namespace ARDOUR_UI_UTILS;
61 ArdourStartup* ArdourStartup::the_startup = 0;
63 ArdourStartup::ArdourStartup ()
64 : _response (RESPONSE_OK)
65 , config_modified (false)
66 , default_dir_chooser (0)
67 , monitor_via_hardware_button (string_compose (_("Use an external mixer or the hardware mixer of your audio interface.\n"
68 "%1 will play NO role in monitoring"), PROGRAM_NAME))
69 , monitor_via_ardour_button (string_compose (_("Ask %1 to play back material as it is being recorded"), PROGRAM_NAME))
70 , audio_page_index (-1)
71 , new_user_page_index (-1)
72 , default_folder_page_index (-1)
73 , monitoring_page_index (-1)
74 , final_page_index (-1)
76 set_position (WIN_POS_CENTER);
77 set_border_width (12);
79 if ((icon_pixbuf = ::get_icon ("ardour_icon_48px")) == 0) {
80 throw failed_constructor();
83 list<Glib::RefPtr<Gdk::Pixbuf> > window_icons;
84 Glib::RefPtr<Gdk::Pixbuf> icon;
86 if ((icon = ::get_icon ("ardour_icon_16px")) != 0) {
87 window_icons.push_back (icon);
89 if ((icon = ::get_icon ("ardour_icon_22px")) != 0) {
90 window_icons.push_back (icon);
92 if ((icon = ::get_icon ("ardour_icon_32px")) != 0) {
93 window_icons.push_back (icon);
95 if ((icon = ::get_icon ("ardour_icon_48px")) != 0) {
96 window_icons.push_back (icon);
98 if (!window_icons.empty ()) {
99 set_default_icon_list (window_icons);
102 setup_new_user_page ();
103 setup_first_time_config_page ();
104 setup_monitoring_choice_page ();
105 setup_monitor_section_choice_page ();
111 ArdourStartup::~ArdourStartup ()
116 ArdourStartup::required ()
118 /* look for a "been here before" file for this version or earlier
122 const int current_version = atoi (PROGRAM_VERSION);
124 for (int v = current_version; v != 0; --v) {
125 if (Glib::file_test (ARDOUR::been_here_before_path (v), Glib::FILE_TEST_EXISTS)) {
126 if (v != current_version) {
127 /* older version exists, create the current one */
128 ofstream fout (been_here_before_path (current_version).c_str());
138 ArdourStartup::setup_new_user_page ()
140 Label* foomatic = manage (new Label);
142 foomatic->set_markup (string_compose (_("\
143 <span size=\"larger\">%1 is a digital audio workstation. You can use it to \
144 record, edit and mix multi-track audio. You can produce your \
145 own CDs, mix video soundtracks, or experiment with new \
146 ideas about music and sound. \
148 There are a few things that need to be configured before you start \
149 using the program.</span> \
151 foomatic->set_justify (JUSTIFY_FILL);
152 foomatic->set_line_wrap ();
154 HBox* hbox = manage (new HBox);
155 HBox* vbox = manage (new HBox);
157 vbox->set_border_width (24);
159 hbox->pack_start (*foomatic, true, true);
160 vbox->pack_start (*hbox, true, true);
166 new_user_page_index = append_page (*vbox);
167 set_page_type (*vbox, ASSISTANT_PAGE_INTRO);
168 set_page_title (*vbox, string_compose (_("Welcome to %1"), PROGRAM_NAME));
169 set_page_header_image (*vbox, icon_pixbuf);
170 set_page_complete (*vbox, true);
174 ArdourStartup::default_dir_changed ()
176 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
177 // make new session folder chooser point to the new default
178 new_folder_chooser.set_current_folder (Config->get_default_session_parent_dir());
183 ArdourStartup::config_changed ()
185 config_modified = true;
189 ArdourStartup::setup_first_time_config_page ()
191 default_dir_chooser = manage (new FileChooserButton (string_compose (_("Default folder for %1 sessions"), PROGRAM_NAME),
192 FILE_CHOOSER_ACTION_SELECT_FOLDER));
193 Gtk::Label* txt = manage (new Label);
194 HBox* hbox = manage (new HBox);
195 VBox* vbox = manage (new VBox);
197 txt->set_markup (string_compose (_("\
198 Each project that you work on with %1 has its own folder.\n\
199 These can require a lot of disk space if you are recording audio.\n\
201 Where would you like new %1 sessions to be stored by default?\n\n\
202 <i>(You can put new sessions anywhere, this is just a default)</i>"), PROGRAM_NAME));
203 txt->set_alignment (0.0, 0.0);
205 vbox->set_spacing (18);
206 vbox->set_border_width (24);
208 hbox->pack_start (*default_dir_chooser, false, true, 8);
209 vbox->pack_start (*txt, false, false);
210 vbox->pack_start (*hbox, false, true);
212 cerr << "set default folder to " << poor_mans_glob (Config->get_default_session_parent_dir()) << endl;
213 default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
214 default_dir_chooser->signal_current_folder_changed().connect (sigc::mem_fun (*this, &ArdourStartup::default_dir_changed));
215 default_dir_chooser->show ();
219 default_folder_page_index = append_page (*vbox);
220 set_page_title (*vbox, _("Default folder for new sessions"));
221 set_page_header_image (*vbox, icon_pixbuf);
222 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
224 /* user can just skip all these settings if they want to */
226 set_page_complete (*vbox, true);
230 ArdourStartup::setup_monitoring_choice_page ()
232 mon_vbox.set_spacing (18);
233 mon_vbox.set_border_width (24);
235 HBox* hbox = manage (new HBox);
236 VBox* vbox = manage (new VBox);
237 /* first button will be on by default */
238 RadioButton::Group g (monitor_via_ardour_button.get_group());
239 monitor_via_hardware_button.set_group (g);
241 monitor_label.set_markup(_("\
242 While recording instruments or vocals, you probably want to listen to the\n\
243 signal as well as record it. This is called \"monitoring\". There are\n\
244 different ways to do this depending on the equipment you have and the\n\
245 configuration of that equipment. The two most common are presented here.\n\
246 Please choose whichever one is right for your setup.\n\n\
247 <i>(You can change this preference at any time, via the Preferences dialog)</i>\n\n\
248 <i>If you do not understand what this is about, just accept the default.</i>"));
249 monitor_label.set_alignment (0.0, 0.0);
251 vbox->set_spacing (6);
253 vbox->pack_start (monitor_via_hardware_button, false, true);
254 vbox->pack_start (monitor_via_ardour_button, false, true);
255 hbox->pack_start (*vbox, true, true, 8);
256 mon_vbox.pack_start (monitor_label, false, false);
257 mon_vbox.pack_start (*hbox, false, false);
259 mon_vbox.show_all ();
261 monitoring_page_index = append_page (mon_vbox);
262 set_page_title (mon_vbox, _("Monitoring Choices"));
263 set_page_header_image (mon_vbox, icon_pixbuf);
265 /* user could just click on "Forward" if default
269 set_page_complete (mon_vbox, true);
273 ArdourStartup::setup_monitor_section_choice_page ()
275 mon_sec_vbox.set_spacing (18);
276 mon_sec_vbox.set_border_width (24);
278 HBox* hbox = manage (new HBox);
279 VBox* main_vbox = manage (new VBox);
281 Label* l = manage (new Label);
283 main_vbox->set_spacing (32);
285 no_monitor_section_button.set_label (_("Use a Master bus directly"));
286 l->set_alignment (0.0, 1.0);
287 l->set_markup(_("Connect the Master bus directly to your hardware outputs. This is preferable for simple usage."));
289 vbox = manage (new VBox);
290 vbox->set_spacing (6);
291 vbox->pack_start (no_monitor_section_button, false, true);
292 vbox->pack_start (*l, false, true);
294 main_vbox->pack_start (*vbox, false, false);
296 use_monitor_section_button.set_label (_("Use an additional Monitor bus"));
297 l = manage (new Label);
298 l->set_alignment (0.0, 1.0);
299 l->set_text (_("Use a Monitor bus between Master bus and hardware outputs for \n\
300 greater control in monitoring without affecting the mix."));
302 vbox = manage (new VBox);
303 vbox->set_spacing (6);
304 vbox->pack_start (use_monitor_section_button, false, true);
305 vbox->pack_start (*l, false, true);
307 main_vbox->pack_start (*vbox, false, false);
309 RadioButton::Group g (use_monitor_section_button.get_group());
310 no_monitor_section_button.set_group (g);
312 if (Config->get_use_monitor_bus()) {
313 use_monitor_section_button.set_active (true);
315 no_monitor_section_button.set_active (true);
318 use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
319 no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
321 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\
322 <i>If you do not understand what this is about, just accept the default.</i>"));
323 monitor_section_label.set_alignment (0.0, 0.0);
325 hbox->pack_start (*main_vbox, true, true, 8);
326 mon_sec_vbox.pack_start (*hbox, false, false);
327 mon_sec_vbox.pack_start (monitor_section_label, false, false);
329 mon_sec_vbox.show_all ();
331 monitor_section_page_index = append_page (mon_sec_vbox);
332 set_page_title (mon_sec_vbox, _("Monitor Section"));
333 set_page_header_image (mon_sec_vbox, icon_pixbuf);
335 /* user could just click on "Forward" if default
339 set_page_complete (mon_sec_vbox, true);
343 ArdourStartup::setup_final_page ()
345 string msg = string_compose (_("%1 is ready for use"), PROGRAM_NAME);
347 final_page.set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", msg));
349 final_page_index = append_page (final_page);
350 set_page_complete (final_page, true);
351 set_page_header_image (final_page, icon_pixbuf);
352 set_page_type (final_page, ASSISTANT_PAGE_CONFIRM);
356 ArdourStartup::on_cancel ()
358 _response = RESPONSE_CANCEL;
363 ArdourStartup::on_delete_event (GdkEventAny*)
365 _response = RESPONSE_CLOSE;
371 ArdourStartup::on_apply ()
373 /* file-chooser button does not emit 'current_folder_changed' signal
374 * when a folder from the dropdown or the sidebar is chosen.
375 * -> explicitly poll for the dir as suggested by the gtk documentation.
377 if (default_dir_chooser && default_dir_chooser->get_filename() != Config->get_default_session_parent_dir ()) {
378 config_modified = true;
381 if (config_modified) {
383 if (default_dir_chooser) {
384 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
387 if (monitor_via_hardware_button.get_active()) {
388 Config->set_monitoring_model (ExternalMonitoring);
389 } else if (monitor_via_ardour_button.get_active()) {
390 Config->set_monitoring_model (SoftwareMonitoring);
393 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
395 Config->save_state ();
400 /* "touch" the been-here-before path now we've successfully
401 made it through the first time setup (at least)
403 ofstream fout (been_here_before_path().c_str());
407 _response = RESPONSE_OK;
413 ArdourStartup::move_along_now ()