* Copyright (C) 2007, Quy Tonthat <qtonthat@gmail.com>
* Copyright (C) 2009, Hein Ragas <viking@ragas.nl>
* Copyright (c) 2012, Rob Norris <rw_norris@hotmail.com>
+ * Copyright (c) 2012-2013, Guilhem Bonnefille <guilhem.bonnefille@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include "vikgpslayer.h"
#include "viktrwlayer_tpwin.h"
#include "viktrwlayer_propwin.h"
+#include "viktrwlayer_analysis.h"
#ifdef VIK_CONFIG_GEOTAG
#include "viktrwlayer_geotag.h"
#include "geotag_exif.h"
#include "acquire.h"
#include "datasources.h"
#include "datasource_gps.h"
+#include "vikexttool_datasources.h"
#include "util.h"
+#include "vikutils.h"
+
+#include "vikrouting.h"
#include "icons/icons.h"
#include <glib/gstdio.h>
#include <glib/gi18n.h>
-#ifdef VIK_CONFIG_GOOGLE
-#define GOOGLE_DIRECTIONS_STRING "maps.google.com/maps?q=from:%s,%s+to:%s,%s&output=js"
-#endif
-
#define VIK_TRW_LAYER_TRACK_GC 6
#define VIK_TRW_LAYER_TRACK_GCS 10
#define VIK_TRW_LAYER_TRACK_GC_BLACK 0
GHashTable *waypoints;
GtkTreeIter tracks_iter, routes_iter, waypoints_iter;
gboolean tracks_visible, routes_visible, waypoints_visible;
+ LatLonBBox waypoints_bbox;
+
+ gboolean track_draw_labels;
guint8 drawmode;
guint8 drawpoints;
guint8 drawpoints_size;
guint8 drawdirections_size;
guint8 line_thickness;
guint8 bg_line_thickness;
+ vik_layer_sort_order_t track_sort_order;
+
+ PangoLayout *tracklabellayout;
+ font_size_t track_font_size;
+ gchar *track_fsize_str;
guint8 wp_symbol;
guint8 wp_size;
gboolean wp_draw_symbols;
font_size_t wp_font_size;
+ gchar *wp_fsize_str;
+ vik_layer_sort_order_t wp_sort_order;
gdouble track_draw_speed_factor;
GArray *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)
GdkGC *current_track_newpoint_gc;
- GdkGC *track_bg_gc;
- GdkGC *waypoint_gc;
- GdkGC *waypoint_text_gc;
- GdkGC *waypoint_bg_gc;
+ GdkGC *track_bg_gc; GdkColor track_bg_color;
+ GdkGC *waypoint_gc; GdkColor waypoint_color;
+ GdkGC *waypoint_text_gc; GdkColor waypoint_text_color;
+ GdkGC *waypoint_bg_gc; GdkColor waypoint_bg_color;
+ gboolean wpbgand;
GdkFont *waypoint_font;
VikTrack *current_track; // ATM shared between new tracks and new routes
guint16 ct_x1, ct_y1, ct_x2, ct_y2;
VikStdLayerMenuItem menu_selection;
gint highest_wp_number;
+
+ // One per layer
+ GtkWidget *tracks_analysis_dialog;
};
/* A caached waypoint image. */
const VikCoord *center;
gboolean one_zone, lat_lon;
gdouble ce1, ce2, cn1, cn2;
+ LatLonBBox bbox;
};
static gboolean trw_layer_delete_waypoint ( VikTrwLayer *vtl, VikWaypoint *wp );
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 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_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 trw_layer_calculate_bounds_waypoints ( VikTrwLayer *vtl );
+
static void goto_coord ( gpointer *vlp, gpointer vvp, gpointer vl, const VikCoord *coord );
static void trw_layer_goto_track_startpoint ( gpointer pass_along[6] );
static void trw_layer_goto_track_endpoint ( gpointer pass_along[6] );
static void trw_layer_geotagging ( gpointer lav[2] );
#endif
static void trw_layer_acquire_gps_cb ( gpointer lav[2] );
-#ifdef VIK_CONFIG_GOOGLE
-static void trw_layer_acquire_google_cb ( gpointer lav[2] );
-#endif
+static void trw_layer_acquire_routing_cb ( gpointer lav[2] );
#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] );
static void trw_layer_tpwin_init ( VikTrwLayer *vtl );
static gpointer tool_edit_trackpoint_create ( VikWindow *vw, VikViewport *vvp);
+static void tool_edit_trackpoint_destroy ( tool_ed_t *t );
static gboolean tool_edit_trackpoint_click ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data );
static gboolean tool_edit_trackpoint_move ( VikTrwLayer *vtl, GdkEventMotion *event, gpointer data );
static gboolean tool_edit_trackpoint_release ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data );
static gpointer tool_show_picture_create ( VikWindow *vw, VikViewport *vvp);
static gboolean tool_show_picture_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
static gpointer tool_edit_waypoint_create ( VikWindow *vw, VikViewport *vvp);
+static void tool_edit_waypoint_destroy ( tool_ed_t *t );
static gboolean tool_edit_waypoint_click ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data );
static gboolean tool_edit_waypoint_move ( VikTrwLayer *vtl, GdkEventMotion *event, gpointer data );
static gboolean tool_edit_waypoint_release ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data );
static gboolean tool_new_track_key_press ( VikTrwLayer *vtl, GdkEventKey *event, VikViewport *vvp );
static gpointer tool_new_waypoint_create ( VikWindow *vw, VikViewport *vvp);
static gboolean tool_new_waypoint_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
-#ifdef VIK_CONFIG_GOOGLE
static gpointer tool_route_finder_create ( VikWindow *vw, VikViewport *vvp);
static gboolean tool_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
-#endif
static void cached_pixbuf_free ( CachedPixbuf *cp );
static gint cached_pixbuf_cmp ( CachedPixbuf *cp, const gchar *name );
GDK_CURSOR_IS_PIXMAP, &cursor_new_route_pixbuf },
{ { "EditWaypoint", "vik-icon-Edit Waypoint", N_("_Edit Waypoint"), "<control><shift>E", N_("Edit Waypoint"), 0 },
- (VikToolConstructorFunc) tool_edit_waypoint_create, NULL, NULL, NULL,
+ (VikToolConstructorFunc) tool_edit_waypoint_create,
+ (VikToolDestructorFunc) tool_edit_waypoint_destroy,
+ NULL, NULL,
(VikToolMouseFunc) tool_edit_waypoint_click,
(VikToolMouseMoveFunc) tool_edit_waypoint_move,
(VikToolMouseFunc) tool_edit_waypoint_release, (VikToolKeyFunc) NULL,
GDK_CURSOR_IS_PIXMAP, &cursor_edwp_pixbuf },
{ { "EditTrackpoint", "vik-icon-Edit Trackpoint", N_("Edit Trac_kpoint"), "<control><shift>K", N_("Edit Trackpoint"), 0 },
- (VikToolConstructorFunc) tool_edit_trackpoint_create, NULL, NULL, NULL,
+ (VikToolConstructorFunc) tool_edit_trackpoint_create,
+ (VikToolDestructorFunc) tool_edit_trackpoint_destroy,
+ NULL, NULL,
(VikToolMouseFunc) tool_edit_trackpoint_click,
(VikToolMouseMoveFunc) tool_edit_trackpoint_move,
(VikToolMouseFunc) tool_edit_trackpoint_release, (VikToolKeyFunc) NULL,
FALSE,
GDK_CURSOR_IS_PIXMAP, &cursor_showpic_pixbuf },
-#ifdef VIK_CONFIG_GOOGLE
{ { "RouteFinder", "vik-icon-Route Finder", N_("Route _Finder"), "<control><shift>F", N_("Route Finder"), 0 },
(VikToolConstructorFunc) tool_route_finder_create, NULL, NULL, NULL,
(VikToolMouseFunc) tool_route_finder_click, NULL, NULL, (VikToolKeyFunc) NULL,
FALSE,
GDK_CURSOR_IS_PIXMAP, &cursor_route_finder_pixbuf },
-#endif
};
enum {
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_groups[] = { N_("Waypoints"), N_("Tracks"), N_("Waypoint Images"), N_("Tracks Advanced") };
+enum { GROUP_WAYPOINTS, GROUP_TRACKS, GROUP_IMAGES, GROUP_TRACKS_ADV };
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 };
N_("Extra Extra Large"),
NULL };
+// Needs to align with vik_layer_sort_order_t
+static gchar* params_sort_order[] = {
+ N_("None"),
+ N_("Name Ascending"),
+ N_("Name Descending"),
+ NULL
+};
+
+static VikLayerParamData black_color_default ( void ) {
+ VikLayerParamData data; gdk_color_parse ( "#000000", &data.c ); return data; // Black
+}
+static VikLayerParamData drawmode_default ( void ) { return VIK_LPD_UINT ( DRAWMODE_BY_TRACK ); }
+static VikLayerParamData line_thickness_default ( void ) { return VIK_LPD_UINT ( 1 ); }
+static VikLayerParamData trkpointsize_default ( void ) { return VIK_LPD_UINT ( MIN_POINT_SIZE ); }
+static VikLayerParamData trkdirectionsize_default ( void ) { return VIK_LPD_UINT ( 5 ); }
+static VikLayerParamData bg_line_thickness_default ( void ) { return VIK_LPD_UINT ( 0 ); }
+static VikLayerParamData trackbgcolor_default ( void ) {
+ VikLayerParamData data; gdk_color_parse ( "#FFFFFF", &data.c ); return data; // White
+}
+static VikLayerParamData elevation_factor_default ( void ) { return VIK_LPD_UINT ( 30 ); }
+static VikLayerParamData stop_length_default ( void ) { return VIK_LPD_UINT ( 60 ); }
+static VikLayerParamData speed_factor_default ( void ) { return VIK_LPD_DOUBLE ( 30.0 ); }
+
+static VikLayerParamData tnfontsize_default ( void ) { return VIK_LPD_UINT ( FS_MEDIUM ); }
+static VikLayerParamData wpfontsize_default ( void ) { return VIK_LPD_UINT ( FS_MEDIUM ); }
+static VikLayerParamData wptextcolor_default ( void ) {
+ VikLayerParamData data; gdk_color_parse ( "#FFFFFF", &data.c ); return data; // White
+}
+static VikLayerParamData wpbgcolor_default ( void ) {
+ VikLayerParamData data; gdk_color_parse ( "#8383C4", &data.c ); return data; // Kind of Blue
+}
+static VikLayerParamData wpsize_default ( void ) { return VIK_LPD_UINT ( 4 ); }
+static VikLayerParamData wpsymbol_default ( void ) { return VIK_LPD_UINT ( WP_SYMBOL_FILLED_SQUARE ); }
+
+static VikLayerParamData image_size_default ( void ) { return VIK_LPD_UINT ( 64 ); }
+static VikLayerParamData image_alpha_default ( void ) { return VIK_LPD_UINT ( 255 ); }
+static VikLayerParamData image_cache_size_default ( void ) { return VIK_LPD_UINT ( 300 ); }
+
+static VikLayerParamData sort_order_default ( void ) { return VIK_LPD_UINT ( 0 ); }
+
VikLayerParam trw_layer_params[] = {
- { "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 },
+ { VIK_LAYER_TRW, "tracks_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL, NULL, vik_lpd_true_default, NULL, NULL },
+ { VIK_LAYER_TRW, "waypoints_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL, NULL, vik_lpd_true_default, NULL, NULL },
+ { VIK_LAYER_TRW, "routes_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL, NULL, vik_lpd_true_default, NULL, NULL },
+
+ { VIK_LAYER_TRW, "trackdrawlabels", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Labels"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL,
+ N_("Note: the individual track controls what labels may be displayed"), vik_lpd_true_default, NULL, NULL },
+ { VIK_LAYER_TRW, "trackfontsize", VIK_LAYER_PARAM_UINT, GROUP_TRACKS_ADV, N_("Track Labels Font Size:"), VIK_LAYER_WIDGET_COMBOBOX, params_font_sizes, NULL, NULL, tnfontsize_default, NULL, NULL },
+ { VIK_LAYER_TRW, "drawmode", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track Drawing Mode:"), VIK_LAYER_WIDGET_COMBOBOX, params_drawmodes, NULL, NULL, drawmode_default, NULL, NULL },
+ { VIK_LAYER_TRW, "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"), black_color_default, NULL, NULL },
+ { VIK_LAYER_TRW, "drawlines", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Track Lines"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL, vik_lpd_true_default, NULL, NULL },
+ { VIK_LAYER_TRW, "line_thickness", VIK_LAYER_PARAM_UINT, GROUP_TRACKS_ADV, N_("Track Thickness:"), VIK_LAYER_WIDGET_SPINBUTTON, ¶ms_scales[0], NULL, NULL, line_thickness_default, NULL, NULL },
+ { VIK_LAYER_TRW, "drawdirections", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Track Direction"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL, vik_lpd_false_default, NULL, NULL },
+ { VIK_LAYER_TRW, "trkdirectionsize", VIK_LAYER_PARAM_UINT, GROUP_TRACKS_ADV, N_("Direction Size:"), VIK_LAYER_WIDGET_SPINBUTTON, ¶ms_scales[11], NULL, NULL, trkdirectionsize_default, NULL, NULL },
+ { VIK_LAYER_TRW, "drawpoints", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Trackpoints"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL, vik_lpd_true_default, NULL, NULL },
+ { VIK_LAYER_TRW, "trkpointsize", VIK_LAYER_PARAM_UINT, GROUP_TRACKS_ADV, N_("Trackpoint Size:"), VIK_LAYER_WIDGET_SPINBUTTON, ¶ms_scales[10], NULL, NULL, trkpointsize_default, NULL, NULL },
+ { VIK_LAYER_TRW, "drawelevation", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Elevation"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL, vik_lpd_false_default, NULL, NULL },
+ { VIK_LAYER_TRW, "elevation_factor", VIK_LAYER_PARAM_UINT, GROUP_TRACKS_ADV, N_("Draw Elevation Height %:"), VIK_LAYER_WIDGET_HSCALE, ¶ms_scales[9], NULL, NULL, elevation_factor_default, NULL, NULL },
+ { VIK_LAYER_TRW, "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"), vik_lpd_false_default, NULL, NULL },
+ { VIK_LAYER_TRW, "stop_length", VIK_LAYER_PARAM_UINT, GROUP_TRACKS_ADV, N_("Min Stop Length (seconds):"), VIK_LAYER_WIDGET_SPINBUTTON, ¶ms_scales[8], NULL, NULL, stop_length_default, NULL, NULL },
+
+ { VIK_LAYER_TRW, "bg_line_thickness", VIK_LAYER_PARAM_UINT, GROUP_TRACKS_ADV, N_("Track BG Thickness:"), VIK_LAYER_WIDGET_SPINBUTTON, ¶ms_scales[6], NULL, NULL, bg_line_thickness_default, NULL, NULL },
+ { VIK_LAYER_TRW, "trackbgcolor", VIK_LAYER_PARAM_COLOR, GROUP_TRACKS_ADV, N_("Track Background Color"), VIK_LAYER_WIDGET_COLOR, NULL, NULL, NULL, trackbgcolor_default, NULL, NULL },
+ { VIK_LAYER_TRW, "speed_factor", VIK_LAYER_PARAM_DOUBLE, GROUP_TRACKS_ADV, 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"), speed_factor_default, NULL, NULL },
+ { VIK_LAYER_TRW, "tracksortorder", VIK_LAYER_PARAM_UINT, GROUP_TRACKS_ADV, N_("Track Sort Order:"), VIK_LAYER_WIDGET_COMBOBOX, params_sort_order, NULL, NULL, sort_order_default, NULL, NULL },
+
+ { VIK_LAYER_TRW, "drawlabels", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, N_("Draw Labels"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL, vik_lpd_true_default, NULL, NULL },
+ { VIK_LAYER_TRW, "wpfontsize", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint Font Size:"), VIK_LAYER_WIDGET_COMBOBOX, params_font_sizes, NULL, NULL, wpfontsize_default, NULL, NULL },
+ { VIK_LAYER_TRW, "wpcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Waypoint Color:"), VIK_LAYER_WIDGET_COLOR, NULL, NULL, NULL, black_color_default, NULL, NULL },
+ { VIK_LAYER_TRW, "wptextcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Waypoint Text:"), VIK_LAYER_WIDGET_COLOR, NULL, NULL, NULL, wptextcolor_default, NULL, NULL },
+ { VIK_LAYER_TRW, "wpbgcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Background:"), VIK_LAYER_WIDGET_COLOR, NULL, NULL, NULL, wpbgcolor_default, NULL, NULL },
+ { VIK_LAYER_TRW, "wpbgand", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, N_("Fake BG Color Translucency:"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL, vik_lpd_false_default, NULL, NULL },
+ { VIK_LAYER_TRW, "wpsymbol", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint marker:"), VIK_LAYER_WIDGET_COMBOBOX, params_wpsymbols, NULL, NULL, wpsymbol_default, NULL, NULL },
+ { VIK_LAYER_TRW, "wpsize", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint size:"), VIK_LAYER_WIDGET_SPINBUTTON, ¶ms_scales[7], NULL, NULL, wpsize_default, NULL, NULL },
+ { VIK_LAYER_TRW, "wpsyms", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, N_("Draw Waypoint Symbols:"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL, vik_lpd_true_default, NULL, NULL },
+ { VIK_LAYER_TRW, "wpsortorder", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint Sort Order:"), VIK_LAYER_WIDGET_COMBOBOX, params_sort_order, NULL, NULL, sort_order_default, NULL, NULL },
+
+ { VIK_LAYER_TRW, "drawimages", VIK_LAYER_PARAM_BOOLEAN, GROUP_IMAGES, N_("Draw Waypoint Images"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL, vik_lpd_true_default, NULL, NULL },
+ { VIK_LAYER_TRW, "image_size", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, N_("Image Size (pixels):"), VIK_LAYER_WIDGET_HSCALE, ¶ms_scales[3], NULL, NULL, image_size_default, NULL, NULL },
+ { VIK_LAYER_TRW, "image_alpha", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, N_("Image Alpha:"), VIK_LAYER_WIDGET_HSCALE, ¶ms_scales[4], NULL, NULL, image_alpha_default, NULL, NULL },
+ { VIK_LAYER_TRW, "image_cache_size", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, N_("Image Memory Cache Size:"), VIK_LAYER_WIDGET_HSCALE, ¶ms_scales[5], NULL, NULL, image_cache_size_default, NULL, NULL },
};
// ENUMERATION MUST BE IN THE SAME ORDER AS THE NAMED PARAMS ABOVE
PARAM_WV,
PARAM_RV,
// Tracks
+ PARAM_TDL,
+ PARAM_TLFONTSIZE,
PARAM_DM,
PARAM_TC,
PARAM_DL,
PARAM_BLT,
PARAM_TBGC,
PARAM_TDSF,
+ PARAM_TSO,
// Waypoints
PARAM_DLA,
PARAM_WPFONTSIZE,
PARAM_WPSYM,
PARAM_WPSIZE,
PARAM_WPSYMS,
+ PARAM_WPSO,
// WP images
PARAM_DI,
PARAM_IS,
/****** END PARAMETERS ******/
-static VikTrwLayer* trw_layer_new ( gint drawmode );
/* Layer Interface function definitions */
static VikTrwLayer* trw_layer_create ( VikViewport *vp );
static void trw_layer_realize ( VikTrwLayer *vtl, VikTreeview *vt, GtkTreeIter *layer_iter );
-static void trw_layer_post_read ( VikTrwLayer *vtl, GtkWidget *vvp );
+static void trw_layer_post_read ( VikTrwLayer *vtl, GtkWidget *vvp, gboolean from_file );
static void trw_layer_free ( VikTrwLayer *trwlayer );
static void trw_layer_draw ( VikTrwLayer *l, gpointer data );
static void trw_layer_change_coord_mode ( VikTrwLayer *vtl, VikCoordMode dest_mode );
name = trw_layer_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_WAYPOINT, w->name);
vik_trw_layer_add_waypoint ( vtl, name, w );
waypoint_convert (NULL, w, &vtl->coord_mode);
+ g_free ( name );
+
+ trw_layer_calculate_bounds_waypoints ( vtl );
// Consider if redraw necessary for the new item
if ( vtl->vl.visible && vtl->waypoints_visible && w->visible )
name = trw_layer_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, t->name);
vik_trw_layer_add_track ( vtl, name, t );
vik_track_convert (t, vtl->coord_mode);
+ g_free ( name );
// Consider if redraw necessary for the new item
if ( vtl->vl.visible && vtl->tracks_visible && t->visible )
name = trw_layer_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_ROUTE, t->name);
vik_trw_layer_add_route ( vtl, name, t );
vik_track_convert (t, vtl->coord_mode);
+ g_free ( name );
// Consider if redraw necessary for the new item
if ( vtl->vl.visible && vtl->routes_visible && t->visible )
case PARAM_TV: vtl->tracks_visible = data.b; break;
case PARAM_WV: vtl->waypoints_visible = data.b; break;
case PARAM_RV: vtl->routes_visible = data.b; break;
+ case PARAM_TDL: vtl->track_draw_labels = data.b; break;
+ case PARAM_TLFONTSIZE:
+ if ( data.u < FS_NUM_SIZES ) {
+ vtl->track_font_size = data.u;
+ g_free ( vtl->track_fsize_str );
+ switch ( vtl->track_font_size ) {
+ case FS_XX_SMALL: vtl->track_fsize_str = g_strdup ( "xx-small" ); break;
+ case FS_X_SMALL: vtl->track_fsize_str = g_strdup ( "x-small" ); break;
+ case FS_SMALL: vtl->track_fsize_str = g_strdup ( "small" ); break;
+ case FS_LARGE: vtl->track_fsize_str = g_strdup ( "large" ); break;
+ case FS_X_LARGE: vtl->track_fsize_str = g_strdup ( "x-large" ); break;
+ case FS_XX_LARGE: vtl->track_fsize_str = g_strdup ( "xx-large" ); break;
+ default: vtl->track_fsize_str = g_strdup ( "medium" ); break;
+ }
+ }
+ break;
case PARAM_DM: vtl->drawmode = data.u; break;
case PARAM_TC:
vtl->track_color = data.c;
- trw_layer_new_track_gcs ( vtl, vp );
+ if ( vp ) trw_layer_new_track_gcs ( vtl, vp );
break;
case PARAM_DP: vtl->drawpoints = data.b; break;
case PARAM_DPS:
case PARAM_LT: if ( data.u > 0 && data.u < 15 && data.u != vtl->line_thickness )
{
vtl->line_thickness = data.u;
- trw_layer_new_track_gcs ( vtl, vp );
+ if ( vp ) trw_layer_new_track_gcs ( vtl, vp );
}
break;
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 );
+ if ( vp ) trw_layer_new_track_gcs ( vtl, vp );
}
break;
- case PARAM_TBGC: gdk_gc_set_rgb_fg_color(vtl->track_bg_gc, &(data.c)); break;
+ case PARAM_TBGC:
+ vtl->track_bg_color = data.c;
+ if ( vtl->track_bg_gc )
+ gdk_gc_set_rgb_fg_color(vtl->track_bg_gc, &(vtl->track_bg_color));
+ break;
case PARAM_TDSF: vtl->track_draw_speed_factor = data.d; break;
+ case PARAM_TSO: if ( data.u < VL_SO_LAST ) vtl->track_sort_order = data.u; break;
case PARAM_DLA: vtl->drawlabels = data.b; break;
case PARAM_DI: vtl->drawimages = data.b; break;
case PARAM_IS: if ( data.u != vtl->image_size )
while ( vtl->image_cache->length > vtl->image_cache_size ) /* if shrinking cache_size, free pixbuf ASAP */
cached_pixbuf_free ( g_queue_pop_tail ( vtl->image_cache ) );
break;
- case PARAM_WPC: gdk_gc_set_rgb_fg_color(vtl->waypoint_gc, &(data.c)); break;
- case PARAM_WPTC: gdk_gc_set_rgb_fg_color(vtl->waypoint_text_gc, &(data.c)); break;
- case PARAM_WPBC: gdk_gc_set_rgb_fg_color(vtl->waypoint_bg_gc, &(data.c)); break;
- case PARAM_WPBA: gdk_gc_set_function(vtl->waypoint_bg_gc, data.b ? GDK_AND : GDK_COPY ); break;
+ case PARAM_WPC:
+ vtl->waypoint_color = data.c;
+ if ( vtl->waypoint_gc )
+ gdk_gc_set_rgb_fg_color(vtl->waypoint_gc, &(vtl->waypoint_color));
+ break;
+ case PARAM_WPTC:
+ vtl->waypoint_text_color = data.c;
+ if ( vtl->waypoint_text_gc )
+ gdk_gc_set_rgb_fg_color(vtl->waypoint_text_gc, &(vtl->waypoint_text_color));
+ break;
+ case PARAM_WPBC:
+ vtl->waypoint_bg_color = data.c;
+ if ( vtl->waypoint_bg_gc )
+ gdk_gc_set_rgb_fg_color(vtl->waypoint_bg_gc, &(vtl->waypoint_bg_color));
+ break;
+ case PARAM_WPBA:
+ vtl->wpbgand = data.b;
+ if ( vtl->waypoint_bg_gc )
+ 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;
- case PARAM_WPFONTSIZE: if ( data.u < FS_NUM_SIZES ) vtl->wp_font_size = data.u; break;
+ case PARAM_WPFONTSIZE:
+ if ( data.u < FS_NUM_SIZES ) {
+ vtl->wp_font_size = data.u;
+ g_free ( vtl->wp_fsize_str );
+ switch ( vtl->wp_font_size ) {
+ case FS_XX_SMALL: vtl->wp_fsize_str = g_strdup ( "xx-small" ); break;
+ case FS_X_SMALL: vtl->wp_fsize_str = g_strdup ( "x-small" ); break;
+ case FS_SMALL: vtl->wp_fsize_str = g_strdup ( "small" ); break;
+ case FS_LARGE: vtl->wp_fsize_str = g_strdup ( "large" ); break;
+ case FS_X_LARGE: vtl->wp_fsize_str = g_strdup ( "x-large" ); break;
+ case FS_XX_LARGE: vtl->wp_fsize_str = g_strdup ( "xx-large" ); break;
+ default: vtl->wp_fsize_str = g_strdup ( "medium" ); break;
+ }
+ }
+ break;
+ case PARAM_WPSO: if ( data.u < VL_SO_LAST ) vtl->wp_sort_order = data.u; break;
}
return TRUE;
}
case PARAM_TV: rv.b = vtl->tracks_visible; break;
case PARAM_WV: rv.b = vtl->waypoints_visible; break;
case PARAM_RV: rv.b = vtl->routes_visible; break;
+ case PARAM_TDL: rv.b = vtl->track_draw_labels; break;
+ case PARAM_TLFONTSIZE: rv.u = vtl->track_font_size; 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_BLT: rv.u = vtl->bg_line_thickness; break;
case PARAM_DLA: rv.b = vtl->drawlabels; break;
case PARAM_DI: rv.b = vtl->drawimages; break;
- case PARAM_TBGC: vik_gc_get_fg_color(vtl->track_bg_gc, &(rv.c)); break;
+ case PARAM_TBGC: rv.c = vtl->track_bg_color; break;
case PARAM_TDSF: rv.d = vtl->track_draw_speed_factor; break;
+ case PARAM_TSO: rv.u = vtl->track_sort_order; break;
case PARAM_IS: rv.u = vtl->image_size; break;
case PARAM_IA: rv.u = vtl->image_alpha; break;
case PARAM_ICS: rv.u = vtl->image_cache_size; break;
- case PARAM_WPC: vik_gc_get_fg_color(vtl->waypoint_gc, &(rv.c)); break;
- case PARAM_WPTC: vik_gc_get_fg_color(vtl->waypoint_text_gc, &(rv.c)); break;
- case PARAM_WPBC: vik_gc_get_fg_color(vtl->waypoint_bg_gc, &(rv.c)); break;
- case PARAM_WPBA: rv.b = (vik_gc_get_function(vtl->waypoint_bg_gc)==GDK_AND); break;
+ case PARAM_WPC: rv.c = vtl->waypoint_color; break;
+ case PARAM_WPTC: rv.c = vtl->waypoint_text_color; break;
+ case PARAM_WPBC: rv.c = vtl->waypoint_bg_color; break;
+ case PARAM_WPBA: rv.b = vtl->wpbgand; 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;
case PARAM_WPFONTSIZE: rv.u = vtl->wp_font_size; break;
+ case PARAM_WPSO: rv.u = vtl->wp_sort_order; break;
}
return rv;
}
}
//g_debug ("consumed_length %d vs len %d", consumed_length, len);
+ // Not stored anywhere else so need to regenerate
+ trw_layer_calculate_bounds_waypoints ( vtl );
+
return vtl;
}
}
*/
-static VikTrwLayer* trw_layer_new ( gint drawmode )
+// Stick a 1 at the end of the function name to make it more unique
+// thus more easily searchable in a simple text editor
+static VikTrwLayer* trw_layer_new1 ( VikViewport *vvp )
{
VikTrwLayer *rv = VIK_TRW_LAYER ( g_object_new ( VIK_TRW_LAYER_TYPE, NULL ) );
vik_layer_set_type ( VIK_LAYER(rv), VIK_LAYER_TRW );
rv->routes = g_hash_table_new_full ( g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) vik_track_free );
rv->routes_iters = g_hash_table_new_full ( g_direct_hash, g_direct_equal, NULL, g_free );
- // Default values
+ rv->image_cache = g_queue_new(); // Must be performed before set_params via set_defaults
+
+ vik_layer_set_defaults ( VIK_LAYER(rv), vvp );
+
+ // Param settings that are not available via the GUI
+ // Force to on after processing params (which defaults them to off with a zero value)
rv->waypoints_visible = rv->tracks_visible = rv->routes_visible = TRUE;
- rv->drawmode = drawmode;
- rv->drawpoints = TRUE;
- rv->drawpoints_size = MIN_POINT_SIZE;
- rv->drawdirections_size = 5;
- rv->elevation_factor = 30;
- rv->stop_length = 60;
- rv->drawlines = TRUE;
- rv->track_draw_speed_factor = 30.0;
- rv->line_thickness = 1;
rv->draw_sync_done = TRUE;
rv->draw_sync_do = TRUE;
-
- rv->image_cache = g_queue_new();
- rv->image_size = 64;
- rv->image_alpha = 255;
- rv->image_cache_size = 300;
- rv->drawimages = TRUE;
- rv->drawlabels = TRUE;
// Everything else is 0, FALSE or NULL
return rv;
static void trw_layer_free ( VikTrwLayer *trwlayer )
{
g_hash_table_destroy(trwlayer->waypoints);
+ g_hash_table_destroy(trwlayer->waypoints_iters);
g_hash_table_destroy(trwlayer->tracks);
+ g_hash_table_destroy(trwlayer->tracks_iters);
+ g_hash_table_destroy(trwlayer->routes);
+ g_hash_table_destroy(trwlayer->routes_iters);
/* ODC: replace with GArray */
trw_layer_free_track_gcs ( trwlayer );
if ( trwlayer->track_right_click_menu )
g_object_ref_sink ( G_OBJECT(trwlayer->track_right_click_menu) );
+ if ( trwlayer->tracklabellayout != NULL)
+ g_object_unref ( G_OBJECT ( trwlayer->tracklabellayout ) );
+
if ( trwlayer->wplabellayout != NULL)
g_object_unref ( G_OBJECT ( trwlayer->wplabellayout ) );
if ( trwlayer->waypoint_bg_gc != NULL )
g_object_unref ( G_OBJECT ( trwlayer->waypoint_bg_gc ) );
+ g_free ( trwlayer->wp_fsize_str );
+ g_free ( trwlayer->track_fsize_str );
+
if ( trwlayer->tpwin != NULL )
gtk_widget_destroy ( GTK_WIDGET(trwlayer->tpwin) );
+ if ( trwlayer->tracks_analysis_dialog != NULL )
+ gtk_widget_destroy ( GTK_WIDGET(trwlayer->tracks_analysis_dialog) );
+
g_list_foreach ( trwlayer->image_cache->head, (GFunc) cached_pixbuf_free, NULL );
g_queue_free ( trwlayer->image_cache );
}
dp->cn1 = bottomright.north_south;
dp->cn2 = upperleft.north_south;
}
+
+ vik_viewport_get_min_max_lat_lon ( vp, &(dp->bbox.south), &(dp->bbox.north), &(dp->bbox.west), &(dp->bbox.east) );
}
/*
vik_viewport_draw_line ( vvp, gc, x+5, y-5, x-5, y+5 );
}
+
+static void trw_layer_draw_track_label ( gchar *name, gchar *fgcolour, gchar *bgcolour, struct DrawingParams *dp, VikCoord *coord )
+{
+ gchar *label_markup = g_strdup_printf ( "<span foreground=\"%s\" background=\"%s\" size=\"%s\">%s</span>", fgcolour, bgcolour, dp->vtl->track_fsize_str, name );
+
+ if ( pango_parse_markup ( label_markup, -1, 0, NULL, NULL, NULL, NULL ) )
+ pango_layout_set_markup ( dp->vtl->tracklabellayout, label_markup, -1 );
+ else
+ // Fallback if parse failure
+ pango_layout_set_text ( dp->vtl->tracklabellayout, name, -1 );
+
+ g_free ( label_markup );
+
+ gint label_x, label_y;
+ gint width, height;
+ pango_layout_get_pixel_size ( dp->vtl->tracklabellayout, &width, &height );
+
+ vik_viewport_coord_to_screen ( dp->vp, coord, &label_x, &label_y );
+ vik_viewport_draw_layout ( dp->vp, dp->vtl->track_bg_gc, label_x-width/2, label_y-height/2, dp->vtl->tracklabellayout );
+}
+
+/**
+ * distance_in_preferred_units:
+ * @dist: The source distance in standard SI Units (i.e. metres)
+ *
+ * TODO: This is a generic function that could be moved into globals.c or utils.c
+ *
+ * Probably best used if you have a only few conversions to perform.
+ * However if doing many points (such as on all points along a track) then this may be a bit slow,
+ * since it will be doing the preference check on each call
+ *
+ * Returns: The distance in the units as specified by the preferences
+ */
+static gdouble distance_in_preferred_units ( gdouble dist )
+{
+ gdouble mydist;
+ vik_units_distance_t dist_units = a_vik_get_units_distance ();
+ switch (dist_units) {
+ case VIK_UNITS_DISTANCE_MILES:
+ mydist = VIK_METERS_TO_MILES(dist);
+ break;
+ // VIK_UNITS_DISTANCE_KILOMETRES:
+ default:
+ mydist = dist/1000.0;
+ break;
+ }
+ return mydist;
+}
+
+/**
+ * trw_layer_draw_dist_labels:
+ *
+ * Draw a few labels along a track at nicely seperated distances
+ * This might slow things down if there's many tracks being displayed with this on.
+ */
+static void trw_layer_draw_dist_labels ( struct DrawingParams *dp, VikTrack *trk, gboolean drawing_highlight )
+{
+ static const gdouble chunksd[] = {0.25, 0.5, 1.0, 2.0, 5.0, 10.0, 15.0, 20.0,
+ 25.0, 40.0, 50.0, 75.0, 100.0,
+ 150.0, 200.0, 250.0, 500.0, 1000.0};
+
+ gdouble dist = vik_track_get_length_including_gaps ( trk ) / (trk->max_number_dist_labels+1);
+
+ // Convert to specified unit to find the friendly breakdown value
+ dist = distance_in_preferred_units ( dist );
+
+ gint index = 0;
+ gint i=0;
+ for ( i = 0; i < G_N_ELEMENTS(chunksd); i++ ) {
+ if ( chunksd[i] > dist ) {
+ index = i;
+ dist = chunksd[index];
+ break;
+ }
+ }
+
+ vik_units_distance_t dist_units = a_vik_get_units_distance ();
+
+ for ( i = 1; i < trk->max_number_dist_labels+1; i++ ) {
+ gdouble dist_i = dist * i;
+
+ // Convert distance back into metres for use in finding a trackpoint
+ switch (dist_units) {
+ case VIK_UNITS_DISTANCE_MILES:
+ dist_i = VIK_MILES_TO_METERS(dist_i);
+ break;
+ // VIK_UNITS_DISTANCE_KILOMETRES:
+ default:
+ dist_i = dist_i*1000.0;
+ break;
+ }
+
+ gdouble dist_current = 0.0;
+ VikTrackpoint *tp_current = vik_track_get_tp_by_dist ( trk, dist_i, FALSE, &dist_current );
+ gdouble dist_next = 0.0;
+ VikTrackpoint *tp_next = vik_track_get_tp_by_dist ( trk, dist_i, TRUE, &dist_next );
+
+ gdouble dist_between_tps = fabs (dist_next - dist_current);
+ gdouble ratio = 0.0;
+ // Prevent division by 0 errors
+ if ( dist_between_tps > 0.0 )
+ ratio = fabs(dist_i-dist_current)/dist_between_tps;
+
+ if ( tp_current && tp_next ) {
+ // Construct the name based on the distance value
+ gchar *name;
+ gchar *units;
+ switch (dist_units) {
+ case VIK_UNITS_DISTANCE_MILES:
+ units = g_strdup ( _("miles") );
+ break;
+ // VIK_UNITS_DISTANCE_KILOMETRES:
+ default:
+ units = g_strdup ( _("km") );
+ break;
+ }
+
+ // Convert for display
+ dist_i = distance_in_preferred_units ( dist_i );
+
+ // Make the precision of the output related to the unit size.
+ if ( index == 0 )
+ name = g_strdup_printf ( "%.2f %s", dist_i, units);
+ else if ( index == 1 )
+ name = g_strdup_printf ( "%.1f %s", dist_i, units);
+ else
+ name = g_strdup_printf ( "%d %s", (gint)round(dist_i), units); // TODO single vs plurals
+ g_free ( units );
+
+ struct LatLon ll_current, ll_next;
+ vik_coord_to_latlon ( &tp_current->coord, &ll_current );
+ vik_coord_to_latlon ( &tp_next->coord, &ll_next );
+
+ // positional interpolation
+ // Using a simple ratio - may not be perfectly correct due to lat/long projections
+ // but should be good enough over the small scale that I anticipate usage on
+ struct LatLon ll_new = { ll_current.lat + (ll_next.lat-ll_current.lat)*ratio,
+ ll_current.lon + (ll_next.lon-ll_current.lon)*ratio };
+ VikCoord coord;
+ vik_coord_load_from_latlon ( &coord, dp->vtl->coord_mode, &ll_new );
+
+ gchar *fgcolour;
+ if ( dp->vtl->drawmode == DRAWMODE_BY_TRACK )
+ fgcolour = gdk_color_to_string ( &(trk->color) );
+ else
+ fgcolour = gdk_color_to_string ( &(dp->vtl->track_color) );
+
+ // if highlight mode on, then colour the background in the highlight colour
+ gchar *bgcolour;
+ if ( drawing_highlight )
+ bgcolour = g_strdup ( vik_viewport_get_highlight_color ( dp->vp ) );
+ else
+ bgcolour = gdk_color_to_string ( &(dp->vtl->track_bg_color) );
+
+ trw_layer_draw_track_label ( name, fgcolour, bgcolour, dp, &coord );
+
+ g_free ( fgcolour );
+ g_free ( bgcolour );
+ g_free ( name );
+ }
+ }
+}
+
+/**
+ * trw_layer_draw_track_name_labels:
+ *
+ * Draw a label (or labels) for the track name somewhere depending on the track's properties
+ */
+static void trw_layer_draw_track_name_labels ( struct DrawingParams *dp, VikTrack *trk, gboolean drawing_highlight )
+{
+ gchar *fgcolour;
+ if ( dp->vtl->drawmode == DRAWMODE_BY_TRACK )
+ fgcolour = gdk_color_to_string ( &(trk->color) );
+ else
+ fgcolour = gdk_color_to_string ( &(dp->vtl->track_color) );
+
+ // if highlight mode on, then colour the background in the highlight colour
+ gchar *bgcolour;
+ if ( drawing_highlight )
+ bgcolour = g_strdup ( vik_viewport_get_highlight_color ( dp->vp ) );
+ else
+ bgcolour = gdk_color_to_string ( &(dp->vtl->track_bg_color) );
+
+ gchar *ename = g_markup_escape_text ( trk->name, -1 );
+
+ if ( trk->draw_name_mode == TRACK_DRAWNAME_START_END_CENTRE ||
+ trk->draw_name_mode == TRACK_DRAWNAME_CENTRE ) {
+ struct LatLon average, maxmin[2] = { {0,0}, {0,0} };
+ trw_layer_find_maxmin_tracks ( NULL, trk, maxmin );
+ average.lat = (maxmin[0].lat+maxmin[1].lat)/2;
+ average.lon = (maxmin[0].lon+maxmin[1].lon)/2;
+ VikCoord coord;
+ vik_coord_load_from_latlon ( &coord, dp->vtl->coord_mode, &average );
+
+ trw_layer_draw_track_label ( ename, fgcolour, bgcolour, dp, &coord );
+ }
+
+ if ( trk->draw_name_mode == TRACK_DRAWNAME_CENTRE )
+ // No other labels to draw
+ return;
+
+ GList *ending = g_list_last ( trk->trackpoints );
+ VikCoord begin_coord = VIK_TRACKPOINT(trk->trackpoints->data)->coord;
+ VikCoord end_coord = VIK_TRACKPOINT(ending->data)->coord;
+
+ gboolean done_start_end = FALSE;
+
+ if ( trk->draw_name_mode == TRACK_DRAWNAME_START_END ||
+ trk->draw_name_mode == TRACK_DRAWNAME_START_END_CENTRE ) {
+
+ // This number can be configured via the settings if you really want to change it
+ gdouble distance_diff;
+ if ( ! a_settings_get_double ( "trackwaypoint_start_end_distance_diff", &distance_diff ) )
+ distance_diff = 100.0; // Metres
+
+ if ( vik_coord_diff ( &begin_coord, &end_coord ) < distance_diff ) {
+ // Start and end 'close' together so only draw one label at an average location
+ gint x1, x2, y1, y2;
+ vik_viewport_coord_to_screen ( dp->vp, &begin_coord, &x1, &y1);
+ vik_viewport_coord_to_screen ( dp->vp, &end_coord, &x2, &y2);
+ VikCoord av_coord;
+ vik_viewport_screen_to_coord ( dp->vp, (x1 + x2) / 2, (y1 + y2) / 2, &av_coord );
+
+ gchar *name = g_strdup_printf ( "%s: %s", ename, _("start/end") );
+ trw_layer_draw_track_label ( name, fgcolour, bgcolour, dp, &av_coord );
+ g_free ( name );
+
+ done_start_end = TRUE;
+ }
+ }
+
+ if ( ! done_start_end ) {
+ if ( trk->draw_name_mode == TRACK_DRAWNAME_START ||
+ trk->draw_name_mode == TRACK_DRAWNAME_START_END ||
+ trk->draw_name_mode == TRACK_DRAWNAME_START_END_CENTRE ) {
+ gchar *name_start = g_strdup_printf ( "%s: %s", ename, _("start") );
+ trw_layer_draw_track_label ( name_start, fgcolour, bgcolour, dp, &begin_coord );
+ g_free ( name_start );
+ }
+ // Don't draw end label if this is the one being created
+ if ( trk != dp->vtl->current_track ) {
+ if ( trk->draw_name_mode == TRACK_DRAWNAME_END ||
+ trk->draw_name_mode == TRACK_DRAWNAME_START_END ||
+ trk->draw_name_mode == TRACK_DRAWNAME_START_END_CENTRE ) {
+ gchar *name_end = g_strdup_printf ( "%s: %s", ename, _("end") );
+ trw_layer_draw_track_label ( name_end, fgcolour, bgcolour, dp, &end_coord );
+ g_free ( name_end );
+ }
+ }
+ }
+
+ g_free ( fgcolour );
+ g_free ( bgcolour );
+ g_free ( ename );
+}
+
static void trw_layer_draw_track ( const gpointer id, VikTrack *track, struct DrawingParams *dp, gboolean draw_track_outline )
{
+ if ( ! track->visible )
+ return;
+
/* TODO: this function is a mess, get rid of any redundancy */
GList *list = track->trackpoints;
GdkGC *main_gc;
alt_diff = max_alt - min_alt;
}
- if ( ! track->visible )
- return;
-
/* 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 ( id, track, dp, TRUE );
useoldvals = FALSE;
}
}
+
+ // Labels drawn after the trackpoints, so the labels are on top
+ if ( dp->vtl->track_draw_labels ) {
+ if ( track->max_number_dist_labels > 0 ) {
+ trw_layer_draw_dist_labels ( dp, track, drawing_highlight );
+ }
+
+ if ( track->draw_name_mode != TRACK_DRAWNAME_NO ) {
+ trw_layer_draw_track_name_labels ( dp, track, drawing_highlight );
+ }
+ }
}
}
-/* 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 gpointer id, VikTrack *track, struct DrawingParams *dp )
{
- trw_layer_draw_track ( id, track, dp, FALSE );
+ if ( BBOX_INTERSECT ( track->bbox, dp->bbox ) ) {
+ trw_layer_draw_track ( id, track, dp, FALSE );
+ }
}
static void cached_pixbuf_free ( CachedPixbuf *cp )
wp->coord.north_south > dp->cn1 && wp->coord.north_south < dp->cn2 ) )
{
gint x, y;
- GdkPixbuf *sym = NULL;
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 */
}
}
- /* DRAW ACTUAL DOT */
- 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 );
+ // Draw appropriate symbol - either symbol image or simple types
+ if ( dp->vtl->wp_draw_symbols && wp->symbol && wp->symbol_pixbuf ) {
+ vik_viewport_draw_pixbuf ( dp->vp, wp->symbol_pixbuf, 0, 0, x - gdk_pixbuf_get_width(wp->symbol_pixbuf)/2, y - gdk_pixbuf_get_height(wp->symbol_pixbuf)/2, -1, -1 );
}
else if ( wp == dp->vtl->current_wp ) {
switch ( dp->vtl->wp_symbol ) {
// Hopefully name won't break the markup (may need to sanitize - g_markup_escape_text())
// Could this stored in the waypoint rather than recreating each pass?
- gchar *fsize = NULL;
- switch (dp->vtl->wp_font_size) {
- case FS_XX_SMALL: fsize = g_strdup ( "xx-small" ); break;
- case FS_X_SMALL: fsize = g_strdup ( "x-small" ); break;
- case FS_SMALL: fsize = g_strdup ( "small" ); break;
- case FS_LARGE: fsize = g_strdup ( "large" ); break;
- case FS_X_LARGE: fsize = g_strdup ( "x-large" ); break;
- case FS_XX_LARGE: fsize = g_strdup ( "xx-large" ); break;
- default: fsize = g_strdup ( "medium" ); break;
- }
-
- gchar *wp_label_markup = g_strdup_printf ( "<span size=\"%s\">%s</span>", fsize, wp->name );
+ gchar *wp_label_markup = g_strdup_printf ( "<span size=\"%s\">%s</span>", dp->vtl->wp_fsize_str, wp->name );
if ( pango_parse_markup ( wp_label_markup, -1, 0, NULL, NULL, NULL, NULL ) )
pango_layout_set_markup ( dp->vtl->wplabellayout, wp_label_markup, -1 );
pango_layout_set_text ( dp->vtl->wplabellayout, wp->name, -1 );
g_free ( wp_label_markup );
- g_free ( fsize );
pango_layout_get_pixel_size ( dp->vtl->wplabellayout, &width, &height );
label_x = x - width/2;
- if (sym)
- label_y = y - height - 2 - gdk_pixbuf_get_height(sym)/2;
+ if ( wp->symbol_pixbuf )
+ label_y = y - height - 2 - gdk_pixbuf_get_height(wp->symbol_pixbuf)/2;
else
label_y = y - dp->vtl->wp_size - height - 2;
}
}
+static void trw_layer_draw_waypoint_cb ( gpointer id, VikWaypoint *wp, struct DrawingParams *dp )
+{
+ if ( BBOX_INTERSECT ( dp->vtl->waypoints_bbox, dp->bbox ) ) {
+ trw_layer_draw_waypoint ( id, wp, dp );
+ }
+}
+
static void trw_layer_draw ( VikTrwLayer *l, gpointer data )
{
static struct DrawingParams dp;
g_hash_table_foreach ( l->routes, (GHFunc) trw_layer_draw_track_cb, &dp );
if (l->waypoints_visible)
- g_hash_table_foreach ( l->waypoints, (GHFunc) trw_layer_draw_waypoint, &dp );
+ g_hash_table_foreach ( l->waypoints, (GHFunc) trw_layer_draw_waypoint_cb, &dp );
}
static void trw_layer_free_track_gcs ( VikTrwLayer *vtl )
if ( vtl->track_bg_gc )
g_object_unref ( vtl->track_bg_gc );
- vtl->track_bg_gc = vik_viewport_new_gc ( vp, "#FFFFFF", width + vtl->bg_line_thickness );
+ vtl->track_bg_gc = vik_viewport_new_gc_from_color ( vp, &(vtl->track_bg_color), width + vtl->bg_line_thickness );
// Ensure new track drawing heeds line thickness setting
// however always have a minium of 2, as 1 pixel is really narrow
static VikTrwLayer* trw_layer_create ( VikViewport *vp )
{
- VikTrwLayer *rv = trw_layer_new ( DRAWMODE_BY_TRACK );
+ VikTrwLayer *rv = trw_layer_new1 ( vp );
vik_layer_rename ( VIK_LAYER(rv), vik_trw_layer_interface.name );
- if ( vp == NULL || GTK_WIDGET(vp)->window == NULL ) {
+ if ( vp == NULL || gtk_widget_get_window(GTK_WIDGET(vp)) == NULL ) {
/* early exit, as the rest is GUI related */
return rv;
}
rv->wplabellayout = gtk_widget_create_pango_layout (GTK_WIDGET(vp), NULL);
pango_layout_set_font_description (rv->wplabellayout, gtk_widget_get_style(GTK_WIDGET(vp))->font_desc);
- gdk_color_parse ( "#000000", &(rv->track_color) ); // Black
+ rv->tracklabellayout = gtk_widget_create_pango_layout (GTK_WIDGET(vp), NULL);
+ pango_layout_set_font_description (rv->tracklabellayout, gtk_widget_get_style(GTK_WIDGET(vp))->font_desc);
trw_layer_new_track_gcs ( rv, vp );
- rv->waypoint_gc = vik_viewport_new_gc ( vp, "#000000", 2 );
- rv->waypoint_text_gc = vik_viewport_new_gc ( vp, "#FFFFFF", 1 );
- rv->waypoint_bg_gc = vik_viewport_new_gc ( vp, "#8383C4", 1 );
- gdk_gc_set_function ( rv->waypoint_bg_gc, GDK_AND );
-
- rv->has_verified_thumbnails = FALSE;
- rv->wp_symbol = WP_SYMBOL_FILLED_SQUARE;
- rv->wp_size = 4;
- rv->wp_draw_symbols = TRUE;
- rv->wp_font_size = FS_MEDIUM;
+ rv->waypoint_gc = vik_viewport_new_gc_from_color ( vp, &(rv->waypoint_color), 2 );
+ rv->waypoint_text_gc = vik_viewport_new_gc_from_color ( vp, &(rv->waypoint_text_color), 1 );
+ rv->waypoint_bg_gc = vik_viewport_new_gc_from_color ( vp, &(rv->waypoint_bg_color), 1 );
+ gdk_gc_set_function ( rv->waypoint_bg_gc, rv->wpbgand );
rv->coord_mode = vik_viewport_get_coord_mode ( vp );
gdk_pixbuf_fill ( pixbuf, pixel );
}
-#ifdef VIK_CONFIG_ALPHABETIZED_TRW
- vik_treeview_add_sublayer_alphabetized ( (VikTreeview *) pass_along[3], (GtkTreeIter *) pass_along[0], (GtkTreeIter *) pass_along[1], track->name, pass_along[2], id, GPOINTER_TO_INT (pass_along[4]), pixbuf, TRUE, TRUE );
-#else
vik_treeview_add_sublayer ( (VikTreeview *) pass_along[3], (GtkTreeIter *) pass_along[0], (GtkTreeIter *) pass_along[1], track->name, pass_along[2], id, GPOINTER_TO_INT (pass_along[4]), pixbuf, TRUE, TRUE );
-#endif
if ( pixbuf )
g_object_unref (pixbuf);
{
GtkTreeIter *new_iter = g_malloc(sizeof(GtkTreeIter));
-#ifdef VIK_CONFIG_ALPHABETIZED_TRW
- vik_treeview_add_sublayer_alphabetized ( (VikTreeview *) pass_along[3], (GtkTreeIter *) pass_along[0], (GtkTreeIter *) pass_along[1], wp->name, pass_along[2], id, GPOINTER_TO_INT (pass_along[4]), get_wp_sym_small (wp->symbol), TRUE, TRUE );
-#else
vik_treeview_add_sublayer ( (VikTreeview *) pass_along[3], (GtkTreeIter *) pass_along[0], (GtkTreeIter *) pass_along[1], wp->name, pass_along[2], id, GPOINTER_TO_UINT (pass_along[4]), get_wp_sym_small (wp->symbol), TRUE, TRUE );
-#endif
*new_iter = *((GtkTreeIter *) pass_along[1]);
g_hash_table_insert ( VIK_TRW_LAYER(pass_along[2])->waypoints_iters, id, new_iter );
static void trw_layer_add_sublayer_tracks ( VikTrwLayer *vtl, VikTreeview *vt, GtkTreeIter *layer_iter )
{
-#ifdef VIK_CONFIG_ALPHABETIZED_TRW
- vik_treeview_add_sublayer_alphabetized ( (VikTreeview *) vt, layer_iter, &(vtl->tracks_iter), _("Tracks"), vtl, NULL, VIK_TRW_LAYER_SUBLAYER_TRACKS, NULL, TRUE, FALSE );
-#else
vik_treeview_add_sublayer ( (VikTreeview *) vt, layer_iter, &(vtl->tracks_iter), _("Tracks"), vtl, NULL, VIK_TRW_LAYER_SUBLAYER_TRACKS, NULL, TRUE, FALSE );
-#endif
}
static void trw_layer_add_sublayer_waypoints ( VikTrwLayer *vtl, VikTreeview *vt, GtkTreeIter *layer_iter )
{
-#ifdef VIK_CONFIG_ALPHABETIZED_TRW
- vik_treeview_add_sublayer_alphabetized ( (VikTreeview *) vt, layer_iter, &(vtl->waypoints_iter), _("Waypoints"), vtl, NULL, VIK_TRW_LAYER_SUBLAYER_WAYPOINTS, NULL, TRUE, FALSE );
-#else
vik_treeview_add_sublayer ( (VikTreeview *) vt, layer_iter, &(vtl->waypoints_iter), _("Waypoints"), vtl, NULL, VIK_TRW_LAYER_SUBLAYER_WAYPOINTS, NULL, TRUE, FALSE );
-#endif
}
static void trw_layer_add_sublayer_routes ( VikTrwLayer *vtl, VikTreeview *vt, GtkTreeIter *layer_iter )
{
-#ifdef VIK_CONFIG_ALPHABETIZED_TRW
- vik_treeview_add_sublayer_alphabetized ( (VikTreeview *) vt, layer_iter, &(vtl->routes_iter), _("Routes"), vtl, NULL, VIK_TRW_LAYER_SUBLAYER_ROUTES, NULL, TRUE, FALSE );
-#else
vik_treeview_add_sublayer ( (VikTreeview *) vt, layer_iter, &(vtl->routes_iter), _("Routes"), vtl, NULL, VIK_TRW_LAYER_SUBLAYER_ROUTES, NULL, TRUE, FALSE );
-#endif
}
static void trw_layer_realize ( VikTrwLayer *vtl, VikTreeview *vt, GtkTreeIter *layer_iter )
if ( g_hash_table_size (vtl->tracks) > 0 ) {
trw_layer_add_sublayer_tracks ( vtl, vt , layer_iter );
+
g_hash_table_foreach ( vtl->tracks, (GHFunc) trw_layer_realize_track, pass_along );
- vik_treeview_item_set_visible ( (VikTreeview *) vt, &(vtl->tracks_iter), vtl->tracks_visible );
+ vik_treeview_item_set_visible ( vt, &(vtl->tracks_iter), vtl->tracks_visible );
}
if ( g_hash_table_size (vtl->routes) > 0 ) {
-
trw_layer_add_sublayer_routes ( vtl, vt, layer_iter );
pass_along[0] = &(vtl->routes_iter);
{
VikWaypoint *w = g_hash_table_lookup ( l->waypoints, sublayer );
// NB It's OK to return NULL
- if ( w )
- return w->comment;
+ if ( w ) {
+ if ( w->comment )
+ return w->comment;
+ else
+ return w->description;
+ }
}
break;
default: break;
return NULL;
}
-/*
- * Function to show basic track point information on the statusbar
+#define VIK_SETTINGS_TRKPT_SELECTED_STATUSBAR_FORMAT "trkpt_selected_statusbar_format"
+
+/**
+ * set_statusbar_msg_info_trkpt:
+ *
+ * Function to show track point information on the statusbar
+ * Items displayed is controlled by the settings format code
*/
static void set_statusbar_msg_info_trkpt ( VikTrwLayer *vtl, VikTrackpoint *trkpt )
{
- gchar tmp_buf1[64];
- switch (a_vik_get_units_height ()) {
- case VIK_UNITS_HEIGHT_FEET:
- g_snprintf(tmp_buf1, sizeof(tmp_buf1), _("Trkpt: Alt %dft"), (int)round(VIK_METERS_TO_FEET(trkpt->altitude)));
- break;
- default:
- //VIK_UNITS_HEIGHT_METRES:
- g_snprintf(tmp_buf1, sizeof(tmp_buf1), _("Trkpt: Alt %dm"), (int)round(trkpt->altitude));
- }
-
- gchar tmp_buf2[64];
- tmp_buf2[0] = '\0';
- if ( trkpt->has_timestamp ) {
- // Compact date time format
- strftime (tmp_buf2, sizeof(tmp_buf2), _(" | Time %x %X"), localtime(&(trkpt->timestamp)));
- }
-
- // Position part
- // Position is put later on, as this bit may not be seen if the display is not big enough,
- // one can easily use the current pointer position to see this if needed
- gchar *lat = NULL, *lon = NULL;
- static struct LatLon ll;
- vik_coord_to_latlon (&(trkpt->coord), &ll);
- a_coords_latlon_to_string ( &ll, &lat, &lon );
-
- // Track name
- // Again is put later on, as this bit may not be seen if the display is not big enough
- // trackname can be seen from the treeview (when enabled)
- // Also name could be very long to not leave room for anything else
- gchar tmp_buf3[64];
- tmp_buf3[0] = '\0';
- if ( vtl->current_tp_track ) {
- g_snprintf(tmp_buf3, sizeof(tmp_buf3), _(" | Track: %s"), vtl->current_tp_track->name );
+ gchar *statusbar_format_code = NULL;
+ gboolean need2free = FALSE;
+ if ( !a_settings_get_string ( VIK_SETTINGS_TRKPT_SELECTED_STATUSBAR_FORMAT, &statusbar_format_code ) ) {
+ // Otherwise use default
+ statusbar_format_code = g_strdup ( "KATDN" );
+ need2free = TRUE;
}
- // Combine parts to make overall message
- gchar *msg = g_strdup_printf (_("%s%s | %s %s %s"), tmp_buf1, tmp_buf2, lat, lon, tmp_buf3);
+ gchar *msg = vu_trackpoint_formatted_message ( statusbar_format_code, trkpt, NULL, vtl->current_tp_track );
vik_statusbar_set_message ( vik_window_get_statusbar (VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl))), VIK_STATUSBAR_INFO, msg );
- g_free ( lat );
- g_free ( lon );
g_free ( msg );
+
+ if ( need2free )
+ g_free ( statusbar_format_code );
}
/*
return l->waypoints;
}
+gboolean vik_trw_layer_is_empty ( VikTrwLayer *vtl )
+{
+ return ! ( g_hash_table_size ( vtl->tracks ) ||
+ g_hash_table_size ( vtl->routes ) ||
+ g_hash_table_size ( vtl->waypoints ) );
+}
+
+gboolean vik_trw_layer_get_tracks_visibility ( VikTrwLayer *vtl )
+{
+ return vtl->tracks_visible;
+}
+
+gboolean vik_trw_layer_get_routes_visibility ( VikTrwLayer *vtl )
+{
+ return vtl->routes_visible;
+}
+
+gboolean vik_trw_layer_get_waypoints_visibility ( VikTrwLayer *vtl )
+{
+ return vtl->waypoints_visible;
+}
+
/*
* ATM use a case sensitive find
* Finds the first one
return g_hash_table_find ( vtl->routes, (GHRFunc) trw_layer_track_find, (gpointer) name );
}
-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 );
- if ( VIK_LATLON(&fixme)->lat > maxmin[0].lat || maxmin[0].lat == 0.0 )
- maxmin[0].lat = VIK_LATLON(&fixme)->lat;
- if ( VIK_LATLON(&fixme)->lat < maxmin[1].lat || maxmin[1].lat == 0.0 )
- maxmin[1].lat = VIK_LATLON(&fixme)->lat;
- if ( VIK_LATLON(&fixme)->lon > maxmin[0].lon || maxmin[0].lon == 0.0 )
- maxmin[0].lon = VIK_LATLON(&fixme)->lon;
- if ( VIK_LATLON(&fixme)->lon < maxmin[1].lon || maxmin[1].lon == 0.0 )
- maxmin[1].lon = VIK_LATLON(&fixme)->lon;
-}
-
static void trw_layer_find_maxmin_tracks ( const gpointer id, const VikTrack *trk, struct LatLon maxmin[2] )
{
- GList *tr = trk->trackpoints;
- static VikCoord fixme;
-
- while ( tr )
- {
- vik_coord_copy_convert ( &(VIK_TRACKPOINT(tr->data)->coord), VIK_COORD_LATLON, &fixme );
- if ( VIK_LATLON(&fixme)->lat > maxmin[0].lat || maxmin[0].lat == 0.0 )
- maxmin[0].lat = VIK_LATLON(&fixme)->lat;
- if ( VIK_LATLON(&fixme)->lat < maxmin[1].lat || maxmin[1].lat == 0.0 )
- maxmin[1].lat = VIK_LATLON(&fixme)->lat;
- if ( VIK_LATLON(&fixme)->lon > maxmin[0].lon || maxmin[0].lon == 0.0 )
- maxmin[0].lon = VIK_LATLON(&fixme)->lon;
- if ( VIK_LATLON(&fixme)->lon < maxmin[1].lon || maxmin[1].lon == 0.0 )
- maxmin[1].lon = VIK_LATLON(&fixme)->lon;
- tr = tr->next;
- }
+ if ( trk->bbox.north > maxmin[0].lat || maxmin[0].lat == 0.0 )
+ maxmin[0].lat = trk->bbox.north;
+ if ( trk->bbox.south < maxmin[1].lat || maxmin[1].lat == 0.0 )
+ maxmin[1].lat = trk->bbox.south;
+ if ( trk->bbox.east > maxmin[0].lon || maxmin[0].lon == 0.0 )
+ maxmin[0].lon = trk->bbox.east;
+ if ( trk->bbox.west < maxmin[1].lon || maxmin[1].lon == 0.0 )
+ maxmin[1].lon = trk->bbox.west;
}
static void trw_layer_find_maxmin (VikTrwLayer *vtl, struct LatLon maxmin[2])
{
// Continually reuse maxmin to find the latest maximum and minimum values
- g_hash_table_foreach ( vtl->waypoints, (GHFunc) trw_layer_find_maxmin_waypoints, maxmin );
+ // First set to waypoints bounds
+ maxmin[0].lat = vtl->waypoints_bbox.north;
+ maxmin[1].lat = vtl->waypoints_bbox.south;
+ maxmin[0].lon = vtl->waypoints_bbox.east;
+ maxmin[1].lon = vtl->waypoints_bbox.west;
g_hash_table_foreach ( vtl->tracks, (GHFunc) trw_layer_find_maxmin_tracks, maxmin );
g_hash_table_foreach ( vtl->routes, (GHFunc) trw_layer_find_maxmin_tracks, maxmin );
}
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
NULL);
+ gchar *cwd = g_get_current_dir();
+ if ( cwd ) {
+ gtk_file_chooser_set_current_folder ( GTK_FILE_CHOOSER(file_selector), cwd );
+ g_free ( cwd );
+ }
+
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER(file_selector), default_name);
while ( gtk_dialog_run ( GTK_DIALOG(file_selector) ) == GTK_RESPONSE_ACCEPT )
if ( g_file_test ( fn, G_FILE_TEST_EXISTS ) == FALSE )
{
gtk_widget_hide ( file_selector );
+ vik_window_set_busy_cursor ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(layer_and_vlp[0])) );
failed = ! a_file_export ( VIK_TRW_LAYER(layer_and_vlp[0]), fn, file_type, trk, TRUE );
+ vik_window_clear_busy_cursor ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(layer_and_vlp[0])) );
break;
}
else
if ( a_dialog_yes_or_no ( GTK_WINDOW(file_selector), _("The file \"%s\" exists, do you wish to overwrite it?"), a_file_basename ( fn ) ) )
{
gtk_widget_hide ( file_selector );
+ vik_window_set_busy_cursor ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(layer_and_vlp[0])) );
failed = ! a_file_export ( VIK_TRW_LAYER(layer_and_vlp[0]), fn, file_type, trk, TRUE );
+ vik_window_clear_busy_cursor ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(layer_and_vlp[0])) );
break;
}
}
int fd;
if ((fd = g_file_open_tmp("tmp-viking.XXXXXX.gpx", &name_used, NULL)) >= 0) {
+ vik_window_set_busy_cursor ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(layer_and_vlp[0])) );
gboolean failed = ! a_file_export ( VIK_TRW_LAYER(layer_and_vlp[0]), name_used, FILE_TYPE_GPX, NULL, TRUE);
+ vik_window_clear_busy_cursor ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(layer_and_vlp[0])) );
if (failed) {
a_dialog_error_msg (VIK_GTK_WINDOW_FROM_LAYER(layer_and_vlp[0]), _("Could not create temporary file for export.") );
}
label = gtk_label_new(_("Waypoint Name:"));
entry = gtk_entry_new();
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dia)->vbox), label, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dia)->vbox), entry, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dia))), label, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dia))), entry, FALSE, FALSE, 0);
gtk_widget_show_all ( label );
gtk_widget_show_all ( entry );
wp->coord = *def_coord;
// Attempt to auto set height if DEM data is available
- gint16 elev = a_dems_get_elev_by_coord ( &(wp->coord), VIK_DEM_INTERPOL_BEST );
- if ( elev != VIK_DEM_INVALID_ELEVATION )
- wp->altitude = (gdouble)elev;
+ vik_waypoint_apply_dem_data ( wp, TRUE );
- returned_name = a_dialog_waypoint ( w, default_name, wp, vtl->coord_mode, TRUE, &updated );
+ returned_name = a_dialog_waypoint ( w, default_name, vtl, wp, vtl->coord_mode, TRUE, &updated );
if ( returned_name )
{
// 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);
+ trw_layer_calculate_bounds_waypoints ( vtl );
vik_layers_panel_emit_update ( vlp );
}
trw_layer_find_maxmin (vtl, maxmin);
a_geonames_wikipedia_box((VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl)), vtl, maxmin);
+ trw_layer_calculate_bounds_waypoints ( vtl );
vik_layers_panel_emit_update ( vlp );
}
VikViewport *vvp = vik_window_viewport(vw);
vik_datasource_gps_interface.mode = VIK_DATASOURCE_ADDTOLAYER;
- a_acquire ( vw, vlp, vvp, &vik_datasource_gps_interface );
+ a_acquire ( vw, vlp, vvp, &vik_datasource_gps_interface, NULL, NULL );
}
-#ifdef VIK_CONFIG_GOOGLE
/*
- * Acquire into this TRW Layer from Google Directions
+ * Acquire into this TRW Layer from Directions
*/
-static void trw_layer_acquire_google_cb ( gpointer lav[2] )
+static void trw_layer_acquire_routing_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_google_interface );
+ a_acquire ( vw, vlp, vvp, &vik_datasource_routing_interface, NULL, NULL );
}
-#endif
#ifdef VIK_CONFIG_OPENSTREETMAP
/*
VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl));
VikViewport *vvp = vik_window_viewport(vw);
- a_acquire ( vw, vlp, vvp, &vik_datasource_osm_interface );
+ a_acquire ( vw, vlp, vvp, &vik_datasource_osm_interface, NULL, NULL );
}
/**
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 );
+ a_acquire ( vw, vlp, vvp, &vik_datasource_osm_my_traces_interface, NULL, NULL );
}
#endif
VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl));
VikViewport *vvp = vik_window_viewport(vw);
- a_acquire ( vw, vlp, vvp, &vik_datasource_gc_interface );
+ a_acquire ( vw, vlp, vvp, &vik_datasource_gc_interface, NULL, NULL );
}
#endif
VikViewport *vvp = vik_window_viewport(vw);
vik_datasource_geotag_interface.mode = VIK_DATASOURCE_ADDTOLAYER;
- a_acquire ( vw, vlp, vvp, &vik_datasource_geotag_interface );
+ a_acquire ( vw, vlp, vvp, &vik_datasource_geotag_interface, NULL, NULL );
// Reverify thumbnails as they may have changed
vtl->has_verified_thumbnails = FALSE;
VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl));
VikViewport *vvp = vik_window_viewport(vw);
- a_acquire ( vw, vlp, vvp, &vik_datasource_file_interface );
+ a_acquire ( vw, vlp, vvp, &vik_datasource_file_interface, NULL, NULL );
}
static void trw_layer_new_wp ( gpointer lav[2] )
VikLayersPanel *vlp = VIK_LAYERS_PANEL(lav[1]);
/* TODO longone: okay, if layer above (aggregate) is invisible but vtl->visible is true, this redraws for no reason.
instead return true if you want to update. */
- if ( vik_trw_layer_new_waypoint ( vtl, VIK_GTK_WINDOW_FROM_LAYER(vtl), vik_viewport_get_center(vik_layers_panel_get_viewport(vlp))) && VIK_LAYER(vtl)->visible )
+ if ( vik_trw_layer_new_waypoint ( vtl, VIK_GTK_WINDOW_FROM_LAYER(vtl), vik_viewport_get_center(vik_layers_panel_get_viewport(vlp))) && VIK_LAYER(vtl)->visible ) {
+ trw_layer_calculate_bounds_waypoints ( vtl );
vik_layers_panel_emit_update ( vlp );
+ }
}
static void new_track_create_common ( VikTrwLayer *vtl, gchar *name )
{
vtl->current_track = vik_track_new();
+ vik_track_set_defaults ( vtl->current_track );
vtl->current_track->visible = TRUE;
if ( vtl->drawmode == DRAWMODE_ALL_SAME_COLOR )
// Create track with the preferred colour from the layer properties
if ( ! vtl->current_track ) {
gchar *name = trw_layer_new_unique_sublayer_name ( vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, _("Track")) ;
new_track_create_common ( vtl, name );
+ g_free ( name );
vik_window_enable_layer_tool ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), VIK_LAYER_TRW, TOOL_CREATE_TRACK );
}
static void new_route_create_common ( VikTrwLayer *vtl, gchar *name )
{
vtl->current_track = vik_track_new();
+ vik_track_set_defaults ( vtl->current_track );
vtl->current_track->visible = TRUE;
vtl->current_track->is_route = TRUE;
// By default make all routes red
if ( ! vtl->current_track ) {
gchar *name = trw_layer_new_unique_sublayer_name ( vtl, VIK_TRW_LAYER_SUBLAYER_ROUTE, _("Route")) ;
new_route_create_common ( vtl, name );
+ g_free ( name );
vik_window_enable_layer_tool ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), VIK_LAYER_TRW, TOOL_CREATE_ROUTE );
}
}
else if ( g_hash_table_size (vtl->waypoints) > 1 )
{
struct LatLon maxmin[2] = { {0,0}, {0,0} };
- g_hash_table_foreach ( vtl->waypoints, (GHFunc) trw_layer_find_maxmin_waypoints, maxmin );
+ maxmin[0].lat = vtl->waypoints_bbox.north;
+ maxmin[1].lat = vtl->waypoints_bbox.south;
+ maxmin[0].lon = vtl->waypoints_bbox.east;
+ maxmin[1].lon = vtl->waypoints_bbox.west;
trw_layer_zoom_to_show_latlons ( vtl, vik_layers_panel_get_viewport (vlp), maxmin );
}
gtk_menu_shell_append (GTK_MENU_SHELL (acquire_submenu), item);
gtk_widget_show ( item );
-#ifdef VIK_CONFIG_GOOGLE
- 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 );
+ /* FIXME: only add menu when at least a routing engine has support for Directions */
+ item = gtk_menu_item_new_with_mnemonic ( _("From _Directions...") );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_acquire_routing_cb), pass_along );
gtk_menu_shell_append (GTK_MENU_SHELL (acquire_submenu), item);
gtk_widget_show ( item );
-#endif
#ifdef VIK_CONFIG_OPENSTREETMAP
item = gtk_menu_item_new_with_mnemonic ( _("From _OSM Traces...") );
gtk_menu_shell_append (GTK_MENU_SHELL (acquire_submenu), item);
gtk_widget_show ( item );
+ vik_ext_tool_datasources_add_menu_items_to_menu ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), GTK_MENU (acquire_submenu) );
+
GtkWidget *upload_submenu = gtk_menu_new ();
item = gtk_image_menu_item_new_with_mnemonic ( _("_Upload") );
gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_GO_UP, GTK_ICON_SIZE_MENU) );
GtkTreeIter *iter = g_malloc(sizeof(GtkTreeIter));
// Visibility column always needed for waypoints
-#ifdef VIK_CONFIG_ALPHABETIZED_TRW
- vik_treeview_add_sublayer_alphabetized ( VIK_LAYER(vtl)->vt, &(vtl->waypoints_iter), iter, name, vtl, GUINT_TO_POINTER(wp_uuid), VIK_TRW_LAYER_SUBLAYER_WAYPOINT, get_wp_sym_small (wp->symbol), TRUE, TRUE );
-#else
vik_treeview_add_sublayer ( VIK_LAYER(vtl)->vt, &(vtl->waypoints_iter), iter, name, vtl, GUINT_TO_POINTER(wp_uuid), VIK_TRW_LAYER_SUBLAYER_WAYPOINT, get_wp_sym_small (wp->symbol), TRUE, TRUE );
-#endif
+
// Actual setting of visibility dependent on the waypoint
vik_treeview_item_set_visible ( VIK_LAYER(vtl)->vt, iter, wp->visible );
g_hash_table_insert ( vtl->waypoints_iters, GUINT_TO_POINTER(wp_uuid), iter );
+
+ // Sort now as post_read is not called on a realized waypoint
+ vik_treeview_sort_children ( VIK_LAYER(vtl)->vt, &(vtl->waypoints_iter), vtl->wp_sort_order );
}
highest_wp_number_add_wp(vtl, name);
GtkTreeIter *iter = g_malloc(sizeof(GtkTreeIter));
// Visibility column always needed for tracks
-#ifdef VIK_CONFIG_ALPHABETIZED_TRW
- vik_treeview_add_sublayer_alphabetized ( VIK_LAYER(vtl)->vt, &(vtl->tracks_iter), iter, name, vtl, GUINT_TO_POINTER(tr_uuid), VIK_TRW_LAYER_SUBLAYER_TRACK, NULL, TRUE, TRUE );
-#else
vik_treeview_add_sublayer ( VIK_LAYER(vtl)->vt, &(vtl->tracks_iter), iter, name, vtl, GUINT_TO_POINTER(tr_uuid), VIK_TRW_LAYER_SUBLAYER_TRACK, NULL, TRUE, TRUE );
-#endif
+
// Actual setting of visibility dependent on the track
vik_treeview_item_set_visible ( VIK_LAYER(vtl)->vt, iter, t->visible );
g_hash_table_insert ( vtl->tracks_iters, GUINT_TO_POINTER(tr_uuid), iter );
+
+ // Sort now as post_read is not called on a realized track
+ vik_treeview_sort_children ( VIK_LAYER(vtl)->vt, &(vtl->tracks_iter), vtl->track_sort_order );
}
g_hash_table_insert ( vtl->tracks, GUINT_TO_POINTER(tr_uuid), t );
}
GtkTreeIter *iter = g_malloc(sizeof(GtkTreeIter));
- // Visibility column always needed for tracks
-#ifdef VIK_CONFIG_ALPHABETIZED_TRW
- vik_treeview_add_sublayer_alphabetized ( VIK_LAYER(vtl)->vt, &(vtl->routes_iter), iter, name, vtl, GUINT_TO_POINTER(rt_uuid), VIK_TRW_LAYER_SUBLAYER_ROUTE, NULL, TRUE, TRUE );
-#else
+ // Visibility column always needed for routes
vik_treeview_add_sublayer ( VIK_LAYER(vtl)->vt, &(vtl->routes_iter), iter, name, vtl, GUINT_TO_POINTER(rt_uuid), VIK_TRW_LAYER_SUBLAYER_ROUTE, NULL, TRUE, TRUE );
-#endif
- // Actual setting of visibility dependent on the track
+ // Actual setting of visibility dependent on the route
vik_treeview_item_set_visible ( VIK_LAYER(vtl)->vt, iter, t->visible );
g_hash_table_insert ( vtl->routes_iters, GUINT_TO_POINTER(rt_uuid), iter );
+
+ // Sort now as post_read is not called on a realized route
+ vik_treeview_sort_children ( VIK_LAYER(vtl)->vt, &(vtl->routes_iter), vtl->track_sort_order );
}
g_hash_table_insert ( vtl->routes, GUINT_TO_POINTER(rt_uuid), t );
trw_layer_cancel_current_tp ( vtl, FALSE );
}
+/**
+ * Normally this is done to due the waypoint size preference having changed
+ */
+void vik_trw_layer_reset_waypoints ( VikTrwLayer *vtl )
+{
+ GHashTableIter iter;
+ gpointer key, value;
+
+ // Foreach waypoint
+ g_hash_table_iter_init ( &iter, vtl->waypoints );
+ while ( g_hash_table_iter_next ( &iter, &key, &value ) ) {
+ VikWaypoint *wp = VIK_WAYPOINT(value);
+ if ( wp->symbol ) {
+ // Reapply symbol setting to update the pixbuf
+ gchar *tmp_symbol = g_strdup ( wp->symbol );
+ vik_waypoint_set_symbol ( wp, tmp_symbol );
+ g_free ( tmp_symbol );
+ }
+ }
+}
+
+/**
+ * trw_layer_new_unique_sublayer_name:
+ *
+ * Allocates a unique new name
+ */
gchar *trw_layer_new_unique_sublayer_name (VikTrwLayer *vtl, gint sublayer_type, const gchar *name)
{
gint i = 2;
*/
static void trw_layer_move_item ( VikTrwLayer *vtl_src, VikTrwLayer *vtl_dest, gpointer id, gint type )
{
+ // TODO reconsider strategy when moving within layer (if anything...)
+ gboolean rename = ( vtl_src != vtl_dest );
+ if ( ! rename )
+ return;
+
if (type == VIK_TRW_LAYER_SUBLAYER_TRACK) {
VikTrack *trk = g_hash_table_lookup ( vtl_src->tracks, id );
- gchar *newname = trw_layer_new_unique_sublayer_name(vtl_dest, type, trk->name);
+ gchar *newname;
+ if ( rename )
+ newname = trw_layer_new_unique_sublayer_name ( vtl_dest, type, trk->name );
+ else
+ newname = g_strdup ( trk->name );
VikTrack *trk2 = vik_track_copy ( trk, TRUE );
vik_trw_layer_add_track ( vtl_dest, newname, trk2 );
+ g_free ( newname );
vik_trw_layer_delete_track ( vtl_src, trk );
}
if (type == VIK_TRW_LAYER_SUBLAYER_ROUTE) {
VikTrack *trk = g_hash_table_lookup ( vtl_src->routes, id );
- gchar *newname = trw_layer_new_unique_sublayer_name(vtl_dest, type, trk->name);
+ gchar *newname;
+ if ( rename )
+ newname = trw_layer_new_unique_sublayer_name ( vtl_dest, type, trk->name );
+ else
+ newname = g_strdup ( trk->name );
VikTrack *trk2 = vik_track_copy ( trk, TRUE );
vik_trw_layer_add_route ( vtl_dest, newname, trk2 );
+ g_free ( newname );
vik_trw_layer_delete_route ( vtl_src, trk );
}
if (type == VIK_TRW_LAYER_SUBLAYER_WAYPOINT) {
VikWaypoint *wp = g_hash_table_lookup ( vtl_src->waypoints, id );
- gchar *newname = trw_layer_new_unique_sublayer_name(vtl_dest, type, wp->name);
+ gchar *newname;
+ if ( rename )
+ newname = trw_layer_new_unique_sublayer_name ( vtl_dest, type, wp->name );
+ else
+ newname = g_strdup ( wp->name );
VikWaypoint *wp2 = vik_waypoint_copy ( wp );
vik_trw_layer_add_waypoint ( vtl_dest, newname, wp2 );
+ g_free ( newname );
trw_layer_delete_waypoint ( vtl_src, wp );
+
+ // Recalculate bounds even if not renamed as maybe dragged between layers
+ trw_layer_calculate_bounds_waypoints ( vtl_dest );
+ trw_layer_calculate_bounds_waypoints ( vtl_src );
}
}
while (iter) {
if (type==VIK_TRW_LAYER_SUBLAYER_TRACKS) {
trw_layer_move_item ( vtl_src, vtl_dest, iter->data, VIK_TRW_LAYER_SUBLAYER_TRACK);
- }
- else if (type==VIK_TRW_LAYER_SUBLAYER_ROUTES) {
+ } else if (type==VIK_TRW_LAYER_SUBLAYER_ROUTES) {
trw_layer_move_item ( vtl_src, vtl_dest, iter->data, VIK_TRW_LAYER_SUBLAYER_ROUTE);
} else {
trw_layer_move_item ( vtl_src, vtl_dest, iter->data, VIK_TRW_LAYER_SUBLAYER_WAYPOINT);
// Get confirmation from the user
// Maybe this Waypoint Delete should be optional as is it could get annoying...
if ( ! a_dialog_yes_or_no ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
- _("Are you sure you want to delete the waypoint \"%s\""),
+ _("Are you sure you want to delete the waypoint \"%s\"?"),
wp->name ) )
return;
was_visible = trw_layer_delete_waypoint ( vtl, wp );
if ( GPOINTER_TO_INT ( pass_along[4]) )
// Get confirmation from the user
if ( ! a_dialog_yes_or_no ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
- _("Are you sure you want to delete the track \"%s\""),
+ _("Are you sure you want to delete the track \"%s\"?"),
trk->name ) )
return;
was_visible = vik_trw_layer_delete_track ( vtl, trk );
if ( GPOINTER_TO_INT ( pass_along[4]) )
// Get confirmation from the user
if ( ! a_dialog_yes_or_no ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
- _("Are you sure you want to delete the route \"%s\""),
+ _("Are you sure you want to delete the route \"%s\"?"),
trk->name ) )
return;
was_visible = vik_trw_layer_delete_route ( vtl, trk );
vik_layer_emit_update ( VIK_LAYER(vtl) );
}
-
-static void trw_layer_properties_item ( gpointer pass_along[7] )
+/**
+ * Rename waypoint and maintain corresponding name of waypoint in the treeview
+ */
+static void trw_layer_waypoint_rename ( VikTrwLayer *vtl, VikWaypoint *wp, const gchar *new_name )
+{
+ vik_waypoint_set_name ( wp, new_name );
+
+ // Now update the treeview as well
+ wpu_udata udataU;
+ udataU.wp = wp;
+ udataU.uuid = NULL;
+
+ // Need key of it for treeview update
+ gpointer *wpf = g_hash_table_find ( vtl->waypoints, (GHRFunc) trw_layer_waypoint_find_uuid, &udataU );
+
+ if ( wpf && udataU.uuid ) {
+ GtkTreeIter *it = g_hash_table_lookup ( vtl->waypoints_iters, udataU.uuid );
+
+ if ( it ) {
+ vik_treeview_item_set_name ( VIK_LAYER(vtl)->vt, it, new_name );
+ vik_treeview_sort_children ( VIK_LAYER(vtl)->vt, &(vtl->waypoints_iter), vtl->wp_sort_order );
+ }
+ }
+}
+
+static void trw_layer_properties_item ( gpointer pass_along[7] )
{
VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_WAYPOINT )
if ( wp && wp->name )
{
gboolean updated = FALSE;
- a_dialog_waypoint ( VIK_GTK_WINDOW_FROM_LAYER(vtl), wp->name, wp, vtl->coord_mode, FALSE, &updated );
+ gchar *new_name = a_dialog_waypoint ( VIK_GTK_WINDOW_FROM_LAYER(vtl), wp->name, vtl, wp, vtl->coord_mode, FALSE, &updated );
+ if ( new_name )
+ trw_layer_waypoint_rename ( vtl, wp, new_name );
- if ( updated && wp->symbol && pass_along[6] )
+ if ( updated && 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 )
tr,
pass_along[1], /* vlp */
pass_along[5], /* vvp */
- pass_along[6]); /* iter */
+ pass_along[6], /* iter */
+ FALSE );
}
}
}
+/**
+ * trw_layer_track_statistics:
+ *
+ * Show track statistics.
+ * ATM jump to the stats page in the properties
+ * TODO: consider separating the stats into an individual dialog?
+ */
+static void trw_layer_track_statistics ( gpointer pass_along[7] )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
+ VikTrack *trk;
+ if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_TRACK )
+ trk = g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+ else
+ trk = g_hash_table_lookup ( vtl->routes, pass_along[3] );
+
+ if ( trk && trk->name ) {
+ vik_trw_layer_propwin_run ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
+ vtl,
+ trk,
+ pass_along[1], // vlp
+ pass_along[5], // vvp
+ pass_along[6], // iter
+ TRUE );
+ }
+}
+
/*
* Update the treeview of the track id - primarily to update the icon
*/
vik_layer_emit_update ( VIK_LAYER(pass_along[0]) );
}
+static void trw_layer_anonymize_times ( gpointer pass_along[6] )
+{
+ VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
+ VikTrack *track;
+ if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ track = (VikTrack *) g_hash_table_lookup ( vtl->routes, pass_along[3] );
+ else
+ track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+
+ if ( track )
+ vik_track_anonymize_times ( track );
+}
static void trw_layer_extend_track_end ( gpointer pass_along[6] )
{
goto_coord ( pass_along[1], pass_along[0], pass_along[5], &(((VikTrackpoint *)g_list_last(track->trackpoints)->data)->coord) );
}
-#ifdef VIK_CONFIG_GOOGLE
/**
* extend a track using route finder
*/
goto_coord ( pass_along[1], pass_along[0], pass_along[5], &last_coord) ;
}
-#endif
-static void trw_layer_apply_dem_data ( gpointer pass_along[6] )
+/**
+ *
+ */
+static gboolean trw_layer_dem_test ( VikTrwLayer *vtl, VikLayersPanel *vlp )
+{
+ // If have a vlp then perform a basic test to see if any DEM info available...
+ if ( vlp ) {
+ GList *dems = vik_layers_panel_get_all_layers_of_type (vlp, VIK_LAYER_DEM, TRUE); // Includes hidden DEM layer types
+
+ if ( !g_list_length(dems) ) {
+ a_dialog_error_msg (VIK_GTK_WINDOW_FROM_LAYER(vtl), _("No DEM layers available, thus no DEM values can be applied.") );
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/**
+ * apply_dem_data_common:
+ *
+ * A common function for applying the DEM values and reporting the results.
+ */
+static void apply_dem_data_common ( VikTrwLayer *vtl, VikLayersPanel *vlp, VikTrack *track, gboolean skip_existing_elevations )
+{
+ if ( !trw_layer_dem_test ( vtl, vlp ) )
+ return;
+
+ gulong changed = vik_track_apply_dem_data ( track, skip_existing_elevations );
+ // Inform user how much was changed
+ gchar str[64];
+ const gchar *tmp_str = ngettext("%ld point adjusted", "%ld points adjusted", changed);
+ g_snprintf(str, 64, tmp_str, changed);
+ a_dialog_info_msg (VIK_GTK_WINDOW_FROM_LAYER(vtl), str);
+}
+
+static void trw_layer_apply_dem_data_all ( gpointer pass_along[6] )
+{
+ VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
+ VikTrack *track;
+ if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ track = (VikTrack *) g_hash_table_lookup ( vtl->routes, pass_along[3] );
+ else
+ track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+
+ if ( track )
+ apply_dem_data_common ( vtl, pass_along[1], track, FALSE );
+}
+
+static void trw_layer_apply_dem_data_only_missing ( gpointer pass_along[6] )
{
- /* TODO: check & warn if no DEM data, or no applicable DEM data. */
- /* Also warn if overwrite old elevation data */
VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
VikTrack *track;
if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, pass_along[3] );
if ( track )
- vik_track_apply_dem_data ( track );
+ apply_dem_data_common ( vtl, pass_along[1], track, TRUE );
+}
+
+/**
+ * smooth_it:
+ *
+ * A common function for applying the elevation smoothing and reporting the results.
+ */
+static void smooth_it ( VikTrwLayer *vtl, VikTrack *track, gboolean flat )
+{
+ gulong changed = vik_track_smooth_missing_elevation_data ( track, flat );
+ // Inform user how much was changed
+ gchar str[64];
+ const gchar *tmp_str = ngettext("%ld point adjusted", "%ld points adjusted", changed);
+ g_snprintf(str, 64, tmp_str, changed);
+ a_dialog_info_msg (VIK_GTK_WINDOW_FROM_LAYER(vtl), str);
+}
+
+/**
+ *
+ */
+static void trw_layer_missing_elevation_data_interp ( gpointer pass_along[6] )
+{
+ VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
+ VikTrack *track;
+ if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ track = (VikTrack *) g_hash_table_lookup ( vtl->routes, pass_along[3] );
+ else
+ track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+
+ if ( !track )
+ return;
+
+ smooth_it ( vtl, track, FALSE );
+}
+
+static void trw_layer_missing_elevation_data_flat ( gpointer pass_along[6] )
+{
+ VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
+ VikTrack *track;
+ if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ track = (VikTrack *) g_hash_table_lookup ( vtl->routes, pass_along[3] );
+ else
+ track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+
+ if ( !track )
+ return;
+
+ smooth_it ( vtl, track, TRUE );
+}
+
+/**
+ * Commonal helper function
+ */
+static void wp_changed_message ( VikTrwLayer *vtl, gint changed )
+{
+ gchar str[64];
+ const gchar *tmp_str = ngettext("%ld waypoint changed", "%ld waypoints changed", changed);
+ g_snprintf(str, 64, tmp_str, changed);
+ a_dialog_info_msg (VIK_GTK_WINDOW_FROM_LAYER(vtl), str);
+}
+
+static void trw_layer_apply_dem_data_wpt_all ( gpointer pass_along[6] )
+{
+ VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
+ VikLayersPanel *vlp = (VikLayersPanel *)pass_along[1];
+
+ if ( !trw_layer_dem_test ( vtl, vlp ) )
+ return;
+
+ gint changed = 0;
+ if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_WAYPOINT ) {
+ // Single Waypoint
+ VikWaypoint *wp = (VikWaypoint *) g_hash_table_lookup ( vtl->waypoints, pass_along[3] );
+ if ( wp )
+ changed = (gint)vik_waypoint_apply_dem_data ( wp, FALSE );
+ }
+ else {
+ // All waypoints
+ GHashTableIter iter;
+ gpointer key, value;
+
+ g_hash_table_iter_init ( &iter, vtl->waypoints );
+ while ( g_hash_table_iter_next (&iter, &key, &value) ) {
+ VikWaypoint *wp = VIK_WAYPOINT(value);
+ changed = changed + (gint)vik_waypoint_apply_dem_data ( wp, FALSE );
+ }
+ }
+ wp_changed_message ( vtl, changed );
+}
+
+static void trw_layer_apply_dem_data_wpt_only_missing ( gpointer pass_along[6] )
+{
+ VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
+ VikLayersPanel *vlp = (VikLayersPanel *)pass_along[1];
+
+ if ( !trw_layer_dem_test ( vtl, vlp ) )
+ return;
+
+ gint changed = 0;
+ if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_WAYPOINT ) {
+ // Single Waypoint
+ VikWaypoint *wp = (VikWaypoint *) g_hash_table_lookup ( vtl->waypoints, pass_along[3] );
+ if ( wp )
+ changed = (gint)vik_waypoint_apply_dem_data ( wp, TRUE );
+ }
+ else {
+ // All waypoints
+ GHashTableIter iter;
+ gpointer key, value;
+
+ g_hash_table_iter_init ( &iter, vtl->waypoints );
+ while ( g_hash_table_iter_next (&iter, &key, &value) ) {
+ VikWaypoint *wp = VIK_WAYPOINT(value);
+ changed = changed + (gint)vik_waypoint_apply_dem_data ( wp, TRUE );
+ }
+ }
+ wp_changed_message ( vtl, changed );
}
static void trw_layer_goto_track_endpoint ( gpointer pass_along[6] )
*/
static void trw_layer_auto_track_view ( gpointer pass_along[6] )
{
- VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
+ VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
VikTrack *trk;
if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
trk = (VikTrack *) g_hash_table_lookup ( vtl->routes, pass_along[3] );
{
struct LatLon maxmin[2] = { {0,0}, {0,0} };
trw_layer_find_maxmin_tracks ( NULL, trk, maxmin );
- trw_layer_zoom_to_show_latlons ( VIK_TRW_LAYER(pass_along[0]), pass_along[5], maxmin );
+ trw_layer_zoom_to_show_latlons ( vtl, pass_along[5], maxmin );
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]) );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+ }
+}
+
+/*
+ * Refine the selected track/route with a routing engine.
+ * The routing engine is selected by the user, when requestiong the job.
+ */
+static void trw_layer_route_refine ( gpointer pass_along[6] )
+{
+ static gint last_engine = 0;
+ VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
+ VikTrack *trk;
+
+ if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ trk = (VikTrack *) g_hash_table_lookup ( vtl->routes, pass_along[3] );
+ else
+ trk = (VikTrack *) g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+
+ if ( trk && trk->trackpoints )
+ {
+ /* Check size of the route */
+ int nb = vik_track_get_tp_count(trk);
+ if (nb > 100) {
+ GtkWidget *dialog = gtk_message_dialog_new (VIK_GTK_WINDOW_FROM_LAYER (vtl),
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_OK_CANCEL,
+ _("Refining a track with many points (%d) is unlikely to yield sensible results. Do you want to Continue?"),
+ nb);
+ gint response = gtk_dialog_run ( GTK_DIALOG(dialog) );
+ gtk_widget_destroy ( dialog );
+ if (response != GTK_RESPONSE_OK )
+ return;
+ }
+ /* Select engine from dialog */
+ GtkWidget *dialog = gtk_dialog_new_with_buttons (_("Refine Route with Routing Engine..."),
+ VIK_GTK_WINDOW_FROM_LAYER (vtl),
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_REJECT,
+ GTK_STOCK_OK,
+ GTK_RESPONSE_ACCEPT,
+ NULL);
+ GtkWidget *label = gtk_label_new ( _("Select routing engine") );
+ gtk_widget_show_all(label);
+
+ gtk_box_pack_start ( GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), label, TRUE, TRUE, 0 );
+
+ GtkWidget * combo = vik_routing_ui_selector_new ( (Predicate)vik_routing_engine_supports_refine, NULL );
+ gtk_combo_box_set_active (GTK_COMBO_BOX (combo), last_engine);
+ gtk_widget_show_all(combo);
+
+ gtk_box_pack_start ( GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), combo, TRUE, TRUE, 0 );
+
+ gtk_dialog_set_default_response ( GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT );
+
+ if ( gtk_dialog_run ( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT )
+ {
+ /* Dialog validated: retrieve selected engine and do the job */
+ last_engine = gtk_combo_box_get_active ( GTK_COMBO_BOX(combo) );
+ VikRoutingEngine *routing = vik_routing_ui_selector_get_nth (combo, last_engine);
+
+ /* Change cursor */
+ vik_window_set_busy_cursor ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(pass_along[0])) );
+
+ /* Force saving track */
+ /* FIXME: remove or rename this hack */
+ vtl->route_finder_check_added_track = TRUE;
+
+ /* the job */
+ vik_routing_engine_refine (routing, vtl, trk);
+
+ /* FIXME: remove or rename this hack */
+ if ( vtl->route_finder_added_track )
+ vik_track_calculate_bounds ( vtl->route_finder_added_track );
+
+ vtl->route_finder_added_track = NULL;
+ vtl->route_finder_check_added_track = FALSE;
+
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+
+ /* Restore cursor */
+ vik_window_clear_busy_cursor ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(pass_along[0])) );
+ }
+ gtk_widget_destroy ( dialog );
}
}
merge_track = vik_trw_layer_get_track ( vtl, l->data );
if (merge_track) {
- track->trackpoints = g_list_concat(track->trackpoints, merge_track->trackpoints);
- merge_track->trackpoints = NULL;
+ vik_track_steal_and_append_trackpoints ( track, merge_track );
if ( track->is_route )
vik_trw_layer_delete_route (vtl, merge_track);
else
track->trackpoints = g_list_sort(track->trackpoints, trackpoint_compare);
}
}
- /* TODO: free data before free merge_list */
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) );
}
}
append_track = vik_trw_layer_get_track ( vtl, l->data );
if ( append_track ) {
- trk->trackpoints = g_list_concat(trk->trackpoints, append_track->trackpoints);
- append_track->trackpoints = NULL;
+ vik_track_steal_and_append_trackpoints ( trk, append_track );
if ( trk->is_route )
vik_trw_layer_delete_route (vtl, append_track);
else
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) );
}
}
}
}
- trk->trackpoints = g_list_concat(trk->trackpoints, append_track->trackpoints);
- append_track->trackpoints = NULL;
+ vik_track_steal_and_append_trackpoints ( trk, append_track );
// Delete copied which is FROM THE OTHER TYPE list
if ( trk->is_route )
*/
/* remove trackpoints from merged track, delete track */
- orig_trk->trackpoints = g_list_concat(orig_trk->trackpoints, VIK_TRACK(l->data)->trackpoints);
- VIK_TRACK(l->data)->trackpoints = NULL;
+ vik_track_steal_and_append_trackpoints ( orig_trk, VIK_TRACK(l->data) );
vik_trw_layer_delete_track (vtl, VIK_TRACK(l->data));
// Tracks have changed, therefore retry again against all the remaining tracks
}
g_list_free(nearby_tracks);
+
vik_layer_emit_update( VIK_LAYER(vtl) );
}
vtl->current_tpl->next->prev = newglist; /* end old track here */
vtl->current_tpl->next = NULL;
+ // Bounds of the selected track changed due to the split
+ vik_track_calculate_bounds ( vtl->current_tp_track );
+
vtl->current_tpl = newglist; /* change tp to first of new track. */
vtl->current_tp_track = tr;
else
vik_trw_layer_add_track ( vtl, name, tr );
+ // Bounds of the new track created by the split
+ vik_track_calculate_bounds ( tr );
+
trku_udata udata;
udata.trk = tr;
udata.uuid = NULL;
vik_layer_emit_update(VIK_LAYER(vtl));
}
+ g_free ( name );
}
}
while (iter) {
ts = VIK_TRACKPOINT(iter->data)->timestamp;
+
+ // Check for unordered time points - this is quite a rare occurence - unless one has reversed a track.
if (ts < prev_ts) {
- g_print("panic: ts < prev_ts: this should never happen!\n");
+ gchar tmp_str[64];
+ strftime ( tmp_str, sizeof(tmp_str), "%c", localtime(&ts) );
+ if ( a_dialog_yes_or_no ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
+ _("Can not split track due to trackpoints not ordered in time - such as at %s.\n\nGoto this trackpoint?"),
+ tmp_str ) ) {
+ goto_coord ( pass_along[1], vtl, pass_along[5], &(VIK_TRACKPOINT(iter->data)->coord) );
+ }
return;
}
+
if (ts - prev_ts > thr*60) {
/* flush accumulated trackpoints into new list */
newlists = g_list_append(newlists, g_list_reverse(newtps));
vik_trw_layer_add_track(vtl, new_tr_name, tr);
/* 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);*/
-
+ g_free ( new_tr_name );
+ vik_track_calculate_bounds ( tr );
iter = g_list_next(iter);
}
// Remove original track and then update the display
new_tr_name = trw_layer_new_unique_sublayer_name ( vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, track->name);
vik_trw_layer_add_track(vtl, new_tr_name, tr);
}
+ g_free ( new_tr_name );
+ vik_track_calculate_bounds ( tr );
+
iter = g_list_next(iter);
}
// Remove original track and then update the display
if ( tracks[i] ) {
new_tr_name = trw_layer_new_unique_sublayer_name ( vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, trk->name);
vik_trw_layer_add_track ( vtl, new_tr_name, tracks[i] );
+ g_free ( new_tr_name );
}
}
if ( tracks ) {
if ( ! track )
return;
- // Check valid track
- GList *trps = track->trackpoints;
- if ( !trps )
- return;
-
vik_track_reverse ( track );
vik_layer_emit_update ( VIK_LAYER(pass_along[0]) );
if ( it ) {
vik_treeview_item_set_name ( VIK_LAYER(vtl)->vt, it, newname );
-#ifdef VIK_CONFIG_ALPHABETIZED_TRW
- vik_treeview_sublayer_realphabetize ( VIK_LAYER(vtl)->vt, it, newname );
-#endif
+ if ( ontrack )
+ vik_treeview_sort_children ( VIK_LAYER(vtl)->vt, &(vtl->tracks_iter), vtl->wp_sort_order );
+ else
+ vik_treeview_sort_children ( VIK_LAYER(vtl)->vt, &(vtl->routes_iter), vtl->wp_sort_order );
}
}
vik_layers_panel_emit_update ( vlp );
}
+static void trw_layer_sort_order_a2z ( gpointer pass_along[6] )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
+ GtkTreeIter *iter;
+
+ switch (GPOINTER_TO_INT (pass_along[2])) {
+ case VIK_TRW_LAYER_SUBLAYER_TRACKS:
+ iter = &(vtl->tracks_iter);
+ vtl->track_sort_order = VL_SO_ALPHABETICAL_ASCENDING;
+ break;
+ case VIK_TRW_LAYER_SUBLAYER_ROUTES:
+ iter = &(vtl->routes_iter);
+ vtl->track_sort_order = VL_SO_ALPHABETICAL_ASCENDING;
+ break;
+ default: // VIK_TRW_LAYER_SUBLAYER_WAYPOINTS:
+ iter = &(vtl->waypoints_iter);
+ vtl->wp_sort_order = VL_SO_ALPHABETICAL_ASCENDING;
+ break;
+ }
+
+ vik_treeview_sort_children ( VIK_LAYER(vtl)->vt, iter, VL_SO_ALPHABETICAL_ASCENDING );
+}
+
+static void trw_layer_sort_order_z2a ( gpointer pass_along[6] )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
+ GtkTreeIter *iter;
+
+ switch (GPOINTER_TO_INT (pass_along[2])) {
+ case VIK_TRW_LAYER_SUBLAYER_TRACKS:
+ iter = &(vtl->tracks_iter);
+ vtl->track_sort_order = VL_SO_ALPHABETICAL_DESCENDING;
+ break;
+ case VIK_TRW_LAYER_SUBLAYER_ROUTES:
+ iter = &(vtl->routes_iter);
+ vtl->track_sort_order = VL_SO_ALPHABETICAL_DESCENDING;
+ break;
+ default: // VIK_TRW_LAYER_SUBLAYER_WAYPOINTS:
+ iter = &(vtl->waypoints_iter);
+ vtl->wp_sort_order = VL_SO_ALPHABETICAL_DESCENDING;
+ break;
+ }
+
+ vik_treeview_sort_children ( VIK_LAYER(vtl)->vt, iter, VL_SO_ALPHABETICAL_DESCENDING );
+}
+
/**
*
*/
// Rename it
gchar *newname = trw_layer_new_unique_sublayer_name ( vtl, VIK_TRW_LAYER_SUBLAYER_WAYPOINT, udata.same_waypoint_name );
- vik_waypoint_set_name ( waypoint, newname );
- wpu_udata udataU;
- udataU.wp = waypoint;
- udataU.uuid = NULL;
-
- // Need want key of it for treeview update
- gpointer *wpf = g_hash_table_find ( vtl->waypoints, (GHRFunc) trw_layer_waypoint_find_uuid, &udataU );
-
- if ( wpf && udataU.uuid ) {
-
- GtkTreeIter *it = g_hash_table_lookup ( vtl->waypoints_iters, udataU.uuid );
-
- if ( it ) {
- vik_treeview_item_set_name ( VIK_LAYER(vtl)->vt, it, newname );
-#ifdef VIK_CONFIG_ALPHABETIZED_TRW
- vik_treeview_sublayer_realphabetize ( VIK_LAYER(vtl)->vt, it, newname );
-#endif
- }
- }
+ trw_layer_waypoint_rename ( vtl, waypoint, newname );
// Start trying to find same names again...
waypoint_names = NULL;
return;
}
- // Sort list alphabetically for better presentation
- g_hash_table_foreach ( vtl->waypoints, (GHFunc) trw_layer_sorted_wp_id_by_name_list, &all);
- if ( ! all ) {
- a_dialog_error_msg (VIK_GTK_WINDOW_FROM_LAYER(vtl), _("No waypoints found"));
- return;
+ // Sort list alphabetically for better presentation
+ g_hash_table_foreach ( vtl->waypoints, (GHFunc) trw_layer_sorted_wp_id_by_name_list, &all);
+ if ( ! all ) {
+ a_dialog_error_msg (VIK_GTK_WINDOW_FROM_LAYER(vtl), _("No waypoints found"));
+ return;
+ }
+
+ all = g_list_sort_with_data(all, sort_alphabetically, NULL);
+
+ // Get list of items to delete from the user
+ GList *delete_list = a_dialog_select_from_list(VIK_GTK_WINDOW_FROM_LAYER(vtl),
+ all,
+ TRUE,
+ _("Delete Selection"),
+ _("Select waypoints to delete"));
+ g_list_free(all);
+
+ // Delete requested waypoints
+ // since specificly requested, IMHO no need for extra confirmation
+ if ( delete_list ) {
+ GList *l;
+ for (l = delete_list; l != NULL; l = g_list_next(l)) {
+ // This deletes first waypoint it finds of that name (but uniqueness is enforced above)
+ trw_layer_delete_waypoint_by_name (vtl, l->data);
+ }
+ g_list_free(delete_list);
+
+ trw_layer_calculate_bounds_waypoints ( vtl );
+ vik_layer_emit_update( VIK_LAYER(vtl) );
+ }
+
+}
+
+/**
+ *
+ */
+static void trw_layer_iter_visibility_toggle ( gpointer id, GtkTreeIter *it, VikTreeview *vt )
+{
+ vik_treeview_item_toggle_visible ( vt, it );
+}
+
+/**
+ *
+ */
+static void trw_layer_iter_visibility ( gpointer id, GtkTreeIter *it, gpointer vis_data[2] )
+{
+ vik_treeview_item_set_visible ( (VikTreeview*)vis_data[0], it, GPOINTER_TO_INT (vis_data[1]) );
+}
+
+/**
+ *
+ */
+static void trw_layer_waypoints_visibility ( gpointer id, VikWaypoint *wp, gpointer on_off )
+{
+ wp->visible = GPOINTER_TO_INT (on_off);
+}
+
+/**
+ *
+ */
+static void trw_layer_waypoints_toggle_visibility ( gpointer id, VikWaypoint *wp )
+{
+ wp->visible = !wp->visible;
+}
+
+/**
+ *
+ */
+static void trw_layer_waypoints_visibility_off ( gpointer lav[2] )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ gpointer vis_data[2] = { VIK_LAYER(vtl)->vt, GINT_TO_POINTER(FALSE) };
+ g_hash_table_foreach ( vtl->waypoints_iters, (GHFunc) trw_layer_iter_visibility, vis_data );
+ g_hash_table_foreach ( vtl->waypoints, (GHFunc) trw_layer_waypoints_visibility, vis_data[1] );
+ // Redraw
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+}
+
+/**
+ *
+ */
+static void trw_layer_waypoints_visibility_on ( gpointer lav[2] )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ gpointer vis_data[2] = { VIK_LAYER(vtl)->vt, GINT_TO_POINTER(TRUE) };
+ g_hash_table_foreach ( vtl->waypoints_iters, (GHFunc) trw_layer_iter_visibility, vis_data );
+ g_hash_table_foreach ( vtl->waypoints, (GHFunc) trw_layer_waypoints_visibility, vis_data[1] );
+ // Redraw
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+}
+
+/**
+ *
+ */
+static void trw_layer_waypoints_visibility_toggle ( gpointer lav[2] )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ g_hash_table_foreach ( vtl->waypoints_iters, (GHFunc) trw_layer_iter_visibility_toggle, VIK_LAYER(vtl)->vt );
+ g_hash_table_foreach ( vtl->waypoints, (GHFunc) trw_layer_waypoints_toggle_visibility, NULL );
+ // Redraw
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+}
+
+/**
+ *
+ */
+static void trw_layer_tracks_visibility ( gpointer id, VikTrack *trk, gpointer on_off )
+{
+ trk->visible = GPOINTER_TO_INT (on_off);
+}
+
+/**
+ *
+ */
+static void trw_layer_tracks_toggle_visibility ( gpointer id, VikTrack *trk )
+{
+ trk->visible = !trk->visible;
+}
+
+/**
+ *
+ */
+static void trw_layer_tracks_visibility_off ( gpointer lav[2] )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ gpointer vis_data[2] = { VIK_LAYER(vtl)->vt, GINT_TO_POINTER(FALSE) };
+ g_hash_table_foreach ( vtl->tracks_iters, (GHFunc) trw_layer_iter_visibility, vis_data );
+ g_hash_table_foreach ( vtl->tracks, (GHFunc) trw_layer_tracks_visibility, vis_data[1] );
+ // Redraw
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+}
+
+/**
+ *
+ */
+static void trw_layer_tracks_visibility_on ( gpointer lav[2] )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ gpointer vis_data[2] = { VIK_LAYER(vtl)->vt, GINT_TO_POINTER(TRUE) };
+ g_hash_table_foreach ( vtl->tracks_iters, (GHFunc) trw_layer_iter_visibility, vis_data );
+ g_hash_table_foreach ( vtl->tracks, (GHFunc) trw_layer_tracks_visibility, vis_data[1] );
+ // Redraw
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+}
+
+/**
+ *
+ */
+static void trw_layer_tracks_visibility_toggle ( gpointer lav[2] )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ g_hash_table_foreach ( vtl->tracks_iters, (GHFunc) trw_layer_iter_visibility_toggle, VIK_LAYER(vtl)->vt );
+ g_hash_table_foreach ( vtl->tracks, (GHFunc) trw_layer_tracks_toggle_visibility, NULL );
+ // Redraw
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+}
+
+/**
+ *
+ */
+static void trw_layer_routes_visibility_off ( gpointer lav[2] )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ gpointer vis_data[2] = { VIK_LAYER(vtl)->vt, GINT_TO_POINTER(FALSE) };
+ g_hash_table_foreach ( vtl->routes_iters, (GHFunc) trw_layer_iter_visibility, vis_data );
+ g_hash_table_foreach ( vtl->routes, (GHFunc) trw_layer_tracks_visibility, vis_data[1] );
+ // Redraw
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+}
+
+/**
+ *
+ */
+static void trw_layer_routes_visibility_on ( gpointer lav[2] )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ gpointer vis_data[2] = { VIK_LAYER(vtl)->vt, GINT_TO_POINTER(TRUE) };
+ g_hash_table_foreach ( vtl->routes_iters, (GHFunc) trw_layer_iter_visibility, vis_data );
+ g_hash_table_foreach ( vtl->routes, (GHFunc) trw_layer_tracks_visibility, vis_data[1] );
+ // Redraw
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+}
+
+/**
+ *
+ */
+static void trw_layer_routes_visibility_toggle ( gpointer lav[2] )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ g_hash_table_foreach ( vtl->routes_iters, (GHFunc) trw_layer_iter_visibility_toggle, VIK_LAYER(vtl)->vt );
+ g_hash_table_foreach ( vtl->routes, (GHFunc) trw_layer_tracks_toggle_visibility, NULL );
+ // Redraw
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+}
+
+/**
+ * trw_layer_analyse_close:
+ *
+ * Stuff to do on dialog closure
+ */
+static void trw_layer_analyse_close ( GtkWidget *dialog, gint resp, VikLayer* vl )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(vl);
+ gtk_widget_destroy ( dialog );
+ vtl->tracks_analysis_dialog = NULL;
+}
+
+/**
+ * trw_layer_analyse_create_list:
+ *
+ * Create the latest list of tracks with the associated layer(s)
+ * Although this will always be from a single layer here
+ */
+static GList* trw_layer_analyse_create_list ( VikLayer *vl, gpointer user_data )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(vl);
+ GList *tracks = NULL;
+ if ( GPOINTER_TO_INT(user_data) == VIK_TRW_LAYER_SUBLAYER_TRACKS )
+ tracks = g_hash_table_get_values ( vik_trw_layer_get_tracks(vtl) );
+ else
+ tracks = g_hash_table_get_values ( vik_trw_layer_get_routes(vtl) );
+
+ GList *tracks_and_layers = NULL;
+ // build tracks_and_layers list
+ tracks = g_list_first ( tracks );
+ while ( tracks ) {
+ vik_trw_track_list_t *vtdl = g_malloc (sizeof(vik_trw_track_list_t));
+ vtdl->trk = VIK_TRACK(tracks->data);
+ vtdl->vtl = vtl;
+ tracks_and_layers = g_list_prepend ( tracks_and_layers, vtdl );
+ tracks = g_list_next ( tracks );
}
- all = g_list_sort_with_data(all, sort_alphabetically, NULL);
+ return tracks_and_layers;
+}
- // Get list of items to delete from the user
- GList *delete_list = a_dialog_select_from_list(VIK_GTK_WINDOW_FROM_LAYER(vtl),
- all,
- TRUE,
- _("Delete Selection"),
- _("Select waypoints to delete"));
- g_list_free(all);
+static void trw_layer_tracks_stats ( gpointer lav[2] )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ // There can only be one!
+ if ( vtl->tracks_analysis_dialog )
+ return;
- // Delete requested waypoints
- // since specificly requested, IMHO no need for extra confirmation
- if ( delete_list ) {
- GList *l;
- for (l = delete_list; l != NULL; l = g_list_next(l)) {
- // This deletes first waypoint it finds of that name (but uniqueness is enforced above)
- trw_layer_delete_waypoint_by_name (vtl, l->data);
- }
- g_list_free(delete_list);
- vik_layer_emit_update( VIK_LAYER(vtl) );
- }
+ vtl->tracks_analysis_dialog = vik_trw_layer_analyse_this ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
+ VIK_LAYER(vtl)->name,
+ VIK_LAYER(vtl),
+ GINT_TO_POINTER(VIK_TRW_LAYER_SUBLAYER_TRACKS),
+ trw_layer_analyse_create_list,
+ trw_layer_analyse_close );
+}
+
+/**
+ *
+ */
+static void trw_layer_routes_stats ( gpointer lav[2] )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ // There can only be one!
+ if ( vtl->tracks_analysis_dialog )
+ return;
+ vtl->tracks_analysis_dialog = vik_trw_layer_analyse_this ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
+ VIK_LAYER(vtl)->name,
+ VIK_LAYER(vtl),
+ GINT_TO_POINTER(VIK_TRW_LAYER_SUBLAYER_ROUTES),
+ trw_layer_analyse_create_list,
+ trw_layer_analyse_close );
}
static void trw_layer_goto_waypoint ( gpointer pass_along[6] )
VikWaypoint *wp = g_hash_table_lookup ( l->waypoints, sublayer );
// No actual change to the name supplied
- if (strcmp(newname, wp->name) == 0 )
- return NULL;
+ if ( wp->name )
+ if (strcmp(newname, wp->name) == 0 )
+ return NULL;
VikWaypoint *wpf = vik_trw_layer_get_waypoint ( l, newname );
// Update WP name and refresh the treeview
vik_waypoint_set_name (wp, newname);
-#ifdef VIK_CONFIG_ALPHABETIZED_TRW
- vik_treeview_sublayer_realphabetize ( VIK_LAYER(l)->vt, iter, newname );
-#endif
+ vik_treeview_item_set_name ( VIK_LAYER(l)->vt, iter, newname );
+ vik_treeview_sort_children ( VIK_LAYER(l)->vt, &(l->waypoints_iter), l->wp_sort_order );
vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(vlp) );
VikTrack *trk = g_hash_table_lookup ( l->tracks, sublayer );
// No actual change to the name supplied
- if (strcmp(newname, trk->name) == 0)
- return NULL;
+ if ( trk->name )
+ if (strcmp(newname, trk->name) == 0)
+ return NULL;
VikTrack *trkf = vik_trw_layer_get_track ( l, (gpointer) newname );
// Property Dialog of the track
vik_trw_layer_propwin_update ( trk );
-#ifdef VIK_CONFIG_ALPHABETIZED_TRW
- vik_treeview_sublayer_realphabetize ( VIK_LAYER(l)->vt, iter, newname );
-#endif
+ vik_treeview_item_set_name ( VIK_LAYER(l)->vt, iter, newname );
+ vik_treeview_sort_children ( VIK_LAYER(l)->vt, &(l->tracks_iter), l->track_sort_order );
vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(vlp) );
VikTrack *trk = g_hash_table_lookup ( l->routes, sublayer );
// No actual change to the name supplied
- if (strcmp(newname, trk->name) == 0)
- return NULL;
+ if ( trk->name )
+ if (strcmp(newname, trk->name) == 0)
+ return NULL;
VikTrack *trkf = vik_trw_layer_get_route ( l, (gpointer) newname );
// Property Dialog of the track
vik_trw_layer_propwin_update ( trk );
-#ifdef VIK_CONFIG_ALPHABETIZED_TRW
- vik_treeview_sublayer_realphabetize ( VIK_LAYER(l)->vt, iter, newname );
-#endif
+ vik_treeview_item_set_name ( VIK_LAYER(l)->vt, iter, newname );
+ vik_treeview_sort_children ( VIK_LAYER(l)->vt, &(l->tracks_iter), l->track_sort_order );
vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(vlp) );
pass_along[5] = wp->image;
item = gtk_image_menu_item_new_with_mnemonic ( _("_Show Picture...") );
- gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock ("Show Picture", GTK_ICON_SIZE_MENU) ); // Own icon - see stock_icons in vikwindow.c
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock ("vik-icon-Show Picture", GTK_ICON_SIZE_MENU) ); // Own icon - see stock_icons in vikwindow.c
g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_show_picture), pass_along );
gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
gtk_widget_show ( item );
g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_delete_waypoints_from_selection), pass_along );
gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
gtk_widget_show ( item );
+
+ GtkWidget *vis_submenu = gtk_menu_new ();
+ item = gtk_menu_item_new_with_mnemonic ( _("_Visibility") );
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show ( item );
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), vis_submenu );
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_Show All Waypoints") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_APPLY, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_waypoints_visibility_on), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(vis_submenu), item );
+ gtk_widget_show ( item );
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_Hide All Waypoints") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_CLEAR, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_waypoints_visibility_off), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(vis_submenu), item );
+ gtk_widget_show ( item );
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_Toggle") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_REFRESH, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_waypoints_visibility_toggle), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(vis_submenu), item );
+ gtk_widget_show ( item );
}
if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACKS )
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(menu), item );
gtk_widget_show ( item );
+
+ GtkWidget *vis_submenu = gtk_menu_new ();
+ item = gtk_menu_item_new_with_mnemonic ( _("_Visibility") );
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show ( item );
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), vis_submenu );
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_Show All Tracks") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_APPLY, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_tracks_visibility_on), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(vis_submenu), item );
+ gtk_widget_show ( item );
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_Hide All Tracks") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_CLEAR, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_tracks_visibility_off), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(vis_submenu), item );
+ gtk_widget_show ( item );
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_Toggle") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_REFRESH, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_tracks_visibility_toggle), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(vis_submenu), item );
+ gtk_widget_show ( item );
+
+ item = gtk_menu_item_new_with_mnemonic ( _("_Statistics") );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_tracks_stats), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
+ gtk_widget_show ( item );
}
if ( subtype == VIK_TRW_LAYER_SUBLAYER_ROUTES )
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(menu), item );
gtk_widget_show ( item );
+
+ GtkWidget *vis_submenu = gtk_menu_new ();
+ item = gtk_menu_item_new_with_mnemonic ( _("_Visibility") );
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show ( item );
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), vis_submenu );
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_Show All Routes") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_APPLY, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_routes_visibility_on), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(vis_submenu), item );
+ gtk_widget_show ( item );
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_Hide All Routes") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_CLEAR, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_routes_visibility_off), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(vis_submenu), item );
+ gtk_widget_show ( item );
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_Toggle") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_REFRESH, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_routes_visibility_toggle), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(vis_submenu), item );
+ gtk_widget_show ( item );
+
+ item = gtk_menu_item_new_with_mnemonic ( _("_Statistics") );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_routes_stats), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
+ gtk_widget_show ( item );
+ }
+
+
+ if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINTS || subtype == VIK_TRW_LAYER_SUBLAYER_TRACKS || subtype == VIK_TRW_LAYER_SUBLAYER_ROUTES ) {
+ GtkWidget *submenu_sort = gtk_menu_new ();
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_Sort") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_REFRESH, 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), submenu_sort );
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("Name _Ascending") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_SORT_ASCENDING, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_sort_order_a2z), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(submenu_sort), item );
+ gtk_widget_show ( item );
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("Name _Descending") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_SORT_DESCENDING, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_sort_order_z2a), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(submenu_sort), item );
+ gtk_widget_show ( item );
}
GtkWidget *upload_submenu = gtk_menu_new ();
gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
gtk_widget_show ( item );
+ item = gtk_menu_item_new_with_mnemonic ( _("_Statistics") );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_track_statistics), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
+ gtk_widget_show ( item );
+
GtkWidget *goto_submenu;
goto_submenu = gtk_menu_new ();
item = gtk_image_menu_item_new_with_mnemonic ( _("_Goto") );
gtk_menu_shell_append ( GTK_MENU_SHELL(delete_submenu), item );
gtk_widget_show ( item );
+ GtkWidget *transform_submenu;
+ transform_submenu = gtk_menu_new ();
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_Transform") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_CONVERT, 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), transform_submenu );
+
+ GtkWidget *dem_submenu;
+ dem_submenu = gtk_menu_new ();
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_Apply DEM Data") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock ("vik-icon-DEM Download", GTK_ICON_SIZE_MENU) ); // Own icon - see stock_icons in vikwindow.c
+ gtk_menu_shell_append ( GTK_MENU_SHELL(transform_submenu), item );
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), dem_submenu );
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_Overwrite") );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_apply_dem_data_all), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(dem_submenu), item );
+ gtk_widget_set_tooltip_text (item, _("Overwrite any existing elevation values with DEM values"));
+ gtk_widget_show ( item );
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_Keep Existing") );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_apply_dem_data_only_missing), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(dem_submenu), item );
+ gtk_widget_set_tooltip_text (item, _("Keep existing elevation values, only attempt for missing values"));
+ gtk_widget_show ( item );
+
+ GtkWidget *smooth_submenu;
+ smooth_submenu = gtk_menu_new ();
+ item = gtk_menu_item_new_with_mnemonic ( _("_Smooth Missing Elevation Data") );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(transform_submenu), item );
+ gtk_widget_show ( item );
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), smooth_submenu );
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_Interpolated") );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_missing_elevation_data_interp), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(smooth_submenu), item );
+ gtk_widget_set_tooltip_text (item, _("Interpolate between known elevation values to derive values for the missing elevations"));
+ gtk_widget_show ( item );
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_Flat") );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_missing_elevation_data_flat), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(smooth_submenu), item );
+ gtk_widget_set_tooltip_text (item, _("Set unknown elevation values to the last known value"));
+ gtk_widget_show ( item );
+
+ if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK )
+ item = gtk_image_menu_item_new_with_mnemonic ( _("C_onvert to a Route") );
+ else
+ item = gtk_image_menu_item_new_with_mnemonic ( _("C_onvert to a Track") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_CONVERT, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_convert_track_route), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(transform_submenu), item );
+ gtk_widget_show ( item );
+
+ // Routes don't have timestamps - so this is only available for tracks
+ if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK ) {
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_Anonymize Times") );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_anonymize_times), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(transform_submenu), item );
+ gtk_widget_set_tooltip_text (item, _("Shift timestamps to a relative offset from 1901-01-01"));
+ gtk_widget_show ( item );
+ }
+
if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK )
item = gtk_image_menu_item_new_with_mnemonic ( _("_Reverse Track") );
else
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 ( _("Refine Route...") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_FIND, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_route_refine), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
+ gtk_widget_show ( item );
+ }
+
/* ATM This function is only available via the layers panel, due to the method in finding out the maps in use */
if ( vlp ) {
if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK )
item = gtk_image_menu_item_new_with_mnemonic ( _("Down_load Maps Along Track...") );
else
item = gtk_image_menu_item_new_with_mnemonic ( _("Down_load Maps Along Route...") );
- gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock ("Maps Download", GTK_ICON_SIZE_MENU) ); // Own icon - see stock_icons in vikwindow.c
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock ("vik-icon-Maps Download", GTK_ICON_SIZE_MENU) ); // Own icon - see stock_icons in vikwindow.c
g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_download_map_along_track_cb), pass_along );
gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
gtk_widget_show ( item );
}
- item = gtk_image_menu_item_new_with_mnemonic ( _("_Apply DEM Data") );
- gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock ("DEM Download/Import", GTK_ICON_SIZE_MENU) ); // Own icon - see stock_icons in vikwindow.c
- g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_apply_dem_data), pass_along );
- gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
- gtk_widget_show ( item );
-
if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK )
item = gtk_image_menu_item_new_with_mnemonic ( _("_Export Track as GPX...") );
else
gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
gtk_widget_show ( item );
- if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK )
- item = gtk_image_menu_item_new_with_mnemonic ( _("C_onvert to a Route") );
- else
- item = gtk_image_menu_item_new_with_mnemonic ( _("C_onvert to a Track") );
- gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_CONVERT, GTK_ICON_SIZE_MENU) );
- g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_convert_track_route), pass_along );
- gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
- gtk_widget_show ( item );
-
-#ifdef VIK_CONFIG_GOOGLE
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
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock ("vik-icon-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
if ( subtype != VIK_TRW_LAYER_SUBLAYER_WAYPOINT ) {
}
}
+ if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINTS || subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT ) {
+ GtkWidget *transform_submenu;
+ transform_submenu = gtk_menu_new ();
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_Transform") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_CONVERT, 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), transform_submenu );
+
+ GtkWidget *dem_submenu;
+ dem_submenu = gtk_menu_new ();
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_Apply DEM Data") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock ("vik-icon-DEM Download", GTK_ICON_SIZE_MENU) ); // Own icon - see stock_icons in vikwindow.c
+ gtk_menu_shell_append ( GTK_MENU_SHELL(transform_submenu), item );
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), dem_submenu );
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_Overwrite") );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_apply_dem_data_wpt_all), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(dem_submenu), item );
+ gtk_widget_set_tooltip_text (item, _("Overwrite any existing elevation values with DEM values"));
+ gtk_widget_show ( item );
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_Keep Existing") );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_apply_dem_data_wpt_only_missing), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(dem_submenu), item );
+ gtk_widget_set_tooltip_text (item, _("Keep existing elevation values, only attempt for missing values"));
+ gtk_widget_show ( item );
+ }
+
+ gtk_widget_show_all ( GTK_WIDGET(menu) );
+
return rv;
}
if courses in degrees are 350 + 020, the mid course more likely to be 005 (not 185)
[similar applies if value is in radians] */
if (tp_current->course != NAN && tp_next->course != NAN)
- tp_new->speed = (tp_current->course + tp_next->course)/2;
+ tp_new->course = (tp_current->course + tp_next->course)/2;
/* DOP / sat values remain at defaults as not they do not seem applicable to a dreamt up point */
gint index = g_list_index ( trk->trackpoints, tp_current );
if ( index > -1 ) {
+ // NB no recalculation of bounds since it is inserted between points
trk->trackpoints = g_list_insert ( trk->trackpoints, tp_new, index+1 );
}
}
vtl->current_tpl = new_tpl;
// Reset dialog with the available adjacent trackpoint
- if ( vtl->current_tp_track )
+ if ( vtl->current_tp_track ) {
+ vik_track_calculate_bounds ( 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));
}
vik_layer_emit_update(VIK_LAYER(vtl));
}
+/**
+ * trw_layer_dialog_shift:
+ * @vertical: The reposition strategy. If Vertical moves dialog vertically, otherwise moves it horizontally
+ *
+ * Try to reposition a dialog if it's over the specified coord
+ * so to not obscure the item of interest
+ */
+void trw_layer_dialog_shift ( VikTrwLayer *vtl, GtkWindow *dialog, VikCoord *coord, gboolean vertical )
+{
+ GtkWindow *parent = VIK_GTK_WINDOW_FROM_LAYER(vtl); //i.e. the main window
+
+ // Attempt force dialog to be shown so we can find out where it is more reliably...
+ while ( gtk_events_pending() )
+ gtk_main_iteration ();
+
+ // get parent window position & size
+ gint win_pos_x, win_pos_y;
+ gtk_window_get_position ( parent, &win_pos_x, &win_pos_y );
+
+ gint win_size_x, win_size_y;
+ gtk_window_get_size ( parent, &win_size_x, &win_size_y );
+
+ // get own dialog size
+ gint dia_size_x, dia_size_y;
+ gtk_window_get_size ( dialog, &dia_size_x, &dia_size_y );
+
+ // get own dialog position
+ gint dia_pos_x, dia_pos_y;
+ gtk_window_get_position ( dialog, &dia_pos_x, &dia_pos_y );
+
+ // Dialog not 'realized'/positioned - so can't really do any repositioning logic
+ if ( dia_pos_x > 2 && dia_pos_y > 2 ) {
+
+ VikViewport *vvp = vik_window_viewport ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)) );
+
+ gint vp_xx, vp_yy; // In viewport pixels
+ vik_viewport_coord_to_screen ( vvp, coord, &vp_xx, &vp_yy );
+
+ // Work out the 'bounding box' in pixel terms of the dialog and only move it when over the position
+
+ gint dest_x = 0;
+ gint dest_y = 0;
+ if ( gtk_widget_translate_coordinates ( GTK_WIDGET(vvp), GTK_WIDGET(parent), 0, 0, &dest_x, &dest_y ) ) {
+
+ // Transform Viewport pixels into absolute pixels
+ gint tmp_xx = vp_xx + dest_x + win_pos_x - 10;
+ gint tmp_yy = vp_yy + dest_y + win_pos_y - 10;
+
+ // Is dialog over the point (to within an ^^ edge value)
+ if ( (tmp_xx > dia_pos_x) && (tmp_xx < (dia_pos_x + dia_size_x)) &&
+ (tmp_yy > dia_pos_y) && (tmp_yy < (dia_pos_y + dia_size_y)) ) {
+
+ if ( vertical ) {
+ // Shift up<->down
+ gint hh = vik_viewport_get_height ( vvp );
+
+ // Consider the difference in viewport to the full window
+ gint offset_y = dest_y;
+ // Add difference between dialog and window sizes
+ offset_y += win_pos_y + (hh/2 - dia_size_y)/2;
+
+ if ( vp_yy > hh/2 ) {
+ // Point in bottom half, move window to top half
+ gtk_window_move ( dialog, dia_pos_x, offset_y );
+ }
+ else {
+ // Point in top half, move dialog down
+ gtk_window_move ( dialog, dia_pos_x, hh/2 + offset_y );
+ }
+ }
+ else {
+ // Shift left<->right
+ gint ww = vik_viewport_get_width ( vvp );
+
+ // Consider the difference in viewport to the full window
+ gint offset_x = dest_x;
+ // Add difference between dialog and window sizes
+ offset_x += win_pos_x + (ww/2 - dia_size_x)/2;
+
+ if ( vp_xx > ww/2 ) {
+ // Point on right, move window to left
+ gtk_window_move ( dialog, offset_x, dia_pos_y );
+ }
+ else {
+ // Point on left, move right
+ gtk_window_move ( dialog, ww/2 + offset_x, dia_pos_y );
+ }
+ }
+ }
+ }
+ }
+}
+
static void trw_layer_tpwin_init ( VikTrwLayer *vtl )
{
if ( ! vtl->tpwin )
g_signal_connect_swapped ( GTK_DIALOG(vtl->tpwin), "response", G_CALLBACK(trw_layer_tpwin_response), vtl );
/* connect signals -- DELETE SIGNAL VERY IMPORTANT TO SET TO NULL */
g_signal_connect_swapped ( vtl->tpwin, "delete-event", G_CALLBACK(trw_layer_cancel_current_tp), vtl );
+
gtk_widget_show_all ( GTK_WIDGET(vtl->tpwin) );
+
+ if ( vtl->current_tpl ) {
+ // get tp pixel position
+ VikTrackpoint *tp = VIK_TRACKPOINT(vtl->current_tpl->data);
+
+ // Shift up<->down to try not to obscure the trackpoint.
+ trw_layer_dialog_shift ( vtl, GTK_WINDOW(vtl->tpwin), &(tp->coord), TRUE );
+ }
}
+
if ( vtl->current_tpl )
if ( vtl->current_tp_track )
vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name );
typedef struct {
gint x, y;
gint closest_x, closest_y;
+ gboolean draw_images;
gpointer *closest_wp_id;
VikWaypoint *closest_wp;
VikViewport *vvp;
VikTrackpoint *closest_tp;
VikViewport *vvp;
GList *closest_tpl;
+ LatLonBBox bbox;
} TPSearchParams;
static void waypoint_search_closest_tp ( gpointer id, VikWaypoint *wp, WPSearchParams *params )
vik_viewport_coord_to_screen ( params->vvp, &(wp->coord), &x, &y );
// If waypoint has an image then use the image size to select
- if ( wp->image ) {
+ if ( params->draw_images && wp->image ) {
gint slackx, slacky;
slackx = wp->image_width / 2;
slacky = wp->image_height / 2;
if ( !t->visible )
return;
+ if ( ! BBOX_INTERSECT ( t->bbox, params->bbox ) )
+ return;
+
while (tpl)
{
gint x, y;
params.vvp = vvp;
params.closest_track_id = NULL;
params.closest_tp = NULL;
+ vik_viewport_get_min_max_lat_lon ( params.vvp, &(params.bbox.south), &(params.bbox.north), &(params.bbox.west), &(params.bbox.east) );
g_hash_table_foreach ( vtl->tracks, (GHFunc) track_search_closest_tp, ¶ms);
return params.closest_tp;
}
params.x = x;
params.y = y;
params.vvp = vvp;
+ params.draw_images = vtl->drawimages;
params.closest_wp = NULL;
params.closest_wp_id = NULL;
g_hash_table_foreach ( vtl->waypoints, (GHFunc) waypoint_search_closest_tp, ¶ms);
marker_end_move ( t );
// Determine if working on a waypoint or a trackpoint
- if ( t->is_waypoint )
+ if ( t->is_waypoint ) {
+ // Update waypoint position
vtl->current_wp->coord = new_coord;
+ trw_layer_calculate_bounds_waypoints ( vtl );
+ // Reset waypoint pointer
+ vtl->current_wp = NULL;
+ vtl->current_wp_id = NULL;
+ }
else {
if ( vtl->current_tpl ) {
VIK_TRACKPOINT(vtl->current_tpl->data)->coord = new_coord;
-
- if ( vtl->tpwin )
+
+ if ( vtl->current_tp_track )
+ vik_track_calculate_bounds ( vtl->current_tp_track );
+
+ if ( vtl->tpwin )
if ( vtl->current_tp_track )
vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name );
+ // NB don't reset the selected trackpoint, thus ensuring it's still in the tpwin
}
}
- // Reset
- vtl->current_wp = NULL;
- vtl->current_wp_id = NULL;
- trw_layer_cancel_current_tp ( vtl, FALSE );
-
vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
}
if ( !vtl->tracks_visible && !vtl->waypoints_visible && !vtl->routes_visible )
return FALSE;
+ LatLonBBox bbox;
+ vik_viewport_get_min_max_lat_lon ( vvp, &(bbox.south), &(bbox.north), &(bbox.west), &(bbox.east) );
+
// Go for waypoints first as these often will be near a track, but it's likely the wp is wanted rather then the track
- if (vtl->waypoints_visible) {
+ if ( vtl->waypoints_visible && BBOX_INTERSECT (vtl->waypoints_bbox, bbox ) ) {
WPSearchParams wp_params;
wp_params.vvp = vvp;
wp_params.x = event->x;
wp_params.y = event->y;
+ wp_params.draw_images = vtl->drawimages;
wp_params.closest_wp_id = NULL;
wp_params.closest_wp = NULL;
tp_params.y = event->y;
tp_params.closest_track_id = NULL;
tp_params.closest_tp = NULL;
+ tp_params.closest_tpl = NULL;
+ tp_params.bbox = bbox;
if (vtl->tracks_visible) {
g_hash_table_foreach ( vtl->tracks, (GHFunc) track_search_closest_tp, &tp_params);
return t;
}
+static void tool_edit_waypoint_destroy ( tool_ed_t *t )
+{
+ g_free ( t );
+}
+
static gboolean tool_edit_waypoint_click ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data )
{
WPSearchParams params;
params.vvp = vvp;
params.x = event->x;
params.y = event->y;
+ params.draw_images = vtl->drawimages;
params.closest_wp_id = NULL;
/* TODO: should get track listitem so we can break it up, make a new track, mess it up, all that. */
params.closest_wp = NULL;
marker_end_move ( t );
vtl->current_wp->coord = new_coord;
+
+ trw_layer_calculate_bounds_waypoints ( vtl );
vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
}
ds->vtl->draw_sync_done = TRUE;
gdk_threads_leave();
}
+ g_free ( ds );
return FALSE;
}
w1 = vik_viewport_get_width(vvp);
h1 = vik_viewport_get_height(vvp);
if (!pixmap) {
- pixmap = gdk_pixmap_new ( GTK_WIDGET(vvp)->window, w1, h1, -1 );
+ pixmap = gdk_pixmap_new ( gtk_widget_get_window(GTK_WIDGET(vvp)), w1, h1, -1 );
}
gdk_drawable_get_size (pixmap, &w2, &h2);
if (w1 != w2 || h1 != h2) {
g_object_unref ( G_OBJECT ( pixmap ) );
- pixmap = gdk_pixmap_new ( GTK_WIDGET(vvp)->window, w1, h1, -1 );
+ pixmap = gdk_pixmap_new ( gtk_widget_get_window(GTK_WIDGET(vvp)), w1, h1, -1 );
}
// Reset to background
elev_loss += last_tpt->altitude - elev_new;
}
}
-
- gchar *str = distance_string (distance);
- PangoLayout *pl = gtk_widget_create_pango_layout (GTK_WIDGET(vvp), NULL);
- pango_layout_set_font_description (pl, gtk_widget_get_style(GTK_WIDGET(vvp))->font_desc);
+ //
+ // Display of the distance 'tooltip' during track creation is controlled by a preference
+ //
+ if ( a_vik_get_create_track_tooltip() ) {
+
+ gchar *str = distance_string (distance);
- pango_layout_set_text (pl, str, -1);
- gint wd, hd;
- pango_layout_get_pixel_size ( pl, &wd, &hd );
+ PangoLayout *pl = gtk_widget_create_pango_layout (GTK_WIDGET(vvp), NULL);
+ pango_layout_set_font_description (pl, gtk_widget_get_style(GTK_WIDGET(vvp))->font_desc);
+ pango_layout_set_text (pl, str, -1);
+ gint wd, hd;
+ pango_layout_get_pixel_size ( pl, &wd, &hd );
- gint xd,yd;
- // offset from cursor a bit depending on font size
- xd = event->x + 10;
- yd = event->y - hd;
+ gint xd,yd;
+ // offset from cursor a bit depending on font size
+ xd = event->x + 10;
+ yd = event->y - hd;
- // Create a background block to make the text easier to read over the background map
- GdkGC *background_block_gc = vik_viewport_new_gc ( vvp, "#cccccc", 1);
- gdk_draw_rectangle (pixmap, background_block_gc, TRUE, xd-2, yd-2, wd+4, hd+2);
- gdk_draw_layout (pixmap, vtl->current_track_newpoint_gc, xd, yd, pl);
+ // Create a background block to make the text easier to read over the background map
+ GdkGC *background_block_gc = vik_viewport_new_gc ( vvp, "#cccccc", 1);
+ gdk_draw_rectangle (pixmap, background_block_gc, TRUE, xd-2, yd-2, wd+4, hd+2);
+ gdk_draw_layout (pixmap, vtl->current_track_newpoint_gc, xd, yd, pl);
- g_object_unref ( G_OBJECT ( pl ) );
- g_object_unref ( G_OBJECT ( background_block_gc ) );
+ g_object_unref ( G_OBJECT ( pl ) );
+ g_object_unref ( G_OBJECT ( background_block_gc ) );
+ g_free (str);
+ }
passalong = g_new(draw_sync_t,1); // freed by draw_sync()
passalong->vtl = vtl;
passalong->pixmap = pixmap;
- passalong->drawable = GTK_WIDGET(vvp)->window;
+ passalong->drawable = gtk_widget_get_window(GTK_WIDGET(vvp));
passalong->gc = vtl->current_track_newpoint_gc;
gdouble angle;
// Update statusbar with full gain/loss information
statusbar_write (distance, elev_gain, elev_loss, last_step, angle, vtl);
- g_free (str);
-
// draw pixmap when we have time to
g_idle_add_full (G_PRIORITY_HIGH_IDLE + 10, draw_sync, passalong, NULL);
vtl->draw_sync_done = FALSE;
g_free ( last->data );
vtl->current_track->trackpoints = g_list_remove_link ( vtl->current_track->trackpoints, last );
}
+ vik_track_calculate_bounds ( vtl->current_track );
update_statusbar ( vtl );
vik_layer_emit_update ( VIK_LAYER(vtl) );
tp->timestamp = 0;
if ( vtl->current_track ) {
- vtl->current_track->trackpoints = g_list_append ( vtl->current_track->trackpoints, tp );
+ vik_track_add_trackpoint ( vtl->current_track, tp, TRUE ); // Ensure bounds is updated
/* Auto attempt to get elevation from DEM data (if it's available) */
vik_track_apply_dem_data_last_trackpoint ( vtl->current_track );
}
if ( event->button == 1 && ( ! vtl->current_track || (vtl->current_track && vtl->current_track->is_route ) ))
{
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 ) ) )
+ if ( ( name = a_dialog_new_track ( VIK_GTK_WINDOW_FROM_LAYER(vtl), name, FALSE ) ) )
{
new_track_create_common ( vtl, name );
+ g_free ( name );
}
else
return TRUE;
if ( event->button == 1 && ( ! vtl->current_track || (vtl->current_track && !vtl->current_track->is_route ) ) )
{
gchar *name = trw_layer_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_ROUTE, _("Route"));
- if ( ( name = a_dialog_new_track ( VIK_GTK_WINDOW_FROM_LAYER(vtl), vtl->routes, name, TRUE ) ) )
+ if ( ( name = a_dialog_new_track ( VIK_GTK_WINDOW_FROM_LAYER(vtl), name, TRUE ) ) ) {
new_route_create_common ( vtl, name );
+ g_free ( name );
+ }
else
return TRUE;
}
if (!vtl || vtl->vl.type != VIK_LAYER_TRW)
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)
+ if (vik_trw_layer_new_waypoint ( vtl, VIK_GTK_WINDOW_FROM_LAYER(vtl), &coord ) && VIK_LAYER(vtl)->visible) {
+ trw_layer_calculate_bounds_waypoints ( vtl );
vik_layer_emit_update ( VIK_LAYER(vtl) );
+ }
return TRUE;
}
return t;
}
+static void tool_edit_trackpoint_destroy ( tool_ed_t *t )
+{
+ g_free ( t );
+}
+
static gboolean tool_edit_trackpoint_click ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data )
{
tool_ed_t *t = data;
params.closest_track_id = NULL;
/* TODO: should get track listitem so we can break it up, make a new track, mess it up, all that. */
params.closest_tp = NULL;
+ params.closest_tpl = NULL;
+ vik_viewport_get_min_max_lat_lon ( vvp, &(params.bbox.south), &(params.bbox.north), &(params.bbox.west), &(params.bbox.east) );
if ( event->button != 1 )
return FALSE;
}
VIK_TRACKPOINT(vtl->current_tpl->data)->coord = new_coord;
+ if ( vtl->current_tp_track )
+ vik_track_calculate_bounds ( vtl->current_tp_track );
marker_end_move ( t );
}
-#ifdef VIK_CONFIG_GOOGLE
/*** Route Finder ***/
static gpointer tool_route_finder_create ( VikWindow *vw, VikViewport *vvp)
{
}
else if ( vtl->route_finder_started || (event->state & GDK_CONTROL_MASK && vtl->route_finder_current_track) ) {
struct LatLon start, end;
- gchar startlat[G_ASCII_DTOSTR_BUF_SIZE], startlon[G_ASCII_DTOSTR_BUF_SIZE];
- gchar endlat[G_ASCII_DTOSTR_BUF_SIZE], endlon[G_ASCII_DTOSTR_BUF_SIZE];
- gchar *url;
vik_coord_to_latlon ( &(vtl->route_finder_coord), &start );
vik_coord_to_latlon ( &(tmp), &end );
vtl->route_finder_started = FALSE;
}
- url = g_strdup_printf(GOOGLE_DIRECTIONS_STRING,
- g_ascii_dtostr (startlat, G_ASCII_DTOSTR_BUF_SIZE, (gdouble) start.lat),
- 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));
- // 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 );
+ vik_routing_default_find ( vtl, start, end);
/* see if anything was done -- a track was added or appended to */
if ( vtl->route_finder_check_added_track && vtl->route_finder_added_track ) {
gchar *new_comment = g_strdup_printf("%s to: %f,%f", vtl->route_finder_current_track->comment, end.lat, end.lon );
vik_track_set_comment_no_copy ( vtl->route_finder_current_track, new_comment );
}
+
+ if ( vtl->route_finder_added_track )
+ vik_track_calculate_bounds ( vtl->route_finder_added_track );
+
vtl->route_finder_added_track = NULL;
vtl->route_finder_check_added_track = FALSE;
vtl->route_finder_append = FALSE;
}
return TRUE;
}
-#endif
/*** Show picture ****/
}
}
-static void trw_layer_post_read ( VikTrwLayer *vtl, GtkWidget *vp )
+/*
+ * (Re)Calculate the bounds of the waypoints in this layer,
+ * This should be called whenever waypoints are changed
+ */
+static void trw_layer_calculate_bounds_waypoints ( VikTrwLayer *vtl )
+{
+ struct LatLon topleft = { 0.0, 0.0 };
+ struct LatLon bottomright = { 0.0, 0.0 };
+ struct LatLon ll;
+
+ GHashTableIter iter;
+ gpointer key, value;
+
+ g_hash_table_iter_init ( &iter, vtl->waypoints );
+
+ // Set bounds to first point
+ if ( g_hash_table_iter_next (&iter, &key, &value) ) {
+ vik_coord_to_latlon ( &(VIK_WAYPOINT(value)->coord), &topleft );
+ vik_coord_to_latlon ( &(VIK_WAYPOINT(value)->coord), &bottomright );
+ }
+
+ // Ensure there is another point...
+ if ( g_hash_table_size ( vtl->waypoints ) > 1 ) {
+
+ while ( g_hash_table_iter_next (&iter, &key, &value) ) {
+
+ // See if this point increases the bounds.
+ vik_coord_to_latlon ( &(VIK_WAYPOINT(value)->coord), &ll );
+
+ if ( ll.lat > topleft.lat) topleft.lat = ll.lat;
+ if ( ll.lon < topleft.lon) topleft.lon = ll.lon;
+ if ( ll.lat < bottomright.lat) bottomright.lat = ll.lat;
+ if ( ll.lon > bottomright.lon) bottomright.lon = ll.lon;
+ }
+ }
+
+ vtl->waypoints_bbox.north = topleft.lat;
+ vtl->waypoints_bbox.east = bottomright.lon;
+ vtl->waypoints_bbox.south = bottomright.lat;
+ vtl->waypoints_bbox.west = topleft.lon;
+}
+
+static void trw_layer_calculate_bounds_track ( gpointer id, VikTrack *trk )
+{
+ vik_track_calculate_bounds ( trk );
+}
+
+static void trw_layer_calculate_bounds_tracks ( VikTrwLayer *vtl )
+{
+ g_hash_table_foreach ( vtl->tracks, (GHFunc) trw_layer_calculate_bounds_track, NULL );
+ g_hash_table_foreach ( vtl->routes, (GHFunc) trw_layer_calculate_bounds_track, NULL );
+}
+
+static void trw_layer_sort_all ( VikTrwLayer *vtl )
+{
+ if ( ! VIK_LAYER(vtl)->vt )
+ return;
+
+ // Obviously need 2 to tango - sorting with only 1 (or less) is a lonely activity!
+ if ( g_hash_table_size (vtl->tracks) > 1 )
+ vik_treeview_sort_children ( VIK_LAYER(vtl)->vt, &(vtl->tracks_iter), vtl->track_sort_order );
+
+ if ( g_hash_table_size (vtl->routes) > 1 )
+ vik_treeview_sort_children ( VIK_LAYER(vtl)->vt, &(vtl->routes_iter), vtl->track_sort_order );
+
+ if ( g_hash_table_size (vtl->waypoints) > 1 )
+ vik_treeview_sort_children ( VIK_LAYER(vtl)->vt, &(vtl->waypoints_iter), vtl->wp_sort_order );
+}
+
+static void trw_layer_post_read ( VikTrwLayer *vtl, GtkWidget *vvp, gboolean from_file )
{
- trw_layer_verify_thumbnails ( vtl, vp );
+ if ( VIK_LAYER(vtl)->realized )
+ trw_layer_verify_thumbnails ( vtl, vvp );
trw_layer_track_alloc_colors ( vtl );
+
+ trw_layer_calculate_bounds_waypoints ( vtl );
+ trw_layer_calculate_bounds_tracks ( vtl );
+
+ // Apply treeview sort after loading all the tracks for this layer
+ // (rather than sorted insert on each individual track additional)
+ // and after subsequent changes to the properties as the specified order may have changed.
+ // since the sorting of a treeview section is now very quick
+ // NB sorting is also performed after every name change as well to maintain the list order
+ trw_layer_sort_all ( vtl );
}
VikCoordMode vik_trw_layer_get_coord_mode ( VikTrwLayer *vtl )
}
for (rect_iter = rects_to_download; rect_iter; rect_iter = rect_iter->next) {
- maps_layer_download_section (vml, vvp, &(((Rect *)(rect_iter->data))->tl), &(((Rect *)(rect_iter->data))->br), zoom_level);
+ vik_maps_layer_download_section (vml, vvp, &(((Rect *)(rect_iter->data))->tl), &(((Rect *)(rect_iter->data))->br), zoom_level);
}
if (fillins) {
static void trw_layer_download_map_along_track_cb ( gpointer pass_along[6] )
{
VikMapsLayer *vml;
- gint selected_map, default_map;
+ gint selected_map;
gchar *zoomlist[] = {"0.125", "0.25", "0.5", "1", "2", "4", "8", "16", "32", "64", "128", "256", "512", "1024", NULL };
gdouble zoom_vals[] = {0.125, 0.25, 0.5, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024};
gint selected_zoom, default_zoom;
- int i,j;
-
VikTrwLayer *vtl = pass_along[0];
VikLayersPanel *vlp = pass_along[1];
int num_maps = g_list_length(vmls);
if (!num_maps) {
- a_dialog_msg(VIK_GTK_WINDOW_FROM_LAYER(vtl), GTK_MESSAGE_ERROR, _("No map layer in use. Create one first"), NULL);
+ a_dialog_error_msg(VIK_GTK_WINDOW_FROM_LAYER(vtl), _("No map layer in use. Create one first") );
return;
}
+ // Convert from list of vmls to list of names. Allowing the user to select one of them
gchar **map_names = g_malloc(1 + num_maps * sizeof(gpointer));
VikMapsLayer **map_layers = g_malloc(1 + num_maps * sizeof(gpointer));
gchar **np = map_names;
VikMapsLayer **lp = map_layers;
+ int i;
for (i = 0; i < num_maps; i++) {
- gboolean dup = FALSE;
vml = (VikMapsLayer *)(vmls->data);
- for (j = 0; j < i; j++) { /* no duplicate allowed */
- if (vik_maps_layer_get_map_type(vml) == vik_maps_layer_get_map_type(map_layers[j])) {
- dup = TRUE;
- break;
- }
- }
- if (!dup) {
- *lp++ = vml;
- *np++ = vik_maps_layer_get_map_label(vml);
- }
+ *lp++ = vml;
+ *np++ = vik_maps_layer_get_map_label(vml);
vmls = vmls->next;
}
+ // Mark end of the array lists
*lp = NULL;
*np = NULL;
- num_maps = lp - map_layers;
-
- for (default_map = 0; default_map < num_maps; default_map++) {
- /* TODO: check for parent layer's visibility */
- if (VIK_LAYER(map_layers[default_map])->visible)
- break;
- }
- default_map = (default_map == num_maps) ? 0 : default_map;
gdouble cur_zoom = vik_viewport_get_zoom(vvp);
- for (default_zoom = 0; default_zoom < sizeof(zoom_vals)/sizeof(gdouble); default_zoom++) {
+ for (default_zoom = 0; default_zoom < G_N_ELEMENTS(zoom_vals); default_zoom++) {
if (cur_zoom == zoom_vals[default_zoom])
break;
}
- default_zoom = (default_zoom == sizeof(zoom_vals)/sizeof(gdouble)) ? sizeof(zoom_vals)/sizeof(gdouble) - 1 : default_zoom;
+ default_zoom = (default_zoom == G_N_ELEMENTS(zoom_vals)) ? G_N_ELEMENTS(zoom_vals) - 1 : default_zoom;
- if (!a_dialog_map_n_zoom(VIK_GTK_WINDOW_FROM_LAYER(vtl), map_names, default_map, zoomlist, default_zoom, &selected_map, &selected_zoom))
+ if (!a_dialog_map_n_zoom(VIK_GTK_WINDOW_FROM_LAYER(vtl), map_names, 0, zoomlist, default_zoom, &selected_map, &selected_zoom))
goto done;
vik_track_download_map(trk, map_layers[selected_map], vvp, zoom_vals[selected_zoom]);