Contents of /trunk/src/gconf.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Sat Jun 20 11:08:47 2009 UTC (14 years, 11 months ago) by harbaum
File MIME type: text/plain
File size: 12603 byte(s)
Initial import
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     #include "gpxview.h"
24    
25     #define GCONF_PATH "/apps/gpxview/"
26     #define GCONF_KEY_GPX GCONF_PATH "gpx%d"
27     #define GCONF_KEY_CNT GCONF_PATH "entries"
28    
29     #define GCONF_KEY_LOC_NAME GCONF_PATH "location%d/name"
30     #define GCONF_KEY_LOC_LAT GCONF_PATH "location%d/latitude"
31     #define GCONF_KEY_LOC_LON GCONF_PATH "location%d/longitude"
32     #define GCONF_KEY_LOC_CNT GCONF_PATH "location_entries"
33    
34     #define GCONF_KEY_CLOSED GCONF_PATH "closed/%s"
35    
36     #include <string.h>
37    
38     enum {
39     STORE_STRING, STORE_FLOAT, STORE_INT, STORE_BOOL,
40     };
41    
42     typedef struct {
43     char *key;
44     int type;
45     int offset;
46     } store_t;
47    
48     #define OFFSET(a) offsetof(appdata_t, a)
49    
50     static store_t store[] = {
51     { "image_path", STORE_STRING, OFFSET(image_path) },
52     { "path", STORE_STRING, OFFSET(path) },
53     { "geotext/text", STORE_STRING, OFFSET(geotext_text) },
54     { "geotext/shift", STORE_INT, OFFSET(geotext_shift) },
55     { "mmpoi_path", STORE_STRING, OFFSET(mmpoi_path) },
56     { "garmin_path", STORE_STRING, OFFSET(garmin_path) },
57     { "fnotes_path", STORE_STRING, OFFSET(fieldnotes_path) },
58     { "garmin_ign_found", STORE_BOOL, OFFSET(garmin_ign_found) },
59     { "active_location", STORE_INT, OFFSET(active_location) },
60     { "mmpoi_use_radius", STORE_BOOL, OFFSET(mmpoi_use_radius) },
61     { "mmpoi_radius", STORE_FLOAT, OFFSET(mmpoi_radius) },
62     { "mmpoi_ign_found", STORE_BOOL, OFFSET(mmpoi_dont_export_found) },
63     { "mmpoi_ign_disabl", STORE_BOOL, OFFSET(mmpoi_dont_export_disabled) },
64     { "use_gps", STORE_BOOL, OFFSET(use_gps) },
65     { "imperial", STORE_BOOL, OFFSET(imperial) },
66     { "compass_locked", STORE_BOOL, OFFSET(compass_locked) },
67     { "latitude", STORE_FLOAT, OFFSET(home.lat) },
68     { "longitude", STORE_FLOAT, OFFSET(home.lon) },
69     { "manual_goto_lat", STORE_FLOAT, OFFSET(manual_goto.lat) },
70     { "manual_goto_lon", STORE_FLOAT, OFFSET(manual_goto.lon) },
71     { "gps_lat", STORE_FLOAT, OFFSET(gps.lat) },
72     { "gps_lon", STORE_FLOAT, OFFSET(gps.lon) },
73     { "load_images", STORE_BOOL, OFFSET(load_images) },
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     #ifdef USE_MAEMO
82     { "mmpoi_dontlaunch", STORE_BOOL, OFFSET(mmpoi_dontlaunch) },
83     { "cachelist_dss", STORE_BOOL, OFFSET(cachelist_disable_screensaver) },
84     { "goto_dss", STORE_BOOL, OFFSET(goto_disable_screensaver) },
85     { "cachelist_update", STORE_BOOL, OFFSET(cachelist_update) },
86     #endif
87    
88     { NULL, -1, -1 }
89     };
90    
91     static char *get_basename(char *name) {
92     char *p = strrchr(name, '/');
93     if(!p) p = name;
94     else p = p+1;
95    
96     g_assert(*p);
97    
98     /* escape all non alnum characters */
99     p = g_strdup(p);
100     int i;
101     for(i=0;i<strlen(p);i++)
102     if(!isalnum(p[i]))
103     p[i] = '_';
104    
105     return p;
106     }
107    
108     void gconf_remove_closed_name(appdata_t *appdata, char *filename) {
109     char *key = g_strdup_printf(GCONF_KEY_CLOSED, get_basename(filename));
110     gconf_client_unset(appdata->gconf_client, key, NULL);
111     g_free(key);
112     }
113    
114     void gconf_save_closed_name(appdata_t *appdata, char *filename, char *name) {
115     char *key = g_strdup_printf(GCONF_KEY_CLOSED, get_basename(filename));
116     gconf_client_set_string(appdata->gconf_client, key, name, NULL);
117     g_free(key);
118     }
119    
120     char *gconf_restore_closed_name(appdata_t *appdata, char *filename) {
121     char *key = g_strdup_printf(GCONF_KEY_CLOSED, get_basename(filename));
122     char *ret = gconf_client_get_string(appdata->gconf_client, key, NULL);
123     g_free(key);
124     return ret;
125     }
126    
127     void gconf_save_state(appdata_t *appdata) {
128     int entries = 0;
129    
130     gpx_t *gpx = appdata->gpx;
131     while(gpx) {
132     char str[128];
133     snprintf(str, sizeof(str), GCONF_KEY_GPX, entries++);
134     gconf_client_set_string(appdata->gconf_client, str, gpx->filename, NULL);
135     gpx = gpx->next;
136     }
137    
138     gconf_client_set_int(appdata->gconf_client, GCONF_KEY_CNT, entries, NULL);
139    
140     /* -------------- save locations (excl. home location) --------------- */
141     entries = 0;
142     location_t *loc = appdata->location;
143     while(loc) {
144     char str[128];
145     snprintf(str, sizeof(str), GCONF_KEY_LOC_NAME, entries);
146     gconf_client_set_string(appdata->gconf_client, str, loc->name, NULL);
147     snprintf(str, sizeof(str), GCONF_KEY_LOC_LAT, entries);
148     gconf_client_set_float(appdata->gconf_client, str, loc->pos.lat, NULL);
149     snprintf(str, sizeof(str), GCONF_KEY_LOC_LON, entries);
150     gconf_client_set_float(appdata->gconf_client, str, loc->pos.lon, NULL);
151     entries++;
152     loc = loc->next;
153     }
154    
155     gconf_client_set_int(appdata->gconf_client, GCONF_KEY_LOC_CNT, entries, NULL);
156    
157     /* store everything listed in the store table */
158     store_t *st = store;
159     while(st->key) {
160     char key[256];
161     void **ptr = ((void*)appdata) + st->offset;
162     snprintf(key, sizeof(key), GCONF_PATH "%s", st->key);
163    
164     switch(st->type) {
165     case STORE_STRING:
166     if((char*)(*ptr)) {
167     gconf_client_set_string(appdata->gconf_client, key, (char*)(*ptr), NULL);
168     }
169     break;
170    
171     case STORE_BOOL:
172     gconf_client_set_bool(appdata->gconf_client, key, *((int*)ptr), NULL);
173     break;
174    
175     case STORE_INT:
176     gconf_client_set_int(appdata->gconf_client, key, *((int*)ptr), NULL);
177     break;
178    
179     case STORE_FLOAT:
180     gconf_client_set_float(appdata->gconf_client, key, *((float*)ptr), NULL);
181     break;
182    
183     default:
184     printf("Unsupported type %d\n", st->type);
185     break;
186     }
187    
188     st++;
189     }
190     }
191    
192     void gconf_load_state(appdata_t *appdata) {
193     gpx_t **gpx = &appdata->gpx;
194    
195     while(*gpx) gpx = &((*gpx)->next);
196    
197     gpx_dialog_t *dialog = NULL;
198    
199     int i, entries = gconf_client_get_int(appdata->gconf_client,
200     GCONF_KEY_CNT, NULL);
201    
202     if(entries)
203     dialog = gpx_busy_dialog_new(GTK_WIDGET(appdata->window));
204    
205     for(i=0;i<entries;i++) {
206     char str[128];
207     snprintf(str, sizeof(str), GCONF_KEY_GPX, i);
208     char *fname = gconf_client_get_string(appdata->gconf_client, str, NULL);
209    
210     if(fname) {
211     /* check if there's a valid name stored for this file. */
212     /* if yes it's a "closed" file */
213     char *name = gconf_restore_closed_name(appdata, fname);
214     if(name) {
215     *gpx = g_new0(gpx_t, 1);
216     (*gpx)->filename = fname;
217     (*gpx)->name = g_strdup(name);
218     (*gpx)->closed = TRUE;
219     } else {
220     if(g_file_test(fname, G_FILE_TEST_IS_DIR))
221     *gpx = gpx_parse_dir(dialog, fname);
222     else
223     *gpx = gpx_parse(dialog, fname);
224    
225     free(fname);
226     }
227     }
228    
229     /* use next gpx entry of this was loaded successfully */
230     if(*gpx)
231     gpx = &((*gpx)->next);
232     }
233    
234     gpx_busy_dialog_destroy(dialog);
235    
236     /* ------------- load locations --------------------- */
237     entries = gconf_client_get_int(appdata->gconf_client,
238     GCONF_KEY_LOC_CNT, NULL);
239    
240     location_t **loc = &appdata->location;
241     for(i=0;i<entries;i++) {
242     *loc = g_new0(location_t, 1);
243     if(*loc) {
244     char str[128];
245     snprintf(str, sizeof(str), GCONF_KEY_LOC_NAME, i);
246     (*loc)->name = gconf_client_get_string(appdata->gconf_client, str, NULL);
247     snprintf(str, sizeof(str), GCONF_KEY_LOC_LAT, i);
248     (*loc)->pos.lat = gconf_client_get_float(appdata->gconf_client, str, NULL);
249     snprintf(str, sizeof(str), GCONF_KEY_LOC_LON, i);
250     (*loc)->pos.lon = gconf_client_get_float(appdata->gconf_client, str, NULL);
251    
252     loc = &((*loc)->next);
253     }
254     }
255    
256     /* restore everything listed in the store table */
257     store_t *st = store;
258     while(st->key) {
259     char key[256];
260     void **ptr = ((void*)appdata) + st->offset;
261     snprintf(key, sizeof(key), GCONF_PATH "%s", st->key);
262    
263     switch(st->type) {
264     case STORE_STRING: {
265     char **str = (char**)ptr;
266     *str = gconf_client_get_string(appdata->gconf_client, key, NULL);
267     } break;
268    
269     case STORE_BOOL:
270     *((int*)ptr) = gconf_client_get_bool(appdata->gconf_client, key, NULL);
271     break;
272    
273     case STORE_INT:
274     *((int*)ptr) = gconf_client_get_int(appdata->gconf_client, key, NULL);
275     break;
276    
277     case STORE_FLOAT:
278     *((float*)ptr) = gconf_client_get_float(appdata->gconf_client, key, NULL);
279     break;
280    
281     default:
282     printf("Unsupported type %d\n", st->type);
283     break;
284     }
285    
286     st++;
287     }
288    
289     /* ----- set all kinds of defaults ------- */
290    
291     #if 0
292     if(!appdata->home.lon || !appdata->home.lat) {
293     appdata->home.lat = DEFAULT_LAT;
294     appdata->home.lon = DEFAULT_LON;
295     }
296    
297     if(!appdata->manual_goto.lon || !appdata->manual_goto.lat) {
298     appdata->manual_goto.lat = DEFAULT_LAT;
299     appdata->manual_goto.lon = DEFAULT_LON;
300     }
301    
302     if(!appdata->gps.lon || !appdata->gps.lat) {
303     appdata->gps.lat = DEFAULT_LAT;
304     appdata->gps.lon = DEFAULT_LON;
305     }
306     #endif
307    
308     if(!appdata->compass_damping) appdata->compass_damping = 1;
309    
310     if(!appdata->mmpoi_radius)
311     appdata->mmpoi_radius = 100.0; // 100 km
312    
313     if(!appdata->search)
314     appdata->search = SEARCH_NAME | SEARCH_ID;
315    
316     if(!appdata->image_path) {
317     /* if we get here, there's no config at all yet. So this is a */
318     /* good place to set all kinds of useful defaults */
319     appdata->load_images = TRUE;
320    
321    
322     #ifndef USE_MAEMO
323     char *p = getenv("HOME");
324     if(p) {
325     /* build image path in home directory */
326     appdata->image_path =
327     malloc(strlen(p)+strlen(DEFAULT_IMAGE_PATH_HOME)+2);
328     strcpy(appdata->image_path, p);
329     if(appdata->image_path[strlen(appdata->image_path)-1] != '/')
330     strcat(appdata->image_path, "/");
331     strcat(appdata->image_path, DEFAULT_IMAGE_PATH_HOME);
332     } else
333     #endif
334     appdata->image_path = strdup(DEFAULT_IMAGE_PATH);
335    
336     } else {
337     /* some versions old versions messed up the path */
338     if(appdata->image_path[strlen(appdata->image_path)-1] != '/') {
339     printf("adjusting image path\n");
340     appdata->image_path = realloc(appdata->image_path,
341     strlen(appdata->image_path)+2);
342     strcat(appdata->image_path, "/");
343     }
344     }
345    
346     if(!appdata->mmpoi_path) {
347     char *p = getenv("HOME");
348     if(p) {
349     /* build mmpoi path in home directory */
350     appdata->mmpoi_path =
351     malloc(strlen(p)+strlen(DEFAULT_MMPOI_PATH)+2);
352     strcpy(appdata->mmpoi_path, p);
353     if(appdata->mmpoi_path[strlen(appdata->mmpoi_path)-1] != '/')
354     strcat(appdata->mmpoi_path, "/");
355     strcat(appdata->mmpoi_path, DEFAULT_MMPOI_PATH);
356     } else
357     appdata->mmpoi_path = strdup(DEFAULT_MMPOI_PATH);
358     }
359    
360     if(!appdata->fieldnotes_path) {
361     char *p = getenv("HOME");
362     if(p) {
363     /* build fieldnotes path in home directory */
364     appdata->fieldnotes_path =
365     malloc(strlen(p)+strlen(DEFAULT_FIELDNOTES_PATH)+2);
366     strcpy(appdata->fieldnotes_path, p);
367     if(appdata->fieldnotes_path[strlen(appdata->fieldnotes_path)-1] != '/')
368     strcat(appdata->fieldnotes_path, "/");
369     strcat(appdata->fieldnotes_path, DEFAULT_FIELDNOTES_PATH);
370     } else
371     appdata->fieldnotes_path = strdup(DEFAULT_FIELDNOTES_PATH);
372     }
373    
374     if(!appdata->garmin_path) {
375     char *p = getenv("HOME");
376     if(p) {
377     /* build image path in home directory */
378     appdata->garmin_path =
379     malloc(strlen(p)+strlen(DEFAULT_GARMIN_PATH)+2);
380     strcpy(appdata->garmin_path, p);
381     if(appdata->garmin_path[strlen(appdata->garmin_path)-1] != '/')
382     strcat(appdata->garmin_path, "/");
383     strcat(appdata->garmin_path, DEFAULT_GARMIN_PATH);
384     } else
385     appdata->garmin_path = strdup(DEFAULT_GARMIN_PATH);
386     }
387    
388     /* make sure image path actually exists */
389     checkdir(appdata->image_path);
390    
391     if(!appdata->gpxlist_items)
392     appdata->gpxlist_items = GPXLIST_ITEM_DEFAULT;
393    
394     if(!appdata->cachelist_items)
395     appdata->cachelist_items = CACHELIST_ITEM_DEFAULT;
396    
397     }
398