gboolean has_verified_thumbnails;
GtkMenu *wp_right_click_menu;
+ GtkMenu *track_right_click_menu;
/* menu */
VikStdLayerMenuItem menu_selection;
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 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_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_with_other ( gpointer pass_along[6] );
static void trw_layer_split_by_timestamp ( gpointer pass_along[6] );
-static void trw_layer_download_map_along_track_cb(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_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_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 */
-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 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 );
(VikLayerFuncSublayerToggleVisible) vik_trw_layer_sublayer_toggle_visible,
(VikLayerFuncSublayerTooltip) trw_layer_sublayer_tooltip,
(VikLayerFuncLayerTooltip) trw_layer_layer_tooltip,
+ (VikLayerFuncLayerSelected) vik_trw_layer_selected,
(VikLayerFuncMarshall) trw_layer_marshall,
(VikLayerFuncUnmarshall) trw_layer_unmarshall,
(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?) */
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;
}
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 )
{
- static gpointer pass_along[5];
+ static gpointer pass_along[6];
if (!sublayer) {
return;
}
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);
}
-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]);
}
}
-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);
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;
trw_layer_free_track_gcs ( trwlayer );
if ( trwlayer->wp_right_click_menu )
- gtk_object_sink ( GTK_OBJECT(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 ) );
drawstops = dp->vtl->drawstops;
}
- if ( dp->vtl->drawmode == DRAWMODE_ALL_BLACK )
- dp->track_gc_iter = VIK_TRW_LAYER_TRACK_GC_BLACK;
-
+ /* Current track - used for creation */
if ( track == dp->vtl->current_track )
main_gc = dp->vtl->current_track_gc;
- else
- main_gc = g_array_index(dp->vtl->track_gc, GdkGC *, dp->track_gc_iter);
+ else {
+ if ( vik_viewport_get_draw_highlight ( dp->vp ) ) {
+ /* Draw all tracks of the layer in special colour */
+ /* if track is member of selected layer or is the current selected track
+ then draw in the highlight colour.
+ NB this supercedes the drawmode */
+ 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 = vik_viewport_get_gc_highlight (dp->vp);
+ }
+ else {
+ if ( dp->vtl->drawmode == DRAWMODE_ALL_BLACK )
+ dp->track_gc_iter = VIK_TRW_LAYER_TRACK_GC_BLACK;
+
+ main_gc = g_array_index(dp->vtl->track_gc, GdkGC *, dp->track_gc_iter);
+ }
+ }
+ else {
+ if ( dp->vtl->drawmode == DRAWMODE_ALL_BLACK )
+ dp->track_gc_iter = VIK_TRW_LAYER_TRACK_GC_BLACK;
+
+ main_gc = g_array_index(dp->vtl->track_gc, GdkGC *, dp->track_gc_iter);
+ }
+ }
if (list) {
int x, y, oldx, oldy;
if ( x+(w/2) > 0 && y+(h/2) > 0 && x-(w/2) < dp->width && y-(h/2) < dp->height ) /* always draw within boundaries */
{
+ 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) ) ) {
+ // Highlighted - so draw a little border around the chosen one
+ // single line seems a little weak so draw 2 of them
+ 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 );
+ 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 );
+ }
+ }
if ( dp->vtl->image_alpha == 255 )
vik_viewport_draw_pixbuf ( dp->vp, pixbuf, 0, 0, x - (w/2), y - (h/2), w, h );
else
else
label_y = y - dp->vtl->wp_size - height - 2;
- vik_viewport_draw_rectangle ( dp->vp, dp->vtl->waypoint_bg_gc, TRUE, label_x - 1, label_y-1,width+2,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) ) )
+ 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);
+ }
vik_viewport_draw_layout ( dp->vp, dp->vtl->waypoint_text_gc, label_x, label_y, dp->vtl->wplabellayout );
}
}
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));
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
return NULL;
}
+/**
+ * General layer selection function, find out which bit is selected and take appropriate action
+ */
+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:
+ {
+ vik_window_set_selected_trw_layer ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(l), l );
+ /* Mark for redraw */
+ return TRUE;
+ }
+ break;
+
+ case VIK_TREEVIEW_TYPE_SUBLAYER:
+ {
+ switch ( subtype )
+ {
+ case VIK_TRW_LAYER_SUBLAYER_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:
+ {
+ 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:
+ {
+ 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:
+ {
+ 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;
+ }
+ break;
+ default:
+ {
+ return vik_window_clear_highlight ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(l) );
+ }
+ break;
+ }
+ return FALSE;
+ }
+ break;
+
+ default:
+ return vik_window_clear_highlight ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(l) );
+ break;
+ }
+}
GHashTable *vik_trw_layer_get_tracks ( VikTrwLayer *l )
{
{
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.") );
}
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];
{
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;
}
gboolean vik_trw_layer_new_waypoint ( VikTrwLayer *vtl, GtkWindow *w, const VikCoord *def_coord )
{
- gchar *name = highest_wp_number_get(vtl);
+ gchar *default_name = highest_wp_number_get(vtl);
VikWaypoint *wp = vik_waypoint_new();
+ gchar *returned_name;
+ gboolean updated;
wp->coord = *def_coord;
- if ( a_dialog_new_waypoint ( w, &name, wp, vik_trw_layer_get_waypoints ( vtl ), vtl->coord_mode ) )
+ if ( ( returned_name = a_dialog_waypoint ( w, default_name, wp, vik_trw_layer_get_waypoints ( vtl ), vtl->coord_mode, TRUE, &updated ) ) )
{
wp->visible = TRUE;
- vik_trw_layer_add_waypoint ( vtl, name, wp );
+ vik_trw_layer_add_waypoint ( vtl, returned_name, wp );
+ g_free (default_name);
return TRUE;
}
+ g_free (default_name);
vik_waypoint_free(wp);
return FALSE;
}
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 );
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 );
#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
// 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 );
}
}
#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 );
}
}
}
}
-
gboolean vik_trw_layer_delete_track ( VikTrwLayer *vtl, const gchar *trk_name )
{
VikTrack *t = g_hash_table_lookup ( vtl->tracks, trk_name );
{
GtkTreeIter *it;
was_visible = t->visible;
- if ( t == vtl->current_track )
+ if ( t == vtl->current_track ) {
vtl->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 );
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;
}
-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 )
VikWaypoint *wp = g_hash_table_lookup ( vtl->waypoints, pass_along[3] );
if ( wp )
{
- if ( a_dialog_new_waypoint ( VIK_GTK_WINDOW_FROM_LAYER(vtl), NULL, wp, NULL, vtl->coord_mode ) )
+ gboolean updated = FALSE;
+ a_dialog_waypoint ( VIK_GTK_WINDOW_FROM_LAYER(vtl), pass_along[3], wp, NULL, vtl->coord_mode, FALSE, &updated );
- if ( VIK_LAYER(vtl)->visible )
- vik_layer_emit_update ( VIK_LAYER(vtl) );
+ if ( updated && VIK_LAYER(vtl)->visible )
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
}
}
else
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 )
- 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] );
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);
}
}
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) );
}
/**
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) ;
}
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;
- 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;
- 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;
- goto_coord ( VIK_LAYERS_PANEL(pass_along[1]), &(vtp->coord));
+ goto_coord ( pass_along[1], pass_along[0], pass_along[5], &(vtp->coord));
}
/*
{
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
*************************************/
vik_layer_emit_update(VIK_LAYER(pass_along[0]));
}
+/**
+ * Split a track by the number of points as specified by the user
+ */
+static void trw_layer_split_by_n_points ( gpointer pass_along[6] )
+{
+ VikTrwLayer *vtl = (VikTrwLayer *)pass_along[0];
+ VikTrack *track = (VikTrack *)g_hash_table_lookup ( vtl->tracks, pass_along[3] );
+
+ // Check valid track
+ GList *trps = track->trackpoints;
+ if ( !trps )
+ return;
+
+ gint points = a_dialog_get_positive_number(VIK_GTK_WINDOW_FROM_LAYER(pass_along[0]),
+ _("Split Every Nth Point"),
+ _("Split on every Nth point:"),
+ 250, // Default value as per typical limited track capacity of various GPS devices
+ 2, // Min
+ 65536, // Max
+ 5); // Step
+ // Was a valid number returned?
+ if (!points)
+ return;
+
+ // Now split...
+ GList *iter;
+ GList *newlists = NULL;
+ GList *newtps = NULL;
+ gint count = 0;
+ iter = trps;
+
+ while (iter) {
+ /* accumulate trackpoint copies in newtps, in reverse order */
+ newtps = g_list_prepend(newtps, vik_trackpoint_copy(VIK_TRACKPOINT(iter->data)));
+ count++;
+ if (count >= points) {
+ /* flush accumulated trackpoints into new list */
+ newlists = g_list_append(newlists, g_list_reverse(newtps));
+ newtps = NULL;
+ count = 0;
+ }
+ iter = g_list_next(iter);
+ }
+
+ // If there is a remaining chunk put that into the new split list
+ // This may well be the whole track if no split points were encountered
+ if (newtps) {
+ newlists = g_list_append(newlists, g_list_reverse(newtps));
+ }
+
+ /* put lists of trackpoints into tracks */
+ iter = newlists;
+ guint i = 1;
+ // 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);
+
+ 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);
+
+ iter = g_list_next(iter);
+ }
+ // Remove original track and then update the display
+ 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);
+}
+
/* 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 )
- 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);
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 );
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 );
}
}
-/* 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 gpointer pass_along[5];
+ static gpointer pass_along[6];
GtkWidget *item;
gboolean rv = FALSE;
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 )
{
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") );
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) )
{
- item = gtk_menu_item_new_with_mnemonic ( _("_New Waypoint") );
+ rv = TRUE;
+ 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 );
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 );
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 ( _("Down_load Maps Along Track...") );
- g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_download_map_along_track_cb), pass_along );
+ 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 );
+ /* 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 ( _("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 );
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 );
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 );
- }
+ }
+
}
return rv;
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 )
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;
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;
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) );
if ( event->button == 3 && vtl->waypoint_rightclick )
{
if ( vtl->wp_right_click_menu )
- gtk_object_sink ( GTK_OBJECT(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;
}
return TRUE;
}
-
/*** New waypoint ****/
static gpointer tool_new_waypoint_create ( VikWindow *vw, VikViewport *vvp)
{
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;
}
}
+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 };
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
*pics = g_slist_append ( *pics, (gpointer) g_strdup ( wp->image ) );
}
-static void create_thumbnails_thread ( GSList *pics, gpointer threaddata )
+/* Structure for thumbnail creating data used in the background thread */
+typedef struct {
+ VikTrwLayer *vtl; // Layer needed for redrawing
+ GSList *pics; // Image list
+} thumbnail_create_thread_data;
+
+static int create_thumbnails_thread ( thumbnail_create_thread_data *tctd, gpointer threaddata )
{
- guint total = g_slist_length(pics), done = 0;
- while ( pics )
+ guint total = g_slist_length(tctd->pics), done = 0;
+ while ( tctd->pics )
{
- a_thumbnails_create ( (gchar *) pics->data );
- a_background_thread_progress ( threaddata, ((gdouble) ++done) / total );
- pics = pics->next;
+ a_thumbnails_create ( (gchar *) tctd->pics->data );
+ int result = a_background_thread_progress ( threaddata, ((gdouble) ++done) / total );
+ if ( result != 0 )
+ return -1; /* Abort thread */
+
+ tctd->pics = tctd->pics->next;
}
+
+ // Redraw to show the thumbnails as they are now created
+ gdk_threads_enter();
+ if ( IS_VIK_LAYER(tctd->vtl) )
+ vik_layer_emit_update ( VIK_LAYER(tctd->vtl) );
+ gdk_threads_leave();
+
+ return 0;
}
-static void free_pics_slist ( GSList *pics )
+static void thumbnail_create_thread_free ( thumbnail_create_thread_data *tctd )
{
- while ( pics )
+ while ( tctd->pics )
{
- g_free ( pics->data );
- pics = g_slist_delete_link ( pics, pics );
+ g_free ( tctd->pics->data );
+ tctd->pics = g_slist_delete_link ( tctd->pics, tctd->pics );
}
+ g_free ( tctd );
}
static void trw_layer_verify_thumbnails ( VikTrwLayer *vtl, GtkWidget *vp )
{
gint len = g_slist_length ( pics );
gchar *tmp = g_strdup_printf ( _("Creating %d Image Thumbnails..."), len );
- a_background_thread ( VIK_GTK_WINDOW_FROM_LAYER(vtl), tmp, (vik_thr_func) create_thumbnails_thread, pics, (vik_thr_free_func) free_pics_slist, NULL, len );
+ thumbnail_create_thread_data *tctd = g_malloc ( sizeof(thumbnail_create_thread_data) );
+ tctd->vtl = vtl;
+ tctd->pics = pics;
+ a_background_thread ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
+ tmp,
+ (vik_thr_func) create_thumbnails_thread,
+ tctd,
+ (vik_thr_free_func) thumbnail_create_thread_free,
+ NULL,
+ len );
g_free ( tmp );
}
}
}
}
-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;
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) {