add well known controls to list accessible via a MIDI binding map (or OSC?)
[ardour.git] / libs / ardour / plugin_manager.cc
index e1d811007609ac09983e5de57342b8c5085eff0e..233f986a7bbc0fb79bdf6b17bda67aa4bbe1259a 100644 (file)
@@ -509,7 +509,7 @@ PluginManager::lua_refresh ()
        for (LuaScriptList::const_iterator s = _scripts.begin(); s != _scripts.end(); ++s) {
                LuaPluginInfoPtr lpi (new LuaPluginInfo(*s));
                _lua_plugin_info->push_back (lpi);
-               set_tags (lpi->type, lpi->unique_id, lpi->category, true);
+               set_tags (lpi->type, lpi->unique_id, lpi->category, lpi->name, FromPlug);
        }
 }
 
@@ -678,13 +678,30 @@ PluginManager::ladspa_discover (string path)
                PluginInfoPtr info(new LadspaPluginInfo);
                info->name = descriptor->Name;
                info->category = get_ladspa_category(descriptor->UniqueID);
-               info->creator = descriptor->Maker;
                info->path = path;
                info->index = i;
                info->n_inputs = ChanCount();
                info->n_outputs = ChanCount();
                info->type = ARDOUR::LADSPA;
 
+               string::size_type pos = 0;
+               string creator = descriptor->Maker;
+               /* stupid LADSPA creator strings */
+#ifdef PLATFORM_WINDOWS
+               while (pos < creator.length() && creator[pos] > -2 && creator[pos] < 256 && (isalnum (creator[pos]) || isspace (creator[pos]) || creator[pos] == '.')) ++pos;
+#else
+               while (pos < creator.length() && (isalnum (creator[pos]) || isspace (creator[pos]) || creator[pos] == '.')) ++pos;
+#endif
+
+               /* If there were too few characters to create a
+                * meaningful name, mark this creator as 'Unknown'
+                */
+               if (creator.length() < 2 || pos < 3) {
+                       info->creator = "Unknown";
+               } else{
+                       info->creator = creator.substr (0, pos);
+               }
+
                char buf[32];
                snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID);
                info->unique_id = buf;
@@ -716,6 +733,7 @@ PluginManager::ladspa_discover (string path)
 
                if(!found){
                    _ladspa_plugin_info->push_back (info);
+                       set_tags (info->type, info->unique_id, info->category, info->name, FromPlug);
                }
 
                DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Found LADSPA plugin, name: %1, Inputs: %2, Outputs: %3\n", info->name, info->n_inputs, info->n_outputs));
@@ -802,7 +820,7 @@ PluginManager::lv2_refresh ()
        _lv2_plugin_info = LV2PluginInfo::discover();
 
        for (PluginInfoList::iterator i = _lv2_plugin_info->begin(); i != _lv2_plugin_info->end(); ++i) {
-               set_tags ((*i)->type, (*i)->unique_id, (*i)->category, true);
+               set_tags ((*i)->type, (*i)->unique_id, (*i)->category, (*i)->name, FromPlug);
        }
 }
 #endif
@@ -826,7 +844,7 @@ PluginManager::au_refresh (bool cache_only)
        Config->save_state();
 
        for (PluginInfoList::iterator i = _au_plugin_info->begin(); i != _au_plugin_info->end(); ++i) {
-               set_tags ((*i)->type, (*i)->unique_id, (*i)->category, true);
+               set_tags ((*i)->type, (*i)->unique_id, (*i)->category, (*i)->name, FromPlug);
        }
 }
 
@@ -997,7 +1015,7 @@ PluginManager::windows_vst_discover (string path, bool cache_only)
 
                snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
                info->unique_id = buf;
-               info->category = finfo->category;
+               info->category = finfo->Category;
                info->path = path;
                info->creator = finfo->creator;
                info->index = 0;
@@ -1008,7 +1026,7 @@ PluginManager::windows_vst_discover (string path, bool cache_only)
                info->type = ARDOUR::Windows_VST;
 
                /* if we don't have any tags for this plugin, make some up. */
-               set_tags (info->type, info->unique_id, info->category, true);
+               set_tags (info->type, info->unique_id, info->category, info->name, FromPlug);
 
                // TODO: check dup-IDs (lxvst AND windows vst)
                bool duplicate = false;
@@ -1148,7 +1166,7 @@ PluginManager::mac_vst_discover (string path, bool cache_only)
                info->type = ARDOUR::MacVST;
 
                /* if we don't have any tags for this plugin, make some up. */
-               set_tags (info->type, info->unique_id, info->category, true);
+               set_tags (info->type, info->unique_id, info->category, info->name, FromPlug);
 
                bool duplicate = false;
                if (!_mac_vst_plugin_info->empty()) {
@@ -1269,7 +1287,7 @@ PluginManager::lxvst_discover (string path, bool cache_only)
                info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
                info->type = ARDOUR::LXVST;
 
-               set_tags (info->type, info->unique_id, info->category, true);
+               set_tags (info->type, info->unique_id, info->category, info->name, FromPlug);
 
                /* Make sure we don't find the same plugin in more than one place along
                 * the LXVST_PATH We can't use a simple 'find' because the path is included
@@ -1457,7 +1475,7 @@ PluginManager::set_status (PluginType t, string id, PluginStatusType status)
                statuses.insert (ps);
        }
 
-       PluginStatusesChanged (t, id, status); /* EMIT SIGNAL */
+       PluginStatusChanged (t, id, status); /* EMIT SIGNAL */
 }
 
 PluginType
@@ -1485,7 +1503,7 @@ PluginManager::get_tags (const PluginInfoPtr& pi) const
 {
        vector<std::string> tags;
 
-       PluginTag ps (to_generic_vst(pi->type), pi->unique_id, "", false);
+       PluginTag ps (to_generic_vst(pi->type), pi->unique_id, "", "", FromPlug);
        PluginTagList::const_iterator i = find (ptags.begin(), ptags.end(), ps);
        if (i != ptags.end ()) {
                PBD::tokenize (i->tags, string(" "), std::back_inserter (tags), true);
@@ -1496,7 +1514,7 @@ PluginManager::get_tags (const PluginInfoPtr& pi) const
 }
 
 std::string
-PluginManager::get_tags_as_string (const PluginInfoPtr& pi) const
+PluginManager::get_tags_as_string (PluginInfoPtr const& pi) const
 {
        std::string ret;
 
@@ -1526,14 +1544,18 @@ PluginManager::save_tags ()
        XMLNode* root = new XMLNode (X_("PluginTags"));
 
        for (PluginTagList::iterator i = ptags.begin(); i != ptags.end(); ++i) {
-               if (!(*i).user_set) {
+               if ( (*i).tagtype == FromFactoryFile || (*i).tagtype == FromUserFile ) {
+                       /* user file should contain only plugins that are (a) newly user-tagged or (b) previously unknown */
                        continue;
                }
                XMLNode* node = new XMLNode (X_("Plugin"));
                node->set_property (X_("type"), to_generic_vst ((*i).type));
                node->set_property (X_("id"), (*i).unique_id);
                node->set_property (X_("tags"), (*i).tags);
-               node->set_property (X_("user-set"), (*i).user_set);
+               node->set_property (X_("name"), (*i).name);
+               if ( (*i).tagtype >= FromUserFile ) {
+                       node->set_property (X_("user-set"), "1");
+               }
                root->add_child_nocopy (*node);
        }
 
@@ -1550,7 +1572,8 @@ PluginManager::load_tags ()
        vector<std::string> tmp;
        find_files_matching_pattern (tmp, plugin_metadata_search_path (), "plugin_tags");
 
-       for (vector<std::string>::const_reverse_iterator p = tmp.rbegin (); p != tmp.rend(); ++p) {
+       for (vector<std::string>::const_reverse_iterator p = tmp.rbegin ();
+                       p != (vector<std::string>::const_reverse_iterator)tmp.rend(); ++p) {
                std::string path = *p;
                info << string_compose (_("Loading plugin meta data file %1"), path) << endmsg;
                if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
@@ -1567,37 +1590,49 @@ PluginManager::load_tags ()
                        PluginType type;
                        string id;
                        string tags;
+                       string name;
                        bool user_set;
                        if (!(*i)->get_property (X_("type"), type) ||
                                        !(*i)->get_property (X_("id"), id) ||
-                                       !(*i)->get_property (X_("tags"), tags)) {
+                                       !(*i)->get_property (X_("tags"), tags) ||
+                                       !(*i)->get_property (X_("name"), name)) {
                        }
                        if (!(*i)->get_property (X_("user-set"), user_set)) {
                                user_set = false;
                        }
                        strip_whitespace_edges (tags);
-                       set_tags (type, id, tags, !user_set);
+                       set_tags (type, id, tags, name, user_set ? FromUserFile : FromFactoryFile );
                }
        }
 }
 
 void
-PluginManager::set_tags (PluginType t, string id, string tag, bool factory, bool force)
+PluginManager::set_tags (PluginType t, string id, string tag, std::string name, TagType ttype )
 {
        string sanitized = sanitize_tag (tag);
 
-       PluginTag ps (to_generic_vst (t), id, sanitized, !factory);
+       PluginTag ps (to_generic_vst (t), id, sanitized, name, ttype );
        PluginTagList::const_iterator i = find (ptags.begin(), ptags.end(), ps);
        if (i == ptags.end()) {
                ptags.insert (ps);
-       } else {
-               if (force || ((*i).user_set && !factory)) {
-                       ptags.erase (ps);
-                       ptags.insert (ps);
-               }
+       } else if ( (uint32_t) ttype >=  (uint32_t) (*i).tagtype ) {  // only overwrite if we are more important than the existing. Gui > UserFile > FactoryFile > Plugin
+               ptags.erase (ps);
+               ptags.insert (ps);
        }
-       if (!factory || force) {
-               PluginTagsChanged (t, id, sanitized); /* EMIT SIGNAL */
+       if ( ttype == FromGui ) {
+               PluginTagChanged (t, id, sanitized); /* EMIT SIGNAL */
+       }
+}
+
+void
+PluginManager::reset_tags (PluginInfoPtr const& pi)
+{
+       PluginTag ps (pi->type, pi->unique_id, pi->category, pi->name, FromPlug);
+
+       PluginTagList::const_iterator i = find (ptags.begin(), ptags.end(), ps);
+       if (i != ptags.end()) {
+               ptags.erase (ps);
+               ptags.insert (ps);
        }
 }
 
@@ -1629,7 +1664,7 @@ PluginManager::sanitize_tag (const std::string to_sanitize) const
 }
 
 std::vector<std::string>
-PluginManager::get_all_tags (bool favorites_only) const
+PluginManager::get_all_tags (TagFilter tag_filter) const
 {
        std::vector<std::string> ret;
 
@@ -1640,7 +1675,7 @@ PluginManager::get_all_tags (bool favorites_only) const
                }
 
                /* if favorites_only then we need to check the info ptr and maybe skip */
-               if (favorites_only) {
+               if (tag_filter == OnlyFavorites) {
                        PluginStatus stat ((*pt).type, (*pt).unique_id);
                        PluginStatusList::const_iterator i =  find (statuses.begin(), statuses.end(), stat);
                        if ((i != statuses.end()) && (i->status == Favorite)) {
@@ -1649,6 +1684,13 @@ PluginManager::get_all_tags (bool favorites_only) const
                                continue;
                        }
                }
+               if (tag_filter == NoHidden) {
+                       PluginStatus stat ((*pt).type, (*pt).unique_id);
+                       PluginStatusList::const_iterator i =  find (statuses.begin(), statuses.end(), stat);
+                       if ((i != statuses.end()) && (i->status == Hidden)) {
+                               continue;
+                       }
+               }
 
                /* parse each plugin's tag string into separate tags */
                vector<string> tags;