]> err.no Git - mapper/blob - src/cb.c
Merge branch 'master' of git+ssh://tal.org/home/git/mapper
[mapper] / src / cb.c
1 #include <config.h>
2
3 #define _GNU_SOURCE
4
5 #include <unistd.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <strings.h>
9 #include <stddef.h>
10 #include <locale.h>
11 #include <math.h>
12 #include <errno.h>
13 #include <sys/wait.h>
14 #include <glib/gstdio.h>
15 #include <gtk/gtk.h>
16 #include <fcntl.h>
17 #include <gconf/gconf-client.h>
18 #include <libintl.h>
19 #include <locale.h>
20
21 #include "hildon-mapper.h"
22
23 #include "utils.h"
24 #include "poi.h"
25 #include "route.h"
26 #include "settings.h"
27 #include "gps.h"
28 #include "map.h"
29 #include "mapper-types.h"
30 #include "bt.h"
31 #include "ui-common.h"
32 #include "db.h"
33
34 #include "cb.h"
35
36 gboolean map_cb_configure(GtkWidget * widget, GdkEventConfigure * event)
37 {
38         printf("%s(%d, %d)\n", __PRETTY_FUNCTION__,
39                _map_widget->allocation.width, _map_widget->allocation.height);
40
41         _screen_width_pixels = _map_widget->allocation.width;
42         _screen_height_pixels = _map_widget->allocation.height;
43         _screen_grids_halfwidth = pixel2grid(_screen_width_pixels) / 2;
44         _screen_grids_halfheight = pixel2grid(_screen_height_pixels) / 2;
45
46         /* Set _scale_rect. */
47         _scale_rect.x = (_screen_width_pixels - SCALE_WIDTH) / 2;
48         _scale_rect.width = SCALE_WIDTH;
49         pango_layout_set_text(_scale_layout, "0", -1);
50         pango_layout_get_pixel_size(_scale_layout, NULL, &_scale_rect.height);
51         _scale_rect.y = _screen_height_pixels - _scale_rect.height - 1;
52
53         MACRO_RECALC_FOCUS_BASE();
54         MACRO_RECALC_FOCUS_SIZE();
55
56         _min_center.unitx = pixel2unit(grid2pixel(_screen_grids_halfwidth));
57         _min_center.unity = pixel2unit(grid2pixel(_screen_grids_halfheight));
58         _max_center.unitx = WORLD_SIZE_UNITS - grid2unit(_screen_grids_halfwidth) - 1;
59         _max_center.unity = WORLD_SIZE_UNITS - grid2unit(_screen_grids_halfheight) - 1;
60
61         map_center_unit(_center.unitx, _center.unity);
62
63         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
64         return TRUE;
65 }
66
67 gboolean menu_cb_route_download(GtkAction * action)
68 {
69         printf("%s()\n", __PRETTY_FUNCTION__);
70         route_download(NULL);
71         vprintf("%s(): return\n", __PRETTY_FUNCTION__);
72         return TRUE;
73 }
74
75 gboolean menu_cb_route_open(GtkAction * action)
76 {
77         printf("%s()\n", __PRETTY_FUNCTION__);
78
79         route_open_file();
80
81         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
82         return TRUE;
83 }
84
85 gboolean menu_cb_route_distnext(GtkAction * action)
86 {
87         printf("%s()\n", __PRETTY_FUNCTION__);
88
89         route_show_distance_to_next();
90
91         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
92         return TRUE;
93 }
94
95 gboolean menu_cb_route_distlast(GtkAction * action)
96 {
97         printf("%s()\n", __PRETTY_FUNCTION__);
98
99         route_show_distance_to_last();
100
101         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
102         return TRUE;
103 }
104
105 gboolean menu_cb_route_reset(GtkAction * action)
106 {
107         printf("%s()\n", __PRETTY_FUNCTION__);
108
109         route_find_nearest_point();
110         MACRO_MAP_RENDER_DATA();
111         MACRO_QUEUE_DRAW_AREA();
112
113         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
114         return TRUE;
115 }
116
117 gboolean menu_cb_route_clear(GtkAction * action)
118 {
119         printf("%s()\n", __PRETTY_FUNCTION__);
120
121         cancel_autoroute(FALSE);
122         MACRO_PATH_FREE(_route);
123         MACRO_PATH_INIT(_route);
124         route_find_nearest_point();
125         map_force_redraw();
126
127         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
128         return TRUE;
129 }
130
131 gboolean menu_cb_track_open(GtkAction * action)
132 {
133         printf("%s()\n", __PRETTY_FUNCTION__);
134
135         track_open();
136
137         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
138         return TRUE;
139 }
140
141 gboolean menu_cb_track_save(GtkAction * action)
142 {
143         printf("%s()\n", __PRETTY_FUNCTION__);
144
145         track_save();
146
147         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
148         return TRUE;
149 }
150
151 gboolean menu_cb_track_insert_break(GtkAction * action)
152 {
153         printf("%s()\n", __PRETTY_FUNCTION__);
154
155         track_insert_break();
156
157         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
158         return TRUE;
159 }
160
161 gboolean menu_cb_track_insert_mark(GtkAction * action)
162 {
163         printf("%s()\n", __PRETTY_FUNCTION__);
164
165         track_insert_mark();
166
167         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
168         return TRUE;
169 }
170
171 gboolean menu_cb_track_distlast(GtkAction * action)
172 {
173         printf("%s()\n", __PRETTY_FUNCTION__);
174
175         track_show_distance_from_last();
176
177         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
178         return TRUE;
179 }
180
181 gboolean menu_cb_track_distfirst(GtkAction * action)
182 {
183         printf("%s()\n", __PRETTY_FUNCTION__);
184
185         track_show_distance_from_first();
186
187         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
188         return TRUE;
189 }
190
191 gboolean menu_cb_route_save(GtkAction * action)
192 {
193         printf("%s()\n", __PRETTY_FUNCTION__);
194
195         route_save();
196
197         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
198         return TRUE;
199 }
200
201 gboolean menu_cb_track_clear(GtkAction * action)
202 {
203         printf("%s()\n", __PRETTY_FUNCTION__);
204
205         track_clear();
206
207         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
208         return TRUE;
209 }
210
211 gboolean menu_cb_track_filter(GtkAction * action)
212 {
213 filter_dialog();
214 return TRUE;
215 }
216
217 gboolean menu_cb_show_tracks(GtkAction * action)
218 {
219         printf("%s()\n", __PRETTY_FUNCTION__);
220
221         _show_tracks ^= TRACKS_MASK;
222         if (gtk_check_menu_item_get_active
223             (GTK_CHECK_MENU_ITEM(_menu_show_tracks_item))) {
224                 _show_tracks |= TRACKS_MASK;
225                 map_render_paths();
226                 MACRO_QUEUE_DRAW_AREA();
227                 MACRO_BANNER_SHOW_INFO(_window, _("Tracks are now shown"));
228         } else {
229                 _show_tracks &= ~TRACKS_MASK;
230                 map_force_redraw();
231                 MACRO_BANNER_SHOW_INFO(_window, _("Tracks are now hidden"));
232         }
233
234         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
235         return TRUE;
236 }
237
238 gboolean menu_cb_show_scale(GtkAction * action)
239 {
240         printf("%s()\n", __PRETTY_FUNCTION__);
241
242         _show_scale =
243             gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM
244                                            (_menu_show_scale_item));
245         MACRO_QUEUE_DRAW_AREA();
246
247         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
248         return TRUE;
249 }
250
251 gboolean menu_cb_show_routes(GtkAction * action)
252 {
253         printf("%s()\n", __PRETTY_FUNCTION__);
254
255         if (gtk_check_menu_item_get_active
256             (GTK_CHECK_MENU_ITEM(_menu_show_routes_item))) {
257                 _show_tracks |= ROUTES_MASK;
258                 map_render_paths();
259                 MACRO_QUEUE_DRAW_AREA();
260                 MACRO_BANNER_SHOW_INFO(_window, _("Routes are now shown"));
261         } else {
262                 _show_tracks &= ~ROUTES_MASK;
263                 map_force_redraw();
264                 MACRO_BANNER_SHOW_INFO(_window, _("Routes are now hidden"));
265         }
266
267         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
268         return TRUE;
269 }
270
271 gboolean menu_cb_show_velvec(GtkAction * action)
272 {
273         printf("%s()\n", __PRETTY_FUNCTION__);
274
275         _show_velvec = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(_menu_show_velvec_item));
276         map_move_mark();
277
278         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
279         return TRUE;
280 }
281
282 gboolean menu_cb_show_poi(GtkAction * action)
283 {
284         printf("%s()\n", __PRETTY_FUNCTION__);
285
286         _show_poi = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(_menu_show_poi_item));
287         map_force_redraw();
288
289         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
290         return TRUE;
291 }
292
293 gboolean menu_cb_gps_show_info(GtkAction * action)
294 {
295         printf("%s()\n", __PRETTY_FUNCTION__);
296
297         _gps_info = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(_menu_gps_show_info_item));
298
299         gps_show_info();
300
301         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
302         return TRUE;
303 }
304
305 gboolean menu_cb_ac_lead(GtkAction * action)
306 {
307         guint new_center_unitx, new_center_unity;
308         printf("%s()\n", __PRETTY_FUNCTION__);
309
310         _center_mode = CENTER_LEAD;
311         MACRO_BANNER_SHOW_INFO(_window, _("Auto-Center Mode: Lead"));
312         MACRO_RECALC_CENTER(new_center_unitx, new_center_unity);
313         map_center_unit(new_center_unitx, new_center_unity);
314
315         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
316         return TRUE;
317 }
318
319 gboolean menu_cb_ac_latlon(GtkAction * action)
320 {
321         guint new_center_unitx, new_center_unity;
322         printf("%s()\n", __PRETTY_FUNCTION__);
323
324         _center_mode = CENTER_LATLON;
325         MACRO_BANNER_SHOW_INFO(_window, _("Auto-Center Mode: Lat/Lon"));
326         MACRO_RECALC_CENTER(new_center_unitx, new_center_unity);
327         map_center_unit(new_center_unitx, new_center_unity);
328
329         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
330         return TRUE;
331 }
332
333 gboolean menu_cb_ac_none(GtkAction * action)
334 {
335         printf("%s()\n", __PRETTY_FUNCTION__);
336
337         _center_mode = -_center_mode;
338         MACRO_BANNER_SHOW_INFO(_window, _("Auto-Center Off"));
339
340         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
341         return TRUE;
342 }
343
344 gboolean menu_cb_goto_latlon(GtkAction * action)
345 {
346         GtkWidget *dialog;
347         GtkWidget *table;
348         GtkWidget *label;
349         GtkWidget *txt_lat;
350         GtkWidget *txt_lon;
351         printf("%s()\n", __PRETTY_FUNCTION__);
352
353         dialog = gtk_dialog_new_with_buttons(_("Go to Lat/Lon"),
354                                              GTK_WINDOW(_window),
355                                              GTK_DIALOG_MODAL, GTK_STOCK_OK,
356                                              GTK_RESPONSE_ACCEPT,
357                                              GTK_STOCK_CANCEL,
358                                              GTK_RESPONSE_REJECT, NULL);
359
360         gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
361                            table = gtk_table_new(2, 3, FALSE), TRUE, TRUE, 0);
362
363         gtk_table_attach(GTK_TABLE(table),
364                          label = gtk_label_new(_("Latitude")),
365                          0, 1, 0, 1, GTK_FILL, 0, 2, 4);
366         gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
367
368         gtk_table_attach(GTK_TABLE(table),
369                          txt_lat = gtk_entry_new(),
370                          1, 2, 0, 1, GTK_FILL, 0, 2, 4);
371         gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
372
373         gtk_table_attach(GTK_TABLE(table),
374                          label = gtk_label_new(_("Longitude")),
375                          0, 1, 1, 2, GTK_FILL, 0, 2, 4);
376         gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
377
378         gtk_table_attach(GTK_TABLE(table),
379                          txt_lon = gtk_entry_new(),
380                          1, 2, 1, 2, GTK_FILL, 0, 2, 4);
381         gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
382
383 #ifdef WITH_DEVICE_770
384         g_object_set(G_OBJECT(txt_lat), HILDON_INPUT_MODE_HINT,
385                      HILDON_INPUT_MODE_HINT_NUMERICSPECIAL, NULL);
386         g_object_set(G_OBJECT(txt_lon), HILDON_INPUT_MODE_HINT,
387                      HILDON_INPUT_MODE_HINT_NUMERICSPECIAL, NULL);
388 #endif
389
390         /* Initialize with the current center position. */
391         {
392                 gchar buffer[32];
393                 gfloat lat, lon;
394                 unit2latlon(_center.unitx, _center.unity, lat, lon);
395                 snprintf(buffer, sizeof(buffer), "%.06f", lat);
396                 gtk_label_set_text(GTK_LABEL(txt_lat), buffer);
397                 snprintf(buffer, sizeof(buffer), "%.06f", lon);
398                 gtk_label_set_text(GTK_LABEL(txt_lon), buffer);
399         }
400
401         gtk_widget_show_all(dialog);
402
403         while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog))) {
404                 const gchar *text;
405                 gchar *error_check;
406                 gfloat lat, lon;
407                 guint unitx, unity;
408
409                 text = gtk_entry_get_text(GTK_ENTRY(txt_lat));
410                 lat = strtof(text, &error_check);
411                 if (text == error_check || lat < -90.f || lat > 90.f) {
412                         popup_error(dialog, _("Invalid Latitude"));
413                         continue;
414                 }
415
416                 text = gtk_entry_get_text(GTK_ENTRY(txt_lon));
417                 lon = strtof(text, &error_check);
418                 if (text == error_check || lon < -180.f || lon > 180.f) {
419                         popup_error(dialog, _("Invalid Longitude"));
420                         continue;
421                 }
422
423                 latlon2unit(lat, lon, unitx, unity);
424                 if (_center_mode > 0)
425                         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM
426                                                        (_menu_ac_none_item), TRUE);
427                 map_center_unit(unitx, unity);
428                 break;
429         }
430         gtk_widget_destroy(dialog);
431         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
432         return TRUE;
433 }
434
435 gboolean menu_cb_goto_home(GtkAction * action)
436 {
437         guint unitx, unity;
438
439         printf("%s()\n", __PRETTY_FUNCTION__);
440
441         if (_center_mode > 0)
442                 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM
443                                                (_menu_ac_none_item), TRUE);
444
445         latlon2unit(_home.lat, _home.lon, unitx, unity);
446         map_center_unit(unitx, unity);
447     map_set_autozoom(FALSE);
448         map_update_location_from_center();
449
450         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
451         return TRUE;
452 }
453
454 gboolean menu_cb_goto_destination(GtkAction *action)
455 {
456 guint unitx, unity;
457
458 if (_dest.valid==FALSE) {
459         MACRO_BANNER_SHOW_INFO(_window, _("Destination not set."));
460         return TRUE;
461 }
462 latlon2unit(_dest.lat, _dest.lon, unitx, unity);
463 map_center_unit(unitx, unity);
464 map_set_autozoom(FALSE);
465 return TRUE;
466 }
467
468 gboolean menu_cb_goto_gps(GtkAction * action)
469 {
470         printf("%s()\n", __PRETTY_FUNCTION__);
471
472         if (_center_mode > 0)
473                 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM
474                                                (_menu_ac_none_item), TRUE);
475
476         map_center_unit(_pos.unitx, _pos.unity);
477         map_update_location_from_center();
478
479         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
480         return TRUE;
481 }
482
483 gboolean menu_cb_goto_nextway(GtkAction * action)
484 {
485         printf("%s()\n", __PRETTY_FUNCTION__);
486
487         if (_next_way && _next_way->point->unity) {
488                 if (_center_mode > 0)
489                         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM
490                                                        (_menu_ac_none_item),
491                                                        TRUE);
492
493                 map_center_unit(_next_way->point->unitx,
494                                 _next_way->point->unity);
495         } else {
496                 MACRO_BANNER_SHOW_INFO(_window, _("There is no next waypoint."));
497         }
498
499         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
500         return TRUE;
501 }
502
503 gboolean menu_cb_goto_nearpoi(GtkAction * action)
504 {
505 gdouble lat, lon;
506 poi_info *p;
507
508 printf("%s()\n", __PRETTY_FUNCTION__);
509
510 if (_center_mode > 0) {
511         /* Auto-Center is enabled - use the GPS position. */
512         unit2latlon(_pos.unitx, _pos.unity, lat, lon);
513 } else {
514         /* Auto-Center is disabled - use the view center. */
515         unit2latlon(_center.unitx, _center.unity, lat, lon);
516 }
517
518 p=poi_find_nearest(lat, lon);
519
520 if (p) {
521         guint unitx, unity;
522         gchar *banner;
523
524         latlon2unit(p->lat, p->lon, unitx, unity);
525         banner = g_strdup_printf("%s (%s)", p->label, p->cat_label);
526         g_printf("%s\n", banner);
527         MACRO_BANNER_SHOW_INFO(_window, banner);
528         g_free(banner);
529         poi_free(p);
530
531         if (_center_mode > 0)
532                 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(_menu_ac_none_item), TRUE);
533
534         map_center_unit(unitx, unity);
535         map_update_location_from_center();
536 } else {
537         MACRO_BANNER_SHOW_INFO(_window, _("No POIs found."));
538 }
539
540 vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
541 return TRUE;
542 }
543
544 gboolean menu_cb_maps_repoman(GtkAction * action)
545 {
546         printf("%s()\n", __PRETTY_FUNCTION__);
547         repoman_dialog();
548         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
549         return TRUE;
550 }
551
552 gboolean menu_cb_maps_select(GtkAction * action, gpointer new_repo)
553 {
554         printf("%s()\n", __PRETTY_FUNCTION__);
555         repo_set_curr(new_repo);
556         map_force_redraw();
557         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
558         return TRUE;
559 }
560
561 gboolean cb_zoom_autozoom(GtkAction * action)
562 {
563         printf("%s()\n", __PRETTY_FUNCTION__);
564
565         map_set_autozoom(TRUE);
566
567         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
568         return TRUE;
569 }
570
571 gboolean cb_zoom_base(GtkAction * action)
572 {
573         printf("%s()\n", __PRETTY_FUNCTION__);
574
575         map_set_autozoom(FALSE);
576         map_set_zoom(4);
577
578         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
579         return TRUE;
580 }
581
582 gboolean cb_zoomin(GtkAction * action)
583 {
584         printf("%s()\n", __PRETTY_FUNCTION__);
585
586         map_set_autozoom(FALSE);
587         map_zoom(-1);
588
589         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
590         return TRUE;
591 }
592
593 gboolean cb_zoomout(GtkAction * action)
594 {
595         printf("%s()\n", __PRETTY_FUNCTION__);
596
597         map_set_autozoom(FALSE);
598         map_zoom(1);
599
600         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
601         return TRUE;
602 }
603
604 gboolean cb_fullscreen_click(GtkAction * action)
605 {
606         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(_menu_fullscreen_item), !_fullscreen);
607         return TRUE;
608 }
609
610 gboolean cb_fullscreen(GtkAction * action)
611 {
612         printf("%s()\n", __PRETTY_FUNCTION__);
613
614         if ((_fullscreen = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(_menu_fullscreen_item)))) {
615                 gtk_window_fullscreen(GTK_WINDOW(_window));
616                 gtk_widget_set_state(_toolbar_fullscreen_item, GTK_STATE_ACTIVE);
617         } else {
618                 gtk_window_unfullscreen(GTK_WINDOW(_window));
619                 gtk_widget_set_state(_toolbar_fullscreen_item, GTK_STATE_NORMAL);
620         }
621
622         gtk_idle_add((GSourceFunc) window_present, NULL);
623
624         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
625         return TRUE;
626 }
627
628 gboolean menu_cb_enable_gps(GtkAction * action)
629 {
630         printf("%s()\n", __PRETTY_FUNCTION__);
631
632         if ((_enable_gps =
633              gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM
634                                             (_menu_enable_gps_item)))) {
635                 if (_rcvr_mac) {
636                         set_conn_state(RCVR_DOWN);
637                         rcvr_connect_now();
638                 } else {
639                         popup_error(_window,
640                                     _("Cannot enable GPS until a GPS Receiver MAC "
641                                      "is set in the Settings dialog box."));
642                         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM
643                                                        (_menu_enable_gps_item),
644                                                        FALSE);
645                 }
646         } else {
647                 if (_conn_state > RCVR_OFF)
648                         set_conn_state(RCVR_OFF);
649                 rcvr_disconnect();
650                 track_add(0, FALSE);
651                 _speed_excess = FALSE;
652         }
653         map_move_mark();
654         gps_show_info();
655         gtk_widget_set_sensitive(GTK_WIDGET(_menu_gps_details_item), _enable_gps);
656
657         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
658         return TRUE;
659 }
660
661 gboolean menu_cb_auto_download(GtkAction * action)
662 {
663         printf("%s()\n", __PRETTY_FUNCTION__);
664
665         if ((_auto_download =
666              gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(_menu_auto_download_item)))) {
667                 if (_curr_repo->url == REPOTYPE_NONE)
668                         popup_error(_window,
669                                     _("NOTE: You must set a Map URI in the current repository in "
670                                      "order to download maps."));
671                 map_force_redraw();
672         }
673
674         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
675         return TRUE;
676 }
677
678 gboolean menu_cb_gps_details(GtkAction * action)
679 {
680         printf("%s()\n", __PRETTY_FUNCTION__);
681
682         gps_details();
683
684         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
685         return TRUE;
686 }
687
688 gboolean menu_cb_settings(GtkAction * action)
689 {
690         printf("%s()\n", __PRETTY_FUNCTION__);
691
692         if (settings_dialog()) {
693                 /* Settings have changed - reconnect to receiver. */
694                 if (_enable_gps) {
695                         set_conn_state(RCVR_DOWN);
696                         rcvr_disconnect();
697                         rcvr_connect_now();
698                 }
699         }
700         MACRO_RECALC_FOCUS_BASE();
701         MACRO_RECALC_FOCUS_SIZE();
702         map_force_redraw();
703
704         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
705         return TRUE;
706 }
707
708 gboolean menu_cb_help(GtkAction * action)
709 {
710         printf("%s()\n", __PRETTY_FUNCTION__);
711
712 #ifdef WITH_OSSO
713         ossohelp_show(_osso, HELP_ID_INTRO, 0);
714 #endif
715
716         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
717         return TRUE;
718 }
719
720 gboolean menu_cb_about(GtkAction * action)
721 {
722 #ifdef WITH_OSSO
723 ossohelp_show(_osso, HELP_ID_ABOUT, OSSO_HELP_SHOW_DIALOG);
724 #else
725 gchar *authors[]={
726         "Kaj-Michael Lang","John Costigan","Cezary Jackiewicz", NULL};
727
728 gtk_show_about_dialog(GTK_WINDOW(_window), 
729         "name", "Mapper",
730         "version", VERSION, 
731         "copyright", "Kaj-Michael Lang",
732         "license", "GPL",
733         "authors", authors,
734         NULL);
735 #endif
736 return TRUE;
737 }
738
739 gboolean window_cb_key_press(GtkWidget * widget, GdkEventKey * event)
740 {
741         CustomKey custom_key;
742         printf("%s()\n", __PRETTY_FUNCTION__);
743
744         switch (event->keyval) {
745         case HILDON_HARDKEY_UP:
746                 custom_key = CUSTOM_KEY_UP;
747                 break;
748         case HILDON_HARDKEY_DOWN:
749                 custom_key = CUSTOM_KEY_DOWN;
750                 break;
751         case HILDON_HARDKEY_LEFT:
752                 custom_key = CUSTOM_KEY_LEFT;
753                 break;
754         case HILDON_HARDKEY_RIGHT:
755                 custom_key = CUSTOM_KEY_RIGHT;
756                 break;
757         case HILDON_HARDKEY_SELECT:
758                 custom_key = CUSTOM_KEY_SELECT;
759                 break;
760         case HILDON_HARDKEY_INCREASE:
761                 custom_key = CUSTOM_KEY_INCREASE;
762                 break;
763         case HILDON_HARDKEY_DECREASE:
764                 custom_key = CUSTOM_KEY_DECREASE;
765                 break;
766         case HILDON_HARDKEY_FULLSCREEN:
767                 custom_key = CUSTOM_KEY_FULLSCREEN;
768                 break;
769         case HILDON_HARDKEY_ESC:
770                 custom_key = CUSTOM_KEY_ESC;
771                 break;
772         default:
773                 vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
774                 return FALSE;
775         }
776
777         switch (_action[custom_key]) {
778         case CUSTOM_ACTION_PAN_NORTH:
779                 map_pan(0, -PAN_UNITS);
780                 break;
781
782         case CUSTOM_ACTION_PAN_WEST:
783                 map_pan(-PAN_UNITS, 0);
784                 break;
785
786         case CUSTOM_ACTION_PAN_SOUTH:
787                 map_pan(0, PAN_UNITS);
788                 break;
789
790         case CUSTOM_ACTION_PAN_EAST:
791                 map_pan(PAN_UNITS, 0);
792                 break;
793
794         case CUSTOM_ACTION_TOGGLE_AUTOCENTER:
795                 switch (_center_mode) {
796                 case CENTER_LATLON:
797                 case CENTER_WAS_LEAD:
798                         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM
799                                                        (_menu_ac_lead_item),
800                                                        TRUE);
801                         break;
802                 case CENTER_LEAD:
803                 case CENTER_WAS_LATLON:
804                         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM
805                                                        (_menu_ac_latlon_item),
806                                                        TRUE);
807                         break;
808                 default:;
809                 }
810                 break;
811
812         case CUSTOM_ACTION_ZOOM_IN:
813         case CUSTOM_ACTION_ZOOM_OUT:
814                 if (!_key_zoom_timeout_sid) {
815                         g_printf("Z: %d %d\n", _key_zoom_new, _zoom);
816                         _key_zoom_new = _zoom
817                             + (_action[custom_key] == CUSTOM_ACTION_ZOOM_IN
818                                ? -_curr_repo->view_zoom_steps
819                                : _curr_repo->view_zoom_steps);
820                         /* Remember, _key_zoom_new is unsigned. */
821                         if (_key_zoom_new < MAX_ZOOM) {
822                                 gchar buffer[80];
823                                 snprintf(buffer, sizeof(buffer), "%s %d",
824                                          _("Zoom to Level"), _key_zoom_new);
825                                 MACRO_BANNER_SHOW_INFO(_window, buffer);
826                                 _key_zoom_timeout_sid =
827                                     g_timeout_add(500, map_key_zoom_timeout,
828                                                   NULL);
829                         }
830                 }
831                 break;
832
833         case CUSTOM_ACTION_TOGGLE_FULLSCREEN:
834                 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(_menu_fullscreen_item), !_fullscreen);
835                 break;
836
837         case CUSTOM_ACTION_TOGGLE_TRACKS:
838                 switch (_show_tracks) {
839                 case 0:
840                         /* Nothing shown, nothing saved; just set both. */
841                         _show_tracks = TRACKS_MASK | ROUTES_MASK;
842                         break;
843                 case TRACKS_MASK << 16:
844                 case ROUTES_MASK << 16:
845                 case (ROUTES_MASK | TRACKS_MASK) << 16:
846                         /* Something was saved and nothing changed since.
847                          * Restore saved. */
848                         _show_tracks = _show_tracks >> 16;
849                         break;
850                 default:
851                         /* There is no history, or they changed something
852                          * since the last historical change. Save and
853                          * clear. */
854                         _show_tracks = _show_tracks << 16;
855                 }
856                 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM
857                                                (_menu_show_routes_item),
858                                                _show_tracks & ROUTES_MASK);
859
860                 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM
861                                                (_menu_show_tracks_item),
862                                                _show_tracks & TRACKS_MASK);
863
864         case CUSTOM_ACTION_TOGGLE_SCALE:
865                 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM
866                                                (_menu_show_scale_item),
867                                                !_show_scale);
868                 break;
869
870         case CUSTOM_ACTION_TOGGLE_POI:
871                 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM
872                                                (_menu_show_poi_item),
873                                                !_show_poi);
874                 break;
875         case CUSTOM_ACTION_CHANGE_REPO:{
876                         GList *curr = g_list_find(_repo_list, _curr_repo);
877                         if (!curr)
878                                 break;
879
880                         /* Loop until we reach a next-able repo, or until we get
881                          * back to the current repo. */
882                         while ((curr = (curr->next ? curr->next : _repo_list))
883                                && !((RepoData *) curr->data)->nextable
884                                && curr->data != _curr_repo) {
885                         }
886
887                         if (curr->data != _curr_repo) {
888                                 repo_set_curr(curr->data);
889                                 gtk_check_menu_item_set_active
890                                     (GTK_CHECK_MENU_ITEM(_curr_repo->menu_item),
891                                      TRUE);
892                         } else {
893                                 popup_error(_window,
894                                             _
895                                             ("There are no other next-able repositories."));
896                         }
897                         break;
898                 }
899
900         case CUSTOM_ACTION_ROUTE_DISTNEXT:
901                 route_show_distance_to_next();
902                 break;
903
904         case CUSTOM_ACTION_ROUTE_DISTLAST:
905                 route_show_distance_to_last();
906                 break;
907
908         case CUSTOM_ACTION_TRACK_BREAK:
909                 track_insert_break();
910                 break;
911
912         case CUSTOM_ACTION_TRACK_DISTLAST:
913                 track_show_distance_from_last();
914                 break;
915
916         case CUSTOM_ACTION_TRACK_DISTFIRST:
917                 track_show_distance_from_first();
918                 break;
919
920         case CUSTOM_ACTION_TOGGLE_GPS:
921                 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM
922                                                (_menu_enable_gps_item),
923                                                !_enable_gps);
924                 break;
925
926         case CUSTOM_ACTION_TOGGLE_GPSINFO:
927                 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM
928                                                (_menu_gps_show_info_item),
929                                                !_gps_info);
930                 break;
931
932         case CUSTOM_ACTION_TOGGLE_SPEEDLIMIT:
933                 _speed_limit_on ^= 1;
934                 break;
935
936         default:
937                 vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
938                 return FALSE;
939         }
940
941         return TRUE;
942         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
943 }
944
945 gboolean window_cb_key_release(GtkWidget * widget, GdkEventKey * event)
946 {
947         printf("%s()\n", __PRETTY_FUNCTION__);
948
949         switch (event->keyval) {
950         case HILDON_HARDKEY_INCREASE:
951         case HILDON_HARDKEY_DECREASE:
952                 if (_key_zoom_timeout_sid) {
953                         g_source_remove(_key_zoom_timeout_sid);
954                         _key_zoom_timeout_sid = 0;
955                         map_set_zoom(_key_zoom_new);
956                 }
957                 return TRUE;
958
959         default:
960                 return FALSE;
961         }
962         vprintf("%s(): return\n", __PRETTY_FUNCTION__);
963 }
964
965 void cmenu_show_latlon(guint unitx, guint unity)
966 {
967         gfloat lat, lon;
968         gchar buffer[80], tmp1[16], tmp2[16];
969         printf("%s()\n", __PRETTY_FUNCTION__);
970
971         g_printf("S: %d %d\n", unitx, unity);
972
973         unit2latlon(unitx, unity, lat, lon);
974         lat_format(lat, tmp1);
975         lon_format(lon, tmp2);
976
977         snprintf(buffer, sizeof(buffer),
978                  "%s: %s\n"
979                  "%s: %s", _("Latitude"), tmp1, _("Longitude"), tmp2);
980
981         MACRO_BANNER_SHOW_INFO(_window, buffer);
982
983         vprintf("%s(): return\n", __PRETTY_FUNCTION__);
984 }
985
986 void cmenu_clip_latlon(guint unitx, guint unity)
987 {
988         gchar buffer[80];
989         gfloat lat, lon;
990         printf("%s()\n", __PRETTY_FUNCTION__);
991
992         unit2latlon(unitx, unity, lat, lon);
993
994         snprintf(buffer, sizeof(buffer), "%.06f,%.06f", lat, lon);
995
996         gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD),
997                                buffer, -1);
998
999         vprintf("%s(): return\n", __PRETTY_FUNCTION__);
1000 }
1001
1002 void cmenu_route_to(guint unitx, guint unity)
1003 {
1004         gchar buffer[80];
1005         gchar strlat[32];
1006         gchar strlon[32];
1007         gfloat lat, lon;
1008         printf("%s()\n", __PRETTY_FUNCTION__);
1009
1010         unit2latlon(unitx, unity, lat, lon);
1011
1012         g_ascii_formatd(strlat, 32, "%.06f", lat);
1013         g_ascii_formatd(strlon, 32, "%.06f", lon);
1014         snprintf(buffer, sizeof(buffer), "%s, %s", strlat, strlon);
1015
1016         route_download(buffer);
1017
1018         vprintf("%s(): return\n", __PRETTY_FUNCTION__);
1019 }
1020
1021 void cmenu_distance_to(guint unitx, guint unity)
1022 {
1023         gchar buffer[80];
1024         gfloat lat, lon;
1025         printf("%s()\n", __PRETTY_FUNCTION__);
1026
1027         unit2latlon(unitx, unity, lat, lon);
1028
1029         snprintf(buffer, sizeof(buffer), "%s: %.02f %s", _("Distance"),
1030                  calculate_distance(_gps.lat, _gps.lon, lat, lon)
1031                  * UNITS_CONVERT[_units], UNITS_TEXT[_units]);
1032         MACRO_BANNER_SHOW_INFO(_window, buffer);
1033
1034         vprintf("%s(): return\n", __PRETTY_FUNCTION__);
1035 }
1036
1037 void cmenu_add_route(guint unitx, guint unity)
1038 {
1039         printf("%s()\n", __PRETTY_FUNCTION__);
1040         MACRO_PATH_INCREMENT_TAIL(_route);
1041         _route.tail->unitx = x2unit(_cmenu_position_x);
1042         _route.tail->unity = y2unit(_cmenu_position_y);
1043         route_find_nearest_point();
1044         map_force_redraw();
1045         vprintf("%s(): return\n", __PRETTY_FUNCTION__);
1046 }
1047
1048 void cmenu_route_add_way(guint unitx, guint unity)
1049 {
1050         gfloat lat, lon;
1051         gchar tmp1[16], tmp2[16], *p_latlon;
1052         GtkWidget *dialog;
1053         GtkWidget *table;
1054         GtkWidget *label;
1055         GtkWidget *txt_scroll;
1056         GtkWidget *txt_desc;
1057         printf("%s()\n", __PRETTY_FUNCTION__);
1058
1059         dialog = gtk_dialog_new_with_buttons(_("Add Waypoint"),
1060                                              GTK_WINDOW(_window),
1061                                              GTK_DIALOG_MODAL, GTK_STOCK_OK,
1062                                              GTK_RESPONSE_ACCEPT,
1063                                              GTK_STOCK_CANCEL,
1064                                              GTK_RESPONSE_REJECT, NULL);
1065
1066         gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
1067                            table = gtk_table_new(2, 2, FALSE), TRUE, TRUE, 0);
1068
1069         gtk_table_attach(GTK_TABLE(table),
1070                          label = gtk_label_new(_("Lat, Lon")),
1071                          0, 1, 0, 1, GTK_FILL, 0, 2, 4);
1072         gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1073
1074         unit2latlon(unitx, unity, lat, lon);
1075         lat_format(lat, tmp1);
1076         lon_format(lon, tmp2);
1077         p_latlon = g_strdup_printf("%s, %s", tmp1, tmp2);
1078         gtk_table_attach(GTK_TABLE(table),
1079                          label = gtk_label_new(p_latlon),
1080                          1, 2, 0, 1, GTK_FILL, 0, 2, 4);
1081         gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
1082         g_free(p_latlon);
1083
1084         gtk_table_attach(GTK_TABLE(table),
1085                          label = gtk_label_new(_("Description")),
1086                          0, 1, 1, 2, GTK_FILL, 0, 2, 4);
1087         gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1088
1089         txt_scroll = gtk_scrolled_window_new(NULL, NULL);
1090         gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(txt_scroll),
1091                                             GTK_SHADOW_IN);
1092         gtk_table_attach(GTK_TABLE(table),
1093                          txt_scroll,
1094                          1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
1095
1096         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scroll),
1097                                        GTK_POLICY_AUTOMATIC,
1098                                        GTK_POLICY_AUTOMATIC);
1099
1100         txt_desc = gtk_text_view_new();
1101         gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt_desc), GTK_WRAP_WORD);
1102
1103         gtk_container_add(GTK_CONTAINER(txt_scroll), txt_desc);
1104         gtk_widget_set_size_request(GTK_WIDGET(txt_scroll), 400, 60);
1105
1106         gtk_widget_show_all(dialog);
1107
1108         while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog))) {
1109                 GtkTextBuffer *tbuf;
1110                 GtkTextIter ti1, ti2;
1111                 gchar *desc;
1112
1113                 tbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txt_desc));
1114                 gtk_text_buffer_get_iter_at_offset(tbuf, &ti1, 0);
1115                 gtk_text_buffer_get_end_iter(tbuf, &ti2);
1116                 desc = gtk_text_buffer_get_text(tbuf, &ti1, &ti2, TRUE);
1117
1118                 if (*desc) {
1119                         /* There's a description.  Add a waypoint. */
1120                         MACRO_PATH_INCREMENT_TAIL(_route);
1121                         _route.tail->unitx = unitx;
1122                         _route.tail->unity = unity;
1123                         _route.tail->time = 0;
1124                         _route.tail->altitude = NAN;
1125
1126                         MACRO_PATH_INCREMENT_WTAIL(_route);
1127                         _route.wtail->point = _route.tail;
1128                         _route.wtail->desc
1129                             = gtk_text_buffer_get_text(tbuf, &ti1, &ti2, TRUE);
1130                 } else {
1131                         GtkWidget *confirm;
1132
1133                         g_free(desc);
1134
1135                         confirm = hildon_note_new_confirmation(GTK_WINDOW(dialog),
1136                                                          _("Creating a \"waypoint\" with no description actually "
1137                                                           "adds a break point.  Is that what you want?"));
1138
1139                         if (GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm))) {
1140                                 /* There's no description.  Add a break by adding a (0, 0)
1141                                  * point (if necessary), and then the ordinary route point. */
1142                                 if (_route.tail->unity) {
1143                                         MACRO_PATH_INCREMENT_TAIL(_route);
1144                                         *_route.tail = _point_null;
1145                                 }
1146
1147                                 MACRO_PATH_INCREMENT_TAIL(_route);
1148                                 _route.tail->unitx = unitx;
1149                                 _route.tail->unity = unity;
1150                                 _route.tail->time = 0;
1151                                 _route.tail->altitude = NAN;
1152
1153                                 gtk_widget_destroy(confirm);
1154                         } else {
1155                                 gtk_widget_destroy(confirm);
1156                                 continue;
1157                         }
1158                 }
1159
1160                 route_find_nearest_point();
1161                 map_render_paths();
1162                 MACRO_QUEUE_DRAW_AREA();
1163                 break;
1164         }
1165         gtk_widget_destroy(dialog);
1166         vprintf("%s(): return\n", __PRETTY_FUNCTION__);
1167 }
1168
1169 gboolean cmenu_cb_loc_show_latlon(GtkAction * action)
1170 {
1171         printf("%s()\n", __PRETTY_FUNCTION__);
1172
1173         cmenu_show_latlon(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y));
1174
1175         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
1176         return TRUE;
1177 }
1178
1179 gboolean cmenu_cb_loc_clip_latlon(GtkAction * action)
1180 {
1181         printf("%s()\n", __PRETTY_FUNCTION__);
1182
1183         cmenu_clip_latlon(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y));
1184
1185         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
1186         return TRUE;
1187 }
1188
1189 gboolean cmenu_cb_loc_route_to(GtkAction * action)
1190 {
1191         printf("%s()\n", __PRETTY_FUNCTION__);
1192
1193         cmenu_route_to(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y));
1194
1195         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
1196         return TRUE;
1197 }
1198
1199 gboolean cmenu_cb_loc_distance_to(GtkAction * action)
1200 {
1201         printf("%s()\n", __PRETTY_FUNCTION__);
1202
1203         cmenu_distance_to(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y));
1204
1205         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
1206         return TRUE;
1207 }
1208
1209 gboolean cmenu_cb_loc_add_route(GtkAction * action)
1210 {
1211         printf("%s()\n", __PRETTY_FUNCTION__);
1212
1213         cmenu_add_route(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y));
1214
1215         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
1216         return TRUE;
1217 }
1218
1219 gboolean cmenu_cb_loc_add_way(GtkAction * action)
1220 {
1221         printf("%s()\n", __PRETTY_FUNCTION__);
1222
1223         cmenu_route_add_way(x2unit(_cmenu_position_x),
1224                             y2unit(_cmenu_position_y));
1225
1226         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
1227         return TRUE;
1228 }
1229
1230 gboolean cmenu_cb_loc_add_poi(GtkAction * action)
1231 {
1232         printf("%s()\n", __PRETTY_FUNCTION__);
1233
1234         poi_dialog(ACTION_ADD_POI, x2unit(_cmenu_position_x), y2unit(_cmenu_position_y));
1235
1236         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
1237         return TRUE;
1238 }
1239
1240 gboolean cb_add_poi(GtkAction * action)
1241 {
1242         guint unitx, unity;
1243         printf("%s()\n", __PRETTY_FUNCTION__);
1244
1245         if (_center_mode > 0) {
1246                 latlon2unit(_gps.lat, _gps.lon, unitx, unity);
1247                 poi_dialog(ACTION_ADD_POI, unitx, unity);
1248         } else {
1249                 poi_dialog(ACTION_ADD_POI, _center.unitx, _center.unity);
1250         }
1251
1252         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
1253         return TRUE;
1254 }
1255
1256 gboolean cmenu_cb_loc_set_home(GtkAction * action)
1257 {
1258 _pos.unitx = x2unit(_cmenu_position_x);
1259 _pos.unity = y2unit(_cmenu_position_y);
1260 unit2latlon(_pos.unitx, _pos.unity, _home.lat, _home.lon);
1261 _home.valid=TRUE;
1262
1263 config_save_home();
1264 return TRUE;
1265 }
1266
1267 gboolean cmenu_cb_loc_set_destination(GtkAction *action)
1268 {
1269 _pos.unitx = x2unit(_cmenu_position_x);
1270 _pos.unity = y2unit(_cmenu_position_y);
1271 unit2latlon(_pos.unitx, _pos.unity, _dest.lat, _dest.lon);
1272 _dest.valid=TRUE;
1273 return TRUE;
1274 }
1275
1276 gboolean cmenu_cb_loc_set_gps(GtkAction * action)
1277 {
1278 _pos.unitx = x2unit(_cmenu_position_x);
1279 _pos.unity = y2unit(_cmenu_position_y);
1280 unit2latlon(_pos.unitx, _pos.unity, _gps.lat, _gps.lon);
1281
1282 /* Move mark to new location. */
1283 refresh_mark();
1284
1285 return TRUE;
1286 }
1287
1288 gboolean cmenu_cb_way_show_latlon(GtkAction * action)
1289 {
1290         WayPoint *way;
1291         printf("%s()\n", __PRETTY_FUNCTION__);
1292
1293         if ((way = find_nearest_waypoint(x2unit(_cmenu_position_x),
1294                                          y2unit(_cmenu_position_y))))
1295                 cmenu_show_latlon(way->point->unitx, way->point->unity);
1296
1297         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
1298         return TRUE;
1299 }
1300
1301 gboolean cmenu_cb_way_show_desc(GtkAction * action)
1302 {
1303         WayPoint *way;
1304         printf("%s()\n", __PRETTY_FUNCTION__);
1305
1306         if ((way = find_nearest_waypoint(x2unit(_cmenu_position_x),
1307                                          y2unit(_cmenu_position_y)))) {
1308                 MACRO_BANNER_SHOW_INFO(_window, way->desc);
1309         }
1310
1311         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
1312         return TRUE;
1313 }
1314
1315 gboolean cmenu_cb_way_clip_latlon(GtkAction * action)
1316 {
1317         WayPoint *way;
1318         printf("%s()\n", __PRETTY_FUNCTION__);
1319
1320         if ((way = find_nearest_waypoint(x2unit(_cmenu_position_x),
1321                                          y2unit(_cmenu_position_y))))
1322                 cmenu_clip_latlon(way->point->unitx, way->point->unity);
1323
1324         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
1325         return TRUE;
1326 }
1327
1328 gboolean cmenu_cb_way_clip_desc(GtkAction * action)
1329 {
1330         WayPoint *way;
1331         printf("%s()\n", __PRETTY_FUNCTION__);
1332
1333         if ((way = find_nearest_waypoint(x2unit(_cmenu_position_x),
1334                                          y2unit(_cmenu_position_y))))
1335                 gtk_clipboard_set_text(gtk_clipboard_get
1336                                        (GDK_SELECTION_CLIPBOARD), way->desc,
1337                                        -1);
1338
1339         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
1340         return TRUE;
1341 }
1342
1343 gboolean cmenu_cb_way_route_to(GtkAction * action)
1344 {
1345         WayPoint *way;
1346         printf("%s()\n", __PRETTY_FUNCTION__);
1347
1348         if ((way = find_nearest_waypoint(x2unit(_cmenu_position_x),
1349                                          y2unit(_cmenu_position_y))))
1350                 cmenu_route_to(way->point->unitx, way->point->unity);
1351
1352         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
1353         return TRUE;
1354 }
1355
1356 gboolean cmenu_cb_way_distance_to(GtkAction * action)
1357 {
1358         WayPoint *way;
1359         printf("%s()\n", __PRETTY_FUNCTION__);
1360
1361         if ((way = find_nearest_waypoint(x2unit(_cmenu_position_x),
1362                                          y2unit(_cmenu_position_y))))
1363                 route_show_distance_to(way->point);
1364
1365         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
1366         return TRUE;
1367 }
1368
1369 gboolean cmenu_cb_way_delete(GtkAction * action)
1370 {
1371         WayPoint *way;
1372         printf("%s()\n", __PRETTY_FUNCTION__);
1373
1374         if ((way = find_nearest_waypoint(x2unit(_cmenu_position_x),
1375                                          y2unit(_cmenu_position_y)))) {
1376                 gchar buffer[BUFFER_SIZE];
1377                 GtkWidget *confirm;
1378
1379                 snprintf(buffer, sizeof(buffer), "%s:\n%s\n",
1380                          _("Confirm delete of waypoint"), way->desc);
1381                 confirm = hildon_note_new_confirmation(GTK_WINDOW(_window), buffer);
1382
1383                 if (GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm))) {
1384                         Point *pdel_min, *pdel_max, *pdel_start, *pdel_end;
1385                         guint num_del;
1386
1387                         /* Delete surrounding route data, too. */
1388                         if (way == _route.whead)
1389                                 pdel_min = _route.head;
1390                         else
1391                                 pdel_min = way[-1].point;
1392
1393                         if (way == _route.wtail)
1394                                 pdel_max = _route.tail;
1395                         else
1396                                 pdel_max = way[1].point;
1397
1398                         /* Find largest continuous segment around the waypoint, EXCLUDING
1399                          * pdel_min and pdel_max. */
1400                         for (pdel_start = way->point - 1; pdel_start->unity
1401                              && pdel_start > pdel_min; pdel_start--) {
1402                         }
1403                         for (pdel_end = way->point + 1; pdel_end->unity
1404                              && pdel_end < pdel_max; pdel_end++) {
1405                         }
1406
1407                         /* If pdel_end is set to _route.tail, and if _route.tail is a
1408                          * non-zero point, then delete _route.tail. */
1409                         if (pdel_end == _route.tail && pdel_end->unity)
1410                                 pdel_end++;     /* delete _route.tail too */
1411                         /* else, if *both* endpoints are zero points, delete one. */
1412                         else if (!pdel_start->unity && !pdel_end->unity)
1413                                 pdel_start--;
1414
1415                         /* Delete BETWEEN pdel_start and pdel_end, exclusive. */
1416                         num_del = pdel_end - pdel_start - 1;
1417
1418                         memmove(pdel_start + 1, pdel_end,
1419                                 (_route.tail - pdel_end + 1) * sizeof(Point));
1420                         _route.tail -= num_del;
1421
1422                         /* Remove waypoint and move/adjust subsequent waypoints. */
1423                         g_free(way->desc);
1424                         while (way++ != _route.wtail) {
1425                                 way[-1] = *way;
1426                                 way[-1].point -= num_del;
1427                         }
1428                         _route.wtail--;
1429
1430                         route_find_nearest_point();
1431                         map_force_redraw();
1432                 }
1433                 gtk_widget_destroy(confirm);
1434         }
1435
1436         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
1437         return TRUE;
1438 }
1439
1440 gboolean cmenu_cb_way_add_poi(GtkAction * action)
1441 {
1442         WayPoint *way;
1443         printf("%s()\n", __PRETTY_FUNCTION__);
1444
1445         if ((way = find_nearest_waypoint(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y))))
1446                 poi_dialog(ACTION_ADD_POI, way->point->unitx, way->point->unity);
1447
1448         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
1449         return TRUE;
1450 }
1451
1452 gboolean cmenu_cb_poi_route_to(GtkAction * action)
1453 {
1454         poi_info poi;
1455         printf("%s()\n", __PRETTY_FUNCTION__);
1456
1457         if (select_poi(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y), &poi)) {
1458                 guint unitx, unity;
1459                 latlon2unit(poi.lat, poi.lon, unitx, unity);
1460                 cmenu_route_to(unitx, unity);
1461         }
1462
1463         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
1464         return TRUE;
1465 }
1466
1467 gboolean cmenu_cb_poi_distance_to(GtkAction * action)
1468 {
1469         poi_info poi;
1470         printf("%s()\n", __PRETTY_FUNCTION__);
1471
1472         if (select_poi(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y), &poi)) {
1473                 guint unitx, unity;
1474                 latlon2unit(poi.lat, poi.lon, unitx, unity);
1475                 cmenu_distance_to(unitx, unity);
1476         }
1477
1478         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
1479         return TRUE;
1480 }
1481
1482 gboolean cmenu_cb_poi_add_route(GtkAction * action)
1483 {
1484         poi_info poi;
1485         printf("%s()\n", __PRETTY_FUNCTION__);
1486
1487         if (select_poi(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y), &poi)) {
1488                 guint unitx, unity;
1489                 latlon2unit(poi.lat, poi.lon, unitx, unity);
1490                 cmenu_add_route(unitx, unity);
1491         }
1492
1493         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
1494         return TRUE;
1495 }
1496
1497 gboolean cmenu_cb_poi_add_way(GtkAction * action)
1498 {
1499         poi_info poi;
1500         printf("%s()\n", __PRETTY_FUNCTION__);
1501
1502         if (select_poi(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y), &poi)) {
1503                 guint unitx, unity;
1504                 latlon2unit(poi.lat, poi.lon, unitx, unity);
1505                 cmenu_route_add_way(unitx, unity);
1506         }
1507
1508         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
1509         return TRUE;
1510 }
1511
1512 gboolean cmenu_cb_poi_edit_poi(GtkAction * action)
1513 {
1514         printf("%s()\n", __PRETTY_FUNCTION__);
1515
1516         poi_dialog(ACTION_EDIT_POI, x2unit(_cmenu_position_x), y2unit(_cmenu_position_y));
1517
1518         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
1519         return TRUE;
1520 }