- made deiconification not automatically focus window in sloppy focus
[wmaker-crm.git] / WPrefs.app / WPrefs.c
blob3edff3bf7920fe0531df8e6e142df9797cf58742
1 /* WPrefs.c- main window and other basic stuff
2 *
3 * WPrefs - Window Maker Preferences Program
4 *
5 * Copyright (c) 1998 Alfredo K. Kojima
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20 * USA.
24 #include "WPrefs.h"
25 #include <assert.h>
28 extern Panel *InitWindowHandling(WMScreen *scr, WMWindow *win);
30 extern Panel *InitKeyboardSettings(WMScreen *scr, WMWindow *win);
32 extern Panel *InitMouseSettings(WMScreen *scr, WMWindow *win);
34 extern Panel *InitKeyboardShortcuts(WMScreen *scr, WMWindow *win);
36 extern Panel *InitWorkspace(WMScreen *scr, WMWindow *win);
38 extern Panel *InitFocus(WMScreen *scr, WMWindow *win);
40 extern Panel *InitPreferences(WMScreen *scr, WMWindow *win);
42 extern Panel *InitText(WMScreen *scr, WMWindow *win);
44 extern Panel *InitConfigurations(WMScreen *scr, WMWindow *win);
46 extern Panel *InitPaths(WMScreen *scr, WMWindow *win);
48 extern Panel *InitMenu(WMScreen *scr, WMWindow *win);
50 extern Panel *InitExpert(WMScreen *scr, WMWindow *win);
52 extern Panel *InitMenuPreferences(WMScreen *scr, WMWindow *win);
54 extern Panel *InitIcons(WMScreen *scr, WMWindow *win);
56 extern Panel *InitThemes(WMScreen *scr, WMWindow *win);
58 extern Panel *InitAppearance(WMScreen *scr, WMWindow *win);
62 #define MAX_SECTIONS 16
65 typedef struct _WPrefs {
66 WMWindow *win;
68 WMScrollView *scrollV;
69 WMFrame *buttonF;
70 WMButton *sectionB[MAX_SECTIONS];
72 int sectionCount;
74 WMButton *saveBtn;
75 WMButton *closeBtn;
76 WMButton *undoBtn;
77 WMButton *undosBtn;
79 WMFrame *banner;
80 WMLabel *nameL;
81 WMLabel *versionL;
82 WMLabel *creditsL;
83 WMLabel *statusL;
85 Panel *currentPanel;
86 } _WPrefs;
89 static _WPrefs WPrefs;
91 /* system wide defaults dictionary. Read-only */
92 static proplist_t GlobalDB = NULL;
93 /* user defaults dictionary */
94 static proplist_t WindowMakerDB = NULL;
97 static Bool TIFFOK = False;
100 #define INITIALIZED_PANEL (1<<0)
105 static void loadConfigurations(WMScreen *scr, WMWindow *mainw);
107 static void savePanelData(Panel *panel);
109 static void prepareForClose();
111 void
112 quit(WMWidget *w, void *data)
114 prepareForClose();
116 exit(0);
120 static void
121 save(WMWidget *w, void *data)
123 int i;
124 proplist_t p1, p2;
125 proplist_t keyList;
126 proplist_t key;
127 char *msg = "Reconfigure";
128 XEvent ev;
131 /* puts("gathering data");*/
132 for (i=0; i<WPrefs.sectionCount; i++) {
133 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
134 if ((rec->callbacks.flags & INITIALIZED_PANEL))
135 savePanelData((Panel*)rec);
137 /* puts("compressing data");*/
138 /* compare the user dictionary with the global and remove redundant data */
139 keyList = PLGetAllDictionaryKeys(GlobalDB);
140 /* puts(PLGetDescription(WindowMakerDB));*/
141 for (i=0; i<PLGetNumberOfElements(keyList); i++) {
142 key = PLGetArrayElement(keyList, i);
144 /* We don't have this value anyway, so no problem.
145 * Probably a new option */
146 p1 = PLGetDictionaryEntry(WindowMakerDB, key);
147 if (!p1)
148 continue;
149 /* The global doesn't have it, so no problem either. */
150 p2 = PLGetDictionaryEntry(GlobalDB, key);
151 if (!p2)
152 continue;
153 /* If both values are the same, don't save. */
154 if (PLIsEqual(p1, p2))
155 PLRemoveDictionaryEntry(WindowMakerDB, key);
157 /* puts(PLGetDescription(WindowMakerDB));*/
158 PLRelease(keyList);
159 /* puts("storing data");*/
161 PLSave(WindowMakerDB, YES);
164 memset(&ev, 0, sizeof(XEvent));
166 ev.xclient.type = ClientMessage;
167 ev.xclient.message_type = XInternAtom(WMScreenDisplay(WMWidgetScreen(w)),
168 "_WINDOWMAKER_COMMAND", False);
169 ev.xclient.window = DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w)));
170 ev.xclient.format = 8;
172 for (i = 0; i <= strlen(msg); i++) {
173 ev.xclient.data.b[i] = msg[i];
175 XSendEvent(WMScreenDisplay(WMWidgetScreen(w)),
176 DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w))),
177 False, SubstructureRedirectMask, &ev);
178 XFlush(WMScreenDisplay(WMWidgetScreen(w)));
183 static void
184 undo(WMWidget *w, void *data)
186 PanelRec *rec = (PanelRec*)WPrefs.currentPanel;
188 if (!rec)
189 return;
191 if (rec->callbacks.undoChanges
192 && (rec->callbacks.flags & INITIALIZED_PANEL)) {
193 (*rec->callbacks.undoChanges)(WPrefs.currentPanel);
198 static void
199 undoAll(WMWidget *w, void *data)
201 int i;
203 for (i=0; i<WPrefs.sectionCount; i++) {
204 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
206 if (rec->callbacks.undoChanges
207 && (rec->callbacks.flags & INITIALIZED_PANEL))
208 (*rec->callbacks.undoChanges)((Panel*)rec);
214 static void
215 prepareForClose()
217 int i;
219 for (i=0; i<WPrefs.sectionCount; i++) {
220 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
222 if (rec->callbacks.prepareForClose
223 && (rec->callbacks.flags & INITIALIZED_PANEL))
224 (*rec->callbacks.prepareForClose)((Panel*)rec);
230 static void
231 createMainWindow(WMScreen *scr)
233 WMScroller *scroller;
234 WMFont *font;
235 char buffer[128];
237 WPrefs.win = WMCreateWindow(scr, "wprefs");
238 WMResizeWidget(WPrefs.win, 520, 390);
239 WMSetWindowTitle(WPrefs.win, _("Window Maker Preferences"));
240 WMSetWindowCloseAction(WPrefs.win, quit, NULL);
241 WMSetWindowMaxSize(WPrefs.win, 520, 390);
242 WMSetWindowMinSize(WPrefs.win, 520, 390);
243 WMSetWindowMiniwindowTitle(WPrefs.win, "Preferences");
244 WMSetWindowMiniwindowImage(WPrefs.win, WMGetApplicationIconImage(scr));
246 WPrefs.scrollV = WMCreateScrollView(WPrefs.win);
247 WMResizeWidget(WPrefs.scrollV, 500, 87);
248 WMMoveWidget(WPrefs.scrollV, 10, 10);
249 WMSetScrollViewRelief(WPrefs.scrollV, WRSunken);
250 WMSetScrollViewHasHorizontalScroller(WPrefs.scrollV, True);
251 WMSetScrollViewHasVerticalScroller(WPrefs.scrollV, False);
252 scroller = WMGetScrollViewHorizontalScroller(WPrefs.scrollV);
253 WMSetScrollerArrowsPosition(scroller, WSANone);
255 WPrefs.buttonF = WMCreateFrame(WPrefs.win);
256 WMSetFrameRelief(WPrefs.buttonF, WRFlat);
258 WMSetScrollViewContentView(WPrefs.scrollV, WMWidgetView(WPrefs.buttonF));
260 WPrefs.undosBtn = WMCreateCommandButton(WPrefs.win);
261 WMResizeWidget(WPrefs.undosBtn, 90, 28);
262 WMMoveWidget(WPrefs.undosBtn, 135, 350);
263 WMSetButtonText(WPrefs.undosBtn, _("Revert Page"));
264 WMSetButtonAction(WPrefs.undosBtn, undo, NULL);
266 WPrefs.undoBtn = WMCreateCommandButton(WPrefs.win);
267 WMResizeWidget(WPrefs.undoBtn, 90, 28);
268 WMMoveWidget(WPrefs.undoBtn, 235, 350);
269 WMSetButtonText(WPrefs.undoBtn, _("Revert All"));
270 WMSetButtonAction(WPrefs.undoBtn, undoAll, NULL);
272 WPrefs.saveBtn = WMCreateCommandButton(WPrefs.win);
273 WMResizeWidget(WPrefs.saveBtn, 80, 28);
274 WMMoveWidget(WPrefs.saveBtn, 335, 350);
275 WMSetButtonText(WPrefs.saveBtn, _("Save"));
276 WMSetButtonAction(WPrefs.saveBtn, save, NULL);
278 WPrefs.closeBtn = WMCreateCommandButton(WPrefs.win);
279 WMResizeWidget(WPrefs.closeBtn, 80, 28);
280 WMMoveWidget(WPrefs.closeBtn, 425, 350);
281 WMSetButtonText(WPrefs.closeBtn, _("Close"));
282 WMSetButtonAction(WPrefs.closeBtn, quit, NULL);
284 /* banner */
285 WPrefs.banner = WMCreateFrame(WPrefs.win);
286 WMResizeWidget(WPrefs.banner, FRAME_WIDTH, FRAME_HEIGHT);
287 WMMoveWidget(WPrefs.banner, FRAME_LEFT, FRAME_TOP);
288 WMSetFrameRelief(WPrefs.banner, WRFlat);
290 font = WMCreateFont(scr, "-*-times-bold-r-*-*-24-*-*-*-*-*-*-*,"
291 "-*-fixed-medium-r-normal-*-24-*");
292 if (!font)
293 font = WMBoldSystemFontOfSize(scr, 24);
294 WPrefs.nameL = WMCreateLabel(WPrefs.banner);
295 WMSetLabelTextAlignment(WPrefs.nameL, WACenter);
296 WMResizeWidget(WPrefs.nameL, FRAME_WIDTH-20, 30);
297 WMMoveWidget(WPrefs.nameL, 10, 25);
298 WMSetLabelFont(WPrefs.nameL, font);
299 WMSetLabelText(WPrefs.nameL, _("Window Maker Preferences Utility"));
300 WMReleaseFont(font);
302 WPrefs.versionL = WMCreateLabel(WPrefs.banner);
303 WMResizeWidget(WPrefs.versionL, FRAME_WIDTH-20, 20);
304 WMMoveWidget(WPrefs.versionL, 10, 65);
305 WMSetLabelTextAlignment(WPrefs.versionL, WACenter);
306 sprintf(buffer, _("Version %s for Window Maker %s or newer"), WVERSION,
307 WMVERSION);
308 WMSetLabelText(WPrefs.versionL, buffer);
310 WPrefs.statusL = WMCreateLabel(WPrefs.banner);
311 WMResizeWidget(WPrefs.statusL, FRAME_WIDTH-20, 60);
312 WMMoveWidget(WPrefs.statusL, 10, 100);
313 WMSetLabelTextAlignment(WPrefs.statusL, WACenter);
314 WMSetLabelText(WPrefs.statusL, _("Starting..."));
316 WPrefs.creditsL = WMCreateLabel(WPrefs.banner);
317 WMResizeWidget(WPrefs.creditsL, FRAME_WIDTH-20, 60);
318 WMMoveWidget(WPrefs.creditsL, 10, FRAME_HEIGHT-60);
319 WMSetLabelTextAlignment(WPrefs.creditsL, WACenter);
320 WMSetLabelText(WPrefs.creditsL, _("Programming/Design: Alfredo K. Kojima\n"
321 "Artwork: Marco van Hylckama Vlieg\n"
322 "More Programming: James Thompson"));
325 WMMapSubwidgets(WPrefs.win);
327 WMUnmapWidget(WPrefs.undosBtn);
328 WMUnmapWidget(WPrefs.undoBtn);
329 WMUnmapWidget(WPrefs.saveBtn);
333 static void
334 showPanel(Panel *panel)
336 PanelRec *rec = (PanelRec*)panel;
338 if (!(rec->callbacks.flags & INITIALIZED_PANEL)) {
339 (*rec->callbacks.createWidgets)(panel);
340 rec->callbacks.flags |= INITIALIZED_PANEL;
343 WMSetWindowTitle(WPrefs.win, rec->sectionName);
345 WMMapWidget(rec->frame);
350 static void
351 hidePanel(Panel *panel)
353 PanelRec *rec = (PanelRec*)panel;
355 WMUnmapWidget(rec->frame);
359 static void
360 savePanelData(Panel *panel)
362 PanelRec *rec = (PanelRec*)panel;
364 if (rec->callbacks.updateDomain) {
365 (*rec->callbacks.updateDomain)(panel);
370 static void
371 changeSection(WMWidget *self, void *data)
373 if (WPrefs.banner) {
374 WMDestroyWidget(WPrefs.banner);
375 WPrefs.banner = NULL;
376 /* WMMapWidget(WPrefs.undosBtn);
377 WMMapWidget(WPrefs.undoBtn);
379 WMMapWidget(WPrefs.saveBtn);
382 showPanel(data);
384 if (WPrefs.currentPanel)
385 hidePanel(WPrefs.currentPanel);
386 WPrefs.currentPanel = data;
393 char*
394 LocateImage(char *name)
396 char *path;
397 char *tmp = wmalloc(strlen(name)+8);
399 if (TIFFOK) {
400 sprintf(tmp, "%s.tiff", name);
401 path = WMPathForResourceOfType(tmp, "tiff");
402 } else {
403 sprintf(tmp, "%s.xpm", name);
404 path = WMPathForResourceOfType(tmp, "xpm");
406 free(tmp);
407 if (!path) {
408 wwarning(_("could not locate image file %s\n"), name);
411 return path;
415 void
416 SetButtonAlphaImage(WMScreen *scr, WMButton *bPtr, char *file)
418 WMPixmap *icon;
419 RColor color;
420 char *iconPath;
422 iconPath = LocateImage(file);
424 color.red = 0xae;
425 color.green = 0xaa;
426 color.blue = 0xae;
427 color.alpha = 0;
428 if (iconPath) {
429 icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
430 if (!icon)
431 wwarning(_("could not load icon file %s"), iconPath);
432 } else {
433 icon = NULL;
436 WMSetButtonImage(bPtr, icon);
438 if (icon)
439 WMReleasePixmap(icon);
441 color.red = 0xff;
442 color.green = 0xff;
443 color.blue = 0xff;
444 color.alpha = 0;
445 if (iconPath) {
446 icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
447 if (!icon)
448 wwarning(_("could not load icon file %s"), iconPath);
449 } else {
450 icon = NULL;
453 WMSetButtonAltImage(bPtr, icon);
455 if (icon)
456 WMReleasePixmap(icon);
458 if (iconPath)
459 free(iconPath);
463 void
464 AddSection(Panel *panel, char *iconFile)
466 WMButton *bPtr;
468 assert(WPrefs.sectionCount < MAX_SECTIONS);
471 bPtr = WMCreateCustomButton(WPrefs.buttonF, WBBStateLightMask
472 |WBBStateChangeMask);
473 WMResizeWidget(bPtr, 64, 64);
474 WMMoveWidget(bPtr, WPrefs.sectionCount*64, 0);
475 WMSetButtonImagePosition(bPtr, WIPImageOnly);
476 WMSetButtonAction(bPtr, changeSection, panel);
477 WMHangData(bPtr, panel);
479 SetButtonAlphaImage(WMWidgetScreen(bPtr), bPtr, iconFile);
481 WMMapWidget(bPtr);
483 WPrefs.sectionB[WPrefs.sectionCount] = bPtr;
485 if (WPrefs.sectionCount > 0) {
486 WMGroupButtons(WPrefs.sectionB[0], bPtr);
489 WPrefs.sectionCount++;
491 WMResizeWidget(WPrefs.buttonF, WPrefs.sectionCount*64, 64);
495 void
496 Initialize(WMScreen *scr)
498 char **list;
499 int i;
500 char *path;
501 WMPixmap *icon;
504 list = RSupportedFileFormats();
505 for (i=0; list[i]!=NULL; i++) {
506 if (strcmp(list[i], "TIFF")==0) {
507 TIFFOK = True;
508 break;
512 if (TIFFOK)
513 path = WMPathForResourceOfType("WPrefs.tiff", NULL);
514 else
515 path = WMPathForResourceOfType("WPrefs.xpm", NULL);
516 if (path) {
517 RImage *tmp;
519 tmp = RLoadImage(WMScreenRContext(scr), path, 0);
520 if (!tmp) {
521 wwarning(_("could not load image file %s:%s"), path,
522 RMessageForError(RErrorCode));
523 } else {
524 icon = WMCreatePixmapFromRImage(scr, tmp, 0);
525 RDestroyImage(tmp);
526 if (icon) {
527 WMSetApplicationIconImage(scr, icon);
528 WMReleasePixmap(icon);
531 free(path);
534 memset(&WPrefs, 0, sizeof(_WPrefs));
535 createMainWindow(scr);
537 WMRealizeWidget(WPrefs.win);
538 WMMapWidget(WPrefs.win);
539 XFlush(WMScreenDisplay(scr));
540 WMSetLabelText(WPrefs.statusL, _("Loading Window Maker configuration files..."));
541 XFlush(WMScreenDisplay(scr));
542 loadConfigurations(scr, WPrefs.win);
544 WMSetLabelText(WPrefs.statusL, _("Initializing configuration panels..."));
546 InitWindowHandling(scr, WPrefs.win);
547 InitFocus(scr, WPrefs.win);
548 InitMenuPreferences(scr, WPrefs.win);
549 InitIcons(scr, WPrefs.win);
550 InitPreferences(scr, WPrefs.win);
552 InitPaths(scr, WPrefs.win);
553 InitWorkspace(scr, WPrefs.win);
554 InitConfigurations(scr, WPrefs.win);
556 InitMenu(scr, WPrefs.win);
558 #ifdef not_yet_fully_implemented
559 InitKeyboardSettings(scr, WPrefs.win);
560 #endif
561 InitKeyboardShortcuts(scr, WPrefs.win);
562 InitMouseSettings(scr, WPrefs.win);
564 InitAppearance(scr, WPrefs.win);
565 #ifdef not_yet_fully_implemented
567 InitText(scr, WPrefs.win);
568 InitThemes(scr, WPrefs.win);
569 #endif
570 InitExpert(scr, WPrefs.win);
572 WMRealizeWidget(WPrefs.scrollV);
574 WMSetLabelText(WPrefs.statusL,
575 _("WPrefs is free software and is distributed WITHOUT ANY\n"
576 "WARRANTY under the terms of the GNU General Public License.\n"
577 "The icons in this program are licensed through the\n"
578 "OpenContent License."));
582 WMWindow*
583 GetWindow(Panel *panel)
585 return WPrefs.win;
589 static void
590 loadConfigurations(WMScreen *scr, WMWindow *mainw)
592 proplist_t db, gdb;
593 char *path;
594 FILE *file;
595 char buffer[1024];
596 char mbuf[1024];
597 int v1, v2, v3;
599 path = wdefaultspathfordomain("WindowMaker");
601 db = PLGetProplistWithPath(path);
602 if (db) {
603 if (!PLIsDictionary(db)) {
604 PLRelease(db);
605 db = NULL;
606 sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), path);
607 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
609 } else {
610 sprintf(mbuf, _("Could not load Window Maker domain (%s) from defaults database."),
611 path);
612 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
614 free(path);
616 file = popen("wmaker --version", "r");
617 if (!file || !fgets(buffer, 1023, file)) {
618 wsyserror(_("could not extract version information from Window Maker"));
619 wfatal(_("Make sure wmaker is in your search path."));
621 WMRunAlertPanel(scr, mainw, _("Error"),
622 _("Could not extract version from Window Maker. Make sure it is correctly installed and is in your PATH environment variable."),
623 _("OK"), NULL, NULL);
624 exit(1);
626 if (file)
627 pclose(file);
629 if (sscanf(buffer, "Window Maker %i.%i.%i",&v1,&v2,&v3)!=3
630 && sscanf(buffer, "WindowMaker %i.%i.%i",&v1,&v2,&v3)!=3) {
631 WMRunAlertPanel(scr, mainw, _("Error"),
632 _("Could not extract version from Window Maker. "
633 "Make sure it is correctly installed and the path "
634 "where it installed is in the PATH environment "
635 "variable."), _("OK"), NULL, NULL);
636 exit(1);
638 if (v1 == 0 && (v2 < 18 || v3 < 0)) {
639 sprintf(mbuf, _("WPrefs only supports Window Maker 0.18.0 or newer.\n"
640 "The version installed is %i.%i.%i\n"), v1, v2, v3);
641 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
642 exit(1);
645 if (v1 > 1 || (v1 == 1 && (v2 > 0))) {
646 sprintf(mbuf, _("Window Maker %i.%i.%i, which is installed in your system, is not fully supported by this version of WPrefs."),
647 v1, v2, v3);
648 WMRunAlertPanel(scr, mainw, _("Warning"), mbuf, _("OK"), NULL, NULL);
651 file = popen("wmaker --global_defaults_path", "r");
652 if (!file || !fgets(buffer, 1023, file)) {
653 wsyserror(_("could not run \"wmaker --global_defaults_path\"."));
654 exit(1);
655 } else {
656 char *ptr;
657 ptr = strchr(buffer, '\n');
658 if (ptr)
659 *ptr = 0;
660 strcat(buffer, "/WindowMaker");
663 if (file)
664 pclose(file);
666 gdb = PLGetProplistWithPath(buffer);
667 if (gdb) {
668 if (!PLIsDictionary(gdb)) {
669 PLRelease(gdb);
670 gdb = NULL;
671 sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), buffer);
672 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
674 } else {
675 sprintf(mbuf, _("Could not load global Window Maker domain (%s)."),
676 buffer);
677 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
680 if (!db) {
681 db = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
683 if (!gdb) {
684 gdb = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
687 GlobalDB = gdb;
689 WindowMakerDB = db;
693 proplist_t
694 GetObjectForKey(char *defaultName)
696 proplist_t object = NULL;
697 proplist_t key = PLMakeString(defaultName);
699 object = PLGetDictionaryEntry(WindowMakerDB, key);
700 if (!object)
701 object = PLGetDictionaryEntry(GlobalDB, key);
703 PLRelease(key);
705 return object;
709 void
710 SetObjectForKey(proplist_t object, char *defaultName)
712 proplist_t key = PLMakeString(defaultName);
714 PLInsertDictionaryEntry(WindowMakerDB, key, object);
715 PLRelease(key);
719 void
720 RemoveObjectForKey(char *defaultName)
722 proplist_t key = PLMakeString(defaultName);
724 PLRemoveDictionaryEntry(WindowMakerDB, key);
726 PLRelease(key);
730 char*
731 GetStringForKey(char *defaultName)
733 proplist_t val;
735 val = GetObjectForKey(defaultName);
737 if (!val)
738 return NULL;
740 if (!PLIsString(val))
741 return NULL;
743 return PLGetString(val);
748 proplist_t
749 GetArrayForKey(char *defaultName)
751 proplist_t val;
753 val = GetObjectForKey(defaultName);
755 if (!val)
756 return NULL;
758 if (!PLIsArray(val))
759 return NULL;
761 return val;
765 proplist_t
766 GetDictionaryForKey(char *defaultName)
768 proplist_t val;
770 val = GetObjectForKey(defaultName);
772 if (!val)
773 return NULL;
775 if (!PLIsDictionary(val))
776 return NULL;
778 return val;
783 GetIntegerForKey(char *defaultName)
785 proplist_t val;
786 char *str;
787 int value;
789 val = GetObjectForKey(defaultName);
791 if (!val)
792 return 0;
794 if (!PLIsString(val))
795 return 0;
797 str = PLGetString(val);
798 if (!str)
799 return 0;
801 if (sscanf(str, "%i", &value)!=1)
802 return 0;
804 return value;
808 Bool
809 GetBoolForKey(char *defaultName)
811 int value;
812 char *str;
814 str = GetStringForKey(defaultName);
816 if (!str)
817 return False;
819 if (sscanf(str, "%i", &value)==1 && value!=0)
820 return True;
822 if (strcasecmp(str, "YES")==0)
823 return True;
825 if (strcasecmp(str, "Y")==0)
826 return True;
828 return False;
832 void
833 SetIntegerForKey(int value, char *defaultName)
835 proplist_t object;
836 char buffer[128];
838 sprintf(buffer, "%i", value);
839 object = PLMakeString(buffer);
841 SetObjectForKey(object, defaultName);
842 PLRelease(object);
847 void
848 SetStringForKey(char *value, char *defaultName)
850 proplist_t object;
852 object = PLMakeString(value);
854 SetObjectForKey(object, defaultName);
855 PLRelease(object);
859 void
860 SetBoolForKey(Bool value, char *defaultName)
862 static proplist_t yes = NULL, no = NULL;
864 if (!yes) {
865 yes = PLMakeString("YES");
866 no = PLMakeString("NO");
869 SetObjectForKey(value ? yes : no, defaultName);
873 void
874 SetSpeedForKey(int speed, char *defaultName)
876 char *str;
878 switch (speed) {
879 case 0:
880 str = "ultraslow";
881 break;
882 case 1:
883 str = "slow";
884 break;
885 case 2:
886 str = "medium";
887 break;
888 case 3:
889 str = "fast";
890 break;
891 case 4:
892 str = "ultrafast";
893 break;
894 default:
895 str = NULL;
898 if (str)
899 SetStringForKey(str, defaultName);
904 GetSpeedForKey(char *defaultName)
906 char *str;
907 int i;
909 str = GetStringForKey(defaultName);
910 if (!str)
911 return 2;
913 if (strcasecmp(str, "ultraslow")==0)
914 i = 0;
915 else if (strcasecmp(str, "slow")==0)
916 i = 1;
917 else if (strcasecmp(str, "medium")==0)
918 i = 2;
919 else if (strcasecmp(str, "fast")==0)
920 i = 3;
921 else if (strcasecmp(str, "ultrafast")==0)
922 i = 4;
923 else {
924 wwarning(_("bad speed value for option %s\n. Using default Medium"),
925 defaultName);
926 i = 2;
928 return i;