Fix processor box for no crash on click
[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 "add_route_dialog.h"
53 #include "ardour_ui.h"
54 #include "route_group_dialog.h"
55 #include "utils.h"
56
57 #include "pbd/i18n.h"
58
59 using namespace Gtk;
60 using namespace Gtkmm2ext;
61 using namespace std;
62 using namespace PBD;
63 using namespace ARDOUR;
64 using namespace ARDOUR_UI_UTILS;
65
66 std::vector<std::string> AddRouteDialog::channel_combo_strings;
67 std::vector<std::pair<std::string,std::string> > AddRouteDialog::builtin_types;
68
69 AddRouteDialog::AddRouteDialog ()
70         : ArdourDialog (_("Add Track/Bus/VCA"))
71         , routes_adjustment (1, 1, 128, 1, 4)
72         , routes_spinner (routes_adjustment)
73         , configuration_label (_("Configuration:"))
74         , manual_label (_("Configuration:"))
75         , add_label (_("Add:"))
76         , name_label (_("Name:"))
77         , group_label (_("Group:"))
78         , insert_label (_("Position:"))
79         , strict_io_label (_("Pin Mode:"))
80         , mode_label (_("Record Mode:"))
81         , instrument_label (_("Instrument:"))
82         , name_edited_by_user (false)
83 {
84         set_name ("AddRouteDialog");
85         set_skip_taskbar_hint (true);
86         set_resizable (false);
87         set_position (WIN_POS_MOUSE);
88
89         name_template_entry.set_name (X_("AddRouteDialogNameTemplateEntry"));
90         // routes_spinner.set_name (X_("AddRouteDialogSpinner"));
91         channel_combo.set_name (X_("ChannelCountSelector"));
92         mode_combo.set_name (X_("ChannelCountSelector"));
93
94         refill_track_modes ();
95
96         if (builtin_types.empty()) {
97                 builtin_types.push_back (
98                    std::pair<string,string> (_("Audio Tracks"), std::string () +
99                      _("Use these settings to create one or more audio tracks.") + "\n\n" +
100                      _("You may select:") + "\n" +
101                      "* " + _("The number of tracks to add") + "\n" +
102                      "* " + _("A name for the track(s)") + "\n" +
103                      "* " + _("Mono, stereo, or multi-channel operation for the track(s)") + "\n" +
104                      "* " + _("A group which the track(s) will be assigned to") + "\n" +
105 #ifndef MIXBUS
106                      "* " + _("The pin connections mode (see tooltip for details)") + "\n" +
107                      "* " + _("Normal (non-destructive) or tape (destructive) recording mode") + "\n" +
108 #endif
109                      "\n" + _("The track(s) will be added at the location specified by \"Position\"")
110                      ));
111
112                 builtin_types.push_back (
113                    std::pair<string,string> (_("MIDI Tracks"), std::string () +
114                      _(" Use these settings to create one or more MIDI tracks.") + "\n\n" +
115                      _("You may select:") + "\n" +
116                      "* " + _("The number of tracks to add") + "\n" +
117                      "* " + _("A name for the track(s)") + "\n" +
118                      "* " + _("An instrument plugin (or select \"None\" to drive an external device)") + "\n" +
119                      "* " + _("A group which the track(s) will be assigned to") + "\n" +
120 #ifndef MIXBUS
121                      "* " + _("The pin connections mode (see tooltip for details)") + "\n" +
122 #endif
123                      "\n" + _("The track(s) will be added at the location specified by \"Position\"")
124                      ));
125
126 #ifndef MIXBUS
127                 builtin_types.push_back (
128                    std::pair<string,string> (_("Audio+MIDI Tracks"), std::string () +
129                      _("Use these settings to create one or more Audio+MIDI tracks.") + "\n\n" +
130                      _("You may select:") + "\n" +
131                      "* " + _("The number of tracks to add") + "\n" +
132                      "* " + _("A name for the track(s)") + "\n" +
133                      "* " + _("An instrument plugin (or select \"None\" to drive an external device)") + "\n" +
134                      "* " + _("A group which the track(s) will be assigned to") + "\n" +
135 #ifndef MIXBUS
136                      "* " + _("The pin connections mode (see tooltip for details)") + "\n" +
137                      "* " + _("Normal (non-destructive) or tape (destructive) recording mode") + "\n" +
138 #endif
139                      "\n" + _("The track(s) will be added at the location specified by \"Position\"")
140                      ));
141 #endif
142
143                 builtin_types.push_back (
144                    std::pair<string,string> (_("Audio Busses"), std::string () +
145                      _("Use these settings to create one or more audio busses.") + "\n\n" +
146                      _("You may select:") + "\n" +
147                      "* " + _("The number of busses to add") + "\n" +
148                      "* " + _("A name for the buss(es)") + "\n" +
149                      "* " + _("A group which the buss(es) will be assigned to") + "\n" +
150 #ifndef MIXBUS
151                      "* " + _("The pin connections mode (see tooltip for details)") + "\n" +
152 #endif
153                      "\n" + _("The buss(es) will be added at the location specified by \"Position\"")
154                      ));
155
156                 builtin_types.push_back (
157                    std::pair<string,string> (_("MIDI Busses"), std::string () +
158                      _("Use these settings to create one or more MIDI busses.") + "\n\n" +
159                      _("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" +
160                      _("You may select:") + "\n" +
161                      "* " + _("The number of busses to add") + "\n" +
162                      "* " + _("A name for the buss(es)") + "\n" +
163                      "* " + _("An instrument plugin (or select \"None\" to drive an external device)") + "\n" +
164                      "* " + _("A group which the buss(es) will be assigned to") + "\n" +
165 #ifndef MIXBUS
166                      "* " + _("The pin connections mode (see tooltip for details)") + "\n" +
167 #endif
168                      "\n" + _("The buss(es) will be added at the location specified by \"Position\"")
169                      ));
170
171                 builtin_types.push_back (
172                    std::pair<string,string> (_("VCA Masters"), std::string () +
173                      _("Use these settings to create one or more VCA masters.") + "\n\n" +
174                      _("You may select:") + "\n" +
175                      "* " + _("The number of VCAs to add") + "\n" +
176                      "* " + _("A name for the VCA(s). \"%n\" will be replaced by an index number for each VCA")
177                      ));
178
179                 builtin_types.push_back (
180                    std::pair<string,string> (_("Foldback Busses"), std::string () +
181                      _("Use these settings to create one or more foldback busses.") + "\n\n" +
182                      _("Foldback busses are used as master outputs for monitor channels and are fed by\nhidden monitor sends.") + "\n\n" +
183                      _("You may select:") + "\n" +
184                      "* " + _("The number of busses to add") + "\n" +
185                      "* " + _("A name for the buss(es)")
186                      ));
187         }
188
189         insert_at_combo.append_text (_("First"));
190         insert_at_combo.append_text (_("Before Selection"));
191         insert_at_combo.append_text (_("After Selection"));
192         insert_at_combo.append_text (_("Last"));
193         insert_at_combo.set_active (3);
194
195         strict_io_combo.append_text (_("Flexible-I/O"));
196         strict_io_combo.append_text (_("Strict-I/O"));
197         strict_io_combo.set_active (Config->get_strict_io () ? 1 : 0);
198
199         /* top-level VBox */
200         VBox* vbox = manage (new VBox);
201         get_vbox()->set_spacing (4);
202         vbox->set_spacing (18);
203         vbox->set_border_width (5);
204
205         /* this box contains the template chooser, and the template details */
206         HBox* template_hbox = manage (new HBox);
207         template_hbox->set_spacing (8);
208
209         /* scrollbars for the template chooser and template descriptions.... */
210         Gtk::ScrolledWindow *template_scroller = manage (new Gtk::ScrolledWindow());
211         template_scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
212         template_scroller->add (trk_template_chooser);
213
214         Gtk::ScrolledWindow *desc_scroller = manage (new Gtk::ScrolledWindow());
215         desc_scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
216         desc_scroller->add (trk_template_desc);
217
218         /* this is the outer sample that surrounds the description and the settings-table */
219         trk_template_outer_frame.set_name (X_("TextHighlightFrame"));
220
221         /* this is the "inner frame" that surrounds the description text */
222         trk_template_desc_frame.set_name (X_("TextHighlightFrame"));
223         trk_template_desc_frame.add (*desc_scroller);
224
225         /* template_chooser is the treeview showing available templates */
226         trk_template_model = TreeStore::create (track_template_columns);
227         trk_template_chooser.set_model (trk_template_model);
228         trk_template_chooser.append_column (_("Template/Type"), track_template_columns.name);
229 #ifdef MIXBUS
230         trk_template_chooser.append_column (_("Modified With"), track_template_columns.modified_with);
231 #endif
232         trk_template_chooser.set_headers_visible (true);
233         trk_template_chooser.get_selection()->set_mode (SELECTION_SINGLE);
234         trk_template_chooser.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &AddRouteDialog::trk_template_row_selected));
235         trk_template_chooser.set_sensitive (true);
236
237         /* template_desc is the textview that displays the currently selected template's description */
238         trk_template_desc.set_editable (false);
239         trk_template_desc.set_can_focus (false);
240         trk_template_desc.set_wrap_mode (Gtk::WRAP_WORD);
241         trk_template_desc.set_size_request(400,200);
242         trk_template_desc.set_name (X_("TextOnBackground"));
243         trk_template_desc.set_border_width (6);
244
245         Table *settings_table = manage (new Table (2, 6, false));
246         settings_table->set_row_spacings (8);
247         settings_table->set_col_spacings        (4);
248         settings_table->set_col_spacing (3, 20);
249         settings_table->set_border_width        (12);
250
251         VBox* settings_vbox = manage (new VBox);
252         settings_vbox->pack_start(trk_template_desc_frame , true, true);
253         settings_vbox->pack_start(*settings_table , true, true);
254         settings_vbox->set_border_width (4);
255
256         trk_template_outer_frame.add (*settings_vbox);
257
258         template_hbox->pack_start (*template_scroller, true, true);
259         template_hbox->pack_start (trk_template_outer_frame, true, true);
260
261         vbox->pack_start (*template_hbox, true, true);
262
263
264         /* Now pack the "settings table" with manual controls (these controls are sensitized by the left-side selection) */
265
266         int n = 0;
267
268         HBox *separator_hbox = manage (new HBox);
269         separator_hbox->pack_start (manual_label, false, false);
270         separator_hbox->pack_start (*(manage (new Gtk::HSeparator)), true, true);
271         separator_hbox->set_spacing (6);
272         settings_table->attach (*separator_hbox, 0, 6, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
273
274         ++n;
275
276         /* Number */
277         add_label.set_alignment (Gtk::ALIGN_RIGHT, Gtk::ALIGN_CENTER);
278         settings_table->attach (add_label, 0, 1, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
279         Gtk::Alignment *align = manage (new Alignment (0, .5, 0, 0));
280         align->add (routes_spinner);
281         settings_table->attach (*align, 1, 2, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
282
283         ++n;
284
285         /* Name */
286         name_label.set_alignment (Gtk::ALIGN_RIGHT, Gtk::ALIGN_CENTER);
287         settings_table->attach (name_label, 0, 1, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
288         settings_table->attach (name_template_entry, 1, 3, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
289
290         /* Route configuration */
291         configuration_label.set_alignment (Gtk::ALIGN_RIGHT, Gtk::ALIGN_CENTER);
292         settings_table->attach (configuration_label, 4, 5, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
293         settings_table->attach (channel_combo, 5, 6, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
294
295         ++n;
296
297         /* instrument choice (for MIDI) */
298         instrument_label.set_alignment (Gtk::ALIGN_RIGHT, Gtk::ALIGN_CENTER);
299         settings_table->attach (instrument_label, 0, 1, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
300         settings_table->attach (instrument_combo, 1, 3, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
301
302         /* Group choice */
303         group_label.set_alignment (Gtk::ALIGN_RIGHT, Gtk::ALIGN_CENTER);
304         settings_table->attach (group_label, 4, 5, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
305         settings_table->attach (route_group_combo, 5, 6, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
306
307         ++n;
308
309         /* New Route's I/O is.. {strict/flexible} */
310         if (Profile->get_mixbus ()) {
311                 strict_io_combo.set_active (1);
312         } else {
313                 strict_io_label.set_alignment (Gtk::ALIGN_RIGHT, Gtk::ALIGN_CENTER);
314                 settings_table->attach (strict_io_label, 0, 1, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
315                 settings_table->attach (strict_io_combo, 1, 3, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
316
317                 ArdourWidgets::set_tooltip (strict_io_combo,
318                                 _("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."));
319
320                 /* recording mode */
321                 mode_label.set_alignment (Gtk::ALIGN_RIGHT, Gtk::ALIGN_CENTER);
322                 settings_table->attach (mode_label, 4, 5, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
323                 settings_table->attach (mode_combo, 5, 6, n, n + 1, Gtk::FILL, Gtk::SHRINK, 0, 0);
324
325                 ++n;
326         }
327
328         HBox* outer_box = manage (new HBox);
329         outer_box->set_spacing (4);
330
331         /* New route will be inserted at.. */
332         insert_label.set_alignment (Gtk::ALIGN_RIGHT, Gtk::ALIGN_CENTER);
333         outer_box->pack_start (insert_label, false, false);
334         outer_box->pack_start (insert_at_combo, false, false);
335
336         /* quick-add button (add item but don't close dialog) */
337         Gtk::Button* addnoclose_button = manage (new Gtk::Button(_("Add selected items (and leave dialog open)")));
338         addnoclose_button->set_can_default ();
339         addnoclose_button->signal_clicked ().connect (sigc::bind (sigc::mem_fun (*this, &Gtk::Dialog::response), Add));
340         outer_box->pack_end (*addnoclose_button, false, false);
341
342         vbox->pack_start (*outer_box, true, true);
343
344         get_vbox()->pack_start (*vbox, false, false);
345
346         name_template_entry.signal_insert_text ().connect (sigc::mem_fun (*this, &AddRouteDialog::name_template_entry_insertion));
347         name_template_entry.signal_delete_text ().connect (sigc::mem_fun (*this, &AddRouteDialog::name_template_entry_deletion));
348         channel_combo.signal_changed().connect (sigc::mem_fun (*this, &AddRouteDialog::channel_combo_changed));
349         channel_combo.set_row_separator_func (sigc::mem_fun (*this, &AddRouteDialog::channel_separator));
350         route_group_combo.set_row_separator_func (sigc::mem_fun (*this, &AddRouteDialog::route_separator));
351         route_group_combo.signal_changed ().connect (sigc::mem_fun (*this, &AddRouteDialog::group_changed));
352
353         routes_spinner.signal_activate ().connect (sigc::bind (sigc::mem_fun (*this, &Gtk::Dialog::response), AddAndClose));
354         name_template_entry.signal_activate ().connect (sigc::bind (sigc::mem_fun (*this, &Gtk::Dialog::response), AddAndClose));
355         trk_template_chooser.signal_row_activated ().connect (sigc::hide (sigc::hide (sigc::bind (sigc::mem_fun (*this, &Gtk::Dialog::response), AddAndClose))));
356
357         show_all_children ();
358
359         /* track template info will be managed whenever
360          * this dialog is shown, via ::on_show()
361          */
362
363         add_button (_("Add and Close"), AddAndClose);
364         set_response_sensitive (AddAndClose, true);
365         set_default_response (AddAndClose);
366
367         refill_channel_setups ();
368 }
369
370 AddRouteDialog::~AddRouteDialog ()
371 {
372 }
373
374 void
375 AddRouteDialog::on_response (int r)
376 {
377         reset_name_edited ();
378         /* Don't call ArdourDialog::on_response() because that will
379            automatically hide the dialog.
380         */
381         Gtk::Dialog::on_response (r);
382 }
383
384 void
385 AddRouteDialog::trk_template_row_selected ()
386 {
387         if (trk_template_chooser.get_selection()->count_selected_rows() != 1) {
388                 return;
389         }
390
391         TreeIter iter = trk_template_chooser.get_selection ()->get_selected ();
392         assert (iter);
393
394         string d = (*iter)[track_template_columns.description];
395         trk_template_desc.get_buffer ()->set_text (d);
396
397         const string n = (*iter)[track_template_columns.name];
398         const string p = (*iter)[track_template_columns.path];
399
400         if (p.substr (0, 11) == "urn:ardour:") {
401                 /* lua script - meta-template */
402                 const std::map<std::string, std::string> rs (ARDOUR_UI::instance()->route_setup_info (p.substr (11)));
403
404                 trk_template_desc.set_sensitive (true);
405
406                 add_label.set_sensitive (rs.find ("how_many") != rs.end ());
407                 name_label.set_sensitive (rs.find ("name") != rs.end());
408                 group_label.set_sensitive (rs.find ("group") != rs.end());
409                 configuration_label.set_sensitive (rs.find ("channels") != rs.end ());
410                 mode_label.set_sensitive (rs.find ("track_mode") != rs.end ());
411                 instrument_label.set_sensitive (rs.find ("instrument") != rs.end ());
412                 strict_io_label.set_sensitive (rs.find ("strict_io") != rs.end());
413
414                 routes_spinner.set_sensitive (rs.find ("how_many") != rs.end ());
415                 name_template_entry.set_sensitive (rs.find ("name") != rs.end ());
416                 route_group_combo.set_sensitive (rs.find ("group") != rs.end());
417                 channel_combo.set_sensitive (rs.find ("channels") != rs.end ());
418                 mode_combo.set_sensitive (rs.find ("track_mode") != rs.end ());
419                 instrument_combo.set_sensitive (rs.find ("instrument") != rs.end ());
420                 strict_io_combo.set_sensitive (rs.find ("strict_io") != rs.end());
421
422                 bool any_enabled = rs.find ("how_many") != rs.end ()
423                         || rs.find ("name") != rs.end ()
424                         || rs.find ("group") != rs.end()
425                         || rs.find ("channels") != rs.end ()
426                         || rs.find ("track_mode") != rs.end ()
427                         || rs.find ("instrument") != rs.end ()
428                         || rs.find ("strict_io") != rs.end();
429
430                 manual_label.set_sensitive (any_enabled);
431
432                 std::map<string,string>::const_iterator it;
433
434                 if ((it = rs.find ("name")) != rs.end()) {
435                         name_template_entry.set_text (it->second);
436                 } else {
437                         name_template_entry.set_text ("");
438                 }
439
440                 if ((it = rs.find ("how_many")) != rs.end()) {
441                         if (atoi (it->second.c_str()) > 0) {
442                                 routes_adjustment.set_value (atoi (it->second.c_str()));
443                         }
444                 }
445
446                 if ((it = rs.find ("track_mode")) != rs.end()) {
447                         switch ((ARDOUR::TrackMode) atoi (it->second.c_str())) {
448                                 case ARDOUR::Normal:
449                                         mode_combo.set_active_text (_("Normal"));
450                                         break;
451                                 case ARDOUR::Destructive:
452                                         if (!ARDOUR::Profile->get_mixbus ()) {
453                                                 mode_combo.set_active_text (_("Tape"));
454                                         }
455                                         break;
456                                 default: // "NonLayered" enum is still present for session-format compat
457                                         break;
458                         }
459                 }
460
461                 if ((it = rs.find ("strict_io")) != rs.end()) {
462                         if (it->second == X_("true")) {
463                                 strict_io_combo.set_active (1);
464                         } else if (it->second == X_("false")) {
465                                 strict_io_combo.set_active (0);
466                         }
467                 }
468
469                 if ((it = rs.find ("channels")) != rs.end()) {
470                         uint32_t channels = atoi (it->second.c_str());
471                         for (ChannelSetups::iterator i = channel_setups.begin(); i != channel_setups.end(); ++i) {
472                                 if ((*i).channels == channels) {
473                                         channel_combo.set_active_text ((*i).name);
474                                         break;
475                                 }
476                         }
477                 }
478
479         } else if (!p.empty ()) {
480                 /* user-template */
481                 trk_template_desc.set_sensitive (true);
482
483                 manual_label.set_sensitive (true);
484                 add_label.set_sensitive (true);
485                 name_label.set_sensitive (true);
486                 group_label.set_sensitive (false);
487                 strict_io_label.set_sensitive (false);
488                 configuration_label.set_sensitive (false);
489                 mode_label.set_sensitive (false);
490                 instrument_label.set_sensitive (false);
491
492                 routes_spinner.set_sensitive (true);
493                 name_template_entry.set_sensitive (true);
494                 channel_combo.set_sensitive (false);
495                 mode_combo.set_sensitive (false);
496                 instrument_combo.set_sensitive (false);
497                 strict_io_combo.set_sensitive (false);
498                 route_group_combo.set_sensitive (false);
499
500         } else {
501                 /* all manual mode */
502                 trk_template_desc.set_sensitive (false);
503
504                 manual_label.set_sensitive (true);
505                 add_label.set_sensitive (true);
506                 name_label.set_sensitive (true);
507                 group_label.set_sensitive (true);
508                 strict_io_label.set_sensitive (true);
509
510                 routes_spinner.set_sensitive (true);
511                 name_template_entry.set_sensitive (true);
512                 track_type_chosen ();
513         }
514 }
515
516
517 void
518 AddRouteDialog::name_template_entry_insertion (Glib::ustring const &,int*)
519 {
520         if (name_template ().empty ()) {
521                 name_edited_by_user = false;
522         } else {
523                 name_edited_by_user = true;
524         }
525 }
526
527 void
528 AddRouteDialog::name_template_entry_deletion (int, int)
529 {
530         if (name_template ().empty ()) {
531                 name_edited_by_user = false;
532         } else {
533                 name_edited_by_user = true;
534         }
535 }
536
537 void
538 AddRouteDialog::channel_combo_changed ()
539 {
540         refill_track_modes ();
541 }
542
543 std::string
544 AddRouteDialog::get_template_path ()
545 {
546         string p;
547
548         if (trk_template_chooser.get_selection()->count_selected_rows() > 0) {
549                 TreeIter iter = trk_template_chooser.get_selection()->get_selected();
550
551                 if (iter) {
552                         string n = (*iter)[track_template_columns.name];
553                         if (n != _("Manual Configuration")) {
554                                 p = (*iter)[track_template_columns.path];
555                         }
556                 }
557         }
558
559         return p;
560 }
561
562
563 AddRouteDialog::TypeWanted
564 AddRouteDialog::type_wanted()
565 {
566         if (trk_template_chooser.get_selection()->count_selected_rows() != 1) {
567                 return AudioTrack;
568         }
569         TreeIter iter = trk_template_chooser.get_selection ()->get_selected ();
570         assert (iter);
571
572         const string str = (*iter)[track_template_columns.name];
573         if (str == _("Audio Busses")) {
574                 return AudioBus;
575         } else if (str == _("MIDI Busses")){
576                 return MidiBus;
577         } else if (str == _("MIDI Tracks")){
578                 return MidiTrack;
579         } else if (str == _("Audio+MIDI Tracks")) {
580                 return MixedTrack;
581         } else if (str == _("Audio Tracks")) {
582                 return AudioTrack;
583         } else if (str == _("VCA Masters")) {
584                 return VCAMaster;
585         } else if (str == _("Foldback Busses")) {
586                 return FoldbackBus;
587         } else {
588                 assert (0);
589                 return AudioTrack;
590         }
591 }
592
593 void
594 AddRouteDialog::maybe_update_name_template_entry ()
595 {
596         if (name_edited_by_user) {
597                 return;
598         }
599
600         switch (type_wanted()) {
601         case AudioTrack:
602                 name_template_entry.set_text (_("Audio"));
603                 break;
604         case MidiTrack:
605                 name_template_entry.set_text (_("MIDI"));
606                 break;
607         case MixedTrack:
608                 name_template_entry.set_text (_("Audio+MIDI"));
609                 break;
610         case AudioBus:
611         case MidiBus:
612                 name_template_entry.set_text (_("Bus"));
613                 break;
614         case FoldbackBus:
615                 name_template_entry.set_text (_("Foldback"));
616                 break;
617         case VCAMaster:
618                 name_template_entry.set_text (VCA::default_name_template());
619                 break;
620         }
621         /* ignore programatic change, restore false */
622         reset_name_edited ();
623 }
624
625 void
626 AddRouteDialog::track_type_chosen ()
627 {
628         switch (type_wanted()) {
629         case AudioTrack:
630
631                 configuration_label.set_sensitive (true);
632                 channel_combo.set_sensitive (true);
633
634                 mode_label.set_sensitive (true);
635                 mode_combo.set_sensitive (true);
636
637                 instrument_label.set_sensitive (false);
638                 instrument_combo.set_sensitive (false);
639
640                 group_label.set_sensitive (true);
641                 route_group_combo.set_sensitive (true);
642
643                 strict_io_label.set_sensitive (true);
644                 strict_io_combo.set_sensitive (true);
645
646                 insert_label.set_sensitive (true);
647                 insert_at_combo.set_sensitive (true);
648
649                 break;
650         case MidiTrack:
651
652                 configuration_label.set_sensitive (false);
653                 channel_combo.set_sensitive (false);
654
655                 mode_label.set_sensitive (false);
656                 mode_combo.set_sensitive (false);
657
658                 instrument_label.set_sensitive (true);
659                 instrument_combo.set_sensitive (true);
660
661                 group_label.set_sensitive (true);
662                 route_group_combo.set_sensitive (true);
663
664                 strict_io_label.set_sensitive (true);
665                 strict_io_combo.set_sensitive (true);
666
667                 insert_label.set_sensitive (true);
668                 insert_at_combo.set_sensitive (true);
669
670                 break;
671         case MixedTrack:
672                 {
673                         MessageDialog msg (_("Audio+MIDI tracks are intended for use <b>ONLY</b> with plugins that use both audio and MIDI input data.\n\n"
674                                              "Use a normal audio or MIDI track if you do not plan to use such a plugin."),
675                                            true, MESSAGE_INFO, BUTTONS_OK, true);
676                         msg.set_position (WIN_POS_MOUSE);
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 }