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) : "";
161std::string def = trim(bod->Default ? bod->Default : "");
162
163switch (bod->Type)
164{
165case OptionYesNo:
166if (s.length()>0)
167[(NSButton*)optionID setIntValue: (toupper(s[0])=='Y' ? 1 : 0 ) ];
168else
169[(NSButton*)optionID setIntValue: (toupper(def[0])=='Y' ? 1 : 0 ) ];
170break;
171
172case OptionKernel1:
173{
174int val = (s.length()>0 ? 1 : 0 );
175[(NSButton*)optionID setIntValue: val ];
176[(NSTextField*) bod->contentID setStringValue:
177 [[NSString alloc] initWithUTF8String: s.c_str()] ];
178[(NSTextField*) bod->contentID setEnabled: val ? true : false];
179[(NSTextField*) bod->contentID setEditable: val ? true : false];
180}
181break;
182case OptionString:
183{
184int val = (s.length()>0 ? 1 : 0 );
185[(NSButton*)optionID setIntValue: val ];
186[(NSTextField*) bod->contentID setStringValue:
187[[NSString alloc] initWithUTF8String: s.c_str()] ];
188[(NSTextField*) bod->contentID setEnabled: val ? true: false];
189[(NSTextField*) bod->contentID setEditable: val ? true : false];
190}
191break;
192
193case OptionUnix:
194case OptionKernel:
195{
196std::string s = kernelFlags.stringFromKey(bod->Name);
197if (s.length()>0)
198{
199[(NSButton*)optionID setIntValue: 1 ];
200if(bod->Type==OptionKernel)
201{
202[(NSTextField*) bod->contentID setStringValue:
203 [[NSString alloc] initWithUTF8String:
204kernelFlags.rightMember(s).c_str()] ];
205[(NSTextField*) bod->contentID setEnabled: true];
206[(NSTextField*) bod->contentID setEditable: true];
207}
208
209}
210else
211{ // set the default for thiso option
212[(NSButton*)optionID setIntValue: (bod->Default[0] ? 1 :0) ];
213if(bod->Type==OptionKernel)
214{
215[(NSTextField*) bod->contentID setEnabled: false];
216[(NSTextField*) bod->contentID setEditable: false];
217}
218
219}
220}
221break;
222default:
223break;
224}
225
226}
227
228//--------------------------------------------------------------------------
229- (void) loadPreferences
230{
231[ [ChameleonPrefPane instance] loadPreferences];
232}
233
234//--------------------------------------------------------------------------
235- (bool) savePreferences
236{
237return [ [ChameleonPrefPane instance] savePreferences: [self preferencesFile] ];
238
239}
240//--------------------------------------------------------------------------
241// update the boot Config with one option change and its associated desc
242- (bool) saveBootConfig: (id) sender withBootOptionDesc: (BootOptionDesc*) bod
243{
244if(!bod)
245{
246return false;
247}
248// load boot config file so that we don't risk to loose
249// externally modified parameters
250
251int val = [(NSButton*) sender intValue ];
252std::string sDefaultValue = trim(bod->Default ? bod->Default : "");
253bool status = false;
254std::string name = trim(bod->Name);
255
256switch (bod->Type) {
257case OptionYesNo:
258{
259std::string sVal = val ? "Yes" : "No";
260if (sDefaultValue.length()==0) sDefaultValue= "No";
261// Avoid populating bootConfig with unnecessary options:
262if (sVal == sDefaultValue)
263status = BootProp::instance().removeKeyAndValue(name.c_str());
264else
265status = BootProp::instance().setStringForKey(name, sVal.c_str());
266}
267break;
268case OptionUnix:
269if (!val)kernelFlags.removeFlag(name);
270elsekernelFlags.addFlag(name);
271BootProp::instance().setStringForKey(kKernelFlags,kernelFlags.options());
272status = true;
273break;
274case OptionKernel:
275{
276std::string contentValue = trim(
277[ [(NSTextField*) bod->contentID stringValue] UTF8String ]);
278kernelFlags.removeFlag(kernelFlags.stringFromKey(bod->Name));
279if(val && contentValue.length()>0)
280{
281std::string concat = trim(name);
282concat+= "=";
283concat+= trim(contentValue);
284
285kernelFlags.addFlag(concat);
286}
287BootProp::instance().setStringForKey(kKernelFlags,kernelFlags.options());
288status = true;
289}
290break;
291case OptionKernel1:
292case OptionString:
293// Avoid populating bootConfig with unnecessary options:
294if (val == 0 && bod->Type!=OptionKernel1)
295status = BootProp::instance().removeKeyAndValue(bod->Name);
296else
297{
298std::string contentValue =
299[ [(NSTextField*) bod->contentID stringValue] UTF8String ];
300if (contentValue.length()>0)
301status = BootProp::instance().setStringForKey(bod->Name, contentValue.c_str());
302else {
303return false; // no content to save so don't save it
304}
305
306}
307break;
308default:
309break;
310}
311
312// Now save the bootConfig
313AuthorizationRef auth = [self getAuthorization ];
314if (status)status = BootProp::instance().save(auth);
315
316return status;
317}
318//--------------------------------------------------------------------------
319-(NSMutableDictionary*) preferencesFile
320{
321return [[ChameleonPrefPane instance] preferencesFile];
322}
323
324//--------------------------------------------------------------------------
325-(NSMutableDictionary*) preferencesParts
326{
327return [[ChameleonPrefPane instance] preferencesParts];
328}
329
330//--------------------------------------------------------------------------
331- (bool) handleSender: (id) sender
332{
333
334const BootOptionDesc * bod = BootProp::instance().findOption(sender);
335
336if (!bod) {
337bod = BootProp::instance().findOptionContent(sender);
338NSTextField* textField = (NSTextField*) sender;
339std::string content = [[textField stringValue] UTF8String ];
340if(bod->ID!=nil) sender = (id) bod->ID;
341}
342else
343{
344
345int state = [sender intValue];
346
347switch (bod->Type) {
348case OptionKernel:
349case OptionKernel1:
350case OptionString:
351[(NSTextField*) bod->contentID setEnabled: state ? true : false];
352[(NSTextField*) bod->contentID setEditable: state ? true : false];
353break;
354default:
355break;
356}
357}
358if(![self saveBootConfig: sender withBootOptionDesc: (BootOptionDesc*) bod] && !bod->contentID )
359{ // Couldn't save, so warn user ...
360NSRunAlertPanel(@"Error saving bootConfig", @"Could not save com.apple.Boot.plist",
361@"OK", nil, nil);
362}
363return true;
364}
365
366@end
367

Archive Download this file

Revision: 58