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