Update Serbian translation from master branch
[wmaker-crm.git] / WPrefs.app / WPrefs.c
blobcbffa5af1829bfe50a10225b2520893bcf8acf44
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 MAX_SECTIONS 16
34 typedef struct _WPrefs {
35 WMWindow *win;
37 WMScrollView *scrollV;
38 WMFrame *buttonF;
39 WMButton *sectionB[MAX_SECTIONS];
41 int sectionCount;
43 WMButton *saveBtn;
44 WMButton *closeBtn;
45 WMButton *undoBtn;
46 WMButton *undosBtn;
48 WMButton *balloonBtn;
50 WMFrame *banner;
51 WMLabel *nameL;
52 WMLabel *versionL;
53 WMLabel *statusL;
55 Panel *currentPanel;
56 } _WPrefs;
58 static _WPrefs WPrefs;
60 /* system wide defaults dictionary. Read-only */
61 static WMPropList *GlobalDB = NULL;
62 /* user defaults dictionary */
63 static WMPropList *WindowMakerDB = NULL;
64 static char *WindowMakerDBPath = NULL;
66 static Bool TIFFOK = False;
68 #define INITIALIZED_PANEL (1<<0)
70 static void loadConfigurations(WMScreen * scr, WMWindow * mainw);
72 static void savePanelData(Panel * panel);
74 static void prepareForClose(void);
76 static noreturn void quit(WMWidget *w, void *data)
78 /* Parameter not used, but tell the compiler that it is ok */
79 (void) w;
80 (void) data;
82 prepareForClose();
84 WMReleaseApplication();
85 exit(0);
88 static void save(WMWidget * w, void *data)
90 int i;
91 WMPropList *p1, *p2;
92 WMPropList *keyList;
93 WMPropList *key;
94 XEvent ev;
96 /* Parameter not used, but tell the compiler that it is ok */
97 (void) data;
99 /* puts("gathering data"); */
100 for (i = 0; i < WPrefs.sectionCount; i++) {
101 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
102 if ((rec->callbacks.flags & INITIALIZED_PANEL))
103 savePanelData((Panel *) rec);
105 /* puts("compressing data"); */
106 /* compare the user dictionary with the global and remove redundant data */
107 keyList = WMGetPLDictionaryKeys(GlobalDB);
108 /* puts(WMGetPropListDescription(WindowMakerDB, False)); */
109 for (i = 0; i < WMGetPropListItemCount(keyList); i++) {
110 key = WMGetFromPLArray(keyList, i);
112 /* We don't have this value anyway, so no problem.
113 * Probably a new option */
114 p1 = WMGetFromPLDictionary(WindowMakerDB, key);
115 if (!p1)
116 continue;
117 /* The global doesn't have it, so no problem either. */
118 p2 = WMGetFromPLDictionary(GlobalDB, key);
119 if (!p2)
120 continue;
121 /* If both values are the same, don't save. */
122 if (WMIsPropListEqualTo(p1, p2))
123 WMRemoveFromPLDictionary(WindowMakerDB, key);
125 /* puts(WMGetPropListDescription(WindowMakerDB, False)); */
126 WMReleasePropList(keyList);
127 /* puts("storing data"); */
129 WMWritePropListToFile(WindowMakerDB, WindowMakerDBPath);
131 memset(&ev, 0, sizeof(XEvent));
133 ev.xclient.type = ClientMessage;
134 ev.xclient.message_type = XInternAtom(WMScreenDisplay(WMWidgetScreen(w)), "_WINDOWMAKER_COMMAND", False);
135 ev.xclient.window = DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w)));
136 ev.xclient.format = 8;
137 strncpy(ev.xclient.data.b, "Reconfigure", sizeof(ev.xclient.data.b));
139 XSendEvent(WMScreenDisplay(WMWidgetScreen(w)),
140 DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w))), False, SubstructureRedirectMask, &ev);
141 XFlush(WMScreenDisplay(WMWidgetScreen(w)));
144 static void undo(WMWidget * w, void *data)
146 PanelRec *rec = (PanelRec *) WPrefs.currentPanel;
148 /* Parameter not used, but tell the compiler that it is ok */
149 (void) w;
150 (void) data;
152 if (!rec)
153 return;
155 if (rec->callbacks.undoChanges && (rec->callbacks.flags & INITIALIZED_PANEL)) {
156 (*rec->callbacks.undoChanges) (WPrefs.currentPanel);
160 static void undoAll(WMWidget * w, void *data)
162 int i;
164 /* Parameter not used, but tell the compiler that it is ok */
165 (void) w;
166 (void) data;
168 for (i = 0; i < WPrefs.sectionCount; i++) {
169 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
171 if (rec->callbacks.undoChanges && (rec->callbacks.flags & INITIALIZED_PANEL))
172 (*rec->callbacks.undoChanges) ((Panel *) rec);
176 static void prepareForClose(void)
178 int i;
180 for (i = 0; i < WPrefs.sectionCount; i++) {
181 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
183 if (rec->callbacks.prepareForClose && (rec->callbacks.flags & INITIALIZED_PANEL))
184 (*rec->callbacks.prepareForClose) ((Panel *) rec);
188 static void toggleBalloons(WMWidget *w, void *data)
190 WMUserDefaults *udb = WMGetStandardUserDefaults();
191 Bool flag;
193 /* Parameter not used, but tell the compiler that it is ok */
194 (void) w;
195 (void) data;
197 flag = WMGetButtonSelected(WPrefs.balloonBtn);
199 WMSetBalloonEnabled(WMWidgetScreen(WPrefs.win), flag);
201 WMSetUDBoolForKey(udb, flag, "BalloonHelp");
204 static void createMainWindow(WMScreen * scr)
206 WMScroller *scroller;
207 WMFont *font;
208 char buffer[128];
210 WPrefs.win = WMCreateWindow(scr, "wprefs");
211 WMResizeWidget(WPrefs.win, 520, 390);
212 WMSetWindowTitle(WPrefs.win, _("Window Maker Preferences"));
213 WMSetWindowCloseAction(WPrefs.win, quit, NULL);
214 WMSetWindowMaxSize(WPrefs.win, 520, 390);
215 WMSetWindowMinSize(WPrefs.win, 520, 390);
216 WMSetWindowMiniwindowTitle(WPrefs.win, _("Preferences"));
218 WPrefs.scrollV = WMCreateScrollView(WPrefs.win);
219 WMResizeWidget(WPrefs.scrollV, 500, 87);
220 WMMoveWidget(WPrefs.scrollV, 10, 10);
221 WMSetScrollViewRelief(WPrefs.scrollV, WRSunken);
222 WMSetScrollViewHasHorizontalScroller(WPrefs.scrollV, True);
223 WMSetScrollViewHasVerticalScroller(WPrefs.scrollV, False);
224 scroller = WMGetScrollViewHorizontalScroller(WPrefs.scrollV);
225 WMSetScrollerArrowsPosition(scroller, WSANone);
227 WPrefs.buttonF = WMCreateFrame(WPrefs.win);
228 WMSetFrameRelief(WPrefs.buttonF, WRFlat);
230 WMSetScrollViewContentView(WPrefs.scrollV, WMWidgetView(WPrefs.buttonF));
232 WPrefs.undosBtn = WMCreateCommandButton(WPrefs.win);
233 WMResizeWidget(WPrefs.undosBtn, 90, 28);
234 WMMoveWidget(WPrefs.undosBtn, 135, 350);
235 WMSetButtonText(WPrefs.undosBtn, _("Revert Page"));
236 WMSetButtonAction(WPrefs.undosBtn, undo, NULL);
238 WPrefs.undoBtn = WMCreateCommandButton(WPrefs.win);
239 WMResizeWidget(WPrefs.undoBtn, 90, 28);
240 WMMoveWidget(WPrefs.undoBtn, 235, 350);
241 WMSetButtonText(WPrefs.undoBtn, _("Revert All"));
242 WMSetButtonAction(WPrefs.undoBtn, undoAll, NULL);
244 WPrefs.saveBtn = WMCreateCommandButton(WPrefs.win);
245 WMResizeWidget(WPrefs.saveBtn, 80, 28);
246 WMMoveWidget(WPrefs.saveBtn, 335, 350);
247 WMSetButtonText(WPrefs.saveBtn, _("Save"));
248 WMSetButtonAction(WPrefs.saveBtn, save, NULL);
250 WPrefs.closeBtn = WMCreateCommandButton(WPrefs.win);
251 WMResizeWidget(WPrefs.closeBtn, 80, 28);
252 WMMoveWidget(WPrefs.closeBtn, 425, 350);
253 WMSetButtonText(WPrefs.closeBtn, _("Close"));
254 WMSetButtonAction(WPrefs.closeBtn, quit, NULL);
256 WPrefs.balloonBtn = WMCreateSwitchButton(WPrefs.win);
257 WMResizeWidget(WPrefs.balloonBtn, 200, 28);
258 WMMoveWidget(WPrefs.balloonBtn, 15, 350);
259 WMSetButtonText(WPrefs.balloonBtn, _("Balloon Help"));
260 WMSetButtonAction(WPrefs.balloonBtn, toggleBalloons, NULL);
262 WMUserDefaults *udb = WMGetStandardUserDefaults();
263 Bool flag = WMGetUDBoolForKey(udb, "BalloonHelp");
265 WMSetButtonSelected(WPrefs.balloonBtn, flag);
266 WMSetBalloonEnabled(scr, flag);
269 /* banner */
270 WPrefs.banner = WMCreateFrame(WPrefs.win);
271 WMResizeWidget(WPrefs.banner, FRAME_WIDTH, FRAME_HEIGHT);
272 WMMoveWidget(WPrefs.banner, FRAME_LEFT, FRAME_TOP);
273 WMSetFrameRelief(WPrefs.banner, WRFlat);
275 font = WMCreateFont(scr, "Lucida Sans,URW Gothic L,Times New Roman,serif"
276 ":bold:pixelsize=26:antialias=true");
277 WPrefs.nameL = WMCreateLabel(WPrefs.banner);
278 WMSetLabelTextAlignment(WPrefs.nameL, WACenter);
279 WMResizeWidget(WPrefs.nameL, FRAME_WIDTH - 20, 60);
280 WMMoveWidget(WPrefs.nameL, 10, 50);
281 WMSetLabelFont(WPrefs.nameL, font);
282 WMSetLabelText(WPrefs.nameL, _("Window Maker Preferences"));
283 WMReleaseFont(font);
285 WPrefs.versionL = WMCreateLabel(WPrefs.banner);
286 WMResizeWidget(WPrefs.versionL, FRAME_WIDTH - 20, 20);
287 WMMoveWidget(WPrefs.versionL, 10, 120);
288 WMSetLabelTextAlignment(WPrefs.versionL, WACenter);
289 sprintf(buffer, _("Version %s"), VERSION);
290 WMSetLabelText(WPrefs.versionL, buffer);
292 WPrefs.statusL = WMCreateLabel(WPrefs.banner);
293 WMResizeWidget(WPrefs.statusL, FRAME_WIDTH - 20, 60);
294 WMMoveWidget(WPrefs.statusL, 10, 150);
295 WMSetLabelTextAlignment(WPrefs.statusL, WACenter);
296 WMSetLabelText(WPrefs.statusL, _("Starting..."));
298 WMMapSubwidgets(WPrefs.win);
300 WMUnmapWidget(WPrefs.undosBtn);
301 WMUnmapWidget(WPrefs.undoBtn);
302 WMUnmapWidget(WPrefs.saveBtn);
305 static void showPanel(Panel * panel)
307 PanelRec *rec = (PanelRec *) panel;
309 if (!(rec->callbacks.flags & INITIALIZED_PANEL)) {
310 (*rec->callbacks.createWidgets) (panel);
311 rec->callbacks.flags |= INITIALIZED_PANEL;
314 WMSetWindowTitle(WPrefs.win, rec->sectionName);
316 if (rec->callbacks.showPanel)
317 (*rec->callbacks.showPanel) (panel);
319 WMMapWidget(rec->box);
322 static void hidePanel(Panel * panel)
324 PanelRec *rec = (PanelRec *) panel;
326 WMUnmapWidget(rec->box);
328 if (rec->callbacks.hidePanel)
329 (*rec->callbacks.hidePanel) (panel);
332 static void savePanelData(Panel * panel)
334 PanelRec *rec = (PanelRec *) panel;
336 if (rec->callbacks.updateDomain) {
337 (*rec->callbacks.updateDomain) (panel);
341 static void changeSection(WMWidget * self, void *data)
343 /* Parameter not used, but tell the compiler that it is ok */
344 (void) self;
346 if (WPrefs.currentPanel == data)
347 return;
349 if (WPrefs.currentPanel == NULL) {
350 WMDestroyWidget(WPrefs.nameL);
351 WMDestroyWidget(WPrefs.versionL);
352 WMDestroyWidget(WPrefs.statusL);
354 WMSetFrameRelief(WPrefs.banner, WRGroove);
356 /* WMMapWidget(WPrefs.undosBtn);
357 WMMapWidget(WPrefs.undoBtn);
359 WMMapWidget(WPrefs.saveBtn);
362 showPanel(data);
364 if (WPrefs.currentPanel)
365 hidePanel(WPrefs.currentPanel);
366 WPrefs.currentPanel = data;
369 char *LocateImage(const char *name)
371 char *path;
372 char *tmp = wmalloc(strlen(name) + 8);
374 if (TIFFOK) {
375 sprintf(tmp, "%s.tiff", name);
376 path = WMPathForResourceOfType(tmp, "tiff");
377 } else {
378 sprintf(tmp, "%s.xpm", name);
379 path = WMPathForResourceOfType(tmp, "xpm");
381 wfree(tmp);
382 if (!path) {
383 wwarning(_("could not locate image file %s"), name);
386 return path;
389 void CreateImages(WMScreen *scr, RContext *rc, RImage *xis, const char *file,
390 WMPixmap **icon_normal, WMPixmap **icon_greyed)
392 RImage *icon;
393 char *path;
394 RColor gray = { 0xae, 0xaa, 0xae, 0 };
396 path = LocateImage(file);
397 if (!path)
399 *icon_normal = NULL;
400 if (icon_greyed)
401 *icon_greyed = NULL;
402 return;
405 *icon_normal = WMCreatePixmapFromFile(scr, path);
406 if (!*icon_normal)
408 wwarning(_("could not load icon %s"), path);
409 if (icon_greyed)
410 *icon_greyed = NULL;
411 wfree(path);
412 return;
415 if (!icon_greyed) // Greyed-out version not requested, we are done
417 wfree(path);
418 return;
421 icon = RLoadImage(rc, path, 0);
422 if (!icon)
424 wwarning(_("could not load icon %s"), path);
425 *icon_greyed = NULL;
426 wfree(path);
427 return;
429 RCombineImageWithColor(icon, &gray);
430 if (xis)
432 RCombineImagesWithOpaqueness(icon, xis, 180);
434 *icon_greyed = WMCreatePixmapFromRImage(scr, icon, 127);
435 if (!*icon_greyed)
437 wwarning(_("could not process icon %s: %s"), path, RMessageForError(RErrorCode));
439 RReleaseImage(icon);
440 wfree(path);
444 void SetButtonAlphaImage(WMScreen *scr, WMButton *bPtr, const char *file)
446 WMPixmap *icon;
447 RColor color;
448 char *iconPath;
450 iconPath = LocateImage(file);
452 color.red = 0xae;
453 color.green = 0xaa;
454 color.blue = 0xae;
455 color.alpha = 0;
456 if (iconPath) {
457 icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
458 if (!icon)
459 wwarning(_("could not load icon file %s"), iconPath);
460 } else {
461 icon = NULL;
464 WMSetButtonImage(bPtr, icon);
466 color.red = 0xff;
467 color.green = 0xff;
468 color.blue = 0xff;
469 color.alpha = 0;
470 if (iconPath) {
471 icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
472 if (!icon)
473 wwarning(_("could not load icon file %s"), iconPath);
474 } else {
475 icon = NULL;
478 WMSetButtonAltImage(bPtr, icon);
480 if (icon)
481 WMReleasePixmap(icon);
483 if (iconPath)
484 wfree(iconPath);
487 void AddSection(Panel * panel, const char *iconFile)
489 WMButton *bPtr;
491 assert(WPrefs.sectionCount < MAX_SECTIONS);
493 bPtr = WMCreateCustomButton(WPrefs.buttonF, WBBStateLightMask | WBBStateChangeMask);
494 WMResizeWidget(bPtr, 64, 64);
495 WMMoveWidget(bPtr, WPrefs.sectionCount * 64, 0);
496 WMSetButtonImagePosition(bPtr, WIPImageOnly);
497 WMSetButtonAction(bPtr, changeSection, panel);
498 WMHangData(bPtr, panel);
500 WMSetBalloonTextForView(((PanelRec *) panel)->description, WMWidgetView(bPtr));
501 SetButtonAlphaImage(WMWidgetScreen(bPtr), bPtr, iconFile);
502 WMMapWidget(bPtr);
504 WPrefs.sectionB[WPrefs.sectionCount] = bPtr;
506 if (WPrefs.sectionCount > 0)
507 WMGroupButtons(WPrefs.sectionB[0], bPtr);
509 WPrefs.sectionCount++;
511 WMResizeWidget(WPrefs.buttonF, WPrefs.sectionCount * 64, 64);
514 void Initialize(WMScreen * scr)
516 char **list;
517 int i;
518 char *path;
520 list = RSupportedFileFormats();
521 for (i = 0; list[i] != NULL; i++) {
522 if (strcmp(list[i], "TIFF") == 0) {
523 TIFFOK = True;
524 break;
528 if (TIFFOK)
529 path = WMPathForResourceOfType("WPrefs.tiff", NULL);
530 else
531 path = WMPathForResourceOfType("WPrefs.xpm", NULL);
532 if (path) {
533 RImage *tmp;
535 tmp = RLoadImage(WMScreenRContext(scr), path, 0);
536 if (!tmp) {
537 wwarning(_("could not load image file %s:%s"), path, RMessageForError(RErrorCode));
538 } else {
539 WMSetApplicationIconImage(scr, tmp);
540 RReleaseImage(tmp);
542 wfree(path);
545 memset(&WPrefs, 0, sizeof(_WPrefs));
546 createMainWindow(scr);
548 WMRealizeWidget(WPrefs.win);
550 WMSetWindowMiniwindowImage(WPrefs.win, WMGetApplicationIconImage(scr));
552 WMMapWidget(WPrefs.win);
553 XFlush(WMScreenDisplay(scr));
554 WMSetLabelText(WPrefs.statusL, _("Loading Window Maker configuration files..."));
555 XFlush(WMScreenDisplay(scr));
556 loadConfigurations(scr, WPrefs.win);
558 WMSetLabelText(WPrefs.statusL, _("Initializing configuration panels..."));
560 InitFocus(WPrefs.banner);
561 InitWindowHandling(WPrefs.banner);
563 InitMenuPreferences(WPrefs.banner);
564 InitIcons(WPrefs.banner);
565 InitPreferences(WPrefs.banner);
567 InitPaths(WPrefs.banner);
568 InitDocks(WPrefs.banner);
569 InitWorkspace(WPrefs.banner);
570 InitConfigurations(WPrefs.banner);
572 InitMenu(WPrefs.banner);
574 #ifdef not_yet_fully_implemented
575 InitKeyboardSettings(WPrefs.banner);
576 #endif
577 InitKeyboardShortcuts(WPrefs.banner);
578 InitHotCornerShortcuts(WPrefs.banner);
579 InitMouseSettings(WPrefs.banner);
581 InitAppearance(WPrefs.banner);
583 InitFontSimple(WPrefs.banner);
585 #ifdef not_yet_fully_implemented
586 InitThemes(WPrefs.banner);
587 #endif
588 InitExpert(WPrefs.banner);
590 WMRealizeWidget(WPrefs.scrollV);
592 WMSetLabelText(WPrefs.statusL, "");
595 WMWindow *GetWindow(void)
597 return WPrefs.win;
600 static void loadConfigurations(WMScreen * scr, WMWindow * mainw)
602 WMPropList *db, *gdb;
603 char *path;
604 FILE *file;
605 char buffer[1024];
606 char mbuf[1069]; /* Size of buffer and extra characters for the sprintfs */
607 int v1, v2, v3;
609 path = wdefaultspathfordomain("WindowMaker");
610 WindowMakerDBPath = path;
612 db = WMReadPropListFromFile(path);
613 if (db) {
614 if (!WMIsPLDictionary(db)) {
615 WMReleasePropList(db);
616 db = NULL;
617 sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), path);
618 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
620 } else {
621 sprintf(mbuf, _("Could not load Window Maker domain (%s) from defaults database."), path);
622 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
625 path = getenv("WMAKER_BIN_NAME");
626 if (!path)
627 path = "wmaker";
629 char *command;
631 command = wstrconcat(path, " --version");
632 file = popen(command, "r");
633 wfree(command);
635 if (!file || !fgets(buffer, 1023, file)) {
636 werror(_("could not extract version information from Window Maker"));
637 wfatal(_("Make sure wmaker is in your search path."));
639 WMRunAlertPanel(scr, mainw, _("Error"),
641 ("Could not extract version from Window Maker. Make sure it is correctly installed and is in your PATH environment variable."),
642 _("OK"), NULL, NULL);
643 exit(1);
645 if (file)
646 pclose(file);
648 if (sscanf(buffer, "Window Maker %i.%i.%i", &v1, &v2, &v3) != 3
649 && sscanf(buffer, "WindowMaker %i.%i.%i", &v1, &v2, &v3) != 3) {
650 WMRunAlertPanel(scr, mainw, _("Error"),
651 _("Could not extract version from Window Maker. "
652 "Make sure it is correctly installed and the path "
653 "where it installed is in the PATH environment "
654 "variable."), _("OK"), NULL, NULL);
655 exit(1);
657 if (v1 == 0 && (v2 < 18 || v3 < 0)) {
658 sprintf(mbuf, _("WPrefs only supports Window Maker 0.18.0 or newer.\n"
659 "The version installed is %i.%i.%i\n"), v1, v2, v3);
660 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
661 exit(1);
664 if (v1 > 1 || (v1 == 1 && (v2 > 0))) {
665 sprintf(mbuf,
667 ("Window Maker %i.%i.%i, which is installed in your system, is not fully supported by this version of WPrefs."),
668 v1, v2, v3);
669 WMRunAlertPanel(scr, mainw, _("Warning"), mbuf, _("OK"), NULL, NULL);
673 char *command;
675 command = wstrconcat(path, " --global_defaults_path");
676 file = popen(command, "r");
677 wfree(command);
679 if (!file || !fgets(buffer, 1023, file)) {
680 werror(_("could not run \"%s --global_defaults_path\"."), path);
681 exit(1);
682 } else {
683 char *ptr;
684 ptr = strchr(buffer, '\n');
685 if (ptr)
686 *ptr = 0;
687 strcat(buffer, "/WindowMaker");
690 if (file)
691 pclose(file);
693 gdb = WMReadPropListFromFile(buffer);
695 if (gdb) {
696 if (!WMIsPLDictionary(gdb)) {
697 WMReleasePropList(gdb);
698 gdb = NULL;
699 sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), buffer);
700 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
702 } else {
703 sprintf(mbuf, _("Could not load global Window Maker domain (%s)."), buffer);
704 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
707 if (!db) {
708 db = WMCreatePLDictionary(NULL, NULL);
710 if (!gdb) {
711 gdb = WMCreatePLDictionary(NULL, NULL);
714 GlobalDB = gdb;
716 WindowMakerDB = db;
719 WMPropList *GetObjectForKey(const char *defaultName)
721 WMPropList *object = NULL;
722 WMPropList *key = WMCreatePLString(defaultName);
724 object = WMGetFromPLDictionary(WindowMakerDB, key);
725 if (!object)
726 object = WMGetFromPLDictionary(GlobalDB, key);
728 WMReleasePropList(key);
730 return object;
733 void SetObjectForKey(WMPropList * object, const char *defaultName)
735 WMPropList *key = WMCreatePLString(defaultName);
737 WMPutInPLDictionary(WindowMakerDB, key, object);
738 WMReleasePropList(key);
741 void RemoveObjectForKey(const char *defaultName)
743 WMPropList *key = WMCreatePLString(defaultName);
745 WMRemoveFromPLDictionary(WindowMakerDB, key);
747 WMReleasePropList(key);
750 char *GetStringForKey(const char *defaultName)
752 WMPropList *val;
754 val = GetObjectForKey(defaultName);
756 if (!val)
757 return NULL;
759 if (!WMIsPLString(val))
760 return NULL;
762 return WMGetFromPLString(val);
765 WMPropList *GetArrayForKey(const char *defaultName)
767 WMPropList *val;
769 val = GetObjectForKey(defaultName);
771 if (!val)
772 return NULL;
774 if (!WMIsPLArray(val))
775 return NULL;
777 return val;
780 WMPropList *GetDictionaryForKey(const char *defaultName)
782 WMPropList *val;
784 val = GetObjectForKey(defaultName);
786 if (!val)
787 return NULL;
789 if (!WMIsPLDictionary(val))
790 return NULL;
792 return val;
795 int GetIntegerForKey(const char *defaultName)
797 WMPropList *val;
798 char *str;
799 int value;
801 val = GetObjectForKey(defaultName);
803 if (!val)
804 return 0;
806 if (!WMIsPLString(val))
807 return 0;
809 str = WMGetFromPLString(val);
810 if (!str)
811 return 0;
813 if (sscanf(str, "%i", &value) != 1)
814 return 0;
816 return value;
819 Bool GetBoolForKey(const char *defaultName)
821 int value;
822 char *str;
824 str = GetStringForKey(defaultName);
826 if (!str)
827 return False;
829 if (sscanf(str, "%i", &value) == 1 && value != 0)
830 return True;
832 if (strcasecmp(str, "YES") == 0)
833 return True;
835 if (strcasecmp(str, "Y") == 0)
836 return True;
838 return False;
841 void SetIntegerForKey(int value, const char *defaultName)
843 WMPropList *object;
844 char buffer[128];
846 sprintf(buffer, "%i", value);
847 object = WMCreatePLString(buffer);
849 SetObjectForKey(object, defaultName);
850 WMReleasePropList(object);
853 void SetStringForKey(const char *value, const char *defaultName)
855 WMPropList *object;
857 object = WMCreatePLString(value);
859 SetObjectForKey(object, defaultName);
860 WMReleasePropList(object);
863 void SetBoolForKey(Bool value, const char *defaultName)
865 static WMPropList *yes = NULL, *no = NULL;
867 if (!yes) {
868 yes = WMCreatePLString("YES");
869 no = WMCreatePLString("NO");
872 SetObjectForKey(value ? yes : no, defaultName);
875 void SetSpeedForKey(int speed, const char *defaultName)
877 char *str;
879 switch (speed) {
880 case 0:
881 str = "ultraslow";
882 break;
883 case 1:
884 str = "slow";
885 break;
886 case 2:
887 str = "medium";
888 break;
889 case 3:
890 str = "fast";
891 break;
892 case 4:
893 str = "ultrafast";
894 break;
895 default:
896 str = NULL;
899 if (str)
900 SetStringForKey(str, defaultName);
903 int GetSpeedForKey(const char *defaultName)
905 char *str;
906 int i;
908 str = GetStringForKey(defaultName);
909 if (!str)
910 return 2;
912 if (strcasecmp(str, "ultraslow") == 0)
913 i = 0;
914 else if (strcasecmp(str, "slow") == 0)
915 i = 1;
916 else if (strcasecmp(str, "medium") == 0)
917 i = 2;
918 else if (strcasecmp(str, "fast") == 0)
919 i = 3;
920 else if (strcasecmp(str, "ultrafast") == 0)
921 i = 4;
922 else {
923 wwarning(_("bad speed value for option %s; using default Medium"), defaultName);
924 i = 2;
926 return i;