OSDN Git Service

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