withObject: NULL waitUntilDone: NO];
}
-- (NSApplicationTerminateReply) applicationShouldTerminate:
- (NSApplication *) app
+- (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication *) app
{
+ // Warn if encoding a movie
hb_state_t s;
- hb_get_state2( fHandle, &s );
- if ( s.state == HB_STATE_WORKING )
+ hb_get_state( fHandle, &s );
+ hb_job_t * job = hb_current_job( fHandle );
+ if ( job && ( s.state != HB_STATE_IDLE ) )
+ {
+ hb_job_t * job = hb_current_job( fHandle );
+ int result = NSRunCriticalAlertPanel(
+ NSLocalizedString(@"Are you sure you want to quit HandBrake?", nil),
+ NSLocalizedString(@"%@ is currently encoding. If you quit HandBrake, your movie will be lost. Do you want to quit anyway?", nil),
+ NSLocalizedString(@"Quit", nil), NSLocalizedString(@"Don't Quit", nil), nil,
+ job ? [NSString stringWithUTF8String:job->title->name] : @"A movie" );
+
+ if (result == NSAlertDefaultReturn)
+ {
+ [self doCancelCurrentJob];
+ return NSTerminateNow;
+ }
+ else
+ return NSTerminateCancel;
+ }
+
+ // Warn if items still in the queue
+ else if ( hb_count( fHandle ) > 0 )
{
- [self Cancel: NULL];
- return NSTerminateCancel;
- }
+ int result = NSRunCriticalAlertPanel(
+ NSLocalizedString(@"Are you sure you want to quit HandBrake?", nil),
+ NSLocalizedString(@"One or more encodes are queued for encoding. Do you want to quit anyway?", nil),
+ NSLocalizedString(@"Quit", nil), NSLocalizedString(@"Don't Quit", nil), nil);
+
+ if ( result == NSAlertDefaultReturn )
+ return NSTerminateNow;
+ else
+ return NSTerminateCancel;
+ }
+
return NSTerminateNow;
}
[item setLabel: @"Toggle Presets"];
[item setPaletteLabel: @"Toggler Presets"];
[item setToolTip: @"Open/Close Preset Drawer"];
- [item setImage: [NSImage imageNamed: @"Drawer-List2"]];
+ [item setImage: [NSImage imageNamed: @"Drawer"]];
[item setTarget: self];
[item setAction: @selector(toggleDrawer:)];
[item setAutovalidates: NO];
[item setLabel: @"Show Queue"];
[item setPaletteLabel: @"Show Queue"];
[item setToolTip: @"Show Queue"];
- [item setImage: [NSImage imageNamed: @"Brushed Window"]];
+ [item setImage: [NSImage imageNamed: @"Queue"]];
[item setTarget: self];
[item setAction: @selector(showQueueWindow:)];
[item setAutovalidates: NO];
[item setLabel: @"Add to Queue"];
[item setPaletteLabel: @"Add to Queue"];
[item setToolTip: @"Add to Queue"];
- [item setImage: [NSImage imageNamed: @"Add"]];
+ [item setImage: [NSImage imageNamed: @"AddToQueue"]];
[item setTarget: self];
[item setAction: @selector(addToQueue:)];
}
[item setLabel: @"Activity Window"];
[item setPaletteLabel: @"Show Activity Window"];
[item setToolTip: @"Show Activity Window"];
- [item setImage: [NSImage imageNamed: @"Terminal"]];
+ [item setImage: [NSImage imageNamed: @"ActivityWindow"]];
[item setTarget: self];
[item setAction: @selector(showDebugOutputPanel:)];
[item setAutovalidates: NO];
[item setLabel: @"Source"];
[item setPaletteLabel: @"Source"];
[item setToolTip: @"Choose Video Source"];
- [item setImage: [NSImage imageNamed: @"Disc"]];
+ [item setImage: [NSImage imageNamed: @"Source"]];
[item setTarget: self];
[item setAction: @selector(showScanPanel:)];
- [item setAutovalidates: NO];
}
else
{
frame.origin.y -= 36;
[fWindow setFrame:frame display:YES animate:YES];
fRipIndicatorShown = YES;
+ /* We check to see if we need to warn the user that the computer will go to sleep
+ or shut down when encoding is finished */
+ [self remindUserOfSleepOrShutdown];
}
/* Update dock icon */
if this is the first successful scan since launch and whether
or not we should set all settings to the defaults */
- SuccessfulScan = 1;
currentSuccessfulScanCount++;
- [self enableUI: YES];
-
[toolbar validateVisibleItems];
[fSrcTitlePopUp removeAllItems];
for( int i = 0; i < hb_list_count( list ); i++ )
{
title = (hb_title_t *) hb_list_item( list, i );
- /*Set DVD Name at top of window*/
- [fSrcDVD2Field setStringValue:[NSString stringWithUTF8String: title->name]];
-
- currentSource = [NSString stringWithUTF8String: title->dvd];
+ currentSource = [NSString stringWithUTF8String: title->dvd];
+
+ /* To get the source name as well as the default output name, first we check to see if
+ the selected directory is the VIDEO_TS Directory */
+ if ([[currentSource lastPathComponent] isEqualToString: @"VIDEO_TS"])
+ {
+ /* If VIDEO_TS Folder is chosen, choose its parent folder for the source display name */
+ sourceDisplayName = [NSString stringWithFormat:[[currentSource stringByDeletingLastPathComponent] lastPathComponent]];
+ }
+ else
+ {
+ /* if not the VIDEO_TS Folder, we can assume the chosen folder is the source name */
+ sourceDisplayName = [NSString stringWithFormat:[currentSource lastPathComponent]];
+ }
+ /*Set DVD Name at top of window*/
+ [fSrcDVD2Field setStringValue:[NSString stringWithFormat: @"%@", sourceDisplayName]];
/* Use the dvd name in the default output field here
May want to add code to remove blank spaces for some dvd names*/
if ([[NSUserDefaults standardUserDefaults] stringForKey:@"LastDestinationDirectory"])
{
[fDstFile2Field setStringValue: [NSString stringWithFormat:
- @"%@/%@.mp4", [[NSUserDefaults standardUserDefaults] stringForKey:@"LastDestinationDirectory"],[NSString
- stringWithUTF8String: title->name]]];
+ @"%@/%@.mp4", [[NSUserDefaults standardUserDefaults] stringForKey:@"LastDestinationDirectory"],sourceDisplayName]];
}
else
{
[fDstFile2Field setStringValue: [NSString stringWithFormat:
- @"%@/Desktop/%@.mp4", NSHomeDirectory(),[NSString
- stringWithUTF8String: title->name]]];
+ @"%@/Desktop/%@.mp4", NSHomeDirectory(),sourceDisplayName]];
}
[self titlePopUpChanged: NULL];
-
+ SuccessfulScan = 1;
[self enableUI: YES];
- /* we record the current source name here in case the next scan is unsuccessful,
- then we can replace the scan progress with the old name if necessary */
- sourceDisplayName = [NSString stringWithFormat:[fSrcDVD2Field stringValue]];
-
- /* if its the initial successful scan after awakeFromNib */
+ /* if its the initial successful scan after awakeFromNib */
if (currentSuccessfulScanCount == 1)
{
[self selectDefaultPreset: NULL];
}
else
{
+ /* if there are no jobs in the queue, then add this one to the queue and rip
+ otherwise, just rip the queue */
+ if( hb_count( fHandle ) == 0)
+ {
+ [self doAddToQueue];
+ }
+
+ NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent];
+ [[NSUserDefaults standardUserDefaults] setObject:destinationDirectory forKey:@"LastDestinationDirectory"];
[self doRip];
}
}
{
if( returnCode == NSAlertAlternateReturn )
{
- /* if there is no job in the queue, then add it to the queue and rip
- otherwise, there are already jobs in queue, so just rip the queue */
- int count = hb_count( fHandle );
- if( count == 0 )
+ /* if there are no jobs in the queue, then add this one to the queue and rip
+ otherwise, just rip the queue */
+ if( hb_count( fHandle ) == 0 )
{
[self doAddToQueue];
}
[NSApp terminate: self];
}
+- (void) remindUserOfSleepOrShutdown
+{
+ if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Put Computer To Sleep"])
+ {
+ /*Warn that computer will sleep after encoding*/
+ int reminduser;
+ NSBeep();
+ reminduser = NSRunAlertPanel(@"The computer will sleep after encoding is done.",@"You have selected to sleep the computer after encoding. To turn off sleeping, go to the HandBrake preferences.", @"OK", @"Preferences...", nil);
+ [NSApp requestUserAttention:NSCriticalRequest];
+ if ( reminduser == NSAlertAlternateReturn )
+ {
+ [self showPreferencesWindow:NULL];
+ }
+ }
+ else if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Shut Down Computer"])
+ {
+ /*Warn that computer will shut down after encoding*/
+ int reminduser;
+ NSBeep();
+ reminduser = NSRunAlertPanel(@"The computer will shut down after encoding is done.",@"You have selected to shut down the computer after encoding. To turn off shut down, go to the HandBrake preferences.", @"OK", @"Preferences...", nil);
+ [NSApp requestUserAttention:NSCriticalRequest];
+ if ( reminduser == NSAlertAlternateReturn )
+ {
+ [self showPreferencesWindow:NULL];
+ }
+ }
+
+}
+
+
- (void) doRip
{
/* Let libhb do the job */
+//------------------------------------------------------------------------------------
+// Removes all jobs from the queue. Does not cancel the current processing job.
+//------------------------------------------------------------------------------------
+- (void) doDeleteQueuedJobs
+{
+ hb_job_t * job;
+ while( ( job = hb_job( fHandle, 0 ) ) )
+ hb_rem( fHandle, job );
+}
//------------------------------------------------------------------------------------
// Cancels the current job and proceeds with the next one in the queue.
hb_job_t * job = hb_current_job(fHandle);
if (!job) return;
- // If command key is down, don't prompt
- BOOL hasCmdKeyMask = ([[NSApp currentEvent] modifierFlags] & NSCommandKeyMask) != 0;
- if (hasCmdKeyMask)
- [self doCancelCurrentJob];
+ NSString * alertTitle = [NSString stringWithFormat:NSLocalizedString(@"Do you want to stop encoding of %@?", nil),
+ [NSString stringWithUTF8String:job->title->name]];
+
+ // Which window to attach the sheet to?
+ NSWindow * docWindow;
+ if ([sender respondsToSelector: @selector(window)])
+ docWindow = [sender window];
else
- {
- NSString * alertTitle = [NSString stringWithFormat:NSLocalizedString(@"Do you want to stop encoding of %@?", nil),
- [NSString stringWithUTF8String:job->title->name]];
-
- // Which window to attach the sheet to?
- NSWindow * docWindow;
- if ([sender respondsToSelector: @selector(window)])
- docWindow = [sender window];
- else
- docWindow = fWindow;
-
- NSBeginCriticalAlertSheet(
- alertTitle,
- NSLocalizedString(@"Keep Encoding", nil), NSLocalizedString(@"Stop Encoding", nil), nil, docWindow, self,
- nil, @selector(didDimissCancelCurrentJob:returnCode:contextInfo:), nil,
- NSLocalizedString(@"Your movie will be lost if you don't continue encoding.", nil),
- [NSString stringWithUTF8String:job->title->name]);
+ docWindow = fWindow;
- // didDimissCancelCurrentJob:returnCode:contextInfo: will be called when the dialog is dismissed
-
- // N.B.: didDimissCancelCurrentJob:returnCode:contextInfo: is designated as the dismiss
- // selector to prevent a crash. As a dismiss selector, the alert window will
- // have already be dismissed. If we don't do it this way, the dismissing of
- // the alert window will cause the table view to be redrawn at a point where
- // current job has been deleted by hblib but we don't know about it yet. This
- // is a prime example of wy we need to NOT be relying on hb_current_job!!!!
- }
+ NSBeginCriticalAlertSheet(
+ alertTitle,
+ NSLocalizedString(@"Keep Encoding", nil),
+ NSLocalizedString(@"Delete All", nil),
+ NSLocalizedString(@"Stop Encoding", nil),
+ docWindow, self,
+ nil, @selector(didDimissCancelCurrentJob:returnCode:contextInfo:), nil,
+ NSLocalizedString(@"Your movie will be lost if you don't continue encoding.", nil),
+ [NSString stringWithUTF8String:job->title->name]);
+
+ // didDimissCancelCurrentJob:returnCode:contextInfo: will be called when the dialog is dismissed
+
+ // N.B.: didDimissCancelCurrentJob:returnCode:contextInfo: is designated as the dismiss
+ // selector to prevent a crash. As a dismiss selector, the alert window will
+ // have already be dismissed. If we don't do it this way, the dismissing of
+ // the alert window will cause the table view to be redrawn at a point where
+ // current job has been deleted by hblib but we don't know about it yet. This
+ // is a prime example of wy we need to NOT be relying on hb_current_job!!!!
}
- (void) didDimissCancelCurrentJob: (NSWindow *)sheet returnCode: (int)returnCode contextInfo: (void *)contextInfo
{
- if (returnCode == NSAlertAlternateReturn)
+ if (returnCode == NSAlertOtherReturn)
+ [self doCancelCurrentJob];
+ else if (returnCode == NSAlertAlternateReturn)
+ {
+ [self doDeleteQueuedJobs];
[self doCancelCurrentJob];
+ }
}
- (IBAction) formatPopUpChanged: (id) sender
{
NSString * string = [fDstFile2Field stringValue];
+ NSString * selectedCodecs = [fDstCodecsPopUp titleOfSelectedItem];
int format = [fDstFormatPopUp indexOfSelectedItem];
char * ext = NULL;
/* Initially set the large file (64 bit formatting) output checkbox to hidden */
[fCreateChapterMarkers setEnabled: YES];
break;
}
+ if ( SuccessfulScan ) {
+ [fDstCodecsPopUp selectItemWithTitle:selectedCodecs];
+ if ( [fDstCodecsPopUp selectedItem] == NULL )
+ [fDstCodecsPopUp selectItemAtIndex:0];
+ }
[self codecsPopUpChanged: NULL];
/* Add/replace to the correct extension */
int audioCodecsSupportMono = ((audio->codec == HB_ACODEC_AC3 ||
audio->codec == HB_ACODEC_DCA) && acodec == HB_ACODEC_FAAC);
int audioCodecsSupport6Ch = ((audio->codec == HB_ACODEC_AC3 ||
- audio->codec == HB_ACODEC_DCA) && acodec == HB_ACODEC_FAAC);
+ audio->codec == HB_ACODEC_DCA) && (acodec == HB_ACODEC_FAAC ||
+ acodec == HB_ACODEC_VORBIS));
/* check for AC-3 passthru */
if (audio->codec == HB_ACODEC_AC3 && acodec == HB_ACODEC_AC3)
break;
case HB_ACODEC_VORBIS:
+ if ([[fAudTrack1MixPopUp selectedItem] tag] == HB_AMIXDOWN_6CH || [[fAudTrack2MixPopUp selectedItem] tag] == HB_AMIXDOWN_6CH)
+ {
+ /* Vorbis causes a crash if we use a bitrate below 192 kbps with 6 channel */
+ minbitrate = 192;
+ /* If either mixdown popup includes 6-channel discrete, then allow up to 384 kbps */
+ maxbitrate = 384;
+ break;
+ }
+ else
+ {
/* Vorbis causes a crash if we use a bitrate below 48 kbps */
minbitrate = 48;
/* Vorbis can cope with 384 kbps quite happily, even for stereo */
maxbitrate = 384;
break;
+ }
default:
/* AC3 passthru disables the bitrate dropdown anyway, so we might as well just use the min and max bitrate */
- (IBAction) calculateBitrate: (id) sender
{
- if( !fHandle || [fVidQualityMatrix selectedRow] != 0 )
+ if( !fHandle || [fVidQualityMatrix selectedRow] != 0 || !SuccessfulScan )
{
return;
}