diff options
Diffstat (limited to 'macosx/HBSubtitles.m')
-rw-r--r-- | macosx/HBSubtitles.m | 509 |
1 files changed, 262 insertions, 247 deletions
diff --git a/macosx/HBSubtitles.m b/macosx/HBSubtitles.m index 85b69ac10..8368c2c74 100644 --- a/macosx/HBSubtitles.m +++ b/macosx/HBSubtitles.m @@ -1,38 +1,34 @@ -// -// HBSubtitles.m -// HandBrake -// -// Created by Damiano Galassi on 12/01/15. -// -// +/* HBSubtitles.m $ + + This file is part of the HandBrake source code. + Homepage: <http://handbrake.fr/>. + It may be used under the terms of the GNU General Public License. */ #import "HBSubtitles.h" #import "HBSubtitlesDefaults.h" +#import "HBSubtitlesTrack.h" + #import "HBTitle.h" #import "HBCodingUtilities.h" -#include "lang.h" #include "common.h" -NSString *keySubTrackSelectionIndex = @"keySubTrackSelectionIndex"; -NSString *keySubTrackName = @"keySubTrackName"; -NSString *keySubTrackIndex = @"keySubTrackIndex"; -NSString *keySubTrackLanguage = @"keySubTrackLanguage"; -NSString *keySubTrackLanguageIsoCode = @"keySubTrackLanguageIsoCode"; -NSString *keySubTrackType = @"keySubTrackType"; +extern NSString *keySubTrackName; +extern NSString *keySubTrackLanguageIsoCode; +extern NSString *keySubTrackType; + +extern NSString *keySubTrackSrtFileURL; -NSString *keySubTrackForced = @"keySubTrackForced"; -NSString *keySubTrackBurned = @"keySubTrackBurned"; -NSString *keySubTrackDefault = @"keySubTrackDefault"; +#define NONE_TRACK_INDEX 0 +#define FOREIGN_TRACK_INDEX 1 -NSString *keySubTrackSrtOffset = @"keySubTrackSrtOffset"; -NSString *keySubTrackSrtFilePath = @"keySubTrackSrtFilePath"; -NSString *keySubTrackSrtCharCode = @"keySubTrackSrtCharCode"; -NSString *keySubTrackSrtCharCodeIndex = @"keySubTrackSrtCharCodeIndex"; -NSString *keySubTrackLanguageIndex = @"keySubTrackLanguageIndex"; +@interface HBSubtitles () <HBTrackDataSource, HBTrackDelegate> -#define CHAR_CODE_DEFAULT_INDEX 11 +/// Used to aovid circular dependecy validation. +@property (nonatomic, readwrite) BOOL validating; + +@end @implementation HBSubtitles @@ -43,72 +39,167 @@ NSString *keySubTrackLanguageIndex = @"keySubTrackLanguageIndex"; { _container = HB_MUX_MP4; + _sourceTracks = [title.subtitlesTracks mutableCopy]; _tracks = [[NSMutableArray alloc] init]; _defaults = [[HBSubtitlesDefaults alloc] init]; - _masterTrackArray = [title.subtitlesTracks mutableCopy]; - - NSMutableArray *forcedSourceNamesArray = [NSMutableArray array]; - for (NSDictionary *dict in _masterTrackArray) + NSMutableSet<NSString *> *forcedSourceNamesArray = [NSMutableSet set]; + int foreignAudioType = VOBSUB; + for (NSDictionary *dict in _sourceTracks) { enum subsource source = [dict[keySubTrackType] intValue]; - NSString *subSourceName = @(hb_subsource_name(source)); + NSString *name = @(hb_subsource_name(source)); // if the subtitle track can be forced, add its source name to the array - if (hb_subtitle_can_force(source) && [forcedSourceNamesArray containsObject:subSourceName] == NO) + if (hb_subtitle_can_force(source) && name.length) { - [forcedSourceNamesArray addObject:subSourceName]; + [forcedSourceNamesArray addObject:name]; } } // now set the name of the Foreign Audio Search track + NSMutableString *foreignAudioSearchTrackName = [@"Foreign Audio Search (Bitmap)" mutableCopy]; if (forcedSourceNamesArray.count) { - [forcedSourceNamesArray sortUsingComparator:^(id obj1, id obj2) - { - return [((NSString *)obj1) compare:((NSString *)obj2)]; - }]; + [foreignAudioSearchTrackName appendFormat:@" ("]; + for (NSString *name in forcedSourceNamesArray) + { + [foreignAudioSearchTrackName appendFormat:@"%@, ", name]; + } + [foreignAudioSearchTrackName deleteCharactersInRange:NSMakeRange(foreignAudioSearchTrackName.length - 2, 2)]; + [foreignAudioSearchTrackName appendFormat:@")"]; + } - NSString *tempList = @""; - for (NSString *tempString in forcedSourceNamesArray) + // Add the none and foreign track to the source array + NSDictionary *none = @{ keySubTrackName: NSLocalizedString(@"None", nil)}; + [_sourceTracks insertObject:none atIndex:0]; + + NSDictionary *foreign = @{ keySubTrackName: foreignAudioSearchTrackName, + keySubTrackType: @(foreignAudioType) }; + [_sourceTracks insertObject:foreign atIndex:1]; + + } + return self; +} + +#pragma mark - Data Source + +- (NSDictionary<NSString *, id> *)sourceTrackAtIndex:(NSUInteger)idx; +{ + return self.sourceTracks[idx]; +} + +- (NSArray<NSString *> *)sourceTracksArray +{ + NSMutableArray *sourceNames = [NSMutableArray array]; + + for (NSDictionary *track in self.sourceTracks) + { + [sourceNames addObject:track[keySubTrackName]]; + } + + return sourceNames; +} + +#pragma mark - Delegate + +- (void)track:(HBSubtitlesTrack *)track didChangeSourceFrom:(NSUInteger)oldSourceIdx; +{ + // If the source was changed to None, remove the track + if (track.sourceTrackIdx == NONE_TRACK_INDEX) + { + NSUInteger idx = [self.tracks indexOfObject:track]; + [self removeObjectFromTracksAtIndex:idx]; + } + // If the source was changed to Foreign Audio Track, + // insert it at top if it wasn't already there + else if (track.sourceTrackIdx == FOREIGN_TRACK_INDEX) + { + NSUInteger idx = [self.tracks indexOfObject:track]; + if (idx != 0) + { + [self removeObjectFromTracksAtIndex:idx]; + if (self.tracks[0].sourceTrackIdx != FOREIGN_TRACK_INDEX) { - if (tempList.length) - { - tempList = [tempList stringByAppendingString:@", "]; - } - tempList = [tempList stringByAppendingString:tempString]; + [self insertObject:track inTracksAtIndex:0]; } - self.foreignAudioSearchTrackName = [NSString stringWithFormat:@"Foreign Audio Search (Bitmap) (%@)", tempList]; } - else + [self addNoneTrack]; + } + // Else add a new None track + else if (oldSourceIdx == NONE_TRACK_INDEX) + { + [self addNoneTrack]; + } + [self validatePassthru]; +} + +- (BOOL)canSetBurnedInOption:(HBSubtitlesTrack *)track +{ + BOOL result = YES; + for (HBSubtitlesTrack *subTrack in self.tracks) + { + if (subTrack != track && subTrack.isEnabled + && subTrack.sourceTrackIdx > FOREIGN_TRACK_INDEX && !subTrack.canPassthru) { - self.foreignAudioSearchTrackName = @"Foreign Audio Search (Bitmap)"; + result = NO; } } - return self; + return result; } -- (void)addAllTracks +- (void)didSetBurnedInOption:(HBSubtitlesTrack *)track { - [self.tracks removeAllObjects]; + if (self.validating == NO && track.sourceTrackIdx != FOREIGN_TRACK_INDEX) + { + self.validating = YES; + NSUInteger idx = [self.tracks indexOfObject:track]; + [self validateBurned:idx]; + self.validating = NO; + } +} - // Add the foreign audio search pass - [self addTrack:[self trackFromSourceTrackIndex:-1]]; +- (void)didSetDefaultOption:(HBSubtitlesTrack *)track +{ + if (self.validating == NO && track.sourceTrackIdx != FOREIGN_TRACK_INDEX) + { + self.validating = YES; + NSUInteger idx = [self.tracks indexOfObject:track]; + [self validateDefault:idx]; + self.validating = NO; + } +} - // Add the remainings tracks - for (NSDictionary *track in self.masterTrackArray) +- (void)addNoneTrack +{ + HBSubtitlesTrack *track = [self trackFromSourceTrackIndex:NONE_TRACK_INDEX]; + [self addTrack:track]; +} + +#pragma mark - Public methods + +- (void)addAllTracks +{ + while (self.countOfTracks) { - NSInteger sourceIndex = [track[keySubTrackIndex] integerValue]; - [self addTrack:[self trackFromSourceTrackIndex:sourceIndex]]; + [self removeObjectFromTracksAtIndex:0]; } - [self.tracks addObject:[self createSubtitleTrack]]; + // Add the remainings tracks + for (NSUInteger idx = 1; idx < self.sourceTracksArray.count; idx++) { + [self addTrack:[self trackFromSourceTrackIndex:idx]]; + } + + [self addNoneTrack]; [self validatePassthru]; } - (void)removeAll { - [self.tracks removeAllObjects]; - [self.tracks addObject:[self createSubtitleTrack]]; + while (self.countOfTracks) + { + [self removeObjectFromTracksAtIndex:0]; + } + [self addNoneTrack]; } - (void)reloadDefaults @@ -116,116 +207,63 @@ NSString *keySubTrackLanguageIndex = @"keySubTrackLanguageIndex"; [self addTracksFromDefaults]; } -// This gets called whenever the video container changes. -- (void)containerChanged:(int)container +- (void)addSrtTrackFromURL:(NSURL *)srtURL { - self.container = container; + // Create a new entry for the subtitle source array so it shows up in our subtitle source list + [self.sourceTracks addObject:@{keySubTrackName: srtURL.lastPathComponent, + keySubTrackType: @(SRTSUB), + keySubTrackSrtFileURL: srtURL}]; + HBSubtitlesTrack *track = [self trackFromSourceTrackIndex:self.sourceTracksArray.count - 1]; + [self insertObject:track inTracksAtIndex:[self countOfTracks] - 1]; +} - [self validatePassthru]; +- (void)setContainer:(int)container +{ + _container = container; + for (HBSubtitlesTrack *track in self.tracks) + { + track.container = container; + } + if (!(self.undo.isUndoing || self.undo.isRedoing)) + { + [self validatePassthru]; + } +} + +- (void)setUndo:(NSUndoManager *)undo +{ + _undo = undo; + for (HBSubtitlesTrack *track in self.tracks) + { + track.undo = undo; + } } /** * Convenience method to add a track to subtitlesArray. - * It calculates the keySubTrackSelectionIndex. * * @param track the track to add. */ -- (void)addTrack:(NSMutableDictionary *)newTrack +- (void)addTrack:(HBSubtitlesTrack *)newTrack { - newTrack[keySubTrackSelectionIndex] = @([newTrack[keySubTrackIndex] integerValue] + 1 + (self.tracks.count == 0)); [self insertObject:newTrack inTracksAtIndex:[self countOfTracks]]; } /** - * Creates a new subtitle track. - */ -- (NSMutableDictionary *)createSubtitleTrack -{ - NSMutableDictionary *newSubtitleTrack = [[NSMutableDictionary alloc] init]; - newSubtitleTrack[keySubTrackIndex] = @(-2); - newSubtitleTrack[keySubTrackSelectionIndex] = @0; - newSubtitleTrack[keySubTrackName] = @"None"; - newSubtitleTrack[keySubTrackForced] = @0; - newSubtitleTrack[keySubTrackBurned] = @0; - newSubtitleTrack[keySubTrackDefault] = @0; - - return newSubtitleTrack; -} - -/** * Creates a new track dictionary from a source track. * - * @param index the index of the source track in the subtitlesSourceArray, - * -1 means a Foreign Audio Search pass. - * - * @return a new mutable track dictionary. + * @param index the index of the source track in the subtitlesSourceArray */ -- (NSMutableDictionary *)trackFromSourceTrackIndex:(NSInteger)index +- (HBSubtitlesTrack *)trackFromSourceTrackIndex:(NSInteger)index { - NSMutableDictionary *track = [self createSubtitleTrack]; - - if (index == -1) - { - /* - * we are foreign lang search, which is inherently bitmap - * - * since it can be either VOBSUB or PGS and the latter can't be - * passed through to MP4, we need to know whether there are any - * PGS tracks in the source - otherwise we can just set the - * source track type to VOBSUB - */ - int subtitleTrackType = VOBSUB; - if ([self.foreignAudioSearchTrackName rangeOfString:@(hb_subsource_name(PGSSUB))].location != NSNotFound) - { - subtitleTrackType = PGSSUB; - } - // Use -1 to indicate the foreign lang search - track[keySubTrackIndex] = @(-1); - track[keySubTrackName] = self.foreignAudioSearchTrackName; - track[keySubTrackType] = @(subtitleTrackType); - // foreign lang search is most useful when combined w/Forced Only - make it default - track[keySubTrackForced] = @1; - } - else - { - NSDictionary *sourceTrack = self.masterTrackArray[index]; - - track[keySubTrackIndex] = @(index); - track[keySubTrackName] = sourceTrack[keySubTrackName]; - - /* check to see if we are an srt, in which case set our file path and source track type kvp's*/ - if ([self.masterTrackArray[index][keySubTrackType] intValue] == SRTSUB) - { - track[keySubTrackType] = @(SRTSUB); - track[keySubTrackSrtFilePath] = sourceTrack[keySubTrackSrtFilePath]; - - track[keySubTrackLanguageIndex] = @(self.languagesArrayDefIndex); - track[keySubTrackLanguageIsoCode] = self.languagesArray[self.languagesArrayDefIndex][1]; - - track[keySubTrackSrtCharCodeIndex] = @(CHAR_CODE_DEFAULT_INDEX); - track[keySubTrackSrtCharCode] = self.charCodeArray[CHAR_CODE_DEFAULT_INDEX]; - } - else - { - track[keySubTrackType] = sourceTrack[keySubTrackType]; - } - } - - if (!hb_subtitle_can_burn([track[keySubTrackType] intValue])) - { - /* the source track cannot be burned in, so uncheck the widget */ - track[keySubTrackBurned] = @0; - } - - if (!hb_subtitle_can_force([track[keySubTrackType] intValue])) - { - /* the source track does not support forced flags, so uncheck the widget */ - track[keySubTrackForced] = @0; - } - + HBSubtitlesTrack *track = [[HBSubtitlesTrack alloc] initWithTrackIdx:index container:self.container + dataSource:self delegate:self]; + track.undo = self.undo; return track; } +#pragma mark - Defaults + /** * Remove all the subtitles tracks and * add new ones based on the defaults settings @@ -236,12 +274,15 @@ NSString *keySubTrackLanguageIndex = @"keySubTrackLanguageIndex"; // so we don't add the same track twice. NSMutableIndexSet *tracksAdded = [NSMutableIndexSet indexSet]; - [self.tracks removeAllObjects]; + while (self.countOfTracks) + { + [self removeObjectFromTracksAtIndex:0]; + } // Add the foreign audio search pass if (self.defaults.addForeignAudioSearch) { - [self addTrack:[self trackFromSourceTrackIndex:-1]]; + [self addTrack:[self trackFromSourceTrackIndex:FOREIGN_TRACK_INDEX]]; } // Add the tracks for the selected languages @@ -249,23 +290,24 @@ NSString *keySubTrackLanguageIndex = @"keySubTrackLanguageIndex"; { for (NSString *lang in self.defaults.trackSelectionLanguages) { - for (NSDictionary *track in self.masterTrackArray) + NSUInteger idx = 0; + for (NSDictionary *track in self.sourceTracks) { - if ([lang isEqualToString:@"und"] || [track[keySubTrackLanguageIsoCode] isEqualToString:lang]) + if (idx > FOREIGN_TRACK_INDEX && + ([lang isEqualToString:@"und"] || [track[keySubTrackLanguageIsoCode] isEqualToString:lang])) { - NSInteger sourceIndex = [track[keySubTrackIndex] intValue]; - - if (![tracksAdded containsIndex:sourceIndex]) + if (![tracksAdded containsIndex:idx]) { - [self addTrack:[self trackFromSourceTrackIndex:sourceIndex]]; + [self addTrack:[self trackFromSourceTrackIndex:idx]]; } - [tracksAdded addIndex:sourceIndex]; + [tracksAdded addIndex:idx]; if (self.defaults.trackSelectionBehavior == HBSubtitleTrackSelectionBehaviorFirst) { break; } } + idx++; } } } @@ -273,14 +315,14 @@ NSString *keySubTrackLanguageIndex = @"keySubTrackLanguageIndex"; // Add the closed captions track if there is one. if (self.defaults.addCC) { - for (NSDictionary *track in self.masterTrackArray) + NSUInteger idx = 0; + for (NSDictionary *track in self.sourceTracks) { if ([track[keySubTrackType] intValue] == CC608SUB) { - NSInteger sourceIndex = [track[keySubTrackIndex] intValue]; - if (![tracksAdded containsIndex:sourceIndex]) + if (![tracksAdded containsIndex:idx]) { - [self addTrack:[self trackFromSourceTrackIndex:sourceIndex]]; + [self addTrack:[self trackFromSourceTrackIndex:idx]]; } if (self.defaults.trackSelectionBehavior == HBSubtitleTrackSelectionBehaviorFirst) @@ -288,6 +330,7 @@ NSString *keySubTrackLanguageIndex = @"keySubTrackLanguageIndex"; break; } } + idx++; } } @@ -296,25 +339,26 @@ NSString *keySubTrackLanguageIndex = @"keySubTrackLanguageIndex"; { if (self.defaults.burnInBehavior == HBSubtitleTrackBurnInBehaviorFirst) { - if ([self.tracks.firstObject[keySubTrackIndex] integerValue] != -1) + if (self.tracks.firstObject.sourceTrackIdx != FOREIGN_TRACK_INDEX) { - self.tracks.firstObject[keySubTrackBurned] = @YES; + self.tracks.firstObject.burnedIn = YES; } else if (self.tracks.count > 1) { - self.tracks[1][keySubTrackBurned] = @YES; + self.tracks[0].burnedIn = NO; + self.tracks[1].burnedIn = YES; } } else if (self.defaults.burnInBehavior == HBSubtitleTrackBurnInBehaviorForeignAudio) { - if ([self.tracks.firstObject[keySubTrackIndex] integerValue] == -1) + if (self.tracks.firstObject.sourceTrackIdx == FOREIGN_TRACK_INDEX) { - self.tracks.firstObject[keySubTrackBurned] = @YES; + self.tracks.firstObject.burnedIn = YES; } } else if (self.defaults.burnInBehavior == HBSubtitleTrackBurnInBehaviorForeignAudioThenFirst) { - self.tracks.firstObject[keySubTrackBurned] = @YES; + self.tracks.firstObject.burnedIn = YES; } } @@ -325,18 +369,18 @@ NSString *keySubTrackLanguageIndex = @"keySubTrackLanguageIndex"; BOOL bitmapSubtitlesFound = NO; NSMutableArray *tracksToDelete = [[NSMutableArray alloc] init]; - for (NSMutableDictionary *track in self.tracks) + for (HBSubtitlesTrack *track in self.tracks) { - if ([track[keySubTrackIndex] integerValue] != -1) + if (track.sourceTrackIdx != 1) { - if ((([track[keySubTrackType] intValue] == VOBSUB && self.defaults.burnInDVDSubtitles) || - ([track[keySubTrackType] intValue] == PGSSUB && self.defaults.burnInBluraySubtitles)) && + if (((track.type == VOBSUB && self.defaults.burnInDVDSubtitles) || + (track.type == PGSSUB && self.defaults.burnInBluraySubtitles)) && !bitmapSubtitlesFound) { - track[keySubTrackBurned] = @YES; + track.burnedIn = YES; bitmapSubtitlesFound = YES; } - else if ([track[keySubTrackType] intValue] == VOBSUB || [track[keySubTrackType] intValue] == PGSSUB) + else if (track.type == VOBSUB || track.type == PGSSUB) { [tracksToDelete addObject:track]; } @@ -346,10 +390,12 @@ NSString *keySubTrackLanguageIndex = @"keySubTrackLanguageIndex"; } // Add an empty track - [self insertObject:[self createSubtitleTrack] inTracksAtIndex:[self countOfTracks]]; + [self addNoneTrack]; [self validatePassthru]; } +#pragma mark - Validation + /** * Checks whether any subtitles in the list cannot be passed through. * Set the first of any such subtitles to burned-in, remove the others. @@ -357,103 +403,70 @@ NSString *keySubTrackLanguageIndex = @"keySubTrackLanguageIndex"; - (void)validatePassthru { BOOL convertToBurnInUsed = NO; - NSMutableArray *tracksToDelete = [[NSMutableArray alloc] init]; + NSMutableIndexSet *tracksToDelete = [[NSMutableIndexSet alloc] init]; // convert any non-None incompatible tracks to burn-in or remove them - for (NSMutableDictionary *track in self.tracks) + NSUInteger idx = 0; + for (HBSubtitlesTrack *track in self.tracks) { - if (track[keySubTrackType] == nil) - { - continue; - } - - int subtitleTrackType = [track[keySubTrackType] intValue]; - if (!hb_subtitle_can_pass(subtitleTrackType, self.container)) + if (track.isEnabled && track.sourceTrackIdx > FOREIGN_TRACK_INDEX && !track.canPassthru) { if (convertToBurnInUsed == NO) { //we haven't set any track to burned-in yet, so we can - track[keySubTrackBurned] = @1; + track.burnedIn = YES; convertToBurnInUsed = YES; //remove any additional tracks } else { //we already have a burned-in track, we must remove others - [tracksToDelete addObject:track]; + [tracksToDelete addIndex:idx]; } } + idx++; } + //if we converted a track to burned-in, unset it for tracks that support passthru if (convertToBurnInUsed == YES) { - for (NSMutableDictionary *track in self.tracks) + for (HBSubtitlesTrack *track in self.tracks) { - if (track[keySubTrackType] == nil) + if (track.isEnabled && track.sourceTrackIdx > FOREIGN_TRACK_INDEX && track.canPassthru) { - continue; - } - - int subtitleTrackType = [track[keySubTrackType] intValue]; - if (hb_subtitle_can_pass(subtitleTrackType, self.container)) - { - track[keySubTrackBurned] = @0; + track.burnedIn = NO; } } } - [self willChangeValueForKey:@"tracks"]; - if (tracksToDelete.count) - { - [self.tracks removeObjectsInArray:tracksToDelete]; - } - [self didChangeValueForKey:@"tracks"]; - -} - -#pragma mark - Languages - -@synthesize languagesArray = _languagesArray; - -- (NSArray *)languagesArray -{ - if (!_languagesArray) + // Delete the tracks + NSUInteger currentIndex = [tracksToDelete lastIndex]; + while (currentIndex != NSNotFound) { - _languagesArray = [self populateLanguageArray]; + [self removeObjectFromTracksAtIndex:currentIndex]; + currentIndex = [tracksToDelete indexLessThanIndex:currentIndex]; } - - return _languagesArray; } -- (NSArray *)populateLanguageArray +- (void)validateBurned:(NSUInteger)index { - NSMutableArray *languages = [[NSMutableArray alloc] init]; - - for (const iso639_lang_t * lang = lang_get_next(NULL); lang != NULL; lang = lang_get_next(lang)) + [self.tracks enumerateObjectsUsingBlock:^(HBSubtitlesTrack *track, NSUInteger idx, BOOL *stop) { - [languages addObject:@[@(lang->eng_name), - @(lang->iso639_2)]]; - if (!strcasecmp(lang->eng_name, "English")) + if (idx != index && track.sourceTrackIdx != FOREIGN_TRACK_INDEX) { - _languagesArrayDefIndex = [languages count] - 1; + track.burnedIn = NO; } - } - return [languages copy]; + }]; } -@synthesize charCodeArray = _charCodeArray; - -- (NSArray *)charCodeArray +- (void)validateDefault:(NSUInteger)index { - if (!_charCodeArray) + [self.tracks enumerateObjectsUsingBlock:^(HBSubtitlesTrack *obj, NSUInteger idx, BOOL *stop) { - // populate the charCodeArray. - _charCodeArray = @[@"ANSI_X3.4-1968", @"ANSI_X3.4-1986", @"ANSI_X3.4", @"ANSI_X3.110-1983", @"ANSI_X3.110", @"ASCII", - @"ECMA-114", @"ECMA-118", @"ECMA-128", @"ECMA-CYRILLIC", @"IEC_P27-1", @"ISO-8859-1", @"ISO-8859-2", - @"ISO-8859-3", @"ISO-8859-4", @"ISO-8859-5", @"ISO-8859-6", @"ISO-8859-7", @"ISO-8859-8", @"ISO-8859-9", - @"ISO-8859-9E", @"ISO-8859-10", @"ISO-8859-11", @"ISO-8859-13", @"ISO-8859-14", @"ISO-8859-15", @"ISO-8859-16", - @"UTF-7", @"UTF-8", @"UTF-16", @"UTF-16LE", @"UTF-16BE", @"UTF-32", @"UTF-32LE", @"UTF-32BE"]; - } - return _charCodeArray; + if (idx != index && obj.sourceTrackIdx != FOREIGN_TRACK_INDEX) + { + obj.def = NO; + } + }]; } #pragma mark - NSCopying @@ -465,15 +478,13 @@ NSString *keySubTrackLanguageIndex = @"keySubTrackLanguageIndex"; if (copy) { copy->_container = _container; - - copy->_masterTrackArray = [_masterTrackArray mutableCopy]; - copy->_foreignAudioSearchTrackName = [_foreignAudioSearchTrackName copy]; + copy->_sourceTracks = [_sourceTracks mutableCopy]; copy->_tracks = [[NSMutableArray alloc] init]; [_tracks enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { if (idx < _tracks.count) { - NSMutableDictionary *trackCopy = [obj copy]; + id trackCopy = [obj copy]; [copy->_tracks addObject:trackCopy]; } }]; @@ -493,14 +504,11 @@ NSString *keySubTrackLanguageIndex = @"keySubTrackLanguageIndex"; - (void)encodeWithCoder:(NSCoder *)coder { - [coder encodeInt:1 forKey:@"HBAudioVersion"]; + [coder encodeInt:1 forKey:@"HBSubtitlesVersion"]; encodeInt(_container); - - encodeObject(_masterTrackArray); - encodeObject(_foreignAudioSearchTrackName); + encodeObject(_sourceTracks); encodeObject(_tracks); - encodeObject(_defaults); } @@ -509,11 +517,15 @@ NSString *keySubTrackLanguageIndex = @"keySubTrackLanguageIndex"; self = [super init]; decodeInt(_container); - - decodeObject(_masterTrackArray, NSMutableArray); - decodeObject(_foreignAudioSearchTrackName, NSString); + decodeObject(_sourceTracks, NSMutableArray); decodeObject(_tracks, NSMutableArray); + for (HBSubtitlesTrack *track in _tracks) + { + track.dataSource = self; + track.delegate = self; + } + decodeObject(_defaults, HBSubtitlesDefaults); return self; @@ -535,23 +547,26 @@ NSString *keySubTrackLanguageIndex = @"keySubTrackLanguageIndex"; #pragma mark - #pragma mark KVC -- (NSUInteger) countOfTracks +- (NSUInteger)countOfTracks { return self.tracks.count; } -- (id)objectInTracksAtIndex:(NSUInteger)index +- (HBSubtitlesTrack *)objectInTracksAtIndex:(NSUInteger)index { return self.tracks[index]; } -- (void)insertObject:(id)track inTracksAtIndex:(NSUInteger)index; +- (void)insertObject:(HBSubtitlesTrack *)track inTracksAtIndex:(NSUInteger)index; { + [[self.undo prepareWithInvocationTarget:self] removeObjectFromTracksAtIndex:index]; [self.tracks insertObject:track atIndex:index]; } - (void)removeObjectFromTracksAtIndex:(NSUInteger)index { + HBSubtitlesTrack *track = self.tracks[index]; + [[self.undo prepareWithInvocationTarget:self] insertObject:track inTracksAtIndex:index]; [self.tracks removeObjectAtIndex:index]; } |