Contents of /trunk/src/area_edit.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 206 - (hide 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 harbaum 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 harbaum 200 #include "osm-gps-map.h"
22 harbaum 1
23 harbaum 205 /* limit of square kilometers above the warning is enabled */
24     #define WARN_OVER 5.0
25    
26 harbaum 1 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 harbaum 205 GtkWidget *warning;
32 harbaum 1
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 harbaum 200 #ifdef USE_HILDON
43 harbaum 1 struct {
44     GtkWidget *fetch;
45     } mmapper;
46 harbaum 200 #endif
47 harbaum 1
48 harbaum 200 struct {
49     GtkWidget *widget;
50     GtkWidget *zoomin, *zoomout;
51 harbaum 204 gboolean needs_redraw;
52 harbaum 200 } map;
53    
54 harbaum 1 } context_t;
55    
56 harbaum 205 static void parse_and_set_lat(GtkWidget *src, pos_float_t *store) {
57 harbaum 9 pos_float_t i = pos_parse_lat((char*)gtk_entry_get_text(GTK_ENTRY(src)));
58 harbaum 205 if(pos_lat_valid(i))
59 harbaum 1 *store = i;
60     }
61    
62 harbaum 205 static void parse_and_set_lon(GtkWidget *src, pos_float_t *store) {
63 harbaum 9 pos_float_t i = pos_parse_lon((char*)gtk_entry_get_text(GTK_ENTRY(src)));
64 harbaum 205 if(pos_lon_valid(i))
65 harbaum 1 *store = i;
66     }
67    
68 harbaum 204 #define LOG2(x) (log(x) / log(2))
69 harbaum 203
70 harbaum 205 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 harbaum 204 /* the contents of the map tab have been changed */
113     static void map_update(context_t *context, gboolean forced) {
114 harbaum 203
115 harbaum 204 /* map is first tab (page 0) */
116 harbaum 205 if(!forced &&
117     gtk_notebook_get_current_page(GTK_NOTEBOOK(context->notebook)) != 0) {
118 harbaum 204 context->map.needs_redraw = TRUE;
119     return;
120     }
121 harbaum 203
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 harbaum 205 /* we know the widgets pixel size, we know the required real size, */
126     /* we want the zoom! */
127 harbaum 204 double vzoom = LOG2((45.0 * context->map.widget->allocation.height)/
128     ((context->max.lat - context->min.lat)*32.0));
129 harbaum 203
130 harbaum 204 double hzoom = LOG2((45.0 * context->map.widget->allocation.width)/
131     ((context->max.lon - context->min.lon)*32.0));
132    
133 harbaum 203 osm_gps_map_set_center(OSM_GPS_MAP(context->map.widget),
134     center_lat, center_lon);
135    
136 harbaum 204 osm_gps_map_set_zoom(OSM_GPS_MAP(context->map.widget), (hzoom+vzoom+0.5)/2);
137    
138     context->map.needs_redraw = FALSE;
139 harbaum 203 }
140    
141     static gboolean on_map_configure(GtkWidget *widget,
142     GdkEventConfigure *event,
143     context_t *context) {
144 harbaum 204 map_update(context, FALSE);
145 harbaum 203 return FALSE;
146     }
147    
148 harbaum 1 /* 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 harbaum 9 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 harbaum 1
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 harbaum 204 /* direct is second tab (page 1) */
178     if(gtk_notebook_get_current_page(GTK_NOTEBOOK(context->notebook)) != 1)
179 harbaum 1 return;
180    
181     /* parse the fields from the direct entry pad */
182 harbaum 205 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 harbaum 1
187 harbaum 205 area_main_update(context);
188    
189 harbaum 1 /* 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 harbaum 204 /* extent is third tab (page 2) */
197     if(gtk_notebook_get_current_page(GTK_NOTEBOOK(context->notebook)) != 2)
198 harbaum 1 return;
199    
200 harbaum 9 pos_float_t center_lat = pos_lat_get(context->extent.lat);
201     pos_float_t center_lon = pos_lon_get(context->extent.lon);
202 harbaum 1
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 harbaum 205
216 harbaum 1 width /= 2 * hscale;
217     context->min.lon = center_lon - width;
218     context->max.lon = center_lon + width;
219 harbaum 205
220     area_main_update(context);
221 harbaum 1
222     /* also update other tabs */
223     direct_update(context);
224 harbaum 204 map_update(context, FALSE);
225 harbaum 1 }
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 harbaum 204 /* maemo mapper is fourth tab (page 3) */
267     if(gtk_notebook_get_current_page(GTK_NOTEBOOK(context->notebook)) != 3)
268 harbaum 1 return;
269    
270     /* maemo mapper pos data ... */
271 harbaum 9 pos_float_t center_lat = context->area->mmpos->pos.lat;
272     pos_float_t center_lon = context->area->mmpos->pos.lon;
273 harbaum 1 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 harbaum 205 area_main_update(context);
289    
290 harbaum 1 /* also update other tabs */
291     direct_update(context);
292     extent_update(context);
293 harbaum 204 map_update(context, FALSE);
294 harbaum 1 }
295     #endif
296    
297 harbaum 204 /* 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 harbaum 205 area_main_update(context);
311 harbaum 204 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 harbaum 200 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 harbaum 204
332     map_has_changed(context);
333 harbaum 200 }
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 harbaum 204 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 harbaum 1 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 harbaum 167 context.dialog =
369 harbaum 200 misc_dialog_new(MISC_DIALOG_HIGH, _("Area editor"),
370 harbaum 167 GTK_WINDOW(area->parent),
371 harbaum 1 GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
372     GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
373     NULL);
374    
375 harbaum 205 GtkWidget *table = gtk_table_new(5, 2, FALSE); // x, y
376 harbaum 1
377 harbaum 203 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 harbaum 1
386 harbaum 203 label = gtk_label_new(_("Longitude:"));
387     misc_table_attach(table, label, 0, 1);
388 harbaum 1 context.minlon = pos_lon_label_new(area->min->lon);
389 harbaum 203 misc_table_attach(table, context.minlon, 1, 1);
390     label = gtk_label_new(_("to"));
391     misc_table_attach(table, label, 2, 1);
392 harbaum 1 context.maxlon = pos_lon_label_new(area->max->lon);
393 harbaum 203 misc_table_attach(table, context.maxlon, 3, 1);
394 harbaum 1
395 harbaum 205 context.warning = gtk_button_new();
396     gtk_button_set_image(GTK_BUTTON(context.warning),
397 harbaum 206 gtk_image_new_from_stock(GTK_STOCK_DIALOG_WARNING,
398     GTK_ICON_SIZE_BUTTON));
399 harbaum 205 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 harbaum 200 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(context.dialog)->vbox),
404     table, FALSE, FALSE, 0);
405 harbaum 1
406     context.notebook = gtk_notebook_new();
407    
408 harbaum 203 /* ------------- fetch from map ------------------------ */
409    
410     GtkWidget *hbox = gtk_hbox_new(FALSE, 0);
411    
412 harbaum 204 context.map.needs_redraw = FALSE;
413 harbaum 203 context.map.widget = g_object_new(OSM_TYPE_GPS_MAP,
414 harbaum 204 "repo-uri", MAP_SOURCE_OPENSTREETMAP,
415 harbaum 203 "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 harbaum 204 g_signal_connect(G_OBJECT(context.map.widget), "button-release-event",
421     G_CALLBACK(on_map_button_release_event), &context);
422 harbaum 203
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 harbaum 1 /* ------------ direct min/max edit --------------- */
448    
449 harbaum 203 vbox = gtk_vbox_new(FALSE, 10);
450 harbaum 1 table = gtk_table_new(3, 3, FALSE); // x, y
451 harbaum 204 gtk_table_set_col_spacings(GTK_TABLE(table), 10);
452     gtk_table_set_row_spacings(GTK_TABLE(table), 5);
453 harbaum 1
454 harbaum 203 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 harbaum 1 context.direct.minlon = pos_lon_entry_new(area->min->lon);
462 harbaum 203 misc_table_attach(table, context.direct.minlon, 0, 1);
463     label = gtk_label_new(_("to"));
464     misc_table_attach(table, label, 1, 1);
465 harbaum 1 context.direct.maxlon = pos_lon_entry_new(0.0);
466 harbaum 203 misc_table_attach(table, context.direct.maxlon, 2, 1);
467 harbaum 1
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 harbaum 200 gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
486 harbaum 1 gtk_notebook_append_page(GTK_NOTEBOOK(context.notebook),
487 harbaum 200 vbox, gtk_label_new(_("Direct")));
488 harbaum 1
489     /* ------------- center/extent edit ------------------------ */
490    
491 harbaum 200 vbox = gtk_vbox_new(FALSE, 10);
492 harbaum 1 table = gtk_table_new(3, 4, FALSE); // x, y
493 harbaum 204 gtk_table_set_col_spacings(GTK_TABLE(table), 10);
494     gtk_table_set_row_spacings(GTK_TABLE(table), 5);
495 harbaum 1
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 harbaum 204 gtk_table_set_row_spacing(GTK_TABLE(table), 0, 10);
505 harbaum 1
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 harbaum 200 gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
546 harbaum 1 gtk_notebook_append_page(GTK_NOTEBOOK(context.notebook),
547 harbaum 200 vbox, gtk_label_new(_("Extent")));
548 harbaum 1
549     #ifdef USE_HILDON
550     /* ------------- fetch from maemo mapper ------------------------ */
551    
552 harbaum 200 vbox = gtk_vbox_new(FALSE, 8);
553 harbaum 1 context.mmapper.fetch =
554     gtk_button_new_with_label(_("Get from Maemo Mapper"));
555 harbaum 200 gtk_box_pack_start(GTK_BOX(vbox), context.mmapper.fetch, FALSE, FALSE, 0);
556 harbaum 1
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 harbaum 200 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
563 harbaum 1
564    
565     gtk_notebook_append_page(GTK_NOTEBOOK(context.notebook),
566     vbox, gtk_label_new(_("Maemo Mapper")));
567     #endif
568    
569 harbaum 200 /* ------------------------------------------------------ */
570    
571 harbaum 1 gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(context.dialog)->vbox),
572     context.notebook);
573    
574 harbaum 204 g_signal_connect(G_OBJECT(context.notebook), "switch-page",
575     G_CALLBACK(on_page_switch), &context);
576 harbaum 1
577     gtk_widget_show_all(context.dialog);
578    
579 harbaum 205 area_main_update(&context);
580    
581 harbaum 1 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     }