Contents of /trunk/src/area_edit.c

Parent Directory Parent Directory | Revision Log Revision Log


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