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