]> git.street.me.uk Git - andy/viking.git/blobdiff - src/viktrwlayer_tpwin.c
SF Bugs#113: Fix waypoints can be accidentally moved on (re)selection by the select...
[andy/viking.git] / src / viktrwlayer_tpwin.c
index 5f7bf812bf297660c6dfd896aaa3f97f98809bba..22c849032faa2de063c6ae3cfc1fdc781a9352d9 100644 (file)
 #include "viktrack.h"
 #include "viktrwlayer_tpwin.h"
 #include "vikwaypoint.h"
 #include "viktrack.h"
 #include "viktrwlayer_tpwin.h"
 #include "vikwaypoint.h"
+#include "vikutils.h"
 #include "dialog.h"
 #include "globals.h"
 #include "dialog.h"
 #include "globals.h"
+#include "vikdatetime_edit_dialog.h"
 
 struct _VikTrwLayerTpwin {
   GtkDialog parent;
   GtkSpinButton *lat, *lon, *alt, *ts;
   GtkWidget *trkpt_name;
 
 struct _VikTrwLayerTpwin {
   GtkDialog parent;
   GtkSpinButton *lat, *lon, *alt, *ts;
   GtkWidget *trkpt_name;
-  GtkLabel *course, *localtime, *diff_dist, *diff_time, *diff_speed, *speed, *hdop, *vdop, *pdop, *sat;
+  GtkWidget *time;
+  GtkLabel *course, *diff_dist, *diff_time, *diff_speed, *speed, *hdop, *vdop, *pdop, *sat;
   // Previously these buttons were in a glist, however I think the ordering behaviour is implicit
   //  thus control manually to ensure operating on the correct button
   GtkWidget *button_close;
   // Previously these buttons were in a glist, however I think the ordering behaviour is implicit
   //  thus control manually to ensure operating on the correct button
   GtkWidget *button_close;
@@ -82,16 +85,15 @@ GType vik_trw_layer_tpwin_get_type (void)
  */
 static void tpwin_update_times ( VikTrwLayerTpwin *tpwin, VikTrackpoint *tp )
 {
  */
 static void tpwin_update_times ( VikTrwLayerTpwin *tpwin, VikTrackpoint *tp )
 {
-  char tmp_str[64];
-
   if ( tp->has_timestamp ) {
     gtk_spin_button_set_value ( tpwin->ts, tp->timestamp );
   if ( tp->has_timestamp ) {
     gtk_spin_button_set_value ( tpwin->ts, tp->timestamp );
-    strftime ( tmp_str, sizeof(tmp_str), "%c", localtime(&(tp->timestamp)) );
-    gtk_label_set_text ( tpwin->localtime, tmp_str );
+    gchar *msg = vu_get_time_string ( &(tp->timestamp), "%c", &(tp->coord), NULL );
+    gtk_button_set_label ( GTK_BUTTON(tpwin->time), msg );
+    g_free ( msg );
   }
   else {
     gtk_spin_button_set_value ( tpwin->ts, 0 );
   }
   else {
     gtk_spin_button_set_value ( tpwin->ts, 0 );
-    gtk_label_set_text (tpwin->localtime, NULL );
+    gtk_button_set_label ( GTK_BUTTON(tpwin->time), "" );
   }
 }
 
   }
 }
 
@@ -145,6 +147,45 @@ static void tpwin_sync_ts_to_tp ( VikTrwLayerTpwin *tpwin )
   }
 }
 
   }
 }
 
+static time_t last_edit_time = 0;
+
+/**
+ * tpwin_sync_time_to_tp:
+ *
+ */
+static void tpwin_sync_time_to_tp ( VikTrwLayerTpwin *tpwin )
+{
+  if ( !tpwin->cur_tp || tpwin->sync_to_tp_block )
+    return;
+
+  if ( tpwin->cur_tp->has_timestamp )
+    last_edit_time = tpwin->cur_tp->timestamp;
+  else if ( last_edit_time == 0 )
+    time ( &last_edit_time );
+
+  GTimeZone *gtz = g_time_zone_new_local ();
+  time_t mytime = vik_datetime_edit_dialog ( GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(&tpwin->parent))),
+                                             _("Date/Time Edit"),
+                                             last_edit_time,
+                                             gtz );
+  g_time_zone_unref ( gtz );
+
+  // Was the dialog cancelled?
+  if ( mytime == 0 )
+    return;
+
+  // Otherwise use the new value
+  tpwin->cur_tp->timestamp = mytime;
+  tpwin->cur_tp->has_timestamp = TRUE;
+  // TODO: consider warning about unsorted times?
+
+  // Clear the previous 'Add' image as now a time is set
+  if ( gtk_button_get_image ( GTK_BUTTON(tpwin->time) ) )
+    gtk_button_set_image ( GTK_BUTTON(tpwin->time), NULL );
+
+  tpwin_update_times ( tpwin, tpwin->cur_tp );
+}
+
 static gboolean tpwin_set_name ( VikTrwLayerTpwin *tpwin )
 {
   if ( tpwin->cur_tp && (!tpwin->sync_to_tp_block) ) {
 static gboolean tpwin_set_name ( VikTrwLayerTpwin *tpwin )
 {
   if ( tpwin->cur_tp && (!tpwin->sync_to_tp_block) ) {
@@ -204,7 +245,9 @@ VikTrwLayerTpwin *vik_trw_layer_tpwin_new ( GtkWindow *parent )
   g_signal_connect_swapped ( G_OBJECT(tpwin->trkpt_name), "focus-out-event", G_CALLBACK(tpwin_set_name), tpwin );
 
   tpwin->course = GTK_LABEL(gtk_label_new(NULL));
   g_signal_connect_swapped ( G_OBJECT(tpwin->trkpt_name), "focus-out-event", G_CALLBACK(tpwin_set_name), tpwin );
 
   tpwin->course = GTK_LABEL(gtk_label_new(NULL));
-  tpwin->localtime = GTK_LABEL(gtk_label_new(NULL));
+  tpwin->time = gtk_button_new();
+  gtk_button_set_relief ( GTK_BUTTON(tpwin->time), GTK_RELIEF_NONE );
+  g_signal_connect_swapped ( G_OBJECT(tpwin->time), "clicked", G_CALLBACK(tpwin_sync_time_to_tp), tpwin );
 
   tpwin->lat = GTK_SPIN_BUTTON(gtk_spin_button_new( GTK_ADJUSTMENT(gtk_adjustment_new (
                                  0, -90, 90, 0.00005, 0.01, 0 )), 0.00005, 6));
 
   tpwin->lat = GTK_SPIN_BUTTON(gtk_spin_button_new( GTK_ADJUSTMENT(gtk_adjustment_new (
                                  0, -90, 90, 0.00005, 0.01, 0 )), 0.00005, 6));
@@ -230,7 +273,7 @@ VikTrwLayerTpwin *vik_trw_layer_tpwin_new ( GtkWindow *parent )
   gtk_box_pack_start ( GTK_BOX(right_vbox), GTK_WIDGET(tpwin->alt), FALSE, FALSE, 3 );
   gtk_box_pack_start ( GTK_BOX(right_vbox), GTK_WIDGET(tpwin->course), FALSE, FALSE, 3 );
   gtk_box_pack_start ( GTK_BOX(right_vbox), GTK_WIDGET(tpwin->ts), FALSE, FALSE, 3 );
   gtk_box_pack_start ( GTK_BOX(right_vbox), GTK_WIDGET(tpwin->alt), FALSE, FALSE, 3 );
   gtk_box_pack_start ( GTK_BOX(right_vbox), GTK_WIDGET(tpwin->course), FALSE, FALSE, 3 );
   gtk_box_pack_start ( GTK_BOX(right_vbox), GTK_WIDGET(tpwin->ts), FALSE, FALSE, 3 );
-  gtk_box_pack_start ( GTK_BOX(right_vbox), GTK_WIDGET(tpwin->localtime), FALSE, FALSE, 3 );
+  gtk_box_pack_start ( GTK_BOX(right_vbox), GTK_WIDGET(tpwin->time), FALSE, FALSE, 3 );
 
   /* diff info */
   diff_left_vbox = a_dialog_create_label_vbox ( right_label_texts, G_N_ELEMENTS(right_label_texts), 1, 3 );
 
   /* diff info */
   diff_left_vbox = a_dialog_create_label_vbox ( right_label_texts, G_N_ELEMENTS(right_label_texts), 1, 3 );
@@ -281,13 +324,14 @@ void vik_trw_layer_tpwin_set_empty ( VikTrwLayerTpwin *tpwin )
   gtk_editable_delete_text ( GTK_EDITABLE(tpwin->trkpt_name), 0, -1 );
   gtk_widget_set_sensitive ( tpwin->trkpt_name, FALSE );
 
   gtk_editable_delete_text ( GTK_EDITABLE(tpwin->trkpt_name), 0, -1 );
   gtk_widget_set_sensitive ( tpwin->trkpt_name, FALSE );
 
-  gtk_label_set_text ( tpwin->localtime, NULL );
+  gtk_button_set_label ( GTK_BUTTON(tpwin->time), "" );
   gtk_label_set_text ( tpwin->course, NULL );
 
   gtk_widget_set_sensitive ( GTK_WIDGET(tpwin->lat), FALSE );
   gtk_widget_set_sensitive ( GTK_WIDGET(tpwin->lon), FALSE );
   gtk_widget_set_sensitive ( GTK_WIDGET(tpwin->alt), FALSE );
   gtk_widget_set_sensitive ( GTK_WIDGET(tpwin->ts), FALSE );
   gtk_label_set_text ( tpwin->course, NULL );
 
   gtk_widget_set_sensitive ( GTK_WIDGET(tpwin->lat), FALSE );
   gtk_widget_set_sensitive ( GTK_WIDGET(tpwin->lon), FALSE );
   gtk_widget_set_sensitive ( GTK_WIDGET(tpwin->alt), FALSE );
   gtk_widget_set_sensitive ( GTK_WIDGET(tpwin->ts), FALSE );
+  gtk_widget_set_sensitive ( GTK_WIDGET(tpwin->time), FALSE );
 
   // Only keep close button enabled
   gtk_widget_set_sensitive ( tpwin->button_insert, FALSE );
 
   // Only keep close button enabled
   gtk_widget_set_sensitive ( tpwin->button_insert, FALSE );
@@ -308,7 +352,17 @@ void vik_trw_layer_tpwin_set_empty ( VikTrwLayerTpwin *tpwin )
   gtk_window_set_title ( GTK_WINDOW(tpwin), _("Trackpoint") );
 }
 
   gtk_window_set_title ( GTK_WINDOW(tpwin), _("Trackpoint") );
 }
 
-void vik_trw_layer_tpwin_set_tp ( VikTrwLayerTpwin *tpwin, GList *tpl, const gchar *track_name )
+/**
+ * vik_trw_layer_tpwin_set_tp:
+ * @tpwin:      The Trackpoint Edit Window
+ * @tpl:        The #Glist of trackpoints pointing at the current trackpoint
+ * @track_name: The name of the track in which the trackpoint belongs
+ * @is_route:   Is the track of the trackpoint actually a route?
+ *
+ * Sets the Trackpoint Edit Window to the values of the current trackpoint given in @tpl.
+ *
+ */
+void vik_trw_layer_tpwin_set_tp ( VikTrwLayerTpwin *tpwin, GList *tpl, const gchar *track_name, gboolean is_route )
 {
   static char tmp_str[64];
   static struct LatLon ll;
 {
   static char tmp_str[64];
   static struct LatLon ll;
@@ -334,6 +388,14 @@ void vik_trw_layer_tpwin_set_tp ( VikTrwLayerTpwin *tpwin, GList *tpl, const gch
   gtk_widget_set_sensitive ( GTK_WIDGET(tpwin->lon), TRUE );
   gtk_widget_set_sensitive ( GTK_WIDGET(tpwin->alt), TRUE );
   gtk_widget_set_sensitive ( GTK_WIDGET(tpwin->ts), tp->has_timestamp );
   gtk_widget_set_sensitive ( GTK_WIDGET(tpwin->lon), TRUE );
   gtk_widget_set_sensitive ( GTK_WIDGET(tpwin->alt), TRUE );
   gtk_widget_set_sensitive ( GTK_WIDGET(tpwin->ts), tp->has_timestamp );
+  gtk_widget_set_sensitive ( GTK_WIDGET(tpwin->time), tp->has_timestamp );
+  // Enable adding timestamps - but not on routepoints
+  if ( !tp->has_timestamp && !is_route ) {
+    gtk_widget_set_sensitive ( GTK_WIDGET(tpwin->time), TRUE );
+    GtkWidget *img = gtk_image_new_from_stock ( GTK_STOCK_ADD, GTK_ICON_SIZE_MENU );
+    gtk_button_set_image ( GTK_BUTTON(tpwin->time), img );
+  }
+  else
 
   vik_trw_layer_tpwin_set_track_name ( tpwin, track_name );
 
 
   vik_trw_layer_tpwin_set_track_name ( tpwin, track_name );
 
@@ -368,6 +430,7 @@ void vik_trw_layer_tpwin_set_tp ( VikTrwLayerTpwin *tpwin, GList *tpl, const gch
       g_snprintf ( tmp_str, sizeof(tmp_str), "%.2f m", vik_coord_diff(&(tp->coord), &(tpwin->cur_tp->coord)));
       break;
     case VIK_UNITS_DISTANCE_MILES:
       g_snprintf ( tmp_str, sizeof(tmp_str), "%.2f m", vik_coord_diff(&(tp->coord), &(tpwin->cur_tp->coord)));
       break;
     case VIK_UNITS_DISTANCE_MILES:
+    case VIK_UNITS_DISTANCE_NAUTICAL_MILES:
       g_snprintf ( tmp_str, sizeof(tmp_str), "%.2f yards", vik_coord_diff(&(tp->coord), &(tpwin->cur_tp->coord))*1.0936133);
       break;
     default:
       g_snprintf ( tmp_str, sizeof(tmp_str), "%.2f yards", vik_coord_diff(&(tp->coord), &(tpwin->cur_tp->coord))*1.0936133);
       break;
     default: