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 */
14 #include <cstring>
15 #include <glibmm/i18n.h>
17 #include "xml/node-event-vector.h"
18 #include "sp-xmlview-content.h"
19 #include "desktop-handles.h"
20 #include "document-private.h"
21 #include "inkscape.h"
23 static void sp_xmlview_content_class_init (SPXMLViewContentClass * klass);
24 static void sp_xmlview_content_init (SPXMLViewContent * text);
25 static void sp_xmlview_content_destroy (GtkObject * object);
27 void sp_xmlview_content_changed (GtkTextBuffer *tb, SPXMLViewContent *text);
29 static void event_content_changed (Inkscape::XML::Node * repr, const gchar * old_content, const gchar * new_content, gpointer data);
31 static GtkTextViewClass * parent_class = NULL;
33 static Inkscape::XML::NodeEventVector repr_events = {
34 NULL, /* child_added */
35 NULL, /* child_removed */
36 NULL, /* attr_changed */
37 event_content_changed,
38 NULL /* order_changed */
39 };
41 GtkWidget *
42 sp_xmlview_content_new (Inkscape::XML::Node * repr)
43 {
44 GtkTextBuffer *tb;
45 SPXMLViewContent *text;
47 tb = gtk_text_buffer_new (NULL);
48 text = (SPXMLViewContent*)gtk_type_new (SP_TYPE_XMLVIEW_CONTENT);
49 gtk_text_view_set_buffer (GTK_TEXT_VIEW (text), tb);
50 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text), GTK_WRAP_CHAR);
52 g_signal_connect (G_OBJECT (tb), "changed", G_CALLBACK (sp_xmlview_content_changed), text);
54 /* should we alter the scrolling adjustments here? */
56 sp_xmlview_content_set_repr (text, repr);
58 return (GtkWidget *) text;
59 }
61 void
62 sp_xmlview_content_set_repr (SPXMLViewContent * text, Inkscape::XML::Node * repr)
63 {
64 if ( repr == text->repr ) return;
65 if (text->repr) {
66 sp_repr_remove_listener_by_data (text->repr, text);
67 Inkscape::GC::release(text->repr);
68 }
69 text->repr = repr;
70 if (repr) {
71 Inkscape::GC::anchor(repr);
72 sp_repr_add_listener (repr, &repr_events, text);
73 sp_repr_synthesize_events (repr, &repr_events, text);
74 } else {
75 gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (text)), "", 0);
76 gtk_text_view_set_editable (GTK_TEXT_VIEW (text), FALSE);
77 }
78 }
80 GType sp_xmlview_content_get_type(void)
81 {
82 static GtkType type = 0;
84 if (!type) {
85 GTypeInfo info = {
86 sizeof(SPXMLViewContentClass),
87 0, // base_init
88 0, // base_finalize
89 (GClassInitFunc)sp_xmlview_content_class_init,
90 0, // class_finalize
91 0, // class_data
92 sizeof(SPXMLViewContent),
93 0, // n_preallocs
94 (GInstanceInitFunc)sp_xmlview_content_init,
95 0 // value_table
96 };
97 type = g_type_register_static(GTK_TYPE_TEXT_VIEW, "SPXMLViewContent", &info, static_cast<GTypeFlags>(0));
98 }
100 return type;
101 }
103 void
104 sp_xmlview_content_class_init (SPXMLViewContentClass * klass)
105 {
106 GtkObjectClass * object_class;
108 object_class = (GtkObjectClass *) klass;
110 parent_class = (GtkTextViewClass*)gtk_type_class (GTK_TYPE_TEXT_VIEW);
112 object_class->destroy = sp_xmlview_content_destroy;
113 }
115 void
116 sp_xmlview_content_init (SPXMLViewContent *text)
117 {
118 text->repr = NULL;
119 text->blocked = FALSE;
120 }
122 void
123 sp_xmlview_content_destroy (GtkObject * object)
124 {
125 SPXMLViewContent * text;
127 text = SP_XMLVIEW_CONTENT (object);
129 sp_xmlview_content_set_repr (text, NULL);
131 GTK_OBJECT_CLASS (parent_class)->destroy (object);
132 }
134 void
135 event_content_changed (Inkscape::XML::Node * /*repr*/, const gchar * /*old_content*/, const gchar * new_content, gpointer data)
136 {
137 SPXMLViewContent * text;
138 text = SP_XMLVIEW_CONTENT (data);
140 if (text->blocked) return;
142 text->blocked = TRUE;
144 if (new_content) {
145 gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (text)), new_content, strlen (new_content));
146 } else {
147 gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (text)), "", 0);
148 }
149 gtk_text_view_set_editable (GTK_TEXT_VIEW (text), new_content != NULL);
151 text->blocked = FALSE;
152 }
154 void
155 sp_xmlview_content_changed (GtkTextBuffer *tb, SPXMLViewContent *text)
156 {
157 if (text->blocked) return;
159 if (text->repr) {
160 GtkTextIter start, end;
161 gchar *data;
162 text->blocked = TRUE;
163 gtk_text_buffer_get_bounds (tb, &start, &end);
164 data = gtk_text_buffer_get_text (tb, &start, &end, TRUE);
165 text->repr->setContent(data);
166 g_free (data);
167 text->blocked = FALSE;
168 sp_document_done (sp_desktop_document (SP_ACTIVE_DESKTOP), SP_VERB_DIALOG_XML_EDITOR,
169 _("Type text in a text node"));
170 }
171 }