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

Archive Download this file

Revision: 49