summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/util/RedlandAtom.h21
-rw-r--r--src/libs/client/Serializer.cpp149
-rw-r--r--src/libs/client/Serializer.h38
-rw-r--r--src/libs/client/Store.cpp6
-rw-r--r--src/progs/ingenuity/Connection.h56
-rw-r--r--src/progs/ingenuity/Loader.cpp2
-rw-r--r--src/progs/ingenuity/Makefile.am1
-rw-r--r--src/progs/ingenuity/NodeModule.cpp3
-rw-r--r--src/progs/ingenuity/PatchCanvas.cpp41
-rw-r--r--src/progs/ingenuity/PatchCanvas.h3
-rw-r--r--src/progs/ingenuity/PatchWindow.cpp24
-rw-r--r--src/progs/ingenuity/PatchWindow.h6
-rw-r--r--src/progs/ingenuity/ingenuity.glade67
13 files changed, 326 insertions, 91 deletions
diff --git a/src/common/util/RedlandAtom.h b/src/common/util/RedlandAtom.h
index df55affb..8d2456a5 100644
--- a/src/common/util/RedlandAtom.h
+++ b/src/common/util/RedlandAtom.h
@@ -17,6 +17,7 @@
#ifndef REDLAND_ATOM_H
#define REDLAND_ATOM_H
+#include <sstream>
#include <cstring>
#include <raptor.h>
#include "util/Atom.h"
@@ -34,37 +35,35 @@ public:
* Caller is responsible for calling free(triple->object).
*/
static void atom_to_triple_object(raptor_statement* triple, const Atom& atom) {
- static const size_t STR_LENGTH = 32; // FIXME ?
- char* str = (char*)malloc(sizeof(char) * STR_LENGTH);
+ std::ostringstream os;
+
+ triple->object_literal_language = NULL;
switch (atom.type()) {
case Atom::INT:
- snprintf(str, 32, "%d", atom.get_int32());
- triple->object = (unsigned char*)str;
+ os << atom.get_int32();
+ triple->object = (unsigned char*)strdup(os.str().c_str());
triple->object_type = RAPTOR_IDENTIFIER_TYPE_LITERAL;
triple->object_literal_datatype = raptor_new_uri(
U("http://www.w3.org/2001/XMLSchema#integer"));
break;
case Atom::FLOAT:
- snprintf(str, 32, "%f", atom.get_float());
- triple->object = (unsigned char*)str;
+ os << atom.get_float();
+ triple->object = (unsigned char*)strdup(os.str().c_str());
triple->object_type = RAPTOR_IDENTIFIER_TYPE_LITERAL;
triple->object_literal_datatype = raptor_new_uri(
U("http://www.w3.org/2001/XMLSchema#float"));
break;
case Atom::STRING:
- snprintf(str, 32, "%f", atom.get_float());
- triple->object = (unsigned char*)str;
+ triple->object = strdup(atom.get_string());
triple->object_type = RAPTOR_IDENTIFIER_TYPE_LITERAL;
break;
case Atom::BLOB:
case Atom::NIL:
default:
- cerr << "WARNING: Unserializable atom!" << endl;
- // FIXME: what to do?
+ cerr << "WARNING: Unserializable Atom!" << endl;
triple->object = NULL;
triple->object_type = RAPTOR_IDENTIFIER_TYPE_UNKNOWN;
- free(str); // FIXME: ew
}
}
diff --git a/src/libs/client/Serializer.cpp b/src/libs/client/Serializer.cpp
index d7c1a153..6bfa08d6 100644
--- a/src/libs/client/Serializer.cpp
+++ b/src/libs/client/Serializer.cpp
@@ -70,8 +70,11 @@ Serializer::~Serializer()
* This must be called before any serializing methods.
*/
void
-Serializer::start_to_filename(const string& filename)
+Serializer::start_to_filename(const string& filename) throw(std::logic_error)
{
+ if (_serializer)
+ throw std::logic_error("start_to_string called with serialization in progress");
+
raptor_init();
_serializer = raptor_new_serializer("rdfxml-abbrev");
setup_prefixes();
@@ -87,8 +90,12 @@ Serializer::start_to_filename(const string& filename)
* the desired objects have been serialized.
*/
void
-Serializer::start_to_string()
+Serializer::start_to_string() throw(std::logic_error)
{
+ if (_serializer)
+ throw std::logic_error("start_to_string called with serialization in progress");
+
+ raptor_init();
_serializer = raptor_new_serializer("rdfxml-abbrev");
setup_prefixes();
raptor_serialize_start_to_string(_serializer,
@@ -207,9 +214,12 @@ Serializer::find_file(const string& filename, const string& additional_path)
void
-Serializer::add_resource_to_rdf(raptor_serializer* rdf,
- const string& subject_uri, const string& predicate_uri, const string& object_uri)
+Serializer::serialize_resource(const string& subject_uri,
+ const string& predicate_uri,
+ const string& object_uri)
{
+ assert(_serializer);
+
raptor_statement triple;
triple.subject = (void*)raptor_new_uri((const unsigned char*)subject_uri.c_str());
triple.subject_type = RAPTOR_IDENTIFIER_TYPE_RESOURCE;
@@ -217,12 +227,28 @@ Serializer::add_resource_to_rdf(raptor_serializer* rdf,
triple.predicate_type = RAPTOR_IDENTIFIER_TYPE_RESOURCE;
triple.object = (void*)raptor_new_uri((const unsigned char*)object_uri.c_str());
triple.object_type = RAPTOR_IDENTIFIER_TYPE_RESOURCE;
- raptor_serialize_statement(rdf, &triple);
+ raptor_serialize_statement(_serializer, &triple);
}
+void
+Serializer::serialize_resource(raptor_identifier* subject,
+ const string& predicate_uri,
+ const string& object_uri)
+{
+ assert(_serializer);
+
+ raptor_statement triple;
+ triple.subject = subject;
+ triple.subject_type = subject->type;
+ triple.predicate = (void*)raptor_new_uri((const unsigned char*)predicate_uri.c_str());
+ triple.predicate_type = RAPTOR_IDENTIFIER_TYPE_RESOURCE;
+ triple.object = (void*)raptor_new_uri((const unsigned char*)object_uri.c_str());
+ triple.object_type = RAPTOR_IDENTIFIER_TYPE_RESOURCE;
+ raptor_serialize_statement(_serializer, &triple);
+}
#if 0
void
-Serializer::add_resource_to_rdf(raptor_serializer* rdf
+Serializer::serialize_resource(raptor_serializer* rdf
librdf_node* subject, const string& predicate_uri, const string& object_uri)
{
cerr << "FIXME: serialize blank node\n";
@@ -245,9 +271,11 @@ Serializer::add_resource_to_rdf(raptor_serializer* rdf
#endif
void
-Serializer::add_atom_to_rdf(raptor_serializer* rdf,
+Serializer::serialize_atom(
const string& subject_uri, const string& predicate_uri, const Atom& atom)
{
+ assert(_serializer);
+
raptor_statement triple;
triple.subject = (void*)raptor_new_uri((const unsigned char*)subject_uri.c_str());
triple.subject_type = RAPTOR_IDENTIFIER_TYPE_RESOURCE;
@@ -256,47 +284,75 @@ Serializer::add_atom_to_rdf(raptor_serializer* rdf,
RedlandAtom::atom_to_triple_object(&triple, atom);
- raptor_serialize_statement(rdf, &triple);
+ raptor_serialize_statement(_serializer, &triple);
}
void
-Serializer::serialize_patch(CountedPtr<PatchModel> patch) throw (std::logic_error)
+Serializer::serialize(CountedPtr<ObjectModel> object) throw (std::logic_error)
{
if (!_serializer)
throw std::logic_error("serialize_patch called without serialization in progress");
+ CountedPtr<PatchModel> patch = PtrCast<PatchModel>(object);
+ if (patch) {
+ serialize_patch(patch);
+ return;
+ }
+
+ CountedPtr<NodeModel> node = PtrCast<NodeModel>(object);
+ if (node) {
+ serialize_node(node);
+ return;
+ }
+
+ CountedPtr<PortModel> port = PtrCast<PortModel>(object);
+ if (port) {
+ serialize_port(port);
+ return;
+ }
+
+ cerr << "[Serializer] WARNING: Unsupported object type, "
+ << object->path() << " not serialized." << endl;
+}
+
+
+void
+Serializer::serialize_patch(CountedPtr<PatchModel> patch)
+{
+ assert(_serializer);
+
const string uri = "#";
- add_resource_to_rdf(_serializer,
+ serialize_resource(
uri.c_str(),
NS_RDF("type"),
NS_INGEN("Patch"));
if (patch->path().name().length() > 0) {
- add_atom_to_rdf(_serializer,
+ serialize_atom(
uri.c_str(),
NS_INGEN("name"),
Atom(patch->path().name().c_str()));
}
- add_atom_to_rdf(_serializer,
+ serialize_atom(
uri.c_str(),
NS_INGEN("polyphony"),
Atom((int)patch->poly()));
for (NodeModelMap::const_iterator n = patch->nodes().begin(); n != patch->nodes().end(); ++n) {
- add_node_to_rdf(_serializer, n->second, "#");
- add_resource_to_rdf(_serializer, "#", NS_INGEN("node"), uri + n->second->path().name());
+ serialize_node(n->second, "#");
+ serialize_resource("#", NS_INGEN("node"), uri + n->second->path().name());
}
for (PortModelList::const_iterator p = patch->ports().begin(); p != patch->ports().end(); ++p) {
- add_port_to_rdf(_serializer, *p, uri);
- add_resource_to_rdf(_serializer, "#", NS_INGEN("port"), uri + (*p)->path().name());
+ serialize_port(*p, uri);
+ serialize_resource("#", NS_INGEN("port"), uri + (*p)->path().name());
}
for (ConnectionList::const_iterator c = patch->connections().begin(); c != patch->connections().end(); ++c) {
- add_connection_to_rdf(_serializer, *c, uri);
+ serialize_connection(*c/*, uri*/);
}
//_engine->set_metadata(patch->path(), "uri", uri);
@@ -304,29 +360,31 @@ Serializer::serialize_patch(CountedPtr<PatchModel> patch) throw (std::logic_erro
void
-Serializer::add_node_to_rdf(raptor_serializer* rdf,
+Serializer::serialize_node(
CountedPtr<NodeModel> node, const string ns_prefix)
{
+ assert(_serializer);
+
const string node_uri = ns_prefix + node->path().name();
- add_resource_to_rdf(_serializer,
+ serialize_resource(
node_uri.c_str(),
NS_RDF("type"),
NS_INGEN("Node"));
- /*add_atom_to_rdf(_serializer,
+ /*serialize_atom(_serializer,
node_uri_ref.c_str(),
NS_INGEN("name"),
Atom(node->path().name()));*/
for (PortModelList::const_iterator p = node->ports().begin(); p != node->ports().end(); ++p) {
- add_port_to_rdf(_serializer, *p, node_uri + "/");
- add_resource_to_rdf(_serializer, node_uri, NS_INGEN("port"), node_uri + "/" + (*p)->path().name());
+ serialize_port(*p, node_uri + "/");
+ serialize_resource(node_uri, NS_INGEN("port"), node_uri + "/" + (*p)->path().name());
}
for (MetadataMap::const_iterator m = node->metadata().begin(); m != node->metadata().end(); ++m) {
if (expand_uri(m->first) != "") {
- add_atom_to_rdf(_serializer,
+ serialize_atom(
node_uri.c_str(),
expand_uri(m->first.c_str()).c_str(),
m->second);
@@ -336,19 +394,20 @@ Serializer::add_node_to_rdf(raptor_serializer* rdf,
void
-Serializer::add_port_to_rdf(raptor_serializer* rdf,
- CountedPtr<PortModel> port, const string ns_prefix)
+Serializer::serialize_port(CountedPtr<PortModel> port, const string ns_prefix)
{
+ assert(_serializer);
+
const string port_uri_ref = ns_prefix + port->path().name();
- add_resource_to_rdf(_serializer,
+ serialize_resource(
port_uri_ref.c_str(),
NS_RDF("type"),
NS_INGEN("Port"));
for (MetadataMap::const_iterator m = port->metadata().begin(); m != port->metadata().end(); ++m) {
if (expand_uri(m->first) != "") {
- add_atom_to_rdf(_serializer,
+ serialize_atom(
port_uri_ref.c_str(),
expand_uri(m->first).c_str(),
m->second);
@@ -358,28 +417,34 @@ Serializer::add_port_to_rdf(raptor_serializer* rdf,
void
-Serializer::add_connection_to_rdf(raptor_serializer* rdf,
- CountedPtr<ConnectionModel> connection, const string ns_prefix)
+Serializer::serialize_connection(CountedPtr<ConnectionModel> connection) throw (std::logic_error)
{
- cerr << "FIXME: serialize connection\n";
-#if 0
- librdf_node* c = librdf_new_node(_world);
+ assert(_serializer);
+
+ string ns_prefix = "";
+
+ // FIXME FIXME FIXME: strip ":" and make sure ID is a valid XMLID!
+
+ raptor_identifier* c = raptor_new_identifier(RAPTOR_IDENTIFIER_TYPE_ANONYMOUS,
+ NULL, RAPTOR_URI_SOURCE_BLANK_ID,
+ (unsigned char*)((
+ connection->src_port_path().parent().name() +"."+ connection->src_port_path().name()
+ + connection->dst_port_path().parent().name() +"."+ connection->dst_port_path().name()
+ ).c_str()),
+ NULL, NULL, NULL);
const string src_port_rel_path = connection->src_port_path().substr(connection->patch_path().length());
const string dst_port_rel_path = connection->dst_port_path().substr(connection->patch_path().length());
- librdf_statement* s = librdf_new_statement_from_nodes(_world, c,
- librdf_new_node_from_uri_string(_world, U(NS_INGEN("source"))),
- librdf_new_node_from_uri_string(_world, U((ns_prefix + src_port_rel_path).c_str())));
- librdf_model_add_statement(_serializer, s);
+ serialize_resource(c,
+ NS_INGEN("source"),
+ ns_prefix + src_port_rel_path);
- librdf_statement* d = librdf_new_statement_from_nodes(_world, c,
- librdf_new_node_from_uri_string(_world, U(NS_INGEN("destination"))),
- librdf_new_node_from_uri_string(_world, U((ns_prefix + dst_port_rel_path).c_str())));
- librdf_model_add_statement(_serializer, d);
+ serialize_resource(c,
+ NS_INGEN("destination"),
+ ns_prefix + dst_port_rel_path);
- add_resource_to_rdf(_serializer, c, NS_RDF("type"), NS_INGEN("Connection"));
-#endif
+ serialize_resource(c, NS_RDF("type"), NS_INGEN("Connection"));
}
diff --git a/src/libs/client/Serializer.h b/src/libs/client/Serializer.h
index a563dbb8..1af18de7 100644
--- a/src/libs/client/Serializer.h
+++ b/src/libs/client/Serializer.h
@@ -68,37 +68,39 @@ public:
MetadataMap initial_data,
bool existing = false);
- void start_to_filename(const string& filename);
- void start_to_string();
-
- void serialize_patch(CountedPtr<PatchModel> patch) throw(std::logic_error);
-
- string finish() throw(std::logic_error);
+ void start_to_filename(const string& filename) throw (std::logic_error);
+ void start_to_string() throw (std::logic_error);
+ void serialize(CountedPtr<ObjectModel> object) throw (std::logic_error);
+ void serialize_connection(CountedPtr<ConnectionModel> c) throw (std::logic_error);
+ string finish() throw (std::logic_error);
private:
// Model -> RDF
- void add_node_to_rdf(raptor_serializer* rdf,
- CountedPtr<NodeModel> node, const string ns_prefix="");
+ void serialize_patch(CountedPtr<PatchModel> p);
+
+ void serialize_node(CountedPtr<NodeModel> n, const string ns_prefix="");
- void add_port_to_rdf(raptor_serializer* rdf,
- CountedPtr<PortModel> port, const string ns_prefix="");
+ void serialize_port(CountedPtr<PortModel> p, const string ns_prefix="");
- void add_connection_to_rdf(raptor_serializer* rdf,
- CountedPtr<ConnectionModel> connection, const string port_ns_prefix="");
+
// Triple -> RDF
- void add_resource_to_rdf(raptor_serializer* rdf,
- const string& subject_uri, const string& predicate_uri, const string& object_uri);
+ void serialize_resource(const string& subject_uri,
+ const string& predicate_uri,
+ const string& object_uri);
- //void add_resource_to_rdf(raptor_serializer* rdf
- // librdf_node* subject, const string& predicate_uri, const string& object_uri);
+
+ void serialize_resource(raptor_identifier* subject,
+ const string& predicate_uri,
+ const string& object_uri);
- void add_atom_to_rdf(raptor_serializer* rdf,
- const string& subject_uri, const string& predicate_uri, const Atom& atom);
+ void serialize_atom(const string& subject_uri,
+ const string& predicate_uri,
+ const Atom& atom);
void setup_prefixes();
string expand_uri(const string& uri);
diff --git a/src/libs/client/Store.cpp b/src/libs/client/Store.cpp
index f9b3f17a..fb16697b 100644
--- a/src/libs/client/Store.cpp
+++ b/src/libs/client/Store.cpp
@@ -435,7 +435,7 @@ Store::metadata_update_event(const Path& subject_path, const string& predicate,
subject->set_metadata(predicate, value);
} else {
add_metadata_orphan(subject_path, predicate, value);
- cerr << "WARNING: metadata for unknown object." << endl;
+ cerr << "WARNING: metadata for unknown object " << subject_path << endl;
}
}
@@ -447,7 +447,7 @@ Store::control_change_event(const Path& port_path, float value)
if (port)
port->value(value);
else
- cerr << "ERROR: metadata for nonexistant object." << endl;
+ cerr << "ERROR: control change for nonexistant port " << port_path << endl;
}
@@ -504,7 +504,7 @@ Store::disconnection_event(const Path& src_port_path, const Path& dst_port_path)
if (patch)
patch->remove_connection(src_port_path, dst_port_path);
else
- cerr << "ERROR: disconnection in nonexistant patch" << endl;
+ cerr << "ERROR: disconnection in nonexistant patch " << cm->patch_path() << endl;
}
diff --git a/src/progs/ingenuity/Connection.h b/src/progs/ingenuity/Connection.h
new file mode 100644
index 00000000..08e37e57
--- /dev/null
+++ b/src/progs/ingenuity/Connection.h
@@ -0,0 +1,56 @@
+/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard.
+ *
+ * Ingen is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef CONNECTION_H
+#define CONNECTION_H
+
+#include <cassert>
+#include <string>
+#include <flowcanvas/Connection.h>
+#include "ConnectionModel.h"
+#include "util/CountedPtr.h"
+using Ingen::Client::ConnectionModel;
+
+namespace Ingenuity {
+
+
+/** A Connection on an Module.
+ *
+ * \ingroup Ingenuity
+ */
+class Connection : public LibFlowCanvas::Connection
+{
+public:
+ Connection(boost::shared_ptr<LibFlowCanvas::FlowCanvas> canvas,
+ boost::shared_ptr<ConnectionModel> model,
+ boost::shared_ptr<LibFlowCanvas::Port> src,
+ boost::shared_ptr<LibFlowCanvas::Port> dst)
+ : LibFlowCanvas::Connection(canvas, src, dst)
+ , m_connection_model(model)
+ {}
+
+ virtual ~Connection() {}
+
+ CountedPtr<ConnectionModel> model() const { return m_connection_model; }
+
+private:
+ CountedPtr<ConnectionModel> m_connection_model;
+};
+
+
+} // namespace Ingenuity
+
+#endif // CONNECTION_H
diff --git a/src/progs/ingenuity/Loader.cpp b/src/progs/ingenuity/Loader.cpp
index c07d99bf..b22669ec 100644
--- a/src/progs/ingenuity/Loader.cpp
+++ b/src/progs/ingenuity/Loader.cpp
@@ -97,7 +97,7 @@ Loader::save_patch_event(CountedPtr<PatchModel> model, const string& filename, b
cerr << "FIXME: Recursive save." << endl;
_serializer->start_to_filename(filename);
- _serializer->serialize_patch(model);
+ _serializer->serialize(model);
_serializer->finish();
}
diff --git a/src/progs/ingenuity/Makefile.am b/src/progs/ingenuity/Makefile.am
index 3044a2fc..753980b8 100644
--- a/src/progs/ingenuity/Makefile.am
+++ b/src/progs/ingenuity/Makefile.am
@@ -70,6 +70,7 @@ ingenuity_SOURCES = \
SubpatchModule.cpp \
Port.h \
Port.cpp \
+ Connection.h \
NewSubpatchWindow.h \
NewSubpatchWindow.cpp \
ConfigWindow.h \
diff --git a/src/progs/ingenuity/NodeModule.cpp b/src/progs/ingenuity/NodeModule.cpp
index 6d4e54de..d9d91193 100644
--- a/src/progs/ingenuity/NodeModule.cpp
+++ b/src/progs/ingenuity/NodeModule.cpp
@@ -85,8 +85,6 @@ NodeModule::show_control_window()
void
NodeModule::store_location()
{
- cerr << "FIXME: store_location\n";
-#if 0
const float x = static_cast<float>(property_x());
const float y = static_cast<float>(property_y());
@@ -98,7 +96,6 @@ NodeModule::store_location()
App::instance().engine()->set_metadata(m_node->path(), "ingenuity:canvas-x", Atom(x));
App::instance().engine()->set_metadata(m_node->path(), "ingenuity:canvas-y", Atom(y));
}
-#endif
}
diff --git a/src/progs/ingenuity/PatchCanvas.cpp b/src/progs/ingenuity/PatchCanvas.cpp
index 6d8403eb..3f9c97fa 100644
--- a/src/progs/ingenuity/PatchCanvas.cpp
+++ b/src/progs/ingenuity/PatchCanvas.cpp
@@ -26,11 +26,14 @@
#include "LoadSubpatchWindow.h"
#include "NewSubpatchWindow.h"
#include "Port.h"
+#include "Connection.h"
#include "NodeModel.h"
#include "NodeModule.h"
#include "SubpatchModule.h"
#include "GladeFactory.h"
#include "WindowFactory.h"
+#include "Serializer.h"
+using Ingen::Client::Serializer;
namespace Ingenuity {
@@ -170,10 +173,14 @@ PatchCanvas::connection(CountedPtr<ConnectionModel> cm)
boost::shared_ptr<LibFlowCanvas::Port> src = get_port(src_parent_name, cm->src_port_path().name());
boost::shared_ptr<LibFlowCanvas::Port> dst = get_port(dst_parent_name, cm->dst_port_path().name());
- if (src && dst)
- add_connection(src, dst);
- else
+ if (src && dst) {
+ boost::shared_ptr<Connection> c(new Connection(shared_from_this(), cm, src, dst));
+ src->add_connection(c);
+ dst->add_connection(c);
+ add_connection(c);
+ } else {
cerr << "[Canvas] ERROR: Unable to find ports to create connection." << endl;
+ }
}
@@ -293,7 +300,7 @@ PatchCanvas::canvas_event(GdkEvent* event)
void
-PatchCanvas::destroy_selected()
+PatchCanvas::destroy_selection()
{
for (list<boost::shared_ptr<Module> >::iterator m = m_selected_modules.begin(); m != m_selected_modules.end(); ++m) {
boost::shared_ptr<NodeModule> module = boost::dynamic_pointer_cast<NodeModule>(*m);
@@ -303,6 +310,32 @@ PatchCanvas::destroy_selected()
}
+void
+PatchCanvas::copy_selection()
+{
+ Serializer serializer(App::instance().engine());
+ serializer.start_to_string();
+
+ for (list<boost::shared_ptr<Module> >::iterator m = m_selected_modules.begin(); m != m_selected_modules.end(); ++m) {
+ boost::shared_ptr<NodeModule> module = boost::dynamic_pointer_cast<NodeModule>(*m);
+ if (module)
+ serializer.serialize(module->node());
+ }
+
+ for (list<boost::shared_ptr<LibFlowCanvas::Connection> >::iterator c = m_selected_connections.begin();
+ c != m_selected_connections.end(); ++c) {
+ boost::shared_ptr<Connection> connection = boost::dynamic_pointer_cast<Connection>(*c);
+ if (connection)
+ serializer.serialize_connection(connection->model());
+ }
+
+ string result = serializer.finish();
+
+ Glib::RefPtr<Gtk::Clipboard> clipboard = Gtk::Clipboard::get();
+ clipboard->set_text(result);
+}
+
+
string
PatchCanvas::generate_port_name(const string& base) {
string name = base;
diff --git a/src/progs/ingenuity/PatchCanvas.h b/src/progs/ingenuity/PatchCanvas.h
index 15312367..7074c785 100644
--- a/src/progs/ingenuity/PatchCanvas.h
+++ b/src/progs/ingenuity/PatchCanvas.h
@@ -69,7 +69,8 @@ public:
void get_new_module_location(double& x, double& y);
- void destroy_selected();
+ void destroy_selection();
+ void copy_selection();
void show_menu(GdkEvent* event)
{ m_menu->popup(event->button.button, event->button.time); }
diff --git a/src/progs/ingenuity/PatchWindow.cpp b/src/progs/ingenuity/PatchWindow.cpp
index e429d136..2ca3da14 100644
--- a/src/progs/ingenuity/PatchWindow.cpp
+++ b/src/progs/ingenuity/PatchWindow.cpp
@@ -59,6 +59,10 @@ PatchWindow::PatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glad
//xml->get_widget("patch_open_into_menuitem", m_menu_open_into);
xml->get_widget("patch_save_menuitem", m_menu_save);
xml->get_widget("patch_save_as_menuitem", m_menu_save_as);
+ xml->get_widget("patch_cut_menuitem", m_menu_cut);
+ xml->get_widget("patch_copy_menuitem", m_menu_copy);
+ xml->get_widget("patch_paste_menuitem", m_menu_paste);
+ xml->get_widget("patch_delete_menuitem", m_menu_delete);
xml->get_widget("patch_close_menuitem", m_menu_close);
xml->get_widget("patch_configuration_menuitem", m_menu_configuration);
xml->get_widget("patch_quit_menuitem", m_menu_quit);
@@ -84,6 +88,10 @@ PatchWindow::PatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glad
sigc::mem_fun(this, &PatchWindow::event_save));
m_menu_save_as->signal_activate().connect(
sigc::mem_fun(this, &PatchWindow::event_save_as));
+ m_menu_copy->signal_activate().connect(
+ sigc::mem_fun(this, &PatchWindow::event_copy));
+ m_menu_delete->signal_activate().connect(
+ sigc::mem_fun(this, &PatchWindow::event_delete));
m_menu_quit->signal_activate().connect(
sigc::mem_fun(this, &PatchWindow::event_quit));
m_menu_configuration->signal_activate().connect(
@@ -307,6 +315,22 @@ PatchWindow::event_save_as()
void
+PatchWindow::event_copy()
+{
+ if (m_view)
+ m_view->canvas()->copy_selection();
+}
+
+
+void
+PatchWindow::event_delete()
+{
+ if (m_view)
+ m_view->canvas()->destroy_selection();
+}
+
+
+void
PatchWindow::on_show()
{
if (m_position_stored)
diff --git a/src/progs/ingenuity/PatchWindow.h b/src/progs/ingenuity/PatchWindow.h
index b957c420..3f9331ec 100644
--- a/src/progs/ingenuity/PatchWindow.h
+++ b/src/progs/ingenuity/PatchWindow.h
@@ -81,6 +81,8 @@ private:
void event_import();
void event_save();
void event_save_as();
+ void event_copy();
+ void event_delete();
void event_quit();
void event_destroy();
void event_clear();
@@ -100,6 +102,10 @@ private:
Gtk::MenuItem* m_menu_import;
Gtk::MenuItem* m_menu_save;
Gtk::MenuItem* m_menu_save_as;
+ Gtk::MenuItem* m_menu_cut;
+ Gtk::MenuItem* m_menu_copy;
+ Gtk::MenuItem* m_menu_paste;
+ Gtk::MenuItem* m_menu_delete;
Gtk::MenuItem* m_menu_configuration;
Gtk::MenuItem* m_menu_close;
Gtk::MenuItem* m_menu_quit;
diff --git a/src/progs/ingenuity/ingenuity.glade b/src/progs/ingenuity/ingenuity.glade
index 7f18f954..7d24d2e8 100644
--- a/src/progs/ingenuity/ingenuity.glade
+++ b/src/progs/ingenuity/ingenuity.glade
@@ -51,7 +51,7 @@
<signal name="activate" handler="on_patch_import_menuitem_activate" last_modification_time="Mon, 06 Feb 2006 06:20:27 GMT"/>
<child internal-child="image">
- <widget class="GtkImage" id="image1925">
+ <widget class="GtkImage" id="image1970">
<property name="visible">True</property>
<property name="stock">gtk-open</property>
<property name="icon_size">1</property>
@@ -106,7 +106,7 @@
<accelerator key="G" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
- <widget class="GtkImage" id="image1926">
+ <widget class="GtkImage" id="image1971">
<property name="visible">True</property>
<property name="stock">gtk-preferences</property>
<property name="icon_size">1</property>
@@ -156,6 +156,57 @@
</child>
<child>
+ <widget class="GtkMenuItem" id="edit2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Edit</property>
+ <property name="use_underline">True</property>
+
+ <child>
+ <widget class="GtkMenu" id="edit2_menu">
+
+ <child>
+ <widget class="GtkImageMenuItem" id="patch_cut_menuitem">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="label">gtk-cut</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="on_patch_cut_menuitem_activate" last_modification_time="Tue, 03 Oct 2006 23:55:43 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="patch_copy_menuitem">
+ <property name="visible">True</property>
+ <property name="label">gtk-copy</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="on_patch_copy_menuitem_activate" last_modification_time="Tue, 03 Oct 2006 23:55:43 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="patch_paste_menuitem">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="label">gtk-paste</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="on_patch_paste_menuitem_activate" last_modification_time="Tue, 03 Oct 2006 23:55:43 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="patch_delete_menuitem">
+ <property name="visible">True</property>
+ <property name="label">gtk-delete</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="on_patch_delete_menuitem_activate" last_modification_time="Tue, 03 Oct 2006 23:55:43 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
<widget class="GtkMenuItem" id="patch_patch_menu">
<property name="visible">True</property>
<property name="label" translatable="yes">_Patch</property>
@@ -189,7 +240,7 @@
<accelerator key="C" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
- <widget class="GtkImage" id="image1927">
+ <widget class="GtkImage" id="image1972">
<property name="visible">True</property>
<property name="stock">gtk-preferences</property>
<property name="icon_size">1</property>
@@ -231,7 +282,7 @@
<signal name="activate" handler="on_patch_destroy_menuitem_activate" last_modification_time="Wed, 25 May 2005 00:22:00 GMT"/>
<child internal-child="image">
- <widget class="GtkImage" id="image1928">
+ <widget class="GtkImage" id="image1973">
<property name="visible">True</property>
<property name="stock">gtk-delete</property>
<property name="icon_size">1</property>
@@ -268,7 +319,7 @@
<accelerator key="E" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
- <widget class="GtkImage" id="image1929">
+ <widget class="GtkImage" id="image1974">
<property name="visible">True</property>
<property name="stock">gtk-connect</property>
<property name="icon_size">1</property>
@@ -291,7 +342,7 @@
<accelerator key="T" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
- <widget class="GtkImage" id="image1930">
+ <widget class="GtkImage" id="image1975">
<property name="visible">True</property>
<property name="stock">gtk-index</property>
<property name="icon_size">1</property>
@@ -314,7 +365,7 @@
<accelerator key="M" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
- <widget class="GtkImage" id="image1931">
+ <widget class="GtkImage" id="image1976">
<property name="visible">True</property>
<property name="stock">gtk-dialog-error</property>
<property name="icon_size">1</property>
@@ -349,7 +400,7 @@
<signal name="activate" handler="on_right-click_the_canvas_to_add_objects1_activate" last_modification_time="Fri, 16 Jun 2006 17:51:05 GMT"/>
<child internal-child="image">
- <widget class="GtkImage" id="image1932">
+ <widget class="GtkImage" id="image1977">
<property name="visible">True</property>
<property name="stock">gtk-info</property>
<property name="icon_size">1</property>