source: trunk/SapphireFrappliance/Browser/SapphireMarkMenu.m @ 929

Revision 929, 34.9 KB checked in by gbooker, 5 years ago (diff)

Change the reset of metadata to be enabled if any import has been done, not just if the type has been identified.

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#import "SapphireTextEntryController.h"
31#import "SapphireErrorDisplayController.h"
32#import "SapphireWaitDisplay.h"
33#import "SapphireConfirmPrompt.h"
34#import "SapphireApplianceController.h"
35#import "SapphirePosterChooser.h"
36#import "NSImage-Extensions.h"
37#import "NSFileManager-Extensions.h"
38
39BOOL allowCoverArtChange( NSString * const path )
40{
41        if ( [[NSFileManager defaultManager] hasVIDEO_TS:path] )
42                return NO;
43       
44        static NSSet *disallowedFormats = nil;
45        if(disallowedFormats == nil)
46        {
47                disallowedFormats = [[NSSet alloc] initWithObjects:@"mkv", @"flv", nil];
48        }
49       
50        return ![disallowedFormats containsObject:[path pathExtension]];
51}
52
53@implementation SapphireMarkMenu
54
55NSString *MARK_NAME                                     = @"Name";
56NSString *MARK_DESCRIPTION                      = @"Description";
57NSString *MARK_COMMAND                          = @"Command";
58
59typedef enum {
60        COMMAND_TOGGLE_WATCHED,
61        COMMAND_TOGGLE_FAVORITE,
62        COMMAND_MARK_TO_REFETCH_TV,
63        COMMAND_MARK_TO_REFETCH_MOVIE,
64        COMMAND_MARK_TO_DELETE_METADATA,
65        COMMAND_MARK_TO_RESET_IMPORT,
66        COMMAND_RENAME,
67        COMMAND_RENAME_TO_PRETTY,
68        COMMAND_CUT_PATH,
69        COMMAND_DELETE_PATH,
70        COMMAND_CHANGE_ARTWORK,
71        //File Only Commands
72        COMMAND_MARK_TO_JOIN,
73        COMMAND_MARK_AND_JOIN,
74        COMMAND_CLEAR_JOIN_MARK,
75        COMMAND_JOIN,
76        //Directory Only Commands
77        COMMAND_MARK_WATCHED,
78        COMMAND_MARK_UNWATCHED,
79        COMMAND_MARK_FAVORITE,
80        COMMAND_MARK_NOT_FAVORITE,
81        COMMAND_TOGGLE_SKIP,
82        COMMAND_TOGGLE_COLLECTION,
83        COMMAND_PASTE_PATH,
84} MarkCommand;
85
86static NSMutableArray *joinList;
87static NSString *movingPath = nil;
88
89+ (void)initialize
90{
91        joinList = [[NSMutableArray alloc] init];
92}
93
94- (id) initWithScene: (BRRenderScene *) scene metaData: (SapphireMetaData *)meta
95{
96        self = [super initWithScene:scene];
97        if(!self)
98                return nil;
99       
100        /*Check to see if it is directory or file*/
101        isDir = [meta conformsToProtocol:@protocol(SapphireDirectory)];
102        metaData = [meta retain];
103        /*Create the menu*/
104        if(isDir)
105        {
106                marks = [[NSMutableArray alloc] initWithObjects:
107                        [NSDictionary dictionaryWithObjectsAndKeys:
108                                BRLocalizedString(@"Rename this Directory", @"Rename a directory"), MARK_NAME,
109                                BRLocalizedString(@"Edit the name for this directory", @""), MARK_DESCRIPTION,
110                                [NSNumber numberWithInt:COMMAND_RENAME], MARK_COMMAND,
111                                nil],
112                        [NSDictionary dictionaryWithObjectsAndKeys:
113                                BRLocalizedString(@"Rename all Files to Pretty Name", @"Rename all files to a pretty name"), MARK_NAME,
114                                BRLocalizedString(@"Rename all files to a pretty name for those which a pretty name exists", @""), MARK_DESCRIPTION,
115                                [NSNumber numberWithInt:COMMAND_RENAME_TO_PRETTY], MARK_COMMAND,
116                                nil],
117                        [NSDictionary dictionaryWithObjectsAndKeys:
118                                BRLocalizedString(@"Mark All as Watched", @"Mark whole directory as watched"), MARK_NAME,
119                                BRLocalizedString(@"Sapphire will save this directory as watched.", @"Mark directory watched description"), MARK_DESCRIPTION,
120                                [NSNumber numberWithInt:COMMAND_MARK_WATCHED], MARK_COMMAND,
121                                nil],
122                        [NSDictionary dictionaryWithObjectsAndKeys:
123                                BRLocalizedString(@"            Unwatched", @"Mark whole directory as unwatched"), MARK_NAME,
124                                BRLocalizedString(@"Sapphire will save this directory as unwatched.", @"Mark directory as unwatched description"), MARK_DESCRIPTION,
125                                [NSNumber numberWithInt:COMMAND_MARK_UNWATCHED], MARK_COMMAND,
126                                nil],
127                        [NSDictionary dictionaryWithObjectsAndKeys:
128                                BRLocalizedString(@"            Favorite", @"Mark whole directory as favorite"), MARK_NAME,
129                                BRLocalizedString(@"Sapphire will add this directory as favorite.", @"Mark directory as favorite description"), MARK_DESCRIPTION,
130                                [NSNumber numberWithInt:COMMAND_MARK_FAVORITE], MARK_COMMAND,
131                                nil],
132                        [NSDictionary dictionaryWithObjectsAndKeys:
133                                BRLocalizedString(@"            Not Favorite", @"Mark whole directory as not favorite"), MARK_NAME,
134                                BRLocalizedString(@"Sapphire will remove this directory from favorites.", @"Mark directory as not favorite"), MARK_DESCRIPTION,
135                                [NSNumber numberWithInt:COMMAND_MARK_NOT_FAVORITE], MARK_COMMAND,
136                                nil],
137                        [NSDictionary dictionaryWithObjectsAndKeys:
138                                BRLocalizedString(@"            Refetch TV Data", @"Mark whole directory to re-fetch its tv data"), MARK_NAME,
139                                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"), MARK_DESCRIPTION,
140                                [NSNumber numberWithInt:COMMAND_MARK_TO_REFETCH_TV], MARK_COMMAND,
141                                nil],
142                        [NSDictionary dictionaryWithObjectsAndKeys:
143                                BRLocalizedString(@"            Refetch Movie Data", @"Mark whole directory to re-fetch its movie data"), MARK_NAME,
144                                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"), MARK_DESCRIPTION,
145                                [NSNumber numberWithInt:COMMAND_MARK_TO_REFETCH_MOVIE], MARK_COMMAND,
146                                nil],
147                        [NSDictionary dictionaryWithObjectsAndKeys:
148                                BRLocalizedString(@"            Clear Metadata", @"Mark whole directory to delete the metadata"), MARK_NAME,
149                                BRLocalizedString(@"Tells Sapphire to remove all metadata for this directory.", @"Mark directory to delete metadata description"), MARK_DESCRIPTION,
150                                [NSNumber numberWithInt:COMMAND_MARK_TO_DELETE_METADATA], MARK_COMMAND,
151                                nil],
152                        [NSDictionary dictionaryWithObjectsAndKeys:
153                                BRLocalizedString(@"            Reset Import Decisions", @"Mark whole directory to reset import decisions"), MARK_NAME,
154                                BRLocalizedString(@"Tells Sapphire to forget import decisions made on files in this directory.", @"Mark directory to reset import decisions description"), MARK_DESCRIPTION,
155                                [NSNumber numberWithInt:COMMAND_MARK_TO_RESET_IMPORT], MARK_COMMAND,
156                                nil],
157                         nil];
158                id <SapphireDirectory> dirMeta = (id <SapphireDirectory>)meta;
159                if([dirMeta isKindOfClass:[SapphireDirectoryMetaData class]])
160                {
161                        SapphireCollectionDirectory *collection = [(SapphireDirectoryMetaData *)dirMeta collectionDirectory];
162                        if([collection isMountValue])
163                        {
164                                [marks replaceObjectAtIndex:0 withObject:
165                                        [NSDictionary dictionaryWithObjectsAndKeys:
166                                                BRLocalizedString(@"Rename this Collection", @"Rename a collection"), MARK_NAME,
167                                                BRLocalizedString(@"Edit the display name for this collection", @""), MARK_DESCRIPTION,
168                                                [NSNumber numberWithInt:COMMAND_RENAME], MARK_COMMAND,
169                                                nil]];
170                        }
171                        if([collection skipValue])
172                        {
173                                [marks addObject:
174                                        [NSDictionary dictionaryWithObjectsAndKeys:
175                                                BRLocalizedString(@"Mark Directory For Importing", @"Marks this directory to be no longer be skipped during import"), MARK_NAME,
176                                                BRLocalizedString(@"Tells Sapphire it's okay to import from this directory.", @"Mark Directory For Importing description"), MARK_DESCRIPTION,
177                                                [NSNumber numberWithInt:COMMAND_TOGGLE_SKIP], MARK_COMMAND,
178                                                nil]];
179                        }
180                        else
181                        {
182                                [marks addObject:
183                                        [NSDictionary dictionaryWithObjectsAndKeys:
184                                                BRLocalizedString(@"Mark this Directory to Skip Import", @"Marks this directory to be skipped during import"), MARK_NAME,
185                                                BRLocalizedString(@"Tells Sapphire to skip this directory when importing.", @"Mark this Directory to Skip Import description"), MARK_DESCRIPTION,
186                                                [NSNumber numberWithInt:COMMAND_TOGGLE_SKIP], MARK_COMMAND,
187                                                nil]];
188                        }
189                        if(![collection isMountValue])
190                        {
191                                if(collection != nil)
192                                {
193                                        [marks addObject:
194                                                [NSDictionary dictionaryWithObjectsAndKeys:
195                                                        BRLocalizedString(@"                    to Not be a Collection", @"Marks the directory to no longer be a collection"), MARK_NAME,
196                                                        BRLocalizedString(@"Tells Sapphire to remove this directory from the Collections list.", @"Marks the directory to no longer be a collection description"), MARK_DESCRIPTION,
197                                                        [NSNumber numberWithInt:COMMAND_TOGGLE_COLLECTION], MARK_COMMAND,
198                                                        nil]];
199                                }
200                                else
201                                {
202                                        [marks addObject:
203                                                [NSDictionary dictionaryWithObjectsAndKeys:
204                                                        BRLocalizedString(@"                    as a Collection", @"Marks the directory to be a collection"), MARK_NAME,
205                                                        BRLocalizedString(@"Tells Sapphire to add this directory to the Collections list.", @"Marks the directory to be a collection description"), MARK_DESCRIPTION,
206                                                        [NSNumber numberWithInt:COMMAND_TOGGLE_COLLECTION], MARK_COMMAND,
207                                                        nil]];
208                                }
209                        }
210                        if(![collection isMountValue])
211                        {
212                                [marks addObject:
213                                        [NSDictionary dictionaryWithObjectsAndKeys:
214                                                BRLocalizedString(@"Move Directory", @"Marks this directory to be moved"), MARK_NAME,
215                                                BRLocalizedString(@"Move this directory.  Select destination later.", @""), MARK_DESCRIPTION,
216                                                [NSNumber numberWithInt:COMMAND_CUT_PATH], MARK_COMMAND,
217                                                nil]];
218                                [marks addObject:
219                                        [NSDictionary dictionaryWithObjectsAndKeys:
220                                                BRLocalizedString(@"Delete Directory", @"Marks this directory to be deleted"), MARK_NAME,
221                                                BRLocalizedString(@"Deletes this directory and its contents", @""), MARK_DESCRIPTION,
222                                                [NSNumber numberWithInt:COMMAND_DELETE_PATH], MARK_COMMAND,
223                                                nil]];
224                        }
225                        if(movingPath != nil && ![[dirMeta path] hasPrefix:movingPath])
226                        {
227                                [marks addObject:
228                                        [NSDictionary dictionaryWithObjectsAndKeys:
229                                                BRLocalizedString(@"Move to Here", @"Move File to within this directory"), MARK_NAME,
230                                                [NSString stringWithFormat:BRLocalizedString(@"Move %@ to %@", @"parameter is last component of path, second is last path component of destination"), [movingPath lastPathComponent], [[meta path] lastPathComponent]], MARK_DESCRIPTION,
231                                                [NSNumber numberWithInt:COMMAND_PASTE_PATH], MARK_COMMAND,
232                                                nil]];
233                        }
234                }
235                else
236                {
237                        [marks removeObjectAtIndex:0];
238                }
239        }
240        else if([meta isKindOfClass:[SapphireFileMetaData class]])
241        {
242                SapphireFileMetaData *fileMeta = (SapphireFileMetaData *)metaData;
243                NSString *watched = nil;
244                NSString *watchedDesc = nil;
245                NSString *favorite = nil;
246                NSString *favoriteDesc = nil;
247               
248                if([fileMeta watchedValue])
249                {
250                        watched         = BRLocalizedString(@"Mark as Unwatched", @"Mark file as unwatched");
251                        watchedDesc = BRLocalizedString(@"Sapphire will save this file as unwatched.", @"Mark directory watched description");
252                }
253                else
254                {
255                        watched         = BRLocalizedString(@"Mark as Watched", @"Mark file as watched");
256                        watchedDesc = BRLocalizedString(@"Sapphire will save this file as watched.", @"Mark directory watched description");
257                }
258
259                if([fileMeta favoriteValue])
260                {
261                        favorite         = BRLocalizedString(@"        Not Favorite", @"Mark file as a favorite");
262                        favoriteDesc = BRLocalizedString(@"Sapphire will remove this file from favorites.", @"Mark directory as not favorite");
263                }
264                else
265                {
266                        favorite         = BRLocalizedString(@"        Favorite", @"Mark file as not a favorite");
267                        favoriteDesc = BRLocalizedString(@"Sapphire will add this file as a favorite.", @"Mark directory as favorite description");
268
269                }
270                marks = [[NSMutableArray alloc] initWithObjects:
271                        [NSDictionary dictionaryWithObjectsAndKeys:
272                                BRLocalizedString(@"Rename this file", @"Rename a file"), MARK_NAME,
273                                BRLocalizedString(@"Move a file to another name", @"Rename file description"), MARK_DESCRIPTION,
274                                [NSNumber numberWithInt:COMMAND_RENAME], MARK_COMMAND,
275                                nil],
276                        [NSDictionary dictionaryWithObjectsAndKeys:
277                                watched, MARK_NAME,
278                                watchedDesc, MARK_DESCRIPTION,
279                                [NSNumber numberWithInt:COMMAND_TOGGLE_WATCHED], MARK_COMMAND,
280                                nil],
281                        [NSDictionary dictionaryWithObjectsAndKeys:
282                                favorite, MARK_NAME,
283                                favoriteDesc, MARK_DESCRIPTION,
284                                [NSNumber numberWithInt:COMMAND_TOGGLE_FAVORITE], MARK_COMMAND,
285                                nil],
286                        nil];
287               
288                NSString *prettyName = [fileMeta prettyName];
289                if(prettyName != nil && [[[[fileMeta path] lastPathComponent] stringByDeletingPathExtension] caseInsensitiveCompare:prettyName] != NSOrderedSame)
290                {
291                        [marks insertObject:
292                                [NSDictionary dictionaryWithObjectsAndKeys:
293                                        BRLocalizedString(@"Rename to Pretty Name", @""), MARK_NAME,
294                                        [NSString stringWithFormat:BRLocalizedString(@"Rename to \"%@\"", @"Parameter is new name"), prettyName], MARK_DESCRIPTION,
295                                        [NSNumber numberWithInt:COMMAND_RENAME_TO_PRETTY], MARK_COMMAND,
296                                        nil]
297                                atIndex:1];
298                }
299                if([fileMeta joinedToFile] != nil)
300                {
301                        [marks removeObjectAtIndex:0];
302                }
303                int importType = [fileMeta importTypeValue];
304                if(importType | IMPORT_TYPE_TVSHOW_MASK)
305                {
306                        [marks addObject:
307                                [NSDictionary dictionaryWithObjectsAndKeys:
308                                        BRLocalizedString(@"        Refetch TV Data", @"Mark file to re-fetch its tv data"), MARK_NAME,
309                                        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"), MARK_DESCRIPTION,
310                                        [NSNumber numberWithInt:COMMAND_MARK_TO_REFETCH_TV], MARK_COMMAND,
311                                        nil]];
312                }
313                if(importType | IMPORT_TYPE_MOVIE_MASK)
314                {
315                        [marks addObject:
316                                [NSDictionary dictionaryWithObjectsAndKeys:
317                                        BRLocalizedString(@"        Refetch Movie Data", @"Mark file to re-fetch its movie data"), MARK_NAME,
318                                        BRLocalizedString(@"Tells Sapphire to refetch Movie metadata for this file the next time an import is run.", @"Mark file to refetch movie description"), MARK_DESCRIPTION,
319                                        [NSNumber numberWithInt:COMMAND_MARK_TO_REFETCH_MOVIE], MARK_COMMAND,
320                                        nil]];
321                }
322                if([fileMeta importTypeValue] != 0)
323                {
324                        [marks addObject:
325                                [NSDictionary dictionaryWithObjectsAndKeys:
326                                        BRLocalizedString(@"        Clear Metadata", @"Mark a file to delete the metadata"), MARK_NAME,
327                                        BRLocalizedString(@"Tells Sapphire to remove all metadata for this file.", @"Mark file to delete metadata description"), MARK_DESCRIPTION,
328                                        [NSNumber numberWithInt:COMMAND_MARK_TO_DELETE_METADATA], MARK_COMMAND,
329                                        nil]];
330                }
331                if([fileMeta fileClass] != FILE_CLASS_UNKNOWN)
332                {
333                        [marks addObject:
334                                [NSDictionary dictionaryWithObjectsAndKeys:
335                                        BRLocalizedString(@"        Reset Import Decisions", @"Mark a file to reset import decisions"), MARK_NAME,
336                                        BRLocalizedString(@"Tells Sapphire to forget import decisions made on this file.", @"Mark a file to reset import decisions description"), MARK_DESCRIPTION,
337                                        [NSNumber numberWithInt:COMMAND_MARK_TO_RESET_IMPORT], MARK_COMMAND,
338                                        nil]];
339                }
340                if(![joinList containsObject:fileMeta])
341                {
342                        [marks addObject:
343                                [NSDictionary dictionaryWithObjectsAndKeys:
344                                        BRLocalizedString(@"Join To Other Files", @"Join To Other Files"), MARK_NAME,
345                                        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"), MARK_DESCRIPTION,
346                                        [NSNumber numberWithInt:COMMAND_MARK_TO_JOIN], MARK_COMMAND,
347                                        nil]];
348                        [marks addObject:
349                                [NSDictionary dictionaryWithObjectsAndKeys:
350                                        BRLocalizedString(@"     This File and Complete", @"     This File and Complete"), MARK_NAME,
351                                        BRLocalizedString(@"Tells Sapphire to use this file to complete the joined list.", @"Mark file and join description"), MARK_DESCRIPTION,
352                                        [NSNumber numberWithInt:COMMAND_MARK_AND_JOIN], MARK_COMMAND,
353                                        nil]];
354                }
355                if([joinList count])
356                {
357                        NSString *joinName;
358                        if(![joinList containsObject:fileMeta])
359                                joinName = BRLocalizedString(@"     Selected Files", @"     Selected Files");
360                        else
361                                joinName = BRLocalizedString(@"Join Selected Files", @"     Selected Files");
362                       
363                        [marks addObject:
364                                [NSDictionary dictionaryWithObjectsAndKeys:
365                                        joinName, MARK_NAME,
366                                        BRLocalizedString(@"Tells Sapphire to complete the file join.", @"Join Marked Files description"), MARK_DESCRIPTION,
367                                        [NSNumber numberWithInt:COMMAND_JOIN], MARK_COMMAND,
368                                        nil]];
369                        [marks addObject:
370                                [NSDictionary dictionaryWithObjectsAndKeys:
371                                        BRLocalizedString(@"     Clear", @"     Clear"), MARK_NAME,
372                                        BRLocalizedString(@"Tells Sapphire to clear the file join list.", @"clear file join list description"), MARK_DESCRIPTION,
373                                        [NSNumber numberWithInt:COMMAND_CLEAR_JOIN_MARK], MARK_COMMAND,
374                                        nil]];
375                }
376                [marks addObject:
377                        [NSDictionary dictionaryWithObjectsAndKeys:
378                                BRLocalizedString(@"Move File", @"Marks this file to be moved"), MARK_NAME,
379                                BRLocalizedString(@"Move this file.  Select destination later.", @""), MARK_DESCRIPTION,
380                                [NSNumber numberWithInt:COMMAND_CUT_PATH], MARK_COMMAND,
381                                nil]];
382                [marks addObject:
383                        [NSDictionary dictionaryWithObjectsAndKeys:
384                                BRLocalizedString(@"Delete File", @"Marks this file to be deleted"), MARK_NAME,
385                                BRLocalizedString(@"Deletes this file", @""), MARK_DESCRIPTION,
386                                [NSNumber numberWithInt:COMMAND_DELETE_PATH], MARK_COMMAND,
387                                nil]];
388                // Allow cover art change for all formats except for DVD, .mkv, and .flv
389                // QTMovie is broken on the ATV, don't do it there
390                if ([SapphireFrontRowCompat usingLeopard] && allowCoverArtChange( [meta path] ) )
391                {
392                        [marks addObject:
393                                [NSDictionary dictionaryWithObjectsAndKeys:
394                                        BRLocalizedString(@"Change artwork", @"Change artwork"), MARK_NAME,
395                                        BRLocalizedString(@"Select artwork using images from the file", @""), MARK_DESCRIPTION,
396                                        [NSNumber numberWithInt:COMMAND_CHANGE_ARTWORK], MARK_COMMAND,
397                                        nil]];
398                }
399        }
400        else
401        {
402                /*Neither, so just return nil*/
403                [self autorelease];
404                return nil;
405        }
406        [[self list] setDatasource:self];
407       
408        return self;
409}
410
411- (void) dealloc
412{
413        [marks release];
414        [metaData release];
415        [super dealloc];
416}
417
418- (BRLayerController *)loadArtwork:(SapphireFileMetaData *)fileMeta
419{
420        NSInvocation *invoke = [NSInvocation invocationWithMethodSignature: [self methodSignatureForSelector: @selector(doChangeArtwork:)]];
421        [invoke setSelector: @selector(doChangeArtwork:)];
422        [invoke setTarget:   self];
423       
424        SapphireWaitDisplay *wait = [[SapphireWaitDisplay alloc] initWithScene: [self scene]
425                                                                                                                                         title: BRLocalizedString(@"Getting artwork selection", @"Getting artwork selection")
426                                                                                                                                invokation: invoke];
427       
428        [invoke setArgument: &fileMeta atIndex: 2];
429        return [wait autorelease];
430}
431
432- (BRLayerController *)doChangeArtwork:(SapphireFileMetaData *)fileMeta
433{
434        SapphirePosterChooser *controller = [[SapphirePosterChooser alloc] initWithScene:[self scene]];
435
436        [controller setListTitle:BRLocalizedString(@"Select cover art", @"Select cover art")];
437        [controller setMovieTitle:@" "];
438        [controller setFile:fileMeta];
439        [controller setPosterImages:[NSImage imagesFromMovie:[fileMeta path] forArraySize:10]];
440       
441        NSInvocation *invoke = [NSInvocation invocationWithMethodSignature: [self methodSignatureForSelector:@selector(doChangeArtwork:)]];
442        [invoke setSelector:@selector(doChangeArtwork:)];
443        [invoke setTarget:self];
444        [invoke retainArguments];
445        [invoke setArgument:&fileMeta atIndex:2];
446        [controller setRefreshInvokation:invoke];
447       
448        return [controller autorelease];
449}
450
451- (BRLayerController *)doJoin:(SapphireWaitDisplay *)wait
452{
453        @try {
454                if(![joinList count])
455                        return nil;
456               
457                BOOL isFav = NO, isUnwatched = NO;
458                QTMovie *resultingMovie = [[QTMovie alloc] init];
459                [resultingMovie setAttribute:[NSNumber numberWithBool:YES] forKey:QTMovieEditableAttribute];
460               
461                NSString *savePath = [[joinList objectAtIndex:0] path];
462                BOOL hasmovExt = [[savePath pathExtension] isEqualToString:@"mov"];
463                NSString *base = [savePath stringByDeletingPathExtension];
464                if([[base lowercaseString] hasSuffix:@" part 1"])
465                        base = [base substringToIndex:[base length] - 7];
466                if(hasmovExt)
467                        savePath = [[base stringByAppendingString:@" Joined"] stringByAppendingPathExtension:@"mov"];
468                else
469                        savePath = [base stringByAppendingPathExtension:@"mov"];
470               
471                NSManagedObjectContext *moc = [[joinList objectAtIndex:0] managedObjectContext];
472                NSMutableString *mutSavePath = [savePath mutableCopy];
473                [mutSavePath replaceOccurrencesOfString:@":" withString:@"-" options:0 range:NSMakeRange(0, [mutSavePath length])];  //Stupid QTKit Programmers.  This bug exists in QT Player in Leopard too.
474                savePath = [mutSavePath autorelease];
475                SapphireFileMetaData *finalFile = [SapphireFileMetaData createFileWithPath:savePath inContext:moc];
476                SapphireJoinedFile *joined = [SapphireJoinedFile joinedFileForPath:savePath inContext:moc];
477                int i, count=[joinList count];
478                for(i=0;i<count;i++)
479                {
480                        SapphireFileMetaData *meta = [joinList objectAtIndex:i];
481                        isFav |= [meta favoriteValue];
482                        isUnwatched |= ![meta watchedValue];
483                        [wait setCurrentStatus:[NSString stringWithFormat:BRLocalizedString(@"Opening %@", @"parameter is filename"), [[meta path] lastPathComponent]]];
484                        NSError *error = nil;
485                        NSDictionary *openAttr = [NSDictionary dictionaryWithObjectsAndKeys:
486                                                                          [meta path], QTMovieFileNameAttribute,
487                                                                          [NSNumber numberWithBool:NO], QTMovieOpenAsyncOKAttribute,
488                                                                          nil];
489                        QTMovie *current = [[QTMovie alloc] initWithAttributes:openAttr error:&error];
490                        if(error == nil)
491                        {
492                                QTTimeRange range;
493                                range.time = [current selectionStart];
494                                range.duration = [current duration];
495                                [current setSelection:range];
496                                [resultingMovie appendSelectionFromMovie:current];
497                                [meta setJoinedToFile:joined];
498                        }
499                        else
500                        {
501                                SapphireErrorDisplayController *errorDisplay = [[SapphireErrorDisplayController alloc] initWithScene:[self scene] error:BRLocalizedString(@"Read Error", @"") longError:[error localizedDescription]];
502                                [resultingMovie release];
503                                [current release];
504                                return [errorDisplay autorelease];
505                        }
506                        [current release];
507                }
508               
509                SapphireErrorDisplayController *errorDisplay = nil;
510                [wait setCurrentStatus:[NSString stringWithFormat:BRLocalizedString(@"Saving Joined File to %@", @"parameter is save path"), [savePath lastPathComponent]]];
511                [finalFile setWatchedValue:!isUnwatched];
512                [finalFile setFavoriteValue:isFav];
513                if(![resultingMovie writeToFile:savePath withAttributes:[NSDictionary dictionary]])
514                {
515                        errorDisplay = [[SapphireErrorDisplayController alloc] initWithScene:[self scene] error:BRLocalizedString(@"Save Error", @"") longError:BRLocalizedString(@"Save Error", @"")];
516                }
517                [resultingMovie release];
518                [joinList removeAllObjects];
519                [SapphireMetaDataSupport save:moc];
520                return [errorDisplay autorelease];
521        }
522        @catch (NSException * e) {
523                [SapphireApplianceController logException:e];
524        }
525        return nil;
526}
527
528- (long)itemCount
529{
530    // return the number of items in your menu list here
531        return [marks count];
532}
533
534- (id<BRMenuItemLayer>)itemForRow:(long)row
535{
536        /*
537         // build a BRTextMenuItemLayer or a BRAdornedMenuItemLayer, etc. here
538         // return that object, it will be used to display the list item.
539         return ( nil );
540         */
541        if(row >= [marks count])
542                return nil;
543       
544        BRAdornedMenuItemLayer *result = nil;
545        NSDictionary *mark = [marks objectAtIndex:row];
546        NSString *name = [mark objectForKey:MARK_NAME];
547        result = [SapphireFrontRowCompat textMenuItemForScene:[self scene] folder:NO];
548       
549        // add text
550        [SapphireFrontRowCompat setTitle:name forMenu:result];
551                               
552        return result;
553}
554
555- (NSString *)titleForRow:(long)row
556{
557       
558        if(row >= [marks count])
559                return nil;
560       
561        NSString *result = [[marks objectAtIndex:row] objectForKey:MARK_NAME];
562        return result;
563}
564
565- (long)rowForTitle:(NSString *)title
566{
567    long result = -1;
568    long i, count = [self itemCount];
569    for(i = 0; i < count; i++)
570    {
571        if([title isEqualToString:[self titleForRow:i]])
572        {
573            result = i;
574            break;
575        }
576    }
577   
578    return result;
579}
580
581- (void)itemSelected:(long) row
582{
583    // This is called when the user presses play/pause on a list item
584        if(row >= [marks count])
585                return;
586       
587        NSManagedObjectContext *moc = [metaData managedObjectContext];
588        BRLayerController *replaceController = nil;
589        MarkCommand command = [[[marks objectAtIndex:row] objectForKey:MARK_COMMAND] intValue];
590        /*Do action on dir or file*/
591        if(isDir)
592        {
593                id <SapphireDirectory> dirMeta = (id <SapphireDirectory>)metaData;
594                SapphireCollectionDirectory *collection = nil;
595                if([dirMeta isKindOfClass:[SapphireDirectoryMetaData class]])
596                        collection = [(SapphireDirectoryMetaData *)dirMeta collectionDirectory];
597                NSString *path = [dirMeta path];
598                switch(command)
599                {
600                        case COMMAND_MARK_WATCHED:
601                                setSubtreeToWatched(dirMeta, YES);
602                                break;
603                        case COMMAND_MARK_UNWATCHED:
604                                setSubtreeToWatched(dirMeta, NO);
605                                break;
606                        case COMMAND_MARK_FAVORITE:
607                                setSubtreeToFavorite(dirMeta, YES);
608                                break;
609                        case COMMAND_MARK_NOT_FAVORITE:
610                                setSubtreeToFavorite(dirMeta, NO);
611                                break;
612                        case COMMAND_MARK_TO_REFETCH_TV:
613                                setSubtreeToReimportFromMask(dirMeta, IMPORT_TYPE_TVSHOW_MASK);
614                                break;
615                        case COMMAND_MARK_TO_REFETCH_MOVIE:
616                                setSubtreeToReimportFromMask(dirMeta, IMPORT_TYPE_MOVIE_MASK);
617                                break;
618                        case COMMAND_MARK_TO_DELETE_METADATA:
619                                setSubtreeToClearMetaData(dirMeta);
620                                break;
621                        case COMMAND_MARK_TO_RESET_IMPORT:
622                                setSubtreeToResetImportDecisions(dirMeta);
623                                break;
624                        case COMMAND_TOGGLE_SKIP:
625                                if(collection == nil)
626                                        [SapphireCollectionDirectory collectionAtPath:path mount:NO skip:YES hidden:NO manual:NO inContext:moc];
627                                else
628                                        [collection setSkipValue:![collection skipValue]];
629                                break;
630                        case COMMAND_TOGGLE_COLLECTION:
631                                if(collection == nil)
632                                        [SapphireCollectionDirectory collectionAtPath:path mount:NO skip:NO hidden:NO manual:YES inContext:moc];
633                                else
634                                        [moc deleteObject:collection];
635                                break;
636                        case COMMAND_RENAME:
637                                if([dirMeta isKindOfClass:[SapphireDirectoryMetaData class]])
638                                {
639                                        NSString *title = [NSString stringWithFormat:BRLocalizedString(@"Rename %@", @"Rename a collection, argument is path"), [dirMeta path]];
640                                        NSInvocation *invoke;
641                                        NSString *oldName;
642                                        if(collection == nil)
643                                        {
644                                                oldName = [[dirMeta path] lastPathComponent];
645                                                invoke = [NSInvocation invocationWithMethodSignature:[(SapphireDirectoryMetaData *)dirMeta methodSignatureForSelector:@selector(rename:)]];
646                                                [invoke setTarget:dirMeta];
647                                        }
648                                        else
649                                        {
650                                                oldName = [collection name];
651                                                if([oldName length] == 0)
652                                                        oldName = title;
653                                               
654                                                invoke = [NSInvocation invocationWithMethodSignature:[collection methodSignatureForSelector:@selector(rename:)]];
655                                                [invoke setTarget:collection];
656                                        }
657                                        [invoke setSelector:@selector(rename:)];
658                                        SapphireTextEntryController *rename = [[SapphireTextEntryController alloc] initWithScene:[self scene] title:title defaultText:oldName completionInvocation:invoke];
659                                        replaceController = [rename autorelease];
660                                }
661                                break;
662                        case COMMAND_RENAME_TO_PRETTY:
663                                doSubtreeInvokation(dirMeta, @selector(renameToPrettyName), nil);
664                                break;
665                        case COMMAND_CUT_PATH:
666                                [movingPath release];
667                                movingPath = [[dirMeta path] retain];
668                                break;
669                        case COMMAND_PASTE_PATH:
670                        {
671                                NSInvocation *invoke = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(pasteInDir:)]];
672                                [invoke setSelector:@selector(pasteInDir:)];
673                                [invoke setTarget:self];
674                                [invoke setArgument:&dirMeta atIndex:2];
675                               
676                                SapphireWaitDisplay *wait = [[SapphireWaitDisplay alloc] initWithScene:[self scene] title:[NSString stringWithFormat:BRLocalizedString(@"Moving %@", @"parameter is file/dir that is being moved"), [movingPath lastPathComponent]] invokation:invoke];
677                               
678                                replaceController = [wait autorelease];
679                        }
680                                break;
681                        case COMMAND_DELETE_PATH:
682                        {
683                                NSInvocation *invoke = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(deletePath:)]];
684                                [invoke setSelector:@selector(deletePath:)];
685                                [invoke setTarget:self];
686                                [invoke setArgument:&dirMeta atIndex:2];
687                               
688                                SapphireConfirmPrompt *confirm = [[SapphireConfirmPrompt alloc] initWithScene:[self scene] title:BRLocalizedString(@"Delete Directory?", @"") subtitle:[NSString stringWithFormat:BRLocalizedString(@"Are you sure you wish to delete %@?", @"parameter is file/dir that is being deleted"), [[dirMeta path] lastPathComponent]] invokation:invoke];
689                               
690                                replaceController = [confirm autorelease];
691                        }
692                }
693        }
694        else
695        {
696                SapphireFileMetaData *fileMeta = (SapphireFileMetaData *)metaData;
697                switch(command)
698                {
699                        case COMMAND_TOGGLE_WATCHED:
700                                [fileMeta setWatchedValue:![fileMeta watchedValue]];
701                                [fileMeta setResumeTime:0];
702                                break;
703                        case COMMAND_TOGGLE_FAVORITE:
704                                [fileMeta setFavoriteValue:![fileMeta favoriteValue]];
705                                break;
706                        case COMMAND_MARK_TO_REFETCH_TV:
707                                [fileMeta setToReimportFromMaskValue:IMPORT_TYPE_TVSHOW_MASK];
708                                break;
709                        case COMMAND_MARK_TO_REFETCH_MOVIE:
710                                [fileMeta setToReimportFromMaskValue:IMPORT_TYPE_MOVIE_MASK];
711                                break;
712                        case COMMAND_MARK_TO_DELETE_METADATA:
713                                [fileMeta clearMetaData];
714                                break;
715                        case COMMAND_MARK_TO_RESET_IMPORT:
716                                [fileMeta setToResetImportDecisions];
717                                break;
718                        case COMMAND_MARK_TO_JOIN:
719                                [joinList addObject:fileMeta];
720                                break;
721                        case COMMAND_CLEAR_JOIN_MARK:
722                                [joinList removeAllObjects];
723                                break;
724                        case COMMAND_MARK_AND_JOIN:
725                                [joinList addObject:fileMeta];
726                        case COMMAND_JOIN:
727                        {
728                                NSInvocation *invoke = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(doJoin:)]];
729                                [invoke setSelector:@selector(doJoin:)];
730                                [invoke setTarget:self];
731                               
732                                SapphireWaitDisplay *wait = [[SapphireWaitDisplay alloc] initWithScene:[self scene] title:BRLocalizedString(@"Joining Files", @"") invokation:invoke];
733                                [invoke setArgument:&wait atIndex:2];
734                               
735                                replaceController = [wait autorelease];
736                        }
737                                break;
738                        case COMMAND_RENAME:
739                        {
740                                NSString *title = [NSString stringWithFormat:BRLocalizedString(@"Rename %@", @"Rename a file, argument is path"), [fileMeta path]];
741                                NSString *oldName = [[[fileMeta path] lastPathComponent] stringByDeletingPathExtension];
742                               
743                                NSInvocation *invoke = [NSInvocation invocationWithMethodSignature:[fileMeta methodSignatureForSelector:@selector(rename:)]];
744                                [invoke setSelector:@selector(rename:)];
745                                [invoke setTarget:fileMeta];
746                                SapphireTextEntryController *rename = [[SapphireTextEntryController alloc] initWithScene:[self scene] title:title defaultText:oldName completionInvocation:invoke];
747                                replaceController = [rename autorelease];                               
748                        }
749                                break;
750                        case COMMAND_RENAME_TO_PRETTY:
751                        {
752                                NSString *error = [fileMeta renameToPrettyName];
753                                if(error != nil)
754                                        replaceController = [[[SapphireErrorDisplayController alloc] initWithScene:[self scene] error:BRLocalizedString(@"Error", @"") longError:error] autorelease];
755                        }
756                        case COMMAND_CUT_PATH:
757                                [movingPath release];
758                                movingPath = [[fileMeta path] retain];
759                                break;                         
760                        case COMMAND_DELETE_PATH:
761                        {
762                                NSInvocation *invoke = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(deletePath:)]];
763                                [invoke setSelector:@selector(deletePath:)];
764                                [invoke setTarget:self];
765                                [invoke setArgument:&fileMeta atIndex:2];
766                               
767                                SapphireConfirmPrompt *confirm = [[SapphireConfirmPrompt alloc] initWithScene:[self scene] title:BRLocalizedString(@"Delete File?", @"") subtitle:[NSString stringWithFormat:BRLocalizedString(@"Are you sure you wish to delete %@?", @"parameter is file/dir that is being deleted"), [[fileMeta path] lastPathComponent]] invokation:invoke];
768                               
769                                replaceController = [confirm autorelease];
770                        }
771                                break;
772                        case COMMAND_CHANGE_ARTWORK:
773                                replaceController = [self loadArtwork:fileMeta];
774                                break;
775                }
776        }
777        /*Save and exit*/
778        [SapphireMetaDataSupport save:moc];
779        if(replaceController != nil)
780                [[self stack] swapController:replaceController];
781        else
782                [[self stack] popController];
783}
784
785- (BRControl *)pasteInDir:(SapphireDirectoryMetaData *)dirMeta
786{
787        NSManagedObjectContext *moc = [metaData managedObjectContext];
788        SapphireMetaData *meta = [SapphireMetaData metaDataWithPath:movingPath inContext:moc];
789        NSString *errorString = nil;
790        if([meta isKindOfClass:[SapphireDirectoryMetaData class]])
791        {
792                SapphireDirectoryMetaData *dir = (SapphireDirectoryMetaData *)meta;
793                errorString = [dir moveToDir:dirMeta];
794        }
795        else if([meta isKindOfClass:[SapphireFileMetaData class]])
796        {
797                SapphireFileMetaData *file = (SapphireFileMetaData *)meta;
798                errorString = [file moveToDir:dirMeta];
799        }
800        else
801                errorString = [NSString stringWithFormat:BRLocalizedString(@"%@ Seems to be missing", @"Could not find file; parameter is moving file"), [movingPath lastPathComponent]];
802        if(errorString != nil)
803        {
804                SapphireErrorDisplayController *error = [[SapphireErrorDisplayController alloc] initWithScene:[self scene] error:BRLocalizedString(@"Moving Error", @"") longError:errorString];
805                return [error autorelease];
806        }
807        else
808        {
809                [movingPath release];
810                movingPath = nil;
811        }
812        [SapphireMetaDataSupport save:moc];
813        return nil;
814}
815
816- (BRControl *)deletePath:(SapphireMetaData *)meta
817{
818        @try {
819                NSManagedObjectContext *moc = [meta managedObjectContext];
820                BOOL success = [[NSFileManager defaultManager] removeFileAtPath:[meta path] handler:nil];
821                if(!success)
822                {
823                        NSString *errorString = [NSString stringWithFormat:BRLocalizedString(@"Could not delete %@.  Is the filesystem read-only?", @"Unknown error renaming file/directory; parameter is name"), [[meta path] lastPathComponent]];
824                        SapphireErrorDisplayController *error = [[SapphireErrorDisplayController alloc] initWithScene:[self scene] error:BRLocalizedString(@"Delete Error", @"") longError:errorString];
825                        return [error autorelease];
826                }
827                [moc deleteObject:meta];
828                [SapphireMetaDataSupport save:moc];
829                return nil;
830        }
831        @catch (NSException * e) {
832                [SapphireApplianceController logException:e];
833        }
834        return nil;
835}
836
837- (id<BRMediaPreviewController>)previewControlForItem:(long)item
838{
839        return [self previewControllerForItem:item];
840}
841
842- (id<BRMediaPreviewController>)previewControllerForItem:(long)item
843{
844    // If subclassing BRMediaMenuController, this function is called when the selection cursor
845    // passes over an item.
846                if(item >= [marks count])
847                return nil;
848        else
849        {
850                /* Get setting name & kill cushion  */
851                NSDictionary *mark = [marks objectAtIndex:item];
852                NSString *markName = [NSString stringWithFormat:@"%@ for \"%@\"",[mark objectForKey:MARK_NAME],(NSString *)[self listTitle]];
853                NSString *markDescription = [mark objectForKey:MARK_DESCRIPTION];
854                /* Construct a gerneric metadata asset for display */
855                NSMutableDictionary *markMeta=[[NSMutableDictionary alloc] init];
856                [markMeta setObject:markName forKey:META_TITLE_KEY];
857                [markMeta setObject:[NSNumber numberWithInt:FILE_CLASS_UTILITY] forKey:FILE_CLASS_KEY];
858                [markMeta setObject:markDescription forKey:META_DESCRIPTION_KEY];
859                SapphireMediaPreview *preview = [[SapphireMediaPreview alloc] initWithScene:[self scene]];
860                [preview setUtilityData:markMeta];
861                [markMeta release];
862                [preview setShowsMetadataImmediately:YES];
863                /*And go*/
864                return [preview autorelease];
865        }
866    return ( nil );
867}
868
869@end
Note: See TracBrowser for help on using the repository browser.