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