Add call to WMReleaseApplication on application exit
[wmaker-crm.git] / WPrefs.app / WPrefs.c
blobc3274ee33e0221f5391659dd4427364ee7e405e1
1 /* WPrefs.c- main window and other basic stuff
3 * WPrefs - Window Maker Preferences Program
5 * Copyright (c) 1998-2003 Alfredo K. Kojima
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 along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "config.h"
24 #include "WPrefs.h"
25 #include <assert.h>
27 #ifdef HAVE_STDNORETURN
28 #include <stdnoreturn.h>
29 #endif
32 #define ICON_TITLE_FONT "sans serif:pixelsize=9"
33 #define ICON_TITLE_VFONT "sans serif:pixelsize=9:weight=100"
35 #define MAX_SECTIONS 16
37 typedef struct _WPrefs {
38 WMWindow *win;
40 WMScrollView *scrollV;
41 WMFrame *buttonF;
42 WMButton *sectionB[MAX_SECTIONS];
44 int sectionCount;
46 WMButton *saveBtn;
47 WMButton *closeBtn;
48 WMButton *undoBtn;
49 WMButton *undosBtn;
51 WMButton *balloonBtn;
53 WMFrame *banner;
54 WMLabel *nameL;
55 WMLabel *versionL;
56 WMLabel *statusL;
58 Panel *currentPanel;
59 } _WPrefs;
61 static _WPrefs WPrefs;
63 /* system wide defaults dictionary. Read-only */
64 static WMPropList *GlobalDB = NULL;
65 /* user defaults dictionary */
66 static WMPropList *WindowMakerDB = NULL;
67 static char *WindowMakerDBPath = NULL;
69 static Bool TIFFOK = False;
71 #define INITIALIZED_PANEL (1<<0)
73 static void loadConfigurations(WMScreen * scr, WMWindow * mainw);
75 static void savePanelData(Panel * panel);
77 static void prepareForClose(void);
79 static noreturn void quit(WMWidget *w, void *data)
81 /* Parameter not used, but tell the compiler that it is ok */
82 (void) w;
83 (void) data;
85 prepareForClose();
87 WMReleaseApplication();
88 exit(0);
91 static void save(WMWidget * w, void *data)
93 int i;
94 WMPropList *p1, *p2;
95 WMPropList *keyList;
96 WMPropList *key;
97 XEvent ev;
99 /* Parameter not used, but tell the compiler that it is ok */
100 (void) data;
102 /* puts("gathering data"); */
103 for (i = 0; i < WPrefs.sectionCount; i++) {
104 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
105 if ((rec->callbacks.flags & INITIALIZED_PANEL))
106 savePanelData((Panel *) rec);
108 /* puts("compressing data"); */
109 /* compare the user dictionary with the global and remove redundant data */
110 keyList = WMGetPLDictionaryKeys(GlobalDB);
111 /* puts(WMGetPropListDescription(WindowMakerDB, False)); */
112 for (i = 0; i < WMGetPropListItemCount(keyList); i++) {
113 key = WMGetFromPLArray(keyList, i);
115 /* We don't have this value anyway, so no problem.
116 * Probably a new option */
117 p1 = WMGetFromPLDictionary(WindowMakerDB, key);
118 if (!p1)
119 continue;
120 /* The global doesn't have it, so no problem either. */
121 p2 = WMGetFromPLDictionary(GlobalDB, key);
122 if (!p2)
123 continue;
124 /* If both values are the same, don't save. */
125 if (WMIsPropListEqualTo(p1, p2))
126 WMRemoveFromPLDictionary(WindowMakerDB, key);
128 /* puts(WMGetPropListDescription(WindowMakerDB, False)); */
129 WMReleasePropList(keyList);
130 /* puts("storing data"); */
132 WMWritePropListToFile(WindowMakerDB, WindowMakerDBPath);
134 memset(&ev, 0, sizeof(XEvent));
136 ev.xclient.type = ClientMessage;
137 ev.xclient.message_type = XInternAtom(WMScreenDisplay(WMWidgetScreen(w)), "_WINDOWMAKER_COMMAND", False);
138 ev.xclient.window = DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w)));
139 ev.xclient.format = 8;
140 strncpy(ev.xclient.data.b, "Reconfigure", sizeof(ev.xclient.data.b));
142 XSendEvent(WMScreenDisplay(WMWidgetScreen(w)),
143 DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w))), False, SubstructureRedirectMask, &ev);
144 XFlush(WMScreenDisplay(WMWidgetScreen(w)));
147 static void undo(WMWidget * w, void *data)
149 PanelRec *rec = (PanelRec *) WPrefs.currentPanel;
151 /* Parameter not used, but tell the compiler that it is ok */
152 (void) w;
153 (void) data;
155 if (!rec)
156 return;
158 if (rec->callbacks.undoChanges && (rec->callbacks.flags & INITIALIZED_PANEL)) {
159 (*rec->callbacks.undoChanges) (WPrefs.currentPanel);
163 static void undoAll(WMWidget * w, void *data)
165 int i;
167 /* Parameter not used, but tell the compiler that it is ok */
168 (void) w;
169 (void) data;
171 for (i = 0; i < WPrefs.sectionCount; i++) {
172 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
174 if (rec->callbacks.undoChanges && (rec->callbacks.flags & INITIALIZED_PANEL))
175 (*rec->callbacks.undoChanges) ((Panel *) rec);
179 static void prepareForClose(void)
181 int i;
183 for (i = 0; i < WPrefs.sectionCount; i++) {
184 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
186 if (rec->callbacks.prepareForClose && (rec->callbacks.flags & INITIALIZED_PANEL))
187 (*rec->callbacks.prepareForClose) ((Panel *) rec);
191 static void toggleBalloons(WMWidget *w, void *data)
193 WMUserDefaults *udb = WMGetStandardUserDefaults();
194 Bool flag;
196 /* Parameter not used, but tell the compiler that it is ok */
197 (void) w;
198 (void) data;
200 flag = WMGetButtonSelected(WPrefs.balloonBtn);
202 WMSetBalloonEnabled(WMWidgetScreen(WPrefs.win), flag);
204 WMSetUDBoolForKey(udb, flag, "BalloonHelp");
207 static void createMainWindow(WMScreen * scr)
209 WMScroller *scroller;
210 WMFont *font;
211 char buffer[128];
213 WPrefs.win = WMCreateWindow(scr, "wprefs");
214 WMResizeWidget(WPrefs.win, 520, 390);
215 WMSetWindowTitle(WPrefs.win, _("Window Maker Preferences"));
216 WMSetWindowCloseAction(WPrefs.win, quit, NULL);
217 WMSetWindowMaxSize(WPrefs.win, 520, 390);
218 WMSetWindowMinSize(WPrefs.win, 520, 390);
219 WMSetWindowMiniwindowTitle(WPrefs.win, "Preferences");
221 WPrefs.scrollV = WMCreateScrollView(WPrefs.win);
222 WMResizeWidget(WPrefs.scrollV, 500, 87);
223 WMMoveWidget(WPrefs.scrollV, 10, 10);
224 WMSetScrollViewRelief(WPrefs.scrollV, WRSunken);
225 WMSetScrollViewHasHorizontalScroller(WPrefs.scrollV, True);
226 WMSetScrollViewHasVerticalScroller(WPrefs.scrollV, False);
227 scroller = WMGetScrollViewHorizontalScroller(WPrefs.scrollV);
228 WMSetScrollerArrowsPosition(scroller, WSANone);
230 WPrefs.buttonF = WMCreateFrame(WPrefs.win);
231 WMSetFrameRelief(WPrefs.buttonF, WRFlat);
233 WMSetScrollViewContentView(WPrefs.scrollV, WMWidgetView(WPrefs.buttonF));
235 WPrefs.undosBtn = WMCreateCommandButton(WPrefs.win);
236 WMResizeWidget(WPrefs.undosBtn, 90, 28);
237 WMMoveWidget(WPrefs.undosBtn, 135, 350);
238 WMSetButtonText(WPrefs.undosBtn, _("Revert Page"));
239 WMSetButtonAction(WPrefs.undosBtn, undo, NULL);
241 WPrefs.undoBtn = WMCreateCommandButton(WPrefs.win);
242 WMResizeWidget(WPrefs.undoBtn, 90, 28);
243 WMMoveWidget(WPrefs.undoBtn, 235, 350);
244 WMSetButtonText(WPrefs.undoBtn, _("Revert All"));
245 WMSetButtonAction(WPrefs.undoBtn, undoAll, NULL);
247 WPrefs.saveBtn = WMCreateCommandButton(WPrefs.win);
248 WMResizeWidget(WPrefs.saveBtn, 80, 28);
249 WMMoveWidget(WPrefs.saveBtn, 335, 350);
250 WMSetButtonText(WPrefs.saveBtn, _("Save"));
251 WMSetButtonAction(WPrefs.saveBtn, save, NULL);
253 WPrefs.closeBtn = WMCreateCommandButton(WPrefs.win);
254 WMResizeWidget(WPrefs.closeBtn, 80, 28);
255 WMMoveWidget(WPrefs.closeBtn, 425, 350);
256 WMSetButtonText(WPrefs.closeBtn, _("Close"));
257 WMSetButtonAction(WPrefs.closeBtn, quit, NULL);
259 WPrefs.balloonBtn = WMCreateSwitchButton(WPrefs.win);
260 WMResizeWidget(WPrefs.balloonBtn, 200, 28);
261 WMMoveWidget(WPrefs.balloonBtn, 15, 350);
262 WMSetButtonText(WPrefs.balloonBtn, _("Balloon Help"));
263 WMSetButtonAction(WPrefs.balloonBtn, toggleBalloons, NULL);
265 WMUserDefaults *udb = WMGetStandardUserDefaults();
266 Bool flag = WMGetUDBoolForKey(udb, "BalloonHelp");
268 WMSetButtonSelected(WPrefs.balloonBtn, flag);
269 WMSetBalloonEnabled(scr, flag);
272 /* banner */
273 WPrefs.banner = WMCreateFrame(WPrefs.win);
274 WMResizeWidget(WPrefs.banner, FRAME_WIDTH, FRAME_HEIGHT);
275 WMMoveWidget(WPrefs.banner, FRAME_LEFT, FRAME_TOP);
276 WMSetFrameRelief(WPrefs.banner, WRFlat);
278 font = WMCreateFont(scr, "Lucida Sans,URW Gothic L,Times New Roman,serif"
279 ":bold:pixelsize=26:antialias=true");
280 WPrefs.nameL = WMCreateLabel(WPrefs.banner);
281 WMSetLabelTextAlignment(WPrefs.nameL, WACenter);
282 WMResizeWidget(WPrefs.nameL, FRAME_WIDTH - 20, 60);
283 WMMoveWidget(WPrefs.nameL, 10, 50);
284 WMSetLabelFont(WPrefs.nameL, font);
285 WMSetLabelText(WPrefs.nameL, _("Window Maker Preferences"));
286 WMReleaseFont(font);
288 WPrefs.versionL = WMCreateLabel(WPrefs.banner);
289 WMResizeWidget(WPrefs.versionL, FRAME_WIDTH - 20, 20);
290 WMMoveWidget(WPrefs.versionL, 10, 120);
291 WMSetLabelTextAlignment(WPrefs.versionL, WACenter);
292 sprintf(buffer, _("Version %s"), VERSION);
293 WMSetLabelText(WPrefs.versionL, buffer);
295 WPrefs.statusL = WMCreateLabel(WPrefs.banner);
296 WMResizeWidget(WPrefs.statusL, FRAME_WIDTH - 20, 60);
297 WMMoveWidget(WPrefs.statusL, 10, 150);
298 WMSetLabelTextAlignment(WPrefs.statusL, WACenter);
299 WMSetLabelText(WPrefs.statusL, _("Starting..."));
301 WMMapSubwidgets(WPrefs.win);
303 WMUnmapWidget(WPrefs.undosBtn);
304 WMUnmapWidget(WPrefs.undoBtn);
305 WMUnmapWidget(WPrefs.saveBtn);
308 static void showPanel(Panel * panel)
310 PanelRec *rec = (PanelRec *) panel;
312 if (!(rec->callbacks.flags & INITIALIZED_PANEL)) {
313 (*rec->callbacks.createWidgets) (panel);
314 rec->callbacks.flags |= INITIALIZED_PANEL;
317 WMSetWindowTitle(WPrefs.win, rec->sectionName);
319 if (rec->callbacks.showPanel)
320 (*rec->callbacks.showPanel) (panel);
322 WMMapWidget(rec->box);
325 static void hidePanel(Panel * panel)
327 PanelRec *rec = (PanelRec *) panel;
329 WMUnmapWidget(rec->box);
331 if (rec->callbacks.hidePanel)
332 (*rec->callbacks.hidePanel) (panel);
335 static void savePanelData(Panel * panel)
337 PanelRec *rec = (PanelRec *) panel;
339 if (rec->callbacks.updateDomain) {
340 (*rec->callbacks.updateDomain) (panel);
344 static void changeSection(WMWidget * self, void *data)
346 /* Parameter not used, but tell the compiler that it is ok */
347 (void) self;
349 if (WPrefs.currentPanel == data)
350 return;
352 if (WPrefs.currentPanel == NULL) {
353 WMDestroyWidget(WPrefs.nameL);
354 WMDestroyWidget(WPrefs.versionL);
355 WMDestroyWidget(WPrefs.statusL);
357 WMSetFrameRelief(WPrefs.banner, WRGroove);
359 /* WMMapWidget(WPrefs.undosBtn);
360 WMMapWidget(WPrefs.undoBtn);
362 WMMapWidget(WPrefs.saveBtn);
365 showPanel(data);
367 if (WPrefs.currentPanel)
368 hidePanel(WPrefs.currentPanel);
369 WPrefs.currentPanel = data;
372 char *LocateImage(const char *name)
374 char *path;
375 char *tmp = wmalloc(strlen(name) + 8);
377 if (TIFFOK) {
378 sprintf(tmp, "%s.tiff", name);
379 path = WMPathForResourceOfType(tmp, "tiff");
380 } else {
381 sprintf(tmp, "%s.xpm", name);
382 path = WMPathForResourceOfType(tmp, "xpm");
384 wfree(tmp);
385 if (!path) {
386 wwarning(_("could not locate image file %s"), name);
389 return path;
392 void CreateImages(WMScreen *scr, RContext *rc, RImage *xis, const char *file,
393 WMPixmap **icon_normal, WMPixmap **icon_greyed)
395 RImage *icon;
396 char *path;
397 RColor gray = { 0xae, 0xaa, 0xae, 0 };
399 path = LocateImage(file);
400 if (!path)
402 *icon_normal = NULL;
403 if (icon_greyed)
404 *icon_greyed = NULL;
405 return;
408 *icon_normal = WMCreatePixmapFromFile(scr, path);
409 if (!*icon_normal)
411 wwarning(_("could not load icon %s"), path);
412 if (icon_greyed)
413 *icon_greyed = NULL;
414 wfree(path);
415 return;
418 if (!icon_greyed) // Greyed-out version not requested, we are done
420 wfree(path);
421 return;
424 icon = RLoadImage(rc, path, 0);
425 if (!icon)
427 wwarning(_("could not load icon %s"), path);
428 *icon_greyed = NULL;
429 wfree(path);
430 return;
432 RCombineImageWithColor(icon, &gray);
433 if (xis)
435 RCombineImagesWithOpaqueness(icon, xis, 180);
437 *icon_greyed = WMCreatePixmapFromRImage(scr, icon, 127);
438 if (!*icon_greyed)
440 wwarning(_("could not process icon %s: %s"), path, RMessageForError(RErrorCode));
442 RReleaseImage(icon);
443 wfree(path);
447 void SetButtonAlphaImage(WMScreen *scr, WMButton *bPtr, const char *file)
449 WMPixmap *icon;
450 RColor color;
451 char *iconPath;
453 iconPath = LocateImage(file);
455 color.red = 0xae;
456 color.green = 0xaa;
457 color.blue = 0xae;
458 color.alpha = 0;
459 if (iconPath) {
460 icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
461 if (!icon)
462 wwarning(_("could not load icon file %s"), iconPath);
463 } else {
464 icon = NULL;
467 WMSetButtonImage(bPtr, icon);
469 color.red = 0xff;
470 color.green = 0xff;
471 color.blue = 0xff;
472 color.alpha = 0;
473 if (iconPath) {
474 icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
475 if (!icon)
476 wwarning(_("could not load icon file %s"), iconPath);
477 } else {
478 icon = NULL;
481 WMSetButtonAltImage(bPtr, icon);
483 if (icon)
484 WMReleasePixmap(icon);
486 if (iconPath)
487 wfree(iconPath);
490 void AddSection(Panel * panel, const char *iconFile)
492 WMButton *bPtr;
494 assert(WPrefs.sectionCount < MAX_SECTIONS);
496 bPtr = WMCreateCustomButton(WPrefs.buttonF, WBBStateLightMask | WBBStateChangeMask);
497 WMResizeWidget(bPtr, 64, 64);
498 WMMoveWidget(bPtr, WPrefs.sectionCount * 64, 0);
499 WMSetButtonImagePosition(bPtr, WIPImageOnly);
500 WMSetButtonAction(bPtr, changeSection, panel);
501 WMHangData(bPtr, panel);
503 WMSetBalloonTextForView(((PanelRec *) panel)->description, WMWidgetView(bPtr));
504 SetButtonAlphaImage(WMWidgetScreen(bPtr), bPtr, iconFile);
505 WMMapWidget(bPtr);
507 WPrefs.sectionB[WPrefs.sectionCount] = bPtr;
509 if (WPrefs.sectionCount > 0)
510 WMGroupButtons(WPrefs.sectionB[0], bPtr);
512 WPrefs.sectionCount++;
514 WMResizeWidget(WPrefs.buttonF, WPrefs.sectionCount * 64, 64);
517 void Initialize(WMScreen * scr)
519 char **list;
520 int i;
521 char *path;
523 list = RSupportedFileFormats();
524 for (i = 0; list[i] != NULL; i++) {
525 if (strcmp(list[i], "TIFF") == 0) {
526 TIFFOK = True;
527 break;
531 if (TIFFOK)
532 path = WMPathForResourceOfType("WPrefs.tiff", NULL);
533 else
534 path = WMPathForResourceOfType("WPrefs.xpm", NULL);
535 if (path) {
536 RImage *tmp;
538 tmp = RLoadImage(WMScreenRContext(scr), path, 0);
539 if (!tmp) {
540 wwarning(_("could not load image file %s:%s"), path, RMessageForError(RErrorCode));
541 } else {
542 WMSetApplicationIconImage(scr, tmp);
543 RReleaseImage(tmp);
545 wfree(path);
548 memset(&WPrefs, 0, sizeof(_WPrefs));
549 createMainWindow(scr);
551 WMRealizeWidget(WPrefs.win);
553 WMSetWindowMiniwindowImage(WPrefs.win, WMGetApplicationIconImage(scr));
555 WMMapWidget(WPrefs.win);
556 XFlush(WMScreenDisplay(scr));
557 WMSetLabelText(WPrefs.statusL, _("Loading Window Maker configuration files..."));
558 XFlush(WMScreenDisplay(scr));
559 loadConfigurations(scr, WPrefs.win);
561 WMSetLabelText(WPrefs.statusL, _("Initializing configuration panels..."));
563 InitFocus(WPrefs.banner);
564 InitWindowHandling(WPrefs.banner);
566 InitMenuPreferences(WPrefs.banner);
567 InitIcons(WPrefs.banner);
568 InitPreferences(WPrefs.banner);
570 InitPaths(WPrefs.banner);
571 InitDocks(WPrefs.banner);
572 InitWorkspace(WPrefs.banner);
573 InitConfigurations(WPrefs.banner);
575 InitMenu(WPrefs.banner);
577 #ifdef not_yet_fully_implemented
578 InitKeyboardSettings(WPrefs.banner);
579 #endif
580 InitKeyboardShortcuts(WPrefs.banner);
581 InitMouseSettings(WPrefs.banner);
583 InitAppearance(WPrefs.banner);
585 InitFontSimple(WPrefs.banner);
587 #ifdef not_yet_fully_implemented
588 InitThemes(WPrefs.banner);
589 #endif
590 InitExpert(WPrefs.banner);
592 WMRealizeWidget(WPrefs.scrollV);
594 WMSetLabelText(WPrefs.statusL, "");
597 WMWindow *GetWindow(void)
599 return WPrefs.win;
602 static void loadConfigurations(WMScreen * scr, WMWindow * mainw)
604 WMPropList *db, *gdb;
605 char *path;
606 FILE *file;
607 char buffer[1024];
608 char mbuf[1024];
609 int v1, v2, v3;
611 path = wdefaultspathfordomain("WindowMaker");
612 WindowMakerDBPath = path;
614 db = WMReadPropListFromFile(path);
615 if (db) {
616 if (!WMIsPLDictionary(db)) {
617 WMReleasePropList(db);
618 db = NULL;
619 sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), path);
620 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
622 } else {
623 sprintf(mbuf, _("Could not load Window Maker domain (%s) from defaults database."), path);
624 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
627 path = getenv("WMAKER_BIN_NAME");
628 if (!path)
629 path = "wmaker";
631 char *command;
633 command = wstrconcat(path, " --version");
634 file = popen(command, "r");
635 wfree(command);
637 if (!file || !fgets(buffer, 1023, file)) {
638 werror(_("could not extract version information from Window Maker"));
639 wfatal(_("Make sure wmaker is in your search path."));
641 WMRunAlertPanel(scr, mainw, _("Error"),
643 ("Could not extract version from Window Maker. Make sure it is correctly installed and is in your PATH environment variable."),
644 _("OK"), NULL, NULL);
645 exit(1);
647 if (file)
648 pclose(file);
650 if (sscanf(buffer, "Window Maker %i.%i.%i", &v1, &v2, &v3) != 3
651 && sscanf(buffer, "WindowMaker %i.%i.%i", &v1, &v2, &v3) != 3) {
652 WMRunAlertPanel(scr, mainw, _("Error"),
653 _("Could not extract version from Window Maker. "
654 "Make sure it is correctly installed and the path "
655 "where it installed is in the PATH environment "
656 "variable."), _("OK"), NULL, NULL);
657 exit(1);
659 if (v1 == 0 && (v2 < 18 || v3 < 0)) {
660 sprintf(mbuf, _("WPrefs only supports Window Maker 0.18.0 or newer.\n"
661 "The version installed is %i.%i.%i\n"), v1, v2, v3);
662 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
663 exit(1);
666 if (v1 > 1 || (v1 == 1 && (v2 > 0))) {
667 sprintf(mbuf,
669 ("Window Maker %i.%i.%i, which is installed in your system, is not fully supported by this version of WPrefs."),
670 v1, v2, v3);
671 WMRunAlertPanel(scr, mainw, _("Warning"), mbuf, _("OK"), NULL, NULL);
675 char *command;
677 command = wstrconcat(path, " --global_defaults_path");
678 file = popen(command, "r");
679 wfree(command);
681 if (!file || !fgets(buffer, 1023, file)) {
682 werror(_("could not run \"%s --global_defaults_path\"."), path);
683 exit(1);
684 } else {
685 char *ptr;
686 ptr = strchr(buffer, '\n');
687 if (ptr)
688 *ptr = 0;
689 strcat(buffer, "/WindowMaker");
692 if (file)
693 pclose(file);
695 gdb = WMReadPropListFromFile(buffer);
697 if (gdb) {
698 if (!WMIsPLDictionary(gdb)) {
699 WMReleasePropList(gdb);
700 gdb = NULL;
701 sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), buffer);
702 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
704 } else {
705 sprintf(mbuf, _("Could not load global Window Maker domain (%s)."), buffer);
706 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
709 if (!db) {
710 db = WMCreatePLDictionary(NULL, NULL);
712 if (!gdb) {
713 gdb = WMCreatePLDictionary(NULL, NULL);
716 GlobalDB = gdb;
718 WindowMakerDB = db;
721 WMPropList *GetObjectForKey(const char *defaultName)
723 WMPropList *object = NULL;
724 WMPropList *key = WMCreatePLString(defaultName);
726 object = WMGetFromPLDictionary(WindowMakerDB, key);
727 if (!object)
728 object = WMGetFromPLDictionary(GlobalDB, key);
730 WMReleasePropList(key);
732 return object;
735 void SetObjectForKey(WMPropList * object, const char *defaultName)
737 WMPropList *key = WMCreatePLString(defaultName);
739 WMPutInPLDictionary(WindowMakerDB, key, object);
740 WMReleasePropList(key);
743 void RemoveObjectForKey(const char *defaultName)
745 WMPropList *key = WMCreatePLString(defaultName);
747 WMRemoveFromPLDictionary(WindowMakerDB, key);
749 WMReleasePropList(key);
752 char *GetStringForKey(const char *defaultName)
754 WMPropList *val;
756 val = GetObjectForKey(defaultName);
758 if (!val)
759 return NULL;
761 if (!WMIsPLString(val))
762 return NULL;
764 return WMGetFromPLString(val);
767 WMPropList *GetArrayForKey(const char *defaultName)
769 WMPropList *val;
771 val = GetObjectForKey(defaultName);
773 if (!val)
774 return NULL;
776 if (!WMIsPLArray(val))
777 return NULL;
779 return val;
782 WMPropList *GetDictionaryForKey(const char *defaultName)
784 WMPropList *val;
786 val = GetObjectForKey(defaultName);
788 if (!val)
789 return NULL;
791 if (!WMIsPLDictionary(val))
792 return NULL;
794 return val;
797 int GetIntegerForKey(const char *defaultName)
799 WMPropList *val;
800 char *str;
801 int value;
803 val = GetObjectForKey(defaultName);
805 if (!val)
806 return 0;
808 if (!WMIsPLString(val))
809 return 0;
811 str = WMGetFromPLString(val);
812 if (!str)
813 return 0;
815 if (sscanf(str, "%i", &value) != 1)
816 return 0;
818 return value;
821 Bool GetBoolForKey(const char *defaultName)
823 int value;
824 char *str;
826 str = GetStringForKey(defaultName);
828 if (!str)
829 return False;
831 if (sscanf(str, "%i", &value) == 1 && value != 0)
832 return True;
834 if (strcasecmp(str, "YES") == 0)
835 return True;
837 if (strcasecmp(str, "Y") == 0)
838 return True;
840 return False;
843 void SetIntegerForKey(int value, const char *defaultName)
845 WMPropList *object;
846 char buffer[128];
848 sprintf(buffer, "%i", value);
849 object = WMCreatePLString(buffer);
851 SetObjectForKey(object, defaultName);
852 WMReleasePropList(object);
855 void SetStringForKey(const char *value, const char *defaultName)
857 WMPropList *object;
859 object = WMCreatePLString(value);
861 SetObjectForKey(object, defaultName);
862 WMReleasePropList(object);
865 void SetBoolForKey(Bool value, const char *defaultName)
867 static WMPropList *yes = NULL, *no = NULL;
869 if (!yes) {
870 yes = WMCreatePLString("YES");
871 no = WMCreatePLString("NO");
874 SetObjectForKey(value ? yes : no, defaultName);
877 void SetSpeedForKey(int speed, const char *defaultName)
879 char *str;
881 switch (speed) {
882 case 0:
883 str = "ultraslow";
884 break;
885 case 1:
886 str = "slow";
887 break;
888 case 2:
889 str = "medium";
890 break;
891 case 3:
892 str = "fast";
893 break;
894 case 4:
895 str = "ultrafast";
896 break;
897 default:
898 str = NULL;
901 if (str)
902 SetStringForKey(str, defaultName);
905 int GetSpeedForKey(const char *defaultName)
907 char *str;
908 int i;
910 str = GetStringForKey(defaultName);
911 if (!str)
912 return 2;
914 if (strcasecmp(str, "ultraslow") == 0)
915 i = 0;
916 else if (strcasecmp(str, "slow") == 0)
917 i = 1;
918 else if (strcasecmp(str, "medium") == 0)
919 i = 2;
920 else if (strcasecmp(str, "fast") == 0)
921 i = 3;
922 else if (strcasecmp(str, "ultrafast") == 0)
923 i = 4;
924 else {
925 wwarning(_("bad speed value for option %s; using default Medium"), defaultName);
926 i = 2;
928 return i;