X-Git-Url: https://git.street.me.uk/andy/viking.git/blobdiff_plain/4efc10ca607a20cd33dfc83be405966b0873cce8..9552af08b0de8cf0de6b8d253d5a77173f35259b:/src/vikwindow.c?ds=sidebyside diff --git a/src/vikwindow.c b/src/vikwindow.c index be00516b..4818ee17 100644 --- a/src/vikwindow.c +++ b/src/vikwindow.c @@ -3,6 +3,7 @@ * * Copyright (C) 2003-2005, Evan Battaglia * Copyright (C) 2005-2006, Alex Foobarian + * Copyright (C) 2012, Rob Norris * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -54,6 +55,12 @@ #include #include +// This seems rather arbitary, quite large and pointless +// I mean, if you have a thousand windows open; +// why not be allowed to open a thousand more... +#define MAX_WINDOWS 1024 +static guint window_count = 0; + #define VIKING_WINDOW_WIDTH 1000 #define VIKING_WINDOW_HEIGHT 800 #define DRAW_IMAGE_DEFAULT_WIDTH 1280 @@ -67,10 +74,18 @@ static void window_init ( VikWindow *vw ); static void window_class_init ( VikWindowClass *klass ); static void window_set_filename ( VikWindow *vw, const gchar *filename ); +static VikWindow *window_new (); + static void draw_update ( VikWindow *vw ); static void newwindow_cb ( GtkAction *a, VikWindow *vw ); +// Signals +static void open_window ( VikWindow *vw, GSList *files ); +static void statusbar_update ( VikWindow *vw, const gchar *message, vik_statusbar_type_t vs_type ); +static void destroy_window ( GtkWidget *widget, + gpointer data ); + /* Drawing & stuff */ static gboolean delete_event( VikWindow *vw ); @@ -177,7 +192,6 @@ struct _VikWindow { gpointer selected_waypoints; /* notionally GList */ gpointer selected_waypoint; /* notionally VikWaypoint */ /* only use for individual track or waypoint */ - gpointer selected_name; /* notionally gchar */ ////// NEED TO THINK ABOUT VALIDITY OF THESE ////// ////// i.e. what happens when stuff is deleted elsewhere ////// ////// Generally seems alright as can not access them ////// @@ -198,11 +212,13 @@ enum { enum { VW_NEWWINDOW_SIGNAL, VW_OPENWINDOW_SIGNAL, + VW_STATUSBAR_UPDATE_SIGNAL, VW_LAST_SIGNAL }; static guint window_signals[VW_LAST_SIGNAL] = { 0 }; +// TODO get rid of this as this is unnecessary duplication... static gchar *tool_names[NUMBER_OF_TOOLS] = { N_("Pan"), N_("Zoom"), N_("Ruler"), N_("Select") }; GType vik_window_get_type (void) @@ -239,6 +255,104 @@ VikLayersPanel * vik_window_layers_panel(VikWindow *vw) return(vw->viking_vlp); } +/** + * Returns the statusbar for the window + */ +VikStatusbar * vik_window_get_statusbar ( VikWindow *vw ) +{ + return vw->viking_vs; +} + +/** + * For signalling the update from a background thread + */ +void vik_window_signal_statusbar_update (VikWindow *vw, const gchar* message, vik_statusbar_type_t vs_type) +{ + g_signal_emit ( G_OBJECT(vw), window_signals[VW_STATUSBAR_UPDATE_SIGNAL], 0, message, vs_type ); +} + +/** + * For the actual statusbar update! + */ +static gboolean statusbar_idle_update ( gpointer indata ) +{ + gpointer *data = indata; + vik_statusbar_set_message ( data[0], GPOINTER_TO_INT(data[2]), data[1] ); + return FALSE; +} + +/** + * Update statusbar in the main thread + */ +static void window_statusbar_update ( VikWindow *vw, const gchar* message, vik_statusbar_type_t vs_type ) +{ + // ATM we know the message has been statically allocated so this is OK (no need to handle any freeing) + static gpointer data[3]; + data[0] = vw->viking_vs; + data[1] = (gchar*) message; + data[2] = GINT_TO_POINTER(vs_type); + g_idle_add ( (GSourceFunc) statusbar_idle_update, data ); +} + +// Actual signal handlers +static void destroy_window ( GtkWidget *widget, + gpointer data ) +{ + if ( ! --window_count ) + gtk_main_quit (); +} + +static void statusbar_update ( VikWindow *vw, const gchar *message, vik_statusbar_type_t vs_type ) +{ + window_statusbar_update ( vw, message, vs_type ); +} + +VikWindow *vik_window_new_window () +{ + if ( window_count < MAX_WINDOWS ) + { + VikWindow *vw = window_new (); + + g_signal_connect (G_OBJECT (vw), "destroy", + G_CALLBACK (destroy_window), NULL); + g_signal_connect (G_OBJECT (vw), "newwindow", + G_CALLBACK (vik_window_new_window), NULL); + g_signal_connect (G_OBJECT (vw), "openwindow", + G_CALLBACK (open_window), NULL); + g_signal_connect (G_OBJECT (vw), "statusbarupdate", + G_CALLBACK (statusbar_update), vw); + + gtk_widget_show_all ( GTK_WIDGET(vw) ); + + window_count++; + + return vw; + } + return NULL; +} + +static void open_window ( VikWindow *vw, GSList *files ) +{ + gboolean change_fn = (g_slist_length(files) == 1); /* only change fn if one file */ + GSList *cur_file = files; + while ( cur_file ) { + // Only open a new window if a viking file + gchar *file_name = cur_file->data; + if (vw != NULL && check_file_magic_vik ( file_name ) ) { + VikWindow *newvw = vik_window_new_window (); + if (newvw) + vik_window_open_file ( newvw, file_name, change_fn ); + } + else { + vik_window_open_file ( vw, file_name, change_fn ); + } + g_free (file_name); + cur_file = g_slist_next (cur_file); + } + g_slist_free (files); +} +// End signals + void vik_window_selected_layer(VikWindow *vw, VikLayer *vl) { int i, j, tool_count; @@ -253,7 +367,7 @@ void vik_window_selected_layer(VikWindow *vw, VikLayer *vl) for (j = 0; j < tool_count; j++) { action = gtk_action_group_get_action(vw->action_group, - layer_interface->tools[j].name); + layer_interface->tools[j].radioActionEntry.name); g_object_set(action, "sensitive", i == vl->type, NULL); } } @@ -264,7 +378,7 @@ static void window_finalize ( GObject *gob ) VikWindow *vw = VIK_WINDOW(gob); g_return_if_fail ( vw != NULL ); - a_background_remove_status ( vw->viking_vs ); + a_background_remove_window ( vw ); G_OBJECT_CLASS(parent_class)->finalize(gob); } @@ -277,6 +391,7 @@ static void window_class_init ( VikWindowClass *klass ) window_signals[VW_NEWWINDOW_SIGNAL] = g_signal_new ( "newwindow", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (VikWindowClass, newwindow), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); window_signals[VW_OPENWINDOW_SIGNAL] = g_signal_new ( "openwindow", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (VikWindowClass, openwindow), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); + window_signals[VW_STATUSBAR_UPDATE_SIGNAL] = g_signal_new ( "statusbarupdate", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (VikWindowClass, statusbarupdate), NULL, NULL, gtk_marshal_VOID__POINTER_UINT, G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_UINT); object_class = G_OBJECT_CLASS (klass); @@ -303,7 +418,8 @@ static void window_init ( VikWindow *vw ) window_set_filename (vw, NULL); vw->toolbar = GTK_TOOLBAR(gtk_ui_manager_get_widget (vw->uim, "/MainToolbar")); - toolbox_activate(vw->vt, "Pan"); + // Set the default tool + gtk_action_activate ( gtk_action_group_get_action ( vw->action_group, "Pan" ) ); vw->filename = NULL; vw->item_factory = NULL; @@ -351,7 +467,7 @@ static void window_init ( VikWindow *vw ) gtk_box_pack_end (GTK_BOX(main_vbox), GTK_WIDGET(vw->viking_vs), FALSE, TRUE, 0); - a_background_add_status(vw->viking_vs); + a_background_add_window ( vw ); vw->open_dia = NULL; vw->save_dia = NULL; @@ -359,7 +475,7 @@ static void window_init ( VikWindow *vw ) vw->save_img_dir_dia = NULL; } -VikWindow *vik_window_new () +static VikWindow *window_new () { return VIK_WINDOW ( g_object_new ( VIK_WINDOW_TYPE, NULL ) ); } @@ -373,9 +489,12 @@ static gboolean key_press_event( VikWindow *vw, GdkEventKey *event, gpointer dat return vw->vt->tools[vw->vt->active_tool].ti.key_press(vl, event, vw->vt->tools[vw->vt->active_tool].state); } - // No layer - but enable window tool keypress processing - these should be able to handle a NULL layer - if ( vw->vt->tools[vw->vt->active_tool].ti.key_press ) { - return vw->vt->tools[vw->vt->active_tool].ti.key_press ( vl, event, vw->vt->tools[vw->vt->active_tool].state ); + // Ensure called only on window tools (i.e. not on any of the Layer tools since the layer is NULL) + if ( vw->current_tool < TOOL_LAYER ) { + // No layer - but enable window tool keypress processing - these should be able to handle a NULL layer + if ( vw->vt->tools[vw->vt->active_tool].ti.key_press ) { + return vw->vt->tools[vw->vt->active_tool].ti.key_press ( vl, event, vw->vt->tools[vw->vt->active_tool].state ); + } } /* Restore Main Menu via Escape key if the user has hidden it */ @@ -454,7 +573,8 @@ static void draw_status ( VikWindow *vw ) /* xmpp should be a whole number so don't show useless .000 bit */ g_snprintf ( zoom_level, 22, "%d %s", (int)xmpp, unit ); if ( vw->current_tool == TOOL_LAYER ) - vik_statusbar_set_message ( vw->viking_vs, VIK_STATUSBAR_TOOL, vik_layer_get_interface(vw->tool_layer_id)->tools[vw->tool_tool_id].name ); + // Use tooltip rather than the internal name as the tooltip is i8n + vik_statusbar_set_message ( vw->viking_vs, VIK_STATUSBAR_TOOL, vik_layer_get_interface(vw->tool_layer_id)->tools[vw->tool_tool_id].radioActionEntry.tooltip ); else vik_statusbar_set_message ( vw->viking_vs, VIK_STATUSBAR_TOOL, _(tool_names[vw->current_tool]) ); @@ -541,6 +661,9 @@ static void draw_click (VikWindow *vw, GdkEventButton *event) * for panning and zooming; tools only get left/right/movement */ if ( event->button == 2) { + if ( vw->vt->tools[vw->vt->active_tool].ti.pan_handler ) + // Tool still may need to do something (such as disable something) + toolbox_click(vw->vt, event); vik_window_pan_click ( vw, event ); } else { @@ -633,7 +756,10 @@ static void draw_release ( VikWindow *vw, GdkEventButton *event ) gtk_widget_grab_focus ( GTK_WIDGET(vw->viking_vvp) ); if ( event->button == 2 ) { /* move / pan */ - vik_window_pan_release(vw, event); + if ( vw->vt->tools[vw->vt->active_tool].ti.pan_handler ) + // Tool still may need to do something (such as reenable something) + toolbox_release(vw->vt, event); + vik_window_pan_release ( vw, event ); } else { toolbox_release(vw->vt, event); @@ -656,7 +782,13 @@ static void draw_scroll (VikWindow *vw, GdkEventScroll *event) else vik_viewport_set_center_screen ( vw->viking_vvp, vik_viewport_get_width(vw->viking_vvp)*2/3, vik_viewport_get_height(vw->viking_vvp)/2 ); } else if ( modifiers == (GDK_CONTROL_MASK | GDK_SHIFT_MASK) ) { - /* control+shift == make sure mouse is still over the same point on the map when we zoom */ + // This zoom is on the center position + if ( event->direction == GDK_SCROLL_UP ) + vik_viewport_zoom_in (vw->viking_vvp); + else + vik_viewport_zoom_out (vw->viking_vvp); + } else { + /* make sure mouse is still over the same point on the map when we zoom */ VikCoord coord; gint x, y; gint center_x = vik_viewport_get_width ( vw->viking_vvp ) / 2; @@ -669,11 +801,6 @@ static void draw_scroll (VikWindow *vw, GdkEventScroll *event) vik_viewport_coord_to_screen ( vw->viking_vvp, &coord, &x, &y ); vik_viewport_set_center_screen ( vw->viking_vvp, center_x + (x - event->x), center_y + (y - event->y) ); - } else { - if ( event->direction == GDK_SCROLL_UP ) - vik_viewport_zoom_in (vw->viking_vvp); - else - vik_viewport_zoom_out (vw->viking_vvp); } draw_update(vw); @@ -1008,7 +1135,7 @@ static gboolean ruler_key_press (VikLayer *vl, GdkEventKey *event, ruler_tool_st } static VikToolInterface ruler_tool = - { "Ruler", + { { "Ruler", "vik-icon-ruler", N_("_Ruler"), "R", N_("Ruler Tool"), 2 }, (VikToolConstructorFunc) ruler_create, (VikToolDestructorFunc) ruler_destroy, (VikToolActivationFunc) NULL, @@ -1017,6 +1144,7 @@ static VikToolInterface ruler_tool = (VikToolMouseMoveFunc) ruler_move, (VikToolMouseFunc) ruler_release, (VikToolKeyFunc) ruler_key_press, + FALSE, GDK_CURSOR_IS_PIXMAP, &cursor_ruler_pixbuf }; /*** end ruler code ********************************************************/ @@ -1026,43 +1154,245 @@ static VikToolInterface ruler_tool = /******************************************************************************** ** Zoom tool code ********************************************************************************/ + +typedef struct { + VikWindow *vw; + GdkPixmap *pixmap; + // Track zoom bounds for zoom tool with shift modifier: + gboolean bounds_active; + gint start_x; + gint start_y; +} zoom_tool_state_t; + +/* + * In case the screen size has changed + */ +static void zoomtool_resize_pixmap (zoom_tool_state_t *zts) +{ + int w1, h1, w2, h2; + + // Allocate a drawing area the size of the viewport + w1 = vik_viewport_get_width ( zts->vw->viking_vvp ); + h1 = vik_viewport_get_height ( zts->vw->viking_vvp ); + + if ( !zts->pixmap ) { + // Totally new + zts->pixmap = gdk_pixmap_new ( GTK_WIDGET(zts->vw->viking_vvp)->window, w1, h1, -1 ); + } + + gdk_drawable_get_size ( zts->pixmap, &w2, &h2 ); + + if ( w1 != w2 || h1 != h2 ) { + // Has changed - delete and recreate with new values + g_object_unref ( G_OBJECT ( zts->pixmap ) ); + zts->pixmap = gdk_pixmap_new ( GTK_WIDGET(zts->vw->viking_vvp)->window, w1, h1, -1 ); + } +} + static gpointer zoomtool_create (VikWindow *vw, VikViewport *vvp) { - return vw; + zoom_tool_state_t *zts = g_new(zoom_tool_state_t, 1); + zts->vw = vw; + zts->pixmap = NULL; + zts->start_x = 0; + zts->start_y = 0; + zts->bounds_active = FALSE; + return zts; } -static VikLayerToolFuncStatus zoomtool_click (VikLayer *vl, GdkEventButton *event, VikWindow *vw) +static void zoomtool_destroy ( zoom_tool_state_t *zts) { - vw->modified = TRUE; - vik_viewport_set_center_screen ( vw->viking_vvp, (gint) event->x, (gint) event->y ); - if ( event->button == 1 ) - vik_viewport_zoom_in (vw->viking_vvp); - else if ( event->button == 3 ) - vik_viewport_zoom_out (vw->viking_vvp); - draw_update ( vw ); + if ( zts->pixmap ) + g_object_unref ( G_OBJECT ( zts->pixmap ) ); + g_free(zts); +} + +static VikLayerToolFuncStatus zoomtool_click (VikLayer *vl, GdkEventButton *event, zoom_tool_state_t *zts) +{ + zts->vw->modified = TRUE; + guint modifiers = event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK); + + VikCoord coord; + gint x, y; + gint center_x = vik_viewport_get_width ( zts->vw->viking_vvp ) / 2; + gint center_y = vik_viewport_get_height ( zts->vw->viking_vvp ) / 2; + + gboolean skip_update = FALSE; + + zts->bounds_active = FALSE; + + if ( modifiers == (GDK_CONTROL_MASK | GDK_SHIFT_MASK) ) { + // This zoom is on the center position + vik_viewport_set_center_screen ( zts->vw->viking_vvp, center_x, center_y ); + if ( event->button == 1 ) + vik_viewport_zoom_in (zts->vw->viking_vvp); + else if ( event->button == 3 ) + vik_viewport_zoom_out (zts->vw->viking_vvp); + } + else if ( modifiers == GDK_CONTROL_MASK ) { + // This zoom is to recenter on the mouse position + vik_viewport_set_center_screen ( zts->vw->viking_vvp, (gint) event->x, (gint) event->y ); + if ( event->button == 1 ) + vik_viewport_zoom_in (zts->vw->viking_vvp); + else if ( event->button == 3 ) + vik_viewport_zoom_out (zts->vw->viking_vvp); + } + else if ( modifiers == GDK_SHIFT_MASK ) { + // Get start of new zoom bounds + if ( event->button == 1 ) { + zts->bounds_active = TRUE; + zts->start_x = (gint) event->x; + zts->start_y = (gint) event->y; + skip_update = TRUE; + } + } + else { + /* make sure mouse is still over the same point on the map when we zoom */ + vik_viewport_screen_to_coord ( zts->vw->viking_vvp, event->x, event->y, &coord ); + if ( event->button == 1 ) + vik_viewport_zoom_in (zts->vw->viking_vvp); + else if ( event->button == 3 ) + vik_viewport_zoom_out(zts->vw->viking_vvp); + vik_viewport_coord_to_screen ( zts->vw->viking_vvp, &coord, &x, &y ); + vik_viewport_set_center_screen ( zts->vw->viking_vvp, + center_x + (x - event->x), + center_y + (y - event->y) ); + } + + if ( !skip_update ) + draw_update ( zts->vw ); + return VIK_LAYER_TOOL_ACK; } -static VikLayerToolFuncStatus zoomtool_move (VikLayer *vl, GdkEventMotion *event, VikViewport *vvp) +static VikLayerToolFuncStatus zoomtool_move (VikLayer *vl, GdkEventMotion *event, zoom_tool_state_t *zts) { + guint modifiers = event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK); + + if ( zts->bounds_active && modifiers == GDK_SHIFT_MASK ) { + zoomtool_resize_pixmap ( zts ); + + // Blank out currently drawn area + gdk_draw_drawable ( zts->pixmap, + GTK_WIDGET(zts->vw->viking_vvp)->style->black_gc, + vik_viewport_get_pixmap(zts->vw->viking_vvp), + 0, 0, 0, 0, -1, -1); + + // Calculate new box starting point & size in pixels + int xx, yy, width, height; + if ( event->y > zts->start_y ) { + yy = zts->start_y; + height = event->y-zts->start_y; + } + else { + yy = event->y; + height = zts->start_y-event->y; + } + if ( event->x > zts->start_x ) { + xx = zts->start_x; + width = event->x-zts->start_x; + } + else { + xx = event->x; + width = zts->start_x-event->x; + } + + // Draw the box + gdk_draw_rectangle (zts->pixmap, GTK_WIDGET(zts->vw->viking_vvp)->style->black_gc, FALSE, xx, yy, width, height); + + // Only actually draw when there's time to do so + if (draw_buf_done) { + static gpointer pass_along[3]; + pass_along[0] = GTK_WIDGET(zts->vw->viking_vvp)->window; + pass_along[1] = GTK_WIDGET(zts->vw->viking_vvp)->style->black_gc; + pass_along[2] = zts->pixmap; + g_idle_add_full (G_PRIORITY_HIGH_IDLE + 10, draw_buf, pass_along, NULL); + draw_buf_done = FALSE; + } + } return VIK_LAYER_TOOL_ACK; } -static VikLayerToolFuncStatus zoomtool_release (VikLayer *vl, GdkEventButton *event, VikViewport *vvp) +static VikLayerToolFuncStatus zoomtool_release (VikLayer *vl, GdkEventButton *event, zoom_tool_state_t *zts) { + guint modifiers = event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK); + + zts->bounds_active = FALSE; + + // Ensure haven't just released on the exact same position + // i.e. probably haven't moved the mouse at all + if ( modifiers == GDK_SHIFT_MASK && !( ( event->x == zts->start_x ) && ( event->y == zts->start_y )) ) { + + VikCoord coord1, coord2; + vik_viewport_screen_to_coord ( zts->vw->viking_vvp, zts->start_x, zts->start_y, &coord1); + vik_viewport_screen_to_coord ( zts->vw->viking_vvp, event->x, event->y, &coord2); + + // From the extend of the bounds pick the best zoom level + // c.f. trw_layer_zoom_to_show_latlons() + // Maybe refactor... + struct LatLon ll1, ll2; + vik_coord_to_latlon(&coord1, &ll1); + vik_coord_to_latlon(&coord2, &ll2); + struct LatLon average = { (ll1.lat+ll2.lat)/2, + (ll1.lon+ll2.lon)/2 }; + + VikCoord new_center; + vik_coord_load_from_latlon ( &new_center, vik_viewport_get_coord_mode ( zts->vw->viking_vvp ), &average ); + vik_viewport_set_center_coord ( zts->vw->viking_vvp, &new_center ); + + /* Convert into definite 'smallest' and 'largest' positions */ + struct LatLon minmin; + if ( ll1.lat < ll2.lat ) + minmin.lat = ll1.lat; + else + minmin.lat = ll2.lat; + + struct LatLon maxmax; + if ( ll1.lon > ll2.lon ) + maxmax.lon = ll1.lon; + else + maxmax.lon = ll2.lon; + + /* Always recalculate the 'best' zoom level */ + gdouble zoom = VIK_VIEWPORT_MIN_ZOOM; + vik_viewport_set_zoom ( zts->vw->viking_vvp, zoom ); + + gdouble min_lat, max_lat, min_lon, max_lon; + /* Should only be a maximum of about 18 iterations from min to max zoom levels */ + while ( zoom <= VIK_VIEWPORT_MAX_ZOOM ) { + vik_viewport_get_min_max_lat_lon ( zts->vw->viking_vvp, &min_lat, &max_lat, &min_lon, &max_lon ); + /* NB I think the logic used in this test to determine if the bounds is within view + fails if track goes across 180 degrees longitude. + Hopefully that situation is not too common... + Mind you viking doesn't really do edge locations to well anyway */ + if ( min_lat < minmin.lat && + max_lat > minmin.lat && + min_lon < maxmax.lon && + max_lon > maxmax.lon ) + /* Found within zoom level */ + break; + + /* Try next */ + zoom = zoom * 2; + vik_viewport_set_zoom ( zts->vw->viking_vvp, zoom ); + } + + draw_update ( zts->vw ); + } return VIK_LAYER_TOOL_ACK; } static VikToolInterface zoom_tool = - { "Zoom", + { { "Zoom", "vik-icon-zoom", N_("_Zoom"), "Z", N_("Zoom Tool"), 1 }, (VikToolConstructorFunc) zoomtool_create, - (VikToolDestructorFunc) NULL, + (VikToolDestructorFunc) zoomtool_destroy, (VikToolActivationFunc) NULL, (VikToolActivationFunc) NULL, (VikToolMouseFunc) zoomtool_click, (VikToolMouseMoveFunc) zoomtool_move, (VikToolMouseFunc) zoomtool_release, NULL, + FALSE, GDK_CURSOR_IS_PIXMAP, &cursor_zoom_pixbuf }; /*** end zoom code ********************************************************/ @@ -1098,7 +1428,7 @@ static VikLayerToolFuncStatus pantool_release (VikLayer *vl, GdkEventButton *eve } static VikToolInterface pan_tool = - { "Pan", + { { "Pan", "vik-icon-pan", N_("_Pan"), "P", N_("Pan Tool"), 0 }, (VikToolConstructorFunc) pantool_create, (VikToolDestructorFunc) NULL, (VikToolActivationFunc) NULL, @@ -1107,6 +1437,7 @@ static VikToolInterface pan_tool = (VikToolMouseMoveFunc) pantool_move, (VikToolMouseFunc) pantool_release, NULL, + FALSE, GDK_FLEUR }; /*** end pan code ********************************************************/ @@ -1181,7 +1512,7 @@ static VikLayerToolFuncStatus selecttool_click (VikLayer *vl, GdkEventButton *ev else if ( ( event->button == 3 ) && ( vl && ( vl->type == VIK_LAYER_TRW ) ) ) { if ( vl->visible ) /* Act on currently selected item to show menu */ - if ( ( t->vw->selected_track || t->vw->selected_waypoint ) && t->vw->selected_name ) + if ( t->vw->selected_track || t->vw->selected_waypoint ) if ( vik_layer_get_interface(vl->type)->show_viewport_menu ) vik_layer_get_interface(vl->type)->show_viewport_menu ( vl, event, t->vw->viking_vvp ); } @@ -1214,7 +1545,7 @@ static VikLayerToolFuncStatus selecttool_release (VikLayer *vl, GdkEventButton * } static VikToolInterface select_tool = - { "Select", + { { "Select", "vik-icon-select", N_("_Select"), "S", N_("Select Tool"), 3 }, (VikToolConstructorFunc) selecttool_create, (VikToolDestructorFunc) selecttool_destroy, (VikToolActivationFunc) NULL, @@ -1223,6 +1554,7 @@ static VikToolInterface select_tool = (VikToolMouseMoveFunc) selecttool_move, (VikToolMouseFunc) selecttool_release, (VikToolKeyFunc) NULL, + FALSE, GDK_LEFT_PTR, NULL, NULL }; @@ -1335,7 +1667,6 @@ static void menu_copy_layer_cb ( GtkAction *a, VikWindow *vw ) static void menu_cut_layer_cb ( GtkAction *a, VikWindow *vw ) { vik_layers_panel_cut_selected ( vw->viking_vlp ); - draw_update ( vw ); vw->modified = TRUE; } @@ -1343,7 +1674,6 @@ static void menu_paste_layer_cb ( GtkAction *a, VikWindow *vw ) { if ( a_clipboard_paste ( vw->viking_vlp ) ) { - draw_update ( vw ); vw->modified = TRUE; } } @@ -1468,7 +1798,7 @@ static int toolbox_get_tool(toolbox_tools_t *vt, const gchar *tool_name) { int i; for (i=0; in_tools; i++) { - if (!strcmp(tool_name, vt->tools[i].ti.name)) { + if (!strcmp(tool_name, vt->tools[i].ti.radioActionEntry.name)) { break; } } @@ -1553,7 +1883,7 @@ static void toolbox_release (toolbox_tools_t *vt, GdkEventButton *event) void vik_window_enable_layer_tool ( VikWindow *vw, gint layer_id, gint tool_id ) { - gtk_action_activate ( gtk_action_group_get_action ( vw->action_group, vik_layer_get_interface(layer_id)->tools[tool_id].name ) ); + gtk_action_activate ( gtk_action_group_get_action ( vw->action_group, vik_layer_get_interface(layer_id)->tools[tool_id].radioActionEntry.name ) ); } /* this function gets called whenever a toolbar tool is clicked */ @@ -1566,8 +1896,10 @@ static void menu_tool_cb ( GtkAction *old, GtkAction *a, VikWindow *vw ) toolbox_activate(vw->vt, gtk_action_get_name(a)); cursor = toolbox_get_cursor(vw->vt, gtk_action_get_name(a)); - /* We set cursor, even if it is NULL: it resets to default */ - gdk_window_set_cursor ( GTK_WIDGET(vw->viking_vvp)->window, (GdkCursor *)cursor ); + + if ( GTK_WIDGET(vw->viking_vvp)->window ) + /* We set cursor, even if it is NULL: it resets to default */ + gdk_window_set_cursor ( GTK_WIDGET(vw->viking_vvp)->window, (GdkCursor *)cursor ); if (!strcmp(gtk_action_get_name(a), "Pan")) { vw->current_tool = TOOL_PAN; @@ -1585,7 +1917,7 @@ static void menu_tool_cb ( GtkAction *old, GtkAction *a, VikWindow *vw ) /* TODO: only enable tools from active layer */ for (layer_id=0; layer_idtools_count; tool_id++ ) { - if (!strcmp(vik_layer_get_interface(layer_id)->tools[tool_id].name, gtk_action_get_name(a))) { + if (!strcmp(vik_layer_get_interface(layer_id)->tools[tool_id].radioActionEntry.name, gtk_action_get_name(a))) { vw->current_tool = TOOL_LAYER; vw->tool_layer_id = layer_id; vw->tool_tool_id = tool_id; @@ -1664,12 +1996,15 @@ static void on_activate_recent_item (GtkRecentChooser *chooser, g_object_unref ( file ); if ( self->filename ) { - gchar *filenames[] = { path, NULL }; + GSList *filenames = NULL; + filenames = g_slist_append ( filenames, path ); g_signal_emit ( G_OBJECT(self), window_signals[VW_OPENWINDOW_SIGNAL], 0, filenames ); + // NB: GSList & contents are freed by main.open_window } - else + else { vik_window_open_file ( self, path, TRUE ); - g_free ( path ); + g_free ( path ); + } } g_free (filename); @@ -1737,6 +2072,12 @@ void vik_window_open_file ( VikWindow *vw, const gchar *filename, gboolean chang case LOAD_TYPE_GPSBABEL_FAILURE: a_dialog_error_msg ( GTK_WINDOW(vw), _("GPSBabel is required to load files of this type or GPSBabel encountered problems.") ); break; + case LOAD_TYPE_GPX_FAILURE: + a_dialog_error_msg_extra ( GTK_WINDOW(vw), _("Unable to load malformed GPX file %s"), filename ); + break; + case LOAD_TYPE_UNSUPPORTED_FAILURE: + a_dialog_error_msg_extra ( GTK_WINDOW(vw), _("Unsupported file type for %s"), filename ); + break; case LOAD_TYPE_VIK_SUCCESS: { GtkWidget *mode_button; @@ -1793,6 +2134,42 @@ static void load_file ( GtkAction *a, VikWindow *vw ) GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); + GtkFileFilter *filter; + // NB file filters are listed this way for alphabetical ordering +#ifdef VIK_CONFIG_GEOCACHES + filter = gtk_file_filter_new (); + gtk_file_filter_set_name( filter, _("Geocaching") ); + gtk_file_filter_add_pattern ( filter, "*.loc" ); // No MIME type available + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(vw->open_dia), filter); +#endif + + filter = gtk_file_filter_new (); + gtk_file_filter_set_name( filter, _("Google Earth") ); + gtk_file_filter_add_mime_type ( filter, "application/vnd.google-earth.kml+xml"); + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(vw->open_dia), filter); + + filter = gtk_file_filter_new (); + gtk_file_filter_set_name( filter, _("GPX") ); + gtk_file_filter_add_pattern ( filter, "*.gpx" ); // No MIME type available + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(vw->open_dia), filter); + + filter = gtk_file_filter_new (); + gtk_file_filter_set_name( filter, _("Viking") ); + gtk_file_filter_add_pattern ( filter, "*.vik" ); + gtk_file_filter_add_pattern ( filter, "*.viking" ); + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(vw->open_dia), filter); + + // NB could have filters for gpspoint (*.gps,*.gpsoint?) + gpsmapper (*.gsm,*.gpsmapper?) + // However assume this are barely used and thus not worthy of inclusion + // as they'll just make the options too many and have no clear file pattern + // one can always use the all option + filter = gtk_file_filter_new (); + gtk_file_filter_set_name( filter, _("All") ); + gtk_file_filter_add_pattern ( filter, "*" ); + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(vw->open_dia), filter); + // Default to any file - same as before open filters were added + gtk_file_chooser_set_filter (GTK_FILE_CHOOSER(vw->open_dia), filter); + gtk_file_chooser_set_select_multiple ( GTK_FILE_CHOOSER(vw->open_dia), TRUE ); gtk_window_set_transient_for ( GTK_WINDOW(vw->open_dia), GTK_WINDOW(vw) ); gtk_window_set_destroy_with_parent ( GTK_WINDOW(vw->open_dia), TRUE ); @@ -1839,6 +2216,12 @@ static gboolean save_file_as ( GtkAction *a, VikWindow *vw ) gtk_window_set_transient_for ( GTK_WINDOW(vw->save_dia), GTK_WINDOW(vw) ); gtk_window_set_destroy_with_parent ( GTK_WINDOW(vw->save_dia), TRUE ); } + // Auto append / replace extension with '.vik' to the suggested file name as it's going to be a Viking File + gchar* auto_save_name = strdup ( vw->filename ? a_file_basename ( vw->filename ) : _("Untitled") ); + if ( ! check_file_ext ( auto_save_name, ".vik" ) ) + auto_save_name = g_strconcat ( auto_save_name, ".vik", NULL ); + + gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER(vw->save_dia), auto_save_name); while ( gtk_dialog_run ( GTK_DIALOG(vw->save_dia) ) == GTK_RESPONSE_ACCEPT ) { @@ -1851,6 +2234,7 @@ static gboolean save_file_as ( GtkAction *a, VikWindow *vw ) break; } } + g_free ( auto_save_name ); gtk_widget_hide ( vw->save_dia ); return rv; } @@ -1882,13 +2266,32 @@ static gboolean save_file ( GtkAction *a, VikWindow *vw ) static void acquire_from_gps ( GtkAction *a, VikWindow *vw ) { + // Via the file menu, acquiring from a GPS makes a new layer + // this has always been the way (not entirely sure if this was the real intention!) + // thus maintain the behaviour ATM. + // Hence explicit setting here (as the value may be changed elsewhere) + vik_datasource_gps_interface.mode = VIK_DATASOURCE_CREATENEWLAYER; a_acquire(vw, vw->viking_vlp, vw->viking_vvp, &vik_datasource_gps_interface ); } +static void acquire_from_file ( GtkAction *a, VikWindow *vw ) +{ + a_acquire(vw, vw->viking_vlp, vw->viking_vvp, &vik_datasource_file_interface ); +} + +#ifdef VIK_CONFIG_GOOGLE_DIRECTIONS static void acquire_from_google ( GtkAction *a, VikWindow *vw ) { a_acquire(vw, vw->viking_vlp, vw->viking_vvp, &vik_datasource_google_interface ); } +#endif + +#ifdef VIK_CONFIG_OPENSTREETMAP +static void acquire_from_osm ( GtkAction *a, VikWindow *vw ) +{ + a_acquire(vw, vw->viking_vlp, vw->viking_vvp, &vik_datasource_osm_interface ); +} +#endif #ifdef VIK_CONFIG_GEOCACHES static void acquire_from_gc ( GtkAction *a, VikWindow *vw ) @@ -1897,6 +2300,14 @@ static void acquire_from_gc ( GtkAction *a, VikWindow *vw ) } #endif +#ifdef VIK_CONFIG_GEOTAG +static void acquire_from_geotag ( GtkAction *a, VikWindow *vw ) +{ + vik_datasource_geotag_interface.mode = VIK_DATASOURCE_CREATENEWLAYER; + a_acquire(vw, vw->viking_vlp, vw->viking_vvp, &vik_datasource_geotag_interface ); +} +#endif + static void goto_default_location( GtkAction *a, VikWindow *vw) { struct LatLon ll; @@ -2255,16 +2666,14 @@ static void draw_to_image_file ( VikWindow *vw, const gchar *fn, gboolean one_im gtk_spin_button_get_value ( GTK_SPIN_BUTTON(zoom_spin) ), /* do not save this value, default is current zoom */ vw->draw_image_save_as_png = gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON(png_radio) ) ); else { - if ( vik_viewport_get_coord_mode(vw->viking_vvp) == VIK_COORD_UTM ) - save_image_dir ( vw, fn, + // NB is in UTM mode ATM + save_image_dir ( vw, fn, vw->draw_image_width = gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON(width_spin) ), vw->draw_image_height = gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON(height_spin) ), gtk_spin_button_get_value ( GTK_SPIN_BUTTON(zoom_spin) ), /* do not save this value, default is current zoom */ vw->draw_image_save_as_png = gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON(png_radio) ), gtk_spin_button_get_value ( GTK_SPIN_BUTTON(tiles_width_spin) ), gtk_spin_button_get_value ( GTK_SPIN_BUTTON(tiles_height_spin) ) ); - else - a_dialog_error_msg ( GTK_WINDOW(vw), _("You must be in UTM mode to use this feature") ); } } gtk_widget_destroy ( GTK_WIDGET(dialog) ); @@ -2303,6 +2712,11 @@ static void draw_to_image_dir_cb ( GtkAction *a, VikWindow *vw ) { gchar *fn = NULL; + if ( vik_viewport_get_coord_mode(vw->viking_vvp) != VIK_COORD_UTM ) { + a_dialog_error_msg ( GTK_WINDOW(vw), _("You must be in UTM mode to use this feature") ); + return; + } + if (!vw->save_img_dir_dia) { vw->save_img_dir_dia = gtk_file_chooser_dialog_new (_("Choose a directory to hold images"), GTK_WINDOW(vw), @@ -2454,11 +2868,20 @@ static GtkActionEntry entries[] = { { "Open", GTK_STOCK_OPEN, N_("_Open..."), "O", N_("Open a file"), (GCallback)load_file }, { "OpenRecentFile", NULL, N_("Open _Recent File"), NULL, NULL, (GCallback)NULL }, { "Append", GTK_STOCK_ADD, N_("Append _File..."), NULL, N_("Append data from a different file"), (GCallback)load_file }, - { "Acquire", NULL, N_("A_cquire"), 0, 0, 0 }, + { "Acquire", GTK_STOCK_GO_DOWN, N_("A_cquire"), NULL, NULL, (GCallback)NULL }, { "AcquireGPS", NULL, N_("From _GPS..."), NULL, N_("Transfer data from a GPS device"), (GCallback)acquire_from_gps }, + { "AcquireGPSBabel", NULL, N_("Import File With GPS_Babel..."), NULL, N_("Import file via GPSBabel converter"), (GCallback)acquire_from_file }, +#ifdef VIK_CONFIG_GOOGLE_DIRECTIONS { "AcquireGoogle", NULL, N_("Google _Directions..."), NULL, N_("Get driving directions from Google"), (GCallback)acquire_from_google }, +#endif +#ifdef VIK_CONFIG_OPENSTREETMAP + { "AcquireOSM", NULL, N_("_OSM Traces..."), NULL, N_("Get traces from OpenStreetMap"), (GCallback)acquire_from_osm }, +#endif #ifdef VIK_CONFIG_GEOCACHES { "AcquireGC", NULL, N_("Geo_caches..."), NULL, N_("Get Geocaches from geocaching.com"), (GCallback)acquire_from_gc }, +#endif +#ifdef VIK_CONFIG_GEOTAG + { "AcquireGeotag", NULL, N_("From Geotagged _Images..."), NULL, N_("Create waypoints from geotagged images"), (GCallback)acquire_from_geotag }, #endif { "Save", GTK_STOCK_SAVE, N_("_Save"), "S", N_("Save the file"), (GCallback)save_file }, { "SaveAs", GTK_STOCK_SAVE_AS, N_("Save _As..."), NULL, N_("Save the file under different name"), (GCallback)save_file_as }, @@ -2528,13 +2951,6 @@ static GtkRadioActionEntry mode_entries[] = { { "ModeLatLon", NULL, N_("Lat_/Lon Mode"), "l", NULL, 5 }, }; -static GtkRadioActionEntry tool_entries[] = { - { "Pan", "vik-icon-pan", N_("_Pan"), "P", N_("Pan Tool"), 0 }, - { "Zoom", "vik-icon-zoom", N_("_Zoom"), "Z", N_("Zoom Tool"), 1 }, - { "Ruler", "vik-icon-ruler", N_("_Ruler"), "R", N_("Ruler Tool"), 2 }, - { "Select", "vik-icon-select", N_("_Select"), "S", N_("Select Tool"), 3 } -}; - static GtkToggleActionEntry toggle_entries[] = { { "ShowScale", NULL, N_("Show _Scale"), "F5", N_("Show Scale"), (GCallback)set_draw_scale, TRUE }, { "ShowCenterMark", NULL, N_("Show _Center Mark"), "F6", N_("Show Center Mark"), (GCallback)set_draw_centermark, TRUE }, @@ -2584,14 +3000,16 @@ static void window_create_ui( VikWindow *window ) register_vik_icons(icon_factory); + // Copy the tool RadioActionEntries out of the main Window structure into an extending array 'tools' + // so that it can be applied to the UI in one action group add function call below ntools = 0; - for (i=0; ivt->n_tools; i++) { tools = g_renew(GtkRadioActionEntry, tools, ntools+1); radio = &tools[ntools]; ntools++; - *radio = tool_entries[i]; + *radio = window->vt->tools[i].ti.radioActionEntry; radio->value = ntools; - } + } for (i=0; iname; action.stock_id = vik_layer_get_interface(i)->name; - action.label = g_strdup_printf( _("New %s Layer"), vik_layer_get_interface(i)->name); - action.accelerator = NULL; + action.label = g_strdup_printf( _("New _%s Layer"), vik_layer_get_interface(i)->name); + action.accelerator = vik_layer_get_interface(i)->accelerator; action.tooltip = NULL; action.callback = (GCallback)menu_addlayer_cb; gtk_action_group_add_actions(action_group, &action, 1, window); @@ -2617,27 +3035,25 @@ static void window_create_ui( VikWindow *window ) gtk_ui_manager_add_ui(uim, mid, "/ui/MainToolbar/ToolItems/", vik_layer_get_interface(i)->name, NULL, GTK_UI_MANAGER_SEPARATOR, FALSE); } + // Further tool copying for to apply to the UI, also apply menu UI setup for ( j = 0; j < vik_layer_get_interface(i)->tools_count; j++ ) { tools = g_renew(GtkRadioActionEntry, tools, ntools+1); radio = &tools[ntools]; ntools++; gtk_ui_manager_add_ui(uim, mid, "/ui/MainMenu/Tools", - _(vik_layer_get_interface(i)->tools[j].name), - vik_layer_get_interface(i)->tools[j].name, + vik_layer_get_interface(i)->tools[j].radioActionEntry.label, + vik_layer_get_interface(i)->tools[j].radioActionEntry.name, GTK_UI_MANAGER_MENUITEM, FALSE); gtk_ui_manager_add_ui(uim, mid, "/ui/MainToolbar/ToolItems", - _(vik_layer_get_interface(i)->tools[j].name), - vik_layer_get_interface(i)->tools[j].name, + vik_layer_get_interface(i)->tools[j].radioActionEntry.label, + vik_layer_get_interface(i)->tools[j].radioActionEntry.name, GTK_UI_MANAGER_TOOLITEM, FALSE); toolbox_add_tool(window->vt, &(vik_layer_get_interface(i)->tools[j]), i); - radio->name = vik_layer_get_interface(i)->tools[j].name; - radio->stock_id = vik_layer_get_interface(i)->tools[j].name, - radio->label = _(vik_layer_get_interface(i)->tools[j].name); - radio->accelerator = NULL; - radio->tooltip = _(vik_layer_get_interface(i)->tools[j].name); + *radio = vik_layer_get_interface(i)->tools[j].radioActionEntry; + // Overwrite with actual number to use radio->value = ntools; } } @@ -2651,7 +3067,7 @@ static void window_create_ui( VikWindow *window ) for (i=0; itools_count; j++ ) { GtkAction *action = gtk_action_group_get_action(action_group, - vik_layer_get_interface(i)->tools[j].name); + vik_layer_get_interface(i)->tools[j].radioActionEntry.name); g_object_set(action, "sensitive", FALSE, NULL); } } @@ -2665,26 +3081,27 @@ static void window_create_ui( VikWindow *window ) } - +// TODO - add method to add tool icons defined from outside this file +// and remove the reverse dependency on icon definition from this file static struct { const GdkPixdata *data; gchar *stock_id; } stock_icons[] = { - { &begintr_18_pixbuf, "Begin Track" }, - { &route_finder_18_pixbuf, "Route Finder" }, - { &mover_22_pixbuf, "vik-icon-pan" }, - { &demdl_18_pixbuf, "DEM Download/Import" }, - { &showpic_18_pixbuf, "Show Picture" }, - { &addtr_18_pixbuf, "Create Track" }, - { &edtr_18_pixbuf, "Edit Trackpoint" }, - { &addwp_18_pixbuf, "Create Waypoint" }, - { &edwp_18_pixbuf, "Edit Waypoint" }, + { &mover_22_pixbuf, "vik-icon-pan" }, { &zoom_18_pixbuf, "vik-icon-zoom" }, { &ruler_18_pixbuf, "vik-icon-ruler" }, { &select_18_pixbuf, "vik-icon-select" }, - { &geozoom_18_pixbuf, "Georef Zoom Tool" }, - { &geomove_18_pixbuf, "Georef Move Map" }, - { &mapdl_18_pixbuf, "Maps Download" }, + { &begintr_18_pixbuf, "vik-icon-Begin Track" }, + { &route_finder_18_pixbuf, "vik-icon-Route Finder" }, + { &demdl_18_pixbuf, "vik-icon-DEM Download" }, + { &showpic_18_pixbuf, "vik-icon-Show Picture" }, + { &addtr_18_pixbuf, "vik-icon-Create Track" }, + { &edtr_18_pixbuf, "vik-icon-Edit Trackpoint" }, + { &addwp_18_pixbuf, "vik-icon-Create Waypoint" }, + { &edwp_18_pixbuf, "vik-icon-Edit Waypoint" }, + { &geozoom_18_pixbuf, "vik-icon-Georef Zoom Tool" }, + { &geomove_18_pixbuf, "vik-icon-Georef Move Map" }, + { &mapdl_18_pixbuf, "vik-icon-Maps Download" }, }; static gint n_stock_icons = G_N_ELEMENTS (stock_icons); @@ -2717,7 +3134,8 @@ void vik_window_set_selected_trw_layer ( VikWindow *vw, gpointer vtl ) vw->selected_tracks = NULL; vw->selected_waypoint = NULL; vw->selected_waypoints = NULL; - vw->selected_name = NULL; + // Set highlight thickness + vik_viewport_set_highlight_thickness ( vw->viking_vvp, vik_trw_layer_get_property_tracks_line_thickness (vw->containing_vtl) ); } gpointer vik_window_get_selected_tracks ( VikWindow *vw ) @@ -2734,7 +3152,8 @@ void vik_window_set_selected_tracks ( VikWindow *vw, gpointer gl, gpointer vtl ) vw->selected_track = NULL; vw->selected_waypoint = NULL; vw->selected_waypoints = NULL; - vw->selected_name = NULL; + // Set highlight thickness + vik_viewport_set_highlight_thickness ( vw->viking_vvp, vik_trw_layer_get_property_tracks_line_thickness (vw->containing_vtl) ); } gpointer vik_window_get_selected_track ( VikWindow *vw ) @@ -2746,13 +3165,15 @@ void vik_window_set_selected_track ( VikWindow *vw, gpointer *vt, gpointer vtl, { vw->selected_track = vt; vw->containing_vtl = vtl; - vw->selected_name = name; /* Clear others */ vw->selected_vtl = NULL; vw->selected_tracks = NULL; vw->selected_waypoint = NULL; vw->selected_waypoints = NULL; + // Set highlight thickness + vik_viewport_set_highlight_thickness ( vw->viking_vvp, vik_trw_layer_get_property_tracks_line_thickness (vw->containing_vtl) ); } + gpointer vik_window_get_selected_waypoints ( VikWindow *vw ) { return vw->selected_waypoints; @@ -2767,7 +3188,6 @@ void vik_window_set_selected_waypoints ( VikWindow *vw, gpointer gl, gpointer vt vw->selected_track = NULL; vw->selected_tracks = NULL; vw->selected_waypoint = NULL; - vw->selected_name = NULL; } gpointer vik_window_get_selected_waypoint ( VikWindow *vw ) @@ -2779,7 +3199,6 @@ void vik_window_set_selected_waypoint ( VikWindow *vw, gpointer *vwp, gpointer v { vw->selected_waypoint = vwp; vw->containing_vtl = vtl; - vw->selected_name = name; /* Clear others */ vw->selected_vtl = NULL; vw->selected_track = NULL; @@ -2787,11 +3206,6 @@ void vik_window_set_selected_waypoint ( VikWindow *vw, gpointer *vwp, gpointer v vw->selected_waypoints = NULL; } -gpointer vik_window_get_selected_name ( VikWindow *vw ) -{ - return vw->selected_name; -} - gboolean vik_window_clear_highlight ( VikWindow *vw ) { gboolean need_redraw = FALSE;