From 6a4a29aa76af1b8ed8695cf8ed16c186b571d9e1 Mon Sep 17 00:00:00 2001 From: Jocelyn Jaubert Date: Sat, 21 Feb 2009 19:47:54 +0100 Subject: [PATCH] Add option to download only maps that are more recent on server --- src/babel.c | 2 +- src/curl_download.c | 86 +++++++++++++++++++++++++++++--------------- src/curl_download.h | 4 +-- src/download.c | 45 ++++++++++++++--------- src/download.h | 12 +++++++ src/expedia.c | 4 +-- src/geonamessearch.c | 2 +- src/googlesearch.c | 4 +-- src/osm.c | 13 +++---- src/terraserver.c | 8 ++--- src/vikdemlayer.c | 2 +- src/vikmapslayer.c | 28 ++++++++++++--- src/vikmapslayer.h | 2 ++ 13 files changed, 144 insertions(+), 68 deletions(-) diff --git a/src/babel.c b/src/babel.c index 50c90f74..79a1ebee 100644 --- a/src/babel.c +++ b/src/babel.c @@ -276,7 +276,7 @@ gboolean a_babel_convert_from_shellcommand ( VikTrwLayer *vt, const char *input_ gboolean a_babel_convert_from_url ( VikTrwLayer *vt, const char *url, const char *input_type, BabelStatusFunc cb, gpointer user_data ) { - static DownloadOptions options = {NULL, 0, a_check_kml_file}; + static DownloadOptions options = { FALSE, NULL, 0, a_check_kml_file}; gint fd_src; int fetch_ret; gboolean ret = FALSE; diff --git a/src/curl_download.c b/src/curl_download.c index f230dca0..6435f2bc 100644 --- a/src/curl_download.c +++ b/src/curl_download.c @@ -25,6 +25,10 @@ #include +#ifdef HAVE_UNISTD_H +#include +#endif + #include #include #include @@ -117,7 +121,7 @@ void curl_download_init() curl_download_user_agent = g_strdup_printf ("%s/%s %s", PACKAGE, VERSION, curl_version()); } -int curl_download_uri ( const char *uri, FILE *f, DownloadOptions *options ) +int curl_download_uri ( const char *uri, FILE *f, DownloadOptions *options, time_t time_condition ) { CURL *curl; CURLcode res = CURLE_FAILED_INIT; @@ -126,43 +130,69 @@ int curl_download_uri ( const char *uri, FILE *f, DownloadOptions *options ) g_debug("%s: uri=%s", __PRETTY_FUNCTION__, uri); curl = curl_easy_init (); - if ( curl ) - { - if (vik_verbose) - curl_easy_setopt ( curl, CURLOPT_VERBOSE, 1 ); - curl_easy_setopt ( curl, CURLOPT_URL, uri ); - curl_easy_setopt ( curl, CURLOPT_WRITEDATA, f ); - curl_easy_setopt ( curl, CURLOPT_WRITEFUNCTION, curl_write_func); - curl_easy_setopt ( curl, CURLOPT_NOPROGRESS, 0 ); - curl_easy_setopt ( curl, CURLOPT_PROGRESSDATA, NULL ); - curl_easy_setopt ( curl, CURLOPT_PROGRESSFUNCTION, curl_progress_func); - if (options != NULL) { - if(options->referer != NULL) - curl_easy_setopt ( curl, CURLOPT_REFERER, options->referer); - if(options->follow_location != 0) { - curl_easy_setopt ( curl, CURLOPT_FOLLOWLOCATION, 1); - curl_easy_setopt ( curl, CURLOPT_MAXREDIRS, options->follow_location); - } - } - curl_easy_setopt ( curl, CURLOPT_USERAGENT, curl_download_user_agent ); - if ((cookie_file = get_cookie_file(FALSE)) != NULL) - curl_easy_setopt(curl, CURLOPT_COOKIEFILE, cookie_file); - res = curl_easy_perform ( curl ); - curl_easy_cleanup ( curl ); + if ( !curl ) { + return DOWNLOAD_ERROR; + } + if (vik_verbose) + curl_easy_setopt ( curl, CURLOPT_VERBOSE, 1 ); + curl_easy_setopt ( curl, CURLOPT_URL, uri ); + curl_easy_setopt ( curl, CURLOPT_WRITEDATA, f ); + curl_easy_setopt ( curl, CURLOPT_WRITEFUNCTION, curl_write_func); + curl_easy_setopt ( curl, CURLOPT_NOPROGRESS, 0 ); + curl_easy_setopt ( curl, CURLOPT_PROGRESSDATA, NULL ); + curl_easy_setopt ( curl, CURLOPT_PROGRESSFUNCTION, curl_progress_func); + if (options != NULL) { + if(options->referer != NULL) + curl_easy_setopt ( curl, CURLOPT_REFERER, options->referer); + if(options->follow_location != 0) { + curl_easy_setopt ( curl, CURLOPT_FOLLOWLOCATION, 1); + curl_easy_setopt ( curl, CURLOPT_MAXREDIRS, options->follow_location); + } + if(options->check_file_server_time && time_condition != 0) { + /* if file exists, check against server if file is recent enough */ + curl_easy_setopt ( curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE); + curl_easy_setopt ( curl, CURLOPT_TIMEVALUE, time_condition); } - return(res); + } + curl_easy_setopt ( curl, CURLOPT_USERAGENT, curl_download_user_agent ); + if ((cookie_file = get_cookie_file(FALSE)) != NULL) + curl_easy_setopt(curl, CURLOPT_COOKIEFILE, cookie_file); + res = curl_easy_perform ( curl ); + if (res == 0) { + glong response; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response); + if (response == 304) { // 304 = Not Modified + res = DOWNLOAD_NO_NEWER_FILE; + } else if (response == 200) { // 200 = Ok + gdouble size; + /* verify if curl sends us any data - this is a workaround on using CURLOPT_TIMECONDITION + when the server has a (incorrect) time earlier than the time on the file we already have */ + curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &size); + if (size == 0) + res = DOWNLOAD_ERROR; + else + res = DOWNLOAD_NO_ERROR; + } else { + g_warning("%s: http response: %ld for uri %s (time_condition = %ld)\n", __FUNCTION__, response, uri, time_condition); + res = DOWNLOAD_ERROR; + } + } else { + res = DOWNLOAD_ERROR; + } + curl_easy_cleanup ( curl ); + return res; } -int curl_download_get_url ( const char *hostname, const char *uri, FILE *f, DownloadOptions *options, gboolean ftp ) +int curl_download_get_url ( const char *hostname, const char *uri, FILE *f, DownloadOptions *options, gboolean ftp, time_t time_condition ) { int ret; gchar *full = NULL; /* Compose the full url */ full = g_strdup_printf ( "%s://%s%s", (ftp?"ftp":"http"), hostname, uri ); - ret = curl_download_uri ( full, f, options ); + ret = curl_download_uri ( full, f, options, time_condition ); g_free ( full ); full = NULL; - return (ret ? -2 : 0); /* -2 HTTP error */ + return ret; } diff --git a/src/curl_download.h b/src/curl_download.h index 0fc75184..33b78ee0 100644 --- a/src/curl_download.h +++ b/src/curl_download.h @@ -27,7 +27,7 @@ #include "download.h" void curl_download_init (); -int curl_download_get_url ( const char *hostname, const char *uri, FILE *f, DownloadOptions *options, gboolean ftp ); -int curl_download_uri ( const char *uri, FILE *f, DownloadOptions *options ); +int curl_download_get_url ( const char *hostname, const char *uri, FILE *f, DownloadOptions *options, gboolean ftp, time_t time_condition ); +int curl_download_uri ( const char *uri, FILE *f, DownloadOptions *options, time_t time_condition ); #endif diff --git a/src/download.c b/src/download.c index 1f10ed12..e973ab8c 100644 --- a/src/download.c +++ b/src/download.c @@ -25,11 +25,15 @@ #include #include +#include #include +#include +#include #include #include #include + #include "download.h" #include "curl_download.h" @@ -95,35 +99,39 @@ static int download( const char *hostname, const char *uri, const char *fn, Down int ret; gchar *tmpfilename; gboolean failure = FALSE; + time_t time_condition = 0; /* Check file */ if ( g_file_test ( fn, G_FILE_TEST_EXISTS ) == TRUE ) { - /* File exists: return */ - return -3; + if (options != NULL && options->check_file_server_time) { + /* Get the modified time of this file */ + struct stat buf; + g_stat ( fn, &buf ); + time_condition = buf.st_mtime; + } else { + /* Nothing to do as file already exists, so return */ + return -3; + } } else { gchar *dir = g_path_get_dirname ( fn ); g_mkdir_with_parents ( dir , 0777 ); g_free ( dir ); - - /* create placeholder file */ - if ( ! (f = g_fopen ( fn, "w+b" )) ) /* immediately open file so other threads won't -- prevents race condition */ - return -4; - fclose ( f ); - f = NULL; } tmpfilename = g_strdup_printf("%s.tmp", fn); - f = g_fopen ( tmpfilename, "w+b" ); + f = g_fopen ( tmpfilename, "w+bx" ); /* truncate file and open it in exclusive mode */ if ( ! f ) { + if (errno == EEXIST) + g_debug("%s: Couldn't take lock on temporary file \"%s\"\n", __FUNCTION__, tmpfilename); g_free ( tmpfilename ); - g_remove ( fn ); /* couldn't create temporary. delete 0-byte file. */ return -4; } /* Call the backend function */ - ret = curl_download_get_url ( hostname, uri, f, options, ftp ); - if (ret == -1 || ret == 1 || ret == -2) { + ret = curl_download_get_url ( hostname, uri, f, options, ftp, time_condition ); + + if (ret != DOWNLOAD_NO_ERROR && ret != DOWNLOAD_NO_NEWER_FILE) { g_debug("%s: download failed: curl_download_get_url=%d", __FUNCTION__, ret); failure = TRUE; } @@ -136,19 +144,22 @@ static int download( const char *hostname, const char *uri, const char *fn, Down if (failure) { g_warning(_("Download error: %s"), fn); - fclose ( f ); - f = NULL; g_remove ( tmpfilename ); g_free ( tmpfilename ); + fclose ( f ); + f = NULL; g_remove ( fn ); /* couldn't create temporary. delete 0-byte file. */ return -1; } + if (ret == DOWNLOAD_NO_NEWER_FILE) + g_remove ( tmpfilename ); + else + g_rename ( tmpfilename, fn ); /* move completely-downloaded file to permanent location */ + g_free ( tmpfilename ); fclose ( f ); f = NULL; - g_rename ( tmpfilename, fn ); /* move completely-downloaded file to permanent location */ - g_free ( tmpfilename ); - return ret; + return 0; } /* success = 0, -1 = couldn't connect, -2 HTTP error, -3 file exists, -4 couldn't write to file... */ diff --git a/src/download.h b/src/download.h index f4aa8df5..109bc4c4 100644 --- a/src/download.h +++ b/src/download.h @@ -31,6 +31,12 @@ gboolean a_check_html_file(FILE*); gboolean a_check_kml_file(FILE*); typedef struct { + /** + * Check if the server has a more recent file than the one we have before downloading it + * This uses http header If-Modified-Since + */ + gboolean check_file_server_time; + /** * The REFERER string to use. * Could be NULL. @@ -47,10 +53,16 @@ typedef struct { * File content checker. */ VikFileContentCheckerFunc check_file; + } DownloadOptions; /* TODO: convert to Glib */ int a_http_download_get_url ( const char *hostname, const char *uri, const char *fn, DownloadOptions *opt ); int a_ftp_download_get_url ( const char *hostname, const char *uri, const char *fn, DownloadOptions *opt ); +/* Error messages returned by download functions */ +enum { DOWNLOAD_NO_ERROR = 0, + DOWNLOAD_NO_NEWER_FILE, + DOWNLOAD_ERROR }; + #endif diff --git a/src/expedia.c b/src/expedia.c index a55fde13..9b996658 100644 --- a/src/expedia.c +++ b/src/expedia.c @@ -44,10 +44,10 @@ static gboolean expedia_coord_to_mapcoord ( const VikCoord *src, gdouble xzoom, static void expedia_mapcoord_to_center_coord ( MapCoord *src, VikCoord *dest ); static int expedia_download ( MapCoord *src, const gchar *dest_fn ); -static DownloadOptions expedia_options = { NULL, 2, a_check_map_file }; +static DownloadOptions expedia_options = { FALSE, NULL, 2, a_check_map_file }; void expedia_init() { - VikMapsLayer_MapType map_type = { 5, 0, 0, VIK_VIEWPORT_DRAWMODE_EXPEDIA, expedia_coord_to_mapcoord, expedia_mapcoord_to_center_coord, expedia_download }; + VikMapsLayer_MapType map_type = { 5, 0, 0, VIK_VIEWPORT_DRAWMODE_EXPEDIA, expedia_coord_to_mapcoord, expedia_mapcoord_to_center_coord, expedia_download, &expedia_options }; maps_layer_register_type(_("Expedia Street Maps"), 5, &map_type); } diff --git a/src/geonamessearch.c b/src/geonamessearch.c index 47ea1a8e..ad65da5a 100644 --- a/src/geonamessearch.c +++ b/src/geonamessearch.c @@ -512,7 +512,7 @@ gchar *download_url(gchar *uri) tmp_file = fdopen(tmp_fd, "r+"); // TODO: curl may not be available - if (curl_download_uri(uri, tmp_file, NULL)) { // error + if (curl_download_uri(uri, tmp_file, NULL, 0)) { // error fclose(tmp_file); tmp_file = NULL; g_remove(tmpname); diff --git a/src/googlesearch.c b/src/googlesearch.c index 2e2749de..8ec9cf74 100644 --- a/src/googlesearch.c +++ b/src/googlesearch.c @@ -43,7 +43,7 @@ static gchar *last_search_str = NULL; static VikCoord *last_coord = NULL; static gchar *last_successful_search_str = NULL; -static DownloadOptions googlesearch_options = { "http://maps.google.com/", 0, a_check_map_file }; +static DownloadOptions googlesearch_options = { FALSE, "http://maps.google.com/", 0, a_check_map_file }; gchar * a_googlesearch_get_search_string_for_this_place(VikWindow *vw) { @@ -206,7 +206,7 @@ static int google_search_get_coord(VikWindow *vw, VikViewport *vvp, gchar *srch_ uri = g_strdup_printf(GOOGLE_SEARCH_URL_FMT, escaped_srch_str); /* TODO: curl may not be available */ - if (curl_download_uri(uri, tmp_file, &googlesearch_options)) { /* error */ + if (curl_download_uri(uri, tmp_file, &googlesearch_options, 0)) { /* error */ fclose(tmp_file); tmp_file = NULL; ret = -1; diff --git a/src/osm.c b/src/osm.c index 18c10a5d..7f6ce149 100644 --- a/src/osm.c +++ b/src/osm.c @@ -52,20 +52,21 @@ static int bluemarble_download ( MapCoord *src, const gchar *dest_fn ); static int openaerialmap_download ( MapCoord *src, const gchar *dest_fn ); #endif -static DownloadOptions osm_options = { NULL, 0, a_check_map_file }; +static DownloadOptions osm_options = { TRUE, NULL, 0, a_check_map_file }; /* initialisation */ void osm_init () { - VikMapsLayer_MapType osmarender_type = { 12, 256, 256, VIK_VIEWPORT_DRAWMODE_MERCATOR, osm_coord_to_mapcoord, osm_mapcoord_to_center_coord, osm_osmarender_download }; - VikMapsLayer_MapType mapnik_type = { 13, 256, 256, VIK_VIEWPORT_DRAWMODE_MERCATOR, osm_coord_to_mapcoord, osm_mapcoord_to_center_coord, osm_mapnik_download }; VikMapsLayer_MapType maplint_type = { 14, 256, 256, VIK_VIEWPORT_DRAWMODE_MERCATOR, osm_coord_to_mapcoord, osm_mapcoord_to_center_coord, osm_maplint_download }; - VikMapsLayer_MapType cycle_type = { 17, 256, 256, VIK_VIEWPORT_DRAWMODE_MERCATOR, osm_coord_to_mapcoord, osm_mapcoord_to_center_coord, osm_cycle_download }; + VikMapsLayer_MapType osmarender_type = { 12, 256, 256, VIK_VIEWPORT_DRAWMODE_MERCATOR, osm_coord_to_mapcoord, osm_mapcoord_to_center_coord, osm_osmarender_download, &osm_options }; + VikMapsLayer_MapType mapnik_type = { 13, 256, 256, VIK_VIEWPORT_DRAWMODE_MERCATOR, osm_coord_to_mapcoord, osm_mapcoord_to_center_coord, osm_mapnik_download, &osm_options }; + VikMapsLayer_MapType maplint_type = { 14, 256, 256, VIK_VIEWPORT_DRAWMODE_MERCATOR, osm_coord_to_mapcoord, osm_mapcoord_to_center_coord, osm_maplint_download, &osm_options }; + VikMapsLayer_MapType cycle_type = { 17, 256, 256, VIK_VIEWPORT_DRAWMODE_MERCATOR, osm_coord_to_mapcoord, osm_mapcoord_to_center_coord, osm_cycle_download, &osm_options }; #ifdef VIK_CONFIG_BLUEMARBLE - VikMapsLayer_MapType bluemarble_type = { 15, 256, 256, VIK_VIEWPORT_DRAWMODE_MERCATOR, osm_coord_to_mapcoord, osm_mapcoord_to_center_coord, bluemarble_download }; + VikMapsLayer_MapType bluemarble_type = { 15, 256, 256, VIK_VIEWPORT_DRAWMODE_MERCATOR, osm_coord_to_mapcoord, osm_mapcoord_to_center_coord, bluemarble_download, &osm_options }; #endif #ifdef VIK_CONFIG_OPENAERIAL - VikMapsLayer_MapType openaerialmap_type = { 20, 256, 256, VIK_VIEWPORT_DRAWMODE_MERCATOR, osm_coord_to_mapcoord, osm_mapcoord_to_center_coord, openaerialmap_download }; + VikMapsLayer_MapType openaerialmap_type = { 20, 256, 256, VIK_VIEWPORT_DRAWMODE_MERCATOR, osm_coord_to_mapcoord, osm_mapcoord_to_center_coord, openaerialmap_download, &osm_options }; #endif maps_layer_register_type("OpenStreetMap (Osmarender)", 12, &osmarender_type); diff --git a/src/terraserver.c b/src/terraserver.c index 8127da2e..489b8d85 100644 --- a/src/terraserver.c +++ b/src/terraserver.c @@ -47,12 +47,12 @@ static int terraserver_urban_download ( MapCoord *src, const gchar *dest_fn ); static void terraserver_mapcoord_to_center_coord ( MapCoord *src, VikCoord *dest ); -static DownloadOptions terraserver_options = { NULL, 0, a_check_map_file }; +static DownloadOptions terraserver_options = { FALSE, NULL, 0, a_check_map_file }; void terraserver_init () { - VikMapsLayer_MapType map_type_1 = { 2, 200, 200, VIK_VIEWPORT_DRAWMODE_UTM, terraserver_topo_coord_to_mapcoord, terraserver_mapcoord_to_center_coord, terraserver_topo_download }; - VikMapsLayer_MapType map_type_2 = { 1, 200, 200, VIK_VIEWPORT_DRAWMODE_UTM, terraserver_aerial_coord_to_mapcoord, terraserver_mapcoord_to_center_coord, terraserver_aerial_download }; - VikMapsLayer_MapType map_type_3 = { 4, 200, 200, VIK_VIEWPORT_DRAWMODE_UTM, terraserver_urban_coord_to_mapcoord, terraserver_mapcoord_to_center_coord, terraserver_urban_download }; + VikMapsLayer_MapType map_type_1 = { 2, 200, 200, VIK_VIEWPORT_DRAWMODE_UTM, terraserver_topo_coord_to_mapcoord, terraserver_mapcoord_to_center_coord, terraserver_topo_download, &terraserver_options }; + VikMapsLayer_MapType map_type_2 = { 1, 200, 200, VIK_VIEWPORT_DRAWMODE_UTM, terraserver_aerial_coord_to_mapcoord, terraserver_mapcoord_to_center_coord, terraserver_aerial_download, &terraserver_options }; + VikMapsLayer_MapType map_type_3 = { 4, 200, 200, VIK_VIEWPORT_DRAWMODE_UTM, terraserver_urban_coord_to_mapcoord, terraserver_mapcoord_to_center_coord, terraserver_urban_download, &terraserver_options }; maps_layer_register_type("Terraserver Topos", 2, &map_type_1); maps_layer_register_type("Terraserver Aerials", 1, &map_type_2); diff --git a/src/vikdemlayer.c b/src/vikdemlayer.c index 3c48f745..6c754914 100644 --- a/src/vikdemlayer.c +++ b/src/vikdemlayer.c @@ -763,7 +763,7 @@ static void srtm_dem_download_thread ( DEMDownloadParams *p, gpointer threaddata (intlon >= 0) ? 'E' : 'W', ABS(intlon) ); - static DownloadOptions options = { NULL, 0, a_check_map_file }; + static DownloadOptions options = { FALSE, NULL, 0, a_check_map_file }; a_http_download_get_url ( SRTM_HTTP_SITE, src_fn, p->dest, &options ); g_free ( src_fn ); } diff --git a/src/vikmapslayer.c b/src/vikmapslayer.c index 045e315a..349fa412 100644 --- a/src/vikmapslayer.c +++ b/src/vikmapslayer.c @@ -199,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 */ /****************************************/ @@ -835,6 +839,9 @@ static int 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; @@ -1169,11 +1176,16 @@ static void download_onscreen_maps ( gpointer vml_vvp[2], gint redownload ) } -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); @@ -1190,11 +1202,19 @@ 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 ); + 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 ); diff --git a/src/vikmapslayer.h b/src/vikmapslayer.h index d32ca8eb..3a392977 100644 --- a/src/vikmapslayer.h +++ b/src/vikmapslayer.h @@ -26,6 +26,7 @@ #include "viklayer.h" #include "vikviewport.h" #include "mapcoord.h" +#include "download.h" #define VIK_MAPS_LAYER_TYPE (vik_maps_layer_get_type ()) #define VIK_MAPS_LAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIK_MAPS_LAYER_TYPE, VikMapsLayer)) @@ -51,6 +52,7 @@ typedef struct { gboolean (*coord_to_mapcoord) ( const VikCoord *src, gdouble xzoom, gdouble yzoom, MapCoord *dest ); void (*mapcoord_to_center_coord) ( MapCoord *src, VikCoord *dest ); int (*download) ( MapCoord *src, const gchar *dest_fn ); + DownloadOptions *options; /* TODO: constant size (yay!) */ } VikMapsLayer_MapType; -- 2.39.5