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

Archive Download this file

Revision: 54