X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fplugin_selector.cc;h=e1aa19588279d772a218e607d2aab3bfc1d22fdc;hb=c2c224727eee4c16bd64ca4a5b5bb2d276f5afe3;hp=e0a62b177f18711ed8f759036e018dfbee28cb62;hpb=ab6f1ed9bafa869648b6e94ee5186ff317b32c3e;p=ardour.git diff --git a/gtk2_ardour/plugin_selector.cc b/gtk2_ardour/plugin_selector.cc index e0a62b177f..e1aa195882 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,18 +16,29 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#ifdef WAF_BUILD +#include "gtk2ardour-config.h" +#endif #include #include +#include + +#include #include #include #include #include -#include -#include -#include +#include + +#include "pbd/convert.h" + +#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" @@ -38,317 +49,334 @@ using namespace ARDOUR; using namespace PBD; using namespace Gtk; +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) + : ArdourDialog (_("ardour: plugins"), true, false), + filter_button (Stock::CLEAR) { set_position (Gtk::WIN_POS_MOUSE); set_name ("PluginSelectorWindow"); add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK); + _plugin_menu = 0; manager = mgr; - session = 0; - - current_selection = PluginInfo::LADSPA; - - lmodel = Gtk::ListStore::create(lcols); - ladspa_display.set_model (lmodel); - ladspa_display.append_column (_("Available LADSPA Plugins"), lcols.name); - ladspa_display.append_column (_("Type"), lcols.type); - ladspa_display.append_column (_("# Inputs"),lcols.ins); - ladspa_display.append_column (_("# Outputs"), lcols.outs); - ladspa_display.set_headers_visible (true); - ladspa_display.set_reorderable (false); - lscroller.set_border_width(10); - lscroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); - lscroller.add(ladspa_display); + in_row_change = false; + + manager->PluginListChanged.connect (plugin_list_changed_connection, 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" 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); + plugin_display.append_column (_("Creator"), plugin_columns.creator); + plugin_display.append_column (_("# Audio In"),plugin_columns.audio_ins); + plugin_display.append_column (_("# Audio Out"), plugin_columns.audio_outs); + plugin_display.append_column (_("# MIDI In"),plugin_columns.midi_ins); + plugin_display.append_column (_("# MIDI Out"), plugin_columns.midi_outs); + plugin_display.set_headers_visible (true); + plugin_display.set_headers_clickable (true); + plugin_display.set_reorderable (false); + plugin_display.set_rules_hint (true); + + CellRendererToggle* fav_cell = dynamic_cast(plugin_display.get_column_cell_renderer (0)); + fav_cell->property_activatable() = true; + 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); + scroller.add(plugin_display); amodel = Gtk::ListStore::create(acols); added_list.set_model (amodel); - added_list.append_column (_("Plugins to be Connected to Insert"), acols.text); + added_list.append_column (_("Plugins to be connected"), acols.text); added_list.set_headers_visible (true); added_list.set_reorderable (false); - for (int i = 0; i <=3; i++) { - Gtk::TreeView::Column* column = ladspa_display.get_column(i); - column->set_sort_column(i); - } - -#ifdef VST_SUPPORT - vmodel = ListStore::create(vcols); - vst_display.set_model (vmodel); - vst_display.append_column (_("Available plugins"), vcols.name); - vst_display.append_column (_("# Inputs"), vcols.ins); - vst_display.append_column (_("# Outputs"), vcols.outs); - vst_display.set_headers_visible (true); - vst_display.set_reorderable (false); - vscroller.set_border_width(10); - vscroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); - vscroller.add(vst_display); - - for (int i = 0; i <=2; i++) { - Gtk::TreeView::Column* column = vst_display.get_column(i); - column->set_sort_column(i); - } -#endif - -#ifdef HAVE_COREAUDIO - aumodel = ListStore::create(aucols); - au_display.set_model (aumodel); - au_display.append_column (_("Available plugins"), aucols.name); - au_display.append_column (_("# Inputs"), aucols.ins); - au_display.append_column (_("# Outputs"), aucols.outs); - au_display.set_headers_visible (true); - au_display.set_reorderable (false); - auscroller.set_border_width(10); - auscroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); - auscroller.add(au_display); - - for (int i = 0; i <=2; i++) { - Gtk::TreeView::Column* column = au_display.get_column(i); + for (int i = 0; i <=8; i++) { + Gtk::TreeView::Column* column = plugin_display.get_column(i); column->set_sort_column(i); } -#endif ascroller.set_border_width(10); 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"); - Gtk::Table* table = manage(new Gtk::Table(7, 10)); + Gtk::Table* table = manage(new Gtk::Table(7, 11)); table->set_size_request(750, 500); - table->attach(notebook, 0, 7, 0, 5); + table->attach(scroller, 0, 7, 0, 5); - table->attach(*btn_add, 1, 2, 5, 6, Gtk::FILL, Gtk::FILL, 5, 5); - table->attach(*btn_remove, 3, 4, 5, 6, Gtk::FILL, Gtk::FILL, 5, 5); - table->attach(*btn_update, 5, 6, 5, 6, Gtk::FILL, Gtk::FILL, 5, 5); + HBox* filter_box = manage (new HBox); - table->attach(ascroller, 0, 7, 7, 9); + vector filter_strings = I18N (_filter_mode_strings); + Gtkmm2ext::set_popdown_strings (filter_mode, filter_strings); + filter_mode.set_active_text (filter_strings.front()); - add_button (Stock::CANCEL, RESPONSE_CANCEL); - add_button (Stock::CONNECT, RESPONSE_APPLY); - set_default_response (RESPONSE_APPLY); - set_response_sensitive (RESPONSE_APPLY, false); - get_vbox()->pack_start (*table); + filter_box->pack_start (filter_mode, false, false); + filter_box->pack_start (filter_entry, true, true); + filter_box->pack_start (filter_button, false, false); - using namespace Gtk::Notebook_Helpers; - notebook.pages().push_back (TabElem (lscroller, _("LADSPA"))); + 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)); -#ifdef VST_SUPPORT - if (Config->get_use_vst()) { - notebook.pages().push_back (TabElem (vscroller, _("VST"))); - } -#endif + filter_box->show (); + filter_mode.show (); + filter_entry.show (); + filter_button.show (); -#ifdef HAVE_COREAUDIO - notebook.pages().push_back (TabElem (auscroller, _("AudioUnit"))); -#endif + 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_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::CLOSE, RESPONSE_CLOSE); + add_button (_("Insert Plugin(s)"), RESPONSE_APPLY); + set_default_response (RESPONSE_APPLY); + set_response_sensitive (RESPONSE_APPLY, false); + get_vbox()->pack_start (*table); table->set_name("PluginSelectorTable"); - ladspa_display.set_name("PluginSelectorDisplay"); - //ladspa_display.set_name("PluginSelectorList"); + plugin_display.set_name("PluginSelectorDisplay"); + //plugin_display.set_name("PluginSelectorList"); added_list.set_name("PluginSelectorList"); - ladspa_display.signal_button_press_event().connect_notify (mem_fun(*this, &PluginSelector::row_clicked)); - ladspa_display.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::ladspa_display_selection_changed)); - -#ifdef VST_SUPPORT - if (Config->get_use_vst()) { - vst_display.signal_button_press_event().connect_notify (mem_fun(*this, &PluginSelector::row_clicked)); - vst_display.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::vst_display_selection_changed)); - } -#endif + 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(); -#ifdef HAVE_COREAUDIO - au_display.signal_button_press_event().connect_notify (mem_fun(*this, &PluginSelector::row_clicked)); - au_display.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::au_display_selection_changed)); -#endif - - 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)); - input_refiller (); - -#ifdef VST_SUPPORT - vst_refiller (); -#endif + refill (); +} -#ifdef HAVE_COREAUDIO - au_refiller (); -#endif +PluginSelector::~PluginSelector () +{ + delete _plugin_menu; } void PluginSelector::row_clicked(GdkEventButton* event) { - if (event->type == GDK_2BUTTON_PRESS) + if (event->type == GDK_2BUTTON_PRESS) { btn_add_clicked(); + } } -void -PluginSelector::set_session (Session* s) +bool +PluginSelector::show_this_plugin (const PluginInfoPtr& info, const std::string& filterstr) { - ENSURE_GUI_THREAD(bind (mem_fun(*this, &PluginSelector::set_session), s)); - - session = s; + std::string compstr; + std::string mode = filter_mode.get_active_text (); - if (session) { - session->going_away.connect (bind (mem_fun(*this, &PluginSelector::set_session), static_cast (0))); + if (mode == _("Favorites only")) { + return manager->get_status (info) == PluginManager::Favorite; } -} -void -PluginSelector::_input_refiller (void *arg) -{ - ((PluginSelector *) arg)->input_refiller (); -} + if (mode == _("Hidden only")) { + return manager->get_status (info) == PluginManager::Hidden; + } -int compare(const void *left, const void *right) -{ - return strcmp(*((char**)left), *((char**)right)); -} + if (!filterstr.empty()) { + + if (mode == _("Name contains")) { + compstr = info->name; + } 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; + } + + } else if (mode == _("Author contains")) { + compstr = info->creator; + } else if (mode == _("Library contains")) { + compstr = info->path; + } -void -PluginSelector::input_refiller () -{ - guint row; - PluginInfoList &plugs = manager->ladspa_plugin_info (); - PluginInfoList::iterator i; - char ibuf[16], obuf[16]; - lmodel->clear(); - - // Insert into GTK list - for (row = 0, i=plugs.begin(); i != plugs.end(); ++i, ++row) { - snprintf (ibuf, sizeof(ibuf)-1, "%d", (*i)->n_inputs); - snprintf (obuf, sizeof(obuf)-1, "%d", (*i)->n_outputs); - - Gtk::TreeModel::Row newrow = *(lmodel->append()); - newrow[lcols.name] = (*i)->name.c_str(); - newrow[lcols.type] = (*i)->category.c_str(); - newrow[lcols.ins] = ibuf; - newrow[lcols.outs] = obuf; - newrow[lcols.plugin] = *i; + if (compstr.empty()) { + return false; + } + + transform (compstr.begin(), compstr.end(), compstr.begin(), ::toupper); + + if (compstr.find (filterstr) != string::npos) { + return true; + } else { + return false; + } } - lmodel->set_sort_column (0, Gtk::SORT_ASCENDING); + return true; } -#ifdef VST_SUPPORT - void -PluginSelector::_vst_refiller (void *arg) +PluginSelector::setup_filter_string (string& filterstr) { - ((PluginSelector *) arg)->vst_refiller (); + filterstr = filter_entry.get_text (); + transform (filterstr.begin(), filterstr.end(), filterstr.begin(), ::toupper); } void -PluginSelector::vst_refiller () +PluginSelector::refill () { - guint row; - PluginInfoList &plugs = manager->vst_plugin_info (); - PluginInfoList::iterator i; - char ibuf[16], obuf[16]; - vmodel->clear(); - - // Insert into GTK list - for (row = 0, i=plugs.begin(); i != plugs.end(); ++i, ++row) { - - snprintf (ibuf, sizeof(ibuf)-1, "%d", (*i)->n_inputs); - snprintf (obuf, sizeof(obuf)-1, "%d", (*i)->n_outputs); - - Gtk::TreeModel::Row newrow = *(vmodel->append()); - newrow[vcols.name] = (*i)->name.c_str(); - newrow[vcols.ins] = ibuf; - newrow[vcols.outs] = obuf; - newrow[vcols.plugin] = *i; - } - vmodel->set_sort_column (0, Gtk::SORT_ASCENDING); + std::string filterstr; + + in_row_change = true; + + plugin_model->clear (); + + setup_filter_string (filterstr); + + ladspa_refiller (filterstr); + lv2_refiller (filterstr); + vst_refiller (filterstr); + au_refiller (filterstr); + + in_row_change = false; } void -PluginSelector::vst_display_selection_changed() +PluginSelector::refiller (const PluginInfoList& plugs, const::std::string& filterstr, const char* type) { - if (vst_display.get_selection()->count_selected_rows() != 0) { - btn_add->set_sensitive (true); - } else { - btn_add->set_sensitive (false); - } + char buf[16]; - current_selection = PluginInfo::VST; -} + for (PluginInfoList::const_iterator i = plugs.begin(); i != plugs.end(); ++i) { + + if (show_this_plugin (*i, filterstr)) { + + 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); + newrow[plugin_columns.name] = (*i)->name; + newrow[plugin_columns.type_name] = type; + newrow[plugin_columns.category] = (*i)->category; + + string creator = (*i)->creator; + string::size_type pos = 0; + + /* stupid LADSPA creator strings */ + + while (pos < creator.length() && (isalnum (creator[pos]) || isspace (creator[pos]))) ++pos; + creator = creator.substr (0, pos); + + newrow[plugin_columns.creator] = creator; + + 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; -#endif //VST_SUPPORT + 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; -#ifdef HAVE_COREAUDIO + newrow[plugin_columns.plugin] = *i; + } + } +} void -PluginSelector::_au_refiller (void *arg) +PluginSelector::ladspa_refiller (const std::string& filterstr) { - ((PluginSelector *) arg)->au_refiller (); + refiller (manager->ladspa_plugin_info(), filterstr, "LADSPA"); } void -PluginSelector::au_refiller () +PluginSelector::lv2_refiller (const std::string& filterstr) { - guint row; - PluginInfoList plugs (AUPluginInfo::discover ()); - PluginInfoList::iterator i; - char ibuf[16], obuf[16]; - aumodel->clear(); - - // Insert into GTK list - for (row = 0, i=plugs.begin(); i != plugs.end(); ++i, ++row) { - - snprintf (ibuf, sizeof(ibuf)-1, "%d", (*i)->n_inputs); - snprintf (obuf, sizeof(obuf)-1, "%d", (*i)->n_outputs); - - Gtk::TreeModel::Row newrow = *(aumodel->append()); - newrow[aucols.name] = (*i)->name.c_str(); - newrow[aucols.ins] = ibuf; - newrow[aucols.outs] = obuf; - newrow[aucols.plugin] = *i; - } - aumodel->set_sort_column (0, Gtk::SORT_ASCENDING); +#ifdef HAVE_SLV2 + refiller (manager->lv2_plugin_info(), filterstr, "LV2"); +#endif } void -PluginSelector::au_display_selection_changed() +#ifdef VST_SUPPORT +PluginSelector::vst_refiller (const std::string& filterstr) +#else +PluginSelector::vst_refiller (const std::string&) +#endif { - if (au_display.get_selection()->count_selected_rows() != 0) { - btn_add->set_sensitive (true); - } else { - btn_add->set_sensitive (false); - } - - current_selection = PluginInfo::AudioUnit; +#ifdef VST_SUPPORT + refiller (manager->vst_plugin_info(), filterstr, "VST"); +#endif } -#endif //HAVE_COREAUDIO - void -PluginSelector::use_plugin (PluginInfoPtr pi) +#ifdef HAVE_AUDIOUNITS +PluginSelector::au_refiller (const std::string& filterstr) +#else +PluginSelector::au_refiller (const std::string&) +#endif { - if (session == 0) { - return; - } - - PluginPtr plugin = pi->load (*session); +#ifdef HAVE_AUDIOUNITS + refiller (manager->au_plugin_info(), filterstr, "AU"); +#endif +} - if (plugin) { - PluginCreated (plugin); +PluginPtr +PluginSelector::load_plugin (PluginInfoPtr pi) +{ + if (_session == 0) { + return PluginPtr(); } + + return pi->load (*_session); } void @@ -356,34 +384,12 @@ PluginSelector::btn_add_clicked() { std::string name; PluginInfoPtr pi; - Gtk::TreeModel::Row newrow = *(amodel->append()); - - Gtk::TreeModel::Row row; - - switch (current_selection) { - case PluginInfo::LADSPA: - row = *(ladspa_display.get_selection()->get_selected()); - name = row[lcols.name]; - pi = row[lcols.plugin]; - break; - case PluginInfo::VST: -#ifdef VST_SUPPORT - row = *(vst_display.get_selection()->get_selected()); - name = row[vcols.name]; - pi = row[vcols.plugin]; -#endif - break; - case PluginInfo::AudioUnit: -#ifdef HAVE_COREAUDIO - row = *(au_display.get_selection()->get_selected()); - name = row[aucols.name]; - pi = row[aucols.plugin]; -#endif - break; - default: - error << "Programming error. Unknown plugin selected." << endmsg; - return; - } + TreeModel::Row newrow = *(amodel->append()); + TreeModel::Row row; + + row = *(plugin_display.get_selection()->get_selected()); + name = row[plugin_columns.name]; + pi = row[plugin_columns.plugin]; newrow[acols.text] = name; newrow[acols.plugin] = pi; @@ -396,8 +402,8 @@ PluginSelector::btn_add_clicked() void PluginSelector::btn_remove_clicked() { - Gtk::TreeModel::iterator iter = added_list.get_selection()->get_selected(); - + TreeModel::iterator iter = added_list.get_selection()->get_selected(); + amodel->erase(iter); if (amodel->children().empty()) { set_response_sensitive (RESPONSE_APPLY, false); @@ -408,35 +414,27 @@ void PluginSelector::btn_update_clicked() { manager->refresh (); - input_refiller (); -#ifdef VST_SUPPORT - vst_refiller (); -#endif -#ifdef HAVE_COREAUDIO - au_refiller (); -#endif + refill(); } void -PluginSelector::ladspa_display_selection_changed() +PluginSelector::display_selection_changed() { - if (ladspa_display.get_selection()->count_selected_rows() != 0) { + if (plugin_display.get_selection()->count_selected_rows() != 0) { btn_add->set_sensitive (true); } else { btn_add->set_sensitive (false); } - - current_selection = PluginInfo::LADSPA; } void PluginSelector::added_list_selection_changed() { - if (added_list.get_selection()->count_selected_rows() != 0) { - btn_remove->set_sensitive (true); - } else { - btn_remove->set_sensitive (false); - } + if (added_list.get_selection()->count_selected_rows() != 0) { + btn_remove->set_sensitive (true); + } else { + btn_remove->set_sensitive (false); + } } int @@ -444,28 +442,358 @@ PluginSelector::run () { ResponseType r; TreeModel::Children::iterator i; + SelectedPlugins plugins; r = (ResponseType) Dialog::run (); switch (r) { case RESPONSE_APPLY: for (i = amodel->children().begin(); i != amodel->children().end(); ++i) { - use_plugin ((*i)[acols.plugin]); + PluginInfoPtr pp = (*i)[acols.plugin]; + PluginPtr p = load_plugin (pp); + if (p) { + plugins.push_back (p); + } + } + if (interested_object && !plugins.empty()) { + interested_object->use_plugins (plugins); } + break; default: break; } - cleanup (); + hide(); + amodel->clear(); + interested_object = 0; return (int) r; } void -PluginSelector::cleanup () +PluginSelector::filter_button_clicked () { - hide(); - amodel->clear(); + filter_entry.set_text (""); +} + +void +PluginSelector::filter_entry_changed () +{ + refill (); +} + +void +PluginSelector::filter_mode_changed () +{ + std::string mode = filter_mode.get_active_text (); + + if (mode == _("Favorites only") || mode == _("Hidden only")) { + filter_entry.set_sensitive (false); + } else { + filter_entry.set_sensitive (true); + } + + refill (); +} + +void +PluginSelector::on_show () +{ + ArdourDialog::on_show (); + filter_entry.grab_focus (); +} + +struct PluginMenuCompareByCreator { + bool operator() (PluginInfoPtr a, PluginInfoPtr b) const { + int cmp; + + cmp = strcasecmp (a->creator.c_str(), b->creator.c_str()); + + if (cmp < 0) { + return true; + } else if (cmp == 0) { + /* same creator ... compare names */ + if (strcasecmp (a->name.c_str(), b->name.c_str()) < 0) { + return true; + } + } + return false; + } +}; + +struct PluginMenuCompareByName { + bool operator() (PluginInfoPtr a, PluginInfoPtr b) const { + int cmp; + + cmp = strcasecmp (a->name.c_str(), b->name.c_str()); + + if (cmp < 0) { + return true; + } else if (cmp == 0) { + /* same name ... compare type */ + if (a->type < b->type) { + return true; + } + } + return false; + } +}; + +struct PluginMenuCompareByCategory { + bool operator() (PluginInfoPtr a, PluginInfoPtr b) const { + int cmp; + + 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()); +#ifdef VST_SUPPORT + all_plugs.insert (all_plugs.end(), manager->vst_plugin_info().begin(), manager->vst_plugin_info().end()); +#endif +#ifdef HAVE_AUDIOUNITS + all_plugs.insert (all_plugs.end(), manager->au_plugin_info().begin(), manager->au_plugin_info().end()); +#endif +#ifdef HAVE_SLV2 + all_plugs.insert (all_plugs.end(), manager->lv2_plugin_info().begin(), manager->lv2_plugin_info().end()); +#endif + + using namespace Menu_Helpers; + + delete _plugin_menu; + + _plugin_menu = 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) { + 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; + + /* 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); + + 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; + 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, (sigc::bind (sigc::mem_fun (*this, &PluginSelector::plugin_chosen_from_menu), *i)))); + } + return by_category; +} + +void +PluginSelector::plugin_chosen_from_menu (const PluginInfoPtr& pi) +{ + PluginPtr p = load_plugin (pi); + + if (p && interested_object) { + SelectedPlugins plugins; + plugins.push_back (p); + interested_object->use_plugins (plugins); + } + + interested_object = 0; +} + +void +PluginSelector::favorite_changed (const Glib::ustring& path) +{ + PluginInfoPtr pi; + + if (in_row_change) { + return; + } + + in_row_change = true; + + TreeModel::iterator iter = plugin_model->get_iter (path); + + if (iter) { + + bool favorite = !(*iter)[plugin_columns.favorite]; + + /* change state */ + + (*iter)[plugin_columns.favorite] = favorite; + (*iter)[plugin_columns.hidden] = false; + PluginManager::PluginStatusType status = (favorite ? PluginManager::Favorite : PluginManager::Normal); + + /* save new statuses list */ + + pi = (*iter)[plugin_columns.plugin]; + + manager->set_status (pi->type, pi->unique_id, status); + + manager->save_statuses (); + + build_plugin_menu (); + } + in_row_change = false; +} + +void +PluginSelector::hidden_changed (const Glib::ustring& 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; +} + +void +PluginSelector::show_manager () +{ + show_all(); + run (); +} + +void +PluginSelector::set_interested_object (PluginInterestedObject& obj) +{ + interested_object = &obj; }