]> git.street.me.uk Git - andy/viking.git/blob - src/viklayer.c
Fix stdout/stderr variable usage.
[andy/viking.git] / src / viklayer.c
1 /*
2  * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
3  *
4  * Copyright (C) 2005, Alex Foobarian <foobarian@gmail.com>
5  * Copyright (C) 2003-2007, Evan Battaglia <gtoevan@gmx.net>
6  * Copyright (C) 2013, Rob Norris <rw_norris@hotmail.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <glib/gi18n.h>
29
30 #include "viking.h"
31 #include <string.h>
32 #include <stdlib.h>
33 #include "viklayer_defaults.h"
34
35 /* functions common to all layers. */
36 /* TODO longone: rename interface free -> finalize */
37
38 extern VikLayerInterface vik_aggregate_layer_interface;
39 extern VikLayerInterface vik_trw_layer_interface;
40 extern VikLayerInterface vik_maps_layer_interface;
41 extern VikLayerInterface vik_coord_layer_interface;
42 extern VikLayerInterface vik_georef_layer_interface;
43 extern VikLayerInterface vik_gps_layer_interface;
44 extern VikLayerInterface vik_dem_layer_interface;
45
46 enum {
47   VL_UPDATE_SIGNAL,
48   VL_LAST_SIGNAL
49 };
50 static guint layer_signals[VL_LAST_SIGNAL] = { 0 };
51
52 static GObjectClass *parent_class;
53
54 static void vik_layer_finalize ( VikLayer *vl );
55 static gboolean vik_layer_properties_factory ( VikLayer *vl, VikViewport *vp );
56 static gboolean layer_defaults_register ( VikLayerTypeEnum type );
57
58 G_DEFINE_TYPE (VikLayer, vik_layer, G_TYPE_OBJECT)
59
60 static void vik_layer_class_init (VikLayerClass *klass)
61 {
62   GObjectClass *object_class;
63
64   object_class = G_OBJECT_CLASS (klass);
65
66   object_class->finalize = (GObjectFinalizeFunc) vik_layer_finalize;
67
68   parent_class = g_type_class_peek_parent (klass);
69
70   layer_signals[VL_UPDATE_SIGNAL] = g_signal_new ( "update", G_TYPE_FROM_CLASS (klass),
71       G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (VikLayerClass, update), NULL, NULL, 
72       g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
73
74   // Register all parameter defaults, early in the start up sequence
75   VikLayerTypeEnum layer;
76   for ( layer = 0; layer < VIK_LAYER_NUM_TYPES; layer++ )
77     // ATM ignore the returned value
78     layer_defaults_register ( layer );
79 }
80
81 /**
82  * Invoke the actual drawing via signal method
83  */
84 static gboolean idle_draw ( VikLayer *vl )
85 {
86   g_signal_emit ( G_OBJECT(vl), layer_signals[VL_UPDATE_SIGNAL], 0 );
87   return FALSE; // Nothing else to do
88 }
89
90 /**
91  * Draw specified layer
92  */
93 void vik_layer_emit_update ( VikLayer *vl )
94 {
95   if ( vl->visible && vl->realized ) {
96     vik_window_set_redraw_trigger(vl);
97
98     // Only ever draw when there is time to do so
99     if ( g_thread_self() != vik_window_get_thread (VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vl))) )
100       // Drawing requested from another (background) thread, so handle via the gdk thread method
101       gdk_threads_add_idle ( (GSourceFunc) idle_draw, vl );
102     else
103       g_idle_add ( (GSourceFunc) idle_draw, vl );
104   }
105 }
106
107 /**
108  * should only be done by VikLayersPanel (hence never used from the background)
109  * need to redraw and record trigger when we make a layer invisible.
110  */
111 void vik_layer_emit_update_although_invisible ( VikLayer *vl )
112 {
113   vik_window_set_redraw_trigger(vl);
114   g_idle_add ( (GSourceFunc) idle_draw, vl );
115 }
116
117 /* doesn't set the trigger. should be done by aggregate layer when child emits update. */
118 void vik_layer_emit_update_secondary ( VikLayer *vl )
119 {
120   if ( vl->visible )
121     // TODO: this can used from the background - eg in acquire
122     //       so will need to flow background update status through too
123     g_idle_add ( (GSourceFunc) idle_draw, vl );
124 }
125
126 static VikLayerInterface *vik_layer_interfaces[VIK_LAYER_NUM_TYPES] = {
127   &vik_aggregate_layer_interface,
128   &vik_trw_layer_interface,
129   &vik_coord_layer_interface,
130   &vik_georef_layer_interface,
131   &vik_gps_layer_interface,
132   &vik_maps_layer_interface,
133   &vik_dem_layer_interface,
134 };
135
136 VikLayerInterface *vik_layer_get_interface ( VikLayerTypeEnum type )
137 {
138   g_assert ( type < VIK_LAYER_NUM_TYPES );
139   return vik_layer_interfaces[type];
140 }
141
142 /**
143  * Store default values for this layer
144  *
145  * Returns whether any parameters where registered
146  */
147 static gboolean layer_defaults_register ( VikLayerTypeEnum type )
148 {
149   // See if any parameters
150   VikLayerParam *params = vik_layer_interfaces[type]->params;
151   if ( ! params )
152     return FALSE;
153
154   gboolean answer = FALSE; // Incase all parameters are 'not in properties'
155   guint16 params_count = vik_layer_interfaces[type]->params_count;
156   guint16 i;
157   // Process each parameter
158   for ( i = 0; i < params_count; i++ ) {
159     if ( params[i].group != VIK_LAYER_NOT_IN_PROPERTIES ) {
160       if ( params[i].default_value ) {
161         VikLayerParamData paramd = params[i].default_value();
162         a_layer_defaults_register ( &params[i], paramd, vik_layer_interfaces[type]->fixed_layer_name );
163         answer = TRUE;
164       }
165     }
166   }
167
168   return answer;
169 }
170
171 static void vik_layer_init ( VikLayer *vl )
172 {
173   vl->visible = TRUE;
174   vl->name = NULL;
175   vl->realized = FALSE;
176 }
177
178 void vik_layer_set_type ( VikLayer *vl, VikLayerTypeEnum type )
179 {
180   vl->type = type;
181 }
182
183 /* frees old name */
184 void vik_layer_rename ( VikLayer *l, const gchar *new_name )
185 {
186   g_assert ( l != NULL );
187   g_assert ( new_name != NULL );
188   g_free ( l->name );
189   l->name = g_strdup ( new_name );
190 }
191
192 void vik_layer_rename_no_copy ( VikLayer *l, gchar *new_name )
193 {
194   g_assert ( l != NULL );
195   g_assert ( new_name != NULL );
196   g_free ( l->name );
197   l->name = new_name;
198 }
199
200 const gchar *vik_layer_get_name ( VikLayer *l )
201 {
202   g_assert ( l != NULL);
203   return l->name;
204 }
205
206 VikLayer *vik_layer_create ( VikLayerTypeEnum type, VikViewport *vp, gboolean interactive )
207 {
208   VikLayer *new_layer = NULL;
209   g_assert ( type < VIK_LAYER_NUM_TYPES );
210
211   new_layer = vik_layer_interfaces[type]->create ( vp );
212
213   g_assert ( new_layer != NULL );
214
215   if ( interactive )
216   {
217     if ( vik_layer_properties ( new_layer, vp ) )
218       /* We translate the name here */
219       /* in order to avoid translating name set by user */
220       vik_layer_rename ( VIK_LAYER(new_layer), _(vik_layer_interfaces[type]->name) );
221     else
222     {
223       g_object_unref ( G_OBJECT(new_layer) ); /* cancel that */
224       new_layer = NULL;
225     }
226   }
227   return new_layer;
228 }
229
230 /* returns TRUE if OK was pressed */
231 gboolean vik_layer_properties ( VikLayer *layer, VikViewport *vp )
232 {
233   if ( vik_layer_interfaces[layer->type]->properties )
234     return vik_layer_interfaces[layer->type]->properties ( layer, vp );
235   return vik_layer_properties_factory ( layer, vp );
236 }
237
238 void vik_layer_draw ( VikLayer *l, VikViewport *vp )
239 {
240   if ( l->visible )
241     if ( vik_layer_interfaces[l->type]->draw )
242       vik_layer_interfaces[l->type]->draw ( l, vp );
243 }
244
245 void vik_layer_change_coord_mode ( VikLayer *l, VikCoordMode mode )
246 {
247   if ( vik_layer_interfaces[l->type]->change_coord_mode )
248     vik_layer_interfaces[l->type]->change_coord_mode ( l, mode );
249 }
250
251 typedef struct {
252   VikLayerTypeEnum layer_type;
253   gint len;
254   guint8 data[0];
255 } header_t;
256
257 void vik_layer_marshall ( VikLayer *vl, guint8 **data, gint *len )
258 {
259   header_t *header;
260   if ( vl && vik_layer_interfaces[vl->type]->marshall ) {
261     vik_layer_interfaces[vl->type]->marshall ( vl, data, len );
262     if (*data) {
263       header = g_malloc(*len + sizeof(*header));
264       header->layer_type = vl->type;
265       header->len = *len;
266       memcpy(header->data, *data, *len);
267       g_free(*data);
268       *data = (guint8 *)header;
269       *len = *len + sizeof(*header);
270     }
271   } else {
272     *data = NULL;
273   }
274 }
275
276 void vik_layer_marshall_params ( VikLayer *vl, guint8 **data, gint *datalen )
277 {
278   VikLayerParam *params = vik_layer_get_interface(vl->type)->params;
279   VikLayerFuncGetParam get_param = vik_layer_get_interface(vl->type)->get_param;
280   GByteArray* b = g_byte_array_new ();
281   gint len;
282
283 #define vlm_append(obj, sz)     \
284   len = (sz);                   \
285   g_byte_array_append ( b, (guint8 *)&len, sizeof(len) );       \
286   g_byte_array_append ( b, (guint8 *)(obj), len );
287
288   vlm_append(vl->name, strlen(vl->name));
289
290   if ( params && get_param )
291   {
292     VikLayerParamData d;
293     guint16 i, params_count = vik_layer_get_interface(vl->type)->params_count;
294     for ( i = 0; i < params_count; i++ )
295     {
296       g_debug("%s: %s", __FUNCTION__, params[i].name);
297       d = get_param(vl, i, FALSE);
298       switch ( params[i].type )
299       {
300       case VIK_LAYER_PARAM_STRING:
301         // Remember need braces as these are macro calls, not single statement functions!
302         if ( d.s ) {
303           vlm_append(d.s, strlen(d.s));
304         }
305         else {
306           // Need to insert empty string otherwise the unmarshall will get confused
307           vlm_append("", 0);
308         }
309         break;
310       /* print out the string list in the array */
311       case VIK_LAYER_PARAM_STRING_LIST: {
312         GList *list = d.sl;
313         
314         /* write length of list (# of strings) */
315         gint listlen = g_list_length ( list );
316         g_byte_array_append ( b, (guint8 *)&listlen, sizeof(listlen) );
317
318         /* write each string */
319         while ( list ) {
320           gchar *s = (gchar *) list->data;
321           vlm_append(s, strlen(s));
322           list = list->next;
323         }
324
325         break;
326       }
327       default:
328         vlm_append(&d, sizeof(d));
329         break;
330       }
331     }
332   }
333   
334   *data = b->data;
335   *datalen = b->len;
336   g_byte_array_free ( b, FALSE );
337
338 #undef vlm_append
339 }
340
341 void vik_layer_unmarshall_params ( VikLayer *vl, guint8 *data, gint datalen, VikViewport *vvp )
342 {
343   VikLayerParam *params = vik_layer_get_interface(vl->type)->params;
344   VikLayerFuncSetParam set_param = vik_layer_get_interface(vl->type)->set_param;
345   gchar *s;
346   guint8 *b = (guint8 *)data;
347   
348 #define vlm_size (*(gint *)b)
349 #define vlm_read(obj)                           \
350   memcpy((obj), b+sizeof(gint), vlm_size);      \
351   b += sizeof(gint) + vlm_size;
352   
353   s = g_malloc(vlm_size + 1);
354   s[vlm_size]=0;
355   vlm_read(s);
356   
357   vik_layer_rename(vl, s);
358   
359   g_free(s);
360
361   if ( params && set_param )
362   {
363     VikLayerParamData d;
364     guint16 i, params_count = vik_layer_get_interface(vl->type)->params_count;
365     for ( i = 0; i < params_count; i++ )
366     {
367       g_debug("%s: %s", __FUNCTION__, params[i].name);
368       switch ( params[i].type )
369       {
370       case VIK_LAYER_PARAM_STRING: 
371         s = g_malloc(vlm_size + 1);
372         s[vlm_size]=0;
373         vlm_read(s);
374         d.s = s;
375         set_param(vl, i, d, vvp, FALSE);
376         g_free(s);
377         break;
378       case VIK_LAYER_PARAM_STRING_LIST:  {
379         gint listlen = vlm_size, j;
380         GList *list = NULL;
381         b += sizeof(gint); /* skip listlen */;
382
383         for ( j = 0; j < listlen; j++ ) {
384           /* get a string */
385           s = g_malloc(vlm_size + 1);
386           s[vlm_size]=0;
387           vlm_read(s);
388           list = g_list_append ( list, s );
389         }
390         d.sl = list;
391         set_param(vl, i, d, vvp, FALSE);
392         /* don't free -- string list is responsibility of the layer */
393
394         break;
395         }
396       default:
397         vlm_read(&d);
398         set_param(vl, i, d, vvp, FALSE);
399         break;
400       }
401     }
402   }
403 }
404
405 VikLayer *vik_layer_unmarshall ( guint8 *data, gint len, VikViewport *vvp )
406 {
407   header_t *header;
408
409   header = (header_t *)data;
410   
411   if ( vik_layer_interfaces[header->layer_type]->unmarshall ) {
412     return vik_layer_interfaces[header->layer_type]->unmarshall ( header->data, header->len, vvp );
413   } else {
414     return NULL;
415   }
416 }
417
418 static void vik_layer_finalize ( VikLayer *vl )
419 {
420   g_assert ( vl != NULL );
421   if ( vik_layer_interfaces[vl->type]->free )
422     vik_layer_interfaces[vl->type]->free ( vl );
423   if ( vl->name )
424     g_free ( vl->name );
425   G_OBJECT_CLASS(parent_class)->finalize(G_OBJECT(vl));
426 }
427
428 /* sublayer switching */
429 gboolean vik_layer_sublayer_toggle_visible ( VikLayer *l, gint subtype, gpointer sublayer )
430 {
431   if ( vik_layer_interfaces[l->type]->sublayer_toggle_visible )
432     return vik_layer_interfaces[l->type]->sublayer_toggle_visible ( l, subtype, sublayer );
433   return TRUE; /* if unknown, will always be visible */
434 }
435
436 gboolean vik_layer_selected ( VikLayer *l, gint subtype, gpointer sublayer, gint type, gpointer vlp )
437 {
438   if ( vik_layer_interfaces[l->type]->layer_selected )
439     return vik_layer_interfaces[l->type]->layer_selected ( l, subtype, sublayer, type, vlp );
440   /* Since no 'layer_selected' function explicitly turn off here */
441   return vik_window_clear_highlight ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(l) );
442 }
443
444 void vik_layer_realize ( VikLayer *l, VikTreeview *vt, GtkTreeIter *layer_iter )
445 {
446   l->vt = vt;
447   l->iter = *layer_iter;
448   l->realized = TRUE;
449   if ( vik_layer_interfaces[l->type]->realize )
450     vik_layer_interfaces[l->type]->realize ( l, vt, layer_iter );
451 }
452
453 void vik_layer_set_menu_items_selection(VikLayer *l, guint16 selection)
454 {
455   if ( vik_layer_interfaces[l->type]->set_menu_selection )
456     vik_layer_interfaces[l->type]->set_menu_selection ( l, selection );
457 }
458
459 guint16 vik_layer_get_menu_items_selection(VikLayer *l)
460 {
461   if ( vik_layer_interfaces[l->type]->get_menu_selection )
462     return(vik_layer_interfaces[l->type]->get_menu_selection (l));
463   else
464     return(vik_layer_interfaces[l->type]->menu_items_selection);
465 }
466
467 void vik_layer_add_menu_items ( VikLayer *l, GtkMenu *menu, gpointer vlp )
468 {
469   if ( vik_layer_interfaces[l->type]->add_menu_items )
470     vik_layer_interfaces[l->type]->add_menu_items ( l, menu, vlp );
471 }
472
473 gboolean vik_layer_sublayer_add_menu_items ( VikLayer *l, GtkMenu *menu, gpointer vlp, gint subtype, gpointer sublayer, GtkTreeIter *iter, VikViewport *vvp )
474 {
475   if ( vik_layer_interfaces[l->type]->sublayer_add_menu_items )
476     return vik_layer_interfaces[l->type]->sublayer_add_menu_items ( l, menu, vlp, subtype, sublayer, iter, vvp );
477   return FALSE;
478 }
479
480
481 const gchar *vik_layer_sublayer_rename_request ( VikLayer *l, const gchar *newname, gpointer vlp, gint subtype, gpointer sublayer, GtkTreeIter *iter )
482 {
483   if ( vik_layer_interfaces[l->type]->sublayer_rename_request )
484     return vik_layer_interfaces[l->type]->sublayer_rename_request ( l, newname, vlp, subtype, sublayer, iter );
485   return NULL;
486 }
487
488 const gchar* vik_layer_sublayer_tooltip ( VikLayer *l, gint subtype, gpointer sublayer )
489 {
490   if ( vik_layer_interfaces[l->type]->sublayer_tooltip )
491     return vik_layer_interfaces[l->type]->sublayer_tooltip ( l, subtype, sublayer );
492   return NULL;
493 }
494
495 const gchar* vik_layer_layer_tooltip ( VikLayer *l )
496 {
497   if ( vik_layer_interfaces[l->type]->layer_tooltip )
498     return vik_layer_interfaces[l->type]->layer_tooltip ( l );
499   return NULL;
500 }
501
502 GdkPixbuf *vik_layer_load_icon ( VikLayerTypeEnum type )
503 {
504   g_assert ( type < VIK_LAYER_NUM_TYPES );
505   if ( vik_layer_interfaces[type]->icon )
506     return gdk_pixbuf_from_pixdata ( vik_layer_interfaces[type]->icon, FALSE, NULL );
507   return NULL;
508 }
509
510 gboolean vik_layer_set_param ( VikLayer *layer, guint16 id, VikLayerParamData data, gpointer vp, gboolean is_file_operation )
511 {
512   if ( vik_layer_interfaces[layer->type]->set_param )
513     return vik_layer_interfaces[layer->type]->set_param ( layer, id, data, vp, is_file_operation );
514   return FALSE;
515 }
516
517 void vik_layer_post_read ( VikLayer *layer, VikViewport *vp, gboolean from_file )
518 {
519   if ( vik_layer_interfaces[layer->type]->post_read )
520     vik_layer_interfaces[layer->type]->post_read ( layer, vp, from_file );
521 }
522
523 static gboolean vik_layer_properties_factory ( VikLayer *vl, VikViewport *vp )
524 {
525   switch ( a_uibuilder_properties_factory ( _("Layer Properties"),
526                                             VIK_GTK_WINDOW_FROM_WIDGET(vp),
527                                             vik_layer_interfaces[vl->type]->params,
528                                             vik_layer_interfaces[vl->type]->params_count,
529                                             vik_layer_interfaces[vl->type]->params_groups,
530                                             vik_layer_interfaces[vl->type]->params_groups_count,
531                                             (gpointer) vik_layer_interfaces[vl->type]->set_param, 
532                                             vl, 
533                                             vp,
534                                             (gpointer) vik_layer_interfaces[vl->type]->get_param, 
535                                             vl,
536                                             (gpointer) vik_layer_interfaces[vl->type]->change_param ) ) {
537     case 0:
538     case 3:
539       return FALSE;
540       /* redraw (?) */
541     case 2:
542       vik_layer_post_read ( vl, vp, FALSE ); /* update any gc's */
543     default:
544       return TRUE;
545   }
546 }
547
548 VikLayerTypeEnum vik_layer_type_from_string ( const gchar *str )
549 {
550   VikLayerTypeEnum i;
551   for ( i = 0; i < VIK_LAYER_NUM_TYPES; i++ )
552     if ( strcasecmp ( str, vik_layer_get_interface(i)->fixed_layer_name ) == 0 )
553       return i;
554   return VIK_LAYER_NUM_TYPES;
555 }
556
557 void vik_layer_typed_param_data_free ( gpointer gp )
558 {
559   VikLayerTypedParamData *val = (VikLayerTypedParamData *)gp;
560   switch ( val->type ) {
561     case VIK_LAYER_PARAM_STRING:
562       if ( val->data.s )
563         g_free ( (gpointer)val->data.s );
564       break;
565     /* TODO: APPLICABLE TO US? NOTE: string layer works auniquely: data.sl should NOT be free'd when
566      * the internals call get_param -- i.e. it should be managed w/in the layer.
567      * The value passed by the internals into set_param should also be managed
568      * by the layer -- i.e. free'd by the layer.
569      */
570     case VIK_LAYER_PARAM_STRING_LIST:
571       g_warning ("Param strings not implemented"); //fake it
572       break;
573     default:
574       break;
575   }
576   g_free ( val );
577 }
578
579 VikLayerTypedParamData *vik_layer_typed_param_data_copy_from_data (VikLayerParamType type, VikLayerParamData val) {
580   VikLayerTypedParamData *newval = g_new(VikLayerTypedParamData,1);
581   newval->data = val;
582   newval->type = type;
583   switch ( newval->type ) {
584     case VIK_LAYER_PARAM_STRING: {
585       gchar *s = g_strdup(newval->data.s);
586       newval->data.s = s;
587       break;
588     }
589     /* TODO: APPLICABLE TO US? NOTE: string layer works auniquely: data.sl should NOT be free'd when
590      * the internals call get_param -- i.e. it should be managed w/in the layer.
591      * The value passed by the internals into set_param should also be managed
592      * by the layer -- i.e. free'd by the layer.
593      */
594     case VIK_LAYER_PARAM_STRING_LIST:
595       g_critical ( "Param strings not implemented"); //fake it
596       break;
597     default:
598       break;
599   }
600   return newval;
601 }
602
603 #define TEST_BOOLEAN(str) (! ((str)[0] == '\0' || (str)[0] == '0' || (str)[0] == 'n' || (str)[0] == 'N' || (str)[0] == 'f' || (str)[0] == 'F') )
604
605 VikLayerTypedParamData *vik_layer_data_typed_param_copy_from_string ( VikLayerParamType type, const gchar *str )
606 {
607   VikLayerTypedParamData *rv = g_new(VikLayerTypedParamData,1);
608   rv->type = type;
609   switch ( type )
610   {
611     case VIK_LAYER_PARAM_DOUBLE: rv->data.d = strtod(str, NULL); break;
612     case VIK_LAYER_PARAM_UINT: rv->data.u = strtoul(str, NULL, 10); break;
613     case VIK_LAYER_PARAM_INT: rv->data.i = strtol(str, NULL, 10); break;
614     case VIK_LAYER_PARAM_BOOLEAN: rv->data.b = TEST_BOOLEAN(str); break;
615     case VIK_LAYER_PARAM_COLOR: memset(&(rv->data.c), 0, sizeof(rv->data.c)); /* default: black */
616       gdk_color_parse ( str, &(rv->data.c) ); break;
617     /* STRING or STRING_LIST -- if STRING_LIST, just set param to add a STRING */
618     default: {
619       gchar *s = g_strdup(str);
620       rv->data.s = s;
621     }
622   }
623   return rv;
624 }
625
626
627 /**
628  * vik_layer_set_defaults:
629  *
630  * Loop around all parameters for the specified layer to call the function to get the
631  *  default value for that parameter
632  */
633 void vik_layer_set_defaults ( VikLayer *vl, VikViewport *vvp )
634 {
635   // Sneaky initialize of the viewport value here
636   vl->vvp = vvp;
637   VikLayerInterface *vli = vik_layer_get_interface ( vl->type );
638   const gchar *layer_name = vli->fixed_layer_name;
639   VikLayerParamData data;
640
641   int i;
642   for ( i = 0; i < vli->params_count; i++ ) {
643     // Ensure parameter is for use
644     if ( vli->params[i].group > VIK_LAYER_NOT_IN_PROPERTIES ) {
645       // ATM can't handle string lists
646       // only DEM files uses this currently
647       if ( vli->params[i].type != VIK_LAYER_PARAM_STRING_LIST ) {
648         data = a_layer_defaults_get ( layer_name, vli->params[i].name, vli->params[i].type );
649         vik_layer_set_param ( vl, i, data, vvp, TRUE ); // Possibly come from a file
650       }
651     }
652   }
653 }