source: branches/CoreData/SapphireFrappliance/FRAppliance/SapphireApplianceController.m @ 723

Revision 723, 20.1 KB checked in by gbooker, 6 years ago (diff)

Changed the order of construction to be consistent with Apple's examples. Doesn't likely matter, but just in case.
Extended tester code so it could handle more cases in the future.

Line 
1/*
2 * SapphireApplianceController.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 "SapphireApplianceController.h"
22#import <BackRow/BackRow.h>
23#include <dlfcn.h>
24#import <SapphireCompatClasses/SapphireFrontRowCompat.h>
25#import <SapphireCompatClasses/SapphireDVDLoadingController.h>
26
27#import "SapphireBrowser.h"
28#import "SapphireDirectoryMetaData.h"
29#import "SapphireFileMetaData.h"
30#import "SapphireSettings.h"
31#import "SapphireTheme.h"
32#import "SapphireCollectionDirectory.h"
33#import "CoreDataSupportFunctions.h"
34#import "SapphireEpisode.h"
35
36#import "SapphireImporterDataMenu.h"
37#import "SapphireXMLFileDataImporter.h"
38#import "SapphireFileDataImporter.h"
39#import "SapphireTVShowImporter.h"
40#import "SapphireMovieImporter.h"
41#import "SapphireAllImporter.h"
42#import "SapphireImportHelper.h"
43#import "SapphireMetaDataSupport.h"
44#import "SapphireEntityDirectory.h"
45#import "SapphireTVShow.h"
46#import "SapphireMovieDirectory.h"
47
48#import "NSFileManager-Extensions.h"
49
50NSString *SAPPHIRE_MANAGED_OBJECT_CONTEXT_CLOSING =     @"SapphireManagedObjectContextClosing";
51
52#define BROWSER_MENU_ITEM               BRLocalizedString(@"  Browse", @"Browser Menu Item")
53#define ALL_IMPORT_MENU_ITEM    BRLocalizedString(@"  Import All Data", @"All Importer Menu Item")
54#define SETTINGS_MENU_ITEM              BRLocalizedString(@"  Settings", @"Settings Menu Item")
55#define RESET_MENU_ITEM                 BRLocalizedString(@"  Reset the thing already", @"UI Quit")
56
57@interface SapphireApplianceController (private)
58- (void)setMenuFromSettings;
59- (void)recreateMenu;
60@end
61
62@implementation SapphireApplianceController
63
64static NSArray *predicates = nil;
65
66NSPredicate *unwatched = nil;
67NSPredicate *favorite = nil;
68NSPredicate *skipJoin = nil;
69NSPredicate *strictUnwatched = nil;
70NSPredicate *strictFavorite = nil;
71
72+ (void)initialize
73{
74        skipJoin = [[NSPredicate predicateWithFormat:@"joinedToFile == nil"] retain];
75        unwatched = [[NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:[NSPredicate predicateWithFormat:@"watched == NO"], skipJoin, nil]] retain];
76        favorite = [[NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:[NSPredicate predicateWithFormat:@"favorite == YES"], skipJoin, nil]] retain];
77//      NSPredicate *topShows = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:[NSPredicate predicateWithFormat:@"top == YES"], skipJoin, nil]];
78        predicates = [[NSArray alloc] initWithObjects:unwatched, favorite/*, topShows*/, nil];
79        strictUnwatched = [[NSPredicate predicateWithFormat:@"watched == NO"] retain];
80        strictFavorite = [[NSPredicate predicateWithFormat:@"favorite == YES"] retain];
81}
82
83+ (NSPredicate *)predicate
84{
85        SapphireSettings *settings = [SapphireSettings sharedSettings];
86        int index = [settings indexOfLastPredicate];
87        if(index == NSNotFound)
88                return skipJoin;
89        return [predicates objectAtIndex:index];
90}
91
92+ (NSPredicate *)nextPredicate
93{
94        SapphireSettings *settings = [SapphireSettings sharedSettings];
95        int index = [settings indexOfLastPredicate];
96        int newIndex;
97        switch(index)
98        {
99                case NSNotFound:
100                        newIndex = 0;
101                        if([settings displayUnwatched])
102                                break;
103                case 0:
104                        newIndex = 1;
105                        if([settings displayFavorites])
106                                break;
107//              case 1:
108//                      newIndex = 2;
109//                      if([settings displayTopShows])
110//                              break;
111                default:
112                        newIndex = NSNotFound;
113        }
114        [settings setIndexOfLastPredicate:newIndex];
115        if(newIndex == NSNotFound)
116                return skipJoin;
117        return [predicates objectAtIndex:newIndex];
118}
119
120+ (PredicateType)predicateType
121{
122        return [[SapphireSettings sharedSettings] indexOfLastPredicate];
123}
124
125+ (void)setPredicateType:(PredicateType)type
126{
127        [[SapphireSettings sharedSettings] setIndexOfLastPredicate:type];
128}
129
130+ (NSPredicate *)unfilteredPredicate
131{
132        return skipJoin;
133}
134
135+ (NSPredicate *)unwatchedPredicate
136{
137        return strictUnwatched;
138}
139
140+ (NSPredicate *)favoritePredicate
141{
142        return strictFavorite;
143}
144
145+ (BRTexture *)gemForPredicate:(NSPredicate *)predicate
146{
147        SapphireTheme *theme = [SapphireTheme sharedTheme];
148        if(predicate == nil)
149                return [theme gem:RED_GEM_KEY];
150        int index = [predicates indexOfObject:predicate];
151        switch (index) {
152                case 0:
153                        return [theme gem:BLUE_GEM_KEY];
154                case 1:
155                        return [theme gem:YELLOW_GEM_KEY];
156                case 2:
157                        return [theme gem:GREEN_GEM_KEY];
158        }
159        return [theme gem:RED_GEM_KEY];
160}
161
162+ (NSString *)keyForFilterPredicate:(NSPredicate *)filter andCheckPredicate:(NSPredicate *)check
163{
164        int found = 0;
165        if(filter == skipJoin)
166                found = 1;
167        else if (filter == unwatched)
168                found = 2;
169        else if (filter == favorite)
170                found = 4;
171        else if (filter != nil)
172                return [[filter description] stringByAppendingString:[check description]];
173       
174        if(check == strictUnwatched)
175                found |= 2;
176        else if (check == strictFavorite)
177                found |= 4;
178        else if (check != nil)
179                return [[filter description] stringByAppendingString:[check description]];
180       
181        switch (found) {
182                case 0:
183                        return @"nil";
184                case 1:
185                        return @"S";
186                case 2:
187                        return @"W";
188                case 3:
189                        return @"SW";
190                case 4:
191                        return @"F";
192                case 5:
193                        return @"SF";
194                case 6:
195                        return @"WF";
196                case 7:
197                        return @"SWF";
198        }
199        return nil;
200}
201
202+ (void)logException:(NSException *)e
203{
204        NSMutableString *ret = [NSMutableString stringWithFormat:@"Exception: %@ %@\n", [e name], [e reason]];
205        if([e respondsToSelector:@selector(backtrace)])
206        {
207                [ret appendFormat:@"%@\n%@", e, [(BRBacktracingException *)e backtrace]];
208                Dl_info info;
209                if(dladdr(&predicates, &info))
210                        [ret appendFormat:@"Sapphire is at 0x%X", info.dli_fbase];
211        }
212        else
213        {
214                NSArray *addrs = [SapphireFrontRowCompat callStackReturnAddressesForException:e];
215                int i, count = [addrs count];
216                NSMutableDictionary *mapping = [NSMutableDictionary dictionary];
217                for(i=0; i<count; i++)
218                {
219                        Dl_info info;
220                        const void *addr = [[addrs objectAtIndex:i] pointerValue];
221                        if(dladdr(addr, &info))
222                                [mapping setObject:[NSString stringWithCString:info.dli_fname] forKey:[NSValue valueWithPointer:info.dli_fbase]];
223                        [ret appendFormat:@" 0x%X", addr];
224                }
225                NSEnumerator *mappingEnum = [mapping keyEnumerator];
226                NSValue *key = nil;
227                while((key = [mappingEnum nextObject]) != nil)
228                        [ret appendFormat:@"\n0x%X\t%@", [key pointerValue], [mapping objectForKey:key]];
229        }
230        SapphireLog(SAPPHIRE_LOG_GENERAL, SAPPHIRE_LOG_LEVEL_ERROR, @"%@", ret);       
231}
232
233+ (NSString *) rootMenuLabel
234{
235        return (@"net.pmerrill.Sapphire" );
236}
237
238+ (BOOL)upgradeNeeded
239{
240        NSFileManager *fm = [NSFileManager defaultManager];
241        NSString *storeFile = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Application Support/Sapphire/metaData.sapphireData"];
242        BOOL exists = [fm fileExistsAtPath:storeFile];
243        NSString *plistFile = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Application Support/Sapphire/metaData.plist"];
244        BOOL oldExists = [fm fileExistsAtPath:plistFile];
245        return !exists && oldExists;
246}
247
248- (id) initWithScene: (BRRenderScene *) scene
249{
250        self = [super initWithScene:scene];
251       
252        //Setup the theme's scene
253        SapphireTheme *theme = [SapphireTheme sharedTheme];
254        [theme setScene:[self scene]];
255       
256        NSFileManager *fm = [NSFileManager defaultManager];
257        NSString *storeFile = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Application Support/Sapphire/metaData.sapphireData"];
258        [fm constructPath:[storeFile stringByDeletingLastPathComponent]];
259        NSURL *storeUrl = [NSURL fileURLWithPath:storeFile];
260        NSError *error = nil;
261
262        NSString *mopath = [[NSBundle bundleForClass:[self class]] pathForResource:@"Sapphire" ofType:@"momd"];
263        mopath = [mopath stringByAppendingPathComponent:@"SapphireV1.mom"];
264        NSURL *mourl = [NSURL fileURLWithPath:mopath];
265        NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:mourl];
266
267        NSPersistentStoreCoordinator *coord = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
268        if(![coord addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error])
269        {
270                SapphireLog(SAPPHIRE_LOG_ALL, SAPPHIRE_LOG_LEVEL_ERROR, @"Could not add store: %@", error);
271               
272                [coord release];
273                [model release];
274                [self autorelease];
275                return nil;
276        }
277
278        moc = [[NSManagedObjectContext alloc] init];
279        [moc setUndoManager:nil];
280        [moc setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
281        [moc setPersistentStoreCoordinator:coord];
282       
283        [coord release];
284       
285        [SapphireDirectoryMetaData createDirectoryWithPath:@"/" parent:nil inContext:moc];
286        [SapphireCollectionDirectory collectionAtPath:@"/" mount:YES skip:YES hidden:YES manual:NO inContext:moc];
287       
288        settings                                                                = [[SapphireSettings alloc] initWithScene:[self scene] settingsPath:[NSHomeDirectory() stringByAppendingPathComponent:@"Library/Application Support/Sapphire/settings.plist"] context:moc];
289        [self setListTitle:                                             BRLocalizedString(@"Main Menu", @"")];
290        [settings setListTitle:                                 BRLocalizedString(@" Settings", @"Settings Menu Item")] ;
291        [settings setListIcon:                                  [theme gem:GEAR_GEM_KEY]];
292        [[self list] setDatasource:self];
293        if([SapphireFrontRowCompat usingFrontRow] && ![SapphireFrontRowCompat usingTakeTwo])
294        {
295                NSString *myBundlePath = [[NSBundle bundleForClass:[self class]] bundlePath] ;
296                NSString *onlyPath = [myBundlePath stringByAppendingPathComponent:@"/Contents/Frameworks/LeopardOnly.framework"];
297                NSBundle *only = [NSBundle bundleWithPath:onlyPath];
298                Class onlyClass = [only principalClass];
299                leoOnly = [[onlyClass alloc] initWithContext:moc];
300        }
301        mountsOnly = NO;
302       
303        SapphireSetLogLevel(SAPPHIRE_LOG_ALL, SAPPHIRE_LOG_LEVEL_ERROR);
304        SapphireSetLogLevel(SAPPHIRE_LOG_METADATA_STORE, SAPPHIRE_LOG_LEVEL_DEBUG);
305       
306        [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(distributedRescanDir:) name:RESCAN_DIRECTORY_NOTIFICATION object:nil];
307       
308        return self;
309}
310
311- (void)dealloc
312{
313        [leoOnly release];
314        [names release];
315        [controllers release];
316        [masterNames release];
317        [masterControllers release];
318        [moc release];
319        [SapphireSettings relinquishSettings];
320        [settings release];
321        [SapphireImportHelper relinquishHelper];
322        [[NSDistributedNotificationCenter defaultCenter] removeObserver:self];
323        [super dealloc];
324}
325
326- (void)recreateMenu
327{
328        names = [[NSMutableArray alloc] init];
329        controllers = [[NSMutableArray alloc] init];
330        if(mountsOnly)
331        {
332                masterNames = [[NSArray alloc] init];
333                masterControllers = [[NSArray alloc] init];
334        }
335        else
336        {
337                SapphireImporterDataMenu *allImporter   = [self allImporter];
338                NSMutableArray *mutableMasterNames = [[NSMutableArray alloc] init];
339                NSMutableArray *mutableMasterControllers = [[NSMutableArray alloc] init];
340               
341                SapphireBrowser *tvBrowser = [self tvBrowser];
342                [mutableMasterNames addObject:BRLocalizedString(@"  TV Shows", nil)];
343                [mutableMasterControllers addObject:tvBrowser];
344               
345                SapphireBrowser *movieBrowser = [self movieBrowser];
346                [mutableMasterNames addObject:BRLocalizedString(@"  Movies", nil)];
347                [mutableMasterControllers addObject:movieBrowser];
348               
349                [mutableMasterNames addObjectsFromArray:[NSArray arrayWithObjects:
350                                                                                                 ALL_IMPORT_MENU_ITEM,
351                                                                                                 SETTINGS_MENU_ITEM,
352                                                                                                 RESET_MENU_ITEM,
353                                                                                                 nil]];
354                [mutableMasterControllers addObjectsFromArray:[NSArray arrayWithObjects:
355                                                                                                           allImporter,
356                                                                                                           settings,
357                                                                                                           nil]];
358                masterNames = [[NSArray alloc] initWithArray:mutableMasterNames];
359                masterControllers = [[NSArray alloc] initWithArray:mutableMasterControllers];
360                [mutableMasterNames release];
361                [mutableMasterControllers release];             
362        }
363        [self setMenuFromSettings];
364}
365
366NSArray *showEntityFetch(NSManagedObjectContext *moc, NSPredicate *filterPredicate)
367{
368        NSPredicate *fetchPredicate = [NSPredicate predicateWithFormat:@"tvEpisode != nil"];
369        NSPredicate *finalPred;
370        if(filterPredicate == nil)
371                finalPred = fetchPredicate;
372        else
373                finalPred = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:filterPredicate, fetchPredicate, nil]];
374        NSArray *files = doFetchRequest(SapphireFileMetaDataName, moc, finalPred);
375
376        NSSet *epIds = [NSSet setWithArray:[files valueForKeyPath:@"tvEpisode.objectID"]];
377        NSPredicate *epPred = [NSPredicate predicateWithFormat:@"SELF IN %@", epIds];
378        NSArray *episodes = doFetchRequest(SapphireEpisodeName, moc, epPred);
379
380        NSSet *showIds = [NSSet setWithArray:[episodes valueForKeyPath:@"tvShow.objectID"]];
381        NSPredicate *showPred = [NSPredicate predicateWithFormat:@"SELF IN %@", showIds];
382
383        return doFetchRequest(SapphireTVShowName, moc, showPred);
384}
385
386- (SapphireBrowser *)tvBrowser
387{
388        BRTexture *predicateGem = [SapphireApplianceController gemForPredicate:[SapphireApplianceController predicate]];
389        SapphireEntityDirectory *tvDir = [[SapphireEntityDirectory alloc] initWithEntityFetch:showEntityFetch inContext:moc];
390        [tvDir setMetaFileFetchPredicate:[NSPredicate predicateWithFormat:@"tvEpisode != nil"]];
391        SapphireBrowser *tvBrowser = [[SapphireBrowser alloc] initWithScene:[self scene] metaData:tvDir];
392        [tvDir release];
393        [tvBrowser setListTitle:BRLocalizedString(@" TV Shows", nil)];
394        [tvBrowser setListIcon:predicateGem];
395        return [tvBrowser autorelease];
396}
397
398- (SapphireBrowser *)movieBrowser
399{
400        BRTexture *predicateGem = [SapphireApplianceController gemForPredicate:[SapphireApplianceController predicate]];
401        SapphireMovieDirectory *movieDir = [[SapphireMovieDirectory alloc] initWithContext:moc];
402        SapphireBrowser *movieBrowser = [[SapphireBrowser alloc] initWithScene:[self scene] metaData:movieDir];
403        [movieDir release];
404        [movieBrowser setListTitle:BRLocalizedString(@" Movies", nil)];
405        [movieBrowser setListIcon:predicateGem];
406        return [movieBrowser autorelease];     
407}
408
409- (void)setToMountsOnly
410{
411        [self setListTitle:BRLocalizedString(@"Collections", @"")];
412        mountsOnly = YES;
413}
414
415- (SapphireImporterDataMenu *)allImporter
416{
417        SapphireXMLFileDataImporter *xmlImpr = [[SapphireXMLFileDataImporter alloc] init];
418        SapphireFileDataImporter *fileImp = [[SapphireFileDataImporter alloc] init];
419        SapphireTVShowImporter *tvImp = [[SapphireTVShowImporter alloc] initWithContext:moc];
420        SapphireMovieImporter *movImp = [[SapphireMovieImporter alloc] initWithContext:moc];
421        SapphireAllImporter *allImp = [[SapphireAllImporter alloc] initWithImporters:[NSArray arrayWithObjects:xmlImpr,tvImp,movImp,fileImp,nil]];
422        [xmlImpr release];
423        [fileImp release];
424        [tvImp release];
425        [movImp release];
426        SapphireImporterDataMenu *ret = [[SapphireImporterDataMenu alloc] initWithScene:[self scene] context:moc importer:allImp];
427        [allImp release];
428        return [ret autorelease];
429}
430
431- (SapphireSettings *)settings
432{
433        return settings;
434}
435
436- (void)setMenuFromSettings
437{
438        [names removeAllObjects];
439        [controllers removeAllObjects];
440        [names addObjectsFromArray:masterNames];
441        [controllers addObjectsFromArray:masterControllers];
442        NSMutableDictionary *dvds = [NSMutableDictionary dictionary];
443        NSEnumerator *dvdEnum = [[NSClassFromString(@"BRDiskArbHandler") mountedDVDs] objectEnumerator];
444        BRDiskInfo *dvdInfo;
445        while((dvdInfo = [dvdEnum nextObject]) != nil)
446        {
447                NSString *mountpoint = [dvdInfo mountpoint];
448                [dvds setObject:dvdInfo forKey:mountpoint];
449        }
450       
451        BRTexture *predicateGem = [SapphireApplianceController gemForPredicate:[SapphireApplianceController predicate]];
452        NSEnumerator *browserPointsEnum = [[SapphireCollectionDirectory availableCollectionDirectoriesInContext:moc] objectEnumerator];
453        SapphireCollectionDirectory *browserPoint = nil;
454        int index = 2;
455        if(mountsOnly)
456                index = 0;
457        while((browserPoint = [browserPointsEnum nextObject]) != nil)
458        {
459                if([browserPoint hiddenValue])
460                        continue;
461                id controller = nil;
462                if((dvdInfo = [dvds objectForKey:browserPoint]) != nil)
463                {
464                        BRDVDMediaAsset *asset = [BRDVDMediaAsset assetFromDiskInfo:dvdInfo];
465                        controller = [[SapphireDVDLoadingController alloc] initWithScene:[self scene] forAsset:asset];
466                        [controller retain];
467                }
468                else
469                {
470                        SapphireDirectoryMetaData *meta = [browserPoint directory];
471                        controller = [[SapphireBrowser alloc] initWithScene:[self scene] metaData:meta];
472                        [controller setListTitle:[NSString stringWithFormat:@" %@",[[meta path] lastPathComponent]]];
473                        [controller setListIcon:predicateGem];
474                }
475                if(controller != nil)
476                {
477                        [names insertObject:[NSString stringWithFormat:@"  %@", [[browserPoint directory] path]] atIndex:index];
478                        [controllers insertObject:controller atIndex:index];
479                        [controller release];
480                        index++;
481                }
482        }       
483       
484        if([settings disableUIQuit] && !mountsOnly)
485                [names removeLastObject];
486}
487
488- (void)distributedRescanDir:(NSNotification *)note
489{
490        id info = [note userInfo];
491        if(![info isKindOfClass:[NSString class]])
492                return;
493        NSString *dirPath = (NSString *)info;
494        if(![[NSFileManager defaultManager] isDirectory:dirPath])
495                return;
496       
497        SapphireDirectoryMetaData *dir = [SapphireDirectoryMetaData directoryWithPath:dirPath inContext:moc];
498        [dir reloadDirectoryContents];
499        [dir resumeImport];
500}
501
502- (void)doInitialPush
503{
504    // We've just been put on screen, the user can see this controller's content now
505    [self recreateMenu];
506        [[self list] reload];
507    // always call super
508    [super doInitialPush];
509}
510
511- (void)doInitialExhume
512{
513    // handle being revealed when the user presses Menu
514   
515        [self setMenuFromSettings];
516        [[self list] reload];
517        [SapphireFrontRowCompat renderScene:[self scene]];
518
519    // always call super
520    [super doInitialExhume];
521}
522
523- (long) itemCount
524{
525    // return the number of items in your menu list here
526        return ( [ names count]);
527}
528
529- (id<BRMenuItemLayer>) itemForRow: (long) row
530{
531/*
532    // build a BRTextMenuItemLayer or a BRAdornedMenuItemLayer, etc. here
533    // return that object, it will be used to display the list item.
534*/
535        if( row > [names count] ) return ( nil ) ;
536       
537        BRAdornedMenuItemLayer * result = nil ;
538        NSString *name = [names objectAtIndex:row];
539        result = [SapphireFrontRowCompat textMenuItemForScene:[self scene] folder:YES];
540       
541        SapphireTheme *theme = [SapphireTheme sharedTheme];
542        if([name isEqual: ALL_IMPORT_MENU_ITEM]) [SapphireFrontRowCompat setLeftIcon:[theme gem:IMPORT_GEM_KEY] forMenu:result];
543        else if([name isEqual: SETTINGS_MENU_ITEM]) [SapphireFrontRowCompat setLeftIcon:[theme gem:GEAR_GEM_KEY] forMenu:result];
544        else if([name isEqual: RESET_MENU_ITEM]) [SapphireFrontRowCompat setLeftIcon:[theme gem:FRONTROW_GEM_KEY] forMenu:result];
545        else if([name isEqual: @"  TV Shows"]) [SapphireFrontRowCompat setLeftIcon:[theme gem:TV_GEM_KEY] forMenu:result];
546        else if([name isEqual: @"  Movies"]) [SapphireFrontRowCompat setLeftIcon:[theme gem:MOV_GEM_KEY] forMenu:result];
547        else [SapphireFrontRowCompat setLeftIcon:[SapphireApplianceController gemForPredicate:[SapphireApplianceController predicate]] forMenu:result];
548       
549        // add text
550        [SapphireFrontRowCompat setTitle:name forMenu:result];
551                               
552        return ( result ) ;
553}
554
555- (NSString *) titleForRow: (long) row
556{
557
558        if ( row > [ names count] ) return ( nil );
559       
560        NSString *result = [ names objectAtIndex: row] ;
561        return ( result ) ;
562/*
563    // return the title for the list item at the given index here
564    return ( @"Sapphire" );
565*/
566}
567
568- (long) rowForTitle: (NSString *) title
569{
570    long result = -1;
571    long i, count = [self itemCount];
572    for ( i = 0; i < count; i++ )
573    {
574        if ( [title isEqualToString: [self titleForRow: i]] )
575        {
576            result = i;
577            break;
578        }
579    }
580   
581    return ( result );
582}
583
584- (void) itemSelected: (long) row
585{
586    // This is called when the user presses play/pause on a list item
587        if(row == [controllers count])
588                [[NSApplication sharedApplication] terminate:self];
589        id controller = [controllers objectAtIndex:row];
590       
591        // This if statement needs to be done in a much more elegant way
592        [[self stack] pushController:controller];
593}
594
595- (id<BRMediaPreviewController>) previewControlForItem:(long)item
596{
597        return [self previewControllerForItem:item];
598}
599
600- (id<BRMediaPreviewController>) previewControllerForItem: (long) item
601{
602    // If subclassing BRMediaMenuController, this function is called when the selection cursor
603    // passes over an item.
604    return ( nil );
605}
606
607@end
Note: See TracBrowser for help on using the repository browser.