source: trunk/SapphireFrappliance/SapphireMarkMenu.m @ 474

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