mut->zoom, mut->tilex, mut->tiley);
/* Test if download succeeded (only if retries != 0). */
- if(mut->pixbuf && mut->repo == _curr_repo)
+ if(mut->pixbuf)
{
gint zoff = mut->zoom - _zoom;
/* Update the UI to reflect the updated map database. */
#endif
if(_dl_errors)
{
- gchar buffer[BUFFER_SIZE];
- snprintf(buffer, sizeof(buffer), "%d %s", _dl_errors,
- _("maps failed to download."));
- MACRO_BANNER_SHOW_INFO(_window, buffer);
+ if (mut->repo->layer_level == 0) {
+ gchar buffer[BUFFER_SIZE];
+ snprintf(buffer, sizeof(buffer), "%d %s", _dl_errors,
+ _("maps failed to download."));
+ MACRO_BANNER_SHOW_INFO(_window, buffer);
+ }
_dl_errors = 0;
}
- else if(mut->update_type != MAP_UPDATE_AUTO)
+
+ if(mut->update_type != MAP_UPDATE_AUTO || _refresh_map_after_download)
{
/* Update the map. */
map_refresh_mark(TRUE);
return FALSE;
}
+
+/* Routine draws one partly-transparent pixbuf on top of the another (base map). For efficiency, we
+ assume that base map's tile have no transparent pixels (because it should not have them). We also
+ assume that pixbufs are have the same size. */
+static void
+combine_tiles (GdkPixbuf *dst_pixbuf, GdkPixbuf *src_pixbuf)
+{
+ gint s_n_channels = gdk_pixbuf_get_n_channels (src_pixbuf);
+ gint d_n_channels = gdk_pixbuf_get_n_channels (dst_pixbuf);
+ gint bps = gdk_pixbuf_get_bits_per_sample (dst_pixbuf);
+ gint width, height, x, y, d_delta, s_delta;
+ guchar *d_p, *s_p;
+
+ if (gdk_pixbuf_get_colorspace (dst_pixbuf) != gdk_pixbuf_get_colorspace (src_pixbuf)) {
+ printf ("combine return (1)\n");
+ return;
+ }
+ if (gdk_pixbuf_get_colorspace (dst_pixbuf) != GDK_COLORSPACE_RGB) {
+ printf ("combine return (2)\n");
+ return;
+ }
+
+ if (bps != gdk_pixbuf_get_bits_per_sample (src_pixbuf)) {
+ printf ("combine return (5)\n");
+ return;
+ }
+
+ width = gdk_pixbuf_get_width (dst_pixbuf);
+ height = gdk_pixbuf_get_height (dst_pixbuf);
+
+ if (width != gdk_pixbuf_get_width (src_pixbuf)) {
+ printf ("combine return (6)\n");
+ return;
+ }
+ if (height != gdk_pixbuf_get_height (src_pixbuf)) {
+ printf ("combine return (7)\n");
+ return;
+ }
+
+ s_delta = (bps >> 3) * s_n_channels;
+ d_delta = (bps >> 3) * d_n_channels;
+ d_p = gdk_pixbuf_get_pixels (dst_pixbuf);
+ s_p = gdk_pixbuf_get_pixels (src_pixbuf);
+
+ /* ok, we're ready to combine */
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++, d_p += d_delta, s_p += s_delta) {
+ /* TODO: alpha blending? */
+ if (s_n_channels == 3 || s_p[3]) {
+ d_p[0] = s_p[0];
+ d_p[1] = s_p[1];
+ d_p[2] = s_p[2];
+ }
+ }
+ }
+}
+
+
gboolean
thread_render_map(MapRenderTask *mrt)
{
mrt->pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8,
mrt->screen_width_pixels, mrt->screen_height_pixels);
+ _refresh_map_after_download = FALSE;
/* Iterate through the tiles, get them (or queue a download if they're
* not in the cache), and rotate them into the pixbuf. */
gint tiley = y + start_tiley;
for(x = 0; x < num_tilex; ++x)
{
- GdkPixbuf *tile_pixbuf = NULL;
+ GdkPixbuf *tile_pixbuf = NULL, *layer_pixbuf = NULL;
gboolean started_download = FALSE;
- gint zoff;
+ gint zoff, zoff_base;
gint tilex;
+ RepoData* repo_p = mrt->repo;
tilex = x + start_tilex;
+ zoff_base = mrt->repo->double_size ? 1 : 0;
- zoff = mrt->repo->double_size ? 1 : 0;
-
- /* Iteratively try to retrieve a map to draw the tile. */
- while((mrt->zoom + zoff) <= MAX_ZOOM && zoff < TILE_SIZE_P2)
+ /* iterating over tile and all it's layers */
+ while (repo_p)
{
- /* Check if we're actually going to draw this map. */
- if(tile_dev[2 * (y*num_tilex + x)] != FLT_MAX)
- {
- if(NULL != (tile_pixbuf = mapdb_get(
- mrt->repo, mrt->zoom + zoff,
- tilex >> zoff,
- tiley >> zoff)))
- {
- /* Found a map. */
- break;
- }
- }
- /* Else we're not going to be drawing this map, so just check
- * if it's in the database. */
- else if(mapdb_exists(
- mrt->repo, mrt->zoom + zoff,
- tilex >> zoff,
- tiley >> zoff))
+ started_download = FALSE;
+
+ /* for layers we must use resolution of underlying map */
+ zoff = zoff_base;
+
+ /* if this is not a bottom layer and layer not enabled, skip it */
+ if (repo_p != mrt->repo && !repo_p->layer_enabled)
{
- break;
+ repo_p = repo_p->layers;
+ continue;
}
- /* No map; download, if we should. */
- if(!started_download && _auto_download
- && mrt->repo->type != REPOTYPE_NONE
- /* Make sure this map is within dl zoom limits. */
- && ((unsigned)(mrt->zoom + zoff - mrt->repo->min_zoom)
- <= (mrt->repo->max_zoom - mrt->repo->min_zoom))
- /* Make sure this map matches the dl_zoom_steps,
- * or that there currently is no cache. */
- && (!mrt->repo->db || !((mrt->zoom + zoff
- - (mrt->repo->double_size ? 1 : 0))
- % mrt->repo->dl_zoom_steps))
- /* Make sure this tile is even possible. */
- && ((unsigned)(tilex >> zoff)
- < unit2ztile(WORLD_SIZE_UNITS, mrt->zoom + zoff)
- && (unsigned)(tiley >> zoff)
- < unit2ztile(WORLD_SIZE_UNITS, mrt->zoom + zoff)))
+ /* Iteratively try to retrieve a map to draw the tile. */
+ while((mrt->zoom + zoff) <= MAX_ZOOM && zoff < TILE_SIZE_P2)
{
- started_download = TRUE;
+ /* Check if we're actually going to draw this map. */
+ if(tile_dev[2 * (y*num_tilex + x)] != FLT_MAX)
+ {
+ if(NULL != (layer_pixbuf = mapdb_get(
+ repo_p, mrt->zoom + zoff,
+ tilex >> zoff,
+ tiley >> zoff)))
+ {
+ /* Found a map. Check for it's age. */
+ gint age = get_tile_age (layer_pixbuf);
+ printf ("Tile age (%d)\n", age);
+
+ /* throw away tile only if we can download something */
+ if (!repo_p->layer_refresh_interval ||
+ age < repo_p->layer_refresh_interval * 60 ||
+ !_auto_download)
+ {
+ /* if this is a layer's tile, join with main tile */
+ if (repo_p != mrt->repo)
+ {
+ /* but only if main layer is exists */
+ if (tile_pixbuf)
+ combine_tiles (tile_pixbuf, layer_pixbuf);
+ g_object_unref (layer_pixbuf);
+ }
+ else {
+ tile_pixbuf = layer_pixbuf;
+ zoff_base = zoff;
+ }
+ break;
+ }
+ else
+ g_object_unref (layer_pixbuf);
+ }
+ else
+ if (repo_p->layers)
+ _refresh_map_after_download = TRUE;
+ }
+ /* Else we're not going to be drawing this map, so just check
+ * if it's in the database. */
+ else if(mapdb_exists(
+ repo_p, mrt->zoom + zoff,
+ tilex >> zoff,
+ tiley >> zoff))
+ {
+ zoff_base = zoff;
+ break;
+ }
- if(!refresh_latch)
+ /* No map; download, if we should. */
+ if(!started_download && _auto_download
+ && mrt->repo->type != REPOTYPE_NONE
+ /* Make sure this map is within dl zoom limits. */
+ && ((unsigned)(mrt->zoom + zoff - mrt->repo->min_zoom)
+ <= (mrt->repo->max_zoom - mrt->repo->min_zoom))
+ /* Make sure this map matches the dl_zoom_steps,
+ * or that there currently is no cache. */
+ && (!repo_p->db || !((mrt->zoom + zoff
+ - (mrt->repo->double_size ? 1 : 0))
+ % mrt->repo->dl_zoom_steps))
+ /* Make sure this tile is even possible. */
+ && ((unsigned)(tilex >> zoff)
+ < unit2ztile(WORLD_SIZE_UNITS, mrt->zoom + zoff)
+ && (unsigned)(tiley >> zoff)
+ < unit2ztile(WORLD_SIZE_UNITS, mrt->zoom + zoff)))
{
- refresh_latch = g_slice_new(ThreadLatch);
- refresh_latch->is_open = FALSE;
- refresh_latch->is_done_adding_tasks = FALSE;
- refresh_latch->num_tasks = 1;
- refresh_latch->num_done = 0;
- refresh_latch->mutex = g_mutex_new();
- refresh_latch->cond = g_cond_new();
+ started_download = TRUE;
+
+ if(!refresh_latch)
+ {
+ refresh_latch = g_slice_new(ThreadLatch);
+ refresh_latch->is_open = FALSE;
+ refresh_latch->is_done_adding_tasks = FALSE;
+ refresh_latch->num_tasks = 1;
+ refresh_latch->num_done = 0;
+ refresh_latch->mutex = g_mutex_new();
+ refresh_latch->cond = g_cond_new();
+ }
+ else
+ ++refresh_latch->num_tasks;
+
+ mapdb_initiate_update(
+ repo_p,
+ mrt->zoom + zoff,
+ tilex >> zoff,
+ tiley >> zoff,
+ MAP_UPDATE_AUTO,
+ auto_download_batch_id,
+ (abs((tilex >> zoff) - unit2ztile(
+ mrt->new_center.unitx, mrt->zoom + zoff))
+ + abs((tiley >> zoff) - unit2ztile(
+ mrt->new_center.unity, mrt->zoom + zoff))),
+ refresh_latch);
}
+
+ /* Try again at a coarser resolution. Only for underlying map.*/
+ if (repo_p == mrt->repo)
+ ++zoff;
else
- ++refresh_latch->num_tasks;
-
- mapdb_initiate_update(
- mrt->repo,
- mrt->zoom + zoff,
- tilex >> zoff,
- tiley >> zoff,
- MAP_UPDATE_AUTO,
- auto_download_batch_id,
- (abs((tilex >> zoff) - unit2ztile(
- mrt->new_center.unitx, mrt->zoom + zoff))
- + abs((tiley >> zoff) - unit2ztile(
- mrt->new_center.unity, mrt->zoom + zoff))),
- refresh_latch);
+ break;
}
- /* Try again at a coarser resolution. */
- ++zoff;
+ repo_p = repo_p->layers;
}
+ /* use zoom of the base map */
+ zoff = zoff_base;
+
if(tile_pixbuf)
{
gint boundx, boundy, width, height;
+
if(zoff)
gdk_pixbuf_rotate_matrix_mult_number(matrix, 1 << zoff);
gdk_pixbuf_rotate(mrt->pixbuf,
#include <glib/gstdio.h>
#include <fcntl.h>
#include <locale.h>
+#include <time.h>
#ifndef LEGACY
# include <hildon/hildon-help.h>
GtkWidget *num_min_zoom;
GtkWidget *num_max_zoom;
BrowseInfo browse_info;
+ RepoData *repo;
};
+
+typedef struct _RepoLayersInfo RepoLayersInfo;
+struct _RepoLayersInfo {
+ GtkWidget *dialog;
+ GtkWidget *notebook;
+ GtkListStore *layers_store;
+ GtkWidget *layers_list;
+ GList *layer_edits;
+};
+
+
+typedef struct _LayerEditInfo LayerEditInfo;
+struct _LayerEditInfo {
+ RepoLayersInfo *rli;
+
+ GtkWidget *txt_name;
+ GtkWidget *txt_url;
+ GtkWidget *txt_db;
+ GtkWidget *num_autofetch;
+ GtkWidget *chk_visible;
+ GtkWidget *vbox;
+};
+
+
+
typedef struct _MapmanInfo MapmanInfo;
struct _MapmanInfo {
GtkWidget *dialog;
GtkWidget *chk_zoom_levels[MAX_ZOOM + 1];
};
+
typedef struct _CompactInfo CompactInfo;
struct _CompactInfo {
GtkWidget *dialog;
static MapCache _map_cache;
+const gchar* layer_timestamp_key = "tEXt::mm_ts";
+
static guint
mapdb_get_data(RepoData *repo, gint zoom, gint tilex, gint tiley, gchar **data)
g_mutex_unlock(_mapdb_mutex);
}
+
+void
+map_cache_clean (void)
+{
+ g_mutex_lock(_mapdb_mutex);
+ if(_map_cache.entries != NULL)
+ g_hash_table_remove_all (_map_cache.entries);
+ g_mutex_unlock(_mapdb_mutex);
+}
+
+
gboolean
mapdb_exists(RepoData *repo, gint zoom, gint tilex, gint tiley)
{
gboolean
repo_set_curr(RepoData *rd)
{
+ RepoData* repo_p;
+
printf("%s()\n", __PRETTY_FUNCTION__);
if(!rd->db_filename || !*rd->db_filename
|| repo_make_db(rd))
{
- if(_curr_repo)
+ repo_p = _curr_repo;
+
+ while (repo_p)
{
- if(_curr_repo->db)
+ if(repo_p->db)
{
g_mutex_lock(_mapdb_mutex);
#ifdef MAPDB_SQLITE
- sqlite3_close(_curr_repo->db);
+ sqlite3_close(repo_p->db);
+ repo_p->db = NULL;
#else
- gdbm_close(_curr_repo->db);
+ gdbm_close(repo_p->db);
+ repo_p->db = NULL;
#endif
- _curr_repo->db = NULL;
g_mutex_unlock(_mapdb_mutex);
}
+ repo_p = repo_p->layers;
}
/* Set the current repository! */
popup_error(_window, buffer);
}
#else
- _curr_repo->db = gdbm_open(_curr_repo->db_filename,
- 0, GDBM_WRCREAT | GDBM_FAST, 0644, NULL);
+ /* initialize all databases for all layers */
+ repo_p = _curr_repo;
+ while (repo_p) {
+ if (repo_p->db_filename && *repo_p->db_filename
+ && repo_make_db (repo_p))
+ repo_p->db = gdbm_open(repo_p->db_filename,
+ 0, GDBM_WRCREAT | GDBM_FAST, 0644, NULL);
+ repo_p = repo_p->layers;
+ }
+
if(!_curr_repo->db)
{
gchar buffer[BUFFER_SIZE];
}
}
+
+/**
+ * Returns true if:
+ * 1. base == layer, or
+ * 2. layer is sublayer of base
+ */
+gboolean repo_is_layer (RepoData* base, RepoData* layer)
+{
+ while (base) {
+ if (base == layer)
+ return TRUE;
+ base = base->layers;
+ }
+
+ return FALSE;
+}
+
+
/**
* Given a wms uri pattern, compute the coordinate transformation and
* trimming.
mut->tilex = tilex;
mut->tiley = tiley;
mut->update_type = update_type;
+ mut->layer_level = repo->layer_level;
/* Lock the mutex if this is an auto-update. */
if(update_type == MAP_UPDATE_AUTO)
while(conic_ensure_connected())
{
gint retries;
- gboolean refresh_sent = FALSE;
+ gboolean refresh_sent = FALSE, layer_tile;
MapUpdateTask *mut = NULL;
/* Get the next MUT from the mut tree. */
printf("%s(%s, %d, %d, %d)\n", __PRETTY_FUNCTION__,
mut->repo->name, mut->zoom, mut->tilex, mut->tiley);
- if(mut->repo != _curr_repo)
+ layer_tile = mut->repo != _curr_repo && repo_is_layer (_curr_repo, mut->repo);
+
+ if (mut->repo != _curr_repo && !layer_tile)
{
/* Do nothing, except report that there is no error. */
mut->vfs_result = GNOME_VFS_OK;
/* Report that there is no error. */
mut->vfs_result = GNOME_VFS_OK;
}
- else for(retries = INITIAL_DOWNLOAD_RETRIES; retries > 0; --retries)
+ else for(retries = mut->repo->layer_level ? 1 : INITIAL_DOWNLOAD_RETRIES; retries > 0; --retries)
{
gboolean exists = FALSE;
gchar *src_url;
}
g_object_unref(loader);
+ /* attach timestamp with loaded pixbuf */
+ {
+ gchar* new_bytes;
+ gsize new_size;
+ GError* error = NULL;
+ char ts_val[12];
+
+ sprintf (ts_val, "%u", (unsigned int)time (NULL));
+
+ /* update bytes with new, timestamped pixbuf */
+ if (gdk_pixbuf_save_to_buffer (mut->pixbuf, &new_bytes, &new_size, "png", &error, layer_timestamp_key, ts_val, NULL))
+ {
+ g_free (bytes);
+ bytes = new_bytes;
+ size = new_size;
+ }
+ }
+
/* Copy database-relevant mut data before we release it. */
repo = mut->repo;
zoom = mut->zoom;
guint
mut_exists_hashfunc(const MapUpdateTask *a)
{
- gint sum = a->zoom + a->tilex + a->tiley + a->update_type;
+ gint sum = a->zoom + a->tilex + a->tiley + a->update_type + a->layer_level;
return g_int_hash(&sum);
}
return (a->tilex == b->tilex
&& a->tiley == b->tiley
&& a->zoom == b->zoom
- && a->update_type == b->update_type);
+ && a->update_type == b->update_type
+ && a->layer_level == b->layer_level);
}
gint
if(diff)
return diff;
diff = (a->priority - b->priority); /* Lower priority numbers first. */
+ if(diff)
+ return diff;
+ diff = (a->layer_level - b->layer_level); /* Lower layers first. */
if(diff)
return diff;
gtk_combo_box_get_model(GTK_COMBO_BOX(rmi->cmb_repos))),
NULL) - 1);
+ /* newly created repos keep this NULL in rei, indicating
+ that layes cannot be added so far */
+ rei->repo = NULL;
+
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
return rei;
}
return TRUE;
}
-static gboolean
-repoman_download(GtkWidget *widget, RepoManInfo *rmi)
+gboolean
+repoman_download()
{
GtkWidget *confirm;
printf("%s()\n", __PRETTY_FUNCTION__);
- confirm = hildon_note_new_confirmation(
- GTK_WINDOW(rmi->dialog),
+ confirm = hildon_note_new_confirmation(GTK_WINDOW(_window),
_("Maemo Mapper will now download and add a list of "
"possibly-duplicate repositories from the internet. "
"Continue?"));
/* Get repo config file from www.gnuite.com. */
if(GNOME_VFS_OK != (vfs_result = gnome_vfs_read_entire_file(
- "http://www.gnuite.com/nokia770/maemo-mapper/repos.txt",
+ "http://www.gnuite.com/nokia770/maemo-mapper/"
+ "repos-with-layers.txt",
&size, &bytes)))
{
- popup_error(rmi->dialog,
+ popup_error(_window,
_("An error occurred while retrieving the repositories. "
"The web service may be temporarily down."));
g_printerr("Error while download repositories: %s\n",
/* Parse each line as a reposotory. */
else
{
+ RepoData *prev_repo = NULL;
+ menu_maps_remove_repos();
for(head = bytes; head && *head; head = tail)
{
- gchar buffer[BUFFER_SIZE];
RepoData *rd;
- RepoEditInfo *rei;
tail = strchr(head, '\n');
*tail++ = '\0';
rd = settings_parse_repo(head);
- snprintf(buffer, sizeof(buffer), "%s.db", rd->db_filename);
- rei = repoman_dialog_add_repo(
- rmi, g_strdup(rd->name));
- /* Initialize fields with data from the RepoData object. */
- gtk_entry_set_text(GTK_ENTRY(rei->txt_url), rd->url);
- gtk_entry_set_text(GTK_ENTRY(rei->txt_db_filename), buffer);
- hildon_controlbar_set_value(
- HILDON_CONTROLBAR(rei->num_dl_zoom_steps),
- rd->dl_zoom_steps);
- hildon_controlbar_set_value(
- HILDON_CONTROLBAR(rei->num_view_zoom_steps),
- rd->view_zoom_steps);
- gtk_toggle_button_set_active(
- GTK_TOGGLE_BUTTON(rei->chk_double_size),
- rd->double_size);
- gtk_toggle_button_set_active(
- GTK_TOGGLE_BUTTON(rei->chk_nextable),
- rd->nextable);
- hildon_number_editor_set_value(
- HILDON_NUMBER_EDITOR(rei->num_min_zoom),
- rd->min_zoom);
- hildon_number_editor_set_value(
- HILDON_NUMBER_EDITOR(rei->num_max_zoom),
- rd->max_zoom);
+ if (rd->layer_level == 0) {
+ _repo_list = g_list_append(_repo_list, rd);
+ }
+ else
+ prev_repo->layers = rd;
+
+ prev_repo = rd;
}
g_free(bytes);
+ menu_maps_add_repos();
+ settings_save();
}
}
gtk_widget_destroy(confirm);
return TRUE;
}
+
+static gint
+layer_get_page_index (RepoLayersInfo *rli, GtkTreeIter list_it)
+{
+ GtkTreePath *p1, *p2;
+ GtkTreeIter p;
+ gint index = 0;
+
+ gtk_tree_model_get_iter_first (GTK_TREE_MODEL (rli->layers_store), &p);
+
+ p1 = gtk_tree_model_get_path (GTK_TREE_MODEL (rli->layers_store), &list_it);
+ p2 = gtk_tree_model_get_path (GTK_TREE_MODEL (rli->layers_store), &p);
+
+ while (gtk_tree_path_compare (p1, p2) != 0) {
+ gtk_tree_path_next (p2);
+ index++;
+ }
+
+ gtk_tree_path_free (p1);
+ gtk_tree_path_free (p2);
+
+ return index;
+}
+
+
+static gboolean
+layer_name_changed (GtkWidget *entry, LayerEditInfo *lei)
+{
+ const gchar* name;
+ GtkTreeSelection *selection;
+ GtkTreeIter iter;
+
+ printf("%s()\n", __PRETTY_FUNCTION__);
+
+ /* take new name */
+ name = gtk_entry_get_text (GTK_ENTRY (entry));
+
+ /* find selected entry in list view */
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (lei->rli->layers_list));
+
+ if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) {
+ vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+ return FALSE;
+ }
+
+ gtk_list_store_set (lei->rli->layers_store, &iter, 0, name, -1);
+
+ vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+ return TRUE;
+}
+
+
+static gboolean
+layer_dialog_browse (GtkWidget *widget, LayerEditInfo *lei)
+{
+ GtkWidget *dialog;
+ gchar *basename;
+ printf("%s()\n", __PRETTY_FUNCTION__);
+
+ dialog = GTK_WIDGET(
+ hildon_file_chooser_dialog_new(GTK_WINDOW(lei->rli->dialog),
+ GTK_FILE_CHOOSER_ACTION_SAVE));
+
+ gtk_file_chooser_set_uri(GTK_FILE_CHOOSER(dialog),
+ gtk_entry_get_text(GTK_ENTRY(lei->txt_db)));
+
+ /* Work around a bug in HildonFileChooserDialog. */
+ basename = g_path_get_basename(
+ gtk_entry_get_text(GTK_ENTRY(lei->txt_db)));
+ g_object_set(G_OBJECT(dialog), "autonaming", FALSE, NULL);
+ gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), basename);
+
+ if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(dialog)))
+ {
+ gchar *filename = gtk_file_chooser_get_filename(
+ GTK_FILE_CHOOSER(dialog));
+ gtk_entry_set_text(GTK_ENTRY(lei->txt_db), filename);
+ g_free(filename);
+ }
+
+ gtk_widget_destroy(dialog);
+
+ vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+ return TRUE;
+}
+
+
+
+static LayerEditInfo*
+repoman_layers_add_layer (RepoLayersInfo *rli, gchar* name)
+{
+ LayerEditInfo *lei = g_new (LayerEditInfo, 1);
+ GtkWidget *vbox;
+ GtkWidget *hbox2;
+ GtkWidget *table;
+ GtkWidget *label;
+ GtkWidget *btn_browse;
+ GtkTreeIter layers_iter;
+
+ printf("%s(%s)\n", __PRETTY_FUNCTION__, name);
+
+ lei->rli = rli;
+
+ rli->layer_edits = g_list_append (rli->layer_edits, lei);
+
+ gtk_notebook_append_page (GTK_NOTEBOOK (rli->notebook), vbox = gtk_vbox_new (FALSE, 4),
+ gtk_label_new (name));
+
+ gtk_box_pack_start (GTK_BOX (vbox), table = gtk_table_new (4, 2, FALSE),
+ FALSE, FALSE, 0);
+
+ /* Layer name */
+ gtk_table_attach (GTK_TABLE (table), label = gtk_label_new (_("Name")),
+ 0, 1, 0, 1, GTK_FILL, 0, 2, 0);
+ gtk_misc_set_alignment (GTK_MISC (label), 1.f, 0.5f);
+ gtk_table_attach (GTK_TABLE (table), lei->txt_name = gtk_entry_new (),
+ 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 0);
+ gtk_entry_set_text (GTK_ENTRY (lei->txt_name), name);
+
+ /* signals */
+ g_signal_connect(G_OBJECT(lei->txt_name), "changed", G_CALLBACK(layer_name_changed), lei);
+
+ /* URL format */
+ gtk_table_attach (GTK_TABLE (table), label = gtk_label_new (_("URL")),
+ 0, 1, 1, 2, GTK_FILL, 0, 2, 0);
+ gtk_misc_set_alignment (GTK_MISC (label), 1.f, 0.5f);
+ gtk_table_attach (GTK_TABLE (table), lei->txt_url = gtk_entry_new (),
+ 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 0);
+
+ /* Map directory */
+ gtk_table_attach (GTK_TABLE (table), label = gtk_label_new (_("Cache DB")),
+ 0, 1, 2, 3, GTK_FILL, 0, 2, 0);
+ gtk_misc_set_alignment (GTK_MISC (label), 1.f, 0.5f);
+ gtk_table_attach (GTK_TABLE (table), hbox2 = gtk_hbox_new (FALSE, 4),
+ 1, 2, 2, 3, GTK_EXPAND | GTK_FILL, 0, 2, 0);
+ gtk_box_pack_start (GTK_BOX (hbox2), lei->txt_db = gtk_entry_new (),
+ TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox2), btn_browse = gtk_button_new_with_label (_("Browse...")),
+ FALSE, FALSE, 0);
+
+ g_signal_connect(G_OBJECT(btn_browse), "clicked", G_CALLBACK(layer_dialog_browse), lei);
+
+ /* Autorefresh */
+ gtk_table_attach (GTK_TABLE (table), label = gtk_label_new (_("Autofetch")),
+ 0, 1, 3, 4, GTK_FILL, 0, 2, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+ gtk_table_attach (GTK_TABLE (table), hbox2 = gtk_hbox_new (FALSE, 4),
+ 1, 2, 3, 4, GTK_EXPAND | GTK_FILL, 0, 2, 0);
+ gtk_box_pack_start (GTK_BOX (hbox2), lei->num_autofetch = hildon_number_editor_new (0, 120),
+ FALSE, FALSE, 4);
+ gtk_box_pack_start (GTK_BOX (hbox2), label = gtk_label_new (_("min.")), FALSE, FALSE, 4);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+
+ /* Visible */
+ gtk_box_pack_start (GTK_BOX (vbox), lei->chk_visible = gtk_check_button_new_with_label (_("Layer is visible")),
+ FALSE, FALSE, 4);
+
+ gtk_widget_show_all (vbox);
+
+ /* Side list view with layers */
+ gtk_list_store_append (rli->layers_store, &layers_iter);
+ gtk_list_store_set (rli->layers_store, &layers_iter, 0, name, -1);
+
+ vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+
+ return lei;
+}
+
+
+
+static gboolean
+repoman_layers_new (GtkWidget *widget, RepoLayersInfo *rli)
+{
+ static GtkWidget *hbox = NULL;
+ static GtkWidget *label = NULL;
+ static GtkWidget *txt_name = NULL;
+ static GtkWidget *dialog = NULL;
+ printf("%s()\n", __PRETTY_FUNCTION__);
+
+ if(dialog == NULL)
+ {
+ dialog = gtk_dialog_new_with_buttons(_("New Layer"),
+ GTK_WINDOW(rli->dialog), GTK_DIALOG_MODAL,
+ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+ NULL);
+
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+ hbox = gtk_hbox_new(FALSE, 4), FALSE, FALSE, 4);
+
+ gtk_box_pack_start(GTK_BOX(hbox),
+ label = gtk_label_new(_("Name")),
+ FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox),
+ txt_name = gtk_entry_new(),
+ TRUE, TRUE, 0);
+ }
+
+ gtk_entry_set_text(GTK_ENTRY(txt_name), "");
+
+ gtk_widget_show_all(dialog);
+
+ while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
+ {
+ repoman_layers_add_layer(rli,
+ g_strdup(gtk_entry_get_text(GTK_ENTRY(txt_name))));
+ break;
+ }
+
+ gtk_widget_hide(dialog);
+ vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+ return TRUE;
+}
+
+
+static gboolean
+repoman_layers_del (GtkWidget *widget, RepoLayersInfo *rli)
+{
+ GtkTreeIter iter;
+ GtkTreeSelection *selection;
+ gint index;
+
+ printf("%s()\n", __PRETTY_FUNCTION__);
+
+ /* delete list item */
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (rli->layers_list));
+
+ if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) {
+ vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+ return FALSE;
+ }
+
+ index = layer_get_page_index (rli, iter);
+ gtk_list_store_remove (rli->layers_store, &iter);
+
+ rli->layer_edits = g_list_remove_link (rli->layer_edits, g_list_nth (rli->layer_edits, index));
+
+ /* delete notebook page */
+ gtk_notebook_remove_page (GTK_NOTEBOOK (rli->notebook), index);
+
+ vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+ return TRUE;
+}
+
+
+static gboolean
+repoman_layers_up (GtkWidget *widget, RepoLayersInfo *rli)
+{
+ GtkTreeSelection *selection;
+ GtkTreeIter iter, iter2;
+ GtkTreePath *path;
+ gint page;
+ LayerEditInfo *lei;
+ GList *list_elem;
+
+ printf("%s()\n", __PRETTY_FUNCTION__);
+
+ /* find selected entry in list view */
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (rli->layers_list));
+
+ if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) {
+ vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+ return FALSE;
+ }
+
+ iter2 = iter;
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (rli->layers_store), &iter);
+ if (!gtk_tree_path_prev (path) || !gtk_tree_model_get_iter (GTK_TREE_MODEL (rli->layers_store), &iter, path)) {
+ vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+ return FALSE;
+ }
+
+ gtk_tree_path_free (path);
+
+ /* move it up */
+ gtk_list_store_move_before (rli->layers_store, &iter2, &iter);
+
+ /* reorder notebook tabs */
+ page = gtk_notebook_get_current_page (GTK_NOTEBOOK (rli->notebook));
+ gtk_notebook_reorder_child (GTK_NOTEBOOK (rli->notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (rli->notebook), page), page-1);
+
+ /* reorder layer edits */
+ list_elem = g_list_nth (rli->layer_edits, page);
+ lei = list_elem->data;
+ rli->layer_edits = g_list_remove_link (rli->layer_edits, list_elem);
+ rli->layer_edits = g_list_insert (rli->layer_edits, lei, page-1);
+
+ vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+ return TRUE;
+}
+
+
+static gboolean
+repoman_layers_dn (GtkWidget *widget, RepoLayersInfo *rli)
+{
+ GtkTreeSelection *selection;
+ GtkTreeIter iter, iter2;
+ gint page;
+ LayerEditInfo *lei;
+ GList *list_elem;
+
+ printf("%s()\n", __PRETTY_FUNCTION__);
+
+ /* find selected entry in list view */
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (rli->layers_list));
+
+ if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) {
+ vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+ return FALSE;
+ }
+
+ iter2 = iter;
+ if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (rli->layers_store), &iter)) {
+ vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+ return FALSE;
+ }
+
+ /* move it down */
+ gtk_list_store_move_after (rli->layers_store, &iter2, &iter);
+
+ /* reorder notebook tabs */
+ page = gtk_notebook_get_current_page (GTK_NOTEBOOK (rli->notebook));
+ gtk_notebook_reorder_child (GTK_NOTEBOOK (rli->notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (rli->notebook), page), page+1);
+
+ /* reorder layer edits */
+ list_elem = g_list_nth (rli->layer_edits, page);
+ lei = list_elem->data;
+ rli->layer_edits = g_list_remove_link (rli->layer_edits, list_elem);
+ rli->layer_edits = g_list_insert (rli->layer_edits, lei, page+1);
+
+ vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+ return TRUE;
+}
+
+
+static gboolean
+repoman_layer_selected (GtkTreeSelection *selection, RepoLayersInfo *rli)
+{
+ GtkTreeIter cur;
+
+ printf("%s()\n", __PRETTY_FUNCTION__);
+
+ if (!gtk_tree_selection_get_selected (selection, NULL, &cur)) {
+ vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+ return FALSE;
+ }
+
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (rli->notebook), layer_get_page_index (rli, cur));
+
+ vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+ return TRUE;
+}
+
+
+static gboolean
+repoman_layers(GtkWidget *widget, RepoManInfo *rmi)
+{
+ GtkWidget *hbox = NULL;
+ GtkWidget *layers_vbox = NULL;
+ GtkWidget *buttons_hbox = NULL;
+ GtkWidget *frame;
+ GtkCellRenderer *layers_rendeder = NULL;
+ GtkTreeViewColumn *layers_column = NULL;
+ GtkTreeSelection *selection;
+
+ /* layers buttons */
+ GtkWidget *btn_new = NULL;
+ GtkWidget *btn_del = NULL;
+ GtkWidget *btn_up = NULL;
+ GtkWidget *btn_dn = NULL;
+
+ const char* t_header = _("Manage layers [%s]");
+ char* header = NULL;
+ RepoEditInfo* rei = NULL;
+ RepoLayersInfo rli;
+ gint curr_repo_index = gtk_combo_box_get_active (GTK_COMBO_BOX (rmi->cmb_repos));
+ RepoData *rd;
+
+ printf("%s()\n", __PRETTY_FUNCTION__);
+
+ if (curr_repo_index < 0) {
+ vprintf("%s(): return FALSE (1)\n", __PRETTY_FUNCTION__);
+ return FALSE;
+ }
+
+ rei = g_list_nth_data (rmi->repo_edits, curr_repo_index);
+
+ if (!rei) {
+ vprintf("%s(): return FALSE (2)\n", __PRETTY_FUNCTION__);
+ return FALSE;
+ }
+
+ /* check that rei have repo data structure. If it haven't, it means that repository have just
+ added, so report about this */
+ if (!rei->repo) {
+ GtkWidget *msg = hildon_note_new_information ( GTK_WINDOW (rmi->dialog),
+ _("You cannot add layers to not saved repository,\nsorry. So, press ok in repository manager\n"
+ "and open this dialog again."));
+
+ gtk_dialog_run (GTK_DIALOG (msg));
+ gtk_widget_destroy (msg);
+
+ vprintf("%s(): return FALSE (3)\n", __PRETTY_FUNCTION__);
+ return FALSE;
+ }
+
+ header = g_malloc (strlen (t_header) + strlen (rei->name));
+ sprintf (header, t_header, rei->name);
+
+ printf ("Creating dialog with header: %s\n", header);
+
+ rli.layer_edits = NULL;
+ rli.dialog = gtk_dialog_new_with_buttons (header, GTK_WINDOW (rmi->dialog), GTK_DIALOG_MODAL,
+ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL);
+
+ rli.layers_store = gtk_list_store_new (1, G_TYPE_STRING);
+ rli.layers_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (rli.layers_store));
+ layers_rendeder = gtk_cell_renderer_text_new ();
+ layers_column = gtk_tree_view_column_new_with_attributes ("Column", layers_rendeder, "text", 0, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (rli.layers_list), layers_column);
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (rli.layers_list));
+
+ frame = gtk_frame_new (NULL);
+ gtk_container_add (GTK_CONTAINER (frame), rli.layers_list);
+ gtk_widget_set_size_request (frame, -1, 100);
+
+ /* beside layers list with have buttons on bottom */
+ layers_vbox = gtk_vbox_new (FALSE, 4);
+ gtk_box_pack_start (GTK_BOX (layers_vbox), frame, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (layers_vbox), buttons_hbox = gtk_hbox_new (FALSE, 4), FALSE, FALSE, 0);
+
+ /* buttons */
+ gtk_box_pack_start (GTK_BOX (buttons_hbox), btn_new = gtk_button_new_with_label (_("New")), FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (buttons_hbox), btn_del = gtk_button_new_with_label (_("Del")), FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (buttons_hbox), btn_up = gtk_button_new_with_label (_("Up")), FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (buttons_hbox), btn_dn = gtk_button_new_with_label (_("Dn")), FALSE, FALSE, 0);
+
+ /* signals */
+ g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(repoman_layer_selected), &rli);
+ g_signal_connect(G_OBJECT(btn_new), "clicked", G_CALLBACK(repoman_layers_new), &rli);
+ g_signal_connect(G_OBJECT(btn_del), "clicked", G_CALLBACK(repoman_layers_del), &rli);
+ g_signal_connect(G_OBJECT(btn_up), "clicked", G_CALLBACK(repoman_layers_up), &rli);
+ g_signal_connect(G_OBJECT(btn_dn), "clicked", G_CALLBACK(repoman_layers_dn), &rli);
+
+ /* notebook with layers' attributes */
+ rli.notebook = gtk_notebook_new ();
+
+ gtk_notebook_set_show_tabs(GTK_NOTEBOOK(rli.notebook), FALSE);
+ gtk_notebook_set_show_border(GTK_NOTEBOOK(rli.notebook), FALSE);
+
+ /* walk through all layers and add notebook pages */
+ rd = rei->repo->layers;
+ while (rd) {
+ LayerEditInfo *lei = repoman_layers_add_layer (&rli, rd->name);
+
+ gtk_entry_set_text (GTK_ENTRY (lei->txt_url), rd->url);
+ gtk_entry_set_text (GTK_ENTRY (lei->txt_db), rd->db_filename);
+ hildon_number_editor_set_value (HILDON_NUMBER_EDITOR (lei->num_autofetch), rd->layer_refresh_interval);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lei->chk_visible), rd->layer_enabled);
+
+ rd = rd->layers;
+ }
+
+ /* pack all widgets together */
+ hbox = gtk_hbox_new (FALSE, 4);
+
+ gtk_box_pack_start (GTK_BOX (hbox), layers_vbox, TRUE, TRUE, 4);
+ gtk_box_pack_start (GTK_BOX (hbox), rli.notebook, TRUE, TRUE, 4);
+
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (rli.dialog)->vbox), hbox, FALSE, FALSE, 4);
+
+ gtk_widget_show_all (rli.dialog);
+
+ while (GTK_RESPONSE_ACCEPT == gtk_dialog_run (GTK_DIALOG (rli.dialog)))
+ {
+ RepoData **rdp;
+ gint i;
+ GList *curr;
+
+ menu_layers_remove_repos ();
+
+ /* iterate over notebook's pages and build layers */
+ /* keep list in memory in case downloads use it (TODO: reference counting) */
+ rdp = &rei->repo->layers;
+ *rdp = NULL;
+
+ for (i = 0, curr = rli.layer_edits; curr; curr = curr->next, i++) {
+ LayerEditInfo *lei = curr->data;
+
+ rd = g_new0 (RepoData, 1);
+ *rdp = rd;
+
+ rd->name = g_strdup (gtk_entry_get_text (GTK_ENTRY (lei->txt_name)));
+ rd->url = g_strdup (gtk_entry_get_text (GTK_ENTRY (lei->txt_url)));
+ rd->db_filename = g_strdup (gtk_entry_get_text (GTK_ENTRY (lei->txt_db)));
+ rd->layer_enabled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (lei->chk_visible));
+ rd->layer_refresh_interval = hildon_number_editor_get_value (HILDON_NUMBER_EDITOR (lei->num_autofetch));
+ rd->layer_refresh_countdown = rd->layer_refresh_interval;
+ rd->layer_level = i+1;
+
+ rd->dl_zoom_steps = rei->repo->dl_zoom_steps;
+ rd->view_zoom_steps = rei->repo->view_zoom_steps;
+ rd->double_size = rei->repo->double_size;
+ rd->nextable = rei->repo->nextable;
+ rd->min_zoom = rei->repo->min_zoom;
+ rd->max_zoom = rei->repo->max_zoom;
+
+ set_repo_type (rd);
+ rdp = &rd->layers;
+ }
+
+ menu_layers_add_repos ();
+ repo_set_curr(_curr_repo);
+ settings_save ();
+ map_cache_clean ();
+ map_refresh_mark (TRUE);
+ break;
+ }
+
+ gtk_widget_destroy (rli.dialog);
+
+ vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+ return TRUE;
+}
+
+
gboolean
repoman_dialog()
{
static GtkWidget *btn_delete = NULL;
static GtkWidget *btn_new = NULL;
static GtkWidget *btn_reset = NULL;
- static GtkWidget *btn_download = NULL;
+ static GtkWidget *btn_layers = NULL;
gint i, curr_repo_index = 0;
GList *curr;
printf("%s()\n", __PRETTY_FUNCTION__);
g_signal_connect(G_OBJECT(btn_reset), "clicked",
G_CALLBACK(repoman_reset), &rmi);
- /* Download button. */
+ /* Layers button. */
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
- btn_download = gtk_button_new_with_label(_("Download...")));
- g_signal_connect(G_OBJECT(btn_download), "clicked",
- G_CALLBACK(repoman_download), &rmi);
+ btn_layers = gtk_button_new_with_label(_("Layers...")));
+ g_signal_connect(G_OBJECT(btn_layers), "clicked",
+ G_CALLBACK(repoman_layers), &rmi);
/* Cancel button. */
gtk_dialog_add_button(GTK_DIALOG(dialog),
RepoData *rd = (RepoData*)curr->data;
RepoEditInfo *rei = repoman_dialog_add_repo(&rmi, g_strdup(rd->name));
+ /* store this to be able to walk through layers attached to repo */
+ rei->repo = rd;
+
/* Initialize fields with data from the RepoData object. */
gtk_entry_set_text(GTK_ENTRY(rei->txt_url), rd->url);
gtk_entry_set_text(GTK_ENTRY(rei->txt_db_filename),
for(i = 0, curr = rmi.repo_edits; curr; curr = curr->next, i++)
{
RepoEditInfo *rei = curr->data;
- RepoData *rd = g_new(RepoData, 1);
+ RepoData *rd = g_new0(RepoData, 1);
+ RepoData *rd0, **rd1;
rd->name = g_strdup(rei->name);
rd->url = g_strdup(gtk_entry_get_text(GTK_ENTRY(rei->txt_url)));
rd->db_filename = gnome_vfs_expand_initial_tilde(
HILDON_NUMBER_EDITOR(rei->num_min_zoom));
rd->max_zoom = hildon_number_editor_get_value(
HILDON_NUMBER_EDITOR(rei->num_max_zoom));
+
+ if (rei->repo) {
+ /* clone layers */
+ rd0 = rei->repo->layers;
+ rd1 = &rd->layers;
+
+ while (rd0) {
+ *rd1 = g_new0 (RepoData, 1);
+ (*rd1)->name = rd0->name;
+ (*rd1)->url = rd0->url;
+ (*rd1)->db_filename = rd0->db_filename;
+ (*rd1)->layer_enabled = rd0->layer_enabled;
+ (*rd1)->layer_refresh_interval = rd0->layer_refresh_interval;
+ (*rd1)->layer_refresh_countdown = rd0->layer_refresh_countdown;
+ (*rd1)->layer_level = rd0->layer_level;
+
+ (*rd1)->dl_zoom_steps = rd0->dl_zoom_steps;
+ (*rd1)->view_zoom_steps = rd0->view_zoom_steps;
+ (*rd1)->double_size = rd0->double_size;
+ (*rd1)->nextable = rd0->nextable;
+ (*rd1)->min_zoom = rd0->min_zoom;
+ (*rd1)->max_zoom = rd0->max_zoom;
+
+ set_repo_type (*rd1);
+
+ rd0 = rd0->layers;
+ rd1 = &(*rd1)->layers;
+ }
+ *rd1 = NULL;
+ }
+ else
+ rd->layers = NULL;
+
+ rd->layer_level = 0;
set_repo_type(rd);
_repo_list = g_list_append(_repo_list, rd);
repoman_delete(&rmi, 0);
map_set_zoom(_zoom); /* make sure we're at an appropriate zoom level. */
+ map_refresh_mark (TRUE);
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
return TRUE;
if((unsigned)tilex < unit2ztile(WORLD_SIZE_UNITS, z)
&& (unsigned)tiley < unit2ztile(WORLD_SIZE_UNITS, z))
{
- mapdb_initiate_update(_curr_repo, z, tilex, tiley,
- update_type, download_batch_id,
- (abs(tilex - unit2tile(_next_center.unitx))
- + abs(tiley - unit2tile(_next_center.unity))),
- NULL);
+ RepoData* rd = _curr_repo;
+
+ while (rd) {
+ if (rd == _curr_repo || (rd->layer_enabled && rd->db))
+ mapdb_initiate_update(rd, z, tilex, tiley,
+ update_type, download_batch_id,
+ (abs(tilex - unit2tile(_next_center.unitx))
+ + abs(tiley - unit2tile(_next_center.unity))),
+ NULL);
+ rd = rd->layers;
+ }
}
}
}
return TRUE;
}
+
+/* changes visibility of current repo's layers to it's previous state */
+void maps_toggle_visible_layers ()
+{
+ RepoData *rd = _curr_repo;
+ gboolean changed = FALSE;
+
+ printf("%s()\n", __PRETTY_FUNCTION__);
+
+ if (!rd) {
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+ return;
+ }
+
+ rd = rd->layers;
+
+ while (rd) {
+ if (rd->layer_enabled) {
+ changed = TRUE;
+ rd->layer_was_enabled = rd->layer_enabled;
+ rd->layer_enabled = FALSE;
+ }
+ else {
+ rd->layer_enabled = rd->layer_was_enabled;
+ if (rd->layer_was_enabled)
+ changed = TRUE;
+ }
+
+ rd = rd->layers;
+ }
+
+ /* redraw map */
+ if (changed) {
+ menu_layers_remove_repos ();
+ menu_layers_add_repos ();
+ map_cache_clean ();
+ map_refresh_mark (TRUE);
+ }
+
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+
+
+/* this routine fired by timer every minute and decrements refetch counter of every active layer of
+ current repository. If one of layer is expired, it forces map redraw. Redraw routine checks every
+ layer's tile download timestamp and desides performs refetch if needed */
+gboolean
+map_layer_refresh_cb (gpointer data)
+{
+ RepoData* rd = _curr_repo;
+ gboolean refresh = FALSE;
+ printf("%s()\n", __PRETTY_FUNCTION__);
+
+ if (rd) {
+ rd = rd->layers;
+
+ while (rd) {
+ if (rd->layer_enabled && rd->layer_refresh_interval) {
+ rd->layer_refresh_countdown--;
+ if (rd->layer_refresh_countdown <= 0) {
+ rd->layer_refresh_countdown = rd->layer_refresh_interval;
+ refresh = TRUE;
+ }
+ }
+
+ rd = rd->layers;
+ }
+ }
+
+ if (refresh)
+ map_refresh_mark (TRUE);
+
+ vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+ return TRUE;
+}
+
+
+
+/*
+ Returns amount of seconds since tile downloaded or 0 if tile
+ have no such information.
+*/
+gint get_tile_age (GdkPixbuf* pixbuf)
+{
+ const char* ts;
+ guint val;
+
+ ts = gdk_pixbuf_get_option (pixbuf, layer_timestamp_key);
+
+ if (!ts)
+ return 0;
+
+ if (sscanf (ts, "%u", &val))
+ return time (NULL) - val;
+ else
+ return 0;
+}