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"
20 #include <glibmm/i18n.h>
22 static void sp_xmlview_content_class_init (SPXMLViewContentClass * klass);
23 static void sp_xmlview_content_init (SPXMLViewContent * text);
24 static void sp_xmlview_content_destroy (GtkObject * object);
26 void sp_xmlview_content_changed (GtkTextBuffer *tb, SPXMLViewContent *text);
28 static void event_content_changed (Inkscape::XML::Node * repr, const gchar * old_content, const gchar * new_content, gpointer data);
30 static GtkTextViewClass * parent_class = NULL;
32 static Inkscape::XML::NodeEventVector repr_events = {
33 NULL, /* child_added */
34 NULL, /* child_removed */
35 NULL, /* attr_changed */
36 event_content_changed,
37 NULL /* order_changed */
38 };
40 GtkWidget *
41 sp_xmlview_content_new (Inkscape::XML::Node * repr)
42 {
43 GtkTextBuffer *tb;
44 SPXMLViewContent *text;
46 tb = gtk_text_buffer_new (NULL);
47 text = (SPXMLViewContent*)gtk_type_new (SP_TYPE_XMLVIEW_CONTENT);
48 gtk_text_view_set_buffer (GTK_TEXT_VIEW (text), tb);
49 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text), GTK_WRAP_CHAR);
51 g_signal_connect (G_OBJECT (tb), "changed", G_CALLBACK (sp_xmlview_content_changed), text);
53 /* should we alter the scrolling adjustments here? */
55 sp_xmlview_content_set_repr (text, repr);
57 return (GtkWidget *) text;
58 }
60 void
61 sp_xmlview_content_set_repr (SPXMLViewContent * text, Inkscape::XML::Node * repr)
62 {
63 if ( repr == text->repr ) return;
64 if (text->repr) {
65 sp_repr_remove_listener_by_data (text->repr, text);
66 Inkscape::GC::release(text->repr);
67 }
68 text->repr = repr;
69 if (repr) {
70 Inkscape::GC::anchor(repr);
71 sp_repr_add_listener (repr, &repr_events, text);
72 sp_repr_synthesize_events (repr, &repr_events, text);
73 } else {
74 gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (text)), "", 0);
75 gtk_text_view_set_editable (GTK_TEXT_VIEW (text), FALSE);
76 }
77 }
79 GtkType
80 sp_xmlview_content_get_type (void)
81 {
82 static GtkType type = 0;
84 if (!type) {
85 static const GtkTypeInfo info = {
86 "SPXMLViewContent",
87 sizeof (SPXMLViewContent),
88 sizeof (SPXMLViewContentClass),
89 (GtkClassInitFunc) sp_xmlview_content_class_init,
90 (GtkObjectInitFunc) sp_xmlview_content_init,
91 NULL, NULL, NULL
92 };
93 type = gtk_type_unique (GTK_TYPE_TEXT_VIEW, &info);
94 }
96 return type;
97 }
99 void
100 sp_xmlview_content_class_init (SPXMLViewContentClass * klass)
101 {
102 GtkObjectClass * object_class;
104 object_class = (GtkObjectClass *) klass;
106 parent_class = (GtkTextViewClass*)gtk_type_class (GTK_TYPE_TEXT_VIEW);
108 object_class->destroy = sp_xmlview_content_destroy;
109 }
111 void
112 sp_xmlview_content_init (SPXMLViewContent *text)
113 {
114 text->repr = NULL;
115 text->blocked = FALSE;
116 }
118 void
119 sp_xmlview_content_destroy (GtkObject * object)
120 {
121 SPXMLViewContent * text;
123 text = SP_XMLVIEW_CONTENT (object);
125 sp_xmlview_content_set_repr (text, NULL);
127 GTK_OBJECT_CLASS (parent_class)->destroy (object);
128 }
130 void
131 event_content_changed (Inkscape::XML::Node * repr, const gchar * old_content, const gchar * new_content, gpointer data)
132 {
133 SPXMLViewContent * text;
134 text = SP_XMLVIEW_CONTENT (data);
136 if (text->blocked) return;
138 text->blocked = TRUE;
140 if (new_content) {
141 gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (text)), new_content, strlen (new_content));
142 } else {
143 gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (text)), "", 0);
144 }
145 gtk_text_view_set_editable (GTK_TEXT_VIEW (text), new_content != NULL);
147 text->blocked = FALSE;
148 }
150 void
151 sp_xmlview_content_changed (GtkTextBuffer *tb, SPXMLViewContent *text)
152 {
153 if (text->blocked) return;
155 if (text->repr) {
156 GtkTextIter start, end;
157 gchar *data;
158 text->blocked = TRUE;
159 gtk_text_buffer_get_bounds (tb, &start, &end);
160 data = gtk_text_buffer_get_text (tb, &start, &end, TRUE);
161 text->repr->setContent(data);
162 g_free (data);
163 text->blocked = FALSE;
164 sp_document_done (sp_desktop_document (SP_ACTIVE_DESKTOP), SP_VERB_DIALOG_XML_EDITOR,
165 _("Type text in a text node"));
166 }
167 }