diff options
author | David Robillard <d@drobilla.net> | 2012-05-12 03:31:57 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2012-05-12 03:31:57 +0000 |
commit | 8211b45bffe20e8a271396b7568609a84b7cf0ec (patch) | |
tree | 8f2b9557977c0b7a681cb8fc2209c554213c1e66 | |
parent | 271b3f9d7f376cbbaef202ef6f898e5f9bb4c324 (diff) | |
download | ingen-8211b45bffe20e8a271396b7568609a84b7cf0ec.tar.gz ingen-8211b45bffe20e8a271396b7568609a84b7cf0ec.tar.bz2 ingen-8211b45bffe20e8a271396b7568609a84b7cf0ec.zip |
Get copy and paste working again.
Client side and text based is probably not the idea way to go about implementing this, but it more or less works and is certainly better than nothing for now.
Copy paste of patch ports, and pasting into any path other than the root still isn't working currently.
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@4367 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r-- | bundles/ingen.lv2/ingen.ttl | 12 | ||||
-rw-r--r-- | ingen/shared/URIs.hpp | 1 | ||||
-rw-r--r-- | src/client/ClientStore.cpp | 6 | ||||
-rw-r--r-- | src/gui/PatchCanvas.cpp | 69 | ||||
-rw-r--r-- | src/serialisation/Parser.cpp | 129 | ||||
-rw-r--r-- | src/serialisation/Serialiser.cpp | 12 | ||||
-rw-r--r-- | src/shared/URIs.cpp | 1 |
7 files changed, 125 insertions, 105 deletions
diff --git a/bundles/ingen.lv2/ingen.ttl b/bundles/ingen.lv2/ingen.ttl index 95c26836..71124bb8 100644 --- a/bundles/ingen.lv2/ingen.ttl +++ b/bundles/ingen.lv2/ingen.ttl @@ -111,18 +111,6 @@ ingen:enabled rdfs:label "Enabled" ; rdfs:comment "Signifies the node is or should be running." . -ingen:Port - a owl:Class ; - rdfs:subClassOf ingen:Object ; - rdfs:label "Port" ; - rdfs:comment """ -A Port is an input or output on a Node. It is implicitly an instance of the -corresponding port on that Node's plugin (specified with ingen:prototype). -A Port MUST have a legal lv2:symbol in the exact way a Node must, see :Node -documentation for details. Ports inherit properties from the Port on their -parent's Plugin in the exact way Nodes inherit properties from their Plugin. -""" . - ingen:Edge a owl:Class ; rdfs:label "Edge" ; diff --git a/ingen/shared/URIs.hpp b/ingen/shared/URIs.hpp index 545a2bf0..0fd2cbdc 100644 --- a/ingen/shared/URIs.hpp +++ b/ingen/shared/URIs.hpp @@ -73,7 +73,6 @@ public: const Quark ingen_Internal; const Quark ingen_Node; const Quark ingen_Patch; - const Quark ingen_Port; const Quark ingen_activity; const Quark ingen_broadcast; const Quark ingen_canvasX; diff --git a/src/client/ClientStore.cpp b/src/client/ClientStore.cpp index a78653e5..75acef63 100644 --- a/src/client/ClientStore.cpp +++ b/src/client/ClientStore.cpp @@ -459,9 +459,11 @@ ClientStore::attempt_connection(const Raul::Path& tail_path, patch->add_edge(cm); return true; + } else { + LOG(Raul::warn) << "Failed to connect " << tail_path + << " => " << head_path << std::endl; + return false; } - - return false; } void diff --git a/src/gui/PatchCanvas.cpp b/src/gui/PatchCanvas.cpp index 3562a007..640051cb 100644 --- a/src/gui/PatchCanvas.cpp +++ b/src/gui/PatchCanvas.cpp @@ -637,42 +637,56 @@ PatchCanvas::destroy_selection() for_each_selected_edge(destroy_edge, &_app); } -void -PatchCanvas::copy_selection() +static void +serialise_node(GanvNode* node, void* data) { - std::cerr << "FIXME: copy" << std::endl; - #if 0 - static const char* base_uri = ""; - Serialiser serialiser(*_app.world(), _app.store()); - serialiser.start_to_string(_patch->path(), base_uri); + Serialisation::Serialiser* serialiser = (Serialisation::Serialiser*)data; + if (!GANV_IS_MODULE(node)) { + return; + } - FOREACH_ITEM(m, selected_items()) { - NodeModule* module = dynamic_cast<NodeModule*>(*m); - if (module) { - serialiser.serialise(module->node()); - } else { - PatchPortModule* port_module = dynamic_cast<PatchPortModule*>(*m); - if (port_module) - serialiser.serialise(port_module->port()); + Ganv::Module* module = Glib::wrap(GANV_MODULE(node)); + NodeModule* node_module = dynamic_cast<NodeModule*>(module); + + if (node_module) { + serialiser->serialise(node_module->node()); + } else { + PatchPortModule* port_module = dynamic_cast<PatchPortModule*>(module); + if (port_module) { + serialiser->serialise(port_module->port()); } } +} - for (SelectedEdges::const_iterator c = selected_edges().begin(); - c != selected_edges().end(); ++c) { - Edge* const edge = dynamic_cast<Edge*>(*c); - if (edge) { - const Sord::URI subject(*_app.world()->rdf_world(), - base_uri); - serialiser.serialise_edge(subject, edge->model()); - } +static void +serialise_edge(GanvEdge* edge, void* data) +{ + Serialisation::Serialiser* serialiser = (Serialisation::Serialiser*)data; + if (!GANV_IS_EDGE(edge)) { + return; + } + + GUI::Edge* gedge = dynamic_cast<GUI::Edge*>(Glib::wrap(GANV_EDGE(edge))); + if (gedge) { + serialiser->serialise_edge(Sord::Node(), gedge->model()); } +} + +void +PatchCanvas::copy_selection() +{ + static const char* base_uri = "http://drobilla.net/ns/ingen/selection/"; + Serialisation::Serialiser serialiser(*_app.world()); + serialiser.start_to_string(_patch->path(), base_uri); + + for_each_selected_node(serialise_node, &serialiser); + for_each_selected_edge(serialise_edge, &serialiser); - string result = serialiser.finish(); + const std::string result = serialiser.finish(); _paste_count = 0; Glib::RefPtr<Gtk::Clipboard> clipboard = Gtk::Clipboard::get(); clipboard->set_text(result); - #endif } void @@ -702,7 +716,7 @@ PatchCanvas::paste() uris.ingen_Patch)); props.insert(make_pair(uris.ingen_polyphony, _app.forge().make(int32_t(_patch->internal_poly())))); - clipboard.put(Path(), props); + clipboard.put(Path("/"), props); size_t first_slash; while (to_create != "/" && !to_create.empty() && (first_slash = to_create.find("/")) != string::npos) { @@ -723,7 +737,8 @@ PatchCanvas::paste() } ClashAvoider avoider(*_app.store().get(), clipboard, &clipboard); - parser->parse_string(_app.world(), &avoider, str, "", + static const char* base_uri = "http://drobilla.net/ns/ingen/selection/"; + parser->parse_string(_app.world(), &avoider, str, base_uri, parent, symbol); for (Store::iterator i = clipboard.begin(); i != clipboard.end(); ++i) { diff --git a/src/serialisation/Parser.cpp b/src/serialisation/Parser.cpp index df17d7ff..2c56dc1e 100644 --- a/src/serialisation/Parser.cpp +++ b/src/serialisation/Parser.cpp @@ -177,6 +177,7 @@ parse( Interface* target, Sord::Model& model, Glib::ustring document_uri, + Sord::Node& subject, boost::optional<Raul::Path> parent = boost::optional<Raul::Path>(), boost::optional<Raul::Symbol> symbol = boost::optional<Raul::Symbol>(), boost::optional<Resource::Properties> data = boost::optional<Resource::Properties>()); @@ -397,49 +398,57 @@ parse_patch(Ingen::Shared::World* world, } static bool -parse_edges(Ingen::Shared::World* world, - Ingen::Interface* target, - Sord::Model& model, - const Sord::Node& subject, - const Raul::Path& parent) +parse_edge(Ingen::Shared::World* world, + Ingen::Interface* target, + Sord::Model& model, + const Sord::Node& subject, + const Raul::Path& parent) { - Sord::URI ingen_edge(*world->rdf_world(), NS_INGEN "edge"); Sord::URI ingen_tail(*world->rdf_world(), NS_INGEN "tail"); Sord::URI ingen_head(*world->rdf_world(), NS_INGEN "head"); + Sord::Iter t = model.find(subject, ingen_tail, nil); + Sord::Iter h = model.find(subject, ingen_head, nil); + const Glib::ustring& base_uri = model.base_uri().to_string(); - RDFNodes connections; - for (Sord::Iter i = model.find(subject, ingen_edge, nil); !i.end(); ++i) { - connections.insert(i.get_object()); + if (t.end()) { + LOG(error) << "Edge has no tail" << endl; + return false; + } else if (h.end()) { + LOG(error) << "Edge has no head" << endl; + return false; } - for (RDFNodes::const_iterator i = connections.begin(); i != connections.end(); ++i) { - Sord::Iter t = model.find(*i, ingen_tail, nil); - Sord::Iter h = model.find(*i, ingen_head, nil); + const Path tail_path( + parent.child(relative_uri(base_uri, t.get_object().to_string(), false))); + const Path head_path( + parent.child(relative_uri(base_uri, h.get_object().to_string(), false))); - if (t.end()) { - LOG(error) << "Edge has no tail" << endl; - return false; - } else if (h.end()) { - LOG(error) << "Edge has no head" << endl; - return false; - } + if (!(++t).end()) { + LOG(error) << "Edge has multiple tails" << endl; + return false; + } else if (!(++h).end()) { + LOG(error) << "Edge has multiple heads" << endl; + return false; + } - const Path tail_path( - parent.child(relative_uri(base_uri, t.get_object().to_string(), false))); - const Path head_path( - parent.child(relative_uri(base_uri, h.get_object().to_string(), false))); - - if (!(++t).end()) { - LOG(error) << "Edge has multiple tails" << endl; - return false; - } else if (!(++h).end()) { - LOG(error) << "Edge has multiple heads" << endl; - return false; - } + target->connect(tail_path, head_path); - target->connect(tail_path, head_path); + return true; +} + +static bool +parse_edges(Ingen::Shared::World* world, + Ingen::Interface* target, + Sord::Model& model, + const Sord::Node& subject, + const Raul::Path& parent) +{ + Sord::URI ingen_edge(*world->rdf_world(), NS_INGEN "edge"); + + for (Sord::Iter i = model.find(subject, ingen_edge, nil); !i.end(); ++i) { + parse_edge(world, target, model, i.get_object(), parent); } return true; @@ -469,24 +478,23 @@ parse(Ingen::Shared::World* world, Ingen::Interface* target, Sord::Model& model, Glib::ustring document_uri, + Sord::Node& subject, boost::optional<Raul::Path> parent, boost::optional<Raul::Symbol> symbol, boost::optional<GraphObject::Properties> data) { const Sord::URI patch_class (*world->rdf_world(), NS_INGEN "Patch"); const Sord::URI node_class (*world->rdf_world(), NS_INGEN "Node"); - const Sord::URI port_class (*world->rdf_world(), NS_INGEN "Port"); + const Sord::URI edge_class (*world->rdf_world(), NS_INGEN "Edge"); const Sord::URI internal_class(*world->rdf_world(), NS_INGEN "Internal"); const Sord::URI in_port_class (*world->rdf_world(), LV2_CORE__InputPort); const Sord::URI out_port_class(*world->rdf_world(), LV2_CORE__OutputPort); const Sord::URI lv2_class (*world->rdf_world(), LV2_CORE__Plugin); - const Sord::URI rdf_type (*world->rdf_world(), NS_RDF "type"); - - Sord::Node subject = model.base_uri(); + const Sord::URI rdf_type (*world->rdf_world(), NS_RDF "type"); - Raul::Path path("/"); - if (parent && symbol) { - path = parent->child(*symbol); + // Parse explicit subject patch + if (subject.is_valid()) { + return parse_patch(world, target, model, subject, parent, symbol, data); } // Get all subjects and their types (?subject a ?type) @@ -508,19 +516,23 @@ parse(Ingen::Shared::World* world, } // Parse and create each subject - boost::optional<Path> ret; for (Subjects::const_iterator i = subjects.begin(); i != subjects.end(); ++i) { - const Sord::Node& subject = i->first; - const std::set<Sord::Node>& types = i->second; + const Sord::Node& s = i->first; + const std::set<Sord::Node>& types = i->second; + boost::optional<Path> ret; + const Raul::Path path( + relative_uri( model.base_uri().to_string(), s.to_string(), true)); if (types.find(patch_class) != types.end()) { - ret = parse_patch(world, target, model, subject, parent, symbol, data); + ret = parse_patch(world, target, model, s, parent, symbol, data); } else if (types.find(node_class) != types.end()) { - ret = parse_node(world, target, model, - subject, path.child(subject.to_string()), - data); - } else if (types.find(port_class) != types.end()) { - parse_properties(world, target, model, subject, path, data); + ret = parse_node(world, target, model, s, path, data); + } else if (types.find(in_port_class) != types.end() || + types.find(out_port_class) != types.end()) { + parse_properties(world, target, model, s, path, data); ret = path; + } else if (types.find(edge_class) != types.end()) { + Path parent_path(parent ? parent.get() : Path("/")); + parse_edge(world, target, model, s, parent_path); } else { LOG(error) << "Subject has no known types" << endl; } @@ -533,11 +545,10 @@ parse(Ingen::Shared::World* world, LOG(error) << " :: " << *t << endl; assert((*t).is_uri()); } - return boost::optional<Path>(); } } - return path; + return boost::optional<Path>(); } Parser::Parser(Ingen::Shared::World& world) @@ -578,7 +589,7 @@ Parser::parse_file(Ingen::Shared::World* world, SerdEnv* env = serd_env_new(&base_node); // Load patch file into model - Sord::Model model(*world->rdf_world(), uri); + Sord::Model model(*world->rdf_world(), uri, SORD_SPO|SORD_PSO, false); model.load_file(env, SERD_TURTLE, uri); serd_env_free(env); @@ -589,8 +600,9 @@ Parser::parse_file(Ingen::Shared::World* world, if (symbol) LOG(Raul::info)(Raul::fmt("Symbol: %1%\n") % symbol->c_str()); + Sord::Node subject(*world->rdf_world(), Sord::Node::URI, uri); boost::optional<Path> parsed_path - = parse(world, target, model, path, parent, symbol, data); + = parse(world, target, model, path, subject, parent, symbol, data); if (parsed_path) { target->set_property(*parsed_path, "http://drobilla.net/ns/ingen#document", @@ -612,8 +624,10 @@ Parser::parse_string(Ingen::Shared::World* world, boost::optional<GraphObject::Properties> data) { // Load string into model - Sord::Model model(*world->rdf_world(), base_uri); - SerdEnv* env = serd_env_new(NULL); + Sord::Model model(*world->rdf_world(), base_uri, SORD_SPO|SORD_PSO, false); + const SerdNode base = serd_node_from_string( + SERD_URI, (const uint8_t*)base_uri.c_str()); + SerdEnv* env = serd_env_new(&base); model.load_string(env, SERD_TURTLE, str.c_str(), str.length(), base_uri); serd_env_free(env); @@ -622,11 +636,8 @@ Parser::parse_string(Ingen::Shared::World* world, info << " (base " << base_uri << ")"; info << endl; - bool ret = parse(world, target, model, base_uri, parent, symbol, data); - Sord::URI subject(*world->rdf_world(), base_uri); - parse_edges(world, target, model, subject, parent ? *parent : "/"); - - return ret; + Sord::Node subject; + return parse(world, target, model, base_uri, subject, parent, symbol, data); } } // namespace Serialisation diff --git a/src/serialisation/Serialiser.cpp b/src/serialisation/Serialiser.cpp index 6e126c42..6a674eb5 100644 --- a/src/serialisation/Serialiser.cpp +++ b/src/serialisation/Serialiser.cpp @@ -526,9 +526,15 @@ Serialiser::Impl::serialise_edge(const Sord::Node& parent, Sord::Curie(world, "ingen:head"), dst); - _model->add_statement(parent, - Sord::Curie(world, "ingen:edge"), - edge_id); + if (parent.is_valid()) { + _model->add_statement(parent, + Sord::Curie(world, "ingen:edge"), + edge_id); + } else { + _model->add_statement(edge_id, + Sord::Curie(world, "rdf:type"), + Sord::Curie(world, "ingen:Edge")); + } } static bool diff --git a/src/shared/URIs.cpp b/src/shared/URIs.cpp index 6cc32c0b..abb0a011 100644 --- a/src/shared/URIs.cpp +++ b/src/shared/URIs.cpp @@ -68,7 +68,6 @@ URIs::URIs(Shared::Forge& f, URIMap* map) , ingen_Internal (forge, map, NS_INGEN "Internal") , ingen_Node (forge, map, NS_INGEN "Node") , ingen_Patch (forge, map, NS_INGEN "Patch") - , ingen_Port (forge, map, NS_INGEN "Port") , ingen_activity (forge, map, NS_INGEN "activity") , ingen_broadcast (forge, map, NS_INGEN "broadcast") , ingen_canvasX (forge, map, NS_INGEN "canvasX") |