source: branches/CoreData/SapphireFrappliance/Browser/SapphireMarkMenu.m @ 670

Revision 670, 19.2 KB checked in by gbooker, 6 years ago (diff)

Added ability to reset decisions made on a file (means importer will have to ask again). Useful if you selected the wrong thing

Line 
1/*
2 * SapphireMarkMenu.m
3 * Sapphire
4 *
5 * Created by Graham Booker on Jun. 25, 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 "SapphireMarkMenu.h"
22#import "SapphireDirectoryMetaData.h"
23#import "SapphireCollectionDirectory.h"
24#import "SapphireFileMetaData.h"
25#import "SapphireJoinedFile.h"
26#import "SapphireMetaDataSupport.h"
27#import "SapphireMediaPreview.h"
28#import <SapphireCompatClasses/SapphireFrontRowCompat.h>
29#import <QTKit/QTKit.h>
30
31@implementation SapphireMarkMenu
32
33typedef enum {
34        COMMAND_TOGGLE_WATCHED,
35        COMMAND_TOGGLE_FAVORITE,
36        COMMAND_MARK_TO_REFETCH_TV,
37        COMMAND_MARK_TO_REFETCH_MOVIE,
38        COMMAND_MARK_TO_DELETE_METADATA,
39        COMMAND_MARK_TO_RESET_IMPORT,
40        //File Only Commands
41        COMMAND_MARK_TO_JOIN,
42        COMMAND_MARK_AND_JOIN,
43        COMMAND_CLEAR_JOIN_MARK,
44        COMMAND_JOIN,
45        //Directory Only Commands
46        COMMAND_MARK_WATCHED,
47        COMMAND_MARK_UNWATCHED,
48        COMMAND_MARK_FAVORITE,
49        COMMAND_MARK_NOT_FAVORITE,
50        COMMAND_TOGGLE_SKIP,
51        COMMAND_TOGGLE_COLLECTION
52} MarkCommand;
53
54static NSMutableArray *joinList;
55
56+ (void)initialize
57{
58        joinList = [[NSMutableArray alloc] init];
59}
60
61- (id) initWithScene: (BRRenderScene *) scene metaData: (SapphireMetaData *)meta
62{
63        self = [super initWithScene:scene];
64        if(!self)
65                return nil;
66       
67        /*Check to see if it is directory or file*/
68        isDir = [meta conformsToProtocol:@protocol(SapphireDirectory)];
69        metaData = [meta retain];
70        commands = nil;
71        /*Create the menu*/
72        if(isDir)
73        {
74                names = [[NSMutableArray alloc] initWithObjects:
75                        BRLocalizedString(@"Mark All as Watched", @"Mark whole directory as watched"),
76                        BRLocalizedString(@"Mark All as Unwatched", @"Mark whole directory as unwatched"),
77                        BRLocalizedString(@"Mark All as Favorite", @"Mark whole directory as favorite"),
78                        BRLocalizedString(@"Mark All as Not Favorite", @"Mark whole directory as not favorite"),
79                        BRLocalizedString(@"Mark All to Refetch TV Data", @"Mark whole directory to re-fetch its tv data"),
80                        BRLocalizedString(@"Mark All to Refetch Movie Data", @"Mark whole directory to re-fetch its movie data"),
81                        BRLocalizedString(@"Mark All to Clear Metadata", @"Mark whole directory to delete the metadata"),
82                        BRLocalizedString(@"Mark All to Reset Import Decisions", @"Mark whole directory to reset import decisions"),
83                        nil];
84                markDescriptions = [[NSMutableArray alloc] initWithObjects:
85                        BRLocalizedString(@"Sapphire will save this directory as watched.", @"Mark directory watched description"),
86                        BRLocalizedString(@"Sapphire will save this directory as unwatched.", @"Mark directory as unwatched description"),
87                        BRLocalizedString(@"Sapphire will add this directory as favorite.", @"Mark directory as favorite description"),
88                        BRLocalizedString(@"Sapphire will remove this directory from favorites.", @"Mark directory as not favorite"),
89                        BRLocalizedString(@"Tells Sapphire to refetch TV Show metadata for this directory the next time an import is run.", @"Mark directory to refetch tv data description"),
90                        BRLocalizedString(@"Tells Sapphire to refetch Movie metadata for this directory the next time an import is run.", @"Mark whole directory to re-fetch its movie data"),
91                        BRLocalizedString(@"Tells Sapphire to remove all metadata for this directory.", @"Mark directory to delete metadata description"),
92                        BRLocalizedString(@"Tells Sapphire to forget import decisions made on files in this directory.", @"Mark directory to reset import decisions description"),
93                        nil];
94                commands = [[NSMutableArray alloc] initWithObjects:
95                                        [NSNumber numberWithInt:COMMAND_MARK_WATCHED],
96                                        [NSNumber numberWithInt:COMMAND_MARK_UNWATCHED],
97                                        [NSNumber numberWithInt:COMMAND_MARK_FAVORITE],
98                                        [NSNumber numberWithInt:COMMAND_MARK_NOT_FAVORITE],
99                                        [NSNumber numberWithInt:COMMAND_MARK_TO_REFETCH_TV],
100                                        [NSNumber numberWithInt:COMMAND_MARK_TO_REFETCH_MOVIE],
101                                        [NSNumber numberWithInt:COMMAND_MARK_TO_DELETE_METADATA],
102                                        [NSNumber numberWithInt:COMMAND_MARK_TO_RESET_IMPORT],
103                                        nil];
104                id <SapphireDirectory> dirMeta = (id <SapphireDirectory>)meta;
105                if([dirMeta isKindOfClass:[SapphireDirectoryMetaData class]])
106                {
107                        SapphireCollectionDirectory *collection = [(SapphireDirectoryMetaData *)dirMeta collectionDirectory];
108                        if([collection skipValue])
109                        {
110                                [names addObject:BRLocalizedString(@"Mark Directory For Importing", @"Marks this directory to be no longer be skipped during import")];
111                                [markDescriptions addObject:BRLocalizedString(@"Tells Sapphire it's okay to import from this directory.", @"Mark Directory For Importing description")];
112                        }
113                        else
114                        {
115                                [names addObject:BRLocalizedString(@"Mark this Directory to Skip Import", @"Marks this directory to be skipped during import")];
116                                [markDescriptions addObject:BRLocalizedString(@"Tells Sapphire to skip this directory when importing.", @"Mark this Directory to Skip Import description")];
117                        }
118                        [commands addObject:[NSNumber numberWithInt:COMMAND_TOGGLE_SKIP]];
119                        if(![collection isMountValue])
120                        {
121                                if(collection != nil)
122                                {
123                                        [names addObject:BRLocalizedString(@"Mark this Directory to Not be a Collection", @"Marks the directory to no longer be a collection")];
124                                        [markDescriptions addObject:BRLocalizedString(@"Tells Sapphire to remove this directory from the Collections list.", @"Marks the directory to no longer be a collection description")];
125                                }
126                                else
127                                {
128                                        [names addObject:BRLocalizedString(@"Mark this Directory as a Collection", @"Marks the directory to be a collection")];
129                                        [markDescriptions addObject:BRLocalizedString(@"Tells Sapphire to add this directory to the Collections list.", @"Marks the directory to be a collection description")];
130                                }
131                                [commands addObject:[NSNumber numberWithInt:COMMAND_TOGGLE_COLLECTION]];
132                        }
133                }
134        }
135        else if([meta isKindOfClass:[SapphireFileMetaData class]])
136        {
137                SapphireFileMetaData *fileMeta = (SapphireFileMetaData *)metaData;
138                NSString *watched = nil;
139                NSString *watchedDesc = nil;
140                NSString *favorite = nil;
141                NSString *favoriteDesc = nil;
142               
143                if([fileMeta watchedValue])
144                {
145                        watched         = BRLocalizedString(@"Mark as Unwatched", @"Mark file as unwatched");
146                        watchedDesc = BRLocalizedString(@"Sapphire will save this file as unwatched.", @"Mark directory watched description");
147                }
148                else
149                {
150                        watched         = BRLocalizedString(@"Mark as Watched", @"Mark file as watched");
151                        watchedDesc = BRLocalizedString(@"Sapphire will save this file as watched.", @"Mark directory watched description");
152                }
153
154                if([fileMeta favoriteValue])
155                {
156                        favorite         = BRLocalizedString(@"Mark as Not Favorite", @"Mark file as a favorite");
157                        favoriteDesc = BRLocalizedString(@"Sapphire will remove this file from favorites.", @"Mark directory as not favorite");
158                }
159                else
160                {
161                        favorite         = BRLocalizedString(@"Mark as Favorite", @"Mark file as not a favorite");
162                        favoriteDesc = BRLocalizedString(@"Sapphire will add this file as a favorite.", @"Mark directory as favorite description");
163
164                }
165                names                    = [[NSMutableArray alloc] initWithObjects:watched, favorite, nil];
166                markDescriptions = [[NSMutableArray alloc] initWithObjects:watchedDesc, favoriteDesc, nil];
167                commands = [[NSMutableArray alloc] initWithObjects: [NSNumber numberWithInt:COMMAND_TOGGLE_WATCHED], [NSNumber numberWithInt:COMMAND_TOGGLE_FAVORITE], nil];
168                int importType = [fileMeta importTypeValue];
169                if(importType | IMPORT_TYPE_TVSHOW_MASK)
170                {
171                        [names addObject:BRLocalizedString(@"Mark to Refetch TV Data", @"Mark file to re-fetch its tv data")];
172                        [markDescriptions addObject:BRLocalizedString(@"Tells Sapphire to refetch TV Show metadata for this file the next time an import is run.", @"Mark file to refetch tv data description")];
173
174                        [commands addObject:[NSNumber numberWithInt:COMMAND_MARK_TO_REFETCH_TV]];
175                }
176                if(importType | IMPORT_TYPE_MOVIE_MASK)
177                {
178                        [names addObject:BRLocalizedString(@"Mark to Refetch Movie Data", @"Mark file to re-fetch its movie data")];
179                        [markDescriptions addObject:BRLocalizedString(@"Tells Sapphire to refetch Movie metadata for this file the next time an import is run.", @"Mark file to refetch movie description")];
180
181                        [commands addObject:[NSNumber numberWithInt:COMMAND_MARK_TO_REFETCH_MOVIE]];
182                }
183                if([fileMeta fileClass] != FILE_CLASS_UNKNOWN)
184                {
185                        [names addObject:BRLocalizedString(@"Mark to Clear Metadata", @"Mark a file to delete the metadata")];
186                        [markDescriptions addObject:BRLocalizedString(@"Tells Sapphire to remove all metadata for this file.", @"Mark file to delete metadata description")];
187
188                        [commands addObject:[NSNumber numberWithInt:COMMAND_MARK_TO_DELETE_METADATA]];
189                       
190                        [names addObject:BRLocalizedString(@"Mark to Reset Import Decisions", @"Mark a file to reset import decisions")];
191                        [markDescriptions addObject:BRLocalizedString(@"Tells Sapphire to forget import decisions made on this file.", @"Mark a file to reset import decisions description")];
192                       
193                        [commands addObject:[NSNumber numberWithInt:COMMAND_MARK_TO_RESET_IMPORT]];
194                }
195                if(![joinList containsObject:fileMeta])
196                {
197                        [names addObject:BRLocalizedString(@"Mark This File to Be Joined", @"Mark This File to Be Joined")];
198                        [markDescriptions addObject:BRLocalizedString(@"Tells Sapphire you wish to add this file to a list of files to be joined. The files will be joined in the order they were added to the list.", @"Mark file to be joined description")];
199                        [commands addObject:[NSNumber numberWithInt:COMMAND_MARK_TO_JOIN]];
200                        [names addObject:BRLocalizedString(@"Mark This File and Join Group", @"Mark This File and Join Group")];
201                        [markDescriptions addObject:BRLocalizedString(@"Tells Sapphire to use this file to complete the joined list.", @"Mark file and join description")];
202                        [commands addObject:[NSNumber numberWithInt:COMMAND_MARK_AND_JOIN]];
203                }
204                if([joinList count])
205                {
206                        [names addObject:BRLocalizedString(@"Join Marked Files", @"Join Marked Files")];
207                        [markDescriptions addObject:BRLocalizedString(@"Tells Sapphire to complete the file join.", @"Join Marked Files description")];
208
209                        [commands addObject:[NSNumber numberWithInt:COMMAND_JOIN]];
210                        [names addObject:BRLocalizedString(@"Clear the Join List", @"Clear the Join List")];
211                        [markDescriptions addObject:BRLocalizedString(@"Tells Sapphire to clear the file join list.", @"clear file join list description")];
212
213                        [commands addObject:[NSNumber numberWithInt:COMMAND_CLEAR_JOIN_MARK]];
214                }
215        }
216        else
217        {
218                /*Neither, so just return nil*/
219                [self autorelease];
220                return nil;
221        }
222        [[self list] setDatasource:self];
223       
224        return self;
225}
226
227- (void) dealloc
228{
229        [commands release];
230        [names release];
231        [markDescriptions release];
232        [metaData release];
233        [names release];
234        [super dealloc];
235}
236
237- (void)doJoin
238{
239        if(![joinList count])
240                return;
241       
242        QTMovie *resultingMovie = [[QTMovie alloc] init];
243        [resultingMovie setAttribute:[NSNumber numberWithBool:YES] forKey:QTMovieEditableAttribute];
244       
245        NSString *savePath = [[joinList objectAtIndex:0] path];
246        BOOL hasmovExt = [[savePath pathExtension] isEqualToString:@"mov"];
247        NSString *base = [savePath stringByDeletingPathExtension];
248        if([[base lowercaseString] hasSuffix:@" part 1"])
249                base = [base substringToIndex:[base length] - 7];
250        if(hasmovExt)
251                savePath = [[base stringByAppendingString:@" Joined"] stringByAppendingPathExtension:@"mov"];
252        else
253                savePath = [base stringByAppendingPathExtension:@"mov"];
254
255        NSManagedObjectContext *moc = [[joinList objectAtIndex:0] managedObjectContext];
256        [SapphireFileMetaData createFileWithPath:savePath inContext:moc];
257        SapphireJoinedFile *joined = [SapphireJoinedFile joinedFileForPath:savePath inContext:moc];
258        int i, count=[joinList count];
259        for(i=0;i<count;i++)
260        {
261                SapphireFileMetaData *meta = [joinList objectAtIndex:i];
262                NSError *error = nil;
263                NSDictionary *openAttr = [NSDictionary dictionaryWithObjectsAndKeys:
264                                                                  [meta path], QTMovieFileNameAttribute,
265                                                                  [NSNumber numberWithBool:NO], QTMovieOpenAsyncOKAttribute,
266                                                                  nil];
267                QTMovie *current = [[QTMovie alloc] initWithAttributes:openAttr error:&error];
268                if(error == nil)
269                {
270                        QTTimeRange range;
271                        range.time = [current selectionStart];
272                        range.duration = [current duration];
273                        [current setSelection:range];
274                        [resultingMovie appendSelectionFromMovie:current];
275                        [meta setJoinedToFile:joined];
276                }
277                [current release];
278        }
279
280        [resultingMovie writeToFile:savePath withAttributes:[NSDictionary dictionary]];
281        [resultingMovie release];
282        [joinList removeAllObjects];
283        [SapphireMetaDataSupport save:moc];
284}
285
286- (void) willBePushed
287{
288    // We're about to be placed on screen, but we're not yet there
289   
290    // always call super
291    [super willBePushed];
292}
293
294- (void) wasPushed
295{
296    // We've just been put on screen, the user can see this controller's content now
297   
298    // always call super
299    [super wasPushed];
300}
301
302- (void) willBePopped
303{
304    // The user pressed Menu, but we've not been removed from the screen yet
305   
306    // always call super
307    [super willBePopped];
308}
309
310- (void) wasPopped
311{
312    // The user pressed Menu, removing us from the screen
313   
314    // always call super
315    [super wasPopped];
316}
317
318- (void) willBeBuried
319{
320    // The user just chose an option, and we will be taken off the screen
321   
322    // always call super
323    [super willBeBuried];
324}
325
326- (void) wasBuriedByPushingController: (BRLayerController *) controller
327{
328    // The user chose an option and this controller os no longer on screen
329   
330    // always call super
331    [super wasBuriedByPushingController: controller];
332}
333
334- (void) willBeExhumed
335{
336    // the user pressed Menu, but we've not been revealed yet
337   
338    // always call super
339    [super willBeExhumed];
340}
341
342- (void) wasExhumedByPoppingController: (BRLayerController *) controller
343{
344    // handle being revealed when the user presses Menu
345   
346    // always call super
347    [super wasExhumedByPoppingController: controller];
348}
349
350- (long) itemCount
351{
352    // return the number of items in your menu list here
353        return ( [ names count]);
354}
355
356- (id<BRMenuItemLayer>) itemForRow: (long) row
357{
358        /*
359         // build a BRTextMenuItemLayer or a BRAdornedMenuItemLayer, etc. here
360         // return that object, it will be used to display the list item.
361         return ( nil );
362         */
363        if( row >= [names count] ) return ( nil ) ;
364       
365        BRAdornedMenuItemLayer * result = nil ;
366        NSString *name = [names objectAtIndex:row];
367        result = [SapphireFrontRowCompat textMenuItemForScene:[self scene] folder:NO];
368       
369        // add text
370        [SapphireFrontRowCompat setTitle:name forMenu:result];
371                               
372        return ( result ) ;
373}
374
375- (NSString *) titleForRow: (long) row
376{
377       
378        if ( row >= [ names count] ) return ( nil );
379       
380        NSString *result = [ names objectAtIndex: row] ;
381        return ( result ) ;
382}
383
384- (long) rowForTitle: (NSString *) title
385{
386    long result = -1;
387    long i, count = [self itemCount];
388    for ( i = 0; i < count; i++ )
389    {
390        if ( [title isEqualToString: [self titleForRow: i]] )
391        {
392            result = i;
393            break;
394        }
395    }
396   
397    return ( result );
398}
399
400- (void) itemSelected: (long) row
401{
402    // This is called when the user presses play/pause on a list item
403        if(row >= [names count])
404                return;
405       
406        NSManagedObjectContext *moc = [metaData managedObjectContext];
407        /*Do action on dir or file*/
408        if(isDir)
409        {
410                id <SapphireDirectory> dirMeta = (id <SapphireDirectory>)metaData;
411                SapphireCollectionDirectory *collection = nil;
412                if([dirMeta isKindOfClass:[SapphireDirectoryMetaData class]])
413                        collection = [(SapphireDirectoryMetaData *)dirMeta collectionDirectory];
414                NSString *path = [dirMeta path];
415                switch([[commands objectAtIndex:row] intValue])
416                {
417                        case COMMAND_MARK_WATCHED:
418                                setSubtreeToWatched(dirMeta, YES);
419                                break;
420                        case COMMAND_MARK_UNWATCHED:
421                                setSubtreeToWatched(dirMeta, NO);
422                                break;
423                        case COMMAND_MARK_FAVORITE:
424                                setSubtreeToFavorite(dirMeta, YES);
425                                break;
426                        case COMMAND_MARK_NOT_FAVORITE:
427                                setSubtreeToFavorite(dirMeta, NO);
428                                break;
429                        case COMMAND_MARK_TO_REFETCH_TV:
430                                setSubtreeToReimportFromMask(dirMeta, IMPORT_TYPE_TVSHOW_MASK);
431                                break;
432                        case COMMAND_MARK_TO_REFETCH_MOVIE:
433                                setSubtreeToReimportFromMask(dirMeta, IMPORT_TYPE_MOVIE_MASK);
434                                break;
435                        case COMMAND_MARK_TO_DELETE_METADATA:
436                                setSubtreeToClearMetaData(dirMeta);
437                                break;
438                        case COMMAND_MARK_TO_RESET_IMPORT:
439                                setSubtreeToResetImportDecisions(dirMeta);
440                                break;
441                        case COMMAND_TOGGLE_SKIP:
442                                if(collection == nil)
443                                        collection = [SapphireCollectionDirectory collectionAtPath:path inContext:moc];
444                                [collection setSkipValue:![collection skipValue]];
445                                break;
446                        case COMMAND_TOGGLE_COLLECTION:
447                                if(collection == nil)
448                                        [SapphireCollectionDirectory collectionAtPath:path inContext:moc];
449                                else
450                                        [moc deleteObject:collection];
451                                break;
452                }
453        }
454        else
455        {
456                SapphireFileMetaData *fileMeta = (SapphireFileMetaData *)metaData;
457                switch([[commands objectAtIndex:row] intValue])
458                {
459                        case COMMAND_TOGGLE_WATCHED:
460                                [fileMeta setWatchedValue:![fileMeta watchedValue]];
461                                [fileMeta setResumeTime:0];
462                                break;
463                        case COMMAND_TOGGLE_FAVORITE:
464                                [fileMeta setFavoriteValue:![fileMeta favoriteValue]];
465                                break;
466                        case COMMAND_MARK_TO_REFETCH_TV:
467                                [fileMeta setToReimportFromMask:IMPORT_TYPE_TVSHOW_MASK];
468                                break;
469                        case COMMAND_MARK_TO_REFETCH_MOVIE:
470                                [fileMeta setToReimportFromMask:IMPORT_TYPE_MOVIE_MASK];
471                                break;
472                        case COMMAND_MARK_TO_DELETE_METADATA:
473                                [fileMeta clearMetaData];
474                                break;
475                        case COMMAND_MARK_TO_RESET_IMPORT:
476                                [fileMeta setToResetImportDecisions];
477                                break;
478                        case COMMAND_MARK_TO_JOIN:
479                                [joinList addObject:fileMeta];
480                                break;
481                        case COMMAND_CLEAR_JOIN_MARK:
482                                [joinList removeAllObjects];
483                                break;
484                        case COMMAND_MARK_AND_JOIN:
485                                [joinList addObject:fileMeta];
486                        case COMMAND_JOIN:
487                                [self doJoin];
488                                break;
489                }
490        }
491        /*Save and exit*/
492        [SapphireMetaDataSupport save:moc];
493        [[self stack] popController];
494}
495
496- (id<BRMediaPreviewController>) previewControlForItem:(long)item
497{
498        return [self previewControllerForItem:item];
499}
500
501- (id<BRMediaPreviewController>) previewControllerForItem: (long) item
502{
503    // If subclassing BRMediaMenuController, this function is called when the selection cursor
504    // passes over an item.
505                if(item >= [names count])
506                return nil;
507        else
508        {
509                /* Get setting name & kill cushion  */
510                NSString *markName =[NSString stringWithFormat:@"%@ for \"%@\"",[names objectAtIndex:item],(NSString *)[self listTitle]];
511                NSString *markDescription=[markDescriptions objectAtIndex:item];
512                /* Construct a gerneric metadata asset for display */
513                NSMutableDictionary *markMeta=[[NSMutableDictionary alloc] init];
514                [markMeta setObject:markName forKey:META_TITLE_KEY];
515                [markMeta setObject:[NSNumber numberWithInt:FILE_CLASS_UTILITY] forKey:FILE_CLASS_KEY];
516                [markMeta setObject:markDescription forKey:META_DESCRIPTION_KEY];
517                SapphireMediaPreview *preview = [[SapphireMediaPreview alloc] initWithScene:[self scene]];
518                [preview setUtilityData:markMeta];
519                [preview setShowsMetadataImmediately:YES];
520                /*And go*/
521                return [preview autorelease];
522        }
523    return ( nil );
524}
525
526@end
Note: See TracBrowser for help on using the repository browser.