Contents of /trunk/src/gconf.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 167 - (hide annotations)
Mon Nov 9 07:50:37 2009 UTC (14 years, 6 months ago) by harbaum
File MIME type: text/plain
File size: 15601 byte(s)
Various fine tuning
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     { "manual_goto_lat", STORE_FLOAT, OFFSET(manual_goto.lat) },
71     { "manual_goto_lon", STORE_FLOAT, OFFSET(manual_goto.lon) },
72     { "gps_lat", STORE_FLOAT, OFFSET(gps.lat) },
73     { "gps_lon", STORE_FLOAT, OFFSET(gps.lon) },
74     { "search_in", STORE_INT, OFFSET(search) },
75     { "search_days", STORE_INT, OFFSET(search_days) },
76     { "search_str", STORE_STRING, OFFSET(search_str) },
77     { "gpxlist_items", STORE_INT, OFFSET(gpxlist_items) },
78     { "cachelist_items", STORE_INT, OFFSET(cachelist_items) },
79     { "compass_damping", STORE_INT, OFFSET(compass_damping) },
80     { "cachelist_hide_found", STORE_BOOL, OFFSET(cachelist_hide_found) },
81 harbaum 129 { "cachelist_update", STORE_BOOL, OFFSET(cachelist_update) },
82 harbaum 167 { "disable_gcvote", STORE_BOOL, OFFSET(disable_gcvote) },
83 harbaum 1 #ifdef USE_MAEMO
84     { "mmpoi_dontlaunch", STORE_BOOL, OFFSET(mmpoi_dontlaunch) },
85     { "cachelist_dss", STORE_BOOL, OFFSET(cachelist_disable_screensaver) },
86     { "goto_dss", STORE_BOOL, OFFSET(goto_disable_screensaver) },
87     #endif
88 harbaum 48 #ifdef ENABLE_OSM_GPS_MAP
89     { "map_lat", STORE_FLOAT, OFFSET(map.pos.lat) },
90     { "map_lon", STORE_FLOAT, OFFSET(map.pos.lon) },
91     { "map_zoom", STORE_INT, OFFSET(map.zoom) },
92 harbaum 89 { "map_source", STORE_INT, OFFSET(map.source) },
93 harbaum 48 #endif
94 harbaum 1 { NULL, -1, -1 }
95     };
96    
97     static char *get_basename(char *name) {
98     char *p = strrchr(name, '/');
99     if(!p) p = name;
100     else p = p+1;
101    
102     g_assert(*p);
103    
104     /* escape all non alnum characters */
105     p = g_strdup(p);
106     int i;
107     for(i=0;i<strlen(p);i++)
108     if(!isalnum(p[i]))
109     p[i] = '_';
110    
111     return p;
112     }
113    
114     void gconf_remove_closed_name(appdata_t *appdata, char *filename) {
115     char *key = g_strdup_printf(GCONF_KEY_CLOSED, get_basename(filename));
116     gconf_client_unset(appdata->gconf_client, key, NULL);
117     g_free(key);
118     }
119    
120     void gconf_save_closed_name(appdata_t *appdata, char *filename, char *name) {
121     char *key = g_strdup_printf(GCONF_KEY_CLOSED, get_basename(filename));
122     gconf_client_set_string(appdata->gconf_client, key, name, NULL);
123     g_free(key);
124     }
125    
126     char *gconf_restore_closed_name(appdata_t *appdata, char *filename) {
127     char *key = g_strdup_printf(GCONF_KEY_CLOSED, get_basename(filename));
128     char *ret = gconf_client_get_string(appdata->gconf_client, key, NULL);
129     g_free(key);
130     return ret;
131     }
132    
133     void gconf_save_state(appdata_t *appdata) {
134     int entries = 0;
135    
136 harbaum 158 /* free proxy settings */
137     if(appdata->proxy) {
138     proxy_t *proxy = appdata->proxy;
139    
140     if(proxy->authentication_password) g_free(proxy->authentication_password);
141     if(proxy->authentication_user) g_free(proxy->authentication_user);
142     if(proxy->host) g_free(proxy->host);
143     if(proxy->ignore_hosts) g_free(proxy->ignore_hosts);
144    
145     g_free(proxy);
146     appdata->proxy = NULL;
147     }
148    
149 harbaum 1 gpx_t *gpx = appdata->gpx;
150     while(gpx) {
151     char str[128];
152     snprintf(str, sizeof(str), GCONF_KEY_GPX, entries++);
153     gconf_client_set_string(appdata->gconf_client, str, gpx->filename, NULL);
154     gpx = gpx->next;
155     }
156    
157     gconf_client_set_int(appdata->gconf_client, GCONF_KEY_CNT, entries, NULL);
158    
159     /* -------------- save locations (excl. home location) --------------- */
160     entries = 0;
161     location_t *loc = appdata->location;
162     while(loc) {
163     char str[128];
164     snprintf(str, sizeof(str), GCONF_KEY_LOC_NAME, entries);
165     gconf_client_set_string(appdata->gconf_client, str, loc->name, NULL);
166     snprintf(str, sizeof(str), GCONF_KEY_LOC_LAT, entries);
167     gconf_client_set_float(appdata->gconf_client, str, loc->pos.lat, NULL);
168     snprintf(str, sizeof(str), GCONF_KEY_LOC_LON, entries);
169     gconf_client_set_float(appdata->gconf_client, str, loc->pos.lon, NULL);
170     entries++;
171     loc = loc->next;
172     }
173    
174     gconf_client_set_int(appdata->gconf_client, GCONF_KEY_LOC_CNT, entries, NULL);
175    
176     /* store everything listed in the store table */
177     store_t *st = store;
178     while(st->key) {
179     void **ptr = ((void*)appdata) + st->offset;
180 harbaum 34 char *key = g_strdup_printf(GCONF_PATH "%s", st->key);
181 harbaum 1
182     switch(st->type) {
183     case STORE_STRING:
184     if((char*)(*ptr)) {
185     gconf_client_set_string(appdata->gconf_client, key, (char*)(*ptr), NULL);
186     }
187     break;
188    
189     case STORE_BOOL:
190     gconf_client_set_bool(appdata->gconf_client, key, *((int*)ptr), NULL);
191     break;
192    
193     case STORE_INT:
194     gconf_client_set_int(appdata->gconf_client, key, *((int*)ptr), NULL);
195     break;
196    
197     case STORE_FLOAT:
198 harbaum 34 if(!isnan(*((float*)ptr)))
199     gconf_client_set_float(appdata->gconf_client, key, *((float*)ptr), NULL);
200 harbaum 1 break;
201    
202     default:
203     printf("Unsupported type %d\n", st->type);
204     break;
205     }
206    
207 harbaum 34 g_free(key);
208 harbaum 1 st++;
209     }
210     }
211    
212     void gconf_load_state(appdata_t *appdata) {
213     gpx_t **gpx = &appdata->gpx;
214    
215     while(*gpx) gpx = &((*gpx)->next);
216    
217     gpx_dialog_t *dialog = NULL;
218    
219 harbaum 34 /* default positions are invalid */
220     appdata->home.lat = appdata->home.lon = NAN;
221     appdata->manual_goto.lat = appdata->manual_goto.lon = NAN;
222     appdata->gps.lat = appdata->gps.lon = NAN;
223    
224 harbaum 158 /* ------------- get proxy settings -------------------- */
225     if(gconf_client_get_bool(appdata->gconf_client,
226     PROXY_KEY "use_http_proxy", NULL)) {
227     proxy_t *proxy = appdata->proxy = g_new0(proxy_t, 1);
228    
229     /* get basic settings */
230     proxy->host = gconf_client_get_string(appdata->gconf_client,
231     PROXY_KEY "host", NULL);
232     proxy->port = gconf_client_get_int(appdata->gconf_client,
233     PROXY_KEY "port", NULL);
234     proxy->ignore_hosts =
235     gconf_client_get_string(appdata->gconf_client,
236     PROXY_KEY "ignore_hosts", NULL);
237    
238     /* check for authentication */
239     proxy->use_authentication =
240     gconf_client_get_bool(appdata->gconf_client,
241     PROXY_KEY "use_authentication", NULL);
242    
243     if(proxy->use_authentication) {
244     proxy->authentication_user =
245     gconf_client_get_string(appdata->gconf_client,
246     PROXY_KEY "authentication_user", NULL);
247     proxy->authentication_password =
248     gconf_client_get_string(appdata->gconf_client,
249     PROXY_KEY "authentication_password", NULL);
250     }
251     }
252    
253 harbaum 1 int i, entries = gconf_client_get_int(appdata->gconf_client,
254     GCONF_KEY_CNT, NULL);
255    
256     if(entries)
257     dialog = gpx_busy_dialog_new(GTK_WIDGET(appdata->window));
258    
259     for(i=0;i<entries;i++) {
260     char str[128];
261     snprintf(str, sizeof(str), GCONF_KEY_GPX, i);
262     char *fname = gconf_client_get_string(appdata->gconf_client, str, NULL);
263     if(fname) {
264     /* check if there's a valid name stored for this file. */
265     /* if yes it's a "closed" file */
266     char *name = gconf_restore_closed_name(appdata, fname);
267     if(name) {
268     *gpx = g_new0(gpx_t, 1);
269     (*gpx)->filename = fname;
270     (*gpx)->name = g_strdup(name);
271     (*gpx)->closed = TRUE;
272     } else {
273     if(g_file_test(fname, G_FILE_TEST_IS_DIR))
274     *gpx = gpx_parse_dir(dialog, fname);
275     else
276     *gpx = gpx_parse(dialog, fname);
277    
278 harbaum 74 if(!*gpx) {
279     /* restoring the gpx file failed, mark it as unusable, but save */
280     /* its presence for later use */
281    
282 harbaum 113 /* create "closed" entry to remember this file for next */
283     /* load attempt */
284 harbaum 74 *gpx = g_new0(gpx_t, 1);
285     (*gpx)->filename = fname;
286 harbaum 113 char *p = fname;
287     if(strrchr(fname, '/'))
288     p = strrchr(fname, '/')+1;
289    
290     (*gpx)->name = g_strdup_printf(_("Failed to load: %s"), p);
291     (*gpx)->closed = TRUE;
292 harbaum 74 } else
293     free(fname);
294 harbaum 1 }
295 harbaum 103 gpx = &((*gpx)->next);
296 harbaum 1 }
297     }
298    
299     gpx_busy_dialog_destroy(dialog);
300    
301     /* ------------- load locations --------------------- */
302     entries = gconf_client_get_int(appdata->gconf_client,
303     GCONF_KEY_LOC_CNT, NULL);
304    
305     location_t **loc = &appdata->location;
306     for(i=0;i<entries;i++) {
307     *loc = g_new0(location_t, 1);
308     if(*loc) {
309     char str[128];
310     snprintf(str, sizeof(str), GCONF_KEY_LOC_NAME, i);
311     (*loc)->name = gconf_client_get_string(appdata->gconf_client, str, NULL);
312     snprintf(str, sizeof(str), GCONF_KEY_LOC_LAT, i);
313     (*loc)->pos.lat = gconf_client_get_float(appdata->gconf_client, str, NULL);
314     snprintf(str, sizeof(str), GCONF_KEY_LOC_LON, i);
315     (*loc)->pos.lon = gconf_client_get_float(appdata->gconf_client, str, NULL);
316    
317     loc = &((*loc)->next);
318     }
319     }
320    
321     /* restore everything listed in the store table */
322     store_t *st = store;
323     while(st->key) {
324     void **ptr = ((void*)appdata) + st->offset;
325 harbaum 34 char *key = g_strdup_printf(GCONF_PATH "%s", st->key);
326 harbaum 1
327 harbaum 34 /* check if key is present */
328     GConfValue *value = gconf_client_get(appdata->gconf_client, key, NULL);
329     if(value) {
330     gconf_value_free(value);
331    
332     switch(st->type) {
333     case STORE_STRING: {
334     char **str = (char**)ptr;
335     *str = gconf_client_get_string(appdata->gconf_client, key, NULL);
336 harbaum 1 } break;
337 harbaum 34
338     case STORE_BOOL:
339     *((int*)ptr) = gconf_client_get_bool(appdata->gconf_client, key, NULL);
340     break;
341    
342     case STORE_INT:
343     *((int*)ptr) = gconf_client_get_int(appdata->gconf_client, key, NULL);
344     break;
345    
346     case STORE_FLOAT:
347     *((float*)ptr) = gconf_client_get_float(appdata->gconf_client, key, NULL);
348     break;
349    
350     default:
351     printf("Unsupported type %d\n", st->type);
352     break;
353     }
354 harbaum 1 }
355 harbaum 34 g_free(key);
356 harbaum 1 st++;
357     }
358    
359     /* ----- set all kinds of defaults ------- */
360    
361     if(!appdata->compass_damping) appdata->compass_damping = 1;
362    
363     if(!appdata->mmpoi_radius)
364     appdata->mmpoi_radius = 100.0; // 100 km
365    
366     if(!appdata->search)
367     appdata->search = SEARCH_NAME | SEARCH_ID;
368    
369     if(!appdata->image_path) {
370 harbaum 122 #ifdef USE_MAEMO
371     /* update cachelist by default */
372     appdata->cachelist_update = TRUE;
373     #endif
374 harbaum 1
375 harbaum 14 /* use gps by default */
376     appdata->use_gps = TRUE;
377    
378 harbaum 1 #ifndef USE_MAEMO
379     char *p = getenv("HOME");
380     if(p) {
381     /* build image path in home directory */
382     appdata->image_path =
383     malloc(strlen(p)+strlen(DEFAULT_IMAGE_PATH_HOME)+2);
384     strcpy(appdata->image_path, p);
385     if(appdata->image_path[strlen(appdata->image_path)-1] != '/')
386     strcat(appdata->image_path, "/");
387     strcat(appdata->image_path, DEFAULT_IMAGE_PATH_HOME);
388     } else
389     #endif
390     appdata->image_path = strdup(DEFAULT_IMAGE_PATH);
391    
392 harbaum 62 /* check if this path is actually accessible */
393     /* and change it to the current users home if not */
394     /* (this should only happen on scratchbox) */
395     if(!g_file_test(appdata->image_path, G_FILE_TEST_IS_DIR)) {
396     if(g_mkdir_with_parents(appdata->image_path, 0700) != 0) {
397     char *p = getenv("HOME");
398     if(!p) p = "/tmp/";
399    
400     appdata->image_path =
401     g_strdup_printf("%s%s%s", p,
402     (p[strlen(p)-1]!='/')?"/":"",
403     DEFAULT_IMAGE_PATH_HOME);
404     printf("using alt path %s\n", appdata->image_path);
405     }
406     }
407    
408 harbaum 1 } else {
409     /* some versions old versions messed up the path */
410     if(appdata->image_path[strlen(appdata->image_path)-1] != '/') {
411     printf("adjusting image path\n");
412     appdata->image_path = realloc(appdata->image_path,
413     strlen(appdata->image_path)+2);
414     strcat(appdata->image_path, "/");
415     }
416     }
417    
418     if(!appdata->mmpoi_path) {
419     char *p = getenv("HOME");
420     if(p) {
421     /* build mmpoi path in home directory */
422     appdata->mmpoi_path =
423     malloc(strlen(p)+strlen(DEFAULT_MMPOI_PATH)+2);
424     strcpy(appdata->mmpoi_path, p);
425     if(appdata->mmpoi_path[strlen(appdata->mmpoi_path)-1] != '/')
426     strcat(appdata->mmpoi_path, "/");
427     strcat(appdata->mmpoi_path, DEFAULT_MMPOI_PATH);
428     } else
429     appdata->mmpoi_path = strdup(DEFAULT_MMPOI_PATH);
430     }
431    
432     if(!appdata->fieldnotes_path) {
433     char *p = getenv("HOME");
434     if(p) {
435     /* build fieldnotes path in home directory */
436     appdata->fieldnotes_path =
437     malloc(strlen(p)+strlen(DEFAULT_FIELDNOTES_PATH)+2);
438     strcpy(appdata->fieldnotes_path, p);
439     if(appdata->fieldnotes_path[strlen(appdata->fieldnotes_path)-1] != '/')
440     strcat(appdata->fieldnotes_path, "/");
441     strcat(appdata->fieldnotes_path, DEFAULT_FIELDNOTES_PATH);
442     } else
443     appdata->fieldnotes_path = strdup(DEFAULT_FIELDNOTES_PATH);
444     }
445    
446     if(!appdata->garmin_path) {
447     char *p = getenv("HOME");
448     if(p) {
449     /* build image path in home directory */
450     appdata->garmin_path =
451     malloc(strlen(p)+strlen(DEFAULT_GARMIN_PATH)+2);
452     strcpy(appdata->garmin_path, p);
453     if(appdata->garmin_path[strlen(appdata->garmin_path)-1] != '/')
454     strcat(appdata->garmin_path, "/");
455     strcat(appdata->garmin_path, DEFAULT_GARMIN_PATH);
456     } else
457     appdata->garmin_path = strdup(DEFAULT_GARMIN_PATH);
458     }
459    
460     /* make sure image path actually exists */
461     checkdir(appdata->image_path);
462    
463     if(!appdata->gpxlist_items)
464     appdata->gpxlist_items = GPXLIST_ITEM_DEFAULT;
465    
466     if(!appdata->cachelist_items)
467     appdata->cachelist_items = CACHELIST_ITEM_DEFAULT;
468    
469 harbaum 13 /* if there are no entries in the main list, try to add the */
470     /* "welcome" one */
471     if(!appdata->gpx) {
472 harbaum 17 char *name = g_strdup(ICONPATH "welcome.gpx");
473 harbaum 13 dialog = gpx_busy_dialog_new(GTK_WIDGET(appdata->window));
474     printf("No GPX file loaded, trying to load demo\n");
475     appdata->gpx = gpx_parse(dialog, name);
476     gpx_busy_dialog_destroy(dialog);
477     g_free(name);
478     }
479 harbaum 1 }
480