static void trw_layer_merge_with_other ( gpointer pass_along[6] );
static void trw_layer_split_by_timestamp ( gpointer pass_along[6] );
static void trw_layer_split_by_n_points ( gpointer pass_along[6] );
-static void trw_layer_download_map_along_track_cb (gpointer pass_along[6]);
+static void trw_layer_download_map_along_track_cb ( gpointer pass_along[6] );
+static void trw_layer_edit_trackpoint ( gpointer pass_along[6] );
+static void trw_layer_show_picture ( gpointer pass_along[6] );
+
static void trw_layer_centerize ( gpointer layer_and_vlp[2] );
static void trw_layer_auto_view ( gpointer layer_and_vlp[2] );
static void trw_layer_export ( gpointer layer_and_vlp[2], const gchar* title, const gchar* default_name, const gchar* trackname, guint file_type );
static void trw_layer_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] );
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 );
+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 );
{ 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 };
(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?) */
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 );
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);
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);
}
*/
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:
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 );
+ 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_WAYPOINT:
{
- vik_window_set_selected_waypoint ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(l), g_hash_table_lookup ( l->waypoints, sublayer ), l );
+ 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;
}
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];
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
+ 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 ) {
#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 );
}
}
#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 );
}
}
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 )
}
}
+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
*************************************/
}
/* 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;
if (t1 > t2) return 1;
return 0;
}
+*/
/* comparison function used to sort trackpoints */
static gint trackpoint_compare(gconstpointer a, gconstpointer b)
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;
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;
}
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;
}
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]));
}
/**
/* 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] )
{
/* 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;
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 )
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) )
{
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;
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 ( _("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 );
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_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 );
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;
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 ) ) )
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 )
+static gboolean trw_layer_select_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp, tool_ed_t* tet )
{
if ( event->button != 1 )
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 */
+ // 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;
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;
}
}
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;
}
return FALSE;
}
-typedef struct {
- VikViewport *vvp;
- gboolean holding;
- GdkGC *gc;
- int oldx, oldy;
-} tool_ed_t;
-
static void marker_begin_move ( tool_ed_t *t, gint x, gint y )
{
t->holding = TRUE;
}
}
+static void 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
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) {