Chameleon Applications

Chameleon Applications Svn Source Tree

Root/trunk/ChameleonPrefPane/Sources/PreferencesControllerBase.mm

1//
2// PreferencesControllerBase.mm
3// ChameleonPrefPane
4//
5// Created by Rekursor on 1/22/10.
6//
7
8#import "PreferencesControllerBase.h"
9#import "KernOptionsParser.h"
10#include <string>
11#include <list>
12#include <map>
13#include <ctype.h>
14
15
16//--------------------------------------------------------------------------
17static std::list< id<GroupControllerProtocol> > groupList;
18
19// for unix-like options types
20static std::map<void*, std::string> IdToUCmdList;
21static KernOptionsParser kernelFlags;
22
23//--------------------------------------------------------------------------
24
25
26@implementation PreferencesControllerBase
27
28-(ChameleonPrefPane*) chameleon { return [ChameleonPrefPane instance]; }
29
30
31//--------------------------------------------------------------------------
32- (id) init
33{
34self = [super init];
35
36[PreferencesControllerBase registerPreferencesGroup: self];
37
38return self;
39}
40//--------------------------------------------------------------------------
41- (id) getResourcePath: (NSString *) str ofType: (NSString*) sType
42{
43NSImage * img=nil;
44if(!str) return nil;
45NSBundle * b = [NSBundle bundleForClass:[self class]];
46id sRes = [b pathForResource: str ofType:sType ];
47return sRes;
48}
49
50
51//--------------------------------------------------------------------------
52// get authorisation from main panel lock
53- (AuthorizationRef) getAuthorization
54{
55AuthorizationRef auth= [[self chameleon] isUnlocked] ?
56[[ [self chameleon]->authView authorization] authorizationRef] : NULL;
57return auth;
58}
59//--------------------------------------------------------------------------
60+ (void) registerPreferencesGroup:(id) myGroup
61{
62groupList.push_back(myGroup);
63}
64
65//--------------------------------------------------------------------------
66+ (void) refreshLockState: (id) item
67{
68 [item setEnabled:[[ChameleonPrefPane instance] isUnlocked]];
69
70}
71
72//--------------------------------------------------------------------------
73+ (void) refreshLockStates
74{
75for (const BootOptionDesc* bod=BootProp::instance().firstOption();
76 bod;
77 bod=BootProp::instance().nextOption())
78{
79[self refreshLockState: (id) bod->ID ];
80if (bod->contentID) [self refreshLockState: (id) bod->contentID ];
81}
82
83}
84//--------------------------------------------------------------------------
85+ (void) doForEachGroup: (GroupAction) action withOption:(id) option
86{
87std::list<id>::iterator it;
88for (it=groupList.begin(); it!=groupList.end(); it++)
89{
90switch (action) {
91case SetDefaultValues:
92[*it setDefaultsValues: option];
93break;
94case RefreshLockStates:
95[*it refreshLockStates ];
96[PreferencesControllerBase refreshLockStates];
97break;
98case LoadPreferencesOptions:
99[*it loadOptionsFromPreferencesFile: option];
100break;
101case LoadBootConfigOptions:
102[*it loadOptionsFromBootFile];
103break;
104case AddOptionsDesc:
105[*it addOptionsDesc];
106break;
107case SaveBootConfigOptions:
108break;
109default:
110break;
111}
112}
113}
114
115//--------------------------------------------------------------------------
116+ (void) loadOptionsFromBootFile
117{
118// parse unix like command string:
119kernelFlags.parseOptions(BootProp::instance().getStringForKey(kKernelFlags));
120
121for (const BootOptionDesc* bod=BootProp::instance().firstOption();
122 bod;
123 bod=BootProp::instance().nextOption())
124{
125[PreferencesControllerBase loadOptionFromBootFile:(id)bod->ID ];
126}
127}
128
129//--------------------------------------------------------------------------
130
131+ (void) loadOptionFromBootFile:(id) optionID
132{
133const BootOptionDesc* bod = BootProp::instance().findOption(optionID);
134if (!bod)
135{
136NSRunAlertPanel(@"Error Parsing Option",@"loadOptionFromBootFile failed",@"OK", nil, nil);
137return;
138}
139
140const char * stringForKey = BootProp::instance().getStringForKey(bod->Name);
141std::string s = stringForKey ? trim(stringForKey) : "";
142std::string def = trim(bod->Default ? bod->Default : "");
143
144switch (bod->Type)
145{
146case OptionYesNo:
147if (s.length()>0)
148[(NSButton*)optionID setIntValue: (toupper(s[0])=='Y' ? 1 : 0 ) ];
149else
150[(NSButton*)optionID setIntValue: (toupper(def[0])=='Y' ? 1 : 0 ) ];
151break;
152
153case OptionKernel1:
154{
155int val = (s.length()>0 ? 1 : 0 );
156[(NSButton*)optionID setIntValue: val ];
157[(NSTextField*) bod->contentID setStringValue:
158 [[NSString alloc] initWithUTF8String: s.c_str()] ];
159[(NSTextField*) bod->contentID setEnabled: val ? true : false];
160[(NSTextField*) bod->contentID setEditable: val ? true : false];
161}
162break;
163case OptionString:
164{
165int val = (s.length()>0 ? 1 : 0 );
166[(NSButton*)optionID setIntValue: val ];
167[(NSTextField*) bod->contentID setStringValue:
168[[NSString alloc] initWithUTF8String: s.c_str()] ];
169[(NSTextField*) bod->contentID setEnabled: val ? true: false];
170[(NSTextField*) bod->contentID setEditable: val ? true : false];
171}
172break;
173
174case OptionUnix:
175case OptionKernel:
176{
177std::string s = kernelFlags.stringFromKey(bod->Name);
178if (s.length()>0)
179{
180[(NSButton*)optionID setIntValue: 1 ];
181if(bod->Type==OptionKernel)
182{
183[(NSTextField*) bod->contentID setStringValue:
184 [[NSString alloc] initWithUTF8String:
185kernelFlags.rightMember(s).c_str()] ];
186[(NSTextField*) bod->contentID setEnabled: true];
187[(NSTextField*) bod->contentID setEditable: true];
188}
189
190}
191else
192{ // set the default for thiso option
193[(NSButton*)optionID setIntValue: (bod->Default[0] ? 1 :0) ];
194if(bod->Type==OptionKernel)
195{
196[(NSTextField*) bod->contentID setEnabled: false];
197[(NSTextField*) bod->contentID setEditable: false];
198}
199
200}
201}
202break;
203default:
204break;
205}
206
207}
208
209//--------------------------------------------------------------------------
210- (void) loadPreferences
211{
212[ [ChameleonPrefPane instance] loadPreferences];
213}
214
215//--------------------------------------------------------------------------
216- (bool) savePreferences
217{
218return [ [ChameleonPrefPane instance] savePreferences: [self preferencesFile] ];
219
220}
221//--------------------------------------------------------------------------
222// update the boot Config with one option change and its associated desc
223- (bool) saveBootConfig: (id) sender withBootOptionDesc: (BootOptionDesc*) bod
224{
225if(!bod)
226{
227return false;
228}
229// load boot config file so that we don't risk to loose
230// externally modified parameters
231
232int val = [(NSButton*) sender intValue ];
233std::string sDefaultValue = trim(bod->Default ? bod->Default : "");
234bool status = false;
235std::string name = trim(bod->Name);
236
237switch (bod->Type) {
238case OptionYesNo:
239{
240std::string sVal = val ? "Yes" : "No";
241if (sDefaultValue.length()==0) sDefaultValue= "No";
242// Avoid populating bootConfig with unnecessary options:
243if (sVal == sDefaultValue)
244status = BootProp::instance().removeKeyAndValue(name.c_str());
245else
246status = BootProp::instance().setStringForKey(name, sVal.c_str());
247}
248break;
249case OptionUnix:
250if (!val)kernelFlags.removeFlag(name);
251elsekernelFlags.addFlag(name);
252BootProp::instance().setStringForKey(kKernelFlags,kernelFlags.options());
253status = true;
254break;
255case OptionKernel:
256{
257std::string contentValue = trim(
258[ [(NSTextField*) bod->contentID stringValue] UTF8String ]);
259kernelFlags.removeFlag(kernelFlags.stringFromKey(bod->Name));
260if(val && contentValue.length()>0)
261{
262std::string concat = trim(name);
263concat+= "=";
264concat+= trim(contentValue);
265
266kernelFlags.addFlag(concat);
267}
268BootProp::instance().setStringForKey(kKernelFlags,kernelFlags.options());
269status = true;
270}
271break;
272case OptionKernel1:
273case OptionString:
274// Avoid populating bootConfig with unnecessary options:
275if (val == 0 && bod->Type!=OptionKernel1)
276status = BootProp::instance().removeKeyAndValue(bod->Name);
277else
278{
279std::string contentValue =
280[ [(NSTextField*) bod->contentID stringValue] UTF8String ];
281if (contentValue.length()>0)
282status = BootProp::instance().setStringForKey(bod->Name, contentValue.c_str());
283else {
284return false; // no content to save so don't save it
285}
286
287}
288break;
289default:
290break;
291}
292
293// Now save the bootConfig
294AuthorizationRef auth = [self getAuthorization ];
295if (status)status = BootProp::instance().save(auth);
296
297return status;
298}
299//--------------------------------------------------------------------------
300-(NSMutableDictionary*) preferencesFile
301{
302return [[ChameleonPrefPane instance] preferencesFile];
303}
304
305//--------------------------------------------------------------------------
306-(NSMutableDictionary*) preferencesParts
307{
308return [[ChameleonPrefPane instance] preferencesParts];
309}
310
311//--------------------------------------------------------------------------
312- (bool) handleSender: (id) sender
313{
314
315const BootOptionDesc * bod = BootProp::instance().findOption(sender);
316
317if (!bod) {
318bod = BootProp::instance().findOptionContent(sender);
319NSTextField* textField = (NSTextField*) sender;
320std::string content = [[textField stringValue] UTF8String ];
321if(bod->ID!=nil) sender = (id) bod->ID;
322}
323else
324{
325
326int state = [sender intValue];
327
328switch (bod->Type) {
329case OptionKernel:
330case OptionKernel1:
331case OptionString:
332[(NSTextField*) bod->contentID setEnabled: state ? true : false];
333[(NSTextField*) bod->contentID setEditable: state ? true : false];
334break;
335default:
336break;
337}
338}
339if(![self saveBootConfig: sender withBootOptionDesc: (BootOptionDesc*) bod] && !bod->contentID )
340{ // Couldn't save, so warn user ...
341NSRunAlertPanel(@"Error saving bootConfig", @"Could not save com.apple.Boot.plist",
342@"OK", nil, nil);
343}
344return true;
345}
346
347@end
348

Archive Download this file

Revision: 65