2 * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
4 * Copyright (C) 2003-2005, Evan Battaglia <gtoevan@gmx.net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "vikradiogroup.h"
26 /* functions common to all layers. */
27 /* TODO longone: rename interface free -> finalize */
29 extern VikLayerInterface vik_aggregate_layer_interface
;
30 extern VikLayerInterface vik_trw_layer_interface
;
31 extern VikLayerInterface vik_maps_layer_interface
;
32 extern VikLayerInterface vik_coord_layer_interface
;
33 extern VikLayerInterface vik_georef_layer_interface
;
34 extern VikLayerInterface vik_gps_layer_interface
;
40 static guint layer_signals
[VL_LAST_SIGNAL
] = { 0 };
42 static GObjectClass
*parent_class
;
44 static void layer_class_init ( VikLayerClass
*klass
);
45 static void layer_init ( VikLayer
*vl
);
46 static void layer_finalize ( VikLayer
*vl
);
47 static gboolean
layer_properties_factory ( VikLayer
*vl
, gpointer vp
);
50 /* TODO longone: rename vik_layer_init -> set_type */
52 GType
vik_layer_get_type ()
54 static GType vl_type
= 0;
58 static const GTypeInfo vl_info
=
60 sizeof (VikLayerClass
),
62 NULL
, /* base_finalize */
63 (GClassInitFunc
) layer_class_init
, /* class init */
64 NULL
, /* class_finalize */
65 NULL
, /* class_data */
68 (GInstanceInitFunc
) layer_init
/* instance init */
70 vl_type
= g_type_register_static ( G_TYPE_OBJECT
, "VikLayer", &vl_info
, 0 );
76 static void layer_class_init (VikLayerClass
*klass
)
78 GObjectClass
*object_class
;
80 object_class
= G_OBJECT_CLASS (klass
);
82 object_class
->finalize
= (GObjectFinalizeFunc
) layer_finalize
;
84 parent_class
= g_type_class_peek_parent (klass
);
86 layer_signals
[VL_UPDATE_SIGNAL
] = g_signal_new ( "update", G_TYPE_FROM_CLASS (klass
),
87 G_SIGNAL_RUN_FIRST
| G_SIGNAL_ACTION
, G_STRUCT_OFFSET (VikLayerClass
, update
), NULL
, NULL
,
88 g_cclosure_marshal_VOID__VOID
, G_TYPE_NONE
, 0);
91 void vik_layer_emit_update ( VikLayer
*vl
)
94 g_signal_emit ( G_OBJECT(vl
), layer_signals
[VL_UPDATE_SIGNAL
], 0 );
97 static VikLayerInterface
*vik_layer_interfaces
[VIK_LAYER_NUM_TYPES
] = {
98 &vik_aggregate_layer_interface
,
99 &vik_trw_layer_interface
,
100 &vik_coord_layer_interface
,
101 &vik_georef_layer_interface
,
102 &vik_gps_layer_interface
,
103 &vik_maps_layer_interface
,
106 VikLayerInterface
*vik_layer_get_interface ( gint type
)
108 g_assert ( type
< VIK_LAYER_NUM_TYPES
);
109 return vik_layer_interfaces
[type
];
112 static void layer_init ( VikLayer
*vl
)
116 vl
->realized
= FALSE
;
119 void vik_layer_init ( VikLayer
*vl
, gint type
)
125 void vik_layer_rename ( VikLayer
*l
, const gchar
*new_name
)
127 g_assert ( l
!= NULL
);
130 l
->name
= g_strdup ( new_name
);
133 void vik_layer_rename_no_copy ( VikLayer
*l
, gchar
*new_name
)
135 g_assert ( l
!= NULL
);
141 VikLayer
*vik_layer_create ( gint type
, gpointer vp
, GtkWindow
*w
, gboolean interactive
)
143 VikLayer
*new_layer
= NULL
;
144 g_assert ( type
< VIK_LAYER_NUM_TYPES
);
146 new_layer
= vik_layer_interfaces
[type
]->create ( vp
);
148 g_assert ( new_layer
!= NULL
);
152 if ( vik_layer_properties ( new_layer
, vp
) )
153 vik_layer_rename ( VIK_LAYER(new_layer
), vik_layer_interfaces
[type
]->name
);
156 g_object_unref ( G_OBJECT(new_layer
) ); /* cancel that */
163 /* returns TRUE if OK was pressed */
164 gboolean
vik_layer_properties ( VikLayer
*layer
, gpointer vp
)
166 if ( vik_layer_interfaces
[layer
->type
]->properties
)
167 return vik_layer_interfaces
[layer
->type
]->properties ( layer
, vp
);
168 return layer_properties_factory ( layer
, vp
);
171 void vik_layer_draw ( VikLayer
*l
, gpointer data
)
174 if ( vik_layer_interfaces
[l
->type
]->draw
)
175 vik_layer_interfaces
[l
->type
]->draw ( l
, data
);
178 void vik_layer_change_coord_mode ( VikLayer
*l
, VikCoordMode mode
)
180 if ( vik_layer_interfaces
[l
->type
]->change_coord_mode
)
181 vik_layer_interfaces
[l
->type
]->change_coord_mode ( l
, mode
);
184 VikLayer
*vik_layer_copy ( VikLayer
*vl
, gpointer vp
)
186 if ( vik_layer_interfaces
[vl
->type
]->copy
)
188 VikLayer
*rv
= vik_layer_interfaces
[vl
->type
]->copy ( vl
, vp
);
191 vik_layer_rename ( rv
, vl
->name
);
192 rv
->visible
= vl
->visible
;
206 void vik_layer_marshall ( VikLayer
*vl
, guint8
**data
, gint
*len
)
209 if ( vl
&& vik_layer_interfaces
[vl
->type
]->marshall
) {
210 vik_layer_interfaces
[vl
->type
]->marshall ( vl
, data
, len
);
212 header
= g_malloc(*len
+ sizeof(*header
));
213 header
->layer_type
= vl
->type
;
215 memcpy(header
->data
, *data
, *len
);
217 *data
= (guint8
*)header
;
218 *len
= *len
+ sizeof(*header
);
225 void vik_layer_marshall_params ( VikLayer
*vl
, guint8
**data
, gint
*datalen
)
227 VikLayerParam
*params
= vik_layer_get_interface(vl
->type
)->params
;
228 VikLayerFuncGetParam get_param
= vik_layer_get_interface(vl
->type
)->get_param
;
229 GByteArray
* b
= g_byte_array_new ();
232 #define vlm_append(obj, sz) \
234 g_byte_array_append ( b, (guint8 *)&len, sizeof(len) ); \
235 g_byte_array_append ( b, (guint8 *)(obj), len );
237 vlm_append(vl
->name
, strlen(vl
->name
));
239 if ( params
&& get_param
)
242 guint16 i
, params_count
= vik_layer_get_interface(vl
->type
)->params_count
;
243 for ( i
= 0; i
< params_count
; i
++ )
245 d
= get_param(vl
, i
);
246 switch ( params
[i
].type
)
248 case VIK_LAYER_PARAM_STRING
:
249 vlm_append(d
.s
, strlen(d
.s
));
252 vlm_append(&d
, sizeof(d
));
260 g_byte_array_free ( b
, FALSE
);
265 void vik_layer_unmarshall_params ( VikLayer
*vl
, guint8
*data
, gint datalen
, VikViewport
*vvp
)
267 VikLayerParam
*params
= vik_layer_get_interface(vl
->type
)->params
;
268 VikLayerFuncSetParam set_param
= vik_layer_get_interface(vl
->type
)->set_param
;
270 guint8
*b
= (guint8
*)data
;
272 #define vlm_size (*(gint *)b)
273 #define vlm_read(obj) \
274 memcpy((obj), b+sizeof(gint), vlm_size); \
275 b += sizeof(gint) + vlm_size;
277 s
= g_malloc(vlm_size
+ 1);
281 vik_layer_rename(vl
, s
);
285 if ( params
&& set_param
)
288 guint16 i
, params_count
= vik_layer_get_interface(vl
->type
)->params_count
;
289 for ( i
= 0; i
< params_count
; i
++ )
291 switch ( params
[i
].type
)
293 case VIK_LAYER_PARAM_STRING
:
294 s
= g_malloc(vlm_size
+ 1);
298 set_param(vl
, i
, d
, vvp
);
303 set_param(vl
, i
, d
, vvp
);
310 VikLayer
*vik_layer_unmarshall ( guint8
*data
, gint len
, VikViewport
*vvp
)
314 header
= (header_t
*)data
;
316 if ( vik_layer_interfaces
[header
->layer_type
]->unmarshall
) {
317 return vik_layer_interfaces
[header
->layer_type
]->unmarshall ( header
->data
, header
->len
, vvp
);
323 static void layer_finalize ( VikLayer
*vl
)
325 g_assert ( vl
!= NULL
);
326 if ( vik_layer_interfaces
[vl
->type
]->free
)
327 vik_layer_interfaces
[vl
->type
]->free ( vl
);
330 G_OBJECT_CLASS(parent_class
)->finalize(G_OBJECT(vl
));
333 /* sublayer switching */
334 gboolean
vik_layer_sublayer_toggle_visible ( VikLayer
*l
, gint subtype
, gpointer sublayer
)
336 if ( vik_layer_interfaces
[l
->type
]->sublayer_toggle_visible
)
337 return vik_layer_interfaces
[l
->type
]->sublayer_toggle_visible ( l
, subtype
, sublayer
);
338 return TRUE
; /* if unknown, will always be visible */
341 void vik_layer_realize ( VikLayer
*l
, VikTreeview
*vt
, GtkTreeIter
*layer_iter
)
344 l
->iter
= *layer_iter
;
346 if ( vik_layer_interfaces
[l
->type
]->realize
)
347 vik_layer_interfaces
[l
->type
]->realize ( l
, vt
, layer_iter
);
350 void vik_layer_set_menu_items_selection(VikLayer
*l
, guint16 selection
)
352 if ( vik_layer_interfaces
[l
->type
]->set_menu_selection
)
353 vik_layer_interfaces
[l
->type
]->set_menu_selection ( l
, selection
);
356 guint16
vik_layer_get_menu_items_selection(VikLayer
*l
)
358 if ( vik_layer_interfaces
[l
->type
]->get_menu_selection
)
359 return(vik_layer_interfaces
[l
->type
]->get_menu_selection (l
));
361 return(vik_layer_interfaces
[l
->type
]->menu_items_selection
);
364 void vik_layer_add_menu_items ( VikLayer
*l
, GtkMenu
*menu
, gpointer vlp
)
366 if ( vik_layer_interfaces
[l
->type
]->add_menu_items
)
367 vik_layer_interfaces
[l
->type
]->add_menu_items ( l
, menu
, vlp
);
370 gboolean
vik_layer_sublayer_add_menu_items ( VikLayer
*l
, GtkMenu
*menu
, gpointer vlp
, gint subtype
, gpointer sublayer
, GtkTreeIter
*iter
)
372 if ( vik_layer_interfaces
[l
->type
]->sublayer_add_menu_items
)
373 return vik_layer_interfaces
[l
->type
]->sublayer_add_menu_items ( l
, menu
, vlp
, subtype
, sublayer
, iter
);
378 const gchar
*vik_layer_sublayer_rename_request ( VikLayer
*l
, const gchar
*newname
, gpointer vlp
, gint subtype
, gpointer sublayer
, GtkTreeIter
*iter
)
380 if ( vik_layer_interfaces
[l
->type
]->sublayer_rename_request
)
381 return vik_layer_interfaces
[l
->type
]->sublayer_rename_request ( l
, newname
, vlp
, subtype
, sublayer
, iter
);
385 GdkPixbuf
*vik_layer_load_icon ( gint type
)
387 g_assert ( type
< VIK_LAYER_NUM_TYPES
);
388 if ( vik_layer_interfaces
[type
]->icon
)
389 return gdk_pixbuf_from_pixdata ( vik_layer_interfaces
[type
]->icon
, FALSE
, NULL
);
393 gboolean
vik_layer_set_param ( VikLayer
*layer
, guint16 id
, VikLayerParamData data
, gpointer vp
)
395 if ( vik_layer_interfaces
[layer
->type
]->set_param
)
396 return vik_layer_interfaces
[layer
->type
]->set_param ( layer
, id
, data
, vp
);
400 void vik_layer_post_read ( VikLayer
*layer
, gpointer vp
)
402 if ( vik_layer_interfaces
[layer
->type
]->post_read
)
403 vik_layer_interfaces
[layer
->type
]->post_read ( layer
, vp
);
406 static GtkWidget
*properties_widget_new_widget ( VikLayerParam
*param
, VikLayerParamData data
)
408 GtkWidget
*rv
= NULL
;
409 switch ( param
->widget_type
)
411 case VIK_LAYER_WIDGET_COLOR
:
412 if ( param
->type
== VIK_LAYER_PARAM_COLOR
)
413 rv
= gtk_color_button_new_with_color ( &(data
.c
) );
415 case VIK_LAYER_WIDGET_CHECKBUTTON
:
416 if ( param
->type
== VIK_LAYER_PARAM_BOOLEAN
)
418 //rv = gtk_check_button_new_with_label ( //param->title );
419 rv
= gtk_check_button_new ();
421 gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON(rv
), TRUE
);
424 case VIK_LAYER_WIDGET_COMBOBOX
:
426 if ( param
->type
== VIK_LAYER_PARAM_UINT
&& param
->widget_data
)
428 gchar
**pstr
= param
->widget_data
;
429 rv
= gtk_combo_box_new_text ();
431 gtk_combo_box_append_text ( GTK_COMBO_BOX ( rv
), *(pstr
++) );
432 if ( param
->extra_widget_data
) /* map of alternate uint values for options */
435 for ( i
= 0; ((const char **)param
->widget_data
)[i
]; i
++ )
436 if ( ((guint
*)param
->extra_widget_data
)[i
] == data
.u
)
438 gtk_combo_box_set_active ( GTK_COMBO_BOX(rv
), i
);
442 gtk_combo_box_set_active ( GTK_COMBO_BOX ( rv
), data
.u
);
446 case VIK_LAYER_WIDGET_RADIOGROUP
:
447 /* widget_data and extra_widget_data are GList */
448 if ( param
->type
== VIK_LAYER_PARAM_UINT
&& param
->widget_data
)
450 rv
= vik_radio_group_new ( param
->widget_data
);
451 if ( param
->extra_widget_data
) /* map of alternate uint values for options */
454 int nb_elem
= g_list_length(param
->widget_data
);
455 for ( i
= 0; i
< nb_elem
; i
++ )
456 if ( g_list_nth_data(param
->extra_widget_data
, i
) == data
.u
)
458 vik_radio_group_set_selected ( VIK_RADIO_GROUP(rv
), i
);
462 else if ( data
.u
) /* zero is already default */
463 vik_radio_group_set_selected ( VIK_RADIO_GROUP(rv
), data
.u
);
466 case VIK_LAYER_WIDGET_SPINBUTTON
:
467 if ( (param
->type
== VIK_LAYER_PARAM_DOUBLE
|| param
->type
== VIK_LAYER_PARAM_UINT
468 || param
->type
== VIK_LAYER_PARAM_INT
) && param
->widget_data
)
470 gdouble init_val
= (param
->type
== VIK_LAYER_PARAM_DOUBLE
) ? data
.d
: (param
->type
== VIK_LAYER_PARAM_UINT
? data
.u
: data
.i
);
471 VikLayerParamScale
*scale
= (VikLayerParamScale
*) param
->widget_data
;
472 rv
= gtk_spin_button_new ( GTK_ADJUSTMENT(gtk_adjustment_new( init_val
, scale
->min
, scale
->max
, scale
->step
, scale
->step
, scale
->step
)), scale
->step
, scale
->digits
);
475 case VIK_LAYER_WIDGET_ENTRY
:
476 if ( param
->type
== VIK_LAYER_PARAM_STRING
)
478 rv
= gtk_entry_new ();
479 gtk_entry_set_text ( GTK_ENTRY(rv
), data
.s
);
482 case VIK_LAYER_WIDGET_FILEENTRY
:
483 if ( param
->type
== VIK_LAYER_PARAM_STRING
)
485 rv
= vik_file_entry_new ();
486 vik_file_entry_set_filename ( VIK_FILE_ENTRY(rv
), data
.s
);
489 case VIK_LAYER_WIDGET_HSCALE
:
490 if ( (param
->type
== VIK_LAYER_PARAM_DOUBLE
|| param
->type
== VIK_LAYER_PARAM_UINT
491 || param
->type
== VIK_LAYER_PARAM_INT
) && param
->widget_data
)
493 gdouble init_val
= (param
->type
== VIK_LAYER_PARAM_DOUBLE
) ? data
.d
: (param
->type
== VIK_LAYER_PARAM_UINT
? data
.u
: data
.i
);
494 VikLayerParamScale
*scale
= (VikLayerParamScale
*) param
->widget_data
;
495 rv
= gtk_hscale_new_with_range ( scale
->min
, scale
->max
, scale
->step
);
496 gtk_scale_set_digits ( GTK_SCALE(rv
), scale
->digits
);
497 gtk_range_set_value ( GTK_RANGE(rv
), init_val
);
503 static VikLayerParamData
properties_widget_get_value ( GtkWidget
*widget
, VikLayerParam
*param
)
505 VikLayerParamData rv
;
506 switch ( param
->widget_type
)
508 case VIK_LAYER_WIDGET_COLOR
:
509 gtk_color_button_get_color ( GTK_COLOR_BUTTON(widget
), &(rv
.c
) );
511 case VIK_LAYER_WIDGET_CHECKBUTTON
:
512 rv
.b
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget
));
514 case VIK_LAYER_WIDGET_COMBOBOX
:
516 rv
.i
= gtk_combo_box_get_active ( GTK_COMBO_BOX(widget
) );
517 if ( rv
.i
== -1 ) rv
.i
= 0;
519 if ( param
->extra_widget_data
)
520 rv
.u
= ((guint
*)param
->extra_widget_data
)[rv
.u
];
523 case VIK_LAYER_WIDGET_RADIOGROUP
:
524 rv
.u
= vik_radio_group_get_selected(VIK_RADIO_GROUP(widget
));
525 if ( param
->extra_widget_data
)
526 rv
.u
= (guint
*)g_list_nth_data(param
->extra_widget_data
, rv
.u
);
528 case VIK_LAYER_WIDGET_SPINBUTTON
:
529 if ( param
->type
== VIK_LAYER_PARAM_UINT
)
530 rv
.u
= gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON(widget
) );
531 else if ( param
->type
== VIK_LAYER_PARAM_INT
)
532 rv
.i
= gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON(widget
) );
534 rv
.d
= gtk_spin_button_get_value ( GTK_SPIN_BUTTON(widget
) );
536 case VIK_LAYER_WIDGET_ENTRY
:
537 rv
.s
= gtk_entry_get_text ( GTK_ENTRY(widget
) );
539 case VIK_LAYER_WIDGET_FILEENTRY
:
540 rv
.s
= vik_file_entry_get_filename ( VIK_FILE_ENTRY(widget
) );
542 case VIK_LAYER_WIDGET_HSCALE
:
543 if ( param
->type
== VIK_LAYER_PARAM_UINT
)
544 rv
.u
= (guint32
) gtk_range_get_value ( GTK_RANGE(widget
) );
545 else if ( param
->type
== VIK_LAYER_PARAM_INT
)
546 rv
.i
= (gint32
) gtk_range_get_value ( GTK_RANGE(widget
) );
548 rv
.d
= gtk_range_get_value ( GTK_RANGE(widget
) );
554 /* false if cancel, true if OK */
555 /* some would claim this wasn't written to be human-readable. */
556 static gboolean
layer_properties_factory ( VikLayer
*vl
, gpointer vp
)
558 VikLayerParam
*params
= vik_layer_interfaces
[vl
->type
]->params
;
559 guint16 params_count
= vik_layer_interfaces
[vl
->type
]->params_count
;
560 guint16 i
, j
, widget_count
= 0;
561 gboolean must_redraw
= FALSE
;
564 return TRUE
; /* no params == no options, so all is good */
566 for ( i
= 0; i
< params_count
; i
++ )
567 if ( params
[i
].group
!= VIK_LAYER_NOT_IN_PROPERTIES
)
570 if ( widget_count
== 0)
574 /* create widgets and titles; place in table */
575 GtkWidget
*dialog
= gtk_dialog_new_with_buttons ( "Layer Properties",
576 VIK_GTK_WINDOW_FROM_WIDGET(vp
),
577 GTK_DIALOG_MODAL
| GTK_DIALOG_DESTROY_WITH_PARENT
,
578 GTK_STOCK_CANCEL
, GTK_RESPONSE_REJECT
,
579 GTK_STOCK_OK
, GTK_RESPONSE_ACCEPT
, NULL
);
582 gchar
**groups
= vik_layer_interfaces
[vl
->type
]->params_groups
;
583 guint8 groups_count
= vik_layer_interfaces
[vl
->type
]->params_groups_count
;
585 GtkWidget
*table
= NULL
;
586 GtkWidget
**tables
= NULL
; /* for more than one group */
588 GtkWidget
*notebook
= NULL
;
589 GtkWidget
**widgets
= g_malloc ( sizeof(GtkWidget
*) * widget_count
);
591 if ( groups
&& groups_count
)
593 guint8 current_group
;
594 guint16 tab_widget_count
;
595 notebook
= gtk_notebook_new ();
596 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog
)->vbox
), notebook
, FALSE
, FALSE
, 0);
597 tables
= g_malloc ( sizeof(GtkWidget
*) * groups_count
);
598 for ( current_group
= 0; current_group
< groups_count
; current_group
++ )
600 tab_widget_count
= 0;
601 for ( j
= 0; j
< params_count
; j
++ )
602 if ( params
[j
].group
== current_group
)
605 if ( tab_widget_count
)
607 tables
[current_group
] = gtk_table_new ( tab_widget_count
, 1, FALSE
);
608 gtk_notebook_append_page ( GTK_NOTEBOOK(notebook
), tables
[current_group
], gtk_label_new(groups
[current_group
]) );
614 table
= gtk_table_new( widget_count
, 1, FALSE
);
615 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog
)->vbox
), table
, FALSE
, FALSE
, 0);
618 for ( i
= 0, j
= 0; i
< params_count
; i
++ )
620 if ( params
[i
].group
!= VIK_LAYER_NOT_IN_PROPERTIES
)
623 table
= tables
[MAX(0, params
[i
].group
)]; /* round up NOT_IN_GROUP, that's not reasonable here */
625 widgets
[j
] = properties_widget_new_widget ( &(params
[i
]),
626 vik_layer_interfaces
[vl
->type
]->get_param ( vl
, i
) );
628 g_assert ( widgets
[j
] != NULL
);
630 gtk_table_attach ( GTK_TABLE(table
), gtk_label_new(params
[i
].title
), 0, 1, j
, j
+1, 0, 0, 0, 0 );
631 gtk_table_attach ( GTK_TABLE(table
), widgets
[j
], 1, 2, j
, j
+1, GTK_EXPAND
| GTK_FILL
, 0, 2, 2 );
636 gtk_widget_show_all ( dialog
);
638 resp
= gtk_dialog_run (GTK_DIALOG (dialog
));
639 if ( resp
== GTK_RESPONSE_ACCEPT
)
641 for ( i
= 0, j
= 0; i
< params_count
; i
++ )
643 if ( params
[i
].group
!= VIK_LAYER_NOT_IN_PROPERTIES
)
645 if ( vik_layer_interfaces
[vl
->type
]->set_param ( vl
, i
,
646 properties_widget_get_value ( widgets
[j
], &(params
[i
]) ), vp
) )
651 vik_layer_post_read ( vl
, vp
); /* update any gc's */
653 gtk_widget_destroy ( dialog
); /* hide before redrawing. */
657 vik_layer_emit_update ( vl
); /* if this is a new layer, it won't redraw twice because no on'es listening to this signal. */
658 return TRUE
; /* user clicked OK */
663 gtk_widget_destroy ( dialog
);