plugin menu/manager patch from J. Abelardo Gutierrez (already applied to 3.0)
authorPaul Davis <paul@linuxaudiosystems.com>
Sun, 8 Nov 2009 19:20:12 +0000 (19:20 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Sun, 8 Nov 2009 19:20:12 +0000 (19:20 +0000)
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@6039 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/plugin_selector.cc
gtk2_ardour/plugin_selector.h
libs/ardour/ardour/plugin_manager.h
libs/ardour/plugin_manager.cc

index 2fd3aa8ee0701a292d12610da0264fa0eb77084f..684ef2f36aa24c9ac5af2f5103f363c4bb74a23e 100644 (file)
@@ -54,6 +54,7 @@ static const char* _filter_mode_strings[] = {
        N_("Author contains"),
        N_("Library contains"),
        N_("Favorites only"),
+       N_("Hidden only"),
        0
 };
 
@@ -73,9 +74,11 @@ PluginSelector::PluginSelector (PluginManager *mgr)
        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);
@@ -89,9 +92,14 @@ PluginSelector::PluginSelector (PluginManager *mgr)
 
        CellRendererToggle* fav_cell = dynamic_cast<CellRendererToggle*>(plugin_display.get_column_cell_renderer (0));
        fav_cell->property_activatable() = true;
-       fav_cell->property_radio() = false;
+       fav_cell->property_radio() = true;
        fav_cell->signal_toggled().connect (mem_fun (*this, &PluginSelector::favorite_changed));
 
+       CellRendererToggle* hidden_cell = dynamic_cast<CellRendererToggle*>(plugin_display.get_column_cell_renderer (1));
+       hidden_cell->property_activatable() = true;
+       hidden_cell->property_radio() = true;
+       hidden_cell->signal_toggled().connect (mem_fun (*this, &PluginSelector::hidden_changed));
+
        scroller.set_border_width(10);
        scroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
        scroller.add(plugin_display);
@@ -102,7 +110,7 @@ PluginSelector::PluginSelector (PluginManager *mgr)
        added_list.set_headers_visible (true);
        added_list.set_reorderable (false);
 
-       for (int i = 0; i <=3; i++) {
+       for (int i = 0; i <=4; i++) {
                Gtk::TreeView::Column* column = plugin_display.get_column(i);
                column->set_sort_column(i);
        }
@@ -153,7 +161,7 @@ PluginSelector::PluginSelector (PluginManager *mgr)
 
        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);
@@ -202,7 +210,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->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()) {
@@ -286,7 +298,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;
@@ -469,7 +482,7 @@ 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);
@@ -485,7 +498,7 @@ PluginSelector::on_show ()
        filter_entry.grab_focus ();
 }
 
-struct PluginMenuCompare {
+struct PluginMenuCompareByCreator {
     bool operator() (PluginInfoPtr a, PluginInfoPtr b) const {
            int cmp;
 
@@ -503,28 +516,45 @@ struct PluginMenuCompare {
     }
 };
 
-Gtk::Menu&
-PluginSelector::plugin_menu()
-{
-       using namespace Menu_Helpers;
+struct PluginMenuCompareByName {
+    bool operator() (PluginInfoPtr a, PluginInfoPtr b) const {
+           int cmp;
 
-       typedef std::map<Glib::ustring,Gtk::Menu*> 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;
+    }
+};
 
+Gtk::Menu&
+PluginSelector::plugin_menu()
+{
        PluginInfoList all_plugs;
 
        all_plugs.insert (all_plugs.end(), manager->ladspa_plugin_info().begin(), manager->ladspa_plugin_info().end());
@@ -538,38 +568,125 @@ PluginSelector::plugin_menu()
        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;
 
-       for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
-               SubmenuMap::iterator x;
-               Gtk::Menu* submenu;
+       if (!_menu) {
+               _menu = new Menu();
+               _menu->set_name("ArdourContextMenu");
+       } 
 
-               string creator = (*i)->creator;
-               string::size_type pos = 0;
+       MenuList& items = _menu->items();
+       items.clear ();
+
+       Gtk::Menu* favs = create_favs_menu(all_plugs);
+       items.push_back (MenuElem (_("Favorites"), *favs));
 
-               if (manager->is_a_favorite_plugin (*i)) {
+       items.push_back (MenuElem (_("Plugin Manager"), 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"), *by_creator));
+
+       Menu* by_category = create_by_category_menu(all_plugs);
+       items.push_back (MenuElem (_("By Category"), *by_category));
+
+       return *_menu;
+}
+
+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, (bind (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<Glib::ustring,Gtk::Menu*> 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);
 
-               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;
-                       items.push_back (MenuElem (creator, *submenu));
-                       submenu_map.insert (pair<Glib::ustring,Menu*> (creator, submenu));
+                       by_creator_items.push_back (MenuElem (creator, *submenu));
+                       creator_submenu_map.insert (pair<Glib::ustring,Menu*> (creator, submenu));
                        submenu->set_name("ArdourContextMenu");
                }
-               
                submenu->items().push_back (MenuElem ((*i)->name, (bind (mem_fun (*this, &PluginSelector::plugin_chosen_from_menu), *i))));
        }
-       
-       return *_menu;
+       return by_creator;
+}
+
+Gtk::Menu*
+PluginSelector::create_by_category_menu (ARDOUR::PluginInfoList& all_plugs)
+{
+       using namespace Menu_Helpers;
+
+       typedef std::map<Glib::ustring,Gtk::Menu*> 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, *submenu));
+                       category_submenu_map.insert (pair<Glib::ustring,Menu*> (category, submenu));
+                       submenu->set_name("ArdourContextMenu");
+               }
+               submenu->items().push_back (MenuElem ((*i)->name, (bind (mem_fun (*this, &PluginSelector::plugin_chosen_from_menu), *i))));
+       }
+       return by_category;
 }
 
 void
@@ -596,9 +713,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];
@@ -606,18 +723,50 @@ 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 ();
+       }
+       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;
 }
index ab5495b3487cdd42a8cbb730bc81e08660ec8cab..dfdb3d05a2bec7b5927c8d961e645f2ab7c58369 100644 (file)
@@ -66,6 +66,7 @@ class PluginSelector : public ArdourDialog
        struct PluginColumns : public Gtk::TreeModel::ColumnRecord {
                PluginColumns () {
                        add (favorite);
+                       add (hidden);
                        add (name);
                        add (type_name);
                        add (category);
@@ -75,6 +76,7 @@ class PluginSelector : public ArdourDialog
                        add (plugin);
                }
                Gtk::TreeModelColumn<bool> favorite;
+               Gtk::TreeModelColumn<bool> hidden;
                Gtk::TreeModelColumn<std::string> name;
                Gtk::TreeModelColumn<std::string> type_name;
                Gtk::TreeModelColumn<std::string> category;
@@ -122,10 +124,15 @@ class PluginSelector : public ArdourDialog
        void setup_filter_string (std::string&);
 
        void favorite_changed (const Glib::ustring& path);
+       void hidden_changed (const Glib::ustring& path);
        bool in_row_change;
 
        void plugin_chosen_from_menu (const ARDOUR::PluginInfoPtr&);
        Gtk::Menu* _menu;
+
+       Gtk::Menu* create_favs_menu (ARDOUR::PluginInfoList&);
+       Gtk::Menu* create_by_creator_menu (ARDOUR::PluginInfoList&);
+       Gtk::Menu* create_by_category_menu (ARDOUR::PluginInfoList&);
 };
 
 #endif // __ardour_plugin_selector_h__
index 858decd0e5faf819e931b92b710f3b9d43ac16ee..7dab6b0009fcc3272cf3efda6eff830b22d9f098 100644 (file)
@@ -55,30 +55,36 @@ class PluginManager {
 
        static PluginManager* the_manager() { return _manager; }
 
-       void load_favorites ();
-       void save_favorites ();
-       void add_favorite (ARDOUR::PluginType type, std::string unique_id);
-       void remove_favorite (ARDOUR::PluginType type, std::string unique_id);
-       bool is_a_favorite_plugin (const PluginInfoPtr&);
-       
+       enum PluginStatusType {
+               Normal = 0,
+               Favorite,
+               Hidden
+       };
+
+       void load_statuses ();
+       void save_statuses ();
+       void set_status (ARDOUR::PluginType type, std::string unique_id, PluginStatusType status);
+       PluginStatusType get_status (const PluginInfoPtr&);
+
   private:
-       struct FavoritePlugin {
+       struct PluginStatus {
            ARDOUR::PluginType type;
            std::string unique_id;
+           PluginStatusType status;
 
-           FavoritePlugin (ARDOUR::PluginType t, std::string id) 
-           : type (t), unique_id (id) {}
+           PluginStatus (ARDOUR::PluginType t, std::string id, PluginStatusType s = Normal)
+           : type (t), unique_id (id), status (s) {}
            
-           bool operator==(const FavoritePlugin& other) const {
+           bool operator==(const PluginStatus& other) const {
                    return other.type == type && other.unique_id == unique_id;
            }
 
-           bool operator<(const FavoritePlugin& other) const {
+           bool operator<(const PluginStatus& other) const {
                    return other.type < type || other.unique_id < unique_id;
            }
        };
-       typedef std::set<FavoritePlugin> FavoritePluginList;
-       FavoritePluginList favorites;
+       typedef std::set<PluginStatus> PluginStatusList;
+       PluginStatusList statuses;
 
        ARDOUR::PluginInfoList _vst_plugin_info;
        ARDOUR::PluginInfoList _ladspa_plugin_info;
index a069dd17626ec1d9078a9f968beb37c953b55f7a..064a19a278b02804d6a8f41e4486c6a9acaec4ab 100644 (file)
@@ -70,7 +70,7 @@ PluginManager::PluginManager ()
        char* s;
        string lrdf_path;
 
-       load_favorites ();
+       load_statuses ();
 
 #ifdef GTKOSX
        ProcessSerialNumber psn = { 0, kCurrentProcess }; 
@@ -400,7 +400,7 @@ PluginManager::get_ladspa_category (uint32_t plugin_id)
        lrdf_statement* matches1 = lrdf_matches (&pattern);
 
        if (!matches1) {
-               return "";
+               return "Unknown";
        }
 
        pattern.subject = matches1->object;
@@ -412,7 +412,7 @@ PluginManager::get_ladspa_category (uint32_t plugin_id)
        lrdf_free_statements(matches1);
 
        if (!matches2) {
-               return ("");
+               return ("Unknown");
        }
 
        string label = matches2->object;
@@ -553,17 +553,22 @@ PluginManager::vst_discover (string path)
 
 #endif // VST_SUPPORT
 
-bool
-PluginManager::is_a_favorite_plugin (const PluginInfoPtr& pi)
+PluginManager::PluginStatusType
+PluginManager::get_status (const PluginInfoPtr& pi)
 {
-       FavoritePlugin fp (pi->type, pi->unique_id);
-       return find (favorites.begin(), favorites.end(), fp) !=  favorites.end();
+       PluginStatus ps (pi->type, pi->unique_id);
+       PluginStatusList::const_iterator i =  find (statuses.begin(), statuses.end(), ps);
+       if (i ==  statuses.end() ) {
+               return Normal;
+       } else {
+               return i->status;
+       }
 }
 
 void
-PluginManager::save_favorites ()
+PluginManager::save_statuses ()
 {
-       Glib::ustring path = Glib::build_filename (get_user_ardour_path (), "favorite_plugins");
+       Glib::ustring path = Glib::build_filename (get_user_ardour_path (), "plugin_statuses");
        ofstream ofs;
 
        ofs.open (path.c_str(), ios_base::openmode (ios::out|ios::trunc));
@@ -572,7 +577,7 @@ PluginManager::save_favorites ()
                return;
        }
 
-       for (FavoritePluginList::iterator i = favorites.begin(); i != favorites.end(); ++i) {
+       for (PluginStatusList::iterator i = statuses.begin(); i != statuses.end(); ++i) {
                switch ((*i).type) {
                case LADSPA:
                        ofs << "LADSPA";
@@ -588,16 +593,30 @@ PluginManager::save_favorites ()
                        break;
                }
                
-               ofs << ' ' << (*i).unique_id << endl;
+               ofs << ' ' << (*i).unique_id << ' ';
+
+               switch ((*i).status) {
+               case Normal:
+                       ofs << "Normal";
+                       break;
+               case Favorite:
+                       ofs << "Favorite";
+                       break;
+               case Hidden:
+                       ofs << "Hidden";
+                       break;
+               }
+
+               ofs << endl;
        }
 
        ofs.close ();
 }
 
 void
-PluginManager::load_favorites ()
+PluginManager::load_statuses ()
 {
-       Glib::ustring path = Glib::build_filename (get_user_ardour_path (),"favorite_plugins");
+       Glib::ustring path = Glib::build_filename (get_user_ardour_path (),"plugin_statuses");
 
        ifstream ifs (path.c_str());
 
@@ -607,7 +626,9 @@ PluginManager::load_favorites ()
        
        std::string stype;
        std::string id;
+       std::string sstatus;
        PluginType type;
+       PluginStatusType status;
 
        while (ifs) {
 
@@ -621,6 +642,12 @@ PluginManager::load_favorites ()
                        break;
                }
 
+               ifs >> sstatus;
+               if (!ifs) {
+                       break;
+
+               }
+
                if (stype == "LADSPA") {
                        type = LADSPA;
                } else if (stype == "AudioUnit") {
@@ -630,28 +657,39 @@ PluginManager::load_favorites ()
                } else if (stype == "VST") {
                        type = VST;
                } else {
-                       error << string_compose (_("unknown favorite plugin type \"%1\" - ignored"), stype)
+                       error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype)
                              << endmsg;
                        continue;
                }
                
-               add_favorite (type, id);
+               if (sstatus == "Normal") {
+                       status = Normal;
+               } else if (sstatus == "Favorite") {
+                       status = Favorite;
+               } else if (sstatus == "Hidden") {
+                       status = Hidden;
+               } else {
+                       error << string_compose (_("unknown plugin status type \"%1\" - ignored"), sstatus)
+                                 << endmsg;
+                       continue;
+               }
+
+               set_status (type, id, status);
        }
        
        ifs.close ();
 }
 
 void
-PluginManager::add_favorite (PluginType t, string id)
+PluginManager::set_status (PluginType t, string id, PluginStatusType status)
 {
-       FavoritePlugin fp (t, id);
-       pair<FavoritePluginList::iterator,bool> res = favorites.insert (fp);
-       //cerr << "Added " << t << " " << id << " success ? " << res.second << endl;
-}
+       PluginStatus ps (t, id, status);
+       statuses.erase (ps);
 
-void
-PluginManager::remove_favorite (PluginType t, string id)
-{
-       FavoritePlugin fp (t, id);
-       favorites.erase (fp);
+       if (status == Normal) {
+               return;
+       }
+
+       pair<PluginStatusList::iterator, bool> res = statuses.insert (ps);
+       //cerr << "Added " << t << " " << id << " " << status << " success ? " << res.second << endl;
 }