OSDN Git Service

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