X-Git-Url: https://git.street.me.uk/andy/viking.git/blobdiff_plain/734652bffd63c5b57a3c7d995dbb2e4bef6cb0ca..0dff88eac247e849f58f8e77f3bfa9ab02f572fb:/src/viktrwlayer.c diff --git a/src/viktrwlayer.c b/src/viktrwlayer.c index 09ea30d8..d16a7379 100644 --- a/src/viktrwlayer.c +++ b/src/viktrwlayer.c @@ -28,6 +28,7 @@ #include "viktrwlayer_pixmap.h" #include "viktrwlayer_tpwin.h" #include "viktrwlayer_propwin.h" +#include "garminsymbols.h" #include "thumbnails.h" #include "background.h" @@ -53,6 +54,10 @@ #define TRACKPOINT_SIZE_APPROX 5 #define WAYPOINT_SIZE_APPROX 5 +#define MIN_STOP_LENGTH 15 +#define MAX_STOP_LENGTH 86400 +#define DRAW_ELEVATION_FACTOR 30 /* height of elevation plotting, sort of relative to zoom level ("mpp" that isn't mpp necessarily) */ + /* this is multiplied by user-inputted value from 1-100. */ enum { VIK_TRW_LAYER_SUBLAYER_TRACKS, VIK_TRW_LAYER_SUBLAYER_WAYPOINTS, @@ -72,12 +77,17 @@ struct _VikTrwLayer { gboolean tracks_visible, waypoints_visible; guint8 drawmode; guint8 drawpoints; + guint8 drawelevation; + guint8 elevation_factor; + guint8 drawstops; + guint32 stop_length; guint8 drawlines; guint8 line_thickness; guint8 bg_line_thickness; guint8 wp_symbol; guint8 wp_size; + gboolean wp_draw_symbols; gdouble velocity_min, velocity_max; GArray *track_gc; @@ -182,6 +192,7 @@ static VikLayerParamData trw_layer_get_param ( VikTrwLayer *vtl, guint16 id ); static gpointer trw_layer_copy_item ( VikTrwLayer *vtl, gint subtype, gpointer sublayer ); static gboolean trw_layer_paste_item ( VikTrwLayer *vtl, gint subtype, gpointer item ); static void trw_layer_free_copied_item ( gint subtype, gpointer item ); +static void trw_layer_drag_drop_request ( VikTrwLayer *vtl_src, VikTrwLayer *vtl_dest, GtkTreeIter *src_item_iter, GtkTreePath *dest_path ); static void trw_layer_cancel_tps_of_track ( VikTrwLayer *vtl, const gchar *trk_name ); static void trw_layer_cancel_last_tp ( VikTrwLayer *vtl ); @@ -206,6 +217,8 @@ static VikWaypoint *closest_wp_in_five_pixel_interval ( VikTrwLayer *vtl, VikVie static void trw_layer_change_coord_mode ( VikTrwLayer *vtl, VikCoordMode dest_mode ); +static gchar *get_new_unique_sublayer_name (VikTrwLayer *vtl, gint sublayer_type, const gchar *name); + static VikToolInterface trw_layer_tools[] = { { "Create Waypoint", (VikToolInterfaceFunc) tool_new_waypoint, NULL }, { "Create Track", (VikToolInterfaceFunc) tool_new_track, NULL }, @@ -223,6 +236,7 @@ enum { GROUP_WAYPOINTS, GROUP_TRACKS, GROUP_IMAGES }; static gchar *params_drawmodes[] = { "Draw by Track", "Draw by Velocity", "All Tracks Black", 0 }; static gchar *params_wpsymbols[] = { "Filled Square", "Square", "Circle", "X", 0 }; + static VikLayerParamScale params_scales[] = { /* min max step digits */ { 1, 10, 1, 0 }, /* line_thickness */ @@ -234,6 +248,8 @@ static VikLayerParamScale params_scales[] = { { 5, 500, 5, 0 }, /* image cache_size */ { 0, 8, 1, 0 }, /* image cache_size */ { 1, 64, 1, 0 }, /* wpsize */ + { MIN_STOP_LENGTH, MAX_STOP_LENGTH, 1, 0 }, /* stop_length */ + { 1, 100, 1, 0 }, /* stop_length */ }; VikLayerParam trw_layer_params[] = { @@ -243,6 +259,12 @@ VikLayerParam trw_layer_params[] = { { "drawmode", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, "Track Drawing Mode:", VIK_LAYER_WIDGET_RADIOGROUP, params_drawmodes }, { "drawlines", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, "Draw Track Lines", VIK_LAYER_WIDGET_CHECKBUTTON }, { "drawpoints", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, "Draw Trackpoints", VIK_LAYER_WIDGET_CHECKBUTTON }, + { "drawelevation", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, "Draw Elevation", VIK_LAYER_WIDGET_CHECKBUTTON }, + { "elevation_factor", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, "Draw Elevation Height %:", VIK_LAYER_WIDGET_HSCALE, params_scales + 9 }, + + { "drawstops", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, "Draw Stops", VIK_LAYER_WIDGET_CHECKBUTTON }, + { "stop_length", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, "Min Stop Length (seconds):", VIK_LAYER_WIDGET_SPINBUTTON, params_scales + 8 }, + { "line_thickness", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, "Track Thickness:", VIK_LAYER_WIDGET_SPINBUTTON, params_scales + 0 }, { "bg_line_thickness", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, "Track BG Thickness:", VIK_LAYER_WIDGET_SPINBUTTON, params_scales + 6 }, { "trackbgcolor", VIK_LAYER_PARAM_COLOR, GROUP_TRACKS, "Track Background Color", VIK_LAYER_WIDGET_COLOR, 0 }, @@ -254,8 +276,9 @@ VikLayerParam trw_layer_params[] = { { "wptextcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, "Waypoint Text:", VIK_LAYER_WIDGET_COLOR, 0 }, { "wpbgcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, "Background:", VIK_LAYER_WIDGET_COLOR, 0 }, { "wpbgand", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, "Fake BG Color Translucency:", VIK_LAYER_WIDGET_CHECKBUTTON, 0 }, - { "wpsymbol", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, "Waypoint symbol:", VIK_LAYER_WIDGET_RADIOGROUP, params_wpsymbols }, + { "wpsymbol", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, "Waypoint marker:", VIK_LAYER_WIDGET_RADIOGROUP, params_wpsymbols }, { "wpsize", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, "Waypoint size:", VIK_LAYER_WIDGET_SPINBUTTON, params_scales + 7 }, + { "wpsyms", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, "Draw Waypoint Symbols:", VIK_LAYER_WIDGET_CHECKBUTTON }, { "drawimages", VIK_LAYER_PARAM_BOOLEAN, GROUP_IMAGES, "Draw Waypoint Images", VIK_LAYER_WIDGET_CHECKBUTTON }, { "image_size", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, "Image Size (pixels):", VIK_LAYER_WIDGET_HSCALE, params_scales + 3 }, @@ -263,7 +286,7 @@ VikLayerParam trw_layer_params[] = { { "image_cache_size", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, "Image Memory Cache Size:", VIK_LAYER_WIDGET_HSCALE, params_scales + 5 }, }; -enum { PARAM_TV, PARAM_WV, PARAM_DM, PARAM_DL, PARAM_DP, PARAM_LT, PARAM_BLT, PARAM_TBGC, PARAM_VMIN, PARAM_VMAX, PARAM_DLA, PARAM_WPC, PARAM_WPTC, PARAM_WPBC, PARAM_WPBA, PARAM_WPSYM, PARAM_WPSIZE, PARAM_DI, PARAM_IS, PARAM_IA, PARAM_ICS, NUM_PARAMS }; +enum { PARAM_TV, PARAM_WV, PARAM_DM, PARAM_DL, PARAM_DP, PARAM_DE, PARAM_EF, PARAM_DS, PARAM_SL, PARAM_LT, PARAM_BLT, PARAM_TBGC, PARAM_VMIN, PARAM_VMAX, PARAM_DLA, PARAM_WPC, PARAM_WPTC, PARAM_WPBC, PARAM_WPBA, PARAM_WPSYM, PARAM_WPSIZE, PARAM_WPSYMS, PARAM_DI, PARAM_IS, PARAM_IA, PARAM_ICS, NUM_PARAMS }; /****** END PARAMETERS ******/ @@ -305,6 +328,8 @@ VikLayerInterface vik_trw_layer_interface = { (VikLayerFuncCopyItem) trw_layer_copy_item, (VikLayerFuncPasteItem) trw_layer_paste_item, (VikLayerFuncFreeCopiedItem) trw_layer_free_copied_item, + + (VikLayerFuncDragDropRequest) trw_layer_drag_drop_request, }; /* for copy & paste (I think?) */ @@ -368,13 +393,17 @@ static gboolean trw_layer_paste_item ( VikTrwLayer *vtl, gint subtype, gpointer if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT && item ) { NamedWaypoint *nw = (NamedWaypoint *) item; - vik_trw_layer_add_waypoint ( vtl, g_strdup(nw->name), vik_waypoint_copy(nw->wp) ); + vik_trw_layer_add_waypoint ( vtl, + get_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_WAYPOINT, nw->name), + vik_waypoint_copy(nw->wp) ); return TRUE; } if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK && item ) { NamedTrack *nt = (NamedTrack *) item; - vik_trw_layer_add_track ( vtl, g_strdup(nt->name), vik_track_copy(nt->tr) ); + vik_trw_layer_add_track ( vtl, + get_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, nt->name), + vik_track_copy(nt->tr) ); return TRUE; } return FALSE; @@ -411,7 +440,15 @@ static gboolean trw_layer_set_param ( VikTrwLayer *vtl, guint16 id, VikLayerPara case PARAM_WV: vtl->waypoints_visible = data.b; break; case PARAM_DM: vtl->drawmode = data.u; break; case PARAM_DP: vtl->drawpoints = data.b; break; + case PARAM_DE: vtl->drawelevation = data.b; break; + case PARAM_DS: vtl->drawstops = data.b; break; case PARAM_DL: vtl->drawlines = data.b; break; + case PARAM_SL: if ( data.u >= MIN_STOP_LENGTH && data.u <= MAX_STOP_LENGTH ) + vtl->stop_length = data.u; + break; + case PARAM_EF: if ( data.u >= 1 && data.u <= 100 ) + vtl->elevation_factor = data.u; + break; case PARAM_LT: if ( data.u > 0 && data.u < 15 && data.u != vtl->line_thickness ) { vtl->line_thickness = data.u; @@ -448,6 +485,7 @@ static gboolean trw_layer_set_param ( VikTrwLayer *vtl, guint16 id, VikLayerPara case PARAM_WPBA: gdk_gc_set_function(vtl->waypoint_bg_gc, data.b ? GDK_AND : GDK_COPY ); break; case PARAM_WPSYM: if ( data.u < WP_NUM_SYMBOLS ) vtl->wp_symbol = data.u; break; case PARAM_WPSIZE: if ( data.u > 0 && data.u <= 64 ) vtl->wp_size = data.u; break; + case PARAM_WPSYMS: vtl->wp_draw_symbols = data.b; break; } return TRUE; } @@ -461,6 +499,10 @@ static VikLayerParamData trw_layer_get_param ( VikTrwLayer *vtl, guint16 id ) case PARAM_WV: rv.b = vtl->waypoints_visible; break; case PARAM_DM: rv.u = vtl->drawmode; break; case PARAM_DP: rv.b = vtl->drawpoints; break; + case PARAM_DE: rv.b = vtl->drawelevation; break; + case PARAM_EF: rv.u = vtl->elevation_factor; break; + case PARAM_DS: rv.b = vtl->drawstops; break; + case PARAM_SL: rv.u = vtl->stop_length; break; case PARAM_DL: rv.b = vtl->drawlines; break; case PARAM_LT: rv.u = vtl->line_thickness; break; case PARAM_BLT: rv.u = vtl->bg_line_thickness; break; @@ -478,6 +520,7 @@ static VikLayerParamData trw_layer_get_param ( VikTrwLayer *vtl, guint16 id ) case PARAM_WPBA: rv.b = (vik_gc_get_function(vtl->waypoint_bg_gc)==GDK_AND); break; case PARAM_WPSYM: rv.u = vtl->wp_symbol; break; case PARAM_WPSIZE: rv.u = vtl->wp_size; break; + case PARAM_WPSYMS: rv.b = vtl->wp_draw_symbols; break; } return rv; } @@ -500,7 +543,11 @@ static VikTrwLayer *trw_layer_copy ( VikTrwLayer *vtl, gpointer vp ) rv->tracks_visible = vtl->tracks_visible; rv->waypoints_visible = vtl->waypoints_visible; rv->drawpoints = vtl->drawpoints; + rv->drawstops = vtl->drawstops; + rv->drawelevation = vtl->drawelevation; + rv->elevation_factor = vtl->elevation_factor; rv->drawlines = vtl->drawlines; + rv->stop_length = vtl->stop_length; rv->line_thickness = vtl->line_thickness; rv->bg_line_thickness = vtl->bg_line_thickness; rv->velocity_min = vtl->velocity_min; @@ -514,6 +561,7 @@ static VikTrwLayer *trw_layer_copy ( VikTrwLayer *vtl, gpointer vp ) rv->coord_mode = vtl->coord_mode; rv->wp_symbol = vtl->wp_symbol; rv->wp_size = vtl->wp_size; + rv->wp_draw_symbols = vtl->wp_draw_symbols; trw_layer_new_track_gcs ( rv, VIK_VIEWPORT(vp) ); @@ -548,6 +596,10 @@ VikTrwLayer *vik_trw_layer_new ( gint drawmode ) rv->waypoints_visible = rv->tracks_visible = TRUE; rv->drawmode = drawmode; rv->drawpoints = TRUE; + rv->drawstops = FALSE; + rv->drawelevation = FALSE; + rv->elevation_factor = 30; + rv->stop_length = 60; rv->drawlines = TRUE; rv->wplabellayout = NULL; rv->wp_right_click_menu = NULL; @@ -558,7 +610,7 @@ VikTrwLayer *vik_trw_layer_new ( gint drawmode ) rv->velocity_max = 5.0; rv->velocity_min = 0.0; rv->line_thickness = 1; - rv->line_thickness = 0; + rv->bg_line_thickness = 0; rv->current_wp = NULL; rv->current_wp_name = NULL; rv->current_track = NULL; @@ -688,11 +740,21 @@ static void trw_layer_draw_track ( const gchar *name, VikTrack *track, struct Dr gboolean useoldvals = TRUE; gboolean drawpoints; + gboolean drawstops; + gboolean drawelevation; + gdouble min_alt, max_alt, alt_diff; const guint8 tp_size_reg = 2; const guint8 tp_size_cur = 4; guint8 tp_size; + if ( dp->vtl->drawelevation ) + { + /* assume if it has elevation at the beginning, it has it throughout. not ness a true good assumption */ + if ( ( drawelevation = vik_track_get_minmax_alt ( track, &min_alt, &max_alt ) ) ) + alt_diff = max_alt - min_alt; + } + if ( ! track->visible ) return; @@ -701,9 +763,11 @@ static void trw_layer_draw_track ( const gchar *name, VikTrack *track, struct Dr trw_layer_draw_track ( name, track, dp, TRUE ); if ( drawing_white_background ) - drawpoints = FALSE; - else + drawpoints = drawstops = FALSE; + else { drawpoints = dp->vtl->drawpoints; + drawstops = dp->vtl->drawstops; + } if (list) { int x, y, oldx, oldy; @@ -743,15 +807,10 @@ static void trw_layer_draw_track ( const gchar *name, VikTrack *track, struct Dr if ( list->next ) { vik_viewport_draw_rectangle ( dp->vp, g_array_index(dp->vtl->track_gc, GdkGC *, dp->track_gc_iter), TRUE, x-tp_size, y-tp_size, 2*tp_size, 2*tp_size ); -#if 0 - if ( VIK_TRACKPOINT(list->next->data)->altitude != VIK_DEFAULT_ALTITUDE ) - vik_viewport_draw_line ( dp->vp, g_array_index(dp->vtl->track_gc, GdkGC *, dp->track_gc_iter), x, y, x, y-(VIK_TRACKPOINT(list->next->data)->altitude-540)/5); -#endif - vik_viewport_draw_rectangle ( dp->vp, g_array_index(dp->vtl->track_gc, GdkGC *, dp->track_gc_iter), TRUE, x-tp_size, y-tp_size, 2*tp_size, 2*tp_size ); /* stops */ - if (0 && VIK_TRACKPOINT(list->next->data)->timestamp - VIK_TRACKPOINT(list->data)->timestamp > 60 ) + if ( drawstops && VIK_TRACKPOINT(list->next->data)->timestamp - VIK_TRACKPOINT(list->data)->timestamp > dp->vtl->stop_length ) vik_viewport_draw_arc ( dp->vp, g_array_index(dp->vtl->track_gc, GdkGC *, 11), TRUE, x-(3*tp_size), y-(3*tp_size), 6*tp_size, 6*tp_size, 0, 360*64 ); } else @@ -772,10 +831,35 @@ static void trw_layer_draw_track ( const gchar *name, VikTrack *track, struct Dr if (!useoldvals) vik_viewport_coord_to_screen ( dp->vp, &(tp2->coord), &oldx, &oldy ); - if ( drawing_white_background ) + if ( drawing_white_background ) { vik_viewport_draw_line ( dp->vp, dp->vtl->track_bg_gc, oldx, oldy, x, y); - else + } + else { + vik_viewport_draw_line ( dp->vp, g_array_index(dp->vtl->track_gc, GdkGC *, dp->track_gc_iter), oldx, oldy, x, y); + if ( dp->vtl->drawelevation && list && list->next && VIK_TRACKPOINT(list->next->data)->altitude != VIK_DEFAULT_ALTITUDE ) { + GdkPoint tmp[4]; + #define FIXALTITUDE(what) ((VIK_TRACKPOINT((what))->altitude-min_alt)/alt_diff*DRAW_ELEVATION_FACTOR*dp->vtl->elevation_factor/dp->xmpp) + if ( list && list->next && VIK_TRACKPOINT(list->next->data)->altitude != VIK_DEFAULT_ALTITUDE ) { + tmp[0].x = oldx; + tmp[0].y = oldy; + tmp[1].x = oldx; + tmp[1].y = oldy-FIXALTITUDE(list->data); + tmp[2].x = x; + tmp[2].y = y-FIXALTITUDE(list->next->data); + tmp[3].x = x; + tmp[3].y = y; + + GdkGC *tmp_gc; + if ( ((oldx - x) > 0 && (oldy - y) > 0) || ((oldx - x) < 0 && (oldy - y) < 0)) + tmp_gc = GTK_WIDGET(dp->vp)->style->light_gc[3]; + else + tmp_gc = GTK_WIDGET(dp->vp)->style->dark_gc[0]; + vik_viewport_draw_polygon ( dp->vp, tmp_gc, TRUE, tmp, 4); + } + vik_viewport_draw_line ( dp->vp, g_array_index(dp->vtl->track_gc, GdkGC *, dp->track_gc_iter), oldx, oldy-FIXALTITUDE(list->data), x, y-FIXALTITUDE(list->next->data)); + } + } } oldx = x; @@ -837,6 +921,7 @@ static void trw_layer_draw_waypoint ( const gchar *name, VikWaypoint *wp, struct wp->coord.north_south > dp->cn1 && wp->coord.north_south < dp->cn2 ) ) { gint x, y; + GdkPixbuf *sym; vik_viewport_coord_to_screen ( dp->vp, &(wp->coord), &x, &y ); /* if in shrunken_cache, get that. If not, get and add to shrunken_cache */ @@ -909,7 +994,10 @@ static void trw_layer_draw_waypoint ( const gchar *name, VikWaypoint *wp, struct } /* DRAW ACTUAL DOT */ - if ( wp == dp->vtl->current_wp ) { + if ( dp->vtl->wp_draw_symbols && wp->symbol && (sym = a_get_wp_sym(wp->symbol)) ) { + vik_viewport_draw_pixbuf ( dp->vp, sym, 0, 0, x - gdk_pixbuf_get_width(sym)/2, y - gdk_pixbuf_get_height(sym)/2, -1, -1 ); + } + else if ( wp == dp->vtl->current_wp ) { switch ( dp->vtl->wp_symbol ) { case WP_SYMBOL_FILLED_SQUARE: vik_viewport_draw_rectangle ( dp->vp, dp->vtl->waypoint_gc, TRUE, x - (dp->vtl->wp_size), y - (dp->vtl->wp_size), dp->vtl->wp_size*2, dp->vtl->wp_size*2 ); break; case WP_SYMBOL_SQUARE: vik_viewport_draw_rectangle ( dp->vp, dp->vtl->waypoint_gc, FALSE, x - (dp->vtl->wp_size), y - (dp->vtl->wp_size), dp->vtl->wp_size*2, dp->vtl->wp_size*2 ); break; @@ -1030,6 +1118,7 @@ VikTrwLayer *vik_trw_layer_create ( VikViewport *vp ) rv->has_verified_thumbnails = FALSE; rv->wp_symbol = WP_SYMBOL_FILLED_SQUARE; rv->wp_size = 4; + rv->wp_draw_symbols = TRUE; rv->coord_mode = vik_viewport_get_coord_mode ( vp ); @@ -1238,6 +1327,11 @@ static void trw_layer_export_gpsmapper ( gpointer layer_and_vlp[2] ) trw_layer_export ( layer_and_vlp, FILE_TYPE_GPSMAPPER ); } +static void trw_layer_export_gpx ( gpointer layer_and_vlp[2] ) +{ + trw_layer_export ( layer_and_vlp, FILE_TYPE_GPX ); +} + static void trw_layer_goto_wp ( gpointer layer_and_vlp[2] ) { GHashTable *wps = vik_trw_layer_get_waypoints ( VIK_TRW_LAYER(layer_and_vlp[0]) ); @@ -1289,17 +1383,16 @@ static void trw_layer_goto_wp ( gpointer layer_and_vlp[2] ) gboolean vik_trw_layer_new_waypoint ( VikTrwLayer *vtl, GtkWindow *w, const VikCoord *def_coord ) { gchar *name; - static VikWaypoint st_wp; - st_wp.coord = *def_coord; - st_wp.altitude = VIK_DEFAULT_ALTITUDE; + VikWaypoint *wp = vik_waypoint_new(); + wp->coord = *def_coord; + wp->altitude = VIK_DEFAULT_ALTITUDE; - if ( a_dialog_new_waypoint ( w, &name, &st_wp, vik_trw_layer_get_waypoints ( vtl ), vtl->coord_mode ) ) + if ( a_dialog_new_waypoint ( w, &name, wp, vik_trw_layer_get_waypoints ( vtl ), vtl->coord_mode ) ) { - VikWaypoint *wp = vik_waypoint_new(); - *wp = st_wp; vik_trw_layer_add_waypoint ( vtl, name, wp ); return TRUE; } + vik_waypoint_free(wp); return FALSE; } @@ -1344,6 +1437,11 @@ void vik_trw_layer_add_menu_items ( VikTrwLayer *vtl, GtkMenu *menu, gpointer vl gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); gtk_widget_show ( item ); + item = gtk_menu_item_new_with_label ( "Export Layer as GPX" ); + g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_export_gpx), pass_along ); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + gtk_widget_show ( item ); + item = gtk_menu_item_new_with_label ( "New Waypoint" ); g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_new_wp), pass_along ); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); @@ -1427,8 +1525,49 @@ static void trw_layer_cancel_tps_of_track ( VikTrwLayer *vtl, const gchar *trk_n else if (vtl->last_tp_track_name && g_strcasecmp(trk_name, vtl->last_tp_track_name) == 0) trw_layer_cancel_last_tp ( vtl ); } + +static gchar *get_new_unique_sublayer_name (VikTrwLayer *vtl, gint sublayer_type, const gchar *name) +{ + gint i = 2; + gchar *newname = g_strdup(name); + while ((sublayer_type == VIK_TRW_LAYER_SUBLAYER_TRACK) ? + vik_trw_layer_get_track(vtl, newname) : vik_trw_layer_get_waypoint(vtl, newname)) { + gchar *new_newname = g_strdup_printf("%s#%d", name, i); + g_free(newname); + newname = new_newname; + i++; + } + return newname; +} + +static void trw_layer_drag_drop_request ( VikTrwLayer *vtl_src, VikTrwLayer *vtl_dest, GtkTreeIter *src_item_iter, GtkTreePath *dest_path ) +{ + VikTreeview *vt = VIK_LAYER(vtl_src)->vt; + if (!vik_treeview_item_get_pointer(vt, src_item_iter)) { + g_print("moving a trw container: not implemented yet.\n"); + } else { + gint type = vik_treeview_item_get_data(vt, src_item_iter); + gchar *name = vik_treeview_item_get_pointer(vt, src_item_iter); + + if (type==VIK_TRW_LAYER_SUBLAYER_TRACK) { + VikTrack *t; + gchar *newname = get_new_unique_sublayer_name(vtl_dest, VIK_TRW_LAYER_SUBLAYER_TRACK, name); + t = vik_track_copy(vik_trw_layer_get_track(vtl_src, name)); + vik_trw_layer_delete_track(vtl_src, name); + vik_trw_layer_add_track(vtl_dest, newname, t); + } + if (type==VIK_TRW_LAYER_SUBLAYER_WAYPOINT) { + VikWaypoint *w; + gchar *newname = get_new_unique_sublayer_name(vtl_dest, VIK_TRW_LAYER_SUBLAYER_WAYPOINT, name); + w = vik_waypoint_copy(vik_trw_layer_get_waypoint(vtl_src, name)); + vik_trw_layer_delete_waypoint(vtl_src, name); + vik_trw_layer_add_waypoint(vtl_dest, newname, w); + } + } +} -static gboolean trw_layer_delete_track ( VikTrwLayer *vtl, const gchar *trk_name ) + +gboolean vik_trw_layer_delete_track ( VikTrwLayer *vtl, const gchar *trk_name ) { VikTrack *t = g_hash_table_lookup ( vtl->tracks, trk_name ); gboolean was_visible = FALSE; @@ -1452,36 +1591,43 @@ static gboolean trw_layer_delete_track ( VikTrwLayer *vtl, const gchar *trk_name return was_visible; } +gboolean vik_trw_layer_delete_waypoint ( VikTrwLayer *vtl, const gchar *wp_name ) +{ + gboolean was_visible = FALSE; + VikWaypoint *wp; + + wp = g_hash_table_lookup ( vtl->waypoints, wp_name ); + if ( wp ) { + GtkTreeIter *it; + + if ( wp == vtl->current_wp ) { + vtl->current_wp = NULL; + vtl->current_wp_name = NULL; + vtl->moving_wp = FALSE; + } + + was_visible = wp->visible; + g_assert ( ( it = g_hash_table_lookup ( vtl->waypoints_iters, (gchar *) wp_name ) ) ); + vik_treeview_item_delete ( VIK_LAYER(vtl)->vt, it ); + g_hash_table_remove ( vtl->waypoints_iters, (gchar *) wp_name ); + g_hash_table_remove ( vtl->waypoints, wp_name ); /* last because this frees name */ + } + + return was_visible; +} + static void trw_layer_delete_item ( gpointer pass_along[5] ) { VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]); gboolean was_visible = FALSE; if ( (gint) pass_along[2] == VIK_TRW_LAYER_SUBLAYER_WAYPOINT ) { - VikWaypoint *wp; - wp = g_hash_table_lookup ( vtl->waypoints, pass_along[3] ); - if ( wp ) - { - GtkTreeIter *it; - - if ( wp == vtl->current_wp ) { - vtl->current_wp = NULL; - vtl->current_wp_name = NULL; - vtl->moving_wp = FALSE; - } - - was_visible = wp->visible; - g_assert ( ( it = g_hash_table_lookup ( vtl->waypoints_iters, (gchar *) pass_along[3] ) ) ); - vik_treeview_item_delete ( VIK_LAYER(vtl)->vt, it ); - g_hash_table_remove ( vtl->waypoints_iters, (gchar *) pass_along[3] ); - g_hash_table_remove ( vtl->waypoints, pass_along[3] ); /* last because this frees name */ - } + was_visible = vik_trw_layer_delete_waypoint ( vtl, (gchar *) pass_along[3] ); } else { - was_visible = trw_layer_delete_track ( vtl, (gchar *) pass_along[3] ); + was_visible = vik_trw_layer_delete_track ( vtl, (gchar *) pass_along[3] ); } - if ( was_visible ) vik_layer_emit_update ( VIK_LAYER(vtl) ); } @@ -1506,7 +1652,7 @@ static void trw_layer_properties_item ( gpointer pass_along[5] ) VikTrack *tr = g_hash_table_lookup ( vtl->tracks, pass_along[3] ); if ( tr ) { - gint resp = vik_trw_layer_propwin_run ( VIK_GTK_WINDOW_FROM_LAYER(vtl), tr ); + gint resp = vik_trw_layer_propwin_run ( VIK_GTK_WINDOW_FROM_LAYER(vtl), tr, pass_along[1] /* vlp */ ); if ( resp == VIK_TRW_LAYER_PROPWIN_DEL_DUP ) { vik_track_remove_dup_points(tr); @@ -1552,7 +1698,7 @@ static void trw_layer_properties_item ( gpointer pass_along[5] ) if ( tracks ) { g_free ( tracks ); - trw_layer_delete_track ( vtl, (gchar *) pass_along[3] ); + vik_trw_layer_delete_track ( vtl, (gchar *) pass_along[3] ); vik_layer_emit_update ( VIK_LAYER(vtl) ); /* chase thru the hoops */ } } @@ -1625,11 +1771,11 @@ static void find_nearby_track(gpointer key, gpointer value, gpointer user_data) p2 = VIK_TRACKPOINT(g_list_last(VIK_TRACK(value)->trackpoints)->data); if (!p1->has_timestamp || !p2->has_timestamp) { - printf("no timestamp\n"); + g_print("no timestamp\n"); return; } - /* printf("Got track named %s, times %d, %d\n", (gchar *)key, p1->timestamp, p2->timestamp); */ + /* g_print("Got track named %s, times %d, %d\n", (gchar *)key, p1->timestamp, p2->timestamp); */ if (abs(t1 - p2->timestamp) < thr*60 || /* p1 p2 t1 t2 */ abs(p1->timestamp - t2) < thr*60 @@ -1699,7 +1845,7 @@ static void trw_layer_merge_by_timestamp ( gpointer pass_along[6] ) t1 = ((VikTrackpoint *)trps->data)->timestamp; t2 = ((VikTrackpoint *)g_list_last(trps)->data)->timestamp; - /* printf("Original track times: %d and %d\n", t1, t2); */ + /* g_print("Original track times: %d and %d\n", t1, t2); */ params[0] = &nearby_tracks; params[1] = trps; params[2] = (gpointer)thr; @@ -1727,14 +1873,14 @@ static void trw_layer_merge_by_timestamp ( gpointer pass_along[6] ) time_t t1, t2; t1 = get_first_trackpoint(l)->timestamp; t2 = get_last_trackpoint(l)->timestamp; - printf(" %20s: track %d - %d\n", (char *)l->data, (int)t1, (int)t2); + g_print(" %20s: track %d - %d\n", (char *)l->data, (int)t1, (int)t2); */ /* remove trackpoints from merged track, delete track */ tr->trackpoints = g_list_concat(tr->trackpoints, get_track(l)->trackpoints); get_track(l)->trackpoints = NULL; - trw_layer_delete_track(VIK_TRW_LAYER(pass_along[0]), l->data); + vik_trw_layer_delete_track(VIK_TRW_LAYER(pass_along[0]), l->data); track_count ++; l = g_list_next(l); @@ -1782,7 +1928,7 @@ static void trw_layer_split_by_timestamp ( gpointer pass_along[6] ) while (iter) { ts = VIK_TRACKPOINT(iter->data)->timestamp; if (ts < prev_ts) { - printf("panic: ts < prev_ts: this should never happen!\n"); + g_print("panic: ts < prev_ts: this should never happen!\n"); return; } if (ts - prev_ts > thr*60) { @@ -1813,13 +1959,13 @@ static void trw_layer_split_by_timestamp ( gpointer pass_along[6] ) new_tr_name = g_strdup_printf("%s #%d", (gchar *) pass_along[3], i++); vik_trw_layer_add_track(VIK_TRW_LAYER(pass_along[0]), new_tr_name, tr); - /* fprintf(stderr, "adding track %s, times %d - %d\n", new_tr_name, VIK_TRACKPOINT(tr->trackpoints->data)->timestamp, + /* g_print("adding track %s, times %d - %d\n", new_tr_name, VIK_TRACKPOINT(tr->trackpoints->data)->timestamp, VIK_TRACKPOINT(g_list_last(tr->trackpoints)->data)->timestamp);*/ iter = g_list_next(iter); } g_list_free(newlists); - trw_layer_delete_track(VIK_TRW_LAYER(pass_along[0]), (gchar *)pass_along[3]); + vik_trw_layer_delete_track(VIK_TRW_LAYER(pass_along[0]), (gchar *)pass_along[3]); vik_layer_emit_update(VIK_LAYER(pass_along[0])); } @@ -1868,12 +2014,12 @@ const gchar *vik_trw_layer_sublayer_rename_request ( VikTrwLayer *l, const gchar return NULL; } - wp = vik_waypoint_copy ( VIK_WAYPOINT(g_hash_table_lookup ( l->waypoints, sublayer )) ); - g_hash_table_remove ( l->waypoints, sublayer ); - iter = g_hash_table_lookup ( l->waypoints_iters, sublayer ); g_hash_table_steal ( l->waypoints_iters, sublayer ); + wp = vik_waypoint_copy ( VIK_WAYPOINT(g_hash_table_lookup ( l->waypoints, sublayer )) ); + g_hash_table_remove ( l->waypoints, sublayer ); + rv = g_strdup(newname); for ( i = strlen(rv) - 1; i >= 0; i-- ) rv[i] = toupper(rv[i]); @@ -1908,7 +2054,7 @@ const gchar *vik_trw_layer_sublayer_rename_request ( VikTrwLayer *l, const gchar return NULL; } - g_hash_table_lookup_extended ( l->tracks, sublayer, (gpointer *)&orig_key, (gpointer *)&tr ); + g_hash_table_lookup_extended ( l->tracks, sublayer, (void *)&orig_key, (void *)&tr ); g_hash_table_steal ( l->tracks, sublayer ); iter = g_hash_table_lookup ( l->tracks_iters, sublayer ); @@ -2280,7 +2426,7 @@ static void trw_layer_tpwin_response ( VikTrwLayer *vtl, gint response ) /* if we did this before, trw_layer_delete_track would have canceled the current tp because * it was the current track. canceling the current tp would have set vtl->current_tpl to NULL */ - trw_layer_delete_track ( vtl, tmp ); + vik_trw_layer_delete_track ( vtl, tmp ); trw_layer_cancel_last_tp ( vtl ); /* same TP, can't join. */ vik_layer_emit_update(VIK_LAYER(vtl)); @@ -2676,3 +2822,13 @@ static void trw_layer_change_coord_mode ( VikTrwLayer *vtl, VikCoordMode dest_mo g_hash_table_foreach ( vtl->tracks, (GHFunc) track_convert, &dest_mode ); } } + +VikWaypoint *vik_trw_layer_get_waypoint ( VikTrwLayer *vtl, gchar *name ) +{ + return g_hash_table_lookup ( vtl->waypoints, name ); +} + +VikTrack *vik_trw_layer_get_track ( VikTrwLayer *vtl, gchar *name ) +{ + return g_hash_table_lookup ( vtl->tracks, name ); +}