Diff of /trunk/src/area_edit.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 9 by harbaum, Fri Dec 12 20:06:32 2008 UTC revision 248 by harbaum, Tue Jul 28 06:27:25 2009 UTC
# Line 19  Line 19 
19    
20  #include "appdata.h"  #include "appdata.h"
21    
22    #ifdef ENABLE_OSM_GPS_MAP
23    #include "osm-gps-map.h"
24    #endif
25    
26    #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    /* limit of square kilometers above the warning is enabled */
32    #define WARN_OVER  5.0
33    
34  typedef struct {  typedef struct {
35    GtkWidget *dialog, *notebook;    GtkWidget *dialog, *notebook;
36    area_edit_t *area;    area_edit_t *area;
37    pos_t min, max;      /* local copy to work on */    pos_t min, max;      /* local copy to work on */
38    GtkWidget *minlat, *maxlat, *minlon, *maxlon;    GtkWidget *minlat, *maxlat, *minlon, *maxlon;
39      GtkWidget *warning;
40    
41    struct {    struct {
42      GtkWidget *minlat, *maxlat, *minlon, *maxlon;      GtkWidget *minlat, *maxlat, *minlon, *maxlon;
# Line 34  typedef struct { Line 47  typedef struct {
47      gboolean is_mil;      gboolean is_mil;
48    } extent;    } extent;
49    
50    #ifdef USE_HILDON
51    struct {    struct {
52      GtkWidget *fetch;      GtkWidget *fetch;
53    } mmapper;    } mmapper;
54    #endif
55    
56    #ifdef ENABLE_OSM_GPS_MAP
57      struct {
58        GtkWidget *widget;
59        GtkWidget *zoomin, *zoomout, *center, *modesel, *gps;
60        gboolean needs_redraw, drag_mode;
61        gint handler_id;
62        coord_t start;
63      } map;
64    #endif
65  } context_t;  } context_t;
66    
67  static void parse_and_set_lat(GtkWidget *src, GtkWidget *dst, pos_float_t *store) {  static void parse_and_set_lat(GtkWidget *src, pos_float_t *store) {
68    pos_float_t i = pos_parse_lat((char*)gtk_entry_get_text(GTK_ENTRY(src)));    pos_float_t i = pos_parse_lat((char*)gtk_entry_get_text(GTK_ENTRY(src)));
69    if(pos_lat_valid(i)) {    if(pos_lat_valid(i))
70      *store = i;      *store = i;
     pos_lat_label_set(dst, i);  
   }  
71  }  }
72    
73  static void parse_and_set_lon(GtkWidget *src, GtkWidget *dst, pos_float_t *store) {  static void parse_and_set_lon(GtkWidget *src, pos_float_t *store) {
74    pos_float_t i = pos_parse_lon((char*)gtk_entry_get_text(GTK_ENTRY(src)));    pos_float_t i = pos_parse_lon((char*)gtk_entry_get_text(GTK_ENTRY(src)));
75    if(pos_lon_valid(i)) {    if(pos_lon_valid(i))
76      *store = i;      *store = i;
77      pos_lon_label_set(dst, i);  }
78    
79    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    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      warningf(context->dialog,
106       _("The currently selected area is %.02f km² (%.02f mi²) in size. "
107         "This is more than the recommended %.02f km² (%.02f mi²).\n\n"
108         "Continuing may result in a big download and low mapping performance "
109         "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    #ifdef ENABLE_OSM_GPS_MAP
137    #define LOG2(x) (log(x) / log(2))
138    
139    static GSList *pos_append_rad(GSList *list, pos_float_t lat, pos_float_t lon) {
140      coord_t *coo = g_new0(coord_t, 1);
141      coo->rlat = lat;
142      coo->rlon = lon;
143      list = g_slist_append(list, coo);
144      return list;
145    }
146    
147    static GSList *pos_append(GSList *list, pos_float_t lat, pos_float_t lon) {
148      return pos_append_rad(list, DEG2RAD(lat), DEG2RAD(lon));
149    }
150    
151    /* the contents of the map tab have been changed */
152    static void map_update(context_t *context, gboolean forced) {
153    
154      /* map is first tab (page 0) */
155      if(!forced && !current_tab_is(context, -1, TAB_LABEL_MAP)) {
156        context->map.needs_redraw = TRUE;
157        return;
158    }    }
159    
160      /* check if the position is invalid */
161      if(isnan(context->min.lat) || isnan(context->min.lon) ||
162         isnan(context->min.lat) || isnan(context->min.lon)) {
163    
164        /* no coordinates given: display the entire world */
165        osm_gps_map_set_mapcenter(OSM_GPS_MAP(context->map.widget),
166                                  0.0, 0.0, 1);
167    
168        osm_gps_map_clear_tracks(OSM_GPS_MAP(context->map.widget));
169      } else {
170    
171        pos_float_t center_lat = (context->max.lat + context->min.lat)/2;
172        pos_float_t center_lon = (context->max.lon + context->min.lon)/2;
173    
174        /* we know the widgets pixel size, we know the required real size, */
175        /* we want the zoom! */
176        double vzoom = LOG2((45.0 * context->map.widget->allocation.height)/
177                            ((context->max.lat - context->min.lat)*32.0));
178    
179        double hzoom = LOG2((45.0 * context->map.widget->allocation.width)/
180                            ((context->max.lon - context->min.lon)*32.0));
181    
182        osm_gps_map_set_center(OSM_GPS_MAP(context->map.widget),
183                               center_lat, center_lon);
184    
185        /* use smallest zoom, so everything fits on screen */
186        osm_gps_map_set_zoom(OSM_GPS_MAP(context->map.widget),
187                             (vzoom < hzoom)?vzoom:hzoom);
188    
189        /* ---------- draw border (as a gps track) -------------- */
190        osm_gps_map_clear_tracks(OSM_GPS_MAP(context->map.widget));
191    
192        GSList *box = pos_append(NULL, context->min.lat, context->min.lon);
193        box = pos_append(box, context->max.lat, context->min.lon);
194        box = pos_append(box, context->max.lat, context->max.lon);
195        box = pos_append(box, context->min.lat, context->max.lon);
196        box = pos_append(box, context->min.lat, context->min.lon);
197    
198        osm_gps_map_add_track(OSM_GPS_MAP(context->map.widget), box);
199      }
200    
201      context->map.needs_redraw = FALSE;
202  }  }
203    
204    static gboolean on_map_configure(GtkWidget *widget,
205                                     GdkEventConfigure *event,
206                                     context_t *context) {
207      map_update(context, FALSE);
208      return FALSE;
209    }
210    #endif
211    
212  /* the contents of the direct tab have been changed */  /* the contents of the direct tab have been changed */
213  static void direct_update(context_t *context) {  static void direct_update(context_t *context) {
214    pos_lat_entry_set(context->direct.minlat, context->min.lat);    pos_lat_entry_set(context->direct.minlat, context->min.lat);
# Line 85  static void extent_update(context_t *con Line 238  static void extent_update(context_t *con
238  static void callback_modified_direct(GtkWidget *widget, gpointer data) {  static void callback_modified_direct(GtkWidget *widget, gpointer data) {
239    context_t *context = (context_t*)data;    context_t *context = (context_t*)data;
240    
241    /* direct is first tab (page 0) */    /* direct is second tab (page 1) */
242    if(gtk_notebook_get_current_page(GTK_NOTEBOOK(context->notebook)) != 0)    if(!current_tab_is(context, -1, TAB_LABEL_DIRECT))
243      return;      return;
244    
245    /* parse the fields from the direct entry pad */    /* parse the fields from the direct entry pad */
246    parse_and_set_lat(context->direct.minlat, context->minlat, &context->min.lat);    parse_and_set_lat(context->direct.minlat, &context->min.lat);
247    parse_and_set_lon(context->direct.minlon, context->minlon, &context->min.lon);    parse_and_set_lon(context->direct.minlon, &context->min.lon);
248    parse_and_set_lat(context->direct.maxlat, context->maxlat, &context->max.lat);    parse_and_set_lat(context->direct.maxlat, &context->max.lat);
249    parse_and_set_lon(context->direct.maxlon, context->maxlon, &context->max.lon);    parse_and_set_lon(context->direct.maxlon, &context->max.lon);
250    
251      area_main_update(context);
252    
253    /* also adjust other views */    /* also adjust other views */
254    extent_update(context);    extent_update(context);
255    #ifdef ENABLE_OSM_GPS_MAP
256      map_update(context, FALSE);
257    #endif
258  }  }
259    
260  static void callback_modified_extent(GtkWidget *widget, gpointer data) {  static void callback_modified_extent(GtkWidget *widget, gpointer data) {
261    context_t *context = (context_t*)data;    context_t *context = (context_t*)data;
262    
263    /* extent is second tab (page 1) */    /* extent is third tab (page 2) */
264    if(gtk_notebook_get_current_page(GTK_NOTEBOOK(context->notebook)) != 1)    if(!current_tab_is(context, -1, TAB_LABEL_EXTENT))
265      return;      return;
266    
267    pos_float_t center_lat = pos_lat_get(context->extent.lat);    pos_float_t center_lat = pos_lat_get(context->extent.lat);
# Line 120  static void callback_modified_extent(Gtk Line 278  static void callback_modified_extent(Gtk
278    
279    height /= 2 * vscale;    height /= 2 * vscale;
280    context->min.lat = center_lat - height;    context->min.lat = center_lat - height;
   pos_lat_label_set(context->minlat, context->min.lat);  
281    context->max.lat = center_lat + height;    context->max.lat = center_lat + height;
282    pos_lat_label_set(context->maxlat, context->max.lat);  
   
283    width /= 2 * hscale;    width /= 2 * hscale;
284    context->min.lon = center_lon - width;    context->min.lon = center_lon - width;
   pos_lon_label_set(context->minlon, context->min.lon);  
285    context->max.lon = center_lon + width;    context->max.lon = center_lon + width;
286    pos_lon_label_set(context->maxlon, context->max.lon);  
287      area_main_update(context);
288    
289    /* also update other tabs */    /* also update other tabs */
290    direct_update(context);    direct_update(context);
291    #ifdef ENABLE_OSM_GPS_MAP
292      map_update(context, FALSE);
293    #endif
294  }  }
295    
296  static void callback_modified_unit(GtkWidget *widget, gpointer data) {  static void callback_modified_unit(GtkWidget *widget, gpointer data) {
# Line 154  static void callback_modified_unit(GtkWi Line 313  static void callback_modified_unit(GtkWi
313  static void callback_fetch_mm_clicked(GtkButton *button, gpointer data) {  static void callback_fetch_mm_clicked(GtkButton *button, gpointer data) {
314    context_t *context = (context_t*)data;    context_t *context = (context_t*)data;
315    
316    printf("clicked fetch mm!\n");    if(!dbus_mm_set_position(context->area->appdata->osso_context, NULL)) {
   
   if(!dbus_mm_set_position(context->area->osso_context, NULL)) {  
317      errorf(context->dialog,      errorf(context->dialog,
318             _("Unable to communicate with Maemo Mapper. "             _("Unable to communicate with Maemo Mapper. "
319               "You need to have Maemo Mapper installed "               "You need to have Maemo Mapper installed "
# Line 164  static void callback_fetch_mm_clicked(Gt Line 321  static void callback_fetch_mm_clicked(Gt
321      return;      return;
322    }    }
323    
324    if(!context->area->mmpos->valid) {    if(!context->area->appdata->mmpos.valid) {
325      errorf(context->dialog,      errorf(context->dialog,
326             _("No valid position received yet. You need "             _("No valid position received yet. You need "
327               "to scroll or zoom the Maemo Mapper view "               "to scroll or zoom the Maemo Mapper view "
# Line 173  static void callback_fetch_mm_clicked(Gt Line 330  static void callback_fetch_mm_clicked(Gt
330      return;      return;
331    }    }
332    
333    /* maemo mapper is third tab (page 2) */    /* maemo mapper is fourth tab (page 3) */
334    if(gtk_notebook_get_current_page(GTK_NOTEBOOK(context->notebook)) != 2)    if(!current_tab_is(context, -1, TAB_LABEL_MM))
335      return;      return;
336    
337    /* maemo mapper pos data ... */    /* maemo mapper pos data ... */
338    pos_float_t center_lat = context->area->mmpos->pos.lat;    pos_float_t center_lat = context->area->appdata->mmpos.pos.lat;
339    pos_float_t center_lon = context->area->mmpos->pos.lon;    pos_float_t center_lon = context->area->appdata->mmpos.pos.lon;
340    int zoom = context->area->mmpos->zoom;    int zoom = context->area->appdata->mmpos.zoom;
341    
342    if(!pos_lat_valid(center_lat) || !pos_lon_valid(center_lon))    if(!pos_lat_valid(center_lat) || !pos_lon_valid(center_lon))
343      return;      return;
# Line 188  static void callback_fetch_mm_clicked(Gt Line 345  static void callback_fetch_mm_clicked(Gt
345    double vscale = DEG2RAD(POS_EQ_RADIUS);    double vscale = DEG2RAD(POS_EQ_RADIUS);
346    double height = 8 * (1<<zoom) / vscale;    double height = 8 * (1<<zoom) / vscale;
347    context->min.lat = center_lat - height;    context->min.lat = center_lat - height;
   pos_lat_label_set(context->minlat, context->min.lat);  
348    context->max.lat = center_lat + height;    context->max.lat = center_lat + height;
   pos_lat_label_set(context->maxlat, context->max.lat);  
349    
350    double hscale = DEG2RAD(cos(DEG2RAD(center_lat)) * POS_EQ_RADIUS);    double hscale = DEG2RAD(cos(DEG2RAD(center_lat)) * POS_EQ_RADIUS);
351    double width  = 16 * (1<<zoom) / hscale;    double width  = 16 * (1<<zoom) / hscale;
352    context->min.lon = center_lon - width;    context->min.lon = center_lon - width;
   pos_lon_label_set(context->minlon, context->min.lon);  
353    context->max.lon = center_lon + width;    context->max.lon = center_lon + width;
354    pos_lon_label_set(context->maxlon, context->max.lon);  
355      area_main_update(context);
356    
357    /* also update other tabs */    /* also update other tabs */
358    direct_update(context);    direct_update(context);
359    extent_update(context);    extent_update(context);
360    #ifdef ENABLE_OSM_GPS_MAP
361      map_update(context, FALSE);
362    #endif
363  }  }
364  #endif  #endif
365    
366    #ifdef ENABLE_OSM_GPS_MAP
367    
368    static gboolean
369    on_map_button_press_event(GtkWidget *widget,
370                              GdkEventButton *event, context_t *context) {
371      if(!context->map.drag_mode) {
372        OsmGpsMap *map = OSM_GPS_MAP(context->map.widget);
373    
374        /* remove existing marker */
375        osm_gps_map_clear_tracks(map);
376    
377        /* and remember this location as the start */
378        context->map.start =
379          osm_gps_map_get_co_ordinates(map, (int)event->x, (int)event->y);
380    
381        return TRUE;
382      }
383    
384      return FALSE;
385    }
386    
387    static gboolean
388    on_map_motion_notify_event(GtkWidget *widget,
389                               GdkEventMotion  *event, context_t *context) {
390      if(!context->map.drag_mode &&
391         !isnan(context->map.start.rlon) &&
392         !isnan(context->map.start.rlat)) {
393        OsmGpsMap *map = OSM_GPS_MAP(context->map.widget);
394    
395        /* remove existing marker */
396        osm_gps_map_clear_tracks(map);
397    
398        coord_t start = context->map.start, end =
399          osm_gps_map_get_co_ordinates(map, (int)event->x, (int)event->y);
400    
401        GSList *box = pos_append_rad(NULL, start.rlat, start.rlon);
402        box = pos_append_rad(box, end.rlat,   start.rlon);
403        box = pos_append_rad(box, end.rlat,   end.rlon);
404        box = pos_append_rad(box, start.rlat, end.rlon);
405        box = pos_append_rad(box, start.rlat, start.rlon);
406    
407        osm_gps_map_add_track(map, box);
408    
409        return TRUE;
410      }
411    
412      return FALSE;
413    }
414    
415    static gboolean
416    on_map_button_release_event(GtkWidget *widget,
417                                GdkEventButton *event, context_t *context) {
418      if(!context->map.drag_mode &&
419         !isnan(context->map.start.rlon) &&
420         !isnan(context->map.start.rlat)) {
421        OsmGpsMap *map = OSM_GPS_MAP(context->map.widget);
422    
423        coord_t start = context->map.start, end =
424          osm_gps_map_get_co_ordinates(map, (int)event->x, (int)event->y);
425    
426        GSList *box = pos_append_rad(NULL, start.rlat, start.rlon);
427        box = pos_append_rad(box, end.rlat,   start.rlon);
428        box = pos_append_rad(box, end.rlat,   end.rlon);
429        box = pos_append_rad(box, start.rlat, end.rlon);
430        box = pos_append_rad(box, start.rlat, start.rlon);
431    
432        osm_gps_map_add_track(map, box);
433    
434        if(start.rlat < end.rlat) {
435          context->min.lat = RAD2DEG(start.rlat);
436          context->max.lat = RAD2DEG(end.rlat);
437        } else {
438          context->min.lat = RAD2DEG(end.rlat);
439          context->max.lat = RAD2DEG(start.rlat);
440        }
441    
442        if(start.rlon < end.rlon) {
443          context->min.lon = RAD2DEG(start.rlon);
444          context->max.lon = RAD2DEG(end.rlon);
445        } else {
446          context->min.lon = RAD2DEG(end.rlon);
447          context->max.lon = RAD2DEG(start.rlon);
448        }
449    
450        area_main_update(context);
451        direct_update(context);
452        extent_update(context);
453    
454        context->map.start.rlon = context->map.start.rlat = NAN;
455    
456        return TRUE;
457      }
458    
459      return FALSE;
460    }
461    
462    static void map_zoom(context_t *context, int step) {
463      int zoom;
464      OsmGpsMap *map = OSM_GPS_MAP(context->map.widget);
465      g_object_get(map, "zoom", &zoom, NULL);
466      zoom = osm_gps_map_set_zoom(map, zoom+step);
467    
468      /* enable/disable zoom buttons as required */
469      gtk_widget_set_sensitive(context->map.zoomin, zoom<17);
470      gtk_widget_set_sensitive(context->map.zoomout, zoom>1);
471    }
472    
473    static gboolean
474    cb_map_zoomin(GtkButton *button, context_t *context) {
475      map_zoom(context, +1);
476      return FALSE;
477    }
478    
479    static gboolean
480    cb_map_zoomout(GtkButton *button, context_t *context) {
481      map_zoom(context, -1);
482      return FALSE;
483    }
484    
485    static gboolean
486    cb_map_center(GtkButton *button, context_t *context) {
487      map_update(context, TRUE);
488      return FALSE;
489    }
490    
491    static gboolean
492    cb_map_modesel(GtkButton *button, context_t *context) {
493      /* toggle between "find" icon and "cut" icon */
494      context->map.drag_mode = !context->map.drag_mode;
495      gtk_button_set_image(GTK_BUTTON(context->map.modesel),
496                   gtk_image_new_from_stock(context->map.drag_mode?
497            GTK_STOCK_FIND:GTK_STOCK_CUT, GTK_ICON_SIZE_MENU));
498    
499      return FALSE;
500    }
501    
502    static gboolean
503    cb_map_gps(GtkButton *button, context_t *context) {
504      pos_t pos;
505    
506      /* user clicked "gps" button -> jump to position */
507      gboolean gps_on =
508        context->area->appdata->settings &&
509        context->area->appdata->settings->enable_gps;
510    
511      if(gps_on && gps_get_pos(context->area->appdata, &pos, NULL)) {
512        osm_gps_map_set_center(OSM_GPS_MAP(context->map.widget),
513                               DEG2RAD(pos.lat), DEG2RAD(pos.lon));
514      }
515    
516      return FALSE;
517    }
518    
519    static void on_page_switch(GtkNotebook *notebook, GtkNotebookPage *page,
520                               guint page_num, context_t *context) {
521    
522      /* updating the map while the user manually changes some coordinates */
523      /* may confuse the map. so we delay those updates until the map tab */
524      /* is becoming visible */
525      if(current_tab_is(context, page_num, TAB_LABEL_MAP) &&
526         context->map.needs_redraw)
527        map_update(context, TRUE);
528    }
529    
530    static GtkWidget
531    *map_add_button(const gchar *icon, GCallback cb, gpointer data,
532                    char *tooltip) {
533      GtkWidget *button = gtk_button_new();
534      gtk_button_set_image(GTK_BUTTON(button),
535           gtk_image_new_from_stock(icon, GTK_ICON_SIZE_MENU));
536      g_signal_connect(button, "clicked", cb, data);
537    #ifndef USE_HILDON
538      gtk_widget_set_tooltip_text(button, tooltip);
539    #endif
540      return button;
541    }
542    
543    static gboolean map_gps_update(gpointer data) {
544      context_t *context = (context_t*)data;
545    
546      gboolean gps_on =
547        context->area->appdata->settings &&
548        context->area->appdata->settings->enable_gps;
549    
550      gboolean gps_fix = gps_on &&
551        gps_get_pos(context->area->appdata, NULL, NULL);
552    
553      gtk_widget_set_sensitive(context->map.gps, gps_fix);
554    
555      return TRUE;
556    }
557    
558    #endif
559    
560  gboolean area_edit(area_edit_t *area) {  gboolean area_edit(area_edit_t *area) {
561      GtkWidget *vbox;
562    gboolean ok = FALSE;    gboolean ok = FALSE;
563    
564    context_t context;    context_t context;
# Line 216  gboolean area_edit(area_edit_t *area) { Line 569  gboolean area_edit(area_edit_t *area) {
569    context.max.lat = area->max->lat;    context.max.lat = area->max->lat;
570    context.max.lon = area->max->lon;    context.max.lon = area->max->lon;
571    
572    context.dialog = gtk_dialog_new_with_buttons(    context.dialog =
573            _("Area editor"),      misc_dialog_new(MISC_DIALOG_HIGH, _("Area editor"),
574            GTK_WINDOW(area->parent), GTK_DIALOG_MODAL,            GTK_WINDOW(area->parent),
575            GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,            GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
576            GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,            GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
577            NULL);            NULL);
578    
579  #ifdef USE_HILDON    GtkWidget *table = gtk_table_new(5, 2, FALSE);  // x, y
   //  gtk_window_set_default_size(GTK_WINDOW(context.dialog), 640, 100);  
 #else  
   //  gtk_window_set_default_size(GTK_WINDOW(context.dialog), 400, 100);  
 #endif  
   
   GtkWidget *table = gtk_table_new(3, 3, FALSE);  // x, y  
   
   GtkWidget *label = gtk_label_new(_("Latitude"));  
   gtk_table_attach_defaults(GTK_TABLE(table),  label, 1, 2, 0, 1);  
   label = gtk_label_new(_("Longitude"));  
   gtk_table_attach_defaults(GTK_TABLE(table),  label, 2, 3, 0, 1);  
580    
581    label = gtk_label_new(_("Min:"));    GtkWidget *label = gtk_label_new(_("Latitude:"));
582    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);    misc_table_attach(table, label, 0, 0);
   gtk_table_attach_defaults(GTK_TABLE(table),  label, 0, 1, 1, 2);  
583    context.minlat = pos_lat_label_new(area->min->lat);    context.minlat = pos_lat_label_new(area->min->lat);
584    gtk_table_attach_defaults(GTK_TABLE(table), context.minlat, 1, 2, 1, 2);    misc_table_attach(table, context.minlat, 1, 0);
585    context.minlon = pos_lon_label_new(area->min->lon);    label = gtk_label_new(_("to"));
586    gtk_table_attach_defaults(GTK_TABLE(table), context.minlon, 2, 3, 1, 2);    misc_table_attach(table, label, 2, 0);
   
   label = gtk_label_new(_("Max:"));  
   gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);  
   gtk_table_attach_defaults(GTK_TABLE(table),  label, 0, 1, 2, 3);  
587    context.maxlat = pos_lat_label_new(area->max->lat);    context.maxlat = pos_lat_label_new(area->max->lat);
588    gtk_table_attach_defaults(GTK_TABLE(table), context.maxlat, 1, 2, 2, 3);    misc_table_attach(table, context.maxlat, 3, 0);
589    
590      label = gtk_label_new(_("Longitude:"));
591      misc_table_attach(table, label, 0, 1);
592      context.minlon = pos_lon_label_new(area->min->lon);
593      misc_table_attach(table, context.minlon, 1, 1);
594      label = gtk_label_new(_("to"));
595      misc_table_attach(table, label, 2, 1);
596    context.maxlon = pos_lon_label_new(area->max->lon);    context.maxlon = pos_lon_label_new(area->max->lon);
597    gtk_table_attach_defaults(GTK_TABLE(table), context.maxlon, 2, 3, 2, 3);    misc_table_attach(table, context.maxlon, 3, 1);
598    
599    gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(context.dialog)->vbox),    context.warning = gtk_button_new();
600                                table);    gtk_button_set_image(GTK_BUTTON(context.warning),
601                           gtk_image_new_from_stock(GTK_STOCK_DIALOG_WARNING,
602                                                    GTK_ICON_SIZE_BUTTON));
603      g_signal_connect(context.warning, "clicked",
604                       G_CALLBACK(on_area_warning_clicked), &context);
605      gtk_table_attach_defaults(GTK_TABLE(table), context.warning, 4, 5, 0, 2);
606    
607      gtk_box_pack_start(GTK_BOX(GTK_DIALOG(context.dialog)->vbox),
608                                  table, FALSE, FALSE, 0);
609    
610    context.notebook = gtk_notebook_new();    context.notebook = gtk_notebook_new();
611    
612    #ifdef ENABLE_OSM_GPS_MAP
613      /* ------------- fetch from map ------------------------ */
614    
615      GtkWidget *hbox = gtk_hbox_new(FALSE, 0);
616    
617      context.map.needs_redraw = FALSE;
618      context.map.widget = g_object_new(OSM_TYPE_GPS_MAP,
619                    "repo-uri", MAP_SOURCE_OPENSTREETMAP,
620                    "proxy-uri", misc_get_proxy_uri(area->settings),
621                    "tile-cache", NULL,
622                     NULL);
623    
624      g_signal_connect(G_OBJECT(context.map.widget), "configure-event",
625                       G_CALLBACK(on_map_configure), &context);
626      g_signal_connect(G_OBJECT(context.map.widget), "button-press-event",
627                       G_CALLBACK(on_map_button_press_event), &context);
628      g_signal_connect(G_OBJECT(context.map.widget), "motion-notify-event",
629                       G_CALLBACK(on_map_motion_notify_event), &context);
630      g_signal_connect(G_OBJECT(context.map.widget), "button-release-event",
631                       G_CALLBACK(on_map_button_release_event), &context);
632    
633      gtk_box_pack_start_defaults(GTK_BOX(hbox), context.map.widget);
634    
635      /* zoom button box */
636      vbox = gtk_vbox_new(FALSE,0);
637    
638      context.map.zoomin =
639        map_add_button(GTK_STOCK_ZOOM_IN, G_CALLBACK(cb_map_zoomin),
640                       &context, _("Zoom in"));
641      gtk_box_pack_start(GTK_BOX(vbox), context.map.zoomin, FALSE, FALSE, 0);
642    
643      context.map.zoomout =
644        map_add_button(GTK_STOCK_ZOOM_OUT, G_CALLBACK(cb_map_zoomout),
645                       &context, _("Zoom out"));
646      gtk_box_pack_start(GTK_BOX(vbox), context.map.zoomout, FALSE, FALSE, 0);
647    
648      context.map.center =
649        map_add_button(GTK_STOCK_HOME, G_CALLBACK(cb_map_center),
650                       &context, _("Center selected area"));
651      gtk_box_pack_start(GTK_BOX(vbox), context.map.center, FALSE, FALSE, 0);
652    
653      context.map.gps =
654        map_add_button(GTK_STOCK_ABOUT, G_CALLBACK(cb_map_gps),
655                       &context, _("Jump to GPS position"));
656      gtk_widget_set_sensitive(context.map.gps, FALSE);
657      /* install handler for timed updates of the gps button */
658      context.map.handler_id = gtk_timeout_add(1000, map_gps_update, &context);
659      gtk_box_pack_start(GTK_BOX(vbox), context.map.gps, FALSE, FALSE, 0);
660    
661      context.map.drag_mode = TRUE;
662      context.map.start.rlon = context.map.start.rlat = NAN;
663      context.map.modesel =
664        map_add_button(GTK_STOCK_FIND, G_CALLBACK(cb_map_modesel),
665                       &context, _("Toggle scroll/select"));
666      gtk_box_pack_start(GTK_BOX(vbox), context.map.modesel, FALSE, FALSE, 0);
667    
668      gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
669    
670      gtk_notebook_append_page(GTK_NOTEBOOK(context.notebook),
671                       hbox, gtk_label_new(_(TAB_LABEL_MAP)));
672    #endif
673    
674    /* ------------ direct min/max edit --------------- */    /* ------------ direct min/max edit --------------- */
675    
676      vbox = gtk_vbox_new(FALSE, 10);
677    table = gtk_table_new(3, 3, FALSE);  // x, y    table = gtk_table_new(3, 3, FALSE);  // x, y
678      gtk_table_set_col_spacings(GTK_TABLE(table), 10);
679      gtk_table_set_row_spacings(GTK_TABLE(table), 5);
680    
681    label = gtk_label_new(_("Min:"));    context.direct.minlat = pos_lat_entry_new(0.0);
682    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);    misc_table_attach(table, context.direct.minlat, 0, 0);
683    gtk_table_attach_defaults(GTK_TABLE(table),  label, 0, 1, 0, 1);    label = gtk_label_new(_("to"));
684    context.direct.minlat = pos_lat_entry_new(0.);    misc_table_attach(table,  label, 1, 0);
   gtk_table_attach_defaults(GTK_TABLE(table), context.direct.minlat, 1, 2, 0, 1);  
   context.direct.minlon = pos_lon_entry_new(area->min->lon);  
   gtk_table_attach_defaults(GTK_TABLE(table), context.direct.minlon, 2, 3, 0, 1);  
   
   label = gtk_label_new(_("Max:"));  
   gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);  
   gtk_table_attach_defaults(GTK_TABLE(table),  label, 0, 1, 1, 2);  
685    context.direct.maxlat = pos_lat_entry_new(0.0);    context.direct.maxlat = pos_lat_entry_new(0.0);
686    gtk_table_attach_defaults(GTK_TABLE(table), context.direct.maxlat, 1, 2, 1, 2);    misc_table_attach(table, context.direct.maxlat, 2, 0);
687    
688      context.direct.minlon = pos_lon_entry_new(area->min->lon);
689      misc_table_attach(table, context.direct.minlon, 0, 1);
690      label = gtk_label_new(_("to"));
691      misc_table_attach(table,  label, 1, 1);
692    context.direct.maxlon = pos_lon_entry_new(0.0);    context.direct.maxlon = pos_lon_entry_new(0.0);
693    gtk_table_attach_defaults(GTK_TABLE(table), context.direct.maxlon, 2, 3, 1, 2);    misc_table_attach(table, context.direct.maxlon, 2, 1);
694    
695    /* setup this page */    /* setup this page */
696    direct_update(&context);    direct_update(&context);
# Line 294  gboolean area_edit(area_edit_t *area) { Line 709  gboolean area_edit(area_edit_t *area) {
709    label = gtk_label_new(_("(recommended min/max diff <0.03 degrees)"));    label = gtk_label_new(_("(recommended min/max diff <0.03 degrees)"));
710    gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 3, 2, 3);    gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 3, 2, 3);
711    
712      gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
713    gtk_notebook_append_page(GTK_NOTEBOOK(context.notebook),    gtk_notebook_append_page(GTK_NOTEBOOK(context.notebook),
714                   table, gtk_label_new(_("Direct")));             vbox, gtk_label_new(_(TAB_LABEL_DIRECT)));
715    
716    /* ------------- center/extent edit ------------------------ */    /* ------------- center/extent edit ------------------------ */
717    
718      vbox = gtk_vbox_new(FALSE, 10);
719    table = gtk_table_new(3, 4, FALSE);  // x, y    table = gtk_table_new(3, 4, FALSE);  // x, y
720      gtk_table_set_col_spacings(GTK_TABLE(table), 10);
721      gtk_table_set_row_spacings(GTK_TABLE(table), 5);
722    
723    label = gtk_label_new(_("Center:"));    label = gtk_label_new(_("Center:"));
724    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
# Line 309  gboolean area_edit(area_edit_t *area) { Line 728  gboolean area_edit(area_edit_t *area) {
728    context.extent.lon = pos_lon_entry_new(0.0);    context.extent.lon = pos_lon_entry_new(0.0);
729    gtk_table_attach_defaults(GTK_TABLE(table), context.extent.lon, 2, 3, 0, 1);    gtk_table_attach_defaults(GTK_TABLE(table), context.extent.lon, 2, 3, 0, 1);
730    
731    gtk_table_set_row_spacing(GTK_TABLE(table), 0, 8);    gtk_table_set_row_spacing(GTK_TABLE(table), 0, 10);
732    
733    label = gtk_label_new(_("Width:"));    label = gtk_label_new(_("Width:"));
734    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
# Line 321  gboolean area_edit(area_edit_t *area) { Line 740  gboolean area_edit(area_edit_t *area) {
740    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
741    gtk_table_attach_defaults(GTK_TABLE(table),  label, 0, 1, 2, 3);    gtk_table_attach_defaults(GTK_TABLE(table),  label, 0, 1, 2, 3);
742    context.extent.height = gtk_entry_new();    context.extent.height = gtk_entry_new();
743    gtk_table_attach_defaults(GTK_TABLE(table), context.extent.height, 1, 2, 2, 3);    gtk_table_attach_defaults(GTK_TABLE(table),
744                                context.extent.height, 1, 2, 2, 3);
745    
746    context.extent.mil_km = gtk_combo_box_new_text();    context.extent.mil_km = gtk_combo_box_new_text();
747    gtk_combo_box_append_text(GTK_COMBO_BOX(context.extent.mil_km), _("mi"));    gtk_combo_box_append_text(GTK_COMBO_BOX(context.extent.mil_km), _("mi"));
# Line 350  gboolean area_edit(area_edit_t *area) { Line 770  gboolean area_edit(area_edit_t *area) {
770    label = gtk_label_new(_("(recommended width/height < 2km/1.25mi)"));    label = gtk_label_new(_("(recommended width/height < 2km/1.25mi)"));
771    gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 3, 3, 4);    gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 3, 3, 4);
772    
773      gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
774    gtk_notebook_append_page(GTK_NOTEBOOK(context.notebook),    gtk_notebook_append_page(GTK_NOTEBOOK(context.notebook),
775                     table, gtk_label_new(_("Extent")));                     vbox, gtk_label_new(_(TAB_LABEL_EXTENT)));
776    
777  #ifdef USE_HILDON  #ifdef USE_HILDON
778    /* ------------- fetch from maemo mapper ------------------------ */    /* ------------- fetch from maemo mapper ------------------------ */
779    
780    GtkWidget *vbox = gtk_vbox_new(FALSE, 8);    vbox = gtk_vbox_new(FALSE, 8);
781    context.mmapper.fetch =    context.mmapper.fetch =
782      gtk_button_new_with_label(_("Get from Maemo Mapper"));      gtk_button_new_with_label(_("Get from Maemo Mapper"));
783    gtk_box_pack_start_defaults(GTK_BOX(vbox), context.mmapper.fetch);    gtk_box_pack_start(GTK_BOX(vbox), context.mmapper.fetch, FALSE, FALSE, 0);
784    
785    g_signal_connect(G_OBJECT(context.mmapper.fetch), "clicked",    g_signal_connect(G_OBJECT(context.mmapper.fetch), "clicked",
786                     G_CALLBACK(callback_fetch_mm_clicked), &context);                     G_CALLBACK(callback_fetch_mm_clicked), &context);
   //  gtk_widget_set_sensitive(context.mmapper.fetch, context.area->mmpos->valid);  
787    
788    /* --- hint --- */    /* --- hint --- */
789    label = gtk_label_new(_("(recommended MM zoom level < 7)"));    label = gtk_label_new(_("(recommended MM zoom level < 7)"));
790    gtk_box_pack_start_defaults(GTK_BOX(vbox), label);    gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
791    
792    
793    gtk_notebook_append_page(GTK_NOTEBOOK(context.notebook),    gtk_notebook_append_page(GTK_NOTEBOOK(context.notebook),
794                     vbox, gtk_label_new(_("Maemo Mapper")));                     vbox, gtk_label_new(_(TAB_LABEL_MM)));
795  #endif  #endif
796    
797      /* ------------------------------------------------------ */
798    
799    gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(context.dialog)->vbox),    gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(context.dialog)->vbox),
800                                context.notebook);                                context.notebook);
801    
802    #ifdef ENABLE_OSM_GPS_MAP
803      g_signal_connect(G_OBJECT(context.notebook), "switch-page",
804                       G_CALLBACK(on_page_switch), &context);
805    #endif
806    
807    gtk_widget_show_all(context.dialog);    gtk_widget_show_all(context.dialog);
808    
809      area_main_update(&context);
810    
811    if(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(context.dialog))) {    if(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(context.dialog))) {
812      /* copy modified values back to given storage */      /* copy modified values back to given storage */
813      area->min->lat = context.min.lat;      area->min->lat = context.min.lat;
# Line 390  gboolean area_edit(area_edit_t *area) { Line 817  gboolean area_edit(area_edit_t *area) {
817      ok = TRUE;      ok = TRUE;
818    }    }
819    
820    #ifdef ENABLE_OSM_GPS_MAP
821      gtk_timeout_remove(context.map.handler_id);
822    #endif
823    
824    gtk_widget_destroy(context.dialog);    gtk_widget_destroy(context.dialog);
825    
826    return ok;    return ok;

Legend:
Removed from v.9  
changed lines
  Added in v.248