root/trunk/ECQTComponent.m

Revision 792, 10.4 kB (checked in by durin42, 6 months ago)

Initial version of an improved component management tab. I've done enough to
get the code Ken wrote working with our setup, but we need to add some smarts
so the components can compute their status (eg should upgrade, remove, etc).

Line 
1 //
2 //  ECQTComponent.m
3 //  QTManager
4 //
5 //  Created by Ken on 12/15/07.
6 //  Copyright 2007 __MyCompanyName__. All rights reserved.
7 //
8
9 #import "ECQTComponent.h"
10
11 #define DISABLED_SUFFIX @" (Disabled)"
12
13 @implementation ECQTComponent
14
15 NSMutableDictionary*    mCache = 0;
16
17 #define SET_KEY(key, value) [mParameters setObject:(value) forKey:(key)]
18 #define SET_KEY_BOOLVAL(key, value) [mParameters setObject:[NSNumber numberWithBool:(value)] forKey:(key)]
19 #define GET_KEY(key) [mParameters objectForKey:(key)]
20 #define GET_KEY_BOOLVAL(key) (([mParameters objectForKey:(key)]) ? [[mParameters objectForKey:(key)] boolValue] : NO)
21
22 +(id)componentWithPath:(NSString*)path
23 {
24         return [[[ECQTComponent alloc] initWithPath:path] autorelease];
25 }
26
27 -(id)initWithPath:(NSString*)path
28 {
29 //      NSLog(@"init with %@", path);
30 #warning TODO(durin42) There's a lot of caching here - I don't think we really need it to be efficient.
31         if (!mCache)
32         {
33                 mCache = [[NSMutableDictionary dictionary] retain];
34         }
35
36         NSDictionary* cachedParams = [mCache objectForKey:path];
37        
38         if (cachedParams)
39         {
40                 mParameters = [cachedParams retain];           
41         }
42         else
43         {
44                 mParameters = [[NSMutableDictionary dictionary] retain];
45                
46                 SET_KEY(@"Location", path);
47                 [self setComponentInfo];
48         }
49
50         SET_KEY_BOOLVAL(@"Enabled", !([path rangeOfString:DISABLED_SUFFIX].length > 0));
51
52         [self setComponentScope];
53
54         return self;
55 }
56
57
58 -(void)setComponentInfo
59 {
60         short resFile = 0;
61
62         NSString* filePath = GET_KEY(@"Location");
63        
64         BOOL isDirectory = NO;
65         NSFileManager* fm = [NSFileManager defaultManager];
66         NSURL* url = [NSURL fileURLWithPath:filePath];
67         if (![fm fileExistsAtPath:filePath isDirectory:&isDirectory])
68         {
69                 return;
70         }
71                        
72         CFBundleRef bundleRef = 0;
73         if (isDirectory)
74         {
75                 bundleRef = CFBundleCreate(0, (CFURLRef)url);
76
77                 if (!bundleRef)
78                         return;
79                
80                 resFile = CFBundleOpenBundleResourceMap(bundleRef);
81                
82                 NSString* cfvers = (NSString*)CFBundleGetValueForInfoDictionaryKey(bundleRef, kCFBundleVersionKey);
83                 if (cfvers)
84                         SET_KEY(@"Version", cfvers);
85                
86         }
87         else
88         {
89                 FSRef ref;
90                 if (CFURLGetFSRef((CFURLRef)url,&ref))
91                 {
92                         resFile = FSOpenResFile(&ref, fsRdPerm);
93                 }
94         }
95
96         NSString* name = [NSString stringWithString:@"Unknown"];
97        
98         short saveRes = CurResFile();
99         if (resFile > 0)
100         {
101                 UseResFile(resFile);
102                 int x = 0;
103                 int count = CountResources('thng');
104                 NSString* firstType = 0;
105                 BOOL mixed = false;
106                
107                 NSString* singletype = 0;
108                 NSMutableArray* allTypes = [NSMutableArray array];
109                 NSMutableArray* allNames = [NSMutableArray array];
110                
111                 for (x = 1; x <= count; x++)
112                 {
113                        
114                         Handle data = Get1IndResource('thng', x);
115                         if (data)
116                         {
117                                 ComponentResource* thng = (ComponentResource*)*data;
118
119                                 ComponentDescription desc;
120
121                                 memcpy(&desc, thng, sizeof(ComponentDescription));
122
123                                 Handle nameData = Get1Resource(thng->componentName.resType, thng->componentName.resID);
124
125                                 if (firstType == 0 && singletype)
126                                         firstType = [singletype copy];
127                                
128                                 if (desc.componentType == 'vdig')
129                                         singletype = @"Camera Driver";
130                                 else if (desc.componentType == 'sgpn')
131                                         singletype = @"Camera Driver";
132                                 else if (desc.componentType == 'spit')
133                                         singletype = @"Exporter";
134                                 else if (desc.componentType == 'eat ')
135                                         singletype = @"Media Importer";
136                                 else if (desc.componentType == 'imdc')
137                                         singletype = @"Image Codec";
138                                 else if (desc.componentType == 'imco')
139                                         singletype = @"Image Codec";
140                                 else if (desc.componentType == 'sdec')
141                                         singletype = @"Sound Decoder";
142                                 else if (desc.componentType == 'scom')
143                                         singletype = @"Sound Compressor";
144                                 else if (desc.componentType == 'aenc')
145                                         singletype = @"Audio Encoder";
146                                 else if (desc.componentType == 'adec')
147                                         singletype = @"Audio Decoder";
148                                 else if (desc.componentType == 'aunt')
149                                         singletype = @"Audio Unit";
150                                 else if (desc.componentType == 'grip')
151                                         singletype = @"Graphics Importer";
152                                 else if (desc.componentType == 'shlr')
153                                         singletype = @"Sound Handler";
154                                 else if (desc.componentType == 'dhlr')
155                                         singletype = @"Data Handler";
156                                 else if (desc.componentType == 'mhlr')
157                                         singletype = @"Media Handler";
158                                 else if (desc.componentType == 'tsvc')
159                                         singletype = @"Text Service";
160                                 else if (desc.componentType == 'osa ')
161                                         singletype = @"Scripting Component";
162                                 else if (desc.componentType == 'crnc')
163                                         singletype = @"Cruncher";
164                                 else if (desc.componentType == 'ihlr')
165                                         singletype = @"Isochronous Handler";
166                                 else if (desc.componentType == 'acca')
167                                         singletype = @"Audio Context";
168                                 else if (desc.componentType == 'sift')
169                                         singletype = @"Sound Converter";
170                                 else
171                                         singletype = @"Unknown";
172
173                                 if (firstType && singletype && ![firstType isEqualToString:singletype])
174                                 {
175                                         mixed = true;
176                                 }
177
178                                 if (![allTypes containsObject:singletype])
179                                         [allTypes addObject:singletype];
180                                
181         //                      NSLog(@"%@", singletype);
182                                 if (nameData && *nameData)
183                                 {
184                                         name = [[[NSString alloc] initWithBytes:(*nameData) + 1 length:**nameData encoding:NSUTF8StringEncoding] autorelease];
185                                         if (!name)
186                                                 name = [[[NSString alloc] initWithBytes:(*nameData) + 1 length:**nameData encoding:NSUnicodeStringEncoding] autorelease];
187                                 }       
188
189                                 if (![allNames containsObject:name])
190                                         [allNames addObject:name];
191                                
192                                 if (GetHandleSize(data) >= (Size)sizeof(ExtComponentResource))
193                                 {
194
195                                         SET_KEY_BOOLVAL(@"Extended", YES);
196                                         NSMutableArray* arches = [NSMutableArray array];
197                                         ExtComponentResource* extthng = (ExtComponentResource*)*data;
198                                         if (extthng)
199                                         {
200                                                 SET_KEY(@"ComponentVersion", [NSNumber numberWithInt:extthng->componentVersion]);
201                                                 SET_KEY(@"RegisterFlags", [NSNumber numberWithInt:extthng->componentRegisterFlags]);
202                                                 int i= 0;
203                                                 for (i = 0; i < extthng->count; i++)
204                                                 {
205                                                         ComponentPlatformInfo* info = &(extthng->platformArray[i]);
206                        
207                                                         NSMutableDictionary* pinfo = [NSMutableDictionary dictionary];
208                                                        
209                                                         [pinfo setObject:[NSNumber numberWithInt:info->platformType] forKey:@"Platform"];
210                                                         [pinfo setObject:[NSNumber numberWithInt:info->componentFlags] forKey:@"Flags"];
211
212                                                         [arches addObject:pinfo];
213                                                 }
214                                                 SET_KEY(@"Arches", arches);
215                                         }
216                                 }
217                         }
218
219                 }
220
221                 name = [GET_KEY(@"Location") lastPathComponent];
222                 if ([[name pathExtension] isEqualToString:@"component"])
223                          name = [name stringByDeletingPathExtension];
224                
225                 SET_KEY(@"Name", name);
226                 SET_KEY(@"Type", singletype);
227                 SET_KEY(@"Types", allTypes);
228                 SET_KEY(@"Names", allNames);
229        
230                 [mCache setObject:mParameters forKey:filePath];
231         }
232        
233         UseResFile(saveRes);
234
235         if (isDirectory && bundleRef && resFile >= 0)
236         {
237                 CFBundleCloseBundleResourceMap(bundleRef, resFile);
238         }
239         else if (!isDirectory && resFile >= 0)
240         {
241                 CloseResFile(resFile);
242         }
243 }
244
245
246
247 -(void)setComponentScope
248 {
249         NSString* mLocation = GET_KEY(@"Location");
250
251         if ([mLocation hasPrefix:@"/System/"])
252                 mWhere = componentIsSystem;
253         else if ([mLocation hasPrefix:@"/Library/"])
254                 mWhere = componentIsGlobal;
255         else if ([mLocation hasPrefix:@"/Users/"])
256                 mWhere = componentIsLocal;
257 }
258
259 -(void)dealloc
260 {
261         if (mParameters)
262                 [mParameters release];
263
264         [super dealloc];
265 }
266
267 -(NSString*)name
268 {
269         return GET_KEY(@"Name");
270 }
271
272 -(NSString*)location
273 {
274         return GET_KEY(@"Location");
275 }
276
277 -(NSString*)version
278 {
279         if (GET_KEY(@"Version"))
280                 return GET_KEY(@"Version");
281         else
282                 return GET_KEY(@"ComponentVersion");   
283 }
284
285 -(NSString*)type
286 {
287         return GET_KEY(@"Type");
288 }
289
290 -(NSString*)types
291 {
292         return [GET_KEY(@"Types") componentsJoinedByString:@", "];
293 }
294
295 -(NSString*)names
296 {
297         return [GET_KEY(@"Names") componentsJoinedByString:@", "];
298 }
299
300 -(NSString*)whereSort
301 {
302         if (mWhere == componentIsLocal)
303                 return @"Home";
304         else if (mWhere == componentIsGlobal)
305                 return @"Library";
306         else if (mWhere == componentIsSystem)
307                 return @"System";
308        
309         return @"";
310 }
311
312 -(NSString*)enabledSort
313 {
314         return [NSString stringWithFormat:@"%d", GET_KEY_BOOLVAL(@"Enabled")];
315 }
316
317 -(componentScope)isWhere
318 {
319         return mWhere;
320 }
321
322 -(BOOL)extended
323 {
324         return GET_KEY_BOOLVAL(@"Extended");
325 }
326
327 -(NSNumber*)compVersion
328 {
329         return GET_KEY(@"ComponentVersion");
330 }
331
332 -(NSNumber*)compFlags
333 {
334         return GET_KEY(@"RegisterFlags");
335 }
336
337 -(NSString*)arches
338 {
339         NSArray* arches = GET_KEY(@"Arches");
340         NSMutableString* archesString = [NSMutableString string];
341         int x= 0;
342         int count = [arches count];
343         for (x = 0; x < count; x++)
344         {
345                 NSDictionary* pinfo = [arches objectAtIndex:x];
346                 int platform = [[pinfo objectForKey:@"Platform"] intValue];
347                
348                 if (platform ==platformPowerPCNativeEntryPoint)
349                         [archesString appendFormat:@" PowerPC"];
350                 else if (platform ==platformIA32NativeEntryPoint)
351                         [archesString appendFormat:@" Intel"];
352                 else
353                         [archesString appendFormat:@" %d", x];
354         }       
355         return archesString;
356 }
357
358
359
360 -(NSImage*)where
361 {
362         NSImage* image = 0;
363         if (mWhere == componentIsLocal)
364                 image = [NSImage imageNamed:@"user"];
365         else if (mWhere == componentIsGlobal)
366                 image = [NSImage imageNamed:@"global"];
367         else if (mWhere == componentIsSystem)
368                 image = [NSImage imageNamed:@"system"];
369                
370         return image;
371 }
372
373 -(NSNumber*)componentEnabled
374 {
375         return GET_KEY(@"Enabled");
376 }
377
378 -(void)setEnabled:(BOOL)enabled
379 {               
380         NSString* mLocation = GET_KEY(@"Location");
381         BOOL mEnabled = GET_KEY_BOOLVAL(@"Enabled");
382        
383         NSString* componentFile = [mLocation lastPathComponent];
384         NSString* containingFolderPath = [mLocation stringByDeletingLastPathComponent];
385         NSString* containingFolder = [containingFolderPath lastPathComponent];
386         NSString* containingFolderFolderPath = [containingFolderPath stringByDeletingLastPathComponent];
387         NSString* otherFolder = 0;
388         if (mEnabled)
389                 otherFolder = [containingFolderFolderPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@%@", containingFolder, DISABLED_SUFFIX]];
390         else
391         {
392                 NSRange range = [containingFolder rangeOfString:DISABLED_SUFFIX];
393                 if (range.length > 0)
394                         otherFolder = [containingFolderFolderPath stringByAppendingPathComponent:[containingFolder substringToIndex:range.location]];
395         }
396        
397         if (!otherFolder)
398                 return;
399                
400         NSFileManager* fm = [NSFileManager defaultManager];
401         BOOL successful = YES;
402         if (![fm fileExistsAtPath:otherFolder isDirectory:nil])
403         {
404                 successful = [fm createDirectoryAtPath:otherFolder attributes:0];
405         }
406         NSString* destFile = [otherFolder stringByAppendingPathComponent:componentFile];
407         if (successful)
408                 successful = [fm movePath:mLocation toPath:destFile handler:self];
409
410         SET_KEY(@"Location", destFile);
411
412         SET_KEY_BOOLVAL(@"Enabled", enabled);
413 }
414
415
416 - (BOOL)fileManager:(NSFileManager *)manager shouldProceedAfterError:(NSDictionary *)errorInfo
417 {
418         NSLog(@"QTComponent Manager: Error: %@", errorInfo);
419         return YES;
420 }
421
422 - (void)fileManager:(NSFileManager *)manager willProcessPath:(NSString *)path
423 {
424 }
425
426 @end
Note: See TracBrowser for help on using the browser.