Chameleon Applications

Chameleon Applications Svn Source Tree

Root/branches/diebuche/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
14#include "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 = "com.apple.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 com.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{
79std::string sPath = [kPreferencesFilePath UTF8String];
80
81if(dict==nil || sPath.length()==0) return false;
82
83AuthorizationRef auth = [self isUnlocked] ? [[authView authorization] authorizationRef] : NULL;
84
85PropertyList::chmodFile(sPath.c_str(), "0777", auth);
86[dict writeToFile:kPreferencesFilePath atomically:YES];
87PropertyList::chmodFile(sPath.c_str(), "0644", auth);
88return true;
89}
90
91//--------------------------------------------------------------------------
92// SFAuthorization implementation
93//--------------------------------------------------------------------------
94
95// SFAuthorization delegates
96- (void)authorizationViewDidAuthorize:(SFAuthorizationView *)view {
97 [self selectDefaultPartition];
98[self refreshLockStates];
99
100}
101
102//--------------------------------------------------------------------------
103- (void)authorizationViewDidDeauthorize:(SFAuthorizationView *)view {
104 [self refreshLockStates];
105}
106
107//--------------------------------------------------------------------------
108// Setup security for changing boot options
109-(void) initAuthorization
110{
111 AuthorizationItem items = {kAuthorizationRightExecute, 0, NULL, 0};
112 AuthorizationRights rights = {1, &items};
113
114[authView setAuthorizationRights:&rights];
115 authView.delegate = self;
116 [authView updateStatus:nil];
117}
118//--------------------------------------------------------------------------
119- (AuthorizationRef) auth
120{
121return [self isUnlocked] ? [[authView authorization] authorizationRef] : NULL;
122
123}
124
125//--------------------------------------------------------------------------
126- (void) refreshLockStates
127{
128 [[TableViewsController instance]->mPartitionsTable setEnabled:[self isUnlocked]];
129 [mStatusText setEnabled:[self isUnlocked]];
130
131// Refresh other panels
132[PreferencesControllerBase doForEachGroup: RefreshLockStates withOption: nil];
133}
134
135
136//--------------------------------------------------------------------------
137- (bool)isUnlocked
138{
139 return [authView authorizationState] == SFAuthorizationViewUnlockedState;
140}
141
142//--------------------------------------------------------------------------
143/** When called here, all outlets references are initialized */
144- (void)awakeFromNib
145{ // called more than once, we only need one resource init
146[footer setBorderWidth:1.0];
147[footer setGradientStartColor:[NSColor colorWithCalibratedWhite:0.72 alpha:1.0]];
148 [footer setGradientEndColor:[NSColor colorWithCalibratedWhite:0.50 alpha:1.0]];
149
150
151
152static bool ft=true;
153if(ft)
154{
155ft=false;
156[selfloadPreferences];
157[self initBootConfig];
158}
159}
160
161//--------------------------------------------------------------------------
162- (void) loadPreferences
163{
164//PrefsProp::instance().open([kPreferencesFilePath UTF8String], CreateIfNotExist,
165// [self auth]);
166
167// test with preferences file already created and when no prefs exists
168
169id oldGlobalPreferences = [ [NSDictionary dictionaryWithContentsOfFile:
170 kPreferencesFilePath ] retain];
171
172mPartitionsDict = [[NSMutableDictionary alloc] init];
173[mPartitionsDict retain];
174
175// Initialize bootConfig desc dict
176[PreferencesControllerBase doForEachGroup: AddOptionsDesc withOption: nil];
177
178if (oldGlobalPreferences!=nil)
179{
180mPreferenceFileVersion= [[oldGlobalPreferences objectForKey: keyPreferencesFileVersion] intValue ];
181[PreferencesControllerBase doForEachGroup: LoadPreferencesOptions withOption: oldGlobalPreferences];
182[mPartitionsDict addEntriesFromDictionary: [oldGlobalPreferences objectForKey: keyPartitionsList] ];
183}
184else
185{ // Create a preference plist file with Defaults values
186oldGlobalPreferences = [[NSMutableDictionary alloc] init];
187[PreferencesControllerBase doForEachGroup: SetDefaultValues withOption: oldGlobalPreferences];
188
189// Initialize defaults
190[oldGlobalPreferences setObject: [[NSNumber alloc] initWithInt: CurrentPreferencesFileVersion]
191 forKey: keyPreferencesFileVersion];
192[oldGlobalPreferences setObject: mPartitionsDict forKey: keyPartitionsList];
193
194// Save the preferences file
195[ self savePreferences:oldGlobalPreferences ];
196}
197
198mOptionsDict = [[NSMutableDictionary alloc] init];
199[mOptionsDict addEntriesFromDictionary:oldGlobalPreferences];
200if (mPartitionsDict!=nil) [mPartitionsDict retain];
201[oldGlobalPreferences release];
202}
203
204//--------------------------------------------------------------------------
205- (void) initBootConfig
206{
207static bool ft=true;
208
209[self initAuthorization];
210
211if (!BootProp::instance().isValid())
212{
213std::string sPath;
214CFStringRef errorString=NULL;
215bool cont =true;
216
217id sForcedPath = [mOptionsDict valueForKey: keyForceBootConfigPath];
218const char * szForcedPath = sForcedPath!=nil ? [sForcedPath UTF8String] : NULL;
219if (szForcedPath && *szForcedPath)
220{
221cont = !BootProp::instance().open(szForcedPath, [self auth]);
222}
223else {
224for(int i=0; szBootPaths[i] && cont; i++)
225{
226sPath = szBootPaths[i];
227sPath += szPropFileName;
228cont = !BootProp::instance().open(sPath.c_str(), [self auth]);
229}
230}
231if (cont)
232{
233if(!ft) return;
234ft=false;
235[mStatusText setTextColor: [NSColor redColor] ];
236if (errorString)
237[mStatusText setStringValue:[NSString stringWithFormat: @"Error while parsing com.apple.Boot.plist : %@",
238 errorString] ];
239else
240[mStatusText setStringValue: @"Error while searching for com.apple.Boot.plist"];
241
242}
243else
244{
245[mStatusText setTextColor: [NSColor grayColor] ];
246NSString* ns = [ [NSString alloc] initWithUTF8String:BootProp::instance().propFilePath() ];
247[mStatusText setStringValue: [NSString stringWithFormat: @"bootConfig: %@", ns] ];
248[[BootSetupController instance]->mBootConfigPathText setStringValue:
249[[NSString alloc] initWithUTF8String: BootProp::instance().propFilePath()] ];
250
251}
252
253if (BootProp::instance().isValid())
254{
255// read options in the plist file
256
257PartitionExtractor::instance().hidePartitions(BootProp::instance().getStringForKey(kHidePartition));
258PartitionExtractor::instance().renamedPartitions(BootProp::instance().getStringForKey(kRenamePartition));
259
260// PartitionExtractor::instance().resetSwapping();
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{
291int index = PartitionExtractor::instance().getIndexFromHdStringSpec(sCurrentDefaultPartition.c_str());
292if (index>=0)
293{
294[[TableViewsController instance ]->mPartitionsTable selectRowIndexes:
295 [NSIndexSet indexSetWithIndex:index] byExtendingSelection:NO];
296[TableViewsController instance ]->currentRowSel = index;
297}
298}
299}
300
301}
302
303//--------------------------------------------------------------------------
304// following DieBuch recommendation : using applescript and system events (thanks!):
305- (IBAction)onRestart: (id)sender
306{
307NSInteger n = NSRunAlertPanel(@"Restarting OS X",
308 @"Are you sure you want to restart your computer now ?",
309 @"OK", @"Cancel", nil);
310if (n==1)
311{
312AuthorizationRef auth = [[authView authorization] authorizationRef];
313executePrivilegedCmd(auth,"/usr/bin/osascript","-e 'tell app \"System Events\" to restart'");
314}
315
316}
317//--------------------------------------------------------------------------
318- (IBAction)onShutdown: (id)sender
319{
320NSInteger n = NSRunAlertPanel(@"Shutting Down OS X",
321 @"Are you sure you want to shut down your computer now ?",
322 @"OK", @"Cancel", /*ThirdButtonHere:*/nil
323 /*, args for a printf-style msg go here */);
324if (n==1)
325{
326system("/usr/bin/osascript -e 'tell app \"System Events\" to shut down'");
327}
328}
329
330- (IBAction)onSleep: (id)sender
331{
332system("/usr/bin/osascript -e 'tell app \"System Events\" to sleep'");
333}
334
335
336@end
337

Archive Download this file

Revision: 83