]> git.street.me.uk Git - andy/viking.git/blobdiff - src/vikwindow.c
Fix mislabelled distance markers when using Nautical Miles.
[andy/viking.git] / src / vikwindow.c
index 3556b9307c69b143c965c024d50e7f3bd89c4393..5c7d484b17ad9e7ed058d96352b78ae67b82d6e5 100644 (file)
@@ -44,6 +44,7 @@
 #include "vikmapslayer.h"
 #include "geonamessearch.h"
 #include "vikutils.h"
 #include "vikmapslayer.h"
 #include "geonamessearch.h"
 #include "vikutils.h"
+#include "dir.h"
 
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
 
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
@@ -114,6 +115,10 @@ static void draw_status ( VikWindow *vw );
 
 /* End Drawing Functions */
 
 
 /* End Drawing Functions */
 
+static void toggle_draw_scale ( GtkAction *a, VikWindow *vw );
+static void toggle_draw_centermark ( GtkAction *a, VikWindow *vw );
+static void toggle_draw_highlight ( GtkAction *a, VikWindow *vw );
+
 static void menu_addlayer_cb ( GtkAction *a, VikWindow *vw );
 static void menu_properties_cb ( GtkAction *a, VikWindow *vw );
 static void menu_delete_layer_cb ( GtkAction *a, VikWindow *vw );
 static void menu_addlayer_cb ( GtkAction *a, VikWindow *vw );
 static void menu_properties_cb ( GtkAction *a, VikWindow *vw );
 static void menu_delete_layer_cb ( GtkAction *a, VikWindow *vw );
@@ -186,6 +191,7 @@ struct _VikWindow {
   gboolean show_toolbar;
   gboolean show_main_menu;
 
   gboolean show_toolbar;
   gboolean show_main_menu;
 
+  gboolean select_move;
   gboolean pan_move;
   gint pan_x, pan_y;
   gint delayed_pan_x, delayed_pan_y; // Temporary storage
   gboolean pan_move;
   gint pan_x, pan_y;
   gint delayed_pan_x, delayed_pan_y; // Temporary storage
@@ -299,12 +305,17 @@ static gboolean statusbar_idle_update ( statusbar_idle_data *sid )
  */
 void vik_window_statusbar_update ( VikWindow *vw, const gchar* message, vik_statusbar_type_t vs_type )
 {
  */
 void vik_window_statusbar_update ( VikWindow *vw, const gchar* message, vik_statusbar_type_t vs_type )
 {
+  GThread *thread = vik_window_get_thread ( vw );
+  if ( !thread )
+    // Do nothing
+    return;
+
   statusbar_idle_data *sid = g_malloc ( sizeof (statusbar_idle_data) );
   sid->vs = vw->viking_vs;
   sid->vs_type = vs_type;
   sid->message = g_strdup ( message );
 
   statusbar_idle_data *sid = g_malloc ( sizeof (statusbar_idle_data) );
   sid->vs = vw->viking_vs;
   sid->vs_type = vs_type;
   sid->message = g_strdup ( message );
 
-  if ( g_thread_self() == vik_window_get_thread ( vw ) ) {
+  if ( g_thread_self() == thread ) {
     g_idle_add ( (GSourceFunc) statusbar_idle_update, sid );
   }
   else {
     g_idle_add ( (GSourceFunc) statusbar_idle_update, sid );
   }
   else {
@@ -468,7 +479,8 @@ void vik_window_new_window_finish ( VikWindow *vw )
 
       vik_statusbar_set_message ( vw->viking_vs, VIK_STATUSBAR_INFO, _("Trying to determine location...") );
 
 
       vik_statusbar_set_message ( vw->viking_vs, VIK_STATUSBAR_INFO, _("Trying to determine location...") );
 
-      a_background_thread ( GTK_WINDOW(vw),
+      a_background_thread ( BACKGROUND_POOL_REMOTE,
+                            GTK_WINDOW(vw),
                             _("Determining location"),
                             (vik_thr_func) determine_location_thread,
                             vw,
                             _("Determining location"),
                             (vik_thr_func) determine_location_thread,
                             vw,
@@ -569,7 +581,7 @@ static void zoom_changed (GtkMenuShell *menushell,
   GtkWidget *aw = gtk_menu_get_active ( GTK_MENU (menushell) );
   gint active = GPOINTER_TO_INT(g_object_get_data ( G_OBJECT (aw), "position" ));
 
   GtkWidget *aw = gtk_menu_get_active ( GTK_MENU (menushell) );
   gint active = GPOINTER_TO_INT(g_object_get_data ( G_OBJECT (aw), "position" ));
 
-  gdouble zoom_request = pow (2, active-2 );
+  gdouble zoom_request = pow (2, active-5 );
 
   // But has it really changed?
   gdouble current_zoom = vik_viewport_get_zoom ( vw->viking_vvp );
 
   // But has it really changed?
   gdouble current_zoom = vik_viewport_get_zoom ( vw->viking_vvp );
@@ -586,7 +598,7 @@ static void zoom_changed (GtkMenuShell *menushell,
 static GtkWidget *create_zoom_menu_all_levels ( gdouble mpp )
 {
   GtkWidget *menu = gtk_menu_new ();
 static GtkWidget *create_zoom_menu_all_levels ( gdouble mpp )
 {
   GtkWidget *menu = gtk_menu_new ();
-  char *itemLabels[] = { "0.25", "0.5", "1", "2", "4", "8", "16", "32", "64", "128", "256", "512", "1024", "2048", "4096", "8192", "16384", "32768" };
+  char *itemLabels[] = { "0.031", "0.063", "0.125", "0.25", "0.5", "1", "2", "4", "8", "16", "32", "64", "128", "256", "512", "1024", "2048", "4096", "8192", "16384", "32768" };
 
   int i;
   for (i = 0 ; i < G_N_ELEMENTS(itemLabels) ; i++)
 
   int i;
   for (i = 0 ; i < G_N_ELEMENTS(itemLabels) ; i++)
@@ -597,7 +609,7 @@ static GtkWidget *create_zoom_menu_all_levels ( gdouble mpp )
       g_object_set_data (G_OBJECT (item), "position", GINT_TO_POINTER(i));
     }
 
       g_object_set_data (G_OBJECT (item), "position", GINT_TO_POINTER(i));
     }
 
-  gint active = 2 + round ( log (mpp) / log (2) );
+  gint active = 5 + round ( log (mpp) / log (2) );
   // Ensure value derived from mpp is in bounds of the menu
   if ( active >= G_N_ELEMENTS(itemLabels) )
     active = G_N_ELEMENTS(itemLabels) - 1;
   // Ensure value derived from mpp is in bounds of the menu
   if ( active >= G_N_ELEMENTS(itemLabels) )
     active = G_N_ELEMENTS(itemLabels) - 1;
@@ -727,6 +739,8 @@ static void toolbar_reload_cb ( GtkActionGroup *grp, gpointer gp )
 #define VIK_SETTINGS_WIN_SAVE_IMAGE_PNG "window_save_image_as_png"
 #define VIK_SETTINGS_WIN_COPY_CENTRE_FULL_FORMAT "window_copy_centre_full_format"
 
 #define VIK_SETTINGS_WIN_SAVE_IMAGE_PNG "window_save_image_as_png"
 #define VIK_SETTINGS_WIN_COPY_CENTRE_FULL_FORMAT "window_copy_centre_full_format"
 
+#define VIKING_ACCELERATOR_KEY_FILE "keys.rc"
+
 static void vik_window_init ( VikWindow *vw )
 {
   vw->action_group = NULL;
 static void vik_window_init ( VikWindow *vw )
 {
   vw->action_group = NULL;
@@ -747,7 +761,8 @@ static void vik_window_init ( VikWindow *vw )
   vw->loaded_type = LOAD_TYPE_READ_FAILURE; //AKA none
   vw->modified = FALSE;
   vw->only_updating_coord_mode_ui = FALSE;
   vw->loaded_type = LOAD_TYPE_READ_FAILURE; //AKA none
   vw->modified = FALSE;
   vw->only_updating_coord_mode_ui = FALSE;
+
+  vw->select_move = FALSE;
   vw->pan_move = FALSE; 
   vw->pan_x = vw->pan_y = -1;
   vw->single_click_pending = FALSE;
   vw->pan_move = FALSE; 
   vw->pan_x = vw->pan_y = -1;
   vw->single_click_pending = FALSE;
@@ -821,7 +836,7 @@ static void vik_window_init ( VikWindow *vw )
   center_changed_cb ( vw );
 
   vw->hpaned = gtk_hpaned_new ();
   center_changed_cb ( vw );
 
   vw->hpaned = gtk_hpaned_new ();
-  gtk_paned_pack1 ( GTK_PANED(vw->hpaned), GTK_WIDGET (vw->viking_vlp), FALSE, FALSE );
+  gtk_paned_pack1 ( GTK_PANED(vw->hpaned), GTK_WIDGET (vw->viking_vlp), FALSE, TRUE );
   gtk_paned_pack2 ( GTK_PANED(vw->hpaned), GTK_WIDGET (vw->viking_vvp), TRUE, TRUE );
 
   /* This packs the button into the window (a gtk container). */
   gtk_paned_pack2 ( GTK_PANED(vw->hpaned), GTK_WIDGET (vw->viking_vvp), TRUE, TRUE );
 
   /* This packs the button into the window (a gtk container). */
@@ -903,6 +918,10 @@ static void vik_window_init ( VikWindow *vw )
   // Set the default tool + mode
   gtk_action_activate ( gtk_action_group_get_action ( vw->action_group, "Pan" ) );
   gtk_action_activate ( gtk_action_group_get_action ( vw->action_group, "ModeMercator" ) );
   // Set the default tool + mode
   gtk_action_activate ( gtk_action_group_get_action ( vw->action_group, "Pan" ) );
   gtk_action_activate ( gtk_action_group_get_action ( vw->action_group, "ModeMercator" ) );
+
+  gchar *accel_file_name = g_build_filename ( a_get_viking_dir(), VIKING_ACCELERATOR_KEY_FILE, NULL );
+  gtk_accel_map_load ( accel_file_name );
+  g_free ( accel_file_name );
 }
 
 static VikWindow *window_new ()
 }
 
 static VikWindow *window_new ()
@@ -1058,6 +1077,10 @@ static gboolean delete_event( VikWindow *vw )
     a_settings_set_integer ( VIK_SETTINGS_WIN_SAVE_IMAGE_WIDTH, vw->draw_image_width );
     a_settings_set_integer ( VIK_SETTINGS_WIN_SAVE_IMAGE_HEIGHT, vw->draw_image_height );
     a_settings_set_boolean ( VIK_SETTINGS_WIN_SAVE_IMAGE_PNG, vw->draw_image_save_as_png );
     a_settings_set_integer ( VIK_SETTINGS_WIN_SAVE_IMAGE_WIDTH, vw->draw_image_width );
     a_settings_set_integer ( VIK_SETTINGS_WIN_SAVE_IMAGE_HEIGHT, vw->draw_image_height );
     a_settings_set_boolean ( VIK_SETTINGS_WIN_SAVE_IMAGE_PNG, vw->draw_image_save_as_png );
+
+    gchar *accel_file_name = g_build_filename ( a_get_viking_dir(), VIKING_ACCELERATOR_KEY_FILE, NULL );
+    gtk_accel_map_save ( accel_file_name );
+    g_free ( accel_file_name );
   }
 
   return FALSE;
   }
 
   return FALSE;
@@ -2130,36 +2153,55 @@ static void click_layer_selected (VikLayer *vl, clicker *ck)
        ck->cont = !vik_layer_get_interface(vl->type)->select_click ( vl, ck->event, ck->vvp, ck->tool_edit );
 }
 
        ck->cont = !vik_layer_get_interface(vl->type)->select_click ( vl, ck->event, ck->vvp, ck->tool_edit );
 }
 
+#ifdef WINDOWS
+// Hopefully Alt keys by default
+#define VIK_MOVE_MODIFIER GDK_MOD1_MASK
+#else
+// Alt+mouse on Linux desktops tend to be used by the desktop manager
+// Thus use an alternate modifier - you may need to set something into this group
+#define VIK_MOVE_MODIFIER GDK_MOD5_MASK
+#endif
+
 static VikLayerToolFuncStatus selecttool_click (VikLayer *vl, GdkEventButton *event, tool_ed_t *t)
 {
 static VikLayerToolFuncStatus selecttool_click (VikLayer *vl, GdkEventButton *event, tool_ed_t *t)
 {
+  t->vw->select_move = FALSE;
   /* Only allow selection on primary button */
   if ( event->button == 1 ) {
   /* Only allow selection on primary button */
   if ( event->button == 1 ) {
-    /* Enable click to apply callback to potentially all track/waypoint layers */
-    /* Useful as we can find things that aren't necessarily in the currently selected layer */
-    GList* gl = vik_layers_panel_get_all_layers_of_type ( t->vw->viking_vlp, VIK_LAYER_TRW, FALSE ); // Don't get invisible layers
-    clicker ck;
-    ck.cont = TRUE;
-    ck.vvp = t->vw->viking_vvp;
-    ck.event = event;
-    ck.tool_edit = t;
-    g_list_foreach ( gl, (GFunc) click_layer_selected, &ck );
-    g_list_free ( gl );
-
-    // If nothing found then deselect & redraw screen if necessary to remove the highlight
-    if ( ck.cont ) {
-      GtkTreeIter iter;
-      VikTreeview *vtv = vik_layers_panel_get_treeview ( t->vw->viking_vlp );
-
-      if ( vik_treeview_get_selected_iter ( vtv, &iter ) ) {
-       // Only clear if selected thing is a TrackWaypoint layer or a sublayer
-       gint type = vik_treeview_item_get_type ( vtv, &iter );
-       if ( type == VIK_TREEVIEW_TYPE_SUBLAYER ||
-            VIK_LAYER(vik_treeview_item_get_pointer ( vtv, &iter ))->type == VIK_LAYER_TRW ) {
+
+    if ( event->state & VIK_MOVE_MODIFIER )
+      vik_window_pan_click ( t->vw, event );
+    else {
+      /* Enable click to apply callback to potentially all track/waypoint layers */
+      /* Useful as we can find things that aren't necessarily in the currently selected layer */
+      GList* gl = vik_layers_panel_get_all_layers_of_type ( t->vw->viking_vlp, VIK_LAYER_TRW, FALSE ); // Don't get invisible layers
+      clicker ck;
+      ck.cont = TRUE;
+      ck.vvp = t->vw->viking_vvp;
+      ck.event = event;
+      ck.tool_edit = t;
+      g_list_foreach ( gl, (GFunc) click_layer_selected, &ck );
+      g_list_free ( gl );
+
+      // If nothing found then deselect & redraw screen if necessary to remove the highlight
+      if ( ck.cont ) {
+        GtkTreeIter iter;
+        VikTreeview *vtv = vik_layers_panel_get_treeview ( t->vw->viking_vlp );
+
+        if ( vik_treeview_get_selected_iter ( vtv, &iter ) ) {
+          // Only clear if selected thing is a TrackWaypoint layer or a sublayer
+          gint type = vik_treeview_item_get_type ( vtv, &iter );
+          if ( type == VIK_TREEVIEW_TYPE_SUBLAYER ||
+            VIK_LAYER(vik_treeview_item_get_pointer ( vtv, &iter ))->type == VIK_LAYER_TRW ) {
    
    
-         vik_treeview_item_unselect ( vtv, &iter );
-         if ( vik_window_clear_highlight ( t->vw ) )
-           draw_update ( t->vw );
-       }
+            vik_treeview_item_unselect ( vtv, &iter );
+            if ( vik_window_clear_highlight ( t->vw ) )
+              draw_update ( t->vw );
+          }
+        }
+      }
+      else {
+        // Something found - so enable movement
+        t->vw->select_move = TRUE;
       }
     }
   }
       }
     }
   }
@@ -2174,27 +2216,41 @@ static VikLayerToolFuncStatus selecttool_click (VikLayer *vl, GdkEventButton *ev
   return VIK_LAYER_TOOL_ACK;
 }
 
   return VIK_LAYER_TOOL_ACK;
 }
 
-static VikLayerToolFuncStatus selecttool_move (VikLayer *vl, GdkEventButton *event, tool_ed_t *t)
+static VikLayerToolFuncStatus selecttool_move (VikLayer *vl, GdkEventMotion *event, tool_ed_t *t)
 {
 {
-  /* Only allow selection on primary button */
-  if ( event->button == 1 ) {
+  if ( t->vw->select_move ) {
     // Don't care about vl here
     if ( t->vtl )
       if ( vik_layer_get_interface(VIK_LAYER_TRW)->select_move )
     // Don't care about vl here
     if ( t->vtl )
       if ( vik_layer_get_interface(VIK_LAYER_TRW)->select_move )
-       vik_layer_get_interface(VIK_LAYER_TRW)->select_move ( vl, event, t->vvp, t );
+        vik_layer_get_interface(VIK_LAYER_TRW)->select_move ( vl, event, t->vvp, t );
   }
   }
+  else
+    // Optional Panning
+    if ( event->state & VIK_MOVE_MODIFIER )
+      vik_window_pan_move ( t->vw, event );
+
   return VIK_LAYER_TOOL_ACK;
 }
 
 static VikLayerToolFuncStatus selecttool_release (VikLayer *vl, GdkEventButton *event, tool_ed_t *t)
 {
   return VIK_LAYER_TOOL_ACK;
 }
 
 static VikLayerToolFuncStatus selecttool_release (VikLayer *vl, GdkEventButton *event, tool_ed_t *t)
 {
-  /* Only allow selection on primary button */
-  if ( event->button == 1 ) {
+  if ( t->vw->select_move ) {
     // Don't care about vl here
     if ( t->vtl )
       if ( vik_layer_get_interface(VIK_LAYER_TRW)->select_release )
     // Don't care about vl here
     if ( t->vtl )
       if ( vik_layer_get_interface(VIK_LAYER_TRW)->select_release )
-       vik_layer_get_interface(VIK_LAYER_TRW)->select_release ( (VikLayer*)t->vtl, event, t->vvp, t );
+        vik_layer_get_interface(VIK_LAYER_TRW)->select_release ( (VikLayer*)t->vtl, event, t->vvp, t );
   }
   }
+
+  if ( event->button == 1 && (event->state & VIK_MOVE_MODIFIER) )
+      vik_window_pan_release ( t->vw, event );
+
+  // Force pan off incase it was on
+  t->vw->pan_move = FALSE;
+  t->vw->pan_x = t->vw->pan_y = -1;
+
+  // End of this select movement
+  t->vw->select_move = FALSE;
+
   return VIK_LAYER_TOOL_ACK;
 }
 
   return VIK_LAYER_TOOL_ACK;
 }
 
@@ -2586,6 +2642,11 @@ static void help_cache_info_cb ( GtkAction *a, VikWindow *vw )
   g_free ( msg );
 }
 
   g_free ( msg );
 }
 
+static void back_forward_info_cb ( GtkAction *a, VikWindow *vw )
+{
+  vik_viewport_show_centers ( vw->viking_vvp, GTK_WINDOW(vw) );
+}
+
 static void menu_delete_layer_cb ( GtkAction *a, VikWindow *vw )
 {
   if ( vik_layers_panel_get_selected ( vw->viking_vlp ) )
 static void menu_delete_layer_cb ( GtkAction *a, VikWindow *vw )
 {
   if ( vik_layers_panel_get_selected ( vw->viking_vlp ) )
@@ -3064,18 +3125,30 @@ void vik_window_open_file ( VikWindow *vw, const gchar *filename, gboolean chang
       vw->only_updating_coord_mode_ui = FALSE;
 
       vik_layers_panel_change_coord_mode ( vw->viking_vlp, vik_viewport_get_coord_mode ( vw->viking_vvp ) );
       vw->only_updating_coord_mode_ui = FALSE;
 
       vik_layers_panel_change_coord_mode ( vw->viking_vlp, vik_viewport_get_coord_mode ( vw->viking_vvp ) );
-      
-      mode_button = gtk_ui_manager_get_widget ( vw->uim, "/ui/MainMenu/View/SetShow/ShowScale" );
-      g_assert ( mode_button );
-      gtk_check_menu_item_set_active ( GTK_CHECK_MENU_ITEM(mode_button),vik_viewport_get_draw_scale(vw->viking_vvp) );
 
 
-      mode_button = gtk_ui_manager_get_widget ( vw->uim, "/ui/MainMenu/View/SetShow/ShowCenterMark" );
-      g_assert ( mode_button );
-      gtk_check_menu_item_set_active ( GTK_CHECK_MENU_ITEM(mode_button),vik_viewport_get_draw_centermark(vw->viking_vvp) );
-      
-      mode_button = gtk_ui_manager_get_widget ( vw->uim, "/ui/MainMenu/View/SetShow/ShowHighlight" );
-      g_assert ( mode_button );
-      gtk_check_menu_item_set_active ( GTK_CHECK_MENU_ITEM(mode_button),vik_viewport_get_draw_highlight (vw->viking_vvp) );
+      // Slightly long winded methods to align loaded viewport settings with the UI
+      //  Since the rewrite for toolbar + menu actions
+      //  there no longer exists a simple way to directly change the UI to a value for toggle settings
+      //  it only supports toggling the existing setting (otherwise get infinite loops in trying to align tb+menu elements)
+      // Thus get state, compare them, if different then invert viewport setting and (re)sync the setting (via toggling)
+      gboolean vp_state_scale = vik_viewport_get_draw_scale ( vw->viking_vvp );
+      gboolean ui_state_scale = gtk_check_menu_item_get_active ( GTK_CHECK_MENU_ITEM(get_show_widget_by_name(vw, "ShowScale")) );
+      if ( vp_state_scale != ui_state_scale ) {
+        vik_viewport_set_draw_scale ( vw->viking_vvp, !vp_state_scale );
+        toggle_draw_scale ( NULL, vw );
+      }
+      gboolean vp_state_centermark = vik_viewport_get_draw_centermark ( vw->viking_vvp );
+      gboolean ui_state_centermark = gtk_check_menu_item_get_active ( GTK_CHECK_MENU_ITEM(get_show_widget_by_name(vw, "ShowCenterMark")) );
+      if ( vp_state_centermark != ui_state_centermark ) {
+        vik_viewport_set_draw_centermark ( vw->viking_vvp, !vp_state_centermark );
+        toggle_draw_centermark ( NULL, vw );
+      }
+      gboolean vp_state_highlight = vik_viewport_get_draw_highlight ( vw->viking_vvp );
+      gboolean ui_state_highlight = gtk_check_menu_item_get_active ( GTK_CHECK_MENU_ITEM(get_show_widget_by_name(vw, "ShowHighlight")) );
+      if ( vp_state_highlight != ui_state_highlight ) {
+        vik_viewport_set_draw_highlight ( vw->viking_vvp, !vp_state_highlight );
+        toggle_draw_highlight ( NULL, vw );
+      }
     }
       // NB No break, carry on to redraw
     //case LOAD_TYPE_OTHER_SUCCESS:
     }
       // NB No break, carry on to redraw
     //case LOAD_TYPE_OTHER_SUCCESS:
@@ -4193,7 +4266,7 @@ static void window_change_coord_mode_cb ( GtkAction *old_a, GtkAction *a, VikWin
   }
 }
 
   }
 }
 
-static void set_draw_scale ( GtkAction *a, VikWindow *vw )
+static void toggle_draw_scale ( GtkAction *a, VikWindow *vw )
 {
   gboolean state = !vik_viewport_get_draw_scale ( vw->viking_vvp );
   GtkWidget *check_box = gtk_ui_manager_get_widget ( vw->uim, "/ui/MainMenu/View/SetShow/ShowScale" );
 {
   gboolean state = !vik_viewport_get_draw_scale ( vw->viking_vvp );
   GtkWidget *check_box = gtk_ui_manager_get_widget ( vw->uim, "/ui/MainMenu/View/SetShow/ShowScale" );
@@ -4204,7 +4277,7 @@ static void set_draw_scale ( GtkAction *a, VikWindow *vw )
   draw_update ( vw );
 }
 
   draw_update ( vw );
 }
 
-static void set_draw_centermark ( GtkAction *a, VikWindow *vw )
+static void toggle_draw_centermark ( GtkAction *a, VikWindow *vw )
 {
   gboolean state = !vik_viewport_get_draw_centermark ( vw->viking_vvp );
   GtkWidget *check_box = gtk_ui_manager_get_widget ( vw->uim, "/ui/MainMenu/View/SetShow/ShowCenterMark" );
 {
   gboolean state = !vik_viewport_get_draw_centermark ( vw->viking_vvp );
   GtkWidget *check_box = gtk_ui_manager_get_widget ( vw->uim, "/ui/MainMenu/View/SetShow/ShowCenterMark" );
@@ -4215,26 +4288,15 @@ static void set_draw_centermark ( GtkAction *a, VikWindow *vw )
   draw_update ( vw );
 }
 
   draw_update ( vw );
 }
 
-static void set_draw_highlight ( GtkAction *a, VikWindow *vw )
+static void toggle_draw_highlight ( GtkAction *a, VikWindow *vw )
 {
 {
-  gboolean next_state = !vik_viewport_get_draw_highlight ( vw->viking_vvp );
-  GtkWidget *check_box = get_show_widget_by_name ( vw, gtk_action_get_name(a) );
-  if ( !check_box )
-    return;
-  gboolean menu_state = gtk_check_menu_item_get_active ( GTK_CHECK_MENU_ITEM(check_box) );
-  if ( next_state != menu_state )
-    gtk_check_menu_item_set_active ( GTK_CHECK_MENU_ITEM(check_box), next_state );
-  else {
-    vik_viewport_set_draw_highlight ( vw->viking_vvp, next_state );
-    draw_update ( vw );
-  }
-/*
   gboolean state = !vik_viewport_get_draw_highlight ( vw->viking_vvp );
   GtkWidget *check_box = gtk_ui_manager_get_widget ( vw->uim, "/ui/MainMenu/View/SetShow/ShowHighlight" );
   if ( !check_box )
     return;
   gtk_check_menu_item_set_active ( GTK_CHECK_MENU_ITEM(check_box), state );
   gboolean state = !vik_viewport_get_draw_highlight ( vw->viking_vvp );
   GtkWidget *check_box = gtk_ui_manager_get_widget ( vw->uim, "/ui/MainMenu/View/SetShow/ShowHighlight" );
   if ( !check_box )
     return;
   gtk_check_menu_item_set_active ( GTK_CHECK_MENU_ITEM(check_box), state );
-  */
+  vik_viewport_set_draw_highlight ( vw->viking_vvp, state );
+  draw_update ( vw );
 }
 
 static void set_bg_color ( GtkAction *a, VikWindow *vw )
 }
 
 static void set_bg_color ( GtkAction *a, VikWindow *vw )
@@ -4355,6 +4417,7 @@ static GtkActionEntry entries[] = {
 
 static GtkActionEntry debug_entries[] = {
   { "MapCacheInfo", NULL,                "_Map Cache Info",                   NULL,         NULL,                                           (GCallback)help_cache_info_cb    },
 
 static GtkActionEntry debug_entries[] = {
   { "MapCacheInfo", NULL,                "_Map Cache Info",                   NULL,         NULL,                                           (GCallback)help_cache_info_cb    },
+  { "BackForwardInfo", NULL,             "_Back/Forward Info",                NULL,         NULL,                                           (GCallback)back_forward_info_cb  },
 };
 
 static GtkActionEntry entries_gpsbabel[] = {
 };
 
 static GtkActionEntry entries_gpsbabel[] = {
@@ -4374,9 +4437,9 @@ static GtkRadioActionEntry mode_entries[] = {
 };
 
 static GtkToggleActionEntry toggle_entries[] = {
 };
 
 static GtkToggleActionEntry toggle_entries[] = {
-  { "ShowScale",      NULL,                 N_("Show _Scale"),               "<shift>F5",  N_("Show Scale"),                              (GCallback)set_draw_scale, TRUE },
-  { "ShowCenterMark", NULL,                 N_("Show _Center Mark"),         "F6",         N_("Show Center Mark"),                        (GCallback)set_draw_centermark, TRUE },
-  { "ShowHighlight",  GTK_STOCK_UNDERLINE,  N_("Show _Highlight"),           "F7",         N_("Show Highlight"),                          (GCallback)set_draw_highlight, TRUE },
+  { "ShowScale",      NULL,                 N_("Show _Scale"),               "<shift>F5",  N_("Show Scale"),                              (GCallback)toggle_draw_scale, TRUE },
+  { "ShowCenterMark", NULL,                 N_("Show _Center Mark"),         "F6",         N_("Show Center Mark"),                        (GCallback)toggle_draw_centermark, TRUE },
+  { "ShowHighlight",  GTK_STOCK_UNDERLINE,  N_("Show _Highlight"),           "F7",         N_("Show Highlight"),                          (GCallback)toggle_draw_highlight, TRUE },
   { "FullScreen",     GTK_STOCK_FULLSCREEN, N_("_Full Screen"),              "F11",        N_("Activate full screen mode"),               (GCallback)full_screen_cb, FALSE },
   { "ViewSidePanel",  GTK_STOCK_INDEX,      N_("Show Side _Panel"),          "F9",         N_("Show Side Panel"),                         (GCallback)view_side_panel_cb, TRUE },
   { "ViewStatusBar",  NULL,                 N_("Show Status_bar"),           "F12",        N_("Show Statusbar"),                          (GCallback)view_statusbar_cb, TRUE },
   { "FullScreen",     GTK_STOCK_FULLSCREEN, N_("_Full Screen"),              "F11",        N_("Activate full screen mode"),               (GCallback)full_screen_cb, FALSE },
   { "ViewSidePanel",  GTK_STOCK_INDEX,      N_("Show Side _Panel"),          "F9",         N_("Show Side Panel"),                         (GCallback)view_side_panel_cb, TRUE },
   { "ViewStatusBar",  NULL,                 N_("Show Status_bar"),           "F12",        N_("Show Statusbar"),                          (GCallback)view_statusbar_cb, TRUE },
@@ -4435,7 +4498,10 @@ static void window_create_ui( VikWindow *window )
   gtk_action_group_add_radio_actions (action_group, mode_entries, G_N_ELEMENTS (mode_entries), 4, (GCallback)window_change_coord_mode_cb, window);
   if ( vik_debug ) {
     if ( gtk_ui_manager_add_ui_from_string ( uim,
   gtk_action_group_add_radio_actions (action_group, mode_entries, G_N_ELEMENTS (mode_entries), 4, (GCallback)window_change_coord_mode_cb, window);
   if ( vik_debug ) {
     if ( gtk_ui_manager_add_ui_from_string ( uim,
-         "<ui><menubar name='MainMenu'><menu action='Help'><menuitem action='MapCacheInfo'/></menu></menubar></ui>",
+         "<ui><menubar name='MainMenu'><menu action='Help'>"
+           "<menuitem action='MapCacheInfo'/>"
+           "<menuitem action='BackForwardInfo'/>"
+         "</menu></menubar></ui>",
          -1, NULL ) ) {
       gtk_action_group_add_actions (action_group, debug_entries, G_N_ELEMENTS (debug_entries), window);
     }
          -1, NULL ) ) {
       gtk_action_group_add_actions (action_group, debug_entries, G_N_ELEMENTS (debug_entries), window);
     }
@@ -4735,7 +4801,12 @@ gboolean vik_window_clear_highlight ( VikWindow *vw )
   return need_redraw;
 }
 
   return need_redraw;
 }
 
+/**
+ * May return NULL if the window no longer exists
+ */
 GThread *vik_window_get_thread ( VikWindow *vw )
 {
 GThread *vik_window_get_thread ( VikWindow *vw )
 {
-  return vw->thread;
+  if ( vw )
+    return vw->thread;
+  return NULL;
 }
 }