diff --git a/libs/ardour/ardour/utils.h b/libs/ardour/ardour/utils.h index 5e4cc3bdc4..7223d1f8ec 100644 --- a/libs/ardour/ardour/utils.h +++ b/libs/ardour/ardour/utils.h @@ -40,6 +40,7 @@ class XMLNode; std::string legalize_for_path (const std::string& str); std::string legalize_for_universal_path (const std::string& str); +std::string legalize_for_uri (const std::string& str); std::string legalize_for_path_2X (const std::string& str); XMLNode* find_named_node (const XMLNode& node, std::string name); std::string bool_as_string (bool); diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc index 8a0e8e07bc..69efa2eeef 100644 --- a/libs/ardour/lv2_plugin.cc +++ b/libs/ardour/lv2_plugin.cc @@ -37,13 +37,14 @@ #include "libardour-config.h" -#include "ardour/types.h" #include "ardour/audio_buffer.h" #include "ardour/audioengine.h" #include "ardour/debug.h" #include "ardour/lv2_plugin.h" #include "ardour/session.h" #include "ardour/tempo.h" +#include "ardour/types.h" +#include "ardour/utils.h" #include "ardour/worker.h" #include "i18n.h" @@ -1023,42 +1024,40 @@ ARDOUR::lv2plugin_get_port_value(const char* port_symbol, std::string LV2Plugin::do_save_preset(string name) { - string pset_uri = uri(); - pset_uri += "#"; - pset_uri += name; - - string save_dir = Glib::build_filename( + const string base_name = legalize_for_uri(name); + const string file_name = base_name + ".ttl"; + const string bundle = Glib::build_filename( Glib::get_home_dir(), - Glib::build_filename(".lv2", "presets") - ); + Glib::build_filename(".lv2", base_name + ".lv2")); LilvState* state = lilv_state_new_from_instance( _impl->plugin, _impl->instance, _uri_map.urid_map(), - scratch_dir().c_str(), // file_dir - NULL, // copy_dir - NULL, // link_dir - save_dir.c_str(), // save_dir - lv2plugin_get_port_value, // get_value - (void*) this, // user_data - LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE, // flags - _features // features + scratch_dir().c_str(), // file_dir + bundle.c_str(), // copy_dir + bundle.c_str(), // link_dir + bundle.c_str(), // save_dir + lv2plugin_get_port_value, // get_value + (void*)this, // user_data + LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE, // flags + _features // features ); lilv_state_set_label(state, name.c_str()); lilv_state_save( _world.world, // world - _uri_map.urid_map(), // map - _uri_map.urid_unmap(), // unmap + _uri_map.urid_map(), // map + _uri_map.urid_unmap(), // unmap state, // state - pset_uri.c_str(), // uri - save_dir.c_str(), // dir - (name + ".ttl").c_str() // filename + NULL, // uri (NULL = use file URI) + bundle.c_str(), // dir + file_name.c_str() // filename ); lilv_state_free(state); - return pset_uri; + + return Glib::filename_to_uri(Glib::build_filename(bundle, file_name)); } void diff --git a/libs/ardour/utils.cc b/libs/ardour/utils.cc index d034eea6ee..ad0823ddaf 100644 --- a/libs/ardour/utils.cc +++ b/libs/ardour/utils.cc @@ -111,6 +111,17 @@ legalize_for_universal_path (const string& str) return replace_chars (str, "<>:\"/\\|?*"); } +/** Legalize for a URI path component. This is like + * legalize_for_universal_path, but stricter, disallowing spaces and hash. + * This avoids %20 escapes in URIs, but probably needs work to be more strictly + * correct. + */ +string +legalize_for_uri (const string& str) +{ + return replace_chars (str, "<>:\"/\\|?* #"); +} + /** take an arbitrary string as an argument, and return a version of it * suitable for use as a path (directory/folder name). This is the Ardour 2.X * version of this code, which used an approach that came to be seen as