Fix gmsynth detection
[ardour.git] / gtk2_ardour / processor_box.cc
index 9e77f97c61865107d9bdb25a46b76dfe2ac1cfe7..4448443136a1bf7d4499ff192fbfafdaecacf2a7 100644 (file)
@@ -2034,7 +2034,7 @@ ProcessorBox::build_possible_aux_menu ()
                return 0;
        }
 
-       if (_route->is_monitor () || _route->is_listenbus ()) {
+       if (_route->is_monitor () || _route->is_foldbackbus ()) {
                return 0;
        }
 
@@ -2047,6 +2047,45 @@ ProcessorBox::build_possible_aux_menu ()
                        /* don't allow sending to master or monitor or to self */
                        continue;
                }
+               if ((*r)->is_foldbackbus ()) {
+                       continue;
+               }
+               if (_route->internal_send_for (*r)) {
+                       /* aux-send to target already exists */
+                       continue;
+               }
+               items.push_back (MenuElemNoMnemonic ((*r)->name(), sigc::bind (sigc::ptr_fun (ProcessorBox::rb_choose_aux), boost::weak_ptr<Route>(*r))));
+       }
+
+       return menu;
+}
+
+Gtk::Menu*
+ProcessorBox::build_possible_listener_menu ()
+{
+       boost::shared_ptr<RouteList> rl = _session->get_routes_with_internal_returns();
+
+       if (rl->empty()) {
+               /* No aux sends if there are no busses */
+               return 0;
+       }
+
+       if (_route->is_monitor () || _route->is_foldbackbus ()) {
+               return 0;
+       }
+
+       using namespace Menu_Helpers;
+       Menu* menu = manage (new Menu);
+       MenuList& items = menu->items();
+
+       for (RouteList::iterator r = rl->begin(); r != rl->end(); ++r) {
+               if ((*r)->is_master() || (*r)->is_monitor () || *r == _route) {
+                       /* don't allow sending to master or monitor or to self */
+                       continue;
+               }
+               if (!(*r)->is_foldbackbus ()) {
+                       continue;
+               }
                if (_route->internal_send_for (*r)) {
                        /* aux-send to target already exists */
                        continue;
@@ -2057,6 +2096,42 @@ ProcessorBox::build_possible_aux_menu ()
        return menu;
 }
 
+Gtk::Menu*
+ProcessorBox::build_possible_remove_listener_menu ()
+{
+       boost::shared_ptr<RouteList> rl = _session->get_routes_with_internal_returns();
+
+       if (rl->empty()) {
+               /* No aux sends if there are no busses */
+               return 0;
+       }
+
+       if (_route->is_monitor () || _route->is_foldbackbus ()) {
+               return 0;
+       }
+
+       using namespace Menu_Helpers;
+       Menu* menu = manage (new Menu);
+       MenuList& items = menu->items();
+
+       for (RouteList::iterator r = rl->begin(); r != rl->end(); ++r) {
+               if ((*r)->is_master() || (*r)->is_monitor () || *r == _route) {
+                       /* don't allow sending to master or monitor or to self */
+                       continue;
+               }
+               if (!(*r)->is_foldbackbus ()) {
+                       continue;
+               }
+               if (!_route->internal_send_for (*r)) {
+                       /* aux-send to target already exists */
+                       continue;
+               }
+               items.push_back (MenuElemNoMnemonic ((*r)->name(), sigc::bind (sigc::ptr_fun (ProcessorBox::rb_remove_aux), boost::weak_ptr<Route>(*r))));
+       }
+
+       return menu;
+}
+
 void
 ProcessorBox::show_processor_menu (int arg)
 {
@@ -2089,8 +2164,36 @@ ProcessorBox::show_processor_menu (int arg)
                }
        }
 
-       ActionManager::get_action (X_("ProcessorMenu"), "newinsert")->set_sensitive (!_route->is_monitor ());
-       ActionManager::get_action (X_("ProcessorMenu"), "newsend")->set_sensitive (!_route->is_monitor ());
+       Gtk::MenuItem* listen_menu_item = dynamic_cast<Gtk::MenuItem*>(ActionManager::get_widget("/ProcessorMenu/newlisten"));
+
+       if (listen_menu_item) {
+               Menu* m = build_possible_listener_menu();
+               if (m && !m->items().empty()) {
+                       listen_menu_item->set_submenu (*m);
+                       listen_menu_item->set_sensitive (true);
+               } else {
+                       /* stupid gtkmm: we need to pass a null reference here */
+                       gtk_menu_item_set_submenu (listen_menu_item->gobj(), 0);
+                       listen_menu_item->set_sensitive (false);
+               }
+       }
+
+       Gtk::MenuItem* remove_listen_menu_item = dynamic_cast<Gtk::MenuItem*>(ActionManager::get_widget("/ProcessorMenu/removelisten"));
+
+       if (remove_listen_menu_item) {
+               Menu* m = build_possible_remove_listener_menu();
+               if (m && !m->items().empty()) {
+                       remove_listen_menu_item->set_submenu (*m);
+                       remove_listen_menu_item->set_sensitive (true);
+               } else {
+                       /* stupid gtkmm: we need to pass a null reference here */
+                       gtk_menu_item_set_submenu (remove_listen_menu_item->gobj(), 0);
+                       remove_listen_menu_item->set_sensitive (false);
+               }
+       }
+
+       ActionManager::get_action (X_("ProcessorMenu"), "newinsert")->set_sensitive (!_route->is_monitor () && !_route->is_foldbackbus ());
+       ActionManager::get_action (X_("ProcessorMenu"), "newsend")->set_sensitive (!_route->is_monitor () && !_route->is_foldbackbus ());
 
        ProcessorEntry* single_selection = 0;
        if (processor_display.selection().size() == 1) {
@@ -2321,18 +2424,17 @@ ProcessorBox::processor_button_press_event (GdkEventButton *ev, ProcessorEntry*
 
        if (processor && (Keyboard::is_edit_event (ev) || (ev->button == 1 && ev->type == GDK_2BUTTON_PRESS))) {
 
-               if (_session->engine().connected()) {
-                       /* XXX giving an error message here is hard, because we may be in the midst of a button press */
-
-                       if (!one_processor_can_be_edited ()) {
-                               return true;
-                       }
+               if (!one_processor_can_be_edited ()) {
+                       return true;
+               }
+               if (!ARDOUR_UI_UTILS::engine_is_running ()) {
+                       return true;
+               }
 
-                       if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) {
-                               generic_edit_processor (processor);
-                       } else {
-                               edit_processor (processor);
-                       }
+               if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) {
+                       generic_edit_processor (processor);
+               } else {
+                       edit_processor (processor);
                }
 
                ret = true;
@@ -2431,8 +2533,10 @@ ProcessorBox::use_plugins (const SelectedPlugins& plugins)
                        else if (boost::dynamic_pointer_cast<PluginInsert>(processor)->plugin()->has_inline_display() && UIConfiguration::instance().get_prefer_inline_over_gui()) {
                                ; /* only show inline display */
                        }
-                       else if (_session->engine().connected () && processor_can_be_edited (processor)) {
-                               if ((*p)->has_editor ()) {
+                       else if (processor_can_be_edited (processor)) {
+                               if (!ARDOUR_UI_UTILS::engine_is_running()) {
+                                       return true;
+                               } else if ((*p)->has_editor ()) {
                                        edit_processor (processor);
                                } else if (boost::dynamic_pointer_cast<PluginInsert>(processor)->plugin()->parameter_count() > 0) {
                                        generic_edit_processor (processor);
@@ -2615,7 +2719,29 @@ ProcessorBox::choose_aux (boost::weak_ptr<Route> wr)
                return;
        }
 
-       _session->add_internal_send (target, _placement, _route);
+       if (target->is_foldbackbus ()) {
+               _route->add_foldback_send (target);
+       } else {
+               _session->add_internal_send (target, _placement, _route);
+       }
+}
+
+void
+ProcessorBox::remove_aux (boost::weak_ptr<Route> wr)
+{
+       if (!_route) {
+               return;
+       }
+
+       boost::shared_ptr<Route> target = wr.lock();
+
+       if (!target) {
+               return;
+       }
+       boost::shared_ptr<Send>  send = _route->internal_send_for (target);
+       boost::shared_ptr<Processor> proc = boost::dynamic_pointer_cast<Processor> (send);
+       _route->remove_processor (proc);
+
 }
 
 void
@@ -3537,7 +3663,7 @@ ProcessorBox::get_editor_window (boost::shared_ptr<Processor> processor, bool us
 
        } else if ((send = boost::dynamic_pointer_cast<Send> (processor)) != 0) {
 
-               if (!_session->engine().connected()) {
+               if (!ARDOUR_UI_UTILS::engine_is_running ()) {
                        return 0;
                }
 
@@ -3553,7 +3679,7 @@ ProcessorBox::get_editor_window (boost::shared_ptr<Processor> processor, bool us
                        return 0;
                }
 
-               if (!_session->engine().connected()) {
+               if (!ARDOUR_UI_UTILS::engine_is_running ()) {
                        return 0;
                }
 
@@ -3595,9 +3721,7 @@ ProcessorBox::get_editor_window (boost::shared_ptr<Processor> processor, bool us
 
        } else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (processor)) != 0) {
 
-               if (!_session->engine().connected()) {
-                       MessageDialog msg ( _("Not connected to audio engine - no I/O changes are possible"));
-                       msg.run ();
+               if (!ARDOUR_UI_UTILS::engine_is_running ()) {
                        return 0;
                }
 
@@ -3654,6 +3778,8 @@ ProcessorBox::register_actions ()
        ActionManager::engine_sensitive_actions.push_back (act);
 
        myactions.register_action (processor_box_actions, X_("newaux"), _("New Aux Send ..."));
+       myactions.register_action (processor_box_actions, X_("newlisten"), _("New Monitor Send ..."));
+       myactions.register_action (processor_box_actions, X_("removelisten"), _("Remove Monitor Send ..."));
 
        myactions.register_action (processor_box_actions, X_("controls"), _("Controls"));
        myactions.register_action (processor_box_actions, X_("send_options"), _("Send Options"));
@@ -3797,6 +3923,16 @@ ProcessorBox::rb_choose_aux (boost::weak_ptr<Route> wr)
        _current_processor_box->choose_aux (wr);
 }
 
+void
+ProcessorBox::rb_remove_aux (boost::weak_ptr<Route> wr)
+{
+       if (_current_processor_box == 0) {
+               return;
+       }
+
+       _current_processor_box->remove_aux (wr);
+}
+
 void
 ProcessorBox::rb_clear ()
 {
@@ -3953,7 +4089,7 @@ ProcessorBox::edit_processor (boost::shared_ptr<Processor> processor)
        if (edit_aux_send (processor)) {
                return;
        }
-       if (!_session->engine().connected()) {
+       if (!ARDOUR_UI_UTILS::engine_is_running ()) {
                return;
        }
 
@@ -3974,7 +4110,7 @@ ProcessorBox::generic_edit_processor (boost::shared_ptr<Processor> processor)
        if (edit_aux_send (processor)) {
                return;
        }
-       if (!_session->engine().connected()) {
+       if (!ARDOUR_UI_UTILS::engine_is_running ()) {
                return;
        }