#import "HBPreferencesController.h"
#import "HBDVDDetector.h"
#import "HBPresets.h"
+#import "HBPreviewController.h"
#define DragDropSimplePboardType @"MyCustomOutlineViewPboardType"
-/* We setup the toolbar values here */
+/* We setup the toolbar values here ShowPreviewIdentifier */
static NSString * ToggleDrawerIdentifier = @"Toggle Drawer Item Identifier";
static NSString * StartEncodingIdentifier = @"Start Encoding Item Identifier";
static NSString * PauseEncodingIdentifier = @"Pause Encoding Item Identifier";
static NSString * ShowQueueIdentifier = @"Show Queue Item Identifier";
static NSString * AddToQueueIdentifier = @"Add to Queue Item Identifier";
+static NSString * ShowPictureIdentifier = @"Show Picture Window Item Identifier";
+static NSString * ShowPreviewIdentifier = @"Show Preview Window Item Identifier";
static NSString * ShowActivityIdentifier = @"Debug Output Item Identifier";
static NSString * ChooseSourceIdentifier = @"Choose Source Item Identifier";
{
return nil;
}
+
+ /* replace bundled app icon with one which is 32/64-bit savvy */
+#if defined( __LP64__ )
+ fApplicationIcon = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForImageResource:@"HandBrake-64.icns"]];
+#else
+ fApplicationIcon = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForImageResource:@"HandBrake.icns"]];
+#endif
+ if( fApplicationIcon != nil )
+ [NSApp setApplicationIconImage:fApplicationIcon];
[HBPreferencesController registerUserDefaults];
fHandle = NULL;
attributes:nil];
}
outputPanel = [[HBOutputPanelController alloc] init];
- fPictureController = [[PictureController alloc] initWithDelegate:self];
+ fPictureController = [[PictureController alloc] init];
fQueueController = [[HBQueueController alloc] init];
fAdvancedOptions = [[HBAdvancedController alloc] init];
/* we init the HBPresets class which currently is only used
fPresetsBuiltin = [[HBPresets alloc] init];
fPreferencesController = [[HBPreferencesController alloc] init];
/* Lets report the HandBrake version number here to the activity log and text log file */
- NSString *versionStringFull = [[NSString stringWithFormat: @"Handbrake Version: %@", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleGetInfoString"]] stringByAppendingString: [NSString stringWithFormat: @" (%@)", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]]];
+ NSString *versionStringFull = [[NSString stringWithFormat: @"Handbrake Version: %@", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]] stringByAppendingString: [NSString stringWithFormat: @" (%@)", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]]];
[self writeToActivityLog: "%s", [versionStringFull UTF8String]];
return self;
/* Init libhb with check for updates libhb style set to "0" so its ignored and lets sparkle take care of it */
int loggingLevel = [[[NSUserDefaults standardUserDefaults] objectForKey:@"LoggingLevel"] intValue];
fHandle = hb_init(loggingLevel, 0);
+ /* Optional dvd nav UseDvdNav*/
+ hb_dvd_set_dvdnav([[[NSUserDefaults standardUserDefaults] objectForKey:@"UseDvdNav"] boolValue]);
/* Init a separate instance of libhb for user scanning and setting up jobs */
fQueueEncodeLibhb = hb_init(loggingLevel, 0);
[GrowlApplicationBridge setGrowlDelegate: self];
/* Init others controllers */
[fPictureController SetHandle: fHandle];
+ [fPictureController setHBController: self];
+
[fQueueController setHandle: fQueueEncodeLibhb];
[fQueueController setHBController: self];
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];
+
+ dockIconProgress = 0;
/* Call UpdateUI every 1/2 sec */
[[NSRunLoop currentRunLoop] addTimer:[NSTimer
scheduledTimerWithTimeInterval:0.5 target:self
selector:@selector(updateUI:) userInfo:nil repeats:YES]
- forMode:NSEventTrackingRunLoopMode];
+ forMode:NSDefaultRunLoopMode];
// Open debug output window now if it was visible when HB was closed
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"OutputPanelIsOpen"])
/*On Screen Notification*/
NSString * alertTitle;
- if (fWorkingCount > 0)
+
+ /* We check to see if there is already another instance of hb running.
+ * Note: hbInstances == 1 means we are the only instance of HandBrake.app
+ */
+ if ([self hbInstances] > 1)
{
- alertTitle = [NSString stringWithFormat:
- NSLocalizedString(@"HandBrake Has Detected %d Previously Encoding Item and %d Pending Item(s) In Your Queue.", @""),
- fWorkingCount,fPendingCount];
+ alertTitle = [NSString stringWithFormat:
+ NSLocalizedString(@"There is already an instance of HandBrake running.", @"")];
+ NSBeginCriticalAlertSheet(
+ alertTitle,
+ NSLocalizedString(@"Reload Queue", nil),
+ nil,
+ nil,
+ fWindow, self,
+ nil, @selector(didDimissReloadQueue:returnCode:contextInfo:), nil,
+ NSLocalizedString(@" HandBrake will now load up the existing queue.", nil));
}
else
{
- alertTitle = [NSString stringWithFormat:
- NSLocalizedString(@"HandBrake Has Detected %d Pending Item(s) In Your Queue.", @""),
- fPendingCount];
+ if (fWorkingCount > 0)
+ {
+ alertTitle = [NSString stringWithFormat:
+ NSLocalizedString(@"HandBrake Has Detected %d Previously Encoding Item and %d Pending Item(s) In Your Queue.", @""),
+ fWorkingCount,fPendingCount];
+ }
+ else
+ {
+ alertTitle = [NSString stringWithFormat:
+ NSLocalizedString(@"HandBrake Has Detected %d Pending Item(s) In Your Queue.", @""),
+ fPendingCount];
+ }
+
+ NSBeginCriticalAlertSheet(
+ alertTitle,
+ NSLocalizedString(@"Reload Queue", nil),
+ nil,
+ NSLocalizedString(@"Empty Queue", nil),
+ fWindow, self,
+ nil, @selector(didDimissReloadQueue:returnCode:contextInfo:), nil,
+ NSLocalizedString(@" Do you want to reload them ?", nil));
}
- NSBeginCriticalAlertSheet(
- alertTitle,
- NSLocalizedString(@"Reload Queue", nil),
- nil,
- NSLocalizedString(@"Empty Queue", nil),
- fWindow, self,
- nil, @selector(didDimissReloadQueue:returnCode:contextInfo:), nil,
- NSLocalizedString(@" Do you want to reload them ?", nil));
+
// call didDimissReloadQueue: (NSWindow *)sheet returnCode: (int)returnCode contextInfo: (void *)contextInfo
// right below to either clear the old queue or keep it loaded up.
}
else
{
+ /* We show whichever open source window specified in LaunchSourceBehavior preference key */
+ if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"LaunchSourceBehavior"] isEqualToString: @"Open Source"])
+ {
+ [self browseSources:nil];
+ }
- /* Show Browse Sources Window ASAP */
- [self performSelectorOnMainThread:@selector(browseSources:)
- withObject:nil waitUntilDone:NO];
+ if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"LaunchSourceBehavior"] isEqualToString: @"Open Source (Title Specific)"])
+ {
+ [self browseSources:(id)fOpenSourceTitleMMenu];
+ }
}
}
+- (int) hbInstances
+{
+ /* check to see if another instance of HandBrake.app is running */
+ NSArray *runningAppDictionaries = [[NSWorkspace sharedWorkspace] launchedApplications];
+ NSDictionary *aDictionary;
+ int hbInstances = 0;
+ for (aDictionary in runningAppDictionaries)
+ {
+ // NSLog(@"Open App: %@", [aDictionary valueForKey:@"NSApplicationName"]);
+
+ if ([[aDictionary valueForKey:@"NSApplicationName"] isEqualToString:@"HandBrake"])
+ {
+ hbInstances++;
+ }
+ }
+ return hbInstances;
+}
+
- (void) didDimissReloadQueue: (NSWindow *)sheet returnCode: (int)returnCode contextInfo: (void *)contextInfo
{
if (returnCode == NSAlertOtherReturn)
{
[self clearQueueAllItems];
- [self performSelectorOnMainThread:@selector(browseSources:)
- withObject:nil waitUntilDone:NO];
+ /* We show whichever open source window specified in LaunchSourceBehavior preference key */
+ if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"LaunchSourceBehavior"] isEqualToString: @"Open Source"])
+ {
+ [self browseSources:nil];
+ }
+
+ if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"LaunchSourceBehavior"] isEqualToString: @"Open Source (Title Specific)"])
+ {
+ [self browseSources:(id)fOpenSourceTitleMMenu];
+ }
}
else
{
- [self setQueueEncodingItemsAsPending];
- [self showQueueWindow:NULL];
+ if ([self hbInstances] == 1)
+ {
+ [self setQueueEncodingItemsAsPending];
+ }
+ [self showQueueWindow:NULL];
}
}
- (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication *) app
{
+ /* if we are in preview full screen mode, we need to go to
+ * windowed mode and release the display before we terminate.
+ * We do it here (instead of applicationWillTerminate) so we
+ * release the displays and can then see the alerts below.
+ */
+ if ([fPictureController previewFullScreenMode] == YES)
+ {
+ [fPictureController previewGoWindowed:nil];
+ }
- // Warn if encoding a movie
hb_state_t s;
hb_get_state( fQueueEncodeLibhb, &s );
- (void)applicationWillTerminate:(NSNotification *)aNotification
{
- [browsedSourceDisplayName release];
+
+ [browsedSourceDisplayName release];
[outputPanel release];
[fQueueController release];
+ [fPreviewController release];
+ [fPictureController release];
+ [fApplicationIcon release];
+
hb_close(&fHandle);
hb_close(&fQueueEncodeLibhb);
}
[fWindow center];
[fWindow setExcludedFromWindowsMenu:YES];
[fAdvancedOptions setView:fAdvancedView];
-
+
/* lets setup our presets drawer for drag and drop here */
[fPresetsOutlineView registerForDraggedTypes: [NSArray arrayWithObject:DragDropSimplePboardType] ];
[fPresetsOutlineView setDraggingSourceOperationMask:NSDragOperationEvery forLocal:YES];
[fPresetsOutlineView setVerticalMotionCanBeginDrag: YES];
-
+
/* Initialize currentScanCount so HB can use it to
- evaluate successive scans */
+ evaluate successive scans */
currentScanCount = 0;
-
-
+
+
/* Init UserPresets .plist */
[self loadPresets];
[self loadQueueFile];
fRipIndicatorShown = NO; // initially out of view in the nib
+
+ /* For 64 bit builds, the threaded animation in the progress
+ * indicators conflicts with the animation in the advanced tab
+ * for reasons not completely clear. jbrjake found a note in the
+ * 10.5 dev notes regarding this possiblility. It was also noted
+ * that unless specified, setUsesThreadedAnimation defaults to true.
+ * So, at least for now we set the indicator animation to NO for
+ * both the scan and regular progress indicators for both 32 and 64 bit
+ * as it test out fine on both and there is no reason our progress indicators
+ * should require their own thread.
+ */
+ [fScanIndicator setUsesThreadedAnimation:NO];
+ [fRipIndicator setUsesThreadedAnimation:NO];
+
+
+
/* Show/Dont Show Presets drawer upon launch based
- on user preference DefaultPresetsDrawerShow*/
- if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultPresetsDrawerShow"] > 0)
+ on user preference DefaultPresetsDrawerShow*/
+ if( [[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultPresetsDrawerShow"] > 0 )
{
+ [fPresetDrawer setDelegate:self];
+ NSSize drawerSize = NSSizeFromString( [[NSUserDefaults standardUserDefaults]
+ stringForKey:@"Drawer Size"] );
+ if( drawerSize.width )
+ [fPresetDrawer setContentSize: drawerSize];
[fPresetDrawer open];
}
-
-
+
+ /* Initially set the dvd angle widgets to hidden (dvdnav only) */
+ [fSrcAngleLabel setHidden:YES];
+ [fSrcAnglePopUp setHidden:YES];
/* Destination box*/
NSMenuItem *menuItem;
// MKV file
menuItem = [[fDstFormatPopUp menu] addItemWithTitle:@"MKV file" action: NULL keyEquivalent: @""];
[menuItem setTag: HB_MUX_MKV];
- // AVI file
- menuItem = [[fDstFormatPopUp menu] addItemWithTitle:@"AVI file" action: NULL keyEquivalent: @""];
- [menuItem setTag: HB_MUX_AVI];
- // OGM file
- menuItem = [[fDstFormatPopUp menu] addItemWithTitle:@"OGM file" action: NULL keyEquivalent: @""];
- [menuItem setTag: HB_MUX_OGM];
+
[fDstFormatPopUp selectItemAtIndex: 0];
-
+
[self formatPopUpChanged:nil];
-
+
/* We enable the create chapters checkbox here since we are .mp4 */
[fCreateChapterMarkers setEnabled: YES];
if ([fDstFormatPopUp indexOfSelectedItem] == 0 && [[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultChapterMarkers"] > 0)
{
[fCreateChapterMarkers setState: NSOnState];
}
-
-
-
-
+
+
+
+
[fDstFile2Field setStringValue: [NSString stringWithFormat:
- @"%@/Desktop/Movie.mp4", NSHomeDirectory()]];
-
+ @"%@/Desktop/Movie.mp4", NSHomeDirectory()]];
+
/* Video encoder */
[fVidEncoderPopUp removeAllItems];
[fVidEncoderPopUp addItemWithTitle: @"FFmpeg"];
- [fVidEncoderPopUp addItemWithTitle: @"XviD"];
-
-
-
+
+
+
/* Video quality */
[fVidTargetSizeField setIntValue: 700];
[fVidBitrateField setIntValue: 1000];
-
+
[fVidQualityMatrix selectCell: fVidBitrateCell];
[self videoMatrixChanged:nil];
-
+
/* Video framerate */
[fVidRatePopUp removeAllItems];
[fVidRatePopUp addItemWithTitle: NSLocalizedString( @"Same as source", @"" )];
if ([[NSString stringWithCString: hb_video_rates[i].string] isEqualToString: [NSString stringWithFormat: @"%.3f",23.976]])
{
[fVidRatePopUp addItemWithTitle:[NSString stringWithFormat: @"%@%@",
- [NSString stringWithCString: hb_video_rates[i].string], @" (NTSC Film)"]];
+ [NSString stringWithCString: hb_video_rates[i].string], @" (NTSC Film)"]];
}
else if ([[NSString stringWithCString: hb_video_rates[i].string] isEqualToString: [NSString stringWithFormat: @"%d",25]])
{
[fVidRatePopUp addItemWithTitle:[NSString stringWithFormat: @"%@%@",
- [NSString stringWithCString: hb_video_rates[i].string], @" (PAL Film/Video)"]];
+ [NSString stringWithCString: hb_video_rates[i].string], @" (PAL Film/Video)"]];
}
else if ([[NSString stringWithCString: hb_video_rates[i].string] isEqualToString: [NSString stringWithFormat: @"%.2f",29.97]])
{
[fVidRatePopUp addItemWithTitle:[NSString stringWithFormat: @"%@%@",
- [NSString stringWithCString: hb_video_rates[i].string], @" (NTSC Video)"]];
+ [NSString stringWithCString: hb_video_rates[i].string], @" (NTSC Video)"]];
}
else
{
[fVidRatePopUp addItemWithTitle:
- [NSString stringWithCString: hb_video_rates[i].string]];
+ [NSString stringWithCString: hb_video_rates[i].string]];
}
}
[fVidRatePopUp selectItemAtIndex: 0];
for( int i = 0; i < hb_audio_bitrates_count; i++ )
{
[fAudTrack1BitratePopUp addItemWithTitle:
- [NSString stringWithCString: hb_audio_bitrates[i].string]];
-
+ [NSString stringWithCString: hb_audio_bitrates[i].string]];
+
}
[fAudTrack1BitratePopUp selectItemAtIndex: hb_audio_bitrates_default];
for( int i = 0; i < hb_audio_rates_count; i++ )
{
[fAudTrack1RatePopUp addItemWithTitle:
- [NSString stringWithCString: hb_audio_rates[i].string]];
+ [NSString stringWithCString: hb_audio_rates[i].string]];
}
[fAudTrack1RatePopUp selectItemAtIndex: hb_audio_rates_default];
/* Bottom */
[fStatusField setStringValue: @""];
-
+
[self enableUI: NO];
[self setupToolbar];
-
+
/* We disable the Turbo 1st pass checkbox since we are not x264 */
[fVidTurboPassCheck setEnabled: NO];
[fVidTurboPassCheck setState: NSOffState];
-
-
+
+
/* lets get our default prefs here */
[self getDefaultPresets:nil];
/* lets initialize the current successful scancount here to 0 */
currentSuccessfulScanCount = 0;
-
-
+
+
}
- (void) enableUI: (bool) b
{
NSControl * controls[] =
- { fSrcTitleField, fSrcTitlePopUp,
+ { fSrcTitleField, fSrcTitlePopUp,
fSrcChapterField, fSrcChapterStartPopUp, fSrcChapterToField,
fSrcChapterEndPopUp, fSrcDuration1Field, fSrcDuration2Field,
fDstFormatField, fDstFormatPopUp, fDstFile1Field, fDstFile2Field,
- fDstBrowseButton, fVidRateField, fVidRatePopUp,
- fVidEncoderField, fVidEncoderPopUp, fVidQualityField,
- fVidQualityMatrix, fVidGrayscaleCheck, fSubField, fSubPopUp,
+ fDstBrowseButton, fVidRateField, fVidRatePopUp,fVidEncoderField, fVidEncoderPopUp, fVidQualityField,
+ fPictureSizeField,fPictureCroppingField, fVideoFiltersField,fVidQualityMatrix, fSubField, fSubPopUp,
fAudSourceLabel, fAudCodecLabel, fAudMixdownLabel, fAudSamplerateLabel, fAudBitrateLabel,
fAudTrack1Label, fAudTrack2Label, fAudTrack3Label, fAudTrack4Label,
fAudLang1PopUp, fAudLang2PopUp, fAudLang3PopUp, fAudLang4PopUp,
fAudTrack1BitratePopUp, fAudTrack2BitratePopUp, fAudTrack3BitratePopUp, fAudTrack4BitratePopUp,
fAudDrcLabel, fAudTrack1DrcSlider, fAudTrack1DrcField, fAudTrack2DrcSlider,
fAudTrack2DrcField, fAudTrack3DrcSlider, fAudTrack3DrcField, fAudTrack4DrcSlider,fAudTrack4DrcField,
- fPictureButton,fQueueStatus,fPicSettingARkeep, fPicSettingDeinterlace,fPicLabelSettings,fPicLabelSrc,
- fPicLabelOutp,fPicSettingsSrc,fPicSettingsOutp,fPicSettingsAnamorphic,
- fPicLabelAr,fPicLabelDeinterlace,fPicSettingPAR,fPicLabelAnamorphic,fPresetsAdd,fPresetsDelete,
- fCreateChapterMarkers,fVidTurboPassCheck,fDstMp4LargeFileCheck,fPicLabelAutoCrop,
- fPicSettingAutoCrop,fPicSettingDetelecine,fPicLabelDetelecine,fPicLabelDenoise,fPicSettingDenoise,
- fSubForcedCheck,fPicSettingDeblock,fPicLabelDeblock,fPicLabelDecomb,fPicSettingDecomb,fPresetsOutlineView,
- fAudDrcLabel,fDstMp4HttpOptFileCheck,fDstMp4iPodFileCheck};
-
+ fQueueStatus,fPresetsAdd,fPresetsDelete,fSrcAngleLabel,fSrcAnglePopUp,
+ fCreateChapterMarkers,fVidTurboPassCheck,fDstMp4LargeFileCheck,fSubForcedCheck,fPresetsOutlineView,
+ fAudDrcLabel,fDstMp4HttpOptFileCheck,fDstMp4iPodFileCheck,fVidQualityRFField,fVidQualityRFLabel};
+
for( unsigned i = 0;
- i < sizeof( controls ) / sizeof( NSControl * ); i++ )
+ i < sizeof( controls ) / sizeof( NSControl * ); i++ )
{
if( [[controls[i] className] isEqualToString: @"NSTextField"] )
{
if( ![tf isBezeled] )
{
[tf setTextColor: b ? [NSColor controlTextColor] :
- [NSColor disabledControlTextColor]];
+ [NSColor disabledControlTextColor]];
continue;
}
}
[controls[i] setEnabled: b];
-
+
}
-
+
if (b) {
-
+
/* if we're enabling the interface, check if the audio mixdown controls need to be enabled or not */
/* these will have been enabled by the mass control enablement above anyway, so we're sense-checking it here */
[self setEnabledStateOfAudioMixdownControls:nil];
/* we also call calculatePictureSizing here to sense check if we already have vfr selected */
[self calculatePictureSizing:nil];
-
+
} else {
-
+
[fPresetsOutlineView setEnabled: NO];
-
+
}
-
+
[self videoMatrixChanged:nil];
[fAdvancedOptions enableUI:b];
}
**********************************************************************/
- (void) UpdateDockIcon: (float) progress
{
- NSImage * icon;
NSData * tiff;
NSBitmapImageRep * bmp;
uint32_t * pen;
int row_start, row_end;
int i, j;
- /* Get application original icon */
- icon = [NSImage imageNamed: @"NSApplicationIcon"];
-
if( progress < 0.0 || progress > 1.0 )
{
- [NSApp setApplicationIconImage: icon];
+ [NSApp setApplicationIconImage: fApplicationIcon];
return;
}
/* Get it in a raw bitmap form */
- tiff = [icon TIFFRepresentationUsingCompression:
+ tiff = [fApplicationIcon TIFFRepresentationUsingCompression:
NSTIFFCompressionNone factor: 1.0];
bmp = [NSBitmapImageRep imageRepWithData: tiff];
/* Now update the dock icon */
tiff = [bmp TIFFRepresentationUsingCompression:
NSTIFFCompressionNone factor: 1.0];
- icon = [[NSImage alloc] initWithData: tiff];
+ NSImage* icon = [[NSImage alloc] initWithData: tiff];
[NSApp setApplicationIconImage: icon];
[icon release];
}
NSLocalizedString( @"Scanning title %d of %d...", @"" ),
p.title_cur, p.title_count]];
[fScanIndicator setHidden: NO];
- [fScanIndicator setDoubleValue: 100.0 * ( p.title_cur - 1 ) / p.title_count];
+ [fScanIndicator setDoubleValue: 100.0 * ((double)( p.title_cur - 1 ) / p.title_count)];
break;
}
#undef p
[fQueueController setQueueStatusString: [NSString stringWithFormat:
NSLocalizedString( @"Queue Scanning title %d of %d...", @"" ),
p.title_cur, p.title_count]];
-
- [fRipIndicator setHidden: NO];
- [fRipIndicator setDoubleValue: 100.0 * ( p.title_cur - 1 ) / p.title_count];
break;
}
#undef p
#define p s.param.scandone
case HB_STATE_SCANDONE:
{
- [fRipIndicator setIndeterminate: NO];
- [fRipIndicator setDoubleValue: 0.0];
-
[self writeToActivityLog:"ScanDone state received from fQueueEncodeLibhb"];
[self processNewQueueEncode];
[[fWindow toolbar] validateVisibleItems];
#define p s.param.working
case HB_STATE_WORKING:
{
- float progress_total;
NSMutableString * string;
/* Update text field */
string = [NSMutableString stringWithFormat: NSLocalizedString( @"Encoding: pass %d of %d, %.2f %%", @"" ), p.job_cur, p.job_count, 100.0 * p.progress];
/* Set the status string in fQueueController as well */
[fQueueController setQueueStatusString: string];
/* Update slider */
- progress_total = ( p.progress + p.job_cur - 1 ) / p.job_count;
+ CGFloat progress_total = ( p.progress + p.job_cur - 1 ) / p.job_count;
[fRipIndicator setIndeterminate: NO];
- [fRipIndicator setDoubleValue: 100.0 * progress_total];
+ [fRipIndicator setDoubleValue:100.0 * progress_total];
// If progress bar hasn't been revealed at the bottom of the window, do
// that now. This code used to be in doRip. I moved it to here to handle
fRipIndicatorShown = YES;
}
-
+
/* Update dock icon */
- [self UpdateDockIcon: progress_total];
-
+ if( dockIconProgress < 100.0 * progress_total )
+ {
+ [self UpdateDockIcon: progress_total];
+ dockIconProgress += 5;
+ }
+
break;
}
#undef p
/* Set the status string in fQueueController as well */
[fQueueController setQueueStatusString: NSLocalizedString( @"Encode Finished.", @"" )];
[fRipIndicator setIndeterminate: NO];
+ [fRipIndicator stopAnimation: nil];
[fRipIndicator setDoubleValue: 0.0];
[[fWindow toolbar] validateVisibleItems];
/* Restore dock icon */
[self UpdateDockIcon: -1.0];
+ dockIconProgress = 0;
if( fRipIndicatorShown )
{
}
/* We use this to write messages to stderr from the macgui which show up in the activity window and log*/
-- (void) writeToActivityLog:(char *) format, ...
+- (void) writeToActivityLog:(const char *) format, ...
{
va_list args;
va_start(args, format);
[item setTarget: self];
[item setAction: @selector(Pause:)];
}
- else if ([itemIdent isEqualToString: ShowActivityIdentifier]) {
+ else if ([itemIdent isEqualToString: ShowPictureIdentifier])
+ {
+ [item setLabel: @"Picture Settings"];
+ [item setPaletteLabel: @"Show Picture Settings"];
+ [item setToolTip: @"Show Picture Settings"];
+ [item setImage: [NSImage imageNamed: @"pref-picture"]];
+ [item setTarget: self];
+ [item setAction: @selector(showPicturePanel:)];
+ }
+ else if ([itemIdent isEqualToString: ShowPreviewIdentifier])
+ {
+ [item setLabel: @"Preview Window"];
+ [item setPaletteLabel: @"Show Preview"];
+ [item setToolTip: @"Show Preview"];
+ //[item setImage: [NSImage imageNamed: @"pref-picture"]];
+ [item setImage: [NSImage imageNamed: @"Brushed_Window"]];
+ [item setTarget: self];
+ [item setAction: @selector(showPreviewWindow:)];
+ }
+ else if ([itemIdent isEqualToString: ShowActivityIdentifier])
+ {
[item setLabel: @"Activity Window"];
[item setPaletteLabel: @"Show Activity Window"];
[item setToolTip: @"Show Activity Window"];
{
return [NSArray arrayWithObjects: ChooseSourceIdentifier, NSToolbarSeparatorItemIdentifier, StartEncodingIdentifier,
PauseEncodingIdentifier, AddToQueueIdentifier, ShowQueueIdentifier, NSToolbarFlexibleSpaceItemIdentifier,
- NSToolbarSpaceItemIdentifier, ShowActivityIdentifier, ToggleDrawerIdentifier, nil];
+ NSToolbarSpaceItemIdentifier, ShowPictureIdentifier, ShowPreviewIdentifier, ShowActivityIdentifier, ToggleDrawerIdentifier, nil];
}
- (NSArray *) toolbarAllowedItemIdentifiers: (NSToolbar *) toolbar
{
return [NSArray arrayWithObjects: StartEncodingIdentifier, PauseEncodingIdentifier, AddToQueueIdentifier,
- ChooseSourceIdentifier, ShowQueueIdentifier, ShowActivityIdentifier, ToggleDrawerIdentifier,
+ ChooseSourceIdentifier, ShowQueueIdentifier, ShowPictureIdentifier, ShowPreviewIdentifier, ShowActivityIdentifier, ToggleDrawerIdentifier,
NSToolbarCustomizeToolbarItemIdentifier, NSToolbarFlexibleSpaceItemIdentifier,
NSToolbarSpaceItemIdentifier, NSToolbarSeparatorItemIdentifier, nil];
}
return YES;
}
if (SuccessfulScan)
+ {
if ([ident isEqualToString: AddToQueueIdentifier])
return YES;
+ if ([ident isEqualToString: ShowPictureIdentifier])
+ return YES;
+ if ([ident isEqualToString: ShowPreviewIdentifier])
+ return YES;
+ }
}
else if (s.state == HB_STATE_PAUSED)
{
return YES;
if ([ident isEqualToString: AddToQueueIdentifier])
return YES;
+ if ([ident isEqualToString: ShowPictureIdentifier])
+ return YES;
+ if ([ident isEqualToString: ShowPreviewIdentifier])
+ return YES;
}
else if (s.state == HB_STATE_SCANNING)
return NO;
}
if ([ident isEqualToString: AddToQueueIdentifier])
return YES;
+ if ([ident isEqualToString: ShowPictureIdentifier])
+ return YES;
+ if ([ident isEqualToString: ShowPreviewIdentifier])
+ return YES;
}
}
}
}
+- (IBAction)showAboutPanel:(id)sender
+{
+ NSMutableDictionary* d = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
+ fApplicationIcon, @"ApplicationIcon",
+ nil ];
+ [NSApp orderFrontStandardAboutPanelWithOptions:d];
+ [d release];
+}
+
/* Here we open the title selection sheet where we can specify an exact title to be scanned */
- (IBAction) showSourceTitleScanPanel: (id) sender
{
BOOL cancelScanDecrypt = 0;
NSString *path = scanPath;
HBDVDDetector *detector = [HBDVDDetector detectorForPath:path];
-
+
// Notify ChapterTitles that there's no title
[fChapterTitlesDelegate resetWithTitle:nil];
[fChapterTable reloadData];
-
+
+ // Notify Subtitles that there's no title
+ [fSubtitlesDelegate resetWithTitle:nil];
+ [fSubtitlesTable reloadData];
+
[self enableUI: NO];
-
+
if( [detector isVideoDVD] )
{
// The chosen path was actually on a DVD, so use the raw block
// device path instead.
path = [detector devicePath];
[self writeToActivityLog: "trying to open a physical dvd at: %s", [scanPath UTF8String]];
+
+#if defined( __LP64__ )
+ /* If we are 64 bit, we cannot read encrypted dvd's as vlc is 32 bit only */
+ cancelScanDecrypt = 1;
+ [self writeToActivityLog: "64 bit mode cannot read dvd's, scan cancelled"];
+ /*On Screen Notification*/
+ int status;
+ NSBeep();
+ status = NSRunAlertPanel(@"64-bit HandBrake cannot read encrypted dvds!",@"", @"Cancel Scan", @"Attempt Scan Anyway", nil);
+ [NSApp requestUserAttention:NSCriticalRequest];
+
+ if (status == NSAlertDefaultReturn)
+ {
+ /* User chose to cancel the scan */
+ [self writeToActivityLog: "cannot open physical dvd , scan cancelled"];
+ cancelScanDecrypt = 1;
+ }
+ else
+ {
+ [self writeToActivityLog: "user overrode 64-bit warning trying to open physical dvd without decryption"];
+ cancelScanDecrypt = 0;
+ }
+#else
/* lets check for vlc here to make sure we have a dylib available to use for decrypting */
- NSString *vlcPath = @"/Applications/VLC.app";
+ NSString *vlcPath = @"/Applications/VLC.app/Contents/MacOS/lib/libdvdcss.2.dylib";
NSFileManager * fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:vlcPath] == 0)
{
cancelScanDecrypt = 1;
[self writeToActivityLog: "VLC app not found for decrypting physical dvd"];
int status;
- status = NSRunAlertPanel(@"HandBrake could not find VLC.",@"Please download and install VLC media player in your /Applications folder if you wish to read encrypted DVDs.", @"Get VLC", @"Cancel Scan", @"Attempt Scan Anyway");
+ status = NSRunAlertPanel(@"HandBrake could not find VLC or your VLC is out of date.",@"Please download and install VLC media player in your /Applications folder if you wish to read encrypted DVDs.", @"Get VLC", @"Cancel Scan", @"Attempt Scan Anyway");
[NSApp requestUserAttention:NSCriticalRequest];
if (status == NSAlertDefaultReturn)
}
else if (status == NSAlertAlternateReturn)
{
- /* User chose to cancel the scan */
- [self writeToActivityLog: "cannot open physical dvd , scan cancelled"];
+ /* User chose to cancel the scan */
+ [self writeToActivityLog: "cannot open physical dvd , scan cancelled"];
}
else
{
- /* User chose to override our warning and scan the physical dvd anyway, at their own peril. on an encrypted dvd this produces massive log files and fails */
- cancelScanDecrypt = 0;
- [self writeToActivityLog: "user overrode vlc warning -trying to open physical dvd without decryption"];
+ /* User chose to override our warning and scan the physical dvd anyway, at their own peril. on an encrypted dvd this produces massive log files and fails */
+ cancelScanDecrypt = 0;
+ [self writeToActivityLog: "user overrode vlc warning -trying to open physical dvd without decryption"];
}
-
+
}
else
{
/* VLC was found in /Applications so all is well, we can carry on using vlc's libdvdcss.dylib for decrypting if needed */
[self writeToActivityLog: "VLC app found for decrypting physical dvd"];
}
+#endif
}
-
+
if (cancelScanDecrypt == 0)
{
/* we actually pass the scan off to libhb here */
}
/* 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 ..."];
}
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];
}
SuccessfulScan = YES;
[self enableUI: YES];
- /* if its the initial successful scan after awakeFromNib */
- if (currentSuccessfulScanCount == 1)
- {
- [self selectDefaultPreset:nil];
- /* initially set deinterlace to 0, will be overridden reset by the default preset anyway */
- //[fPictureController setDeinterlace:0];
-
- /* lets set Denoise to index 0 or "None" since this is the first scan */
- //[fPictureController setDenoise:0];
-
- [fPictureController setInitialPictureFilters];
- }
+ /* if its the initial successful scan after awakeFromNib */
+ if (currentSuccessfulScanCount == 1)
+ {
+ [self selectDefaultPreset:nil];
+
+ // Open preview window now if it was visible when HB was closed
+ if ([[NSUserDefaults standardUserDefaults] boolForKey:@"PreviewWindowIsOpen"])
+ [self showPreviewWindow:nil];
+
+ // Open picture sizing window now if it was visible when HB was closed
+ if ([[NSUserDefaults standardUserDefaults] boolForKey:@"PictureSizeWindowIsOpen"])
+ [self showPicturePanel:nil];
+
+ }
}
}
- (void) browseFileDone: (NSSavePanel *) sheet
- returnCode: (int) returnCode contextInfo: (void *) contextInfo
+ returnCode: (int) returnCode contextInfo: (void *) contextInfo
{
if( returnCode == NSOKButton )
{
[fDstFile2Field setStringValue: [sheet filename]];
+ /* Save this path to the prefs so that on next browse destination window it opens there */
+ NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent];
+ [[NSUserDefaults standardUserDefaults] setObject:destinationDirectory forKey:@"LastDestinationDirectory"];
}
}
return NO;
}
+- (NSSize) drawerWillResizeContents:(NSDrawer *) drawer toSize:(NSSize) contentSize {
+ [[NSUserDefaults standardUserDefaults] setObject:NSStringFromSize( contentSize ) forKey:@"Drawer Size"];
+ return contentSize;
+}
#pragma mark -
#pragma mark Queue File
[queueFileJob setObject:[NSString stringWithUTF8String: title->dvd] forKey:@"SourcePath"];
[queueFileJob setObject:[fSrcDVD2Field stringValue] forKey:@"SourceName"];
[queueFileJob setObject:[NSNumber numberWithInt:title->index] forKey:@"TitleNumber"];
+ [queueFileJob setObject:[NSNumber numberWithInt:[fSrcAnglePopUp indexOfSelectedItem] + 1] forKey:@"TitleAngle"];
[queueFileJob setObject:[NSNumber numberWithInt:[fSrcChapterStartPopUp indexOfSelectedItem] + 1] forKey:@"ChapterStart"];
[queueFileJob setObject:[NSNumber numberWithInt:[fSrcChapterEndPopUp indexOfSelectedItem] + 1] forKey:@"ChapterEnd"];
[queueFileJob setObject:[NSNumber numberWithInt:[fPresetsOutlineView selectedRow]] forKey:@"PresetIndexNum"];
[queueFileJob setObject:[fDstFormatPopUp titleOfSelectedItem] forKey:@"FileFormat"];
- /* Chapter Markers fCreateChapterMarkers*/
- [queueFileJob setObject:[NSNumber numberWithInt:[fCreateChapterMarkers state]] forKey:@"ChapterMarkers"];
+ /* Chapter Markers*/
+ /* If we have only one chapter or a title without chapters, set chapter markers to off */
+ if ([fSrcChapterStartPopUp indexOfSelectedItem] == [fSrcChapterEndPopUp indexOfSelectedItem])
+ {
+ [queueFileJob setObject:[NSNumber numberWithInt:0] forKey:@"ChapterMarkers"];
+ }
+ else
+ {
+ [queueFileJob setObject:[NSNumber numberWithInt:[fCreateChapterMarkers state]] forKey:@"ChapterMarkers"];
+ }
/* We need to get the list of chapter names to put into an array and store
* in our queue, so they can be reapplied in prepareJob when this queue
[queueFileJob setObject:[NSNumber numberWithInt:[fVidQualityMatrix selectedRow]] forKey:@"VideoQualityType"];
[queueFileJob setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
[queueFileJob setObject:[fVidBitrateField stringValue] forKey:@"VideoAvgBitrate"];
- [queueFileJob setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
+ [queueFileJob setObject:[NSNumber numberWithFloat:[fVidQualityRFField floatValue]] forKey:@"VideoQualitySlider"];
/* Framerate */
[queueFileJob setObject:[fVidRatePopUp titleOfSelectedItem] forKey:@"VideoFramerate"];
- /* GrayScale */
- [queueFileJob setObject:[NSNumber numberWithInt:[fVidGrayscaleCheck state]] forKey:@"VideoGrayScale"];
/* 2 Pass Encoding */
[queueFileJob setObject:[NSNumber numberWithInt:[fVidTwoPassCheck state]] forKey:@"VideoTwoPass"];
/* Turbo 2 pass Encoding fVidTurboPassCheck*/
[queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->width] forKey:@"PictureWidth"];
[queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->height] forKey:@"PictureHeight"];
[queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->keep_ratio] forKey:@"PictureKeepRatio"];
- [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->pixel_ratio] forKey:@"PicturePAR"];
+ [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->anamorphic.mode] forKey:@"PicturePAR"];
+ /* if we are custom anamorphic, store the exact storage, par and display dims */
+ if (fTitle->job->anamorphic.mode == 3)
+ {
+ [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->width] forKey:@"PicturePARStorageWidth"];
+ [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->height] forKey:@"PicturePARStorageHeight"];
+
+ [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->anamorphic.par_width] forKey:@"PicturePARPixelWidth"];
+ [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->anamorphic.par_height] forKey:@"PicturePARPixelHeight"];
+
+ [queueFileJob setObject:[NSNumber numberWithFloat:fTitle->job->anamorphic.dar_width] forKey:@"PicturePARDisplayWidth"];
+ [queueFileJob setObject:[NSNumber numberWithFloat:fTitle->job->anamorphic.dar_height] forKey:@"PicturePARDisplayHeight"];
+
+ }
NSString * pictureSummary;
- pictureSummary = [NSString stringWithFormat:@"Source: %@ Output: %@ Anamorphic: %@",
- [fPicSettingsSrc stringValue],
- [fPicSettingsOutp stringValue],
- [fPicSettingsAnamorphic stringValue]];
+ pictureSummary = [fPictureSizeField stringValue];
[queueFileJob setObject:pictureSummary forKey:@"PictureSizingSummary"];
/* Set crop settings here */
[queueFileJob setObject:[NSNumber numberWithInt:[fPictureController autoCrop]] forKey:@"PictureAutoCrop"];
[queueFileJob setObject:[NSNumber numberWithInt:job->crop[3]] forKey:@"PictureRightCrop"];
/* Picture Filters */
+ [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController detelecine]] forKey:@"PictureDetelecine"];
+ [queueFileJob setObject:[fPictureController detelecineCustomString] forKey:@"PictureDetelecineCustom"];
+
+ [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController useDecomb]] forKey:@"PictureDecombDeinterlace"];
+ [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController decomb]] forKey:@"PictureDecomb"];
+ [queueFileJob setObject:[fPictureController decombCustomString] forKey:@"PictureDecombCustom"];
+
[queueFileJob setObject:[NSNumber numberWithInt:[fPictureController deinterlace]] forKey:@"PictureDeinterlace"];
- [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController detelecine]] forKey:@"PictureDetelecine"];
+ [queueFileJob setObject:[fPictureController deinterlaceCustomString] forKey:@"PictureDeinterlaceCustom"];
+
[queueFileJob setObject:[NSNumber numberWithInt:[fPictureController denoise]] forKey:@"PictureDenoise"];
- [queueFileJob setObject:[NSString stringWithFormat:@"%d",[fPictureController deblock]] forKey:@"PictureDeblock"];
- [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController decomb]] forKey:@"PictureDecomb"];
+ [queueFileJob setObject:[fPictureController denoiseCustomString] forKey:@"PictureDenoiseCustom"];
+
+ [queueFileJob setObject:[NSString stringWithFormat:@"%d",[fPictureController deblock]] forKey:@"PictureDeblock"];
+
+ [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController grayscale]] forKey:@"VideoGrayScale"];
/*Audio*/
if ([fAudLang1PopUp indexOfSelectedItem] > 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"];
[queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->width] forKey:@"PictureWidth"];
[queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->height] forKey:@"PictureHeight"];
[queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->keep_ratio] forKey:@"PictureKeepRatio"];
- [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->pixel_ratio] forKey:@"PicturePAR"];
+ [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->anamorphic.mode] forKey:@"PicturePAR"];
/* Set crop settings here */
[queueFileJob setObject:[NSNumber numberWithInt:[fPictureController autoCrop]] forKey:@"PictureAutoCrop"];
[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)
[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];
}
/* this is actually called from the queue controller to modify the queue array and return it back to the queue controller */
-- (void)moveObjectsInQueueArray:(NSMutableArray *)array fromIndexes:(NSIndexSet *)indexSet toIndex:(unsigned)insertIndex
+- (void)moveObjectsInQueueArray:(NSMutableArray *)array fromIndexes:(NSIndexSet *)indexSet toIndex:(NSUInteger)insertIndex
{
- unsigned index = [indexSet lastIndex];
- unsigned aboveInsertIndexCount = 0;
+ NSUInteger index = [indexSet lastIndex];
+ NSUInteger aboveInsertIndexCount = 0;
- while (index != NSNotFound)
- {
- unsigned removeIndex;
-
- if (index >= insertIndex)
- {
- removeIndex = index + aboveInsertIndexCount;
- aboveInsertIndexCount++;
- }
- else
- {
- removeIndex = index;
- insertIndex--;
- }
-
- id object = [[QueueFileArray objectAtIndex:removeIndex] retain];
- [QueueFileArray removeObjectAtIndex:removeIndex];
- [QueueFileArray insertObject:object atIndex:insertIndex];
- [object release];
+
+ NSUInteger removeIndex;
- index = [indexSet indexLessThanIndex:index];
+ if (index >= insertIndex)
+ {
+ removeIndex = index + aboveInsertIndexCount;
+ aboveInsertIndexCount++;
+ }
+ else
+ {
+ removeIndex = index;
+ insertIndex--;
}
+
+ id object = [[QueueFileArray objectAtIndex:removeIndex] retain];
+ [QueueFileArray removeObjectAtIndex:removeIndex];
+ [QueueFileArray insertObject:object atIndex:insertIndex];
+ [object release];
+
+ index = [indexSet indexLessThanIndex:index];
+
/* We save all of the Queue data here
* and it also gets sent back to the queue controller*/
[self saveQueueFileItem];
//status = NSRunAlertPanel(@"HandBrake is now loading up a new queue item...",@"Would You Like to wait until you add another encode?", @"Cancel", @"Okay", nil);
//[NSApp requestUserAttention:NSCriticalRequest];
- // Notify ChapterTitles that there's no title
- [fChapterTitlesDelegate resetWithTitle:nil];
- [fChapterTable reloadData];
-
- //[self enableUI: NO];
-
if( [detector isVideoDVD] )
{
// The chosen path was actually on a DVD, so use the raw block
[fVidRatePopUp selectItemWithTitle:[queueToApply objectForKey:@"VideoFramerate"]];
}
- /* GrayScale */
- [fVidGrayscaleCheck setState:[[queueToApply objectForKey:@"VideoGrayScale"] intValue]];
-
/* 2 Pass Encoding */
[fVidTwoPassCheck setState:[[queueToApply objectForKey:@"VideoTwoPass"] intValue]];
[self twoPassCheckboxChanged:nil];
hb_fix_aspect( job, HB_KEEP_HEIGHT );
}
}
- job->pixel_ratio = [[queueToApply objectForKey:@"PicturePAR"] intValue];
+ job->anamorphic.mode = [[queueToApply objectForKey:@"PicturePAR"] intValue];
/* If Cropping is set to custom, then recall all four crop values from
[fPictureController setDeblock:[[queueToApply objectForKey:@"PictureDeblock"] intValue]];
/* Decomb */
[fPictureController setDecomb:[[queueToApply objectForKey:@"PictureDecomb"] intValue]];
+ /* Grayscale */
+ [fPictureController setGrayscale:[[queueToApply objectForKey:@"VideoGrayScale"] intValue]];
[self calculatePictureSizing:nil];
{
[self writeToActivityLog: "processNewQueueEncode WARNING nothing found in the title list"];
}
- else
- {
- [self writeToActivityLog: "processNewQueueEncode title list is: %d", hb_list_count( list )];
- }
NSMutableDictionary * queueToApply = [QueueFileArray objectAtIndex:currentQueueEncodeIndex];
[self writeToActivityLog: "Preset: %s", [[queueToApply objectForKey:@"PresetName"] UTF8String]];
job->file = [[queueToApply objectForKey:@"DestinationPath"] UTF8String];
//[self writeToActivityLog: "processNewQueueEncode sending to prepareJob"];
[self prepareJob];
- if( [[queueToApply objectForKey:@"SubtitlesForced"] intValue] == 1 )
- job->subtitle_force = 1;
- else
- job->subtitle_force = 0;
/*
- * subtitle of -1 is a scan
+ * If scanning we need to do some extra setup of the job.
*/
- if( job->subtitle == -1 )
+ if( job->indepth_scan == 1 )
{
char *x264opts_tmp;
*/
job->pass = -1;
x264opts_tmp = job->x264opts;
- job->subtitle = -1;
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
hb_add( fQueueEncodeLibhb, job );
job->x264opts = x264opts_tmp;
}
- else
- job->select_subtitle = NULL;
-
- /* No subtitle were selected, so reset the subtitle to -1 (which before
- * this point meant we were scanning
- */
- if( job->subtitle == -2 )
- job->subtitle = -1;
+
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;
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 );
}
/* 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];
}
[fSrcTitlePopUp indexOfSelectedItem] );
hb_job_t * job = title->job;
hb_audio_config_t * audio;
-
+ /* set job->angle for libdvdnav */
+ job->angle = [fSrcAnglePopUp indexOfSelectedItem] + 1;
/* Chapter selection */
job->chapter_start = [fSrcChapterStartPopUp indexOfSelectedItem] + 1;
job->chapter_end = [fSrcChapterEndPopUp indexOfSelectedItem] + 1;
job->mux = [[fDstFormatPopUp selectedItem] tag];
job->vcodec = [[fVidEncoderPopUp selectedItem] tag];
-
- /* If mpeg-4, then set mpeg-4 specific options like chapters and > 4gb file sizes */
- if( [fDstFormatPopUp indexOfSelectedItem] == 0 )
- {
- /* We set the largeFileSize (64 bit formatting) variable here to allow for > 4gb files based on the format being
- mpeg4 and the checkbox being checked
- *Note: this will break compatibility with some target devices like iPod, etc.!!!!*/
- if( [fDstMp4LargeFileCheck state] == NSOnState )
- {
- job->largeFileSize = 1;
- }
- else
- {
- job->largeFileSize = 0;
- }
- /* We set http optimized mp4 here */
- if( [fDstMp4HttpOptFileCheck state] == NSOnState && [fDstMp4HttpOptFileCheck isEnabled] )
- {
- job->mp4_optimize = 1;
- }
- else
- {
- job->mp4_optimize = 0;
- }
- }
- if( [fDstFormatPopUp indexOfSelectedItem] == 0 || [fDstFormatPopUp indexOfSelectedItem] == 1 )
- {
- /* We set the chapter marker extraction here based on the format being
- mpeg4 or mkv and the checkbox being checked */
- if ([fCreateChapterMarkers state] == NSOnState)
- {
- job->chapter_markers = 1;
- }
- else
- {
- job->chapter_markers = 0;
- }
- }
-
- if( job->vcodec & HB_VCODEC_X264 )
+ job->chapter_markers = 0;
+
+ if( job->vcodec & HB_VCODEC_X264 )
{
- if ([fDstMp4iPodFileCheck state] == NSOnState)
- {
- job->ipod_atom = 1;
- }
- else
- {
- job->ipod_atom = 0;
- }
-
/* Set this flag to switch from Constant Quantizer(default) to Constant Rate Factor Thanks jbrjake
Currently only used with Constant Quality setting*/
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultCrf"] > 0 && [fVidQualityMatrix selectedRow] == 2)
job->vbitrate = [fVidBitrateField intValue];
break;
case 2:
- job->vquality = [fVidQualitySlider floatValue];
+ job->vquality = [fVidQualityRFField floatValue];
job->vbitrate = 0;
break;
}
- job->grayscale = ( [fVidGrayscaleCheck state] == NSOnState );
-
/* Subtitle settings */
- job->subtitle = [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])
+ {
+
+ 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.
+ */
+ if (subtitle > 0)
+ {
+ /* 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;
+ }
+ else
+ {
+ job->select_subtitle_config.dest = hb_subtitle_config_s::RENDERSUB;
+ }
+
+ 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;
+
+ subt = (hb_subtitle_t *)hb_list_item(title->list_subtitle, subtitle);
+
+ if (subt != NULL)
+ {
+ [self writeToActivityLog: "Setting Subtitle: %s", subt];
+ hb_subtitle_config_t sub_config = subt->config;
+
+ 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);
- /* Filters */
+ /* Filters */
+
+ /* Though Grayscale is not really a filter, per se
+ * we put it here since its in the filters panel
+ */
+
+ if ([fPictureController grayscale])
+ {
+ job->grayscale = 1;
+ }
+ else
+ {
+ job->grayscale = 0;
+ }
+
+ /* Initialize the filters list */
job->filters = hb_list_init();
/* Now lets call the filters if applicable.
*/
/* Detelecine */
- if ([fPictureController detelecine])
+ if ([fPictureController detelecine] == 1)
{
hb_list_add( job->filters, &hb_filter_detelecine );
}
-
- /* Decomb */
- if ([fPictureController decomb] > 0)
- {
- /* Run old deinterlacer fd by default */
- //fPicSettingDecomb
- hb_filter_decomb.settings = (char *) [[fPicSettingDecomb stringValue] UTF8String];
- //hb_filter_decomb.settings = "4:10:15:9:10:35:9"; // <-- jbrjakes recommended parameters as of 5/23/08
- hb_list_add( job->filters, &hb_filter_decomb );
- }
-
-
- /* Deinterlace */
- if ([fPictureController deinterlace] == 1)
+ if ([fPictureController detelecine] == 2)
{
- /* Run old deinterlacer fd by default */
- hb_filter_deinterlace.settings = "-1";
- hb_list_add( job->filters, &hb_filter_deinterlace );
+ /* use a custom detelecine string */
+ hb_filter_detelecine.settings = (char *) [[fPictureController detelecineCustomString] UTF8String];
+ hb_list_add( job->filters, &hb_filter_detelecine );
}
- else if ([fPictureController deinterlace] == 2)
+ if ([fPictureController useDecomb] == 1)
{
- /* Yadif mode 0 (without spatial deinterlacing.) */
- hb_filter_deinterlace.settings = "2";
- hb_list_add( job->filters, &hb_filter_deinterlace );
+ /* Decomb */
+ if ([fPictureController decomb] == 1)
+ {
+ /* Run old deinterlacer fd by default */
+ //hb_filter_decomb.settings = (char *) [[fPicSettingDecomb stringValue] UTF8String];
+ hb_list_add( job->filters, &hb_filter_decomb );
+ }
+ /* we add the custom string if present */
+ if ([fPictureController decomb] == 2)
+ {
+ /* use a custom decomb string */
+ hb_filter_decomb.settings = (char *) [[fPictureController decombCustomString] UTF8String];
+ hb_list_add( job->filters, &hb_filter_decomb );
+ }
}
- else if ([fPictureController deinterlace] == 3)
+ else
{
- /* Yadif (with spatial deinterlacing) */
- hb_filter_deinterlace.settings = "0";
- hb_list_add( job->filters, &hb_filter_deinterlace );
- }
-
+
+ /* Deinterlace */
+ if ([fPictureController deinterlace] == 1)
+ {
+ /* Run old deinterlacer fd by default */
+ hb_filter_deinterlace.settings = "-1";
+ hb_list_add( job->filters, &hb_filter_deinterlace );
+ }
+ else if ([fPictureController deinterlace] == 2)
+ {
+ /* Yadif mode 0 (without spatial deinterlacing.) */
+ hb_filter_deinterlace.settings = "2";
+ hb_list_add( job->filters, &hb_filter_deinterlace );
+ }
+ else if ([fPictureController deinterlace] == 3)
+ {
+ /* Yadif (with spatial deinterlacing) */
+ hb_filter_deinterlace.settings = "0";
+ hb_list_add( job->filters, &hb_filter_deinterlace );
+ }
+ else if ([fPictureController deinterlace] == 4)
+ {
+ /* we add the custom string if present */
+ hb_filter_deinterlace.settings = (char *) [[fPictureController deinterlaceCustomString] UTF8String];
+ hb_list_add( job->filters, &hb_filter_deinterlace );
+ }
+ }
+
/* Denoise */
if ([fPictureController denoise] == 1) // Weak in popup
{
hb_filter_denoise.settings = "7:7:5:5";
hb_list_add( job->filters, &hb_filter_denoise );
}
+ else if ([fPictureController denoise] == 4) // custom in popup
+ {
+ /* we add the custom string if present */
+ hb_filter_denoise.settings = (char *) [[fPictureController denoiseCustomString] UTF8String];
+ hb_list_add( job->filters, &hb_filter_denoise );
+ }
/* Deblock (uses pp7 default) */
- if ([fPictureController deblock])
+ /* NOTE: even though there is a valid deblock setting of 0 for the filter, for
+ * the macgui's purposes a value of 0 actually means to not even use the filter
+ * current hb_filter_deblock.settings valid ranges are from 5 - 15
+ */
+ if ([fPictureController deblock] != 0)
{
+ NSString *deblockStringValue = [NSString stringWithFormat: @"%d",[fPictureController deblock]];
+ hb_filter_deblock.settings = (char *) [deblockStringValue UTF8String];
hb_list_add( job->filters, &hb_filter_deblock );
}
hb_title_t * title = (hb_title_t *) hb_list_item( list,0 ); // is always zero since now its a single title scan
hb_job_t * job = title->job;
hb_audio_config_t * audio;
+ /* Title Angle for dvdnav */
+ job->angle = [[queueToApply objectForKey:@"TitleAngle"] intValue];
/* Chapter selection */
job->chapter_start = [[queueToApply objectForKey:@"JobChapterStart"] intValue];
job->chapter_end = [[queueToApply objectForKey:@"JobChapterEnd"] intValue];
/* If mpeg-4, then set mpeg-4 specific options like chapters and > 4gb file sizes */
- //if( [fDstFormatPopUp indexOfSelectedItem] == 0 )
- //{
- /* We set the largeFileSize (64 bit formatting) variable here to allow for > 4gb files based on the format being
- mpeg4 and the checkbox being checked
- *Note: this will break compatibility with some target devices like iPod, etc.!!!!*/
if( [[queueToApply objectForKey:@"Mp4LargeFile"] intValue] == 1)
{
job->largeFileSize = 1;
{
job->mp4_optimize = 0;
}
-
- //}
+
/* We set the chapter marker extraction here based on the format being
mpeg4 or mkv and the checkbox being checked */
job->height = [[queueToApply objectForKey:@"PictureHeight"] intValue];
job->keep_ratio = [[queueToApply objectForKey:@"PictureKeepRatio"] intValue];
- job->pixel_ratio = [[queueToApply objectForKey:@"PicturePAR"] intValue];
-
+ job->anamorphic.mode = [[queueToApply objectForKey:@"PicturePAR"] intValue];
+ if ([[queueToApply objectForKey:@"PicturePAR"] intValue] == 3)
+ {
+ /* insert our custom values here for capuj */
+ job->width = [[queueToApply objectForKey:@"PicturePARStorageWidth"] intValue];
+ job->height = [[queueToApply objectForKey:@"PicturePARStorageHeight"] intValue];
+
+ job->anamorphic.par_width = [[queueToApply objectForKey:@"PicturePARPixelWidth"] intValue];
+ job->anamorphic.par_height = [[queueToApply objectForKey:@"PicturePARPixelHeight"] intValue];
+
+ job->anamorphic.dar_width = [[queueToApply objectForKey:@"PicturePARDisplayWidth"] floatValue];
+ job->anamorphic.dar_height = [[queueToApply objectForKey:@"PicturePARDisplayHeight"] floatValue];
+ }
/* Here we use the crop values saved at the time the preset was saved */
job->crop[0] = [[queueToApply objectForKey:@"PictureTopCrop"] intValue];
}
job->grayscale = [[queueToApply objectForKey:@"VideoGrayScale"] intValue];
- /* Subtitle settings */
- job->subtitle = [[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])
+ {
+
+ 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.
+ */
+ if (subtitle > 0)
+ {
+ /* 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;
+ }
+ else
+ {
+ job->select_subtitle_config.dest = hb_subtitle_config_s::RENDERSUB;
+ }
+
+ 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;
+
+ subt = (hb_subtitle_t *)hb_list_item(title->list_subtitle, subtitle);
+
+ if (subt != NULL)
+ {
+ [self writeToActivityLog: "Setting Subtitle: %s", subt];
+
+ hb_subtitle_config_t sub_config = subt->config;
+
+ 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);
audio->out.dynamic_range_compression = [[queueToApply objectForKey:@"Audio4TrackDRCSlider"] floatValue];
hb_audio_add( job, audio );
- free(audio);
+
+
}
/* Filters */
/* Detelecine */
if ([[queueToApply objectForKey:@"PictureDetelecine"] intValue] == 1)
{
+ //if ([queueToApply objectForKey:@"PictureDetelecineCustom"])
hb_list_add( job->filters, &hb_filter_detelecine );
}
-
- /* Decomb */
- if ([[queueToApply objectForKey:@"PictureDecomb"] intValue] == 1)
+ if ([[queueToApply objectForKey:@"PictureDetelecine"] intValue] == 2)
{
- /* Run old deinterlacer fd by default */
- hb_filter_decomb.settings = (char *) [[queueToApply objectForKey:@"JobPictureDecomb"] UTF8String];
- hb_list_add( job->filters, &hb_filter_decomb );
+ /* use a custom detelecine string */
+ hb_filter_detelecine.settings = (char *) [[queueToApply objectForKey:@"PictureDetelecineCustom"] UTF8String];
+ hb_list_add( job->filters, &hb_filter_detelecine );
}
- /* Deinterlace */
- if ([[queueToApply objectForKey:@"PictureDeinterlace"] intValue] == 1)
+ if ([[queueToApply objectForKey:@"PictureDecombDeinterlace"] intValue] == 1)
{
- /* Run old deinterlacer fd by default */
- hb_filter_deinterlace.settings = "-1";
- hb_list_add( job->filters, &hb_filter_deinterlace );
- }
- else if ([[queueToApply objectForKey:@"PictureDeinterlace"] intValue] == 2)
- {
- /* Yadif mode 0 (without spatial deinterlacing.) */
- hb_filter_deinterlace.settings = "2";
- hb_list_add( job->filters, &hb_filter_deinterlace );
+ /* Decomb */
+ if ([[queueToApply objectForKey:@"PictureDecomb"] intValue] == 1)
+ {
+ /* Run old deinterlacer fd by default */
+ hb_list_add( job->filters, &hb_filter_decomb );
+ }
+ /* we add the custom string if present */
+ if ([[queueToApply objectForKey:@"PictureDecomb"] intValue] == 2)
+ {
+ /* use a custom decomb string */
+ hb_filter_decomb.settings = (char *) [[queueToApply objectForKey:@"PictureDecombCustom"] UTF8String];
+ hb_list_add( job->filters, &hb_filter_decomb );
+ }
+
}
- else if ([[queueToApply objectForKey:@"PictureDeinterlace"] intValue] == 3)
+ else
{
- /* Yadif (with spatial deinterlacing) */
- hb_filter_deinterlace.settings = "0";
- hb_list_add( job->filters, &hb_filter_deinterlace );
+
+ /* Deinterlace */
+ if ([[queueToApply objectForKey:@"PictureDeinterlace"] intValue] == 1)
+ {
+ /* Run old deinterlacer fd by default */
+ hb_filter_deinterlace.settings = "-1";
+ hb_list_add( job->filters, &hb_filter_deinterlace );
+ }
+ else if ([[queueToApply objectForKey:@"PictureDeinterlace"] intValue] == 2)
+ {
+ /* Yadif mode 0 (without spatial deinterlacing.) */
+ hb_filter_deinterlace.settings = "2";
+ hb_list_add( job->filters, &hb_filter_deinterlace );
+ }
+ else if ([[queueToApply objectForKey:@"PictureDeinterlace"] intValue] == 3)
+ {
+ /* Yadif (with spatial deinterlacing) */
+ hb_filter_deinterlace.settings = "0";
+ hb_list_add( job->filters, &hb_filter_deinterlace );
+ }
+ else if ([[queueToApply objectForKey:@"PictureDeinterlace"] intValue] == 4)
+ {
+ /* we add the custom string if present */
+ hb_filter_deinterlace.settings = (char *) [[queueToApply objectForKey:@"PictureDeinterlaceCustom"] UTF8String];
+ hb_list_add( job->filters, &hb_filter_deinterlace );
+ }
+
+
}
-
/* Denoise */
if ([[queueToApply objectForKey:@"PictureDenoise"] intValue] == 1) // Weak in popup
{
hb_filter_denoise.settings = "7:7:5:5";
hb_list_add( job->filters, &hb_filter_denoise );
}
+ else if ([[queueToApply objectForKey:@"PictureDenoise"] intValue] == 4) // Custom in popup
+ {
+ /* we add the custom string if present */
+ hb_filter_denoise.settings = (char *) [[queueToApply objectForKey:@"PictureDenoiseCustom"] UTF8String];
+ hb_list_add( job->filters, &hb_filter_denoise );
+ }
/* Deblock (uses pp7 default) */
/* NOTE: even though there is a valid deblock setting of 0 for the filter, for
NSRunAlertPanel(@"Warning!", @"This is not a valid destination directory!", @"OK", nil, nil);
return;
}
-
- /* We check for duplicate name here */
- if( [[NSFileManager defaultManager] fileExistsAtPath:
- [fDstFile2Field stringValue]] )
+
+ BOOL fileExists;
+ fileExists = NO;
+
+ BOOL fileExistsInQueue;
+ fileExistsInQueue = NO;
+
+ /* We check for and existing file here */
+ if([[NSFileManager defaultManager] fileExistsAtPath: [fDstFile2Field stringValue]])
{
- NSBeginCriticalAlertSheet( NSLocalizedString( @"File already exists", @"" ),
- NSLocalizedString( @"Cancel", @"" ), NSLocalizedString( @"Overwrite", @"" ), nil, fWindow, self,
- @selector( overwriteAddToQueueAlertDone:returnCode:contextInfo: ),
- NULL, NULL, [NSString stringWithFormat:
- NSLocalizedString( @"Do you want to overwrite %@?", @"" ),
- [fDstFile2Field stringValue]] );
- // overwriteAddToQueueAlertDone: will be called when the alert is dismissed.
+ fileExists = YES;
+ }
+
+ /* We now run through the queue and make sure we are not overwriting an exisiting queue item */
+ int i = 0;
+ NSEnumerator *enumerator = [QueueFileArray objectEnumerator];
+ id tempObject;
+ while (tempObject = [enumerator nextObject])
+ {
+ NSDictionary *thisQueueDict = tempObject;
+ if ([[thisQueueDict objectForKey:@"DestinationPath"] isEqualToString: [fDstFile2Field stringValue]])
+ {
+ fileExistsInQueue = YES;
+ }
+ i++;
+ }
+
+
+ if(fileExists == YES)
+ {
+ NSBeginCriticalAlertSheet( NSLocalizedString( @"File already exists.", @"" ),
+ NSLocalizedString( @"Cancel", @"" ), NSLocalizedString( @"Overwrite", @"" ), nil, fWindow, self,
+ @selector( overwriteAddToQueueAlertDone:returnCode:contextInfo: ),
+ NULL, NULL, [NSString stringWithFormat:
+ NSLocalizedString( @"Do you want to overwrite %@?", @"" ),
+ [fDstFile2Field stringValue]] );
+ }
+ else if (fileExistsInQueue == YES)
+ {
+ NSBeginCriticalAlertSheet( NSLocalizedString( @"There is already a queue item for this destination.", @"" ),
+ NSLocalizedString( @"Cancel", @"" ), NSLocalizedString( @"Overwrite", @"" ), nil, fWindow, self,
+ @selector( overwriteAddToQueueAlertDone:returnCode:contextInfo: ),
+ NULL, NULL, [NSString stringWithFormat:
+ NSLocalizedString( @"Do you want to overwrite %@?", @"" ),
+ [fDstFile2Field stringValue]] );
}
else
{
otherwise, just rip the queue */
if(fPendingCount == 0)
{
- [self writeToActivityLog: "Rip: No pending jobs, so sending this one to doAddToQueue"];
- [self doAddToQueue];
+ [self writeToActivityLog: "Rip: No pending jobs, so sending this one to doAddToQueue"];
+ [self doAddToQueue];
}
- NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent];
- [[NSUserDefaults standardUserDefaults] setObject:destinationDirectory forKey:@"LastDestinationDirectory"];
/* go right to processing the new queue encode */
- [self writeToActivityLog: "Rip: Going right to performNewQueueScan"];
- [self performNewQueueScan:[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"SourcePath"] scanTitleNum:[[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"TitleNumber"]intValue]];
+ [self writeToActivityLog: "Rip: Going right to performNewQueueScan"];
+ [self performNewQueueScan:[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"SourcePath"] scanTitleNum:[[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"TitleNumber"]intValue]];
}
}
[fSrcChapterEndPopUp selectItemAtIndex:
hb_list_count( title->list_chapter ) - 1];
[self chapterPopUpChanged:nil];
-
+
+ /* if using dvd nav, show the angle widget */
+ if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"UseDvdNav"] boolValue])
+ {
+ [fSrcAngleLabel setHidden:NO];
+ [fSrcAnglePopUp setHidden:NO];
+
+ [fSrcAnglePopUp removeAllItems];
+ for( int i = 0; i < title->angle_count; i++ )
+ {
+ [fSrcAnglePopUp addItemWithTitle: [NSString stringWithFormat: @"%d", i + 1]];
+ }
+ [fSrcAnglePopUp selectItemAtIndex: 0];
+ }
+ else
+ {
+ [fSrcAngleLabel setHidden:YES];
+ [fSrcAnglePopUp setHidden:YES];
+ }
+
/* Start Get and set the initial pic size for display */
hb_job_t * job = title->job;
fTitle = title;
- /* Reset the new title in fPictureController */
- [fPictureController SetTitle:title];
-
- /*Set Source Size Field Here */
- [fPicSettingsSrc setStringValue: [NSString stringWithFormat: @"%d x %d", fTitle->width, fTitle->height]];
-
- /* Set Auto Crop to on upon selecting a new title */
+ /* Set Auto Crop to on upon selecting a new title */
[fPictureController setAutoCrop:YES];
/* We get the originial output picture width and height and put them
AutoCropLeft = job->crop[2];
AutoCropRight = job->crop[3];
- /* Run Through encoderPopUpChanged to see if there
- needs to be any pic value modifications based on encoder settings */
- //[self encoderPopUpChanged: NULL];
- /* END Get and set the initial pic size for display */
-
- /* 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];
+ /* Reset the new title in fPictureController && fPreviewController*/
+ [fPictureController SetTitle:title];
- [self subtitleSelectionChanged:nil];
+
+ /* Update Subtitle Table */
+ [fSubtitlesDelegate resetWithTitle:title];
+ [fSubtitlesTable reloadData];
+
/* Update chapter table */
[fChapterTitlesDelegate resetWithTitle:title];
[self calculatePictureSizing:nil];
/* lets call tableViewSelected to make sure that any preset we have selected is enforced after a title change */
- [self selectPreset:nil];
+ [self selectPreset:nil];
}
- (IBAction) chapterPopUpChanged: (id) sender
duration % 60]];
[self calculateBitrate: sender];
+
+ if ( [fSrcChapterStartPopUp indexOfSelectedItem] == [fSrcChapterEndPopUp indexOfSelectedItem] )
+ {
+ /* Disable chapter markers for any source with less than two chapters as it makes no sense. */
+ [fCreateChapterMarkers setEnabled: NO];
+ [fCreateChapterMarkers setState: NSOffState];
+ }
+ else
+ {
+ [fCreateChapterMarkers setEnabled: YES];
+ }
}
- (IBAction) formatPopUpChanged: (id) sender
[fDstMp4iPodFileCheck setHidden: YES];
/* Update the Video Codec PopUp */
+ /* lets get the tag of the currently selected item first so we might reset it later */
+ int selectedVidEncoderTag;
+ selectedVidEncoderTag = [[fVidEncoderPopUp selectedItem] tag];
+
/* Note: we now store the video encoder int values from common.c in the tags of each popup for easy retrieval later */
[fVidEncoderPopUp removeAllItems];
NSMenuItem *menuItem;
menuItem = [[fVidEncoderPopUp menu] addItemWithTitle:@"MPEG-4 (FFmpeg)" action: NULL keyEquivalent: @""];
[menuItem setTag: HB_VCODEC_FFMPEG];
- menuItem = [[fVidEncoderPopUp menu] addItemWithTitle:@"MPEG-4 (XviD)" action: NULL keyEquivalent: @""];
- [menuItem setTag: HB_VCODEC_XVID];
switch( format )
{
case 0:
[fCreateChapterMarkers setEnabled: YES];
break;
- case 2:
- ext = "avi";
- /* Add additional video encoders here */
- menuItem = [[fVidEncoderPopUp menu] addItemWithTitle:@"H.264 (x264)" action: NULL keyEquivalent: @""];
- [menuItem setTag: HB_VCODEC_X264];
- /* We disable the create chapters checkbox here and make sure it is unchecked*/
- [fCreateChapterMarkers setEnabled: NO];
- [fCreateChapterMarkers setState: NSOffState];
- break;
-
- case 3:
- ext = "ogm";
- /* Add additional video encoders here */
- menuItem = [[fVidEncoderPopUp menu] addItemWithTitle:@"VP3 (Theora)" action: NULL keyEquivalent: @""];
- [menuItem setTag: HB_VCODEC_THEORA];
- /* We disable the create chapters checkbox here and make sure it is unchecked*/
- [fCreateChapterMarkers setEnabled: NO];
- [fCreateChapterMarkers setState: NSOffState];
- break;
+
+ }
+ /* 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)
+ {
+ [fVidEncoderPopUp selectItemWithTag: selectedVidEncoderTag];
+ }
+ else
+ {
+ [fVidEncoderPopUp selectItemAtIndex: 0];
}
- [fVidEncoderPopUp selectItemAtIndex: 0];
[self audioAddAudioTrackCodecs: fAudTrack1CodecPopUp];
[self audioAddAudioTrackCodecs: fAudTrack2CodecPopUp];
to use the index itself but this is easier */
if (videoEncoder == HB_VCODEC_FFMPEG)
{
- if (job->pixel_ratio == 2)
+ if (job->anamorphic.mode == 2)
{
- job->pixel_ratio = 0;
+ job->anamorphic.mode = 0;
}
[fPictureController setAllowLooseAnamorphic:NO];
/* We set the iPod atom checkbox to disabled and uncheck it as its only for x264 in the mp4
[fPictureController setAllowLooseAnamorphic:YES];
[fDstMp4iPodFileCheck setEnabled: YES];
}
-
+ [self setupQualitySlider];
[self calculatePictureSizing: sender];
[self twoPassCheckboxChanged: sender];
}
[fVidTargetSizeField setEnabled: target];
[fVidBitrateField setEnabled: bitrate];
[fVidQualitySlider setEnabled: quality];
+ [fVidQualityRFField setEnabled: quality];
+ [fVidQualityRFLabel setEnabled: quality];
[fVidTwoPassCheck setEnabled: !quality &&
[fVidQualityMatrix isEnabled]];
if( quality )
[self customSettingUsed: sender];
}
+/* Use this method to setup the quality slider for cq/rf values depending on
+ * the video encoder selected.
+ */
+- (void) setupQualitySlider
+{
+ /* Get the current slider maxValue to check for a change in slider scale later
+ * so that we can choose a new similar value on the new slider scale */
+ float previousMaxValue = [fVidQualitySlider maxValue];
+ float previousPercentOfSliderScale = [fVidQualitySlider floatValue] / ([fVidQualitySlider maxValue] - [fVidQualitySlider minValue] + 1);
+ NSString * qpRFLabelString = @"QP:";
+ /* x264 0-51 */
+ if ([[fVidEncoderPopUp selectedItem] tag] == HB_VCODEC_X264)
+ {
+ [fVidQualitySlider setMinValue:0.0];
+ [fVidQualitySlider setMaxValue:51.0];
+ /* As x264 allows for qp/rf values that are fractional, we get the value from the preferences */
+ int fractionalGranularity = 1 / [[NSUserDefaults standardUserDefaults] floatForKey:@"x264CqSliderFractional"];
+ [fVidQualitySlider setNumberOfTickMarks:(([fVidQualitySlider maxValue] - [fVidQualitySlider minValue]) * fractionalGranularity) + 1];
+ if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultCrf"] > 0)
+ {
+ qpRFLabelString = @"RF:";
+ }
+ }
+ /* ffmpeg 1-31 */
+ if ([[fVidEncoderPopUp selectedItem] tag] == HB_VCODEC_FFMPEG )
+ {
+ [fVidQualitySlider setMinValue:1.0];
+ [fVidQualitySlider setMaxValue:31.0];
+ [fVidQualitySlider setNumberOfTickMarks:31];
+ }
+ /* Theora 0-63 */
+ if ([[fVidEncoderPopUp selectedItem] tag] == HB_VCODEC_THEORA)
+ {
+ [fVidQualitySlider setMinValue:0.0];
+ [fVidQualitySlider setMaxValue:63.0];
+ [fVidQualitySlider setNumberOfTickMarks:64];
+ }
+ [fVidQualityRFLabel setStringValue:qpRFLabelString];
+
+ /* check to see if we have changed slider scales */
+ if (previousMaxValue != [fVidQualitySlider maxValue])
+ {
+ /* if so, convert the old setting to the new scale as close as possible based on percentages */
+ float rf = ([fVidQualitySlider maxValue] - [fVidQualitySlider minValue] + 1) * previousPercentOfSliderScale;
+ [fVidQualitySlider setFloatValue:rf];
+ }
+
+ [self qualitySliderChanged:nil];
+}
+
- (IBAction) qualitySliderChanged: (id) sender
{
+ /* Our constant quality slider is in a range based
+ * on each encoders qp/rf values. The range depends
+ * on the encoder. Also, the range is inverse of quality
+ * for all of the encoders *except* for theora
+ * (ie. as the "quality" goes up, the cq or rf value
+ * actually goes down). Since the IB sliders always set
+ * their max value at the right end of the slider, we
+ * will calculate the inverse, so as the slider floatValue
+ * goes up, we will show the inverse in the rf field
+ * so, the floatValue at the right for x264 would be 51
+ * and our rf field needs to show 0 and vice versa.
+ */
+
+ float sliderRfInverse = ([fVidQualitySlider maxValue] - [fVidQualitySlider floatValue]) + [fVidQualitySlider minValue];
+ /* If the encoder is theora, use the float, otherwise use the inverse float*/
+ float sliderRfToPercent;
+ if ([[fVidEncoderPopUp selectedItem] tag] == HB_VCODEC_THEORA)
+ {
+ [fVidQualityRFField setStringValue: [NSString stringWithFormat: @"%.2f", [fVidQualitySlider floatValue]]];
+ sliderRfToPercent = [fVidQualityRFField floatValue] / ([fVidQualitySlider maxValue] - [fVidQualitySlider minValue]);
+ }
+ else
+ {
+ [fVidQualityRFField setStringValue: [NSString stringWithFormat: @"%.2f", sliderRfInverse]];
+ sliderRfToPercent = ( ([fVidQualitySlider maxValue] - [fVidQualitySlider minValue]) - ([fVidQualityRFField floatValue] - [fVidQualitySlider minValue])) / ([fVidQualitySlider maxValue] - [fVidQualitySlider minValue]);
+ }
[fVidConstantCell setTitle: [NSString stringWithFormat:
- NSLocalizedString( @"Constant quality: %.0f %%", @"" ), 100.0 *
- [fVidQualitySlider floatValue]]];
- [self customSettingUsed: sender];
+ NSLocalizedString( @"Constant quality: %.2f %%", @"" ), 100 * sliderRfToPercent]];
+
+ [self customSettingUsed: sender];
}
- (void) controlTextDidChange: (NSNotification *) notification
- (IBAction) revertPictureSizeToMax: (id) sender
{
hb_job_t * job = fTitle->job;
- /* Here we apply the max source storage width and height */
- job->width = fTitle->width-fTitle->job->crop[2]-fTitle->job->crop[3];
- job->height = fTitle->height-fTitle->job->crop[0]-fTitle->job->crop[1];
+ /* Here we apply the title source and height */
+ job->width = fTitle->width;
+ job->height = fTitle->height;
[self calculatePictureSizing: sender];
/* We call method to change UI to reflect whether a preset is used or not*/
* Registers changes made in the Picture Settings Window.
*/
-- (void)pictureSettingsDidChange {
+- (void)pictureSettingsDidChange
+{
[self calculatePictureSizing:nil];
}
/* Get and Display Current Pic Settings in main window */
- (IBAction) calculatePictureSizing: (id) sender
{
- [fPicSettingsOutp setStringValue: [NSString stringWithFormat:@"%d x %d", fTitle->job->width, fTitle->job->height]];
-
- if (fTitle->job->pixel_ratio == 1)
+ if (fTitle->job->anamorphic.mode > 0)
{
- int titlewidth = fTitle->width-fTitle->job->crop[2]-fTitle->job->crop[3];
- int arpwidth = fTitle->job->pixel_aspect_width;
- int arpheight = fTitle->job->pixel_aspect_height;
- int displayparwidth = titlewidth * arpwidth / arpheight;
- int displayparheight = fTitle->height-fTitle->job->crop[0]-fTitle->job->crop[1];
- [fPicSettingsOutp setStringValue: [NSString stringWithFormat:@"%d x %d", titlewidth, displayparheight]];
- [fPicSettingsAnamorphic setStringValue: [NSString stringWithFormat:@"%d x %d Strict", displayparwidth, displayparheight]];
- fTitle->job->keep_ratio = 0;
- }
- else if (fTitle->job->pixel_ratio == 2)
- {
- hb_job_t * job = fTitle->job;
- int output_width, output_height, output_par_width, output_par_height;
- hb_set_anamorphic_size(job, &output_width, &output_height, &output_par_width, &output_par_height);
- int display_width;
- display_width = output_width * output_par_width / output_par_height;
-
- [fPicSettingsOutp setStringValue: [NSString stringWithFormat:@"%d x %d", output_width, output_height]];
- [fPicSettingsAnamorphic setStringValue: [NSString stringWithFormat:@"%d x %d Loose", display_width, output_height]];
-
fTitle->job->keep_ratio = 0;
- }
- else
- {
- [fPicSettingsAnamorphic setStringValue:@"Off"];
}
-
- /* Set ON/Off values for the deinterlace/keep aspect ratio according to boolean */
- if (fTitle->job->keep_ratio > 0)
+
+ [fPictureSizeField setStringValue: [NSString stringWithFormat:@"Picture Size: %@", [fPictureController getPictureSizeInfoString]]];
+
+ NSString *picCropping;
+ /* Set the display field for crop as per boolean */
+ if (![fPictureController autoCrop])
{
- [fPicSettingARkeep setStringValue: @"On"];
+ picCropping = @"Custom";
}
else
{
- [fPicSettingARkeep setStringValue: @"Off"];
- }
+ picCropping = @"Auto";
+ }
+ picCropping = [picCropping stringByAppendingString:[NSString stringWithFormat:@" %d/%d/%d/%d",fTitle->job->crop[0],fTitle->job->crop[1],fTitle->job->crop[2],fTitle->job->crop[3]]];
+
+ [fPictureCroppingField setStringValue: [NSString stringWithFormat:@"Picture Cropping: %@",picCropping]];
+ NSString *videoFilters;
+ videoFilters = @"";
/* Detelecine */
- if ([fPictureController detelecine])
+ if ([fPictureController detelecine] == 1)
{
- [fPicSettingDetelecine setStringValue: @"Yes"];
+ videoFilters = [videoFilters stringByAppendingString:@" - Detelecine (Default)"];
}
- else
+ else if ([fPictureController detelecine] == 2)
{
- [fPicSettingDetelecine setStringValue: @"Off"];
+ videoFilters = [videoFilters stringByAppendingString:[NSString stringWithFormat:@" - Detelecine (%@)",[fPictureController detelecineCustomString]]];
}
- /* Decomb */
- if ([fPictureController decomb])
- {
- [fPicSettingDecomb setStringValue: @"1:2:6:9:80:16:16"];
- }
- else
- {
- [fPicSettingDecomb setStringValue: @"Off"];
- }
-
- /* VFR (Variable Frame Rate) */
+ if ([fPictureController useDecomb] == 1)
+ {
+ /* Decomb */
+ if ([fPictureController decomb] == 1)
+ {
+ videoFilters = [videoFilters stringByAppendingString:@" - Decomb (Default)"];
+ }
+ else if ([fPictureController decomb] == 2)
+ {
+ videoFilters = [videoFilters stringByAppendingString:[NSString stringWithFormat:@" - Decomb (%@)",[fPictureController decombCustomString]]];
+ }
+ }
+ else
+ {
+ /* Deinterlace */
+ if ([fPictureController deinterlace] > 0)
+ {
+ fTitle->job->deinterlace = 1;
+ }
+ else
+ {
+ fTitle->job->deinterlace = 0;
+ }
+
+ if ([fPictureController deinterlace] == 1)
+ {
+ videoFilters = [videoFilters stringByAppendingString:@" - Deinterlace (Fast)"];
+ }
+ else if ([fPictureController deinterlace] == 2)
+ {
+ videoFilters = [videoFilters stringByAppendingString:@" - Deinterlace (Slow)"];
+ }
+ else if ([fPictureController deinterlace] == 3)
+ {
+ videoFilters = [videoFilters stringByAppendingString:@" - Deinterlace (Slower)"];
+ }
+ else if ([fPictureController deinterlace] == 4)
+ {
+ videoFilters = [videoFilters stringByAppendingString:[NSString stringWithFormat:@" - Deinterlace (%@)",[fPictureController deinterlaceCustomString]]];
+ }
+ }
- /* Deinterlace */
- if ([fPictureController deinterlace] == 0)
- {
- [fPicSettingDeinterlace setStringValue: @"Off"];
- }
- else if ([fPictureController deinterlace] == 1)
- {
- [fPicSettingDeinterlace setStringValue: @"Fast"];
- }
- else if ([fPictureController deinterlace] == 2)
- {
- [fPicSettingDeinterlace setStringValue: @"Slow"];
- }
- else if ([fPictureController deinterlace] == 3)
- {
- [fPicSettingDeinterlace setStringValue: @"Slower"];
- }
-
/* Denoise */
- if ([fPictureController denoise] == 0)
- {
- [fPicSettingDenoise setStringValue: @"Off"];
- }
- else if ([fPictureController denoise] == 1)
+ if ([fPictureController denoise] == 1)
{
- [fPicSettingDenoise setStringValue: @"Weak"];
- }
+ videoFilters = [videoFilters stringByAppendingString:@" - Denoise (Weak)"];
+ }
else if ([fPictureController denoise] == 2)
{
- [fPicSettingDenoise setStringValue: @"Medium"];
- }
+ videoFilters = [videoFilters stringByAppendingString:@" - Denoise (Medium)"];
+ }
else if ([fPictureController denoise] == 3)
{
- [fPicSettingDenoise setStringValue: @"Strong"];
+ videoFilters = [videoFilters stringByAppendingString:@" - Denoise (Strong)"];
+ }
+ else if ([fPictureController denoise] == 4)
+ {
+ videoFilters = [videoFilters stringByAppendingString:[NSString stringWithFormat:@" - Denoise (%@)",[fPictureController denoiseCustomString]]];
}
/* Deblock */
- if ([fPictureController deblock] == 0)
+ if ([fPictureController deblock] > 0)
{
- [fPicSettingDeblock setStringValue: @"Off"];
+ videoFilters = [videoFilters stringByAppendingString:[NSString stringWithFormat:@" - Deblock (%d)",[fPictureController deblock]]];
}
- else
+
+ /* Grayscale */
+ if ([fPictureController grayscale])
{
- [fPicSettingDeblock setStringValue: [NSString stringWithFormat:@"%d",[fPictureController deblock]]];
+ videoFilters = [videoFilters stringByAppendingString:@" - Grayscale"];
}
-
- if (fTitle->job->pixel_ratio > 0)
- {
- [fPicSettingPAR setStringValue: @""];
- }
- else
- {
- [fPicSettingPAR setStringValue: @"Off"];
- }
-
- /* Set the display field for crop as per boolean */
- if (![fPictureController autoCrop])
- {
- [fPicSettingAutoCrop setStringValue: @"Custom"];
- }
- else
- {
- [fPicSettingAutoCrop setStringValue: @"Auto"];
- }
-
-//[self showPicturePanel:self];
-hb_list_t * list = hb_get_titles( fHandle );
- hb_title_t * title = (hb_title_t *) hb_list_item( list,
- [fSrcTitlePopUp indexOfSelectedItem] );
- [fPictureController SetTitle:title];
+ [fVideoFiltersField setStringValue: [NSString stringWithFormat:@"Video Filters: %@", videoFilters]];
+
+ //[fPictureController reloadStillPreview];
}
[fAudTrack1DrcSlider setFloatValue: 1.00];
[self audioDRCSliderChanged: fAudTrack1DrcSlider];
}
- else if ([[fAudTrack1MixPopUp selectedItem] tag] == HB_ACODEC_AC3)
+ else if ([[fAudTrack1MixPopUp selectedItem] tag] == HB_ACODEC_AC3 || [[fAudTrack1MixPopUp selectedItem] tag] == HB_ACODEC_DCA)
{
[fAudTrack1RatePopUp setEnabled: NO];
[fAudTrack1BitratePopUp setEnabled: NO];
[fAudTrack2DrcSlider setFloatValue: 1.00];
[self audioDRCSliderChanged: fAudTrack2DrcSlider];
}
- else if ([[fAudTrack2MixPopUp selectedItem] tag] == HB_ACODEC_AC3)
+ else if ([[fAudTrack2MixPopUp selectedItem] tag] == HB_ACODEC_AC3 || [[fAudTrack2MixPopUp selectedItem] tag] == HB_ACODEC_DCA)
{
[fAudTrack2RatePopUp setEnabled: NO];
[fAudTrack2BitratePopUp setEnabled: NO];
[fAudTrack3DrcSlider setFloatValue: 1.00];
[self audioDRCSliderChanged: fAudTrack3DrcSlider];
}
- else if ([[fAudTrack3MixPopUp selectedItem] tag] == HB_ACODEC_AC3)
+ else if ([[fAudTrack3MixPopUp selectedItem] tag] == HB_ACODEC_AC3 || [[fAudTrack3MixPopUp selectedItem] tag] == HB_ACODEC_DCA)
{
[fAudTrack3RatePopUp setEnabled: NO];
[fAudTrack3BitratePopUp setEnabled: NO];
[fAudTrack4DrcSlider setFloatValue: 1.00];
[self audioDRCSliderChanged: fAudTrack4DrcSlider];
}
- else if ([[fAudTrack4MixPopUp selectedItem] tag] == HB_ACODEC_AC3)
+ else if ([[fAudTrack4MixPopUp selectedItem] tag] == HB_ACODEC_AC3 || [[fAudTrack4MixPopUp selectedItem] tag] == HB_ACODEC_DCA)
{
[fAudTrack4RatePopUp setEnabled: NO];
[fAudTrack4BitratePopUp setEnabled: NO];
{
case 0:
/* MP4 */
- // AAC
+ // FAAC
menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AAC (faac)" action: NULL keyEquivalent: @""];
[menuItem setTag: HB_ACODEC_FAAC];
-
+
+ // CA_AAC
+ menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AAC (CoreAudio)" action: NULL keyEquivalent: @""];
+ [menuItem setTag: HB_ACODEC_CA_AAC];
+
// AC3 Passthru
menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AC3 Passthru" action: NULL keyEquivalent: @""];
[menuItem setTag: HB_ACODEC_AC3];
case 1:
/* MKV */
- // AAC
+ // FAAC
menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AAC (faac)" action: NULL keyEquivalent: @""];
[menuItem setTag: HB_ACODEC_FAAC];
+ // CA_AAC
+ menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AAC (CoreAudio)" action: NULL keyEquivalent: @""];
+ [menuItem setTag: HB_ACODEC_CA_AAC];
// AC3 Passthru
menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AC3 Passthru" action: NULL keyEquivalent: @""];
[menuItem setTag: HB_ACODEC_AC3];
+ // DTS Passthru
+ menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"DTS Passthru" action: NULL keyEquivalent: @""];
+ [menuItem setTag: HB_ACODEC_DCA];
// MP3
menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"MP3 (lame)" action: NULL keyEquivalent: @""];
[menuItem setTag: HB_ACODEC_LAME];
action: NULL keyEquivalent: @""];
[menuItem setTag: HB_ACODEC_AC3];
}
+ else if (audio->in.codec == HB_ACODEC_DCA && acodec == HB_ACODEC_DCA)
+ {
+ NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
+ [NSString stringWithCString: "DTS Passthru"]
+ action: NULL keyEquivalent: @""];
+ [menuItem setTag: HB_ACODEC_DCA];
+ }
else
{
maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[5].amixdown);
}
+ /* do we want to add a DTS Passthru option ? HB_ACODEC_DCA*/
+ if (audio->in.codec == HB_ACODEC_DCA && acodec == HB_ACODEC_DCA)
+ {
+ NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
+ [NSString stringWithCString: hb_audio_mixdowns[5].human_readable_name]
+ action: NULL keyEquivalent: @""];
+ [menuItem setTag: HB_ACODEC_DCA];
+ if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[5].amixdown;
+ maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[5].amixdown);
+ }
+
/* auto-select the best mixdown based on our saved mixdown preference */
/* for now, this is hard-coded to a "best" mixdown of HB_AMIXDOWN_DOLBYPLII */
[audiocodecPopUp selectItemWithTag: HB_ACODEC_FAAC];
}
}
+
+ /* In the case of a source track that is not DTS and the user tries to use DTS Passthru (which does not work)
+ * we force the Audio Codec choice back to a workable codec. We use MP3 for avi and aac for all
+ * other containers.
+ */
+ if (audio->in.codec != HB_ACODEC_DCA && [[audiocodecPopUp selectedItem] tag] == HB_ACODEC_DCA)
+ {
+ /* If we are using the avi container, we select MP3 as there is no aac available*/
+ if ([[fDstFormatPopUp selectedItem] tag] == HB_MUX_AVI)
+ {
+ [audiocodecPopUp selectItemWithTag: HB_ACODEC_LAME];
+ }
+ else
+ {
+ [audiocodecPopUp selectItemWithTag: HB_ACODEC_FAAC];
+ }
+ }
+
/* Setup our samplerate and bitrate popups we will need based on mixdown */
[self audioTrackMixdownChanged: mixdownPopUp];
}
maxbitrate = 160;
break;
}
-
+
+ case HB_ACODEC_CA_AAC:
+ /* check if we have a 6ch discrete conversion in either audio track */
+ if ([[mixdownPopUp selectedItem] tag] == HB_AMIXDOWN_6CH)
+ {
+ minbitrate = 128;
+ maxbitrate = 768;
+ break;
+ }
+ else
+ {
+ minbitrate = 64;
+ maxbitrate = 320;
+ break;
+ }
+
case HB_ACODEC_LAME:
/* Lame is happy using our min bitrate of 32 kbps */
minbitrate = 32;
int inputbitrate = audio->in.bitrate / 1000;
int inputsamplerate = audio->in.samplerate;
- if ([[mixdownPopUp selectedItem] tag] != HB_ACODEC_AC3)
+ if ([[mixdownPopUp selectedItem] tag] != HB_ACODEC_AC3 && [[mixdownPopUp selectedItem] tag] != HB_ACODEC_DCA)
{
[bitratePopUp removeAllItems];
[sampleratePopUp selectItemWithTag: inputsamplerate];
- /* Since AC3 Pass Thru uses the input ac3 bitrate and sample rate, we get the input tracks
- * bitrate and dispay it in the bitrate popup even though libhb happily ignores any bitrate input from
+ /* Since AC3 Pass Thru and DTS Pass Thru uses the input bitrate and sample rate, we get the input tracks
+ * bitrate and display it in the bitrate popup even though libhb happily ignores any bitrate input from
* the gui. We do this for better user feedback in the audio tab as well as the queue for the most part
*/
- if ([[mixdownPopUp selectedItem] tag] == HB_ACODEC_AC3)
+ if ([[mixdownPopUp selectedItem] tag] == HB_ACODEC_AC3 || [[mixdownPopUp selectedItem] tag] == HB_ACODEC_DCA)
{
/* lets also set the bitrate popup to the input bitrate as thats what passthru will use */
drcSlider = fAudTrack4DrcSlider;
drcField = fAudTrack4DrcField;
}
+
+ /* If we are between 0.0 and 1.0 on the slider, snap it to 1.0 */
+ if ([drcSlider floatValue] > 0.0 && [drcSlider floatValue] < 1.0)
+ {
+ [drcSlider setFloatValue:1.0];
+ }
+
+
[drcField setStringValue: [NSString stringWithFormat: @"%.2f", [drcSlider floatValue]]];
/* For now, do not call this until we have an intelligent way to determine audio track selections
* compared to presets
//[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
- (IBAction) showPicturePanel: (id) sender
{
- hb_list_t * list = hb_get_titles( fHandle );
- hb_title_t * title = (hb_title_t *) hb_list_item( list,
- [fSrcTitlePopUp indexOfSelectedItem] );
- //[fPictureController SetTitle:title];
- [fPictureController showPreviewPanel:sender forTitle:title];
+ [fPictureController showPictureWindow:sender];
+}
+
+- (void) picturePanelFullScreen
+{
+ [fPictureController setToFullScreenMode];
+}
+
+- (void) picturePanelWindowed
+{
+ [fPictureController setToWindowedMode];
+}
+
+- (IBAction) showPreviewWindow: (id) sender
+{
+ [fPictureController showPreviewWindow:sender];
}
#pragma mark -
}
/* We use this to deterimine children of an item */
-- (id)outlineView:(NSOutlineView *)fPresetsOutlineView child:(int)index ofItem:(id)item
+- (id)outlineView:(NSOutlineView *)fPresetsOutlineView child:(NSInteger)index ofItem:(id)item
{
/* we need to return the count of the array in ChildrenArray for this folder */
children = [item objectForKey:@"ChildrenArray"];
}
}
- if ((children == nil) || ([children count] <= index))
+ if ((children == nil) || ( [children count] <= (NSUInteger) index))
{
return nil;
}
}
}
+- (id)outlineView:(NSOutlineView *)outlineView itemForPersistentObject:(id)object
+{
+ return [NSKeyedUnarchiver unarchiveObjectWithData:object];
+}
+- (id)outlineView:(NSOutlineView *)outlineView persistentObjectForItem:(id)item
+{
+ return [NSKeyedArchiver archivedDataWithRootObject:item];
+}
+
#pragma mark - Added Functionality (optional)
/* Use to customize the font and display characteristics of the title cell */
- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
return YES;
}
-- (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id <NSDraggingInfo>)info proposedItem:(id)item proposedChildIndex:(int)index
+- (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id <NSDraggingInfo>)info proposedItem:(id)item proposedChildIndex:(NSInteger)index
{
// Don't allow dropping ONTO an item since they can't really contain any children.
-- (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id <NSDraggingInfo>)info item:(id)item childIndex:(int)index
+- (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id <NSDraggingInfo>)info item:(id)item childIndex:(NSInteger)index
{
/* first, lets see if we are dropping into a folder */
if ([[fPresetsOutlineView itemAtRow:index] objectForKey:@"Folder"] && [[[fPresetsOutlineView itemAtRow:index] objectForKey:@"Folder"] intValue] == 1) // if its a folder
return YES;
}
-- (void)moveObjectsInPresetsArray:(NSMutableArray *)array fromIndexes:(NSIndexSet *)indexSet toIndex:(unsigned)insertIndex
+- (void)moveObjectsInPresetsArray:(NSMutableArray *)array fromIndexes:(NSIndexSet *)indexSet toIndex:(NSUInteger)insertIndex
{
- unsigned index = [indexSet lastIndex];
- unsigned aboveInsertIndexCount = 0;
+ NSUInteger index = [indexSet lastIndex];
+ NSUInteger aboveInsertIndexCount = 0;
- while (index != NSNotFound)
+ NSUInteger removeIndex;
+
+ if (index >= insertIndex)
{
- unsigned removeIndex;
-
- if (index >= insertIndex)
- {
- removeIndex = index + aboveInsertIndexCount;
- aboveInsertIndexCount++;
- }
- else
- {
- removeIndex = index;
- insertIndex--;
- }
-
- id object = [[array objectAtIndex:removeIndex] retain];
- [array removeObjectAtIndex:removeIndex];
- [array insertObject:object atIndex:insertIndex];
- [object release];
-
- index = [indexSet indexLessThanIndex:index];
+ removeIndex = index + aboveInsertIndexCount;
+ aboveInsertIndexCount++;
}
+ else
+ {
+ removeIndex = index;
+ insertIndex--;
+ }
+
+ id object = [[array objectAtIndex:removeIndex] retain];
+ [array removeObjectAtIndex:removeIndex];
+ [array insertObject:object atIndex:insertIndex];
+ [object release];
+
+ index = [indexSet indexLessThanIndex:index];
}
/* Chapter Markers*/
[fCreateChapterMarkers setState:[[chosenPreset objectForKey:@"ChapterMarkers"] intValue]];
+ /* check to see if we have only one chapter */
+ [self chapterPopUpChanged:nil];
+
/* Allow Mpeg4 64 bit formatting +4GB file sizes */
[fDstMp4LargeFileCheck setState:[[chosenPreset objectForKey:@"Mp4LargeFile"] intValue]];
/* Mux mp4 with http optimization */
[fDstMp4HttpOptFileCheck setState:[[chosenPreset objectForKey:@"Mp4HttpOptimize"] intValue]];
/* Video encoder */
+ [fVidEncoderPopUp selectItemWithTitle:[chosenPreset objectForKey:@"VideoEncoder"]];
/* We set the advanced opt string here if applicable*/
[fAdvancedOptions setOptions:[chosenPreset objectForKey:@"x264Option"]];
- /* We use a conditional to account for the new x264 encoder dropdown as well as presets made using legacy x264 settings*/
- if ([[chosenPreset objectForKey:@"VideoEncoder"] isEqualToString:@"x264 (h.264 Main)"] ||
- [[chosenPreset objectForKey:@"VideoEncoder"] isEqualToString:@"x264 (h.264 iPod)"] ||
- [[chosenPreset objectForKey:@"VideoEncoder"] isEqualToString:@"x264"])
- {
- [fVidEncoderPopUp selectItemWithTitle:@"H.264 (x264)"];
- /* special case for legacy preset to check the new fDstMp4HttpOptFileCheck checkbox to set the ipod atom */
- if ([[chosenPreset objectForKey:@"VideoEncoder"] isEqualToString:@"x264 (h.264 iPod)"])
- {
- [fDstMp4iPodFileCheck setState:NSOnState];
- /* We also need to add "level=30:" to the advanced opts string to set the correct level for the iPod when
- encountering a legacy preset as it used to be handled separately from the opt string*/
- [fAdvancedOptions setOptions:[@"level=30:" stringByAppendingString:[fAdvancedOptions optionsString]]];
- }
- else
- {
- [fDstMp4iPodFileCheck setState:NSOffState];
- }
- }
- else if ([[chosenPreset objectForKey:@"VideoEncoder"] isEqualToString:@"FFmpeg"])
- {
- [fVidEncoderPopUp selectItemWithTitle:@"MPEG-4 (FFmpeg)"];
- }
- else if ([[chosenPreset objectForKey:@"VideoEncoder"] isEqualToString:@"XviD"])
- {
- [fVidEncoderPopUp selectItemWithTitle:@"MPEG-4 (XviD)"];
- }
- else
- {
- [fVidEncoderPopUp selectItemWithTitle:[chosenPreset objectForKey:@"VideoEncoder"]];
- }
/* Lets run through the following functions to get variables set there */
[self videoEncoderPopUpChanged:nil];
[fVidTargetSizeField setStringValue:[chosenPreset objectForKey:@"VideoTargetSize"]];
[fVidBitrateField setStringValue:[chosenPreset objectForKey:@"VideoAvgBitrate"]];
- [fVidQualitySlider setFloatValue:[[chosenPreset objectForKey:@"VideoQualitySlider"] floatValue]];
+
+ /* Since we are now using RF Values for the slider, we detect if the preset uses an old quality float.
+ * So, check to see if the quality value is less than 1.0 which should indicate the old ".062" type
+ * quality preset. Caveat: in the case of x264, where the RF scale starts at 0, it would misinterpret
+ * a preset that uses 0.0 - 0.99 for RF as an old style preset. Not sure how to get around that one yet,
+ * though it should be a corner case since it would pretty much be a preset for lossless encoding. */
+ if ([[chosenPreset objectForKey:@"VideoQualitySlider"] floatValue] < 1.0)
+ {
+ /* For the quality slider we need to convert the old percent's to the new rf scales */
+ float rf = (([fVidQualitySlider maxValue] - [fVidQualitySlider minValue]) * [[chosenPreset objectForKey:@"VideoQualitySlider"] floatValue]);
+ [fVidQualitySlider setFloatValue:rf];
+
+ }
+ else
+ {
+ /* Since theora's qp value goes up from left to right, we can just set the slider float value */
+ if ([[fVidEncoderPopUp selectedItem] tag] == HB_VCODEC_THEORA)
+ {
+ [fVidQualitySlider setFloatValue:[[chosenPreset objectForKey:@"VideoQualitySlider"] floatValue]];
+ }
+ else
+ {
+ /* since ffmpeg and x264 use an "inverted" slider (lower qp/rf values indicate a higher quality) we invert the value on the slider */
+ [fVidQualitySlider setFloatValue:([fVidQualitySlider maxValue] + [fVidQualitySlider minValue]) - [[chosenPreset objectForKey:@"VideoQualitySlider"] floatValue]];
+ }
+ }
[self videoMatrixChanged:nil];
[fVidRatePopUp selectItemWithTitle:[chosenPreset objectForKey:@"VideoFramerate"]];
}
- /* GrayScale */
- [fVidGrayscaleCheck setState:[[chosenPreset objectForKey:@"VideoGrayScale"] intValue]];
/* 2 Pass Encoding */
[fVidTwoPassCheck setState:[[chosenPreset objectForKey:@"VideoTwoPass"] intValue]];
[self twoPassCheckboxChanged:nil];
- /* Turbo 1st pass for 2 Pass Encoding */
- [fVidTurboPassCheck setState:[[chosenPreset objectForKey:@"VideoTurboTwoPass"] intValue]];
-
- /*Audio*/
- if ([chosenPreset objectForKey:@"FileCodecs"])
- {
- /* We need to handle the audio codec popup by determining what was chosen from the deprecated Codecs PopUp for past presets*/
- if ([[chosenPreset objectForKey:@"FileCodecs"] isEqualToString: @"AVC/H.264 Video / AAC + AC3 Audio"])
- {
- /* We need to address setting languages etc. here in the new multi track audio panel */
- /* Track One set here */
- /*for track one though a track should be selected but lets check here anyway and use track one if its not.*/
- if ([fAudLang1PopUp indexOfSelectedItem] == 0)
- {
- [fAudLang1PopUp selectItemAtIndex: 1];
- [self audioTrackPopUpChanged: fAudLang1PopUp];
- }
- [fAudTrack1CodecPopUp selectItemWithTitle: @"AAC (faac)"];
- [self audioTrackPopUpChanged: fAudTrack1CodecPopUp];
- /* Track Two, set source same as track one */
- [fAudLang2PopUp selectItemAtIndex: [fAudLang1PopUp indexOfSelectedItem]];
- [self audioTrackPopUpChanged: fAudLang2PopUp];
- [fAudTrack2CodecPopUp selectItemWithTitle: @"AC3 Passthru"];
- [self audioTrackPopUpChanged: fAudTrack2CodecPopUp];
- }
- else if ([[chosenPreset objectForKey:@"FileCodecs"] isEqualToString:@"MPEG-4 Video / AAC Audio"] ||
- [[chosenPreset objectForKey:@"FileCodecs"] isEqualToString:@"AVC/H.264 Video / AAC Audio"])
- {
- if ([fAudLang1PopUp indexOfSelectedItem] > 0)
- {
- [fAudTrack1CodecPopUp selectItemWithTitle: @"AAC (faac)"];
- [self audioTrackPopUpChanged: fAudTrack1CodecPopUp];
- }
- if ([fAudLang2PopUp indexOfSelectedItem] > 0)
- {
- [fAudTrack2CodecPopUp selectItemWithTitle: @"AAC (faac)"];
- [self audioTrackPopUpChanged: fAudTrack2CodecPopUp];
- }
- if ([fAudLang3PopUp indexOfSelectedItem] > 0)
- {
- [fAudTrack3CodecPopUp selectItemWithTitle: @"AAC (faac)"];
- [self audioTrackPopUpChanged: fAudTrack3CodecPopUp];
- }
- if ([fAudLang4PopUp indexOfSelectedItem] > 0)
- {
- [fAudTrack4CodecPopUp selectItemWithTitle: @"AAC (faac)"];
- [self audioTrackPopUpChanged: fAudTrack4CodecPopUp];
- }
- }
- else if ([[chosenPreset objectForKey:@"FileCodecs"] isEqualToString:@"MPEG-4 Video / AC-3 Audio"] ||
- [[chosenPreset objectForKey:@"FileCodecs"] isEqualToString:@"AVC/H.264 Video / AC-3 Audio"])
- {
- if ([fAudLang1PopUp indexOfSelectedItem] > 0)
- {
- [fAudTrack1CodecPopUp selectItemWithTitle: @"AC3 Passthru"];
- [self audioTrackPopUpChanged: fAudTrack1CodecPopUp];
- }
- if ([fAudLang2PopUp indexOfSelectedItem] > 0)
- {
- [fAudTrack2CodecPopUp selectItemWithTitle: @"AC3 Passthru"];
- [self audioTrackPopUpChanged: fAudTrack2CodecPopUp];
- }
- if ([fAudLang3PopUp indexOfSelectedItem] > 0)
- {
- [fAudTrack3CodecPopUp selectItemWithTitle: @"AC3 Passthru"];
- [self audioTrackPopUpChanged: fAudTrack3CodecPopUp];
- }
- if ([fAudLang4PopUp indexOfSelectedItem] > 0)
- {
- [fAudTrack4CodecPopUp selectItemWithTitle: @"AC3 Passthru"];
- [self audioTrackPopUpChanged: fAudTrack4CodecPopUp];
- }
- }
- else if ([[chosenPreset objectForKey:@"FileCodecs"] isEqualToString:@"MPEG-4 Video / MP3 Audio"] ||
- [[chosenPreset objectForKey:@"FileCodecs"] isEqualToString:@"AVC/H.264 Video / MP3 Audio"])
- {
- if ([fAudLang1PopUp indexOfSelectedItem] > 0)
- {
- [fAudTrack1CodecPopUp selectItemWithTitle: @"MP3 (lame)"];
- [self audioTrackPopUpChanged: fAudTrack1CodecPopUp];
- }
- if ([fAudLang2PopUp indexOfSelectedItem] > 0)
- {
- [fAudTrack2CodecPopUp selectItemWithTitle: @"MP3 (lame)"];
- [self audioTrackPopUpChanged: fAudTrack2CodecPopUp];
- }
- if ([fAudLang3PopUp indexOfSelectedItem] > 0)
- {
- [fAudTrack3CodecPopUp selectItemWithTitle: @"MP3 (lame)"];
- [self audioTrackPopUpChanged: fAudTrack3CodecPopUp];
- }
- if ([fAudLang4PopUp indexOfSelectedItem] > 0)
- {
- [fAudTrack4CodecPopUp selectItemWithTitle: @"MP3 (lame)"];
- [self audioTrackPopUpChanged: fAudTrack4CodecPopUp];
- }
- }
- else if ([[chosenPreset objectForKey:@"FileCodecs"] isEqualToString:@"MPEG-4 Video / Vorbis Audio"])
+
+ /* Turbo 1st pass for 2 Pass Encoding */
+ [fVidTurboPassCheck setState:[[chosenPreset objectForKey:@"VideoTurboTwoPass"] intValue]];
+
+ /*Audio*/
+ /* First we check to see if we are using the current audio track layout based on AudioList array */
+ if ([chosenPreset objectForKey:@"AudioList"])
+ {
+ /* Populate the audio widgets based on the contents of the AudioList array */
+ int i = 0;
+ NSEnumerator *enumerator = [[chosenPreset objectForKey:@"AudioList"] objectEnumerator];
+ id tempObject;
+ while (tempObject = [enumerator nextObject])
{
- if ([fAudLang1PopUp indexOfSelectedItem] > 0)
+ i++;
+ if( i == 1 )
{
- [fAudTrack1CodecPopUp selectItemWithTitle: @"Vorbis (vorbis)"];
+ if ([fAudLang1PopUp indexOfSelectedItem] == 0)
+ {
+ [fAudLang1PopUp selectItemAtIndex: 1];
+ }
+ [self audioTrackPopUpChanged: fAudLang1PopUp];
+ [fAudTrack1CodecPopUp selectItemWithTitle:[tempObject objectForKey:@"AudioEncoder"]];
+ /* check our pref for core audio and use it in place of faac if applicable */
+ if ([[NSUserDefaults standardUserDefaults] boolForKey: @"UseCoreAudio"] == YES &&
+ [[tempObject objectForKey:@"AudioEncoder"] isEqualToString: @"AAC (faac)"])
+ {
+ [fAudTrack1CodecPopUp selectItemWithTitle:@"AAC (CoreAudio)"];
+ }
+
[self audioTrackPopUpChanged: fAudTrack1CodecPopUp];
+ [fAudTrack1MixPopUp selectItemWithTitle:[tempObject objectForKey:@"AudioMixdown"]];
+ /* check to see if the selections was available, if not, rerun audioTrackPopUpChanged using the codec to just set the default
+ * mixdown*/
+ if ([fAudTrack1MixPopUp selectedItem] == nil)
+ {
+ [self audioTrackPopUpChanged: fAudTrack1CodecPopUp];
+ }
+ [fAudTrack1RatePopUp selectItemWithTitle:[tempObject objectForKey:@"AudioSamplerate"]];
+ /* We set the presets bitrate if it is *not* an AC3 track since that uses the input bitrate */
+ if (![[tempObject objectForKey:@"AudioEncoder"] isEqualToString:@"AC3 Passthru"])
+ {
+ [fAudTrack1BitratePopUp selectItemWithTitle:[tempObject objectForKey:@"AudioBitrate"]];
+ }
+ [fAudTrack1DrcSlider setFloatValue:[[tempObject objectForKey:@"AudioTrackDRCSlider"] floatValue]];
+ [self audioDRCSliderChanged: fAudTrack1DrcSlider];
}
- if ([fAudLang2PopUp indexOfSelectedItem] > 0)
+
+ if( i == 2 )
{
- [fAudTrack2CodecPopUp selectItemWithTitle: @"Vorbis (vorbis)"];
+
+ if ([fAudLang2PopUp indexOfSelectedItem] == 0)
+ {
+ [fAudLang2PopUp selectItemAtIndex: 1];
+ }
+ [self audioTrackPopUpChanged: fAudLang2PopUp];
+ [fAudTrack2CodecPopUp selectItemWithTitle:[tempObject objectForKey:@"AudioEncoder"]];
+ /* check our pref for core audio and use it in place of faac if applicable */
+ if ([[NSUserDefaults standardUserDefaults] boolForKey: @"UseCoreAudio"] == YES &&
+ [[tempObject objectForKey:@"AudioEncoder"] isEqualToString: @"AAC (faac)"])
+ {
+ [fAudTrack2CodecPopUp selectItemWithTitle:@"AAC (CoreAudio)"];
+ }
[self audioTrackPopUpChanged: fAudTrack2CodecPopUp];
+ [fAudTrack2MixPopUp selectItemWithTitle:[tempObject objectForKey:@"AudioMixdown"]];
+ /* check to see if the selections was available, if not, rerun audioTrackPopUpChanged using the codec to just set the default
+ * mixdown*/
+ if ([fAudTrack2MixPopUp selectedItem] == nil)
+ {
+ [self audioTrackPopUpChanged: fAudTrack2CodecPopUp];
+ }
+ [fAudTrack2RatePopUp selectItemWithTitle:[tempObject objectForKey:@"AudioSamplerate"]];
+ /* We set the presets bitrate if it is *not* an AC3 track since that uses the input bitrate */
+ if (![[tempObject objectForKey:@"AudioEncoder"] isEqualToString:@"AC3 Passthru"])
+ {
+ [fAudTrack2BitratePopUp selectItemWithTitle:[tempObject objectForKey:@"AudioBitrate"]];
+ }
+ [fAudTrack2DrcSlider setFloatValue:[[tempObject objectForKey:@"AudioTrackDRCSlider"] floatValue]];
+ [self audioDRCSliderChanged: fAudTrack2DrcSlider];
+
}
- if ([fAudLang3PopUp indexOfSelectedItem] > 0)
- {
- [fAudTrack3CodecPopUp selectItemWithTitle: @"Vorbis (vorbis)"];
- [self audioTrackPopUpChanged: fAudTrack3CodecPopUp];
- }
- if ([fAudLang4PopUp indexOfSelectedItem] > 0)
- {
- [fAudTrack4CodecPopUp selectItemWithTitle: @"Vorbis (vorbis)"];
- [self audioTrackPopUpChanged: fAudTrack4CodecPopUp];
- }
- }
- /* We detect here if we have the old audio sample rate and if so we apply samplerate and bitrate to the existing four tracks if chosen
- * UNLESS the CodecPopUp is AC3 in which case the preset values are ignored in favor of rates set in audioTrackMixdownChanged*/
- if ([chosenPreset objectForKey:@"AudioSampleRate"])
- {
- if ([fAudLang1PopUp indexOfSelectedItem] > 0 && [fAudTrack1CodecPopUp titleOfSelectedItem] != @"AC3 Passthru")
- {
- [fAudTrack1RatePopUp selectItemWithTitle:[chosenPreset objectForKey:@"AudioSampleRate"]];
- [fAudTrack1BitratePopUp selectItemWithTitle:[chosenPreset objectForKey:@"AudioBitRate"]];
- }
- if ([fAudLang2PopUp indexOfSelectedItem] > 0 && [fAudTrack2CodecPopUp titleOfSelectedItem] != @"AC3 Passthru")
- {
- [fAudTrack2RatePopUp selectItemWithTitle:[chosenPreset objectForKey:@"AudioSampleRate"]];
- [fAudTrack2BitratePopUp selectItemWithTitle:[chosenPreset objectForKey:@"AudioBitRate"]];
- }
- if ([fAudLang3PopUp indexOfSelectedItem] > 0 && [fAudTrack3CodecPopUp titleOfSelectedItem] != @"AC3 Passthru")
- {
- [fAudTrack3RatePopUp selectItemWithTitle:[chosenPreset objectForKey:@"AudioSampleRate"]];
- [fAudTrack3BitratePopUp selectItemWithTitle:[chosenPreset objectForKey:@"AudioBitRate"]];
- }
- if ([fAudLang4PopUp indexOfSelectedItem] > 0 && [fAudTrack4CodecPopUp titleOfSelectedItem] != @"AC3 Passthru")
- {
- [fAudTrack4RatePopUp selectItemWithTitle:[chosenPreset objectForKey:@"AudioSampleRate"]];
- [fAudTrack4BitratePopUp selectItemWithTitle:[chosenPreset objectForKey:@"AudioBitRate"]];
- }
+
}
- /* We detect here if we have the old DRC Slider and if so we apply it to the existing four tracks if chosen */
- if ([chosenPreset objectForKey:@"AudioDRCSlider"])
+
+ /* We now cleanup any extra audio tracks that may have been previously set if we need to */
+
+ if (i < 4)
{
- if ([fAudLang1PopUp indexOfSelectedItem] > 0)
- {
- [fAudTrack1DrcSlider setFloatValue:[[chosenPreset objectForKey:@"AudioDRCSlider"] floatValue]];
- [self audioDRCSliderChanged: fAudTrack1DrcSlider];
- }
- if ([fAudLang2PopUp indexOfSelectedItem] > 0)
- {
- [fAudTrack2DrcSlider setFloatValue:[[chosenPreset objectForKey:@"AudioDRCSlider"] floatValue]];
- [self audioDRCSliderChanged: fAudTrack2DrcSlider];
- }
- if ([fAudLang3PopUp indexOfSelectedItem] > 0)
- {
- [fAudTrack3DrcSlider setFloatValue:[[chosenPreset objectForKey:@"AudioDRCSlider"] floatValue]];
- [self audioDRCSliderChanged: fAudTrack3DrcSlider];
- }
- if ([fAudLang4PopUp indexOfSelectedItem] > 0)
+ [fAudLang4PopUp selectItemAtIndex: 0];
+ [self audioTrackPopUpChanged: fAudLang4PopUp];
+
+ if (i < 3)
{
- [fAudTrack4DrcSlider setFloatValue:[[chosenPreset objectForKey:@"AudioDRCSlider"] floatValue]];
- [self audioDRCSliderChanged: fAudTrack4DrcSlider];
+ [fAudLang3PopUp selectItemAtIndex: 0];
+ [self audioTrackPopUpChanged: fAudLang3PopUp];
+
+ if (i < 2)
+ {
+ [fAudLang2PopUp selectItemAtIndex: 0];
+ [self audioTrackPopUpChanged: fAudLang2PopUp];
+ }
}
}
+
}
- else // since there was no codecs key in the preset we know we can use new multi-audio track presets
+ else
{
if ([chosenPreset objectForKey:@"Audio1Track"] > 0)
{
}
[self audioTrackPopUpChanged: fAudLang1PopUp];
[fAudTrack1CodecPopUp selectItemWithTitle:[chosenPreset objectForKey:@"Audio1Encoder"]];
+ /* check our pref for core audio and use it in place of faac if applicable */
+ if ([[NSUserDefaults standardUserDefaults] boolForKey: @"UseCoreAudio"] == YES &&
+ [[chosenPreset objectForKey:@"Audio1Encoder"] isEqualToString: @"AAC (faac)"])
+ {
+ [fAudTrack1CodecPopUp selectItemWithTitle:@"AAC (CoreAudio)"];
+ }
[self audioTrackPopUpChanged: fAudTrack1CodecPopUp];
[fAudTrack1MixPopUp selectItemWithTitle:[chosenPreset objectForKey:@"Audio1Mixdown"]];
/* check to see if the selections was available, if not, rerun audioTrackPopUpChanged using the codec to just set the default
}
[self audioTrackPopUpChanged: fAudLang2PopUp];
[fAudTrack2CodecPopUp selectItemWithTitle:[chosenPreset objectForKey:@"Audio2Encoder"]];
+ /* check our pref for core audio and use it in place of faac if applicable */
+ if ([[NSUserDefaults standardUserDefaults] boolForKey: @"UseCoreAudio"] == YES &&
+ [[chosenPreset objectForKey:@"Audio2Encoder"] isEqualToString: @"AAC (faac)"])
+ {
+ [fAudTrack2CodecPopUp selectItemWithTitle:@"AAC (CoreAudio)"];
+ }
[self audioTrackPopUpChanged: fAudTrack2CodecPopUp];
[fAudTrack2MixPopUp selectItemWithTitle:[chosenPreset objectForKey:@"Audio2Mixdown"]];
/* check to see if the selections was available, if not, rerun audioTrackPopUpChanged using the codec to just set the default
}
[self audioTrackPopUpChanged: fAudLang3PopUp];
[fAudTrack3CodecPopUp selectItemWithTitle:[chosenPreset objectForKey:@"Audio3Encoder"]];
+ /* check our pref for core audio and use it in place of faac if applicable */
+ if ([[NSUserDefaults standardUserDefaults] boolForKey: @"UseCoreAudio"] == YES &&
+ [[chosenPreset objectForKey:@"Audio3Encoder"] isEqualToString: @"AAC (faac)"])
+ {
+ [fAudTrack3CodecPopUp selectItemWithTitle:@"AAC (CoreAudio)"];
+ }
[self audioTrackPopUpChanged: fAudTrack3CodecPopUp];
[fAudTrack3MixPopUp selectItemWithTitle:[chosenPreset objectForKey:@"Audio3Mixdown"]];
/* check to see if the selections was available, if not, rerun audioTrackPopUpChanged using the codec to just set the default
}
[self audioTrackPopUpChanged: fAudLang4PopUp];
[fAudTrack4CodecPopUp selectItemWithTitle:[chosenPreset objectForKey:@"Audio4Encoder"]];
+ /* check our pref for core audio and use it in place of faac if applicable */
+ if ([[NSUserDefaults standardUserDefaults] boolForKey: @"UseCoreAudio"] == YES &&
+ [[chosenPreset objectForKey:@"Audio4Encoder"] isEqualToString: @"AAC (faac)"])
+ {
+ [fAudTrack4CodecPopUp selectItemWithTitle:@"AAC (CoreAudio)"];
+ }
[self audioTrackPopUpChanged: fAudTrack4CodecPopUp];
[fAudTrack4MixPopUp selectItemWithTitle:[chosenPreset objectForKey:@"Audio4Mixdown"]];
/* check to see if the selections was available, if not, rerun audioTrackPopUpChanged using the codec to just set the default
[self audioDRCSliderChanged: fAudTrack4DrcSlider];
}
+ /* We now cleanup any extra audio tracks that may have been previously set if we need to */
- }
-
- /* We now cleanup any extra audio tracks that may be previously set if we need to, we do it here so we don't have to
- * duplicate any code for legacy presets.*/
- /* First we handle the legacy Codecs crazy AVC/H.264 Video / AAC + AC3 Audio atv hybrid */
- if ([chosenPreset objectForKey:@"FileCodecs"] && [[chosenPreset objectForKey:@"FileCodecs"] isEqualToString:@"AVC/H.264 Video / AAC + AC3 Audio"])
- {
- [fAudLang3PopUp selectItemAtIndex: 0];
- [self audioTrackPopUpChanged: fAudLang3PopUp];
- [fAudLang4PopUp selectItemAtIndex: 0];
- [self audioTrackPopUpChanged: fAudLang4PopUp];
- }
- else
- {
if (![chosenPreset objectForKey:@"Audio2Track"] || [chosenPreset objectForKey:@"Audio2Track"] == 0)
{
[fAudLang2PopUp selectItemAtIndex: 0];
[fSubForcedCheck setState:[[chosenPreset objectForKey:@"SubtitlesForced"] intValue]];
/* Picture Settings */
- /* Note: objectForKey:@"UsesPictureSettings" now refers to picture size, this encompasses:
+ /* Note: objectForKey:@"UsesPictureSettings" refers to picture size, which encompasses:
* height, width, keep ar, anamorphic and crop settings.
- * picture filters are now handled separately.
- * We will be able to actually change the key names for legacy preset keys when preset file
- * update code is done. But for now, lets hang onto the old legacy key name for backwards compatibility.
+ * picture filters are handled separately below.
*/
/* Check to see if the objectForKey:@"UsesPictureSettings is greater than 0, as 0 means use picture sizing "None"
- * and the preset completely ignores any picture sizing values in the preset.
+ * ( 2 is use max for source and 1 is use exact size when the preset was created ) and the
+ * preset completely ignores any picture sizing values in the preset.
*/
if ([[chosenPreset objectForKey:@"UsesPictureSettings"] intValue] > 0)
{
hb_job_t * job = fTitle->job;
/* If Cropping is set to custom, then recall all four crop values from
- when the preset was created and apply them */
- if ([[chosenPreset objectForKey:@"PictureAutoCrop"] intValue] == 0)
- {
- [fPictureController setAutoCrop:NO];
-
- /* Here we use the custom crop values saved at the time the preset was saved */
- job->crop[0] = [[chosenPreset objectForKey:@"PictureTopCrop"] intValue];
- job->crop[1] = [[chosenPreset objectForKey:@"PictureBottomCrop"] intValue];
- job->crop[2] = [[chosenPreset objectForKey:@"PictureLeftCrop"] intValue];
- job->crop[3] = [[chosenPreset objectForKey:@"PictureRightCrop"] intValue];
-
- }
- else /* if auto crop has been saved in preset, set to auto and use post scan auto crop */
- {
- [fPictureController setAutoCrop:YES];
- /* Here we use the auto crop values determined right after scan */
- job->crop[0] = AutoCropTop;
- job->crop[1] = AutoCropBottom;
- job->crop[2] = AutoCropLeft;
- job->crop[3] = AutoCropRight;
-
- }
-
+ when the preset was created and apply them */
+ if ([[chosenPreset objectForKey:@"PictureAutoCrop"] intValue] == 0)
+ {
+ [fPictureController setAutoCrop:NO];
+
+ /* Here we use the custom crop values saved at the time the preset was saved */
+ job->crop[0] = [[chosenPreset objectForKey:@"PictureTopCrop"] intValue];
+ job->crop[1] = [[chosenPreset objectForKey:@"PictureBottomCrop"] intValue];
+ job->crop[2] = [[chosenPreset objectForKey:@"PictureLeftCrop"] intValue];
+ job->crop[3] = [[chosenPreset objectForKey:@"PictureRightCrop"] intValue];
+
+ }
+ else /* if auto crop has been saved in preset, set to auto and use post scan auto crop */
+ {
+ [fPictureController setAutoCrop:YES];
+ /* Here we use the auto crop values determined right after scan */
+ job->crop[0] = AutoCropTop;
+ job->crop[1] = AutoCropBottom;
+ job->crop[2] = AutoCropLeft;
+ job->crop[3] = AutoCropRight;
+
+ }
+
/* Check to see if the objectForKey:@"UsesPictureSettings is 2 which is "Use Max for the source */
if ([[chosenPreset objectForKey:@"UsesPictureSettings"] intValue] == 2 || [[chosenPreset objectForKey:@"UsesMaxPictureSettings"] intValue] == 1)
hb_fix_aspect( job, HB_KEEP_HEIGHT );
}
}
- job->pixel_ratio = [[chosenPreset objectForKey:@"PicturePAR"] intValue];
+ job->anamorphic.mode = [[chosenPreset objectForKey:@"PicturePAR"] intValue];
}
else // /* If not 0 or 2 we assume objectForKey:@"UsesPictureSettings is 1 which is "Use picture sizing from when the preset was set" */
{
if (fTitle->width < [[chosenPreset objectForKey:@"PictureWidth"] intValue] || fTitle->height < [[chosenPreset objectForKey:@"PictureHeight"] intValue])
{
/* if so, then we use the sources height and width to avoid scaling up */
- job->width = fTitle->width;
- job->height = fTitle->height;
+ //job->width = fTitle->width;
+ //job->height = fTitle->height;
+ [self revertPictureSizeToMax:nil];
}
else // source width/height is >= the preset height/width
{
hb_fix_aspect( job, HB_KEEP_HEIGHT );
}
}
- job->pixel_ratio = [[chosenPreset objectForKey:@"PicturePAR"] intValue];
-
-
- /* If the preset has no objectForKey:@"UsesPictureFilters", then we know it is a legacy preset
- * and handle the filters here as before.
- * NOTE: This should be removed when the update presets code is done as we can be assured that legacy
- * presets are updated to work properly with new keys.
- */
- if (![chosenPreset objectForKey:@"UsesPictureFilters"])
- {
- /* Filters */
- /* Deinterlace */
- if ([chosenPreset objectForKey:@"PictureDeinterlace"])
- {
- /* We check to see if the preset used the past fourth "Slowest" deinterlaceing and set that to "Slower
- * since we no longer have a fourth "Slowest" deinterlacing due to the mcdeint bug */
- if ([[chosenPreset objectForKey:@"PictureDeinterlace"] intValue] == 4)
- {
- [fPictureController setDeinterlace:3];
- }
- else
- {
-
- [fPictureController setDeinterlace:[[chosenPreset objectForKey:@"PictureDeinterlace"] intValue]];
- }
- }
- else
- {
- [fPictureController setDeinterlace:0];
- }
- /* VFR */
- if ([[chosenPreset objectForKey:@"VFR"] intValue] == 1)
- {
- // We make sure that framerate is set to Same as source variable
- // detelecine will take care of itself right below
- //[fPictureController setVFR:[[chosenPreset objectForKey:@"VFR"] intValue]];
- }
-
- /* Detelecine */
- if ([[chosenPreset objectForKey:@"PictureDetelecine"] intValue] == 1)
- {
- [fPictureController setDetelecine:[[chosenPreset objectForKey:@"PictureDetelecine"] intValue]];
- }
- else
- {
- [fPictureController setDetelecine:0];
- }
- /* Denoise */
- if ([chosenPreset objectForKey:@"PictureDenoise"])
- {
- [fPictureController setDenoise:[[chosenPreset objectForKey:@"PictureDenoise"] intValue]];
- }
- else
- {
- [fPictureController setDenoise:0];
- }
- /* Deblock */
- if ([[chosenPreset objectForKey:@"PictureDeblock"] intValue] == 1)
- {
- /* since we used to use 1 to turn on deblock, we now use a 5 in our sliding scale */
- [fPictureController setDeblock:5];
- }
- else
- {
- [fPictureController setDeblock:0];
-
- }
-
- [self calculatePictureSizing:nil];
- }
+ job->anamorphic.mode = [[chosenPreset objectForKey:@"PicturePAR"] intValue];
}
}
- /* If the preset has an objectForKey:@"UsesPictureFilters", then we know it is a newer style filters preset
- * and handle the filters here depending on whether or not the preset specifies applying the filter.
- */
+ /* If the preset has an objectForKey:@"UsesPictureFilters", and handle the filters here */
if ([chosenPreset objectForKey:@"UsesPictureFilters"] && [[chosenPreset objectForKey:@"UsesPictureFilters"] intValue] > 0)
{
/* Filters */
- /* Deinterlace */
- if ([chosenPreset objectForKey:@"PictureDeinterlace"])
+
+ /* We only allow *either* Decomb or Deinterlace. So check for the PictureDecombDeinterlace key.
+ * also, older presets may not have this key, in which case we also check to see if that preset had PictureDecomb
+ * specified, in which case we use decomb and ignore any possible Deinterlace settings as using both was less than
+ * sane.
+ */
+ [fPictureController setUseDecomb:1];
+ [fPictureController setDecomb:0];
+ [fPictureController setDeinterlace:0];
+ if ([[chosenPreset objectForKey:@"PictureDecombDeinterlace"] intValue] == 1 || [[chosenPreset objectForKey:@"PictureDecomb"] intValue] > 0)
{
- /* We check to see if the preset used the past fourth "Slowest" deinterlaceing and set that to "Slower
- * since we no longer have a fourth "Slowest" deinterlacing due to the mcdeint bug */
- if ([[chosenPreset objectForKey:@"PictureDeinterlace"] intValue] == 4)
+ /* we are using decomb */
+ /* Decomb */
+ if ([[chosenPreset objectForKey:@"PictureDecomb"] intValue] > 0)
{
- [fPictureController setDeinterlace:3];
+ [fPictureController setDecomb:[[chosenPreset objectForKey:@"PictureDecomb"] intValue]];
+
+ /* if we are using "Custom" in the decomb setting, also set the custom string*/
+ if ([[chosenPreset objectForKey:@"PictureDecomb"] intValue] == 2)
+ {
+ [fPictureController setDecombCustomString:[chosenPreset objectForKey:@"PictureDecombCustom"]];
+ }
}
- else
+ }
+ else
+ {
+ /* We are using Deinterlace */
+ /* Deinterlace */
+ if ([[chosenPreset objectForKey:@"PictureDeinterlace"] intValue] > 0)
{
+ [fPictureController setUseDecomb:0];
[fPictureController setDeinterlace:[[chosenPreset objectForKey:@"PictureDeinterlace"] intValue]];
+ /* if we are using "Custom" in the deinterlace setting, also set the custom string*/
+ if ([[chosenPreset objectForKey:@"PictureDeinterlace"] intValue] == 4)
+ {
+ [fPictureController setDeinterlaceCustomString:[chosenPreset objectForKey:@"PictureDeinterlaceCustom"]];
+ }
}
}
- else
- {
- [fPictureController setDeinterlace:0];
- }
+
/* Detelecine */
- if ([[chosenPreset objectForKey:@"PictureDetelecine"] intValue] == 1)
+ if ([[chosenPreset objectForKey:@"PictureDetelecine"] intValue] > 0)
{
[fPictureController setDetelecine:[[chosenPreset objectForKey:@"PictureDetelecine"] intValue]];
+ /* if we are using "Custom" in the detelecine setting, also set the custom string*/
+ if ([[chosenPreset objectForKey:@"PictureDetelecine"] intValue] == 2)
+ {
+ [fPictureController setDetelecineCustomString:[chosenPreset objectForKey:@"PictureDetelecineCustom"]];
+ }
}
else
{
[fPictureController setDetelecine:0];
}
+
/* Denoise */
- if ([chosenPreset objectForKey:@"PictureDenoise"])
+ if ([[chosenPreset objectForKey:@"PictureDenoise"] intValue] > 0)
{
[fPictureController setDenoise:[[chosenPreset objectForKey:@"PictureDenoise"] intValue]];
+ /* if we are using "Custom" in the denoise setting, also set the custom string*/
+ if ([[chosenPreset objectForKey:@"PictureDenoise"] intValue] == 4)
+ {
+ [fPictureController setDenoiseCustomString:[chosenPreset objectForKey:@"PictureDenoiseCustom"]];
+ }
}
else
{
[fPictureController setDenoise:0];
}
+
/* Deblock */
if ([[chosenPreset objectForKey:@"PictureDeblock"] intValue] == 1)
{
/* use the settings intValue */
[fPictureController setDeblock:[[chosenPreset objectForKey:@"PictureDeblock"] intValue]];
}
- /* Decomb */
- /* Even though we currently allow for a custom setting for decomb, ultimately it will only have Off and
- * Default so we just pay attention to anything greater than 0 as 1 (Default). 0 is Off. */
- if ([[chosenPreset objectForKey:@"PictureDecomb"] intValue] == 1)
+
+ if ([[chosenPreset objectForKey:@"VideoGrayScale"] intValue] == 1)
{
- [fPictureController setDecomb:1];
+ [fPictureController setGrayscale:1];
}
else
{
- [fPictureController setDecomb:0];
+ [fPictureController setGrayscale:0];
}
}
+ /* we call SetTitle: in fPictureController so we get an instant update in the Picture Settings window */
+ [fPictureController SetTitle:fTitle];
+ [fPictureController SetTitle:fTitle];
[self calculatePictureSizing:nil];
}
}
[self addFactoryPresets:nil];
}
[fPresetsOutlineView reloadData];
+
+ [self checkBuiltInsForUpdates];
+}
+
+- (void) checkBuiltInsForUpdates {
+
+ BOOL updateBuiltInPresets = NO;
+ int i = 0;
+ NSEnumerator *enumerator = [UserPresets objectEnumerator];
+ id tempObject;
+ while (tempObject = [enumerator nextObject])
+ {
+ /* iterate through the built in presets to see if any have an old build number */
+ NSMutableDictionary *thisPresetDict = tempObject;
+ /*Key Type == 0 is built in, and key PresetBuildNumber is the build number it was created with */
+ if ([[thisPresetDict objectForKey:@"Type"] intValue] == 0)
+ {
+ if (![thisPresetDict objectForKey:@"PresetBuildNumber"] || [[thisPresetDict objectForKey:@"PresetBuildNumber"] intValue] < [[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"] intValue])
+ {
+ updateBuiltInPresets = YES;
+ }
+ }
+ i++;
+ }
+ /* if we have built in presets to update, then do so AlertBuiltInPresetUpdate*/
+ if ( updateBuiltInPresets == YES)
+ {
+ if( [[NSUserDefaults standardUserDefaults] boolForKey:@"AlertBuiltInPresetUpdate"] == YES)
+ {
+ /* Show an alert window that built in presets will be updated */
+ /*On Screen Notification*/
+ int status;
+ NSBeep();
+ status = NSRunAlertPanel(@"HandBrake has determined your built in presets are out of date...",@"HandBrake will now update your built-in presets.", @"OK", nil, nil);
+ [NSApp requestUserAttention:NSCriticalRequest];
+ }
+ /* when alert is dismissed, go ahead and update the built in presets */
+ [self addFactoryPresets:nil];
+ }
+
}
- (NSDictionary *)createPreset
{
NSMutableDictionary *preset = [[NSMutableDictionary alloc] init];
+ /* Preset build number */
+ [preset setObject:[NSString stringWithFormat: @"%d", [[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"] intValue]] forKey:@"PresetBuildNumber"];
+ [preset setObject:[fPresetNewName stringValue] forKey:@"PresetName"];
/* Get the New Preset Name from the field in the AddPresetPanel */
[preset setObject:[fPresetNewName stringValue] forKey:@"PresetName"];
/* Set whether or not this is to be a folder fPresetNewFolderCheck*/
[preset setObject:[NSNumber numberWithInt:[fVidQualityMatrix selectedRow]] forKey:@"VideoQualityType"];
[preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
[preset setObject:[fVidBitrateField stringValue] forKey:@"VideoAvgBitrate"];
- [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
+ [preset setObject:[NSNumber numberWithFloat:[fVidQualityRFField floatValue]] forKey:@"VideoQualitySlider"];
/* Video framerate */
if ([fVidRatePopUp indexOfSelectedItem] == 0) // Same as source is selected
{
[preset setObject:[fVidRatePopUp titleOfSelectedItem] forKey:@"VideoFramerate"];
}
- /* GrayScale */
- [preset setObject:[NSNumber numberWithInt:[fVidGrayscaleCheck state]] forKey:@"VideoGrayScale"];
+
/* 2 Pass Encoding */
[preset setObject:[NSNumber numberWithInt:[fVidTwoPassCheck state]] forKey:@"VideoTwoPass"];
/* Turbo 2 pass Encoding fVidTurboPassCheck*/
[preset setObject:[NSNumber numberWithInt:fTitle->job->width] forKey:@"PictureWidth"];
[preset setObject:[NSNumber numberWithInt:fTitle->job->height] forKey:@"PictureHeight"];
[preset setObject:[NSNumber numberWithInt:fTitle->job->keep_ratio] forKey:@"PictureKeepRatio"];
- [preset setObject:[NSNumber numberWithInt:fTitle->job->pixel_ratio] forKey:@"PicturePAR"];
+ [preset setObject:[NSNumber numberWithInt:fTitle->job->anamorphic.mode] forKey:@"PicturePAR"];
/* Set crop settings here */
[preset setObject:[NSNumber numberWithInt:[fPictureController autoCrop]] forKey:@"PictureAutoCrop"];
[preset setObject:[NSNumber numberWithInt:job->crop[3]] forKey:@"PictureRightCrop"];
/* Picture Filters */
+ [preset setObject:[NSNumber numberWithInt:[fPictureController useDecomb]] forKey:@"PictureDecombDeinterlace"];
[preset setObject:[NSNumber numberWithInt:[fPictureController deinterlace]] forKey:@"PictureDeinterlace"];
+ [preset setObject:[fPictureController deinterlaceCustomString] forKey:@"PictureDeinterlaceCustom"];
[preset setObject:[NSNumber numberWithInt:[fPictureController detelecine]] forKey:@"PictureDetelecine"];
- //[preset setObject:[NSNumber numberWithInt:[fPictureController vfr]] forKey:@"VFR"];
+ [preset setObject:[fPictureController detelecineCustomString] forKey:@"PictureDetelecineCustom"];
[preset setObject:[NSNumber numberWithInt:[fPictureController denoise]] forKey:@"PictureDenoise"];
+ [preset setObject:[fPictureController denoiseCustomString] forKey:@"PictureDenoiseCustom"];
[preset setObject:[NSNumber numberWithInt:[fPictureController deblock]] forKey:@"PictureDeblock"];
[preset setObject:[NSNumber numberWithInt:[fPictureController decomb]] forKey:@"PictureDecomb"];
-
+ [preset setObject:[fPictureController decombCustomString] forKey:@"PictureDecombCustom"];
+ [preset setObject:[NSNumber numberWithInt:[fPictureController grayscale]] forKey:@"VideoGrayScale"];
/*Audio*/
+ NSMutableArray *audioListArray = [[NSMutableArray alloc] init];
+ /* we actually call the methods for the nests here */
if ([fAudLang1PopUp indexOfSelectedItem] > 0)
{
- [preset setObject:[NSNumber numberWithInt:[fAudLang1PopUp indexOfSelectedItem]] forKey:@"Audio1Track"];
- [preset setObject:[fAudLang1PopUp titleOfSelectedItem] forKey:@"Audio1TrackDescription"];
- [preset setObject:[fAudTrack1CodecPopUp titleOfSelectedItem] forKey:@"Audio1Encoder"];
- [preset setObject:[fAudTrack1MixPopUp titleOfSelectedItem] forKey:@"Audio1Mixdown"];
- [preset setObject:[fAudTrack1RatePopUp titleOfSelectedItem] forKey:@"Audio1Samplerate"];
- [preset setObject:[fAudTrack1BitratePopUp titleOfSelectedItem] forKey:@"Audio1Bitrate"];
- [preset setObject:[NSNumber numberWithFloat:[fAudTrack1DrcSlider floatValue]] forKey:@"Audio1TrackDRCSlider"];
+ NSMutableDictionary *audioTrack1Array = [[NSMutableDictionary alloc] init];
+ [audioTrack1Array setObject:[NSNumber numberWithInt:[fAudLang1PopUp indexOfSelectedItem]] forKey:@"AudioTrack"];
+ [audioTrack1Array setObject:[fAudLang1PopUp titleOfSelectedItem] forKey:@"AudioTrackDescription"];
+ [audioTrack1Array setObject:[fAudTrack1CodecPopUp titleOfSelectedItem] forKey:@"AudioEncoder"];
+ [audioTrack1Array setObject:[fAudTrack1MixPopUp titleOfSelectedItem] forKey:@"AudioMixdown"];
+ [audioTrack1Array setObject:[fAudTrack1RatePopUp titleOfSelectedItem] forKey:@"AudioSamplerate"];
+ [audioTrack1Array setObject:[fAudTrack1BitratePopUp titleOfSelectedItem] forKey:@"AudioBitrate"];
+ [audioTrack1Array setObject:[NSNumber numberWithFloat:[fAudTrack1DrcSlider floatValue]] forKey:@"AudioTrackDRCSlider"];
+ [audioTrack1Array autorelease];
+ [audioListArray addObject:audioTrack1Array];
}
+
if ([fAudLang2PopUp indexOfSelectedItem] > 0)
{
- [preset setObject:[NSNumber numberWithInt:[fAudLang2PopUp indexOfSelectedItem]] forKey:@"Audio2Track"];
- [preset setObject:[fAudLang2PopUp titleOfSelectedItem] forKey:@"Audio2TrackDescription"];
- [preset setObject:[fAudTrack2CodecPopUp titleOfSelectedItem] forKey:@"Audio2Encoder"];
- [preset setObject:[fAudTrack2MixPopUp titleOfSelectedItem] forKey:@"Audio2Mixdown"];
- [preset setObject:[fAudTrack2RatePopUp titleOfSelectedItem] forKey:@"Audio2Samplerate"];
- [preset setObject:[fAudTrack2BitratePopUp titleOfSelectedItem] forKey:@"Audio2Bitrate"];
- [preset setObject:[NSNumber numberWithFloat:[fAudTrack2DrcSlider floatValue]] forKey:@"Audio2TrackDRCSlider"];
+ NSMutableDictionary *audioTrack2Array = [[NSMutableDictionary alloc] init];
+ [audioTrack2Array setObject:[NSNumber numberWithInt:[fAudLang2PopUp indexOfSelectedItem]] forKey:@"AudioTrack"];
+ [audioTrack2Array setObject:[fAudLang2PopUp titleOfSelectedItem] forKey:@"AudioTrackDescription"];
+ [audioTrack2Array setObject:[fAudTrack2CodecPopUp titleOfSelectedItem] forKey:@"AudioEncoder"];
+ [audioTrack2Array setObject:[fAudTrack2MixPopUp titleOfSelectedItem] forKey:@"AudioMixdown"];
+ [audioTrack2Array setObject:[fAudTrack2RatePopUp titleOfSelectedItem] forKey:@"AudioSamplerate"];
+ [audioTrack2Array setObject:[fAudTrack2BitratePopUp titleOfSelectedItem] forKey:@"AudioBitrate"];
+ [audioTrack2Array setObject:[NSNumber numberWithFloat:[fAudTrack2DrcSlider floatValue]] forKey:@"AudioTrackDRCSlider"];
+ [audioTrack2Array autorelease];
+ [audioListArray addObject:audioTrack2Array];
}
+
if ([fAudLang3PopUp indexOfSelectedItem] > 0)
{
- [preset setObject:[NSNumber numberWithInt:[fAudLang3PopUp indexOfSelectedItem]] forKey:@"Audio3Track"];
- [preset setObject:[fAudLang3PopUp titleOfSelectedItem] forKey:@"Audio3TrackDescription"];
- [preset setObject:[fAudTrack3CodecPopUp titleOfSelectedItem] forKey:@"Audio3Encoder"];
- [preset setObject:[fAudTrack3MixPopUp titleOfSelectedItem] forKey:@"Audio3Mixdown"];
- [preset setObject:[fAudTrack3RatePopUp titleOfSelectedItem] forKey:@"Audio3Samplerate"];
- [preset setObject:[fAudTrack3BitratePopUp titleOfSelectedItem] forKey:@"Audio3Bitrate"];
- [preset setObject:[NSNumber numberWithFloat:[fAudTrack3DrcSlider floatValue]] forKey:@"Audio3TrackDRCSlider"];
+ NSMutableDictionary *audioTrack3Array = [[NSMutableDictionary alloc] init];
+ [audioTrack3Array setObject:[NSNumber numberWithInt:[fAudLang3PopUp indexOfSelectedItem]] forKey:@"AudioTrack"];
+ [audioTrack3Array setObject:[fAudLang3PopUp titleOfSelectedItem] forKey:@"AudioTrackDescription"];
+ [audioTrack3Array setObject:[fAudTrack3CodecPopUp titleOfSelectedItem] forKey:@"AudioEncoder"];
+ [audioTrack3Array setObject:[fAudTrack3MixPopUp titleOfSelectedItem] forKey:@"AudioMixdown"];
+ [audioTrack3Array setObject:[fAudTrack3RatePopUp titleOfSelectedItem] forKey:@"AudioSamplerate"];
+ [audioTrack3Array setObject:[fAudTrack3BitratePopUp titleOfSelectedItem] forKey:@"AudioBitrate"];
+ [audioTrack3Array setObject:[NSNumber numberWithFloat:[fAudTrack3DrcSlider floatValue]] forKey:@"AudioTrackDRCSlider"];
+ [audioTrack3Array autorelease];
+ [audioListArray addObject:audioTrack3Array];
}
+
if ([fAudLang4PopUp indexOfSelectedItem] > 0)
{
- [preset setObject:[NSNumber numberWithInt:[fAudLang4PopUp indexOfSelectedItem]] forKey:@"Audio4Track"];
- [preset setObject:[fAudLang4PopUp titleOfSelectedItem] forKey:@"Audio4TrackDescription"];
- [preset setObject:[fAudTrack4CodecPopUp titleOfSelectedItem] forKey:@"Audio4Encoder"];
- [preset setObject:[fAudTrack4MixPopUp titleOfSelectedItem] forKey:@"Audio4Mixdown"];
- [preset setObject:[fAudTrack4RatePopUp titleOfSelectedItem] forKey:@"Audio4Samplerate"];
- [preset setObject:[fAudTrack4BitratePopUp titleOfSelectedItem] forKey:@"Audio4Bitrate"];
- [preset setObject:[NSNumber numberWithFloat:[fAudTrack4DrcSlider floatValue]] forKey:@"Audio4TrackDRCSlider"];
+ NSMutableDictionary *audioTrack4Array = [[NSMutableDictionary alloc] init];
+ [audioTrack4Array setObject:[NSNumber numberWithInt:[fAudLang4PopUp indexOfSelectedItem]] forKey:@"AudioTrack"];
+ [audioTrack4Array setObject:[fAudLang4PopUp titleOfSelectedItem] forKey:@"AudioTrackDescription"];
+ [audioTrack4Array setObject:[fAudTrack4CodecPopUp titleOfSelectedItem] forKey:@"AudioEncoder"];
+ [audioTrack4Array setObject:[fAudTrack4MixPopUp titleOfSelectedItem] forKey:@"AudioMixdown"];
+ [audioTrack4Array setObject:[fAudTrack4RatePopUp titleOfSelectedItem] forKey:@"AudioSamplerate"];
+ [audioTrack4Array setObject:[fAudTrack4BitratePopUp titleOfSelectedItem] forKey:@"AudioBitrate"];
+ [audioTrack4Array setObject:[NSNumber numberWithFloat:[fAudTrack4DrcSlider floatValue]] forKey:@"AudioTrackDRCSlider"];
+ [audioTrack4Array autorelease];
+ [audioListArray addObject:audioTrack4Array];
}
+
+ [preset setObject:[NSMutableArray arrayWithArray: audioListArray] forKey:@"AudioList"];
+
+
+ /* Temporarily remove subtitles from creating a new preset as it has to be converted over to use the new
+ * subititle array code. */
/* Subtitles*/
- [preset setObject:[fSubPopUp titleOfSelectedItem] forKey:@"Subtitles"];
+ //[preset setObject:[fSubPopUp titleOfSelectedItem] forKey:@"Subtitles"];
/* Forced Subtitles */
- [preset setObject:[NSNumber numberWithInt:[fSubForcedCheck state]] forKey:@"SubtitlesForced"];
+ //[preset setObject:[NSNumber numberWithInt:[fSubForcedCheck state]] forKey:@"SubtitlesForced"];
}
[preset autorelease];
return preset;
}
}
+
+#pragma mark -
+#pragma mark Import Export Preset(s)
+
+- (IBAction) browseExportPresetFile: (id) sender
+{
+ /* Open a panel to let the user choose where and how to save the export file */
+ NSSavePanel * panel = [NSSavePanel savePanel];
+ /* We get the current file name and path from the destination field here */
+ NSString *defaultExportDirectory = [NSString stringWithFormat: @"%@/Desktop/", NSHomeDirectory()];
+
+ [panel beginSheetForDirectory: defaultExportDirectory file: @"HB_Export.plist"
+ modalForWindow: fWindow modalDelegate: self
+ didEndSelector: @selector( browseExportPresetFileDone:returnCode:contextInfo: )
+ contextInfo: NULL];
+}
+
+- (void) browseExportPresetFileDone: (NSSavePanel *) sheet
+ returnCode: (int) returnCode contextInfo: (void *) contextInfo
+{
+ if( returnCode == NSOKButton )
+ {
+ NSString *presetExportDirectory = [[sheet filename] stringByDeletingLastPathComponent];
+ NSString *exportPresetsFile = [sheet filename];
+ [[NSUserDefaults standardUserDefaults] setObject:presetExportDirectory forKey:@"LastPresetExportDirectory"];
+ /* We check for the presets.plist */
+ if ([[NSFileManager defaultManager] fileExistsAtPath:exportPresetsFile] == 0)
+ {
+ [[NSFileManager defaultManager] createFileAtPath:exportPresetsFile contents:nil attributes:nil];
+ }
+ NSMutableArray * presetsToExport = [[NSMutableArray alloc] initWithContentsOfFile:exportPresetsFile];
+ if (nil == presetsToExport)
+ {
+ presetsToExport = [[NSMutableArray alloc] init];
+
+ /* now get and add selected presets to export */
+
+ }
+ if ([fPresetsOutlineView selectedRow] >= 0 && [[[fPresetsOutlineView itemAtRow:[fPresetsOutlineView selectedRow]] objectForKey:@"Folder"] intValue] != 1)
+ {
+ [presetsToExport addObject:[fPresetsOutlineView itemAtRow:[fPresetsOutlineView selectedRow]]];
+ [presetsToExport writeToFile:exportPresetsFile atomically:YES];
+
+ }
+
+ }
+}
+
+
+- (IBAction) browseImportPresetFile: (id) sender
+{
+
+ NSOpenPanel * panel;
+
+ panel = [NSOpenPanel openPanel];
+ [panel setAllowsMultipleSelection: NO];
+ [panel setCanChooseFiles: YES];
+ [panel setCanChooseDirectories: NO ];
+ NSString * sourceDirectory;
+ if ([[NSUserDefaults standardUserDefaults] stringForKey:@"LastPresetImportDirectory"])
+ {
+ sourceDirectory = [[NSUserDefaults standardUserDefaults] stringForKey:@"LastPresetImportDirectory"];
+ }
+ else
+ {
+ sourceDirectory = @"~/Desktop";
+ sourceDirectory = [sourceDirectory stringByExpandingTildeInPath];
+ }
+ /* we open up the browse sources sheet here and call for browseSourcesDone after the sheet is closed
+ * to evaluate whether we want to specify a title, we pass the sender in the contextInfo variable
+ */
+ /* set this for allowed file types, not sure if we should allow xml or not */
+ NSArray *fileTypes = [NSArray arrayWithObjects:@"plist", @"xml", nil];
+ [panel beginSheetForDirectory: sourceDirectory file: nil types: fileTypes
+ modalForWindow: fWindow modalDelegate: self
+ didEndSelector: @selector( browseImportPresetDone:returnCode:contextInfo: )
+ contextInfo: sender];
+}
+
+- (void) browseImportPresetDone: (NSSavePanel *) sheet
+ returnCode: (int) returnCode contextInfo: (void *) contextInfo
+{
+ if( returnCode == NSOKButton )
+ {
+ NSString *importPresetsDirectory = [[sheet filename] stringByDeletingLastPathComponent];
+ NSString *importPresetsFile = [sheet filename];
+ [[NSUserDefaults standardUserDefaults] setObject:importPresetsDirectory forKey:@"LastPresetImportDirectory"];
+ /* NOTE: here we need to do some sanity checking to verify we do not hose up our presets file */
+ NSMutableArray * presetsToImport = [[NSMutableArray alloc] initWithContentsOfFile:importPresetsFile];
+ /* iterate though the new array of presets to import and add them to our presets array */
+ int i = 0;
+ NSEnumerator *enumerator = [presetsToImport objectEnumerator];
+ id tempObject;
+ while (tempObject = [enumerator nextObject])
+ {
+ /* make any changes to the incoming preset we see fit */
+ /* make sure the incoming preset is not tagged as default */
+ [tempObject setObject:[NSNumber numberWithInt:0] forKey:@"Default"];
+ /* prepend "(imported) to the name of the incoming preset for clarification since it can be changed */
+ NSString * prependedName = [@"(import) " stringByAppendingString:[tempObject objectForKey:@"PresetName"]] ;
+ [tempObject setObject:prependedName forKey:@"PresetName"];
+
+ /* actually add the new preset to our presets array */
+ [UserPresets addObject:tempObject];
+ i++;
+ }
+ [presetsToImport autorelease];
+ [self sortPresets];
+ [self addPreset];
+
+ }
+}
+
#pragma mark -
#pragma mark Manage Default Preset
}
- /* We use this method to recreate new, updated factory
- presets */
+ /* We use this method to recreate new, updated factory presets */
- (IBAction)addFactoryPresets:(id)sender
{
-
- /* First, we delete any existing built in presets */
+
+ /* First, we delete any existing built in presets */
[self deleteFactoryPresets: sender];
/* Then we generate new built in presets programmatically with fPresetsBuiltin
- * which is all setup in HBPresets.h and HBPresets.m*/
+ * which is all setup in HBPresets.h and HBPresets.m*/
[fPresetsBuiltin generateBuiltinPresets:UserPresets];
+ /* update build number for built in presets */
+ /* iterate though the new array of presets to import and add them to our presets array */
+ int i = 0;
+ NSEnumerator *enumerator = [UserPresets objectEnumerator];
+ id tempObject;
+ while (tempObject = [enumerator nextObject])
+ {
+ /* Record the apps current build number in the PresetBuildNumber key */
+ if ([[tempObject objectForKey:@"Type"] intValue] == 0) // Type 0 is a built in preset
+ {
+ /* Preset build number */
+ [[UserPresets objectAtIndex:i] setObject:[NSNumber numberWithInt:[[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"] intValue]] forKey:@"PresetBuildNumber"];
+ }
+ i++;
+ }
+ /* report the built in preset updating to the activity log */
+ [self writeToActivityLog: "built in presets updated to build number: %d", [[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"] intValue]];
+
[self sortPresets];
[self addPreset];
}
-
-
-
@end
/*******************************