]> git.itanic.dy.fi Git - maemo-mapper/blob - src/cmenu.c
1c5612def3474d62bf4f9b0fcd7e80cbefed50ca
[maemo-mapper] / src / cmenu.c
1 /*
2  * Copyright (C) 2006, 2007 John Costigan.
3  *
4  * POI and GPS-Info code originally written by Cezary Jackiewicz.
5  *
6  * Default map data provided by http://www.openstreetmap.org/
7  *
8  * This file is part of Maemo Mapper.
9  *
10  * Maemo Mapper is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * Maemo Mapper is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #    include "config.h"
26 #endif
27
28 #define _GNU_SOURCE
29
30 #include <string.h>
31 #include <math.h>
32 #include <gtk/gtk.h>
33 #include <gconf/gconf-client.h>
34
35 #ifndef LEGACY
36 #    include <hildon/hildon-note.h>
37 #    include <hildon/hildon-banner.h>
38 #else
39 #    include <hildon-widgets/hildon-note.h>
40 #    include <hildon-widgets/hildon-banner.h>
41 #endif
42
43 #include "types.h"
44 #include "data.h"
45 #include "defines.h"
46
47 #include "cmenu.h"
48 #include "display.h"
49 #include "gdk-pixbuf-rotate.h"
50 #include "menu.h"
51 #include "path.h"
52 #include "poi.h"
53 #include "util.h"
54
55 #define GCONF_SUPL_KEY_PREFIX "/system/osso/supl"
56 #define GCONF_KEY_SUPL_LAT GCONF_SUPL_KEY_PREFIX"/pos_latitude"
57 #define GCONF_KEY_SUPL_LON GCONF_SUPL_KEY_PREFIX"/pos_longitude"
58 #define GCONF_KEY_SUPL_TIME GCONF_SUPL_KEY_PREFIX"/pos_timestamp"
59
60 static void
61 cmenu_show_latlon(gint unitx, gint unity)
62 {
63   gdouble lat, lon;
64   gchar buffer[80], tmp1[LL_FMT_LEN], tmp2[LL_FMT_LEN];
65   printf("%s()\n", __PRETTY_FUNCTION__);
66
67   unit2latlon(unitx, unity, lat, lon);
68   lat_format(lat, tmp1);
69   lon_format(lon, tmp2);
70
71   snprintf(buffer, sizeof(buffer),
72             "%s: %s\n"
73           "%s: %s",
74           _("Latitude"), tmp1,
75           _("Longitude"), tmp2);
76
77   MACRO_BANNER_SHOW_INFO(_window, buffer);
78
79   vprintf("%s(): return\n", __PRETTY_FUNCTION__);
80 }
81
82 static void
83 cmenu_clip_latlon(gint unitx, gint unity)
84 {
85     gchar buffer[80];
86     gdouble lat, lon;
87     printf("%s()\n", __PRETTY_FUNCTION__);
88
89     unit2latlon(unitx, unity, lat, lon);
90
91     snprintf(buffer, sizeof(buffer), "%.06f,%.06f", lat, lon);
92
93     gtk_clipboard_set_text(
94             gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), buffer, -1);
95
96     vprintf("%s(): return\n", __PRETTY_FUNCTION__);
97 }
98
99 static void
100 cmenu_route_to(gint unitx, gint unity)
101 {
102     gchar buffer[80];
103     gchar strlat[32];
104     gchar strlon[32];
105     gdouble lat, lon;
106     printf("%s()\n", __PRETTY_FUNCTION__);
107
108     unit2latlon(unitx, unity, lat, lon);
109
110     g_ascii_formatd(strlat, 32, "%.06f", lat);
111     g_ascii_formatd(strlon, 32, "%.06f", lon);
112     snprintf(buffer, sizeof(buffer), "%s, %s", strlat, strlon);
113
114     route_download(buffer);
115
116     vprintf("%s(): return\n", __PRETTY_FUNCTION__);
117 }
118
119 static void
120 cmenu_distance_to(gint unitx, gint unity)
121 {
122     gchar buffer[80];
123     gdouble lat, lon;
124     printf("%s()\n", __PRETTY_FUNCTION__);
125
126     unit2latlon(unitx, unity, lat, lon);
127
128     snprintf(buffer, sizeof(buffer), "%s: %.02f %s", _("Distance"),
129             calculate_distance(_gps.lat, _gps.lon, lat, lon)
130               * UNITS_CONVERT[_units],
131             UNITS_ENUM_TEXT[_units]);
132     MACRO_BANNER_SHOW_INFO(_window, buffer);
133
134     vprintf("%s(): return\n", __PRETTY_FUNCTION__);
135 }
136
137 static void
138 cmenu_add_route(gint unitx, gint unity)
139 {
140     printf("%s()\n", __PRETTY_FUNCTION__);
141     MACRO_PATH_INCREMENT_TAIL(_route);
142     screen2unit(_cmenu_position_x, _cmenu_position_y,
143             _route.tail->unitx, _route.tail->unity);
144     route_find_nearest_point();
145     map_force_redraw();
146     vprintf("%s(): return\n", __PRETTY_FUNCTION__);
147 }
148
149 static gboolean
150 cmenu_cb_loc_show_latlon(GtkMenuItem *item)
151 {
152     gint unitx, unity;
153     gdouble lat, lon;
154     printf("%s()\n", __PRETTY_FUNCTION__);
155
156     screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
157     unit2latlon(unitx, unity, lat, lon);
158
159     latlon_dialog(lat, lon);
160
161     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
162     return TRUE;
163 }
164
165 static gboolean
166 cmenu_cb_loc_route_to(GtkMenuItem *item)
167 {
168     gint unitx, unity;
169     printf("%s()\n", __PRETTY_FUNCTION__);
170
171     screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
172     cmenu_route_to(unitx, unity);
173
174     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
175     return TRUE;
176 }
177
178 static gboolean
179 cmenu_cb_loc_download_poi(GtkMenuItem *item)
180 {
181     gint unitx, unity;
182     printf("%s()\n", __PRETTY_FUNCTION__);
183
184     screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
185     poi_download_dialog(unitx, unity);
186
187     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
188     return TRUE;
189 }
190
191 static gboolean
192 cmenu_cb_loc_browse_poi(GtkMenuItem *item)
193 {
194     gint unitx, unity;
195     printf("%s()\n", __PRETTY_FUNCTION__);
196
197     screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
198     poi_browse_dialog(unitx, unity);
199
200     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
201     return TRUE;
202 }
203
204 static gboolean
205 cmenu_cb_loc_distance_to(GtkMenuItem *item)
206 {
207     gint unitx, unity;
208     printf("%s()\n", __PRETTY_FUNCTION__);
209
210     screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
211     cmenu_distance_to(unitx, unity);
212
213     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
214     return TRUE;
215 }
216
217 static gboolean
218 cmenu_cb_loc_add_route(GtkMenuItem *item)
219 {
220     gint unitx, unity;
221     printf("%s()\n", __PRETTY_FUNCTION__);
222
223     screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
224     cmenu_add_route(unitx, unity);
225
226     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
227     return TRUE;
228 }
229
230 static gboolean
231 cmenu_cb_loc_add_way(GtkMenuItem *item)
232 {
233     gint unitx, unity;
234     printf("%s()\n", __PRETTY_FUNCTION__);
235
236     screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
237     route_add_way_dialog(unitx, unity);
238
239     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
240     return TRUE;
241 }
242
243 static gboolean
244 cmenu_cb_loc_add_poi(GtkMenuItem *item)
245 {
246     gint unitx, unity;
247     printf("%s()\n", __PRETTY_FUNCTION__);
248
249     screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
250     poi_add_dialog(_window, unitx, unity);
251
252     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
253     return TRUE;
254 }
255
256 static gboolean
257 cmenu_cb_loc_set_gps(GtkMenuItem *item)
258 {
259     printf("%s()\n", __PRETTY_FUNCTION__);
260
261     screen2unit(_cmenu_position_x, _cmenu_position_y, _pos.unitx, _pos.unity);
262     unit2latlon(_pos.unitx, _pos.unity, _gps.lat, _gps.lon);
263
264     /* Move mark to new location. */
265     map_refresh_mark(_center_mode > 0);
266
267     GConfClient *gconf_client = gconf_client_get_default();
268     GTimeVal curtime;
269
270     gconf_client_set_float(gconf_client, GCONF_KEY_SUPL_LON, _gps.lon, NULL);
271     gconf_client_set_float(gconf_client, GCONF_KEY_SUPL_LAT, _gps.lat, NULL);
272     g_get_current_time(&curtime);
273     gconf_client_set_float(gconf_client, GCONF_KEY_SUPL_TIME, curtime.tv_sec, NULL);
274
275     g_object_unref(gconf_client);
276
277     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
278     return TRUE;
279 }
280
281 static gboolean
282 cmenu_cb_loc_apply_correction(GtkMenuItem *item)
283 {
284     printf("%s()\n", __PRETTY_FUNCTION__);
285
286     if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item)))
287     {
288         /* Get difference between tap point and GPS location. */
289         gint unitx, unity;
290         screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
291         _map_correction_unitx = unitx - _pos.unitx;
292         _map_correction_unity = unity - _pos.unity;
293         map_refresh_mark(TRUE);
294         MACRO_BANNER_SHOW_INFO(_window, _("Map correction applied."));
295     }
296     else
297     {
298         _map_correction_unitx = 0;
299         _map_correction_unity = 0;
300         map_refresh_mark(TRUE);
301         MACRO_BANNER_SHOW_INFO(_window, _("Map correction removed."));
302     }
303
304     printf("Map correction now set to: %d, %d\n");
305
306     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
307     return TRUE;
308 }
309
310 static gboolean
311 cmenu_cb_way_show_latlon(GtkMenuItem *item)
312 {
313     gint unitx, unity;
314     WayPoint *way;
315     printf("%s()\n", __PRETTY_FUNCTION__);
316
317     screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
318     if((way = find_nearest_waypoint(unitx, unity)))
319         cmenu_show_latlon(way->point->unitx, way->point->unity);
320     else
321     {
322         MACRO_BANNER_SHOW_INFO(_window, _("There are no waypoints."));
323     }
324
325
326     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
327     return TRUE;
328 }
329
330 static gboolean
331 cmenu_cb_way_show_desc(GtkMenuItem *item)
332 {
333     gint unitx, unity;
334     WayPoint *way;
335     printf("%s()\n", __PRETTY_FUNCTION__);
336
337     screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
338     if((way = find_nearest_waypoint(unitx, unity)))
339     {
340         MACRO_BANNER_SHOW_INFO(_window, way->desc);
341     }
342     else
343     {
344         MACRO_BANNER_SHOW_INFO(_window, _("There are no waypoints."));
345     }
346
347     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
348     return TRUE;
349 }
350
351 static gboolean
352 cmenu_cb_way_clip_latlon(GtkMenuItem *item)
353 {
354     gint unitx, unity;
355     WayPoint *way;
356     printf("%s()\n", __PRETTY_FUNCTION__);
357
358     screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
359     if((way = find_nearest_waypoint(unitx, unity)))
360         cmenu_clip_latlon(way->point->unitx, way->point->unity);
361     else
362     {
363         MACRO_BANNER_SHOW_INFO(_window, _("There are no waypoints."));
364     }
365
366     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
367     return TRUE;
368 }
369
370 static gboolean
371 cmenu_cb_way_clip_desc(GtkMenuItem *item)
372 {
373     gint unitx, unity;
374     WayPoint *way;
375     printf("%s()\n", __PRETTY_FUNCTION__);
376
377     screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
378     if((way = find_nearest_waypoint(unitx, unity)))
379         gtk_clipboard_set_text(
380                 gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), way->desc, -1);
381     else
382     {
383         MACRO_BANNER_SHOW_INFO(_window, _("There are no waypoints."));
384     }
385
386     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
387     return TRUE;
388 }
389
390 static gboolean
391 cmenu_cb_way_route_to(GtkMenuItem *item)
392 {
393     gint unitx, unity;
394     WayPoint *way;
395     printf("%s()\n", __PRETTY_FUNCTION__);
396
397     screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
398     if((way = find_nearest_waypoint(unitx, unity)))
399         cmenu_route_to(way->point->unitx, way->point->unity);
400     else
401     {
402         MACRO_BANNER_SHOW_INFO(_window, _("There are no waypoints."));
403     }
404
405     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
406     return TRUE;
407 }
408
409 static gboolean
410 cmenu_cb_way_distance_to(GtkMenuItem *item)
411 {
412     gint unitx, unity;
413     WayPoint *way;
414     printf("%s()\n", __PRETTY_FUNCTION__);
415
416     screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
417     if((way = find_nearest_waypoint(unitx, unity)))
418         route_show_distance_to(way->point);
419     else
420     {
421         MACRO_BANNER_SHOW_INFO(_window, _("There are no waypoints."));
422     }
423
424     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
425     return TRUE;
426 }
427
428 static gboolean
429 cmenu_cb_way_delete(GtkMenuItem *item)
430 {
431     gint unitx, unity;
432     WayPoint *way;
433     printf("%s()\n", __PRETTY_FUNCTION__);
434
435     screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
436     if((way = find_nearest_waypoint(unitx, unity)))
437     {
438         gchar buffer[BUFFER_SIZE];
439         GtkWidget *confirm;
440
441         snprintf(buffer, sizeof(buffer), "%s:\n%s\n",
442                 _("Confirm delete of waypoint"), way->desc);
443         confirm = hildon_note_new_confirmation(GTK_WINDOW(_window), buffer);
444
445         if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
446         {
447             Point *pdel_min, *pdel_max, *pdel_start, *pdel_end;
448             gint num_del;
449
450             /* Delete surrounding route data, too. */
451             if(way == _route.whead)
452                 pdel_min = _route.head;
453             else
454                 pdel_min = way[-1].point;
455
456             if(way == _route.wtail)
457                 pdel_max = _route.tail;
458             else
459                 pdel_max = way[1].point;
460
461             /* Find largest continuous segment around the waypoint, EXCLUDING
462              * pdel_min and pdel_max. */
463             for(pdel_start = way->point - 1; pdel_start->unity
464                     && pdel_start > pdel_min; pdel_start--) { }
465             for(pdel_end = way->point + 1; pdel_end->unity
466                     && pdel_end < pdel_max; pdel_end++) { }
467
468             /* If pdel_end is set to _route.tail, and if _route.tail is a
469              * non-zero point, then delete _route.tail. */
470             if(pdel_end == _route.tail && pdel_end->unity)
471                 pdel_end++; /* delete _route.tail too */
472             /* else, if *both* endpoints are zero points, delete one. */
473             else if(!pdel_start->unity && !pdel_end->unity)
474                 pdel_start--;
475
476             /* Delete BETWEEN pdel_start and pdel_end, exclusive. */
477             num_del = pdel_end - pdel_start - 1;
478
479             memmove(pdel_start + 1, pdel_end,
480                     (_route.tail - pdel_end + 1) * sizeof(Point));
481             _route.tail -= num_del;
482
483             /* Remove waypoint and move/adjust subsequent waypoints. */
484             g_free(way->desc);
485             while(way++ != _route.wtail)
486             {
487                 way[-1] = *way;
488                 way[-1].point -= num_del;
489             }
490             _route.wtail--;
491
492             route_find_nearest_point();
493             map_force_redraw();
494         }
495         gtk_widget_destroy(confirm);
496     }
497     else
498     {
499         MACRO_BANNER_SHOW_INFO(_window, _("There are no waypoints."));
500     }
501
502     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
503     return TRUE;
504 }
505
506 static gboolean
507 cmenu_cb_way_add_poi(GtkMenuItem *item)
508 {
509     gint unitx, unity;
510     WayPoint *way;
511     printf("%s()\n", __PRETTY_FUNCTION__);
512
513     screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
514     if((way = find_nearest_waypoint(unitx, unity)))
515         poi_add_dialog(_window, way->point->unitx, way->point->unity);
516     else
517     {
518         MACRO_BANNER_SHOW_INFO(_window, _("There are no waypoints."));
519     }
520
521     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
522     return TRUE;
523 }
524
525 static gboolean
526 cmenu_cb_poi_route_to(GtkMenuItem *item)
527 {
528     gint unitx, unity;
529     PoiInfo poi;
530     printf("%s()\n", __PRETTY_FUNCTION__);
531
532     screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
533     if(select_poi(unitx, unity, &poi, FALSE)) /* FALSE = not quick */
534     {
535         gint unitx, unity;
536         latlon2unit(poi.lat, poi.lon, unitx, unity);
537         cmenu_route_to(unitx, unity);
538     }
539
540     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
541     return TRUE;
542 }
543
544 static gboolean
545 cmenu_cb_poi_distance_to(GtkMenuItem *item)
546 {
547     gint unitx, unity;
548     PoiInfo poi;
549     printf("%s()\n", __PRETTY_FUNCTION__);
550
551     screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
552     if(select_poi(unitx, unity, &poi, FALSE)) /* FALSE = not quick */
553     {
554         gint unitx, unity;
555         latlon2unit(poi.lat, poi.lon, unitx, unity);
556         cmenu_distance_to(unitx, unity);
557     }
558
559     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
560     return TRUE;
561 }
562
563 static gboolean
564 cmenu_cb_poi_add_route(GtkMenuItem *item)
565 {
566     gint unitx, unity;
567     PoiInfo poi;
568     printf("%s()\n", __PRETTY_FUNCTION__);
569
570     screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
571     if(select_poi(unitx, unity, &poi, FALSE)) /* FALSE = not quick */
572     {
573         gint unitx, unity;
574         latlon2unit(poi.lat, poi.lon, unitx, unity);
575         cmenu_add_route(unitx, unity);
576     }
577
578     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
579     return TRUE;
580 }
581
582 static gboolean
583 cmenu_cb_poi_add_way(GtkMenuItem *item)
584 {
585     gint unitx, unity;
586     PoiInfo poi;
587     printf("%s()\n", __PRETTY_FUNCTION__);
588
589     screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
590     if(select_poi(unitx, unity, &poi, FALSE)) /* FALSE = not quick */
591     {
592         gint unitx, unity;
593         latlon2unit(poi.lat, poi.lon, unitx, unity);
594         route_add_way_dialog(unitx, unity);
595     }
596
597     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
598     return TRUE;
599 }
600
601 static gboolean
602 cmenu_cb_poi_edit_poi(GtkMenuItem *item)
603 {
604     PoiInfo poi;
605     gint unitx, unity;
606     printf("%s()\n", __PRETTY_FUNCTION__);
607
608     memset(&poi, 0, sizeof(poi));
609     screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
610     select_poi(unitx, unity, &poi, FALSE); /* FALSE = not quick */
611     poi_view_dialog(_window, &poi);
612     if(poi.label)
613         g_free(poi.label);
614     if(poi.desc)
615         g_free(poi.desc);
616     if(poi.clabel)
617         g_free(poi.clabel);
618
619     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
620     return TRUE;
621 }
622
623 static gboolean
624 cmenu_cb_hide(GtkMenuItem *item)
625 {
626     printf("%s()\n", __PRETTY_FUNCTION__);
627
628     if(_mouse_is_down)
629         g_mutex_unlock(_mouse_mutex);
630     _mouse_is_down = _mouse_is_dragging = FALSE;
631
632     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
633     return TRUE;
634 }
635
636 void cmenu_init()
637 {
638     /* Create needed handles. */
639     GtkWidget *submenu;
640     GtkWidget *menu_item;
641     printf("%s()\n", __PRETTY_FUNCTION__);
642
643     /* Setup the context menu. */
644     _map_cmenu = GTK_MENU(gtk_menu_new());
645
646     /* Setup the map context menu. */
647     gtk_menu_append(_map_cmenu, menu_item
648             = gtk_menu_item_new_with_label(_("Tap Point")));
649     gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
650             submenu = gtk_menu_new());
651
652     /* Setup the map context menu. */
653     gtk_menu_append(submenu, _cmenu_loc_show_latlon_item
654             = gtk_menu_item_new_with_label(_("Show Lat/Lon")));
655     gtk_menu_append(submenu, gtk_separator_menu_item_new());
656     gtk_menu_append(submenu, _cmenu_loc_distance_to_item
657             = gtk_menu_item_new_with_label(_("Show Distance to")));
658     gtk_menu_append(submenu, _cmenu_loc_route_to_item
659             = gtk_menu_item_new_with_label(_("Download Route to...")));
660     gtk_menu_append(submenu, _cmenu_loc_download_poi_item
661                 = gtk_menu_item_new_with_label(_("Download POI...")));
662     gtk_menu_append(submenu, _cmenu_loc_browse_poi_item
663                 = gtk_menu_item_new_with_label(_("Browse POI...")));
664     gtk_menu_append(submenu, gtk_separator_menu_item_new());
665     gtk_menu_append(submenu, _cmenu_loc_add_route_item
666                 = gtk_menu_item_new_with_label(_("Add Route Point")));
667     gtk_menu_append(submenu, _cmenu_loc_add_way_item
668                 = gtk_menu_item_new_with_label(_("Add Waypoint...")));
669     gtk_menu_append(submenu, _cmenu_loc_add_poi_item
670                 = gtk_menu_item_new_with_label(_("Add POI...")));
671     gtk_menu_append(submenu, gtk_separator_menu_item_new());
672     gtk_menu_append(submenu, _cmenu_loc_set_gps_item
673                 = gtk_menu_item_new_with_label(_("Set as GPS Location")));
674     gtk_menu_append(submenu, _cmenu_loc_apply_correction_item
675                 = gtk_check_menu_item_new_with_label(
676                     _("Apply Map Correction")));
677     gtk_check_menu_item_set_active(
678             GTK_CHECK_MENU_ITEM(_cmenu_loc_apply_correction_item),
679             _map_correction_unitx != 0 || _map_correction_unity != 0);
680
681     /* Setup the waypoint context menu. */
682     gtk_menu_append(_map_cmenu, menu_item
683             = gtk_menu_item_new_with_label(_("Waypoint")));
684     gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
685             submenu = gtk_menu_new());
686
687     gtk_menu_append(submenu, _cmenu_way_show_latlon_item
688             = gtk_menu_item_new_with_label(_("Show Lat/Lon")));
689     gtk_menu_append(submenu, _cmenu_way_show_desc_item
690             = gtk_menu_item_new_with_label(_("Show Description")));
691     gtk_menu_append(submenu, _cmenu_way_clip_latlon_item
692             = gtk_menu_item_new_with_label(_("Copy Lat/Lon")));
693     gtk_menu_append(submenu, _cmenu_way_clip_desc_item
694             = gtk_menu_item_new_with_label(_("Copy Description")));
695     gtk_menu_append(submenu, gtk_separator_menu_item_new());
696     gtk_menu_append(submenu, _cmenu_way_distance_to_item
697             = gtk_menu_item_new_with_label(_("Show Distance to")));
698     gtk_menu_append(submenu, _cmenu_way_route_to_item
699             = gtk_menu_item_new_with_label(_("Download Route to...")));
700     gtk_menu_append(submenu, _cmenu_way_delete_item
701             = gtk_menu_item_new_with_label(_("Delete...")));
702     gtk_menu_append(submenu, gtk_separator_menu_item_new());
703     gtk_menu_append(submenu, _cmenu_way_add_poi_item
704                 = gtk_menu_item_new_with_label(_("Add POI...")));
705     gtk_menu_append(submenu, gtk_separator_menu_item_new());
706     gtk_menu_append(submenu, _cmenu_way_goto_nextway_item
707                 = gtk_menu_item_new_with_label(_("Go to Next")));
708
709     /* Setup the POI context menu. */
710     gtk_menu_append(_map_cmenu, _cmenu_poi_submenu
711             = gtk_menu_item_new_with_label(_("POI")));
712     gtk_menu_item_set_submenu(GTK_MENU_ITEM(_cmenu_poi_submenu),
713             submenu = gtk_menu_new());
714
715     gtk_menu_append(submenu, _cmenu_poi_edit_poi_item
716                 = gtk_menu_item_new_with_label(_("View/Edit...")));
717     gtk_menu_append(submenu, gtk_separator_menu_item_new());
718     gtk_menu_append(submenu, _cmenu_poi_distance_to_item
719             = gtk_menu_item_new_with_label(_("Show Distance to")));
720     gtk_menu_append(submenu, _cmenu_poi_route_to_item
721             = gtk_menu_item_new_with_label(_("Download Route to...")));
722     gtk_menu_append(submenu, gtk_separator_menu_item_new());
723     gtk_menu_append(submenu, _cmenu_poi_add_route_item
724                 = gtk_menu_item_new_with_label(_("Add Route Point")));
725     gtk_menu_append(submenu, _cmenu_poi_add_way_item
726                 = gtk_menu_item_new_with_label(_("Add Waypoint...")));
727     gtk_menu_append(submenu, gtk_separator_menu_item_new());
728     gtk_menu_append(submenu, _cmenu_poi_goto_nearpoi_item
729                 = gtk_menu_item_new_with_label(_("Go to Nearest")));
730
731     /* Connect signals for context menu. */
732     g_signal_connect(G_OBJECT(_cmenu_loc_show_latlon_item), "activate",
733                       G_CALLBACK(cmenu_cb_loc_show_latlon), NULL);
734     g_signal_connect(G_OBJECT(_cmenu_loc_route_to_item), "activate",
735                       G_CALLBACK(cmenu_cb_loc_route_to), NULL);
736     g_signal_connect(G_OBJECT(_cmenu_loc_download_poi_item), "activate",
737                       G_CALLBACK(cmenu_cb_loc_download_poi), NULL);
738     g_signal_connect(G_OBJECT(_cmenu_loc_browse_poi_item), "activate",
739                       G_CALLBACK(cmenu_cb_loc_browse_poi), NULL);
740     g_signal_connect(G_OBJECT(_cmenu_loc_distance_to_item), "activate",
741                       G_CALLBACK(cmenu_cb_loc_distance_to), NULL);
742     g_signal_connect(G_OBJECT(_cmenu_loc_add_route_item), "activate",
743                         G_CALLBACK(cmenu_cb_loc_add_route), NULL);
744     g_signal_connect(G_OBJECT(_cmenu_loc_add_way_item), "activate",
745                         G_CALLBACK(cmenu_cb_loc_add_way), NULL);
746     g_signal_connect(G_OBJECT(_cmenu_loc_add_poi_item), "activate",
747                         G_CALLBACK(cmenu_cb_loc_add_poi), NULL);
748     g_signal_connect(G_OBJECT(_cmenu_loc_set_gps_item), "activate",
749                         G_CALLBACK(cmenu_cb_loc_set_gps), NULL);
750     g_signal_connect(G_OBJECT(_cmenu_loc_apply_correction_item), "toggled",
751                         G_CALLBACK(cmenu_cb_loc_apply_correction), NULL);
752
753     g_signal_connect(G_OBJECT(_cmenu_way_show_latlon_item), "activate",
754                       G_CALLBACK(cmenu_cb_way_show_latlon), NULL);
755     g_signal_connect(G_OBJECT(_cmenu_way_show_desc_item), "activate",
756                       G_CALLBACK(cmenu_cb_way_show_desc), NULL);
757     g_signal_connect(G_OBJECT(_cmenu_way_clip_latlon_item), "activate",
758                       G_CALLBACK(cmenu_cb_way_clip_latlon), NULL);
759     g_signal_connect(G_OBJECT(_cmenu_way_clip_desc_item), "activate",
760                       G_CALLBACK(cmenu_cb_way_clip_desc), NULL);
761     g_signal_connect(G_OBJECT(_cmenu_way_route_to_item), "activate",
762                       G_CALLBACK(cmenu_cb_way_route_to), NULL);
763     g_signal_connect(G_OBJECT(_cmenu_way_distance_to_item), "activate",
764                       G_CALLBACK(cmenu_cb_way_distance_to), NULL);
765     g_signal_connect(G_OBJECT(_cmenu_way_delete_item), "activate",
766                       G_CALLBACK(cmenu_cb_way_delete), NULL);
767     g_signal_connect(G_OBJECT(_cmenu_way_add_poi_item), "activate",
768                         G_CALLBACK(cmenu_cb_way_add_poi), NULL);
769     g_signal_connect(G_OBJECT(_cmenu_way_goto_nextway_item), "activate",
770                         G_CALLBACK(menu_cb_view_goto_nextway), NULL);
771
772     g_signal_connect(G_OBJECT(_cmenu_poi_edit_poi_item), "activate",
773                         G_CALLBACK(cmenu_cb_poi_edit_poi), NULL);
774     g_signal_connect(G_OBJECT(_cmenu_poi_route_to_item), "activate",
775                       G_CALLBACK(cmenu_cb_poi_route_to), NULL);
776     g_signal_connect(G_OBJECT(_cmenu_poi_distance_to_item), "activate",
777                       G_CALLBACK(cmenu_cb_poi_distance_to), NULL);
778     g_signal_connect(G_OBJECT(_cmenu_poi_add_route_item), "activate",
779                         G_CALLBACK(cmenu_cb_poi_add_route), NULL);
780     g_signal_connect(G_OBJECT(_cmenu_poi_add_way_item), "activate",
781                         G_CALLBACK(cmenu_cb_poi_add_way), NULL);
782     g_signal_connect(G_OBJECT(_cmenu_poi_goto_nearpoi_item), "activate",
783                         G_CALLBACK(menu_cb_view_goto_nearpoi), NULL);
784
785     gtk_widget_show_all(GTK_WIDGET(_map_cmenu));
786
787 #ifdef MAEMO_CHANGES
788     gtk_widget_tap_and_hold_setup(_map_widget, GTK_WIDGET(_map_cmenu), NULL, 0);
789 #endif
790
791     /* Add a "hide" signal event handler to handle dismissing the context
792      * menu. */
793     g_signal_connect(GTK_WIDGET(_map_cmenu), "hide",
794             G_CALLBACK(cmenu_cb_hide), NULL);
795
796     vprintf("%s(): return\n", __PRETTY_FUNCTION__);
797 }