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