add icons for cut mouse mode button and cut cursor (both need improving)
[ardour.git] / gtk2_ardour / plugin_selector.cc
index deed9735d303da857187698d9f7435d186501540..fcf056307e7be2deaf81460a609df947fbdc46b0 100644 (file)
@@ -21,7 +21,6 @@
 #endif
 
 #include <cstdio>
-#include <lrdf.h>
 #include <map>
 
 #include <algorithm>
@@ -37,8 +36,7 @@
 
 #include "ardour/plugin_manager.h"
 #include "ardour/plugin.h"
-#include "ardour/configuration.h"
-#include "ardour/session.h"
+#include "ardour/utils.h"
 
 #include "ardour_ui.h"
 #include "plugin_selector.h"
@@ -62,19 +60,20 @@ static const char* _filter_mode_strings[] = {
        0
 };
 
-PluginSelector::PluginSelector (PluginManager *mgr)
-       : ArdourDialog (_("Plugin Manager"), 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);
 
        _plugin_menu = 0;
-       manager = 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::build_plugin_menu, this), gui_context());
+       manager.PluginListChanged.connect (plugin_list_changed_connection, invalidator (*this), boost::bind (&PluginSelector::refill, this), gui_context());
        build_plugin_menu ();
 
        plugin_model = Gtk::ListStore::create (plugin_columns);
@@ -84,7 +83,7 @@ PluginSelector::PluginSelector (PluginManager *mgr)
           related to "hidden"
        */
        plugin_display.append_column (_("Fav"), plugin_columns.favorite);
-       plugin_display.append_column (_("Hid"), plugin_columns.hidden);
+       plugin_display.append_column (_("Hide"), 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);
@@ -180,7 +179,7 @@ PluginSelector::PluginSelector (PluginManager *mgr)
        //plugin_display.set_name("PluginSelectorList");
        added_list.set_name("PluginSelectorList");
 
-       plugin_display.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &PluginSelector::row_clicked));
+       plugin_display.signal_row_activated().connect_notify (sigc::mem_fun(*this, &PluginSelector::row_activated));
        plugin_display.get_selection()->signal_changed().connect (sigc::mem_fun(*this, &PluginSelector::display_selection_changed));
        plugin_display.grab_focus();
 
@@ -198,11 +197,9 @@ PluginSelector::~PluginSelector ()
 }
 
 void
-PluginSelector::row_clicked(GdkEventButton* event)
+PluginSelector::row_activated(Gtk::TreeModel::Path, Gtk::TreeViewColumn*)
 {
-       if (event->type == GDK_2BUTTON_PRESS) {
-               btn_add_clicked();
-       }
+       btn_add_clicked();
 }
 
 bool
@@ -212,11 +209,11 @@ PluginSelector::show_this_plugin (const PluginInfoPtr& info, const std::string&
        std::string mode = filter_mode.get_active_text ();
 
        if (mode == _("Favorites only")) {
-               return manager->get_status (info) == PluginManager::Favorite;
+               return manager.get_status (info) == PluginManager::Favorite;
        }
 
        if (mode == _("Hidden only")) {
-               return manager->get_status (info) == PluginManager::Hidden;
+               return manager.get_status (info) == PluginManager::Hidden;
        }
 
        if (!filterstr.empty()) {
@@ -237,9 +234,12 @@ PluginSelector::show_this_plugin (const PluginInfoPtr& info, const std::string&
                        case LV2:
                                compstr = X_("LV2");
                                break;
-                       case VST:
+                       case Windows_VST:
                                compstr = X_("VST");
                                break;
+                       case LXVST:
+                               compstr = X_("LXVST");
+                               break;
                        }
 
                } else if (mode == _("Author contains")) {
@@ -285,6 +285,7 @@ PluginSelector::refill ()
        ladspa_refiller (filterstr);
        lv2_refiller (filterstr);
        vst_refiller (filterstr);
+       lxvst_refiller (filterstr);
        au_refiller (filterstr);
 
        in_row_change = false;
@@ -300,8 +301,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->get_status (*i) == PluginManager::Favorite);
-                       newrow[plugin_columns.hidden] = (manager->get_status (*i) == PluginManager::Hidden);
+                       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;
@@ -310,21 +311,36 @@ PluginSelector::refiller (const PluginInfoList& plugs, const::std::string& filte
                        string::size_type pos = 0;
 
                        /* 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;
-                       creator = creator.substr (0, pos);
+#endif
+                       // If there were too few characters to create a
+                       // meaningful name, mark this creator as 'Unknown'
+                       if (creator.length()<2 || pos<3)
+                               creator = "Unknown";
+                       else
+                               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;
-
-                       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;
+                       if ((*i)->reconfigurable_io ()) {
+                               newrow[plugin_columns.audio_ins] = _("variable");
+                               newrow[plugin_columns.midi_ins] = _("variable");
+                               newrow[plugin_columns.audio_outs] = _("variable");
+                               newrow[plugin_columns.midi_outs] = _("variable");
+                       } 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;
+                               
+                               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;
                }
@@ -334,38 +350,50 @@ PluginSelector::refiller (const PluginInfoList& plugs, const::std::string& filte
 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_SLV2
-       refiller (manager->lv2_plugin_info(), filterstr, "LV2");
+#ifdef LV2_SUPPORT
+       refiller (manager.lv2_plugin_info(), filterstr, "LV2");
 #endif
 }
 
 void
-#ifdef VST_SUPPORT
+#ifdef WINDOWS_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");
+#ifdef WINDOWS_VST_SUPPORT
+       refiller (manager.windows_vst_plugin_info(), filterstr, "VST");
 #endif
 }
 
 void
-#ifdef HAVE_AUDIOUNITS
+#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
 }
 
@@ -413,8 +441,7 @@ PluginSelector::btn_remove_clicked()
 void
 PluginSelector::btn_update_clicked()
 {
-       manager->refresh ();
-       refill();
+       manager.refresh ();
 }
 
 void
@@ -444,12 +471,12 @@ PluginSelector::run ()
        TreeModel::Children::iterator i;
 
        bool finish = false;
-       
+
        while (!finish) {
 
                SelectedPlugins plugins;
                r = (ResponseType) Dialog::run ();
-               
+
                switch (r) {
                case RESPONSE_APPLY:
                        for (i = amodel->children().begin(); i != amodel->children().end(); ++i) {
@@ -465,16 +492,16 @@ PluginSelector::run ()
                        if (interested_object && !plugins.empty()) {
                                finish = !interested_object->use_plugins (plugins);
                         }
-                       
+
                        break;
-                       
+
                default:
                        finish = true;
                        break;
                }
        }
-               
-               
+
+
        hide();
        amodel->clear();
        interested_object = 0;
@@ -519,13 +546,13 @@ struct PluginMenuCompareByCreator {
     bool operator() (PluginInfoPtr a, PluginInfoPtr b) const {
            int cmp;
 
-           cmp = strcasecmp (a->creator.c_str(), b->creator.c_str());
+           cmp = cmp_nocase_utf8 (a->creator, b->creator);
 
            if (cmp < 0) {
                    return true;
            } else if (cmp == 0) {
                    /* same creator ... compare names */
-                   if (strcasecmp (a->name.c_str(), b->name.c_str()) < 0) {
+                   if (cmp_nocase_utf8 (a->name, b->name) < 0) {
                            return true;
                    }
            }
@@ -537,7 +564,7 @@ struct PluginMenuCompareByName {
     bool operator() (PluginInfoPtr a, PluginInfoPtr b) const {
            int cmp;
 
-           cmp = strcasecmp (a->name.c_str(), b->name.c_str());
+           cmp = cmp_nocase_utf8 (a->name, b->name);
 
            if (cmp < 0) {
                    return true;
@@ -555,13 +582,13 @@ struct PluginMenuCompareByCategory {
     bool operator() (PluginInfoPtr a, PluginInfoPtr b) const {
            int cmp;
 
-           cmp = strcasecmp (a->category.c_str(), b->category.c_str());
+           cmp = cmp_nocase_utf8 (a->category, b->category);
 
            if (cmp < 0) {
                    return true;
            } else if (cmp == 0) {
                    /* same category ... compare names */
-                   if (strcasecmp (a->name.c_str(), b->name.c_str()) < 0) {
+                   if (cmp_nocase_utf8 (a->name, b->name) < 0) {
                            return true;
                    }
            }
@@ -581,24 +608,27 @@ 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());
+       all_plugs.insert (all_plugs.end(), manager.ladspa_plugin_info().begin(), manager.ladspa_plugin_info().end());
+#ifdef WINDOWS_VST_SUPPORT
+       all_plugs.insert (all_plugs.end(), manager.windows_vst_plugin_info().begin(), manager.windows_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_SLV2
-       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
 
        using namespace Menu_Helpers;
 
        delete _plugin_menu;
-       
+
        _plugin_menu = manage (new Menu);
        _plugin_menu->set_name("ArdourContextMenu");
-       
+
        MenuList& items = _plugin_menu->items();
        items.clear ();
 
@@ -627,8 +657,10 @@ PluginSelector::create_favs_menu (PluginInfoList& all_plugs)
        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))));
+               if (manager.get_status (*i) == PluginManager::Favorite) {
+                       MenuElem elem ((*i)->name, (sigc::bind (sigc::mem_fun (*this, &PluginSelector::plugin_chosen_from_menu), *i)));
+                       elem.get_child()->set_use_underline (false);
+                       favs->items().push_back (elem);
                }
        }
        return favs;
@@ -651,14 +683,27 @@ 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;
+               if (manager.get_status (*i) == PluginManager::Hidden) continue;
 
                string creator = (*i)->creator;
 
                /* stupid LADSPA creator strings */
                string::size_type pos = 0;
+#ifdef PLATFORM_WINDOWS
+               while (pos < creator.length() && creator[pos]>(-2) && creator[pos]<256 && (isprint (creator[pos]))) ++pos;
+#else
                while (pos < creator.length() && (isalnum (creator[pos]) || isspace (creator[pos]))) ++pos;
-               creator = creator.substr (0, pos);
+#endif
+
+               // Check to see if we found any invalid characters.
+               if (creator.length() != pos) {
+                       // If there were too few characters to create a
+                       // meaningful name, mark this creator as 'Unknown'
+                       if (pos<3)
+                               creator = "Unknown?";
+                       else
+                               creator = creator.substr (0, pos);
+               }
 
                SubmenuMap::iterator x;
                Gtk::Menu* submenu;
@@ -670,7 +715,9 @@ PluginSelector::create_by_creator_menu (ARDOUR::PluginInfoList& all_plugs)
                        creator_submenu_map.insert (pair<std::string,Menu*> (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))));
+               MenuElem elem ((*i)->name, (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_creator;
 }
@@ -692,7 +739,7 @@ PluginSelector::create_by_category_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;
+               if (manager.get_status (*i) == PluginManager::Hidden) continue;
 
                string category = (*i)->category;
 
@@ -706,7 +753,9 @@ PluginSelector::create_by_category_menu (ARDOUR::PluginInfoList& all_plugs)
                        category_submenu_map.insert (pair<std::string,Menu*> (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))));
+               MenuElem elem ((*i)->name, (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_category;
 }
@@ -752,9 +801,9 @@ PluginSelector::favorite_changed (const std::string& path)
 
                pi = (*iter)[plugin_columns.plugin];
 
-               manager->set_status (pi->type, pi->unique_id, status);
+               manager.set_status (pi->type, pi->unique_id, status);
 
-               manager->save_statuses ();
+               manager.save_statuses ();
 
                build_plugin_menu ();
        }
@@ -788,9 +837,11 @@ PluginSelector::hidden_changed (const std::string& path)
 
                pi = (*iter)[plugin_columns.plugin];
 
-               manager->set_status (pi->type, pi->unique_id, status);
+               manager.set_status (pi->type, pi->unique_id, status);
+
+               manager.save_statuses ();
 
-               manager->save_statuses ();
+               build_plugin_menu ();
        }
        in_row_change = false;
 }