Save LV2 presets with relative URIs to their own bundle, in the same style as Jalv.

This commit is contained in:
David Robillard 2013-03-17 12:52:49 -04:00
parent 2233e91086
commit 07112b55e0
3 changed files with 33 additions and 22 deletions

View file

@ -40,6 +40,7 @@ class XMLNode;
std::string legalize_for_path (const std::string& str); std::string legalize_for_path (const std::string& str);
std::string legalize_for_universal_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); std::string legalize_for_path_2X (const std::string& str);
XMLNode* find_named_node (const XMLNode& node, std::string name); XMLNode* find_named_node (const XMLNode& node, std::string name);
std::string bool_as_string (bool); std::string bool_as_string (bool);

View file

@ -37,13 +37,14 @@
#include "libardour-config.h" #include "libardour-config.h"
#include "ardour/types.h"
#include "ardour/audio_buffer.h" #include "ardour/audio_buffer.h"
#include "ardour/audioengine.h" #include "ardour/audioengine.h"
#include "ardour/debug.h" #include "ardour/debug.h"
#include "ardour/lv2_plugin.h" #include "ardour/lv2_plugin.h"
#include "ardour/session.h" #include "ardour/session.h"
#include "ardour/tempo.h" #include "ardour/tempo.h"
#include "ardour/types.h"
#include "ardour/utils.h"
#include "ardour/worker.h" #include "ardour/worker.h"
#include "i18n.h" #include "i18n.h"
@ -1023,42 +1024,40 @@ ARDOUR::lv2plugin_get_port_value(const char* port_symbol,
std::string std::string
LV2Plugin::do_save_preset(string name) LV2Plugin::do_save_preset(string name)
{ {
string pset_uri = uri(); const string base_name = legalize_for_uri(name);
pset_uri += "#"; const string file_name = base_name + ".ttl";
pset_uri += name; const string bundle = Glib::build_filename(
string save_dir = Glib::build_filename(
Glib::get_home_dir(), Glib::get_home_dir(),
Glib::build_filename(".lv2", "presets") Glib::build_filename(".lv2", base_name + ".lv2"));
);
LilvState* state = lilv_state_new_from_instance( LilvState* state = lilv_state_new_from_instance(
_impl->plugin, _impl->plugin,
_impl->instance, _impl->instance,
_uri_map.urid_map(), _uri_map.urid_map(),
scratch_dir().c_str(), // file_dir scratch_dir().c_str(), // file_dir
NULL, // copy_dir bundle.c_str(), // copy_dir
NULL, // link_dir bundle.c_str(), // link_dir
save_dir.c_str(), // save_dir bundle.c_str(), // save_dir
lv2plugin_get_port_value, // get_value lv2plugin_get_port_value, // get_value
(void*) this, // user_data (void*)this, // user_data
LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE, // flags LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE, // flags
_features // features _features // features
); );
lilv_state_set_label(state, name.c_str()); lilv_state_set_label(state, name.c_str());
lilv_state_save( lilv_state_save(
_world.world, // world _world.world, // world
_uri_map.urid_map(), // map _uri_map.urid_map(), // map
_uri_map.urid_unmap(), // unmap _uri_map.urid_unmap(), // unmap
state, // state state, // state
pset_uri.c_str(), // uri NULL, // uri (NULL = use file URI)
save_dir.c_str(), // dir bundle.c_str(), // dir
(name + ".ttl").c_str() // filename file_name.c_str() // filename
); );
lilv_state_free(state); lilv_state_free(state);
return pset_uri;
return Glib::filename_to_uri(Glib::build_filename(bundle, file_name));
} }
void void

View file

@ -111,6 +111,17 @@ legalize_for_universal_path (const string& str)
return replace_chars (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 /** 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 * 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 * version of this code, which used an approach that came to be seen as