OSDN Git Service

Repeat after me, eddyg is a wally.
[handbrake-jp/handbrake-jp-git.git] / macosx / Controller.mm
1 /* $Id: Controller.mm,v 1.79 2005/11/04 19:41:32 titer Exp $
2
3    This file is part of the HandBrake source code.
4    Homepage: <http://handbrake.m0k.org/>.
5    It may be used under the terms of the GNU General Public License. */
6
7 #include "Controller.h"
8 #include "a52dec/a52.h"
9 #import "HBOutputPanelController.h"
10 #import "HBPreferencesController.h"
11 /* Added to integrate scanning into HBController */
12 #include <IOKit/IOKitLib.h>
13 #include <IOKit/storage/IOMedia.h>
14 #include <IOKit/storage/IODVDMedia.h>
15 #include "HBDVDDetector.h"
16 #include "dvdread/dvd_reader.h"
17
18 #define _(a) NSLocalizedString(a,NULL)
19
20 static int FormatSettings[4][10] =
21   { { HB_MUX_MP4 | HB_VCODEC_FFMPEG | HB_ACODEC_FAAC,
22           HB_MUX_MP4 | HB_VCODEC_X264   | HB_ACODEC_FAAC,
23           0,
24           0 },
25     { HB_MUX_MKV | HB_VCODEC_FFMPEG | HB_ACODEC_FAAC,
26           HB_MUX_MKV | HB_VCODEC_FFMPEG | HB_ACODEC_AC3,
27           HB_MUX_MKV | HB_VCODEC_FFMPEG | HB_ACODEC_LAME,
28           HB_MUX_MKV | HB_VCODEC_FFMPEG | HB_ACODEC_VORBIS,
29           HB_MUX_MKV | HB_VCODEC_X264   | HB_ACODEC_FAAC,
30           HB_MUX_MKV | HB_VCODEC_X264   | HB_ACODEC_AC3,
31           HB_MUX_MKV | HB_VCODEC_X264   | HB_ACODEC_LAME,
32           HB_MUX_MKV | HB_VCODEC_X264   | HB_ACODEC_VORBIS,
33           0,
34           0 },
35     { HB_MUX_AVI | HB_VCODEC_FFMPEG | HB_ACODEC_LAME,
36           HB_MUX_AVI | HB_VCODEC_FFMPEG | HB_ACODEC_AC3,
37           HB_MUX_AVI | HB_VCODEC_X264   | HB_ACODEC_LAME,
38           HB_MUX_AVI | HB_VCODEC_X264   | HB_ACODEC_AC3},
39     { HB_MUX_OGM | HB_VCODEC_FFMPEG | HB_ACODEC_VORBIS,
40           HB_MUX_OGM | HB_VCODEC_FFMPEG | HB_ACODEC_LAME,
41           0,
42           0 } };
43
44 /* We setup the toolbar values here */
45 static NSString *        ToggleDrawerIdentifier             = @"Toggle Drawer Item Identifier";
46 static NSString *        StartEncodingIdentifier            = @"Start Encoding Item Identifier";
47 static NSString *        PauseEncodingIdentifier            = @"Pause Encoding Item Identifier";
48 static NSString *        ShowQueueIdentifier                = @"Show Queue Item Identifier";
49 static NSString *        AddToQueueIdentifier               = @"Add to Queue Item Identifier";
50 static NSString *        ShowActivityIdentifier             = @"Debug Output Item Identifier";
51 static NSString *        ChooseSourceIdentifier             = @"Choose Source Item Identifier";
52
53
54 /*******************************
55  * HBController implementation *
56  *******************************/
57 @implementation HBController
58
59 - init
60 {
61     self = [super init];
62     [HBPreferencesController registerUserDefaults];
63     fHandle = NULL;
64     outputPanel = [[HBOutputPanelController alloc] init];
65     fPictureController = [[PictureController alloc] initWithDelegate:self];
66     fQueueController = [[HBQueueController alloc] init];
67     fAdvancedOptions = [[HBAdvancedController alloc] init];
68     fPreferencesController = [[HBPreferencesController alloc] init];
69     return self;
70 }
71
72 - (void) applicationDidFinishLaunching: (NSNotification *) notification
73 {
74     int    build;
75     char * version;
76
77     // Init libhb
78         int debugLevel = [[NSUserDefaults standardUserDefaults] boolForKey:@"ShowVerboseOutput"] ? HB_DEBUG_ALL : HB_DEBUG_NONE;
79     fHandle = hb_init(debugLevel, [[NSUserDefaults standardUserDefaults] boolForKey:@"CheckForUpdates"]);
80
81         // Set the Growl Delegate
82     [GrowlApplicationBridge setGrowlDelegate: self];    
83     /* Init others controllers */
84     [fPictureController SetHandle: fHandle];
85     [fQueueController   setHandle: fHandle];
86     [fQueueController   setHBController: self];
87         
88     fChapterTitlesDelegate = [[ChapterTitles alloc] init];
89     [fChapterTable setDataSource:fChapterTitlesDelegate];
90
91      /* Call UpdateUI every 1/2 sec */
92     [[NSRunLoop currentRunLoop] addTimer: [NSTimer
93         scheduledTimerWithTimeInterval: 0.5 target: self
94         selector: @selector( updateUI: ) userInfo: NULL repeats: YES]
95         forMode: NSEventTrackingRunLoopMode];
96
97     if( ( build = hb_check_update( fHandle, &version ) ) > -1 )
98     {
99         /* Update available - tell the user */
100         
101         NSBeginInformationalAlertSheet( _( @"Update is available" ),
102             _( @"Go get it!" ), _( @"Discard" ), NULL, fWindow, self,
103             @selector( updateAlertDone:returnCode:contextInfo: ),
104             NULL, NULL, [NSString stringWithFormat:
105             _( @"HandBrake %s (build %d) is now available for download." ),
106             version, build] );
107         return;
108
109     }
110
111     // Open debug output window now if it was visible when HB was closed
112     if ([[NSUserDefaults standardUserDefaults] boolForKey:@"OutputPanelIsOpen"])
113         [self showDebugOutputPanel:nil];
114
115     // Open queue window now if it was visible when HB was closed
116     if ([[NSUserDefaults standardUserDefaults] boolForKey:@"QueueWindowIsOpen"])
117         [self showQueueWindow:nil];
118
119         [self openMainWindow:nil];
120         
121     /* Show scan panel ASAP */
122     [self performSelectorOnMainThread: @selector(showScanPanel:)
123         withObject: NULL waitUntilDone: NO];
124 }
125
126 - (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication *) app
127 {
128     // Warn if encoding a movie
129     hb_state_t s;
130     hb_get_state( fHandle, &s );
131     hb_job_t * job = hb_current_job( fHandle );
132     if ( job && ( s.state != HB_STATE_IDLE ) )
133     {
134         hb_job_t * job = hb_current_job( fHandle );
135         int result = NSRunCriticalAlertPanel(
136                 NSLocalizedString(@"Are you sure you want to quit HandBrake?", nil),
137                 NSLocalizedString(@"%@ is currently encoding. If you quit HandBrake, your movie will be lost. Do you want to quit anyway?", nil),
138                 NSLocalizedString(@"Quit", nil), NSLocalizedString(@"Don't Quit", nil), nil,
139                 job ? [NSString stringWithUTF8String:job->title->name] : @"A movie" );
140         
141         if (result == NSAlertDefaultReturn)
142         {
143             [self doCancelCurrentJob];
144             return NSTerminateNow;
145         }
146         else
147             return NSTerminateCancel;
148     }
149     
150     // Warn if items still in the queue
151     else if ( hb_count( fHandle ) > 0 )
152     {
153         int result = NSRunCriticalAlertPanel(
154                 NSLocalizedString(@"Are you sure you want to quit HandBrake?", nil),
155                 NSLocalizedString(@"One or more encodes are queued for encoding. Do you want to quit anyway?", nil),
156                 NSLocalizedString(@"Quit", nil), NSLocalizedString(@"Don't Quit", nil), nil);
157         
158         if ( result == NSAlertDefaultReturn )
159             return NSTerminateNow;
160         else
161             return NSTerminateCancel;
162     }
163     
164     return NSTerminateNow;
165 }
166
167 - (void)applicationWillTerminate:(NSNotification *)aNotification
168 {
169         [outputPanel release];
170         [fQueueController release];
171         hb_close(&fHandle);
172 }
173
174
175 - (void) awakeFromNib
176 {
177     [fWindow center];
178     [fWindow setExcludedFromWindowsMenu:YES];
179     [fAdvancedOptions setView:fAdvancedView];
180
181     /* Initialize currentScanCount so HB can use it to
182                 evaluate successive scans */
183         currentScanCount = 0;
184         
185     /* Init UserPresets .plist */
186         [self loadPresets];
187                 
188         fRipIndicatorShown = NO;  // initially out of view in the nib
189         
190         /* Show/Dont Show Presets drawer upon launch based
191                 on user preference DefaultPresetsDrawerShow*/
192         if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultPresetsDrawerShow"] > 0)
193         {
194                 [fPresetDrawer open];
195         }
196         
197         
198     /* Destination box*/
199     [fDstFormatPopUp removeAllItems];
200     [fDstFormatPopUp addItemWithTitle: _( @"MP4 file" )];
201         [fDstFormatPopUp addItemWithTitle: _( @"MKV file" )];
202     [fDstFormatPopUp addItemWithTitle: _( @"AVI file" )];
203     [fDstFormatPopUp addItemWithTitle: _( @"OGM file" )];
204     [fDstFormatPopUp selectItemAtIndex: 0];
205         
206     [self formatPopUpChanged: NULL];
207     
208         /* We enable the create chapters checkbox here since we are .mp4 */     
209         [fCreateChapterMarkers setEnabled: YES];
210         if ([fDstFormatPopUp indexOfSelectedItem] == 0 && [[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultChapterMarkers"] > 0)
211         {
212                 [fCreateChapterMarkers setState: NSOnState];
213         }
214         
215         
216         
217         
218     [fDstFile2Field setStringValue: [NSString stringWithFormat:
219         @"%@/Desktop/Movie.mp4", NSHomeDirectory()]];
220         
221     /* Video encoder */
222     [fVidEncoderPopUp removeAllItems];
223     [fVidEncoderPopUp addItemWithTitle: @"FFmpeg"];
224     [fVidEncoderPopUp addItemWithTitle: @"XviD"];
225         
226     
227         
228     /* Video quality */
229     [fVidTargetSizeField setIntValue: 700];
230         [fVidBitrateField    setIntValue: 1000];
231         
232     [fVidQualityMatrix   selectCell: fVidBitrateCell];
233     [self videoMatrixChanged: NULL];
234         
235     /* Video framerate */
236     [fVidRatePopUp removeAllItems];
237         [fVidRatePopUp addItemWithTitle: _( @"Same as source" )];
238     for( int i = 0; i < hb_video_rates_count; i++ )
239     {
240         if ([[NSString stringWithCString: hb_video_rates[i].string] isEqualToString: [NSString stringWithFormat: @"%.3f",23.976]])
241                 {
242                         [fVidRatePopUp addItemWithTitle:[NSString stringWithFormat: @"%@%@",
243                                 [NSString stringWithCString: hb_video_rates[i].string], @" (NTSC Film)"]];
244                 }
245                 else if ([[NSString stringWithCString: hb_video_rates[i].string] isEqualToString: [NSString stringWithFormat: @"%d",25]])
246                 {
247                         [fVidRatePopUp addItemWithTitle:[NSString stringWithFormat: @"%@%@",
248                                 [NSString stringWithCString: hb_video_rates[i].string], @" (PAL Film/Video)"]];
249                 }
250                 else if ([[NSString stringWithCString: hb_video_rates[i].string] isEqualToString: [NSString stringWithFormat: @"%.2f",29.97]])
251                 {
252                         [fVidRatePopUp addItemWithTitle:[NSString stringWithFormat: @"%@%@",
253                                 [NSString stringWithCString: hb_video_rates[i].string], @" (NTSC Video)"]];
254                 }
255                 else
256                 {
257                         [fVidRatePopUp addItemWithTitle:
258                                 [NSString stringWithCString: hb_video_rates[i].string]];
259                 }
260     }
261     [fVidRatePopUp selectItemAtIndex: 0];
262         
263         /* Picture Settings */
264         [fPicLabelPAROutputX setStringValue: @""];
265         [fPicSettingPARWidth setStringValue: @""];
266         [fPicSettingPARHeight setStringValue:  @""];
267         
268         /* Set Auto Crop to On at launch */
269     [fPictureController setAutoCrop:YES];
270         
271         /* Audio bitrate */
272     [fAudBitratePopUp removeAllItems];
273     for( int i = 0; i < hb_audio_bitrates_count; i++ )
274     {
275         [fAudBitratePopUp addItemWithTitle:
276                                 [NSString stringWithCString: hb_audio_bitrates[i].string]];
277
278     }
279     [fAudBitratePopUp selectItemAtIndex: hb_audio_bitrates_default];
280         
281     /* Audio samplerate */
282     [fAudRatePopUp removeAllItems];
283     for( int i = 0; i < hb_audio_rates_count; i++ )
284     {
285         [fAudRatePopUp addItemWithTitle:
286             [NSString stringWithCString: hb_audio_rates[i].string]];
287     }
288     [fAudRatePopUp selectItemAtIndex: hb_audio_rates_default];
289         
290     /* Bottom */
291     [fStatusField setStringValue: @""];
292         
293     [self enableUI: NO];
294         [self setupToolbar];
295         
296         [fPresetsActionButton setMenu:fPresetsActionMenu];
297         
298         /* We disable the Turbo 1st pass checkbox since we are not x264 */
299         [fVidTurboPassCheck setEnabled: NO];
300         [fVidTurboPassCheck setState: NSOffState];
301         
302         
303         /* lets get our default prefs here */
304         [self getDefaultPresets: NULL];
305         /* lets initialize the current successful scancount here to 0 */
306         currentSuccessfulScanCount = 0;
307     
308 }
309
310 - (void) loadPresets {
311         /* We declare the default NSFileManager into fileManager */
312         NSFileManager * fileManager = [NSFileManager defaultManager];
313         /* we set the files and support paths here */
314         AppSupportDirectory = @"~/Library/Application Support/HandBrake";
315     AppSupportDirectory = [AppSupportDirectory stringByExpandingTildeInPath];
316     //UserPresetsFile = @"~/Library/Application Support/HandBrake/UserPresets.plist";
317     //UserPresetsFile = [UserPresetsFile stringByExpandingTildeInPath];
318         /* We check for the app support directory for handbrake */
319         if ([fileManager fileExistsAtPath:AppSupportDirectory] == 0) 
320         {
321                 // If it doesnt exist yet, we create it here 
322                 [fileManager createDirectoryAtPath:AppSupportDirectory attributes:nil];
323         }
324         /* We check for the presets.plist here */
325         if ([fileManager fileExistsAtPath:UserPresetsFile] == 0) 
326         {
327                 [fileManager createFileAtPath:UserPresetsFile contents:nil attributes:nil];
328         }
329         UserPresetsFile = @"~/Library/Application Support/HandBrake/UserPresets.plist";
330         UserPresetsFile = [[UserPresetsFile stringByExpandingTildeInPath]retain];
331         
332         UserPresets = [[NSMutableArray alloc] initWithContentsOfFile:UserPresetsFile];
333         if (nil == UserPresets) 
334         {
335                 UserPresets = [[NSMutableArray alloc] init];
336                 [self addFactoryPresets:NULL];
337         }
338         
339 }
340
341 // ============================================================
342 // NSToolbar Related Methods
343 // ============================================================
344
345 - (void) setupToolbar {
346     toolbar = [[[NSToolbar alloc] initWithIdentifier: @"HandBrake Toolbar"] autorelease];
347     
348     [toolbar setAllowsUserCustomization: YES];
349     [toolbar setAutosavesConfiguration: YES];
350     [toolbar setDisplayMode: NSToolbarDisplayModeIconAndLabel];
351     
352     [toolbar setDelegate: self];
353     
354     [fWindow setToolbar: toolbar];
355 }
356
357 - (NSToolbarItem *) toolbar: (NSToolbar *)toolbar itemForItemIdentifier:
358     (NSString *) itemIdent willBeInsertedIntoToolbar:(BOOL) willBeInserted {
359     NSToolbarItem * item = [[NSToolbarItem alloc] initWithItemIdentifier: itemIdent];
360     
361     if ([itemIdent isEqualToString: ToggleDrawerIdentifier])
362     {
363         [item setLabel: @"Toggle Presets"];
364         [item setPaletteLabel: @"Toggler Presets"];
365         [item setToolTip: @"Open/Close Preset Drawer"];
366         [item setImage: [NSImage imageNamed: @"Drawer"]];
367         [item setTarget: self];
368         [item setAction: @selector(toggleDrawer:)];
369         [item setAutovalidates: NO];
370     }
371     else if ([itemIdent isEqualToString: StartEncodingIdentifier])
372     {
373         [item setLabel: @"Start"];
374         [item setPaletteLabel: @"Start Encoding"];
375         [item setToolTip: @"Start Encoding"];
376         [item setImage: [NSImage imageNamed: @"Play"]];
377         [item setTarget: self];
378         [item setAction: @selector(Rip:)];
379     }
380     else if ([itemIdent isEqualToString: ShowQueueIdentifier])
381     {
382         [item setLabel: @"Show Queue"];
383         [item setPaletteLabel: @"Show Queue"];
384         [item setToolTip: @"Show Queue"];
385         [item setImage: [NSImage imageNamed: @"Queue"]];
386         [item setTarget: self];
387         [item setAction: @selector(showQueueWindow:)];
388         [item setAutovalidates: NO];
389     }
390     else if ([itemIdent isEqualToString: AddToQueueIdentifier])
391     {
392         [item setLabel: @"Add to Queue"];
393         [item setPaletteLabel: @"Add to Queue"];
394         [item setToolTip: @"Add to Queue"];
395         [item setImage: [NSImage imageNamed: @"AddToQueue"]];
396         [item setTarget: self];
397         [item setAction: @selector(addToQueue:)];
398     }
399     else if ([itemIdent isEqualToString: PauseEncodingIdentifier])
400     {
401         [item setLabel: @"Pause"];
402         [item setPaletteLabel: @"Pause Encoding"];
403         [item setToolTip: @"Pause Encoding"];
404         [item setImage: [NSImage imageNamed: @"Pause"]];
405         [item setTarget: self];
406         [item setAction: @selector(Pause:)];
407     }
408     else if ([itemIdent isEqualToString: ShowActivityIdentifier]) {
409         [item setLabel: @"Activity Window"];
410         [item setPaletteLabel: @"Show Activity Window"];
411         [item setToolTip: @"Show Activity Window"];
412         [item setImage: [NSImage imageNamed: @"ActivityWindow"]];
413         [item setTarget: self];
414         [item setAction: @selector(showDebugOutputPanel:)];
415         [item setAutovalidates: NO];
416     }
417     else if ([itemIdent isEqualToString: ChooseSourceIdentifier])
418     {
419         [item setLabel: @"Source"];
420         [item setPaletteLabel: @"Source"];
421         [item setToolTip: @"Choose Video Source"];
422         [item setImage: [NSImage imageNamed: @"Source"]];
423         [item setTarget: self];
424         [item setAction: @selector(showScanPanel:)];
425     }
426     else
427     {
428         [item release];
429         return nil;
430     }
431
432     return item;
433 }
434
435 - (NSArray *) toolbarDefaultItemIdentifiers: (NSToolbar *) toolbar
436 {
437     return [NSArray arrayWithObjects: ChooseSourceIdentifier, NSToolbarSeparatorItemIdentifier, StartEncodingIdentifier,
438         PauseEncodingIdentifier, AddToQueueIdentifier, ShowQueueIdentifier, NSToolbarFlexibleSpaceItemIdentifier, 
439                 NSToolbarSpaceItemIdentifier, ShowActivityIdentifier, ToggleDrawerIdentifier, nil];
440 }
441
442 - (NSArray *) toolbarAllowedItemIdentifiers: (NSToolbar *) toolbar
443 {
444     return [NSArray arrayWithObjects:  StartEncodingIdentifier, PauseEncodingIdentifier, AddToQueueIdentifier,
445         ChooseSourceIdentifier, ShowQueueIdentifier, ShowActivityIdentifier, ToggleDrawerIdentifier,
446         NSToolbarCustomizeToolbarItemIdentifier, NSToolbarFlexibleSpaceItemIdentifier,
447         NSToolbarSpaceItemIdentifier, NSToolbarSeparatorItemIdentifier, nil];
448 }
449
450 - (BOOL) validateToolbarItem: (NSToolbarItem *) toolbarItem
451 {
452     NSString * ident = [toolbarItem itemIdentifier];
453         
454     if (fHandle)
455     {
456         hb_state_t s;
457         hb_get_state2( fHandle, &s );
458         
459         if (s.state == HB_STATE_WORKING || s.state == HB_STATE_MUXING)
460         {
461             if ([ident isEqualToString: StartEncodingIdentifier])
462             {
463                 [toolbarItem setImage: [NSImage imageNamed: @"Stop"]];
464                 [toolbarItem setLabel: @"Stop"];
465                 [toolbarItem setPaletteLabel: @"Stop"];
466                 [toolbarItem setToolTip: @"Stop Encoding"];
467                 return YES;
468             }
469             if ([ident isEqualToString: PauseEncodingIdentifier])
470             {
471                 [toolbarItem setImage: [NSImage imageNamed: @"Pause"]];
472                 [toolbarItem setLabel: @"Pause"];
473                 [toolbarItem setPaletteLabel: @"Pause Encoding"];
474                 [toolbarItem setToolTip: @"Pause Encoding"];
475                 return YES;
476             }
477             if (SuccessfulScan)
478                 if ([ident isEqualToString: AddToQueueIdentifier])
479                     return YES;
480         }
481         else if (s.state == HB_STATE_PAUSED)
482         {
483             if ([ident isEqualToString: PauseEncodingIdentifier])
484             {
485                 [toolbarItem setImage: [NSImage imageNamed: @"Play"]];
486                 [toolbarItem setLabel: @"Resume"];
487                 [toolbarItem setPaletteLabel: @"Resume Encoding"];
488                 [toolbarItem setToolTip: @"Resume Encoding"];
489                 return YES;
490             }
491             if ([ident isEqualToString: StartEncodingIdentifier])
492                 return YES;
493             if ([ident isEqualToString: AddToQueueIdentifier])
494                 return YES;
495         }
496         else if (s.state == HB_STATE_SCANNING)
497             return NO;
498         else if (s.state == HB_STATE_WORKDONE || s.state == HB_STATE_SCANDONE || SuccessfulScan)
499         {
500             if ([ident isEqualToString: StartEncodingIdentifier])
501             {
502                 [toolbarItem setImage: [NSImage imageNamed: @"Play"]];
503                 if (hb_count(fHandle) > 0)
504                     [toolbarItem setLabel: @"Start Queue"];
505                 else
506                     [toolbarItem setLabel: @"Start"];
507                 [toolbarItem setPaletteLabel: @"Start Encoding"];
508                 [toolbarItem setToolTip: @"Start Encoding"];
509                 return YES;
510             }
511             if ([ident isEqualToString: AddToQueueIdentifier])
512                 return YES;
513         }
514
515     }
516     
517     if ([ident isEqualToString: ShowQueueIdentifier])
518         return YES;
519     if ([ident isEqualToString: ToggleDrawerIdentifier])
520         return YES;
521     if ([ident isEqualToString: ChooseSourceIdentifier])
522         return YES;
523     if ([ident isEqualToString: ShowActivityIdentifier])
524         return YES;
525     
526     return NO;
527 }
528
529 - (BOOL) validateMenuItem: (NSMenuItem *) menuItem
530 {
531     SEL action = [menuItem action];
532     
533     hb_state_t s;
534     hb_get_state2( fHandle, &s );
535     
536     if (fHandle)
537     {
538         if (action == @selector(addToQueue:) || action == @selector(showPicturePanel:) || action == @selector(showAddPresetPanel:))
539             return SuccessfulScan && [fWindow attachedSheet] == nil;
540         
541         if (action == @selector(showScanPanel:))
542         {
543             if (s.state == HB_STATE_SCANNING)
544                 return NO;
545             else
546                 return [fWindow attachedSheet] == nil;
547         }
548         if (action == @selector(selectDefaultPreset:))
549             return [tableView selectedRow] >= 0 && [fWindow attachedSheet] == nil;
550         if (action == @selector(Pause:))
551         {
552             if (s.state == HB_STATE_WORKING)
553             {
554                 if(![[menuItem title] isEqualToString:@"Pause Encoding"])
555                     [menuItem setTitle:@"Pause Encoding"];
556                 return YES;
557             }
558             else if (s.state == HB_STATE_PAUSED)
559             {
560                 if(![[menuItem title] isEqualToString:@"Resume Encoding"])
561                     [menuItem setTitle:@"Resume Encoding"];
562                 return YES;
563             }
564             else
565                 return NO;
566         }
567         if (action == @selector(Rip:))
568             if (s.state == HB_STATE_WORKING || s.state == HB_STATE_MUXING || s.state == HB_STATE_PAUSED)
569             {
570                 if(![[menuItem title] isEqualToString:@"Stop Encoding"])
571                     [menuItem setTitle:@"Stop Encoding"];
572                 return YES;
573             }
574             else if (SuccessfulScan)
575             {
576                 if(![[menuItem title] isEqualToString:@"Start Encoding"])
577                     [menuItem setTitle:@"Start Encoding"];
578                 return [fWindow attachedSheet] == nil;
579             }
580             else
581                 return NO;
582         }
583     
584     return YES;
585 }
586
587
588 // register a test notification and make
589 // it enabled by default
590 #define SERVICE_NAME @"Encode Done"
591 - (NSDictionary *)registrationDictionaryForGrowl 
592
593     NSDictionary *registrationDictionary = [NSDictionary dictionaryWithObjectsAndKeys: 
594     [NSArray arrayWithObjects:SERVICE_NAME,nil], GROWL_NOTIFICATIONS_ALL, 
595     [NSArray arrayWithObjects:SERVICE_NAME,nil], GROWL_NOTIFICATIONS_DEFAULT, 
596     nil]; 
597
598     return registrationDictionary; 
599
600
601 - (void) TranslateStrings
602 {
603     [fSrcTitleField     setStringValue: _( @"Title:" )];
604     [fSrcChapterField   setStringValue: _( @"Chapters:" )];
605     [fSrcChapterToField setStringValue: _( @"to" )];
606     [fSrcDuration1Field setStringValue: _( @"Duration:" )];
607
608     [fDstFormatField    setStringValue: _( @"Format:" )];
609     [fDstCodecsField    setStringValue: _( @"Codecs:" )];
610     [fDstFile1Field     setStringValue: _( @"File:" )];
611     [fDstBrowseButton   setTitle:       _( @"Browse" )];
612
613     [fVidRateField      setStringValue: _( @"Framerate (fps):" )];
614     [fVidEncoderField   setStringValue: _( @"Encoder:" )];
615     [fVidQualityField   setStringValue: _( @"Quality:" )];
616 }
617
618 /***********************************************************************
619  * UpdateDockIcon
620  ***********************************************************************
621  * Shows a progression bar on the dock icon, filled according to
622  * 'progress' (0.0 <= progress <= 1.0).
623  * Called with progress < 0.0 or progress > 1.0, restores the original
624  * icon.
625  **********************************************************************/
626 - (void) UpdateDockIcon: (float) progress
627 {
628     NSImage * icon;
629     NSData * tiff;
630     NSBitmapImageRep * bmp;
631     uint32_t * pen;
632     uint32_t black = htonl( 0x000000FF );
633     uint32_t red   = htonl( 0xFF0000FF );
634     uint32_t white = htonl( 0xFFFFFFFF );
635     int row_start, row_end;
636     int i, j;
637
638     /* Get application original icon */
639     icon = [NSImage imageNamed: @"NSApplicationIcon"];
640
641     if( progress < 0.0 || progress > 1.0 )
642     {
643         [NSApp setApplicationIconImage: icon];
644         return;
645     }
646
647     /* Get it in a raw bitmap form */
648     tiff = [icon TIFFRepresentationUsingCompression:
649             NSTIFFCompressionNone factor: 1.0];
650     bmp = [NSBitmapImageRep imageRepWithData: tiff];
651     
652     /* Draw the progression bar */
653     /* It's pretty simple (ugly?) now, but I'm no designer */
654
655     row_start = 3 * (int) [bmp size].height / 4;
656     row_end   = 7 * (int) [bmp size].height / 8;
657
658     for( i = row_start; i < row_start + 2; i++ )
659     {
660         pen = (uint32_t *) ( [bmp bitmapData] + i * [bmp bytesPerRow] );
661         for( j = 0; j < (int) [bmp size].width; j++ )
662         {
663             pen[j] = black;
664         }
665     }
666     for( i = row_start + 2; i < row_end - 2; i++ )
667     {
668         pen = (uint32_t *) ( [bmp bitmapData] + i * [bmp bytesPerRow] );
669         pen[0] = black;
670         pen[1] = black;
671         for( j = 2; j < (int) [bmp size].width - 2; j++ )
672         {
673             if( j < 2 + (int) ( ( [bmp size].width - 4.0 ) * progress ) )
674             {
675                 pen[j] = red;
676             }
677             else
678             {
679                 pen[j] = white;
680             }
681         }
682         pen[j]   = black;
683         pen[j+1] = black;
684     }
685     for( i = row_end - 2; i < row_end; i++ )
686     {
687         pen = (uint32_t *) ( [bmp bitmapData] + i * [bmp bytesPerRow] );
688         for( j = 0; j < (int) [bmp size].width; j++ )
689         {
690             pen[j] = black;
691         }
692     }
693
694     /* Now update the dock icon */
695     tiff = [bmp TIFFRepresentationUsingCompression:
696             NSTIFFCompressionNone factor: 1.0];
697     icon = [[NSImage alloc] initWithData: tiff];
698     [NSApp setApplicationIconImage: icon];
699     [icon release];
700 }
701
702 - (void) updateUI: (NSTimer *) timer
703 {
704
705     hb_list_t  * list;
706     list = hb_get_titles( fHandle );    
707     /* check to see if there has been a new scan done
708         this bypasses the constraints of HB_STATE_WORKING
709         not allowing setting a newly scanned source */
710         int checkScanCount = hb_get_scancount( fHandle );
711         if (checkScanCount > currentScanCount)
712         {
713                 
714                 currentScanCount = checkScanCount;
715                 //[fScanController Cancel: NULL];
716                 [fScanIndicator setIndeterminate: NO];
717                 [fScanIndicator setDoubleValue: 0.0];
718                 [fScanIndicator setHidden: YES];
719
720                 [self showNewScan: NULL];
721         }
722         
723     hb_state_t s;
724     hb_get_state( fHandle, &s );
725         
726         
727     switch( s.state )
728     {
729         case HB_STATE_IDLE:
730                 break;
731 #define p s.param.scanning                      
732         case HB_STATE_SCANNING:
733                 {
734             [fSrcDVD2Field setStringValue: [NSString stringWithFormat:
735                 _( @"Scanning title %d of %d..." ),
736                 p.title_cur, p.title_count]];
737             [fScanIndicator setIndeterminate: NO];
738                         [fScanIndicator setDoubleValue: 100.0 * ( p.title_cur - 1 ) /
739                 p.title_count];
740             break;
741                 }
742 #undef p
743         
744 #define p s.param.scandone
745         case HB_STATE_SCANDONE:
746         {
747                         
748                         [fScanIndicator setIndeterminate: NO];
749             [fScanIndicator setDoubleValue: 0.0];
750                         [fScanIndicator setHidden: YES];
751                         [self showNewScan: NULL];
752             [toolbar validateVisibleItems];
753                         break;
754         }
755 #undef p
756                         
757 #define p s.param.working
758         case HB_STATE_WORKING:
759         {
760             float progress_total;
761             NSMutableString * string;
762                         /* Currently, p.job_cur and p.job_count get screwed up when adding
763                                 jobs during encoding, if they cannot be fixed in libhb, will implement a
764                                 nasty but working cocoa solution */
765                         /* Update text field */
766                         string = [NSMutableString stringWithFormat: _( @"Encoding: task %d of %d, %.2f %%" ), p.job_cur, p.job_count, 100.0 * p.progress];
767             
768                         if( p.seconds > -1 )
769             {
770                 [string appendFormat:
771                     _( @" (%.2f fps, avg %.2f fps, ETA %02dh%02dm%02ds)" ),
772                     p.rate_cur, p.rate_avg, p.hours, p.minutes, p.seconds];
773             }
774             [fStatusField setStringValue: string];
775                         
776             /* Update slider */
777                         progress_total = ( p.progress + p.job_cur - 1 ) / p.job_count;
778             [fRipIndicator setIndeterminate: NO];
779             [fRipIndicator setDoubleValue: 100.0 * progress_total];
780                         
781             // If progress bar hasn't been revealed at the bottom of the window, do
782             // that now. This code used to be in doRip. I moved it to here to handle
783             // the case where hb_start is called by HBQueueController and not from
784             // HBController.
785             if (!fRipIndicatorShown)
786             {
787                 NSRect frame = [fWindow frame];
788                 if (frame.size.width <= 591)
789                     frame.size.width = 591;
790                 frame.size.height += 36;
791                 frame.origin.y -= 36;
792                 [fWindow setFrame:frame display:YES animate:YES];
793                 fRipIndicatorShown = YES;
794                 /* We check to see if we need to warn the user that the computer will go to sleep
795                    or shut down when encoding is finished */
796                 [self remindUserOfSleepOrShutdown];
797             }
798
799             /* Update dock icon */
800             [self UpdateDockIcon: progress_total];
801                         
802             // Has current job changed? That means the queue has probably changed as
803                         // well so update it
804             [fQueueController hblibStateChanged: s];
805             
806             break;
807         }
808 #undef p
809                         
810 #define p s.param.muxing
811         case HB_STATE_MUXING:
812         {
813             NSMutableString * string;
814                         
815             /* Update text field */
816             string = [NSMutableString stringWithFormat:
817                 _( @"Muxing..." )];
818             [fStatusField setStringValue: string];
819                         
820             /* Update slider */
821             [fRipIndicator setIndeterminate: YES];
822             [fRipIndicator startAnimation: nil];
823                         
824             /* Update dock icon */
825             [self UpdateDockIcon: 1.0];
826                         
827                         // Pass along the info to HBQueueController
828             [fQueueController hblibStateChanged: s];
829                         
830             break;
831         }
832 #undef p
833                         
834         case HB_STATE_PAUSED:
835                     [fStatusField setStringValue: _( @"Paused" )];
836             
837                         // Pass along the info to HBQueueController
838             [fQueueController hblibStateChanged: s];
839
840             break;
841                         
842         case HB_STATE_WORKDONE:
843         {
844             // HB_STATE_WORKDONE happpens as a result of hblib finishing all its jobs
845             // or someone calling hb_stop. In the latter case, hb_stop does not clear
846             // out the remaining passes/jobs in the queue. We'll do that here.
847                         
848             // Delete all remaining scans of this job, ie, delete whole encodes.
849             hb_job_t * job;
850             while( ( job = hb_job( fHandle, 0 ) ) && (job->sequence_id != 0) )
851                 hb_rem( fHandle, job );
852
853             // Start processing back up if jobs still left in queue
854             if (hb_count(fHandle) > 0)
855             {
856                 hb_start(fHandle);
857                 fEncodeState = 1;
858                 // Validate the toolbar (hack). The toolbar will usually get autovalidated
859                 // before we had the chance to restart the queue, hence it will now be in
860                 // the wrong state.
861                 [toolbar validateVisibleItems];
862                 break;
863             }
864
865             [fStatusField setStringValue: _( @"Done." )];
866             [fRipIndicator setIndeterminate: NO];
867             [fRipIndicator setDoubleValue: 0.0];
868             [toolbar validateVisibleItems];
869
870             /* Restore dock icon */
871             [self UpdateDockIcon: -1.0];
872
873             if (fRipIndicatorShown)
874             {
875                 NSRect frame = [fWindow frame];
876                 if (frame.size.width <= 591)
877                                     frame.size.width = 591;
878                 frame.size.height += -36;
879                 frame.origin.y -= -36;
880                 [fWindow setFrame:frame display:YES animate:YES];
881                                 fRipIndicatorShown = NO;
882                         }
883                         
884                         // Pass along the info to HBQueueController
885             [fQueueController hblibStateChanged: s];
886                         
887             /* Check to see if the encode state has not been cancelled
888                                 to determine if we should check for encode done notifications */
889                         if (fEncodeState != 2)                  {
890                                 /* If Growl Notification or Window and Growl has been selected */
891                                 if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Growl Notification"] || 
892                                         [[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Alert Window And Growl"])
893                 {
894                                         /*Growl Notification*/
895                                         [self showGrowlDoneNotification: NULL];
896                 }
897                 /* If Alert Window or Window and Growl has been selected */
898                                 if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Alert Window"] || 
899                                         [[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Alert Window And Growl"])
900                 {
901                                         /*On Screen Notification*/
902                                         int status;
903                                         NSBeep();
904                                         status = NSRunAlertPanel(@"Put down that cocktail...",@"Your HandBrake encode is done!", @"OK", nil, nil);
905                                         [NSApp requestUserAttention:NSCriticalRequest];
906                                         if ( status == NSAlertDefaultReturn ) 
907                                         {
908                                                 [self enableUI: YES];
909                                         }
910                 }
911                                 else
912                                 {
913                                         [self enableUI: YES];
914                                 }
915                                    /* If sleep has been selected */ 
916             if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Put Computer To Sleep"]) 
917                 { 
918                /* Sleep */ 
919                NSDictionary* errorDict; 
920                NSAppleEventDescriptor* returnDescriptor = NULL; 
921                NSAppleScript* scriptObject = [[NSAppleScript alloc] initWithSource: 
922                         @"tell application \"Finder\" to sleep"]; 
923                returnDescriptor = [scriptObject executeAndReturnError: &errorDict]; 
924                [scriptObject release]; 
925                [self enableUI: YES]; 
926                 } 
927             /* If Shutdown has been selected */ 
928             if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Shut Down Computer"]) 
929                 { 
930                /* Shut Down */ 
931                NSDictionary* errorDict; 
932                NSAppleEventDescriptor* returnDescriptor = NULL; 
933                NSAppleScript* scriptObject = [[NSAppleScript alloc] initWithSource: 
934                         @"tell application \"Finder\" to shut down"]; 
935                returnDescriptor = [scriptObject executeAndReturnError: &errorDict]; 
936                [scriptObject release]; 
937                [self enableUI: YES]; 
938                 }
939                         
940                                                 // MetaX insertion via AppleScript
941                         if([[NSUserDefaults standardUserDefaults] boolForKey: @"sendToMetaX"] == YES)
942                         {
943                         NSAppleScript *myScript = [[NSAppleScript alloc] initWithSource: [NSString stringWithFormat: @"%@%@%@", @"tell application \"MetaX\" to open (POSIX file \"", [fDstFile2Field stringValue], @"\")"]];
944                         [myScript executeAndReturnError: nil];
945                         [myScript release];
946                         }
947                         
948                         
949                         }
950                         else
951                         {
952                                 [self enableUI: YES];
953                         }
954             break;
955         }
956     }
957         
958     /* Lets show the queue status here in the main window */
959         int queue_count = hb_count( fHandle );
960         if( queue_count )
961         {
962                 [fQueueStatus setStringValue: [NSString stringWithFormat:
963                         @"%d pass%s in the queue",
964                                                  queue_count, ( queue_count > 1 ) ? "es" : ""]];
965         }
966         else
967         {
968                 [fQueueStatus setStringValue: @""];
969         }
970 }
971
972 - (IBAction) showNewScan:(id)sender
973 {
974         hb_list_t  * list;
975         hb_title_t * title;
976         int indxpri=0;    // Used to search the longuest title (default in combobox)
977         int longuestpri=0; // Used to search the longuest title (default in combobox)
978         
979         list = hb_get_titles( fHandle );
980         
981         if( !hb_list_count( list ) )
982         {
983                 /* We display a message if a valid dvd source was not chosen */
984                 [fSrcDVD2Field setStringValue: @"No Valid Title Found"];
985         SuccessfulScan = NO;
986         }
987         else
988         {
989      /* We increment the successful scancount here by one,
990                    which we use at the end of this function to tell the gui
991                    if this is the first successful scan since launch and whether
992                    or not we should set all settings to the defaults */
993                 
994         currentSuccessfulScanCount++;
995
996         [toolbar validateVisibleItems];
997                 
998                 [fSrcTitlePopUp removeAllItems];
999                 for( int i = 0; i < hb_list_count( list ); i++ )
1000                 {
1001                         title = (hb_title_t *) hb_list_item( list, i );
1002                         
1003             currentSource = [NSString stringWithUTF8String: title->name];
1004             
1005             /* To get the source name as well as the default output name, first we check to see if
1006                the selected directory is the VIDEO_TS Directory */
1007             if ([[currentSource lastPathComponent] isEqualToString: @"VIDEO_TS"])
1008             {
1009             /* If VIDEO_TS Folder is chosen, choose its parent folder for the source display name 
1010                we have to use the title->dvd value so we get the proper name of the volume if a physical dvd is the source*/
1011             sourceDisplayName = [NSString stringWithFormat:[[[NSString stringWithUTF8String: title->dvd] stringByDeletingLastPathComponent] lastPathComponent]];
1012             }
1013             else
1014             {
1015             /* if not the VIDEO_TS Folder, we can assume the chosen folder is the source name */
1016             sourceDisplayName = [NSString stringWithFormat:[currentSource lastPathComponent]];
1017             }
1018                         /*Set DVD Name at top of window*/
1019                         [fSrcDVD2Field setStringValue:[NSString stringWithFormat: @"%@", sourceDisplayName]];
1020                         
1021                         /* Use the dvd name in the default output field here 
1022                                 May want to add code to remove blank spaces for some dvd names*/
1023                         /* Check to see if the last destination has been set,use if so, if not, use Desktop */
1024                         if ([[NSUserDefaults standardUserDefaults] stringForKey:@"LastDestinationDirectory"])
1025                         {
1026                                 [fDstFile2Field setStringValue: [NSString stringWithFormat:
1027                                         @"%@/%@.mp4", [[NSUserDefaults standardUserDefaults] stringForKey:@"LastDestinationDirectory"],sourceDisplayName]];
1028                         }
1029                         else
1030                         {
1031                                 [fDstFile2Field setStringValue: [NSString stringWithFormat:
1032                                         @"%@/Desktop/%@.mp4", NSHomeDirectory(),sourceDisplayName]];
1033                         }
1034                         
1035                         
1036                         if (longuestpri < title->hours*60*60 + title->minutes *60 + title->seconds)
1037                         {
1038                                 longuestpri=title->hours*60*60 + title->minutes *60 + title->seconds;
1039                                 indxpri=i;
1040                         }
1041                         
1042                         
1043         [self formatPopUpChanged:NULL];
1044                         
1045         [fSrcTitlePopUp addItemWithTitle: [NSString
1046                 stringWithFormat: @"%d - %02dh%02dm%02ds",
1047                 title->index, title->hours, title->minutes,
1048                 title->seconds]];
1049                 }
1050         
1051                 // Select the longuest title
1052                 [fSrcTitlePopUp selectItemAtIndex: indxpri];
1053                 [self titlePopUpChanged: NULL];
1054                 
1055         SuccessfulScan = YES;
1056                 [self enableUI: YES];
1057                 
1058                 /* if its the initial successful scan after awakeFromNib */
1059            if (currentSuccessfulScanCount == 1)
1060            {
1061            [self selectDefaultPreset: NULL];
1062            /* if Deinterlace upon launch is specified in the prefs, then set to 1 for "Fast",
1063            if not, then set to 0 for none */
1064            if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultDeinterlaceOn"] > 0)
1065                [fPictureController setDeinterlace:1];
1066            else
1067                [fPictureController setDeinterlace:0];
1068            }
1069        
1070         }
1071 }
1072
1073 -(IBAction)showGrowlDoneNotification:(id)sender
1074 {
1075   [GrowlApplicationBridge 
1076             notifyWithTitle:@"Put down that cocktail..." 
1077                 description:@"your HandBrake encode is done!" 
1078            notificationName:SERVICE_NAME
1079                    iconData:nil 
1080                    priority:0 
1081                    isSticky:1 
1082                clickContext:nil];
1083 }
1084
1085 - (void) enableUI: (bool) b
1086 {
1087     NSControl * controls[] =
1088       { fSrcTitleField, fSrcTitlePopUp,
1089         fSrcChapterField, fSrcChapterStartPopUp, fSrcChapterToField,
1090         fSrcChapterEndPopUp, fSrcDuration1Field, fSrcDuration2Field,
1091         fDstFormatField, fDstFormatPopUp, fDstCodecsField,
1092         fDstCodecsPopUp, fDstFile1Field, fDstFile2Field,
1093         fDstBrowseButton, fVidRateField, fVidRatePopUp,
1094         fVidEncoderField, fVidEncoderPopUp, fVidQualityField,
1095         fVidQualityMatrix, fVidGrayscaleCheck, fSubField, fSubPopUp,
1096         fAudLang1Field, fAudLang1PopUp, fAudLang2Field, fAudLang2PopUp,
1097         fAudTrack1MixLabel, fAudTrack1MixPopUp, fAudTrack2MixLabel, fAudTrack2MixPopUp,
1098         fAudRateField, fAudRatePopUp, fAudBitrateField,
1099         fAudBitratePopUp, fPictureButton,fQueueStatus, 
1100                 fPicSrcWidth,fPicSrcHeight,fPicSettingWidth,fPicSettingHeight,fPicSettingARkeep,
1101                 fPicSettingDeinterlace,fPicLabelSettings,fPicLabelSrc,fPicLabelOutp,
1102                 fPicLabelAr,fPicLabelDeinterlace,fPicLabelSrcX,fPicLabelOutputX,
1103                 fPicLabelPAROutputX,fPicSettingPARWidth,fPicSettingPARHeight,
1104                 fPicSettingPAR,fPicLabelAnamorphic,tableView,fPresetsAdd,fPresetsDelete,
1105                 fCreateChapterMarkers,fVidTurboPassCheck,fDstMpgLargeFileCheck,fPicLabelAutoCrop,
1106                 fPicSettingAutoCrop,fPicSettingDetelecine,fPicLabelDetelecine,fPicLabelDenoise,fPicSettingDenoise,fSubForcedCheck,};
1107
1108     for( unsigned i = 0;
1109          i < sizeof( controls ) / sizeof( NSControl * ); i++ )
1110     {
1111         if( [[controls[i] className] isEqualToString: @"NSTextField"] )
1112         {
1113             NSTextField * tf = (NSTextField *) controls[i];
1114             if( ![tf isBezeled] )
1115             {
1116                 [tf setTextColor: b ? [NSColor controlTextColor] :
1117                     [NSColor disabledControlTextColor]];
1118                 continue;
1119             }
1120         }
1121         [controls[i] setEnabled: b];
1122
1123     }
1124         
1125         if (b) {
1126
1127         /* if we're enabling the interface, check if the audio mixdown controls need to be enabled or not */
1128         /* these will have been enabled by the mass control enablement above anyway, so we're sense-checking it here */
1129         [self setEnabledStateOfAudioMixdownControls: NULL];
1130         
1131         } else {
1132
1133                 [tableView setEnabled: NO];
1134         
1135         }
1136
1137     [self videoMatrixChanged: NULL];
1138     [fAdvancedOptions enableUI:b];
1139 }
1140
1141 - (IBAction) showScanPanel: (id) sender
1142 {
1143     [self enableUI: NO];
1144         [self browseSources:NULL];
1145 }
1146
1147 - (void) browseSources: (id) sender
1148 {
1149     NSOpenPanel * panel;
1150         
1151     panel = [NSOpenPanel openPanel];
1152     [panel setAllowsMultipleSelection: NO];
1153     [panel setCanChooseFiles: YES];
1154     [panel setCanChooseDirectories: YES ];
1155     NSString * sourceDirectory;
1156         if ([[NSUserDefaults standardUserDefaults] stringForKey:@"LastSourceDirectory"])
1157         {
1158                 sourceDirectory = [[NSUserDefaults standardUserDefaults] stringForKey:@"LastSourceDirectory"];
1159         }
1160         else
1161         {
1162                 sourceDirectory = @"~/Desktop";
1163                 sourceDirectory = [sourceDirectory stringByExpandingTildeInPath];
1164         }
1165    [panel beginSheetForDirectory: sourceDirectory file: nil types: nil
1166                                    modalForWindow: fWindow modalDelegate: self
1167                                    didEndSelector: @selector( browseSourcesDone:returnCode:contextInfo: )
1168                                           contextInfo: nil];
1169 }
1170
1171 - (void) browseSourcesDone: (NSOpenPanel *) sheet
1172                  returnCode: (int) returnCode contextInfo: (void *) contextInfo
1173 {
1174     /* User selected a file to open */
1175         if( returnCode == NSOKButton )
1176     {
1177         [fSrcDVD2Field setStringValue: _( @"Opening a new source ..." )];
1178                 [fScanIndicator setHidden: NO];
1179             [fScanIndicator setIndeterminate: YES];
1180         [fScanIndicator startAnimation: nil];
1181                 
1182                 /* we set the last source directory in the prefs here */
1183                 NSString *sourceDirectory = [[[sheet filenames] objectAtIndex: 0] stringByDeletingLastPathComponent];
1184                 [[NSUserDefaults standardUserDefaults] setObject:sourceDirectory forKey:@"LastSourceDirectory"];
1185                 
1186         NSString *path = [[sheet filenames] objectAtIndex: 0];
1187         HBDVDDetector *detector = [HBDVDDetector detectorForPath:path];
1188         if( [detector isVideoDVD] )
1189         {
1190             // The chosen path was actually on a DVD, so use the raw block
1191             // device path instead.
1192             path = [detector devicePath];
1193         }
1194                 
1195                 hb_scan( fHandle, [path UTF8String], 0 );
1196         }
1197         else // User clicked Cancel in browse window
1198         {
1199                 /* if we have a title loaded up */
1200                 if ([[fSrcDVD2Field stringValue] length] > 0)
1201                 {
1202             [self enableUI: YES];
1203         }
1204         }
1205 }
1206
1207 - (IBAction) openMainWindow: (id) sender
1208 {
1209     [fWindow  makeKeyAndOrderFront:nil];
1210 }
1211
1212 - (BOOL) windowShouldClose: (id) sender
1213 {
1214     return YES;
1215 }
1216
1217 - (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag
1218 {
1219     if( !flag ) {
1220         [fWindow  makeKeyAndOrderFront:nil];
1221                 
1222         return YES;
1223     }
1224     
1225     return NO;
1226 }
1227
1228 - (IBAction) videoMatrixChanged: (id) sender;
1229 {
1230     bool target, bitrate, quality;
1231
1232     target = bitrate = quality = false;
1233     if( [fVidQualityMatrix isEnabled] )
1234     {
1235         switch( [fVidQualityMatrix selectedRow] )
1236         {
1237             case 0:
1238                 target = true;
1239                 break;
1240             case 1:
1241                 bitrate = true;
1242                 break;
1243             case 2:
1244                 quality = true;
1245                 break;
1246         }
1247     }
1248     [fVidTargetSizeField  setEnabled: target];
1249     [fVidBitrateField     setEnabled: bitrate];
1250     [fVidQualitySlider    setEnabled: quality];
1251     [fVidTwoPassCheck     setEnabled: !quality &&
1252         [fVidQualityMatrix isEnabled]];
1253     if( quality )
1254     {
1255         [fVidTwoPassCheck setState: NSOffState];
1256                 [fVidTurboPassCheck setHidden: YES];
1257                 [fVidTurboPassCheck setState: NSOffState];
1258     }
1259
1260     [self qualitySliderChanged: sender];
1261     [self calculateBitrate: sender];
1262         [self customSettingUsed: sender];
1263 }
1264
1265 - (IBAction) qualitySliderChanged: (id) sender
1266 {
1267     [fVidConstantCell setTitle: [NSString stringWithFormat:
1268         _( @"Constant quality: %.0f %%" ), 100.0 *
1269         [fVidQualitySlider floatValue]]];
1270                 [self customSettingUsed: sender];
1271 }
1272
1273 - (IBAction) browseFile: (id) sender
1274 {
1275     /* Open a panel to let the user choose and update the text field */
1276     NSSavePanel * panel = [NSSavePanel savePanel];
1277         /* We get the current file name and path from the destination field here */
1278         [panel beginSheetForDirectory: [[fDstFile2Field stringValue] stringByDeletingLastPathComponent] file: [[fDstFile2Field stringValue] lastPathComponent]
1279                                    modalForWindow: fWindow modalDelegate: self
1280                                    didEndSelector: @selector( browseFileDone:returnCode:contextInfo: )
1281                                           contextInfo: NULL];
1282 }
1283
1284 - (void) browseFileDone: (NSSavePanel *) sheet
1285     returnCode: (int) returnCode contextInfo: (void *) contextInfo
1286 {
1287     if( returnCode == NSOKButton )
1288     {
1289         [fDstFile2Field setStringValue: [sheet filename]];
1290     }
1291 }
1292
1293 - (IBAction) showPicturePanel: (id) sender
1294 {
1295         hb_list_t  * list  = hb_get_titles( fHandle );
1296     hb_title_t * title = (hb_title_t *) hb_list_item( list,
1297             [fSrcTitlePopUp indexOfSelectedItem] );
1298     [fPictureController showPanelInWindow:fWindow forTitle:title];
1299 }
1300
1301 - (void)pictureSettingsDidChange {
1302         [self calculatePictureSizing: NULL];
1303 }
1304
1305 - (void) PrepareJob
1306 {
1307     hb_list_t  * list  = hb_get_titles( fHandle );
1308     hb_title_t * title = (hb_title_t *) hb_list_item( list,
1309             [fSrcTitlePopUp indexOfSelectedItem] );
1310     hb_job_t * job = title->job;
1311     //int i;
1312
1313     /* Chapter selection */
1314     job->chapter_start = [fSrcChapterStartPopUp indexOfSelectedItem] + 1;
1315     job->chapter_end   = [fSrcChapterEndPopUp   indexOfSelectedItem] + 1;
1316         
1317     /* Format and codecs */
1318     int format = [fDstFormatPopUp indexOfSelectedItem];
1319     int codecs = [fDstCodecsPopUp indexOfSelectedItem];
1320     job->mux    = FormatSettings[format][codecs] & HB_MUX_MASK;
1321     job->vcodec = FormatSettings[format][codecs] & HB_VCODEC_MASK;
1322     job->acodec = FormatSettings[format][codecs] & HB_ACODEC_MASK;
1323     /* If mpeg-4, then set mpeg-4 specific options like chapters and > 4gb file sizes */
1324         if ([fDstFormatPopUp indexOfSelectedItem] == 0)
1325         {
1326         /* We set the largeFileSize (64 bit formatting) variable here to allow for > 4gb files based on the format being
1327                 mpeg4 and the checkbox being checked 
1328                 *Note: this will break compatibility with some target devices like iPod, etc.!!!!*/
1329                 if ([[NSUserDefaults standardUserDefaults] boolForKey:@"AllowLargeFiles"] > 0 && [fDstMpgLargeFileCheck state] == NSOnState)
1330                 {
1331                         job->largeFileSize = 1;
1332                 }
1333                 else
1334                 {
1335                         job->largeFileSize = 0;
1336                 }
1337         }
1338         if ([fDstFormatPopUp indexOfSelectedItem] == 0 || [fDstFormatPopUp indexOfSelectedItem] == 3)
1339         {
1340           /* We set the chapter marker extraction here based on the format being
1341                 mpeg4 or mkv and the checkbox being checked */
1342                 if ([fCreateChapterMarkers state] == NSOnState)
1343                 {
1344                         job->chapter_markers = 1;
1345                 }
1346                 else
1347                 {
1348                         job->chapter_markers = 0;
1349                 }
1350         }
1351         if( ( job->vcodec & HB_VCODEC_FFMPEG ) &&
1352         [fVidEncoderPopUp indexOfSelectedItem] > 0 )
1353     {
1354         job->vcodec = HB_VCODEC_XVID;
1355     }
1356     if( job->vcodec & HB_VCODEC_X264 )
1357     {
1358                 if ([fVidEncoderPopUp indexOfSelectedItem] > 0 )
1359             {
1360                         /* Just use new Baseline Level 3.0 
1361                         Lets Deprecate Baseline Level 1.3h264_level*/
1362                         job->h264_level = 30;
1363                         job->mux = HB_MUX_IPOD;
1364                         /* move sanity check for iPod Encoding here */
1365                         job->pixel_ratio = 0 ;
1366                         
1367                 }
1368                 
1369                 /* Set this flag to switch from Constant Quantizer(default) to Constant Rate Factor Thanks jbrjake
1370                 Currently only used with Constant Quality setting*/
1371                 if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultCrf"] > 0 && [fVidQualityMatrix selectedRow] == 2)
1372                 {
1373                 job->crf = 1;
1374                 }
1375                 
1376                 /* Below Sends x264 options to the core library if x264 is selected*/
1377                 /* Lets use this as per Nyx, Thanks Nyx!*/
1378                 job->x264opts = (char *)calloc(1024, 1); /* Fixme, this just leaks */
1379                 /* Turbo first pass if two pass and Turbo First pass is selected */
1380                 if( [fVidTwoPassCheck state] == NSOnState && [fVidTurboPassCheck state] == NSOnState )
1381                 {
1382                         /* pass the "Turbo" string to be appended to the existing x264 opts string into a variable for the first pass */
1383                         NSString *firstPassOptStringTurbo = @":ref=1:subme=1:me=dia:analyse=none:trellis=0:no-fast-pskip=0:8x8dct=0";
1384                         /* append the "Turbo" string variable to the existing opts string.
1385                         Note: the "Turbo" string must be appended, not prepended to work properly*/
1386                         NSString *firstPassOptStringCombined = [[fAdvancedOptions optionsString] stringByAppendingString:firstPassOptStringTurbo];
1387                         strcpy(job->x264opts, [firstPassOptStringCombined UTF8String]);
1388                 }
1389                 else
1390                 {
1391                         strcpy(job->x264opts, [[fAdvancedOptions optionsString] UTF8String]);
1392                 }
1393                 
1394         job->h264_13 = [fVidEncoderPopUp indexOfSelectedItem];
1395     }
1396
1397     /* Video settings */
1398     if( [fVidRatePopUp indexOfSelectedItem] > 0 )
1399     {
1400         job->vrate      = 27000000;
1401         job->vrate_base = hb_video_rates[[fVidRatePopUp
1402             indexOfSelectedItem]-1].rate;
1403     }
1404     else
1405     {
1406         job->vrate      = title->rate;
1407         job->vrate_base = title->rate_base;
1408     }
1409
1410     switch( [fVidQualityMatrix selectedRow] )
1411     {
1412         case 0:
1413             /* Target size.
1414                Bitrate should already have been calculated and displayed
1415                in fVidBitrateField, so let's just use it */
1416         case 1:
1417             job->vquality = -1.0;
1418             job->vbitrate = [fVidBitrateField intValue];
1419             break;
1420         case 2:
1421             job->vquality = [fVidQualitySlider floatValue];
1422             job->vbitrate = 0;
1423             break;
1424     }
1425
1426     job->grayscale = ( [fVidGrayscaleCheck state] == NSOnState );
1427
1428     /* Subtitle settings */
1429     job->subtitle = [fSubPopUp indexOfSelectedItem] - 2;
1430
1431     /* Audio tracks and mixdowns */
1432     /* check for the condition where track 2 has an audio selected, but track 1 does not */
1433     /* we will use track 2 as track 1 in this scenario */
1434     if ([fAudLang1PopUp indexOfSelectedItem] > 0)
1435     {
1436         job->audios[0] = [fAudLang1PopUp indexOfSelectedItem] - 1;
1437         job->audios[1] = [fAudLang2PopUp indexOfSelectedItem] - 1; /* will be -1 if "none" is selected */
1438         job->audios[2] = -1;
1439         job->audio_mixdowns[0] = [[fAudTrack1MixPopUp selectedItem] tag];
1440         job->audio_mixdowns[1] = [[fAudTrack2MixPopUp selectedItem] tag];
1441     }
1442     else if ([fAudLang2PopUp indexOfSelectedItem] > 0)
1443     {
1444         job->audios[0] = [fAudLang2PopUp indexOfSelectedItem] - 1;
1445         job->audio_mixdowns[0] = [[fAudTrack2MixPopUp selectedItem] tag];
1446         job->audios[1] = -1;
1447     }
1448     else
1449     {
1450         job->audios[0] = -1;
1451     }
1452
1453     /* Audio settings */
1454     job->arate = hb_audio_rates[[fAudRatePopUp
1455                      indexOfSelectedItem]].rate;
1456     job->abitrate = [[fAudBitratePopUp selectedItem] tag];
1457     
1458     job->filters = hb_list_init();
1459    
1460         /* Detelecine */
1461     if ([fPictureController detelecine])
1462     {
1463         hb_list_add( job->filters, &hb_filter_detelecine );
1464     }
1465    
1466     /* Deinterlace */
1467     if ([fPictureController deinterlace] == 1)
1468     {
1469         /* Run old deinterlacer by default */
1470         hb_filter_deinterlace.settings = "-1"; 
1471         hb_list_add( job->filters, &hb_filter_deinterlace );
1472     }
1473     else if ([fPictureController deinterlace] == 2)
1474     {
1475         /* Yadif mode 0 (1-pass with spatial deinterlacing.) */
1476         hb_filter_deinterlace.settings = "0"; 
1477         hb_list_add( job->filters, &hb_filter_deinterlace );            
1478     }
1479     else if ([fPictureController deinterlace] == 3)
1480     {
1481         /* Yadif (1-pass w/o spatial deinterlacing) and Mcdeint */
1482         hb_filter_deinterlace.settings = "2:-1:1"; 
1483         hb_list_add( job->filters, &hb_filter_deinterlace );            
1484     }
1485     else if ([fPictureController deinterlace] == 4)
1486     {
1487         /* Yadif (2-pass w/ spatial deinterlacing) and Mcdeint*/
1488         hb_filter_deinterlace.settings = "1:-1:1"; 
1489         hb_list_add( job->filters, &hb_filter_deinterlace );            
1490     }
1491         
1492         /* Denoise */
1493         
1494         if ([fPictureController denoise] == 1) // Weak in popup
1495         {
1496                 hb_filter_denoise.settings = "2:1:2:3"; 
1497         hb_list_add( job->filters, &hb_filter_denoise );        
1498         }
1499         else if ([fPictureController denoise] == 2) // Medium in popup
1500         {
1501                 hb_filter_denoise.settings = "3:2:2:3"; 
1502         hb_list_add( job->filters, &hb_filter_denoise );        
1503         }
1504         else if ([fPictureController denoise] == 3) // Strong in popup
1505         {
1506                 hb_filter_denoise.settings = "7:7:5:5"; 
1507         hb_list_add( job->filters, &hb_filter_denoise );        
1508         }
1509
1510 }
1511
1512
1513
1514 /* addToQueue: puts up an alert before ultimately calling doAddToQueue
1515 */
1516 - (IBAction) addToQueue: (id) sender
1517 {
1518         /* We get the destination directory from the destination field here */
1519         NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent];
1520         /* We check for a valid destination here */
1521         if ([[NSFileManager defaultManager] fileExistsAtPath:destinationDirectory] == 0) 
1522         {
1523                 NSRunAlertPanel(@"Warning!", @"This is not a valid destination directory!", @"OK", nil, nil);
1524         return;
1525         }
1526
1527     /* We check for duplicate name here */
1528         if( [[NSFileManager defaultManager] fileExistsAtPath:
1529             [fDstFile2Field stringValue]] )
1530     {
1531         NSBeginCriticalAlertSheet( _( @"File already exists" ),
1532             _( @"Cancel" ), _( @"Overwrite" ), NULL, fWindow, self,
1533             @selector( overwriteAddToQueueAlertDone:returnCode:contextInfo: ),
1534             NULL, NULL, [NSString stringWithFormat:
1535             _( @"Do you want to overwrite %@?" ),
1536             [fDstFile2Field stringValue]] );
1537         // overwriteAddToQueueAlertDone: will be called when the alert is dismissed.
1538     }
1539     else
1540     {
1541         [self doAddToQueue];
1542     }
1543 }
1544
1545 /* overwriteAddToQueueAlertDone: called from the alert posted by addToQueue that asks
1546    the user if they want to overwrite an exiting movie file.
1547 */
1548 - (void) overwriteAddToQueueAlertDone: (NSWindow *) sheet
1549     returnCode: (int) returnCode contextInfo: (void *) contextInfo
1550 {
1551     if( returnCode == NSAlertAlternateReturn )
1552         [self doAddToQueue];
1553 }
1554
1555 - (void) doAddToQueue
1556 {
1557     hb_list_t  * list  = hb_get_titles( fHandle );
1558     hb_title_t * title = (hb_title_t *) hb_list_item( list, [fSrcTitlePopUp indexOfSelectedItem] );
1559     hb_job_t * job = title->job;
1560
1561     // Assign a sequence number, starting at zero, to each job added so they can
1562     // be lumped together in the UI.
1563     job->sequence_id = -1;
1564
1565     [self PrepareJob];
1566
1567     /* Destination file */
1568     job->file = [[fDstFile2Field stringValue] UTF8String];
1569
1570     if( [fSubForcedCheck state] == NSOnState )
1571         job->subtitle_force = 1;
1572     else
1573         job->subtitle_force = 0;
1574
1575     /*
1576     * subtitle of -1 is a scan
1577     */
1578     if( job->subtitle == -1 )
1579     {
1580         char *x264opts_tmp;
1581
1582         /*
1583         * When subtitle scan is enabled do a fast pre-scan job
1584         * which will determine which subtitles to enable, if any.
1585         */
1586         job->pass = -1;
1587         x264opts_tmp = job->x264opts;
1588         job->subtitle = -1;
1589
1590         job->x264opts = NULL;
1591
1592         job->indepth_scan = 1;  
1593
1594         job->select_subtitle = (hb_subtitle_t**)malloc(sizeof(hb_subtitle_t*));
1595         *(job->select_subtitle) = NULL;
1596
1597         /*
1598         * Add the pre-scan job
1599         */
1600         job->sequence_id++; // for job grouping
1601         hb_add( fHandle, job );
1602
1603         job->x264opts = x264opts_tmp;
1604     }
1605     else
1606         job->select_subtitle = NULL;
1607
1608     /* No subtitle were selected, so reset the subtitle to -1 (which before
1609     * this point meant we were scanning
1610     */
1611     if( job->subtitle == -2 )
1612         job->subtitle = -1;
1613
1614     if( [fVidTwoPassCheck state] == NSOnState )
1615     {
1616         hb_subtitle_t **subtitle_tmp = job->select_subtitle;
1617         job->indepth_scan = 0;
1618
1619         /*
1620          * Do not autoselect subtitles on the first pass of a two pass
1621          */
1622         job->select_subtitle = NULL;
1623         
1624         job->pass = 1;
1625         job->sequence_id++; // for job grouping
1626         hb_add( fHandle, job );
1627
1628         job->pass = 2;
1629         job->sequence_id++; // for job grouping
1630
1631         job->x264opts = (char *)calloc(1024, 1); /* Fixme, this just leaks */  
1632         strcpy(job->x264opts, [[fAdvancedOptions optionsString] UTF8String]);
1633
1634         job->select_subtitle = subtitle_tmp;
1635
1636         hb_add( fHandle, job );
1637     }
1638     else
1639     {
1640         job->indepth_scan = 0;
1641         job->pass = 0;
1642         job->sequence_id++; // for job grouping
1643         hb_add( fHandle, job );
1644     }
1645         
1646     NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent];
1647         [[NSUserDefaults standardUserDefaults] setObject:destinationDirectory forKey:@"LastDestinationDirectory"];
1648         
1649     // Notify the queue
1650         [fQueueController hblibJobListChanged];
1651 }
1652
1653 /* Rip: puts up an alert before ultimately calling doRip
1654 */
1655 - (IBAction) Rip: (id) sender
1656 {
1657     /* Rip or Cancel ? */
1658     hb_state_t s;
1659     hb_get_state2( fHandle, &s );
1660
1661     if(s.state == HB_STATE_WORKING || s.state == HB_STATE_PAUSED)
1662         {
1663         [self Cancel: sender];
1664         return;
1665     }
1666     
1667     // If there are jobs in the queue, then this is a rip the queue
1668     
1669     if (hb_count( fHandle ) > 0)
1670     {
1671         [self doRip];
1672         return;
1673     }
1674
1675     // Before adding jobs to the queue, check for a valid destination.
1676
1677     NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent];
1678     if ([[NSFileManager defaultManager] fileExistsAtPath:destinationDirectory] == 0) 
1679     {
1680         NSRunAlertPanel(@"Warning!", @"This is not a valid destination directory!", @"OK", nil, nil);
1681         return;
1682     }
1683
1684     /* We check for duplicate name here */
1685     if( [[NSFileManager defaultManager] fileExistsAtPath:[fDstFile2Field stringValue]] )
1686     {
1687         NSBeginCriticalAlertSheet( _( @"File already exists" ),
1688             _( @"Cancel" ), _( @"Overwrite" ), NULL, fWindow, self,
1689             @selector( overWriteAlertDone:returnCode:contextInfo: ),
1690             NULL, NULL, [NSString stringWithFormat:
1691             _( @"Do you want to overwrite %@?" ),
1692             [fDstFile2Field stringValue]] );
1693             
1694         // overWriteAlertDone: will be called when the alert is dismissed. It will call doRip.
1695     }
1696     else
1697     {
1698         /* if there are no jobs in the queue, then add this one to the queue and rip 
1699         otherwise, just rip the queue */
1700         if( hb_count( fHandle ) == 0)
1701         {
1702             [self doAddToQueue];
1703         }
1704
1705         NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent];
1706         [[NSUserDefaults standardUserDefaults] setObject:destinationDirectory forKey:@"LastDestinationDirectory"];
1707         [self doRip];
1708     }
1709 }
1710
1711 /* overWriteAlertDone: called from the alert posted by Rip: that asks the user if they
1712    want to overwrite an exiting movie file.
1713 */
1714 - (void) overWriteAlertDone: (NSWindow *) sheet
1715     returnCode: (int) returnCode contextInfo: (void *) contextInfo
1716 {
1717     if( returnCode == NSAlertAlternateReturn )
1718     {
1719         /* if there are no jobs in the queue, then add this one to the queue and rip 
1720         otherwise, just rip the queue */
1721         if( hb_count( fHandle ) == 0 )
1722         {
1723             [self doAddToQueue];
1724         }
1725
1726         NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent];
1727         [[NSUserDefaults standardUserDefaults] setObject:destinationDirectory forKey:@"LastDestinationDirectory"];
1728         [self doRip];
1729     }
1730 }
1731
1732 - (void) updateAlertDone: (NSWindow *) sheet
1733     returnCode: (int) returnCode contextInfo: (void *) contextInfo
1734 {
1735     if( returnCode == NSAlertAlternateReturn )
1736     {
1737         /* Show scan panel */
1738         [self performSelectorOnMainThread: @selector(showScanPanel:)
1739             withObject: NULL waitUntilDone: NO];
1740         return;
1741     }
1742
1743     /* Go to HandBrake homepage and exit */
1744     [self openHomepage: NULL];
1745     [NSApp terminate: self];
1746 }
1747
1748 - (void) remindUserOfSleepOrShutdown
1749 {
1750        if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Put Computer To Sleep"])
1751        {
1752                /*Warn that computer will sleep after encoding*/
1753                int reminduser;
1754                NSBeep();
1755                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);
1756                [NSApp requestUserAttention:NSCriticalRequest];
1757                if ( reminduser == NSAlertAlternateReturn ) 
1758                {
1759                        [self showPreferencesWindow:NULL];
1760                }
1761        } 
1762        else if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Shut Down Computer"])
1763        {
1764                /*Warn that computer will shut down after encoding*/
1765                int reminduser;
1766                NSBeep();
1767                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);
1768                [NSApp requestUserAttention:NSCriticalRequest];
1769                if ( reminduser == NSAlertAlternateReturn ) 
1770                {
1771                        [self showPreferencesWindow:NULL];
1772                }
1773        }
1774
1775 }
1776
1777
1778 - (void) doRip
1779 {
1780     /* Let libhb do the job */
1781     hb_start( fHandle );
1782         /*set the fEncodeState State */
1783         fEncodeState = 1;
1784 }
1785
1786
1787
1788
1789 //------------------------------------------------------------------------------------
1790 // Removes all jobs from the queue. Does not cancel the current processing job.
1791 //------------------------------------------------------------------------------------
1792 - (void) doDeleteQueuedJobs
1793 {
1794     hb_job_t * job;
1795     while( ( job = hb_job( fHandle, 0 ) ) )
1796         hb_rem( fHandle, job );
1797 }
1798
1799 //------------------------------------------------------------------------------------
1800 // Cancels the current job and proceeds with the next one in the queue.
1801 //------------------------------------------------------------------------------------
1802 - (void) doCancelCurrentJob
1803 {
1804     // Stop the current job. hb_stop will only cancel the current pass and then set
1805     // its state to HB_STATE_WORKDONE. It also does this asynchronously. So when we
1806     // see the state has changed to HB_STATE_WORKDONE (in updateUI), we'll delete the
1807     // remaining passes of the job and then start the queue back up if there are any
1808     // remaining jobs.
1809      
1810     [fQueueController hblibWillStop];
1811     hb_stop( fHandle );
1812     fEncodeState = 2;   // don't alert at end of processing since this was a cancel
1813     
1814 }
1815
1816 //------------------------------------------------------------------------------------
1817 // Displays an alert asking user if the want to cancel encoding of current job.
1818 // Cancel: returns immediately after posting the alert. Later, when the user
1819 // acknowledges the alert, doCancelCurrentJob is called.
1820 //------------------------------------------------------------------------------------
1821 - (IBAction)Cancel: (id)sender
1822 {
1823     if (!fHandle) return;
1824     
1825     hb_job_t * job = hb_current_job(fHandle);
1826     if (!job) return;
1827
1828     NSString * alertTitle = [NSString stringWithFormat:NSLocalizedString(@"Do you want to stop encoding of %@?", nil),
1829             [NSString stringWithUTF8String:job->title->name]];
1830     
1831     // Which window to attach the sheet to?
1832     NSWindow * docWindow;
1833     if ([sender respondsToSelector: @selector(window)])
1834         docWindow = [sender window];
1835     else
1836         docWindow = fWindow;
1837         
1838     NSBeginCriticalAlertSheet(
1839             alertTitle,
1840             NSLocalizedString(@"Keep Encoding", nil),
1841             NSLocalizedString(@"Delete All", nil),
1842             NSLocalizedString(@"Stop Encoding", nil),
1843             docWindow, self,
1844             nil, @selector(didDimissCancelCurrentJob:returnCode:contextInfo:), nil,
1845             NSLocalizedString(@"Your movie will be lost if you don't continue encoding.", nil),
1846             [NSString stringWithUTF8String:job->title->name]);
1847     
1848     // didDimissCancelCurrentJob:returnCode:contextInfo: will be called when the dialog is dismissed
1849
1850     // N.B.: didDimissCancelCurrentJob:returnCode:contextInfo: is designated as the dismiss
1851     // selector to prevent a crash. As a dismiss selector, the alert window will
1852     // have already be dismissed. If we don't do it this way, the dismissing of
1853     // the alert window will cause the table view to be redrawn at a point where
1854     // current job has been deleted by hblib but we don't know about it yet. This
1855     // is a prime example of wy we need to NOT be relying on hb_current_job!!!!
1856 }
1857
1858 - (void) didDimissCancelCurrentJob: (NSWindow *)sheet returnCode: (int)returnCode contextInfo: (void *)contextInfo
1859 {
1860     if (returnCode == NSAlertOtherReturn)
1861         [self doCancelCurrentJob];
1862     else if (returnCode == NSAlertAlternateReturn)
1863     {
1864         [self doDeleteQueuedJobs];
1865         [self doCancelCurrentJob];
1866     }
1867 }
1868
1869
1870
1871
1872
1873 - (IBAction) Pause: (id) sender
1874 {
1875     hb_state_t s;
1876     hb_get_state2( fHandle, &s );
1877
1878     if( s.state == HB_STATE_PAUSED )
1879     {
1880         hb_resume( fHandle );
1881     }
1882     else
1883     {
1884         hb_pause( fHandle );
1885     }
1886 }
1887
1888 - (IBAction) titlePopUpChanged: (id) sender
1889 {
1890     hb_list_t  * list  = hb_get_titles( fHandle );
1891     hb_title_t * title = (hb_title_t*)
1892         hb_list_item( list, [fSrcTitlePopUp indexOfSelectedItem] );
1893                 
1894                 
1895     /* If Auto Naming is on. We create an output filename of dvd name - title number */
1896     if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultAutoNaming"] > 0)
1897         {
1898                 [fDstFile2Field setStringValue: [NSString stringWithFormat:
1899                         @"%@/%@-%d.%@", [[fDstFile2Field stringValue] stringByDeletingLastPathComponent],
1900                         [NSString stringWithUTF8String: title->name],
1901                           title->index,
1902                         [[fDstFile2Field stringValue] pathExtension]]]; 
1903         }
1904
1905     /* Update chapter popups */
1906     [fSrcChapterStartPopUp removeAllItems];
1907     [fSrcChapterEndPopUp   removeAllItems];
1908     for( int i = 0; i < hb_list_count( title->list_chapter ); i++ )
1909     {
1910         [fSrcChapterStartPopUp addItemWithTitle: [NSString
1911             stringWithFormat: @"%d", i + 1]];
1912         [fSrcChapterEndPopUp addItemWithTitle: [NSString
1913             stringWithFormat: @"%d", i + 1]];
1914     }
1915     [fSrcChapterStartPopUp selectItemAtIndex: 0];
1916     [fSrcChapterEndPopUp   selectItemAtIndex:
1917         hb_list_count( title->list_chapter ) - 1];
1918     [self chapterPopUpChanged: NULL];
1919
1920 /* Start Get and set the initial pic size for display */
1921         hb_job_t * job = title->job;
1922         fTitle = title; 
1923         /* Turn Deinterlace on/off depending on the preference */
1924         if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultDeinterlaceOn"] > 0)
1925         {
1926                 [fPictureController setDeinterlace:1];
1927         }
1928         else
1929         {
1930                 [fPictureController setDeinterlace:0];
1931         }
1932         
1933         /* Pixel Ratio Setting */
1934         if ([[NSUserDefaults standardUserDefaults] boolForKey:@"PixelRatio"])
1935     {
1936                 job->pixel_ratio = 1 ;
1937         }
1938         else
1939         {
1940                 job->pixel_ratio = 0 ;
1941         }
1942         /*Set Source Size Fields Here */
1943         [fPicSrcWidth setStringValue: [NSString stringWithFormat:
1944                                                          @"%d", fTitle->width]];
1945         [fPicSrcHeight setStringValue: [NSString stringWithFormat:
1946                                                          @"%d", fTitle->height]];
1947                                                          
1948         /* Set Auto Crop to on upon selecting a new title */
1949     [fPictureController setAutoCrop:YES];
1950     
1951         /* We get the originial output picture width and height and put them
1952         in variables for use with some presets later on */
1953         PicOrigOutputWidth = job->width;
1954         PicOrigOutputHeight = job->height;
1955         AutoCropTop = job->crop[0];
1956         AutoCropBottom = job->crop[1];
1957         AutoCropLeft = job->crop[2];
1958         AutoCropRight = job->crop[3];
1959         /* we test getting the max output value for pic sizing here to be used later*/
1960         [fPicSettingWidth setStringValue: [NSString stringWithFormat:
1961                 @"%d", PicOrigOutputWidth]];
1962         [fPicSettingHeight setStringValue: [NSString stringWithFormat:
1963                 @"%d", PicOrigOutputHeight]];
1964         /* we run the picture size values through
1965         calculatePictureSizing to get all picture size
1966         information*/
1967         [self calculatePictureSizing: NULL];
1968         /* Run Through encoderPopUpChanged to see if there
1969                 needs to be any pic value modifications based on encoder settings */
1970         //[self encoderPopUpChanged: NULL];
1971         /* END Get and set the initial pic size for display */ 
1972
1973     /* Update subtitle popups */
1974     hb_subtitle_t * subtitle;
1975     [fSubPopUp removeAllItems];
1976     [fSubPopUp addItemWithTitle: @"None"];
1977     [fSubPopUp addItemWithTitle: @"Autoselect"];
1978     for( int i = 0; i < hb_list_count( title->list_subtitle ); i++ )
1979     {
1980         subtitle = (hb_subtitle_t *) hb_list_item( title->list_subtitle, i );
1981
1982         /* We cannot use NSPopUpButton's addItemWithTitle because
1983            it checks for duplicate entries */
1984         [[fSubPopUp menu] addItemWithTitle: [NSString stringWithCString:
1985             subtitle->lang] action: NULL keyEquivalent: @""];
1986     }
1987     [fSubPopUp selectItemAtIndex: 0];
1988         
1989         [self subtitleSelectionChanged: NULL];
1990     
1991     /* Update chapter table */
1992     [fChapterTitlesDelegate resetWithTitle:title];
1993     [fChapterTable reloadData];
1994
1995     /* Update audio popups */
1996     [self addAllAudioTracksToPopUp: fAudLang1PopUp];
1997     [self addAllAudioTracksToPopUp: fAudLang2PopUp];
1998     /* search for the first instance of our prefs default language for track 1, and set track 2 to "none" */
1999         NSString * audioSearchPrefix = [[NSUserDefaults standardUserDefaults] stringForKey:@"DefaultLanguage"];
2000         [self selectAudioTrackInPopUp: fAudLang1PopUp searchPrefixString: audioSearchPrefix selectIndexIfNotFound: 1];
2001     [self selectAudioTrackInPopUp: fAudLang2PopUp searchPrefixString: NULL selectIndexIfNotFound: 0];
2002         
2003         /* changing the title may have changed the audio channels on offer, */
2004         /* so call audioTrackPopUpChanged for both audio tracks to update the mixdown popups */
2005         [self audioTrackPopUpChanged: fAudLang1PopUp];
2006         [self audioTrackPopUpChanged: fAudLang2PopUp];
2007     
2008     /* We repopulate the Video Framerate popup and show the detected framerate along with "Same as Source"*/
2009     [fVidRatePopUp removeAllItems];
2010     if (fTitle->rate_base == 1126125) // 23.976 NTSC Film
2011     {
2012         [fVidRatePopUp addItemWithTitle: @"Same as source (23.976)"];
2013     }
2014     else if (fTitle->rate_base == 1080000) // 25 PAL Film/Video
2015     {
2016         [fVidRatePopUp addItemWithTitle: @"Same as source (25)"];
2017     }
2018     else if (fTitle->rate_base == 900900) // 29.97 NTSC Video
2019     {
2020         [fVidRatePopUp addItemWithTitle: @"Same as source (29.97)"];
2021     }
2022     else
2023     {
2024         /* if none of the common dvd source framerates is detected, just use "Same as source" */
2025         [fVidRatePopUp addItemWithTitle: @"Same as source"];
2026     }
2027         for( int i = 0; i < hb_video_rates_count; i++ )
2028     {
2029         if ([[NSString stringWithCString: hb_video_rates[i].string] isEqualToString: [NSString stringWithFormat: @"%.3f",23.976]])
2030                 {
2031                         [fVidRatePopUp addItemWithTitle:[NSString stringWithFormat: @"%@%@",
2032                                 [NSString stringWithCString: hb_video_rates[i].string], @" (NTSC Film)"]];
2033                 }
2034                 else if ([[NSString stringWithCString: hb_video_rates[i].string] isEqualToString: [NSString stringWithFormat: @"%d",25]])
2035                 {
2036                         [fVidRatePopUp addItemWithTitle:[NSString stringWithFormat: @"%@%@",
2037                                 [NSString stringWithCString: hb_video_rates[i].string], @" (PAL Film/Video)"]];
2038                 }
2039                 else if ([[NSString stringWithCString: hb_video_rates[i].string] isEqualToString: [NSString stringWithFormat: @"%.2f",29.97]])
2040                 {
2041                         [fVidRatePopUp addItemWithTitle:[NSString stringWithFormat: @"%@%@",
2042                                 [NSString stringWithCString: hb_video_rates[i].string], @" (NTSC Video)"]];
2043                 }
2044                 else
2045                 {
2046                         [fVidRatePopUp addItemWithTitle:
2047                                 [NSString stringWithCString: hb_video_rates[i].string]];
2048                 }
2049     }   
2050     [fVidRatePopUp selectItemAtIndex: 0];
2051     
2052    /* lets call tableViewSelected to make sure that any preset we have selected is enforced after a title change */
2053         [self tableViewSelected:NULL]; 
2054         
2055 }
2056
2057 - (IBAction) chapterPopUpChanged: (id) sender
2058 {
2059     
2060         /* If start chapter popup is greater than end chapter popup,
2061         we set the end chapter popup to the same as start chapter popup */
2062         if ([fSrcChapterStartPopUp indexOfSelectedItem] > [fSrcChapterEndPopUp indexOfSelectedItem])
2063         {
2064                 [fSrcChapterEndPopUp selectItemAtIndex: [fSrcChapterStartPopUp indexOfSelectedItem]];
2065     }
2066
2067                 
2068         hb_list_t  * list  = hb_get_titles( fHandle );
2069     hb_title_t * title = (hb_title_t *)
2070         hb_list_item( list, [fSrcTitlePopUp indexOfSelectedItem] );
2071
2072     hb_chapter_t * chapter;
2073     int64_t        duration = 0;
2074     for( int i = [fSrcChapterStartPopUp indexOfSelectedItem];
2075          i <= [fSrcChapterEndPopUp indexOfSelectedItem]; i++ )
2076     {
2077         chapter = (hb_chapter_t *) hb_list_item( title->list_chapter, i );
2078         duration += chapter->duration;
2079     }
2080     
2081     duration /= 90000; /* pts -> seconds */
2082     [fSrcDuration2Field setStringValue: [NSString stringWithFormat:
2083         @"%02lld:%02lld:%02lld", duration / 3600, ( duration / 60 ) % 60,
2084         duration % 60]];
2085
2086     [self calculateBitrate: sender];
2087 }
2088
2089 - (IBAction) formatPopUpChanged: (id) sender
2090 {
2091     NSString * string = [fDstFile2Field stringValue];
2092     NSString * selectedCodecs = [fDstCodecsPopUp titleOfSelectedItem];
2093     int format = [fDstFormatPopUp indexOfSelectedItem];
2094     char * ext = NULL;
2095         /* Initially set the large file (64 bit formatting) output checkbox to hidden */
2096     [fDstMpgLargeFileCheck setHidden: YES];
2097     /* Update the codecs popup */
2098     [fDstCodecsPopUp removeAllItems];
2099     switch( format )
2100     {
2101         case 0:
2102                         /*Get Default MP4 File Extension*/
2103                         if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultMpegName"] > 0)
2104                         {
2105                                 ext = "m4v";
2106                         }
2107                         else
2108                         {
2109                                 ext = "mp4";
2110                         }
2111             
2112             [fDstCodecsPopUp addItemWithTitle:_( @"MPEG-4 Video / AAC Audio" )];
2113             [fDstCodecsPopUp addItemWithTitle:_( @"AVC/H.264 Video / AAC Audio" )];
2114             
2115                         /* We enable the create chapters checkbox here since we are .mp4*/
2116                         [fCreateChapterMarkers setEnabled: YES];
2117                         /* We show the Large File (64 bit formatting) checkbox since we are .mp4 
2118                         if we have enabled the option in the global preferences*/
2119                         if ([[NSUserDefaults standardUserDefaults] boolForKey:@"AllowLargeFiles"] > 0)
2120                         {
2121                                 [fDstMpgLargeFileCheck setHidden: NO];
2122                         }
2123                                 else
2124                                 {
2125                                         /* if not enable in global preferences, we additionaly sanity check that the
2126                                         hidden checkbox is set to off. */
2127                     [fDstMpgLargeFileCheck setState: NSOffState];
2128                                 }
2129             break;
2130             
2131         case 1:
2132             ext = "mkv";
2133             [fDstCodecsPopUp addItemWithTitle:_( @"MPEG-4 Video / AAC Audio" )];
2134             [fDstCodecsPopUp addItemWithTitle:_( @"MPEG-4 Video / AC-3 Audio" )];
2135                         [fDstCodecsPopUp addItemWithTitle:_( @"MPEG-4 Video / MP3 Audio" )];
2136                         [fDstCodecsPopUp addItemWithTitle:_( @"MPEG-4 Video / Vorbis Audio" )];
2137             
2138                         [fDstCodecsPopUp addItemWithTitle:_( @"AVC/H.264 Video / AAC Audio" )];
2139                         [fDstCodecsPopUp addItemWithTitle:_( @"AVC/H.264 Video / AC-3 Audio" )];
2140                         [fDstCodecsPopUp addItemWithTitle:_( @"AVC/H.264 Video / MP3 Audio" )];
2141                         [fDstCodecsPopUp addItemWithTitle:_( @"AVC/H.264 Video / Vorbis Audio" )];
2142             /* We enable the create chapters checkbox here */
2143                         [fCreateChapterMarkers setEnabled: YES];
2144                         break;
2145             
2146         case 2: 
2147             ext = "avi";
2148             [fDstCodecsPopUp addItemWithTitle:_( @"MPEG-4 Video / MP3 Audio" )];
2149             [fDstCodecsPopUp addItemWithTitle:_( @"MPEG-4 Video / AC-3 Audio" )];
2150             [fDstCodecsPopUp addItemWithTitle:_( @"AVC/H.264 Video / MP3 Audio" )];
2151             [fDstCodecsPopUp addItemWithTitle:_( @"AVC/H.264 Video / AC-3 Audio" )];
2152                         /* We disable the create chapters checkbox here and make sure it is unchecked*/
2153                         [fCreateChapterMarkers setEnabled: NO];
2154                         [fCreateChapterMarkers setState: NSOffState];
2155                         break;
2156             
2157         case 3:
2158             ext = "ogm";
2159             [fDstCodecsPopUp addItemWithTitle:_( @"MPEG-4 Video / Vorbis Audio" )];
2160             [fDstCodecsPopUp addItemWithTitle:_( @"MPEG-4 Video / MP3 Audio" )];
2161             /* We disable the create chapters checkbox here and make sure it is unchecked*/
2162                         [fCreateChapterMarkers setEnabled: NO];
2163                         [fCreateChapterMarkers setState: NSOffState];
2164                         break;
2165     }
2166     
2167     if ( SuccessfulScan ) {
2168         [fDstCodecsPopUp selectItemWithTitle:selectedCodecs];
2169         
2170         /* Add/replace to the correct extension */
2171         if( [string characterAtIndex: [string length] - 4] == '.' )
2172         {
2173             [fDstFile2Field setStringValue: [NSString stringWithFormat:
2174                 @"%@.%s", [string substringToIndex: [string length] - 4],
2175                 ext]];
2176         }
2177         else
2178         {
2179             [fDstFile2Field setStringValue: [NSString stringWithFormat:
2180                 @"%@.%s", string, ext]];
2181         }
2182         
2183         if ( [fDstCodecsPopUp selectedItem] == NULL )
2184         {
2185             [fDstCodecsPopUp selectItemAtIndex:0];
2186             [self codecsPopUpChanged: NULL];
2187             
2188             /* changing the format may mean that we can / can't offer mono or 6ch, */
2189             /* so call audioTrackPopUpChanged for both audio tracks to update the mixdown popups */
2190             [self audioTrackPopUpChanged: fAudLang1PopUp];
2191             [self audioTrackPopUpChanged: fAudLang2PopUp];
2192             /* We call the method to properly enable/disable turbo 2 pass */
2193             [self twoPassCheckboxChanged: sender];
2194             /* We call method method to change UI to reflect whether a preset is used or not*/
2195         }
2196     }
2197     
2198         [self customSettingUsed: sender];       
2199 }
2200
2201 - (IBAction) codecsPopUpChanged: (id) sender
2202 {
2203     int format = [fDstFormatPopUp indexOfSelectedItem];
2204     int codecs = [fDstCodecsPopUp indexOfSelectedItem];
2205         
2206     [fAdvancedOptions setHidden:YES];
2207
2208     /* Update the encoder popup*/
2209     if( ( FormatSettings[format][codecs] & HB_VCODEC_X264 ) )
2210     {
2211         /* MPEG-4 -> H.264 */
2212         [fVidEncoderPopUp removeAllItems];
2213                 [fVidEncoderPopUp addItemWithTitle: @"x264 (h.264 Main)"];
2214                 [fVidEncoderPopUp addItemWithTitle: @"x264 (h.264 iPod)"];
2215                 [fVidEncoderPopUp selectItemAtIndex: 0];
2216         [fAdvancedOptions setHidden:NO];
2217     }
2218     
2219     else if( ( FormatSettings[format][codecs] & HB_VCODEC_FFMPEG ) )
2220     {
2221         /* H.264 -> MPEG-4 */
2222         [fVidEncoderPopUp removeAllItems];
2223         [fVidEncoderPopUp addItemWithTitle: @"FFmpeg"];
2224         [fVidEncoderPopUp addItemWithTitle: @"XviD"];
2225         [fVidEncoderPopUp selectItemAtIndex: 0];
2226                                 
2227     }
2228
2229     if( FormatSettings[format][codecs] & HB_ACODEC_AC3 )
2230     {
2231         /* AC-3 pass-through: disable samplerate and bitrate */
2232         [fAudRatePopUp    setEnabled: NO];
2233         [fAudBitratePopUp setEnabled: NO];
2234     }
2235     else
2236     {
2237         [fAudRatePopUp    setEnabled: YES];
2238         [fAudBitratePopUp setEnabled: YES];
2239     }
2240     /* changing the codecs on offer may mean that we can / can't offer mono or 6ch, */
2241         /* so call audioTrackPopUpChanged for both audio tracks to update the mixdown popups */
2242         [self audioTrackPopUpChanged: fAudLang1PopUp];
2243         [self audioTrackPopUpChanged: fAudLang2PopUp];
2244
2245     [self calculateBitrate: sender];
2246     [self twoPassCheckboxChanged: sender];
2247 }
2248
2249 - (IBAction) encoderPopUpChanged: (id) sender
2250 {
2251     
2252         /* Check to see if we need to modify the job pic values based on x264 (iPod) encoder selection */
2253     if ([fDstFormatPopUp indexOfSelectedItem] == 0 && [fDstCodecsPopUp indexOfSelectedItem] == 1 && [fVidEncoderPopUp indexOfSelectedItem] == 1)
2254     {
2255                 hb_job_t * job = fTitle->job;
2256                 job->pixel_ratio = 0 ;
2257                 
2258                 if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultPicSizeAutoiPod"] > 0)
2259                 {
2260                         
2261                         if (job->width > 640)
2262                         {
2263                                 job->width = 640;
2264                         }
2265                         job->keep_ratio = 1;
2266                         hb_fix_aspect( job, HB_KEEP_WIDTH );
2267                         
2268                 }
2269                 /* Make sure the 64bit formatting checkbox is off */
2270                 [fDstMpgLargeFileCheck setState: NSOffState];
2271         }
2272     
2273         [self calculatePictureSizing: sender];
2274         [self twoPassCheckboxChanged: sender];
2275 }
2276
2277 - (IBAction) twoPassCheckboxChanged: (id) sender
2278 {
2279         /* check to see if x264 is chosen */
2280         int format = [fDstFormatPopUp indexOfSelectedItem];
2281     int codecs = [fDstCodecsPopUp indexOfSelectedItem];
2282         if( ( FormatSettings[format][codecs] & HB_VCODEC_X264 ) )
2283     {
2284                 if( [fVidTwoPassCheck state] == NSOnState)
2285                 {
2286                         [fVidTurboPassCheck setHidden: NO];
2287                 }
2288                 else
2289                 {
2290                         [fVidTurboPassCheck setHidden: YES];
2291                         [fVidTurboPassCheck setState: NSOffState];
2292                 }
2293                 /* Make sure Two Pass is checked if Turbo is checked */
2294                 if( [fVidTurboPassCheck state] == NSOnState)
2295                 {
2296                         [fVidTwoPassCheck setState: NSOnState];
2297                 }
2298         }
2299         else
2300         {
2301                 [fVidTurboPassCheck setHidden: YES];
2302                 [fVidTurboPassCheck setState: NSOffState];
2303         }
2304         
2305         /* We call method method to change UI to reflect whether a preset is used or not*/
2306         [self customSettingUsed: sender];
2307 }
2308
2309 - (IBAction ) videoFrameRateChanged: (id) sender
2310 {
2311     /* We call method method to calculatePictureSizing to error check detelecine*/
2312     [self calculatePictureSizing: sender];
2313
2314     /* We call method method to change UI to reflect whether a preset is used or not*/
2315         [self customSettingUsed: sender];
2316 }
2317
2318 - (IBAction) setEnabledStateOfAudioMixdownControls: (id) sender
2319 {
2320
2321     /* enable/disable the mixdown text and popupbutton for audio track 1 */
2322     [fAudTrack1MixPopUp setEnabled: ([fAudLang1PopUp indexOfSelectedItem] == 0) ? NO : YES];
2323     [fAudTrack1MixLabel setTextColor: ([fAudLang1PopUp indexOfSelectedItem] == 0) ?
2324         [NSColor disabledControlTextColor] : [NSColor controlTextColor]];
2325
2326     /* enable/disable the mixdown text and popupbutton for audio track 2 */
2327     [fAudTrack2MixPopUp setEnabled: ([fAudLang2PopUp indexOfSelectedItem] == 0) ? NO : YES];
2328     [fAudTrack2MixLabel setTextColor: ([fAudLang2PopUp indexOfSelectedItem] == 0) ?
2329         [NSColor disabledControlTextColor] : [NSColor controlTextColor]];
2330
2331 }
2332
2333 - (IBAction) addAllAudioTracksToPopUp: (id) sender
2334 {
2335
2336     hb_list_t  * list  = hb_get_titles( fHandle );
2337     hb_title_t * title = (hb_title_t*)
2338         hb_list_item( list, [fSrcTitlePopUp indexOfSelectedItem] );
2339
2340         hb_audio_t * audio;
2341
2342     [sender removeAllItems];
2343     [sender addItemWithTitle: _( @"None" )];
2344     for( int i = 0; i < hb_list_count( title->list_audio ); i++ )
2345     {
2346         audio = (hb_audio_t *) hb_list_item( title->list_audio, i );
2347         [[sender menu] addItemWithTitle:
2348             [NSString stringWithCString: audio->lang]
2349             action: NULL keyEquivalent: @""];
2350     }
2351     [sender selectItemAtIndex: 0];
2352
2353 }
2354
2355 - (IBAction) selectAudioTrackInPopUp: (id) sender searchPrefixString: (NSString *) searchPrefixString selectIndexIfNotFound: (int) selectIndexIfNotFound
2356 {
2357
2358     /* this method can be used to find a language, or a language-and-source-format combination, by passing in the appropriate string */
2359     /* e.g. to find the first French track, pass in an NSString * of "Francais" */
2360     /* e.g. to find the first English 5.1 AC3 track, pass in an NSString * of "English (AC3) (5.1 ch)" */
2361     /* if no matching track is found, then selectIndexIfNotFound is used to choose which track to select instead */
2362     
2363         if (searchPrefixString != NULL) 
2364         {
2365
2366         for( int i = 0; i < [sender numberOfItems]; i++ )
2367         {
2368             /* Try to find the desired search string */
2369             if ([[[sender itemAtIndex: i] title] hasPrefix:searchPrefixString])
2370             {
2371                 [sender selectItemAtIndex: i];
2372                 return;
2373             }
2374         }
2375         /* couldn't find the string, so select the requested "search string not found" item */
2376         /* index of 0 means select the "none" item */
2377         /* index of 1 means select the first audio track */
2378         [sender selectItemAtIndex: selectIndexIfNotFound];
2379         }
2380     else
2381     {
2382         /* if no search string is provided, then select the selectIndexIfNotFound item */
2383         [sender selectItemAtIndex: selectIndexIfNotFound];
2384     }
2385
2386 }
2387
2388 - (IBAction) audioTrackPopUpChanged: (id) sender
2389 {
2390     /* utility function to call audioTrackPopUpChanged without passing in a mixdown-to-use */
2391     [self audioTrackPopUpChanged: sender mixdownToUse: 0];
2392 }
2393
2394 - (IBAction) audioTrackPopUpChanged: (id) sender mixdownToUse: (int) mixdownToUse
2395 {
2396
2397     /* make sure we have a selected title before continuing */
2398     if (fTitle == NULL) return;
2399
2400     /* find out if audio track 1 or 2 was changed - this is passed to us in the tag of the sender */
2401     /* the sender will have been either fAudLang1PopUp (tag = 0) or fAudLang2PopUp (tag = 1) */
2402     int thisAudio = [sender tag];
2403
2404     /* get the index of the selected audio */
2405     int thisAudioIndex = [sender indexOfSelectedItem] - 1;
2406
2407     /* Handbrake can't currently cope with ripping the same source track twice */
2408     /* So, if this audio is also selected in the other audio track popup, set that popup's selection to "none" */
2409     /* get a reference to the two audio track popups */
2410     NSPopUpButton * thisAudioPopUp  = (thisAudio == 1 ? fAudLang2PopUp : fAudLang1PopUp);
2411     NSPopUpButton * otherAudioPopUp = (thisAudio == 1 ? fAudLang1PopUp : fAudLang2PopUp);
2412     /* if the same track is selected in the other audio popup, then select "none" in that popup */
2413     /* unless, of course, both are selected as "none!" */
2414     if ([thisAudioPopUp indexOfSelectedItem] != 0 && [thisAudioPopUp indexOfSelectedItem] == [otherAudioPopUp indexOfSelectedItem]) {
2415         [otherAudioPopUp selectItemAtIndex: 0];
2416         [self audioTrackPopUpChanged: otherAudioPopUp];
2417     }
2418
2419     /* pointer for the hb_audio_s struct we will use later on */
2420     hb_audio_t * audio;
2421
2422     /* find out what the currently-selected output audio codec is */
2423     int format = [fDstFormatPopUp indexOfSelectedItem];
2424     int codecs = [fDstCodecsPopUp indexOfSelectedItem];
2425     int acodec = FormatSettings[format][codecs] & HB_ACODEC_MASK;
2426
2427     /* pointer to this track's mixdown NSPopUpButton */
2428     NSTextField   * mixdownTextField;
2429     NSPopUpButton * mixdownPopUp;
2430
2431     /* find our mixdown NSTextField and NSPopUpButton */
2432     if (thisAudio == 0)
2433     {
2434         mixdownTextField = fAudTrack1MixLabel;
2435         mixdownPopUp = fAudTrack1MixPopUp;
2436     }
2437     else
2438     {
2439         mixdownTextField = fAudTrack2MixLabel;
2440         mixdownPopUp = fAudTrack2MixPopUp;
2441     }
2442
2443     /* delete the previous audio mixdown options */
2444     [mixdownPopUp removeAllItems];
2445
2446     /* check if the audio mixdown controls need their enabled state changing */
2447     [self setEnabledStateOfAudioMixdownControls: NULL];
2448
2449     if (thisAudioIndex != -1)
2450     {
2451
2452         /* get the audio */
2453         audio = (hb_audio_t *) hb_list_item( fTitle->list_audio, thisAudioIndex );
2454         if (audio != NULL)
2455         {
2456
2457             /* find out if our selected output audio codec supports mono and / or 6ch */
2458             /* we also check for an input codec of AC3 or DCA,
2459                as they are the only libraries able to do the mixdown to mono / conversion to 6-ch */
2460             /* audioCodecsSupportMono and audioCodecsSupport6Ch are the same for now,
2461                but this may change in the future, so they are separated for flexibility */
2462             int audioCodecsSupportMono = ((audio->codec == HB_ACODEC_AC3 ||
2463                 audio->codec == HB_ACODEC_DCA) && acodec == HB_ACODEC_FAAC);
2464             int audioCodecsSupport6Ch =  ((audio->codec == HB_ACODEC_AC3 ||
2465                 audio->codec == HB_ACODEC_DCA) && (acodec == HB_ACODEC_FAAC ||
2466                 acodec == HB_ACODEC_VORBIS));
2467
2468             /* check for AC-3 passthru */
2469             if (audio->codec == HB_ACODEC_AC3 && acodec == HB_ACODEC_AC3)
2470             {
2471                     [[mixdownPopUp menu] addItemWithTitle:
2472                         [NSString stringWithCString: "AC3 Passthru"]
2473                         action: NULL keyEquivalent: @""];
2474             }
2475             else
2476             {
2477
2478                 /* add the appropriate audio mixdown menuitems to the popupbutton */
2479                 /* in each case, we set the new menuitem's tag to be the amixdown value for that mixdown,
2480                    so that we can reference the mixdown later */
2481
2482                 /* keep a track of the min and max mixdowns we used, so we can select the best match later */
2483                 int minMixdownUsed = 0;
2484                 int maxMixdownUsed = 0;
2485                 
2486                 /* get the input channel layout without any lfe channels */
2487                 int layout = audio->input_channel_layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK;
2488
2489                 /* do we want to add a mono option? */
2490                 if (audioCodecsSupportMono == 1) {
2491                     id<NSMenuItem> menuItem = [[mixdownPopUp menu] addItemWithTitle:
2492                         [NSString stringWithCString: hb_audio_mixdowns[0].human_readable_name]
2493                         action: NULL keyEquivalent: @""];
2494                     [menuItem setTag: hb_audio_mixdowns[0].amixdown];
2495                     if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[0].amixdown;
2496                     maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[0].amixdown);
2497                 }
2498
2499                 /* do we want to add a stereo option? */
2500                 /* offer stereo if we have a mono source and non-mono-supporting codecs, as otherwise we won't have a mixdown at all */
2501                 /* also offer stereo if we have a stereo-or-better source */
2502                 if ((layout == HB_INPUT_CH_LAYOUT_MONO && audioCodecsSupportMono == 0) || layout >= HB_INPUT_CH_LAYOUT_STEREO) {
2503                     id<NSMenuItem> menuItem = [[mixdownPopUp menu] addItemWithTitle:
2504                         [NSString stringWithCString: hb_audio_mixdowns[1].human_readable_name]
2505                         action: NULL keyEquivalent: @""];
2506                     [menuItem setTag: hb_audio_mixdowns[1].amixdown];
2507                     if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[1].amixdown;
2508                     maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[1].amixdown);
2509                 }
2510
2511                 /* do we want to add a dolby surround (DPL1) option? */
2512                 if (layout == HB_INPUT_CH_LAYOUT_3F1R || layout == HB_INPUT_CH_LAYOUT_3F2R || layout == HB_INPUT_CH_LAYOUT_DOLBY) {
2513                     id<NSMenuItem> menuItem = [[mixdownPopUp menu] addItemWithTitle:
2514                         [NSString stringWithCString: hb_audio_mixdowns[2].human_readable_name]
2515                         action: NULL keyEquivalent: @""];
2516                     [menuItem setTag: hb_audio_mixdowns[2].amixdown];
2517                     if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[2].amixdown;
2518                     maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[2].amixdown);
2519                 }
2520
2521                 /* do we want to add a dolby pro logic 2 (DPL2) option? */
2522                 if (layout == HB_INPUT_CH_LAYOUT_3F2R) {
2523                     id<NSMenuItem> menuItem = [[mixdownPopUp menu] addItemWithTitle:
2524                         [NSString stringWithCString: hb_audio_mixdowns[3].human_readable_name]
2525                         action: NULL keyEquivalent: @""];
2526                     [menuItem setTag: hb_audio_mixdowns[3].amixdown];
2527                     if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[3].amixdown;
2528                     maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[3].amixdown);
2529                 }
2530
2531                 /* do we want to add a 6-channel discrete option? */
2532                 if (audioCodecsSupport6Ch == 1 && layout == HB_INPUT_CH_LAYOUT_3F2R && (audio->input_channel_layout & HB_INPUT_CH_LAYOUT_HAS_LFE)) {
2533                     id<NSMenuItem> menuItem = [[mixdownPopUp menu] addItemWithTitle:
2534                         [NSString stringWithCString: hb_audio_mixdowns[4].human_readable_name]
2535                         action: NULL keyEquivalent: @""];
2536                     [menuItem setTag: hb_audio_mixdowns[4].amixdown];
2537                     if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[4].amixdown;
2538                     maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[4].amixdown);
2539                 }
2540
2541                 /* auto-select the best mixdown based on our saved mixdown preference */
2542                 
2543                 /* for now, this is hard-coded to a "best" mixdown of HB_AMIXDOWN_DOLBYPLII */
2544                 /* ultimately this should be a prefs option */
2545                 int useMixdown;
2546                 
2547                 /* if we passed in a mixdown to use - in order to load a preset - then try and use it */
2548                 if (mixdownToUse > 0)
2549                 {
2550                     useMixdown = mixdownToUse;
2551                 }
2552                 else
2553                 {
2554                     useMixdown = HB_AMIXDOWN_DOLBYPLII;
2555                 }
2556                 
2557                 /* if useMixdown > maxMixdownUsed, then use maxMixdownUsed */
2558                 if (useMixdown > maxMixdownUsed) useMixdown = maxMixdownUsed;
2559
2560                 /* if useMixdown < minMixdownUsed, then use minMixdownUsed */
2561                 if (useMixdown < minMixdownUsed) useMixdown = minMixdownUsed;
2562
2563                 /* select the (possibly-amended) preferred mixdown */
2564                 [mixdownPopUp selectItemWithTag: useMixdown];
2565                                 
2566                                 /* lets call the audioTrackMixdownChanged method here to determine appropriate bitrates, etc. */
2567                 [self audioTrackMixdownChanged: NULL];
2568             }
2569
2570         }
2571         
2572     }
2573
2574         /* see if the new audio track choice will change the bitrate we need */
2575     [self calculateBitrate: sender];    
2576
2577 }
2578 - (IBAction) audioTrackMixdownChanged: (id) sender
2579 {
2580
2581     /* find out what the currently-selected output audio codec is */
2582     int format = [fDstFormatPopUp indexOfSelectedItem];
2583     int codecs = [fDstCodecsPopUp indexOfSelectedItem];
2584     int acodec = FormatSettings[format][codecs] & HB_ACODEC_MASK;
2585     
2586     /* storage variable for the min and max bitrate allowed for this codec */
2587     int minbitrate;
2588     int maxbitrate;
2589     
2590     switch( acodec )
2591     {
2592         case HB_ACODEC_FAAC:
2593             /* check if we have a 6ch discrete conversion in either audio track */
2594             if ([[fAudTrack1MixPopUp selectedItem] tag] == HB_AMIXDOWN_6CH || [[fAudTrack2MixPopUp selectedItem] tag] == HB_AMIXDOWN_6CH)
2595             {
2596                 /* FAAC is happy using our min bitrate of 32 kbps, even for 6ch */
2597                 minbitrate = 32;
2598                 /* If either mixdown popup includes 6-channel discrete, then allow up to 384 kbps */
2599                 maxbitrate = 384;
2600                 break;
2601             }
2602             else
2603             {
2604                 /* FAAC is happy using our min bitrate of 32 kbps for stereo or mono */
2605                 minbitrate = 32;
2606                 /* FAAC won't honour anything more than 160 for stereo, so let's not offer it */
2607                 /* note: haven't dealt with mono separately here, FAAC will just use the max it can */
2608                 maxbitrate = 160;
2609                 break;
2610             }
2611
2612         case HB_ACODEC_LAME:
2613             /* Lame is happy using our min bitrate of 32 kbps */
2614             minbitrate = 32;
2615             /* Lame won't encode if the bitrate is higher than 320 kbps */
2616             maxbitrate = 320;
2617             break;
2618
2619         case HB_ACODEC_VORBIS:
2620         if ([[fAudTrack1MixPopUp selectedItem] tag] == HB_AMIXDOWN_6CH || [[fAudTrack2MixPopUp selectedItem] tag] == HB_AMIXDOWN_6CH)
2621             {
2622                 /* Vorbis causes a crash if we use a bitrate below 192 kbps with 6 channel */
2623                 minbitrate = 192;
2624                 /* If either mixdown popup includes 6-channel discrete, then allow up to 384 kbps */
2625                 maxbitrate = 384;
2626                 break;
2627             }
2628             else
2629             {
2630             /* Vorbis causes a crash if we use a bitrate below 48 kbps */
2631             minbitrate = 48;
2632             /* Vorbis can cope with 384 kbps quite happily, even for stereo */
2633             maxbitrate = 384;
2634             break;
2635             }
2636
2637         default:
2638             /* AC3 passthru disables the bitrate dropdown anyway, so we might as well just use the min and max bitrate */
2639             minbitrate = 32;
2640             maxbitrate = 384;
2641         
2642     }
2643
2644     [fAudBitratePopUp removeAllItems];
2645
2646     for( int i = 0; i < hb_audio_bitrates_count; i++ )
2647     {
2648         if (hb_audio_bitrates[i].rate >= minbitrate && hb_audio_bitrates[i].rate <= maxbitrate)
2649         {
2650             /* add a new menuitem for this bitrate */
2651             id<NSMenuItem> menuItem = [[fAudBitratePopUp menu] addItemWithTitle:
2652                 [NSString stringWithCString: hb_audio_bitrates[i].string]
2653                 action: NULL keyEquivalent: @""];
2654             /* set its tag to be the actual bitrate as an integer, so we can retrieve it later */
2655             [menuItem setTag: hb_audio_bitrates[i].rate];
2656         }
2657     }
2658
2659     /* select the default bitrate (but use 384 for 6-ch AAC) */
2660     if ([[fAudTrack1MixPopUp selectedItem] tag] == HB_AMIXDOWN_6CH || [[fAudTrack2MixPopUp selectedItem] tag] == HB_AMIXDOWN_6CH)
2661     {
2662         [fAudBitratePopUp selectItemWithTag: 384];
2663     }
2664     else
2665     {
2666         [fAudBitratePopUp selectItemWithTag: hb_audio_bitrates[hb_audio_bitrates_default].rate];
2667     }
2668
2669 }
2670
2671 - (IBAction) subtitleSelectionChanged: (id) sender
2672 {
2673         if ([fSubPopUp indexOfSelectedItem] == 0)
2674         {
2675         [fSubForcedCheck setState: NSOffState];
2676         [fSubForcedCheck setEnabled: NO];       
2677         }
2678         else
2679         {
2680         [fSubForcedCheck setEnabled: YES];      
2681         }
2682         
2683 }
2684
2685 /* lets set the picture size back to the max from right after title scan
2686    Lets use an IBAction here as down the road we could always use a checkbox
2687    in the gui to easily take the user back to max. Remember, the compiler
2688    resolves IBActions down to -(void) during compile anyway */
2689 - (IBAction) revertPictureSizeToMax: (id) sender
2690 {
2691         hb_job_t * job = fTitle->job;
2692         /* We use the output picture width and height
2693         as calculated from libhb right after title is set
2694         in TitlePopUpChanged */
2695         job->width = PicOrigOutputWidth;
2696         job->height = PicOrigOutputHeight;
2697     [fPictureController setAutoCrop:YES];
2698         /* Here we use the auto crop values determined right after scan */
2699         job->crop[0] = AutoCropTop;
2700         job->crop[1] = AutoCropBottom;
2701         job->crop[2] = AutoCropLeft;
2702         job->crop[3] = AutoCropRight;
2703                                 
2704                                 
2705                                 [self calculatePictureSizing: sender];
2706                                 /* We call method method to change UI to reflect whether a preset is used or not*/    
2707                                 [self customSettingUsed: sender];
2708 }
2709
2710
2711 /* Get and Display Current Pic Settings in main window */
2712 - (IBAction) calculatePictureSizing: (id) sender
2713 {
2714         [fPicSettingWidth setStringValue: [NSString stringWithFormat:@"%d", fTitle->job->width]];
2715         [fPicSettingHeight setStringValue: [NSString stringWithFormat:@"%d", fTitle->job->height]];
2716                 
2717         if (fTitle->job->pixel_ratio == 1)
2718         {
2719         int titlewidth = fTitle->width-fTitle->job->crop[2]-fTitle->job->crop[3];
2720         int arpwidth = fTitle->job->pixel_aspect_width;
2721         int arpheight = fTitle->job->pixel_aspect_height;
2722         int displayparwidth = titlewidth * arpwidth / arpheight;
2723         int displayparheight = fTitle->height-fTitle->job->crop[0]-fTitle->job->crop[1];
2724         
2725         [fPicSettingWidth setStringValue: [NSString stringWithFormat:@"%d", titlewidth]];
2726         [fPicSettingHeight setStringValue: [NSString stringWithFormat:@"%d", displayparheight]];
2727         [fPicLabelPAROutputX setStringValue: @"x"];
2728         [fPicSettingPARWidth setStringValue: [NSString stringWithFormat:@"%d", displayparwidth]];
2729         [fPicSettingPARHeight setStringValue: [NSString stringWithFormat:@"%d", displayparheight]];
2730         
2731         fTitle->job->keep_ratio = 0;
2732         }
2733         else
2734         {
2735         [fPicLabelPAROutputX setStringValue: @""];
2736         [fPicSettingPARWidth setStringValue: @""];
2737         [fPicSettingPARHeight setStringValue:  @""];
2738         }
2739                                 
2740         /* Set ON/Off values for the deinterlace/keep aspect ratio according to boolean */      
2741         if (fTitle->job->keep_ratio > 0)
2742         {
2743                 [fPicSettingARkeep setStringValue: @"On"];
2744         }
2745         else
2746         {
2747                 [fPicSettingARkeep setStringValue: @"Off"];
2748         }       
2749     /* Detelecine */
2750     if ([fPictureController detelecine]) {
2751         [fPicSettingDetelecine setStringValue: @"Yes"];
2752     }
2753     else {
2754         [fPicSettingDetelecine setStringValue: @"No"];
2755     }
2756
2757         /* Deinterlace */
2758         if ([fPictureController deinterlace] == 0)
2759         {
2760                 [fPicSettingDeinterlace setStringValue: @"Off"];
2761         }
2762         else if ([fPictureController deinterlace] == 1)
2763         {
2764                 [fPicSettingDeinterlace setStringValue: @"Fast"];
2765         }
2766         else if ([fPictureController deinterlace] == 2)
2767         {
2768                 [fPicSettingDeinterlace setStringValue: @"Slow"];
2769         }
2770         else if ([fPictureController deinterlace] == 3)
2771         {
2772                 [fPicSettingDeinterlace setStringValue: @"Slower"];
2773         }
2774         else if ([fPictureController deinterlace] ==4)
2775         {
2776                 [fPicSettingDeinterlace setStringValue: @"Slowest"];
2777         }
2778         /* Denoise */
2779         if ([fPictureController denoise] == 0)
2780         {
2781                 [fPicSettingDenoise setStringValue: @"Off"];
2782         }
2783         else if ([fPictureController denoise] == 1)
2784         {
2785                 [fPicSettingDenoise setStringValue: @"Weak"];
2786         }
2787         else if ([fPictureController denoise] == 2)
2788         {
2789                 [fPicSettingDenoise setStringValue: @"Medium"];
2790         }
2791         else if ([fPictureController denoise] == 3)
2792         {
2793                 [fPicSettingDenoise setStringValue: @"Strong"];
2794         }
2795         
2796         if (fTitle->job->pixel_ratio > 0)
2797         {
2798                 [fPicSettingPAR setStringValue: @""];
2799         }
2800         else
2801         {
2802                 [fPicSettingPAR setStringValue: @"Off"];
2803         }
2804         /* Set the display field for crop as per boolean */
2805         if (![fPictureController autoCrop])
2806         {
2807             [fPicSettingAutoCrop setStringValue: @"Custom"];
2808         }
2809         else
2810         {
2811                 [fPicSettingAutoCrop setStringValue: @"Auto"];
2812         }       
2813         
2814         
2815         
2816         
2817         /* below will trigger the preset, if selected, to be
2818         changed to "Custom". Lets comment out for now until
2819         we figure out a way to determine if the picture values
2820         changed modify the preset values */     
2821         //[self customSettingUsed: sender];
2822 }
2823
2824 - (IBAction) calculateBitrate: (id) sender
2825 {
2826     if( !fHandle || [fVidQualityMatrix selectedRow] != 0 || !SuccessfulScan )
2827     {
2828         return;
2829     }
2830
2831     hb_list_t  * list  = hb_get_titles( fHandle );
2832     hb_title_t * title = (hb_title_t *) hb_list_item( list,
2833             [fSrcTitlePopUp indexOfSelectedItem] );
2834     hb_job_t * job = title->job;
2835
2836     [self PrepareJob];
2837
2838     [fVidBitrateField setIntValue: hb_calc_bitrate( job,
2839             [fVidTargetSizeField intValue] )];
2840 }
2841
2842 /* Method to determine if we should change the UI
2843 To reflect whether or not a Preset is being used or if
2844 the user is using "Custom" settings by determining the sender*/
2845 - (IBAction) customSettingUsed: (id) sender
2846 {
2847         if ([sender stringValue] != NULL)
2848         {
2849                 /* Deselect the currently selected Preset if there is one*/
2850                 [tableView deselectRow:[tableView selectedRow]];
2851                 [[fPresetsActionMenu itemAtIndex:0] setEnabled: NO];
2852                 /* Change UI to show "Custom" settings are being used */
2853                 [fPresetSelectedDisplay setStringValue: @"Custom"];
2854                 
2855                 curUserPresetChosenNum = nil;
2856         }
2857
2858 }
2859
2860    /* We use this method to recreate new, updated factory
2861    presets */
2862 - (IBAction)addFactoryPresets:(id)sender
2863 {
2864     /* First, we delete any existing built in presets */
2865     [self deleteFactoryPresets: sender];
2866     /* Then, we re-create new built in presets programmatically CreateIpodOnlyPreset*/
2867     [UserPresets addObject:[self createNormalPreset]];
2868     [UserPresets addObject:[self createClassicPreset]];
2869     [UserPresets addObject:[self createQuickTimePreset]];
2870         [UserPresets addObject:[self createIpodLowPreset]];
2871         [UserPresets addObject:[self createIpodHighPreset]];
2872         [UserPresets addObject:[self createAppleTVPreset]];
2873     [UserPresets addObject:[self createiPhonePreset]];
2874         [UserPresets addObject:[self createPSThreePreset]];
2875         [UserPresets addObject:[self createPSPPreset]];
2876         [UserPresets addObject:[self createFilmPreset]];
2877     [UserPresets addObject:[self createTelevisionPreset]];
2878     [UserPresets addObject:[self createAnimationPreset]];
2879     [UserPresets addObject:[self createBedlamPreset]];
2880     [UserPresets addObject:[self createDeuxSixQuatrePreset]];
2881     [UserPresets addObject:[self createBrokePreset]];
2882     [UserPresets addObject:[self createBlindPreset]];
2883     [UserPresets addObject:[self createCRFPreset]];
2884     
2885     [self addPreset];
2886 }
2887 - (IBAction)deleteFactoryPresets:(id)sender
2888 {
2889     //int status;
2890     NSEnumerator *enumerator = [UserPresets objectEnumerator];
2891         id tempObject;
2892     
2893         //NSNumber *index;
2894     NSMutableArray *tempArray;
2895
2896
2897         tempArray = [NSMutableArray array];
2898         /* we look here to see if the preset is we move on to the next one */
2899         while ( tempObject = [enumerator nextObject] )  
2900                 {
2901                         /* if the preset is "Factory" then we put it in the array of
2902                         presets to delete */
2903                         if ([[tempObject objectForKey:@"Type"] intValue] == 0)
2904                         {
2905                                 [tempArray addObject:tempObject];
2906                         }
2907         }
2908         
2909         [UserPresets removeObjectsInArray:tempArray];
2910         [tableView reloadData];
2911         [self savePreset];   
2912
2913 }
2914
2915 - (IBAction) showAddPresetPanel: (id) sender
2916 {
2917     /* Deselect the currently selected Preset if there is one*/
2918     [tableView deselectRow:[tableView selectedRow]];
2919
2920     /* Populate the preset picture settings popup here */
2921     [fPresetNewPicSettingsPopUp removeAllItems];
2922     [fPresetNewPicSettingsPopUp addItemWithTitle:@"None"];
2923     [fPresetNewPicSettingsPopUp addItemWithTitle:@"Current"];
2924     [fPresetNewPicSettingsPopUp addItemWithTitle:@"Source Maximum (post source scan)"];
2925     [fPresetNewPicSettingsPopUp selectItemAtIndex: 0];  
2926         
2927     /* Erase info from the input fields fPresetNewDesc*/
2928         [fPresetNewName setStringValue: @""];
2929         [fPresetNewDesc setStringValue: @""];
2930         /* Show the panel */
2931         [NSApp beginSheet: fAddPresetPanel modalForWindow: fWindow modalDelegate: NULL didEndSelector: NULL contextInfo: NULL];
2932 }
2933
2934 - (IBAction) closeAddPresetPanel: (id) sender
2935 {
2936     [NSApp endSheet: fAddPresetPanel];
2937     [fAddPresetPanel orderOut: self];
2938 }
2939
2940 - (IBAction)addUserPreset:(id)sender
2941 {
2942     if (![[fPresetNewName stringValue] length])
2943             NSRunAlertPanel(@"Warning!", @"You need to insert a name for the preset.", @"OK", nil , nil);
2944     else
2945     {
2946         /* Here we create a custom user preset */
2947         [UserPresets addObject:[self createPreset]];
2948         [self addPreset];
2949         
2950         [self closeAddPresetPanel:NULL];
2951     }
2952 }
2953 - (void)addPreset
2954 {
2955
2956         
2957         /* We Sort the Presets By Factory or Custom */
2958         NSSortDescriptor * presetTypeDescriptor=[[[NSSortDescriptor alloc] initWithKey:@"Type" 
2959                                                     ascending:YES] autorelease];
2960         /* We Sort the Presets Alphabetically by name */
2961         NSSortDescriptor * presetNameDescriptor=[[[NSSortDescriptor alloc] initWithKey:@"PresetName" 
2962                                                     ascending:YES selector:@selector(caseInsensitiveCompare:)] autorelease];
2963         NSArray *sortDescriptors=[NSArray arrayWithObjects:presetTypeDescriptor,presetNameDescriptor,nil];
2964         NSArray *sortedArray=[UserPresets sortedArrayUsingDescriptors:sortDescriptors];
2965         [UserPresets setArray:sortedArray];
2966         
2967         
2968         /* We Reload the New Table data for presets */
2969     [tableView reloadData];
2970    /* We save all of the preset data here */
2971     [self savePreset];
2972 }
2973
2974 - (IBAction)insertPreset:(id)sender
2975 {
2976     int index = [tableView selectedRow];
2977     [UserPresets insertObject:[self createPreset] atIndex:index];
2978     [tableView reloadData];
2979     [self savePreset];
2980 }
2981
2982 - (NSDictionary *)createPreset
2983 {
2984     NSMutableDictionary *preset = [[NSMutableDictionary alloc] init];
2985         /* Get the New Preset Name from the field in the AddPresetPanel */
2986     [preset setObject:[fPresetNewName stringValue] forKey:@"PresetName"];
2987         /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/
2988         [preset setObject:[NSNumber numberWithInt:1] forKey:@"Type"];
2989         /*Set whether or not this is default, at creation set to 0*/
2990         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Default"];
2991         /*Get the whether or not to apply pic settings in the AddPresetPanel*/
2992         [preset setObject:[NSNumber numberWithInt:[fPresetNewPicSettingsPopUp indexOfSelectedItem]] forKey:@"UsesPictureSettings"];
2993         /* Get New Preset Description from the field in the AddPresetPanel*/
2994         [preset setObject:[fPresetNewDesc stringValue] forKey:@"PresetDescription"];
2995         /* File Format */
2996     [preset setObject:[fDstFormatPopUp titleOfSelectedItem] forKey:@"FileFormat"];
2997         /* Chapter Markers fCreateChapterMarkers*/
2998         [preset setObject:[NSNumber numberWithInt:[fCreateChapterMarkers state]] forKey:@"ChapterMarkers"];
2999         /* Allow Mpeg4 64 bit formatting +4GB file sizes */
3000         [preset setObject:[NSNumber numberWithInt:[fDstMpgLargeFileCheck state]] forKey:@"Mp4LargeFile"];
3001         /* Codecs */
3002         [preset setObject:[fDstCodecsPopUp titleOfSelectedItem] forKey:@"FileCodecs"];
3003         /* Video encoder */
3004         [preset setObject:[fVidEncoderPopUp titleOfSelectedItem] forKey:@"VideoEncoder"];
3005         /* x264 Option String */
3006         [preset setObject:[fAdvancedOptions optionsString] forKey:@"x264Option"];
3007         
3008         [preset setObject:[NSNumber numberWithInt:[fVidQualityMatrix selectedRow]] forKey:@"VideoQualityType"];
3009         [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
3010         [preset setObject:[fVidBitrateField stringValue] forKey:@"VideoAvgBitrate"];
3011         [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
3012         
3013         /* Video framerate */
3014     if ([fVidRatePopUp indexOfSelectedItem] == 0) // Same as source is selected
3015         {
3016     [preset setObject:[NSString stringWithFormat: @"Same as source"] forKey:@"VideoFramerate"];
3017     }
3018     else // we can record the actual titleOfSelectedItem
3019     {
3020     [preset setObject:[fVidRatePopUp titleOfSelectedItem] forKey:@"VideoFramerate"];
3021     }
3022         /* GrayScale */
3023         [preset setObject:[NSNumber numberWithInt:[fVidGrayscaleCheck state]] forKey:@"VideoGrayScale"];
3024         /* 2 Pass Encoding */
3025         [preset setObject:[NSNumber numberWithInt:[fVidTwoPassCheck state]] forKey:@"VideoTwoPass"];
3026         /* Turbo 2 pass Encoding fVidTurboPassCheck*/
3027         [preset setObject:[NSNumber numberWithInt:[fVidTurboPassCheck state]] forKey:@"VideoTurboTwoPass"];
3028         /*Picture Settings*/
3029         hb_job_t * job = fTitle->job;
3030         /* Basic Picture Settings */
3031         /* Use Max Picture settings for whatever the dvd is.*/
3032         [preset setObject:[NSNumber numberWithInt:0] forKey:@"UsesMaxPictureSettings"];
3033         [preset setObject:[NSNumber numberWithInt:fTitle->job->width] forKey:@"PictureWidth"];
3034         [preset setObject:[NSNumber numberWithInt:fTitle->job->height] forKey:@"PictureHeight"];
3035         [preset setObject:[NSNumber numberWithInt:fTitle->job->keep_ratio] forKey:@"PictureKeepRatio"];
3036         [preset setObject:[NSNumber numberWithInt:[fPictureController deinterlace]] forKey:@"PictureDeinterlace"];
3037         [preset setObject:[NSNumber numberWithInt:fTitle->job->pixel_ratio] forKey:@"PicturePAR"];
3038         [preset setObject:[NSNumber numberWithInt:[fPictureController detelecine]] forKey:@"PictureDetelecine"];
3039         [preset setObject:[NSNumber numberWithInt:[fPictureController denoise]] forKey:@"PictureDenoise"]; 
3040         /* Set crop settings here */
3041         /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */
3042         [preset setObject:[NSNumber numberWithInt:[fPictureController autoCrop]] forKey:@"PictureAutoCrop"];
3043
3044         [preset setObject:[NSNumber numberWithInt:job->crop[0]] forKey:@"PictureTopCrop"];
3045     [preset setObject:[NSNumber numberWithInt:job->crop[1]] forKey:@"PictureBottomCrop"];
3046         [preset setObject:[NSNumber numberWithInt:job->crop[2]] forKey:@"PictureLeftCrop"];
3047         [preset setObject:[NSNumber numberWithInt:job->crop[3]] forKey:@"PictureRightCrop"];
3048         
3049         /*Audio*/
3050         /* Audio Sample Rate*/
3051         [preset setObject:[fAudRatePopUp titleOfSelectedItem] forKey:@"AudioSampleRate"];
3052         /* Audio Bitrate Rate*/
3053         [preset setObject:[fAudBitratePopUp titleOfSelectedItem] forKey:@"AudioBitRate"];
3054         /* Subtitles*/
3055         [preset setObject:[fSubPopUp titleOfSelectedItem] forKey:@"Subtitles"];
3056         
3057
3058     [preset autorelease];
3059     return preset;
3060
3061 }
3062
3063 - (NSDictionary *)createIpodLowPreset
3064 {
3065     NSMutableDictionary *preset = [[NSMutableDictionary alloc] init];
3066         /* Get the New Preset Name from the field in the AddPresetPanel */
3067     [preset setObject:@"iPod Low-Rez" forKey:@"PresetName"];
3068         /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/
3069         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"];
3070         /*Set whether or not this is default, at creation set to 0*/
3071         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Default"];
3072         /*Get the whether or not to apply pic settings in the AddPresetPanel*/
3073         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesPictureSettings"];
3074         /* Get the New Preset Description from the field in the AddPresetPanel */
3075     [preset setObject:@"HandBrake's low resolution settings for the iPod. Optimized for great playback on the iPod screen, with smaller file size." forKey:@"PresetDescription"];
3076         /* File Format */
3077     [preset setObject:@"MP4 file" forKey:@"FileFormat"];
3078         /* Chapter Markers*/
3079          [preset setObject:[NSNumber numberWithInt:1] forKey:@"ChapterMarkers"];
3080     /* Codecs */
3081         [preset setObject:@"AVC/H.264 Video / AAC Audio" forKey:@"FileCodecs"];
3082         /* Video encoder */
3083         [preset setObject:@"x264 (h.264 iPod)" forKey:@"VideoEncoder"];
3084         /* x264 Option String */
3085         [preset setObject:@"keyint=300:keyint-min=30:bframes=0:cabac=0:ref=1:vbv-maxrate=768:vbv-bufsize=2000:analyse=all:me=umh:subme=6:no-fast-pskip=1" forKey:@"x264Option"];
3086         /* Video quality */
3087         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"];
3088         [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
3089         [preset setObject:@"700" forKey:@"VideoAvgBitrate"];
3090         [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
3091         
3092         /* Video framerate */
3093         [preset setObject:@"Same as source" forKey:@"VideoFramerate"];
3094         /* GrayScale */
3095         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"];
3096         /* 2 Pass Encoding */
3097         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoTwoPass"];
3098         
3099         /*Picture Settings*/
3100         //hb_job_t * job = fTitle->job;
3101         /* Basic Picture Settings */
3102         /* Use Max Picture settings for whatever the dvd is.*/
3103         [preset setObject:[NSNumber numberWithInt:0] forKey:@"UsesMaxPictureSettings"];
3104         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureAutoCrop"];
3105         [preset setObject:[NSNumber numberWithInt:320] forKey:@"PictureWidth"];
3106         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureHeight"];
3107         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureKeepRatio"];
3108         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureDeinterlace"];
3109         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PicturePAR"];
3110         /* Set crop settings here */
3111         /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */
3112         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureTopCrop"];
3113     [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureBottomCrop"];
3114         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureLeftCrop"];
3115         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureRightCrop"];
3116         
3117         /*Audio*/
3118         /* Audio Sample Rate*/
3119         [preset setObject:@"48" forKey:@"AudioSampleRate"];
3120         /* Audio Bitrate Rate*/
3121         [preset setObject:@"160" forKey:@"AudioBitRate"];
3122         /* Subtitles*/
3123         [preset setObject:@"None" forKey:@"Subtitles"];
3124         
3125
3126     [preset autorelease];
3127     return preset;
3128
3129 }
3130
3131
3132 - (NSDictionary *)createIpodHighPreset
3133 {
3134     NSMutableDictionary *preset = [[NSMutableDictionary alloc] init];
3135         /* Get the New Preset Name from the field in the AddPresetPanel */
3136     [preset setObject:@"iPod High-Rez" forKey:@"PresetName"];
3137         /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/
3138         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"];
3139         /*Set whether or not this is default, at creation set to 0*/
3140         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Default"];
3141         /*Get the whether or not to apply pic settings in the AddPresetPanel*/
3142         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesPictureSettings"];
3143         /* Get the New Preset Description from the field in the AddPresetPanel */
3144     [preset setObject:@"HandBrake's high resolution settings for the iPod. Good video quality, great for viewing on a TV using your iPod" forKey:@"PresetDescription"];
3145         /* File Format */
3146     [preset setObject:@"MP4 file" forKey:@"FileFormat"];
3147         /* Chapter Markers*/
3148          [preset setObject:[NSNumber numberWithInt:1] forKey:@"ChapterMarkers"];
3149     /* Codecs */
3150         [preset setObject:@"AVC/H.264 Video / AAC Audio" forKey:@"FileCodecs"];
3151         /* Video encoder */
3152         [preset setObject:@"x264 (h.264 iPod)" forKey:@"VideoEncoder"];
3153         /* x264 Option String */
3154         [preset setObject:@"keyint=300:keyint-min=30:bframes=0:cabac=0:ref=1:vbv-maxrate=1500:vbv-bufsize=2000:analyse=all:me=umh:subme=6:no-fast-pskip=1" forKey:@"x264Option"];
3155         /* Video quality */
3156         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"];
3157         [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
3158         [preset setObject:@"1500" forKey:@"VideoAvgBitrate"];
3159         [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
3160         
3161         /* Video framerate */
3162         [preset setObject:@"Same as source" forKey:@"VideoFramerate"];
3163         /* GrayScale */
3164         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"];
3165         /* 2 Pass Encoding */
3166         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoTwoPass"];
3167         
3168         /*Picture Settings*/
3169         //hb_job_t * job = fTitle->job;
3170         /* Basic Picture Settings */
3171         /* Use Max Picture settings for whatever the dvd is.*/
3172         [preset setObject:[NSNumber numberWithInt:0] forKey:@"UsesMaxPictureSettings"];
3173         [preset setObject:[NSNumber numberWithInt:640] forKey:@"PictureWidth"];
3174         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureHeight"];
3175         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureKeepRatio"];
3176         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureDeinterlace"];
3177         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PicturePAR"];
3178         /* Set crop settings here */
3179         /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */
3180         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureAutoCrop"];
3181         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureTopCrop"];
3182     [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureBottomCrop"];
3183         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureLeftCrop"];
3184         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureRightCrop"];
3185         
3186         /*Audio*/
3187         /* Audio Sample Rate*/
3188         [preset setObject:@"48" forKey:@"AudioSampleRate"];
3189         /* Audio Bitrate Rate*/
3190         [preset setObject:@"160" forKey:@"AudioBitRate"];
3191         /* Subtitles*/
3192         [preset setObject:@"None" forKey:@"Subtitles"];
3193         
3194
3195     [preset autorelease];
3196     return preset;
3197
3198 }
3199
3200 - (NSDictionary *)createAppleTVPreset
3201 {
3202     NSMutableDictionary *preset = [[NSMutableDictionary alloc] init];
3203         /* Get the New Preset Name from the field in the AddPresetPanel */
3204     [preset setObject:@"AppleTV" forKey:@"PresetName"];
3205         /*Set whether or not this is a user preset where 0 is factory, 1 is user*/
3206         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"];
3207         /*Set whether or not this is default, at creation set to 0*/
3208         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Default"];
3209         /*Get the whether or not to apply pic settings in the AddPresetPanel*/
3210         [preset setObject:[NSNumber numberWithInt:2] forKey:@"UsesPictureSettings"];
3211         /* Get the New Preset Description from the field in the AddPresetPanel */
3212     [preset setObject:@"HandBrake's settings for the AppleTV. Provides a good balance between quality and file size, and optimizes performance." forKey:@"PresetDescription"];
3213         /* File Format */
3214     [preset setObject:@"MP4 file" forKey:@"FileFormat"];
3215         /* Chapter Markers*/
3216          [preset setObject:[NSNumber numberWithInt:1] forKey:@"ChapterMarkers"];
3217         /* Codecs */
3218         [preset setObject:@"AVC/H.264 Video / AAC Audio" forKey:@"FileCodecs"];
3219         /* Video encoder */
3220         [preset setObject:@"x264 (h.264 Main)" forKey:@"VideoEncoder"];
3221         /* x264 Option String (We can use this to tweak the appleTV output)*/
3222         [preset setObject:@"bframes=3:ref=1:subme=5:me=umh:no-fast-pskip=1:trellis=2:cabac=0" forKey:@"x264Option"];
3223         /* Video quality */
3224         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"];
3225         [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
3226         [preset setObject:@"2500" forKey:@"VideoAvgBitrate"];
3227         [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
3228         
3229         /* Video framerate */
3230         [preset setObject:@"Same as source" forKey:@"VideoFramerate"];
3231         /* GrayScale */
3232         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"];
3233         /* 2 Pass Encoding */
3234         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoTwoPass"];
3235         
3236         /*Picture Settings*/
3237         /* For AppleTV we only want to retain UsesMaxPictureSettings
3238         which depend on the source dvd picture settings, so we don't
3239         record the current dvd's picture info since it will vary from
3240         source to source*/
3241         //hb_job_t * job = fTitle->job;
3242         //hb_job_t * job = title->job;
3243         /* Basic Picture Settings */
3244         /* Use Max Picture settings for whatever the dvd is.*/
3245         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesMaxPictureSettings"];
3246         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureWidth"];
3247         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureHeight"];
3248         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureKeepRatio"];
3249         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureDeinterlace"];
3250         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PicturePAR"];
3251         /* Set crop settings here */
3252         /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */
3253         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureTopCrop"];
3254     [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureBottomCrop"];
3255         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureLeftCrop"];
3256         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureRightCrop"];
3257         
3258         /*Audio*/
3259         /* Audio Sample Rate*/
3260         [preset setObject:@"48" forKey:@"AudioSampleRate"];
3261         /* Audio Bitrate Rate*/
3262         [preset setObject:@"160" forKey:@"AudioBitRate"];
3263         /* Subtitles*/
3264         [preset setObject:@"None" forKey:@"Subtitles"];
3265         
3266
3267     [preset autorelease];
3268     return preset;
3269
3270 }
3271
3272 - (NSDictionary *)createPSThreePreset
3273 {
3274     NSMutableDictionary *preset = [[NSMutableDictionary alloc] init];
3275         /* Get the New Preset Name from the field in the AddPresetPanel */
3276     [preset setObject:@"PS3" forKey:@"PresetName"];
3277         /*Set whether or not this is a user preset where 0 is factory, 1 is user*/
3278         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"];
3279         /*Set whether or not this is default, at creation set to 0*/
3280         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Default"];
3281         /*Get the whether or not to apply pic settings in the AddPresetPanel*/
3282         [preset setObject:[NSNumber numberWithInt:2] forKey:@"UsesPictureSettings"];
3283         /* Get the New Preset Description from the field in the AddPresetPanel */
3284     [preset setObject:@"HandBrake's settings for the Sony PlayStation 3." forKey:@"PresetDescription"];
3285         /* File Format */
3286     [preset setObject:@"MP4 file" forKey:@"FileFormat"];
3287         /* Chapter Markers*/
3288          [preset setObject:[NSNumber numberWithInt:1] forKey:@"ChapterMarkers"];
3289         /* Codecs */
3290         [preset setObject:@"AVC/H.264 Video / AAC Audio" forKey:@"FileCodecs"];
3291         /* Video encoder */
3292         [preset setObject:@"x264 (h.264 Main)" forKey:@"VideoEncoder"];
3293         /* x264 Option String (We can use this to tweak the appleTV output)*/
3294         [preset setObject:@"level=41:subme=5:me=umh" forKey:@"x264Option"];
3295         /* Video quality */
3296         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"];
3297         [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
3298         [preset setObject:@"2500" forKey:@"VideoAvgBitrate"];
3299         [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
3300         
3301         /* Video framerate */
3302         [preset setObject:@"Same as source" forKey:@"VideoFramerate"];
3303         /* GrayScale */
3304         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"];
3305         /* 2 Pass Encoding */
3306         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoTwoPass"];
3307         
3308         /*Picture Settings*/
3309         /* For PS3 we only want to retain UsesMaxPictureSettings
3310         which depend on the source dvd picture settings, so we don't
3311         record the current dvd's picture info since it will vary from
3312         source to source*/
3313         /* Use Max Picture settings for whatever the dvd is.*/
3314         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesMaxPictureSettings"];
3315         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureWidth"];
3316         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureHeight"];
3317         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureKeepRatio"];
3318         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureDeinterlace"];
3319         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PicturePAR"];
3320         /* Set crop settings here */
3321         /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */
3322         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureTopCrop"];
3323     [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureBottomCrop"];
3324         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureLeftCrop"];
3325         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureRightCrop"];
3326         
3327         /*Audio*/
3328         /* Audio Sample Rate*/
3329         [preset setObject:@"48" forKey:@"AudioSampleRate"];
3330         /* Audio Bitrate Rate*/
3331         [preset setObject:@"160" forKey:@"AudioBitRate"];
3332         /* Subtitles*/
3333         [preset setObject:@"None" forKey:@"Subtitles"];
3334         
3335
3336     [preset autorelease];
3337     return preset;
3338
3339 }
3340 - (NSDictionary *)createPSPPreset
3341 {
3342     NSMutableDictionary *preset = [[NSMutableDictionary alloc] init];
3343         /* Get the New Preset Name from the field in the AddPresetPanel */
3344     [preset setObject:@"PSP" forKey:@"PresetName"];
3345         /*Set whether or not this is a user preset where 0 is factory, 1 is user*/
3346         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"];
3347         /*Set whether or not this is default, at creation set to 0*/
3348         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Default"];
3349         /*Get the whether or not to apply pic settings in the AddPresetPanel*/
3350         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesPictureSettings"];
3351         /* Get the New Preset Description from the field in the AddPresetPanel */
3352     [preset setObject:@"HandBrake's settings for the Sony PlayStation Portable." forKey:@"PresetDescription"];
3353         /* File Format */
3354     [preset setObject:@"MP4 file" forKey:@"FileFormat"];
3355         /* Chapter Markers*/
3356          [preset setObject:[NSNumber numberWithInt:1] forKey:@"ChapterMarkers"];
3357         /* Codecs */
3358         [preset setObject:@"MPEG-4 Video / AAC Audio" forKey:@"FileCodecs"];
3359         /* Video encoder */
3360         [preset setObject:@"FFmpeg" forKey:@"VideoEncoder"];
3361         /* x264 Option String (We can use this to tweak the appleTV output)*/
3362         [preset setObject:@"" forKey:@"x264Option"];
3363         /* Video quality */
3364         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"];
3365         [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
3366         [preset setObject:@"1024" forKey:@"VideoAvgBitrate"];
3367         [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
3368         
3369         /* Video framerate */
3370         [preset setObject:@"Same as source" forKey:@"VideoFramerate"];
3371         /* GrayScale */
3372         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"];
3373         /* 2 Pass Encoding */
3374         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoTwoPass"];
3375         
3376         /*Picture Settings*/
3377         /* For PS3 we only want to retain UsesMaxPictureSettings
3378         which depend on the source dvd picture settings, so we don't
3379         record the current dvd's picture info since it will vary from
3380         source to source*/
3381         /* Use Max Picture settings for whatever the dvd is.*/
3382         [preset setObject:[NSNumber numberWithInt:0] forKey:@"UsesMaxPictureSettings"];
3383         [preset setObject:@"368" forKey:@"PictureWidth"];
3384         [preset setObject:@"208" forKey:@"PictureHeight"];
3385         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureKeepRatio"];
3386         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureDeinterlace"];
3387         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PicturePAR"];
3388         /* Set crop settings here */
3389         /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */
3390         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureAutoCrop"];
3391         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureTopCrop"];
3392     [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureBottomCrop"];
3393         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureLeftCrop"];
3394         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureRightCrop"];
3395         
3396         /*Audio*/
3397         /* Audio Sample Rate*/
3398         [preset setObject:@"48" forKey:@"AudioSampleRate"];
3399         /* Audio Bitrate Rate*/
3400         [preset setObject:@"128" forKey:@"AudioBitRate"];
3401         /* Subtitles*/
3402         [preset setObject:@"None" forKey:@"Subtitles"];
3403         
3404
3405     [preset autorelease];
3406     return preset;
3407
3408 }
3409
3410 - (NSDictionary *)createNormalPreset
3411 {
3412     NSMutableDictionary *preset = [[NSMutableDictionary alloc] init];
3413         /* Get the New Preset Name from the field in the AddPresetPanel */
3414     [preset setObject:@"Normal" forKey:@"PresetName"];
3415         /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/
3416         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"];
3417         /*Set whether or not this is default, at creation set to 0*/
3418         [preset setObject:[NSNumber numberWithInt:1] forKey:@"Default"];
3419         /*Get the whether or not to apply pic settings in the AddPresetPanel*/
3420         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesPictureSettings"];
3421         /* Get the New Preset Description from the field in the AddPresetPanel */
3422     [preset setObject:@"HandBrake's normal, default settings." forKey:@"PresetDescription"];
3423         /* File Format */
3424     [preset setObject:@"MP4 file" forKey:@"FileFormat"];
3425         /* Chapter Markers*/
3426          [preset setObject:[NSNumber numberWithInt:1] forKey:@"ChapterMarkers"];
3427     /* Codecs */
3428         [preset setObject:@"AVC/H.264 Video / AAC Audio" forKey:@"FileCodecs"];
3429         /* Video encoder */
3430         [preset setObject:@"x264 (h.264 Main)" forKey:@"VideoEncoder"];
3431         /* x264 Option String */
3432         [preset setObject:@"ref=2:bframes=2:subme=5:me=umh" forKey:@"x264Option"];
3433         /* Video quality */
3434         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"];
3435         [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
3436         [preset setObject:@"1500" forKey:@"VideoAvgBitrate"];
3437         [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
3438         
3439         /* Video framerate */
3440         [preset setObject:@"Same as source" forKey:@"VideoFramerate"];
3441         /* GrayScale */
3442         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"];
3443         /* 2 Pass Encoding */
3444         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTwoPass"];
3445         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTurboTwoPass"];
3446         
3447         /*Picture Settings*/
3448         //hb_job_t * job = fTitle->job;
3449         /* Basic Picture Settings */
3450         /* Use Max Picture settings for whatever the dvd is.*/
3451         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesMaxPictureSettings"];
3452         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureAutoCrop"];
3453         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureWidth"];
3454         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureHeight"];
3455         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureKeepRatio"];
3456         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureDeinterlace"];
3457         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PicturePAR"];
3458         /* Set crop settings here */
3459         /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */
3460         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureTopCrop"];
3461     [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureBottomCrop"];
3462         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureLeftCrop"];
3463         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureRightCrop"];
3464         
3465         /*Audio*/
3466         /* Audio Sample Rate*/
3467         [preset setObject:@"48" forKey:@"AudioSampleRate"];
3468         /* Audio Bitrate Rate*/
3469         [preset setObject:@"160" forKey:@"AudioBitRate"];
3470         /* Subtitles*/
3471         [preset setObject:@"None" forKey:@"Subtitles"];
3472         
3473
3474     [preset autorelease];
3475     return preset;
3476
3477 }
3478
3479 - (NSDictionary *)createClassicPreset
3480 {
3481     NSMutableDictionary *preset = [[NSMutableDictionary alloc] init];
3482         /* Get the New Preset Name from the field in the AddPresetPanel */
3483     [preset setObject:@"Classic" forKey:@"PresetName"];
3484         /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/
3485         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"];
3486         /*Set whether or not this is default, at creation set to 0*/
3487         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Default"];
3488         /*Get the whether or not to apply pic settings in the AddPresetPanel*/
3489         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesPictureSettings"];
3490         /* Get the New Preset Description from the field in the AddPresetPanel */
3491     [preset setObject:@"HandBrake's traditional, faster, lower-quality settings." forKey:@"PresetDescription"];
3492         /* File Format */
3493     [preset setObject:@"MP4 file" forKey:@"FileFormat"];
3494         /* Chapter Markers*/
3495          [preset setObject:[NSNumber numberWithInt:0] forKey:@"ChapterMarkers"];
3496     /* Codecs */
3497         [preset setObject:@"MPEG-4 Video / AAC Audio" forKey:@"FileCodecs"];
3498         /* Video encoder */
3499         [preset setObject:@"FFmpeg" forKey:@"VideoEncoder"];
3500         /* x264 Option String */
3501         [preset setObject:@"" forKey:@"x264Option"];
3502         /* Video quality */
3503         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"];
3504         [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
3505         [preset setObject:@"1000" forKey:@"VideoAvgBitrate"];
3506         [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
3507         
3508         /* Video framerate */
3509         [preset setObject:@"Same as source" forKey:@"VideoFramerate"];
3510         /* GrayScale */
3511         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"];
3512         /* 2 Pass Encoding */
3513         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoTwoPass"];
3514         
3515         /*Picture Settings*/
3516         //hb_job_t * job = fTitle->job;
3517         /* Basic Picture Settings */
3518         /* Use Max Picture settings for whatever the dvd is.*/
3519         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesMaxPictureSettings"];
3520         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureAutoCrop"];
3521         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureWidth"];
3522         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureHeight"];
3523         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureKeepRatio"];
3524         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureDeinterlace"];
3525         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PicturePAR"];
3526         /* Set crop settings here */
3527         /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */
3528         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureTopCrop"];
3529     [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureBottomCrop"];
3530         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureLeftCrop"];
3531         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureRightCrop"];
3532         
3533         /*Audio*/
3534         /* Audio Sample Rate*/
3535         [preset setObject:@"48" forKey:@"AudioSampleRate"];
3536         /* Audio Bitrate Rate*/
3537         [preset setObject:@"160" forKey:@"AudioBitRate"];
3538         /* Subtitles*/
3539         [preset setObject:@"None" forKey:@"Subtitles"];
3540         
3541
3542     [preset autorelease];
3543     return preset;
3544
3545 }
3546
3547 - (NSDictionary *)createFilmPreset
3548 {
3549     NSMutableDictionary *preset = [[NSMutableDictionary alloc] init];
3550         /* Get the New Preset Name from the field in the AddPresetPanel */
3551     [preset setObject:@"Film" forKey:@"PresetName"];
3552         /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/
3553         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"];
3554         /*Set whether or not this is default, at creation set to 0*/
3555         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Default"];
3556         /*Get the whether or not to apply pic settings in the AddPresetPanel*/
3557         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesPictureSettings"];
3558         /* Get the New Preset Description from the field in the AddPresetPanel */
3559     [preset setObject:@"HandBrake's preset for feature films." forKey:@"PresetDescription"];
3560         /* File Format */
3561     [preset setObject:@"MKV file" forKey:@"FileFormat"];
3562         /* Chapter Markers*/
3563          [preset setObject:[NSNumber numberWithInt:1] forKey:@"ChapterMarkers"];
3564     /* Codecs */
3565         [preset setObject:@"AVC/H.264 Video / AC-3 Audio" forKey:@"FileCodecs"];
3566         /* Video encoder */
3567         [preset setObject:@"x264 (h.264 Main)" forKey:@"VideoEncoder"];
3568         /* x264 Option String */
3569         [preset setObject:@"ref=3:mixed-refs:bframes=3:bime:weightb:b-rdo:direct=auto:b-pyramid:me=umh:subme=6:analyse=all:8x8dct:trellis=1:no-fast-pskip" forKey:@"x264Option"];
3570         /* Video quality */
3571         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"];
3572         [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
3573         [preset setObject:@"2000" forKey:@"VideoAvgBitrate"];
3574         [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
3575         
3576         /* Video framerate */
3577         [preset setObject:@"Same as source" forKey:@"VideoFramerate"];
3578         /* GrayScale */
3579         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"];
3580         /* 2 Pass Encoding */
3581         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTwoPass"];
3582         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTurboTwoPass"];
3583         
3584         /*Picture Settings*/
3585         //hb_job_t * job = fTitle->job;
3586         /* Basic Picture Settings */
3587         /* Use Max Picture settings for whatever the dvd is.*/
3588         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesMaxPictureSettings"];
3589         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureAutoCrop"];
3590         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureWidth"];
3591         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureHeight"];
3592         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureKeepRatio"];
3593         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureDeinterlace"];
3594         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PicturePAR"];
3595         /* Set crop settings here */
3596         /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */
3597         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureTopCrop"];
3598     [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureBottomCrop"];
3599         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureLeftCrop"];
3600         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureRightCrop"];
3601         
3602         /*Audio*/
3603         /* Audio Sample Rate*/
3604         [preset setObject:@"48" forKey:@"AudioSampleRate"];
3605         /* Audio Bitrate Rate*/
3606         [preset setObject:@"160" forKey:@"AudioBitRate"];
3607         /* Subtitles*/
3608         [preset setObject:@"None" forKey:@"Subtitles"];
3609         
3610
3611     [preset autorelease];
3612     return preset;
3613
3614 }
3615
3616 - (NSDictionary *)createTelevisionPreset
3617 {
3618     NSMutableDictionary *preset = [[NSMutableDictionary alloc] init];
3619         /* Get the New Preset Name from the field in the AddPresetPanel */
3620     [preset setObject:@"Television" forKey:@"PresetName"];
3621         /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/
3622         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"];
3623         /*Set whether or not this is default, at creation set to 0*/
3624         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Default"];
3625         /*Get the whether or not to apply pic settings in the AddPresetPanel*/
3626         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesPictureSettings"];
3627         /* Get the New Preset Description from the field in the AddPresetPanel */
3628     [preset setObject:@"HandBrake's settings for video from television." forKey:@"PresetDescription"];
3629         /* File Format */
3630     [preset setObject:@"MKV file" forKey:@"FileFormat"];
3631         /* Chapter Markers*/
3632          [preset setObject:[NSNumber numberWithInt:1] forKey:@"ChapterMarkers"];
3633     /* Codecs */
3634         [preset setObject:@"AVC/H.264 Video / AAC Audio" forKey:@"FileCodecs"];
3635         /* Video encoder */
3636         [preset setObject:@"x264 (h.264 Main)" forKey:@"VideoEncoder"];
3637         /* x264 Option String */
3638         [preset setObject:@"ref=3:mixed-refs:bframes=6:bime:weightb:direct=auto:b-pyramid:me=umh:subme=6:analyse=all:8x8dct:trellis=1:nr=150:no-fast-pskip" forKey:@"x264Option"];
3639         /* Video quality */
3640         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"];
3641         [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
3642         [preset setObject:@"1300" forKey:@"VideoAvgBitrate"];
3643         [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
3644         
3645         /* Video framerate */
3646         [preset setObject:@"Same as source" forKey:@"VideoFramerate"];
3647         /* GrayScale */
3648         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"];
3649         /* 2 Pass Encoding */
3650         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTwoPass"];
3651         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTurboTwoPass"];
3652         
3653         /*Picture Settings*/
3654         //hb_job_t * job = fTitle->job;
3655         /* Basic Picture Settings */
3656         /* Use Max Picture settings for whatever the dvd is.*/
3657         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesMaxPictureSettings"];
3658         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureAutoCrop"];
3659         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureWidth"];
3660         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureHeight"];
3661         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureKeepRatio"];
3662         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureDeinterlace"];
3663         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PicturePAR"];
3664         /* Set crop settings here */
3665         /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */
3666         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureTopCrop"];
3667     [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureBottomCrop"];
3668         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureLeftCrop"];
3669         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureRightCrop"];
3670         
3671         /*Audio*/
3672         /* Audio Sample Rate*/
3673         [preset setObject:@"48" forKey:@"AudioSampleRate"];
3674         /* Audio Bitrate Rate*/
3675         [preset setObject:@"160" forKey:@"AudioBitRate"];
3676         /* Subtitles*/
3677         [preset setObject:@"None" forKey:@"Subtitles"];
3678         
3679
3680     [preset autorelease];
3681     return preset;
3682
3683 }
3684
3685 - (NSDictionary *)createAnimationPreset
3686 {
3687     NSMutableDictionary *preset = [[NSMutableDictionary alloc] init];
3688         /* Get the New Preset Name from the field in the AddPresetPanel */
3689     [preset setObject:@"Animation" forKey:@"PresetName"];
3690         /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/
3691         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"];
3692         /*Set whether or not this is default, at creation set to 0*/
3693         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Default"];
3694         /*Get the whether or not to apply pic settings in the AddPresetPanel*/
3695         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesPictureSettings"];
3696         /* Get the New Preset Description from the field in the AddPresetPanel */
3697     [preset setObject:@"HandBrake's settings for cartoons, anime, and CGI." forKey:@"PresetDescription"];
3698         /* File Format */
3699     [preset setObject:@"MKV file" forKey:@"FileFormat"];
3700         /* Chapter Markers*/
3701          [preset setObject:[NSNumber numberWithInt:1] forKey:@"ChapterMarkers"];
3702     /* Codecs */
3703         [preset setObject:@"AVC/H.264 Video / AAC Audio" forKey:@"FileCodecs"];
3704         /* Video encoder */
3705         [preset setObject:@"x264 (h.264 Main)" forKey:@"VideoEncoder"];
3706         /* x264 Option String */
3707         [preset setObject:@"ref=5:mixed-refs:bframes=6: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"];
3708         /* Video quality */
3709         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"];
3710         [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
3711         [preset setObject:@"1000" forKey:@"VideoAvgBitrate"];
3712         [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
3713         
3714         /* Video framerate */
3715         [preset setObject:@"Same as source" forKey:@"VideoFramerate"];
3716         /* GrayScale */
3717         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"];
3718         /* 2 Pass Encoding */
3719         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTwoPass"];
3720         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTurboTwoPass"];
3721         
3722         /*Picture Settings*/
3723         //hb_job_t * job = fTitle->job;
3724         /* Basic Picture Settings */
3725         /* Use Max Picture settings for whatever the dvd is.*/
3726         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesMaxPictureSettings"];
3727         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureAutoCrop"];
3728         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureWidth"];
3729         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureHeight"];
3730         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureKeepRatio"];
3731         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureDeinterlace"];
3732         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PicturePAR"];
3733         /* Set crop settings here */
3734         /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */
3735         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureTopCrop"];
3736     [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureBottomCrop"];
3737         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureLeftCrop"];
3738         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureRightCrop"];
3739         
3740         /*Audio*/
3741         /* Audio Sample Rate*/
3742         [preset setObject:@"48" forKey:@"AudioSampleRate"];
3743         /* Audio Bitrate Rate*/
3744         [preset setObject:@"160" forKey:@"AudioBitRate"];
3745         /* Subtitles*/
3746         [preset setObject:@"None" forKey:@"Subtitles"];
3747         
3748
3749     [preset autorelease];
3750     return preset;
3751
3752 }
3753
3754 - (NSDictionary *)createQuickTimePreset
3755 {
3756     NSMutableDictionary *preset = [[NSMutableDictionary alloc] init];
3757         /* Get the New Preset Name from the field in the AddPresetPanel */
3758     [preset setObject:@"QuickTime" forKey:@"PresetName"];
3759         /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/
3760         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"];
3761         /*Set whether or not this is default, at creation set to 0*/
3762         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Default"];
3763         /*Get the whether or not to apply pic settings in the AddPresetPanel*/
3764         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesPictureSettings"];
3765         /* Get the New Preset Description from the field in the AddPresetPanel */
3766     [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"];
3767         /* File Format */
3768     [preset setObject:@"MP4 file" forKey:@"FileFormat"];
3769         /* Chapter Markers*/
3770          [preset setObject:[NSNumber numberWithInt:1] forKey:@"ChapterMarkers"];
3771     /* Codecs */
3772         [preset setObject:@"AVC/H.264 Video / AAC Audio" forKey:@"FileCodecs"];
3773         /* Video encoder */
3774         [preset setObject:@"x264 (h.264 Main)" forKey:@"VideoEncoder"];
3775         /* x264 Option String */
3776         [preset setObject:@"ref=3:mixed-refs:bframes=3:bime:weightb:b-rdo:direct=auto:me=umh:subme=5:analyse=all:8x8dct:trellis=1:no-fast-pskip" forKey:@"x264Option"];
3777         /* Video quality */
3778         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"];
3779         [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
3780         [preset setObject:@"2000" forKey:@"VideoAvgBitrate"];
3781         [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
3782         
3783         /* Video framerate */
3784         [preset setObject:@"Same as source" forKey:@"VideoFramerate"];
3785         /* GrayScale */
3786         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"];
3787         /* 2 Pass Encoding */
3788         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTwoPass"];
3789         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTurboTwoPass"];
3790         
3791         /*Picture Settings*/
3792         //hb_job_t * job = fTitle->job;
3793         /* Basic Picture Settings */
3794         /* Use Max Picture settings for whatever the dvd is.*/
3795         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesMaxPictureSettings"];
3796         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureAutoCrop"];
3797         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureWidth"];
3798         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureHeight"];
3799         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureKeepRatio"];
3800         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureDeinterlace"];
3801         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PicturePAR"];
3802         /* Set crop settings here */
3803         /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */
3804         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureTopCrop"];
3805     [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureBottomCrop"];
3806         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureLeftCrop"];
3807         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureRightCrop"];
3808         
3809         /*Audio*/
3810         /* Audio Sample Rate*/
3811         [preset setObject:@"48" forKey:@"AudioSampleRate"];
3812         /* Audio Bitrate Rate*/
3813         [preset setObject:@"160" forKey:@"AudioBitRate"];
3814         /* Subtitles*/
3815         [preset setObject:@"None" forKey:@"Subtitles"];
3816         
3817
3818     [preset autorelease];
3819     return preset;
3820
3821 }
3822
3823 - (NSDictionary *)createBedlamPreset
3824 {
3825     NSMutableDictionary *preset = [[NSMutableDictionary alloc] init];
3826         /* Get the New Preset Name from the field in the AddPresetPanel */
3827     [preset setObject:@"Bedlam" forKey:@"PresetName"];
3828         /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/
3829         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"];
3830         /*Set whether or not this is default, at creation set to 0*/
3831         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Default"];
3832         /*Get the whether or not to apply pic settings in the AddPresetPanel*/
3833         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesPictureSettings"];
3834         /* Get the New Preset Description from the field in the AddPresetPanel */
3835     [preset setObject:@"HandBrake's settings maxed out for slowest encoding and highest quality. Use at your own risk. So slow it's not just insane...it's a trip to the looney bin." forKey:@"PresetDescription"];
3836         /* File Format */
3837     [preset setObject:@"MKV file" forKey:@"FileFormat"];
3838         /* Chapter Markers*/
3839          [preset setObject:[NSNumber numberWithInt:1] forKey:@"ChapterMarkers"];
3840     /* Codecs */
3841         [preset setObject:@"AVC/H.264 Video / AC-3 Audio" forKey:@"FileCodecs"];
3842         /* Video encoder */
3843         [preset setObject:@"x264 (h.264 Main)" forKey:@"VideoEncoder"];
3844         /* x264 Option String */
3845         [preset setObject:@"ref=16:mixed-refs:bframes=6: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"];
3846         /* Video quality */
3847         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"];
3848         [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
3849         [preset setObject:@"1800" forKey:@"VideoAvgBitrate"];
3850         [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
3851         
3852         /* Video framerate */
3853         [preset setObject:@"Same as source" forKey:@"VideoFramerate"];
3854         /* GrayScale */
3855         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"];
3856         /* 2 Pass Encoding */
3857         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTwoPass"];
3858         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTurboTwoPass"];
3859         
3860         /*Picture Settings*/
3861         //hb_job_t * job = fTitle->job;
3862         /* Basic Picture Settings */
3863         /* Use Max Picture settings for whatever the dvd is.*/
3864         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesMaxPictureSettings"];
3865         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureAutoCrop"];
3866         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureWidth"];
3867         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureHeight"];
3868         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureKeepRatio"];
3869         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureDeinterlace"];
3870         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PicturePAR"];
3871         /* Set crop settings here */
3872         /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */
3873         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureTopCrop"];
3874     [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureBottomCrop"];
3875         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureLeftCrop"];
3876         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureRightCrop"];
3877         
3878         /*Audio*/
3879         /* Audio Sample Rate*/
3880         [preset setObject:@"48" forKey:@"AudioSampleRate"];
3881         /* Audio Bitrate Rate*/
3882         [preset setObject:@"160" forKey:@"AudioBitRate"];
3883         /* Subtitles*/
3884         [preset setObject:@"None" forKey:@"Subtitles"];
3885         
3886
3887     [preset autorelease];
3888     return preset;
3889
3890 }
3891
3892 - (NSDictionary *)createiPhonePreset
3893 {
3894     NSMutableDictionary *preset = [[NSMutableDictionary alloc] init];
3895         /* Get the New Preset Name from the field in the AddPresetPanel */
3896     [preset setObject:@"iPhone / iPod Touch" forKey:@"PresetName"];
3897         /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/
3898         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"];
3899         /*Set whether or not this is default, at creation set to 0*/
3900         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Default"];
3901         /*Get the whether or not to apply pic settings in the AddPresetPanel*/
3902         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesPictureSettings"];
3903         /* Get the New Preset Description from the field in the AddPresetPanel */
3904     [preset setObject:@"HandBrake's settings for the iPhone." forKey:@"PresetDescription"];
3905         /* File Format */
3906     [preset setObject:@"MP4 file" forKey:@"FileFormat"];
3907         /* Chapter Markers*/
3908          [preset setObject:[NSNumber numberWithInt:1] forKey:@"ChapterMarkers"];
3909     /* Codecs */
3910         [preset setObject:@"AVC/H.264 Video / AAC Audio" forKey:@"FileCodecs"];
3911         /* Video encoder */
3912         [preset setObject:@"x264 (h.264 iPod)" forKey:@"VideoEncoder"];
3913         /* x264 Option String */
3914         [preset setObject:@"cabac=0:ref=1:analyse=all:me=umh:subme=6:no-fast-pskip=1:trellis=1" forKey:@"x264Option"];
3915         /* Video quality */
3916         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"];
3917         [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
3918         [preset setObject:@"960" forKey:@"VideoAvgBitrate"];
3919         [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
3920         
3921         /* Video framerate */
3922         [preset setObject:@"Same as source" forKey:@"VideoFramerate"];
3923         /* GrayScale */
3924         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"];
3925         /* 2 Pass Encoding */
3926         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoTwoPass"];
3927         
3928         /*Picture Settings*/
3929         //hb_job_t * job = fTitle->job;
3930         /* Basic Picture Settings */
3931         /* Use Max Picture settings for whatever the dvd is.*/
3932         [preset setObject:[NSNumber numberWithInt:0] forKey:@"UsesMaxPictureSettings"];
3933         [preset setObject:[NSNumber numberWithInt:480] forKey:@"PictureWidth"];
3934         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureHeight"];
3935         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureKeepRatio"];
3936         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureDeinterlace"];
3937         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PicturePAR"];
3938         /* Set crop settings here */
3939         /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */
3940         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureAutoCrop"];
3941         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureTopCrop"];
3942     [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureBottomCrop"];
3943         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureLeftCrop"];
3944         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureRightCrop"];
3945         
3946         /*Audio*/
3947         /* Audio Sample Rate*/
3948         [preset setObject:@"48" forKey:@"AudioSampleRate"];
3949         /* Audio Bitrate Rate*/
3950         [preset setObject:@"128" forKey:@"AudioBitRate"];
3951         /* Subtitles*/
3952         [preset setObject:@"None" forKey:@"Subtitles"];
3953         
3954
3955     [preset autorelease];
3956     return preset;
3957
3958 }
3959
3960 - (NSDictionary *)createDeuxSixQuatrePreset
3961 {
3962     NSMutableDictionary *preset = [[NSMutableDictionary alloc] init];
3963         /* Get the New Preset Name from the field in the AddPresetPanel */
3964     [preset setObject:@"Deux Six Quatre" forKey:@"PresetName"];
3965         /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/
3966         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"];
3967         /*Set whether or not this is default, at creation set to 0*/
3968         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Default"];
3969         /*Get the whether or not to apply pic settings in the AddPresetPanel*/
3970         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesPictureSettings"];
3971         /* Get the New Preset Description from the field in the AddPresetPanel */
3972     [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"];
3973         /* File Format */
3974     [preset setObject:@"MKV file" forKey:@"FileFormat"];
3975         /* Chapter Markers*/
3976          [preset setObject:[NSNumber numberWithInt:1] forKey:@"ChapterMarkers"];
3977     /* Codecs */
3978         [preset setObject:@"AVC/H.264 Video / AC-3 Audio" forKey:@"FileCodecs"];
3979         /* Video encoder */
3980         [preset setObject:@"x264 (h.264 Main)" forKey:@"VideoEncoder"];
3981         /* x264 Option String */
3982         [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"];
3983         /* Video quality */
3984         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"];
3985         [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
3986         [preset setObject:@"1600" forKey:@"VideoAvgBitrate"];
3987         [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
3988         
3989         /* Video framerate */
3990         [preset setObject:@"Same as source" forKey:@"VideoFramerate"];
3991         /* GrayScale */
3992         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"];
3993         /* 2 Pass Encoding */
3994         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTwoPass"];
3995         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTurboTwoPass"];
3996         
3997         /*Picture Settings*/
3998         //hb_job_t * job = fTitle->job;
3999         /* Basic Picture Settings */
4000         /* Use Max Picture settings for whatever the dvd is.*/
4001         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesMaxPictureSettings"];
4002         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureAutoCrop"];
4003         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureWidth"];
4004         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureHeight"];
4005         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureKeepRatio"];
4006         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureDeinterlace"];
4007         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PicturePAR"];
4008         /* Set crop settings here */
4009         /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */
4010         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureTopCrop"];
4011     [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureBottomCrop"];
4012         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureLeftCrop"];
4013         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureRightCrop"];
4014         
4015         /*Audio*/
4016         /* Audio Sample Rate*/
4017         [preset setObject:@"48" forKey:@"AudioSampleRate"];
4018         /* Audio Bitrate Rate*/
4019         [preset setObject:@"160" forKey:@"AudioBitRate"];
4020         /* Subtitles*/
4021         [preset setObject:@"None" forKey:@"Subtitles"];
4022         
4023
4024     [preset autorelease];
4025     return preset;
4026
4027 }
4028
4029 - (NSDictionary *)createBrokePreset
4030 {
4031     NSMutableDictionary *preset = [[NSMutableDictionary alloc] init];
4032         /* Get the New Preset Name from the field in the AddPresetPanel */
4033     [preset setObject:@"Broke" forKey:@"PresetName"];
4034         /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/
4035         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"];
4036         /*Set whether or not this is default, at creation set to 0*/
4037         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Default"];
4038         /*Get the whether or not to apply pic settings in the AddPresetPanel*/
4039         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesPictureSettings"];
4040         /* Get the New Preset Description from the field in the AddPresetPanel */
4041     [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"];
4042         /* File Format */
4043     [preset setObject:@"MP4 file" forKey:@"FileFormat"];
4044         /* Chapter Markers*/
4045          [preset setObject:[NSNumber numberWithInt:1] forKey:@"ChapterMarkers"];
4046     /* Codecs */
4047         [preset setObject:@"AVC/H.264 Video / AAC Audio" forKey:@"FileCodecs"];
4048         /* Video encoder */
4049         [preset setObject:@"x264 (h.264 Main)" forKey:@"VideoEncoder"];
4050         /* x264 Option String */
4051         [preset setObject:@"ref=3:mixed-refs:bframes=6:bime:weightb:b-rdo:b-pyramid:direct=auto:me=umh:subme=6:trellis=1:analyse=all:8x8dct:no-fast-pskip" forKey:@"x264Option"];
4052         /* Video quality */
4053         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoQualityType"];
4054         [preset setObject:@"695" forKey:@"VideoTargetSize"];
4055         [preset setObject:@"1600" forKey:@"VideoAvgBitrate"];
4056         [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
4057         
4058         /* Video framerate */
4059         [preset setObject:@"Same as source" forKey:@"VideoFramerate"];
4060         /* GrayScale */
4061         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"];
4062         /* 2 Pass Encoding */
4063         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTwoPass"];
4064         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoTurboTwoPass"];
4065         
4066         /*Picture Settings*/
4067         //hb_job_t * job = fTitle->job;
4068         /* Basic Picture Settings */
4069         /* Use Max Picture settings for whatever the dvd is.*/
4070         [preset setObject:[NSNumber numberWithInt:0] forKey:@"UsesMaxPictureSettings"];
4071         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureAutoCrop"];
4072         [preset setObject:[NSNumber numberWithInt:640] forKey:@"PictureWidth"];
4073         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureHeight"];
4074         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureKeepRatio"];
4075         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureDeinterlace"];
4076         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PicturePAR"];
4077         /* Set crop settings here */
4078         /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */
4079         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureTopCrop"];
4080     [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureBottomCrop"];
4081         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureLeftCrop"];
4082         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureRightCrop"];
4083         
4084         /*Audio*/
4085         /* Audio Sample Rate*/
4086         [preset setObject:@"48" forKey:@"AudioSampleRate"];
4087         /* Audio Bitrate Rate*/
4088         [preset setObject:@"128" forKey:@"AudioBitRate"];
4089         /* Subtitles*/
4090         [preset setObject:@"None" forKey:@"Subtitles"];
4091         
4092
4093     [preset autorelease];
4094     return preset;
4095
4096 }
4097
4098 - (NSDictionary *)createBlindPreset
4099 {
4100     NSMutableDictionary *preset = [[NSMutableDictionary alloc] init];
4101         /* Get the New Preset Name from the field in the AddPresetPanel */
4102     [preset setObject:@"Blind" forKey:@"PresetName"];
4103         /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/
4104         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"];
4105         /*Set whether or not this is default, at creation set to 0*/
4106         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Default"];
4107         /*Get the whether or not to apply pic settings in the AddPresetPanel*/
4108         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesPictureSettings"];
4109         /* Get the New Preset Description from the field in the AddPresetPanel */
4110     [preset setObject:@"HandBrake's preset for impatient people who don't care about picture quality." forKey:@"PresetDescription"];
4111         /* File Format */
4112     [preset setObject:@"MP4 file" forKey:@"FileFormat"];
4113         /* Chapter Markers*/
4114          [preset setObject:[NSNumber numberWithInt:1] forKey:@"ChapterMarkers"];
4115     /* Codecs */
4116         [preset setObject:@"MPEG-4 Video / AAC Audio" forKey:@"FileCodecs"];
4117         /* Video encoder */
4118         [preset setObject:@"FFmpeg" forKey:@"VideoEncoder"];
4119         /* x264 Option String */
4120         [preset setObject:@"" forKey:@"x264Option"];
4121         /* Video quality */
4122         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"];
4123         [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
4124         [preset setObject:@"512" forKey:@"VideoAvgBitrate"];
4125         [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
4126         
4127         /* Video framerate */
4128         [preset setObject:@"Same as source" forKey:@"VideoFramerate"];
4129         /* GrayScale */
4130         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"];
4131         /* 2 Pass Encoding */
4132         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoTwoPass"];
4133         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoTurboTwoPass"];
4134         
4135         /*Picture Settings*/
4136         //hb_job_t * job = fTitle->job;
4137         /* Basic Picture Settings */
4138         /* Use Max Picture settings for whatever the dvd is.*/
4139         [preset setObject:[NSNumber numberWithInt:0] forKey:@"UsesMaxPictureSettings"];
4140         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureAutoCrop"];
4141         [preset setObject:[NSNumber numberWithInt:512] forKey:@"PictureWidth"];
4142         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureHeight"];
4143         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureKeepRatio"];
4144         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureDeinterlace"];
4145         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PicturePAR"];
4146         /* Set crop settings here */
4147         /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */
4148         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureTopCrop"];
4149     [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureBottomCrop"];
4150         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureLeftCrop"];
4151         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureRightCrop"];
4152         
4153         /*Audio*/
4154         /* Audio Sample Rate*/
4155         [preset setObject:@"48" forKey:@"AudioSampleRate"];
4156         /* Audio Bitrate Rate*/
4157         [preset setObject:@"128" forKey:@"AudioBitRate"];
4158         /* Subtitles*/
4159         [preset setObject:@"None" forKey:@"Subtitles"];
4160         
4161
4162     [preset autorelease];
4163     return preset;
4164
4165 }
4166
4167 - (NSDictionary *)createCRFPreset
4168 {
4169     NSMutableDictionary *preset = [[NSMutableDictionary alloc] init];
4170         /* Get the New Preset Name from the field in the AddPresetPanel */
4171     [preset setObject:@"Constant Quality Rate" forKey:@"PresetName"];
4172         /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/
4173         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"];
4174         /*Set whether or not this is default, at creation set to 0*/
4175         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Default"];
4176         /*Get the whether or not to apply pic settings in the AddPresetPanel*/
4177         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesPictureSettings"];
4178         /* Get the New Preset Description from the field in the AddPresetPanel */
4179     [preset setObject:@"HandBrake's preset for consistently excellent quality in one pass, with the downside of entirely unpredictable file sizes and bitrates." forKey:@"PresetDescription"];
4180         /* File Format */
4181     [preset setObject:@"MKV file" forKey:@"FileFormat"];
4182         /* Chapter Markers*/
4183          [preset setObject:[NSNumber numberWithInt:1] forKey:@"ChapterMarkers"];
4184     /* Codecs */
4185         [preset setObject:@"AVC/H.264 Video / AC-3 Audio" forKey:@"FileCodecs"];
4186         /* Video encoder */
4187         [preset setObject:@"x264 (h.264 Main)" forKey:@"VideoEncoder"];
4188         /* x264 Option String */
4189         [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"];
4190         /* Video quality */
4191         [preset setObject:[NSNumber numberWithInt:2] forKey:@"VideoQualityType"];
4192         [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
4193         [preset setObject:@"2000" forKey:@"VideoAvgBitrate"];
4194         [preset setObject:[NSNumber numberWithFloat:0.6471] forKey:@"VideoQualitySlider"];
4195         
4196         /* Video framerate */
4197         [preset setObject:@"Same as source" forKey:@"VideoFramerate"];
4198         /* GrayScale */
4199         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"];
4200         /* 2 Pass Encoding */
4201         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoTwoPass"];
4202         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoTurboTwoPass"];
4203         
4204         /*Picture Settings*/
4205         //hb_job_t * job = fTitle->job;
4206         /* Basic Picture Settings */
4207         /* Use Max Picture settings for whatever the dvd is.*/
4208         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesMaxPictureSettings"];
4209         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PictureAutoCrop"];
4210         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureWidth"];
4211         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureHeight"];
4212         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureKeepRatio"];
4213         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureDeinterlace"];
4214         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PicturePAR"];
4215         /* Set crop settings here */
4216         /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */
4217         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureTopCrop"];
4218     [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureBottomCrop"];
4219         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureLeftCrop"];
4220         [preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureRightCrop"];
4221         
4222         /*Audio*/
4223         /* Audio Sample Rate*/
4224         [preset setObject:@"48" forKey:@"AudioSampleRate"];
4225         /* Audio Bitrate Rate*/
4226         [preset setObject:@"160" forKey:@"AudioBitRate"];
4227         /* Subtitles*/
4228         [preset setObject:@"None" forKey:@"Subtitles"];
4229         
4230
4231     [preset autorelease];
4232     return preset;
4233
4234 }
4235
4236
4237 - (IBAction)deletePreset:(id)sender
4238 {
4239     int status;
4240     NSEnumerator *enumerator;
4241     NSNumber *index;
4242     NSMutableArray *tempArray;
4243     id tempObject;
4244     
4245     if ( [tableView numberOfSelectedRows] == 0 )
4246         return;
4247     /* Alert user before deleting preset */
4248         /* Comment out for now, tie to user pref eventually */
4249
4250     //NSBeep();
4251     status = NSRunAlertPanel(@"Warning!", @"Are you sure that you want to delete the selected preset?", @"OK", @"Cancel", nil);
4252     
4253     if ( status == NSAlertDefaultReturn ) {
4254         enumerator = [tableView selectedRowEnumerator];
4255         tempArray = [NSMutableArray array];
4256         
4257         while ( (index = [enumerator nextObject]) ) {
4258             tempObject = [UserPresets objectAtIndex:[index intValue]];
4259             [tempArray addObject:tempObject];
4260         }
4261         
4262         [UserPresets removeObjectsInArray:tempArray];
4263         [tableView reloadData];
4264         [self savePreset];   
4265     }
4266 }
4267
4268 - (IBAction)getDefaultPresets:(id)sender
4269 {
4270         int i = 0;
4271     NSEnumerator *enumerator = [UserPresets objectEnumerator];
4272         id tempObject;
4273         while (tempObject = [enumerator nextObject])
4274         {
4275                 NSDictionary *thisPresetDict = tempObject;
4276                 if ([[thisPresetDict objectForKey:@"Default"] intValue] == 1) // 1 is HB default
4277                 {
4278                         presetHbDefault = i;    
4279                 }
4280                 if ([[thisPresetDict objectForKey:@"Default"] intValue] == 2) // 2 is User specified default
4281                 {
4282                         presetUserDefault = i;  
4283                 }
4284                 i++;
4285         }
4286 }
4287
4288 - (IBAction)setDefaultPreset:(id)sender
4289 {
4290     int i = 0;
4291     NSEnumerator *enumerator = [UserPresets objectEnumerator];
4292         id tempObject;
4293         /* First make sure the old user specified default preset is removed */
4294         while (tempObject = [enumerator nextObject])
4295         {
4296                 /* make sure we are not removing the default HB preset */
4297                 if ([[[UserPresets objectAtIndex:i] objectForKey:@"Default"] intValue] != 1) // 1 is HB default
4298                 {
4299                         [[UserPresets objectAtIndex:i] setObject:[NSNumber numberWithInt:0] forKey:@"Default"];
4300                 }
4301                 i++;
4302         }
4303         /* Second, go ahead and set the appropriate user specfied preset */
4304         /* we get the chosen preset from the UserPresets array */
4305         if ([[[UserPresets objectAtIndex:[tableView selectedRow]] objectForKey:@"Default"] intValue] != 1) // 1 is HB default
4306         {
4307                 [[UserPresets objectAtIndex:[tableView selectedRow]] setObject:[NSNumber numberWithInt:2] forKey:@"Default"];
4308         }
4309         presetUserDefault = [tableView selectedRow];
4310         
4311         /* We save all of the preset data here */
4312     [self savePreset];
4313         /* We Reload the New Table data for presets */
4314     [tableView reloadData];
4315 }
4316
4317 - (IBAction)selectDefaultPreset:(id)sender
4318 {
4319         /* if there is a user specified default, we use it */
4320         if (presetUserDefault)
4321         {
4322         [tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:presetUserDefault] byExtendingSelection:NO];
4323         [self tableViewSelected:NULL];
4324         }
4325         else if (presetHbDefault) //else we use the built in default presetHbDefault
4326         {
4327         [tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:presetHbDefault] byExtendingSelection:NO];
4328         [self tableViewSelected:NULL];
4329         }
4330 }
4331
4332 - (IBAction)tableViewSelected:(id)sender
4333 {
4334     /* Since we cannot disable the presets tableView in terms of clickability
4335            we will use the enabled state of the add presets button to determine whether
4336            or not clicking on a preset will do anything */
4337         if ([fPresetsAdd isEnabled])
4338         {
4339                 if ([tableView selectedRow] >= 0)
4340                 {       
4341                         /* we get the chosen preset from the UserPresets array */
4342                         chosenPreset = [UserPresets objectAtIndex:[tableView selectedRow]];
4343                         curUserPresetChosenNum = [sender selectedRow];
4344                         /* we set the preset display field in main window here */
4345                         [fPresetSelectedDisplay setStringValue: [NSString stringWithFormat: @"%@",[chosenPreset valueForKey:@"PresetName"]]];
4346                         if ([[chosenPreset objectForKey:@"Default"] intValue] == 1)
4347                         {
4348                                 [fPresetSelectedDisplay setStringValue: [NSString stringWithFormat: @"%@ (Default)",[chosenPreset valueForKey:@"PresetName"]]];
4349                         }
4350                         else
4351                         {
4352                                 [fPresetSelectedDisplay setStringValue: [NSString stringWithFormat: @"%@",[chosenPreset valueForKey:@"PresetName"]]];
4353                         }
4354                         /* File Format */
4355                         [fDstFormatPopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"FileFormat"]]];
4356                         [self formatPopUpChanged: NULL];
4357                         
4358                         /* Chapter Markers*/
4359                         [fCreateChapterMarkers setState:[[chosenPreset objectForKey:@"ChapterMarkers"] intValue]];
4360                         /* Allow Mpeg4 64 bit formatting +4GB file sizes */
4361                         [fDstMpgLargeFileCheck setState:[[chosenPreset objectForKey:@"Mp4LargeFile"] intValue]];
4362                         /* Codecs */
4363                         [fDstCodecsPopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"FileCodecs"]]];
4364                         [self codecsPopUpChanged: NULL];
4365                         /* Video encoder */
4366                         [fVidEncoderPopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"VideoEncoder"]]];
4367                         
4368                         /* We can show the preset options here in the gui if we want to
4369                                 so we check to see it the user has specified it in the prefs */
4370                         [fAdvancedOptions setOptions: [NSString stringWithFormat:[chosenPreset valueForKey:@"x264Option"]]];
4371                         
4372                         /* Lets run through the following functions to get variables set there */
4373                         [self encoderPopUpChanged: NULL];
4374                         
4375                         [self calculateBitrate: NULL];
4376                         
4377                         /* Video quality */
4378                         [fVidQualityMatrix selectCellAtRow:[[chosenPreset objectForKey:@"VideoQualityType"] intValue] column:0];
4379                         
4380                         [fVidTargetSizeField setStringValue: [NSString stringWithFormat:[chosenPreset valueForKey:@"VideoTargetSize"]]];
4381                         [fVidBitrateField setStringValue: [NSString stringWithFormat:[chosenPreset valueForKey:@"VideoAvgBitrate"]]];
4382                         
4383                         [fVidQualitySlider setFloatValue: [[chosenPreset valueForKey:@"VideoQualitySlider"] floatValue]];
4384                         [self videoMatrixChanged: NULL];
4385                         
4386                         /* Video framerate */
4387                         /* For video preset video framerate, we want to make sure that Same as source does not conflict with the
4388                detected framerate in the fVidRatePopUp so we use index 0*/
4389                         if ([[NSString stringWithFormat:[chosenPreset valueForKey:@"VideoFramerate"]] isEqualToString: @"Same as source"])
4390             {
4391                 [fVidRatePopUp selectItemAtIndex: 0];
4392             }
4393             else
4394             {
4395                 [fVidRatePopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"VideoFramerate"]]];
4396             }
4397                         
4398                         /* GrayScale */
4399                         [fVidGrayscaleCheck setState:[[chosenPreset objectForKey:@"VideoGrayScale"] intValue]];
4400                         
4401                         /* 2 Pass Encoding */
4402                         [fVidTwoPassCheck setState:[[chosenPreset objectForKey:@"VideoTwoPass"] intValue]];
4403                         [self twoPassCheckboxChanged: NULL];
4404                         /* Turbo 1st pass for 2 Pass Encoding */
4405                         [fVidTurboPassCheck setState:[[chosenPreset objectForKey:@"VideoTurboTwoPass"] intValue]];
4406                         
4407                         /*Audio*/
4408                         
4409                         /* Audio Sample Rate*/
4410                         [fAudRatePopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"AudioSampleRate"]]];
4411                         /* Audio Bitrate Rate*/
4412                         [fAudBitratePopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"AudioBitRate"]]];
4413                         /*Subtitles*/
4414                         [fSubPopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"Subtitles"]]];
4415                         
4416                         /* Picture Settings */
4417                         /* Look to see if we apply these here in objectForKey:@"UsesPictureSettings"] */
4418                         if ([[chosenPreset objectForKey:@"UsesPictureSettings"]  intValue] > 0)
4419                         {
4420                                 hb_job_t * job = fTitle->job;
4421                                 /* Check to see if we should use the max picture setting for the current title*/
4422                                 if ([[chosenPreset objectForKey:@"UsesPictureSettings"]  intValue] == 2 || [[chosenPreset objectForKey:@"UsesMaxPictureSettings"]  intValue] == 1)
4423                                 {
4424                                         /* Use Max Picture settings for whatever the dvd is.*/
4425                                         [self revertPictureSizeToMax: NULL];
4426                                         job->keep_ratio = [[chosenPreset objectForKey:@"PictureKeepRatio"]  intValue];
4427                                         if (job->keep_ratio == 1)
4428                                         {
4429                                                 hb_fix_aspect( job, HB_KEEP_WIDTH );
4430                                                 if( job->height > fTitle->height )
4431                                                 {
4432                                                         job->height = fTitle->height;
4433                                                         hb_fix_aspect( job, HB_KEEP_HEIGHT );
4434                                                 }
4435                                         }
4436                                         job->pixel_ratio = [[chosenPreset objectForKey:@"PicturePAR"]  intValue];
4437                                 }
4438                                 else // Apply picture settings that were in effect at the time the preset was saved
4439                                 {
4440                                         job->width = [[chosenPreset objectForKey:@"PictureWidth"]  intValue];
4441                                         job->height = [[chosenPreset objectForKey:@"PictureHeight"]  intValue];
4442                                         job->keep_ratio = [[chosenPreset objectForKey:@"PictureKeepRatio"]  intValue];
4443                                         if (job->keep_ratio == 1)
4444                                         {
4445                                                 hb_fix_aspect( job, HB_KEEP_WIDTH );
4446                                                 if( job->height > fTitle->height )
4447                                                 {
4448                                                         job->height = fTitle->height;
4449                                                         hb_fix_aspect( job, HB_KEEP_HEIGHT );
4450                                                 }
4451                                         }
4452                                         job->pixel_ratio = [[chosenPreset objectForKey:@"PicturePAR"]  intValue];
4453                     [fPictureController setDeinterlace:[[chosenPreset objectForKey:@"PictureDeinterlace"] intValue]];
4454                                         
4455                                         if ([chosenPreset objectForKey:@"PictureDetelecine"])
4456                                         {
4457                         [fPictureController setDetelecine:[[chosenPreset objectForKey:@"PictureDetelecine"] intValue]];
4458                                         }
4459                                         if ([chosenPreset objectForKey:@"PictureDenoise"])
4460                                         {
4461                         [fPictureController setDenoise:[[chosenPreset objectForKey:@"PictureDenoise"] intValue]];
4462                                         }
4463                                         /* If Cropping is set to custom, then recall all four crop values from
4464                                                 when the preset was created and apply them */
4465                                         if ([[chosenPreset objectForKey:@"PictureAutoCrop"]  intValue] == 0)
4466                                         {
4467                         [fPictureController setAutoCrop:NO];
4468                                                 
4469                                                 /* Here we use the custom crop values saved at the time the preset was saved */
4470                                                 job->crop[0] = [[chosenPreset objectForKey:@"PictureTopCrop"]  intValue];
4471                                                 job->crop[1] = [[chosenPreset objectForKey:@"PictureBottomCrop"]  intValue];
4472                                                 job->crop[2] = [[chosenPreset objectForKey:@"PictureLeftCrop"]  intValue];
4473                                                 job->crop[3] = [[chosenPreset objectForKey:@"PictureRightCrop"]  intValue];
4474                                                 
4475                                         }
4476                                         else /* if auto crop has been saved in preset, set to auto and use post scan auto crop */
4477                                         {
4478                         [fPictureController setAutoCrop:YES];
4479                         /* Here we use the auto crop values determined right after scan */
4480                                                 job->crop[0] = AutoCropTop;
4481                                                 job->crop[1] = AutoCropBottom;
4482                                                 job->crop[2] = AutoCropLeft;
4483                                                 job->crop[3] = AutoCropRight;
4484                                                 
4485                                         }
4486                                 }
4487                                 [self calculatePictureSizing: NULL]; 
4488                         }
4489                         
4490                         
4491                         [[fPresetsActionMenu itemAtIndex:0] setEnabled: YES];
4492                         }
4493 }
4494 }
4495
4496
4497
4498 - (int)numberOfRowsInTableView:(NSTableView *)aTableView
4499 {
4500     return [UserPresets count];
4501 }
4502
4503 /* we use this to determine display characteristics for
4504 each table cell based on content currently only used to
4505 show the built in presets in a blue font. */
4506 - (void)tableView:(NSTableView *)aTableView
4507  willDisplayCell:(id)aCell 
4508  forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
4509 {
4510     NSDictionary *userPresetDict = [UserPresets objectAtIndex:rowIndex];
4511         NSFont *txtFont;
4512         NSColor *fontColor;
4513         NSColor *shadowColor;
4514         txtFont = [NSFont systemFontOfSize: [NSFont smallSystemFontSize]];
4515         /* First, we check to see if its a selected row, if so, we use white since its highlighted in blue */
4516         if ([[aTableView selectedRowIndexes] containsIndex:rowIndex] && ([tableView editedRow] != rowIndex))
4517         {
4518                 
4519                 fontColor = [NSColor whiteColor];
4520                 shadowColor = [NSColor colorWithDeviceRed:(127.0/255.0) green:(140.0/255.0) blue:(160.0/255.0) alpha:1.0];
4521         }
4522         else
4523         {
4524                 /* We set the properties of unselected rows */
4525                 /* if built-in preset (defined by "type" == 0) we use a blue font */
4526                 if ([[userPresetDict objectForKey:@"Type"] intValue] == 0)
4527                 {
4528                         fontColor = [NSColor blueColor];
4529                 }
4530                 else // User created preset, use a black font
4531                 {
4532                         fontColor = [NSColor blackColor];
4533                 }
4534                 shadowColor = nil;
4535         }
4536         /* We check to see if this is the HB default, if so, color it appropriately */
4537         if (!presetUserDefault && presetHbDefault && rowIndex == presetHbDefault)
4538         {
4539         txtFont = [NSFont boldSystemFontOfSize: [NSFont smallSystemFontSize]];
4540         }
4541         /* We check to see if this is the User Specified default, if so, color it appropriately */
4542         if (presetUserDefault && rowIndex == presetUserDefault)
4543         {
4544         txtFont = [NSFont boldSystemFontOfSize: [NSFont smallSystemFontSize]];
4545         }
4546         
4547         [aCell setTextColor:fontColor];
4548         [aCell setFont:txtFont];
4549         /* this shadow stuff (like mail app) for some reason looks crappy, commented out
4550         temporarily in case we want to resurrect it */
4551         /*
4552         NSShadow *shadow = [[NSShadow alloc] init];
4553         NSSize shadowOffset = { width: 1.0, height: -1.5};
4554         [shadow setShadowOffset:shadowOffset];
4555         [shadow setShadowColor:shadowColor];
4556         [shadow set];
4557         */
4558         
4559 }
4560 /* Method to display tooltip with the description for each preset, if available */
4561 - (NSString *)tableView:(NSTableView *)aTableView toolTipForCell:(NSCell *)aCell 
4562                    rect:(NSRectPointer)aRect tableColumn:(NSTableColumn *)aTableColumn
4563                     row:(int)rowIndex mouseLocation:(NSPoint)aPos
4564 {
4565      /* initialize the tooltip contents variable */
4566          NSString *loc_tip;
4567      /* if there is a description for the preset, we show it in the tooltip */
4568          if ([[UserPresets objectAtIndex:rowIndex] valueForKey:@"PresetDescription"])
4569          {
4570         loc_tip = [NSString stringWithFormat: @"%@",[[UserPresets objectAtIndex:rowIndex] valueForKey:@"PresetDescription"]];
4571         return (loc_tip);
4572          }
4573          else
4574          {
4575         loc_tip = @"No description available";
4576          }
4577          return (loc_tip);
4578
4579 }
4580
4581 - (id)tableView:(NSTableView *)aTableView
4582       objectValueForTableColumn:(NSTableColumn *)aTableColumn
4583       row:(int)rowIndex
4584 {
4585 id theRecord, theValue;
4586     
4587     theRecord = [UserPresets objectAtIndex:rowIndex];
4588     theValue = [theRecord objectForKey:[aTableColumn identifier]];
4589     return theValue;
4590 }
4591
4592 // NSTableDataSource method that we implement to edit values directly in the table...
4593 - (void)tableView:(NSTableView *)aTableView
4594         setObjectValue:(id)anObject
4595         forTableColumn:(NSTableColumn *)aTableColumn
4596         row:(int)rowIndex
4597 {
4598     id theRecord;
4599     
4600     theRecord = [UserPresets objectAtIndex:rowIndex];
4601     [theRecord setObject:anObject forKey:@"PresetName"];
4602     /* We Sort the Presets By Factory or Custom */
4603         NSSortDescriptor * presetTypeDescriptor=[[[NSSortDescriptor alloc] initWithKey:@"Type" 
4604                                                     ascending:YES] autorelease];
4605                 /* We Sort the Presets Alphabetically by name */
4606         NSSortDescriptor * presetNameDescriptor=[[[NSSortDescriptor alloc] initWithKey:@"PresetName" 
4607                                                     ascending:YES selector:@selector(caseInsensitiveCompare:)] autorelease];
4608         NSArray *sortDescriptors=[NSArray arrayWithObjects:presetTypeDescriptor,presetNameDescriptor,nil];
4609     NSArray *sortedArray=[UserPresets sortedArrayUsingDescriptors:sortDescriptors];
4610         [UserPresets setArray:sortedArray];
4611         /* We Reload the New Table data for presets */
4612     [tableView reloadData];
4613    /* We save all of the preset data here */
4614     [self savePreset];
4615 }
4616
4617 - (void)savePreset
4618 {
4619     [UserPresets writeToFile:UserPresetsFile atomically:YES];
4620         /* We get the default preset in case it changed */
4621         [self getDefaultPresets: NULL];
4622
4623 }
4624
4625 - (void) controlTextDidChange: (NSNotification *) notification
4626 {
4627     [self calculateBitrate: NULL];
4628 }
4629
4630 - (IBAction) openHomepage: (id) sender
4631 {
4632     [[NSWorkspace sharedWorkspace] openURL: [NSURL
4633         URLWithString:@"http://handbrake.m0k.org/"]];
4634 }
4635
4636 - (IBAction) openForums: (id) sender
4637 {
4638     [[NSWorkspace sharedWorkspace] openURL: [NSURL
4639         URLWithString:@"http://handbrake.m0k.org/forum/"]];
4640 }
4641 - (IBAction) openUserGuide: (id) sender
4642 {
4643     [[NSWorkspace sharedWorkspace] openURL: [NSURL
4644         URLWithString:@"http://handbrake.m0k.org/trac/wiki/HandBrakeGuide"]];
4645 }
4646
4647 /**
4648  * Shows debug output window.
4649  */
4650 - (IBAction)showDebugOutputPanel:(id)sender
4651 {
4652     [outputPanel showOutputPanel:sender];
4653 }
4654
4655 /**
4656  * Shows preferences window.
4657  */
4658 - (IBAction) showPreferencesWindow: (id) sender
4659 {
4660     NSWindow * window = [fPreferencesController window];
4661     if (![window isVisible])
4662         [window center];
4663
4664     [window makeKeyAndOrderFront: nil];
4665 }
4666
4667 /**
4668  * Shows queue window.
4669  */
4670 - (IBAction) showQueueWindow:(id)sender
4671 {
4672     [fQueueController showQueueWindow:sender];
4673 }
4674
4675
4676 - (IBAction) toggleDrawer:(id)sender {
4677     [fPresetDrawer toggle:self];
4678 }
4679
4680 @end