X-Git-Url: https://git.street.me.uk/andy/viking.git/blobdiff_plain/43f2e1dabaf1937e9dd159798ba9a8110d5f912f..1d0351050d93479f131ca47509751a4c3dcadce5:/src/vikwindow.c diff --git a/src/vikwindow.c b/src/vikwindow.c index 37951fbc..b76b5197 100644 --- a/src/vikwindow.c +++ b/src/vikwindow.c @@ -180,6 +180,8 @@ struct _VikWindow { gpointer selected_name; /* notionally gchar */ ////// NEED TO THINK ABOUT VALIDITY OF THESE ////// ////// i.e. what happens when stuff is deleted elsewhere ////// + ////// Generally seems alright as can not access them ////// + ////// containing_vtl now seems unecessary ////// /* For track(s) & waypoint(s) it is the layer they are in - this helps refering to the individual item easier */ gpointer containing_vtl; /* notionally VikTrwLayer */ }; @@ -188,6 +190,7 @@ enum { TOOL_PAN = 0, TOOL_ZOOM, TOOL_RULER, + TOOL_SELECT, TOOL_LAYER, NUMBER_OF_TOOLS }; @@ -200,7 +203,7 @@ enum { static guint window_signals[VW_LAST_SIGNAL] = { 0 }; -static gchar *tool_names[NUMBER_OF_TOOLS] = { N_("Pan"), N_("Zoom"), N_("Ruler") }; +static gchar *tool_names[NUMBER_OF_TOOLS] = { N_("Pan"), N_("Zoom"), N_("Ruler"), N_("Select") }; GType vik_window_get_type (void) { @@ -236,6 +239,14 @@ VikLayersPanel * vik_window_layers_panel(VikWindow *vw) return(vw->viking_vlp); } +/** + * Returns the statusbar for the window + */ +VikStatusbar * vik_window_get_statusbar ( VikWindow *vw ) +{ + return vw->viking_vs; +} + void vik_window_selected_layer(VikWindow *vw, VikLayer *vl) { int i, j, tool_count; @@ -370,6 +381,11 @@ static gboolean key_press_event( VikWindow *vw, GdkEventKey *event, gpointer dat return vw->vt->tools[vw->vt->active_tool].ti.key_press(vl, event, vw->vt->tools[vw->vt->active_tool].state); } + // No layer - but enable window tool keypress processing - these should be able to handle a NULL layer + if ( vw->vt->tools[vw->vt->active_tool].ti.key_press ) { + return vw->vt->tools[vw->vt->active_tool].ti.key_press ( vl, event, vw->vt->tools[vw->vt->active_tool].state ); + } + /* Restore Main Menu via Escape key if the user has hidden it */ /* This key is more likely to be used as they may not remember the function key */ if ( event->keyval == GDK_Escape ) { @@ -446,11 +462,11 @@ static void draw_status ( VikWindow *vw ) /* xmpp should be a whole number so don't show useless .000 bit */ g_snprintf ( zoom_level, 22, "%d %s", (int)xmpp, unit ); if ( vw->current_tool == TOOL_LAYER ) - vik_statusbar_set_message ( vw->viking_vs, 0, vik_layer_get_interface(vw->tool_layer_id)->tools[vw->tool_tool_id].name ); + vik_statusbar_set_message ( vw->viking_vs, VIK_STATUSBAR_TOOL, vik_layer_get_interface(vw->tool_layer_id)->tools[vw->tool_tool_id].name ); else - vik_statusbar_set_message ( vw->viking_vs, 0, _(tool_names[vw->current_tool]) ); + vik_statusbar_set_message ( vw->viking_vs, VIK_STATUSBAR_TOOL, _(tool_names[vw->current_tool]) ); - vik_statusbar_set_message ( vw->viking_vs, 2, zoom_level ); + vik_statusbar_set_message ( vw->viking_vs, VIK_STATUSBAR_ZOOM, zoom_level ); } void vik_window_set_redraw_trigger(VikLayer *vl) @@ -597,7 +613,7 @@ static void draw_mouse_motion (VikWindow *vw, GdkEventMotion *event) lat = NULL; g_free (lon); lon = NULL; - vik_statusbar_set_message ( vw->viking_vs, 4, pointer_buf ); + vik_statusbar_set_message ( vw->viking_vs, VIK_STATUSBAR_POSITION, pointer_buf ); vik_window_pan_move ( vw, event ); @@ -909,7 +925,7 @@ static VikLayerToolFuncStatus ruler_click (VikLayer *vl, GdkEventButton *event, s->has_oldcoord = TRUE; } - vik_statusbar_set_message ( s->vw->viking_vs, 3, temp ); + vik_statusbar_set_message ( s->vw->viking_vs, VIK_STATUSBAR_INFO, temp ); g_free ( temp ); s->oldcoord = coord; @@ -973,7 +989,7 @@ static VikLayerToolFuncStatus ruler_move (VikLayer *vl, GdkEventMotion *event, r temp = g_strdup_printf ("Just to keep the compiler happy"); g_critical("Houston, we've had a problem. distance=%d", dist_units); } - vik_statusbar_set_message ( vw->viking_vs, 3, temp ); + vik_statusbar_set_message ( vw->viking_vs, VIK_STATUSBAR_INFO, temp ); g_free ( temp ); } return VIK_LAYER_TOOL_ACK; @@ -989,6 +1005,16 @@ static void ruler_deactivate (VikLayer *vl, ruler_tool_state_t *s) draw_update ( s->vw ); } +static gboolean ruler_key_press (VikLayer *vl, GdkEventKey *event, ruler_tool_state_t *s) +{ + if (event->keyval == GDK_Escape) { + s->has_oldcoord = FALSE; + ruler_deactivate ( vl, s ); + return TRUE; + } + return FALSE; +} + static VikToolInterface ruler_tool = { "Ruler", (VikToolConstructorFunc) ruler_create, @@ -998,7 +1024,7 @@ static VikToolInterface ruler_tool = (VikToolMouseFunc) ruler_click, (VikToolMouseMoveFunc) ruler_move, (VikToolMouseFunc) ruler_release, - NULL, + (VikToolKeyFunc) ruler_key_press, GDK_CURSOR_IS_PIXMAP, &cursor_ruler_pixbuf }; /*** end ruler code ********************************************************/ @@ -1092,6 +1118,124 @@ static VikToolInterface pan_tool = GDK_FLEUR }; /*** end pan code ********************************************************/ +/******************************************************************************** + ** Select tool code + ********************************************************************************/ +static gpointer selecttool_create (VikWindow *vw, VikViewport *vvp) +{ + tool_ed_t *t = g_new(tool_ed_t, 1); + t->vw = vw; + t->vvp = vvp; + t->vtl = NULL; + t->is_waypoint = FALSE; + return t; +} + +static void selecttool_destroy (tool_ed_t *t) +{ + g_free(t); +} + +typedef struct { + gboolean cont; + VikViewport *vvp; + GdkEventButton *event; + tool_ed_t *tool_edit; +} clicker; + +static void click_layer_selected (VikLayer *vl, clicker *ck) +{ + /* Do nothing when function call returns true; */ + /* i.e. stop on first found item */ + if ( ck->cont ) + if ( vl->visible ) + if ( vik_layer_get_interface(vl->type)->select_click ) + ck->cont = !vik_layer_get_interface(vl->type)->select_click ( vl, ck->event, ck->vvp, ck->tool_edit ); +} + +static VikLayerToolFuncStatus selecttool_click (VikLayer *vl, GdkEventButton *event, tool_ed_t *t) +{ + /* Only allow selection on primary button */ + if ( event->button == 1 ) { + /* Enable click to apply callback to potentially all track/waypoint layers */ + /* Useful as we can find things that aren't necessarily in the currently selected layer */ + GList* gl = vik_layers_panel_get_all_layers_of_type ( t->vw->viking_vlp, VIK_LAYER_TRW, FALSE ); // Don't get invisible layers + clicker ck; + ck.cont = TRUE; + ck.vvp = t->vw->viking_vvp; + ck.event = event; + ck.tool_edit = t; + g_list_foreach ( gl, (GFunc) click_layer_selected, &ck ); + g_list_free ( gl ); + + // If nothing found then deselect & redraw screen if necessary to remove the highlight + if ( ck.cont ) { + GtkTreeIter iter; + VikTreeview *vtv = vik_layers_panel_get_treeview ( t->vw->viking_vlp ); + + if ( vik_treeview_get_selected_iter ( vtv, &iter ) ) { + // Only clear if selected thing is a TrackWaypoint layer or a sublayer + gint type = vik_treeview_item_get_type ( vtv, &iter ); + if ( type == VIK_TREEVIEW_TYPE_SUBLAYER || + VIK_LAYER(vik_treeview_item_get_pointer ( vtv, &iter ))->type == VIK_LAYER_TRW ) { + + vik_treeview_item_unselect ( vtv, &iter ); + if ( vik_window_clear_highlight ( t->vw ) ) + draw_update ( t->vw ); + } + } + } + } + else if ( ( event->button == 3 ) && ( vl && ( vl->type == VIK_LAYER_TRW ) ) ) { + if ( vl->visible ) + /* Act on currently selected item to show menu */ + if ( ( t->vw->selected_track || t->vw->selected_waypoint ) && t->vw->selected_name ) + if ( vik_layer_get_interface(vl->type)->show_viewport_menu ) + vik_layer_get_interface(vl->type)->show_viewport_menu ( vl, event, t->vw->viking_vvp ); + } + + return VIK_LAYER_TOOL_ACK; +} + +static VikLayerToolFuncStatus selecttool_move (VikLayer *vl, GdkEventButton *event, tool_ed_t *t) +{ + /* Only allow selection on primary button */ + if ( event->button == 1 ) { + // Don't care about vl here + if ( t->vtl ) + if ( vik_layer_get_interface(VIK_LAYER_TRW)->select_move ) + vik_layer_get_interface(VIK_LAYER_TRW)->select_move ( vl, event, t->vvp, t ); + } + return VIK_LAYER_TOOL_ACK; +} + +static VikLayerToolFuncStatus selecttool_release (VikLayer *vl, GdkEventButton *event, tool_ed_t *t) +{ + /* Only allow selection on primary button */ + if ( event->button == 1 ) { + // Don't care about vl here + if ( t->vtl ) + if ( vik_layer_get_interface(VIK_LAYER_TRW)->select_release ) + vik_layer_get_interface(VIK_LAYER_TRW)->select_release ( (VikLayer*)t->vtl, event, t->vvp, t ); + } + return VIK_LAYER_TOOL_ACK; +} + +static VikToolInterface select_tool = + { "Select", + (VikToolConstructorFunc) selecttool_create, + (VikToolDestructorFunc) selecttool_destroy, + (VikToolActivationFunc) NULL, + (VikToolActivationFunc) NULL, + (VikToolMouseFunc) selecttool_click, + (VikToolMouseMoveFunc) selecttool_move, + (VikToolMouseFunc) selecttool_release, + (VikToolKeyFunc) NULL, + GDK_LEFT_PTR, + NULL, + NULL }; +/*** end select tool code ********************************************************/ + static void draw_pan_cb ( GtkAction *a, VikWindow *vw ) { if (!strcmp(gtk_action_get_name(a), "PanNorth")) { @@ -1198,8 +1342,9 @@ static void menu_copy_layer_cb ( GtkAction *a, VikWindow *vw ) static void menu_cut_layer_cb ( GtkAction *a, VikWindow *vw ) { - a_clipboard_copy_selected ( vw->viking_vlp ); - menu_delete_layer_cb ( a, vw ); + vik_layers_panel_cut_selected ( vw->viking_vlp ); + draw_update ( vw ); + vw->modified = TRUE; } static void menu_paste_layer_cb ( GtkAction *a, VikWindow *vw ) @@ -1441,6 +1586,9 @@ static void menu_tool_cb ( GtkAction *old, GtkAction *a, VikWindow *vw ) else if (!strcmp(gtk_action_get_name(a), "Ruler")) { vw->current_tool = TOOL_RULER; } + else if (!strcmp(gtk_action_get_name(a), "Select")) { + vw->current_tool = TOOL_SELECT; + } else { /* TODO: only enable tools from active layer */ for (layer_id=0; layer_idviking_vlp), vw->viking_vvp, filename ) ) { - case 0: + case LOAD_TYPE_READ_FAILURE: a_dialog_error_msg ( GTK_WINDOW(vw), _("The file you requested could not be opened.") ); break; - case 1: + case LOAD_TYPE_GPSBABEL_FAILURE: + a_dialog_error_msg ( GTK_WINDOW(vw), _("GPSBabel is required to load files of this type or GPSBabel encountered problems.") ); + break; + case LOAD_TYPE_VIK_SUCCESS: { GtkWidget *mode_button; /* Update UI */ @@ -1619,9 +1770,11 @@ void vik_window_open_file ( VikWindow *vw, const gchar *filename, gboolean chang g_assert ( mode_button ); gtk_check_menu_item_set_active ( GTK_CHECK_MENU_ITEM(mode_button),vik_viewport_get_draw_highlight (vw->viking_vvp) ); } + //case LOAD_TYPE_OTHER_SUCCESS: default: update_recently_used_document(filename); draw_update ( vw ); + break; } } static void load_file ( GtkAction *a, VikWindow *vw ) @@ -1745,6 +1898,13 @@ static void acquire_from_google ( GtkAction *a, VikWindow *vw ) a_acquire(vw, vw->viking_vlp, vw->viking_vvp, &vik_datasource_google_interface ); } +#ifdef VIK_CONFIG_OPENSTREETMAP +static void acquire_from_osm ( GtkAction *a, VikWindow *vw ) +{ + a_acquire(vw, vw->viking_vlp, vw->viking_vvp, &vik_datasource_osm_interface ); +} +#endif + #ifdef VIK_CONFIG_GEOCACHES static void acquire_from_gc ( GtkAction *a, VikWindow *vw ) { @@ -2312,6 +2472,9 @@ static GtkActionEntry entries[] = { { "Acquire", NULL, N_("A_cquire"), 0, 0, 0 }, { "AcquireGPS", NULL, N_("From _GPS..."), NULL, N_("Transfer data from a GPS device"), (GCallback)acquire_from_gps }, { "AcquireGoogle", NULL, N_("Google _Directions..."), NULL, N_("Get driving directions from Google"), (GCallback)acquire_from_google }, +#ifdef VIK_CONFIG_OPENSTREETMAP + { "AcquireOSM", NULL, N_("_OSM Traces..."), NULL, N_("Get traces from OpenStreetMap"), (GCallback)acquire_from_osm }, +#endif #ifdef VIK_CONFIG_GEOCACHES { "AcquireGC", NULL, N_("Geo_caches..."), NULL, N_("Get Geocaches from geocaching.com"), (GCallback)acquire_from_gc }, #endif @@ -2386,7 +2549,8 @@ static GtkRadioActionEntry mode_entries[] = { static GtkRadioActionEntry tool_entries[] = { { "Pan", "vik-icon-pan", N_("_Pan"), "P", N_("Pan Tool"), 0 }, { "Zoom", "vik-icon-zoom", N_("_Zoom"), "Z", N_("Zoom Tool"), 1 }, - { "Ruler", "vik-icon-ruler", N_("_Ruler"), "R", N_("Ruler Tool"), 2 } + { "Ruler", "vik-icon-ruler", N_("_Ruler"), "R", N_("Ruler Tool"), 2 }, + { "Select", "vik-icon-select", N_("_Select"), "S", N_("Select Tool"), 3 } }; static GtkToggleActionEntry toggle_entries[] = { @@ -2419,6 +2583,7 @@ static void window_create_ui( VikWindow *window ) toolbox_add_tool(window->vt, &ruler_tool, TOOL_LAYER_TYPE_NONE); toolbox_add_tool(window->vt, &zoom_tool, TOOL_LAYER_TYPE_NONE); toolbox_add_tool(window->vt, &pan_tool, TOOL_LAYER_TYPE_NONE); + toolbox_add_tool(window->vt, &select_tool, TOOL_LAYER_TYPE_NONE); error = NULL; if (!(mid = gtk_ui_manager_add_ui_from_string (uim, menu_xml, -1, &error))) { @@ -2524,7 +2689,7 @@ static struct { gchar *stock_id; } stock_icons[] = { { &begintr_18_pixbuf, "Begin Track" }, - { &iscissors_18_pixbuf, "Magic Scissors" }, + { &route_finder_18_pixbuf, "Route Finder" }, { &mover_22_pixbuf, "vik-icon-pan" }, { &demdl_18_pixbuf, "DEM Download/Import" }, { &showpic_18_pixbuf, "Show Picture" }, @@ -2534,6 +2699,7 @@ static struct { { &edwp_18_pixbuf, "Edit Waypoint" }, { &zoom_18_pixbuf, "vik-icon-zoom" }, { &ruler_18_pixbuf, "vik-icon-ruler" }, + { &select_18_pixbuf, "vik-icon-select" }, { &geozoom_18_pixbuf, "Georef Zoom Tool" }, { &geomove_18_pixbuf, "Georef Move Map" }, { &mapdl_18_pixbuf, "Maps Download" },