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{
201//static 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{
227//if(!ft) return;
228//ft=false;
229[mStatusText setTextColor: [NSColor redColor] ];
230if (errorString)
231[mStatusText setStringValue:[NSString stringWithFormat:
232 GetLocStrDef(@"Error_Parsing", @"error", @"Error while parsing %@"),
233 errorString] ];
234else
235[mStatusText setStringValue:
236GetLocStrDef(@"Error_Searching", @"Error while searching for org.chameleon.Boot.plist", @"error") ];
237
238}
239else
240{
241//[mStatusText setTextColor: [NSColor grayColor] ];
242//NSString* ns = [ [NSString alloc] initWithUTF8String:BootProp::instance().propFilePath() ];
243[mStatusText setStringValue: [NSString stringWithFormat: @""] ];
244BootSetupController* bsc = [BootSetupController instance];
245[bsc->mBootConfigPathText setStringValue: [NSString stringWithUTF8String: BootProp::instance().propFilePath()] ];
246[bsc->mBootExtraPathText setStringValue: [[bsc->mBootConfigPathText stringValue] stringByDeletingLastPathComponent] ];
247[bsc->mBootCdbootPathText setStringValue: [[bsc->mBootConfigPathText stringValue] stringByDeletingLastPathComponent]];
248
249}
250
251[PartsInfoMgr resetSwapping];
252
253if (BootProp::instance().isValid())
254{
255// read options in the plist file
256const char *s = BootProp::instance().getStringForKey(kHidePartition) ;
257if (s==nil) s = "";
258[PartsInfoMgr hideParts: [NSString stringWithUTF8String: s] ];
259
260s = BootProp::instance().getStringForKey(kRenamePartition);
261if (s==nil) s = "";
262[PartsInfoMgr renameParts: [NSString stringWithUTF8String: s]];
263
264
265id val = [mOptionsDict valueForKey: keySwapHD01];
266[[BootSetupController instance]->mSwapHD01 setIntValue: [val intValue] ];
267[[BootSetupController instance] doSwapHD: [val boolValue] save: false src:0 dst:1];
268
269val = [mOptionsDict valueForKey: keySwapHD02];
270[[BootSetupController instance]->mSwapHD02 setIntValue: [val intValue] ];
271[[BootSetupController instance] doSwapHD: [val boolValue] save: false src:0 dst:2];
272
273// Load all boot Options into the interface components
274[PreferencesControllerBase loadOptionsFromBootFile];
275[self selectDefaultPartition];
276
277}
278
279}
280}
281//--------------------------------------------------------------------------
282- (void) selectDefaultPartition
283{
284 if(!authView) return;
285
286[self refreshLockStates];
287
288// try to get the current default partition if any
289if(BootProp::instance().isValid())
290{
291const char *sdp = BootProp::instance().getStringForKey(kDefaultPartition);
292sCurrentDefaultPartition = sdp ? sdp : "";
293if (sCurrentDefaultPartition.size())
294{
295NSUInteger index=0;
296PartitionInfoElement* p = [PartsInfoMgr partWithName:[NSString stringWithUTF8String:sCurrentDefaultPartition.c_str()] outIndex: &index];
297if (p!=nil)
298{
299[[TableViewsController instance ]->mPartitionsTable selectRowIndexes: [NSIndexSet indexSetWithIndex:index] byExtendingSelection:NO];
300}
301}
302 else
303 [[TableViewsController instance ]->mPartitionsTable selectRowIndexes: nil byExtendingSelection:NO];
304
305}
306
307}
308
309//--------------------------------------------------------------------------
310// following DieBuch recommendation : using applescript and system events (thanks!):
311- (IBAction)onRestart: (id)sender
312{
313NSInteger n = NSRunAlertPanel(@"Restarting OS X",
314 @"Are you sure you want to restart your computer now ?",
315 @"OK", @"Cancel", nil);
316if (n==1)
317{
318AuthorizationRef auth = [[authView authorization] authorizationRef];
319executePrivilegedCmd(auth,"/usr/bin/osascript","-e 'tell app \"System Events\" to restart'");
320}
321
322}
323//--------------------------------------------------------------------------
324- (IBAction)onShutdown: (id)sender
325{
326NSInteger n = NSRunAlertPanel(@"Shutting Down OS X",
327 @"Are you sure you want to shut down your computer now ?",
328 @"OK", @"Cancel", /*ThirdButtonHere:*/nil
329 /*, args for a printf-style msg go here */);
330if (n==1)
331{
332system("/usr/bin/osascript -e 'tell app \"System Events\" to shut down'");
333}
334}
335
336- (IBAction)onSleep: (id)sender
337{
338system("/usr/bin/osascript -e 'tell app \"System Events\" to sleep'");
339}
340
341//--------------------------------------------------------------------------
342
343@end
344

Archive Download this file

Revision: 459