X-Git-Url: https://git.street.me.uk/andy/viking.git/blobdiff_plain/0c1044e93484981566c54b80120ac1d07ad64c38..5e1088096edeee2984e7135b618a503799369fa5:/src/vikmapslayer.c diff --git a/src/vikmapslayer.c b/src/vikmapslayer.c index 1cfd13a9..e09d54d9 100644 --- a/src/vikmapslayer.c +++ b/src/vikmapslayer.c @@ -21,6 +21,10 @@ * */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #define MAX_SHRINKFACTOR 8.0000001 /* zoom 1 viewing 8-tiles */ #define MIN_SHRINKFACTOR 0.0312499 /* zoom 32 viewing 1-tiles */ @@ -28,9 +32,17 @@ #include #include -#include +#include +#include +#include + +#ifdef HAVE_STRING_H #include +#endif +#ifdef HAVE_MATH_H #include +#endif + #include "globals.h" #include "coords.h" #include "vikcoord.h" @@ -38,11 +50,10 @@ #include "vikviewport.h" #include "viklayer.h" #include "vikmapslayer.h" -#include "vikmapslayer_pixmap.h" +#ifdef HAVE_UNISTD_H #include -#include -#include +#endif #include "mapcache.h" /* only for dialog.h -- ugh */ @@ -58,6 +69,8 @@ #include "mapcoord.h" #include "terraserver.h" +#include "icons/icons.h" + /****** MAP TYPES ******/ static GList *__map_types = NULL; @@ -72,7 +85,7 @@ static GList *params_maptypes_ids = NULL; /******** MAPZOOMS *********/ -static gchar *params_mapzooms[] = { "Use Viking Zoom Level", "0.25", "1", "2", "4", "8", "16", "32", "64", "128", "256", "512", "1024", "USGS 10k", "USGS 24k", "USGS 25k", "USGS 50k", "USGS 100k", "USGS 200k", "USGS 250k", NULL }; +static gchar *params_mapzooms[] = { N_("Use Viking Zoom Level"), "0.25", "1", "2", "4", "8", "16", "32", "64", "128", "256", "512", "1024", "USGS 10k", "USGS 24k", "USGS 25k", "USGS 50k", "USGS 100k", "USGS 200k", "USGS 250k", NULL }; static gdouble __mapzooms_x[] = { 0.0, 0.25, 1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0, 1024.0, 1.016, 2.4384, 2.54, 5.08, 10.16, 20.32, 25.4 }; static gdouble __mapzooms_y[] = { 0.0, 0.25, 1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0, 1024.0, 1.016, 2.4384, 2.54, 5.08, 10.16, 20.32, 25.4 }; @@ -81,7 +94,6 @@ static gdouble __mapzooms_y[] = { 0.0, 0.25, 1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64. /**************************/ -static VikMapsLayer *maps_layer_copy ( VikMapsLayer *vml, VikViewport *vvp ); static void maps_layer_post_read (VikLayer *vl, VikViewport *vp, gboolean from_file); static void maps_layer_marshall( VikMapsLayer *vml, guint8 **data, gint *len ); static VikMapsLayer *maps_layer_unmarshall( guint8 *data, gint len, VikViewport *vvp ); @@ -104,23 +116,24 @@ static VikLayerParamScale params_scales[] = { }; VikLayerParam maps_layer_params[] = { - { "mode", VIK_LAYER_PARAM_UINT, VIK_LAYER_GROUP_NONE, "Map Type:", VIK_LAYER_WIDGET_RADIOGROUP, NULL, NULL }, - { "directory", VIK_LAYER_PARAM_STRING, VIK_LAYER_GROUP_NONE, "Maps Directory (Optional):", VIK_LAYER_WIDGET_FILEENTRY }, - { "alpha", VIK_LAYER_PARAM_UINT, VIK_LAYER_GROUP_NONE, "Alpha:", VIK_LAYER_WIDGET_HSCALE, params_scales }, - { "autodownload", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_GROUP_NONE, "Autodownload maps:", VIK_LAYER_WIDGET_CHECKBUTTON }, - { "mapzoom", VIK_LAYER_PARAM_UINT, VIK_LAYER_GROUP_NONE, "Zoom Level:", VIK_LAYER_WIDGET_COMBOBOX, params_mapzooms }, + { "mode", VIK_LAYER_PARAM_UINT, VIK_LAYER_GROUP_NONE, N_("Map Type:"), VIK_LAYER_WIDGET_RADIOGROUP, NULL, NULL }, + { "directory", VIK_LAYER_PARAM_STRING, VIK_LAYER_GROUP_NONE, N_("Maps Directory:"), VIK_LAYER_WIDGET_FOLDERENTRY }, + { "alpha", VIK_LAYER_PARAM_UINT, VIK_LAYER_GROUP_NONE, N_("Alpha:"), VIK_LAYER_WIDGET_HSCALE, params_scales }, + { "autodownload", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_GROUP_NONE, N_("Autodownload maps:"), VIK_LAYER_WIDGET_CHECKBUTTON }, + { "mapzoom", VIK_LAYER_PARAM_UINT, VIK_LAYER_GROUP_NONE, N_("Zoom Level:"), VIK_LAYER_WIDGET_COMBOBOX, params_mapzooms }, }; enum { PARAM_MAPTYPE=0, PARAM_CACHE_DIR, PARAM_ALPHA, PARAM_AUTODOWNLOAD, PARAM_MAPZOOM, NUM_PARAMS }; static VikToolInterface maps_tools[] = { - { "Maps Download", (VikToolConstructorFunc) maps_layer_download_create, NULL, NULL, NULL, - (VikToolMouseFunc) maps_layer_download_click, NULL, (VikToolMouseFunc) maps_layer_download_release }, + { N_("Maps Download"), (VikToolConstructorFunc) maps_layer_download_create, NULL, NULL, NULL, + (VikToolMouseFunc) maps_layer_download_click, NULL, (VikToolMouseFunc) maps_layer_download_release, + (VikToolKeyFunc) NULL, GDK_CURSOR_IS_PIXMAP, &cursor_mapdl_pixbuf }, }; VikLayerInterface vik_maps_layer_interface = { - "Map", - &mapslayer_pixbuf, + N_("Map"), + &vikmapslayer_pixbuf, maps_tools, sizeof(maps_tools) / sizeof(maps_tools[0]), @@ -134,7 +147,7 @@ VikLayerInterface vik_maps_layer_interface = { (VikLayerFuncCreate) maps_layer_new, (VikLayerFuncRealize) NULL, - maps_layer_post_read, + (VikLayerFuncPostRead) maps_layer_post_read, (VikLayerFuncFree) maps_layer_free, (VikLayerFuncProperties) NULL, @@ -150,7 +163,6 @@ VikLayerInterface vik_maps_layer_interface = { (VikLayerFuncSublayerRenameRequest) NULL, (VikLayerFuncSublayerToggleVisible) NULL, - (VikLayerFuncCopy) maps_layer_copy, (VikLayerFuncMarshall) maps_layer_marshall, (VikLayerFuncUnmarshall) maps_layer_unmarshall, @@ -187,7 +199,11 @@ struct _VikMapsLayer { VikViewport *redownload_vvp; }; -enum { REDOWNLOAD_NONE = 0, REDOWNLOAD_BAD, REDOWNLOAD_ALL, DOWNLOAD_OR_REFRESH }; +enum { REDOWNLOAD_NONE = 0, /* download only missing maps */ + REDOWNLOAD_BAD, /* download missing and bad maps */ + REDOWNLOAD_NEW, /* download missing maps that are newer on server only */ + REDOWNLOAD_ALL, /* download all maps */ + DOWNLOAD_OR_REFRESH }; /* download missing maps and refresh cache */ /****************************************/ @@ -204,7 +220,7 @@ void maps_layer_register_type ( const char *label, guint id, VikMapsLayer_MapTyp params_maptypes = g_list_append(params_maptypes, g_strdup(label)); /* Add the id */ - params_maptypes_ids = g_list_append(params_maptypes_ids, (gpointer)id); + params_maptypes_ids = g_list_append(params_maptypes_ids, GUINT_TO_POINTER (id)); /* We have to clone */ VikMapsLayer_MapType *clone = g_memdup(map_type, sizeof(VikMapsLayer_MapType)); @@ -242,14 +258,17 @@ gchar *vik_maps_layer_get_map_label(VikMapsLayer *vml) /****************************************/ #define DIRSTRUCTURE "%st%ds%dz%d" G_DIR_SEPARATOR_S "%d" G_DIR_SEPARATOR_S "%d" +#define MAPS_CACHE_DIR maps_layer_default_dir() + #ifdef WINDOWS -#define MAPS_CACHE_DIR "C:\\VIKING-MAPS\\" +#include +#define GLOBAL_MAPS_DIR "C:\\VIKING-MAPS\\" +#define LOCAL_MAPS_DIR "VIKING-MAPS" #else /* POSIX */ - #include - -#define MAPS_CACHE_DIR maps_layer_default_dir() #define GLOBAL_MAPS_DIR "/var/cache/maps/" +#define LOCAL_MAPS_DIR ".viking-maps" +#endif gchar *maps_layer_default_dir () { @@ -260,16 +279,16 @@ gchar *maps_layer_default_dir () const gchar *mapdir = g_getenv("VIKING_MAPS"); if ( mapdir ) { defaultdir = g_strdup ( mapdir ); - } else if ( access ( GLOBAL_MAPS_DIR, W_OK ) == 0 ) { + } else if ( g_access ( GLOBAL_MAPS_DIR, W_OK ) == 0 ) { defaultdir = g_strdup ( GLOBAL_MAPS_DIR ); } else { - const gchar *home = g_getenv("HOME"); - if (!home || access(home, W_OK)) + const gchar *home = g_get_home_dir(); + if (!home || g_access(home, W_OK)) home = g_get_home_dir (); if ( home ) - defaultdir = g_build_filename ( home, ".viking-maps", NULL ); + defaultdir = g_build_filename ( home, LOCAL_MAPS_DIR, NULL ); else - defaultdir = g_strdup ( ".viking-maps" ); + defaultdir = g_strdup ( LOCAL_MAPS_DIR ); } if (defaultdir && (defaultdir[strlen(defaultdir)-1] != G_DIR_SEPARATOR)) { @@ -283,17 +302,11 @@ gchar *maps_layer_default_dir () return defaultdir; } -#endif - static void maps_layer_mkdir_if_default_dir ( VikMapsLayer *vml ) { - if ( vml->cache_dir && strcmp ( vml->cache_dir, MAPS_CACHE_DIR ) == 0 && access ( vml->cache_dir, F_OK ) != 0 ) + if ( vml->cache_dir && strcmp ( vml->cache_dir, MAPS_CACHE_DIR ) == 0 && g_file_test ( vml->cache_dir, G_FILE_TEST_EXISTS ) == FALSE ) { -#ifdef WINDOWS - mkdir ( vml->cache_dir ); -#else - mkdir ( vml->cache_dir, 0777 ); -#endif + g_mkdir ( vml->cache_dir, 0777 ); } } @@ -376,7 +389,7 @@ static gboolean maps_layer_set_param ( VikMapsLayer *vml, guint16 id, VikLayerPa case PARAM_CACHE_DIR: maps_layer_set_cache_dir ( vml, data.s ); break; case PARAM_MAPTYPE: { gint maptype = map_uniq_id_to_index(data.u); - if ( maptype == NUM_MAP_TYPES ) g_warning("Unknown map type"); + if ( maptype == NUM_MAP_TYPES ) g_warning(_("Unknown map type")); else vml->maptype = maptype; break; } @@ -386,7 +399,7 @@ static gboolean maps_layer_set_param ( VikMapsLayer *vml, guint16 id, VikLayerPa vml->mapzoom_id = data.u; vml->xmapzoom = __mapzooms_x [data.u]; vml->ymapzoom = __mapzooms_y [data.u]; - }else g_warning ("Unknown Map Zoom"); break; + }else g_warning (_("Unknown Map Zoom")); break; } return TRUE; } @@ -396,7 +409,7 @@ static VikLayerParamData maps_layer_get_param ( VikMapsLayer *vml, guint16 id ) VikLayerParamData rv; switch ( id ) { - case PARAM_CACHE_DIR: rv.s = (vml->cache_dir && strcmp(vml->cache_dir, MAPS_CACHE_DIR) != 0) ? vml->cache_dir : ""; break; + case PARAM_CACHE_DIR: rv.s = vml->cache_dir ? vml->cache_dir : ""; break; case PARAM_MAPTYPE: rv.u = map_index_to_uniq_id ( vml->maptype ); break; case PARAM_ALPHA: rv.u = vml->alpha; break; case PARAM_AUTODOWNLOAD: rv.u = vml->autodownload; break; @@ -455,22 +468,13 @@ static void maps_layer_post_read (VikLayer *vl, VikViewport *vp, gboolean from_f map_type = MAPS_LAYER_NTH_TYPE(vml->maptype); if (map_type->drawmode != vp_drawmode) { const gchar *drawmode_name = vik_viewport_get_drawmode_name (VIK_VIEWPORT(vp), map_type->drawmode); - gchar *msg = g_strdup_printf("New map cannot be displayed in the current drawmode.\nSelect \"%s\" from View menu to view it.", drawmode_name); + gchar *msg = g_strdup_printf(_("New map cannot be displayed in the current drawmode.\nSelect \"%s\" from View menu to view it."), drawmode_name); a_dialog_warning_msg ( VIK_GTK_WINDOW_FROM_LAYER(vml), msg ); g_free(msg); } } } -static VikMapsLayer *maps_layer_copy ( VikMapsLayer *vml, VikViewport *vvp ) -{ - VikMapsLayer *rv = maps_layer_new ( vvp ); - *rv = *vml; - rv->cache_dir = g_strdup(rv->cache_dir); - VIK_LAYER(rv)->name = NULL; - return rv; -} - static void maps_layer_marshall( VikMapsLayer *vml, guint8 **data, gint *len ) { vik_layer_marshall_params ( VIK_LAYER(vml), data, len ); @@ -516,7 +520,7 @@ static GdkPixbuf *pixbuf_shrink ( GdkPixbuf *pixbuf, gdouble xshrinkfactor, gdou { GdkPixbuf *tmp; guint16 width = gdk_pixbuf_get_width(pixbuf), height = gdk_pixbuf_get_height(pixbuf); - tmp = gdk_pixbuf_scale_simple(pixbuf, ceil(width * xshrinkfactor), ceil(height * yshrinkfactor), GDK_INTERP_BILINEAR); + tmp = gdk_pixbuf_scale_simple(pixbuf, ceil(width * xshrinkfactor), ceil(height * yshrinkfactor), GDK_INTERP_NEAREST); g_object_unref ( G_OBJECT(pixbuf) ); return tmp; } @@ -533,7 +537,7 @@ static GdkPixbuf *get_pixbuf( VikMapsLayer *vml, gint mode, MapCoord *mapcoord, g_snprintf ( filename_buf, buf_len, DIRSTRUCTURE, vml->cache_dir, mode, mapcoord->scale, mapcoord->z, mapcoord->x, mapcoord->y ); - if ( access ( filename_buf, R_OK ) == 0) { + if ( g_file_test ( filename_buf, G_FILE_TEST_EXISTS ) == TRUE) { { GError *gx = NULL; pixbuf = gdk_pixbuf_new_from_file ( filename_buf, &gx ); @@ -541,7 +545,7 @@ static GdkPixbuf *get_pixbuf( VikMapsLayer *vml, gint mode, MapCoord *mapcoord, if (gx) { if ( gx->domain != GDK_PIXBUF_ERROR || gx->code != GDK_PIXBUF_ERROR_CORRUPT_IMAGE ) - g_warning ( "Couldn't open image file: %s", gx->message ); + g_warning ( _("Couldn't open image file: %s"), gx->message ); g_error_free ( gx ); if ( pixbuf ) @@ -606,7 +610,7 @@ static void maps_layer_draw_section ( VikMapsLayer *vml, VikViewport *vvp, VikCo if ( xshrinkfactor > REAL_MIN_SHRINKFACTOR && yshrinkfactor > REAL_MIN_SHRINKFACTOR ) existence_only = TRUE; else { - g_warning ( "Cowardly refusing to draw tiles or existence of tiles beyond %d zoom out factor", (int)( 1.0/REAL_MIN_SHRINKFACTOR)); + g_warning ( _("Cowardly refusing to draw tiles or existence of tiles beyond %d zoom out factor"), (int)( 1.0/REAL_MIN_SHRINKFACTOR)); return; } } @@ -634,7 +638,12 @@ static void maps_layer_draw_section ( VikMapsLayer *vml, VikViewport *vvp, VikCo #ifdef DEBUG fputs(stderr, "DEBUG: Starting autodownload\n"); #endif - start_download_thread ( vml, vvp, ul, br, REDOWNLOAD_NONE ); + if ( map_type->options != NULL && map_type->options->check_file_server_time ) + // Try to download newer tiles + start_download_thread ( vml, vvp, ul, br, REDOWNLOAD_NEW ); + else + // Download only missing tiles + start_download_thread ( vml, vvp, ul, br, REDOWNLOAD_NONE ); } if ( map_type->tilesize_x == 0 && !existence_only ) { @@ -690,13 +699,31 @@ static void maps_layer_draw_section ( VikMapsLayer *vml, VikViewport *vvp, VikCo g_snprintf ( path_buf, max_path_len, DIRSTRUCTURE, vml->cache_dir, mode, ulm.scale, ulm.z, ulm.x, ulm.y ); - if ( access ( path_buf, F_OK ) == 0 ) { + if ( g_file_test ( path_buf, G_FILE_TEST_EXISTS ) == TRUE ) { vik_viewport_draw_line ( vvp, black_gc, xx+tilesize_x_ceil, yy, xx, yy+tilesize_y_ceil ); } } else { pixbuf = get_pixbuf ( vml, mode, &ulm, path_buf, max_path_len, xshrinkfactor, yshrinkfactor ); if ( pixbuf ) vik_viewport_draw_pixbuf ( vvp, pixbuf, 0, 0, xx, yy, tilesize_x_ceil, tilesize_y_ceil ); + else { + /* retry with bigger shrinkfactor */ + int scale_inc; + for (scale_inc = 1; scale_inc < 4; scale_inc ++) { + int scale_factor = 1 << scale_inc; /* 2^scale_inc */ + MapCoord ulm2 = ulm; + ulm2.x = ulm.x / scale_factor; + ulm2.y = ulm.y / scale_factor; + ulm2.scale = ulm.scale + scale_inc; + pixbuf = get_pixbuf ( vml, mode, &ulm2, path_buf, max_path_len, xshrinkfactor * scale_factor, yshrinkfactor * scale_factor ); + if ( pixbuf ) { + gint src_x = (ulm.x % scale_factor) * tilesize_x_ceil; + gint src_y = (ulm.y % scale_factor) * tilesize_y_ceil; + vik_viewport_draw_pixbuf ( vvp, pixbuf, src_x, src_y, xx, yy, tilesize_x_ceil, tilesize_y_ceil ); + break; + } + } + } } yy += tilesize_y; @@ -774,7 +801,7 @@ static void weak_ref_cb(gpointer ptr, GObject * dead_vml) g_mutex_unlock(mdi->mutex); } -static void map_download_thread ( MapDownloadInfo *mdi, gpointer threaddata ) +static int map_download_thread ( MapDownloadInfo *mdi, gpointer threaddata ) { guint donemaps = 0; gint x, y; @@ -789,25 +816,27 @@ static void map_download_thread ( MapDownloadInfo *mdi, gpointer threaddata ) mdi->mapcoord.scale, mdi->mapcoord.z, x, y ); donemaps++; - a_background_thread_progress ( threaddata, ((gdouble)donemaps) / mdi->mapstoget ); /* this also calls testcancel */ + int res = a_background_thread_progress ( threaddata, ((gdouble)donemaps) / mdi->mapstoget ); /* this also calls testcancel */ + if (res != 0) + return -1; if ( mdi->redownload == REDOWNLOAD_ALL) - remove ( mdi->filename_buf ); + g_remove ( mdi->filename_buf ); - else if ( (mdi->redownload == REDOWNLOAD_BAD) && (access ( mdi->filename_buf, F_OK ) == 0) ) + else if ( (mdi->redownload == REDOWNLOAD_BAD) && (g_file_test ( mdi->filename_buf, G_FILE_TEST_EXISTS ) == TRUE) ) { /* see if this one is bad or what */ GError *gx = NULL; GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file ( mdi->filename_buf, &gx ); if (gx || (!pixbuf)) - remove ( mdi->filename_buf ); + g_remove ( mdi->filename_buf ); if ( pixbuf ) g_object_unref ( pixbuf ); if ( gx ) g_error_free ( gx ); } - if ( access ( mdi->filename_buf, F_OK ) != 0 ) + if ( g_file_test ( mdi->filename_buf, G_FILE_TEST_EXISTS ) == FALSE ) { need_download = TRUE; if (( mdi->redownload != REDOWNLOAD_NONE ) && @@ -815,6 +844,9 @@ static void map_download_thread ( MapDownloadInfo *mdi, gpointer threaddata ) remove_mem_cache = TRUE; } else if ( mdi->redownload == DOWNLOAD_OR_REFRESH ) { remove_mem_cache = TRUE; + } else if ( mdi->redownload == REDOWNLOAD_NEW) { + need_download = TRUE; + remove_mem_cache = TRUE; } else continue; @@ -843,6 +875,7 @@ static void map_download_thread ( MapDownloadInfo *mdi, gpointer threaddata ) if (mdi->map_layer_alive) g_object_weak_unref(G_OBJECT(mdi->vml), weak_ref_cb, mdi); g_mutex_unlock(mdi->mutex); + return 0; } static void mdi_cancel_cleanup ( MapDownloadInfo *mdi ) @@ -852,9 +885,9 @@ static void mdi_cancel_cleanup ( MapDownloadInfo *mdi ) g_snprintf ( mdi->filename_buf, mdi->maxlen, DIRSTRUCTURE, mdi->cache_dir, MAPS_LAYER_NTH_TYPE(mdi->maptype)->uniq_id, mdi->mapcoord.scale, mdi->mapcoord.z, mdi->mapcoord.x, mdi->mapcoord.y ); - if ( access ( mdi->filename_buf, F_OK ) == 0) + if ( g_file_test ( mdi->filename_buf, G_FILE_TEST_EXISTS ) == TRUE) { - remove ( mdi->filename_buf ); + g_remove ( mdi->filename_buf ); } } } @@ -905,7 +938,7 @@ static void start_download_thread ( VikMapsLayer *vml, VikViewport *vvp, const V g_snprintf ( mdi->filename_buf, mdi->maxlen, DIRSTRUCTURE, vml->cache_dir, map_type->uniq_id, ulm.scale, ulm.z, a, b ); - if ( access ( mdi->filename_buf, F_OK ) != 0) + if ( g_file_test ( mdi->filename_buf, G_FILE_TEST_EXISTS ) == FALSE ) mdi->mapstoget++; } } @@ -915,8 +948,22 @@ static void start_download_thread ( VikMapsLayer *vml, VikViewport *vvp, const V if ( mdi->mapstoget ) { - gchar *tmp = g_strdup_printf ( "%s %s%d %s %s...", redownload ? "Redownloading" : "Downloading", redownload == REDOWNLOAD_BAD ? "up to " : "", mdi->mapstoget, MAPS_LAYER_NTH_LABEL(vml->maptype), (mdi->mapstoget == 1) ? "map" : "maps" ); + const gchar *tmp_str; + gchar *tmp; + if (redownload) + { + if (redownload == REDOWNLOAD_BAD) + tmp_str = ngettext("Redownloading up to %d %s map...", "Redownloading up to %d %s maps...", mdi->mapstoget); + else + tmp_str = ngettext("Redownloading %d %s map...", "Redownloading %d %s maps...", mdi->mapstoget); + } + else + { + tmp_str = ngettext("Downloading %d %s map...", "Downloading %d %s maps...", mdi->mapstoget); + } + tmp = g_strdup_printf ( tmp_str, mdi->mapstoget, MAPS_LAYER_NTH_LABEL(vml->maptype)); + g_object_weak_ref(G_OBJECT(mdi->vml), weak_ref_cb, mdi); /* launch the thread */ a_background_thread ( VIK_GTK_WINDOW_FROM_LAYER(vml), /* parent window */ @@ -940,7 +987,7 @@ void maps_layer_download_section_without_redraw( VikMapsLayer *vml, VikViewport if (!map_type->coord_to_mapcoord(ul, zoom, zoom, &ulm) || !map_type->coord_to_mapcoord(br, zoom, zoom, &brm)) { - g_warning("%s() coord_to_mapcoord() failed\n", __PRETTY_FUNCTION__); + g_warning("%s() coord_to_mapcoord() failed", __PRETTY_FUNCTION__); return; } @@ -974,7 +1021,7 @@ void maps_layer_download_section_without_redraw( VikMapsLayer *vml, VikViewport g_snprintf ( mdi->filename_buf, mdi->maxlen, DIRSTRUCTURE, vml->cache_dir, map_type->uniq_id, ulm.scale, ulm.z, i, j ); - if ( access ( mdi->filename_buf, F_OK ) != 0) + if ( g_file_test ( mdi->filename_buf, G_FILE_TEST_EXISTS ) == FALSE ) mdi->mapstoget++; } } @@ -982,7 +1029,12 @@ void maps_layer_download_section_without_redraw( VikMapsLayer *vml, VikViewport mdi->mapcoord.x = mdi->mapcoord.y = 0; /* for cleanup -- no current map */ if (mdi->mapstoget) { - gchar *tmp = g_strdup_printf ( "%s %d %s %s...", "Downloading", mdi->mapstoget, MAPS_LAYER_NTH_LABEL(vml->maptype), (mdi->mapstoget == 1) ? "map" : "maps" ); + gchar *tmp; + const gchar *fmt; + fmt = ngettext("Downloading %d %s map...", + "Downloading %d %s maps...", + mdi->mapstoget); + tmp = g_strdup_printf ( fmt, mdi->mapstoget, MAPS_LAYER_NTH_LABEL(vml->maptype) ); g_object_weak_ref(G_OBJECT(mdi->vml), weak_ref_cb, mdi); /* launch the thread */ @@ -1003,11 +1055,17 @@ static void maps_layer_redownload_bad ( VikMapsLayer *vml ) { start_download_thread ( vml, vml->redownload_vvp, &(vml->redownload_ul), &(vml->redownload_br), REDOWNLOAD_BAD ); } + static void maps_layer_redownload_all ( VikMapsLayer *vml ) { start_download_thread ( vml, vml->redownload_vvp, &(vml->redownload_ul), &(vml->redownload_br), REDOWNLOAD_ALL ); } +static void maps_layer_redownload_new ( VikMapsLayer *vml ) +{ + start_download_thread ( vml, vml->redownload_vvp, &(vml->redownload_ul), &(vml->redownload_br), REDOWNLOAD_NEW ); +} + static gboolean maps_layer_download_release ( VikMapsLayer *vml, GdkEventButton *event, VikViewport *vvp ) { if (!vml || vml->vl.type != VIK_LAYER_MAPS) @@ -1036,11 +1094,15 @@ static gboolean maps_layer_download_release ( VikMapsLayer *vml, GdkEventButton GtkWidget *item; vml->dl_right_click_menu = GTK_MENU ( gtk_menu_new () ); - item = gtk_menu_item_new_with_label ( "Redownload bad map(s)" ); + item = gtk_menu_item_new_with_label ( _("Redownload bad map(s)") ); g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(maps_layer_redownload_bad), vml ); gtk_menu_shell_append ( GTK_MENU_SHELL(vml->dl_right_click_menu), item ); - item = gtk_menu_item_new_with_label ( "Redownload all map(s)" ); + item = gtk_menu_item_new_with_label ( _("Redownload new map(s)") ); + g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(maps_layer_redownload_new), vml ); + gtk_menu_shell_append ( GTK_MENU_SHELL(vml->dl_right_click_menu), item ); + + item = gtk_menu_item_new_with_label ( _("Redownload all map(s)") ); g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(maps_layer_redownload_all), vml ); gtk_menu_shell_append ( GTK_MENU_SHELL(vml->dl_right_click_menu), item ); } @@ -1120,20 +1182,25 @@ static void download_onscreen_maps ( gpointer vml_vvp[2], gint redownload ) start_download_thread ( vml, vvp, &ul, &br, redownload ); else if (map_type->drawmode != vp_drawmode) { const gchar *drawmode_name = vik_viewport_get_drawmode_name (vvp, map_type->drawmode); - gchar *err = g_strdup_printf("Wrong drawmode for this map.\nSelect \"%s\" from View menu and try again.", drawmode_name); + gchar *err = g_strdup_printf(_("Wrong drawmode for this map.\nSelect \"%s\" from View menu and try again."), _(drawmode_name)); a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_LAYER(vml), err ); g_free(err); } else - a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_LAYER(vml), "Wrong zoom level for this map." ); + a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_LAYER(vml), _("Wrong zoom level for this map.") ); } -static void maps_layer_download_onscreen_maps ( gpointer vml_vvp[2] ) +static void maps_layer_download_missing_onscreen_maps ( gpointer vml_vvp[2] ) { download_onscreen_maps( vml_vvp, REDOWNLOAD_NONE); } +static void maps_layer_download_new_onscreen_maps ( gpointer vml_vvp[2] ) +{ + download_onscreen_maps( vml_vvp, REDOWNLOAD_NEW); +} + static void maps_layer_redownload_all_onscreen_maps ( gpointer vml_vvp[2] ) { download_onscreen_maps( vml_vvp, REDOWNLOAD_ALL); @@ -1150,12 +1217,21 @@ static void maps_layer_add_menu_items ( VikMapsLayer *vml, GtkMenu *menu, VikLay gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item ); gtk_widget_show ( item ); - item = gtk_menu_item_new_with_label ( "Download Onscreen Maps" ); - g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(maps_layer_download_onscreen_maps), pass_along ); + item = gtk_menu_item_new_with_label ( _("Download missing Onscreen Maps") ); + g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(maps_layer_download_missing_onscreen_maps), pass_along ); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); gtk_widget_show ( item ); - item = gtk_menu_item_new_with_label ( "Refresh Onscreen Tiles" ); + if ( MAPS_LAYER_NTH_TYPE(vml->maptype)->options != NULL && + MAPS_LAYER_NTH_TYPE(vml->maptype)->options->check_file_server_time ) { + item = gtk_menu_item_new_with_label ( _("Download new Onscreen Maps from server") ); + g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(maps_layer_download_new_onscreen_maps), pass_along ); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + gtk_widget_show ( item ); + } + + /* TODO Add GTK_STOCK_REFRESH icon */ + item = gtk_menu_item_new_with_label ( _("Refresh Onscreen Tiles") ); g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(maps_layer_redownload_all_onscreen_maps), pass_along ); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); gtk_widget_show ( item );