]> git.street.me.uk Git - andy/viking.git/blobdiff - src/viktrwlayer.c
Improve the associated icon, remove the scissor effort and use something to try to...
[andy/viking.git] / src / viktrwlayer.c
index 5f30ad1d81a378befd6aea6cd91aa919664888f8..202a8266d22f441c214cea43aac49b3ff1239464 100644 (file)
@@ -250,6 +250,10 @@ static void trw_layer_goto_wp ( gpointer layer_and_vlp[2] );
 static void trw_layer_new_wp ( gpointer lav[2] );
 static void trw_layer_auto_waypoints_view ( gpointer lav[2] );
 static void trw_layer_auto_tracks_view ( gpointer lav[2] );
+static void trw_layer_delete_all_tracks ( gpointer lav[2] );
+static void trw_layer_delete_tracks_from_selection ( gpointer lav[2] );
+static void trw_layer_delete_all_waypoints ( gpointer lav[2] );
+static void trw_layer_delete_waypoints_from_selection ( gpointer lav[2] );
 static void trw_layer_new_wikipedia_wp_viewport ( gpointer lav[2] );
 static void trw_layer_new_wikipedia_wp_layer ( gpointer lav[2] );
 
@@ -353,8 +357,8 @@ static VikToolInterface trw_layer_tools[] = {
   { N_("Show Picture"),    (VikToolConstructorFunc) tool_show_picture_create,    NULL, NULL, NULL, 
     (VikToolMouseFunc) tool_show_picture_click,    NULL, NULL, (VikToolKeyFunc) NULL, GDK_CURSOR_IS_PIXMAP, &cursor_showpic_pixbuf },
 
-  { N_("Magic Scissors"),  (VikToolConstructorFunc) tool_magic_scissors_create,  NULL, NULL, NULL,
-    (VikToolMouseFunc) tool_magic_scissors_click, NULL, NULL, (VikToolKeyFunc) NULL, GDK_CURSOR_IS_PIXMAP, &cursor_iscissors_pixbuf },
+  { N_("Route Finder"),  (VikToolConstructorFunc) tool_magic_scissors_create,  NULL, NULL, NULL,
+    (VikToolMouseFunc) tool_magic_scissors_click, NULL, NULL, (VikToolKeyFunc) NULL, GDK_CURSOR_IS_PIXMAP, &cursor_route_finder_pixbuf },
 };
 enum { TOOL_CREATE_WAYPOINT=0, TOOL_CREATE_TRACK, TOOL_BEGIN_TRACK, TOOL_EDIT_WAYPOINT, TOOL_EDIT_TRACKPOINT, TOOL_SHOW_PICTURE, NUM_TOOLS };
 
@@ -526,7 +530,7 @@ static void trw_layer_del_item ( VikTrwLayer *vtl, gint subtype, gpointer sublay
   pass_along[1] = NULL;
   pass_along[2] = GINT_TO_POINTER (subtype);
   pass_along[3] = sublayer;
-  pass_along[4] = NULL;
+  pass_along[4] = GINT_TO_POINTER (1); // Confirm delete request
   pass_along[5] = NULL;
 
   trw_layer_delete_item ( pass_along );
@@ -543,7 +547,7 @@ static void trw_layer_cut_item ( VikTrwLayer *vtl, gint subtype, gpointer sublay
   pass_along[1] = NULL;
   pass_along[2] = GINT_TO_POINTER (subtype);
   pass_along[3] = sublayer;
-  pass_along[4] = NULL;
+  pass_along[4] = GINT_TO_POINTER (0); // No delete confirmation needed for auto delete
   pass_along[5] = NULL;
 
   trw_layer_copy_item_cb(pass_along);
@@ -569,6 +573,7 @@ static void trw_layer_copy_item_cb ( gpointer pass_along[6])
 static void trw_layer_cut_item_cb ( gpointer pass_along[6])
 {
   trw_layer_copy_item_cb(pass_along);
+  pass_along[4] = GINT_TO_POINTER (0); // Never need to confirm automatic delete
   trw_layer_delete_item(pass_along);
 }
 
@@ -2085,6 +2090,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 );
 }
 
+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];
@@ -2297,7 +2314,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 );
 
-  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 );
@@ -2308,22 +2325,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 );
   
-  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 );
 
-  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 );
 
-  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 );
 
-  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 );
@@ -2347,12 +2369,38 @@ void vik_trw_layer_add_menu_items ( VikTrwLayer *vtl, GtkMenu *menu, gpointer vl
 #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 );
 #endif
 
+  GtkWidget *delete_submenu = gtk_menu_new ();
+  item = gtk_menu_item_new_with_mnemonic ( _("De_lete") );
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+  gtk_widget_show ( item );
+  gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), delete_submenu );
+  
+  item = gtk_menu_item_new_with_mnemonic ( _("Delete All _Tracks") );
+  g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_delete_all_tracks), pass_along );
+  gtk_menu_shell_append ( GTK_MENU_SHELL(delete_submenu), item );
+  gtk_widget_show ( item );
+  
+  item = gtk_menu_item_new_with_mnemonic ( _("Delete Tracks _From Selection...") );
+  g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_delete_tracks_from_selection), pass_along );
+  gtk_menu_shell_append ( GTK_MENU_SHELL(delete_submenu), item );
+  gtk_widget_show ( item );
+  
+  item = gtk_menu_item_new_with_mnemonic ( _("Delete All _Waypoints") );
+  g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_delete_all_waypoints), pass_along );
+  gtk_menu_shell_append ( GTK_MENU_SHELL(delete_submenu), item );
+  gtk_widget_show ( item );
+  
+  item = gtk_menu_item_new_with_mnemonic ( _("Delete Waypoints From _Selection...") );
+  g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_delete_waypoints_from_selection), pass_along );
+  gtk_menu_shell_append ( GTK_MENU_SHELL(delete_submenu), item );
+  gtk_widget_show ( item );
+  
   item = a_acquire_trwlayer_menu ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), vlp,
                                   vik_layers_panel_get_viewport(VIK_LAYERS_PANEL(vlp)), vtl );
   if ( item ) {
@@ -2386,7 +2434,6 @@ 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 );
-      vik_treeview_select_iter ( VIK_LAYER(vtl)->vt, iter, TRUE );
       g_hash_table_insert ( vtl->waypoints_iters, name, iter );
     }
   }
@@ -2414,7 +2461,6 @@ 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 );
-      vik_treeview_select_iter ( VIK_LAYER(vtl)->vt, iter, TRUE );
       g_hash_table_insert ( vtl->tracks_iters, name, iter );
     }
   }
@@ -2619,16 +2665,49 @@ void vik_trw_layer_delete_all_waypoints ( VikTrwLayer *vtl )
   vik_layer_emit_update ( VIK_LAYER(vtl) );
 }
 
+static void trw_layer_delete_all_tracks ( gpointer lav[2] )
+{
+  VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+  // Get confirmation from the user
+  if ( a_dialog_yes_or_no ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
+                           _("Are you sure you want to delete all tracks in %s?"),
+                           vik_layer_get_name ( VIK_LAYER(vtl) ) ) )
+    vik_trw_layer_delete_all_tracks (vtl);
+}
+
+static void trw_layer_delete_all_waypoints ( gpointer lav[2] )
+{
+  VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+  // Get confirmation from the user
+  if ( a_dialog_yes_or_no ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
+                           _("Are you sure you want to delete all waypoints in %s?"),
+                           vik_layer_get_name ( VIK_LAYER(vtl) ) ) )
+    vik_trw_layer_delete_all_waypoints (vtl);
+}
+
 static void trw_layer_delete_item ( gpointer pass_along[6] )
 {
   VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
   gboolean was_visible = FALSE;
   if ( GPOINTER_TO_INT (pass_along[2]) == VIK_TRW_LAYER_SUBLAYER_WAYPOINT )
   {
+    if ( GPOINTER_TO_INT ( pass_along[4]) )
+      // Get confirmation from the user
+      // Maybe this Waypoint Delete should be optional as is it could get annoying...
+      if ( ! a_dialog_yes_or_no ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
+                                 _("Are you sure you want to delete the waypoint \"%s\""),
+                                 pass_along[3] ) )
+       return;
     was_visible = vik_trw_layer_delete_waypoint ( vtl, (gchar *) pass_along[3] );
   }
   else
   {
+    if ( GPOINTER_TO_INT ( pass_along[4]) )
+      // Get confirmation from the user
+      if ( ! a_dialog_yes_or_no ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
+                                 _("Are you sure you want to delete the track \"%s\""),
+                                 pass_along[3] ) )
+       return;
     was_visible = vik_trw_layer_delete_track ( vtl, (gchar *) pass_along[3] );
   }
   if ( was_visible )
@@ -2889,6 +2968,7 @@ static void find_nearby_track(gpointer key, gpointer value, gpointer user_data)
 }
 
 /* comparison function used to sort tracks; a and b are hash table keys */
+/* Not actively used - can be restored if needed
 static gint track_compare(gconstpointer a, gconstpointer b, gpointer user_data)
 {
   GHashTable *tracks = user_data;
@@ -2901,6 +2981,7 @@ static gint track_compare(gconstpointer a, gconstpointer b, gpointer user_data)
   if (t1 > t2) return 1;
   return 0;
 }
+*/
 
 /* comparison function used to sort trackpoints */
 static gint trackpoint_compare(gconstpointer a, gconstpointer b)
@@ -2991,7 +3072,7 @@ static void trw_layer_merge_by_timestamp ( gpointer pass_along[6] )
   VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
   gchar *orig_track_name = strdup(pass_along[3]);
 
-  time_t t1, t2;
+  //time_t t1, t2;
   GList *nearby_tracks;
   VikTrack *track;
   GList *trps;
@@ -3022,8 +3103,8 @@ static void trw_layer_merge_by_timestamp ( gpointer pass_along[6] )
       nearby_tracks = NULL;
     }
 
-    t1 = ((VikTrackpoint *)trps->data)->timestamp;
-    t2 = ((VikTrackpoint *)g_list_last(trps)->data)->timestamp;
+    //t1 = ((VikTrackpoint *)trps->data)->timestamp;
+    //t2 = ((VikTrackpoint *)g_list_last(trps)->data)->timestamp;
     
     /*    g_print("Original track times: %d and %d\n", t1, t2);  */
     params[0] = &nearby_tracks;
@@ -3110,7 +3191,7 @@ static void trw_layer_split_by_timestamp ( gpointer pass_along[6] )
     }
     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;
     }
 
@@ -3120,30 +3201,33 @@ static void trw_layer_split_by_timestamp ( gpointer pass_along[6] )
     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;
-  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);*/
 
-    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);
-  vik_trw_layer_delete_track(VIK_TRW_LAYER(pass_along[0]), (gchar *)pass_along[3]);
-  vik_layer_emit_update(VIK_LAYER(pass_along[0]));
 }
 
 /**
@@ -3223,6 +3307,89 @@ static void trw_layer_split_by_n_points ( gpointer pass_along[6] )
 
 /* end of split/merge routines */
 
+/**
+ * Similar to trw_layer_enum_item, but this uses a sorted method
+ */
+static void trw_layer_sorted_name_list(gpointer key, gpointer value, gpointer udata)
+{
+  GList **list = (GList**)udata;
+  //*list = g_list_prepend(*all, key); //unsorted method
+  // Sort named list alphabetically
+  *list = g_list_insert_sorted_with_data (*list, key, sort_alphabetically, NULL);
+}
+
+/**
+ *
+ */
+static void trw_layer_delete_tracks_from_selection ( gpointer lav[2] )
+{
+  VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+  GList *all = NULL;
+  // Sort list alphabetically for better presentation
+  g_hash_table_foreach(vtl->tracks, trw_layer_sorted_name_list, &all);
+
+  if ( ! all ) {
+    a_dialog_error_msg (VIK_GTK_WINDOW_FROM_LAYER(vtl),        _("No tracks found"));
+    return;
+  }
+
+  // Get list of items to delete from the user
+  GList *delete_list = a_dialog_select_from_list(VIK_GTK_WINDOW_FROM_LAYER(vtl),
+                                                all,
+                                                TRUE,
+                                                _("Delete Selection"),
+                                                _("Select tracks to delete"));
+  g_list_free(all);
+
+  // Delete requested tracks
+  // since specificly requested, IMHO no need for extra confirmation
+  if ( delete_list ) {
+    GList *l;
+    for (l = delete_list; l != NULL; l = g_list_next(l)) {
+      vik_trw_layer_delete_track(vtl, l->data);
+    }
+    g_list_free(delete_list);
+    vik_layer_emit_update( VIK_LAYER(vtl) );
+  }
+}
+
+/**
+ *
+ */
+static void trw_layer_delete_waypoints_from_selection ( gpointer lav[2] )
+{
+  VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+  GList *all = NULL;
+
+  // Sort list alphabetically for better presentation
+  g_hash_table_foreach ( vtl->waypoints, trw_layer_sorted_name_list, &all);
+  if ( ! all ) {
+    a_dialog_error_msg (VIK_GTK_WINDOW_FROM_LAYER(vtl),        _("No waypoints found"));
+    return;
+  }
+
+  all = g_list_sort_with_data(all, sort_alphabetically, NULL);
+
+  // Get list of items to delete from the user
+  GList *delete_list = a_dialog_select_from_list(VIK_GTK_WINDOW_FROM_LAYER(vtl),
+                                                all,
+                                                TRUE,
+                                                _("Delete Selection"),
+                                                _("Select waypoints to delete"));
+  g_list_free(all);
+
+  // Delete requested waypoints
+  // since specificly requested, IMHO no need for extra confirmation
+  if ( delete_list ) {
+    GList *l;
+    for (l = delete_list; l != NULL; l = g_list_next(l)) {
+      vik_trw_layer_delete_waypoint(vtl, l->data);
+    }
+    g_list_free(delete_list);
+    vik_layer_emit_update( VIK_LAYER(vtl) );
+  }
+
+}
 
 static void trw_layer_goto_waypoint ( gpointer pass_along[6] )
 {
@@ -3368,7 +3535,6 @@ static void trw_layer_track_google_route_webpage ( gpointer pass_along[6] )
 /* 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 gpointer pass_along[6];
   GtkWidget *item;
   gboolean rv = FALSE;
@@ -3377,10 +3543,7 @@ 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;
-  if ( iter ) {
-    staticiter = *iter; /* will exist after function has ended */
-    pass_along[4] = &staticiter;
-  }
+  pass_along[4] = GINT_TO_POINTER (1); // Confirm delete request
   pass_along[5] = vvp;
 
   if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT || subtype == VIK_TRW_LAYER_SUBLAYER_TRACK )
@@ -3473,12 +3636,55 @@ gboolean vik_trw_layer_sublayer_add_menu_items ( VikTrwLayer *l, GtkMenu *menu,
   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 );
   }
 
+  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 );
+
+    item = gtk_menu_item_new_with_mnemonic ( _("Delete _All Waypoints") );
+    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_delete_all_waypoints), pass_along );
+    gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
+    gtk_widget_show ( item );
+
+    item = gtk_menu_item_new_with_mnemonic ( _("_Delete Waypoints From Selection...") );
+    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_delete_waypoints_from_selection), pass_along );
+    gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
+    gtk_widget_show ( item );
+  }
+
+  if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACKS )
+  {
+    rv = TRUE;
+
+    item = gtk_menu_item_new_with_mnemonic ( _("_View All Tracks") );
+    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_auto_tracks_view), pass_along );
+    gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+    gtk_widget_show ( item );
+
+    item = gtk_menu_item_new_with_mnemonic ( _("Delete _All Tracks") );
+    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_delete_all_tracks), pass_along );
+    gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
+    gtk_widget_show ( item );
+
+    item = gtk_menu_item_new_with_mnemonic ( _("_Delete Tracks From Selection...") );
+    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_delete_tracks_from_selection), pass_along );
+    gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
+    gtk_widget_show ( item );
+  }
+
   if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK )
   {
     GtkWidget *goto_submenu;
@@ -3527,7 +3733,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 );
 
-    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 );
@@ -3537,12 +3743,12 @@ 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 );
 
-    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 );
 
-    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 );
@@ -3560,7 +3766,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 );
 
-    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 );
@@ -3570,13 +3776,13 @@ 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 );
 
-    item = gtk_menu_item_new_with_mnemonic ( _("Extend _Using Magic Scissors") );
+    item = gtk_menu_item_new_with_mnemonic ( _("Extend _Using Route Finder") );
     g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_extend_track_end_ms), pass_along );
     gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
     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 );
@@ -3712,7 +3918,11 @@ static void trw_layer_tpwin_response ( VikTrwLayer *vtl, gint response )
   g_assert ( vtl->tpwin != NULL );
   if ( response == VIK_TRW_LAYER_TPWIN_CLOSE )
     trw_layer_cancel_current_tp ( vtl, TRUE );
-  else if ( response == VIK_TRW_LAYER_TPWIN_SPLIT && vtl->current_tpl->next && vtl->current_tpl->prev )
+
+  if ( vtl->current_tpl == NULL )
+    return;
+
+  if ( response == VIK_TRW_LAYER_TPWIN_SPLIT && vtl->current_tpl->next && vtl->current_tpl->prev )
   {
     gchar *name = get_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, vtl->current_tp_track_name);
     if ( ( name = a_dialog_new_track ( GTK_WINDOW(vtl->tpwin), vtl->tracks, name ) ) )
@@ -5195,7 +5405,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)));
 
-  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) {