1 #define __SP_XMLVIEW_CONTENT_C__
3 /*
4 * Specialization of GtkTextView for the XML tree view
5 *
6 * Authors:
7 * MenTaLguY <mental@rydia.net>
8 *
9 * Copyright (C) 2002 MenTaLguY
10 *
11 * Released under the GNU GPL; see COPYING for details
12 */
15 #include "xml/node-event-vector.h"
16 #include "sp-xmlview-content.h"
17 #include "desktop-handles.h"
18 #include "document-private.h"
19 #include "inkscape.h"
21 static void sp_xmlview_content_class_init (SPXMLViewContentClass * klass);
22 static void sp_xmlview_content_init (SPXMLViewContent * text);
23 static void sp_xmlview_content_destroy (GtkObject * object);
25 void sp_xmlview_content_changed (GtkTextBuffer *tb, SPXMLViewContent *text);
27 static void event_content_changed (Inkscape::XML::Node * repr, const gchar * old_content, const gchar * new_content, gpointer data);
29 static GtkTextViewClass * parent_class = NULL;
31 static Inkscape::XML::NodeEventVector repr_events = {
32 NULL, /* child_added */
33 NULL, /* child_removed */
34 NULL, /* attr_changed */
35 event_content_changed,
36 NULL /* order_changed */
37 };
39 GtkWidget *
40 sp_xmlview_content_new (Inkscape::XML::Node * repr)
41 {
42 GtkTextBuffer *tb;
43 SPXMLViewContent *text;
45 tb = gtk_text_buffer_new (NULL);
46 text = (SPXMLViewContent*)gtk_type_new (SP_TYPE_XMLVIEW_CONTENT);
47 gtk_text_view_set_buffer (GTK_TEXT_VIEW (text), tb);
48 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text), GTK_WRAP_CHAR);
50 g_signal_connect (G_OBJECT (tb), "changed", G_CALLBACK (sp_xmlview_content_changed), text);
52 /* should we alter the scrolling adjustments here? */
54 sp_xmlview_content_set_repr (text, repr);
56 return (GtkWidget *) text;
57 }
59 void
60 sp_xmlview_content_set_repr (SPXMLViewContent * text, Inkscape::XML::Node * repr)
61 {
62 if ( repr == text->repr ) return;
63 if (text->repr) {
64 sp_repr_remove_listener_by_data (text->repr, text);
65 Inkscape::GC::release(text->repr);
66 }
67 text->repr = repr;
68 if (repr) {
69 Inkscape::GC::anchor(repr);
70 sp_repr_add_listener (repr, &repr_events, text);
71 sp_repr_synthesize_events (repr, &repr_events, text);
72 } else {
73 gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (text)), "", 0);
74 gtk_text_view_set_editable (GTK_TEXT_VIEW (text), FALSE);
75 }
76 }
78 GtkType
79 sp_xmlview_content_get_type (void)
80 {
81 static GtkType type = 0;
83 if (!type) {
84 static const GtkTypeInfo info = {
85 "SPXMLViewContent",
86 sizeof (SPXMLViewContent),
87 sizeof (SPXMLViewContentClass),
88 (GtkClassInitFunc) sp_xmlview_content_class_init,
89 (GtkObjectInitFunc) sp_xmlview_content_init,
90 NULL, NULL, NULL
91 };
92 type = gtk_type_unique (GTK_TYPE_TEXT_VIEW, &info);
93 }
95 return type;
96 }
98 void
99 sp_xmlview_content_class_init (SPXMLViewContentClass * klass)
100 {
101 GtkObjectClass * object_class;
103 object_class = (GtkObjectClass *) klass;
105 parent_class = (GtkTextViewClass*)gtk_type_class (GTK_TYPE_TEXT_VIEW);
107 object_class->destroy = sp_xmlview_content_destroy;
108 }
110 void
111 sp_xmlview_content_init (SPXMLViewContent *text)
112 {
113 text->repr = NULL;
114 text->blocked = FALSE;
115 }
117 void
118 sp_xmlview_content_destroy (GtkObject * object)
119 {
120 SPXMLViewContent * text;
122 text = SP_XMLVIEW_CONTENT (object);
124 sp_xmlview_content_set_repr (text, NULL);
126 GTK_OBJECT_CLASS (parent_class)->destroy (object);
127 }
129 void
130 event_content_changed (Inkscape::XML::Node * repr, const gchar * old_content, const gchar * new_content, gpointer data)
131 {
132 SPXMLViewContent * text;
133 text = SP_XMLVIEW_CONTENT (data);
135 if (text->blocked) return;
137 text->blocked = TRUE;
139 if (new_content) {
140 gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (text)), new_content, strlen (new_content));
141 } else {
142 gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (text)), "", 0);
143 }
144 gtk_text_view_set_editable (GTK_TEXT_VIEW (text), new_content != NULL);
146 text->blocked = FALSE;
147 }
149 void
150 sp_xmlview_content_changed (GtkTextBuffer *tb, SPXMLViewContent *text)
151 {
152 if (text->blocked) return;
154 if (text->repr) {
155 GtkTextIter start, end;
156 gchar *data;
157 text->blocked = TRUE;
158 gtk_text_buffer_get_bounds (tb, &start, &end);
159 data = gtk_text_buffer_get_text (tb, &start, &end, TRUE);
160 text->repr->setContent(data);
161 g_free (data);
162 text->blocked = FALSE;
163 sp_document_done (SP_DT_DOCUMENT (SP_ACTIVE_DESKTOP));
164 }
165 }