Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /XspfQT/XspfQTDocument.m

Parent Directory Parent Directory | Revision Log Revision Log


Revision 378 - (hide annotations) (download)
Sun Mar 4 02:31:49 2012 UTC (12 years, 1 month ago) by masakih
File size: 16619 byte(s)
[New] XspfQTMovieLoaderにdelegateを引数にとらないイニシャライザを追加

1 masaki 2 //
2 masaki 72 // XspfQTDocument.m
3 masaki 2 // XspfQT
4     //
5     // Created by Hori,Masaki on 08/08/29.
6     //
7    
8 masakih 312 /*
9 masakih 316 This source code is release under the New BSD License.
10 masakih 370 Copyright (c) 2008-2010,2012, masakih
11 masakih 312 All rights reserved.
12    
13 masakih 316 ソースコード形式かバイナリ形式か、変更するかしないかを問わず、以下の条件を満たす場合に
14     限り、再頒布および使用が許可されます。
15    
16     1, ソースコードを再頒布する場合、上記の著作権表示、本条件一覧、および下記免責条項を含
17     めること。
18     2, バイナリ形式で再頒布する場合、頒布物に付属のドキュメント等の資料に、上記の著作権表
19     示、本条件一覧、および下記免責条項を含めること。
20     3, 書面による特別の許可なしに、本ソフトウェアから派生した製品の宣伝または販売促進に、
21     コントリビューターの名前を使用してはならない。
22     本ソフトウェアは、著作権者およびコントリビューターによって「現状のまま」提供されており、
23     明示黙示を問わず、商業的な使用可能性、および特定の目的に対する適合性に関する暗黙の保証
24     も含め、またそれに限定されない、いかなる保証もありません。著作権者もコントリビューター
25     も、事由のいかんを問わず、 損害発生の原因いかんを問わず、かつ責任の根拠が契約であるか
26     厳格責任であるか(過失その他の)不法行為であるかを問わず、仮にそのような損害が発生する
27     可能性を知らされていたとしても、本ソフトウェアの使用によって発生した(代替品または代用
28     サービスの調達、使用の喪失、データの喪失、利益の喪失、業務の中断も含め、またそれに限定
29     されない)直接損害、間接損害、偶発的な損害、特別損害、懲罰的損害、または結果損害につい
30     て、一切責任を負わないものとします。
31 masakih 312 -------------------------------------------------------------------
32 masakih 370 Copyright (c) 2008-2010,2012, masakih
33 masakih 312 All rights reserved.
34    
35 masakih 316 Redistribution and use in source and binary forms, with or without
36     modification, are permitted provided that the following conditions
37     are met:
38 masakih 312
39 masakih 316 1, Redistributions of source code must retain the above copyright
40     notice, this list of conditions and the following disclaimer.
41     2, Redistributions in binary form must reproduce the above copyright
42     notice, this list of conditions and the following disclaimer in
43     the documentation and/or other materials provided with the
44     distribution.
45     3, The names of its contributors may be used to endorse or promote
46     products derived from this software without specific prior
47     written permission.
48     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
49     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
50     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
51     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
52     COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
53     INCIDENTAL, SPECIAL,EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
54     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
55     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
56     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
58     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
59     POSSIBILITY OF SUCH DAMAGE.
60 masakih 312 */
61    
62 masaki 72 #import "XspfQTDocument.h"
63 masaki 202 #import "XspfQTAppDelegate.h"
64 masaki 205 #import "XspfQTPreference.h"
65 masaki 306 #import "HMXSPFComponent.h"
66 masaki 72 #import "XspfQTMovieWindowController.h"
67     #import "XspfQTPlayListWindowController.h"
68 masaki 171 #import <QTKit/QTKit.h>
69 masaki 2
70 masaki 306 #import "NSURL-HMExtensions.h"
71 masaki 181 #import "XspfQTMovieLoader.h"
72 masaki 269 #import "XspfQTValueTransformers.h"
73 masaki 181
74 masaki 298 #import "XspfQTMovieTimer.h"
75 masaki 207
76 masaki 298
77 masaki 207 #pragma mark #### Global Variables ####
78     /********* Global variables *******/
79     NSString *XspfQTDocumentWillCloseNotification = @"XspfQTDocumentWillCloseNotification";
80    
81     /**********************************/
82    
83 masakih 370 @interface XspfQTDocument()
84     @property (retain) HMXSPFComponent *playlist;
85     @property (retain) QTMovie *playingMovie;
86     @property (readonly) NSXMLDocument *XMLDocument;
87    
88     // private
89     @property (retain) XspfQTMovieLoader *loader;
90     @property NSTimeInterval playingMovieDuration;
91     @property BOOL didPreloading;
92     @end
93    
94 masaki 72 @interface XspfQTDocument (Private)
95 masaki 141 - (NSData *)dataFromURL:(NSURL *)url error:(NSError **)outError;
96 masaki 274
97     inline static BOOL isXspfFileType(NSString *typeName);
98     inline static BOOL isReadableMovieType(NSString *typeName);
99 masaki 2 @end
100    
101 masaki 207 static NSString *XspfDocumentType = @"XML Shareable Playlist Format";
102     static NSString *QuickTimeMovieDocumentType = @"QuickTime Movie";
103     static NSString *MatroskaVideoDocumentType = @"Matroska Video";
104     static NSString *DivXMediaFormatDocumentType = @"DivX Media Format";
105    
106 masaki 224 static NSString *XspfUTI = @"com.masakih.xspf";
107    
108 masaki 244 static NSString *XspfQTCurrentTrackKey = @"currentTrack";
109    
110 masaki 72 @implementation XspfQTDocument
111 masakih 370 @synthesize playlist = _playlist;
112     @synthesize playingMovie = _playingMovie;
113 masaki 2
114 masakih 370 @synthesize loader = _loader;
115     @synthesize playingMovieDuration = _playingMovieDuration;
116     @synthesize didPreloading = _didPreloading;
117    
118 masaki 298 static XspfQTMovieTimer* timer = nil;
119     + (void)initialize
120     {
121     timer = [[XspfQTMovieTimer movieTimer] retain];
122     }
123    
124 masaki 182 - (id)init
125     {
126     self = [super init];
127     if(self) {
128 masakih 378 self.loader = [[XspfQTMovieLoader loaderWithMovieURL:nil] retain];
129 masaki 182 }
130    
131     return self;
132     }
133 masaki 95 - (id)initWithType:(NSString *)typeName error:(NSError **)outError
134     {
135     [self init];
136    
137 masaki 306 id newPlaylist = [HMXSPFComponent xspfPlaylist];
138 masaki 116 if(!newPlaylist) {
139 masaki 95 [self autorelease];
140     return nil;
141     }
142    
143 masakih 370 self.playlist = newPlaylist;
144 masaki 95
145     return self;
146     }
147 masaki 182 - (void)dealloc
148     {
149 masakih 370 self.playingMovie = nil;
150     self.playlist = nil;
151 masaki 182 [playListWindowController release];
152     [movieWindowController release];
153 masakih 370 self.loader = nil;
154 masaki 182
155     [super dealloc];
156     }
157 masaki 2
158     - (void)makeWindowControllers
159     {
160 masaki 72 playListWindowController = [[XspfQTPlayListWindowController alloc] init];
161 masaki 2 [self addWindowController:playListWindowController];
162    
163 masaki 72 movieWindowController = [[XspfQTMovieWindowController alloc] init];
164 masaki 42 [movieWindowController setShouldCloseDocument:YES];
165 masaki 2 [self addWindowController:movieWindowController];
166 masaki 298
167 masakih 360 [movieWindowController showWindow:nil];
168 masakih 354
169 masaki 298 [timer put:self];
170 masaki 2 }
171    
172     - (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError
173     {
174 masakih 370 return [self.XMLDocument XMLDataWithOptions:NSXMLNodePrettyPrint];
175 masaki 2 }
176    
177 masaki 141 - (BOOL)readFromURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError
178     {
179 masaki 274 if(!isReadableMovieType(typeName)) {
180 masaki 141 NSData *data = [self dataFromURL:absoluteURL error:outError];
181     if(!data) return NO;
182    
183     return [self readFromData:data ofType:typeName error:outError];
184     }
185    
186 masaki 306 id new = [HMXSPFComponent xspfTrackWithLocation:absoluteURL];
187 masaki 279 if(!new) {
188 masaki 141 if(outError) {
189 masaki 279 *outError = [NSError errorWithDomain:@"XspfQTErrorDomain" code:1 userInfo:nil];
190 masaki 141 }
191     return NO;
192     }
193    
194 masaki 306 id pl = [HMXSPFComponent xspfPlaylist];
195 masaki 141 if(!pl) {
196     return NO;
197     }
198    
199     [[[pl children] objectAtIndex:0] addChild:new];
200    
201 masakih 370 self.playlist = pl;
202     HMXSPFComponent *t = self.trackList;
203     if(!t.title) {
204     t.title = [[[self fileURL] path] lastPathComponent];
205 masaki 141 }
206    
207 masaki 207 [self setFileType:XspfDocumentType];
208 masaki 141 [self setFileURL:nil];
209    
210     return YES;
211     }
212 masaki 2 - (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError
213     {
214 masaki 274 if(!isXspfFileType(typeName)) {
215 masaki 141 return NO;
216     }
217    
218 masaki 2 NSError *error = nil;
219 masaki 10 NSXMLDocument *d = [[[NSXMLDocument alloc] initWithData:data
220     options:0
221     error:&error] autorelease];
222 masaki 121 if(error) {
223     NSLog(@"%@", error);
224 masaki 272 if(outError) {
225     *outError = error;
226     }
227 masaki 121 return NO;
228     }
229 masaki 2 NSXMLElement *root = [d rootElement];
230 masakih 320 id pl = [HMXSPFComponent xspfComponentWithXMLElement:root];
231 masaki 121 if(!pl) {
232 masaki 306 NSLog(@"Can not create HMXSPFComponent.");
233 masaki 121 return NO;
234     }
235 masakih 370 self.playlist = pl;
236 masaki 2
237 masakih 370 HMXSPFComponent *t = self.trackList;
238     if(!t.title) {
239     t.title = [[[[self fileURL] path] lastPathComponent] stringByDeletingPathExtension];
240 masaki 39 }
241 masaki 272
242 masaki 2 return YES;
243     }
244    
245 masaki 42 - (void)close
246     {
247 masaki 61 NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
248 masaki 72 [nc postNotificationName:XspfQTDocumentWillCloseNotification object:self];
249 masaki 61
250 masaki 42 [self removeWindowController:playListWindowController];
251     [playListWindowController release];
252     playListWindowController = nil;
253    
254     [self removeWindowController:movieWindowController];
255     [movieWindowController release];
256     movieWindowController = nil;
257 masakih 329
258 masaki 42 [super close];
259     }
260    
261 masaki 269 #pragma mark### Actions ###
262 masaki 33 - (IBAction)togglePlayAndPause:(id)sender
263     {
264     [movieWindowController togglePlayAndPause:sender];
265     }
266 masaki 2 - (IBAction)showPlayList:(id)sender
267     {
268     [playListWindowController showWindow:self];
269     }
270 masakih 322 - (IBAction)showHidePlayList:(id)sender
271     {
272     [playListWindowController showHideWindow:self];
273     }
274 masaki 281 - (IBAction)setThumbnailFrame:(id)sender
275 masaki 269 {
276 masakih 370 HMXSPFComponent *currentTrack = self.trackList.currentTrack;
277     QTTime currentQTTime = [self.playingMovie currentTime];
278 masaki 269
279     NSTimeInterval currentTI;
280     QTGetTimeInterval(currentQTTime, &currentTI);
281    
282 masakih 370 HMXSPFComponent *prevThumbnailTrack = self.playlist.thumbnailTrack;
283     NSTimeInterval ti = self.playlist.thumbnailTimeInterval;
284 masaki 269
285 masakih 370 [self.playlist setThumbnailComponent:currentTrack timeIntarval:currentTI];
286 masaki 269
287     id undo = [self undoManager];
288 masaki 281 if(prevThumbnailTrack) {
289 masakih 370 [[undo prepareWithInvocationTarget:self.playlist] setThumbnailComponent:prevThumbnailTrack timeIntarval:ti];
290 masaki 281 [undo setActionName:NSLocalizedString(@"Change Thumbnail frame.", @"Undo Action Name Change Thumbnail frame")];
291 masaki 269 } else {
292 masakih 370 [[undo prepareWithInvocationTarget:self.playlist] removeThumbnailFrame];
293 masaki 281 [undo setActionName:NSLocalizedString(@"Add Thumbnail frame.", @"Undo Action Name Add Thumbnail frame")];
294 masaki 269 }
295     }
296 masaki 281 - (IBAction)removeThumbnail:(id)sender
297 masaki 269 {
298 masakih 370 HMXSPFComponent *prevThumbnailTrack = self.playlist.thumbnailTrack;
299     NSTimeInterval ti = self.playlist.thumbnailTimeInterval;
300 masaki 269
301 masakih 370 [self.playlist removeThumbnailFrame];
302 masaki 269
303 masaki 281 if(prevThumbnailTrack) {
304 masaki 269 id undo = [self undoManager];
305 masakih 370 [[undo prepareWithInvocationTarget:self.playlist] setThumbnailComponent:prevThumbnailTrack timeIntarval:ti];
306 masaki 281 [undo setActionName:NSLocalizedString(@"Remove Thumbnail frame.", @"Undo Action Name Remove Thumbnail frame")];
307 masaki 269 }
308     }
309     - (BOOL)validateMenuItem:(NSMenuItem *)menuItem
310     {
311     SEL action = [menuItem action];
312    
313 masaki 281 if(action == @selector(removeThumbnail:)) {
314 masakih 370 HMXSPFComponent *component = self.playlist.thumbnailTrack;
315 masaki 269 if(!component) return NO;
316     }
317    
318     return YES;
319     }
320 masaki 2
321 masaki 306 - (void)setPlaylist:(HMXSPFComponent *)newList
322 masaki 2 {
323 masakih 370 if(_playlist == newList) return;
324 masaki 2
325 masakih 370 [[_playlist childAtIndex:0] removeObserver:self forKeyPath:XspfQTCurrentTrackKey];
326     [_playlist autorelease];
327     _playlist = [newList retain];
328     [[_playlist childAtIndex:0] addObserver:self
329     forKeyPath:XspfQTCurrentTrackKey
330     options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
331     context:NULL];
332 masaki 2 }
333 masaki 306 - (HMXSPFComponent *)playlist
334 masaki 116 {
335 masakih 370 return _playlist;
336 masaki 116 }
337    
338 masaki 306 - (HMXSPFComponent *)trackList
339 masaki 2 {
340 masakih 370 return [self.playlist childAtIndex:0];
341 masaki 2 }
342    
343 masaki 196 + (NSSet *)keyPathsForValuesAffectingPlayingMovieDuration
344     {
345     return [NSSet setWithObject:@"playingMovie"];
346     }
347 masaki 171 - (void)setPlayingMovie:(QTMovie *)newMovie
348     {
349     NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
350 masakih 370 if(_playingMovie) {
351 masaki 188 [nc removeObserver:self
352     name:nil
353 masakih 370 object:_playingMovie];
354 masaki 188 }
355 masaki 171
356 masakih 370 [_playingMovie autorelease];
357     _playingMovie = [newMovie retain];
358     self.playingMovieDuration = 0;
359 masaki 171
360 masakih 370 if(_playingMovie) {
361 masaki 188 [nc addObserver:self
362     selector:@selector(notifee:)
363     name:QTMovieRateDidChangeNotification
364 masakih 370 object:_playingMovie];
365 masaki 188 }
366 masaki 171 }
367     - (QTMovie *)playingMovie
368     {
369 masakih 370 return _playingMovie;
370 masaki 171 }
371 masakih 370 - (void)setPlayingMovieDuration:(NSTimeInterval)playingMovieDuration
372     {
373     _playingMovieDuration = playingMovieDuration;
374     }
375 masaki 182 - (NSTimeInterval)playingMovieDuration
376     {
377 masakih 370 if(_playingMovieDuration == 0) {
378     QTTime qttime = [self.playingMovie duration];
379     if(!QTGetTimeInterval(qttime, &_playingMovieDuration)) _playingMovieDuration = 0;
380 masaki 182 }
381    
382 masakih 370 return _playingMovieDuration;
383 masaki 182 }
384 masaki 171 - (void)loadMovie
385     {
386 masakih 370 NSURL *location = self.trackList.movieLocation;
387 masaki 171
388 masakih 370 if(self.playingMovie) {
389     id movieURL = [self.playingMovie attributeForKey:QTMovieURLAttribute];
390 masaki 181 if([location isEqualUsingLocalhost:movieURL]) return;
391 masaki 174 }
392    
393 masakih 370 self.loader.movieURL = location;
394     [self.loader load];
395     QTMovie *newMovie = self.loader.qtMovie;
396     self.playingMovie = newMovie;
397 masaki 171
398     QTTime qttime = [newMovie duration];
399     id t = [NSValueTransformer valueTransformerForName:@"XspfQTTimeDateTransformer"];
400 masakih 370 [self.trackList setCurrentTrackDuration:[t transformedValue:[NSValue valueWithQTTime:qttime]]];
401 masaki 182
402 masakih 370 self.didPreloading = NO;
403 masaki 171 }
404 masaki 242
405 masaki 171 - (void)observeValueForKeyPath:(NSString *)keyPath
406     ofObject:(id)object
407     change:(NSDictionary *)change
408     context:(void *)context
409     {
410 masaki 244 if([keyPath isEqualToString:XspfQTCurrentTrackKey]) {
411 masaki 242 [self loadMovie];
412 masaki 171 }
413     }
414 masaki 31
415 masaki 71 - (NSXMLDocument *)XMLDocument
416 masaki 31 {
417 masakih 370 id root = self.playlist.XMLElement;
418 masaki 31
419     id d = [[[NSXMLDocument alloc] initWithRootElement:root] autorelease];
420     [d setVersion:@"1.0"];
421     [d setCharacterEncoding:@"UTF-8"];
422    
423     return d;
424     }
425 masaki 42
426 masaki 89 - (void)insertComponentFromURL:(NSURL *)url atIndex:(NSUInteger)index
427     {
428 masaki 306 id new = [HMXSPFComponent xspfTrackWithLocation:url];
429 masaki 89 if(!new) {
430     @throw self;
431     }
432    
433     [self insertComponent:new atIndex:index];
434     }
435 masaki 306 - (void)insertComponent:(HMXSPFComponent *)item atIndex:(NSUInteger)index
436 masaki 55 {
437 masaki 83 id undo = [self undoManager];
438 masaki 86 [undo registerUndoWithTarget:self selector:@selector(removeComponent:) object:item];
439 masakih 370 [self.trackList insertChild:item atIndex:index];
440 masaki 261 [undo setActionName:NSLocalizedString(@"Insert Movie", @"Undo Action Name Insert Movie")];
441 masaki 55 }
442 masaki 306 - (void)removeComponent:(HMXSPFComponent *)item
443 masaki 55 {
444 masakih 370 NSUInteger index = [self.trackList indexOfChild:item];
445 masaki 121 if(index == NSNotFound) {
446 masaki 269 NSLog(@"Can not found item (%@)", item);
447 masaki 121 return;
448     }
449 masaki 83
450     id undo = [self undoManager];
451 masaki 86 [[undo prepareWithInvocationTarget:self] insertComponent:item atIndex:index];
452 masakih 370 [self.trackList removeChild:item];
453 masaki 261 [undo setActionName:NSLocalizedString(@"Remove Movie", @"Undo Action Name Remove Movie")];
454 masaki 55 }
455 masaki 247 - (void)moveComponentFromIndex:(NSUInteger)from toIndex:(NSUInteger)to
456     {
457     id undo = [self undoManager];
458     [[undo prepareWithInvocationTarget:self] moveComponentFromIndex:to toIndex:from];
459 masakih 370 [self.trackList moveChildFromIndex:from toIndex:to];
460 masaki 261 [undo setActionName:NSLocalizedString(@"Move Movie", @"Undo Action Name Move Movie")];
461 masaki 247 }
462 masaki 306 - (void)moveComponent:(HMXSPFComponent *)item toIndex:(NSUInteger)index
463 masaki 247 {
464 masakih 370 NSUInteger from = [self.trackList indexOfChild:item];
465 masaki 247 if(from == NSNotFound) return;
466     [self moveComponentFromIndex:from toIndex:index];
467     }
468 masaki 55
469 masaki 141 - (NSData *)dataFromURL:(NSURL *)url error:(NSError **)outError
470     {
471     NSURLRequest *req = [NSURLRequest requestWithURL:url];
472     NSURLResponse *res = nil;
473     NSError *err = nil;
474     NSData *data = [NSURLConnection sendSynchronousRequest:req
475     returningResponse:&res
476     error:&err];
477     if(err) {
478     if(outError) {
479     *outError = err;
480     }
481     return nil;
482     }
483    
484     return data;
485     }
486    
487 masaki 171 - (void)notifee:(id)notification
488     {
489     // NSLog(@"Notifed: name -> (%@)\ndict -> (%@)", [notification name], [notification userInfo]);
490    
491 masakih 370 HMXSPFComponent *track = self.trackList.currentTrack;
492 masaki 171 NSNumber *rateValue = [[notification userInfo] objectForKey:QTMovieRateDidChangeNotificationParameter];
493     if(rateValue) {
494     float rate = [rateValue floatValue];
495     if(rate == 0) {
496 masakih 370 track.isPlayed = NO;
497 masaki 171 } else {
498 masakih 370 track.isPlayed = YES;
499 masaki 171 }
500     }
501     }
502    
503 masaki 298 // call from XspfQTMovieTimer.
504 masaki 182 - (void)checkPreload:(NSTimer *)timer
505     {
506 masaki 205 if(![XspfQTPref preloadingEnabled]) return;
507 masakih 370 if(self.didPreloading) return;
508 masaki 182
509     NSTimeInterval duration;
510     NSTimeInterval current;
511 masakih 370 QTTime qttime = [self.playingMovie currentTime];
512 masaki 182 if(!QTGetTimeInterval(qttime, &current)) return;
513    
514 masakih 370 duration = self.playingMovieDuration;
515 masaki 182
516 masakih 370 if( current / duration > XspfQTPref.beginingPreloadPercent ) {
517     self.didPreloading = YES;
518     HMXSPFComponent *list = self.trackList;
519     NSUInteger nextIndex = list.selectionIndex + 1;
520     NSUInteger max = list.childrenCount;
521 masaki 182 if(max <= nextIndex) return;
522    
523 masaki 306 HMXSPFComponent *nextTrack = [list childAtIndex:nextIndex];
524 masakih 370 NSURL *nextMovieURL = nextTrack.movieLocation;
525     self.loader.movieURL = nextMovieURL;
526     [self.loader load];
527 masaki 182 }
528     }
529    
530 masaki 274 inline static BOOL isXspfFileType(NSString *typeName)
531     {
532     return [typeName isEqualToString:XspfDocumentType] || [typeName isEqualToString:XspfUTI];
533     }
534     inline static BOOL isReadableMovieType(NSString *typeName)
535     {
536     return [typeName isEqualToString:QuickTimeMovieDocumentType]
537     || [typeName isEqualToString:MatroskaVideoDocumentType]
538     || [typeName isEqualToString:DivXMediaFormatDocumentType];
539     }
540    
541 masaki 2 @end
542    

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26