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