]> git.itanic.dy.fi Git - maemo-mapper/blob - src/settings.c
Added "Map Correction" feature, to address the rare problem of inaccurate
[maemo-mapper] / src / settings.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 <stdlib.h>
31 #include <string.h>
32 #include <math.h>
33 #include <dbus/dbus-glib.h>
34 #include <bt-dbus.h>
35 #include <gconf/gconf-client.h>
36
37 #ifndef LEGACY
38 #    include <hildon/hildon-help.h>
39 #    include <hildon/hildon-note.h>
40 #    include <hildon/hildon-color-button.h>
41 #    include <hildon/hildon-file-chooser-dialog.h>
42 #    include <hildon/hildon-number-editor.h>
43 #    include <hildon/hildon-banner.h>
44 #else
45 #    include <osso-helplib.h>
46 #    include <hildon-widgets/hildon-note.h>
47 #    include <hildon-widgets/hildon-color-button.h>
48 #    include <hildon-widgets/hildon-file-chooser-dialog.h>
49 #    include <hildon-widgets/hildon-number-editor.h>
50 #    include <hildon-widgets/hildon-banner.h>
51 #    include <hildon-widgets/hildon-input-mode-hint.h>
52 #endif
53
54 #include "types.h"
55 #include "data.h"
56 #include "defines.h"
57
58 #include "gps.h"
59 #include "display.h"
60 #include "gdk-pixbuf-rotate.h"
61 #include "maps.h"
62 #include "marshal.h"
63 #include "poi.h"
64 #include "settings.h"
65 #include "util.h"
66
67 #define GCONF_KEY_PREFIX "/apps/maemo/maemo-mapper"
68 #define GCONF_KEY_GPS_RCVR_TYPE GCONF_KEY_PREFIX"/gps_rcvr_type"
69 #define GCONF_KEY_GPS_BT_MAC GCONF_KEY_PREFIX"/receiver_mac"
70 #define GCONF_KEY_GPS_GPSD_HOST GCONF_KEY_PREFIX"/gps_gpsd_host"
71 #define GCONF_KEY_GPS_GPSD_PORT GCONF_KEY_PREFIX"/gps_gpsd_port"
72 #define GCONF_KEY_GPS_FILE_PATH GCONF_KEY_PREFIX"/gps_file_path"
73 #define GCONF_KEY_AUTO_DOWNLOAD GCONF_KEY_PREFIX"/auto_download"
74 #define GCONF_KEY_AUTO_DOWNLOAD_PRECACHE \
75                                       GCONF_KEY_PREFIX"/auto_download_precache"
76 #define GCONF_KEY_CENTER_SENSITIVITY GCONF_KEY_PREFIX"/center_sensitivity"
77 #define GCONF_KEY_ENABLE_ANNOUNCE GCONF_KEY_PREFIX"/enable_announce"
78 #define GCONF_KEY_ANNOUNCE_NOTICE GCONF_KEY_PREFIX"/announce_notice"
79 #define GCONF_KEY_ROTATE_SENSITIVITY GCONF_KEY_PREFIX"/rotate_sensitivity"
80 #define GCONF_KEY_AC_MIN_SPEED GCONF_KEY_PREFIX"/autocenter_min_speed"
81 #define GCONF_KEY_ROTATE_DIR GCONF_KEY_PREFIX"/rotate_direction"
82 #define GCONF_KEY_DRAW_WIDTH GCONF_KEY_PREFIX"/draw_width"
83 #define GCONF_KEY_ENABLE_VOICE GCONF_KEY_PREFIX"/enable_voice"
84 #define GCONF_KEY_VOICE_SPEED GCONF_KEY_PREFIX"/voice_speed"
85 #define GCONF_KEY_VOICE_PITCH GCONF_KEY_PREFIX"/voice_pitch"
86 #define GCONF_KEY_FULLSCREEN GCONF_KEY_PREFIX"/fullscreen"
87 #define GCONF_KEY_UNITS GCONF_KEY_PREFIX"/units"
88 #define GCONF_KEY_SPEED_LIMIT_ON GCONF_KEY_PREFIX"/speed_limit_on"
89 #define GCONF_KEY_SPEED_LIMIT GCONF_KEY_PREFIX"/speed_limit"
90 #define GCONF_KEY_SPEED_LOCATION GCONF_KEY_PREFIX"/speed_location"
91 #define GCONF_KEY_UNBLANK_SIZE GCONF_KEY_PREFIX"/unblank_option"
92 #define GCONF_KEY_INFO_FONT_SIZE GCONF_KEY_PREFIX"/info_font_size"
93
94 #define GCONF_KEY_POI_DB GCONF_KEY_PREFIX"/poi_db"
95 #define GCONF_KEY_POI_ZOOM GCONF_KEY_PREFIX"/poi_zoom"
96
97 #define GCONF_KEY_AUTOCENTER_MODE GCONF_KEY_PREFIX"/autocenter_mode"
98 #define GCONF_KEY_AUTOCENTER_ROTATE GCONF_KEY_PREFIX"/autocenter_rotate"
99 #define GCONF_KEY_LEAD_AMOUNT GCONF_KEY_PREFIX"/lead_amount"
100 #define GCONF_KEY_LEAD_IS_FIXED GCONF_KEY_PREFIX"/lead_is_fixed"
101 #define GCONF_KEY_LAST_LAT GCONF_KEY_PREFIX"/last_latitude"
102 #define GCONF_KEY_LAST_LON GCONF_KEY_PREFIX"/last_longitude"
103 #define GCONF_KEY_LAST_ALT GCONF_KEY_PREFIX"/last_altitude"
104 #define GCONF_KEY_LAST_SPEED GCONF_KEY_PREFIX"/last_speed"
105 #define GCONF_KEY_LAST_HEADING GCONF_KEY_PREFIX"/last_heading"
106 #define GCONF_KEY_LAST_TIME GCONF_KEY_PREFIX"/last_timestamp"
107 #define GCONF_KEY_CENTER_LAT GCONF_KEY_PREFIX"/center_latitude"
108 #define GCONF_KEY_CENTER_LON GCONF_KEY_PREFIX"/center_longitude"
109 #define GCONF_KEY_CENTER_ANGLE GCONF_KEY_PREFIX"/center_angle"
110 #define GCONF_KEY_MAP_CORRECTION_UNITX GCONF_KEY_PREFIX"/map_correction_unitx"
111 #define GCONF_KEY_MAP_CORRECTION_UNITY GCONF_KEY_PREFIX"/map_correction_unity"
112 #define GCONF_KEY_ZOOM GCONF_KEY_PREFIX"/zoom"
113 #define GCONF_KEY_ROUTEDIR GCONF_KEY_PREFIX"/route_directory"
114 #define GCONF_KEY_TRACKFILE GCONF_KEY_PREFIX"/track_file"
115 #define GCONF_KEY_SHOWZOOMLEVEL GCONF_KEY_PREFIX"/show_zoomlevel"
116 #define GCONF_KEY_SHOWSCALE GCONF_KEY_PREFIX"/show_scale"
117 #define GCONF_KEY_SHOWCOMPROSE GCONF_KEY_PREFIX"/show_comprose"
118 #define GCONF_KEY_SHOWTRACKS GCONF_KEY_PREFIX"/show_tracks"
119 #define GCONF_KEY_SHOWROUTES GCONF_KEY_PREFIX"/show_routes"
120 #define GCONF_KEY_SHOWVELVEC GCONF_KEY_PREFIX"/show_velocity_vector" 
121 #define GCONF_KEY_SHOWPOIS GCONF_KEY_PREFIX"/show_poi" 
122 #define GCONF_KEY_ENABLE_GPS GCONF_KEY_PREFIX"/enable_gps" 
123 #define GCONF_KEY_ROUTE_LOCATIONS GCONF_KEY_PREFIX"/route_locations" 
124 #define GCONF_KEY_REPOSITORIES GCONF_KEY_PREFIX"/repositories" 
125 #define GCONF_KEY_CURRREPO GCONF_KEY_PREFIX"/curr_repo" 
126 #define GCONF_KEY_GPS_INFO GCONF_KEY_PREFIX"/gps_info" 
127 #define GCONF_KEY_ROUTE_DL_URL GCONF_KEY_PREFIX"/route_dl_url" 
128 #define GCONF_KEY_ROUTE_DL_RADIUS GCONF_KEY_PREFIX"/route_dl_radius" 
129 #define GCONF_KEY_POI_DL_URL GCONF_KEY_PREFIX"/poi_dl_url" 
130 #define GCONF_KEY_DEG_FORMAT GCONF_KEY_PREFIX"/deg_format" 
131
132
133 typedef struct _ScanInfo ScanInfo;
134 struct _ScanInfo {
135     GtkWidget *settings_dialog;
136     GtkWidget *txt_gps_bt_mac;
137     GtkWidget *scan_dialog;
138     GtkWidget *banner;
139     GtkListStore *store;
140     gint sid;
141     DBusGConnection *bus;
142     DBusGProxy *req_proxy;
143     DBusGProxy *sig_proxy;
144 };
145
146 typedef struct _KeysDialogInfo KeysDialogInfo;
147 struct _KeysDialogInfo {
148     GtkWidget *cmb[CUSTOM_KEY_ENUM_COUNT];
149 };
150
151 typedef struct _ColorsDialogInfo ColorsDialogInfo;
152 struct _ColorsDialogInfo {
153     GtkWidget *col[COLORABLE_ENUM_COUNT];
154 };
155
156
157 /**
158  * Save all configuration data to GCONF.
159  */
160 void
161 settings_save()
162 {
163     gchar *settings_dir;
164     GConfClient *gconf_client;
165     gchar buffer[16];
166     printf("%s()\n", __PRETTY_FUNCTION__);
167
168     /* Initialize settings_dir. */
169     settings_dir = gnome_vfs_expand_initial_tilde(CONFIG_DIR_NAME);
170     g_mkdir_with_parents(settings_dir, 0700);
171
172     /* SAVE ALL GCONF SETTINGS. */
173
174     gconf_client = gconf_client_get_default();
175     if(!gconf_client)
176     {
177         popup_error(_window,
178                 _("Failed to initialize GConf.  Settings were not saved."));
179         return;
180     }
181
182     /* Save GPS Receiver Type. */
183     gconf_client_set_string(gconf_client,
184             GCONF_KEY_GPS_RCVR_TYPE,
185             GPS_RCVR_ENUM_TEXT[_gri.type], NULL);
186
187     /* Save Bluetooth Receiver MAC. */
188     if(_gri.bt_mac)
189         gconf_client_set_string(gconf_client,
190                 GCONF_KEY_GPS_BT_MAC, _gri.bt_mac, NULL);
191     else
192         gconf_client_unset(gconf_client,
193                 GCONF_KEY_GPS_BT_MAC, NULL);
194
195     /* Save GPSD Host. */
196     if(_gri.gpsd_host)
197         gconf_client_set_string(gconf_client,
198                 GCONF_KEY_GPS_GPSD_HOST, _gri.gpsd_host, NULL);
199     else
200         gconf_client_unset(gconf_client,
201                 GCONF_KEY_GPS_GPSD_HOST, NULL);
202
203     /* Save GPSD Port. */
204     gconf_client_set_int(gconf_client,
205             GCONF_KEY_GPS_GPSD_PORT, _gri.gpsd_port, NULL);
206
207     /* Save File Path. */
208     if(_gri.file_path)
209         gconf_client_set_string(gconf_client,
210                 GCONF_KEY_GPS_FILE_PATH, _gri.file_path, NULL);
211     else
212         gconf_client_unset(gconf_client,
213                 GCONF_KEY_GPS_FILE_PATH, NULL);
214
215     /* Save Auto-Download. */
216     gconf_client_set_bool(gconf_client,
217             GCONF_KEY_AUTO_DOWNLOAD, _auto_download, NULL);
218
219     /* Save Auto-Download Pre-cache. */
220     gconf_client_set_int(gconf_client,
221             GCONF_KEY_AUTO_DOWNLOAD_PRECACHE, _auto_download_precache, NULL);
222
223     /* Save Auto-Center Sensitivity. */
224     gconf_client_set_int(gconf_client,
225             GCONF_KEY_CENTER_SENSITIVITY, _center_ratio, NULL);
226
227     /* Save Auto-Center Lead Amount. */
228     gconf_client_set_int(gconf_client,
229             GCONF_KEY_LEAD_AMOUNT, _lead_ratio, NULL);
230
231     /* Save Auto-Center Lead Fixed flag. */
232     gconf_client_set_bool(gconf_client,
233             GCONF_KEY_LEAD_IS_FIXED, _lead_is_fixed, NULL);
234
235     /* Save Auto-Rotate Sensitivity. */
236     gconf_client_set_int(gconf_client,
237             GCONF_KEY_ROTATE_SENSITIVITY, _rotate_sens, NULL);
238
239     /* Save Auto-Center/Rotate Minimum Speed. */
240     gconf_client_set_int(gconf_client,
241             GCONF_KEY_AC_MIN_SPEED, _ac_min_speed, NULL);
242
243     /* Save Auto-Rotate Sensitivity. */
244     gconf_client_set_string(gconf_client,
245             GCONF_KEY_ROTATE_DIR, ROTATE_DIR_ENUM_TEXT[_rotate_dir], NULL);
246
247     /* Save Draw Line Width. */
248     gconf_client_set_int(gconf_client,
249             GCONF_KEY_DRAW_WIDTH, _draw_width, NULL);
250
251     /* Save Announce Flag. */
252     gconf_client_set_bool(gconf_client,
253             GCONF_KEY_ENABLE_ANNOUNCE, _enable_announce, NULL);
254
255     /* Save Announce Advance Notice Ratio. */
256     gconf_client_set_int(gconf_client,
257             GCONF_KEY_ANNOUNCE_NOTICE, _announce_notice_ratio, NULL);
258
259     /* Save Enable Voice flag. */
260     gconf_client_set_bool(gconf_client,
261             GCONF_KEY_ENABLE_VOICE, _enable_voice, NULL);
262
263     /* Save fullscreen flag. */
264     gconf_client_set_bool(gconf_client,
265             GCONF_KEY_FULLSCREEN, _fullscreen, NULL);
266
267     /* Save Units. */
268     gconf_client_set_string(gconf_client,
269             GCONF_KEY_UNITS, UNITS_ENUM_TEXT[_units], NULL);
270
271     /* Save Custom Key Actions. */
272     {
273         gint i;
274         for(i = 0; i < CUSTOM_KEY_ENUM_COUNT; i++)
275             gconf_client_set_string(gconf_client,
276                     CUSTOM_KEY_GCONF[i],
277                     CUSTOM_ACTION_ENUM_TEXT[_action[i]], NULL);
278     }
279
280     /* Save Deg Format. */
281     gconf_client_set_string(gconf_client,
282             GCONF_KEY_DEG_FORMAT, DEG_FORMAT_ENUM_TEXT[_degformat], NULL);
283
284     /* Save Speed Limit On flag. */
285     gconf_client_set_bool(gconf_client,
286             GCONF_KEY_SPEED_LIMIT_ON, _speed_limit_on, NULL);
287
288     /* Save Speed Limit. */
289     gconf_client_set_int(gconf_client,
290             GCONF_KEY_SPEED_LIMIT, _speed_limit, NULL);
291
292     /* Save Speed Location. */
293     gconf_client_set_string(gconf_client,
294             GCONF_KEY_SPEED_LOCATION,
295             SPEED_LOCATION_ENUM_TEXT[_speed_location], NULL);
296
297     /* Save Info Font Size. */
298     gconf_client_set_string(gconf_client,
299             GCONF_KEY_INFO_FONT_SIZE,
300             INFO_FONT_ENUM_TEXT[_info_font_size], NULL);
301
302     /* Save Unblank Option. */
303     gconf_client_set_string(gconf_client,
304             GCONF_KEY_UNBLANK_SIZE,
305             UNBLANK_ENUM_TEXT[_unblank_option], NULL);
306
307     /* Save last saved latitude. */
308     gconf_client_set_float(gconf_client,
309             GCONF_KEY_LAST_LAT, _gps.lat, NULL);
310
311     /* Save last saved longitude. */
312     gconf_client_set_float(gconf_client,
313             GCONF_KEY_LAST_LON, _gps.lon, NULL);
314
315     /* Save last saved altitude. */
316     gconf_client_set_int(gconf_client,
317             GCONF_KEY_LAST_ALT, _pos.altitude, NULL);
318
319     /* Save last saved speed. */
320     gconf_client_set_float(gconf_client,
321             GCONF_KEY_LAST_SPEED, _gps.speed, NULL);
322
323     /* Save last saved heading. */
324     gconf_client_set_float(gconf_client,
325             GCONF_KEY_LAST_HEADING, _gps.heading, NULL);
326
327     /* Save last saved timestamp. */
328     gconf_client_set_float(gconf_client,
329             GCONF_KEY_LAST_TIME, _pos.time, NULL);
330
331     /* Save last center point. */
332     {
333         gdouble center_lat, center_lon;
334         unit2latlon(_center.unitx, _center.unity, center_lat, center_lon);
335
336         /* Save last center latitude. */
337         gconf_client_set_float(gconf_client,
338                 GCONF_KEY_CENTER_LAT, center_lat, NULL);
339
340         /* Save last center longitude. */
341         gconf_client_set_float(gconf_client,
342                 GCONF_KEY_CENTER_LON, center_lon, NULL);
343
344         /* Save last view angle. */
345         gconf_client_set_int(gconf_client,
346                 GCONF_KEY_CENTER_ANGLE, _map_rotate_angle, NULL);
347     }
348
349     /* Save map correction. */
350     gconf_client_set_int(gconf_client,
351             GCONF_KEY_MAP_CORRECTION_UNITX, _map_correction_unitx, NULL);
352     gconf_client_set_int(gconf_client,
353             GCONF_KEY_MAP_CORRECTION_UNITY, _map_correction_unity, NULL);
354
355     /* Save last Zoom Level. */
356     gconf_client_set_int(gconf_client,
357             GCONF_KEY_ZOOM, _zoom, NULL);
358
359     /* Save Route Directory. */
360     if(_route_dir_uri)
361         gconf_client_set_string(gconf_client,
362                 GCONF_KEY_ROUTEDIR, _route_dir_uri, NULL);
363
364     /* Save the repositories. */
365     {
366         GList *curr = _repo_list;
367         GSList *temp_list = NULL;
368         gint curr_repo_index = 0;
369
370         for(curr = _repo_list; curr != NULL; curr = curr->next)
371         {
372             /* Build from each part of a repo, delimited by newline characters:
373              * 1. url
374              * 2. db_filename
375              * 3. dl_zoom_steps
376              * 4. view_zoom_steps
377              */
378             RepoData *rd = curr->data;
379             gchar buffer[BUFFER_SIZE];
380             snprintf(buffer, sizeof(buffer),
381                     "%s\t%s\t%s\t%d\t%d\t%d\t%d\t%d\t%d",
382                     rd->name,
383                     rd->url,
384                     rd->db_filename,
385                     rd->dl_zoom_steps,
386                     rd->view_zoom_steps,
387                     rd->double_size,
388                     rd->nextable,
389                     rd->min_zoom,
390                     rd->max_zoom);
391             temp_list = g_slist_append(temp_list, g_strdup(buffer));
392             if(rd == _curr_repo)
393                 gconf_client_set_int(gconf_client,
394                         GCONF_KEY_CURRREPO, curr_repo_index, NULL);
395             curr_repo_index++;
396         }
397         gconf_client_set_list(gconf_client,
398                 GCONF_KEY_REPOSITORIES, GCONF_VALUE_STRING, temp_list, NULL);
399     }
400
401     /* Save Last Track File. */
402     if(_track_file_uri)
403         gconf_client_set_string(gconf_client,
404                 GCONF_KEY_TRACKFILE, _track_file_uri, NULL);
405
406     /* Save Auto-Center Mode. */
407     gconf_client_set_int(gconf_client,
408             GCONF_KEY_AUTOCENTER_MODE, _center_mode, NULL);
409
410     /* Save Auto-Center Rotate Flag. */
411     gconf_client_set_bool(gconf_client,
412             GCONF_KEY_AUTOCENTER_ROTATE, _center_rotate, NULL);
413
414     /* Save Show Zoom Level flag. */
415     gconf_client_set_bool(gconf_client,
416             GCONF_KEY_SHOWZOOMLEVEL, _show_zoomlevel, NULL);
417
418     /* Save Show Scale flag. */
419     gconf_client_set_bool(gconf_client,
420             GCONF_KEY_SHOWSCALE, _show_scale, NULL);
421
422     /* Save Show Compass Rose flag. */
423     gconf_client_set_bool(gconf_client,
424             GCONF_KEY_SHOWCOMPROSE, _show_comprose, NULL);
425
426     /* Save Show Tracks flag. */
427     gconf_client_set_bool(gconf_client,
428             GCONF_KEY_SHOWTRACKS, _show_paths & TRACKS_MASK, NULL);
429
430     /* Save Show Routes flag. */
431     gconf_client_set_bool(gconf_client,
432             GCONF_KEY_SHOWROUTES, _show_paths & ROUTES_MASK, NULL);
433
434     /* Save Show Velocity Vector flag. */
435     gconf_client_set_bool(gconf_client,
436             GCONF_KEY_SHOWVELVEC, _show_velvec, NULL);
437
438     /* Save Show POIs flag. */
439     gconf_client_set_bool(gconf_client,
440             GCONF_KEY_SHOWPOIS, _show_poi, NULL);
441
442     /* Save Enable GPS flag. */
443     gconf_client_set_bool(gconf_client,
444             GCONF_KEY_ENABLE_GPS, _enable_gps, NULL);
445
446     /* Save Route Locations. */
447     gconf_client_set_list(gconf_client,
448             GCONF_KEY_ROUTE_LOCATIONS, GCONF_VALUE_STRING, _loc_list, NULL);
449
450     /* Save GPS Info flag. */
451     gconf_client_set_bool(gconf_client,
452             GCONF_KEY_GPS_INFO, _gps_info, NULL);
453
454     /* Save Route Download URL Format. */
455     gconf_client_set_string(gconf_client,
456             GCONF_KEY_ROUTE_DL_URL, _route_dl_url, NULL);
457
458     /* Save Route Download Radius. */
459     gconf_client_set_int(gconf_client,
460             GCONF_KEY_ROUTE_DL_RADIUS, _route_dl_radius, NULL);
461
462     /* Save POI Download URL Format. */
463     gconf_client_set_string(gconf_client,
464             GCONF_KEY_POI_DL_URL, _poi_dl_url, NULL);
465
466     /* Save Colors. */
467     {
468         gint i;
469         for(i = 0; i < COLORABLE_ENUM_COUNT; i++)
470         {
471             snprintf(buffer, sizeof(buffer), "#%02x%02x%02x",
472                     _color[i].red >> 8,
473                     _color[i].green >> 8,
474                     _color[i].blue >> 8);
475             gconf_client_set_string(gconf_client,
476                     COLORABLE_GCONF[i], buffer, NULL);
477         }
478     }
479
480     /* Save POI database. */
481     if(_poi_db_filename)
482         gconf_client_set_string(gconf_client,
483                 GCONF_KEY_POI_DB, _poi_db_filename, NULL);
484     else
485         gconf_client_unset(gconf_client, GCONF_KEY_POI_DB, NULL);
486
487     /* Save Show POI below zoom. */
488     gconf_client_set_int(gconf_client,
489             GCONF_KEY_POI_ZOOM, _poi_zoom, NULL);
490
491     gconf_client_clear_cache(gconf_client);
492     g_object_unref(gconf_client);
493     g_free(settings_dir);
494
495     vprintf("%s(): return\n", __PRETTY_FUNCTION__);
496 }
497
498 static void
499 scan_cb_dev_found(DBusGProxy *sig_proxy, const gchar *bda,
500         const gchar *name, gpointer *class, guchar rssi, gint coff,
501         ScanInfo *scan_info)
502 {
503     GtkTreeIter iter;
504     printf("%s()\n", __PRETTY_FUNCTION__);
505     gtk_list_store_append(scan_info->store, &iter);
506     gtk_list_store_set(scan_info->store, &iter,
507             0, g_strdup(bda),
508             1, g_strdup(name),
509             -1);
510     vprintf("%s(): return\n", __PRETTY_FUNCTION__);
511 }
512
513 static void
514 scan_cb_search_complete(DBusGProxy *sig_proxy, ScanInfo *scan_info)
515 {
516     printf("%s()\n", __PRETTY_FUNCTION__);
517     gtk_widget_destroy(scan_info->banner);
518     dbus_g_proxy_disconnect_signal(sig_proxy, BTSEARCH_DEV_FOUND_SIG,
519             G_CALLBACK(scan_cb_dev_found), scan_info);
520     dbus_g_proxy_disconnect_signal(sig_proxy, BTSEARCH_SEARCH_COMPLETE_SIG,
521             G_CALLBACK(scan_cb_search_complete), scan_info);
522     vprintf("%s(): return\n", __PRETTY_FUNCTION__);
523 }
524
525 static gint
526 scan_start_search(ScanInfo *scan_info)
527 {
528     GError *error = NULL;
529     printf("%s()\n", __PRETTY_FUNCTION__);
530
531     /* Initialize D-Bus. */
532     if(NULL == (scan_info->bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error)))
533     {
534         g_printerr("Failed to open connection to D-Bus: %s.\n",
535                 error->message);
536         return 1;
537     }
538
539     if(NULL == (scan_info->req_proxy =dbus_g_proxy_new_for_name(scan_info->bus,
540             BTSEARCH_SERVICE,
541             BTSEARCH_REQ_PATH,
542             BTSEARCH_REQ_INTERFACE)))
543     {
544         g_printerr("Failed to create D-Bus request proxy for btsearch.");
545         return 2;
546     }
547
548     if(NULL == (scan_info->sig_proxy =dbus_g_proxy_new_for_name(scan_info->bus,
549             BTSEARCH_SERVICE,
550             BTSEARCH_SIG_PATH,
551             BTSEARCH_SIG_INTERFACE)))
552     {
553         g_printerr("Failed to create D-Bus signal proxy for btsearch.");
554         return 2;
555     }
556
557     dbus_g_object_register_marshaller(
558             g_cclosure_user_marshal_VOID__STRING_STRING_POINTER_UCHAR_UINT,
559             G_TYPE_NONE,
560             G_TYPE_STRING,
561             G_TYPE_STRING,
562             DBUS_TYPE_G_UCHAR_ARRAY,
563             G_TYPE_UCHAR,
564             G_TYPE_UINT,
565             G_TYPE_INVALID);
566
567     dbus_g_proxy_add_signal(scan_info->sig_proxy,
568             BTSEARCH_DEV_FOUND_SIG,
569             G_TYPE_STRING,
570             G_TYPE_STRING,
571             DBUS_TYPE_G_UCHAR_ARRAY,
572             G_TYPE_UCHAR,
573             G_TYPE_UINT,
574             G_TYPE_INVALID);
575     dbus_g_proxy_connect_signal(scan_info->sig_proxy, BTSEARCH_DEV_FOUND_SIG,
576             G_CALLBACK(scan_cb_dev_found), scan_info, NULL);
577
578     dbus_g_proxy_add_signal(scan_info->sig_proxy,
579             BTSEARCH_SEARCH_COMPLETE_SIG,
580             G_TYPE_INVALID);
581     dbus_g_proxy_connect_signal(scan_info->sig_proxy,
582             BTSEARCH_SEARCH_COMPLETE_SIG,
583             G_CALLBACK(scan_cb_search_complete), scan_info, NULL);
584
585     error = NULL;
586     if(!dbus_g_proxy_call(scan_info->req_proxy, BTSEARCH_START_SEARCH_REQ,
587                 &error, G_TYPE_INVALID, G_TYPE_INVALID))
588     {
589         if(error->domain == DBUS_GERROR
590                 && error->code == DBUS_GERROR_REMOTE_EXCEPTION)
591         {
592             g_printerr("Caught remote method exception %s: %s",
593                     dbus_g_error_get_name(error),
594                     error->message);
595         }
596         else
597             g_printerr("Error: %s\n", error->message);
598         return 3;
599     }
600
601     vprintf("%s(): return\n", __PRETTY_FUNCTION__);
602     return 0;
603 }
604
605 /**
606  * Scan for all bluetooth devices.  This method can take a few seconds,
607  * during which the UI will freeze.
608  */
609 static gboolean
610 scan_bluetooth(GtkWidget *widget, ScanInfo *scan_info)
611 {
612     GError *error = NULL;
613     GtkWidget *dialog = NULL;
614     GtkWidget *lst_devices = NULL;
615     GtkTreeViewColumn *column = NULL;
616     GtkCellRenderer *renderer = NULL;
617     printf("%s()\n", __PRETTY_FUNCTION__);
618
619     dialog = gtk_dialog_new_with_buttons(_("Select Bluetooth Device"),
620             GTK_WINDOW(scan_info->settings_dialog), GTK_DIALOG_MODAL,
621             GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
622             GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
623             NULL);
624
625     scan_info->scan_dialog = dialog;
626
627     scan_info->store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
628
629     gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 300);
630
631     gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
632             lst_devices = gtk_tree_view_new_with_model(
633                 GTK_TREE_MODEL(scan_info->store)), TRUE, TRUE, 0);
634
635     g_object_unref(G_OBJECT(scan_info->store));
636
637     gtk_tree_selection_set_mode(
638             gtk_tree_view_get_selection(GTK_TREE_VIEW(lst_devices)),
639             GTK_SELECTION_SINGLE);
640     gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(lst_devices), TRUE);
641
642     renderer = gtk_cell_renderer_text_new();
643     column = gtk_tree_view_column_new_with_attributes(
644             _("MAC"), renderer, "text", 0, NULL);
645     gtk_tree_view_append_column(GTK_TREE_VIEW(lst_devices), column);
646
647     renderer = gtk_cell_renderer_text_new();
648     column = gtk_tree_view_column_new_with_attributes(
649             _("Description"), renderer, "text", 1, NULL);
650     gtk_tree_view_append_column(GTK_TREE_VIEW(lst_devices), column);
651
652     gtk_widget_show_all(dialog);
653
654     scan_info->banner = hildon_banner_show_animation(dialog, NULL,
655             _("Scanning for Bluetooth Devices"));
656
657     if(scan_start_search(scan_info))
658     {
659         gtk_widget_destroy(scan_info->banner);
660         popup_error(scan_info->settings_dialog,
661                 _("An error occurred while attempting to scan for "
662                 "bluetooth devices."));
663     }
664     else while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
665     {
666         GtkTreeIter iter;
667         if(gtk_tree_selection_get_selected(
668                     gtk_tree_view_get_selection(GTK_TREE_VIEW(lst_devices)),
669                     NULL, &iter))
670         {
671             gchar *mac;
672             gtk_tree_model_get(GTK_TREE_MODEL(scan_info->store),
673                     &iter, 0, &mac, -1);
674             gtk_entry_set_text(GTK_ENTRY(scan_info->txt_gps_bt_mac), mac);
675             break;
676         }
677         else
678             popup_error(dialog,
679                     _("Please select a bluetooth device from the list."));
680     }
681
682     gtk_widget_destroy(dialog);
683
684     /* Clean up D-Bus. */
685     if(scan_info->req_proxy)
686     {
687         dbus_g_proxy_call(scan_info->req_proxy, BTSEARCH_STOP_SEARCH_REQ,
688                     &error, G_TYPE_INVALID, G_TYPE_INVALID);
689         g_object_unref(scan_info->req_proxy);
690         scan_info->req_proxy = NULL;
691     }
692     if(scan_info->sig_proxy)
693     {
694         g_object_unref(scan_info->sig_proxy);
695         scan_info->sig_proxy = NULL;
696     }
697     if(scan_info->bus)
698     {
699         dbus_g_connection_unref(scan_info->bus);
700         scan_info->bus = NULL;
701     }
702
703     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
704     return TRUE;
705 }
706
707 static gboolean
708 settings_dialog_browse_forfile(GtkWidget *widget, BrowseInfo *browse_info)
709 {
710     GtkWidget *dialog;
711     printf("%s()\n", __PRETTY_FUNCTION__);
712
713     dialog = GTK_WIDGET(
714             hildon_file_chooser_dialog_new(GTK_WINDOW(browse_info->dialog),
715             GTK_FILE_CHOOSER_ACTION_OPEN));
716
717     gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(dialog), TRUE);
718     gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),
719             gtk_entry_get_text(GTK_ENTRY(browse_info->txt)));
720
721     if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(dialog)))
722     {
723         gchar *filename = gtk_file_chooser_get_filename(
724                 GTK_FILE_CHOOSER(dialog));
725         gtk_entry_set_text(GTK_ENTRY(browse_info->txt), filename);
726         g_free(filename);
727     }
728
729     gtk_widget_destroy(dialog);
730
731     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
732     return TRUE;
733 }
734
735 static gboolean
736 settings_dialog_hardkeys_reset(GtkWidget *widget, KeysDialogInfo *cdi)
737 {
738     GtkWidget *confirm;
739     printf("%s()\n", __PRETTY_FUNCTION__);
740
741     confirm = hildon_note_new_confirmation(GTK_WINDOW(_window),
742             _("Reset all hardware keys to their original defaults?"));
743
744     if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
745     {
746         gint i;
747         for(i = 0; i < CUSTOM_KEY_ENUM_COUNT; i++)
748             gtk_combo_box_set_active(GTK_COMBO_BOX(cdi->cmb[i]),
749                     CUSTOM_KEY_DEFAULT[i]);
750     }
751     gtk_widget_destroy(confirm);
752
753     vprintf("%s(): return\n", __PRETTY_FUNCTION__);
754     return TRUE;
755 }
756
757 static gboolean
758 settings_dialog_hardkeys(GtkWidget *widget, GtkWidget *parent)
759 {
760     gint i;
761     static GtkWidget *dialog = NULL;
762     static GtkWidget *table = NULL;
763     static GtkWidget *label = NULL;
764     static KeysDialogInfo bdi;
765     static GtkWidget *btn_defaults = NULL;
766     printf("%s()\n", __PRETTY_FUNCTION__);
767
768     if(dialog == NULL)
769     {
770         dialog = gtk_dialog_new_with_buttons(_("Hardware Keys"),
771                 GTK_WINDOW(parent), GTK_DIALOG_MODAL,
772                 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
773                 NULL);
774
775         gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
776                 btn_defaults = gtk_button_new_with_label(_("Reset...")));
777         g_signal_connect(G_OBJECT(btn_defaults), "clicked",
778                           G_CALLBACK(settings_dialog_hardkeys_reset), &bdi);
779
780         gtk_dialog_add_button(GTK_DIALOG(dialog),
781                 GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
782
783         gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
784                 table = gtk_table_new(2, 9, FALSE), TRUE, TRUE, 0);
785         for(i = 0; i < CUSTOM_KEY_ENUM_COUNT; i++)
786         {
787             gint j;
788             gtk_table_attach(GTK_TABLE(table),
789                     label = gtk_label_new(""),
790                     0, 1, i, i + 1, GTK_FILL, 0, 2, 1);
791             gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
792             gtk_label_set_markup(GTK_LABEL(label), CUSTOM_KEY_ICON[i]);
793             gtk_table_attach(GTK_TABLE(table),
794                     bdi.cmb[i] = gtk_combo_box_new_text(),
795                     1, 2, i, i + 1, GTK_FILL, 0, 2, 1);
796             for(j = 0; j < CUSTOM_ACTION_ENUM_COUNT; j++)
797                 gtk_combo_box_append_text(GTK_COMBO_BOX(bdi.cmb[i]),
798                         CUSTOM_ACTION_ENUM_TEXT[j]);
799         }
800     }
801
802     /* Initialize contents of the combo boxes. */
803     for(i = 0; i < CUSTOM_KEY_ENUM_COUNT; i++)
804         gtk_combo_box_set_active(GTK_COMBO_BOX(bdi.cmb[i]), _action[i]);
805
806     gtk_widget_show_all(dialog);
807
808 OUTER_WHILE:
809     while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
810     {
811         /* Check for duplicates. */
812         for(i = 0; i < CUSTOM_KEY_ENUM_COUNT; i++)
813         {
814             gint j;
815             for(j = i + 1; j < CUSTOM_KEY_ENUM_COUNT; j++)
816             {
817                 if(gtk_combo_box_get_active(GTK_COMBO_BOX(bdi.cmb[i]))
818                         == gtk_combo_box_get_active(GTK_COMBO_BOX(bdi.cmb[j])))
819                 {
820                     GtkWidget *confirm;
821                     gchar *buffer = g_strdup_printf("%s:\n    %s\n%s",
822                         _("The following action is mapped to multiple keys"),
823                         CUSTOM_ACTION_ENUM_TEXT[gtk_combo_box_get_active(
824                             GTK_COMBO_BOX(bdi.cmb[i]))],
825                         _("Continue?"));
826                     confirm = hildon_note_new_confirmation(GTK_WINDOW(_window),
827                             buffer);
828
829                     if(GTK_RESPONSE_OK != gtk_dialog_run(GTK_DIALOG(confirm)))
830                     {
831                         gtk_widget_destroy(confirm);
832                         goto OUTER_WHILE;
833                     }
834                     gtk_widget_destroy(confirm);
835                 }
836             }
837         }
838         for(i = 0; i < CUSTOM_KEY_ENUM_COUNT; i++)
839             _action[i] = gtk_combo_box_get_active(GTK_COMBO_BOX(bdi.cmb[i]));
840         break;
841     }
842
843     gtk_widget_hide(dialog);
844
845     vprintf("%s(): return\n", __PRETTY_FUNCTION__);
846     return TRUE;
847 }
848
849 static gboolean
850 settings_dialog_colors_reset(GtkWidget *widget, ColorsDialogInfo *cdi)
851 {
852     GtkWidget *confirm;
853     printf("%s()\n", __PRETTY_FUNCTION__);
854
855     confirm = hildon_note_new_confirmation(GTK_WINDOW(_window),
856             _("Reset all colors to their original defaults?"));
857
858     if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
859     {
860         gint i;
861         for(i = 0; i < COLORABLE_ENUM_COUNT; i++)
862         {
863             hildon_color_button_set_color(
864                     HILDON_COLOR_BUTTON(cdi->col[i]),
865                     &COLORABLE_DEFAULT[i]);
866         }
867     }
868     gtk_widget_destroy(confirm);
869
870     vprintf("%s(): return\n", __PRETTY_FUNCTION__);
871     return TRUE;
872 }
873
874 static gboolean
875 settings_dialog_colors(GtkWidget *widget, GtkWidget *parent)
876 {
877     static GtkWidget *dialog = NULL;
878     static GtkWidget *table = NULL;
879     static GtkWidget *label = NULL;
880     static GtkWidget *btn_defaults = NULL;
881     static ColorsDialogInfo cdi;
882     printf("%s()\n", __PRETTY_FUNCTION__);
883
884     if(dialog == NULL)
885     {
886         dialog = gtk_dialog_new_with_buttons(_("Colors"),
887                 GTK_WINDOW(parent), GTK_DIALOG_MODAL,
888                 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
889                 NULL);
890
891         gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
892                 btn_defaults = gtk_button_new_with_label(_("Reset...")));
893         g_signal_connect(G_OBJECT(btn_defaults), "clicked",
894                           G_CALLBACK(settings_dialog_colors_reset), &cdi);
895
896         gtk_dialog_add_button(GTK_DIALOG(dialog),
897                 GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
898
899         gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
900                 table = gtk_table_new(4, 3, FALSE), TRUE, TRUE, 0);
901
902         /* GPS. */
903         gtk_table_attach(GTK_TABLE(table),
904                 label = gtk_label_new(_("GPS")),
905                 0, 1, 0, 1, GTK_FILL, 0, 2, 4);
906         gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
907         gtk_table_attach(GTK_TABLE(table),
908                 cdi.col[COLORABLE_MARK] = hildon_color_button_new(),
909                 1, 2, 0, 1, 0, 0, 2, 4);
910         gtk_table_attach(GTK_TABLE(table),
911                 cdi.col[COLORABLE_MARK_VELOCITY] = hildon_color_button_new(),
912                 2, 3, 0, 1, 0, 0, 2, 4);
913         gtk_table_attach(GTK_TABLE(table),
914                 cdi.col[COLORABLE_MARK_OLD] = hildon_color_button_new(),
915                 3, 4, 0, 1, 0, 0, 2, 4);
916
917         /* Track. */
918         gtk_table_attach(GTK_TABLE(table),
919                 label = gtk_label_new(_("Track")),
920                 0, 1, 1, 2, GTK_FILL, 0, 2, 4);
921         gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
922         gtk_table_attach(GTK_TABLE(table),
923                 cdi.col[COLORABLE_TRACK] = hildon_color_button_new(),
924                 1, 2, 1, 2, 0, 0, 2, 4);
925         gtk_table_attach(GTK_TABLE(table),
926                 cdi.col[COLORABLE_TRACK_MARK] = hildon_color_button_new(),
927                 2, 3, 1, 2, 0, 0, 2, 4);
928         gtk_table_attach(GTK_TABLE(table),
929                 cdi.col[COLORABLE_TRACK_BREAK] = hildon_color_button_new(),
930                 3, 4, 1, 2, 0, 0, 2, 4);
931
932         /* Route. */
933         gtk_table_attach(GTK_TABLE(table),
934                 label = gtk_label_new(_("Route")),
935                 0, 1, 2, 3, GTK_FILL, 0, 2, 4);
936         gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
937         gtk_table_attach(GTK_TABLE(table),
938                 cdi.col[COLORABLE_ROUTE] = hildon_color_button_new(),
939                 1, 2, 2, 3, 0, 0, 2, 4);
940         gtk_table_attach(GTK_TABLE(table),
941                 cdi.col[COLORABLE_ROUTE_WAY] = hildon_color_button_new(),
942                 2, 3, 2, 3, 0, 0, 2, 4);
943         gtk_table_attach(GTK_TABLE(table),
944                 cdi.col[COLORABLE_ROUTE_BREAK] = hildon_color_button_new(),
945                 3, 4, 2, 3, 0, 0, 2, 4);
946
947         /* POI. */
948         gtk_table_attach(GTK_TABLE(table),
949                 label = gtk_label_new(_("POI")),
950                 0, 1, 3, 4, GTK_FILL, 0, 2, 4);
951         gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
952         gtk_table_attach(GTK_TABLE(table),
953                 cdi.col[COLORABLE_POI] = hildon_color_button_new(),
954                 1, 2, 3, 4, 0, 0, 2, 4);
955     }
956
957     /* Initialize GPS. */
958     hildon_color_button_set_color(
959             HILDON_COLOR_BUTTON(cdi.col[COLORABLE_MARK]),
960             &_color[COLORABLE_MARK]);
961     hildon_color_button_set_color(
962             HILDON_COLOR_BUTTON(cdi.col[COLORABLE_MARK_VELOCITY]),
963             &_color[COLORABLE_MARK_VELOCITY]);
964     hildon_color_button_set_color(
965             HILDON_COLOR_BUTTON(cdi.col[COLORABLE_MARK_OLD]),
966             &_color[COLORABLE_MARK_OLD]);
967
968     /* Initialize Track. */
969     hildon_color_button_set_color(
970             HILDON_COLOR_BUTTON(cdi.col[COLORABLE_TRACK]),
971             &_color[COLORABLE_TRACK]);
972     hildon_color_button_set_color(
973             HILDON_COLOR_BUTTON(cdi.col[COLORABLE_TRACK_MARK]),
974             &_color[COLORABLE_TRACK_MARK]);
975     hildon_color_button_set_color(
976             HILDON_COLOR_BUTTON(cdi.col[COLORABLE_TRACK_BREAK]),
977             &_color[COLORABLE_TRACK_BREAK]);
978
979     /* Initialize Route. */
980     hildon_color_button_set_color(
981             HILDON_COLOR_BUTTON(cdi.col[COLORABLE_ROUTE]),
982             &_color[COLORABLE_ROUTE]);
983     hildon_color_button_set_color(
984             HILDON_COLOR_BUTTON(cdi.col[COLORABLE_ROUTE_WAY]),
985             &_color[COLORABLE_ROUTE_WAY]);
986     hildon_color_button_set_color(
987             HILDON_COLOR_BUTTON(cdi.col[COLORABLE_ROUTE_BREAK]),
988             &_color[COLORABLE_ROUTE_BREAK]);
989
990     /* Initialize POI. */
991     hildon_color_button_set_color(
992             HILDON_COLOR_BUTTON(cdi.col[COLORABLE_POI]),
993             &_color[COLORABLE_POI]);
994
995     gtk_widget_show_all(dialog);
996
997     while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
998     {
999 #ifndef LEGACY
1000         hildon_color_button_get_color(
1001                 HILDON_COLOR_BUTTON(cdi.col[COLORABLE_MARK]), 
1002                 &_color[COLORABLE_MARK]);
1003
1004         hildon_color_button_get_color(
1005                 HILDON_COLOR_BUTTON(cdi.col[COLORABLE_MARK_VELOCITY]), 
1006                 &_color[COLORABLE_MARK_VELOCITY]);
1007
1008         hildon_color_button_get_color(
1009                 HILDON_COLOR_BUTTON(cdi.col[COLORABLE_MARK_OLD]),
1010                 &_color[COLORABLE_MARK_OLD]);
1011
1012         hildon_color_button_get_color(
1013                 HILDON_COLOR_BUTTON(cdi.col[COLORABLE_TRACK]),
1014                 &_color[COLORABLE_TRACK]);
1015
1016         hildon_color_button_get_color(
1017                 HILDON_COLOR_BUTTON(cdi.col[COLORABLE_TRACK_MARK]),
1018                 &_color[COLORABLE_TRACK_MARK]);
1019
1020         hildon_color_button_get_color(
1021                 HILDON_COLOR_BUTTON(cdi.col[COLORABLE_TRACK_BREAK]),
1022                 &_color[COLORABLE_TRACK_BREAK]);
1023
1024         hildon_color_button_get_color(
1025                 HILDON_COLOR_BUTTON(cdi.col[COLORABLE_ROUTE]),
1026                 &_color[COLORABLE_ROUTE]);
1027
1028         hildon_color_button_get_color(
1029                 HILDON_COLOR_BUTTON(cdi.col[COLORABLE_ROUTE_WAY]),
1030                 &_color[COLORABLE_ROUTE_WAY]);
1031
1032         hildon_color_button_get_color(
1033                 HILDON_COLOR_BUTTON(cdi.col[COLORABLE_ROUTE_BREAK]),
1034                 &_color[COLORABLE_ROUTE_BREAK]);
1035
1036         hildon_color_button_get_color(
1037                 HILDON_COLOR_BUTTON(cdi.col[COLORABLE_POI]),
1038                 &_color[COLORABLE_POI]);
1039 #else
1040         GdkColor *color;
1041
1042         color = hildon_color_button_get_color(
1043                 HILDON_COLOR_BUTTON(cdi.col[COLORABLE_MARK]));
1044         _color[COLORABLE_MARK] = *color;
1045
1046         color = hildon_color_button_get_color(
1047                 HILDON_COLOR_BUTTON(cdi.col[COLORABLE_MARK_VELOCITY]));
1048         _color[COLORABLE_MARK_VELOCITY] = *color;
1049
1050         color = hildon_color_button_get_color(
1051                 HILDON_COLOR_BUTTON(cdi.col[COLORABLE_MARK_OLD]));
1052         _color[COLORABLE_MARK_OLD] = *color;
1053
1054         color = hildon_color_button_get_color(
1055                 HILDON_COLOR_BUTTON(cdi.col[COLORABLE_TRACK]));
1056         _color[COLORABLE_TRACK] = *color;
1057
1058         color = hildon_color_button_get_color(
1059                 HILDON_COLOR_BUTTON(cdi.col[COLORABLE_TRACK_MARK]));
1060         _color[COLORABLE_TRACK_MARK] = *color;
1061
1062         color = hildon_color_button_get_color(
1063                 HILDON_COLOR_BUTTON(cdi.col[COLORABLE_TRACK_BREAK]));
1064         _color[COLORABLE_TRACK_BREAK] = *color;
1065
1066         color = hildon_color_button_get_color(
1067                 HILDON_COLOR_BUTTON(cdi.col[COLORABLE_ROUTE]));
1068         _color[COLORABLE_ROUTE] = *color;
1069
1070         color = hildon_color_button_get_color(
1071                 HILDON_COLOR_BUTTON(cdi.col[COLORABLE_ROUTE_WAY]));
1072         _color[COLORABLE_ROUTE_WAY] = *color;
1073
1074         color = hildon_color_button_get_color(
1075                 HILDON_COLOR_BUTTON(cdi.col[COLORABLE_ROUTE_BREAK]));
1076         _color[COLORABLE_ROUTE_BREAK] = *color;
1077
1078         color = hildon_color_button_get_color(
1079                 HILDON_COLOR_BUTTON(cdi.col[COLORABLE_POI]));
1080         _color[COLORABLE_POI] = *color;
1081
1082 #endif
1083         
1084         update_gcs();
1085         break;
1086     }
1087
1088     map_force_redraw();
1089
1090     gtk_widget_hide(dialog);
1091
1092     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
1093     return TRUE;
1094 }
1095
1096 /**
1097  * Bring up the Settings dialog.  Return TRUE if and only if the recever
1098  * information has changed (MAC or channel).
1099  */
1100 gboolean
1101 settings_dialog()
1102 {
1103     static GtkWidget *dialog = NULL;
1104     static GtkWidget *notebook = NULL;
1105     static GtkWidget *table = NULL;
1106     static GtkWidget *hbox = NULL;
1107     static GtkWidget *label = NULL;
1108     static GtkWidget *rad_gps_bt = NULL;
1109     static GtkWidget *rad_gps_gpsd = NULL;
1110     static GtkWidget *rad_gps_file = NULL;
1111     static GtkWidget *txt_gps_bt_mac = NULL;
1112     static GtkWidget *txt_gps_gpsd_host = NULL;
1113     static GtkWidget *num_gps_gpsd_port = NULL;
1114     static GtkWidget *txt_gps_file_path = NULL;
1115     static GtkWidget *num_center_ratio = NULL;
1116     static GtkWidget *num_lead_ratio = NULL;
1117     static GtkWidget *chk_lead_is_fixed = NULL;
1118     static GtkWidget *num_rotate_sens = NULL;
1119     static GtkWidget *cmb_rotate_dir = NULL;
1120     static GtkWidget *num_ac_min_speed = NULL;
1121     static GtkWidget *num_announce_notice = NULL;
1122     static GtkWidget *chk_enable_voice = NULL;
1123     static GtkWidget *chk_enable_announce = NULL;
1124     static GtkWidget *num_draw_width = NULL;
1125     static GtkWidget *cmb_units = NULL;
1126     static GtkWidget *cmb_degformat = NULL;
1127     static GtkWidget *btn_scan = NULL;
1128     static GtkWidget *btn_browse_gps = NULL;
1129     static GtkWidget *btn_buttons = NULL;
1130     static GtkWidget *btn_colors = NULL;
1131
1132     static GtkWidget *txt_poi_db = NULL;
1133     static GtkWidget *btn_browse_poi = NULL;
1134     static GtkWidget *num_poi_zoom = NULL;
1135     static GtkWidget *num_auto_download_precache = NULL;
1136     static GtkWidget *chk_speed_limit_on = NULL;
1137     static GtkWidget *num_speed = NULL;
1138     static GtkWidget *cmb_speed_location = NULL;
1139     static GtkWidget *cmb_unblank_option = NULL;
1140     static GtkWidget *cmb_info_font_size = NULL;
1141
1142     static BrowseInfo poi_browse_info = {0, 0};
1143     static BrowseInfo gps_file_browse_info = {0, 0};
1144     static ScanInfo scan_info = {0};
1145     gboolean rcvr_changed = FALSE;
1146     gint i;
1147     printf("%s()\n", __PRETTY_FUNCTION__);
1148
1149     if(dialog == NULL)
1150     {
1151         dialog = gtk_dialog_new_with_buttons(_("Settings"),
1152                 GTK_WINDOW(_window), GTK_DIALOG_MODAL,
1153                 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
1154                 NULL);
1155
1156         /* Enable the help button. */
1157 #ifndef LEGACY
1158         hildon_help_dialog_help_enable(
1159 #else
1160         ossohelp_dialog_help_enable(
1161 #endif 
1162                 GTK_DIALOG(dialog), HELP_ID_SETTINGS, _osso);
1163
1164         gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
1165                btn_buttons = gtk_button_new_with_label(_("Hardware Keys...")));
1166
1167         gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
1168                 btn_colors = gtk_button_new_with_label(_("Colors...")));
1169
1170         gtk_dialog_add_button(GTK_DIALOG(dialog),
1171                 GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
1172
1173         gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
1174                 notebook = gtk_notebook_new(), TRUE, TRUE, 0);
1175
1176         /* Receiver page. */
1177         gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
1178                 table = gtk_table_new(3, 4, FALSE),
1179                 label = gtk_label_new(_("GPS")));
1180
1181         /* Receiver MAC Address. */
1182         gtk_table_attach(GTK_TABLE(table),
1183                 rad_gps_bt = gtk_radio_button_new_with_label(
1184                     NULL, _("Bluetooth")),
1185                 0, 1, 0, 1, GTK_FILL, 0, 2, 4);
1186         gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1187         gtk_table_attach(GTK_TABLE(table),
1188                 hbox = gtk_hbox_new(FALSE, 4),
1189                 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
1190         gtk_box_pack_start(GTK_BOX(hbox),
1191                 txt_gps_bt_mac = gtk_entry_new(),
1192                 TRUE, TRUE, 0);
1193 #ifndef LEGACY
1194         g_object_set(G_OBJECT(txt_gps_bt_mac), "hildon-input-mode",
1195                 HILDON_GTK_INPUT_MODE_FULL, NULL);
1196 #else
1197         g_object_set(G_OBJECT(txt_gps_bt_mac), HILDON_AUTOCAP, FALSE, NULL);
1198 #endif
1199         gtk_box_pack_start(GTK_BOX(hbox),
1200                 btn_scan = gtk_button_new_with_label(_("Scan...")),
1201                 FALSE, FALSE, 0);
1202
1203         /* File Path (RFComm). */
1204         gtk_table_attach(GTK_TABLE(table),
1205                 rad_gps_file = gtk_radio_button_new_with_label_from_widget(
1206                     GTK_RADIO_BUTTON(rad_gps_bt), _("File Path")),
1207                 0, 1, 1, 2, GTK_FILL, 0, 2, 4);
1208         gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1209         gtk_table_attach(GTK_TABLE(table),
1210                 hbox = gtk_hbox_new(FALSE, 4),
1211                 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
1212         gtk_box_pack_start(GTK_BOX(hbox),
1213                 txt_gps_file_path = gtk_entry_new(),
1214                 TRUE, TRUE, 0);
1215 #ifndef LEGACY
1216         g_object_set(G_OBJECT(txt_gps_file_path), "hildon-input-mode",
1217                 HILDON_GTK_INPUT_MODE_FULL, NULL);
1218 #else
1219         g_object_set(G_OBJECT(txt_gps_file_path), HILDON_AUTOCAP, FALSE, NULL);
1220 #endif
1221         gtk_box_pack_start(GTK_BOX(hbox),
1222                 btn_browse_gps = gtk_button_new_with_label(_("Browse...")),
1223                 FALSE, FALSE, 0);
1224
1225         /* GPSD Hostname and Port. */
1226         gtk_table_attach(GTK_TABLE(table),
1227                 rad_gps_gpsd = gtk_radio_button_new_with_label_from_widget(
1228                     GTK_RADIO_BUTTON(rad_gps_bt), _("GPSD Host")),
1229                 0, 1, 2, 3, GTK_FILL, 0, 2, 4);
1230         gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1231         gtk_table_attach(GTK_TABLE(table),
1232                 hbox = gtk_hbox_new(FALSE, 4),
1233                 1, 2, 2, 3, GTK_EXPAND | GTK_FILL, 0, 2, 4);
1234         gtk_box_pack_start(GTK_BOX(hbox),
1235                 txt_gps_gpsd_host = gtk_entry_new(),
1236                 TRUE, TRUE, 0);
1237 #ifndef LEGACY
1238         g_object_set(G_OBJECT(txt_gps_gpsd_host), "hildon-input-mode",
1239                 HILDON_GTK_INPUT_MODE_FULL, NULL);
1240 #else
1241         g_object_set(G_OBJECT(txt_gps_gpsd_host), HILDON_AUTOCAP, FALSE, NULL);
1242 #endif
1243         gtk_box_pack_start(GTK_BOX(hbox),
1244                 label = gtk_label_new(_("Port")),
1245                 FALSE, FALSE, 0);
1246         gtk_box_pack_start(GTK_BOX(hbox),
1247                 num_gps_gpsd_port = hildon_number_editor_new(1, 65535),
1248                 FALSE, FALSE, 0);
1249
1250
1251         /* Auto-Center page. */
1252         gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
1253                 table = gtk_table_new(3, 3, FALSE),
1254                 label = gtk_label_new(_("Auto-Center")));
1255
1256         /* Lead Amount. */
1257         gtk_table_attach(GTK_TABLE(table),
1258                 label = gtk_label_new(_("Lead Amount")),
1259                 0, 1, 0, 1, GTK_FILL, 0, 2, 4);
1260         gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1261         gtk_table_attach(GTK_TABLE(table),
1262                 label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
1263                 1, 2, 0, 1, GTK_FILL, 0, 2, 4);
1264         gtk_container_add(GTK_CONTAINER(label),
1265                 num_lead_ratio = hildon_controlbar_new());
1266         hildon_controlbar_set_range(HILDON_CONTROLBAR(num_lead_ratio), 1, 10);
1267         force_min_visible_bars(HILDON_CONTROLBAR(num_lead_ratio), 1);
1268
1269         gtk_table_attach(GTK_TABLE(table),
1270                 label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
1271                 2, 3, 0, 1, GTK_FILL, 0, 2, 4);
1272         gtk_container_add(GTK_CONTAINER(label),
1273             chk_lead_is_fixed = gtk_check_button_new_with_label(_("Fixed")));
1274
1275         /* Auto-Center Pan Sensitivity. */
1276         gtk_table_attach(GTK_TABLE(table),
1277                 label = gtk_label_new(_("Pan Sensitivity")),
1278                 0, 1, 1, 2, GTK_FILL, 0, 2, 4);
1279         gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1280         gtk_table_attach(GTK_TABLE(table),
1281                 label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
1282                 1, 2, 1, 2, GTK_FILL, 0, 2, 4);
1283         gtk_container_add(GTK_CONTAINER(label),
1284                 num_center_ratio = hildon_controlbar_new());
1285         hildon_controlbar_set_range(HILDON_CONTROLBAR(num_center_ratio), 1,10);
1286         force_min_visible_bars(HILDON_CONTROLBAR(num_center_ratio), 1);
1287
1288         gtk_table_attach(GTK_TABLE(table),
1289                 hbox = gtk_hbox_new(FALSE, 4),
1290                 2, 3, 1, 2, GTK_FILL, 0, 2, 4);
1291         gtk_box_pack_start(GTK_BOX(hbox),
1292                 label = gtk_label_new(_("Min. Speed")),
1293                 TRUE, TRUE, 4);
1294         gtk_box_pack_start(GTK_BOX(hbox),
1295                 num_ac_min_speed = hildon_number_editor_new(0, 99),
1296                 TRUE, TRUE, 4);
1297
1298         /* Auto-Center Rotate Sensitivity. */
1299         gtk_table_attach(GTK_TABLE(table),
1300                 label = gtk_label_new(_("Rotate Sensit.")),
1301                 0, 1, 2, 3, GTK_FILL, 0, 2, 4);
1302         gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1303         gtk_table_attach(GTK_TABLE(table),
1304                 num_rotate_sens = hildon_controlbar_new(),
1305                 1, 2, 2, 3, GTK_FILL, 0, 2, 4);
1306         hildon_controlbar_set_range(HILDON_CONTROLBAR(num_rotate_sens), 1,10);
1307         force_min_visible_bars(HILDON_CONTROLBAR(num_rotate_sens), 1);
1308
1309         gtk_table_attach(GTK_TABLE(table),
1310                 hbox = gtk_hbox_new(FALSE, 4),
1311                 2, 3, 2, 3, GTK_FILL, 0, 2, 4);
1312         gtk_box_pack_start(GTK_BOX(hbox),
1313                 label = gtk_label_new(_("Points")),
1314                 TRUE, TRUE, 4);
1315         gtk_box_pack_start(GTK_BOX(hbox),
1316                 cmb_rotate_dir = gtk_combo_box_new_text(),
1317                 TRUE, TRUE, 4);
1318         for(i = 0; i < ROTATE_DIR_ENUM_COUNT; i++)
1319             gtk_combo_box_append_text(GTK_COMBO_BOX(cmb_rotate_dir),
1320                     ROTATE_DIR_ENUM_TEXT[i]);
1321
1322         /* Announcement. */
1323         gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
1324                 table = gtk_table_new(2, 3, FALSE),
1325                 label = gtk_label_new(_("Announce")));
1326
1327         /* Enable Waypoint Announcements. */
1328         gtk_table_attach(GTK_TABLE(table),
1329                 chk_enable_announce = gtk_check_button_new_with_label(
1330                     _("Enable Waypoint Announcements")),
1331                 0, 2, 0, 1, GTK_FILL, 0, 2, 4);
1332         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chk_enable_announce),
1333                 _enable_announce);
1334
1335         /* Announcement Advance Notice. */
1336         gtk_table_attach(GTK_TABLE(table),
1337                 label = gtk_label_new(_("Advance Notice")),
1338                 0, 1, 1, 2, GTK_FILL, 0, 2, 4);
1339         gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1340         gtk_table_attach(GTK_TABLE(table),
1341                 num_announce_notice = hildon_controlbar_new(),
1342                 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
1343         hildon_controlbar_set_range(
1344                 HILDON_CONTROLBAR(num_announce_notice), 1, 20);
1345         force_min_visible_bars(HILDON_CONTROLBAR(num_announce_notice), 1);
1346
1347         /* Enable Voice. */
1348         gtk_table_attach(GTK_TABLE(table),
1349                 chk_enable_voice = gtk_check_button_new_with_label(
1350                     _("Enable Voice Synthesis (requires flite)")),
1351                 0, 2, 2, 3, GTK_FILL, 0, 2, 4);
1352         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chk_enable_voice),
1353                 _enable_voice);
1354
1355         /* Misc. page. */
1356         gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
1357                 table = gtk_table_new(3, 5, FALSE),
1358                 label = gtk_label_new(_("Misc.")));
1359
1360         /* Line Width. */
1361         gtk_table_attach(GTK_TABLE(table),
1362                 label = gtk_label_new(_("Line Width")),
1363                 0, 1, 0, 1, GTK_FILL, 0, 2, 4);
1364         gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1365         gtk_table_attach(GTK_TABLE(table),
1366                 num_draw_width = hildon_controlbar_new(),
1367                 1, 5, 0, 1, GTK_FILL, 0, 2, 4);
1368         hildon_controlbar_set_range(HILDON_CONTROLBAR(num_draw_width), 1, 20);
1369         force_min_visible_bars(HILDON_CONTROLBAR(num_draw_width), 1);
1370
1371         /* Unblank Screen */
1372         gtk_table_attach(GTK_TABLE(table),
1373                 label = gtk_label_new(_("Unblank Screen")),
1374                 0, 1, 1, 2, GTK_FILL, 0, 2, 4);
1375         gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1376         gtk_table_attach(GTK_TABLE(table),
1377                 cmb_unblank_option = gtk_combo_box_new_text(),
1378                 1, 5, 1, 2, GTK_FILL, 0, 2, 4);
1379         for(i = 0; i < UNBLANK_ENUM_COUNT; i++)
1380             gtk_combo_box_append_text(GTK_COMBO_BOX(cmb_unblank_option),
1381                     UNBLANK_ENUM_TEXT[i]);
1382
1383         /* Information Font Size. */
1384         gtk_table_attach(GTK_TABLE(table),
1385                 label = gtk_label_new(_("Info Font Size")),
1386                 0, 1, 2, 3, GTK_FILL, 0, 2, 4);
1387         gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1388         gtk_table_attach(GTK_TABLE(table),
1389                 cmb_info_font_size = gtk_combo_box_new_text(),
1390                 1, 2, 2, 3, GTK_FILL, 0, 2, 4);
1391         for(i = 0; i < INFO_FONT_ENUM_COUNT; i++)
1392             gtk_combo_box_append_text(GTK_COMBO_BOX(cmb_info_font_size),
1393                     INFO_FONT_ENUM_TEXT[i]);
1394
1395         gtk_table_attach(GTK_TABLE(table),
1396                 gtk_vseparator_new(),
1397                 2, 3, 2, 3, GTK_EXPAND | GTK_FILL, GTK_FILL, 2,4);
1398
1399
1400         /* Units. */
1401         gtk_table_attach(GTK_TABLE(table),
1402                 label = gtk_label_new(_("Units")),
1403                 3, 4, 2, 3, GTK_FILL, 0, 2, 4);
1404         gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1405         gtk_table_attach(GTK_TABLE(table),
1406                 cmb_units = gtk_combo_box_new_text(),
1407                 4, 5, 2, 3, GTK_FILL, 0, 2, 4);
1408         for(i = 0; i < UNITS_ENUM_COUNT; i++)
1409             gtk_combo_box_append_text(
1410                     GTK_COMBO_BOX(cmb_units), UNITS_ENUM_TEXT[i]);
1411
1412         /* Misc. 2 page. */
1413         gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
1414                 table = gtk_table_new(3, 4, FALSE),
1415                 label = gtk_label_new(_("Misc. 2")));
1416
1417         /* Degrees format */
1418         gtk_table_attach(GTK_TABLE(table),
1419                 label = gtk_label_new(_("Degrees Format")),
1420                 0, 1, 0, 1, GTK_FILL, 0, 2, 4);
1421         gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1422         gtk_table_attach(GTK_TABLE(table),
1423                 label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
1424                 1, 2, 0, 1, GTK_FILL, 0, 2, 4);
1425         gtk_container_add(GTK_CONTAINER(label),
1426                 cmb_degformat = gtk_combo_box_new_text());
1427         for(i = 0; i < DEG_FORMAT_ENUM_COUNT; i++)
1428             gtk_combo_box_append_text(GTK_COMBO_BOX(cmb_degformat),
1429                 DEG_FORMAT_ENUM_TEXT[i]);
1430
1431         gtk_table_attach(GTK_TABLE(table),
1432                 label = gtk_label_new(_("Auto-Download Pre-cache")),
1433                 0, 1, 1, 2, GTK_FILL, 0, 2, 4);
1434         gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1435         gtk_table_attach(GTK_TABLE(table),
1436                 num_auto_download_precache = hildon_controlbar_new(),
1437                 1, 2, 1, 2, GTK_FILL, 0, 2, 4);
1438         hildon_controlbar_set_range(
1439                 HILDON_CONTROLBAR(num_auto_download_precache), 1, 5);
1440         force_min_visible_bars(
1441                 HILDON_CONTROLBAR(num_auto_download_precache), 1);
1442
1443         /* Speed warner. */
1444         gtk_table_attach(GTK_TABLE(table),
1445                 hbox = gtk_hbox_new(FALSE, 4),
1446                 0, 4, 2, 3, GTK_FILL, 0, 2, 4);
1447
1448         gtk_box_pack_start(GTK_BOX(hbox),
1449                 chk_speed_limit_on = gtk_check_button_new_with_label(
1450                     _("Speed Limit")),
1451                 FALSE, FALSE, 0);
1452
1453         gtk_box_pack_start(GTK_BOX(hbox),
1454                 label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
1455                 FALSE, FALSE, 0);
1456         gtk_container_add(GTK_CONTAINER(label),
1457                 num_speed = hildon_number_editor_new(0, 999));
1458
1459         gtk_box_pack_start(GTK_BOX(hbox),
1460                 label = gtk_label_new(_("Location")),
1461                 FALSE, FALSE, 0);
1462         gtk_box_pack_start(GTK_BOX(hbox),
1463                 label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
1464                 FALSE, FALSE, 0);
1465         gtk_container_add(GTK_CONTAINER(label),
1466                 cmb_speed_location = gtk_combo_box_new_text());
1467         for(i = 0; i < SPEED_LOCATION_ENUM_COUNT; i++)
1468             gtk_combo_box_append_text(GTK_COMBO_BOX(cmb_speed_location),
1469                     SPEED_LOCATION_ENUM_TEXT[i]);
1470
1471
1472         /* POI page */
1473         gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
1474                 table = gtk_table_new(2, 3, FALSE),
1475                 label = gtk_label_new(_("POI")));
1476
1477         /* POI database. */
1478         gtk_table_attach(GTK_TABLE(table),
1479                 label = gtk_label_new(_("POI database")),
1480                 0, 1, 1, 2, GTK_FILL, 0, 2, 4);
1481         gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1482         gtk_table_attach(GTK_TABLE(table),
1483                 hbox = gtk_hbox_new(FALSE, 4),
1484                 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
1485         gtk_box_pack_start(GTK_BOX(hbox),
1486                 txt_poi_db = gtk_entry_new(),
1487                 TRUE, TRUE, 0);
1488 #ifndef LEGACY
1489         g_object_set(G_OBJECT(txt_poi_db), "hildon-input-mode",
1490                 HILDON_GTK_INPUT_MODE_FULL, NULL);
1491 #else
1492         g_object_set(G_OBJECT(txt_poi_db), HILDON_AUTOCAP, FALSE, NULL);
1493 #endif
1494         gtk_box_pack_start(GTK_BOX(hbox),
1495                 btn_browse_poi = gtk_button_new_with_label(_("Browse...")),
1496                 FALSE, FALSE, 0);
1497
1498         /* Show POI below zoom. */
1499         gtk_table_attach(GTK_TABLE(table),
1500                 label = gtk_label_new(_("Show POI below zoom")),
1501                 0, 1, 2, 3, GTK_FILL, 0, 2, 4);
1502         gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
1503         gtk_table_attach(GTK_TABLE(table),
1504                 label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
1505                 1, 2, 2, 3, GTK_FILL, 0, 2, 4);
1506         gtk_container_add(GTK_CONTAINER(label),
1507                 num_poi_zoom = hildon_number_editor_new(0, MAX_ZOOM));
1508
1509         /* Connect signals. */
1510         memset(&scan_info, 0, sizeof(scan_info));
1511         scan_info.settings_dialog = dialog;
1512         scan_info.txt_gps_bt_mac = txt_gps_bt_mac;
1513         g_signal_connect(G_OBJECT(btn_scan), "clicked",
1514                          G_CALLBACK(scan_bluetooth), &scan_info);
1515         g_signal_connect(G_OBJECT(btn_buttons), "clicked",
1516                          G_CALLBACK(settings_dialog_hardkeys), dialog);
1517         g_signal_connect(G_OBJECT(btn_colors), "clicked",
1518                          G_CALLBACK(settings_dialog_colors), dialog);
1519
1520         poi_browse_info.dialog = dialog;
1521         poi_browse_info.txt = txt_poi_db;
1522         g_signal_connect(G_OBJECT(btn_browse_poi), "clicked",
1523                 G_CALLBACK(settings_dialog_browse_forfile), &poi_browse_info);
1524
1525         gps_file_browse_info.dialog = dialog;
1526         gps_file_browse_info.txt = txt_gps_file_path;
1527         g_signal_connect(G_OBJECT(btn_browse_gps), "clicked",
1528                 G_CALLBACK(settings_dialog_browse_forfile),
1529                 &gps_file_browse_info);
1530     }
1531
1532
1533     /* Initialize fields. */
1534     if(_gri.bt_mac)
1535         gtk_entry_set_text(GTK_ENTRY(txt_gps_bt_mac), _gri.bt_mac);
1536     if(_gri.gpsd_host)
1537         gtk_entry_set_text(GTK_ENTRY(txt_gps_gpsd_host), _gri.gpsd_host);
1538     hildon_number_editor_set_value(
1539             HILDON_NUMBER_EDITOR(num_gps_gpsd_port), _gri.gpsd_port);
1540     if(_gri.file_path)
1541         gtk_entry_set_text(GTK_ENTRY(txt_gps_file_path), _gri.file_path);
1542     switch(_gri.type)
1543     {
1544         case GPS_RCVR_GPSD:
1545             gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rad_gps_gpsd),TRUE);
1546             break;
1547         case GPS_RCVR_FILE:
1548             gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rad_gps_file),TRUE);
1549             break;
1550         default: /* Including GPS_RCVR_BT */
1551             gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rad_gps_bt), TRUE);
1552             break;
1553     }
1554
1555     if(_poi_db_filename)
1556         gtk_entry_set_text(GTK_ENTRY(txt_poi_db), _poi_db_filename);
1557     hildon_number_editor_set_value(HILDON_NUMBER_EDITOR(num_poi_zoom),
1558             _poi_zoom);
1559     hildon_controlbar_set_value(HILDON_CONTROLBAR(num_center_ratio),
1560             _center_ratio);
1561     hildon_controlbar_set_value(HILDON_CONTROLBAR(num_lead_ratio),
1562             _lead_ratio);
1563     gtk_toggle_button_set_active(
1564             GTK_TOGGLE_BUTTON(chk_lead_is_fixed), _lead_is_fixed);
1565     hildon_controlbar_set_value(HILDON_CONTROLBAR(num_rotate_sens),
1566             _rotate_sens);
1567     gtk_combo_box_set_active(GTK_COMBO_BOX(cmb_rotate_dir), _rotate_dir);
1568     hildon_number_editor_set_value(HILDON_NUMBER_EDITOR(num_ac_min_speed),
1569             _ac_min_speed);
1570     hildon_controlbar_set_value(HILDON_CONTROLBAR(num_announce_notice),
1571             _announce_notice_ratio);
1572     hildon_controlbar_set_value(HILDON_CONTROLBAR(num_draw_width),
1573             _draw_width);
1574     gtk_combo_box_set_active(GTK_COMBO_BOX(cmb_units), _units);
1575     gtk_combo_box_set_active(GTK_COMBO_BOX(cmb_degformat), _degformat);
1576     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chk_speed_limit_on),
1577             _speed_limit_on);
1578     hildon_controlbar_set_value(HILDON_CONTROLBAR(num_auto_download_precache),
1579             _auto_download_precache);
1580     hildon_number_editor_set_value(HILDON_NUMBER_EDITOR(num_speed),
1581             _speed_limit);
1582     gtk_combo_box_set_active(GTK_COMBO_BOX(cmb_speed_location),
1583             _speed_location);
1584     gtk_combo_box_set_active(GTK_COMBO_BOX(cmb_unblank_option),
1585             _unblank_option);
1586     gtk_combo_box_set_active(GTK_COMBO_BOX(cmb_info_font_size),
1587             _info_font_size);
1588
1589     gtk_widget_show_all(dialog);
1590
1591     while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
1592     {
1593         GpsRcvrType new_grtype;
1594
1595         if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rad_gps_gpsd))
1596                 && !*gtk_entry_get_text(GTK_ENTRY(txt_gps_gpsd_host)))
1597         {
1598             popup_error(dialog, _("Please specify a GPSD hostname."));
1599             continue;
1600         }
1601
1602         if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rad_gps_file))
1603                 && !*gtk_entry_get_text(GTK_ENTRY(txt_gps_file_path)))
1604         {
1605             popup_error(dialog, _("Please specify a GPS file pathname."));
1606             continue;
1607         }
1608
1609         /* Set _gri.bt_mac if necessary. */
1610         if(!*gtk_entry_get_text(GTK_ENTRY(txt_gps_bt_mac)))
1611         {
1612             /* User specified no rcvr mac - set _gri.bt_mac to NULL. */
1613             if(_gri.bt_mac)
1614             {
1615                 g_free(_gri.bt_mac);
1616                 _gri.bt_mac = NULL;
1617                 rcvr_changed = (_gri.type == GPS_RCVR_BT);
1618             }
1619         }
1620         else if(!_gri.bt_mac || strcmp(_gri.bt_mac,
1621                       gtk_entry_get_text(GTK_ENTRY(txt_gps_bt_mac))))
1622         {
1623             /* User specified a new rcvr mac. */
1624             g_free(_gri.bt_mac);
1625             _gri.bt_mac = g_strdup(gtk_entry_get_text(
1626                         GTK_ENTRY(txt_gps_bt_mac)));
1627             rcvr_changed = (_gri.type == GPS_RCVR_BT);
1628         }
1629
1630         /* Set _gri.gpsd_host if necessary. */
1631         if(!*gtk_entry_get_text(GTK_ENTRY(txt_gps_gpsd_host)))
1632         {
1633             /* User specified no rcvr mac - set _gri.gpsd_host to NULL. */
1634             if(_gri.gpsd_host)
1635             {
1636                 g_free(_gri.gpsd_host);
1637                 _gri.gpsd_host = NULL;
1638                 rcvr_changed = (_gri.type == GPS_RCVR_GPSD);
1639             }
1640         }
1641         else if(!_gri.gpsd_host || strcmp(_gri.gpsd_host,
1642                       gtk_entry_get_text(GTK_ENTRY(txt_gps_gpsd_host))))
1643         {
1644             /* User specified a new rcvr mac. */
1645             g_free(_gri.gpsd_host);
1646             _gri.gpsd_host = g_strdup(gtk_entry_get_text(
1647                         GTK_ENTRY(txt_gps_gpsd_host)));
1648             rcvr_changed = (_gri.type == GPS_RCVR_GPSD);
1649         }
1650
1651         if(_gri.gpsd_port != hildon_number_editor_get_value(
1652                     HILDON_NUMBER_EDITOR(num_gps_gpsd_port)))
1653         {
1654             _gri.gpsd_port = hildon_number_editor_get_value(
1655                     HILDON_NUMBER_EDITOR(num_gps_gpsd_port));
1656             rcvr_changed = (_gri.type == GPS_RCVR_GPSD);
1657         }
1658
1659         /* Set _gri.file_path if necessary. */
1660         if(!*gtk_entry_get_text(GTK_ENTRY(txt_gps_file_path)))
1661         {
1662             /* User specified no rcvr mac - set _gri.file_path to NULL. */
1663             if(_gri.file_path)
1664             {
1665                 g_free(_gri.file_path);
1666                 _gri.file_path = NULL;
1667                 rcvr_changed = (_gri.type == GPS_RCVR_FILE);
1668             }
1669         }
1670         else if(!_gri.file_path || strcmp(_gri.file_path,
1671                       gtk_entry_get_text(GTK_ENTRY(txt_gps_file_path))))
1672         {
1673             /* User specified a new rcvr mac. */
1674             g_free(_gri.file_path);
1675             _gri.file_path = g_strdup(gtk_entry_get_text(
1676                         GTK_ENTRY(txt_gps_file_path)));
1677             rcvr_changed = (_gri.type == GPS_RCVR_FILE);
1678         }
1679
1680         if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rad_gps_bt)))
1681             new_grtype = GPS_RCVR_BT;
1682         else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rad_gps_gpsd)))
1683             new_grtype = GPS_RCVR_GPSD;
1684         else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rad_gps_file)))
1685             new_grtype = GPS_RCVR_FILE;
1686         else
1687             new_grtype = GPS_RCVR_BT;
1688
1689         if(new_grtype != _gri.type)
1690         {
1691             _gri.type = new_grtype;
1692             rcvr_changed = TRUE;
1693         }
1694
1695         _center_ratio = hildon_controlbar_get_value(
1696                 HILDON_CONTROLBAR(num_center_ratio));
1697
1698         _lead_ratio = hildon_controlbar_get_value(
1699                 HILDON_CONTROLBAR(num_lead_ratio));
1700
1701         _lead_is_fixed = gtk_toggle_button_get_active(
1702                 GTK_TOGGLE_BUTTON(chk_lead_is_fixed));
1703
1704         _rotate_sens = hildon_controlbar_get_value(
1705                 HILDON_CONTROLBAR(num_rotate_sens));
1706
1707         _ac_min_speed = hildon_number_editor_get_value(
1708                 HILDON_NUMBER_EDITOR(num_ac_min_speed));
1709
1710         _rotate_dir = gtk_combo_box_get_active(GTK_COMBO_BOX(cmb_rotate_dir));
1711
1712         _auto_download_precache = hildon_controlbar_get_value(
1713                 HILDON_CONTROLBAR(num_auto_download_precache));
1714
1715         _draw_width = hildon_controlbar_get_value(
1716                 HILDON_CONTROLBAR(num_draw_width));
1717
1718         _units = gtk_combo_box_get_active(GTK_COMBO_BOX(cmb_units));
1719         _degformat = gtk_combo_box_get_active(GTK_COMBO_BOX(cmb_degformat));
1720
1721         _speed_limit_on = gtk_toggle_button_get_active(
1722                 GTK_TOGGLE_BUTTON(chk_speed_limit_on));
1723         _speed_limit = hildon_number_editor_get_value(
1724                 HILDON_NUMBER_EDITOR(num_speed));
1725         _speed_location = gtk_combo_box_get_active(
1726                 GTK_COMBO_BOX(cmb_speed_location));
1727
1728         _unblank_option = gtk_combo_box_get_active(
1729                 GTK_COMBO_BOX(cmb_unblank_option));
1730
1731         _info_font_size = gtk_combo_box_get_active(
1732                 GTK_COMBO_BOX(cmb_info_font_size));
1733
1734         _announce_notice_ratio = hildon_controlbar_get_value(
1735                 HILDON_CONTROLBAR(num_announce_notice));
1736
1737         _enable_announce = gtk_toggle_button_get_active(
1738                 GTK_TOGGLE_BUTTON(chk_enable_announce));
1739
1740         _enable_voice = gtk_toggle_button_get_active(
1741                 GTK_TOGGLE_BUTTON(chk_enable_voice));
1742
1743         /* Check if user specified a different POI database from before. */
1744         if((!_poi_db_filename && *gtk_entry_get_text(GTK_ENTRY(txt_poi_db)))
1745                 || strcmp(_poi_db_filename,
1746                     gtk_entry_get_text(GTK_ENTRY(txt_poi_db))))
1747         {
1748             /* Clear old filename/dirname, if necessary. */
1749             if(_poi_db_filename)
1750             {
1751                 g_free(_poi_db_filename);
1752                 _poi_db_filename = NULL;
1753                 g_free(_poi_db_dirname);
1754                 _poi_db_dirname = NULL;
1755             }
1756
1757             if(*gtk_entry_get_text(GTK_ENTRY(txt_poi_db)))
1758             {
1759                 _poi_db_filename = g_strdup(gtk_entry_get_text(
1760                             GTK_ENTRY(txt_poi_db)));
1761                 _poi_db_dirname = g_path_get_dirname(_poi_db_filename);
1762             }
1763
1764             poi_db_connect();
1765         }
1766
1767         _poi_zoom = hildon_number_editor_get_value(
1768                 HILDON_NUMBER_EDITOR(num_poi_zoom));
1769
1770         update_gcs();
1771
1772         settings_save();
1773
1774         map_force_redraw();
1775         map_refresh_mark(TRUE);
1776
1777         break;
1778     }
1779
1780     gtk_widget_hide(dialog);
1781
1782     vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, rcvr_changed);
1783     return rcvr_changed;
1784 }
1785
1786 RepoData*
1787 settings_parse_repo(gchar *str)
1788 {
1789     /* Parse each part of a repo, delimited by newline characters:
1790      * 1. name
1791      * 2. url
1792      * 3. db_filename
1793      * 4. dl_zoom_steps
1794      * 5. view_zoom_steps
1795      */
1796     gchar *token, *error_check;
1797     printf("%s(%s)\n", __PRETTY_FUNCTION__, str);
1798
1799     RepoData *rd = g_new0(RepoData, 1);
1800
1801     /* Parse name. */
1802     token = strsep(&str, "\n\t");
1803     if(token)
1804         rd->name = g_strdup(token);
1805
1806     /* Parse URL format. */
1807     token = strsep(&str, "\n\t");
1808     if(token)
1809         rd->url = g_strdup(token);
1810
1811     /* Parse cache dir. */
1812     token = strsep(&str, "\n\t");
1813     if(token)
1814         rd->db_filename = gnome_vfs_expand_initial_tilde(token);
1815
1816     /* Parse download zoom steps. */
1817     token = strsep(&str, "\n\t");
1818     if(!token || !*token || !(rd->dl_zoom_steps = atoi(token)))
1819         rd->dl_zoom_steps = 2;
1820
1821     /* Parse view zoom steps. */
1822     token = strsep(&str, "\n\t");
1823     if(!token || !*token || !(rd->view_zoom_steps = atoi(token)))
1824         rd->view_zoom_steps = 1;
1825
1826     /* Parse double-size. */
1827     token = strsep(&str, "\n\t");
1828     if(token)
1829         rd->double_size = atoi(token); /* Default is zero (FALSE) */
1830
1831     /* Parse next-able. */
1832     token = strsep(&str, "\n\t");
1833     if(!token || !*token
1834             || (rd->nextable = strtol(token, &error_check, 10), token == str))
1835         rd->nextable = TRUE;
1836
1837     /* Parse min zoom. */
1838     token = strsep(&str, "\n\t");
1839     if(!token || !*token
1840             || (rd->min_zoom = strtol(token, &error_check, 10), token == str))
1841         rd->min_zoom = 4;
1842
1843     /* Parse max zoom. */
1844     token = strsep(&str, "\n\t");
1845     if(!token || !*token
1846             || (rd->max_zoom = strtol(token, &error_check, 10), token == str))
1847         rd->max_zoom = 20;
1848
1849     set_repo_type(rd);
1850
1851     vprintf("%s(): return %p\n", __PRETTY_FUNCTION__, rd);
1852     return rd;
1853 }
1854
1855 /**
1856  * Initialize all configuration from GCONF.  This should not be called more
1857  * than once during execution.
1858  */
1859 void
1860 settings_init()
1861 {
1862     GConfValue *value;
1863     GConfClient *gconf_client = gconf_client_get_default();
1864     gchar *str;
1865     printf("%s()\n", __PRETTY_FUNCTION__);
1866
1867     /* Initialize some constants. */
1868     CUSTOM_KEY_GCONF[CUSTOM_KEY_UP] = GCONF_KEY_PREFIX"/key_up";
1869     CUSTOM_KEY_GCONF[CUSTOM_KEY_DOWN] = GCONF_KEY_PREFIX"/key_down";
1870     CUSTOM_KEY_GCONF[CUSTOM_KEY_LEFT] = GCONF_KEY_PREFIX"/key_left";
1871     CUSTOM_KEY_GCONF[CUSTOM_KEY_RIGHT] = GCONF_KEY_PREFIX"/key_right";
1872     CUSTOM_KEY_GCONF[CUSTOM_KEY_SELECT] = GCONF_KEY_PREFIX"/key_select";
1873     CUSTOM_KEY_GCONF[CUSTOM_KEY_INCREASE] = GCONF_KEY_PREFIX"/key_increase";
1874     CUSTOM_KEY_GCONF[CUSTOM_KEY_DECREASE] = GCONF_KEY_PREFIX"/key_decrease";
1875     CUSTOM_KEY_GCONF[CUSTOM_KEY_FULLSCREEN]= GCONF_KEY_PREFIX"/key_fullscreen";
1876     CUSTOM_KEY_GCONF[CUSTOM_KEY_ESC] = GCONF_KEY_PREFIX"/key_esc";
1877
1878     COLORABLE_GCONF[COLORABLE_MARK] = GCONF_KEY_PREFIX"/color_mark";
1879     COLORABLE_GCONF[COLORABLE_MARK_VELOCITY]
1880         = GCONF_KEY_PREFIX"/color_mark_velocity";
1881     COLORABLE_GCONF[COLORABLE_MARK_OLD] = GCONF_KEY_PREFIX"/color_mark_old";
1882     COLORABLE_GCONF[COLORABLE_TRACK] = GCONF_KEY_PREFIX"/color_track";
1883     COLORABLE_GCONF[COLORABLE_TRACK_MARK] =GCONF_KEY_PREFIX"/color_track_mark";
1884     COLORABLE_GCONF[COLORABLE_TRACK_BREAK]
1885         = GCONF_KEY_PREFIX"/color_track_break";
1886     COLORABLE_GCONF[COLORABLE_ROUTE] = GCONF_KEY_PREFIX"/color_route";
1887     COLORABLE_GCONF[COLORABLE_ROUTE_WAY] = GCONF_KEY_PREFIX"/color_route_way";
1888     COLORABLE_GCONF[COLORABLE_ROUTE_BREAK]
1889         = GCONF_KEY_PREFIX"/color_route_break";
1890     COLORABLE_GCONF[COLORABLE_POI] = GCONF_KEY_PREFIX"/color_poi";
1891
1892     if(!gconf_client)
1893     {
1894         popup_error(_window, _("Failed to initialize GConf.  Quitting."));
1895         exit(1);
1896     }
1897
1898     /* Get GPS Receiver Type.  Default is Bluetooth Receiver. */
1899     {
1900         gchar *gri_type_str = gconf_client_get_string(gconf_client,
1901                 GCONF_KEY_GPS_RCVR_TYPE, NULL);
1902         gint i = 0;
1903         if(gri_type_str)
1904         {
1905             for(i = GPS_RCVR_ENUM_COUNT - 1; i > 0; i--)
1906                 if(!strcmp(gri_type_str, GPS_RCVR_ENUM_TEXT[i]))
1907                     break;
1908             g_free(gri_type_str);
1909         }
1910         _gri.type = i;
1911     }
1912
1913     /* Get Bluetooth Receiver MAC.  Default is NULL. */
1914     _gri.bt_mac = gconf_client_get_string(
1915             gconf_client, GCONF_KEY_GPS_BT_MAC, NULL);
1916
1917     /* Get GPSD Host.  Default is localhost. */
1918     _gri.gpsd_host = gconf_client_get_string(
1919             gconf_client, GCONF_KEY_GPS_GPSD_HOST, NULL);
1920     if(!_gri.gpsd_host)
1921         _gri.gpsd_host = g_strdup("127.0.0.1");
1922
1923     /* Get GPSD Port.  Default is GPSD_PORT_DEFAULT (2947). */
1924     if(!(_gri.gpsd_port = gconf_client_get_int(
1925             gconf_client, GCONF_KEY_GPS_GPSD_PORT, NULL)))
1926         _gri.gpsd_port = GPSD_PORT_DEFAULT;
1927
1928     /* Get File Path.  Default is /dev/pgps. */
1929     _gri.file_path = gconf_client_get_string(
1930             gconf_client, GCONF_KEY_GPS_FILE_PATH, NULL);
1931     if(!_gri.file_path)
1932         _gri.file_path = g_strdup("/dev/pgps");
1933
1934     /* Get Auto-Download.  Default is FALSE. */
1935     _auto_download = gconf_client_get_bool(gconf_client,
1936             GCONF_KEY_AUTO_DOWNLOAD, NULL);
1937
1938     /* Get Auto-Download Pre-cache - Default is 2. */
1939     _auto_download_precache = gconf_client_get_int(gconf_client,
1940             GCONF_KEY_AUTO_DOWNLOAD_PRECACHE, NULL);
1941     if(!_auto_download_precache)
1942         _auto_download_precache = 2;
1943
1944     /* Get Center Ratio - Default is 5. */
1945     _center_ratio = gconf_client_get_int(gconf_client,
1946             GCONF_KEY_CENTER_SENSITIVITY, NULL);
1947     if(!_center_ratio)
1948         _center_ratio = 5;
1949
1950     /* Get Lead Ratio - Default is 5. */
1951     _lead_ratio = gconf_client_get_int(gconf_client,
1952             GCONF_KEY_LEAD_AMOUNT, NULL);
1953     if(!_lead_ratio)
1954         _lead_ratio = 5;
1955
1956     /* Get Lead Is Fixed flag - Default is FALSE. */
1957     _lead_is_fixed = gconf_client_get_bool(gconf_client,
1958             GCONF_KEY_LEAD_IS_FIXED, NULL);
1959
1960     /* Get Rotate Sensitivity - Default is 5. */
1961     _rotate_sens = gconf_client_get_int(gconf_client,
1962             GCONF_KEY_ROTATE_SENSITIVITY, NULL);
1963     if(!_rotate_sens)
1964         _rotate_sens = 5;
1965
1966     /* Get Auto-Center/Rotate Minimum Speed - Default is 2. */
1967     value = gconf_client_get(gconf_client, GCONF_KEY_AC_MIN_SPEED, NULL);
1968     if(value)
1969     {
1970         _ac_min_speed = gconf_value_get_int(value);
1971         gconf_value_free(value);
1972     }
1973     else
1974         _ac_min_speed = 2;
1975
1976     /* Get Rotate Dir - Default is ROTATE_DIR_UP. */
1977     {
1978         gchar *rotate_dir_str = gconf_client_get_string(gconf_client,
1979                 GCONF_KEY_ROTATE_DIR, NULL);
1980         gint i = -1;
1981         if(rotate_dir_str)
1982             for(i = ROTATE_DIR_ENUM_COUNT - 1; i >= 0; i--)
1983                 if(!strcmp(rotate_dir_str, ROTATE_DIR_ENUM_TEXT[i]))
1984                     break;
1985         if(i == -1)
1986             i = ROTATE_DIR_UP;
1987         _rotate_dir = i;
1988     }
1989
1990     /* Get Draw Line Width- Default is 5. */
1991     _draw_width = gconf_client_get_int(gconf_client,
1992             GCONF_KEY_DRAW_WIDTH, NULL);
1993     if(!_draw_width)
1994         _draw_width = 5;
1995
1996     /* Get Enable Announcements flag.  Default is TRUE. */
1997     value = gconf_client_get(gconf_client, GCONF_KEY_ENABLE_ANNOUNCE, NULL);
1998     if(value)
1999     {
2000         _enable_announce = gconf_value_get_bool(value);
2001         gconf_value_free(value);
2002     }
2003     else
2004         _enable_announce = TRUE;
2005
2006     /* Get Announce Advance Notice - Default is 30. */
2007     value = gconf_client_get(gconf_client, GCONF_KEY_ANNOUNCE_NOTICE, NULL);
2008     if(value)
2009     {
2010         _announce_notice_ratio = gconf_value_get_int(value);
2011         gconf_value_free(value);
2012     }
2013     else
2014         _announce_notice_ratio = 8;
2015
2016     /* Get Enable Voice flag.  Default is TRUE. */
2017     value = gconf_client_get(gconf_client, GCONF_KEY_ENABLE_VOICE, NULL);
2018     if(value)
2019     {
2020         _enable_voice = gconf_value_get_bool(value);
2021         gconf_value_free(value);
2022     }
2023     else
2024         _enable_voice = TRUE;
2025
2026     /* Get Fullscreen flag. Default is FALSE. */
2027     _fullscreen = gconf_client_get_bool(gconf_client,
2028             GCONF_KEY_FULLSCREEN, NULL);
2029
2030     /* Get Units.  Default is UNITS_KM. */
2031     {
2032         gchar *units_str = gconf_client_get_string(gconf_client,
2033                 GCONF_KEY_UNITS, NULL);
2034         gint i = 0;
2035         if(units_str)
2036             for(i = UNITS_ENUM_COUNT - 1; i > 0; i--)
2037                 if(!strcmp(units_str, UNITS_ENUM_TEXT[i]))
2038                     break;
2039         _units = i;
2040     }
2041
2042     /* Get Custom Key Actions. */
2043     {
2044         gint i;
2045         for(i = 0; i < CUSTOM_KEY_ENUM_COUNT; i++)
2046         {
2047             gint j = CUSTOM_KEY_DEFAULT[i];
2048             gchar *str = gconf_client_get_string(gconf_client,
2049                     CUSTOM_KEY_GCONF[i], NULL);
2050             if(str)
2051                 for(j = CUSTOM_ACTION_ENUM_COUNT - 1; j > 0; j--)
2052                     if(!strcmp(str, CUSTOM_ACTION_ENUM_TEXT[j]))
2053                         break;
2054             _action[i] = j;
2055         }
2056     }
2057
2058     /* Get Deg format.  Default is DDPDDDDD. */
2059     {
2060         gchar *degformat_key_str = gconf_client_get_string(gconf_client,
2061                 GCONF_KEY_DEG_FORMAT, NULL);
2062         gint i = 0;
2063         if(degformat_key_str)
2064             for(i = DEG_FORMAT_ENUM_COUNT - 1; i > 0; i--)
2065                 if(!strcmp(degformat_key_str, DEG_FORMAT_ENUM_TEXT[i]))
2066                     break;
2067         _degformat = i;
2068     }
2069
2070     /* Get Speed Limit On flag.  Default is FALSE. */
2071     _speed_limit_on = gconf_client_get_bool(gconf_client,
2072             GCONF_KEY_SPEED_LIMIT_ON, NULL);
2073
2074     /* Get Speed Limit */
2075     _speed_limit = gconf_client_get_int(gconf_client,
2076             GCONF_KEY_SPEED_LIMIT, NULL);
2077     if(_speed_limit <= 0)
2078         _speed_limit = 100;
2079
2080     /* Get Speed Location.  Default is SPEED_LOCATION_TOP_LEFT. */
2081     {
2082         gchar *speed_location_str = gconf_client_get_string(gconf_client,
2083                 GCONF_KEY_SPEED_LOCATION, NULL);
2084         gint i = 0;
2085         if(speed_location_str)
2086             for(i = SPEED_LOCATION_ENUM_COUNT - 1; i > 0; i--)
2087                 if(!strcmp(speed_location_str, SPEED_LOCATION_ENUM_TEXT[i]))
2088                     break;
2089         _speed_location = i;
2090     }
2091
2092     /* Get Unblank Option.  Default is UNBLANK_FULLSCREEN. */
2093     {
2094         gchar *unblank_option_str = gconf_client_get_string(gconf_client,
2095                 GCONF_KEY_UNBLANK_SIZE, NULL);
2096         gint i = -1;
2097         if(unblank_option_str)
2098             for(i = UNBLANK_ENUM_COUNT - 1; i >= 0; i--)
2099                 if(!strcmp(unblank_option_str, UNBLANK_ENUM_TEXT[i]))
2100                     break;
2101         if(i == -1)
2102             i = UNBLANK_FULLSCREEN;
2103         _unblank_option = i;
2104     }
2105
2106     /* Get Info Font Size.  Default is INFO_FONT_MEDIUM. */
2107     {
2108         gchar *info_font_size_str = gconf_client_get_string(gconf_client,
2109                 GCONF_KEY_INFO_FONT_SIZE, NULL);
2110         gint i = -1;
2111         if(info_font_size_str)
2112             for(i = INFO_FONT_ENUM_COUNT - 1; i >= 0; i--)
2113                 if(!strcmp(info_font_size_str, INFO_FONT_ENUM_TEXT[i]))
2114                     break;
2115         if(i == -1)
2116             i = INFO_FONT_MEDIUM;
2117         _info_font_size = i;
2118     }
2119
2120     /* Get last saved latitude.  Default is 50.f. */
2121     value = gconf_client_get(gconf_client, GCONF_KEY_LAST_LAT, NULL);
2122     if(value)
2123     {
2124         _gps.lat = gconf_value_get_float(value);
2125         gconf_value_free(value);
2126     }
2127     else
2128         _gps.lat = 50.f;
2129
2130     /* Get last saved longitude.  Default is 0. */
2131     _gps.lon = gconf_client_get_float(gconf_client, GCONF_KEY_LAST_LON, NULL);
2132
2133     /* Get last saved altitude.  Default is 0. */
2134     _pos.altitude = gconf_client_get_int(
2135             gconf_client, GCONF_KEY_LAST_ALT, NULL);
2136
2137     /* Get last saved speed.  Default is 0. */
2138     _gps.speed = gconf_client_get_float(
2139             gconf_client, GCONF_KEY_LAST_SPEED, NULL);
2140
2141     /* Get last saved speed.  Default is 0. */
2142     _gps.heading = gconf_client_get_float(
2143             gconf_client, GCONF_KEY_LAST_HEADING, NULL);
2144
2145     /* Get last saved timestamp.  Default is 0. */
2146     _pos.time= gconf_client_get_float(gconf_client, GCONF_KEY_LAST_TIME, NULL);
2147
2148     /* Get last center point. */
2149     {
2150         gdouble center_lat, center_lon;
2151
2152         /* Get last saved latitude.  Default is last saved latitude. */
2153         value = gconf_client_get(gconf_client, GCONF_KEY_CENTER_LAT, NULL);
2154         if(value)
2155         {
2156             center_lat = gconf_value_get_float(value);
2157             gconf_value_free(value);
2158         }
2159         else
2160         {
2161             _is_first_time = TRUE;
2162             center_lat = _gps.lat;
2163         }
2164
2165         /* Get last saved longitude.  Default is last saved longitude. */
2166         value = gconf_client_get(gconf_client, GCONF_KEY_CENTER_LON, NULL);
2167         if(value)
2168         {
2169             center_lon = gconf_value_get_float(value);
2170             gconf_value_free(value);
2171         }
2172         else
2173             center_lon = _gps.lon;
2174
2175         latlon2unit(center_lat, center_lon, _center.unitx, _center.unity);
2176         _next_center = _center;
2177     }
2178
2179     /* Get map correction.  Default is 0. */
2180     _map_correction_unitx = gconf_client_get_int(gconf_client,
2181             GCONF_KEY_MAP_CORRECTION_UNITX, NULL);
2182     _map_correction_unity = gconf_client_get_int(gconf_client,
2183             GCONF_KEY_MAP_CORRECTION_UNITY, NULL);
2184
2185     /* Get last viewing angle.  Default is 0. */
2186     _map_rotate_angle = _next_map_rotate_angle = gconf_client_get_int(
2187             gconf_client, GCONF_KEY_CENTER_ANGLE, NULL);
2188     gdk_pixbuf_rotate_matrix_fill_for_rotation(
2189             _map_rotate_matrix,
2190             deg2rad(ROTATE_DIR_ENUM_DEGREES[_rotate_dir] - _map_rotate_angle));
2191     gdk_pixbuf_rotate_matrix_fill_for_rotation(
2192             _map_reverse_matrix,
2193             deg2rad(_map_rotate_angle - ROTATE_DIR_ENUM_DEGREES[_rotate_dir]));
2194
2195
2196     /* Load the repositories. */
2197     {
2198         GSList *list, *curr;
2199         gint curr_repo_index = gconf_client_get_int(gconf_client,
2200             GCONF_KEY_CURRREPO, NULL);
2201         list = gconf_client_get_list(gconf_client,
2202             GCONF_KEY_REPOSITORIES, GCONF_VALUE_STRING, NULL);
2203
2204         for(curr = list; curr != NULL; curr = curr->next)
2205         {
2206             RepoData *rd = settings_parse_repo(curr->data);
2207             _repo_list = g_list_append(_repo_list, rd);
2208             if(!curr_repo_index--)
2209                 repo_set_curr(rd);
2210             g_free(curr->data);
2211         }
2212         g_slist_free(list);
2213     }
2214
2215
2216     if(_repo_list == NULL)
2217     {
2218         /* We have no repositories - create a default one. */
2219         RepoData *repo = g_new(RepoData, 1);
2220
2221         repo->db_filename = gnome_vfs_expand_initial_tilde(
2222                 REPO_DEFAULT_CACHE_DIR);
2223         repo->url=g_strdup(REPO_DEFAULT_MAP_URI);
2224         repo->dl_zoom_steps = REPO_DEFAULT_DL_ZOOM_STEPS;
2225         repo->name = g_strdup(REPO_DEFAULT_NAME);
2226         repo->view_zoom_steps = REPO_DEFAULT_VIEW_ZOOM_STEPS;
2227         repo->double_size = FALSE;
2228         repo->nextable = TRUE;
2229         repo->min_zoom = REPO_DEFAULT_MIN_ZOOM;
2230         repo->max_zoom = REPO_DEFAULT_MAX_ZOOM;
2231         set_repo_type(repo);
2232
2233         _repo_list = g_list_append(_repo_list, repo);
2234         repo_set_curr(repo);
2235     }
2236
2237     /* Get last Zoom Level.  Default is 16. */
2238     value = gconf_client_get(gconf_client, GCONF_KEY_ZOOM, NULL);
2239     if(value)
2240     {
2241         _zoom = gconf_value_get_int(value) / _curr_repo->view_zoom_steps
2242             * _curr_repo->view_zoom_steps;
2243         gconf_value_free(value);
2244     }
2245     else
2246         _zoom = 16 / _curr_repo->view_zoom_steps
2247             * _curr_repo->view_zoom_steps;
2248     BOUND(_zoom, 0, MAX_ZOOM);
2249     _next_zoom = _zoom;
2250
2251     /* Get Route Directory.  Default is NULL. */
2252     _route_dir_uri = gconf_client_get_string(gconf_client,
2253             GCONF_KEY_ROUTEDIR, NULL);
2254
2255     /* Get Last Track File.  Default is NULL. */
2256     _track_file_uri = gconf_client_get_string(gconf_client,
2257             GCONF_KEY_TRACKFILE, NULL);
2258
2259     /* Get Auto-Center Mode.  Default is CENTER_LEAD. */
2260     value = gconf_client_get(gconf_client, GCONF_KEY_AUTOCENTER_MODE, NULL);
2261     if(value)
2262     {
2263         _center_mode = gconf_value_get_int(value);
2264         gconf_value_free(value);
2265     }
2266     else
2267         _center_mode = CENTER_LEAD;
2268
2269     /* Get Auto-Center Rotate Flag.  Default is TRUE. */
2270     value = gconf_client_get(gconf_client, GCONF_KEY_AUTOCENTER_ROTATE, NULL);
2271     if(value)
2272     {
2273         _center_rotate = gconf_value_get_bool(value);
2274         gconf_value_free(value);
2275     }
2276     else
2277         _center_rotate = TRUE;
2278
2279     /* Get Show Zoom Level flag.  Default is FALSE. */
2280     _show_zoomlevel = gconf_client_get_bool(gconf_client,
2281             GCONF_KEY_SHOWZOOMLEVEL, NULL);
2282
2283     /* Get Show Scale flag.  Default is TRUE. */
2284     value = gconf_client_get(gconf_client, GCONF_KEY_SHOWSCALE, NULL);
2285     if(value)
2286     {
2287         _show_scale = gconf_value_get_bool(value);
2288         gconf_value_free(value);
2289     }
2290     else
2291         _show_scale = TRUE;
2292
2293     /* Get Show Compass Rose flag.  Default is TRUE. */
2294     value = gconf_client_get(gconf_client, GCONF_KEY_SHOWCOMPROSE, NULL);
2295     if(value)
2296     {
2297         _show_comprose = gconf_value_get_bool(value);
2298         gconf_value_free(value);
2299     }
2300     else
2301         _show_comprose = TRUE;
2302
2303     /* Get Show Tracks flag.  Default is TRUE. */
2304     value = gconf_client_get(gconf_client, GCONF_KEY_SHOWTRACKS, NULL);
2305     if(value)
2306     {
2307         _show_paths |= (gconf_value_get_bool(value) ? TRACKS_MASK : 0);
2308         gconf_value_free(value);
2309     }
2310     else
2311         _show_paths |= TRACKS_MASK;
2312
2313     /* Get Show Routes flag.  Default is TRUE. */
2314     value = gconf_client_get(gconf_client, GCONF_KEY_SHOWROUTES, NULL);
2315     if(value)
2316     {
2317         _show_paths |= (gconf_value_get_bool(value) ? ROUTES_MASK : 0);
2318         gconf_value_free(value);
2319     }
2320     else
2321         _show_paths |= ROUTES_MASK;
2322
2323     /* Get Show Velocity Vector flag.  Default is TRUE. */
2324     value = gconf_client_get(gconf_client, GCONF_KEY_SHOWVELVEC, NULL);
2325     if(value)
2326     {
2327         _show_velvec = gconf_value_get_bool(value);
2328         gconf_value_free(value);
2329     }
2330     else
2331         _show_velvec = TRUE;
2332
2333     /* Get Show Velocity Vector flag.  Default is TRUE. */
2334     value = gconf_client_get(gconf_client, GCONF_KEY_SHOWPOIS, NULL);
2335     if(value)
2336     {
2337         _show_poi = gconf_value_get_bool(value);
2338         gconf_value_free(value);
2339     }
2340     else
2341         _show_poi = TRUE;
2342
2343     /* Get Enable GPS flag.  Default is TRUE. */
2344     value = gconf_client_get(gconf_client, GCONF_KEY_ENABLE_GPS, NULL);
2345     if(value)
2346     {
2347         _enable_gps = gconf_value_get_bool(value);
2348         gconf_value_free(value);
2349     }
2350     else
2351         _enable_gps = TRUE;
2352
2353     /* Initialize _gps_state based on _enable_gps. */
2354     _gps_state = RCVR_OFF;
2355
2356     /* Load the route locations. */
2357     {
2358         GSList *curr;
2359         _loc_list = gconf_client_get_list(gconf_client,
2360             GCONF_KEY_ROUTE_LOCATIONS, GCONF_VALUE_STRING, NULL);
2361         _loc_model = gtk_list_store_new(1, G_TYPE_STRING);
2362         for(curr = _loc_list; curr != NULL; curr = curr->next)
2363         {
2364             GtkTreeIter iter;
2365             gtk_list_store_insert_with_values(_loc_model, &iter, INT_MAX,
2366                     0, curr->data, -1);
2367         }
2368     }
2369
2370     /* Get POI Database.  Default is in REPO_DEFAULT_CACHE_BASE */
2371     _poi_db_filename = gconf_client_get_string(gconf_client,
2372             GCONF_KEY_POI_DB, NULL);
2373     if(_poi_db_filename == NULL)
2374     {
2375         gchar *poi_base = gnome_vfs_expand_initial_tilde(
2376                 REPO_DEFAULT_CACHE_BASE);
2377         _poi_db_filename = gnome_vfs_uri_make_full_from_relative(
2378                 poi_base, "poi.db");
2379         g_free(poi_base);
2380     }
2381
2382     _poi_db_dirname = g_path_get_dirname(_poi_db_filename);
2383
2384     _poi_zoom = gconf_client_get_int(gconf_client,
2385             GCONF_KEY_POI_ZOOM, NULL);
2386     if(!_poi_zoom)
2387         _poi_zoom = MAX_ZOOM - 10;
2388
2389
2390     /* Get GPS Info flag.  Default is FALSE. */
2391     _gps_info = gconf_client_get_bool(gconf_client, GCONF_KEY_GPS_INFO, NULL);
2392
2393     /* Get Route Download URL.  Default is:
2394      * "http://www.gnuite.com/cgi-bin/gpx.cgi?saddr=%s&daddr=%s" */
2395     _route_dl_url = gconf_client_get_string(gconf_client,
2396             GCONF_KEY_ROUTE_DL_URL, NULL);
2397     if(_route_dl_url == NULL)
2398         _route_dl_url = g_strdup(
2399                 "http://www.gnuite.com/cgi-bin/gpx.cgi?saddr=%s&daddr=%s");
2400
2401     /* Get Route Download Radius.  Default is 4. */
2402     value = gconf_client_get(gconf_client, GCONF_KEY_ROUTE_DL_RADIUS, NULL);
2403     if(value)
2404     {
2405         _route_dl_radius = gconf_value_get_int(value);
2406         gconf_value_free(value);
2407     }
2408     else
2409         _route_dl_radius = 8;
2410
2411     /* Get POI Download URL.  Default is:
2412      * "http://www.gnuite.com/cgi-bin/poi.cgi?saddr=%s&query=%s&page=%d" */
2413     _poi_dl_url = gconf_client_get_string(gconf_client,
2414             GCONF_KEY_POI_DL_URL, NULL);
2415     if(_poi_dl_url == NULL)
2416         _poi_dl_url = g_strdup(
2417             "http://www.gnuite.com/cgi-bin/poi.cgi?saddr=%s&query=%s&page=%d");
2418
2419     /* Get Colors. */
2420     {
2421         gint i;
2422         for(i = 0; i < COLORABLE_ENUM_COUNT; i++)
2423         {
2424             str = gconf_client_get_string(gconf_client,
2425                     COLORABLE_GCONF[i], NULL);
2426             if(!str || !gdk_color_parse(str, &_color[i]))
2427                 _color[i] = COLORABLE_DEFAULT[i];
2428         }
2429     }
2430
2431     gconf_client_clear_cache(gconf_client);
2432     g_object_unref(gconf_client);
2433
2434     /* GPS data init */
2435     _gps.fix = 1;
2436     _gps.satinuse = 0;
2437     _gps.satinview = 0;
2438
2439     vprintf("%s(): return\n", __PRETTY_FUNCTION__);
2440 }
2441