X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fplugin_selector.cc;h=0384a6281d53ebb77114b9c7b63ae046691cb48c;hb=a8d62ce056fe260792d4e72bf8cf2fbff0e8b39b;hp=93a17f260c290a22abf56787babe7403d15e6c77;hpb=54e155f4c7d63117e9ff4a42a57563ae18490c31;p=ardour.git diff --git a/gtk2_ardour/plugin_selector.cc b/gtk2_ardour/plugin_selector.cc index 93a17f260c..0384a6281d 100644 --- a/gtk2_ardour/plugin_selector.cc +++ b/gtk2_ardour/plugin_selector.cc @@ -1,21 +1,28 @@ /* - Copyright (C) 2000-2006 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ + * Copyright (C) 2005-2006 Doug McLain + * Copyright (C) 2005-2007 Taybin Rutkin + * Copyright (C) 2005-2017 Paul Davis + * Copyright (C) 2006 Nick Mainsbridge + * Copyright (C) 2007-2012 David Robillard + * Copyright (C) 2009-2011 Carl Hetherington + * Copyright (C) 2013-2014 John Emmas + * Copyright (C) 2014-2018 Ben Loftis + * Copyright (C) 2014-2019 Robin Gareus + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ #ifdef WAF_BUILD #include "gtk2ardour-config.h" #endif @@ -24,6 +31,7 @@ #include #include +#include #include #include @@ -32,6 +40,7 @@ #include #include #include +#include #include "gtkmm2ext/utils.h" @@ -60,7 +69,10 @@ PluginSelector::PluginSelector (PluginManager& mgr) : ArdourDialog (_("Plugin Manager"), true, false) , search_clear_button (Stock::CLEAR) , manager (mgr) - , inhibit_refill (false) + , _need_tag_save (false) + , _need_status_save (false) + , _need_menu_rebuild (false) + , _inhibit_refill (false) { set_name ("PluginSelectorWindow"); add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK); @@ -69,9 +81,11 @@ PluginSelector::PluginSelector (PluginManager& mgr) in_row_change = false; manager.PluginListChanged.connect (plugin_list_changed_connection, invalidator (*this), boost::bind (&PluginSelector::build_plugin_menu, this), gui_context()); - manager.PluginListChanged.connect (plugin_list_changed_connection, invalidator (*this), boost::bind (&PluginSelector::refill, this), gui_context()); - manager.PluginStatusesChanged.connect (plugin_list_changed_connection, invalidator (*this), boost::bind (&PluginSelector::plugin_status_changed, this, _1, _2, _3), gui_context()); - manager.PluginTagsChanged.connect(plugin_list_changed_connection, invalidator (*this), boost::bind (&PluginSelector::tags_changed, this, _1, _2, _3), gui_context()); + manager.PluginStatusChanged.connect (plugin_list_changed_connection, invalidator (*this), boost::bind (&PluginSelector::build_plugin_menu, this), gui_context()); + manager.PluginTagChanged.connect (plugin_list_changed_connection, invalidator (*this), boost::bind (&PluginSelector::build_plugin_menu, this), gui_context()); + + manager.PluginStatusChanged.connect (plugin_list_changed_connection, invalidator (*this), boost::bind (&PluginSelector::plugin_status_changed, this, _1, _2, _3), gui_context()); + manager.PluginTagChanged.connect(plugin_list_changed_connection, invalidator (*this), boost::bind (&PluginSelector::tags_changed, this, _1, _2, _3), gui_context()); plugin_model = Gtk::ListStore::create (plugin_columns); plugin_display.set_model (plugin_model); @@ -148,15 +162,17 @@ PluginSelector::PluginSelector (PluginManager& mgr) search_entry.signal_changed().connect (sigc::mem_fun (*this, &PluginSelector::search_entry_changed)); search_clear_button.signal_clicked().connect (sigc::mem_fun (*this, &PluginSelector::search_clear_button_clicked)); - _search_name_checkbox = manage (new CheckButton (_("Name"))); - _search_name_checkbox->set_active(); + _search_name_checkbox = manage (new ArdourButton (_("Name"), ArdourButton::led_default_elements, true)); + _search_name_checkbox->set_active(true); + _search_name_checkbox->set_name ("pluginlist filter button"); - _search_tags_checkbox = manage (new CheckButton (_("Tags"))); - _search_tags_checkbox->set_active(); + _search_tags_checkbox = manage (new ArdourButton (_("Tags"), ArdourButton::led_default_elements, true)); + _search_tags_checkbox->set_active(true); + _search_tags_checkbox->set_name ("pluginlist filter button"); - _search_ignore_checkbox = manage (new CheckButton(_("Ignore Filters when searching"))); - _search_ignore_checkbox->set_active(); - _search_ignore_checkbox->signal_toggled().connect (sigc::mem_fun (*this, &PluginSelector::set_sensitive_widgets)); + _search_ignore_checkbox = manage (new ArdourButton(_("Ignore Filters when searching"), ArdourButton::led_default_elements, true)); + _search_ignore_checkbox->set_active(true); + _search_ignore_checkbox->set_name ("pluginlist filter button"); Gtk::Label* search_help_label1 = manage (new Label( _("All search terms must be matched."), Gtk::ALIGN_LEFT)); @@ -182,8 +198,9 @@ PluginSelector::PluginSelector (PluginManager& mgr) search_frame->add (*search_table); search_frame->show_all (); - _search_name_checkbox->signal_clicked().connect (sigc::mem_fun (*this, &PluginSelector::refill)); - _search_tags_checkbox->signal_clicked().connect (sigc::mem_fun (*this, &PluginSelector::refill)); + _search_name_checkbox->signal_clicked.connect (sigc::mem_fun (*this, &PluginSelector::refill)); + _search_tags_checkbox->signal_clicked.connect (sigc::mem_fun (*this, &PluginSelector::refill)); + _search_ignore_checkbox->signal_clicked.connect (sigc::mem_fun (*this, &PluginSelector::set_sensitive_widgets)); /* FILTER */ @@ -205,7 +222,7 @@ PluginSelector::PluginSelector (PluginManager& mgr) #ifdef LV2_SUPPORT _fil_type_combo.append_text_item (X_("LV2")); #endif - _fil_type_combo.append_text_item (X_("LUA")); + _fil_type_combo.append_text_item (X_("Lua")); _fil_type_combo.append_text_item (X_("LADSPA")); _fil_type_combo.set_text (_("Show All Formats")); @@ -213,17 +230,6 @@ PluginSelector::PluginSelector (PluginManager& mgr) _fil_creator_combo.set_text_ellipsize (Pango::ELLIPSIZE_END); _fil_creator_combo.set_layout_ellipsize_width (PANGO_SCALE * 160 * UIConfiguration::instance ().get_ui_scale ()); - _fil_channel_combo.append_text_item (_("Audio I/O")); - _fil_channel_combo.append_text_item (_("Mono Audio I/O")); - _fil_channel_combo.append_text_item (_("Stereo Audio I/O")); - _fil_channel_combo.append_text_item (_("MIDI I/O (only)")); - _fil_channel_combo.append_text_item (_("Show All I/O")); -#ifdef MIXBUS - _fil_channel_combo.set_text (_("Audio I/O")); -#else - _fil_channel_combo.set_text (_("Show All I/O")); -#endif - VBox* filter_vbox = manage (new VBox); filter_vbox->pack_start (*_fil_effects_radio, false, false); filter_vbox->pack_start (*_fil_instruments_radio, false, false); @@ -233,7 +239,6 @@ PluginSelector::PluginSelector (PluginManager& mgr) filter_vbox->pack_start (*_fil_all_radio, false, false); filter_vbox->pack_start (_fil_type_combo, false, false); filter_vbox->pack_start (_fil_creator_combo, false, false); - filter_vbox->pack_start (_fil_channel_combo, false, false); filter_vbox->set_border_width (4); filter_vbox->set_spacing (4); @@ -252,7 +257,6 @@ PluginSelector::PluginSelector (PluginManager& mgr) _fil_type_combo.StateChanged.connect (sigc::mem_fun (*this, &PluginSelector::refill)); _fil_creator_combo.StateChanged.connect (sigc::mem_fun (*this, &PluginSelector::refill)); - _fil_channel_combo.StateChanged.connect (sigc::mem_fun (*this, &PluginSelector::refill)); /* TAG entry */ @@ -264,7 +268,7 @@ PluginSelector::PluginSelector (PluginManager& mgr) tag_entry = manage (new Gtk::Entry); tag_entry_connection = tag_entry->signal_changed().connect (sigc::mem_fun (*this, &PluginSelector::tag_entry_changed)); - Gtk::Button* tag_reset_button = manage (new Button (_("Reset"))); + tag_reset_button = manage (new Button (_("Reset"))); tag_reset_button->signal_clicked().connect (sigc::mem_fun (*this, &PluginSelector::tag_reset_button_clicked)); Gtk::Label* tagging_help_label1 = manage (new Label( @@ -328,6 +332,7 @@ PluginSelector::PluginSelector (PluginManager& mgr) plugin_display.grab_focus(); build_plugin_menu (); + display_selection_changed (); } PluginSelector::~PluginSelector () @@ -348,30 +353,46 @@ PluginSelector::added_row_clicked(GdkEventButton* event) btn_remove_clicked(); } + +static void +setup_search_string (string& searchstr) +{ + transform (searchstr.begin(), searchstr.end(), searchstr.begin(), ::toupper); +} + +static bool +match_search_strings (string const& haystack, string const& needle) +{ + boost::char_separator sep (" "); + typedef boost::tokenizer > tokenizer; + tokenizer t (needle, sep); + for (tokenizer::iterator ti = t.begin(); ti != t.end(); ++ti) { + if (haystack.find (*ti) == string::npos) { + return false; + } + } + return true; +} + bool PluginSelector::show_this_plugin (const PluginInfoPtr& info, const std::string& searchstr) { string mode; bool maybe_show = false; + PluginManager::PluginStatusType status = manager.get_status (info); if (!searchstr.empty()) { - std::string compstr; - if (_search_name_checkbox->get_active()) { /* name contains */ - compstr = info->name; - transform (compstr.begin(), compstr.end(), compstr.begin(), ::toupper); - if (compstr.find (searchstr) != string::npos) { - maybe_show = true; - } + std::string compstr = info->name; + setup_search_string (compstr); + maybe_show |= match_search_strings (compstr, searchstr); } if (_search_tags_checkbox->get_active()) { /* tag contains */ - compstr = manager.get_tags_as_string (info); - transform (compstr.begin(), compstr.end(), compstr.begin(), ::toupper); - if (compstr.find (searchstr) != string::npos) { - maybe_show = true; - } + std::string compstr = manager.get_tags_as_string (info); + setup_search_string (compstr); + maybe_show |= match_search_strings (compstr, searchstr); } if (!maybe_show) { @@ -380,6 +401,12 @@ PluginSelector::show_this_plugin (const PluginInfoPtr& info, const std::string& /* user asked to ignore filters */ if (maybe_show && _search_ignore_checkbox->get_active()) { + if (status == PluginManager::Hidden) { + return false; + } + if (status == PluginManager::Concealed) { + return false; + } return true; } } @@ -396,18 +423,20 @@ PluginSelector::show_this_plugin (const PluginInfoPtr& info, const std::string& return false; } - if (_fil_favorites_radio->get_active() && !(manager.get_status (info) == PluginManager::Favorite)) { + if (_fil_favorites_radio->get_active() && status != PluginManager::Favorite) { return false; } - if (_fil_hidden_radio->get_active() && !(manager.get_status (info) == PluginManager::Hidden)) { + if (_fil_hidden_radio->get_active() && (status != PluginManager::Hidden && status != PluginManager::Concealed)) { return false; } - if (manager.get_status (info) == PluginManager::Hidden) { - if (!_fil_hidden_radio->get_active() && !_fil_all_radio->get_active()) { - return false; - } + if (!_fil_hidden_radio->get_active() && status == PluginManager::Hidden) { + return false; + } + + if (!_fil_hidden_radio->get_active() && status == PluginManager::Concealed) { + return false; } /* Filter "type" combobox */ @@ -426,7 +455,7 @@ PluginSelector::show_this_plugin (const PluginInfoPtr& info, const std::string& } #endif - if (_fil_type_combo.get_text() == X_("LUA") && info->type != Lua) { + if (_fil_type_combo.get_text() == X_("Lua") && info->type != Lua) { return false; } @@ -442,52 +471,9 @@ PluginSelector::show_this_plugin (const PluginInfoPtr& info, const std::string& } } - /* Filter "I/O" combobox */ - - if (_fil_channel_combo.get_text() != _("Show All I/O") || info->reconfigurable_io ()) { - -#if 0 - if (info->reconfigurable_io ()) { - return true; // who knows.... ? - } -#endif - - if (_fil_channel_combo.get_text() == _("Audio I/O")) { - if ((info->n_inputs.n_audio() == 0 || info->n_outputs.n_audio() == 0)) { - return false; - } - } - - if (_fil_channel_combo.get_text() == _("Mono Audio I/O")) { - if (info->n_inputs.n_audio() != 1 || info->n_outputs.n_audio() != 1) { - return false; - } - } - - if (_fil_channel_combo.get_text() == _("Stereo Audio I/O")) { - if (info->n_inputs.n_audio() != 2 || info->n_outputs.n_audio() != 2) { - return false; - } - } - - if (_fil_channel_combo.get_text() == _("MIDI I/O (only)")) { - if ((info->n_inputs.n_audio() != 0 || info->n_outputs.n_audio() == 0)) { - return false; - } - } - - } - return true; } -void -PluginSelector::setup_search_string (string& searchstr) -{ - searchstr = search_entry.get_text (); - transform (searchstr.begin(), searchstr.end(), searchstr.begin(), ::toupper); -} - void PluginSelector::set_sensitive_widgets () { @@ -498,9 +484,10 @@ PluginSelector::set_sensitive_widgets () _fil_favorites_radio->set_sensitive(false); _fil_hidden_radio->set_sensitive(false); _fil_all_radio->set_sensitive(false); + _inhibit_refill = true; _fil_type_combo.set_sensitive(false); _fil_creator_combo.set_sensitive(false); - _fil_channel_combo.set_sensitive(false); + _inhibit_refill = false; } else { _fil_effects_radio->set_sensitive(true); _fil_instruments_radio->set_sensitive(true); @@ -508,9 +495,10 @@ PluginSelector::set_sensitive_widgets () _fil_favorites_radio->set_sensitive(true); _fil_hidden_radio->set_sensitive(true); _fil_all_radio->set_sensitive(true); + _inhibit_refill = true; _fil_type_combo.set_sensitive(true); _fil_creator_combo.set_sensitive(true); - _fil_channel_combo.set_sensitive(true); + _inhibit_refill = false; } if (!search_entry.get_text().empty()) { refill (); @@ -520,16 +508,24 @@ PluginSelector::set_sensitive_widgets () void PluginSelector::refill () { - if (inhibit_refill) { + if (_inhibit_refill) { return; } - std::string searchstr; - in_row_change = true; + plugin_display.set_model (Glib::RefPtr(0)); + + int sort_col; + SortType sort_type; + bool sorted = plugin_model->get_sort_column_id (sort_col, sort_type); + + /* Disable sorting to gain performance */ + plugin_model->set_sort_column (-2, SORT_ASCENDING); + plugin_model->clear (); + std::string searchstr = search_entry.get_text (); setup_search_string (searchstr); ladspa_refiller (searchstr); @@ -541,6 +537,11 @@ PluginSelector::refill () lua_refiller (searchstr); in_row_change = false; + + plugin_display.set_model (plugin_model); + if (sorted) { + plugin_model->set_sort_column (sort_col, sort_type); + } } void @@ -553,8 +554,10 @@ PluginSelector::refiller (const PluginInfoList& plugs, const::std::string& searc if (show_this_plugin (*i, searchstr)) { TreeModel::Row newrow = *(plugin_model->append()); - newrow[plugin_columns.favorite] = (manager.get_status (*i) == PluginManager::Favorite); - newrow[plugin_columns.hidden] = (manager.get_status (*i) == PluginManager::Hidden); + + PluginManager::PluginStatusType status = manager.get_status (*i); + newrow[plugin_columns.favorite] = status == PluginManager::Favorite; + newrow[plugin_columns.hidden] = status == PluginManager::Hidden; string name = (*i)->name; if (name.length() > 48) { @@ -606,7 +609,7 @@ PluginSelector::refiller (const PluginInfoList& plugs, const::std::string& searc } else { snprintf (buf, sizeof(buf), "%d / %d", (*i)->n_inputs.n_audio(), (*i)->n_outputs.n_audio()); newrow[plugin_columns.audio_io] = buf; - snprintf (buf, sizeof(buf), "%d / %d", (*i)->n_inputs.n_audio(), (*i)->n_outputs.n_audio()); + snprintf (buf, sizeof(buf), "%d / %d", (*i)->n_inputs.n_midi(), (*i)->n_outputs.n_midi()); newrow[plugin_columns.midi_io] = buf; } @@ -696,6 +699,10 @@ PluginSelector::load_plugin (PluginInfoPtr pi) void PluginSelector::btn_add_clicked() { + if (plugin_display.get_selection()->count_selected_rows() == 0) { + /* may happen with ctrl + double-click un-selecting but activating a row */ + return; + } std::string name; PluginInfoPtr pi; TreeModel::Row newrow = *(amodel->append()); @@ -736,12 +743,14 @@ PluginSelector::display_selection_changed() tag_entry->set_text (tags); tag_entry->set_sensitive (true); + tag_reset_button->set_sensitive (true); btn_add->set_sensitive (true); } else { tag_entry->set_text (""); tag_entry->set_sensitive (false); + tag_reset_button->set_sensitive (false); btn_add->set_sensitive (false); } tag_entry_connection.unblock (); @@ -806,9 +815,8 @@ PluginSelector::run () if (_need_status_save) { manager.save_statuses(); } - if (_need_menu_rebuild) { - build_plugin_menu(); + build_plugin_menu (); } return (int) r; @@ -848,7 +856,7 @@ PluginSelector::tag_entry_changed () TreeModel::Row row = *(plugin_display.get_selection()->get_selected()); ARDOUR::PluginInfoPtr pi = row[plugin_columns.plugin]; - manager.set_tags (pi->type, pi->unique_id, tag_entry->get_text(), false); + manager.set_tags (pi->type, pi->unique_id, tag_entry->get_text(), pi->name, PluginManager::FromGui); _need_tag_save = true; } @@ -865,11 +873,6 @@ PluginSelector::tags_changed (PluginType t, std::string unique_id, std::string t } row[plugin_columns.tags] = tags; } - - /* A plugin's tags change while the user is entering them. - * defer a rebuilding of the "tag" menu until the dialog is closed. - */ - _need_menu_rebuild = true; } void @@ -883,7 +886,7 @@ PluginSelector::plugin_status_changed (PluginType t, std::string uid, PluginMana (*i)[plugin_columns.hidden] = (stat == PluginManager::Hidden) ? true : false; /* if plug was hidden, remove it from the view */ - if (stat == PluginManager::Hidden) { + if (stat == PluginManager::Hidden || stat == PluginManager::Concealed) { if (!_fil_hidden_radio->get_active() && !_fil_all_radio->get_active()) { plugin_model->erase(i); } @@ -895,9 +898,6 @@ PluginSelector::plugin_status_changed (PluginType t, std::string uid, PluginMana plugin_model->erase(i); } - /* plugin menu must be re-built to accommodate Hidden and Favorite plugins */ - build_plugin_menu(); - return; } } @@ -913,7 +913,6 @@ PluginSelector::on_show () _need_tag_save = false; _need_status_save = false; - _need_menu_rebuild = false; } struct PluginMenuCompareByCreator { @@ -962,6 +961,11 @@ PluginSelector::plugin_menu() void PluginSelector::build_plugin_menu () { + if (is_visible ()) { + _need_menu_rebuild = true; + return; + } + _need_menu_rebuild = false; PluginInfoList all_plugs; all_plugs.insert (all_plugs.end(), manager.ladspa_plugin_info().begin(), manager.ladspa_plugin_info().end()); @@ -986,7 +990,7 @@ PluginSelector::build_plugin_menu () delete _plugin_menu; - _plugin_menu = manage (new Menu); + _plugin_menu = new Menu; _plugin_menu->set_name("ArdourContextMenu"); MenuList& items = _plugin_menu->items(); @@ -1058,11 +1062,11 @@ PluginSelector::create_favs_menu (PluginInfoList& all_plugs) Gtk::Menu* PluginSelector::create_by_creator_menu (ARDOUR::PluginInfoList& all_plugs) { - inhibit_refill = true; + _inhibit_refill = true; _fil_creator_combo.clear_items (); _fil_creator_combo.append_text_item (_("Show All Creators")); _fil_creator_combo.set_text (_("Show All Creators")); - inhibit_refill = false; + _inhibit_refill = false; using namespace Menu_Helpers; @@ -1078,29 +1082,17 @@ PluginSelector::create_by_creator_menu (ARDOUR::PluginInfoList& all_plugs) for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) { - if (manager.get_status (*i) == PluginManager::Hidden) continue; + PluginManager::PluginStatusType status = manager.get_status (*i); + if (status == PluginManager::Hidden) continue; + if (status == PluginManager::Concealed) continue; string creator = (*i)->creator; - string::size_type pos = 0; - - if ((*i)->type == ARDOUR::LADSPA) { - /* stupid LADSPA creator strings */ -#ifdef PLATFORM_WINDOWS - while (pos < creator.length() && creator[pos] > -2 && creator[pos] < 256 && (isalnum (creator[pos]) || isspace (creator[pos]))) ++pos; -#else - while (pos < creator.length() && (isalnum (creator[pos]) || isspace (creator[pos]))) ++pos; -#endif - } else { - pos = creator.length (); - } /* If there were too few characters to create a * meaningful name, mark this creator as 'Unknown' */ - if (creator.length() < 2 || pos < 3) { + if (creator.length() < 2) { creator = "Unknown"; - } else{ - creator = creator.substr (0, pos); } SubmenuMap::iterator x; @@ -1137,7 +1129,7 @@ PluginSelector::create_by_tags_menu (ARDOUR::PluginInfoList& all_plugs) by_tags->set_name("ArdourContextMenu"); MenuList& by_tags_items = by_tags->items(); - std::vector all_tags = manager.get_all_tags(false); + std::vector all_tags = manager.get_all_tags (PluginManager::NoHidden); for (vector::iterator t = all_tags.begin(); t != all_tags.end(); ++t) { Gtk::Menu *submenu = new Gtk::Menu; by_tags_items.push_back (MenuElem (*t, *manage (submenu))); @@ -1150,7 +1142,9 @@ PluginSelector::create_by_tags_menu (ARDOUR::PluginInfoList& all_plugs) for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) { - if (manager.get_status (*i) == PluginManager::Hidden) continue; + PluginManager::PluginStatusType status = manager.get_status (*i); + if (status == PluginManager::Hidden) continue; + if (status == PluginManager::Concealed) continue; /* for each tag in the plugins tag list, add it to that submenu */ vector tokens = manager.get_tags(*i); @@ -1159,12 +1153,11 @@ PluginSelector::create_by_tags_menu (ARDOUR::PluginInfoList& all_plugs) Gtk::Menu* submenu; if ((x = tags_submenu_map.find (*t)) != tags_submenu_map.end()) { submenu = x->second; - } else { + string typ = GetPluginTypeStr(*i); + MenuElem elem ((*i)->name + typ, (sigc::bind (sigc::mem_fun (*this, &PluginSelector::plugin_chosen_from_menu), *i))); + elem.get_child()->set_use_underline (false); + submenu->items().push_back (elem); } - string typ = GetPluginTypeStr(*i); - MenuElem elem ((*i)->name + typ, (sigc::bind (sigc::mem_fun (*this, &PluginSelector::plugin_chosen_from_menu), *i))); - elem.get_child()->set_use_underline (false); - submenu->items().push_back (elem); } } return by_tags;