/* * Specialization of GtkTextView for the XML tree view * * Authors: * MenTaLguY * * Copyright (C) 2002 MenTaLguY * Abhishek Sharma * * Released under the GNU GPL; see COPYING for details */ #include #include #include "xml/node-event-vector.h" #include "sp-xmlview-content.h" #include "desktop-handles.h" #include "document-private.h" #include "document-undo.h" #include "inkscape.h" #include "verbs.h" using Inkscape::DocumentUndo; static void sp_xmlview_content_class_init (SPXMLViewContentClass * klass); static void sp_xmlview_content_init (SPXMLViewContent * text); #if GTK_CHECK_VERSION(3,0,0) static void sp_xmlview_content_destroy(GtkWidget * object); #else static void sp_xmlview_content_destroy(GtkObject * object); #endif void sp_xmlview_content_changed (GtkTextBuffer *tb, SPXMLViewContent *text); static void event_content_changed (Inkscape::XML::Node * repr, const gchar * old_content, const gchar * new_content, gpointer data); static GtkTextViewClass * parent_class = NULL; static Inkscape::XML::NodeEventVector repr_events = { NULL, /* child_added */ NULL, /* child_removed */ NULL, /* attr_changed */ event_content_changed, NULL /* order_changed */ }; GtkWidget *sp_xmlview_content_new(Inkscape::XML::Node * repr) { GtkTextBuffer *tb = gtk_text_buffer_new(NULL); SPXMLViewContent *text = SP_XMLVIEW_CONTENT(g_object_new(SP_TYPE_XMLVIEW_CONTENT, NULL)); gtk_text_view_set_buffer (GTK_TEXT_VIEW (text), tb); gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text), GTK_WRAP_CHAR); g_signal_connect (G_OBJECT (tb), "changed", G_CALLBACK (sp_xmlview_content_changed), text); /* should we alter the scrolling adjustments here? */ sp_xmlview_content_set_repr (text, repr); return GTK_WIDGET(text); } void sp_xmlview_content_set_repr (SPXMLViewContent * text, Inkscape::XML::Node * repr) { if ( repr == text->repr ) return; if (text->repr) { sp_repr_remove_listener_by_data (text->repr, text); Inkscape::GC::release(text->repr); } text->repr = repr; if (repr) { Inkscape::GC::anchor(repr); sp_repr_add_listener (repr, &repr_events, text); sp_repr_synthesize_events (repr, &repr_events, text); } else { gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (text)), "", 0); gtk_text_view_set_editable (GTK_TEXT_VIEW (text), FALSE); } } GType sp_xmlview_content_get_type(void) { static GType type = 0; if (!type) { GTypeInfo info = { sizeof(SPXMLViewContentClass), 0, // base_init 0, // base_finalize (GClassInitFunc)sp_xmlview_content_class_init, 0, // class_finalize 0, // class_data sizeof(SPXMLViewContent), 0, // n_preallocs (GInstanceInitFunc)sp_xmlview_content_init, 0 // value_table }; type = g_type_register_static(GTK_TYPE_TEXT_VIEW, "SPXMLViewContent", &info, static_cast(0)); } return type; } void sp_xmlview_content_class_init(SPXMLViewContentClass * klass) { #if GTK_CHECK_VERSION(3,0,0) GtkWidgetClass * widget_class = GTK_WIDGET_CLASS(klass); widget_class->destroy = sp_xmlview_content_destroy; #else GtkObjectClass * object_class = GTK_OBJECT_CLASS(klass); object_class->destroy = sp_xmlview_content_destroy; #endif parent_class = GTK_TEXT_VIEW_CLASS(g_type_class_peek_parent (klass)); } void sp_xmlview_content_init (SPXMLViewContent *text) { text->repr = NULL; text->blocked = FALSE; } #if GTK_CHECK_VERSION(3,0,0) void sp_xmlview_content_destroy(GtkWidget * object) #else void sp_xmlview_content_destroy(GtkObject * object) #endif { SPXMLViewContent * text = SP_XMLVIEW_CONTENT (object); sp_xmlview_content_set_repr (text, NULL); #if GTK_CHECK_VERSION(3,0,0) GTK_WIDGET_CLASS (parent_class)->destroy (object); #else GTK_OBJECT_CLASS (parent_class)->destroy (object); #endif } void event_content_changed (Inkscape::XML::Node * /*repr*/, const gchar * /*old_content*/, const gchar * new_content, gpointer data) { SPXMLViewContent * text; text = SP_XMLVIEW_CONTENT (data); if (text->blocked) return; text->blocked = TRUE; if (new_content) { gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (text)), new_content, strlen (new_content)); } else { gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (text)), "", 0); } gtk_text_view_set_editable (GTK_TEXT_VIEW (text), new_content != NULL); text->blocked = FALSE; } void sp_xmlview_content_changed (GtkTextBuffer *tb, SPXMLViewContent *text) { if (text->blocked) return; if (text->repr) { GtkTextIter start, end; gchar *data; text->blocked = TRUE; gtk_text_buffer_get_bounds (tb, &start, &end); data = gtk_text_buffer_get_text (tb, &start, &end, TRUE); text->repr->setContent(data); g_free (data); text->blocked = FALSE; DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_DIALOG_XML_EDITOR, _("Type text in a text node")); } }