source: branches/CoreData/SapphireFrappliance/Browser/SapphireBrowser.m @ 598

Revision 598, 22.4 KB checked in by gbooker, 7 years ago (diff)
  • Changed cache structure to be more efficient on predicates
  • Use a less restrictive predicate for watched/favorite checking than the filter since the filter's is a bit more complex
  • Corrected sort mechanisms for many directories
  • Fixed browser's display of divider lines for both frontrow and take 2
Line 
1/*
2 * SapphireBrowser.m
3 * Sapphire
4 *
5 * Created by pnmerrill on Jun. 20, 2007.
6 * Copyright 2007 Sapphire Development Team and/or www.nanopi.net
7 * All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
10 * General Public License as published by the Free Software Foundation; either version 3 of the License,
11 * or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
14 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
15 * Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along with this program; if not,
18 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 */
20
21#import "SapphireBrowser.h"
22#import <BackRow/BackRow.h>
23#import "SapphireDirectoryMetaData.h"
24#import "SapphireFileMetaData.h"
25#import "SapphireEpisode.h"
26#import "SapphireSeason.h"
27#import "SapphireTVShow.h"
28#import "SapphireMovie.h"
29#import "SapphireMarkMenu.h"
30#import "SapphireMedia.h"
31#import "SapphireVideoPlayer.h"
32#import "SapphireMediaPreview.h"
33#import "SapphireTheme.h"
34#import "SapphireSettings.h"
35#import "NSString-Extensions.h"
36#import "SapphireAudioPlayer.h"
37#import "SapphireAudioMedia.h"
38#import "SapphireApplianceController.h"
39#import "SapphireVideoPlayerController.h"
40#import "SapphireMetaDataSupport.h"
41#import <SapphireCompatClasses/SapphireFrontRowCompat.h>
42#import <SapphireCompatClasses/SapphireDVDLoadingController.h>
43
44#import <objc/objc-class.h>
45
46#import "NSFileManager-Extensions.h"
47
48@interface SapphireBrowser (private)
49- (void)reloadDirectoryContents;
50- (void)setNewPredicate:(NSPredicate *)newPredicate;
51@end
52
53@interface BRMusicNowPlayingController (bypassAccess)
54- (void)setPlayer:(BRMusicPlayer *)player;
55- (BRMusicPlayer *)player;
56@end
57
58@implementation BRMusicNowPlayingController (bypassAccess)
59- (void)setPlayer:(BRMusicPlayer *)player
60{
61        Class myClass = [self class];
62        Ivar ret = class_getInstanceVariable(myClass, "_player");
63        BRMusicPlayer * *thePlayer = (BRMusicPlayer * *)(((char *)self)+ret->ivar_offset);     
64       
65        [*thePlayer release];
66        *thePlayer = [player retain];
67}
68
69- (BRMusicPlayer *)player
70{
71        Class myClass = [self class];
72        Ivar ret = class_getInstanceVariable(myClass, "_player");
73        return *(BRMusicPlayer * *)(((char *)self)+ret->ivar_offset);   
74}
75
76@end
77
78static BOOL is10Version = NO;
79
80@implementation SapphireBrowser
81
82- (id) initWithScene: (BRRenderScene *) scene metaData:(id <SapphireDirectory>)meta
83{
84        if([super initWithScene:scene] == nil)
85                return nil;
86               
87        _names = [NSMutableArray new];
88        items = [NSMutableDictionary new];
89        metaData = [meta retain];
90        predicate = [[SapphireApplianceController predicate] retain];
91        [metaData setFilterPredicate:predicate];
92
93        // set the datasource *after* you've setup your array
94        [[self list] setDatasource: self] ;
95               
96        return ( self );
97}
98
99- (void) dealloc
100{
101    // always remember to deallocate your resources
102        [_names release];
103        [items release];
104        if([metaData delegate] == self)
105                [metaData setDelegate:nil];
106        [metaData release];
107        [predicate release];
108    [super dealloc];
109}
110
111- (void)reloadDirectoryContents
112{
113        /*Tell the metadata to get new data*/
114        [metaData reloadDirectoryContents];
115}
116
117- (void)directoryContentsChanged
118{
119        BOOL isTake2 = [SapphireFrontRowCompat usingTakeTwo];
120        BOOL isReallyFrontrow = !isTake2 && [SapphireFrontRowCompat usingFrontRow];
121        NSString *oldName=nil;
122        int row = [self getSelection];
123       
124        if(row < [_names count])
125                oldName = [[_names objectAtIndex:row] retain];
126
127        /*Flush our cache*/
128        [_names removeAllObjects];
129        [items removeAllObjects];
130        /*Set up the dirs and files into names and the counts*/
131        NSArray *dirs = [metaData directories];
132        [_names addObjectsFromArray:dirs];
133        NSArray *files = [metaData files];
134        [_names addObjectsFromArray:files];
135        dirCount = [dirs count];
136        fileCount = [files count];
137        if(predicate != NULL)
138        {
139                /*Put in the menu for rescan if fast switching enabled*/
140                if([[SapphireSettings sharedSettings] fastSwitching])
141                        [_names addObject:BRLocalizedString(@"     < Scan for new files >", @"Conduct a scan of the directory for new files")];
142        }               
143        /*Remove the dividers*/
144        BRListControl *list = [self list];
145        if([list respondsToSelector:@selector(removeDividers)])
146                [list removeDividers];
147        else
148                [list setDividerIndex:0];
149        [list removeDividerAtIndex:0];
150        /*Do a reload*/
151        [list reload];
152        /*Add dividers*/
153        int indexOffset = 0;
154        if(dirCount && fileCount)
155        {
156                [SapphireFrontRowCompat addDividerAtIndex:dirCount toList:list];
157                if(!is10Version && !isTake2)
158                        indexOffset++;
159        }
160        if(predicate != NULL && [[SapphireSettings sharedSettings] fastSwitching])
161                if(!isReallyFrontrow || indexOffset == 0) //Frontrow cannot display a list with two dividers correctly!!!!!
162                        [SapphireFrontRowCompat addDividerAtIndex:dirCount + fileCount + indexOffset toList:list];
163        if([[self stack] peekController] == self)
164                [metaData resumeImport];
165       
166        /*Attempt to preserve the user's current highlighted selection*/
167        if(oldName)
168        {
169                row = [_names indexOfObject:oldName];
170                if(row != NSNotFound)
171                        [(BRListControl *)[self list] setSelection:row];
172                else
173                        [(BRListControl *)[self list] setSelection:0];
174                [oldName release];
175        }
176        /*Draw*/
177        justReloaded = YES;
178        [self updatePreviewController];
179        [SapphireFrontRowCompat renderScene:[self scene]];
180}
181
182- (id <SapphireDirectory>)metaData
183{
184        return metaData;
185}
186
187- (void) willBePushed
188{
189    // We're about to be placed on screen, but we're not yet there
190   
191    // always call super
192    [super willBePushed];
193        /*Reload upon display*/
194        @try {
195                [metaData setDelegate:self];
196                [self setNewPredicate:[SapphireApplianceController predicate]];
197        }
198        @catch (NSException * e) {
199                [SapphireApplianceController logException:e];
200        }
201}
202
203- (void) wasPushed
204{
205    // We've just been put on screen, the user can see this controller's content now
206   
207    // always call super
208    [super wasPushed];
209        /*Get metadata when we can*/
210        [metaData resumeImport];
211}
212
213- (void) willBePopped
214{
215    // The user pressed Menu, but we've not been removed from the screen yet
216   
217    // always call super
218    [super willBePopped];
219        /*Cancel everything we were doing*/
220        [metaData cancelImport];
221        cancelScan = YES;
222        [metaData setDelegate:nil];
223}
224
225- (void) wasPopped
226{
227    // The user pressed Menu, removing us from the screen
228    // always call super
229    [super wasPopped];
230}
231
232- (void) willBeBuried
233{
234    // The user just chose an option, and we will be taken off the screen
235   
236        /*Cancel everything we were doing*/
237        [metaData cancelImport];
238        cancelScan = YES;
239        // always call super
240    [super willBeBuried];
241}
242
243- (void) wasBuriedByPushingController: (BRLayerController *) controller
244{
245    // The user chose an option and this controller is no longer on screen
246   
247    // always call super
248    [super wasBuriedByPushingController: controller];
249}
250
251- (void) willBeExhumed
252{
253    // the user pressed Menu, but we've not been revealed yet
254   
255        /*Reload our display*/
256        [self setNewPredicate:[SapphireApplianceController predicate]];
257    // always call super
258    [super willBeExhumed];
259}
260
261- (void) wasExhumedByPoppingController: (BRLayerController *) controller
262{
263    // handle being revealed when the user presses Menu
264   
265    // always call super
266    [super wasExhumedByPoppingController: controller];
267        /*Check to see if dir is empty*/
268        if(fileCount + dirCount == 0)
269                [[self stack] popController];
270        else
271                /*Resume importing now that we are up again*/
272                [metaData resumeImport];
273}
274
275- (long) itemCount
276{
277    // return the number of items in your menu list here
278        if([_names count])
279                return ( [ _names count]);
280        // Put up an empty item
281        return 1;
282}
283
284- (id<BRMenuItemLayer>) itemForRow: (long) row
285{
286        NSString * displayName=nil ;
287        /*Check for no items*/
288        int nameCount = [_names count];
289        FileClass fileCls=0;
290        if( nameCount == 0)
291        {
292                BRAdornedMenuItemLayer *result = [SapphireFrontRowCompat textMenuItemForScene:[self scene] folder:NO];
293                [SapphireFrontRowCompat setTitle:BRLocalizedString(@"< EMPTY >", @"Empty directory") forMenu:result];
294                return result;
295        }
296        if( row >= nameCount ) return ( nil ) ;
297       
298        /*Check our cache*/
299        NSString *name = [_names objectAtIndex:row];
300        id cached = [items objectForKey:name];
301        if(cached != nil)
302                return cached;
303        // Pad filename to correcrtly display gem icons
304        BRAdornedMenuItemLayer * result = nil;
305        BOOL watched = NO;
306        BOOL favorite = NO;
307        BOOL utility = NO;
308        BRRenderScene *scene = [self scene];
309        SapphireTheme *theme = [SapphireTheme sharedTheme];
310        /*Is this a dir*/
311        if(row < dirCount)
312        {
313                result = [SapphireFrontRowCompat textMenuItemForScene:scene folder:YES];
314                id <SapphireDirectory> meta = [metaData metaDataForDirectory:name];
315                watched = ![meta containsFileMatchingPredicate:[SapphireApplianceController unwatchedPredicate]];
316                favorite = [meta containsFileMatchingPredicate:[SapphireApplianceController favoritePredicate]];
317        }
318        /*Check for a file next*/
319        else if(row < dirCount + fileCount)
320        {
321                result = [SapphireFrontRowCompat textMenuItemForScene:scene folder:NO];
322                SapphireFileMetaData *meta = [metaData metaDataForFile:name];
323                if(meta != nil)
324                {
325                        fileCls=[meta fileClassValue];
326                        BOOL rightTextSet;
327                        if(fileCls==FILE_CLASS_TV_SHOW)
328                        {
329                                SapphireEpisode *ep = [meta tvEpisode];
330                                /*Display episode number if availble*/
331                                int eps= [ep episodeNumberValue];
332                                int ep2= [ep lastEpisodeNumberValue];
333                                displayName=[ep episodeTitle] ;
334                                if(eps>0)
335                                {
336                                        NSArray *comp = [[metaData path] pathComponents];
337                                        NSString *prefix = @"";
338                                        if([comp count] == 2 && [[comp objectAtIndex:0] isEqual:@"@TV"])
339                                                /*Eps listed outside of seasons*/
340                                                prefix = [NSString stringWithFormat:@"%02d/", [[ep season] seasonNumberValue]];
341                                        if(ep2>0 && ep2 != eps)
342                                                [SapphireFrontRowCompat setRightJustifiedText:[NSString stringWithFormat:@" %@%02d-%02d", prefix, eps, ep2] forMenu:result];
343                                        else
344                                                [SapphireFrontRowCompat setRightJustifiedText:[NSString stringWithFormat:@" %@%02d", prefix, eps] forMenu:result];
345                                        rightTextSet = YES;
346                                }
347                        }
348                        if(fileCls==FILE_CLASS_MOVIE)
349                        {
350                                SapphireMovie *movie = [meta movie];
351                                displayName=[movie title];
352                                /* Find out if we are displaying a virtual directoy we need to filter for */
353                                NSString *dirFilter=[[[metaData path] pathComponents] objectAtIndex:1];
354                                /*Add icons & stats (RIGHT)*/
355                                int top250 = [movie imdbTop250RankingValue];
356                                if([dirFilter isEqualToString:VIRTUAL_DIR_TOP250_KEY] && top250 > 0)
357                                {
358                                        NSString *movieStatsTop250 = [NSString stringWithFormat:@"#%d ", top250];
359                                        /* This list is already filtered so all displayed movies will have a top250 stat */
360                                        [SapphireFrontRowCompat setRightJustifiedText:movieStatsTop250 forMenu:result];
361                                        [SapphireFrontRowCompat setRightIcon:[theme gem:IMDB_GEM_KEY] forMenu:result];
362                                        rightTextSet = YES;
363                                }
364                                else if([movie oscarsWonValue] > 0)
365                                {
366                                        NSString *movieStatsOscar = [NSString stringWithFormat:@"%dx", [movie oscarsWonValue]];
367                                        [SapphireFrontRowCompat setRightJustifiedText:movieStatsOscar forMenu:result];
368                                        [SapphireFrontRowCompat setRightIcon:[theme gem:OSCAR_GEM_KEY] forMenu:result];
369                                        rightTextSet = YES;
370                                }
371                                else if(top250 > 0)
372                                {
373                                        NSString *movieStatsTop250 = [NSString stringWithFormat:@"#%d ", top250];
374                                        [SapphireFrontRowCompat setRightJustifiedText:movieStatsTop250 forMenu:result];
375                                        [SapphireFrontRowCompat setRightIcon:[theme gem:IMDB_GEM_KEY] forMenu:result];
376                                        rightTextSet = YES;
377                                }
378                        }
379                        watched = [meta watchedValue];
380                        favorite = [meta favoriteValue];
381                        NSString *sizeString = [meta sizeString];
382                        if(!rightTextSet && [sizeString length] > 1)
383                                /*Fallback to size*/
384                                [SapphireFrontRowCompat setRightJustifiedText:sizeString forMenu:result];
385
386                }
387        }
388        /*Utility*/
389        else
390        {
391                result = [SapphireFrontRowCompat textMenuItemForScene:scene folder:NO];
392                utility = YES;
393        }
394        /*Add icons (LEFT)*/
395        if(utility) [SapphireFrontRowCompat setLeftIcon:[theme gem:FAST_GEM_KEY] forMenu:result];
396        else if(!watched) [SapphireFrontRowCompat setLeftIcon:[theme gem:BLUE_GEM_KEY] forMenu:result];
397        else if(favorite) [SapphireFrontRowCompat setLeftIcon:[theme gem:YELLOW_GEM_KEY] forMenu:result];
398        else if(fileCls==FILE_CLASS_AUDIO)[SapphireFrontRowCompat setLeftIcon:[theme gem:GREEN_GEM_KEY] forMenu:result];
399        else [SapphireFrontRowCompat setLeftIcon:[theme gem:RED_GEM_KEY] forMenu:result];
400                       
401        // add text
402        if(displayName)name= displayName ;
403        name=[@"  " stringByAppendingString: name] ;
404        [SapphireFrontRowCompat setTitle:name forMenu:result];
405        [items setObject:result forKey:name];
406                               
407        return ( result ) ;
408}
409
410- (NSString *) titleForRow: (long) row
411{
412
413        if ( row >= [ _names count] ) return ( nil );
414       
415        NSString *result = [ _names objectAtIndex: row] ;
416       
417        return ([@"  ????? " stringByAppendingString: result] ) ;
418}
419
420- (long) rowForTitle: (NSString *) title
421{
422    long result = -1;
423    long i, count = [self itemCount];
424    for ( i = 0; i < count; i++ )
425    {
426        if ( [title isEqualToString: [self titleForRow: i]] )
427        {
428            result = i;
429            break;
430        }
431    }
432   
433    return ( result );
434}
435
436- (void)setNewPredicate:(NSPredicate *)newPredicate
437{
438        [newPredicate retain];
439        [predicate release];
440        predicate = newPredicate;
441        if([metaData filterPredicate] != predicate)
442                [metaData setFilterPredicate:predicate];
443        [self setListIcon:[SapphireApplianceController gemForPredicate:predicate]];
444        [self reloadDirectoryContents];
445}
446
447- (void) itemSelected: (long) row
448{
449    // This is called when the user presses play/pause on a list item
450       
451        if([_names count] == 0)
452        {
453                /*No items, so leave the empty dir*/
454                [[self stack] popController];
455                return;
456        }
457       
458        NSString *name = [_names objectAtIndex:row];
459       
460        /*Check for dir*/
461        if(row < dirCount)
462        {
463                /*Browse the subdir*/
464                id controller = [[SapphireBrowser alloc] initWithScene:[self scene] metaData:[metaData metaDataForDirectory:name]];
465                [controller setListTitle:[NSString stringWithFormat:@" %@",name]];
466                [controller setListIcon:[self listIcon]];
467                [[self stack] pushController:controller];
468                [controller release];
469        }
470        else if(row < dirCount + fileCount)
471        {
472                /*Play the file*/
473                SapphireFileMetaData *currentPlayFile = [[metaData metaDataForFile:name] retain];
474                if([currentPlayFile updateMetaData])
475                        [SapphireMetaDataSupport save:[currentPlayFile managedObjectContext]];
476               
477                NSString *path = [currentPlayFile path];
478               
479                /*Anonymous reporting*/
480                SapphireSettings *settings = [SapphireSettings sharedSettings];
481                if(![settings disableAnonymousReporting])
482                {
483                        NSMutableString *reqData = [NSMutableString string];
484                        NSMutableArray *reqComp = [NSMutableArray array];
485                        NSMutableURLRequest *request=nil;
486                        NSString *ext=nil;
487                        int fileClass=-1;
488                       
489                        if(path != 0)
490                        {
491                                [reqComp addObject:[NSString stringWithFormat:@"path=%@", [[path lastPathComponent]lowercaseString]]];
492                                ext=[[path pathExtension]lowercaseString] ;
493                        }
494                       
495                        if([currentPlayFile fileClassValue] == FILE_CLASS_TV_SHOW)
496                        {
497                                SapphireEpisode *episode = [currentPlayFile tvEpisode];
498                                fileClass=1;
499                                request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://appletv.nanopi.net/show.php"]];
500                                int ep = [episode episodeNumberValue];
501                                int season = [[episode season] seasonNumberValue];
502                                SapphireTVShow *show = [episode tvShow];
503                                NSString *showID = [show showPath];
504                                NSString *showName= [show name];
505                                 
506                                if(season != 0)
507                                        [reqComp addObject:[NSString stringWithFormat:@"season=%d", season]];
508                                if(ep != 0)
509                                        [reqComp addObject:[NSString stringWithFormat:@"ep=%d", ep]];
510                                if(showName != 0)
511                                        [reqComp addObject:[NSString stringWithFormat:@"showname=%@", showName]];
512                                if(showID != 0)
513                                        [reqComp addObject:[NSString stringWithFormat:@"showid=%@", showID]];
514                        }
515                        else if([currentPlayFile fileClassValue] == FILE_CLASS_MOVIE)
516                        {
517                                fileClass=2;
518                                request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://appletv.nanopi.net/movie.php"]];
519                                SapphireMovie *movie = [currentPlayFile movie];
520                                NSString *movieTitle=[movie title];
521                                int movieID=[movie imdbNumberValue];
522                                NSDate * releaseDate=[movie releaseDate];
523                                if(movieTitle != 0)
524                                        [reqComp addObject:[NSString stringWithFormat:@"title=%@", movieTitle]];
525                                if(releaseDate != 0)
526                                        [reqComp addObject:[NSString stringWithFormat:@"year=%@", [releaseDate descriptionWithCalendarFormat:@"%Y" timeZone:nil locale:[[NSUserDefaults standardUserDefaults] dictionaryRepresentation]]]];
527                                if(movieID != 0)
528                                        [reqComp addObject:[NSString stringWithFormat:@"movieid=%d", movieID]];
529                        }
530                        else
531                        {
532                                request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://appletv.nanopi.net/ext.php"]];
533                                if([currentPlayFile fileClassValue] == FILE_CLASS_UNKNOWN)
534                                         fileClass=0;
535                                if([currentPlayFile fileClassValue] == FILE_CLASS_AUDIO)
536                                         fileClass=3;
537                                if([currentPlayFile fileClassValue] == FILE_CLASS_OTHER)
538                                        fileClass=5;
539                                else
540                                        fileClass=99;
541                        }
542                       
543                        if(ext!=0)
544                        {
545                                [reqComp addObject:[NSString stringWithFormat:@"filetype=%d",fileClass]];
546                                [reqComp addObject:[NSString stringWithFormat:@"extension=%@", ext]];
547                                if([SapphireFrontRowCompat usingFrontRow])
548                                        [reqComp addObject:[NSString stringWithFormat:@"ckey=FRONTROW-%@-%d",ext,fileClass]];
549                                else
550                                        [reqComp addObject:[NSString stringWithFormat:@"ckey=ATV-%@-%d",ext,fileClass]];
551                        }
552                       
553                        int count = [reqComp count];
554                        int i;
555                        for(i=0; i<count-1; i++)
556                        {
557                                [reqData appendFormat:@"%@&", [reqComp objectAtIndex:i]];
558                        }
559                        if(count)
560                                [reqData appendFormat:@"%@", [reqComp objectAtIndex:i]];
561                       
562                        NSData *postData = [reqData dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
563                       
564                        [request setHTTPMethod:@"POST"];
565                        [request setValue:[NSString stringWithFormat:@"%d", [postData length]] forHTTPHeaderField:@"Content-Length"];
566                        [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
567                        [request setHTTPBody:postData];
568                        [request setCachePolicy:NSURLRequestReloadIgnoringCacheData];
569                        /*Trigger the req*/
570                        NSURLDownload *download = [[NSURLDownload alloc] initWithRequest:request delegate:nil];
571                        [download autorelease];
572                }
573               
574                if ([currentPlayFile fileContainerTypeValue] == FILE_CONTAINER_TYPE_VIDEO_TS)
575                {
576                        BRDVDMediaAsset *asset = [[BRDVDMediaAsset alloc] initWithPath:path];
577                        SapphireDVDLoadingController *controller = [[SapphireDVDLoadingController alloc] initWithScene:[self scene] forAsset:asset];
578                        [asset release];
579                        [[self stack] pushController:controller];
580                        [controller release];
581                }
582                else if([[NSFileManager defaultManager] acceptFilePath:path] && [currentPlayFile hasVideoValue])
583                {
584                        /*Video*/
585                        /*Set the asset resume time*/
586                        NSURL *url = [NSURL fileURLWithPath:path];
587                        SapphireMedia *asset  =[[SapphireMedia alloc] initWithMediaURL:url];
588                        [asset setResumeTime:[currentPlayFile resumeTimeValue]];
589                       
590                        /*Get the player*/
591                        SapphireVideoPlayer *player = [[SapphireVideoPlayer alloc] init];
592                        NSError *error = nil;
593                        [player setMedia:asset error:&error];
594                       
595                        /*and go*/
596                        SapphireVideoPlayerController *controller = [[SapphireVideoPlayerController alloc] initWithScene:[self scene]];
597                        [controller setPlayFile:currentPlayFile];
598                        [controller setAllowsResume:YES];
599                        [controller setVideoPlayer:player];
600                        [[self stack] pushController:controller];
601
602                        [asset release];
603                        [player release];
604                        [controller release];
605                }
606                else
607                {
608                        /*Audio*/
609                        /*Set the asset*/
610                        NSURL *url = [NSURL fileURLWithPath:path];
611                        SapphireAudioMedia *asset  =[[SapphireAudioMedia alloc] initWithMediaURL:url];
612                        [asset setResumeTime:[currentPlayFile resumeTimeValue]];
613                       
614                        SapphireAudioPlayer *player = [[SapphireAudioPlayer alloc] init];
615                        NSError *error = nil;
616                        [player setMedia:asset inTracklist:[NSArray arrayWithObject:asset] error:&error];
617                       
618                        /*and go*/
619                        BRMusicNowPlayingController *controller = [BRMusicNowPlayingController alloc];
620                        if([controller respondsToSelector:@selector(initWithScene:)])
621                                controller = [controller initWithScene:[self scene]];
622                        else
623                                controller = [controller init];
624                        [controller setPlayer:player];
625                        [player setElapsedPlaybackTime:[currentPlayFile resumeTimeValue]];
626                        [player play];
627                        [[self stack] pushController:controller];
628                       
629                        [asset release];
630                        [player release];
631                        [controller release];
632                }
633        }
634        else
635        {
636                /*Do a scan*/
637                cancelScan = NO;
638                [metaData scanForNewFilesWithDelegate:self skipDirectories:[NSMutableSet set]];
639        }
640}
641
642- (void)gotSubFiles:(NSArray *)subs
643{
644        [self reloadDirectoryContents];
645}
646
647- (void)scanningDir:(NSString *)dir
648{
649}
650
651- (BOOL)getSubFilesCanceled
652{
653        return cancelScan;
654}
655
656- (id<BRMediaPreviewController>) previewControlForItem: (long) row
657{
658        return [self previewControllerForItem:row];
659}
660
661- (id<BRMediaPreviewController>) previewControllerForItem: (long) row
662{
663    // If subclassing BRMediaMenuController, this function is called when the selection cursor
664    // passes over an item.
665        if(row >= [_names count])
666                return nil;
667        /*Check to see if it is a dir or file*/
668        NSString *name = [_names objectAtIndex:row];
669        if(row < dirCount + fileCount)
670        {
671                SapphireMediaPreview *preview = [[SapphireMediaPreview alloc] initWithScene:[self scene]];
672                /*Check for dir*/
673                if(row < dirCount)
674                        [preview setMetaData:[metaData metaDataForDirectory:name] inMetaData:metaData];
675                else
676                        [preview setMetaData:[metaData metaDataForFile:name] inMetaData:metaData];
677                [preview setShowsMetadataImmediately:justReloaded];
678                justReloaded = NO;
679                /*And go*/
680                return [preview autorelease];
681        }
682    return ( nil );
683}
684
685- (BOOL)brEventAction:(BREvent *)event
686{
687        BREventPageUsageHash hashVal = [event pageUsageHash];
688        if ([(BRControllerStack *)[self stack] peekController] != self)
689                hashVal = 0;
690               
691        int row = [self getSelection];
692       
693        switch (hashVal)
694        {
695                case kBREventTapRight:
696                {
697                        id meta = nil;
698                        if(row >= [_names count])
699                                break;
700                       
701                        NSString *name = [_names objectAtIndex:row];
702                       
703                        /*Get metadata*/
704                        if(row < dirCount)
705                                meta = [metaData metaDataForDirectory:name];
706                        else if (row < dirCount + fileCount)
707                                meta = [metaData metaDataForFile:name];
708                        else
709                                break;
710                        /*Do mark menu*/
711                        id controller = [[SapphireMarkMenu alloc] initWithScene:[self scene] metaData:meta];
712                        [(SapphireMarkMenu *)controller setListTitle:name];
713                        [[self stack] pushController:controller];
714                        [controller release];
715                        return YES;
716                }
717                case kBREventTapLeft:
718                {
719                        [self setNewPredicate:[SapphireApplianceController nextPredicate]];
720                        return YES;
721                }
722        }
723        return [super brEventAction:event];
724}
725
726- (void)updateCompleteForFile:(NSString *)file
727{
728        /*Get the file*/
729        [items removeObjectForKey:file];
730        /*Relead the list and render*/
731        BRListControl *list = [self list];
732        [list reload];
733        [SapphireFrontRowCompat renderScene:[self scene]];
734}
735
736@end
Note: See TracBrowser for help on using the repository browser.