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 | ␊ |
14 | static const char cPartDescSep = ';'; // partition descriptor separator␊ |
15 | ␊ |
16 | static BootSetupController *gInstance = NULL;␊ |
17 | ␊ |
18 | @implementation BootSetupController␊ |
19 | ␊ |
20 | //--------------------------------------------------------------------------␊ |
21 | - (id) init␊ |
22 | {␊ |
23 | ␉self = [super init];␊ |
24 | ␉return (gInstance = self);␊ |
25 | }␉␊ |
26 | ␊ |
27 | //--------------------------------------------------------------------------␊ |
28 | - (void) addOptionsDesc␊ |
29 | {␊ |
30 | BootProp::instance().addOptionDesc(mDefaultPartition, mDefaultPartitionText, OptionString, "Default Partition", "");␊ |
31 | BootProp::instance().addOptionDesc(mHidePartition , mHidePartitionText, OptionString, "Hide Partition", "");␊ |
32 | BootProp::instance().addOptionDesc(mRenamePartition , mRenamePartitionText, OptionString, "Rename Partition", "");␊ |
33 | }␊ |
34 | ␊ |
35 | //--------------------------------------------------------------------------␊ |
36 | - (void) refreshLockStates␊ |
37 | {␊ |
38 | ␉// non boot config options (not automatized)␊ |
39 | [PreferencesControllerBase refreshLockState: mSwapHD01 ];␊ |
40 | [PreferencesControllerBase refreshLockState: mSwapHD02 ];␊ |
41 | [PreferencesControllerBase refreshLockState: mFreezeParts ];␊ |
42 | [PreferencesControllerBase refreshLockState: mInjectFrozenParts ];␊ |
43 | [PreferencesControllerBase refreshLockState: mBootConfigPath ];␊ |
44 | [PreferencesControllerBase refreshLockState: mBootConfigPathText ];␊ |
45 | }␊ |
46 | ␊ |
47 | //--------------------------------------------------------------------------␊ |
48 | - (void) setDefaultsValues: (NSMutableDictionary*) dict␊ |
49 | {␊ |
50 | ␉[dict setObject: [[NSNumber alloc] initWithBool: false] forKey: keySwapHD01];␊ |
51 | ␉[dict setObject: [[NSNumber alloc] initWithBool: false] forKey: keySwapHD02];␊ |
52 | ␉[dict setObject:[[NSNumber alloc] initWithBool: false] forKey: keyUseFrozenParts];␊ |
53 | ␉[dict setObject:[[NSNumber alloc] initWithBool: false] forKey: keyUseFrozenParts];␊ |
54 | ␉[dict setObject:[[NSString alloc] initWithString: @""] forKey: keyForceBootConfigPath];␊ |
55 | }␊ |
56 | //--------------------------------------------------------------------------␊ |
57 | -(void) loadOptionsFromPreferencesFile: (NSMutableDictionary*) dict␊ |
58 | {␊ |
59 | ␉[mSwapHD01 setIntValue: [[dict objectForKey:␉keySwapHD01] intValue]];␊ |
60 | ␉[mSwapHD02 setIntValue: [[dict objectForKey:␉keySwapHD02] intValue]];␊ |
61 | ␉[mFreezeParts setIntValue: [[dict objectForKey: keyUseFrozenParts] intValue] ];␊ |
62 | ␉id obj = [dict objectForKey: keyForceBootConfigPath];␊ |
63 | ␉[mBootConfigPathText setStringValue: obj ? obj : @"" ];␊ |
64 | ␉int val = (obj && [[mBootConfigPathText stringValue] length] >0 ? 1 : 0);␊ |
65 | ␉[mBootConfigPath setIntValue: val];␊ |
66 | ␉[dict setObject:[[NSString alloc] initWithString: [mBootConfigPathText stringValue]] ␊ |
67 | ␉␉␉ forKey: keyForceBootConfigPath];␊ |
68 | ␉[mBootConfigPathText setEnabled: val ? true : false]; ␊ |
69 | ␉[mBootConfigPathText setEditable: val ? true : false];␊ |
70 | ␊ |
71 | }␊ |
72 | ␊ |
73 | //--------------------------------------------------------------------------␊ |
74 | - (void) loadFrozenParts␊ |
75 | {␊ |
76 | ␉// iterate for all entries to add␊ |
77 | ␉char keyPartN[32] = ""; ␊ |
78 | ␉int k=0;␊ |
79 | ␉␊ |
80 | ␉NSMutableArray* partList = (NSMutableArray*) [PartsInfoMgr parts];␊ |
81 | ␉[partList removeAllObjects];␊ |
82 | ␉␊ |
83 | ␉for (int i=0; i< [[self preferencesParts] count]; i++)␊ |
84 | ␉{␊ |
85 | ␉␉// get the key␊ |
86 | ␉␉snprintf(keyPartN, sizeof(keyPartN)-1, "partition%02d",i);␊ |
87 | ␉␉NSString* obj = [[self preferencesParts] objectForKey: [[NSString alloc] initWithUTF8String: keyPartN] ];␊ |
88 | ␉␉// assign this key if valid␊ |
89 | ␉␉if (obj!=nil && [obj length]>0)␊ |
90 | ␉␉{␊ |
91 | ␉␉␉PartitionInfoElement* p = [[PartitionInfoElement alloc] init];␊ |
92 | ␉␉␉// parse string␊ |
93 | ␉␉␉NSArray* words = [obj componentsSeparatedByCharactersInSet: [NSCharacterSet characterSetWithCharactersInString: @";"]];␊ |
94 | ␉␉␉k=0;␊ |
95 | ␉␉␉int diskNum=0, partNum=0;␊ |
96 | ␉␉␉for (NSString * word in words)␊ |
97 | ␉␉␉{␊ |
98 | ␉␉␉␉switch (k) {␊ |
99 | ␉␉␉␉␉case 0: // disk number␊ |
100 | ␉␉␉␉␉␉diskNum = [word characterAtIndex:0] - '0' ;␊ |
101 | ␉␉␉␉␉␉break;␊ |
102 | ␉␉␉␉␉case 1: // partition number␊ |
103 | ␉␉␉␉␉␉partNum = [word characterAtIndex:0] - '0' ;␊ |
104 | ␉␉␉␉␉␉break;␊ |
105 | ␉␉␉␉␉case 2: // volume label␊ |
106 | ␉␉␉␉␉␉[p setVName: word];␊ |
107 | ␉␉␉␉␉case 3: // fstype␊ |
108 | ␉␉␉␉␉␉[p setVKind: word];␊ |
109 | ␉␉␉␉␉␉break;␊ |
110 | ␉␉␉␉␉default:␊ |
111 | ␉␉␉␉␉␉break;␊ |
112 | ␉␉␉␉}␊ |
113 | ␉␉␉}␊ |
114 | ␉␉␉␊ |
115 | ␉␉␉[partList addObject:p];␊ |
116 | ␉␉}␊ |
117 | ␉}␊ |
118 | ␉// PartitionExtractor::instance().sortPartList();␊ |
119 | ␉␊ |
120 | }␊ |
121 | ␊ |
122 | //--------------------------------------------------------------------------␊ |
123 | - (void) swapDisks: (bool) bSwap src: (int) iSrc dst: (int) iDst;␊ |
124 | {␊ |
125 | ␉if(!BootProp::instance().isValid()) return;␊ |
126 | ␉if (bSwap)␊ |
127 | ␉{␊ |
128 | ␉␉[PartsInfoMgr swapHD:iSrc with: iDst ];␉␊ |
129 | ␉}␊ |
130 | ␉␊ |
131 | ␉if ([mFreezeParts intValue]==0) ␊ |
132 | ␉␉[PartsInfoMgr reload];␊ |
133 | ␉else ␊ |
134 | ␉␉[self loadFrozenParts ];␊ |
135 | ␉␊ |
136 | ␉[ [self chameleon] selectDefaultPartition];␊ |
137 | ␉␊ |
138 | }␊ |
139 | ␊ |
140 | //--------------------------------------------------------------------------␊ |
141 | - (void) doSwapHD: (int) val save: (bool) doSave src: (int) isrc dst: (int) idst␊ |
142 | {␊ |
143 | ␉␊ |
144 | ␉if( val>0 && ![[BootSetupController instance]->mFreezeParts intValue]) //on␊ |
145 | ␉{␊ |
146 | ␉␉[self swapDisks: true src:isrc dst:idst ];␊ |
147 | ␉}␊ |
148 | ␉else␊ |
149 | ␉{␊ |
150 | ␉␉[self swapDisks: false src:isrc dst:idst ];␊ |
151 | ␉}␊ |
152 | ␉␊ |
153 | ␉if(doSave)␊ |
154 | ␉{␊ |
155 | ␉␉if (isrc==0 && idst==1)␊ |
156 | ␉␉␉[[self preferencesFile] setObject: [NSNumber numberWithBool: val ? true : false] forKey: keySwapHD01];␊ |
157 | ␉␉if (isrc==0 && idst==2)␊ |
158 | ␉␉␉[[self preferencesFile] setObject: [NSNumber numberWithBool: val ? true : false] forKey: keySwapHD02];␊ |
159 | ␉␉[ [self chameleon] savePreferences:[self preferencesFile] ];␊ |
160 | ␉}␊ |
161 | ␉␊ |
162 | ␉[[[TableViewsController instance] partitionsTable] reloadData];␊ |
163 | ␉[[[TableViewsController instance] partitionsTable] scrollRowToVisible: 0];␊ |
164 | ␉//[self tableViewSelectionDidChange: nil];␊ |
165 | ␉␊ |
166 | }␊ |
167 | ␊ |
168 | ␊ |
169 | //--------------------------------------------------------------------------␊ |
170 | - (IBAction)onInjectPartsToFreeze: (id)sender␊ |
171 | {␊ |
172 | ␉int size = [[PartsInfoMgr parts] count ];␊ |
173 | ␉if (!size) ␊ |
174 | ␉{ // nothing to inject␊ |
175 | ␉␉NSRunAlertPanel(@"Inject Partitions to Freeze Configuration", ␊ |
176 | ␉␉␉␉␉␉@"No current partitions to inject, did you check boot config file ?",@"OK", nil,nil);␊ |
177 | ␉␉return;␊ |
178 | ␉}␊ |
179 | ␉// generate the parts list in preferences proplist␊ |
180 | ␉NSInteger n = NSRunAlertPanel(@"Inject Partitions to Freeze Configuration", ␊ |
181 | ␉␉␉␉␉␉␉␉ @"Are you sure you want to overwrite your Freeze settings with current partition list ?",␊ |
182 | ␉␉␉␉␉␉␉␉ @"OK", @"Cancel",nil);␊ |
183 | ␉if (n==1)␊ |
184 | ␉{␊ |
185 | ␉␉// populate the dictionary with the current partitions␊ |
186 | ␉␉␊ |
187 | ␉␉// empty dictionary and update key in parent:␊ |
188 | ␉␉[[self preferencesFile] removeObjectForKey: keyPartitionsList];␊ |
189 | ␉␉[[self preferencesParts] removeAllObjects ];␊ |
190 | ␉␉␊ |
191 | ␉␉// iterate for all entries to add␊ |
192 | ␉␉char partDesc[256]="";␊ |
193 | ␉␉char keyPartN[32] = "";␊ |
194 | ␉␉for (int i=0; i< size; i++)␊ |
195 | ␉␉{␊ |
196 | ␉␉␉␊ |
197 | ␉␉␉PartitionInfoElement* p = [PartsInfoMgr objectAtIndex:i];␊ |
198 | ␉␉␉␊ |
199 | ␉␉␉// format the partition key and descriptor string␊ |
200 | ␉␉␉snprintf(keyPartN, sizeof(keyPartN)-1, "partition%02d",i);␊ |
201 | ␉␉␉␊ |
202 | ␉␉␉snprintf(partDesc, sizeof(partDesc)-1, "%d%c%d%c%s%c%s",␊ |
203 | ␉␉␉␉␉ [p diskNumber], cPartDescSep,␊ |
204 | ␉␉␉␉␉ [p partitionNumber], cPartDescSep,␊ |
205 | ␉␉␉␉␉ [[p vName] UTF8String], cPartDescSep,␊ |
206 | ␉␉␉␉␉ [[p vKind] UTF8String]);␊ |
207 | ␉␉␉␊ |
208 | ␉␉␉// write it to the dictionary␊ |
209 | ␉␉␉NSString * key = [[NSString alloc] initWithUTF8String: keyPartN];␊ |
210 | ␉␉␉NSString * desc = [[NSString alloc] initWithUTF8String: partDesc]; ␊ |
211 | ␉␉␉[[self preferencesParts] setObject: desc forKey: key];␊ |
212 | ␉␉␉␊ |
213 | ␉␉␉[p release];␊ |
214 | ␉␉}␊ |
215 | ␉␉[[self preferencesFile] setObject: [self preferencesParts] forKey: keyPartitionsList];␊ |
216 | ␉␉[self savePreferences ];␊ |
217 | ␉}␊ |
218 | }␊ |
219 | ␊ |
220 | //--------------------------------------------------------------------------␊ |
221 | - (IBAction) onForceBootConfigPath: (id) sender␊ |
222 | {␊ |
223 | ␉if (sender == mBootConfigPath)␊ |
224 | ␉{␊ |
225 | ␉␉int val = [mBootConfigPath intValue];␊ |
226 | ␉␉[mBootConfigPathText setEnabled: val ? true : false]; ␊ |
227 | ␉␉[mBootConfigPathText setEditable: val ? true : false];␊ |
228 | ␉␉␊ |
229 | ␉␉if (val) ␊ |
230 | ␉␉{␊ |
231 | ␉␉␉NSString * f = [self selectPlistFile: @"org.chameleon.Boot.plist"];␊ |
232 | ␉␉␉if(f)␊ |
233 | ␉␉␉{␊ |
234 | ␉␉␉␉[mBootConfigPathText setStringValue:f];␊ |
235 | ␉␉␉␉[f release];␊ |
236 | ␉␉␉}␊ |
237 | ␉␉}␊ |
238 | ␉␉␉␊ |
239 | ␊ |
240 | ␉␉[[self preferencesFile] setObject: ␊ |
241 | ␉␉ val ? [mBootConfigPathText stringValue] : [[NSString alloc] initWithUTF8String: ""] ␊ |
242 | ␉␉␉␉␉␉␉␉ forKey: keyForceBootConfigPath];␊ |
243 | ␉␉␊ |
244 | ␉}␊ |
245 | ␉else␊ |
246 | ␉␉[[self preferencesFile] setObject: [mBootConfigPathText stringValue] forKey: keyForceBootConfigPath];␊ |
247 | ␉[self savePreferences ];␊ |
248 | ␊ |
249 | ␉␉␊ |
250 | ␉[PreferencesControllerBase loadOptionsFromBootFile ];␊ |
251 | ␊ |
252 | }␊ |
253 | //--------------------------------------------------------------------------␊ |
254 | -(IBAction) onCheckButtonChange: (NSButton*) sender␊ |
255 | {␊ |
256 | ␉// IMPROVE ME: Should automatize the callback/load/save mechanism ␊ |
257 | ␉// for the preferences file like the bootConfig file␊ |
258 | ␉if (sender == mSwapHD01 || sender == mSwapHD02)␊ |
259 | ␉{␊ |
260 | ␉␉[PartsInfoMgr resetSwapping];␊ |
261 | ␉␉[self doSwapHD: [mSwapHD01 intValue] save:true src:0 dst:1];␊ |
262 | ␉␉[self doSwapHD: [mSwapHD02 intValue] save:true src:0 dst:2];␊ |
263 | ␉}␊ |
264 | ␉else if (sender == mFreezeParts)␊ |
265 | ␉{␊ |
266 | ␉␉bool val = !![sender intValue];␊ |
267 | ␉␉[[self preferencesFile] setObject: [NSNumber numberWithBool: val] forKey: keyUseFrozenParts];␊ |
268 | ␉␉[[self chameleon] savePreferences: [self preferencesFile]];␊ |
269 | ␉␉[ self onCheckButtonChange: mSwapHD01];␊ |
270 | ␉}␊ |
271 | ␉else if (sender == mInjectFrozenParts)␊ |
272 | ␉{␊ |
273 | ␉␉[self onInjectPartsToFreeze: mInjectFrozenParts];␊ |
274 | ␉}␉␊ |
275 | ␉else if (sender == mDefaultPartition || sender == mHidePartition␊ |
276 | ␉␉␉ || sender == mRenamePartition )␊ |
277 | ␉{ // sync with other panels␊ |
278 | ␉␉[self handleSender:sender];␊ |
279 | ␉}␉␊ |
280 | ␉else if (sender == mBootConfigPath || (NSTextField*)sender == mBootConfigPathText)␊ |
281 | ␉{ // sync with other panels␊ |
282 | ␉␉[self onForceBootConfigPath: sender];␊ |
283 | ␉}␉␊ |
284 | ␉// Handle BootOptions generically:␊ |
285 | ␉else ␊ |
286 | ␉␉[self handleSender:sender];␊ |
287 | }␊ |
288 | //--------------------------------------------------------------------------␊ |
289 | -(IBAction) onTextFiedChange: (NSTextField*) sender␊ |
290 | {␊ |
291 | ␉if ( sender == mDefaultPartitionText || sender == mHidePartitionText ||␊ |
292 | ␉␉␉ sender == mRenamePartitionText )␊ |
293 | ␉{␊ |
294 | ␉␉[self handleSender:sender];␊ |
295 | ␊ |
296 | ␉␉[PreferencesControllerBase loadOptionsFromBootFile ];␊ |
297 | ␉␉[PartsInfoMgr reloadWithHideSpec: [mHidePartitionText stringValue] andRenameSpec: [mRenamePartitionText stringValue] ];␊ |
298 | ␊ |
299 | ␉␉[self doSwapHD: [mSwapHD01 intValue] save:true src:0 dst:1];␊ |
300 | ␉␉[self doSwapHD: [mSwapHD02 intValue] save:true src:0 dst:2];␊ |
301 | ␉}␉␊ |
302 | }␊ |
303 | ␊ |
304 | //--------------------------------------------------------------------------␊ |
305 | + (BootSetupController *)instance { return(gInstance);}␊ |
306 | ␊ |
307 | @end␊ |
308 | |