static void use_internal_defaults_if_missing_default ( VikLayerTypeEnum type ) { VikLayerParam *params = vik_layer_get_interface(type)->params; if ( ! params ) return; guint16 params_count = vik_layer_get_interface(type)->params_count; guint16 i; // Process each parameter for ( i = 0; i < params_count; i++ ) { if ( params[i].group != VIK_LAYER_NOT_IN_PROPERTIES ) { gpointer success = GINT_TO_POINTER (FALSE); // Check current default is available get_default_data_answer ( vik_layer_get_interface(type)->fixed_layer_name, params[i].name, params[i].type, success); // If no longer have a viable default if ( ! GPOINTER_TO_INT (success) ) { // Reset value if ( params[i].default_value ) { VikLayerParamData paramd = params[i].default_value(); set_default_data ( paramd, vik_layer_get_interface(type)->fixed_layer_name, params[i].name, params[i].type ); } } } } }
static void write_layer_params_and_data ( VikLayer *l, FILE *f ) { VikLayerParam *params = vik_layer_get_interface(l->type)->params; VikLayerFuncGetParam get_param = vik_layer_get_interface(l->type)->get_param; fprintf ( f, "name=%s\n", l->name ? l->name : "" ); if ( !l->visible ) fprintf ( f, "visible=f\n" ); if ( params && get_param ) { VikLayerParamData data; guint16 i, params_count = vik_layer_get_interface(l->type)->params_count; for ( i = 0; i < params_count; i++ ) { data = get_param(l, i, TRUE); file_write_layer_param(f, params[i].name, params[i].type, data); } } if ( vik_layer_get_interface(l->type)->write_file_data ) { fprintf ( f, "\n\n~LayerData\n" ); vik_layer_get_interface(l->type)->write_file_data ( l, f ); fprintf ( f, "~EndLayerData\n" ); } /* foreach param: write param, and get_value, etc. then run layer data, and that's it. */ }
void vik_layer_marshall_params ( VikLayer *vl, guint8 **data, gint *datalen ) { VikLayerParam *params = vik_layer_get_interface(vl->type)->params; VikLayerFuncGetParam get_param = vik_layer_get_interface(vl->type)->get_param; GByteArray* b = g_byte_array_new (); gint len; #define vlm_append(obj, sz) \ len = (sz); \ g_byte_array_append ( b, (guint8 *)&len, sizeof(len) ); \ g_byte_array_append ( b, (guint8 *)(obj), len ); vlm_append(vl->name, strlen(vl->name)); if ( params && get_param ) { VikLayerParamData d; guint16 i, params_count = vik_layer_get_interface(vl->type)->params_count; for ( i = 0; i < params_count; i++ ) { g_debug("%s: %s", __FUNCTION__, params[i].name); d = get_param(vl, i, FALSE); switch ( params[i].type ) { case VIK_LAYER_PARAM_STRING: vlm_append(d.s, strlen(d.s)); break; /* print out the string list in the array */ case VIK_LAYER_PARAM_STRING_LIST: { GList *list = d.sl; /* write length of list (# of strings) */ gint listlen = g_list_length ( list ); g_byte_array_append ( b, (guint8 *)&listlen, sizeof(listlen) ); /* write each string */ while ( list ) { gchar *s = (gchar *) list->data; vlm_append(s, strlen(s)); list = list->next; } break; } default: vlm_append(&d, sizeof(d)); break; } } } *data = b->data; *datalen = b->len; g_byte_array_free ( b, FALSE ); #undef vlm_append }
VikLayerTypeEnum vik_layer_type_from_string ( const gchar *str ) { VikLayerTypeEnum i; for ( i = 0; i < VIK_LAYER_NUM_TYPES; i++ ) if ( strcasecmp ( str, vik_layer_get_interface(i)->fixed_layer_name ) == 0 ) return i; return VIK_LAYER_NUM_TYPES; }
static VikLayerParamData defaults_run_getparam ( gpointer index_ptr, guint16 i, gboolean notused2 ) { // Index is only an index into values from this layer gint index = GPOINTER_TO_INT ( index_ptr ); VikLayerParam *vlp = (VikLayerParam *)g_ptr_array_index(paramsVD,index+i); return get_default_data ( vik_layer_get_interface(vlp->layer)->fixed_layer_name, vlp->name, vlp->type ); }
static void defaults_run_setparam ( gpointer index_ptr, guint16 i, VikLayerParamData data, VikLayerParam *params ) { // Index is only an index into values from this layer gint index = GPOINTER_TO_INT ( index_ptr ); VikLayerParam *vlp = (VikLayerParam *)g_ptr_array_index(paramsVD,index+i); set_default_data ( data, vik_layer_get_interface(vlp->layer)->fixed_layer_name, vlp->name, vlp->type ); }
void vik_layers_panel_delete_selected ( VikLayersPanel *vlp ) { gint type; GtkTreeIter iter; if ( ! vik_treeview_get_selected_iter ( vlp->vt, &iter ) ) /* Nothing to do */ return; type = vik_treeview_item_get_type ( vlp->vt, &iter ); if ( type == VIK_TREEVIEW_TYPE_LAYER ) { // Get confirmation from the user if ( ! a_dialog_yes_or_no ( VIK_GTK_WINDOW_FROM_WIDGET(vlp), _("Are you sure you want to delete %s?"), vik_layer_get_name ( VIK_LAYER(vik_treeview_item_get_pointer ( vlp->vt, &iter )) ) ) ) return; VikAggregateLayer *parent = vik_treeview_item_get_parent ( vlp->vt, &iter ); if ( parent ) { /* reset trigger if trigger deleted */ if ( vik_layers_panel_get_selected ( vlp ) == vik_viewport_get_trigger ( vlp->vvp ) ) vik_viewport_set_trigger ( vlp->vvp, NULL ); if (IS_VIK_AGGREGATE_LAYER(parent)) { if ( vik_aggregate_layer_delete ( parent, &iter ) ) vik_layers_panel_emit_update ( vlp ); } } else a_dialog_info_msg ( VIK_GTK_WINDOW_FROM_WIDGET(vlp), _("You cannot delete the Top Layer.") ); } else if (type == VIK_TREEVIEW_TYPE_SUBLAYER) { VikLayer *sel = vik_layers_panel_get_selected ( vlp ); if ( vik_layer_get_interface(sel->type)->delete_item ) { gint subtype = vik_treeview_item_get_data( vlp->vt, &iter); vik_layer_get_interface(sel->type)->delete_item ( sel, subtype, vik_treeview_item_get_pointer(sel->vt, &iter) ); } } }
/* our own data type */ static void clip_receive_viking ( GtkClipboard *c, GtkSelectionData *sd, gpointer p ) { VikLayersPanel *vlp = p; vik_clipboard_t *vc; if (sd->length == -1) { g_warning ( _("paste failed") ); return; } // g_print("clip receive: target = %s, type = %s\n", gdk_atom_name(sd->target), gdk_atom_name(sd->type)); g_assert(!strcmp(gdk_atom_name(sd->target), target_table[0].target)); vc = (vik_clipboard_t *)sd->data; // g_print(" sd->data = %p, sd->length = %d, vc->len = %d\n", sd->data, sd->length, vc->len); if (sd->length != sizeof(*vc) + vc->len) { g_warning ( _("wrong clipboard data size") ); return; } if ( vc->type == VIK_CLIPBOARD_DATA_LAYER ) { VikLayer *new_layer = vik_layer_unmarshall ( vc->data, vc->len, vik_layers_panel_get_viewport(vlp) ); vik_layers_panel_add_layer ( vlp, new_layer ); } else if ( vc->type == VIK_CLIPBOARD_DATA_SUBLAYER ) { VikLayer *sel = vik_layers_panel_get_selected ( vlp ); if ( sel && sel->type == vc->layer_type) { if ( vik_layer_get_interface(vc->layer_type)->paste_item ) vik_layer_get_interface(vc->layer_type)->paste_item ( sel, vc->subtype, vc->data, vc->len); } else a_dialog_error_msg_extra ( VIK_GTK_WINDOW_FROM_WIDGET(GTK_WIDGET(vlp)), _("The clipboard contains sublayer data for %s layers. " "You must select a layer of this type to paste the clipboard data."), vik_layer_get_interface(vc->layer_type)->name ); } }
/** * a_clipboard_copy_selected: * * Make a copy of selected object and associate ourselves with the clipboard. */ void a_clipboard_copy_selected ( VikLayersPanel *vlp ) { VikLayer *sel = vik_layers_panel_get_selected ( vlp ); GtkTreeIter iter; VikClipboardDataType type; guint16 layer_type = 0; gint subtype = 0; guint8 *data = NULL; guint len; const gchar *name = NULL; if ( ! sel ) return; vik_treeview_get_selected_iter ( sel->vt, &iter ); layer_type = sel->type; if ( vik_treeview_item_get_type ( sel->vt, &iter ) == VIK_TREEVIEW_TYPE_SUBLAYER ) { type = VIK_CLIPBOARD_DATA_SUBLAYER; if ( vik_layer_get_interface(layer_type)->copy_item) { subtype = vik_treeview_item_get_data(sel->vt, &iter); vik_layer_get_interface(layer_type)->copy_item(sel, subtype, vik_treeview_item_get_pointer(sel->vt, &iter), &data, &len ); // This name is used in setting the text representation of the item on the clipboard. name = vik_treeview_item_get_name(sel->vt, &iter); } } else { gint ilen; type = VIK_CLIPBOARD_DATA_LAYER; vik_layer_marshall ( sel, &data, &ilen ); len = ilen; name = vik_layer_get_name ( vik_treeview_item_get_pointer(sel->vt, &iter) ); } if (data) { a_clipboard_copy( type, layer_type, subtype, len, name, data); } }
void vik_layers_panel_cut_selected ( VikLayersPanel *vlp ) { gint type; GtkTreeIter iter; if ( ! vik_treeview_get_selected_iter ( vlp->vt, &iter ) ) /* Nothing to do */ return; type = vik_treeview_item_get_type ( vlp->vt, &iter ); if ( type == VIK_TREEVIEW_TYPE_LAYER ) { VikAggregateLayer *parent = vik_treeview_item_get_parent ( vlp->vt, &iter ); if ( parent ) { /* reset trigger if trigger deleted */ if ( vik_layers_panel_get_selected ( vlp ) == vik_viewport_get_trigger ( vlp->vvp ) ) vik_viewport_set_trigger ( vlp->vvp, NULL ); a_clipboard_copy_selected ( vlp ); if (IS_VIK_AGGREGATE_LAYER(parent)) { if ( vik_aggregate_layer_delete ( parent, &iter ) ) vik_layers_panel_emit_update ( vlp ); } } else a_dialog_info_msg ( VIK_GTK_WINDOW_FROM_WIDGET(vlp), _("You cannot cut the Top Layer.") ); } else if (type == VIK_TREEVIEW_TYPE_SUBLAYER) { VikLayer *sel = vik_layers_panel_get_selected ( vlp ); if ( vik_layer_get_interface(sel->type)->cut_item ) { gint subtype = vik_treeview_item_get_data( vlp->vt, &iter); vik_layer_get_interface(sel->type)->cut_item ( sel, subtype, vik_treeview_item_get_pointer(sel->vt, &iter) ); } } }
/** * 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 ); } } } }
static void layers_panel_init ( VikLayersPanel *vlp ) { GtkWidget *hbox; GtkWidget *addbutton, *addimage; GtkWidget *removebutton, *removeimage; GtkWidget *upbutton, *upimage; GtkWidget *downbutton, *downimage; GtkWidget *cutbutton, *cutimage; GtkWidget *copybutton, *copyimage; GtkWidget *pastebutton, *pasteimage; GtkWidget *scrolledwindow; GtkItemFactoryEntry entry; guint i, tmp; vlp->vvp = NULL; hbox = gtk_hbox_new ( TRUE, 2 ); vlp->vt = vik_treeview_new ( ); vlp->toplayer = vik_aggregate_layer_new (); vik_layer_rename ( VIK_LAYER(vlp->toplayer), _("Top Layer")); g_signal_connect_swapped ( G_OBJECT(vlp->toplayer), "update", G_CALLBACK(vik_layers_panel_emit_update), vlp ); vik_treeview_add_layer ( vlp->vt, NULL, &(vlp->toplayer_iter), VIK_LAYER(vlp->toplayer)->name, NULL, vlp->toplayer, VIK_LAYER_AGGREGATE, VIK_LAYER_AGGREGATE ); vik_layer_realize ( VIK_LAYER(vlp->toplayer), vlp->vt, &(vlp->toplayer_iter) ); g_signal_connect_swapped ( vlp->vt, "popup_menu", G_CALLBACK(menu_popup_cb), vlp); g_signal_connect_swapped ( vlp->vt, "button_press_event", G_CALLBACK(layers_button_press_cb), vlp); g_signal_connect_swapped ( vlp->vt, "item_toggled", G_CALLBACK(layers_item_toggled), vlp); g_signal_connect_swapped ( vlp->vt, "item_edited", G_CALLBACK(layers_item_edited), vlp); g_signal_connect_swapped ( vlp->vt, "key_press_event", G_CALLBACK(layers_key_press_cb), vlp); /* Add button */ addimage = gtk_image_new_from_stock ( GTK_STOCK_ADD, GTK_ICON_SIZE_SMALL_TOOLBAR ); addbutton = gtk_button_new ( ); gtk_container_add ( GTK_CONTAINER(addbutton), addimage ); gtk_widget_set_tooltip_text ( GTK_WIDGET(addbutton), _("Add new layer")); gtk_box_pack_start ( GTK_BOX(hbox), addbutton, TRUE, TRUE, 0 ); g_signal_connect_swapped ( G_OBJECT(addbutton), "clicked", G_CALLBACK(layers_popup_cb), vlp ); /* Remove button */ removeimage = gtk_image_new_from_stock ( GTK_STOCK_REMOVE, GTK_ICON_SIZE_SMALL_TOOLBAR ); removebutton = gtk_button_new ( ); gtk_container_add ( GTK_CONTAINER(removebutton), removeimage ); gtk_widget_set_tooltip_text ( GTK_WIDGET(removebutton), _("Remove selected layer")); gtk_box_pack_start ( GTK_BOX(hbox), removebutton, TRUE, TRUE, 0 ); g_signal_connect_swapped ( G_OBJECT(removebutton), "clicked", G_CALLBACK(vik_layers_panel_delete_selected), vlp ); /* Up button */ upimage = gtk_image_new_from_stock ( GTK_STOCK_GO_UP, GTK_ICON_SIZE_SMALL_TOOLBAR ); upbutton = gtk_button_new ( ); gtk_container_add ( GTK_CONTAINER(upbutton), upimage ); gtk_widget_set_tooltip_text ( GTK_WIDGET(upbutton), _("Move selected layer up")); gtk_box_pack_start ( GTK_BOX(hbox), upbutton, TRUE, TRUE, 0 ); g_signal_connect_swapped ( G_OBJECT(upbutton), "clicked", G_CALLBACK(layers_move_item_up), vlp ); /* Down button */ downimage = gtk_image_new_from_stock ( GTK_STOCK_GO_DOWN, GTK_ICON_SIZE_SMALL_TOOLBAR ); downbutton = gtk_button_new ( ); gtk_container_add ( GTK_CONTAINER(downbutton), downimage ); gtk_widget_set_tooltip_text ( GTK_WIDGET(downbutton), _("Move selected layer down")); gtk_box_pack_start ( GTK_BOX(hbox), downbutton, TRUE, TRUE, 0 ); g_signal_connect_swapped ( G_OBJECT(downbutton), "clicked", G_CALLBACK(layers_move_item_down), vlp ); /* Cut button */ cutimage = gtk_image_new_from_stock ( GTK_STOCK_CUT, GTK_ICON_SIZE_SMALL_TOOLBAR ); cutbutton = gtk_button_new ( ); gtk_container_add ( GTK_CONTAINER(cutbutton), cutimage ); gtk_widget_set_tooltip_text ( GTK_WIDGET(cutbutton), _("Cut selected layer")); gtk_box_pack_start ( GTK_BOX(hbox), cutbutton, TRUE, TRUE, 0 ); g_signal_connect_swapped ( G_OBJECT(cutbutton), "clicked", G_CALLBACK(vik_layers_panel_cut_selected), vlp ); /* Copy button */ copyimage = gtk_image_new_from_stock ( GTK_STOCK_COPY, GTK_ICON_SIZE_SMALL_TOOLBAR ); copybutton = gtk_button_new ( ); gtk_container_add ( GTK_CONTAINER(copybutton), copyimage ); gtk_widget_set_tooltip_text ( GTK_WIDGET(copybutton), _("Copy selected layer")); gtk_box_pack_start ( GTK_BOX(hbox), copybutton, TRUE, TRUE, 0 ); g_signal_connect_swapped ( G_OBJECT(copybutton), "clicked", G_CALLBACK(vik_layers_panel_copy_selected), vlp ); /* Paste button */ pasteimage = gtk_image_new_from_stock ( GTK_STOCK_PASTE, GTK_ICON_SIZE_SMALL_TOOLBAR ); pastebutton = gtk_button_new ( ); gtk_container_add ( GTK_CONTAINER(pastebutton),pasteimage ); gtk_widget_set_tooltip_text ( GTK_WIDGET(pastebutton), _("Paste layer below selected layer")); gtk_box_pack_start ( GTK_BOX(hbox), pastebutton, TRUE, TRUE, 0 ); g_signal_connect_swapped ( G_OBJECT(pastebutton), "clicked", G_CALLBACK(vik_layers_panel_paste_selected), vlp ); scrolledwindow = gtk_scrolled_window_new ( NULL, NULL ); gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW(scrolledwindow), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC ); gtk_container_add ( GTK_CONTAINER(scrolledwindow), GTK_WIDGET(vlp->vt) ); gtk_box_pack_start ( GTK_BOX(vlp), scrolledwindow, TRUE, TRUE, 0 ); gtk_box_pack_start ( GTK_BOX(vlp), hbox, FALSE, FALSE, 0 ); vlp->popup_factory = gtk_item_factory_new ( GTK_TYPE_MENU, "<main>", NULL ); gtk_item_factory_create_items ( vlp->popup_factory, NUM_BASE_ENTRIES, base_entries, vlp ); for ( i = 0; i < VIK_LAYER_NUM_TYPES; i++ ) { /* TODO: FIXME: if name has a '/' in it it will get all messed up. why not have an itemfactory field with name, icon, shortcut, etc.? */ /* Note: we use a temporary label in order to share translation with other codde */ gchar *label = g_strdup_printf(_("New %s Layer"), vik_layer_get_interface(i)->name ); entry.path = g_strdup_printf("%s/%s", base_entries[NUM_BASE_ENTRIES-1].path, label ); g_free ( label ); entry.accelerator = NULL; entry.callback = (GtkItemFactoryCallback) vik_layers_panel_new_layer; entry.callback_action = i; if ( vik_layer_get_interface(i)->icon ) { entry.item_type = "<ImageItem>"; entry.extra_data = gdk_pixdata_serialize ( vik_layer_get_interface(i)->icon, &tmp ); } else entry.item_type = "<Item>"; gtk_item_factory_create_item ( vlp->popup_factory, &entry, vlp, 1 ); g_free ( (gpointer) entry.extra_data ); g_free ( entry.path ); } }
void vik_layer_unmarshall_params ( VikLayer *vl, guint8 *data, gint datalen, VikViewport *vvp ) { VikLayerParam *params = vik_layer_get_interface(vl->type)->params; VikLayerFuncSetParam set_param = vik_layer_get_interface(vl->type)->set_param; gchar *s; guint8 *b = (guint8 *)data; #define vlm_size (*(gint *)b) #define vlm_read(obj) \ memcpy((obj), b+sizeof(gint), vlm_size); \ b += sizeof(gint) + vlm_size; s = g_malloc(vlm_size + 1); s[vlm_size]=0; vlm_read(s); vik_layer_rename(vl, s); g_free(s); if ( params && set_param ) { VikLayerParamData d; guint16 i, params_count = vik_layer_get_interface(vl->type)->params_count; for ( i = 0; i < params_count; i++ ) { g_debug("%s: %s", __FUNCTION__, params[i].name); switch ( params[i].type ) { case VIK_LAYER_PARAM_STRING: s = g_malloc(vlm_size + 1); s[vlm_size]=0; vlm_read(s); d.s = s; set_param(vl, i, d, vvp, FALSE); g_free(s); break; case VIK_LAYER_PARAM_STRING_LIST: { gint listlen = vlm_size, j; GList *list = NULL; b += sizeof(gint); /* skip listlen */; for ( j = 0; j < listlen; j++ ) { /* get a string */ s = g_malloc(vlm_size + 1); s[vlm_size]=0; vlm_read(s); list = g_list_append ( list, s ); } d.sl = list; set_param(vl, i, d, vvp, FALSE); /* don't free -- string list is responsibility of the layer */ break; } default: vlm_read(&d); set_param(vl, i, d, vvp, FALSE); break; } } } }
/** * 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 file_write ( VikAggregateLayer *top, FILE *f, gpointer vp ) { Stack *stack = NULL; VikLayer *current_layer; struct LatLon ll; VikViewportDrawMode mode; gchar *modestring = NULL; push(&stack); stack->data = (gpointer) vik_aggregate_layer_get_children(VIK_AGGREGATE_LAYER(top)); stack->under = NULL; /* crazhy CRAZHY */ vik_coord_to_latlon ( vik_viewport_get_center ( VIK_VIEWPORT(vp) ), &ll ); mode = vik_viewport_get_drawmode ( VIK_VIEWPORT(vp) ); switch ( mode ) { case VIK_VIEWPORT_DRAWMODE_UTM: modestring = "utm"; break; case VIK_VIEWPORT_DRAWMODE_EXPEDIA: modestring = "expedia"; break; case VIK_VIEWPORT_DRAWMODE_MERCATOR: modestring = "mercator"; break; case VIK_VIEWPORT_DRAWMODE_LATLON: modestring = "latlon"; break; default: g_critical("Houston, we've had a problem. mode=%d", mode); } fprintf ( f, "#VIKING GPS Data file " VIKING_URL "\n" ); fprintf ( f, "FILE_VERSION=%d\n", VIKING_FILE_VERSION ); fprintf ( f, "\nxmpp=%f\nympp=%f\nlat=%f\nlon=%f\nmode=%s\ncolor=%s\nhighlightcolor=%s\ndrawscale=%s\ndrawcentermark=%s\ndrawhighlight=%s\n", vik_viewport_get_xmpp ( VIK_VIEWPORT(vp) ), vik_viewport_get_ympp ( VIK_VIEWPORT(vp) ), ll.lat, ll.lon, modestring, vik_viewport_get_background_color(VIK_VIEWPORT(vp)), vik_viewport_get_highlight_color(VIK_VIEWPORT(vp)), vik_viewport_get_draw_scale(VIK_VIEWPORT(vp)) ? "t" : "f", vik_viewport_get_draw_centermark(VIK_VIEWPORT(vp)) ? "t" : "f", vik_viewport_get_draw_highlight(VIK_VIEWPORT(vp)) ? "t" : "f" ); if ( ! VIK_LAYER(top)->visible ) fprintf ( f, "visible=f\n" ); while (stack && stack->data) { current_layer = VIK_LAYER(((GList *)stack->data)->data); fprintf ( f, "\n~Layer %s\n", vik_layer_get_interface(current_layer->type)->fixed_layer_name ); write_layer_params_and_data ( current_layer, f ); if ( current_layer->type == VIK_LAYER_AGGREGATE && !vik_aggregate_layer_is_empty(VIK_AGGREGATE_LAYER(current_layer)) ) { push(&stack); stack->data = (gpointer) vik_aggregate_layer_get_children(VIK_AGGREGATE_LAYER(current_layer)); } else if ( current_layer->type == VIK_LAYER_GPS && !vik_gps_layer_is_empty(VIK_GPS_LAYER(current_layer)) ) { push(&stack); stack->data = (gpointer) vik_gps_layer_get_children(VIK_GPS_LAYER(current_layer)); } else { stack->data = (gpointer) ((GList *)stack->data)->next; fprintf ( f, "~EndLayer\n\n" ); while ( stack && (!stack->data) ) { pop(&stack); if ( stack ) { stack->data = (gpointer) ((GList *)stack->data)->next; fprintf ( f, "~EndLayer\n\n" ); } } } } /* get vikaggregatelayer's children (?) foreach write ALL params, then layer data (IF function exists) then endlayer impl: stack of layers (LIST) we are working on when layer->next == NULL ... we move on. */ }
/** * a_layer_defaults_show_window: * @parent: The Window * @layername: The layer * * This displays a Window showing the default parameter values for the selected layer * It allows the parameters to be changed. * * Returns: %TRUE if the window is displayed (because there are parameters to view) */ gboolean a_layer_defaults_show_window ( GtkWindow *parent, const gchar *layername ) { if ( ! loaded ) { // since we can't load the file in a_defaults_init (no params registered yet), // do it once before we display the params. defaults_load_from_file(); loaded = TRUE; } VikLayerTypeEnum layer = vik_layer_type_from_string ( layername ); // Need to know where the params start and they finish for this layer // 1. inspect every registered param - see if it has the layer value required to determine overall size // [they are contiguous from the start index] // 2. copy the these params from the main list into a tmp struct // // Then pass this tmp struct to uibuilder for display guint layer_params_count = 0; gboolean found_first = FALSE; gint index = 0; int i; for ( i = 0; i < paramsVD->len; i++ ) { VikLayerParam *param = (VikLayerParam*)(g_ptr_array_index(paramsVD,i)); if ( param->layer == layer ) { layer_params_count++; if ( !found_first ) { index = i; found_first = TRUE; } } } // Have we any parameters to show! if ( !layer_params_count ) return FALSE; VikLayerParam *params = g_new(VikLayerParam,layer_params_count); for ( i = 0; i < layer_params_count; i++ ) { params[i] = *((VikLayerParam*)(g_ptr_array_index(paramsVD,i+index))); } gchar *title = g_strconcat ( layername, ": ", _("Layer Defaults"), NULL ); if ( a_uibuilder_properties_factory ( title, parent, params, layer_params_count, vik_layer_get_interface(layer)->params_groups, vik_layer_get_interface(layer)->params_groups_count, (gboolean (*) (gpointer,guint16,VikLayerParamData,gpointer,gboolean)) defaults_run_setparam, GINT_TO_POINTER ( index ), params, defaults_run_getparam, GINT_TO_POINTER ( index ) ) ) { // Save layer_defaults_save_to_file(); } g_free ( title ); g_free ( params ); return TRUE; }