X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=macosx%2FController.mm;h=79c9d6c94977fe861a97f6f0d848d0baf31f5568;hb=ba2fb816048acfd20d9da4dd0eeb5a59bdd0b3cc;hp=4fab8de1df09efe20b1e18caef58d968c4c830e9;hpb=13b3c20fb3be511f8afe162d09f62b427900b4f3;p=handbrake-jp%2Fhandbrake-jp-git.git diff --git a/macosx/Controller.mm b/macosx/Controller.mm index 4fab8de1..79c9d6c9 100644 --- a/macosx/Controller.mm +++ b/macosx/Controller.mm @@ -8,6 +8,12 @@ #include "a52dec/a52.h" #import "HBOutputPanelController.h" #import "HBPreferencesController.h" +/* Added to integrate scanning into HBController */ +#include +#include +#include +#include "HBDVDDetector.h" +#include "dvdread/dvd_reader.h" #define _(a) NSLocalizedString(a,NULL) @@ -15,14 +21,6 @@ static int FormatSettings[4][10] = { { HB_MUX_MP4 | HB_VCODEC_FFMPEG | HB_ACODEC_FAAC, HB_MUX_MP4 | HB_VCODEC_X264 | HB_ACODEC_FAAC, 0, - 0}, - { HB_MUX_AVI | HB_VCODEC_FFMPEG | HB_ACODEC_LAME, - HB_MUX_AVI | HB_VCODEC_FFMPEG | HB_ACODEC_AC3, - HB_MUX_AVI | HB_VCODEC_X264 | HB_ACODEC_LAME, - HB_MUX_AVI | HB_VCODEC_X264 | HB_ACODEC_AC3}, - { HB_MUX_OGM | HB_VCODEC_FFMPEG | HB_ACODEC_VORBIS, - HB_MUX_OGM | HB_VCODEC_FFMPEG | HB_ACODEC_LAME, - 0, 0 }, { HB_MUX_MKV | HB_VCODEC_FFMPEG | HB_ACODEC_FAAC, HB_MUX_MKV | HB_VCODEC_FFMPEG | HB_ACODEC_AC3, @@ -33,17 +31,25 @@ static int FormatSettings[4][10] = HB_MUX_MKV | HB_VCODEC_X264 | HB_ACODEC_LAME, HB_MUX_MKV | HB_VCODEC_X264 | HB_ACODEC_VORBIS, 0, + 0 }, + { HB_MUX_AVI | HB_VCODEC_FFMPEG | HB_ACODEC_LAME, + HB_MUX_AVI | HB_VCODEC_FFMPEG | HB_ACODEC_AC3, + HB_MUX_AVI | HB_VCODEC_X264 | HB_ACODEC_LAME, + HB_MUX_AVI | HB_VCODEC_X264 | HB_ACODEC_AC3}, + { HB_MUX_OGM | HB_VCODEC_FFMPEG | HB_ACODEC_VORBIS, + HB_MUX_OGM | HB_VCODEC_FFMPEG | HB_ACODEC_LAME, + 0, 0 } }; /* We setup the toolbar values here */ -static NSString* MyDocToolbarIdentifier = @"My Document Toolbar Identifier"; -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* DebugOutputIdentifier = @"Debug Output Item Identifier"; -static NSString* ChooseSourceIdentifier = @"Choose Source Item Identifier"; +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 * ShowActivityIdentifier = @"Debug Output Item Identifier"; +static NSString * ChooseSourceIdentifier = @"Choose Source Item Identifier"; + /******************************* * HBController implementation * @@ -55,73 +61,151 @@ static NSString* ChooseSourceIdentifier = @"Choose Source Item Identifie self = [super init]; [HBPreferencesController registerUserDefaults]; fHandle = NULL; + /* Check for check for the app support directory here as + * outputPanel needs it right away, as may other future methods + */ + /* We declare the default NSFileManager into fileManager */ + NSFileManager * fileManager = [NSFileManager defaultManager]; + /* we set the files and support paths here */ + AppSupportDirectory = @"~/Library/Application Support/HandBrake"; + AppSupportDirectory = [AppSupportDirectory stringByExpandingTildeInPath]; + /* We check for the app support directory for handbrake */ + if ([fileManager fileExistsAtPath:AppSupportDirectory] == 0) + { + // If it doesnt exist yet, we create it here + [fileManager createDirectoryAtPath:AppSupportDirectory attributes:nil]; + } + outputPanel = [[HBOutputPanelController alloc] init]; + fPictureController = [[PictureController alloc] initWithDelegate:self]; + fQueueController = [[HBQueueController alloc] init]; + fAdvancedOptions = [[HBAdvancedController alloc] init]; + fPreferencesController = [[HBPreferencesController alloc] init]; return self; } + - (void) applicationDidFinishLaunching: (NSNotification *) notification { int build; char * version; - - // Open debug output window now if it was visible when HB was closed - if ([[NSUserDefaults standardUserDefaults] boolForKey:@"OutputPanelIsOpen"]) - [self showDebugOutputPanel:nil]; - + // Init libhb int debugLevel = [[NSUserDefaults standardUserDefaults] boolForKey:@"ShowVerboseOutput"] ? HB_DEBUG_ALL : HB_DEBUG_NONE; fHandle = hb_init(debugLevel, [[NSUserDefaults standardUserDefaults] boolForKey:@"CheckForUpdates"]); - + // Set the Growl Delegate - HBController *hbGrowlDelegate = [[HBController alloc] init]; - [GrowlApplicationBridge setGrowlDelegate: hbGrowlDelegate]; + [GrowlApplicationBridge setGrowlDelegate: self]; /* Init others controllers */ - [fScanController SetHandle: fHandle]; [fPictureController SetHandle: fHandle]; - [fQueueController SetHandle: fHandle]; + [fQueueController setHandle: fHandle]; + [fQueueController setHBController: self]; fChapterTitlesDelegate = [[ChapterTitles alloc] init]; [fChapterTable setDataSource:fChapterTitlesDelegate]; - - /* Call UpdateUI every 2/10 sec */ + + /* Call UpdateUI every 1/2 sec */ [[NSRunLoop currentRunLoop] addTimer: [NSTimer - scheduledTimerWithTimeInterval: 0.2 target: self - selector: @selector( UpdateUI: ) userInfo: NULL repeats: FALSE] - forMode: NSModalPanelRunLoopMode]; - + scheduledTimerWithTimeInterval: 0.5 target: self + selector: @selector( updateUI: ) userInfo: NULL repeats: YES] + forMode: NSEventTrackingRunLoopMode]; + + // Open debug output window now if it was visible when HB was closed + if ([[NSUserDefaults standardUserDefaults] boolForKey:@"OutputPanelIsOpen"]) + [self showDebugOutputPanel:nil]; + + // Open queue window now if it was visible when HB was closed + if ([[NSUserDefaults standardUserDefaults] boolForKey:@"QueueWindowIsOpen"]) + [self showQueueWindow:nil]; + + [self openMainWindow:nil]; + if( ( build = hb_check_update( fHandle, &version ) ) > -1 ) { /* Update available - tell the user */ - + NSBeginInformationalAlertSheet( _( @"Update is available" ), - _( @"Go get it!" ), _( @"Discard" ), NULL, fWindow, self, - @selector( UpdateAlertDone:returnCode:contextInfo: ), - NULL, NULL, [NSString stringWithFormat: - _( @"HandBrake %s (build %d) is now available for download." ), - version, build] ); + _( @"Go get it!" ), _( @"Discard" ), NULL, fWindow, self, + @selector( updateAlertDone:returnCode:contextInfo: ), + NULL, NULL, [NSString stringWithFormat: + _( @"HandBrake %s (build %d) is now available for download." ), + version, build] ); return; - + } + + /* Show Browse Sources Window ASAP */ + [self performSelectorOnMainThread: @selector(browseSources:) + withObject: NULL waitUntilDone: NO]; + } - /* Show scan panel ASAP */ - [self performSelectorOnMainThread: @selector(ShowScanPanel:) - withObject: NULL waitUntilDone: NO]; +- (void) updateAlertDone: (NSWindow *) sheet + returnCode: (int) returnCode contextInfo: (void *) contextInfo +{ + if( returnCode == NSAlertDefaultReturn ) + { + /* Go to HandBrake homepage and exit */ + [self openHomepage: NULL]; + [NSApp terminate: self]; + + } + else + { + /* Show scan panel */ + [self performSelectorOnMainThread: @selector(showScanPanel:) + withObject: NULL waitUntilDone: NO]; + return; + /* Go to HandBrake homepage and exit */ + [self openHomepage: NULL]; + [NSApp terminate: self]; + } } -- (NSApplicationTerminateReply) applicationShouldTerminate: - (NSApplication *) app +- (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication *) app { - if( [[fRipButton title] isEqualToString: _( @"Cancel" )] ) + // Warn if encoding a movie + hb_state_t s; + hb_get_state( fHandle, &s ); + hb_job_t * job = hb_current_job( fHandle ); + if ( job && ( s.state != HB_STATE_IDLE ) ) + { + hb_job_t * job = hb_current_job( fHandle ); + int result = NSRunCriticalAlertPanel( + NSLocalizedString(@"Are you sure you want to quit HandBrake?", nil), + NSLocalizedString(@"%@ is currently encoding. If you quit HandBrake, your movie will be lost. Do you want to quit anyway?", nil), + NSLocalizedString(@"Quit", nil), NSLocalizedString(@"Don't Quit", nil), nil, + job ? [NSString stringWithUTF8String:job->title->name] : @"A movie" ); + + if (result == NSAlertDefaultReturn) + { + [self doCancelCurrentJob]; + return NSTerminateNow; + } + else + return NSTerminateCancel; + } + + // Warn if items still in the queue + else if ( hb_count( fHandle ) > 0 ) { - [self Cancel: NULL]; - return NSTerminateCancel; - } + int result = NSRunCriticalAlertPanel( + NSLocalizedString(@"Are you sure you want to quit HandBrake?", nil), + NSLocalizedString(@"One or more encodes are queued for encoding. Do you want to quit anyway?", nil), + NSLocalizedString(@"Quit", nil), NSLocalizedString(@"Don't Quit", nil), nil); + + if ( result == NSAlertDefaultReturn ) + return NSTerminateNow; + else + return NSTerminateCancel; + } + return NSTerminateNow; } - (void)applicationWillTerminate:(NSNotification *)aNotification { [outputPanel release]; + [fQueueController release]; hb_close(&fHandle); } @@ -129,78 +213,35 @@ static NSString* ChooseSourceIdentifier = @"Choose Source Item Identifie - (void) awakeFromNib { [fWindow center]; + [fWindow setExcludedFromWindowsMenu:YES]; + [fAdvancedOptions setView:fAdvancedView]; - [self TranslateStrings]; /* Initialize currentScanCount so HB can use it to - evaluate successive scans */ + evaluate successive scans */ currentScanCount = 0; - - /* Init User Presets .plist */ - /* We declare the default NSFileManager into fileManager */ - NSFileManager * fileManager = [NSFileManager defaultManager]; - //presetPrefs = [[NSUserDefaults standardUserDefaults] retain]; - /* we set the files and support paths here */ - AppSupportDirectory = @"~/Library/Application Support/HandBrake"; - AppSupportDirectory = [AppSupportDirectory stringByExpandingTildeInPath]; - - UserPresetsFile = @"~/Library/Application Support/HandBrake/UserPresets.plist"; - UserPresetsFile = [UserPresetsFile stringByExpandingTildeInPath]; - - x264ProfilesFile = @"~/Library/Application Support/HandBrake/x264Profiles.plist"; - x264ProfilesFile = [x264ProfilesFile stringByExpandingTildeInPath]; - /* We check for the app support directory for media fork */ - if ([fileManager fileExistsAtPath:AppSupportDirectory] == 0) - { - // If it doesnt exist yet, we create it here - [fileManager createDirectoryAtPath:AppSupportDirectory attributes:nil]; - } - // We check for the presets.plist here - if ([fileManager fileExistsAtPath:UserPresetsFile] == 0) - { - - [fileManager createFileAtPath:UserPresetsFile contents:nil attributes:nil]; + /* Init UserPresets .plist */ + [self loadPresets]; - } - // We check for the x264profiles.plist here - - if ([fileManager fileExistsAtPath:x264ProfilesFile] == 0) + fRipIndicatorShown = NO; // initially out of view in the nib + + /* Show/Dont Show Presets drawer upon launch based + on user preference DefaultPresetsDrawerShow*/ + if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultPresetsDrawerShow"] > 0) { - - [fileManager createFileAtPath:x264ProfilesFile contents:nil attributes:nil]; + [fPresetDrawer open]; } - - UserPresetsFile = @"~/Library/Application Support/HandBrake/UserPresets.plist"; - UserPresetsFile = [[UserPresetsFile stringByExpandingTildeInPath]retain]; - - UserPresets = [[NSMutableArray alloc] initWithContentsOfFile:UserPresetsFile]; - if (nil == UserPresets) - { - UserPresets = [[NSMutableArray alloc] init]; - [self AddFactoryPresets:NULL]; - } - - - - /* Show/Dont Show Presets drawer upon launch based - on user preference DefaultPresetsDrawerShow*/ - if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultPresetsDrawerShow"] > 0) - { - [fPresetDrawer open]; - } - - - + /* Destination box*/ [fDstFormatPopUp removeAllItems]; [fDstFormatPopUp addItemWithTitle: _( @"MP4 file" )]; + [fDstFormatPopUp addItemWithTitle: _( @"MKV file" )]; [fDstFormatPopUp addItemWithTitle: _( @"AVI file" )]; [fDstFormatPopUp addItemWithTitle: _( @"OGM file" )]; - [fDstFormatPopUp addItemWithTitle: _( @"MKV file" )]; [fDstFormatPopUp selectItemAtIndex: 0]; - - [self FormatPopUpChanged: NULL]; + + [self formatPopUpChanged: NULL]; /* We enable the create chapters checkbox here since we are .mp4 */ [fCreateChapterMarkers setEnabled: YES]; @@ -209,51 +250,72 @@ static NSString* ChooseSourceIdentifier = @"Choose Source Item Identifie [fCreateChapterMarkers setState: NSOnState]; } - + [fDstFile2Field setStringValue: [NSString stringWithFormat: @"%@/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: NULL]; - + [self videoMatrixChanged: NULL]; + /* Video framerate */ [fVidRatePopUp removeAllItems]; [fVidRatePopUp addItemWithTitle: _( @"Same as source" )]; for( int i = 0; i < hb_video_rates_count; i++ ) { - [fVidRatePopUp addItemWithTitle: - [NSString stringWithCString: hb_video_rates[i].string]]; + 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)"]]; + } + 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)"]]; + } + 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)"]]; + } + else + { + [fVidRatePopUp addItemWithTitle: + [NSString stringWithCString: hb_video_rates[i].string]]; + } } [fVidRatePopUp selectItemAtIndex: 0]; /* Picture Settings */ - [fPicLabelPAROutp setStringValue: @""]; [fPicLabelPAROutputX setStringValue: @""]; [fPicSettingPARWidth setStringValue: @""]; [fPicSettingPARHeight setStringValue: @""]; - /* Audio bitrate */ + /* Set Auto Crop to On at launch */ + [fPictureController setAutoCrop:YES]; + + /* Audio bitrate */ [fAudBitratePopUp removeAllItems]; for( int i = 0; i < hb_audio_bitrates_count; i++ ) { [fAudBitratePopUp addItemWithTitle: - [NSString stringWithCString: hb_audio_bitrates[i].string]]; + [NSString stringWithCString: hb_audio_bitrates[i].string]]; + } [fAudBitratePopUp selectItemAtIndex: hb_audio_bitrates_default]; - + /* Audio samplerate */ [fAudRatePopUp removeAllItems]; for( int i = 0; i < hb_audio_rates_count; i++ ) @@ -262,278 +324,35 @@ static NSString* ChooseSourceIdentifier = @"Choose Source Item Identifie [NSString stringWithCString: hb_audio_rates[i].string]]; } [fAudRatePopUp selectItemAtIndex: hb_audio_rates_default]; - + /* Bottom */ [fStatusField setStringValue: @""]; - - [self EnableUI: NO]; - //[fPauseButton setEnabled: NO]; - //[fRipButton setEnabled: NO]; - /* Use new Toolbar start and pause here */ - - pauseButtonEnabled = NO; - startButtonEnabled = NO; - [self setupToolbar]; - /* In Ritsuka's patch, this goes below the Turbo stuff below - Lets try to keep it all together */ - startButtonEnabled = NO; - stopOrStart = NO; - AddToQueueButtonEnabled = NO; - pauseButtonEnabled = NO; - resumeOrPause = NO; - + + [self enableUI: NO]; + [self setupToolbar]; + + [fPresetsActionButton setMenu:fPresetsActionMenu]; + /* 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: NULL]; - /* lets initialize the current successful scancount here to 0 */ - currentSuccessfulScanCount = 0; - -} - - -// ============================================================ -// NSToolbar Related Methods -// ============================================================ - -- (void) setupToolbar { - // Create a new toolbar instance, and attach it to our document window - NSToolbar *toolbar = [[[NSToolbar alloc] initWithIdentifier: MyDocToolbarIdentifier] autorelease]; - - // Set up toolbar properties: Allow customization, give a default display mode, and remember state in user defaults - [toolbar setAllowsUserCustomization: YES]; - [toolbar setAutosavesConfiguration: YES]; - [toolbar setDisplayMode: NSToolbarDisplayModeIconAndLabel]; - - // We are the delegate - [toolbar setDelegate: self]; - - // Attach the toolbar to the document window - [fWindow setToolbar: toolbar]; -} - -- (NSToolbarItem *) toolbar: (NSToolbar *)toolbar itemForItemIdentifier: (NSString *) itemIdent willBeInsertedIntoToolbar:(BOOL) willBeInserted { - // Required delegate method: Given an item identifier, this method returns an item - // The toolbar will use this method to obtain toolbar items that can be displayed in the customization sheet, or in the toolbar itself - NSToolbarItem *toolbarItem = nil; - - if ([itemIdent isEqual: ToggleDrawerIdentifier]) { - toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdent] autorelease]; - - // Set the text label to be displayed in the toolbar and customization palette - [toolbarItem setLabel: @"Toggle Presets"]; - [toolbarItem setPaletteLabel: @"Toggler Presets"]; - - // Set up a reasonable tooltip, and image Note, these aren't localized, but you will likely want to localize many of the item's properties - [toolbarItem setToolTip: @"Open/Close Preset Drawer"]; - [toolbarItem setImage: [NSImage imageNamed: @"Drawer-List2"]]; - - // Tell the item what message to send when it is clicked - [toolbarItem setTarget: self]; - [toolbarItem setAction: @selector(toggleDrawer)]; - - } else if ([itemIdent isEqual: StartEncodingIdentifier]) { - toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdent] autorelease]; - - // Set the text label to be displayed in the toolbar and customization palette - [toolbarItem setLabel: @"Start"]; - [toolbarItem setPaletteLabel: @"Start Encoding"]; - - // Set up a reasonable tooltip, and image Note, these aren't localized, but you will likely want to localize many of the item's properties - [toolbarItem setToolTip: @"Start Encoding"]; - [toolbarItem setImage: [NSImage imageNamed: @"Play"]]; - - // Tell the item what message to send when it is clicked - [toolbarItem setTarget: self]; - [toolbarItem setAction: @selector(Rip:)]; - - - - } else if ([itemIdent isEqual: ShowQueueIdentifier]) { - toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdent] autorelease]; - - // Set the text label to be displayed in the toolbar and customization palette - [toolbarItem setLabel: @"Show Queue"]; - [toolbarItem setPaletteLabel: @"Show Queue"]; - - // Set up a reasonable tooltip, and image Note, these aren't localized, but you will likely want to localize many of the item's properties - [toolbarItem setToolTip: @"Show Queue"]; - [toolbarItem setImage: [NSImage imageNamed: @"Brushed Window"]]; - - // Tell the item what message to send when it is clicked - [toolbarItem setTarget: self]; - [toolbarItem setAction: @selector(ShowQueuePanel:)]; - - } else if ([itemIdent isEqual: AddToQueueIdentifier]) { - toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdent] autorelease]; - - // Set the text label to be displayed in the toolbar and customization palette - [toolbarItem setLabel: @"Add to Queue"]; - [toolbarItem setPaletteLabel: @"Add to Queue"]; - - // Set up a reasonable tooltip, and image Note, these aren't localized, but you will likely want to localize many of the item's properties - [toolbarItem setToolTip: @"Add to Queue"]; - [toolbarItem setImage: [NSImage imageNamed: @"Add"]]; - - // Tell the item what message to send when it is clicked - [toolbarItem setTarget: self]; - [toolbarItem setAction: @selector(AddToQueue:)]; - - - } else if ([itemIdent isEqual: PauseEncodingIdentifier]) { - toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdent] autorelease]; - - // Set the text label to be displayed in the toolbar and customization palette - [toolbarItem setLabel: @"Pause"]; - [toolbarItem setPaletteLabel: @"Pause Encoding"]; - - // Set up a reasonable tooltip, and image Note, these aren't localized, but you will likely want to localize many of the item's properties - [toolbarItem setToolTip: @"Pause Encoding"]; - [toolbarItem setImage: [NSImage imageNamed: @"Pause"]]; - - // Tell the item what message to send when it is clicked - [toolbarItem setTarget: self]; - [toolbarItem setAction: @selector(Pause:)]; - - } else if ([itemIdent isEqual: DebugOutputIdentifier]) { - toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdent] autorelease]; - - // Set the text label to be displayed in the toolbar and customization palette - [toolbarItem setLabel: @"Activity Window"]; - [toolbarItem setPaletteLabel: @"Show Activity Window"]; - - // Set up a reasonable tooltip, and image Note, these aren't localized, but you will likely want to localize many of the item's properties - [toolbarItem setToolTip: @"Show Activity Window"]; - [toolbarItem setImage: [NSImage imageNamed: @"Terminal"]]; - - // Tell the item what message to send when it is clicked - [toolbarItem setTarget: self]; - [toolbarItem setAction: @selector(showDebugOutputPanel:)]; - - } else if ([itemIdent isEqual: ChooseSourceIdentifier]) { - toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdent] autorelease]; - - // Set the text label to be displayed in the toolbar and customization palette - [toolbarItem setLabel: @"Source"]; - [toolbarItem setPaletteLabel: @"Source"]; - - // Set up a reasonable tooltip, and image Note, these aren't localized, but you will likely want to localize many of the item's properties - [toolbarItem setToolTip: @"Choose Video Source"]; - [toolbarItem setImage: [NSImage imageNamed: @"Disc"]]; - - // Tell the item what message to send when it is clicked - [toolbarItem setTarget: self]; - [toolbarItem setAction: @selector(ShowScanPanel:)]; - - } else { - //itemIdent refered to a toolbar item that is not provide or supported by us or cocoa - //Returning nil will inform the toolbar this kind of item is not supported - toolbarItem = nil; - } - return toolbarItem; -} - -- (void) toggleDrawer { - [fPresetDrawer toggle:self]; -} - -- (NSArray *) toolbarDefaultItemIdentifiers: (NSToolbar *) toolbar { - // Required delegate method: Returns the ordered list of items to be shown in the toolbar by default - // If during the toolbar's initialization, no overriding values are found in the user defaults, or if the - // user chooses to revert to the default items this set will be used - return [NSArray arrayWithObjects: ChooseSourceIdentifier, NSToolbarSeparatorItemIdentifier, StartEncodingIdentifier, PauseEncodingIdentifier, - AddToQueueIdentifier, ShowQueueIdentifier, - NSToolbarFlexibleSpaceItemIdentifier, - NSToolbarSpaceItemIdentifier, DebugOutputIdentifier, ToggleDrawerIdentifier, nil]; -} - -- (NSArray *) toolbarAllowedItemIdentifiers: (NSToolbar *) toolbar { - // Required delegate method: Returns the list of all allowed items by identifier. By default, the toolbar - // does not assume any items are allowed, even the separator. So, every allowed item must be explicitly listed - // The set of allowed items is used to construct the customization palette - return [NSArray arrayWithObjects: StartEncodingIdentifier, PauseEncodingIdentifier, AddToQueueIdentifier, ShowQueueIdentifier, - DebugOutputIdentifier, NSToolbarCustomizeToolbarItemIdentifier, - NSToolbarFlexibleSpaceItemIdentifier, NSToolbarSpaceItemIdentifier, NSToolbarSpaceItemIdentifier, ChooseSourceIdentifier, - NSToolbarSeparatorItemIdentifier,ToggleDrawerIdentifier, nil]; -} - -- (BOOL) validateToolbarItem: (NSToolbarItem *) toolbarItem { - // Optional method: This message is sent to us since we are the target of some toolbar item actions - BOOL enable = NO; - if ([[toolbarItem itemIdentifier] isEqual: ToggleDrawerIdentifier]) { - enable = YES; - } - if ([[toolbarItem itemIdentifier] isEqual: StartEncodingIdentifier]) { - enable = startButtonEnabled; - if(stopOrStart) { - [toolbarItem setImage: [NSImage imageNamed: @"Stop"]]; - [toolbarItem setLabel: @"Cancel"]; - [toolbarItem setPaletteLabel: @"Cancel"]; - [toolbarItem setToolTip: @"Cancel Encoding"]; - } - else { - [toolbarItem setImage: [NSImage imageNamed: @"Play"]]; - [toolbarItem setLabel: @"Start"]; - [toolbarItem setPaletteLabel: @"Start Encoding"]; - [toolbarItem setToolTip: @"Start Encoding"]; - } - - } - if ([[toolbarItem itemIdentifier] isEqual: PauseEncodingIdentifier]) { - enable = pauseButtonEnabled; - if(resumeOrPause) { - [toolbarItem setImage: [NSImage imageNamed: @"Play"]]; - [toolbarItem setLabel: @"Resume"]; - [toolbarItem setPaletteLabel: @"Resume Encoding"]; - [toolbarItem setToolTip: @"Resume Encoding"]; - } - else { - [toolbarItem setImage: [NSImage imageNamed: @"Pause"]]; - [toolbarItem setLabel: @"Pause"]; - [toolbarItem setPaletteLabel: @"Pause Encoding"]; - [toolbarItem setToolTip: @"Pause Encoding"]; - } - } - if ([[toolbarItem itemIdentifier] isEqual: DebugOutputIdentifier]) { - enable = YES; - } - if ([[toolbarItem itemIdentifier] isEqual: ShowQueueIdentifier]) { - enable = YES; - } - if ([[toolbarItem itemIdentifier] isEqual: AddToQueueIdentifier]) { - enable = AddToQueueButtonEnabled; - } - if ([[toolbarItem itemIdentifier] isEqual: ChooseSourceIdentifier]) { - enable = YES; - } - return enable; + + /* lets get our default prefs here */ + [self getDefaultPresets: NULL]; + /* lets initialize the current successful scancount here to 0 */ + currentSuccessfulScanCount = 0; + } -// register a test notification and make -// it enabled by default -#define SERVICE_NAME @"Encode Done" -- (NSDictionary *)registrationDictionaryForGrowl -{ -NSDictionary *registrationDictionary = [NSDictionary dictionaryWithObjectsAndKeys: -[NSArray arrayWithObjects:SERVICE_NAME,nil], GROWL_NOTIFICATIONS_ALL, -[NSArray arrayWithObjects:SERVICE_NAME,nil], GROWL_NOTIFICATIONS_DEFAULT, -nil]; - -return registrationDictionary; -} - (void) TranslateStrings { - [fSrcDVD1Field setStringValue: _( @"DVD:" )]; [fSrcTitleField setStringValue: _( @"Title:" )]; [fSrcChapterField setStringValue: _( @"Chapters:" )]; [fSrcChapterToField setStringValue: _( @"to" )]; [fSrcDuration1Field setStringValue: _( @"Duration:" )]; - [fDstFormatField setStringValue: _( @"File format:" )]; + [fDstFormatField setStringValue: _( @"Format:" )]; [fDstCodecsField setStringValue: _( @"Codecs:" )]; [fDstFile1Field setStringValue: _( @"File:" )]; [fDstBrowseButton setTitle: _( @"Browse" )]; @@ -543,36 +362,95 @@ return registrationDictionary; [fVidQualityField setStringValue: _( @"Quality:" )]; } -/*********************************************************************** - * UpdateDockIcon - *********************************************************************** - * Shows a progression bar on the dock icon, filled according to - * 'progress' (0.0 <= progress <= 1.0). - * Called with progress < 0.0 or progress > 1.0, restores the original - * icon. - **********************************************************************/ -- (void) UpdateDockIcon: (float) progress -{ - NSImage * icon; - NSData * tiff; - NSBitmapImageRep * bmp; - uint32_t * pen; - uint32_t black = htonl( 0x000000FF ); - uint32_t red = htonl( 0xFF0000FF ); - uint32_t white = htonl( 0xFFFFFFFF ); - int row_start, row_end; - int i, j; - /* Get application original icon */ - icon = [NSImage imageNamed: @"NSApplicationIcon"]; +- (void) enableUI: (bool) b +{ + NSControl * controls[] = + { fSrcTitleField, fSrcTitlePopUp, + fSrcChapterField, fSrcChapterStartPopUp, fSrcChapterToField, + fSrcChapterEndPopUp, fSrcDuration1Field, fSrcDuration2Field, + fDstFormatField, fDstFormatPopUp, fDstCodecsField, + fDstCodecsPopUp, fDstFile1Field, fDstFile2Field, + fDstBrowseButton, fVidRateField, fVidRatePopUp, + fVidEncoderField, fVidEncoderPopUp, fVidQualityField, + fVidQualityMatrix, fVidGrayscaleCheck, fSubField, fSubPopUp, + fAudLang1Field, fAudLang1PopUp, fAudLang2Field, fAudLang2PopUp, + fAudTrack1MixLabel, fAudTrack1MixPopUp, fAudTrack2MixLabel, fAudTrack2MixPopUp, + fAudRateField, fAudRatePopUp, fAudBitrateField, + fAudBitratePopUp, fPictureButton,fQueueStatus, + fPicSrcWidth,fPicSrcHeight,fPicSettingWidth,fPicSettingHeight,fPicSettingARkeep, + fPicSettingDeinterlace,fPicLabelSettings,fPicLabelSrc,fPicLabelOutp, + fPicLabelAr,fPicLabelDeinterlace,fPicLabelSrcX,fPicLabelOutputX, + fPicLabelPAROutputX,fPicSettingPARWidth,fPicSettingPARHeight, + fPicSettingPAR,fPicLabelAnamorphic,tableView,fPresetsAdd,fPresetsDelete, + fCreateChapterMarkers,fVidTurboPassCheck,fDstMpgLargeFileCheck,fPicLabelAutoCrop, + fPicSettingAutoCrop,fPicSettingDetelecine,fPicLabelDetelecine,fPicLabelDenoise,fPicSettingDenoise, + fSubForcedCheck,fPicSettingDeblock,fPicLabelDeblock,}; - if( progress < 0.0 || progress > 1.0 ) + for( unsigned i = 0; + i < sizeof( controls ) / sizeof( NSControl * ); i++ ) { - [NSApp setApplicationIconImage: icon]; - return; - } - - /* Get it in a raw bitmap form */ + if( [[controls[i] className] isEqualToString: @"NSTextField"] ) + { + NSTextField * tf = (NSTextField *) controls[i]; + if( ![tf isBezeled] ) + { + [tf setTextColor: b ? [NSColor controlTextColor] : + [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: NULL]; + + } else { + + [tableView setEnabled: NO]; + + } + + [self videoMatrixChanged: NULL]; + [fAdvancedOptions enableUI:b]; +} + + +/*********************************************************************** + * UpdateDockIcon + *********************************************************************** + * Shows a progression bar on the dock icon, filled according to + * 'progress' (0.0 <= progress <= 1.0). + * Called with progress < 0.0 or progress > 1.0, restores the original + * icon. + **********************************************************************/ +- (void) UpdateDockIcon: (float) progress +{ + NSImage * icon; + NSData * tiff; + NSBitmapImageRep * bmp; + uint32_t * pen; + uint32_t black = htonl( 0x000000FF ); + uint32_t red = htonl( 0xFF0000FF ); + uint32_t white = htonl( 0xFFFFFFFF ); + 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]; + return; + } + + /* Get it in a raw bitmap form */ tiff = [icon TIFFRepresentationUsingCompression: NSTIFFCompressionNone factor: 1.0]; bmp = [NSBitmapImageRep imageRepWithData: tiff]; @@ -627,31 +505,27 @@ return registrationDictionary; [icon release]; } -- (void) UpdateUI: (NSTimer *) timer +- (void) updateUI: (NSTimer *) timer { -hb_list_t * list; -list = hb_get_titles( fHandle ); + hb_list_t * list; + list = hb_get_titles( fHandle ); /* check to see if there has been a new scan done this bypasses the constraints of HB_STATE_WORKING not allowing setting a newly scanned source */ int checkScanCount = hb_get_scancount( fHandle ); if (checkScanCount > currentScanCount) { - + currentScanCount = checkScanCount; - [fScanController Cancel: NULL]; - [fScanIndicator setIndeterminate: NO]; - [fScanIndicator setDoubleValue: 0.0]; - [fScanIndicator setHidden: YES]; - [fScanController Cancel: NULL]; - [self ShowNewScan: NULL]; + //[fScanController Cancel: NULL]; + [fScanIndicator setIndeterminate: NO]; + [fScanIndicator setDoubleValue: 0.0]; + [fScanIndicator setHidden: YES]; + [self showNewScan: NULL]; } - - - hb_state_t s; hb_get_state( fHandle, &s ); @@ -659,7 +533,7 @@ list = hb_get_titles( fHandle ); switch( s.state ) { case HB_STATE_IDLE: - break; + break; #define p s.param.scanning case HB_STATE_SCANNING: { @@ -680,8 +554,8 @@ list = hb_get_titles( fHandle ); [fScanIndicator setIndeterminate: NO]; [fScanIndicator setDoubleValue: 0.0]; [fScanIndicator setHidden: YES]; - [fScanController Cancel: NULL]; - [self ShowNewScan: NULL]; + [self showNewScan: NULL]; + [toolbar validateVisibleItems]; break; } #undef p @@ -710,15 +584,31 @@ list = hb_get_titles( fHandle ); [fRipIndicator setIndeterminate: NO]; [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 + // the case where hb_start is called by HBQueueController and not from + // HBController. + if (!fRipIndicatorShown) + { + NSRect frame = [fWindow frame]; + if (frame.size.width <= 591) + frame.size.width = 591; + frame.size.height += 36; + frame.origin.y -= 36; + [fWindow setFrame:frame display:YES animate:YES]; + fRipIndicatorShown = YES; + /* We check to see if we need to warn the user that the computer will go to sleep + or shut down when encoding is finished */ + [self remindUserOfSleepOrShutdown]; + } + /* Update dock icon */ [self UpdateDockIcon: progress_total]; - /* new toolbar controls */ - pauseButtonEnabled = YES; - resumeOrPause = NO; - startButtonEnabled = YES; - stopOrStart = YES; - + // Has current job changed? That means the queue has probably changed as + // well so update it + [fQueueController hblibStateChanged: s]; + break; } #undef p @@ -740,59 +630,66 @@ list = hb_get_titles( fHandle ); /* Update dock icon */ [self UpdateDockIcon: 1.0]; - //[fPauseButton setEnabled: YES]; - //[fPauseButton setTitle: _( @"Pause" )]; - //[fRipButton setEnabled: YES]; - // [fRipButton setTitle: _( @"Cancel" )]; + // Pass along the info to HBQueueController + [fQueueController hblibStateChanged: s]; + break; } #undef p case HB_STATE_PAUSED: - //[fStatusField setStringValue: _( @"Paused" )]; - //[fPauseButton setEnabled: YES]; - //[fPauseButton setTitle: _( @"Resume" )]; - //[fRipButton setEnabled: YES]; - //[fRipButton setTitle: _( @"Cancel" )]; - /* new toolbar controls */ - pauseButtonEnabled = YES; - resumeOrPause = YES; - startButtonEnabled = YES; - stopOrStart = YES; + [fStatusField setStringValue: _( @"Paused" )]; + + // Pass along the info to HBQueueController + [fQueueController hblibStateChanged: s]; + break; case HB_STATE_WORKDONE: { + // HB_STATE_WORKDONE happpens as a result of hblib finishing all its jobs + // or someone calling hb_stop. In the latter case, hb_stop does not clear + // out the remaining passes/jobs in the queue. We'll do that here. + + // Delete all remaining scans of this job, ie, delete whole encodes. + hb_job_t * job; + while( ( job = hb_job( fHandle, 0 ) ) && (job->sequence_id != 0) ) + hb_rem( fHandle, job ); + + // Start processing back up if jobs still left in queue + if (hb_count(fHandle) > 0) + { + hb_start(fHandle); + fEncodeState = 1; + // Validate the toolbar (hack). The toolbar will usually get autovalidated + // before we had the chance to restart the queue, hence it will now be in + // the wrong state. + [toolbar validateVisibleItems]; + break; + } + [fStatusField setStringValue: _( @"Done." )]; [fRipIndicator setIndeterminate: NO]; [fRipIndicator setDoubleValue: 0.0]; - //[fRipButton setTitle: _( @"Start" )]; - + [toolbar validateVisibleItems]; + /* Restore dock icon */ [self UpdateDockIcon: -1.0]; + + if (fRipIndicatorShown) + { + NSRect frame = [fWindow frame]; + if (frame.size.width <= 591) + frame.size.width = 591; + frame.size.height += -36; + frame.origin.y -= -36; + [fWindow setFrame:frame display:YES animate:YES]; + fRipIndicatorShown = NO; + } - //[fPauseButton setEnabled: NO]; - //[fPauseButton setTitle: _( @"Pause" )]; - // [fRipButton setEnabled: YES]; - // [fRipButton setTitle: _( @"Start" )]; - /* new toolbar controls */ - pauseButtonEnabled = NO; - resumeOrPause = NO; - startButtonEnabled = YES; - stopOrStart = NO; - NSRect frame = [fWindow frame]; - if (frame.size.width <= 591) - frame.size.width = 591; - frame.size.height += -44; - frame.origin.y -= -44; - [fWindow setFrame:frame display:YES animate:YES]; + // Pass along the info to HBQueueController + [fQueueController hblibStateChanged: s]; - /* FIXME */ - hb_job_t * job; - while( ( job = hb_job( fHandle, 0 ) ) ) - { - hb_rem( fHandle, job ); - } /* Check to see if the encode state has not been cancelled to determine if we should check for encode done notifications */ if (fEncodeState != 2) { @@ -810,16 +707,16 @@ list = hb_get_titles( fHandle ); /*On Screen Notification*/ int status; NSBeep(); - status = NSRunAlertPanel(@"Put down that cocktail...",@"your HandBrake encode is done!", @"OK", nil, nil); + status = NSRunAlertPanel(@"Put down that cocktail...",@"Your HandBrake encode is done!", @"OK", nil, nil); [NSApp requestUserAttention:NSCriticalRequest]; if ( status == NSAlertDefaultReturn ) { - [self EnableUI: YES]; + [self enableUI: YES]; } } else { - [self EnableUI: YES]; + [self enableUI: YES]; } /* If sleep has been selected */ if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Put Computer To Sleep"]) @@ -831,7 +728,7 @@ list = hb_get_titles( fHandle ); @"tell application \"Finder\" to sleep"]; returnDescriptor = [scriptObject executeAndReturnError: &errorDict]; [scriptObject release]; - [self EnableUI: YES]; + [self enableUI: YES]; } /* If Shutdown has been selected */ if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Shut Down Computer"]) @@ -843,390 +740,621 @@ list = hb_get_titles( fHandle ); @"tell application \"Finder\" to shut down"]; returnDescriptor = [scriptObject executeAndReturnError: &errorDict]; [scriptObject release]; - [self EnableUI: YES]; + [self enableUI: YES]; } + // MetaX insertion via AppleScript + if([[NSUserDefaults standardUserDefaults] boolForKey: @"sendToMetaX"] == YES) + { + NSAppleScript *myScript = [[NSAppleScript alloc] initWithSource: [NSString stringWithFormat: @"%@%@%@", @"tell application \"MetaX\" to open (POSIX file \"", [fDstFile2Field stringValue], @"\")"]]; + [myScript executeAndReturnError: nil]; + [myScript release]; + } + + } else { - [self EnableUI: YES]; + [self enableUI: YES]; } break; } } - /* Lets show the queue status - here in the main window*/ + /* Lets show the queue status here in the main window */ int queue_count = hb_count( fHandle ); if( queue_count ) { [fQueueStatus setStringValue: [NSString stringWithFormat: - @"%d task%s in the queue", - queue_count, ( queue_count > 1 ) ? "s" : ""]]; + @"%d pass%s in the queue", + queue_count, ( queue_count > 1 ) ? "es" : ""]]; } else { [fQueueStatus setStringValue: @""]; } - - [[NSRunLoop currentRunLoop] addTimer: [NSTimer - scheduledTimerWithTimeInterval: 0.5 target: self - selector: @selector( UpdateUI: ) userInfo: NULL repeats: FALSE] - forMode: NSModalPanelRunLoopMode]; -} -- (IBAction) ShowNewScan:(id)sender -{ - hb_list_t * list; - hb_title_t * title; - int indxpri=0; // Used to search the longuest title (default in combobox) - int longuestpri=0; // Used to search the longuest title (default in combobox) - - list = hb_get_titles( fHandle ); - - if( !hb_list_count( list ) ) - { - /* We display a message if a valid dvd source was not chosen */ - if (sourceDisplayName) - { - /* Temporary string if til restoring old source is fixed */ - [fSrcDVD2Field setStringValue: @"Not A Valid Source"]; - //[fSrcDVD2Field setStringValue: [NSString stringWithFormat: @"%s", sourceDisplayName]]; - } - else - { - [fSrcDVD2Field setStringValue: @"No Valid Title Found"]; - } - } - else - { - /* We increment the successful scancount here by one, - which we use at the end of this function to tell the gui - if this is the first successful scan since launch and whether - or not we should set all settings to the defaults */ - currentSuccessfulScanCount++; - - [fSrcTitlePopUp removeAllItems]; - for( int i = 0; i < hb_list_count( list ); i++ ) - { - title = (hb_title_t *) hb_list_item( list, i ); - /*Set DVD Name at top of window*/ - [fSrcDVD2Field setStringValue:[NSString stringWithUTF8String: title->name]]; - - currentSource = [NSString stringWithUTF8String: title->dvd]; - - - /* Use the dvd name in the default output field here - May want to add code to remove blank spaces for some dvd names*/ - /* Check to see if the last destination has been set,use if so, if not, use Desktop */ - if ([[NSUserDefaults standardUserDefaults] stringForKey:@"LastDestinationDirectory"]) - { - [fDstFile2Field setStringValue: [NSString stringWithFormat: - @"%@/%@.mp4", [[NSUserDefaults standardUserDefaults] stringForKey:@"LastDestinationDirectory"],[NSString - stringWithUTF8String: title->name]]]; - } - else - { - [fDstFile2Field setStringValue: [NSString stringWithFormat: - @"%@/Desktop/%@.mp4", NSHomeDirectory(),[NSString - stringWithUTF8String: title->name]]]; - } - - - if (longuestpri < title->hours*60*60 + title->minutes *60 + title->seconds) - { - longuestpri=title->hours*60*60 + title->minutes *60 + title->seconds; - indxpri=i; - } - - - int format = [fDstFormatPopUp indexOfSelectedItem]; - char * ext = NULL; - switch( format ) - { - case 0: - - /*Get Default MP4 File Extension for mpeg4 (.mp4 or .m4v) from prefs*/ - if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultMpegName"] > 0) - { - ext = "m4v"; - } - else - { - ext = "mp4"; - } - break; - case 1: - ext = "avi"; - break; - case 2: - ext = "ogm"; - break; - } - - - NSString * string = [fDstFile2Field stringValue]; - /* Add/replace File Output name to the correct extension*/ - if( [string characterAtIndex: [string length] - 4] == '.' ) - { - [fDstFile2Field setStringValue: [NSString stringWithFormat: - @"%@.%s", [string substringToIndex: [string length] - 4], - ext]]; - } - else - { - [fDstFile2Field setStringValue: [NSString stringWithFormat: - @"%@.%s", string, ext]]; - } - - - [fSrcTitlePopUp addItemWithTitle: [NSString - stringWithFormat: @"%d - %02dh%02dm%02ds", - title->index, title->hours, title->minutes, - title->seconds]]; - - } - // Select the longuest title - [fSrcTitlePopUp selectItemAtIndex: indxpri]; - /* We set the Settings Display to "Default" here - until we get default presets implemented */ - [fPresetSelectedDisplay setStringValue: @"Default"]; - /* We set the auto crop in the main window to value "1" just as in PictureController, - as it does not seem to be taken from any job-> variable */ - [fPicSettingAutoCrop setStringValue: [NSString stringWithFormat: - @"%d", 0]]; - - [self TitlePopUpChanged: NULL]; - [self EnableUI: YES]; - - startButtonEnabled = YES; - stopOrStart = NO; - AddToQueueButtonEnabled = YES; - pauseButtonEnabled = NO; - resumeOrPause = NO; - /* we record the current source name here in case the next scan is unsuccessful, - then we can replace the scan progress with the old name if necessary */ - sourceDisplayName = [NSString stringWithFormat:[fSrcDVD2Field stringValue]]; - - - /* if its the initial successful scan after awakeFromNib */ - if (currentSuccessfulScanCount == 1) - { - [self SelectDefaultPreset: NULL]; - } - } } --(IBAction)showGrowlDoneNotification:(id)sender -{ +#pragma mark - +#pragma mark Toolbar +// ============================================================ +// NSToolbar Related Methods +// ============================================================ - - [GrowlApplicationBridge - notifyWithTitle:@"Put down that cocktail..." - description:@"your HandBrake encode is done!" - notificationName:SERVICE_NAME - iconData:nil - priority:0 - isSticky:1 - clickContext:nil]; +- (void) setupToolbar { + toolbar = [[[NSToolbar alloc] initWithIdentifier: @"HandBrake Toolbar"] autorelease]; + + [toolbar setAllowsUserCustomization: YES]; + [toolbar setAutosavesConfiguration: YES]; + [toolbar setDisplayMode: NSToolbarDisplayModeIconAndLabel]; + + [toolbar setDelegate: self]; + + [fWindow setToolbar: toolbar]; } -- (void) EnableUI: (bool) b -{ - NSControl * controls[] = - { fSrcDVD1Field, fSrcTitleField, fSrcTitlePopUp, - fSrcChapterField, fSrcChapterStartPopUp, fSrcChapterToField, - fSrcChapterEndPopUp, fSrcDuration1Field, fSrcDuration2Field, - fDstFormatField, fDstFormatPopUp, fDstCodecsField, - fDstCodecsPopUp, fDstFile1Field, fDstFile2Field, - fDstBrowseButton, fVidRateField, fVidRatePopUp, - fVidEncoderField, fVidEncoderPopUp, fVidQualityField, - fVidQualityMatrix, fVidGrayscaleCheck, fSubField, fSubPopUp, - fAudLang1Field, fAudLang1PopUp, fAudLang2Field, fAudLang2PopUp, - fAudTrack1MixLabel, fAudTrack1MixPopUp, fAudTrack2MixLabel, fAudTrack2MixPopUp, - fAudRateField, fAudRatePopUp, fAudBitrateField, - fAudBitratePopUp, fPictureButton,fQueueStatus, - fPicSrcWidth,fPicSrcHeight,fPicSettingWidth,fPicSettingHeight, - fPicSettingARkeep,fPicSettingDeinterlace,fPicSettingARkeepDsply, - fPicSettingDeinterlaceDsply,fPicLabelSettings,fPicLabelSrc,fPicLabelOutp, - fPicLabelAr,fPicLabelDeinter,fPicLabelSrcX,fPicLabelOutputX, - fPicLabelPAROutp,fPicLabelPAROutputX,fPicSettingPARWidth,fPicSettingPARHeight, - fPicSettingPARDsply,fPicLabelAnamorphic,tableView,fPresetsAdd,fPresetsDelete, - fCreateChapterMarkers,fX264optViewTitleLabel,fDisplayX264Options,fDisplayX264OptionsLabel,fX264optBframesLabel, - fX264optBframesPopUp,fX264optRefLabel,fX264optRefPopUp,fX264optNfpskipLabel,fX264optNfpskipSwitch, - fX264optNodctdcmtLabel,fX264optNodctdcmtSwitch,fX264optSubmeLabel,fX264optSubmePopUp, - fX264optTrellisLabel,fX264optTrellisPopUp,fX264optMixedRefsLabel,fX264optMixedRefsSwitch, - fX264optMotionEstLabel,fX264optMotionEstPopUp,fX264optMERangeLabel,fX264optMERangePopUp, - fX264optWeightBLabel,fX264optWeightBSwitch,fX264optBRDOLabel,fX264optBRDOSwitch, - fX264optBPyramidLabel,fX264optBPyramidSwitch,fX264optBiMELabel,fX264optBiMESwitch, - fX264optDirectPredLabel,fX264optDirectPredPopUp,fX264optDeblockLabel,fX264optAnalyseLabel, - fX264optAnalysePopUp,fX264opt8x8dctLabel,fX264opt8x8dctSwitch,fX264optCabacLabel,fX264optCabacSwitch, - fX264optAlphaDeblockPopUp,fX264optBetaDeblockPopUp,fVidTurboPassCheck,fDstMpgLargeFileCheck,fPicSettingAutoCropLabel, - fPicSettingAutoCropDsply}; - for( unsigned i = 0; - i < sizeof( controls ) / sizeof( NSControl * ); i++ ) +- (NSToolbarItem *) toolbar: (NSToolbar *)toolbar itemForItemIdentifier: + (NSString *) itemIdent willBeInsertedIntoToolbar:(BOOL) willBeInserted { + NSToolbarItem * item = [[NSToolbarItem alloc] initWithItemIdentifier: itemIdent]; + + if ([itemIdent isEqualToString: ToggleDrawerIdentifier]) { - if( [[controls[i] className] isEqualToString: @"NSTextField"] ) - { - NSTextField * tf = (NSTextField *) controls[i]; - if( ![tf isBezeled] ) - { - [tf setTextColor: b ? [NSColor controlTextColor] : - [NSColor disabledControlTextColor]]; - continue; - } - } - [controls[i] setEnabled: b]; - + [item setLabel: @"Toggle Presets"]; + [item setPaletteLabel: @"Toggler Presets"]; + [item setToolTip: @"Open/Close Preset Drawer"]; + [item setImage: [NSImage imageNamed: @"Drawer"]]; + [item setTarget: self]; + [item setAction: @selector(toggleDrawer:)]; + [item setAutovalidates: NO]; + } + else if ([itemIdent isEqualToString: StartEncodingIdentifier]) + { + [item setLabel: @"Start"]; + [item setPaletteLabel: @"Start Encoding"]; + [item setToolTip: @"Start Encoding"]; + [item setImage: [NSImage imageNamed: @"Play"]]; + [item setTarget: self]; + [item setAction: @selector(Rip:)]; + } + else if ([itemIdent isEqualToString: ShowQueueIdentifier]) + { + [item setLabel: @"Show Queue"]; + [item setPaletteLabel: @"Show Queue"]; + [item setToolTip: @"Show Queue"]; + [item setImage: [NSImage imageNamed: @"Queue"]]; + [item setTarget: self]; + [item setAction: @selector(showQueueWindow:)]; + [item setAutovalidates: NO]; + } + else if ([itemIdent isEqualToString: AddToQueueIdentifier]) + { + [item setLabel: @"Add to Queue"]; + [item setPaletteLabel: @"Add to Queue"]; + [item setToolTip: @"Add to Queue"]; + [item setImage: [NSImage imageNamed: @"AddToQueue"]]; + [item setTarget: self]; + [item setAction: @selector(addToQueue:)]; + } + else if ([itemIdent isEqualToString: PauseEncodingIdentifier]) + { + [item setLabel: @"Pause"]; + [item setPaletteLabel: @"Pause Encoding"]; + [item setToolTip: @"Pause Encoding"]; + [item setImage: [NSImage imageNamed: @"Pause"]]; + [item setTarget: self]; + [item setAction: @selector(Pause:)]; + } + else if ([itemIdent isEqualToString: ShowActivityIdentifier]) { + [item setLabel: @"Activity Window"]; + [item setPaletteLabel: @"Show Activity Window"]; + [item setToolTip: @"Show Activity Window"]; + [item setImage: [NSImage imageNamed: @"ActivityWindow"]]; + [item setTarget: self]; + [item setAction: @selector(showDebugOutputPanel:)]; + [item setAutovalidates: NO]; + } + else if ([itemIdent isEqualToString: ChooseSourceIdentifier]) + { + [item setLabel: @"Source"]; + [item setPaletteLabel: @"Source"]; + [item setToolTip: @"Choose Video Source"]; + [item setImage: [NSImage imageNamed: @"Source"]]; + [item setTarget: self]; + [item setAction: @selector(browseSources:)]; + } + else + { + [item release]; + return nil; } - - 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: NULL]; - - } else { - - [tableView setEnabled: NO]; - - } - [self VideoMatrixChanged: NULL]; + return item; } -- (IBAction) ShowScanPanel: (id) sender +- (NSArray *) toolbarDefaultItemIdentifiers: (NSToolbar *) toolbar { - [fScanController Show]; + return [NSArray arrayWithObjects: ChooseSourceIdentifier, NSToolbarSeparatorItemIdentifier, StartEncodingIdentifier, + PauseEncodingIdentifier, AddToQueueIdentifier, ShowQueueIdentifier, NSToolbarFlexibleSpaceItemIdentifier, + NSToolbarSpaceItemIdentifier, ShowActivityIdentifier, ToggleDrawerIdentifier, nil]; } -- (IBAction) OpenMainWindow: (id) sender -{ -[fWindow makeKeyAndOrderFront:nil]; -[fWindow setReleasedWhenClosed: YES]; -} -- (BOOL) windowShouldClose: (id) sender +- (NSArray *) toolbarAllowedItemIdentifiers: (NSToolbar *) toolbar { - - /* See if we are currently running */ - hb_state_t s; - hb_get_state( fHandle, &s ); - if ( s.state == HB_STATE_WORKING) - { - /* If we are running, leave in memory when closing main window */ - [fWindow setReleasedWhenClosed: NO]; - return YES; - - } - else - { - /* Stop the application when the user closes the window */ - [NSApp terminate: self]; - return YES; - } - + return [NSArray arrayWithObjects: StartEncodingIdentifier, PauseEncodingIdentifier, AddToQueueIdentifier, + ChooseSourceIdentifier, ShowQueueIdentifier, ShowActivityIdentifier, ToggleDrawerIdentifier, + NSToolbarCustomizeToolbarItemIdentifier, NSToolbarFlexibleSpaceItemIdentifier, + NSToolbarSpaceItemIdentifier, NSToolbarSeparatorItemIdentifier, nil]; } -- (IBAction) VideoMatrixChanged: (id) sender; +- (BOOL) validateToolbarItem: (NSToolbarItem *) toolbarItem { - bool target, bitrate, quality; - - target = bitrate = quality = false; - if( [fVidQualityMatrix isEnabled] ) + NSString * ident = [toolbarItem itemIdentifier]; + + if (fHandle) { - switch( [fVidQualityMatrix selectedRow] ) + hb_state_t s; + hb_get_state2( fHandle, &s ); + + if (s.state == HB_STATE_WORKING || s.state == HB_STATE_MUXING) { - case 0: - target = true; - break; - case 1: - bitrate = true; - break; - case 2: - quality = true; - break; + if ([ident isEqualToString: StartEncodingIdentifier]) + { + [toolbarItem setImage: [NSImage imageNamed: @"Stop"]]; + [toolbarItem setLabel: @"Stop"]; + [toolbarItem setPaletteLabel: @"Stop"]; + [toolbarItem setToolTip: @"Stop Encoding"]; + return YES; + } + if ([ident isEqualToString: PauseEncodingIdentifier]) + { + [toolbarItem setImage: [NSImage imageNamed: @"Pause"]]; + [toolbarItem setLabel: @"Pause"]; + [toolbarItem setPaletteLabel: @"Pause Encoding"]; + [toolbarItem setToolTip: @"Pause Encoding"]; + return YES; + } + if (SuccessfulScan) + if ([ident isEqualToString: AddToQueueIdentifier]) + return YES; + } + else if (s.state == HB_STATE_PAUSED) + { + if ([ident isEqualToString: PauseEncodingIdentifier]) + { + [toolbarItem setImage: [NSImage imageNamed: @"Play"]]; + [toolbarItem setLabel: @"Resume"]; + [toolbarItem setPaletteLabel: @"Resume Encoding"]; + [toolbarItem setToolTip: @"Resume Encoding"]; + return YES; + } + if ([ident isEqualToString: StartEncodingIdentifier]) + return YES; + if ([ident isEqualToString: AddToQueueIdentifier]) + return YES; + } + else if (s.state == HB_STATE_SCANNING) + return NO; + else if (s.state == HB_STATE_WORKDONE || s.state == HB_STATE_SCANDONE || SuccessfulScan) + { + if ([ident isEqualToString: StartEncodingIdentifier]) + { + [toolbarItem setImage: [NSImage imageNamed: @"Play"]]; + if (hb_count(fHandle) > 0) + [toolbarItem setLabel: @"Start Queue"]; + else + [toolbarItem setLabel: @"Start"]; + [toolbarItem setPaletteLabel: @"Start Encoding"]; + [toolbarItem setToolTip: @"Start Encoding"]; + return YES; + } + if ([ident isEqualToString: AddToQueueIdentifier]) + return YES; } + } - [fVidTargetSizeField setEnabled: target]; - [fVidBitrateField setEnabled: bitrate]; - [fVidQualitySlider setEnabled: quality]; - [fVidTwoPassCheck setEnabled: !quality && - [fVidQualityMatrix isEnabled]]; - if( quality ) + + if ([ident isEqualToString: ShowQueueIdentifier]) + return YES; + if ([ident isEqualToString: ToggleDrawerIdentifier]) + return YES; + if ([ident isEqualToString: ChooseSourceIdentifier]) + return YES; + if ([ident isEqualToString: ShowActivityIdentifier]) + return YES; + + return NO; +} + +- (BOOL) validateMenuItem: (NSMenuItem *) menuItem +{ + SEL action = [menuItem action]; + + hb_state_t s; + hb_get_state2( fHandle, &s ); + + if (fHandle) { - [fVidTwoPassCheck setState: NSOffState]; + if (action == @selector(addToQueue:) || action == @selector(showPicturePanel:) || action == @selector(showAddPresetPanel:)) + return SuccessfulScan && [fWindow attachedSheet] == nil; + + if (action == @selector(browseSources:)) + { + if (s.state == HB_STATE_SCANNING) + return NO; + else + return [fWindow attachedSheet] == nil; + } + if (action == @selector(selectDefaultPreset:)) + return [tableView selectedRow] >= 0 && [fWindow attachedSheet] == nil; + if (action == @selector(Pause:)) + { + if (s.state == HB_STATE_WORKING) + { + if(![[menuItem title] isEqualToString:@"Pause Encoding"]) + [menuItem setTitle:@"Pause Encoding"]; + return YES; + } + else if (s.state == HB_STATE_PAUSED) + { + if(![[menuItem title] isEqualToString:@"Resume Encoding"]) + [menuItem setTitle:@"Resume Encoding"]; + return YES; + } + else + return NO; + } + if (action == @selector(Rip:)) + if (s.state == HB_STATE_WORKING || s.state == HB_STATE_MUXING || s.state == HB_STATE_PAUSED) + { + if(![[menuItem title] isEqualToString:@"Stop Encoding"]) + [menuItem setTitle:@"Stop Encoding"]; + return YES; + } + else if (SuccessfulScan) + { + if(![[menuItem title] isEqualToString:@"Start Encoding"]) + [menuItem setTitle:@"Start Encoding"]; + return [fWindow attachedSheet] == nil; + } + else + return NO; + } + + return YES; +} + +#pragma mark - +#pragma mark Growl +// register a test notification and make +// it enabled by default +#define SERVICE_NAME @"Encode Done" +- (NSDictionary *)registrationDictionaryForGrowl +{ + NSDictionary *registrationDictionary = [NSDictionary dictionaryWithObjectsAndKeys: + [NSArray arrayWithObjects:SERVICE_NAME,nil], GROWL_NOTIFICATIONS_ALL, + [NSArray arrayWithObjects:SERVICE_NAME,nil], GROWL_NOTIFICATIONS_DEFAULT, + nil]; + + return registrationDictionary; +} + +-(IBAction)showGrowlDoneNotification:(id)sender +{ + [GrowlApplicationBridge + notifyWithTitle:@"Put down that cocktail..." + description:@"your HandBrake encode is done!" + notificationName:SERVICE_NAME + iconData:nil + priority:0 + isSticky:1 + clickContext:nil]; +} + +#pragma mark - +#pragma mark Get New Source + +/*Opens the source browse window, called from Open Source widgets */ +- (IBAction) browseSources: (id) sender +{ + [self enableUI: NO]; + NSOpenPanel * panel; + + panel = [NSOpenPanel openPanel]; + [panel setAllowsMultipleSelection: NO]; + [panel setCanChooseFiles: YES]; + [panel setCanChooseDirectories: YES ]; + NSString * sourceDirectory; + if ([[NSUserDefaults standardUserDefaults] stringForKey:@"LastSourceDirectory"]) + { + sourceDirectory = [[NSUserDefaults standardUserDefaults] stringForKey:@"LastSourceDirectory"]; + } + 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 + */ + [panel beginSheetForDirectory: sourceDirectory file: nil types: nil + modalForWindow: fWindow modalDelegate: self + didEndSelector: @selector( browseSourcesDone:returnCode:contextInfo: ) + contextInfo: sender]; +} + +- (void) browseSourcesDone: (NSOpenPanel *) sheet + returnCode: (int) returnCode contextInfo: (void *) contextInfo +{ + /* we convert the sender content of contextInfo back into a variable called sender + * mostly just for consistency for evaluation later + */ + id sender = (id)contextInfo; + /* User selected a file to open */ + if( returnCode == NSOKButton ) + { + + NSString *scanPath = [[sheet filenames] objectAtIndex: 0]; + /* we order out sheet, which is the browse window as we need to open + * the title selection sheet right away + */ + [sheet orderOut: self]; + + if (sender == fOpenSourceTitleMMenu) + { + /* We put the chosen source path in the source display text field for the + * source title selection sheet in which the user specifies the specific title to be + * scanned as well as the short source name in fSrcDsplyNameTitleScan just for display + * purposes in the title panel + */ + /* Full Path */ + [fScanSrcTitlePathField setStringValue: [NSString stringWithFormat:@"%@", scanPath]]; + NSString *displayTitlescanSourceName; + + if ([[scanPath lastPathComponent] isEqualToString: @"VIDEO_TS"]) + { + /* If VIDEO_TS Folder is chosen, choose its parent folder for the source display name + we have to use the title->dvd value so we get the proper name of the volume if a physical dvd is the source*/ + displayTitlescanSourceName = [NSString stringWithFormat:[[scanPath stringByDeletingLastPathComponent] lastPathComponent]]; + } + else + { + /* if not the VIDEO_TS Folder, we can assume the chosen folder is the source name */ + displayTitlescanSourceName = [NSString stringWithFormat:[scanPath lastPathComponent]]; + } + /* we set the source display name in the title selection dialogue */ + [fSrcDsplyNameTitleScan setStringValue: [NSString stringWithFormat:@"%@", displayTitlescanSourceName]]; + /* We show the actual sheet where the user specifies the title to be scanned + * as we are going to do a title specific scan + */ + [self showSourceTitleScanPanel:NULL]; + } + else + { + /* We are just doing a standard full source scan, so we specify "0" to libhb */ + NSString *path = [[sheet filenames] objectAtIndex: 0]; + [self performScan:path scanTitleNum:0]; + } + + } + else // User clicked Cancel in browse window + { + /* if we have a title loaded up */ + if ([[fSrcDVD2Field stringValue] length] > 0) + { + [self enableUI: YES]; + } + } +} + +/* Here we open the title selection sheet where we can specify an exact title to be scanned */ +- (IBAction) showSourceTitleScanPanel: (id) sender +{ + /* We default the title number to be scanned to "0" which results in a full source scan, unless the + * user changes it + */ + [fScanSrcTitleNumField setStringValue: @"0"]; + /* Show the panel */ + [NSApp beginSheet: fScanSrcTitlePanel modalForWindow: fWindow modalDelegate: NULL didEndSelector: NULL contextInfo: NULL]; +} + +- (IBAction) closeSourceTitleScanPanel: (id) sender +{ + [NSApp endSheet: fScanSrcTitlePanel]; + [fScanSrcTitlePanel orderOut: self]; + if(sender == fScanSrcTitleOpenButton) + { + /* We setup the scan status in the main window to indicate a source title scan */ + [fSrcDVD2Field setStringValue: _( @"Opening a new source title ..." )]; + [fScanIndicator setHidden: NO]; + [fScanIndicator setIndeterminate: YES]; + [fScanIndicator startAnimation: nil]; + + /* we set the last source directory in the prefs here */ + NSString *sourceDirectory = [[fScanSrcTitlePathField stringValue] stringByDeletingLastPathComponent]; + [[NSUserDefaults standardUserDefaults] setObject:sourceDirectory forKey:@"LastSourceDirectory"]; + /* We use the performScan method to actually perform the specified scan passing the path and the title + * to be scanned + */ + [self performScan:[fScanSrcTitlePathField stringValue] scanTitleNum:[fScanSrcTitleNumField intValue]]; } +} + - [self QualitySliderChanged: sender]; - [self CalculateBitrate: sender]; - [self CustomSettingUsed: sender]; +/* Here we actually tell hb_scan to perform the source scan, using the path to source and title number*/ +- (void) performScan:(NSString *) scanPath scanTitleNum: (int) scanTitleNum +{ + NSString *path = scanPath; + HBDVDDetector *detector = [HBDVDDetector detectorForPath:path]; + if( [detector isVideoDVD] ) + { + // The chosen path was actually on a DVD, so use the raw block + // device path instead. + path = [detector devicePath]; + } + /* If there is no title number passed to scan, we use "0" + * which causes the default behavior of a full source scan + */ + if (!scanTitleNum) + { + scanTitleNum = 0; + } + hb_scan( fHandle, [path UTF8String], scanTitleNum ); } -- (IBAction) QualitySliderChanged: (id) sender +- (IBAction) showNewScan:(id)sender { - [fVidConstantCell setTitle: [NSString stringWithFormat: - _( @"Constant quality: %.0f %%" ), 100.0 * - [fVidQualitySlider floatValue]]]; - [self CustomSettingUsed: sender]; + hb_list_t * list; + hb_title_t * title; + int indxpri=0; // Used to search the longuest title (default in combobox) + int longuestpri=0; // Used to search the longuest title (default in combobox) + + list = hb_get_titles( fHandle ); + + if( !hb_list_count( list ) ) + { + /* We display a message if a valid dvd source was not chosen */ + [fSrcDVD2Field setStringValue: @"No Valid Title Found"]; + SuccessfulScan = NO; + } + else + { + /* We increment the successful scancount here by one, + which we use at the end of this function to tell the gui + if this is the first successful scan since launch and whether + or not we should set all settings to the defaults */ + + currentSuccessfulScanCount++; + + [toolbar validateVisibleItems]; + + [fSrcTitlePopUp removeAllItems]; + for( int i = 0; i < hb_list_count( list ); i++ ) + { + title = (hb_title_t *) hb_list_item( list, i ); + + currentSource = [NSString stringWithUTF8String: title->name]; + + /* To get the source name as well as the default output name, first we check to see if + the selected directory is the VIDEO_TS Directory */ + if ([[currentSource lastPathComponent] isEqualToString: @"VIDEO_TS"]) + { + /* If VIDEO_TS Folder is chosen, choose its parent folder for the source display name + we have to use the title->dvd value so we get the proper name of the volume if a physical dvd is the source*/ + sourceDisplayName = [NSString stringWithFormat:[[[NSString stringWithUTF8String: title->dvd] stringByDeletingLastPathComponent] lastPathComponent]]; + } + else + { + /* if not the VIDEO_TS Folder, we can assume the chosen folder is the source name */ + sourceDisplayName = [NSString stringWithFormat:[currentSource lastPathComponent]]; + } + /*Set DVD Name at top of window*/ + [fSrcDVD2Field setStringValue:[NSString stringWithFormat: @"%@", sourceDisplayName]]; + + /* Use the dvd name in the default output field here + May want to add code to remove blank spaces for some dvd names*/ + /* Check to see if the last destination has been set,use if so, if not, use Desktop */ + if ([[NSUserDefaults standardUserDefaults] stringForKey:@"LastDestinationDirectory"]) + { + [fDstFile2Field setStringValue: [NSString stringWithFormat: + @"%@/%@.mp4", [[NSUserDefaults standardUserDefaults] stringForKey:@"LastDestinationDirectory"],sourceDisplayName]]; + } + else + { + [fDstFile2Field setStringValue: [NSString stringWithFormat: + @"%@/Desktop/%@.mp4", NSHomeDirectory(),sourceDisplayName]]; + } + + if (longuestpri < title->hours*60*60 + title->minutes *60 + title->seconds) + { + longuestpri=title->hours*60*60 + title->minutes *60 + title->seconds; + indxpri=i; + } + + [self formatPopUpChanged:NULL]; + + [fSrcTitlePopUp addItemWithTitle: [NSString + stringWithFormat: @"%d - %02dh%02dm%02ds", + title->index, title->hours, title->minutes, + title->seconds]]; + } + + // Select the longuest title + [fSrcTitlePopUp selectItemAtIndex: indxpri]; + [self titlePopUpChanged: NULL]; + + SuccessfulScan = YES; + [self enableUI: YES]; + + /* if its the initial successful scan after awakeFromNib */ + if (currentSuccessfulScanCount == 1) + { + [self selectDefaultPreset: NULL]; + /* if Deinterlace upon launch is specified in the prefs, then set to 1 for "Fast", + if not, then set to 0 for none */ + if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultDeinterlaceOn"] > 0) + [fPictureController setDeinterlace:1]; + else + [fPictureController setDeinterlace:0]; + } + + } } -- (IBAction) BrowseFile: (id) sender + +#pragma mark - +#pragma mark New Output Destination + +- (IBAction) browseFile: (id) sender { /* Open a panel to let the user choose and update the text field */ NSSavePanel * panel = [NSSavePanel savePanel]; /* We get the current file name and path from the destination field here */ [panel beginSheetForDirectory: [[fDstFile2Field stringValue] stringByDeletingLastPathComponent] file: [[fDstFile2Field stringValue] lastPathComponent] modalForWindow: fWindow modalDelegate: self - didEndSelector: @selector( BrowseFileDone:returnCode:contextInfo: ) + didEndSelector: @selector( browseFileDone:returnCode:contextInfo: ) contextInfo: NULL]; } -- (void) BrowseFileDone: (NSSavePanel *) sheet +- (void) browseFileDone: (NSSavePanel *) sheet returnCode: (int) returnCode contextInfo: (void *) contextInfo { if( returnCode == NSOKButton ) { [fDstFile2Field setStringValue: [sheet filename]]; - } } -- (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] ); - /* Resize the panel */ - NSSize newSize; - newSize.width = 246 + title->width; - newSize.height = 80 + title->height; - [fPicturePanel setContentSize: newSize]; +#pragma mark - +#pragma mark Main Window Control - [fPictureController SetTitle: title]; +- (IBAction) openMainWindow: (id) sender +{ + [fWindow makeKeyAndOrderFront:nil]; +} - [NSApp beginSheet: fPicturePanel modalForWindow: fWindow - modalDelegate: NULL didEndSelector: NULL contextInfo: NULL]; - [NSApp runModalForWindow: fPicturePanel]; - [NSApp endSheet: fPicturePanel]; - [fPicturePanel orderOut: self]; - [self CalculatePictureSizing: sender]; +- (BOOL) windowShouldClose: (id) sender +{ + return YES; } -- (IBAction) ShowQueuePanel: (id) sender +- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag { - /* Update the OutlineView */ - [fQueueController Update: sender]; - - /* Show the panel */ - [NSApp beginSheet: fQueuePanel modalForWindow: fWindow - modalDelegate: NULL didEndSelector: NULL contextInfo: NULL]; - [NSApp runModalForWindow: fQueuePanel]; - [NSApp endSheet: fQueuePanel]; - [fQueuePanel orderOut: self]; + if( !flag ) { + [fWindow makeKeyAndOrderFront:nil]; + + return YES; + } + + return NO; } -- (void) PrepareJob +#pragma mark - +#pragma mark Job Handling + + +- (void) prepareJob { hb_list_t * list = hb_get_titles( fHandle ); hb_title_t * title = (hb_title_t *) hb_list_item( list, @@ -1247,17 +1375,7 @@ list = hb_get_titles( fHandle ); /* If mpeg-4, then set mpeg-4 specific options like chapters and > 4gb file sizes */ if ([fDstFormatPopUp indexOfSelectedItem] == 0) { - /* We set the chapter marker extraction here based on the format being - mpeg4 and the checkbox being checked */ - if ([fCreateChapterMarkers state] == NSOnState) - { - job->chapter_markers = 1; - } - else - { - job->chapter_markers = 0; - } - /* We set the largeFileSize (64 bit formatting) variable here to allow for > 4gb files based on the format being + /* 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 ([[NSUserDefaults standardUserDefaults] boolForKey:@"AllowLargeFiles"] > 0 && [fDstMpgLargeFileCheck state] == NSOnState) @@ -1269,8 +1387,19 @@ list = hb_get_titles( fHandle ); job->largeFileSize = 0; } } - - + if ([fDstFormatPopUp indexOfSelectedItem] == 0 || [fDstFormatPopUp indexOfSelectedItem] == 3) + { + /* 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_FFMPEG ) && [fVidEncoderPopUp indexOfSelectedItem] > 0 ) { @@ -1303,15 +1432,15 @@ list = hb_get_titles( fHandle ); if( [fVidTwoPassCheck state] == NSOnState && [fVidTurboPassCheck state] == NSOnState ) { /* pass the "Turbo" string to be appended to the existing x264 opts string into a variable for the first pass */ - NSString *firstPassOptStringTurbo = @":ref=1:subme=1:me=dia:analyse=none:weightb=0:trellis=0:no-fast-pskip=0:8x8dct=0"; + NSString *firstPassOptStringTurbo = @":ref=1:subme=1:me=dia:analyse=none:trellis=0:no-fast-pskip=0:8x8dct=0"; /* append the "Turbo" string variable to the existing opts string. Note: the "Turbo" string must be appended, not prepended to work properly*/ - NSString *firstPassOptStringCombined = [[fDisplayX264Options stringValue] stringByAppendingString:firstPassOptStringTurbo]; + NSString *firstPassOptStringCombined = [[fAdvancedOptions optionsString] stringByAppendingString:firstPassOptStringTurbo]; strcpy(job->x264opts, [firstPassOptStringCombined UTF8String]); } else { - strcpy(job->x264opts, [[fDisplayX264Options stringValue] UTF8String]); + strcpy(job->x264opts, [[fAdvancedOptions optionsString] UTF8String]); } job->h264_13 = [fVidEncoderPopUp indexOfSelectedItem]; @@ -1347,11 +1476,9 @@ list = hb_get_titles( fHandle ); } job->grayscale = ( [fVidGrayscaleCheck state] == NSOnState ); - - /* Subtitle settings */ - job->subtitle = [fSubPopUp indexOfSelectedItem] - 1; + job->subtitle = [fSubPopUp indexOfSelectedItem] - 2; /* Audio tracks and mixdowns */ /* check for the condition where track 2 has an audio selected, but track 1 does not */ @@ -1380,208 +1507,428 @@ list = hb_get_titles( fHandle ); indexOfSelectedItem]].rate; job->abitrate = [[fAudBitratePopUp selectedItem] tag]; - /* TODO: Filter settings */ - if( job->filters ) + /* set vfr according to the Picture Window */ + if ([fPictureController vfr]) + { + job->vfr = 1; + } + else { - hb_list_close( &job->filters ); + job->vfr = 0; } + + /* Filters */ job->filters = hb_list_init(); -#if 1 - /* Run old deinterlacer if deinterlacing specified */ - if( job->deinterlace ) - { + + /* Detelecine */ + if ([fPictureController detelecine]) + { + hb_list_add( job->filters, &hb_filter_detelecine ); + } + + /* Deinterlace */ + if ([fPictureController deinterlace] == 1) + { + /* Run old deinterlacer by default */ hb_filter_deinterlace.settings = "-1"; hb_list_add( job->filters, &hb_filter_deinterlace ); } -#else - /* Choose your own filters! Here's some examples... */ - hb_filter_detelecine.settings = "1:1:4:4:0:0"; - hb_list_add( job->filters, &hb_filter_detelecine ); - - hb_filter_deinterlace.settings = "3:-1:2:10"; - hb_list_add( job->filters, &hb_filter_deinterlace ); - - hb_filter_deblock.settings = "4:2"; - hb_list_add( job->filters, &hb_filter_deblock ); + else if ([fPictureController deinterlace] == 2) + { + /* Yadif mode 0 (1-pass with spatial deinterlacing.) */ + hb_filter_deinterlace.settings = "0"; + hb_list_add( job->filters, &hb_filter_deinterlace ); + } + else if ([fPictureController deinterlace] == 3) + { + /* Yadif (1-pass w/o spatial deinterlacing) and Mcdeint */ + hb_filter_deinterlace.settings = "2:-1:1"; + hb_list_add( job->filters, &hb_filter_deinterlace ); + } + else if ([fPictureController deinterlace] == 4) + { + /* Yadif (2-pass w/ spatial deinterlacing) and Mcdeint*/ + hb_filter_deinterlace.settings = "1:-1:1"; + hb_list_add( job->filters, &hb_filter_deinterlace ); + } + + /* Denoise */ + + if ([fPictureController denoise] == 1) // Weak in popup + { + hb_filter_denoise.settings = "2:1:2:3"; + hb_list_add( job->filters, &hb_filter_denoise ); + } + else if ([fPictureController denoise] == 2) // Medium in popup + { + hb_filter_denoise.settings = "3:2:2:3"; + hb_list_add( job->filters, &hb_filter_denoise ); + } + else if ([fPictureController denoise] == 3) // Strong in popup + { + hb_filter_denoise.settings = "7:7:5:5"; + hb_list_add( job->filters, &hb_filter_denoise ); + } + + /* Deblock (uses pp7 default) */ + if ([fPictureController deblock]) + { + hb_list_add( job->filters, &hb_filter_deblock ); + } - hb_filter_denoise.settings = "3:2:3:3"; - hb_list_add( job->filters, &hb_filter_denoise ); -#endif } -- (IBAction) AddToQueue: (id) sender +/* addToQueue: puts up an alert before ultimately calling doAddToQueue +*/ +- (IBAction) addToQueue: (id) sender { -/* We get the destination directory from the destingation field here */ + /* We get the destination directory from the destination field here */ NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent]; /* We check for a valid destination here */ if ([[NSFileManager defaultManager] fileExistsAtPath:destinationDirectory] == 0) { NSRunAlertPanel(@"Warning!", @"This is not a valid destination directory!", @"OK", nil, nil); + return; } - else - { - - hb_list_t * list = hb_get_titles( fHandle ); - hb_title_t * title = (hb_title_t *) hb_list_item( list, - [fSrcTitlePopUp indexOfSelectedItem] ); - hb_job_t * job = title->job; - - [self PrepareJob]; - - /* Destination file */ - job->file = [[fDstFile2Field stringValue] UTF8String]; - - if( [fVidTwoPassCheck state] == NSOnState ) - { - job->pass = 1; - hb_add( fHandle, job ); - job->pass = 2; - - job->x264opts = (char *)calloc(1024, 1); /* Fixme, this just leaks */ - strcpy(job->x264opts, [[fDisplayX264Options stringValue] UTF8String]); - - hb_add( fHandle, job ); - } - else - { - job->pass = 0; - hb_add( fHandle, job ); - } + + /* We check for duplicate name here */ + if( [[NSFileManager defaultManager] fileExistsAtPath: + [fDstFile2Field stringValue]] ) + { + NSBeginCriticalAlertSheet( _( @"File already exists" ), + _( @"Cancel" ), _( @"Overwrite" ), NULL, fWindow, self, + @selector( overwriteAddToQueueAlertDone:returnCode:contextInfo: ), + NULL, NULL, [NSString stringWithFormat: + _( @"Do you want to overwrite %@?" ), + [fDstFile2Field stringValue]] ); + // overwriteAddToQueueAlertDone: will be called when the alert is dismissed. + } + else + { + [self doAddToQueue]; + } +} + +/* overwriteAddToQueueAlertDone: called from the alert posted by addToQueue that asks + the user if they want to overwrite an exiting movie file. +*/ +- (void) overwriteAddToQueueAlertDone: (NSWindow *) sheet + returnCode: (int) returnCode contextInfo: (void *) contextInfo +{ + if( returnCode == NSAlertAlternateReturn ) + [self doAddToQueue]; +} + +- (void) doAddToQueue +{ + hb_list_t * list = hb_get_titles( fHandle ); + hb_title_t * title = (hb_title_t *) hb_list_item( list, [fSrcTitlePopUp indexOfSelectedItem] ); + hb_job_t * job = title->job; + + // Assign a sequence number, starting at zero, to each job added so they can + // be lumped together in the UI. + job->sequence_id = -1; + + [self prepareJob]; + + /* Destination file */ + job->file = [[fDstFile2Field stringValue] UTF8String]; + + if( [fSubForcedCheck state] == NSOnState ) + job->subtitle_force = 1; + else + job->subtitle_force = 0; + + /* + * subtitle of -1 is a scan + */ + if( job->subtitle == -1 ) + { + char *x264opts_tmp; + + /* + * When subtitle scan is enabled do a fast pre-scan job + * which will determine which subtitles to enable, if any. + */ + 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 + */ + job->sequence_id++; // for job grouping + hb_add( fHandle, 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( [fVidTwoPassCheck state] == NSOnState ) + { + 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->sequence_id++; // for job grouping + hb_add( fHandle, job ); + + job->pass = 2; + job->sequence_id++; // for job grouping + + job->x264opts = (char *)calloc(1024, 1); /* Fixme, this just leaks */ + strcpy(job->x264opts, [[fAdvancedOptions optionsString] UTF8String]); + + job->select_subtitle = subtitle_tmp; + + hb_add( fHandle, job ); + } + else + { + job->indepth_scan = 0; + job->pass = 0; + job->sequence_id++; // for job grouping + hb_add( fHandle, job ); + } + NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent]; [[NSUserDefaults standardUserDefaults] setObject:destinationDirectory forKey:@"LastDestinationDirectory"]; - /* Lets try to update stuff, taken from remove in the queue controller */ - [fQueueController performSelectorOnMainThread: @selector( Update: ) - withObject: sender waitUntilDone: NO]; - } + + // Notify the queue + [fQueueController hblibJobListChanged]; } +/* Rip: puts up an alert before ultimately calling doRip +*/ - (IBAction) Rip: (id) sender { /* Rip or Cancel ? */ - // if( [[fRipButton title] isEqualToString: _( @"Cancel" )] ) - if(stopOrStart) + hb_state_t s; + hb_get_state2( fHandle, &s ); + + if(s.state == HB_STATE_WORKING || s.state == HB_STATE_PAUSED) { [self Cancel: sender]; return; } - /* if there is no job in the queue, then add it to the queue and rip - otherwise, there are already jobs in queue, so just rip the queue */ - int count = hb_count( fHandle ); - if( count < 1 ) - { - [self AddToQueue: sender]; - } - /* We check for duplicate name here */ - if( [[NSFileManager defaultManager] fileExistsAtPath: - [fDstFile2Field stringValue]] ) + // If there are jobs in the queue, then this is a rip the queue + + if (hb_count( fHandle ) > 0) + { + [self doRip]; + return; + } + + // Before adding jobs to the queue, check for a valid destination. + + NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent]; + if ([[NSFileManager defaultManager] fileExistsAtPath:destinationDirectory] == 0) + { + 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]] ) { NSBeginCriticalAlertSheet( _( @"File already exists" ), _( @"Cancel" ), _( @"Overwrite" ), NULL, fWindow, self, - @selector( OverwriteAlertDone:returnCode:contextInfo: ), + @selector( overWriteAlertDone:returnCode:contextInfo: ), NULL, NULL, [NSString stringWithFormat: _( @"Do you want to overwrite %@?" ), [fDstFile2Field stringValue]] ); - return; + + // overWriteAlertDone: will be called when the alert is dismissed. It will call doRip. } - /* We get the destination directory from the destination field here */ - NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent]; - /* We check for a valid destination here */ - if ([[NSFileManager defaultManager] fileExistsAtPath:destinationDirectory] == 0) - { - NSRunAlertPanel(@"Warning!", @"This is not a valid destination directory!", @"OK", nil, nil); - } - else - { - [[NSUserDefaults standardUserDefaults] setObject:destinationDirectory forKey:@"LastDestinationDirectory"]; - [self _Rip]; - } - - + else + { + /* if there are no jobs in the queue, then add this one to the queue and rip + otherwise, just rip the queue */ + if( hb_count( fHandle ) == 0) + { + [self doAddToQueue]; + } + NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent]; + [[NSUserDefaults standardUserDefaults] setObject:destinationDirectory forKey:@"LastDestinationDirectory"]; + [self doRip]; + } } -- (void) OverwriteAlertDone: (NSWindow *) sheet +/* overWriteAlertDone: called from the alert posted by Rip: that asks the user if they + want to overwrite an exiting movie file. +*/ +- (void) overWriteAlertDone: (NSWindow *) sheet returnCode: (int) returnCode contextInfo: (void *) contextInfo { if( returnCode == NSAlertAlternateReturn ) { - [self _Rip]; + /* if there are no jobs in the queue, then add this one to the queue and rip + otherwise, just rip the queue */ + if( hb_count( fHandle ) == 0 ) + { + [self doAddToQueue]; + } + + NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent]; + [[NSUserDefaults standardUserDefaults] setObject:destinationDirectory forKey:@"LastDestinationDirectory"]; + [self doRip]; } } -- (void) UpdateAlertDone: (NSWindow *) sheet - returnCode: (int) returnCode contextInfo: (void *) contextInfo +- (void) remindUserOfSleepOrShutdown { - if( returnCode == NSAlertAlternateReturn ) - { - /* Show scan panel */ - [self performSelectorOnMainThread: @selector(ShowScanPanel:) - withObject: NULL waitUntilDone: NO]; - return; - } + if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Put Computer To Sleep"]) + { + /*Warn that computer will sleep after encoding*/ + int reminduser; + NSBeep(); + reminduser = NSRunAlertPanel(@"The computer will sleep after encoding is done.",@"You have selected to sleep the computer after encoding. To turn off sleeping, go to the HandBrake preferences.", @"OK", @"Preferences...", nil); + [NSApp requestUserAttention:NSCriticalRequest]; + if ( reminduser == NSAlertAlternateReturn ) + { + [self showPreferencesWindow:NULL]; + } + } + else if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Shut Down Computer"]) + { + /*Warn that computer will shut down after encoding*/ + int reminduser; + NSBeep(); + reminduser = NSRunAlertPanel(@"The computer will shut down after encoding is done.",@"You have selected to shut down the computer after encoding. To turn off shut down, go to the HandBrake preferences.", @"OK", @"Preferences...", nil); + [NSApp requestUserAttention:NSCriticalRequest]; + if ( reminduser == NSAlertAlternateReturn ) + { + [self showPreferencesWindow:NULL]; + } + } - /* Go to HandBrake homepage and exit */ - [self OpenHomepage: NULL]; - [NSApp terminate: self]; } -- (void) _Rip + +- (void) doRip { /* Let libhb do the job */ hb_start( fHandle ); /*set the fEncodeState State */ fEncodeState = 1; - - /* Disable interface */ - //[self EnableUI: NO]; - // [fPauseButton setEnabled: NO]; - // [fRipButton setEnabled: NO]; - pauseButtonEnabled = NO; - startButtonEnabled = NO; - NSRect frame = [fWindow frame]; - if (frame.size.width <= 591) - frame.size.width = 591; - frame.size.height += 44; - frame.origin.y -= 44; - [fWindow setFrame:frame display:YES animate:YES]; } -- (IBAction) Cancel: (id) sender + + + +//------------------------------------------------------------------------------------ +// Removes all jobs from the queue. Does not cancel the current processing job. +//------------------------------------------------------------------------------------ +- (void) doDeleteQueuedJobs +{ + hb_job_t * job; + while( ( job = hb_job( fHandle, 0 ) ) ) + hb_rem( fHandle, job ); +} + +//------------------------------------------------------------------------------------ +// Cancels the current job and proceeds with the next one in the queue. +//------------------------------------------------------------------------------------ +- (void) doCancelCurrentJob { - NSBeginCriticalAlertSheet( _( @"Cancel - Are you sure?" ), - _( @"Keep working" ), _( @"Cancel encoding" ), NULL, fWindow, self, - @selector( _Cancel:returnCode:contextInfo: ), NULL, NULL, - _( @"Encoding won't be recoverable." ) ); + // Stop the current job. hb_stop will only cancel the current pass and then set + // its state to HB_STATE_WORKDONE. It also does this asynchronously. So when we + // see the state has changed to HB_STATE_WORKDONE (in updateUI), we'll delete the + // remaining passes of the job and then start the queue back up if there are any + // remaining jobs. + + [fQueueController hblibWillStop]; + hb_stop( fHandle ); + fEncodeState = 2; // don't alert at end of processing since this was a cancel + } -- (void) _Cancel: (NSWindow *) sheet - returnCode: (int) returnCode contextInfo: (void *) contextInfo +//------------------------------------------------------------------------------------ +// Displays an alert asking user if the want to cancel encoding of current job. +// Cancel: returns immediately after posting the alert. Later, when the user +// acknowledges the alert, doCancelCurrentJob is called. +//------------------------------------------------------------------------------------ +- (IBAction)Cancel: (id)sender { - if( returnCode == NSAlertAlternateReturn ) + if (!fHandle) return; + + hb_job_t * job = hb_current_job(fHandle); + if (!job) return; + + NSString * alertTitle = [NSString stringWithFormat:NSLocalizedString(@"Do you want to stop encoding of %@?", nil), + [NSString stringWithUTF8String:job->title->name]]; + + // Which window to attach the sheet to? + NSWindow * docWindow; + if ([sender respondsToSelector: @selector(window)]) + docWindow = [sender window]; + else + docWindow = fWindow; + + NSBeginCriticalAlertSheet( + alertTitle, + NSLocalizedString(@"Keep Encoding", nil), + NSLocalizedString(@"Delete All", nil), + NSLocalizedString(@"Stop Encoding", nil), + docWindow, self, + nil, @selector(didDimissCancelCurrentJob:returnCode:contextInfo:), nil, + NSLocalizedString(@"Your movie will be lost if you don't continue encoding.", nil), + [NSString stringWithUTF8String:job->title->name]); + + // didDimissCancelCurrentJob:returnCode:contextInfo: will be called when the dialog is dismissed + + // N.B.: didDimissCancelCurrentJob:returnCode:contextInfo: is designated as the dismiss + // selector to prevent a crash. As a dismiss selector, the alert window will + // have already be dismissed. If we don't do it this way, the dismissing of + // the alert window will cause the table view to be redrawn at a point where + // current job has been deleted by hblib but we don't know about it yet. This + // is a prime example of wy we need to NOT be relying on hb_current_job!!!! +} + +- (void) didDimissCancelCurrentJob: (NSWindow *)sheet returnCode: (int)returnCode contextInfo: (void *)contextInfo +{ + if (returnCode == NSAlertOtherReturn) + [self doCancelCurrentJob]; + else if (returnCode == NSAlertAlternateReturn) { - hb_stop( fHandle ); - // [fPauseButton setEnabled: NO]; - // [fRipButton setEnabled: NO]; - pauseButtonEnabled = NO; - startButtonEnabled = NO; - /*set the fEncodeState State */ - fEncodeState = 2; + [self doDeleteQueuedJobs]; + [self doCancelCurrentJob]; } } + + + + - (IBAction) Pause: (id) sender { - // [fPauseButton setEnabled: NO]; - // [fRipButton setEnabled: NO]; - - // if( [[fPauseButton title] isEqualToString: _( @"Resume" )] ) - pauseButtonEnabled = NO; - startButtonEnabled = NO; + hb_state_t s; + hb_get_state2( fHandle, &s ); - if(resumeOrPause) + if( s.state == HB_STATE_PAUSED ) { hb_resume( fHandle ); } @@ -1591,7 +1938,10 @@ list = hb_get_titles( fHandle ); } } -- (IBAction) TitlePopUpChanged: (id) sender +#pragma mark - +#pragma mark GUI Controls Changed Methods + +- (IBAction) titlePopUpChanged: (id) sender { hb_list_t * list = hb_get_titles( fHandle ); hb_title_t * title = (hb_title_t*) @@ -1604,7 +1954,7 @@ list = hb_get_titles( fHandle ); [fDstFile2Field setStringValue: [NSString stringWithFormat: @"%@/%@-%d.%@", [[fDstFile2Field stringValue] stringByDeletingLastPathComponent], [NSString stringWithUTF8String: title->name], - [fSrcTitlePopUp indexOfSelectedItem] + 1, + title->index, [[fDstFile2Field stringValue] pathExtension]]]; } @@ -1621,7 +1971,7 @@ list = hb_get_titles( fHandle ); [fSrcChapterStartPopUp selectItemAtIndex: 0]; [fSrcChapterEndPopUp selectItemAtIndex: hb_list_count( title->list_chapter ) - 1]; - [self ChapterPopUpChanged: NULL]; + [self chapterPopUpChanged: NULL]; /* Start Get and set the initial pic size for display */ hb_job_t * job = title->job; @@ -1629,17 +1979,16 @@ list = hb_get_titles( fHandle ); /* Turn Deinterlace on/off depending on the preference */ if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultDeinterlaceOn"] > 0) { - job->deinterlace = 1; + [fPictureController setDeinterlace:1]; } else { - job->deinterlace = 0; + [fPictureController setDeinterlace:0]; } /* Pixel Ratio Setting */ if ([[NSUserDefaults standardUserDefaults] boolForKey:@"PixelRatio"]) { - job->pixel_ratio = 1 ; } else @@ -1652,6 +2001,9 @@ list = hb_get_titles( fHandle ); [fPicSrcHeight setStringValue: [NSString stringWithFormat: @"%d", fTitle->height]]; + /* 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 in variables for use with some presets later on */ PicOrigOutputWidth = job->width; @@ -1666,18 +2018,19 @@ list = hb_get_titles( fHandle ); [fPicSettingHeight setStringValue: [NSString stringWithFormat: @"%d", PicOrigOutputHeight]]; /* we run the picture size values through - CalculatePictureSizing to get all picture size + calculatePictureSizing to get all picture size information*/ - [self CalculatePictureSizing: NULL]; - /* Run Through EncoderPopUpChanged to see if there + [self calculatePictureSizing: NULL]; + /* Run Through encoderPopUpChanged to see if there needs to be any pic value modifications based on encoder settings */ - //[self EncoderPopUpChanged: NULL]; + //[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 ); @@ -1688,27 +2041,76 @@ list = hb_get_titles( fHandle ); subtitle->lang] action: NULL keyEquivalent: @""]; } [fSubPopUp selectItemAtIndex: 0]; + + [self subtitleSelectionChanged: NULL]; /* Update chapter table */ [fChapterTitlesDelegate resetWithTitle:title]; [fChapterTable reloadData]; /* Update audio popups */ - [self AddAllAudioTracksToPopUp: fAudLang1PopUp]; - [self AddAllAudioTracksToPopUp: fAudLang2PopUp]; + [self addAllAudioTracksToPopUp: fAudLang1PopUp]; + [self addAllAudioTracksToPopUp: fAudLang2PopUp]; /* search for the first instance of our prefs default language for track 1, and set track 2 to "none" */ NSString * audioSearchPrefix = [[NSUserDefaults standardUserDefaults] stringForKey:@"DefaultLanguage"]; - [self SelectAudioTrackInPopUp: fAudLang1PopUp searchPrefixString: audioSearchPrefix selectIndexIfNotFound: 1]; - [self SelectAudioTrackInPopUp: fAudLang2PopUp searchPrefixString: NULL selectIndexIfNotFound: 0]; + [self selectAudioTrackInPopUp: fAudLang1PopUp searchPrefixString: audioSearchPrefix selectIndexIfNotFound: 1]; + [self selectAudioTrackInPopUp: fAudLang2PopUp searchPrefixString: NULL selectIndexIfNotFound: 0]; /* changing the title may have changed the audio channels on offer, */ - /* so call AudioTrackPopUpChanged for both audio tracks to update the mixdown popups */ - [self AudioTrackPopUpChanged: fAudLang1PopUp]; - [self AudioTrackPopUpChanged: fAudLang2PopUp]; - + /* so call audioTrackPopUpChanged for both audio tracks to update the mixdown popups */ + [self audioTrackPopUpChanged: fAudLang1PopUp]; + [self audioTrackPopUpChanged: fAudLang2PopUp]; + + /* We repopulate the Video Framerate popup and show the detected framerate along with "Same as Source"*/ + [fVidRatePopUp removeAllItems]; + if (fTitle->rate_base == 1126125) // 23.976 NTSC Film + { + [fVidRatePopUp addItemWithTitle: @"Same as source (23.976)"]; + } + else if (fTitle->rate_base == 1080000) // 25 PAL Film/Video + { + [fVidRatePopUp addItemWithTitle: @"Same as source (25)"]; + } + else if (fTitle->rate_base == 900900) // 29.97 NTSC Video + { + [fVidRatePopUp addItemWithTitle: @"Same as source (29.97)"]; + } + else + { + /* if none of the common dvd source framerates is detected, just use "Same as source" */ + [fVidRatePopUp addItemWithTitle: @"Same as source"]; + } + for( int i = 0; i < hb_video_rates_count; i++ ) + { + 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)"]]; + } + 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)"]]; + } + 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)"]]; + } + else + { + [fVidRatePopUp addItemWithTitle: + [NSString stringWithCString: hb_video_rates[i].string]]; + } + } + [fVidRatePopUp selectItemAtIndex: 0]; + + /* lets call tableViewSelected to make sure that any preset we have selected is enforced after a title change */ + [self tableViewSelected:NULL]; + } -- (IBAction) ChapterPopUpChanged: (id) sender +- (IBAction) chapterPopUpChanged: (id) sender { /* If start chapter popup is greater than end chapter popup, @@ -1719,7 +2121,6 @@ list = hb_get_titles( fHandle ); } - hb_list_t * list = hb_get_titles( fHandle ); hb_title_t * title = (hb_title_t *) hb_list_item( list, [fSrcTitlePopUp indexOfSelectedItem] ); @@ -1738,12 +2139,13 @@ list = hb_get_titles( fHandle ); @"%02lld:%02lld:%02lld", duration / 3600, ( duration / 60 ) % 60, duration % 60]]; - [self CalculateBitrate: sender]; + [self calculateBitrate: sender]; } -- (IBAction) FormatPopUpChanged: (id) sender +- (IBAction) formatPopUpChanged: (id) sender { NSString * string = [fDstFile2Field stringValue]; + NSString * selectedCodecs = [fDstCodecsPopUp titleOfSelectedItem]; int format = [fDstFormatPopUp indexOfSelectedItem]; char * ext = NULL; /* Initially set the large file (64 bit formatting) output checkbox to hidden */ @@ -1762,10 +2164,10 @@ list = hb_get_titles( fHandle ); { ext = "mp4"; } - [fDstCodecsPopUp addItemWithTitle: - _( @"MPEG-4 Video / AAC Audio" )]; - [fDstCodecsPopUp addItemWithTitle: - _( @"AVC/H.264 Video / AAC Audio" )]; + + [fDstCodecsPopUp addItemWithTitle:_( @"MPEG-4 Video / AAC Audio" )]; + [fDstCodecsPopUp addItemWithTitle:_( @"AVC/H.264 Video / AAC Audio" )]; + /* We enable the create chapters checkbox here since we are .mp4*/ [fCreateChapterMarkers setEnabled: YES]; /* We show the Large File (64 bit formatting) checkbox since we are .mp4 @@ -1778,92 +2180,86 @@ list = hb_get_titles( fHandle ); { /* if not enable in global preferences, we additionaly sanity check that the hidden checkbox is set to off. */ - [fDstMpgLargeFileCheck setState: NSOffState]; + [fDstMpgLargeFileCheck setState: NSOffState]; } - break; - case 1: + break; + + case 1: + ext = "mkv"; + [fDstCodecsPopUp addItemWithTitle:_( @"MPEG-4 Video / AAC Audio" )]; + [fDstCodecsPopUp addItemWithTitle:_( @"MPEG-4 Video / AC-3 Audio" )]; + [fDstCodecsPopUp addItemWithTitle:_( @"MPEG-4 Video / MP3 Audio" )]; + [fDstCodecsPopUp addItemWithTitle:_( @"MPEG-4 Video / Vorbis Audio" )]; + + [fDstCodecsPopUp addItemWithTitle:_( @"AVC/H.264 Video / AAC Audio" )]; + [fDstCodecsPopUp addItemWithTitle:_( @"AVC/H.264 Video / AC-3 Audio" )]; + [fDstCodecsPopUp addItemWithTitle:_( @"AVC/H.264 Video / MP3 Audio" )]; + [fDstCodecsPopUp addItemWithTitle:_( @"AVC/H.264 Video / Vorbis Audio" )]; + /* We enable the create chapters checkbox here */ + [fCreateChapterMarkers setEnabled: YES]; + break; + + case 2: ext = "avi"; - [fDstCodecsPopUp addItemWithTitle: - _( @"MPEG-4 Video / MP3 Audio" )]; - [fDstCodecsPopUp addItemWithTitle: - _( @"MPEG-4 Video / AC-3 Audio" )]; - [fDstCodecsPopUp addItemWithTitle: - _( @"AVC/H.264 Video / MP3 Audio" )]; - [fDstCodecsPopUp addItemWithTitle: - _( @"AVC/H.264 Video / AC-3 Audio" )]; - /* We disable the create chapters checkbox here since we are NOT .mp4 - and make sure it is unchecked*/ + [fDstCodecsPopUp addItemWithTitle:_( @"MPEG-4 Video / MP3 Audio" )]; + [fDstCodecsPopUp addItemWithTitle:_( @"MPEG-4 Video / AC-3 Audio" )]; + [fDstCodecsPopUp addItemWithTitle:_( @"AVC/H.264 Video / MP3 Audio" )]; + [fDstCodecsPopUp addItemWithTitle:_( @"AVC/H.264 Video / AC-3 Audio" )]; + /* We disable the create chapters checkbox here and make sure it is unchecked*/ [fCreateChapterMarkers setEnabled: NO]; [fCreateChapterMarkers setState: NSOffState]; break; - case 2: + + case 3: ext = "ogm"; - [fDstCodecsPopUp addItemWithTitle: - _( @"MPEG-4 Video / Vorbis Audio" )]; - [fDstCodecsPopUp addItemWithTitle: - _( @"MPEG-4 Video / MP3 Audio" )]; - /* We disable the create chapters checkbox here since we are NOT .mp4 - and make sure it is unchecked*/ + [fDstCodecsPopUp addItemWithTitle:_( @"MPEG-4 Video / Vorbis Audio" )]; + [fDstCodecsPopUp addItemWithTitle:_( @"MPEG-4 Video / MP3 Audio" )]; + /* We disable the create chapters checkbox here and make sure it is unchecked*/ [fCreateChapterMarkers setEnabled: NO]; [fCreateChapterMarkers setState: NSOffState]; break; - case 3: - ext = "mkv"; - [fDstCodecsPopUp addItemWithTitle: - _( @"MPEG-4 Video / AAC Audio" )]; - [fDstCodecsPopUp addItemWithTitle: - _( @"MPEG-4 Video / AC-3 Audio" )]; - [fDstCodecsPopUp addItemWithTitle: - _( @"MPEG-4 Video / MP3 Audio" )]; - [fDstCodecsPopUp addItemWithTitle: - _( @"MPEG-4 Video / Vorbis Audio" )]; - - [fDstCodecsPopUp addItemWithTitle: - _( @"AVC/H.264 Video / AAC Audio" )]; - [fDstCodecsPopUp addItemWithTitle: - _( @"AVC/H.264 Video / AC-3 Audio" )]; - [fDstCodecsPopUp addItemWithTitle: - _( @"AVC/H.264 Video / MP3 Audio" )]; - [fDstCodecsPopUp addItemWithTitle: - _( @"AVC/H.264 Video / Vorbis Audio" )]; - /* We disable the create chapters checkbox here since we are NOT .mp4 - and make sure it is unchecked*/ - [fCreateChapterMarkers setEnabled: YES]; - break; - } - [self CodecsPopUpChanged: NULL]; - - /* Add/replace to the correct extension */ - if( [string characterAtIndex: [string length] - 4] == '.' ) - { - [fDstFile2Field setStringValue: [NSString stringWithFormat: - @"%@.%s", [string substringToIndex: [string length] - 4], - ext]]; } - else - { - [fDstFile2Field setStringValue: [NSString stringWithFormat: - @"%@.%s", string, ext]]; + + if ( SuccessfulScan ) { + [fDstCodecsPopUp selectItemWithTitle:selectedCodecs]; + + /* Add/replace to the correct extension */ + if( [string characterAtIndex: [string length] - 4] == '.' ) + { + [fDstFile2Field setStringValue: [NSString stringWithFormat: + @"%@.%s", [string substringToIndex: [string length] - 4], + ext]]; + } + else + { + [fDstFile2Field setStringValue: [NSString stringWithFormat: + @"%@.%s", string, ext]]; + } + + if ( [fDstCodecsPopUp selectedItem] == NULL ) + { + [fDstCodecsPopUp selectItemAtIndex:0]; + [self codecsPopUpChanged: NULL]; + + /* changing the format may mean that we can / can't offer mono or 6ch, */ + /* so call audioTrackPopUpChanged for both audio tracks to update the mixdown popups */ + [self audioTrackPopUpChanged: fAudLang1PopUp]; + [self audioTrackPopUpChanged: fAudLang2PopUp]; + /* We call the method to properly enable/disable turbo 2 pass */ + [self twoPassCheckboxChanged: sender]; + /* We call method method to change UI to reflect whether a preset is used or not*/ + } } - - /* changing the format may mean that we can / can't offer mono or 6ch, */ - /* so call AudioTrackPopUpChanged for both audio tracks to update the mixdown popups */ - [self AudioTrackPopUpChanged: fAudLang1PopUp]; - [self AudioTrackPopUpChanged: fAudLang2PopUp]; - /* We call the method to properly enable/disable turbo 2 pass */ - [self TwoPassCheckboxChanged: sender]; - /* We call method method to change UI to reflect whether a preset is used or not*/ - [self CustomSettingUsed: sender]; - + + [self customSettingUsed: sender]; } -- (IBAction) CodecsPopUpChanged: (id) sender +- (IBAction) codecsPopUpChanged: (id) sender { int format = [fDstFormatPopUp indexOfSelectedItem]; int codecs = [fDstCodecsPopUp indexOfSelectedItem]; - [fX264optView setHidden: YES]; - [fX264optViewTitleLabel setStringValue: @"Only Used With The x264 (H.264) Codec"]; - + + [fAdvancedOptions setHidden:YES]; /* Update the encoder popup*/ if( ( FormatSettings[format][codecs] & HB_VCODEC_X264 ) ) @@ -1873,12 +2269,9 @@ list = hb_get_titles( fHandle ); [fVidEncoderPopUp addItemWithTitle: @"x264 (h.264 Main)"]; [fVidEncoderPopUp addItemWithTitle: @"x264 (h.264 iPod)"]; [fVidEncoderPopUp selectItemAtIndex: 0]; - [fX264optView setHidden: NO]; - [fX264optViewTitleLabel setStringValue: @""]; - - - + [fAdvancedOptions setHidden:NO]; } + else if( ( FormatSettings[format][codecs] & HB_VCODEC_FFMPEG ) ) { /* H.264 -> MPEG-4 */ @@ -1901,15 +2294,15 @@ list = hb_get_titles( fHandle ); [fAudBitratePopUp setEnabled: YES]; } /* changing the codecs on offer may mean that we can / can't offer mono or 6ch, */ - /* so call AudioTrackPopUpChanged for both audio tracks to update the mixdown popups */ - [self AudioTrackPopUpChanged: fAudLang1PopUp]; - [self AudioTrackPopUpChanged: fAudLang2PopUp]; + /* so call audioTrackPopUpChanged for both audio tracks to update the mixdown popups */ + [self audioTrackPopUpChanged: fAudLang1PopUp]; + [self audioTrackPopUpChanged: fAudLang2PopUp]; - [self CalculateBitrate: sender]; - [self TwoPassCheckboxChanged: sender]; + [self calculateBitrate: sender]; + [self twoPassCheckboxChanged: sender]; } -- (IBAction) EncoderPopUpChanged: (id) sender +- (IBAction) encoderPopUpChanged: (id) sender { /* Check to see if we need to modify the job pic values based on x264 (iPod) encoder selection */ @@ -1933,11 +2326,33 @@ list = hb_get_titles( fHandle ); [fDstMpgLargeFileCheck setState: NSOffState]; } - [self CalculatePictureSizing: sender]; - [self TwoPassCheckboxChanged: sender]; + [self calculatePictureSizing: sender]; + [self twoPassCheckboxChanged: sender]; +} + +/* Method to determine if we should change the UI +To reflect whether or not a Preset is being used or if +the user is using "Custom" settings by determining the sender*/ +- (IBAction) customSettingUsed: (id) sender +{ + if ([sender stringValue] != NULL) + { + /* Deselect the currently selected Preset if there is one*/ + [tableView deselectRow:[tableView selectedRow]]; + [[fPresetsActionMenu itemAtIndex:0] setEnabled: NO]; + /* Change UI to show "Custom" settings are being used */ + [fPresetSelectedDisplay setStringValue: @"Custom"]; + + curUserPresetChosenNum = nil; + } + } -- (IBAction) TwoPassCheckboxChanged: (id) sender + +#pragma mark - +#pragma mark - Video + +- (IBAction) twoPassCheckboxChanged: (id) sender { /* check to see if x264 is chosen */ int format = [fDstFormatPopUp indexOfSelectedItem]; @@ -1966,47 +2381,294 @@ list = hb_get_titles( fHandle ); } /* We call method method to change UI to reflect whether a preset is used or not*/ - [self CustomSettingUsed: sender]; + [self customSettingUsed: sender]; } -- (IBAction) SetEnabledStateOfAudioMixdownControls: (id) sender +- (IBAction ) videoFrameRateChanged: (id) sender { + /* We call method method to calculatePictureSizing to error check detelecine*/ + [self calculatePictureSizing: sender]; - /* enable/disable the mixdown text and popupbutton for audio track 1 */ - [fAudTrack1MixPopUp setEnabled: ([fAudLang1PopUp indexOfSelectedItem] == 0) ? NO : YES]; - [fAudTrack1MixLabel setTextColor: ([fAudLang1PopUp indexOfSelectedItem] == 0) ? - [NSColor disabledControlTextColor] : [NSColor controlTextColor]]; - - /* enable/disable the mixdown text and popupbutton for audio track 2 */ - [fAudTrack2MixPopUp setEnabled: ([fAudLang2PopUp indexOfSelectedItem] == 0) ? NO : YES]; - [fAudTrack2MixLabel setTextColor: ([fAudLang2PopUp indexOfSelectedItem] == 0) ? - [NSColor disabledControlTextColor] : [NSColor controlTextColor]]; - + /* We call method method to change UI to reflect whether a preset is used or not*/ + [self customSettingUsed: sender]; } - -- (IBAction) AddAllAudioTracksToPopUp: (id) sender +- (IBAction) videoMatrixChanged: (id) sender; { + bool target, bitrate, quality; - hb_list_t * list = hb_get_titles( fHandle ); - hb_title_t * title = (hb_title_t*) - hb_list_item( list, [fSrcTitlePopUp indexOfSelectedItem] ); - - hb_audio_t * audio; - - [sender removeAllItems]; - [sender addItemWithTitle: _( @"None" )]; - for( int i = 0; i < hb_list_count( title->list_audio ); i++ ) + target = bitrate = quality = false; + if( [fVidQualityMatrix isEnabled] ) { - audio = (hb_audio_t *) hb_list_item( title->list_audio, i ); - [[sender menu] addItemWithTitle: - [NSString stringWithCString: audio->lang] - action: NULL keyEquivalent: @""]; + switch( [fVidQualityMatrix selectedRow] ) + { + case 0: + target = true; + break; + case 1: + bitrate = true; + break; + case 2: + quality = true; + break; + } + } + [fVidTargetSizeField setEnabled: target]; + [fVidBitrateField setEnabled: bitrate]; + [fVidQualitySlider setEnabled: quality]; + [fVidTwoPassCheck setEnabled: !quality && + [fVidQualityMatrix isEnabled]]; + if( quality ) + { + [fVidTwoPassCheck setState: NSOffState]; + [fVidTurboPassCheck setHidden: YES]; + [fVidTurboPassCheck setState: NSOffState]; + } + + [self qualitySliderChanged: sender]; + [self calculateBitrate: sender]; + [self customSettingUsed: sender]; +} + +- (IBAction) qualitySliderChanged: (id) sender +{ + [fVidConstantCell setTitle: [NSString stringWithFormat: + _( @"Constant quality: %.0f %%" ), 100.0 * + [fVidQualitySlider floatValue]]]; + [self customSettingUsed: sender]; +} + +- (void) controlTextDidChange: (NSNotification *) notification +{ + [self calculateBitrate: NULL]; +} + +- (IBAction) calculateBitrate: (id) sender +{ + if( !fHandle || [fVidQualityMatrix selectedRow] != 0 || !SuccessfulScan ) + { + return; + } + + hb_list_t * list = hb_get_titles( fHandle ); + hb_title_t * title = (hb_title_t *) hb_list_item( list, + [fSrcTitlePopUp indexOfSelectedItem] ); + hb_job_t * job = title->job; + + [self prepareJob]; + + [fVidBitrateField setIntValue: hb_calc_bitrate( job, + [fVidTargetSizeField intValue] )]; +} + +#pragma mark - +#pragma mark - Picture + +/* lets set the picture size back to the max from right after title scan + Lets use an IBAction here as down the road we could always use a checkbox + in the gui to easily take the user back to max. Remember, the compiler + resolves IBActions down to -(void) during compile anyway */ +- (IBAction) revertPictureSizeToMax: (id) sender +{ + hb_job_t * job = fTitle->job; + /* We use the output picture width and height + as calculated from libhb right after title is set + in TitlePopUpChanged */ + job->width = PicOrigOutputWidth; + job->height = PicOrigOutputHeight; + [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; + + + [self calculatePictureSizing: sender]; + /* We call method method to change UI to reflect whether a preset is used or not*/ + [self customSettingUsed: sender]; +} + +/** + * Registers changes made in the Picture Settings Window. + */ + +- (void)pictureSettingsDidChange { + [self calculatePictureSizing: NULL]; +} + +/* Get and Display Current Pic Settings in main window */ +- (IBAction) calculatePictureSizing: (id) sender +{ + [fPicSettingWidth setStringValue: [NSString stringWithFormat:@"%d", fTitle->job->width]]; + [fPicSettingHeight setStringValue: [NSString stringWithFormat:@"%d", fTitle->job->height]]; + + if (fTitle->job->pixel_ratio == 1) + { + 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]; + + [fPicSettingWidth setStringValue: [NSString stringWithFormat:@"%d", titlewidth]]; + [fPicSettingHeight setStringValue: [NSString stringWithFormat:@"%d", displayparheight]]; + [fPicLabelPAROutputX setStringValue: @"x"]; + [fPicSettingPARWidth setStringValue: [NSString stringWithFormat:@"%d", displayparwidth]]; + [fPicSettingPARHeight setStringValue: [NSString stringWithFormat:@"%d", displayparheight]]; + + fTitle->job->keep_ratio = 0; + } + else + { + [fPicLabelPAROutputX setStringValue: @""]; + [fPicSettingPARWidth setStringValue: @""]; + [fPicSettingPARHeight setStringValue: @""]; + } + + /* Set ON/Off values for the deinterlace/keep aspect ratio according to boolean */ + if (fTitle->job->keep_ratio > 0) + { + [fPicSettingARkeep setStringValue: @"On"]; + } + else + { + [fPicSettingARkeep setStringValue: @"Off"]; + } + /* Detelecine */ + if ([fPictureController detelecine]) { + [fPicSettingDetelecine setStringValue: @"Yes"]; + } + else { + [fPicSettingDetelecine setStringValue: @"No"]; + } + + /* VFR (Variable Frame Rate) */ + if ([fPictureController vfr]) { + /* vfr has to set the framerate to 29.97 (ntsc video) + and disable the framerate popup */ + [fVidRatePopUp selectItemAtIndex: 8]; + [fVidRatePopUp setEnabled: NO]; + /* We change the string of the fps popup to warn that vfr is on Framerate (FPS): */ + [fVidRateField setStringValue: @"Framerate (VFR On):"]; + + } + else { + /* vfr is off, make sure the framerate popup is enabled */ + [fVidRatePopUp setEnabled: YES]; + /* and make sure the label for framerate is set to its default */ + [fVidRateField setStringValue: @"Framerate (FPS):"]; + } + + /* 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"]; + } + else if ([fPictureController deinterlace] ==4) + { + [fPicSettingDeinterlace setStringValue: @"Slowest"]; + } + /* Denoise */ + if ([fPictureController denoise] == 0) + { + [fPicSettingDenoise setStringValue: @"Off"]; + } + else if ([fPictureController denoise] == 1) + { + [fPicSettingDenoise setStringValue: @"Weak"]; + } + else if ([fPictureController denoise] == 2) + { + [fPicSettingDenoise setStringValue: @"Medium"]; + } + else if ([fPictureController denoise] == 3) + { + [fPicSettingDenoise setStringValue: @"Strong"]; + } + + /* Deblock */ + if ([fPictureController deblock]) { + [fPicSettingDeblock setStringValue: @"Yes"]; + } + else { + [fPicSettingDeblock setStringValue: @"No"]; + } + + 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"]; + } + + +} + + +#pragma mark - +#pragma mark - Audio and Subtitles + +- (IBAction) setEnabledStateOfAudioMixdownControls: (id) sender +{ + + /* enable/disable the mixdown text and popupbutton for audio track 1 */ + [fAudTrack1MixPopUp setEnabled: ([fAudLang1PopUp indexOfSelectedItem] == 0) ? NO : YES]; + [fAudTrack1MixLabel setTextColor: ([fAudLang1PopUp indexOfSelectedItem] == 0) ? + [NSColor disabledControlTextColor] : [NSColor controlTextColor]]; + + /* enable/disable the mixdown text and popupbutton for audio track 2 */ + [fAudTrack2MixPopUp setEnabled: ([fAudLang2PopUp indexOfSelectedItem] == 0) ? NO : YES]; + [fAudTrack2MixLabel setTextColor: ([fAudLang2PopUp indexOfSelectedItem] == 0) ? + [NSColor disabledControlTextColor] : [NSColor controlTextColor]]; + +} + +- (IBAction) addAllAudioTracksToPopUp: (id) sender +{ + + hb_list_t * list = hb_get_titles( fHandle ); + hb_title_t * title = (hb_title_t*) + hb_list_item( list, [fSrcTitlePopUp indexOfSelectedItem] ); + + hb_audio_t * audio; + + [sender removeAllItems]; + [sender addItemWithTitle: _( @"None" )]; + for( int i = 0; i < hb_list_count( title->list_audio ); i++ ) + { + audio = (hb_audio_t *) hb_list_item( title->list_audio, i ); + [[sender menu] addItemWithTitle: + [NSString stringWithCString: audio->lang] + action: NULL keyEquivalent: @""]; } [sender selectItemAtIndex: 0]; } -- (IBAction) SelectAudioTrackInPopUp: (id) sender searchPrefixString: (NSString *) searchPrefixString selectIndexIfNotFound: (int) selectIndexIfNotFound +- (IBAction) selectAudioTrackInPopUp: (id) sender searchPrefixString: (NSString *) searchPrefixString selectIndexIfNotFound: (int) selectIndexIfNotFound { /* this method can be used to find a language, or a language-and-source-format combination, by passing in the appropriate string */ @@ -2039,13 +2701,13 @@ list = hb_get_titles( fHandle ); } -- (IBAction) AudioTrackPopUpChanged: (id) sender +- (IBAction) audioTrackPopUpChanged: (id) sender { - /* utility function to call AudioTrackPopUpChanged without passing in a mixdown-to-use */ - [self AudioTrackPopUpChanged: sender mixdownToUse: 0]; + /* utility function to call audioTrackPopUpChanged without passing in a mixdown-to-use */ + [self audioTrackPopUpChanged: sender mixdownToUse: 0]; } -- (IBAction) AudioTrackPopUpChanged: (id) sender mixdownToUse: (int) mixdownToUse +- (IBAction) audioTrackPopUpChanged: (id) sender mixdownToUse: (int) mixdownToUse { /* make sure we have a selected title before continuing */ @@ -2067,7 +2729,7 @@ list = hb_get_titles( fHandle ); /* unless, of course, both are selected as "none!" */ if ([thisAudioPopUp indexOfSelectedItem] != 0 && [thisAudioPopUp indexOfSelectedItem] == [otherAudioPopUp indexOfSelectedItem]) { [otherAudioPopUp selectItemAtIndex: 0]; - [self AudioTrackPopUpChanged: otherAudioPopUp]; + [self audioTrackPopUpChanged: otherAudioPopUp]; } /* pointer for the hb_audio_s struct we will use later on */ @@ -2098,7 +2760,7 @@ list = hb_get_titles( fHandle ); [mixdownPopUp removeAllItems]; /* check if the audio mixdown controls need their enabled state changing */ - [self SetEnabledStateOfAudioMixdownControls: NULL]; + [self setEnabledStateOfAudioMixdownControls: NULL]; if (thisAudioIndex != -1) { @@ -2116,7 +2778,8 @@ list = hb_get_titles( fHandle ); int audioCodecsSupportMono = ((audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA) && acodec == HB_ACODEC_FAAC); int audioCodecsSupport6Ch = ((audio->codec == HB_ACODEC_AC3 || - audio->codec == HB_ACODEC_DCA) && acodec == HB_ACODEC_FAAC); + audio->codec == HB_ACODEC_DCA) && (acodec == HB_ACODEC_FAAC || + acodec == HB_ACODEC_VORBIS)); /* check for AC-3 passthru */ if (audio->codec == HB_ACODEC_AC3 && acodec == HB_ACODEC_AC3) @@ -2216,8 +2879,8 @@ list = hb_get_titles( fHandle ); /* select the (possibly-amended) preferred mixdown */ [mixdownPopUp selectItemWithTag: useMixdown]; - /* lets call the AudioTrackMixdownChanged method here to determine appropriate bitrates, etc. */ - [self AudioTrackMixdownChanged: NULL]; + /* lets call the audioTrackMixdownChanged method here to determine appropriate bitrates, etc. */ + [self audioTrackMixdownChanged: NULL]; } } @@ -2225,10 +2888,10 @@ list = hb_get_titles( fHandle ); } /* see if the new audio track choice will change the bitrate we need */ - [self CalculateBitrate: sender]; + [self calculateBitrate: sender]; } -- (IBAction) AudioTrackMixdownChanged: (id) sender +- (IBAction) audioTrackMixdownChanged: (id) sender { /* find out what the currently-selected output audio codec is */ @@ -2270,11 +2933,22 @@ list = hb_get_titles( fHandle ); break; case HB_ACODEC_VORBIS: + if ([[fAudTrack1MixPopUp selectedItem] tag] == HB_AMIXDOWN_6CH || [[fAudTrack2MixPopUp selectedItem] tag] == HB_AMIXDOWN_6CH) + { + /* Vorbis causes a crash if we use a bitrate below 192 kbps with 6 channel */ + minbitrate = 192; + /* If either mixdown popup includes 6-channel discrete, then allow up to 384 kbps */ + maxbitrate = 384; + break; + } + else + { /* Vorbis causes a crash if we use a bitrate below 48 kbps */ minbitrate = 48; /* Vorbis can cope with 384 kbps quite happily, even for stereo */ maxbitrate = 384; break; + } default: /* AC3 passthru disables the bitrate dropdown anyway, so we might as well just use the min and max bitrate */ @@ -2309,1213 +2983,450 @@ list = hb_get_titles( fHandle ); } } -/* lets set the picture size back to the max from right after title scan - Lets use an IBAction here as down the road we could always use a checkbox - in the gui to easily take the user back to max. Remember, the compiler - resolves IBActions down to -(void) during compile anyway */ -- (IBAction) RevertPictureSizeToMax: (id) sender -{ - hb_job_t * job = fTitle->job; - /* We use the output picture width and height - as calculated from libhb right after title is set - in TitlePopUpChanged */ - job->width = PicOrigOutputWidth; - job->height = PicOrigOutputHeight; - [fPicSettingAutoCrop setStringValue: [NSString stringWithFormat: - @"%d", 1]]; - /* 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; - - - [self CalculatePictureSizing: sender]; - /* We call method method to change UI to reflect whether a preset is used or not*/ - [self CustomSettingUsed: sender]; -} - -/* Get and Display Current Pic Settings in main window */ -- (IBAction) CalculatePictureSizing: (id) sender +- (IBAction) subtitleSelectionChanged: (id) sender { - - - [fPicSettingWidth setStringValue: [NSString stringWithFormat: - @"%d", fTitle->job->width]]; - [fPicSettingHeight setStringValue: [NSString stringWithFormat: - @"%d", fTitle->job->height]]; - [fPicSettingARkeep setStringValue: [NSString stringWithFormat: - @"%d", fTitle->job->keep_ratio]]; - [fPicSettingDeinterlace setStringValue: [NSString stringWithFormat: - @"%d", fTitle->job->deinterlace]]; - [fPicSettingPAR setStringValue: [NSString stringWithFormat: - @"%d", fTitle->job->pixel_ratio]]; - - if (fTitle->job->pixel_ratio == 1) - { - 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]; - [fPicSettingWidth setStringValue: [NSString stringWithFormat: - @"%d", titlewidth]]; - [fPicSettingHeight setStringValue: [NSString stringWithFormat: - @"%d", displayparheight]]; - [fPicLabelPAROutp setStringValue: @"Anamorphic Output:"]; - [fPicLabelPAROutputX setStringValue: @"x"]; - [fPicSettingPARWidth setStringValue: [NSString stringWithFormat: - @"%d", displayparwidth]]; - [fPicSettingPARHeight setStringValue: [NSString stringWithFormat: - @"%d", displayparheight]]; - - fTitle->job->keep_ratio = 0; - } - else - { - [fPicLabelPAROutp setStringValue: @""]; - [fPicLabelPAROutputX setStringValue: @""]; - [fPicSettingPARWidth setStringValue: @""]; - [fPicSettingPARHeight setStringValue: @""]; - } - - /* Set ON/Off values for the deinterlace/keep aspect ratio according to boolean */ - if (fTitle->job->keep_ratio > 0) - { - [fPicSettingARkeepDsply setStringValue: @"On"]; - } - else - { - [fPicSettingARkeepDsply setStringValue: @"Off"]; - } - if (fTitle->job->deinterlace > 0) - { - [fPicSettingDeinterlaceDsply setStringValue: @"On"]; - } - else - { - [fPicSettingDeinterlaceDsply setStringValue: @"Off"]; - } - if (fTitle->job->pixel_ratio > 0) + if ([fSubPopUp indexOfSelectedItem] == 0) { - [fPicSettingPARDsply setStringValue: @"On"]; + [fSubForcedCheck setState: NSOffState]; + [fSubForcedCheck setEnabled: NO]; } else { - [fPicSettingPARDsply setStringValue: @"Off"]; + [fSubForcedCheck setEnabled: YES]; } - /* Set the display field for crop as per boolean */ - if ([[fPicSettingAutoCrop stringValue] isEqualToString: @"0"]) - { - [fPicSettingAutoCropDsply setStringValue: @"Custom"]; - } - else - { - [fPicSettingAutoCropDsply setStringValue: @"Auto"]; - } - /* below will trigger the preset, if selected, to be - changed to "Custom". Lets comment out for now until - we figure out a way to determine if the picture values - changed modify the preset values */ - //[self CustomSettingUsed: sender]; } -- (IBAction) CalculateBitrate: (id) sender -{ - if( !fHandle || [fVidQualityMatrix selectedRow] != 0 ) - { - return; - } - hb_list_t * list = hb_get_titles( fHandle ); - hb_title_t * title = (hb_title_t *) hb_list_item( list, - [fSrcTitlePopUp indexOfSelectedItem] ); - hb_job_t * job = title->job; - [self PrepareJob]; - [fVidBitrateField setIntValue: hb_calc_bitrate( job, - [fVidTargetSizeField intValue] )]; - - +#pragma mark - +#pragma mark Open New Windows + +- (IBAction) openHomepage: (id) sender +{ + [[NSWorkspace sharedWorkspace] openURL: [NSURL + URLWithString:@"http://handbrake.m0k.org/"]]; } -/* Method to determine if we should change the UI -To reflect whether or not a Preset is being used or if -the user is using "Custom" settings by determining the sender*/ -- (IBAction) CustomSettingUsed: (id) sender +- (IBAction) openForums: (id) sender { - if ([sender stringValue] != NULL) - { - /* Deselect the currently selected Preset if there is one*/ - [tableView deselectRow:[tableView selectedRow]]; - [fPresetMakeDefault setEnabled: NO]; - /* Change UI to show "Custom" settings are being used */ - [fPresetSelectedDisplay setStringValue: @"Custom"]; - - curUserPresetChosenNum = nil; + [[NSWorkspace sharedWorkspace] openURL: [NSURL + URLWithString:@"http://handbrake.m0k.org/forum/"]]; +} +- (IBAction) openUserGuide: (id) sender +{ + [[NSWorkspace sharedWorkspace] openURL: [NSURL + URLWithString:@"http://handbrake.m0k.org/trac/wiki/HandBrakeGuide"]]; +} - - } +/** + * Shows debug output window. + */ +- (IBAction)showDebugOutputPanel:(id)sender +{ + [outputPanel showOutputPanel:sender]; +} + +/** + * Shows preferences window. + */ +- (IBAction) showPreferencesWindow: (id) sender +{ + NSWindow * window = [fPreferencesController window]; + if (![window isVisible]) + [window center]; + [window makeKeyAndOrderFront: nil]; } -- (IBAction) X264AdvancedOptionsSet: (id) sender +/** + * Shows queue window. + */ +- (IBAction) showQueueWindow:(id)sender { - /*Set opt widget values here*/ - - /*B-Frames fX264optBframesPopUp*/ - int i; - [fX264optBframesPopUp removeAllItems]; - [fX264optBframesPopUp addItemWithTitle:@"Default (0)"]; - for (i=0; i<17;i++) - { - [fX264optBframesPopUp addItemWithTitle:[NSString stringWithFormat:@"%d",i]]; - } - - /*Reference Frames fX264optRefPopUp*/ - [fX264optRefPopUp removeAllItems]; - [fX264optRefPopUp addItemWithTitle:@"Default (1)"]; - for (i=0; i<17;i++) - { - [fX264optRefPopUp addItemWithTitle:[NSString stringWithFormat:@"%d",i]]; - } - - /*No Fast P-Skip fX264optNfpskipSwitch BOOLEAN*/ - [fX264optNfpskipSwitch setState:0]; - - /*No Dict Decimate fX264optNodctdcmtSwitch BOOLEAN*/ - [fX264optNodctdcmtSwitch setState:0]; + [fQueueController showQueueWindow:sender]; +} - /*Sub Me fX264optSubmePopUp*/ - [fX264optSubmePopUp removeAllItems]; - [fX264optSubmePopUp addItemWithTitle:@"Default (4)"]; - for (i=0; i<8;i++) - { - [fX264optSubmePopUp addItemWithTitle:[NSString stringWithFormat:@"%d",i]]; - } - - /*Trellis fX264optTrellisPopUp*/ - [fX264optTrellisPopUp removeAllItems]; - [fX264optTrellisPopUp addItemWithTitle:@"Default (0)"]; - for (i=0; i<3;i++) - { - [fX264optTrellisPopUp addItemWithTitle:[NSString stringWithFormat:@"%d",i]]; - } - - /*Mixed-references fX264optMixedRefsSwitch BOOLEAN*/ - [fX264optMixedRefsSwitch setState:0]; - - /*Motion Estimation fX264optMotionEstPopUp*/ - [fX264optMotionEstPopUp removeAllItems]; - [fX264optMotionEstPopUp addItemWithTitle:@"Default (Hexagon)"]; - [fX264optMotionEstPopUp addItemWithTitle:@"Diamond"]; - [fX264optMotionEstPopUp addItemWithTitle:@"Hexagon"]; - [fX264optMotionEstPopUp addItemWithTitle:@"Uneven Multi-Hexagon"]; - [fX264optMotionEstPopUp addItemWithTitle:@"Exhaustive"]; - - /*Motion Estimation range fX264optMERangePopUp*/ - [fX264optMERangePopUp removeAllItems]; - [fX264optMERangePopUp addItemWithTitle:@"Default (16)"]; - for (i=4; i<65;i++) - { - [fX264optMERangePopUp addItemWithTitle:[NSString stringWithFormat:@"%d",i]]; - } - - /*Weighted B-Frame Prediction fX264optWeightBSwitch BOOLEAN*/ - [fX264optWeightBSwitch setState:0]; - - /*B-Frame Rate Distortion Optimization fX264optBRDOSwitch BOOLEAN*/ - [fX264optBRDOSwitch setState:0]; - - /*B-frame Pyramids fX264optBPyramidSwitch BOOLEAN*/ - [fX264optBPyramidSwitch setState:0]; - - /*Bidirectional Motion Estimation Refinement fX264optBiMESwitch BOOLEAN*/ - [fX264optBiMESwitch setState:0]; - - /*Direct B-Frame Prediction Mode fX264optDirectPredPopUp*/ - [fX264optDirectPredPopUp removeAllItems]; - [fX264optDirectPredPopUp addItemWithTitle:@"Default (Spatial)"]; - [fX264optDirectPredPopUp addItemWithTitle:@"None"]; - [fX264optDirectPredPopUp addItemWithTitle:@"Spatial"]; - [fX264optDirectPredPopUp addItemWithTitle:@"Temporal"]; - [fX264optDirectPredPopUp addItemWithTitle:@"Automatic"]; - - /*Alpha Deblock*/ - [fX264optAlphaDeblockPopUp removeAllItems]; - [fX264optAlphaDeblockPopUp addItemWithTitle:@"Default (0)"]; - for (i=-6; i<7;i++) - { - [fX264optAlphaDeblockPopUp addItemWithTitle:[NSString stringWithFormat:@"%d",i]]; - } - - /*Beta Deblock*/ - [fX264optBetaDeblockPopUp removeAllItems]; - [fX264optBetaDeblockPopUp addItemWithTitle:@"Default (0)"]; - for (i=-6; i<7;i++) - { - [fX264optBetaDeblockPopUp addItemWithTitle:[NSString stringWithFormat:@"%d",i]]; - } - - /* Analysis fX264optAnalysePopUp */ - [fX264optAnalysePopUp removeAllItems]; - [fX264optAnalysePopUp addItemWithTitle:@"Default (some)"]; /* 0=default */ - [fX264optAnalysePopUp addItemWithTitle:[NSString stringWithFormat:@"None"]]; /* 1=none */ - [fX264optAnalysePopUp addItemWithTitle:[NSString stringWithFormat:@"All"]]; /* 2=all */ - - /* 8x8 DCT fX264op8x8dctSwitch */ - [fX264opt8x8dctSwitch setState:0]; - - /* CABAC fX264opCabacSwitch */ - [fX264optCabacSwitch setState:1]; - /* Standardize the option string */ - [self X264AdvancedOptionsStandardizeOptString: NULL]; - /* Set Current GUI Settings based on newly standardized string */ - [self X264AdvancedOptionsSetCurrentSettings: NULL]; +- (IBAction) toggleDrawer:(id)sender { + [fPresetDrawer toggle:self]; } -- (IBAction) X264AdvancedOptionsStandardizeOptString: (id) sender +/** + * Shows Picture Settings Window. + */ + +- (IBAction) showPicturePanel: (id) sender { - /* Set widgets depending on the opt string in field */ - NSString * thisOpt; // The separated option such as "bframes=3" - NSString * optName = @""; // The option name such as "bframes" - NSString * optValue = @"";// The option value such as "3" - NSString * changedOptString = @""; - NSArray *currentOptsArray; - - /*First, we get an opt string to process */ - NSString *currentOptString = [fDisplayX264Options stringValue]; - - /*verify there is an opt string to process */ - NSRange currentOptRange = [currentOptString rangeOfString:@"="]; - if (currentOptRange.location != NSNotFound) - { - /*Put individual options into an array based on the ":" separator for processing, result is "="*/ - currentOptsArray = [currentOptString componentsSeparatedByString:@":"]; - - /*iterate through the array and get and = 0) + { + /* we get the chosen preset from the UserPresets array */ + chosenPreset = [UserPresets objectAtIndex:[tableView selectedRow]]; + curUserPresetChosenNum = [sender selectedRow]; + /* we set the preset display field in main window here */ + [fPresetSelectedDisplay setStringValue: [NSString stringWithFormat: @"%@",[chosenPreset valueForKey:@"PresetName"]]]; + if ([[chosenPreset objectForKey:@"Default"] intValue] == 1) + { + [fPresetSelectedDisplay setStringValue: [NSString stringWithFormat: @"%@ (Default)",[chosenPreset valueForKey:@"PresetName"]]]; + } + else + { + [fPresetSelectedDisplay setStringValue: [NSString stringWithFormat: @"%@",[chosenPreset valueForKey:@"PresetName"]]]; + } + /* File Format */ + [fDstFormatPopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"FileFormat"]]]; + [self formatPopUpChanged: NULL]; + + /* Chapter Markers*/ + [fCreateChapterMarkers setState:[[chosenPreset objectForKey:@"ChapterMarkers"] intValue]]; + /* Allow Mpeg4 64 bit formatting +4GB file sizes */ + [fDstMpgLargeFileCheck setState:[[chosenPreset objectForKey:@"Mp4LargeFile"] intValue]]; + /* Codecs */ + [fDstCodecsPopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"FileCodecs"]]]; + [self codecsPopUpChanged: NULL]; + /* Video encoder */ + [fVidEncoderPopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"VideoEncoder"]]]; + + /* We can show the preset options here in the gui if we want to + so we check to see it the user has specified it in the prefs */ + [fAdvancedOptions setOptions: [NSString stringWithFormat:[chosenPreset valueForKey:@"x264Option"]]]; + + /* Lets run through the following functions to get variables set there */ + [self encoderPopUpChanged: NULL]; + + [self calculateBitrate: NULL]; + + /* Video quality */ + [fVidQualityMatrix selectCellAtRow:[[chosenPreset objectForKey:@"VideoQualityType"] intValue] column:0]; + + [fVidTargetSizeField setStringValue: [NSString stringWithFormat:[chosenPreset valueForKey:@"VideoTargetSize"]]]; + [fVidBitrateField setStringValue: [NSString stringWithFormat:[chosenPreset valueForKey:@"VideoAvgBitrate"]]]; + + [fVidQualitySlider setFloatValue: [[chosenPreset valueForKey:@"VideoQualitySlider"] floatValue]]; + [self videoMatrixChanged: NULL]; + + /* Video framerate */ + /* For video preset video framerate, we want to make sure that Same as source does not conflict with the + detected framerate in the fVidRatePopUp so we use index 0*/ + if ([[NSString stringWithFormat:[chosenPreset valueForKey:@"VideoFramerate"]] isEqualToString: @"Same as source"]) { - changedOptString = [NSString stringWithFormat:@"%@%@",changedOptString,thisOpt]; + [fVidRatePopUp selectItemAtIndex: 0]; } else { - if ([changedOptString isEqualToString:@""]) - { - changedOptString = [NSString stringWithFormat:@"%@",thisOpt]; - } - else - { - changedOptString = [NSString stringWithFormat:@"%@:%@",changedOptString,thisOpt]; - } + [fVidRatePopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"VideoFramerate"]]]; } - } - } - - /* Change the option string to reflect the new standardized option string */ - [fDisplayX264Options setStringValue:[NSString stringWithFormat:changedOptString]]; + + /* GrayScale */ + [fVidGrayscaleCheck setState:[[chosenPreset objectForKey:@"VideoGrayScale"] intValue]]; + + /* 2 Pass Encoding */ + [fVidTwoPassCheck setState:[[chosenPreset objectForKey:@"VideoTwoPass"] intValue]]; + [self twoPassCheckboxChanged: NULL]; + /* Turbo 1st pass for 2 Pass Encoding */ + [fVidTurboPassCheck setState:[[chosenPreset objectForKey:@"VideoTurboTwoPass"] intValue]]; + + /*Audio*/ + + /* Audio Sample Rate*/ + [fAudRatePopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"AudioSampleRate"]]]; + /* Audio Bitrate Rate*/ + [fAudBitratePopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"AudioBitRate"]]]; + /*Subtitles*/ + [fSubPopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"Subtitles"]]]; + + /* Picture Settings */ + /* Look to see if we apply these here in objectForKey:@"UsesPictureSettings"] */ + if ([[chosenPreset objectForKey:@"UsesPictureSettings"] intValue] > 0) + { + hb_job_t * job = fTitle->job; + /* Check to see if we should use the max picture setting for the current title*/ + if ([[chosenPreset objectForKey:@"UsesPictureSettings"] intValue] == 2 || [[chosenPreset objectForKey:@"UsesMaxPictureSettings"] intValue] == 1) + { + /* Use Max Picture settings for whatever the dvd is.*/ + [self revertPictureSizeToMax: NULL]; + job->keep_ratio = [[chosenPreset objectForKey:@"PictureKeepRatio"] intValue]; + if (job->keep_ratio == 1) + { + hb_fix_aspect( job, HB_KEEP_WIDTH ); + if( job->height > fTitle->height ) + { + job->height = fTitle->height; + hb_fix_aspect( job, HB_KEEP_HEIGHT ); + } + } + job->pixel_ratio = [[chosenPreset objectForKey:@"PicturePAR"] intValue]; + } + else // Apply picture settings that were in effect at the time the preset was saved + { + job->width = [[chosenPreset objectForKey:@"PictureWidth"] intValue]; + job->height = [[chosenPreset objectForKey:@"PictureHeight"] intValue]; + job->keep_ratio = [[chosenPreset objectForKey:@"PictureKeepRatio"] intValue]; + if (job->keep_ratio == 1) + { + hb_fix_aspect( job, HB_KEEP_WIDTH ); + if( job->height > fTitle->height ) + { + job->height = fTitle->height; + hb_fix_aspect( job, HB_KEEP_HEIGHT ); + } + } + job->pixel_ratio = [[chosenPreset objectForKey:@"PicturePAR"] intValue]; + + /* Filters */ + [fPictureController setDeinterlace:[[chosenPreset objectForKey:@"PictureDeinterlace"] intValue]]; + + if ([chosenPreset objectForKey:@"PictureDetelecine"]) + { + [fPictureController setDetelecine:[[chosenPreset objectForKey:@"PictureDetelecine"] intValue]]; + } + if ([chosenPreset objectForKey:@"PictureDenoise"]) + { + [fPictureController setDenoise:[[chosenPreset objectForKey:@"PictureDenoise"] intValue]]; + } + if ([chosenPreset objectForKey:@"PictureDeblock"]) + { + [fPictureController setDeblock:[[chosenPreset objectForKey:@"PictureDeblock"] intValue]]; + } + /* 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; + + } + } + [self calculatePictureSizing: NULL]; + } + + + [[fPresetsActionMenu itemAtIndex:0] setEnabled: YES]; + } } +} + -- (NSString *) X264AdvancedOptionsStandardizeOptNames:(NSString *) cleanOptNameString + +- (int)numberOfRowsInTableView:(NSTableView *)aTableView { - if ([cleanOptNameString isEqualToString:@"ref"] || [cleanOptNameString isEqualToString:@"frameref"]) - { - cleanOptNameString = @"ref"; - } - - /*No Fast PSkip nofast_pskip*/ - if ([cleanOptNameString isEqualToString:@"no-fast-pskip"] || [cleanOptNameString isEqualToString:@"no_fast_pskip"] || [cleanOptNameString isEqualToString:@"nofast_pskip"]) - { - cleanOptNameString = @"no-fast-pskip"; - } - - /*No Dict Decimate*/ - if ([cleanOptNameString isEqualToString:@"no-dct-decimate"] || [cleanOptNameString isEqualToString:@"no_dct_decimate"] || [cleanOptNameString isEqualToString:@"nodct_decimate"]) - { - cleanOptNameString = @"no-dct-decimate"; - } - - /*Subme*/ - if ([cleanOptNameString isEqualToString:@"subme"]) - { - cleanOptNameString = @"subq"; - } - - /*ME Range*/ - if ([cleanOptNameString isEqualToString:@"me-range"] || [cleanOptNameString isEqualToString:@"me_range"]) - cleanOptNameString = @"merange"; - - /*WeightB*/ - if ([cleanOptNameString isEqualToString:@"weight-b"] || [cleanOptNameString isEqualToString:@"weight_b"]) - { - cleanOptNameString = @"weightb"; - } - - /*BRDO*/ - if ([cleanOptNameString isEqualToString:@"b-rdo"] || [cleanOptNameString isEqualToString:@"b_rdo"]) - { - cleanOptNameString = @"brdo"; - } - - /*B Pyramid*/ - if ([cleanOptNameString isEqualToString:@"b_pyramid"]) - { - cleanOptNameString = @"b-pyramid"; - } - - /*Direct Prediction*/ - if ([cleanOptNameString isEqualToString:@"direct-pred"] || [cleanOptNameString isEqualToString:@"direct_pred"]) - { - cleanOptNameString = @"direct"; - } - - /*Deblocking*/ - if ([cleanOptNameString isEqualToString:@"filter"]) - { - cleanOptNameString = @"deblock"; - } + return [UserPresets count]; +} - /*Analysis*/ - if ([cleanOptNameString isEqualToString:@"partitions"]) - { - cleanOptNameString = @"analyse"; - } +/* we use this to determine display characteristics for +each table cell based on content currently only used to +show the built in presets in a blue font. */ +- (void)tableView:(NSTableView *)aTableView + willDisplayCell:(id)aCell + forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex +{ + NSDictionary *userPresetDict = [UserPresets objectAtIndex:rowIndex]; + NSFont *txtFont; + NSColor *fontColor; + NSColor *shadowColor; + txtFont = [NSFont systemFontOfSize: [NSFont smallSystemFontSize]]; + /* First, we check to see if its a selected row, if so, we use white since its highlighted in blue */ + if ([[aTableView selectedRowIndexes] containsIndex:rowIndex] && ([tableView editedRow] != rowIndex)) + { + + fontColor = [NSColor whiteColor]; + shadowColor = [NSColor colorWithDeviceRed:(127.0/255.0) green:(140.0/255.0) blue:(160.0/255.0) alpha:1.0]; + } + else + { + /* We set the properties of unselected rows */ + /* if built-in preset (defined by "type" == 0) we use a blue font */ + if ([[userPresetDict objectForKey:@"Type"] intValue] == 0) + { + fontColor = [NSColor blueColor]; + } + else // User created preset, use a black font + { + fontColor = [NSColor blackColor]; + } + shadowColor = nil; + } + /* We check to see if this is the HB default, if so, color it appropriately */ + if (!presetUserDefault && presetHbDefault && rowIndex == presetHbDefault) + { + txtFont = [NSFont boldSystemFontOfSize: [NSFont smallSystemFontSize]]; + } + /* We check to see if this is the User Specified default, if so, color it appropriately */ + if (presetUserDefault && rowIndex == presetUserDefault) + { + txtFont = [NSFont boldSystemFontOfSize: [NSFont smallSystemFontSize]]; + } + + [aCell setTextColor:fontColor]; + [aCell setFont:txtFont]; + /* this shadow stuff (like mail app) for some reason looks crappy, commented out + temporarily in case we want to resurrect it */ + /* + NSShadow *shadow = [[NSShadow alloc] init]; + NSSize shadowOffset = { width: 1.0, height: -1.5}; + [shadow setShadowOffset:shadowOffset]; + [shadow setShadowColor:shadowColor]; + [shadow set]; + */ + +} +/* Method to display tooltip with the description for each preset, if available */ +- (NSString *)tableView:(NSTableView *)aTableView toolTipForCell:(NSCell *)aCell + rect:(NSRectPointer)aRect tableColumn:(NSTableColumn *)aTableColumn + row:(int)rowIndex mouseLocation:(NSPoint)aPos +{ + /* initialize the tooltip contents variable */ + NSString *loc_tip; + /* if there is a description for the preset, we show it in the tooltip */ + if ([[UserPresets objectAtIndex:rowIndex] valueForKey:@"PresetDescription"]) + { + loc_tip = [NSString stringWithFormat: @"%@",[[UserPresets objectAtIndex:rowIndex] valueForKey:@"PresetDescription"]]; + return (loc_tip); + } + else + { + loc_tip = @"No description available"; + } + return (loc_tip); - - return cleanOptNameString; } -- (IBAction) X264AdvancedOptionsSetCurrentSettings: (id) sender +- (id)tableView:(NSTableView *)aTableView + objectValueForTableColumn:(NSTableColumn *)aTableColumn + row:(int)rowIndex { - /* Set widgets depending on the opt string in field */ - NSString * thisOpt; // The separated option such as "bframes=3" - NSString * optName = @""; // The option name such as "bframes" - NSString * optValue = @"";// The option value such as "3" - NSArray *currentOptsArray; +id theRecord, theValue; - /*First, we get an opt string to process */ - //NSString *currentOptString = @"bframes=3:ref=1:subme=5:me=umh:no-fast-pskip=1:no-dct-decimate=1:trellis=2"; - NSString *currentOptString = [fDisplayX264Options stringValue]; + theRecord = [UserPresets objectAtIndex:rowIndex]; + theValue = [theRecord objectForKey:[aTableColumn identifier]]; + return theValue; +} + +// NSTableDataSource method that we implement to edit values directly in the table... +- (void)tableView:(NSTableView *)aTableView + setObjectValue:(id)anObject + forTableColumn:(NSTableColumn *)aTableColumn + row:(int)rowIndex +{ + id theRecord; - /*verify there is an opt string to process */ - NSRange currentOptRange = [currentOptString rangeOfString:@"="]; - if (currentOptRange.location != NSNotFound) - { - /* lets clean the opt string here to standardize any names*/ - /*Put individual options into an array based on the ":" separator for processing, result is "="*/ - currentOptsArray = [currentOptString componentsSeparatedByString:@":"]; - - /*iterate through the array and get and and "optNameToChange"=" to modify the option to - see if the name falls at the beginning of the line, where we would not have the ":" as a pattern to test against*/ - NSString *checkOptNameToChangeBeginning = [NSString stringWithFormat:@"%@=",optNameToChange]; - NSRange currentOptRangeBeginning = [currentOptString rangeOfString:checkOptNameToChangeBeginning]; - if (currentOptRange.location != NSNotFound || currentOptRangeBeginning.location == 0) - { - /* Create new empty opt string*/ - NSString *changedOptString = @""; - - /*Put individual options into an array based on the ":" separator for processing, result is "="*/ - currentOptsArray = [currentOptString componentsSeparatedByString:@":"]; - - /*iterate through the array and get and 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->deinterlace] forKey:@"PictureDeinterlace"]; + [preset setObject:[NSNumber numberWithInt:[fPictureController deinterlace]] forKey:@"PictureDeinterlace"]; [preset setObject:[NSNumber numberWithInt:fTitle->job->pixel_ratio] forKey:@"PicturePAR"]; + [preset setObject:[NSNumber numberWithInt:[fPictureController detelecine]] forKey:@"PictureDetelecine"]; + [preset setObject:[NSNumber numberWithInt:[fPictureController denoise]] forKey:@"PictureDenoise"]; + [preset setObject:[NSNumber numberWithInt:[fPictureController deblock]] forKey:@"PictureDeblock"]; + /* Set crop settings here */ /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */ - [preset setObject:[NSNumber numberWithInt:[fPicSettingAutoCrop intValue]] forKey:@"PictureAutoCrop"]; + [preset setObject:[NSNumber numberWithInt:[fPictureController autoCrop]] forKey:@"PictureAutoCrop"]; [preset setObject:[NSNumber numberWithInt:job->crop[0]] forKey:@"PictureTopCrop"]; [preset setObject:[NSNumber numberWithInt:job->crop[1]] forKey:@"PictureBottomCrop"]; @@ -3616,11 +3538,181 @@ the user is using "Custom" settings by determining the sender*/ } -- (NSDictionary *)CreateIpodLowPreset +- (void)savePreset +{ + [UserPresets writeToFile:UserPresetsFile atomically:YES]; + /* We get the default preset in case it changed */ + [self getDefaultPresets: NULL]; + +} + +- (IBAction)deletePreset:(id)sender +{ + int status; + NSEnumerator *enumerator; + NSNumber *index; + NSMutableArray *tempArray; + id tempObject; + + if ( [tableView numberOfSelectedRows] == 0 ) + return; + /* Alert user before deleting preset */ + /* Comment out for now, tie to user pref eventually */ + + //NSBeep(); + status = NSRunAlertPanel(@"Warning!", @"Are you sure that you want to delete the selected preset?", @"OK", @"Cancel", nil); + + if ( status == NSAlertDefaultReturn ) { + enumerator = [tableView selectedRowEnumerator]; + tempArray = [NSMutableArray array]; + + while ( (index = [enumerator nextObject]) ) { + tempObject = [UserPresets objectAtIndex:[index intValue]]; + [tempArray addObject:tempObject]; + } + + [UserPresets removeObjectsInArray:tempArray]; + [tableView reloadData]; + [self savePreset]; + } +} + +#pragma mark - +#pragma mark Manage Default Preset + +- (IBAction)getDefaultPresets:(id)sender +{ + int i = 0; + NSEnumerator *enumerator = [UserPresets objectEnumerator]; + id tempObject; + while (tempObject = [enumerator nextObject]) + { + NSDictionary *thisPresetDict = tempObject; + if ([[thisPresetDict objectForKey:@"Default"] intValue] == 1) // 1 is HB default + { + presetHbDefault = i; + } + if ([[thisPresetDict objectForKey:@"Default"] intValue] == 2) // 2 is User specified default + { + presetUserDefault = i; + } + i++; + } +} + +- (IBAction)setDefaultPreset:(id)sender +{ + int i = 0; + NSEnumerator *enumerator = [UserPresets objectEnumerator]; + id tempObject; + /* First make sure the old user specified default preset is removed */ + while (tempObject = [enumerator nextObject]) + { + /* make sure we are not removing the default HB preset */ + if ([[[UserPresets objectAtIndex:i] objectForKey:@"Default"] intValue] != 1) // 1 is HB default + { + [[UserPresets objectAtIndex:i] setObject:[NSNumber numberWithInt:0] forKey:@"Default"]; + } + i++; + } + /* Second, go ahead and set the appropriate user specfied preset */ + /* we get the chosen preset from the UserPresets array */ + if ([[[UserPresets objectAtIndex:[tableView selectedRow]] objectForKey:@"Default"] intValue] != 1) // 1 is HB default + { + [[UserPresets objectAtIndex:[tableView selectedRow]] setObject:[NSNumber numberWithInt:2] forKey:@"Default"]; + } + presetUserDefault = [tableView selectedRow]; + + /* We save all of the preset data here */ + [self savePreset]; + /* We Reload the New Table data for presets */ + [tableView reloadData]; +} + +- (IBAction)selectDefaultPreset:(id)sender +{ + /* if there is a user specified default, we use it */ + if (presetUserDefault) + { + [tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:presetUserDefault] byExtendingSelection:NO]; + [self tableViewSelected:NULL]; + } + else if (presetHbDefault) //else we use the built in default presetHbDefault + { + [tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:presetHbDefault] byExtendingSelection:NO]; + [self tableViewSelected:NULL]; + } +} + + +#pragma mark - +#pragma mark Manage Built In Presets + + +- (IBAction)deleteFactoryPresets:(id)sender +{ + //int status; + NSEnumerator *enumerator = [UserPresets objectEnumerator]; + id tempObject; + + //NSNumber *index; + NSMutableArray *tempArray; + + + tempArray = [NSMutableArray array]; + /* we look here to see if the preset is we move on to the next one */ + while ( tempObject = [enumerator nextObject] ) + { + /* if the preset is "Factory" then we put it in the array of + presets to delete */ + if ([[tempObject objectForKey:@"Type"] intValue] == 0) + { + [tempArray addObject:tempObject]; + } + } + + [UserPresets removeObjectsInArray:tempArray]; + [tableView reloadData]; + [self savePreset]; + +} + + /* We use this method to recreate new, updated factory + presets */ +- (IBAction)addFactoryPresets:(id)sender +{ + /* First, we delete any existing built in presets */ + [self deleteFactoryPresets: sender]; + /* Then, we re-create new built in presets programmatically CreateIpodOnlyPreset*/ + [UserPresets addObject:[self createNormalPreset]]; + [UserPresets addObject:[self createClassicPreset]]; + [UserPresets addObject:[self createQuickTimePreset]]; + [UserPresets addObject:[self createIpodLowPreset]]; + [UserPresets addObject:[self createIpodHighPreset]]; + [UserPresets addObject:[self createAppleTVPreset]]; + [UserPresets addObject:[self createiPhonePreset]]; + [UserPresets addObject:[self createPSThreePreset]]; + [UserPresets addObject:[self createPSPPreset]]; + [UserPresets addObject:[self createFilmPreset]]; + [UserPresets addObject:[self createTelevisionPreset]]; + [UserPresets addObject:[self createAnimationPreset]]; + [UserPresets addObject:[self createBedlamPreset]]; + [UserPresets addObject:[self createDeuxSixQuatrePreset]]; + [UserPresets addObject:[self createBrokePreset]]; + [UserPresets addObject:[self createBlindPreset]]; + [UserPresets addObject:[self createCRFPreset]]; + + [self addPreset]; +} + +#pragma mark - +#pragma mark Built In Preset Definitions +/* These NSDictionary Buit In Preset definitions contain all of the settings for one built in preset */ +- (NSDictionary *)createIpodLowPreset { NSMutableDictionary *preset = [[NSMutableDictionary alloc] init]; /* Get the New Preset Name from the field in the AddPresetPanel */ - [preset setObject:@"HB-iPod Low-Res" forKey:@"PresetName"]; + [preset setObject:@"iPod Low-Rez" forKey:@"PresetName"]; /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/ [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"]; /*Set whether or not this is default, at creation set to 0*/ @@ -3685,11 +3777,11 @@ the user is using "Custom" settings by determining the sender*/ } -- (NSDictionary *)CreateIpodHighPreset +- (NSDictionary *)createIpodHighPreset { NSMutableDictionary *preset = [[NSMutableDictionary alloc] init]; /* Get the New Preset Name from the field in the AddPresetPanel */ - [preset setObject:@"HB-iPod High-Res" forKey:@"PresetName"]; + [preset setObject:@"iPod High-Rez" forKey:@"PresetName"]; /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/ [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"]; /*Set whether or not this is default, at creation set to 0*/ @@ -3753,11 +3845,11 @@ the user is using "Custom" settings by determining the sender*/ } -- (NSDictionary *)CreateAppleTVPreset +- (NSDictionary *)createAppleTVPreset { NSMutableDictionary *preset = [[NSMutableDictionary alloc] init]; /* Get the New Preset Name from the field in the AddPresetPanel */ - [preset setObject:@"HB-AppleTV" forKey:@"PresetName"]; + [preset setObject:@"AppleTV" forKey:@"PresetName"]; /*Set whether or not this is a user preset where 0 is factory, 1 is user*/ [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"]; /*Set whether or not this is default, at creation set to 0*/ @@ -3775,7 +3867,7 @@ the user is using "Custom" settings by determining the sender*/ /* Video encoder */ [preset setObject:@"x264 (h.264 Main)" forKey:@"VideoEncoder"]; /* x264 Option String (We can use this to tweak the appleTV output)*/ - [preset setObject:@"bframes=3:ref=1:subme=5:me=umh:no-fast-pskip=1:trellis=2" forKey:@"x264Option"]; + [preset setObject:@"bframes=3:ref=1:subme=5:me=umh:no-fast-pskip=1:trellis=2:cabac=0" forKey:@"x264Option"]; /* Video quality */ [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"]; [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"]; @@ -3825,11 +3917,11 @@ the user is using "Custom" settings by determining the sender*/ } -- (NSDictionary *)CreatePSThreePreset +- (NSDictionary *)createPSThreePreset { NSMutableDictionary *preset = [[NSMutableDictionary alloc] init]; /* Get the New Preset Name from the field in the AddPresetPanel */ - [preset setObject:@"HB-PS3" forKey:@"PresetName"]; + [preset setObject:@"PS3" forKey:@"PresetName"]; /*Set whether or not this is a user preset where 0 is factory, 1 is user*/ [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"]; /*Set whether or not this is default, at creation set to 0*/ @@ -3841,7 +3933,7 @@ the user is using "Custom" settings by determining the sender*/ /* File Format */ [preset setObject:@"MP4 file" forKey:@"FileFormat"]; /* Chapter Markers*/ - [preset setObject:[NSNumber numberWithInt:1] forKey:@"ChapterMarkers"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"ChapterMarkers"]; /* Codecs */ [preset setObject:@"AVC/H.264 Video / AAC Audio" forKey:@"FileCodecs"]; /* Video encoder */ @@ -3893,11 +3985,11 @@ the user is using "Custom" settings by determining the sender*/ return preset; } -- (NSDictionary *)CreatePSPPreset +- (NSDictionary *)createPSPPreset { NSMutableDictionary *preset = [[NSMutableDictionary alloc] init]; /* Get the New Preset Name from the field in the AddPresetPanel */ - [preset setObject:@"HB-PSP" forKey:@"PresetName"]; + [preset setObject:@"PSP" forKey:@"PresetName"]; /*Set whether or not this is a user preset where 0 is factory, 1 is user*/ [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"]; /*Set whether or not this is default, at creation set to 0*/ @@ -3963,11 +4055,11 @@ the user is using "Custom" settings by determining the sender*/ } -- (NSDictionary *)CreateNormalPreset +- (NSDictionary *)createNormalPreset { NSMutableDictionary *preset = [[NSMutableDictionary alloc] init]; /* Get the New Preset Name from the field in the AddPresetPanel */ - [preset setObject:@"HB-Normal" forKey:@"PresetName"]; + [preset setObject:@"Normal" forKey:@"PresetName"]; /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/ [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"]; /*Set whether or not this is default, at creation set to 0*/ @@ -3985,7 +4077,7 @@ the user is using "Custom" settings by determining the sender*/ /* Video encoder */ [preset setObject:@"x264 (h.264 Main)" forKey:@"VideoEncoder"]; /* x264 Option String */ - [preset setObject:@"ref=2:mixed-refs:bframes=3:weightb:bime:direct=auto:subme=5:me=umh:trellis=1" forKey:@"x264Option"]; + [preset setObject:@"ref=2:bframes=2:subme=5:me=umh" forKey:@"x264Option"]; /* Video quality */ [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"]; [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"]; @@ -3998,6 +4090,7 @@ the user is using "Custom" settings by determining the sender*/ [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"]; /* 2 Pass Encoding */ [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTwoPass"]; + [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTurboTwoPass"]; /*Picture Settings*/ //hb_job_t * job = fTitle->job; @@ -4031,11 +4124,11 @@ the user is using "Custom" settings by determining the sender*/ } -- (NSDictionary *)CreateClassicPreset +- (NSDictionary *)createClassicPreset { NSMutableDictionary *preset = [[NSMutableDictionary alloc] init]; /* Get the New Preset Name from the field in the AddPresetPanel */ - [preset setObject:@"HB-Classic" forKey:@"PresetName"]; + [preset setObject:@"Classic" forKey:@"PresetName"]; /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/ [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"]; /*Set whether or not this is default, at creation set to 0*/ @@ -4099,11 +4192,11 @@ the user is using "Custom" settings by determining the sender*/ } -- (NSDictionary *)CreateFilmPreset +- (NSDictionary *)createFilmPreset { NSMutableDictionary *preset = [[NSMutableDictionary alloc] init]; /* Get the New Preset Name from the field in the AddPresetPanel */ - [preset setObject:@"HB-Film" forKey:@"PresetName"]; + [preset setObject:@"Film" forKey:@"PresetName"]; /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/ [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"]; /*Set whether or not this is default, at creation set to 0*/ @@ -4121,11 +4214,11 @@ the user is using "Custom" settings by determining the sender*/ /* Video encoder */ [preset setObject:@"x264 (h.264 Main)" forKey:@"VideoEncoder"]; /* x264 Option String */ - [preset setObject:@"ref=6:mixed-refs:bframes=3:bime:weightb:b-rdo:direct=auto:b-pyramid:me=umh:subme=7:me-range=24:analyse=all:8x8dct:trellis=2:no-fast-pskip" forKey:@"x264Option"]; + [preset setObject:@"ref=3:mixed-refs:bframes=16:bime:weightb:b-rdo:direct=auto:b-pyramid:me=umh:subme=6:analyse=all:8x8dct:trellis=1:no-fast-pskip" forKey:@"x264Option"]; /* Video quality */ [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"]; [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"]; - [preset setObject:@"2000" forKey:@"VideoAvgBitrate"]; + [preset setObject:@"1800" forKey:@"VideoAvgBitrate"]; [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"]; /* Video framerate */ @@ -4134,6 +4227,7 @@ the user is using "Custom" settings by determining the sender*/ [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"]; /* 2 Pass Encoding */ [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTwoPass"]; + [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTurboTwoPass"]; /*Picture Settings*/ //hb_job_t * job = fTitle->job; @@ -4167,11 +4261,11 @@ the user is using "Custom" settings by determining the sender*/ } -- (NSDictionary *)CreateTelevisionPreset +- (NSDictionary *)createTelevisionPreset { NSMutableDictionary *preset = [[NSMutableDictionary alloc] init]; /* Get the New Preset Name from the field in the AddPresetPanel */ - [preset setObject:@"HB-Television" forKey:@"PresetName"]; + [preset setObject:@"Television" forKey:@"PresetName"]; /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/ [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"]; /*Set whether or not this is default, at creation set to 0*/ @@ -4189,7 +4283,7 @@ the user is using "Custom" settings by determining the sender*/ /* Video encoder */ [preset setObject:@"x264 (h.264 Main)" forKey:@"VideoEncoder"]; /* x264 Option String */ - [preset setObject:@"ref=3:mixed-refs:bframes=9:bime:weightb:direct=auto:b-pyramid:me=umh:subme=6:me-range=24:analyse=all:8x8dct:trellis=2:nr=150:no-fast-pskip" forKey:@"x264Option"]; + [preset setObject:@"ref=3:mixed-refs:bframes=16:bime:weightb:direct=auto:b-pyramid:me=umh:subme=6:analyse=all:8x8dct:trellis=1:nr=150:no-fast-pskip" forKey:@"x264Option"]; /* Video quality */ [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"]; [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"]; @@ -4197,11 +4291,12 @@ the user is using "Custom" settings by determining the sender*/ [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"]; /* Video framerate */ - [preset setObject:@"29.97" forKey:@"VideoFramerate"]; + [preset setObject:@"Same as source" forKey:@"VideoFramerate"]; /* GrayScale */ [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"]; /* 2 Pass Encoding */ [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTwoPass"]; + [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTurboTwoPass"]; /*Picture Settings*/ //hb_job_t * job = fTitle->job; @@ -4235,11 +4330,11 @@ the user is using "Custom" settings by determining the sender*/ } -- (NSDictionary *)CreateAnimationPreset +- (NSDictionary *)createAnimationPreset { NSMutableDictionary *preset = [[NSMutableDictionary alloc] init]; /* Get the New Preset Name from the field in the AddPresetPanel */ - [preset setObject:@"HB-Animation" forKey:@"PresetName"]; + [preset setObject:@"Animation" forKey:@"PresetName"]; /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/ [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"]; /*Set whether or not this is default, at creation set to 0*/ @@ -4257,7 +4352,7 @@ the user is using "Custom" settings by determining the sender*/ /* Video encoder */ [preset setObject:@"x264 (h.264 Main)" forKey:@"VideoEncoder"]; /* x264 Option String */ - [preset setObject:@"ref=9:mixed-refs:bframes=13:bime:weightb:b-rdo:direct=auto:b-pyramid:me=umh:subme=7:me-range=24:analyse=all:8x8dct:trellis=2:nr=150:no-fast-pskip:filter=2,2" forKey:@"x264Option"]; + [preset setObject:@"ref=5:mixed-refs:bframes=16:bime:weightb:b-rdo:direct=auto:b-pyramid:me=umh:subme=5:analyse=all:8x8dct:trellis=1:nr=150:no-fast-pskip:filter=2,2" forKey:@"x264Option"]; /* Video quality */ [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"]; [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"]; @@ -4265,11 +4360,12 @@ the user is using "Custom" settings by determining the sender*/ [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"]; /* Video framerate */ - [preset setObject:@"29.97" forKey:@"VideoFramerate"]; + [preset setObject:@"Same as source" forKey:@"VideoFramerate"]; /* GrayScale */ [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"]; /* 2 Pass Encoding */ [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTwoPass"]; + [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTurboTwoPass"]; /*Picture Settings*/ //hb_job_t * job = fTitle->job; @@ -4303,11 +4399,11 @@ the user is using "Custom" settings by determining the sender*/ } -- (NSDictionary *)CreateQuickTimePreset +- (NSDictionary *)createQuickTimePreset { NSMutableDictionary *preset = [[NSMutableDictionary alloc] init]; /* Get the New Preset Name from the field in the AddPresetPanel */ - [preset setObject:@"HB-QuickTime" forKey:@"PresetName"]; + [preset setObject:@"QuickTime" forKey:@"PresetName"]; /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/ [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"]; /*Set whether or not this is default, at creation set to 0*/ @@ -4315,7 +4411,7 @@ the user is using "Custom" settings by determining the sender*/ /*Get the whether or not to apply pic settings in the AddPresetPanel*/ [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesPictureSettings"]; /* Get the New Preset Description from the field in the AddPresetPanel */ - [preset setObject:@"HandBrake's settings for use with QuickTime." forKey:@"PresetDescription"]; + [preset setObject:@"HandBrake's high quality settings for use with QuickTime. It can be slow, so use it when the Normal preset doesn't look good enough." forKey:@"PresetDescription"]; /* File Format */ [preset setObject:@"MP4 file" forKey:@"FileFormat"]; /* Chapter Markers*/ @@ -4325,7 +4421,7 @@ the user is using "Custom" settings by determining the sender*/ /* Video encoder */ [preset setObject:@"x264 (h.264 Main)" forKey:@"VideoEncoder"]; /* x264 Option String */ - [preset setObject:@"ref=6:mixed-refs:bframes=3:bime:weightb:b-rdo:direct-auto:me=umh:subme=7:me-range=24:analyse=all:8x8dct:trellis=2:no-fast-pskip" forKey:@"x264Option"]; + [preset setObject:@"ref=3:mixed-refs:bframes=3:bime:weightb:b-rdo:direct=auto:me=umh:subme=5:analyse=all:trellis=1:no-fast-pskip" forKey:@"x264Option"]; /* Video quality */ [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"]; [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"]; @@ -4338,6 +4434,7 @@ the user is using "Custom" settings by determining the sender*/ [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"]; /* 2 Pass Encoding */ [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTwoPass"]; + [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTurboTwoPass"]; /*Picture Settings*/ //hb_job_t * job = fTitle->job; @@ -4371,11 +4468,11 @@ the user is using "Custom" settings by determining the sender*/ } -- (NSDictionary *)CreateBedlamPreset +- (NSDictionary *)createBedlamPreset { NSMutableDictionary *preset = [[NSMutableDictionary alloc] init]; /* Get the New Preset Name from the field in the AddPresetPanel */ - [preset setObject:@"HB-Bedlam" forKey:@"PresetName"]; + [preset setObject:@"Bedlam" forKey:@"PresetName"]; /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/ [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"]; /*Set whether or not this is default, at creation set to 0*/ @@ -4393,7 +4490,7 @@ the user is using "Custom" settings by determining the sender*/ /* Video encoder */ [preset setObject:@"x264 (h.264 Main)" forKey:@"VideoEncoder"]; /* x264 Option String */ - [preset setObject:@"ref=16:mixed-refs:bframes=13:bime:weightb:b-rdo:direct=auto:b-pyramid:me=umh:subme=7:me-range=64:analyse=all:8x8dct:trellis=2:no-fast-pskip:no-dct-decimate:filter=-2,-1" forKey:@"x264Option"]; + [preset setObject:@"ref=16:mixed-refs:bframes=16:bime:weightb:b-rdo:direct=auto:b-pyramid:me=umh:subme=7:me-range=64:analyse=all:8x8dct:trellis=2:no-fast-pskip:no-dct-decimate:filter=-2,-1" forKey:@"x264Option"]; /* Video quality */ [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"]; [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"]; @@ -4406,6 +4503,7 @@ the user is using "Custom" settings by determining the sender*/ [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"]; /* 2 Pass Encoding */ [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTwoPass"]; + [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTurboTwoPass"]; /*Picture Settings*/ //hb_job_t * job = fTitle->job; @@ -4439,11 +4537,11 @@ the user is using "Custom" settings by determining the sender*/ } -- (NSDictionary *)CreateiPhonePreset +- (NSDictionary *)createiPhonePreset { NSMutableDictionary *preset = [[NSMutableDictionary alloc] init]; /* Get the New Preset Name from the field in the AddPresetPanel */ - [preset setObject:@"HB-iPhone" forKey:@"PresetName"]; + [preset setObject:@"iPhone / iPod Touch" forKey:@"PresetName"]; /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/ [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"]; /*Set whether or not this is default, at creation set to 0*/ @@ -4461,7 +4559,7 @@ the user is using "Custom" settings by determining the sender*/ /* Video encoder */ [preset setObject:@"x264 (h.264 iPod)" forKey:@"VideoEncoder"]; /* x264 Option String */ - [preset setObject:@"cabac=0:ref=1:analyse=all:me=umh:subme=6:no-fast-pskip=1:trellis=2" forKey:@"x264Option"]; + [preset setObject:@"cabac=0:ref=1:analyse=all:me=umh:subme=6:no-fast-pskip=1:trellis=1" forKey:@"x264Option"]; /* Video quality */ [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"]; [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"]; @@ -4497,7 +4595,7 @@ the user is using "Custom" settings by determining the sender*/ /* Audio Sample Rate*/ [preset setObject:@"48" forKey:@"AudioSampleRate"]; /* Audio Bitrate Rate*/ - [preset setObject:@"160" forKey:@"AudioBitRate"]; + [preset setObject:@"128" forKey:@"AudioBitRate"]; /* Subtitles*/ [preset setObject:@"None" forKey:@"Subtitles"]; @@ -4507,420 +4605,284 @@ the user is using "Custom" settings by determining the sender*/ } -- (IBAction)DeletePreset:(id)sender +- (NSDictionary *)createDeuxSixQuatrePreset { - int status; - NSEnumerator *enumerator; - NSNumber *index; - NSMutableArray *tempArray; - id tempObject; - - if ( [tableView numberOfSelectedRows] == 0 ) - return; - /* Alert user before deleting preset */ - /* Comment out for now, tie to user pref eventually */ + NSMutableDictionary *preset = [[NSMutableDictionary alloc] init]; + /* Get the New Preset Name from the field in the AddPresetPanel */ + [preset setObject:@"Deux Six Quatre" forKey:@"PresetName"]; + /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/ + [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"]; + /*Set whether or not this is default, at creation set to 0*/ + [preset setObject:[NSNumber numberWithInt:0] forKey:@"Default"]; + /*Get the whether or not to apply pic settings in the AddPresetPanel*/ + [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesPictureSettings"]; + /* Get the New Preset Description from the field in the AddPresetPanel */ + [preset setObject:@"HandBrake's preset for true high profile x264 quality. A good balance of quality and speed, based on community standards found in the wild. This preset will give you a much better sense of x264's capabilities than vanilla main profile." forKey:@"PresetDescription"]; + /* File Format */ + [preset setObject:@"MKV file" forKey:@"FileFormat"]; + /* Chapter Markers*/ + [preset setObject:[NSNumber numberWithInt:1] forKey:@"ChapterMarkers"]; + /* Codecs */ + [preset setObject:@"AVC/H.264 Video / AC-3 Audio" forKey:@"FileCodecs"]; + /* Video encoder */ + [preset setObject:@"x264 (h.264 Main)" forKey:@"VideoEncoder"]; + /* x264 Option String */ + [preset setObject:@"ref=5:mixed-refs:bframes=3:bime:weightb:b-rdo:b-pyramid:me=umh:subme=7:trellis=1:analyse=all:8x8dct:no-fast-pskip" forKey:@"x264Option"]; + /* Video quality */ + [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"]; + [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"]; + [preset setObject:@"1600" forKey:@"VideoAvgBitrate"]; + [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"]; + + /* Video framerate */ + [preset setObject:@"Same as source" forKey:@"VideoFramerate"]; + /* GrayScale */ + [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"]; + /* 2 Pass Encoding */ + [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTwoPass"]; + [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTurboTwoPass"]; + + /*Picture Settings*/ + //hb_job_t * job = fTitle->job; + /* Basic Picture Settings */ + /* Use Max Picture settings for whatever the dvd is.*/ + [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesMaxPictureSettings"]; + [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureAutoCrop"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureWidth"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureHeight"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureKeepRatio"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureDeinterlace"]; + [preset setObject:[NSNumber numberWithInt:1] forKey:@"PicturePAR"]; + /* Set crop settings here */ + /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */ + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureTopCrop"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureBottomCrop"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureLeftCrop"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureRightCrop"]; + + /*Audio*/ + /* Audio Sample Rate*/ + [preset setObject:@"48" forKey:@"AudioSampleRate"]; + /* Audio Bitrate Rate*/ + [preset setObject:@"160" forKey:@"AudioBitRate"]; + /* Subtitles*/ + [preset setObject:@"None" forKey:@"Subtitles"]; + - //NSBeep(); - status = NSRunAlertPanel(@"Warning!", @"Are you sure that you want to delete the selected preset?", @"OK", @"Cancel", nil); - - if ( status == NSAlertDefaultReturn ) { - enumerator = [tableView selectedRowEnumerator]; - tempArray = [NSMutableArray array]; - - while ( (index = [enumerator nextObject]) ) { - tempObject = [UserPresets objectAtIndex:[index intValue]]; - [tempArray addObject:tempObject]; - } - - [UserPresets removeObjectsInArray:tempArray]; - [tableView reloadData]; - [self savePreset]; - } -} + [preset autorelease]; + return preset; -- (IBAction)GetDefaultPresets:(id)sender -{ - int i = 0; - NSEnumerator *enumerator = [UserPresets objectEnumerator]; - id tempObject; - while (tempObject = [enumerator nextObject]) - { - NSDictionary *thisPresetDict = tempObject; - if ([[thisPresetDict objectForKey:@"Default"] intValue] == 1) // 1 is HB default - { - presetHbDefault = i; - } - if ([[thisPresetDict objectForKey:@"Default"] intValue] == 2) // 2 is User specified default - { - presetUserDefault = i; - } - i++; - } } -- (IBAction)SetDefaultPreset:(id)sender +- (NSDictionary *)createBrokePreset { - int i = 0; - NSEnumerator *enumerator = [UserPresets objectEnumerator]; - id tempObject; - /* First make sure the old user specified default preset is removed */ - while (tempObject = [enumerator nextObject]) - { - /* make sure we are not removing the default HB preset */ - if ([[[UserPresets objectAtIndex:i] objectForKey:@"Default"] intValue] != 1) // 1 is HB default - { - [[UserPresets objectAtIndex:i] setObject:[NSNumber numberWithInt:0] forKey:@"Default"]; - } - i++; - } - /* Second, go ahead and set the appropriate user specfied preset */ - /* we get the chosen preset from the UserPresets array */ - if ([[[UserPresets objectAtIndex:[tableView selectedRow]] objectForKey:@"Default"] intValue] != 1) // 1 is HB default - { - [[UserPresets objectAtIndex:[tableView selectedRow]] setObject:[NSNumber numberWithInt:2] forKey:@"Default"]; - } + NSMutableDictionary *preset = [[NSMutableDictionary alloc] init]; + /* Get the New Preset Name from the field in the AddPresetPanel */ + [preset setObject:@"Broke" forKey:@"PresetName"]; + /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/ + [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"]; + /*Set whether or not this is default, at creation set to 0*/ + [preset setObject:[NSNumber numberWithInt:0] forKey:@"Default"]; + /*Get the whether or not to apply pic settings in the AddPresetPanel*/ + [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesPictureSettings"]; + /* Get the New Preset Description from the field in the AddPresetPanel */ + [preset setObject:@"HandBrake's preset for people without a lot of money to waste on hard drives. Tries to maximize quality for burning to CDs, so you can party like it's 1999." forKey:@"PresetDescription"]; + /* File Format */ + [preset setObject:@"MP4 file" forKey:@"FileFormat"]; + /* Chapter Markers*/ + [preset setObject:[NSNumber numberWithInt:1] forKey:@"ChapterMarkers"]; + /* Codecs */ + [preset setObject:@"AVC/H.264 Video / AAC Audio" forKey:@"FileCodecs"]; + /* Video encoder */ + [preset setObject:@"x264 (h.264 Main)" forKey:@"VideoEncoder"]; + /* x264 Option String */ + [preset setObject:@"ref=3:mixed-refs:bframes=16:bime:weightb:b-rdo:b-pyramid:direct=auto:me=umh:subme=6:trellis=1:analyse=all:8x8dct:no-fast-pskip" forKey:@"x264Option"]; + /* Video quality */ + [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoQualityType"]; + [preset setObject:@"695" forKey:@"VideoTargetSize"]; + [preset setObject:@"1600" forKey:@"VideoAvgBitrate"]; + [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"]; + /* Video framerate */ + [preset setObject:@"Same as source" forKey:@"VideoFramerate"]; + /* GrayScale */ + [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"]; + /* 2 Pass Encoding */ + [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTwoPass"]; + [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTurboTwoPass"]; - /* We save all of the preset data here */ - [self savePreset]; - /* We Reload the New Table data for presets */ - [tableView reloadData]; -} - -- (IBAction)SelectDefaultPreset:(id)sender -{ - if (presetUserDefault) - { - [tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:presetUserDefault] byExtendingSelection:NO]; - [self tableViewSelected:NULL]; - } - else if (presetHbDefault) // we use the built in default presetHbDefault - { - [tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:presetHbDefault] byExtendingSelection:NO]; - [self tableViewSelected:NULL]; - } -} - -- (IBAction)tableViewSelected:(id)sender -{ - /* Since we cannot disable the presets tableView in terms of clickability - we will use the enabled state of the add presets button to determine whether - or not clicking on a preset will do anything */ - if ([fPresetsAdd isEnabled]) - { - - /* we get the chosen preset from the UserPresets array */ - chosenPreset = [UserPresets objectAtIndex:[tableView selectedRow]]; - curUserPresetChosenNum = [sender selectedRow]; - /* we set the preset display field in main window here */ - [fPresetSelectedDisplay setStringValue: [NSString stringWithFormat: @"%@",[chosenPreset valueForKey:@"PresetName"]]]; - if ([[chosenPreset objectForKey:@"Default"] intValue] == 1) - { - [fPresetSelectedDisplay setStringValue: [NSString stringWithFormat: @"%@ (Default)",[chosenPreset valueForKey:@"PresetName"]]]; - } - else - { - [fPresetSelectedDisplay setStringValue: [NSString stringWithFormat: @"%@",[chosenPreset valueForKey:@"PresetName"]]]; - } - /* File Format */ - [fDstFormatPopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"FileFormat"]]]; - [self FormatPopUpChanged: NULL]; - - /* Chapter Markers*/ - [fCreateChapterMarkers setState:[[chosenPreset objectForKey:@"ChapterMarkers"] intValue]]; - /* Allow Mpeg4 64 bit formatting +4GB file sizes */ - [fDstMpgLargeFileCheck setState:[[chosenPreset objectForKey:@"Mp4LargeFile"] intValue]]; - /* Codecs */ - [fDstCodecsPopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"FileCodecs"]]]; - [self CodecsPopUpChanged: NULL]; - /* Video encoder */ - [fVidEncoderPopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"VideoEncoder"]]]; - - /* We can show the preset options here in the gui if we want to - so we check to see it the user has specified it in the prefs */ - [fDisplayX264Options setStringValue: [NSString stringWithFormat:[chosenPreset valueForKey:@"x264Option"]]]; - - [self X264AdvancedOptionsSet:NULL]; - - /* Lets run through the following functions to get variables set there */ - [self EncoderPopUpChanged: NULL]; - - [self CalculateBitrate: NULL]; - - /* Video quality */ - [fVidQualityMatrix selectCellAtRow:[[chosenPreset objectForKey:@"VideoQualityType"] intValue] column:0]; - - [fVidTargetSizeField setStringValue: [NSString stringWithFormat:[chosenPreset valueForKey:@"VideoTargetSize"]]]; - [fVidBitrateField setStringValue: [NSString stringWithFormat:[chosenPreset valueForKey:@"VideoAvgBitrate"]]]; - - [fVidQualitySlider setFloatValue: [[chosenPreset valueForKey:@"VideoQualitySlider"] floatValue]]; - [self VideoMatrixChanged: NULL]; - - /* Video framerate */ - [fVidRatePopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"VideoFramerate"]]]; - - /* GrayScale */ - [fVidGrayscaleCheck setState:[[chosenPreset objectForKey:@"VideoGrayScale"] intValue]]; - - /* 2 Pass Encoding */ - [fVidTwoPassCheck setState:[[chosenPreset objectForKey:@"VideoTwoPass"] intValue]]; - [self TwoPassCheckboxChanged: NULL]; - /* Turbo 1st pass for 2 Pass Encoding */ - [fVidTurboPassCheck setState:[[chosenPreset objectForKey:@"VideoTurboTwoPass"] intValue]]; - - /*Audio*/ - - /* Audio Sample Rate*/ - [fAudRatePopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"AudioSampleRate"]]]; - /* Audio Bitrate Rate*/ - [fAudBitratePopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"AudioBitRate"]]]; - /*Subtitles*/ - [fSubPopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"Subtitles"]]]; - - /* Picture Settings */ - /* Look to see if we apply these here in objectForKey:@"UsesPictureSettings"] */ - if ([[chosenPreset objectForKey:@"UsesPictureSettings"] intValue] > 0) - { - hb_job_t * job = fTitle->job; - /* Check to see if we should use the max picture setting for the current title*/ - if ([[chosenPreset objectForKey:@"UsesPictureSettings"] intValue] == 2 || [[chosenPreset objectForKey:@"UsesMaxPictureSettings"] intValue] == 1) - { - /* Use Max Picture settings for whatever the dvd is.*/ - [self RevertPictureSizeToMax: NULL]; - job->keep_ratio = [[chosenPreset objectForKey:@"PictureKeepRatio"] intValue]; - if (job->keep_ratio == 1) - { - hb_fix_aspect( job, HB_KEEP_WIDTH ); - } - job->pixel_ratio = [[chosenPreset objectForKey:@"PicturePAR"] intValue]; - } - else - { - job->width = [[chosenPreset objectForKey:@"PictureWidth"] intValue]; - job->height = [[chosenPreset objectForKey:@"PictureHeight"] intValue]; - job->keep_ratio = [[chosenPreset objectForKey:@"PictureKeepRatio"] intValue]; - if (job->keep_ratio == 1) - { - hb_fix_aspect( job, HB_KEEP_WIDTH ); - } - job->pixel_ratio = [[chosenPreset objectForKey:@"PicturePAR"] intValue]; - job->deinterlace = [[chosenPreset objectForKey:@"PictureDeinterlace"] intValue]; - /* 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) - { - [fPicSettingAutoCrop setStringValue: [NSString stringWithFormat: - @"%d", 0]]; - - /* 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 */ - { - [fPicSettingAutoCrop setStringValue: [NSString stringWithFormat: - @"%d", 1]]; - /* 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; - - } - } - [self CalculatePictureSizing: NULL]; - } - - -[fPresetMakeDefault setEnabled: YES]; - -} -} - - - -- (int)numberOfRowsInTableView:(NSTableView *)aTableView -{ - return [UserPresets count]; -} - -/* we use this to determine display characteristics for -each table cell based on content currently only used to -show the built in presets in a blue font. */ -- (void)tableView:(NSTableView *)aTableView - willDisplayCell:(id)aCell - forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex -{ - NSDictionary *userPresetDict = [UserPresets objectAtIndex:rowIndex]; - NSFont *txtFont; - NSColor *fontColor; - NSColor *shadowColor; - txtFont = [NSFont systemFontOfSize: [NSFont smallSystemFontSize]]; - /* First, we check to see if its a selected row, if so, we use white since its highlighted in blue */ - if ([[aTableView selectedRowIndexes] containsIndex:rowIndex] && ([tableView editedRow] != rowIndex)) - { - - fontColor = [NSColor whiteColor]; - shadowColor = [NSColor colorWithDeviceRed:(127.0/255.0) green:(140.0/255.0) blue:(160.0/255.0) alpha:1.0]; - } - else - { - /* We set the properties of unselected rows */ - /* if built-in preset (defined by "type" == 0) we use a blue font */ - if ([[userPresetDict objectForKey:@"Type"] intValue] == 0) - { - fontColor = [NSColor blueColor]; - } - else // User created preset, use a black font - { - fontColor = [NSColor blackColor]; - } - shadowColor = nil; - } - /* We check to see if this is the HB default, if so, color it appropriately */ - if (!presetUserDefault && presetHbDefault && rowIndex == presetHbDefault) - { - txtFont = [NSFont boldSystemFontOfSize: [NSFont smallSystemFontSize]]; - } - /* We check to see if this is the User Specified default, if so, color it appropriately */ - if (presetUserDefault && rowIndex == presetUserDefault) - { - txtFont = [NSFont boldSystemFontOfSize: [NSFont smallSystemFontSize]]; - } + /*Picture Settings*/ + //hb_job_t * job = fTitle->job; + /* Basic Picture Settings */ + /* Use Max Picture settings for whatever the dvd is.*/ + [preset setObject:[NSNumber numberWithInt:0] forKey:@"UsesMaxPictureSettings"]; + [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureAutoCrop"]; + [preset setObject:[NSNumber numberWithInt:640] forKey:@"PictureWidth"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureHeight"]; + [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureKeepRatio"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureDeinterlace"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PicturePAR"]; + /* Set crop settings here */ + /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */ + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureTopCrop"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureBottomCrop"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureLeftCrop"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureRightCrop"]; - [aCell setTextColor:fontColor]; - [aCell setFont:txtFont]; - /* this shadow stuff (like mail app) for some reason looks crappy, commented out - temporarily in case we want to resurrect it */ - /* - NSShadow *shadow = [[NSShadow alloc] init]; - NSSize shadowOffset = { width: 1.0, height: -1.5}; - [shadow setShadowOffset:shadowOffset]; - [shadow setShadowColor:shadowColor]; - [shadow set]; - */ + /*Audio*/ + /* Audio Sample Rate*/ + [preset setObject:@"48" forKey:@"AudioSampleRate"]; + /* Audio Bitrate Rate*/ + [preset setObject:@"128" forKey:@"AudioBitRate"]; + /* Subtitles*/ + [preset setObject:@"None" forKey:@"Subtitles"]; -} -/* Method to display tooltip with the description for each preset, if available */ -- (NSString *)tableView:(NSTableView *)aTableView toolTipForCell:(NSCell *)aCell - rect:(NSRectPointer)aRect tableColumn:(NSTableColumn *)aTableColumn - row:(int)rowIndex mouseLocation:(NSPoint)aPos -{ - /* initialize the tooltip contents variable */ - NSString *loc_tip; - /* if there is a description for the preset, we show it in the tooltip */ - if ([[UserPresets objectAtIndex:rowIndex] valueForKey:@"PresetDescription"]) - { - loc_tip = [NSString stringWithFormat: @"%@",[[UserPresets objectAtIndex:rowIndex] valueForKey:@"PresetDescription"]]; - return (loc_tip); - } - else - { - loc_tip = @"No description available"; - } - return (loc_tip); -} + [preset autorelease]; + return preset; -- (id)tableView:(NSTableView *)aTableView - objectValueForTableColumn:(NSTableColumn *)aTableColumn - row:(int)rowIndex -{ -id theRecord, theValue; - - theRecord = [UserPresets objectAtIndex:rowIndex]; - theValue = [theRecord objectForKey:[aTableColumn identifier]]; - return theValue; } -// NSTableDataSource method that we implement to edit values directly in the table... -- (void)tableView:(NSTableView *)aTableView - setObjectValue:(id)anObject - forTableColumn:(NSTableColumn *)aTableColumn - row:(int)rowIndex +- (NSDictionary *)createBlindPreset { - id theRecord; - - theRecord = [UserPresets objectAtIndex:rowIndex]; - [theRecord setObject:anObject forKey:@"PresetName"]; - /* We Sort the Presets By Factory or Custom */ - NSSortDescriptor * presetTypeDescriptor=[[[NSSortDescriptor alloc] initWithKey:@"Type" - ascending:YES] autorelease]; - /* We Sort the Presets Alphabetically by name */ - NSSortDescriptor * presetNameDescriptor=[[[NSSortDescriptor alloc] initWithKey:@"PresetName" - ascending:YES selector:@selector(caseInsensitiveCompare:)] autorelease]; - NSArray *sortDescriptors=[NSArray arrayWithObjects:presetTypeDescriptor,presetNameDescriptor,nil]; - NSArray *sortedArray=[UserPresets sortedArrayUsingDescriptors:sortDescriptors]; - [UserPresets setArray:sortedArray]; - /* We Reload the New Table data for presets */ - [tableView reloadData]; - /* We save all of the preset data here */ - [self savePreset]; -} - + NSMutableDictionary *preset = [[NSMutableDictionary alloc] init]; + /* Get the New Preset Name from the field in the AddPresetPanel */ + [preset setObject:@"Blind" forKey:@"PresetName"]; + /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/ + [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"]; + /*Set whether or not this is default, at creation set to 0*/ + [preset setObject:[NSNumber numberWithInt:0] forKey:@"Default"]; + /*Get the whether or not to apply pic settings in the AddPresetPanel*/ + [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesPictureSettings"]; + /* Get the New Preset Description from the field in the AddPresetPanel */ + [preset setObject:@"HandBrake's preset for impatient people who don't care about picture quality." forKey:@"PresetDescription"]; + /* File Format */ + [preset setObject:@"MP4 file" forKey:@"FileFormat"]; + /* Chapter Markers*/ + [preset setObject:[NSNumber numberWithInt:1] forKey:@"ChapterMarkers"]; + /* Codecs */ + [preset setObject:@"MPEG-4 Video / AAC Audio" forKey:@"FileCodecs"]; + /* Video encoder */ + [preset setObject:@"FFmpeg" forKey:@"VideoEncoder"]; + /* x264 Option String */ + [preset setObject:@"" forKey:@"x264Option"]; + /* Video quality */ + [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"]; + [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"]; + [preset setObject:@"512" forKey:@"VideoAvgBitrate"]; + [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"]; + + /* Video framerate */ + [preset setObject:@"Same as source" forKey:@"VideoFramerate"]; + /* GrayScale */ + [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"]; + /* 2 Pass Encoding */ + [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoTwoPass"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoTurboTwoPass"]; + + /*Picture Settings*/ + //hb_job_t * job = fTitle->job; + /* Basic Picture Settings */ + /* Use Max Picture settings for whatever the dvd is.*/ + [preset setObject:[NSNumber numberWithInt:0] forKey:@"UsesMaxPictureSettings"]; + [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureAutoCrop"]; + [preset setObject:[NSNumber numberWithInt:512] forKey:@"PictureWidth"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureHeight"]; + [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureKeepRatio"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureDeinterlace"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PicturePAR"]; + /* Set crop settings here */ + /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */ + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureTopCrop"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureBottomCrop"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureLeftCrop"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureRightCrop"]; + + /*Audio*/ + /* Audio Sample Rate*/ + [preset setObject:@"48" forKey:@"AudioSampleRate"]; + /* Audio Bitrate Rate*/ + [preset setObject:@"128" forKey:@"AudioBitRate"]; + /* Subtitles*/ + [preset setObject:@"None" forKey:@"Subtitles"]; + -- (void)savePreset -{ - [UserPresets writeToFile:UserPresetsFile atomically:YES]; - /* We get the default preset in case it changed */ - [self GetDefaultPresets: NULL]; + [preset autorelease]; + return preset; } - - -- (void) controlTextDidBeginEditing: (NSNotification *) notification +- (NSDictionary *)createCRFPreset { - [self CalculateBitrate: NULL]; -} + NSMutableDictionary *preset = [[NSMutableDictionary alloc] init]; + /* Get the New Preset Name from the field in the AddPresetPanel */ + [preset setObject:@"Constant Quality Rate" forKey:@"PresetName"]; + /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/ + [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"]; + /*Set whether or not this is default, at creation set to 0*/ + [preset setObject:[NSNumber numberWithInt:0] forKey:@"Default"]; + /*Get the whether or not to apply pic settings in the AddPresetPanel*/ + [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesPictureSettings"]; + /* Get the New Preset Description from the field in the AddPresetPanel */ + [preset setObject:@"HandBrake's preset for consistently excellent quality in one pass, with the downside of entirely unpredictable file sizes and bitrates." forKey:@"PresetDescription"]; + /* File Format */ + [preset setObject:@"MKV file" forKey:@"FileFormat"]; + /* Chapter Markers*/ + [preset setObject:[NSNumber numberWithInt:1] forKey:@"ChapterMarkers"]; + /* Codecs */ + [preset setObject:@"AVC/H.264 Video / AC-3 Audio" forKey:@"FileCodecs"]; + /* Video encoder */ + [preset setObject:@"x264 (h.264 Main)" forKey:@"VideoEncoder"]; + /* x264 Option String */ + [preset setObject:@"ref=3:mixed-refs:bframes=3:b-pyramid:b-rdo:bime:weightb:filter=-2,-1:subme=6:trellis=1:analyse=all:8x8dct:me=umh" forKey:@"x264Option"]; + /* Video quality */ + [preset setObject:[NSNumber numberWithInt:2] forKey:@"VideoQualityType"]; + [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"]; + [preset setObject:@"2000" forKey:@"VideoAvgBitrate"]; + [preset setObject:[NSNumber numberWithFloat:0.6471] forKey:@"VideoQualitySlider"]; + + /* Video framerate */ + [preset setObject:@"Same as source" forKey:@"VideoFramerate"]; + /* GrayScale */ + [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"]; + /* 2 Pass Encoding */ + [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoTwoPass"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoTurboTwoPass"]; + + /*Picture Settings*/ + //hb_job_t * job = fTitle->job; + /* Basic Picture Settings */ + /* Use Max Picture settings for whatever the dvd is.*/ + [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesMaxPictureSettings"]; + [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureAutoCrop"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureWidth"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureHeight"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureKeepRatio"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureDeinterlace"]; + [preset setObject:[NSNumber numberWithInt:1] forKey:@"PicturePAR"]; + /* Set crop settings here */ + /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */ + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureTopCrop"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureBottomCrop"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureLeftCrop"]; + [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureRightCrop"]; + + /*Audio*/ + /* Audio Sample Rate*/ + [preset setObject:@"48" forKey:@"AudioSampleRate"]; + /* Audio Bitrate Rate*/ + [preset setObject:@"160" forKey:@"AudioBitRate"]; + /* Subtitles*/ + [preset setObject:@"None" forKey:@"Subtitles"]; + -- (void) controlTextDidEndEditing: (NSNotification *) notification -{ - [self CalculateBitrate: NULL]; -} + [preset autorelease]; + return preset; -- (void) controlTextDidChange: (NSNotification *) notification -{ - [self CalculateBitrate: NULL]; } -- (IBAction) OpenHomepage: (id) sender -{ - [[NSWorkspace sharedWorkspace] openURL: [NSURL - URLWithString:@"http://handbrake.m0k.org/"]]; -} -- (IBAction) OpenForums: (id) sender -{ - [[NSWorkspace sharedWorkspace] openURL: [NSURL - URLWithString:@"http://handbrake.m0k.org/forum/"]]; -} -- (IBAction) OpenUserGuide: (id) sender -{ - [[NSWorkspace sharedWorkspace] openURL: [NSURL - URLWithString:@"http://handbrake.m0k.org/trac/wiki/HandBrakeGuide"]]; -} -/** - * Shows debug output window. - */ -- (IBAction)showDebugOutputPanel:(id)sender -{ - [outputPanel showOutputPanel:sender]; -} -/** - * Creates preferences controller, shows preferences window modally, and - * releases the controller after user has closed the window. - */ -- (IBAction)showPreferencesWindow:(id)sender -{ - HBPreferencesController *controller = [[HBPreferencesController alloc] init]; - [controller runModal:nil]; - [controller release]; -} @end