Chameleon Applications

Chameleon Applications Svn Source Tree

Root/trunk/ChameleonPrefPane/Sources/BootSetupController.mm

1//
2// BootSetupController.mm
3// ChameleonPrefPane
4//
5// Created by Rekursor on 1/22/10.
6//
7
8#import "BootSetupController.h"
9#import "ChameleonPrefPane.h"
10#import "TableViewsController.h"
11#import "ShellProcess.h"
12#import "PartitionInfoManager.h"
13#include "ChameleonPropertyList.h"
14
15static const char cPartDescSep = ';'; // partition descriptor separator
16
17static BootSetupController *gInstance = NULL;
18
19@implementation BootSetupController
20
21//--------------------------------------------------------------------------
22- (id) init
23{
24self = [super init];
25return (gInstance = self);
26}
27
28//--------------------------------------------------------------------------
29- (void) addOptionsDesc
30{
31 BootProp::instance().addOptionDesc(mDefaultPartition, mDefaultPartitionText, OptionString, "Default Partition", "");
32 BootProp::instance().addOptionDesc(mHidePartition , mHidePartitionText, OptionString, "Hide Partition", "");
33 BootProp::instance().addOptionDesc(mRenamePartition , mRenamePartitionText, OptionString, "Rename Partition", "");
34}
35
36//--------------------------------------------------------------------------
37- (void) refreshLockStates
38{
39// non boot config options (not automatized)
40 [PreferencesControllerBase refreshLockState: mSwapHD01 ];
41 [PreferencesControllerBase refreshLockState: mSwapHD02 ];
42 [PreferencesControllerBase refreshLockState: mFreezeParts ];
43 [PreferencesControllerBase refreshLockState: mInjectFrozenParts ];
44 [PreferencesControllerBase refreshLockState: mBootConfigPath ];
45 [PreferencesControllerBase refreshLockState: mBootConfigPathText ];
46}
47
48//--------------------------------------------------------------------------
49- (void) setDefaultsValues: (NSMutableDictionary*) dict
50{
51[dict setObject: [[NSNumber alloc] initWithBool: false] forKey: keySwapHD01];
52[dict setObject: [[NSNumber alloc] initWithBool: false] forKey: keySwapHD02];
53[dict setObject:[[NSNumber alloc] initWithBool: false] forKey: keyUseFrozenParts];
54[dict setObject:[[NSNumber alloc] initWithBool: false] forKey: keyUseFrozenParts];
55[dict setObject:[[NSString alloc] initWithString: @""] forKey: keyForceBootConfigPath];
56}
57//--------------------------------------------------------------------------
58-(void) loadOptionsFromPreferencesFile: (NSMutableDictionary*) dict
59{
60[mSwapHD01 setIntValue: [[dict objectForKey:keySwapHD01] intValue]];
61[mSwapHD02 setIntValue: [[dict objectForKey:keySwapHD02] intValue]];
62[mFreezeParts setIntValue: [[dict objectForKey: keyUseFrozenParts] intValue] ];
63id obj = [dict objectForKey: keyForceBootConfigPath];
64[mBootConfigPathText setStringValue: obj ? obj : @"" ];
65int val = (obj && [[mBootConfigPathText stringValue] length] >0 ? 1 : 0);
66[mBootConfigPath setIntValue: val];
67[dict setObject:[[NSString alloc] initWithString: [mBootConfigPathText stringValue]]
68 forKey: keyForceBootConfigPath];
69[mBootConfigPathText setEnabled: val ? true : false];
70[mBootConfigPathText setEditable: val ? true : false];
71
72}
73
74//--------------------------------------------------------------------------
75- (void) loadFrozenParts
76{
77// iterate for all entries to add
78char keyPartN[32] = "";
79int k=0;
80
81NSMutableArray* partList = (NSMutableArray*) [PartsInfoMgr parts];
82[partList removeAllObjects];
83
84for (int i=0; i< [[self preferencesParts] count]; i++)
85{
86// get the key
87snprintf(keyPartN, sizeof(keyPartN)-1, "partition%02d",i);
88NSString* obj = [[self preferencesParts] objectForKey: [[NSString alloc] initWithUTF8String: keyPartN] ];
89// assign this key if valid
90if (obj!=nil && [obj length]>0)
91{
92PartitionInfoElement* p = [[PartitionInfoElement alloc] init];
93// parse string
94NSArray* words = [obj componentsSeparatedByCharactersInSet: [NSCharacterSet characterSetWithCharactersInString: @";"]];
95k=0;
96int diskNum=0, partNum=0;
97for (NSString * word in words)
98{
99switch (k) {
100case 0: // disk number
101diskNum = [word intValue] ;
102[ p setDiskNumber:diskNum];
103break;
104case 1: // partition number
105partNum = [word intValue] ;
106[ p setPartitionNumber: partNum];
107break;
108case 2: // volume label
109[p setVName: word];
110[p setVAliasName: word];
111break;
112case 3: // fstype
113[p setVKind: word];
114break;
115case 4: // vUUID
116[p setVUUID: word];
117break;
118default:
119break;
120}
121k++;
122}
123
124[partList addObject:p];
125}
126}
127// for mgr to refresh hide and rename attributes
128[PartsInfoMgr hideParts:nil];
129[PartsInfoMgr renameParts:nil];
130
131}
132
133//--------------------------------------------------------------------------
134- (void) swapDisks: (bool) bSwap src: (int) iSrc dst: (int) iDst;
135{
136//if(!BootProp::instance().isValid()) return;
137if ([mFreezeParts intValue]==0)
138[PartsInfoMgr reload];
139else
140[self loadFrozenParts ];
141
142if (bSwap)
143{
144[PartsInfoMgr swapHD:iSrc with: iDst ];
145}
146
147[ [self chameleon] selectDefaultPartition];
148
149}
150
151//--------------------------------------------------------------------------
152- (void) doSwapHD: (int) val save: (bool) doSave src: (int) isrc dst: (int) idst
153{
154
155if( val>0 && ![[BootSetupController instance]->mFreezeParts intValue]) //on
156{
157[self swapDisks: true src:isrc dst:idst ];
158}
159else
160{
161[self swapDisks: false src:isrc dst:idst ];
162}
163
164if(doSave)
165{
166if (isrc==0 && idst==1)
167[[self preferencesFile] setObject: [NSNumber numberWithBool: val ? true : false] forKey: keySwapHD01];
168if (isrc==0 && idst==2)
169[[self preferencesFile] setObject: [NSNumber numberWithBool: val ? true : false] forKey: keySwapHD02];
170[ [self chameleon] savePreferences:[self preferencesFile] ];
171}
172
173[[[TableViewsController instance] partitionsTable] reloadData];
174[[[TableViewsController instance] partitionsTable] scrollRowToVisible: 0];
175//[self tableViewSelectionDidChange: nil];
176
177}
178
179
180//--------------------------------------------------------------------------
181- (IBAction)onInjectPartsToFreeze: (id)sender
182{
183int size = [[PartsInfoMgr parts] count ];
184if (!size)
185{ // nothing to inject
186NSRunAlertPanel(@"Inject Partitions to Freeze Configuration",
187@"No current partitions to inject, did you check boot config file ?",@"OK", nil,nil);
188return;
189}
190// generate the parts list in preferences proplist
191NSInteger n = NSRunAlertPanel(@"Inject Partitions to Freeze Configuration",
192 @"Are you sure you want to overwrite your Freeze settings with current partition list ?",
193 @"OK", @"Cancel",nil);
194if (n==1)
195{
196// populate the dictionary with the current partitions
197
198// empty dictionary and update key in parent:
199[[self preferencesFile] removeObjectForKey: keyPartitionsList];
200[[self preferencesParts] removeAllObjects ];
201
202// iterate for all entries to add
203char partDesc[256]="";
204char keyPartN[32] = "";
205for (int i=0; i< size; i++)
206{
207
208PartitionInfoElement* p = [PartsInfoMgr objectAtIndex:i];
209
210// format the partition key and descriptor string
211snprintf(keyPartN, sizeof(keyPartN)-1, "partition%02d",i);
212
213snprintf(partDesc, sizeof(partDesc)-1, "%d%c%d%c%s%c%s%c%s",
214 [p diskNumber], cPartDescSep,
215 [p partitionNumber], cPartDescSep,
216 [[p vAliasName] UTF8String], cPartDescSep,
217 [[p vKind] UTF8String], cPartDescSep,
218 [[p vUUID] UTF8String]);
219
220// write it to the dictionary
221NSString * key = [[NSString alloc] initWithUTF8String: keyPartN];
222NSString * desc = [[NSString alloc] initWithUTF8String: partDesc];
223[[self preferencesParts] setObject: desc forKey: key];
224
225[p release];
226}
227[[self preferencesFile] setObject: [self preferencesParts] forKey: keyPartitionsList];
228[self savePreferences ];
229}
230}
231
232//--------------------------------------------------------------------------
233- (IBAction) onForceBootConfigPath: (id) sender
234{
235if (sender == mBootConfigPath)
236{
237int val = [mBootConfigPath intValue];
238[mBootConfigPathText setEnabled: val ? true : false];
239[mBootConfigPathText setEditable: val ? true : false];
240
241if (val)
242{
243NSString * f = [self selectPlistFile: @"org.chameleon.Boot.plist"];
244if(f)
245{
246[mBootConfigPathText setStringValue:f];
247[f release];
248}
249}
250
251
252[[self preferencesFile] setObject:
253 val ? [mBootConfigPathText stringValue] : [[NSString alloc] initWithUTF8String: ""]
254 forKey: keyForceBootConfigPath];
255
256}
257else
258[[self preferencesFile] setObject: [mBootConfigPathText stringValue] forKey: keyForceBootConfigPath];
259[self savePreferences ];
260BootProp::instance().cleanup();
261[[ChameleonPrefPane instance ] initBootConfig];
262}
263//--------------------------------------------------------------------------
264-(IBAction) onCheckButtonChange: (NSButton*) sender
265{
266// IMPROVE ME: Should automatize the callback/load/save mechanism
267// for the preferences file like the bootConfig file
268if (sender == mSwapHD01 || sender == mSwapHD02)
269{
270[PartsInfoMgr resetSwapping];
271[self doSwapHD: [mSwapHD01 intValue] save:true src:0 dst:1];
272[self doSwapHD: [mSwapHD02 intValue] save:true src:0 dst:2];
273}
274else if (sender == mFreezeParts)
275{
276bool val = !![sender intValue];
277[[self preferencesFile] setObject: [NSNumber numberWithBool: val] forKey: keyUseFrozenParts];
278[[self chameleon] savePreferences: [self preferencesFile]];
279[ self onCheckButtonChange: mSwapHD01];
280}
281else if (sender == mInjectFrozenParts)
282{
283[self onInjectPartsToFreeze: mInjectFrozenParts];
284}
285else if (sender == mDefaultPartition || sender == mHidePartition
286 || sender == mRenamePartition )
287{ // sync with other panels
288[self handleSender:sender];
289}
290else if (sender == mBootConfigPath || (NSTextField*)sender == mBootConfigPathText)
291{ // sync with other panels
292[self onForceBootConfigPath: sender];
293}
294else if (sender == mBootExtraPath || (NSTextField*)sender == mBootExtraPathText)
295{ // sync with other panels
296[self onForceBootConfigPath: sender];
297}
298else if (sender == mBootCdbootPath || (NSTextField*)sender == mBootCdbootPathText)
299{ // sync with other panels
300[self onForceBootConfigPath: sender];
301}
302// Handle BootOptions generically:
303else
304[self handleSender:sender];
305}
306//--------------------------------------------------------------------------
307-(IBAction) onTextFiedChange: (NSTextField*) sender
308{
309if ( sender == mDefaultPartitionText || sender == mHidePartitionText ||
310 sender == mRenamePartitionText )
311{
312[self handleSender:sender];
313
314[PreferencesControllerBase loadOptionsFromBootFile ];
315[PartsInfoMgr reloadWithHideSpec: [mHidePartitionText stringValue] andRenameSpec: [mRenamePartitionText stringValue] ];
316
317[self doSwapHD: [mSwapHD01 intValue] save:true src:0 dst:1];
318[self doSwapHD: [mSwapHD02 intValue] save:true src:0 dst:2];
319}
320else if (sender == mBootConfigPathText)
321{
322[self onForceBootConfigPath: sender];
323}
324}
325//--------------------------------------------------------------------------
326- (IBAction) onCdBootConfigPath: (id) sender
327{
328if ( sender == mBootCdbootPath)
329{
330NSString * dir = [self selectDirectory:@"/"];
331if (dir!=nil)
332[mBootCdbootPathText setStringValue: dir];
333}
334
335}
336//--------------------------------------------------------------------------
337- (IBAction) onExtraConfigPath: (id) sender
338{
339if ( sender == mBootExtraPath)
340{
341NSString * dir = [self selectDirectory:@"/"];
342if (dir!=nil)
343[mBootExtraPathText setStringValue: dir];
344}
345}
346
347//--------------------------------------------------------------------------
348- (IBAction) onCreateBootCD: (id) sender
349{
350// using rek modified rohan script from Lizard boot cd creator:
351NSString* destination = @"~/Desktop/Chameleon";
352NSString* pathTask = [self getResourcePath:@"cdBootCreator" ofType:@"sh"];
353NSString* pathExtra = [mBootExtraPathText stringValue];
354NSString* pathCdboot = [mBootCdbootPathText stringValue];
355NSMutableArray* arr = [[NSMutableArray alloc] init];
356bool result;
357
358if (
359pathTask!=nil && [pathTask length] > 0
360&& pathExtra !=nil && [pathExtra length] > 0
361&& pathCdboot !=nil && [pathCdboot length] > 0
362 )
363{
364[arr addObject: pathExtra];
365[arr addObject: pathCdboot];
366result = [self executeTaskAndWaitForTermination: pathTask withArgs: arr];
367if (result)
368{
369[self msgBoxInfo:
370 [NSString stringWithFormat:@"Boot cd creator script successfully executed. BootCD.iso created in %@.",
371destination]];
372}
373else
374[self msgBoxError:@"ERROR: Couldn't execute boot cd creator script successfully!"];
375}
376
377[arr release];
378}
379//--------------------------------------------------------------------------
380+ (BootSetupController *)instance { return(gInstance);}
381
382@end
383

Archive Download this file

Revision: 383