OSDN Git Service

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