Latest fixes for released 0.51.0
[wmaker-crm.git] / WINGs / userdefaults.c
blobae8fe5fdf13aec977d8c077b099b2994d9ae53c5
2 #include <stdlib.h>
3 #include <strings.h>
4 #include <stdio.h>
5 #include <assert.h>
8 #include "../src/config.h"
10 #include "WUtil.h"
12 #include <proplist.h>
15 typedef struct W_UserDefaults {
16 proplist_t defaults;
18 proplist_t appDomain;
20 proplist_t searchListArray;
21 proplist_t *searchList; /* cache for searchListArray */
23 char dirty;
25 } UserDefaults;
28 static UserDefaults *sharedUserDefaults = NULL;
30 extern char *WMGetApplicationName();
32 #define DEFAULTS_DIR "/Defaults"
35 char*
36 wusergnusteppath()
38 char *path;
39 char *gspath;
40 int pathlen;
42 gspath = getenv("GNUSTEP_USER_ROOT");
43 if (gspath) {
44 gspath = wexpandpath(gspath);
45 pathlen = strlen(gspath) + 4;
46 path = wmalloc(pathlen);
47 strcpy(path, gspath);
48 free(gspath);
49 } else {
50 pathlen = strlen(wgethomedir()) + 10;
51 path = wmalloc(pathlen);
52 strcpy(path, wgethomedir());
53 strcat(path, "/GNUstep");
56 return path;
60 char*
61 wdefaultspathfordomain(char *domain)
63 char *path;
64 char *gspath;
66 gspath = wusergnusteppath();
67 path = wmalloc(strlen(gspath)+strlen(DEFAULTS_DIR)+strlen(domain)+4);
68 strcpy(path, gspath);
69 free(gspath);
70 strcat(path, DEFAULTS_DIR);
71 strcat(path, "/");
72 strcat(path, domain);
74 return path;
78 static void
79 #ifndef HAVE_ATEXIT
80 saveDefaultsChanges(int foo, void *bar)
81 #else
82 saveDefaultsChanges(void)
83 #endif
85 if (sharedUserDefaults && sharedUserDefaults->dirty) {
86 PLSave(sharedUserDefaults->appDomain, YES);
91 WMUserDefaults*
92 WMGetStandardUserDefaults(void)
94 if (!sharedUserDefaults) {
95 WMUserDefaults *defaults;
97 proplist_t domain;
98 proplist_t key;
99 char *path;
100 int i;
102 defaults = wmalloc(sizeof(WMUserDefaults));
103 memset(defaults, 0, sizeof(WMUserDefaults));
105 defaults->defaults = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
107 defaults->searchList = wmalloc(sizeof(proplist_t)*3);
109 /* application domain */
110 key = PLMakeString(WMGetApplicationName());
111 defaults->searchList[0] = key;
113 /* temporary kluge */
114 if (strcmp(WMGetApplicationName(), "WindowMaker")==0) {
115 domain = NULL;
116 path = NULL;
117 } else {
118 path = wdefaultspathfordomain(PLGetString(key));
120 domain = PLGetProplistWithPath(path);
122 if (!domain) {
123 proplist_t p;
125 domain = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
126 if (path) {
127 p = PLMakeString(path);
128 PLSetFilename(domain, p);
129 PLRelease(p);
132 if (path)
133 free(path);
135 defaults->appDomain = domain;
137 if (domain)
138 PLInsertDictionaryEntry(defaults->defaults, key, domain);
140 PLRelease(key);
142 /* global domain */
143 key = PLMakeString("WMGLOBAL");
144 defaults->searchList[1] = key;
146 path = wdefaultspathfordomain(PLGetString(key));
148 domain = PLGetProplistWithPath(path);
150 free(path);
152 if (!domain)
153 domain = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
155 if (domain)
156 PLInsertDictionaryEntry(defaults->defaults, key, domain);
158 PLRelease(key);
160 /* terminate list */
161 defaults->searchList[2] = NULL;
163 defaults->searchListArray=PLMakeArrayFromElements(NULL,NULL);
166 i = 0;
167 while (defaults->searchList[i]) {
168 PLAppendArrayElement(defaults->searchListArray,
169 defaults->searchList[i]);
170 i++;
173 sharedUserDefaults = defaults;
175 /* set to save changes in defaults when program is exited */
178 #ifndef HAVE_ATEXIT
179 on_exit(saveDefaultsChanges, (void*)NULL);
180 #else
181 atexit(saveDefaultsChanges);
182 #endif
185 return sharedUserDefaults;
190 proplist_t
191 WMGetUDObjectForKey(WMUserDefaults *database, char *defaultName)
193 proplist_t domainName, domain;
194 proplist_t object = NULL;
195 proplist_t key = PLMakeString(defaultName);
196 int i = 0;
198 while (database->searchList[i] && !object) {
199 domainName = database->searchList[i];
200 domain = PLGetDictionaryEntry(database->defaults, domainName);
201 if (domain) {
202 object = PLGetDictionaryEntry(domain, key);
204 i++;
206 PLRelease(key);
208 return object;
212 void
213 WMSetUDObjectForKey(WMUserDefaults *database, proplist_t object,
214 char *defaultName)
216 proplist_t key = PLMakeString(defaultName);
218 database->dirty = 1;
220 PLInsertDictionaryEntry(database->appDomain, key, object);
221 PLRelease(key);
225 void
226 WMRemoveUDObjectForKey(WMUserDefaults *database, char *defaultName)
228 proplist_t key = PLMakeString(defaultName);
230 database->dirty = 1;
232 PLRemoveDictionaryEntry(database->appDomain, key);
234 PLRelease(key);
238 char*
239 WMGetUDStringForKey(WMUserDefaults *database, char *defaultName)
241 proplist_t val;
243 val = WMGetUDObjectForKey(database, defaultName);
245 if (!val)
246 return NULL;
248 if (!PLIsString(val))
249 return NULL;
251 return wstrdup(PLGetString(val));
256 WMGetUDIntegerForKey(WMUserDefaults *database, char *defaultName)
258 proplist_t val;
259 char *str;
260 int value;
262 val = WMGetUDObjectForKey(database, defaultName);
264 if (!val)
265 return 0;
267 if (!PLIsString(val))
268 return 0;
270 str = PLGetString(val);
271 if (!str)
272 return 0;
274 if (sscanf(str, "%i", &value)!=1)
275 return 0;
277 return value;
283 WMGetUDFloatForKey(WMUserDefaults *database, char *defaultName)
285 proplist_t val;
286 char *str;
287 float value;
289 val = WMGetUDObjectForKey(database, defaultName);
291 if (!val)
292 return 0.0;
294 if (!PLIsString(val))
295 return 0.0;
297 str = PLGetString(val);
298 if (!str)
299 return 0.0;
301 if (sscanf(str, "%f", &value)!=1)
302 return 0.0;
304 return value;
309 Bool
310 WMGetUDBoolForKey(WMUserDefaults *database, char *defaultName)
312 proplist_t val;
313 int value;
314 char *str;
316 val = WMGetUDObjectForKey(database, defaultName);
318 if (!val)
319 return False;
321 if (!PLIsString(val))
322 return False;
324 str = PLGetString(val);
325 if (!str)
326 return False;
328 if (sscanf(str, "%i", &value)==1 && value!=0)
329 return True;
331 if (strcasecmp(str, "YES")==0)
332 return True;
334 if (strcasecmp(str, "Y")==0)
335 return True;
337 return False;
341 void
342 WMSetUDIntegerForKey(WMUserDefaults *database, int value, char *defaultName)
344 proplist_t object;
345 char buffer[128];
347 sprintf(buffer, "%i", value);
348 object = PLMakeString(buffer);
350 WMSetUDObjectForKey(database, object, defaultName);
351 PLRelease(object);
357 void
358 WMSetUDStringForKey(WMUserDefaults *database, char *value, char *defaultName)
360 proplist_t object;
362 object = PLMakeString(value);
364 WMSetUDObjectForKey(database, object, defaultName);
365 PLRelease(object);
370 void
371 WMSetUDFloatForKey(WMUserDefaults *database, float value, char *defaultName)
373 proplist_t object;
374 char buffer[128];
376 sprintf(buffer, "%f", value);
377 object = PLMakeString(buffer);
379 WMSetUDObjectForKey(database, object, defaultName);
380 PLRelease(object);
385 void
386 WMSetUDBoolForKey(WMUserDefaults *database, Bool value, char *defaultName)
388 static proplist_t yes = NULL, no = NULL;
390 if (!yes) {
391 yes = PLMakeString("YES");
392 no = PLMakeString("NO");
395 WMSetUDObjectForKey(database, value ? yes : no, defaultName);
399 proplist_t
400 WMGetUDSearchList(WMUserDefaults *database)
402 return database->searchListArray;
406 void
407 WMSetUDSearchList(WMUserDefaults *database, proplist_t list)
409 int i, c;
411 if (database->searchList) {
412 i = 0;
413 while (database->searchList[i]) {
414 PLRelease(database->searchList[i]);
415 i++;
417 free(database->searchList);
419 if (database->searchListArray) {
420 PLRelease(database->searchListArray);
423 c = PLGetNumberOfElements(list);
424 database->searchList = wmalloc(sizeof(proplist_t)*(c+1));
426 for (i=0; i<c; i++) {
427 database->searchList[i] = PLGetArrayElement(list, i);
430 database->searchListArray = PLDeepCopy(list);