Transfer Fn: skip phase calculation for silence and small signal levels
[ardour.git] / gtk2_ardour / plugin_selector.cc
index e7e804482123a5137b4b981a89dd7ed1c5feaeb0..989d4f31a3b9326982b55f9d1512cd45583b9638 100644 (file)
@@ -32,6 +32,7 @@
 #include <gtkmm/notebook.h>
 #include <gtkmm/stock.h>
 #include <gtkmm/table.h>
+#include <gtkmm/treestore.h>
 
 #include "gtkmm2ext/utils.h"
 
@@ -60,7 +61,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 +73,10 @@ 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.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);
@@ -160,17 +165,19 @@ PluginSelector::PluginSelector (PluginManager& mgr)
        _search_ignore_checkbox->set_active(true);
        _search_ignore_checkbox->set_name ("pluginlist filter button");
 
-       Gtk::Label* search_help_label = manage (new Label(
-                       _("All search terms must be matched.\n"
-                         "Ex: \"ess dyn\" will find \"dynamic de-esser\" but not \"de-esser\"."
-                        ), Gtk::ALIGN_LEFT));
+       Gtk::Label* search_help_label1 = manage (new Label(
+               _("All search terms must be matched."), Gtk::ALIGN_LEFT));
+
+       Gtk::Label* search_help_label2 = manage (new Label(
+               _("Ex: \"ess dyn\" will find \"dynamic de-esser\" but not \"de-esser\"."), Gtk::ALIGN_LEFT));
 
        search_table->attach (search_entry,            0, 3, 0, 1, FILL|EXPAND, FILL);
        search_table->attach (search_clear_button,     3, 4, 0, 1, FILL, FILL);
        search_table->attach (*_search_name_checkbox,  0, 1, 1, 2, FILL, FILL);
        search_table->attach (*_search_tags_checkbox,  1, 2, 1, 2, FILL, FILL);
        search_table->attach (*_search_ignore_checkbox,2, 3, 1, 2, FILL, FILL);
-       search_table->attach (*search_help_label,      0, 3, 2, 3, FILL, FILL);
+       search_table->attach (*search_help_label1,     0, 3, 2, 3, FILL, FILL);
+       search_table->attach (*search_help_label2,     0, 3, 3, 4, FILL, FILL);
 
        search_table->set_border_width (4);
        search_table->set_col_spacings (4);
@@ -206,7 +213,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"));
 
@@ -214,17 +221,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);
@@ -234,7 +230,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);
@@ -253,7 +248,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 */
 
@@ -268,16 +262,21 @@ PluginSelector::PluginSelector (PluginManager& mgr)
        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_label = manage (new Label(
-                       _("Enter space-separated, one-word Tags for the selected plugin.\n"
-                         "You can include dashes, colons or underscores in a Tag.\n"
-                         "Ex: \"dynamic de-esser vocal\" applies 3 Tags."
-                        ), Gtk::ALIGN_LEFT));
+       Gtk::Label* tagging_help_label1 = manage (new Label(
+               _("Enter space-separated, one-word Tags for the selected plugin."), Gtk::ALIGN_LEFT));
+
+       Gtk::Label* tagging_help_label2 = manage (new Label(
+               _("You can include dashes, colons or underscores in a Tag."), Gtk::ALIGN_LEFT));
+
+       Gtk::Label* tagging_help_label3 = manage (new Label(
+               _("Ex: \"dynamic de-esser vocal\" applies 3 Tags."), Gtk::ALIGN_LEFT));
 
        int p = 0;
        tagging_table->attach (*tag_entry,           0, 1, p, p+1, FILL|EXPAND, FILL);
        tagging_table->attach (*tag_reset_button,    1, 2, p, p+1, FILL, FILL); p++;
-       tagging_table->attach (*tagging_help_label,  0, 2, p, p+1, FILL, FILL); p++;
+       tagging_table->attach (*tagging_help_label1, 0, 2, p, p+1, FILL, FILL); p++;
+       tagging_table->attach (*tagging_help_label2, 0, 2, p, p+1, FILL, FILL); p++;
+       tagging_table->attach (*tagging_help_label3, 0, 2, p, p+1, FILL, FILL); p++;
 
        Frame* tag_frame = manage (new Frame);
        tag_frame->set_name ("BaseFrame");
@@ -350,6 +349,7 @@ PluginSelector::show_this_plugin (const PluginInfoPtr& info, const std::string&
 {
        string mode;
        bool maybe_show = false;
+       PluginManager::PluginStatusType status = manager.get_status (info);
 
        if (!searchstr.empty()) {
 
@@ -377,6 +377,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;
                }
        }
@@ -393,18 +399,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 */
@@ -423,7 +431,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;
        }
 
@@ -439,42 +447,6 @@ 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;
 }
 
@@ -495,9 +467,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);
@@ -505,9 +478,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 ();
@@ -517,7 +491,7 @@ PluginSelector::set_sensitive_widgets ()
 void
 PluginSelector::refill ()
 {
-       if (inhibit_refill) {
+       if (_inhibit_refill) {
                return;
        }
 
@@ -525,6 +499,15 @@ PluginSelector::refill ()
 
        in_row_change = true;
 
+       plugin_display.set_model (Glib::RefPtr<Gtk::TreeStore>(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 ();
 
        setup_search_string (searchstr);
@@ -538,6 +521,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
@@ -550,8 +538,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) {
@@ -603,7 +593,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;
                        }
 
@@ -809,9 +799,8 @@ PluginSelector::run ()
        if (_need_status_save) {
                manager.save_statuses();
        }
-
        if (_need_menu_rebuild) {
-               build_plugin_menu();
+               build_plugin_menu ();
        }
 
        return (int) r;
@@ -851,7 +840,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;
        }
@@ -868,11 +857,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
@@ -886,7 +870,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);
                                }
@@ -898,9 +882,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;
                }
        }
@@ -916,7 +897,6 @@ PluginSelector::on_show ()
 
        _need_tag_save = false;
        _need_status_save = false;
-       _need_menu_rebuild = false;
 }
 
 struct PluginMenuCompareByCreator {
@@ -965,6 +945,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());
@@ -989,7 +974,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();
@@ -1061,11 +1046,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;
 
@@ -1081,7 +1066,9 @@ 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;
 
@@ -1139,7 +1126,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<string> tokens = manager.get_tags(*i);
@@ -1148,12 +1137,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;