From 1e01da451b279943ed51999ee06d64aba7c8faa2 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 4 Oct 2006 04:47:30 +0000 Subject: Bug fixes. Added copy to ingen (no cut or paste yet). Serialization work. git-svn-id: http://svn.drobilla.net/lad/ingen@153 a436a847-0d15-0410-975c-d299462d15a1 --- src/common/util/RedlandAtom.h | 21 +++-- src/libs/client/Serializer.cpp | 149 ++++++++++++++++++++++++++---------- src/libs/client/Serializer.h | 38 ++++----- src/libs/client/Store.cpp | 6 +- src/progs/ingenuity/Connection.h | 56 ++++++++++++++ src/progs/ingenuity/Loader.cpp | 2 +- src/progs/ingenuity/Makefile.am | 1 + src/progs/ingenuity/NodeModule.cpp | 3 - src/progs/ingenuity/PatchCanvas.cpp | 41 +++++++++- src/progs/ingenuity/PatchCanvas.h | 3 +- src/progs/ingenuity/PatchWindow.cpp | 24 ++++++ src/progs/ingenuity/PatchWindow.h | 6 ++ src/progs/ingenuity/ingenuity.glade | 67 ++++++++++++++-- 13 files changed, 326 insertions(+), 91 deletions(-) create mode 100644 src/progs/ingenuity/Connection.h (limited to 'src') 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 #include #include #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 patch) throw (std::logic_error) +Serializer::serialize(CountedPtr object) throw (std::logic_error) { if (!_serializer) throw std::logic_error("serialize_patch called without serialization in progress"); + CountedPtr patch = PtrCast(object); + if (patch) { + serialize_patch(patch); + return; + } + + CountedPtr node = PtrCast(object); + if (node) { + serialize_node(node); + return; + } + + CountedPtr port = PtrCast(object); + if (port) { + serialize_port(port); + return; + } + + cerr << "[Serializer] WARNING: Unsupported object type, " + << object->path() << " not serialized." << endl; +} + + +void +Serializer::serialize_patch(CountedPtr 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 patch) throw (std::logic_erro void -Serializer::add_node_to_rdf(raptor_serializer* rdf, +Serializer::serialize_node( CountedPtr 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 port, const string ns_prefix) +Serializer::serialize_port(CountedPtr 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 connection, const string ns_prefix) +Serializer::serialize_connection(CountedPtr 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 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 object) throw (std::logic_error); + void serialize_connection(CountedPtr c) throw (std::logic_error); + string finish() throw (std::logic_error); private: // Model -> RDF - void add_node_to_rdf(raptor_serializer* rdf, - CountedPtr node, const string ns_prefix=""); + void serialize_patch(CountedPtr p); + + void serialize_node(CountedPtr n, const string ns_prefix=""); - void add_port_to_rdf(raptor_serializer* rdf, - CountedPtr port, const string ns_prefix=""); + void serialize_port(CountedPtr p, const string ns_prefix=""); - void add_connection_to_rdf(raptor_serializer* rdf, - CountedPtr 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 +#include +#include +#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 canvas, + boost::shared_ptr model, + boost::shared_ptr src, + boost::shared_ptr dst) + : LibFlowCanvas::Connection(canvas, src, dst) + , m_connection_model(model) + {} + + virtual ~Connection() {} + + CountedPtr model() const { return m_connection_model; } + +private: + CountedPtr 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 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(property_x()); const float y = static_cast(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 cm) boost::shared_ptr src = get_port(src_parent_name, cm->src_port_path().name()); boost::shared_ptr 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 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 >::iterator m = m_selected_modules.begin(); m != m_selected_modules.end(); ++m) { boost::shared_ptr module = boost::dynamic_pointer_cast(*m); @@ -303,6 +310,32 @@ PatchCanvas::destroy_selected() } +void +PatchCanvas::copy_selection() +{ + Serializer serializer(App::instance().engine()); + serializer.start_to_string(); + + for (list >::iterator m = m_selected_modules.begin(); m != m_selected_modules.end(); ++m) { + boost::shared_ptr module = boost::dynamic_pointer_cast(*m); + if (module) + serializer.serialize(module->node()); + } + + for (list >::iterator c = m_selected_connections.begin(); + c != m_selected_connections.end(); ++c) { + boost::shared_ptr connection = boost::dynamic_pointer_cast(*c); + if (connection) + serializer.serialize_connection(connection->model()); + } + + string result = serializer.finish(); + + Glib::RefPtr 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::RefPtrget_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::RefPtrsignal_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( @@ -306,6 +314,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() { 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 @@ - + True gtk-open 1 @@ -106,7 +106,7 @@ - + True gtk-preferences 1 @@ -155,6 +155,57 @@ + + + True + _Edit + True + + + + + + + True + False + gtk-cut + True + + + + + + + True + gtk-copy + True + + + + + + + True + False + gtk-paste + True + + + + + + + True + gtk-delete + True + + + + + + + + True @@ -189,7 +240,7 @@ - + True gtk-preferences 1 @@ -231,7 +282,7 @@ - + True gtk-delete 1 @@ -268,7 +319,7 @@ - + True gtk-connect 1 @@ -291,7 +342,7 @@ - + True gtk-index 1 @@ -314,7 +365,7 @@ - + True gtk-dialog-error 1 @@ -349,7 +400,7 @@ - + True gtk-info 1 -- cgit v1.2.1