]> git.street.me.uk Git - andy/viking.git/blobdiff - src/viktrwlayer.c
Add operations on waypoints into the 'new' Waypoints treeview menu.
[andy/viking.git] / src / viktrwlayer.c
index 5da99d1dc7ee1562f85448df867a5b87d54726ea..9bafdaca7c86b06934f37bcb7816cacdc67ef37c 100644 (file)
@@ -75,12 +75,11 @@ static g_hash_table_remove_all (GHashTable *ght) { g_hash_table_foreach_remove (
 #endif
 
 #define GOOGLE_DIRECTIONS_STRING "maps.google.com/maps?q=from:%s,%s+to:%s,%s&output=kml"
 #endif
 
 #define GOOGLE_DIRECTIONS_STRING "maps.google.com/maps?q=from:%s,%s+to:%s,%s&output=kml"
-#define VIK_TRW_LAYER_TRACK_GC 14
+#define VIK_TRW_LAYER_TRACK_GC 13
 #define VIK_TRW_LAYER_TRACK_GC_RATES 10
 #define VIK_TRW_LAYER_TRACK_GC_MIN 0
 #define VIK_TRW_LAYER_TRACK_GC_MAX 11
 #define VIK_TRW_LAYER_TRACK_GC_BLACK 12
 #define VIK_TRW_LAYER_TRACK_GC_RATES 10
 #define VIK_TRW_LAYER_TRACK_GC_MIN 0
 #define VIK_TRW_LAYER_TRACK_GC_MAX 11
 #define VIK_TRW_LAYER_TRACK_GC_BLACK 12
-#define VIK_TRW_LAYER_TRACK_GC_HIGHLIGHT 13
 
 #define DRAWMODE_BY_TRACK 0
 #define DRAWMODE_BY_VELOCITY 1
 
 #define DRAWMODE_BY_TRACK 0
 #define DRAWMODE_BY_VELOCITY 1
@@ -183,6 +182,7 @@ struct _VikTrwLayer {
   gboolean has_verified_thumbnails;
 
   GtkMenu *wp_right_click_menu;
   gboolean has_verified_thumbnails;
 
   GtkMenu *wp_right_click_menu;
+  GtkMenu *track_right_click_menu;
 
   /* menu */
   VikStdLayerMenuItem menu_selection;
 
   /* menu */
   VikStdLayerMenuItem menu_selection;
@@ -210,9 +210,9 @@ struct DrawingParams {
 static void vik_trw_layer_set_menu_selection(VikTrwLayer *vtl, guint16);
 static guint16 vik_trw_layer_get_menu_selection(VikTrwLayer *vtl);
 
 static void vik_trw_layer_set_menu_selection(VikTrwLayer *vtl, guint16);
 static guint16 vik_trw_layer_get_menu_selection(VikTrwLayer *vtl);
 
-static void trw_layer_delete_item ( gpointer *pass_along );
-static void trw_layer_copy_item_cb( gpointer *pass_along);
-static void trw_layer_cut_item_cb( gpointer *pass_along);
+static void trw_layer_delete_item ( gpointer pass_along[6] );
+static void trw_layer_copy_item_cb ( gpointer pass_along[6] );
+static void trw_layer_cut_item_cb ( gpointer pass_along[6] );
 
 static void trw_layer_find_maxmin_waypoints ( const gchar *name, const VikWaypoint *w, struct LatLon maxmin[2] );
 static void trw_layer_find_maxmin_tracks ( const gchar *name, GList **t, struct LatLon maxmin[2] );    
 
 static void trw_layer_find_maxmin_waypoints ( const gchar *name, const VikWaypoint *w, struct LatLon maxmin[2] );
 static void trw_layer_find_maxmin_tracks ( const gchar *name, GList **t, struct LatLon maxmin[2] );    
@@ -228,17 +228,21 @@ static void trw_layer_draw_waypoint ( const gchar *name, VikWaypoint *wp, struct
 static const gchar* trw_layer_layer_tooltip ( VikTrwLayer *vtl );
 static const gchar* trw_layer_sublayer_tooltip ( VikTrwLayer *l, gint subtype, gpointer sublayer );
 
 static const gchar* trw_layer_layer_tooltip ( VikTrwLayer *vtl );
 static const gchar* trw_layer_sublayer_tooltip ( VikTrwLayer *l, gint subtype, gpointer sublayer );
 
-static void goto_coord ( VikLayersPanel *vlp, const VikCoord *coord );
-static void trw_layer_goto_track_startpoint ( gpointer pass_along[5] );
+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_endpoint ( gpointer pass_along[6] );
-static void trw_layer_goto_track_max_speed ( gpointer pass_along[5] );
-static void trw_layer_goto_track_max_alt ( gpointer pass_along[5] );
-static void trw_layer_goto_track_min_alt ( gpointer pass_along[5] );
-static void trw_layer_auto_track_view ( gpointer pass_along[5] );
+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_timestamp ( 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_split_by_timestamp ( gpointer pass_along[6] );
 static void trw_layer_split_by_n_points ( 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_download_map_along_track_cb(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_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, const gchar* trackname, guint file_type );
 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, const gchar* trackname, guint file_type );
@@ -248,15 +252,14 @@ static void trw_layer_auto_waypoints_view ( gpointer lav[2] );
 static void trw_layer_auto_tracks_view ( 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_auto_tracks_view ( 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_merge_with_other ( gpointer pass_along[6] );
 
 /* pop-up items */
 
 /* pop-up items */
-static void trw_layer_properties_item ( gpointer pass_along[5] );
-static void trw_layer_goto_waypoint ( gpointer pass_along[5] );
-static void trw_layer_waypoint_gc_webpage ( gpointer pass_along[5] );
+static void trw_layer_properties_item ( gpointer pass_along[6] );
+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_realize_waypoint ( gchar *name, VikWaypoint *wp, gpointer pass_along[4] );
-static void trw_layer_realize_track ( gchar *name, VikTrack *track, gpointer pass_along[4] );
+static void trw_layer_realize_waypoint ( gchar *name, VikWaypoint *wp, gpointer pass_along[5] );
+static void trw_layer_realize_track ( gchar *name, VikTrack *track, gpointer pass_along[5] );
 static void init_drawing_params ( struct DrawingParams *dp, VikViewport *vp );
 
 
 static void init_drawing_params ( struct DrawingParams *dp, VikViewport *vp );
 
 
@@ -274,6 +277,11 @@ static gboolean trw_layer_paste_item ( VikTrwLayer *vtl, gint subtype, guint8 *i
 static void trw_layer_free_copied_item ( gint subtype, gpointer item );
 static void trw_layer_drag_drop_request ( VikTrwLayer *vtl_src, VikTrwLayer *vtl_dest, GtkTreeIter *src_item_iter, GtkTreePath *dest_path );
 
 static void trw_layer_free_copied_item ( gint subtype, gpointer item );
 static void trw_layer_drag_drop_request ( VikTrwLayer *vtl_src, VikTrwLayer *vtl_dest, GtkTreeIter *src_item_iter, GtkTreePath *dest_path );
 
+static gboolean trw_layer_select_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp, tool_ed_t *t );
+static gboolean trw_layer_select_move ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp, tool_ed_t *t );
+static gboolean trw_layer_select_release ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp, tool_ed_t *t );
+static gboolean trw_layer_show_selected_viewport_menu ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
+
 static void trw_layer_insert_tp_after_current_tp ( VikTrwLayer *vtl );
 static void trw_layer_cancel_last_tp ( VikTrwLayer *vtl );
 static void trw_layer_cancel_current_tp ( VikTrwLayer *vtl, gboolean destroy );
 static void trw_layer_insert_tp_after_current_tp ( VikTrwLayer *vtl );
 static void trw_layer_cancel_last_tp ( VikTrwLayer *vtl );
 static void trw_layer_cancel_current_tp ( VikTrwLayer *vtl, gboolean destroy );
@@ -468,6 +476,11 @@ VikLayerInterface vik_trw_layer_interface = {
   (VikLayerFuncFreeCopiedItem)          trw_layer_free_copied_item,
   
   (VikLayerFuncDragDropRequest)         trw_layer_drag_drop_request,
   (VikLayerFuncFreeCopiedItem)          trw_layer_free_copied_item,
   
   (VikLayerFuncDragDropRequest)         trw_layer_drag_drop_request,
+
+  (VikLayerFuncSelectClick)             trw_layer_select_click,
+  (VikLayerFuncSelectMove)              trw_layer_select_move,
+  (VikLayerFuncSelectRelease)           trw_layer_select_release,
+  (VikLayerFuncSelectedViewportMenu)    trw_layer_show_selected_viewport_menu,
 };
 
 /* for copy & paste (I think?) */
 };
 
 /* for copy & paste (I think?) */
@@ -504,7 +517,7 @@ GType vik_trw_layer_get_type ()
 
 static void trw_layer_del_item ( VikTrwLayer *vtl, gint subtype, gpointer sublayer )
 {
 
 static void trw_layer_del_item ( VikTrwLayer *vtl, gint subtype, gpointer sublayer )
 {
-  static gpointer pass_along[5];
+  static gpointer pass_along[6];
   if (!sublayer) {
     return;
   }
   if (!sublayer) {
     return;
   }
@@ -514,13 +527,14 @@ static void trw_layer_del_item ( VikTrwLayer *vtl, gint subtype, gpointer sublay
   pass_along[2] = GINT_TO_POINTER (subtype);
   pass_along[3] = sublayer;
   pass_along[4] = NULL;
   pass_along[2] = GINT_TO_POINTER (subtype);
   pass_along[3] = sublayer;
   pass_along[4] = NULL;
+  pass_along[5] = NULL;
 
   trw_layer_delete_item ( pass_along );
 }
 
 static void trw_layer_cut_item ( VikTrwLayer *vtl, gint subtype, gpointer sublayer )
 {
 
   trw_layer_delete_item ( pass_along );
 }
 
 static void trw_layer_cut_item ( VikTrwLayer *vtl, gint subtype, gpointer sublayer )
 {
-  static gpointer pass_along[5];
+  static gpointer pass_along[6];
   if (!sublayer) {
     return;
   }
   if (!sublayer) {
     return;
   }
@@ -530,12 +544,13 @@ static void trw_layer_cut_item ( VikTrwLayer *vtl, gint subtype, gpointer sublay
   pass_along[2] = GINT_TO_POINTER (subtype);
   pass_along[3] = sublayer;
   pass_along[4] = NULL;
   pass_along[2] = GINT_TO_POINTER (subtype);
   pass_along[3] = sublayer;
   pass_along[4] = NULL;
+  pass_along[5] = NULL;
 
   trw_layer_copy_item_cb(pass_along);
   trw_layer_cut_item_cb(pass_along);
 }
 
 
   trw_layer_copy_item_cb(pass_along);
   trw_layer_cut_item_cb(pass_along);
 }
 
-static void trw_layer_copy_item_cb( gpointer pass_along[5])
+static void trw_layer_copy_item_cb ( gpointer pass_along[6])
 {
   VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
   gint subtype = GPOINTER_TO_INT (pass_along[2]);
 {
   VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
   gint subtype = GPOINTER_TO_INT (pass_along[2]);
@@ -551,7 +566,7 @@ static void trw_layer_copy_item_cb( gpointer pass_along[5])
   }
 }
 
   }
 }
 
-static void trw_layer_cut_item_cb( gpointer pass_along[5])
+static void trw_layer_cut_item_cb ( gpointer pass_along[6])
 {
   trw_layer_copy_item_cb(pass_along);
   trw_layer_delete_item(pass_along);
 {
   trw_layer_copy_item_cb(pass_along);
   trw_layer_delete_item(pass_along);
@@ -897,6 +912,7 @@ VikTrwLayer *vik_trw_layer_new ( gint drawmode )
   rv->drawlines = TRUE;
   rv->wplabellayout = NULL;
   rv->wp_right_click_menu = NULL;
   rv->drawlines = TRUE;
   rv->wplabellayout = NULL;
   rv->wp_right_click_menu = NULL;
+  rv->track_right_click_menu = NULL;
   rv->waypoint_gc = NULL;
   rv->waypoint_text_gc = NULL;
   rv->waypoint_bg_gc = NULL;
   rv->waypoint_gc = NULL;
   rv->waypoint_text_gc = NULL;
   rv->waypoint_bg_gc = NULL;
@@ -946,6 +962,9 @@ void vik_trw_layer_free ( VikTrwLayer *trwlayer )
   if ( trwlayer->wp_right_click_menu )
     g_object_ref_sink ( G_OBJECT(trwlayer->wp_right_click_menu) );
 
   if ( trwlayer->wp_right_click_menu )
     g_object_ref_sink ( G_OBJECT(trwlayer->wp_right_click_menu) );
 
+  if ( trwlayer->track_right_click_menu )
+    gtk_object_sink ( GTK_OBJECT(trwlayer->track_right_click_menu) );
+
   if ( trwlayer->wplabellayout != NULL)
     g_object_unref ( G_OBJECT ( trwlayer->wplabellayout ) );
 
   if ( trwlayer->wplabellayout != NULL)
     g_object_unref ( G_OBJECT ( trwlayer->wplabellayout ) );
 
@@ -1085,7 +1104,7 @@ static void trw_layer_draw_track ( const gchar *name, VikTrack *track, struct Dr
       if ( dp->vtl && ( ( dp->vtl == vik_window_get_selected_trw_layer ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ) ||
                        ( dp->vtl->tracks == vik_window_get_selected_tracks ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ) ||
                        track == vik_window_get_selected_track ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ) ) {
       if ( dp->vtl && ( ( dp->vtl == vik_window_get_selected_trw_layer ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ) ||
                        ( dp->vtl->tracks == vik_window_get_selected_tracks ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ) ||
                        track == vik_window_get_selected_track ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ) ) {
-       main_gc = g_array_index(dp->vtl->track_gc, GdkGC *, VIK_TRW_LAYER_TRACK_GC_HIGHLIGHT);
+       main_gc = vik_viewport_get_gc_highlight (dp->vp);
       }
       else {
        if ( dp->vtl->drawmode == DRAWMODE_ALL_BLACK )
       }
       else {
        if ( dp->vtl->drawmode == DRAWMODE_ALL_BLACK )
@@ -1224,8 +1243,7 @@ static void trw_layer_draw_track ( const gchar *name, VikTrack *track, struct Dr
     }
   }
   if ( dp->vtl->drawmode == DRAWMODE_BY_TRACK )
     }
   }
   if ( dp->vtl->drawmode == DRAWMODE_BY_TRACK )
-    /* NB Don't draw in the highlight colour gc */
-    if ( ++(dp->track_gc_iter) >= VIK_TRW_LAYER_TRACK_GC_HIGHLIGHT )
+    if ( ++(dp->track_gc_iter) >= VIK_TRW_LAYER_TRACK_GC )
       dp->track_gc_iter = 0;
 }
 
       dp->track_gc_iter = 0;
 }
 
@@ -1323,10 +1341,9 @@ static void trw_layer_draw_waypoint ( const gchar *name, VikWaypoint *wp, struct
                 wp == vik_window_get_selected_waypoint ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ) {
              // Highlighted - so draw a little border around the chosen one
              // single line seems a little weak so draw 2 of them
                 wp == vik_window_get_selected_waypoint ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ) {
              // Highlighted - so draw a little border around the chosen one
              // single line seems a little weak so draw 2 of them
-             // Reuse track highlight ATM
-             vik_viewport_draw_rectangle (dp->vp, g_array_index(dp->vtl->track_gc, GdkGC *, VIK_TRW_LAYER_TRACK_GC_HIGHLIGHT), FALSE,
+             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 );
                                           x - (w/2) - 1, y - (h/2) - 1, w + 2, h + 2 );
-             vik_viewport_draw_rectangle (dp->vp, g_array_index(dp->vtl->track_gc, GdkGC *, VIK_TRW_LAYER_TRACK_GC_HIGHLIGHT), FALSE,
+             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 );
            }
          }
                                           x - (w/2) - 2, y - (h/2) - 2, w + 4, h + 4 );
            }
          }
@@ -1375,12 +1392,12 @@ static void trw_layer_draw_waypoint ( const gchar *name, VikWaypoint *wp, struct
       else
         label_y = y - dp->vtl->wp_size - height - 2;
 
       else
         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 ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ||
             dp->vtl->waypoints == vik_window_get_selected_waypoints ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ||
             wp == vik_window_get_selected_waypoint ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) )
       if ( vik_viewport_get_draw_highlight ( dp->vp ) ) {
        if ( dp->vtl == vik_window_get_selected_trw_layer ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ||
             dp->vtl->waypoints == vik_window_get_selected_waypoints ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ||
             wp == vik_window_get_selected_waypoint ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) )
-         // Reuse track highlight ATM
-         vik_viewport_draw_rectangle ( dp->vp, g_array_index(dp->vtl->track_gc, GdkGC *, VIK_TRW_LAYER_TRACK_GC_HIGHLIGHT), TRUE, label_x - 1, label_y-1,width+2,height+2);
+         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);
       }
@@ -1465,8 +1482,6 @@ static void trw_layer_new_track_gcs ( VikTrwLayer *vtl, VikViewport *vp )
 
   gc[12] = vik_viewport_new_gc ( vp, "#000000", width ); /* black / no speed data */
 
 
   gc[12] = vik_viewport_new_gc ( vp, "#000000", width ); /* black / no speed data */
 
-  gc[VIK_TRW_LAYER_TRACK_GC_HIGHLIGHT] = vik_viewport_new_gc ( vp, "#EEA500", width ); /* Highlight colour (orange)*/
-
   g_array_append_vals ( vtl->track_gc, gc, VIK_TRW_LAYER_TRACK_GC );
 }
 
   g_array_append_vals ( vtl->track_gc, gc, VIK_TRW_LAYER_TRACK_GC );
 }
 
@@ -1503,7 +1518,7 @@ VikTrwLayer *vik_trw_layer_create ( VikViewport *vp )
   return rv;
 }
 
   return rv;
 }
 
-static void trw_layer_realize_track ( gchar *name, VikTrack *track, gpointer pass_along[4] )
+static void trw_layer_realize_track ( gchar *name, VikTrack *track, gpointer pass_along[5] )
 {
   GtkTreeIter *new_iter = g_malloc(sizeof(GtkTreeIter));
 
 {
   GtkTreeIter *new_iter = g_malloc(sizeof(GtkTreeIter));
 
@@ -1520,7 +1535,7 @@ static void trw_layer_realize_track ( gchar *name, VikTrack *track, gpointer pas
     vik_treeview_item_set_visible ( (VikTreeview *) pass_along[3], (GtkTreeIter *) pass_along[1], FALSE );
 }
 
     vik_treeview_item_set_visible ( (VikTreeview *) pass_along[3], (GtkTreeIter *) pass_along[1], FALSE );
 }
 
-static void trw_layer_realize_waypoint ( gchar *name, VikWaypoint *wp, gpointer pass_along[4] )
+static void trw_layer_realize_waypoint ( gchar *name, VikWaypoint *wp, gpointer pass_along[5] )
 {
   GtkTreeIter *new_iter = g_malloc(sizeof(GtkTreeIter));
 #ifdef VIK_CONFIG_ALPHABETIZED_TRW
 {
   GtkTreeIter *new_iter = g_malloc(sizeof(GtkTreeIter));
 #ifdef VIK_CONFIG_ALPHABETIZED_TRW
@@ -1783,6 +1798,11 @@ static const gchar* trw_layer_sublayer_tooltip ( VikTrwLayer *l, gint subtype, g
  */
 gboolean vik_trw_layer_selected ( VikTrwLayer *l, gint subtype, gpointer sublayer, gint type, gpointer vlp )
 {
  */
 gboolean vik_trw_layer_selected ( VikTrwLayer *l, gint subtype, gpointer sublayer, gint type, gpointer vlp )
 {
+  // Reset
+  l->current_wp      = NULL;
+  l->current_wp_name = NULL;
+  trw_layer_cancel_current_tp ( l, FALSE );
+
   switch ( type )
     {
     case VIK_TREEVIEW_TYPE_LAYER:
   switch ( type )
     {
     case VIK_TREEVIEW_TYPE_LAYER:
@@ -1799,28 +1819,28 @@ gboolean vik_trw_layer_selected ( VikTrwLayer *l, gint subtype, gpointer sublaye
          {
          case VIK_TRW_LAYER_SUBLAYER_TRACKS:
            {
          {
          case VIK_TRW_LAYER_SUBLAYER_TRACKS:
            {
-             vik_window_set_selected_tracks ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(l), l->tracks );
+             vik_window_set_selected_tracks ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(l), l->tracks, l );
              /* Mark for redraw */
              return TRUE;
            }
            break;
          case VIK_TRW_LAYER_SUBLAYER_TRACK:
            {
              /* Mark for redraw */
              return TRUE;
            }
            break;
          case VIK_TRW_LAYER_SUBLAYER_TRACK:
            {
-             vik_window_set_selected_track ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(l), g_hash_table_lookup ( l->tracks, sublayer ) );
+             vik_window_set_selected_track ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(l), g_hash_table_lookup ( l->tracks, sublayer ), l, sublayer );
              /* Mark for redraw */
              return TRUE;
            }
            break;
          case VIK_TRW_LAYER_SUBLAYER_WAYPOINTS:
            {
              /* Mark for redraw */
              return TRUE;
            }
            break;
          case VIK_TRW_LAYER_SUBLAYER_WAYPOINTS:
            {
-             vik_window_set_selected_waypoints ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(l), l->waypoints );
+             vik_window_set_selected_waypoints ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(l), l->waypoints, l );
              /* Mark for redraw */
              return TRUE;
            }
            break;
          case VIK_TRW_LAYER_SUBLAYER_WAYPOINT:
            {
              /* Mark for redraw */
              return TRUE;
            }
            break;
          case VIK_TRW_LAYER_SUBLAYER_WAYPOINT:
            {
-             vik_window_set_selected_waypoint ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(l), g_hash_table_lookup ( l->waypoints, sublayer ) );
+             vik_window_set_selected_waypoint ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(l), g_hash_table_lookup ( l->waypoints, sublayer ), l, sublayer );
              /* Mark for redraw */
              return TRUE;
            }
              /* Mark for redraw */
              return TRUE;
            }
@@ -1937,7 +1957,7 @@ static void trw_layer_centerize ( gpointer layer_and_vlp[2] )
 {
   VikCoord coord;
   if ( vik_trw_layer_find_center ( VIK_TRW_LAYER(layer_and_vlp[0]), &coord ) )
 {
   VikCoord coord;
   if ( vik_trw_layer_find_center ( VIK_TRW_LAYER(layer_and_vlp[0]), &coord ) )
-    goto_coord ( VIK_LAYERS_PANEL(layer_and_vlp[1]), &coord );
+    goto_coord ( layer_and_vlp[1], NULL, NULL, &coord );
   else
     a_dialog_info_msg ( VIK_GTK_WINDOW_FROM_LAYER(layer_and_vlp[0]), _("This layer has no waypoints or trackpoints.") );
 }
   else
     a_dialog_info_msg ( VIK_GTK_WINDOW_FROM_LAYER(layer_and_vlp[0]), _("This layer has no waypoints or trackpoints.") );
 }
@@ -2065,6 +2085,18 @@ static void trw_layer_export_gpx ( 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_GPX );
 }
 
   trw_layer_export ( layer_and_vlp, _("Export Layer"), vik_layer_get_name(VIK_LAYER(layer_and_vlp[0])), NULL, FILE_TYPE_GPX );
 }
 
+static void trw_layer_export_kml ( gpointer layer_and_vlp[2] )
+{
+  /* 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 );
+
+  trw_layer_export ( layer_and_vlp, _("Export Layer"), auto_save_name, NULL, FILE_TYPE_KML );
+
+  g_free ( auto_save_name );
+}
+
 static void trw_layer_export_gpx_track ( gpointer pass_along[6] )
 {
   gpointer layer_and_vlp[2];
 static void trw_layer_export_gpx_track ( gpointer pass_along[6] )
 {
   gpointer layer_and_vlp[2];
@@ -2121,7 +2153,7 @@ static void trw_layer_goto_wp ( gpointer layer_and_vlp[2] )
     {
       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(VIK_LAYERS_PANEL(layer_and_vlp[1])), &(wp->coord) );
       vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(layer_and_vlp[1]) );
-      vik_treeview_select_iter ( VIK_LAYER(layer_and_vlp[0])->vt, g_hash_table_lookup ( VIK_TRW_LAYER(layer_and_vlp[0])->waypoints_iters, upname ) );
+      vik_treeview_select_iter ( VIK_LAYER(layer_and_vlp[0])->vt, g_hash_table_lookup ( VIK_TRW_LAYER(layer_and_vlp[0])->waypoints_iters, upname ), TRUE );
       break;
     }
 
       break;
     }
 
@@ -2277,7 +2309,7 @@ void vik_trw_layer_add_menu_items ( VikTrwLayer *vtl, GtkMenu *menu, gpointer vl
   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 ( _("Goto _Waypoint") );
+  item = gtk_menu_item_new_with_mnemonic ( _("Goto _Waypoint...") );
   g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_goto_wp), pass_along );
   gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
   gtk_widget_show ( item );
   g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_goto_wp), pass_along );
   gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
   gtk_widget_show ( item );
@@ -2288,22 +2320,27 @@ void vik_trw_layer_add_menu_items ( VikTrwLayer *vtl, GtkMenu *menu, gpointer vl
   gtk_widget_show ( item );
   gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), export_submenu );
   
   gtk_widget_show ( item );
   gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), export_submenu );
   
-  item = gtk_menu_item_new_with_mnemonic ( _("Export as GPS_Point") );
+  item = gtk_menu_item_new_with_mnemonic ( _("Export as GPS_Point...") );
   g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_export_gpspoint), pass_along );
   gtk_menu_shell_append (GTK_MENU_SHELL (export_submenu), item);
   gtk_widget_show ( item );
 
   g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_export_gpspoint), pass_along );
   gtk_menu_shell_append (GTK_MENU_SHELL (export_submenu), item);
   gtk_widget_show ( item );
 
-  item = gtk_menu_item_new_with_mnemonic ( _("Export as GPS_Mapper") );
+  item = gtk_menu_item_new_with_mnemonic ( _("Export as GPS_Mapper...") );
   g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_export_gpsmapper), pass_along );
   gtk_menu_shell_append (GTK_MENU_SHELL (export_submenu), item);
   gtk_widget_show ( item );
 
   g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_export_gpsmapper), pass_along );
   gtk_menu_shell_append (GTK_MENU_SHELL (export_submenu), item);
   gtk_widget_show ( item );
 
-  item = gtk_menu_item_new_with_mnemonic ( _("Export as _GPX") );
+  item = gtk_menu_item_new_with_mnemonic ( _("Export as _GPX...") );
   g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_export_gpx), pass_along );
   gtk_menu_shell_append (GTK_MENU_SHELL (export_submenu), item);
   gtk_widget_show ( item );
 
   g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_export_gpx), pass_along );
   gtk_menu_shell_append (GTK_MENU_SHELL (export_submenu), item);
   gtk_widget_show ( item );
 
-  item = gtk_menu_item_new_with_mnemonic ( _("_New Waypoint") );
+  item = gtk_menu_item_new_with_mnemonic ( _("Export as _KML...") );
+  g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_export_kml), pass_along );
+  gtk_menu_shell_append (GTK_MENU_SHELL (export_submenu), item);
+  gtk_widget_show ( item );
+
+  item = gtk_menu_item_new_with_mnemonic ( _("_New Waypoint...") );
   g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_new_wp), pass_along );
   gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
   gtk_widget_show ( item );
   g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_new_wp), pass_along );
   gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
   gtk_widget_show ( item );
@@ -2327,7 +2364,7 @@ void vik_trw_layer_add_menu_items ( VikTrwLayer *vtl, GtkMenu *menu, gpointer vl
 #endif
 
 #ifdef VIK_CONFIG_OPENSTREETMAP 
 #endif
 
 #ifdef VIK_CONFIG_OPENSTREETMAP 
-  item = gtk_menu_item_new_with_mnemonic ( _("Upload to _OSM") );
+  item = gtk_menu_item_new_with_mnemonic ( _("Upload to _OSM...") );
   g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(osm_traces_upload_cb), pass_along );
   gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
   gtk_widget_show ( item );
   g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(osm_traces_upload_cb), pass_along );
   gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
   gtk_widget_show ( item );
@@ -2366,7 +2403,7 @@ void vik_trw_layer_add_waypoint ( VikTrwLayer *vtl, gchar *name, VikWaypoint *wp
 #endif
       // Actual setting of visibility dependent on the waypoint
       vik_treeview_item_set_visible ( VIK_LAYER(vtl)->vt, iter, wp->visible );
 #endif
       // Actual setting of visibility dependent on the waypoint
       vik_treeview_item_set_visible ( VIK_LAYER(vtl)->vt, iter, wp->visible );
-      vik_treeview_select_iter ( VIK_LAYER(vtl)->vt, iter );
+      vik_treeview_select_iter ( VIK_LAYER(vtl)->vt, iter, TRUE );
       g_hash_table_insert ( vtl->waypoints_iters, name, iter );
     }
   }
       g_hash_table_insert ( vtl->waypoints_iters, name, iter );
     }
   }
@@ -2394,7 +2431,7 @@ void vik_trw_layer_add_track ( VikTrwLayer *vtl, gchar *name, VikTrack *t )
 #endif
       // Actual setting of visibility dependent on the track
       vik_treeview_item_set_visible ( VIK_LAYER(vtl)->vt, iter, t->visible );
 #endif
       // Actual setting of visibility dependent on the track
       vik_treeview_item_set_visible ( VIK_LAYER(vtl)->vt, iter, t->visible );
-      vik_treeview_select_iter ( VIK_LAYER(vtl)->vt, iter );
+      vik_treeview_select_iter ( VIK_LAYER(vtl)->vt, iter, TRUE );
       g_hash_table_insert ( vtl->tracks_iters, name, iter );
     }
   }
       g_hash_table_insert ( vtl->tracks_iters, name, iter );
     }
   }
@@ -2507,7 +2544,6 @@ static void trw_layer_drag_drop_request ( VikTrwLayer *vtl_src, VikTrwLayer *vtl
   }
 }
 
   }
 }
 
-
 gboolean vik_trw_layer_delete_track ( VikTrwLayer *vtl, const gchar *trk_name )
 {
   VikTrack *t = g_hash_table_lookup ( vtl->tracks, trk_name );
 gboolean vik_trw_layer_delete_track ( VikTrwLayer *vtl, const gchar *trk_name )
 {
   VikTrack *t = g_hash_table_lookup ( vtl->tracks, trk_name );
@@ -2516,11 +2552,11 @@ gboolean vik_trw_layer_delete_track ( VikTrwLayer *vtl, const gchar *trk_name )
   {
     GtkTreeIter *it;
     was_visible = t->visible;
   {
     GtkTreeIter *it;
     was_visible = t->visible;
-    if ( t == vtl->current_track )
+    if ( t == vtl->current_track ) {
       vtl->current_track = NULL;
       vtl->current_track = NULL;
+    }
     if ( t == vtl->magic_scissors_current_track )
       vtl->magic_scissors_current_track = NULL;
     if ( t == vtl->magic_scissors_current_track )
       vtl->magic_scissors_current_track = NULL;
-
     /* could be current_tp, so we have to check */
     trw_layer_cancel_tps_of_track ( vtl, trk_name );
 
     /* could be current_tp, so we have to check */
     trw_layer_cancel_tps_of_track ( vtl, trk_name );
 
@@ -2600,7 +2636,7 @@ void vik_trw_layer_delete_all_waypoints ( VikTrwLayer *vtl )
   vik_layer_emit_update ( VIK_LAYER(vtl) );
 }
 
   vik_layer_emit_update ( VIK_LAYER(vtl) );
 }
 
-static void trw_layer_delete_item ( gpointer pass_along[5] )
+static void trw_layer_delete_item ( gpointer pass_along[6] )
 {
   VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
   gboolean was_visible = FALSE;
 {
   VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
   gboolean was_visible = FALSE;
@@ -2617,7 +2653,7 @@ static void trw_layer_delete_item ( gpointer pass_along[5] )
 }
 
 
 }
 
 
-static void trw_layer_properties_item ( gpointer pass_along[5] )
+static void trw_layer_properties_item ( gpointer pass_along[6] )
 {
   VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
   if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_WAYPOINT )
 {
   VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
   if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_WAYPOINT )
@@ -2638,27 +2674,42 @@ static void trw_layer_properties_item ( gpointer pass_along[5] )
     if ( tr )
     {
       vik_trw_layer_propwin_run ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
     if ( tr )
     {
       vik_trw_layer_propwin_run ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
-                     vtl, tr,
-                     pass_along[1], /* vlp */ 
-                     pass_along[3]  /* track name */);
+                                 vtl, tr,
+                                 pass_along[1], /* vlp */
+                                 pass_along[3],  /* track name */
+                                 pass_along[5] );  /* vvp */
     }
   }
 }
 
     }
   }
 }
 
-static void goto_coord ( VikLayersPanel *vlp, const VikCoord *coord )
-{
-  vik_viewport_set_center_coord ( vik_layers_panel_get_viewport(vlp), coord );
-  vik_layers_panel_emit_update ( vlp );
+/*
+   Parameter 1 -> VikLayersPanel
+   Parameter 2 -> VikLayer
+   Parameter 3 -> VikViewport
+*/
+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_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_layer_emit_update ( VIK_LAYER(vl) );
+    }
+  }
 }
 
 }
 
-static void trw_layer_goto_track_startpoint ( gpointer pass_along[5] )
+static void trw_layer_goto_track_startpoint ( gpointer pass_along[6] )
 {
   GList *trps = ((VikTrack *) g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->tracks, pass_along[3] ))->trackpoints;
   if ( trps && trps->data )
 {
   GList *trps = ((VikTrack *) g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->tracks, pass_along[3] ))->trackpoints;
   if ( trps && trps->data )
-    goto_coord ( VIK_LAYERS_PANEL(pass_along[1]), &(((VikTrackpoint *) trps->data)->coord));
+    goto_coord ( pass_along[1], pass_along[0], pass_along[5], &(((VikTrackpoint *) trps->data)->coord));
 }
 
 }
 
-static void trw_layer_goto_track_center ( gpointer pass_along[5] )
+static void trw_layer_goto_track_center ( gpointer pass_along[6] )
 {
   /* FIXME: get this into viktrack.c, and should be ->trackpoints right? */
   GList **trps = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->tracks, pass_along[3] );
 {
   /* FIXME: get this into viktrack.c, and should be ->trackpoints right? */
   GList **trps = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->tracks, pass_along[3] );
@@ -2670,7 +2721,7 @@ static void trw_layer_goto_track_center ( gpointer pass_along[5] )
     average.lat = (maxmin[0].lat+maxmin[1].lat)/2;
     average.lon = (maxmin[0].lon+maxmin[1].lon)/2;
     vik_coord_load_from_latlon ( &coord, VIK_TRW_LAYER(pass_along[0])->coord_mode, &average );
     average.lat = (maxmin[0].lat+maxmin[1].lat)/2;
     average.lon = (maxmin[0].lon+maxmin[1].lon)/2;
     vik_coord_load_from_latlon ( &coord, VIK_TRW_LAYER(pass_along[0])->coord_mode, &average );
-    goto_coord ( VIK_LAYERS_PANEL(pass_along[1]), &coord);
+    goto_coord ( pass_along[1], pass_along[0], pass_along[5], &coord);
   }
 }
 
   }
 }
 
@@ -2683,7 +2734,7 @@ static void trw_layer_extend_track_end ( gpointer pass_along[6] )
   vik_window_enable_layer_tool ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), VIK_LAYER_TRW, TOOL_CREATE_TRACK);
 
   if ( track->trackpoints )
   vik_window_enable_layer_tool ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), VIK_LAYER_TRW, TOOL_CREATE_TRACK);
 
   if ( track->trackpoints )
-    goto_coord ( VIK_LAYERS_PANEL(pass_along[1]), &(((VikTrackpoint *)g_list_last(track->trackpoints)->data)->coord) );
+    goto_coord ( pass_along[1], pass_along[0], pass_along[5], &(((VikTrackpoint *)g_list_last(track->trackpoints)->data)->coord) );
 }
 
 /**
 }
 
 /**
@@ -2701,7 +2752,7 @@ static void trw_layer_extend_track_end_ms ( gpointer pass_along[6] )
   vtl->magic_scissors_started = TRUE;
 
   if ( track->trackpoints )
   vtl->magic_scissors_started = TRUE;
 
   if ( track->trackpoints )
-    goto_coord ( VIK_LAYERS_PANEL(pass_along[1]), &last_coord) ;
+    goto_coord ( pass_along[1], pass_along[0], pass_along[5], &last_coord) ;
 
 }
 
 
 }
 
@@ -2720,31 +2771,31 @@ static void trw_layer_goto_track_endpoint ( gpointer pass_along[6] )
   if ( !trps )
     return;
   trps = g_list_last(trps);
   if ( !trps )
     return;
   trps = g_list_last(trps);
-  goto_coord ( VIK_LAYERS_PANEL(pass_along[1]), &(((VikTrackpoint *) trps->data)->coord));
+  goto_coord ( pass_along[1], pass_along[0], pass_along[5], &(((VikTrackpoint *) trps->data)->coord));
 }
 
 }
 
-static void trw_layer_goto_track_max_speed ( gpointer pass_along[5] )
+static void trw_layer_goto_track_max_speed ( gpointer pass_along[6] )
 {
   VikTrackpoint* vtp = vik_track_get_tp_by_max_speed ( g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->tracks, pass_along[3] ) );
   if ( !vtp )
     return;
 {
   VikTrackpoint* vtp = vik_track_get_tp_by_max_speed ( g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->tracks, pass_along[3] ) );
   if ( !vtp )
     return;
-  goto_coord ( VIK_LAYERS_PANEL(pass_along[1]), &(vtp->coord));
+  goto_coord ( pass_along[1], pass_along[0], pass_along[5], &(vtp->coord));
 }
 
 }
 
-static void trw_layer_goto_track_max_alt ( gpointer pass_along[5] )
+static void trw_layer_goto_track_max_alt ( gpointer pass_along[6] )
 {
   VikTrackpoint* vtp = vik_track_get_tp_by_max_alt ( g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->tracks, pass_along[3] ) );
   if ( !vtp )
     return;
 {
   VikTrackpoint* vtp = vik_track_get_tp_by_max_alt ( g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->tracks, pass_along[3] ) );
   if ( !vtp )
     return;
-  goto_coord ( VIK_LAYERS_PANEL(pass_along[1]), &(vtp->coord));
+  goto_coord ( pass_along[1], pass_along[0], pass_along[5], &(vtp->coord));
 }
 
 }
 
-static void trw_layer_goto_track_min_alt ( gpointer pass_along[5] )
+static void trw_layer_goto_track_min_alt ( gpointer pass_along[6] )
 {
   VikTrackpoint* vtp = vik_track_get_tp_by_min_alt ( g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->tracks, pass_along[3] ) );
   if ( !vtp )
     return;
 {
   VikTrackpoint* vtp = vik_track_get_tp_by_min_alt ( g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->tracks, pass_along[3] ) );
   if ( !vtp )
     return;
-  goto_coord ( VIK_LAYERS_PANEL(pass_along[1]), &(vtp->coord));
+  goto_coord ( pass_along[1], pass_along[0], pass_along[5], &(vtp->coord));
 }
 
 /* 
 }
 
 /* 
@@ -2757,12 +2808,20 @@ static void trw_layer_auto_track_view ( gpointer pass_along[5] )
   {
     struct LatLon maxmin[2] = { {0,0}, {0,0} };
     trw_layer_find_maxmin_tracks ( NULL, trps, maxmin );
   {
     struct LatLon maxmin[2] = { {0,0}, {0,0} };
     trw_layer_find_maxmin_tracks ( NULL, trps, maxmin );
-
-    trw_layer_zoom_to_show_latlons ( VIK_TRW_LAYER(pass_along[0]), vik_layers_panel_get_viewport (VIK_LAYERS_PANEL(pass_along[1])), maxmin );
-    vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(pass_along[1]) );
+    trw_layer_zoom_to_show_latlons ( VIK_TRW_LAYER(pass_along[0]), pass_along[5], maxmin );
+    if ( pass_along[1] )
+      vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(pass_along[1]) );
+    else
+      vik_layer_emit_update ( VIK_LAYER(pass_along[0]) );
   }
 }
 
   }
 }
 
+static void trw_layer_edit_trackpoint ( gpointer pass_along[6] )
+{
+  VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
+  trw_layer_tpwin_init ( vtl );
+}
+
 /*************************************
  * merge/split by time routines 
  *************************************/
 /*************************************
  * merge/split by time routines 
  *************************************/
@@ -3068,7 +3127,7 @@ static void trw_layer_split_by_timestamp ( gpointer pass_along[6] )
     }
     if (ts - prev_ts > thr*60) {
       /* flush accumulated trackpoints into new list */
     }
     if (ts - prev_ts > thr*60) {
       /* flush accumulated trackpoints into new list */
-      newlists = g_list_prepend(newlists, g_list_reverse(newtps));
+      newlists = g_list_append(newlists, g_list_reverse(newtps));
       newtps = NULL;
     }
 
       newtps = NULL;
     }
 
@@ -3078,30 +3137,33 @@ static void trw_layer_split_by_timestamp ( gpointer pass_along[6] )
     iter = g_list_next(iter);
   }
   if (newtps) {
     iter = g_list_next(iter);
   }
   if (newtps) {
-      newlists = g_list_prepend(newlists, g_list_reverse(newtps));
+      newlists = g_list_append(newlists, g_list_reverse(newtps));
   }
 
   /* put lists of trackpoints into tracks */
   iter = newlists;
   i = 1;
   }
 
   /* put lists of trackpoints into tracks */
   iter = newlists;
   i = 1;
-  while (iter) {
-    gchar *new_tr_name;
-    VikTrack *tr;
+  // Only bother updating if the split results in new tracks
+  if (g_list_length (newlists) > 1) {
+    while (iter) {
+      gchar *new_tr_name;
+      VikTrack *tr;
 
 
-    tr = vik_track_new();
-    tr->visible = track->visible;
-    tr->trackpoints = (GList *)(iter->data);
+      tr = vik_track_new();
+      tr->visible = track->visible;
+      tr->trackpoints = (GList *)(iter->data);
 
 
-    new_tr_name = g_strdup_printf("%s #%d", (gchar *) pass_along[3], i++);
-    vik_trw_layer_add_track(VIK_TRW_LAYER(pass_along[0]), new_tr_name, tr);
-    /*    g_print("adding track %s, times %d - %d\n", new_tr_name, VIK_TRACKPOINT(tr->trackpoints->data)->timestamp,
+      new_tr_name = g_strdup_printf("%s #%d", (gchar *) pass_along[3], i++);
+      vik_trw_layer_add_track(VIK_TRW_LAYER(pass_along[0]), 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);*/
 
          VIK_TRACKPOINT(g_list_last(tr->trackpoints)->data)->timestamp);*/
 
-    iter = g_list_next(iter);
+      iter = g_list_next(iter);
+    }
+    vik_trw_layer_delete_track(VIK_TRW_LAYER(pass_along[0]), (gchar *)pass_along[3]);
+    vik_layer_emit_update(VIK_LAYER(pass_along[0]));
   }
   g_list_free(newlists);
   }
   g_list_free(newlists);
-  vik_trw_layer_delete_track(VIK_TRW_LAYER(pass_along[0]), (gchar *)pass_along[3]);
-  vik_layer_emit_update(VIK_LAYER(pass_along[0]));
 }
 
 /**
 }
 
 /**
@@ -3182,14 +3244,14 @@ static void trw_layer_split_by_n_points ( gpointer pass_along[6] )
 /* end of split/merge routines */
 
 
 /* end of split/merge routines */
 
 
-static void trw_layer_goto_waypoint ( gpointer pass_along[5] )
+static void trw_layer_goto_waypoint ( gpointer pass_along[6] )
 {
   VikWaypoint *wp = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->waypoints, pass_along[3] );
   if ( wp )
 {
   VikWaypoint *wp = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->waypoints, pass_along[3] );
   if ( wp )
-    goto_coord ( VIK_LAYERS_PANEL(pass_along[1]), &(wp->coord) );
+    goto_coord ( pass_along[1], pass_along[0], pass_along[5], &(wp->coord) );
 }
 
 }
 
-static void trw_layer_waypoint_gc_webpage ( gpointer pass_along[5] )
+static void trw_layer_waypoint_gc_webpage ( gpointer pass_along[6] )
 {
   gchar *webpage = g_strdup_printf("http://www.geocaching.com/seek/cache_details.aspx?wp=%s", (gchar *) pass_along[3] );
   open_url(VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(pass_along[0])), webpage);
 {
   gchar *webpage = g_strdup_printf("http://www.geocaching.com/seek/cache_details.aspx?wp=%s", (gchar *) pass_along[3] );
   open_url(VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(pass_along[0])), webpage);
@@ -3296,7 +3358,7 @@ static gboolean is_valid_geocache_name ( gchar *str )
   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]));
 }
 
   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 )
+static void trw_layer_track_use_with_filter ( gpointer pass_along[6] )
 {
   gchar *track_name = (gchar *) pass_along[3];
   VikTrack *tr = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->tracks, track_name );
 {
   gchar *track_name = (gchar *) pass_along[3];
   VikTrack *tr = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->tracks, track_name );
@@ -3309,7 +3371,7 @@ static gboolean is_valid_google_route ( VikTrwLayer *vtl, const gchar *track_nam
   return ( tr && tr->comment && strlen(tr->comment) > 7 && !strncmp(tr->comment, "from:", 5) );
 }
 
   return ( tr && tr->comment && strlen(tr->comment) > 7 && !strncmp(tr->comment, "from:", 5) );
 }
 
-static void trw_layer_track_google_route_webpage( gpointer *pass_along )
+static void trw_layer_track_google_route_webpage ( gpointer pass_along[6] )
 {
   gchar *track_name = (gchar *) pass_along[3];
   VikTrack *tr = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->tracks, track_name );
 {
   gchar *track_name = (gchar *) pass_along[3];
   VikTrack *tr = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->tracks, track_name );
@@ -3322,11 +3384,12 @@ static void trw_layer_track_google_route_webpage( gpointer *pass_along )
   }
 }
 
   }
 }
 
-/* vlp can be NULL if necessary - i.e. right-click from a tool -- but be careful, some functions may try to use it */
-gboolean vik_trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *menu, gpointer vlp, gint subtype, gpointer sublayer, GtkTreeIter *iter )
+/* vlp can be NULL if necessary - i.e. right-click from a tool */
+/* viewpoint is now available instead */
+gboolean vik_trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *menu, gpointer vlp, gint subtype, gpointer sublayer, GtkTreeIter *iter, VikViewport *vvp )
 {
   static GtkTreeIter staticiter;
 {
   static GtkTreeIter staticiter;
-  static gpointer pass_along[5];
+  static gpointer pass_along[6];
   GtkWidget *item;
   gboolean rv = FALSE;
 
   GtkWidget *item;
   gboolean rv = FALSE;
 
@@ -3334,8 +3397,11 @@ gboolean vik_trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *menu,
   pass_along[1] = vlp;
   pass_along[2] = GINT_TO_POINTER (subtype);
   pass_along[3] = sublayer;
   pass_along[1] = vlp;
   pass_along[2] = GINT_TO_POINTER (subtype);
   pass_along[3] = sublayer;
-  staticiter = *iter; /* will exist after function has ended */
-  pass_along[4] = &staticiter;
+  if ( iter ) {
+    staticiter = *iter; /* will exist after function has ended */
+    pass_along[4] = &staticiter;
+  }
+  pass_along[5] = vvp;
 
   if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT || subtype == VIK_TRW_LAYER_SUBLAYER_TRACK )
   {
 
   if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT || subtype == VIK_TRW_LAYER_SUBLAYER_TRACK )
   {
@@ -3392,6 +3458,7 @@ gboolean vik_trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *menu,
          item = gtk_menu_item_new ();
          gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
          gtk_widget_show ( item );
          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") );
        }
 
         item = gtk_menu_item_new_with_mnemonic ( _("_Visit Geocache Webpage") );
@@ -3400,18 +3467,51 @@ gboolean vik_trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *menu,
         gtk_widget_show ( item );
       }
 
         gtk_widget_show ( item );
       }
 
+      VikWaypoint *wp = g_hash_table_lookup ( VIK_TRW_LAYER(l)->waypoints, sublayer );
+
+      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;
+
+        item = gtk_menu_item_new_with_mnemonic ( _("_Show Picture...") );
+        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 ( vlp && (subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINTS || subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT) )
   {
     rv = TRUE;
     }
   }
 
   if ( vlp && (subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINTS || subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT) )
   {
     rv = TRUE;
-    item = gtk_menu_item_new_with_mnemonic ( _("_New Waypoint") );
+    item = gtk_menu_item_new_with_mnemonic ( _("_New Waypoint...") );
     g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_new_wp), pass_along );
     gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
     gtk_widget_show ( item );
   }
 
     g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_new_wp), pass_along );
     gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
     gtk_widget_show ( item );
   }
 
+  if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINTS )
+  {
+    item = gtk_menu_item_new_with_mnemonic ( _("_View All Waypoints") );
+    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_auto_waypoints_view), pass_along );
+    gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+    gtk_widget_show ( item );
+
+    item = gtk_menu_item_new_with_mnemonic ( _("Goto _Waypoint...") );
+    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_goto_wp), pass_along );
+    gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+    gtk_widget_show ( item );
+  }
+
   if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK )
   {
     GtkWidget *goto_submenu;
   if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK )
   {
     GtkWidget *goto_submenu;
@@ -3460,7 +3560,7 @@ gboolean vik_trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *menu,
     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 ( _("_Merge By Time") );
+    item = gtk_menu_item_new_with_mnemonic ( _("_Merge By Time...") );
     g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_merge_by_timestamp), pass_along );
     gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
     gtk_widget_show ( item );
     g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_merge_by_timestamp), pass_along );
     gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
     gtk_widget_show ( item );
@@ -3470,27 +3570,30 @@ gboolean vik_trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *menu,
     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 ( _("_Split By Time") );
+    item = gtk_menu_item_new_with_mnemonic ( _("_Split By Time...") );
     g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_split_by_timestamp), pass_along );
     gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
     gtk_widget_show ( item );
 
     g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_split_by_timestamp), pass_along );
     gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
     gtk_widget_show ( item );
 
-    item = gtk_menu_item_new_with_mnemonic ( _("Split By _Number of Points") );
+    item = gtk_menu_item_new_with_mnemonic ( _("Split By _Number of Points...") );
     g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_split_by_n_points), pass_along );
     gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
     gtk_widget_show ( item );
 
     g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_split_by_n_points), pass_along );
     gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
     gtk_widget_show ( item );
 
-    item = gtk_menu_item_new_with_mnemonic ( _("Down_load Maps Along Track...") );
-    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 );
+    /* ATM This function is only available via the layers panel, due to the method in finding out the maps in use */
+    if ( vlp ) {
+      item = gtk_menu_item_new_with_mnemonic ( _("Down_load Maps Along Track...") );
+      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_menu_item_new_with_mnemonic ( _("_Apply DEM Data") );
     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 );
 
 
     item = gtk_menu_item_new_with_mnemonic ( _("_Apply DEM Data") );
     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 );
 
-    item = gtk_menu_item_new_with_mnemonic ( _("Export Trac_k as GPX") );
+    item = gtk_menu_item_new_with_mnemonic ( _("Export Trac_k as GPX...") );
     g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_export_gpx_track), pass_along );
     gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
     gtk_widget_show ( item );
     g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_export_gpx_track), pass_along );
     gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
     gtk_widget_show ( item );
@@ -3506,7 +3609,7 @@ gboolean vik_trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *menu,
     gtk_widget_show ( item );
 
 #ifdef VIK_CONFIG_OPENSTREETMAP
     gtk_widget_show ( item );
 
 #ifdef VIK_CONFIG_OPENSTREETMAP
-    item = gtk_menu_item_new_with_mnemonic ( _("Upload to _OSM") );
+    item = gtk_menu_item_new_with_mnemonic ( _("Upload to _OSM...") );
     g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(osm_traces_upload_track_cb), pass_along );
     gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
     gtk_widget_show ( item );
     g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(osm_traces_upload_track_cb), pass_along );
     gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
     gtk_widget_show ( item );
@@ -3525,13 +3628,31 @@ gboolean vik_trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *menu,
     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 = a_acquire_track_menu ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(l)), vlp,
-                                 vik_layers_panel_get_viewport(VIK_LAYERS_PANEL(vlp)),
-                                 g_hash_table_lookup ( l->tracks, (gchar *) sublayer ) );
-    if ( item ) {
-      gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+    /* ATM This function is only available via the layers panel, due to needing a vlp */
+    if ( vlp ) {
+      item = a_acquire_track_menu ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(l)), vlp,
+                                   vik_layers_panel_get_viewport(VIK_LAYERS_PANEL(vlp)),
+                                   g_hash_table_lookup ( l->tracks, (gchar *) sublayer ) );
+      if ( item ) {
+       gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+       gtk_widget_show ( item );
+      }
+    }
+
+    // Only show on viewport popmenu when a trackpoint is selected
+    if ( ! vlp && l->current_tpl ) {
+      // Add separator
+      item = gtk_menu_item_new ();
+      gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
+      gtk_widget_show ( item );
+
+      item = gtk_image_menu_item_new_with_mnemonic ( _("_Edit Trackpoint") );
+      gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_PROPERTIES, GTK_ICON_SIZE_MENU) );
+      g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_edit_trackpoint), pass_along );
+      gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
       gtk_widget_show ( item );
       gtk_widget_show ( item );
-    }  
+    }
+
   }
 
   return rv;
   }
 
   return rv;
@@ -3788,16 +3909,30 @@ static void waypoint_search_closest_tp ( gchar *name, VikWaypoint *wp, WPSearchP
     return;
 
   vik_viewport_coord_to_screen ( params->vvp, &(wp->coord), &x, &y );
     return;
 
   vik_viewport_coord_to_screen ( params->vvp, &(wp->coord), &x, &y );
-  if ( abs (x - params->x) <= WAYPOINT_SIZE_APPROX && abs (y - params->y) <= WAYPOINT_SIZE_APPROX &&
-      ((!params->closest_wp) ||        /* was the old waypoint we already found closer than this one? */
-        abs(x - params->x)+abs(y - params->y) < abs(x - params->closest_x)+abs(y - params->closest_y)))
-  {
-    params->closest_wp_name = name;
-    params->closest_wp = wp;
-    params->closest_x = x;
-    params->closest_y = y;
+
+  // If waypoint has an image then use the image size to select
+  if ( wp->image ) {
+    gint slackx, slacky;
+    slackx = wp->image_width / 2;
+    slacky = wp->image_height / 2;
+
+    if (    x <= params->x + slackx && x >= params->x - slackx
+         && y <= params->y + slacky && y >= params->y - slacky ) {
+      params->closest_wp_name = name;
+      params->closest_wp = wp;
+      params->closest_x = x;
+      params->closest_y = y;
+    }
   }
   }
+  else if ( abs (x - params->x) <= WAYPOINT_SIZE_APPROX && abs (y - params->y) <= WAYPOINT_SIZE_APPROX &&
+           ((!params->closest_wp) ||        /* was the old waypoint we already found closer than this one? */
+            abs(x - params->x)+abs(y - params->y) < abs(x - params->closest_x)+abs(y - params->closest_y)))
+    {
+      params->closest_wp_name = name;
+      params->closest_wp = wp;
+      params->closest_x = x;
+      params->closest_y = y;
+    }
 }
 
 static void track_search_closest_tp ( gchar *name, VikTrack *t, TPSearchParams *params )
 }
 
 static void track_search_closest_tp ( gchar *name, VikTrack *t, TPSearchParams *params )
@@ -3853,6 +3988,263 @@ static VikWaypoint *closest_wp_in_five_pixel_interval ( VikTrwLayer *vtl, VikVie
   return params.closest_wp;
 }
 
   return params.closest_wp;
 }
 
+// Some forward declarations
+static void marker_begin_move ( tool_ed_t *t, gint x, gint y );
+static void marker_moveto ( tool_ed_t *t, gint x, gint y );
+static void marker_end_move ( tool_ed_t *t );
+//
+
+static gboolean trw_layer_select_move ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp, tool_ed_t* t )
+{
+  if ( t->holding ) {
+    VikCoord new_coord;
+    vik_viewport_screen_to_coord ( vvp, event->x, event->y, &new_coord );
+
+    // Here always allow snapping back to the original location
+    //  this is useful when one decides not to move the thing afterall
+    // If one wants to move the item only a little bit then don't hold down the 'snap' key!
+    // snap to TP
+    if ( event->state & GDK_CONTROL_MASK )
+    {
+      VikTrackpoint *tp = closest_tp_in_five_pixel_interval ( vtl, vvp, event->x, event->y );
+      if ( tp )
+        new_coord = tp->coord;
+    }
+
+    // snap to WP
+    if ( event->state & GDK_SHIFT_MASK )
+    {
+      VikWaypoint *wp = closest_wp_in_five_pixel_interval ( vtl, vvp, event->x, event->y );
+      if ( wp )
+        new_coord = wp->coord;
+    }
+    
+    gint x, y;
+    vik_viewport_coord_to_screen ( vvp, &new_coord, &x, &y );
+
+    marker_moveto ( t, x, y );
+
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static gboolean trw_layer_select_release ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp, tool_ed_t* t )
+{
+  if ( t->holding && event->button == 1 )
+  {
+    VikCoord new_coord;
+    vik_viewport_screen_to_coord ( vvp, event->x, event->y, &new_coord );
+
+    // snap to TP
+    if ( event->state & GDK_CONTROL_MASK )
+    {
+      VikTrackpoint *tp = closest_tp_in_five_pixel_interval ( vtl, vvp, event->x, event->y );
+      if ( tp )
+        new_coord = tp->coord;
+    }
+
+    // snap to WP
+    if ( event->state & GDK_SHIFT_MASK )
+    {
+      VikWaypoint *wp = closest_wp_in_five_pixel_interval ( vtl, vvp, event->x, event->y );
+      if ( wp )
+        new_coord = wp->coord;
+    }
+
+    marker_end_move ( t );
+
+    // Determine if working on a waypoint or a trackpoint
+    if ( t->is_waypoint )
+      vtl->current_wp->coord = new_coord;
+    else {
+      if ( vtl->current_tpl ) {
+       VIK_TRACKPOINT(vtl->current_tpl->data)->coord = new_coord;
+      
+       if ( vtl->tpwin )
+         vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track_name );
+
+       // Don't really know what this is for but seems like it might be handy...
+       /* can't join with itself! */
+       trw_layer_cancel_last_tp ( vtl );
+      }
+    }
+
+    // Reset
+    vtl->current_wp      = NULL;
+    vtl->current_wp_name = NULL;
+    trw_layer_cancel_current_tp ( vtl, FALSE );
+
+    vik_layer_emit_update ( VIK_LAYER(vtl) );
+    return TRUE;
+  }
+  return FALSE;
+}
+
+/*
+  Returns true if a waypoint or track is found near the requested event position for this particular layer
+  The item found is automatically selected
+  This is a tool like feature but routed via the layer interface, since it's instigated by a 'global' layer tool in vikwindow.c
+ */
+static gboolean trw_layer_select_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp, tool_ed_t* tet )
+{
+  if ( event->button != 1 )
+    return FALSE;
+
+  if (!vtl || vtl->vl.type != VIK_LAYER_TRW)
+    return FALSE;
+
+  if ( !vtl->tracks_visible && !vtl->waypoints_visible )
+    return FALSE;
+
+  // Go for waypoints first as these often will be near a track, but it's likely the wp is wanted rather then the track
+
+  if (vtl->waypoints_visible) {
+    WPSearchParams wp_params;
+    wp_params.vvp = vvp;
+    wp_params.x = event->x;
+    wp_params.y = event->y;
+    wp_params.closest_wp_name = NULL;
+    wp_params.closest_wp = NULL;
+
+    g_hash_table_foreach ( vtl->waypoints, (GHFunc) waypoint_search_closest_tp, &wp_params);
+
+    if ( wp_params.closest_wp )  {
+
+      // Select
+      vik_treeview_select_iter ( VIK_LAYER(vtl)->vt, g_hash_table_lookup ( vtl->waypoints_iters, wp_params.closest_wp_name ), TRUE );
+
+      // Too easy to move it so must be holding shift to start immediately moving it
+      //   or otherwise be previously selected
+      if ( event->state & GDK_SHIFT_MASK ||
+          vtl->current_wp == wp_params.closest_wp ) {
+       // Put into 'move buffer'
+       // NB vvp & vw already set in tet
+       tet->vtl = (gpointer)vtl;
+       tet->is_waypoint = TRUE;
+      
+       marker_begin_move (tet, event->x, event->y);
+      }
+
+      vtl->current_wp =      wp_params.closest_wp;
+      vtl->current_wp_name = wp_params.closest_wp_name;
+
+      vik_layer_emit_update ( VIK_LAYER(vtl) );
+
+      return TRUE;
+    }
+  }
+
+  if (vtl->tracks_visible) {
+    TPSearchParams tp_params;
+    tp_params.vvp = vvp;
+    tp_params.x = event->x;
+    tp_params.y = event->y;
+    tp_params.closest_track_name = NULL;
+    tp_params.closest_tp = NULL;
+
+    g_hash_table_foreach ( vtl->tracks, (GHFunc) track_search_closest_tp, &tp_params);
+
+    if ( tp_params.closest_tp )  {
+
+      // Always select + highlight the track
+      vik_treeview_select_iter ( VIK_LAYER(vtl)->vt, g_hash_table_lookup ( vtl->tracks_iters, tp_params.closest_track_name ), TRUE );
+
+      tet->is_waypoint = FALSE;
+
+      // Select the Trackpoint
+      // Can move it immediately when control held or it's the previously selected tp
+      if ( event->state & GDK_CONTROL_MASK ||
+          vtl->current_tpl == tp_params.closest_tpl ) {
+       // Put into 'move buffer'
+       // NB vvp & vw already set in tet
+       tet->vtl = (gpointer)vtl;
+       marker_begin_move (tet, event->x, event->y);
+      }
+
+      vtl->current_tpl = tp_params.closest_tpl;
+      vtl->current_tp_track_name = tp_params.closest_track_name;
+
+      if ( vtl->tpwin )
+       vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track_name );
+
+      vik_layer_emit_update ( VIK_LAYER(vtl) );
+      return TRUE;
+    }
+  }
+
+  /* these aren't the droids you're looking for */
+  vtl->current_wp      = NULL;
+  vtl->current_wp_name = NULL;
+  trw_layer_cancel_current_tp ( vtl, FALSE );
+
+  return FALSE;
+}
+
+static gboolean trw_layer_show_selected_viewport_menu ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
+{
+  if ( event->button != 3 )
+    return FALSE;
+
+  if (!vtl || vtl->vl.type != VIK_LAYER_TRW)
+    return FALSE;
+
+  if ( !vtl->tracks_visible && !vtl->waypoints_visible )
+    return FALSE;
+
+  /* Post menu for the currently selected item */
+
+  /* See if a track is selected */
+  VikTrack *track = (VikTrack*)vik_window_get_selected_track ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(vtl) );
+  if ( track && track->visible ) {
+
+    if ( vik_window_get_selected_name ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(vtl) ) ) {
+
+      if ( vtl->track_right_click_menu )
+       gtk_object_sink ( GTK_OBJECT(vtl->track_right_click_menu) );
+
+      vtl->track_right_click_menu = GTK_MENU ( gtk_menu_new () );
+      
+      vik_trw_layer_sublayer_add_menu_items ( vtl,
+                                             vtl->track_right_click_menu,
+                                             NULL,
+                                             VIK_TRW_LAYER_SUBLAYER_TRACK,
+                                             vik_window_get_selected_name ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(vtl) ),
+                                             g_hash_table_lookup ( vtl->tracks_iters, vik_window_get_selected_name ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(vtl) ) ),
+                                             vvp);
+
+      gtk_menu_popup ( vtl->track_right_click_menu, NULL, NULL, NULL, NULL, event->button, gtk_get_current_event_time() );
+       
+      return TRUE;
+    }
+  }
+
+  /* See if a waypoint is selected */
+  VikWaypoint *waypoint = (VikWaypoint*)vik_window_get_selected_waypoint ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(vtl) );
+  if ( waypoint && waypoint->visible ) {
+    if ( vik_window_get_selected_name ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(vtl) ) ) {
+
+      if ( vtl->wp_right_click_menu )
+       gtk_object_sink ( GTK_OBJECT(vtl->wp_right_click_menu) );
+
+      vtl->wp_right_click_menu = GTK_MENU ( gtk_menu_new () );
+      vik_trw_layer_sublayer_add_menu_items ( vtl,
+                                             vtl->wp_right_click_menu,
+                                             NULL,
+                                             VIK_TRW_LAYER_SUBLAYER_WAYPOINT,
+                                             vik_window_get_selected_name ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(vtl) ),
+                                             g_hash_table_lookup ( vtl->waypoints_iters, vik_window_get_selected_name ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(vtl) ) ),
+                                             vvp);
+      gtk_menu_popup ( vtl->wp_right_click_menu, NULL, NULL, NULL, NULL, event->button, gtk_get_current_event_time() );
+
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+
 /* background drawing hook, to be passed the viewport */
 static gboolean tool_sync_done = TRUE;
 
 /* background drawing hook, to be passed the viewport */
 static gboolean tool_sync_done = TRUE;
 
@@ -3866,13 +4258,6 @@ static gboolean tool_sync(gpointer data)
   return FALSE;
 }
 
   return FALSE;
 }
 
-typedef struct {
-  VikViewport *vvp;
-  gboolean holding;
-  GdkGC *gc;
-  int oldx, oldy;
-} tool_ed_t;
-
 static void marker_begin_move ( tool_ed_t *t, gint x, gint y )
 {
   t->holding = TRUE;
 static void marker_begin_move ( tool_ed_t *t, gint x, gint y )
 {
   t->holding = TRUE;
@@ -3974,7 +4359,7 @@ static gboolean tool_edit_waypoint_click ( VikTrwLayer *vtl, GdkEventButton *eve
     vtl->current_wp_name = params.closest_wp_name;
 
     if ( params.closest_wp )
     vtl->current_wp_name = params.closest_wp_name;
 
     if ( params.closest_wp )
-      vik_treeview_select_iter ( VIK_LAYER(vtl)->vt, g_hash_table_lookup ( vtl->waypoints_iters, vtl->current_wp_name ) );
+      vik_treeview_select_iter ( VIK_LAYER(vtl)->vt, g_hash_table_lookup ( vtl->waypoints_iters, vtl->current_wp_name ), TRUE );
 
     /* could make it so don't update if old WP is off screen and new is null but oh well */
     vik_layer_emit_update ( VIK_LAYER(vtl) );
 
     /* could make it so don't update if old WP is off screen and new is null but oh well */
     vik_layer_emit_update ( VIK_LAYER(vtl) );
@@ -4068,7 +4453,7 @@ static gboolean tool_edit_waypoint_release ( VikTrwLayer *vtl, GdkEventButton *e
     if ( vtl->wp_right_click_menu )
       g_object_ref_sink ( G_OBJECT(vtl->wp_right_click_menu) );
     vtl->wp_right_click_menu = GTK_MENU ( gtk_menu_new () );
     if ( vtl->wp_right_click_menu )
       g_object_ref_sink ( G_OBJECT(vtl->wp_right_click_menu) );
     vtl->wp_right_click_menu = GTK_MENU ( gtk_menu_new () );
-    vik_trw_layer_sublayer_add_menu_items ( vtl, vtl->wp_right_click_menu, NULL, VIK_TRW_LAYER_SUBLAYER_WAYPOINT, vtl->current_wp_name, g_hash_table_lookup ( vtl->waypoints_iters, vtl->current_wp_name  ) );
+    vik_trw_layer_sublayer_add_menu_items ( vtl, vtl->wp_right_click_menu, NULL, VIK_TRW_LAYER_SUBLAYER_WAYPOINT, vtl->current_wp_name, g_hash_table_lookup ( vtl->waypoints_iters, vtl->current_wp_name ), vvp );
     gtk_menu_popup ( vtl->wp_right_click_menu, NULL, NULL, NULL, NULL, event->button, gtk_get_current_event_time() );
     vtl->waypoint_rightclick = FALSE;
   }
     gtk_menu_popup ( vtl->wp_right_click_menu, NULL, NULL, NULL, NULL, event->button, gtk_get_current_event_time() );
     vtl->waypoint_rightclick = FALSE;
   }
@@ -4239,7 +4624,6 @@ static gboolean tool_new_track_click ( VikTrwLayer *vtl, GdkEventButton *event,
   return TRUE;
 }
 
   return TRUE;
 }
 
-
 /*** New waypoint ****/
 
 static gpointer tool_new_waypoint_create ( VikWindow *vw, VikViewport *vvp)
 /*** New waypoint ****/
 
 static gpointer tool_new_waypoint_create ( VikWindow *vw, VikViewport *vvp)
@@ -4323,7 +4707,7 @@ static gboolean tool_edit_trackpoint_click ( VikTrwLayer *vtl, GdkEventButton *e
   {
     vtl->current_tpl = params.closest_tpl;
     vtl->current_tp_track_name = params.closest_track_name;
   {
     vtl->current_tpl = params.closest_tpl;
     vtl->current_tp_track_name = params.closest_track_name;
-    vik_treeview_select_iter ( VIK_LAYER(vtl)->vt, g_hash_table_lookup ( vtl->tracks_iters, vtl->current_tp_track_name ) );
+    vik_treeview_select_iter ( VIK_LAYER(vtl)->vt, g_hash_table_lookup ( vtl->tracks_iters, vtl->current_tp_track_name ), TRUE );
     trw_layer_tpwin_init ( vtl );
     vik_layer_emit_update ( VIK_LAYER(vtl) );
     return TRUE;
     trw_layer_tpwin_init ( vtl );
     vik_layer_emit_update ( VIK_LAYER(vtl) );
     return TRUE;
@@ -4516,6 +4900,25 @@ static void tool_show_picture_wp ( char *name, VikWaypoint *wp, gpointer params[
   }
 }
 
   }
 }
 
+static void trw_layer_show_picture ( gpointer pass_along[6] )
+{
+  /* thanks to the Gaim people for showing me ShellExecute and g_spawn_command_line_async */
+#ifdef WINDOWS
+  ShellExecute(NULL, NULL, (char *) pass_along[2], NULL, ".\\", 0);
+#else /* WINDOWS */
+  GError *err = NULL;
+  gchar *quoted_file = g_shell_quote ( (gchar *) pass_along[5] );
+  gchar *cmd = g_strdup_printf ( "eog %s", quoted_file );
+  g_free ( quoted_file );
+  if ( ! g_spawn_command_line_async ( cmd, &err ) )
+    {
+      a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_LAYER( pass_along[0]), _("Could not launch eog to open file.") );
+      g_error_free ( err );
+    }
+  g_free ( cmd );
+#endif /* WINDOWS */
+}
+
 static gboolean tool_show_picture_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
 {
   gpointer params[3] = { vvp, event, NULL };
 static gboolean tool_show_picture_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
 {
   gpointer params[3] = { vvp, event, NULL };
@@ -4524,21 +4927,10 @@ static gboolean tool_show_picture_click ( VikTrwLayer *vtl, GdkEventButton *even
   g_hash_table_foreach ( vtl->waypoints, (GHFunc) tool_show_picture_wp, params );
   if ( params[2] )
   {
   g_hash_table_foreach ( vtl->waypoints, (GHFunc) tool_show_picture_wp, params );
   if ( params[2] )
   {
-    /* thanks to the Gaim people for showing me ShellExecute and g_spawn_command_line_async */
-#ifdef WINDOWS
-    ShellExecute(NULL, NULL, (char *) params[2], NULL, ".\\", 0);
-#else /* WINDOWS */
-    GError *err = NULL;
-    gchar *quoted_file = g_shell_quote ( (gchar *) params[2] );
-    gchar *cmd = g_strdup_printf ( "eog %s", quoted_file );
-    g_free ( quoted_file );
-    if ( ! g_spawn_command_line_async ( cmd, &err ) )
-    {
-      a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_LAYER(vtl), _("Could not launch eog to open file.") );
-      g_error_free ( err );
-    }
-    g_free ( cmd );
-#endif /* WINDOWS */
+    static gpointer pass_along[6];
+    pass_along[0] = vtl;
+    pass_along[5] = params[2];
+    trw_layer_show_picture ( pass_along );
     return TRUE; /* found a match */
   }
   else
     return TRUE; /* found a match */
   }
   else
@@ -4821,7 +5213,7 @@ void vik_track_download_map(VikTrack *tr, VikMapsLayer *vml, VikViewport *vvp, g
   }
 }
 
   }
 }
 
-static void trw_layer_download_map_along_track_cb(gpointer pass_along[6])
+static void trw_layer_download_map_along_track_cb ( gpointer pass_along[6] )
 {
   VikMapsLayer *vml;
   gint selected_map, default_map;
 {
   VikMapsLayer *vml;
   gint selected_map, default_map;
@@ -4836,7 +5228,7 @@ static void trw_layer_download_map_along_track_cb(gpointer pass_along[6])
   VikTrack *tr = (VikTrack *) g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->tracks, pass_along[3] );
   VikViewport *vvp = vik_window_viewport((VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl)));
 
   VikTrack *tr = (VikTrack *) g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->tracks, pass_along[3] );
   VikViewport *vvp = vik_window_viewport((VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl)));
 
-  GList *vmls = vik_layers_panel_get_all_layers_of_type(vlp, VIK_LAYER_MAPS);
+  GList *vmls = vik_layers_panel_get_all_layers_of_type(vlp, VIK_LAYER_MAPS, TRUE); // Includes hidden map layer types
   int num_maps = g_list_length(vmls);
 
   if (!num_maps) {
   int num_maps = g_list_length(vmls);
 
   if (!num_maps) {