From 61ee3250a66a273d3bf7b7594b5b8656993bc33f Mon Sep 17 00:00:00 2001 From: dynaflash Date: Sat, 13 Jun 2009 19:50:12 +0000 Subject: [PATCH] MacGui: Multiple subtitle tracks initial implementation - Subtitles now get their own tab - "None" track is an empty track, add a new subtitle track by switching it to a valid source track. - First track allows for "Foreign Language Search" which replaces the old "Auto Select". - Remove a previously selected track by setting it back to "None" - Sanity Checks: -- Allow only one Burned In track. -- Text tracks do not allow burned in to be set. -- MP4 specific: --- Allow only one VobSub and force burned in to be set. ---- Trying to set more than one vobsub in mp4 results in a warning, and the first vobsub track is retained. - Presets: Currently subtitles are not recorded into presets (which they never have been). - Live Preview: -- Foreign Language Search is borked for live preview, so is ignored -- Burned in subtitles work for both mp4 and mkv -- Text subtitles work for mp4 if set to default (preview has no way to turn soft subs on/off) -- Text subtitles do not show up in preview window even if checked as default. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@2530 b64f7644-9d1e-0410-96f1-a4d463321fa5 --- macosx/Controller.h | 15 +- macosx/Controller.mm | 403 +++++++--- macosx/English.lproj/MainMenu.xib | 893 ++++++++++++--------- macosx/HBQueueController.mm | 34 + macosx/HBSubtitles.h | 44 + macosx/HBSubtitles.m | 444 ++++++++++ macosx/HandBrake.xcodeproj/project.pbxproj | 10 +- 7 files changed, 1370 insertions(+), 473 deletions(-) create mode 100644 macosx/HBSubtitles.h create mode 100644 macosx/HBSubtitles.m diff --git a/macosx/Controller.h b/macosx/Controller.h index 87e7cd6a7..798e44393 100644 --- a/macosx/Controller.h +++ b/macosx/Controller.h @@ -10,6 +10,7 @@ #include "hb.h" #import "ChapterTitles.h" +#import "HBSubtitles.h" #import "PictureController.h" #import "HBPreviewController.h" #import "HBQueueController.h" @@ -70,7 +71,8 @@ BOOL fIsDragging; IBOutlet NSTextField * fSrcTitleField; IBOutlet NSPopUpButton * fSrcTitlePopUp; - /* Angle selection popup (only used for libdvdnav */ + + /* lib dvd nav specific */ IBOutlet NSTextField * fSrcAngleLabel; IBOutlet NSPopUpButton * fSrcAnglePopUp; @@ -132,6 +134,12 @@ BOOL fIsDragging; IBOutlet NSTextField * fSubField; IBOutlet NSPopUpButton * fSubPopUp; IBOutlet NSButton * fSubForcedCheck; + + + IBOutlet NSTableView * fSubtitlesTable; + HBSubtitles * fSubtitlesDelegate; + //NSMutableArray * subtitleArray; + /* Audio box */ /* Track Labels */ @@ -287,7 +295,6 @@ BOOL fIsDragging; - (IBAction) audioTrackPopUpChanged: (id) sender; - (IBAction) audioTrackPopUpChanged: (id) sender mixdownToUse: (int) mixdownToUse; - (IBAction) audioTrackMixdownChanged: (id) sender; -- (IBAction) subtitleSelectionChanged: (id) sender; - (void) prepareJob; - (IBAction) browseFile: (id) sender; - (void) browseFileDone: (NSSavePanel *) sheet @@ -411,5 +418,9 @@ BOOL fIsDragging; - (void)moveObjectsInPresetsArray:(NSMutableArray *)array fromIndexes:(NSIndexSet *)indexSet toIndex:(NSUInteger)insertIndex; - (int) hbInstances; + + + + @end diff --git a/macosx/Controller.mm b/macosx/Controller.mm index 150d23381..da04ca25a 100644 --- a/macosx/Controller.mm +++ b/macosx/Controller.mm @@ -101,7 +101,13 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It fChapterTitlesDelegate = [[ChapterTitles alloc] init]; [fChapterTable setDataSource:fChapterTitlesDelegate]; [fChapterTable setDelegate:fChapterTitlesDelegate]; - + + /* setup the subtitles delegate and connections to table */ + fSubtitlesDelegate = [[HBSubtitles alloc] init]; + [fSubtitlesTable setDataSource:fSubtitlesDelegate]; + [fSubtitlesTable setDelegate:fSubtitlesDelegate]; + [fSubtitlesTable setRowHeight:25.0]; + [fPresetsOutlineView setAutosaveName:@"Presets View"]; [fPresetsOutlineView setAutosaveExpandedItems:YES]; @@ -1470,6 +1476,10 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It [fChapterTitlesDelegate resetWithTitle:nil]; [fChapterTable reloadData]; + // Notify Subtitles that there's no title + [fSubtitlesDelegate resetWithTitle:nil]; + [fSubtitlesTable reloadData]; + [self enableUI: NO]; if( [detector isVideoDVD] ) @@ -1556,6 +1566,8 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It } /* We use our advance pref to determine how many previews to scan */ int hb_num_previews = [[[NSUserDefaults standardUserDefaults] objectForKey:@"PreviewsNumber"] intValue]; + /* set title to NULL */ + //fTitle = NULL; hb_scan( fHandle, [path UTF8String], scanTitleNum, hb_num_previews, 1 ); [fSrcDVD2Field setStringValue:@"Scanning new source ..."]; } @@ -1578,6 +1590,10 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It SuccessfulScan = NO; // Notify ChapterTitles that there's no title + [fSubtitlesDelegate resetWithTitle:nil]; + [fSubtitlesTable reloadData]; + + // Notify Subtitles that there's no title [fChapterTitlesDelegate resetWithTitle:nil]; [fChapterTable reloadData]; } @@ -2093,13 +2109,10 @@ fWorkingCount = 0; } /* Subtitles*/ - [queueFileJob setObject:[fSubPopUp titleOfSelectedItem] forKey:@"Subtitles"]; - [queueFileJob setObject:[NSNumber numberWithInt:[fSubPopUp indexOfSelectedItem]] forKey:@"JobSubtitlesIndex"]; - /* Forced Subtitles */ - [queueFileJob setObject:[NSNumber numberWithInt:[fSubForcedCheck state]] forKey:@"SubtitlesForced"]; - - - + NSMutableArray *subtitlesArray = [[NSMutableArray alloc] init]; + [queueFileJob setObject:[NSArray arrayWithArray: [fSubtitlesDelegate getSubtitleArray: subtitlesArray]] forKey:@"SubtitleList"]; + [subtitlesArray autorelease]; + /* Now we go ahead and set the "job->values in the plist for passing right to fQueueEncodeLibhb */ [queueFileJob setObject:[NSNumber numberWithInt:[fSrcChapterStartPopUp indexOfSelectedItem] + 1] forKey:@"JobChapterStart"]; @@ -2133,8 +2146,6 @@ fWorkingCount = 0; [queueFileJob setObject:[NSNumber numberWithInt:job->crop[2]] forKey:@"PictureLeftCrop"]; [queueFileJob setObject:[NSNumber numberWithInt:job->crop[3]] forKey:@"PictureRightCrop"]; - /* Picture Filters */ - //[queueFileJob setObject:[fPicSettingDecomb stringValue] forKey:@"JobPictureDecomb"]; /*Audio*/ if ([fAudLang1PopUp indexOfSelectedItem] > 0) @@ -2169,10 +2180,7 @@ fWorkingCount = 0; [queueFileJob setObject:[NSNumber numberWithInt:[[fAudTrack4RatePopUp selectedItem] tag]] forKey:@"JobAudio4Samplerate"]; [queueFileJob setObject:[NSNumber numberWithInt:[[fAudTrack4BitratePopUp selectedItem] tag]] forKey:@"JobAudio4Bitrate"]; } - /* Subtitles*/ - [queueFileJob setObject:[fSubPopUp titleOfSelectedItem] forKey:@"Subtitles"]; - /* Forced Subtitles */ - [queueFileJob setObject:[NSNumber numberWithInt:[fSubForcedCheck state]] forKey:@"SubtitlesForced"]; + /* we need to auto relase the queueFileJob and return it */ [queueFileJob autorelease]; @@ -2649,9 +2657,7 @@ fWorkingCount = 0; job->x264opts = NULL; job->indepth_scan = 1; - - job->select_subtitle = (hb_subtitle_t**)malloc(sizeof(hb_subtitle_t*)); - *(job->select_subtitle) = NULL; + /* * Add the pre-scan job @@ -2659,18 +2665,13 @@ fWorkingCount = 0; hb_add( fQueueEncodeLibhb, job ); job->x264opts = x264opts_tmp; } - else - job->select_subtitle = NULL; + if( [[queueToApply objectForKey:@"VideoTwoPass"] intValue] == 1 ) { - hb_subtitle_t **subtitle_tmp = job->select_subtitle; job->indepth_scan = 0; - /* - * Do not autoselect subtitles on the first pass of a two pass - */ - job->select_subtitle = NULL; + job->pass = 1; @@ -2681,8 +2682,6 @@ fWorkingCount = 0; job->x264opts = (char *)calloc(1024, 1); /* Fixme, this just leaks */ strcpy(job->x264opts, [[queueToApply objectForKey:@"x264Option"] UTF8String]); - job->select_subtitle = subtitle_tmp; - hb_add( fQueueEncodeLibhb, job ); } @@ -2699,6 +2698,21 @@ fWorkingCount = 0; /* Lets mark our new encode as 1 or "Encoding" */ [queueToApply setObject:[NSNumber numberWithInt:1] forKey:@"Status"]; [self saveQueueFileItem]; + + /* we need to clean up the subtitle tracks after the job(s) have been set */ + int num_subtitle_tracks = hb_list_count(job->list_subtitle); + int ii; + for(ii = 0; ii < num_subtitle_tracks; ii++) + { + hb_subtitle_t * subtitle; + subtitle = (hb_subtitle_t *)hb_list_item(job->list_subtitle, 0); + + + hb_list_rem(job->list_subtitle, subtitle); + free(subtitle); + } + + /* We should be all setup so let 'er rip */ [self doRip]; } @@ -2795,29 +2809,131 @@ fWorkingCount = 0; } /* Subtitle settings */ - switch( [fSubPopUp indexOfSelectedItem] - 2 ) + NSMutableArray *subtitlesArray = nil; + subtitlesArray = [[NSMutableArray alloc] initWithArray:[fSubtitlesDelegate getSubtitleArray: subtitlesArray]]; + + + + int subtitle = nil; +int force; +int burned; +int def; +bool one_burned = FALSE; + + int i = 0; + NSEnumerator *enumerator = [subtitlesArray objectEnumerator]; + id tempObject; + while (tempObject = [enumerator nextObject]) { - case -2: - /* - * No subtitles selected - */ - break; - case -1: - /* - * Subtitle scan selected - */ - job->indepth_scan = 1; - break; - default: - /* - * Subtitle selected, add it into the job from the title. + + subtitle = [[tempObject objectForKey:@"subtitleSourceTrackNum"] intValue]; + force = [[tempObject objectForKey:@"subtitleTrackForced"] intValue]; + burned = [[tempObject objectForKey:@"subtitleTrackBurned"] intValue]; + def = [[tempObject objectForKey:@"subtitleTrackDefault"] intValue]; + + /* since the subtitleSourceTrackNum 0 is "None" in our array of the subtitle popups, + * we want to ignore it for display as well as encoding. */ - job->indepth_scan = 0; - hb_subtitle_t *subtitle = (hb_subtitle_t *) hb_list_item( title->list_subtitle, [fSubPopUp indexOfSelectedItem] - 2 ); - hb_list_add( job->list_subtitle, subtitle ); - break; + if (subtitle > 0) + { + hb_subtitle_t * subt; + hb_subtitle_config_t sub_config; + + subt = (hb_subtitle_t *)hb_list_item(title->list_subtitle, subtitle); + sub_config = subt->config; + + /* if i is 0, then we are in the first item of the subtitles which we need to + * check for the "Foreign Audio Search" which would be subtitleSourceTrackNum of 1 + * bearing in mind that for all tracks subtitleSourceTrackNum of 0 is None. + */ + + /* if we are on the first track and using "Foreign Audio Search" */ + if (i == 0 && subtitle == 1) + { + /* NOTE: Currently foreign language search is borked for preview. + * Commented out but left in for initial commit. */ + + /* + [self writeToActivityLog: "Foreign Language Search: %d", 1]; + + job->indepth_scan = 1; + if (burned == 1 || job->mux != HB_MUX_MP4) + { + if (burned != 1 && job->mux == HB_MUX_MKV) + { + job->select_subtitle_config.dest = hb_subtitle_config_s::PASSTHRUSUB; + } + + job->select_subtitle_config.force = force; + job->select_subtitle_config.default_track = def; + + } + */ + + } + else + { + + /* for the actual source tracks, we must subtract the non source entries so + * that the menu index matches the source subtitle_list index for convenience */ + if (i == 0) + { + /* for the first track, the source tracks start at menu index 2 ( None is 0, + * Foreign Language Search is 1) so subtract 2 */ + subtitle = subtitle - 2; + } + else + { + /* for all other tracks, the source tracks start at menu index 1 (None is 0) + * so subtract 1. */ + + subtitle = subtitle - 1; + } + + /* We are setting a source subtitle so access the source subtitle info */ + hb_subtitle_t * subt; + hb_subtitle_config_t sub_config; + + subt = (hb_subtitle_t *)hb_list_item(title->list_subtitle, subtitle); + sub_config = subt->config; + + if (subt != NULL) + { + [self writeToActivityLog: "Setting Subtitle: %s", subt]; + + if (!burned && job->mux == HB_MUX_MKV && + subt->format == hb_subtitle_s::PICTURESUB) + { + sub_config.dest = hb_subtitle_config_s::PASSTHRUSUB; + } + else if (!burned && job->mux == HB_MUX_MP4 && + subt->format == hb_subtitle_s::PICTURESUB) + { + // Skip any non-burned vobsubs when output is mp4 + continue; + } + else if ( burned && subt->format == hb_subtitle_s::PICTURESUB ) + { + // Only allow one subtitle to be burned into the video + if (one_burned) + continue; + one_burned = TRUE; + } + sub_config.force = force; + sub_config.default_track = def; + hb_subtitle_add( job, &sub_config, subtitle ); + } + + } + } + i++; } - + + + +[subtitlesArray autorelease]; + + /* Audio tracks and mixdowns */ /* Lets make sure there arent any erroneous audio tracks in the job list, so lets make sure its empty*/ int audiotrack_count = hb_list_count(job->list_audio); @@ -3207,36 +3323,133 @@ fWorkingCount = 0; } job->grayscale = [[queueToApply objectForKey:@"VideoGrayScale"] intValue]; - /* Subtitle settings */ - switch( [[queueToApply objectForKey:@"JobSubtitlesIndex"] intValue] - 2 ) + + +#pragma mark - +#pragma mark Process Subtitles to libhb + +/* Map the settings in the dictionaries for the SubtitleList array to match title->list_subtitle + * which means that we need to account for the offset of non source language settings in from + * the NSPopUpCell menu. For all of the objects in the SubtitleList array this means 0 is "None" + * from the popup menu, additionally the first track has "Foreign Audio Search" at 1. So we use + * an int to offset the index number for the objectForKey:@"subtitleSourceTrackNum" to map that + * to the source tracks position in title->list_subtitle. + */ + +int subtitle = nil; +int force; +int burned; +int def; +bool one_burned = FALSE; + + int i = 0; + NSEnumerator *enumerator = [[queueToApply objectForKey:@"SubtitleList"] objectEnumerator]; + id tempObject; + while (tempObject = [enumerator nextObject]) { - case -2: - /* - * No subtitles selected - */ - break; - case -1: - /* - * Subtitle scan selected - */ - job->indepth_scan = 1; - break; - default: - /* - * Subtitle selected, add it into the job from the title. + + subtitle = [[tempObject objectForKey:@"subtitleSourceTrackNum"] intValue]; + force = [[tempObject objectForKey:@"subtitleTrackForced"] intValue]; + burned = [[tempObject objectForKey:@"subtitleTrackBurned"] intValue]; + def = [[tempObject objectForKey:@"subtitleTrackDefault"] intValue]; + + /* since the subtitleSourceTrackNum 0 is "None" in our array of the subtitle popups, + * we want to ignore it for display as well as encoding. */ - job->indepth_scan = 0; - hb_subtitle_t *subtitle = (hb_subtitle_t *) hb_list_item( title->list_subtitle, - [[queueToApply objectForKey:@"JobSubtitlesIndex"] intValue] - 2 ); - if( [[queueToApply objectForKey:@"SubtitlesForced"] intValue] == 1 ) - subtitle->config.force = 1; - else - subtitle->config.force = 0; - hb_list_add( job->list_subtitle, subtitle ); - break; + if (subtitle > 0) + { + hb_subtitle_t * subt; + hb_subtitle_config_t sub_config; + + subt = (hb_subtitle_t *)hb_list_item(title->list_subtitle, subtitle); + sub_config = subt->config; + + /* if i is 0, then we are in the first item of the subtitles which we need to + * check for the "Foreign Audio Search" which would be subtitleSourceTrackNum of 1 + * bearing in mind that for all tracks subtitleSourceTrackNum of 0 is None. + */ + + /* if we are on the first track and using "Foreign Audio Search" */ + if (i == 0 && subtitle == 1) + { + [self writeToActivityLog: "Foreign Language Search: %d", 1]; + + job->indepth_scan = 1; + if (burned == 1 || job->mux != HB_MUX_MP4) + { + if (burned != 1 && job->mux == HB_MUX_MKV) + { + job->select_subtitle_config.dest = hb_subtitle_config_s::PASSTHRUSUB; + } + + job->select_subtitle_config.force = force; + job->select_subtitle_config.default_track = def; + } + + + } + else + { + + /* for the actual source tracks, we must subtract the non source entries so + * that the menu index matches the source subtitle_list index for convenience */ + if (i == 0) + { + /* for the first track, the source tracks start at menu index 2 ( None is 0, + * Foreign Language Search is 1) so subtract 2 */ + subtitle = subtitle - 2; + } + else + { + /* for all other tracks, the source tracks start at menu index 1 (None is 0) + * so subtract 1. */ + + subtitle = subtitle - 1; + } + + /* We are setting a source subtitle so access the source subtitle info */ + hb_subtitle_t * subt; + hb_subtitle_config_t sub_config; + + subt = (hb_subtitle_t *)hb_list_item(title->list_subtitle, subtitle); + sub_config = subt->config; + + if (subt != NULL) + { + [self writeToActivityLog: "Setting Subtitle: %s", subt]; + + if (!burned && job->mux == HB_MUX_MKV && + subt->format == hb_subtitle_s::PICTURESUB) + { + sub_config.dest = hb_subtitle_config_s::PASSTHRUSUB; + } + else if (!burned && job->mux == HB_MUX_MP4 && + subt->format == hb_subtitle_s::PICTURESUB) + { + // Skip any non-burned vobsubs when output is mp4 + continue; + } + else if ( burned && subt->format == hb_subtitle_s::PICTURESUB ) + { + // Only allow one subtitle to be burned into the video + if (one_burned) + continue; + one_burned = TRUE; + } + sub_config.force = force; + sub_config.default_track = def; + hb_subtitle_add( job, &sub_config, subtitle ); + } + + } + } + i++; } +#pragma mark - + + /* Audio tracks and mixdowns */ /* Lets make sure there arent any erroneous audio tracks in the job list, so lets make sure its empty*/ int audiotrack_count = hb_list_count(job->list_audio); @@ -3312,7 +3525,8 @@ fWorkingCount = 0; audio->out.dynamic_range_compression = [[queueToApply objectForKey:@"Audio4TrackDRCSlider"] floatValue]; hb_audio_add( job, audio ); - free(audio); + + } /* Filters */ @@ -3827,23 +4041,11 @@ fWorkingCount = 0; /* Reset the new title in fPictureController && fPreviewController*/ [fPictureController SetTitle:title]; - /* Update subtitle popups */ - hb_subtitle_t * subtitle; - [fSubPopUp removeAllItems]; - [fSubPopUp addItemWithTitle: @"None"]; - [fSubPopUp addItemWithTitle: @"Autoselect"]; - for( int i = 0; i < hb_list_count( title->list_subtitle ); i++ ) - { - subtitle = (hb_subtitle_t *) hb_list_item( title->list_subtitle, i ); - - /* We cannot use NSPopUpButton's addItemWithTitle because - it checks for duplicate entries */ - [[fSubPopUp menu] addItemWithTitle: [NSString stringWithCString: - subtitle->lang] action: NULL keyEquivalent: @""]; - } - [fSubPopUp selectItemAtIndex: 0]; - - [self subtitleSelectionChanged:nil]; + + /* Update Subtitle Table */ + [fSubtitlesDelegate resetWithTitle:title]; + [fSubtitlesTable reloadData]; + /* Update chapter table */ [fChapterTitlesDelegate resetWithTitle:title]; @@ -3985,6 +4187,10 @@ fWorkingCount = 0; } + /* tell fSubtitlesDelegate we have a new video container */ + + [fSubtitlesDelegate containerChanged:[[fDstFormatPopUp selectedItem] tag]]; + [fSubtitlesTable reloadData]; /* if we have a previously selected vid encoder tag, then try to select it */ if (selectedVidEncoderTag) { @@ -5427,22 +5633,6 @@ the user is using "Custom" settings by determining the sender*/ //[self customSettingUsed: sender]; } -- (IBAction) subtitleSelectionChanged: (id) sender -{ - if ([fSubPopUp indexOfSelectedItem] == 0) - { - [fSubForcedCheck setState: NSOffState]; - [fSubForcedCheck setEnabled: NO]; - } - else - { - [fSubForcedCheck setEnabled: YES]; - } - -} - - - #pragma mark - #pragma mark Open New Windows @@ -7166,9 +7356,6 @@ return YES; } - - - @end /******************************* diff --git a/macosx/English.lproj/MainMenu.xib b/macosx/English.lproj/MainMenu.xib index be20ff85f..542f3453f 100644 --- a/macosx/English.lproj/MainMenu.xib +++ b/macosx/English.lproj/MainMenu.xib @@ -2,14 +2,13 @@ 1050 - 9G55 + 9J61 677 - 949.43 + 949.46 353.00 YES - - + YES @@ -109,7 +108,7 @@ 1 - + 256 YES @@ -550,7 +549,6 @@ {{10, 25}, {714, 305}} - Video @@ -673,7 +671,6 @@ 256 {{578, 221}, {66, 22}} - YES -2076049856 @@ -717,72 +714,6 @@ 1 - - - 256 - {{-10, 48}, {70, 14}} - - - YES - - 67239424 - 71303168 - Subtitles: - - - - - - - - - 256 - {{65, 42}, {157, 22}} - - - YES - - -2076049856 - 132096 - - - 109199615 - 1 - - - - - - 400 - 75 - - - - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - YES - - - - 3 - YES - YES - 1 - - 256 @@ -899,27 +830,6 @@ 1 - - - 256 - {{229, 46}, {147, 17}} - - YES - - 67239424 - 131072 - Forced Subtitles Only - - - 1211912703 - 2 - - - - 200 - 25 - - 268 @@ -930,7 +840,7 @@ 67239488 272761856 Audio Tracks - + LucidaGrande-Bold 1.100000e+01 16 @@ -979,44 +889,6 @@ - - - 268 - {{86, 84}, {624, 5}} - - {0, 0} - - 67239424 - 0 - Box - - - - 3 - MCAwLjgwMDAwMDAxAA - - - 3 - 2 - 0 - NO - - - - 268 - {{17, 79}, {54, 14}} - - YES - - 67239488 - 272761856 - Subtitles - - - - - - 256 @@ -2045,12 +1917,351 @@ {{10, 25}, {714, 305}} - QXVkaW8gJiBTdWJ0aXRsZXM + Audio - + 3 + + + 256 + + YES + + + 268 + + YES + + + 2304 + + YES + + + 256 + {700, 265} + + YES + + + 256 + {700, 17} + + + + + + -2147483392 + {{-26, 0}, {16, 17}} + + + + YES + + track + 3.140000e+02 + 4.000000e+01 + 1.000000e+03 + + 75628032 + 0 + Track + + + 3 + MC4zMzMzMzI5OQA + + + 6 + System + headerTextColor + + + + + -2076049856 + 264192 + + + 100679935 + 129 + + + 400 + 75 + + + Pop Up + + 1048576 + 2147483647 + 1 + + + _popUpItemAction: + + + YES + + OtherViews + + YES + + + + YES + YES + 2 + + 3 + YES + + + + forced + 1.390000e+02 + 1.000000e+01 + 3.402823e+38 + + 75628032 + 134217728 + Forced Only + + + 6 + System + headerColor + + + + + + 67239424 + 131072 + Check + + + 1215582719 + 130 + + + + + 200 + 25 + + 3 + YES + YES + + + + burned + 1.210000e+02 + 1.000000e+01 + 3.402823e+38 + + 75628032 + 134217728 + Burned In + + + + + + 67239424 + 131072 + Check + + + 1215582719 + 130 + + + + + 200 + 25 + + 3 + YES + YES + + + + default + 1.140000e+02 + 1.000000e+01 + 3.402823e+38 + + 75628032 + 134217728 + Default + + + + + + 67239424 + 131072 + Check + + + 1215582719 + 130 + + + + + 200 + 25 + + 3 + YES + YES + + + + 3.000000e+00 + 2.000000e+00 + + 1 + MC45MDE5NjA3OSAwLjkwMTk2MDc5IDAuOTAxOTYwNzkAA + + + 6 + System + gridColor + + 3 + MC41AA + + + 1.700000e+01 + 1111490560 + 4 + 15 + 0 + NO + + + {{0, 17}, {700, 265}} + + + + + 6 + System + controlBackgroundColor + + + 4 + + + + -2147483392 + {{-100, -100}, {15, 206}} + + + _doScroller: + 3.700000e+01 + 1.947368e-01 + + + + 256 + {{-100, -100}, {685, 15}} + + 1 + + _doScroller: + 5.714286e-01 + + + + 2304 + + YES + + + {700, 17} + + + + + 4 + + + + {{9, 7}, {700, 282}} + + + 512 + + + + + + QSAAAEEgAABBmAAAQZgAAA + + + {{10, 25}, {714, 305}} + + + Subtitles + + + + + 5 + + + 256 + + YES + + + 256 + + YES + + + 256 + {700, 290} + + + + {{7, 8}, {700, 290}} + + {0, 0} + + 67239424 + 0 + Box + + + + 3 + MCAwLjgwMDAwMDAxAA + + + + 0 + 3 + 0 + NO + + + {{10, 25}, {714, 305}} + + Advanced + + + + + 4 256 @@ -2104,12 +2315,7 @@ 3 MC4zMzMzMzI5OQA - - 6 - System - headerTextColor - - + 337772096 @@ -2117,12 +2323,7 @@ Text Cell - - 6 - System - controlBackgroundColor - - + 3 @@ -2160,15 +2361,7 @@ 3.000000e+00 2.000000e+00 - - 6 - System - gridColor - - 3 - MC41AA - - + 1.700000e+01 -700448768 4 @@ -2262,61 +2455,15 @@ - - 4 - - - 256 - - YES - - - 256 - - YES - - - 256 - {700, 290} - - - - {{7, 8}, {700, 290}} - - {0, 0} - - 67239424 - 0 - Box - - - - 3 - MCAwLjgwMDAwMDAxAA - - - - 0 - 3 - 0 - NO - - - {{10, 25}, {714, 305}} - - Advanced - - - - + 134217728 YES YES YES - + @@ -4953,22 +5100,6 @@ 1620 - - - fSubPopUp - - - - 1637 - - - - fSubField - - - - 1758 - performFindPanelAction: @@ -5409,22 +5540,6 @@ 2496 - - - fSubForcedCheck - - - - 2505 - - - - subtitleSelectionChanged: - - - - 2506 - performClose: @@ -6193,6 +6308,14 @@ 5193 + + + fSubtitlesTable + + + + 5214 + @@ -6293,8 +6416,9 @@ YES - + + @@ -6317,17 +6441,12 @@ - - - - - @@ -6432,24 +6551,6 @@ - - 1634 - - - YES - - - - - - 1638 - - - YES - - - - 1962 @@ -6486,15 +6587,6 @@ - - 2504 - - - YES - - - - 3075 @@ -6509,20 +6601,6 @@ - - 3081 - - - - - 3082 - - - YES - - - - 1477 @@ -7939,20 +8017,6 @@ - - 4855 - - - YES - - - - - - 4856 - - - 4857 @@ -7981,21 +8045,11 @@ - - 4861 - - - 4862 - - 4864 - - - 4872 @@ -8385,20 +8439,6 @@ - - 1635 - - - YES - - - - - - 1636 - - - 1963 @@ -9377,6 +9417,137 @@ + + 5194 + + + YES + + + + + + 5195 + + + YES + + + + + + 5196 + + + YES + + + + + + + + + 5197 + + + + + 5198 + + + + + 5199 + + + YES + + + + + + + + + 5201 + + + YES + + + + + + 5215 + + + YES + + + + + + 5217 + + + YES + + + + + + 5219 + + + YES + + + + + + 5225 + + + YES + + + + + + 5226 + + + YES + + + + + + 5227 + + + + + 5232 + + + + + 5233 + + + + + 5234 + + + + + 5244 + + + @@ -9556,14 +9727,6 @@ 1628.ImportedFromIB2 1629.IBPluginDependency 1629.ImportedFromIB2 - 1634.IBPluginDependency - 1634.ImportedFromIB2 - 1635.IBPluginDependency - 1635.ImportedFromIB2 - 1636.IBPluginDependency - 1636.ImportedFromIB2 - 1638.IBPluginDependency - 1638.ImportedFromIB2 1795.IBPluginDependency 1795.ImportedFromIB2 1796.IBPluginDependency @@ -9749,8 +9912,6 @@ 2488.ImportedFromIB2 2494.IBPluginDependency 2494.ImportedFromIB2 - 2504.IBPluginDependency - 2504.ImportedFromIB2 2507.IBPluginDependency 2507.ImportedFromIB2 2508.IBPluginDependency @@ -9817,10 +9978,6 @@ 3075.ImportedFromIB2 3077.IBPluginDependency 3077.ImportedFromIB2 - 3081.IBPluginDependency - 3081.ImportedFromIB2 - 3082.IBPluginDependency - 3082.ImportedFromIB2 3203.IBPluginDependency 3203.ImportedFromIB2 3205.IBPluginDependency @@ -9865,15 +10022,11 @@ 4852.IBPluginDependency 4853.IBPluginDependency 4854.IBPluginDependency - 4855.IBPluginDependency - 4856.IBPluginDependency 4857.IBPluginDependency 4858.IBPluginDependency 4859.IBPluginDependency 4860.IBPluginDependency - 4861.IBPluginDependency 4862.IBPluginDependency - 4864.IBPluginDependency 4872.IBPluginDependency 4873.IBPluginDependency 4874.IBPluginDependency @@ -10125,6 +10278,23 @@ 5185.IBPluginDependency 5188.IBPluginDependency 5192.IBPluginDependency + 5194.IBPluginDependency + 5195.IBPluginDependency + 5196.IBPluginDependency + 5197.IBPluginDependency + 5198.IBPluginDependency + 5199.IBPluginDependency + 5201.IBPluginDependency + 5215.IBPluginDependency + 5217.IBPluginDependency + 5219.IBPluginDependency + 5225.IBPluginDependency + 5226.IBEditorWindowLastContentRect + 5226.IBPluginDependency + 5227.IBPluginDependency + 5232.IBPluginDependency + 5233.IBPluginDependency + 5234.IBPluginDependency 56.IBPluginDependency 56.ImportedFromIB2 57.IBPluginDependency @@ -10379,14 +10549,6 @@ com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - {{454, 306}, {270, 550}} com.apple.InterfaceBuilder.CocoaPlugin @@ -10480,9 +10642,9 @@ com.apple.InterfaceBuilder.CocoaPlugin - {{248, 306}, {760, 550}} + {{59, 306}, {760, 550}} - {{248, 306}, {760, 550}} + {{59, 306}, {760, 550}} {{65, 541}, {760, 550}} @@ -10541,8 +10703,6 @@ com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{72, 851}, {392, 144}} {{72, 851}, {392, 144}} @@ -10595,10 +10755,6 @@ com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - HBPresetsOutlineView com.apple.InterfaceBuilder.CocoaPlugin @@ -10709,10 +10865,6 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -10912,6 +11064,23 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{154, 542}, {700, 18}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -10946,7 +11115,7 @@ - 5193 + 5244 @@ -11005,7 +11174,6 @@ showPreviewWindow: showQueueWindow: showSourceTitleScanPanel: - subtitleSelectionChanged: titlePopUpChanged: twoPassCheckboxChanged: videoEncoderPopUpChanged: @@ -11066,7 +11234,6 @@ id id id - id @@ -11160,6 +11327,7 @@ fSubField fSubForcedCheck fSubPopUp + fSubtitlesTable fVidBitrateCell fVidBitrateField fVidConstantCell @@ -11268,6 +11436,7 @@ NSTextField NSButton NSPopUpButton + NSTableView NSButtonCell NSTextField NSButtonCell diff --git a/macosx/HBQueueController.mm b/macosx/HBQueueController.mm index 39fb40ce0..a3e61ce29 100644 --- a/macosx/HBQueueController.mm +++ b/macosx/HBQueueController.mm @@ -1187,6 +1187,7 @@ return ![(HBQueueOutlineView*)outlineView isDragging]; } + /* Seventh Line Audio Details*/ [finalString appendString: @"Audio Track 1: " withAttributes:detailBoldAttr]; [finalString appendString: audioDetail1 withAttributes:detailAttr]; @@ -1202,6 +1203,39 @@ return ![(HBQueueOutlineView*)outlineView isDragging]; [finalString appendString: @"Audio Track 4: " withAttributes:detailBoldAttr]; [finalString appendString: audioDetail4 withAttributes:detailAttr]; + [finalString appendString:@"\n" withAttributes:detailAttr]; + + /* Eighth Line Subtitle Details */ + + int i = 0; + NSEnumerator *enumerator = [[item objectForKey:@"SubtitleList"] objectEnumerator]; + id tempObject; + while (tempObject = [enumerator nextObject]) + { + /* since the subtitleSourceTrackNum 0 is "None" in our array of the subtitle popups, + * we want to ignore it for display as well as encoding. + */ + if ([[tempObject objectForKey:@"subtitleSourceTrackNum"] intValue] > 0) + { + /* remember that index 0 of Subtitles can contain "Foreign Audio Search*/ + [finalString appendString: @"Subtitle: " withAttributes:detailBoldAttr]; + [finalString appendString: [tempObject objectForKey:@"subtitleSourceTrackName"] withAttributes:detailAttr]; + if ([[tempObject objectForKey:@"subtitleTrackForced"] intValue] == 1) + { + [finalString appendString: @" - Forced Only" withAttributes:detailAttr]; + } + if ([[tempObject objectForKey:@"subtitleTrackBurned"] intValue] == 1) + { + [finalString appendString: @" - Burned In" withAttributes:detailAttr]; + } + if ([[tempObject objectForKey:@"subtitleTrackDefault"] intValue] == 1) + { + [finalString appendString: @" - Default" withAttributes:detailAttr]; + } + [finalString appendString:@"\n" withAttributes:detailAttr]; + } + i++; + } return finalString; } diff --git a/macosx/HBSubtitles.h b/macosx/HBSubtitles.h new file mode 100644 index 000000000..990492db2 --- /dev/null +++ b/macosx/HBSubtitles.h @@ -0,0 +1,44 @@ +/* $Id: HBSubtitles.h,v 1.35 2005/08/01 14:29:50 titer Exp $ + + This file is part of the HandBrake source code. + Homepage: . + It may be used under the terms of the GNU General Public License. */ + +#import +#include "hb.h" + +@interface HBSubtitles : NSObject { +hb_title_t *fTitle; + +NSMutableArray *subtitleArray; +int container; +} + +// Trigger a refresh of data +- (void)resetWithTitle:(hb_title_t *)title; + +// Create new subtitle track +- (void)addSubtitleTrack; +- (NSDictionary *)createSubtitleTrack; +- (NSMutableArray*) getSubtitleArray: (NSMutableArray *) subtitlesArray ; + +- (void)containerChanged:(int) newContainer; + +// Table View Delegates +- (int)numberOfRowsInTableView:(NSTableView *)aTableView; + +- (id)tableView:(NSTableView *)aTableView + objectValueForTableColumn:(NSTableColumn *)aTableColumn + row:(NSInteger)rowIndex; + +- (void)tableView:(NSTableView *)aTableView + setObjectValue:(id)anObject + forTableColumn:(NSTableColumn *)aTableColumn + row:(NSInteger)rowIndex; + +- (void)tableView:(NSTableView *)aTableView + willDisplayCell:(id)aCell + forTableColumn:(NSTableColumn *)aTableColumn + row:(NSInteger)rowIndex; + +@end diff --git a/macosx/HBSubtitles.m b/macosx/HBSubtitles.m new file mode 100644 index 000000000..c125779e1 --- /dev/null +++ b/macosx/HBSubtitles.m @@ -0,0 +1,444 @@ +/* $Id: HBSubtitles.m,v 1.35 2005/08/01 14:29:50 titer Exp $ + + This file is part of the HandBrake source code. + Homepage: . + It may be used under the terms of the GNU General Public License. */ +// + +#import "HBSubtitles.h" +#include "hb.h" + +@implementation HBSubtitles +- (id)init +{ + self = [super init]; + if( self != nil ) + { + fTitle = NULL; + } + + return self; +} + + +- (void)resetWithTitle:(hb_title_t *)title +{ + fTitle = title; + + if (!title) + { + return; + } + + if (subtitleArray) + { + [subtitleArray release]; + } + subtitleArray = [[NSMutableArray alloc] init]; + [self addSubtitleTrack]; +} + +#pragma mark - +#pragma mark Create new Subtitles + +- (void)addSubtitleTrack +{ + [subtitleArray addObject:[self createSubtitleTrack]]; +} + +/* Creates a new subtitle track and stores it in an NSMutableDictionary */ +- (NSDictionary *)createSubtitleTrack +{ + NSMutableDictionary *newSubtitleTrack = [[NSMutableDictionary alloc] init]; + /* Subtitle Source track popup index */ + [newSubtitleTrack setObject:[NSNumber numberWithInt:0] forKey:@"subtitleSourceTrackNum"]; + /* Subtitle Source track popup language */ + [newSubtitleTrack setObject:@"None" forKey:@"subtitleSourceTrackName"]; + /* Subtitle Source track popup isPictureSub */ + [newSubtitleTrack setObject:[NSNumber numberWithInt:0] forKey:@"subtitleSourceTrackisPictureSub"]; + /* Subtitle track forced state */ + [newSubtitleTrack setObject:[NSNumber numberWithInt:0] forKey:@"subtitleTrackForced"]; + /* Subtitle track burned state */ + [newSubtitleTrack setObject:[NSNumber numberWithInt:0] forKey:@"subtitleTrackBurned"]; + /* Subtitle track default state */ + [newSubtitleTrack setObject:[NSNumber numberWithInt:0] forKey:@"subtitleTrackDefault"]; + + [newSubtitleTrack autorelease]; + return newSubtitleTrack; +} + +- (NSMutableArray*) getSubtitleArray: (NSMutableArray *) subtitlesArray +{ + //NSMutableArray *returnSubtitlesArray = [[NSMutableArray alloc] init]; + //[returnSubtitlesArray initWithArray:subtitleArray]; + //[returnSubtitlesArray autorelease]; + return subtitleArray; +} + +- (void)containerChanged:(int) newContainer +{ +container = newContainer; +} + +#pragma mark - +#pragma mark Subtitle Table Delegate Methods +/* Table View delegate methods */ +/* Returns the number of tracks displayed + * NOTE: we return one more than the actual number of tracks + * specified as we always keep one track set to "None" which is ignored + * for setting up tracks, but is used to add tracks. + */ +- (int)numberOfRowsInTableView:(NSTableView *)aTableView +{ + if( fTitle == NULL || ![subtitleArray count]) + { + return 0; + } + else + { + return [subtitleArray count]; + } +} + +/* Used to tell the Table view which information is to be displayed per item */ +- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex +{ + NSString *cellEntry = @"__DATA ERROR__"; + + /* we setup whats displayed given the column identifier */ + if ([[aTableColumn identifier] isEqualToString:@"track"]) + { + /* 'track' is a popup of all available source subtitle tracks for the given title */ + + + NSPopUpButtonCell *cellTrackPopup = [[NSPopUpButtonCell alloc] init]; + [cellTrackPopup autorelease]; + /* Set the Popups properties */ + /* Following two lines can be used to show kind of a text field with indicator arrows which + * will popup when clicked on. Comment out for a standard style popup */ + //[cellTrackPopup setShowsBorderOnlyWhileMouseInside:YES]; + //[cellTrackPopup setBordered:NO]; + + [cellTrackPopup setControlSize:NSSmallControlSize]; + [cellTrackPopup setFont:[NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]]]; + + + /* Add our initial "None" track which we use to add source tracks or remove tracks. + * "None" is always index 0. + */ + [[cellTrackPopup menu] addItemWithTitle: @"None" action: NULL keyEquivalent: @""]; + + /* Foreign Audio Search (index 1 in the popup) is only available for the first track */ + if (rowIndex == 0) + { + [[cellTrackPopup menu] addItemWithTitle: @"Foreign Audio Search - (Bitmap)" action: NULL keyEquivalent: @""]; + } + + if (fTitle) + { + hb_subtitle_t *subtitle; + hb_subtitle_config_t sub_config; + int i; + for(i = 0; i < hb_list_count( fTitle->list_subtitle ); i++ ) + { + NSString * trackTypeString = @""; + subtitle = (hb_subtitle_t *) hb_list_item( fTitle->list_subtitle, i ); + sub_config = subtitle->config; + + if (subtitle->format == PICTURESUB) + { + trackTypeString = @"- (Bitmap)"; + } + else + { + trackTypeString = @"- (Text)"; + } + + + NSString *popupMenuItemDescription = [NSString stringWithFormat:@"%d - %@ %@",i,[NSString stringWithUTF8String:subtitle->lang],trackTypeString]; + + [[cellTrackPopup menu] addItemWithTitle: popupMenuItemDescription action: NULL keyEquivalent: @""]; + } + } + + [aTableColumn setDataCell:cellTrackPopup]; + + } + else if ([[aTableColumn identifier] isEqualToString:@"forced"]) + { + /* 'forced' is a checkbox to determine if a given source track is only to be forced */ + NSButtonCell *cellForcedCheckBox = [[NSButtonCell alloc] init]; + [cellForcedCheckBox autorelease]; + [cellForcedCheckBox setButtonType:NSSwitchButton]; + [cellForcedCheckBox setImagePosition:NSImageOnly]; + [cellForcedCheckBox setAllowsMixedState:NO]; + [aTableColumn setDataCell:cellForcedCheckBox]; + + } + else if ([[aTableColumn identifier] isEqualToString:@"burned"]) + { + /* 'burned' is a checkbox to determine if a given source track is only to be burned */ + NSButtonCell *cellBurnedCheckBox = [[NSButtonCell alloc] init]; + [cellBurnedCheckBox autorelease]; + [cellBurnedCheckBox setButtonType:NSSwitchButton]; + [cellBurnedCheckBox setImagePosition:NSImageOnly]; + [cellBurnedCheckBox setAllowsMixedState:NO]; + [aTableColumn setDataCell:cellBurnedCheckBox]; + } + else if ([[aTableColumn identifier] isEqualToString:@"default"]) + { + NSButtonCell *cellDefaultCheckBox = [[NSButtonCell alloc] init]; + [cellDefaultCheckBox autorelease]; + [cellDefaultCheckBox setButtonType:NSSwitchButton]; + [cellDefaultCheckBox setImagePosition:NSImageOnly]; + [cellDefaultCheckBox setAllowsMixedState:NO]; + [aTableColumn setDataCell:cellDefaultCheckBox]; + } + else + { + cellEntry = nil; + } + + return cellEntry; +} + +/* Called whenever a widget in the table is edited or changed, we use it to record the change in the controlling array + * including removing and adding new tracks via the "None" ("track" index of 0) */ +- (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex +{ + + if ([[aTableColumn identifier] isEqualToString:@"track"]) + { + [[subtitleArray objectAtIndex:rowIndex] setObject:[NSNumber numberWithInt:[anObject intValue]] forKey:@"subtitleSourceTrackNum"]; + /* Set the array to track if we are vobsub (picture sub) */ + if ([anObject intValue] != 0) + { + int sourceSubtitleIndex; + bool isPictureSub = FALSE; + if (rowIndex == 0) + { + sourceSubtitleIndex = [anObject intValue] - 2; + } + else + { + sourceSubtitleIndex = [anObject intValue] - 1; + } + + if (rowIndex == 0 && [anObject intValue] == 1)// we are Foreign Launguage Search, which is inherently bitmap + { + isPictureSub = TRUE; + } + else + { + hb_subtitle_t * subtitle; + hb_subtitle_config_t sub_config; + subtitle = (hb_subtitle_t *) hb_list_item( fTitle->list_subtitle, sourceSubtitleIndex ); + sub_config = subtitle->config; + if (subtitle->format == PICTURESUB) + { + isPictureSub = TRUE; + } + } + if (isPictureSub == TRUE) + { + [[subtitleArray objectAtIndex:rowIndex] setObject:[NSNumber numberWithInt:1] forKey:@"subtitleSourceTrackisPictureSub"]; + } + else + { + [[subtitleArray objectAtIndex:rowIndex] setObject:[NSNumber numberWithInt:0] forKey:@"subtitleSourceTrackisPictureSub"]; + /* if we are not picture sub, then we must be a text sub, handbrake does not support burning in text subs */ + [[subtitleArray objectAtIndex:rowIndex] setObject:[NSNumber numberWithInt:0] forKey:@"subtitleTrackBurned"]; + } + } + } + else if ([[aTableColumn identifier] isEqualToString:@"forced"]) + { + [[subtitleArray objectAtIndex:rowIndex] setObject:[NSNumber numberWithInt:[anObject intValue]] forKey:@"subtitleTrackForced"]; + } + else if ([[aTableColumn identifier] isEqualToString:@"burned"]) + { + [[subtitleArray objectAtIndex:rowIndex] setObject:[NSNumber numberWithInt:[anObject intValue]] forKey:@"subtitleTrackBurned"]; + /* now we need to make sure no other tracks are set to burned if we have set burned*/ + if ([anObject intValue] == 1) + { + int i = 0; + NSEnumerator *enumerator = [subtitleArray objectEnumerator]; + id tempObject; + while ( tempObject = [enumerator nextObject] ) + { + if (i != rowIndex ) + { + [tempObject setObject:[NSNumber numberWithInt:0] forKey:@"subtitleTrackBurned"]; + } + i++; + } + } + } + else if ([[aTableColumn identifier] isEqualToString:@"default"]) + { + [[subtitleArray objectAtIndex:rowIndex] setObject:[NSNumber numberWithInt:[anObject intValue]] forKey:@"subtitleTrackDefault"]; + /* now we need to make sure no other tracks are set to default */ + if ([anObject intValue] == 1) + { + int i = 0; + NSEnumerator *enumerator = [subtitleArray objectEnumerator]; + id tempObject; + while ( tempObject = [enumerator nextObject] ) + { + if (i != rowIndex) + { + [tempObject setObject:[NSNumber numberWithInt:0] forKey:@"subtitleTrackDefault"]; + } + i++; + } + } + + } + + + /* now lets do a bit of logic to add / remove tracks as necessary via the "None" track (index 0) */ + if ([[aTableColumn identifier] isEqualToString:@"track"]) + { + + /* since mp4 only supports burned in vobsubs (bitmap) we need to make sure burned in is specified */ + if (container == HB_MUX_MP4 && [anObject intValue] != 0) + { + /* so, if isPictureSub = TRUE and we are mp4, we now have to A) set burned-in to 1 and b) remove any other + * tracks specified that are burned in */ + if ([[[subtitleArray objectAtIndex:rowIndex] objectForKey:@"subtitleSourceTrackisPictureSub"] intValue] == 1) + { + [[subtitleArray objectAtIndex:rowIndex] setObject:[NSNumber numberWithInt:1] forKey:@"subtitleTrackBurned"]; + } + } + + + /* We use the track popup index number (presumes index 0 is "None" which is ignored and only used to remove tracks if need be) + * to determine whether to 1 modify an existing track, 2. add a new empty "None" track or 3. remove an existing track. + */ + + if ([anObject intValue] != 0 && rowIndex == [subtitleArray count] - 1) // if we have a last track which != "None" + { + /* add a new empty None track */ + [self addSubtitleTrack]; + } + else if ([anObject intValue] == 0 && rowIndex != ([subtitleArray count] -1))// if this track is none and not the last track displayed + { + /* we know the user chose to remove this track by setting it to None, so remove it from the array */ + [subtitleArray removeObjectAtIndex: rowIndex]; + } + + + + } + + [aTableView reloadData]; +} + + +/* Gives fine grained control over the final drawing of the widget, including widget status via the controlling array */ +- (void)tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex +{ + /* we setup whats displayed given the column identifier */ + if ([[aTableColumn identifier] isEqualToString:@"track"]) + { + /* Set the index of the recorded source track here */ + [aCell selectItemAtIndex:[[[subtitleArray objectAtIndex:rowIndex] objectForKey:@"subtitleSourceTrackNum"] intValue]]; + /* now that we have actually selected our track, we can grok the titleOfSelectedItem for that track */ + [[subtitleArray objectAtIndex:rowIndex] setObject:[[aTableColumn dataCellForRow:rowIndex] titleOfSelectedItem] forKey:@"subtitleSourceTrackName"]; + + } + else + { + + [aCell setAlignment:NSCenterTextAlignment]; + /* If the Track is None, we disable the other cells as None is an empty track */ + if ([[[subtitleArray objectAtIndex:rowIndex] objectForKey:@"subtitleSourceTrackNum"] intValue] == 0) + { + [aCell setState:0]; + [aCell setEnabled:NO]; + } + else + { + /* Since we have a valid track, we go ahead and enable the rest of the widgets and set them according to the controlling array */ + [aCell setEnabled:YES]; + } + + if ([[aTableColumn identifier] isEqualToString:@"forced"]) + { + [aCell setState:[[[subtitleArray objectAtIndex:rowIndex] objectForKey:@"subtitleTrackForced"] intValue]]; + } + else if ([[aTableColumn identifier] isEqualToString:@"burned"]) + { + [aCell setState:[[[subtitleArray objectAtIndex:rowIndex] objectForKey:@"subtitleTrackBurned"] intValue]]; + /* Disable the "Burned-In" checkbox if a) the track is "None", b) the subtitle track is text (we do not support burning in + * text subs, or c) we are mp4 and the track is a vobsub (picture sub) */ + if ([[[subtitleArray objectAtIndex:rowIndex] objectForKey:@"subtitleSourceTrackNum"] intValue] == 0 || + [[[subtitleArray objectAtIndex:rowIndex] objectForKey:@"subtitleSourceTrackisPictureSub"] intValue] == 0 || + (container == HB_MUX_MP4 && [[[subtitleArray objectAtIndex:rowIndex] objectForKey:@"subtitleSourceTrackisPictureSub"] intValue] == 1)) + { + [aCell setEnabled:NO]; + } + else + { + [aCell setEnabled:YES]; + } + } + else if ([[aTableColumn identifier] isEqualToString:@"default"]) + { + [aCell setState:[[[subtitleArray objectAtIndex:rowIndex] objectForKey:@"subtitleTrackDefault"] intValue]]; + } + + } + + BOOL useMp4VobsubDelete = YES; + if (useMp4VobsubDelete == YES) + { + if (container == HB_MUX_MP4) + { + /* now remove any other tracks that are set as burned and are picturesubs */ + int i = 0; + int removedTracks = 0; + NSEnumerator *enumerator = [subtitleArray objectEnumerator]; + id tempObject; + NSMutableArray *tempArrayToDelete = [NSMutableArray array]; + BOOL removeTrack = NO; + while ( tempObject = [enumerator nextObject] ) + { + + if ([[tempObject objectForKey:@"subtitleSourceTrackisPictureSub"] intValue] == 1) + { + /* if this is the first vobsub mark it. if not, remove it */ + if (removeTrack == NO) + { + /* make sure that this is set to be burned in */ + [tempObject setObject:[NSNumber numberWithInt:1] forKey:@"subtitleTrackBurned"]; + removeTrack = YES; + } + else + { + [tempArrayToDelete addObject:tempObject]; + removedTracks ++; + } + } + + i++; + } + /* check to see if there are tracks to remove from the array */ + if ([tempArrayToDelete count] > 0) + { + /* Popup a warning that hb only support one pic sub being burned in with mp4 */ + int status; + NSBeep(); + status = NSRunAlertPanel(@"More than one vobsub is not supported in an mp4...",@"Your first vobsub track will now be used.", @"OK", nil, nil); + [NSApp requestUserAttention:NSCriticalRequest]; + + [subtitleArray removeObjectsInArray:tempArrayToDelete]; + [aTableView reloadData]; + } + } + } + +} + + +@end diff --git a/macosx/HandBrake.xcodeproj/project.pbxproj b/macosx/HandBrake.xcodeproj/project.pbxproj index ac8c33b5f..4b9b02175 100644 --- a/macosx/HandBrake.xcodeproj/project.pbxproj +++ b/macosx/HandBrake.xcodeproj/project.pbxproj @@ -51,6 +51,8 @@ A2BEA5FC0F2A1ED1001CE7A1 /* PictureController.mm in Sources */ = {isa = PBXBuildFile; fileRef = A2BEA5FA0F2A1ED1001CE7A1 /* PictureController.mm */; }; A2D0A0AB0D3E5929002D57CB /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2D0A0AA0D3E5929002D57CB /* Sparkle.framework */; }; A2D0A0BF0D3E596F002D57CB /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = A2D0A0AA0D3E5929002D57CB /* Sparkle.framework */; }; + A2D18AA70FD81C50003C997B /* HBSubtitles.h in Headers */ = {isa = PBXBuildFile; fileRef = A2D18AA50FD81C50003C997B /* HBSubtitles.h */; }; + A2D18AA80FD81C50003C997B /* HBSubtitles.m in Sources */ = {isa = PBXBuildFile; fileRef = A2D18AA60FD81C50003C997B /* HBSubtitles.m */; }; A2D7AD670C998AD30082CA33 /* ActivityWindow.tiff in Resources */ = {isa = PBXBuildFile; fileRef = A2D7AD5E0C998AD30082CA33 /* ActivityWindow.tiff */; }; A2D7AD680C998AD30082CA33 /* AddToQueue.tiff in Resources */ = {isa = PBXBuildFile; fileRef = A2D7AD5F0C998AD30082CA33 /* AddToQueue.tiff */; }; A2D7AD690C998AD30082CA33 /* Drawer.tiff in Resources */ = {isa = PBXBuildFile; fileRef = A2D7AD600C998AD30082CA33 /* Drawer.tiff */; }; @@ -174,6 +176,8 @@ A2BEA5F90F2A1ED1001CE7A1 /* PictureController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PictureController.h; sourceTree = ""; }; A2BEA5FA0F2A1ED1001CE7A1 /* PictureController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PictureController.mm; sourceTree = ""; }; A2D0A0AA0D3E5929002D57CB /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Sparkle.framework; sourceTree = ""; }; + A2D18AA50FD81C50003C997B /* HBSubtitles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBSubtitles.h; sourceTree = ""; }; + A2D18AA60FD81C50003C997B /* HBSubtitles.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBSubtitles.m; sourceTree = ""; }; A2D7AD5E0C998AD30082CA33 /* ActivityWindow.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = ActivityWindow.tiff; sourceTree = ""; }; A2D7AD5F0C998AD30082CA33 /* AddToQueue.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = AddToQueue.tiff; sourceTree = ""; }; A2D7AD600C998AD30082CA33 /* Drawer.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = Drawer.tiff; sourceTree = ""; }; @@ -328,13 +332,15 @@ 526FBC930B4CAA260064E04C /* HandBrake Sources */ = { isa = PBXGroup; children = ( + A2D18AA50FD81C50003C997B /* HBSubtitles.h */, + A2D18AA60FD81C50003C997B /* HBSubtitles.m */, 4DF3C8CC052889CD00A80101 /* Controller.mm */, A2BEA5F90F2A1ED1001CE7A1 /* PictureController.h */, A2BEA5FA0F2A1ED1001CE7A1 /* PictureController.mm */, A22C85EA0D05D35000C10E36 /* HBPresets.h */, A22C85EB0D05D35000C10E36 /* HBPresets.m */, - 4D1FD381073D19CE00E46515 /* HBPreviewController.h */, 4D1FD382073D19CE00E46515 /* HBPreviewController.mm */, + 4D1FD381073D19CE00E46515 /* HBPreviewController.h */, 4DF3C8CB052889CD00A80101 /* Controller.h */, 593034E90BBA39A100172349 /* ChapterTitles.h */, 593034EA0BBA39A100172349 /* ChapterTitles.m */, @@ -415,6 +421,7 @@ A22C85EC0D05D35000C10E36 /* HBPresets.h in Headers */, A2BEA5FB0F2A1ED1001CE7A1 /* PictureController.h in Headers */, 278070240F5C261300699207 /* ChapterTitles.h in Headers */, + A2D18AA70FD81C50003C997B /* HBSubtitles.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -604,6 +611,7 @@ E37172670C977D340072B384 /* HBImageAndTextCell.m in Sources */, A22C85ED0D05D35100C10E36 /* HBPresets.m in Sources */, A2BEA5FC0F2A1ED1001CE7A1 /* PictureController.mm in Sources */, + A2D18AA80FD81C50003C997B /* HBSubtitles.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; -- 2.40.0