Contents of /trunk/src/area_edit.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 206 - (show annotations)
Fri Jul 10 08:41:54 2009 UTC (14 years, 10 months ago) by harbaum
File MIME type: text/plain
File size: 20345 byte(s)
Area range warning icon and dialog
1 /*
2 * Copyright (C) 2008 Till Harbaum <till@harbaum.org>.
3 *
4 * This file is part of OSM2Go.
5 *
6 * OSM2Go is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * OSM2Go is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with OSM2Go. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "appdata.h"
21 #include "osm-gps-map.h"
22
23 /* limit of square kilometers above the warning is enabled */
24 #define WARN_OVER 5.0
25
26 typedef struct {
27 GtkWidget *dialog, *notebook;
28 area_edit_t *area;
29 pos_t min, max; /* local copy to work on */
30 GtkWidget *minlat, *maxlat, *minlon, *maxlon;
31 GtkWidget *warning;
32
33 struct {
34 GtkWidget *minlat, *maxlat, *minlon, *maxlon;
35 } direct;
36
37 struct {
38 GtkWidget *lat, *lon, *height, *width, *mil_km;
39 gboolean is_mil;
40 } extent;
41
42 #ifdef USE_HILDON
43 struct {
44 GtkWidget *fetch;
45 } mmapper;
46 #endif
47
48 struct {
49 GtkWidget *widget;
50 GtkWidget *zoomin, *zoomout;
51 gboolean needs_redraw;
52 } map;
53
54 } context_t;
55
56 static void parse_and_set_lat(GtkWidget *src, pos_float_t *store) {
57 pos_float_t i = pos_parse_lat((char*)gtk_entry_get_text(GTK_ENTRY(src)));
58 if(pos_lat_valid(i))
59 *store = i;
60 }
61
62 static void parse_and_set_lon(GtkWidget *src, pos_float_t *store) {
63 pos_float_t i = pos_parse_lon((char*)gtk_entry_get_text(GTK_ENTRY(src)));
64 if(pos_lon_valid(i))
65 *store = i;
66 }
67
68 #define LOG2(x) (log(x) / log(2))
69
70 static void on_area_warning_clicked(GtkButton *button, gpointer data) {
71 context_t *context = (context_t*)data;
72
73 /* compute area size */
74 pos_float_t center_lat = (context->max.lat + context->min.lat)/2;
75 double vscale = DEG2RAD(POS_EQ_RADIUS / 1000.0);
76 double hscale = DEG2RAD(cos(DEG2RAD(center_lat)) * POS_EQ_RADIUS / 1000.0);
77
78 double area = vscale * (context->max.lat - context->min.lat) *
79 hscale * (context->max.lon - context->min.lon);
80
81 messagef(context->dialog, _("Area size warning"),
82 _("The currently selected area is %.02f km² (%.02f mil²) in size. "
83 "This is more than the recommended %.02f km² (%.02f mil²). "
84 "This may result in a big download and slow mapping performance "
85 "in a densly mapped area (e.g. cities)!"),
86 area, area/(KMPMIL*KMPMIL),
87 WARN_OVER, WARN_OVER/(KMPMIL*KMPMIL)
88 );
89
90 }
91
92 static void area_main_update(context_t *context) {
93 pos_lat_label_set(context->minlat, context->min.lat);
94 pos_lat_label_set(context->maxlat, context->max.lat);
95 pos_lon_label_set(context->minlon, context->min.lon);
96 pos_lon_label_set(context->maxlon, context->max.lon);
97
98 /* check if area size exceeds recommended values */
99 pos_float_t center_lat = (context->max.lat + context->min.lat)/2;
100 double vscale = DEG2RAD(POS_EQ_RADIUS / 1000.0);
101 double hscale = DEG2RAD(cos(DEG2RAD(center_lat)) * POS_EQ_RADIUS / 1000.0);
102
103 double area = vscale * (context->max.lat - context->min.lat) *
104 hscale * (context->max.lon - context->min.lon);
105
106 if(area > WARN_OVER)
107 gtk_widget_show(context->warning);
108 else
109 gtk_widget_hide(context->warning);
110 }
111
112 /* the contents of the map tab have been changed */
113 static void map_update(context_t *context, gboolean forced) {
114
115 /* map is first tab (page 0) */
116 if(!forced &&
117 gtk_notebook_get_current_page(GTK_NOTEBOOK(context->notebook)) != 0) {
118 context->map.needs_redraw = TRUE;
119 return;
120 }
121
122 pos_float_t center_lat = (context->max.lat + context->min.lat)/2;
123 pos_float_t center_lon = (context->max.lon + context->min.lon)/2;
124
125 /* we know the widgets pixel size, we know the required real size, */
126 /* we want the zoom! */
127 double vzoom = LOG2((45.0 * context->map.widget->allocation.height)/
128 ((context->max.lat - context->min.lat)*32.0));
129
130 double hzoom = LOG2((45.0 * context->map.widget->allocation.width)/
131 ((context->max.lon - context->min.lon)*32.0));
132
133 osm_gps_map_set_center(OSM_GPS_MAP(context->map.widget),
134 center_lat, center_lon);
135
136 osm_gps_map_set_zoom(OSM_GPS_MAP(context->map.widget), (hzoom+vzoom+0.5)/2);
137
138 context->map.needs_redraw = FALSE;
139 }
140
141 static gboolean on_map_configure(GtkWidget *widget,
142 GdkEventConfigure *event,
143 context_t *context) {
144 map_update(context, FALSE);
145 return FALSE;
146 }
147
148 /* the contents of the direct tab have been changed */
149 static void direct_update(context_t *context) {
150 pos_lat_entry_set(context->direct.minlat, context->min.lat);
151 pos_lon_entry_set(context->direct.minlon, context->min.lon);
152 pos_lat_entry_set(context->direct.maxlat, context->max.lat);
153 pos_lon_entry_set(context->direct.maxlon, context->max.lon);
154 }
155
156 /* update the contents of the extent tab */
157 static void extent_update(context_t *context) {
158 pos_float_t center_lat = (context->max.lat + context->min.lat)/2;
159 pos_float_t center_lon = (context->max.lon + context->min.lon)/2;
160
161 pos_lat_entry_set(context->extent.lat, center_lat);
162 pos_lat_entry_set(context->extent.lon, center_lon);
163
164 double vscale = DEG2RAD(POS_EQ_RADIUS / 1000.0);
165 double hscale = DEG2RAD(cos(DEG2RAD(center_lat)) * POS_EQ_RADIUS / 1000.0);
166
167 double height = vscale * (context->max.lat - context->min.lat);
168 double width = hscale * (context->max.lon - context->min.lon);
169
170 pos_dist_entry_set(context->extent.width, width, context->extent.is_mil);
171 pos_dist_entry_set(context->extent.height, height, context->extent.is_mil);
172 }
173
174 static void callback_modified_direct(GtkWidget *widget, gpointer data) {
175 context_t *context = (context_t*)data;
176
177 /* direct is second tab (page 1) */
178 if(gtk_notebook_get_current_page(GTK_NOTEBOOK(context->notebook)) != 1)
179 return;
180
181 /* parse the fields from the direct entry pad */
182 parse_and_set_lat(context->direct.minlat, &context->min.lat);
183 parse_and_set_lon(context->direct.minlon, &context->min.lon);
184 parse_and_set_lat(context->direct.maxlat, &context->max.lat);
185 parse_and_set_lon(context->direct.maxlon, &context->max.lon);
186
187 area_main_update(context);
188
189 /* also adjust other views */
190 extent_update(context);
191 }
192
193 static void callback_modified_extent(GtkWidget *widget, gpointer data) {
194 context_t *context = (context_t*)data;
195
196 /* extent is third tab (page 2) */
197 if(gtk_notebook_get_current_page(GTK_NOTEBOOK(context->notebook)) != 2)
198 return;
199
200 pos_float_t center_lat = pos_lat_get(context->extent.lat);
201 pos_float_t center_lon = pos_lon_get(context->extent.lon);
202
203 if(!pos_lat_valid(center_lat) || !pos_lon_valid(center_lon))
204 return;
205
206 double vscale = DEG2RAD(POS_EQ_RADIUS / 1000.0);
207 double hscale = DEG2RAD(cos(DEG2RAD(center_lat)) * POS_EQ_RADIUS / 1000.0);
208
209 double height = pos_dist_get(context->extent.height, context->extent.is_mil);
210 double width = pos_dist_get(context->extent.width, context->extent.is_mil);
211
212 height /= 2 * vscale;
213 context->min.lat = center_lat - height;
214 context->max.lat = center_lat + height;
215
216 width /= 2 * hscale;
217 context->min.lon = center_lon - width;
218 context->max.lon = center_lon + width;
219
220 area_main_update(context);
221
222 /* also update other tabs */
223 direct_update(context);
224 map_update(context, FALSE);
225 }
226
227 static void callback_modified_unit(GtkWidget *widget, gpointer data) {
228 context_t *context = (context_t*)data;
229
230 /* get current values */
231 double height = pos_dist_get(context->extent.height, context->extent.is_mil);
232 double width = pos_dist_get(context->extent.width, context->extent.is_mil);
233
234 /* adjust unit flag */
235 context->extent.is_mil = gtk_combo_box_get_active(
236 GTK_COMBO_BOX(context->extent.mil_km)) == 0;
237
238 /* save values */
239 pos_dist_entry_set(context->extent.width, width, context->extent.is_mil);
240 pos_dist_entry_set(context->extent.height, height, context->extent.is_mil);
241 }
242
243 #ifdef USE_HILDON
244 static void callback_fetch_mm_clicked(GtkButton *button, gpointer data) {
245 context_t *context = (context_t*)data;
246
247 printf("clicked fetch mm!\n");
248
249 if(!dbus_mm_set_position(context->area->osso_context, NULL)) {
250 errorf(context->dialog,
251 _("Unable to communicate with Maemo Mapper. "
252 "You need to have Maemo Mapper installed "
253 "to use this feature."));
254 return;
255 }
256
257 if(!context->area->mmpos->valid) {
258 errorf(context->dialog,
259 _("No valid position received yet. You need "
260 "to scroll or zoom the Maemo Mapper view "
261 "in order to force it to send its current "
262 "view position to osm2go."));
263 return;
264 }
265
266 /* maemo mapper is fourth tab (page 3) */
267 if(gtk_notebook_get_current_page(GTK_NOTEBOOK(context->notebook)) != 3)
268 return;
269
270 /* maemo mapper pos data ... */
271 pos_float_t center_lat = context->area->mmpos->pos.lat;
272 pos_float_t center_lon = context->area->mmpos->pos.lon;
273 int zoom = context->area->mmpos->zoom;
274
275 if(!pos_lat_valid(center_lat) || !pos_lon_valid(center_lon))
276 return;
277
278 double vscale = DEG2RAD(POS_EQ_RADIUS);
279 double height = 8 * (1<<zoom) / vscale;
280 context->min.lat = center_lat - height;
281 context->max.lat = center_lat + height;
282
283 double hscale = DEG2RAD(cos(DEG2RAD(center_lat)) * POS_EQ_RADIUS);
284 double width = 16 * (1<<zoom) / hscale;
285 context->min.lon = center_lon - width;
286 context->max.lon = center_lon + width;
287
288 area_main_update(context);
289
290 /* also update other tabs */
291 direct_update(context);
292 extent_update(context);
293 map_update(context, FALSE);
294 }
295 #endif
296
297 /* the user has changed the map view, update other views accordingly */
298 static void map_has_changed(context_t *context) {
299 coord_t pt1, pt2;
300
301 /* get maps bounding box */
302 osm_gps_map_get_bbox(OSM_GPS_MAP(context->map.widget), &pt1, &pt2);
303
304 context->min.lat = RAD2DEG(pt2.rlat);
305 context->max.lat = RAD2DEG(pt1.rlat);
306
307 context->min.lon = RAD2DEG(pt1.rlon);
308 context->max.lon = RAD2DEG(pt2.rlon);
309
310 area_main_update(context);
311 direct_update(context);
312 extent_update(context);
313 }
314
315 static gboolean
316 on_map_button_release_event(GtkWidget *widget,
317 GdkEventButton *event, context_t *context) {
318 map_has_changed(context);
319 return FALSE;
320 }
321
322 static void map_zoom(context_t *context, int step) {
323 int zoom;
324 OsmGpsMap *map = OSM_GPS_MAP(context->map.widget);
325 g_object_get(map, "zoom", &zoom, NULL);
326 zoom = osm_gps_map_set_zoom(map, zoom+step);
327
328 /* enable/disable zoom buttons as required */
329 gtk_widget_set_sensitive(context->map.zoomin, zoom<17);
330 gtk_widget_set_sensitive(context->map.zoomout, zoom>1);
331
332 map_has_changed(context);
333 }
334
335 static gboolean
336 cb_map_zoomin(GtkButton *button, context_t *context) {
337 map_zoom(context, +1);
338 return FALSE;
339 }
340
341 static gboolean
342 cb_map_zoomout(GtkButton *button, context_t *context) {
343 map_zoom(context, -1);
344 return FALSE;
345 }
346
347 static void on_page_switch(GtkNotebook *notebook, GtkNotebookPage *page,
348 guint page_num, context_t *context) {
349
350 /* updating the map while the user manually changes some coordinates */
351 /* may confuse the map. so we delay those updates until the map tab */
352 /* is becoming visible */
353 if((page_num == 0) && context->map.needs_redraw)
354 map_update(context, TRUE);
355 }
356
357 gboolean area_edit(area_edit_t *area) {
358 gboolean ok = FALSE;
359
360 context_t context;
361 memset(&context, 0, sizeof(context_t));
362 context.area = area;
363 context.min.lat = area->min->lat;
364 context.min.lon = area->min->lon;
365 context.max.lat = area->max->lat;
366 context.max.lon = area->max->lon;
367
368 context.dialog =
369 misc_dialog_new(MISC_DIALOG_HIGH, _("Area editor"),
370 GTK_WINDOW(area->parent),
371 GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
372 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
373 NULL);
374
375 GtkWidget *table = gtk_table_new(5, 2, FALSE); // x, y
376
377 GtkWidget *label = gtk_label_new(_("Latitude:"));
378 misc_table_attach(table, label, 0, 0);
379 context.minlat = pos_lat_label_new(area->min->lat);
380 misc_table_attach(table, context.minlat, 1, 0);
381 label = gtk_label_new(_("to"));
382 misc_table_attach(table, label, 2, 0);
383 context.maxlat = pos_lat_label_new(area->max->lat);
384 misc_table_attach(table, context.maxlat, 3, 0);
385
386 label = gtk_label_new(_("Longitude:"));
387 misc_table_attach(table, label, 0, 1);
388 context.minlon = pos_lon_label_new(area->min->lon);
389 misc_table_attach(table, context.minlon, 1, 1);
390 label = gtk_label_new(_("to"));
391 misc_table_attach(table, label, 2, 1);
392 context.maxlon = pos_lon_label_new(area->max->lon);
393 misc_table_attach(table, context.maxlon, 3, 1);
394
395 context.warning = gtk_button_new();
396 gtk_button_set_image(GTK_BUTTON(context.warning),
397 gtk_image_new_from_stock(GTK_STOCK_DIALOG_WARNING,
398 GTK_ICON_SIZE_BUTTON));
399 g_signal_connect(context.warning, "clicked",
400 G_CALLBACK(on_area_warning_clicked), &context);
401 gtk_table_attach_defaults(GTK_TABLE(table), context.warning, 4, 5, 0, 2);
402
403 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(context.dialog)->vbox),
404 table, FALSE, FALSE, 0);
405
406 context.notebook = gtk_notebook_new();
407
408 /* ------------- fetch from map ------------------------ */
409
410 GtkWidget *hbox = gtk_hbox_new(FALSE, 0);
411
412 context.map.needs_redraw = FALSE;
413 context.map.widget = g_object_new(OSM_TYPE_GPS_MAP,
414 "repo-uri", MAP_SOURCE_OPENSTREETMAP,
415 "proxy-uri", misc_get_proxy_uri(area->settings),
416 NULL);
417
418 g_signal_connect(G_OBJECT(context.map.widget), "configure-event",
419 G_CALLBACK(on_map_configure), &context);
420 g_signal_connect(G_OBJECT(context.map.widget), "button-release-event",
421 G_CALLBACK(on_map_button_release_event), &context);
422
423 gtk_box_pack_start_defaults(GTK_BOX(hbox), context.map.widget);
424
425 /* zoom button box */
426 GtkWidget *vbox = gtk_vbox_new(FALSE,0);
427
428 context.map.zoomin = gtk_button_new();
429 gtk_button_set_image(GTK_BUTTON(context.map.zoomin),
430 gtk_image_new_from_stock(GTK_STOCK_ZOOM_IN, GTK_ICON_SIZE_MENU));
431 g_signal_connect(context.map.zoomin, "clicked",
432 G_CALLBACK(cb_map_zoomin), &context);
433 gtk_box_pack_start(GTK_BOX(vbox), context.map.zoomin, FALSE, FALSE, 0);
434
435 context.map.zoomout = gtk_button_new();
436 gtk_button_set_image(GTK_BUTTON(context.map.zoomout),
437 gtk_image_new_from_stock(GTK_STOCK_ZOOM_OUT, GTK_ICON_SIZE_MENU));
438 g_signal_connect(context.map.zoomout, "clicked",
439 G_CALLBACK(cb_map_zoomout), &context);
440 gtk_box_pack_start(GTK_BOX(vbox), context.map.zoomout, FALSE, FALSE, 0);
441
442 gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
443
444 gtk_notebook_append_page(GTK_NOTEBOOK(context.notebook),
445 hbox, gtk_label_new(_("Map")));
446
447 /* ------------ direct min/max edit --------------- */
448
449 vbox = gtk_vbox_new(FALSE, 10);
450 table = gtk_table_new(3, 3, FALSE); // x, y
451 gtk_table_set_col_spacings(GTK_TABLE(table), 10);
452 gtk_table_set_row_spacings(GTK_TABLE(table), 5);
453
454 context.direct.minlat = pos_lat_entry_new(0.0);
455 misc_table_attach(table, context.direct.minlat, 0, 0);
456 label = gtk_label_new(_("to"));
457 misc_table_attach(table, label, 1, 0);
458 context.direct.maxlat = pos_lat_entry_new(0.0);
459 misc_table_attach(table, context.direct.maxlat, 2, 0);
460
461 context.direct.minlon = pos_lon_entry_new(area->min->lon);
462 misc_table_attach(table, context.direct.minlon, 0, 1);
463 label = gtk_label_new(_("to"));
464 misc_table_attach(table, label, 1, 1);
465 context.direct.maxlon = pos_lon_entry_new(0.0);
466 misc_table_attach(table, context.direct.maxlon, 2, 1);
467
468 /* setup this page */
469 direct_update(&context);
470
471 g_signal_connect(G_OBJECT(context.direct.minlat), "changed",
472 G_CALLBACK(callback_modified_direct), &context);
473 g_signal_connect(G_OBJECT(context.direct.minlon), "changed",
474 G_CALLBACK(callback_modified_direct), &context);
475 g_signal_connect(G_OBJECT(context.direct.maxlat), "changed",
476 G_CALLBACK(callback_modified_direct), &context);
477 g_signal_connect(G_OBJECT(context.direct.maxlon), "changed",
478 G_CALLBACK(callback_modified_direct), &context);
479
480
481 /* --- hint --- */
482 label = gtk_label_new(_("(recommended min/max diff <0.03 degrees)"));
483 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 3, 2, 3);
484
485 gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
486 gtk_notebook_append_page(GTK_NOTEBOOK(context.notebook),
487 vbox, gtk_label_new(_("Direct")));
488
489 /* ------------- center/extent edit ------------------------ */
490
491 vbox = gtk_vbox_new(FALSE, 10);
492 table = gtk_table_new(3, 4, FALSE); // x, y
493 gtk_table_set_col_spacings(GTK_TABLE(table), 10);
494 gtk_table_set_row_spacings(GTK_TABLE(table), 5);
495
496 label = gtk_label_new(_("Center:"));
497 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
498 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
499 context.extent.lat = pos_lat_entry_new(0.0);
500 gtk_table_attach_defaults(GTK_TABLE(table), context.extent.lat, 1, 2, 0, 1);
501 context.extent.lon = pos_lon_entry_new(0.0);
502 gtk_table_attach_defaults(GTK_TABLE(table), context.extent.lon, 2, 3, 0, 1);
503
504 gtk_table_set_row_spacing(GTK_TABLE(table), 0, 10);
505
506 label = gtk_label_new(_("Width:"));
507 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
508 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2);
509 context.extent.width = gtk_entry_new();
510 gtk_table_attach_defaults(GTK_TABLE(table), context.extent.width, 1, 2, 1, 2);
511
512 label = gtk_label_new(_("Height:"));
513 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
514 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 3);
515 context.extent.height = gtk_entry_new();
516 gtk_table_attach_defaults(GTK_TABLE(table), context.extent.height, 1, 2, 2, 3);
517
518 context.extent.mil_km = gtk_combo_box_new_text();
519 gtk_combo_box_append_text(GTK_COMBO_BOX(context.extent.mil_km), _("mi"));
520 gtk_combo_box_append_text(GTK_COMBO_BOX(context.extent.mil_km), _("km"));
521 gtk_combo_box_set_active(GTK_COMBO_BOX(context.extent.mil_km), 1); // km
522
523 gtk_table_attach(GTK_TABLE(table), context.extent.mil_km, 2, 3, 1, 3,
524 0, 0, 0, 0);
525
526 /* setup this page */
527 extent_update(&context);
528
529 /* connect signals after inital update to avoid confusion */
530 g_signal_connect(G_OBJECT(context.extent.lat), "changed",
531 G_CALLBACK(callback_modified_extent), &context);
532 g_signal_connect(G_OBJECT(context.extent.lon), "changed",
533 G_CALLBACK(callback_modified_extent), &context);
534 g_signal_connect(G_OBJECT(context.extent.width), "changed",
535 G_CALLBACK(callback_modified_extent), &context);
536 g_signal_connect(G_OBJECT(context.extent.height), "changed",
537 G_CALLBACK(callback_modified_extent), &context);
538 g_signal_connect(G_OBJECT(context.extent.mil_km), "changed",
539 G_CALLBACK(callback_modified_unit), &context);
540
541 /* --- hint --- */
542 label = gtk_label_new(_("(recommended width/height < 2km/1.25mi)"));
543 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 3, 3, 4);
544
545 gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
546 gtk_notebook_append_page(GTK_NOTEBOOK(context.notebook),
547 vbox, gtk_label_new(_("Extent")));
548
549 #ifdef USE_HILDON
550 /* ------------- fetch from maemo mapper ------------------------ */
551
552 vbox = gtk_vbox_new(FALSE, 8);
553 context.mmapper.fetch =
554 gtk_button_new_with_label(_("Get from Maemo Mapper"));
555 gtk_box_pack_start(GTK_BOX(vbox), context.mmapper.fetch, FALSE, FALSE, 0);
556
557 g_signal_connect(G_OBJECT(context.mmapper.fetch), "clicked",
558 G_CALLBACK(callback_fetch_mm_clicked), &context);
559
560 /* --- hint --- */
561 label = gtk_label_new(_("(recommended MM zoom level < 7)"));
562 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
563
564
565 gtk_notebook_append_page(GTK_NOTEBOOK(context.notebook),
566 vbox, gtk_label_new(_("Maemo Mapper")));
567 #endif
568
569 /* ------------------------------------------------------ */
570
571 gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(context.dialog)->vbox),
572 context.notebook);
573
574 g_signal_connect(G_OBJECT(context.notebook), "switch-page",
575 G_CALLBACK(on_page_switch), &context);
576
577 gtk_widget_show_all(context.dialog);
578
579 area_main_update(&context);
580
581 if(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(context.dialog))) {
582 /* copy modified values back to given storage */
583 area->min->lat = context.min.lat;
584 area->min->lon = context.min.lon;
585 area->max->lat = context.max.lat;
586 area->max->lon = context.max.lon;
587 ok = TRUE;
588 }
589
590 gtk_widget_destroy(context.dialog);
591
592 return ok;
593 }