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