Contents of /trunk/src/gconf.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 252 - (hide annotations)
Thu Feb 4 20:15:19 2010 UTC (14 years, 4 months ago) by harbaum
File MIME type: text/plain
File size: 16399 byte(s)
Geotoad fixes
1 harbaum 1 /*
2     * Copyright (C) 2008 Till Harbaum <till@harbaum.org>.
3     *
4     * This file is part of GPXView.
5     *
6     * GPXView is free software: you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation, either version 3 of the License, or
9     * (at your option) any later version.
10     *
11     * GPXView is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with GPXView. If not, see <http://www.gnu.org/licenses/>.
18     */
19    
20     #include <stddef.h>
21     #include <stdlib.h>
22     #include <ctype.h>
23 harbaum 34 #include <math.h> // for isnan
24 harbaum 1 #include "gpxview.h"
25    
26     #define GCONF_PATH "/apps/gpxview/"
27     #define GCONF_KEY_GPX GCONF_PATH "gpx%d"
28     #define GCONF_KEY_CNT GCONF_PATH "entries"
29    
30     #define GCONF_KEY_LOC_NAME GCONF_PATH "location%d/name"
31     #define GCONF_KEY_LOC_LAT GCONF_PATH "location%d/latitude"
32     #define GCONF_KEY_LOC_LON GCONF_PATH "location%d/longitude"
33     #define GCONF_KEY_LOC_CNT GCONF_PATH "location_entries"
34    
35     #define GCONF_KEY_CLOSED GCONF_PATH "closed/%s"
36    
37     #include <string.h>
38    
39     enum {
40     STORE_STRING, STORE_FLOAT, STORE_INT, STORE_BOOL,
41     };
42    
43     typedef struct {
44     char *key;
45     int type;
46     int offset;
47     } store_t;
48    
49     #define OFFSET(a) offsetof(appdata_t, a)
50    
51     static store_t store[] = {
52     { "image_path", STORE_STRING, OFFSET(image_path) },
53     { "path", STORE_STRING, OFFSET(path) },
54     { "geotext/text", STORE_STRING, OFFSET(geotext_text) },
55     { "geotext/shift", STORE_INT, OFFSET(geotext_shift) },
56     { "mmpoi_path", STORE_STRING, OFFSET(mmpoi_path) },
57     { "garmin_path", STORE_STRING, OFFSET(garmin_path) },
58     { "fnotes_path", STORE_STRING, OFFSET(fieldnotes_path) },
59     { "garmin_ign_found", STORE_BOOL, OFFSET(garmin_ign_found) },
60     { "active_location", STORE_INT, OFFSET(active_location) },
61     { "mmpoi_use_radius", STORE_BOOL, OFFSET(mmpoi_use_radius) },
62     { "mmpoi_radius", STORE_FLOAT, OFFSET(mmpoi_radius) },
63     { "mmpoi_ign_found", STORE_BOOL, OFFSET(mmpoi_dont_export_found) },
64     { "mmpoi_ign_disabl", STORE_BOOL, OFFSET(mmpoi_dont_export_disabled) },
65     { "use_gps", STORE_BOOL, OFFSET(use_gps) },
66     { "imperial", STORE_BOOL, OFFSET(imperial) },
67     { "compass_locked", STORE_BOOL, OFFSET(compass_locked) },
68     { "latitude", STORE_FLOAT, OFFSET(home.lat) },
69     { "longitude", STORE_FLOAT, OFFSET(home.lon) },
70     { "gps_lat", STORE_FLOAT, OFFSET(gps.lat) },
71     { "gps_lon", STORE_FLOAT, OFFSET(gps.lon) },
72     { "search_in", STORE_INT, OFFSET(search) },
73     { "search_days", STORE_INT, OFFSET(search_days) },
74     { "search_str", STORE_STRING, OFFSET(search_str) },
75     { "gpxlist_items", STORE_INT, OFFSET(gpxlist_items) },
76     { "cachelist_items", STORE_INT, OFFSET(cachelist_items) },
77     { "compass_damping", STORE_INT, OFFSET(compass_damping) },
78     { "cachelist_hide_found", STORE_BOOL, OFFSET(cachelist_hide_found) },
79 harbaum 129 { "cachelist_update", STORE_BOOL, OFFSET(cachelist_update) },
80 harbaum 167 { "disable_gcvote", STORE_BOOL, OFFSET(disable_gcvote) },
81 harbaum 204 { "username", STORE_STRING, OFFSET(username) },
82 harbaum 1 #ifdef USE_MAEMO
83     { "mmpoi_dontlaunch", STORE_BOOL, OFFSET(mmpoi_dontlaunch) },
84     { "cachelist_dss", STORE_BOOL, OFFSET(cachelist_disable_screensaver) },
85     { "goto_dss", STORE_BOOL, OFFSET(goto_disable_screensaver) },
86     #endif
87 harbaum 48 #ifdef ENABLE_OSM_GPS_MAP
88     { "map_lat", STORE_FLOAT, OFFSET(map.pos.lat) },
89     { "map_lon", STORE_FLOAT, OFFSET(map.pos.lon) },
90     { "map_zoom", STORE_INT, OFFSET(map.zoom) },
91 harbaum 89 { "map_source", STORE_INT, OFFSET(map.source) },
92 harbaum 48 #endif
93 harbaum 246 #ifdef ESPEAK
94     { "espeak/enabled", STORE_BOOL, OFFSET(espeak.enabled) },
95     #endif
96 harbaum 196
97 harbaum 197 { "geotoad/password", STORE_STRING, OFFSET(gt.password) },
98     { "geotoad/filename", STORE_STRING, OFFSET(gt.filename) },
99     { "geotoad/distance", STORE_FLOAT, OFFSET(gt.distance) },
100     { "geotoad/lat", STORE_FLOAT, OFFSET(gt.lat) },
101     { "geotoad/lon", STORE_FLOAT, OFFSET(gt.lon) },
102     { "geotoad/flags", STORE_INT, OFFSET(gt.flags) },
103 harbaum 252 { "geotoad/no_ownfnd",STORE_BOOL, OFFSET(gt.no_owned_found) },
104 harbaum 196
105 harbaum 1 { NULL, -1, -1 }
106     };
107    
108     static char *get_basename(char *name) {
109     char *p = strrchr(name, '/');
110     if(!p) p = name;
111     else p = p+1;
112    
113     g_assert(*p);
114    
115     /* escape all non alnum characters */
116     p = g_strdup(p);
117     int i;
118     for(i=0;i<strlen(p);i++)
119     if(!isalnum(p[i]))
120     p[i] = '_';
121    
122     return p;
123     }
124    
125     void gconf_remove_closed_name(appdata_t *appdata, char *filename) {
126 harbaum 211 if(!filename || !strlen(filename)) return;
127    
128 harbaum 1 char *key = g_strdup_printf(GCONF_KEY_CLOSED, get_basename(filename));
129     gconf_client_unset(appdata->gconf_client, key, NULL);
130     g_free(key);
131     }
132    
133     void gconf_save_closed_name(appdata_t *appdata, char *filename, char *name) {
134 harbaum 211 if(!filename || !strlen(filename)) return;
135    
136 harbaum 1 char *key = g_strdup_printf(GCONF_KEY_CLOSED, get_basename(filename));
137     gconf_client_set_string(appdata->gconf_client, key, name, NULL);
138     g_free(key);
139     }
140    
141     char *gconf_restore_closed_name(appdata_t *appdata, char *filename) {
142 harbaum 211 if(!filename || !strlen(filename)) return NULL;
143    
144 harbaum 1 char *key = g_strdup_printf(GCONF_KEY_CLOSED, get_basename(filename));
145     char *ret = gconf_client_get_string(appdata->gconf_client, key, NULL);
146     g_free(key);
147     return ret;
148     }
149    
150     void gconf_save_state(appdata_t *appdata) {
151     int entries = 0;
152    
153 harbaum 221 printf("saving gconf state\n");
154    
155 harbaum 158 /* free proxy settings */
156     if(appdata->proxy) {
157     proxy_t *proxy = appdata->proxy;
158    
159     if(proxy->authentication_password) g_free(proxy->authentication_password);
160     if(proxy->authentication_user) g_free(proxy->authentication_user);
161     if(proxy->host) g_free(proxy->host);
162     if(proxy->ignore_hosts) g_free(proxy->ignore_hosts);
163    
164     g_free(proxy);
165     appdata->proxy = NULL;
166     }
167    
168 harbaum 1 gpx_t *gpx = appdata->gpx;
169     while(gpx) {
170     char str[128];
171     snprintf(str, sizeof(str), GCONF_KEY_GPX, entries++);
172     gconf_client_set_string(appdata->gconf_client, str, gpx->filename, NULL);
173     gpx = gpx->next;
174     }
175    
176     gconf_client_set_int(appdata->gconf_client, GCONF_KEY_CNT, entries, NULL);
177    
178     /* -------------- save locations (excl. home location) --------------- */
179     entries = 0;
180     location_t *loc = appdata->location;
181     while(loc) {
182     char str[128];
183     snprintf(str, sizeof(str), GCONF_KEY_LOC_NAME, entries);
184     gconf_client_set_string(appdata->gconf_client, str, loc->name, NULL);
185     snprintf(str, sizeof(str), GCONF_KEY_LOC_LAT, entries);
186     gconf_client_set_float(appdata->gconf_client, str, loc->pos.lat, NULL);
187     snprintf(str, sizeof(str), GCONF_KEY_LOC_LON, entries);
188     gconf_client_set_float(appdata->gconf_client, str, loc->pos.lon, NULL);
189     entries++;
190     loc = loc->next;
191     }
192    
193     gconf_client_set_int(appdata->gconf_client, GCONF_KEY_LOC_CNT, entries, NULL);
194    
195     /* store everything listed in the store table */
196     store_t *st = store;
197     while(st->key) {
198     void **ptr = ((void*)appdata) + st->offset;
199 harbaum 34 char *key = g_strdup_printf(GCONF_PATH "%s", st->key);
200 harbaum 1
201     switch(st->type) {
202     case STORE_STRING:
203     if((char*)(*ptr)) {
204     gconf_client_set_string(appdata->gconf_client, key, (char*)(*ptr), NULL);
205     }
206 harbaum 196 g_free((char*)(*ptr));
207     *ptr = NULL;
208 harbaum 1 break;
209    
210     case STORE_BOOL:
211     gconf_client_set_bool(appdata->gconf_client, key, *((int*)ptr), NULL);
212     break;
213    
214     case STORE_INT:
215     gconf_client_set_int(appdata->gconf_client, key, *((int*)ptr), NULL);
216     break;
217    
218     case STORE_FLOAT:
219 harbaum 34 if(!isnan(*((float*)ptr)))
220     gconf_client_set_float(appdata->gconf_client, key, *((float*)ptr), NULL);
221 harbaum 1 break;
222    
223     default:
224     printf("Unsupported type %d\n", st->type);
225     break;
226     }
227    
228 harbaum 34 g_free(key);
229 harbaum 1 st++;
230     }
231     }
232    
233     void gconf_load_state(appdata_t *appdata) {
234     gpx_t **gpx = &appdata->gpx;
235    
236     while(*gpx) gpx = &((*gpx)->next);
237    
238     gpx_dialog_t *dialog = NULL;
239    
240 harbaum 34 /* default positions are invalid */
241     appdata->home.lat = appdata->home.lon = NAN;
242     appdata->gps.lat = appdata->gps.lon = NAN;
243 harbaum 220 appdata->geomath.lat = appdata->geomath.lon = NAN;
244 harbaum 34
245 harbaum 196 appdata->gt.lat = appdata->gt.lon = NAN;
246 harbaum 198 appdata->gt.distance = 1.0; // in km/mil
247 harbaum 196
248 harbaum 158 /* ------------- get proxy settings -------------------- */
249     if(gconf_client_get_bool(appdata->gconf_client,
250     PROXY_KEY "use_http_proxy", NULL)) {
251     proxy_t *proxy = appdata->proxy = g_new0(proxy_t, 1);
252    
253     /* get basic settings */
254     proxy->host = gconf_client_get_string(appdata->gconf_client,
255     PROXY_KEY "host", NULL);
256     proxy->port = gconf_client_get_int(appdata->gconf_client,
257     PROXY_KEY "port", NULL);
258     proxy->ignore_hosts =
259     gconf_client_get_string(appdata->gconf_client,
260     PROXY_KEY "ignore_hosts", NULL);
261    
262     /* check for authentication */
263     proxy->use_authentication =
264     gconf_client_get_bool(appdata->gconf_client,
265     PROXY_KEY "use_authentication", NULL);
266    
267     if(proxy->use_authentication) {
268     proxy->authentication_user =
269     gconf_client_get_string(appdata->gconf_client,
270     PROXY_KEY "authentication_user", NULL);
271     proxy->authentication_password =
272     gconf_client_get_string(appdata->gconf_client,
273     PROXY_KEY "authentication_password", NULL);
274     }
275     }
276    
277 harbaum 204 /* restore everything listed in the store table */
278     store_t *st = store;
279     while(st->key) {
280     void **ptr = ((void*)appdata) + st->offset;
281     char *key = g_strdup_printf(GCONF_PATH "%s", st->key);
282    
283     /* check if key is present */
284     GConfValue *value = gconf_client_get(appdata->gconf_client, key, NULL);
285     if(value) {
286     gconf_value_free(value);
287    
288     switch(st->type) {
289     case STORE_STRING: {
290     char **str = (char**)ptr;
291     *str = gconf_client_get_string(appdata->gconf_client, key, NULL);
292     } break;
293    
294     case STORE_BOOL:
295     *((int*)ptr) = gconf_client_get_bool(appdata->gconf_client, key, NULL);
296     break;
297    
298     case STORE_INT:
299     *((int*)ptr) = gconf_client_get_int(appdata->gconf_client, key, NULL);
300     break;
301    
302     case STORE_FLOAT:
303     *((float*)ptr) = gconf_client_get_float(appdata->gconf_client, key, NULL);
304     break;
305    
306     default:
307     printf("Unsupported type %d\n", st->type);
308     break;
309     }
310     }
311     g_free(key);
312     st++;
313     }
314    
315 harbaum 1 int i, entries = gconf_client_get_int(appdata->gconf_client,
316     GCONF_KEY_CNT, NULL);
317    
318     if(entries)
319     dialog = gpx_busy_dialog_new(GTK_WIDGET(appdata->window));
320    
321     for(i=0;i<entries;i++) {
322     char str[128];
323     snprintf(str, sizeof(str), GCONF_KEY_GPX, i);
324     char *fname = gconf_client_get_string(appdata->gconf_client, str, NULL);
325     if(fname) {
326     /* check if there's a valid name stored for this file. */
327     /* if yes it's a "closed" file */
328     char *name = gconf_restore_closed_name(appdata, fname);
329     if(name) {
330     *gpx = g_new0(gpx_t, 1);
331     (*gpx)->filename = fname;
332     (*gpx)->name = g_strdup(name);
333     (*gpx)->closed = TRUE;
334     } else {
335     if(g_file_test(fname, G_FILE_TEST_IS_DIR))
336 harbaum 204 *gpx = gpx_parse_dir(dialog, fname, appdata->username);
337 harbaum 1 else
338 harbaum 204 *gpx = gpx_parse(dialog, fname, appdata->username);
339 harbaum 1
340 harbaum 74 if(!*gpx) {
341     /* restoring the gpx file failed, mark it as unusable, but save */
342     /* its presence for later use */
343    
344 harbaum 113 /* create "closed" entry to remember this file for next */
345     /* load attempt */
346 harbaum 74 *gpx = g_new0(gpx_t, 1);
347     (*gpx)->filename = fname;
348 harbaum 113 char *p = fname;
349     if(strrchr(fname, '/'))
350     p = strrchr(fname, '/')+1;
351    
352     (*gpx)->name = g_strdup_printf(_("Failed to load: %s"), p);
353     (*gpx)->closed = TRUE;
354 harbaum 74 } else
355     free(fname);
356 harbaum 1 }
357 harbaum 103 gpx = &((*gpx)->next);
358 harbaum 1 }
359     }
360    
361     gpx_busy_dialog_destroy(dialog);
362    
363     /* ------------- load locations --------------------- */
364     entries = gconf_client_get_int(appdata->gconf_client,
365     GCONF_KEY_LOC_CNT, NULL);
366    
367     location_t **loc = &appdata->location;
368     for(i=0;i<entries;i++) {
369     *loc = g_new0(location_t, 1);
370     if(*loc) {
371     char str[128];
372     snprintf(str, sizeof(str), GCONF_KEY_LOC_NAME, i);
373     (*loc)->name = gconf_client_get_string(appdata->gconf_client, str, NULL);
374     snprintf(str, sizeof(str), GCONF_KEY_LOC_LAT, i);
375     (*loc)->pos.lat = gconf_client_get_float(appdata->gconf_client, str, NULL);
376     snprintf(str, sizeof(str), GCONF_KEY_LOC_LON, i);
377     (*loc)->pos.lon = gconf_client_get_float(appdata->gconf_client, str, NULL);
378    
379     loc = &((*loc)->next);
380     }
381     }
382    
383     /* ----- set all kinds of defaults ------- */
384    
385     if(!appdata->compass_damping) appdata->compass_damping = 1;
386    
387     if(!appdata->mmpoi_radius)
388     appdata->mmpoi_radius = 100.0; // 100 km
389    
390     if(!appdata->search)
391     appdata->search = SEARCH_NAME | SEARCH_ID;
392    
393     if(!appdata->image_path) {
394 harbaum 122 #ifdef USE_MAEMO
395     /* update cachelist by default */
396     appdata->cachelist_update = TRUE;
397     #endif
398 harbaum 1
399 harbaum 14 /* use gps by default */
400     appdata->use_gps = TRUE;
401    
402 harbaum 1 #ifndef USE_MAEMO
403     char *p = getenv("HOME");
404     if(p) {
405     /* build image path in home directory */
406     appdata->image_path =
407     malloc(strlen(p)+strlen(DEFAULT_IMAGE_PATH_HOME)+2);
408     strcpy(appdata->image_path, p);
409     if(appdata->image_path[strlen(appdata->image_path)-1] != '/')
410     strcat(appdata->image_path, "/");
411     strcat(appdata->image_path, DEFAULT_IMAGE_PATH_HOME);
412     } else
413     #endif
414     appdata->image_path = strdup(DEFAULT_IMAGE_PATH);
415    
416 harbaum 62 /* check if this path is actually accessible */
417     /* and change it to the current users home if not */
418     /* (this should only happen on scratchbox) */
419     if(!g_file_test(appdata->image_path, G_FILE_TEST_IS_DIR)) {
420     if(g_mkdir_with_parents(appdata->image_path, 0700) != 0) {
421     char *p = getenv("HOME");
422     if(!p) p = "/tmp/";
423    
424     appdata->image_path =
425     g_strdup_printf("%s%s%s", p,
426     (p[strlen(p)-1]!='/')?"/":"",
427     DEFAULT_IMAGE_PATH_HOME);
428     printf("using alt path %s\n", appdata->image_path);
429     }
430     }
431    
432 harbaum 1 } else {
433     /* some versions old versions messed up the path */
434     if(appdata->image_path[strlen(appdata->image_path)-1] != '/') {
435     printf("adjusting image path\n");
436     appdata->image_path = realloc(appdata->image_path,
437     strlen(appdata->image_path)+2);
438     strcat(appdata->image_path, "/");
439     }
440     }
441    
442     if(!appdata->mmpoi_path) {
443     char *p = getenv("HOME");
444     if(p) {
445     /* build mmpoi path in home directory */
446     appdata->mmpoi_path =
447     malloc(strlen(p)+strlen(DEFAULT_MMPOI_PATH)+2);
448     strcpy(appdata->mmpoi_path, p);
449     if(appdata->mmpoi_path[strlen(appdata->mmpoi_path)-1] != '/')
450     strcat(appdata->mmpoi_path, "/");
451     strcat(appdata->mmpoi_path, DEFAULT_MMPOI_PATH);
452     } else
453     appdata->mmpoi_path = strdup(DEFAULT_MMPOI_PATH);
454     }
455    
456     if(!appdata->fieldnotes_path) {
457     char *p = getenv("HOME");
458     if(p) {
459     /* build fieldnotes path in home directory */
460     appdata->fieldnotes_path =
461     malloc(strlen(p)+strlen(DEFAULT_FIELDNOTES_PATH)+2);
462     strcpy(appdata->fieldnotes_path, p);
463     if(appdata->fieldnotes_path[strlen(appdata->fieldnotes_path)-1] != '/')
464     strcat(appdata->fieldnotes_path, "/");
465     strcat(appdata->fieldnotes_path, DEFAULT_FIELDNOTES_PATH);
466     } else
467     appdata->fieldnotes_path = strdup(DEFAULT_FIELDNOTES_PATH);
468     }
469    
470     if(!appdata->garmin_path) {
471     char *p = getenv("HOME");
472     if(p) {
473     /* build image path in home directory */
474     appdata->garmin_path =
475     malloc(strlen(p)+strlen(DEFAULT_GARMIN_PATH)+2);
476     strcpy(appdata->garmin_path, p);
477     if(appdata->garmin_path[strlen(appdata->garmin_path)-1] != '/')
478     strcat(appdata->garmin_path, "/");
479     strcat(appdata->garmin_path, DEFAULT_GARMIN_PATH);
480     } else
481     appdata->garmin_path = strdup(DEFAULT_GARMIN_PATH);
482     }
483    
484     /* make sure image path actually exists */
485     checkdir(appdata->image_path);
486    
487     if(!appdata->gpxlist_items)
488     appdata->gpxlist_items = GPXLIST_ITEM_DEFAULT;
489    
490     if(!appdata->cachelist_items)
491     appdata->cachelist_items = CACHELIST_ITEM_DEFAULT;
492    
493 harbaum 13 /* if there are no entries in the main list, try to add the */
494     /* "welcome" one */
495     if(!appdata->gpx) {
496 harbaum 17 char *name = g_strdup(ICONPATH "welcome.gpx");
497 harbaum 13 dialog = gpx_busy_dialog_new(GTK_WIDGET(appdata->window));
498     printf("No GPX file loaded, trying to load demo\n");
499 harbaum 204 appdata->gpx = gpx_parse(dialog, name, appdata->username);
500 harbaum 13 gpx_busy_dialog_destroy(dialog);
501     g_free(name);
502     }
503 harbaum 1 }
504