X-Git-Url: https://git.street.me.uk/andy/viking.git/blobdiff_plain/b1453c161366d6f7a95dfe7e96cf62f5b7d8bb02..ec84f3a6395b3a3c672f0572841ed6eda8ee828a:/src/viktrwlayer.c diff --git a/src/viktrwlayer.c b/src/viktrwlayer.c index 3634fc67..c8220d6c 100644 --- a/src/viktrwlayer.c +++ b/src/viktrwlayer.c @@ -77,17 +77,18 @@ #define GOOGLE_DIRECTIONS_STRING "maps.google.com/maps?q=from:%s,%s+to:%s,%s&output=js" #endif -#define VIK_TRW_LAYER_TRACK_GC 5 +#define VIK_TRW_LAYER_TRACK_GC 6 #define VIK_TRW_LAYER_TRACK_GCS 10 #define VIK_TRW_LAYER_TRACK_GC_BLACK 0 #define VIK_TRW_LAYER_TRACK_GC_SLOW 1 #define VIK_TRW_LAYER_TRACK_GC_AVER 2 #define VIK_TRW_LAYER_TRACK_GC_FAST 3 #define VIK_TRW_LAYER_TRACK_GC_STOP 4 +#define VIK_TRW_LAYER_TRACK_GC_SINGLE 5 #define DRAWMODE_BY_TRACK 0 #define DRAWMODE_BY_SPEED 1 -#define DRAWMODE_ALL_BLACK 2 +#define DRAWMODE_ALL_SAME_COLOR 2 // Note using DRAWMODE_BY_SPEED may be slow especially for vast numbers of trackpoints // as we are (re)calculating the colour for every point @@ -148,6 +149,7 @@ struct _VikTrwLayer { gdouble track_draw_speed_factor; GArray *track_gc; GdkGC *track_1color_gc; + GdkColor track_color; GdkGC *current_track_gc; // Separate GC for a track's potential new point as drawn via separate method // (compared to the actual track points drawn in the main trw_layer_draw_track function) @@ -217,6 +219,7 @@ typedef struct { struct DrawingParams { VikViewport *vp; VikTrwLayer *vtl; + VikWindow *vw; gdouble xmpp, ympp; guint16 width, height; gdouble cc; // Cosine factor in track directions @@ -232,15 +235,15 @@ static void trw_layer_delete_item ( gpointer pass_along[6] ); static void trw_layer_copy_item_cb ( gpointer pass_along[6] ); static void trw_layer_cut_item_cb ( gpointer pass_along[6] ); -static void trw_layer_find_maxmin_waypoints ( const gchar *name, const VikWaypoint *w, struct LatLon maxmin[2] ); -static void trw_layer_find_maxmin_tracks ( const gchar *name, const VikTrack *trk, struct LatLon maxmin[2] ); +static void trw_layer_find_maxmin_waypoints ( const gpointer id, const VikWaypoint *w, struct LatLon maxmin[2] ); +static void trw_layer_find_maxmin_tracks ( const gpointer id, const VikTrack *trk, struct LatLon maxmin[2] ); static void trw_layer_find_maxmin (VikTrwLayer *vtl, struct LatLon maxmin[2]); static void trw_layer_new_track_gcs ( VikTrwLayer *vtl, VikViewport *vp ); static void trw_layer_free_track_gcs ( VikTrwLayer *vtl ); -static void trw_layer_draw_track_cb ( const gchar *name, VikTrack *track, struct DrawingParams *dp ); -static void trw_layer_draw_waypoint ( const gchar *name, VikWaypoint *wp, struct DrawingParams *dp ); +static void trw_layer_draw_track_cb ( const gpointer id, VikTrack *track, struct DrawingParams *dp ); +static void trw_layer_draw_waypoint ( const gpointer id, VikWaypoint *wp, struct DrawingParams *dp ); static void goto_coord ( gpointer *vlp, gpointer vvp, gpointer vl, const VikCoord *coord ); static void trw_layer_goto_track_startpoint ( gpointer pass_along[6] ); @@ -293,6 +296,7 @@ static void trw_layer_acquire_google_cb ( gpointer lav[2] ); #endif #ifdef VIK_CONFIG_OPENSTREETMAP static void trw_layer_acquire_osm_cb ( gpointer lav[2] ); +static void trw_layer_acquire_osm_my_traces_cb ( gpointer lav[2] ); #endif #ifdef VIK_CONFIG_GEOCACHES static void trw_layer_acquire_geocache_cb ( gpointer lav[2] ); @@ -307,12 +311,14 @@ static void trw_layer_gps_upload ( gpointer lav[2] ); // Most track handling functions can handle operating on the route list // However these ones are easier in separate functions static void trw_layer_auto_routes_view ( gpointer lav[2] ); +static void trw_layer_delete_all_routes ( gpointer lav[2] ); static void trw_layer_delete_routes_from_selection ( gpointer lav[2] ); /* pop-up items */ static void trw_layer_properties_item ( gpointer pass_along[7] ); static void trw_layer_goto_waypoint ( gpointer pass_along[6] ); static void trw_layer_waypoint_gc_webpage ( gpointer pass_along[6] ); +static void trw_layer_waypoint_webpage ( gpointer pass_along[6] ); static void trw_layer_realize_waypoint ( gpointer id, VikWaypoint *wp, gpointer pass_along[5] ); static void trw_layer_realize_track ( gpointer id, VikTrack *track, gpointer pass_along[5] ); @@ -354,7 +360,7 @@ static VikTrackpoint *closest_tp_in_five_pixel_interval ( VikTrwLayer *vtl, VikV static VikWaypoint *closest_wp_in_five_pixel_interval ( VikTrwLayer *vtl, VikViewport *vvp, gint x, gint y ); static void waypoint_convert ( const gpointer id, VikWaypoint *wp, VikCoordMode *dest_mode ); -static void track_convert ( const gchar *name, VikTrack *tr, VikCoordMode *dest_mode ); +static void track_convert ( const gpointer id, VikTrack *tr, VikCoordMode *dest_mode ); static gchar *highest_wp_number_get(VikTrwLayer *vtl); static void highest_wp_number_reset(VikTrwLayer *vtl); @@ -422,14 +428,26 @@ static VikToolInterface trw_layer_tools[] = { GDK_CURSOR_IS_PIXMAP, &cursor_route_finder_pixbuf }, #endif }; -enum { TOOL_CREATE_WAYPOINT=0, TOOL_CREATE_TRACK, TOOL_CREATE_ROUTE, TOOL_EDIT_WAYPOINT, TOOL_EDIT_TRACKPOINT, TOOL_SHOW_PICTURE, NUM_TOOLS }; + +enum { + TOOL_CREATE_WAYPOINT=0, + TOOL_CREATE_TRACK, + TOOL_CREATE_ROUTE, + TOOL_EDIT_WAYPOINT, + TOOL_EDIT_TRACKPOINT, + TOOL_SHOW_PICTURE, +#ifdef VIK_CONFIG_GOOGLE + TOOL_ROUTE_FINDER, +#endif + NUM_TOOLS +}; /****** PARAMETERS ******/ static gchar *params_groups[] = { N_("Waypoints"), N_("Tracks"), N_("Waypoint Images") }; enum { GROUP_WAYPOINTS, GROUP_TRACKS, GROUP_IMAGES }; -static gchar *params_drawmodes[] = { N_("Draw by Track"), N_("Draw by Speed"), N_("All Tracks Black"), 0 }; +static gchar *params_drawmodes[] = { N_("Draw by Track"), N_("Draw by Speed"), N_("All Tracks Same Color"), NULL }; static gchar *params_wpsymbols[] = { N_("Filled Square"), N_("Square"), N_("Circle"), N_("X"), 0 }; #define MIN_POINT_SIZE 2 @@ -466,41 +484,45 @@ static gchar* params_font_sizes[] = { NULL }; VikLayerParam trw_layer_params[] = { - { "tracks_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES }, - { "waypoints_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES }, - { "routes_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES }, - - { "drawmode", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track Drawing Mode:"), VIK_LAYER_WIDGET_RADIOGROUP, NULL }, - { "drawlines", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Track Lines"), VIK_LAYER_WIDGET_CHECKBUTTON }, - { "line_thickness", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track Thickness:"), VIK_LAYER_WIDGET_SPINBUTTON, params_scales + 0 }, - { "drawdirections", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Track Direction"), VIK_LAYER_WIDGET_CHECKBUTTON }, - { "trkdirectionsize", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Direction Size:"), VIK_LAYER_WIDGET_SPINBUTTON, params_scales + 11 }, - { "drawpoints", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Trackpoints"), VIK_LAYER_WIDGET_CHECKBUTTON }, - { "trkpointsize", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Trackpoint Size:"), VIK_LAYER_WIDGET_SPINBUTTON, params_scales + 10 }, - { "drawelevation", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Elevation"), VIK_LAYER_WIDGET_CHECKBUTTON }, - { "elevation_factor", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Draw Elevation Height %:"), VIK_LAYER_WIDGET_HSCALE, params_scales + 9 }, - - { "drawstops", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Stops"), VIK_LAYER_WIDGET_CHECKBUTTON }, - { "stop_length", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Min Stop Length (seconds):"), VIK_LAYER_WIDGET_SPINBUTTON, params_scales + 8 }, - - { "bg_line_thickness", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track BG Thickness:"), VIK_LAYER_WIDGET_SPINBUTTON, params_scales + 6 }, - { "trackbgcolor", VIK_LAYER_PARAM_COLOR, GROUP_TRACKS, N_("Track Background Color"), VIK_LAYER_WIDGET_COLOR, 0 }, - { "speed_factor", VIK_LAYER_PARAM_DOUBLE, GROUP_TRACKS, N_("Draw by Speed Factor (%):"), VIK_LAYER_WIDGET_HSCALE, params_scales + 1 }, - - { "drawlabels", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, N_("Draw Labels"), VIK_LAYER_WIDGET_CHECKBUTTON }, - { "wpfontsize", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint Font Size:"), VIK_LAYER_WIDGET_COMBOBOX, params_font_sizes, NULL }, - { "wpcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Waypoint Color:"), VIK_LAYER_WIDGET_COLOR, 0 }, - { "wptextcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Waypoint Text:"), VIK_LAYER_WIDGET_COLOR, 0 }, - { "wpbgcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Background:"), VIK_LAYER_WIDGET_COLOR, 0 }, - { "wpbgand", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, N_("Fake BG Color Translucency:"), VIK_LAYER_WIDGET_CHECKBUTTON, 0 }, - { "wpsymbol", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint marker:"), VIK_LAYER_WIDGET_RADIOGROUP, NULL }, - { "wpsize", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint size:"), VIK_LAYER_WIDGET_SPINBUTTON, params_scales + 7 }, - { "wpsyms", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, N_("Draw Waypoint Symbols:"), VIK_LAYER_WIDGET_CHECKBUTTON }, - - { "drawimages", VIK_LAYER_PARAM_BOOLEAN, GROUP_IMAGES, N_("Draw Waypoint Images"), VIK_LAYER_WIDGET_CHECKBUTTON }, - { "image_size", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, N_("Image Size (pixels):"), VIK_LAYER_WIDGET_HSCALE, params_scales + 3 }, - { "image_alpha", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, N_("Image Alpha:"), VIK_LAYER_WIDGET_HSCALE, params_scales + 4 }, - { "image_cache_size", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, N_("Image Memory Cache Size:"), VIK_LAYER_WIDGET_HSCALE, params_scales + 5 }, + { "tracks_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL }, + { "waypoints_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL }, + { "routes_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL }, + + { "drawmode", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track Drawing Mode:"), VIK_LAYER_WIDGET_COMBOBOX, params_drawmodes, NULL, NULL }, + { "trackcolor", VIK_LAYER_PARAM_COLOR, GROUP_TRACKS, N_("All Tracks Color:"), VIK_LAYER_WIDGET_COLOR, NULL, NULL, + N_("The color used when 'All Tracks Same Color' drawing mode is selected") }, + { "drawlines", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Track Lines"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL }, + { "line_thickness", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track Thickness:"), VIK_LAYER_WIDGET_SPINBUTTON, ¶ms_scales[0], NULL, NULL }, + { "drawdirections", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Track Direction"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL }, + { "trkdirectionsize", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Direction Size:"), VIK_LAYER_WIDGET_SPINBUTTON, ¶ms_scales[11], NULL, NULL }, + { "drawpoints", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Trackpoints"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL }, + { "trkpointsize", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Trackpoint Size:"), VIK_LAYER_WIDGET_SPINBUTTON, ¶ms_scales[10], NULL, NULL }, + { "drawelevation", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Elevation"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL }, + { "elevation_factor", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Draw Elevation Height %:"), VIK_LAYER_WIDGET_HSCALE, ¶ms_scales[9], NULL, NULL }, + + { "drawstops", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Stops"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, + N_("Whether to draw a marker when trackpoints are at the same position but over the minimum stop length apart in time") }, + { "stop_length", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Min Stop Length (seconds):"), VIK_LAYER_WIDGET_SPINBUTTON, ¶ms_scales[8], NULL, NULL }, + + { "bg_line_thickness", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track BG Thickness:"), VIK_LAYER_WIDGET_SPINBUTTON, ¶ms_scales[6], NULL, NULL}, + { "trackbgcolor", VIK_LAYER_PARAM_COLOR, GROUP_TRACKS, N_("Track Background Color"), VIK_LAYER_WIDGET_COLOR, NULL, NULL, NULL }, + { "speed_factor", VIK_LAYER_PARAM_DOUBLE, GROUP_TRACKS, N_("Draw by Speed Factor (%):"), VIK_LAYER_WIDGET_HSCALE, ¶ms_scales[1], NULL, + N_("The percentage factor away from the average speed determining the color used") }, + + { "drawlabels", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, N_("Draw Labels"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL }, + { "wpfontsize", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint Font Size:"), VIK_LAYER_WIDGET_COMBOBOX, params_font_sizes, NULL, NULL }, + { "wpcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Waypoint Color:"), VIK_LAYER_WIDGET_COLOR, NULL, NULL, NULL }, + { "wptextcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Waypoint Text:"), VIK_LAYER_WIDGET_COLOR, NULL, NULL, NULL }, + { "wpbgcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Background:"), VIK_LAYER_WIDGET_COLOR, NULL, NULL, NULL }, + { "wpbgand", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, N_("Fake BG Color Translucency:"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL }, + { "wpsymbol", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint marker:"), VIK_LAYER_WIDGET_COMBOBOX, params_wpsymbols, NULL, NULL }, + { "wpsize", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint size:"), VIK_LAYER_WIDGET_SPINBUTTON, ¶ms_scales[7], NULL, NULL }, + { "wpsyms", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, N_("Draw Waypoint Symbols:"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL }, + + { "drawimages", VIK_LAYER_PARAM_BOOLEAN, GROUP_IMAGES, N_("Draw Waypoint Images"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL }, + { "image_size", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, N_("Image Size (pixels):"), VIK_LAYER_WIDGET_HSCALE, ¶ms_scales[3], NULL, NULL }, + { "image_alpha", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, N_("Image Alpha:"), VIK_LAYER_WIDGET_HSCALE, ¶ms_scales[4], NULL, NULL }, + { "image_cache_size", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, N_("Image Memory Cache Size:"), VIK_LAYER_WIDGET_HSCALE, ¶ms_scales[5], NULL, NULL }, }; // ENUMERATION MUST BE IN THE SAME ORDER AS THE NAMED PARAMS ABOVE @@ -511,6 +533,7 @@ enum { PARAM_RV, // Tracks PARAM_DM, + PARAM_TC, PARAM_DL, PARAM_LT, PARAM_DD, @@ -642,12 +665,6 @@ VikLayerInterface vik_trw_layer_interface = { (VikLayerFuncSelectedViewportMenu) trw_layer_show_selected_viewport_menu, }; -// for copy & paste -typedef struct { - guint len; - guint8 data[0]; -} FlatItem; - GType vik_trw_layer_get_type () { static GType vtl_type = 0; @@ -761,7 +778,6 @@ static void trw_layer_paste_item_cb ( gpointer pass_along[6]) static void trw_layer_copy_item ( VikTrwLayer *vtl, gint subtype, gpointer sublayer, guint8 **item, guint *len ) { - FlatItem *fi; guint8 *id; guint il; @@ -770,44 +786,36 @@ static void trw_layer_copy_item ( VikTrwLayer *vtl, gint subtype, gpointer subla return; } - if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT ) - { + GByteArray *ba = g_byte_array_new (); + + if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT ) { vik_waypoint_marshall ( g_hash_table_lookup ( vtl->waypoints, sublayer ), &id, &il ); - // 'Simple' memory copy of byte array from the marshalling above - *len = sizeof(FlatItem) + 1 + il; // not sure what the 1 is for yet... - fi = g_malloc ( *len ); - fi->len = *len; - memcpy(fi->data, id, il); } else if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK ) { vik_track_marshall ( g_hash_table_lookup ( vtl->tracks, sublayer ), &id, &il ); - // less magic than before... - *len = sizeof(FlatItem) + 1 + il; - fi = g_malloc ( *len ); - fi->len = *len; - memcpy(fi->data, id, il); } else { vik_track_marshall ( g_hash_table_lookup ( vtl->routes, sublayer ), &id, &il ); - // less magic than before... - *len = sizeof(FlatItem) + 1 + il; - fi = g_malloc ( *len ); - fi->len = *len; - memcpy(fi->data, id, il); } + g_byte_array_append ( ba, id, il ); + g_free(id); - *item = (guint8 *)fi; + + *len = ba->len; + *item = ba->data; } static gboolean trw_layer_paste_item ( VikTrwLayer *vtl, gint subtype, guint8 *item, guint len ) { - FlatItem *fi = (FlatItem *) item; + if ( !item ) + return FALSE; + + gchar *name; - if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT && fi ) + if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT ) { VikWaypoint *w; - gchar *name; - w = vik_waypoint_unmarshall(fi->data, fi->len); + w = vik_waypoint_unmarshall ( item, len ); // When copying - we'll create a new name based on the original name = trw_layer_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_WAYPOINT, w->name); vik_trw_layer_add_waypoint ( vtl, name, w ); @@ -815,15 +823,14 @@ static gboolean trw_layer_paste_item ( VikTrwLayer *vtl, gint subtype, guint8 *i // Consider if redraw necessary for the new item if ( vtl->vl.visible && vtl->waypoints_visible && w->visible ) - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); return TRUE; } - if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK && fi ) + if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK ) { VikTrack *t; - gchar *name; - t = vik_track_unmarshall(fi->data, fi->len); + t = vik_track_unmarshall ( item, len ); // When copying - we'll create a new name based on the original name = trw_layer_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, t->name); vik_trw_layer_add_track ( vtl, name, t ); @@ -831,15 +838,14 @@ static gboolean trw_layer_paste_item ( VikTrwLayer *vtl, gint subtype, guint8 *i // Consider if redraw necessary for the new item if ( vtl->vl.visible && vtl->tracks_visible && t->visible ) - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); return TRUE; } - if ( subtype == VIK_TRW_LAYER_SUBLAYER_ROUTE && fi ) + if ( subtype == VIK_TRW_LAYER_SUBLAYER_ROUTE ) { VikTrack *t; - gchar *name; - t = vik_track_unmarshall(fi->data, fi->len); + t = vik_track_unmarshall ( item, len ); // When copying - we'll create a new name based on the original name = trw_layer_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_ROUTE, t->name); vik_trw_layer_add_route ( vtl, name, t ); @@ -847,7 +853,7 @@ static gboolean trw_layer_paste_item ( VikTrwLayer *vtl, gint subtype, guint8 *i // Consider if redraw necessary for the new item if ( vtl->vl.visible && vtl->routes_visible && t->visible ) - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); return TRUE; } return FALSE; @@ -868,6 +874,10 @@ static gboolean trw_layer_set_param ( VikTrwLayer *vtl, guint16 id, VikLayerPara case PARAM_WV: vtl->waypoints_visible = data.b; break; case PARAM_RV: vtl->routes_visible = data.b; break; case PARAM_DM: vtl->drawmode = data.u; break; + case PARAM_TC: + vtl->track_color = data.c; + trw_layer_new_track_gcs ( vtl, vp ); + break; case PARAM_DP: vtl->drawpoints = data.b; break; case PARAM_DPS: if ( data.u >= MIN_POINT_SIZE && data.u <= MAX_POINT_SIZE ) @@ -893,7 +903,7 @@ static gboolean trw_layer_set_param ( VikTrwLayer *vtl, guint16 id, VikLayerPara trw_layer_new_track_gcs ( vtl, vp ); } break; - case PARAM_BLT: if ( data.u >= 0 && data.u <= 8 && data.u != vtl->bg_line_thickness ) + case PARAM_BLT: if ( data.u <= 8 && data.u != vtl->bg_line_thickness ) { vtl->bg_line_thickness = data.u; trw_layer_new_track_gcs ( vtl, vp ); @@ -937,6 +947,7 @@ static VikLayerParamData trw_layer_get_param ( VikTrwLayer *vtl, guint16 id, gbo case PARAM_WV: rv.b = vtl->waypoints_visible; break; case PARAM_RV: rv.b = vtl->routes_visible; break; case PARAM_DM: rv.u = vtl->drawmode; break; + case PARAM_TC: rv.c = vtl->track_color; break; case PARAM_DP: rv.b = vtl->drawpoints; break; case PARAM_DPS: rv.u = vtl->drawpoints_size; break; case PARAM_DE: rv.b = vtl->drawelevation; break; @@ -970,58 +981,126 @@ static VikLayerParamData trw_layer_get_param ( VikTrwLayer *vtl, guint16 id, gbo static void trw_layer_marshall( VikTrwLayer *vtl, guint8 **data, gint *len ) { guint8 *pd; - gchar *dd; - gsize dl; gint pl; - gchar *tmpname; - FILE *f; *data = NULL; - if ((f = fdopen(g_file_open_tmp (NULL, &tmpname, NULL), "r+"))) { - a_gpx_write_file(vtl, f, NULL); - vik_layer_marshall_params(VIK_LAYER(vtl), &pd, &pl); - fclose(f); - f = NULL; - g_file_get_contents(tmpname, &dd, &dl, NULL); - *len = sizeof(pl) + pl + dl; - *data = g_malloc(*len); - memcpy(*data, &pl, sizeof(pl)); - memcpy(*data + sizeof(pl), pd, pl); - memcpy(*data + sizeof(pl) + pl, dd, dl); - - g_free(pd); - g_free(dd); - g_remove(tmpname); - g_free(tmpname); + // Use byte arrays to store sublayer data + // much like done elsewhere e.g. vik_layer_marshall_params() + GByteArray *ba = g_byte_array_new ( ); + + guint8 *sl_data; + guint sl_len; + + guint object_length; + guint subtype; + // store: + // the length of the item + // the sublayer type of item + // the the actual item +#define tlm_append(object_pointer, size, type) \ + subtype = (type); \ + object_length = (size); \ + g_byte_array_append ( ba, (guint8 *)&object_length, sizeof(object_length) ); \ + g_byte_array_append ( ba, (guint8 *)&subtype, sizeof(subtype) ); \ + g_byte_array_append ( ba, (object_pointer), object_length ); + + // Layer parameters first + vik_layer_marshall_params(VIK_LAYER(vtl), &pd, &pl); + g_byte_array_append ( ba, (guint8 *)&pl, sizeof(pl) ); \ + g_byte_array_append ( ba, pd, pl ); + g_free ( pd ); + + // Now sublayer data + GHashTableIter iter; + gpointer key, value; + + // Waypoints + g_hash_table_iter_init ( &iter, vtl->waypoints ); + while ( g_hash_table_iter_next (&iter, &key, &value) ) { + vik_waypoint_marshall ( VIK_WAYPOINT(value), &sl_data, &sl_len ); + tlm_append ( sl_data, sl_len, VIK_TRW_LAYER_SUBLAYER_WAYPOINT ); + g_free ( sl_data ); + } + + // Tracks + g_hash_table_iter_init ( &iter, vtl->tracks ); + while ( g_hash_table_iter_next (&iter, &key, &value) ) { + vik_track_marshall ( VIK_TRACK(value), &sl_data, &sl_len ); + tlm_append ( sl_data, sl_len, VIK_TRW_LAYER_SUBLAYER_TRACK ); + g_free ( sl_data ); + } + + // Routes + g_hash_table_iter_init ( &iter, vtl->routes ); + while ( g_hash_table_iter_next (&iter, &key, &value) ) { + vik_track_marshall ( VIK_TRACK(value), &sl_data, &sl_len ); + tlm_append ( sl_data, sl_len, VIK_TRW_LAYER_SUBLAYER_ROUTE ); + g_free ( sl_data ); } + +#undef tlm_append + + *data = ba->data; + *len = ba->len; } static VikTrwLayer *trw_layer_unmarshall( guint8 *data, gint len, VikViewport *vvp ) { - VikTrwLayer *rv = VIK_TRW_LAYER(vik_layer_create ( VIK_LAYER_TRW, vvp, NULL, FALSE )); + VikTrwLayer *vtl = VIK_TRW_LAYER(vik_layer_create ( VIK_LAYER_TRW, vvp, NULL, FALSE )); gint pl; - gchar *tmpname; - FILE *f; - + gint consumed_length; + // First the overall layer parameters memcpy(&pl, data, sizeof(pl)); data += sizeof(pl); - vik_layer_unmarshall_params ( VIK_LAYER(rv), data, pl, vvp ); + vik_layer_unmarshall_params ( VIK_LAYER(vtl), data, pl, vvp ); data += pl; - if (!(f = fdopen(g_file_open_tmp (NULL, &tmpname, NULL), "r+"))) { - g_critical("couldn't open temp file"); - exit(1); - } - fwrite(data, len - pl - sizeof(pl), 1, f); - rewind(f); - a_gpx_read_file(rv, f); - fclose(f); - f = NULL; - g_remove(tmpname); - g_free(tmpname); - return rv; + consumed_length = pl; + const gint sizeof_len_and_subtype = sizeof(gint) + sizeof(gint); + +#define tlm_size (*(gint *)data) + // See marshalling above for order of how this is written +#define tlm_next \ + data += sizeof_len_and_subtype + tlm_size; + + // Now the individual sublayers: + + while ( *data && consumed_length < len ) { + // Normally four extra bytes at the end of the datastream + // (since it's a GByteArray and that's where it's length is stored) + // So only attempt read when there's an actual block of sublayer data + if ( consumed_length + tlm_size < len ) { + + // Reuse pl to read the subtype from the data stream + memcpy(&pl, data+sizeof(gint), sizeof(pl)); + + if ( pl == VIK_TRW_LAYER_SUBLAYER_TRACK ) { + VikTrack *trk = vik_track_unmarshall ( data + sizeof_len_and_subtype, 0 ); + gchar *name = g_strdup ( trk->name ); + vik_trw_layer_add_track ( vtl, name, trk ); + g_free ( name ); + } + if ( pl == VIK_TRW_LAYER_SUBLAYER_WAYPOINT ) { + VikWaypoint *wp = vik_waypoint_unmarshall ( data + sizeof_len_and_subtype, 0 ); + gchar *name = g_strdup ( wp->name ); + vik_trw_layer_add_waypoint ( vtl, name, wp ); + g_free ( name ); + } + if ( pl == VIK_TRW_LAYER_SUBLAYER_ROUTE ) { + VikTrack *trk = vik_track_unmarshall ( data + sizeof_len_and_subtype, 0 ); + gchar *name = g_strdup ( trk->name ); + vik_trw_layer_add_route ( vtl, name, trk ); + g_free ( name ); + } + } + consumed_length += tlm_size + sizeof_len_and_subtype; + tlm_next; + } + //g_debug ("consumed_length %d vs len %d", consumed_length, len); + + return vtl; } // Keep interesting hash function at least visible @@ -1051,11 +1130,6 @@ static guint strcase_hash(gconstpointer v) static VikTrwLayer* trw_layer_new ( gint drawmode ) { - if (trw_layer_params[PARAM_DM].widget_data == NULL) - trw_layer_params[PARAM_DM].widget_data = str_array_to_glist(params_drawmodes); - if (trw_layer_params[PARAM_WPSYM].widget_data == NULL) - trw_layer_params[PARAM_WPSYM].widget_data = str_array_to_glist(params_wpsymbols); - VikTrwLayer *rv = VIK_TRW_LAYER ( g_object_new ( VIK_TRW_LAYER_TYPE, NULL ) ); vik_layer_set_type ( VIK_LAYER(rv), VIK_LAYER_TRW ); @@ -1142,12 +1216,13 @@ static void init_drawing_params ( struct DrawingParams *dp, VikTrwLayer *vtl, Vi { dp->vtl = vtl; dp->vp = vp; + dp->vw = (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl); dp->xmpp = vik_viewport_get_xmpp ( vp ); dp->ympp = vik_viewport_get_ympp ( vp ); dp->width = vik_viewport_get_width ( vp ); dp->height = vik_viewport_get_height ( vp ); - dp->cc = vtl->drawdirections_size*cos(45 * DEG2RAD); // Calculate once per vtl update - even if not used - dp->ss = vtl->drawdirections_size*sin(45 * DEG2RAD); // Calculate once per vtl update - even if not used + dp->cc = vtl->drawdirections_size*cos(DEG2RAD(45)); // Calculate once per vtl update - even if not used + dp->ss = vtl->drawdirections_size*sin(DEG2RAD(45)); // Calculate once per vtl update - even if not used dp->center = vik_viewport_get_center ( vp ); dp->one_zone = vik_viewport_is_one_zone ( vp ); /* false if some other projection besides UTM */ @@ -1209,7 +1284,7 @@ static void draw_utm_skip_insignia ( VikViewport *vvp, GdkGC *gc, gint x, gint y vik_viewport_draw_line ( vvp, gc, x+5, y-5, x-5, y+5 ); } -static void trw_layer_draw_track ( const gchar *name, VikTrack *track, struct DrawingParams *dp, gboolean draw_track_outline ) +static void trw_layer_draw_track ( const gpointer id, VikTrack *track, struct DrawingParams *dp, gboolean draw_track_outline ) { /* TODO: this function is a mess, get rid of any redundancy */ GList *list = track->trackpoints; @@ -1237,7 +1312,7 @@ static void trw_layer_draw_track ( const gchar *name, VikTrack *track, struct Dr /* admittedly this is not an efficient way to do it because we go through the whole GC thing all over... */ if ( dp->vtl->bg_line_thickness && !draw_track_outline ) - trw_layer_draw_track ( name, track, dp, TRUE ); + trw_layer_draw_track ( id, track, dp, TRUE ); if ( draw_track_outline ) drawpoints = drawstops = FALSE; @@ -1256,10 +1331,10 @@ static void trw_layer_draw_track ( const gchar *name, VikTrack *track, struct Dr /* if track is member of selected layer or is the current selected track then draw in the highlight colour. NB this supercedes the drawmode */ - if ( dp->vtl && ( ( dp->vtl == vik_window_get_selected_trw_layer ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ) || - ( !track->is_route && ( dp->vtl->tracks == vik_window_get_selected_tracks ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ) ) || - ( track->is_route && ( dp->vtl->routes == vik_window_get_selected_tracks ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ) ) || - track == vik_window_get_selected_track ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ) ) { + if ( ( dp->vtl == vik_window_get_selected_trw_layer ( dp->vw ) ) || + ( !track->is_route && ( dp->vtl->tracks == vik_window_get_selected_tracks ( dp->vw ) ) ) || + ( track->is_route && ( dp->vtl->routes == vik_window_get_selected_tracks ( dp->vw ) ) ) || + ( track == vik_window_get_selected_track ( dp->vw ) ) ) { main_gc = vik_viewport_get_gc_highlight (dp->vp); drawing_highlight = TRUE; } @@ -1274,9 +1349,9 @@ static void trw_layer_draw_track ( const gchar *name, VikTrack *track, struct Dr main_gc = dp->vtl->track_1color_gc; break; default: - // Mostly for DRAWMODE_ALL_BLACK + // Mostly for DRAWMODE_ALL_SAME_COLOR // but includes DRAWMODE_BY_SPEED, main_gc is set later on as necessary - main_gc = g_array_index(dp->vtl->track_gc, GdkGC *, VIK_TRW_LAYER_TRACK_GC_BLACK); + main_gc = g_array_index(dp->vtl->track_gc, GdkGC *, VIK_TRW_LAYER_TRACK_GC_SINGLE); break; } } @@ -1474,9 +1549,9 @@ static void trw_layer_draw_track ( const gchar *name, VikTrack *track, struct Dr } /* the only reason this exists is so that trw_layer_draw_track can first call itself to draw the white track background */ -static void trw_layer_draw_track_cb ( const gchar *name, VikTrack *track, struct DrawingParams *dp ) +static void trw_layer_draw_track_cb ( const gpointer id, VikTrack *track, struct DrawingParams *dp ) { - trw_layer_draw_track ( name, track, dp, FALSE ); + trw_layer_draw_track ( id, track, dp, FALSE ); } static void cached_pixbuf_free ( CachedPixbuf *cp ) @@ -1490,7 +1565,7 @@ static gint cached_pixbuf_cmp ( CachedPixbuf *cp, const gchar *name ) return strcmp ( cp->image, name ); } -static void trw_layer_draw_waypoint ( const gchar *name, VikWaypoint *wp, struct DrawingParams *dp ) +static void trw_layer_draw_waypoint ( const gpointer id, VikWaypoint *wp, struct DrawingParams *dp ) { if ( wp->visible ) if ( (!dp->one_zone && !dp->lat_lon) || ( ( dp->lat_lon || wp->coord.utm_zone == dp->center->utm_zone ) && @@ -1562,9 +1637,9 @@ static void trw_layer_draw_waypoint ( const gchar *name, VikWaypoint *wp, struct if ( x+(w/2) > 0 && y+(h/2) > 0 && x-(w/2) < dp->width && y-(h/2) < dp->height ) /* always draw within boundaries */ { if ( vik_viewport_get_draw_highlight ( dp->vp ) ) { - if ( dp->vtl == vik_window_get_selected_trw_layer ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) || - dp->vtl->waypoints == vik_window_get_selected_waypoints ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) || - wp == vik_window_get_selected_waypoint ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ) { + if ( dp->vtl == vik_window_get_selected_trw_layer ( dp->vw ) || + dp->vtl->waypoints == vik_window_get_selected_waypoints ( dp->vw ) || + wp == vik_window_get_selected_waypoint ( dp->vw ) ) { // Highlighted - so draw a little border around the chosen one // single line seems a little weak so draw 2 of them vik_viewport_draw_rectangle (dp->vp, vik_viewport_get_gc_highlight (dp->vp), FALSE, @@ -1644,9 +1719,9 @@ static void trw_layer_draw_waypoint ( const gchar *name, VikWaypoint *wp, struct /* if highlight mode on, then draw background text in highlight colour */ if ( vik_viewport_get_draw_highlight ( dp->vp ) ) { - if ( dp->vtl == vik_window_get_selected_trw_layer ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) || - dp->vtl->waypoints == vik_window_get_selected_waypoints ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) || - wp == vik_window_get_selected_waypoint ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ) + if ( dp->vtl == vik_window_get_selected_trw_layer ( dp->vw ) || + dp->vtl->waypoints == vik_window_get_selected_waypoints ( dp->vw ) || + wp == vik_window_get_selected_waypoint ( dp->vw ) ) vik_viewport_draw_rectangle ( dp->vp, vik_viewport_get_gc_highlight (dp->vp), TRUE, label_x - 1, label_y-1,width+2,height+2); else vik_viewport_draw_rectangle ( dp->vp, dp->vtl->waypoint_bg_gc, TRUE, label_x - 1, label_y-1,width+2,height+2); @@ -1744,6 +1819,8 @@ static void trw_layer_new_track_gcs ( VikTrwLayer *vtl, VikViewport *vp ) gc[VIK_TRW_LAYER_TRACK_GC_AVER] = vik_viewport_new_gc ( vp, "#D2CD26", width ); // yellow-ish gc[VIK_TRW_LAYER_TRACK_GC_FAST] = vik_viewport_new_gc ( vp, "#2B8700", width ); // green-ish + gc[VIK_TRW_LAYER_TRACK_GC_SINGLE] = vik_viewport_new_gc_from_color ( vp, &(vtl->track_color), width ); + g_array_append_vals ( vtl->track_gc, gc, VIK_TRW_LAYER_TRACK_GC ); } @@ -1760,6 +1837,8 @@ static VikTrwLayer* trw_layer_create ( VikViewport *vp ) rv->wplabellayout = gtk_widget_create_pango_layout (GTK_WIDGET(vp), NULL); pango_layout_set_font_description (rv->wplabellayout, GTK_WIDGET(vp)->style->font_desc); + gdk_color_parse ( "#000000", &(rv->track_color) ); // Black + trw_layer_new_track_gcs ( rv, vp ); rv->waypoint_gc = vik_viewport_new_gc ( vp, "#000000", 2 ); @@ -2418,7 +2497,7 @@ VikTrack *vik_trw_layer_get_route ( VikTrwLayer *vtl, const gchar *name ) return g_hash_table_find ( vtl->routes, (GHRFunc) trw_layer_track_find, (gpointer) name ); } -static void trw_layer_find_maxmin_waypoints ( const gchar *name, const VikWaypoint *w, struct LatLon maxmin[2] ) +static void trw_layer_find_maxmin_waypoints ( const gpointer id, const VikWaypoint *w, struct LatLon maxmin[2] ) { static VikCoord fixme; vik_coord_copy_convert ( &(w->coord), VIK_COORD_LATLON, &fixme ); @@ -2432,7 +2511,7 @@ static void trw_layer_find_maxmin_waypoints ( const gchar *name, const VikWaypoi maxmin[1].lon = VIK_LATLON(&fixme)->lon; } -static void trw_layer_find_maxmin_tracks ( const gchar *name, const VikTrack *trk, struct LatLon maxmin[2] ) +static void trw_layer_find_maxmin_tracks ( const gpointer id, const VikTrack *trk, struct LatLon maxmin[2] ) { GList *tr = trk->trackpoints; static VikCoord fixme; @@ -2798,35 +2877,16 @@ gboolean vik_trw_layer_new_waypoint ( VikTrwLayer *vtl, GtkWindow *w, const VikC static void trw_layer_new_wikipedia_wp_viewport ( gpointer lav[2] ) { - VikCoord one, two; - struct LatLon one_ll, two_ll; struct LatLon maxmin[2] = { {0.0,0.0}, {0.0,0.0} }; - VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]); VikLayersPanel *vlp = VIK_LAYERS_PANEL(lav[1]); VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl)); VikViewport *vvp = vik_window_viewport(vw); - vik_viewport_screen_to_coord ( vvp, 0, 0, &one); - vik_viewport_screen_to_coord ( vvp, vik_viewport_get_width(vvp), vik_viewport_get_height(vvp), &two); - vik_coord_to_latlon(&one, &one_ll); - vik_coord_to_latlon(&two, &two_ll); - if (one_ll.lat > two_ll.lat) { - maxmin[0].lat = one_ll.lat; - maxmin[1].lat = two_ll.lat; - } - else { - maxmin[0].lat = two_ll.lat; - maxmin[1].lat = one_ll.lat; - } - if (one_ll.lon > two_ll.lon) { - maxmin[0].lon = one_ll.lon; - maxmin[1].lon = two_ll.lon; - } - else { - maxmin[0].lon = two_ll.lon; - maxmin[1].lon = one_ll.lon; - } - a_geonames_wikipedia_box((VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl)), vtl, vlp, maxmin); + + // Note the order is max part first then min part - thus reverse order of use in min_max function: + vik_viewport_get_min_max_lat_lon ( vvp, &maxmin[1].lat, &maxmin[0].lat, &maxmin[1].lon, &maxmin[0].lon ); + a_geonames_wikipedia_box((VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl)), vtl, maxmin); + vik_layers_panel_emit_update ( vlp ); } static void trw_layer_new_wikipedia_wp_layer ( gpointer lav[2] ) @@ -2836,7 +2896,8 @@ static void trw_layer_new_wikipedia_wp_layer ( gpointer lav[2] ) struct LatLon maxmin[2] = { {0.0,0.0}, {0.0,0.0} }; trw_layer_find_maxmin (vtl, maxmin); - a_geonames_wikipedia_box((VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl)), vtl, vlp, maxmin); + a_geonames_wikipedia_box((VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl)), vtl, maxmin); + vik_layers_panel_emit_update ( vlp ); } #ifdef VIK_CONFIG_GEOTAG @@ -2929,6 +2990,19 @@ static void trw_layer_acquire_osm_cb ( gpointer lav[2] ) a_acquire ( vw, vlp, vvp, &vik_datasource_osm_interface ); } + +/** + * Acquire into this TRW Layer from OSM for 'My' Traces + */ +static void trw_layer_acquire_osm_my_traces_cb ( gpointer lav[2] ) +{ + VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]); + VikLayersPanel *vlp = VIK_LAYERS_PANEL(lav[1]); + VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl)); + VikViewport *vvp = vik_window_viewport(vw); + + a_acquire ( vw, vlp, vvp, &vik_datasource_osm_my_traces_interface ); +} #endif #ifdef VIK_CONFIG_GEOCACHES @@ -3097,15 +3171,26 @@ static void trw_layer_new_wp ( gpointer lav[2] ) vik_layers_panel_emit_update ( vlp ); } +static void new_track_create_common ( VikTrwLayer *vtl, gchar *name ) +{ + vtl->current_track = vik_track_new(); + vtl->current_track->visible = TRUE; + if ( vtl->drawmode == DRAWMODE_ALL_SAME_COLOR ) + // Create track with the preferred colour from the layer properties + vtl->current_track->color = vtl->track_color; + else + gdk_color_parse ( "#000000", &(vtl->current_track->color) ); + vtl->current_track->has_color = TRUE; + vik_trw_layer_add_track ( vtl, name, vtl->current_track ); +} + static void trw_layer_new_track ( gpointer lav[2] ) { VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]); if ( ! vtl->current_track ) { gchar *name = trw_layer_new_unique_sublayer_name ( vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, _("Track")) ; - vtl->current_track = vik_track_new(); - vtl->current_track->visible = TRUE; - vik_trw_layer_add_track ( vtl, name, vtl->current_track ); + new_track_create_common ( vtl, name ); vik_window_enable_layer_tool ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), VIK_LAYER_TRW, TOOL_CREATE_TRACK ); } @@ -3151,7 +3236,7 @@ static void trw_layer_finish_track ( gpointer lav[2] ) { VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]); vtl->current_track = NULL; - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); } static void trw_layer_auto_tracks_view ( gpointer lav[2] ) @@ -3167,7 +3252,7 @@ static void trw_layer_auto_tracks_view ( gpointer lav[2] ) } } -static void trw_layer_single_waypoint_jump ( const gchar *name, const VikWaypoint *wp, gpointer vvp ) +static void trw_layer_single_waypoint_jump ( const gpointer id, const VikWaypoint *wp, gpointer vvp ) { /* NB do not care if wp is visible or not */ vik_viewport_set_center_coord ( VIK_VIEWPORT(vvp), &(wp->coord) ); @@ -3331,27 +3416,6 @@ static void trw_layer_add_menu_items ( VikTrwLayer *vtl, GtkMenu *menu, gpointer // Make it available only when a new track *not* already in progress gtk_widget_set_sensitive ( item, ! (gboolean)GPOINTER_TO_INT(vtl->current_track) ); -#ifdef VIK_CONFIG_GEONAMES - GtkWidget *wikipedia_submenu = gtk_menu_new(); - item = gtk_image_menu_item_new_with_mnemonic ( _("_Add Wikipedia Waypoints") ); - gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_MENU) ); - gtk_menu_shell_append(GTK_MENU_SHELL (menu), item); - gtk_widget_show(item); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), wikipedia_submenu); - - item = gtk_image_menu_item_new_with_mnemonic ( _("Within _Layer Bounds") ); - gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_ZOOM_FIT, GTK_ICON_SIZE_MENU) ); - g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_new_wikipedia_wp_layer), pass_along ); - gtk_menu_shell_append (GTK_MENU_SHELL (wikipedia_submenu), item); - gtk_widget_show ( item ); - - item = gtk_image_menu_item_new_with_mnemonic ( _("Within _Current View") ); - gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_ZOOM_100, GTK_ICON_SIZE_MENU) ); - g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_new_wikipedia_wp_viewport), pass_along ); - gtk_menu_shell_append (GTK_MENU_SHELL (wikipedia_submenu), item); - gtk_widget_show ( item ); -#endif - #ifdef VIK_CONFIG_GEOTAG item = gtk_menu_item_new_with_mnemonic ( _("Geotag _Images...") ); g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_geotagging), pass_along ); @@ -3360,7 +3424,7 @@ static void trw_layer_add_menu_items ( VikTrwLayer *vtl, GtkMenu *menu, gpointer #endif GtkWidget *acquire_submenu = gtk_menu_new (); - item = gtk_image_menu_item_new_with_mnemonic ( _("Ac_quire") ); + item = gtk_image_menu_item_new_with_mnemonic ( _("_Acquire") ); gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_GO_DOWN, GTK_ICON_SIZE_MENU) ); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); gtk_widget_show ( item ); @@ -3372,7 +3436,7 @@ static void trw_layer_add_menu_items ( VikTrwLayer *vtl, GtkMenu *menu, gpointer gtk_widget_show ( item ); #ifdef VIK_CONFIG_GOOGLE - item = gtk_menu_item_new_with_mnemonic ( _("From G_oogle Directions...") ); + item = gtk_menu_item_new_with_mnemonic ( _("From Google _Directions...") ); g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_acquire_google_cb), pass_along ); gtk_menu_shell_append (GTK_MENU_SHELL (acquire_submenu), item); gtk_widget_show ( item ); @@ -3383,6 +3447,32 @@ static void trw_layer_add_menu_items ( VikTrwLayer *vtl, GtkMenu *menu, gpointer g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_acquire_osm_cb), pass_along ); gtk_menu_shell_append (GTK_MENU_SHELL (acquire_submenu), item); gtk_widget_show ( item ); + + item = gtk_menu_item_new_with_mnemonic ( _("From _My OSM Traces...") ); + g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_acquire_osm_my_traces_cb), pass_along ); + gtk_menu_shell_append (GTK_MENU_SHELL (acquire_submenu), item); + gtk_widget_show ( item ); +#endif + +#ifdef VIK_CONFIG_GEONAMES + GtkWidget *wikipedia_submenu = gtk_menu_new(); + item = gtk_image_menu_item_new_with_mnemonic ( _("From _Wikipedia Waypoints") ); + gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_MENU) ); + gtk_menu_shell_append(GTK_MENU_SHELL (acquire_submenu), item); + gtk_widget_show(item); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), wikipedia_submenu); + + item = gtk_image_menu_item_new_with_mnemonic ( _("Within _Layer Bounds") ); + gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_ZOOM_FIT, GTK_ICON_SIZE_MENU) ); + g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_new_wikipedia_wp_layer), pass_along ); + gtk_menu_shell_append (GTK_MENU_SHELL (wikipedia_submenu), item); + gtk_widget_show ( item ); + + item = gtk_image_menu_item_new_with_mnemonic ( _("Within _Current View") ); + gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_ZOOM_100, GTK_ICON_SIZE_MENU) ); + g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_new_wikipedia_wp_viewport), pass_along ); + gtk_menu_shell_append (GTK_MENU_SHELL (wikipedia_submenu), item); + gtk_widget_show ( item ); #endif #ifdef VIK_CONFIG_GEOCACHES @@ -3443,6 +3533,18 @@ static void trw_layer_add_menu_items ( VikTrwLayer *vtl, GtkMenu *menu, gpointer g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_delete_tracks_from_selection), pass_along ); gtk_menu_shell_append ( GTK_MENU_SHELL(delete_submenu), item ); gtk_widget_show ( item ); + + item = gtk_image_menu_item_new_with_mnemonic ( _("Delete _All Routes") ); + gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU) ); + g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_delete_all_routes), pass_along ); + gtk_menu_shell_append ( GTK_MENU_SHELL(delete_submenu), item ); + gtk_widget_show ( item ); + + item = gtk_image_menu_item_new_with_mnemonic ( _("_Delete Routes From Selection...") ); + gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_INDEX, GTK_ICON_SIZE_MENU) ); + g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_delete_routes_from_selection), pass_along ); + gtk_menu_shell_append ( GTK_MENU_SHELL(delete_submenu), item ); + gtk_widget_show ( item ); item = gtk_image_menu_item_new_with_mnemonic ( _("Delete All _Waypoints") ); gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU) ); @@ -3656,7 +3758,7 @@ static void trw_layer_move_item ( VikTrwLayer *vtl_src, VikTrwLayer *vtl_dest, g gchar *newname = trw_layer_new_unique_sublayer_name(vtl_dest, type, trk->name); - VikTrack *trk2 = vik_track_copy ( trk ); + VikTrack *trk2 = vik_track_copy ( trk, TRUE ); vik_trw_layer_add_track ( vtl_dest, newname, trk2 ); vik_trw_layer_delete_track ( vtl_src, trk ); } @@ -3666,7 +3768,7 @@ static void trw_layer_move_item ( VikTrwLayer *vtl_src, VikTrwLayer *vtl_dest, g gchar *newname = trw_layer_new_unique_sublayer_name(vtl_dest, type, trk->name); - VikTrack *trk2 = vik_track_copy ( trk ); + VikTrack *trk2 = vik_track_copy ( trk, TRUE ); vik_trw_layer_add_route ( vtl_dest, newname, trk2 ); vik_trw_layer_delete_route ( vtl_src, trk ); } @@ -3960,7 +4062,7 @@ static gboolean trw_layer_delete_track_by_name ( VikTrwLayer *vtl, const gchar * return FALSE; } -static void remove_item_from_treeview(const gchar *name, GtkTreeIter *it, VikTreeview * vt) +static void remove_item_from_treeview ( const gpointer id, GtkTreeIter *it, VikTreeview * vt ) { vik_treeview_item_delete (vt, it ); } @@ -3980,7 +4082,7 @@ void vik_trw_layer_delete_all_routes ( VikTrwLayer *vtl ) vik_treeview_item_delete ( VIK_LAYER(vtl)->vt, &(vtl->routes_iter) ); - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); } void vik_trw_layer_delete_all_tracks ( VikTrwLayer *vtl ) @@ -3998,7 +4100,7 @@ void vik_trw_layer_delete_all_tracks ( VikTrwLayer *vtl ) vik_treeview_item_delete ( VIK_LAYER(vtl)->vt, &(vtl->tracks_iter) ); - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); } void vik_trw_layer_delete_all_waypoints ( VikTrwLayer *vtl ) @@ -4015,7 +4117,7 @@ void vik_trw_layer_delete_all_waypoints ( VikTrwLayer *vtl ) vik_treeview_item_delete ( VIK_LAYER(vtl)->vt, &(vtl->waypoints_iter) ); - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); } static void trw_layer_delete_all_tracks ( gpointer lav[2] ) @@ -4093,7 +4195,7 @@ static void trw_layer_delete_item ( gpointer pass_along[6] ) } } if ( was_visible ) - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); } @@ -4109,11 +4211,11 @@ static void trw_layer_properties_item ( gpointer pass_along[7] ) gboolean updated = FALSE; a_dialog_waypoint ( VIK_GTK_WINDOW_FROM_LAYER(vtl), wp->name, wp, vtl->coord_mode, FALSE, &updated ); - if ( updated && pass_along[6] ) + if ( updated && wp->symbol && pass_along[6] ) vik_treeview_item_set_icon ( VIK_LAYER(vtl)->vt, pass_along[6], get_wp_sym_small (wp->symbol) ); if ( updated && VIK_LAYER(vtl)->visible ) - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); } } else @@ -4188,7 +4290,7 @@ static void goto_coord ( gpointer *vlp, gpointer vl, gpointer vvp, const VikCoor /* since vlp not set, vl & vvp should be valid instead! */ if ( vl && vvp ) { vik_viewport_set_center_coord ( VIK_VIEWPORT(vvp), coord ); - vik_layer_emit_update ( VIK_LAYER(vl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vl) ); } } } @@ -4251,7 +4353,7 @@ static void trw_layer_convert_track_route ( gpointer pass_along[6] ) } // Copy it - VikTrack *trk_copy = vik_track_copy ( trk ); + VikTrack *trk_copy = vik_track_copy ( trk, TRUE ); // Convert trk_copy->is_route = !trk_copy->is_route; @@ -4275,7 +4377,7 @@ static void trw_layer_convert_track_route ( gpointer pass_along[6] ) g_free ( name ); // Update in case color of track / route changes when moving between sublayers - vik_layer_emit_update ( VIK_LAYER(pass_along[0]), FALSE ); + vik_layer_emit_update ( VIK_LAYER(pass_along[0]) ); } @@ -4305,10 +4407,12 @@ static void trw_layer_extend_track_end ( gpointer pass_along[6] ) static void trw_layer_extend_track_end_route_finder ( gpointer pass_along[6] ) { VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]); - VikTrack *track = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->tracks, pass_along[3] ); + VikTrack *track = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->routes, pass_along[3] ); + if ( !track ) + return; VikCoord last_coord = (((VikTrackpoint *)g_list_last(track->trackpoints)->data)->coord); - vik_window_enable_layer_tool ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), VIK_LAYER_TRW, NUM_TOOLS ); + vik_window_enable_layer_tool ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), VIK_LAYER_TRW, TOOL_ROUTE_FINDER ); vtl->route_finder_coord = last_coord; vtl->route_finder_current_track = track; vtl->route_finder_started = TRUE; @@ -4427,7 +4531,7 @@ static void trw_layer_auto_track_view ( gpointer pass_along[6] ) if ( pass_along[1] ) vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(pass_along[1]) ); else - vik_layer_emit_update ( VIK_LAYER(pass_along[0]), FALSE ); + vik_layer_emit_update ( VIK_LAYER(pass_along[0]) ); } } @@ -4654,7 +4758,7 @@ static void trw_layer_merge_with_other ( gpointer pass_along[6] ) for (l = merge_list; l != NULL; l = g_list_next(l)) g_free(l->data); g_list_free(merge_list); - vik_layer_emit_update( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update( VIK_LAYER(vtl) ); } } @@ -4741,7 +4845,7 @@ static void trw_layer_append_track ( gpointer pass_along[6] ) for (l = append_list; l != NULL; l = g_list_next(l)) g_free(l->data); g_list_free(append_list); - vik_layer_emit_update( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update( VIK_LAYER(vtl) ); } } @@ -4837,7 +4941,7 @@ static void trw_layer_append_other ( gpointer pass_along[6] ) for (l = append_list; l != NULL; l = g_list_next(l)) g_free(l->data); g_list_free(append_list); - vik_layer_emit_update( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update( VIK_LAYER(vtl) ); } } @@ -4951,7 +5055,7 @@ static void trw_layer_merge_by_timestamp ( gpointer pass_along[6] ) } g_list_free(nearby_tracks); - vik_layer_emit_update( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update( VIK_LAYER(vtl) ); } /** @@ -4965,15 +5069,12 @@ static void trw_layer_split_at_selected_trackpoint ( VikTrwLayer *vtl, gint subt if ( vtl->current_tpl->next && vtl->current_tpl->prev ) { gchar *name = trw_layer_new_unique_sublayer_name(vtl, subtype, vtl->current_tp_track->name); if ( name ) { - VikTrack *tr = vik_track_new (); + VikTrack *tr = vik_track_copy ( vtl->current_tp_track, FALSE ); GList *newglist = g_list_alloc (); newglist->prev = NULL; newglist->next = vtl->current_tpl->next; newglist->data = vik_trackpoint_copy(VIK_TRACKPOINT(vtl->current_tpl->data)); tr->trackpoints = newglist; - tr->is_route = vtl->current_tp_track->is_route; - tr->color = vtl->current_tp_track->color; - tr->visible = TRUE; vtl->current_tpl->next->prev = newglist; /* end old track here */ vtl->current_tpl->next = NULL; @@ -5002,7 +5103,7 @@ static void trw_layer_split_at_selected_trackpoint ( VikTrwLayer *vtl, gint subt else vtl->current_tp_id = NULL; - vik_layer_emit_update(VIK_LAYER(vtl), FALSE); + vik_layer_emit_update(VIK_LAYER(vtl)); } } } @@ -5063,8 +5164,7 @@ static void trw_layer_split_by_timestamp ( gpointer pass_along[6] ) gchar *new_tr_name; VikTrack *tr; - tr = vik_track_new(); - tr->visible = track->visible; + tr = vik_track_copy ( track, FALSE ); tr->trackpoints = (GList *)(iter->data); new_tr_name = trw_layer_new_unique_sublayer_name ( vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, track->name); @@ -5076,7 +5176,7 @@ static void trw_layer_split_by_timestamp ( gpointer pass_along[6] ) } // Remove original track and then update the display vik_trw_layer_delete_track (vtl, track); - vik_layer_emit_update(VIK_LAYER(pass_along[0]), FALSE); + vik_layer_emit_update(VIK_LAYER(pass_along[0])); } g_list_free(newlists); } @@ -5146,10 +5246,7 @@ static void trw_layer_split_by_n_points ( gpointer pass_along[6] ) gchar *new_tr_name; VikTrack *tr; - tr = vik_track_new(); - tr->visible = track->visible; - tr->is_route = track->is_route; - tr->color = track->color; + tr = vik_track_copy ( track, FALSE ); tr->trackpoints = (GList *)(iter->data); if ( track->is_route ) { @@ -5167,7 +5264,7 @@ static void trw_layer_split_by_n_points ( gpointer pass_along[6] ) vik_trw_layer_delete_route (vtl, track); else vik_trw_layer_delete_track (vtl, track); - vik_layer_emit_update(VIK_LAYER(pass_along[0]), FALSE); + vik_layer_emit_update(VIK_LAYER(pass_along[0])); } g_list_free(newlists); } @@ -5209,7 +5306,7 @@ static void trw_layer_split_segments ( gpointer pass_along[6] ) g_free ( tracks ); // Remove original track vik_trw_layer_delete_track ( vtl, trk ); - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); } else { a_dialog_error_msg (VIK_GTK_WINDOW_FROM_LAYER(vtl), _("Can not split track as it has no segments")); @@ -5244,7 +5341,7 @@ static void trw_layer_delete_points_same_position ( gpointer pass_along[6] ) g_snprintf(str, 64, tmp_str, removed); a_dialog_info_msg (VIK_GTK_WINDOW_FROM_LAYER(vtl), str); - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); } /** @@ -5274,7 +5371,7 @@ static void trw_layer_delete_points_same_time ( gpointer pass_along[6] ) g_snprintf(str, 64, tmp_str, removed); a_dialog_info_msg (VIK_GTK_WINDOW_FROM_LAYER(vtl), str); - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); } /** @@ -5299,7 +5396,7 @@ static void trw_layer_reverse ( gpointer pass_along[6] ) vik_track_reverse ( track ); - vik_layer_emit_update ( VIK_LAYER(pass_along[0]), FALSE ); + vik_layer_emit_update ( VIK_LAYER(pass_along[0]) ); } /** @@ -5520,7 +5617,7 @@ static void trw_layer_delete_tracks_from_selection ( gpointer lav[2] ) trw_layer_delete_track_by_name (vtl, l->data, vtl->tracks); } g_list_free(delete_list); - vik_layer_emit_update( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update( VIK_LAYER(vtl) ); } } @@ -5567,7 +5664,7 @@ static void trw_layer_delete_routes_from_selection ( gpointer lav[2] ) trw_layer_delete_track_by_name (vtl, l->data, vtl->routes); } g_list_free(delete_list); - vik_layer_emit_update( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update( VIK_LAYER(vtl) ); } } @@ -5747,7 +5844,7 @@ static void trw_layer_delete_waypoints_from_selection ( gpointer lav[2] ) trw_layer_delete_waypoint_by_name (vtl, l->data); } g_list_free(delete_list); - vik_layer_emit_update( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update( VIK_LAYER(vtl) ); } } @@ -5761,11 +5858,26 @@ static void trw_layer_goto_waypoint ( gpointer pass_along[6] ) static void trw_layer_waypoint_gc_webpage ( gpointer pass_along[6] ) { - gchar *webpage = g_strdup_printf("http://www.geocaching.com/seek/cache_details.aspx?wp=%s", (gchar *) pass_along[3] ); + VikWaypoint *wp = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->waypoints, pass_along[3] ); + if ( !wp ) + return; + gchar *webpage = g_strdup_printf("http://www.geocaching.com/seek/cache_details.aspx?wp=%s", wp->name ); open_url(VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(pass_along[0])), webpage); g_free ( webpage ); } +static void trw_layer_waypoint_webpage ( gpointer pass_along[6] ) +{ + VikWaypoint *wp = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->waypoints, pass_along[3] ); + if ( !wp ) + return; + if ( !strncmp(wp->comment, "http", 4) ) { + open_url(VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(pass_along[0])), wp->comment); + } else if ( !strncmp(wp->description, "http", 4) ) { + open_url(VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(pass_along[0])), wp->description); + } +} + static const gchar* trw_layer_sublayer_rename_request ( VikTrwLayer *l, const gchar *newname, gpointer vlp, gint subtype, gpointer sublayer, GtkTreeIter *iter ) { if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT ) @@ -5889,13 +6001,13 @@ static void trw_layer_track_use_with_filter ( gpointer pass_along[6] ) #ifdef VIK_CONFIG_GOOGLE static gboolean is_valid_google_route ( VikTrwLayer *vtl, const gpointer track_id ) { - VikTrack *tr = g_hash_table_lookup ( vtl->tracks, track_id ); + VikTrack *tr = g_hash_table_lookup ( vtl->routes, track_id ); return ( tr && tr->comment && strlen(tr->comment) > 7 && !strncmp(tr->comment, "from:", 5) ); } -static void trw_layer_track_google_route_webpage ( gpointer pass_along[6] ) +static void trw_layer_google_route_webpage ( gpointer pass_along[6] ) { - VikTrack *tr = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->tracks, pass_along[3] ); + VikTrack *tr = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->routes, pass_along[3] ); if ( tr ) { gchar *escaped = uri_escape ( tr->comment ); gchar *webpage = g_strdup_printf("http://maps.google.com/maps?f=q&hl=en&q=%s", escaped ); @@ -6034,6 +6146,18 @@ static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *men #endif } + if ( wp ) + { + if ( ( wp->comment && !strncmp(wp->comment, "http", 4) ) || + ( wp->description && !strncmp(wp->description, "http", 4) )) { + item = gtk_image_menu_item_new_with_mnemonic ( _("Visit _Webpage") ); + gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_NETWORK, GTK_ICON_SIZE_MENU) ); + g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_waypoint_webpage), pass_along ); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + gtk_widget_show ( item ); + } + } + } } @@ -6404,11 +6528,13 @@ static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *men gtk_widget_show ( item ); #ifdef VIK_CONFIG_GOOGLE - item = gtk_image_menu_item_new_with_mnemonic ( _("Extend _Using Route Finder") ); - gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock ("Route Finder", GTK_ICON_SIZE_MENU) ); // Own icon - see stock_icons in vikwindow.c - g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_extend_track_end_route_finder), pass_along ); - gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item ); - gtk_widget_show ( item ); + if ( subtype == VIK_TRW_LAYER_SUBLAYER_ROUTE ) { + item = gtk_image_menu_item_new_with_mnemonic ( _("Extend _Using Route Finder") ); + gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock ("Route Finder", GTK_ICON_SIZE_MENU) ); // Own icon - see stock_icons in vikwindow.c + g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_extend_track_end_route_finder), pass_along ); + gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item ); + gtk_widget_show ( item ); + } #endif // ATM can't upload a single waypoint but can do waypoints to a GPS @@ -6427,6 +6553,17 @@ static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *men } } +#ifdef VIK_CONFIG_GOOGLE + if ( subtype == VIK_TRW_LAYER_SUBLAYER_ROUTE && is_valid_google_route ( l, sublayer ) ) + { + item = gtk_image_menu_item_new_with_mnemonic ( _("_View Google Directions") ); + gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_NETWORK, GTK_ICON_SIZE_MENU) ); + g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_google_route_webpage), pass_along ); + gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item ); + gtk_widget_show ( item ); + } +#endif + // Some things aren't usable with routes if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK ) { #ifdef VIK_CONFIG_OPENSTREETMAP @@ -6439,23 +6576,6 @@ static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *men gtk_widget_show ( item ); #endif - item = gtk_image_menu_item_new_with_mnemonic ( _("_Upload to GPS...") ); - gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_GO_FORWARD, GTK_ICON_SIZE_MENU) ); - g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_gps_upload_any), pass_along ); - gtk_menu_shell_append ( GTK_MENU_SHELL(upload_submenu), item ); - gtk_widget_show ( item ); - -#ifdef VIK_CONFIG_GOOGLE - if ( is_valid_google_route ( l, sublayer ) ) - { - item = gtk_image_menu_item_new_with_mnemonic ( _("_View Google Directions") ); - gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_NETWORK, GTK_ICON_SIZE_MENU) ); - g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_track_google_route_webpage), pass_along ); - gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item ); - gtk_widget_show ( item ); - } -#endif - item = gtk_image_menu_item_new_with_mnemonic ( _("Use with _Filter") ); gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_INDEX, GTK_ICON_SIZE_MENU) ); g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_track_use_with_filter), pass_along ); @@ -6576,7 +6696,7 @@ static void trw_layer_cancel_current_tp ( VikTrwLayer *vtl, gboolean destroy ) vtl->current_tpl = NULL; vtl->current_tp_track = NULL; vtl->current_tp_id = NULL; - vik_layer_emit_update(VIK_LAYER(vtl), FALSE); + vik_layer_emit_update(VIK_LAYER(vtl)); } } @@ -6621,7 +6741,7 @@ static void trw_layer_tpwin_response ( VikTrwLayer *vtl, gint response ) if ( vtl->current_tp_track ) vik_trw_layer_tpwin_set_tp ( vtl->tpwin, new_tpl, vtl->current_tp_track->name ); - vik_layer_emit_update(VIK_LAYER(vtl), FALSE); + vik_layer_emit_update(VIK_LAYER(vtl)); } else { @@ -6635,21 +6755,21 @@ static void trw_layer_tpwin_response ( VikTrwLayer *vtl, gint response ) { if ( vtl->current_tp_track ) vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl = vtl->current_tpl->next, vtl->current_tp_track->name ); - vik_layer_emit_update(VIK_LAYER(vtl), FALSE); /* TODO longone: either move or only update if tp is inside drawing window */ + vik_layer_emit_update(VIK_LAYER(vtl)); /* TODO longone: either move or only update if tp is inside drawing window */ } else if ( response == VIK_TRW_LAYER_TPWIN_BACK && vtl->current_tpl->prev ) { if ( vtl->current_tp_track ) vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl = vtl->current_tpl->prev, vtl->current_tp_track->name ); - vik_layer_emit_update(VIK_LAYER(vtl), FALSE); + vik_layer_emit_update(VIK_LAYER(vtl)); } else if ( response == VIK_TRW_LAYER_TPWIN_INSERT && vtl->current_tpl->next ) { trw_layer_insert_tp_after_current_tp ( vtl ); - vik_layer_emit_update(VIK_LAYER(vtl), FALSE); + vik_layer_emit_update(VIK_LAYER(vtl)); } else if ( response == VIK_TRW_LAYER_TPWIN_DATA_CHANGED ) - vik_layer_emit_update(VIK_LAYER(vtl), FALSE); + vik_layer_emit_update(VIK_LAYER(vtl)); } static void trw_layer_tpwin_init ( VikTrwLayer *vtl ) @@ -6865,7 +6985,7 @@ static gboolean trw_layer_select_release ( VikTrwLayer *vtl, GdkEventButton *eve vtl->current_wp_id = NULL; trw_layer_cancel_current_tp ( vtl, FALSE ); - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); return TRUE; } return FALSE; @@ -6919,7 +7039,7 @@ static gboolean trw_layer_select_click ( VikTrwLayer *vtl, GdkEventButton *event vtl->current_wp = wp_params.closest_wp; vtl->current_wp_id = wp_params.closest_wp_id; - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); return TRUE; } @@ -6962,7 +7082,7 @@ static gboolean trw_layer_select_click ( VikTrwLayer *vtl, GdkEventButton *event if ( vtl->tpwin ) vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name ); - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); return TRUE; } } @@ -6997,7 +7117,7 @@ static gboolean trw_layer_select_click ( VikTrwLayer *vtl, GdkEventButton *event if ( vtl->tpwin ) vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name ); - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); return TRUE; } } @@ -7222,14 +7342,14 @@ static gboolean tool_edit_waypoint_click ( VikTrwLayer *vtl, GdkEventButton *eve vtl->current_wp_id = params.closest_wp_id; /* could make it so don't update if old WP is off screen and new is null but oh well */ - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); return TRUE; } vtl->current_wp = NULL; vtl->current_wp_id = NULL; vtl->waypoint_rightclick = FALSE; - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); return FALSE; } @@ -7304,7 +7424,7 @@ static gboolean tool_edit_waypoint_release ( VikTrwLayer *vtl, GdkEventButton *e marker_end_move ( t ); vtl->current_wp->coord = new_coord; - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); return TRUE; } /* PUT IN RIGHT PLACE!!! */ @@ -7390,11 +7510,14 @@ static gchar* distance_string (gdouble distance) /* * Actually set the message in statusbar */ -static void statusbar_write (const gchar *distance_string, gdouble elev_gain, gdouble elev_loss, VikTrwLayer *vtl ) +static void statusbar_write (gdouble distance, gdouble elev_gain, gdouble elev_loss, gdouble last_step, gdouble angle, VikTrwLayer *vtl ) { // Only show elevation data when track has some elevation properties gchar str_gain_loss[64]; str_gain_loss[0] = '\0'; + gchar str_last_step[64]; + str_last_step[0] = '\0'; + gchar *str_total = distance_string (distance); if ( (elev_gain > 0.1) || (elev_loss > 0.1) ) { if ( a_vik_get_units_height () == VIK_UNITS_HEIGHT_METRES ) @@ -7402,11 +7525,20 @@ static void statusbar_write (const gchar *distance_string, gdouble elev_gain, gd else g_sprintf(str_gain_loss, _(" - Gain %dft:Loss %dft"), (int)VIK_METERS_TO_FEET(elev_gain), (int)VIK_METERS_TO_FEET(elev_loss)); } + + if ( last_step > 0 ) { + gchar *tmp = distance_string (last_step); + g_sprintf(str_last_step, _(" - Bearing %3.1f° - Step %s"), RAD2DEG(angle), tmp); + g_free ( tmp ); + } + + VikWindow *vw = VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)); // Write with full gain/loss information - gchar *msg = g_strdup_printf ( "%s%s", distance_string, str_gain_loss); - vik_statusbar_set_message ( vik_window_get_statusbar (VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl))), VIK_STATUSBAR_INFO, msg ); + gchar *msg = g_strdup_printf ( "Total %s%s%s", str_total, str_last_step, str_gain_loss); + vik_statusbar_set_message ( vik_window_get_statusbar (vw), VIK_STATUSBAR_INFO, msg ); g_free ( msg ); + g_free ( str_total ); } /* @@ -7420,11 +7552,8 @@ static void update_statusbar ( VikTrwLayer *vtl ) /* Find out actual distance of current track */ gdouble distance = vik_track_get_length (vtl->current_track); - gchar *str = distance_string (distance); - - statusbar_write (str, elev_gain, elev_loss, vtl); - g_free (str); + statusbar_write (distance, elev_gain, elev_loss, 0, 0, vtl); } @@ -7476,7 +7605,8 @@ static VikLayerToolFuncStatus tool_new_track_move ( VikTrwLayer *vtl, GdkEventMo struct LatLon ll; vik_viewport_screen_to_coord ( vvp, (gint) event->x, (gint) event->y, &coord ); vik_coord_to_latlon ( &coord, &ll ); - distance = distance + vik_coord_diff( &coord, &(last_tpt->coord)); + gdouble last_step = vik_coord_diff( &coord, &(last_tpt->coord)); + distance = distance + last_step; // Get elevation data gdouble elev_gain, elev_loss; @@ -7496,7 +7626,7 @@ static VikLayerToolFuncStatus tool_new_track_move ( VikTrwLayer *vtl, GdkEventMo elev_loss += last_tpt->altitude - elev_new; } } - + gchar *str = distance_string (distance); PangoLayout *pl = gtk_widget_create_pango_layout (GTK_WIDGET(vvp), NULL); @@ -7525,8 +7655,12 @@ static VikLayerToolFuncStatus tool_new_track_move ( VikTrwLayer *vtl, GdkEventMo passalong->drawable = GTK_WIDGET(vvp)->window; passalong->gc = vtl->current_track_newpoint_gc; + gdouble angle; + gdouble baseangle; + vik_viewport_compute_bearing ( vvp, x1, y1, event->x, event->y, &angle, &baseangle ); + // Update statusbar with full gain/loss information - statusbar_write (str, elev_gain, elev_loss, vtl); + statusbar_write (distance, elev_gain, elev_loss, last_step, angle, vtl); g_free (str); @@ -7542,7 +7676,7 @@ static gboolean tool_new_track_key_press ( VikTrwLayer *vtl, GdkEventKey *event, { if ( vtl->current_track && event->keyval == GDK_Escape ) { vtl->current_track = NULL; - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); return TRUE; } else if ( vtl->current_track && event->keyval == GDK_BackSpace ) { /* undo */ @@ -7555,7 +7689,7 @@ static gboolean tool_new_track_key_press ( VikTrwLayer *vtl, GdkEventKey *event, update_statusbar ( vtl ); - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); return TRUE; } return FALSE; @@ -7594,7 +7728,7 @@ static gboolean tool_new_track_or_route_click ( VikTrwLayer *vtl, GdkEventButton } update_statusbar ( vtl ); - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); return TRUE; } @@ -7609,7 +7743,7 @@ static gboolean tool_new_track_or_route_click ( VikTrwLayer *vtl, GdkEventButton /* undo last, then end */ vtl->current_track = NULL; } - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); return TRUE; } @@ -7639,7 +7773,7 @@ static gboolean tool_new_track_or_route_click ( VikTrwLayer *vtl, GdkEventButton vtl->ct_x2 = event->x; vtl->ct_y2 = event->y; - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); return TRUE; } @@ -7651,9 +7785,7 @@ static gboolean tool_new_track_click ( VikTrwLayer *vtl, GdkEventButton *event, gchar *name = trw_layer_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, _("Track")); if ( ( name = a_dialog_new_track ( VIK_GTK_WINDOW_FROM_LAYER(vtl), vtl->tracks, name, FALSE ) ) ) { - vtl->current_track = vik_track_new(); - vtl->current_track->visible = TRUE; - vik_trw_layer_add_track ( vtl, name, vtl->current_track ); + new_track_create_common ( vtl, name ); } else return TRUE; @@ -7705,7 +7837,7 @@ static gboolean tool_new_waypoint_click ( VikTrwLayer *vtl, GdkEventButton *even return FALSE; vik_viewport_screen_to_coord ( vvp, event->x, event->y, &coord ); if (vik_trw_layer_new_waypoint ( vtl, VIK_GTK_WINDOW_FROM_LAYER(vtl), &coord ) && VIK_LAYER(vtl)->visible) - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); return TRUE; } @@ -7778,7 +7910,7 @@ static gboolean tool_edit_trackpoint_click ( VikTrwLayer *vtl, GdkEventButton *e vtl->current_tp_track = g_hash_table_lookup ( vtl->tracks, params.closest_track_id ); trw_layer_tpwin_init ( vtl ); set_statusbar_msg_info_trkpt ( vtl, params.closest_tp ); - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); return TRUE; } @@ -7793,7 +7925,7 @@ static gboolean tool_edit_trackpoint_click ( VikTrwLayer *vtl, GdkEventButton *e vtl->current_tp_track = g_hash_table_lookup ( vtl->routes, params.closest_track_id ); trw_layer_tpwin_init ( vtl ); set_statusbar_msg_info_trkpt ( vtl, params.closest_tp ); - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); return TRUE; } @@ -7863,7 +7995,7 @@ static gboolean tool_edit_trackpoint_release ( VikTrwLayer *vtl, GdkEventButton if ( vtl->tpwin ) vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name ); - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); return TRUE; } return FALSE; @@ -7888,7 +8020,7 @@ static gboolean tool_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *even if ( new_end ) { vtl->route_finder_coord = *new_end; g_free ( new_end ); - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); /* remove last ' to:...' */ if ( vtl->route_finder_current_track->comment ) { gchar *last_to = strrchr ( vtl->route_finder_current_track->comment, 't' ); @@ -7923,7 +8055,8 @@ static gboolean tool_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *even g_ascii_dtostr (startlon, G_ASCII_DTOSTR_BUF_SIZE, (gdouble) start.lon), g_ascii_dtostr (endlat, G_ASCII_DTOSTR_BUF_SIZE, (gdouble) end.lat), g_ascii_dtostr (endlon, G_ASCII_DTOSTR_BUF_SIZE, (gdouble) end.lon)); - a_babel_convert_from_url ( vtl, url, "google", NULL, NULL ); + // NB normally this returns a GPX Route - so subsequent usage of it must lookup via the routes hash + a_babel_convert_from_url ( vtl, url, "google", NULL, NULL, NULL ); g_free ( url ); /* see if anything was done -- a track was added or appended to */ @@ -7938,7 +8071,7 @@ static gboolean tool_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *even vtl->route_finder_check_added_track = FALSE; vtl->route_finder_append = FALSE; - vik_layer_emit_update ( VIK_LAYER(vtl), FALSE ); + vik_layer_emit_update ( VIK_LAYER(vtl) ); } else { vtl->route_finder_started = TRUE; vtl->route_finder_coord = tmp; @@ -7956,7 +8089,7 @@ static gpointer tool_show_picture_create ( VikWindow *vw, VikViewport *vvp) } /* Params are: vvp, event, last match found or NULL */ -static void tool_show_picture_wp ( char *name, VikWaypoint *wp, gpointer params[3] ) +static void tool_show_picture_wp ( const gpointer id, VikWaypoint *wp, gpointer params[3] ) { if ( wp->image && wp->visible ) { @@ -8018,10 +8151,7 @@ static gboolean tool_show_picture_click ( VikTrwLayer *vtl, GdkEventButton *even ***************************************************************************/ - - - -static void image_wp_make_list ( char *name, VikWaypoint *wp, GSList **pics ) +static void image_wp_make_list ( const gpointer id, VikWaypoint *wp, GSList **pics ) { if ( wp->image && ( ! a_thumbnails_exists ( wp->image ) ) ) *pics = g_slist_append ( *pics, (gpointer) g_strdup ( wp->image ) ); @@ -8048,7 +8178,7 @@ static int create_thumbnails_thread ( thumbnail_create_thread_data *tctd, gpoint // Redraw to show the thumbnails as they are now created if ( IS_VIK_LAYER(tctd->vtl) ) - vik_layer_emit_update ( VIK_LAYER(tctd->vtl), TRUE ); // Yes update from background thread + vik_layer_emit_update ( VIK_LAYER(tctd->vtl) ); // NB update from background thread return 0; } @@ -8092,14 +8222,14 @@ static const gchar* my_track_colors ( gint ii ) { static const gchar* colors[VIK_TRW_LAYER_TRACK_GCS] = { "#2d870a", - "#0a8742", + "#135D34", "#0a8783", "#0e4d87", "#05469f", - "#1b059f", + "#695CBB", "#2d059f", "#4a059f", - "#84059f", + "#5A171A", "#96059f" }; // Fast and reliable way of returning a colour @@ -8119,7 +8249,11 @@ static void trw_layer_track_alloc_colors ( VikTrwLayer *vtl ) // Tracks get a random spread of colours if not already assigned if ( ! VIK_TRACK(value)->has_color ) { - gdk_color_parse ( my_track_colors (ii) , &(VIK_TRACK(value)->color) ); + if ( vtl->drawmode == DRAWMODE_ALL_SAME_COLOR ) + VIK_TRACK(value)->color = vtl->track_color; + else { + gdk_color_parse ( my_track_colors (ii), &(VIK_TRACK(value)->color) ); + } VIK_TRACK(value)->has_color = TRUE; } @@ -8183,7 +8317,7 @@ static void waypoint_convert ( const gpointer id, VikWaypoint *wp, VikCoordMode vik_coord_convert ( &(wp->coord), *dest_mode ); } -static void track_convert ( const gchar *name, VikTrack *tr, VikCoordMode *dest_mode ) +static void track_convert ( const gpointer id, VikTrack *tr, VikCoordMode *dest_mode ) { vik_track_convert ( tr, *dest_mode ); } @@ -8195,6 +8329,7 @@ static void trw_layer_change_coord_mode ( VikTrwLayer *vtl, VikCoordMode dest_mo vtl->coord_mode = dest_mode; g_hash_table_foreach ( vtl->waypoints, (GHFunc) waypoint_convert, &dest_mode ); g_hash_table_foreach ( vtl->tracks, (GHFunc) track_convert, &dest_mode ); + g_hash_table_foreach ( vtl->routes, (GHFunc) track_convert, &dest_mode ); } }