/** * vik_layer_set_defaults: * * Loop around all parameters for the specified layer to call the function to get the * default value for that parameter */ void vik_layer_set_defaults ( VikLayer *vl, VikViewport *vvp ) { VikLayerInterface *vli = vik_layer_get_interface ( vl->type ); const gchar *layer_name = vli->fixed_layer_name; VikLayerParamData data; int i; for ( i = 0; i < vli->params_count; i++ ) { // Ensure parameter is for use if ( vli->params[i].group > VIK_LAYER_NOT_IN_PROPERTIES ) { // ATM can't handle string lists // only DEM files uses this currently if ( vli->params[i].type != VIK_LAYER_PARAM_STRING_LIST ) { data = a_layer_defaults_get ( layer_name, vli->params[i].name, vli->params[i].type ); vik_layer_set_param ( vl, i, data, vvp, FALSE ); } } } }
/** * Read in a Viking file and return how successful the parsing was * ATM this will always work, in that even if there are parsing problems * then there will be no new values to override the defaults * * TODO flow up line number(s) / error messages of problems encountered... * */ static gboolean file_read ( VikAggregateLayer *top, FILE *f, const gchar *dirpath, VikViewport *vp ) { Stack *stack; struct LatLon ll = { 0.0, 0.0 }; gchar buffer[4096]; gchar *line; guint16 len; long line_num = 0; VikLayerParam *params = NULL; /* for current layer, so we don't have to keep on looking up interface */ guint8 params_count = 0; GHashTable *string_lists = g_hash_table_new(g_direct_hash,g_direct_equal); gboolean successful_read = TRUE; push(&stack); stack->under = NULL; stack->data = (gpointer) top; while ( fgets ( buffer, 4096, f ) ) { line_num++; line = buffer; while ( *line == ' ' || *line =='\t' ) line++; if ( line[0] == '#' ) continue; len = strlen(line); if ( len > 0 && line[len-1] == '\n' ) line[--len] = '\0'; if ( len > 0 && line[len-1] == '\r' ) line[--len] = '\0'; if ( len == 0 ) continue; if ( line[0] == '~' ) { line++; len--; if ( *line == '\0' ) continue; else if ( str_starts_with ( line, "Layer ", 6, TRUE ) ) { int parent_type = VIK_LAYER(stack->data)->type; if ( ( ! stack->data ) || ((parent_type != VIK_LAYER_AGGREGATE) && (parent_type != VIK_LAYER_GPS)) ) { successful_read = FALSE; g_warning ( "Line %ld: Layer command inside non-Aggregate Layer (type %d)", line_num, parent_type ); push(&stack); /* inside INVALID layer */ stack->data = NULL; continue; } else { VikLayerTypeEnum type = vik_layer_type_from_string ( line+6 ); push(&stack); if ( type == VIK_LAYER_NUM_TYPES ) { successful_read = FALSE; g_warning ( "Line %ld: Unknown type %s", line_num, line+6 ); stack->data = NULL; } else if (parent_type == VIK_LAYER_GPS) { stack->data = (gpointer) vik_gps_layer_get_a_child(VIK_GPS_LAYER(stack->under->data)); params = vik_layer_get_interface(type)->params; params_count = vik_layer_get_interface(type)->params_count; } else { stack->data = (gpointer) vik_layer_create ( type, vp, FALSE ); params = vik_layer_get_interface(type)->params; params_count = vik_layer_get_interface(type)->params_count; } } } else if ( str_starts_with ( line, "EndLayer", 8, FALSE ) ) { if ( stack->under == NULL ) { successful_read = FALSE; g_warning ( "Line %ld: Mismatched ~EndLayer command", line_num ); } else { /* add any string lists we've accumulated */ gpointer layer_and_vp[2]; layer_and_vp[0] = stack->data; layer_and_vp[1] = vp; g_hash_table_foreach ( string_lists, (GHFunc) string_list_set_param, layer_and_vp ); g_hash_table_remove_all ( string_lists ); if ( stack->data && stack->under->data ) { if (VIK_LAYER(stack->under->data)->type == VIK_LAYER_AGGREGATE) { vik_aggregate_layer_add_layer ( VIK_AGGREGATE_LAYER(stack->under->data), VIK_LAYER(stack->data), FALSE ); vik_layer_post_read ( VIK_LAYER(stack->data), vp, TRUE ); } else if (VIK_LAYER(stack->under->data)->type == VIK_LAYER_GPS) { /* TODO: anything else needs to be done here ? */ } else { successful_read = FALSE; g_warning ( "Line %ld: EndLayer command inside non-Aggregate Layer (type %d)", line_num, VIK_LAYER(stack->data)->type ); } } pop(&stack); } } else if ( str_starts_with ( line, "LayerData", 9, FALSE ) ) { if ( stack->data && vik_layer_get_interface(VIK_LAYER(stack->data)->type)->read_file_data ) { /* must read until hits ~EndLayerData */ if ( ! vik_layer_get_interface(VIK_LAYER(stack->data)->type)->read_file_data ( VIK_LAYER(stack->data), f, dirpath ) ) successful_read = FALSE; } else { /* simply skip layer data over */ while ( fgets ( buffer, 4096, f ) ) { line_num++; line = buffer; len = strlen(line); if ( len > 0 && line[len-1] == '\n' ) line[--len] = '\0'; if ( len > 0 && line[len-1] == '\r' ) line[--len] = '\0'; if ( strcasecmp ( line, "~EndLayerData" ) == 0 ) break; } continue; } } else { successful_read = FALSE; g_warning ( "Line %ld: Unknown tilde command", line_num ); } } else { gint32 eq_pos = -1; guint16 i; if ( ! stack->data ) continue; for ( i = 0; i < len; i++ ) if ( line[i] == '=' ) eq_pos = i; if ( stack->under == NULL && eq_pos == 12 && strncasecmp ( line, "FILE_VERSION", eq_pos ) == 0) { gint version = strtol(line+13, NULL, 10); g_debug ( "%s: reading file version %d", __FUNCTION__, version ); if ( version > VIKING_FILE_VERSION ) successful_read = FALSE; // However we'll still carry and attempt to read whatever we can } else if ( stack->under == NULL && eq_pos == 4 && strncasecmp ( line, "xmpp", eq_pos ) == 0) /* "hard coded" params: global & for all layer-types */ vik_viewport_set_xmpp ( VIK_VIEWPORT(vp), strtod ( line+5, NULL ) ); else if ( stack->under == NULL && eq_pos == 4 && strncasecmp ( line, "ympp", eq_pos ) == 0) vik_viewport_set_ympp ( VIK_VIEWPORT(vp), strtod ( line+5, NULL ) ); else if ( stack->under == NULL && eq_pos == 3 && strncasecmp ( line, "lat", eq_pos ) == 0 ) ll.lat = strtod ( line+4, NULL ); else if ( stack->under == NULL && eq_pos == 3 && strncasecmp ( line, "lon", eq_pos ) == 0 ) ll.lon = strtod ( line+4, NULL ); else if ( stack->under == NULL && eq_pos == 4 && strncasecmp ( line, "mode", eq_pos ) == 0 && strcasecmp ( line+5, "utm" ) == 0) vik_viewport_set_drawmode ( VIK_VIEWPORT(vp), VIK_VIEWPORT_DRAWMODE_UTM); else if ( stack->under == NULL && eq_pos == 4 && strncasecmp ( line, "mode", eq_pos ) == 0 && strcasecmp ( line+5, "expedia" ) == 0) vik_viewport_set_drawmode ( VIK_VIEWPORT(vp), VIK_VIEWPORT_DRAWMODE_EXPEDIA ); else if ( stack->under == NULL && eq_pos == 4 && strncasecmp ( line, "mode", eq_pos ) == 0 && strcasecmp ( line+5, "google" ) == 0) { successful_read = FALSE; g_warning ( _("Draw mode '%s' no more supported"), "google" ); } else if ( stack->under == NULL && eq_pos == 4 && strncasecmp ( line, "mode", eq_pos ) == 0 && strcasecmp ( line+5, "kh" ) == 0) { successful_read = FALSE; g_warning ( _("Draw mode '%s' no more supported"), "kh" ); } else if ( stack->under == NULL && eq_pos == 4 && strncasecmp ( line, "mode", eq_pos ) == 0 && strcasecmp ( line+5, "mercator" ) == 0) vik_viewport_set_drawmode ( VIK_VIEWPORT(vp), VIK_VIEWPORT_DRAWMODE_MERCATOR ); else if ( stack->under == NULL && eq_pos == 4 && strncasecmp ( line, "mode", eq_pos ) == 0 && strcasecmp ( line+5, "latlon" ) == 0) vik_viewport_set_drawmode ( VIK_VIEWPORT(vp), VIK_VIEWPORT_DRAWMODE_LATLON ); else if ( stack->under == NULL && eq_pos == 5 && strncasecmp ( line, "color", eq_pos ) == 0 ) vik_viewport_set_background_color ( VIK_VIEWPORT(vp), line+6 ); else if ( stack->under == NULL && eq_pos == 14 && strncasecmp ( line, "highlightcolor", eq_pos ) == 0 ) vik_viewport_set_highlight_color ( VIK_VIEWPORT(vp), line+15 ); else if ( stack->under == NULL && eq_pos == 9 && strncasecmp ( line, "drawscale", eq_pos ) == 0 ) vik_viewport_set_draw_scale ( VIK_VIEWPORT(vp), TEST_BOOLEAN(line+10) ); else if ( stack->under == NULL && eq_pos == 14 && strncasecmp ( line, "drawcentermark", eq_pos ) == 0 ) vik_viewport_set_draw_centermark ( VIK_VIEWPORT(vp), TEST_BOOLEAN(line+15) ); else if ( stack->under == NULL && eq_pos == 13 && strncasecmp ( line, "drawhighlight", eq_pos ) == 0 ) vik_viewport_set_draw_highlight ( VIK_VIEWPORT(vp), TEST_BOOLEAN(line+14) ); else if ( stack->under && eq_pos == 4 && strncasecmp ( line, "name", eq_pos ) == 0 ) vik_layer_rename ( VIK_LAYER(stack->data), line+5 ); else if ( eq_pos == 7 && strncasecmp ( line, "visible", eq_pos ) == 0 ) VIK_LAYER(stack->data)->visible = TEST_BOOLEAN(line+8); else if ( eq_pos != -1 && stack->under ) { gboolean found_match = FALSE; /* go thru layer params. if len == eq_pos && starts_with jazz, set it. */ /* also got to check for name and visible. */ if ( ! params ) { successful_read = FALSE; g_warning ( "Line %ld: No options for this kind of layer", line_num ); continue; } for ( i = 0; i < params_count; i++ ) if ( strlen(params[i].name) == eq_pos && strncasecmp ( line, params[i].name, eq_pos ) == 0 ) { VikLayerParamData x; line += eq_pos+1; if ( params[i].type == VIK_LAYER_PARAM_STRING_LIST ) { GList *l = g_list_append ( g_hash_table_lookup ( string_lists, GINT_TO_POINTER ((gint) i) ), g_strdup(line) ); g_hash_table_replace ( string_lists, GINT_TO_POINTER ((gint)i), l ); /* add the value to a list, possibly making a new list. * this will be passed to the layer when we read an ~EndLayer */ } else { switch ( params[i].type ) { case VIK_LAYER_PARAM_DOUBLE: x.d = strtod(line, NULL); break; case VIK_LAYER_PARAM_UINT: x.u = strtoul(line, NULL, 10); break; case VIK_LAYER_PARAM_INT: x.i = strtol(line, NULL, 10); break; case VIK_LAYER_PARAM_BOOLEAN: x.b = TEST_BOOLEAN(line); break; case VIK_LAYER_PARAM_COLOR: memset(&(x.c), 0, sizeof(x.c)); /* default: black */ gdk_color_parse ( line, &(x.c) ); break; /* STRING or STRING_LIST -- if STRING_LIST, just set param to add a STRING */ default: x.s = line; } vik_layer_set_param ( VIK_LAYER(stack->data), i, x, vp, TRUE ); } found_match = TRUE; break; } if ( ! found_match ) { // ATM don't flow up this issue because at least one internal parameter has changed from version 1.3 // and don't what to worry users about raising such issues // TODO Maybe hold old values here - compare the line value against them and if a match // generate a different style of message in the GUI... // successful_read = FALSE; g_warning ( "Line %ld: Unknown parameter. Line:\n%s", line_num, line ); } } else { successful_read = FALSE; g_warning ( "Line %ld: Invalid parameter or parameter outside of layer.", line_num ); } } /* could be: [Layer Type=Bla] [EndLayer] [LayerData] name=this #comment */ } while ( stack ) { if ( stack->under && stack->under->data && stack->data ) { vik_aggregate_layer_add_layer ( VIK_AGGREGATE_LAYER(stack->under->data), VIK_LAYER(stack->data), FALSE ); vik_layer_post_read ( VIK_LAYER(stack->data), vp, TRUE ); } pop(&stack); } if ( ll.lat != 0.0 || ll.lon != 0.0 ) vik_viewport_set_center_latlon ( VIK_VIEWPORT(vp), &ll, TRUE ); if ( ( ! VIK_LAYER(top)->visible ) && VIK_LAYER(top)->realized ) vik_treeview_item_set_visible ( VIK_LAYER(top)->vt, &(VIK_LAYER(top)->iter), FALSE ); /* delete anything we've forgotten about -- should only happen when file ends before an EndLayer */ g_hash_table_foreach ( string_lists, string_list_delete, NULL ); g_hash_table_destroy ( string_lists ); return successful_read; }
static void string_list_set_param (gint i, GList *list, gpointer *layer_and_vp) { VikLayerParamData x; x.sl = list; vik_layer_set_param ( VIK_LAYER(layer_and_vp[0]), i, x, layer_and_vp[1], TRUE ); }