Unconditionally save instant.xml on session-close
[ardour.git] / gtk2_ardour / add_route_dialog.cc
1 /*
2  * Copyright (C) 2005-2006 Taybin Rutkin <taybin@taybin.com>
3  * Copyright (C) 2005-2017 Paul Davis <paul@linuxaudiosystems.com>
4  * Copyright (C) 2006-2014 David Robillard <d@drobilla.net>
5  * Copyright (C) 2009-2011 Carl Hetherington <carl@carlh.net>
6  * Copyright (C) 2014-2019 Robin Gareus <robin@gareus.org>
7  * Copyright (C) 2015-2017 Ben Loftis <ben@harrisonconsoles.com>
8  * Copyright (C) 2015 Nick Mainsbridge <mainsbridge@gmail.com>
9  * Copyright (C) 2018 Len Ovens <len@ovenwerks.net>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License along
22  * with this program; if not, write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25
26 #include <cstdio>
27 #include <cmath>
28
29 #include <sigc++/bind.h>
30 #include <gtkmm/stock.h>
31 #include <gtkmm/messagedialog.h>
32 #include <gtkmm/separator.h>
33 #include <gtkmm/table.h>
34
35 #include "pbd/error.h"
36 #include "pbd/convert.h"
37
38 #include "gtkmm2ext/utils.h"
39 #include "gtkmm2ext/doi.h"
40
41 #include "widgets/tooltips.h"
42
43 #include "ardour/plugin_manager.h"
44 #include "ardour/profile.h"
45 #include "ardour/template_utils.h"
46 #include "ardour/route_group.h"
47 #include "ardour/session.h"
48 #include "ardour/vca.h"
49
50 #include "LuaBridge/LuaBridge.h"
51
52 #include "ardour_message.h"
53 #include "add_route_dialog.h"
54 #include "ardour_ui.h"
55 #include "route_group_dialog.h"
56 #include "utils.h"
57
58 #include "pbd/i18n.h"
59
60 using namespace Gtk;
61 using namespace Gtkmm2ext;
62 using namespace std;
63 using namespace PBD;
64 using namespace ARDOUR;
65 using namespace ARDOUR_UI_UTILS;
66
67 std::vector<std::string> AddRouteDialog::channel_combo_strings;
68 std::vector<std::pair<std::string,std::string> > AddRouteDialog::builtin_types;
69
70 AddRouteDialog::AddRouteDialog ()
71         : ArdourDialog (_("Add Track/Bus/VCA"))
72         , routes_adjustment (1, 1, 128, 1, 4)
73         , routes_spinner (routes_adjustment)
74         , configuration_label (_("Configuration:"))
75         , manual_label (_("Configuration:"))
76         , add_label (_("Add:"))
77         , name_label (_("Name:"))
78         , group_label (_("Group:"))
79         , insert_label (_("Position:"))
80         , strict_io_label (_("Pin Mode:"))
81         , mode_label (_("Record Mode:"))
82         , instrument_label (_("Instrument:"))
83         , name_edited_by_user (false)
84 {
85         set_name ("AddRouteDialog");
86         set_skip_taskbar_hint (true);
87         set_resizable (false);
88         set_position (WIN_POS_MOUSE);
89
90         name_template_entry.set_name (X_("AddRouteDialogNameTemplateEntry"));
91         // routes_spinner.set_name (X_("AddRouteDialogSpinner"));
92         channel_combo.set_name (X_("ChannelCountSelector"));
93         mode_combo.set_name (X_("ChannelCountSelector"));
94
95         refill_track_modes ();
96
97         if (builtin_types.empty()) {
98                 builtin_types.push_back (
99                    std::pair<string,string> (_("Audio Tracks"), std::string () +
100                      _("Use these settings to create one or more audio tracks.") + "\n\n" +
101                      _("You may select:") + "\n" +
102                      "* " + _("The number of tracks to add") + "\n" +
103                      "* " + _("A name for the track(s)") + "\n" +
104                      "* " + _("Mono, stereo, or multi-channel operation for the track(s)") + "\n" +
105                      "* " + _("A group which the track(s) will be assigned to") + "\n" +
106 #ifndef MIXBUS
107                      "* " + _("The pin connections mode (see tooltip for details)") + "\n" +
108                      "* " + _("Normal (non-destructive) or tape (destructive) recording mode") + "\n" +
109 #endif
110                      "\n" + _("The track(s) will be added at the location specified by \"Position\"")
111                      ));
112
113                 builtin_types.push_back (
114                    std::pair<string,string> (_("MIDI Tracks"), std::string () +
115                      _("Use these settings to create one or more MIDI tracks.") + "\n\n" +
116                      _("You may select:") + "\n" +
117                      "* " + _("The number of tracks to add") + "\n" +
118                      "* " + _("A name for the track(s)") + "\n" +
119                      "* " + _("An instrument plugin (or select \"None\" to drive an external device)") + "\n" +
120                      "* " + _("A group which the track(s) will be assigned to") + "\n" +
121 #ifndef MIXBUS
122                      "* " + _("The pin connections mode (see tooltip for details)") + "\n" +
123 #endif
124                      "\n" + _("The track(s) will be added at the location specified by \"Position\"")
125                      ));
126
127 #ifndef MIXBUS
128                 builtin_types.push_back (
129                    std::pair<string,string> (_("Audio+MIDI Tracks"), std::string () +
130                      _("Use these settings to create one or more Audio+MIDI tracks.") + "\n\n" +
131                      _("You may select:") + "\n" +
132                      "* " + _("The number of tracks to add") + "\n" +
133                      "* " + _("A name for the track(s)") + "\n" +
134                      "* " + _("An instrument plugin (or select \"None\" to drive an external device)") + "\n" +
135                      "* " + _("A group which the track(s) will be assigned to") + "\n" +
136 #ifndef MIXBUS
137                      "* " + _("The pin connections mode (see tooltip for details)") + "\n" +
138                      "* " + _("Normal (non-destructive) or tape (destructive) recording mode") + "\n" +
139 #endif
140                      "\n" + _("The track(s) will be added at the location specified by \"Position\"")
141                      ));
142 #endif
143
144                 builtin_types.push_back (
145                    std::pair<string,string> (_("Audio Busses"), std::string () +
146                      _("Use these settings to create one or more audio busses.") + "\n\n" +
147                      _("You may select:") + "\n" +
148                      "* " + _("The number of busses to add") + "\n" +
149                      "* " + _("A name for the buss(es)") + "\n" +
150                      "* " + _("A group which the buss(es) will be assigned to") + "\n" +
151 #ifndef MIXBUS
152                      "* " + _("The pin connections mode (see tooltip for details)") + "\n" +
153 #endif
154                      "\n" + _("The buss(es) will be added at the location specified by \"Position\"")
155                      ));
156
157                 builtin_types.push_back (
158                    std::pair<string,string> (_("MIDI Busses"), std::string () +
159                      _("Use these settings to create one or more MIDI busses.") + "\n\n" +
160                      _("MIDI busses can combine the output of multiple tracks. They are sometimes used\nto host a single \"heavy\" instrument plugin which is fed from multiple MIDI tracks.") + "\n\n" +
161                      _("You may select:") + "\n" +
162                      "* " + _("The number of busses to add") + "\n" +
163                      "* " + _("A name for the buss(es)") + "\n" +
164                      "* " + _("An instrument plugin (or select \"None\" to drive an external device)") + "\n" +
165                      "* " + _("A group which the buss(es) will be assigned to") + "\n" +
166 #ifndef MIXBUS
167                      "* " + _("The pin connections mode (see tooltip for details)") + "\n" +
168 #endif
169                      "\n" + _("The buss(es) will be added at the location specified by \"Position\"")
170                      ));
171
172                 builtin_types.push_back (
173                    std::pair<string,string> (_("VCA Masters"), std::string () +
174                      _("Use these settings to create one or more VCA masters.") + "\n\n" +
175                      _("You may select:") + "\n" +
176                      "* " + _("The number of VCAs to add") + "\n" +
177                      "* " + _("A name for the VCA(s). \"%n\" will be replaced by an index number for each VCA")
178                      ));
179
180                 builtin_types.push_back (
181                    std::pair<string,string> (_("Foldback Busses"), std::string () +
182                      _("Use these settings to create one or more foldback busses.") + "\n\n" +
183                      _("Foldback busses are used as master outputs for monitor channels and are fed by\nhidden monitor sends.") + "\n\n" +
184                      _("You may select:") + "\n" +
185                      "* " + _("The number of busses to add") + "\n" +
186                      "* " + _("A name for the buss(es)")
187                      ));
188         }
189
190         insert_at_combo.append_text (_("First"));
191         insert_at_combo.append_text (_("Before Selection"));
192         insert_at_combo.append_text (_("After Selection"));
193         insert_at_combo.append_text (_("Last"));
194         insert_at_combo.set_active (3);
195
196         strict_io_combo.append_text (_("Flexible-I/O"));
197         strict_io_combo.append_text (_("Strict-I/O"));
198         strict_io_combo.set_active (Config->get_strict_io () ? 1 : 0);
199
200         /* top-level VBox */
201         VBox* vbox = manage (new VBox);
202         get_vbox()->set_spacing (4);
203         vbox->set_spacing (18);
204         vbox->set_border_width (5);
205
206         /* this box contains the template chooser, and the template details */
207         HBox* template_hbox = manage (new HBox);
208         template_hbox->set_spacing (8);
209
210         /* scrollbars for the template chooser and template descriptions.... */
211         Gtk::ScrolledWindow *template_scroller = manage (new Gtk::ScrolledWindow());
212         template_scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
213         template_scroller->add (trk_template_chooser);
214
215         Gtk::ScrolledWindow *desc_scroller = manage (new Gtk::ScrolledWindow());
216         desc_scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
217         desc_scroller->add (trk_template_desc);
218
219         /* this is the outer sample that surrounds the description and the settings-table */
220         trk_template_outer_frame.set_name (X_("TextHighlightFrame"));
221
222         /* this is the "inner frame" that surrounds the description text */
223         trk_template_desc_frame.set_name (X_("TextHighlightFrame"));
224         trk_template_desc_frame.add (*desc_scroller);
225
226         /* template_chooser is the treeview showing available templates */
227         trk_template_model = TreeStore::create (track_template_columns);
228         trk_template_chooser.set_model (trk_template_model);
229         trk_template_chooser.append_column (_("Template/Type"), track_template_columns.name);
230 #ifdef MIXBUS
231         trk_template_chooser.append_column (_("Modified With"), track_template_columns.modified_with);
232 #endif
233         trk_template_chooser.set_headers_visible (true);
234         trk_template_chooser.get_selection()->set_mode (SELECTION_SINGLE);
235         trk_template_chooser.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &AddRouteDialog::trk_template_row_selected));
236         trk_template_chooser.set_sensitive (true);
237
238         /* template_desc is the textview that displays the currently selected template's description */
239         trk_template_desc.set_editable (false);
240         trk_template_desc.set_can_focus (false);
241         trk_template_desc.set_wrap_mode (Gtk::WRAP_WORD);
242         trk_template_desc.set_size_request(400,200);
243         trk_template_desc.set_name (X_("TextOnBackground"));
244         trk_template_desc.set_border_width (6);
245
246         Table *settings_table = manage (new Table (2, 6, false));
247         settings_table->set_row_spacings (8);
248         settings_table->set_col_spacings        (4);
249         settings_table->set_col_spacing (3, 20);
250         settings_table->set_border_width        (12);
251
252         VBox* settings_vbox = manage (new VBox);
253         settings_vbox->pack_start(trk_template_desc_frame , true, true);
254         settings_vbox->pack_start(*settings_table , true, true);
255         settings_vbox->set_border_width (4);
256
257         trk_template_outer_frame.add (*settings_vbox);
258
259         template_hbox->pack_start (*template_scroller, true, true);
260         template_hbox->pack_start (trk_template_outer_frame, true, true);
261
262         vbox->pack_start (*template_hbox, true, true);
263
264
265         /* Now pack the "settings table" with manual controls (these controls are sensitized by the left-side selection) */
266
267         int n = 0;
268
269         HBox *separator_hbox = manage (new HBox);
270         separator_hbox->pack_start (manual_label, false, false);
271         separator_hbox->pack_start (*(manage (new Gtk::HSeparator)), true, true);
272         separator_hbox->set_spacing (6);
273         settings_table->attach (*separator_hbox, 0, 6, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
274
275         ++n;
276
277         /* Number */
278         add_label.set_alignment (Gtk::ALIGN_RIGHT, Gtk::ALIGN_CENTER);
279         settings_table->attach (add_label, 0, 1, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
280         Gtk::Alignment *align = manage (new Alignment (0, .5, 0, 0));
281         align->add (routes_spinner);
282         settings_table->attach (*align, 1, 2, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
283
284         ++n;
285
286         /* Name */
287         name_label.set_alignment (Gtk::ALIGN_RIGHT, Gtk::ALIGN_CENTER);
288         settings_table->attach (name_label, 0, 1, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
289         settings_table->attach (name_template_entry, 1, 3, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
290
291         /* Route configuration */
292         configuration_label.set_alignment (Gtk::ALIGN_RIGHT, Gtk::ALIGN_CENTER);
293         settings_table->attach (configuration_label, 4, 5, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
294         settings_table->attach (channel_combo, 5, 6, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
295
296         ++n;
297
298         /* instrument choice (for MIDI) */
299         instrument_label.set_alignment (Gtk::ALIGN_RIGHT, Gtk::ALIGN_CENTER);
300         settings_table->attach (instrument_label, 0, 1, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
301         settings_table->attach (instrument_combo, 1, 3, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
302
303         /* Group choice */
304         group_label.set_alignment (Gtk::ALIGN_RIGHT, Gtk::ALIGN_CENTER);
305         settings_table->attach (group_label, 4, 5, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
306         settings_table->attach (route_group_combo, 5, 6, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
307
308         ++n;
309
310         /* New Route's I/O is.. {strict/flexible} */
311         if (Profile->get_mixbus ()) {
312                 strict_io_combo.set_active (1);
313         } else {
314                 strict_io_label.set_alignment (Gtk::ALIGN_RIGHT, Gtk::ALIGN_CENTER);
315                 settings_table->attach (strict_io_label, 0, 1, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
316                 settings_table->attach (strict_io_combo, 1, 3, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
317
318                 ArdourWidgets::set_tooltip (strict_io_combo,
319                                 _("With strict-i/o enabled, Effect Processors will not modify the number of channels on a track. The number of output channels will always match the number of input channels."));
320
321                 /* recording mode */
322                 mode_label.set_alignment (Gtk::ALIGN_RIGHT, Gtk::ALIGN_CENTER);
323                 settings_table->attach (mode_label, 4, 5, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
324                 settings_table->attach (mode_combo, 5, 6, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
325
326                 ++n;
327         }
328
329         HBox* outer_box = manage (new HBox);
330         outer_box->set_spacing (4);
331
332         /* New route will be inserted at.. */
333         insert_label.set_alignment (Gtk::ALIGN_RIGHT, Gtk::ALIGN_CENTER);
334         outer_box->pack_start (insert_label, false, false);
335         outer_box->pack_start (insert_at_combo, false, false);
336
337         /* quick-add button (add item but don't close dialog) */
338         Gtk::Button* addnoclose_button = manage (new Gtk::Button(_("Add selected items (and leave dialog open)")));
339         addnoclose_button->set_can_default ();
340         addnoclose_button->signal_clicked ().connect (sigc::bind (sigc::mem_fun (*this, &Gtk::Dialog::response), Add));
341         outer_box->pack_end (*addnoclose_button, false, false);
342
343         vbox->pack_start (*outer_box, true, true);
344
345         get_vbox()->pack_start (*vbox, false, false);
346
347         name_template_entry.signal_insert_text ().connect (sigc::mem_fun (*this, &AddRouteDialog::name_template_entry_insertion));
348         name_template_entry.signal_delete_text ().connect (sigc::mem_fun (*this, &AddRouteDialog::name_template_entry_deletion));
349         channel_combo.signal_changed().connect (sigc::mem_fun (*this, &AddRouteDialog::channel_combo_changed));
350         channel_combo.set_row_separator_func (sigc::mem_fun (*this, &AddRouteDialog::channel_separator));
351         route_group_combo.set_row_separator_func (sigc::mem_fun (*this, &AddRouteDialog::route_separator));
352         route_group_combo.signal_changed ().connect (sigc::mem_fun (*this, &AddRouteDialog::group_changed));
353
354         routes_spinner.signal_activate ().connect (sigc::bind (sigc::mem_fun (*this, &Gtk::Dialog::response), AddAndClose));
355         name_template_entry.signal_activate ().connect (sigc::bind (sigc::mem_fun (*this, &Gtk::Dialog::response), AddAndClose));
356         trk_template_chooser.signal_row_activated ().connect (sigc::hide (sigc::hide (sigc::bind (sigc::mem_fun (*this, &Gtk::Dialog::response), AddAndClose))));
357
358         show_all_children ();
359
360         /* track template info will be managed whenever
361          * this dialog is shown, via ::on_show()
362          */
363
364         add_button (_("Add and Close"), AddAndClose);
365         set_response_sensitive (AddAndClose, true);
366         set_default_response (AddAndClose);
367
368         refill_channel_setups ();
369 }
370
371 AddRouteDialog::~AddRouteDialog ()
372 {
373 }
374
375 void
376 AddRouteDialog::on_response (int r)
377 {
378         reset_name_edited ();
379         /* Don't call ArdourDialog::on_response() because that will
380            automatically hide the dialog.
381         */
382         Gtk::Dialog::on_response (r);
383 }
384
385 void
386 AddRouteDialog::trk_template_row_selected ()
387 {
388         if (trk_template_chooser.get_selection()->count_selected_rows() != 1) {
389                 return;
390         }
391
392         TreeIter iter = trk_template_chooser.get_selection ()->get_selected ();
393         assert (iter);
394
395         string d = (*iter)[track_template_columns.description];
396         trk_template_desc.get_buffer ()->set_text (d);
397
398         const string n = (*iter)[track_template_columns.name];
399         const string p = (*iter)[track_template_columns.path];
400
401         if (p.substr (0, 11) == "urn:ardour:") {
402                 /* lua script - meta-template */
403                 const std::map<std::string, std::string> rs (ARDOUR_UI::instance()->route_setup_info (p.substr (11)));
404
405                 trk_template_desc.set_sensitive (true);
406
407                 add_label.set_sensitive (rs.find ("how_many") != rs.end ());
408                 name_label.set_sensitive (rs.find ("name") != rs.end());
409                 group_label.set_sensitive (rs.find ("group") != rs.end());
410                 configuration_label.set_sensitive (rs.find ("channels") != rs.end ());
411                 mode_label.set_sensitive (rs.find ("track_mode") != rs.end ());
412                 instrument_label.set_sensitive (rs.find ("instrument") != rs.end ());
413                 strict_io_label.set_sensitive (rs.find ("strict_io") != rs.end());
414
415                 routes_spinner.set_sensitive (rs.find ("how_many") != rs.end ());
416                 name_template_entry.set_sensitive (rs.find ("name") != rs.end ());
417                 route_group_combo.set_sensitive (rs.find ("group") != rs.end());
418                 channel_combo.set_sensitive (rs.find ("channels") != rs.end ());
419                 mode_combo.set_sensitive (rs.find ("track_mode") != rs.end ());
420                 instrument_combo.set_sensitive (rs.find ("instrument") != rs.end ());
421                 strict_io_combo.set_sensitive (rs.find ("strict_io") != rs.end());
422
423                 bool any_enabled = rs.find ("how_many") != rs.end ()
424                         || rs.find ("name") != rs.end ()
425                         || rs.find ("group") != rs.end()
426                         || rs.find ("channels") != rs.end ()
427                         || rs.find ("track_mode") != rs.end ()
428                         || rs.find ("instrument") != rs.end ()
429                         || rs.find ("strict_io") != rs.end();
430
431                 manual_label.set_sensitive (any_enabled);
432
433                 std::map<string,string>::const_iterator it;
434
435                 if ((it = rs.find ("name")) != rs.end()) {
436                         name_template_entry.set_text (it->second);
437                 } else {
438                         name_template_entry.set_text ("");
439                 }
440
441                 if ((it = rs.find ("how_many")) != rs.end()) {
442                         if (atoi (it->second.c_str()) > 0) {
443                                 routes_adjustment.set_value (atoi (it->second.c_str()));
444                         }
445                 }
446
447                 if ((it = rs.find ("track_mode")) != rs.end()) {
448                         switch ((ARDOUR::TrackMode) atoi (it->second.c_str())) {
449                                 case ARDOUR::Normal:
450                                         mode_combo.set_active_text (_("Normal"));
451                                         break;
452                                 case ARDOUR::Destructive:
453                                         if (!ARDOUR::Profile->get_mixbus ()) {
454                                                 mode_combo.set_active_text (_("Tape"));
455                                         }
456                                         break;
457                                 default: // "NonLayered" enum is still present for session-format compat
458                                         break;
459                         }
460                 }
461
462                 if ((it = rs.find ("strict_io")) != rs.end()) {
463                         if (it->second == X_("true")) {
464                                 strict_io_combo.set_active (1);
465                         } else if (it->second == X_("false")) {
466                                 strict_io_combo.set_active (0);
467                         }
468                 }
469
470                 if ((it = rs.find ("channels")) != rs.end()) {
471                         uint32_t channels = atoi (it->second.c_str());
472                         for (ChannelSetups::iterator i = channel_setups.begin(); i != channel_setups.end(); ++i) {
473                                 if ((*i).channels == channels) {
474                                         channel_combo.set_active_text ((*i).name);
475                                         break;
476                                 }
477                         }
478                 }
479
480         } else if (!p.empty ()) {
481                 /* user-template */
482                 trk_template_desc.set_sensitive (true);
483
484                 manual_label.set_sensitive (true);
485                 add_label.set_sensitive (true);
486                 name_label.set_sensitive (true);
487                 group_label.set_sensitive (false);
488                 strict_io_label.set_sensitive (false);
489                 configuration_label.set_sensitive (false);
490                 mode_label.set_sensitive (false);
491                 instrument_label.set_sensitive (false);
492
493                 routes_spinner.set_sensitive (true);
494                 name_template_entry.set_sensitive (true);
495                 channel_combo.set_sensitive (false);
496                 mode_combo.set_sensitive (false);
497                 instrument_combo.set_sensitive (false);
498                 strict_io_combo.set_sensitive (false);
499                 route_group_combo.set_sensitive (false);
500
501         } else {
502                 /* all manual mode */
503                 trk_template_desc.set_sensitive (false);
504
505                 manual_label.set_sensitive (true);
506                 add_label.set_sensitive (true);
507                 name_label.set_sensitive (true);
508                 group_label.set_sensitive (true);
509                 strict_io_label.set_sensitive (true);
510
511                 routes_spinner.set_sensitive (true);
512                 name_template_entry.set_sensitive (true);
513                 track_type_chosen ();
514         }
515 }
516
517
518 void
519 AddRouteDialog::name_template_entry_insertion (Glib::ustring const &,int*)
520 {
521         if (name_template ().empty ()) {
522                 name_edited_by_user = false;
523         } else {
524                 name_edited_by_user = true;
525         }
526 }
527
528 void
529 AddRouteDialog::name_template_entry_deletion (int, int)
530 {
531         if (name_template ().empty ()) {
532                 name_edited_by_user = false;
533         } else {
534                 name_edited_by_user = true;
535         }
536 }
537
538 void
539 AddRouteDialog::channel_combo_changed ()
540 {
541         refill_track_modes ();
542 }
543
544 std::string
545 AddRouteDialog::get_template_path ()
546 {
547         string p;
548
549         if (trk_template_chooser.get_selection()->count_selected_rows() > 0) {
550                 TreeIter iter = trk_template_chooser.get_selection()->get_selected();
551
552                 if (iter) {
553                         string n = (*iter)[track_template_columns.name];
554                         if (n != _("Manual Configuration")) {
555                                 p = (*iter)[track_template_columns.path];
556                         }
557                 }
558         }
559
560         return p;
561 }
562
563
564 AddRouteDialog::TypeWanted
565 AddRouteDialog::type_wanted()
566 {
567         if (trk_template_chooser.get_selection()->count_selected_rows() != 1) {
568                 return AudioTrack;
569         }
570         TreeIter iter = trk_template_chooser.get_selection ()->get_selected ();
571         assert (iter);
572
573         const string str = (*iter)[track_template_columns.name];
574         if (str == _("Audio Busses")) {
575                 return AudioBus;
576         } else if (str == _("MIDI Busses")){
577                 return MidiBus;
578         } else if (str == _("MIDI Tracks")){
579                 return MidiTrack;
580         } else if (str == _("Audio+MIDI Tracks")) {
581                 return MixedTrack;
582         } else if (str == _("Audio Tracks")) {
583                 return AudioTrack;
584         } else if (str == _("VCA Masters")) {
585                 return VCAMaster;
586         } else if (str == _("Foldback Busses")) {
587                 return FoldbackBus;
588         } else {
589                 assert (0);
590                 return AudioTrack;
591         }
592 }
593
594 void
595 AddRouteDialog::maybe_update_name_template_entry ()
596 {
597         if (name_edited_by_user) {
598                 return;
599         }
600
601         switch (type_wanted()) {
602         case AudioTrack:
603                 name_template_entry.set_text (_("Audio"));
604                 break;
605         case MidiTrack:
606                 name_template_entry.set_text (_("MIDI"));
607                 break;
608         case MixedTrack:
609                 name_template_entry.set_text (_("Audio+MIDI"));
610                 break;
611         case AudioBus:
612         case MidiBus:
613                 name_template_entry.set_text (_("Bus"));
614                 break;
615         case FoldbackBus:
616                 name_template_entry.set_text (_("Foldback"));
617                 break;
618         case VCAMaster:
619                 name_template_entry.set_text (VCA::default_name_template());
620                 break;
621         }
622         /* ignore programatic change, restore false */
623         reset_name_edited ();
624 }
625
626 void
627 AddRouteDialog::track_type_chosen ()
628 {
629         switch (type_wanted()) {
630         case AudioTrack:
631
632                 configuration_label.set_sensitive (true);
633                 channel_combo.set_sensitive (true);
634
635                 mode_label.set_sensitive (true);
636                 mode_combo.set_sensitive (true);
637
638                 instrument_label.set_sensitive (false);
639                 instrument_combo.set_sensitive (false);
640
641                 group_label.set_sensitive (true);
642                 route_group_combo.set_sensitive (true);
643
644                 strict_io_label.set_sensitive (true);
645                 strict_io_combo.set_sensitive (true);
646
647                 insert_label.set_sensitive (true);
648                 insert_at_combo.set_sensitive (true);
649
650                 break;
651         case MidiTrack:
652
653                 configuration_label.set_sensitive (false);
654                 channel_combo.set_sensitive (false);
655
656                 mode_label.set_sensitive (false);
657                 mode_combo.set_sensitive (false);
658
659                 instrument_label.set_sensitive (true);
660                 instrument_combo.set_sensitive (true);
661
662                 group_label.set_sensitive (true);
663                 route_group_combo.set_sensitive (true);
664
665                 strict_io_label.set_sensitive (true);
666                 strict_io_combo.set_sensitive (true);
667
668                 insert_label.set_sensitive (true);
669                 insert_at_combo.set_sensitive (true);
670
671                 break;
672         case MixedTrack:
673                 {
674                         ArdourMessageDialog msg (_("Audio+MIDI tracks are intended for use <b>ONLY</b> with plugins that use both audio and MIDI input data.\n\n"
675                                                    "Use a normal audio or MIDI track if you do not plan to use such a plugin."),
676                                                  true, MESSAGE_INFO, BUTTONS_OK, true);
677                         msg.run ();
678                 }
679
680                 configuration_label.set_sensitive (true);
681                 channel_combo.set_sensitive (true);
682
683                 mode_label.set_sensitive (true);
684                 mode_combo.set_sensitive (true);
685
686                 instrument_label.set_sensitive (true);
687                 instrument_combo.set_sensitive (true);
688
689                 group_label.set_sensitive (true);
690                 route_group_combo.set_sensitive (true);
691
692                 strict_io_label.set_sensitive (true);
693                 strict_io_combo.set_sensitive (true);
694
695                 insert_label.set_sensitive (true);
696                 insert_at_combo.set_sensitive (true);
697
698                 break;
699         case AudioBus:
700
701                 configuration_label.set_sensitive (true);
702                 channel_combo.set_sensitive (true);
703
704                 mode_label.set_sensitive (false);
705                 mode_combo.set_sensitive (false);
706
707                 instrument_label.set_sensitive (false);
708                 instrument_combo.set_sensitive (false);
709
710                 group_label.set_sensitive (true);
711                 route_group_combo.set_sensitive (true);
712
713                 strict_io_label.set_sensitive (true);
714                 strict_io_combo.set_sensitive (true);
715
716                 insert_label.set_sensitive (true);
717                 insert_at_combo.set_sensitive (true);
718
719                 break;
720         case VCAMaster:
721
722                 configuration_label.set_sensitive (false);
723                 channel_combo.set_sensitive (false);
724
725                 mode_label.set_sensitive (false);
726                 mode_combo.set_sensitive (false);
727
728                 instrument_label.set_sensitive (false);
729                 instrument_combo.set_sensitive (false);
730
731                 group_label.set_sensitive (false);
732                 route_group_combo.set_sensitive (false);
733
734                 strict_io_label.set_sensitive (false);
735                 strict_io_combo.set_sensitive (false);
736
737                 insert_label.set_sensitive (false);
738                 insert_at_combo.set_sensitive (false);
739
740                 break;
741         case MidiBus:
742
743                 configuration_label.set_sensitive (false);
744                 channel_combo.set_sensitive (false);
745
746                 mode_label.set_sensitive (false);
747                 mode_combo.set_sensitive (false);
748
749                 instrument_label.set_sensitive (true);
750                 instrument_combo.set_sensitive (true);
751
752                 group_label.set_sensitive (true);
753                 route_group_combo.set_sensitive (true);
754
755                 strict_io_label.set_sensitive (true);
756                 strict_io_combo.set_sensitive (true);
757
758                 insert_label.set_sensitive (true);
759                 insert_at_combo.set_sensitive (true);
760
761                 break;
762         case FoldbackBus:
763
764                 configuration_label.set_sensitive (true);
765                 channel_combo.set_sensitive (true);
766
767                 mode_label.set_sensitive (false);
768                 mode_combo.set_sensitive (false);
769
770                 instrument_label.set_sensitive (false);
771                 instrument_combo.set_sensitive (false);
772
773                 group_label.set_sensitive (false);
774                 route_group_combo.set_sensitive (false);
775
776                 strict_io_label.set_sensitive (false);
777                 strict_io_combo.set_sensitive (false);
778
779                 insert_label.set_sensitive (false);
780                 insert_at_combo.set_sensitive (false);
781
782                 break;
783         }
784
785         maybe_update_name_template_entry ();
786 }
787
788 string
789 AddRouteDialog::name_template () const
790 {
791         return name_template_entry.get_text ();
792 }
793
794 bool
795 AddRouteDialog::name_template_is_default () const
796 {
797         string n = name_template();
798
799         if (n == _("Audio") ||
800             n == _("MIDI") ||
801             n == _("Audio+MIDI") ||
802             n == _("Bus") ||
803             n == _("Foldback") ||
804             n == VCA::default_name_template()) {
805                 return true;
806         }
807
808         return false;
809 }
810
811 int
812 AddRouteDialog::count ()
813 {
814         return (int) floor (routes_adjustment.get_value ());
815 }
816
817 void
818 AddRouteDialog::refill_track_modes ()
819 {
820         vector<string> s;
821
822         s.push_back (_("Normal"));
823         if (!ARDOUR::Profile->get_mixbus ()) {
824                 s.push_back (_("Tape"));
825         }
826
827         set_popdown_strings (mode_combo, s);
828         mode_combo.set_active_text (s.front());
829 }
830
831 ARDOUR::TrackMode
832 AddRouteDialog::mode ()
833 {
834         std::string str = mode_combo.get_active_text();
835         if (str == _("Normal")) {
836                 return ARDOUR::Normal;
837         } else if (str == _("Non Layered")){
838                 return ARDOUR::NonLayered;
839         } else if (str == _("Tape")) {
840                 return ARDOUR::Destructive;
841         } else {
842                 fatal << string_compose (X_("programming error: unknown track mode in add route dialog combo = %1"), str)
843                       << endmsg;
844                 abort(); /*NOTREACHED*/
845         }
846         /* keep gcc happy */
847         return ARDOUR::Normal;
848 }
849
850 uint32_t
851 AddRouteDialog::channel_count ()
852 {
853         string str = channel_combo.get_active_text();
854         for (ChannelSetups::iterator i = channel_setups.begin(); i != channel_setups.end(); ++i) {
855                 if (str == (*i).name) {
856                         return (*i).channels;
857                 }
858         }
859         return 0;
860 }
861
862 ChanCount
863 AddRouteDialog::channels ()
864 {
865         ChanCount ret;
866         switch (type_wanted()) {
867         case AudioTrack:
868         case AudioBus:
869                 ret.set (DataType::AUDIO, channel_count ());
870                 ret.set (DataType::MIDI, 0);
871                 break;
872
873         case MidiBus:
874         case MidiTrack:
875                 ret.set (DataType::AUDIO, 0);
876                 ret.set (DataType::MIDI, 1);
877                 break;
878
879         case MixedTrack:
880                 ret.set (DataType::AUDIO, channel_count ());
881                 ret.set (DataType::MIDI, 1);
882                 break;
883
884         case FoldbackBus:
885                 ret.set (DataType::AUDIO, channel_count ());
886                 ret.set (DataType::MIDI, 0);
887                 break;
888
889         default:
890                 break;
891         }
892
893         return ret;
894 }
895
896 void
897 AddRouteDialog::on_show ()
898 {
899         routes_spinner.grab_focus ();
900         reset_name_edited ();
901
902         refill_route_groups ();
903         refill_channel_setups ();
904
905         Dialog::on_show ();
906 }
907
908 void
909 AddRouteDialog::refill_channel_setups ()
910 {
911         ChannelSetup chn;
912
913         string channel_current_choice = channel_combo.get_active_text();
914
915         channel_combo_strings.clear ();
916         channel_setups.clear ();
917
918         chn.name = _("Mono");
919         chn.channels = 1;
920         channel_setups.push_back (chn);
921
922         chn.name = _("Stereo");
923         chn.channels = 2;
924         channel_setups.push_back (chn);
925
926         if (!ARDOUR::Profile->get_mixbus()) {
927
928                 chn.name = "separator";
929                 channel_setups.push_back (chn);
930
931                 chn.name = _("3 Channel");
932                 chn.channels = 3;
933                 channel_setups.push_back (chn);
934
935                 chn.name = _("4 Channel");
936                 chn.channels = 4;
937                 channel_setups.push_back (chn);
938
939                 chn.name = _("5 Channel");
940                 chn.channels = 5;
941                 channel_setups.push_back (chn);
942
943                 chn.name = _("6 Channel");
944                 chn.channels = 6;
945                 channel_setups.push_back (chn);
946
947                 chn.name = _("8 Channel");
948                 chn.channels = 8;
949                 channel_setups.push_back (chn);
950
951                 chn.name = _("12 Channel");
952                 chn.channels = 12;
953                 channel_setups.push_back (chn);
954
955                 chn.name = _("Custom");
956                 chn.channels = 0;
957                 channel_setups.push_back (chn);
958         }
959
960         for (ChannelSetups::iterator i = channel_setups.begin(); i != channel_setups.end(); ++i) {
961                 channel_combo_strings.push_back ((*i).name);
962         }
963
964         trk_template_model->clear();
965         bool selected_default = false;
966
967         for (std::vector<std::pair<std::string,std::string> >::const_iterator i = builtin_types.begin(); i != builtin_types.end(); ++i) {
968                 TreeModel::Row row = *(trk_template_model->append ());
969                 row[track_template_columns.name] = (*i).first;
970                 row[track_template_columns.path] = "";
971                 row[track_template_columns.description] = (*i).second;
972                 row[track_template_columns.modified_with] = "";
973
974                 if (!selected_default && !Profile->get_mixbus ()) {
975                         trk_template_chooser.get_selection()->select(row);
976                         selected_default = true;
977                 }
978         }
979
980         /* Add any Lua scripts (factory templates) found in the scripts folder */
981         LuaScriptList& ms (LuaScripting::instance ().scripts (LuaScriptInfo::EditorAction));
982         for (LuaScriptList::const_iterator s = ms.begin(); s != ms.end(); ++s) {
983                 if (!((*s)->subtype & LuaScriptInfo::RouteSetup)) {
984                         continue;
985                 }
986                 TreeModel::Row row;
987                 if ((*s)->name == "Create Audio Tracks Interactively" && Profile->get_mixbus ()) {
988                         /* somewhat-special, Ben says: "most-used template" */
989                         row = *(trk_template_model->prepend ());
990                 } else {
991                         row = *(trk_template_model->append ());
992                 }
993                 row[track_template_columns.name] = (*s)->name;
994                 row[track_template_columns.path] = "urn:ardour:" + (*s)->path;
995                 row[track_template_columns.description] = (*s)->description;
996                 row[track_template_columns.modified_with] = _("{Factory Template}");
997
998                 if ((*s)->name == "Create Audio Tracks Interactively" && Profile->get_mixbus ()) {
999                         trk_template_chooser.get_selection()->select(row);
1000                         selected_default = true;
1001                 }
1002         }
1003
1004         if (!selected_default && !trk_template_model->children().empty()) {
1005                 TreeModel::Children rows = trk_template_model->children();
1006                 trk_template_chooser.get_selection()->select(rows[0]);
1007         }
1008
1009         std::vector<ARDOUR::TemplateInfo> route_templates;
1010         ARDOUR::find_route_templates (route_templates);
1011
1012         for (vector<TemplateInfo>::iterator x = route_templates.begin(); x != route_templates.end(); ++x) {
1013                 TreeModel::Row row = *(trk_template_model->append ());
1014
1015                 row[track_template_columns.name] = x->name;
1016                 row[track_template_columns.path] = x->path;
1017                 row[track_template_columns.description] = x->description;
1018                 row[track_template_columns.modified_with] = x->modified_with;
1019         }
1020
1021         set_popdown_strings (channel_combo, channel_combo_strings);
1022
1023         if (!channel_current_choice.empty()) {
1024                 channel_combo.set_active_text (channel_current_choice);
1025         } else {
1026                 channel_combo.set_active_text (channel_combo_strings.front());
1027         }
1028 }
1029
1030 void
1031 AddRouteDialog::add_route_group (RouteGroup* g)
1032 {
1033         route_group_combo.insert_text (3, g->name ());
1034 }
1035
1036 RouteGroup*
1037 AddRouteDialog::route_group ()
1038 {
1039         if (!_session || route_group_combo.get_active_row_number () == 2) {
1040                 return 0;
1041         }
1042
1043         return _session->route_group_by_name (route_group_combo.get_active_text());
1044 }
1045
1046 bool
1047 AddRouteDialog::use_strict_io() {
1048         return strict_io_combo.get_active_row_number () == 1;
1049 }
1050
1051 void
1052 AddRouteDialog::refill_route_groups ()
1053 {
1054         route_group_combo.clear ();
1055         route_group_combo.append_text (_("New Group..."));
1056
1057         route_group_combo.append_text ("separator");
1058
1059         route_group_combo.append_text (_("No Group"));
1060
1061         if (_session) {
1062                 _session->foreach_route_group (sigc::mem_fun (*this, &AddRouteDialog::add_route_group));
1063         }
1064
1065         route_group_combo.set_active (2);
1066 }
1067
1068 void
1069 AddRouteDialog::group_changed ()
1070 {
1071         if (_session && route_group_combo.get_active_text () == _("New Group...")) {
1072                 RouteGroup* g = new RouteGroup (*_session, "");
1073                 RouteGroupDialog* d = new RouteGroupDialog (g, true);
1074
1075                 d->signal_response().connect (sigc::bind (sigc::mem_fun (*this, &AddRouteDialog::new_group_dialog_finished), d));
1076                 d->present();
1077         }
1078 }
1079
1080 void
1081 AddRouteDialog::new_group_dialog_finished (int r, RouteGroupDialog* d)
1082 {
1083         if (r == RESPONSE_OK) {
1084
1085                 if (!d->name_check()) {
1086                         return;
1087                 }
1088
1089                 if (_session) {
1090                         _session->add_route_group (d->group());
1091                 }
1092
1093                 add_route_group (d->group());
1094                 route_group_combo.set_active (3);
1095         } else {
1096                 delete d->group ();
1097                 route_group_combo.set_active (2);
1098         }
1099
1100         delete_when_idle (d);
1101 }
1102
1103 RouteDialogs::InsertAt
1104 AddRouteDialog::insert_at ()
1105 {
1106         using namespace RouteDialogs;
1107
1108         std::string str = insert_at_combo.get_active_text();
1109
1110         if (str == _("First")) {
1111                 return First;
1112         } else if (str == _("After Selection")) {
1113                 return AfterSelection;
1114         } else if (str == _("Before Selection")){
1115                 return BeforeSelection;
1116         }
1117         return Last;
1118 }
1119
1120 bool
1121 AddRouteDialog::channel_separator (const Glib::RefPtr<Gtk::TreeModel> &, const Gtk::TreeModel::iterator &i)
1122 {
1123         channel_combo.set_active (i);
1124
1125         return channel_combo.get_active_text () == "separator";
1126 }
1127
1128 bool
1129 AddRouteDialog::route_separator (const Glib::RefPtr<Gtk::TreeModel> &, const Gtk::TreeModel::iterator &i)
1130 {
1131         route_group_combo.set_active (i);
1132
1133         return route_group_combo.get_active_text () == "separator";
1134 }
1135
1136 PluginInfoPtr
1137 AddRouteDialog::requested_instrument ()
1138 {
1139         return instrument_combo.selected_instrument();
1140 }