2de735245a6005b5f9fd805977c7ba2fa1e1e09a
[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/separator.h>
26 #include <gtkmm/table.h>
27
28 #include "pbd/error.h"
29 #include "pbd/convert.h"
30 #include "gtkmm2ext/utils.h"
31 #include "ardour/profile.h"
32 #include "ardour/template_utils.h"
33 #include "ardour/route_group.h"
34 #include "ardour/session.h"
35
36 #include "utils.h"
37 #include "add_route_dialog.h"
38 #include "route_group_dialog.h"
39 #include "i18n.h"
40
41 using namespace Gtk;
42 using namespace Gtkmm2ext;
43 using namespace std;
44 using namespace PBD;
45 using namespace ARDOUR;
46
47 std::vector<std::string> AddRouteDialog::channel_combo_strings;
48
49 AddRouteDialog::AddRouteDialog (Session* s)
50         : ArdourDialog (_("Add Track or Bus"))
51         , routes_adjustment (1, 1, 128, 1, 4)
52         , routes_spinner (routes_adjustment)
53         , mode_label (_("Track mode:"))
54 {
55         set_session (s);
56
57         set_name ("AddRouteDialog");
58         set_position (Gtk::WIN_POS_MOUSE);
59         set_modal (true);
60         set_skip_taskbar_hint (true);
61         set_resizable (false);
62
63         name_template_entry.set_name (X_("AddRouteDialogNameTemplateEntry"));
64         // routes_spinner.set_name (X_("AddRouteDialogSpinner"));
65         channel_combo.set_name (X_("ChannelCountSelector"));
66         mode_combo.set_name (X_("ChannelCountSelector"));
67
68         refill_channel_setups ();
69         refill_route_groups ();
70         refill_track_modes ();
71
72         channel_combo.set_active_text (channel_combo_strings.front());
73
74         track_bus_combo.append_text (_("Audio Tracks"));
75         track_bus_combo.append_text (_("MIDI Tracks"));
76         track_bus_combo.append_text (_("Busses"));
77         track_bus_combo.set_active (0);
78
79         VBox* vbox = manage (new VBox);
80         Gtk::Label* l;
81
82         get_vbox()->set_spacing (4);
83
84         vbox->set_spacing (18);
85         vbox->set_border_width (5);
86
87         HBox *type_hbox = manage (new HBox);
88         type_hbox->set_spacing (6);
89
90         /* track/bus choice */
91
92         type_hbox->pack_start (*manage (new Label (_("Add:"))));
93         type_hbox->pack_start (routes_spinner);
94         type_hbox->pack_start (track_bus_combo);
95
96         vbox->pack_start (*type_hbox, false, true);
97
98         VBox* options_box = manage (new VBox);
99         Table *table2 = manage (new Table (3, 3, false));
100
101         options_box->set_spacing (6);
102         table2->set_row_spacings (6);
103         table2->set_col_spacing (1, 6);
104
105         l = manage (new Label (_("<b>Options</b>"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
106         l->set_use_markup ();
107         options_box->pack_start (*l, false, true);
108
109         l = manage (new Label ("", Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
110         l->set_padding (8, 0);
111         table2->attach (*l, 0, 1, 0, 3, Gtk::FILL, Gtk::FILL, 0, 0);
112
113         int n = 0;
114
115         l = manage (new Label (_("Name:"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
116         table2->attach (*l, 1, 2, n, n + 1, Gtk::FILL, Gtk::EXPAND, 0, 0);
117         table2->attach (name_template_entry, 2, 3, n, n + 1, Gtk::FILL, Gtk::EXPAND | Gtk::FILL, 0, 0);
118         ++n;
119
120         /* Route configuration */
121
122         l = manage (new Label (_("Configuration:"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
123         table2->attach (*l, 1, 2, n, n + 1, Gtk::FILL, Gtk::EXPAND, 0, 0);
124         table2->attach (channel_combo, 2, 3, n, n + 1, Gtk::FILL, Gtk::EXPAND | Gtk::FILL, 0, 0);
125         ++n;
126
127         if (!ARDOUR::Profile->get_sae ()) {
128
129                 /* Track mode */
130
131                 mode_label.set_alignment (Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER);
132                 table2->attach (mode_label, 1, 2, n, n + 1, Gtk::FILL, Gtk::EXPAND, 0, 0);
133                 table2->attach (mode_combo, 2, 3, n, n + 1, Gtk::FILL, Gtk::EXPAND | Gtk::FILL, 0, 0);
134                 ++n;
135
136         }
137
138         /* Group choice */
139
140         l = manage (new Label (_("Group:"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
141         table2->attach (*l, 1, 2, n, n + 1, Gtk::FILL, Gtk::EXPAND, 0, 0);
142         table2->attach (route_group_combo, 2, 3, n, n + 1, Gtk::FILL, Gtk::EXPAND | Gtk::FILL, 0, 0);
143         ++n;
144
145         options_box->pack_start (*table2, false, true);
146         vbox->pack_start (*options_box, false, true);
147
148         get_vbox()->pack_start (*vbox, false, false);
149
150         track_bus_combo.signal_changed().connect (sigc::mem_fun (*this, &AddRouteDialog::track_type_chosen));
151         channel_combo.signal_changed().connect (sigc::mem_fun (*this, &AddRouteDialog::channel_combo_changed));
152         channel_combo.set_row_separator_func (sigc::mem_fun (*this, &AddRouteDialog::channel_separator));
153         route_group_combo.set_row_separator_func (sigc::mem_fun (*this, &AddRouteDialog::route_separator));
154         route_group_combo.signal_changed ().connect (sigc::mem_fun (*this, &AddRouteDialog::group_changed));
155
156         show_all_children ();
157
158         /* track template info will be managed whenever
159            this dialog is shown, via ::on_show()
160         */
161
162         add_button (Stock::CANCEL, RESPONSE_CANCEL);
163         add_button (Stock::ADD, RESPONSE_ACCEPT);
164
165         track_type_chosen ();
166 }
167
168 AddRouteDialog::~AddRouteDialog ()
169 {
170 }
171
172 void
173 AddRouteDialog::channel_combo_changed ()
174 {
175         maybe_update_name_template_entry ();
176         refill_track_modes ();
177 }
178
179 void
180 AddRouteDialog::maybe_update_name_template_entry ()
181 {
182         if (
183                 name_template_entry.get_text() != "" &&
184                 name_template_entry.get_text() != _("Audio") &&
185                 name_template_entry.get_text() != _("MIDI")  &&
186                 name_template_entry.get_text() != _("Bus")) {
187                 return;
188         }
189
190         if (audio_tracks_wanted ()) {
191                 name_template_entry.set_text (_("Audio"));
192         } else if (midi_tracks_wanted()) {
193                 name_template_entry.set_text (_("MIDI"));
194         } else {
195                 name_template_entry.set_text (_("Bus"));
196         }
197 }
198
199 void
200 AddRouteDialog::track_type_chosen ()
201 {
202         if (midi_tracks_wanted()) {
203                 channel_combo.set_sensitive (false);
204                 mode_combo.set_sensitive (false);
205         } else if (audio_tracks_wanted()) {
206                 mode_combo.set_sensitive (true);
207                 channel_combo.set_sensitive (true);
208         } else {
209                 mode_combo.set_sensitive (false);
210                 channel_combo.set_sensitive (true);
211         }
212
213         maybe_update_name_template_entry ();
214 }
215
216 bool
217 AddRouteDialog::audio_tracks_wanted ()
218 {
219         return track_bus_combo.get_active_row_number () == 0;
220 }
221
222 bool
223 AddRouteDialog::midi_tracks_wanted ()
224 {
225         return track_bus_combo.get_active_row_number () == 1;
226 }
227
228 string
229 AddRouteDialog::name_template ()
230 {
231         return name_template_entry.get_text ();
232 }
233
234 int
235 AddRouteDialog::count ()
236 {
237         return (int) floor (routes_adjustment.get_value ());
238 }
239
240 void
241 AddRouteDialog::refill_track_modes ()
242 {
243         vector<string> s;
244         
245         s.push_back (_("Normal"));
246
247         if (!ARDOUR::Profile->get_sae ()) {
248                 s.push_back (_("Non Layered"));
249                 s.push_back (_("Tape"));
250         }
251
252         set_popdown_strings (mode_combo, s);
253         mode_combo.set_active_text (s.front());
254 }
255
256 ARDOUR::TrackMode
257 AddRouteDialog::mode ()
258 {
259         if (ARDOUR::Profile->get_sae()) {
260                 return ARDOUR::Normal;
261         }
262
263         std::string str = mode_combo.get_active_text();
264         if (str == _("Normal")) {
265                 return ARDOUR::Normal;
266         } else if (str == _("Non Layered")){
267                 return ARDOUR::NonLayered;
268         } else if (str == _("Tape")) {
269                 return ARDOUR::Destructive;
270         } else {
271                 fatal << string_compose (X_("programming error: unknown track mode in add route dialog combo = %1"), str)
272                       << endmsg;
273                 /*NOTREACHED*/
274         }
275         /* keep gcc happy */
276         return ARDOUR::Normal;
277 }
278
279 int
280 AddRouteDialog::channels ()
281 {
282         string str = channel_combo.get_active_text();
283
284         for (ChannelSetups::iterator i = channel_setups.begin(); i != channel_setups.end(); ++i) {
285                 if (str == (*i).name) {
286                         return (*i).channels;
287                 }
288         }
289
290         return 0;
291 }
292
293 string
294 AddRouteDialog::track_template ()
295 {
296         string str = channel_combo.get_active_text();
297
298         for (ChannelSetups::iterator i = channel_setups.begin(); i != channel_setups.end(); ++i) {
299                 if (str == (*i).name) {
300                         return (*i).template_path;
301                 }
302         }
303
304         return string();
305 }
306
307 void
308 AddRouteDialog::on_show ()
309 {
310         refill_channel_setups ();
311         refill_route_groups ();
312
313         Dialog::on_show ();
314 }
315
316 void
317 AddRouteDialog::refill_channel_setups ()
318 {
319         ChannelSetup chn;
320
321         route_templates.clear ();
322         channel_combo_strings.clear ();
323         channel_setups.clear ();
324
325         chn.name = _("Mono");
326         chn.channels = 1;
327         channel_setups.push_back (chn);
328
329         chn.name = _("Stereo");
330         chn.channels = 2;
331         channel_setups.push_back (chn);
332
333         chn.name = "separator";
334         channel_setups.push_back (chn);
335
336         ARDOUR::find_route_templates (route_templates);
337
338         if (!ARDOUR::Profile->get_sae()) {
339                 if (!route_templates.empty()) {
340                         vector<string> v;
341                         for (vector<TemplateInfo>::iterator x = route_templates.begin(); x != route_templates.end(); ++x) {
342                                 chn.name = x->name;
343                                 chn.channels = 0;
344                                 chn.template_path = x->path;
345                                 channel_setups.push_back (chn);
346                         }
347                 }
348
349                 /* clear template path for the rest */
350
351                 chn.template_path = "";
352
353                 chn.name = _("3 Channel");
354                 chn.channels = 3;
355                 channel_setups.push_back (chn);
356
357                 chn.name = _("4 Channel");
358                 chn.channels = 4;
359                 channel_setups.push_back (chn);
360
361                 chn.name = _("5 Channel");
362                 chn.channels = 5;
363                 channel_setups.push_back (chn);
364
365                 chn.name = _("6 Channel");
366                 chn.channels = 6;
367                 channel_setups.push_back (chn);
368
369                 chn.name = _("8 Channel");
370                 chn.channels = 8;
371                 channel_setups.push_back (chn);
372
373                 chn.name = _("12 Channel");
374                 chn.channels = 12;
375                 channel_setups.push_back (chn);
376
377                 chn.name = _("Custom");
378                 chn.channels = 0;
379                 channel_setups.push_back (chn);
380         }
381
382         for (ChannelSetups::iterator i = channel_setups.begin(); i != channel_setups.end(); ++i) {
383                 channel_combo_strings.push_back ((*i).name);
384         }
385
386         set_popdown_strings (channel_combo, channel_combo_strings);
387         channel_combo.set_active_text (channel_combo_strings.front());
388 }
389
390 void
391 AddRouteDialog::add_route_group (RouteGroup* g)
392 {
393         route_group_combo.insert_text (3, g->name ());
394 }
395
396 RouteGroup*
397 AddRouteDialog::route_group ()
398 {
399         if (route_group_combo.get_active_row_number () == 2) {
400                 return 0;
401         }
402
403         return _session->route_group_by_name (route_group_combo.get_active_text());
404 }
405
406 void
407 AddRouteDialog::refill_route_groups ()
408 {
409         route_group_combo.clear ();
410         route_group_combo.append_text (_("New Group..."));
411
412         route_group_combo.append_text ("separator");
413
414         route_group_combo.append_text (_("No Group"));
415
416         _session->foreach_route_group (sigc::mem_fun (*this, &AddRouteDialog::add_route_group));
417
418         route_group_combo.set_active (2);
419 }
420
421 void
422 AddRouteDialog::group_changed ()
423 {
424         if (_session && route_group_combo.get_active_text () == _("New Group...")) {
425                 RouteGroup* g = new RouteGroup (*_session, "");
426
427                 PropertyList plist;
428                 plist.add (Properties::active, true);
429                 g->apply_changes (plist);
430
431                 RouteGroupDialog d (g, true);
432
433                 if (d.do_run ()) {
434                         delete g;
435                         route_group_combo.set_active (2);
436                 } else {
437                         _session->add_route_group (g);
438                         add_route_group (g);
439                         route_group_combo.set_active (3);
440                 }
441         }
442 }
443
444 bool
445 AddRouteDialog::channel_separator (const Glib::RefPtr<Gtk::TreeModel> &, const Gtk::TreeModel::iterator &i)
446 {
447         channel_combo.set_active (i);
448
449         return channel_combo.get_active_text () == "separator";
450 }
451
452 bool
453 AddRouteDialog::route_separator (const Glib::RefPtr<Gtk::TreeModel> &, const Gtk::TreeModel::iterator &i)
454 {
455         route_group_combo.set_active (i);
456
457         return route_group_combo.get_active_text () == "separator";
458 }
459