Don't report an error when the user cancels a time stretch operation.
[ardour.git] / gtk2_ardour / route_ui.cc
index f5bf2f9208051656706b964606450da0bdda9694..ae36ccba86c30179f7a6b34975a0e33832cd39e9 100644 (file)
@@ -50,9 +50,7 @@
 #include "ardour/session.h"
 #include "ardour/audioengine.h"
 #include "ardour/audio_track.h"
-#include "ardour/audio_diskstream.h"
 #include "ardour/midi_track.h"
-#include "ardour/midi_diskstream.h"
 #include "ardour/template_utils.h"
 #include "ardour/filename_extensions.h"
 #include "ardour/directory_names.h"
@@ -99,15 +97,23 @@ RouteUI::init ()
        post_fader_mute_check = 0;
        listen_mute_check = 0;
        main_mute_check = 0;
+        solo_safe_check = 0;
+        solo_isolated_check = 0;
        ignore_toggle = false;
        _solo_release = 0;
        _mute_release = 0;
        route_active_menu_item = 0;
-       polarity_menu_item = 0;
        denormal_menu_item = 0;
        multiple_mute_change = false;
        multiple_solo_change = false;
 
+       invert_button = manage (new BindableToggleButton ());
+       // mute_button->set_self_managed (true);
+       invert_button->set_name ("InvertButton");
+       invert_button->add (invert_button_label);
+       invert_button_label.show ();
+       UI::instance()->set_tip (invert_button, _("Invert (Phase reverse) this track"), "");
+
        mute_button = manage (new BindableToggleButton ());
        // mute_button->set_self_managed (true);
        mute_button->set_name ("MuteButton");
@@ -151,6 +157,8 @@ RouteUI::init ()
        solo_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::solo_release), false);
        mute_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::mute_press), false);
        mute_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::mute_release), false);
+       invert_button->signal_toggled().connect (sigc::mem_fun(*this, &RouteUI::invert_toggled), false);
+
 }
 
 void
@@ -170,7 +178,6 @@ RouteUI::reset ()
        }
 
        route_active_menu_item = 0;
-       polarity_menu_item = 0;
        denormal_menu_item = 0;
 }
 
@@ -202,15 +209,19 @@ RouteUI::set_route (boost::shared_ptr<Route> rp)
 
        _route->active_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::route_active_changed, this), gui_context());
        _route->mute_changed.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::mute_changed, this, _1), gui_context());
-       _route->solo_changed.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::solo_changed, this, _1), gui_context());
-       _route->listen_changed.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::listen_changed, this, _1), gui_context());
-       _route->solo_isolated_changed.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::solo_changed, this, _1), gui_context());
+
+       _route->solo_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context());
+       _route->solo_safe_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context());
+       _route->listen_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context());
+       _route->solo_isolated_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context());
+
+        _route->phase_invert_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::polarity_changed, this), gui_context());
        _route->PropertyChanged.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::property_changed, this, _1), gui_context());
 
        if (_session->writable() && is_track()) {
                boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_route);
 
-               t->diskstream()->RecordEnableChanged.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::route_rec_enable_changed, this), gui_context());
+               t->RecordEnableChanged.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::route_rec_enable_changed, this), gui_context());
 
                rec_enable_button->show();
                rec_enable_button->set_controllable (t->rec_enable_control());
@@ -222,6 +233,7 @@ RouteUI::set_route (boost::shared_ptr<Route> rp)
        solo_button->unset_flags (Gtk::CAN_FOCUS);
 
        mute_button->show();
+        invert_button->show ();
 
        if (_route->is_monitor()) {
                solo_button->hide ();
@@ -229,12 +241,28 @@ RouteUI::set_route (boost::shared_ptr<Route> rp)
                solo_button->show();
        }
 
-       /* map the current state */
+       map_frozen ();
+}
 
-       mute_changed (0);
-       solo_changed (0);
+void
+RouteUI::invert_toggled ()
+{
+        cerr << this << " button state = " << invert_button->get_active() << " PI = " << _route->phase_invert() << endl;
+        _route->set_phase_invert (invert_button->get_active());
+}
 
-       map_frozen ();
+void
+RouteUI::polarity_changed ()
+{
+        if (!_route) {
+                return;
+        }
+        
+       if (_route->phase_invert()) {
+                invert_button->set_active (true);
+       } else {
+                invert_button->set_active (false);
+       }
 }
 
 bool
@@ -267,7 +295,7 @@ RouteUI::mute_press (GdkEventButton* ev)
                                         return true;
                                 }
 
-                               _mute_release = new SoloMuteRelease (_route->muted ());
+                               _mute_release = new SoloMuteRelease (_route->self_muted ());
                        }
 
                        if (ev->button == 1 || Keyboard::is_button2_event (ev)) {
@@ -278,7 +306,7 @@ RouteUI::mute_press (GdkEventButton* ev)
                                                _mute_release->routes = _session->get_routes ();
                                        }
 
-                                       _session->set_mute (_session->get_routes(), !_route->muted());
+                                       _session->set_mute (_session->get_routes(), !_route->self_muted());
 
                                } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
 
@@ -291,7 +319,7 @@ RouteUI::mute_press (GdkEventButton* ev)
                                                        _mute_release->routes = _session->get_routes ();
                                                }
                                                                
-                                               _session->set_mute (_session->get_routes(), !_route->muted(), Session::rt_cleanup, true);
+                                               _session->set_mute (_session->get_routes(), !_route->self_muted(), Session::rt_cleanup, true);
                                        }
 
                                } else {
@@ -305,7 +333,7 @@ RouteUI::mute_press (GdkEventButton* ev)
                                                _mute_release->routes = rl;
                                        }
 
-                                       _session->set_mute (rl, !_route->muted());
+                                       _session->set_mute (rl, !_route->self_muted());
 
                                }
                        }
@@ -362,7 +390,7 @@ RouteUI::solo_press(GdkEventButton* ev)
                                         return true;
                                 }
 
-                               _solo_release = new SoloMuteRelease (_route->soloed());
+                               _solo_release = new SoloMuteRelease (_route->self_soloed());
                        }
                        
                        if (ev->button == 1 || Keyboard::is_button2_event (ev)) {
@@ -378,7 +406,7 @@ RouteUI::solo_press(GdkEventButton* ev)
                                        if (Config->get_solo_control_is_listen_control()) {
                                                _session->set_listen (_session->get_routes(), !_route->listening(),  Session::rt_cleanup, true);
                                        } else {
-                                               _session->set_solo (_session->get_routes(), !_route->soloed(),  Session::rt_cleanup, true);
+                                               _session->set_solo (_session->get_routes(), !_route->self_soloed(),  Session::rt_cleanup, true);
                                        }
                                        
                                } else if (Keyboard::modifier_state_contains (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::SecondaryModifier))) {
@@ -428,7 +456,7 @@ RouteUI::solo_press(GdkEventButton* ev)
                                                if (Config->get_solo_control_is_listen_control()) {
                                                        _session->set_listen (_route->route_group()->route_list(), !_route->listening(),  Session::rt_cleanup, true);
                                                } else {
-                                                       _session->set_solo (_route->route_group()->route_list(), !_route->soloed(),  Session::rt_cleanup, true);
+                                                       _session->set_solo (_route->route_group()->route_list(), !_route->self_soloed(),  Session::rt_cleanup, true);
                                                }
                                        }
                                        
@@ -446,7 +474,7 @@ RouteUI::solo_press(GdkEventButton* ev)
                                        if (Config->get_solo_control_is_listen_control()) {
                                                _session->set_listen (rl, !_route->listening());
                                        } else {
-                                               _session->set_solo (rl, !_route->soloed());
+                                               _session->set_solo (rl, !_route->self_soloed());
                                        }
                                }
                        }
@@ -665,19 +693,6 @@ RouteUI::send_blink (bool onoff)
        }
 }
 
-void
-RouteUI::solo_changed(void* /*src*/)
-{
-       Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&RouteUI::update_solo_display, this));
-}
-
-
-void
-RouteUI::listen_changed(void* /*src*/)
-{
-       Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&RouteUI::update_solo_display, this));
-}
-
 int
 RouteUI::solo_visual_state (boost::shared_ptr<Route> r)
 {
@@ -714,7 +729,7 @@ RouteUI::solo_visual_state_with_isolate (boost::shared_ptr<Route> r)
                if (r->listening()) {
                        return 1;
                } else {
-                       return 0;
+                        return 0;
                }
 
        } 
@@ -722,7 +737,11 @@ RouteUI::solo_visual_state_with_isolate (boost::shared_ptr<Route> r)
        if (r->solo_isolated()) {
                return 2;
        } else if (r->soloed()) {
-               return 1;
+                if (!r->self_soloed()) {
+                        return 3;
+                } else {
+                        return 1;
+                }
        } else {
                return 0;
        }
@@ -736,7 +755,21 @@ RouteUI::solo_isolate_visual_state (boost::shared_ptr<Route> r)
        }
        
        if (r->solo_isolated()) {
-                       return 1;
+               return 1;
+       } else {
+               return 0;
+       }
+}
+
+int
+RouteUI::solo_safe_visual_state (boost::shared_ptr<Route> r)
+{
+       if (r->is_master() || r->is_monitor()) {
+               return 0;
+       }
+       
+       if (r->solo_safe()) {
+               return 1;
        } else {
                return 0;
        }
@@ -765,6 +798,20 @@ RouteUI::update_solo_display ()
 
        }
 
+       bool yn = _route->solo_safe ();
+
+       if (solo_safe_check && solo_safe_check->get_active() != yn) {
+               solo_safe_check->set_active (yn);
+       }
+
+       yn = _route->solo_isolated ();
+
+       if (solo_isolated_check && solo_isolated_check->get_active() != yn) {
+               solo_isolated_check->set_active (yn);
+       }
+
+        set_button_names ();
+
        solo_button->set_visual_state (solo_visual_state_with_isolate (_route));
 }
 
@@ -789,11 +836,10 @@ RouteUI::mute_visual_state (Session* s, boost::shared_ptr<Route> r)
        
        if (Config->get_show_solo_mutes()) {
                
-               if (r->muted ()) {
+               if (r->self_muted ()) {
                        /* full mute */
                        return 2;
-               } else if (s->soloing() && !r->soloed() && !r->solo_isolated()) {
-                       /* mute-because-not-soloed */
+               } else if (r->muted_by_others()) {
                        return 1;
                } else {
                        /* no mute at all */
@@ -802,7 +848,7 @@ RouteUI::mute_visual_state (Session* s, boost::shared_ptr<Route> r)
 
        } else {
 
-               if (r->muted()) {
+               if (r->self_muted()) {
                        /* full mute */
                        return 2;
                } else {
@@ -905,15 +951,15 @@ RouteUI::build_solo_menu (void)
        check = new CheckMenuItem(_("Solo Isolate"));
        check->set_active (_route->solo_isolated());
        check->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_solo_isolated), check));
-       _route->solo_isolated_changed.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::solo_isolated_toggle, this, _1, check), gui_context());
        items.push_back (CheckMenuElem(*check));
+        solo_isolated_check = dynamic_cast<CheckMenuItem*>(&items.back());
        check->show_all();
 
        check = new CheckMenuItem(_("Solo Safe"));
        check->set_active (_route->solo_safe());
        check->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_solo_safe), check));
-       _route->solo_safe_changed.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::solo_safe_toggle, this, _1, check), gui_context());
        items.push_back (CheckMenuElem(*check));
+        solo_safe_check = dynamic_cast<CheckMenuItem*>(&items.back());
        check->show_all();
 
        //items.push_back (SeparatorElem());
@@ -1196,35 +1242,6 @@ RouteUI::route_active_changed ()
        }
 }
 
-void
-RouteUI::toggle_polarity ()
-{
-       if (polarity_menu_item) {
-
-               bool x;
-
-               ENSURE_GUI_THREAD (*this, &RouteUI::toggle_polarity)
-
-               if ((x = polarity_menu_item->get_active()) != _route->phase_invert()) {
-                       _route->set_phase_invert (x);
-                       if (x) {
-                               name_label.set_text (X_("Ø ") + name_label.get_text());
-                       } else {
-                               name_label.set_text (_route->name());
-                       }
-               }
-       }
-}
-
-void
-RouteUI::polarity_changed ()
-{
-       if (_route->phase_invert()) {
-               name_label.set_text (X_("Ø ") + name_label.get_text());
-       } else {
-               name_label.set_text (_route->name());
-       }
-}
 
 void
 RouteUI::toggle_denormal_protection ()
@@ -1249,27 +1266,6 @@ RouteUI::denormal_protection_changed ()
        }
 }
 
-void
-RouteUI::solo_isolated_toggle(void* /*src*/, Gtk::CheckMenuItem* check)
-{
-       bool yn = _route->solo_isolated ();
-
-       if (check->get_active() != yn) {
-               check->set_active (yn);
-       }
-}
-
-
-void
-RouteUI::solo_safe_toggle(void* /*src*/, Gtk::CheckMenuItem* check)
-{
-       bool yn = _route->solo_safe ();
-
-       if (check->get_active() != yn) {
-               check->set_active (yn);
-       }
-}
-
 void
 RouteUI::disconnect_input ()
 {
@@ -1318,18 +1314,6 @@ RouteUI::midi_track() const
        return boost::dynamic_pointer_cast<MidiTrack>(_route);
 }
 
-boost::shared_ptr<Diskstream>
-RouteUI::get_diskstream () const
-{
-       boost::shared_ptr<Track> t;
-
-       if ((t = boost::dynamic_pointer_cast<Track>(_route)) != 0) {
-               return t->diskstream();
-       } else {
-               return boost::shared_ptr<Diskstream> ((Diskstream*) 0);
-       }
-}
-
 string
 RouteUI::name() const
 {