Code

fix 198818
[inkscape.git] / src / widgets / sp-xmlview-content.cpp
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 GtkType
81 sp_xmlview_content_get_type (void)
82 {
83     static GtkType type = 0;
85     if (!type) {
86         static const GtkTypeInfo info = {
87             "SPXMLViewContent",
88             sizeof (SPXMLViewContent),
89             sizeof (SPXMLViewContentClass),
90             (GtkClassInitFunc) sp_xmlview_content_class_init,
91             (GtkObjectInitFunc) sp_xmlview_content_init,
92             NULL, NULL, NULL
93         };
94         type = gtk_type_unique (GTK_TYPE_TEXT_VIEW, &info);
95     }
97     return type;
98 }
100 void
101 sp_xmlview_content_class_init (SPXMLViewContentClass * klass)
103     GtkObjectClass * object_class;
105     object_class = (GtkObjectClass *) klass;
107     parent_class = (GtkTextViewClass*)gtk_type_class (GTK_TYPE_TEXT_VIEW);
109     object_class->destroy = sp_xmlview_content_destroy;
112 void
113 sp_xmlview_content_init (SPXMLViewContent *text)
115     text->repr = NULL;
116     text->blocked = FALSE;
119 void
120 sp_xmlview_content_destroy (GtkObject * object)
122     SPXMLViewContent * text;
124     text = SP_XMLVIEW_CONTENT (object);
126     sp_xmlview_content_set_repr (text, NULL);
128     GTK_OBJECT_CLASS (parent_class)->destroy (object);
131 void
132 event_content_changed (Inkscape::XML::Node * /*repr*/, const gchar * /*old_content*/, const gchar * new_content, gpointer data)
134     SPXMLViewContent * text;
135     text = SP_XMLVIEW_CONTENT (data);
137     if (text->blocked) return;
139     text->blocked = TRUE;
141     if (new_content) {
142         gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (text)), new_content, strlen (new_content));
143     } else {
144         gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (text)), "", 0);
145     }
146     gtk_text_view_set_editable (GTK_TEXT_VIEW (text), new_content != NULL);
148     text->blocked = FALSE;
151 void
152 sp_xmlview_content_changed (GtkTextBuffer *tb, SPXMLViewContent *text)
154     if (text->blocked) return;
156     if (text->repr) {
157         GtkTextIter start, end;
158         gchar *data;
159         text->blocked = TRUE;
160         gtk_text_buffer_get_bounds (tb, &start, &end);
161         data = gtk_text_buffer_get_text (tb, &start, &end, TRUE);
162         text->repr->setContent(data);
163         g_free (data);
164         text->blocked = FALSE;
165         sp_document_done (sp_desktop_document (SP_ACTIVE_DESKTOP), SP_VERB_DIALOG_XML_EDITOR,
166                           _("Type text in a text node"));
167     }