diff options
Diffstat (limited to 'macosx')
26 files changed, 2721 insertions, 1818 deletions
diff --git a/macosx/Controller.h b/macosx/Controller.h index 400246af8..c32dacc04 100644 --- a/macosx/Controller.h +++ b/macosx/Controller.h @@ -1,4 +1,4 @@ -/* $Id: Controller.h,v 1.14 2004/02/13 13:45:51 titer Exp $ +/* $Id: Controller.h,v 1.35 2005/08/01 14:29:50 titer Exp $ This file is part of the HandBrake source code. Homepage: <http://handbrake.m0k.org/>. @@ -6,153 +6,138 @@ #include <Cocoa/Cocoa.h> -#include "HandBrake.h" -#include "PictureGLView.h" -#include "TargetSizeField.h" +#include "hb.h" + +#include "ScanController.h" +#include "PictureController.h" +#include "QueueController.h" @interface HBController : NSObject { IBOutlet NSWindow * fWindow; - /* Scan view */ - IBOutlet NSView * fScView; - IBOutlet NSTextField * fScWelcomeField; - IBOutlet NSTextField * fScSelectField; - IBOutlet NSMatrix * fScMatrix; - IBOutlet NSButtonCell * fScDetectedCell; - IBOutlet NSPopUpButton * fScDetectedPopUp; - IBOutlet NSButtonCell * fScFolderCell; - IBOutlet NSTextField * fScFolderField; - IBOutlet NSButton * fScBrowseButton; - IBOutlet NSTextField * fScStatusField; - IBOutlet NSProgressIndicator * fScProgress; - IBOutlet NSButton * fScOpenButton; - - IBOutlet NSView * fTempView; - - /* Rip view */ - IBOutlet NSView * fRipView; - - /* General box */ - IBOutlet NSTextField * fRipGeneralField; - IBOutlet NSTextField * fRipTitleField; - IBOutlet NSPopUpButton * fRipTitlePopUp; - IBOutlet NSTextField * fRipFormatField; - IBOutlet NSPopUpButton * fRipFormatPopUp; - IBOutlet NSTextField * fRipFileField1; - IBOutlet NSTextField * fRipFileField2; - IBOutlet NSButton * fRipBrowseButton; + /* Scan panel */ + IBOutlet ScanController * fScanController; + IBOutlet NSPanel * fScanPanel; + + /* Picture panel */ + IBOutlet PictureController * fPictureController; + IBOutlet NSPanel * fPicturePanel; + + /* Queue panel */ + IBOutlet QueueController * fQueueController; + IBOutlet NSPanel * fQueuePanel; + IBOutlet NSButton * fQueueCheck; + IBOutlet NSButton * fQueueAddButton; + IBOutlet NSButton * fQueueShowButton; + + /* Source box */ + IBOutlet NSTextField * fSrcDVD1Field; + IBOutlet NSTextField * fSrcDVD2Field; + IBOutlet NSTextField * fSrcTitleField; + IBOutlet NSPopUpButton * fSrcTitlePopUp; + IBOutlet NSTextField * fSrcChapterField; + IBOutlet NSPopUpButton * fSrcChapterStartPopUp; + IBOutlet NSTextField * fSrcChapterToField; + IBOutlet NSPopUpButton * fSrcChapterEndPopUp; + IBOutlet NSTextField * fSrcDuration1Field; + IBOutlet NSTextField * fSrcDuration2Field; + + /* Destination box */ + IBOutlet NSTextField * fDstFormatField; + IBOutlet NSPopUpButton * fDstFormatPopUp; + IBOutlet NSTextField * fDstCodecsField; + IBOutlet NSPopUpButton * fDstCodecsPopUp; + IBOutlet NSTextField * fDstFile1Field; + IBOutlet NSTextField * fDstFile2Field; + IBOutlet NSButton * fDstBrowseButton; /* Video box */ - IBOutlet NSTextField * fRipVideoField; - IBOutlet NSTextField * fRipEncoderField; - IBOutlet NSPopUpButton * fRipEncoderPopUp; - IBOutlet NSTextField * fRipBitrateField; - IBOutlet NSMatrix * fRipVideoMatrix; - IBOutlet NSButtonCell * fRipCustomCell; - IBOutlet NSTextField * fRipCustomField; - IBOutlet NSButtonCell * fRipTargetCell; - IBOutlet HBTargetSizeField * fRipTargetField; - IBOutlet NSButton * fRipTwoPassCheck; - IBOutlet NSButton * fRipCropButton; + IBOutlet NSTextField * fVidRateField; + IBOutlet NSPopUpButton * fVidRatePopUp; + IBOutlet NSTextField * fVidEncoderField; + IBOutlet NSPopUpButton * fVidEncoderPopUp; + IBOutlet NSTextField * fVidQualityField; + IBOutlet NSMatrix * fVidQualityMatrix; + IBOutlet NSButtonCell * fVidTargetCell; + IBOutlet NSTextField * fVidTargetSizeField; + IBOutlet NSButtonCell * fVidBitrateCell; + IBOutlet NSTextField * fVidBitrateField; + IBOutlet NSButtonCell * fVidConstantCell; + IBOutlet NSSlider * fVidQualitySlider; + IBOutlet NSButton * fVidGrayscaleCheck; + IBOutlet NSButton * fVidTwoPassCheck; + + /* Subtitles box */ + IBOutlet NSTextField * fSubField; + IBOutlet NSPopUpButton * fSubPopUp; /* Audio box */ - IBOutlet NSTextField * fRipAudioField; - IBOutlet NSTextField * fRipLang1Field; - IBOutlet NSPopUpButton * fRipLang1PopUp; - IBOutlet NSTextField * fRipLang2Field; - IBOutlet NSPopUpButton * fRipLang2PopUp; - IBOutlet NSTextField * fRipAudBitField; - IBOutlet NSPopUpButton * fRipAudBitPopUp; + IBOutlet NSTextField * fAudLang1Field; + IBOutlet NSPopUpButton * fAudLang1PopUp; + IBOutlet NSTextField * fAudLang2Field; + IBOutlet NSPopUpButton * fAudLang2PopUp; + IBOutlet NSTextField * fAudRateField; + IBOutlet NSPopUpButton * fAudRatePopUp; + IBOutlet NSTextField * fAudBitrateField; + IBOutlet NSPopUpButton * fAudBitratePopUp; /* Bottom */ - IBOutlet NSTextField * fRipStatusField; - IBOutlet NSTextField * fRipInfoField; - IBOutlet NSProgressIndicator * fRipProgress; - IBOutlet NSButton * fRipPauseButton; - IBOutlet NSButton * fRipRipButton; + IBOutlet NSButton * fPictureButton; + IBOutlet NSTextField * fStatusField; + IBOutlet NSProgressIndicator * fRipIndicator; + IBOutlet NSButton * fShowQuButton; + IBOutlet NSButton * fAddToQuButton; + IBOutlet NSButton * fPauseButton; + IBOutlet NSButton * fRipButton; + + hb_handle_t * fHandle; +} - /* "Done" alert panel */ - IBOutlet NSPanel * fDonePanel; +- (void) TranslateStrings; - /* Crop & scale panel */ - IBOutlet NSPanel * fPicturePanel; - IBOutlet HBPictureGLView * fPictureGLView; - IBOutlet NSTextField * fWidthField1; - IBOutlet NSTextField * fWidthField2; - IBOutlet NSStepper * fWidthStepper; - IBOutlet NSButton * fDeinterlaceCheck; - IBOutlet NSTextField * fTopField1; - IBOutlet NSTextField * fTopField2; - IBOutlet NSStepper * fTopStepper; - IBOutlet NSTextField * fBottomField1; - IBOutlet NSTextField * fBottomField2; - IBOutlet NSStepper * fBottomStepper; - IBOutlet NSTextField * fLeftField1; - IBOutlet NSTextField * fLeftField2; - IBOutlet NSStepper * fLeftStepper; - IBOutlet NSTextField * fRightField1; - IBOutlet NSTextField * fRightField2; - IBOutlet NSStepper * fRightStepper; - IBOutlet NSButton * fPreviousButton; - IBOutlet NSButton * fNextButton; - IBOutlet NSButton * fAutocropButton; - IBOutlet NSButton * fOpenGLCheck; - IBOutlet NSTextField * fInfoField; - IBOutlet NSButton * fCloseButton; - int fPicture; - - HBHandle * fHandle; - int fTitle; - int fTitleCount; - HBList * fTitleList; - float fPosition; - int fPass; - int fPassCount; - float fCurFrameRate; - float fAvgFrameRate; - int fRemainingTime; - int fResult; -} +- (void) UpdateUI: (NSTimer *) timer; +- (void) EnableUI: (bool) enable; -- (IBAction) ScanMatrixChanged: (id) sender; -- (IBAction) BrowseDVD: (id) sender; -- (void) BrowseDVDDone: (NSOpenPanel *) sheet - returnCode: (int) returnCode contextInfo: (void *) contextInfo; -- (IBAction) Scan: (id) sender; +- (IBAction) ShowScanPanel: (id) sender; - (IBAction) TitlePopUpChanged: (id) sender; +- (IBAction) ChapterPopUpChanged: (id) sender; + - (IBAction) FormatPopUpChanged: (id) sender; -- (IBAction) VideoMatrixChanged: (id) sender; -- (IBAction) AudioPopUpChanged: (id) sender; +- (IBAction) CodecsPopUpChanged: (id) sender; - (IBAction) BrowseFile: (id) sender; - (void) BrowseFileDone: (NSSavePanel *) sheet returnCode: (int) returnCode contextInfo: (void *) contextInfo; + +- (IBAction) VideoMatrixChanged: (id) sender; +- (IBAction) QualitySliderChanged: (id) sender; + - (IBAction) ShowPicturePanel: (id) sender; -- (IBAction) ClosePanel: (id) sender; + +- (IBAction) EnableQueue: (id) sender; +- (IBAction) AddToQueue: (id) sender; +- (IBAction) ShowQueuePanel: (id) sender; + - (IBAction) Rip: (id) sender; - (void) OverwriteAlertDone: (NSWindow *) sheet returnCode: (int) returnCode contextInfo: (void *) contextInfo; +- (void) UpdateAlertDone: (NSWindow *) sheet + returnCode: (int) returnCode contextInfo: (void *) contextInfo; - (void) _Rip; - (IBAction) Cancel: (id) sender; - (void) _Cancel: (NSWindow *) sheet returnCode: (int) returnCode contextInfo: (void *) contextInfo; - (IBAction) Pause: (id) sender; -- (IBAction) Resume: (id) sender; - -- (IBAction) PreviousPicture: (id) sender; -- (IBAction) NextPicture: (id) sender; -- (IBAction) UpdatePicture: (id) sender; -- (IBAction) AutoCrop: (id) sender; -- (void) DetectDrives: (NSNotification *) notification; +- (IBAction) CalculateBitrate: (id) sender; +- (void) controlTextDidBeginEditing: (NSNotification *) notification; +- (void) controlTextDidEndEditing: (NSNotification *) notification; +- (void) controlTextDidChange: (NSNotification *) notification; -/* libhb callbacks */ -- (void) Scanning: (id) sender; -- (void) ScanDone: (id) sender; -- (void) Encoding: (id) sender; -- (void) RipDone: (id) sender; +- (IBAction) OpenHomepage: (id) sender; +- (IBAction) OpenForums: (id) sender; @end diff --git a/macosx/Controller.mm b/macosx/Controller.mm index eb53a9dd5..a4ba98afe 100644 --- a/macosx/Controller.mm +++ b/macosx/Controller.mm @@ -1,229 +1,488 @@ -/* $Id: Controller.mm,v 1.31 2004/04/21 21:21:17 titer Exp $ +/* $Id: Controller.mm,v 1.78 2005/11/04 13:09:41 titer Exp $ This file is part of the HandBrake source code. Homepage: <http://handbrake.m0k.org/>. It may be used under the terms of the GNU General Public License. */ -#include <paths.h> -#include <IOKit/IOKitLib.h> -#include <IOKit/IOBSD.h> -#include <IOKit/storage/IOMedia.h> -#include <IOKit/storage/IODVDMedia.h> - #include "Controller.h" -#define _(a) NSLocalizedString(a,nil) - -static void _Scanning( void * data, int title, int titleCount ); -static void _ScanDone( void * data, HBList * titleList ); -static void _Encoding( void * data, float position, int pass, - int passCount, float curFrameRate, - float avgFrameRate, int remainingTime ); -static void _RipDone( void * data, int result ); +#define _(a) NSLocalizedString(a,NULL) + +static int FormatSettings[3][4] = + { { HB_MUX_MP4 | HB_VCODEC_FFMPEG | HB_ACODEC_FAAC, + HB_MUX_MP4 | HB_VCODEC_X264 | HB_ACODEC_FAAC, + 0, + 0 }, + { HB_MUX_AVI | HB_VCODEC_FFMPEG | HB_ACODEC_LAME, + HB_MUX_AVI | HB_VCODEC_FFMPEG | HB_ACODEC_AC3, + HB_MUX_AVI | HB_VCODEC_X264 | HB_ACODEC_LAME, + HB_MUX_AVI | HB_VCODEC_X264 | HB_ACODEC_AC3 }, + { HB_MUX_OGM | HB_VCODEC_FFMPEG | HB_ACODEC_VORBIS, + HB_MUX_OGM | HB_VCODEC_FFMPEG | HB_ACODEC_LAME, + 0, + 0 } }; /******************************* * HBController implementation * *******************************/ @implementation HBController -- (void) applicationDidFinishLaunching: (NSNotification *) notification +- init { - /* Init libhb */ - HBCallbacks callbacks; - callbacks.data = self; - callbacks.scanning = _Scanning; - callbacks.scanDone = _ScanDone; - callbacks.encoding = _Encoding; - callbacks.ripDone = _RipDone; + self = [super init]; + fHandle = NULL; + return self; +} - fHandle = HBInit( 1, 0 ); - HBSetCallbacks( fHandle, callbacks ); +- (void) applicationDidFinishLaunching: (NSNotification *) notification +{ + int build; + char * version; - [fPictureGLView SetHandle: fHandle]; + /* Init libhb */ + fHandle = hb_init( HB_DEBUG_ALL, [[NSUserDefaults + standardUserDefaults] boolForKey:@"CheckForUpdates"] ); + + /* Init others controllers */ + [fScanController SetHandle: fHandle]; + [fPictureController SetHandle: fHandle]; + [fQueueController SetHandle: fHandle]; + + /* Call UpdateUI every 2/10 sec */ + [[NSRunLoop currentRunLoop] addTimer: [NSTimer + scheduledTimerWithTimeInterval: 0.2 target: self + selector: @selector( UpdateUI: ) userInfo: NULL repeats: FALSE] + forMode: NSModalPanelRunLoopMode]; + + if( ( build = hb_check_update( fHandle, &version ) ) > -1 ) + { + /* Update available - tell the user */ + NSBeginInformationalAlertSheet( _( @"Update is available" ), + _( @"Go get it!" ), _( @"Discard" ), NULL, fWindow, self, + @selector( UpdateAlertDone:returnCode:contextInfo: ), + NULL, NULL, [NSString stringWithFormat: + _( @"HandBrake %s (build %d) is now available for download." ), + version, build] ); + return; + } - /* Detect drives mounted after the app is started */ - [[[NSWorkspace sharedWorkspace] notificationCenter] - addObserver: self selector: @selector( DetectDrives: ) - name: NSWorkspaceDidMountNotification object: nil]; + /* Show scan panel ASAP */ + [self performSelectorOnMainThread: @selector(ShowScanPanel:) + withObject: NULL waitUntilDone: NO]; } - (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication *) app { - if( [[fRipRipButton title] compare: _( @"Cancel" ) ] - == NSOrderedSame ) + if( [[fRipButton title] isEqualToString: _( @"Cancel" )] ) { - [self Cancel: self]; + [self Cancel: NULL]; return NSTerminateCancel; } /* Clean up */ - HBClose( &fHandle ); - + hb_close( &fHandle ); return NSTerminateNow; } - (void) awakeFromNib { - /* Strings for the Scan view */ - [fScWelcomeField setStringValue: _( @"Welcome to HandBrake" )]; - [fScSelectField setStringValue: _( @"Select a DVD:" )]; - [fScDetectedCell setTitle: _( @"Detected volume" )]; - [fScDetectedPopUp removeAllItems]; - [fScFolderCell setTitle: _( @"DVD Folder" )]; - [fScBrowseButton setTitle: _( @"Browse" )]; - [fScStatusField setStringValue: @""]; - [fScOpenButton setTitle: _( @"Open" )]; - - /* Strings for the Rip view */ - /* General box */ - [fRipGeneralField setStringValue: _( @"General" )]; - [fRipTitleField setStringValue: _( @"DVD title" )]; - [fRipTitlePopUp removeAllItems]; - [fRipFormatField setStringValue: _( @"Output format" )]; - [fRipFormatPopUp removeAllItems]; - [fRipFormatPopUp addItemWithTitle: - _( @"MP4 file / MPEG-4 video / AAC audio" )]; - [fRipFormatPopUp addItemWithTitle: - _( @"AVI file / MPEG-4 video / MP3 audio" )]; - [fRipFormatPopUp addItemWithTitle: - _( @"AVI file / H264 video / MP3 audio" )]; - [fRipFormatPopUp addItemWithTitle: - _( @"OGM file / MPEG-4 video / Vorbis audio" )]; - [fRipFileField1 setStringValue: _( @"File" )]; - [fRipFileField2 setStringValue: [NSString stringWithFormat: + [fWindow center]; + + [self TranslateStrings]; + + /* Destination box */ + [fDstFormatPopUp removeAllItems]; + [fDstFormatPopUp addItemWithTitle: _( @"MP4 file" )]; + [fDstFormatPopUp addItemWithTitle: _( @"AVI file" )]; + [fDstFormatPopUp addItemWithTitle: _( @"OGM file" )]; + [fDstFormatPopUp selectItemAtIndex: 0]; + + [self FormatPopUpChanged: NULL]; + + [fDstFile2Field setStringValue: [NSString stringWithFormat: @"%@/Desktop/Movie.mp4", NSHomeDirectory()]]; - [fRipBrowseButton setTitle: _( @"Browse" )]; - - /* Video box */ - [fRipVideoField setStringValue: _( @"Video" )]; - [fRipEncoderField setStringValue: _( @"MPEG-4 encoder" )]; - [fRipEncoderPopUp removeAllItems]; - [fRipEncoderPopUp addItemWithTitle: @"FFmpeg"]; - [fRipEncoderPopUp addItemWithTitle: @"XviD"]; - [fRipBitrateField setStringValue: _( @"Bitrate" )]; - [fRipCustomCell setTitle: _( @"Custom (kbps)" )]; - [fRipCustomField setIntValue: 1024]; - [fRipTargetCell setTitle: _( @"Target size (MB)" )]; - [fRipTargetField setIntValue: 700]; - [fRipTwoPassCheck setTitle: _( @"2-pass encoding" )]; - [fRipCropButton setTitle: _( @"Crop & Scale..." )]; - - /* Audio box */ - [fRipAudioField setStringValue: _( @"Audio" )]; - [fRipLang1Field setStringValue: _( @"Language 1" )]; - [fRipLang1PopUp removeAllItems]; - [fRipLang2Field setStringValue: _( @"Language 2 (optional)" )]; - [fRipLang2PopUp removeAllItems]; - [fRipAudBitField setStringValue: _( @"Bitrate (kbps)" )]; - [fRipAudBitPopUp removeAllItems]; - [fRipAudBitPopUp addItemWithTitle: @"32"]; - [fRipAudBitPopUp addItemWithTitle: @"40"]; - [fRipAudBitPopUp addItemWithTitle: @"48"]; - [fRipAudBitPopUp addItemWithTitle: @"56"]; - [fRipAudBitPopUp addItemWithTitle: @"64"]; - [fRipAudBitPopUp addItemWithTitle: @"80"]; - [fRipAudBitPopUp addItemWithTitle: @"96"]; - [fRipAudBitPopUp addItemWithTitle: @"112"]; - [fRipAudBitPopUp addItemWithTitle: @"128"]; - [fRipAudBitPopUp addItemWithTitle: @"160"]; - [fRipAudBitPopUp addItemWithTitle: @"192"]; - [fRipAudBitPopUp addItemWithTitle: @"224"]; - [fRipAudBitPopUp addItemWithTitle: @"256"]; - [fRipAudBitPopUp addItemWithTitle: @"320"]; - [fRipAudBitPopUp selectItemWithTitle: @"128"]; + + /* Video encoder */ + [fVidEncoderPopUp removeAllItems]; + [fVidEncoderPopUp addItemWithTitle: @"FFmpeg"]; + [fVidEncoderPopUp addItemWithTitle: @"XviD"]; + + /* Video quality */ + [fVidTargetSizeField setIntValue: 700]; + [fVidBitrateField setIntValue: 1000]; + [fVidQualityMatrix selectCell: fVidBitrateCell]; + [self VideoMatrixChanged: NULL]; + + /* Video framerate */ + [fVidRatePopUp removeAllItems]; + [fVidRatePopUp addItemWithTitle: _( @"Same as source" )]; + for( int i = 0; i < hb_video_rates_count; i++ ) + { + [fVidRatePopUp addItemWithTitle: + [NSString stringWithCString: hb_video_rates[i].string]]; + } + [fVidRatePopUp selectItemAtIndex: 0]; + + /* Audio bitrate */ + [fAudBitratePopUp removeAllItems]; + for( int i = 0; i < hb_audio_bitrates_count; i++ ) + { + [fAudBitratePopUp addItemWithTitle: + [NSString stringWithCString: hb_audio_bitrates[i].string]]; + } + [fAudBitratePopUp selectItemAtIndex: hb_audio_bitrates_default]; + + /* Audio samplerate */ + [fAudRatePopUp removeAllItems]; + for( int i = 0; i < hb_audio_rates_count; i++ ) + { + [fAudRatePopUp addItemWithTitle: + [NSString stringWithCString: hb_audio_rates[i].string]]; + } + [fAudRatePopUp selectItemAtIndex: hb_audio_rates_default]; /* Bottom */ - [fRipStatusField setStringValue: @""]; - [fRipInfoField setStringValue: @""]; - [fRipPauseButton setTitle: _( @"Pause" )]; - [fRipRipButton setTitle: _( @"Rip" )]; - - /* Strings for the crop panel */ - [fWidthField1 setStringValue: _( @"Picture width" )]; - [fDeinterlaceCheck setTitle: _( @"Deinterlace picture" )]; - [fTopField1 setStringValue: _( @"Top cropping" )]; - [fBottomField1 setStringValue: _( @"Bottom cropping" )]; - [fLeftField1 setStringValue: _( @"Left cropping" )]; - [fRightField1 setStringValue: _( @"Right cropping" )]; - [fPreviousButton setTitle: _( @"Previous" )]; - [fNextButton setTitle: _( @"Next" )]; - [fAutocropButton setTitle: _( @"Autocrop" )]; - [fOpenGLCheck setTitle: _( @"Useless OpenGL effects" )]; - [fInfoField setStringValue: @""]; - [fCloseButton setTitle: _( @"Close" )]; - - [self VideoMatrixChanged: self]; - - /* Show the scan view */ - [fWindow setContentSize: [fScView frame].size]; - [fWindow setContentView: fScView]; - [fWindow center]; + [fStatusField setStringValue: @""]; - /* Detect DVD drives */ - [self DetectDrives: nil]; - [self ScanMatrixChanged: self]; + [self EnableUI: NO]; + [fPauseButton setEnabled: NO]; + [fRipButton setEnabled: NO]; } -- (BOOL) windowShouldClose: (id) sender +- (void) TranslateStrings { - if( [[fRipRipButton title] compare: _( @"Cancel" ) ] - == NSOrderedSame ) + [fSrcDVD1Field setStringValue: _( @"DVD:" )]; + [fSrcTitleField setStringValue: _( @"Title:" )]; + [fSrcChapterField setStringValue: _( @"Chapters:" )]; + [fSrcChapterToField setStringValue: _( @"to" )]; + [fSrcDuration1Field setStringValue: _( @"Duration:" )]; + + [fDstFormatField setStringValue: _( @"File format:" )]; + [fDstCodecsField setStringValue: _( @"Codecs:" )]; + [fDstFile1Field setStringValue: _( @"File:" )]; + [fDstBrowseButton setTitle: _( @"Browse" )]; + + [fVidRateField setStringValue: _( @"Framerate (fps):" )]; + [fVidEncoderField setStringValue: _( @"Encoder:" )]; + [fVidQualityField setStringValue: _( @"Quality:" )]; +} + +/*********************************************************************** + * UpdateDockIcon + *********************************************************************** + * Shows a progression bar on the dock icon, filled according to + * 'progress' (0.0 <= progress <= 1.0). + * Called with progress < 0.0 or progress > 1.0, restores the original + * icon. + **********************************************************************/ +- (void) UpdateDockIcon: (float) progress +{ + NSImage * icon; + NSData * tiff; + NSBitmapImageRep * bmp; + uint32_t * pen; + int row_start, row_end; + int i, j; + + /* Get application original icon */ + icon = [NSImage imageNamed: @"NSApplicationIcon"]; + + if( progress < 0.0 || progress > 1.0 ) { - [self Cancel: self]; - return NO; + [NSApp setApplicationIconImage: icon]; + return; } - /* Stop the application when the user closes the window */ - [NSApp terminate: self]; - return YES; + /* Get it in a raw bitmap form */ + tiff = [icon TIFFRepresentationUsingCompression: + NSTIFFCompressionNone factor: 1.0]; + bmp = [NSBitmapImageRep imageRepWithData: tiff]; + + /* Draw the progression bar */ + /* It's pretty simple (ugly?) now, but I'm no designer */ + + row_start = 3 * (int) [bmp size].height / 4; + row_end = 7 * (int) [bmp size].height / 8; + + for( i = row_start; i < row_start + 2; i++ ) + { + pen = (uint32_t *) ( [bmp bitmapData] + i * [bmp bytesPerRow] ); + for( j = 0; j < (int) [bmp size].width; j++ ) + { + pen[j] = 0x000000FF; /* Black */ + } + } + for( i = row_start + 2; i < row_end - 2; i++ ) + { + pen = (uint32_t *) ( [bmp bitmapData] + i * [bmp bytesPerRow] ); + pen[0] = 0x000000FF; + pen[1] = 0x000000FF; + for( j = 2; j < (int) [bmp size].width - 2; j++ ) + { + if( j < 2 + (int) ( ( [bmp size].width - 4.0 ) * progress ) ) + { + pen[j] = 0xFF0000FF; /* Red */ + } + else + { + pen[j] = 0xFFFFFFFF; /* White */ + } + } + pen[j] = 0x000000FF; + pen[j+1] = 0x000000FF; + } + for( i = row_end - 2; i < row_end; i++ ) + { + pen = (uint32_t *) ( [bmp bitmapData] + i * [bmp bytesPerRow] ); + for( j = 0; j < (int) [bmp size].width; j++ ) + { + pen[j] = 0x000000FF; /* Black */ + } + } + + /* Now update the dock icon */ + tiff = [bmp TIFFRepresentationUsingCompression: + NSTIFFCompressionNone factor: 1.0]; + icon = [[NSImage alloc] initWithData: tiff]; + [NSApp setApplicationIconImage: icon]; + [icon release]; } -- (IBAction) BrowseDVD: (id) sender +- (void) UpdateUI: (NSTimer *) timer { - /* Open a panel to let the user choose and update the text field */ - NSOpenPanel * panel = [NSOpenPanel openPanel]; + hb_state_t s; + hb_get_state( fHandle, &s ); + + switch( s.state ) + { + case HB_STATE_IDLE: + /* If the scan panel is currently showing, recheck for DVD + drives. The clean way would be to use + NSWorkspaceDidMountNotification, but for some reason the + notifications don't work when having the sheet attached */ + if( [fWindow attachedSheet] == fScanPanel ) + { + [fScanController DetectDrives: NULL]; + } + break; - [panel setAllowsMultipleSelection: NO]; - [panel setCanChooseFiles: NO]; - [panel setCanChooseDirectories: YES ]; + case HB_STATE_SCANNING: + [fScanController UpdateUI: &s]; + break; - [panel beginSheetForDirectory: nil file: nil types: nil - modalForWindow: fWindow modalDelegate: self - didEndSelector: @selector( BrowseDVDDone:returnCode:contextInfo: ) - contextInfo: nil]; +#define p s.param.scandone + case HB_STATE_SCANDONE: + { + hb_list_t * list; + hb_title_t * title; + + [fScanController UpdateUI: &s]; + + list = hb_get_titles( fHandle ); + + if( !hb_list_count( list ) ) + { + break; + } + + [fSrcTitlePopUp removeAllItems]; + for( int i = 0; i < hb_list_count( list ); i++ ) + { + title = (hb_title_t *) hb_list_item( list, i ); + [fSrcDVD2Field setStringValue: [NSString + stringWithUTF8String: title->dvd]]; + [fSrcTitlePopUp addItemWithTitle: [NSString + stringWithFormat: @"%d - %02dh%02dm%02ds", + title->index, title->hours, title->minutes, + title->seconds]]; + } + + [self TitlePopUpChanged: NULL]; + [self EnableUI: YES]; + [fPauseButton setEnabled: NO]; + [fRipButton setEnabled: YES]; + break; + } +#undef p + +#define p s.param.working + case HB_STATE_WORKING: + { + float progress_total; + NSMutableString * string; + + /* Update text field */ + string = [NSMutableString stringWithFormat: + _( @"Encoding: task %d of %d, %.2f %%" ), + p.job_cur, p.job_count, 100.0 * p.progress]; + if( p.seconds > -1 ) + { + [string appendFormat: + _( @" (%.2f fps, avg %.2f fps, ETA %02dh%02dm%02ds)" ), + p.rate_cur, p.rate_avg, p.hours, p.minutes, p.seconds]; + } + [fStatusField setStringValue: string]; + + /* Update slider */ + progress_total = ( p.progress + p.job_cur - 1 ) / p.job_count; + [fRipIndicator setDoubleValue: 100.0 * progress_total]; + + /* Update dock icon */ + [self UpdateDockIcon: progress_total]; + + [fPauseButton setEnabled: YES]; + [fPauseButton setTitle: _( @"Pause" )]; + [fRipButton setEnabled: YES]; + [fRipButton setTitle: _( @"Cancel" )]; + break; + } +#undef p + + case HB_STATE_PAUSED: + [fStatusField setStringValue: _( @"Paused" )]; + [fPauseButton setEnabled: YES]; + [fPauseButton setTitle: _( @"Resume" )]; + [fRipButton setEnabled: YES]; + [fRipButton setTitle: _( @"Cancel" )]; + break; + + case HB_STATE_WORKDONE: + { + [self EnableUI: YES]; + [fStatusField setStringValue: _( @"Done." )]; + [fRipIndicator setDoubleValue: 0.0]; + [fRipButton setTitle: _( @"Rip" )]; + + /* Restore dock icon */ + [self UpdateDockIcon: -1.0]; + + [fPauseButton setEnabled: NO]; + [fPauseButton setTitle: _( @"Pause" )]; + [fRipButton setEnabled: YES]; + [fRipButton setTitle: _( @"Rip" )]; + + /* FIXME */ + hb_job_t * job; + while( ( job = hb_job( fHandle, 0 ) ) ) + { + hb_rem( fHandle, job ); + } + break; + } + } + + /* FIXME: we should only do that when necessary */ + if( [fQueueCheck state] == NSOnState ) + { + int count = hb_count( fHandle ); + if( count ) + { + [fQueueCheck setTitle: [NSString stringWithFormat: + @"Enable queue (%d task%s in queue)", + count, ( count > 1 ) ? "s" : ""]]; + } + else + { + [fQueueCheck setTitle: @"Enable queue (no task in queue)"]; + } + } + + [[NSRunLoop currentRunLoop] addTimer: [NSTimer + scheduledTimerWithTimeInterval: 0.2 target: self + selector: @selector( UpdateUI: ) userInfo: NULL repeats: FALSE] + forMode: NSModalPanelRunLoopMode]; } -- (void) BrowseDVDDone: (NSOpenPanel *) sheet - returnCode: (int) returnCode contextInfo: (void *) contextInfo +- (void) EnableUI: (bool) b { - if( returnCode == NSOKButton ) + NSControl * controls[] = + { fSrcDVD1Field, fSrcDVD2Field, fSrcTitleField, fSrcTitlePopUp, + fSrcChapterField, fSrcChapterStartPopUp, fSrcChapterToField, + fSrcChapterEndPopUp, fSrcDuration1Field, fSrcDuration2Field, + fDstFormatField, fDstFormatPopUp, fDstCodecsField, + fDstCodecsPopUp, fDstFile1Field, fDstFile2Field, + fDstBrowseButton, fVidRateField, fVidRatePopUp, + fVidEncoderField, fVidEncoderPopUp, fVidQualityField, + fVidQualityMatrix, fVidGrayscaleCheck, fSubField, fSubPopUp, + fAudLang1Field, fAudLang1PopUp, fAudLang2Field, fAudLang2PopUp, + fAudRateField, fAudRatePopUp, fAudBitrateField, + fAudBitratePopUp, fPictureButton }; + + for( unsigned i = 0; + i < sizeof( controls ) / sizeof( NSControl * ); i++ ) { - [fScFolderField setStringValue: - [[sheet filenames] objectAtIndex: 0]]; + if( [[controls[i] className] isEqualToString: @"NSTextField"] ) + { + NSTextField * tf = (NSTextField *) controls[i]; + if( ![tf isBezeled] ) + { + [tf setTextColor: b ? [NSColor controlTextColor] : + [NSColor disabledControlTextColor]]; + continue; + } + } + [controls[i] setEnabled: b]; } + + [self VideoMatrixChanged: NULL]; +} + +- (IBAction) ShowScanPanel: (id) sender +{ + [NSApp beginSheet: fScanPanel modalForWindow: fWindow + modalDelegate: NULL didEndSelector: NULL contextInfo: NULL]; + [NSApp runModalForWindow: fScanPanel]; + [NSApp endSheet: fScanPanel]; + [fScanPanel orderOut: self]; +} + +- (BOOL) windowShouldClose: (id) sender +{ + /* Stop the application when the user closes the window */ + [NSApp terminate: self]; + return YES; } - (IBAction) VideoMatrixChanged: (id) sender; { - if( ![fRipVideoMatrix isEnabled] ) - { - [fRipCustomField setEnabled: NO]; - [fRipTargetField setEnabled: NO]; - return; - } - - if( ![fRipVideoMatrix selectedRow] ) + bool target, bitrate, quality; + + target = bitrate = quality = false; + if( [fVidQualityMatrix isEnabled] ) { - [fRipCustomField setEnabled: YES]; - [fRipTargetField setEnabled: NO]; + switch( [fVidQualityMatrix selectedRow] ) + { + case 0: + target = true; + break; + case 1: + bitrate = true; + break; + case 2: + quality = true; + break; + } } - else + [fVidTargetSizeField setEnabled: target]; + [fVidBitrateField setEnabled: bitrate]; + [fVidQualitySlider setEnabled: quality]; + [fVidTwoPassCheck setEnabled: !quality && + [fVidQualityMatrix isEnabled]]; + if( quality ) { - [fRipCustomField setEnabled: NO]; - [fRipTargetField setEnabled: YES]; - [fRipTargetField UpdateBitrate]; + [fVidTwoPassCheck setState: NSOffState]; } + + [self QualitySliderChanged: sender]; + [self CalculateBitrate: sender]; +} + +- (IBAction) QualitySliderChanged: (id) sender +{ + [fVidConstantCell setTitle: [NSString stringWithFormat: + _( @"Constant quality: %.0f %%" ), 100.0 * + [fVidQualitySlider floatValue]]]; } - (IBAction) BrowseFile: (id) sender @@ -231,10 +490,10 @@ static void _RipDone( void * data, int result ); /* Open a panel to let the user choose and update the text field */ NSSavePanel * panel = [NSSavePanel savePanel]; - [panel beginSheetForDirectory: nil file: nil + [panel beginSheetForDirectory: NULL file: NULL modalForWindow: fWindow modalDelegate: self didEndSelector: @selector( BrowseFileDone:returnCode:contextInfo: ) - contextInfo: nil]; + contextInfo: NULL]; } - (void) BrowseFileDone: (NSSavePanel *) sheet @@ -242,146 +501,176 @@ static void _RipDone( void * data, int result ); { if( returnCode == NSOKButton ) { - [fRipFileField2 setStringValue: [sheet filename]]; - [self FormatPopUpChanged: self]; - } -} - -- (IBAction) Scan: (id) sender -{ - [fScMatrix setEnabled: NO]; - [fScDetectedPopUp setEnabled: NO]; - [fScFolderField setEnabled: NO]; - [fScBrowseButton setEnabled: NO]; - [fScProgress setIndeterminate: YES]; - [fScProgress startAnimation: self]; - [fScOpenButton setEnabled: NO]; - [fScStatusField setStringValue: _( @"Opening device..." )]; - - /* Ask libhb to start scanning the specified volume */ - if( ![fScMatrix selectedRow] ) - { - /* DVD drive */ - HBScanDVD( fHandle, - [[fScDetectedPopUp titleOfSelectedItem] cString], 0 ); - } - else - { - /* DVD folder */ - HBScanDVD( fHandle, - [[fScFolderField stringValue] cString], 0 ); + [fDstFile2Field setStringValue: [sheet filename]]; + [self FormatPopUpChanged: NULL]; } } - (IBAction) ShowPicturePanel: (id) sender { - HBTitle * title = (HBTitle*) - HBListItemAt( fTitleList, [fRipTitlePopUp indexOfSelectedItem] ); - - [fPictureGLView SetTitle: title]; - - fPicture = 0; - [fPictureGLView ShowPicture: fPicture animate: HB_ANIMATE_NONE]; - - [fWidthStepper setValueWraps: NO]; - [fWidthStepper setIncrement: 16]; - [fWidthStepper setMinValue: 16]; - [fWidthStepper setMaxValue: title->outWidthMax]; - [fWidthStepper setIntValue: title->outWidth]; - [fWidthField2 setIntValue: title->outWidth]; - [fDeinterlaceCheck setState: - title->deinterlace ? NSOnState : NSOffState]; - [fTopStepper setValueWraps: NO]; - [fTopStepper setIncrement: 2]; - [fTopStepper setMinValue: 0]; - [fTopStepper setMaxValue: title->inHeight / 4]; - [fTopStepper setIntValue: title->topCrop]; - [fTopField2 setIntValue: title->topCrop]; - [fBottomStepper setValueWraps: NO]; - [fBottomStepper setIncrement: 2]; - [fBottomStepper setMinValue: 0]; - [fBottomStepper setMaxValue: title->inHeight / 4]; - [fBottomStepper setIntValue: title->bottomCrop]; - [fBottomField2 setIntValue: title->bottomCrop]; - [fLeftStepper setValueWraps: NO]; - [fLeftStepper setIncrement: 2]; - [fLeftStepper setMinValue: 0]; - [fLeftStepper setMaxValue: title->inWidth / 4]; - [fLeftStepper setIntValue: title->leftCrop]; - [fLeftField2 setIntValue: title->leftCrop]; - [fRightStepper setValueWraps: NO]; - [fRightStepper setIncrement: 2]; - [fRightStepper setMinValue: 0]; - [fRightStepper setMaxValue: title->inWidth / 4]; - [fRightStepper setIntValue: title->rightCrop]; - [fRightField2 setIntValue: title->rightCrop]; - - [fPreviousButton setEnabled: NO]; - [fNextButton setEnabled: YES]; - - [fInfoField setStringValue: [NSString stringWithFormat: - _( @"Final size: %dx%d" ), title->outWidth, title->outHeight] ]; + hb_list_t * list = hb_get_titles( fHandle ); + hb_title_t * title = (hb_title_t *) hb_list_item( list, + [fSrcTitlePopUp indexOfSelectedItem] ); /* Resize the panel */ NSSize newSize; - newSize.width = 42 + MAX( 720, title->outWidthMax ); - newSize.height = 165 + title->outHeightMax; + newSize.width = 246 + title->width; + newSize.height = 80 + title->height; [fPicturePanel setContentSize: newSize]; + [fPictureController SetTitle: title]; + [NSApp beginSheet: fPicturePanel modalForWindow: fWindow - modalDelegate: nil didEndSelector: nil contextInfo: nil]; + modalDelegate: NULL didEndSelector: NULL contextInfo: NULL]; [NSApp runModalForWindow: fPicturePanel]; [NSApp endSheet: fPicturePanel]; [fPicturePanel orderOut: self]; } -- (IBAction) ClosePanel: (id) sender +- (IBAction) ShowQueuePanel: (id) sender { - [NSApp stopModal]; + /* Update the OutlineView */ + [fQueueController Update: sender]; + + /* Show the panel */ + [NSApp beginSheet: fQueuePanel modalForWindow: fWindow + modalDelegate: NULL didEndSelector: NULL contextInfo: NULL]; + [NSApp runModalForWindow: fQueuePanel]; + [NSApp endSheet: fQueuePanel]; + [fQueuePanel orderOut: self]; } -- (IBAction) Rip: (id) sender +- (void) PrepareJob { - /* Rip or Cancel ? */ - if( [[fRipRipButton title] compare: _( @"Cancel" ) ] - == NSOrderedSame ) + hb_list_t * list = hb_get_titles( fHandle ); + hb_title_t * title = (hb_title_t *) hb_list_item( list, + [fSrcTitlePopUp indexOfSelectedItem] ); + hb_job_t * job = title->job; + + /* Chapter selection */ + job->chapter_start = [fSrcChapterStartPopUp indexOfSelectedItem] + 1; + job->chapter_end = [fSrcChapterEndPopUp indexOfSelectedItem] + 1; + + /* Format and codecs */ + int format = [fDstFormatPopUp indexOfSelectedItem]; + int codecs = [fDstCodecsPopUp indexOfSelectedItem]; + job->mux = FormatSettings[format][codecs] & HB_MUX_MASK; + job->vcodec = FormatSettings[format][codecs] & HB_VCODEC_MASK; + job->acodec = FormatSettings[format][codecs] & HB_ACODEC_MASK; + + if( ( job->vcodec & HB_VCODEC_FFMPEG ) && + [fVidEncoderPopUp indexOfSelectedItem] > 0 ) { - [self Cancel: self]; - return; + job->vcodec = HB_VCODEC_XVID; + } + if( job->vcodec & HB_VCODEC_X264 ) + { + job->h264_13 = [fVidEncoderPopUp indexOfSelectedItem]; } - if( [fRipCustomField intValue] < 64 ) + /* Video settings */ + if( [fVidRatePopUp indexOfSelectedItem] > 0 ) { - NSBeginCriticalAlertSheet( _( @"Invalid video bitrate" ), - _( @"Ooops" ), nil, nil, fWindow, self, nil, nil, nil, - _( @"Video bitrate is too low." ) ); - return; + job->vrate = 27000000; + job->vrate_base = hb_video_rates[[fVidRatePopUp + indexOfSelectedItem]-1].rate; } - if( [fRipCustomField intValue] > 8192 ) + else { - NSBeginCriticalAlertSheet( _( @"Invalid video bitrate" ), - _( @"Ooops" ), nil, nil, fWindow, self, nil, nil, nil, - _( @"Video bitrate is too high." ) ); - return; + job->vrate = title->rate; + job->vrate_base = title->rate_base; } - if( [fRipLang1PopUp indexOfSelectedItem] == - [fRipLang2PopUp indexOfSelectedItem] ) + + switch( [fVidQualityMatrix selectedRow] ) { - NSBeginCriticalAlertSheet( _( @"Invalid secondary language" ), - _( @"Ooops" ), nil, nil, fWindow, self, nil, nil, nil, - _( @"You can't encode the same audio track twice." ) ); + case 0: + /* Target size. + Bitrate should already have been calculated and displayed + in fVidBitrateField, so let's just use it */ + case 1: + job->vquality = -1.0; + job->vbitrate = [fVidBitrateField intValue]; + break; + case 2: + job->vquality = [fVidQualitySlider floatValue]; + job->vbitrate = 0; + break; + } + + job->grayscale = ( [fVidGrayscaleCheck state] == NSOnState ); + + /* Subtitle settings */ + job->subtitle = [fSubPopUp indexOfSelectedItem] - 1; + + /* Audio tracks */ + job->audios[0] = [fAudLang1PopUp indexOfSelectedItem] - 1; + job->audios[1] = [fAudLang2PopUp indexOfSelectedItem] - 1; + job->audios[2] = -1; + + /* Audio settings */ + job->arate = hb_audio_rates[[fAudRatePopUp + indexOfSelectedItem]].rate; + job->abitrate = hb_audio_bitrates[[fAudBitratePopUp + indexOfSelectedItem]].rate; +} + +- (IBAction) EnableQueue: (id) sender +{ + bool e = ( [fQueueCheck state] == NSOnState ); + [fQueueAddButton setHidden: !e]; + [fQueueShowButton setHidden: !e]; + [fRipButton setTitle: e ? @"Start" : @"Rip"]; +} + +- (IBAction) AddToQueue: (id) sender +{ + hb_list_t * list = hb_get_titles( fHandle ); + hb_title_t * title = (hb_title_t *) hb_list_item( list, + [fSrcTitlePopUp indexOfSelectedItem] ); + hb_job_t * job = title->job; + + [self PrepareJob]; + + /* Destination file */ + job->file = strdup( [[fDstFile2Field stringValue] UTF8String] ); + + if( [fVidTwoPassCheck state] == NSOnState ) + { + job->pass = 1; + hb_add( fHandle, job ); + job->pass = 2; + hb_add( fHandle, job ); + } + else + { + job->pass = 0; + hb_add( fHandle, job ); + } +} + +- (IBAction) Rip: (id) sender +{ + /* Rip or Cancel ? */ + if( [[fRipButton title] isEqualToString: _( @"Cancel" )] ) + { + [self Cancel: sender]; return; } + if( [fQueueCheck state] == NSOffState ) + { + [self AddToQueue: sender]; + } + if( [[NSFileManager defaultManager] fileExistsAtPath: - [fRipFileField2 stringValue]] ) + [fDstFile2Field stringValue]] ) { NSBeginCriticalAlertSheet( _( @"File already exists" ), - _( @"No" ), _( @"Yes" ), nil, fWindow, self, + _( @"Cancel" ), _( @"Overwrite" ), NULL, fWindow, self, @selector( OverwriteAlertDone:returnCode:contextInfo: ), - nil, nil, [NSString stringWithFormat: + NULL, NULL, [NSString stringWithFormat: _( @"Do you want to overwrite %@?" ), - [fRipFileField2 stringValue]] ); + [fDstFile2Field stringValue]] ); return; } @@ -397,70 +686,38 @@ static void _RipDone( void * data, int result ); } } -- (void) _Rip +- (void) UpdateAlertDone: (NSWindow *) sheet + returnCode: (int) returnCode contextInfo: (void *) contextInfo { - /* Get the specified title & audio track(s) */ - HBTitle * title = (HBTitle*) HBListItemAt( fTitleList, - [fRipTitlePopUp indexOfSelectedItem] ); - HBAudio * audio1 = (HBAudio*) HBListItemAt( title->audioList, - [fRipLang1PopUp indexOfSelectedItem] ); - HBAudio * audio2 = (HBAudio*) HBListItemAt( title->audioList, - [fRipLang2PopUp indexOfSelectedItem] ); - - /* Use user settings */ - title->file = strdup( [[fRipFileField2 stringValue] cString] ); - title->bitrate = [fRipCustomField intValue]; - title->twoPass = ( [fRipTwoPassCheck state] == NSOnState ); - - int format = [fRipFormatPopUp indexOfSelectedItem]; - int codec = [fRipEncoderPopUp indexOfSelectedItem]; - title->mux = ( !format ) ? HB_MUX_MP4 : ( ( format == 3 ) ? - HB_MUX_OGM : HB_MUX_AVI ); - title->codec = ( format == 2 ) ? HB_CODEC_X264 : ( ( !codec ) ? - HB_CODEC_FFMPEG : HB_CODEC_XVID ); - - audio1->outBitrate = [[fRipAudBitPopUp titleOfSelectedItem] - intValue]; - audio1->outCodec = ( !format ) ? HB_CODEC_AAC : ( ( format == 3 ) ? - HB_CODEC_VORBIS : HB_CODEC_MP3 );; - HBListAdd( title->ripAudioList, audio1 ); - if( audio2 ) - { - audio2->outBitrate = [[fRipAudBitPopUp - titleOfSelectedItem] intValue]; - audio2->outCodec = ( !format ) ? HB_CODEC_AAC : ( ( format == 3 ) ? - HB_CODEC_VORBIS : HB_CODEC_MP3 ); - HBListAdd( title->ripAudioList, audio2 ); + if( returnCode == NSAlertAlternateReturn ) + { + /* Show scan panel */ + [self performSelectorOnMainThread: @selector(ShowScanPanel:) + withObject: NULL waitUntilDone: NO]; + return; } - /* Disable interface */ - [fRipTitlePopUp setEnabled: NO]; - [fRipFormatPopUp setEnabled: NO]; - [fRipVideoMatrix setEnabled: NO]; - [fRipCustomField setEnabled: NO]; - [fRipTargetField setEnabled: NO]; - [fRipTwoPassCheck setEnabled: NO]; - [fRipCropButton setEnabled: NO]; - [fRipLang1PopUp setEnabled: NO]; - [fRipLang2PopUp setEnabled: NO]; - [fRipAudBitPopUp setEnabled: NO]; - [fRipFileField2 setEnabled: NO]; - [fRipEncoderPopUp setEnabled: NO]; - [fRipBrowseButton setEnabled: NO]; - [fRipPauseButton setEnabled: YES]; - [fRipRipButton setTitle: _( @"Cancel" )]; - [fRipProgress setIndeterminate: YES]; - [fRipProgress startAnimation: self];; + /* Go to HandBrake homepage and exit */ + [self OpenHomepage: NULL]; + [NSApp terminate: self]; +} +- (void) _Rip +{ /* Let libhb do the job */ - HBStartRip( fHandle, title ); + hb_start( fHandle ); + + /* Disable interface */ + [self EnableUI: NO]; + [fPauseButton setEnabled: NO]; + [fRipButton setEnabled: NO]; } - (IBAction) Cancel: (id) sender { NSBeginCriticalAlertSheet( _( @"Cancel - Are you sure?" ), - _( @"No" ), _( @"Yes" ), nil, fWindow, self, - @selector( _Cancel:returnCode:contextInfo: ), nil, nil, + _( @"Keep working" ), _( @"Cancel encoding" ), NULL, fWindow, self, + @selector( _Cancel:returnCode:contextInfo: ), NULL, NULL, _( @"Encoding won't be recoverable." ) ); } @@ -469,500 +726,241 @@ static void _RipDone( void * data, int result ); { if( returnCode == NSAlertAlternateReturn ) { - if( [[fRipPauseButton title] compare: _( @"Resume" ) ] - == NSOrderedSame ) - { - HBResumeRip( fHandle ); - } - HBStopRip( fHandle ); + hb_stop( fHandle ); + [fPauseButton setEnabled: NO]; + [fRipButton setEnabled: NO]; } } - (IBAction) Pause: (id) sender { - if( [[fRipPauseButton title] compare: _( @"Resume" ) ] - == NSOrderedSame ) - { - [self Resume: self]; - return; - } - - [fRipPauseButton setTitle: _( @"Resume" )]; - HBPauseRip( fHandle ); -} - -- (IBAction) Resume: (id) sender -{ - [fRipPauseButton setTitle: _( @"Pause" )]; - HBResumeRip( fHandle ); -} - -- (IBAction) PreviousPicture: (id) sender -{ - fPicture--; - if( [fOpenGLCheck state] == NSOnState ) - { - [fPictureGLView ShowPicture: fPicture - animate: HB_ANIMATE_LEFT]; - } - else - { - [fPictureGLView ShowPicture: fPicture - animate: HB_ANIMATE_NONE]; - } - - [fPreviousButton setEnabled: ( fPicture > 0 )]; - [fNextButton setEnabled: YES]; -} + [fPauseButton setEnabled: NO]; + [fRipButton setEnabled: NO]; -- (IBAction) NextPicture: (id) sender -{ - fPicture++; - if( [fOpenGLCheck state] == NSOnState ) + if( [[fPauseButton title] isEqualToString: _( @"Resume" )] ) { - [fPictureGLView ShowPicture: fPicture - animate: HB_ANIMATE_RIGHT]; + hb_resume( fHandle ); } else { - [fPictureGLView ShowPicture: fPicture - animate: HB_ANIMATE_NONE]; + hb_pause( fHandle ); } - - [fPreviousButton setEnabled: YES]; - [fNextButton setEnabled: ( fPicture < 9 )]; } -- (IBAction) UpdatePicture: (id) sender -{ - HBTitle * title = (HBTitle*) - HBListItemAt( fTitleList, [fRipTitlePopUp indexOfSelectedItem] ); - title->outWidth = [fWidthStepper intValue]; - title->deinterlace = ( [fDeinterlaceCheck state] == NSOnState ); - title->topCrop = [fTopStepper intValue]; - title->bottomCrop = [fBottomStepper intValue]; - title->leftCrop = [fLeftStepper intValue]; - title->rightCrop = [fRightStepper intValue]; - - [fPictureGLView ShowPicture: fPicture animate: HB_ANIMATE_NONE]; - - [fWidthStepper setIntValue: title->outWidth]; - [fTopStepper setIntValue: title->topCrop]; - [fBottomStepper setIntValue: title->bottomCrop]; - [fLeftStepper setIntValue: title->leftCrop]; - [fRightStepper setIntValue: title->rightCrop]; - [fWidthField2 setIntValue: [fWidthStepper intValue]]; - [fTopField2 setIntValue: [fTopStepper intValue]]; - [fBottomField2 setIntValue: [fBottomStepper intValue]]; - [fLeftField2 setIntValue: [fLeftStepper intValue]]; - [fRightField2 setIntValue: [fRightStepper intValue]]; - - [fInfoField setStringValue: [NSString stringWithFormat: - _( @"Final size: %dx%d" ), title->outWidth, title->outHeight]]; -} - -- (IBAction) AutoCrop: (id) sender -{ - HBTitle * title = (HBTitle*) - HBListItemAt( fTitleList, [fRipTitlePopUp indexOfSelectedItem] ); - title->topCrop = title->autoTopCrop; - title->bottomCrop = title->autoBottomCrop; - title->leftCrop = title->autoLeftCrop; - title->rightCrop = title->autoRightCrop; - - [fPictureGLView ShowPicture: fPicture animate: HB_ANIMATE_NONE]; - - [fWidthStepper setIntValue: title->outWidth]; - [fTopStepper setIntValue: title->topCrop]; - [fBottomStepper setIntValue: title->bottomCrop]; - [fLeftStepper setIntValue: title->leftCrop]; - [fRightStepper setIntValue: title->rightCrop]; - [fWidthField2 setIntValue: [fWidthStepper intValue]]; - [fTopField2 setIntValue: [fTopStepper intValue]]; - [fBottomField2 setIntValue: [fBottomStepper intValue]]; - [fLeftField2 setIntValue: [fLeftStepper intValue]]; - [fRightField2 setIntValue: [fRightStepper intValue]]; - - [fInfoField setStringValue: [NSString stringWithFormat: - _( @"Final size: %dx%d" ), title->outWidth, title->outHeight]]; -} - -- (void) DetectDrives: (NSNotification *) notification +- (IBAction) TitlePopUpChanged: (id) sender { - /* Scan DVD drives (stolen from VLC) */ - io_object_t next_media; - mach_port_t master_port; - kern_return_t kern_result; - io_iterator_t media_iterator; - CFMutableDictionaryRef classes_to_match; - - kern_result = IOMasterPort( MACH_PORT_NULL, &master_port ); - if( kern_result != KERN_SUCCESS ) - { - return; - } + hb_list_t * list = hb_get_titles( fHandle ); + hb_title_t * title = (hb_title_t*) + hb_list_item( list, [fSrcTitlePopUp indexOfSelectedItem] ); - classes_to_match = IOServiceMatching( kIODVDMediaClass ); - if( classes_to_match == NULL ) + /* Update chapter popups */ + [fSrcChapterStartPopUp removeAllItems]; + [fSrcChapterEndPopUp removeAllItems]; + for( int i = 0; i < hb_list_count( title->list_chapter ); i++ ) { - return; + [fSrcChapterStartPopUp addItemWithTitle: [NSString + stringWithFormat: @"%d", i + 1]]; + [fSrcChapterEndPopUp addItemWithTitle: [NSString + stringWithFormat: @"%d", i + 1]]; } + [fSrcChapterStartPopUp selectItemAtIndex: 0]; + [fSrcChapterEndPopUp selectItemAtIndex: + hb_list_count( title->list_chapter ) - 1]; + [self ChapterPopUpChanged: NULL]; - CFDictionarySetValue( classes_to_match, CFSTR( kIOMediaEjectableKey ), - kCFBooleanTrue ); - - kern_result = - IOServiceGetMatchingServices( master_port, classes_to_match, - &media_iterator ); - if( kern_result != KERN_SUCCESS ) + /* Update subtitle popups */ + hb_subtitle_t * subtitle; + [fSubPopUp removeAllItems]; + [fSubPopUp addItemWithTitle: @"None"]; + for( int i = 0; i < hb_list_count( title->list_subtitle ); i++ ) { - return; - } - - NSMutableArray * drivesList; - drivesList = [NSMutableArray arrayWithCapacity: 1]; - - next_media = IOIteratorNext( media_iterator ); - if( next_media != NULL ) - { - char psz_buf[0x32]; - size_t dev_path_length; - CFTypeRef str_bsd_path; - do - { - str_bsd_path = - IORegistryEntryCreateCFProperty( next_media, - CFSTR( kIOBSDNameKey ), - kCFAllocatorDefault, - 0 ); - if( str_bsd_path == NULL ) - { - IOObjectRelease( next_media ); - continue; - } + subtitle = (hb_subtitle_t *) hb_list_item( title->list_subtitle, i ); - snprintf( psz_buf, sizeof(psz_buf), "%s%c", _PATH_DEV, 'r' ); - dev_path_length = strlen( psz_buf ); - - if( CFStringGetCString( (CFStringRef) str_bsd_path, - (char*)&psz_buf + dev_path_length, - sizeof(psz_buf) - dev_path_length, - kCFStringEncodingASCII ) ) - { - [drivesList addObject: - [NSString stringWithCString: psz_buf]]; - } - - CFRelease( str_bsd_path ); - - IOObjectRelease( next_media ); - - } while( ( next_media = IOIteratorNext( media_iterator ) ) != NULL ); + /* We cannot use NSPopUpButton's addItemWithTitle because + it checks for duplicate entries */ + [[fSubPopUp menu] addItemWithTitle: [NSString stringWithCString: + subtitle->lang] action: NULL keyEquivalent: @""]; } + [fSubPopUp selectItemAtIndex: 0]; - IOObjectRelease( media_iterator ); - - [fScDetectedPopUp removeAllItems]; - for( unsigned i = 0; i < [drivesList count]; i++ ) + /* Update lang popups */ + hb_audio_t * audio; + [fAudLang1PopUp removeAllItems]; + [fAudLang2PopUp removeAllItems]; + [fAudLang1PopUp addItemWithTitle: _( @"None" )]; + [fAudLang2PopUp addItemWithTitle: _( @"None" )]; + for( int i = 0; i < hb_list_count( title->list_audio ); i++ ) { - [[fScDetectedPopUp menu] addItemWithTitle: - [drivesList objectAtIndex: i] action: nil - keyEquivalent: @""]; - } - [self ScanMatrixChanged: self]; -} + audio = (hb_audio_t *) hb_list_item( title->list_audio, i ); -- (IBAction) ScanMatrixChanged: (id) sender -{ - if( ![fScMatrix selectedRow] ) - { - [fScDetectedPopUp setEnabled: YES]; - [fScFolderField setEnabled: NO]; - [fScBrowseButton setEnabled: NO]; - [fScOpenButton setEnabled: ( [fScDetectedPopUp selectedItem] != nil )]; - } - else - { - [fScDetectedPopUp setEnabled: NO]; - [fScFolderField setEnabled: YES]; - [fScBrowseButton setEnabled: YES]; - [fScOpenButton setEnabled: YES]; + [[fAudLang1PopUp menu] addItemWithTitle: + [NSString stringWithCString: audio->lang] + action: NULL keyEquivalent: @""]; + [[fAudLang2PopUp menu] addItemWithTitle: + [NSString stringWithCString: audio->lang] + action: NULL keyEquivalent: @""]; } + [fAudLang1PopUp selectItemAtIndex: 1]; + [fAudLang2PopUp selectItemAtIndex: 0]; } -- (IBAction) TitlePopUpChanged: (id) sender +- (IBAction) ChapterPopUpChanged: (id) sender { - HBTitle * title = (HBTitle*) - HBListItemAt( fTitleList, [fRipTitlePopUp indexOfSelectedItem] ); + hb_list_t * list = hb_get_titles( fHandle ); + hb_title_t * title = (hb_title_t *) + hb_list_item( list, [fSrcTitlePopUp indexOfSelectedItem] ); - [fRipLang1PopUp removeAllItems]; - [fRipLang2PopUp removeAllItems]; - - HBAudio * audio; - for( int i = 0; i < HBListCount( title->audioList ); i++ ) + hb_chapter_t * chapter; + int64_t duration = 0; + for( int i = [fSrcChapterStartPopUp indexOfSelectedItem]; + i <= [fSrcChapterEndPopUp indexOfSelectedItem]; i++ ) { - audio = (HBAudio*) HBListItemAt( title->audioList, i ); - - /* We cannot use NSPopUpButton's addItemWithTitle because - it checks for duplicate entries */ - [[fRipLang1PopUp menu] addItemWithTitle: - [NSString stringWithCString: audio->language] - action: nil keyEquivalent: @""]; - [[fRipLang2PopUp menu] addItemWithTitle: - [NSString stringWithCString: audio->language] - action: nil keyEquivalent: @""]; + chapter = (hb_chapter_t *) hb_list_item( title->list_chapter, i ); + duration += chapter->duration; } - [fRipLang2PopUp addItemWithTitle: _( @"None" )]; - [fRipLang2PopUp selectItemWithTitle: _( @"None" )]; - [fRipLang2PopUp setEnabled: - ( HBListCount( title->audioList ) > 1 )]; + + duration /= 90000; /* pts -> seconds */ + [fSrcDuration2Field setStringValue: [NSString stringWithFormat: + @"%02lld:%02lld:%02lld", duration / 3600, ( duration / 60 ) % 60, + duration % 60]]; - [fRipTargetField SetHBTitle: title]; - if( [fRipVideoMatrix selectedRow] ) - { - [fRipTargetField UpdateBitrate]; - } + [self CalculateBitrate: sender]; } - (IBAction) FormatPopUpChanged: (id) sender { - /* Headers size changes depending on the format, so let's - recalculate the bitrate if necessary */ - if( [fRipVideoMatrix selectedRow] ) + NSString * string = [fDstFile2Field stringValue]; + int format = [fDstFormatPopUp indexOfSelectedItem]; + char * ext = NULL; + + /* Update the codecs popup */ + [fDstCodecsPopUp removeAllItems]; + switch( format ) { - [fRipTargetField UpdateBitrate]; + case 0: + ext = "mp4"; + [fDstCodecsPopUp addItemWithTitle: + _( @"MPEG-4 Video / AAC Audio" )]; + [fDstCodecsPopUp addItemWithTitle: + _( @"AVC/H.264 Video / AAC Audio" )]; + break; + case 1: + ext = "avi"; + [fDstCodecsPopUp addItemWithTitle: + _( @"MPEG-4 Video / MP3 Audio" )]; + [fDstCodecsPopUp addItemWithTitle: + _( @"MPEG-4 Video / AC-3 Audio" )]; + [fDstCodecsPopUp addItemWithTitle: + _( @"AVC/H.264 Video / MP3 Audio" )]; + [fDstCodecsPopUp addItemWithTitle: + _( @"AVC/H.264 Video / AC-3 Audio" )]; + break; + case 2: + ext = "ogm"; + [fDstCodecsPopUp addItemWithTitle: + _( @"MPEG-4 Video / Vorbis Audio" )]; + [fDstCodecsPopUp addItemWithTitle: + _( @"MPEG-4 Video / MP3 Audio" )]; + break; } + [self CodecsPopUpChanged: NULL]; /* Add/replace to the correct extension */ - NSString * string = [fRipFileField2 stringValue]; - int format = [fRipFormatPopUp indexOfSelectedItem]; if( [string characterAtIndex: [string length] - 4] == '.' ) { - [fRipFileField2 setStringValue: [NSString stringWithFormat: + [fDstFile2Field setStringValue: [NSString stringWithFormat: @"%@.%s", [string substringToIndex: [string length] - 4], - ( !format ) ? "mp4" : ( ( format == 3 ) ? - "ogm" : "avi" )]]; + ext]]; } else { - [fRipFileField2 setStringValue: [NSString stringWithFormat: - @"%@.%s", string, ( !format ) ? "mp4" : - ( ( format == 3 ) ? "ogm" : "avi" )]]; + [fDstFile2Field setStringValue: [NSString stringWithFormat: + @"%@.%s", string, ext]]; } +} - if( format == 2 ) +- (IBAction) CodecsPopUpChanged: (id) sender +{ + int format = [fDstFormatPopUp indexOfSelectedItem]; + int codecs = [fDstCodecsPopUp indexOfSelectedItem]; + + /* Update the encoder popup if necessary */ + if( ( FormatSettings[format][codecs] & HB_VCODEC_X264 ) && + [fVidEncoderPopUp numberOfItems] > 1 ) { - /* Can't set X264 bitrate */ - [fRipEncoderPopUp setEnabled: NO]; - [fRipVideoMatrix setEnabled: NO]; - [fRipTwoPassCheck setEnabled: NO]; + /* MPEG-4 -> H.264 */ + [fVidEncoderPopUp removeAllItems]; + [fVidEncoderPopUp addItemWithTitle: @"x264 (Main profile)"]; + [fVidEncoderPopUp addItemWithTitle: @"x264 (Baseline profile)"]; } - else if( format == 3 ) + else if( ( FormatSettings[format][codecs] & HB_VCODEC_FFMPEG ) && + [fVidEncoderPopUp numberOfItems] < 2 ) + { + /* H.264 -> MPEG-4 */ + [fVidEncoderPopUp removeAllItems]; + [fVidEncoderPopUp addItemWithTitle: @"FFmpeg"]; + [fVidEncoderPopUp addItemWithTitle: @"XviD"]; + [fVidEncoderPopUp selectItemAtIndex: 0]; + } + + if( FormatSettings[format][codecs] & HB_ACODEC_AC3 ) { - [fRipEncoderPopUp setEnabled: YES]; - [fRipVideoMatrix setEnabled: YES]; - [fRipTwoPassCheck setEnabled: YES]; + /* AC-3 pass-through: disable samplerate and bitrate */ + [fAudRatePopUp setEnabled: NO]; + [fAudBitratePopUp setEnabled: NO]; } else { - [fRipEncoderPopUp setEnabled: YES]; - [fRipVideoMatrix setEnabled: YES]; - [fRipTwoPassCheck setEnabled: YES]; + [fAudRatePopUp setEnabled: YES]; + [fAudBitratePopUp setEnabled: YES]; } - [self VideoMatrixChanged: self]; + + [self CalculateBitrate: sender]; } -- (IBAction) AudioPopUpChanged: (id) sender +- (IBAction) CalculateBitrate: (id) sender { - /* Recalculate the bitrate */ - if( [fRipVideoMatrix selectedRow] ) + if( !fHandle || [fVidQualityMatrix selectedRow] != 0 ) { - [fRipTargetField UpdateBitrate]; + return; } + + hb_list_t * list = hb_get_titles( fHandle ); + hb_title_t * title = (hb_title_t *) hb_list_item( list, + [fSrcTitlePopUp indexOfSelectedItem] ); + hb_job_t * job = title->job; + + [self PrepareJob]; + + [fVidBitrateField setIntValue: hb_calc_bitrate( job, + [fVidTargetSizeField intValue] )]; } -/******************* - * libhb callbacks * - *******************/ -static void _Scanning( void * data, int title, int titleCount ) +- (void) controlTextDidBeginEditing: (NSNotification *) notification { - HBController * controller = (HBController*) data; - controller->fTitle = title; - controller->fTitleCount = titleCount; - [controller performSelectorOnMainThread: @selector(Scanning:) - withObject: nil waitUntilDone: YES]; + [self CalculateBitrate: NULL]; } -- (void) Scanning: (id) sender -{ - [fScProgress stopAnimation: self]; - [fScProgress setIndeterminate: NO]; - [fScProgress setDoubleValue: 100.0 * fTitle / fTitleCount]; - [fScStatusField setStringValue: [NSString stringWithFormat: - _( @"Scanning title %d of %d..." ), fTitle, fTitleCount]]; +- (void) controlTextDidEndEditing: (NSNotification *) notification +{ + [self CalculateBitrate: NULL]; } -static void _ScanDone( void * data, HBList * titleList ) +- (void) controlTextDidChange: (NSNotification *) notification { - HBController * controller = (HBController*) data; - controller->fTitleList = titleList; - [controller performSelectorOnMainThread: @selector(ScanDone:) - withObject: nil waitUntilDone: YES]; + [self CalculateBitrate: NULL]; } -- (void) ScanDone: (id) sender + +- (IBAction) OpenHomepage: (id) sender { - if( !fTitleList ) - { - [fScMatrix setEnabled: YES]; - [self ScanMatrixChanged: self]; - [fScProgress stopAnimation: self]; - [fScProgress setIndeterminate: NO]; - [fScOpenButton setEnabled: YES]; - [fScStatusField setStringValue: - _( @"Invalid volume, try again" ) ]; - return; - } + [[NSWorkspace sharedWorkspace] openURL: [NSURL + URLWithString:@"http://handbrake.m0k.org/"]]; +} - /* Show a temporary empty view while the window - resizing animation */ - [fWindow setContentView: fTempView ]; - - /* Actually resize it */ - NSRect newFrame; - newFrame = [NSWindow contentRectForFrameRect: [fWindow frame] - styleMask: [fWindow styleMask]]; - newFrame.origin.y += newFrame.size.height - - [fRipView frame].size.height; - newFrame.size.height = [fRipView frame].size.height; - newFrame.size.width = [fRipView frame].size.width; - newFrame = [NSWindow frameRectForContentRect: newFrame - styleMask: [fWindow styleMask]]; - [fWindow setFrame: newFrame display: YES animate: YES]; - - /* Show the new GUI */ - [fWindow setContentView: fRipView ]; - [fRipPauseButton setEnabled: NO]; - - [fRipTitlePopUp removeAllItems]; - HBTitle * title; - for( int i = 0; i < HBListCount( fTitleList ); i++ ) - { - title = (HBTitle*) HBListItemAt( fTitleList, i ); - [[fRipTitlePopUp menu] addItemWithTitle: - [NSString stringWithFormat: @"%d - %02dh%02dm%02ds", - title->title, title->hours, title->minutes, - title->seconds] action: nil keyEquivalent: @""]; - } - [self TitlePopUpChanged: self]; -} - -static void _Encoding( void * data, float position, int pass, - int passCount, float curFrameRate, - float avgFrameRate, int remainingTime ) -{ - HBController * controller = (HBController*) data; - controller->fPosition = position; - controller->fPass = pass; - controller->fPassCount = passCount; - controller->fCurFrameRate = curFrameRate; - controller->fAvgFrameRate = avgFrameRate; - controller->fRemainingTime = remainingTime; - [controller performSelectorOnMainThread: @selector(Encoding:) - withObject: nil waitUntilDone: YES]; -} -- (void) Encoding: (id) sender -{ - [fRipStatusField setStringValue: [NSString stringWithFormat: - _( @"Encoding: %.2f %% (pass %d of %d)" ), - 100.0 * fPosition, fPass, fPassCount]]; - [fRipInfoField setStringValue: [NSString stringWithFormat: - _( @"Speed: %.2f fps (avg %.2f fps), %02dh%02dm%02ds remaining" ), - fCurFrameRate, fAvgFrameRate, fRemainingTime / 3600, - ( fRemainingTime / 60 ) % 60, fRemainingTime % 60]]; - - [fRipProgress setIndeterminate: NO]; - [fRipProgress setDoubleValue: 100.0 * fPosition]; -} - -static void _RipDone( void * data, int result ) -{ - HBController * controller = (HBController*) data; - controller->fResult = result; - [controller performSelectorOnMainThread: @selector(RipDone:) - withObject: nil waitUntilDone: YES]; -} -- (void) RipDone: (id) sender -{ - [fRipTitlePopUp setEnabled: YES]; - [fRipFormatPopUp setEnabled: YES]; - [fRipVideoMatrix setEnabled: YES]; - [fRipTwoPassCheck setEnabled: YES]; - [fRipCropButton setEnabled: YES]; - [fRipLang1PopUp setEnabled: YES]; - [fRipLang2PopUp setEnabled: YES]; - [fRipAudBitPopUp setEnabled: YES]; - [fRipFileField2 setEnabled: YES]; - [fRipBrowseButton setEnabled: YES]; - [fRipEncoderPopUp setEnabled: YES]; - [fRipPauseButton setEnabled: NO]; - [fRipPauseButton setTitle: _( @"Pause" )]; - [fRipRipButton setTitle: _( @"Rip" )]; - [fRipProgress setIndeterminate: NO]; - [fRipProgress setDoubleValue: 0.0]; - [self VideoMatrixChanged: self]; - - switch( fResult ) - { - case HB_SUCCESS: - [fRipStatusField setStringValue: _( @"Rip completed." )]; - [fRipInfoField setStringValue: @""]; - NSBeep(); - [NSApp requestUserAttention: NSInformationalRequest]; - [NSApp beginSheet: fDonePanel - modalForWindow: fWindow modalDelegate: nil - didEndSelector: nil contextInfo: nil]; - [NSApp runModalForWindow: fDonePanel]; - [NSApp endSheet: fDonePanel]; - [fDonePanel orderOut: self]; - break; - case HB_CANCELED: - [fRipStatusField setStringValue: _( @"Canceled." )]; - [fRipInfoField setStringValue: @""]; - break; - case HB_ERROR_A52_SYNC: - [fRipStatusField setStringValue: @"Error."]; - [fRipInfoField setStringValue: @"Corrupted AC3 data"]; - break; - case HB_ERROR_AVI_WRITE: - [fRipStatusField setStringValue: @"Error."]; - [fRipInfoField setStringValue: @"Write error"]; - break; - case HB_ERROR_DVD_OPEN: - [fRipStatusField setStringValue: @"Error."]; - [fRipInfoField setStringValue: @"Could not open the DVD"]; - break; - case HB_ERROR_DVD_READ: - [fRipStatusField setStringValue: @"Error."]; - [fRipInfoField setStringValue: @"DVD read error"]; - break; - case HB_ERROR_MP3_INIT: - [fRipStatusField setStringValue: @"Error."]; - [fRipInfoField setStringValue: - @"MP3 encoder initialization failed"]; - break; - case HB_ERROR_MP3_ENCODE: - [fRipStatusField setStringValue: @"Error."]; - [fRipInfoField setStringValue: @"MP3 encoder failed"]; - break; - case HB_ERROR_MPEG4_INIT: - [fRipStatusField setStringValue: @"Error."]; - [fRipInfoField setStringValue: - @"MPEG4 encoder initialization failed"]; - break; - default: - [fRipStatusField setStringValue: @"Error."]; - [fRipInfoField setStringValue: @"Unknown error"]; - } +- (IBAction) OpenForums: (id) sender +{ + [[NSWorkspace sharedWorkspace] openURL: [NSURL + URLWithString:@"http://handbrake.m0k.org/forum/"]]; } @end diff --git a/macosx/English.lproj/MainMenu.nib/classes.nib b/macosx/English.lproj/MainMenu.nib/classes.nib index b77248ae6..59629f07f 100644 --- a/macosx/English.lproj/MainMenu.nib/classes.nib +++ b/macosx/English.lproj/MainMenu.nib/classes.nib @@ -3,102 +3,85 @@ {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, { ACTIONS = { - AudioPopUpChanged = id; - AutoCrop = id; - BrowseDVD = id; + AddToQueue = id; BrowseFile = id; + CalculateBitrate = id; Cancel = id; - ClosePanel = id; - Encoding = id; + ChapterPopUpChanged = id; + CodecsPopUpChanged = id; + EnableQueue = id; FormatPopUpChanged = id; - NextPicture = id; + OpenForums = id; + OpenHomepage = id; Pause = id; - PreviousPicture = id; - Resume = id; + QualitySliderChanged = id; Rip = id; - RipDone = id; - Scan = id; - ScanDone = id; - ScanMatrixChanged = id; - Scanning = id; ShowPicturePanel = id; + ShowQueuePanel = id; + ShowScanPanel = id; TitlePopUpChanged = id; - UpdatePicture = id; VideoMatrixChanged = id; }; CLASS = HBController; LANGUAGE = ObjC; OUTLETS = { - fAutocropButton = NSButton; - fBottomField1 = NSTextField; - fBottomField2 = NSTextField; - fBottomStepper = NSStepper; - fCloseButton = NSButton; - fDeinterlaceCheck = NSButton; - fDonePanel = NSPanel; - fInfoField = NSTextField; - fLeftField1 = NSTextField; - fLeftField2 = NSTextField; - fLeftStepper = NSStepper; - fNextButton = NSButton; - fOpenGLCheck = NSButton; - fPictureGLView = HBPictureGLView; + fAddToQuButton = NSButton; + fAudBitrateField = NSTextField; + fAudBitratePopUp = NSPopUpButton; + fAudLang1Field = NSTextField; + fAudLang1PopUp = NSPopUpButton; + fAudLang2Field = NSTextField; + fAudLang2PopUp = NSPopUpButton; + fAudRateField = NSTextField; + fAudRatePopUp = NSPopUpButton; + fDstBrowseButton = NSButton; + fDstCodecsField = NSTextField; + fDstCodecsPopUp = NSPopUpButton; + fDstFile1Field = NSTextField; + fDstFile2Field = NSTextField; + fDstFormatField = NSTextField; + fDstFormatPopUp = NSPopUpButton; + fPauseButton = NSButton; + fPictureButton = NSButton; + fPictureController = PictureController; fPicturePanel = NSPanel; - fPreviousButton = NSButton; - fRightField1 = NSTextField; - fRightField2 = NSTextField; - fRightStepper = NSStepper; - fRipAudBitField = NSTextField; - fRipAudBitPopUp = NSPopUpButton; - fRipAudioField = NSTextField; - fRipBitrateField = NSTextField; - fRipBrowseButton = NSButton; - fRipCropButton = NSButton; - fRipCustomCell = NSButtonCell; - fRipCustomField = NSTextField; - fRipEncoderField = NSTextField; - fRipEncoderPopUp = NSPopUpButton; - fRipFileField1 = NSTextField; - fRipFileField2 = NSTextField; - fRipFormatField = NSTextField; - fRipFormatPopUp = NSPopUpButton; - fRipGeneralField = NSTextField; - fRipInfoField = NSTextField; - fRipLang1Field = NSTextField; - fRipLang1PopUp = NSPopUpButton; - fRipLang2Field = NSTextField; - fRipLang2PopUp = NSPopUpButton; - fRipPauseButton = NSButton; - fRipProgress = NSProgressIndicator; - fRipRipButton = NSButton; - fRipStatusField = NSTextField; - fRipTargetCell = NSButtonCell; - fRipTargetField = HBTargetSizeField; - fRipTitleField = NSTextField; - fRipTitlePopUp = NSPopUpButton; - fRipTwoPassCheck = NSButton; - fRipVideoField = NSTextField; - fRipVideoMatrix = NSMatrix; - fRipView = NSView; - fScBrowseButton = NSButton; - fScDetectedCell = NSButtonCell; - fScDetectedPopUp = NSPopUpButton; - fScFolderCell = NSButtonCell; - fScFolderField = NSTextField; - fScMatrix = NSMatrix; - fScOpenButton = NSButton; - fScProgress = NSProgressIndicator; - fScSelectField = NSTextField; - fScStatusField = NSTextField; - fScView = NSView; - fScWelcomeField = NSTextField; - fTempView = NSView; - fTopField1 = NSTextField; - fTopField2 = NSTextField; - fTopStepper = NSStepper; - fWidthField1 = NSTextField; - fWidthField2 = NSTextField; - fWidthStepper = NSStepper; + fQueueAddButton = NSButton; + fQueueCheck = NSButton; + fQueueController = QueueController; + fQueuePanel = NSPanel; + fQueueShowButton = NSButton; + fRipButton = NSButton; + fRipIndicator = NSProgressIndicator; + fScanController = ScanController; + fScanPanel = NSPanel; + fShowQuButton = NSButton; + fSrcChapterEndPopUp = NSPopUpButton; + fSrcChapterField = NSTextField; + fSrcChapterStartPopUp = NSPopUpButton; + fSrcChapterToField = NSTextField; + fSrcDVD1Field = NSTextField; + fSrcDVD2Field = NSTextField; + fSrcDuration1Field = NSTextField; + fSrcDuration2Field = NSTextField; + fSrcTitleField = NSTextField; + fSrcTitlePopUp = NSPopUpButton; + fStatusField = NSTextField; + fSubField = NSTextField; + fSubPopUp = NSPopUpButton; + fVidBitrateCell = NSButtonCell; + fVidBitrateField = NSTextField; + fVidConstantCell = NSButtonCell; + fVidEncoderField = NSTextField; + fVidEncoderPopUp = NSPopUpButton; + fVidGrayscaleCheck = NSButton; + fVidQualityField = NSTextField; + fVidQualityMatrix = NSMatrix; + fVidQualitySlider = NSSlider; + fVidRateField = NSTextField; + fVidRatePopUp = NSPopUpButton; + fVidTargetCell = NSButtonCell; + fVidTargetSizeField = NSTextField; + fVidTwoPassCheck = NSButton; fWindow = NSWindow; }; SUPERCLASS = NSObject; @@ -115,7 +98,82 @@ }; SUPERCLASS = NSTextField; }, - {CLASS = PictureGLView; LANGUAGE = ObjC; SUPERCLASS = NSOpenGLView; } + { + ACTIONS = { + ClosePanel = id; + NextPicture = id; + PreviousPicture = id; + SettingsChanged = id; + }; + CLASS = PictureController; + LANGUAGE = ObjC; + OUTLETS = { + fCropBottomField = NSTextField; + fCropBottomStepper = NSStepper; + fCropLeftField = NSTextField; + fCropLeftStepper = NSStepper; + fCropMatrix = NSMatrix; + fCropRightField = NSTextField; + fCropRightStepper = NSStepper; + fCropTopField = NSTextField; + fCropTopStepper = NSStepper; + fDeinterlaceCheck = NSButton; + fEffectsCheck = NSButton; + fHeightField = NSTextField; + fHeightStepper = NSStepper; + fInfoField = NSTextField; + fNextButton = NSButton; + fPictureGLView = HBPictureGLView; + fPrevButton = NSButton; + fRatioCheck = NSButton; + fWidthField = NSTextField; + fWidthStepper = NSStepper; + }; + SUPERCLASS = NSObject; + }, + {CLASS = PictureGLView; LANGUAGE = ObjC; SUPERCLASS = NSOpenGLView; }, + { + ACTIONS = {CheckChanged = id; ClosePanel = id; OpenPanel = id; }; + CLASS = PrefsController; + LANGUAGE = ObjC; + OUTLETS = {fPanel = NSPanel; fUpdateCheck = NSButton; }; + SUPERCLASS = NSObject; + }, + { + ACTIONS = {ClosePanel = id; Remove = id; Update = id; }; + CLASS = QueueController; + LANGUAGE = ObjC; + OUTLETS = {fScrollView = NSScrollView; fTaskView = NSView; }; + SUPERCLASS = NSObject; + }, + { + ACTIONS = { + Browse = id; + Browse2 = id; + BrowseDone2 = id; + Cancel = id; + MatrixChanged = id; + Open = id; + }; + CLASS = ScanController; + LANGUAGE = ObjC; + OUTLETS = { + fBrowseButton = NSButton; + fCancelButton = NSButton; + fDetectedCell = NSButtonCell; + fDetectedPopUp = NSPopUpButton; + fFolderCell = NSButtonCell; + fFolderField = NSTextField; + fIndicator = NSProgressIndicator; + fMatrix = NSMatrix; + fOpenButton = NSButton; + fPanel = NSPanel; + fSelectString = NSTextField; + fStatusField = NSTextField; + fWindow = NSWindow; + }; + SUPERCLASS = NSObject; + } ); IBVersion = 1; }
\ No newline at end of file diff --git a/macosx/English.lproj/MainMenu.nib/info.nib b/macosx/English.lproj/MainMenu.nib/info.nib index 07d1cfa67..0854e6d3d 100644 --- a/macosx/English.lproj/MainMenu.nib/info.nib +++ b/macosx/English.lproj/MainMenu.nib/info.nib @@ -3,29 +3,24 @@ <plist version="1.0"> <dict> <key>IBDocumentLocation</key> - <string>37 177 381 380 0 0 1440 878 </string> + <string>73 30 382 380 0 0 1440 878 </string> <key>IBEditorPositions</key> <dict> <key>29</key> - <string>277 674 165 44 0 0 1440 878 </string> - <key>556</key> - <string>130 59 470 306 0 0 1440 878 </string> - <key>583</key> - <string>650 499 144 171 0 0 1440 878 </string> - <key>689</key> - <string>513 258 470 610 0 0 1440 878 </string> + <string>157 764 261 44 0 0 1280 832 </string> </dict> <key>IBFramework Version</key> - <string>349.0</string> + <string>439.0</string> <key>IBOpenObjects</key> <array> - <integer>29</integer> <integer>365</integer> - <integer>583</integer> - <integer>434</integer> + <integer>1438</integer> <integer>21</integer> + <integer>29</integer> + <integer>1162</integer> + <integer>1348</integer> </array> <key>IBSystem Version</key> - <string>7F44</string> + <string>8F46</string> </dict> </plist> diff --git a/macosx/English.lproj/MainMenu.nib/keyedobjects.nib b/macosx/English.lproj/MainMenu.nib/keyedobjects.nib Binary files differnew file mode 100644 index 000000000..9d8af0121 --- /dev/null +++ b/macosx/English.lproj/MainMenu.nib/keyedobjects.nib diff --git a/macosx/English.lproj/MainMenu.nib/objects.nib b/macosx/English.lproj/MainMenu.nib/objects.nib Binary files differdeleted file mode 100644 index 5a2d37443..000000000 --- a/macosx/English.lproj/MainMenu.nib/objects.nib +++ /dev/null diff --git a/macosx/HandBrake.icns b/macosx/HandBrake.icns Binary files differindex f1d08d36f..f81352be3 100644 --- a/macosx/HandBrake.icns +++ b/macosx/HandBrake.icns diff --git a/macosx/HandBrake.xcode/project.pbxproj b/macosx/HandBrake.xcode/project.pbxproj deleted file mode 100644 index c9ac3a6a3..000000000 --- a/macosx/HandBrake.xcode/project.pbxproj +++ /dev/null @@ -1,560 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 39; - objects = { - 080E96DCFE201CFB7F000001 = { - fileRef = 29B97318FDCFA39411CA2CEA; - isa = PBXBuildFile; - settings = { - }; - }; - 080E96DDFE201D6D7F000001 = { - children = ( - 4DF3C8CB052889CD00A80101, - 4DF3C8CC052889CD00A80101, - 4D85758E052B78E300C39CA9, - 4D85758F052B78E300C39CA9, - 4D358C000534A91300D654EB, - 4D358C010534A91300D654EB, - ); - isa = PBXGroup; - name = Classes; - refType = 4; - sourceTree = "<group>"; - }; - 089C165CFE840E0CC02AAC07 = { - children = ( - 089C165DFE840E0CC02AAC07, - ); - isa = PBXVariantGroup; - name = InfoPlist.strings; - refType = 4; - sourceTree = "<group>"; - }; - 089C165DFE840E0CC02AAC07 = { - fileEncoding = 10; - isa = PBXFileReference; - lastKnownFileType = text.plist.strings; - name = English; - path = English.lproj/InfoPlist.strings; - refType = 4; - sourceTree = "<group>"; - }; - 089C165EFE840E0CC02AAC07 = { - fileRef = 089C165CFE840E0CC02AAC07; - isa = PBXBuildFile; - settings = { - }; - }; -//080 -//081 -//082 -//083 -//084 -//100 -//101 -//102 -//103 -//104 - 1058C7A0FEA54F0111CA2CBB = { - children = ( - 1058C7A1FEA54F0111CA2CBB, - 4DEB2024052B055F00C39CA9, - 4DDE9724052B7B2B00C39CA9, - ); - isa = PBXGroup; - name = "Linked Frameworks"; - refType = 4; - sourceTree = "<group>"; - }; - 1058C7A1FEA54F0111CA2CBB = { - fallbackIsa = PBXFileReference; - isa = PBXFrameworkReference; - lastKnownFileType = wrapper.framework; - name = Cocoa.framework; - path = /System/Library/Frameworks/Cocoa.framework; - refType = 0; - sourceTree = "<absolute>"; - }; - 1058C7A2FEA54F0111CA2CBB = { - children = ( - 29B97325FDCFA39411CA2CEA, - 29B97324FDCFA39411CA2CEA, - ); - isa = PBXGroup; - name = "Other Frameworks"; - refType = 4; - sourceTree = "<group>"; - }; - 1058C7A3FEA54F0111CA2CBB = { - fileRef = 1058C7A1FEA54F0111CA2CBB; - isa = PBXBuildFile; - settings = { - }; - }; -//100 -//101 -//102 -//103 -//104 -//170 -//171 -//172 -//173 -//174 - 17587328FF379C6511CA2CBB = { - explicitFileType = wrapper.application; - fallbackIsa = PBXFileReference; - isa = PBXApplicationReference; - path = HandBrake.app; - refType = 3; - sourceTree = BUILT_PRODUCTS_DIR; - }; -//170 -//171 -//172 -//173 -//174 -//190 -//191 -//192 -//193 -//194 - 19C28FACFE9D520D11CA2CBB = { - children = ( - 17587328FF379C6511CA2CBB, - ); - isa = PBXGroup; - name = Products; - refType = 4; - sourceTree = "<group>"; - }; -//190 -//191 -//192 -//193 -//194 -//290 -//291 -//292 -//293 -//294 - 29B97313FDCFA39411CA2CEA = { - buildSettings = { - MACOSX_DEPLOYMENT_TARGET = 10.2; - SDKROOT = /Developer/SDKs/MacOSX10.2.7.sdk; - }; - buildStyles = ( - 4A9504CCFFE6A4B311CA0CBA, - 4A9504CDFFE6A4B311CA0CBA, - ); - hasScannedForEncodings = 1; - isa = PBXProject; - mainGroup = 29B97314FDCFA39411CA2CEA; - projectDirPath = ""; - targets = ( - 29B97326FDCFA39411CA2CEA, - ); - }; - 29B97314FDCFA39411CA2CEA = { - children = ( - 080E96DDFE201D6D7F000001, - 29B97315FDCFA39411CA2CEA, - 29B97317FDCFA39411CA2CEA, - 29B97323FDCFA39411CA2CEA, - 19C28FACFE9D520D11CA2CBB, - ); - isa = PBXGroup; - name = HandBrake; - path = ""; - refType = 4; - sourceTree = "<group>"; - }; - 29B97315FDCFA39411CA2CEA = { - children = ( - 29B97316FDCFA39411CA2CEA, - 4DFDC318054AC84C00151618, - ); - isa = PBXGroup; - name = "Other Sources"; - path = ""; - refType = 4; - sourceTree = "<group>"; - }; - 29B97316FDCFA39411CA2CEA = { - fileEncoding = 30; - isa = PBXFileReference; - lastKnownFileType = sourcecode.cpp.objcpp; - path = main.mm; - refType = 4; - sourceTree = "<group>"; - }; - 29B97317FDCFA39411CA2CEA = { - children = ( - 29B97318FDCFA39411CA2CEA, - 4D118405053054CD00C39CA9, - 089C165CFE840E0CC02AAC07, - ); - isa = PBXGroup; - name = Resources; - path = ""; - refType = 4; - sourceTree = "<group>"; - }; - 29B97318FDCFA39411CA2CEA = { - children = ( - 29B97319FDCFA39411CA2CEA, - ); - isa = PBXVariantGroup; - name = MainMenu.nib; - path = ""; - refType = 4; - sourceTree = "<group>"; - }; - 29B97319FDCFA39411CA2CEA = { - isa = PBXFileReference; - lastKnownFileType = wrapper.nib; - name = English; - path = English.lproj/MainMenu.nib; - refType = 4; - sourceTree = "<group>"; - }; - 29B97323FDCFA39411CA2CEA = { - children = ( - 1058C7A0FEA54F0111CA2CBB, - 1058C7A2FEA54F0111CA2CBB, - ); - isa = PBXGroup; - name = Frameworks; - path = ""; - refType = 4; - sourceTree = "<group>"; - }; - 29B97324FDCFA39411CA2CEA = { - fallbackIsa = PBXFileReference; - isa = PBXFrameworkReference; - lastKnownFileType = wrapper.framework; - name = AppKit.framework; - path = /System/Library/Frameworks/AppKit.framework; - refType = 0; - sourceTree = "<absolute>"; - }; - 29B97325FDCFA39411CA2CEA = { - fallbackIsa = PBXFileReference; - isa = PBXFrameworkReference; - lastKnownFileType = wrapper.framework; - name = Foundation.framework; - path = /System/Library/Frameworks/Foundation.framework; - refType = 0; - sourceTree = "<absolute>"; - }; - 29B97326FDCFA39411CA2CEA = { - buildPhases = ( - 29B97327FDCFA39411CA2CEA, - 29B97328FDCFA39411CA2CEA, - 29B9732BFDCFA39411CA2CEA, - 29B9732DFDCFA39411CA2CEA, - ); - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ""; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; - HEADER_SEARCH_PATHS = ""; - LIBRARY_SEARCH_PATHS = ""; - OPTIMIZATION_CFLAGS = "-O3"; - OTHER_CFLAGS = ""; - OTHER_LDFLAGS = "../core/libhb.a ../contrib/liba52/liba52.a ../contrib/libavcodec/libavcodec.a ../contrib/libdvdread/libdvdread.a ../contrib/libdvdcss/libdvdcss.a ../contrib/libfaac/libfaac.a ../contrib/libmp3lame/libmp3lame.a ../contrib/libmp4v2/libmp4v2.a ../contrib/libmpeg2/libmpeg2.a ../contrib/libvorbis/libvorbis.a ../contrib/libvorbis/libvorbisenc.a ../contrib/libogg/libogg.a ../contrib/libsamplerate/libsamplerate.a ../contrib/libx264/libx264.a ../contrib/libxvidcore/libxvidcore.a"; - PRODUCT_NAME = HandBrake; - SECTORDER_FLAGS = ""; - WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas"; - WRAPPER_EXTENSION = app; - }; - dependencies = ( - ); - isa = PBXApplicationTarget; - name = HandBrake; - productName = HandBrake; - productReference = 17587328FF379C6511CA2CBB; - productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> -<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"> -<plist version=\"1.0\"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>English</string> - <key>CFBundleDisplayName</key> - <string>HandBrake</string> - <key>CFBundleExecutable</key> - <string>HandBrake</string> - <key>CFBundleGetInfoString</key> - <string>0.6.2</string> - <key>CFBundleIconFile</key> - <string>HandBrake.icns</string> - <key>CFBundleIdentifier</key> - <string>org.m0k.handbrake</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>HandBrake</string> - <key>CFBundlePackageType</key> - <string>APPL</string> - <key>CFBundleShortVersionString</key> - <string>0.6.2</string> - <key>CFBundleSignature</key> - <string>HB##</string> - <key>CFBundleVersion</key> - <string>0.6.2</string> - <key>NSHumanReadableCopyright</key> - <string>By Eric Petit <[email protected]></string> - <key>NSMainNibFile</key> - <string>MainMenu</string> - <key>NSPrincipalClass</key> - <string>NSApplication</string> -</dict> -</plist> -"; - }; - 29B97327FDCFA39411CA2CEA = { - buildActionMask = 2147483647; - files = ( - 4D6615EA05288C2300A80101, - 4D857591052B78E300C39CA9, - 4D358C020534A91300D654EB, - 4DFDC319054AC84C00151618, - ); - isa = PBXHeadersBuildPhase; - runOnlyForDeploymentPostprocessing = 0; - }; - 29B97328FDCFA39411CA2CEA = { - buildActionMask = 2147483647; - files = ( - 080E96DCFE201CFB7F000001, - 089C165EFE840E0CC02AAC07, - 4D118406053054CD00C39CA9, - ); - isa = PBXResourcesBuildPhase; - runOnlyForDeploymentPostprocessing = 0; - }; - 29B9732BFDCFA39411CA2CEA = { - buildActionMask = 2147483647; - files = ( - 29B9732CFDCFA39411CA2CEA, - 4DF3C8CE052889CD00A80101, - 4D857590052B78E300C39CA9, - 4D358C030534A91300D654EB, - ); - isa = PBXSourcesBuildPhase; - runOnlyForDeploymentPostprocessing = 0; - }; - 29B9732CFDCFA39411CA2CEA = { - fileRef = 29B97316FDCFA39411CA2CEA; - isa = PBXBuildFile; - settings = { - ATTRIBUTES = ( - ); - }; - }; - 29B9732DFDCFA39411CA2CEA = { - buildActionMask = 2147483647; - files = ( - 1058C7A3FEA54F0111CA2CBB, - 4DEB2025052B055F00C39CA9, - 4DDE9725052B7B2B00C39CA9, - ); - isa = PBXFrameworksBuildPhase; - runOnlyForDeploymentPostprocessing = 0; - }; -//290 -//291 -//292 -//293 -//294 -//4A0 -//4A1 -//4A2 -//4A3 -//4A4 - 4A9504CCFFE6A4B311CA0CBA = { - buildRules = ( - ); - buildSettings = { - COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = "0.6.2"; - GCC_DYNAMIC_NO_PIC = YES; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - GCC_GENERATE_DEBUGGING_SYMBOLS = YES; - GCC_OPTIMIZATION_LEVEL = 3; - LIBRARY_SEARCH_PATHS = ../core; - OPTIMIZATION_CFLAGS = "-O0"; - ZERO_LINK = NO; - }; - isa = PBXBuildStyle; - name = Development; - }; - 4A9504CDFFE6A4B311CA0CBA = { - buildRules = ( - ); - buildSettings = { - COPY_PHASE_STRIP = YES; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - ZERO_LINK = NO; - }; - isa = PBXBuildStyle; - name = Deployment; - }; -//4A0 -//4A1 -//4A2 -//4A3 -//4A4 -//4D0 -//4D1 -//4D2 -//4D3 -//4D4 - 4D118405053054CD00C39CA9 = { - isa = PBXFileReference; - lastKnownFileType = image.icns; - path = HandBrake.icns; - refType = 4; - sourceTree = "<group>"; - }; - 4D118406053054CD00C39CA9 = { - fileRef = 4D118405053054CD00C39CA9; - isa = PBXBuildFile; - settings = { - }; - }; - 4D358C000534A91300D654EB = { - fileEncoding = 30; - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - path = TargetSizeField.h; - refType = 4; - sourceTree = "<group>"; - }; - 4D358C010534A91300D654EB = { - fileEncoding = 30; - isa = PBXFileReference; - lastKnownFileType = sourcecode.cpp.objcpp; - path = TargetSizeField.mm; - refType = 4; - sourceTree = "<group>"; - }; - 4D358C020534A91300D654EB = { - fileRef = 4D358C000534A91300D654EB; - isa = PBXBuildFile; - settings = { - }; - }; - 4D358C030534A91300D654EB = { - fileRef = 4D358C010534A91300D654EB; - isa = PBXBuildFile; - settings = { - }; - }; - 4D6615EA05288C2300A80101 = { - fileRef = 4DF3C8CB052889CD00A80101; - isa = PBXBuildFile; - settings = { - }; - }; - 4D85758E052B78E300C39CA9 = { - fileEncoding = 30; - isa = PBXFileReference; - lastKnownFileType = sourcecode.cpp.objcpp; - path = PictureGLView.mm; - refType = 4; - sourceTree = "<group>"; - }; - 4D85758F052B78E300C39CA9 = { - fileEncoding = 30; - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - path = PictureGLView.h; - refType = 4; - sourceTree = "<group>"; - }; - 4D857590052B78E300C39CA9 = { - fileRef = 4D85758E052B78E300C39CA9; - isa = PBXBuildFile; - settings = { - }; - }; - 4D857591052B78E300C39CA9 = { - fileRef = 4D85758F052B78E300C39CA9; - isa = PBXBuildFile; - settings = { - }; - }; - 4DDE9724052B7B2B00C39CA9 = { - fallbackIsa = PBXFileReference; - isa = PBXFrameworkReference; - lastKnownFileType = wrapper.framework; - name = OpenGL.framework; - path = /System/Library/Frameworks/OpenGL.framework; - refType = 0; - sourceTree = "<absolute>"; - }; - 4DDE9725052B7B2B00C39CA9 = { - fileRef = 4DDE9724052B7B2B00C39CA9; - isa = PBXBuildFile; - settings = { - }; - }; - 4DEB2024052B055F00C39CA9 = { - fallbackIsa = PBXFileReference; - isa = PBXFrameworkReference; - lastKnownFileType = wrapper.framework; - name = IOKit.framework; - path = /System/Library/Frameworks/IOKit.framework; - refType = 0; - sourceTree = "<absolute>"; - }; - 4DEB2025052B055F00C39CA9 = { - fileRef = 4DEB2024052B055F00C39CA9; - isa = PBXBuildFile; - settings = { - }; - }; - 4DF3C8CB052889CD00A80101 = { - fileEncoding = 30; - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - path = Controller.h; - refType = 4; - sourceTree = "<group>"; - }; - 4DF3C8CC052889CD00A80101 = { - fileEncoding = 30; - isa = PBXFileReference; - lastKnownFileType = sourcecode.cpp.objcpp; - path = Controller.mm; - refType = 4; - sourceTree = "<group>"; - }; - 4DF3C8CE052889CD00A80101 = { - fileRef = 4DF3C8CC052889CD00A80101; - isa = PBXBuildFile; - settings = { - }; - }; - 4DFDC318054AC84C00151618 = { - fileEncoding = 30; - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = HandBrake.h; - path = ../core/HandBrake.h; - refType = 4; - sourceTree = "<group>"; - }; - 4DFDC319054AC84C00151618 = { - fileRef = 4DFDC318054AC84C00151618; - isa = PBXBuildFile; - settings = { - }; - }; - }; - rootObject = 29B97313FDCFA39411CA2CEA; -} diff --git a/macosx/HandBrake.xcodeproj/project.pbxproj b/macosx/HandBrake.xcodeproj/project.pbxproj new file mode 100644 index 000000000..e733e1991 --- /dev/null +++ b/macosx/HandBrake.xcodeproj/project.pbxproj @@ -0,0 +1,502 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + 4DD93F8F082036E8008E1322 /* Controller.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DF3C8CB052889CD00A80101 /* Controller.h */; }; + 4DD93F90082036E8008E1322 /* PictureGLView.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D85758F052B78E300C39CA9 /* PictureGLView.h */; }; + 4DD93F91082036E8008E1322 /* ScanController.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D86C74F07281F4E007BA979 /* ScanController.h */; }; + 4DD93F92082036E8008E1322 /* PictureController.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D1FD381073D19CE00E46515 /* PictureController.h */; }; + 4DD93F93082036E8008E1322 /* QueueController.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DD27BA507C0065C0023D231 /* QueueController.h */; }; + 4DD93F94082036E8008E1322 /* PrefsController.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DE93A3507F5A2C900F3C78F /* PrefsController.h */; }; + 4DD93F96082036E8008E1322 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 29B97318FDCFA39411CA2CEA /* MainMenu.nib */; }; + 4DD93F97082036E8008E1322 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; + 4DD93F98082036E8008E1322 /* HandBrake.icns in Resources */ = {isa = PBXBuildFile; fileRef = 4D118405053054CD00C39CA9 /* HandBrake.icns */; }; + 4DD93F9A082036E8008E1322 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.mm */; settings = {ATTRIBUTES = (); }; }; + 4DD93F9B082036E8008E1322 /* Controller.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4DF3C8CC052889CD00A80101 /* Controller.mm */; }; + 4DD93F9C082036E8008E1322 /* PictureGLView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4D85758E052B78E300C39CA9 /* PictureGLView.mm */; }; + 4DD93F9D082036E8008E1322 /* ScanController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4D86C74E07281F4E007BA979 /* ScanController.mm */; }; + 4DD93F9E082036E8008E1322 /* PictureController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4D1FD382073D19CE00E46515 /* PictureController.mm */; }; + 4DD93F9F082036E8008E1322 /* QueueController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4DD27BA607C0065C0023D231 /* QueueController.mm */; }; + 4DD93FA0082036E8008E1322 /* PrefsController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4DE93A3607F5A2C900F3C78F /* PrefsController.m */; }; + 4DD93FA2082036E8008E1322 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; + 4DD93FA3082036E8008E1322 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DEB2024052B055F00C39CA9 /* IOKit.framework */; }; + 4DD93FA4082036E8008E1322 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DDE9724052B7B2B00C39CA9 /* OpenGL.framework */; }; + 4DE09E63082038A400FB751F /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4DE09E62082038A400FB751F /* Info.plist */; }; +/* End PBXBuildFile section */ + +/* Begin PBXBuildStyle section */ + 4A9504CCFFE6A4B311CA0CBA /* Development */ = { + isa = PBXBuildStyle; + buildSettings = { + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = "0.7.0"; + GCC_DYNAMIC_NO_PIC = YES; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 3; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; + LIBRARY_SEARCH_PATHS = ""; + ZERO_LINK = NO; + }; + name = Development; + }; + 4A9504CDFFE6A4B311CA0CBA /* Deployment */ = { + isa = PBXBuildStyle; + buildSettings = { + COPY_PHASE_STRIP = YES; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; + ZERO_LINK = NO; + }; + name = Deployment; + }; +/* End PBXBuildStyle section */ + +/* Begin PBXFileReference section */ + 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; }; + 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; }; + 29B97316FDCFA39411CA2CEA /* main.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = "<group>"; }; + 29B97319FDCFA39411CA2CEA /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; sourceTree = "<group>"; }; + 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; }; + 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; }; + 4D118405053054CD00C39CA9 /* HandBrake.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = HandBrake.icns; sourceTree = "<group>"; }; + 4D1FD381073D19CE00E46515 /* PictureController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PictureController.h; sourceTree = "<group>"; }; + 4D1FD382073D19CE00E46515 /* PictureController.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = PictureController.mm; sourceTree = "<group>"; }; + 4D85758E052B78E300C39CA9 /* PictureGLView.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = PictureGLView.mm; sourceTree = "<group>"; }; + 4D85758F052B78E300C39CA9 /* PictureGLView.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PictureGLView.h; sourceTree = "<group>"; }; + 4D86C74E07281F4E007BA979 /* ScanController.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = ScanController.mm; sourceTree = "<group>"; }; + 4D86C74F07281F4E007BA979 /* ScanController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ScanController.h; sourceTree = "<group>"; }; + 4DD27BA507C0065C0023D231 /* QueueController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = QueueController.h; sourceTree = SOURCE_ROOT; }; + 4DD27BA607C0065C0023D231 /* QueueController.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = QueueController.mm; sourceTree = SOURCE_ROOT; }; + 4DD93FA6082036E8008E1322 /* HandBrake.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HandBrake.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4DDE9724052B7B2B00C39CA9 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = "<absolute>"; }; + 4DE09E62082038A400FB751F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = Info.plist; sourceTree = "<group>"; }; + 4DE93A3507F5A2C900F3C78F /* PrefsController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PrefsController.h; sourceTree = "<group>"; }; + 4DE93A3607F5A2C900F3C78F /* PrefsController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = PrefsController.m; sourceTree = "<group>"; }; + 4DEB2024052B055F00C39CA9 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = "<absolute>"; }; + 4DF3C8CB052889CD00A80101 /* Controller.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Controller.h; sourceTree = "<group>"; }; + 4DF3C8CC052889CD00A80101 /* Controller.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = Controller.mm; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 4DD93FA1082036E8008E1322 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4DD93FA2082036E8008E1322 /* Cocoa.framework in Frameworks */, + 4DD93FA3082036E8008E1322 /* IOKit.framework in Frameworks */, + 4DD93FA4082036E8008E1322 /* OpenGL.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 4D1FD381073D19CE00E46515 /* PictureController.h */, + 4D1FD382073D19CE00E46515 /* PictureController.mm */, + 4DF3C8CB052889CD00A80101 /* Controller.h */, + 4DF3C8CC052889CD00A80101 /* Controller.mm */, + 4D86C74E07281F4E007BA979 /* ScanController.mm */, + 4D86C74F07281F4E007BA979 /* ScanController.h */, + 4D85758E052B78E300C39CA9 /* PictureGLView.mm */, + 4D85758F052B78E300C39CA9 /* PictureGLView.h */, + 4DD27BA507C0065C0023D231 /* QueueController.h */, + 4DD27BA607C0065C0023D231 /* QueueController.mm */, + 4DE93A3507F5A2C900F3C78F /* PrefsController.h */, + 4DE93A3607F5A2C900F3C78F /* PrefsController.m */, + ); + name = Classes; + sourceTree = "<group>"; + }; + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { + isa = PBXGroup; + children = ( + 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, + 4DEB2024052B055F00C39CA9 /* IOKit.framework */, + 4DDE9724052B7B2B00C39CA9 /* OpenGL.framework */, + ); + name = "Linked Frameworks"; + sourceTree = "<group>"; + }; + 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + 29B97325FDCFA39411CA2CEA /* Foundation.framework */, + 29B97324FDCFA39411CA2CEA /* AppKit.framework */, + ); + name = "Other Frameworks"; + sourceTree = "<group>"; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 4DD93FA6082036E8008E1322 /* HandBrake.app */, + ); + name = Products; + sourceTree = "<group>"; + }; + 29B97314FDCFA39411CA2CEA /* HandBrake */ = { + isa = PBXGroup; + children = ( + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + 4DE09E62082038A400FB751F /* Info.plist */, + ); + name = HandBrake; + sourceTree = "<group>"; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 29B97316FDCFA39411CA2CEA /* main.mm */, + ); + name = "Other Sources"; + sourceTree = "<group>"; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 29B97318FDCFA39411CA2CEA /* MainMenu.nib */, + 4D118405053054CD00C39CA9 /* HandBrake.icns */, + 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, + ); + name = Resources; + sourceTree = "<group>"; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, + 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, + ); + name = Frameworks; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 4DD93F8E082036E8008E1322 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4DD93F8F082036E8008E1322 /* Controller.h in Headers */, + 4DD93F90082036E8008E1322 /* PictureGLView.h in Headers */, + 4DD93F91082036E8008E1322 /* ScanController.h in Headers */, + 4DD93F92082036E8008E1322 /* PictureController.h in Headers */, + 4DD93F93082036E8008E1322 /* QueueController.h in Headers */, + 4DD93F94082036E8008E1322 /* PrefsController.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 4DD93F8D082036E8008E1322 /* HandBrake */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4D4E7BC0087804870051572B /* Build configuration list for PBXNativeTarget "HandBrake" */; + buildPhases = ( + 4DD93F8E082036E8008E1322 /* Headers */, + 4DD93F95082036E8008E1322 /* Resources */, + 4DD93F99082036E8008E1322 /* Sources */, + 4DD93FA1082036E8008E1322 /* Frameworks */, + ); + buildRules = ( + ); + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ""; + GCC_OPTIMIZATION_LEVEL = 3; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; + HEADER_SEARCH_PATHS = ../libhb; + INFOPLIST_FILE = Info.plist; + LIBRARY_SEARCH_PATHS = ""; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + ../libhb/libhb.a, + ../contrib/lib/liba52.a, + ../contrib/lib/libavcodec.a, + ../contrib/lib/libavutil.a, + ../contrib/lib/libdvdread.a, + ../contrib/lib/libdvdcss.a, + ../contrib/lib/libfaac.a, + ../contrib/lib/libmp3lame.a, + ../contrib/lib/libmp4v2.a, + ../contrib/lib/libmpeg2.a, + ../contrib/lib/libvorbis.a, + ../contrib/lib/libvorbisenc.a, + ../contrib/lib/libogg.a, + ../contrib/lib/libsamplerate.a, + ../contrib/lib/libx264.a, + ../contrib/lib/libxvidcore.a, + ); + PRODUCT_NAME = HandBrake; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + WRAPPER_EXTENSION = app; + }; + dependencies = ( + ); + name = HandBrake; + productName = HandBrake; + productReference = 4DD93FA6082036E8008E1322 /* HandBrake.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 4D4E7BC4087804870051572B /* Build configuration list for PBXProject "HandBrake" */; + buildSettings = { + MACOSX_DEPLOYMENT_TARGET = 10.3; + SDKROOT = /Developer/SDKs/MacOSX10.3.9.sdk; + }; + buildStyles = ( + 4A9504CCFFE6A4B311CA0CBA /* Development */, + 4A9504CDFFE6A4B311CA0CBA /* Deployment */, + ); + hasScannedForEncodings = 1; + mainGroup = 29B97314FDCFA39411CA2CEA /* HandBrake */; + projectDirPath = ""; + targets = ( + 4DD93F8D082036E8008E1322 /* HandBrake */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 4DD93F95082036E8008E1322 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4DD93F96082036E8008E1322 /* MainMenu.nib in Resources */, + 4DD93F97082036E8008E1322 /* InfoPlist.strings in Resources */, + 4DD93F98082036E8008E1322 /* HandBrake.icns in Resources */, + 4DE09E63082038A400FB751F /* Info.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 4DD93F99082036E8008E1322 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4DD93F9A082036E8008E1322 /* main.mm in Sources */, + 4DD93F9B082036E8008E1322 /* Controller.mm in Sources */, + 4DD93F9C082036E8008E1322 /* PictureGLView.mm in Sources */, + 4DD93F9D082036E8008E1322 /* ScanController.mm in Sources */, + 4DD93F9E082036E8008E1322 /* PictureController.mm in Sources */, + 4DD93F9F082036E8008E1322 /* QueueController.mm in Sources */, + 4DD93FA0082036E8008E1322 /* PrefsController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 089C165DFE840E0CC02AAC07 /* English */, + ); + name = InfoPlist.strings; + sourceTree = "<group>"; + }; + 29B97318FDCFA39411CA2CEA /* MainMenu.nib */ = { + isa = PBXVariantGroup; + children = ( + 29B97319FDCFA39411CA2CEA /* English */, + ); + name = MainMenu.nib; + sourceTree = "<group>"; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 4D4E7BC1087804870051572B /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = "0.7.0"; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_DYNAMIC_NO_PIC = YES; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 3; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; + HEADER_SEARCH_PATHS = ../libhb; + INFOPLIST_FILE = Info.plist; + LIBRARY_SEARCH_PATHS = ""; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + ../libhb/libhb.a, + ../contrib/lib/liba52.a, + ../contrib/lib/libavcodec.a, + ../contrib/lib/libavutil.a, + ../contrib/lib/libdvdread.a, + ../contrib/lib/libdvdcss.a, + ../contrib/lib/libfaac.a, + ../contrib/lib/libmp3lame.a, + ../contrib/lib/libmp4v2.a, + ../contrib/lib/libmpeg2.a, + ../contrib/lib/libvorbis.a, + ../contrib/lib/libvorbisenc.a, + ../contrib/lib/libogg.a, + ../contrib/lib/libsamplerate.a, + ../contrib/lib/libx264.a, + ../contrib/lib/libxvidcore.a, + ); + PRODUCT_NAME = HandBrake; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Development; + }; + 4D4E7BC2087804870051572B /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = 3; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; + HEADER_SEARCH_PATHS = ../libhb; + INFOPLIST_FILE = Info.plist; + LIBRARY_SEARCH_PATHS = ""; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + ../libhb/libhb.a, + ../contrib/lib/liba52.a, + ../contrib/lib/libavcodec.a, + ../contrib/lib/libavutil.a, + ../contrib/lib/libdvdread.a, + ../contrib/lib/libdvdcss.a, + ../contrib/lib/libfaac.a, + ../contrib/lib/libmp3lame.a, + ../contrib/lib/libmp4v2.a, + ../contrib/lib/libmpeg2.a, + ../contrib/lib/libvorbis.a, + ../contrib/lib/libvorbisenc.a, + ../contrib/lib/libogg.a, + ../contrib/lib/libsamplerate.a, + ../contrib/lib/libx264.a, + ../contrib/lib/libxvidcore.a, + ); + PRODUCT_NAME = HandBrake; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4D4E7BC3087804870051572B /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ""; + GCC_OPTIMIZATION_LEVEL = 3; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; + HEADER_SEARCH_PATHS = ../libhb; + INFOPLIST_FILE = Info.plist; + LIBRARY_SEARCH_PATHS = ""; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + ../libhb/libhb.a, + ../contrib/lib/liba52.a, + ../contrib/lib/libavcodec.a, + ../contrib/lib/libavutil.a, + ../contrib/lib/libdvdread.a, + ../contrib/lib/libdvdcss.a, + ../contrib/lib/libfaac.a, + ../contrib/lib/libmp3lame.a, + ../contrib/lib/libmp4v2.a, + ../contrib/lib/libmpeg2.a, + ../contrib/lib/libvorbis.a, + ../contrib/lib/libvorbisenc.a, + ../contrib/lib/libogg.a, + ../contrib/lib/libsamplerate.a, + ../contrib/lib/libx264.a, + ../contrib/lib/libxvidcore.a, + ); + PRODUCT_NAME = HandBrake; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + WRAPPER_EXTENSION = app; + }; + name = Default; + }; + 4D4E7BC5087804870051572B /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Development; + }; + 4D4E7BC6087804870051572B /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Deployment; + }; + 4D4E7BC7087804870051572B /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Default; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 4D4E7BC0087804870051572B /* Build configuration list for PBXNativeTarget "HandBrake" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4D4E7BC1087804870051572B /* Development */, + 4D4E7BC2087804870051572B /* Deployment */, + 4D4E7BC3087804870051572B /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; + 4D4E7BC4087804870051572B /* Build configuration list for PBXProject "HandBrake" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4D4E7BC5087804870051572B /* Development */, + 4D4E7BC6087804870051572B /* Deployment */, + 4D4E7BC7087804870051572B /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/macosx/Info.plist b/macosx/Info.plist new file mode 100644 index 000000000..f7df901d4 --- /dev/null +++ b/macosx/Info.plist @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundleDisplayName</key> + <string>HandBrake</string> + <key>CFBundleExecutable</key> + <string>HandBrake</string> + <key>CFBundleGetInfoString</key> + <string>0.7.0</string> + <key>CFBundleIconFile</key> + <string>HandBrake.icns</string> + <key>CFBundleIdentifier</key> + <string>org.m0k.handbrake</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>HandBrake</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>0.7.0</string> + <key>CFBundleSignature</key> + <string>HB##</string> + <key>CFBundleVersion</key> + <string>2005110400</string> + <key>NSHumanReadableCopyright</key> + <string>By Eric Petit <[email protected]></string> + <key>NSMainNibFile</key> + <string>MainMenu</string> + <key>NSPrincipalClass</key> + <string>NSApplication</string> +</dict> +</plist> diff --git a/macosx/PictureController.h b/macosx/PictureController.h new file mode 100644 index 000000000..3a279e133 --- /dev/null +++ b/macosx/PictureController.h @@ -0,0 +1,55 @@ +/* $Id: PictureController.h,v 1.6 2005/04/14 20:40:05 titer Exp $ + + This file is part of the HandBrake source code. + Homepage: <http://handbrake.m0k.org/>. + It may be used under the terms of the GNU General Public License. */ + +#include <Cocoa/Cocoa.h> + +#include "hb.h" +#include "PictureGLView.h" + +@interface PictureController : NSObject +{ + hb_handle_t * fHandle; + hb_title_t * fTitle; + + bool fHasQE; + uint8_t * fBuffer; + int fBufferSize; + uint8_t * fTexBuf[2]; + int fTexBufSize; + int fPicture; + + IBOutlet HBPictureGLView * fPictureGLView; + IBOutlet NSTextField * fWidthField; + IBOutlet NSStepper * fWidthStepper; + IBOutlet NSTextField * fHeightField; + IBOutlet NSStepper * fHeightStepper; + IBOutlet NSButton * fRatioCheck; + IBOutlet NSMatrix * fCropMatrix; + IBOutlet NSTextField * fCropTopField; + IBOutlet NSStepper * fCropTopStepper; + IBOutlet NSTextField * fCropBottomField; + IBOutlet NSStepper * fCropBottomStepper; + IBOutlet NSTextField * fCropLeftField; + IBOutlet NSStepper * fCropLeftStepper; + IBOutlet NSTextField * fCropRightField; + IBOutlet NSStepper * fCropRightStepper; + IBOutlet NSButton * fDeinterlaceCheck; + IBOutlet NSButton * fEffectsCheck; + IBOutlet NSButton * fPrevButton; + IBOutlet NSButton * fNextButton; + IBOutlet NSTextField * fInfoField; +} + +- (void) SetHandle: (hb_handle_t *) handle; +- (void) SetTitle: (hb_title_t *) title; +- (void) Display: (int) anim; + +- (IBAction) SettingsChanged: (id) sender; +- (IBAction) PreviousPicture: (id) sender; +- (IBAction) NextPicture: (id) sender; +- (IBAction) ClosePanel: (id) sender; + +@end diff --git a/macosx/PictureController.mm b/macosx/PictureController.mm new file mode 100644 index 000000000..f4e9d51d9 --- /dev/null +++ b/macosx/PictureController.mm @@ -0,0 +1,228 @@ +/* $Id: PictureController.mm,v 1.11 2005/08/01 15:10:44 titer Exp $ + + This file is part of the HandBrake source code. + Homepage: <http://handbrake.m0k.org/>. + It may be used under the terms of the GNU General Public License. */ + +#include "PictureController.h" + +static int GetAlignedSize( int size ) +{ + int result = 1; + while( result < size ) + { + result *= 2; + } + return result; +} + +@implementation PictureController + +- (void) SetHandle: (hb_handle_t *) handle +{ + fHandle = handle; + + fHasQE = CGDisplayUsesOpenGLAcceleration( kCGDirectMainDisplay ); + + fBuffer = NULL; + fBufferSize = 0; + fTexBuf[0] = NULL; + fTexBuf[1] = NULL; + fTexBufSize = 0; + + [fWidthStepper setValueWraps: NO]; + [fWidthStepper setIncrement: 16]; + [fWidthStepper setMinValue: 16]; + [fHeightStepper setValueWraps: NO]; + [fHeightStepper setIncrement: 16]; + [fHeightStepper setMinValue: 16]; + + [fCropTopStepper setIncrement: 2]; + [fCropTopStepper setMinValue: 0]; + [fCropBottomStepper setIncrement: 2]; + [fCropBottomStepper setMinValue: 0]; + [fCropLeftStepper setIncrement: 2]; + [fCropLeftStepper setMinValue: 0]; + [fCropRightStepper setIncrement: 2]; + [fCropRightStepper setMinValue: 0]; +} + +- (void) SetTitle: (hb_title_t *) title +{ + hb_job_t * job = title->job; + + fTitle = title; + + /* Make sure we have big enough buffers */ + int newSize; + newSize = ( title->width + 2 ) * (title->height + 2 ) * 4; + if( fBufferSize < newSize ) + { + fBufferSize = newSize; + fBuffer = (uint8_t *) realloc( fBuffer, fBufferSize ); + } + if( !fHasQE ) + { + newSize = ( GetAlignedSize( title->width + 2 ) * + GetAlignedSize( title->height + 2 ) * 4 ); + } + if( fTexBufSize < newSize ) + { + fTexBufSize = newSize; + fTexBuf[0] = (uint8_t *) realloc( fTexBuf[0], fTexBufSize ); + fTexBuf[1] = (uint8_t *) realloc( fTexBuf[1], fTexBufSize ); + } + + [fWidthStepper setMaxValue: title->width]; + [fWidthStepper setIntValue: job->width]; + [fWidthField setIntValue: job->width]; + [fHeightStepper setMaxValue: title->height]; + [fHeightStepper setIntValue: job->height]; + [fHeightField setIntValue: job->height]; + [fRatioCheck setState: job->keep_ratio ? NSOnState : NSOffState]; + [fCropTopStepper setMaxValue: title->height/2-2]; + [fCropBottomStepper setMaxValue: title->height/2-2]; + [fCropLeftStepper setMaxValue: title->width/2-2]; + [fCropRightStepper setMaxValue: title->width/2-2]; + [fDeinterlaceCheck setState: job->deinterlace ? NSOnState : NSOffState]; + + fPicture = 0; + [self SettingsChanged: nil]; +} + +- (void) Display: (int) anim +{ + hb_get_preview( fHandle, fTitle, fPicture, fBuffer ); + + /* Backup previous picture (for effects) */ + memcpy( fTexBuf[1], fTexBuf[0], fTexBufSize ); + + if( fHasQE ) + { + /* Simply copy */ + memcpy( fTexBuf[0], fBuffer, fTexBufSize ); + } + else + { + /* Copy line by line */ + uint8_t * in = fBuffer; + uint8_t * out = fTexBuf[0]; + for( int i = fTitle->height + 2; i--; ) + { + memcpy( out, in, 4 * ( fTitle->width + 2 ) ); + in += 4 * ( fTitle->width + 2 ); + out += 4 * GetAlignedSize( fTitle->width + 2 ); + } + } + + if( [fEffectsCheck state] == NSOffState ) + { + anim = HB_ANIMATE_NONE; + } + else if( [[NSApp currentEvent] modifierFlags] & NSShiftKeyMask ) + { + anim |= HB_ANIMATE_SLOW; + } + + [fPictureGLView Display: anim buffer1: fTexBuf[0] + buffer2: fTexBuf[1] width: ( fTitle->width + 2 ) + height: ( fTitle->height + 2 )]; + + [fInfoField setStringValue: [NSString stringWithFormat: + @"Source %dx%d, output %dx%d", fTitle->width, fTitle->height, + fTitle->job->width, fTitle->job->height]]; + + [fPrevButton setEnabled: ( fPicture > 0 )]; + [fNextButton setEnabled: ( fPicture < 9 )]; +} + +- (IBAction) SettingsChanged: (id) sender +{ + hb_job_t * job = fTitle->job; + + job->width = [fWidthStepper intValue]; + job->height = [fHeightStepper intValue]; + job->keep_ratio = ( [fRatioCheck state] == NSOnState ); + job->deinterlace = ( [fDeinterlaceCheck state] == NSOnState ); + + bool autocrop = ( [fCropMatrix selectedRow] == 0 ); + [fCropTopStepper setEnabled: !autocrop]; + [fCropBottomStepper setEnabled: !autocrop]; + [fCropLeftStepper setEnabled: !autocrop]; + [fCropRightStepper setEnabled: !autocrop]; + if( autocrop ) + { + memcpy( job->crop, fTitle->crop, 4 * sizeof( int ) ); + } + else + { + job->crop[0] = [fCropTopStepper intValue]; + job->crop[1] = [fCropBottomStepper intValue]; + job->crop[2] = [fCropLeftStepper intValue]; + job->crop[3] = [fCropRightStepper intValue]; + } + + if( job->keep_ratio ) + { + if( sender == fWidthStepper || sender == fRatioCheck || + sender == fCropTopStepper || sender == fCropBottomStepper ) + { + hb_fix_aspect( job, HB_KEEP_WIDTH ); + if( job->height > fTitle->height ) + { + job->height = fTitle->height; + hb_fix_aspect( job, HB_KEEP_HEIGHT ); + } + } + else + { + hb_fix_aspect( job, HB_KEEP_HEIGHT ); + if( job->width > fTitle->width ) + { + job->width = fTitle->width; + hb_fix_aspect( job, HB_KEEP_WIDTH ); + } + } + } + + [fWidthStepper setIntValue: job->width]; + [fWidthField setIntValue: job->width]; + [fHeightStepper setIntValue: job->height]; + [fHeightField setIntValue: job->height]; + [fCropTopStepper setIntValue: job->crop[0]]; + [fCropTopField setIntValue: job->crop[0]]; + [fCropBottomStepper setIntValue: job->crop[1]]; + [fCropBottomField setIntValue: job->crop[1]]; + [fCropLeftStepper setIntValue: job->crop[2]]; + [fCropLeftField setIntValue: job->crop[2]]; + [fCropRightStepper setIntValue: job->crop[3]]; + [fCropRightField setIntValue: job->crop[3]]; + [self Display: HB_ANIMATE_NONE]; +} + +- (IBAction) PreviousPicture: (id) sender +{ + if( fPicture <= 0 ) + { + return; + } + fPicture--; + [self Display: HB_ANIMATE_BACKWARD]; +} + +- (IBAction) NextPicture: (id) sender +{ + if( fPicture >= 9 ) + { + return; + } + fPicture++; + [self Display: HB_ANIMATE_FORWARD]; +} + +- (IBAction) ClosePanel: (id) sender +{ + [NSApp stopModal]; +} + +@end diff --git a/macosx/PictureGLView.h b/macosx/PictureGLView.h index c558c3c0f..229d822ac 100644 --- a/macosx/PictureGLView.h +++ b/macosx/PictureGLView.h @@ -1,4 +1,4 @@ -/* $Id: PictureGLView.h,v 1.1.1.1 2003/11/03 12:03:51 titer Exp $ +/* $Id: PictureGLView.h,v 1.7 2005/08/01 15:10:44 titer Exp $ This file is part of the HandBrake source code. Homepage: <http://handbrake.m0k.org/>. @@ -6,29 +6,41 @@ #include <Cocoa/Cocoa.h> -#include "HandBrake.h" +#include "hb.h" -#define HB_ANIMATE_NONE 0 -#define HB_ANIMATE_LEFT 1 -#define HB_ANIMATE_RIGHT 2 +#define HB_ANIMATE_NONE 1 +#define HB_ANIMATE_BACKWARD 2 +#define HB_ANIMATE_FORWARD 4 +#define HB_ANIMATE_SLOW 8 @interface HBPictureGLView : NSOpenGLView { - HBHandle * fHandle; - HBTitle * fTitle; - - uint8_t * fPicture; - uint8_t * fOldPicture; + bool fHasQE; + unsigned long fTarget; + + int fWidth; + int fHeight; + int fTexWidth; + int fTexHeight; + float fCoordX; + float fCoordY; + + uint8_t * fBuffers[2]; + unsigned long fTextures[2]; + + int fLastEffect; + int fAnimDuration; + int fFrameRate; } - (id) initWithFrame: (NSRect) frame; - (void) reshape; - (void) drawRect: (NSRect) rect; -- (void) drawAnimation: (int) how; +- (void) drawAnimation: (int) anim; -- (void) SetHandle: (HBHandle*) handle; -- (void) SetTitle: (HBTitle*) title; -- (void) ShowPicture: (int) index animate: (int) how; +- (void) Display: (int) anim buffer1: (uint8_t *) buffer1 + buffer2: (uint8_t *) buffer2 width: (int) width + height: (int) height; @end diff --git a/macosx/PictureGLView.mm b/macosx/PictureGLView.mm index dbb641729..611fb3a86 100644 --- a/macosx/PictureGLView.mm +++ b/macosx/PictureGLView.mm @@ -1,4 +1,4 @@ -/* $Id: PictureGLView.mm,v 1.6 2004/03/08 12:39:49 titer Exp $ +/* $Id: PictureGLView.mm,v 1.18 2005/08/01 15:10:44 titer Exp $ This file is part of the HandBrake source code. Homepage: <http://handbrake.m0k.org/>. @@ -6,146 +6,35 @@ #include <OpenGL/OpenGL.h> #include <OpenGL/gl.h> +#include <OpenGL/glext.h> #include <math.h> #include "PictureGLView.h" -#define PROUT 2.5 - -/* XXX This file needs some serious cleaning XXX */ - -GLuint texture[2]; -float rotation; -float translation; -uint8_t * truc; - -@implementation HBPictureGLView - -- (void) SetHandle: (HBHandle*) handle -{ - fHandle = handle; -} - -- (void) SetTitle: (HBTitle*) title -{ - fTitle = title; - - /* This is needed as the view's size may have changed */ - [self clearGLContext]; - [self openGLContext]; -} - -- (void) ShowPicture: (int) index animate: (int) how +static int GetAlignedSize( int size ) { - if( fOldPicture ) free( fOldPicture ); - fOldPicture = fPicture; - - /* Get the picture */ - uint8_t * tmp = HBGetPreview( fHandle, fTitle, index ); - - /* Make it be upside-down */ - fPicture = (uint8_t*) malloc( 4 * ( fTitle->outWidthMax + 2 ) * - ( fTitle->outHeightMax + 2 ) ); - uint8_t * in = tmp; - uint8_t * out = fPicture + - 4 * ( fTitle->outWidthMax + 2 ) * ( fTitle->outHeightMax + 1 ); - for( int i = fTitle->outHeightMax + 2; i--; ) - { - memcpy( out, in, 4 * ( fTitle->outWidthMax + 2 ) ); - in += 4 * ( fTitle->outWidthMax + 2 ); - out -= 4 * ( fTitle->outWidthMax + 2 ); - } - free( tmp ); - - /* ARGB -> RGBA */ - uint32_t * p = (uint32_t*) fPicture; - for( int i = ( fTitle->outHeightMax + 2 ) * - ( fTitle->outWidthMax + 2 ); i--; ) + int result = 1; + while( result < size ) { - *(p++) = ( ( (*p) & 0x00FFFFFF ) << 8 ) | 0xFF; + result *= 2; } - - if( how == HB_ANIMATE_NONE ) - { - [self drawRect: [self bounds]]; - return; - } - - in = fOldPicture; - out = truc; - for( int i = fTitle->outHeightMax + 2; i--; ) - { - memcpy( out, in, ( fTitle->outWidthMax + 2 ) * 4 ); - in += ( fTitle->outWidthMax + 2 ) * 4; - out += 1024 * 4; - } - glBindTexture( GL_TEXTURE_2D, texture[0] ); - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 1024, - 1024, 0, GL_RGBA, - GL_UNSIGNED_BYTE, truc ); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); - - in = fPicture; - out = truc; - for( int i = fTitle->outHeightMax + 2; i--; ) - { - memcpy( out, in, ( fTitle->outWidthMax + 2 ) * 4 ); - in += ( fTitle->outWidthMax + 2 ) * 4; - out += 1024 * 4; - } - glBindTexture( GL_TEXTURE_2D, texture[1] ); - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 1024, - 1024, 0, GL_RGBA, - GL_UNSIGNED_BYTE, truc ); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); - - glEnable( GL_TEXTURE_2D ); - glShadeModel( GL_SMOOTH ); - glClearColor( 0.0f, 0.0f, 0.0f, 0.5f ); - glClearDepth( 1.0f ); - glEnable( GL_DEPTH_TEST ); - glDepthFunc( GL_LEQUAL ); - glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); - -#define ANIMATION_TIME 500000 -#define FRAME_PER_SEC 50 - - rotation = 0.0; - float w = ( how == HB_ANIMATE_LEFT ) ? 1.0 : -1.0; - uint64_t date; - int64_t wait; - for( ;; ) - { - date = HBGetDate(); - translation = - PROUT - cos( rotation * M_PI / 180 ) * - ( 1 + w * tan( rotation * M_PI / 180 ) ); - [self drawAnimation: how]; - - rotation += w * 90 * 1000000 / ANIMATION_TIME / FRAME_PER_SEC; - if( w * rotation >= 90.0 ) - { - break; - } - - wait = 1000000 / FRAME_PER_SEC - ( HBGetDate() - date ); - if( wait > 0 ) - { - HBSnooze( wait ); - } - } - - [self drawRect: [self bounds]]; + return result; } +@implementation HBPictureGLView + - (id) initWithFrame: (NSRect) frame { - fHandle = NULL; - fTitle = NULL; - fPicture = NULL; - fOldPicture = NULL; + fHasQE = CGDisplayUsesOpenGLAcceleration( kCGDirectMainDisplay ); + fTarget = fHasQE ? GL_TEXTURE_RECTANGLE_EXT : GL_TEXTURE_2D; + + fBuffers[0] = NULL; + fBuffers[1] = NULL; + fWidth = 0; + fHeight = 0; + fLastEffect = -1; + GLuint attribs[] = { NSOpenGLPFANoRecovery, @@ -173,110 +62,368 @@ uint8_t * truc; [[self openGLContext] makeCurrentContext]; [self reshape]; - - glGenTextures( 2, texture ); - truc = (uint8_t*) malloc( 1024*1024*4 ); + glGenTextures( 2, fTextures ); return self; } -/* - * Resize ourself - */ - (void) reshape { - NSRect bounds; - - [[self openGLContext] update]; - bounds = [self bounds]; - if( fTitle ) - { - glViewport( 0, 0, fTitle->outWidthMax + 2, - fTitle->outHeightMax + 2 ); - } + NSRect bounds; + [[self openGLContext] update]; + [[self openGLContext] makeCurrentContext]; + bounds = [self bounds]; + glViewport( 0, 0, (int) bounds.size.width, + (int) bounds.size.height ); } -- (void) drawAnimation: (int) how +- (void) drawRect: (NSRect) rect { - /* Swap buffers only during the vertical retrace of the monitor. - http://developer.apple.com/documentation/GraphicsImaging/ - Conceptual/OpenGL/chap5/chapter_5_section_44.html */ - long params[] = { 1 }; - CGLSetParameter( CGLGetCurrentContext(), kCGLCPSwapInterval, - params ); + [[self openGLContext] makeCurrentContext]; + + glDisable( GL_DEPTH_TEST ); + glDisable( GL_CULL_FACE ); + glDisable( GL_BLEND ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + if( fBuffers[0] ) + { + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + glEnable( fTarget ); + glBindTexture( fTarget, fTextures[0] ); + glTexImage2D( fTarget, 0, GL_RGBA, fTexWidth, fTexHeight, 0, + GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, fBuffers[0] ); + glTexParameteri( fTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( fTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + + glBegin( GL_QUADS ); + glTexCoord2f( 0.0 , 0.0 ); glVertex2f( -1.0, 1.0 ); + glTexCoord2f( 0.0 , fCoordY ); glVertex2f( -1.0, -1.0 ); + glTexCoord2f( fCoordX, fCoordY ); glVertex2f( 1.0, -1.0 ); + glTexCoord2f( fCoordX, 0.0 ); glVertex2f( 1.0, 1.0 ); + glEnd(); + } + [[self openGLContext] flushBuffer]; +} + +#define FRUSTUM_NEAR 2.5 +#define FRUSTUM_FAR 20.0 + +- (void) drawCube: (int) anim +{ + uint64_t date; + float w, rotation, translation; + + w = ( anim & HB_ANIMATE_BACKWARD ) ? 1.0 : -1.0; + + glEnable( GL_DEPTH_TEST ); + glEnable( GL_CULL_FACE ); + glDisable( GL_BLEND ); + + for( rotation = 0.0; w * rotation < 90.0; + rotation += w * 90 * 1000 / fAnimDuration / fFrameRate ) + { + date = hb_get_date(); + translation = - FRUSTUM_NEAR - cos( rotation * M_PI / 180 ) * + ( 1 + w * tan( rotation * M_PI / 180 ) ); + + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glFrustum( -1.0, 1.0, -1.0, 1.0, FRUSTUM_NEAR, FRUSTUM_FAR ); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + glTranslatef( 0.0, 0.0, translation ); + glRotatef( rotation, 0.0, 1.0, 0.0 ); + + glBindTexture( fTarget, fTextures[0] ); + glBegin( GL_QUADS ); + glTexCoord2f( 0.0 , 0.0 ); glVertex3f( -1.0, 1.0, 1.0 ); + glTexCoord2f( 0.0 , fCoordY ); glVertex3f( -1.0, -1.0, 1.0 ); + glTexCoord2f( fCoordX, fCoordY ); glVertex3f( 1.0, -1.0, 1.0 ); + glTexCoord2f( fCoordX, 0.0 ); glVertex3f( 1.0, 1.0, 1.0 ); + glEnd(); + + glBindTexture( fTarget, fTextures[1] ); + glBegin( GL_QUADS ); + if( anim & HB_ANIMATE_FORWARD ) + { + glTexCoord2f( 0.0, 0.0 ); glVertex3f( 1.0, 1.0, 1.0 ); + glTexCoord2f( 0.0, fCoordY ); glVertex3f( 1.0, -1.0, 1.0 ); + glTexCoord2f( fCoordX, fCoordY ); glVertex3f( 1.0, -1.0, -1.0 ); + glTexCoord2f( fCoordX, 0.0 ); glVertex3f( 1.0, 1.0, -1.0 ); + } + else + { + glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, 1.0, -1.0 ); + glTexCoord2f( 0.0, fCoordY ); glVertex3f( -1.0, -1.0, -1.0 ); + glTexCoord2f( fCoordX, fCoordY ); glVertex3f( -1.0, -1.0, 1.0 ); + glTexCoord2f( fCoordX, 0.0 ); glVertex3f( -1.0, 1.0, 1.0 ); + } + glEnd(); + + [[self openGLContext] flushBuffer]; + + hb_snooze( 1000 / fFrameRate - ( hb_get_date() - date ) ); + } + +} + +- (void) drawSwap: (int) anim +{ + uint64_t date; + float w, rotation, x, z; + + w = ( anim & HB_ANIMATE_BACKWARD ) ? 1.0 : -1.0; + + glEnable( GL_DEPTH_TEST ); + glEnable( GL_CULL_FACE ); + glDisable( GL_BLEND ); + glMatrixMode( GL_PROJECTION ); glLoadIdentity(); - glFrustum( -1.0, 1.0, -1.0, 1.0, PROUT, 20.0 ); + glFrustum( -1.0, 1.0, -1.0, 1.0, FRUSTUM_NEAR, FRUSTUM_FAR ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); - glTranslatef( 0.0, 0.0, translation ); - glRotatef( rotation, 0.0, 1.0, 0.0 ); - - glEnable( GL_POLYGON_SMOOTH ); - glHint( GL_POLYGON_SMOOTH_HINT, GL_NICEST ); - - glBindTexture( GL_TEXTURE_2D, texture[0] ); - - glBegin( GL_QUADS ); - glTexCoord2f( 0.0, 0.0 ); - glVertex3f( -1.0, -1.0, 1.0 ); - glTexCoord2f( ( 2.0 + fTitle->outWidthMax ) / 1024, 0.0 ); - glVertex3f( 1.0, -1.0, 1.0 ); - glTexCoord2f( ( 2.0 + fTitle->outWidthMax ) / 1024, - ( 2.0 + fTitle->outHeightMax ) / 1024 ); - glVertex3f( 1.0, 1.0, 1.0 ); - glTexCoord2f( 0.0, ( 2.0 + fTitle->outHeightMax ) / 1024 ); - glVertex3f( -1.0, 1.0, 1.0 ); - glEnd(); - - glBindTexture( GL_TEXTURE_2D, texture[1] ); - - glBegin( GL_QUADS ); - if( how == HB_ANIMATE_RIGHT ) + glTranslatef( 0.0, 0.0, - FRUSTUM_NEAR - 1.0 ); + + for( rotation = 0.0; w * rotation < 180.0; + rotation += w * 180 * 1000 / fAnimDuration / fFrameRate ) + { + date = hb_get_date(); + + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + x = 1.1 * sin( rotation * M_PI / 180 ); + z = cos( rotation * M_PI / 180 ); + + glBindTexture( fTarget, fTextures[0] ); + glBegin( GL_QUADS ); + glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0 + x, 1.0, z ); + glTexCoord2f( 0.0, fCoordY ); glVertex3f( -1.0 + x, -1.0, z ); + glTexCoord2f( fCoordX, fCoordY ); glVertex3f( 1.0 + x, -1.0, z ); + glTexCoord2f( fCoordX, 0.0 ); glVertex3f( 1.0 + x, 1.0, z ); + glEnd(); + + glBindTexture( fTarget, fTextures[1] ); + glBegin( GL_QUADS ); + glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0 - x, 1.0, - z ); + glTexCoord2f( 0.0, fCoordY ); glVertex3f( -1.0 - x, -1.0, - z ); + glTexCoord2f( fCoordX, fCoordY ); glVertex3f( 1.0 - x, -1.0, - z ); + glTexCoord2f( fCoordX, 0.0 ); glVertex3f( 1.0 - x, 1.0, - z ); + glEnd(); + + [[self openGLContext] flushBuffer]; + + hb_snooze( 1000 / fFrameRate - ( hb_get_date() - date ) ); + } +} + +- (void) drawFade +{ + uint64_t date; + float alpha; + + glDisable( GL_DEPTH_TEST ); + glDisable( GL_CULL_FACE ); + glEnable( GL_BLEND ); + + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + for( alpha = 0.0; alpha < 1.0; + alpha += 1000.0 / fAnimDuration / fFrameRate ) + { + date = hb_get_date(); + + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + glColor4f( 1.0, 1.0, 1.0, 1.0 - alpha ); + glBlendFunc( GL_SRC_ALPHA, GL_ONE ); + + glBindTexture( fTarget, fTextures[0] ); + glBegin( GL_QUADS ); + glTexCoord2f( 0.0, 0.0 ); glVertex2f( -1.0, 1.0 ); + glTexCoord2f( 0.0, fCoordY ); glVertex2f( -1.0, -1.0 ); + glTexCoord2f( fCoordX, fCoordY ); glVertex2f( 1.0, -1.0 ); + glTexCoord2f( fCoordX, 0.0 ); glVertex2f( 1.0, 1.0 ); + glEnd(); + + glColor4f( 1.0, 1.0, 1.0, alpha ); + glBlendFunc( GL_SRC_ALPHA, GL_ONE ); + + glBindTexture( fTarget, fTextures[1] ); + glBegin( GL_QUADS ); + glTexCoord2f( 0.0, 0.0 ); glVertex2f( -1.0, 1.0 ); + glTexCoord2f( 0.0, fCoordY ); glVertex2f( -1.0, -1.0 ); + glTexCoord2f( fCoordX, fCoordY ); glVertex2f( 1.0, -1.0 ); + glTexCoord2f( fCoordX, 0.0 ); glVertex2f( 1.0, 1.0 ); + glEnd(); + + [[self openGLContext] flushBuffer]; + + hb_snooze( 1000 / fFrameRate - ( hb_get_date() - date ) ); + } +} + +- (void) drawSlide: (int) anim +{ + uint64_t date; + float foo, w; + int left, right; + if( anim & HB_ANIMATE_FORWARD ) { - glTexCoord2f( 0.0, 0.0 ); - glVertex3f( 1.0, -1.0, 1.0 ); - glTexCoord2f( ( 2.0 + fTitle->outWidthMax ) / 1024, 0.0 ); - glVertex3f( 1.0, -1.0, -1.0 ); - glTexCoord2f( ( 2.0 + fTitle->outWidthMax ) / 1024, - ( 2.0 + fTitle->outHeightMax ) / 1024 ); - glVertex3f( 1.0, 1.0, -1.0 ); - glTexCoord2f( 0.0, ( 2.0 + fTitle->outHeightMax ) / 1024 ); - glVertex3f( 1.0, 1.0, 1.0 ); + left = 0; + right = 1; + w = 1.0; } else { - glTexCoord2f( 0.0, 0.0 ); - glVertex3f( -1.0, -1.0, -1.0 ); - glTexCoord2f( ( 2.0 + fTitle->outWidthMax ) / 1024, 0.0 ); - glVertex3f( -1.0, -1.0, 1.0 ); - glTexCoord2f( ( 2.0 + fTitle->outWidthMax ) / 1024, - ( 2.0 + fTitle->outHeightMax ) / 1024 ); - glVertex3f( -1.0, 1.0, 1.0 ); - glTexCoord2f( 0.0, ( 2.0 + fTitle->outHeightMax ) / 1024 ); - glVertex3f( -1.0, 1.0, -1.0 ); + left = 1; + right = 0; + w = -1.0; + } + + glDisable( GL_DEPTH_TEST ); + glDisable( GL_CULL_FACE ); + glDisable( GL_BLEND ); + + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + for( foo = w; foo >= -1.0 && foo <= 1.0; + foo -= w * 2000.0 / fAnimDuration / fFrameRate ) + { + date = hb_get_date(); + + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + glBindTexture( fTarget, fTextures[left] ); + glBegin( GL_QUADS ); + glTexCoord2f( 0.0, 0.0 ); glVertex2f( foo - 2.0, 1.0 ); + glTexCoord2f( 0.0, fCoordY ); glVertex2f( foo - 2.0, -1.0 ); + glTexCoord2f( fCoordX, fCoordY ); glVertex2f( foo, -1.0 ); + glTexCoord2f( fCoordX, 0.0 ); glVertex2f( foo, 1.0 ); + glEnd(); + + glBindTexture( fTarget, fTextures[right] ); + glBegin( GL_QUADS ); + glTexCoord2f( 0.0, 0.0 ); glVertex2f( foo, 1.0 ); + glTexCoord2f( 0.0, fCoordY ); glVertex2f( foo, -1.0 ); + glTexCoord2f( fCoordX, fCoordY ); glVertex2f( foo + 2.0, -1.0 ); + glTexCoord2f( fCoordX, 0.0 ); glVertex2f( foo + 2.0, 1.0 ); + glEnd(); + + [[self openGLContext] flushBuffer]; + + hb_snooze( 1000 / fFrameRate - ( hb_get_date() - date ) ); } - glEnd(); - - [[self openGLContext] flushBuffer]; } -- (void) drawRect: (NSRect) rect +#undef FRUSTUM_NEAR +#undef FRUSTUM_FAR + +- (void) drawAnimation: (int) anim +{ + glEnable( fTarget ); + + glBindTexture( fTarget, fTextures[0] ); + glTexImage2D( fTarget, 0, GL_RGBA, fTexWidth, fTexHeight, 0, + GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, fBuffers[1] ); + glTexParameteri( fTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( fTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + + glBindTexture( fTarget, fTextures[1] ); + glTexImage2D( fTarget, 0, GL_RGBA, fTexWidth, fTexHeight, 0, + GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, fBuffers[0] ); + glTexParameteri( fTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( fTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + + /* Draw a random animation, just making sure we don't use the same + effect two times in a row */ + int effect; + do + { + effect = hb_get_date() % 4; + } + while( effect == fLastEffect ); + + fAnimDuration = ( anim & HB_ANIMATE_SLOW ) ? 3000 : 600; + fFrameRate = 60.0; + + switch( effect ) + { + case 0: + [self drawCube: anim]; + break; + case 1: + [self drawSwap: anim]; + break; + case 2: + [self drawFade]; + break; + case 3: + [self drawSlide: anim]; + break; + } + + fLastEffect = effect; +} + +- (void) Display: (int) anim buffer1: (uint8_t *) buffer1 + buffer2: (uint8_t *) buffer2 width: (int) width height: (int) height { - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + [[self openGLContext] makeCurrentContext]; - if( !fPicture ) - { - return; - } + if( width != fWidth || height != fHeight ) + { + fWidth = width; + fHeight = height; + if( fHasQE ) + { + fTexWidth = fWidth; + fTexHeight = fHeight; + fCoordX = (float) fWidth; + fCoordY = (float) fHeight; + } + else + { + fTexWidth = GetAlignedSize( fWidth ); + fTexHeight = GetAlignedSize( fHeight ); + fCoordX = (float) fWidth / (float) fTexWidth; + fCoordY = (float) fHeight / (float) fTexHeight; + } + [self clearGLContext]; + [self openGLContext]; + [self reshape]; + } - glDrawPixels( fTitle->outWidthMax + 2, - fTitle->outHeightMax + 2, GL_RGBA, - GL_UNSIGNED_BYTE, fPicture ); + fBuffers[0] = buffer1; + fBuffers[1] = buffer2; - [[self openGLContext] flushBuffer]; + /* Swap buffers only during the vertical retrace of the monitor. + http://developer.apple.com/documentation/GraphicsImaging/ + Conceptual/OpenGL/chap5/chapter_5_section_44.html */ + long params[] = { 1 }; + CGLSetParameter( CGLGetCurrentContext(), kCGLCPSwapInterval, + params ); + + if( !( anim & HB_ANIMATE_NONE ) ) + { + [self drawAnimation: anim]; + } + + [self drawRect: [self bounds]]; } @end diff --git a/macosx/PrefsController.h b/macosx/PrefsController.h new file mode 100644 index 000000000..cdd960f89 --- /dev/null +++ b/macosx/PrefsController.h @@ -0,0 +1,15 @@ +/* PrefsController */ + +#include <Cocoa/Cocoa.h> + +@interface PrefsController : NSObject +{ + IBOutlet NSPanel * fPanel; + IBOutlet NSButton * fUpdateCheck; +} + +- (IBAction) OpenPanel: (id) sender; +- (IBAction) ClosePanel: (id) sender; +- (IBAction) CheckChanged: (id) sender; + +@end diff --git a/macosx/PrefsController.m b/macosx/PrefsController.m new file mode 100644 index 000000000..8e7c865e2 --- /dev/null +++ b/macosx/PrefsController.m @@ -0,0 +1,47 @@ +#import "PrefsController.h" + +@implementation PrefsController + +- (void) awakeFromNib +{ + NSUserDefaults * defaults; + NSDictionary * appDefaults; + + /* Unless the user specified otherwise, default is to check + for update */ + defaults = [NSUserDefaults standardUserDefaults]; + appDefaults = [NSDictionary dictionaryWithObject:@"YES" + forKey:@"CheckForUpdates"]; + [defaults registerDefaults: appDefaults]; + + /* Check or uncheck according to the preferences */ + [fUpdateCheck setState: [defaults boolForKey:@"CheckForUpdates"] ? + NSOnState : NSOffState]; +} + +- (IBAction) OpenPanel: (id) sender; +{ + [NSApp runModalForWindow: fPanel]; +} + +- (IBAction) ClosePanel: (id) sender; +{ + [NSApp stopModal]; + [fPanel orderOut: sender]; +} + +- (IBAction) CheckChanged: (id) sender +{ + NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; + + if( [fUpdateCheck state] == NSOnState ) + { + [defaults setObject:@"YES" forKey:@"CheckForUpdates"]; + } + else + { + [defaults setObject:@"NO" forKey:@"CheckForUpdates"]; + } +} + +@end diff --git a/macosx/QueueController.h b/macosx/QueueController.h new file mode 100644 index 000000000..635adc7b8 --- /dev/null +++ b/macosx/QueueController.h @@ -0,0 +1,18 @@ +/* QueueController */ + +#include <Cocoa/Cocoa.h> + +#include "hb.h" + +@interface QueueController : NSObject +{ + hb_handle_t * fHandle; + IBOutlet NSScrollView * fScrollView; + IBOutlet NSView * fTaskView; +} + +- (void) SetHandle: (hb_handle_t *) handle; +- (IBAction) Update: (id) sender; +- (IBAction) ClosePanel: (id) sender; + +@end diff --git a/macosx/QueueController.mm b/macosx/QueueController.mm new file mode 100644 index 000000000..e775bb33d --- /dev/null +++ b/macosx/QueueController.mm @@ -0,0 +1,120 @@ +#include "QueueController.h" + +@implementation QueueController + +- (void) SetHandle: (hb_handle_t *) handle +{ + fHandle = handle; +} + +- (void) AddTextField: (NSString *) string rect: (NSRect *) rect +{ + NSTextField * textField; + + rect->origin.x = 10; + rect->origin.y -= 17; + rect->size.height = 17; + textField = [[NSTextField alloc] initWithFrame: *rect]; + + [textField setEditable: NO]; + [textField setSelectable: NO]; + [textField setDrawsBackground: NO]; + [textField setBordered: NO]; + [textField setStringValue: string]; + + [fTaskView addSubview: textField]; +} + +- (void) removeTask: (id) sender +{ + hb_rem( fHandle, hb_job( fHandle, [sender tag] ) ); + [self performSelectorOnMainThread: @selector( Update: ) + withObject: sender waitUntilDone: NO]; +} + +- (void) AddButton: (NSRect *) rect tag: (int) tag +{ + NSButton * button; + + rect->origin.x = rect->size.width - 90; + rect->origin.y -= 20; + rect->size.width = 100; + rect->size.height = 20; + button = [[NSButton alloc] initWithFrame: *rect]; + rect->size.width = rect->origin.x + 90; + + [button setTitle: @"Remove"]; + [button setBezelStyle: NSRoundedBezelStyle]; + [button setFont: [NSFont systemFontOfSize: + [NSFont systemFontSizeForControlSize: NSSmallControlSize]]]; + [[button cell] setControlSize: NSSmallControlSize]; + + [button setTag: tag]; + [button setTarget: self]; + [button setAction: @selector( removeTask: )]; + + [fTaskView addSubview: button]; + + NSBox * box; + + rect->origin.x = 15; + rect->origin.y -= 10; + rect->size.width -= 10; + rect->size.height = 1; + box = [[NSBox alloc] initWithFrame: *rect]; + [box setBoxType: NSBoxSeparator]; + rect->origin.y -= 10; + rect->size.width += 10; + + [fTaskView addSubview: box]; +} + +- (IBAction) Update: (id) sender +{ + int i; + hb_job_t * j; + hb_title_t * title; + + NSSize size = [fScrollView contentSize]; + int height = MAX( 20 + 125 * hb_count( fHandle ), size.height ); + [fTaskView setFrame: NSMakeRect(0,0,size.width,height)]; + + NSRect rect = NSMakeRect(10,height-10,size.width-20,10); + + NSArray * subviews = [fTaskView subviews]; + while( [subviews count] > 0 ) + { + [[subviews objectAtIndex: 0] + removeFromSuperviewWithoutNeedingDisplay]; + } + + for( i = 0; i < hb_count( fHandle ); i++ ) + { + j = hb_job( fHandle, i ); + title = j->title; + + [self AddTextField: [NSString stringWithFormat: + @"DVD: %s", title->dvd] rect: &rect]; + [self AddTextField: [NSString stringWithFormat: + @"Title: %d", title->index] rect: &rect]; + [self AddTextField: [NSString stringWithFormat: + @"Chapters: %d to %d", j->chapter_start, j->chapter_end] + rect: &rect]; + [self AddTextField: [NSString stringWithFormat: + @"Pass: %d of %d", MAX( 1, j->pass ), MIN( 2, j->pass + 1 )] + rect: &rect]; + [self AddTextField: [NSString stringWithFormat: + @"Destination: %s", j->file] rect: &rect]; + [self AddButton: &rect tag: i]; + } + + [fTaskView scrollPoint: NSMakePoint(0,height)]; + [fTaskView setNeedsDisplay: YES]; +} + +- (IBAction) ClosePanel: (id) sender +{ + [NSApp stopModal]; +} + +@end diff --git a/macosx/ScanController.h b/macosx/ScanController.h new file mode 100644 index 000000000..d038e6eea --- /dev/null +++ b/macosx/ScanController.h @@ -0,0 +1,47 @@ +/* $Id: ScanController.h,v 1.4 2005/03/21 12:37:32 titer Exp $ + + This file is part of the HandBrake source code. + Homepage: <http://handbrake.m0k.org/>. + It may be used under the terms of the GNU General Public License. */ + +#include <Cocoa/Cocoa.h> + +#include "hb.h" + +@interface ScanController : NSObject +{ + hb_handle_t * fHandle; + + IBOutlet NSWindow * fWindow; + IBOutlet NSPanel * fPanel; + IBOutlet NSTextField * fSelectString; + IBOutlet NSMatrix * fMatrix; + IBOutlet NSButtonCell * fDetectedCell; + IBOutlet NSPopUpButton * fDetectedPopUp; + IBOutlet NSButtonCell * fFolderCell; + IBOutlet NSTextField * fFolderField; + IBOutlet NSButton * fBrowseButton; + IBOutlet NSTextField * fStatusField; + IBOutlet NSProgressIndicator * fIndicator; + IBOutlet NSButton * fCancelButton; + IBOutlet NSButton * fOpenButton; + + uint64_t fLastCheck; +} + +- (void) TranslateStrings; +- (void) SetHandle: (hb_handle_t *) handle; +- (void) DetectDrives: (NSNotification *) notification; +- (void) UpdateUI: (hb_state_t *) state; + +- (IBAction) MatrixChanged: (id) sender; +- (IBAction) Browse: (id) sender; +- (IBAction) Open: (id) sender; +- (IBAction) Cancel: (id) sender; + +- (void) Browse2: (id) sender; +- (void) BrowseDone: (NSOpenPanel *) sheet + returnCode: (int) returnCode contextInfo: (void *) contextInfo; +- (void) BrowseDone2: (id) sender; + +@end diff --git a/macosx/ScanController.mm b/macosx/ScanController.mm new file mode 100644 index 000000000..5a4075416 --- /dev/null +++ b/macosx/ScanController.mm @@ -0,0 +1,272 @@ +/* $Id: ScanController.mm,v 1.10 2005/04/27 21:05:24 titer Exp $ + + This file is part of the HandBrake source code. + Homepage: <http://handbrake.m0k.org/>. + It may be used under the terms of the GNU General Public License. */ + +#include <paths.h> +#include <IOKit/IOKitLib.h> +#include <IOKit/IOBSD.h> +#include <IOKit/storage/IOMedia.h> +#include <IOKit/storage/IODVDMedia.h> + +#include "ScanController.h" + +#define _(a) NSLocalizedString(a,nil) + +@implementation ScanController + +- (void) TranslateStrings +{ + [fSelectString setStringValue: _( @"Select a DVD:" )]; + [fDetectedCell setTitle: _( @"Detected volume" )]; + [fFolderCell setTitle: _( @"DVD Folder / Image" )]; + [fBrowseButton setTitle: _( @"Browse" )]; + [fCancelButton setTitle: _( @"Cancel" )]; + [fOpenButton setTitle: _( @"Open" )]; +} + +- (void) SetHandle: (hb_handle_t *) handle +{ + fHandle = handle; + fLastCheck = 0; + + [self TranslateStrings]; + + [fStatusField setStringValue: @""]; +} + +- (void) DetectDrives: (NSNotification *) notification +{ + if( [fMatrix isEnabled] == NO ) + { + /* We're scanning */ + return; + } + if( hb_get_date() < fLastCheck + 1000 ) + { + /* Don't check more than every second */ + return; + } + fLastCheck = hb_get_date(); + + /* Scan DVD drives (stolen from VLC) */ + io_object_t next_media; + mach_port_t master_port; + kern_return_t kern_result; + io_iterator_t media_iterator; + CFMutableDictionaryRef classes_to_match; + + kern_result = IOMasterPort( MACH_PORT_NULL, &master_port ); + if( kern_result != KERN_SUCCESS ) + { + return; + } + + classes_to_match = IOServiceMatching( kIODVDMediaClass ); + if( classes_to_match == NULL ) + { + return; + } + + CFDictionarySetValue( classes_to_match, CFSTR( kIOMediaEjectableKey ), + kCFBooleanTrue ); + + kern_result = IOServiceGetMatchingServices( master_port, + classes_to_match, &media_iterator ); + if( kern_result != KERN_SUCCESS ) + { + return; + } + + NSMutableArray * drivesList; + drivesList = [NSMutableArray arrayWithCapacity: 1]; + + next_media = IOIteratorNext( media_iterator ); + if( next_media ) + { + char psz_buf[0x32]; + size_t dev_path_length; + CFTypeRef str_bsd_path; + do + { + str_bsd_path = + IORegistryEntryCreateCFProperty( next_media, + CFSTR( kIOBSDNameKey ), + kCFAllocatorDefault, + 0 ); + if( str_bsd_path == NULL ) + { + IOObjectRelease( next_media ); + continue; + } + + snprintf( psz_buf, sizeof(psz_buf), "%s%c", _PATH_DEV, 'r' ); + dev_path_length = strlen( psz_buf ); + + if( CFStringGetCString( (CFStringRef) str_bsd_path, + (char*)&psz_buf + dev_path_length, + sizeof(psz_buf) - dev_path_length, + kCFStringEncodingASCII ) ) + { + [drivesList addObject: + [NSString stringWithCString: psz_buf]]; + } + + CFRelease( str_bsd_path ); + + IOObjectRelease( next_media ); + + } while( ( next_media = IOIteratorNext( media_iterator ) ) ); + } + + IOObjectRelease( media_iterator ); + + [fDetectedPopUp removeAllItems]; + for( unsigned i = 0; i < [drivesList count]; i++ ) + { + [[fDetectedPopUp menu] addItemWithTitle: + [drivesList objectAtIndex: i] action: nil + keyEquivalent: @""]; + } + [self MatrixChanged: self]; +} + +- (void) EnableUI: (bool) b +{ + [fMatrix setEnabled: b]; + [fDetectedCell setEnabled: b]; + [fDetectedPopUp setEnabled: b]; + [fFolderCell setEnabled: b]; + [fFolderField setEnabled: b]; + [fBrowseButton setEnabled: b]; + [fOpenButton setEnabled: b]; + + if( b ) + { + [self MatrixChanged: nil]; + } +} + +- (void) UpdateUI: (hb_state_t *) s +{ + switch( s->state ) + { +#define p s->param.scanning + case HB_STATE_SCANNING: + [fStatusField setStringValue: [NSString stringWithFormat: + _( @"Scanning title %d of %d..." ), + p.title_cur, p.title_count]]; + [fIndicator setDoubleValue: 100.0 * ( p.title_cur - 1 ) / + p.title_count]; + break; +#undef p + + case HB_STATE_SCANDONE: + [self EnableUI: YES]; + [fIndicator setDoubleValue: 0.0]; + + if( hb_list_count( hb_get_titles( fHandle ) ) ) + { + /* Success */ + [fStatusField setStringValue: @""]; + [NSApp abortModal]; + } + else + { + [fStatusField setStringValue: + _( @"No valid title found." )]; + } + break; + } +} + +- (IBAction) MatrixChanged: (id) sender +{ + /* Do we have detected drives */ + if( [fDetectedPopUp numberOfItems] > 0 ) + { + [fDetectedCell setEnabled: YES]; + } + else + { + [fMatrix selectCell: fFolderCell]; + [fDetectedCell setEnabled: NO]; + } + + /* Enable controls related to the current choice */ + bool foo; + foo = ( [fMatrix selectedRow] == 0 ); + [fDetectedPopUp setEnabled: foo]; + [fFolderField setEnabled: !foo]; + [fBrowseButton setEnabled: !foo]; +} + +/* Browse: + Remove the current sheet (the scan panel) and show an OpenPanel. + Because we can't open the new sheet before the other one is + completely gone, we use performSelectorOnMainThread so it will be + done right afterwards */ +- (IBAction) Browse: (id) sender +{ + [NSApp stopModal]; + [self performSelectorOnMainThread: @selector( Browse2: ) + withObject: nil waitUntilDone: NO]; +} +- (void) Browse2: (id) sender +{ + NSOpenPanel * panel; + + panel = [NSOpenPanel openPanel]; + [panel setAllowsMultipleSelection: NO]; + [panel setCanChooseFiles: YES]; + [panel setCanChooseDirectories: YES ]; + + [panel beginSheetForDirectory: nil file: nil types: nil + modalForWindow: [NSApp mainWindow] modalDelegate: self + didEndSelector: @selector( BrowseDone:returnCode:contextInfo: ) + contextInfo: nil]; +} + +/* Get the folder and switch sheets again. Use the same trick as + above */ +- (void) BrowseDone: (NSOpenPanel *) sheet + returnCode: (int) returnCode contextInfo: (void *) contextInfo +{ + if( returnCode == NSOKButton ) + { + [fFolderField setStringValue: + [[sheet filenames] objectAtIndex: 0]]; + [self Open: nil]; + } + + [self performSelectorOnMainThread: @selector( BrowseDone2: ) + withObject: nil waitUntilDone: NO]; +} +- (void) BrowseDone2: (id) sender +{ + [NSApp beginSheet: fPanel modalForWindow: fWindow + modalDelegate: nil didEndSelector: nil contextInfo: nil]; + [NSApp runModalForWindow: fWindow]; + [NSApp endSheet: fPanel]; + [fPanel orderOut: self]; +} + +- (IBAction) Open: (id) sender +{ + NSString * path; + + [self EnableUI: NO]; + [fStatusField setStringValue: _( @"Opening..." )]; + + path = [fMatrix selectedRow] ? [fFolderField stringValue] : + [fDetectedPopUp titleOfSelectedItem]; + hb_scan( fHandle, [path UTF8String], 0 ); +} + +- (IBAction) Cancel: (id) sender +{ + [NSApp stopModal]; +} + +@end diff --git a/macosx/TargetSizeField.h b/macosx/TargetSizeField.h deleted file mode 100644 index d9396ee3a..000000000 --- a/macosx/TargetSizeField.h +++ /dev/null @@ -1,24 +0,0 @@ -/* $Id: TargetSizeField.h,v 1.3 2004/01/28 14:41:31 titer Exp $ - - This file is part of the HandBrake source code. - Homepage: <http://handbrake.m0k.org/>. - It may be used under the terms of the GNU General Public License. */ - -#include <Cocoa/Cocoa.h> - -#include "HandBrake.h" - -@interface HBTargetSizeField : NSTextField - -{ - HBTitle * fTitle; - IBOutlet NSPopUpButton * fRipFormatPopUp; - IBOutlet NSTextField * fRipCustomField; - IBOutlet NSPopUpButton * fRipLang2PopUp; - IBOutlet NSPopUpButton * fRipAudBitPopUp; -} - -- (void) SetHBTitle: (HBTitle *) title; -- (void) UpdateBitrate; - -@end diff --git a/macosx/TargetSizeField.mm b/macosx/TargetSizeField.mm deleted file mode 100644 index e113a4bf1..000000000 --- a/macosx/TargetSizeField.mm +++ /dev/null @@ -1,48 +0,0 @@ -/* $Id: TargetSizeField.mm,v 1.4 2004/01/28 14:41:31 titer Exp $ - - This file is part of the HandBrake source code. - Homepage: <http://handbrake.m0k.org/>. - It may be used under the terms of the GNU General Public License. */ - -#include "TargetSizeField.h" - -@implementation HBTargetSizeField - -- (void) textDidBeginEditing: (NSNotification *) notification -{ - [self UpdateBitrate]; - [super textDidBeginEditing: notification]; -} - -- (void) textDidEndEditing: (NSNotification *) notification -{ - [self UpdateBitrate]; - [super textDidEndEditing: notification]; -} - -- (void) textDidChange: (NSNotification *) notification -{ - [self UpdateBitrate]; - [super textDidChange: notification]; -} - -- (void) SetHBTitle: (HBTitle*) title -{ - fTitle = title; -} - -- (void) UpdateBitrate -{ - int size = [self intValue]; - int format = [fRipFormatPopUp indexOfSelectedItem]; - int muxer = ( format == 0 ) ? HB_MUX_MP4 : ( ( format == 1 ) ? - HB_MUX_OGM : HB_MUX_AVI ); - int audioCount = ( [fRipLang2PopUp selectedItem] == - [fRipLang2PopUp lastItem] ) ? 1 : 2; - int audioBitrate = [[fRipAudBitPopUp titleOfSelectedItem] intValue]; - - [fRipCustomField setIntValue: HBGetBitrateForSize( fTitle, size, - muxer, audioCount, audioBitrate )]; -} - -@end diff --git a/macosx/genstrings.sh b/macosx/genstrings.sh index 38da1de92..3c3215777 100755 --- a/macosx/genstrings.sh +++ b/macosx/genstrings.sh @@ -1,6 +1,6 @@ #! /bin/sh rm -f genstrings.tmp -cat Controller.mm | grep -v "^#define.*_(" | \ +cat *.mm | grep -v "^#define.*_(" | \ sed 's/_( \(@"[^"]*"\) )/NSLocalizedString( \1, nil )/g' > \ genstrings.tmp genstrings genstrings.tmp diff --git a/macosx/i18n/Localizable.strings b/macosx/i18n/Localizable.strings Binary files differindex cbad7b524..d2415f302 100644 --- a/macosx/i18n/Localizable.strings +++ b/macosx/i18n/Localizable.strings diff --git a/macosx/i18n/fr.strings b/macosx/i18n/fr.strings Binary files differindex c1218f28c..a2841c40e 100644 --- a/macosx/i18n/fr.strings +++ b/macosx/i18n/fr.strings diff --git a/macosx/main.mm b/macosx/main.mm index bd649f8ba..78f659e03 100644 --- a/macosx/main.mm +++ b/macosx/main.mm @@ -1,10 +1,10 @@ -/* $Id: main.mm,v 1.1.1.1 2003/11/03 12:03:51 titer Exp $ +/* $Id: main.mm,v 1.2 2004/10/26 20:49:41 titer Exp $ This file is part of the HandBrake source code. Homepage: <http://handbrake.m0k.org/>. It may be used under the terms of the GNU General Public License. */ -#import <Cocoa/Cocoa.h> +#include <Cocoa/Cocoa.h> int main( int argc, const char ** argv ) { |