OSDN Git Service

MacGui: Presets - modify built in presets to work with the new audio formats. Make...
[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
10 #define _(a) NSLocalizedString(a,NULL)
11
12 static int FormatSettings[3][4] =
13   { { HB_MUX_MP4 | HB_VCODEC_FFMPEG | HB_ACODEC_FAAC,
14       HB_MUX_MP4 | HB_VCODEC_X264   | HB_ACODEC_FAAC,
15       0,
16       0 },
17     { HB_MUX_AVI | HB_VCODEC_FFMPEG | HB_ACODEC_LAME,
18       HB_MUX_AVI | HB_VCODEC_FFMPEG | HB_ACODEC_AC3,
19       HB_MUX_AVI | HB_VCODEC_X264   | HB_ACODEC_LAME,
20       HB_MUX_AVI | HB_VCODEC_X264   | HB_ACODEC_AC3 },
21     { HB_MUX_OGM | HB_VCODEC_FFMPEG | HB_ACODEC_VORBIS,
22       HB_MUX_OGM | HB_VCODEC_FFMPEG | HB_ACODEC_LAME,
23       0,
24       0 } };
25
26 /*******************************
27  * HBController implementation *
28  *******************************/
29 @implementation HBController
30
31 - init
32 {
33     self    = [super init];
34     fHandle = NULL;
35     return self;
36 }
37
38 - (void) applicationDidFinishLaunching: (NSNotification *) notification
39 {
40     int    build;
41     char * version;
42
43     /* Init libhb */
44     fHandle = hb_init( HB_DEBUG_NONE, [[NSUserDefaults
45         standardUserDefaults] boolForKey:@"CheckForUpdates"] );
46     
47     /* Init others controllers */
48     [fScanController    SetHandle: fHandle];
49     [fPictureController SetHandle: fHandle];
50     [fQueueController   SetHandle: fHandle];
51         
52
53      /* Call UpdateUI every 2/10 sec */
54     [[NSRunLoop currentRunLoop] addTimer: [NSTimer
55         scheduledTimerWithTimeInterval: 0.2 target: self
56         selector: @selector( UpdateUI: ) userInfo: NULL repeats: FALSE]
57         forMode: NSModalPanelRunLoopMode];
58
59     if( ( build = hb_check_update( fHandle, &version ) ) > -1 )
60     {
61         /* Update available - tell the user */
62         
63         NSBeginInformationalAlertSheet( _( @"Update is available" ),
64             _( @"Go get it!" ), _( @"Discard" ), NULL, fWindow, self,
65             @selector( UpdateAlertDone:returnCode:contextInfo: ),
66             NULL, NULL, [NSString stringWithFormat:
67             _( @"HandBrake %s (build %d) is now available for download." ),
68             version, build] );
69         return;
70
71     }
72
73     /* Show scan panel ASAP */
74     [self performSelectorOnMainThread: @selector(ShowScanPanel:)
75         withObject: NULL waitUntilDone: NO];
76 }
77
78 - (NSApplicationTerminateReply) applicationShouldTerminate:
79     (NSApplication *) app
80 {
81     if( [[fRipButton title] isEqualToString: _( @"Cancel" )] )
82     {
83         [self Cancel: NULL];
84         return NSTerminateCancel;
85     }
86     
87     /* Clean up */
88     hb_close( &fHandle );
89     return NSTerminateNow;
90 }
91
92 - (void) awakeFromNib
93 {
94     [fWindow center];
95
96     [self TranslateStrings];
97
98         /* Init User Presets .plist */
99         /* We declare the default NSFileManager into fileManager */
100         NSFileManager * fileManager = [NSFileManager defaultManager];
101         //presetPrefs = [[NSUserDefaults standardUserDefaults] retain];
102         /* we set the files and support paths here */
103         AppSupportDirectory = @"~/Library/Application Support/HandBrake";
104     AppSupportDirectory = [AppSupportDirectory stringByExpandingTildeInPath];
105     
106         UserPresetsFile = @"~/Library/Application Support/HandBrake/UserPresets.plist";
107     UserPresetsFile = [UserPresetsFile stringByExpandingTildeInPath];
108         
109         x264ProfilesFile = @"~/Library/Application Support/HandBrake/x264Profiles.plist";
110     x264ProfilesFile = [x264ProfilesFile stringByExpandingTildeInPath];
111         /* We check for the app support directory for media fork */
112         if ([fileManager fileExistsAtPath:AppSupportDirectory] == 0) 
113         {
114                 // If it doesnt exist yet, we create it here 
115                 [fileManager createDirectoryAtPath:AppSupportDirectory attributes:nil];
116         }
117         // We check for the presets.plist here
118         
119         if ([fileManager fileExistsAtPath:UserPresetsFile] == 0) 
120         {
121
122                 [fileManager createFileAtPath:UserPresetsFile contents:nil attributes:nil];
123                 
124         }
125         // We check for the x264profiles.plist here
126          
127         if ([fileManager fileExistsAtPath:x264ProfilesFile] == 0) 
128         {
129         
130                 [fileManager createFileAtPath:x264ProfilesFile contents:nil attributes:nil];
131         }
132     
133         
134   UserPresetsFile = @"~/Library/Application Support/HandBrake/UserPresets.plist";
135   UserPresetsFile = [[UserPresetsFile stringByExpandingTildeInPath]retain];
136
137   UserPresets = [[NSMutableArray alloc] initWithContentsOfFile:UserPresetsFile];
138   if (nil == UserPresets) 
139   {
140     UserPresets = [[NSMutableArray alloc] init];
141         [self AddFactoryPresets:NULL];
142   }
143   /* Show/Dont Show Presets drawer upon launch based
144   on user preference DefaultPresetsDrawerShow*/
145   if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultPresetsDrawerShow"] > 0)
146                 {
147           [fPresetDrawer open];
148                 }
149
150
151
152     /* Destination box*/
153     [fDstFormatPopUp removeAllItems];
154     [fDstFormatPopUp addItemWithTitle: _( @"MP4 file" )];
155     [fDstFormatPopUp addItemWithTitle: _( @"AVI file" )];
156     [fDstFormatPopUp addItemWithTitle: _( @"OGM file" )];
157     [fDstFormatPopUp selectItemAtIndex: 0];
158
159     [self FormatPopUpChanged: NULL];
160     /* We enable the create chapters checkbox here since we are .mp4 */ 
161         [fCreateChapterMarkers setEnabled: YES];
162         if ([fDstFormatPopUp indexOfSelectedItem] == 0 && [[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultChapterMarkers"] > 0)
163         {
164                 [fCreateChapterMarkers setState: NSOnState];
165         }
166     [fDstFile2Field setStringValue: [NSString stringWithFormat:
167         @"%@/Desktop/Movie.mp4", NSHomeDirectory()]];
168
169     /* Video encoder */
170     [fVidEncoderPopUp removeAllItems];
171     [fVidEncoderPopUp addItemWithTitle: @"FFmpeg"];
172     [fVidEncoderPopUp addItemWithTitle: @"XviD"];
173
174     /* Video quality */
175     [fVidTargetSizeField setIntValue: 700];
176         [fVidBitrateField    setIntValue: 1000];
177
178     [fVidQualityMatrix   selectCell: fVidBitrateCell];
179     [self VideoMatrixChanged: NULL];
180
181     /* Video framerate */
182     [fVidRatePopUp removeAllItems];
183         [fVidRatePopUp addItemWithTitle: _( @"Same as source" )];
184     for( int i = 0; i < hb_video_rates_count; i++ )
185     {
186         [fVidRatePopUp addItemWithTitle:
187             [NSString stringWithCString: hb_video_rates[i].string]];
188     }
189     [fVidRatePopUp selectItemAtIndex: 0];
190         
191         /* Picture Settings */
192         [fPicLabelPAROutp setStringValue: @""];
193         [fPicLabelPAROutputX setStringValue: @""];
194         [fPicSettingPARWidth setStringValue: @""];
195         [fPicSettingPARHeight setStringValue:  @""];
196         
197     /* Audio bitrate */
198     [fAudBitratePopUp removeAllItems];
199     for( int i = 0; i < hb_audio_bitrates_count; i++ )
200     {
201         [fAudBitratePopUp addItemWithTitle:
202             [NSString stringWithCString: hb_audio_bitrates[i].string]];
203     }
204     [fAudBitratePopUp selectItemAtIndex: hb_audio_bitrates_default];
205
206     /* Audio samplerate */
207     [fAudRatePopUp removeAllItems];
208     for( int i = 0; i < hb_audio_rates_count; i++ )
209     {
210         [fAudRatePopUp addItemWithTitle:
211             [NSString stringWithCString: hb_audio_rates[i].string]];
212     }
213     [fAudRatePopUp selectItemAtIndex: hb_audio_rates_default];
214
215     /* Bottom */
216     [fStatusField setStringValue: @""];
217
218     [self EnableUI: NO];
219     [fPauseButton setEnabled: NO];
220     [fRipButton setEnabled: NO];
221
222
223
224 }
225
226
227 - (void) TranslateStrings
228 {
229     [fSrcDVD1Field      setStringValue: _( @"DVD:" )];
230     [fSrcTitleField     setStringValue: _( @"Title:" )];
231     [fSrcChapterField   setStringValue: _( @"Chapters:" )];
232     [fSrcChapterToField setStringValue: _( @"to" )];
233     [fSrcDuration1Field setStringValue: _( @"Duration:" )];
234
235     [fDstFormatField    setStringValue: _( @"File format:" )];
236     [fDstCodecsField    setStringValue: _( @"Codecs:" )];
237     [fDstFile1Field     setStringValue: _( @"File:" )];
238     [fDstBrowseButton   setTitle:       _( @"Browse" )];
239
240     [fVidRateField      setStringValue: _( @"Framerate (fps):" )];
241     [fVidEncoderField   setStringValue: _( @"Encoder:" )];
242     [fVidQualityField   setStringValue: _( @"Quality:" )];
243 }
244
245 /***********************************************************************
246  * UpdateDockIcon
247  ***********************************************************************
248  * Shows a progression bar on the dock icon, filled according to
249  * 'progress' (0.0 <= progress <= 1.0).
250  * Called with progress < 0.0 or progress > 1.0, restores the original
251  * icon.
252  **********************************************************************/
253 - (void) UpdateDockIcon: (float) progress
254 {
255     NSImage * icon;
256     NSData * tiff;
257     NSBitmapImageRep * bmp;
258     uint32_t * pen;
259     uint32_t black = htonl( 0x000000FF );
260     uint32_t red   = htonl( 0xFF0000FF );
261     uint32_t white = htonl( 0xFFFFFFFF );
262     int row_start, row_end;
263     int i, j;
264
265     /* Get application original icon */
266     icon = [NSImage imageNamed: @"NSApplicationIcon"];
267
268     if( progress < 0.0 || progress > 1.0 )
269     {
270         [NSApp setApplicationIconImage: icon];
271         return;
272     }
273
274     /* Get it in a raw bitmap form */
275     tiff = [icon TIFFRepresentationUsingCompression:
276             NSTIFFCompressionNone factor: 1.0];
277     bmp = [NSBitmapImageRep imageRepWithData: tiff];
278     
279     /* Draw the progression bar */
280     /* It's pretty simple (ugly?) now, but I'm no designer */
281
282     row_start = 3 * (int) [bmp size].height / 4;
283     row_end   = 7 * (int) [bmp size].height / 8;
284
285     for( i = row_start; i < row_start + 2; i++ )
286     {
287         pen = (uint32_t *) ( [bmp bitmapData] + i * [bmp bytesPerRow] );
288         for( j = 0; j < (int) [bmp size].width; j++ )
289         {
290             pen[j] = black;
291         }
292     }
293     for( i = row_start + 2; i < row_end - 2; i++ )
294     {
295         pen = (uint32_t *) ( [bmp bitmapData] + i * [bmp bytesPerRow] );
296         pen[0] = black;
297         pen[1] = black;
298         for( j = 2; j < (int) [bmp size].width - 2; j++ )
299         {
300             if( j < 2 + (int) ( ( [bmp size].width - 4.0 ) * progress ) )
301             {
302                 pen[j] = red;
303             }
304             else
305             {
306                 pen[j] = white;
307             }
308         }
309         pen[j]   = black;
310         pen[j+1] = black;
311     }
312     for( i = row_end - 2; i < row_end; i++ )
313     {
314         pen = (uint32_t *) ( [bmp bitmapData] + i * [bmp bytesPerRow] );
315         for( j = 0; j < (int) [bmp size].width; j++ )
316         {
317             pen[j] = black;
318         }
319     }
320
321     /* Now update the dock icon */
322     tiff = [bmp TIFFRepresentationUsingCompression:
323             NSTIFFCompressionNone factor: 1.0];
324     icon = [[NSImage alloc] initWithData: tiff];
325     [NSApp setApplicationIconImage: icon];
326     [icon release];
327 }
328
329 - (void) UpdateUI: (NSTimer *) timer
330 {
331
332     hb_state_t s;
333     hb_get_state( fHandle, &s );
334
335     switch( s.state )
336     {
337         case HB_STATE_IDLE:
338             break;
339
340         case HB_STATE_SCANNING:
341             [fScanController UpdateUI: &s];
342             break;
343
344 #define p s.param.scandone
345         case HB_STATE_SCANDONE:
346         {
347             hb_list_t  * list;
348             hb_title_t * title;
349                         int indxpri=0;    // Used to search the longuest title (default in combobox)
350                         int longuestpri=0; // Used to search the longuest title (default in combobox)
351
352             [fScanController UpdateUI: &s];
353
354             list = hb_get_titles( fHandle );
355
356             if( !hb_list_count( list ) )
357             {
358                 break;
359             }
360
361
362             [fSrcTitlePopUp removeAllItems];
363             for( int i = 0; i < hb_list_count( list ); i++ )
364             {
365                 title = (hb_title_t *) hb_list_item( list, i );
366                 /*Set DVD Name at top of window*/
367                                 [fSrcDVD2Field setStringValue: [NSString
368                   stringWithUTF8String: title->name]];  
369                                 
370                                 /* Use the dvd name in the default output field here 
371                                 May want to add code to remove blank spaces for some dvd names*/
372                                 /* Check to see if the last destination has been set,use if so, if not, use Desktop */
373                                 if ([[NSUserDefaults standardUserDefaults] stringForKey:@"LastDestinationDirectory"])
374                                 {
375                                 [fDstFile2Field setStringValue: [NSString stringWithFormat:
376                 @"%@/%@.mp4", [[NSUserDefaults standardUserDefaults] stringForKey:@"LastDestinationDirectory"],[NSString
377                   stringWithUTF8String: title->name]]];
378                                 }
379                                 else
380                                 {
381                                 [fDstFile2Field setStringValue: [NSString stringWithFormat:
382                 @"%@/Desktop/%@.mp4", NSHomeDirectory(),[NSString
383                   stringWithUTF8String: title->name]]];
384                                 }
385
386                   
387                 if (longuestpri < title->hours*60*60 + title->minutes *60 + title->seconds)
388                 {
389                         longuestpri=title->hours*60*60 + title->minutes *60 + title->seconds;
390                         indxpri=i;
391                 }
392                 
393                                 
394                 int format = [fDstFormatPopUp indexOfSelectedItem];
395                                 char * ext = NULL;
396                                 switch( format )
397                 {
398                  case 0:
399                                          
400                                          /*Get Default MP4 File Extension for mpeg4 (.mp4 or .m4v) from prefs*/
401                                          if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultMpegName"] > 0)
402                                          {
403                                          ext = "m4v";
404                                          }
405                                      else
406                                      {
407                                          ext = "mp4";
408                                          }
409                                         break;
410                                 case 1: 
411                      ext = "avi";
412                                 case 2:
413                                    break;
414                      ext = "ogm";
415                                break;
416                                    }
417                                 
418                                 
419                                 NSString * string = [fDstFile2Field stringValue];
420                                 /* Add/replace File Output name to the correct extension*/
421                                 if( [string characterAtIndex: [string length] - 4] == '.' )
422                                 {
423                                         [fDstFile2Field setStringValue: [NSString stringWithFormat:
424                                                 @"%@.%s", [string substringToIndex: [string length] - 4],
425                                                 ext]];
426                                 }
427                                 else
428                                 {
429                                         [fDstFile2Field setStringValue: [NSString stringWithFormat:
430                                                 @"%@.%s", string, ext]];
431                                 }
432
433                                 
434                             [fSrcTitlePopUp addItemWithTitle: [NSString
435                     stringWithFormat: @"%d - %02dh%02dm%02ds",
436                     title->index, title->hours, title->minutes,
437                     title->seconds]];
438                         
439             }
440             // Select the longuest title
441                         [fSrcTitlePopUp selectItemAtIndex: indxpri];
442             /* We set the Settings Display to "Default" here
443                         until we get default presets implemented */
444                         [fPresetSelectedDisplay setStringValue: @"Default"];
445                         
446             [self TitlePopUpChanged: NULL];
447             [self EnableUI: YES];
448             [fPauseButton setEnabled: NO];
449             [fRipButton   setEnabled: YES];
450             break;
451         }
452 #undef p
453
454 #define p s.param.working
455         case HB_STATE_WORKING:
456         {
457             float progress_total;
458             NSMutableString * string;
459
460             /* Update text field */
461             string = [NSMutableString stringWithFormat:
462                 _( @"Encoding: task %d of %d, %.2f %%" ),
463                 p.job_cur, p.job_count, 100.0 * p.progress];
464             if( p.seconds > -1 )
465             {
466                 [string appendFormat:
467                     _( @" (%.2f fps, avg %.2f fps, ETA %02dh%02dm%02ds)" ),
468                     p.rate_cur, p.rate_avg, p.hours, p.minutes, p.seconds];
469             }
470             [fStatusField setStringValue: string];
471
472             /* Update slider */
473             progress_total = ( p.progress + p.job_cur - 1 ) / p.job_count;
474             [fRipIndicator setIndeterminate: NO];
475             [fRipIndicator setDoubleValue: 100.0 * progress_total];
476
477             /* Update dock icon */
478             [self UpdateDockIcon: progress_total];
479
480             [fPauseButton setEnabled: YES];
481             [fPauseButton setTitle: _( @"Pause" )];
482             [fRipButton setEnabled: YES];
483             [fRipButton setTitle: _( @"Cancel" )];
484             break;
485         }
486 #undef p
487
488 #define p s.param.muxing
489         case HB_STATE_MUXING:
490         {
491             NSMutableString * string;
492                         
493             /* Update text field */
494             string = [NSMutableString stringWithFormat:
495                 _( @"Muxing..." )];
496             [fStatusField setStringValue: string];
497                         
498             /* Update slider */
499             [fRipIndicator setIndeterminate: YES];
500             [fRipIndicator startAnimation: nil];
501                         
502             /* Update dock icon */
503             [self UpdateDockIcon: 1.0];
504                         
505             [fPauseButton setEnabled: YES];
506             [fPauseButton setTitle: _( @"Pause" )];
507             [fRipButton setEnabled: YES];
508             [fRipButton setTitle: _( @"Cancel" )];
509             break;
510         }
511 #undef p
512                         
513         case HB_STATE_PAUSED:
514                     [fStatusField setStringValue: _( @"Paused" )];
515             [fPauseButton setEnabled: YES];
516             [fPauseButton setTitle: _( @"Resume" )];
517             [fRipButton setEnabled: YES];
518             [fRipButton setTitle: _( @"Cancel" )];
519             break;
520
521         case HB_STATE_WORKDONE:
522         {
523             [self EnableUI: YES];
524             [fStatusField setStringValue: _( @"Done." )];
525             [fRipIndicator setIndeterminate: NO];
526             [fRipIndicator setDoubleValue: 0.0];
527             [fRipButton setTitle: _( @"Rip" )];
528
529             /* Restore dock icon */
530             [self UpdateDockIcon: -1.0];
531
532             [fPauseButton setEnabled: NO];
533             [fPauseButton setTitle: _( @"Pause" )];
534             [fRipButton setEnabled: YES];
535             [fRipButton setTitle: _( @"Rip" )];
536
537             /* FIXME */
538             hb_job_t * job;
539             while( ( job = hb_job( fHandle, 0 ) ) )
540             {
541                 hb_rem( fHandle, job );
542             }
543             break;
544         }
545     }
546
547     /* FIXME: we should only do that when necessary */
548     if( [fQueueCheck state] == NSOnState )
549     {
550         int count = hb_count( fHandle );
551         if( count )
552         {
553             [fQueueCheck setTitle: [NSString stringWithFormat:
554                 @"Enable queue (%d task%s in queue)",
555                 count, ( count > 1 ) ? "s" : ""]];
556         }
557         else
558         {
559             [fQueueCheck setTitle: @"Enable queue (no task in queue)"];
560         }
561     }
562
563     [[NSRunLoop currentRunLoop] addTimer: [NSTimer
564         scheduledTimerWithTimeInterval: 0.2 target: self
565         selector: @selector( UpdateUI: ) userInfo: NULL repeats: FALSE]
566         forMode: NSModalPanelRunLoopMode];
567 }
568
569 - (void) EnableUI: (bool) b
570 {
571     NSControl * controls[] =
572       { fSrcDVD1Field, fSrcDVD2Field, fSrcTitleField, fSrcTitlePopUp,
573         fSrcChapterField, fSrcChapterStartPopUp, fSrcChapterToField,
574         fSrcChapterEndPopUp, fSrcDuration1Field, fSrcDuration2Field,
575         fDstFormatField, fDstFormatPopUp, fDstCodecsField,
576         fDstCodecsPopUp, fDstFile1Field, fDstFile2Field,
577         fDstBrowseButton, fVidRateField, fVidRatePopUp,
578         fVidEncoderField, fVidEncoderPopUp, fVidQualityField,
579         fVidQualityMatrix, fVidGrayscaleCheck, fSubField, fSubPopUp,
580         fAudLang1Field, fAudLang1PopUp, fAudLang2Field, fAudLang2PopUp,
581         fAudTrack1MixLabel, fAudTrack1MixPopUp, fAudTrack2MixLabel, fAudTrack2MixPopUp,
582         fAudRateField, fAudRatePopUp, fAudBitrateField,
583         fAudBitratePopUp, fPictureButton, fQueueCheck, 
584                 fPicSrcWidth,fPicSrcHeight,fPicSettingWidth,fPicSettingHeight,
585                 fPicSettingARkeep,fPicSettingDeinterlace,fPicSettingARkeepDsply,
586                 fPicSettingDeinterlaceDsply,fPicLabelSettings,fPicLabelSrc,fPicLabelOutp,
587                 fPicLabelAr,fPicLabelDeinter,fPicLabelSrcX,fPicLabelOutputX,
588                 fPicLabelPAROutp,fPicLabelPAROutputX,fPicSettingPARWidth,fPicSettingPARHeight,
589                 fPicSettingPARDsply,fPicLabelAnamorphic,tableView,fPresetsAdd,fPresetsDelete,
590                 fCreateChapterMarkers,fPresetNewX264OptLabel};
591
592     for( unsigned i = 0;
593          i < sizeof( controls ) / sizeof( NSControl * ); i++ )
594     {
595         if( [[controls[i] className] isEqualToString: @"NSTextField"] )
596         {
597             NSTextField * tf = (NSTextField *) controls[i];
598             if( ![tf isBezeled] )
599             {
600                 [tf setTextColor: b ? [NSColor controlTextColor] :
601                     [NSColor disabledControlTextColor]];
602                 continue;
603             }
604         }
605         [controls[i] setEnabled: b];
606
607     }
608         
609         if (b) {
610
611         /* if we're enabling the interface, check if the audio mixdown controls need to be enabled or not */
612         /* these will have been enabled by the mass control enablement above anyway, so we're sense-checking it here */
613         [self SetEnabledStateOfAudioMixdownControls: NULL];
614         
615         } else {
616
617                 [tableView setEnabled: NO];
618         
619         }
620
621     [self VideoMatrixChanged: NULL];
622 }
623
624 - (IBAction) ShowScanPanel: (id) sender
625 {
626     [fScanController Show];
627 }
628
629 - (BOOL) windowShouldClose: (id) sender
630 {
631     /* Stop the application when the user closes the window */
632     [NSApp terminate: self];
633     return YES;
634 }
635
636 - (IBAction) VideoMatrixChanged: (id) sender;
637 {
638     bool target, bitrate, quality;
639
640     target = bitrate = quality = false;
641     if( [fVidQualityMatrix isEnabled] )
642     {
643         switch( [fVidQualityMatrix selectedRow] )
644         {
645             case 0:
646                 target = true;
647                 break;
648             case 1:
649                 bitrate = true;
650                 break;
651             case 2:
652                 quality = true;
653                 break;
654         }
655     }
656     [fVidTargetSizeField  setEnabled: target];
657     [fVidBitrateField     setEnabled: bitrate];
658     [fVidQualitySlider    setEnabled: quality];
659     [fVidTwoPassCheck     setEnabled: !quality &&
660         [fVidQualityMatrix isEnabled]];
661     if( quality )
662     {
663         [fVidTwoPassCheck setState: NSOffState];
664     }
665
666     [self QualitySliderChanged: sender];
667     [self CalculateBitrate:     sender];
668         [self CustomSettingUsed: sender];
669 }
670
671 - (IBAction) QualitySliderChanged: (id) sender
672 {
673     [fVidConstantCell setTitle: [NSString stringWithFormat:
674         _( @"Constant quality: %.0f %%" ), 100.0 *
675         [fVidQualitySlider floatValue]]];
676                 [self CustomSettingUsed: sender];
677 }
678
679 - (IBAction) BrowseFile: (id) sender
680 {
681     /* Open a panel to let the user choose and update the text field */
682     NSSavePanel * panel = [NSSavePanel savePanel];
683         /* We get the current file name and path from the destination field here */
684         [panel beginSheetForDirectory: [[fDstFile2Field stringValue] stringByDeletingLastPathComponent] file: [[fDstFile2Field stringValue] lastPathComponent]
685                                    modalForWindow: fWindow modalDelegate: self
686                                    didEndSelector: @selector( BrowseFileDone:returnCode:contextInfo: )
687                                           contextInfo: NULL];
688 }
689
690 - (void) BrowseFileDone: (NSSavePanel *) sheet
691     returnCode: (int) returnCode contextInfo: (void *) contextInfo
692 {
693     if( returnCode == NSOKButton )
694     {
695         [fDstFile2Field setStringValue: [sheet filename]];
696                 
697     }
698 }
699
700 - (IBAction) ShowPicturePanel: (id) sender
701 {
702     hb_list_t  * list  = hb_get_titles( fHandle );
703     hb_title_t * title = (hb_title_t *) hb_list_item( list,
704             [fSrcTitlePopUp indexOfSelectedItem] );
705
706     /* Resize the panel */
707     NSSize newSize;
708     newSize.width  = 246 + title->width;
709     newSize.height = 80 + title->height;
710     [fPicturePanel setContentSize: newSize];
711
712     [fPictureController SetTitle: title];
713
714     [NSApp beginSheet: fPicturePanel modalForWindow: fWindow
715         modalDelegate: NULL didEndSelector: NULL contextInfo: NULL];
716     [NSApp runModalForWindow: fPicturePanel];
717     [NSApp endSheet: fPicturePanel];
718     [fPicturePanel orderOut: self];
719         [self CalculatePictureSizing: sender];
720 }
721
722 - (IBAction) ShowQueuePanel: (id) sender
723 {
724     /* Update the OutlineView */
725     [fQueueController Update: sender];
726
727     /* Show the panel */
728     [NSApp beginSheet: fQueuePanel modalForWindow: fWindow
729         modalDelegate: NULL didEndSelector: NULL contextInfo: NULL];
730     [NSApp runModalForWindow: fQueuePanel];
731     [NSApp endSheet: fQueuePanel];
732     [fQueuePanel orderOut: self];
733 }
734
735 - (void) PrepareJob
736 {
737     hb_list_t  * list  = hb_get_titles( fHandle );
738     hb_title_t * title = (hb_title_t *) hb_list_item( list,
739             [fSrcTitlePopUp indexOfSelectedItem] );
740     hb_job_t * job = title->job;
741
742     /* Chapter selection */
743     job->chapter_start = [fSrcChapterStartPopUp indexOfSelectedItem] + 1;
744     job->chapter_end   = [fSrcChapterEndPopUp   indexOfSelectedItem] + 1;
745         
746
747
748     /* Format and codecs */
749     int format = [fDstFormatPopUp indexOfSelectedItem];
750     int codecs = [fDstCodecsPopUp indexOfSelectedItem];
751     job->mux    = FormatSettings[format][codecs] & HB_MUX_MASK;
752     job->vcodec = FormatSettings[format][codecs] & HB_VCODEC_MASK;
753     job->acodec = FormatSettings[format][codecs] & HB_ACODEC_MASK;
754     /* We set the chapter marker extraction here based on the format being
755         mpeg4 and the checkbox being checked */
756         if ([fDstFormatPopUp indexOfSelectedItem] == 0 && [fCreateChapterMarkers state] == NSOnState)
757         {
758         job->chapter_markers = 1;
759         }
760         else
761         {
762         job->chapter_markers = 0;
763         }
764     if( ( job->vcodec & HB_VCODEC_FFMPEG ) &&
765         [fVidEncoderPopUp indexOfSelectedItem] > 0 )
766     {
767         job->vcodec = HB_VCODEC_XVID;
768     }
769     if( job->vcodec & HB_VCODEC_X264 )
770     {
771          if ([fVidEncoderPopUp indexOfSelectedItem] > 0 )
772             {
773                 /* Just use new Baseline Level 3.0 
774                 Lets Deprecate Baseline Level 1.3*/
775                 job->h264_level = 30;
776                 job->mux = HB_MUX_IPOD;
777         /* move sanity check for iPod Encoding here */
778                 job->pixel_ratio = 0 ;
779
780                 }
781                 
782                 /* Set this flag to switch from Constant Quantizer(default) to Constant Rate Factor Thanks jbrjake
783                 Currently only used with Constant Quality setting*/
784                         if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultCrf"] > 0 && [fVidQualityMatrix selectedRow] == 2)
785                 {
786                 /* Can only be used with svn rev >= 89 */
787                         job->crf = 1;
788                 }
789                 
790                 /* Below Sends x264 options to the core library if x264 is selected*/
791                 /* First we look to see if a user preset has been selected that contains a x264 optional string CurUserPresetChosenNum = nil */
792                 if (curUserPresetChosenNum != nil)
793                 {
794                         /* Lets use this to see if the proper string is being passed in the gui. We can comment out if need be.
795                         for public use we have the field hidden in the nib */
796                         [fDisplayX264Options setStringValue: [NSString stringWithFormat:@"%@",[chosenPreset valueForKey:@"x264Option"]]];
797                         job->x264opts = [[chosenPreset valueForKey:@"x264Option"] cString];
798                 }
799                 else
800                 {
801                     /* if not, then we check to see if there is a x264 opt in the preferences and use that if we want */
802                         job->x264opts = [[[NSUserDefaults standardUserDefaults] stringForKey:@"DefAdvancedx264Flags"] UTF8String];
803                 } 
804                 
805                 
806                 
807         job->h264_13 = [fVidEncoderPopUp indexOfSelectedItem];
808     }
809
810     /* Video settings */
811     if( [fVidRatePopUp indexOfSelectedItem] > 0 )
812     {
813         job->vrate      = 27000000;
814         job->vrate_base = hb_video_rates[[fVidRatePopUp
815             indexOfSelectedItem]-1].rate;
816     }
817     else
818     {
819         job->vrate      = title->rate;
820         job->vrate_base = title->rate_base;
821     }
822
823     switch( [fVidQualityMatrix selectedRow] )
824     {
825         case 0:
826             /* Target size.
827                Bitrate should already have been calculated and displayed
828                in fVidBitrateField, so let's just use it */
829         case 1:
830             job->vquality = -1.0;
831             job->vbitrate = [fVidBitrateField intValue];
832             break;
833         case 2:
834             job->vquality = [fVidQualitySlider floatValue];
835             job->vbitrate = 0;
836             break;
837     }
838
839     job->grayscale = ( [fVidGrayscaleCheck state] == NSOnState );
840     
841
842
843     /* Subtitle settings */
844     job->subtitle = [fSubPopUp indexOfSelectedItem] - 1;
845
846     /* Audio tracks */
847     job->audios[0] = [fAudLang1PopUp indexOfSelectedItem] - 1;
848     job->audios[1] = [fAudLang2PopUp indexOfSelectedItem] - 1;
849     job->audios[2] = -1;
850
851     /* Audio settings */
852     job->arate = hb_audio_rates[[fAudRatePopUp
853                      indexOfSelectedItem]].rate;
854     job->abitrate = hb_audio_bitrates[[fAudBitratePopUp
855                         indexOfSelectedItem]].rate;
856
857     /* Audio mixdown(s) */
858     if (job->audios[0] > -1)
859     {
860         job->audio_mixdowns[0] = [[fAudTrack1MixPopUp selectedItem] tag];
861     }
862
863     if (job->audios[1] > -1)
864     {
865         job->audio_mixdowns[1] = [[fAudTrack2MixPopUp selectedItem] tag];
866     }
867
868 }
869
870 - (IBAction) EnableQueue: (id) sender
871 {
872     bool e = ( [fQueueCheck state] == NSOnState );
873     [fQueueAddButton  setHidden: !e];
874     [fQueueShowButton setHidden: !e];
875     [fRipButton       setTitle: e ? @"Start" : @"Rip"];
876 }
877
878 - (IBAction) AddToQueue: (id) sender
879 {
880 /* We get the destination directory from the destingation field here */
881         NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent];
882         /* We check for a valid destination here */
883         if ([[NSFileManager defaultManager] fileExistsAtPath:destinationDirectory] == 0) 
884         {
885                 NSRunAlertPanel(@"Warning!", @"This is not a valid destination directory!", @"OK", nil, nil);
886         }
887         else
888         {
889                 
890                 hb_list_t  * list  = hb_get_titles( fHandle );
891                 hb_title_t * title = (hb_title_t *) hb_list_item( list,
892                                                                                                                   [fSrcTitlePopUp indexOfSelectedItem] );
893                 hb_job_t * job = title->job;
894                 
895                 [self PrepareJob];
896                 
897                 /* Destination file */
898                 job->file = [[fDstFile2Field stringValue] UTF8String];
899                 
900                 if( [fVidTwoPassCheck state] == NSOnState )
901                 {
902                         job->pass = 1;
903                         hb_add( fHandle, job );
904                         job->pass = 2;
905                         job->x264opts = [[[NSUserDefaults standardUserDefaults] stringForKey:@"DefAdvancedx264Flags"] UTF8String];
906                         hb_add( fHandle, job );
907                 }
908                 else
909                 {
910                         job->pass = 0;
911                         hb_add( fHandle, job );
912                 }
913         
914         [[NSUserDefaults standardUserDefaults] setObject:destinationDirectory forKey:@"LastDestinationDirectory"];
915         }
916 }
917
918 - (IBAction) Rip: (id) sender
919 {
920    
921     
922     /* Rip or Cancel ? */
923     if( [[fRipButton title] isEqualToString: _( @"Cancel" )] )
924     {
925         [self Cancel: sender];
926         return;
927     }
928
929     if( [fQueueCheck state] == NSOffState )
930     {
931
932                         [self AddToQueue: sender];
933
934                 
935
936     }
937
938     /* We check for duplicate name here */
939         if( [[NSFileManager defaultManager] fileExistsAtPath:
940             [fDstFile2Field stringValue]] )
941     {
942         NSBeginCriticalAlertSheet( _( @"File already exists" ),
943             _( @"Cancel" ), _( @"Overwrite" ), NULL, fWindow, self,
944             @selector( OverwriteAlertDone:returnCode:contextInfo: ),
945             NULL, NULL, [NSString stringWithFormat:
946             _( @"Do you want to overwrite %@?" ),
947             [fDstFile2Field stringValue]] );
948         return;
949     }
950         /* We get the destination directory from the destination field here */
951         NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent];
952         /* We check for a valid destination here */
953         if ([[NSFileManager defaultManager] fileExistsAtPath:destinationDirectory] == 0) 
954         {
955                 NSRunAlertPanel(@"Warning!", @"This is not a valid destination directory!", @"OK", nil, nil);
956         }
957         else
958         {
959         [[NSUserDefaults standardUserDefaults] setObject:destinationDirectory forKey:@"LastDestinationDirectory"];
960                 [self _Rip];
961         }
962         
963
964
965 }
966
967 - (void) OverwriteAlertDone: (NSWindow *) sheet
968     returnCode: (int) returnCode contextInfo: (void *) contextInfo
969 {
970     if( returnCode == NSAlertAlternateReturn )
971     {
972         [self _Rip];
973     }
974 }
975
976 - (void) UpdateAlertDone: (NSWindow *) sheet
977     returnCode: (int) returnCode contextInfo: (void *) contextInfo
978 {
979     if( returnCode == NSAlertAlternateReturn )
980     {
981         /* Show scan panel */
982         [self performSelectorOnMainThread: @selector(ShowScanPanel:)
983             withObject: NULL waitUntilDone: NO];
984         return;
985     }
986
987     /* Go to HandBrake homepage and exit */
988     [self OpenHomepage: NULL];
989     [NSApp terminate: self];
990 }
991
992 - (void) _Rip
993 {
994     /* Let libhb do the job */
995     hb_start( fHandle );
996
997     /* Disable interface */
998    [self EnableUI: NO];
999     [fPauseButton setEnabled: NO];
1000     [fRipButton   setEnabled: NO];
1001 }
1002
1003 - (IBAction) Cancel: (id) sender
1004 {
1005     NSBeginCriticalAlertSheet( _( @"Cancel - Are you sure?" ),
1006         _( @"Keep working" ), _( @"Cancel encoding" ), NULL, fWindow, self,
1007         @selector( _Cancel:returnCode:contextInfo: ), NULL, NULL,
1008         _( @"Encoding won't be recoverable." ) );
1009 }
1010
1011 - (void) _Cancel: (NSWindow *) sheet
1012     returnCode: (int) returnCode contextInfo: (void *) contextInfo
1013 {
1014     if( returnCode == NSAlertAlternateReturn )
1015     {
1016         hb_stop( fHandle );
1017         [fPauseButton setEnabled: NO];
1018         [fRipButton   setEnabled: NO];
1019     }
1020 }
1021
1022 - (IBAction) Pause: (id) sender
1023 {
1024     [fPauseButton setEnabled: NO];
1025     [fRipButton   setEnabled: NO];
1026
1027     if( [[fPauseButton title] isEqualToString: _( @"Resume" )] )
1028     {
1029         hb_resume( fHandle );
1030     }
1031     else
1032     {
1033         hb_pause( fHandle );
1034     }
1035 }
1036
1037 - (IBAction) TitlePopUpChanged: (id) sender
1038 {
1039     hb_list_t  * list  = hb_get_titles( fHandle );
1040     hb_title_t * title = (hb_title_t*)
1041         hb_list_item( list, [fSrcTitlePopUp indexOfSelectedItem] );
1042                 
1043                 
1044     /* If Auto Naming is on. We create an output filename of dvd name - title number */
1045     if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultAutoNaming"] > 0)
1046         {
1047                 [fDstFile2Field setStringValue: [NSString stringWithFormat:
1048                         @"%@/%@-%d.%@", [[fDstFile2Field stringValue] stringByDeletingLastPathComponent],
1049                         [NSString stringWithUTF8String: title->name],
1050                         [fSrcTitlePopUp indexOfSelectedItem] + 1,
1051                         [[fDstFile2Field stringValue] pathExtension]]]; 
1052         }
1053
1054     /* Update chapter popups */
1055     [fSrcChapterStartPopUp removeAllItems];
1056     [fSrcChapterEndPopUp   removeAllItems];
1057     for( int i = 0; i < hb_list_count( title->list_chapter ); i++ )
1058     {
1059         [fSrcChapterStartPopUp addItemWithTitle: [NSString
1060             stringWithFormat: @"%d", i + 1]];
1061         [fSrcChapterEndPopUp addItemWithTitle: [NSString
1062             stringWithFormat: @"%d", i + 1]];
1063     }
1064     [fSrcChapterStartPopUp selectItemAtIndex: 0];
1065     [fSrcChapterEndPopUp   selectItemAtIndex:
1066         hb_list_count( title->list_chapter ) - 1];
1067     [self ChapterPopUpChanged: NULL];
1068
1069 /* Start Get and set the initial pic size for display */
1070         hb_job_t * job = title->job;
1071         fTitle = title; 
1072         /*Set Source Size Fields Here */
1073         [fPicSrcWidth setStringValue: [NSString stringWithFormat:
1074                                                          @"%d", fTitle->width]];
1075         [fPicSrcHeight setStringValue: [NSString stringWithFormat:
1076                                                          @"%d", fTitle->height]];
1077         /* We get the originial output picture width and height and put them
1078         in variables for use with some presets later on */
1079         PicOrigOutputWidth = job->width;
1080         PicOrigOutputHeight = job->height;
1081         /* we test getting the max output value for pic sizing here to be used later*/
1082         [fPicSettingWidth setStringValue: [NSString stringWithFormat:
1083                 @"%d", PicOrigOutputWidth]];
1084         [fPicSettingHeight setStringValue: [NSString stringWithFormat:
1085                 @"%d", PicOrigOutputHeight]];
1086         /* Turn Deinterlace on/off depending on the preference */
1087         if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultDeinterlaceOn"] > 0)
1088         {
1089                 job->deinterlace = 1;
1090         }
1091         else
1092         {
1093                 job->deinterlace = 0;
1094         }
1095         
1096         /* Pixel Ratio Setting */
1097         if ([[NSUserDefaults standardUserDefaults] boolForKey:@"PixelRatio"])
1098     {
1099
1100                 job->pixel_ratio = 1 ;
1101         }
1102         else
1103         {
1104                 job->pixel_ratio = 0 ;
1105         }
1106         /* Run Through EncoderPopUpChanged to see if there
1107                 needs to be any pic value modifications based on encoder settings */
1108         //[self EncoderPopUpChanged: NULL];
1109         /* END Get and set the initial pic size for display */ 
1110
1111
1112     /* Update subtitle popups */
1113     hb_subtitle_t * subtitle;
1114     [fSubPopUp removeAllItems];
1115     [fSubPopUp addItemWithTitle: @"None"];
1116     for( int i = 0; i < hb_list_count( title->list_subtitle ); i++ )
1117     {
1118         subtitle = (hb_subtitle_t *) hb_list_item( title->list_subtitle, i );
1119
1120         /* We cannot use NSPopUpButton's addItemWithTitle because
1121            it checks for duplicate entries */
1122         [[fSubPopUp menu] addItemWithTitle: [NSString stringWithCString:
1123             subtitle->lang] action: NULL keyEquivalent: @""];
1124     }
1125     [fSubPopUp selectItemAtIndex: 0];
1126
1127     /* START pri */
1128         hb_audio_t * audio;
1129
1130         // PRI CHANGES 02/12/06
1131         NSString * audiotmppri;
1132         NSString * audiosearchpri=[[NSUserDefaults standardUserDefaults] stringForKey:@"DefaultLanguage"];
1133         int indxpri=0;
1134         // End of pri changes 02/12/06
1135     [fAudLang1PopUp removeAllItems];
1136         [fAudLang2PopUp removeAllItems];
1137     [fAudLang1PopUp addItemWithTitle: _( @"None" )];
1138         [fAudLang2PopUp addItemWithTitle: _( @"None" )];
1139     for( int i = 0; i < hb_list_count( title->list_audio ); i++ )
1140     {
1141         audio = (hb_audio_t *) hb_list_item( title->list_audio, i );
1142         // PRI CHANGES 02/12/06
1143                 if (audiosearchpri!= NULL) 
1144                 {
1145                         audiotmppri=(NSString *) [NSString stringWithCString: audio->lang];
1146                         // Try to find the desired default language
1147                         if ([audiotmppri hasPrefix:audiosearchpri] && indxpri==0)
1148                         {
1149                                 indxpri=i+1;
1150                         }
1151                 }
1152         // End of pri changes 02/12/06
1153
1154         [[fAudLang1PopUp menu] addItemWithTitle:
1155             [NSString stringWithCString: audio->lang]
1156             action: NULL keyEquivalent: @""];
1157        
1158            [[fAudLang2PopUp menu] addItemWithTitle:
1159             [NSString stringWithCString: audio->lang]
1160             action: NULL keyEquivalent: @""];
1161                 
1162     }
1163         // PRI CHANGES 02/12/06
1164         if (indxpri==0) { indxpri=1; }
1165           [fAudLang1PopUp selectItemAtIndex: indxpri];
1166         // End of pri changes 02/12/06
1167     [fAudLang2PopUp selectItemAtIndex: 0];
1168         
1169         /* END pri */
1170
1171         /* changing the title may have changed the audio channels on offer, */
1172         /* so call AudioTrackPopUpChanged for both audio tracks to update the mixdown popups */
1173         [self AudioTrackPopUpChanged: fAudLang1PopUp mixdownToUse: 0];
1174         [self AudioTrackPopUpChanged: fAudLang2PopUp mixdownToUse: 0];
1175
1176 }
1177
1178 - (IBAction) ChapterPopUpChanged: (id) sender
1179 {
1180     hb_list_t  * list  = hb_get_titles( fHandle );
1181     hb_title_t * title = (hb_title_t *)
1182         hb_list_item( list, [fSrcTitlePopUp indexOfSelectedItem] );
1183
1184     hb_chapter_t * chapter;
1185     int64_t        duration = 0;
1186     for( int i = [fSrcChapterStartPopUp indexOfSelectedItem];
1187          i <= [fSrcChapterEndPopUp indexOfSelectedItem]; i++ )
1188     {
1189         chapter = (hb_chapter_t *) hb_list_item( title->list_chapter, i );
1190         duration += chapter->duration;
1191     }
1192     
1193     duration /= 90000; /* pts -> seconds */
1194     [fSrcDuration2Field setStringValue: [NSString stringWithFormat:
1195         @"%02lld:%02lld:%02lld", duration / 3600, ( duration / 60 ) % 60,
1196         duration % 60]];
1197
1198     [self CalculateBitrate: sender];
1199 }
1200
1201 - (IBAction) FormatPopUpChanged: (id) sender
1202 {
1203     NSString * string = [fDstFile2Field stringValue];
1204     int format = [fDstFormatPopUp indexOfSelectedItem];
1205     char * ext = NULL;
1206
1207     /* Update the codecs popup */
1208     [fDstCodecsPopUp removeAllItems];
1209     switch( format )
1210     {
1211         case 0:
1212                                 /*Get Default MP4 File Extension*/
1213                                 if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultMpegName"] > 0)
1214                                 {
1215                                 ext = "m4v";
1216                                 }
1217                                 else
1218                                 {
1219                                 ext = "mp4";
1220                                 }
1221             [fDstCodecsPopUp addItemWithTitle:
1222                 _( @"MPEG-4 Video / AAC Audio" )];
1223             [fDstCodecsPopUp addItemWithTitle:
1224                 _( @"AVC/H.264 Video / AAC Audio" )];
1225                         /* We enable the create chapters checkbox here since we are .mp4*/
1226                         [fCreateChapterMarkers setEnabled: YES];
1227                         break;
1228         case 1: 
1229             ext = "avi";
1230             [fDstCodecsPopUp addItemWithTitle:
1231                 _( @"MPEG-4 Video / MP3 Audio" )];
1232             [fDstCodecsPopUp addItemWithTitle:
1233                 _( @"MPEG-4 Video / AC-3 Audio" )];
1234             [fDstCodecsPopUp addItemWithTitle:
1235                 _( @"AVC/H.264 Video / MP3 Audio" )];
1236             [fDstCodecsPopUp addItemWithTitle:
1237                 _( @"AVC/H.264 Video / AC-3 Audio" )];
1238                         /* We disable the create chapters checkbox here since we are NOT .mp4 
1239                         and make sure it is unchecked*/
1240                         [fCreateChapterMarkers setEnabled: NO];
1241                         [fCreateChapterMarkers setState: NSOffState];
1242             break;
1243         case 2:
1244             ext = "ogm";
1245             [fDstCodecsPopUp addItemWithTitle:
1246                 _( @"MPEG-4 Video / Vorbis Audio" )];
1247             [fDstCodecsPopUp addItemWithTitle:
1248                 _( @"MPEG-4 Video / MP3 Audio" )];
1249             /* We disable the create chapters checkbox here since we are NOT .mp4 
1250                         and make sure it is unchecked*/
1251                         [fCreateChapterMarkers setEnabled: NO];
1252                         [fCreateChapterMarkers setState: NSOffState];
1253                         break;
1254     }
1255     [self CodecsPopUpChanged: NULL];
1256
1257     /* Add/replace to the correct extension */
1258     if( [string characterAtIndex: [string length] - 4] == '.' )
1259     {
1260         [fDstFile2Field setStringValue: [NSString stringWithFormat:
1261             @"%@.%s", [string substringToIndex: [string length] - 4],
1262             ext]];
1263     }
1264     else
1265     {
1266         [fDstFile2Field setStringValue: [NSString stringWithFormat:
1267             @"%@.%s", string, ext]];
1268     }
1269
1270         /* changing the format may mean that we can / can't offer mono or 6ch, */
1271         /* so call AudioTrackPopUpChanged for both audio tracks to update the mixdown popups */
1272         [self AudioTrackPopUpChanged: fAudLang1PopUp mixdownToUse: 0];
1273         [self AudioTrackPopUpChanged: fAudLang2PopUp mixdownToUse: 0];
1274
1275         /* We call method method to change UI to reflect whether a preset is used or not*/
1276         [self CustomSettingUsed: sender];       
1277         
1278 }
1279
1280 - (IBAction) CodecsPopUpChanged: (id) sender
1281 {
1282     int format = [fDstFormatPopUp indexOfSelectedItem];
1283     int codecs = [fDstCodecsPopUp indexOfSelectedItem];
1284
1285     /* Update the encoder popup */
1286     if( ( FormatSettings[format][codecs] & HB_VCODEC_X264 ) )
1287     {
1288         /* MPEG-4 -> H.264 */
1289         [fVidEncoderPopUp removeAllItems];
1290                 [fVidEncoderPopUp addItemWithTitle: @"x264 (h.264 Main)"];
1291                 [fVidEncoderPopUp addItemWithTitle: @"x264 (h.264 iPod)"];
1292         
1293         
1294     }
1295     else if( ( FormatSettings[format][codecs] & HB_VCODEC_FFMPEG ) )
1296     {
1297         /* H.264 -> MPEG-4 */
1298         [fVidEncoderPopUp removeAllItems];
1299         [fVidEncoderPopUp addItemWithTitle: @"FFmpeg"];
1300         [fVidEncoderPopUp addItemWithTitle: @"XviD"];
1301         [fVidEncoderPopUp selectItemAtIndex: 0];
1302     }
1303
1304     if( FormatSettings[format][codecs] & HB_ACODEC_AC3 )
1305     {
1306         /* AC-3 pass-through: disable samplerate and bitrate */
1307         [fAudRatePopUp    setEnabled: NO];
1308         [fAudBitratePopUp setEnabled: NO];
1309     }
1310     else
1311     {
1312         [fAudRatePopUp    setEnabled: YES];
1313         [fAudBitratePopUp setEnabled: YES];
1314     }
1315
1316         /* changing the codecs on offer may mean that we can / can't offer mono or 6ch, */
1317         /* so call AudioTrackPopUpChanged for both audio tracks to update the mixdown popups */
1318         [self AudioTrackPopUpChanged: fAudLang1PopUp mixdownToUse: 0];
1319         [self AudioTrackPopUpChanged: fAudLang2PopUp mixdownToUse: 0];
1320
1321     [self CalculateBitrate: sender];
1322     /* We call method method to change UI to reflect whether a preset is used or not*/
1323         [self CustomSettingUsed: sender];
1324 }
1325
1326 - (IBAction) EncoderPopUpChanged: (id) sender
1327 {
1328     
1329         /* Check to see if we need to modify the job pic values based on x264 (iPod) encoder selection */
1330     if ([fDstFormatPopUp indexOfSelectedItem] == 0 && [fDstCodecsPopUp indexOfSelectedItem] == 1 && [fVidEncoderPopUp indexOfSelectedItem] == 1)
1331     {
1332         hb_job_t * job = fTitle->job;
1333         job->pixel_ratio = 0 ;
1334         
1335                  if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultPicSizeAutoiPod"] > 0)
1336                  {
1337                  
1338                  if (job->width > 640)
1339                                 {
1340                                 job->width = 640;
1341                                 }
1342                  job->keep_ratio = 1;
1343                  hb_fix_aspect( job, HB_KEEP_WIDTH );
1344                  
1345                  }
1346
1347                 /* uncheck the "export 5.1 as 6-channel AAC" checkbox if it is checked */
1348 //              [fAudLang1SurroundCheck setState: NSOffState];
1349
1350         }
1351     
1352         [self CalculatePictureSizing: sender];
1353         /* We call method method to change UI to reflect whether a preset is used or not*/    
1354     [self CustomSettingUsed: sender];
1355 }
1356
1357 - (IBAction) SetEnabledStateOfAudioMixdownControls: (id) sender
1358 {
1359
1360     /* enable/disable the mixdown text and popupbutton for audio track 1 */
1361     [fAudTrack1MixPopUp setEnabled: ([fAudLang1PopUp indexOfSelectedItem] == 0) ? NO : YES];
1362     [fAudTrack1MixLabel setTextColor: ([fAudLang1PopUp indexOfSelectedItem] == 0) ?
1363         [NSColor disabledControlTextColor] : [NSColor controlTextColor]];
1364
1365     /* enable/disable the mixdown text and popupbutton for audio track 2 */
1366     [fAudTrack2MixPopUp setEnabled: ([fAudLang2PopUp indexOfSelectedItem] == 0) ? NO : YES];
1367     [fAudTrack2MixLabel setTextColor: ([fAudLang2PopUp indexOfSelectedItem] == 0) ?
1368         [NSColor disabledControlTextColor] : [NSColor controlTextColor]];
1369
1370 }
1371
1372 - (IBAction) AudioTrackPopUpChanged: (id) sender
1373 {
1374     [self AudioTrackPopUpChanged: sender mixdownToUse: 0];
1375 }
1376
1377 - (IBAction) AudioTrackPopUpChanged: (id) sender mixdownToUse: (int) mixdownToUse
1378 {
1379
1380     /* make sure we have a selected title before continuing */
1381     if (fTitle == NULL) return;
1382
1383     /* find out if audio track 1 or 2 was changed - this is passed to us in the tag of the sender */
1384     /* the sender will have been either fAudLang1PopUp (tag = 0) or fAudLang2PopUp (tag = 1) */
1385     int thisAudio = [sender tag];
1386
1387     /* get the index of the selected audio */
1388     int thisAudioIndex = [sender indexOfSelectedItem] - 1;;
1389
1390     /* pointer for the hb_audio_s struct we will use later on */
1391     hb_audio_t * audio;
1392
1393     /* find out what the currently-selected output audio codec is */
1394     int format = [fDstFormatPopUp indexOfSelectedItem];
1395     int codecs = [fDstCodecsPopUp indexOfSelectedItem];
1396     int acodec = FormatSettings[format][codecs] & HB_ACODEC_MASK;
1397
1398     /* pointer to this track's mixdown NSPopUpButton */
1399     NSTextField   * mixdownTextField;
1400     NSPopUpButton * mixdownPopUp;
1401
1402     /* find our mixdown NSTextField and NSPopUpButton */
1403     if (thisAudio == 0)
1404     {
1405         mixdownTextField = fAudTrack1MixLabel;
1406         mixdownPopUp = fAudTrack1MixPopUp;
1407     }
1408     else
1409     {
1410         mixdownTextField = fAudTrack2MixLabel;
1411         mixdownPopUp = fAudTrack2MixPopUp;
1412     }
1413
1414     /* delete the previous audio mixdown options */
1415     [mixdownPopUp removeAllItems];
1416
1417     /* check if the audio mixdown controls need their enabled state changing */
1418     [self SetEnabledStateOfAudioMixdownControls: NULL];
1419
1420     if (thisAudioIndex != -1)
1421     {
1422
1423         /* get the audio */
1424         audio = (hb_audio_t *) hb_list_item( fTitle->list_audio, thisAudioIndex );
1425         if (audio != NULL)
1426         {
1427
1428             int audioCodecsSupportMono = (audio->codec == HB_ACODEC_AC3 && acodec == HB_ACODEC_FAAC);
1429             int audioCodecsSupport6Ch = (audio->codec == HB_ACODEC_AC3 && acodec == HB_ACODEC_FAAC);
1430
1431             /* check for AC-3 passthru */
1432             if (audio->codec == HB_ACODEC_AC3 && acodec == HB_ACODEC_AC3)
1433             {
1434                     [[mixdownPopUp menu] addItemWithTitle:
1435                         [NSString stringWithCString: "AC3 Passthru"]
1436                         action: NULL keyEquivalent: @""];
1437             }
1438             else
1439             {
1440             
1441                 /* find out if our selected output audio codec supports mono and / or 6ch */
1442                 /* we also check for an input codec of AC3,
1443                    as it is the only library able to do the mixdown to mono / conversion to 6-ch */
1444                 /* audioCodecsSupportMono and audioCodecsSupport6Ch are the same for now,
1445                    but this may change in the future, so they are separated for flexibility */
1446
1447                 /* find out the audio channel layout for our input audio */
1448                 /* we'll cheat and use the liba52 layouts, even if the source isn't AC3 */
1449                 int channel_layout;
1450                 int audio_has_lfe;
1451                 if (audio->codec == HB_ACODEC_AC3)
1452                 {
1453                     channel_layout = (audio->ac3flags & A52_CHANNEL_MASK);
1454                     audio_has_lfe = (audio->ac3flags & A52_LFE);
1455                 }
1456                 else
1457                 {
1458                     /* assume a stereo input for all other input codecs */
1459                     channel_layout = A52_STEREO;
1460                     audio_has_lfe = 0;
1461                 }
1462
1463                 /* add the appropriate audio mixdown menuitems to the popupbutton */
1464                 /* in each case, we set the new menuitem's tag to be the amixdown value for that mixdown,
1465                    so that we can reference the mixdown later */
1466
1467                 /* keep a track of the min and max mixdowns we used, so we can select the best match later */
1468                 int minMixdownUsed = 0;
1469                 int maxMixdownUsed = 0;
1470
1471                 /* do we want to add a mono option? */
1472                 if (audioCodecsSupportMono == 1) {
1473                     id<NSMenuItem> menuItem = [[mixdownPopUp menu] addItemWithTitle:
1474                         [NSString stringWithCString: hb_audio_mixdowns[0].human_readable_name]
1475                         action: NULL keyEquivalent: @""];
1476                     [menuItem setTag: hb_audio_mixdowns[0].amixdown];
1477                     if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[0].amixdown;
1478                     maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[0].amixdown);
1479                 }
1480
1481                 /* do we want to add a stereo option? */
1482                 if (channel_layout >= A52_STEREO && channel_layout != A52_CHANNEL1 && channel_layout != A52_CHANNEL2) {
1483                     id<NSMenuItem> menuItem = [[mixdownPopUp menu] addItemWithTitle:
1484                         [NSString stringWithCString: hb_audio_mixdowns[1].human_readable_name]
1485                         action: NULL keyEquivalent: @""];
1486                     [menuItem setTag: hb_audio_mixdowns[1].amixdown];
1487                     if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[1].amixdown;
1488                     maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[1].amixdown);
1489                 }
1490
1491                 /* do we want to add a dolby surround (DPL1) option? */
1492                 if (channel_layout == A52_3F1R || channel_layout == A52_3F2R || channel_layout == A52_DOLBY) {
1493                     id<NSMenuItem> menuItem = [[mixdownPopUp menu] addItemWithTitle:
1494                         [NSString stringWithCString: hb_audio_mixdowns[2].human_readable_name]
1495                         action: NULL keyEquivalent: @""];
1496                     [menuItem setTag: hb_audio_mixdowns[2].amixdown];
1497                     if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[2].amixdown;
1498                     maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[2].amixdown);
1499                 }
1500
1501                 /* do we want to add a dolby pro logic 2 (DPL2) option? */
1502                 if (channel_layout == A52_3F2R) {
1503                     id<NSMenuItem> menuItem = [[mixdownPopUp menu] addItemWithTitle:
1504                         [NSString stringWithCString: hb_audio_mixdowns[3].human_readable_name]
1505                         action: NULL keyEquivalent: @""];
1506                     [menuItem setTag: hb_audio_mixdowns[3].amixdown];
1507                     if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[3].amixdown;
1508                     maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[3].amixdown);
1509                 }
1510
1511                 /* do we want to add a 6-channel discrete option? */
1512                 if (audioCodecsSupport6Ch == 1 && channel_layout == A52_3F2R && audio_has_lfe == A52_LFE) {
1513                     id<NSMenuItem> menuItem = [[mixdownPopUp menu] addItemWithTitle:
1514                         [NSString stringWithCString: hb_audio_mixdowns[4].human_readable_name]
1515                         action: NULL keyEquivalent: @""];
1516                     [menuItem setTag: hb_audio_mixdowns[4].amixdown];
1517                     if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[4].amixdown;
1518                     maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[4].amixdown);
1519                 }
1520
1521                 /* auto-select the best mixdown based on our saved mixdown preference */
1522                 
1523                 /* for now, this is hard-coded to a "best" mixdown of HB_AMIXDOWN_DOLBYPLII */
1524                 /* ultimately this should be a prefs option */
1525                 int useMixdown;
1526                 
1527                 /* if we passed in a mixdown to use - in order to load a preset - then try and use it */
1528                 if (mixdownToUse > 0)
1529                 {
1530                     useMixdown = mixdownToUse;
1531                 }
1532                 else
1533                 {
1534                     useMixdown = HB_AMIXDOWN_DOLBYPLII;
1535                 }
1536                 
1537                 /* if useMixdown > maxMixdownUsed, then use maxMixdownUsed */
1538                 if (useMixdown > maxMixdownUsed) useMixdown = maxMixdownUsed;
1539
1540                 /* if useMixdown < minMixdownUsed, then use minMixdownUsed */
1541                 if (useMixdown < minMixdownUsed) useMixdown = minMixdownUsed;
1542
1543                 /* select the (possibly-amended) preferred mixdown */
1544                 [mixdownPopUp selectItemWithTag: useMixdown];
1545             
1546             }
1547
1548         }
1549         
1550     }
1551
1552         /* see if the new audio track choice will change the bitrate we need */
1553     [self CalculateBitrate: sender];    
1554
1555 }
1556
1557 /* lets set the picture size back to the max from right after title scan
1558    Lets use an IBAction here as down the road we could always use a checkbox
1559    in the gui to easily take the user back to max. Remember, the compiler
1560    resolves IBActions down to -(void) during compile anyway */
1561 - (IBAction) RevertPictureSizeToMax: (id) sender
1562 {
1563          hb_job_t * job = fTitle->job;
1564         /* We use the output picture width and height
1565         as calculated from libhb right after title is set
1566         in TitlePopUpChanged */
1567         job->width = PicOrigOutputWidth;
1568         job->height = PicOrigOutputHeight;
1569
1570
1571     
1572         [self CalculatePictureSizing: sender];
1573         /* We call method method to change UI to reflect whether a preset is used or not*/    
1574     [self CustomSettingUsed: sender];
1575 }
1576
1577
1578 /* Get and Display Current Pic Settings in main window */
1579 - (IBAction) CalculatePictureSizing: (id) sender
1580 {
1581
1582         //hb_job_t * job = fTitle->job;         
1583
1584         [fPicSettingWidth setStringValue: [NSString stringWithFormat:
1585                 @"%d", fTitle->job->width]];
1586         [fPicSettingHeight setStringValue: [NSString stringWithFormat:
1587                 @"%d", fTitle->job->height]];
1588         [fPicSettingARkeep setStringValue: [NSString stringWithFormat:
1589                 @"%d", fTitle->job->keep_ratio]];                
1590         [fPicSettingDeinterlace setStringValue: [NSString stringWithFormat:
1591                 @"%d", fTitle->job->deinterlace]];
1592         [fPicSettingPAR setStringValue: [NSString stringWithFormat:
1593                 @"%d", fTitle->job->pixel_ratio]];
1594                 
1595         if (fTitle->job->pixel_ratio == 1)
1596         {
1597         int titlewidth = fTitle->width-fTitle->job->crop[2]-fTitle->job->crop[3];
1598         int arpwidth = fTitle->job->pixel_aspect_width;
1599         int arpheight = fTitle->job->pixel_aspect_height;
1600         int displayparwidth = titlewidth * arpwidth / arpheight;
1601         int displayparheight = fTitle->height-fTitle->job->crop[0]-fTitle->job->crop[1];
1602         [fPicLabelPAROutp setStringValue: @"Anamorphic Output:"];
1603         [fPicLabelPAROutputX setStringValue: @"x"];
1604     [fPicSettingPARWidth setStringValue: [NSString stringWithFormat:
1605         @"%d", displayparwidth]];
1606         [fPicSettingPARHeight setStringValue: [NSString stringWithFormat:
1607         @"%d", displayparheight]];
1608
1609         fTitle->job->keep_ratio = 0;
1610         }
1611         else
1612         {
1613         [fPicLabelPAROutp setStringValue: @""];
1614         [fPicLabelPAROutputX setStringValue: @""];
1615         [fPicSettingPARWidth setStringValue: @""];
1616         [fPicSettingPARHeight setStringValue:  @""];
1617         }
1618                 
1619         /* Set ON/Off values for the deinterlace/keep aspect ratio according to boolean */      
1620         if (fTitle->job->keep_ratio > 0)
1621                 {
1622                 [fPicSettingARkeepDsply setStringValue: @"On"];
1623         }
1624                 else
1625                 {
1626                 [fPicSettingARkeepDsply setStringValue: @"Off"];
1627                 }       
1628         if (fTitle->job->deinterlace > 0)
1629                 {
1630                 [fPicSettingDeinterlaceDsply setStringValue: @"On"];
1631         }
1632                 else
1633                 {
1634                 [fPicSettingDeinterlaceDsply setStringValue: @"Off"];
1635                 }
1636         if (fTitle->job->pixel_ratio > 0)
1637                 {
1638                 [fPicSettingPARDsply setStringValue: @"On"];
1639         }
1640                 else
1641                 {
1642                 [fPicSettingPARDsply setStringValue: @"Off"];
1643                 }       
1644                 
1645         [self CustomSettingUsed: sender];
1646 }
1647
1648 - (IBAction) CalculateBitrate: (id) sender
1649 {
1650     if( !fHandle || [fVidQualityMatrix selectedRow] != 0 )
1651     {
1652         return;
1653     }
1654
1655     hb_list_t  * list  = hb_get_titles( fHandle );
1656     hb_title_t * title = (hb_title_t *) hb_list_item( list,
1657             [fSrcTitlePopUp indexOfSelectedItem] );
1658     hb_job_t * job = title->job;
1659
1660     [self PrepareJob];
1661
1662     [fVidBitrateField setIntValue: hb_calc_bitrate( job,
1663             [fVidTargetSizeField intValue] )];
1664                         
1665                         
1666 }
1667
1668 /* Method to determine if we should change the UI
1669 To reflect whether or not a Preset is being used or if
1670 the user is using "Custom" settings by determining the sender*/
1671 - (IBAction) CustomSettingUsed: (id) sender
1672 {
1673         if ([sender stringValue] != NULL)
1674         {
1675                 /* Deselect the currently selected Preset if there is one*/
1676                 [tableView deselectRow:[tableView selectedRow]];
1677                 /* Change UI to show "Custom" settings are being used */
1678                 [fPresetSelectedDisplay setStringValue: @"Custom"];
1679                 /* Empty the field to display custom x264 preset options*/
1680                 [fDisplayX264Options setStringValue: @""];
1681                 curUserPresetChosenNum = nil;
1682                 
1683         }
1684 }
1685
1686
1687 - (IBAction) ShowAddPresetPanel: (id) sender
1688 {
1689     /* If we have MP4, AVC H.264 and x264 Main then we enable the x264 Options field for the
1690          Add Preset window we are about to open. We do this before we actually open the panel,
1691          as doing it after causes it to stick from the last selection for some reason. */
1692         if ([fDstFormatPopUp indexOfSelectedItem] == 0 && [fDstCodecsPopUp indexOfSelectedItem] == 1)
1693         {
1694                 [fPresetNewX264Opt setEditable: YES];
1695                 [fPresetNewX264OptLabel setEnabled: YES];
1696         }
1697         else
1698         {
1699                 [fPresetNewX264Opt setEditable: NO];
1700                 [fPresetNewX264OptLabel setEnabled: NO];
1701         }
1702         
1703         /* Show the panel */
1704         [NSApp beginSheet: fAddPresetPanel modalForWindow: fWindow
1705         modalDelegate: NULL didEndSelector: NULL contextInfo: NULL];
1706     [NSApp runModalForWindow: fAddPresetPanel];
1707     [NSApp endSheet: fAddPresetPanel];
1708     [fAddPresetPanel orderOut: self];
1709         
1710         
1711 }
1712 - (IBAction) CloseAddPresetPanel: (id) sender
1713 {
1714     [NSApp stopModal];
1715 }
1716    /* We use this method to recreate new, updated factory
1717    presets */
1718 - (IBAction)AddFactoryPresets:(id)sender
1719 {
1720     /* First, we delete any existing built in presets */
1721     [self DeleteFactoryPresets: sender];
1722     /* Then, we re-create new built in presets programmatically CreatePS3Preset*/
1723         [UserPresets addObject:[self CreateIpodPreset]];
1724         [UserPresets addObject:[self CreateAppleTVPreset]];
1725         [UserPresets addObject:[self CreatePSThreePreset]];
1726     [self AddPreset];
1727 }
1728 - (IBAction)DeleteFactoryPresets:(id)sender
1729 {
1730     //int status;
1731     NSEnumerator *enumerator = [UserPresets objectEnumerator];
1732         id tempObject;
1733     
1734         //NSNumber *index;
1735     NSMutableArray *tempArray;
1736
1737
1738         tempArray = [NSMutableArray array];
1739         /* we look here to see if the preset is we move on to the next one */
1740         while ( tempObject = [enumerator nextObject] )  
1741                 {
1742                         /* if the preset is "Factory" then we put it in the array of
1743                         presets to delete */
1744                         if ([[tempObject objectForKey:@"Type"] intValue] == 0)
1745                         {
1746                                 [tempArray addObject:tempObject];
1747                         }
1748         }
1749         
1750         [UserPresets removeObjectsInArray:tempArray];
1751         [tableView reloadData];
1752         [self savePreset];   
1753
1754 }
1755
1756 - (IBAction)AddUserPreset:(id)sender
1757 {
1758     /* Here we create a custom user preset */
1759         [UserPresets addObject:[self CreatePreset]];
1760     [self AddPreset];
1761
1762 }
1763 - (void)AddPreset
1764 {
1765
1766         
1767         /* We Sort the Presets By Factory or Custom */
1768         NSSortDescriptor * presetTypeDescriptor=[[[NSSortDescriptor alloc] initWithKey:@"Type" 
1769                                                     ascending:YES] autorelease];
1770         /* We Sort the Presets Alphabetically by name */
1771         NSSortDescriptor * presetNameDescriptor=[[[NSSortDescriptor alloc] initWithKey:@"PresetName" 
1772                                                     ascending:YES selector:@selector(caseInsensitiveCompare:)] autorelease];
1773         NSArray *sortDescriptors=[NSArray arrayWithObjects:presetTypeDescriptor,presetNameDescriptor,nil];
1774         NSArray *sortedArray=[UserPresets sortedArrayUsingDescriptors:sortDescriptors];
1775         [UserPresets setArray:sortedArray];
1776         
1777         /* We stop the modal window for the new preset */
1778         [fPresetNewName setStringValue: @""];
1779         //[fPresetNewX264Opt setStringValue: @""];
1780         [NSApp stopModal];
1781         /* We Reload the New Table data for presets */
1782     [tableView reloadData];
1783    /* We save all of the preset data here */
1784     [self savePreset];
1785 }
1786
1787 - (IBAction)InsertPreset:(id)sender
1788 {
1789     int index = [tableView selectedRow];
1790     [UserPresets insertObject:[self CreatePreset] atIndex:index];
1791     [tableView reloadData];
1792     [self savePreset];
1793 }
1794
1795 - (NSDictionary *)CreatePreset
1796 {
1797     NSMutableDictionary *preset = [[NSMutableDictionary alloc] init];
1798         /* Get the New Preset Name from the field in the AddPresetPanel */
1799     [preset setObject:[fPresetNewName stringValue] forKey:@"PresetName"];
1800         /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/
1801         [preset setObject:[NSNumber numberWithInt:1] forKey:@"Type"];
1802         /*Set whether or not this is default, at creation set to 0*/
1803         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Default"];
1804         /*Get the whether or not to apply pic settings in the AddPresetPanel*/
1805         [preset setObject:[NSNumber numberWithInt:[fPresetNewPicSettingsApply state]] forKey:@"UsesPictureSettings"];
1806         /* File Format */
1807     [preset setObject:[fDstFormatPopUp titleOfSelectedItem] forKey:@"FileFormat"];
1808         /* Chapter Markers fCreateChapterMarkers*/
1809         [preset setObject:[NSNumber numberWithInt:[fCreateChapterMarkers state]] forKey:@"ChapterMarkers"];
1810         /* Codecs */
1811         [preset setObject:[fDstCodecsPopUp titleOfSelectedItem] forKey:@"FileCodecs"];
1812         /* Video encoder */
1813         [preset setObject:[fVidEncoderPopUp titleOfSelectedItem] forKey:@"VideoEncoder"];
1814         /* x264 Option String */
1815         [preset setObject:[fPresetNewX264Opt string] forKey:@"x264Option"];
1816         //[fDisplayX264Options setStringValue: [NSString stringWithFormat: @"Using Option: %@",CurUserPresetx264Opt]];
1817         /* Video quality */
1818         [preset setObject:[NSNumber numberWithInt:[fVidQualityMatrix selectedRow]] forKey:@"VideoQualityType"];
1819         [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
1820         [preset setObject:[fVidBitrateField stringValue] forKey:@"VideoAvgBitrate"];
1821         [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
1822         
1823         /* Video framerate */
1824         [preset setObject:[fVidRatePopUp titleOfSelectedItem] forKey:@"VideoFramerate"];
1825         /* GrayScale */
1826         [preset setObject:[NSNumber numberWithInt:[fVidGrayscaleCheck state]] forKey:@"VideoGrayScale"];
1827         /* 2 Pass Encoding */
1828         [preset setObject:[NSNumber numberWithInt:[fVidTwoPassCheck state]] forKey:@"VideoTwoPass"];
1829         
1830         /*Picture Settings*/
1831         hb_job_t * job = fTitle->job;
1832         /* Basic Picture Settings */
1833         /* Use Max Picture settings for whatever the dvd is.*/
1834         [preset setObject:[NSNumber numberWithInt:0] forKey:@"UsesMaxPictureSettings"];
1835         [preset setObject:[NSNumber numberWithInt:fTitle->job->width] forKey:@"PictureWidth"];
1836         [preset setObject:[NSNumber numberWithInt:fTitle->job->height] forKey:@"PictureHeight"];
1837         [preset setObject:[NSNumber numberWithInt:fTitle->job->keep_ratio] forKey:@"PictureKeepRatio"];
1838         [preset setObject:[NSNumber numberWithInt:fTitle->job->deinterlace] forKey:@"PictureDeinterlace"];
1839         [preset setObject:[NSNumber numberWithInt:fTitle->job->pixel_ratio] forKey:@"PicturePAR"];
1840         /* Set crop settings here */
1841         /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */
1842         [preset setObject:[NSNumber numberWithInt:job->crop[0]] forKey:@"PictureTopCrop"];
1843     [preset setObject:[NSNumber numberWithInt:job->crop[1]] forKey:@"PictureBottomCrop"];
1844         [preset setObject:[NSNumber numberWithInt:job->crop[2]] forKey:@"PictureLeftCrop"];
1845         [preset setObject:[NSNumber numberWithInt:job->crop[3]] forKey:@"PictureRightCrop"];
1846         
1847         /*Audio*/
1848         /* Audio Language One*/
1849         [preset setObject:[fAudLang1PopUp titleOfSelectedItem] forKey:@"AudioLang1"];
1850         /* Audio Track one mixdown */
1851     if ([fAudLang1PopUp indexOfSelectedItem] > 0) {
1852         [preset setObject:[NSString stringWithCString:hb_mixdown_get_short_name_from_mixdown([[fAudTrack1MixPopUp selectedItem] tag])] forKey:@"AudioLang1Mixdown"];
1853     }
1854     else
1855     {
1856         [preset setObject:[NSString stringWithCString:""] forKey:@"AudioLang1Mixdown"];
1857     }
1858         /* Audio Language Two*/
1859         [preset setObject:[fAudLang2PopUp titleOfSelectedItem] forKey:@"AudioLang2"];
1860         /* Audio Track Two mixdown */
1861     if ([fAudLang2PopUp indexOfSelectedItem] > 0) {
1862         [preset setObject:[NSString stringWithCString:hb_mixdown_get_short_name_from_mixdown([[fAudTrack2MixPopUp selectedItem] tag])] forKey:@"AudioLang2Mixdown"];
1863     }
1864     else
1865     {
1866         [preset setObject:[NSString stringWithCString:""] forKey:@"AudioLang2Mixdown"];
1867     }
1868         /* Audio Sample Rate*/
1869         [preset setObject:[fAudRatePopUp titleOfSelectedItem] forKey:@"AudioSampleRate"];
1870         /* Audio Bitrate Rate*/
1871         [preset setObject:[fAudBitratePopUp titleOfSelectedItem] forKey:@"AudioBitRate"];
1872         /* Subtitles*/
1873         [preset setObject:[fSubPopUp titleOfSelectedItem] forKey:@"Subtitles"];
1874         
1875
1876     [preset autorelease];
1877     return preset;
1878
1879 }
1880
1881 - (NSDictionary *)CreateIpodPreset
1882 {
1883     NSMutableDictionary *preset = [[NSMutableDictionary alloc] init];
1884         /* Get the New Preset Name from the field in the AddPresetPanel */
1885     [preset setObject:@"HB-iPod" forKey:@"PresetName"];
1886         /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/
1887         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"];
1888         /*Set whether or not this is default, at creation set to 0*/
1889         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Default"];
1890         /*Get the whether or not to apply pic settings in the AddPresetPanel*/
1891         [preset setObject:[NSNumber numberWithInt:0] forKey:@"UsesPictureSettings"];
1892         /* File Format */
1893     [preset setObject:@"MP4 file" forKey:@"FileFormat"];
1894         /* Chapter Markers*/
1895          [preset setObject:[NSNumber numberWithInt:1] forKey:@"ChapterMarkers"];
1896     /* Codecs */
1897         [preset setObject:@"AVC/H.264 Video / AAC Audio" forKey:@"FileCodecs"];
1898         /* Video encoder */
1899         [preset setObject:@"x264 (h.264 iPod)" forKey:@"VideoEncoder"];
1900         /* x264 Option String */
1901         [preset setObject:@"" forKey:@"x264Option"];
1902         /* Video quality */
1903         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"];
1904         [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
1905         [preset setObject:@"1400" forKey:@"VideoAvgBitrate"];
1906         [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
1907         
1908         /* Video framerate */
1909         [preset setObject:@"Same as source" forKey:@"VideoFramerate"];
1910         /* GrayScale */
1911         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"];
1912         /* 2 Pass Encoding */
1913         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoTwoPass"];
1914         
1915         /*Picture Settings*/
1916         //hb_job_t * job = fTitle->job;
1917         /* Basic Picture Settings */
1918         /* Use Max Picture settings for whatever the dvd is.*/
1919         [preset setObject:[NSNumber numberWithInt:0] forKey:@"UsesMaxPictureSettings"];
1920         //[preset setObject:[NSNumber numberWithInt:fTitle->job->width] forKey:@"PictureWidth"];
1921         //[preset setObject:[NSNumber numberWithInt:fTitle->job->height] forKey:@"PictureHeight"];
1922         //[preset setObject:[NSNumber numberWithInt:fTitle->job->keep_ratio] forKey:@"PictureKeepRatio"];
1923         //[preset setObject:[NSNumber numberWithInt:fTitle->job->deinterlace] forKey:@"PictureDeinterlace"];
1924         //[preset setObject:[NSNumber numberWithInt:fTitle->job->pixel_ratio] forKey:@"PicturePAR"];
1925         /* Set crop settings here */
1926         /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */
1927         //[preset setObject:[NSNumber numberWithInt:job->crop[0]] forKey:@"PictureTopCrop"];
1928     //[preset setObject:[NSNumber numberWithInt:job->crop[1]] forKey:@"PictureBottomCrop"];
1929         //[preset setObject:[NSNumber numberWithInt:job->crop[2]] forKey:@"PictureLeftCrop"];
1930         //[preset setObject:[NSNumber numberWithInt:job->crop[3]] forKey:@"PictureRightCrop"];
1931         
1932         /*Audio*/
1933         /* Audio track one*/
1934         [preset setObject:[fAudLang1PopUp titleOfSelectedItem] forKey:@"AudioLang1"];
1935         /* Track one mixdown dpl2*/
1936         [preset setObject:[NSString stringWithCString:"stereo"] forKey:@"AudioLang1Mixdown"];
1937     /* Audio track two */
1938         [preset setObject:[NSString stringWithFormat:@"None"] forKey:@"AudioLang2"];
1939         /* Track two mixdown */
1940         [preset setObject:[NSString stringWithCString:""] forKey:@"AudioLang2Mixdown"];
1941         /* Audio Sample Rate*/
1942         [preset setObject:@"44.1" forKey:@"AudioSampleRate"];
1943         /* Audio Bitrate Rate*/
1944         [preset setObject:@"128" forKey:@"AudioBitRate"];
1945         /* Subtitles*/
1946         [preset setObject:@"None" forKey:@"Subtitles"];
1947         
1948
1949     [preset autorelease];
1950     return preset;
1951
1952 }
1953
1954 - (NSDictionary *)CreateAppleTVPreset
1955 {
1956     NSMutableDictionary *preset = [[NSMutableDictionary alloc] init];
1957         /* Get the New Preset Name from the field in the AddPresetPanel */
1958     [preset setObject:@"HB-AppleTV" forKey:@"PresetName"];
1959         /*Set whether or not this is a user preset where 0 is factory, 1 is user*/
1960         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"];
1961         /*Set whether or not this is default, at creation set to 0*/
1962         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Default"];
1963         /*Get the whether or not to apply pic settings in the AddPresetPanel*/
1964         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesPictureSettings"];
1965         /* File Format */
1966     [preset setObject:@"MP4 file" forKey:@"FileFormat"];
1967         /* Chapter Markers*/
1968          [preset setObject:[NSNumber numberWithInt:1] forKey:@"ChapterMarkers"];
1969         /* Codecs */
1970         [preset setObject:@"AVC/H.264 Video / AAC Audio" forKey:@"FileCodecs"];
1971         /* Video encoder */
1972         [preset setObject:@"x264 (h.264 Main)" forKey:@"VideoEncoder"];
1973         /* x264 Option String (We can use this to tweak the appleTV output)*/
1974         [preset setObject:@"" forKey:@"x264Option"];
1975         /* Video quality */
1976         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"];
1977         [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
1978         [preset setObject:@"2500" forKey:@"VideoAvgBitrate"];
1979         [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
1980         
1981         /* Video framerate */
1982         [preset setObject:@"Same as source" forKey:@"VideoFramerate"];
1983         /* GrayScale */
1984         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"];
1985         /* 2 Pass Encoding */
1986         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoTwoPass"];
1987         
1988         /*Picture Settings*/
1989         /* For AppleTV we only want to retain UsesMaxPictureSettings
1990         which depend on the source dvd picture settings, so we don't
1991         record the current dvd's picture info since it will vary from
1992         source to source*/
1993         //hb_job_t * job = fTitle->job;
1994         //hb_job_t * job = title->job;
1995         /* Basic Picture Settings */
1996         /* Use Max Picture settings for whatever the dvd is.*/
1997         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesMaxPictureSettings"];
1998         //[preset setObject:[NSNumber numberWithInt:PicOrigOutputWidth] forKey:@"PictureWidth"];
1999         //[preset setObject:[NSNumber numberWithInt:PicOrigOutputHeight] forKey:@"PictureHeight"];
2000         //[preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureKeepRatio"];
2001         //[preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureDeinterlace"];
2002         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PicturePAR"];
2003         /* Set crop settings here */
2004         /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */
2005         //[preset setObject:[NSNumber numberWithInt:job->crop[0]] forKey:@"PictureTopCrop"];
2006     //[preset setObject:[NSNumber numberWithInt:job->crop[1]] forKey:@"PictureBottomCrop"];
2007         //[preset setObject:[NSNumber numberWithInt:job->crop[2]] forKey:@"PictureLeftCrop"];
2008         //[preset setObject:[NSNumber numberWithInt:job->crop[3]] forKey:@"PictureRightCrop"];
2009         
2010         /*Audio*/
2011         /* Audio track one*/
2012         [preset setObject:[fAudLang1PopUp titleOfSelectedItem] forKey:@"AudioLang1"];
2013         /* Track one mixdown dpl2*/
2014         [preset setObject:[NSString stringWithCString:"dpl2"] forKey:@"AudioLang1Mixdown"];
2015     /* Audio track two */
2016         [preset setObject:[NSString stringWithFormat:@"None"] forKey:@"AudioLang2"];
2017         /* Track two mixdown */
2018         [preset setObject:[NSString stringWithCString:""] forKey:@"AudioLang2Mixdown"];
2019         /* Audio Sample Rate*/
2020         [preset setObject:@"44.1" forKey:@"AudioSampleRate"];
2021         /* Audio Bitrate Rate*/
2022         [preset setObject:@"160" forKey:@"AudioBitRate"];
2023         /* Subtitles*/
2024         [preset setObject:@"None" forKey:@"Subtitles"];
2025         
2026
2027     [preset autorelease];
2028     return preset;
2029
2030 }
2031
2032 - (NSDictionary *)CreatePSThreePreset
2033 {
2034     NSMutableDictionary *preset = [[NSMutableDictionary alloc] init];
2035         /* Get the New Preset Name from the field in the AddPresetPanel */
2036     [preset setObject:@"HB-PS3" forKey:@"PresetName"];
2037         /*Set whether or not this is a user preset where 0 is factory, 1 is user*/
2038         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Type"];
2039         /*Set whether or not this is default, at creation set to 0*/
2040         [preset setObject:[NSNumber numberWithInt:0] forKey:@"Default"];
2041         /*Get the whether or not to apply pic settings in the AddPresetPanel*/
2042         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesPictureSettings"];
2043         /* File Format */
2044     [preset setObject:@"MP4 file" forKey:@"FileFormat"];
2045         /* Chapter Markers*/
2046          [preset setObject:[NSNumber numberWithInt:1] forKey:@"ChapterMarkers"];
2047         /* Codecs */
2048         [preset setObject:@"AVC/H.264 Video / AAC Audio" forKey:@"FileCodecs"];
2049         /* Video encoder */
2050         [preset setObject:@"x264 (h.264 Main)" forKey:@"VideoEncoder"];
2051         /* x264 Option String (We can use this to tweak the appleTV output)*/
2052         [preset setObject:@"level=41" forKey:@"x264Option"];
2053         /* Video quality */
2054         [preset setObject:[NSNumber numberWithInt:1] forKey:@"VideoQualityType"];
2055         [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
2056         [preset setObject:@"2500" forKey:@"VideoAvgBitrate"];
2057         [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
2058         
2059         /* Video framerate */
2060         [preset setObject:@"Same as source" forKey:@"VideoFramerate"];
2061         /* GrayScale */
2062         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoGrayScale"];
2063         /* 2 Pass Encoding */
2064         [preset setObject:[NSNumber numberWithInt:0] forKey:@"VideoTwoPass"];
2065         
2066         /*Picture Settings*/
2067         /* For PS3 we only want to retain UsesMaxPictureSettings
2068         which depend on the source dvd picture settings, so we don't
2069         record the current dvd's picture info since it will vary from
2070         source to source*/
2071         /* Use Max Picture settings for whatever the dvd is.*/
2072         [preset setObject:[NSNumber numberWithInt:1] forKey:@"UsesMaxPictureSettings"];
2073         //[preset setObject:[NSNumber numberWithInt:PicOrigOutputWidth] forKey:@"PictureWidth"];
2074         //[preset setObject:[NSNumber numberWithInt:PicOrigOutputHeight] forKey:@"PictureHeight"];
2075         //[preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureKeepRatio"];
2076         //[preset setObject:[NSNumber numberWithInt:0] forKey:@"PictureDeinterlace"];
2077         [preset setObject:[NSNumber numberWithInt:1] forKey:@"PicturePAR"];
2078         /* Set crop settings here */
2079         /* The Auto Crop Matrix in the Picture Window autodetects differences in crop settings */
2080         //[preset setObject:[NSNumber numberWithInt:job->crop[0]] forKey:@"PictureTopCrop"];
2081     //[preset setObject:[NSNumber numberWithInt:job->crop[1]] forKey:@"PictureBottomCrop"];
2082         //[preset setObject:[NSNumber numberWithInt:job->crop[2]] forKey:@"PictureLeftCrop"];
2083         //[preset setObject:[NSNumber numberWithInt:job->crop[3]] forKey:@"PictureRightCrop"];
2084         
2085         /*Audio*/
2086         /* Audio track one*/
2087         [preset setObject:[fAudLang1PopUp titleOfSelectedItem] forKey:@"AudioLang1"];
2088         /* Track one mixdown dpl2*/
2089         [preset setObject:[NSString stringWithCString:"dpl2"] forKey:@"AudioLang1Mixdown"];
2090     /* Audio track two */
2091         [preset setObject:[NSString stringWithFormat:@"None"] forKey:@"AudioLang2"];
2092         /* Track two mixdown */
2093         [preset setObject:[NSString stringWithCString:""] forKey:@"AudioLang2Mixdown"];
2094         /* Audio Sample Rate*/
2095         [preset setObject:@"44.1" forKey:@"AudioSampleRate"];
2096         /* Audio Bitrate Rate*/
2097         [preset setObject:@"160" forKey:@"AudioBitRate"];
2098         /* Subtitles*/
2099         [preset setObject:@"None" forKey:@"Subtitles"];
2100         
2101
2102     [preset autorelease];
2103     return preset;
2104
2105 }
2106
2107
2108 - (IBAction)DeletePreset:(id)sender
2109 {
2110     int status;
2111     NSEnumerator *enumerator;
2112     NSNumber *index;
2113     NSMutableArray *tempArray;
2114     id tempObject;
2115     
2116     if ( [tableView numberOfSelectedRows] == 0 )
2117         return;
2118     /* Alert user before deleting preset */
2119         /* Comment out for now, tie to user pref eventually */
2120     //NSBeep();
2121     status = NSRunAlertPanel(@"Warning!", @"Are you sure that you want to delete the selected preset?", @"OK", @"Cancel", nil);
2122     
2123     if ( status == NSAlertDefaultReturn ) {
2124         enumerator = [tableView selectedRowEnumerator];
2125         tempArray = [NSMutableArray array];
2126         
2127         while ( (index = [enumerator nextObject]) ) {
2128             tempObject = [UserPresets objectAtIndex:[index intValue]];
2129             [tempArray addObject:tempObject];
2130         }
2131         
2132         [UserPresets removeObjectsInArray:tempArray];
2133         [tableView reloadData];
2134         [self savePreset];   
2135     }
2136 }
2137 - (IBAction)tableViewSelected:(id)sender
2138 {
2139     /* Since we cannot disable the presets tableView in terms of clickability
2140            we will use the enabled state of the add presets button to determine whether
2141            or not clicking on a preset will do anything */
2142         if ([fPresetsAdd isEnabled])
2143         {
2144                 
2145                 /* we get the chosen preset from the UserPresets array */
2146                 chosenPreset = [UserPresets objectAtIndex:[sender selectedRow]];
2147                 curUserPresetChosenNum = [sender selectedRow];
2148                 /* we set the preset display field in main window here */
2149                 [fPresetSelectedDisplay setStringValue: [NSString stringWithFormat: @"%@",[chosenPreset valueForKey:@"PresetName"]]];
2150                 /* File Format */
2151                 [fDstFormatPopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"FileFormat"]]];
2152                 [self FormatPopUpChanged: NULL];
2153                 /* Chapter Markers*/
2154                 [fCreateChapterMarkers setState:[[chosenPreset objectForKey:@"ChapterMarkers"] intValue]];
2155             /* Codecs */
2156                 [fDstCodecsPopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"FileCodecs"]]];
2157                 [self CodecsPopUpChanged: NULL];
2158                 /* Video encoder */
2159                 [fVidEncoderPopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"VideoEncoder"]]];
2160                 
2161                 /* We can show the preset options here in the gui if we want to
2162                 Field is currently hidden from user, unhide it if we need to test */
2163                 [fDisplayX264Options setStringValue: [NSString stringWithFormat:[chosenPreset valueForKey:@"x264Option"]]];
2164                 /* Lets run through the following functions to get variables set there */
2165                 [self EncoderPopUpChanged: NULL];
2166                 [self CalculateBitrate: NULL];
2167                 
2168                 /* Video quality */
2169                 [fVidQualityMatrix selectCellAtRow:[[chosenPreset objectForKey:@"VideoQualityType"] intValue] column:0];
2170                 
2171                 [fVidTargetSizeField setStringValue: [NSString stringWithFormat:[chosenPreset valueForKey:@"VideoTargetSize"]]];
2172                 [fVidBitrateField setStringValue: [NSString stringWithFormat:[chosenPreset valueForKey:@"VideoAvgBitrate"]]];
2173                 
2174                 [fVidQualitySlider setFloatValue: [[chosenPreset valueForKey:@"VideoQualitySlider"] floatValue]];
2175                 [self VideoMatrixChanged: NULL];
2176                 
2177                 /* Video framerate */
2178                 [fVidRatePopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"VideoFramerate"]]];
2179
2180                 /* GrayScale */
2181                 [fVidGrayscaleCheck setState:[[chosenPreset objectForKey:@"VideoGrayScale"] intValue]];
2182                 
2183                 /* 2 Pass Encoding */
2184                 [fVidTwoPassCheck setState:[[chosenPreset objectForKey:@"VideoTwoPass"] intValue]];
2185                 
2186                 
2187                 /*Audio*/
2188                 /* Audio Language One*/
2189                 [fAudLang1PopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"AudioLang1"]]];
2190                 /* We check to make sure something is selected for track 1 */
2191                 if ([fAudLang1PopUp indexOfSelectedItem] == -1)
2192                 {
2193                         /* If not we choose the first source in the track 1 dropdown */
2194                         [fAudLang1PopUp selectItemAtIndex: 0];
2195                 }
2196
2197         /* if the preset contains a mixdown value for track 1, then try and load it */
2198         /* if the preset contains the empty string for this value, then we'll get
2199            a mixdown of 0 from hb_mixdown_get_mixdown_from_short_name,
2200            which will be correctly ignored by AudioTrackPopUpChanged */
2201         /* if the mixdown is unavailable, AudioTrackPopUpChanged will choose the next best mixdown */
2202         char cBuffer1[32];
2203         NSString * short_name1 = [NSString stringWithFormat:[chosenPreset valueForKey:@"AudioLang1Mixdown"]];
2204         [short_name1 getCString:cBuffer1];
2205         int mixdown1 = hb_mixdown_get_mixdown_from_short_name(cBuffer1);
2206         [self AudioTrackPopUpChanged: fAudLang1PopUp mixdownToUse: mixdown1];
2207
2208                 /* Audio Language Two*/
2209                 [fAudLang2PopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"AudioLang2"]]];
2210                 /* We check to make sure something is selected for track 2 */
2211                 if ([fAudLang2PopUp indexOfSelectedItem] == -1)
2212                 {
2213                         /* If not we choose "None" in the track 2 dropdown */
2214                         [fAudLang2PopUp selectItemWithTitle: [NSString stringWithFormat:@"None"]];
2215                         //[self SetEnabledStateOfAudioMixdownControls: sender];
2216                 }
2217                 /* if the preset contains a mixdown value for track 2, then try and load it */
2218         /* if the preset contains the empty string for this value, then we'll get
2219            a mixdown of 0 from hb_mixdown_get_mixdown_from_short_name,
2220            which will be correctly ignored by AudioTrackPopUpChanged */
2221         /* if the mixdown is unavailable, AudioTrackPopUpChanged will choose the next best mixdown */
2222         char cBuffer2[32];
2223         NSString * short_name2 = [NSString stringWithFormat:[chosenPreset valueForKey:@"AudioLang2Mixdown"]];
2224         [short_name2 getCString:cBuffer2];
2225         int mixdown2 = hb_mixdown_get_mixdown_from_short_name(cBuffer2);
2226         [self AudioTrackPopUpChanged: fAudLang2PopUp mixdownToUse: mixdown2];
2227         
2228                 
2229                 /* Audio Sample Rate*/
2230                 [fAudRatePopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"AudioSampleRate"]]];
2231                 /* Audio Bitrate Rate*/
2232                 [fAudBitratePopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"AudioBitRate"]]];
2233                 /*Subtitles*/
2234                 [fSubPopUp selectItemWithTitle: [NSString stringWithFormat:[chosenPreset valueForKey:@"Subtitles"]]];
2235                 
2236                 /* Picture Settings */
2237                 /* Look to see if we apply these here in objectForKey:@"UsesPictureSettings"] */
2238                 if ([[chosenPreset objectForKey:@"UsesPictureSettings"]  intValue] == 1)
2239                 {
2240                         hb_job_t * job = fTitle->job;
2241                         /* Check to see if we should use the max picture setting for the current title*/
2242                         if ([[chosenPreset objectForKey:@"UsesMaxPictureSettings"]  intValue] == 1)
2243                         {
2244                                 /* Use Max Picture settings for whatever the dvd is.*/
2245                                 [self RevertPictureSizeToMax: NULL];
2246                                 job->keep_ratio = [[chosenPreset objectForKey:@"PictureKeepRatio"]  intValue];
2247                                 if (job->keep_ratio == 1)
2248                                 {
2249                                         hb_fix_aspect( job, HB_KEEP_WIDTH );
2250                                 }
2251                                 job->pixel_ratio = [[chosenPreset objectForKey:@"PicturePAR"]  intValue];
2252                         }
2253                         else
2254                         {
2255                                 job->width = [[chosenPreset objectForKey:@"PictureWidth"]  intValue];
2256                                 job->height = [[chosenPreset objectForKey:@"PictureHeight"]  intValue];
2257                                 job->keep_ratio = [[chosenPreset objectForKey:@"PictureKeepRatio"]  intValue];
2258                                 if (job->keep_ratio == 1)
2259                                 {
2260                                         hb_fix_aspect( job, HB_KEEP_WIDTH );
2261                                 }
2262                                 job->pixel_ratio = [[chosenPreset objectForKey:@"PicturePAR"]  intValue];
2263                                 job->crop[0] = [[chosenPreset objectForKey:@"PictureTopCrop"]  intValue];
2264                                 job->crop[1] = [[chosenPreset objectForKey:@"PictureBottomCrop"]  intValue];
2265                                 job->crop[2] = [[chosenPreset objectForKey:@"PictureLeftCrop"]  intValue];
2266                                 job->crop[3] = [[chosenPreset objectForKey:@"PictureRightCrop"]  intValue];
2267                         }
2268                         [self CalculatePictureSizing: NULL]; 
2269                 }
2270                 
2271
2272
2273
2274 }
2275 }
2276
2277
2278
2279 - (int)numberOfRowsInTableView:(NSTableView *)aTableView
2280 {
2281     return [UserPresets count];
2282 }
2283
2284 /* we use this to determine display characteristics for
2285 each table cell based on content currently only used to
2286 show the built in presets in a blue font. */
2287 - (void)tableView:(NSTableView *)aTableView
2288  willDisplayCell:(id)aCell 
2289  forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
2290 {
2291     NSDictionary *userPresetDict = [UserPresets objectAtIndex:rowIndex];
2292    if ([[userPresetDict objectForKey:@"Type"] intValue] == 0)
2293         {
2294                 [aCell setTextColor:[NSColor blueColor]];
2295         }
2296         else
2297         {
2298                 [aCell setTextColor:[NSColor blackColor]];
2299         }
2300
2301 }
2302
2303 - (id)tableView:(NSTableView *)aTableView
2304       objectValueForTableColumn:(NSTableColumn *)aTableColumn
2305       row:(int)rowIndex
2306 {
2307 id theRecord, theValue;
2308     
2309     theRecord = [UserPresets objectAtIndex:rowIndex];
2310     theValue = [theRecord objectForKey:[aTableColumn identifier]];
2311     return theValue;
2312 }
2313
2314 // NSTableDataSource method that we implement to edit values directly in the table...
2315 - (void)tableView:(NSTableView *)aTableView
2316         setObjectValue:(id)anObject
2317         forTableColumn:(NSTableColumn *)aTableColumn
2318         row:(int)rowIndex
2319 {
2320     id theRecord;
2321     
2322     theRecord = [UserPresets objectAtIndex:rowIndex];
2323     [theRecord setObject:anObject forKey:@"PresetName"];
2324     /* We Sort the Presets By Factory or Custom */
2325         NSSortDescriptor * presetTypeDescriptor=[[[NSSortDescriptor alloc] initWithKey:@"Type" 
2326                                                     ascending:YES] autorelease];
2327                 /* We Sort the Presets Alphabetically by name */
2328         NSSortDescriptor * presetNameDescriptor=[[[NSSortDescriptor alloc] initWithKey:@"PresetName" 
2329                                                     ascending:YES selector:@selector(caseInsensitiveCompare:)] autorelease];
2330         NSArray *sortDescriptors=[NSArray arrayWithObjects:presetTypeDescriptor,presetNameDescriptor,nil];
2331     NSArray *sortedArray=[UserPresets sortedArrayUsingDescriptors:sortDescriptors];
2332         [UserPresets setArray:sortedArray];
2333         /* We Reload the New Table data for presets */
2334     [tableView reloadData];
2335    /* We save all of the preset data here */
2336     [self savePreset];
2337 }
2338
2339
2340 - (void)savePreset
2341 {
2342     [UserPresets writeToFile:UserPresetsFile atomically:YES];
2343
2344 }
2345
2346
2347
2348 - (void) controlTextDidBeginEditing: (NSNotification *) notification
2349 {
2350     [self CalculateBitrate: NULL];
2351 }
2352
2353 - (void) controlTextDidEndEditing: (NSNotification *) notification
2354 {
2355     [self CalculateBitrate: NULL];
2356 }
2357
2358 - (void) controlTextDidChange: (NSNotification *) notification
2359 {
2360     [self CalculateBitrate: NULL];
2361 }
2362
2363 - (IBAction) OpenHomepage: (id) sender
2364 {
2365     [[NSWorkspace sharedWorkspace] openURL: [NSURL
2366         URLWithString:@"http://handbrake.m0k.org/"]];
2367 }
2368
2369 - (IBAction) OpenForums: (id) sender
2370 {
2371     [[NSWorkspace sharedWorkspace] openURL: [NSURL
2372         URLWithString:@"http://handbrake.m0k.org/forum/"]];
2373 }
2374
2375
2376
2377 @end