1 /*
2 * Specialization of GtkTextView for the XML tree view
3 *
4 * Authors:
5 * MenTaLguY <mental@rydia.net>
6 *
7 * Copyright (C) 2002 MenTaLguY
8 * Abhishek Sharma
9 *
10 * Released under the GNU GPL; see COPYING for details
11 */
13 #include <cstring>
14 #include <glibmm/i18n.h>
16 #include "xml/node-event-vector.h"
17 #include "sp-xmlview-content.h"
18 #include "desktop-handles.h"
19 #include "document-private.h"
20 #include "inkscape.h"
22 using Inkscape::DocumentUndo;
24 static void sp_xmlview_content_class_init (SPXMLViewContentClass * klass);
25 static void sp_xmlview_content_init (SPXMLViewContent * text);
26 static void sp_xmlview_content_destroy (GtkObject * object);
28 void sp_xmlview_content_changed (GtkTextBuffer *tb, SPXMLViewContent *text);
30 static void event_content_changed (Inkscape::XML::Node * repr, const gchar * old_content, const gchar * new_content, gpointer data);
32 static GtkTextViewClass * parent_class = NULL;
34 static Inkscape::XML::NodeEventVector repr_events = {
35 NULL, /* child_added */
36 NULL, /* child_removed */
37 NULL, /* attr_changed */
38 event_content_changed,
39 NULL /* order_changed */
40 };
42 GtkWidget *
43 sp_xmlview_content_new (Inkscape::XML::Node * repr)
44 {
45 GtkTextBuffer *tb;
46 SPXMLViewContent *text;
48 tb = gtk_text_buffer_new (NULL);
49 text = (SPXMLViewContent*)gtk_type_new (SP_TYPE_XMLVIEW_CONTENT);
50 gtk_text_view_set_buffer (GTK_TEXT_VIEW (text), tb);
51 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text), GTK_WRAP_CHAR);
53 g_signal_connect (G_OBJECT (tb), "changed", G_CALLBACK (sp_xmlview_content_changed), text);
55 /* should we alter the scrolling adjustments here? */
57 sp_xmlview_content_set_repr (text, repr);
59 return (GtkWidget *) text;
60 }
62 void
63 sp_xmlview_content_set_repr (SPXMLViewContent * text, Inkscape::XML::Node * repr)
64 {
65 if ( repr == text->repr ) return;
66 if (text->repr) {
67 sp_repr_remove_listener_by_data (text->repr, text);
68 Inkscape::GC::release(text->repr);
69 }
70 text->repr = repr;
71 if (repr) {
72 Inkscape::GC::anchor(repr);
73 sp_repr_add_listener (repr, &repr_events, text);
74 sp_repr_synthesize_events (repr, &repr_events, text);
75 } else {
76 gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (text)), "", 0);
77 gtk_text_view_set_editable (GTK_TEXT_VIEW (text), FALSE);
78 }
79 }
81 GType sp_xmlview_content_get_type(void)
82 {
83 static GtkType type = 0;
85 if (!type) {
86 GTypeInfo info = {
87 sizeof(SPXMLViewContentClass),
88 0, // base_init
89 0, // base_finalize
90 (GClassInitFunc)sp_xmlview_content_class_init,
91 0, // class_finalize
92 0, // class_data
93 sizeof(SPXMLViewContent),
94 0, // n_preallocs
95 (GInstanceInitFunc)sp_xmlview_content_init,
96 0 // value_table
97 };
98 type = g_type_register_static(GTK_TYPE_TEXT_VIEW, "SPXMLViewContent", &info, static_cast<GTypeFlags>(0));
99 }
101 return type;
102 }
104 void
105 sp_xmlview_content_class_init (SPXMLViewContentClass * klass)
106 {
107 GtkObjectClass * object_class;
109 object_class = (GtkObjectClass *) klass;
111 parent_class = (GtkTextViewClass*)gtk_type_class (GTK_TYPE_TEXT_VIEW);
113 object_class->destroy = sp_xmlview_content_destroy;
114 }
116 void
117 sp_xmlview_content_init (SPXMLViewContent *text)
118 {
119 text->repr = NULL;
120 text->blocked = FALSE;
121 }
123 void
124 sp_xmlview_content_destroy (GtkObject * object)
125 {
126 SPXMLViewContent * text;
128 text = SP_XMLVIEW_CONTENT (object);
130 sp_xmlview_content_set_repr (text, NULL);
132 GTK_OBJECT_CLASS (parent_class)->destroy (object);
133 }
135 void
136 event_content_changed (Inkscape::XML::Node * /*repr*/, const gchar * /*old_content*/, const gchar * new_content, gpointer data)
137 {
138 SPXMLViewContent * text;
139 text = SP_XMLVIEW_CONTENT (data);
141 if (text->blocked) return;
143 text->blocked = TRUE;
145 if (new_content) {
146 gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (text)), new_content, strlen (new_content));
147 } else {
148 gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (text)), "", 0);
149 }
150 gtk_text_view_set_editable (GTK_TEXT_VIEW (text), new_content != NULL);
152 text->blocked = FALSE;
153 }
155 void
156 sp_xmlview_content_changed (GtkTextBuffer *tb, SPXMLViewContent *text)
157 {
158 if (text->blocked) return;
160 if (text->repr) {
161 GtkTextIter start, end;
162 gchar *data;
163 text->blocked = TRUE;
164 gtk_text_buffer_get_bounds (tb, &start, &end);
165 data = gtk_text_buffer_get_text (tb, &start, &end, TRUE);
166 text->repr->setContent(data);
167 g_free (data);
168 text->blocked = FALSE;
169 DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_DIALOG_XML_EDITOR,
170 _("Type text in a text node"));
171 }
172 }