]> err.no Git - mapper/blob - src/ui-common.c
More map widget integration changes
[mapper] / src / ui-common.c
1 #include <config.h>
2
3 #include <unistd.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <strings.h>
7 #include <stddef.h>
8 #include <locale.h>
9 #include <math.h>
10 #include <errno.h>
11 #include <sys/wait.h>
12 #include <glib/gstdio.h>
13 #include <gtk/gtk.h>
14 #include <fcntl.h>
15 #include <libgnomevfs/gnome-vfs.h>
16 #include <curl/multi.h>
17 #include <glib/gi18n.h>
18
19 #include "gtkgps.h"
20 #include "gtkcompass.h"
21
22 #include "hildon-mapper.h"
23
24 #include "utils.h"
25 #include "poi.h"
26 #include "path.h"
27 #include "settings.h"
28 #include "gps.h"
29 #include "gtkmap.h"
30 #include "mapper-types.h"
31 #include "ui-common.h"
32 #include "db.h"
33 #include "gps-panels.h"
34 #include "gps-conn.h"
35 #include "filter.h"
36 #include "dialogs.h"
37 #include "settings-gui.h"
38 #include "map-repo.h"
39 #include "poi-gui.h"
40
41 #ifdef WITH_GST
42 #include "audio-note.h"
43 #endif
44
45 /* Callbacks */
46 #include "cb.h"
47
48 /* Default size */
49 #define WINDOW_SIZE_X 800
50 #define WINDOW_SIZE_Y 480
51
52 static GtkWidget *menu_bar;
53 GtkWidget *_fix_banner=NULL;
54
55 static GtkActionGroup *actions;
56 static GtkActionGroup *map_repos_action_group;
57 static GtkUIManager *ui;
58
59 struct ui_notebook_struct {
60         GtkWidget *notebook;
61         gint map;
62         gint gps;
63         gint heading;
64         gint route;
65         gint track;
66         gint qpoi;
67         gint audio;
68 };
69 struct ui_notebook_struct ui_notebook;
70
71 static poi_quick_data tqp;
72
73 osm_location map_loc;
74
75 /* A GPS icon would be nice.. anyone ? */
76
77 #ifndef GTK_STOCK_INFO
78 #define GTK_STOCK_INFO GTK_STOCK_PROPERTIES
79 #endif
80
81 static gboolean mapper_cb_quit(GtkWidget *widget, GdkEvent *event, gpointer data);
82
83 /**
84  * Action groups and UI
85  */
86 static const gchar *mapper_ui =
87 "<ui>"
88 "  <menubar name='MenuBar'>"
89 "    <menu action='file'>"
90 "      <menu action='file_settings'>"
91 "       <menuitem action='file_settings_gps'/>"
92 "       <menuitem action='file_settings_generic'/>"
93 "       <menuitem action='file_settings_colors'/>"
94 "       <separator/>"
95 "       <menuitem action='file_settings_osm'/>"
96 #ifdef WITH_DEVICE_770
97 "       <separator/>"
98 "       <menuitem action='file_settings_keys'/>"
99 #endif
100 "          </menu>"
101 "      <separator/>"
102 "      <menuitem action='file_import_osm'/>"
103 "      <menuitem action='file_quit'/>"
104 "    </menu>"
105 "    <menu action='map' name='map'>"
106 "      <menu action='map_maps' name='map_maps'>"
107 "      </menu>"
108 "      <separator/>"
109 "      <menuitem action='map_manager'/>"
110 "      <menuitem action='map_repositories'/>"
111 "      <separator/>"
112 "      <menuitem action='map_auto_download'/>"
113 "      <separator/>"
114 "     <menu action='autocenter'>"
115 "      <menuitem action='autocenter_latlon'/>"
116 "      <menuitem action='autocenter_lead'/>"
117 "      <menuitem action='autocenter_none'/>"
118 "     </menu>"
119 "    </menu>"
120 "    <menu action='search'>"
121 "      <menuitem action='search_address'/>"
122 "    </menu>"
123 "    <menu action='track'>"
124 "      <menuitem action='track_open'/>"
125 "      <menuitem action='track_save'/>"
126 "      <menuitem action='track_clear'/>"
127 "      <separator/>"
128 "      <menuitem action='track_insert_break'/>"
129 "      <menuitem action='track_insert_mark'/>"
130 "      <separator/>"
131 "      <menuitem action='track_dist_last_mark'/>"
132 "      <menuitem action='track_dist_first'/>"
133 "      <separator/>"
134 "      <menuitem action='track_filter'/>"
135 "    </menu>"
136 "    <menu action='route'>"
137 "      <menuitem action='route_open'/>"
138 "      <menuitem action='route_save'/>"
139 "      <menuitem action='route_download'/>"
140 "      <separator/>"
141 "      <menuitem action='route_dist_next'/>"
142 "      <menuitem action='route_dist_last'/>"
143 "      <separator/>"
144 "      <menuitem action='route_reset'/>"
145 "      <menuitem action='route_clear'/>"
146 "    </menu>"
147 "    <menu action='poi'>"
148 "      <menuitem action='poi_categories'/>"
149 "      <menuitem action='poi_search'/>"
150 #if 0
151 "      <separator/>"
152 "      <menuitem action='poi_import'/>"
153 "      <menuitem action='poi_export'/>"
154 #endif
155 "    </menu>"
156 "    <menu action='view'>"
157 "      <menuitem action='view_zoom_in'/>"
158 "      <menuitem action='view_zoom_out'/>"
159 "      <menuitem action='view_zoom_normal'/>"
160 "      <menuitem action='view_zoom_auto'/>"
161 "      <separator/>"
162 "      <menuitem action='view_fullscreen'/>"
163 "      <separator/>"
164 "      <menuitem action='view_toolbar'/>"
165 "      <separator/>"
166 "      <menu action='view_items'>"
167 "       <menuitem action='view_scale'/>"
168 "       <menuitem action='view_route'/>"
169 "       <menuitem action='view_track'/>"
170 "       <menuitem action='view_vector'/>"
171 "       <menuitem action='view_poi'/>"
172 "      </menu>"
173 "    </menu>"
174 "    <menu action='goto'>"
175 "      <menuitem action='goto_home'/>"
176 "      <menuitem action='goto_destination'/>"
177 "      <menuitem action='goto_gps'/>"
178 "      <separator/>"
179 "      <menuitem action='goto_latlon'/>"
180 "      <menuitem action='goto_nearpoi'/>"
181 "      <menuitem action='goto_nextway'/>"
182 "      <separator/>"
183 "    </menu>"
184 "    <menu action='gps'>"
185 "      <menuitem action='gps_enabled'/>"
186 "      <menuitem action='gps_information'/>"
187 "    </menu>"
188 "    <menu action='help'>"
189 #if defined (WITH_OSSO_HELP) || defined(WITH_HILDON_HELP)
190 "      <menuitem action='help_help'/>"
191 #endif
192 "      <menuitem action='help_about'/>"
193 "    </menu>"
194 "  </menubar>"
195 "  <toolbar name='ToolBar'>"
196 "    <toolitem action='goto_home'/>"
197 "    <toolitem action='goto_destination'/>"
198 "    <toolitem action='goto_gps'/>"
199 "    <separator/>"
200 "    <toolitem action='poi_add'/>"
201 "    <toolitem action='poi_quick_add'/>"
202 "    <separator/>"
203 "    <toolitem action='search_address'/>"
204 "    <separator/>"
205 "    <toolitem action='view_zoom_in'/>"
206 "    <toolitem action='view_zoom_out'/>"
207 #ifndef WITH_DEVICE_770
208 "    <toolitem action='view_zoom_normal'/>"
209 "    <toolitem action='view_zoom_auto'/>"
210 #endif
211 "    <separator/>"
212 "  </toolbar>"
213 "  <toolbar name='MappingToolBar'>"
214 "    <toolitem action='goto_gps'/>"
215 "    <separator/>"
216 "    <toolitem action='poi_add'/>"
217 "    <toolitem action='poi_quick_add'/>"
218 "    <toolitem action='track_insert_break'/>"
219 "    <toolitem action='track_insert_mark'/>"
220 "    <separator/>"
221 "    <toolitem action='search_address'/>"
222 "  </toolbar>"
223 "</ui>";
224
225 static GtkActionEntry ui_entries[] = {
226         {"file", NULL, N_("_File"), NULL, NULL, NULL },
227         {"file_settings", GTK_STOCK_PREFERENCES, N_("_Settings..."), NULL, NULL, NULL },
228         {"file_settings_generic", NULL, N_("Generic..."), NULL, NULL, G_CALLBACK(menu_cb_settings) },
229         {"file_settings_colors", NULL, N_("_Colors..."), NULL, NULL, G_CALLBACK(menu_cb_settings_colors) },
230         {"file_settings_gps", NULL, N_("_Gps..."), NULL, NULL, G_CALLBACK(menu_cb_settings_gps) },
231         {"file_settings_osm", NULL, N_("_Map info..."), NULL, NULL, G_CALLBACK(menu_cb_settings_osm) },
232         {"file_settings_keys", NULL, N_("_Keys..."), NULL, NULL, G_CALLBACK(menu_cb_settings_keys) },
233         {"file_import_osm", NULL, N_("_Import OSM data..."), NULL, NULL, G_CALLBACK(menu_cb_import_osm) },
234         {"file_quit", GTK_STOCK_QUIT, N_("_Quit"), "<control>Q", NULL, G_CALLBACK(mapper_cb_quit) },
235
236         {"help", NULL, N_("_Help"), NULL, NULL, NULL },
237         {"help_help", GTK_STOCK_HELP, N_("_Help"), NULL, NULL, G_CALLBACK(menu_cb_help) },
238         {"help_about", GTK_STOCK_ABOUT, N_("_About"), "<control>A", NULL, G_CALLBACK(menu_cb_about) },
239
240         {"track", NULL, N_("_Track"), NULL, NULL, NULL },
241         {"track_open", GTK_STOCK_OPEN, N_("_Open..."), NULL, NULL, G_CALLBACK(menu_cb_track_open) },
242         {"track_save", GTK_STOCK_SAVE, N_("_Save..."), "<control>S", NULL, G_CALLBACK(menu_cb_track_save) },
243         {"track_clear", GTK_STOCK_CLEAR, N_("_Clear"), NULL, NULL, G_CALLBACK(menu_cb_track_clear) },
244         {"track_insert_break", NULL, N_("Insert _Break"), NULL, NULL, G_CALLBACK(menu_cb_track_insert_break) },
245         {"track_insert_mark", NULL, N_("Insert _Mark..."), NULL, NULL, G_CALLBACK(menu_cb_track_insert_mark) },
246         {"track_dist_last_mark", NULL, N_("Distance to _last mark"), NULL, NULL, G_CALLBACK(menu_cb_track_distlast) },
247         {"track_dist_first", NULL, N_("Distance from _first"), NULL, NULL, G_CALLBACK(menu_cb_track_distfirst) },
248         {"track_filter", NULL, N_("_Filter..."), NULL, NULL, G_CALLBACK(menu_cb_track_filter) },
249
250         {"route", NULL, N_("_Route"), NULL, NULL, NULL },
251         {"route_open", GTK_STOCK_OPEN, N_("_Open..."), NULL, NULL, G_CALLBACK(menu_cb_route_open) },
252         {"route_save", GTK_STOCK_SAVE, N_("_Save..."), NULL, NULL, G_CALLBACK(menu_cb_route_save) },
253         {"route_download", NULL, N_("Do_wnload..."), NULL, NULL, G_CALLBACK(menu_cb_route_download)},
254         {"route_reset", NULL, N_("Reset"), NULL, NULL, G_CALLBACK(menu_cb_route_reset) },
255         {"route_clear", GTK_STOCK_CLEAR, N_("_Clear"), NULL, NULL, G_CALLBACK(menu_cb_route_clear) },
256         {"route_dist_next", NULL, N_("Show Distance to _Next Waypoint"), NULL, NULL, G_CALLBACK(menu_cb_route_distnext) },
257         {"route_dist_last", NULL, N_("Show Distance to _End of Route"), NULL, NULL, G_CALLBACK(menu_cb_route_distlast) },
258
259         {"poi", NULL, N_("_Poi"), NULL, NULL, NULL },
260         {"poi_categories", GTK_STOCK_INDEX, N_("_Categories.."), NULL, NULL, G_CALLBACK(menu_cb_category) },
261         {"poi_settings", GTK_STOCK_PREFERENCES, N_("_Settings..."), NULL, NULL, NULL },
262         {"poi_add", GTK_STOCK_ADD, N_("_Add"), "<control>A", NULL, G_CALLBACK(cb_poi_add) },
263         {"poi_quick_add", GTK_STOCK_ABOUT, N_("_Quick Add"), "<control>E", NULL, G_CALLBACK(cb_poi_add) },
264         {"poi_search", GTK_STOCK_FIND, N_("_Search..."), NULL, NULL, G_CALLBACK(cb_poi_search) },
265         {"poi_import", GTK_STOCK_OPEN, N_("_Import..."), NULL, NULL, NULL },
266         {"poi_export", GTK_STOCK_SAVE, N_("_Export..."), NULL, NULL, NULL },
267
268         {"search", NULL, N_("_Search"), NULL, NULL, NULL },
269         {"search_address", GTK_STOCK_FIND, N_("Address..."), "<control>F", NULL, G_CALLBACK(menu_cb_search_address) },
270
271         {"map", NULL, N_("_Map"), NULL, NULL, NULL },
272         {"map_maps", NULL, N_("_Maps"), NULL, NULL, NULL },
273         {"map_manager", NULL, N_("Manager..."), NULL, NULL, G_CALLBACK(menu_cb_mapman) },
274         {"map_repositories", NULL, N_("_Repositories..."), NULL, NULL, G_CALLBACK(menu_cb_maps_repoman) },
275         {"autocenter", NULL, N_("_Autocenter"), NULL, NULL, NULL },
276
277         {"view", NULL, N_("_View"), NULL, NULL, NULL },
278         {"view_zoom_in", GTK_STOCK_ZOOM_IN, N_("Zoom _in"), NULL, NULL, G_CALLBACK(cb_zoomin) },
279         {"view_zoom_out", GTK_STOCK_ZOOM_OUT, N_("Zoom _out"), NULL, NULL, G_CALLBACK(cb_zoomout) },
280         {"view_zoom_normal", GTK_STOCK_ZOOM_100, N_("Zoom _normal"), "<control>0", NULL, G_CALLBACK(cb_zoom_base) },
281
282         {"view_items", NULL, N_("_Features"), NULL, NULL, NULL },
283
284         {"goto", NULL, N_("_Go"), NULL, NULL, NULL },
285         {"goto_home", GTK_STOCK_HOME, N_("_Home"), "<control>H", NULL, G_CALLBACK(menu_cb_goto_home) },
286         {"goto_destination", GTK_STOCK_JUMP_TO, N_("_Destination"), "<control>J", NULL, G_CALLBACK(menu_cb_goto_destination) },
287         {"goto_gps", NULL, N_("_GPS"), "<control>G", NULL, G_CALLBACK(menu_cb_goto_gps) },
288         {"goto_latlon", NULL, N_("Lat/Lon"), NULL, NULL, G_CALLBACK(menu_cb_goto_latlon) },
289         {"goto_nextway", NULL, N_("Next Waypoint"), NULL, NULL, G_CALLBACK(menu_cb_goto_nextway) },
290         {"goto_nearpoi", NULL, N_("Near POI"), NULL, NULL, G_CALLBACK(menu_cb_goto_nearpoi) },
291
292         {"gps", NULL, N_("Gp_s"), NULL, NULL, NULL },
293         {"gps_settings", NULL, N_("_Settings..."), NULL, NULL, NULL },
294 };
295 static guint n_ui_entries = G_N_ELEMENTS (ui_entries);
296
297 static GtkToggleActionEntry ui_toggle_entries[] = {
298         {"map_auto_download", NULL, N_("Auto download"), NULL, NULL, G_CALLBACK(menu_cb_auto_download), FALSE},
299         {"view_zoom_auto", GTK_STOCK_ZOOM_FIT, N_("AutoZoom"), NULL, NULL, G_CALLBACK(cb_zoom_auto), FALSE},
300         {"gps_enabled", GTK_STOCK_CONNECT, N_("Enabled"), NULL, NULL, G_CALLBACK(menu_cb_enable_gps), FALSE},
301         {"gps_information", GTK_STOCK_INFO, N_("Panel"), NULL, NULL, G_CALLBACK (menu_cb_gps_show_info), FALSE},
302 #if 0
303         {"view_fullscreen", GTK_STOCK_FULLSCREEN, N_("Fullscreen"), NULL, NULL, G_CALLBACK(cb_fullscreen), FALSE},
304 #else
305         {"view_fullscreen", NULL, N_("Fullscreen"), "F11", NULL, G_CALLBACK(cb_fullscreen), FALSE},
306 #endif
307         {"view_toolbar", NULL, N_("Toolbar"), NULL, NULL, G_CALLBACK(menu_cb_view_toolbar), FALSE},
308         {"view_scale", NULL, N_("Scale"), NULL, NULL, G_CALLBACK(menu_cb_show_scale), TRUE},
309         {"view_route", NULL, N_("Route"), NULL, NULL, G_CALLBACK(menu_cb_show_routes), TRUE},
310         {"view_track", NULL, N_("Track"), NULL, NULL, G_CALLBACK(menu_cb_show_tracks), TRUE},
311         {"view_vector", NULL, N_("Vector"), NULL, NULL, G_CALLBACK(menu_cb_show_velvec), TRUE},
312         {"view_poi", NULL, N_("POIs"), NULL, NULL, G_CALLBACK(menu_cb_show_poi), TRUE},
313 };
314 static guint n_ui_toggle_entries = G_N_ELEMENTS (ui_toggle_entries);
315
316 static GtkRadioActionEntry ui_autocenter_entries[] = {
317   { "autocenter_latlon", NULL, "Lat/Lon", "<control>L", NULL, CENTER_LATLON },
318   { "autocenter_lead", NULL, "Lead", "<control>E", NULL, CENTER_LEAD },
319   { "autocenter_none", NULL, "None", "<control>N", NULL, CENTER_MANUAL },
320 };
321 static guint n_ui_autocenter_entries = G_N_ELEMENTS (ui_autocenter_entries);
322
323 /************************************************************************************/
324
325 void
326 set_action_sensitive(const char *name, gboolean sensitive)
327 {
328 GtkAction *action = gtk_action_group_get_action(actions, name);
329 g_assert(action);
330 gtk_action_set_sensitive(action, sensitive);
331 }
332
333 void
334 set_action_activate(const char *name, gboolean active)
335 {
336 GtkAction *action = gtk_action_group_get_action(actions, name);
337 g_assert(action);
338 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), active);
339 }
340
341 #if 0
342 void
343 set_radio_action_value(const char *name, gint value)
344 {
345 GtkAction *action = gtk_action_group_get_action(actions, name);
346 gtk_radio_action_set_current_value(action, value);
347 }
348 #endif
349
350 /************************************************************************************/
351
352 #ifdef WITH_HILDON
353 void force_min_visible_bars(HildonControlbar * control_bar, gint num_bars)
354 {
355 GValue val;
356 memset(&val, 0, sizeof(val));
357 g_value_init(&val, G_TYPE_INT);
358 g_value_set_int(&val, num_bars);
359 g_object_set_property(G_OBJECT(control_bar), "minimum-visible-bars", &val);
360 }
361 #else
362 void force_min_visible_bars(void *a, gint b)
363 {
364 }
365 #endif
366
367 static gboolean
368 mapper_cb_quit(GtkWidget *widget, GdkEvent  *event, gpointer data)
369 {
370 if (dialog_confirm(_window, _("Are sure you'd like to quit ?"))==TRUE) {
371         gtk_main_quit();
372         return FALSE;
373 }
374 return TRUE;
375 }
376
377 void 
378 menu_maps_add_repos(void)
379 {
380 GList *curr;
381 static gint id=0;
382 gint i=0;
383
384 if (id>0) {
385         gtk_ui_manager_remove_ui(ui, id);
386 } else {
387         id=gtk_ui_manager_new_merge_id(ui);
388 }
389
390 if (map_repos_action_group) {
391         gtk_ui_manager_remove_action_group(ui, map_repos_action_group);
392         g_object_unref(map_repos_action_group);
393 }
394
395 map_repos_action_group=gtk_action_group_new("map_repos_actions");
396 g_assert(map_repos_action_group);
397 gtk_ui_manager_insert_action_group(ui, map_repos_action_group, 0);
398 gtk_ui_manager_ensure_update(ui);
399
400 for (curr = g_list_last(_repo_list); curr; curr = curr->prev) {
401         RepoData *rd = (RepoData *) curr->data;
402         GtkAction *action;
403         gchar *action_name;
404
405         action_name = g_strdup_printf ("MapRepo%u", i++);
406         action=g_object_new(GTK_TYPE_ACTION, "name", action_name, "label", rd->name, NULL);
407         g_signal_connect(G_OBJECT(action), "activate", G_CALLBACK (menu_cb_maps_select), curr->data);
408         gtk_action_group_add_action(map_repos_action_group, action);
409         g_object_unref(action);
410         gtk_ui_manager_add_ui(ui, id, "/MenuBar/map/map_maps", rd->name, action_name, GTK_UI_MANAGER_MENUITEM, FALSE);
411 }
412
413 }
414
415 /**
416  * Call gtk_window_present() on Mapper.
417  */
418 gboolean 
419 window_present()
420 {
421 gtk_window_present(GTK_WINDOW(_window));
422 return FALSE;
423 }
424
425 static void 
426 menu_init_cmenu()
427 {
428 /* Create needed handles. */
429 GtkMenu *menu;
430 GtkWidget *submenu;
431 GtkWidget *menu_item;
432
433 /* Setup the context menu. */
434 menu = GTK_MENU(gtk_menu_new());
435
436 /* Setup the map context menu. */
437 gtk_menu_append(menu, menu_item = gtk_menu_item_new_with_label(_("Location")));
438 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), submenu = gtk_menu_new());
439
440 /* Setup the map context menu. */
441 gtk_menu_append(submenu, _cmenu_loc_show_latlon_item= gtk_menu_item_new_with_label(_("Show Lat/Lon")));
442 gtk_menu_append(submenu, _cmenu_loc_clip_latlon_item = gtk_menu_item_new_with_label(_("Copy Lat/Lon")));
443 gtk_menu_append(submenu, gtk_separator_menu_item_new());
444 gtk_menu_append(submenu, _cmenu_loc_distance_to_item = gtk_menu_item_new_with_label(_("Show Distance to")));
445 gtk_menu_append(submenu, _cmenu_loc_route_to_item= gtk_menu_item_new_with_label(_("Download Route to...")));
446 gtk_menu_append(submenu, gtk_separator_menu_item_new());
447 gtk_menu_append(submenu, _cmenu_loc_add_route= gtk_menu_item_new_with_label(_("Add Route Point")));
448 gtk_menu_append(submenu, _cmenu_loc_add_way     = gtk_menu_item_new_with_label(_("Add Waypoint...")));
449 gtk_menu_append(submenu, gtk_separator_menu_item_new());
450 gtk_menu_append(submenu, _cmenu_loc_set_gps = gtk_menu_item_new_with_label(_("Set as GPS Location")));
451 gtk_menu_append(submenu, _cmenu_loc_set_home = gtk_menu_item_new_with_label(_("Set as Home Location")));
452 gtk_menu_append(submenu, _cmenu_loc_set_destination     = gtk_menu_item_new_with_label(_("Set as Destination")));
453
454 /* Setup the waypoint context menu. */
455 gtk_menu_append(menu, menu_item = gtk_menu_item_new_with_label(_("Waypoint")));
456 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), submenu = gtk_menu_new());
457
458 gtk_menu_append(submenu, _cmenu_way_show_latlon_item = gtk_menu_item_new_with_label(_("Show Lat/Lon")));
459 gtk_menu_append(submenu, _cmenu_way_show_desc_item = gtk_menu_item_new_with_label(_("Show Description")));
460 gtk_menu_append(submenu, _cmenu_way_clip_latlon_item = gtk_menu_item_new_with_label(_("Copy Lat/Lon")));
461 gtk_menu_append(submenu, _cmenu_way_clip_desc_item = gtk_menu_item_new_with_label(_("Copy Description")));
462 gtk_menu_append(submenu, gtk_separator_menu_item_new());
463 gtk_menu_append(submenu, _cmenu_way_distance_to_item = gtk_menu_item_new_with_label(_("Show Distance to")));
464 gtk_menu_append(submenu, _cmenu_way_route_to_item = gtk_menu_item_new_with_label(_("Download Route to...")));
465 gtk_menu_append(submenu, _cmenu_way_delete_item = gtk_menu_item_new_with_label(_("Delete...")));
466 gtk_menu_append(submenu, gtk_separator_menu_item_new());
467 gtk_menu_append(submenu, _cmenu_way_add_poi = gtk_menu_item_new_with_label(_("Add POI...")));
468 gtk_widget_set_sensitive(_cmenu_way_add_poi, _db != NULL);
469 gtk_menu_append(submenu, gtk_separator_menu_item_new());
470 gtk_menu_append(submenu, _cmenu_way_goto_nextway = gtk_menu_item_new_with_label(_("Go to Next")));
471
472 /* Setup the POI context menu. */
473 gtk_menu_append(menu, _cmenu_poi = gtk_menu_item_new_with_label(_("POI")));
474 gtk_widget_set_sensitive(_cmenu_poi, _db != NULL);
475 gtk_menu_item_set_submenu(GTK_MENU_ITEM(_cmenu_poi), submenu = gtk_menu_new());
476
477 gtk_menu_append(submenu, _cmenu_loc_add_poi     = gtk_menu_item_new_with_label(_("Add POI...")));
478 gtk_menu_append(submenu, _cmenu_poi_edit_poi = gtk_menu_item_new_with_label(_("View/Edit...")));
479 gtk_menu_append(submenu, gtk_separator_menu_item_new());
480 gtk_menu_append(submenu, _cmenu_poi_distance_to_item = gtk_menu_item_new_with_label(_("Show Distance to")));
481 gtk_menu_append(submenu, _cmenu_poi_route_to_item = gtk_menu_item_new_with_label(_("Download Route to...")));
482 gtk_menu_append(submenu, gtk_separator_menu_item_new());
483 gtk_menu_append(submenu, _cmenu_poi_add_route = gtk_menu_item_new_with_label(_("Add Route Point")));
484 gtk_menu_append(submenu, _cmenu_poi_add_way     = gtk_menu_item_new_with_label(_("Add Waypoint...")));
485 gtk_menu_append(submenu, gtk_separator_menu_item_new());
486 gtk_menu_append(submenu, _cmenu_poi_goto_nearpoi = gtk_menu_item_new_with_label(_("Go to Nearest")));
487
488 /* Connect signals for context menu. */
489 g_signal_connect(G_OBJECT(_cmenu_loc_show_latlon_item), "activate", G_CALLBACK(cmenu_cb_loc_show_latlon), NULL);
490 g_signal_connect(G_OBJECT(_cmenu_loc_clip_latlon_item), "activate", G_CALLBACK(cmenu_cb_loc_clip_latlon), NULL);
491 g_signal_connect(G_OBJECT(_cmenu_loc_route_to_item), "activate", G_CALLBACK(cmenu_cb_loc_route_to), NULL);
492 g_signal_connect(G_OBJECT(_cmenu_loc_distance_to_item), "activate", G_CALLBACK(cmenu_cb_loc_distance_to), NULL);
493 g_signal_connect(G_OBJECT(_cmenu_loc_add_route), "activate", G_CALLBACK(cmenu_cb_loc_add_route), NULL);
494 g_signal_connect(G_OBJECT(_cmenu_loc_add_way), "activate", G_CALLBACK(cmenu_cb_loc_add_way), NULL);
495 g_signal_connect(G_OBJECT(_cmenu_loc_add_poi), "activate", G_CALLBACK(cmenu_cb_loc_add_poi), NULL);
496 g_signal_connect(G_OBJECT(_cmenu_loc_set_gps), "activate", G_CALLBACK(cmenu_cb_loc_set_gps), NULL);
497 g_signal_connect(G_OBJECT(_cmenu_loc_set_home), "activate", G_CALLBACK(cmenu_cb_loc_set_home), NULL);
498 g_signal_connect(G_OBJECT(_cmenu_loc_set_destination), "activate", G_CALLBACK(cmenu_cb_loc_set_destination), NULL);
499
500 g_signal_connect(G_OBJECT(_cmenu_way_show_latlon_item), "activate", G_CALLBACK(cmenu_cb_way_show_latlon), NULL);
501 g_signal_connect(G_OBJECT(_cmenu_way_show_desc_item), "activate", G_CALLBACK(cmenu_cb_way_show_desc), NULL);
502 g_signal_connect(G_OBJECT(_cmenu_way_clip_latlon_item), "activate", G_CALLBACK(cmenu_cb_way_clip_latlon), NULL);
503 g_signal_connect(G_OBJECT(_cmenu_way_clip_desc_item), "activate", G_CALLBACK(cmenu_cb_way_clip_desc), NULL);
504 g_signal_connect(G_OBJECT(_cmenu_way_route_to_item), "activate", G_CALLBACK(cmenu_cb_way_route_to), NULL);
505 g_signal_connect(G_OBJECT(_cmenu_way_distance_to_item), "activate", G_CALLBACK(cmenu_cb_way_distance_to), NULL);
506 g_signal_connect(G_OBJECT(_cmenu_way_delete_item), "activate", G_CALLBACK(cmenu_cb_way_delete), NULL);
507 g_signal_connect(G_OBJECT(_cmenu_way_add_poi), "activate", G_CALLBACK(cmenu_cb_way_add_poi), NULL);
508 g_signal_connect(G_OBJECT(_cmenu_way_goto_nextway), "activate", G_CALLBACK(menu_cb_goto_nextway), NULL);
509
510 g_signal_connect(G_OBJECT(_cmenu_poi_edit_poi), "activate", G_CALLBACK(cmenu_cb_poi_edit_poi), NULL);
511 g_signal_connect(G_OBJECT(_cmenu_poi_route_to_item), "activate", G_CALLBACK(cmenu_cb_poi_route_to), NULL);
512 g_signal_connect(G_OBJECT(_cmenu_poi_distance_to_item), "activate", G_CALLBACK(cmenu_cb_poi_distance_to), NULL);
513 g_signal_connect(G_OBJECT(_cmenu_poi_add_route), "activate", G_CALLBACK(cmenu_cb_poi_add_route), NULL);
514 g_signal_connect(G_OBJECT(_cmenu_poi_add_way), "activate", G_CALLBACK(cmenu_cb_poi_add_way), NULL);
515 g_signal_connect(G_OBJECT(_cmenu_poi_goto_nearpoi), "activate", G_CALLBACK(menu_cb_goto_nearpoi), NULL);
516
517 gtk_widget_show_all(GTK_WIDGET(menu));
518
519 #ifdef WITH_DEVICE_770
520 gtk_widget_tap_and_hold_setup(map, GTK_WIDGET(menu), NULL, 0);
521 #else
522 _menu_map = menu;
523 #endif
524 }
525
526 static GtkWidget *
527 mapper_window_new(void) 
528 {
529 GtkWidget *window;
530
531 #ifdef WITH_HILDON
532 _program=HILDON_PROGRAM(hildon_program_get_instance());
533 window=GTK_WIDGET(hildon_window_new());
534 hildon_program_add_window(_program, HILDON_WINDOW(window));
535 #else
536 window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
537 gtk_window_set_title(GTK_WINDOW(window), "Mapper");
538 gtk_window_set_resizable(GTK_WINDOW(window), TRUE);
539 gtk_widget_set_size_request(GTK_WIDGET(window), WINDOW_SIZE_X, WINDOW_SIZE_Y);
540 gtk_window_resize(GTK_WINDOW(window), WINDOW_SIZE_X, WINDOW_SIZE_Y);
541 #endif
542
543 return window;
544 }
545
546 /**
547  * Set sensitivity of route menu items
548  */
549 void
550 route_menu_set_sensitive(gboolean s)
551 {
552 set_action_sensitive("route_save", s);
553 set_action_sensitive("route_dist_next", s);
554 set_action_sensitive("route_dist_last", s);
555 set_action_sensitive("route_reset", s);
556 set_action_sensitive("route_clear", s);
557 }
558
559 /**
560  * Create a tree view inside given container
561  */
562 static GtkWidget *
563 mapper_tree_view_new(GtkWidget *container) 
564 {
565 GtkWidget *tree_view, *sw;
566 GtkTreeViewColumn *column;
567 GtkCellRenderer *renderer;
568
569 tree_view=gtk_tree_view_new();
570 sw=gtk_scrolled_window_new(NULL, NULL);
571 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
572 gtk_container_add(GTK_CONTAINER(sw), tree_view);
573 gtk_box_pack_start(container, sw, TRUE, TRUE, 0);
574 gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view)), GTK_SELECTION_SINGLE);
575 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree_view), TRUE);
576
577 renderer=gtk_cell_renderer_text_new();
578 column=gtk_tree_view_column_new_with_attributes(_("Location"), renderer, "text", PATH_LATLON, NULL);
579 gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
580
581 renderer=gtk_cell_renderer_text_new();
582 column=gtk_tree_view_column_new_with_attributes(_("Distance"), renderer, "text", PATH_DISTANCE, NULL);
583 gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
584
585 renderer=gtk_cell_renderer_text_new();
586 column=gtk_tree_view_column_new_with_attributes(_("Waypoint"), renderer, "text", PATH_WAYPOINT, NULL);
587 gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
588
589 return tree_view;
590 }
591
592 /**
593  * Initialize everything required in preparation for calling gtk_main().
594  */
595 void 
596 mapper_ui_init(void)
597 {
598 GError *error = NULL;
599 GtkWidget *hbox, *mapvbox, *label, *vbox_main;
600 GtkWidget *vbox;
601 GtkNotebook *notebook;
602 GtkToolItem *item;
603 GtkTreeViewColumn *column;
604 GtkCellRenderer *renderer;
605
606 _window=mapper_window_new();
607 gtk_container_set_border_width (GTK_CONTAINER (_window), 0);
608
609 actions = gtk_action_group_new ("Actions");
610 g_assert(actions);
611
612 ui = gtk_ui_manager_new ();
613 g_assert(ui);
614
615 /* N810 has keyboard so set this up on hildon too */
616 gtk_window_add_accel_group(GTK_WINDOW(_window), gtk_ui_manager_get_accel_group (ui));
617
618 if (!gtk_ui_manager_add_ui_from_string(ui, mapper_ui, -1, &error)) {
619         g_message ("building menus failed: %s", error->message);
620         g_error_free(error);
621         g_assert(FALSE);
622 }
623
624 /* Menu and Toolbar */
625 menu_bar = gtk_ui_manager_get_widget (ui, "/MenuBar");
626 g_assert(menu_bar);
627
628 _toolbar = gtk_ui_manager_get_widget (ui, "/ToolBar");
629 g_assert(_toolbar);
630
631 /* Toolbar progress item */
632 item=gtk_tool_item_new();
633 _progress_item=gtk_progress_bar_new();
634 gtk_tool_item_set_expand(item, TRUE);
635 gtk_progress_bar_set_ellipsize(_progress_item, PANGO_ELLIPSIZE_END);
636 gtk_progress_bar_set_pulse_step(_progress_item, 0.2);
637 gtk_container_add(item, _progress_item);
638 gtk_toolbar_insert(GTK_TOOLBAR(_toolbar), item, -1);
639
640 /* Notebook with different views */
641 notebook = gtk_notebook_new();
642 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook), TRUE);
643
644 info_banner.container=gtk_hbox_new(FALSE, 0);
645 info_banner.location=gtk_label_new("");
646 info_banner.speed=gtk_label_new("");
647 info_banner.distance=gtk_label_new("");
648
649 gtk_misc_set_alignment(GTK_MISC(info_banner.location), 0.f, 0.5f);
650 gtk_misc_set_alignment(GTK_MISC(info_banner.speed), 1.f, 0.5f);
651 gtk_misc_set_alignment(GTK_MISC(info_banner.distance), 1.f, 0.5f);
652
653 gtk_box_pack_start(GTK_BOX(info_banner.container), info_banner.location, TRUE, TRUE, 0);
654 gtk_box_pack_end(GTK_BOX(info_banner.container), info_banner.speed, FALSE, FALSE, 0);
655 gtk_box_pack_end(GTK_BOX(info_banner.container), info_banner.distance, FALSE, FALSE, 0);
656
657 vbox_main = gtk_vbox_new(FALSE, 0);
658 gtk_container_add(GTK_CONTAINER(_window), vbox_main);
659
660 #ifdef WITH_HILDON
661 /* Create and add widgets and supporting data. */
662 gtk_box_pack_start(GTK_BOX(vbox_main), GTK_WIDGET(notebook), TRUE, TRUE, 0);
663 gtk_box_pack_start(GTK_BOX(vbox_main), GTK_WIDGET(info_banner.container), FALSE, FALSE, 0);
664 {
665         GtkMenu *hmenu;
666         hmenu = GTK_MENU(gtk_menu_new());
667
668         gtk_container_foreach(GTK_CONTAINER(menu_bar), (GtkCallback)gtk_widget_reparent, hmenu);
669         hildon_window_set_menu(HILDON_WINDOW(_window), hmenu);
670 }
671 hildon_window_add_toolbar(_window, GTK_TOOLBAR(_toolbar));
672 gtk_widget_show_all(GTK_WIDGET(_toolbar));
673 #else
674 _status_bar = gtk_statusbar_new();
675 gtk_box_pack_start(GTK_BOX(vbox_main), menu_bar, FALSE, FALSE, 0);
676 gtk_box_pack_start(GTK_BOX(vbox_main), _toolbar, FALSE, FALSE, 0);
677 gtk_box_pack_start(GTK_BOX(vbox_main), notebook, TRUE, TRUE, 0);
678 gtk_box_pack_start(GTK_BOX(vbox_main), info_banner.container, FALSE, FALSE, 0);
679 gtk_box_pack_start(GTK_BOX(vbox_main), _status_bar, FALSE, FALSE, 0);
680 #endif
681
682 label = gtk_label_new("Map");
683 hbox = gtk_hpaned_new();
684
685 /* GPS Panel */
686 _gps_widget=gps_info_panel();
687 gtk_widget_set_size_request(GTK_WIDGET(_gps_widget), 180, 0);
688 gtk_paned_add1(GTK_PANED(hbox), _gps_widget);
689
690 mapvbox=gtk_vbox_new(FALSE, 0);
691 gtk_box_pack_start(GTK_BOX(mapvbox), hbox, TRUE, TRUE, 0);
692 ui_notebook.map=gtk_notebook_append_page(notebook, mapvbox, label);
693
694 /* Map widget */
695 _map=gtk_map_new();
696 gtk_paned_add2(GTK_PANED(hbox), _map);
697
698 #ifndef WITH_DEVICE_770
699 gtk_map_set_cache_size(_map, 256);
700 #endif
701
702 gtk_action_group_add_actions(actions, ui_entries, n_ui_entries, NULL);
703 gtk_action_group_add_toggle_actions(actions, ui_toggle_entries, n_ui_toggle_entries, NULL);
704 gtk_action_group_add_radio_actions(actions, ui_autocenter_entries, 
705         n_ui_autocenter_entries, gtk_map_get_center_mode(_map), G_CALLBACK(menu_cb_autocenter),  NULL);
706
707 gtk_ui_manager_insert_action_group(ui, actions, 0);
708 g_object_unref(actions);
709
710 /* GPS Tab */
711 vbox = gtk_vbox_new(FALSE, 0);
712 label = gtk_label_new("Gps");
713 _gps_sat_view = gtk_gps_new(GTK_GPS_MODE_SKY, &_gps->data);
714 gtk_box_pack_start(GTK_BOX(vbox), _gps_sat_view, TRUE, TRUE, 0);
715 _gps_sat_view = gtk_gps_new(GTK_GPS_MODE_SIGNAL, &_gps->data);
716 gtk_box_pack_start(GTK_BOX(vbox), _gps_sat_view, TRUE, TRUE, 0);
717 ui_notebook.gps=gtk_notebook_append_page(notebook, vbox, label);
718
719 /* Heading Tab */
720 vbox = gtk_vbox_new(FALSE, 0);
721 label = gtk_label_new("Heading");
722 _tab_compass = gtk_compass_new(&_gps->data);
723 gtk_box_pack_start(GTK_BOX(vbox), _tab_compass, TRUE, TRUE, 0);
724 ui_notebook.heading=gtk_notebook_append_page(notebook, vbox, label);
725
726 /* Track Tab */
727 vbox=gtk_vbox_new(FALSE, 0);
728 label=gtk_label_new("Track");
729 track_tree_view=mapper_tree_view_new(vbox);
730 #if 0
731 g_signal_connect(G_OBJECT(track_tree_view), "row-activated", G_CALLBACK(track_waypoint_activated_cb), NULL);
732 #endif
733 ui_notebook.track=gtk_notebook_append_page(notebook, vbox, label);
734
735 /* Route Tab */
736 vbox=gtk_vbox_new(FALSE, 0);
737 label=gtk_label_new("Route");
738 route_tree_view=mapper_tree_view_new(vbox);
739 #if 0
740 g_signal_connect(G_OBJECT(route_tree_view), "row-activated", G_CALLBACK(route_waypoint_activated_cb), NULL);
741 #endif
742 ui_notebook.route=gtk_notebook_append_page(notebook, vbox, label);
743
744 /* Quick POI Tab */
745 label=gtk_label_new("Quick POI");
746 tqp.fixed=FALSE;
747 tqp.close=FALSE;
748 vbox=poi_quick_button_box(&tqp);
749 ui_notebook.qpoi=gtk_notebook_append_page(notebook, vbox, label);
750
751 #ifdef WITH_GST
752 {
753 audio_note_ui *an_ui;
754 label=gtk_label_new("Audio");
755 an_ui=audio_note_new();
756 ui_notebook.audio=gtk_notebook_append_page(notebook, an_ui->vbox, label);
757 }
758 #endif
759
760 menu_maps_add_repos();
761 menu_init_cmenu();
762
763 memset(&_autoroute_data, 0, sizeof(_autoroute_data));
764
765 g_signal_connect(G_OBJECT(_window), "delete_event", G_CALLBACK(mapper_cb_quit), NULL);
766 g_signal_connect(G_OBJECT(_window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
767
768 gtk_widget_show_all(GTK_WIDGET(vbox_main));
769 gtk_widget_show_all(GTK_WIDGET(_window));
770
771 /* Initialize our line styles. */
772 update_gcs();
773
774 /* Set defaults for items */
775 set_action_activate("map_auto_download", _auto_download);
776 set_action_activate("gps_enabled", _enable_gps);
777 set_action_sensitive("goto_gps", _enable_gps);
778
779 set_action_sensitive("autocenter_latlon", _enable_gps);
780 set_action_sensitive("autocenter_lead", _enable_gps);
781
782 set_action_activate("gps_information", _gps_info);
783
784 set_action_activate("view_toolbar", TRUE);
785
786 set_action_activate("view_scale", _show_scale);
787 set_action_activate("view_vector", _show_velvec);
788 set_action_activate("view_poi", _show_poi);
789
790 set_action_activate("view_track", _show_tracks & TRACKS_MASK);
791 set_action_activate("view_route", _show_tracks & ROUTES_MASK);
792
793 route_menu_set_sensitive(FALSE);
794
795 gps_show_info(&_gps->data);
796
797 /* Connect signals. */
798 g_signal_connect(G_OBJECT(_window), "key_press_event", G_CALLBACK(window_cb_key_press), NULL);
799 g_signal_connect(G_OBJECT(_window), "key_release_event", G_CALLBACK(window_cb_key_release), NULL);
800
801 gtk_idle_add((GSourceFunc)window_present, NULL);
802 }
803
804 /******* XXX: Move these !! *******/
805
806 gboolean
807 gps_info_update(Gps *gps)
808 {
809 g_assert(gps);
810 if (_gps_info)
811     gps_display_data(&gps->data);
812
813 gps_display_data_speed(info_banner.speed, gps->data.speed);
814
815 return FALSE;
816 }
817
818 gboolean
819 gps_satellite_update(Gps *gps)
820 {
821 g_assert(gps);
822 if (_satdetails_on)
823     gps_display_details(&gps->data);
824
825 return FALSE;
826 }
827
828 gboolean
829 gps_location_update(Gps *gps)
830 {
831 g_assert(gps);
832 if (filter_check(&filter, &gps->data, &map_loc)==TRUE) {
833         if (path_add_point(_track, &_gps->data)) {
834                 path_check_waypoint_announce(_route, &_gps->data);
835 #if 0
836                 route_autoroute_check(_route);
837 #endif
838                 KEEP_DISPLAY_ON();
839         }
840 }
841 return FALSE;
842 }
843
844 /**
845  * Simple dialog to ask if we should try to reconnect to GPS
846  * returns TRUE or FALSE
847  */
848 gboolean
849 gps_retry_connection(Gps *gps, const gchar *error)
850 {
851 GtkWidget *confirm;
852 gboolean r;
853
854 g_assert(gps);
855 confirm=hildon_note_new_confirmation(GTK_WINDOW(_window), _("Failed to connect to GPS receiver. Retry?"));
856 r=(GTK_RESPONSE_OK==gtk_dialog_run(GTK_DIALOG(confirm))) ? TRUE : FALSE;
857 gtk_widget_destroy(confirm);
858 return r;
859 }