1
#define __SP_ATTRIBUTE_WIDGET_C__
4
* \brief SPAttributeWidget
6
* Widget, that listens and modifies repr attributes
9
* Lauris Kaplinski <lauris@ximian.com>
11
* Copyright (C) 2001 Ximian, Inc.
13
* Licensed under GNU GPL
19
#include <gtk/gtktable.h>
20
#include <gtk/gtklabel.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,
37
SPAttributeWidget *spaw );
38
static void sp_attribute_widget_object_release ( SPObject *object,
39
SPAttributeWidget *spaw );
41
static GtkEntryClass *parent_class;
47
sp_attribute_widget_get_type (void)
49
static GtkType type = 0;
51
static const GtkTypeInfo info = {
53
sizeof (SPAttributeWidget),
54
sizeof (SPAttributeWidgetClass),
55
(GtkClassInitFunc) sp_attribute_widget_class_init,
56
(GtkObjectInitFunc) sp_attribute_widget_init,
59
type = gtk_type_unique (GTK_TYPE_ENTRY, &info);
63
} // end of sp_attribute_widget_get_type()
68
sp_attribute_widget_class_init (SPAttributeWidgetClass *klass)
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()
89
sp_attribute_widget_init (SPAttributeWidget *spaw)
91
spaw->blocked = FALSE;
94
spaw->src.object = NULL;
96
spaw->attribute = NULL;
102
sp_attribute_widget_destroy (GtkObject *object)
105
SPAttributeWidget *spaw;
107
spaw = SP_ATTRIBUTE_WIDGET (object);
109
if (spaw->attribute) {
110
g_free (spaw->attribute);
111
spaw->attribute = NULL;
117
if (spaw->src.object) {
118
sp_signal_disconnect_by_data (spaw->src.object, spaw);
119
spaw->src.object = NULL;
123
if (spaw->src.repr) {
124
spaw->src.repr = Inkscape::GC::release(spaw->src.repr);
128
((GtkObjectClass *) parent_class)->destroy (object);
135
sp_attribute_widget_changed (GtkEditable *editable)
138
SPAttributeWidget *spaw;
140
spaw = SP_ATTRIBUTE_WIDGET (editable);
142
if (!spaw->blocked) {
145
spaw->blocked = TRUE;
146
text = gtk_entry_get_text (GTK_ENTRY (spaw));
150
if (spaw->hasobj && spaw->src.object) {
152
if (!sp_repr_set_attr ( SP_OBJECT_REPR (spaw->src.object),
153
spaw->attribute, text) )
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 : "");
159
sp_document_done (SP_OBJECT_DOCUMENT (spaw->src.object));
161
} else if (spaw->src.repr) {
163
if (!sp_repr_set_attr (spaw->src.repr, spaw->attribute, text))
165
/* Cannot set attribute */
166
text = spaw->src.repr->attribute(spaw->attribute);
167
gtk_entry_set_text (GTK_ENTRY (spaw), text ? text : "");
169
/* TODO: Warning! Undo will not be flushed in given case */
171
spaw->blocked = FALSE;
174
} // end of sp_attribute_widget_changed()
179
sp_attribute_widget_new ( SPObject *object, const gchar *attribute )
181
SPAttributeWidget *spaw;
183
g_return_val_if_fail (!object || SP_IS_OBJECT (object), NULL);
184
g_return_val_if_fail (!object || attribute, NULL);
186
spaw = (SPAttributeWidget*)gtk_type_new (SP_TYPE_ATTRIBUTE_WIDGET);
188
sp_attribute_widget_set_object (spaw, object, attribute);
190
return GTK_WIDGET (spaw);
192
} // end of sp_attribute_widget_new()
197
sp_attribute_widget_new_repr ( Inkscape::XML::Node *repr, const gchar *attribute )
199
SPAttributeWidget *spaw;
201
spaw = (SPAttributeWidget*)gtk_type_new (SP_TYPE_ATTRIBUTE_WIDGET);
203
sp_attribute_widget_set_repr (spaw, repr, attribute);
205
return GTK_WIDGET (spaw);
211
sp_attribute_widget_set_object ( SPAttributeWidget *spaw,
213
const gchar *attribute )
216
g_return_if_fail (spaw != NULL);
217
g_return_if_fail (SP_IS_ATTRIBUTE_WIDGET (spaw));
218
g_return_if_fail (!object || SP_IS_OBJECT (object));
219
g_return_if_fail (!object || attribute);
220
g_return_if_fail (attribute != NULL);
222
if (spaw->attribute) {
223
g_free (spaw->attribute);
224
spaw->attribute = NULL;
229
if (spaw->src.object) {
230
sp_signal_disconnect_by_data (spaw->src.object, spaw);
231
spaw->src.object = NULL;
235
if (spaw->src.repr) {
236
spaw->src.repr = Inkscape::GC::release(spaw->src.repr);
245
spaw->blocked = TRUE;
246
spaw->src.object = object;
247
g_signal_connect ( G_OBJECT (object), "modified",
248
G_CALLBACK (sp_attribute_widget_object_modified),
250
g_signal_connect ( G_OBJECT (object), "release",
251
G_CALLBACK (sp_attribute_widget_object_release),
254
spaw->attribute = g_strdup (attribute);
256
val = SP_OBJECT_REPR (object)->attribute(attribute);
257
gtk_entry_set_text (GTK_ENTRY (spaw), val ? val : (const gchar *) "");
258
spaw->blocked = FALSE;
261
gtk_widget_set_sensitive (GTK_WIDGET (spaw), (spaw->src.object != NULL));
263
} // end of sp_attribute_widget_set_object()
268
sp_attribute_widget_set_repr ( SPAttributeWidget *spaw,
269
Inkscape::XML::Node *repr,
270
const gchar *attribute )
273
g_return_if_fail (spaw != NULL);
274
g_return_if_fail (SP_IS_ATTRIBUTE_WIDGET (spaw));
275
g_return_if_fail (attribute != NULL);
277
if (spaw->attribute) {
278
g_free (spaw->attribute);
279
spaw->attribute = NULL;
284
if (spaw->src.object) {
285
sp_signal_disconnect_by_data (spaw->src.object, spaw);
286
spaw->src.object = NULL;
290
if (spaw->src.repr) {
291
spaw->src.repr = Inkscape::GC::release(spaw->src.repr);
295
spaw->hasobj = FALSE;
300
spaw->blocked = TRUE;
301
spaw->src.repr = Inkscape::GC::anchor(repr);
302
spaw->attribute = g_strdup (attribute);
304
val = repr->attribute(attribute);
305
gtk_entry_set_text (GTK_ENTRY (spaw), val ? val : (const gchar *) "");
306
spaw->blocked = FALSE;
309
gtk_widget_set_sensitive (GTK_WIDGET (spaw), (spaw->src.repr != NULL));
311
} // end of sp_attribute_widget_set_repr()
316
sp_attribute_widget_object_modified ( SPObject *object,
318
SPAttributeWidget *spaw )
321
if (flags && SP_OBJECT_MODIFIED_FLAG) {
323
const gchar *val, *text;
324
val = SP_OBJECT_REPR (spaw->src.object)->attribute(spaw->attribute);
325
text = gtk_entry_get_text (GTK_ENTRY (spaw));
329
if (!val || !text || strcmp (val, text)) {
330
/* We are different */
331
spaw->blocked = TRUE;
332
gtk_entry_set_text ( GTK_ENTRY (spaw),
333
val ? val : (const gchar *) "");
334
spaw->blocked = FALSE;
341
} // end of sp_attribute_widget_object_modified()
346
sp_attribute_widget_object_release ( SPObject *object,
347
SPAttributeWidget *spaw )
349
sp_attribute_widget_set_object (spaw, NULL, NULL);
354
/* SPAttributeTable */
356
static void sp_attribute_table_class_init (SPAttributeTableClass *klass);
357
static void sp_attribute_table_init (SPAttributeTable *widget);
358
static void sp_attribute_table_destroy (GtkObject *object);
360
static void sp_attribute_table_object_modified (SPObject *object, guint flags, SPAttributeTable *spaw);
361
static void sp_attribute_table_object_release (SPObject *object, SPAttributeTable *spaw);
362
static void sp_attribute_table_entry_changed (GtkEditable *editable, SPAttributeTable *spat);
364
static GtkVBoxClass *table_parent_class;
370
sp_attribute_table_get_type (void)
372
static GtkType type = 0;
374
static const GtkTypeInfo info = {
376
sizeof (SPAttributeTable),
377
sizeof (SPAttributeTableClass),
378
(GtkClassInitFunc) sp_attribute_table_class_init,
379
(GtkObjectInitFunc) sp_attribute_table_init,
382
type = gtk_type_unique (GTK_TYPE_VBOX, &info);
386
} // end of sp_attribute_table_get_type()
391
sp_attribute_table_class_init (SPAttributeTableClass *klass)
393
GtkObjectClass *object_class;
394
GtkWidgetClass *widget_class;
396
object_class = GTK_OBJECT_CLASS (klass);
397
widget_class = GTK_WIDGET_CLASS (klass);
399
table_parent_class = (GtkVBoxClass*)gtk_type_class (GTK_TYPE_VBOX);
401
object_class->destroy = sp_attribute_table_destroy;
403
} // end of sp_attribute_table_class_init()
408
sp_attribute_table_init ( SPAttributeTable *spat )
410
spat->blocked = FALSE;
411
spat->hasobj = FALSE;
413
spat->src.object = NULL;
415
spat->attributes = NULL;
416
spat->entries = NULL;
420
sp_attribute_table_destroy ( GtkObject *object )
422
SPAttributeTable *spat;
424
spat = SP_ATTRIBUTE_TABLE (object);
426
if (spat->attributes) {
428
for (i = 0; i < spat->num_attr; i++) {
429
g_free (spat->attributes[i]);
431
g_free (spat->attributes);
432
spat->attributes = NULL;
437
if (spat->src.object) {
438
sp_signal_disconnect_by_data (spat->src.object, spat);
439
spat->src.object = NULL;
442
if (spat->src.repr) {
443
spat->src.repr = Inkscape::GC::release(spat->src.repr);
449
g_free (spat->entries);
450
spat->entries = NULL;
455
if (((GtkObjectClass *) table_parent_class)->destroy) {
456
(* ((GtkObjectClass *) table_parent_class)->destroy) (object);
459
} // end of sp_attribute_table_destroy()
463
sp_attribute_table_new ( SPObject *object,
465
const gchar **labels,
466
const gchar **attributes )
468
SPAttributeTable *spat;
470
g_return_val_if_fail (!object || SP_IS_OBJECT (object), NULL);
471
g_return_val_if_fail (!object || (num_attr > 0), NULL);
472
g_return_val_if_fail (!num_attr || (labels && attributes), NULL);
474
spat = (SPAttributeTable*)gtk_type_new (SP_TYPE_ATTRIBUTE_TABLE);
476
sp_attribute_table_set_object (spat, object, num_attr, labels, attributes);
478
return GTK_WIDGET (spat);
480
} // end of sp_attribute_table_new()
485
sp_attribute_table_new_repr ( Inkscape::XML::Node *repr,
487
const gchar **labels,
488
const gchar **attributes )
490
SPAttributeTable *spat;
492
g_return_val_if_fail (!num_attr || (labels && attributes), NULL);
494
spat = (SPAttributeTable*)gtk_type_new (SP_TYPE_ATTRIBUTE_TABLE);
496
sp_attribute_table_set_repr (spat, repr, num_attr, labels, attributes);
498
return GTK_WIDGET (spat);
500
} // end of sp_attribute_table_new_repr()
508
sp_attribute_table_set_object ( SPAttributeTable *spat,
511
const gchar **labels,
512
const gchar **attributes )
515
g_return_if_fail (spat != NULL);
516
g_return_if_fail (SP_IS_ATTRIBUTE_TABLE (spat));
517
g_return_if_fail (!object || SP_IS_OBJECT (object));
518
g_return_if_fail (!object || (num_attr > 0));
519
g_return_if_fail (!num_attr || (labels && attributes));
522
gtk_widget_destroy (spat->table);
526
if (spat->attributes) {
528
for (i = 0; i < spat->num_attr; i++) {
529
g_free (spat->attributes[i]);
531
g_free (spat->attributes);
532
spat->attributes = NULL;
536
g_free (spat->entries);
537
spat->entries = NULL;
541
if (spat->src.object) {
542
sp_signal_disconnect_by_data (spat->src.object, spat);
543
spat->src.object = NULL;
546
if (spat->src.repr) {
547
spat->src.repr = Inkscape::GC::release(spat->src.repr);
556
spat->blocked = TRUE;
559
spat->src.object = object;
560
spat->num_attr = num_attr;
561
g_signal_connect ( G_OBJECT (object), "modified",
562
G_CALLBACK (sp_attribute_table_object_modified),
564
g_signal_connect ( G_OBJECT (object), "release",
565
G_CALLBACK (sp_attribute_table_object_release),
568
spat->table = gtk_table_new (num_attr, 2, FALSE);
569
gtk_container_add (GTK_CONTAINER (spat), spat->table);
571
spat->attributes = g_new0 (gchar *, num_attr);
572
spat->entries = g_new0 (GtkWidget *, num_attr);
574
for (i = 0; i < num_attr; i++) {
578
spat->attributes[i] = g_strdup (attributes[i]);
579
w = gtk_label_new (_(labels[i]));
581
gtk_misc_set_alignment (GTK_MISC (w), 1.0, 0.5);
582
gtk_table_attach ( GTK_TABLE (spat->table), w, 0, 1, i, i + 1,
584
(GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
586
w = gtk_entry_new ();
588
val = SP_OBJECT_REPR (object)->attribute(attributes[i]);
589
gtk_entry_set_text (GTK_ENTRY (w), val ? val : (const gchar *) "");
590
gtk_table_attach ( GTK_TABLE (spat->table), w, 1, 2, i, i + 1,
591
(GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
592
(GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
594
spat->entries[i] = w;
595
g_signal_connect ( G_OBJECT (w), "changed",
596
G_CALLBACK (sp_attribute_table_entry_changed),
600
gtk_widget_show (spat->table);
602
spat->blocked = FALSE;
605
gtk_widget_set_sensitive ( GTK_WIDGET (spat),
606
(spat->src.object != NULL) );
608
} // end of sp_attribute_table_set_object()
613
sp_attribute_table_set_repr ( SPAttributeTable *spat,
614
Inkscape::XML::Node *repr,
616
const gchar **labels,
617
const gchar **attributes )
619
g_return_if_fail (spat != NULL);
620
g_return_if_fail (SP_IS_ATTRIBUTE_TABLE (spat));
621
g_return_if_fail (!num_attr || (labels && attributes));
624
gtk_widget_destroy (spat->table);
628
if (spat->attributes) {
630
for (i = 0; i < spat->num_attr; i++) {
631
g_free (spat->attributes[i]);
633
g_free (spat->attributes);
634
spat->attributes = NULL;
638
g_free (spat->entries);
639
spat->entries = NULL;
643
if (spat->src.object) {
644
sp_signal_disconnect_by_data (spat->src.object, spat);
645
spat->src.object = NULL;
648
if (spat->src.repr) {
649
spat->src.repr = Inkscape::GC::release(spat->src.repr);
653
spat->hasobj = FALSE;
658
spat->blocked = TRUE;
661
spat->src.repr = Inkscape::GC::anchor(repr);
662
spat->num_attr = num_attr;
664
spat->table = gtk_table_new (num_attr, 2, FALSE);
665
gtk_container_add (GTK_CONTAINER (spat), spat->table);
667
spat->attributes = g_new0 (gchar *, num_attr);
668
spat->entries = g_new0 (GtkWidget *, num_attr);
671
for (i = 0; i < num_attr; i++) {
675
spat->attributes[i] = g_strdup (attributes[i]);
676
w = gtk_label_new (labels[i]);
678
gtk_misc_set_alignment (GTK_MISC (w), 1.0, 0.5);
679
gtk_table_attach ( GTK_TABLE (spat->table), w, 0, 1, i, i + 1,
681
(GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
683
w = gtk_entry_new ();
685
val = repr->attribute(attributes[i]);
686
gtk_entry_set_text (GTK_ENTRY (w), val ? val : (const gchar *) "");
687
gtk_table_attach ( GTK_TABLE (spat->table), w, 1, 2, i, i + 1,
688
(GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
689
(GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
691
spat->entries[i] = w;
692
g_signal_connect ( G_OBJECT (w), "changed",
693
G_CALLBACK (sp_attribute_table_entry_changed),
697
gtk_widget_show (spat->table);
699
spat->blocked = FALSE;
702
gtk_widget_set_sensitive (GTK_WIDGET (spat), (spat->src.repr != NULL));
704
} // end of sp_attribute_table_set_repr()
709
sp_attribute_table_object_modified ( SPObject *object,
711
SPAttributeTable *spat )
713
if (flags && SP_OBJECT_MODIFIED_FLAG)
716
for (i = 0; i < spat->num_attr; i++) {
717
const gchar *val, *text;
718
val = SP_OBJECT_REPR (spat->src.object)->attribute(spat->attributes[i]);
719
text = gtk_entry_get_text (GTK_ENTRY (spat->entries[i]));
721
if (!val || !text || strcmp (val, text)) {
722
/* We are different */
723
spat->blocked = TRUE;
724
gtk_entry_set_text ( GTK_ENTRY (spat->entries[i]),
725
val ? val : (const gchar *) "");
726
spat->blocked = FALSE;
732
} // end of sp_attribute_table_object_modified()
737
sp_attribute_table_object_release (SPObject *object, SPAttributeTable *spat)
739
sp_attribute_table_set_object (spat, NULL, 0, NULL, NULL);
745
sp_attribute_table_entry_changed ( GtkEditable *editable,
746
SPAttributeTable *spat )
751
for (i = 0; i < spat->num_attr; i++) {
753
if (GTK_WIDGET (editable) == spat->entries[i]) {
755
spat->blocked = TRUE;
756
text = gtk_entry_get_text (GTK_ENTRY (spat->entries[i]));
761
if (spat->hasobj && spat->src.object) {
762
if (!sp_repr_set_attr ( SP_OBJECT_REPR (spat->src.object),
763
spat->attributes[i], text))
765
/* Cannot set attribute */
766
text = SP_OBJECT_REPR (spat->src.object)->attribute(spat->attributes[i]);
767
gtk_entry_set_text ( GTK_ENTRY (spat->entries[i]),
768
text ? text : (const gchar *) "");
770
sp_document_done (SP_OBJECT_DOCUMENT (spat->src.object));
772
} else if (spat->src.repr) {
774
if (!sp_repr_set_attr (spat->src.repr,
775
spat->attributes[i], text))
777
/* Cannot set attribute */
778
text = spat->src.repr->attribute(spat->attributes[i]);
779
gtk_entry_set_text ( GTK_ENTRY (spat->entries[i]),
780
text ? text : (const gchar *) "" );
782
/* TODO: Warning! Undo will not be flushed in given case */
784
spat->blocked = FALSE;
788
g_warning ("file %s: line %d: Entry signalled change, but there is no such entry", __FILE__, __LINE__);
791
} // end of sp_attribute_table_entry_changed()
796
c-file-style:"stroustrup"
797
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
802
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :