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