Contents of /trunk/src/gconf.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 48 - (hide annotations)
Fri Aug 7 07:57:33 2009 UTC (14 years, 9 months ago) by harbaum
File MIME type: text/plain
File size: 13006 byte(s)
Save map position
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     #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 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     #endif
92 harbaum 1 { NULL, -1, -1 }
93     };
94    
95     static char *get_basename(char *name) {
96     char *p = strrchr(name, '/');
97     if(!p) p = name;
98     else p = p+1;
99    
100     g_assert(*p);
101    
102     /* escape all non alnum characters */
103     p = g_strdup(p);
104     int i;
105     for(i=0;i<strlen(p);i++)
106     if(!isalnum(p[i]))
107     p[i] = '_';
108    
109     return p;
110     }
111    
112     void gconf_remove_closed_name(appdata_t *appdata, char *filename) {
113     char *key = g_strdup_printf(GCONF_KEY_CLOSED, get_basename(filename));
114     gconf_client_unset(appdata->gconf_client, key, NULL);
115     g_free(key);
116     }
117    
118     void gconf_save_closed_name(appdata_t *appdata, char *filename, char *name) {
119     char *key = g_strdup_printf(GCONF_KEY_CLOSED, get_basename(filename));
120     gconf_client_set_string(appdata->gconf_client, key, name, NULL);
121     g_free(key);
122     }
123    
124     char *gconf_restore_closed_name(appdata_t *appdata, char *filename) {
125     char *key = g_strdup_printf(GCONF_KEY_CLOSED, get_basename(filename));
126     char *ret = gconf_client_get_string(appdata->gconf_client, key, NULL);
127     g_free(key);
128     return ret;
129     }
130    
131     void gconf_save_state(appdata_t *appdata) {
132     int entries = 0;
133    
134     gpx_t *gpx = appdata->gpx;
135     while(gpx) {
136     char str[128];
137     snprintf(str, sizeof(str), GCONF_KEY_GPX, entries++);
138     gconf_client_set_string(appdata->gconf_client, str, gpx->filename, NULL);
139     gpx = gpx->next;
140     }
141    
142     gconf_client_set_int(appdata->gconf_client, GCONF_KEY_CNT, entries, NULL);
143    
144     /* -------------- save locations (excl. home location) --------------- */
145     entries = 0;
146     location_t *loc = appdata->location;
147     while(loc) {
148     char str[128];
149     snprintf(str, sizeof(str), GCONF_KEY_LOC_NAME, entries);
150     gconf_client_set_string(appdata->gconf_client, str, loc->name, NULL);
151     snprintf(str, sizeof(str), GCONF_KEY_LOC_LAT, entries);
152     gconf_client_set_float(appdata->gconf_client, str, loc->pos.lat, NULL);
153     snprintf(str, sizeof(str), GCONF_KEY_LOC_LON, entries);
154     gconf_client_set_float(appdata->gconf_client, str, loc->pos.lon, NULL);
155     entries++;
156     loc = loc->next;
157     }
158    
159     gconf_client_set_int(appdata->gconf_client, GCONF_KEY_LOC_CNT, entries, NULL);
160    
161     /* store everything listed in the store table */
162     store_t *st = store;
163     while(st->key) {
164     void **ptr = ((void*)appdata) + st->offset;
165 harbaum 34 char *key = g_strdup_printf(GCONF_PATH "%s", st->key);
166 harbaum 1
167     switch(st->type) {
168     case STORE_STRING:
169     if((char*)(*ptr)) {
170     gconf_client_set_string(appdata->gconf_client, key, (char*)(*ptr), NULL);
171     }
172     break;
173    
174     case STORE_BOOL:
175     gconf_client_set_bool(appdata->gconf_client, key, *((int*)ptr), NULL);
176     break;
177    
178     case STORE_INT:
179     gconf_client_set_int(appdata->gconf_client, key, *((int*)ptr), NULL);
180     break;
181    
182     case STORE_FLOAT:
183 harbaum 34 if(!isnan(*((float*)ptr)))
184     gconf_client_set_float(appdata->gconf_client, key, *((float*)ptr), NULL);
185 harbaum 1 break;
186    
187     default:
188     printf("Unsupported type %d\n", st->type);
189     break;
190     }
191    
192 harbaum 34 g_free(key);
193 harbaum 1 st++;
194     }
195     }
196    
197     void gconf_load_state(appdata_t *appdata) {
198     gpx_t **gpx = &appdata->gpx;
199    
200     while(*gpx) gpx = &((*gpx)->next);
201    
202     gpx_dialog_t *dialog = NULL;
203    
204 harbaum 34 /* default positions are invalid */
205     appdata->home.lat = appdata->home.lon = NAN;
206     appdata->manual_goto.lat = appdata->manual_goto.lon = NAN;
207     appdata->gps.lat = appdata->gps.lon = NAN;
208    
209 harbaum 1 int i, entries = gconf_client_get_int(appdata->gconf_client,
210     GCONF_KEY_CNT, NULL);
211    
212     if(entries)
213     dialog = gpx_busy_dialog_new(GTK_WIDGET(appdata->window));
214    
215     for(i=0;i<entries;i++) {
216     char str[128];
217     snprintf(str, sizeof(str), GCONF_KEY_GPX, i);
218     char *fname = gconf_client_get_string(appdata->gconf_client, str, NULL);
219    
220     if(fname) {
221     /* check if there's a valid name stored for this file. */
222     /* if yes it's a "closed" file */
223     char *name = gconf_restore_closed_name(appdata, fname);
224     if(name) {
225     *gpx = g_new0(gpx_t, 1);
226     (*gpx)->filename = fname;
227     (*gpx)->name = g_strdup(name);
228     (*gpx)->closed = TRUE;
229     } else {
230     if(g_file_test(fname, G_FILE_TEST_IS_DIR))
231     *gpx = gpx_parse_dir(dialog, fname);
232     else
233     *gpx = gpx_parse(dialog, fname);
234    
235     free(fname);
236     }
237     }
238    
239     /* use next gpx entry of this was loaded successfully */
240     if(*gpx)
241     gpx = &((*gpx)->next);
242     }
243    
244     gpx_busy_dialog_destroy(dialog);
245    
246     /* ------------- load locations --------------------- */
247     entries = gconf_client_get_int(appdata->gconf_client,
248     GCONF_KEY_LOC_CNT, NULL);
249    
250     location_t **loc = &appdata->location;
251     for(i=0;i<entries;i++) {
252     *loc = g_new0(location_t, 1);
253     if(*loc) {
254     char str[128];
255     snprintf(str, sizeof(str), GCONF_KEY_LOC_NAME, i);
256     (*loc)->name = gconf_client_get_string(appdata->gconf_client, str, NULL);
257     snprintf(str, sizeof(str), GCONF_KEY_LOC_LAT, i);
258     (*loc)->pos.lat = gconf_client_get_float(appdata->gconf_client, str, NULL);
259     snprintf(str, sizeof(str), GCONF_KEY_LOC_LON, i);
260     (*loc)->pos.lon = gconf_client_get_float(appdata->gconf_client, str, NULL);
261    
262     loc = &((*loc)->next);
263     }
264     }
265    
266     /* restore everything listed in the store table */
267     store_t *st = store;
268     while(st->key) {
269     void **ptr = ((void*)appdata) + st->offset;
270 harbaum 34 char *key = g_strdup_printf(GCONF_PATH "%s", st->key);
271 harbaum 1
272 harbaum 34 /* check if key is present */
273     GConfValue *value = gconf_client_get(appdata->gconf_client, key, NULL);
274     if(value) {
275     gconf_value_free(value);
276    
277     switch(st->type) {
278     case STORE_STRING: {
279     char **str = (char**)ptr;
280     *str = gconf_client_get_string(appdata->gconf_client, key, NULL);
281 harbaum 1 } break;
282 harbaum 34
283     case STORE_BOOL:
284     *((int*)ptr) = gconf_client_get_bool(appdata->gconf_client, key, NULL);
285     break;
286    
287     case STORE_INT:
288     *((int*)ptr) = gconf_client_get_int(appdata->gconf_client, key, NULL);
289     break;
290    
291     case STORE_FLOAT:
292     *((float*)ptr) = gconf_client_get_float(appdata->gconf_client, key, NULL);
293     break;
294    
295     default:
296     printf("Unsupported type %d\n", st->type);
297     break;
298     }
299 harbaum 1 }
300 harbaum 34 g_free(key);
301 harbaum 1 st++;
302     }
303    
304     /* ----- set all kinds of defaults ------- */
305    
306     if(!appdata->compass_damping) appdata->compass_damping = 1;
307    
308     if(!appdata->mmpoi_radius)
309     appdata->mmpoi_radius = 100.0; // 100 km
310    
311     if(!appdata->search)
312     appdata->search = SEARCH_NAME | SEARCH_ID;
313    
314     if(!appdata->image_path) {
315    
316 harbaum 14 /* use gps by default */
317     appdata->use_gps = TRUE;
318    
319 harbaum 1 #ifndef USE_MAEMO
320     char *p = getenv("HOME");
321     if(p) {
322     /* build image path in home directory */
323     appdata->image_path =
324     malloc(strlen(p)+strlen(DEFAULT_IMAGE_PATH_HOME)+2);
325     strcpy(appdata->image_path, p);
326     if(appdata->image_path[strlen(appdata->image_path)-1] != '/')
327     strcat(appdata->image_path, "/");
328     strcat(appdata->image_path, DEFAULT_IMAGE_PATH_HOME);
329     } else
330     #endif
331     appdata->image_path = strdup(DEFAULT_IMAGE_PATH);
332    
333     } else {
334     /* some versions old versions messed up the path */
335     if(appdata->image_path[strlen(appdata->image_path)-1] != '/') {
336     printf("adjusting image path\n");
337     appdata->image_path = realloc(appdata->image_path,
338     strlen(appdata->image_path)+2);
339     strcat(appdata->image_path, "/");
340     }
341     }
342    
343     if(!appdata->mmpoi_path) {
344     char *p = getenv("HOME");
345     if(p) {
346     /* build mmpoi path in home directory */
347     appdata->mmpoi_path =
348     malloc(strlen(p)+strlen(DEFAULT_MMPOI_PATH)+2);
349     strcpy(appdata->mmpoi_path, p);
350     if(appdata->mmpoi_path[strlen(appdata->mmpoi_path)-1] != '/')
351     strcat(appdata->mmpoi_path, "/");
352     strcat(appdata->mmpoi_path, DEFAULT_MMPOI_PATH);
353     } else
354     appdata->mmpoi_path = strdup(DEFAULT_MMPOI_PATH);
355     }
356    
357     if(!appdata->fieldnotes_path) {
358     char *p = getenv("HOME");
359     if(p) {
360     /* build fieldnotes path in home directory */
361     appdata->fieldnotes_path =
362     malloc(strlen(p)+strlen(DEFAULT_FIELDNOTES_PATH)+2);
363     strcpy(appdata->fieldnotes_path, p);
364     if(appdata->fieldnotes_path[strlen(appdata->fieldnotes_path)-1] != '/')
365     strcat(appdata->fieldnotes_path, "/");
366     strcat(appdata->fieldnotes_path, DEFAULT_FIELDNOTES_PATH);
367     } else
368     appdata->fieldnotes_path = strdup(DEFAULT_FIELDNOTES_PATH);
369     }
370    
371     if(!appdata->garmin_path) {
372     char *p = getenv("HOME");
373     if(p) {
374     /* build image path in home directory */
375     appdata->garmin_path =
376     malloc(strlen(p)+strlen(DEFAULT_GARMIN_PATH)+2);
377     strcpy(appdata->garmin_path, p);
378     if(appdata->garmin_path[strlen(appdata->garmin_path)-1] != '/')
379     strcat(appdata->garmin_path, "/");
380     strcat(appdata->garmin_path, DEFAULT_GARMIN_PATH);
381     } else
382     appdata->garmin_path = strdup(DEFAULT_GARMIN_PATH);
383     }
384    
385     /* make sure image path actually exists */
386     checkdir(appdata->image_path);
387    
388     if(!appdata->gpxlist_items)
389     appdata->gpxlist_items = GPXLIST_ITEM_DEFAULT;
390    
391     if(!appdata->cachelist_items)
392     appdata->cachelist_items = CACHELIST_ITEM_DEFAULT;
393    
394 harbaum 13 /* if there are no entries in the main list, try to add the */
395     /* "welcome" one */
396     if(!appdata->gpx) {
397 harbaum 17 char *name = g_strdup(ICONPATH "welcome.gpx");
398 harbaum 13 dialog = gpx_busy_dialog_new(GTK_WIDGET(appdata->window));
399     printf("No GPX file loaded, trying to load demo\n");
400     appdata->gpx = gpx_parse(dialog, name);
401     gpx_busy_dialog_destroy(dialog);
402     g_free(name);
403     }
404 harbaum 1 }
405