From 684a8fd8fd54a391662e72b1113ddbda14e66612 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 30 Nov 2008 19:56:36 +0000 Subject: Some support for bundle saving. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@1831 a436a847-0d15-0410-975c-d299462d15a1 --- src/gui/LoadPatchWindow.cpp | 19 +++++++---- src/gui/PatchWindow.cpp | 44 +++++++++++++------------- src/gui/ThreadedLoader.cpp | 9 ++++-- src/serialisation/Serialiser.cpp | 68 +++++++++++++++++++++++++++++++++++++++- src/serialisation/Serialiser.hpp | 18 ++++++++++- 5 files changed, 127 insertions(+), 31 deletions(-) diff --git a/src/gui/LoadPatchWindow.cpp b/src/gui/LoadPatchWindow.cpp index caa6c8bf..5da4b459 100644 --- a/src/gui/LoadPatchWindow.cpp +++ b/src/gui/LoadPatchWindow.cpp @@ -45,19 +45,26 @@ LoadPatchWindow::LoadPatchWindow(BaseObjectType* cobject, const Glib::RefPtrget_widget("load_patch_ok_button", _ok_button); xml->get_widget("load_patch_cancel_button", _cancel_button); - _poly_from_current_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadPatchWindow::poly_from_file_selected)); - _poly_from_file_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadPatchWindow::poly_from_file_selected)); - _poly_from_user_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadPatchWindow::poly_from_user_selected)); - _ok_button->signal_clicked().connect(sigc::mem_fun(this, &LoadPatchWindow::ok_clicked)); - _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &LoadPatchWindow::cancel_clicked)); + _poly_from_current_radio->signal_toggled().connect( + sigc::mem_fun(this, &LoadPatchWindow::poly_from_file_selected)); + _poly_from_file_radio->signal_toggled().connect( + sigc::mem_fun(this, &LoadPatchWindow::poly_from_file_selected)); + _poly_from_user_radio->signal_toggled().connect( + sigc::mem_fun(this, &LoadPatchWindow::poly_from_user_selected)); + _ok_button->signal_clicked().connect( + sigc::mem_fun(this, &LoadPatchWindow::ok_clicked)); + _cancel_button->signal_clicked().connect( + sigc::mem_fun(this, &LoadPatchWindow::cancel_clicked)); _poly_from_current_radio->set_active(true); Gtk::FileFilter filt; filt.add_pattern("*.om"); filt.set_name("Om patch files (XML, DEPRECATED) (*.om)"); + filt.add_pattern("*.ingen.lv2"); + filt.set_name("Ingen bundles (*.ingen.lv2)"); filt.add_pattern("*.ingen.ttl"); - filt.set_name("Ingen patch files (RDF, *.ingen.ttl)"); + filt.set_name("Ingen patch files (*.ingen.ttl)"); set_filter(filt); // Add global examples directory to "shortcut folders" (bookmarks) diff --git a/src/gui/PatchWindow.cpp b/src/gui/PatchWindow.cpp index 7d9980df..707f5f0e 100644 --- a/src/gui/PatchWindow.cpp +++ b/src/gui/PatchWindow.cpp @@ -393,10 +393,10 @@ PatchWindow::event_save() if (doc == _patch->variables().end()) { event_save_as(); } else { - const Glib::ustring& filename = Glib::filename_from_uri(doc->second.get_string()); - App::instance().loader()->save_patch(_patch, filename); + const Glib::ustring& document_uri = doc->second.get_string(); + App::instance().loader()->save_patch(_patch, document_uri); _status_bar->push( - (boost::format("Wrote %1% to %2%") % _patch->path() % filename).str(), + (boost::format("Wrote %1% to %2%") % _patch->path() % document_uri).str(), STATUS_CONTEXT_PATCH); } } @@ -411,6 +411,13 @@ PatchWindow::event_save_as() Gtk::Button* save_button = dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK); save_button->property_has_default() = true; + Gtk::FileFilter filt; + filt.add_pattern("*.ingen.ttl"); + filt.set_name("Ingen patches"); + filt.add_pattern("*.ingen.lv2"); + filt.set_name("Ingen bundles"); + dialog.set_filter(filt); + // Set current folder to most sensible default GraphObject::Variables::const_iterator doc = _patch->variables().find("ingen:document"); if (doc != _patch->variables().end()) @@ -423,10 +430,14 @@ PatchWindow::event_save_as() if (result == Gtk::RESPONSE_OK) { string filename = dialog.get_filename(); - if (filename.length() < 11 || filename.substr(filename.length()-10) != ".ingen.ttl") + const bool is_bundle = filename.find(".ingen.lv2") != string::npos; + const bool is_patch = filename.find(".ingen.ttl") != string::npos; + + // Save a bundle by default + if (!is_bundle && !is_patch) filename += ".ingen.ttl"; - bool confirm = false; + bool confirm = true; std::fstream fin; fin.open(filename.c_str(), std::ios::in); if (fin.is_open()) { // File exists @@ -434,20 +445,16 @@ PatchWindow::event_save_as() msg += filename + "?"; Gtk::MessageDialog confirm_dialog(*this, msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true); - if (confirm_dialog.run() == Gtk::RESPONSE_YES) - confirm = true; - else - confirm = false; - } else { // File doesn't exist - confirm = true; + confirm = (confirm_dialog.run() == Gtk::RESPONSE_YES); } fin.close(); if (confirm) { - App::instance().loader()->save_patch(_patch, filename); - _patch->set_variable("ingen:document", Atom(Glib::filename_to_uri(filename).c_str())); + const Glib::ustring uri = Glib::filename_to_uri(filename); + App::instance().loader()->save_patch(_patch, uri); + _patch->set_variable("ingen:document", Atom(uri.c_str())); _status_bar->push( - (boost::format("Wrote %1% to %2%") % _patch->path() % filename).str(), + (boost::format("Wrote %1% to %2%") % _patch->path() % uri).str(), STATUS_CONTEXT_PATCH); } } @@ -478,7 +485,7 @@ PatchWindow::event_draw() if (filename.find(".") == string::npos) filename += ".dot"; - bool confirm = false; + bool confirm = true; std::fstream fin; fin.open(filename.c_str(), std::ios::in); if (fin.is_open()) { // File exists @@ -486,12 +493,7 @@ PatchWindow::event_draw() + "Are you sure you want to overwrite " + filename + "?"; Gtk::MessageDialog confirm_dialog(*this, msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true); - if (confirm_dialog.run() == Gtk::RESPONSE_YES) - confirm = true; - else - confirm = false; - } else { // File doesn't exist - confirm = true; + confirm = (confirm_dialog.run() == Gtk::RESPONSE_YES); } fin.close(); diff --git a/src/gui/ThreadedLoader.cpp b/src/gui/ThreadedLoader.cpp index 087ade58..d2bfec76 100644 --- a/src/gui/ThreadedLoader.cpp +++ b/src/gui/ThreadedLoader.cpp @@ -147,8 +147,13 @@ ThreadedLoader::save_patch(SharedPtr model, const string& filename) void ThreadedLoader::save_patch_event(SharedPtr model, const string& filename) { - if (App::instance().serialiser()) - App::instance().serialiser()->to_file(model, filename); + if (App::instance().serialiser()) { + Serialiser::Record r(model, filename); + if (filename.find(".ingen.lv2") != string::npos) + App::instance().serialiser()->write_bundle(r); + else + App::instance().serialiser()->to_file(r); + } } diff --git a/src/serialisation/Serialiser.cpp b/src/serialisation/Serialiser.cpp index baf8a475..0bb7b57d 100644 --- a/src/serialisation/Serialiser.cpp +++ b/src/serialisation/Serialiser.cpp @@ -27,6 +27,9 @@ #include #include // pair, make_pair #include +#include +#include +#include #include "raul/Atom.hpp" #include "raul/AtomRDF.hpp" #include "raul/Path.hpp" @@ -62,8 +65,11 @@ Serialiser::Serialiser(Shared::World& world, SharedPtr store) void -Serialiser::to_file(SharedPtr object, const string& filename) +Serialiser::to_file(const Record& record) { + SharedPtr object = record.object; + const string& filename = record.uri; + _root_path = object->path(); start_to_filename(filename); serialise(object); @@ -71,6 +77,66 @@ Serialiser::to_file(SharedPtr object, const string& filename) } +static +std::string +uri_to_symbol(const std::string& uri) +{ + string symbol = uri; + symbol = symbol.substr(symbol.find_last_of("/") + 1); + symbol = symbol.substr(0, symbol.find(".")); + symbol = Path::nameify(symbol); + return symbol; +} + + +void +Serialiser::write_manifest(const std::string& bundle_uri, + const Records& records) +{ + + cout << "WRITE MANIFEST BUNDLE URI: " << bundle_uri << endl; + const string filename = Glib::filename_from_uri(bundle_uri) + "manifest.ttl"; + cout << "FILENAME: " << filename << endl; + start_to_filename(filename); + _model->set_base_uri(bundle_uri); + for (Records::const_iterator i = records.begin(); i != records.end(); ++i) { + SharedPtr patch = PtrCast(i->object); + if (patch) { + const Redland::Node subject(_model->world(), Redland::Node::RESOURCE, + uri_to_symbol(i->uri)); + _model->add_statement(subject, "rdf:type", + Redland::Node(_model->world(), Redland::Node::RESOURCE, "ingen:Patch")); + _model->add_statement(subject, "rdf:type", + Redland::Node(_model->world(), Redland::Node::RESOURCE, "lv2:Plugin")); + _model->add_statement(subject, "rdfs:seeAlso", + Redland::Node(_model->world(), Redland::Node::RESOURCE, i->uri)); + } + } + finish(); +} + + +void +Serialiser::write_bundle(const Record& record) +{ + SharedPtr object = record.object; + string bundle_uri = record.uri; + if (bundle_uri[bundle_uri.length()-1] != '/') + bundle_uri.append("/"); + + g_mkdir_with_parents(Glib::filename_from_uri(bundle_uri).c_str(), 0744); + Records records; + + string symbol = uri_to_symbol(record.uri); + + const string root_file = bundle_uri + symbol + ".ingen.ttl"; + start_to_filename(root_file); + serialise(object); + finish(); + records.push_back(Record(object, bundle_uri + symbol + ".ingen.ttl")); + write_manifest(bundle_uri, records); +} + string Serialiser::to_string(SharedPtr object, diff --git a/src/serialisation/Serialiser.hpp b/src/serialisation/Serialiser.hpp index 4d33d771..6151bae2 100644 --- a/src/serialisation/Serialiser.hpp +++ b/src/serialisation/Serialiser.hpp @@ -58,7 +58,23 @@ class Serialiser public: Serialiser(Shared::World& world, SharedPtr store); - void to_file(SharedPtr object, const std::string& filename); + struct Record { + Record(SharedPtr o, const std::string& u) + : object(o), uri(u) + {} + + const SharedPtr object; + const std::string uri; + }; + + typedef std::list Records; + + void to_file(const Record& record); + + void write_bundle(const Record& record); + + void write_manifest(const std::string& bundle_uri, + const Records& records); std::string to_string(SharedPtr object, const std::string& base_uri, -- cgit v1.2.1