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 const int current_version = atoi (PROGRAM_VERSION);
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 default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
208 default_dir_chooser->signal_current_folder_changed().connect (sigc::mem_fun (*this, &ArdourStartup::default_dir_changed));
209 default_dir_chooser->show ();
213 default_folder_page_index = append_page (*vbox);
214 set_page_title (*vbox, _("Default folder for new sessions"));
215 set_page_header_image (*vbox, icon_pixbuf);
216 set_page_type (*vbox, ASSISTANT_PAGE_CONTENT);
218 /* user can just skip all these settings if they want to */
220 set_page_complete (*vbox, true);
224 ArdourStartup::setup_monitoring_choice_page ()
226 mon_vbox.set_spacing (18);
227 mon_vbox.set_border_width (24);
229 HBox* hbox = manage (new HBox);
230 VBox* vbox = manage (new VBox);
231 /* first button will be on by default */
232 RadioButton::Group g (monitor_via_ardour_button.get_group());
233 monitor_via_hardware_button.set_group (g);
235 monitor_label.set_markup(_("\
236 While recording instruments or vocals, you probably want to listen to the\n\
237 signal as well as record it. This is called \"monitoring\". There are\n\
238 different ways to do this depending on the equipment you have and the\n\
239 configuration of that equipment. The two most common are presented here.\n\
240 Please choose whichever one is right for your setup.\n\n\
241 <i>(You can change this preference at any time, via the Preferences dialog)</i>\n\n\
242 <i>If you do not understand what this is about, just accept the default.</i>"));
243 monitor_label.set_alignment (0.0, 0.0);
245 vbox->set_spacing (6);
247 vbox->pack_start (monitor_via_hardware_button, false, true);
248 vbox->pack_start (monitor_via_ardour_button, false, true);
249 hbox->pack_start (*vbox, true, true, 8);
250 mon_vbox.pack_start (monitor_label, false, false);
251 mon_vbox.pack_start (*hbox, false, false);
253 mon_vbox.show_all ();
255 monitoring_page_index = append_page (mon_vbox);
256 set_page_title (mon_vbox, _("Monitoring Choices"));
257 set_page_header_image (mon_vbox, icon_pixbuf);
259 /* user could just click on "Forward" if default
263 set_page_complete (mon_vbox, true);
267 ArdourStartup::setup_monitor_section_choice_page ()
269 mon_sec_vbox.set_spacing (18);
270 mon_sec_vbox.set_border_width (24);
272 HBox* hbox = manage (new HBox);
273 VBox* main_vbox = manage (new VBox);
275 Label* l = manage (new Label);
277 main_vbox->set_spacing (32);
279 no_monitor_section_button.set_label (_("Use a Master bus directly"));
280 l->set_alignment (0.0, 1.0);
281 l->set_markup(_("Connect the Master bus directly to your hardware outputs. This is preferable for simple usage."));
283 vbox = manage (new VBox);
284 vbox->set_spacing (6);
285 vbox->pack_start (no_monitor_section_button, false, true);
286 vbox->pack_start (*l, false, true);
288 main_vbox->pack_start (*vbox, false, false);
290 use_monitor_section_button.set_label (_("Use an additional Monitor bus"));
291 l = manage (new Label);
292 l->set_alignment (0.0, 1.0);
293 l->set_text (_("Use a Monitor bus between Master bus and hardware outputs for \n\
294 greater control in monitoring without affecting the mix."));
296 vbox = manage (new VBox);
297 vbox->set_spacing (6);
298 vbox->pack_start (use_monitor_section_button, false, true);
299 vbox->pack_start (*l, false, true);
301 main_vbox->pack_start (*vbox, false, false);
303 RadioButton::Group g (use_monitor_section_button.get_group());
304 no_monitor_section_button.set_group (g);
306 if (Config->get_use_monitor_bus()) {
307 use_monitor_section_button.set_active (true);
309 no_monitor_section_button.set_active (true);
312 use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
313 no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
315 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\
316 <i>If you do not understand what this is about, just accept the default.</i>"));
317 monitor_section_label.set_alignment (0.0, 0.0);
319 hbox->pack_start (*main_vbox, true, true, 8);
320 mon_sec_vbox.pack_start (*hbox, false, false);
321 mon_sec_vbox.pack_start (monitor_section_label, false, false);
323 mon_sec_vbox.show_all ();
325 monitor_section_page_index = append_page (mon_sec_vbox);
326 set_page_title (mon_sec_vbox, _("Monitor Section"));
327 set_page_header_image (mon_sec_vbox, icon_pixbuf);
329 /* user could just click on "Forward" if default
333 set_page_complete (mon_sec_vbox, true);
337 ArdourStartup::setup_final_page ()
339 string msg = string_compose (_("%1 is ready for use"), PROGRAM_NAME);
341 plugin_disco_button.signal_clicked().connect (sigc::mem_fun(*this, &ArdourStartup::discover_plugins));
342 plugin_disco_button.set_label (_("Scan for Plugins"));
343 plugin_disco_button.show ();
345 Gtk::Label* final_label = manage (new Label);
346 final_label->set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", msg));
347 final_label->show ();
349 VBox* vbox = manage (new VBox);
350 vbox->pack_start (*final_label, true, true);
351 if (!Profile->get_mixbus()) {
352 vbox->pack_start (plugin_disco_button, true, false);
356 final_page_index = append_page (*vbox);
357 set_page_complete (*vbox, true);
358 set_page_header_image (*vbox, icon_pixbuf);
359 set_page_type (*vbox, ASSISTANT_PAGE_CONFIRM);
363 ArdourStartup::discover_plugins () {
364 plugin_disco_button.set_sensitive (false);
365 PluginManager::instance().refresh();
369 ArdourStartup::on_cancel ()
371 _response = RESPONSE_CANCEL;
376 ArdourStartup::on_delete_event (GdkEventAny*)
378 _response = RESPONSE_CLOSE;
384 ArdourStartup::on_apply ()
386 /* file-chooser button does not emit 'current_folder_changed' signal
387 * when a folder from the dropdown or the sidebar is chosen.
388 * -> explicitly poll for the dir as suggested by the gtk documentation.
390 if (default_dir_chooser && default_dir_chooser->get_filename() != Config->get_default_session_parent_dir ()) {
391 config_modified = true;
394 if (config_modified) {
396 if (default_dir_chooser) {
397 Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
400 if (monitor_via_hardware_button.get_active()) {
401 Config->set_monitoring_model (ExternalMonitoring);
402 } else if (monitor_via_ardour_button.get_active()) {
403 Config->set_monitoring_model (SoftwareMonitoring);
406 Config->set_use_monitor_bus (use_monitor_section_button.get_active());
408 Config->save_state ();
413 /* "touch" the been-here-before path now we've successfully
414 made it through the first time setup (at least)
416 PBD::ScopedFileDescriptor fout (g_open (been_here_before_path ().c_str(), O_CREAT|O_TRUNC|O_RDWR, 0666));
420 _response = RESPONSE_OK;
426 ArdourStartup::move_along_now ()