#include "viking.h"
#include "vikmapslayer.h"
#include "vikgpslayer.h"
+#include "viktrwlayer_export.h"
#include "viktrwlayer_tpwin.h"
#include "viktrwlayer_propwin.h"
+#include "viktrwlayer_analysis.h"
+#include "viktrwlayer_tracklist.h"
+#include "viktrwlayer_waypointlist.h"
#ifdef VIK_CONFIG_GEOTAG
#include "viktrwlayer_geotag.h"
#include "geotag_exif.h"
#include "datasource_gps.h"
#include "vikexttool_datasources.h"
#include "util.h"
+#include "vikutils.h"
#include "vikrouting.h"
gboolean tracks_visible, routes_visible, waypoints_visible;
LatLonBBox waypoints_bbox;
+ gboolean track_draw_labels;
guint8 drawmode;
guint8 drawpoints;
guint8 drawpoints_size;
guint8 bg_line_thickness;
vik_layer_sort_order_t track_sort_order;
+ // Metadata
+ VikTRWMetadata *metadata;
+
+ PangoLayout *tracklabellayout;
+ font_size_t track_font_size;
+ gchar *track_fsize_str;
+
guint8 wp_symbol;
guint8 wp_size;
gboolean wp_draw_symbols;
/* route finder tool */
gboolean route_finder_started;
- VikCoord route_finder_coord;
gboolean route_finder_check_added_track;
VikTrack *route_finder_added_track;
- VikTrack *route_finder_current_track;
gboolean route_finder_append;
gboolean drawlabels;
VikStdLayerMenuItem menu_selection;
gint highest_wp_number;
+
+ // One per layer
+ GtkWidget *tracks_analysis_dialog;
};
/* A caached waypoint image. */
gboolean one_zone, lat_lon;
gdouble ce1, ce2, cn1, cn2;
LatLonBBox bbox;
+ gboolean highlight;
};
static gboolean trw_layer_delete_waypoint ( VikTrwLayer *vtl, VikWaypoint *wp );
-static void trw_layer_delete_item ( gpointer pass_along[6] );
-static void trw_layer_copy_item_cb ( gpointer pass_along[6] );
-static void trw_layer_cut_item_cb ( gpointer pass_along[6] );
+typedef enum {
+ MA_VTL = 0,
+ MA_VLP,
+ MA_SUBTYPE, // OR END for Layer only
+ MA_SUBLAYER_ID,
+ MA_CONFIRM,
+ MA_VVP,
+ MA_TV_ITER,
+ MA_MISC,
+ MA_LAST,
+} menu_array_index;
+
+typedef gpointer menu_array_layer[2];
+typedef gpointer menu_array_sublayer[MA_LAST];
+
+static void trw_layer_delete_item ( menu_array_sublayer values );
+static void trw_layer_copy_item_cb ( menu_array_sublayer values );
+static void trw_layer_cut_item_cb ( menu_array_sublayer values );
-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_goto_track_max_speed ( gpointer pass_along[6] );
-static void trw_layer_goto_track_max_alt ( gpointer pass_along[6] );
-static void trw_layer_goto_track_min_alt ( gpointer pass_along[6] );
-static void trw_layer_goto_track_center ( gpointer pass_along[6] );
-static void trw_layer_merge_by_segment ( gpointer pass_along[6] );
-static void trw_layer_merge_by_timestamp ( gpointer pass_along[6] );
-static void trw_layer_merge_with_other ( gpointer pass_along[6] );
-static void trw_layer_append_track ( gpointer pass_along[6] );
-static void trw_layer_split_by_timestamp ( gpointer pass_along[6] );
-static void trw_layer_split_by_n_points ( gpointer pass_along[6] );
-static void trw_layer_split_at_trackpoint ( gpointer pass_along[6] );
-static void trw_layer_split_segments ( gpointer pass_along[6] );
-static void trw_layer_delete_points_same_position ( gpointer pass_along[6] );
-static void trw_layer_delete_points_same_time ( gpointer pass_along[6] );
-static void trw_layer_reverse ( gpointer pass_along[6] );
-static void trw_layer_download_map_along_track_cb ( gpointer pass_along[6] );
-static void trw_layer_edit_trackpoint ( gpointer pass_along[6] );
-static void trw_layer_show_picture ( gpointer pass_along[6] );
-static void trw_layer_gps_upload_any ( gpointer pass_along[6] );
-
-static void trw_layer_centerize ( gpointer layer_and_vlp[2] );
-static void trw_layer_auto_view ( gpointer layer_and_vlp[2] );
-static void trw_layer_export ( gpointer layer_and_vlp[2], const gchar* title, const gchar* default_name, VikTrack* trk, guint file_type );
-static void trw_layer_goto_wp ( gpointer layer_and_vlp[2] );
-static void trw_layer_new_wp ( gpointer lav[2] );
-static void trw_layer_new_track ( gpointer lav[2] );
-static void trw_layer_new_route ( gpointer lav[2] );
-static void trw_layer_finish_track ( gpointer lav[2] );
-static void trw_layer_auto_waypoints_view ( gpointer lav[2] );
-static void trw_layer_auto_tracks_view ( gpointer lav[2] );
-static void trw_layer_delete_all_tracks ( gpointer lav[2] );
-static void trw_layer_delete_tracks_from_selection ( gpointer lav[2] );
-static void trw_layer_delete_all_waypoints ( gpointer lav[2] );
-static void trw_layer_delete_waypoints_from_selection ( gpointer lav[2] );
-static void trw_layer_new_wikipedia_wp_viewport ( gpointer lav[2] );
-static void trw_layer_new_wikipedia_wp_layer ( gpointer lav[2] );
+static void trw_layer_goto_track_startpoint ( menu_array_sublayer values );
+static void trw_layer_goto_track_endpoint ( menu_array_sublayer values );
+static void trw_layer_goto_track_max_speed ( menu_array_sublayer values );
+static void trw_layer_goto_track_max_alt ( menu_array_sublayer values );
+static void trw_layer_goto_track_min_alt ( menu_array_sublayer values );
+static void trw_layer_goto_track_center ( menu_array_sublayer values );
+static void trw_layer_merge_by_segment ( menu_array_sublayer values );
+static void trw_layer_merge_by_timestamp ( menu_array_sublayer values );
+static void trw_layer_merge_with_other ( menu_array_sublayer values );
+static void trw_layer_append_track ( menu_array_sublayer values );
+static void trw_layer_split_by_timestamp ( menu_array_sublayer values );
+static void trw_layer_split_by_n_points ( menu_array_sublayer values );
+static void trw_layer_split_at_trackpoint ( menu_array_sublayer values );
+static void trw_layer_split_segments ( menu_array_sublayer values );
+static void trw_layer_delete_point_selected ( menu_array_sublayer values );
+static void trw_layer_delete_points_same_position ( menu_array_sublayer values );
+static void trw_layer_delete_points_same_time ( menu_array_sublayer values );
+static void trw_layer_reverse ( menu_array_sublayer values );
+static void trw_layer_download_map_along_track_cb ( menu_array_sublayer values );
+static void trw_layer_edit_trackpoint ( menu_array_sublayer values );
+static void trw_layer_show_picture ( menu_array_sublayer values );
+static void trw_layer_gps_upload_any ( menu_array_sublayer values );
+
+static void trw_layer_centerize ( menu_array_layer values );
+static void trw_layer_auto_view ( menu_array_layer values );
+static void trw_layer_goto_wp ( menu_array_layer values );
+static void trw_layer_new_wp ( menu_array_layer values );
+static void trw_layer_new_track ( menu_array_layer values );
+static void trw_layer_new_route ( menu_array_layer values );
+static void trw_layer_finish_track ( menu_array_layer values );
+static void trw_layer_auto_waypoints_view ( menu_array_layer values );
+static void trw_layer_auto_tracks_view ( menu_array_layer values );
+static void trw_layer_delete_all_tracks ( menu_array_layer values );
+static void trw_layer_delete_tracks_from_selection ( menu_array_layer values );
+static void trw_layer_delete_all_waypoints ( menu_array_layer values );
+static void trw_layer_delete_waypoints_from_selection ( menu_array_layer values );
+static void trw_layer_new_wikipedia_wp_viewport ( menu_array_layer values );
+static void trw_layer_new_wikipedia_wp_layer ( menu_array_layer values );
#ifdef VIK_CONFIG_GEOTAG
-static void trw_layer_geotagging_waypoint_mtime_keep ( gpointer pass_along[6] );
-static void trw_layer_geotagging_waypoint_mtime_update ( gpointer pass_along[6] );
-static void trw_layer_geotagging_track ( 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] );
+static void trw_layer_geotagging_waypoint_mtime_keep ( menu_array_sublayer values );
+static void trw_layer_geotagging_waypoint_mtime_update ( menu_array_sublayer values );
+static void trw_layer_geotagging_track ( menu_array_sublayer values );
+static void trw_layer_geotagging ( menu_array_layer values );
#endif
+static void trw_layer_acquire_gps_cb ( menu_array_layer values );
+static void trw_layer_acquire_routing_cb ( menu_array_layer values );
+static void trw_layer_acquire_url_cb ( menu_array_layer values );
#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_acquire_osm_cb ( menu_array_layer values );
+static void trw_layer_acquire_osm_my_traces_cb ( menu_array_layer values );
#endif
#ifdef VIK_CONFIG_GEOCACHES
-static void trw_layer_acquire_geocache_cb ( gpointer lav[2] );
+static void trw_layer_acquire_geocache_cb ( menu_array_layer values );
#endif
#ifdef VIK_CONFIG_GEOTAG
-static void trw_layer_acquire_geotagged_cb ( gpointer lav[2] );
+static void trw_layer_acquire_geotagged_cb ( menu_array_layer values );
#endif
-static void trw_layer_acquire_file_cb ( gpointer lav[2] );
-static void trw_layer_gps_upload ( gpointer lav[2] );
+static void trw_layer_acquire_file_cb ( menu_array_layer values );
+static void trw_layer_gps_upload ( menu_array_layer values );
+
+static void trw_layer_track_list_dialog_single ( menu_array_sublayer values );
+static void trw_layer_track_list_dialog ( menu_array_layer values );
+static void trw_layer_waypoint_list_dialog ( menu_array_layer values );
// Specific route versions:
// Most track handling functions can handle operating on the route list
// However these ones are easier in separate functions
-static void trw_layer_auto_routes_view ( gpointer lav[2] );
-static void trw_layer_delete_all_routes ( gpointer lav[2] );
-static void trw_layer_delete_routes_from_selection ( gpointer lav[2] );
+static void trw_layer_auto_routes_view ( menu_array_layer values );
+static void trw_layer_delete_all_routes ( menu_array_layer values );
+static void trw_layer_delete_routes_from_selection ( menu_array_layer values );
/* pop-up items */
-static void trw_layer_properties_item ( gpointer pass_along[7] );
-static void trw_layer_goto_waypoint ( gpointer pass_along[6] );
-static void trw_layer_waypoint_gc_webpage ( gpointer pass_along[6] );
-static void trw_layer_waypoint_webpage ( gpointer pass_along[6] );
+static void trw_layer_properties_item ( gpointer pass_along[7] ); //TODO??
+static void trw_layer_goto_waypoint ( menu_array_sublayer values );
+static void trw_layer_waypoint_gc_webpage ( menu_array_sublayer values );
+static void trw_layer_waypoint_webpage ( menu_array_sublayer values );
static void trw_layer_realize_waypoint ( gpointer id, VikWaypoint *wp, gpointer pass_along[5] );
static void trw_layer_realize_track ( gpointer id, VikTrack *track, gpointer pass_along[5] );
-static void init_drawing_params ( struct DrawingParams *dp, VikTrwLayer *vtl, VikViewport *vp );
-static void trw_layer_insert_tp_after_current_tp ( VikTrwLayer *vtl );
+static void trw_layer_insert_tp_beside_current_tp ( VikTrwLayer *vtl, gboolean );
static void trw_layer_cancel_current_tp ( VikTrwLayer *vtl, gboolean destroy );
static void trw_layer_tpwin_response ( VikTrwLayer *vtl, gint response );
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 );
-static gpointer tool_route_finder_create ( VikWindow *vw, VikViewport *vvp);
-static gboolean tool_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
+static gpointer tool_extended_route_finder_create ( VikWindow *vw, VikViewport *vvp);
+static gboolean tool_extended_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
+static gboolean tool_extended_route_finder_key_press ( VikTrwLayer *vtl, GdkEventKey *event, VikViewport *vvp );
static void cached_pixbuf_free ( CachedPixbuf *cp );
static gint cached_pixbuf_cmp ( CachedPixbuf *cp, const gchar *name );
(VikToolConstructorFunc) tool_new_waypoint_create, NULL, NULL, NULL,
(VikToolMouseFunc) tool_new_waypoint_click, NULL, NULL, (VikToolKeyFunc) NULL,
FALSE,
- GDK_CURSOR_IS_PIXMAP, &cursor_addwp_pixbuf },
+ GDK_CURSOR_IS_PIXMAP, &cursor_addwp_pixbuf, NULL },
{ { "CreateTrack", "vik-icon-Create Track", N_("Create _Track"), "<control><shift>T", N_("Create Track"), 0 },
(VikToolConstructorFunc) tool_new_track_create, NULL, NULL, NULL,
(VikToolMouseFunc) tool_new_track_release,
(VikToolKeyFunc) tool_new_track_key_press,
TRUE, // Still need to handle clicks when in PAN mode to disable the potential trackpoint drawing
- GDK_CURSOR_IS_PIXMAP, &cursor_addtr_pixbuf },
+ GDK_CURSOR_IS_PIXMAP, &cursor_addtr_pixbuf, NULL },
{ { "CreateRoute", "vik-icon-Create Route", N_("Create _Route"), "<control><shift>B", N_("Create Route"), 0 },
(VikToolConstructorFunc) tool_new_route_create, NULL, NULL, NULL,
(VikToolMouseFunc) tool_new_track_release, // -> Reuse these track methods on a route
(VikToolKeyFunc) tool_new_track_key_press, // -/#
TRUE, // Still need to handle clicks when in PAN mode to disable the potential trackpoint drawing
- GDK_CURSOR_IS_PIXMAP, &cursor_new_route_pixbuf },
+ GDK_CURSOR_IS_PIXMAP, &cursor_new_route_pixbuf, NULL },
+
+ { { "ExtendedRouteFinder", "vik-icon-Route Finder", N_("Route _Finder"), "<control><shift>F", N_("Route Finder"), 0 },
+ (VikToolConstructorFunc) tool_extended_route_finder_create, NULL, NULL, NULL,
+ (VikToolMouseFunc) tool_extended_route_finder_click,
+ (VikToolMouseMoveFunc) tool_new_track_move, // -\#
+ (VikToolMouseFunc) tool_new_track_release, // -> Reuse these track methods on a route
+ (VikToolKeyFunc) tool_extended_route_finder_key_press,
+ TRUE, // Still need to handle clicks when in PAN mode to disable the potential trackpoint drawing
+ GDK_CURSOR_IS_PIXMAP, &cursor_route_finder_pixbuf, NULL },
{ { "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,
FALSE,
- GDK_CURSOR_IS_PIXMAP, &cursor_edwp_pixbuf },
+ GDK_CURSOR_IS_PIXMAP, &cursor_edwp_pixbuf, NULL },
{ { "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_edtr_pixbuf },
+ GDK_CURSOR_IS_PIXMAP, &cursor_edtr_pixbuf, NULL },
{ { "ShowPicture", "vik-icon-Show Picture", N_("Show P_icture"), "<control><shift>I", N_("Show Picture"), 0 },
(VikToolConstructorFunc) tool_show_picture_create, NULL, NULL, NULL,
(VikToolMouseFunc) tool_show_picture_click, NULL, NULL, (VikToolKeyFunc) NULL,
FALSE,
- GDK_CURSOR_IS_PIXMAP, &cursor_showpic_pixbuf },
+ GDK_CURSOR_IS_PIXMAP, &cursor_showpic_pixbuf, NULL },
- { { "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 },
};
enum {
TOOL_CREATE_WAYPOINT=0,
TOOL_CREATE_TRACK,
TOOL_CREATE_ROUTE,
+ TOOL_ROUTE_FINDER,
TOOL_EDIT_WAYPOINT,
TOOL_EDIT_TRACKPOINT,
TOOL_SHOW_PICTURE,
- TOOL_ROUTE_FINDER,
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"), N_("Metadata") };
+enum { GROUP_WAYPOINTS, GROUP_TRACKS, GROUP_IMAGES, GROUP_TRACKS_ADV, GROUP_METADATA };
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 };
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 sort_order_default ( void ) { return VIK_LPD_UINT ( 0 ); }
-VikLayerParam trw_layer_params[] = {
- { VIK_LAYER_TRW, "tracks_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL, NULL, vik_lpd_true_default },
- { VIK_LAYER_TRW, "waypoints_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL, NULL, vik_lpd_true_default },
- { VIK_LAYER_TRW, "routes_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL, NULL, vik_lpd_true_default },
+static VikLayerParamData string_default ( void )
+{
+ VikLayerParamData data;
+ data.s = "";
+ return data;
+}
- { VIK_LAYER_TRW, "drawmode", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track Drawing Mode:"), VIK_LAYER_WIDGET_COMBOBOX, params_drawmodes, NULL, NULL, drawmode_default },
+VikLayerParam trw_layer_params[] = {
+ { 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 },
- { 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 },
- { VIK_LAYER_TRW, "line_thickness", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track Thickness:"), VIK_LAYER_WIDGET_SPINBUTTON, ¶ms_scales[0], NULL, NULL, line_thickness_default },
- { 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 },
- { VIK_LAYER_TRW, "trkdirectionsize", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Direction Size:"), VIK_LAYER_WIDGET_SPINBUTTON, ¶ms_scales[11], NULL, NULL, trkdirectionsize_default },
- { VIK_LAYER_TRW, "drawpoints", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Trackpoints"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL, vik_lpd_true_default },
- { VIK_LAYER_TRW, "trkpointsize", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Trackpoint Size:"), VIK_LAYER_WIDGET_SPINBUTTON, ¶ms_scales[10], NULL, NULL, trkpointsize_default },
- { VIK_LAYER_TRW, "drawelevation", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Elevation"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL, vik_lpd_false_default },
- { VIK_LAYER_TRW, "elevation_factor", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Draw Elevation Height %:"), VIK_LAYER_WIDGET_HSCALE, ¶ms_scales[9], NULL, NULL, elevation_factor_default },
-
+ 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 },
- { VIK_LAYER_TRW, "stop_length", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Min Stop Length (seconds):"), VIK_LAYER_WIDGET_SPINBUTTON, ¶ms_scales[8], NULL, NULL, stop_length_default },
-
- { VIK_LAYER_TRW, "bg_line_thickness", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track BG Thickness:"), VIK_LAYER_WIDGET_SPINBUTTON, ¶ms_scales[6], NULL, NULL, bg_line_thickness_default },
- { VIK_LAYER_TRW, "trackbgcolor", VIK_LAYER_PARAM_COLOR, GROUP_TRACKS, N_("Track Background Color"), VIK_LAYER_WIDGET_COLOR, NULL, NULL, NULL, trackbgcolor_default },
- { VIK_LAYER_TRW, "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"), speed_factor_default },
-
- { VIK_LAYER_TRW, "tracksortorder", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track Sort Order:"), VIK_LAYER_WIDGET_COMBOBOX, params_sort_order, NULL, NULL, sort_order_default },
-
- // Waypoint Options:
- { VIK_LAYER_TRW, "drawlabels", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, N_("Draw Labels"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL, vik_lpd_true_default },
- { 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 },
- { VIK_LAYER_TRW, "wpcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Waypoint Color:"), VIK_LAYER_WIDGET_COLOR, NULL, NULL, NULL, black_color_default },
- { VIK_LAYER_TRW, "wptextcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Waypoint Text:"), VIK_LAYER_WIDGET_COLOR, NULL, NULL, NULL, wptextcolor_default },
- { VIK_LAYER_TRW, "wpbgcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Background:"), VIK_LAYER_WIDGET_COLOR, NULL, NULL, NULL, wpbgcolor_default },
- { 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 },
- { VIK_LAYER_TRW, "wpsymbol", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint marker:"), VIK_LAYER_WIDGET_COMBOBOX, params_wpsymbols, NULL, NULL, wpsymbol_default },
- { VIK_LAYER_TRW, "wpsize", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint size:"), VIK_LAYER_WIDGET_SPINBUTTON, ¶ms_scales[7], NULL, NULL, wpsize_default },
- { 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 },
- { 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 },
-
- { 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 },
- { 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 },
- { 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 },
- { 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 },
+ 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 },
+
+ { VIK_LAYER_TRW, "metadatadesc", VIK_LAYER_PARAM_STRING, GROUP_METADATA, N_("Description"), VIK_LAYER_WIDGET_ENTRY, NULL, NULL, NULL, string_default, NULL, NULL },
+ { VIK_LAYER_TRW, "metadataauthor", VIK_LAYER_PARAM_STRING, GROUP_METADATA, N_("Author"), VIK_LAYER_WIDGET_ENTRY, NULL, NULL, NULL, string_default, NULL, NULL },
+ { VIK_LAYER_TRW, "metadatatime", VIK_LAYER_PARAM_STRING, GROUP_METADATA, N_("Creation Time"), VIK_LAYER_WIDGET_ENTRY, NULL, NULL, NULL, string_default, NULL, NULL },
+ { VIK_LAYER_TRW, "metadatakeywords", VIK_LAYER_PARAM_STRING, GROUP_METADATA, N_("Keywords"), VIK_LAYER_WIDGET_ENTRY, NULL, NULL, NULL, string_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_IS,
PARAM_IA,
PARAM_ICS,
+ // Metadata
+ PARAM_MDDESC,
+ PARAM_MDAUTH,
+ PARAM_MDTIME,
+ PARAM_MDKEYS,
NUM_PARAMS
};
static VikTrwLayer *trw_layer_unmarshall ( guint8 *data, gint len, VikViewport *vvp );
static gboolean trw_layer_set_param ( VikTrwLayer *vtl, guint16 id, VikLayerParamData data, VikViewport *vp, gboolean is_file_operation );
static VikLayerParamData trw_layer_get_param ( VikTrwLayer *vtl, guint16 id, gboolean is_file_operation );
+static void trw_layer_change_param ( GtkWidget *widget, ui_change_values values );
static void trw_layer_del_item ( VikTrwLayer *vtl, gint subtype, gpointer sublayer );
static void trw_layer_cut_item ( VikTrwLayer *vtl, gint subtype, gpointer sublayer );
static void trw_layer_copy_item ( VikTrwLayer *vtl, gint subtype, gpointer sublayer, guint8 **item, guint *len );
(VikLayerFuncSetParam) trw_layer_set_param,
(VikLayerFuncGetParam) trw_layer_get_param,
+ (VikLayerFuncChangeParam) trw_layer_change_param,
(VikLayerFuncReadFileData) a_gpspoint_read_file,
(VikLayerFuncWriteFileData) a_gpspoint_write_file,
(VikLayerFuncSelectedViewportMenu) trw_layer_show_selected_viewport_menu,
};
+static gboolean have_diary_program = FALSE;
+
+// NB Only performed once per program run
+static void vik_trwlayer_class_init ( VikTrwLayerClass *klass )
+{
+ if ( g_find_program_in_path( "rednotebook" ) ) {
+ gchar *stdout = NULL;
+ gchar *stderr = NULL;
+ // Needs RedNotebook 1.7.3+ for support of opening on a specified date
+ if ( g_spawn_command_line_sync ( "rednotebook --version", &stdout, &stderr, NULL, NULL ) ) {
+ // Annoyingly 1.7.1|2|3 versions of RedNotebook prints the version to stderr!!
+ if ( stdout )
+ g_debug ("Diary: %s", stdout ); // Should be something like 'RedNotebook 1.4'
+ if ( stderr )
+ g_warning ("Diary: stderr: %s", stderr );
+
+ gchar **tokens = NULL;
+ if ( stdout && g_strcmp0(stdout, "") )
+ tokens = g_strsplit(stdout, " ", 0);
+ else if ( stderr )
+ tokens = g_strsplit(stderr, " ", 0);
+
+ gint num = 0;
+ gchar *token = tokens[num];
+ while ( token && num < 2 ) {
+ if (num == 1) {
+ if ( viking_version_to_number(token) >= viking_version_to_number("1.7.3") )
+ have_diary_program = TRUE;
+ }
+ num++;
+ token = tokens[num];
+ }
+ g_strfreev ( tokens );
+ }
+ g_free ( stdout );
+ g_free ( stderr );
+ }
+}
+
GType vik_trw_layer_get_type ()
{
static GType vtl_type = 0;
sizeof (VikTrwLayerClass),
NULL, /* base_init */
NULL, /* base_finalize */
- NULL, /* class init */
+ (GClassInitFunc) vik_trwlayer_class_init, /* class init */
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (VikTrwLayer),
};
vtl_type = g_type_register_static ( VIK_LAYER_TYPE, "VikTrwLayer", &vtl_info, 0 );
}
-
return vtl_type;
}
+VikTRWMetadata *vik_trw_metadata_new()
+{
+ return (VikTRWMetadata*)g_malloc0(sizeof(VikTRWMetadata));
+}
+
+void vik_trw_metadata_free ( VikTRWMetadata *metadata)
+{
+ g_free (metadata);
+}
+
+VikTRWMetadata *vik_trw_layer_get_metadata ( VikTrwLayer *vtl )
+{
+ return vtl->metadata;
+}
+
+void vik_trw_layer_set_metadata ( VikTrwLayer *vtl, VikTRWMetadata *metadata)
+{
+ if ( vtl->metadata )
+ vik_trw_metadata_free ( vtl->metadata );
+ vtl->metadata = metadata;
+}
+
+typedef struct {
+ gboolean found;
+ const gchar *date_str;
+ const VikTrack *trk;
+ const VikWaypoint *wpt;
+ gpointer *trk_id;
+ gpointer *wpt_id;
+} date_finder_type;
+
+static gboolean trw_layer_find_date_track ( const gpointer id, const VikTrack *trk, date_finder_type *df )
+{
+ gchar date_buf[20];
+ date_buf[0] = '\0';
+ // Might be an easier way to compare dates rather than converting the strings all the time...
+ if ( trk->trackpoints && VIK_TRACKPOINT(trk->trackpoints->data)->has_timestamp ) {
+ strftime (date_buf, sizeof(date_buf), "%Y-%m-%d", gmtime(&(VIK_TRACKPOINT(trk->trackpoints->data)->timestamp)));
+
+ if ( ! g_strcmp0 ( df->date_str, date_buf ) ) {
+ df->found = TRUE;
+ df->trk = trk;
+ df->trk_id = id;
+ }
+ }
+ return df->found;
+}
+
+static gboolean trw_layer_find_date_waypoint ( const gpointer id, const VikWaypoint *wpt, date_finder_type *df )
+{
+ gchar date_buf[20];
+ date_buf[0] = '\0';
+ // Might be an easier way to compare dates rather than converting the strings all the time...
+ if ( wpt->has_timestamp ) {
+ strftime (date_buf, sizeof(date_buf), "%Y-%m-%d", gmtime(&(wpt->timestamp)));
+
+ if ( ! g_strcmp0 ( df->date_str, date_buf ) ) {
+ df->found = TRUE;
+ df->wpt = wpt;
+ df->wpt_id = id;
+ }
+ }
+ return df->found;
+}
+
+/**
+ * Find an item by date
+ */
+gboolean vik_trw_layer_find_date ( VikTrwLayer *vtl, const gchar *date_str, VikCoord *position, VikViewport *vvp, gboolean do_tracks, gboolean select )
+{
+ date_finder_type df;
+ df.found = FALSE;
+ df.date_str = date_str;
+ df.trk = NULL;
+ df.wpt = NULL;
+ // Only tracks ATM
+ if ( do_tracks )
+ g_hash_table_find ( vtl->tracks, (GHRFunc) trw_layer_find_date_track, &df );
+ else
+ g_hash_table_find ( vtl->waypoints, (GHRFunc) trw_layer_find_date_waypoint, &df );
+
+ if ( select && df.found ) {
+ if ( do_tracks && df.trk ) {
+ struct LatLon maxmin[2] = { {0,0}, {0,0} };
+ trw_layer_find_maxmin_tracks ( NULL, df.trk, maxmin );
+ trw_layer_zoom_to_show_latlons ( vtl, vvp, maxmin );
+ vik_treeview_select_iter ( VIK_LAYER(vtl)->vt, g_hash_table_lookup (vtl->tracks_iters, df.trk_id), TRUE );
+ }
+ else if ( df.wpt ) {
+ vik_viewport_set_center_coord ( vvp, &(df.wpt->coord), TRUE );
+ vik_treeview_select_iter ( VIK_LAYER(vtl)->vt, g_hash_table_lookup (vtl->waypoints_iters, df.wpt_id), TRUE );
+ }
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+ }
+ return df.found;
+}
+
static void trw_layer_del_item ( VikTrwLayer *vtl, gint subtype, gpointer sublayer )
{
- static gpointer pass_along[6];
+ static menu_array_sublayer values;
if (!sublayer) {
return;
}
-
- pass_along[0] = vtl;
- pass_along[1] = NULL;
- pass_along[2] = GINT_TO_POINTER (subtype);
- pass_along[3] = sublayer;
- pass_along[4] = GINT_TO_POINTER (1); // Confirm delete request
- pass_along[5] = NULL;
- trw_layer_delete_item ( pass_along );
+ gint ii;
+ for ( ii = MA_VTL; ii < MA_LAST; ii++ )
+ values[ii] = NULL;
+
+ values[MA_VTL] = vtl;
+ values[MA_SUBTYPE] = GINT_TO_POINTER (subtype);
+ values[MA_SUBLAYER_ID] = sublayer;
+ values[MA_CONFIRM] = GINT_TO_POINTER (1); // Confirm delete request
+
+ trw_layer_delete_item ( values );
}
static void trw_layer_cut_item ( VikTrwLayer *vtl, gint subtype, gpointer sublayer )
{
- static gpointer pass_along[6];
+ static menu_array_sublayer values;
if (!sublayer) {
return;
}
- pass_along[0] = vtl;
- pass_along[1] = NULL;
- pass_along[2] = GINT_TO_POINTER (subtype);
- pass_along[3] = sublayer;
- pass_along[4] = GINT_TO_POINTER (0); // No delete confirmation needed for auto delete
- pass_along[5] = NULL;
+ gint ii;
+ for ( ii = MA_VTL; ii < MA_LAST; ii++ )
+ values[ii] = NULL;
- trw_layer_copy_item_cb(pass_along);
- trw_layer_cut_item_cb(pass_along);
+ values[MA_VTL] = vtl;
+ values[MA_SUBTYPE] = GINT_TO_POINTER (subtype);
+ values[MA_SUBLAYER_ID] = sublayer;
+ values[MA_CONFIRM] = GINT_TO_POINTER (1); // Confirm delete request
+
+ trw_layer_copy_item_cb(values);
+ trw_layer_cut_item_cb(values);
}
-static void trw_layer_copy_item_cb ( gpointer pass_along[6])
+static void trw_layer_copy_item_cb ( menu_array_sublayer values)
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
- gint subtype = GPOINTER_TO_INT (pass_along[2]);
- gpointer * sublayer = pass_along[3];
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+ gint subtype = GPOINTER_TO_INT (values[MA_SUBTYPE]);
+ gpointer * sublayer = values[MA_SUBLAYER_ID];
guint8 *data = NULL;
guint len;
}
}
-static void trw_layer_cut_item_cb ( gpointer pass_along[6])
+static void trw_layer_cut_item_cb ( menu_array_sublayer values)
{
- trw_layer_copy_item_cb(pass_along);
- pass_along[4] = GINT_TO_POINTER (0); // Never need to confirm automatic delete
- trw_layer_delete_item(pass_along);
+ trw_layer_copy_item_cb(values);
+ values[MA_CONFIRM] = GINT_TO_POINTER (0); // Never need to confirm automatic delete
+ trw_layer_delete_item(values);
}
-static void trw_layer_paste_item_cb ( gpointer pass_along[6])
+static void trw_layer_paste_item_cb ( menu_array_sublayer values)
{
// Slightly cheating method, routing via the panels capability
- a_clipboard_paste (VIK_LAYERS_PANEL(pass_along[1]));
+ a_clipboard_paste (VIK_LAYERS_PANEL(values[MA_VLP]));
}
static void trw_layer_copy_item ( VikTrwLayer *vtl, gint subtype, gpointer sublayer, guint8 **item, guint *len )
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 );
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;
}
break;
case PARAM_WPSO: if ( data.u < VL_SO_LAST ) vtl->wp_sort_order = data.u; break;
+ // Metadata
+ case PARAM_MDDESC: if ( data.s && vtl->metadata ) vtl->metadata->description = g_strdup (data.s); break;
+ case PARAM_MDAUTH: if ( data.s && vtl->metadata ) vtl->metadata->author = g_strdup (data.s); break;
+ case PARAM_MDTIME: if ( data.s && vtl->metadata ) vtl->metadata->timestamp = g_strdup (data.s); break;
+ case PARAM_MDKEYS: if ( data.s && vtl->metadata ) vtl->metadata->keywords = g_strdup (data.s); break;
+ default: 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_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;
+ // Metadata
+ case PARAM_MDDESC: if (vtl->metadata) { rv.s = vtl->metadata->description; } break;
+ case PARAM_MDAUTH: if (vtl->metadata) { rv.s = vtl->metadata->author; } break;
+ case PARAM_MDTIME: if (vtl->metadata) { rv.s = vtl->metadata->timestamp; } break;
+ case PARAM_MDKEYS: if (vtl->metadata) { rv.s = vtl->metadata->keywords; } break;
+ default: break;
}
return rv;
}
+static void trw_layer_change_param ( GtkWidget *widget, ui_change_values values )
+{
+ // This '-3' is to account for the first few parameters not in the properties
+ const gint OFFSET = -3;
+
+ switch ( GPOINTER_TO_INT(values[UI_CHG_PARAM_ID]) ) {
+ // Alter sensitivity of waypoint draw image related widgets according to the draw image setting.
+ case PARAM_DI: {
+ // Get new value
+ VikLayerParamData vlpd = a_uibuilder_widget_get_value ( widget, values[UI_CHG_PARAM] );
+ GtkWidget **ww1 = values[UI_CHG_WIDGETS];
+ GtkWidget **ww2 = values[UI_CHG_LABELS];
+ GtkWidget *w1 = ww1[OFFSET + PARAM_IS];
+ GtkWidget *w2 = ww2[OFFSET + PARAM_IS];
+ GtkWidget *w3 = ww1[OFFSET + PARAM_IA];
+ GtkWidget *w4 = ww2[OFFSET + PARAM_IA];
+ GtkWidget *w5 = ww1[OFFSET + PARAM_ICS];
+ GtkWidget *w6 = ww2[OFFSET + PARAM_ICS];
+ if ( w1 ) gtk_widget_set_sensitive ( w1, vlpd.b );
+ if ( w2 ) gtk_widget_set_sensitive ( w2, vlpd.b );
+ if ( w3 ) gtk_widget_set_sensitive ( w3, vlpd.b );
+ if ( w4 ) gtk_widget_set_sensitive ( w4, vlpd.b );
+ if ( w5 ) gtk_widget_set_sensitive ( w5, vlpd.b );
+ if ( w6 ) gtk_widget_set_sensitive ( w6, vlpd.b );
+ break;
+ }
+ // Alter sensitivity of waypoint label related widgets according to the draw label setting.
+ case PARAM_DLA: {
+ // Get new value
+ VikLayerParamData vlpd = a_uibuilder_widget_get_value ( widget, values[UI_CHG_PARAM] );
+ GtkWidget **ww1 = values[UI_CHG_WIDGETS];
+ GtkWidget **ww2 = values[UI_CHG_LABELS];
+ GtkWidget *w1 = ww1[OFFSET + PARAM_WPTC];
+ GtkWidget *w2 = ww2[OFFSET + PARAM_WPTC];
+ GtkWidget *w3 = ww1[OFFSET + PARAM_WPBC];
+ GtkWidget *w4 = ww2[OFFSET + PARAM_WPBC];
+ GtkWidget *w5 = ww1[OFFSET + PARAM_WPBA];
+ GtkWidget *w6 = ww2[OFFSET + PARAM_WPBA];
+ GtkWidget *w7 = ww1[OFFSET + PARAM_WPFONTSIZE];
+ GtkWidget *w8 = ww2[OFFSET + PARAM_WPFONTSIZE];
+ if ( w1 ) gtk_widget_set_sensitive ( w1, vlpd.b );
+ if ( w2 ) gtk_widget_set_sensitive ( w2, vlpd.b );
+ if ( w3 ) gtk_widget_set_sensitive ( w3, vlpd.b );
+ if ( w4 ) gtk_widget_set_sensitive ( w4, vlpd.b );
+ if ( w5 ) gtk_widget_set_sensitive ( w5, vlpd.b );
+ if ( w6 ) gtk_widget_set_sensitive ( w6, vlpd.b );
+ if ( w7 ) gtk_widget_set_sensitive ( w7, vlpd.b );
+ if ( w8 ) gtk_widget_set_sensitive ( w8, vlpd.b );
+ break;
+ }
+ // Alter sensitivity of all track colours according to the draw track mode.
+ case PARAM_DM: {
+ // Get new value
+ VikLayerParamData vlpd = a_uibuilder_widget_get_value ( widget, values[UI_CHG_PARAM] );
+ gboolean sensitive = ( vlpd.u == DRAWMODE_ALL_SAME_COLOR );
+ GtkWidget **ww1 = values[UI_CHG_WIDGETS];
+ GtkWidget **ww2 = values[UI_CHG_LABELS];
+ GtkWidget *w1 = ww1[OFFSET + PARAM_TC];
+ GtkWidget *w2 = ww2[OFFSET + PARAM_TC];
+ if ( w1 ) gtk_widget_set_sensitive ( w1, sensitive );
+ if ( w2 ) gtk_widget_set_sensitive ( w2, sensitive );
+ break;
+ }
+ case PARAM_MDTIME: {
+ // Force metadata->timestamp to be always read-only for now.
+ GtkWidget **ww = values[UI_CHG_WIDGETS];
+ GtkWidget *w1 = ww[OFFSET + PARAM_MDTIME];
+ if ( w1 ) gtk_widget_set_sensitive ( w1, FALSE );
+ }
+ // NB Since other track settings have been split across tabs,
+ // I don't think it's useful to set sensitivities on widgets you can't immediately see
+ default: break;
+ }
+}
+
static void trw_layer_marshall( VikTrwLayer *vtl, guint8 **data, gint *len )
{
guint8 *pd;
static VikTrwLayer *trw_layer_unmarshall( guint8 *data, gint len, VikViewport *vvp )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(vik_layer_create ( VIK_LAYER_TRW, vvp, NULL, FALSE ));
+ VikTrwLayer *vtl = VIK_TRW_LAYER(vik_layer_create ( VIK_LAYER_TRW, vvp, FALSE ));
gint pl;
gint consumed_length;
// 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->metadata = vik_trw_metadata_new ();
rv->draw_sync_done = TRUE;
rv->draw_sync_do = TRUE;
// Everything else is 0, FALSE or NULL
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 ) );
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 );
}
-static void init_drawing_params ( struct DrawingParams *dp, VikTrwLayer *vtl, VikViewport *vp )
+static void init_drawing_params ( struct DrawingParams *dp, VikTrwLayer *vtl, VikViewport *vp, gboolean highlight )
{
dp->vtl = vtl;
dp->vp = vp;
+ dp->highlight = highlight;
dp->vw = (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl);
dp->xmpp = vik_viewport_get_xmpp ( vp );
dp->ympp = vik_viewport_get_ympp ( vp );
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;
+
+ VikTrackpoint *tp_end = vik_track_get_tp_last ( trk );
+ if ( !tp_end )
+ return;
+ VikTrackpoint *tp_begin = vik_track_get_tp_first ( trk );
+ if ( !tp_begin )
+ return;
+ VikCoord begin_coord = tp_begin->coord;
+ VikCoord end_coord = tp_end->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 )
if ( track == dp->vtl->current_track )
main_gc = dp->vtl->current_track_gc;
else {
- if ( vik_viewport_get_draw_highlight ( dp->vp ) ) {
- /* Draw all tracks of the layer in special colour */
- /* if track is member of selected layer or is the current selected track
- then draw in the highlight colour.
- NB this supercedes the drawmode */
- if ( ( dp->vtl == vik_window_get_selected_trw_layer ( dp->vw ) ) ||
- ( !track->is_route && ( dp->vtl->tracks == vik_window_get_selected_tracks ( dp->vw ) ) ) ||
- ( track->is_route && ( dp->vtl->routes == vik_window_get_selected_tracks ( dp->vw ) ) ) ||
- ( track == vik_window_get_selected_track ( dp->vw ) ) ) {
- main_gc = vik_viewport_get_gc_highlight (dp->vp);
- drawing_highlight = TRUE;
- }
+ if ( dp->highlight ) {
+ /* Draw all tracks of the layer in special colour
+ NB this supercedes the drawmode */
+ main_gc = vik_viewport_get_gc_highlight (dp->vp);
+ drawing_highlight = TRUE;
}
if ( !drawing_highlight ) {
// Still need to figure out the gc according to the drawing mode:
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 );
+ }
+ }
}
}
if ( x+(w/2) > 0 && y+(h/2) > 0 && x-(w/2) < dp->width && y-(h/2) < dp->height ) /* always draw within boundaries */
{
- if ( vik_viewport_get_draw_highlight ( dp->vp ) ) {
- if ( dp->vtl == vik_window_get_selected_trw_layer ( dp->vw ) ||
- dp->vtl->waypoints == vik_window_get_selected_waypoints ( dp->vw ) ||
- wp == vik_window_get_selected_waypoint ( dp->vw ) ) {
- // Highlighted - so draw a little border around the chosen one
- // single line seems a little weak so draw 2 of them
- vik_viewport_draw_rectangle (dp->vp, vik_viewport_get_gc_highlight (dp->vp), FALSE,
- x - (w/2) - 1, y - (h/2) - 1, w + 2, h + 2 );
- vik_viewport_draw_rectangle (dp->vp, vik_viewport_get_gc_highlight (dp->vp), FALSE,
- x - (w/2) - 2, y - (h/2) - 2, w + 4, h + 4 );
- }
- }
+ if ( dp->highlight ) {
+ // Highlighted - so draw a little border around the chosen one
+ // single line seems a little weak so draw 2 of them
+ vik_viewport_draw_rectangle (dp->vp, vik_viewport_get_gc_highlight (dp->vp), FALSE,
+ x - (w/2) - 1, y - (h/2) - 1, w + 2, h + 2 );
+ vik_viewport_draw_rectangle (dp->vp, vik_viewport_get_gc_highlight (dp->vp), FALSE,
+ x - (w/2) - 2, y - (h/2) - 2, w + 4, h + 4 );
+ }
+
if ( dp->vtl->image_alpha == 255 )
vik_viewport_draw_pixbuf ( dp->vp, pixbuf, 0, 0, x - (w/2), y - (h/2), w, h );
else
case WP_SYMBOL_CIRCLE: vik_viewport_draw_arc ( dp->vp, dp->vtl->waypoint_gc, TRUE, x - dp->vtl->wp_size, y - dp->vtl->wp_size, dp->vtl->wp_size, dp->vtl->wp_size, 0, 360*64 ); break;
case WP_SYMBOL_X: vik_viewport_draw_line ( dp->vp, dp->vtl->waypoint_gc, x - dp->vtl->wp_size*2, y - dp->vtl->wp_size*2, x + dp->vtl->wp_size*2, y + dp->vtl->wp_size*2 );
vik_viewport_draw_line ( dp->vp, dp->vtl->waypoint_gc, x - dp->vtl->wp_size*2, y + dp->vtl->wp_size*2, x + dp->vtl->wp_size*2, y - dp->vtl->wp_size*2 );
+ default: break;
}
}
else {
case WP_SYMBOL_CIRCLE: vik_viewport_draw_arc ( dp->vp, dp->vtl->waypoint_gc, TRUE, x-dp->vtl->wp_size/2, y-dp->vtl->wp_size/2, dp->vtl->wp_size, dp->vtl->wp_size, 0, 360*64 ); break;
case WP_SYMBOL_X: vik_viewport_draw_line ( dp->vp, dp->vtl->waypoint_gc, x-dp->vtl->wp_size, y-dp->vtl->wp_size, x+dp->vtl->wp_size, y+dp->vtl->wp_size );
vik_viewport_draw_line ( dp->vp, dp->vtl->waypoint_gc, x-dp->vtl->wp_size, y+dp->vtl->wp_size, x+dp->vtl->wp_size, y-dp->vtl->wp_size ); break;
+ default: break;
}
}
label_y = y - dp->vtl->wp_size - height - 2;
/* if highlight mode on, then draw background text in highlight colour */
- if ( vik_viewport_get_draw_highlight ( dp->vp ) ) {
- if ( dp->vtl == vik_window_get_selected_trw_layer ( dp->vw ) ||
- dp->vtl->waypoints == vik_window_get_selected_waypoints ( dp->vw ) ||
- wp == vik_window_get_selected_waypoint ( dp->vw ) )
- vik_viewport_draw_rectangle ( dp->vp, vik_viewport_get_gc_highlight (dp->vp), TRUE, label_x - 1, label_y-1,width+2,height+2);
- else
- vik_viewport_draw_rectangle ( dp->vp, dp->vtl->waypoint_bg_gc, TRUE, label_x - 1, label_y-1,width+2,height+2);
- }
- else {
- vik_viewport_draw_rectangle ( dp->vp, dp->vtl->waypoint_bg_gc, TRUE, label_x - 1, label_y-1,width+2,height+2);
- }
+ if ( dp->highlight )
+ vik_viewport_draw_rectangle ( dp->vp, vik_viewport_get_gc_highlight (dp->vp), TRUE, label_x - 1, label_y-1,width+2,height+2);
+ else
+ vik_viewport_draw_rectangle ( dp->vp, dp->vtl->waypoint_bg_gc, TRUE, label_x - 1, label_y-1,width+2,height+2);
vik_viewport_draw_layout ( dp->vp, dp->vtl->waypoint_text_gc, label_x, label_y, dp->vtl->wplabellayout );
}
}
}
}
-static void trw_layer_draw ( VikTrwLayer *l, gpointer data )
+static void trw_layer_draw_with_highlight ( VikTrwLayer *l, gpointer data, gboolean highlight )
{
static struct DrawingParams dp;
g_assert ( l != NULL );
- init_drawing_params ( &dp, l, VIK_VIEWPORT(data) );
+ init_drawing_params ( &dp, l, VIK_VIEWPORT(data), highlight );
if ( l->tracks_visible )
g_hash_table_foreach ( l->tracks, (GHFunc) trw_layer_draw_track_cb, &dp );
g_hash_table_foreach ( l->waypoints, (GHFunc) trw_layer_draw_waypoint_cb, &dp );
}
+static void trw_layer_draw ( VikTrwLayer *l, gpointer data )
+{
+ // If this layer is to be highlighted - then don't draw now - as it will be drawn later on in the specific highlight draw stage
+ // This may seem slightly inefficient to test each time for every layer
+ // but for a layer with *lots* of tracks & waypoints this can save some effort by not drawing the items twice
+ if ( vik_viewport_get_draw_highlight ( (VikViewport*)data ) &&
+ vik_window_get_selected_trw_layer ((VikWindow*)VIK_GTK_WINDOW_FROM_LAYER((VikLayer*)l)) == l )
+ return;
+ trw_layer_draw_with_highlight ( l, data, FALSE );
+}
+
+void vik_trw_layer_draw_highlight ( VikTrwLayer *vtl, VikViewport *vvp )
+{
+ // Check the layer for visibility (including all the parents visibilities)
+ if ( !vik_treeview_item_get_visible_tree (VIK_LAYER(vtl)->vt, &(VIK_LAYER(vtl)->iter)) )
+ return;
+ trw_layer_draw_with_highlight ( vtl, vvp, TRUE );
+}
+
+/**
+ * vik_trw_layer_draw_highlight_item:
+ *
+ * Only handles a single track or waypoint ATM
+ * It assumes the track or waypoint belongs to the TRW Layer (it doesn't check this is the case)
+ */
+void vik_trw_layer_draw_highlight_item ( VikTrwLayer *vtl, VikTrack *trk, VikWaypoint *wpt, VikViewport *vvp )
+{
+ // Check the layer for visibility (including all the parents visibilities)
+ if ( !vik_treeview_item_get_visible_tree (VIK_LAYER(vtl)->vt, &(VIK_LAYER(vtl)->iter)) )
+ return;
+
+ static struct DrawingParams dp;
+ init_drawing_params ( &dp, vtl, vvp, TRUE );
+
+ if ( trk ) {
+ gboolean draw = ( trk->is_route && vtl->routes_visible ) || ( !trk->is_route && vtl->tracks_visible );
+ if ( draw )
+ trw_layer_draw_track_cb ( NULL, trk, &dp );
+ }
+ if ( vtl->waypoints_visible && wpt ) {
+ trw_layer_draw_waypoint_cb ( NULL, wpt, &dp );
+ }
+}
+
+/**
+ * vik_trw_layer_draw_highlight_item:
+ *
+ * Generally for drawing all tracks or routes or waypoints
+ * trks may be actually routes
+ * It assumes they belong to the TRW Layer (it doesn't check this is the case)
+ */
+void vik_trw_layer_draw_highlight_items ( VikTrwLayer *vtl, GHashTable *trks, GHashTable *wpts, VikViewport *vvp )
+{
+ // Check the layer for visibility (including all the parents visibilities)
+ if ( !vik_treeview_item_get_visible_tree (VIK_LAYER(vtl)->vt, &(VIK_LAYER(vtl)->iter)) )
+ return;
+
+ static struct DrawingParams dp;
+ init_drawing_params ( &dp, vtl, vvp, TRUE );
+
+ if ( trks ) {
+ gboolean is_routes = (trks == vtl->routes);
+ gboolean draw = ( is_routes && vtl->routes_visible ) || ( !is_routes && vtl->tracks_visible );
+ if ( draw )
+ g_hash_table_foreach ( trks, (GHFunc) trw_layer_draw_track_cb, &dp );
+ }
+
+ if ( vtl->waypoints_visible && wpts )
+ g_hash_table_foreach ( wpts, (GHFunc) trw_layer_draw_waypoint_cb, &dp );
+}
+
static void trw_layer_free_track_gcs ( VikTrwLayer *vtl )
{
int i;
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);
+ 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_from_color ( vp, &(rv->waypoint_color), 2 );
/*
* Can accept a null symbol, and may return null value
*/
-static GdkPixbuf* get_wp_sym_small ( gchar *symbol )
+GdkPixbuf* get_wp_sym_small ( gchar *symbol )
{
GdkPixbuf* wp_icon = a_get_wp_sym (symbol);
// ATM a_get_wp_sym returns a cached icon, with the size dependent on the preferences.
if ( g_hash_table_size (vtl->tracks) > 0 ) {
trw_layer_add_sublayer_tracks ( vtl, vt , layer_iter );
- pass_along[5] = GINT_TO_POINTER(g_hash_table_size (vtl->tracks));
+
g_hash_table_foreach ( vtl->tracks, (GHFunc) trw_layer_realize_track, pass_along );
vik_treeview_item_set_visible ( vt, &(vtl->tracks_iter), vtl->tracks_visible );
else
return TRUE;
}
+ default: break;
}
return TRUE;
}
tt->length = tt->length + vik_track_get_length (tr);
// Ensure times are available
- if ( tr->trackpoints &&
- VIK_TRACKPOINT(tr->trackpoints->data)->has_timestamp &&
- VIK_TRACKPOINT(g_list_last(tr->trackpoints)->data)->has_timestamp ) {
-
- time_t t1, t2;
- t1 = VIK_TRACKPOINT(tr->trackpoints->data)->timestamp;
- t2 = VIK_TRACKPOINT(g_list_last(tr->trackpoints)->data)->timestamp;
+ if ( tr->trackpoints && vik_track_get_tp_first(tr)->has_timestamp ) {
+ // Get trkpt only once - as using vik_track_get_tp_last() iterates whole track each time
+ VikTrackpoint *trkpt_last = vik_track_get_tp_last(tr);
+ if ( trkpt_last->has_timestamp ) {
+ time_t t1, t2;
+ t1 = vik_track_get_tp_first(tr)->timestamp;
+ t2 = trkpt_last->timestamp;
- // Assume never actually have a track with a time of 0 (1st Jan 1970)
- // Hence initialize to the first 'proper' value
- if ( tt->start_time == 0 )
- tt->start_time = t1;
- if ( tt->end_time == 0 )
- tt->end_time = t2;
+ // Assume never actually have a track with a time of 0 (1st Jan 1970)
+ // Hence initialize to the first 'proper' value
+ if ( tt->start_time == 0 )
+ tt->start_time = t1;
+ if ( tt->end_time == 0 )
+ tt->end_time = t2;
- // Update find the earliest / last times
- if ( t1 < tt->start_time )
- tt->start_time = t1;
- if ( t2 > tt->end_time )
- tt->end_time = t2;
+ // Update find the earliest / last times
+ if ( t1 < tt->start_time )
+ tt->start_time = t1;
+ if ( t2 > tt->end_time )
+ tt->end_time = t2;
- // Keep track of total time
- // there maybe gaps within a track (eg segments)
- // but this should be generally good enough for a simple indicator
- tt->duration = tt->duration + (int)(t2-t1);
+ // Keep track of total time
+ // there maybe gaps within a track (eg segments)
+ // but this should be generally good enough for a simple indicator
+ tt->duration = tt->duration + (int)(t2-t1);
+ }
}
}
// Safety check - I think these should always be valid
if ( vtl->tracks && vtl->waypoints ) {
- tooltip_tracks tt = { 0.0, 0, 0 };
+ tooltip_tracks tt = { 0.0, 0, 0, 0 };
g_hash_table_foreach ( vtl->tracks, (GHFunc) trw_layer_tracks_tooltip, &tt );
GDate* gdate_start = g_date_new ();
static gchar tmp_buf[100];
// Compact info: Short date eg (11/20/99), duration and length
// Hopefully these are the things that are most useful and so promoted into the tooltip
- if ( tr->trackpoints && VIK_TRACKPOINT(tr->trackpoints->data)->has_timestamp ) {
+ if ( tr->trackpoints && vik_track_get_tp_first(tr)->has_timestamp ) {
// %x The preferred date representation for the current locale without the time.
- strftime (time_buf1, sizeof(time_buf1), "%x: ", gmtime(&(VIK_TRACKPOINT(tr->trackpoints->data)->timestamp)));
- if ( VIK_TRACKPOINT(g_list_last(tr->trackpoints)->data)->has_timestamp ) {
- gint dur = ( (VIK_TRACKPOINT(g_list_last(tr->trackpoints)->data)->timestamp) - (VIK_TRACKPOINT(tr->trackpoints->data)->timestamp) );
+ strftime (time_buf1, sizeof(time_buf1), "%x: ", gmtime(&(vik_track_get_tp_first(tr)->timestamp)));
+ VikTrackpoint *trkpt = vik_track_get_tp_last(tr);
+ if ( trkpt->has_timestamp ) {
+ gint dur = ( trkpt->timestamp - (vik_track_get_tp_first(tr)->timestamp) );
if ( dur > 0 )
g_snprintf ( time_buf2, sizeof(time_buf2), _("- %d:%02d hrs:mins"), (int)round(dur/3600), (int)round((dur/60)%60) );
}
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 ( "KEATDN" );
+ 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 )
+GHashTable *vik_trw_layer_get_tracks_iters ( VikTrwLayer *vtl )
{
- return ! ( g_hash_table_size ( vtl->tracks ) ||
- g_hash_table_size ( vtl->routes ) ||
+ return vtl->tracks_iters;
+}
+
+GHashTable *vik_trw_layer_get_routes_iters ( VikTrwLayer *vtl )
+{
+ return vtl->routes_iters;
+}
+
+GHashTable *vik_trw_layer_get_waypoints_iters ( VikTrwLayer *vtl )
+{
+ return vtl->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 );
}
}
}
-static void trw_layer_centerize ( gpointer layer_and_vlp[2] )
+static void trw_layer_centerize ( menu_array_layer values )
{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
VikCoord coord;
- if ( vik_trw_layer_find_center ( VIK_TRW_LAYER(layer_and_vlp[0]), &coord ) )
- goto_coord ( layer_and_vlp[1], NULL, NULL, &coord );
+ if ( vik_trw_layer_find_center ( vtl, &coord ) )
+ goto_coord ( values[MA_VLP], NULL, NULL, &coord );
else
- a_dialog_info_msg ( VIK_GTK_WINDOW_FROM_LAYER(layer_and_vlp[0]), _("This layer has no waypoints or trackpoints.") );
+ a_dialog_info_msg ( VIK_GTK_WINDOW_FROM_LAYER(vtl), _("This layer has no waypoints or trackpoints.") );
}
-static void trw_layer_zoom_to_show_latlons ( VikTrwLayer *vtl, VikViewport *vvp, struct LatLon maxmin[2] )
+void trw_layer_zoom_to_show_latlons ( VikTrwLayer *vtl, VikViewport *vvp, struct LatLon maxmin[2] )
{
/* First set the center [in case previously viewing from elsewhere] */
/* Then loop through zoom levels until provided positions are in view */
struct LatLon average = { (maxmin[0].lat+maxmin[1].lat)/2, (maxmin[0].lon+maxmin[1].lon)/2 };
VikCoord coord;
vik_coord_load_from_latlon ( &coord, vtl->coord_mode, &average );
- vik_viewport_set_center_coord ( vvp, &coord );
+ vik_viewport_set_center_coord ( vvp, &coord, TRUE );
/* Convert into definite 'smallest' and 'largest' positions */
struct LatLon minmin;
}
}
-static void trw_layer_auto_view ( gpointer layer_and_vlp[2] )
+static void trw_layer_auto_view ( menu_array_layer values )
{
- if ( vik_trw_layer_auto_set_view ( VIK_TRW_LAYER(layer_and_vlp[0]), vik_layers_panel_get_viewport (VIK_LAYERS_PANEL(layer_and_vlp[1])) ) ) {
- vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(layer_and_vlp[1]) );
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+ VikLayersPanel *vlp = VIK_LAYERS_PANEL(values[MA_VLP]);
+ if ( vik_trw_layer_auto_set_view ( vtl, vik_layers_panel_get_viewport (vlp) ) ) {
+ vik_layers_panel_emit_update ( vlp );
}
else
- a_dialog_info_msg ( VIK_GTK_WINDOW_FROM_LAYER(layer_and_vlp[0]), _("This layer has no waypoints or trackpoints.") );
+ a_dialog_info_msg ( VIK_GTK_WINDOW_FROM_LAYER(vtl), _("This layer has no waypoints or trackpoints.") );
}
-static void trw_layer_export ( gpointer layer_and_vlp[2], const gchar *title, const gchar* default_name, VikTrack* trk, guint file_type )
+static void trw_layer_export_gpspoint ( menu_array_layer values )
{
- GtkWidget *file_selector;
- const gchar *fn;
- gboolean failed = FALSE;
- file_selector = gtk_file_chooser_dialog_new (title,
- NULL,
- GTK_FILE_CHOOSER_ACTION_SAVE,
- 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 );
- }
+ gchar *auto_save_name = append_file_ext ( vik_layer_get_name(VIK_LAYER(values[MA_VTL])), FILE_TYPE_GPSPOINT );
- gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER(file_selector), default_name);
+ vik_trw_layer_export ( VIK_TRW_LAYER (values[MA_VTL]), _("Export Layer"), auto_save_name, NULL, FILE_TYPE_GPSPOINT );
- while ( gtk_dialog_run ( GTK_DIALOG(file_selector) ) == GTK_RESPONSE_ACCEPT )
- {
- fn = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(file_selector) );
- 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;
- }
- }
- }
- gtk_widget_destroy ( file_selector );
- if ( failed )
- a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_LAYER(layer_and_vlp[0]), _("The filename you requested could not be opened for writing.") );
+ g_free ( auto_save_name );
}
-static void trw_layer_export_gpspoint ( gpointer layer_and_vlp[2] )
+static void trw_layer_export_gpsmapper ( menu_array_layer values )
{
- trw_layer_export ( layer_and_vlp, _("Export Layer"), vik_layer_get_name(VIK_LAYER(layer_and_vlp[0])), NULL, FILE_TYPE_GPSPOINT );
-}
+ gchar *auto_save_name = append_file_ext ( vik_layer_get_name(VIK_LAYER(values[MA_VTL])), FILE_TYPE_GPSMAPPER );
-static void trw_layer_export_gpsmapper ( gpointer layer_and_vlp[2] )
-{
- trw_layer_export ( layer_and_vlp, _("Export Layer"), vik_layer_get_name(VIK_LAYER(layer_and_vlp[0])), NULL, FILE_TYPE_GPSMAPPER );
+ vik_trw_layer_export ( VIK_TRW_LAYER (values[MA_VTL]), _("Export Layer"), auto_save_name, NULL, FILE_TYPE_GPSMAPPER );
+
+ g_free ( auto_save_name );
}
-static void trw_layer_export_gpx ( gpointer layer_and_vlp[2] )
+static void trw_layer_export_gpx ( menu_array_layer values )
{
- /* Auto append '.gpx' to track name (providing it's not already there) for the default filename */
- gchar *auto_save_name = g_strdup ( vik_layer_get_name(VIK_LAYER(layer_and_vlp[0])) );
- if ( ! check_file_ext ( auto_save_name, ".gpx" ) )
- auto_save_name = g_strconcat ( auto_save_name, ".gpx", NULL );
+ gchar *auto_save_name = append_file_ext ( vik_layer_get_name(VIK_LAYER(values[MA_VTL])), FILE_TYPE_GPX );
- trw_layer_export ( layer_and_vlp, _("Export Layer"), auto_save_name, NULL, FILE_TYPE_GPX );
+ vik_trw_layer_export ( VIK_TRW_LAYER (values[MA_VTL]), _("Export Layer"), auto_save_name, NULL, FILE_TYPE_GPX );
g_free ( auto_save_name );
}
-static void trw_layer_export_kml ( gpointer layer_and_vlp[2] )
+static void trw_layer_export_kml ( menu_array_layer values )
{
- /* Auto append '.kml' to the name (providing it's not already there) for the default filename */
- gchar *auto_save_name = g_strdup ( vik_layer_get_name(VIK_LAYER(layer_and_vlp[0])) );
- if ( ! check_file_ext ( auto_save_name, ".kml" ) )
- auto_save_name = g_strconcat ( auto_save_name, ".kml", NULL );
+ gchar *auto_save_name = append_file_ext ( vik_layer_get_name(VIK_LAYER(values[MA_VTL])), FILE_TYPE_KML );
- trw_layer_export ( layer_and_vlp, _("Export Layer"), auto_save_name, NULL, FILE_TYPE_KML );
+ vik_trw_layer_export ( VIK_TRW_LAYER (values[MA_VTL]), _("Export Layer"), auto_save_name, NULL, FILE_TYPE_KML );
g_free ( auto_save_name );
}
-/**
- * Convert the given TRW layer into a temporary GPX file and open it with the specified program
- *
- */
-static void trw_layer_export_external_gpx ( gpointer layer_and_vlp[2], const gchar* external_program )
+static void trw_layer_export_babel ( gpointer layer_and_vlp[2] )
{
- gchar *name_used = NULL;
- 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.") );
- }
- else {
- GError *err = NULL;
- gchar *quoted_file = g_shell_quote ( name_used );
- gchar *cmd = g_strdup_printf ( "%s %s", external_program, quoted_file );
- g_free ( quoted_file );
- if ( ! g_spawn_command_line_async ( cmd, &err ) )
- {
- a_dialog_error_msg_extra ( VIK_GTK_WINDOW_FROM_LAYER( layer_and_vlp[0]), _("Could not launch %s."), external_program );
- g_error_free ( err );
- }
- g_free ( cmd );
- }
- // Note ATM the 'temporary' file is not deleted, as loading via another program is not instantaneous
- //g_remove ( name_used );
- // Perhaps should be deleted when the program ends?
- // For now leave it to the user to delete it / use system temp cleanup methods.
- g_free ( name_used );
- }
+ const gchar *auto_save_name = vik_layer_get_name(VIK_LAYER(layer_and_vlp[0]));
+ vik_trw_layer_export_gpsbabel ( VIK_TRW_LAYER (layer_and_vlp[0]), _("Export Layer"), auto_save_name );
}
-static void trw_layer_export_external_gpx_1 ( gpointer layer_and_vlp[2] )
+static void trw_layer_export_external_gpx_1 ( menu_array_layer values )
{
- trw_layer_export_external_gpx ( layer_and_vlp, a_vik_get_external_gpx_program_1() );
+ vik_trw_layer_export_external_gpx ( VIK_TRW_LAYER (values[MA_VTL]), a_vik_get_external_gpx_program_1() );
}
-static void trw_layer_export_external_gpx_2 ( gpointer layer_and_vlp[2] )
+static void trw_layer_export_external_gpx_2 ( menu_array_layer values )
{
- trw_layer_export_external_gpx ( layer_and_vlp, a_vik_get_external_gpx_program_2() );
+ vik_trw_layer_export_external_gpx ( VIK_TRW_LAYER (values[MA_VTL]), a_vik_get_external_gpx_program_2() );
}
-static void trw_layer_export_gpx_track ( gpointer pass_along[6] )
+static void trw_layer_export_gpx_track ( menu_array_sublayer values )
{
- gpointer layer_and_vlp[2];
- layer_and_vlp[0] = pass_along[0];
- layer_and_vlp[1] = pass_along[1];
-
- VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
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] );
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ trk = (VikTrack *) g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
else
- trk = (VikTrack *) g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+ trk = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
if ( !trk || !trk->name )
return;
- /* Auto append '.gpx' to track name (providing it's not already there) for the default filename */
- gchar *auto_save_name = g_strdup ( trk->name );
- if ( ! check_file_ext ( auto_save_name, ".gpx" ) )
- auto_save_name = g_strconcat ( auto_save_name, ".gpx", NULL );
+ gchar *auto_save_name = append_file_ext ( trk->name, FILE_TYPE_GPX );
- trw_layer_export ( layer_and_vlp, _("Export Track as GPX"), auto_save_name, trk, FILE_TYPE_GPX );
+ gchar *label = NULL;
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ label = _("Export Route as GPX");
+ else
+ label = _("Export Track as GPX");
+ vik_trw_layer_export ( VIK_TRW_LAYER (values[MA_VTL]), label, auto_save_name, trk, FILE_TYPE_GPX );
g_free ( auto_save_name );
}
-typedef struct {
- VikWaypoint *wp; // input
- gpointer uuid; // output
-} wpu_udata;
-
-static gboolean trw_layer_waypoint_find_uuid ( const gpointer id, const VikWaypoint *wp, gpointer udata )
+gboolean trw_layer_waypoint_find_uuid ( const gpointer id, const VikWaypoint *wp, gpointer udata )
{
wpu_udata *user_data = udata;
if ( wp == user_data->wp ) {
return FALSE;
}
-static void trw_layer_goto_wp ( gpointer layer_and_vlp[2] )
+static void trw_layer_goto_wp ( menu_array_layer values )
{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+ VikLayersPanel *vlp = VIK_LAYERS_PANEL(values[MA_VLP]);
GtkWidget *dia = gtk_dialog_new_with_buttons (_("Find"),
- VIK_GTK_WINDOW_FROM_LAYER(layer_and_vlp[0]),
+ VIK_GTK_WINDOW_FROM_LAYER(vtl),
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_STOCK_CANCEL,
GTK_RESPONSE_REJECT,
{
gchar *name = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
// Find *first* wp with the given name
- VikWaypoint *wp = vik_trw_layer_get_waypoint ( VIK_TRW_LAYER(layer_and_vlp[0]), name );
+ VikWaypoint *wp = vik_trw_layer_get_waypoint ( vtl, name );
if ( !wp )
- a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_LAYER(layer_and_vlp[0]), _("Waypoint not found in this layer.") );
+ a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_LAYER(vtl), _("Waypoint not found in this layer.") );
else
{
- vik_viewport_set_center_coord ( vik_layers_panel_get_viewport(VIK_LAYERS_PANEL(layer_and_vlp[1])), &(wp->coord) );
- vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(layer_and_vlp[1]) );
+ vik_viewport_set_center_coord ( vik_layers_panel_get_viewport(vlp), &(wp->coord), TRUE );
+ vik_layers_panel_emit_update ( vlp );
// Find and select on the side panel
wpu_udata udata;
udata.uuid = NULL;
// Hmmm, want key of it
- gpointer *wpf = g_hash_table_find ( VIK_TRW_LAYER(layer_and_vlp[0])->waypoints, (GHRFunc) trw_layer_waypoint_find_uuid, (gpointer) &udata );
+ gpointer *wpf = g_hash_table_find ( vtl->waypoints, (GHRFunc) trw_layer_waypoint_find_uuid, (gpointer) &udata );
if ( wpf && udata.uuid ) {
- GtkTreeIter *it = g_hash_table_lookup ( VIK_TRW_LAYER(layer_and_vlp[0])->waypoints_iters, udata.uuid );
- vik_treeview_select_iter ( VIK_LAYER(layer_and_vlp[0])->vt, it, TRUE );
+ GtkTreeIter *it = g_hash_table_lookup ( vtl->waypoints_iters, udata.uuid );
+ vik_treeview_select_iter ( VIK_LAYER(vtl)->vt, it, TRUE );
}
break;
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, vtl, wp, vtl->coord_mode, TRUE, &updated );
return FALSE;
}
-static void trw_layer_new_wikipedia_wp_viewport ( gpointer lav[2] )
+static void trw_layer_new_wikipedia_wp_viewport ( menu_array_layer values )
{
struct LatLon maxmin[2] = { {0.0,0.0}, {0.0,0.0} };
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
- VikLayersPanel *vlp = VIK_LAYERS_PANEL(lav[1]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+ VikLayersPanel *vlp = VIK_LAYERS_PANEL(values[MA_VLP]);
VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl));
VikViewport *vvp = vik_window_viewport(vw);
vik_layers_panel_emit_update ( vlp );
}
-static void trw_layer_new_wikipedia_wp_layer ( gpointer lav[2] )
+static void trw_layer_new_wikipedia_wp_layer ( menu_array_layer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
- VikLayersPanel *vlp = VIK_LAYERS_PANEL(lav[1]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+ VikLayersPanel *vlp = VIK_LAYERS_PANEL(values[MA_VLP]);
struct LatLon maxmin[2] = { {0.0,0.0}, {0.0,0.0} };
trw_layer_find_maxmin (vtl, maxmin);
}
#ifdef VIK_CONFIG_GEOTAG
-static void trw_layer_geotagging_waypoint_mtime_keep ( gpointer pass_along[6] )
+static void trw_layer_geotagging_waypoint_mtime_keep ( menu_array_sublayer values )
{
- VikWaypoint *wp = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->waypoints, pass_along[3] );
+ VikWaypoint *wp = g_hash_table_lookup ( VIK_TRW_LAYER(values[MA_VTL])->waypoints, values[MA_SUBLAYER_ID] );
if ( wp )
// Update directly - not changing the mtime
a_geotag_write_exif_gps ( wp->image, wp->coord, wp->altitude, TRUE );
}
-static void trw_layer_geotagging_waypoint_mtime_update ( gpointer pass_along[6] )
+static void trw_layer_geotagging_waypoint_mtime_update ( menu_array_sublayer values )
{
- VikWaypoint *wp = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->waypoints, pass_along[3] );
+ VikWaypoint *wp = g_hash_table_lookup ( VIK_TRW_LAYER(values[MA_VTL])->waypoints, values[MA_SUBLAYER_ID] );
if ( wp )
// Update directly
a_geotag_write_exif_gps ( wp->image, wp->coord, wp->altitude, FALSE );
/*
* Use code in separate file for this feature as reasonably complex
*/
-static void trw_layer_geotagging_track ( gpointer pass_along[6] )
+static void trw_layer_geotagging_track ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
- VikTrack *track = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->tracks, pass_along[3] );
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+ VikTrack *track = g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
// Unset so can be reverified later if necessary
vtl->has_verified_thumbnails = FALSE;
trw_layer_geotag_dialog ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
- vtl,
- track,
- track->name );
+ vtl,
+ NULL,
+ track );
+}
+
+static void trw_layer_geotagging_waypoint ( menu_array_sublayer values )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+ VikWaypoint *wpt = g_hash_table_lookup ( vtl->waypoints, values[MA_SUBLAYER_ID] );
+
+ trw_layer_geotag_dialog ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
+ vtl,
+ wpt,
+ NULL );
}
-static void trw_layer_geotagging ( gpointer lav[2] )
+static void trw_layer_geotagging ( menu_array_layer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
// Unset so can be reverified later if necessary
vtl->has_verified_thumbnails = FALSE;
trw_layer_geotag_dialog ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
- vtl,
- NULL,
- NULL);
+ vtl,
+ NULL,
+ NULL );
}
#endif
// 'Acquires' - Same as in File Menu -> Acquire - applies into the selected TRW Layer //
-/*
- * Acquire into this TRW Layer straight from GPS Device
- */
-static void trw_layer_acquire_gps_cb ( gpointer lav[2] )
+static void trw_layer_acquire ( menu_array_layer values, VikDataSourceInterface *datasource )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
- VikLayersPanel *vlp = VIK_LAYERS_PANEL(lav[1]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+ VikLayersPanel *vlp = VIK_LAYERS_PANEL(values[MA_VLP]);
VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl));
VikViewport *vvp = vik_window_viewport(vw);
+ a_acquire ( vw, vlp, vvp, datasource, NULL, NULL );
+}
+
+/*
+ * Acquire into this TRW Layer straight from GPS Device
+ */
+static void trw_layer_acquire_gps_cb ( menu_array_layer values )
+{
vik_datasource_gps_interface.mode = VIK_DATASOURCE_ADDTOLAYER;
- a_acquire ( vw, vlp, vvp, &vik_datasource_gps_interface, NULL, NULL );
+ trw_layer_acquire ( values, &vik_datasource_gps_interface );
}
-#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 ( menu_array_layer values )
{
- 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);
+ trw_layer_acquire ( values, &vik_datasource_routing_interface );
+}
- a_acquire ( vw, vlp, vvp, &vik_datasource_google_interface, NULL, NULL );
+/*
+ * Acquire into this TRW Layer from an entered URL
+ */
+static void trw_layer_acquire_url_cb ( menu_array_layer values )
+{
+ vik_datasource_url_interface.mode = VIK_DATASOURCE_ADDTOLAYER;
+ trw_layer_acquire ( values, &vik_datasource_url_interface );
}
-#endif
#ifdef VIK_CONFIG_OPENSTREETMAP
/*
* Acquire into this TRW Layer from OSM
*/
-static void trw_layer_acquire_osm_cb ( gpointer lav[2] )
+static void trw_layer_acquire_osm_cb ( menu_array_layer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
- VikLayersPanel *vlp = VIK_LAYERS_PANEL(lav[1]);
- VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl));
- VikViewport *vvp = vik_window_viewport(vw);
-
- a_acquire ( vw, vlp, vvp, &vik_datasource_osm_interface, NULL, NULL );
+ trw_layer_acquire ( values, &vik_datasource_osm_interface );
}
/**
* Acquire into this TRW Layer from OSM for 'My' Traces
*/
-static void trw_layer_acquire_osm_my_traces_cb ( gpointer lav[2] )
+static void trw_layer_acquire_osm_my_traces_cb ( menu_array_layer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
- VikLayersPanel *vlp = VIK_LAYERS_PANEL(lav[1]);
- VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl));
- VikViewport *vvp = vik_window_viewport(vw);
-
- a_acquire ( vw, vlp, vvp, &vik_datasource_osm_my_traces_interface, NULL, NULL );
+ trw_layer_acquire ( values, &vik_datasource_osm_my_traces_interface );
}
#endif
/*
* Acquire into this TRW Layer from Geocaching.com
*/
-static void trw_layer_acquire_geocache_cb ( gpointer lav[2] )
+static void trw_layer_acquire_geocache_cb ( menu_array_layer values )
{
- 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_gc_interface, NULL, NULL );
+ trw_layer_acquire ( values, &vik_datasource_gc_interface );
}
#endif
/*
* Acquire into this TRW Layer from images
*/
-static void trw_layer_acquire_geotagged_cb ( gpointer lav[2] )
+static void trw_layer_acquire_geotagged_cb ( menu_array_layer values )
{
- 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);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
vik_datasource_geotag_interface.mode = VIK_DATASOURCE_ADDTOLAYER;
- a_acquire ( vw, vlp, vvp, &vik_datasource_geotag_interface, NULL, NULL );
+ trw_layer_acquire ( values, &vik_datasource_geotag_interface );
// Reverify thumbnails as they may have changed
vtl->has_verified_thumbnails = FALSE;
}
#endif
-static void trw_layer_gps_upload ( gpointer lav[2] )
+static void trw_layer_gps_upload ( menu_array_layer values )
{
- gpointer pass_along[6];
- pass_along[0] = lav[0];
- pass_along[1] = lav[1];
- pass_along[2] = NULL; // No track - operate on the layer
- pass_along[3] = NULL;
- pass_along[4] = NULL;
- pass_along[5] = NULL;
+ menu_array_sublayer data;
+ gint ii;
+ for ( ii = MA_VTL; ii < MA_LAST; ii++ )
+ data[ii] = NULL;
+ data[MA_VTL] = values[MA_VTL];
+ data[MA_VLP] = values[MA_VLP];
- trw_layer_gps_upload_any ( pass_along );
+ trw_layer_gps_upload_any ( data );
}
/**
* If pass_along[3] is defined that this will upload just that track
*/
-static void trw_layer_gps_upload_any ( gpointer pass_along[6] )
+static void trw_layer_gps_upload_any ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
- VikLayersPanel *vlp = VIK_LAYERS_PANEL(pass_along[1]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+ VikLayersPanel *vlp = VIK_LAYERS_PANEL(values[MA_VLP]);
- // May not actually get a track here as pass_along[2&3] can be null
+ // May not actually get a track here as values[2&3] can be null
VikTrack *track = NULL;
vik_gps_xfer_type xfer_type = TRK; // VIK_TRW_LAYER_SUBLAYER_TRACKS = 0 so hard to test different from NULL!
gboolean xfer_all = FALSE;
- if ( pass_along[2] ) {
+ if ( values[MA_SUBTYPE] ) {
xfer_all = FALSE;
- if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_ROUTE ) {
- track = (VikTrack *) g_hash_table_lookup ( vtl->routes, pass_along[3] );
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE ) {
+ track = (VikTrack *) g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
xfer_type = RTE;
}
- else if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_TRACK ) {
- track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+ else if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_TRACK ) {
+ track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
xfer_type = TRK;
}
- else if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_WAYPOINTS ) {
+ else if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_WAYPOINTS ) {
xfer_type = WPT;
}
- else if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_ROUTES ) {
+ else if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTES ) {
xfer_type = RTE;
}
}
- else if ( !pass_along[4] )
+ else if ( !values[MA_CONFIRM] )
xfer_all = TRUE; // i.e. whole layer
if (track && !track->visible) {
}
GtkWidget *dialog = gtk_dialog_new_with_buttons ( _("GPS Upload"),
- VIK_GTK_WINDOW_FROM_LAYER(pass_along[0]),
+ VIK_GTK_WINDOW_FROM_LAYER(vtl),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_STOCK_OK,
GTK_RESPONSE_ACCEPT,
/*
* Acquire into this TRW Layer from any GPS Babel supported file
*/
-static void trw_layer_acquire_file_cb ( gpointer lav[2] )
+static void trw_layer_acquire_file_cb ( menu_array_layer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
- VikLayersPanel *vlp = VIK_LAYERS_PANEL(lav[1]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+ VikLayersPanel *vlp = VIK_LAYERS_PANEL(values[MA_VLP]);
VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl));
VikViewport *vvp = vik_window_viewport(vw);
a_acquire ( vw, vlp, vvp, &vik_datasource_file_interface, NULL, NULL );
}
-static void trw_layer_new_wp ( gpointer lav[2] )
+static void trw_layer_new_wp ( menu_array_layer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
- VikLayersPanel *vlp = VIK_LAYERS_PANEL(lav[1]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+ VikLayersPanel *vlp = VIK_LAYERS_PANEL(values[MA_VLP]);
/* 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 ) {
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
vik_trw_layer_add_track ( vtl, name, vtl->current_track );
}
-static void trw_layer_new_track ( gpointer lav[2] )
+static void trw_layer_new_track ( menu_array_layer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
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
vik_trw_layer_add_route ( vtl, name, vtl->current_track );
}
-static void trw_layer_new_route ( gpointer lav[2] )
+static void trw_layer_new_route ( menu_array_layer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
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 );
}
}
-static void trw_layer_auto_routes_view ( gpointer lav[2] )
+static void trw_layer_auto_routes_view ( menu_array_layer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
- VikLayersPanel *vlp = VIK_LAYERS_PANEL(lav[1]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+ VikLayersPanel *vlp = VIK_LAYERS_PANEL(values[MA_VLP]);
if ( g_hash_table_size (vtl->routes) > 0 ) {
struct LatLon maxmin[2] = { {0,0}, {0,0} };
}
-static void trw_layer_finish_track ( gpointer lav[2] )
+static void trw_layer_finish_track ( menu_array_layer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
vtl->current_track = NULL;
+ vtl->route_finder_started = FALSE;
vik_layer_emit_update ( VIK_LAYER(vtl) );
}
-static void trw_layer_auto_tracks_view ( gpointer lav[2] )
+static void trw_layer_auto_tracks_view ( menu_array_layer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
- VikLayersPanel *vlp = VIK_LAYERS_PANEL(lav[1]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+ VikLayersPanel *vlp = VIK_LAYERS_PANEL(values[MA_VLP]);
if ( g_hash_table_size (vtl->tracks) > 0 ) {
struct LatLon maxmin[2] = { {0,0}, {0,0} };
static void trw_layer_single_waypoint_jump ( const gpointer id, const VikWaypoint *wp, gpointer vvp )
{
/* NB do not care if wp is visible or not */
- vik_viewport_set_center_coord ( VIK_VIEWPORT(vvp), &(wp->coord) );
+ vik_viewport_set_center_coord ( VIK_VIEWPORT(vvp), &(wp->coord), TRUE );
}
-static void trw_layer_auto_waypoints_view ( gpointer lav[2] )
+static void trw_layer_auto_waypoints_view ( menu_array_layer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
- VikLayersPanel *vlp = VIK_LAYERS_PANEL(lav[1]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+ VikLayersPanel *vlp = VIK_LAYERS_PANEL(values[MA_VLP]);
/* Only 1 waypoint - jump straight to it */
if ( g_hash_table_size (vtl->waypoints) == 1 ) {
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 );
}
vik_layers_panel_emit_update ( vlp );
}
+void trw_layer_osm_traces_upload_cb ( menu_array_layer values )
+{
+ osm_traces_upload_viktrwlayer(VIK_TRW_LAYER(values[MA_VTL]), NULL);
+}
+
+void trw_layer_osm_traces_upload_track_cb ( menu_array_sublayer values )
+{
+ if ( values[MA_MISC] ) {
+ VikTrack *trk = VIK_TRACK(values[MA_MISC]);
+ osm_traces_upload_viktrwlayer(VIK_TRW_LAYER(values[MA_VTL]), trk);
+ }
+}
+
static void trw_layer_add_menu_items ( VikTrwLayer *vtl, GtkMenu *menu, gpointer vlp )
{
- static gpointer pass_along[2];
+ static menu_array_layer pass_along;
GtkWidget *item;
GtkWidget *export_submenu;
- pass_along[0] = vtl;
- pass_along[1] = vlp;
+ pass_along[MA_VTL] = vtl;
+ pass_along[MA_VLP] = vlp;
item = gtk_menu_item_new();
gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
gtk_menu_shell_append (GTK_MENU_SHELL (export_submenu), item);
gtk_widget_show ( item );
- gchar* external1 = g_strconcat ( _("Open with External Program_1: "), a_vik_get_external_gpx_program_1(), NULL );
+ item = gtk_menu_item_new_with_mnemonic ( _("Export via GPSbabel...") );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_export_babel), pass_along );
+ gtk_menu_shell_append (GTK_MENU_SHELL (export_submenu), item);
+ gtk_widget_show ( item );
+
+ gchar* external1 = g_strdup_printf ( _("Open with External Program_1: %s"), a_vik_get_external_gpx_program_1() );
item = gtk_menu_item_new_with_mnemonic ( external1 );
g_free ( external1 );
g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_export_external_gpx_1), pass_along );
gtk_menu_shell_append (GTK_MENU_SHELL (export_submenu), item);
gtk_widget_show ( item );
- gchar* external2 = g_strconcat ( _("Open with External Program_2: "), a_vik_get_external_gpx_program_2(), NULL );
+ gchar* external2 = g_strdup_printf ( _("Open with External Program_2: %s"), a_vik_get_external_gpx_program_2() );
item = gtk_menu_item_new_with_mnemonic ( external2 );
g_free ( external2 );
g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_export_external_gpx_2), pass_along );
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_widget_show ( item );
#endif
+ item = gtk_menu_item_new_with_mnemonic ( _("From _URL...") );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_acquire_url_cb), pass_along );
+ gtk_menu_shell_append (GTK_MENU_SHELL (acquire_submenu), item);
+ gtk_widget_show ( item );
+
#ifdef VIK_CONFIG_GEONAMES
GtkWidget *wikipedia_submenu = gtk_menu_new();
item = gtk_image_menu_item_new_with_mnemonic ( _("From _Wikipedia Waypoints") );
item = gtk_menu_item_new_with_mnemonic ( _("From _File...") );
g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_acquire_file_cb), pass_along );
gtk_menu_shell_append (GTK_MENU_SHELL (acquire_submenu), item);
+ gtk_widget_set_tooltip_text (item, _("Import File With GPS_Babel..."));
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) );
#ifdef VIK_CONFIG_OPENSTREETMAP
item = gtk_image_menu_item_new_with_mnemonic ( _("Upload to _OSM...") );
gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_GO_UP, GTK_ICON_SIZE_MENU) );
- g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(osm_traces_upload_cb), pass_along );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_osm_traces_upload_cb), pass_along );
gtk_menu_shell_append (GTK_MENU_SHELL (upload_submenu), item);
gtk_widget_show ( item );
#endif
if ( item ) {
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
gtk_widget_show ( item );
- }
+ }
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("Track _List...") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_INDEX, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_track_list_dialog), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
+ gtk_widget_show ( item );
+ gtk_widget_set_sensitive ( item, (gboolean)(g_hash_table_size (vtl->tracks)+g_hash_table_size (vtl->routes)) );
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_Waypoint List...") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_INDEX, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_waypoint_list_dialog), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
+ gtk_widget_show ( item );
+ gtk_widget_set_sensitive ( item, (gboolean)(g_hash_table_size (vtl->waypoints)) );
}
// Fake Waypoint UUIDs vi simple increasing integer
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);
g_hash_table_insert ( vtl->tracks, GUINT_TO_POINTER(tr_uuid), t );
- trw_layer_update_treeview ( vtl, t, GUINT_TO_POINTER(tr_uuid) );
+ trw_layer_update_treeview ( vtl, t );
}
// Fake Route UUIDs vi simple increasing integer
g_hash_table_insert ( vtl->routes, GUINT_TO_POINTER(rt_uuid), t );
- trw_layer_update_treeview ( vtl, t, GUINT_TO_POINTER(rt_uuid) );
+ trw_layer_update_treeview ( vtl, t );
}
/* to be called whenever a track has been deleted or may have been changed. */
}
}
+/**
+ * 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;
void vik_trw_layer_filein_add_track ( VikTrwLayer *vtl, gchar *name, VikTrack *tr )
{
- if ( vtl->route_finder_append && vtl->route_finder_current_track ) {
+ if ( vtl->route_finder_append && vtl->current_track ) {
vik_track_remove_dup_points ( tr ); /* make "double point" track work to undo */
- vik_track_steal_and_append_trackpoints ( vtl->route_finder_current_track, tr );
+
+ // enforce end of current track equal to start of tr
+ VikTrackpoint *cur_end = vik_track_get_tp_last ( vtl->current_track );
+ VikTrackpoint *new_start = vik_track_get_tp_first ( tr );
+ if ( ! vik_coord_equals ( &cur_end->coord, &new_start->coord ) ) {
+ vik_track_add_trackpoint ( vtl->current_track,
+ vik_trackpoint_copy ( cur_end ),
+ FALSE );
+ }
+
+ vik_track_steal_and_append_trackpoints ( vtl->current_track, tr );
vik_track_free ( tr );
vtl->route_finder_append = FALSE; /* this means we have added it */
} else {
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 );
}
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 );
}
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
}
}
-typedef struct {
- VikTrack *trk; // input
- gpointer uuid; // output
-} trku_udata;
-
-static gboolean trw_layer_track_find_uuid ( const gpointer id, const VikTrack *trk, gpointer udata )
+gboolean trw_layer_track_find_uuid ( const gpointer id, const VikTrack *trk, gpointer udata )
{
trku_udata *user_data = udata;
if ( trk == user_data->trk ) {
gboolean vik_trw_layer_delete_track ( VikTrwLayer *vtl, VikTrack *trk )
{
gboolean was_visible = FALSE;
-
if ( trk && trk->name ) {
if ( trk == vtl->current_track ) {
vtl->current_tp_track = NULL;
vtl->current_tp_id = NULL;
vtl->moving_tp = FALSE;
+ vtl->route_finder_started = FALSE;
}
was_visible = trk->visible;
- if ( trk == vtl->route_finder_current_track )
- vtl->route_finder_current_track = NULL;
-
if ( trk == vtl->route_finder_added_track )
vtl->route_finder_added_track = NULL;
vik_treeview_item_delete ( VIK_LAYER(vtl)->vt, &(vtl->tracks_iter) );
}
}
+ // Incase it was selected (no item delete signal ATM)
+ vik_window_clear_highlight ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)) );
}
}
return was_visible;
was_visible = trk->visible;
- if ( trk == vtl->route_finder_current_track )
- vtl->route_finder_current_track = NULL;
-
if ( trk == vtl->route_finder_added_track )
vtl->route_finder_added_track = NULL;
vik_treeview_item_delete ( VIK_LAYER(vtl)->vt, &(vtl->routes_iter) );
}
}
+ // Incase it was selected (no item delete signal ATM)
+ vik_window_clear_highlight ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)) );
}
}
return was_visible;
vik_treeview_item_delete ( VIK_LAYER(vtl)->vt, &(vtl->waypoints_iter) );
}
}
+ // Incase it was selected (no item delete signal ATM)
+ vik_window_clear_highlight ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)) );
}
}
{
vtl->current_track = NULL;
- vtl->route_finder_current_track = NULL;
vtl->route_finder_added_track = NULL;
if (vtl->current_tp_track)
trw_layer_cancel_current_tp(vtl, FALSE);
{
vtl->current_track = NULL;
- vtl->route_finder_current_track = NULL;
vtl->route_finder_added_track = NULL;
if (vtl->current_tp_track)
trw_layer_cancel_current_tp(vtl, FALSE);
vik_layer_emit_update ( VIK_LAYER(vtl) );
}
-static void trw_layer_delete_all_tracks ( gpointer lav[2] )
+static void trw_layer_delete_all_tracks ( menu_array_layer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
// Get confirmation from the user
if ( a_dialog_yes_or_no ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
_("Are you sure you want to delete all tracks in %s?"),
vik_trw_layer_delete_all_tracks (vtl);
}
-static void trw_layer_delete_all_routes ( gpointer lav[2] )
+static void trw_layer_delete_all_routes ( menu_array_layer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
// Get confirmation from the user
if ( a_dialog_yes_or_no ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
_("Are you sure you want to delete all routes in %s?"),
vik_trw_layer_delete_all_routes (vtl);
}
-static void trw_layer_delete_all_waypoints ( gpointer lav[2] )
+static void trw_layer_delete_all_waypoints ( menu_array_layer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
// Get confirmation from the user
if ( a_dialog_yes_or_no ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
_("Are you sure you want to delete all waypoints in %s?"),
vik_trw_layer_delete_all_waypoints (vtl);
}
-static void trw_layer_delete_item ( gpointer pass_along[6] )
+static void trw_layer_delete_item ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
gboolean was_visible = FALSE;
- if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_WAYPOINT )
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_WAYPOINT )
{
- VikWaypoint *wp = g_hash_table_lookup ( vtl->waypoints, pass_along[3] );
+ VikWaypoint *wp = g_hash_table_lookup ( vtl->waypoints, values[MA_SUBLAYER_ID] );
if ( wp && wp->name ) {
- if ( GPOINTER_TO_INT ( pass_along[4]) )
+ if ( GPOINTER_TO_INT (values[MA_CONFIRM]) )
// 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 );
}
}
- else if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_TRACK )
+ else if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_TRACK )
{
- VikTrack *trk = g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+ VikTrack *trk = g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
if ( trk && trk->name ) {
- if ( GPOINTER_TO_INT ( pass_along[4]) )
+ if ( GPOINTER_TO_INT (values[MA_CONFIRM]) )
// 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 );
}
else
{
- VikTrack *trk = g_hash_table_lookup ( vtl->routes, pass_along[3] );
+ VikTrack *trk = g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
if ( trk && trk->name ) {
- if ( GPOINTER_TO_INT ( pass_along[4]) )
+ if ( GPOINTER_TO_INT (values[MA_CONFIRM]) )
// 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 );
/**
* 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 )
+void trw_layer_waypoint_rename ( VikTrwLayer *vtl, VikWaypoint *wp, const gchar *new_name )
{
vik_waypoint_set_name ( wp, new_name );
}
}
-static void trw_layer_properties_item ( gpointer pass_along[7] )
+/**
+ * Maintain icon of waypoint in the treeview
+ */
+void trw_layer_waypoint_reset_icon ( VikTrwLayer *vtl, VikWaypoint *wp )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
- if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_WAYPOINT )
+ // update the treeview
+ 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_icon ( VIK_LAYER(vtl)->vt, it, get_wp_sym_small (wp->symbol) );
+ }
+ }
+}
+
+static void trw_layer_properties_item ( menu_array_sublayer values )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_WAYPOINT )
{
- VikWaypoint *wp = g_hash_table_lookup ( vtl->waypoints, pass_along[3] ); // sublayer
+ VikWaypoint *wp = g_hash_table_lookup ( vtl->waypoints, values[MA_SUBLAYER_ID] );
if ( wp && wp->name )
{
if ( new_name )
trw_layer_waypoint_rename ( vtl, wp, new_name );
- 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 && values[MA_TV_ITER] )
+ vik_treeview_item_set_icon ( VIK_LAYER(vtl)->vt, values[MA_TV_ITER], get_wp_sym_small (wp->symbol) );
if ( updated && VIK_LAYER(vtl)->visible )
vik_layer_emit_update ( VIK_LAYER(vtl) );
else
{
VikTrack *tr;
- if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_TRACK )
- tr = g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_TRACK )
+ tr = g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
else
- tr = g_hash_table_lookup ( vtl->routes, pass_along[3] );
+ tr = g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
if ( tr && tr->name )
{
vik_trw_layer_propwin_run ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
- vtl,
+ vtl,
tr,
- pass_along[1], /* vlp */
- pass_along[5], /* vvp */
- pass_along[6]); /* iter */
+ values[MA_VLP],
+ values[MA_VVP],
+ 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 ( menu_array_sublayer values )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+ VikTrack *trk;
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_TRACK )
+ trk = g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
+ else
+ trk = g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
+
+ if ( trk && trk->name ) {
+ vik_trw_layer_propwin_run ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
+ vtl,
+ trk,
+ values[MA_VLP],
+ values[MA_VVP],
+ TRUE );
+ }
+}
+
/*
* Update the treeview of the track id - primarily to update the icon
*/
-void trw_layer_update_treeview ( VikTrwLayer *vtl, VikTrack *trk, gpointer *trk_id )
+void trw_layer_update_treeview ( VikTrwLayer *vtl, VikTrack *trk )
{
trku_udata udata;
udata.trk = trk;
static void goto_coord ( gpointer *vlp, gpointer vl, gpointer vvp, const VikCoord *coord )
{
if ( vlp ) {
- vik_viewport_set_center_coord ( vik_layers_panel_get_viewport (VIK_LAYERS_PANEL(vlp)), coord );
+ vik_viewport_set_center_coord ( vik_layers_panel_get_viewport (VIK_LAYERS_PANEL(vlp)), coord, TRUE );
vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(vlp) );
}
else {
/* since vlp not set, vl & vvp should be valid instead! */
if ( vl && vvp ) {
- vik_viewport_set_center_coord ( VIK_VIEWPORT(vvp), coord );
+ vik_viewport_set_center_coord ( VIK_VIEWPORT(vvp), coord, TRUE );
vik_layer_emit_update ( VIK_LAYER(vl) );
}
}
}
-static void trw_layer_goto_track_startpoint ( gpointer pass_along[6] )
+static void trw_layer_goto_track_startpoint ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
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] );
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ track = (VikTrack *) g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
else
- track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+ track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
if ( track && track->trackpoints )
- goto_coord ( pass_along[1], pass_along[0], pass_along[5], &(((VikTrackpoint *) track->trackpoints->data)->coord) );
+ goto_coord ( values[MA_VLP], vtl, values[MA_VVP], &(vik_track_get_tp_first(track)->coord) );
}
-static void trw_layer_goto_track_center ( gpointer pass_along[6] )
+static void trw_layer_goto_track_center ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
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] );
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ track = (VikTrack *) g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
else
- track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+ track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
if ( track && track->trackpoints )
{
average.lat = (maxmin[0].lat+maxmin[1].lat)/2;
average.lon = (maxmin[0].lon+maxmin[1].lon)/2;
vik_coord_load_from_latlon ( &coord, vtl->coord_mode, &average );
- goto_coord ( pass_along[1], pass_along[0], pass_along[5], &coord);
+ goto_coord ( values[MA_VLP], vtl, values[MA_VVP], &coord);
}
}
-static void trw_layer_convert_track_route ( gpointer pass_along[6] )
+static void trw_layer_convert_track_route ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
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] );
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ trk = (VikTrack *) g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
else
- trk = (VikTrack *) g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+ trk = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
if ( !trk )
return;
g_free ( name );
// Update in case color of track / route changes when moving between sublayers
- vik_layer_emit_update ( VIK_LAYER(pass_along[0]) );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
}
+static void trw_layer_anonymize_times ( menu_array_sublayer values )
+{
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
+ VikTrack *track;
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ track = (VikTrack *) g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
+ else
+ track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
+
+ if ( track )
+ vik_track_anonymize_times ( track );
+}
-static void trw_layer_extend_track_end ( gpointer pass_along[6] )
+static void trw_layer_extend_track_end ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
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] );
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ track = (VikTrack *) g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
else
- track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+ track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
if ( !track )
return;
vik_window_enable_layer_tool ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), VIK_LAYER_TRW, track->is_route ? TOOL_CREATE_ROUTE : TOOL_CREATE_TRACK);
if ( track->trackpoints )
- goto_coord ( pass_along[1], pass_along[0], pass_along[5], &(((VikTrackpoint *)g_list_last(track->trackpoints)->data)->coord) );
+ goto_coord ( values[MA_VLP], vtl, values[MA_VVP], &(vik_track_get_tp_last(track)->coord) );
}
/**
* extend a track using route finder
*/
-static void trw_layer_extend_track_end_route_finder ( gpointer pass_along[6] )
+static void trw_layer_extend_track_end_route_finder ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
- VikTrack *track = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->routes, pass_along[3] );
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+ VikTrack *track = g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
if ( !track )
return;
- VikCoord last_coord = (((VikTrackpoint *)g_list_last(track->trackpoints)->data)->coord);
vik_window_enable_layer_tool ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), VIK_LAYER_TRW, TOOL_ROUTE_FINDER );
- vtl->route_finder_coord = last_coord;
- vtl->route_finder_current_track = track;
+ vtl->current_track = track;
vtl->route_finder_started = TRUE;
if ( track->trackpoints )
- goto_coord ( pass_along[1], pass_along[0], pass_along[5], &last_coord) ;
+ goto_coord ( values[MA_VLP], vtl, values[MA_VVP], &vik_track_get_tp_last(track)->coord );
+}
+/**
+ *
+ */
+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;
}
-static void trw_layer_apply_dem_data ( gpointer pass_along[6] )
+/**
+ * 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 )
{
- /* 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];
+ 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 ( menu_array_sublayer values )
+{
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
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] );
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ track = (VikTrack *) g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
else
- track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+ track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
if ( track )
- vik_track_apply_dem_data ( track );
+ apply_dem_data_common ( vtl, values[MA_VLP], track, FALSE );
+}
+
+static void trw_layer_apply_dem_data_only_missing ( menu_array_sublayer values )
+{
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
+ VikTrack *track;
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ track = (VikTrack *) g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
+ else
+ track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
+
+ if ( track )
+ apply_dem_data_common ( vtl, values[MA_VLP], 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_goto_track_endpoint ( gpointer pass_along[6] )
+/**
+ *
+ */
+static void trw_layer_missing_elevation_data_interp ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
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] );
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ track = (VikTrack *) g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
else
- track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+ track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
if ( !track )
return;
- GList *trps = track->trackpoints;
- if ( !trps )
+ smooth_it ( vtl, track, FALSE );
+}
+
+static void trw_layer_missing_elevation_data_flat ( menu_array_sublayer values )
+{
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
+ VikTrack *track;
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ track = (VikTrack *) g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
+ else
+ track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
+
+ 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 ( menu_array_sublayer values )
+{
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
+ VikLayersPanel *vlp = (VikLayersPanel *)values[MA_VLP];
+
+ if ( !trw_layer_dem_test ( vtl, vlp ) )
+ return;
+
+ gint changed = 0;
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_WAYPOINT ) {
+ // Single Waypoint
+ VikWaypoint *wp = (VikWaypoint *) g_hash_table_lookup ( vtl->waypoints, values[MA_SUBLAYER_ID] );
+ 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 ( menu_array_sublayer values )
+{
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
+ VikLayersPanel *vlp = (VikLayersPanel *)values[MA_VLP];
+
+ if ( !trw_layer_dem_test ( vtl, vlp ) )
return;
- trps = g_list_last(trps);
- goto_coord ( pass_along[1], pass_along[0], pass_along[5], &(((VikTrackpoint *) trps->data)->coord));
+
+ gint changed = 0;
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_WAYPOINT ) {
+ // Single Waypoint
+ VikWaypoint *wp = (VikWaypoint *) g_hash_table_lookup ( vtl->waypoints, values[MA_SUBLAYER_ID] );
+ 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_max_speed ( gpointer pass_along[6] )
+static void trw_layer_goto_track_endpoint ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
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] );
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ track = (VikTrack *) g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
else
- track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+ track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
+
+ if ( !track )
+ return;
+ if ( !track->trackpoints )
+ return;
+ goto_coord ( values[MA_VLP], vtl, values[MA_VVP], &(vik_track_get_tp_last(track)->coord));
+}
+
+static void trw_layer_goto_track_max_speed ( menu_array_sublayer values )
+{
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
+ VikTrack *track;
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ track = (VikTrack *) g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
+ else
+ track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
if ( !track )
return;
VikTrackpoint* vtp = vik_track_get_tp_by_max_speed ( track );
if ( !vtp )
return;
- goto_coord ( pass_along[1], pass_along[0], pass_along[5], &(vtp->coord));
+ goto_coord ( values[MA_VLP], vtl, values[MA_VVP], &(vtp->coord));
}
-static void trw_layer_goto_track_max_alt ( gpointer pass_along[6] )
+static void trw_layer_goto_track_max_alt ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
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] );
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ track = (VikTrack *) g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
else
- track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+ track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
if ( !track )
return;
VikTrackpoint* vtp = vik_track_get_tp_by_max_alt ( track );
if ( !vtp )
return;
- goto_coord ( pass_along[1], pass_along[0], pass_along[5], &(vtp->coord));
+ goto_coord ( values[MA_VLP], vtl, values[MA_VVP], &(vtp->coord));
}
-static void trw_layer_goto_track_min_alt ( gpointer pass_along[6] )
+static void trw_layer_goto_track_min_alt ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
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] );
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ track = (VikTrack *) g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
else
- track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+ track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
if ( !track )
return;
VikTrackpoint* vtp = vik_track_get_tp_by_min_alt ( track );
if ( !vtp )
return;
- goto_coord ( pass_along[1], pass_along[0], pass_along[5], &(vtp->coord));
+ goto_coord ( values[MA_VLP], vtl, values[MA_VVP], &(vtp->coord));
}
/*
* Automatically change the viewport to center on the track and zoom to see the extent of the track
*/
-static void trw_layer_auto_track_view ( gpointer pass_along[6] )
+static void trw_layer_auto_track_view ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
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] );
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ trk = (VikTrack *) g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
else
- trk = (VikTrack *) g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+ trk = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
if ( trk && trk->trackpoints )
{
struct LatLon maxmin[2] = { {0,0}, {0,0} };
trw_layer_find_maxmin_tracks ( NULL, trk, 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]) );
+ trw_layer_zoom_to_show_latlons ( vtl, values[MA_VVP], maxmin );
+ if ( values[MA_VLP] )
+ vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(values[MA_VLP]) );
else
vik_layer_emit_update ( VIK_LAYER(vtl) );
}
}
-static void trw_layer_edit_trackpoint ( gpointer pass_along[6] )
+/*
+ * 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 ( menu_array_sublayer values )
+{
+ static gint last_engine = 0;
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+ VikTrack *trk;
+
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ trk = (VikTrack *) g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
+ else
+ trk = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
+
+ 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(vtl)) );
+
+ /* 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(vtl)) );
+ }
+ gtk_widget_destroy ( dialog );
+ }
+}
+
+static void trw_layer_edit_trackpoint ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
trw_layer_tpwin_init ( vtl );
}
*/
typedef struct {
GList **result;
- GList *exclude;
+ VikTrack *exclude;
gboolean with_timestamps;
} twt_udata;
static void find_tracks_with_timestamp_type(gpointer key, gpointer value, gpointer udata)
{
twt_udata *user_data = udata;
VikTrackpoint *p1, *p2;
-
- if (VIK_TRACK(value)->trackpoints == user_data->exclude) {
+ VikTrack *trk = VIK_TRACK(value);
+ if (trk == user_data->exclude) {
return;
}
- if (VIK_TRACK(value)->trackpoints) {
- p1 = VIK_TRACKPOINT(VIK_TRACK(value)->trackpoints->data);
- p2 = VIK_TRACKPOINT(g_list_last(VIK_TRACK(value)->trackpoints)->data);
+ if (trk->trackpoints) {
+ p1 = vik_track_get_tp_first(trk);
+ p2 = vik_track_get_tp_last(trk);
if ( user_data->with_timestamps ) {
if (!p1->has_timestamp || !p2->has_timestamp) {
VikTrack *trk = VIK_TRACK(value);
GList **nearby_tracks = ((gpointer *)user_data)[0];
- GList *tpoints = ((gpointer *)user_data)[1];
/* outline:
* detect reasons for not merging, and return
* if no reason is found not to merge, then do it.
*/
+ twt_udata *udata = user_data;
// Exclude the original track from the compiled list
- if (trk->trackpoints == tpoints) {
+ if (trk == udata->exclude) {
return;
}
- t1 = VIK_TRACKPOINT(g_list_first(tpoints)->data)->timestamp;
- t2 = VIK_TRACKPOINT(g_list_last(tpoints)->data)->timestamp;
+ t1 = vik_track_get_tp_first(trk)->timestamp;
+ t2 = vik_track_get_tp_last(trk)->timestamp;
if (trk->trackpoints) {
- p1 = VIK_TRACKPOINT(g_list_first(trk->trackpoints)->data);
- p2 = VIK_TRACKPOINT(g_list_last(trk->trackpoints)->data);
+ p1 = vik_track_get_tp_first(trk);
+ p2 = vik_track_get_tp_last(trk);
if (!p1->has_timestamp || !p2->has_timestamp) {
//g_print("no timestamp\n");
* Tracks to merge with must be of the same 'type' as the selected track -
* either all with timestamps, or all without timestamps
*/
-static void trw_layer_merge_with_other ( gpointer pass_along[6] )
+static void trw_layer_merge_with_other ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
GList *other_tracks = NULL;
GHashTable *ght_tracks;
- if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
ght_tracks = vtl->routes;
else
ght_tracks = vtl->tracks;
- VikTrack *track = (VikTrack *) g_hash_table_lookup ( ght_tracks, pass_along[3] );
+ VikTrack *track = (VikTrack *) g_hash_table_lookup ( ght_tracks, values[MA_SUBLAYER_ID] );
if ( !track )
return;
twt_udata udata;
udata.result = &other_tracks;
- udata.exclude = track->trackpoints;
+ udata.exclude = track;
// Allow merging with 'similar' time type time tracks
// i.e. either those times, or those without
- udata.with_timestamps = (VIK_TRACKPOINT(track->trackpoints->data)->has_timestamp);
+ udata.with_timestamps = vik_track_get_tp_first(track)->has_timestamp;
g_hash_table_foreach(ght_tracks, find_tracks_with_timestamp_type, (gpointer)&udata);
other_tracks = g_list_reverse(other_tracks);
twt_udata *user_data = udata;
// Skip self
- if (trk->trackpoints == user_data->exclude) {
+ if (trk == user_data->exclude) {
return;
}
* i.e. doesn't care about whether tracks have consistent timestamps
* ATM can only append one track at a time to the currently selected track
*/
-static void trw_layer_append_track ( gpointer pass_along[6] )
+static void trw_layer_append_track ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
VikTrack *trk;
GHashTable *ght_tracks;
- if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
ght_tracks = vtl->routes;
else
ght_tracks = vtl->tracks;
- trk = (VikTrack *) g_hash_table_lookup ( ght_tracks, pass_along[3] );
+ trk = (VikTrack *) g_hash_table_lookup ( ght_tracks, values[MA_SUBLAYER_ID] );
if ( !trk )
return;
// TODO: Need to consider how to work best when we can have multiple tracks the same name...
twt_udata udata;
udata.result = &other_tracks_names;
- udata.exclude = trk->trackpoints;
+ udata.exclude = trk;
g_hash_table_foreach(ght_tracks, (GHFunc) trw_layer_sorted_track_id_by_name_list_exclude_self, (gpointer)&udata);
* If a track is selected, then is shows routes and joins the selected one
* If a route is selected, then is shows tracks and joins the selected one
*/
-static void trw_layer_append_other ( gpointer pass_along[6] )
+static void trw_layer_append_other ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
VikTrack *trk;
GHashTable *ght_mykind, *ght_others;
- if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_ROUTE ) {
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE ) {
ght_mykind = vtl->routes;
ght_others = vtl->tracks;
}
ght_others = vtl->routes;
}
- trk = (VikTrack *) g_hash_table_lookup ( ght_mykind, pass_along[3] );
+ trk = (VikTrack *) g_hash_table_lookup ( ght_mykind, values[MA_SUBLAYER_ID] );
if ( !trk )
return;
// TODO: Need to consider how to work best when we can have multiple tracks the same name...
twt_udata udata;
udata.result = &other_tracks_names;
- udata.exclude = trk->trackpoints;
+ udata.exclude = trk;
g_hash_table_foreach(ght_others, (GHFunc) trw_layer_sorted_track_id_by_name_list_exclude_self, (gpointer)&udata);
}
/* merge by segments */
-static void trw_layer_merge_by_segment ( gpointer pass_along[6] )
+static void trw_layer_merge_by_segment ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
- VikTrack *trk = (VikTrack *) g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
+ VikTrack *trk = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
guint segments = vik_track_merge_segments ( trk );
// NB currently no need to redraw as segments not actually shown on the display
// However inform the user of what happened:
}
/* merge by time routine */
-static void trw_layer_merge_by_timestamp ( gpointer pass_along[6] )
+static void trw_layer_merge_by_timestamp ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
//time_t t1, t2;
GList *tracks_with_timestamp = NULL;
- VikTrack *orig_trk = (VikTrack *) g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+ VikTrack *orig_trk = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
if (orig_trk->trackpoints &&
- !VIK_TRACKPOINT(orig_trk->trackpoints->data)->has_timestamp) {
+ !vik_track_get_tp_first(orig_trk)->has_timestamp) {
a_dialog_error_msg(VIK_GTK_WINDOW_FROM_LAYER(vtl), _("Failed. This track does not have timestamp"));
return;
}
twt_udata udata;
udata.result = &tracks_with_timestamp;
- udata.exclude = orig_trk->trackpoints;
+ udata.exclude = orig_trk;
udata.with_timestamps = TRUE;
g_hash_table_foreach(vtl->tracks, find_tracks_with_timestamp_type, (gpointer)&udata);
tracks_with_timestamp = g_list_reverse(tracks_with_timestamp);
nearby_tracks = NULL;
}
- //t1 = ((VikTrackpoint *)trps->data)->timestamp;
- //t2 = ((VikTrackpoint *)g_list_last(trps)->data)->timestamp;
-
- /* g_print("Original track times: %d and %d\n", t1, t2); */
params[0] = &nearby_tracks;
params[1] = (gpointer)trps;
params[2] = GUINT_TO_POINTER (threshold_in_minutes*60); // In seconds
/* merge them */
GList *l = nearby_tracks;
while ( l ) {
- /*
-#define get_first_trackpoint(x) VIK_TRACKPOINT(VIK_TRACK(x)->trackpoints->data)
-#define get_last_trackpoint(x) VIK_TRACKPOINT(g_list_last(VIK_TRACK(x)->trackpoints)->data)
- time_t t1, t2;
- t1 = get_first_trackpoint(l)->timestamp;
- t2 = get_last_trackpoint(l)->timestamp;
-#undef get_first_trackpoint
-#undef get_last_trackpoint
- g_print(" %20s: track %d - %d\n", VIK_TRACK(l->data)->name, (int)t1, (int)t2);
- */
-
/* remove trackpoints from merged track, delete track */
vik_track_steal_and_append_trackpoints ( orig_trk, VIK_TRACK(l->data) );
vik_trw_layer_delete_track (vtl, VIK_TRACK(l->data));
vik_layer_emit_update(VIK_LAYER(vtl));
}
+ g_free ( name );
}
}
/* split by time routine */
-static void trw_layer_split_by_timestamp ( gpointer pass_along[6] )
+static void trw_layer_split_by_timestamp ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
- VikTrack *track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
+ VikTrack *track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
GList *trps = track->trackpoints;
GList *iter;
GList *newlists = NULL;
if ( !trps )
return;
- if (!a_dialog_time_threshold(VIK_GTK_WINDOW_FROM_LAYER(pass_along[0]),
+ if (!a_dialog_time_threshold(VIK_GTK_WINDOW_FROM_LAYER(vtl),
_("Split Threshold..."),
_("Split when time between trackpoints exceeds:"),
&thr)) {
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) );
+ goto_coord ( values[MA_VLP], vtl, values[MA_VVP], &(VIK_TRACKPOINT(iter->data)->coord) );
}
return;
}
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_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
vik_trw_layer_delete_track (vtl, track);
- vik_layer_emit_update(VIK_LAYER(pass_along[0]));
+ vik_layer_emit_update(VIK_LAYER(vtl));
}
g_list_free(newlists);
}
/**
* Split a track by the number of points as specified by the user
*/
-static void trw_layer_split_by_n_points ( gpointer pass_along[6] )
+static void trw_layer_split_by_n_points ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
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] );
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ track = (VikTrack *) g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
else
- track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+ track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
if ( !track )
return;
if ( !trps )
return;
- gint points = a_dialog_get_positive_number(VIK_GTK_WINDOW_FROM_LAYER(pass_along[0]),
+ gint points = a_dialog_get_positive_number(VIK_GTK_WINDOW_FROM_LAYER(vtl),
_("Split Every Nth Point"),
_("Split on every Nth point:"),
250, // Default value as per typical limited track capacity of various GPS devices
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);
vik_trw_layer_delete_route (vtl, track);
else
vik_trw_layer_delete_track (vtl, track);
- vik_layer_emit_update(VIK_LAYER(pass_along[0]));
+ vik_layer_emit_update(VIK_LAYER(vtl));
}
g_list_free(newlists);
}
/**
* Split a track at the currently selected trackpoint
*/
-static void trw_layer_split_at_trackpoint ( gpointer pass_along[6] )
+static void trw_layer_split_at_trackpoint ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
- gint subtype = GPOINTER_TO_INT (pass_along[2]);
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
+ gint subtype = GPOINTER_TO_INT (values[MA_SUBTYPE]);
trw_layer_split_at_selected_trackpoint ( vtl, subtype );
}
* Split a track by its segments
* Routes do not have segments so don't call this for routes
*/
-static void trw_layer_split_segments ( gpointer pass_along[6] )
+static void trw_layer_split_segments ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
- VikTrack *trk = g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
+ VikTrack *trk = g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
if ( !trk )
return;
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 ) {
}
/* end of split/merge routines */
+static void trw_layer_trackpoint_selected_delete ( VikTrwLayer *vtl, VikTrack *trk )
+{
+ GList *new_tpl;
+
+ // Find available adjacent trackpoint
+ if ( (new_tpl = vtl->current_tpl->next) || (new_tpl = vtl->current_tpl->prev) ) {
+ if ( VIK_TRACKPOINT(vtl->current_tpl->data)->newsegment && vtl->current_tpl->next )
+ VIK_TRACKPOINT(vtl->current_tpl->next->data)->newsegment = TRUE; /* don't concat segments on del */
+
+ // Delete current trackpoint
+ vik_trackpoint_free ( vtl->current_tpl->data );
+ trk->trackpoints = g_list_delete_link ( trk->trackpoints, vtl->current_tpl );
+
+ // Set to current to the available adjacent trackpoint
+ vtl->current_tpl = new_tpl;
+
+ if ( vtl->current_tp_track ) {
+ vik_track_calculate_bounds ( vtl->current_tp_track );
+ }
+ }
+ else {
+ // Delete current trackpoint
+ vik_trackpoint_free ( vtl->current_tpl->data );
+ trk->trackpoints = g_list_delete_link ( trk->trackpoints, vtl->current_tpl );
+ trw_layer_cancel_current_tp ( vtl, FALSE );
+ }
+}
+
+/**
+ * Delete the selected point
+ */
+static void trw_layer_delete_point_selected ( menu_array_sublayer values )
+{
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
+ VikTrack *trk;
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ trk = (VikTrack *) g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
+ else
+ trk = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
+
+ if ( !trk )
+ return;
+
+ if ( !vtl->current_tpl )
+ return;
+
+ trw_layer_trackpoint_selected_delete ( vtl, trk );
+
+ // Track has been updated so update tps:
+ trw_layer_cancel_tps_of_track ( vtl, trk );
+
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+}
+
/**
* Delete adjacent track points at the same position
* AKA Delete Dulplicates on the Properties Window
*/
-static void trw_layer_delete_points_same_position ( gpointer pass_along[6] )
+static void trw_layer_delete_points_same_position ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
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] );
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ trk = (VikTrack *) g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
else
- trk = (VikTrack *) g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+ trk = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
if ( !trk )
return;
* Delete adjacent track points with the same timestamp
* Normally new tracks that are 'routes' won't have any timestamps so should be OK to clean up the track
*/
-static void trw_layer_delete_points_same_time ( gpointer pass_along[6] )
+static void trw_layer_delete_points_same_time ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
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] );
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ trk = (VikTrack *) g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
else
- trk = (VikTrack *) g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+ trk = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
if ( !trk )
return;
vik_layer_emit_update ( VIK_LAYER(vtl) );
}
+/**
+ * Insert a point
+ */
+static void trw_layer_insert_point_after ( menu_array_sublayer values )
+{
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
+ VikTrack *track;
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ track = (VikTrack *) g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
+ else
+ track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
+
+ if ( ! track )
+ return;
+
+ trw_layer_insert_tp_beside_current_tp ( vtl, FALSE );
+
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+}
+
+static void trw_layer_insert_point_before ( menu_array_sublayer values )
+{
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
+ VikTrack *track;
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ track = (VikTrack *) g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
+ else
+ track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
+
+ if ( ! track )
+ return;
+
+ trw_layer_insert_tp_beside_current_tp ( vtl, TRUE );
+
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+}
+
/**
* Reverse a track
*/
-static void trw_layer_reverse ( gpointer pass_along[6] )
+static void trw_layer_reverse ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
+ VikTrwLayer *vtl = (VikTrwLayer *)values[MA_VTL];
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] );
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ track = (VikTrack *) g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
else
- track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+ track = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
if ( ! track )
return;
vik_track_reverse ( track );
- vik_layer_emit_update ( VIK_LAYER(pass_along[0]) );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+}
+
+/**
+ * Open a diary at the specified date
+ */
+static void trw_layer_diary_open ( VikTrwLayer *vtl, const gchar *date_str )
+{
+ GError *err = NULL;
+ gchar *cmd = g_strdup_printf ( "%s%s", "rednotebook --date=", date_str );
+ if ( ! g_spawn_command_line_async ( cmd, &err ) ) {
+ a_dialog_error_msg_extra ( VIK_GTK_WINDOW_FROM_LAYER(vtl), _("Could not launch %s to open file."), "rednotebook" );
+ g_error_free ( err );
+ }
+ g_free ( cmd );
+}
+
+/**
+ * Open a diary at the date of the track or waypoint
+ */
+static void trw_layer_diary ( menu_array_sublayer values )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+
+ if ( GPOINTER_TO_INT(values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_TRACK ) {
+ VikTrack *trk = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
+ if ( ! trk )
+ return;
+
+ gchar date_buf[20];
+ date_buf[0] = '\0';
+ if ( trk->trackpoints && VIK_TRACKPOINT(trk->trackpoints->data)->has_timestamp ) {
+ strftime (date_buf, sizeof(date_buf), "%Y-%m-%d", gmtime(&(VIK_TRACKPOINT(trk->trackpoints->data)->timestamp)));
+ trw_layer_diary_open ( vtl, date_buf );
+ }
+ else
+ a_dialog_info_msg ( VIK_GTK_WINDOW_FROM_LAYER(vtl), _("This track has no date information.") );
+ }
+ else if ( GPOINTER_TO_INT(values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_WAYPOINT ) {
+ VikWaypoint *wpt = (VikWaypoint *) g_hash_table_lookup ( vtl->waypoints, values[MA_SUBLAYER_ID] );
+ if ( ! wpt )
+ return;
+
+ gchar date_buf[20];
+ date_buf[0] = '\0';
+ if ( wpt->has_timestamp ) {
+ strftime (date_buf, sizeof(date_buf), "%Y-%m-%d", gmtime(&(wpt->timestamp)));
+ trw_layer_diary_open ( vtl, date_buf );
+ }
+ else
+ a_dialog_info_msg ( VIK_GTK_WINDOW_FROM_LAYER(vtl), _("This waypoint has no date information.") );
+ }
}
/**
vik_layers_panel_emit_update ( vlp );
}
-static void trw_layer_sort_order_a2z ( gpointer pass_along[6] )
+static void trw_layer_sort_order_a2z ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
GtkTreeIter *iter;
- switch (GPOINTER_TO_INT (pass_along[2])) {
+ switch (GPOINTER_TO_INT (values[MA_SUBTYPE])) {
case VIK_TRW_LAYER_SUBLAYER_TRACKS:
iter = &(vtl->tracks_iter);
vtl->track_sort_order = VL_SO_ALPHABETICAL_ASCENDING;
vik_treeview_sort_children ( VIK_LAYER(vtl)->vt, iter, VL_SO_ALPHABETICAL_ASCENDING );
}
-static void trw_layer_sort_order_z2a ( gpointer pass_along[6] )
+static void trw_layer_sort_order_z2a ( menu_array_sublayer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
GtkTreeIter *iter;
- switch (GPOINTER_TO_INT (pass_along[2])) {
+ switch (GPOINTER_TO_INT (values[MA_SUBTYPE])) {
case VIK_TRW_LAYER_SUBLAYER_TRACKS:
iter = &(vtl->tracks_iter);
vtl->track_sort_order = VL_SO_ALPHABETICAL_DESCENDING;
/**
*
*/
-static void trw_layer_delete_tracks_from_selection ( gpointer lav[2] )
+static void trw_layer_delete_tracks_from_selection ( menu_array_layer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
GList *all = NULL;
// Ensure list of track names offered is unique
if ( trw_layer_has_same_track_names ( vtl->tracks ) ) {
if ( a_dialog_yes_or_no ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
_("Multiple entries with the same name exist. This method only works with unique names. Force unique names now?"), NULL ) ) {
- vik_trw_layer_uniquify_tracks ( vtl, VIK_LAYERS_PANEL(lav[1]), vtl->tracks, TRUE );
+ vik_trw_layer_uniquify_tracks ( vtl, VIK_LAYERS_PANEL(values[MA_VLP]), vtl->tracks, TRUE );
}
else
return;
/**
*
*/
-static void trw_layer_delete_routes_from_selection ( gpointer lav[2] )
+static void trw_layer_delete_routes_from_selection ( menu_array_layer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
GList *all = NULL;
// Ensure list of track names offered is unique
if ( trw_layer_has_same_track_names ( vtl->routes ) ) {
if ( a_dialog_yes_or_no ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
_("Multiple entries with the same name exist. This method only works with unique names. Force unique names now?"), NULL ) ) {
- vik_trw_layer_uniquify_tracks ( vtl, VIK_LAYERS_PANEL(lav[1]), vtl->routes, FALSE );
+ vik_trw_layer_uniquify_tracks ( vtl, VIK_LAYERS_PANEL(values[MA_VLP]), vtl->routes, FALSE );
}
else
return;
/**
*
*/
-static void trw_layer_delete_waypoints_from_selection ( gpointer lav[2] )
+static void trw_layer_delete_waypoints_from_selection ( menu_array_layer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
GList *all = NULL;
// Ensure list of waypoint names offered is unique
if ( trw_layer_has_same_waypoint_names ( vtl ) ) {
if ( a_dialog_yes_or_no ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
_("Multiple entries with the same name exist. This method only works with unique names. Force unique names now?"), NULL ) ) {
- vik_trw_layer_uniquify_waypoints ( vtl, VIK_LAYERS_PANEL(lav[1]) );
+ vik_trw_layer_uniquify_waypoints ( vtl, VIK_LAYERS_PANEL(values[MA_VLP]) );
}
else
return;
/**
*
*/
-static void trw_layer_waypoints_visibility_off ( gpointer lav[2] )
+static void trw_layer_waypoints_visibility_off ( menu_array_layer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
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] );
/**
*
*/
-static void trw_layer_waypoints_visibility_on ( gpointer lav[2] )
+static void trw_layer_waypoints_visibility_on ( menu_array_layer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
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] );
/**
*
*/
-static void trw_layer_waypoints_visibility_toggle ( gpointer lav[2] )
+static void trw_layer_waypoints_visibility_toggle ( menu_array_layer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
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
/**
*
*/
-static void trw_layer_tracks_visibility_off ( gpointer lav[2] )
+static void trw_layer_tracks_visibility_off ( menu_array_layer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
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] );
/**
*
*/
-static void trw_layer_tracks_visibility_on ( gpointer lav[2] )
+static void trw_layer_tracks_visibility_on ( menu_array_layer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
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] );
/**
*
*/
-static void trw_layer_tracks_visibility_toggle ( gpointer lav[2] )
+static void trw_layer_tracks_visibility_toggle ( menu_array_layer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
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
/**
*
*/
-static void trw_layer_routes_visibility_off ( gpointer lav[2] )
+static void trw_layer_routes_visibility_off ( menu_array_layer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
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] );
/**
*
*/
-static void trw_layer_routes_visibility_on ( gpointer lav[2] )
+static void trw_layer_routes_visibility_on ( menu_array_layer values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
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] );
/**
*
*/
-static void trw_layer_routes_visibility_toggle ( gpointer lav[2] )
+static void trw_layer_routes_visibility_toggle ( menu_array_layer values )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+ 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) );
+}
+
+/**
+ * vik_trw_layer_build_waypoint_list_t:
+ *
+ * Helper function to construct a list of #vik_trw_waypoint_list_t
+ */
+GList *vik_trw_layer_build_waypoint_list_t ( VikTrwLayer *vtl, GList *waypoints )
+{
+ GList *waypoints_and_layers = NULL;
+ // build waypoints_and_layers list
+ while ( waypoints ) {
+ vik_trw_waypoint_list_t *vtdl = g_malloc (sizeof(vik_trw_waypoint_list_t));
+ vtdl->wpt = VIK_WAYPOINT(waypoints->data);
+ vtdl->vtl = vtl;
+ waypoints_and_layers = g_list_prepend ( waypoints_and_layers, vtdl );
+ waypoints = g_list_next ( waypoints );
+ }
+ return waypoints_and_layers;
+}
+
+/**
+ * trw_layer_create_waypoint_list:
+ *
+ * Create the latest list of waypoints with the associated layer(s)
+ * Although this will always be from a single layer here
+ */
+static GList* trw_layer_create_waypoint_list ( VikLayer *vl, gpointer user_data )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(vl);
+ GList *waypoints = g_hash_table_get_values ( vik_trw_layer_get_waypoints(vtl) );
+
+ return vik_trw_layer_build_waypoint_list_t ( vtl, waypoints );
+}
+
+/**
+ * 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;
+}
+
+/**
+ * vik_trw_layer_build_track_list_t:
+ *
+ * Helper function to construct a list of #vik_trw_track_list_t
+ */
+GList *vik_trw_layer_build_track_list_t ( VikTrwLayer *vtl, GList *tracks )
+{
+ GList *tracks_and_layers = NULL;
+ // build tracks_and_layers list
+ 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 );
+ }
+ return tracks_and_layers;
+}
+
+/**
+ * trw_layer_create_track_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_create_track_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) );
+
+ return vik_trw_layer_build_track_list_t ( vtl, tracks );
+}
+
+static void trw_layer_tracks_stats ( menu_array_layer values )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+ // 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_TRACKS),
+ trw_layer_create_track_list,
+ trw_layer_analyse_close );
+}
+
+/**
+ *
+ */
+static void trw_layer_routes_stats ( menu_array_layer values )
{
- 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) );
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+ // 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_create_track_list,
+ trw_layer_analyse_close );
}
-static void trw_layer_goto_waypoint ( gpointer pass_along[6] )
+static void trw_layer_goto_waypoint ( menu_array_sublayer values )
{
- VikWaypoint *wp = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->waypoints, pass_along[3] );
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+ VikWaypoint *wp = g_hash_table_lookup ( vtl->waypoints, values[MA_SUBLAYER_ID] );
if ( wp )
- goto_coord ( pass_along[1], pass_along[0], pass_along[5], &(wp->coord) );
+ goto_coord ( values[MA_VLP], vtl, values[MA_VVP], &(wp->coord) );
}
-static void trw_layer_waypoint_gc_webpage ( gpointer pass_along[6] )
+static void trw_layer_waypoint_gc_webpage ( menu_array_sublayer values )
{
- VikWaypoint *wp = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->waypoints, pass_along[3] );
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+ VikWaypoint *wp = g_hash_table_lookup ( vtl->waypoints, values[MA_SUBLAYER_ID] );
if ( !wp )
return;
gchar *webpage = g_strdup_printf("http://www.geocaching.com/seek/cache_details.aspx?wp=%s", wp->name );
- open_url(VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(pass_along[0])), webpage);
+ open_url(VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(vtl)), webpage);
g_free ( webpage );
}
-static void trw_layer_waypoint_webpage ( gpointer pass_along[6] )
+static void trw_layer_waypoint_webpage ( menu_array_sublayer values )
{
- VikWaypoint *wp = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->waypoints, pass_along[3] );
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+ VikWaypoint *wp = g_hash_table_lookup ( vtl->waypoints, values[MA_SUBLAYER_ID] );
if ( !wp )
return;
- if ( !strncmp(wp->comment, "http", 4) ) {
- open_url(VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(pass_along[0])), wp->comment);
+ if ( wp->url ) {
+ open_url(VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(vtl)), wp->url);
+ } else if ( !strncmp(wp->comment, "http", 4) ) {
+ open_url(VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(vtl)), wp->comment);
} else if ( !strncmp(wp->description, "http", 4) ) {
- open_url(VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(pass_along[0])), wp->description);
+ open_url(VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(vtl)), wp->description);
}
}
return len >= 3 && len <= 7 && str[0] == 'G' && str[1] == 'C' && isalnum(str[2]) && (len < 4 || isalnum(str[3])) && (len < 5 || isalnum(str[4])) && (len < 6 || isalnum(str[5])) && (len < 7 || isalnum(str[6]));
}
-static void trw_layer_track_use_with_filter ( gpointer pass_along[6] )
+static void trw_layer_track_use_with_filter ( menu_array_sublayer values )
{
- VikTrack *trk = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->tracks, pass_along[3] );
+ VikTrack *trk = g_hash_table_lookup ( VIK_TRW_LAYER(values[MA_VTL])->tracks, values[MA_SUBLAYER_ID] );
a_acquire_set_filter_track ( trk );
}
return ( tr && tr->comment && strlen(tr->comment) > 7 && !strncmp(tr->comment, "from:", 5) );
}
-static void trw_layer_google_route_webpage ( gpointer pass_along[6] )
+static void trw_layer_google_route_webpage ( menu_array_sublayer values )
{
- VikTrack *tr = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->routes, pass_along[3] );
+ VikTrack *tr = g_hash_table_lookup ( VIK_TRW_LAYER(values[MA_VTL])->routes, values[MA_SUBLAYER_ID] );
if ( tr ) {
gchar *escaped = uri_escape ( tr->comment );
gchar *webpage = g_strdup_printf("http://maps.google.com/maps?f=q&hl=en&q=%s", escaped );
- open_url(VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(pass_along[0])), webpage);
+ open_url(VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(values[MA_VTL])), webpage);
g_free ( escaped );
g_free ( webpage );
}
/* viewpoint is now available instead */
static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *menu, gpointer vlp, gint subtype, gpointer sublayer, GtkTreeIter *iter, VikViewport *vvp )
{
- static gpointer pass_along[8];
+ static menu_array_sublayer pass_along;
GtkWidget *item;
gboolean rv = FALSE;
- pass_along[0] = l;
- pass_along[1] = vlp;
- pass_along[2] = GINT_TO_POINTER (subtype);
- pass_along[3] = sublayer;
- pass_along[4] = GINT_TO_POINTER (1); // Confirm delete request
- pass_along[5] = vvp;
- pass_along[6] = iter;
- pass_along[7] = NULL; // For misc purposes - maybe track or waypoint
+ pass_along[MA_VTL] = l;
+ pass_along[MA_VLP] = vlp;
+ pass_along[MA_SUBTYPE] = GINT_TO_POINTER (subtype);
+ pass_along[MA_SUBLAYER_ID] = sublayer;
+ pass_along[MA_CONFIRM] = GINT_TO_POINTER (1); // Confirm delete request
+ pass_along[MA_VVP] = vvp;
+ pass_along[MA_TV_ITER] = iter;
+ pass_along[MA_MISC] = NULL; // For misc purposes - maybe track or waypoint
if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT || subtype == VIK_TRW_LAYER_SUBLAYER_TRACK || subtype == VIK_TRW_LAYER_SUBLAYER_ROUTE )
{
if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT )
{
- gboolean separator_created = FALSE;
+ // Always create separator as now there is always at least the transform menu option
+ item = gtk_menu_item_new ();
+ gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
+ gtk_widget_show ( item );
/* could be a right-click using the tool */
if ( vlp != NULL ) {
- item = gtk_menu_item_new ();
- gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
- gtk_widget_show ( item );
-
- separator_created = TRUE;
-
item = gtk_image_menu_item_new_with_mnemonic ( _("_Goto") );
- gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_JUMP_TO, GTK_ICON_SIZE_MENU) );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_JUMP_TO, GTK_ICON_SIZE_MENU) );
g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_goto_waypoint), pass_along );
gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
gtk_widget_show ( item );
if ( wp && wp->name ) {
if ( is_valid_geocache_name ( wp->name ) ) {
-
- if ( !separator_created ) {
- item = gtk_menu_item_new ();
- gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
- gtk_widget_show ( item );
- separator_created = TRUE;
- }
-
item = gtk_menu_item_new_with_mnemonic ( _("_Visit Geocache Webpage") );
g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_waypoint_gc_webpage), pass_along );
gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
gtk_widget_show ( item );
}
+#ifdef VIK_CONFIG_GEOTAG
+ item = gtk_menu_item_new_with_mnemonic ( _("Geotag _Images...") );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_geotagging_waypoint), pass_along );
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_set_tooltip_text (item, _("Geotag multiple images against this waypoint"));
+ gtk_widget_show ( item );
+#endif
}
if ( wp && wp->image )
{
- if ( !separator_created ) {
- item = gtk_menu_item_new ();
- gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
- gtk_widget_show ( item );
- separator_created = TRUE;
- }
-
- // Set up image paramater
- pass_along[5] = wp->image;
+ // Set up image paramater
+ pass_along[MA_MISC] = 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 );
if ( wp )
{
- if ( ( wp->comment && !strncmp(wp->comment, "http", 4) ) ||
+ if ( wp->url ||
+ ( wp->comment && !strncmp(wp->comment, "http", 4) ) ||
( wp->description && !strncmp(wp->description, "http", 4) )) {
item = gtk_image_menu_item_new_with_mnemonic ( _("Visit _Webpage") );
gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_NETWORK, GTK_ICON_SIZE_MENU) );
gtk_widget_show ( item );
}
}
-
}
}
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 );
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_List Waypoints...") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_INDEX, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_waypoint_list_dialog), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
}
if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACKS )
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 );
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_List Tracks...") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_INDEX, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_track_list_dialog_single), pass_along );
+ 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_tracks_stats), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
gtk_widget_show ( item );
}
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 );
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_List Routes...") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_INDEX, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_track_list_dialog_single), pass_along );
+ 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_routes_stats), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
gtk_widget_show ( item );
}
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") );
// Make it available only when a trackpoint is selected.
gtk_widget_set_sensitive ( item, (gboolean)GPOINTER_TO_INT(l->current_tpl) );
+ GtkWidget *insert_submenu = gtk_menu_new ();
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_Insert Points") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_MENU) );
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show ( item );
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), insert_submenu );
+
+ item = gtk_menu_item_new_with_mnemonic ( _("Insert Point _Before Selected Point") );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_insert_point_before), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(insert_submenu), item );
+ gtk_widget_show ( item );
+ // Make it available only when a point is selected
+ gtk_widget_set_sensitive ( item, (gboolean)GPOINTER_TO_INT(l->current_tpl) );
+
+ item = gtk_menu_item_new_with_mnemonic ( _("Insert Point _After Selected Point") );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_insert_point_after), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(insert_submenu), item );
+ gtk_widget_show ( item );
+ // Make it available only when a point is selected
+ gtk_widget_set_sensitive ( item, (gboolean)GPOINTER_TO_INT(l->current_tpl) );
+
GtkWidget *delete_submenu;
delete_submenu = gtk_menu_new ();
item = gtk_image_menu_item_new_with_mnemonic ( _("Delete Poi_nts") );
gtk_widget_show ( item );
gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), delete_submenu );
+ item = gtk_image_menu_item_new_with_mnemonic ( _("Delete _Selected Point") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_DELETE, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_delete_point_selected), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(delete_submenu), item );
+ gtk_widget_show ( item );
+ // Make it available only when a point is selected
+ gtk_widget_set_sensitive ( item, (gboolean)GPOINTER_TO_INT(l->current_tpl) );
+
item = gtk_menu_item_new_with_mnemonic ( _("Delete Points With The Same _Position") );
g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_delete_points_same_position), pass_along );
gtk_menu_shell_append ( GTK_MENU_SHELL(delete_submenu), item );
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 );
-
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 );
}
}
+ // Only made available if a suitable program is installed
+ if ( have_diary_program ) {
+ if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK || subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT ) {
+ item = gtk_image_menu_item_new_with_mnemonic ( _("Diar_y") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_SPELL_CHECK, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_diary), 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 && is_valid_google_route ( l, sublayer ) )
{
if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK ) {
#ifdef VIK_CONFIG_OPENSTREETMAP
item = gtk_image_menu_item_new_with_mnemonic ( _("Upload to _OSM...") );
- // Convert internal pointer into actual track for usage outside this file
- pass_along[7] = g_hash_table_lookup ( l->tracks, sublayer);
+ // Convert internal pointer into track
+ pass_along[MA_MISC] = g_hash_table_lookup ( l->tracks, sublayer);
gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_GO_UP, GTK_ICON_SIZE_MENU) );
- g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(osm_traces_upload_track_cb), pass_along );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_osm_traces_upload_track_cb), pass_along );
gtk_menu_shell_append ( GTK_MENU_SHELL(upload_submenu), item );
gtk_widget_show ( item );
#endif
}
}
+ 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;
}
-static void trw_layer_insert_tp_after_current_tp ( VikTrwLayer *vtl )
+// TODO: Probably better to rework this track manipulation in viktrack.c
+static void trw_layer_insert_tp_beside_current_tp ( VikTrwLayer *vtl, gboolean before )
{
- /* sanity checks */
+ // sanity check
if (!vtl->current_tpl)
return;
- if (!vtl->current_tpl->next)
- return;
VikTrackpoint *tp_current = VIK_TRACKPOINT(vtl->current_tpl->data);
- VikTrackpoint *tp_next = VIK_TRACKPOINT(vtl->current_tpl->next->data);
+ VikTrackpoint *tp_other = NULL;
+
+ if ( before ) {
+ if (!vtl->current_tpl->prev)
+ return;
+ tp_other = VIK_TRACKPOINT(vtl->current_tpl->prev->data);
+ } else {
+ if (!vtl->current_tpl->next)
+ return;
+ tp_other = VIK_TRACKPOINT(vtl->current_tpl->next->data);
+ }
- /* Use current and next trackpoints to form a new track point which is inserted into the tracklist */
- if ( tp_next ) {
+ // Use current and other trackpoints to form a new track point which is inserted into the tracklist
+ if ( tp_other ) {
VikTrackpoint *tp_new = vik_trackpoint_new();
- struct LatLon ll_current, ll_next;
+ struct LatLon ll_current, ll_other;
vik_coord_to_latlon ( &tp_current->coord, &ll_current );
- vik_coord_to_latlon ( &tp_next->coord, &ll_next );
+ vik_coord_to_latlon ( &tp_other->coord, &ll_other );
/* main positional interpolation */
- struct LatLon ll_new = { (ll_current.lat+ll_next.lat)/2, (ll_current.lon+ll_next.lon)/2 };
+ struct LatLon ll_new = { (ll_current.lat+ll_other.lat)/2, (ll_current.lon+ll_other.lon)/2 };
vik_coord_load_from_latlon ( &(tp_new->coord), vtl->coord_mode, &ll_new );
/* Now other properties that can be interpolated */
- tp_new->altitude = (tp_current->altitude + tp_next->altitude) / 2;
+ tp_new->altitude = (tp_current->altitude + tp_other->altitude) / 2;
- if (tp_current->has_timestamp && tp_next->has_timestamp) {
+ if (tp_current->has_timestamp && tp_other->has_timestamp) {
/* Note here the division is applied to each part, then added
This is to avoid potential overflow issues with a 32 time_t for dates after midpoint of this Unix time on 2004/01/04 */
- tp_new->timestamp = (tp_current->timestamp/2) + (tp_next->timestamp/2);
+ tp_new->timestamp = (tp_current->timestamp/2) + (tp_other->timestamp/2);
tp_new->has_timestamp = TRUE;
}
- if (tp_current->speed != NAN && tp_next->speed != NAN)
- tp_new->speed = (tp_current->speed + tp_next->speed)/2;
+ if (tp_current->speed != NAN && tp_other->speed != NAN)
+ tp_new->speed = (tp_current->speed + tp_other->speed)/2;
/* TODO - improve interpolation of course, as it may not be correct.
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;
+ if (tp_current->course != NAN && tp_other->course != NAN)
+ tp_new->course = (tp_current->course + tp_other->course)/2;
/* DOP / sat values remain at defaults as not they do not seem applicable to a dreamt up point */
- /* Insert new point into the trackpoints list after the current TP */
+ // Insert new point into the appropriate trackpoint list, either before or after the current trackpoint as directed
VikTrack *trk = g_hash_table_lookup ( vtl->tracks, vtl->current_tp_id );
if ( !trk )
// Otherwise try routes
gint index = g_list_index ( trk->trackpoints, tp_current );
if ( index > -1 ) {
+ if ( !before )
+ index = index + 1;
// NB no recalculation of bounds since it is inserted between points
- trk->trackpoints = g_list_insert ( trk->trackpoints, tp_new, index+1 );
+ trk->trackpoints = g_list_insert ( trk->trackpoints, tp_new, index );
}
}
}
if ( tr == NULL )
return;
- GList *new_tpl;
-
- // Find available adjacent trackpoint
- if ( (new_tpl = vtl->current_tpl->next) || (new_tpl = vtl->current_tpl->prev) )
- {
- if ( VIK_TRACKPOINT(vtl->current_tpl->data)->newsegment && vtl->current_tpl->next )
- VIK_TRACKPOINT(vtl->current_tpl->next->data)->newsegment = TRUE; /* don't concat segments on del */
-
- // Delete current trackpoint
- vik_trackpoint_free ( vtl->current_tpl->data );
- tr->trackpoints = g_list_delete_link ( tr->trackpoints, vtl->current_tpl );
-
- // Set to current to the available adjacent trackpoint
- vtl->current_tpl = new_tpl;
+ trw_layer_trackpoint_selected_delete ( vtl, tr );
+ if ( vtl->current_tpl )
// Reset dialog with the available adjacent trackpoint
- 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_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name );
- vik_layer_emit_update(VIK_LAYER(vtl));
- }
- else
- {
- // Delete current trackpoint
- vik_trackpoint_free ( vtl->current_tpl->data );
- tr->trackpoints = g_list_delete_link ( tr->trackpoints, vtl->current_tpl );
- trw_layer_cancel_current_tp ( vtl, FALSE );
- }
+ vik_layer_emit_update(VIK_LAYER(vtl));
}
else if ( response == VIK_TRW_LAYER_TPWIN_FORWARD && vtl->current_tpl->next )
{
}
else if ( response == VIK_TRW_LAYER_TPWIN_INSERT && vtl->current_tpl->next )
{
- trw_layer_insert_tp_after_current_tp ( vtl );
+ trw_layer_insert_tp_beside_current_tp ( vtl, FALSE );
vik_layer_emit_update(VIK_LAYER(vtl));
}
else if ( response == VIK_TRW_LAYER_TPWIN_DATA_CHANGED )
{
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 );
// Determine if working on a waypoint or a trackpoint
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 ) {
if ( vtl->current_tp_track )
vik_track_calculate_bounds ( vtl->current_tp_track );
- if ( vtl->tpwin )
+ 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;
}
vtl->current_wp = wp_params.closest_wp;
vtl->current_wp_id = wp_params.closest_wp_id;
+ if ( event->type == GDK_2BUTTON_PRESS ) {
+ if ( vtl->current_wp->image ) {
+ menu_array_sublayer values;
+ values[MA_VTL] = vtl;
+ values[MA_MISC] = vtl->current_wp->image;
+ trw_layer_show_picture ( values );
+ }
+ }
+
vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
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) {
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.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;
g_hash_table_foreach ( vtl->waypoints, (GHFunc) waypoint_search_closest_tp, ¶ms);
- if ( vtl->current_wp == params.closest_wp && vtl->current_wp != NULL )
+ if ( vtl->current_wp && (vtl->current_wp == params.closest_wp) )
{
- // how do we get here?
- marker_begin_move(t, event->x, event->y);
- g_critical("shouldn't be here");
+ if ( event->button == 3 )
+ vtl->waypoint_rightclick = TRUE; /* remember that we're clicking; other layers will ignore release signal */
+ else
+ marker_begin_move(t, event->x, event->y);
return FALSE;
}
else if ( params.closest_wp )
ds->vtl->draw_sync_done = TRUE;
gdk_threads_leave();
}
+ g_free ( ds );
return FALSE;
}
{
/* if we haven't sync'ed yet, we don't have time to do more. */
if ( vtl->draw_sync_done && vtl->current_track && vtl->current_track->trackpoints ) {
- GList *iter = g_list_last ( vtl->current_track->trackpoints );
- VikTrackpoint *last_tpt = VIK_TRACKPOINT(iter->data);
+ VikTrackpoint *last_tpt = vik_track_get_tp_last(vtl->current_track);
static GdkPixmap *pixmap = NULL;
int w1, h1, w2, h2;
return VIK_LAYER_TOOL_ACK;
}
+// NB vtl->current_track must be valid
+static void undo_trackpoint_add ( VikTrwLayer *vtl )
+{
+ // 'undo'
+ if ( vtl->current_track->trackpoints ) {
+ // TODO rework this...
+ //vik_trackpoint_free ( vik_track_get_tp_last (vtl->current_track) );
+ GList *last = g_list_last(vtl->current_track->trackpoints);
+ g_free ( last->data );
+ vtl->current_track->trackpoints = g_list_remove_link ( vtl->current_track->trackpoints, last );
+
+ vik_track_calculate_bounds ( vtl->current_track );
+ }
+}
+
static gboolean tool_new_track_key_press ( VikTrwLayer *vtl, GdkEventKey *event, VikViewport *vvp )
{
if ( vtl->current_track && event->keyval == GDK_Escape ) {
vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
} else if ( vtl->current_track && event->keyval == GDK_BackSpace ) {
- /* undo */
- if ( vtl->current_track->trackpoints )
- {
- GList *last = g_list_last(vtl->current_track->trackpoints);
- g_free ( last->data );
- vtl->current_track->trackpoints = g_list_remove_link ( vtl->current_track->trackpoints, last );
- }
-
+ undo_trackpoint_add ( vtl );
update_statusbar ( vtl );
-
vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
}
{
if ( !vtl->current_track )
return FALSE;
- /* undo */
- if ( vtl->current_track->trackpoints )
- {
- GList *last = g_list_last(vtl->current_track->trackpoints);
- g_free ( last->data );
- vtl->current_track->trackpoints = g_list_remove_link ( vtl->current_track->trackpoints, last );
- }
- vik_track_calculate_bounds ( vtl->current_track );
+ undo_trackpoint_add ( vtl );
update_statusbar ( vtl );
-
vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
}
/* subtract last (duplicate from double click) tp then end */
if ( vtl->current_track && vtl->current_track->trackpoints && vtl->ct_x1 == vtl->ct_x2 && vtl->ct_y1 == vtl->ct_y2 )
{
- GList *last = g_list_last(vtl->current_track->trackpoints);
- g_free ( last->data );
- vtl->current_track->trackpoints = g_list_remove_link ( vtl->current_track->trackpoints, last );
/* undo last, then end */
+ undo_trackpoint_add ( vtl );
vtl->current_track = NULL;
}
vik_layer_emit_update ( VIK_LAYER(vtl) );
static gboolean tool_new_track_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
{
+ // if we were running the route finder, cancel it
+ vtl->route_finder_started = FALSE;
+
// ----------------------------------------------------- if current is a route - switch to new 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;
static gboolean tool_new_route_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
{
- // -------------------------- if current is a track - switch to new route
- if ( event->button == 1 && ( ! vtl->current_track || (vtl->current_track && !vtl->current_track->is_route ) ) )
+ // if we were running the route finder, cancel it
+ vtl->route_finder_started = FALSE;
+
+ // -------------------------- if current is a track - switch to new route,
+ 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;
}
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 )
}
-/*** Route Finder ***/
-static gpointer tool_route_finder_create ( VikWindow *vw, VikViewport *vvp)
+/*** Extended Route Finder ***/
+
+static gpointer tool_extended_route_finder_create ( VikWindow *vw, VikViewport *vvp)
{
return vvp;
}
-static gboolean tool_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
+static void tool_extended_route_finder_undo ( VikTrwLayer *vtl )
+{
+ VikCoord *new_end;
+ new_end = vik_track_cut_back_to_double_point ( vtl->current_track );
+ if ( new_end ) {
+ g_free ( new_end );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+
+ /* remove last ' to:...' */
+ if ( vtl->current_track->comment ) {
+ gchar *last_to = strrchr ( vtl->current_track->comment, 't' );
+ if ( last_to && (last_to - vtl->current_track->comment > 1) ) {
+ gchar *new_comment = g_strndup ( vtl->current_track->comment,
+ last_to - vtl->current_track->comment - 1);
+ vik_track_set_comment_no_copy ( vtl->current_track, new_comment );
+ }
+ }
+ }
+}
+
+
+static gboolean tool_extended_route_finder_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
{
VikCoord tmp;
if ( !vtl ) return FALSE;
vik_viewport_screen_to_coord ( vvp, event->x, event->y, &tmp );
- if ( event->button == 3 && vtl->route_finder_current_track ) {
- VikCoord *new_end;
- new_end = vik_track_cut_back_to_double_point ( vtl->route_finder_current_track );
- if ( new_end ) {
- vtl->route_finder_coord = *new_end;
- g_free ( new_end );
- vik_layer_emit_update ( VIK_LAYER(vtl) );
- /* remove last ' to:...' */
- if ( vtl->route_finder_current_track->comment ) {
- gchar *last_to = strrchr ( vtl->route_finder_current_track->comment, 't' );
- if ( last_to && (last_to - vtl->route_finder_current_track->comment > 1) ) {
- gchar *new_comment = g_strndup ( vtl->route_finder_current_track->comment,
- last_to - vtl->route_finder_current_track->comment - 1);
- vik_track_set_comment_no_copy ( vtl->route_finder_current_track, new_comment );
- }
- }
- }
+ if ( event->button == 3 && vtl->current_track ) {
+ tool_extended_route_finder_undo ( vtl );
+ }
+ else if ( event->button == 2 ) {
+ vtl->draw_sync_do = FALSE;
+ return FALSE;
+ }
+ // if we started the track but via undo deleted all the track points, begin again
+ else if ( vtl->current_track && vtl->current_track->is_route && ! vik_track_get_tp_first ( vtl->current_track ) ) {
+ return tool_new_track_or_route_click ( vtl, event, vvp );
}
- else if ( vtl->route_finder_started || (event->state & GDK_CONTROL_MASK && vtl->route_finder_current_track) ) {
+ else if ( ( vtl->current_track && vtl->current_track->is_route ) ||
+ ( event->state & GDK_CONTROL_MASK && vtl->current_track ) ) {
struct LatLon start, end;
- vik_coord_to_latlon ( &(vtl->route_finder_coord), &start );
+ VikTrackpoint *tp_start = vik_track_get_tp_last ( vtl->current_track );
+ vik_coord_to_latlon ( &(tp_start->coord), &start );
vik_coord_to_latlon ( &(tmp), &end );
- vtl->route_finder_coord = tmp; /* for continuations */
- /* these are checked when adding a track from a file (vik_trw_layer_filein_add_track) */
- if ( event->state & GDK_CONTROL_MASK && vtl->route_finder_current_track ) {
- vtl->route_finder_append = TRUE; // merge tracks. keep started true.
- } else {
- vtl->route_finder_check_added_track = TRUE;
- vtl->route_finder_started = FALSE;
+ vtl->route_finder_started = TRUE;
+ vtl->route_finder_append = TRUE; // merge tracks. keep started true.
+
+ // update UI to let user know what's going on
+ VikStatusbar *sb = vik_window_get_statusbar (VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)));
+ VikRoutingEngine *engine = vik_routing_default_engine ( );
+ if ( ! engine ) {
+ vik_statusbar_set_message ( sb, VIK_STATUSBAR_INFO, "Cannot plan route without a default routing engine." );
+ return TRUE;
}
+ gchar *msg = g_strdup_printf ( _("Querying %s for route between (%.3f, %.3f) and (%.3f, %.3f)."),
+ vik_routing_engine_get_label ( engine ),
+ start.lat, start.lon, end.lat, end.lon );
+ vik_statusbar_set_message ( sb, VIK_STATUSBAR_INFO, msg );
+ g_free ( msg );
+ vik_window_set_busy_cursor ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)) );
- 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 ) {
- vik_track_set_comment_no_copy ( vtl->route_finder_added_track, g_strdup_printf("from: %f,%f to: %f,%f", start.lat, start.lon, end.lat, end.lon ) );
- } else if ( vtl->route_finder_append == FALSE && vtl->route_finder_current_track ) {
- /* route_finder_append was originally TRUE but set to FALSE by filein_add_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 );
- }
+ /* Give GTK a change to display the new status bar before querying the web */
+ while ( gtk_events_pending ( ) )
+ gtk_main_iteration ( );
- if ( vtl->route_finder_added_track )
- vik_track_calculate_bounds ( vtl->route_finder_added_track );
+ gboolean find_status = vik_routing_default_find ( vtl, start, end );
- vtl->route_finder_added_track = NULL;
- vtl->route_finder_check_added_track = FALSE;
- vtl->route_finder_append = FALSE;
+ /* Update UI to say we're done */
+ vik_window_clear_busy_cursor ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)) );
+ msg = ( find_status ) ? g_strdup_printf ( _("%s returned route between (%.3f, %.3f) and (%.3f, %.3f)."),
+ vik_routing_engine_get_label ( engine ),
+ start.lat, start.lon, end.lat, end.lon )
+ : g_strdup_printf ( _("Error getting route from %s."),
+ vik_routing_engine_get_label ( engine ) );
+ vik_statusbar_set_message ( sb, VIK_STATUSBAR_INFO, msg );
+ g_free ( msg );
vik_layer_emit_update ( VIK_LAYER(vtl) );
} else {
+ vtl->current_track = NULL;
+
+ // create a new route where we will add the planned route to
+ gboolean ret = tool_new_route_click( vtl, event, vvp );
+
vtl->route_finder_started = TRUE;
- vtl->route_finder_coord = tmp;
- vtl->route_finder_current_track = NULL;
+
+ return ret;
}
return TRUE;
}
+static gboolean tool_extended_route_finder_key_press ( VikTrwLayer *vtl, GdkEventKey *event, VikViewport *vvp )
+{
+ if ( vtl->current_track && event->keyval == GDK_Escape ) {
+ vtl->route_finder_started = FALSE;
+ vtl->current_track = NULL;
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+ return TRUE;
+ } else if ( vtl->current_track && event->keyval == GDK_BackSpace ) {
+ tool_extended_route_finder_undo ( vtl );
+ }
+ return FALSE;
+}
+
+
+
/*** Show picture ****/
static gpointer tool_show_picture_create ( VikWindow *vw, VikViewport *vvp)
}
}
-static void trw_layer_show_picture ( gpointer pass_along[6] )
+static void trw_layer_show_picture ( menu_array_sublayer values )
{
/* thanks to the Gaim people for showing me ShellExecute and g_spawn_command_line_async */
#ifdef WINDOWS
- ShellExecute(NULL, "open", (char *) pass_along[5], NULL, NULL, SW_SHOWNORMAL);
+ ShellExecute(NULL, "open", (char *) values[MA_MISC], NULL, NULL, SW_SHOWNORMAL);
#else /* WINDOWS */
GError *err = NULL;
- gchar *quoted_file = g_shell_quote ( (gchar *) pass_along[5] );
+ gchar *quoted_file = g_shell_quote ( (gchar *) values[MA_MISC] );
gchar *cmd = g_strdup_printf ( "%s %s", a_vik_get_image_viewer(), quoted_file );
g_free ( quoted_file );
if ( ! g_spawn_command_line_async ( cmd, &err ) )
{
- a_dialog_error_msg_extra ( VIK_GTK_WINDOW_FROM_LAYER( pass_along[0]), _("Could not launch %s to open file."), a_vik_get_image_viewer() );
+ a_dialog_error_msg_extra ( VIK_GTK_WINDOW_FROM_LAYER(values[MA_VTL]), _("Could not launch %s to open file."), a_vik_get_image_viewer() );
g_error_free ( err );
}
g_free ( cmd );
g_hash_table_foreach ( vtl->waypoints, (GHFunc) tool_show_picture_wp, params );
if ( params[2] )
{
- static gpointer pass_along[6];
- pass_along[0] = vtl;
- pass_along[5] = params[2];
- trw_layer_show_picture ( pass_along );
+ static menu_array_sublayer values;
+ values[MA_VTL] = vtl;
+ values[MA_MISC] = params[2];
+ trw_layer_show_picture ( values );
return TRUE; /* found a match */
}
else
VIK_TRACK(value)->has_color = TRUE;
}
- trw_layer_update_treeview ( vtl, VIK_TRACK(value), key );
+ trw_layer_update_treeview ( vtl, VIK_TRACK(value) );
ii++;
if (ii > VIK_TRW_LAYER_TRACK_GCS)
VIK_TRACK(value)->has_color = TRUE;
}
- trw_layer_update_treeview ( vtl, VIK_TRACK(value), key );
+ trw_layer_update_treeview ( vtl, VIK_TRACK(value) );
ii = !ii;
}
* (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 )
+void trw_layer_calculate_bounds_waypoints ( VikTrwLayer *vtl )
{
struct LatLon topleft = { 0.0, 0.0 };
struct LatLon bottomright = { 0.0, 0.0 };
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 );
static void trw_layer_post_read ( VikTrwLayer *vtl, GtkWidget *vvp, gboolean from_file )
{
- trw_layer_verify_thumbnails ( vtl, vvp );
+ if ( VIK_LAYER(vtl)->realized )
+ trw_layer_verify_thumbnails ( vtl, vvp );
trw_layer_track_alloc_colors ( vtl );
trw_layer_calculate_bounds_waypoints ( vtl );
// 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 );
+
+ // Setting metadata time if not otherwise set
+ if ( vtl->metadata ) {
+
+ gboolean need_to_set_time = TRUE;
+ if ( vtl->metadata->timestamp ) {
+ need_to_set_time = FALSE;
+ if ( !g_strcmp0(vtl->metadata->timestamp, "" ) )
+ need_to_set_time = TRUE;
+ }
+
+ if ( need_to_set_time ) {
+ // Could rewrite this as a general get first time of a TRW Layer function
+ GTimeVal timestamp;
+ timestamp.tv_usec = 0;
+ gboolean has_timestamp = FALSE;
+
+ GList *gl = NULL;
+ gl = g_hash_table_get_values ( vtl->tracks );
+ gl = g_list_sort ( gl, vik_track_compare_timestamp );
+ gl = g_list_first ( gl );
+
+ // Check times of tracks
+ if ( gl ) {
+ // Only need to check the first track as they have been sorted by time
+ VikTrack *trk = (VikTrack*)gl->data;
+ // Assume trackpoints already sorted by time
+ VikTrackpoint *tpt = vik_track_get_tp_first(trk);
+ if ( tpt && tpt->has_timestamp ) {
+ timestamp.tv_sec = tpt->timestamp;
+ has_timestamp = TRUE;
+ }
+ g_list_free ( gl );
+ }
+
+ if ( !has_timestamp ) {
+ // 'Last' resort - current time
+ // Get before waypoint tests - so that if a waypoint time value (in the past) is found it should be used
+ g_get_current_time ( ×tamp );
+
+ // Check times of waypoints
+ gl = g_hash_table_get_values ( vtl->waypoints );
+ GList *iter;
+ for (iter = g_list_first (gl); iter != NULL; iter = g_list_next (iter)) {
+ VikWaypoint *wpt = (VikWaypoint*)iter->data;
+ if ( wpt->has_timestamp ) {
+ if ( timestamp.tv_sec > wpt->timestamp ) {
+ timestamp.tv_sec = wpt->timestamp;
+ has_timestamp = TRUE;
+ }
+ }
+ }
+ g_list_free ( gl );
+ }
+
+ vtl->metadata->timestamp = g_time_val_to_iso8601 ( ×tamp );
+ }
+ }
}
VikCoordMode vik_trw_layer_get_coord_mode ( VikTrwLayer *vtl )
g_message("%s: this feature works only in Mercator mode", __FUNCTION__);
if (fillins) {
- GList *iter = fillins;
- while (iter) {
- cur_coord = (VikCoord *)(iter->data);
+ GList *fiter = fillins;
+ while (fiter) {
+ cur_coord = (VikCoord *)(fiter->data);
vik_coord_set_area(cur_coord, &wh, &tl, &br);
rect = g_malloc(sizeof(Rect));
rect->tl = tl;
rect->br = br;
rect->center = *cur_coord;
rects_to_download = g_list_prepend(rects_to_download, rect);
- iter = iter->next;
+ fiter = fiter->next;
}
}
}
}
-static void trw_layer_download_map_along_track_cb ( gpointer pass_along[6] )
+static void trw_layer_download_map_along_track_cb ( menu_array_sublayer values )
{
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];
+ VikTrwLayer *vtl = values[MA_VTL];
+ VikLayersPanel *vlp = values[MA_VLP];
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] );
+ if ( GPOINTER_TO_INT (values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_ROUTE )
+ trk = (VikTrack *) g_hash_table_lookup ( vtl->routes, values[MA_SUBLAYER_ID] );
else
- trk = (VikTrack *) g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+ trk = (VikTrack *) g_hash_table_lookup ( vtl->tracks, values[MA_SUBLAYER_ID] );
if ( !trk )
return;
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]);
g_snprintf(buf,4,"%03d", vtl->highest_wp_number+1 );
return g_strdup(buf);
}
+
+/**
+ * trw_layer_create_track_list_both:
+ *
+ * Create the latest list of tracks and routes
+ */
+static GList* trw_layer_create_track_list_both ( VikLayer *vl, gpointer user_data )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(vl);
+ GList *tracks = NULL;
+ tracks = g_list_concat ( tracks, g_hash_table_get_values ( vik_trw_layer_get_tracks ( vtl ) ) );
+ tracks = g_list_concat ( tracks, g_hash_table_get_values ( vik_trw_layer_get_routes ( vtl ) ) );
+
+ return vik_trw_layer_build_track_list_t ( vtl, tracks );
+}
+
+static void trw_layer_track_list_dialog_single ( menu_array_sublayer values )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+
+ gchar *title = NULL;
+ if ( GPOINTER_TO_INT(values[MA_SUBTYPE]) == VIK_TRW_LAYER_SUBLAYER_TRACKS )
+ title = g_strdup_printf ( _("%s: Track List"), VIK_LAYER(vtl)->name );
+ else
+ title = g_strdup_printf ( _("%s: Route List"), VIK_LAYER(vtl)->name );
+
+ vik_trw_layer_track_list_show_dialog ( title, VIK_LAYER(vtl), values[MA_SUBTYPE], trw_layer_create_track_list, FALSE );
+ g_free ( title );
+}
+
+static void trw_layer_track_list_dialog ( menu_array_layer values )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+
+ gchar *title = g_strdup_printf ( _("%s: Track and Route List"), VIK_LAYER(vtl)->name );
+ vik_trw_layer_track_list_show_dialog ( title, VIK_LAYER(vtl), NULL, trw_layer_create_track_list_both, FALSE );
+ g_free ( title );
+}
+
+static void trw_layer_waypoint_list_dialog ( menu_array_layer values )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
+
+ gchar *title = g_strdup_printf ( _("%s: Waypoint List"), VIK_LAYER(vtl)->name );
+ vik_trw_layer_waypoint_list_show_dialog ( title, VIK_LAYER(vtl), NULL, trw_layer_create_waypoint_list, FALSE );
+ g_free ( title );
+}