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