Code

switch to sigc++ SPObject signals for SPAttributeWidget and SPAttributeTable
[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 <sigc++/functors/ptr_fun.h>
28 #include <sigc++/adaptors/bind.h>
30 #include "sp-attribute-widget.h"
32 static void sp_attribute_widget_class_init (SPAttributeWidgetClass *klass);
33 static void sp_attribute_widget_init (SPAttributeWidget *widget);
34 static void sp_attribute_widget_destroy (GtkObject *object);
36 static void sp_attribute_widget_changed (GtkEditable *editable);
38 static void sp_attribute_widget_object_modified ( SPObject *object, 
39                                                   guint flags, 
40                                                   SPAttributeWidget *spaw );
41 static void sp_attribute_widget_object_release ( SPObject *object, 
42                                                  SPAttributeWidget *spaw );
44 static GtkEntryClass *parent_class;
49 GtkType
50 sp_attribute_widget_get_type (void)
51 {
52     static GtkType type = 0;
53     if (!type) {
54         static const GtkTypeInfo info = {
55             "SPAttributeWidget",
56             sizeof (SPAttributeWidget),
57             sizeof (SPAttributeWidgetClass),
58             (GtkClassInitFunc) sp_attribute_widget_class_init,
59             (GtkObjectInitFunc) sp_attribute_widget_init,
60             NULL, NULL, NULL
61         };
62         type = gtk_type_unique (GTK_TYPE_ENTRY, &info);
63     }
64     return type;
65     
66 } // end of sp_attribute_widget_get_type()
70 static void
71 sp_attribute_widget_class_init (SPAttributeWidgetClass *klass)
72 {
73     GtkObjectClass *object_class;
74     GtkWidgetClass *widget_class;
75     GtkEditableClass *editable_class;
77     object_class = GTK_OBJECT_CLASS (klass);
78     widget_class = GTK_WIDGET_CLASS (klass);
79     editable_class = GTK_EDITABLE_CLASS (klass);
81     parent_class = (GtkEntryClass*)gtk_type_class (GTK_TYPE_ENTRY);
83     object_class->destroy = sp_attribute_widget_destroy;
85     editable_class->changed = sp_attribute_widget_changed;
87 } // end of sp_attribute_widget_class_init()
91 static void
92 sp_attribute_widget_init (SPAttributeWidget *spaw)
93 {
94     spaw->blocked = FALSE;
95     spaw->hasobj = FALSE;
97     spaw->src.object = NULL;
99     spaw->attribute = NULL;
101     new (&spaw->modified_connection) sigc::connection();
102     new (&spaw->release_connection) sigc::connection();
107 static void
108 sp_attribute_widget_destroy (GtkObject *object)
110     
111     SPAttributeWidget *spaw;
113     spaw = SP_ATTRIBUTE_WIDGET (object);
115     if (spaw->attribute) {
116         g_free (spaw->attribute);
117         spaw->attribute = NULL;
118     }
120     
121     if (spaw->hasobj) {
122         
123         if (spaw->src.object) {
124             spaw->modified_connection.disconnect();
125             spaw->release_connection.disconnect();
126             spaw->src.object = NULL;
127         }
128     } else {
129     
130         if (spaw->src.repr) {
131             spaw->src.repr = Inkscape::GC::release(spaw->src.repr);
132         }
133     } // end of if()
135     spaw->modified_connection.~connection();
136     spaw->release_connection.~connection();
137     
138     ((GtkObjectClass *) parent_class)->destroy (object);
144 static void
145 sp_attribute_widget_changed (GtkEditable *editable)
148     SPAttributeWidget *spaw;
150     spaw = SP_ATTRIBUTE_WIDGET (editable);
152     if (!spaw->blocked) {
153     
154         const gchar *text;
155         spaw->blocked = TRUE;
156         text = gtk_entry_get_text (GTK_ENTRY (spaw));
157         if (!*text) 
158             text = NULL;
159         
160         if (spaw->hasobj && spaw->src.object) {
161             
162             if (!sp_repr_set_attr ( SP_OBJECT_REPR (spaw->src.object), 
163                                     spaw->attribute, text) )
164             {
165                 /* Cannot set attribute */
166                 text = SP_OBJECT_REPR (spaw->src.object)->attribute(spaw->attribute);
167                 gtk_entry_set_text (GTK_ENTRY (spaw), text ? text : "");
168             }
169             sp_document_done (SP_OBJECT_DOCUMENT (spaw->src.object), SP_VERB_NONE, 
170                               /* TODO: annotate */ "sp-attribute-widget.cpp:160");
171             
172         } else if (spaw->src.repr) {
173         
174             if (!sp_repr_set_attr (spaw->src.repr, spaw->attribute, text))
175             {
176                 /* Cannot set attribute */
177                 text = spaw->src.repr->attribute(spaw->attribute);
178                 gtk_entry_set_text (GTK_ENTRY (spaw), text ? text : "");
179             }
180             /* TODO: Warning! Undo will not be flushed in given case */
181         }
182         spaw->blocked = FALSE;
183     }
184     
185 } // end of sp_attribute_widget_changed()
189 GtkWidget *
190 sp_attribute_widget_new ( SPObject *object, const gchar *attribute )
192     SPAttributeWidget *spaw;
194     g_return_val_if_fail (!object || SP_IS_OBJECT (object), NULL);
195     g_return_val_if_fail (!object || attribute, NULL);
197     spaw = (SPAttributeWidget*)gtk_type_new (SP_TYPE_ATTRIBUTE_WIDGET);
199     sp_attribute_widget_set_object (spaw, object, attribute);
201     return GTK_WIDGET (spaw);
202     
203 } // end of sp_attribute_widget_new()
207 GtkWidget *
208 sp_attribute_widget_new_repr ( Inkscape::XML::Node *repr, const gchar *attribute )
210     SPAttributeWidget *spaw;
212     spaw = (SPAttributeWidget*)gtk_type_new (SP_TYPE_ATTRIBUTE_WIDGET);
214     sp_attribute_widget_set_repr (spaw, repr, attribute);
216     return GTK_WIDGET (spaw);
221 void
222 sp_attribute_widget_set_object ( SPAttributeWidget *spaw, 
223                                  SPObject *object, 
224                                  const gchar *attribute )
227     g_return_if_fail (spaw != NULL);
228     g_return_if_fail (SP_IS_ATTRIBUTE_WIDGET (spaw));
229     g_return_if_fail (!object || SP_IS_OBJECT (object));
230     g_return_if_fail (!object || attribute);
231     g_return_if_fail (attribute != NULL);
233     if (spaw->attribute) {
234         g_free (spaw->attribute);
235         spaw->attribute = NULL;
236     }
238     if (spaw->hasobj) {
239     
240         if (spaw->src.object) {
241             spaw->modified_connection.disconnect();
242             spaw->release_connection.disconnect();
243             spaw->src.object = NULL;
244         }
245     } else {
246         
247         if (spaw->src.repr) {
248             spaw->src.repr = Inkscape::GC::release(spaw->src.repr);
249         }
250     }
252     spaw->hasobj = TRUE;
254     if (object) {
255         const gchar *val;
257         spaw->blocked = TRUE;
258         spaw->src.object = object;
260         spaw->modified_connection = object->connectModified(sigc::bind<2>(sigc::ptr_fun(&sp_attribute_widget_object_modified), spaw));
261         spaw->release_connection = object->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_attribute_widget_object_release), spaw));
263         spaw->attribute = g_strdup (attribute);
265         val = SP_OBJECT_REPR (object)->attribute(attribute);
266         gtk_entry_set_text (GTK_ENTRY (spaw), val ? val : (const gchar *) "");
267         spaw->blocked = FALSE;
268     }
270     gtk_widget_set_sensitive (GTK_WIDGET (spaw), (spaw->src.object != NULL));
272 } // end of sp_attribute_widget_set_object()
276 void
277 sp_attribute_widget_set_repr ( SPAttributeWidget *spaw, 
278                                Inkscape::XML::Node *repr, 
279                                const gchar *attribute )
282     g_return_if_fail (spaw != NULL);
283     g_return_if_fail (SP_IS_ATTRIBUTE_WIDGET (spaw));
284     g_return_if_fail (attribute != NULL);
286     if (spaw->attribute) {
287         g_free (spaw->attribute);
288         spaw->attribute = NULL;
289     }
291     if (spaw->hasobj) {
292     
293         if (spaw->src.object) {
294             spaw->modified_connection.disconnect();
295             spaw->release_connection.disconnect();
296             spaw->src.object = NULL;
297         }
298     } else {
299         
300         if (spaw->src.repr) {
301             spaw->src.repr = Inkscape::GC::release(spaw->src.repr);
302         }
303     }
305     spaw->hasobj = FALSE;
307     if (repr) {
308         const gchar *val;
310         spaw->blocked = TRUE;
311         spaw->src.repr = Inkscape::GC::anchor(repr);
312         spaw->attribute = g_strdup (attribute);
314         val = repr->attribute(attribute);
315         gtk_entry_set_text (GTK_ENTRY (spaw), val ? val : (const gchar *) "");
316         spaw->blocked = FALSE;
317     }
319     gtk_widget_set_sensitive (GTK_WIDGET (spaw), (spaw->src.repr != NULL));
321 } // end of sp_attribute_widget_set_repr()
325 static void
326 sp_attribute_widget_object_modified ( SPObject *object, 
327                                       guint flags, 
328                                       SPAttributeWidget *spaw )
331     if (flags && SP_OBJECT_MODIFIED_FLAG) {
332         
333         const gchar *val, *text;
334         val = SP_OBJECT_REPR (spaw->src.object)->attribute(spaw->attribute);
335         text = gtk_entry_get_text (GTK_ENTRY (spaw));
336         
337         if (val || text) {
338             
339             if (!val || !text || strcmp (val, text)) {
340                 /* We are different */
341                 spaw->blocked = TRUE;
342                 gtk_entry_set_text ( GTK_ENTRY (spaw), 
343                                      val ? val : (const gchar *) "");
344                 spaw->blocked = FALSE;
345             } // end of if()
346         
347         } // end of if()
348         
349     } //end of if()
351 } // end of sp_attribute_widget_object_modified()
355 static void
356 sp_attribute_widget_object_release ( SPObject *object, 
357                                      SPAttributeWidget *spaw )
359     sp_attribute_widget_set_object (spaw, NULL, NULL);
364 /* SPAttributeTable */
366 static void sp_attribute_table_class_init (SPAttributeTableClass *klass);
367 static void sp_attribute_table_init (SPAttributeTable *widget);
368 static void sp_attribute_table_destroy (GtkObject *object);
370 static void sp_attribute_table_object_modified (SPObject *object, guint flags, SPAttributeTable *spaw);
371 static void sp_attribute_table_object_release (SPObject *object, SPAttributeTable *spaw);
372 static void sp_attribute_table_entry_changed (GtkEditable *editable, SPAttributeTable *spat);
374 static GtkVBoxClass *table_parent_class;
379 GtkType
380 sp_attribute_table_get_type (void)
382     static GtkType type = 0;
383     if (!type) {
384         static const GtkTypeInfo info = {
385             "SPAttributeTable",
386             sizeof (SPAttributeTable),
387             sizeof (SPAttributeTableClass),
388             (GtkClassInitFunc) sp_attribute_table_class_init,
389             (GtkObjectInitFunc) sp_attribute_table_init,
390             NULL, NULL, NULL
391         };
392         type = gtk_type_unique (GTK_TYPE_VBOX, &info);
393     }
394     return type;
396 } // end of sp_attribute_table_get_type()
400 static void
401 sp_attribute_table_class_init (SPAttributeTableClass *klass)
403     GtkObjectClass *object_class;
404     GtkWidgetClass *widget_class;
406     object_class = GTK_OBJECT_CLASS (klass);
407     widget_class = GTK_WIDGET_CLASS (klass);
409     table_parent_class = (GtkVBoxClass*)gtk_type_class (GTK_TYPE_VBOX);
411     object_class->destroy = sp_attribute_table_destroy;
413 } // end of sp_attribute_table_class_init()
417 static void
418 sp_attribute_table_init ( SPAttributeTable *spat )
420     spat->blocked = FALSE;
421     spat->hasobj = FALSE;
422     spat->table = NULL;
423     spat->src.object = NULL;
424     spat->num_attr = 0;
425     spat->attributes = NULL;
426     spat->entries = NULL;
428     new (&spat->modified_connection) sigc::connection();
429     new (&spat->release_connection) sigc::connection();
432 static void
433 sp_attribute_table_destroy ( GtkObject *object )
435     SPAttributeTable *spat;
437     spat = SP_ATTRIBUTE_TABLE (object);
439     if (spat->attributes) {
440         gint i;
441         for (i = 0; i < spat->num_attr; i++) {
442             g_free (spat->attributes[i]);
443         }
444         g_free (spat->attributes);
445         spat->attributes = NULL;
446     }
448     if (spat->hasobj) {
449         
450         if (spat->src.object) {
451             spat->modified_connection.disconnect();
452             spat->release_connection.disconnect();
453             spat->src.object = NULL;
454         }
455     } else {
456         if (spat->src.repr) {
457             spat->src.repr = Inkscape::GC::release(spat->src.repr);
458         }
459     } // end of if()
461     spat->modified_connection.~connection();
462     spat->release_connection.~connection();
463     
464     if (spat->entries) {
465         g_free (spat->entries);
466         spat->entries = NULL;
467     }
469     spat->table = NULL;
471     if (((GtkObjectClass *) table_parent_class)->destroy) {
472         (* ((GtkObjectClass *) table_parent_class)->destroy) (object);
473     }
474         
475 } // end of sp_attribute_table_destroy()
478 GtkWidget *
479 sp_attribute_table_new ( SPObject *object, 
480                          gint num_attr, 
481                          const gchar **labels, 
482                          const gchar **attributes )
484     SPAttributeTable *spat;
486     g_return_val_if_fail (!object || SP_IS_OBJECT (object), NULL);
487     g_return_val_if_fail (!object || (num_attr > 0), NULL);
488     g_return_val_if_fail (!num_attr || (labels && attributes), NULL);
490     spat = (SPAttributeTable*)gtk_type_new (SP_TYPE_ATTRIBUTE_TABLE);
492     sp_attribute_table_set_object (spat, object, num_attr, labels, attributes);
494     return GTK_WIDGET (spat);
496 } // end of sp_attribute_table_new()
500 GtkWidget *
501 sp_attribute_table_new_repr ( Inkscape::XML::Node *repr, 
502                               gint num_attr, 
503                               const gchar **labels, 
504                               const gchar **attributes )
506     SPAttributeTable *spat;
508     g_return_val_if_fail (!num_attr || (labels && attributes), NULL);
510     spat = (SPAttributeTable*)gtk_type_new (SP_TYPE_ATTRIBUTE_TABLE);
512     sp_attribute_table_set_repr (spat, repr, num_attr, labels, attributes);
514     return GTK_WIDGET (spat);
516 } // end of sp_attribute_table_new_repr()
520 #define XPAD 4
521 #define YPAD 0
523 void
524 sp_attribute_table_set_object ( SPAttributeTable *spat, 
525                                 SPObject *object, 
526                                 gint num_attr, 
527                                 const gchar **labels, 
528                                 const gchar **attributes )
531     g_return_if_fail (spat != NULL);
532     g_return_if_fail (SP_IS_ATTRIBUTE_TABLE (spat));
533     g_return_if_fail (!object || SP_IS_OBJECT (object));
534     g_return_if_fail (!object || (num_attr > 0));
535     g_return_if_fail (!num_attr || (labels && attributes));
537     if (spat->table) {
538         gtk_widget_destroy (spat->table);
539         spat->table = NULL;
540     }
542     if (spat->attributes) {
543         gint i;
544         for (i = 0; i < spat->num_attr; i++) {
545             g_free (spat->attributes[i]);
546         }
547         g_free (spat->attributes);
548         spat->attributes = NULL;
549     }
551     if (spat->entries) {
552         g_free (spat->entries);
553         spat->entries = NULL;
554     }
556     if (spat->hasobj) {
557         if (spat->src.object) {
558             spat->modified_connection.disconnect();
559             spat->release_connection.disconnect();
560             spat->src.object = NULL;
561         }
562     } else {
563         if (spat->src.repr) {
564             spat->src.repr = Inkscape::GC::release(spat->src.repr);
565         }
566     }
568     spat->hasobj = TRUE;
570     if (object) {
571         gint i;
573         spat->blocked = TRUE;
575         /* Set up object */
576         spat->src.object = object;
577         spat->num_attr = num_attr;
579         spat->modified_connection = object->connectModified(sigc::bind<2>(sigc::ptr_fun(&sp_attribute_table_object_modified), spat));
580         spat->modified_connection = object->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_attribute_table_object_release), spat));
582         /* Create table */
583         spat->table = gtk_table_new (num_attr, 2, FALSE);
584         gtk_container_add (GTK_CONTAINER (spat), spat->table);
585         /* Arrays */
586         spat->attributes = g_new0 (gchar *, num_attr);
587         spat->entries = g_new0 (GtkWidget *, num_attr);
588         /* Fill rows */
589         for (i = 0; i < num_attr; i++) {
590             GtkWidget *w;
591             const gchar *val;
593             spat->attributes[i] = g_strdup (attributes[i]);
594             w = gtk_label_new (_(labels[i]));
595             gtk_widget_show (w);
596             gtk_misc_set_alignment (GTK_MISC (w), 1.0, 0.5);
597             gtk_table_attach ( GTK_TABLE (spat->table), w, 0, 1, i, i + 1, 
598                                GTK_FILL, 
599                                (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 
600                                XPAD, YPAD );
601             w = gtk_entry_new ();
602             gtk_widget_show (w);
603             val = SP_OBJECT_REPR (object)->attribute(attributes[i]);
604             gtk_entry_set_text (GTK_ENTRY (w), val ? val : (const gchar *) "");
605             gtk_table_attach ( GTK_TABLE (spat->table), w, 1, 2, i, i + 1, 
606                                (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 
607                                (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 
608                                XPAD, YPAD );
609             spat->entries[i] = w;
610             g_signal_connect ( G_OBJECT (w), "changed", 
611                                G_CALLBACK (sp_attribute_table_entry_changed), 
612                                spat );
613         }
614         /* Show table */
615         gtk_widget_show (spat->table);
617         spat->blocked = FALSE;
618     }
620     gtk_widget_set_sensitive ( GTK_WIDGET (spat), 
621                                (spat->src.object != NULL) );
623 } // end of sp_attribute_table_set_object()
627 void
628 sp_attribute_table_set_repr ( SPAttributeTable *spat, 
629                               Inkscape::XML::Node *repr, 
630                               gint num_attr, 
631                               const gchar **labels, 
632                               const gchar **attributes )
634     g_return_if_fail (spat != NULL);
635     g_return_if_fail (SP_IS_ATTRIBUTE_TABLE (spat));
636     g_return_if_fail (!num_attr || (labels && attributes));
638     if (spat->table) {
639         gtk_widget_destroy (spat->table);
640         spat->table = NULL;
641     }
643     if (spat->attributes) {
644         gint i;
645         for (i = 0; i < spat->num_attr; i++) {
646             g_free (spat->attributes[i]);
647         }
648         g_free (spat->attributes);
649         spat->attributes = NULL;
650     }
652     if (spat->entries) {
653         g_free (spat->entries);
654         spat->entries = NULL;
655     }
657     if (spat->hasobj) {
658         if (spat->src.object) {
659             spat->modified_connection.disconnect();
660             spat->release_connection.disconnect();
661             spat->src.object = NULL;
662         }
663     } else {
664         if (spat->src.repr) {
665             spat->src.repr = Inkscape::GC::release(spat->src.repr);
666         }
667     }
669     spat->hasobj = FALSE;
671     if (repr) {
672         gint i;
674         spat->blocked = TRUE;
676         /* Set up repr */
677         spat->src.repr = Inkscape::GC::anchor(repr);
678         spat->num_attr = num_attr;
679         /* Create table */
680         spat->table = gtk_table_new (num_attr, 2, FALSE);
681         gtk_container_add (GTK_CONTAINER (spat), spat->table);
682         /* Arrays */
683         spat->attributes = g_new0 (gchar *, num_attr);
684         spat->entries = g_new0 (GtkWidget *, num_attr);
685         
686         /* Fill rows */
687         for (i = 0; i < num_attr; i++) {
688             GtkWidget *w;
689             const gchar *val;
691             spat->attributes[i] = g_strdup (attributes[i]);
692             w = gtk_label_new (labels[i]);
693             gtk_widget_show (w);
694             gtk_misc_set_alignment (GTK_MISC (w), 1.0, 0.5);
695             gtk_table_attach ( GTK_TABLE (spat->table), w, 0, 1, i, i + 1, 
696                                GTK_FILL, 
697                                (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 
698                                XPAD, YPAD );
699             w = gtk_entry_new ();
700             gtk_widget_show (w);
701             val = repr->attribute(attributes[i]);
702             gtk_entry_set_text (GTK_ENTRY (w), val ? val : (const gchar *) "");
703             gtk_table_attach ( GTK_TABLE (spat->table), w, 1, 2, i, i + 1, 
704                                (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 
705                                (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 
706                                XPAD, YPAD );
707             spat->entries[i] = w;
708             g_signal_connect ( G_OBJECT (w), "changed", 
709                                G_CALLBACK (sp_attribute_table_entry_changed), 
710                                spat );
711         }
712         /* Show table */
713         gtk_widget_show (spat->table);
715         spat->blocked = FALSE;
716     }
718     gtk_widget_set_sensitive (GTK_WIDGET (spat), (spat->src.repr != NULL));
720 } // end of sp_attribute_table_set_repr()
724 static void
725 sp_attribute_table_object_modified ( SPObject *object, 
726                                      guint flags, 
727                                      SPAttributeTable *spat )
729     if (flags && SP_OBJECT_MODIFIED_FLAG)
730     {
731         gint i;
732         for (i = 0; i < spat->num_attr; i++) {
733             const gchar *val, *text;
734             val = SP_OBJECT_REPR (spat->src.object)->attribute(spat->attributes[i]);
735             text = gtk_entry_get_text (GTK_ENTRY (spat->entries[i]));
736             if (val || text) {
737                 if (!val || !text || strcmp (val, text)) {
738                     /* We are different */
739                     spat->blocked = TRUE;
740                     gtk_entry_set_text ( GTK_ENTRY (spat->entries[i]), 
741                                          val ? val : (const gchar *) "");
742                     spat->blocked = FALSE;
743                 }
744             }
745         }
746     } // end of if()
747     
748 } // end of sp_attribute_table_object_modified()
752 static void
753 sp_attribute_table_object_release (SPObject *object, SPAttributeTable *spat)
755     sp_attribute_table_set_object (spat, NULL, 0, NULL, NULL);
760 static void
761 sp_attribute_table_entry_changed ( GtkEditable *editable, 
762                                    SPAttributeTable *spat )
764     if (!spat->blocked)
765     {
766         gint i;
767         for (i = 0; i < spat->num_attr; i++) {
768         
769             if (GTK_WIDGET (editable) == spat->entries[i]) {
770                 const gchar *text;
771                 spat->blocked = TRUE;
772                 text = gtk_entry_get_text (GTK_ENTRY (spat->entries[i]));
773                 
774                 if (!*text) 
775                     text = NULL;
776                 
777                 if (spat->hasobj && spat->src.object) {
778                     if (!sp_repr_set_attr ( SP_OBJECT_REPR (spat->src.object), 
779                                             spat->attributes[i], text))
780                     {
781                         /* Cannot set attribute */
782                         text = SP_OBJECT_REPR (spat->src.object)->attribute(spat->attributes[i]);
783                         gtk_entry_set_text ( GTK_ENTRY (spat->entries[i]), 
784                                              text ? text : (const gchar *) "");
785                     }
786                     sp_document_done (SP_OBJECT_DOCUMENT (spat->src.object), SP_VERB_NONE, 
787                                       /* TODO: annotate */ "sp-attribute-widget.cpp:772");
788                     
789                 } else if (spat->src.repr) {
790                     
791                     if (!sp_repr_set_attr (spat->src.repr, 
792                                            spat->attributes[i], text)) 
793                     {
794                         /* Cannot set attribute */
795                         text = spat->src.repr->attribute(spat->attributes[i]);
796                         gtk_entry_set_text ( GTK_ENTRY (spat->entries[i]), 
797                                              text ? text : (const gchar *) "" );
798                     }
799                     /* TODO: Warning! Undo will not be flushed in given case */
800                 }
801                 spat->blocked = FALSE;
802                 return;
803             }
804         }
805         g_warning ("file %s: line %d: Entry signalled change, but there is no such entry", __FILE__, __LINE__);
806     } // end of if()
808 } // end of sp_attribute_table_entry_changed()
810 /*
811   Local Variables:
812   mode:c++
813   c-file-style:"stroustrup"
814   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
815   indent-tabs-mode:nil
816   fill-column:99
817   End:
818 */
819 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :