1/*
2	PrefsAppController.m
3
4	Controller class for this bundle
5
6	Copyright (C) 2001 Dusk to Dawn Computing, Inc.
7	Additional copyrights here
8
9	Author: Jeff Teunissen <deek@d2dc.net>
10	Date:	24 Nov 2001
11
12	This program is free software; you can redistribute it and/or
13	modify it under the terms of the GNU General Public License as
14	published by the Free Software Foundation; either version 2 of
15	the License, or (at your option) any later version.
16
17	This program is distributed in the hope that it will be useful,
18	but WITHOUT ANY WARRANTY; without even the implied warranty of
19	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20
21	See the GNU General Public License for more details.
22
23	You should have received a copy of the GNU General Public
24	License along with this program; if not, write to:
25
26		Free Software Foundation, Inc.
27		59 Temple Place - Suite 330
28		Boston, MA  02111-1307, USA
29*/
30static const char rcsid[] =
31	"$Id: PrefsApp.m,v 1.3 2002/06/08 08:29:36 deek Exp $";
32
33#ifdef HAVE_CONFIG_H
34# include "Config.h"
35#endif
36
37#import <Foundation/NSDebug.h>
38#import <Foundation/NSUserDefaults.h>
39#import <Foundation/NSValue.h>
40
41#import <AppKit/NSButton.h>
42#import <AppKit/NSNibLoading.h>
43#import <AppKit/NSOpenPanel.h>
44
45#import "PrefsApp.h"
46#import "PrefsAppView.h"
47
48@interface PrefsApp (Private)
49
50- (NSDictionary *) preferencesFromDefaults;
51- (void) savePreferencesToDefaults: (NSDictionary *) dict;
52
53- (void) commitDisplayedValues;
54- (void) discardDisplayedValues;
55
56- (void) updateUI;
57
58@end
59
60@implementation PrefsApp (Private)
61
62static NSDictionary			*currentValues = nil;
63static NSMutableDictionary	*displayedValues = nil;
64static id <PrefsController>	controller;
65
66static NSMutableDictionary *
67defaultValues (void) {
68    static NSMutableDictionary *dict = nil;
69
70    if (!dict) {
71        dict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
72				[NSNumber numberWithBool: YES], @"BundlesFromUser",
73				[NSNumber numberWithBool: YES], @"BundlesFromLocal",
74				[NSNumber numberWithBool: YES], @"BundlesFromNetwork",
75				[NSNumber numberWithBool: YES], @"BundlesFromSystem",
76				nil];
77    }
78    return dict;
79}
80
81static BOOL
82getBoolDefault (NSMutableDictionary *dict, NSString *name)
83{
84	NSString	*str = [[NSUserDefaults standardUserDefaults] stringForKey: name];
85	NSNumber	*num = nil;
86
87	if (!str) {	// not in the database, get it from our internals
88		num = [defaultValues() objectForKey: name];
89	} else {
90		NSArray			*trues = [[NSArray alloc] initWithObjects:
91							@"YES", @"Yes", @"Y", @"yes",	// things that eval to YES
92							@"TRUE", @"True", @"true",
93							@"1", nil];
94		NSEnumerator	*list;
95		id				temp;
96
97		list = [trues objectEnumerator];
98		while ((temp = [list nextObject])) {
99			if ([str isEqualToString: temp]) {
100				num = [NSNumber numberWithBool: YES];
101				break;
102			}
103		}
104
105		if (!num)
106			num = [NSNumber numberWithBool: NO];
107	}
108
109	[dict setObject: num forKey: name];
110
111	return [num boolValue];
112}
113
114#if 0
115static NSString *
116getStringDefault (NSMutableDictionary *dict, NSString *name)
117{
118	NSString	*str = [[NSUserDefaults standardUserDefaults] stringForKey: name];
119
120	if (!str)
121		str = [defaultValues() objectForKey: name];
122
123	[dict setObject: str forKey: name];
124
125	return str;
126}
127#endif
128
129- (NSDictionary *) preferencesFromDefaults
130{
131	NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity: 5];
132
133	getBoolDefault (dict, @"BundlesFromLocal");
134	getBoolDefault (dict, @"BundlesFromNetwork");
135	getBoolDefault (dict, @"BundlesFromSystem");
136	getBoolDefault (dict, @"BundlesFromUser");
137	return dict;
138}
139
140- (void) savePreferencesToDefaults: (NSDictionary *) dict
141{
142	NSUserDefaults	*defaults = [NSUserDefaults standardUserDefaults];
143
144#define setStringDefault(name) \
145	[defaults setObject: [dict objectForKey: (name)] forKey: (name)]
146#define setBoolDefault(name) \
147	[defaults setBool: [[dict objectForKey: (name)] boolValue] forKey: (name)]
148
149	NSDebugLog (@"Updating Main Preferences...");
150	setBoolDefault (@"BundlesFromLocal");
151	setBoolDefault (@"BundlesFromNetwork");
152	setBoolDefault (@"BundlesFromSystem");
153	setBoolDefault (@"BundlesFromUser");
154	[defaults synchronize];
155}
156
157- (void) commitDisplayedValues
158{
159	[currentValues release];
160	currentValues = [[displayedValues copy] retain];
161	[self savePreferencesToDefaults: currentValues];
162	[self updateUI];
163}
164
165- (void) discardDisplayedValues
166{
167	[displayedValues release];
168	displayedValues = [[currentValues mutableCopy] retain];
169	[self updateUI];
170}
171
172- (void) updateUI
173{
174	[bundlesFromLocalButton setIntValue: [[displayedValues objectForKey: @"BundlesFromLocal"] intValue]];
175	[bundlesFromNetworkButton setIntValue: [[displayedValues objectForKey: @"BundlesFromNetwork"] intValue]];
176	[bundlesFromSystemButton setIntValue: [[displayedValues objectForKey: @"BundlesFromSystem"] intValue]];
177	[bundlesFromUserButton setIntValue: [[displayedValues objectForKey: @"BundlesFromUser"] intValue]];
178	[view setNeedsDisplay: YES];
179}
180
181@end	// PrefsApp (Private)
182
183@implementation PrefsApp
184
185static PrefsApp			*sharedInstance = nil;
186static id <PrefsApplication>	owner = nil;
187
188- (id) initWithOwner: (id <PrefsApplication>) anOwner
189{
190	if (sharedInstance) {
191		[self dealloc];
192	} else {
193		self = [super init];
194		owner = anOwner;
195		controller = [owner prefsController];
196		[controller registerPrefsModule: self];
197		if (![NSBundle loadNibNamed: @"PrefsApp" owner: self]) {
198			NSLog (@"PrefsApp: Could not load nib \"PrefsApp\", using compiled-in version");
199			view = [[PrefsAppView alloc] initWithOwner: self andFrame: PrefsRect];
200
201			// hook up to our outlet(s)
202			bundlesFromUserButton = [view bundlesFromUserButton];
203			bundlesFromLocalButton = [view bundlesFromLocalButton];
204			bundlesFromNetworkButton = [view bundlesFromNetworkButton];
205			bundlesFromSystemButton = [view bundlesFromSystemButton];
206		} else {
207			// window can be any size, as long as it's 486x228 :)
208			view = [window contentView];
209		}
210		[view retain];
211
212		[self loadPrefs: self];
213
214		sharedInstance = self;
215	}
216	return sharedInstance;
217}
218
219- (void) loadPrefs: (id) sender
220{
221	if (currentValues)
222		[currentValues release];
223
224	currentValues = [[[self preferencesFromDefaults] copyWithZone: [self zone]] retain];
225	[self discardDisplayedValues];
226}
227
228- (void) savePrefs: (id) sender
229{
230	[self commitDisplayedValues];
231}
232
233- (void) resetPrefsToDefault: (id) sender
234{
235	if (currentValues)
236		[currentValues release];
237
238	currentValues = [[defaultValues () copyWithZone: [self zone]] retain];
239
240	[self discardDisplayedValues];
241}
242
243- (void) showView: (id) sender;
244{
245	[controller setCurrentModule: self];
246	[view setNeedsDisplay: YES];
247}
248
249- (NSView *) view
250{
251	return view;
252}
253
254- (NSString *) buttonCaption
255{
256	return @"Preferences.app Preferences";
257}
258
259- (NSImage *) buttonImage
260{
261	return [NSImage imageNamed: @"NSApplicationIcon"];
262}
263
264- (SEL) buttonAction
265{
266	return @selector(showView:);
267}
268
269/*
270	Action methods
271*/
272- (IBAction) bundlesFromLocalButtonChanged: (id) sender
273{
274	[displayedValues setObject: [NSNumber numberWithBool: [sender intValue]] forKey: @"BundlesFromLocal"];
275	[self updateUI];
276}
277
278- (IBAction) bundlesFromNetworkButtonChanged: (id) sender
279{
280	[displayedValues setObject: [NSNumber numberWithBool: [sender intValue]] forKey: @"BundlesFromNetwork"];
281	[self updateUI];
282}
283
284- (IBAction) bundlesFromSystemButtonChanged: (id) sender
285{
286	[displayedValues setObject: [NSNumber numberWithBool: [sender intValue]] forKey: @"BundlesFromSystem"];
287	[self updateUI];
288}
289
290- (IBAction) bundlesFromUserButtonChanged: (id) sender
291{
292	[displayedValues setObject: [NSNumber numberWithBool: [sender intValue]] forKey: @"BundlesFromUser"];
293	[self updateUI];
294}
295
296@end	// PrefsApp
297