diff --git a/gtk2_ardour/ardour.menus.in b/gtk2_ardour/ardour.menus.in index 87fd8c973d..68eb7871fc 100644 --- a/gtk2_ardour/ardour.menus.in +++ b/gtk2_ardour/ardour.menus.in @@ -647,6 +647,8 @@ + + diff --git a/gtk2_ardour/processor_box.cc b/gtk2_ardour/processor_box.cc index 9e77f97c61..3b23f294a3 100644 --- a/gtk2_ardour/processor_box.cc +++ b/gtk2_ardour/processor_box.cc @@ -2047,6 +2047,9 @@ ProcessorBox::build_possible_aux_menu () /* don't allow sending to master or monitor or to self */ continue; } + if ((*r)->is_listenbus ()) { + continue; + } if (_route->internal_send_for (*r)) { /* aux-send to target already exists */ continue; @@ -2057,6 +2060,78 @@ ProcessorBox::build_possible_aux_menu () return menu; } +Gtk::Menu* +ProcessorBox::build_possible_listener_menu () +{ + boost::shared_ptr 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_listenbus ()) { + 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_listenbus ()) { + 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(*r)))); + } + + return menu; +} + +Gtk::Menu* +ProcessorBox::build_possible_remove_listener_menu () +{ + boost::shared_ptr 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_listenbus ()) { + 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_listenbus ()) { + 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(*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(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(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_listenbus ()); + ActionManager::get_action (X_("ProcessorMenu"), "newsend")->set_sensitive (!_route->is_monitor () && !_route->is_listenbus ()); ProcessorEntry* single_selection = 0; if (processor_display.selection().size() == 1) { @@ -2615,7 +2718,29 @@ ProcessorBox::choose_aux (boost::weak_ptr wr) return; } - _session->add_internal_send (target, _placement, _route); + if (target->is_listenbus ()) { + _route->add_personal_send (target); + } else { + _session->add_internal_send (target, _placement, _route); + } +} + +void +ProcessorBox::remove_aux (boost::weak_ptr wr) +{ + if (!_route) { + return; + } + + boost::shared_ptr target = wr.lock(); + + if (!target) { + return; + } + boost::shared_ptr send = _route->internal_send_for (target); + boost::shared_ptr proc = boost::dynamic_pointer_cast (send); + _route->remove_processor (proc); + } void @@ -3654,6 +3779,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 +3924,16 @@ ProcessorBox::rb_choose_aux (boost::weak_ptr wr) _current_processor_box->choose_aux (wr); } +void +ProcessorBox::rb_remove_aux (boost::weak_ptr wr) +{ + if (_current_processor_box == 0) { + return; + } + + _current_processor_box->remove_aux (wr); +} + void ProcessorBox::rb_clear () { diff --git a/gtk2_ardour/processor_box.h b/gtk2_ardour/processor_box.h index 81c5c8e20f..037e601f33 100644 --- a/gtk2_ardour/processor_box.h +++ b/gtk2_ardour/processor_box.h @@ -511,8 +511,11 @@ private: Gtk::Menu * build_processor_menu (); void show_processor_menu (int); Gtk::Menu* build_possible_aux_menu(); + Gtk::Menu* build_possible_listener_menu(); + Gtk::Menu* build_possible_remove_listener_menu(); void choose_aux (boost::weak_ptr); + void remove_aux (boost::weak_ptr); void choose_send (); void send_io_finished (IOSelector::Result, boost::weak_ptr, IOSelectorWindow*); void return_io_finished (IOSelector::Result, boost::weak_ptr, IOSelectorWindow*); @@ -581,6 +584,7 @@ private: static ProcessorBox* _current_processor_box; static void rb_choose_aux (boost::weak_ptr); + static void rb_remove_aux (boost::weak_ptr); static void rb_choose_plugin (); static void rb_choose_insert (); static void rb_choose_send (); diff --git a/gtk2_ardour/trx.menus.in b/gtk2_ardour/trx.menus.in index d4a7e3187a..5dd401c310 100644 --- a/gtk2_ardour/trx.menus.in +++ b/gtk2_ardour/trx.menus.in @@ -24,7 +24,7 @@ --> - + @@ -44,7 +44,7 @@ -#ifdef GTKOSX +#ifdef GTKOSX #endif @@ -86,12 +86,12 @@ - - + + - + @@ -101,10 +101,10 @@ #endif - + - + @@ -173,6 +173,8 @@ + + @@ -229,7 +231,7 @@ - + @@ -243,7 +245,7 @@ - + @@ -295,7 +297,7 @@ - + @@ -315,7 +317,7 @@ - +