Contents of /trunk/src/area_edit.c

Parent Directory Parent Directory | Revision Log Revision Log


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