Remove spurious semicolon.
[ardour.git] / gtk2_ardour / route_ui.cc
1 /*
2     Copyright (C) 2002-2006 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 <gtkmm2ext/gtk_ui.h>
21 #include <gtkmm2ext/choice.h>
22 #include <gtkmm2ext/doi.h>
23 #include <gtkmm2ext/bindable_button.h>
24 #include <gtkmm2ext/barcontroller.h>
25 #include <gtkmm2ext/gtk_ui.h>
26
27 #include "ardour/route_group.h"
28 #include "ardour/dB.h"
29 #include "pbd/memento_command.h"
30 #include "pbd/stacktrace.h"
31 #include "pbd/controllable.h"
32 #include "pbd/enumwriter.h"
33
34 #include "ardour_ui.h"
35 #include "editor.h"
36 #include "route_ui.h"
37 #include "ardour_button.h"
38 #include "keyboard.h"
39 #include "utils.h"
40 #include "prompter.h"
41 #include "gui_thread.h"
42 #include "ardour_dialog.h"
43 #include "latency_gui.h"
44 #include "mixer_strip.h"
45 #include "automation_time_axis.h"
46 #include "route_time_axis.h"
47 #include "group_tabs.h"
48
49 #include "ardour/route.h"
50 #include "ardour/event_type_map.h"
51 #include "ardour/session.h"
52 #include "ardour/audioengine.h"
53 #include "ardour/audio_track.h"
54 #include "ardour/midi_track.h"
55 #include "ardour/template_utils.h"
56 #include "ardour/filename_extensions.h"
57 #include "ardour/directory_names.h"
58 #include "ardour/profile.h"
59
60 #include "i18n.h"
61 using namespace Gtk;
62 using namespace Gtkmm2ext;
63 using namespace ARDOUR;
64 using namespace PBD;
65
66 uint32_t RouteUI::_max_invert_buttons = 3;
67 sigc::signal<void, boost::shared_ptr<Route> > RouteUI::BusSendDisplayChanged;
68 boost::weak_ptr<Route> RouteUI::_showing_sends_to;
69
70 RouteUI::RouteUI (ARDOUR::Session* sess)
71         : AxisView(sess)
72 {
73         init ();
74 }
75
76 RouteUI::~RouteUI()
77 {
78         _route.reset (); /* drop reference to route, so that it can be cleaned up */
79         route_connections.drop_connections ();
80
81         delete solo_menu;
82         delete mute_menu;
83         delete sends_menu;
84         delete record_menu;
85         delete _invert_menu;
86 }
87
88 void
89 RouteUI::init ()
90 {
91         self_destruct = true;
92         mute_menu = 0;
93         solo_menu = 0;
94         sends_menu = 0;
95         record_menu = 0;
96         _invert_menu = 0;
97         pre_fader_mute_check = 0;
98         post_fader_mute_check = 0;
99         listen_mute_check = 0;
100         main_mute_check = 0;
101         solo_safe_check = 0;
102         solo_isolated_check = 0;
103         solo_isolated_led = 0;
104         solo_safe_led = 0;
105         _solo_release = 0;
106         _mute_release = 0;
107         denormal_menu_item = 0;
108         step_edit_item = 0;
109         multiple_mute_change = false;
110         multiple_solo_change = false;
111         _i_am_the_modifier = 0;
112
113         setup_invert_buttons ();
114
115         mute_button = manage (new ArdourButton);
116         mute_button->set_name ("mute button");
117         UI::instance()->set_tip (mute_button, _("Mute this track"), "");
118
119         solo_button = manage (new ArdourButton);
120         solo_button->set_name ("solo button");
121         UI::instance()->set_tip (solo_button, _("Mute other (non-soloed) tracks"), "");
122         solo_button->set_no_show_all (true);
123
124         rec_enable_button = manage (new ArdourButton);
125         rec_enable_button->set_name ("record enable button");
126         UI::instance()->set_tip (rec_enable_button, _("Enable recording on this track"), "");
127
128         show_sends_button = manage (new ArdourButton);
129         show_sends_button->set_name ("send alert button");
130         UI::instance()->set_tip (show_sends_button, _("make mixer strips show sends to this bus"), "");
131
132         monitor_input_button = manage (new ArdourButton (ArdourButton::led_default_elements));
133         monitor_input_button->set_name ("monitor");
134         monitor_input_button->set_text (_("In"));
135         UI::instance()->set_tip (monitor_input_button, _("Monitor input"), "");
136         monitor_input_button->set_no_show_all (true);
137
138         monitor_disk_button = manage (new ArdourButton (ArdourButton::led_default_elements));
139         monitor_disk_button->set_name ("monitor");
140         monitor_disk_button->set_text (_("Disk"));
141         UI::instance()->set_tip (monitor_disk_button, _("Monitor playback"), "");
142         monitor_disk_button->set_no_show_all (true);
143
144         _session->SoloChanged.connect (_session_connections, invalidator (*this), boost::bind (&RouteUI::solo_changed_so_update_mute, this), gui_context());
145         _session->TransportStateChange.connect (_session_connections, invalidator (*this), boost::bind (&RouteUI::check_rec_enable_sensitivity, this), gui_context());
146         _session->RecordStateChanged.connect (_session_connections, invalidator (*this), boost::bind (&RouteUI::session_rec_enable_changed, this), gui_context());
147
148         _session->config.ParameterChanged.connect (*this, invalidator (*this), ui_bind (&RouteUI::parameter_changed, this, _1), gui_context());
149         Config->ParameterChanged.connect (*this, invalidator (*this), ui_bind (&RouteUI::parameter_changed, this, _1), gui_context());
150
151         rec_enable_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::rec_enable_press), false);
152         rec_enable_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::rec_enable_release), false);
153
154         show_sends_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::show_sends_press), false);
155         show_sends_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::show_sends_release));
156
157         solo_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::solo_press), false);
158         solo_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::solo_release), false);
159         mute_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::mute_press), false);
160         mute_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::mute_release), false);
161         
162         monitor_input_button->set_distinct_led_click (false);
163         monitor_disk_button->set_distinct_led_click (false);
164
165         monitor_input_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_input_press));
166         monitor_input_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_input_release));
167
168         monitor_disk_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_disk_press));
169         monitor_disk_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_disk_release));
170
171         BusSendDisplayChanged.connect (sigc::mem_fun (*this, &RouteUI::bus_send_display_changed));
172 }
173
174 void
175 RouteUI::reset ()
176 {
177         route_connections.drop_connections ();
178
179         delete solo_menu;
180         solo_menu = 0;
181
182         delete mute_menu;
183         mute_menu = 0;
184
185         denormal_menu_item = 0;
186 }
187
188 void
189 RouteUI::self_delete ()
190 {
191         delete this;
192 }
193
194 void
195 RouteUI::set_route (boost::shared_ptr<Route> rp)
196 {
197         reset ();
198
199         _route = rp;
200
201         if (set_color_from_route()) {
202                 set_color (unique_random_color());
203         }
204
205         if (self_destruct) {
206                 rp->DropReferences.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::self_delete, this), gui_context());
207         }
208
209         mute_button->set_controllable (_route->mute_control());
210         solo_button->set_controllable (_route->solo_control());
211
212         _route->active_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::route_active_changed, this), gui_context());
213         _route->mute_changed.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::mute_changed, this, _1), gui_context());
214
215         _route->solo_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context());
216         _route->solo_safe_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context());
217         _route->listen_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context());
218         _route->solo_isolated_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context());
219
220         _route->phase_invert_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::polarity_changed, this), gui_context());
221         _route->PropertyChanged.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::property_changed, this, _1), gui_context());
222
223         _route->io_changed.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::setup_invert_buttons, this), gui_context ());
224         _route->gui_changed.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::route_gui_changed, this, _1), gui_context ());
225
226         if (_session->writable() && is_track()) {
227                 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_route);
228
229                 t->RecordEnableChanged.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::route_rec_enable_changed, this), gui_context());
230                 
231                 rec_enable_button->show();
232                 rec_enable_button->set_controllable (t->rec_enable_control());
233
234                 update_rec_display ();
235
236                 if (is_midi_track()) {
237                         midi_track()->StepEditStatusChange.connect (route_connections, invalidator (*this),
238                                                                     ui_bind (&RouteUI::step_edit_changed, this, _1), gui_context());
239                 }
240
241         }
242
243         if (is_track()) {
244                 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_route);
245                 t->MonitoringChanged.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::monitoring_changed, this), gui_context());
246
247                 update_monitoring_display ();
248         }
249
250         mute_button->unset_flags (Gtk::CAN_FOCUS);
251         solo_button->unset_flags (Gtk::CAN_FOCUS);
252
253         mute_button->show();
254
255         if (_route->is_monitor()) {
256                 solo_button->hide ();
257         } else {
258                 solo_button->show();
259         }
260
261         map_frozen ();
262
263         setup_invert_buttons ();
264         set_invert_button_state ();
265
266         boost::shared_ptr<Route> s = _showing_sends_to.lock ();
267         bus_send_display_changed (s);
268 }
269
270 void
271 RouteUI::polarity_changed ()
272 {
273         if (!_route) {
274                 return;
275         }
276
277         set_invert_button_state ();
278 }
279
280 bool
281 RouteUI::mute_press (GdkEventButton* ev)
282 {
283         if (ev->type == GDK_2BUTTON_PRESS || ev->type == GDK_3BUTTON_PRESS ) {
284                 return true;
285         }
286
287         multiple_mute_change = false;
288
289         if (!_i_am_the_modifier) {
290
291                 if (Keyboard::is_context_menu_event (ev)) {
292
293                         if (mute_menu == 0){
294                                 build_mute_menu();
295                         }
296
297                         mute_menu->popup(0,ev->time);
298
299                 } else {
300
301                         if (Keyboard::is_button2_event (ev)) {
302                                 // Primary-button2 click is the midi binding click
303                                 // button2-click is "momentary"
304
305
306                                 if (mute_button->on_button_press_event (ev)) {
307                                         return true;
308                                 }
309
310                                 _mute_release = new SoloMuteRelease (_route->muted ());
311                         }
312
313                         if (ev->button == 1 || Keyboard::is_button2_event (ev)) {
314
315                                 if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
316
317                                         if (_mute_release) {
318                                                 _mute_release->routes = _session->get_routes ();
319                                         }
320
321                                         _session->set_mute (_session->get_routes(), !_route->muted());
322
323                                 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
324
325                                         /* Primary-button1 applies change to the mix group even if it is not active
326                                            NOTE: Primary-button2 is MIDI learn.
327                                         */
328
329                                         if (ev->button == 1 && _route->route_group()) {
330                                                 if (_mute_release) {
331                                                         _mute_release->routes = _session->get_routes ();
332                                                 }
333
334                                                 _session->set_mute (_session->get_routes(), !_route->muted(), Session::rt_cleanup, true);
335                                         }
336
337                                 } else {
338
339                                         /* plain click applies change to this route */
340
341                                         boost::shared_ptr<RouteList> rl (new RouteList);
342                                         rl->push_back (_route);
343
344                                         if (_mute_release) {
345                                                 _mute_release->routes = rl;
346                                         }
347
348                                         _session->set_mute (rl, !_route->muted());
349
350                                 }
351                         }
352                 }
353
354         }
355
356         return true;
357 }
358
359 bool
360 RouteUI::mute_release (GdkEventButton*)
361 {
362         if (!_i_am_the_modifier) {
363                 if (_mute_release){
364                         _session->set_mute (_mute_release->routes, _mute_release->active, Session::rt_cleanup, true);
365                         delete _mute_release;
366                         _mute_release = 0;
367                 }
368         }
369
370         return true;
371 }
372
373 bool
374 RouteUI::solo_press(GdkEventButton* ev)
375 {
376         /* ignore double/triple clicks */
377
378         if (ev->type == GDK_2BUTTON_PRESS || ev->type == GDK_3BUTTON_PRESS ) {
379                 return true;
380         }
381
382         multiple_solo_change = false;
383
384         if (!_i_am_the_modifier) {
385
386                 if (Keyboard::is_context_menu_event (ev)) {
387
388                         if (! (solo_isolated_led && solo_isolated_led->is_visible()) ||
389                             ! (solo_safe_led && solo_safe_led->is_visible())) {
390
391                                 if (solo_menu == 0) {
392                                         build_solo_menu ();
393                                 }
394
395                                 solo_menu->popup (1, ev->time);
396                         }
397
398                 } else {
399
400                         if (Keyboard::is_button2_event (ev)) {
401
402                                 // Primary-button2 click is the midi binding click
403                                 // button2-click is "momentary"
404
405                                 if (solo_button->on_button_press_event (ev)) {
406                                         return true;
407                                 }
408
409                                 _solo_release = new SoloMuteRelease (_route->self_soloed());
410                         }
411
412                         if (ev->button == 1 || Keyboard::is_button2_event (ev)) {
413
414                                 if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
415
416                                         /* Primary-Tertiary-click applies change to all routes */
417
418                                         if (_solo_release) {
419                                                 _solo_release->routes = _session->get_routes ();
420                                         }
421
422                                         if (Config->get_solo_control_is_listen_control()) {
423                                                 _session->set_listen (_session->get_routes(), !_route->listening_via_monitor(),  Session::rt_cleanup, true);
424                                         } else {
425                                                 _session->set_solo (_session->get_routes(), !_route->self_soloed(),  Session::rt_cleanup, true);
426                                         }
427
428                                 } else if (Keyboard::modifier_state_contains (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::SecondaryModifier))) {
429
430                                         // Primary-Secondary-click: exclusively solo this track
431
432                                         if (_solo_release) {
433                                                 _solo_release->exclusive = true;
434
435                                                 boost::shared_ptr<RouteList> routes = _session->get_routes();
436
437                                                 for (RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
438                                                         if ((*i)->soloed ()) {
439                                                                 _solo_release->routes_on->push_back (*i);
440                                                         } else {
441                                                                 _solo_release->routes_off->push_back (*i);
442                                                         }
443                                                 }
444                                         }
445
446                                         if (Config->get_solo_control_is_listen_control()) {
447                                                 /* ??? we need a just_one_listen() method */
448                                         } else {
449                                                 _session->set_just_one_solo (_route, true);
450                                         }
451
452                                 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
453
454                                         // shift-click: toggle solo isolated status
455
456                                         _route->set_solo_isolated (!_route->solo_isolated(), this);
457                                         delete _solo_release;
458                                         _solo_release = 0;
459
460                                 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
461
462                                         /* Primary-button1: solo mix group.
463                                            NOTE: Primary-button2 is MIDI learn.
464                                         */
465
466                                         if (ev->button == 1 && _route->route_group()) {
467
468                                                 if (_solo_release) {
469                                                         _solo_release->routes = _route->route_group()->route_list();
470                                                 }
471
472                                                 if (Config->get_solo_control_is_listen_control()) {
473                                                         _session->set_listen (_route->route_group()->route_list(), !_route->listening_via_monitor(),  Session::rt_cleanup, true);
474                                                 } else {
475                                                         _session->set_solo (_route->route_group()->route_list(), !_route->self_soloed(),  Session::rt_cleanup, true);
476                                                 }
477                                         }
478
479                                 } else {
480
481                                         /* click: solo this route */
482
483                                         boost::shared_ptr<RouteList> rl (new RouteList);
484                                         rl->push_back (route());
485
486                                         if (_solo_release) {
487                                                 _solo_release->routes = rl;
488                                         }
489
490                                         if (Config->get_solo_control_is_listen_control()) {
491                                                 _session->set_listen (rl, !_route->listening_via_monitor());
492                                         } else {
493                                                 _session->set_solo (rl, !_route->self_soloed());
494                                         }
495                                 }
496                         }
497                 }
498         }
499
500         return true;
501 }
502
503 bool
504 RouteUI::solo_release (GdkEventButton*)
505 {
506         if (!_i_am_the_modifier) {
507
508                 if (_solo_release) {
509
510                         if (_solo_release->exclusive) {
511
512                         } else {
513                                 if (Config->get_solo_control_is_listen_control()) {
514                                         _session->set_listen (_solo_release->routes, _solo_release->active, Session::rt_cleanup, true);
515                                 } else {
516                                         _session->set_solo (_solo_release->routes, _solo_release->active, Session::rt_cleanup, true);
517                                 }
518                         }
519
520                         delete _solo_release;
521                         _solo_release = 0;
522                 }
523         }
524
525         return true;
526 }
527
528 bool
529 RouteUI::rec_enable_press(GdkEventButton* ev)
530 {
531         if (ev->type == GDK_2BUTTON_PRESS || ev->type == GDK_3BUTTON_PRESS ) {
532                 return true;
533         }
534
535         if (!_session->engine().connected()) {
536                 MessageDialog msg (_("Not connected to JACK - cannot engage record"));
537                 msg.run ();
538                 return true;
539         }
540
541         if (is_midi_track()) {
542
543                 /* cannot rec-enable while step-editing */
544
545                 if (midi_track()->step_editing()) {
546                         return true;
547                 }
548         }
549
550         if (!_i_am_the_modifier && is_track() && rec_enable_button) {
551
552                 if (Keyboard::is_button2_event (ev)) {
553
554                         // do nothing on midi sigc::bind event
555                         return rec_enable_button->on_button_press_event (ev);
556
557                 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
558
559                         _session->set_record_enabled (_session->get_routes(), !rec_enable_button->active_state());
560
561                 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
562
563                         /* Primary-button1 applies change to the route group (even if it is not active)
564                            NOTE: Primary-button2 is MIDI learn.
565                         */
566                         if (ev->button == 1 && _route->route_group()) {
567                                 _session->set_record_enabled (_route->route_group()->route_list(), !rec_enable_button->active_state(), Session::rt_cleanup, true);
568                         }
569
570                 } else if (Keyboard::is_context_menu_event (ev)) {
571
572                         /* do this on release */
573
574                 } else {
575
576                         boost::shared_ptr<RouteList> rl (new RouteList);
577                         rl->push_back (route());
578                         _session->set_record_enabled (rl, !rec_enable_button->active_state());
579                 }
580         }
581
582         return true;
583 }
584
585 void
586 RouteUI::monitoring_changed ()
587 {
588         update_monitoring_display ();
589 }
590
591 void
592 RouteUI::update_monitoring_display ()
593 {
594         if (!_route) {
595                 return;
596         }
597
598         boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_route);
599
600         if (!t) {
601                 return;
602         }
603
604         MonitorState ms = t->monitoring_state();
605
606         if (t->monitoring_choice() & MonitorInput) {
607                 monitor_input_button->set_active_state (Gtkmm2ext::Active);
608         } else {
609                 if (ms & MonitoringInput) {
610                         monitor_input_button->set_active_state (Gtkmm2ext::Mid);
611                 } else {
612                         monitor_input_button->unset_active_state ();
613                 }
614         }
615
616         if (t->monitoring_choice() & MonitorDisk) {
617                 monitor_disk_button->set_active_state (Gtkmm2ext::Active);
618         } else {
619                 if (ms & MonitoringDisk) {
620                         monitor_disk_button->set_active_state (Gtkmm2ext::Mid);
621                 } else {
622                         monitor_disk_button->unset_active_state ();
623                 }
624         }
625 }
626
627 bool
628 RouteUI::monitor_input_press(GdkEventButton* ev)
629 {
630         return true;
631 }
632
633 bool
634 RouteUI::monitor_input_release(GdkEventButton* ev)
635 {
636         return monitor_release (ev, MonitorInput);
637 }
638
639 bool
640 RouteUI::monitor_disk_press (GdkEventButton* ev)
641 {
642         return true;
643 }
644
645 bool
646 RouteUI::monitor_disk_release (GdkEventButton* ev)
647 {
648         return monitor_release (ev, MonitorDisk);
649 }
650
651 bool
652 RouteUI::monitor_release (GdkEventButton* ev, MonitorChoice monitor_choice)
653 {       
654         if (ev->button != 1) {
655                 return false;
656         }
657
658         boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_route);
659
660         if (!t) {
661                 return true;
662         }
663
664         MonitorChoice mc;
665         boost::shared_ptr<RouteList> rl;
666         
667         /* XXX for now, monitoring choices are orthogonal. cue monitoring 
668            will follow in 3.X but requires mixing the input and playback (disk)
669            signal together, which requires yet more buffers.
670         */
671
672         if (t->monitoring_choice() & monitor_choice) {
673                 mc = MonitorChoice (t->monitoring_choice() & ~monitor_choice);
674         } else {
675                 /* this line will change when the options are non-orthogonal */
676                 // mc = MonitorChoice (t->monitoring_choice() | monitor_choice);
677                 mc = monitor_choice;
678         }
679
680         if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {       
681                 rl = _session->get_routes ();
682
683         } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
684                 if (_route->route_group() && _route->route_group()->is_monitoring()) {
685                         rl = _route->route_group()->route_list();
686                 } else {
687                         rl.reset (new RouteList);
688                         rl->push_back (route());
689                 }
690         } else {
691                 rl.reset (new RouteList);
692                 rl->push_back (route());
693         }
694
695         _session->set_monitoring (rl, mc, Session::rt_cleanup, true);           
696
697         return true;
698 }
699
700 void
701 RouteUI::build_record_menu ()
702 {
703         if (record_menu) {
704                 return;
705         }
706
707         /* no rec-button context menu for non-MIDI tracks
708          */
709
710         if (is_midi_track()) {
711                 record_menu = new Menu;
712                 record_menu->set_name ("ArdourContextMenu");
713
714                 using namespace Menu_Helpers;
715                 MenuList& items = record_menu->items();
716
717                 items.push_back (CheckMenuElem (_("Step Entry"), sigc::mem_fun (*this, &RouteUI::toggle_step_edit)));
718                 step_edit_item = dynamic_cast<CheckMenuItem*> (&items.back());
719
720                 if (_route->record_enabled()) {
721                         step_edit_item->set_sensitive (false);
722                 }
723
724                 step_edit_item->set_active (midi_track()->step_editing());
725         }
726 }
727
728 void
729 RouteUI::toggle_step_edit ()
730 {
731         if (!is_midi_track() || _route->record_enabled()) {
732                 return;
733         }
734
735         midi_track()->set_step_editing (step_edit_item->get_active());
736 }
737
738 void
739 RouteUI::step_edit_changed (bool yn)
740 {
741         if (yn) {
742                 if (rec_enable_button) {
743                         rec_enable_button->set_active_state (Active);
744                 }
745
746                 start_step_editing ();
747
748                 if (step_edit_item) {
749                         step_edit_item->set_active (true);
750                 }
751
752         } else {
753
754                 if (rec_enable_button) {
755                         rec_enable_button->unset_active_state ();
756                 }
757
758                 stop_step_editing ();
759
760                 if (step_edit_item) {
761                         step_edit_item->set_active (false);
762                 }
763         }
764 }
765
766 bool
767 RouteUI::rec_enable_release (GdkEventButton* ev)
768 {
769         if (Keyboard::is_context_menu_event (ev)) {
770                 build_record_menu ();
771                 if (record_menu) {
772                         record_menu->popup (1, ev->time);
773                 }
774                 return true;
775         }
776
777         return true;
778 }
779
780 void
781 RouteUI::build_sends_menu ()
782 {
783         using namespace Menu_Helpers;
784
785         sends_menu = new Menu;
786         sends_menu->set_name ("ArdourContextMenu");
787         MenuList& items = sends_menu->items();
788
789         items.push_back (
790                 MenuElem(_("Assign all tracks (prefader)"), sigc::bind (sigc::mem_fun (*this, &RouteUI::create_sends), PreFader, false))
791                 );
792
793         items.push_back (
794                 MenuElem(_("Assign all tracks and buses (prefader)"), sigc::bind (sigc::mem_fun (*this, &RouteUI::create_sends), PreFader, true))
795                 );
796
797         items.push_back (
798                 MenuElem(_("Assign all tracks (postfader)"), sigc::bind (sigc::mem_fun (*this, &RouteUI::create_sends), PostFader, false))
799                 );
800
801         items.push_back (
802                 MenuElem(_("Assign all tracks and buses (postfader)"), sigc::bind (sigc::mem_fun (*this, &RouteUI::create_sends), PostFader, true))
803                 );
804
805         items.push_back (
806                 MenuElem(_("Assign selected tracks (prefader)"), sigc::bind (sigc::mem_fun (*this, &RouteUI::create_selected_sends), PreFader, false))
807                 );
808
809         items.push_back (
810                 MenuElem(_("Assign selected tracks and buses (prefader)"), sigc::bind (sigc::mem_fun (*this, &RouteUI::create_selected_sends), PreFader, true)));
811
812         items.push_back (
813                 MenuElem(_("Assign selected tracks (postfader)"), sigc::bind (sigc::mem_fun (*this, &RouteUI::create_selected_sends), PostFader, false))
814                 );
815
816         items.push_back (
817                 MenuElem(_("Assign selected tracks and buses (postfader)"), sigc::bind (sigc::mem_fun (*this, &RouteUI::create_selected_sends), PostFader, true))
818                 );
819
820         items.push_back (MenuElem(_("Copy track/bus gains to sends"), sigc::mem_fun (*this, &RouteUI::set_sends_gain_from_track)));
821         items.push_back (MenuElem(_("Set sends gain to -inf"), sigc::mem_fun (*this, &RouteUI::set_sends_gain_to_zero)));
822         items.push_back (MenuElem(_("Set sends gain to 0dB"), sigc::mem_fun (*this, &RouteUI::set_sends_gain_to_unity)));
823
824 }
825
826 void
827 RouteUI::create_sends (Placement p, bool include_buses)
828 {
829         _session->globally_add_internal_sends (_route, p, include_buses);
830 }
831
832 void
833 RouteUI::create_selected_sends (Placement p, bool include_buses)
834 {
835         boost::shared_ptr<RouteList> rlist (new RouteList);
836         TrackSelection& selected_tracks (ARDOUR_UI::instance()->the_editor().get_selection().tracks);
837
838         for (TrackSelection::iterator i = selected_tracks.begin(); i != selected_tracks.end(); ++i) {
839                 RouteTimeAxisView* rtv;
840                 RouteUI* rui;
841                 if ((rtv = dynamic_cast<RouteTimeAxisView*>(*i)) != 0) {
842                         if ((rui = dynamic_cast<RouteUI*>(rtv)) != 0) {
843                                 if (include_buses || boost::dynamic_pointer_cast<AudioTrack>(rui->route())) {
844                                         rlist->push_back (rui->route());
845                                 }
846                         }
847                 }
848         }
849
850         _session->add_internal_sends (_route, p, rlist);
851 }
852
853 void
854 RouteUI::set_sends_gain_from_track ()
855 {
856         _session->globally_set_send_gains_from_track (_route);
857 }
858
859 void
860 RouteUI::set_sends_gain_to_zero ()
861 {
862         _session->globally_set_send_gains_to_zero (_route);
863 }
864
865 void
866 RouteUI::set_sends_gain_to_unity ()
867 {
868         _session->globally_set_send_gains_to_unity (_route);
869 }
870
871 bool
872 RouteUI::show_sends_press(GdkEventButton* ev)
873 {
874         if (ev->type == GDK_2BUTTON_PRESS || ev->type == GDK_3BUTTON_PRESS ) {
875                 return true;
876         }
877
878         if (!_i_am_the_modifier && !is_track() && show_sends_button) {
879
880                 if (Keyboard::is_button2_event (ev) && Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
881
882                         // do nothing on midi sigc::bind event
883                         return false;
884
885                 } else if (Keyboard::is_context_menu_event (ev)) {
886
887                         if (sends_menu == 0) {
888                                 build_sends_menu ();
889                         }
890
891                         sends_menu->popup (0, ev->time);
892
893                 } else {
894
895                         boost::shared_ptr<Route> s = _showing_sends_to.lock ();
896
897                         if (s == _route) {
898                                 set_showing_sends_to (boost::shared_ptr<Route> ());
899                         } else {
900                                 set_showing_sends_to (_route);
901                         }
902                 }
903         }
904
905         return true;
906 }
907
908 bool
909 RouteUI::show_sends_release (GdkEventButton*)
910 {
911         return true;
912 }
913
914 void
915 RouteUI::send_blink (bool onoff)
916 {
917         if (!show_sends_button) {
918                 return;
919         }
920
921         if (onoff) {
922                 show_sends_button->set_active_state (Gtkmm2ext::Active);
923         } else {
924                 show_sends_button->unset_active_state ();
925         }
926 }
927
928 Gtkmm2ext::ActiveState
929 RouteUI::solo_active_state (boost::shared_ptr<Route> r)
930 {
931         if (r->is_master() || r->is_monitor()) {
932                 return ActiveState (0);
933         }
934
935         if (Config->get_solo_control_is_listen_control()) {
936
937                 if (r->listening_via_monitor()) {
938                         return Active;
939                 } else {
940                         return ActiveState (0);
941                 }
942
943         }
944
945         if (r->soloed()) {
946                 if (!r->self_soloed()) {
947                         return Mid;
948                 } else {
949                         return Active;
950                 }
951         } else {
952                 return ActiveState(0);
953         }
954 }
955
956 Gtkmm2ext::ActiveState
957 RouteUI::solo_isolate_active_state (boost::shared_ptr<Route> r)
958 {
959         if (r->is_master() || r->is_monitor()) {
960                 return ActiveState (0);
961         }
962
963         if (r->solo_isolated()) {
964                 return Active;
965         } else {
966                 return ActiveState(0);
967         }
968 }
969
970 Gtkmm2ext::ActiveState
971 RouteUI::solo_safe_active_state (boost::shared_ptr<Route> r)
972 {
973         if (r->is_master() || r->is_monitor()) {
974                 return ActiveState (0);
975         }
976
977         if (r->solo_safe()) {
978                 return Active;
979         } else {
980                 return ActiveState (0);
981         }
982 }
983
984 void
985 RouteUI::update_solo_display ()
986 {
987         bool x;
988
989         if (Config->get_solo_control_is_listen_control()) {
990
991                 if ((bool) solo_button->active_state() != (x = _route->listening_via_monitor())) {
992                         ++_i_am_the_modifier;
993                         solo_button->set_active_state (Active);
994                         --_i_am_the_modifier;
995                 }
996
997         } else {
998
999                 if ((bool) solo_button->active_state() != (x = _route->soloed())) {
1000                         ++_i_am_the_modifier;
1001                         if (x) {
1002                                 solo_button->set_active_state (Active);
1003                         } else {
1004                                 solo_button->unset_active_state();
1005                         }
1006                         --_i_am_the_modifier;
1007                 }
1008
1009         }
1010
1011         bool yn = _route->solo_safe ();
1012
1013         if (solo_safe_check && solo_safe_check->get_active() != yn) {
1014                 solo_safe_check->set_active (yn);
1015         }
1016
1017         yn = _route->solo_isolated ();
1018
1019         if (solo_isolated_check && solo_isolated_check->get_active() != yn) {
1020                 solo_isolated_check->set_active (yn);
1021         }
1022
1023         set_button_names ();
1024
1025         if (solo_isolated_led) {
1026                 if (_route->solo_isolated()) {
1027                         solo_isolated_led->set_active_state (Gtkmm2ext::Active);
1028                 } else {
1029                         solo_isolated_led->unset_active_state ();
1030                 }
1031         }
1032
1033         if (solo_safe_led) {
1034                 if (_route->solo_safe()) {
1035                         solo_safe_led->set_active_state (Gtkmm2ext::Active);
1036                 } else {
1037                         solo_safe_led->unset_active_state ();
1038                 }
1039         }
1040
1041         solo_button->set_active_state (solo_active_state (_route));
1042
1043         /* some changes to solo status can affect mute display, so catch up
1044          */
1045
1046         update_mute_display ();
1047 }
1048
1049 void
1050 RouteUI::solo_changed_so_update_mute ()
1051 {
1052         update_mute_display ();
1053 }
1054
1055 void
1056 RouteUI::mute_changed(void* /*src*/)
1057 {
1058         update_mute_display ();
1059 }
1060
1061 ActiveState
1062 RouteUI::mute_active_state (Session* s, boost::shared_ptr<Route> r)
1063 {
1064         if (r->is_monitor()) {
1065                 return ActiveState(0);
1066         }
1067
1068
1069         if (Config->get_show_solo_mutes() && !Config->get_solo_control_is_listen_control ()) {
1070
1071                 if (r->muted ()) {
1072                         /* full mute */
1073                         return Active;
1074                 } else if (!r->is_master() && s->soloing() && !r->soloed() && !r->solo_isolated()) {
1075                         /* master is NEVER muted by others */
1076                         return Mid;
1077                 } else {
1078                         /* no mute at all */
1079                         return ActiveState(0);
1080                 }
1081
1082         } else {
1083
1084                 if (r->muted()) {
1085                         /* full mute */
1086                         return Active;
1087                 } else {
1088                         /* no mute at all */
1089                         return ActiveState(0);
1090                 }
1091         }
1092
1093         return ActiveState(0);
1094 }
1095
1096 void
1097 RouteUI::update_mute_display ()
1098 {
1099         if (!_route) {
1100                 return;
1101         }
1102
1103         mute_button->set_active_state (mute_active_state (_session, _route));
1104 }
1105
1106 void
1107 RouteUI::route_rec_enable_changed ()
1108 {
1109         update_rec_display ();
1110         update_monitoring_display ();
1111 }
1112
1113 void
1114 RouteUI::session_rec_enable_changed ()
1115 {
1116         update_rec_display ();
1117         update_monitoring_display ();
1118 }
1119
1120 void
1121 RouteUI::update_rec_display ()
1122 {
1123         if (!rec_enable_button || !_route) {
1124                 return;
1125         }
1126
1127         if (_route->record_enabled()) {
1128                 switch (_session->record_status ()) {
1129                 case Session::Recording:
1130                         rec_enable_button->set_active_state (Active);
1131                         break;
1132
1133                 case Session::Disabled:
1134                 case Session::Enabled:
1135                         rec_enable_button->set_active_state (Mid);
1136                         break;
1137
1138                 }
1139
1140                 if (step_edit_item) {
1141                         step_edit_item->set_sensitive (false);
1142                 }
1143
1144         } else {
1145                 rec_enable_button->unset_active_state ();
1146
1147                 if (step_edit_item) {
1148                         step_edit_item->set_sensitive (true);
1149                 }
1150         }
1151
1152
1153         check_rec_enable_sensitivity ();
1154 }
1155
1156 void
1157 RouteUI::build_solo_menu (void)
1158 {
1159         using namespace Menu_Helpers;
1160
1161         solo_menu = new Menu;
1162         solo_menu->set_name ("ArdourContextMenu");
1163         MenuList& items = solo_menu->items();
1164         CheckMenuItem* check;
1165
1166         check = new CheckMenuItem(_("Solo Isolate"));
1167         check->set_active (_route->solo_isolated());
1168         check->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_solo_isolated), check));
1169         items.push_back (CheckMenuElem(*check));
1170         solo_isolated_check = dynamic_cast<CheckMenuItem*>(&items.back());
1171         check->show_all();
1172
1173         check = new CheckMenuItem(_("Solo Safe"));
1174         check->set_active (_route->solo_safe());
1175         check->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_solo_safe), check));
1176         items.push_back (CheckMenuElem(*check));
1177         solo_safe_check = dynamic_cast<CheckMenuItem*>(&items.back());
1178         check->show_all();
1179
1180         //items.push_back (SeparatorElem());
1181         // items.push_back (MenuElem (_("MIDI Bind"), sigc::mem_fun (*mute_button, &BindableToggleButton::midi_learn)));
1182
1183 }
1184
1185 void
1186 RouteUI::build_mute_menu(void)
1187 {
1188         using namespace Menu_Helpers;
1189
1190         mute_menu = new Menu;
1191         mute_menu->set_name ("ArdourContextMenu");
1192
1193         MenuList& items = mute_menu->items();
1194
1195         pre_fader_mute_check = manage (new CheckMenuItem(_("Pre Fader")));
1196         init_mute_menu(MuteMaster::PreFader, pre_fader_mute_check);
1197         pre_fader_mute_check->signal_toggled().connect(sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_mute_menu), MuteMaster::PreFader, pre_fader_mute_check));
1198         items.push_back (CheckMenuElem(*pre_fader_mute_check));
1199         pre_fader_mute_check->show_all();
1200
1201         post_fader_mute_check = manage (new CheckMenuItem(_("Post Fader")));
1202         init_mute_menu(MuteMaster::PostFader, post_fader_mute_check);
1203         post_fader_mute_check->signal_toggled().connect(sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_mute_menu), MuteMaster::PostFader, post_fader_mute_check));
1204         items.push_back (CheckMenuElem(*post_fader_mute_check));
1205         post_fader_mute_check->show_all();
1206
1207         listen_mute_check = manage (new CheckMenuItem(_("Control Outs")));
1208         init_mute_menu(MuteMaster::Listen, listen_mute_check);
1209         listen_mute_check->signal_toggled().connect(sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_mute_menu), MuteMaster::Listen, listen_mute_check));
1210         items.push_back (CheckMenuElem(*listen_mute_check));
1211         listen_mute_check->show_all();
1212
1213         main_mute_check = manage (new CheckMenuItem(_("Main Outs")));
1214         init_mute_menu(MuteMaster::Main, main_mute_check);
1215         main_mute_check->signal_toggled().connect(sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_mute_menu), MuteMaster::Main, main_mute_check));
1216         items.push_back (CheckMenuElem(*main_mute_check));
1217         main_mute_check->show_all();
1218
1219         //items.push_back (SeparatorElem());
1220         // items.push_back (MenuElem (_("MIDI Bind"), sigc::mem_fun (*mute_button, &BindableToggleButton::midi_learn)));
1221
1222         _route->mute_points_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::muting_change, this), gui_context());
1223 }
1224
1225 void
1226 RouteUI::init_mute_menu(MuteMaster::MutePoint mp, CheckMenuItem* check)
1227 {
1228         check->set_active (_route->mute_points() & mp);
1229 }
1230
1231 void
1232 RouteUI::toggle_mute_menu(MuteMaster::MutePoint mp, Gtk::CheckMenuItem* check)
1233 {
1234         if (check->get_active()) {
1235                 _route->set_mute_points (MuteMaster::MutePoint (_route->mute_points() | mp));
1236         } else {
1237                 _route->set_mute_points (MuteMaster::MutePoint (_route->mute_points() & ~mp));
1238         }
1239 }
1240
1241 void
1242 RouteUI::muting_change ()
1243 {
1244         ENSURE_GUI_THREAD (*this, &RouteUI::muting_change)
1245
1246         bool yn;
1247         MuteMaster::MutePoint current = _route->mute_points ();
1248
1249         yn = (current & MuteMaster::PreFader);
1250
1251         if (pre_fader_mute_check->get_active() != yn) {
1252                 pre_fader_mute_check->set_active (yn);
1253         }
1254
1255         yn = (current & MuteMaster::PostFader);
1256
1257         if (post_fader_mute_check->get_active() != yn) {
1258                 post_fader_mute_check->set_active (yn);
1259         }
1260
1261         yn = (current & MuteMaster::Listen);
1262
1263         if (listen_mute_check->get_active() != yn) {
1264                 listen_mute_check->set_active (yn);
1265         }
1266
1267         yn = (current & MuteMaster::Main);
1268
1269         if (main_mute_check->get_active() != yn) {
1270                 main_mute_check->set_active (yn);
1271         }
1272 }
1273
1274 bool
1275 RouteUI::solo_isolate_button_release (GdkEventButton* ev)
1276 {
1277         if (ev->type == GDK_2BUTTON_PRESS || ev->type == GDK_3BUTTON_PRESS) {
1278                 return true;
1279         }
1280
1281         bool view = solo_isolated_led->active_state();
1282         bool model = _route->solo_isolated();
1283
1284         /* called BEFORE the view has changed */
1285
1286         if (ev->button == 1) {
1287                 if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
1288
1289                         if (model) {
1290                                 /* disable isolate for all routes */
1291                                 _session->set_solo_isolated (_session->get_routes(), false, Session::rt_cleanup, true);
1292                         }
1293
1294                 } else {
1295                         if (model == view) {
1296
1297                                 /* flip just this route */
1298
1299                                 boost::shared_ptr<RouteList> rl (new RouteList);
1300                                 rl->push_back (_route);
1301                                 _session->set_solo_isolated (rl, !view, Session::rt_cleanup, true);
1302                         }
1303                 }
1304         }
1305
1306         return true;
1307 }
1308
1309 bool
1310 RouteUI::solo_safe_button_release (GdkEventButton*)
1311 {
1312         _route->set_solo_safe (!solo_safe_led->active_state(), this);
1313         return true;
1314 }
1315
1316 void
1317 RouteUI::toggle_solo_isolated (Gtk::CheckMenuItem* check)
1318 {
1319         bool view = check->get_active();
1320         bool model = _route->solo_isolated();
1321
1322         /* called AFTER the view has changed */
1323
1324         if (model != view) {
1325                 _route->set_solo_isolated (view, this);
1326         }
1327 }
1328
1329 void
1330 RouteUI::toggle_solo_safe (Gtk::CheckMenuItem* check)
1331 {
1332         _route->set_solo_safe (check->get_active(), this);
1333 }
1334
1335 /** Ask the user to choose a colour, and then set all selected tracks
1336  *  to that colour.
1337  */
1338 void
1339 RouteUI::choose_color ()
1340 {
1341         bool picked;
1342         Gdk::Color const color = Gtkmm2ext::UI::instance()->get_color (_("Color Selection"), picked, &_color);
1343
1344         if (picked) {
1345                 ARDOUR_UI::instance()->the_editor().get_selection().tracks.foreach_route_ui (
1346                         boost::bind (&RouteUI::set_color, _1, color)
1347                         );
1348         }
1349 }
1350
1351 /** Set the route's own color.  This may not be used for display if
1352  *  the route is in a group which shares its color with its routes.
1353  */
1354 void
1355 RouteUI::set_color (const Gdk::Color & c)
1356 {
1357         char buf[64];
1358
1359         _color = c;
1360
1361         snprintf (buf, sizeof (buf), "%d:%d:%d", c.get_red(), c.get_green(), c.get_blue());
1362
1363         /* note: we use the route state ID here so that color is the same for both
1364            the time axis view and the mixer strip
1365         */
1366         
1367         gui_object_state().set<string> (route_state_id(), X_("color"), buf);
1368         _route->gui_changed ("color", (void *) 0); /* EMIT_SIGNAL */
1369 }
1370
1371 /** @return GUI state ID for things that are common to the route in all its representations */
1372 string
1373 RouteUI::route_state_id () const
1374 {
1375         return string_compose (X_("route %1"), _route->id().to_s());
1376 }
1377
1378 int
1379 RouteUI::set_color_from_route ()
1380 {
1381         const string str = gui_object_state().get_string (route_state_id(), X_("color"));
1382
1383         if (str.empty()) {
1384                 return 1;
1385         }
1386
1387         int r, g, b;
1388
1389         sscanf (str.c_str(), "%d:%d:%d", &r, &g, &b);
1390
1391         _color.set_red (r);
1392         _color.set_green (g);
1393         _color.set_blue (b);
1394
1395         return 0;
1396 }
1397
1398 void
1399 RouteUI::remove_this_route (bool apply_to_selection)
1400 {
1401         if (apply_to_selection) {
1402                 ARDOUR_UI::instance()->the_editor().get_selection().tracks.foreach_route_ui (boost::bind (&RouteUI::remove_this_route, _1, false));
1403         } else {
1404                 if ((route()->is_master() || route()->is_monitor()) &&
1405                     !Config->get_allow_special_bus_removal()) {
1406                         MessageDialog msg (_("That would be bad news ...."),
1407                                            false,
1408                                            Gtk::MESSAGE_INFO,
1409                                    Gtk::BUTTONS_OK);
1410                         msg.set_secondary_text (string_compose (_(
1411 "Removing the master or monitor bus is such a bad idea\n\
1412 that %1 is not going to allow it.\n\
1413 \n\
1414 If you really want to do this sort of thing\n\
1415 edit your ardour.rc file to set the\n\
1416 \"allow-special-bus-removal\" option to be \"yes\""), PROGRAM_NAME));
1417
1418                         msg.present ();
1419                         msg.run ();
1420                         return;
1421                 }
1422
1423                 vector<string> choices;
1424                 string prompt;
1425
1426                 if (is_track()) {
1427                         prompt  = string_compose (_("Do you really want to remove track \"%1\" ?\n\nYou may also lose the playlist used by this track.\n\n(This action cannot be undone, and the session file will be overwritten)"), _route->name());
1428                 } else {
1429                         prompt  = string_compose (_("Do you really want to remove bus \"%1\" ?\n\n(This action cannot be undone, and the session file will be overwritten)"), _route->name());
1430                 }
1431
1432                 choices.push_back (_("No, do nothing."));
1433                 choices.push_back (_("Yes, remove it."));
1434
1435                 string title;
1436                 if (is_track()) {
1437                         title = _("Remove track");
1438                 } else {
1439                         title = _("Remove bus");
1440                 }
1441
1442                 Choice prompter (title, prompt, choices);
1443
1444                 if (prompter.run () == 1) {
1445                         Glib::signal_idle().connect (sigc::bind (sigc::ptr_fun (&RouteUI::idle_remove_this_route), this));
1446                 }
1447         }
1448 }
1449
1450 gint
1451 RouteUI::idle_remove_this_route (RouteUI *rui)
1452 {
1453         rui->_session->remove_route (rui->route());
1454         return false;
1455 }
1456
1457 /** @return true if this name should be used for the route, otherwise false */
1458 bool
1459 RouteUI::verify_new_route_name (const std::string& name)
1460 {
1461         if (name.find (':') == string::npos) {
1462                 return true;
1463         }
1464         
1465         MessageDialog colon_msg (
1466                 _("The use of colons (':') is discouraged in track and bus names.\nDo you want to use this new name?"),
1467                 false, MESSAGE_QUESTION, BUTTONS_NONE
1468                 );
1469         
1470         colon_msg.add_button (_("Use the new name"), Gtk::RESPONSE_ACCEPT);
1471         colon_msg.add_button (_("Re-edit the name"), Gtk::RESPONSE_CANCEL);
1472
1473         return (colon_msg.run () == Gtk::RESPONSE_ACCEPT);
1474 }
1475
1476 void
1477 RouteUI::route_rename ()
1478 {
1479         ArdourPrompter name_prompter (true);
1480         string result;
1481         bool done = false;
1482
1483         if (is_track()) {
1484                 name_prompter.set_title (_("Rename Track"));
1485         } else {
1486                 name_prompter.set_title (_("Rename Bus"));
1487         }
1488         name_prompter.set_prompt (_("New name:"));
1489         name_prompter.set_initial_text (_route->name());
1490         name_prompter.add_button (_("Rename"), Gtk::RESPONSE_ACCEPT);
1491         name_prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
1492         name_prompter.show_all ();
1493
1494         while (!done) {
1495                 switch (name_prompter.run ()) {
1496                 case Gtk::RESPONSE_ACCEPT:
1497                         name_prompter.get_result (result);
1498                         name_prompter.hide ();
1499                         if (result.length()) {
1500                                 if (verify_new_route_name (result)) {
1501                                         _route->set_name (result);
1502                                         done = true;
1503                                 } else {
1504                                         /* back to name prompter */
1505                                 }
1506
1507                         } else {
1508                                 /* nothing entered, just get out of here */
1509                                 done = true;
1510                         }
1511                         break;
1512                 }
1513         }
1514
1515         return;
1516
1517 }
1518
1519 void
1520 RouteUI::property_changed (const PropertyChange& what_changed)
1521 {
1522         if (what_changed.contains (ARDOUR::Properties::name)) {
1523                 name_label.set_text (_route->name());
1524         }
1525 }
1526
1527 void
1528 RouteUI::set_route_active (bool a, bool apply_to_selection)
1529 {
1530         if (apply_to_selection) {
1531                 ARDOUR_UI::instance()->the_editor().get_selection().tracks.foreach_route_ui (boost::bind (&RouteTimeAxisView::set_route_active, _1, a, false));
1532         } else {
1533                 _route->set_active (a, this);
1534         }
1535 }
1536
1537 void
1538 RouteUI::toggle_denormal_protection ()
1539 {
1540         if (denormal_menu_item) {
1541
1542                 bool x;
1543
1544                 ENSURE_GUI_THREAD (*this, &RouteUI::toggle_denormal_protection)
1545
1546                 if ((x = denormal_menu_item->get_active()) != _route->denormal_protection()) {
1547                         _route->set_denormal_protection (x);
1548                 }
1549         }
1550 }
1551
1552 void
1553 RouteUI::denormal_protection_changed ()
1554 {
1555         if (denormal_menu_item) {
1556                 denormal_menu_item->set_active (_route->denormal_protection());
1557         }
1558 }
1559
1560 void
1561 RouteUI::disconnect_input ()
1562 {
1563         _route->input()->disconnect (this);
1564 }
1565
1566 void
1567 RouteUI::disconnect_output ()
1568 {
1569         _route->output()->disconnect (this);
1570 }
1571
1572 bool
1573 RouteUI::is_track () const
1574 {
1575         return boost::dynamic_pointer_cast<Track>(_route) != 0;
1576 }
1577
1578 boost::shared_ptr<Track>
1579 RouteUI::track() const
1580 {
1581         return boost::dynamic_pointer_cast<Track>(_route);
1582 }
1583
1584 bool
1585 RouteUI::is_audio_track () const
1586 {
1587         return boost::dynamic_pointer_cast<AudioTrack>(_route) != 0;
1588 }
1589
1590 boost::shared_ptr<AudioTrack>
1591 RouteUI::audio_track() const
1592 {
1593         return boost::dynamic_pointer_cast<AudioTrack>(_route);
1594 }
1595
1596 bool
1597 RouteUI::is_midi_track () const
1598 {
1599         return boost::dynamic_pointer_cast<MidiTrack>(_route) != 0;
1600 }
1601
1602 boost::shared_ptr<MidiTrack>
1603 RouteUI::midi_track() const
1604 {
1605         return boost::dynamic_pointer_cast<MidiTrack>(_route);
1606 }
1607
1608 bool
1609 RouteUI::has_audio_outputs () const
1610 {
1611         return (_route->n_outputs().n_audio() > 0);
1612 }
1613
1614 string
1615 RouteUI::name() const
1616 {
1617         return _route->name();
1618 }
1619
1620 void
1621 RouteUI::map_frozen ()
1622 {
1623         ENSURE_GUI_THREAD (*this, &RouteUI::map_frozen)
1624
1625         AudioTrack* at = dynamic_cast<AudioTrack*>(_route.get());
1626
1627         if (at) {
1628                 switch (at->freeze_state()) {
1629                 case AudioTrack::Frozen:
1630                         rec_enable_button->set_sensitive (false);
1631                         break;
1632                 default:
1633                         rec_enable_button->set_sensitive (true);
1634                         break;
1635                 }
1636         }
1637 }
1638
1639 void
1640 RouteUI::adjust_latency ()
1641 {
1642         LatencyDialog dialog (_route->name() + _(" latency"), *(_route->output()), _session->frame_rate(), _session->engine().frames_per_cycle());
1643 }
1644
1645 void
1646 RouteUI::save_as_template ()
1647 {
1648         sys::path path;
1649         std::string safe_name;
1650         string name;
1651
1652         path = ARDOUR::user_route_template_directory ();
1653
1654         if (g_mkdir_with_parents (path.to_string().c_str(), 0755)) {
1655                 error << string_compose (_("Cannot create route template directory %1"), path.to_string()) << endmsg;
1656                 return;
1657         }
1658
1659         Prompter p (true); // modal
1660
1661         p.set_title (_("Save As Template"));
1662         p.set_prompt (_("Template name:"));
1663         p.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1664         switch (p.run()) {
1665         case RESPONSE_ACCEPT:
1666                 break;
1667         default:
1668                 return;
1669         }
1670
1671         p.hide ();
1672         p.get_result (name, true);
1673
1674         safe_name = legalize_for_path (name);
1675         safe_name += template_suffix;
1676
1677         path /= safe_name;
1678
1679         _route->save_as_template (path.to_string(), name);
1680 }
1681
1682 void
1683 RouteUI::check_rec_enable_sensitivity ()
1684 {
1685         if (_session->transport_rolling() && rec_enable_button->active_state() && Config->get_disable_disarm_during_roll()) {
1686                 rec_enable_button->set_sensitive (false);
1687         } else {
1688                 rec_enable_button->set_sensitive (true);
1689         }
1690
1691         update_monitoring_display ();
1692 }
1693
1694 void
1695 RouteUI::parameter_changed (string const & p)
1696 {
1697         /* this handles RC and per-session parameter changes */
1698
1699         if (p == "disable-disarm-during-roll") {
1700                 check_rec_enable_sensitivity ();
1701         } else if (p == "use-monitor-bus" || p == "solo-control-is-listen-control" || p == "listen-position") {
1702                 set_button_names ();
1703         } else if (p == "auto-input") {
1704                 update_monitoring_display ();
1705         }
1706 }
1707
1708 void
1709 RouteUI::step_gain_up ()
1710 {
1711         _route->set_gain (dB_to_coefficient (accurate_coefficient_to_dB (_route->gain_control()->get_value()) + 0.1), this);
1712 }
1713
1714 void
1715 RouteUI::page_gain_up ()
1716 {
1717         _route->set_gain (dB_to_coefficient (accurate_coefficient_to_dB (_route->gain_control()->get_value()) + 0.5), this);
1718 }
1719
1720 void
1721 RouteUI::step_gain_down ()
1722 {
1723         _route->set_gain (dB_to_coefficient (accurate_coefficient_to_dB (_route->gain_control()->get_value()) - 0.1), this);
1724 }
1725
1726 void
1727 RouteUI::page_gain_down ()
1728 {
1729         _route->set_gain (dB_to_coefficient (accurate_coefficient_to_dB (_route->gain_control()->get_value()) - 0.5), this);
1730 }
1731
1732 void
1733 RouteUI::open_remote_control_id_dialog ()
1734 {
1735         ArdourDialog dialog (_("Remote Control ID"));
1736
1737         uint32_t const limit = _session->ntracks() + _session->nbusses () + 4;
1738
1739         HBox* hbox = manage (new HBox);
1740         hbox->set_spacing (6);
1741         hbox->pack_start (*manage (new Label (_("Remote control ID:"))));
1742         SpinButton* spin = manage (new SpinButton);
1743         spin->set_digits (0);
1744         spin->set_increments (1, 10);
1745         spin->set_range (0, limit);
1746         spin->set_value (_route->remote_control_id());
1747         hbox->pack_start (*spin);
1748         dialog.get_vbox()->pack_start (*hbox);
1749
1750         dialog.add_button (Stock::CANCEL, RESPONSE_CANCEL);
1751         dialog.add_button (Stock::APPLY, RESPONSE_ACCEPT);
1752
1753         dialog.show_all ();
1754         int const r = dialog.run ();
1755
1756         if (r == RESPONSE_ACCEPT) {
1757                 _route->set_remote_control_id (spin->get_value_as_int ());
1758         }
1759 }
1760
1761 void
1762 RouteUI::setup_invert_buttons ()
1763 {
1764         /* remove old invert buttons */
1765         for (list<BindableToggleButton*>::iterator i = _invert_buttons.begin(); i != _invert_buttons.end(); ++i) {
1766                 _invert_button_box.remove (**i);
1767         }
1768
1769         _invert_buttons.clear ();
1770
1771         if (!_route || !_route->input()) {
1772                 return;
1773         }
1774
1775         uint32_t const N = _route->input()->n_ports().n_audio ();
1776
1777         uint32_t const to_add = (N <= _max_invert_buttons) ? N : 1;
1778
1779         for (uint32_t i = 0; i < to_add; ++i) {
1780                 BindableToggleButton* b = manage (new BindableToggleButton);
1781                 b->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &RouteUI::invert_toggled), i, b));
1782                 b->signal_button_press_event().connect (sigc::mem_fun (*this, &RouteUI::invert_press));
1783
1784                 b->set_name (X_("MixerInvertButton"));
1785                 if (to_add == 1) {
1786                         b->add (*manage (new Label (X_("Ø"))));
1787                 } else {
1788                         b->add (*manage (new Label (string_compose (X_("Ø%1"), i + 1))));
1789                 }
1790
1791                 if (N <= 4) {
1792                         UI::instance()->set_tip (*b, string_compose (_("Left-click to invert (phase reverse) channel %1 of this track.  Right-click to show menu."), i + 1));
1793                 } else {
1794                         UI::instance()->set_tip (*b, string_compose (_("Left-click to invert (phase reverse) all channels of this track.  Right-click to show menu."), i + 1));
1795                 }
1796
1797                 _invert_buttons.push_back (b);
1798                 _invert_button_box.pack_start (*b);
1799         }
1800
1801         _invert_button_box.show_all ();
1802 }
1803
1804 void
1805 RouteUI::set_invert_button_state ()
1806 {
1807         ++_i_am_the_modifier;
1808
1809         uint32_t const N = _route->input()->n_ports().n_audio();
1810         if (N > _max_invert_buttons) {
1811                 _invert_buttons.front()->set_active (_route->phase_invert().any());
1812                 --_i_am_the_modifier;
1813                 return;
1814         }
1815
1816         int j = 0;
1817         for (list<BindableToggleButton*>::iterator i = _invert_buttons.begin(); i != _invert_buttons.end(); ++i, ++j) {
1818                 (*i)->set_active (_route->phase_invert (j));
1819         }
1820
1821         --_i_am_the_modifier;
1822 }
1823
1824 void
1825 RouteUI::invert_toggled (uint32_t i, BindableToggleButton* b)
1826 {
1827         if (_i_am_the_modifier) {
1828                 return;
1829         }
1830
1831         uint32_t const N = _route->input()->n_ports().n_audio();
1832         if (N <= _max_invert_buttons) {
1833                 _route->set_phase_invert (i, b->get_active ());
1834         } else {
1835                 boost::dynamic_bitset<> p (N);
1836                 if (b->get_active ()) {
1837                         p.set ();
1838                 }
1839                 _route->set_phase_invert (p);
1840         }
1841 }
1842
1843 bool
1844 RouteUI::invert_press (GdkEventButton* ev)
1845 {
1846         using namespace Menu_Helpers;
1847
1848         if (ev->button != 3) {
1849                 return true;
1850         }
1851
1852         delete _invert_menu;
1853         _invert_menu = new Menu;
1854         _invert_menu->set_name ("ArdourContextMenu");
1855         MenuList& items = _invert_menu->items ();
1856
1857         uint32_t const N = _route->input()->n_ports().n_audio();
1858         for (uint32_t i = 0; i < N; ++i) {
1859                 items.push_back (CheckMenuElem (string_compose (X_("Ø%1"), i + 1), sigc::bind (sigc::mem_fun (*this, &RouteUI::invert_menu_toggled), i)));
1860                 CheckMenuItem* e = dynamic_cast<CheckMenuItem*> (&items.back ());
1861                 ++_i_am_the_modifier;
1862                 e->set_active (_route->phase_invert (i));
1863                 --_i_am_the_modifier;
1864         }
1865
1866         _invert_menu->popup (0, ev->time);
1867
1868         return false;
1869 }
1870
1871 void
1872 RouteUI::invert_menu_toggled (uint32_t c)
1873 {
1874         if (_i_am_the_modifier) {
1875                 return;
1876         }
1877
1878         _route->set_phase_invert (c, !_route->phase_invert (c));
1879 }
1880
1881 void
1882 RouteUI::set_invert_sensitive (bool yn)
1883 {
1884         for (list<BindableToggleButton*>::iterator b = _invert_buttons.begin(); b != _invert_buttons.end(); ++b) {
1885                 (*b)->set_sensitive (yn);
1886         }
1887 }
1888
1889 void
1890 RouteUI::request_redraw ()
1891 {
1892         if (_route) {
1893                 _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
1894         }
1895 }
1896
1897 /** The Route's gui_changed signal has been emitted */
1898 void
1899 RouteUI::route_gui_changed (string what_changed)
1900 {
1901         if (what_changed == "color") {
1902                 if (set_color_from_route () == 0) {
1903                         route_color_changed ();
1904                 }
1905         }
1906 }
1907
1908 /** @return the color that this route should use; it maybe its own,
1909     or it maybe that of its route group.
1910 */
1911 Gdk::Color
1912 RouteUI::color () const
1913 {
1914         RouteGroup* g = _route->route_group ();
1915         
1916         if (g && g->is_color()) {
1917                 return GroupTabs::group_color (g);
1918         }
1919
1920         return _color;
1921 }
1922
1923 void
1924 RouteUI::set_showing_sends_to (boost::shared_ptr<Route> send_to)
1925 {
1926         _showing_sends_to = send_to;
1927         BusSendDisplayChanged (send_to); /* EMIT SIGNAL */
1928 }
1929
1930 void
1931 RouteUI::bus_send_display_changed (boost::shared_ptr<Route> send_to)
1932 {
1933         if (_route == send_to) {
1934                 show_sends_button->set_active_state (Gtkmm2ext::Active);
1935                 send_blink_connection = ARDOUR_UI::instance()->Blink.connect (sigc::mem_fun (*this, &RouteUI::send_blink));
1936         } else {
1937                 show_sends_button->unset_active_state ();
1938                 send_blink_connection.disconnect ();
1939         }
1940 }
1941
1942 RouteGroup*
1943 RouteUI::route_group() const
1944 {
1945         return _route->route_group();
1946 }