Chameleon Applications

Chameleon Applications Svn Source Tree

Root/trunk/ChameleonPrefPane/Sources/ChameleonPrefPane.mm

1//
2// StartupPrefPanePref.mm
3//
4// Created by Rekursor on 1/16/10.
5//
6
7#import "ChameleonPrefPane.h"
8#import "BootSetupController.h"
9#import "BootFlagsController.h"
10#import "PeripheralsController.h"
11#import "AdvancedSetupController.h"
12#import "TableViewsController.h"
13#import "PartitionInfoManager.h"
14#import "ShellProcess.h"
15#import "ChameleonPropertyList.h"
16#include <string>
17
18//--------------------------------------------------------------------------
19// Constants
20//--------------------------------------------------------------------------
21static const char * const szBootPaths[]= {
22"/",
23"/Extra/",
24"/Volumes/EFI/Extra/",
25"/Volumes/Cham/Extra/",
26"/Volumes/BootLoaders/Extra/",
27"/Volumes/RX0/Extra/",
28"/Library/Preferences/SystemConfiguration/",
29NULL
30};
31
32static const char* const szPropFileName = "org.chameleon.Boot.plist";
33static const int CurrentPreferencesFileVersion = 0x02; // for future back compatibility
34
35// TODO move table views handling code to a dedicated controller
36
37//--------------------------------------------------------------------------
38//--------------------------------------------------------------------------
39// Static file variables
40//--------------------------------------------------------------------------
41static std::string sCurrentDefaultPartition;
42
43static ChameleonPrefPane * _prefPaneInstance = NULL;
44
45
46//--------------------------------------------------------------------------
47
48@implementation ChameleonPrefPane
49
50+ (ChameleonPrefPane *)instance { return(_prefPaneInstance);}
51
52//--------------------------------------------------------------------------
53- (id) init
54{
55self = [super init];
56_prefPaneInstance = self;
57
58
59
60
61// Retrieve the org.chameleon.prefPane.plist config
62return self;
63}
64- (void)dealloc
65{
66// release the colors
67[mOptionsDict release];
68[mPartitionsDict release];
69
70[super dealloc];
71}
72
73- (NSMutableDictionary*) preferencesFile {return mOptionsDict; }
74- (NSMutableDictionary*) preferencesParts {return mPartitionsDict; }
75
76//--------------------------------------------------------------------------
77-(bool) savePreferences: (NSDictionary*) dict
78{
79
80if(dict==nil) return false;
81
82AuthorizationRef auth = [self isUnlocked] ? [[authView authorization] authorizationRef] : NULL;
83if (!auth) return false;
84
85NSString* tmpPropName = @"/tmp/chamPrefPane.plist";
86BOOL ret = [dict writeToFile:tmpPropName atomically:YES];
87if (!ret) return false;
88NSString* args = [NSString stringWithFormat:@"%@ %@", tmpPropName, kPreferencesFilePath];
89const char * cArgs = [args UTF8String];
90ret = executePrivilegedCmd(auth, "/bin/cp", cArgs , NULL);
91return ret;
92}
93
94//--------------------------------------------------------------------------
95// SFAuthorization implementation
96//--------------------------------------------------------------------------
97
98// SFAuthorization delegates
99- (void)authorizationViewDidAuthorize:(SFAuthorizationView *)view {
100 [self selectDefaultPartition];
101[self refreshLockStates];
102
103}
104
105//--------------------------------------------------------------------------
106- (void)authorizationViewDidDeauthorize:(SFAuthorizationView *)view {
107 [self refreshLockStates];
108}
109
110//--------------------------------------------------------------------------
111// Setup security for changing boot options
112-(void) initAuthorization
113{
114 AuthorizationItem items = {kAuthorizationRightExecute, 0, NULL, 0};
115 AuthorizationRights rights = {1, &items};
116
117[authView setAuthorizationRights:&rights];
118 authView.delegate = self;
119 [authView updateStatus:nil];
120}
121//--------------------------------------------------------------------------
122- (AuthorizationRef) auth
123{
124return [self isUnlocked] ? [[authView authorization] authorizationRef] : NULL;
125
126}
127
128//--------------------------------------------------------------------------
129- (void) refreshLockStates
130{
131 [[TableViewsController instance]->mPartitionsTable setEnabled:[self isUnlocked]];
132 [mStatusText setEnabled:[self isUnlocked]];
133
134// Refresh other panels
135[PreferencesControllerBase doForEachGroup: RefreshLockStates withOption: nil];
136}
137
138
139//--------------------------------------------------------------------------
140- (bool)isUnlocked
141{
142 return [authView authorizationState] == SFAuthorizationViewUnlockedState;
143}
144
145//--------------------------------------------------------------------------
146/** When called here, all outlets references are initialized */
147- (void)awakeFromNib
148{ // called more than once, we only need one resource init
149static bool ft=true;
150if(ft)
151{
152ft=false;
153[selfloadPreferences];
154[self initBootConfig];
155}
156}
157
158//--------------------------------------------------------------------------
159- (void) loadPreferences
160{
161// test with preferences file already created and when no prefs exists
162
163id oldGlobalPreferences = [ [NSDictionary dictionaryWithContentsOfFile:
164 kPreferencesFilePath ] retain];
165
166mPartitionsDict = [[NSMutableDictionary alloc] init];
167[mPartitionsDict retain];
168
169// Initialize bootConfig desc dict
170[PreferencesControllerBase doForEachGroup: AddOptionsDesc withOption: nil];
171
172if (oldGlobalPreferences!=nil)
173{
174mPreferenceFileVersion= [[oldGlobalPreferences objectForKey: keyPreferencesFileVersion] intValue ];
175[PreferencesControllerBase doForEachGroup: LoadPreferencesOptions withOption: oldGlobalPreferences];
176[mPartitionsDict addEntriesFromDictionary: [oldGlobalPreferences objectForKey: keyPartitionsList] ];
177}
178else
179{ // Create a preference plist file with Defaults values
180oldGlobalPreferences = [[NSMutableDictionary alloc] init];
181[PreferencesControllerBase doForEachGroup: SetDefaultValues withOption: oldGlobalPreferences];
182
183// Initialize defaults
184[oldGlobalPreferences setObject: [[NSNumber alloc] initWithInt: CurrentPreferencesFileVersion]
185 forKey: keyPreferencesFileVersion];
186[oldGlobalPreferences setObject: mPartitionsDict forKey: keyPartitionsList];
187
188// Save the preferences file
189[ self savePreferences:oldGlobalPreferences ];
190}
191
192mOptionsDict = [[NSMutableDictionary alloc] init];
193[mOptionsDict addEntriesFromDictionary:oldGlobalPreferences];
194if (mPartitionsDict!=nil) [mPartitionsDict retain];
195[oldGlobalPreferences release];
196}
197
198//--------------------------------------------------------------------------
199- (void) initBootConfig
200{
201static bool ft=true;
202
203[self initAuthorization];
204
205if (!BootProp::instance().isValid())
206{
207std::string sPath;
208CFStringRef errorString=NULL;
209bool cont =true;
210
211id sForcedPath = [mOptionsDict valueForKey: keyForceBootConfigPath];
212const char * szForcedPath = sForcedPath!=nil ? [sForcedPath UTF8String] : NULL;
213if (szForcedPath && *szForcedPath)
214{
215cont = !BootProp::instance().open(szForcedPath, false, [self auth]);
216}
217else {
218for(int i=0; szBootPaths[i] && cont; i++)
219{
220sPath = szBootPaths[i];
221sPath += szPropFileName;
222cont = !BootProp::instance().open(sPath.c_str(), false, [self auth]);
223}
224}
225if (cont)
226{
227if(!ft) return;
228ft=false;
229[mStatusText setTextColor: [NSColor redColor] ];
230if (errorString)
231[mStatusText setStringValue:[NSString stringWithFormat: @"Error while parsing org.chameleon.Boot.plist : %@",
232 errorString] ];
233else
234[mStatusText setStringValue: @"Error while searching for org.chameleon.Boot.plist"];
235
236}
237else
238{
239[mStatusText setTextColor: [NSColor grayColor] ];
240NSString* ns = [ [NSString alloc] initWithUTF8String:BootProp::instance().propFilePath() ];
241[mStatusText setStringValue: [NSString stringWithFormat: @"bootConfig: %@", ns] ];
242[[BootSetupController instance]->mBootConfigPathText setStringValue:
243[[NSString alloc] initWithUTF8String: BootProp::instance().propFilePath()] ];
244
245}
246
247[PartsInfoMgr resetSwapping];
248
249if (BootProp::instance().isValid())
250{
251// read options in the plist file
252const char *s = BootProp::instance().getStringForKey(kHidePartition) ;
253if (s==nil) s = "";
254[PartsInfoMgr hideParts: [NSString stringWithUTF8String: s] ];
255
256s = BootProp::instance().getStringForKey(kRenamePartition);
257if (s==nil) s = "";
258[PartsInfoMgr renameParts: [NSString stringWithUTF8String: s]];
259
260
261id val = [mOptionsDict valueForKey: keySwapHD01];
262[[BootSetupController instance]->mSwapHD01 setIntValue: [val intValue] ];
263[[BootSetupController instance] doSwapHD: [val boolValue] save: false src:0 dst:1];
264
265val = [mOptionsDict valueForKey: keySwapHD02];
266[[BootSetupController instance]->mSwapHD02 setIntValue: [val intValue] ];
267[[BootSetupController instance] doSwapHD: [val boolValue] save: false src:0 dst:2];
268
269// Load all boot Options into the interface components
270[PreferencesControllerBase loadOptionsFromBootFile];
271[self selectDefaultPartition];
272
273}
274
275}
276}
277//--------------------------------------------------------------------------
278- (void) selectDefaultPartition
279{
280 if(!authView) return;
281
282[self refreshLockStates];
283
284// try to get the current default partition if any
285if(BootProp::instance().isValid())
286{
287const char *sdp = BootProp::instance().getStringForKey(kDefaultPartition);
288sCurrentDefaultPartition = sdp ? sdp : "";
289if (sCurrentDefaultPartition.size())
290{
291NSUInteger index=0;
292PartitionInfoElement* p = [PartsInfoMgr partWithName:[NSString stringWithUTF8String:sCurrentDefaultPartition.c_str()] outIndex: &index];
293if (p!=nil)
294{
295[[TableViewsController instance ]->mPartitionsTable selectRowIndexes: [NSIndexSet indexSetWithIndex:index] byExtendingSelection:NO];
296}
297}
298}
299
300}
301
302//--------------------------------------------------------------------------
303// following DieBuch recommendation : using applescript and system events (thanks!):
304- (IBAction)onRestart: (id)sender
305{
306NSInteger n = NSRunAlertPanel(@"Restarting OS X",
307 @"Are you sure you want to restart your computer now ?",
308 @"OK", @"Cancel", nil);
309if (n==1)
310{
311AuthorizationRef auth = [[authView authorization] authorizationRef];
312executePrivilegedCmd(auth,"/usr/bin/osascript","-e 'tell app \"System Events\" to restart'");
313}
314
315}
316//--------------------------------------------------------------------------
317- (IBAction)onShutdown: (id)sender
318{
319NSInteger n = NSRunAlertPanel(@"Shutting Down OS X",
320 @"Are you sure you want to shut down your computer now ?",
321 @"OK", @"Cancel", /*ThirdButtonHere:*/nil
322 /*, args for a printf-style msg go here */);
323if (n==1)
324{
325system("/usr/bin/osascript -e 'tell app \"System Events\" to shut down'");
326}
327}
328
329- (IBAction)onSleep: (id)sender
330{
331system("/usr/bin/osascript -e 'tell app \"System Events\" to sleep'");
332}
333
334//--------------------------------------------------------------------------
335
336@end
337

Archive Download this file

Revision: 383