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>
38 #include <curl/multi.h>
39 #include <gconf/gconf-client.h>
41 #include "hildon-mapper.h"
49 #include "mapper-types.h"
50 #include "map-download.h"
51 #include "ui-common.h"
55 #define MAP_REPO_LIST_URL "http://www.gnuite.com/nokia770/maemo-mapper/repos.txt"
57 typedef struct _RepoManInfo RepoManInfo;
65 typedef struct _RepoEditInfo RepoEditInfo;
66 struct _RepoEditInfo {
69 GtkWidget *txt_cache_dir;
70 GtkWidget *num_dl_zoom_steps;
71 GtkWidget *num_view_zoom_steps;
72 GtkWidget *chk_double_size;
73 GtkWidget *chk_nextable;
74 GtkWidget *btn_browse;
75 BrowseInfo browse_info;
78 typedef struct _MapmanInfo MapmanInfo;
84 /* The "Setup" tab. */
85 GtkWidget *rad_download;
86 GtkWidget *rad_delete;
87 GtkWidget *chk_overwrite;
88 GtkWidget *rad_by_area;
89 GtkWidget *rad_by_route;
90 GtkWidget *num_route_radius;
93 GtkWidget *txt_topleft_lat;
94 GtkWidget *txt_topleft_lon;
95 GtkWidget *txt_botright_lat;
96 GtkWidget *txt_botright_lon;
99 GtkWidget *chk_zoom_levels[MAX_ZOOM];
102 void set_repo_type(RepoData * repo)
104 if (repo->url && *repo->url) {
105 gchar *url = g_utf8_strdown(repo->url, -1);
107 /* Determine type of repository. */
108 if (strstr(url, "service=wms"))
109 repo->type = REPOTYPE_WMS;
110 else if (strstr(url, "%s"))
111 repo->type = REPOTYPE_QUAD_QRST;
112 else if (strstr(url, "%0d"))
113 repo->type = REPOTYPE_XYZ_INV;
114 else if (strstr(url, "%0s"))
115 repo->type = REPOTYPE_QUAD_ZERO;
117 repo->type = REPOTYPE_XYZ;
121 repo->type = REPOTYPE_NONE;
125 config_parse_repo(gchar * str)
127 /* Parse each part of a repo, delimited by newline characters:
134 gchar *token, *error_check;
136 RepoData *rd = g_new0(RepoData, 1);
139 token = strsep(&str, "\n\t");
141 rd->name = g_strdup(token);
143 /* Parse URL format. */
144 token = strsep(&str, "\n\t");
146 rd->url = g_strdup(token);
148 /* Parse cache dir. */
149 token = strsep(&str, "\n\t");
151 rd->cache_dir = gnome_vfs_expand_initial_tilde(token);
153 /* Parse download zoom steps. */
154 token = strsep(&str, "\n\t");
155 if (!token || !*token || !(rd->dl_zoom_steps = atoi(token)))
156 rd->dl_zoom_steps = 2;
158 /* Parse view zoom steps. */
159 token = strsep(&str, "\n\t");
160 if (!token || !*token || !(rd->view_zoom_steps = atoi(token)))
161 rd->view_zoom_steps = 1;
163 /* Parse double-size. */
164 token = strsep(&str, "\n\t");
166 rd->double_size = atoi(token); /* Default is zero (FALSE) */
168 /* Parse next-able. */
169 token = strsep(&str, "\n\t");
170 if (!token || !*token
171 || (rd->nextable = strtol(token, &error_check, 10), token == str))
179 repo_make_cache_dir(gchar * name, const gchar * cache_dir, GtkWidget * parent)
181 if (g_mkdir_with_parents(cache_dir, 0755)) {
182 /* Failed to create Map Cache directory. */
183 gchar buffer[BUFFER_SIZE];
184 g_snprintf(buffer, sizeof(buffer), "%s: %s",
185 _("Unable to create cache directory for repository"), name);
186 popup_error(parent, buffer);
189 return g_file_test(cache_dir, G_FILE_TEST_EXISTS);
193 repo_set_curr(RepoData * rd)
196 return repo_make_cache_dir(rd->name, rd->cache_dir, _window);
200 repoman_dialog_select(GtkWidget * widget, RepoManInfo * rmi)
202 gint curr_index = gtk_combo_box_get_active(GTK_COMBO_BOX(rmi->cmb_repos));
203 gtk_notebook_set_current_page(GTK_NOTEBOOK(rmi->notebook), curr_index);
208 repoman_dialog_browse(GtkWidget * widget, BrowseInfo * browse_info)
212 dialog = GTK_WIDGET(hildon_file_chooser_dialog_new
213 (GTK_WINDOW(browse_info->dialog),
214 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER));
216 gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(dialog), TRUE);
217 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), gtk_entry_get_text(GTK_ENTRY(browse_info->txt)));
219 if (GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(dialog))) {
220 gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
221 gtk_entry_set_text(GTK_ENTRY(browse_info->txt), filename);
225 gtk_widget_destroy(dialog);
231 repoman_dialog_rename(GtkWidget * widget, RepoManInfo * rmi)
238 dialog = gtk_dialog_new_with_buttons(_("New Name"),
239 GTK_WINDOW(rmi->dialog),
240 GTK_DIALOG_MODAL, GTK_STOCK_OK,
243 GTK_RESPONSE_REJECT, NULL);
245 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
246 hbox = gtk_hbox_new(FALSE, 4), FALSE, FALSE, 4);
248 gtk_box_pack_start(GTK_BOX(hbox),
249 label = gtk_label_new(_("Name")), FALSE, FALSE, 0);
250 gtk_box_pack_start(GTK_BOX(hbox),
251 txt_name = gtk_entry_new(), TRUE, TRUE, 0);
253 gtk_widget_show_all(dialog);
255 while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog))) {
257 gtk_combo_box_get_active(GTK_COMBO_BOX(rmi->cmb_repos));
258 RepoEditInfo *rei = g_list_nth_data(rmi->repo_edits, active);
260 rei->name = g_strdup(gtk_entry_get_text(GTK_ENTRY(txt_name)));
261 gtk_combo_box_insert_text(GTK_COMBO_BOX(rmi->cmb_repos),
262 active, g_strdup(rei->name));
263 gtk_combo_box_set_active(GTK_COMBO_BOX(rmi->cmb_repos), active);
264 gtk_combo_box_remove_text(GTK_COMBO_BOX(rmi->cmb_repos),
269 gtk_widget_destroy(dialog);
274 repoman_dialog_delete(GtkWidget * widget, RepoManInfo * rmi)
278 gint active = gtk_combo_box_get_active(GTK_COMBO_BOX(rmi->cmb_repos));
280 if (gtk_tree_model_iter_n_children
282 (gtk_combo_box_get_model(GTK_COMBO_BOX(rmi->cmb_repos))),
284 popup_error(rmi->dialog,
285 _("Cannot delete the last repository - there must be at"
286 " lease one repository."));
290 g_snprintf(buffer, sizeof(buffer), "%s:\n%s\n",
291 _("Confirm delete of repository"),
292 gtk_combo_box_get_active_text(GTK_COMBO_BOX(rmi->cmb_repos)));
293 confirm = hildon_note_new_confirmation(GTK_WINDOW(_window), buffer);
295 if (GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm))) {
296 gtk_combo_box_remove_text(GTK_COMBO_BOX(rmi->cmb_repos),
298 gtk_notebook_remove_page(GTK_NOTEBOOK(rmi->notebook), active);
299 rmi->repo_edits = g_list_remove_link(rmi->repo_edits,
300 g_list_nth(rmi->repo_edits,
302 gtk_combo_box_set_active(GTK_COMBO_BOX(rmi->cmb_repos),
306 gtk_widget_destroy(confirm);
311 static RepoEditInfo *
312 repoman_dialog_add_repo(RepoManInfo * rmi, gchar * name)
318 RepoEditInfo *rei = g_new(RepoEditInfo, 1);
323 gtk_notebook_append_page(GTK_NOTEBOOK(rmi->notebook),
324 vbox = gtk_vbox_new(FALSE, 4),
325 gtk_label_new(name));
327 gtk_box_pack_start(GTK_BOX(vbox),
328 table = gtk_table_new(2, 2, FALSE), FALSE, FALSE, 0);
329 /* Map download URI. */
330 gtk_table_attach(GTK_TABLE(table),
331 label = gtk_label_new(_("URL Format")),
332 0, 1, 0, 1, GTK_FILL, 0, 2, 4);
333 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
334 gtk_table_attach(GTK_TABLE(table),
335 rei->txt_url = gtk_entry_new(),
336 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
339 gtk_table_attach(GTK_TABLE(table),
340 label = gtk_label_new(_("Cache Dir.")),
341 0, 1, 1, 2, GTK_FILL, 0, 2, 4);
342 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
343 gtk_table_attach(GTK_TABLE(table),
344 hbox = gtk_hbox_new(FALSE, 4),
345 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
346 gtk_box_pack_start(GTK_BOX(hbox),
347 rei->txt_cache_dir = gtk_entry_new(), TRUE, TRUE, 0);
348 gtk_box_pack_start(GTK_BOX(hbox),
350 gtk_button_new_with_label(_("Browse...")), FALSE,
353 /* Initialize cache dir */
355 gchar *cache_base = gnome_vfs_expand_initial_tilde(REPO_DEFAULT_CACHE_BASE);
356 gchar *cache_dir = gnome_vfs_uri_make_full_from_relative(cache_base, name);
357 gtk_entry_set_text(GTK_ENTRY(rei->txt_cache_dir), cache_dir);
362 gtk_box_pack_start(GTK_BOX(vbox),
363 table = gtk_table_new(3, 2, FALSE), FALSE, FALSE, 0);
365 /* Download Zoom Steps. */
366 gtk_table_attach(GTK_TABLE(table),
367 label = gtk_label_new(_("Download Zoom Steps")),
368 0, 1, 0, 1, GTK_FILL, 0, 2, 4);
369 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
370 gtk_table_attach(GTK_TABLE(table),
371 label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
372 1, 2, 0, 1, GTK_FILL, 0, 2, 4);
373 gtk_container_add(GTK_CONTAINER(label),
374 rei->num_dl_zoom_steps = hildon_controlbar_new());
375 hildon_controlbar_set_range(HILDON_CONTROLBAR(rei->num_dl_zoom_steps),
377 hildon_controlbar_set_value(HILDON_CONTROLBAR(rei->num_dl_zoom_steps),
378 REPO_DEFAULT_DL_ZOOM_STEPS);
379 force_min_visible_bars(HILDON_CONTROLBAR(rei->num_dl_zoom_steps), 1);
381 /* Download Zoom Steps. */
382 gtk_table_attach(GTK_TABLE(table),
383 label = gtk_label_new(_("View Zoom Steps")),
384 0, 1, 1, 2, GTK_FILL, 0, 2, 4);
385 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
386 gtk_table_attach(GTK_TABLE(table),
387 label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
388 1, 2, 1, 2, GTK_FILL, 0, 2, 4);
389 gtk_container_add(GTK_CONTAINER(label),
390 rei->num_view_zoom_steps = hildon_controlbar_new());
391 hildon_controlbar_set_range(HILDON_CONTROLBAR(rei->num_view_zoom_steps),
393 hildon_controlbar_set_value(HILDON_CONTROLBAR(rei->num_view_zoom_steps),
394 REPO_DEFAULT_VIEW_ZOOM_STEPS);
395 force_min_visible_bars(HILDON_CONTROLBAR(rei->num_view_zoom_steps), 1);
397 gtk_table_attach(GTK_TABLE(table),
398 label = gtk_vseparator_new(),
399 2, 3, 0, 2, GTK_FILL, GTK_FILL, 4, 4);
402 gtk_table_attach(GTK_TABLE(table),
403 rei->chk_double_size =
404 gtk_check_button_new_with_label(_("Double Pixels")), 3,
405 4, 0, 1, GTK_FILL, GTK_FILL, 0, 4);
406 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rei->chk_double_size),
410 gtk_table_attach(GTK_TABLE(table),
412 gtk_check_button_new_with_label(_("Next-able")), 3, 4,
413 1, 2, GTK_FILL, GTK_FILL, 0, 4);
414 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rei->chk_nextable),
417 rmi->repo_edits = g_list_append(rmi->repo_edits, rei);
419 /* Connect signals. */
420 rei->browse_info.dialog = rmi->dialog;
421 rei->browse_info.txt = rei->txt_cache_dir;
422 g_signal_connect(G_OBJECT(rei->btn_browse), "clicked",
423 G_CALLBACK(repoman_dialog_browse), &rei->browse_info);
425 gtk_widget_show_all(vbox);
427 gtk_combo_box_append_text(GTK_COMBO_BOX(rmi->cmb_repos), name);
428 gtk_combo_box_set_active(GTK_COMBO_BOX(rmi->cmb_repos),
429 gtk_tree_model_iter_n_children(GTK_TREE_MODEL
430 (gtk_combo_box_get_model
440 repoman_dialog_new(GtkWidget * widget, RepoManInfo * rmi)
447 dialog = gtk_dialog_new_with_buttons(_("New Repository"),
448 GTK_WINDOW(rmi->dialog),
449 GTK_DIALOG_MODAL, GTK_STOCK_OK,
452 GTK_RESPONSE_REJECT, NULL);
454 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
455 hbox = gtk_hbox_new(FALSE, 4), FALSE, FALSE, 4);
457 gtk_box_pack_start(GTK_BOX(hbox),
458 label = gtk_label_new(_("Name")), FALSE, FALSE, 0);
459 gtk_box_pack_start(GTK_BOX(hbox),
460 txt_name = gtk_entry_new(), TRUE, TRUE, 0);
462 gtk_widget_show_all(dialog);
464 while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog))) {
465 repoman_dialog_add_repo(rmi,
466 g_strdup(gtk_entry_get_text
467 (GTK_ENTRY(txt_name))));
471 gtk_widget_destroy(dialog);
477 repoman_reset(GtkWidget * widget, RepoManInfo * rmi)
481 confirm = hildon_note_new_confirmation(GTK_WINDOW(_window),
482 _("Replace all repositories with the default repository?"));
484 if (GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm))) {
485 /* First, delete all existing repositories. */
486 while (rmi->repo_edits) {
487 gtk_combo_box_remove_text(GTK_COMBO_BOX(rmi->cmb_repos),
489 gtk_notebook_remove_page(GTK_NOTEBOOK(rmi->notebook),
492 g_list_remove_link(rmi->repo_edits,
493 g_list_first(rmi->repo_edits));
496 /* Now, add the default repository. */
497 repoman_dialog_add_repo(rmi, REPO_DEFAULT_NAME);
498 gtk_entry_set_text(GTK_ENTRY
499 (((RepoEditInfo *) rmi->repo_edits->data)->
500 txt_url), REPO_DEFAULT_MAP_URI);
502 gtk_combo_box_set_active(GTK_COMBO_BOX(rmi->cmb_repos), 0);
504 gtk_widget_destroy(confirm);
510 repoman_download(GtkWidget * widget, RepoManInfo * rmi)
514 confirm = hildon_note_new_confirmation(GTK_WINDOW(rmi->dialog),
515 _("Maemo Mapper will now download and add a list of "
516 "possibly-duplicate repositories from the internet. "
519 if (GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm))) {
524 GnomeVFSResult vfs_result;
526 /* Get repo config file from www.gnuite.com. */
527 if (GNOME_VFS_OK != (vfs_result = gnome_vfs_read_entire_file
528 (MAP_REPO_LIST_URL, &size, &bytes))) {
529 popup_error(rmi->dialog,
531 ("An error occurred while retrieving the repositories. "
532 "The web service may be temporarily down."));
533 g_printerr("Error while download repositories: %s\n",
534 gnome_vfs_result_to_string(vfs_result));
536 /* Parse each line as a reposotory. */
538 for (head = bytes; head && *head; head = tail) {
541 tail = strchr(head, '\n');
543 rd = config_parse_repo(head);
545 repoman_dialog_add_repo(rmi,
547 /* Initialize fields with data from the RepoData object. */
548 gtk_entry_set_text(GTK_ENTRY(rei->txt_url),
550 gtk_entry_set_text(GTK_ENTRY
551 (rei->txt_cache_dir),
553 hildon_controlbar_set_value(HILDON_CONTROLBAR
557 hildon_controlbar_set_value(HILDON_CONTROLBAR
559 num_view_zoom_steps),
562 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
566 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
574 gtk_widget_destroy(confirm);
584 GtkWidget *btn_rename;
585 GtkWidget *btn_delete;
587 GtkWidget *btn_reset;
588 GtkWidget *btn_download;
589 guint i, curr_repo_index = 0;
592 rmi.dialog = gtk_dialog_new_with_buttons(_("Manage Repositories"),
594 GTK_DIALOG_MODAL, GTK_STOCK_OK,
595 GTK_RESPONSE_ACCEPT, NULL);
597 help_dialog_help_enable(GTK_DIALOG(rmi.dialog), HELP_ID_REPOMAN);
600 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(rmi.dialog)->action_area),
601 btn_reset = gtk_button_new_with_label(_("Reset...")));
602 g_signal_connect(G_OBJECT(btn_reset), "clicked",
603 G_CALLBACK(repoman_reset), &rmi);
605 /* Download button. */
606 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(rmi.dialog)->action_area),
608 gtk_button_new_with_label(_("Download...")));
609 g_signal_connect(G_OBJECT(btn_download), "clicked",
610 G_CALLBACK(repoman_download), &rmi);
613 gtk_dialog_add_button(GTK_DIALOG(rmi.dialog),
614 GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
616 hbox = gtk_hbox_new(FALSE, 4);
618 gtk_box_pack_start(GTK_BOX(hbox),
620 gtk_combo_box_new_text(), TRUE, TRUE, 4);
622 gtk_box_pack_start(GTK_BOX(hbox),
623 gtk_vseparator_new(), FALSE, FALSE, 4);
624 gtk_box_pack_start(GTK_BOX(hbox),
626 gtk_button_new_with_label(_("Rename...")), FALSE,
628 gtk_box_pack_start(GTK_BOX(hbox), btn_delete =
629 gtk_button_new_with_label(_("Delete...")), FALSE,
631 gtk_box_pack_start(GTK_BOX(hbox), btn_new =
632 gtk_button_new_with_label(_("New...")), FALSE, FALSE,
635 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(rmi.dialog)->vbox),
636 hbox, FALSE, FALSE, 4);
638 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(rmi.dialog)->vbox),
639 gtk_hseparator_new(), TRUE, TRUE, 4);
640 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(rmi.dialog)->vbox),
641 rmi.notebook = gtk_notebook_new(), TRUE, TRUE, 4);
643 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(rmi.notebook), FALSE);
644 gtk_notebook_set_show_border(GTK_NOTEBOOK(rmi.notebook), FALSE);
646 rmi.repo_edits = NULL;
648 /* Populate combo box and pages in notebook. */
649 for (i = 0, curr = _repo_list; curr; curr = curr->next, i++) {
650 RepoData *rd = (RepoData *) curr->data;
651 RepoEditInfo *rei = repoman_dialog_add_repo(&rmi, g_strdup(rd->name));
653 /* Initialize fields with data from the RepoData object. */
654 gtk_entry_set_text(GTK_ENTRY(rei->txt_url), rd->url);
655 gtk_entry_set_text(GTK_ENTRY(rei->txt_cache_dir), rd->cache_dir);
656 hildon_controlbar_set_value(HILDON_CONTROLBAR
657 (rei->num_dl_zoom_steps),
659 hildon_controlbar_set_value(HILDON_CONTROLBAR
660 (rei->num_view_zoom_steps),
661 rd->view_zoom_steps);
662 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
663 (rei->chk_double_size),
665 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
666 (rei->chk_nextable), rd->nextable);
667 if (rd == _curr_repo)
671 /* Connect signals. */
672 g_signal_connect(G_OBJECT(btn_rename), "clicked", G_CALLBACK(repoman_dialog_rename), &rmi);
673 g_signal_connect(G_OBJECT(btn_delete), "clicked", G_CALLBACK(repoman_dialog_delete), &rmi);
674 g_signal_connect(G_OBJECT(btn_new), "clicked", G_CALLBACK(repoman_dialog_new), &rmi);
675 g_signal_connect(G_OBJECT(rmi.cmb_repos), "changed", G_CALLBACK(repoman_dialog_select), &rmi);
676 gtk_combo_box_set_active(GTK_COMBO_BOX(rmi.cmb_repos), curr_repo_index);
677 gtk_notebook_set_current_page(GTK_NOTEBOOK(rmi.notebook), curr_repo_index);
679 gtk_widget_show_all(rmi.dialog);
681 while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(rmi.dialog))) {
682 /* Iterate through repos and verify each. */
683 gboolean verified = TRUE;
686 gchar *old_curr_repo_name = _curr_repo->name;
688 for (i = 0, curr = rmi.repo_edits;
689 verified && curr; curr = curr->next, i++) {
690 RepoEditInfo *rei = curr->data;
691 gchar *expanded = gnome_vfs_expand_initial_tilde(gtk_entry_get_text(GTK_ENTRY(rei->txt_cache_dir)));
692 verified = repo_make_cache_dir(rei->name, expanded, rmi.dialog);
696 gtk_combo_box_set_active(GTK_COMBO_BOX(rmi.cmb_repos), i - 1);
702 /* But keep the repo list in memory, in case downloads are using it. */
705 /* Write new _repo_list. */
706 curr_repo_index = gtk_combo_box_get_active(GTK_COMBO_BOX(rmi.cmb_repos));
708 for (i = 0, curr = rmi.repo_edits; curr; curr = curr->next, i++) {
709 RepoEditInfo *rei = curr->data;
710 RepoData *rd = g_new(RepoData, 1);
711 rd->name = g_strdup(rei->name);
712 rd->url = g_strdup(gtk_entry_get_text(GTK_ENTRY(rei->txt_url)));
713 rd->cache_dir = gnome_vfs_expand_initial_tilde(gtk_entry_get_text(GTK_ENTRY(rei->txt_cache_dir)));
714 rd->dl_zoom_steps = hildon_controlbar_get_value(HILDON_CONTROLBAR(rei->num_dl_zoom_steps));
715 rd->view_zoom_steps = hildon_controlbar_get_value(HILDON_CONTROLBAR(rei->num_view_zoom_steps));
716 rd->double_size = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rei->chk_double_size));
717 rd->nextable = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rei->chk_nextable));
720 _repo_list = g_list_append(_repo_list, rd);
722 if (!_curr_repo && !strcmp(old_curr_repo_name, rd->name))
724 else if (i == curr_repo_index)
728 repo_set_curr((RepoData *) g_list_first(_repo_list)->data);
730 menu_maps_add_repos();
736 gtk_widget_hide(rmi.dialog); /* Destroying causes a crash (!?!?!??!) */
738 map_set_zoom(_zoom); /* make sure we're at an appropriate zoom level. */
744 mapman_by_area(gfloat start_lat, gfloat start_lon,
745 gfloat end_lat, gfloat end_lon, MapmanInfo * mapman_info,
746 gboolean is_deleting, gboolean is_overwriting)
748 guint start_unitx, start_unity, end_unitx, end_unity;
754 latlon2unit(start_lat, start_lon, start_unitx, start_unity);
755 latlon2unit(end_lat, end_lon, end_unitx, end_unity);
757 /* Swap if they specified flipped lats or lons. */
758 if (start_unitx > end_unitx) {
759 guint swap = start_unitx;
760 start_unitx = end_unitx;
763 if (start_unity > end_unity) {
764 guint swap = start_unity;
765 start_unity = end_unity;
769 /* First, get the number of maps to download. */
770 for (i = 0; i < MAX_ZOOM; i++) {
771 if (gtk_toggle_button_get_active
772 (GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[i]))) {
773 guint start_tilex, start_tiley, end_tilex, end_tiley;
774 start_tilex = unit2ztile(start_unitx, i);
775 start_tiley = unit2ztile(start_unity, i);
776 end_tilex = unit2ztile(end_unitx, i);
777 end_tiley = unit2ztile(end_unity, i);
778 num_maps += (end_tilex - start_tilex + 1)
779 * (end_tiley - start_tiley + 1);
784 g_snprintf(buffer, sizeof(buffer), "%s %d %s",
785 _("Confirm DELETION of"), num_maps, _("maps "));
787 g_snprintf(buffer, sizeof(buffer),
788 "%s %d %s\n(%s %.2f MB)\n", _("Confirm download of"),
789 num_maps, _("maps"), _("up to about"),
791 (strstr(_curr_repo->url, "%s") ? 18e-3 : 6e-3));
793 confirm = hildon_note_new_confirmation(GTK_WINDOW(mapman_info->dialog), buffer);
795 if (GTK_RESPONSE_OK != gtk_dialog_run(GTK_DIALOG(confirm))) {
796 gtk_widget_destroy(confirm);
799 for (i = 0; i < MAX_ZOOM; i++) {
800 if (gtk_toggle_button_get_active
801 (GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[i]))) {
802 guint start_tilex, start_tiley, end_tilex, end_tiley;
804 start_tilex = unit2ztile(start_unitx, i);
805 start_tiley = unit2ztile(start_unity, i);
806 end_tilex = unit2ztile(end_unitx, i);
807 end_tiley = unit2ztile(end_unity, i);
808 for (tiley = start_tiley; tiley <= end_tiley; tiley++)
809 for (tilex = start_tilex; tilex <= end_tilex;
811 map_initiate_download(tilex, tiley, i,
815 -INITIAL_DOWNLOAD_RETRIES
817 INITIAL_DOWNLOAD_RETRIES));
820 gtk_widget_destroy(confirm);
825 mapman_by_route(MapmanInfo * mapman_info,
826 gboolean is_deleting, gboolean is_overwriting)
829 guint prev_tilex, prev_tiley, num_maps = 0, i;
832 guint radius = hildon_number_editor_get_value(HILDON_NUMBER_EDITOR(mapman_info->num_route_radius));
834 /* First, get the number of maps to download. */
835 for (i = 0; i < MAX_ZOOM; i++) {
836 if (gtk_toggle_button_get_active
837 (GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[i]))) {
840 for (curr = _route.head - 1; curr++ != _route.tail;) {
843 unit2ztile(curr->unitx, i);
845 unit2ztile(curr->unity, i);
846 if (tilex != prev_tilex
847 || tiley != prev_tiley) {
865 num_maps *= 0.625 * pow(radius + 1, 1.85);
868 g_snprintf(buffer, sizeof(buffer), "%s %s %d %s",
869 _("Confirm DELETION of"), _("about"),
870 num_maps, _("maps "));
872 g_snprintf(buffer, sizeof(buffer),
873 "%s %s %d %s\n(%s %.2f MB)\n",
874 _("Confirm download of"), _("about"), num_maps,
875 _("maps"), _("up to about"),
877 (strstr(_curr_repo->url, "%s") ? 18e-3 : 6e-3));
880 hildon_note_new_confirmation(GTK_WINDOW(mapman_info->dialog),
883 if (GTK_RESPONSE_OK != gtk_dialog_run(GTK_DIALOG(confirm))) {
884 gtk_widget_destroy(confirm);
888 /* Now, do the actual download. */
889 for (i = 0; i < MAX_ZOOM; i++) {
890 if (gtk_toggle_button_get_active
891 (GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[i]))) {
894 for (curr = _route.head - 1; curr++ != _route.tail;) {
897 unit2ztile(curr->unitx, i);
899 unit2ztile(curr->unity, i);
900 if (tilex != prev_tilex
901 || tiley != prev_tiley) {
902 guint minx, miny, maxx, maxy, x,
904 if (prev_tiley != 0) {
905 minx = MIN(tilex, prev_tilex) - radius;
906 miny = MIN(tiley, prev_tiley) - radius;
907 maxx = MAX(tilex, prev_tilex) + radius;
908 maxy = MAX(tiley, prev_tiley) + radius;
910 minx = tilex - radius;
911 miny = tiley - radius;
912 maxx = tilex + radius;
913 maxy = tiley + radius;
915 for (x = minx; x <= maxx; x++)
918 map_initiate_download
925 -INITIAL_DOWNLOAD_RETRIES
927 INITIAL_DOWNLOAD_RETRIES));
935 _route_dl_radius = radius;
936 gtk_widget_destroy(confirm);
941 mapman_clear(GtkWidget * widget, MapmanInfo * mapman_info)
945 if (gtk_notebook_get_current_page(GTK_NOTEBOOK(mapman_info->notebook))) {
946 /* This is the second page (the "Zoom" page) - clear the checks. */
947 for (i = 0; i < MAX_ZOOM; i++)
948 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[i]), FALSE);
950 /* This is the first page (the "Area" page) - clear the text fields. */
951 gtk_entry_set_text(GTK_ENTRY(mapman_info->txt_topleft_lat), "");
952 gtk_entry_set_text(GTK_ENTRY(mapman_info->txt_topleft_lon), "");
953 gtk_entry_set_text(GTK_ENTRY(mapman_info->txt_botright_lat), "");
954 gtk_entry_set_text(GTK_ENTRY(mapman_info->txt_botright_lon), "");
959 mapman_update_state(GtkWidget * widget, MapmanInfo * mapman_info)
961 gtk_widget_set_sensitive(mapman_info->chk_overwrite,
962 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mapman_info->rad_download)));
964 if (gtk_toggle_button_get_active
965 (GTK_TOGGLE_BUTTON(mapman_info->rad_by_area)))
966 gtk_widget_show(mapman_info->tbl_area);
967 else if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(mapman_info->notebook))
969 gtk_widget_hide(mapman_info->tbl_area);
971 gtk_widget_set_sensitive(mapman_info->num_route_radius,
972 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON
973 (mapman_info->rad_by_route)));
976 gboolean menu_cb_mapman(GtkAction * action)
984 GtkWidget *lbl_gps_lat;
985 GtkWidget *lbl_gps_lon;
986 GtkWidget *lbl_center_lat;
987 GtkWidget *lbl_center_lon;
988 MapmanInfo mapman_info;
993 mapman_info.dialog = dialog = gtk_dialog_new_with_buttons(_("Manage Maps"), GTK_WINDOW(_window),
994 GTK_DIALOG_MODAL, GTK_STOCK_OK,
995 GTK_RESPONSE_ACCEPT, NULL);
997 help_dialog_help_enable(GTK_DIALOG(mapman_info.dialog), HELP_ID_MAPMAN);
1000 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
1001 button = gtk_button_new_with_label(_("Clear")));
1002 g_signal_connect(G_OBJECT(button), "clicked",
1003 G_CALLBACK(mapman_clear), &mapman_info);
1005 /* Cancel button. */
1006 gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
1008 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
1009 mapman_info.notebook = gtk_notebook_new(), TRUE, TRUE, 0);
1012 gtk_notebook_append_page(GTK_NOTEBOOK(mapman_info.notebook),
1013 vbox = gtk_vbox_new(FALSE, 2),
1014 label = gtk_label_new(_("Setup")));
1015 gtk_notebook_set_tab_label_packing(GTK_NOTEBOOK(mapman_info.notebook),
1016 vbox, FALSE, FALSE, GTK_PACK_START);
1018 gtk_box_pack_start(GTK_BOX(vbox),
1019 hbox = gtk_hbox_new(FALSE, 4), FALSE, FALSE, 0);
1020 gtk_box_pack_start(GTK_BOX(hbox),
1021 mapman_info.rad_download = gtk_radio_button_new_with_label(NULL, _("Download Maps")), FALSE, FALSE, 0);
1022 gtk_box_pack_start(GTK_BOX(hbox), label =
1023 gtk_alignment_new(0.f, 0.5f, 0.f, 0.f), FALSE, FALSE,
1025 gtk_container_add(GTK_CONTAINER(label), mapman_info.chk_overwrite =
1026 gtk_check_button_new_with_label(_("Overwrite"))),
1027 gtk_box_pack_start(GTK_BOX(vbox), mapman_info.rad_delete =
1028 gtk_radio_button_new_with_label_from_widget
1029 (GTK_RADIO_BUTTON(mapman_info.rad_download),
1030 _("Delete Maps")), FALSE, FALSE, 0);
1032 gtk_box_pack_start(GTK_BOX(vbox),
1033 gtk_hseparator_new(), FALSE, FALSE, 0);
1035 gtk_box_pack_start(GTK_BOX(vbox),
1036 mapman_info.rad_by_area
1037 = gtk_radio_button_new_with_label(NULL, _("By Area (see tab)")), FALSE, FALSE, 0);
1038 gtk_box_pack_start(GTK_BOX(vbox), hbox =
1039 gtk_hbox_new(FALSE, 4), FALSE, FALSE, 0);
1040 gtk_box_pack_start(GTK_BOX(hbox), mapman_info.rad_by_route =
1041 gtk_radio_button_new_with_label_from_widget
1042 (GTK_RADIO_BUTTON(mapman_info.rad_by_area),
1043 _("Along Route - Radius (tiles):")), FALSE, FALSE,
1045 gtk_widget_set_sensitive(mapman_info.rad_by_route,
1046 _route.head != _route.tail);
1047 gtk_box_pack_start(GTK_BOX(hbox), mapman_info.num_route_radius =
1048 hildon_number_editor_new(0, 100), FALSE, FALSE, 0);
1049 hildon_number_editor_set_value(HILDON_NUMBER_EDITOR
1050 (mapman_info.num_route_radius),
1054 gtk_notebook_append_page(GTK_NOTEBOOK(mapman_info.notebook),
1055 table = gtk_table_new(5, 5, FALSE),
1056 label = gtk_label_new(_("Zoom")));
1057 gtk_notebook_set_tab_label_packing(GTK_NOTEBOOK(mapman_info.notebook),
1058 table, FALSE, FALSE, GTK_PACK_START);
1059 gtk_table_attach(GTK_TABLE(table), label =
1061 ("Zoom Levels to Download: (0 = most detail)")),
1062 0, 4, 0, 1, GTK_FILL, 0, 4, 0);
1063 gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f);
1064 for (i = 0; i < MAX_ZOOM; i++) {
1065 g_snprintf(buffer, sizeof(buffer), "%d", i);
1066 gtk_table_attach(GTK_TABLE(table),
1067 mapman_info.chk_zoom_levels[i]
1068 = gtk_check_button_new_with_label(buffer),
1069 i % 4, i % 4 + 1, i / 4 + 1, i / 4 + 2,
1070 GTK_EXPAND | GTK_FILL, 0, 4, 0);
1074 gtk_notebook_append_page(GTK_NOTEBOOK(mapman_info.notebook),
1075 mapman_info.tbl_area =
1076 gtk_table_new(3, 4, FALSE), label =
1077 gtk_label_new(_("Area")));
1079 /* Label Columns. */
1080 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
1081 label = gtk_label_new(_("Latitude")),
1082 1, 2, 0, 1, GTK_FILL, 0, 4, 0);
1083 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1084 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
1085 label = gtk_label_new(_("Longitude")),
1086 2, 3, 0, 1, GTK_FILL, 0, 4, 0);
1087 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1090 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
1091 label = gtk_label_new(_("GPS Location")),
1092 0, 1, 1, 2, GTK_FILL, 0, 4, 0);
1093 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1094 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
1095 lbl_gps_lat = gtk_label_new(""),
1096 1, 2, 1, 2, GTK_FILL, 0, 4, 0);
1097 gtk_label_set_selectable(GTK_LABEL(lbl_gps_lat), TRUE);
1098 gtk_misc_set_alignment(GTK_MISC(lbl_gps_lat), 1.f, 0.5f);
1099 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
1100 lbl_gps_lon = gtk_label_new(""),
1101 2, 3, 1, 2, GTK_FILL, 0, 4, 0);
1102 gtk_label_set_selectable(GTK_LABEL(lbl_gps_lon), TRUE);
1103 gtk_misc_set_alignment(GTK_MISC(lbl_gps_lon), 1.f, 0.5f);
1106 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
1107 label = gtk_label_new(_("View Center")),
1108 0, 1, 2, 3, GTK_FILL, 0, 4, 0);
1109 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1110 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
1111 lbl_center_lat = gtk_label_new(""),
1112 1, 2, 2, 3, GTK_FILL, 0, 4, 0);
1113 gtk_label_set_selectable(GTK_LABEL(lbl_center_lat), TRUE);
1114 gtk_misc_set_alignment(GTK_MISC(lbl_center_lat), 1.f, 0.5f);
1115 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
1116 lbl_center_lon = gtk_label_new(""),
1117 2, 3, 2, 3, GTK_FILL, 0, 4, 0);
1118 gtk_label_set_selectable(GTK_LABEL(lbl_center_lon), TRUE);
1119 gtk_misc_set_alignment(GTK_MISC(lbl_center_lon), 1.f, 0.5f);
1121 /* default values for Top Left and Bottom Right are defined by the
1122 * rectangle of the current and the previous Center */
1125 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
1126 label = gtk_label_new(_("Top-Left")),
1127 0, 1, 3, 4, GTK_FILL, 0, 4, 0);
1128 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1129 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
1130 mapman_info.txt_topleft_lat = gtk_entry_new(),
1131 1, 2, 3, 4, GTK_EXPAND | GTK_FILL, 0, 4, 0);
1132 gtk_entry_set_alignment(GTK_ENTRY(mapman_info.txt_topleft_lat), 1.f);
1133 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
1134 mapman_info.txt_topleft_lon = gtk_entry_new(),
1135 2, 3, 3, 4, GTK_EXPAND | GTK_FILL, 0, 4, 0);
1136 gtk_entry_set_alignment(GTK_ENTRY(mapman_info.txt_topleft_lon), 1.f);
1139 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
1140 label = gtk_label_new(_("Bottom-Right")),
1141 0, 1, 4, 5, GTK_FILL, 0, 4, 0);
1142 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1143 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
1144 mapman_info.txt_botright_lat = gtk_entry_new(),
1145 1, 2, 4, 5, GTK_EXPAND | GTK_FILL, 0, 4, 0);
1146 gtk_entry_set_alignment(GTK_ENTRY(mapman_info.txt_botright_lat), 1.f);
1147 gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
1148 mapman_info.txt_botright_lon = gtk_entry_new(),
1149 2, 3, 4, 5, GTK_EXPAND | GTK_FILL, 0, 4, 0);
1150 gtk_entry_set_alignment(GTK_ENTRY(mapman_info.txt_botright_lon), 1.f);
1152 #if defined(WITH_DEVICE_770) && !defined(WITH_HILDON_NEW)
1153 /* Set hildon input hints */
1154 g_object_set(G_OBJECT(mapman_info.txt_topleft_lon),
1155 HILDON_INPUT_MODE_HINT,
1156 HILDON_INPUT_MODE_HINT_NUMERICSPECIAL, NULL);
1157 g_object_set(G_OBJECT(mapman_info.txt_topleft_lat),
1158 HILDON_INPUT_MODE_HINT,
1159 HILDON_INPUT_MODE_HINT_NUMERICSPECIAL, NULL);
1160 g_object_set(G_OBJECT(mapman_info.txt_botright_lon),
1161 HILDON_INPUT_MODE_HINT,
1162 HILDON_INPUT_MODE_HINT_NUMERICSPECIAL, NULL);
1163 g_object_set(G_OBJECT(mapman_info.txt_botright_lat),
1164 HILDON_INPUT_MODE_HINT,
1165 HILDON_INPUT_MODE_HINT_NUMERICSPECIAL, NULL);
1168 /* Default action is to download by area. */
1169 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mapman_info.rad_by_area), TRUE);
1171 /* Initialize fields. Do no use g_ascii_formatd; these strings will be
1172 * output (and parsed) as locale-dependent. */
1174 g_snprintf(buffer, sizeof(buffer), "%.06f", _gps->data.lat);
1175 gtk_label_set_text(GTK_LABEL(lbl_gps_lat), buffer);
1176 g_snprintf(buffer, sizeof(buffer), "%.06f", _gps->data.lon);
1177 gtk_label_set_text(GTK_LABEL(lbl_gps_lon), buffer);
1179 unit2latlon(_center.unitx, _center.unity, lat, lon);
1180 g_snprintf(buffer, sizeof(buffer), "%.06f", lat);
1181 gtk_label_set_text(GTK_LABEL(lbl_center_lat), buffer);
1182 g_snprintf(buffer, sizeof(buffer), "%.06f", lon);
1183 gtk_label_set_text(GTK_LABEL(lbl_center_lon), buffer);
1185 /* Initialize to the bounds of the screen. */
1186 unit2latlon(x2unit(0), y2unit(0), lat, lon);
1187 g_snprintf(buffer, sizeof(buffer), "%.06f", lat);
1188 gtk_entry_set_text(GTK_ENTRY(mapman_info.txt_topleft_lat), buffer);
1189 g_snprintf(buffer, sizeof(buffer), "%.06f", lon);
1190 gtk_entry_set_text(GTK_ENTRY(mapman_info.txt_topleft_lon), buffer);
1192 unit2latlon(x2unit(_screen_width_pixels), y2unit(_screen_height_pixels), lat, lon);
1193 g_snprintf(buffer, sizeof(buffer), "%.06f", lat);
1194 gtk_entry_set_text(GTK_ENTRY(mapman_info.txt_botright_lat), buffer);
1195 g_snprintf(buffer, sizeof(buffer), "%.06f", lon);
1196 gtk_entry_set_text(GTK_ENTRY(mapman_info.txt_botright_lon), buffer);
1198 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mapman_info.chk_zoom_levels[_zoom]), TRUE);
1200 gtk_widget_show_all(dialog);
1202 mapman_update_state(NULL, &mapman_info);
1204 /* Connect signals. */
1205 if (_curr_repo->type != REPOTYPE_NONE) {
1206 g_signal_connect(G_OBJECT(mapman_info.rad_download), "clicked", G_CALLBACK(mapman_update_state), &mapman_info);
1207 gtk_widget_set_sensitive(mapman_info.rad_download, TRUE);
1209 gtk_widget_set_sensitive(mapman_info.rad_download, FALSE);
1210 popup_error(dialog, _("NOTE: You must set a Map URI in the current repository in order to download maps."));
1213 g_signal_connect(G_OBJECT(mapman_info.rad_delete), "clicked", G_CALLBACK(mapman_update_state), &mapman_info);
1214 g_signal_connect(G_OBJECT(mapman_info.rad_by_area), "clicked", G_CALLBACK(mapman_update_state), &mapman_info);
1215 g_signal_connect(G_OBJECT(mapman_info.rad_by_route), "clicked", G_CALLBACK(mapman_update_state), &mapman_info);
1217 while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog))) {
1218 gboolean is_deleting = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mapman_info.rad_delete));
1219 gboolean is_overwriting = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mapman_info.chk_overwrite));
1220 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mapman_info.rad_by_route))) {
1221 if (mapman_by_route(&mapman_info, is_deleting, is_overwriting))
1226 gfloat start_lat, start_lon, end_lat, end_lon;
1228 text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_topleft_lat));
1229 start_lat = strtof(text, &error_check);
1230 if (text == error_check || start_lat < -90.f || start_lat > 90.f) {
1231 popup_error(dialog, _("Invalid Top-Left Latitude"));
1235 text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_topleft_lon));
1236 start_lon = strtof(text, &error_check);
1237 if (text == error_check || start_lon < -180.f || start_lon > 180.f) {
1238 popup_error(dialog, _("Invalid Top-Left Longitude"));
1242 text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_botright_lat));
1243 end_lat = strtof(text, &error_check);
1244 if (text == error_check || end_lat < -90.f || end_lat > 90.f) {
1245 popup_error(dialog, _("Invalid Bottom-Right Latitude"));
1249 text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_botright_lon));
1250 end_lon = strtof(text, &error_check);
1251 if (text == error_check || end_lon < -180.f || end_lon > 180.f) {
1252 popup_error(dialog, _("Invalid Bottom-Right Longitude"));
1256 if (mapman_by_area(start_lat, start_lon, end_lat, end_lon, &mapman_info, is_deleting, is_overwriting))
1261 gtk_widget_hide(dialog); /* Destroying causes a crash (!?!?!??!) */