X-Git-Url: https://git.street.me.uk/andy/viking.git/blobdiff_plain/07c9d42b37ca6cd48ddfaf48b40dd5d8e0502bdd..7a7ba2f18eb800222454692507c7bc688e533091:/src/viktrwlayer.c diff --git a/src/viktrwlayer.c b/src/viktrwlayer.c index d5c7abc8..aa7d08e0 100644 --- a/src/viktrwlayer.c +++ b/src/viktrwlayer.c @@ -37,6 +37,7 @@ #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" @@ -262,8 +263,6 @@ static void trw_layer_free_track_gcs ( VikTrwLayer *vtl ); 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] ); @@ -312,6 +311,7 @@ static void trw_layer_geotagging ( gpointer lav[2] ); #endif static void trw_layer_acquire_gps_cb ( gpointer lav[2] ); static void trw_layer_acquire_routing_cb ( gpointer lav[2] ); +static void trw_layer_acquire_url_cb ( gpointer lav[2] ); #ifdef VIK_CONFIG_OPENSTREETMAP static void trw_layer_acquire_osm_cb ( gpointer lav[2] ); static void trw_layer_acquire_osm_my_traces_cb ( gpointer lav[2] ); @@ -327,6 +327,7 @@ static void trw_layer_gps_upload ( gpointer lav[2] ); static void trw_layer_track_list_dialog_single ( gpointer pass_along[6] ); static void trw_layer_track_list_dialog ( gpointer lav[2] ); +static void trw_layer_waypoint_list_dialog ( gpointer lav[2] ); // Specific route versions: // Most track handling functions can handle operating on the route list @@ -661,6 +662,7 @@ static void trw_layer_marshall ( VikTrwLayer *vtl, guint8 **data, gint *len ); 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 ); @@ -715,6 +717,7 @@ VikLayerInterface vik_trw_layer_interface = { (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, @@ -1107,6 +1110,75 @@ static VikLayerParamData trw_layer_get_param ( VikTrwLayer *vtl, guint16 id, gbo 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; + } + // 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; @@ -2258,7 +2330,7 @@ static VikTrwLayer* trw_layer_create ( VikViewport *vp ) /* * 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. @@ -2648,7 +2720,7 @@ static void set_statusbar_msg_info_trkpt ( VikTrwLayer *vtl, VikTrackpoint *trkp gboolean need2free = FALSE; if ( !a_settings_get_string ( VIK_SETTINGS_TRKPT_SELECTED_STATUSBAR_FORMAT, &statusbar_format_code ) ) { // Otherwise use default - statusbar_format_code = g_strdup ( "KATDN" ); + statusbar_format_code = g_strdup ( "KEATDN" ); need2free = TRUE; } @@ -3032,7 +3104,8 @@ static void trw_layer_export ( gpointer layer_and_vlp[2], const gchar *title, co 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 ) + if ( g_file_test ( fn, G_FILE_TEST_EXISTS ) == FALSE || + 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])) ); @@ -3040,17 +3113,6 @@ static void trw_layer_export ( gpointer layer_and_vlp[2], const gchar *title, co 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 ) @@ -3158,17 +3220,17 @@ static void trw_layer_export_gpx_track ( gpointer pass_along[6] ) if ( ! check_file_ext ( auto_save_name, ".gpx" ) ) auto_save_name = g_strconcat ( auto_save_name, ".gpx", NULL ); - trw_layer_export ( layer_and_vlp, _("Export Track as GPX"), auto_save_name, trk, FILE_TYPE_GPX ); + gchar *label = NULL; + if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_ROUTE ) + label = _("Export Route as GPX"); + else + label = _("Export Track as GPX"); + trw_layer_export ( layer_and_vlp, 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 ) { @@ -3316,9 +3378,20 @@ static void trw_layer_geotagging_track ( gpointer pass_along[6] ) 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 ( gpointer pass_along[6] ) +{ + VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]); + VikWaypoint *wpt = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->waypoints, pass_along[3] ); + + trw_layer_geotag_dialog ( VIK_GTK_WINDOW_FROM_LAYER(vtl), + vtl, + wpt, + NULL ); } static void trw_layer_geotagging ( gpointer lav[2] ) @@ -3328,26 +3401,31 @@ static void trw_layer_geotagging ( gpointer lav[2] ) 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 ( gpointer lav[2], VikDataSourceInterface *datasource ) { 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, datasource, NULL, NULL ); +} + +/* + * Acquire into this TRW Layer straight from GPS Device + */ +static void trw_layer_acquire_gps_cb ( gpointer lav[2] ) +{ vik_datasource_gps_interface.mode = VIK_DATASOURCE_ADDTOLAYER; - a_acquire ( vw, vlp, vvp, &vik_datasource_gps_interface, NULL, NULL ); + trw_layer_acquire ( lav, &vik_datasource_gps_interface ); } /* @@ -3355,12 +3433,16 @@ static void trw_layer_acquire_gps_cb ( gpointer lav[2] ) */ static void trw_layer_acquire_routing_cb ( gpointer lav[2] ) { - VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]); - VikLayersPanel *vlp = VIK_LAYERS_PANEL(lav[1]); - VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl)); - VikViewport *vvp = vik_window_viewport(vw); + trw_layer_acquire ( lav, &vik_datasource_routing_interface ); +} - a_acquire ( vw, vlp, vvp, &vik_datasource_routing_interface, NULL, NULL ); +/* + * Acquire into this TRW Layer from an entered URL + */ +static void trw_layer_acquire_url_cb ( gpointer lav[2] ) +{ + vik_datasource_url_interface.mode = VIK_DATASOURCE_ADDTOLAYER; + trw_layer_acquire ( lav, &vik_datasource_url_interface ); } #ifdef VIK_CONFIG_OPENSTREETMAP @@ -3369,12 +3451,7 @@ static void trw_layer_acquire_routing_cb ( gpointer lav[2] ) */ static void trw_layer_acquire_osm_cb ( gpointer lav[2] ) { - VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]); - VikLayersPanel *vlp = VIK_LAYERS_PANEL(lav[1]); - VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl)); - VikViewport *vvp = vik_window_viewport(vw); - - a_acquire ( vw, vlp, vvp, &vik_datasource_osm_interface, NULL, NULL ); + trw_layer_acquire ( lav, &vik_datasource_osm_interface ); } /** @@ -3382,12 +3459,7 @@ static void trw_layer_acquire_osm_cb ( gpointer lav[2] ) */ static void trw_layer_acquire_osm_my_traces_cb ( gpointer lav[2] ) { - VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]); - VikLayersPanel *vlp = VIK_LAYERS_PANEL(lav[1]); - VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl)); - VikViewport *vvp = vik_window_viewport(vw); - - a_acquire ( vw, vlp, vvp, &vik_datasource_osm_my_traces_interface, NULL, NULL ); + trw_layer_acquire ( lav, &vik_datasource_osm_my_traces_interface ); } #endif @@ -3397,12 +3469,7 @@ static void trw_layer_acquire_osm_my_traces_cb ( gpointer lav[2] ) */ static void trw_layer_acquire_geocache_cb ( gpointer lav[2] ) { - VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]); - VikLayersPanel *vlp = VIK_LAYERS_PANEL(lav[1]); - VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl)); - VikViewport *vvp = vik_window_viewport(vw); - - a_acquire ( vw, vlp, vvp, &vik_datasource_gc_interface, NULL, NULL ); + trw_layer_acquire ( lav, &vik_datasource_gc_interface ); } #endif @@ -3413,12 +3480,9 @@ static void trw_layer_acquire_geocache_cb ( gpointer lav[2] ) static void trw_layer_acquire_geotagged_cb ( gpointer lav[2] ) { VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]); - VikLayersPanel *vlp = VIK_LAYERS_PANEL(lav[1]); - VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl)); - VikViewport *vvp = vik_window_viewport(vw); vik_datasource_geotag_interface.mode = VIK_DATASOURCE_ADDTOLAYER; - a_acquire ( vw, vlp, vvp, &vik_datasource_geotag_interface, NULL, NULL ); + trw_layer_acquire ( lav, &vik_datasource_geotag_interface ); // Reverify thumbnails as they may have changed vtl->has_verified_thumbnails = FALSE; @@ -3768,14 +3832,14 @@ static void trw_layer_add_menu_items ( VikTrwLayer *vtl, GtkMenu *menu, gpointer 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 ); + 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 ); @@ -3848,6 +3912,11 @@ static void trw_layer_add_menu_items ( VikTrwLayer *vtl, GtkMenu *menu, gpointer 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") ); @@ -3886,6 +3955,7 @@ static void trw_layer_add_menu_items ( VikTrwLayer *vtl, GtkMenu *menu, gpointer 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) ); @@ -3974,6 +4044,13 @@ static void trw_layer_add_menu_items ( VikTrwLayer *vtl, GtkMenu *menu, gpointer 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 @@ -4042,7 +4119,7 @@ void vik_trw_layer_add_track ( VikTrwLayer *vtl, gchar *name, VikTrack *t ) 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 @@ -4075,7 +4152,7 @@ void vik_trw_layer_add_route ( VikTrwLayer *vtl, gchar *name, VikTrack *t ) 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. */ @@ -4647,7 +4724,7 @@ static void trw_layer_delete_item ( gpointer pass_along[6] ) /** * 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 ); @@ -4669,6 +4746,28 @@ static void trw_layer_waypoint_rename ( VikTrwLayer *vtl, VikWaypoint *wp, const } } +/** + * Maintain icon of waypoint in the treeview + */ +void trw_layer_waypoint_reset_icon ( VikTrwLayer *vtl, VikWaypoint *wp ) +{ + // 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 ( gpointer pass_along[7] ) { VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]); @@ -4705,7 +4804,6 @@ static void trw_layer_properties_item ( gpointer pass_along[7] ) tr, pass_along[1], /* vlp */ pass_along[5], /* vvp */ - pass_along[6], /* iter */ FALSE ); } } @@ -4733,7 +4831,6 @@ static void trw_layer_track_statistics ( gpointer pass_along[7] ) trk, pass_along[1], // vlp pass_along[5], // vvp - pass_along[6], // iter TRUE ); } } @@ -4741,7 +4838,7 @@ static void trw_layer_track_statistics ( gpointer pass_along[7] ) /* * 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; @@ -4921,6 +5018,8 @@ static void trw_layer_extend_track_end_route_finder ( gpointer pass_along[6] ) VikTrack *track = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->routes, pass_along[3] ); if ( !track ) return; + if ( !track->trackpoints ) + 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 ); @@ -6905,6 +7004,39 @@ static void trw_layer_routes_visibility_toggle ( gpointer lav[2] ) 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: * @@ -7210,18 +7342,15 @@ static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *men 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 ); @@ -7231,30 +7360,22 @@ static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *men 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; @@ -7295,7 +7416,6 @@ static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *men gtk_widget_show ( item ); } } - } } @@ -7375,6 +7495,11 @@ static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *men 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 ) @@ -7445,7 +7570,6 @@ static gboolean trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *men 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") ); @@ -9763,7 +9887,7 @@ static void trw_layer_track_alloc_colors ( VikTrwLayer *vtl ) 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) @@ -9785,7 +9909,7 @@ static void trw_layer_track_alloc_colors ( VikTrwLayer *vtl ) 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; } @@ -9795,7 +9919,7 @@ static void trw_layer_track_alloc_colors ( VikTrwLayer *vtl ) * (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 }; @@ -10241,3 +10365,13 @@ static void trw_layer_track_list_dialog ( gpointer lav[2] ) 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 ( gpointer lav[2] ) +{ + VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]); + //VikLayersPanel *vlp = VIK_LAYERS_PANEL(lav[1]); + + 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 ); +}