X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fplugin_selector.cc;h=71036b72da10f9d762aaaac34fbaebc390f97b11;hb=e3d9a971a735174687067cb7d7b9419c7ecbb114;hp=ac9e785522487b056cd9ffa4579087c76474e6d2;hpb=e0aaed6d65f160c328cb8b56d7c6552ee15d65e2;p=ardour.git diff --git a/gtk2_ardour/plugin_selector.cc b/gtk2_ardour/plugin_selector.cc index ac9e785522..71036b72da 100644 --- a/gtk2_ardour/plugin_selector.cc +++ b/gtk2_ardour/plugin_selector.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2000-2006 Paul Davis + 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 @@ -16,6 +16,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#ifdef WAF_BUILD +#include "gtk2ardour-config.h" +#endif #include #include @@ -35,6 +38,7 @@ #include "ardour/plugin_manager.h" #include "ardour/plugin.h" #include "ardour/configuration.h" +#include "ardour/session.h" #include "ardour_ui.h" #include "plugin_selector.h" @@ -50,31 +54,38 @@ using namespace std; static const char* _filter_mode_strings[] = { N_("Name contains"), N_("Type contains"), + N_("Category contains"), N_("Author contains"), N_("Library contains"), N_("Favorites only"), + N_("Hidden only"), 0 }; -PluginSelector::PluginSelector (PluginManager *mgr) - : ArdourDialog (_("ardour: plugins"), true, false), - filter_button (Stock::CLEAR) +PluginSelector::PluginSelector (PluginManager& mgr) + : ArdourDialog (_("Plugin Manager"), true, false) + , filter_button (Stock::CLEAR) + , manager (mgr) + { set_position (Gtk::WIN_POS_MOUSE); set_name ("PluginSelectorWindow"); add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK); - manager = mgr; - session = 0; - _menu = 0; + _plugin_menu = 0; in_row_change = false; + manager.PluginListChanged.connect (plugin_list_changed_connection, invalidator (*this), boost::bind (&PluginSelector::build_plugin_menu, this), gui_context()); + build_plugin_menu (); + plugin_model = Gtk::ListStore::create (plugin_columns); plugin_display.set_model (plugin_model); /* XXX translators: try to convert "Fav" into a short term - related to "favorite" + related to "favorite" and "Hid" into a short term + related to "hidden" */ plugin_display.append_column (_("Fav"), plugin_columns.favorite); + plugin_display.append_column (_("Hid"), plugin_columns.hidden); plugin_display.append_column (_("Available Plugins"), plugin_columns.name); plugin_display.append_column (_("Type"), plugin_columns.type_name); plugin_display.append_column (_("Category"), plugin_columns.category); @@ -90,8 +101,13 @@ PluginSelector::PluginSelector (PluginManager *mgr) CellRendererToggle* fav_cell = dynamic_cast(plugin_display.get_column_cell_renderer (0)); fav_cell->property_activatable() = true; - fav_cell->property_radio() = false; - fav_cell->signal_toggled().connect (mem_fun (*this, &PluginSelector::favorite_changed)); + fav_cell->property_radio() = true; + fav_cell->signal_toggled().connect (sigc::mem_fun (*this, &PluginSelector::favorite_changed)); + + CellRendererToggle* hidden_cell = dynamic_cast(plugin_display.get_column_cell_renderer (1)); + hidden_cell->property_activatable() = true; + hidden_cell->property_radio() = true; + hidden_cell->signal_toggled().connect (sigc::mem_fun (*this, &PluginSelector::hidden_changed)); scroller.set_border_width(10); scroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); @@ -103,7 +119,7 @@ PluginSelector::PluginSelector (PluginManager *mgr) added_list.set_headers_visible (true); added_list.set_reorderable (false); - for (int i = 0; i <=7; i++) { + for (int i = 0; i <=8; i++) { Gtk::TreeView::Column* column = plugin_display.get_column(i); column->set_sort_column(i); } @@ -112,13 +128,13 @@ PluginSelector::PluginSelector (PluginManager *mgr) ascroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); ascroller.add(added_list); btn_add = manage(new Gtk::Button(Stock::ADD)); - ARDOUR_UI::instance()->tooltips().set_tip(*btn_add, _("Add a plugin to the effect list")); + ARDOUR_UI::instance()->set_tip(*btn_add, _("Add a plugin to the effect list")); btn_add->set_sensitive (false); btn_remove = manage(new Gtk::Button(Stock::REMOVE)); btn_remove->set_sensitive (false); - ARDOUR_UI::instance()->tooltips().set_tip(*btn_remove, _("Remove a plugin from the effect list")); + ARDOUR_UI::instance()->set_tip(*btn_remove, _("Remove a plugin from the effect list")); Gtk::Button *btn_update = manage(new Gtk::Button(Stock::REFRESH)); - ARDOUR_UI::instance()->tooltips().set_tip(*btn_update, _("Update available plugins")); + ARDOUR_UI::instance()->set_tip(*btn_update, _("Update available plugins")); btn_add->set_name("PluginSelectorButton"); btn_remove->set_name("PluginSelectorButton"); @@ -137,9 +153,9 @@ PluginSelector::PluginSelector (PluginManager *mgr) filter_box->pack_start (filter_entry, true, true); filter_box->pack_start (filter_button, false, false); - filter_entry.signal_changed().connect (mem_fun (*this, &PluginSelector::filter_entry_changed)); - filter_button.signal_clicked().connect (mem_fun (*this, &PluginSelector::filter_button_clicked)); - filter_mode.signal_changed().connect (mem_fun (*this, &PluginSelector::filter_mode_changed)); + filter_entry.signal_changed().connect (sigc::mem_fun (*this, &PluginSelector::filter_entry_changed)); + filter_button.signal_clicked().connect (sigc::mem_fun (*this, &PluginSelector::filter_button_clicked)); + filter_mode.signal_changed().connect (sigc::mem_fun (*this, &PluginSelector::filter_mode_changed)); filter_box->show (); filter_mode.show (); @@ -148,13 +164,13 @@ PluginSelector::PluginSelector (PluginManager *mgr) table->attach (*filter_box, 0, 7, 5, 6, FILL|EXPAND, FILL, 5, 5); - table->attach(*btn_add, 1, 2, 6, 7, FILL, FILL, 5, 5); + table->attach(*btn_add, 1, 2, 6, 7, FILL, FILL, 5, 5); table->attach(*btn_remove, 3, 4, 6, 7, FILL, FILL, 5, 5); table->attach(*btn_update, 5, 6, 6, 7, FILL, FILL, 5, 5); table->attach(ascroller, 0, 7, 8, 10); - add_button (Stock::CANCEL, RESPONSE_CANCEL); + add_button (Stock::CLOSE, RESPONSE_CLOSE); add_button (_("Insert Plugin(s)"), RESPONSE_APPLY); set_default_response (RESPONSE_APPLY); set_response_sensitive (RESPONSE_APPLY, false); @@ -165,34 +181,28 @@ PluginSelector::PluginSelector (PluginManager *mgr) //plugin_display.set_name("PluginSelectorList"); added_list.set_name("PluginSelectorList"); - plugin_display.signal_button_press_event().connect_notify (mem_fun(*this, &PluginSelector::row_clicked)); - plugin_display.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::display_selection_changed)); + plugin_display.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &PluginSelector::row_clicked)); + plugin_display.get_selection()->signal_changed().connect (sigc::mem_fun(*this, &PluginSelector::display_selection_changed)); plugin_display.grab_focus(); - - btn_update->signal_clicked().connect (mem_fun(*this, &PluginSelector::btn_update_clicked)); - btn_add->signal_clicked().connect(mem_fun(*this, &PluginSelector::btn_add_clicked)); - btn_remove->signal_clicked().connect(mem_fun(*this, &PluginSelector::btn_remove_clicked)); - added_list.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::added_list_selection_changed)); + + btn_update->signal_clicked().connect (sigc::mem_fun(*this, &PluginSelector::btn_update_clicked)); + btn_add->signal_clicked().connect(sigc::mem_fun(*this, &PluginSelector::btn_add_clicked)); + btn_remove->signal_clicked().connect(sigc::mem_fun(*this, &PluginSelector::btn_remove_clicked)); + added_list.get_selection()->signal_changed().connect (sigc::mem_fun(*this, &PluginSelector::added_list_selection_changed)); refill (); } -void -PluginSelector::row_clicked(GdkEventButton* event) +PluginSelector::~PluginSelector () { - if (event->type == GDK_2BUTTON_PRESS) - btn_add_clicked(); + delete _plugin_menu; } void -PluginSelector::set_session (Session* s) +PluginSelector::row_clicked(GdkEventButton* event) { - ENSURE_GUI_THREAD(bind (mem_fun(*this, &PluginSelector::set_session), s)); - - session = s; - - if (session) { - session->GoingAway.connect (bind (mem_fun(*this, &PluginSelector::set_session), static_cast (0))); + if (event->type == GDK_2BUTTON_PRESS) { + btn_add_clicked(); } } @@ -203,20 +213,48 @@ PluginSelector::show_this_plugin (const PluginInfoPtr& info, const std::string& std::string mode = filter_mode.get_active_text (); if (mode == _("Favorites only")) { - return manager->is_a_favorite_plugin (info); + return manager.get_status (info) == PluginManager::Favorite; + } + + if (mode == _("Hidden only")) { + return manager.get_status (info) == PluginManager::Hidden; } if (!filterstr.empty()) { - + if (mode == _("Name contains")) { compstr = info->name; - } else if (mode == _("Type contains")) { + } else if (mode == _("Category contains")) { compstr = info->category; + } else if (mode == _("Type contains")) { + + switch (info->type) { + case LADSPA: + compstr = X_("LADSPA"); + break; + case AudioUnit: + compstr = X_("AudioUnit"); + break; + case LV2: + compstr = X_("LV2"); + break; + case VST: + compstr = X_("VST"); + break; + case LXVST: + compstr = X_("LXVST"); + break; + } + } else if (mode == _("Author contains")) { compstr = info->creator; } else if (mode == _("Library contains")) { compstr = info->path; - } + } + + if (compstr.empty()) { + return false; + } transform (compstr.begin(), compstr.end(), compstr.begin(), ::toupper); @@ -235,7 +273,7 @@ PluginSelector::setup_filter_string (string& filterstr) { filterstr = filter_entry.get_text (); transform (filterstr.begin(), filterstr.end(), filterstr.begin(), ::toupper); -} +} void PluginSelector::refill () @@ -251,6 +289,7 @@ PluginSelector::refill () ladspa_refiller (filterstr); lv2_refiller (filterstr); vst_refiller (filterstr); + lxvst_refiller (filterstr); au_refiller (filterstr); in_row_change = false; @@ -266,7 +305,8 @@ PluginSelector::refiller (const PluginInfoList& plugs, const::std::string& filte if (show_this_plugin (*i, filterstr)) { TreeModel::Row newrow = *(plugin_model->append()); - newrow[plugin_columns.favorite] = manager->is_a_favorite_plugin (*i); + newrow[plugin_columns.favorite] = (manager.get_status (*i) == PluginManager::Favorite); + newrow[plugin_columns.hidden] = (manager.get_status (*i) == PluginManager::Hidden); newrow[plugin_columns.name] = (*i)->name; newrow[plugin_columns.type_name] = type; newrow[plugin_columns.category] = (*i)->category; @@ -281,68 +321,79 @@ PluginSelector::refiller (const PluginInfoList& plugs, const::std::string& filte newrow[plugin_columns.creator] = creator; - if ((*i)->n_inputs.n_total() < 0) { - newrow[plugin_columns.audio_ins] = "various"; - newrow[plugin_columns.midi_ins] = "various"; - } else { - snprintf (buf, sizeof(buf), "%d", (*i)->n_inputs.n_audio()); - newrow[plugin_columns.audio_ins] = buf; - snprintf (buf, sizeof(buf), "%d", (*i)->n_inputs.n_midi()); - newrow[plugin_columns.midi_ins] = buf; - } - if ((*i)->n_outputs.n_total() < 0) { - newrow[plugin_columns.audio_outs] = "various"; - newrow[plugin_columns.midi_outs] = "various"; - } else { - snprintf (buf, sizeof(buf), "%d", (*i)->n_outputs.n_audio()); - newrow[plugin_columns.audio_outs] = buf; - snprintf (buf, sizeof(buf), "%d", (*i)->n_outputs.n_midi()); - newrow[plugin_columns.midi_outs] = buf; - } + snprintf (buf, sizeof(buf), "%d", (*i)->n_inputs.n_audio()); + newrow[plugin_columns.audio_ins] = buf; + snprintf (buf, sizeof(buf), "%d", (*i)->n_inputs.n_midi()); + newrow[plugin_columns.midi_ins] = buf; + + snprintf (buf, sizeof(buf), "%d", (*i)->n_outputs.n_audio()); + newrow[plugin_columns.audio_outs] = buf; + snprintf (buf, sizeof(buf), "%d", (*i)->n_outputs.n_midi()); + newrow[plugin_columns.midi_outs] = buf; newrow[plugin_columns.plugin] = *i; } - } + } } void PluginSelector::ladspa_refiller (const std::string& filterstr) { - refiller (manager->ladspa_plugin_info(), filterstr, "LADSPA"); + refiller (manager.ladspa_plugin_info(), filterstr, "LADSPA"); } void PluginSelector::lv2_refiller (const std::string& filterstr) { -#ifdef HAVE_LV2 - refiller (manager->lv2_plugin_info(), filterstr, "LV2"); +#ifdef LV2_SUPPORT + refiller (manager.lv2_plugin_info(), filterstr, "LV2"); #endif } void +#ifdef VST_SUPPORT PluginSelector::vst_refiller (const std::string& filterstr) +#else +PluginSelector::vst_refiller (const std::string&) +#endif { #ifdef VST_SUPPORT - refiller (manager->vst_plugin_info(), filterstr, "VST"); + refiller (manager.vst_plugin_info(), filterstr, "VST"); +#endif +} + +void +#ifdef LXVST_SUPPORT +PluginSelector::lxvst_refiller (const std::string& filterstr) +#else +PluginSelector::lxvst_refiller (const std::string&) +#endif +{ +#ifdef LXVST_SUPPORT + refiller (manager.lxvst_plugin_info(), filterstr, "LXVST"); #endif } void +#ifdef AUDIOUNIT_SUPPORT PluginSelector::au_refiller (const std::string& filterstr) +#else +PluginSelector::au_refiller (const std::string&) +#endif { -#ifdef HAVE_AUDIOUNITS - refiller (manager->au_plugin_info(), filterstr, "AU"); +#ifdef AUDIOUNIT_SUPPORT + refiller (manager.au_plugin_info(), filterstr, "AU"); #endif } PluginPtr PluginSelector::load_plugin (PluginInfoPtr pi) { - if (session == 0) { + if (_session == 0) { return PluginPtr(); } - return pi->load (*session); + return pi->load (*_session); } void @@ -369,7 +420,7 @@ void PluginSelector::btn_remove_clicked() { TreeModel::iterator iter = added_list.get_selection()->get_selected(); - + amodel->erase(iter); if (amodel->children().empty()) { set_response_sensitive (RESPONSE_APPLY, false); @@ -379,7 +430,7 @@ PluginSelector::btn_remove_clicked() void PluginSelector::btn_update_clicked() { - manager->refresh (); + manager.refresh (); refill(); } @@ -408,29 +459,39 @@ PluginSelector::run () { ResponseType r; TreeModel::Children::iterator i; - SelectedPlugins plugins; - r = (ResponseType) Dialog::run (); + bool finish = false; + + while (!finish) { - switch (r) { - case RESPONSE_APPLY: - for (i = amodel->children().begin(); i != amodel->children().end(); ++i) { - PluginInfoPtr pp = (*i)[acols.plugin]; - PluginPtr p = load_plugin (pp); - if (p) { - plugins.push_back (p); + SelectedPlugins plugins; + r = (ResponseType) Dialog::run (); + + switch (r) { + case RESPONSE_APPLY: + for (i = amodel->children().begin(); i != amodel->children().end(); ++i) { + PluginInfoPtr pp = (*i)[acols.plugin]; + PluginPtr p = load_plugin (pp); + if (p) { + plugins.push_back (p); + } else { + MessageDialog msg (string_compose (_("The plugin \"%1\" could not be loaded\n\nSee the Log window for more details (maybe)"), pp->name)); + msg.run (); + } } - } - if (interested_object && !plugins.empty()) { - interested_object->use_plugins (plugins); - } - - break; + if (interested_object && !plugins.empty()) { + finish = !interested_object->use_plugins (plugins); + } + + break; - default: - break; + default: + finish = true; + break; + } } + hide(); amodel->clear(); interested_object = 0; @@ -450,12 +511,12 @@ PluginSelector::filter_entry_changed () refill (); } -void +void PluginSelector::filter_mode_changed () { std::string mode = filter_mode.get_active_text (); - if (mode == _("Favorites only")) { + if (mode == _("Favorites only") || mode == _("Hidden only")) { filter_entry.set_sensitive (false); } else { filter_entry.set_sensitive (true); @@ -471,7 +532,7 @@ PluginSelector::on_show () filter_entry.grab_focus (); } -struct PluginMenuCompare { +struct PluginMenuCompareByCreator { bool operator() (PluginInfoPtr a, PluginInfoPtr b) const { int cmp; @@ -483,79 +544,191 @@ struct PluginMenuCompare { /* same creator ... compare names */ if (strcasecmp (a->name.c_str(), b->name.c_str()) < 0) { return true; - } + } } return false; } }; -Gtk::Menu& -PluginSelector::plugin_menu() -{ - using namespace Menu_Helpers; +struct PluginMenuCompareByName { + bool operator() (PluginInfoPtr a, PluginInfoPtr b) const { + int cmp; - typedef std::map SubmenuMap; - SubmenuMap submenu_map; + cmp = strcasecmp (a->name.c_str(), b->name.c_str()); - if (!_menu) { - _menu = new Menu(); - _menu->set_name("ArdourContextMenu"); - } + if (cmp < 0) { + return true; + } else if (cmp == 0) { + /* same name ... compare type */ + if (a->type < b->type) { + return true; + } + } + return false; + } +}; - MenuList& items = _menu->items(); - Menu* favs = new Menu(); - favs->set_name("ArdourContextMenu"); +struct PluginMenuCompareByCategory { + bool operator() (PluginInfoPtr a, PluginInfoPtr b) const { + int cmp; - items.clear (); - items.push_back (MenuElem (_("Favorites"), *favs)); - items.push_back (MenuElem (_("Plugin Manager"), mem_fun (*this, &PluginSelector::show_manager))); - items.push_back (SeparatorElem ()); + cmp = strcasecmp (a->category.c_str(), b->category.c_str()); + if (cmp < 0) { + return true; + } else if (cmp == 0) { + /* same category ... compare names */ + if (strcasecmp (a->name.c_str(), b->name.c_str()) < 0) { + return true; + } + } + return false; + } +}; + +/** @return Plugin menu. The caller should not delete it */ +Gtk::Menu* +PluginSelector::plugin_menu() +{ + return _plugin_menu; +} + +void +PluginSelector::build_plugin_menu () +{ PluginInfoList all_plugs; - all_plugs.insert (all_plugs.end(), manager->ladspa_plugin_info().begin(), manager->ladspa_plugin_info().end()); + all_plugs.insert (all_plugs.end(), manager.ladspa_plugin_info().begin(), manager.ladspa_plugin_info().end()); #ifdef VST_SUPPORT - all_plugs.insert (all_plugs.end(), manager->vst_plugin_info().begin(), manager->vst_plugin_info().end()); + all_plugs.insert (all_plugs.end(), manager.vst_plugin_info().begin(), manager.vst_plugin_info().end()); +#endif +#ifdef LXVST_SUPPORT + all_plugs.insert (all_plugs.end(), manager.lxvst_plugin_info().begin(), manager.lxvst_plugin_info().end()); #endif -#ifdef HAVE_AUDIOUNITS - all_plugs.insert (all_plugs.end(), manager->au_plugin_info().begin(), manager->au_plugin_info().end()); +#ifdef AUDIOUNIT_SUPPORT + all_plugs.insert (all_plugs.end(), manager.au_plugin_info().begin(), manager.au_plugin_info().end()); #endif -#ifdef HAVE_LV2 - all_plugs.insert (all_plugs.end(), manager->lv2_plugin_info().begin(), manager->lv2_plugin_info().end()); +#ifdef LV2_SUPPORT + all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end()); #endif - PluginMenuCompare cmp; - all_plugs.sort (cmp); + using namespace Menu_Helpers; + + delete _plugin_menu; + + _plugin_menu = manage (new Menu); + _plugin_menu->set_name("ArdourContextMenu"); + + MenuList& items = _plugin_menu->items(); + items.clear (); + + Gtk::Menu* favs = create_favs_menu(all_plugs); + items.push_back (MenuElem (_("Favorites"), *manage (favs))); + + items.push_back (MenuElem (_("Plugin Manager..."), sigc::mem_fun (*this, &PluginSelector::show_manager))); + items.push_back (SeparatorElem ()); + + Menu* by_creator = create_by_creator_menu(all_plugs); + items.push_back (MenuElem (_("By Creator"), *manage (by_creator))); + + Menu* by_category = create_by_category_menu(all_plugs); + items.push_back (MenuElem (_("By Category"), *manage (by_category))); +} + +Gtk::Menu* +PluginSelector::create_favs_menu (PluginInfoList& all_plugs) +{ + using namespace Menu_Helpers; + + Menu* favs = new Menu(); + favs->set_name("ArdourContextMenu"); + + PluginMenuCompareByName cmp_by_name; + all_plugs.sort (cmp_by_name); for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) { - SubmenuMap::iterator x; - Gtk::Menu* submenu; + if (manager.get_status (*i) == PluginManager::Favorite) { + favs->items().push_back (MenuElem ((*i)->name, (sigc::bind (sigc::mem_fun (*this, &PluginSelector::plugin_chosen_from_menu), *i)))); + } + } + return favs; +} + +Gtk::Menu* +PluginSelector::create_by_creator_menu (ARDOUR::PluginInfoList& all_plugs) +{ + using namespace Menu_Helpers; + + typedef std::map SubmenuMap; + SubmenuMap creator_submenu_map; + + Menu* by_creator = new Menu(); + by_creator->set_name("ArdourContextMenu"); + + MenuList& by_creator_items = by_creator->items(); + PluginMenuCompareByCreator cmp_by_creator; + all_plugs.sort (cmp_by_creator); + + for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) { + + if (manager.get_status (*i) == PluginManager::Hidden) continue; string creator = (*i)->creator; - string::size_type pos = 0; - if (manager->is_a_favorite_plugin (*i)) { - favs->items().push_back (MenuElem ((*i)->name, (bind (mem_fun (*this, &PluginSelector::plugin_chosen_from_menu), *i)))); - } - /* stupid LADSPA creator strings */ - + string::size_type pos = 0; while (pos < creator.length() && (isalnum (creator[pos]) || isspace (creator[pos]))) ++pos; creator = creator.substr (0, pos); - if ((x = submenu_map.find (creator)) != submenu_map.end()) { + SubmenuMap::iterator x; + Gtk::Menu* submenu; + if ((x = creator_submenu_map.find (creator)) != creator_submenu_map.end()) { + submenu = x->second; + } else { + submenu = new Gtk::Menu; + by_creator_items.push_back (MenuElem (creator, *manage (submenu))); + creator_submenu_map.insert (pair (creator, submenu)); + submenu->set_name("ArdourContextMenu"); + } + submenu->items().push_back (MenuElem ((*i)->name, (sigc::bind (sigc::mem_fun (*this, &PluginSelector::plugin_chosen_from_menu), *i)))); + } + return by_creator; +} + +Gtk::Menu* +PluginSelector::create_by_category_menu (ARDOUR::PluginInfoList& all_plugs) +{ + using namespace Menu_Helpers; + + typedef std::map SubmenuMap; + SubmenuMap category_submenu_map; + + Menu* by_category = new Menu(); + by_category->set_name("ArdourContextMenu"); + + MenuList& by_category_items = by_category->items(); + PluginMenuCompareByCategory cmp_by_category; + all_plugs.sort (cmp_by_category); + + for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) { + + if (manager.get_status (*i) == PluginManager::Hidden) continue; + + string category = (*i)->category; + + SubmenuMap::iterator x; + Gtk::Menu* submenu; + if ((x = category_submenu_map.find (category)) != category_submenu_map.end()) { submenu = x->second; } else { submenu = new Gtk::Menu; - items.push_back (MenuElem (creator, *submenu)); - submenu_map.insert (pair (creator, submenu)); + by_category_items.push_back (MenuElem (category, *manage (submenu))); + category_submenu_map.insert (pair (category, submenu)); submenu->set_name("ArdourContextMenu"); } - - submenu->items().push_back (MenuElem ((*i)->name, (bind (mem_fun (*this, &PluginSelector::plugin_chosen_from_menu), *i)))); + submenu->items().push_back (MenuElem ((*i)->name, (sigc::bind (sigc::mem_fun (*this, &PluginSelector::plugin_chosen_from_menu), *i)))); } - - return *_menu; + return by_category; } void @@ -572,8 +745,8 @@ PluginSelector::plugin_chosen_from_menu (const PluginInfoPtr& pi) interested_object = 0; } -void -PluginSelector::favorite_changed (const Glib::ustring& path) +void +PluginSelector::favorite_changed (const std::string& path) { PluginInfoPtr pi; @@ -582,9 +755,9 @@ PluginSelector::favorite_changed (const Glib::ustring& path) } in_row_change = true; - + TreeModel::iterator iter = plugin_model->get_iter (path); - + if (iter) { bool favorite = !(*iter)[plugin_columns.favorite]; @@ -592,18 +765,52 @@ PluginSelector::favorite_changed (const Glib::ustring& path) /* change state */ (*iter)[plugin_columns.favorite] = favorite; + (*iter)[plugin_columns.hidden] = false; + PluginManager::PluginStatusType status = (favorite ? PluginManager::Favorite : PluginManager::Normal); - /* save new favorites list */ + /* save new statuses list */ pi = (*iter)[plugin_columns.plugin]; - - if (favorite) { - manager->add_favorite (pi->type, pi->unique_id); - } else { - manager->remove_favorite (pi->type, pi->unique_id); - } - - manager->save_favorites (); + + manager.set_status (pi->type, pi->unique_id, status); + + manager.save_statuses (); + + build_plugin_menu (); + } + in_row_change = false; +} + +void +PluginSelector::hidden_changed (const std::string& path) +{ + PluginInfoPtr pi; + + if (in_row_change) { + return; + } + + in_row_change = true; + + TreeModel::iterator iter = plugin_model->get_iter (path); + + if (iter) { + + bool hidden = !(*iter)[plugin_columns.hidden]; + + /* change state */ + + (*iter)[plugin_columns.favorite] = false; + (*iter)[plugin_columns.hidden] = hidden; + PluginManager::PluginStatusType status = (hidden ? PluginManager::Hidden : PluginManager::Normal); + + /* save new statuses list */ + + pi = (*iter)[plugin_columns.plugin]; + + manager.set_status (pi->type, pi->unique_id, status); + + manager.save_statuses (); } in_row_change = false; }