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