2 * This file is part of mapper
4 * Copyright (C) 2007 Kaj-Michael Lang
5 * Copyright (C) 2006-2007 John Costigan.
7 * POI and GPS-Info code originally written by Cezary Jackiewicz.
9 * Default map data provided by http://www.openstreetmap.org/
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
37 #include <libgnomevfs/gnome-vfs.h>
39 #include "hildon-mapper.h"
47 #include "mapper-types.h"
48 #include "map-download.h"
49 #include "ui-common.h"
53 #define MAP_REPO_LIST_URL "http://www.gnuite.com/nokia770/maemo-mapper/repos.txt"
55 typedef struct _RepoManInfo RepoManInfo;
63 typedef struct _RepoEditInfo RepoEditInfo;
64 struct _RepoEditInfo {
67 GtkWidget *txt_cache_dir;
68 GtkWidget *num_dl_zoom_steps;
69 GtkWidget *num_view_zoom_steps;
70 GtkWidget *chk_double_size;
71 GtkWidget *chk_nextable;
72 GtkWidget *btn_browse;
73 BrowseInfo browse_info;
76 typedef struct _MapmanInfo MapmanInfo;
82 /* The "Setup" tab. */
83 GtkWidget *rad_download;
84 GtkWidget *rad_delete;
85 GtkWidget *chk_overwrite;
86 GtkWidget *rad_by_area;
87 GtkWidget *rad_by_route;
88 GtkWidget *num_route_radius;
91 GtkWidget *txt_topleft_lat;
92 GtkWidget *txt_topleft_lon;
93 GtkWidget *txt_botright_lat;
94 GtkWidget *txt_botright_lon;
97 GtkWidget *chk_zoom_levels[MAX_ZOOM];
100 void set_repo_type(RepoData * repo)
102 if (repo->url && *repo->url) {
103 gchar *url = g_utf8_strdown(repo->url, -1);
105 /* Determine type of repository. */
106 if (strstr(url, "service=wms"))
107 repo->type = REPOTYPE_WMS;
108 else if (strstr(url, "%s"))
109 repo->type = REPOTYPE_QUAD_QRST;
110 else if (strstr(url, "%0d"))
111 repo->type = REPOTYPE_XYZ_INV;
112 else if (strstr(url, "%0s"))
113 repo->type = REPOTYPE_QUAD_ZERO;
115 repo->type = REPOTYPE_XYZ;
119 repo->type = REPOTYPE_NONE;
123 config_parse_repo(gchar * str)
125 /* Parse each part of a repo, delimited by newline characters:
132 gchar *token, *error_check;
134 RepoData *rd = g_new0(RepoData, 1);
137 token = strsep(&str, "\n\t");
139 rd->name = g_strdup(token);
141 /* Parse URL format. */
142 token = strsep(&str, "\n\t");
144 rd->url = g_strdup(token);
146 /* Parse cache dir. */
147 token = strsep(&str, "\n\t");
149 rd->cache_dir = gnome_vfs_expand_initial_tilde(token);
151 /* Parse download zoom steps. */
152 token = strsep(&str, "\n\t");
153 if (!token || !*token || !(rd->dl_zoom_steps = atoi(token)))
154 rd->dl_zoom_steps = 2;
156 /* Parse view zoom steps. */
157 token = strsep(&str, "\n\t");
158 if (!token || !*token || !(rd->view_zoom_steps = atoi(token)))
159 rd->view_zoom_steps = 1;
161 /* Parse double-size. */
162 token = strsep(&str, "\n\t");
164 rd->double_size = atoi(token); /* Default is zero (FALSE) */
166 /* Parse next-able. */
167 token = strsep(&str, "\n\t");
168 if (!token || !*token
169 || (rd->nextable = strtol(token, &error_check, 10), token == str))
177 repo_make_cache_dir(gchar * name, const gchar * cache_dir, GtkWidget * parent)
179 if (g_mkdir_with_parents(cache_dir, 0755)) {
180 /* Failed to create Map Cache directory. */
181 gchar buffer[BUFFER_SIZE];
182 g_snprintf(buffer, sizeof(buffer), "%s: %s",
183 _("Unable to create cache directory for repository"), name);
184 popup_error(parent, buffer);
187 return g_file_test(cache_dir, G_FILE_TEST_EXISTS);
191 repo_set_curr(RepoData * rd)
194 return repo_make_cache_dir(rd->name, rd->cache_dir, _window);
198 repoman_dialog_select(GtkWidget * widget, RepoManInfo * rmi)
200 gint curr_index = gtk_combo_box_get_active(GTK_COMBO_BOX(rmi->cmb_repos));
201 gtk_notebook_set_current_page(GTK_NOTEBOOK(rmi->notebook), curr_index);
206 repoman_dialog_browse(GtkWidget * widget, BrowseInfo * browse_info)
210 dialog = GTK_WIDGET(hildon_file_chooser_dialog_new
211 (GTK_WINDOW(browse_info->dialog),
212 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER));
214 gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(dialog), TRUE);
215 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), gtk_entry_get_text(GTK_ENTRY(browse_info->txt)));
217 if (GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(dialog))) {
218 gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
219 gtk_entry_set_text(GTK_ENTRY(browse_info->txt), filename);
223 gtk_widget_destroy(dialog);
229 repoman_dialog_rename(GtkWidget * widget, RepoManInfo * rmi)
236 dialog = gtk_dialog_new_with_buttons(_("New Name"),
237 GTK_WINDOW(rmi->dialog),
238 GTK_DIALOG_MODAL, GTK_STOCK_OK,
241 GTK_RESPONSE_REJECT, NULL);
243 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
244 hbox = gtk_hbox_new(FALSE, 4), FALSE, FALSE, 4);
246 gtk_box_pack_start(GTK_BOX(hbox),
247 label = gtk_label_new(_("Name")), FALSE, FALSE, 0);
248 gtk_box_pack_start(GTK_BOX(hbox),
249 txt_name = gtk_entry_new(), TRUE, TRUE, 0);
251 gtk_widget_show_all(dialog);
253 while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog))) {
254 gint active = gtk_combo_box_get_active(GTK_COMBO_BOX(rmi->cmb_repos));
255 RepoEditInfo *rei = g_list_nth_data(rmi->repo_edits, active);
257 rei->name = g_strdup(gtk_entry_get_text(GTK_ENTRY(txt_name)));
258 gtk_combo_box_insert_text(GTK_COMBO_BOX(rmi->cmb_repos), active, g_strdup(rei->name));
259 gtk_combo_box_set_active(GTK_COMBO_BOX(rmi->cmb_repos), active);
260 gtk_combo_box_remove_text(GTK_COMBO_BOX(rmi->cmb_repos), active + 1);
264 gtk_widget_destroy(dialog);
269 repoman_dialog_delete(GtkWidget * widget, RepoManInfo * rmi)
273 gint active = gtk_combo_box_get_active(GTK_COMBO_BOX(rmi->cmb_repos));
275 if (gtk_tree_model_iter_n_children
277 (gtk_combo_box_get_model(GTK_COMBO_BOX(rmi->cmb_repos))),
279 popup_error(rmi->dialog,
280 _("Cannot delete the last repository - there must be at"
281 " lease one repository."));
285 g_snprintf(buffer, sizeof(buffer), "%s:\n%s\n",
286 _("Confirm delete of repository"),
287 gtk_combo_box_get_active_text(GTK_COMBO_BOX(rmi->cmb_repos)));
288 confirm = hildon_note_new_confirmation(GTK_WINDOW(_window), buffer);
290 if (GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm))) {
291 gtk_combo_box_remove_text(GTK_COMBO_BOX(rmi->cmb_repos), active);
292 gtk_notebook_remove_page(GTK_NOTEBOOK(rmi->notebook), active);
293 rmi->repo_edits = g_list_remove_link(rmi->repo_edits, g_list_nth(rmi->repo_edits, active));
294 gtk_combo_box_set_active(GTK_COMBO_BOX(rmi->cmb_repos), MAX(0, active - 1));
297 gtk_widget_destroy(confirm);
302 static RepoEditInfo *
303 repoman_dialog_add_repo(RepoManInfo * rmi, gchar * name)
309 RepoEditInfo *rei = g_new(RepoEditInfo, 1);
314 gtk_notebook_append_page(GTK_NOTEBOOK(rmi->notebook),
315 vbox = gtk_vbox_new(FALSE, 4),
316 gtk_label_new(name));
318 gtk_box_pack_start(GTK_BOX(vbox), table = gtk_table_new(2, 2, FALSE), FALSE, FALSE, 0);
319 /* Map download URI. */
320 gtk_table_attach(GTK_TABLE(table), label = gtk_label_new(_("URL Format")), 0, 1, 0, 1, GTK_FILL, 0, 2, 4);
321 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
322 gtk_table_attach(GTK_TABLE(table), rei->txt_url = gtk_entry_new(), 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
325 gtk_table_attach(GTK_TABLE(table), label = gtk_label_new(_("Cache Dir.")), 0, 1, 1, 2, GTK_FILL, 0, 2, 4);
326 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
327 gtk_table_attach(GTK_TABLE(table), hbox = gtk_hbox_new(FALSE, 4), 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
328 gtk_box_pack_start(GTK_BOX(hbox), rei->txt_cache_dir = gtk_entry_new(), TRUE, TRUE, 0);
329 gtk_box_pack_start(GTK_BOX(hbox), rei->btn_browse = gtk_button_new_with_label(_("Browse...")), FALSE, FALSE, 0);
331 /* Initialize cache dir */
333 gchar *cache_base = gnome_vfs_expand_initial_tilde(REPO_DEFAULT_CACHE_BASE);
334 gchar *cache_dir = gnome_vfs_uri_make_full_from_relative(cache_base, name);
335 gtk_entry_set_text(GTK_ENTRY(rei->txt_cache_dir), cache_dir);
340 gtk_box_pack_start(GTK_BOX(vbox), table = gtk_table_new(3, 2, FALSE), FALSE, FALSE, 0);
342 /* Download Zoom Steps. */
343 gtk_table_attach(GTK_TABLE(table), label = gtk_label_new(_("Download Zoom Steps")), 0, 1, 0, 1, GTK_FILL, 0, 2, 4);
344 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
345 gtk_table_attach(GTK_TABLE(table), label = gtk_alignment_new(0.5f, 0.5f, 0.f, 0.f), 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 2, 4);
346 gtk_container_add(GTK_CONTAINER(label), rei->num_dl_zoom_steps = hildon_controlbar_new());
347 hildon_controlbar_set_range(HILDON_CONTROLBAR(rei->num_dl_zoom_steps), 1, 4);
348 hildon_controlbar_set_value(HILDON_CONTROLBAR(rei->num_dl_zoom_steps), REPO_DEFAULT_DL_ZOOM_STEPS);
349 force_min_visible_bars(HILDON_CONTROLBAR(rei->num_dl_zoom_steps), 1);
351 /* Download Zoom Steps. */
352 gtk_table_attach(GTK_TABLE(table), label = gtk_label_new(_("View Zoom Steps")), 0, 1, 1, 2, GTK_FILL, 0, 2, 4);
353 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
354 gtk_table_attach(GTK_TABLE(table), label = gtk_alignment_new(0.5f, 0.5f, 0.f, 0.f), 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, 0, 2, 4);
355 gtk_container_add(GTK_CONTAINER(label), rei->num_view_zoom_steps = hildon_controlbar_new());
356 hildon_controlbar_set_range(HILDON_CONTROLBAR(rei->num_view_zoom_steps), 1, 4);
357 hildon_controlbar_set_value(HILDON_CONTROLBAR(rei->num_view_zoom_steps), REPO_DEFAULT_VIEW_ZOOM_STEPS);
358 force_min_visible_bars(HILDON_CONTROLBAR(rei->num_view_zoom_steps), 1);
360 gtk_table_attach(GTK_TABLE(table), label = gtk_vseparator_new(), 2, 3, 0, 2, GTK_FILL, GTK_FILL, 4, 4);
363 gtk_table_attach(GTK_TABLE(table), rei->chk_double_size = gtk_check_button_new_with_label(_("Double Pixels")), 3, 4, 0, 1, GTK_FILL, GTK_FILL, 0, 4);
364 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rei->chk_double_size), FALSE);
367 gtk_table_attach(GTK_TABLE(table), rei->chk_nextable = gtk_check_button_new_with_label(_("Next-able")), 3, 4, 1, 2, GTK_FILL, GTK_FILL, 0, 4);
368 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rei->chk_nextable), TRUE);
370 rmi->repo_edits = g_list_append(rmi->repo_edits, rei);
372 /* Connect signals. */
373 rei->browse_info.dialog = rmi->dialog;
374 rei->browse_info.txt = rei->txt_cache_dir;
375 g_signal_connect(G_OBJECT(rei->btn_browse), "clicked", G_CALLBACK(repoman_dialog_browse), &rei->browse_info);
377 gtk_widget_show_all(vbox);
379 gtk_combo_box_append_text(GTK_COMBO_BOX(rmi->cmb_repos), name);
380 gtk_combo_box_set_active(GTK_COMBO_BOX(rmi->cmb_repos),
381 gtk_tree_model_iter_n_children(GTK_TREE_MODEL
382 (gtk_combo_box_get_model
392 repoman_dialog_new(GtkWidget * widget, RepoManInfo * rmi)
399 dialog = gtk_dialog_new_with_buttons(_("New Repository"),
400 GTK_WINDOW(rmi->dialog),
401 GTK_DIALOG_MODAL, GTK_STOCK_OK,
404 GTK_RESPONSE_REJECT, NULL);
406 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
407 hbox = gtk_hbox_new(FALSE, 4), FALSE, FALSE, 4);
409 gtk_box_pack_start(GTK_BOX(hbox),
410 label = gtk_label_new(_("Name")), FALSE, FALSE, 0);
411 gtk_box_pack_start(GTK_BOX(hbox),
412 txt_name = gtk_entry_new(), TRUE, TRUE, 0);
414 gtk_widget_show_all(dialog);
416 while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog))) {
417 repoman_dialog_add_repo(rmi,
418 g_strdup(gtk_entry_get_text
419 (GTK_ENTRY(txt_name))));
423 gtk_widget_destroy(dialog);
429 repoman_reset(GtkWidget * widget, RepoManInfo * rmi)
433 confirm = hildon_note_new_confirmation(GTK_WINDOW(_window),
434 _("Replace all repositories with the default repository?"));
436 if (GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm))) {
437 /* First, delete all existing repositories. */
438 while (rmi->repo_edits) {
439 gtk_combo_box_remove_text(GTK_COMBO_BOX(rmi->cmb_repos),
441 gtk_notebook_remove_page(GTK_NOTEBOOK(rmi->notebook),
444 g_list_remove_link(rmi->repo_edits,
445 g_list_first(rmi->repo_edits));
448 /* Now, add the default repository. */
449 repoman_dialog_add_repo(rmi, REPO_DEFAULT_NAME);
450 gtk_entry_set_text(GTK_ENTRY
451 (((RepoEditInfo *) rmi->repo_edits->data)->
452 txt_url), REPO_DEFAULT_MAP_URI);
454 gtk_combo_box_set_active(GTK_COMBO_BOX(rmi->cmb_repos), 0);
456 gtk_widget_destroy(confirm);
462 repoman_download(GtkWidget * widget, RepoManInfo * rmi)
466 confirm = hildon_note_new_confirmation(GTK_WINDOW(rmi->dialog),
467 _("Mapper will now download and add a list of "
468 "possibly-duplicate repositories from the internet. "
471 if (GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm))) {
476 GnomeVFSResult vfs_result;
478 /* Get repo config file from www.gnuite.com. */
479 if (GNOME_VFS_OK != (vfs_result = gnome_vfs_read_entire_file
480 (MAP_REPO_LIST_URL, &size, &bytes))) {
481 popup_error(rmi->dialog,
482 _("An error occurred while retrieving the repositories. "
483 "The web service may be temporarily down."));
484 g_printerr("Error while download repositories: %s\n", gnome_vfs_result_to_string(vfs_result));
486 /* Parse each line as a reposotory. */
488 for (head = bytes; head && *head; head = tail) {
491 tail = strchr(head, '\n');
493 rd = config_parse_repo(head);
494 rei = repoman_dialog_add_repo(rmi, g_strdup(rd->name));
495 /* Initialize fields with data from the RepoData object. */
496 gtk_entry_set_text(GTK_ENTRY(rei->txt_url), rd->url);
497 gtk_entry_set_text(GTK_ENTRY(rei->txt_cache_dir), rd->cache_dir);
498 hildon_controlbar_set_value(HILDON_CONTROLBAR(rei->num_dl_zoom_steps), rd->dl_zoom_steps);
499 hildon_controlbar_set_value(HILDON_CONTROLBAR(rei->num_view_zoom_steps), rd->view_zoom_steps);
500 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rei->chk_double_size), rd->double_size);
501 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rei->chk_nextable), rd->nextable);
506 gtk_widget_destroy(confirm);
516 GtkWidget *btn_rename;
517 GtkWidget *btn_delete;
519 GtkWidget *btn_reset;
520 GtkWidget *btn_download;
521 guint i, curr_repo_index = 0;
524 rmi.dialog = gtk_dialog_new_with_buttons(_("Manage Repositories"),
526 GTK_DIALOG_MODAL, GTK_STOCK_OK,
527 GTK_RESPONSE_ACCEPT, NULL);
529 help_dialog_help_enable(GTK_DIALOG(rmi.dialog), HELP_ID_REPOMAN);
532 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(rmi.dialog)->action_area),
533 btn_reset = gtk_button_new_with_label(_("Reset...")));
534 g_signal_connect(G_OBJECT(btn_reset), "clicked", G_CALLBACK(repoman_reset), &rmi);
536 /* Download button. */
537 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(rmi.dialog)->action_area),
538 btn_download = gtk_button_new_with_label(_("Download...")));
539 g_signal_connect(G_OBJECT(btn_download), "clicked", G_CALLBACK(repoman_download), &rmi);
542 gtk_dialog_add_button(GTK_DIALOG(rmi.dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
544 hbox = gtk_hbox_new(FALSE, 4);
546 gtk_box_pack_start(GTK_BOX(hbox), rmi.cmb_repos = gtk_combo_box_new_text(), TRUE, TRUE, 4);
548 gtk_box_pack_start(GTK_BOX(hbox), gtk_vseparator_new(), FALSE, FALSE, 4);
549 gtk_box_pack_start(GTK_BOX(hbox), btn_rename = gtk_button_new_with_label(_("Rename...")), FALSE, FALSE, 4);
550 gtk_box_pack_start(GTK_BOX(hbox), btn_delete = gtk_button_new_with_label(_("Delete...")), FALSE, FALSE, 4);
551 gtk_box_pack_start(GTK_BOX(hbox), btn_new = gtk_button_new_with_label(_("New...")), FALSE, FALSE, 4);
553 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(rmi.dialog)->vbox), hbox, FALSE, FALSE, 4);
554 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(rmi.dialog)->vbox), gtk_hseparator_new(), TRUE, TRUE, 4);
555 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(rmi.dialog)->vbox), rmi.notebook = gtk_notebook_new(), TRUE, TRUE, 4);
557 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(rmi.notebook), FALSE);
558 gtk_notebook_set_show_border(GTK_NOTEBOOK(rmi.notebook), FALSE);
560 rmi.repo_edits = NULL;
562 /* Populate combo box and pages in notebook. */
563 for (i = 0, curr = _repo_list; curr; curr = curr->next, i++) {
564 RepoData *rd = (RepoData *) curr->data;
565 RepoEditInfo *rei = repoman_dialog_add_repo(&rmi, g_strdup(rd->name));
567 /* Initialize fields with data from the RepoData object. */
568 gtk_entry_set_text(GTK_ENTRY(rei->txt_url), rd->url);
569 gtk_entry_set_text(GTK_ENTRY(rei->txt_cache_dir), rd->cache_dir);
570 hildon_controlbar_set_value(HILDON_CONTROLBAR(rei->num_dl_zoom_steps), rd->dl_zoom_steps);
571 hildon_controlbar_set_value(HILDON_CONTROLBAR(rei->num_view_zoom_steps), rd->view_zoom_steps);
572 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rei->chk_double_size), rd->double_size);
573 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rei->chk_nextable), rd->nextable);
574 if (rd == _curr_repo)
578 /* Connect signals. */
579 g_signal_connect(G_OBJECT(btn_rename), "clicked", G_CALLBACK(repoman_dialog_rename), &rmi);
580 g_signal_connect(G_OBJECT(btn_delete), "clicked", G_CALLBACK(repoman_dialog_delete), &rmi);
581 g_signal_connect(G_OBJECT(btn_new), "clicked", G_CALLBACK(repoman_dialog_new), &rmi);
582 g_signal_connect(G_OBJECT(rmi.cmb_repos), "changed", G_CALLBACK(repoman_dialog_select), &rmi);
583 gtk_combo_box_set_active(GTK_COMBO_BOX(rmi.cmb_repos), curr_repo_index);
584 gtk_notebook_set_current_page(GTK_NOTEBOOK(rmi.notebook), curr_repo_index);
586 gtk_widget_show_all(rmi.dialog);
588 while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(rmi.dialog))) {
589 /* Iterate through repos and verify each. */
590 gboolean verified = TRUE;
593 gchar *old_curr_repo_name = _curr_repo->name;
595 for (i = 0, curr = rmi.repo_edits;
596 verified && curr; curr = curr->next, i++) {
597 RepoEditInfo *rei = curr->data;
598 gchar *expanded = gnome_vfs_expand_initial_tilde(gtk_entry_get_text(GTK_ENTRY(rei->txt_cache_dir)));
599 verified = repo_make_cache_dir(rei->name, expanded, rmi.dialog);
603 gtk_combo_box_set_active(GTK_COMBO_BOX(rmi.cmb_repos), i - 1);
609 /* But keep the repo list in memory, in case downloads are using it. */
612 /* Write new _repo_list. */
613 curr_repo_index = gtk_combo_box_get_active(GTK_COMBO_BOX(rmi.cmb_repos));
615 for (i = 0, curr = rmi.repo_edits; curr; curr = curr->next, i++) {
616 RepoEditInfo *rei = curr->data;
617 RepoData *rd = g_new(RepoData, 1);
618 rd->name = g_strdup(rei->name);
619 rd->url = g_strdup(gtk_entry_get_text(GTK_ENTRY(rei->txt_url)));
620 rd->cache_dir = gnome_vfs_expand_initial_tilde(gtk_entry_get_text(GTK_ENTRY(rei->txt_cache_dir)));
621 rd->dl_zoom_steps = hildon_controlbar_get_value(HILDON_CONTROLBAR(rei->num_dl_zoom_steps));
622 rd->view_zoom_steps = hildon_controlbar_get_value(HILDON_CONTROLBAR(rei->num_view_zoom_steps));
623 rd->double_size = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rei->chk_double_size));
624 rd->nextable = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rei->chk_nextable));
627 _repo_list = g_list_append(_repo_list, rd);
629 if (!_curr_repo && !strcmp(old_curr_repo_name, rd->name))
631 else if (i == curr_repo_index)
635 repo_set_curr((RepoData *) g_list_first(_repo_list)->data);
637 menu_maps_add_repos();
643 gtk_widget_hide(rmi.dialog); /* Destroying causes a crash (!?!?!??!) */
645 map_set_zoom(_zoom); /* make sure we're at an appropriate zoom level. */
651 mapman_by_area(gfloat start_lat, gfloat start_lon,
652 gfloat end_lat, gfloat end_lon, MapmanInfo * mapman_info,
653 gboolean is_deleting, gboolean is_overwriting)
655 guint start_unitx, start_unity, end_unitx, end_unity;
661 latlon2unit(start_lat, start_lon, start_unitx, start_unity);
662 latlon2unit(end_lat, end_lon, end_unitx, end_unity);
664 /* Swap if they specified flipped lats or lons. */
665 if (start_unitx > end_unitx) {
666 guint swap = start_unitx;
667 start_unitx = end_unitx;
670 if (start_unity > end_unity) {
671 guint swap = start_unity;
672 start_unity = end_unity;
676 /* First, get the number of maps to download. */
677 for (i = 0; i < MAX_ZOOM; i++) {
678 if (gtk_toggle_button_get_active
679 (GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[i]))) {
680 guint start_tilex, start_tiley, end_tilex, end_tiley;
681 start_tilex = unit2ztile(start_unitx, i);
682 start_tiley = unit2ztile(start_unity, i);
683 end_tilex = unit2ztile(end_unitx, i);
684 end_tiley = unit2ztile(end_unity, i);
685 num_maps += (end_tilex - start_tilex + 1)
686 * (end_tiley - start_tiley + 1);
691 g_snprintf(buffer, sizeof(buffer), "%s %d %s",
692 _("Confirm DELETION of"), num_maps, _("maps "));
694 g_snprintf(buffer, sizeof(buffer),
695 "%s %d %s\n(%s %.2f MB)\n", _("Confirm download of"),
696 num_maps, _("maps"), _("up to about"),
698 (strstr(_curr_repo->url, "%s") ? 18e-3 : 6e-3));
700 confirm = hildon_note_new_confirmation(GTK_WINDOW(mapman_info->dialog), buffer);
702 if (GTK_RESPONSE_OK != gtk_dialog_run(GTK_DIALOG(confirm))) {
703 gtk_widget_destroy(confirm);
706 for (i = 0; i < MAX_ZOOM; i++) {
707 if (gtk_toggle_button_get_active
708 (GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[i]))) {
709 guint start_tilex, start_tiley, end_tilex, end_tiley;
711 start_tilex = unit2ztile(start_unitx, i);
712 start_tiley = unit2ztile(start_unity, i);
713 end_tilex = unit2ztile(end_unitx, i);
714 end_tiley = unit2ztile(end_unity, i);
715 for (tiley = start_tiley; tiley <= end_tiley; tiley++)
716 for (tilex = start_tilex; tilex <= end_tilex;
718 map_initiate_download(tilex, tiley, i,
722 -INITIAL_DOWNLOAD_RETRIES
724 INITIAL_DOWNLOAD_RETRIES));
727 gtk_widget_destroy(confirm);
732 mapman_by_route(MapmanInfo * mapman_info,
733 gboolean is_deleting, gboolean is_overwriting)
736 guint prev_tilex, prev_tiley, num_maps = 0, i;
739 guint radius = hildon_number_editor_get_value(HILDON_NUMBER_EDITOR(mapman_info->num_route_radius));
741 /* First, get the number of maps to download. */
742 for (i = 0; i < MAX_ZOOM; i++) {
743 if (gtk_toggle_button_get_active
744 (GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[i]))) {
747 for (curr = _route.head - 1; curr++ != _route.tail;) {
750 unit2ztile(curr->unitx, i);
752 unit2ztile(curr->unity, i);
753 if (tilex != prev_tilex
754 || tiley != prev_tiley) {
772 num_maps *= 0.625 * pow(radius + 1, 1.85);
775 g_snprintf(buffer, sizeof(buffer), "%s %s %d %s",
776 _("Confirm DELETION of"), _("about"),
777 num_maps, _("maps "));
779 g_snprintf(buffer, sizeof(buffer),
780 "%s %s %d %s\n(%s %.2f MB)\n",
781 _("Confirm download of"), _("about"), num_maps,
782 _("maps"), _("up to about"),
784 (strstr(_curr_repo->url, "%s") ? 18e-3 : 6e-3));
787 hildon_note_new_confirmation(GTK_WINDOW(mapman_info->dialog),
790 if (GTK_RESPONSE_OK != gtk_dialog_run(GTK_DIALOG(confirm))) {
791 gtk_widget_destroy(confirm);
795 /* Now, do the actual download. */
796 for (i = 0; i < MAX_ZOOM; i++) {
797 if (gtk_toggle_button_get_active
798 (GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[i]))) {
801 for (curr = _route.head - 1; curr++ != _route.tail;) {
804 unit2ztile(curr->unitx, i);
806 unit2ztile(curr->unity, i);
807 if (tilex != prev_tilex
808 || tiley != prev_tiley) {
809 guint minx, miny, maxx, maxy, x,
811 if (prev_tiley != 0) {
812 minx = MIN(tilex, prev_tilex) - radius;
813 miny = MIN(tiley, prev_tiley) - radius;
814 maxx = MAX(tilex, prev_tilex) + radius;
815 maxy = MAX(tiley, prev_tiley) + radius;
817 minx = tilex - radius;
818 miny = tiley - radius;
819 maxx = tilex + radius;
820 maxy = tiley + radius;
822 for (x = minx; x <= maxx; x++)
825 map_initiate_download
832 -INITIAL_DOWNLOAD_RETRIES
834 INITIAL_DOWNLOAD_RETRIES));
842 _route_dl_radius = radius;
843 gtk_widget_destroy(confirm);
848 mapman_clear(GtkWidget * widget, MapmanInfo * mapman_info)
852 if (gtk_notebook_get_current_page(GTK_NOTEBOOK(mapman_info->notebook))) {
853 /* This is the second page (the "Zoom" page) - clear the checks. */
854 for (i = 0; i < MAX_ZOOM; i++)
855 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[i]), FALSE);
857 /* This is the first page (the "Area" page) - clear the text fields. */
858 gtk_entry_set_text(GTK_ENTRY(mapman_info->txt_topleft_lat), "");
859 gtk_entry_set_text(GTK_ENTRY(mapman_info->txt_topleft_lon), "");
860 gtk_entry_set_text(GTK_ENTRY(mapman_info->txt_botright_lat), "");
861 gtk_entry_set_text(GTK_ENTRY(mapman_info->txt_botright_lon), "");
866 mapman_update_state(GtkWidget * widget, MapmanInfo * mapman_info)
868 gtk_widget_set_sensitive(mapman_info->chk_overwrite,
869 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mapman_info->rad_download)));
871 if (gtk_toggle_button_get_active
872 (GTK_TOGGLE_BUTTON(mapman_info->rad_by_area)))
873 gtk_widget_show(mapman_info->tbl_area);
874 else if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(mapman_info->notebook))
876 gtk_widget_hide(mapman_info->tbl_area);
878 gtk_widget_set_sensitive(mapman_info->num_route_radius,
879 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON
880 (mapman_info->rad_by_route)));
883 gboolean menu_cb_mapman(GtkAction * action)
891 GtkWidget *lbl_gps_lat;
892 GtkWidget *lbl_gps_lon;
893 GtkWidget *lbl_center_lat;
894 GtkWidget *lbl_center_lon;
895 MapmanInfo mapman_info;
900 mapman_info.dialog = dialog = gtk_dialog_new_with_buttons(_("Manage Maps"), GTK_WINDOW(_window),
901 GTK_DIALOG_MODAL, GTK_STOCK_OK,
902 GTK_RESPONSE_ACCEPT, NULL);
904 help_dialog_help_enable(GTK_DIALOG(mapman_info.dialog), HELP_ID_MAPMAN);
907 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
908 button = gtk_button_new_with_label(_("Clear")));
909 g_signal_connect(G_OBJECT(button), "clicked",
910 G_CALLBACK(mapman_clear), &mapman_info);
913 gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
915 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
916 mapman_info.notebook = gtk_notebook_new(), TRUE, TRUE, 0);
919 gtk_notebook_append_page(GTK_NOTEBOOK(mapman_info.notebook),
920 vbox = gtk_vbox_new(FALSE, 2),
921 label = gtk_label_new(_("Setup")));
922 gtk_notebook_set_tab_label_packing(GTK_NOTEBOOK(mapman_info.notebook),
923 vbox, FALSE, FALSE, GTK_PACK_START);
925 gtk_box_pack_start(GTK_BOX(vbox),
926 hbox = gtk_hbox_new(FALSE, 4), FALSE, FALSE, 0);
927 gtk_box_pack_start(GTK_BOX(hbox),
928 mapman_info.rad_download = gtk_radio_button_new_with_label(NULL, _("Download Maps")), FALSE, FALSE, 0);
929 gtk_box_pack_start(GTK_BOX(hbox), label =
930 gtk_alignment_new(0.f, 0.5f, 0.f, 0.f), FALSE, FALSE,
932 gtk_container_add(GTK_CONTAINER(label), mapman_info.chk_overwrite =
933 gtk_check_button_new_with_label(_("Overwrite"))),
934 gtk_box_pack_start(GTK_BOX(vbox), mapman_info.rad_delete =
935 gtk_radio_button_new_with_label_from_widget
936 (GTK_RADIO_BUTTON(mapman_info.rad_download),
937 _("Delete Maps")), FALSE, FALSE, 0);
939 gtk_box_pack_start(GTK_BOX(vbox),
940 gtk_hseparator_new(), FALSE, FALSE, 0);
942 gtk_box_pack_start(GTK_BOX(vbox),
943 mapman_info.rad_by_area
944 = gtk_radio_button_new_with_label(NULL, _("By Area (see tab)")), FALSE, FALSE, 0);
945 gtk_box_pack_start(GTK_BOX(vbox), hbox =
946 gtk_hbox_new(FALSE, 4), FALSE, FALSE, 0);
947 gtk_box_pack_start(GTK_BOX(hbox), mapman_info.rad_by_route =
948 gtk_radio_button_new_with_label_from_widget
949 (GTK_RADIO_BUTTON(mapman_info.rad_by_area),
950 _("Along Route - Radius (tiles):")), FALSE, FALSE,
952 gtk_widget_set_sensitive(mapman_info.rad_by_route,
953 _route.head != _route.tail);
954 gtk_box_pack_start(GTK_BOX(hbox), mapman_info.num_route_radius =
955 hildon_number_editor_new(0, 100), FALSE, FALSE, 0);
956 hildon_number_editor_set_value(HILDON_NUMBER_EDITOR
957 (mapman_info.num_route_radius),
961 gtk_notebook_append_page(GTK_NOTEBOOK(mapman_info.notebook),
962 table = gtk_table_new(5, 5, FALSE),
963 label = gtk_label_new(_("Zoom")));
964 gtk_notebook_set_tab_label_packing(GTK_NOTEBOOK(mapman_info.notebook),
965 table, FALSE, FALSE, GTK_PACK_START);
966 gtk_table_attach(GTK_TABLE(table), label =
968 ("Zoom Levels to Download: (0 = most detail)")),
969 0, 4, 0, 1, GTK_FILL, 0, 4, 0);
970 gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f);
971 for (i = 0; i < MAX_ZOOM; i++) {
972 g_snprintf(buffer, sizeof(buffer), "%d", i);
973 gtk_table_attach(GTK_TABLE(table),
974 mapman_info.chk_zoom_levels[i]
975 = gtk_check_button_new_with_label(buffer),
976 i % 4, i % 4 + 1, i / 4 + 1, i / 4 + 2,
977 GTK_EXPAND | GTK_FILL, 0, 4, 0);
981 gtk_notebook_append_page(GTK_NOTEBOOK(mapman_info.notebook),
982 mapman_info.tbl_area =
983 gtk_table_new(3, 4, FALSE), label =
984 gtk_label_new(_("Area")));
987 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
988 label = gtk_label_new(_("Latitude")),
989 1, 2, 0, 1, GTK_FILL, 0, 4, 0);
990 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
991 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
992 label = gtk_label_new(_("Longitude")),
993 2, 3, 0, 1, GTK_FILL, 0, 4, 0);
994 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
997 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
998 label = gtk_label_new(_("GPS Location")),
999 0, 1, 1, 2, GTK_FILL, 0, 4, 0);
1000 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1001 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
1002 lbl_gps_lat = gtk_label_new(""),
1003 1, 2, 1, 2, GTK_FILL, 0, 4, 0);
1004 gtk_label_set_selectable(GTK_LABEL(lbl_gps_lat), TRUE);
1005 gtk_misc_set_alignment(GTK_MISC(lbl_gps_lat), 1.f, 0.5f);
1006 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
1007 lbl_gps_lon = gtk_label_new(""),
1008 2, 3, 1, 2, GTK_FILL, 0, 4, 0);
1009 gtk_label_set_selectable(GTK_LABEL(lbl_gps_lon), TRUE);
1010 gtk_misc_set_alignment(GTK_MISC(lbl_gps_lon), 1.f, 0.5f);
1013 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
1014 label = gtk_label_new(_("View Center")),
1015 0, 1, 2, 3, GTK_FILL, 0, 4, 0);
1016 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1017 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
1018 lbl_center_lat = gtk_label_new(""),
1019 1, 2, 2, 3, GTK_FILL, 0, 4, 0);
1020 gtk_label_set_selectable(GTK_LABEL(lbl_center_lat), TRUE);
1021 gtk_misc_set_alignment(GTK_MISC(lbl_center_lat), 1.f, 0.5f);
1022 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
1023 lbl_center_lon = gtk_label_new(""),
1024 2, 3, 2, 3, GTK_FILL, 0, 4, 0);
1025 gtk_label_set_selectable(GTK_LABEL(lbl_center_lon), TRUE);
1026 gtk_misc_set_alignment(GTK_MISC(lbl_center_lon), 1.f, 0.5f);
1028 /* default values for Top Left and Bottom Right are defined by the
1029 * rectangle of the current and the previous Center */
1032 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
1033 label = gtk_label_new(_("Top-Left")),
1034 0, 1, 3, 4, GTK_FILL, 0, 4, 0);
1035 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1036 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
1037 mapman_info.txt_topleft_lat = gtk_entry_new(),
1038 1, 2, 3, 4, GTK_EXPAND | GTK_FILL, 0, 4, 0);
1039 gtk_entry_set_alignment(GTK_ENTRY(mapman_info.txt_topleft_lat), 1.f);
1040 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
1041 mapman_info.txt_topleft_lon = gtk_entry_new(),
1042 2, 3, 3, 4, GTK_EXPAND | GTK_FILL, 0, 4, 0);
1043 gtk_entry_set_alignment(GTK_ENTRY(mapman_info.txt_topleft_lon), 1.f);
1046 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
1047 label = gtk_label_new(_("Bottom-Right")),
1048 0, 1, 4, 5, GTK_FILL, 0, 4, 0);
1049 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1050 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
1051 mapman_info.txt_botright_lat = gtk_entry_new(),
1052 1, 2, 4, 5, GTK_EXPAND | GTK_FILL, 0, 4, 0);
1053 gtk_entry_set_alignment(GTK_ENTRY(mapman_info.txt_botright_lat), 1.f);
1054 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
1055 mapman_info.txt_botright_lon = gtk_entry_new(),
1056 2, 3, 4, 5, GTK_EXPAND | GTK_FILL, 0, 4, 0);
1057 gtk_entry_set_alignment(GTK_ENTRY(mapman_info.txt_botright_lon), 1.f);
1059 #if defined(WITH_DEVICE_770) && !defined(WITH_HILDON_NEW)
1060 /* Set hildon input hints */
1061 g_object_set(G_OBJECT(mapman_info.txt_topleft_lon),
1062 HILDON_INPUT_MODE_HINT,
1063 HILDON_INPUT_MODE_HINT_NUMERICSPECIAL, NULL);
1064 g_object_set(G_OBJECT(mapman_info.txt_topleft_lat),
1065 HILDON_INPUT_MODE_HINT,
1066 HILDON_INPUT_MODE_HINT_NUMERICSPECIAL, NULL);
1067 g_object_set(G_OBJECT(mapman_info.txt_botright_lon),
1068 HILDON_INPUT_MODE_HINT,
1069 HILDON_INPUT_MODE_HINT_NUMERICSPECIAL, NULL);
1070 g_object_set(G_OBJECT(mapman_info.txt_botright_lat),
1071 HILDON_INPUT_MODE_HINT,
1072 HILDON_INPUT_MODE_HINT_NUMERICSPECIAL, NULL);
1075 /* Default action is to download by area. */
1076 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mapman_info.rad_by_area), TRUE);
1078 /* Initialize fields. Do no use g_ascii_formatd; these strings will be
1079 * output (and parsed) as locale-dependent. */
1081 g_snprintf(buffer, sizeof(buffer), "%.06f", _gps->data.lat);
1082 gtk_label_set_text(GTK_LABEL(lbl_gps_lat), buffer);
1083 g_snprintf(buffer, sizeof(buffer), "%.06f", _gps->data.lon);
1084 gtk_label_set_text(GTK_LABEL(lbl_gps_lon), buffer);
1086 unit2latlon(_center.unitx, _center.unity, lat, lon);
1087 g_snprintf(buffer, sizeof(buffer), "%.06f", lat);
1088 gtk_label_set_text(GTK_LABEL(lbl_center_lat), buffer);
1089 g_snprintf(buffer, sizeof(buffer), "%.06f", lon);
1090 gtk_label_set_text(GTK_LABEL(lbl_center_lon), buffer);
1092 /* Initialize to the bounds of the screen. */
1093 unit2latlon(x2unit(0), y2unit(0), lat, lon);
1094 g_snprintf(buffer, sizeof(buffer), "%.06f", lat);
1095 gtk_entry_set_text(GTK_ENTRY(mapman_info.txt_topleft_lat), buffer);
1096 g_snprintf(buffer, sizeof(buffer), "%.06f", lon);
1097 gtk_entry_set_text(GTK_ENTRY(mapman_info.txt_topleft_lon), buffer);
1099 unit2latlon(x2unit(_screen_width_pixels), y2unit(_screen_height_pixels), lat, lon);
1100 g_snprintf(buffer, sizeof(buffer), "%.06f", lat);
1101 gtk_entry_set_text(GTK_ENTRY(mapman_info.txt_botright_lat), buffer);
1102 g_snprintf(buffer, sizeof(buffer), "%.06f", lon);
1103 gtk_entry_set_text(GTK_ENTRY(mapman_info.txt_botright_lon), buffer);
1105 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mapman_info.chk_zoom_levels[_zoom]), TRUE);
1107 gtk_widget_show_all(dialog);
1109 mapman_update_state(NULL, &mapman_info);
1111 /* Connect signals. */
1112 if (_curr_repo->type != REPOTYPE_NONE) {
1113 g_signal_connect(G_OBJECT(mapman_info.rad_download), "clicked", G_CALLBACK(mapman_update_state), &mapman_info);
1114 gtk_widget_set_sensitive(mapman_info.rad_download, TRUE);
1116 gtk_widget_set_sensitive(mapman_info.rad_download, FALSE);
1117 popup_error(dialog, _("NOTE: You must set a Map URI in the current repository in order to download maps."));
1120 g_signal_connect(G_OBJECT(mapman_info.rad_delete), "clicked", G_CALLBACK(mapman_update_state), &mapman_info);
1121 g_signal_connect(G_OBJECT(mapman_info.rad_by_area), "clicked", G_CALLBACK(mapman_update_state), &mapman_info);
1122 g_signal_connect(G_OBJECT(mapman_info.rad_by_route), "clicked", G_CALLBACK(mapman_update_state), &mapman_info);
1124 while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog))) {
1125 gboolean is_deleting = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mapman_info.rad_delete));
1126 gboolean is_overwriting = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mapman_info.chk_overwrite));
1127 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mapman_info.rad_by_route))) {
1128 if (mapman_by_route(&mapman_info, is_deleting, is_overwriting))
1133 gfloat start_lat, start_lon, end_lat, end_lon;
1135 text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_topleft_lat));
1136 start_lat = strtof(text, &error_check);
1137 if (text == error_check || start_lat < -90.f || start_lat > 90.f) {
1138 popup_error(dialog, _("Invalid Top-Left Latitude"));
1142 text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_topleft_lon));
1143 start_lon = strtof(text, &error_check);
1144 if (text == error_check || start_lon < -180.f || start_lon > 180.f) {
1145 popup_error(dialog, _("Invalid Top-Left Longitude"));
1149 text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_botright_lat));
1150 end_lat = strtof(text, &error_check);
1151 if (text == error_check || end_lat < -90.f || end_lat > 90.f) {
1152 popup_error(dialog, _("Invalid Bottom-Right Latitude"));
1156 text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_botright_lon));
1157 end_lon = strtof(text, &error_check);
1158 if (text == error_check || end_lon < -180.f || end_lon > 180.f) {
1159 popup_error(dialog, _("Invalid Bottom-Right Longitude"));
1163 if (mapman_by_area(start_lat, start_lon, end_lat, end_lon, &mapman_info, is_deleting, is_overwriting))
1168 gtk_widget_hide(dialog); /* Destroying causes a crash (!?!?!??!) */