Code

670da965e763d8b10f75b26c6494be42006f3543
[inkscape.git] / src / dialogs / sp-attribute-widget.cpp
1 #define __SP_ATTRIBUTE_WIDGET_C__
3 /**
4  * \brief  SPAttributeWidget
5  *
6  * Widget, that listens and modifies repr attributes
7  *
8  * Authors:
9  *  Lauris Kaplinski <lauris@ximian.com>
10  *
11  * Copyright (C) 2001 Ximian, Inc.
12  *
13  * Licensed under GNU GPL
14  */
15 #ifdef HAVE_CONFIG_H
16 # include "config.h"
17 #endif
19 #include <gtk/gtktable.h>
20 #include <gtk/gtklabel.h>
21 #include "xml/repr.h"
22 #include "macros.h"
23 #include "document.h"
24 #include "sp-object.h"
25 #include <glibmm/i18n.h>
27 #include "sp-attribute-widget.h"
29 static void sp_attribute_widget_class_init (SPAttributeWidgetClass *klass);
30 static void sp_attribute_widget_init (SPAttributeWidget *widget);
31 static void sp_attribute_widget_destroy (GtkObject *object);
33 static void sp_attribute_widget_changed (GtkEditable *editable);
35 static void sp_attribute_widget_object_modified ( SPObject *object, 
36                                                   guint flags, 
37                                                   SPAttributeWidget *spaw );
38 static void sp_attribute_widget_object_release ( SPObject *object, 
39                                                  SPAttributeWidget *spaw );
41 static GtkEntryClass *parent_class;
46 GtkType
47 sp_attribute_widget_get_type (void)
48 {
49     static GtkType type = 0;
50     if (!type) {
51         static const GtkTypeInfo info = {
52             "SPAttributeWidget",
53             sizeof (SPAttributeWidget),
54             sizeof (SPAttributeWidgetClass),
55             (GtkClassInitFunc) sp_attribute_widget_class_init,
56             (GtkObjectInitFunc) sp_attribute_widget_init,
57             NULL, NULL, NULL
58         };
59         type = gtk_type_unique (GTK_TYPE_ENTRY, &info);
60     }
61     return type;
62     
63 } // end of sp_attribute_widget_get_type()
67 static void
68 sp_attribute_widget_class_init (SPAttributeWidgetClass *klass)
69 {
70     GtkObjectClass *object_class;
71     GtkWidgetClass *widget_class;
72     GtkEditableClass *editable_class;
74     object_class = GTK_OBJECT_CLASS (klass);
75     widget_class = GTK_WIDGET_CLASS (klass);
76     editable_class = GTK_EDITABLE_CLASS (klass);
78     parent_class = (GtkEntryClass*)gtk_type_class (GTK_TYPE_ENTRY);
80     object_class->destroy = sp_attribute_widget_destroy;
82     editable_class->changed = sp_attribute_widget_changed;
84 } // end of sp_attribute_widget_class_init()
88 static void
89 sp_attribute_widget_init (SPAttributeWidget *spaw)
90 {
91     spaw->blocked = FALSE;
92     spaw->hasobj = FALSE;
94     spaw->src.object = NULL;
96     spaw->attribute = NULL;
97 }
101 static void
102 sp_attribute_widget_destroy (GtkObject *object)
104     
105     SPAttributeWidget *spaw;
107     spaw = SP_ATTRIBUTE_WIDGET (object);
109     if (spaw->attribute) {
110         g_free (spaw->attribute);
111         spaw->attribute = NULL;
112     }
114     
115     if (spaw->hasobj) {
116         
117         if (spaw->src.object) {
118             sp_signal_disconnect_by_data (spaw->src.object, spaw);
119             spaw->src.object = NULL;
120         }
121     } else {
122     
123         if (spaw->src.repr) {
124             spaw->src.repr = Inkscape::GC::release(spaw->src.repr);
125         }
126     } // end of if()
127     
128     ((GtkObjectClass *) parent_class)->destroy (object);
134 static void
135 sp_attribute_widget_changed (GtkEditable *editable)
138     SPAttributeWidget *spaw;
140     spaw = SP_ATTRIBUTE_WIDGET (editable);
142     if (!spaw->blocked) {
143     
144         const gchar *text;
145         spaw->blocked = TRUE;
146         text = gtk_entry_get_text (GTK_ENTRY (spaw));
147         if (!*text) 
148             text = NULL;
149         
150         if (spaw->hasobj && spaw->src.object) {
151             
152             if (!sp_repr_set_attr ( SP_OBJECT_REPR (spaw->src.object), 
153                                     spaw->attribute, text) )
154             {
155                 /* Cannot set attribute */
156                 text = SP_OBJECT_REPR (spaw->src.object)->attribute(spaw->attribute);
157                 gtk_entry_set_text (GTK_ENTRY (spaw), text ? text : "");
158             }
159             sp_document_done (SP_OBJECT_DOCUMENT (spaw->src.object), SP_VERB_NONE, 
160                               /* TODO: annotate */ "sp-attribute-widget.cpp:160");
161             
162         } else if (spaw->src.repr) {
163         
164             if (!sp_repr_set_attr (spaw->src.repr, spaw->attribute, text))
165             {
166                 /* Cannot set attribute */
167                 text = spaw->src.repr->attribute(spaw->attribute);
168                 gtk_entry_set_text (GTK_ENTRY (spaw), text ? text : "");
169             }
170             /* TODO: Warning! Undo will not be flushed in given case */
171         }
172         spaw->blocked = FALSE;
173     }
174     
175 } // end of sp_attribute_widget_changed()
179 GtkWidget *
180 sp_attribute_widget_new ( SPObject *object, const gchar *attribute )
182     SPAttributeWidget *spaw;
184     g_return_val_if_fail (!object || SP_IS_OBJECT (object), NULL);
185     g_return_val_if_fail (!object || attribute, NULL);
187     spaw = (SPAttributeWidget*)gtk_type_new (SP_TYPE_ATTRIBUTE_WIDGET);
189     sp_attribute_widget_set_object (spaw, object, attribute);
191     return GTK_WIDGET (spaw);
192     
193 } // end of sp_attribute_widget_new()
197 GtkWidget *
198 sp_attribute_widget_new_repr ( Inkscape::XML::Node *repr, const gchar *attribute )
200     SPAttributeWidget *spaw;
202     spaw = (SPAttributeWidget*)gtk_type_new (SP_TYPE_ATTRIBUTE_WIDGET);
204     sp_attribute_widget_set_repr (spaw, repr, attribute);
206     return GTK_WIDGET (spaw);
211 void
212 sp_attribute_widget_set_object ( SPAttributeWidget *spaw, 
213                                  SPObject *object, 
214                                  const gchar *attribute )
217     g_return_if_fail (spaw != NULL);
218     g_return_if_fail (SP_IS_ATTRIBUTE_WIDGET (spaw));
219     g_return_if_fail (!object || SP_IS_OBJECT (object));
220     g_return_if_fail (!object || attribute);
221     g_return_if_fail (attribute != NULL);
223     if (spaw->attribute) {
224         g_free (spaw->attribute);
225         spaw->attribute = NULL;
226     }
228     if (spaw->hasobj) {
229     
230         if (spaw->src.object) {
231             sp_signal_disconnect_by_data (spaw->src.object, spaw);
232             spaw->src.object = NULL;
233         }
234     } else {
235         
236         if (spaw->src.repr) {
237             spaw->src.repr = Inkscape::GC::release(spaw->src.repr);
238         }
239     }
241     spaw->hasobj = TRUE;
243     if (object) {
244         const gchar *val;
246         spaw->blocked = TRUE;
247         spaw->src.object = object;
248         g_signal_connect ( G_OBJECT (object), "modified", 
249                            G_CALLBACK (sp_attribute_widget_object_modified), 
250                            spaw );
251         g_signal_connect ( G_OBJECT (object), "release", 
252                            G_CALLBACK (sp_attribute_widget_object_release), 
253                            spaw );
255         spaw->attribute = g_strdup (attribute);
257         val = SP_OBJECT_REPR (object)->attribute(attribute);
258         gtk_entry_set_text (GTK_ENTRY (spaw), val ? val : (const gchar *) "");
259         spaw->blocked = FALSE;
260     }
262     gtk_widget_set_sensitive (GTK_WIDGET (spaw), (spaw->src.object != NULL));
264 } // end of sp_attribute_widget_set_object()
268 void
269 sp_attribute_widget_set_repr ( SPAttributeWidget *spaw, 
270                                Inkscape::XML::Node *repr, 
271                                const gchar *attribute )
274     g_return_if_fail (spaw != NULL);
275     g_return_if_fail (SP_IS_ATTRIBUTE_WIDGET (spaw));
276     g_return_if_fail (attribute != NULL);
278     if (spaw->attribute) {
279         g_free (spaw->attribute);
280         spaw->attribute = NULL;
281     }
283     if (spaw->hasobj) {
284     
285         if (spaw->src.object) {
286             sp_signal_disconnect_by_data (spaw->src.object, spaw);
287             spaw->src.object = NULL;
288         }
289     } else {
290         
291         if (spaw->src.repr) {
292             spaw->src.repr = Inkscape::GC::release(spaw->src.repr);
293         }
294     }
296     spaw->hasobj = FALSE;
298     if (repr) {
299         const gchar *val;
301         spaw->blocked = TRUE;
302         spaw->src.repr = Inkscape::GC::anchor(repr);
303         spaw->attribute = g_strdup (attribute);
305         val = repr->attribute(attribute);
306         gtk_entry_set_text (GTK_ENTRY (spaw), val ? val : (const gchar *) "");
307         spaw->blocked = FALSE;
308     }
310     gtk_widget_set_sensitive (GTK_WIDGET (spaw), (spaw->src.repr != NULL));
312 } // end of sp_attribute_widget_set_repr()
316 static void
317 sp_attribute_widget_object_modified ( SPObject *object, 
318                                       guint flags, 
319                                       SPAttributeWidget *spaw )
322     if (flags && SP_OBJECT_MODIFIED_FLAG) {
323         
324         const gchar *val, *text;
325         val = SP_OBJECT_REPR (spaw->src.object)->attribute(spaw->attribute);
326         text = gtk_entry_get_text (GTK_ENTRY (spaw));
327         
328         if (val || text) {
329             
330             if (!val || !text || strcmp (val, text)) {
331                 /* We are different */
332                 spaw->blocked = TRUE;
333                 gtk_entry_set_text ( GTK_ENTRY (spaw), 
334                                      val ? val : (const gchar *) "");
335                 spaw->blocked = FALSE;
336             } // end of if()
337         
338         } // end of if()
339         
340     } //end of if()
342 } // end of sp_attribute_widget_object_modified()
346 static void
347 sp_attribute_widget_object_release ( SPObject *object, 
348                                      SPAttributeWidget *spaw )
350     sp_attribute_widget_set_object (spaw, NULL, NULL);
355 /* SPAttributeTable */
357 static void sp_attribute_table_class_init (SPAttributeTableClass *klass);
358 static void sp_attribute_table_init (SPAttributeTable *widget);
359 static void sp_attribute_table_destroy (GtkObject *object);
361 static void sp_attribute_table_object_modified (SPObject *object, guint flags, SPAttributeTable *spaw);
362 static void sp_attribute_table_object_release (SPObject *object, SPAttributeTable *spaw);
363 static void sp_attribute_table_entry_changed (GtkEditable *editable, SPAttributeTable *spat);
365 static GtkVBoxClass *table_parent_class;
370 GtkType
371 sp_attribute_table_get_type (void)
373     static GtkType type = 0;
374     if (!type) {
375         static const GtkTypeInfo info = {
376             "SPAttributeTable",
377             sizeof (SPAttributeTable),
378             sizeof (SPAttributeTableClass),
379             (GtkClassInitFunc) sp_attribute_table_class_init,
380             (GtkObjectInitFunc) sp_attribute_table_init,
381             NULL, NULL, NULL
382         };
383         type = gtk_type_unique (GTK_TYPE_VBOX, &info);
384     }
385     return type;
387 } // end of sp_attribute_table_get_type()
391 static void
392 sp_attribute_table_class_init (SPAttributeTableClass *klass)
394     GtkObjectClass *object_class;
395     GtkWidgetClass *widget_class;
397     object_class = GTK_OBJECT_CLASS (klass);
398     widget_class = GTK_WIDGET_CLASS (klass);
400     table_parent_class = (GtkVBoxClass*)gtk_type_class (GTK_TYPE_VBOX);
402     object_class->destroy = sp_attribute_table_destroy;
404 } // end of sp_attribute_table_class_init()
408 static void
409 sp_attribute_table_init ( SPAttributeTable *spat )
411     spat->blocked = FALSE;
412     spat->hasobj = FALSE;
413     spat->table = NULL;
414     spat->src.object = NULL;
415     spat->num_attr = 0;
416     spat->attributes = NULL;
417     spat->entries = NULL;
420 static void
421 sp_attribute_table_destroy ( GtkObject *object )
423     SPAttributeTable *spat;
425     spat = SP_ATTRIBUTE_TABLE (object);
427     if (spat->attributes) {
428         gint i;
429         for (i = 0; i < spat->num_attr; i++) {
430             g_free (spat->attributes[i]);
431         }
432         g_free (spat->attributes);
433         spat->attributes = NULL;
434     }
436     if (spat->hasobj) {
437         
438         if (spat->src.object) {
439             sp_signal_disconnect_by_data (spat->src.object, spat);
440             spat->src.object = NULL;
441         }
442     } else {
443         if (spat->src.repr) {
444             spat->src.repr = Inkscape::GC::release(spat->src.repr);
445         }
446     } // end of if()
448     
449     if (spat->entries) {
450         g_free (spat->entries);
451         spat->entries = NULL;
452     }
454     spat->table = NULL;
456     if (((GtkObjectClass *) table_parent_class)->destroy) {
457         (* ((GtkObjectClass *) table_parent_class)->destroy) (object);
458     }
459         
460 } // end of sp_attribute_table_destroy()
463 GtkWidget *
464 sp_attribute_table_new ( SPObject *object, 
465                          gint num_attr, 
466                          const gchar **labels, 
467                          const gchar **attributes )
469     SPAttributeTable *spat;
471     g_return_val_if_fail (!object || SP_IS_OBJECT (object), NULL);
472     g_return_val_if_fail (!object || (num_attr > 0), NULL);
473     g_return_val_if_fail (!num_attr || (labels && attributes), NULL);
475     spat = (SPAttributeTable*)gtk_type_new (SP_TYPE_ATTRIBUTE_TABLE);
477     sp_attribute_table_set_object (spat, object, num_attr, labels, attributes);
479     return GTK_WIDGET (spat);
481 } // end of sp_attribute_table_new()
485 GtkWidget *
486 sp_attribute_table_new_repr ( Inkscape::XML::Node *repr, 
487                               gint num_attr, 
488                               const gchar **labels, 
489                               const gchar **attributes )
491     SPAttributeTable *spat;
493     g_return_val_if_fail (!num_attr || (labels && attributes), NULL);
495     spat = (SPAttributeTable*)gtk_type_new (SP_TYPE_ATTRIBUTE_TABLE);
497     sp_attribute_table_set_repr (spat, repr, num_attr, labels, attributes);
499     return GTK_WIDGET (spat);
501 } // end of sp_attribute_table_new_repr()
505 #define XPAD 4
506 #define YPAD 0
508 void
509 sp_attribute_table_set_object ( SPAttributeTable *spat, 
510                                 SPObject *object, 
511                                 gint num_attr, 
512                                 const gchar **labels, 
513                                 const gchar **attributes )
516     g_return_if_fail (spat != NULL);
517     g_return_if_fail (SP_IS_ATTRIBUTE_TABLE (spat));
518     g_return_if_fail (!object || SP_IS_OBJECT (object));
519     g_return_if_fail (!object || (num_attr > 0));
520     g_return_if_fail (!num_attr || (labels && attributes));
522     if (spat->table) {
523         gtk_widget_destroy (spat->table);
524         spat->table = NULL;
525     }
527     if (spat->attributes) {
528         gint i;
529         for (i = 0; i < spat->num_attr; i++) {
530             g_free (spat->attributes[i]);
531         }
532         g_free (spat->attributes);
533         spat->attributes = NULL;
534     }
536     if (spat->entries) {
537         g_free (spat->entries);
538         spat->entries = NULL;
539     }
541     if (spat->hasobj) {
542         if (spat->src.object) {
543             sp_signal_disconnect_by_data (spat->src.object, spat);
544             spat->src.object = NULL;
545         }
546     } else {
547         if (spat->src.repr) {
548             spat->src.repr = Inkscape::GC::release(spat->src.repr);
549         }
550     }
552     spat->hasobj = TRUE;
554     if (object) {
555         gint i;
557         spat->blocked = TRUE;
559         /* Set up object */
560         spat->src.object = object;
561         spat->num_attr = num_attr;
562         g_signal_connect ( G_OBJECT (object), "modified", 
563                            G_CALLBACK (sp_attribute_table_object_modified), 
564                            spat );
565         g_signal_connect ( G_OBJECT (object), "release", 
566                            G_CALLBACK (sp_attribute_table_object_release), 
567                            spat );
568         /* Create table */
569         spat->table = gtk_table_new (num_attr, 2, FALSE);
570         gtk_container_add (GTK_CONTAINER (spat), spat->table);
571         /* Arrays */
572         spat->attributes = g_new0 (gchar *, num_attr);
573         spat->entries = g_new0 (GtkWidget *, num_attr);
574         /* Fill rows */
575         for (i = 0; i < num_attr; i++) {
576             GtkWidget *w;
577             const gchar *val;
579             spat->attributes[i] = g_strdup (attributes[i]);
580             w = gtk_label_new (_(labels[i]));
581             gtk_widget_show (w);
582             gtk_misc_set_alignment (GTK_MISC (w), 1.0, 0.5);
583             gtk_table_attach ( GTK_TABLE (spat->table), w, 0, 1, i, i + 1, 
584                                GTK_FILL, 
585                                (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 
586                                XPAD, YPAD );
587             w = gtk_entry_new ();
588             gtk_widget_show (w);
589             val = SP_OBJECT_REPR (object)->attribute(attributes[i]);
590             gtk_entry_set_text (GTK_ENTRY (w), val ? val : (const gchar *) "");
591             gtk_table_attach ( GTK_TABLE (spat->table), w, 1, 2, i, i + 1, 
592                                (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 
593                                (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 
594                                XPAD, YPAD );
595             spat->entries[i] = w;
596             g_signal_connect ( G_OBJECT (w), "changed", 
597                                G_CALLBACK (sp_attribute_table_entry_changed), 
598                                spat );
599         }
600         /* Show table */
601         gtk_widget_show (spat->table);
603         spat->blocked = FALSE;
604     }
606     gtk_widget_set_sensitive ( GTK_WIDGET (spat), 
607                                (spat->src.object != NULL) );
609 } // end of sp_attribute_table_set_object()
613 void
614 sp_attribute_table_set_repr ( SPAttributeTable *spat, 
615                               Inkscape::XML::Node *repr, 
616                               gint num_attr, 
617                               const gchar **labels, 
618                               const gchar **attributes )
620     g_return_if_fail (spat != NULL);
621     g_return_if_fail (SP_IS_ATTRIBUTE_TABLE (spat));
622     g_return_if_fail (!num_attr || (labels && attributes));
624     if (spat->table) {
625         gtk_widget_destroy (spat->table);
626         spat->table = NULL;
627     }
629     if (spat->attributes) {
630         gint i;
631         for (i = 0; i < spat->num_attr; i++) {
632             g_free (spat->attributes[i]);
633         }
634         g_free (spat->attributes);
635         spat->attributes = NULL;
636     }
638     if (spat->entries) {
639         g_free (spat->entries);
640         spat->entries = NULL;
641     }
643     if (spat->hasobj) {
644         if (spat->src.object) {
645             sp_signal_disconnect_by_data (spat->src.object, spat);
646             spat->src.object = NULL;
647         }
648     } else {
649         if (spat->src.repr) {
650             spat->src.repr = Inkscape::GC::release(spat->src.repr);
651         }
652     }
654     spat->hasobj = FALSE;
656     if (repr) {
657         gint i;
659         spat->blocked = TRUE;
661         /* Set up repr */
662         spat->src.repr = Inkscape::GC::anchor(repr);
663         spat->num_attr = num_attr;
664         /* Create table */
665         spat->table = gtk_table_new (num_attr, 2, FALSE);
666         gtk_container_add (GTK_CONTAINER (spat), spat->table);
667         /* Arrays */
668         spat->attributes = g_new0 (gchar *, num_attr);
669         spat->entries = g_new0 (GtkWidget *, num_attr);
670         
671         /* Fill rows */
672         for (i = 0; i < num_attr; i++) {
673             GtkWidget *w;
674             const gchar *val;
676             spat->attributes[i] = g_strdup (attributes[i]);
677             w = gtk_label_new (labels[i]);
678             gtk_widget_show (w);
679             gtk_misc_set_alignment (GTK_MISC (w), 1.0, 0.5);
680             gtk_table_attach ( GTK_TABLE (spat->table), w, 0, 1, i, i + 1, 
681                                GTK_FILL, 
682                                (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 
683                                XPAD, YPAD );
684             w = gtk_entry_new ();
685             gtk_widget_show (w);
686             val = repr->attribute(attributes[i]);
687             gtk_entry_set_text (GTK_ENTRY (w), val ? val : (const gchar *) "");
688             gtk_table_attach ( GTK_TABLE (spat->table), w, 1, 2, i, i + 1, 
689                                (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 
690                                (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 
691                                XPAD, YPAD );
692             spat->entries[i] = w;
693             g_signal_connect ( G_OBJECT (w), "changed", 
694                                G_CALLBACK (sp_attribute_table_entry_changed), 
695                                spat );
696         }
697         /* Show table */
698         gtk_widget_show (spat->table);
700         spat->blocked = FALSE;
701     }
703     gtk_widget_set_sensitive (GTK_WIDGET (spat), (spat->src.repr != NULL));
705 } // end of sp_attribute_table_set_repr()
709 static void
710 sp_attribute_table_object_modified ( SPObject *object, 
711                                      guint flags, 
712                                      SPAttributeTable *spat )
714     if (flags && SP_OBJECT_MODIFIED_FLAG)
715     {
716         gint i;
717         for (i = 0; i < spat->num_attr; i++) {
718             const gchar *val, *text;
719             val = SP_OBJECT_REPR (spat->src.object)->attribute(spat->attributes[i]);
720             text = gtk_entry_get_text (GTK_ENTRY (spat->entries[i]));
721             if (val || text) {
722                 if (!val || !text || strcmp (val, text)) {
723                     /* We are different */
724                     spat->blocked = TRUE;
725                     gtk_entry_set_text ( GTK_ENTRY (spat->entries[i]), 
726                                          val ? val : (const gchar *) "");
727                     spat->blocked = FALSE;
728                 }
729             }
730         }
731     } // end of if()
732     
733 } // end of sp_attribute_table_object_modified()
737 static void
738 sp_attribute_table_object_release (SPObject *object, SPAttributeTable *spat)
740     sp_attribute_table_set_object (spat, NULL, 0, NULL, NULL);
745 static void
746 sp_attribute_table_entry_changed ( GtkEditable *editable, 
747                                    SPAttributeTable *spat )
749     if (!spat->blocked)
750     {
751         gint i;
752         for (i = 0; i < spat->num_attr; i++) {
753         
754             if (GTK_WIDGET (editable) == spat->entries[i]) {
755                 const gchar *text;
756                 spat->blocked = TRUE;
757                 text = gtk_entry_get_text (GTK_ENTRY (spat->entries[i]));
758                 
759                 if (!*text) 
760                     text = NULL;
761                 
762                 if (spat->hasobj && spat->src.object) {
763                     if (!sp_repr_set_attr ( SP_OBJECT_REPR (spat->src.object), 
764                                             spat->attributes[i], text))
765                     {
766                         /* Cannot set attribute */
767                         text = SP_OBJECT_REPR (spat->src.object)->attribute(spat->attributes[i]);
768                         gtk_entry_set_text ( GTK_ENTRY (spat->entries[i]), 
769                                              text ? text : (const gchar *) "");
770                     }
771                     sp_document_done (SP_OBJECT_DOCUMENT (spat->src.object), SP_VERB_NONE, 
772                                       /* TODO: annotate */ "sp-attribute-widget.cpp:772");
773                     
774                 } else if (spat->src.repr) {
775                     
776                     if (!sp_repr_set_attr (spat->src.repr, 
777                                            spat->attributes[i], text)) 
778                     {
779                         /* Cannot set attribute */
780                         text = spat->src.repr->attribute(spat->attributes[i]);
781                         gtk_entry_set_text ( GTK_ENTRY (spat->entries[i]), 
782                                              text ? text : (const gchar *) "" );
783                     }
784                     /* TODO: Warning! Undo will not be flushed in given case */
785                 }
786                 spat->blocked = FALSE;
787                 return;
788             }
789         }
790         g_warning ("file %s: line %d: Entry signalled change, but there is no such entry", __FILE__, __LINE__);
791     } // end of if()
793 } // end of sp_attribute_table_entry_changed()
795 /*
796   Local Variables:
797   mode:c++
798   c-file-style:"stroustrup"
799   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
800   indent-tabs-mode:nil
801   fill-column:99
802   End:
803 */
804 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :