source: trunk/SapphireFrappliance/Settings/SapphireSettings.m @ 1345

Revision 1345, 31.6 KB checked in by gbooker, 4 years ago (diff)

Made computed auto sort paths into a set, and ask about each item in the set.

Line 
1/*
2 * SapphireSettings.m
3 * Sapphire
4 *
5 * Created by pnmerrill on Jun. 23, 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
22#import <BackRow/BackRow.h>
23#include <unistd.h>
24#import "SapphireApplianceController.h"
25#import "SapphireSettings.h"
26#import "SapphireTheme.h"
27#import "SapphireMediaPreview.h"
28#import "SapphireAllFileDataImporter.h"
29#import "SapphireTVShowImporter.h"
30#import "SapphireMovieImporter.h"
31#import "SapphirePosterChooser.h"
32#import "SapphireCollectionSettings.h"
33#import "SapphireFileMetaData.h"
34#import "SapphireCollectionDirectory.h"
35#import "SapphireDirectoryMetaData.h"
36#import "SapphireMetaDataSupport.h"
37#import "SapphireTVShow.h"
38#import "SapphireConfirmPrompt.h"
39#import "CoreDataSupportFunctions.h"
40#import "SapphireErrorDisplayController.h"
41#import "SapphireWaitDisplay.h"
42
43#import <SapphireCompatClasses/SapphireFrontRowCompat.h>
44#import "NSString-Extensions.h"
45#import "NSFileManager-Extensions.h"
46
47static SapphireSettings *sharedInstance = nil;
48
49@implementation SapphireSettings
50
51NSString *SettingHideFavorite           = @"HideFavorites";
52NSString *SettingHideTopShows           = @"HideTopShows";
53NSString *SettingHideUnwatched          = @"HideUnwatched";
54NSString *SettingHideSpoilers           = @"HideSpoilers";
55NSString *SettingHideAudio                      = @"HideAudio";
56NSString *SettingHideVideo                      = @"HideVideo";
57NSString *SettingHidePosterChooser      = @"PosterChooserOptOut";
58NSString *SettingHideUIQuit                     = @"HideUIQuit";
59NSString *SettingEnableFastSwitch       = @"EnableFastSwitching";
60NSString *SettingAC3Passthrough         = @"EnableAC3Passthrough";
61NSString *SettingDirLookup                      = @"EnableDirLookup";
62NSString *SettingEnableAutoSelect       = @"EnableAutoSelection";
63NSString *SettingDisableAnonReport      = @"DisableAnonymousReporting";
64NSString *SettingLastPredicate          = @"LastPredicate";
65
66NSString *SettingLogGeneralLevel        = @"GeneralLogLevel";
67NSString *SettingLogImportLevel         = @"ImportLogLevel";
68NSString *SettingLogFileLevel           = @"FileLogLevel";
69NSString *SettingLogPlaybackLevel       = @"PlaybackLogLevel";
70NSString *SettingLogMetadataLevel       = @"MetadataLogLevel";
71
72NSString *SettingListName                       = @"Name";
73NSString *SettingListDescription        = @"Description";
74NSString *SettingListKey                        = @"Key";
75NSString *SettingListGem                        = @"Gem";
76NSString *SettingListCommand            = @"Command";
77
78typedef enum {
79        SettingsCommandNone,
80        SettingsCommandImportFileData,
81        SettingsCommandImportTVData,
82        SettingsCommandImportMovieData,
83        SettingsCommandImportTVAutosortCalculate,
84        SettingsCommandImportUpdateScrapers,
85        SettingsCommandImportHidePosterChooser,
86        SettingsCommandImportUseDirName,
87        SettingsCommandImportHideAllChoosers,
88       
89        SettingsCommandCollectionsHide,
90        SettingsCommandCollectionsDontImport,
91        SettingsCommandCollectionsDelete,
92       
93        SettingsCommandFiltersSkipFavorite,
94        SettingsCommandFiltersSkipUnwatched,
95       
96        SettingsCommandMetadataHideSpoilers,
97        SettingsCommandMetadataHideAudio,
98        SettingsCommandMetadataHideVideo,
99       
100        SettingsCommandAudioEnableAC3,
101       
102        SettingsCommandGeneralHideUIQuit,
103        SettingsCommandGeneralFastDirectorySwitching,
104        SettingsCommandGeneralDontAnonReport,
105} SettingsCommand;
106
107+ (SapphireSettings *)sharedSettings
108{
109        return sharedInstance;
110}
111
112+ (void)relinquishSettings
113{
114        [sharedInstance release];
115        sharedInstance = nil;
116}
117
118- (id) initWithScene: (BRRenderScene *) scene settingsPath:(NSString *)dictionaryPath context:(NSManagedObjectContext *)context;
119{
120        if(sharedInstance != nil)
121        {
122                [self autorelease];
123                return [sharedInstance retain];
124        }
125       
126        self = [super initWithScene:scene];
127       
128        lastCommand = SettingsCommandNone;
129        /*Setup display*/
130        moc = [context retain];
131       
132        SapphireTheme *theme = [SapphireTheme sharedTheme];
133        settings = [[NSArray alloc] initWithObjects:
134                [NSDictionary dictionaryWithObjectsAndKeys:
135                        BRLocalizedString(@"  Populate File Data", @"Populate File Data menu item"), SettingListName,
136                        BRLocalizedString(@"Tells Sapphire to examine all files, and remember the file size, length and other information that can be gathered from the file itself.", @"Populate File Data description"), SettingListDescription,
137                        [theme gem:IMPORT_GEM_KEY], SettingListGem,
138                        [NSNumber numberWithInt:SettingsCommandImportFileData], SettingListCommand,
139                        nil],
140                [NSDictionary dictionaryWithObjectsAndKeys:
141                        BRLocalizedString(@"  Fetch TV Show Data", @"Fetch TV Show Data menu item"), SettingListName,
142                        BRLocalizedString(@"Tells Sapphire that for every TV episode, gather more information about this episode from the internet.", @"Fetch TV Show Data description"), SettingListDescription,
143                        [theme gem:TVR_GEM_KEY], SettingListGem,
144                        [NSNumber numberWithInt:SettingsCommandImportTVData], SettingListCommand,
145                        nil],
146                [NSDictionary dictionaryWithObjectsAndKeys:
147                        BRLocalizedString(@"  Fetch Movie Data", @"Fetch Movie Data menu item"), SettingListName,
148                        BRLocalizedString(@"Tells Sapphire that for every Movie, gather more information from the internet.", @"Fetch Movie Data description"), SettingListDescription,
149                        [theme gem:IMDB_GEM_KEY], SettingListGem,
150                        [NSNumber numberWithInt:SettingsCommandImportMovieData], SettingListCommand,
151                        nil],
152                [NSDictionary dictionaryWithObjectsAndKeys:
153                        BRLocalizedString(@"  Calculate TV Directories", @"Calculate TV Dirs menu item"), SettingListName,
154                        BRLocalizedString(@"Tells Sapphire to calculate directories where each TV show is stored.", @"Calculate TV Dirs description"), SettingListDescription,
155                        [theme gem:TVR_GEM_KEY], SettingListGem,
156                        [NSNumber numberWithInt:SettingsCommandImportTVAutosortCalculate], SettingListCommand,
157                        nil],
158                [NSDictionary dictionaryWithObjectsAndKeys:
159                        BRLocalizedString(@"  Update Scrapers", @"Update Scrapers menu item"), SettingListName,
160                        BRLocalizedString(@"Tells Sapphire to download latest scrapers from the website.", @"Update Scrapers description"), SettingListDescription,
161                        [theme gem:CONE_GEM_KEY], SettingListGem,
162                        [NSNumber numberWithInt:SettingsCommandImportUpdateScrapers], SettingListCommand,
163                        nil],
164/*              [NSDictionary dictionaryWithObjectsAndKeys:
165                        BRLocalizedString(@"  Choose Movie Posters", @"Start Poster Chooser menu item"), SettingListName,
166                        BRLocalizedString(@"Choose Movie Posters", @"Start Poster Chooser description"), SettingListDescription,
167                        [theme gem:GREEN_GEM_KEY], SettingListGem,
168                        [NSNumber numberWithInt:COMMAND_IMPORT_MOVIE_POSTERS], SettingListCommand,
169                        nil],*/
170                [NSDictionary dictionaryWithObjectsAndKeys:
171                        BRLocalizedString(@"  Hide Collections", @"Hide Collections menu item"), SettingListName,
172                        BRLocalizedString(@"Allows the user to specify which collections should be hidden from Sapphire's main menu.", @"Hide Collections description"), SettingListDescription,
173                        [theme gem:FILE_GEM_KEY], SettingListGem,
174                        [NSNumber numberWithInt:SettingsCommandCollectionsHide], SettingListCommand,
175                        nil],
176                [NSDictionary dictionaryWithObjectsAndKeys:
177                        BRLocalizedString(@"  Don't Import Collections", @"Don't Import Collections menu item"), SettingListName,
178                        BRLocalizedString(@"Allows the user to specify which collections should be skipped when importing meta data.", @"Don't Import Collections description"), SettingListDescription,
179                        [theme gem:FILE_GEM_KEY], SettingListGem,
180                        [NSNumber numberWithInt:SettingsCommandCollectionsDontImport], SettingListCommand,
181                        nil],
182                [NSDictionary dictionaryWithObjectsAndKeys:
183                        BRLocalizedString(@"  Delete Collections", @"Delete Collections menu item"), SettingListName,
184                        BRLocalizedString(@"Allows the user to specify which collections should be delete along with its data.  Use this for collections which will never be used again.", @"Delete Collections description"), SettingListDescription,
185                        [theme gem:FILE_GEM_KEY], SettingListGem,
186                        [NSNumber numberWithInt:SettingsCommandCollectionsDelete], SettingListCommand,
187                        nil],
188                [NSDictionary dictionaryWithObjectsAndKeys:
189                        BRLocalizedString(@"  Skip \"Favorite Shows\" filter", @"Skip Favorite shows menu item"), SettingListName,
190                        BRLocalizedString(@"Tells Sapphire that when changing filter settings, skip over the favorite shows filter.", @"Skip Favorite shows description"), SettingListDescription,
191                        SettingHideFavorite, SettingListKey,
192                        [theme gem:YELLOW_GEM_KEY], SettingListGem,
193                        [NSNumber numberWithInt:SettingsCommandFiltersSkipFavorite], SettingListCommand,
194                        nil],
195/*              [NSDictionary dictionaryWithObjectsAndKeys:
196                        BRLocalizedString(@"  Skip \"Top Shows\" filter", @"Skip Top shows menu item"), SettingListName,
197                        BRLocalizedString(@"Skip \"Top Shows\" filter", @"Skip Top shows description"), SettingListDescription,
198                        SettingHideTopShows, SettingListKey,
199                        [theme gem:GREEN_GEM_KEY], SettingListGem,
200                        [NSNumber numberWithInt:COMMAND_FILTERS_SKIP_TOP_SHOWS], SettingListCommand,
201                        nil],*/
202                [NSDictionary dictionaryWithObjectsAndKeys:
203                        BRLocalizedString(@"  Skip \"Unwatched Shows\" filter", @"Skip Unwatched shows menu item"), SettingListName,
204                        BRLocalizedString(@"Tells Sapphire that when changing filter settings, skip over the unwatched shows filter.", @"Skip Unwatched shows description"),  SettingListDescription,
205                        SettingHideUnwatched, SettingListKey,
206                        [theme gem:BLUE_GEM_KEY], SettingListGem,
207                        [NSNumber numberWithInt:SettingsCommandFiltersSkipUnwatched], SettingListCommand,
208                        nil],
209                [NSDictionary dictionaryWithObjectsAndKeys:
210                        BRLocalizedString(@"  Hide Show Spoilers", @"Hide show summary menu item"), SettingListName,
211                        BRLocalizedString(@"Tells Sapphire to disable the display of the show's synopsis.", @"Hide show summary description"), SettingListDescription,
212                        SettingHideSpoilers, SettingListKey,
213                        [theme gem:NOTE_GEM_KEY], SettingListGem,
214                        [NSNumber numberWithInt:SettingsCommandMetadataHideSpoilers], SettingListCommand,
215                        nil],
216                [NSDictionary dictionaryWithObjectsAndKeys:
217                        BRLocalizedString(@"  Hide Audio Info", @"Hide perian audio info menu item"), SettingListName,
218                        BRLocalizedString(@"Tells Sapphire to disable the display of audio codec and sample rate information.", @"Hide perian audio info description"), SettingListDescription,
219                        SettingHideAudio, SettingListKey,
220                        [theme gem:AUDIO_GEM_KEY], SettingListGem,
221                        [NSNumber numberWithInt:SettingsCommandMetadataHideAudio], SettingListCommand,
222                        nil],
223                [NSDictionary dictionaryWithObjectsAndKeys:
224                        BRLocalizedString(@"  Hide Video Info", @"Hide perian video info menu item"), SettingListName,
225                        BRLocalizedString(@"Tells Sapphire to disable the display of video codec, resolution, and color depth information.", @"Hide perian video info description"), SettingListDescription,
226                        SettingHideVideo, SettingListKey,
227                        [theme gem:VIDEO_GEM_KEY], SettingListGem,
228                        [NSNumber numberWithInt:SettingsCommandMetadataHideVideo], SettingListCommand,
229                        nil],
230                [NSDictionary dictionaryWithObjectsAndKeys:
231                        BRLocalizedString(@"  Hide Poster Chooser", @"Hide poster chooser menu item"), SettingListName,
232                        BRLocalizedString(@"Tells Sapphire to automatically choose posters for movies instead of asking the user to choose one.", @"Hide poster chooser description"), SettingListDescription,
233                        SettingHidePosterChooser, SettingListKey,
234                        [theme gem:IMPORT_GEM_KEY], SettingListGem,
235                        [NSNumber numberWithInt:SettingsCommandImportHidePosterChooser], SettingListCommand,
236                        nil],
237                [NSDictionary dictionaryWithObjectsAndKeys:
238                        BRLocalizedString(@"  Hide UI Quit", @"Hide the ui quitter menu item"), SettingListName,
239                        BRLocalizedString(@"Tells Sapphire to hide the main menu element forcing FrontRow to quit.", @"Hide the ui quitter description"), SettingListDescription,
240                        SettingHideUIQuit, SettingListKey,
241                        [theme gem:FRONTROW_GEM_KEY], SettingListGem,
242                        [NSNumber numberWithInt:SettingsCommandGeneralHideUIQuit], SettingListCommand,
243                        nil],
244                [NSDictionary dictionaryWithObjectsAndKeys:
245                        BRLocalizedString(@"  Fast Directory Switching", @"Don't rescan directories upon entry and used cached data"), SettingListName,
246                        BRLocalizedString(@"Tells Sapphire that when using a filter, use the cached data to setup directories rather than scanning the directories themselves for new files.", @"Fast Directory Switching description"), SettingListDescription,
247                        SettingEnableFastSwitch, SettingListKey,
248                        [theme gem:FAST_GEM_KEY], SettingListGem,
249                        [NSNumber numberWithInt:SettingsCommandGeneralFastDirectorySwitching], SettingListCommand,
250                        nil],
251                [NSDictionary dictionaryWithObjectsAndKeys:
252                        BRLocalizedString(@"  Enable AC3 Passthrough", @"Enable AC3 Passthrough menu item"), SettingListName,
253                        BRLocalizedString(@"Tells Sapphire that you have an AC3 decoder and to enable passthrough of the full audio information to the decoder. This is how you get 5.1 and DTS output.", @"Enable AC3 Passthrough description"), SettingListDescription,
254                        SettingAC3Passthrough, SettingListKey,
255                        [theme gem:AC3_GEM_KEY], SettingListGem,
256                        [NSNumber numberWithInt:SettingsCommandAudioEnableAC3], SettingListCommand,
257                        nil],
258                [NSDictionary dictionaryWithObjectsAndKeys:
259                        BRLocalizedString(@"  Use Directory Lookup", @"Use directory names instead of filenames for movie lookup"), SettingListName,
260                        BRLocalizedString(@"Tells Sapphire that you want to use directory names instead of file names for identifying movies.", @"Enable Directory lookup description"), SettingListDescription,
261                        SettingDirLookup, SettingListKey,
262                        [theme gem:IMDB_GEM_KEY], SettingListGem,
263                        [NSNumber numberWithInt:SettingsCommandImportUseDirName], SettingListCommand,
264                        nil],
265                [NSDictionary dictionaryWithObjectsAndKeys:
266                        BRLocalizedString(@"  Auto-Select Movies/Shows", @"Hide movie/show chooser menu item"), SettingListName,
267                        BRLocalizedString(@"Tells Sapphire skip the TV Show and Movie choosers when importing and make selections automatically.", @"Enable movie/show chooser description"), SettingListDescription,
268                        SettingEnableAutoSelect, SettingListKey,
269                        [theme gem:IMPORT_GEM_KEY], SettingListGem,
270                        [NSNumber numberWithInt:SettingsCommandImportHideAllChoosers], SettingListCommand,
271                        nil],
272                [NSDictionary dictionaryWithObjectsAndKeys:
273                        BRLocalizedString(@"  Disable Anonymous Reporting", @"Disable the anonymous reporting for aid in future features"), SettingListName,
274                        BRLocalizedString(@"Tells Sapphire to not report any anonymous information on how you use Sapphire. Anonymous reporting enables us to improve the plugin for future use.", @"Disable the anonymous reporting description"), SettingListDescription,
275                        SettingDisableAnonReport, SettingListKey,
276                        [theme gem:REPORT_GEM_KEY], SettingListGem,
277                        [NSNumber numberWithInt:SettingsCommandGeneralDontAnonReport], SettingListCommand,
278                        nil],
279                nil];
280       
281        path = [dictionaryPath retain];
282        options = [[NSDictionary dictionaryWithContentsOfFile:dictionaryPath] mutableCopy];
283        /*Set deaults*/
284        defaults = [[NSDictionary alloc] initWithObjectsAndKeys:
285                [NSNumber numberWithBool:NO], SettingHideFavorite,
286                [NSNumber numberWithBool:YES], SettingHideTopShows,
287                [NSNumber numberWithBool:NO], SettingHideUnwatched,
288                [NSNumber numberWithBool:NO], SettingHideSpoilers,
289                [NSNumber numberWithBool:NO], SettingHideAudio,
290                [NSNumber numberWithBool:NO], SettingHideVideo,
291                [NSNumber numberWithBool:NO], SettingHidePosterChooser,
292                [NSNumber numberWithBool:YES], SettingHideUIQuit,
293                [NSNumber numberWithBool:YES], SettingEnableFastSwitch,
294                [NSNumber numberWithBool:NO], SettingAC3Passthrough,
295                [NSNumber numberWithBool:NO], SettingDirLookup,
296                [NSNumber numberWithBool:NO], SettingEnableAutoSelect,
297                [NSNumber numberWithBool:NO], SettingDisableAnonReport,
298                [NSNumber numberWithInt:NSNotFound], SettingLastPredicate,
299                [NSNumber numberWithInt:SapphireLogLevelError], SettingLogGeneralLevel,
300                [NSNumber numberWithInt:SapphireLogLevelError], SettingLogImportLevel,
301                [NSNumber numberWithInt:SapphireLogLevelError], SettingLogFileLevel,
302                [NSNumber numberWithInt:SapphireLogLevelError], SettingLogPlaybackLevel,
303                [NSNumber numberWithInt:SapphireLogLevelError], SettingLogMetadataLevel,
304                nil];
305        if(options == nil)
306                options = [[NSMutableDictionary alloc] init];
307
308        /*display*/
309        BRListControl *list = [self list];
310        [list setDatasource:self];
311        [SapphireFrontRowCompat addDividerAtIndex:8 toList:list];
312        /*Save our instance*/
313        sharedInstance = [self retain];
314
315        return self;
316}
317
318/*!
319 * @brief Writes settings to disk
320 */
321- (void)writeSettings
322{
323        [options writeToFile:path atomically:YES];
324}
325
326- (void)dealloc
327{
328        [settings release];
329        [options release];
330        [path release];
331        [defaults release];
332        [moc release];
333        [displayOnlyPlot release];
334        [super dealloc];
335}
336
337/*!
338 * @brief Get a setting
339 *
340 * @param key The setting to retrieve
341 * @return The setting in an NSNumber
342 */
343- (NSNumber *)numberForKey:(NSString *)key
344{
345        /*Check the user's setting*/
346        NSNumber *num = [options objectForKey:key];
347        if(!num)
348                /*User hasn't set yet, use default then*/
349                num = [defaults objectForKey:key];
350        return num;
351}
352
353/*!
354 * @brief Get a setting
355 *
356 * @param key The setting to retrieve
357 * @return YES if set, NO otherwise
358 */
359- (BOOL)boolForKey:(NSString *)key
360{
361        /*Check the user's setting*/
362        NSNumber *num = [options objectForKey:key];
363        if(!num)
364                /*User hasn't set yet, use default then*/
365                num = [defaults objectForKey:key];
366        return [num boolValue];
367}
368
369- (SapphireLogLevel)logLevelForKey:(NSString *)key
370{
371        /*Check the user's setting*/
372        NSNumber *num = [options objectForKey:key];
373        SapphireLogLevel value = [num intValue];
374        if(num != nil && value > 0 && value < SapphireLogLevelCount)
375                return value;
376        return [[defaults objectForKey:key] intValue];
377}
378
379- (BOOL)displayUnwatched
380{
381        return ![self boolForKey:SettingHideUnwatched];
382}
383
384- (BOOL)displayFavorites
385{
386        return ![self boolForKey:SettingHideFavorite];
387}
388
389- (BOOL)displayTopShows
390{
391        return ![self boolForKey:SettingHideTopShows];
392}
393
394- (BOOL)displaySpoilers
395{
396        return ![self boolForKey:SettingHideSpoilers];
397}
398
399- (BOOL)displayAudio
400{
401        return ![self boolForKey:SettingHideAudio];
402}
403
404- (BOOL)displayVideo
405{
406        return ![self boolForKey:SettingHideVideo];
407}
408
409- (BOOL)displayPosterChooser
410{
411        return ![self boolForKey:SettingHidePosterChooser];
412}
413
414- (BOOL)disableUIQuit
415{
416        return [self boolForKey:SettingHideUIQuit];
417}
418
419- (BOOL)disableAnonymousReporting;
420{
421        return [self boolForKey:SettingDisableAnonReport];
422}
423
424- (BOOL)useAC3Passthrough
425{
426        return [self boolForKey:SettingAC3Passthrough];
427}
428
429- (BOOL)fastSwitching
430{
431        return [self boolForKey:SettingEnableFastSwitch];
432
433}
434
435- (BOOL)dirLookup
436{
437        return [self boolForKey:SettingDirLookup];
438}
439
440- (BOOL)autoSelection
441{
442        return [self boolForKey:SettingEnableAutoSelect];
443}
444
445- (int)indexOfLastPredicate
446{
447        return [[self numberForKey:SettingLastPredicate] intValue];
448}
449
450- (void)setIndexOfLastPredicate:(int)index
451{
452        [options setObject:[NSNumber numberWithInt:index] forKey:SettingLastPredicate];
453        /*Save our settings*/
454        [self writeSettings];
455}
456
457- (void)setDisplayOnlyPlotUntil:(NSDate *)plotOnlyTime
458{
459        [displayOnlyPlot release];
460        displayOnlyPlot = [plotOnlyTime retain];
461}
462
463- (BOOL)displayOnlyPlot
464{
465        return [displayOnlyPlot compare:[NSDate date]] == NSOrderedDescending;
466}
467
468- (SapphireLogLevel)generalLogLevel
469{
470        return [self logLevelForKey:SettingLogGeneralLevel];
471}
472
473- (SapphireLogLevel)importLogLevel
474{
475        return [self logLevelForKey:SettingLogImportLevel];
476}
477
478- (SapphireLogLevel)fileLogLevel
479{
480        return [self logLevelForKey:SettingLogFileLevel];
481}
482
483- (SapphireLogLevel)playbackLogLevel
484{
485        return [self logLevelForKey:SettingLogPlaybackLevel];
486}
487
488- (SapphireLogLevel)metadataLogLevel
489{
490        return [self logLevelForKey:SettingLogMetadataLevel];
491}
492
493int checkPaths(NSString *autoPath, NSArray *computedPaths, int startIndex)
494{
495        int i, count = [computedPaths count];
496        for (i=startIndex; i<count; i++) {
497                if(![autoPath isEqualToString:[computedPaths objectAtIndex:i]])
498                        break;
499        }
500        return i;
501}
502
503- (SapphireConfirmPrompt *)nextAutoSortPathConfirm:(NSArray *)paths forShow:(SapphireTVShow *)show remaining:(NSArray *)remaining
504{
505        NSString *calcAutoPath = nil;
506        NSString *autoPath = [show autoSortPath];
507        if([paths count] > 0)
508        {
509                int skipCount = checkPaths(autoPath, paths, 1);  //We had just checked the first one, continue after that.
510                paths = [paths subarrayWithRange:NSMakeRange(skipCount, [paths count]-skipCount)];
511        }
512        if([paths count] != 0)
513                calcAutoPath = [paths objectAtIndex:0];
514        else
515        {
516                int i, count = [remaining count];
517                for(i=0; i<count; i++)
518                {
519                        show = [remaining objectAtIndex:i];
520                        autoPath = [show autoSortPath];
521                        paths = [[show calculateAutoSortPaths] allObjects];
522                        NSLog(@"Paths for %@ are %@", [show name], paths);
523                        if([paths count])
524                        {
525                                int skipCount = checkPaths(autoPath, paths, 0);
526                                if(skipCount > 0)
527                                        paths = [paths subarrayWithRange:NSMakeRange(skipCount, [paths count]-skipCount)];
528                        }
529                        if([paths count])
530                        {
531                                calcAutoPath = [paths objectAtIndex:0];
532                                break;
533                        }
534                }
535                if(i == count)
536                        return nil;
537                remaining = [remaining subarrayWithRange:NSMakeRange(i + 1, [remaining count] - i - 1)];
538        }
539       
540        NSInvocation *invoke = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(promptResult:forShow:paths:remaining:)]];
541        [invoke setTarget:self];
542        [invoke setSelector:@selector(promptResult:forShow:paths:remaining:)];
543        [invoke setArgument:&show atIndex:3];
544        [invoke setArgument:&paths atIndex:4];
545        [invoke setArgument:&remaining atIndex:5];
546        [invoke retainArguments];
547       
548        NSString *question;
549        if(calcAutoPath != nil)
550                question = [NSString stringWithFormat:BRLocalizedString(@"Do you want to set the show path for %@ to %@?", @"Prompt for setting a show's path, arguments are show name and path"), [show name], calcAutoPath];
551        else
552                question = [NSString stringWithFormat:BRLocalizedString(@"Do you want to delete the show path for %@?", @"Prompt for deleting a show's path, argument is show name"), [show name]];
553       
554        SapphireConfirmPrompt *prompt = [[SapphireConfirmPrompt alloc] initWithScene:[self scene] title:BRLocalizedString(@"Show Path", @"Show Path") subtitle:question invocation:invoke];
555        return [prompt autorelease];
556}
557
558- (BRLayerController *)promptResult:(SapphireConfirmPromptResult)result forShow:(SapphireTVShow *)show paths:(NSArray *)paths remaining:(NSArray *)remain
559{
560        if(result == SapphireConfirmPromptResultAbort)
561                return nil;
562       
563        if(result == SapphireConfirmPromptResultOK)
564        {
565                [show setAutoSortPath:[paths objectAtIndex:0]];
566                [SapphireMetaDataSupport save:moc];
567                return [self nextAutoSortPathConfirm:nil forShow:nil remaining:remain];
568        }
569       
570        return [self nextAutoSortPathConfirm:paths forShow:show remaining:remain];
571}
572
573- (BRLayerController *)waitForDownloads
574{
575        SapphireURLLoader *loader = [SapphireApplianceController urlLoader];
576        while([loader loadingURLCount] != 0)
577                usleep(100000);
578       
579        SapphireErrorDisplayController *error = [[SapphireErrorDisplayController alloc] initWithScene:[self scene] error:BRLocalizedString(@"Restart Needed", @"Restart Needed") longError:BRLocalizedString(@"You must exit Frontrow for new scrapers to take effect", @"You must exit Frontrow for new scrapers to take effect")];
580        return [error autorelease];
581}
582
583- (void)wasExhumed
584{
585    // handle being revealed when the user presses Menu
586       
587        if(lastCommand == SettingsCommandCollectionsDelete)
588        {
589                NSArray *collections = [SapphireCollectionDirectory allCollectionsInContext:moc];
590                NSEnumerator *colEnum = [collections objectEnumerator];
591                SapphireCollectionDirectory *collection;
592                BOOL change = NO;
593                while((collection = [colEnum nextObject]) != nil)
594                {
595                        if([collection deleteValue])
596                        {
597                                change = YES;
598                                SapphireDirectoryMetaData *dir = [collection directory];
599                                [moc deleteObject:dir];
600                        }
601                }
602                if(change)
603                        [SapphireMetaDataSupport save:moc];
604        }
605   
606    // always call super
607    [super wasExhumed];
608}
609
610- (long) itemCount
611{
612    // return the number of items in your menu list here
613        return [settings count];
614}
615
616- (id<BRMenuItemLayer>) itemForRow: (long) row
617{
618/*
619    // build a BRTextMenuItemLayer or a BRAdornedMenuItemLayer, etc. here
620    // return that object, it will be used to display the list item.
621    return ( nil );
622*/
623        if( row >= [settings count] ) return ( nil ) ;
624       
625        BRAdornedMenuItemLayer * result = nil;
626        NSDictionary *setting = [settings objectAtIndex:row];
627        NSString *name = [setting objectForKey:SettingListName];
628        result = [SapphireFrontRowCompat textMenuItemForScene:[self scene] folder:NO];
629
630        NSString *key = [setting objectForKey:SettingListKey];
631        if(key != nil && [self boolForKey:key])
632        {
633                [SapphireFrontRowCompat setLeftIcon:[SapphireFrontRowCompat selectedSettingImageForScene:[self scene]] forMenu:result];
634        }
635        [SapphireFrontRowCompat setRightIcon:[setting objectForKey:SettingListGem] forMenu:result];
636
637        // add text
638        [SapphireFrontRowCompat setTitle:name forMenu:result];
639                               
640        return result;
641}
642
643- (NSString *) titleForRow: (long) row
644{
645
646        if (row >= [settings count])
647                return nil;
648       
649        NSString *result = [[settings objectAtIndex:row] objectForKey:SettingListName];
650        return result;
651/*
652    // return the title for the list item at the given index here
653    return ( @"Sapphire" );
654*/
655}
656
657- (long) rowForTitle: (NSString *) title
658{
659    long result = -1;
660    long i, count = [self itemCount];
661    for ( i = 0; i < count; i++ )
662    {
663        if ( [title isEqualToString: [self titleForRow: i]] )
664        {
665            result = i;
666            break;
667        }
668    }
669   
670    return ( result );
671}
672
673- (void) itemSelected: (long) row
674{
675    // This is called when the user changed a setting
676        NSDictionary *setting = [settings objectAtIndex:row];
677
678        lastCommand = [[setting objectForKey:SettingListCommand] intValue];
679        switch (lastCommand) {
680                case SettingsCommandImportFileData:
681                {
682                        SapphireAllFileDataImporter *importer = [[SapphireAllFileDataImporter alloc] init];
683                        SapphireImporterDataMenu *menu = [[SapphireImporterDataMenu alloc] initWithScene:[self scene] context:moc importer:importer];
684                        [[self stack] pushController:menu];
685                        [menu release];
686                        [importer release];
687                        break;
688                }
689                case SettingsCommandImportTVData:
690                {
691                        SapphireTVShowImporter *importer = [[SapphireTVShowImporter alloc] init];
692                        SapphireImporterDataMenu *menu = [[SapphireImporterDataMenu alloc] initWithScene:[self scene] context:moc importer:importer];
693                        [[self stack] pushController:menu];
694                        [menu release];
695                        [importer release];
696                        break;
697                }
698                case SettingsCommandImportMovieData:
699                {
700                        SapphireMovieImporter *importer = [[SapphireMovieImporter alloc] init];
701                        SapphireImporterDataMenu *menu = [[SapphireImporterDataMenu alloc] initWithScene:[self scene] context:moc importer:importer];
702                        [[self stack] pushController:menu];
703                        [menu release];
704                        [importer release];
705                        break;
706                }
707                case SettingsCommandImportTVAutosortCalculate:
708                {
709                        NSArray *shows = doFetchRequest(SapphireTVShowName, moc, nil);
710                        SapphireConfirmPrompt *confirm = [self nextAutoSortPathConfirm:nil forShow:nil remaining:shows];
711                        if(confirm != nil)
712                                [[self stack] pushController:confirm];
713                        else
714                        {
715                                SapphireErrorDisplayController *error = [[SapphireErrorDisplayController alloc] initWithScene:[self scene] error:BRLocalizedString(@"No Changes", @"No Changes") longError:BRLocalizedString(@"Sapphire didn't detect any changes to show paths", @"Display info for no show path changes detected")];
716                                [[self stack] pushController:error];
717                                [error release];
718                        }
719                        break;
720                }
721                case SettingsCommandImportUpdateScrapers:
722                {
723                        SapphireURLLoader *loader = [SapphireApplianceController urlLoader];
724                        NSFileManager *fm = [NSFileManager defaultManager];
725                        [fm constructPath:[applicationSupportDir() stringByAppendingPathComponent:@"scrapers/common"]];
726                        NSArray *loads = [NSArray arrayWithObjects:@"tvrage.xml", @"imdb.xml", @"/common/dtrailer.xml", @"common/imdb.xml", @"common/impa.xml", @"common/movieposterdb.xml", @"common/tmdb.xml", nil];
727                        NSString *dest = [applicationSupportDir() stringByAppendingPathComponent:@"scrapers"];
728                        NSEnumerator *loadEnum = [loads objectEnumerator];
729                        NSString *load;
730                        while((load = [loadEnum nextObject]) != nil)
731                                [loader saveDataAtURL:[@"http://appletv.nanopi.net/svn/trunk/SapphireFrappliance/MetaDataImporting/Scrapers/" stringByAppendingString:load] toFile:[dest stringByAppendingPathComponent:load]];
732                        NSInvocation *invoke = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(waitForDownloads)]];
733                        [invoke setTarget:self];
734                        [invoke setSelector:@selector(waitForDownloads)];
735                        SapphireWaitDisplay *wait = [[SapphireWaitDisplay alloc] initWithScene:[self scene] title:BRLocalizedString(@"Downloading", @"Downloading") invocation:invoke];
736                        [[self stack] pushController:wait];
737                        [wait release];
738                        break;
739                }
740/*              case COMMAND_IMPORT_MOVIE_POSTERS:
741                {
742                        SapphirePosterBrowse *chooser = [[SapphirePosterChooser alloc] initWithScene:[self scene] metaDataPath:[[path stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"movieData.plist"]];
743                        [[self stack] pushController:chooser];
744                        [chooser release];
745                        break;
746                }*/
747                case SettingsCommandCollectionsHide:
748                {
749                        SapphireCollectionSettings *colSettings = [[SapphireCollectionSettings alloc] initWithScene:[self scene] context:moc];
750                        [colSettings setGettingSelector:@selector(hiddenValue)];
751                        [colSettings setSettingSelector:@selector(setHiddenValue:)];
752                        [colSettings setListTitle:BRLocalizedString(@"Hide Collections", @"Hide Collections Menu Title")] ;
753                        [[self stack] pushController:colSettings];
754                        [colSettings release];
755                        break;
756                }
757                case SettingsCommandCollectionsDontImport:
758                {
759                        SapphireCollectionSettings *colSettings = [[SapphireCollectionSettings alloc] initWithScene:[self scene] context:moc];
760                        [colSettings setGettingSelector:@selector(skipValue)];
761                        [colSettings setSettingSelector:@selector(setSkipValue:)];
762                        [colSettings setListTitle:BRLocalizedString(@"Skip Collections", @"Skip Collections Menu Title")] ;
763                        [[self stack] pushController:colSettings];
764                        [colSettings release];
765                        break;
766                }
767                case SettingsCommandCollectionsDelete:
768                {
769                        SapphireCollectionSettings *colSettings = [[SapphireCollectionSettings alloc] initWithScene:[self scene] context:moc];
770                        [colSettings setGettingSelector:@selector(deleteValue)];
771                        [colSettings setSettingSelector:@selector(setDeleteValue:)];
772                        [colSettings setListTitle:BRLocalizedString(@"Delete Collections", @"Delete Collections Menu Title")];
773                        [[self stack] pushController:colSettings];
774                        [colSettings release];
775                        break;
776                }
777                default:
778                {
779                        NSString *key = [setting objectForKey:SettingListKey];
780                        if(key == nil)
781                                break;
782                        BOOL setting = [self boolForKey:key];
783                        [options setObject:[NSNumber numberWithBool:!setting] forKey:key];
784                }
785        }
786
787        /*Save our settings*/
788        [self writeSettings];
789
790        /*Redraw*/
791        [[self list] reload] ;
792        [SapphireFrontRowCompat renderScene:[self scene]];
793
794}
795
796- (id<BRMediaPreviewController>) previewControlForItem: (long) row
797{
798        return [self previewControllerForItem:row];
799}
800
801- (id<BRMediaPreviewController>) previewControllerForItem: (long) item
802{
803        if(item >= [settings count])
804                return nil;
805       
806        NSDictionary *setting = [settings objectAtIndex:item];
807       
808        /* Get setting name & kill the gem cushion  */
809        NSString *settingName = [[setting objectForKey:SettingListName] substringFromIndex:2];
810        NSString *settingDescription=[setting objectForKey:SettingListDescription];
811        /* Construct a gerneric metadata asset for display */
812        NSMutableDictionary *settingMeta=[[NSMutableDictionary alloc] init];
813        [settingMeta setObject:settingName forKey:META_TITLE_KEY];
814        [settingMeta setObject:[NSNumber numberWithInt:FileClassUtility] forKey:FILE_CLASS_KEY];
815        [settingMeta setObject:settingDescription forKey:META_DESCRIPTION_KEY];
816        SapphireMediaPreview *preview = [[SapphireMediaPreview alloc] initWithScene:[self scene]];
817        [preview setUtilityData:settingMeta];
818        [settingMeta release];
819        [preview setShowsMetadataImmediately:YES];
820        /*And go*/
821        return [preview autorelease];
822}
823
824@end
825
Note: See TracBrowser for help on using the repository browser.