From 35c3cb421abbf6c79d640b5b9695198a75fe963b Mon Sep 17 00:00:00 2001 From: dynaflash Date: Tue, 11 Sep 2007 15:03:01 +0000 Subject: [PATCH] MacGui: New queue enhancements - clean up work related to starting and stopping of jobs to make sure the behavior is the same in both the queue window and the main window - No longer adds jobs to queue when you've hit Start but then canceled the overwrite warning. - Added overwrite alert when doing an Add to Queue. Was only happening previously when you did a Start. - Stopping a job from either the Queue window or the Main window now goes through the same code path and so the behavior will be identical. - In the main window, the Start button now changes to Start Queue once you've added things to the queue. This helps clear up any ambiguity about what that button will do - Cancel button now named Stop. Recommended by BradleyS and/or hawkman I think because this button no longer cancels everything in the queue, just the current job. Wording in the stop warning dialog has been improved (mentions job title). - The "Show Alert When Done" options now work when you have started the queue from the Queue window. - Uses the term "passes" in main window - Added unique icons for each pass type. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@949 b64f7644-9d1e-0410-96f1-a4d463321fa5 --- macosx/Controller.h | 9 +- macosx/Controller.mm | 426 +++-- macosx/English.lproj/Queue.nib/classes.nib | 13 +- macosx/English.lproj/Queue.nib/info.nib | 2 +- .../English.lproj/Queue.nib/keyedobjects.nib | 1514 +++++------------ macosx/HBQueueController.h | 22 +- macosx/HBQueueController.mm | 953 +++++++---- macosx/HandBrake.xcodeproj/project.pbxproj | 58 +- macosx/icons/Detail.png | Bin 0 -> 1808 bytes macosx/icons/DetailPressed.png | Bin 0 -> 4164 bytes macosx/icons/JobPassFirstLarge.png | Bin 0 -> 620 bytes macosx/icons/JobPassFirstSmall.png | Bin 0 -> 280 bytes macosx/icons/JobPassSecondLarge.png | Bin 0 -> 923 bytes macosx/icons/JobPassSecondSmall.png | Bin 0 -> 322 bytes macosx/icons/JobPassSubtitleLarge.png | Bin 0 -> 1051 bytes macosx/icons/JobPassSubtitleSmall.png | Bin 0 -> 333 bytes macosx/icons/JobPassUnknownLarge.png | Bin 0 -> 454 bytes macosx/icons/JobPassUnknownSmall.png | Bin 0 -> 234 bytes 18 files changed, 1383 insertions(+), 1614 deletions(-) create mode 100644 macosx/icons/Detail.png create mode 100644 macosx/icons/DetailPressed.png create mode 100644 macosx/icons/JobPassFirstLarge.png create mode 100644 macosx/icons/JobPassFirstSmall.png create mode 100644 macosx/icons/JobPassSecondLarge.png create mode 100644 macosx/icons/JobPassSecondSmall.png create mode 100644 macosx/icons/JobPassSubtitleLarge.png create mode 100644 macosx/icons/JobPassSubtitleSmall.png create mode 100644 macosx/icons/JobPassUnknownLarge.png create mode 100644 macosx/icons/JobPassUnknownSmall.png diff --git a/macosx/Controller.h b/macosx/Controller.h index dd985a7b1..807e08ff7 100644 --- a/macosx/Controller.h +++ b/macosx/Controller.h @@ -221,6 +221,10 @@ - (IBAction) openMainWindow: (id) sender; - (IBAction) addToQueue: (id) sender; +- (void) overwriteAddToQueueAlertDone: (NSWindow *) sheet + returnCode: (int) returnCode contextInfo: (void *) contextInfo; +- (void) doAddToQueue; + - (IBAction) showQueueWindow:(id)sender; - (IBAction)showPreferencesWindow:(id)sender; @@ -230,10 +234,9 @@ returnCode: (int) returnCode contextInfo: (void *) contextInfo; - (void) updateAlertDone: (NSWindow *) sheet returnCode: (int) returnCode contextInfo: (void *) contextInfo; -- (void) _Rip; +- (void) doRip; + - (IBAction) Cancel: (id) sender; -- (void) _Cancel: (NSWindow *) sheet returnCode: (int) returnCode - contextInfo: (void *) contextInfo; - (IBAction) Pause: (id) sender; - (IBAction) calculateBitrate: (id) sender; diff --git a/macosx/Controller.mm b/macosx/Controller.mm index 297eaf7e2..86d18ff13 100644 --- a/macosx/Controller.mm +++ b/macosx/Controller.mm @@ -51,23 +51,6 @@ static NSString * AddToQueueIdentifier = @"Add to Queue Ite static NSString * ShowActivityIdentifier = @"Debug Output Item Identifier"; static NSString * ChooseSourceIdentifier = @"Choose Source Item Identifier"; -/** - * Returns the number of jobs groups in the queue. - * @param h Handle to hb_handle_t. - * @return Number of job groups. - */ -static int hb_group_count(hb_handle_t * h) -{ - hb_job_t * job; - int count = 0; - int index = 0; - while( ( job = hb_job( h, index++ ) ) ) - { - if (job->sequence_id == 0) - count++; - } - return count; -} /******************************* * HBController implementation * @@ -101,6 +84,7 @@ static int hb_group_count(hb_handle_t * h) /* Init others controllers */ [fPictureController SetHandle: fHandle]; [fQueueController setHandle: fHandle]; + [fQueueController setHBController: self]; fChapterTitlesDelegate = [[ChapterTitles alloc] init]; [fChapterTable setDataSource:fChapterTitlesDelegate]; @@ -433,7 +417,7 @@ static int hb_group_count(hb_handle_t * h) { return [NSArray arrayWithObjects: StartEncodingIdentifier, PauseEncodingIdentifier, AddToQueueIdentifier, ChooseSourceIdentifier, ShowQueueIdentifier, ShowActivityIdentifier, ToggleDrawerIdentifier, - NSToolbarCustomizeToolbarItemIdentifier, NSToolbarFlexibleSpaceItemIdentifier, NSToolbarSpaceItemIdentifier, + NSToolbarCustomizeToolbarItemIdentifier, NSToolbarFlexibleSpaceItemIdentifier, NSToolbarSpaceItemIdentifier, NSToolbarSeparatorItemIdentifier, nil]; } @@ -451,9 +435,9 @@ static int hb_group_count(hb_handle_t * h) if ([ident isEqualToString: StartEncodingIdentifier]) { [toolbarItem setImage: [NSImage imageNamed: @"Stop"]]; - [toolbarItem setLabel: @"Cancel"]; - [toolbarItem setPaletteLabel: @"Cancel"]; - [toolbarItem setToolTip: @"Cancel Encoding"]; + [toolbarItem setLabel: @"Stop"]; + [toolbarItem setPaletteLabel: @"Stop"]; + [toolbarItem setToolTip: @"Stop Encoding"]; return YES; } if ([ident isEqualToString: PauseEncodingIdentifier]) @@ -490,7 +474,10 @@ static int hb_group_count(hb_handle_t * h) if ([ident isEqualToString: StartEncodingIdentifier]) { [toolbarItem setImage: [NSImage imageNamed: @"Play"]]; - [toolbarItem setLabel: @"Start"]; + if (hb_count(fHandle) > 0) + [toolbarItem setLabel: @"Start Queue"]; + else + [toolbarItem setLabel: @"Start"]; [toolbarItem setPaletteLabel: @"Start Encoding"]; [toolbarItem setToolTip: @"Start Encoding"]; return YES; @@ -707,8 +694,6 @@ static int hb_group_count(hb_handle_t * h) [self showNewScan: NULL]; } - BOOL jobGroups = [[NSUserDefaults standardUserDefaults] boolForKey:@"QueueShowsJobsAsGroups"]; - hb_state_t s; hb_get_state( fHandle, &s ); @@ -768,7 +753,7 @@ static int hb_group_count(hb_handle_t * h) [fRipIndicator setDoubleValue: 100.0 * progress_total]; // If progress bar hasn't been revealed at the bottom of the window, do - // that now. This code used to be in _Rip. I moved it to here to handle + // that now. This code used to be in doRip. I moved it to here to handle // the case where hb_start is called by HBQueueController and not from // HBController. if (!fRipIndicatorShown) @@ -832,6 +817,27 @@ static int hb_group_count(hb_handle_t * h) case HB_STATE_WORKDONE: { + // HB_STATE_WORKDONE happpens as a result of hblib finishing all its jobs + // or someone calling hb_stop. In the latter case, hb_stop does not clear + // out the remaining passes/jobs in the queue. We'll do that here. + + // Delete all remaining scans of this job, ie, delete whole encodes. + hb_job_t * job; + while( ( job = hb_job( fHandle, 0 ) ) && (job->sequence_id != 0) ) + hb_rem( fHandle, job ); + + // Start processing back up if jobs still left in queue + if (hb_count(fHandle) > 0) + { + hb_start(fHandle); + fEncodeState = 1; + // Validate the toolbar (hack). The toolbar will usually get autovalidated + // before we had the chance to restart the queue, hence it will now be in + // the wrong state. + [toolbar validateVisibleItems]; + break; + } + [fStatusField setStringValue: _( @"Done." )]; [fRipIndicator setIndeterminate: NO]; [fRipIndicator setDoubleValue: 0.0]; @@ -840,21 +846,6 @@ static int hb_group_count(hb_handle_t * h) /* Restore dock icon */ [self UpdateDockIcon: -1.0]; - if (jobGroups) - { - // Delete all remaining scans of this job - hb_job_t * job; - while( ( job = hb_job( fHandle, 0 ) ) && (job->sequence_id != 0) ) - hb_rem( fHandle, job ); - } - - // Start processing back up if jobs still left in queue - if (hb_count(fHandle) > 0) - { - hb_start(fHandle); - break; - } - if (fRipIndicatorShown) { NSRect frame = [fWindow frame]; @@ -888,7 +879,7 @@ static int hb_group_count(hb_handle_t * h) /*On Screen Notification*/ int status; NSBeep(); - status = NSRunAlertPanel(@"Put down that cocktail...",@"your HandBrake encode is done!", @"OK", nil, nil); + status = NSRunAlertPanel(@"Put down that cocktail...",@"Your HandBrake encode is done!", @"OK", nil, nil); [NSApp requestUserAttention:NSCriticalRequest]; if ( status == NSAlertDefaultReturn ) { @@ -943,12 +934,12 @@ static int hb_group_count(hb_handle_t * h) } /* Lets show the queue status here in the main window */ - int queue_count = jobGroups ? hb_group_count( fHandle ) : hb_count( fHandle ); + int queue_count = hb_count( fHandle ); if( queue_count ) { [fQueueStatus setStringValue: [NSString stringWithFormat: - @"%d task%s in the queue", - queue_count, ( queue_count > 1 ) ? "s" : ""]]; + @"%d pass%s in the queue", + queue_count, ( queue_count > 1 ) ? "es" : ""]]; } else { @@ -1540,114 +1531,142 @@ static int hb_group_count(hb_handle_t * h) +/* addToQueue: puts up an alert before ultimately calling doAddToQueue +*/ - (IBAction) addToQueue: (id) sender { -/* We get the destination directory from the destingation field here */ + /* We get the destination directory from the destination field here */ NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent]; /* We check for a valid destination here */ if ([[NSFileManager defaultManager] fileExistsAtPath:destinationDirectory] == 0) { NSRunAlertPanel(@"Warning!", @"This is not a valid destination directory!", @"OK", nil, nil); + return; } - else - { - - 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; - - // Assign a sequence number, starting at zero, to each job added so they can - // be lumped together in the UI. - job->sequence_id = -1; - - [self PrepareJob]; - - /* Destination file */ - job->file = [[fDstFile2Field stringValue] UTF8String]; - if( [fSubForcedCheck state] == NSOnState ) - { - job->subtitle_force = 1; - } else { - job->subtitle_force = 0; - } + /* We check for duplicate name here */ + if( [[NSFileManager defaultManager] fileExistsAtPath: + [fDstFile2Field stringValue]] ) + { + NSBeginCriticalAlertSheet( _( @"File already exists" ), + _( @"Cancel" ), _( @"Overwrite" ), NULL, fWindow, self, + @selector( overwriteAddToQueueAlertDone:returnCode:contextInfo: ), + NULL, NULL, [NSString stringWithFormat: + _( @"Do you want to overwrite %@?" ), + [fDstFile2Field stringValue]] ); + // overwriteAddToQueueAlertDone: will be called when the alert is dismissed. + } + else + { + [self doAddToQueue]; + } +} - /* - * subtitle of -1 is a scan - */ - if( job->subtitle == -1 ) - { - char *x264opts_tmp; - - /* - * When subtitle scan is enabled do a fast pre-scan job - * which will determine which subtitles to enable, if any. - */ - job->pass = -1; - x264opts_tmp = job->x264opts; - job->subtitle = -1; - - job->x264opts = NULL; - - job->indepth_scan = 1; - - job->select_subtitle = (hb_subtitle_t**)malloc(sizeof(hb_subtitle_t*)); - *(job->select_subtitle) = NULL; - - /* - * Add the pre-scan job - */ - job->sequence_id++; // for job grouping - hb_add( fHandle, job ); - - job->x264opts = x264opts_tmp; - } else { - job->select_subtitle = NULL; - } +/* overwriteAddToQueueAlertDone: called from the alert posted by addToQueue that asks + the user if they want to overwrite an exiting movie file. +*/ +- (void) overwriteAddToQueueAlertDone: (NSWindow *) sheet + returnCode: (int) returnCode contextInfo: (void *) contextInfo +{ + if( returnCode == NSAlertAlternateReturn ) + [self doAddToQueue]; +} - /* No subtitle were selected, so reset the subtitle to -1 (which before - * this point meant we were scanning - */ - if( job->subtitle == -2 ) - { - job->subtitle = -1; - } +- (void) doAddToQueue +{ + 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; - if( [fVidTwoPassCheck state] == NSOnState ) - { - hb_subtitle_t **subtitle_tmp = job->select_subtitle; - job->indepth_scan = 0; + // Assign a sequence number, starting at zero, to each job added so they can + // be lumped together in the UI. + job->sequence_id = -1; - job->pass = 1; - job->sequence_id++; // for job grouping - hb_add( fHandle, job ); - - job->pass = 2; - job->sequence_id++; // for job grouping - - job->x264opts = (char *)calloc(1024, 1); /* Fixme, this just leaks */ - strcpy(job->x264opts, [[fAdvancedOptions optionsString] UTF8String]); + [self PrepareJob]; - job->select_subtitle = subtitle_tmp; + /* Destination file */ + job->file = [[fDstFile2Field stringValue] UTF8String]; - hb_add( fHandle, job ); - } - else - { - job->indepth_scan = 0; - job->pass = 0; - job->sequence_id++; // for job grouping - hb_add( fHandle, job ); - } + if( [fSubForcedCheck state] == NSOnState ) + job->subtitle_force = 1; + else + job->subtitle_force = 0; + + /* + * subtitle of -1 is a scan + */ + if( job->subtitle == -1 ) + { + char *x264opts_tmp; + + /* + * When subtitle scan is enabled do a fast pre-scan job + * which will determine which subtitles to enable, if any. + */ + job->pass = -1; + x264opts_tmp = job->x264opts; + job->subtitle = -1; + + job->x264opts = NULL; + + job->indepth_scan = 1; + + job->select_subtitle = (hb_subtitle_t**)malloc(sizeof(hb_subtitle_t*)); + *(job->select_subtitle) = NULL; + + /* + * Add the pre-scan job + */ + job->sequence_id++; // for job grouping + hb_add( fHandle, job ); + + job->x264opts = x264opts_tmp; + } + else + job->select_subtitle = NULL; + + /* No subtitle were selected, so reset the subtitle to -1 (which before + * this point meant we were scanning + */ + if( job->subtitle == -2 ) + job->subtitle = -1; + + if( [fVidTwoPassCheck state] == NSOnState ) + { + hb_subtitle_t **subtitle_tmp = job->select_subtitle; + job->indepth_scan = 0; + + job->pass = 1; + job->sequence_id++; // for job grouping + hb_add( fHandle, job ); + + job->pass = 2; + job->sequence_id++; // for job grouping + + job->x264opts = (char *)calloc(1024, 1); /* Fixme, this just leaks */ + strcpy(job->x264opts, [[fAdvancedOptions optionsString] UTF8String]); + + job->select_subtitle = subtitle_tmp; + + hb_add( fHandle, job ); + } + else + { + job->indepth_scan = 0; + job->pass = 0; + job->sequence_id++; // for job grouping + hb_add( fHandle, job ); + } + NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent]; [[NSUserDefaults standardUserDefaults] setObject:destinationDirectory forKey:@"LastDestinationDirectory"]; /* Lets try to update stuff, taken from remove in the queue controller */ [fQueueController performSelectorOnMainThread: @selector( updateQueueUI ) withObject: NULL waitUntilDone: NO]; - } } +/* Rip: puts up an alert before ultimately calling doRip +*/ - (IBAction) Rip: (id) sender { /* Rip or Cancel ? */ @@ -1659,17 +1678,26 @@ static int hb_group_count(hb_handle_t * h) [self Cancel: sender]; return; } - /* 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 < 1 ) - { - [self addToQueue: sender]; - } - /* We check for duplicate name here */ - if( [[NSFileManager defaultManager] fileExistsAtPath: - [fDstFile2Field stringValue]] ) + // If there are jobs in the queue, then this is a rip the queue + + if (hb_count( fHandle ) > 0) + { + [self doRip]; + return; + } + + // Before adding jobs to the queue, check for a valid destination. + + NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent]; + if ([[NSFileManager defaultManager] fileExistsAtPath:destinationDirectory] == 0) + { + NSRunAlertPanel(@"Warning!", @"This is not a valid destination directory!", @"OK", nil, nil); + return; + } + + /* We check for duplicate name here */ + if( [[NSFileManager defaultManager] fileExistsAtPath:[fDstFile2Field stringValue]] ) { NSBeginCriticalAlertSheet( _( @"File already exists" ), _( @"Cancel" ), _( @"Overwrite" ), NULL, fWindow, self, @@ -1677,31 +1705,34 @@ static int hb_group_count(hb_handle_t * h) NULL, NULL, [NSString stringWithFormat: _( @"Do you want to overwrite %@?" ), [fDstFile2Field stringValue]] ); - return; + + // overWriteAlertDone: will be called when the alert is dismissed. It will call doRip. + } + else + { + [self doRip]; } - /* We get the destination directory from the destination field here */ - NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent]; - /* We check for a valid destination here */ - if ([[NSFileManager defaultManager] fileExistsAtPath:destinationDirectory] == 0) - { - NSRunAlertPanel(@"Warning!", @"This is not a valid destination directory!", @"OK", nil, nil); - } - else - { - [[NSUserDefaults standardUserDefaults] setObject:destinationDirectory forKey:@"LastDestinationDirectory"]; - [self _Rip]; - } - - - } +/* overWriteAlertDone: called from the alert posted by Rip: that asks the user if they + want to overwrite an exiting movie file. +*/ - (void) overWriteAlertDone: (NSWindow *) sheet returnCode: (int) returnCode contextInfo: (void *) contextInfo { if( returnCode == NSAlertAlternateReturn ) { - [self _Rip]; + /* 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 ) + { + [self doAddToQueue]; + } + + NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent]; + [[NSUserDefaults standardUserDefaults] setObject:destinationDirectory forKey:@"LastDestinationDirectory"]; + [self doRip]; } } @@ -1721,7 +1752,7 @@ static int hb_group_count(hb_handle_t * h) [NSApp terminate: self]; } -- (void) _Rip +- (void) doRip { /* Let libhb do the job */ hb_start( fHandle ); @@ -1729,25 +1760,82 @@ static int hb_group_count(hb_handle_t * h) fEncodeState = 1; } -- (IBAction) Cancel: (id) sender + + + + +//------------------------------------------------------------------------------------ +// Cancels the current job and proceeds with the next one in the queue. +//------------------------------------------------------------------------------------ +- (void) doCancelCurrentJob { - NSBeginCriticalAlertSheet( _( @"Cancel - Are you sure?" ), - _( @"Keep working" ), _( @"Cancel encoding" ), NULL, fWindow, self, - @selector( _Cancel:returnCode:contextInfo: ), NULL, NULL, - _( @"Encoding won't be recoverable." ) ); + // Stop the current job. hb_stop will only cancel the current pass and then set + // its state to HB_STATE_WORKDONE. It also does this asynchronously. So when we + // see the state has changed to HB_STATE_WORKDONE (in updateUI), we'll delete the + // remaining passes of the job and then start the queue back up if there are any + // remaining jobs. + + hb_stop( fHandle ); + fEncodeState = 2; // don't alert at end of processing since this was a cancel + } -- (void) _Cancel: (NSWindow *) sheet - returnCode: (int) returnCode contextInfo: (void *) contextInfo +//------------------------------------------------------------------------------------ +// Displays an alert asking user if the want to cancel encoding of current job. +// Cancel: returns immediately after posting the alert. Later, when the user +// acknowledges the alert, doCancelCurrentJob is called. +//------------------------------------------------------------------------------------ +- (IBAction)Cancel: (id)sender { - if( returnCode == NSAlertAlternateReturn ) + if (!fHandle) return; + + 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]; + else { - hb_stop( fHandle ); - /*set the fEncodeState State */ - fEncodeState = 2; + 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]); + + // 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) + [self doCancelCurrentJob]; +} + + + + + - (IBAction) Pause: (id) sender { hb_state_t s; diff --git a/macosx/English.lproj/Queue.nib/classes.nib b/macosx/English.lproj/Queue.nib/classes.nib index 4e9bbaa78..3e0a52912 100644 --- a/macosx/English.lproj/Queue.nib/classes.nib +++ b/macosx/English.lproj/Queue.nib/classes.nib @@ -212,32 +212,31 @@ }; SUPERCLASS = NSObject; }, + {CLASS = HBImageAndTextCell; LANGUAGE = ObjC; SUPERCLASS = NSTextFieldCell; }, {CLASS = HBPictureGLView; LANGUAGE = ObjC; SUPERCLASS = NSOpenGLView; }, { ACTIONS = { cancelCurrentJob = id; - detailChanged = id; - jobGroupsChanged = id; + hideDetail = id; removeSelectedJob = id; + showDetail = id; + showJobsAsGroups = id; + showJobsAsPasses = id; showQueueWindow = id; - toggleShowsDetail = id; - toggleShowsJobsAsGroups = id; toggleStartPause = id; }; CLASS = HBQueueController; LANGUAGE = ObjC; OUTLETS = { fCurrentJobPane = NSView; - fDetailCheckbox = NSButton; fJobDescTextField = NSTextField; - fJobGroupsCheckbox = NSButton; fJobIconView = NSImageView; + fOutlineView = NSOutlineView; fProgressBar = NSProgressIndicator; fProgressTextField = NSTextField; fQueueCountField = NSTextField; fQueuePane = NSView; fQueueWindow = NSWindow; - fStartPauseButton = NSButton; fTaskView = NSTableView; }; SUPERCLASS = NSObject; diff --git a/macosx/English.lproj/Queue.nib/info.nib b/macosx/English.lproj/Queue.nib/info.nib index f2104c54a..0d9cf8ed4 100644 --- a/macosx/English.lproj/Queue.nib/info.nib +++ b/macosx/English.lproj/Queue.nib/info.nib @@ -3,7 +3,7 @@ IBDocumentLocation - 63 594 453 434 0 0 1680 1028 + 361 594 453 434 0 0 1680 1028 IBFramework Version 446.1 IBLockedObjects diff --git a/macosx/English.lproj/Queue.nib/keyedobjects.nib b/macosx/English.lproj/Queue.nib/keyedobjects.nib index 2b8608f38..b43b41bee 100644 --- a/macosx/English.lproj/Queue.nib/keyedobjects.nib +++ b/macosx/English.lproj/Queue.nib/keyedobjects.nib @@ -11,32 +11,32 @@ $class CF$UID - 264 + 222 NSAccessibilityConnectors CF$UID - 261 + 219 NSAccessibilityOidsKeys CF$UID - 262 + 220 NSAccessibilityOidsValues CF$UID - 263 + 221 NSClassesKeys CF$UID - 216 + 183 NSClassesValues CF$UID - 217 + 184 NSConnections @@ -56,34 +56,34 @@ NSNamesKeys CF$UID - 202 + 171 NSNamesValues CF$UID - 203 + 172 NSNextOid - 2596 + 2610 NSObjectsKeys CF$UID - 199 + 168 NSObjectsValues CF$UID - 201 + 170 NSOidsKeys CF$UID - 218 + 185 NSOidsValues CF$UID - 219 + 186 NSRoot @@ -160,7 +160,7 @@ $class CF$UID - 67 + 65 NS.objects @@ -170,79 +170,55 @@ CF$UID - 74 - - - CF$UID - 150 - - - CF$UID - 152 + 72 CF$UID - 154 - - - CF$UID - 156 - - - CF$UID - 158 - - - CF$UID - 160 - - - CF$UID - 162 + 131 CF$UID - 165 + 133 CF$UID - 167 + 135 CF$UID - 169 + 137 CF$UID - 171 + 139 CF$UID - 186 + 141 CF$UID - 187 + 144 CF$UID - 189 + 146 CF$UID - 191 + 148 CF$UID - 193 + 163 CF$UID - 195 + 164 CF$UID - 197 + 166 @@ -250,7 +226,7 @@ $class CF$UID - 73 + 71 NSDestination @@ -260,7 +236,7 @@ NSLabel CF$UID - 72 + 70 NSSource @@ -272,22 +248,22 @@ $class CF$UID - 71 + 69 NSClassName CF$UID - 69 + 67 NSExtension CF$UID - 70 + 68 NSFrame CF$UID - 68 + 66 NSNextResponder @@ -311,12 +287,12 @@ $class CF$UID - 179 + 156 NSFrame CF$UID - 178 + 155 NSNextResponder @@ -326,14 +302,14 @@ NSSubviews CF$UID - 177 + 154 $class CF$UID - 67 + 65 NS.objects @@ -351,11 +327,11 @@ CF$UID - 52 + 48 CF$UID - 57 + 53 @@ -629,7 +605,7 @@ $class CF$UID - 51 + 47 NSCell @@ -708,7 +684,7 @@ $class CF$UID - 50 + 46 NSAlign 0 @@ -718,45 +694,11 @@ 130560 NSCellFlags2 33554432 - NSContents - - CF$UID - 46 - NSScale 0 NSStyle 0 - - $class - - CF$UID - 49 - - NSClassName - - CF$UID - 47 - - NSResourceName - - CF$UID - 48 - - - NSImage - JobLarge - - $classes - - NSCustomResource - %NSCustomResource - NSObject - - $classname - NSCustomResource - $classes @@ -789,14 +731,14 @@ NSCell CF$UID - 54 + 50 NSEnabled NSFrame CF$UID - 53 + 49 NSNextResponder @@ -830,17 +772,17 @@ NSContents CF$UID - 55 + 51 NSControlView CF$UID - 52 + 48 NSSupport CF$UID - 56 + 52 NSTextColor @@ -869,19 +811,19 @@ $class CF$UID - 66 + 64 NSCell CF$UID - 59 + 55 NSEnabled NSFrame CF$UID - 58 + 54 NSNextResponder @@ -901,7 +843,7 @@ $class CF$UID - 65 + 63 NSAlternateContents @@ -911,7 +853,7 @@ NSAlternateImage CF$UID - 62 + 60 NSButtonFlags 138690815 @@ -929,17 +871,17 @@ NSControlView CF$UID - 57 + 53 NSKeyEquivalent CF$UID - 64 + 62 NSNormalImage CF$UID - 60 + 56 NSPeriodicDelay 200 @@ -948,42 +890,53 @@ NSSupport CF$UID - 56 + 52 $class CF$UID - 49 + 59 NSClassName CF$UID - 47 + 57 NSResourceName CF$UID - 61 + 58 + NSImage Delete + + $classes + + NSCustomResource + %NSCustomResource + NSObject + + $classname + NSCustomResource + $class CF$UID - 49 + 59 NSClassName CF$UID - 47 + 57 NSResourceName CF$UID - 63 + 61 DeletePressed @@ -1059,17 +1012,17 @@ $class CF$UID - 73 + 71 NSDestination CF$UID - 75 + 73 NSLabel CF$UID - 149 + 130 NSSource @@ -1081,22 +1034,22 @@ $class CF$UID - 71 + 69 NSClassName CF$UID - 69 + 67 NSExtension CF$UID - 70 + 68 NSFrameSize CF$UID - 148 + 129 NSNextResponder @@ -1106,7 +1059,7 @@ NSSubviews CF$UID - 76 + 74 NSSuperview @@ -1120,29 +1073,17 @@ $class CF$UID - 67 + 65 NS.objects CF$UID - 77 - - - CF$UID - 82 - - - CF$UID - 131 - - - CF$UID - 138 + 75 CF$UID - 144 + 80 @@ -1155,29 +1096,29 @@ NSCell CF$UID - 79 + 77 NSEnabled NSFrame CF$UID - 78 + 76 NSNextResponder CF$UID - 75 + 73 NSSuperview CF$UID - 75 + 73 NSvFlags 264 - {{17, 227}, {231, 14}} + {{17, 227}, {540, 14}} $class @@ -1196,17 +1137,17 @@ NSContents CF$UID - 80 + 78 NSControlView CF$UID - 77 + 75 NSSupport CF$UID - 81 + 79 NSTextColor @@ -1235,32 +1176,32 @@ $class CF$UID - 130 + 128 NSContentView CF$UID - 84 + 82 NSFrame CF$UID - 129 + 127 NSHScroller CF$UID - 126 + 124 NSNextKeyView CF$UID - 84 + 82 NSNextResponder CF$UID - 75 + 73 NSScrollAmts @@ -1269,17 +1210,17 @@ NSSubviews CF$UID - 83 + 81 NSSuperview CF$UID - 75 + 73 NSVScroller CF$UID - 122 + 120 NSsFlags 18 @@ -1290,21 +1231,21 @@ $class CF$UID - 67 + 65 NS.objects CF$UID - 84 + 82 CF$UID - 122 + 120 CF$UID - 126 + 124 @@ -1312,42 +1253,42 @@ $class CF$UID - 121 + 119 NSBGColor CF$UID - 109 + 107 NSDocView CF$UID - 86 + 84 NSFrame CF$UID - 120 + 118 NSNextKeyView CF$UID - 86 + 84 NSNextResponder CF$UID - 82 + 80 NSSubviews CF$UID - 85 + 83 NSSuperview CF$UID - 82 + 80 NScvFlags 4 @@ -1358,13 +1299,13 @@ $class CF$UID - 67 + 65 NS.objects CF$UID - 86 + 84 @@ -1372,19 +1313,19 @@ $class CF$UID - 119 + 117 NSBackgroundColor CF$UID - 97 + 95 NSColumnAutoresizingStyle 1 NSCornerView CF$UID - 88 + 86 NSDraggingSourceMaskForLocal 15 @@ -1395,12 +1336,12 @@ NSFrameSize CF$UID - 87 + 85 NSGridColor CF$UID - 116 + 114 NSIntercellSpacingHeight 2 @@ -1409,36 +1350,36 @@ NSNextResponder CF$UID - 84 + 82 NSRowHeight 17 NSSuperview CF$UID - 84 + 82 NSTableColumns CF$UID - 91 + 89 NSTvFlags 314605568 NSvFlags 4352 - {517, 190} + {518, 190} $class CF$UID - 90 + 88 NSFrame CF$UID - 89 + 87 NSNextResponder @@ -1464,21 +1405,21 @@ $class CF$UID - 67 + 65 NS.objects CF$UID - 92 + 90 CF$UID - 103 + 101 CF$UID - 111 + 109 @@ -1486,22 +1427,22 @@ $class CF$UID - 102 + 100 NSDataCell CF$UID - 101 + 99 NSHeaderCell CF$UID - 94 + 92 NSIdentifier CF$UID - 93 + 91 NSIsEditable @@ -1512,7 +1453,7 @@ NSTableView CF$UID - 86 + 84 NSWidth 20 @@ -1522,12 +1463,12 @@ $class CF$UID - 100 + 98 NSBackgroundColor CF$UID - 95 + 93 NSCellFlags 67239424 @@ -1541,12 +1482,12 @@ NSSupport CF$UID - 81 + 79 NSTextColor CF$UID - 98 + 96 @@ -1563,12 +1504,12 @@ NSColor CF$UID - 97 + 95 NSColorName CF$UID - 96 + 94 NSColorSpace 6 @@ -1606,7 +1547,7 @@ NSColorName CF$UID - 99 + 97 NSColorSpace 6 @@ -1628,7 +1569,7 @@ $class CF$UID - 50 + 46 NSAlign 1 @@ -1656,22 +1597,22 @@ $class CF$UID - 102 + 100 NSDataCell CF$UID - 108 + 106 NSHeaderCell CF$UID - 105 + 103 NSIdentifier CF$UID - 104 + 102 NSIsResizeable @@ -1684,22 +1625,22 @@ NSTableView CF$UID - 86 + 84 NSWidth - 468 + 469 desc $class CF$UID - 100 + 98 NSBackgroundColor CF$UID - 107 + 105 NSCellFlags 75628032 @@ -1708,17 +1649,17 @@ NSContents CF$UID - 106 + 104 NSSupport CF$UID - 81 + 79 NSTextColor CF$UID - 98 + 96 Job @@ -1744,7 +1685,7 @@ NSBackgroundColor CF$UID - 109 + 107 NSCellFlags 337772096 @@ -1753,12 +1694,12 @@ NSControlView CF$UID - 86 + 84 NSSupport CF$UID - 81 + 52 NSTextColor @@ -1785,7 +1726,7 @@ NSColorName CF$UID - 110 + 108 NSColorSpace 6 @@ -1795,31 +1736,31 @@ $class CF$UID - 102 + 100 NSDataCell CF$UID - 114 + 112 NSHeaderCell CF$UID - 113 + 111 NSIdentifier CF$UID - 112 + 110 NSMaxWidth - 1000 + 20 NSMinWidth - 4 + 8 NSTableView CF$UID - 86 + 84 NSWidth 20 @@ -1829,12 +1770,12 @@ $class CF$UID - 100 + 98 NSBackgroundColor CF$UID - 95 + 93 NSCellFlags 67239424 @@ -1848,19 +1789,19 @@ NSSupport CF$UID - 81 + 79 NSTextColor CF$UID - 98 + 96 $class CF$UID - 65 + 63 NSAlternateContents @@ -1883,7 +1824,7 @@ NSControlView CF$UID - 86 + 84 NSKeyEquivalent @@ -1893,7 +1834,7 @@ NSNormalImage CF$UID - 60 + 56 NSPeriodicDelay 400 @@ -1902,7 +1843,7 @@ NSSupport CF$UID - 115 + 113 @@ -1935,12 +1876,12 @@ NSColor CF$UID - 118 + 116 NSColorName CF$UID - 117 + 115 NSColorSpace 6 @@ -1972,7 +1913,7 @@ $classname NSTableView - {{1, 1}, {517, 190}} + {{1, 1}, {518, 190}} $classes @@ -1988,39 +1929,39 @@ $class CF$UID - 125 + 123 NSAction CF$UID - 124 + 122 NSFrame CF$UID - 123 + 121 NSNextResponder CF$UID - 82 + 80 NSPercent - 0.93596059083938599 + 0.95263159275054932 NSSuperview CF$UID - 82 + 80 NSTarget CF$UID - 82 + 80 NSvFlags 256 - {{518, 1}, {15, 190}} + {{519, 1}, {15, 190}} _doScroller: $classes @@ -2038,34 +1979,34 @@ $class CF$UID - 125 + 123 NSAction CF$UID - 128 + 126 NSFrame CF$UID - 127 + 125 NSNextResponder CF$UID - 82 + 80 NSPercent 0.88602942228317261 NSSuperview CF$UID - 82 + 80 NSTarget CF$UID - 82 + 80 NSsFlags 1 @@ -2074,7 +2015,7 @@ {{-100, -100}, {482, 11}} _doScroller: - {{20, 20}, {534, 192}} + {{20, 20}, {535, 192}} $classes @@ -2086,493 +2027,176 @@ $classname NSScrollView + {574, 257} + fQueuePane $class CF$UID - 66 + 71 - NSCell + NSDestination CF$UID - 133 + 14 - NSEnabled - - NSFrame + NSLabel CF$UID 132 - NSNextResponder - - CF$UID - 75 - - NSSuperview + NSSource CF$UID - 75 + 2 - NSvFlags - -2147483383 - {{471, 226}, {85, 16}} + fProgressBar $class CF$UID - 65 - - NSAlternateContents - - CF$UID - 22 + 71 - NSAlternateImage + NSDestination CF$UID - 135 + 75 - NSButtonFlags - 1211912703 - NSButtonFlags2 - 2 - NSCellFlags - 67239424 - NSCellFlags2 - 131072 - NSContents + NSLabel CF$UID 134 - NSControlView + NSSource CF$UID - 131 + 2 - NSKeyEquivalent + + fQueueCountField + + $class CF$UID - 22 + 71 - NSPeriodicDelay - 200 - NSPeriodicInterval - 25 - NSSupport + NSDestination CF$UID - 81 + 84 - - Show Detail - - $class + NSLabel CF$UID - 137 + 136 - NSImageName + NSSource CF$UID - 136 + 2 - NSSwitch - - $classes - - NSButtonImageSource - NSObject - - $classname - NSButtonImageSource - + fTaskView $class CF$UID - 66 - - NSCell - - CF$UID - 140 + 71 - NSEnabled - - NSFrame + NSDestination CF$UID - 139 + 19 - NSNextResponder + NSLabel CF$UID - 75 + 138 - NSSuperview + NSSource CF$UID - 75 + 2 - NSvFlags - -2147483380 - {{20, 220}, {34, 32}} + fProgressTextField $class CF$UID - 65 + 71 - NSAlternateContents + NSDestination CF$UID - 22 + 48 - NSButtonFlags - 138690815 - NSButtonFlags2 - 34 - NSCellFlags - 67239424 - NSCellFlags2 - 134217728 - NSContents + NSLabel CF$UID - 22 + 140 - NSControlView + NSSource CF$UID - 138 + 2 - NSKeyEquivalent + + fJobDescTextField + + $class CF$UID 143 - NSNormalImage + NSDestination CF$UID - 141 + 2 - NSPeriodicDelay - 200 - NSPeriodicInterval - 25 - NSSupport + NSLabel CF$UID - 56 + 142 + + NSSource + + CF$UID + 112 + removeSelectedJob: + + $classes + + NSNibControlConnector + NSNibConnector + NSObject + + $classname + NSNibControlConnector + $class CF$UID - 49 + 71 - NSClassName + NSDestination CF$UID - 47 + 2 - NSResourceName + NSLabel CF$UID - 142 + 145 - - Play - - $class + NSSource CF$UID - 6 - - NS.string - - - - $class - - CF$UID - 66 - - NSCell - - CF$UID - 146 - - NSEnabled - - NSFrame - - CF$UID - 145 - - NSNextResponder - - CF$UID - 75 - - NSSuperview - - CF$UID - 75 - - NSvFlags - -2147483383 - - {{370, 226}, {98, 16}} - - $class - - CF$UID - 65 - - NSAlternateContents - - CF$UID - 22 - - NSAlternateImage - - CF$UID - 135 - - NSButtonFlags - 1211912703 - NSButtonFlags2 - 2 - NSCellFlags - -2080244224 - NSCellFlags2 - 131072 - NSContents - - CF$UID - 147 - - NSControlView - - CF$UID - 144 - - NSKeyEquivalent - - CF$UID - 22 - - NSPeriodicDelay - 200 - NSPeriodicInterval - 25 - NSSupport - - CF$UID - 81 - - - Show Encodes - {574, 257} - fQueuePane - - $class - - CF$UID - 73 - - NSDestination - - CF$UID - 14 - - NSLabel - - CF$UID - 151 - - NSSource - - CF$UID - 2 - - - fProgressBar - - $class - - CF$UID - 73 - - NSDestination - - CF$UID - 131 - - NSLabel - - CF$UID - 153 - - NSSource - - CF$UID - 2 - - - fDetailCheckbox - - $class - - CF$UID - 73 - - NSDestination - - CF$UID - 77 - - NSLabel - - CF$UID - 155 - - NSSource - - CF$UID - 2 - - - fQueueCountField - - $class - - CF$UID - 73 - - NSDestination - - CF$UID - 86 - - NSLabel - - CF$UID - 157 - - NSSource - - CF$UID - 2 - - - fTaskView - - $class - - CF$UID - 73 - - NSDestination - - CF$UID - 19 - - NSLabel - - CF$UID - 159 - - NSSource - - CF$UID - 2 - - - fProgressTextField - - $class - - CF$UID - 73 - - NSDestination - - CF$UID - 52 - - NSLabel - - CF$UID - 161 - - NSSource - - CF$UID - 2 - - - fJobDescTextField - - $class - - CF$UID - 164 - - NSDestination - - CF$UID - 2 - - NSLabel - - CF$UID - 163 - - NSSource - - CF$UID - 114 - - - removeSelectedJob: - - $classes - - NSNibControlConnector - NSNibConnector - NSObject - - $classname - NSNibControlConnector - - - $class - - CF$UID - 73 - - NSDestination - - CF$UID - 2 - - NSLabel - - CF$UID - 166 - - NSSource - - CF$UID - 86 + 84 dataSource @@ -2580,7 +2204,7 @@ $class CF$UID - 73 + 71 NSDestination @@ -2590,12 +2214,12 @@ NSLabel CF$UID - 168 + 147 NSSource CF$UID - 86 + 84 delegate @@ -2603,40 +2227,17 @@ $class CF$UID - 164 - - NSDestination - - CF$UID - 2 - - NSLabel - - CF$UID - 170 - - NSSource - - CF$UID - 131 - - - detailChanged: - - $class - - CF$UID - 73 + 71 NSDestination CF$UID - 172 + 149 NSLabel CF$UID - 185 + 162 NSSource @@ -2648,32 +2249,32 @@ $class CF$UID - 184 + 161 NSFrameAutosaveName CF$UID - 183 + 160 NSMaxSize CF$UID - 182 + 159 NSMinSize CF$UID - 181 + 158 NSScreenRect CF$UID - 180 + 157 NSViewClass CF$UID - 176 + 153 NSWTFlags 1886912512 @@ -2682,19 +2283,19 @@ NSWindowClass CF$UID - 175 + 152 NSWindowRect CF$UID - 173 + 150 NSWindowStyleMask 4110 NSWindowTitle CF$UID - 174 + 151 NSWindowView @@ -2702,17 +2303,9 @@ 12 - {{420, 319}, {574, 433}} + {{176, 464}, {574, 433}} Queue - HandBrake - - $class - - CF$UID - 6 - - NS.string - NSWindow - + NSWindow $class @@ -2726,7 +2319,7 @@ $class CF$UID - 67 + 65 NS.objects @@ -2736,7 +2329,7 @@ CF$UID - 75 + 73 @@ -2769,52 +2362,7 @@ $class CF$UID - 73 - - NSDestination - - CF$UID - 2 - - NSLabel - - CF$UID - 168 - - NSSource - - CF$UID - 172 - - - - $class - - CF$UID - 73 - - NSDestination - - CF$UID - 138 - - NSLabel - - CF$UID - 188 - - NSSource - - CF$UID - 2 - - - fStartPauseButton - - $class - - CF$UID - 164 + 71 NSDestination @@ -2824,20 +2372,19 @@ NSLabel CF$UID - 190 + 147 NSSource CF$UID - 138 + 149 - toggleStartPause: $class CF$UID - 164 + 143 NSDestination @@ -2847,12 +2394,12 @@ NSLabel CF$UID - 192 + 165 NSSource CF$UID - 57 + 53 cancelCurrentJob: @@ -2860,53 +2407,7 @@ $class CF$UID - 164 - - NSDestination - - CF$UID - 2 - - NSLabel - - CF$UID - 194 - - NSSource - - CF$UID - 144 - - - jobGroupsChanged: - - $class - - CF$UID - 73 - - NSDestination - - CF$UID - 144 - - NSLabel - - CF$UID - 196 - - NSSource - - CF$UID - 2 - - - fJobGroupsCheckbox - - $class - - CF$UID - 73 + 71 NSDestination @@ -2916,7 +2417,7 @@ NSLabel CF$UID - 198 + 167 NSSource @@ -2929,41 +2430,41 @@ $class CF$UID - 200 + 169 NS.objects CF$UID - 75 + 112 CF$UID - 82 + 53 CF$UID - 172 + 90 CF$UID - 77 + 84 CF$UID - 131 + 149 CF$UID - 92 + 19 CF$UID - 57 + 12 CF$UID - 103 + 75 CF$UID @@ -2971,19 +2472,19 @@ CF$UID - 138 + 73 CF$UID - 111 + 14 CF$UID - 12 + 80 CF$UID - 144 + 48 CF$UID @@ -2991,19 +2492,7 @@ CF$UID - 114 - - - CF$UID - 52 - - - CF$UID - 14 - - - CF$UID - 86 + 99 CF$UID @@ -3011,7 +2500,7 @@ CF$UID - 19 + 109 @@ -3028,41 +2517,29 @@ $class CF$UID - 200 + 169 NS.objects CF$UID - 12 - - - CF$UID - 75 - - - CF$UID - 2 - - - CF$UID - 75 + 109 CF$UID - 75 + 11 CF$UID - 86 + 84 CF$UID - 11 + 80 CF$UID - 86 + 2 CF$UID @@ -3070,27 +2547,27 @@ CF$UID - 75 + 149 CF$UID - 86 + 73 CF$UID - 172 + 11 CF$UID - 75 + 12 CF$UID - 92 + 11 CF$UID - 111 + 73 CF$UID @@ -3098,11 +2575,11 @@ CF$UID - 11 + 84 CF$UID - 82 + 90 CF$UID @@ -3110,7 +2587,7 @@ CF$UID - 11 + 84 @@ -3118,33 +2595,21 @@ $class CF$UID - 200 + 169 NS.objects CF$UID - 131 - - - CF$UID - 86 - - - CF$UID - 82 - - - CF$UID - 138 + 149 CF$UID - 52 + 48 CF$UID - 103 + 2 CF$UID @@ -3152,7 +2617,7 @@ CF$UID - 144 + 84 CF$UID @@ -3160,19 +2625,19 @@ CF$UID - 57 + 80 CF$UID - 172 + 101 CF$UID - 2 + 75 CF$UID - 77 + 53 @@ -3180,74 +2645,54 @@ $class CF$UID - 200 + 169 NS.objects CF$UID - 204 - - - CF$UID - 205 - - - CF$UID - 206 - - - CF$UID - 207 + 173 CF$UID - 208 + 174 CF$UID - 209 + 175 CF$UID - 210 + 176 CF$UID - 211 + 177 CF$UID - 212 + 178 CF$UID - 207 + 179 CF$UID - 213 + 180 CF$UID - 214 + 181 CF$UID - 215 + 182 - NSButton4 - NSTableView - NSScrollView1 - NSButton - NSTextField221 - NSTableColumn - 1 - NSButton41 - NSTextField1 Window + NSTextField221 $class @@ -3257,12 +2702,18 @@ NS.string File's Owner + 1 + NSTableView + NSTextField1 + NSScrollView1 + NSTableColumn NSTextField2 + NSButton $class CF$UID - 200 + 169 NS.objects @@ -3271,7 +2722,7 @@ $class CF$UID - 200 + 169 NS.objects @@ -3280,73 +2731,41 @@ $class CF$UID - 200 + 169 NS.objects CF$UID - 12 - - - CF$UID - 197 - - - CF$UID - 19 - - - CF$UID - 160 - - - CF$UID - 172 - - - CF$UID - 57 - - - CF$UID - 77 - - - CF$UID - 186 - - - CF$UID - 52 + 14 CF$UID - 75 + 99 CF$UID - 193 + 36 CF$UID - 74 + 80 CF$UID - 101 + 11 CF$UID - 138 + 137 CF$UID - 92 + 131 CF$UID - 167 + 19 CF$UID @@ -3354,99 +2773,95 @@ CF$UID - 154 - - - CF$UID - 189 + 144 CF$UID - 162 + 90 CF$UID - 169 + 133 CF$UID - 152 + 101 CF$UID - 165 + 112 CF$UID - 187 + 166 CF$UID - 114 + 141 CF$UID - 11 + 48 CF$UID - 111 + 146 CF$UID - 171 + 75 CF$UID - 14 + 164 CF$UID - 82 + 73 CF$UID - 191 + 12 CF$UID - 156 + 148 CF$UID - 144 + 10 CF$UID - 195 + 135 CF$UID - 10 + 163 CF$UID - 103 + 139 CF$UID - 86 + 149 CF$UID - 158 + 84 CF$UID - 36 + 53 CF$UID - 150 + 109 CF$UID - 131 + 72 @@ -3454,222 +2869,177 @@ $class CF$UID - 200 + 169 NS.objects CF$UID - 220 - - - CF$UID - 221 - - - CF$UID - 222 - - - CF$UID - 223 - - - CF$UID - 224 - - - CF$UID - 225 - - - CF$UID - 226 - - - CF$UID - 227 - - - CF$UID - 228 - - - CF$UID - 229 + 187 CF$UID - 230 + 188 CF$UID - 231 + 189 CF$UID - 232 + 190 CF$UID - 233 + 191 CF$UID - 234 + 192 CF$UID - 235 + 193 CF$UID - 236 + 194 CF$UID - 237 + 195 CF$UID - 238 + 196 CF$UID - 239 + 197 CF$UID - 240 + 198 CF$UID - 241 + 199 CF$UID - 242 + 200 CF$UID - 243 + 201 CF$UID - 244 + 202 CF$UID - 245 + 203 CF$UID - 246 + 204 CF$UID - 247 + 205 CF$UID - 248 + 206 CF$UID - 249 + 207 CF$UID - 250 + 208 CF$UID - 251 + 209 CF$UID - 252 + 210 CF$UID - 253 + 211 CF$UID - 254 + 212 CF$UID - 255 + 213 CF$UID - 256 + 214 CF$UID - 257 + 215 CF$UID - 258 + 216 CF$UID - 259 + 217 CF$UID - 260 + 218 - 2577 - 2595 - 2541 - 2568 - 2576 - 2584 - 2511 - 2579 - 2515 - 2547 - 2588 - 2561 + 2539 2559 - 2580 - 2553 - 2571 + 2538 + 2517 + 2543 + 2567 + 2562 + 2541 1 - 2564 - 2583 - 2569 - 2572 - 2563 2570 - 2581 + 2553 + 2564 + 2519 2523 - 2543 - 2522 - 2578 - 2539 - 2517 + 2595 + 2569 + 2515 + 2571 + 2511 2586 - 2565 - 2587 - 2589 + 2547 + 2577 + 2578 2560 - 2519 + 2565 + 2579 + 2568 + 2576 2518 - 2567 - 2538 - 2562 - 2535 + 2584 + 2522 + 2561 $class CF$UID - 67 + 65 NS.objects @@ -3678,7 +3048,7 @@ $class CF$UID - 200 + 169 NS.objects @@ -3687,7 +3057,7 @@ $class CF$UID - 200 + 169 NS.objects diff --git a/macosx/HBQueueController.h b/macosx/HBQueueController.h index 7ee030eec..474392507 100644 --- a/macosx/HBQueueController.h +++ b/macosx/HBQueueController.h @@ -8,14 +8,24 @@ #include #include "hb.h" +@class HBController; + +// HB_OUTLINE_QUEUE turns on an outline view for the queue. +#define HB_OUTLINE_QUEUE 0 + @interface HBQueueController : NSObject { hb_handle_t *fHandle; + HBController *fHBController; NSViewAnimation *fAnimation; BOOL fCurrentJobHidden; // YES when fCurrentJobPane has been shifted out of view (see showCurrentJobPane) BOOL fShowsJobsAsGroups; BOOL fShowsDetail; +#if HB_OUTLINE_QUEUE + NSMutableArray *fEncodes; + IBOutlet NSOutlineView *fOutlineView; +#endif // +---------------fQueueWindow----------------+ // |+-------------fCurrentJobPane-------------+| @@ -46,24 +56,22 @@ // fQueuePane - always visible; fills entire window when fCurrentJobPane is hidden IBOutlet NSView *fQueuePane; IBOutlet NSTableView *fTaskView; - IBOutlet NSButton *fDetailCheckbox; - IBOutlet NSButton *fJobGroupsCheckbox; // just for testing IBOutlet NSTextField *fQueueCountField; - IBOutlet NSButton *fStartPauseButton; } - (void)setHandle: (hb_handle_t *)handle; +- (void)setHBController: (HBController *)controller; - (void)updateQueueUI; - (void)updateCurrentJobUI; - (IBAction)showQueueWindow: (id)sender; - (IBAction)removeSelectedJob: (id)sender; - (IBAction)cancelCurrentJob: (id)sender; -- (IBAction)detailChanged: (id)sender; -- (IBAction)jobGroupsChanged: (id)sender; -- (IBAction)toggleShowsDetail: (id)sender; -- (IBAction)toggleShowsJobsAsGroups: (id)sender; +- (IBAction)showDetail: (id)sender; +- (IBAction)hideDetail: (id)sender; +- (IBAction)showJobsAsGroups: (id)sender; +- (IBAction)showJobsAsPasses: (id)sender; - (IBAction)toggleStartPause: (id)sender; @end diff --git a/macosx/HBQueueController.mm b/macosx/HBQueueController.mm index 657178c74..755692a02 100644 --- a/macosx/HBQueueController.mm +++ b/macosx/HBQueueController.mm @@ -5,6 +5,25 @@ It may be used under the terms of the GNU General Public License. */ #include "HBQueueController.h" +#include "Controller.h" + +#define HB_QUEUE_DRAGGING 0 +#define HBQueueDataType @"HBQueueDataType" + +// UNI_QUEUE turns on the feature where the first item in the queue NSTableView is the +// current job followed by the jobs in hblib's queue. In this scheme, fCurrentJobPane +// disappers. +#define HB_UNI_QUEUE 0 + +#define HB_ROW_HEIGHT_DETAIL 98.0 +#define HB_ROW_HEIGHT_NO_DETAIL 17.0 +#define HB_ROW_HEIGHT_ACTIVE_JOB 60.0 + +//------------------------------------------------------------------------------------ +#pragma mark Job group functions +//------------------------------------------------------------------------------------ +// These could be part of hblib if we think hblib should have knowledge of groups. +// For now, I see groups as a metaphor that HBQueueController provides. /** * Returns the number of jobs groups in the queue. @@ -85,11 +104,52 @@ static hb_job_t * hb_next_job( hb_handle_t * h, hb_job_t * job ) while( ( j = hb_job( h, index++ ) ) ) { if (j == job) - return hb_job( h, index+1 ); + return hb_job( h, index ); } return NULL; } +#pragma mark - +//------------------------------------------------------------------------------------ +// HBJob +//------------------------------------------------------------------------------------ + +#if HB_OUTLINE_QUEUE + +@interface HBJob : NSObject +{ + hb_job_t *fJob; +} ++ (HBJob*) jobWithJob: (hb_job_t *) job; +- (id) initWithJob: (hb_job_t *) job; +- (hb_job_t *) job; +@end + +@implementation HBJob ++ (HBJob*) jobWithJob: (hb_job_t *) job +{ + return [[[HBJob alloc] initWithJob:job] autorelease]; +} + +- (id) initWithJob: (hb_job_t *) job +{ + if (self = [super init]) + { + // job is not owned by HBJob. It does not get dealloacted when HBJob is released. + fJob = job; + } + return self; +} + +- (hb_job_t*) job +{ + return fJob; +} + +@end + +#endif // HB_OUTLINE_QUEUE + #pragma mark - // Toolbar identifiers @@ -116,8 +176,15 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo nil]]; fShowsDetail = [[NSUserDefaults standardUserDefaults] boolForKey:@"QueueShowsDetail"]; +#if HB_OUTLINE_QUEUE + fShowsJobsAsGroups = YES; +#else fShowsJobsAsGroups = [[NSUserDefaults standardUserDefaults] boolForKey:@"QueueShowsJobsAsGroups"]; +#endif +#if HB_OUTLINE_QUEUE + fEncodes = [[NSMutableArray arrayWithCapacity:0] retain]; +#endif } return self; } @@ -133,6 +200,10 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo if ([fQueueWindow delegate] == self) [fQueueWindow setDelegate:nil]; +#if HB_OUTLINE_QUEUE + [fEncodes release]; +#endif + [super dealloc]; } @@ -144,6 +215,14 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo fHandle = handle; } +//------------------------------------------------------------------------------------ +// Receive HBController +//------------------------------------------------------------------------------------ +- (void)setHBController: (HBController *)controller +{ + fHBController = controller; +} + //------------------------------------------------------------------------------------ // Displays and brings the queue window to the front //------------------------------------------------------------------------------------ @@ -220,10 +299,19 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo [[NSUserDefaults standardUserDefaults] setBool:showsDetail forKey:@"QueueShowsDetail"]; [[NSUserDefaults standardUserDefaults] synchronize]; - // clumsy - have to update UI - [fDetailCheckbox setState:showsDetail ? NSOnState : NSOffState]; - - [fTaskView setRowHeight:showsDetail ? 98.0 : 17.0]; + [fTaskView setRowHeight:showsDetail ? HB_ROW_HEIGHT_DETAIL : HB_ROW_HEIGHT_NO_DETAIL]; +#if HB_UNI_QUEUE + if (hb_count(fHandle)) + [fTaskView noteHeightOfRowsWithIndexesChanged:[NSIndexSet indexSetWithIndex:0]]; +#endif +#if HB_OUTLINE_QUEUE + + [fOutlineView noteHeightOfRowsWithIndexesChanged: + [NSIndexSet indexSetWithIndexesInRange: + NSMakeRange(0,[fOutlineView numberOfRows]) + ]]; +#endif + if ([fTaskView selectedRow] != -1) [fTaskView scrollRowToVisible:[fTaskView selectedRow]]; } @@ -233,19 +321,76 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo //------------------------------------------------------------------------------------ - (void)setShowsJobsAsGroups: (BOOL)showsGroups { +#if HB_OUTLINE_QUEUE + return; // Can't modify this value. It's always YES. +#endif fShowsJobsAsGroups = showsGroups; [[NSUserDefaults standardUserDefaults] setBool:showsGroups forKey:@"QueueShowsJobsAsGroups"]; [[NSUserDefaults standardUserDefaults] synchronize]; - // clumsy - have to update UI - [fJobGroupsCheckbox setState:showsGroups ? NSOnState : NSOffState]; - [self updateQueueUI]; if ([fTaskView selectedRow] != -1) [fTaskView scrollRowToVisible:[fTaskView selectedRow]]; } +//------------------------------------------------------------------------------------ +// Returns a 16x16 image that represents a job pass. +//------------------------------------------------------------------------------------ +- (NSImage *)smallImageForPass: (int)pass +{ + switch (pass) + { + case -1: return [NSImage imageNamed: @"JobPassSubtitleSmall"]; + case 1: return [NSImage imageNamed: @"JobPassFirstSmall"]; + case 2: return [NSImage imageNamed: @"JobPassSecondSmall"]; + default: return [NSImage imageNamed: @"JobPassUnknownSmall"]; + } +} + +//------------------------------------------------------------------------------------ +// Returns a 64x64 image that represents a job pass. +//------------------------------------------------------------------------------------ +- (NSImage *)largeImageForPass: (int)pass +{ + switch (pass) + { + case -1: return [NSImage imageNamed: @"JobPassSubtitleLarge"]; + case 1: return [NSImage imageNamed: @"JobPassFirstLarge"]; + case 2: return [NSImage imageNamed: @"JobPassSecondLarge"]; + default: return [NSImage imageNamed: @"JobPassUnknownLarge"]; + } +} + +#if HB_OUTLINE_QUEUE +//------------------------------------------------------------------------------------ +// Rebuilds the contents of fEncodes which is a array of encodes and HBJobs. +//------------------------------------------------------------------------------------ +- (void)rebuildEncodes +{ + [fEncodes removeAllObjects]; + + NSMutableArray * aJobGroup = [NSMutableArray arrayWithCapacity:0]; + hb_job_t * nextJob = hb_group( fHandle, 0 ); + while( nextJob ) + { + if (nextJob->sequence_id == 0) + { + // Encountered a new group. Add the current one to fEncodes and then start a new one. + if ([aJobGroup count] > 0) + { + [fEncodes addObject:aJobGroup]; + aJobGroup = [NSMutableArray arrayWithCapacity:0]; + } + } + [aJobGroup addObject: [HBJob jobWithJob:nextJob]]; + nextJob = hb_next_job (fHandle, nextJob); + } + if ([aJobGroup count] > 0) + [fEncodes addObject:aJobGroup]; +} +#endif + //------------------------------------------------------------------------------------ // Generates a multi-line text string that includes the job name on the first line // followed by details of the job on subsequent lines. If the text is to be drawn as @@ -253,7 +398,8 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo // contain multiple fonts and paragraph formating. //------------------------------------------------------------------------------------ - (NSAttributedString *)attributedDescriptionForJob: (hb_job_t *)job - withDetail: (BOOL)detail + withTitle: (BOOL)withTitle + withDetail: (BOOL)withDetail withHighlighting: (BOOL)highlighted { NSMutableAttributedString * finalString; // the return value @@ -284,17 +430,19 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo // Title, in bold // Show the name of the source Note: use title->name instead of title->dvd since // name is just the chosen folder, instead of dvd which is the full path - anAttributedString = [[[NSAttributedString alloc] initWithString:[NSString stringWithUTF8String:title->name] attributes:titleAttribute] autorelease]; - [finalString appendAttributedString:anAttributedString]; - + if (withTitle) + { + anAttributedString = [[[NSAttributedString alloc] initWithString:[NSString stringWithUTF8String:title->name] attributes:titleAttribute] autorelease]; + [finalString appendAttributedString:anAttributedString]; + } + // Other info in plain - aMutableString = [NSMutableString stringWithCapacity:200]; - BOOL jobGroups = [[NSUserDefaults standardUserDefaults] boolForKey:@"QueueShowsJobsAsGroups"]; + aMutableString = [NSMutableString stringWithCapacity:200]; // The subtitle scan doesn't contain all the stuff we need (like x264opts). // So grab the next job in the group for display purposes. - if (jobGroups && job->pass == -1) + if (fShowsJobsAsGroups && job->pass == -1) { // When job is the one currently being processed, then the next in its group // is the the first job in the queue. @@ -307,177 +455,182 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo job = nextjob; } - NSString * chapterString = (job->chapter_start == job->chapter_end) ? - [NSString stringWithFormat:@"Chapter %d", job->chapter_start] : - [NSString stringWithFormat:@"Chapters %d through %d", job->chapter_start, job->chapter_end]; - - // Scan pass - if (job->pass == -1) + if (withTitle) { - [aMutableString appendString:[NSString stringWithFormat: - @" (Title %d, %@, Subtitle Scan)", title->index, chapterString]]; + NSString * chapterString = (job->chapter_start == job->chapter_end) ? + [NSString stringWithFormat:@"Chapter %d", job->chapter_start] : + [NSString stringWithFormat:@"Chapters %d through %d", job->chapter_start, job->chapter_end]; + + // Scan pass + if (job->pass == -1) + { + [aMutableString appendString:[NSString stringWithFormat: + @" (Title %d, %@, Subtitle Scan)", title->index, chapterString]]; + } + else + { + if (fShowsJobsAsGroups) + [aMutableString appendString:[NSString stringWithFormat: + @" (Title %d, %@, %d-Pass)", + title->index, chapterString, MIN( 2, job->pass + 1 )]]; + else + [aMutableString appendString:[NSString stringWithFormat: + @" (Title %d, %@, Pass %d of %d)", + title->index, chapterString, MAX( 1, job->pass ), MIN( 2, job->pass + 1 )]]; + } } - - // Normal pass - else + + // End of title stuff + + + // Normal pass - show detail + if (withDetail && job->pass != -1) { - if (jobGroups) - [aMutableString appendString:[NSString stringWithFormat: - @" (Title %d, %@, %d-Pass)", - title->index, chapterString, MIN( 2, job->pass + 1 )]]; + NSString * jobFormat; + NSString * jobPictureDetail; + NSString * jobVideoDetail; + NSString * jobVideoCodec; + NSString * jobVideoQuality; + NSString * jobAudioDetail; + NSString * jobAudioCodec; + + /* Muxer settings (File Format in the gui) */ + if (job->mux == 65536 || job->mux == 131072 || job->mux == 1048576) + jobFormat = @"MP4"; // HB_MUX_MP4,HB_MUX_PSP,HB_MUX_IPOD + else if (job->mux == 262144) + jobFormat = @"AVI"; // HB_MUX_AVI + else if (job->mux == 524288) + jobFormat = @"OGM"; // HB_MUX_OGM + else if (job->mux == 2097152) + jobFormat = @"MKV"; // HB_MUX_MKV else - [aMutableString appendString:[NSString stringWithFormat: - @" (Title %d, %@, Pass %d of %d)", - title->index, chapterString, MAX( 1, job->pass ), MIN( 2, job->pass + 1 )]]; + jobFormat = @"unknown"; - if (detail) + // 2097152 + /* Video Codec settings (Encoder in the gui) */ + if (job->vcodec == 1) + jobVideoCodec = @"FFmpeg"; // HB_VCODEC_FFMPEG + else if (job->vcodec == 2) + jobVideoCodec = @"XviD"; // HB_VCODEC_XVID + else if (job->vcodec == 4) { - NSString * jobFormat; - NSString * jobPictureDetail; - NSString * jobVideoDetail; - NSString * jobVideoCodec; - NSString * jobVideoQuality; - NSString * jobAudioDetail; - NSString * jobAudioCodec; - - /* Muxer settings (File Format in the gui) */ - if (job->mux == 65536 || job->mux == 131072 || job->mux == 1048576) - jobFormat = @"MP4"; // HB_MUX_MP4,HB_MUX_PSP,HB_MUX_IPOD - else if (job->mux == 262144) - jobFormat = @"AVI"; // HB_MUX_AVI - else if (job->mux == 524288) - jobFormat = @"OGM"; // HB_MUX_OGM - else if (job->mux == 2097152) - jobFormat = @"MKV"; // HB_MUX_MKV - else - jobFormat = @"unknown"; - - // 2097152 - /* Video Codec settings (Encoder in the gui) */ - if (job->vcodec == 1) - jobVideoCodec = @"FFmpeg"; // HB_VCODEC_FFMPEG - else if (job->vcodec == 2) - jobVideoCodec = @"XviD"; // HB_VCODEC_XVID - else if (job->vcodec == 4) - { - /* Deterimine for sure how we are now setting iPod uuid atom */ - if (job->h264_level) // We are encoding for iPod - jobVideoCodec = @"x264 (H.264 iPod)"; // HB_VCODEC_X264 - else - jobVideoCodec = @"x264 (H.264 Main)"; // HB_VCODEC_X264 - } - else - jobVideoCodec = @"unknown"; - - /* Audio Codecs (Second half of Codecs in the gui) */ - if (job->acodec == 256) - jobAudioCodec = @"AAC"; // HB_ACODEC_FAAC - else if (job->acodec == 512) - jobAudioCodec = @"MP3"; // HB_ACODEC_LAME - else if (job->acodec == 1024) - jobAudioCodec = @"Vorbis"; // HB_ACODEC_VORBIS - else if (job->acodec == 2048) - jobAudioCodec = @"AC3"; // HB_ACODEC_AC3 + /* Deterimine for sure how we are now setting iPod uuid atom */ + if (job->h264_level) // We are encoding for iPod + jobVideoCodec = @"x264 (H.264 iPod)"; // HB_VCODEC_X264 else - jobAudioCodec = @"unknown"; - /* Show Basic File info */ - if (job->chapter_markers == 1) - [aMutableString appendString:[NSString stringWithFormat:@"\nFormat: %@ Container, %@ Video + %@ Audio, Chapter Markers", jobFormat, jobVideoCodec, jobAudioCodec]]; - else - [aMutableString appendString:[NSString stringWithFormat:@"\nFormat: %@ Container, %@ Video + %@ Audio", jobFormat, jobVideoCodec, jobAudioCodec]]; - - /*Picture info*/ - /*integers for picture values deinterlace, crop[4], keep_ratio, grayscale, pixel_ratio, pixel_aspect_width, pixel_aspect_height, - maxWidth, maxHeight */ - if (job->pixel_ratio == 1) - { - int titlewidth = title->width - job->crop[2] - job->crop[3]; - int displayparwidth = titlewidth * job->pixel_aspect_width / job->pixel_aspect_height; - int displayparheight = title->height - job->crop[0] - job->crop[1]; - jobPictureDetail = [NSString stringWithFormat:@"Picture: %dx%d (%dx%d Anamorphic)", displayparwidth, displayparheight, job->width, displayparheight]; - } - else - jobPictureDetail = [NSString stringWithFormat:@"Picture: %dx%d", job->width, job->height]; - if (job->keep_ratio == 1) - jobPictureDetail = [jobPictureDetail stringByAppendingString:@" Keep Aspect Ratio"]; - - if (job->grayscale == 1) - jobPictureDetail = [jobPictureDetail stringByAppendingString:@", Grayscale"]; - - if (job->deinterlace == 1) - jobPictureDetail = [jobPictureDetail stringByAppendingString:@", Deinterlace"]; - /* Show Picture info */ - [aMutableString appendString:[NSString stringWithFormat:@"\n%@", jobPictureDetail]]; - - /* Detailed Video info */ - if (job->vquality <= 0 || job->vquality >= 1) - jobVideoQuality =[NSString stringWithFormat:@"%d kbps", job->vbitrate]; - else - { - NSNumber * vidQuality; - vidQuality = [NSNumber numberWithInt:job->vquality * 100]; - /* this is screwed up kind of. Needs to be formatted properly */ - if (job->crf == 1) - jobVideoQuality =[NSString stringWithFormat:@"%@%% CRF", vidQuality]; - else - jobVideoQuality =[NSString stringWithFormat:@"%@%% CQP", vidQuality]; - } - - if (job->vrate_base == 1126125) - { - /* NTSC FILM 23.976 */ - jobVideoDetail = [NSString stringWithFormat:@"Video: %@, %@, 23.976 fps", jobVideoCodec, jobVideoQuality]; - } - else if (job->vrate_base == 900900) - { - /* NTSC 29.97 */ - jobVideoDetail = [NSString stringWithFormat:@"Video: %@, %@, 29.97 fps", jobVideoCodec, jobVideoQuality]; - } - else - { - /* Everything else */ - jobVideoDetail = [NSString stringWithFormat:@"Video: %@, %@, %d fps", jobVideoCodec, jobVideoQuality, job->vrate / job->vrate_base]; - } - - /* Add the video detail string to the job filed in the window */ - [aMutableString appendString:[NSString stringWithFormat:@"\n%@", jobVideoDetail]]; - - /* if there is an x264 option string, lets add it here*/ - /*NOTE: Due to size, lets get this in a tool tip*/ - - if (job->x264opts) - [aMutableString appendString:[NSString stringWithFormat:@"\nx264 Options: %@", [NSString stringWithUTF8String:job->x264opts]]]; + jobVideoCodec = @"x264 (H.264 Main)"; // HB_VCODEC_X264 + } + else + jobVideoCodec = @"unknown"; + + /* Audio Codecs (Second half of Codecs in the gui) */ + if (job->acodec == 256) + jobAudioCodec = @"AAC"; // HB_ACODEC_FAAC + else if (job->acodec == 512) + jobAudioCodec = @"MP3"; // HB_ACODEC_LAME + else if (job->acodec == 1024) + jobAudioCodec = @"Vorbis"; // HB_ACODEC_VORBIS + else if (job->acodec == 2048) + jobAudioCodec = @"AC3"; // HB_ACODEC_AC3 + else + jobAudioCodec = @"unknown"; + /* Show Basic File info */ + if (job->chapter_markers == 1) + [aMutableString appendString:[NSString stringWithFormat:@"\nFormat: %@ Container, %@ Video + %@ Audio, Chapter Markers", jobFormat, jobVideoCodec, jobAudioCodec]]; + else + [aMutableString appendString:[NSString stringWithFormat:@"\nFormat: %@ Container, %@ Video + %@ Audio", jobFormat, jobVideoCodec, jobAudioCodec]]; - /* Audio Detail */ - if ([jobAudioCodec isEqualToString: @"AC3"]) - jobAudioDetail = [NSString stringWithFormat:@"Audio: %@, Pass-Through", jobAudioCodec]; + /*Picture info*/ + /*integers for picture values deinterlace, crop[4], keep_ratio, grayscale, pixel_ratio, pixel_aspect_width, pixel_aspect_height, + maxWidth, maxHeight */ + if (job->pixel_ratio == 1) + { + int titlewidth = title->width - job->crop[2] - job->crop[3]; + int displayparwidth = titlewidth * job->pixel_aspect_width / job->pixel_aspect_height; + int displayparheight = title->height - job->crop[0] - job->crop[1]; + jobPictureDetail = [NSString stringWithFormat:@"Picture: %dx%d (%dx%d Anamorphic)", displayparwidth, displayparheight, job->width, displayparheight]; + } + else + jobPictureDetail = [NSString stringWithFormat:@"Picture: %dx%d", job->width, job->height]; + if (job->keep_ratio == 1) + jobPictureDetail = [jobPictureDetail stringByAppendingString:@" Keep Aspect Ratio"]; + + if (job->grayscale == 1) + jobPictureDetail = [jobPictureDetail stringByAppendingString:@", Grayscale"]; + + if (job->deinterlace == 1) + jobPictureDetail = [jobPictureDetail stringByAppendingString:@", Deinterlace"]; + /* Show Picture info */ + [aMutableString appendString:[NSString stringWithFormat:@"\n%@", jobPictureDetail]]; + + /* Detailed Video info */ + if (job->vquality <= 0 || job->vquality >= 1) + jobVideoQuality =[NSString stringWithFormat:@"%d kbps", job->vbitrate]; + else + { + NSNumber * vidQuality; + vidQuality = [NSNumber numberWithInt:job->vquality * 100]; + /* this is screwed up kind of. Needs to be formatted properly */ + if (job->crf == 1) + jobVideoQuality =[NSString stringWithFormat:@"%@%% CRF", vidQuality]; else - jobAudioDetail = [NSString stringWithFormat:@"Audio: %@, %d kbps, %d Hz", jobAudioCodec, job->abitrate, job->arate]; - - /* we now get the audio mixdown info for each of the two gui audio tracks */ - /* lets do it the long way here to get a handle on things. - Hardcoded for two tracks for gui: audio_mixdowns[i] audio_mixdowns[i] */ - int ai; // counter for each audios [] , macgui only allows for two audio tracks currently - for( ai = 0; ai < 2; ai++ ) - { - if (job->audio_mixdowns[ai] == HB_AMIXDOWN_MONO) - jobAudioDetail = [jobAudioDetail stringByAppendingString:[NSString stringWithFormat:@", Track %d: Mono",ai + 1]]; - if (job->audio_mixdowns[ai] == HB_AMIXDOWN_STEREO) - jobAudioDetail = [jobAudioDetail stringByAppendingString:[NSString stringWithFormat:@", Track %d: Stereo",ai + 1]]; - if (job->audio_mixdowns[ai] == HB_AMIXDOWN_DOLBY) - jobAudioDetail = [jobAudioDetail stringByAppendingString:[NSString stringWithFormat:@", Track %d: Dolby Surround",ai + 1]]; - if (job->audio_mixdowns[ai] == HB_AMIXDOWN_DOLBYPLII) - jobAudioDetail = [jobAudioDetail stringByAppendingString:[NSString stringWithFormat:@", Track %d: Dolby Pro Logic II",ai + 1]]; - if (job->audio_mixdowns[ai] == HB_AMIXDOWN_6CH) - jobAudioDetail = [jobAudioDetail stringByAppendingString:[NSString stringWithFormat:@", Track %d: 6-channel discreet",ai + 1]]; - } - - /* Add the Audio detail string to the job filed in the window */ - [aMutableString appendString:[NSString stringWithFormat: @"\n%@", jobAudioDetail]]; - - /*Destination Field */ - [aMutableString appendString:[NSString stringWithFormat:@"\nDestination: %@", [NSString stringWithUTF8String:job->file]]]; + jobVideoQuality =[NSString stringWithFormat:@"%@%% CQP", vidQuality]; + } + + if (job->vrate_base == 1126125) + { + /* NTSC FILM 23.976 */ + jobVideoDetail = [NSString stringWithFormat:@"Video: %@, %@, 23.976 fps", jobVideoCodec, jobVideoQuality]; + } + else if (job->vrate_base == 900900) + { + /* NTSC 29.97 */ + jobVideoDetail = [NSString stringWithFormat:@"Video: %@, %@, 29.97 fps", jobVideoCodec, jobVideoQuality]; } + else + { + /* Everything else */ + jobVideoDetail = [NSString stringWithFormat:@"Video: %@, %@, %d fps", jobVideoCodec, jobVideoQuality, job->vrate / job->vrate_base]; + } + + /* Add the video detail string to the job filed in the window */ + [aMutableString appendString:[NSString stringWithFormat:@"\n%@", jobVideoDetail]]; + + /* if there is an x264 option string, lets add it here*/ + /*NOTE: Due to size, lets get this in a tool tip*/ + + if (job->x264opts) + [aMutableString appendString:[NSString stringWithFormat:@"\nx264 Options: %@", [NSString stringWithUTF8String:job->x264opts]]]; + + /* Audio Detail */ + if ([jobAudioCodec isEqualToString: @"AC3"]) + jobAudioDetail = [NSString stringWithFormat:@"Audio: %@, Pass-Through", jobAudioCodec]; + else + jobAudioDetail = [NSString stringWithFormat:@"Audio: %@, %d kbps, %d Hz", jobAudioCodec, job->abitrate, job->arate]; + + /* we now get the audio mixdown info for each of the two gui audio tracks */ + /* lets do it the long way here to get a handle on things. + Hardcoded for two tracks for gui: audio_mixdowns[i] audio_mixdowns[i] */ + int ai; // counter for each audios [] , macgui only allows for two audio tracks currently + for( ai = 0; ai < 2; ai++ ) + { + if (job->audio_mixdowns[ai] == HB_AMIXDOWN_MONO) + jobAudioDetail = [jobAudioDetail stringByAppendingString:[NSString stringWithFormat:@", Track %d: Mono",ai + 1]]; + if (job->audio_mixdowns[ai] == HB_AMIXDOWN_STEREO) + jobAudioDetail = [jobAudioDetail stringByAppendingString:[NSString stringWithFormat:@", Track %d: Stereo",ai + 1]]; + if (job->audio_mixdowns[ai] == HB_AMIXDOWN_DOLBY) + jobAudioDetail = [jobAudioDetail stringByAppendingString:[NSString stringWithFormat:@", Track %d: Dolby Surround",ai + 1]]; + if (job->audio_mixdowns[ai] == HB_AMIXDOWN_DOLBYPLII) + jobAudioDetail = [jobAudioDetail stringByAppendingString:[NSString stringWithFormat:@", Track %d: Dolby Pro Logic II",ai + 1]]; + if (job->audio_mixdowns[ai] == HB_AMIXDOWN_6CH) + jobAudioDetail = [jobAudioDetail stringByAppendingString:[NSString stringWithFormat:@", Track %d: 6-channel discreet",ai + 1]]; + } + + /* Add the Audio detail string to the job filed in the window */ + [aMutableString appendString:[NSString stringWithFormat: @"\n%@", jobAudioDetail]]; + + /*Destination Field */ + [aMutableString appendString:[NSString stringWithFormat:@"\nDestination: %@", [NSString stringWithUTF8String:job->file]]]; } anAttributedString = [[[NSAttributedString alloc] initWithString:aMutableString attributes:highlighted ? detailHighlightedAttribute : detailAttribute] autorelease]; @@ -609,8 +762,7 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo #define p s->param.working [fProgressBar setIndeterminate:NO]; - BOOL jobGroups = [[NSUserDefaults standardUserDefaults] boolForKey:@"QueueShowsJobsAsGroups"]; - float progress_total = jobGroups ? + float progress_total = fShowsJobsAsGroups ? 100.0 * ( p.progress + p.job_cur - 1 ) / p.job_count : 100.0 * p.progress; @@ -633,47 +785,6 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo } } -//------------------------------------------------------------------------------------ -// Refresh start/pause button (fStartPauseButton) from current state. -//------------------------------------------------------------------------------------ -- (void) updateStartPauseButton -{ - -// ************* THIS METHOD CAN DISAPPEAR. THE BUTTON IS NOW HIDDEN AND CAN BE DELETED - if (!fHandle) return; - - hb_state_t s; - hb_get_state2 (fHandle, &s); - - if (s.state == HB_STATE_PAUSED) - { - [fStartPauseButton setEnabled:YES]; -// [fStartPauseButton setTitle:NSLocalizedString(@"Resume", nil)]; - [fStartPauseButton setImage:[NSImage imageNamed: @"Play"]]; - } - - else if ((s.state == HB_STATE_WORKING) || (s.state == HB_STATE_MUXING)) - { - [fStartPauseButton setEnabled:YES]; -// [fStartPauseButton setTitle:NSLocalizedString(@"Pause", nil)]; - [fStartPauseButton setImage:[NSImage imageNamed: @"Pause"]]; - } - - else if (hb_count(fHandle) > 0) - { - [fStartPauseButton setEnabled:YES]; -// [fStartPauseButton setTitle:NSLocalizedString(@"Start", nil)]; - [fStartPauseButton setImage:[NSImage imageNamed: @"Play"]]; - } - - else - { - [fStartPauseButton setEnabled:NO]; -// [fStartPauseButton setTitle:NSLocalizedString(@"Start", nil)]; - [fStartPauseButton setImage:[NSImage imageNamed: @"Play"]]; - } -} - //------------------------------------------------------------------------------------ // Refresh queue count text field (fQueueCountField). //------------------------------------------------------------------------------------ @@ -681,9 +792,8 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo { NSString * msg; int jobCount; - BOOL jobGroups = [[NSUserDefaults standardUserDefaults] boolForKey:@"QueueShowsJobsAsGroups"]; - if (jobGroups) + if (fShowsJobsAsGroups) { jobCount = fHandle ? hb_group_count(fHandle) : 0; if (jobCount == 1) @@ -715,16 +825,16 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo if (fHandle) { - hb_get_state( fHandle, &s ); + hb_get_state2( fHandle, &s ); job = hb_current_job(fHandle); } if (job) { - [fJobDescTextField setAttributedStringValue:[self attributedDescriptionForJob:job withDetail:YES withHighlighting:NO]]; + [fJobDescTextField setAttributedStringValue:[self attributedDescriptionForJob:job withTitle:YES withDetail:YES withHighlighting:NO]]; [self showCurrentJobPane:YES]; - [fJobIconView setImage: fShowsJobsAsGroups ? [NSImage imageNamed:@"JobLarge"] : [NSImage imageNamed:@"JobPassLarge"] ]; + [fJobIconView setImage: fShowsJobsAsGroups ? [NSImage imageNamed:@"JobLarge"] : [self largeImageForPass: job->pass] ]; NSString * statusMsg = [self progressStatusStringForJob:job state:&s]; NSString * timeMsg = [self progressTimeRemainingStringForJob:job state:&s]; @@ -740,10 +850,6 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo [self showCurrentJobPane:NO]; [fProgressBar stopAnimation:nil]; // just in case in was animating } - - // Gross hack. Also update start/pause button. Have to do it here since we don't - // have any other periodic chance to update the button. - [self updateStartPauseButton]; } //------------------------------------------------------------------------------------ @@ -752,11 +858,15 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo //------------------------------------------------------------------------------------ - (void)updateQueueUI { +#if HB_OUTLINE_QUEUE + [self rebuildEncodes]; + [fOutlineView noteNumberOfRowsChanged]; + [fOutlineView reloadData]; +#endif [fTaskView noteNumberOfRowsChanged]; [fTaskView reloadData]; [self updateQueueCountField]; - [self updateStartPauseButton]; } //------------------------------------------------------------------------------------ @@ -769,109 +879,76 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo int row = [sender selectedRow]; if (row != -1) { - BOOL jobGroups = [[NSUserDefaults standardUserDefaults] boolForKey:@"QueueShowsJobsAsGroups"]; - if (jobGroups) +#if HB_UNI_QUEUE + if (row == 0) + { + [self cancelCurrentJob:sender]; + } + else + { + row--; + if (fShowsJobsAsGroups) + hb_rem_group( fHandle, hb_group( fHandle, row ) ); + else + hb_rem( fHandle, hb_job( fHandle, row ) ); + } +#else + if (fShowsJobsAsGroups) hb_rem_group( fHandle, hb_group( fHandle, row ) ); else hb_rem( fHandle, hb_job( fHandle, row ) ); +#endif [self updateQueueUI]; } } //------------------------------------------------------------------------------------ -// Prompts user if the want to cancel encoding of current job. If so, hb_stop gets -// called. +// Prompts user if the want to cancel encoding of current job. If so, doCancelCurrentJob +// gets called. //------------------------------------------------------------------------------------ - (IBAction)cancelCurrentJob: (id)sender { - if (!fHandle) return; - - 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) - hb_stop(fHandle); - else - { - NSString * alertTitle = [NSString stringWithFormat:NSLocalizedString(@"Do you want to stop processing of %@?", nil), - [NSString stringWithUTF8String:job->title->name]]; - - NSBeginCriticalAlertSheet( - alertTitle, - NSLocalizedString(@"Stop Processing", nil), NSLocalizedString(@"Keep Processing", nil), nil, fQueueWindow, self, - @selector(cancelCurrentJob:returnCode:contextInfo:), nil, nil, - NSLocalizedString(@"Your movie will be lost if you don't continue processing.", nil), - [NSString stringWithUTF8String:job->title->name]); - - // cancelCurrentJob:returnCode:contextInfo: will be called when the dialog is dismissed - } -} - -- (void) cancelCurrentJob: (NSWindow *)sheet returnCode: (int)returnCode contextInfo: (void *)contextInfo -{ - if (returnCode == NSAlertDefaultReturn) - hb_stop(fHandle); + [fHBController Cancel:sender]; } //------------------------------------------------------------------------------------ -// Enables or disables the display of detail information for each job based on the -// state of the sender. +// Turns on the display of detail information for each job. Does nothing if detail is +// already turned on. //------------------------------------------------------------------------------------ -- (IBAction)detailChanged: (id)sender +- (IBAction)showDetail: (id)sender { - if ([sender isMemberOfClass:[NSButton class]]) - { - BOOL detail = [sender state] == NSOnState; - [[NSUserDefaults standardUserDefaults] setBool:detail forKey:@"QueueShowsDetail"]; - - [self setShowsDetail:detail]; - } + if (!fShowsDetail) + [self setShowsDetail:YES]; } //------------------------------------------------------------------------------------ -// Enables or disables the display of job groups based on the state of the sender. +// Turns off the display of detail information for each job. Does nothing if detail is +// already turned off. //------------------------------------------------------------------------------------ -- (IBAction)jobGroupsChanged: (id)sender +- (IBAction)hideDetail: (id)sender { - if ([sender isMemberOfClass:[NSButton class]]) - { - BOOL groups = [sender state] == NSOnState; - [[NSUserDefaults standardUserDefaults] setBool:groups forKey:@"QueueShowsJobsAsGroups"]; - - [self setShowsJobsAsGroups:groups]; - } - else if ([sender isMemberOfClass:[NSSegmentedControl class]]) - { - BOOL groups = [sender selectedSegment] == 0; - [[NSUserDefaults standardUserDefaults] setBool:groups forKey:@"QueueShowsJobsAsGroups"]; - - [self setShowsJobsAsGroups:groups]; - } - else if ([sender isMemberOfClass:[NSMatrix class]]) - { - BOOL groups = [sender selectedColumn] == 0; - [[NSUserDefaults standardUserDefaults] setBool:groups forKey:@"QueueShowsJobsAsGroups"]; - - [self setShowsJobsAsGroups:groups]; - } + if (fShowsDetail) + [self setShowsDetail:NO]; } //------------------------------------------------------------------------------------ -// Toggles the Shows Detail setting. +// Turns on displaying of jobs as groups by calling setShowsJobsAsGroups:YES. Does +// nothing if groups are already turned on. //------------------------------------------------------------------------------------ -- (IBAction)toggleShowsDetail: (id)sender +- (IBAction)showJobsAsGroups: (id)sender { - [self setShowsDetail:!fShowsDetail]; + if (!fShowsJobsAsGroups) + [self setShowsJobsAsGroups:YES]; } //------------------------------------------------------------------------------------ -// Toggles the Shows Jobs As Groups setting. +// Turns on displaying of jobs as individual items by calling setShowsJobsAsGroups:NO. +// Does nothing if groups are already turned off. //------------------------------------------------------------------------------------ -- (IBAction)toggleShowsJobsAsGroups: (id)sender +- (IBAction)showJobsAsPasses: (id)sender { - [self setShowsJobsAsGroups:!fShowsJobsAsGroups]; + if (fShowsJobsAsGroups) + [self setShowsJobsAsGroups:NO]; } //------------------------------------------------------------------------------------ @@ -890,14 +967,13 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo hb_pause (fHandle); else { - BOOL jobGroups = [[NSUserDefaults standardUserDefaults] boolForKey:@"QueueShowsJobsAsGroups"]; - if (jobGroups) + if (fShowsJobsAsGroups) { if (hb_group_count(fHandle) > 0) - hb_start (fHandle); + [fHBController doRip]; } else if (hb_count(fHandle) > 0) - hb_start (fHandle); + [fHBController doRip]; } } @@ -959,33 +1035,45 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdentifier] autorelease]; // Set the text label to be displayed in the toolbar and customization palette - [toolbarItem setLabel: @"Show Detail"]; - [toolbarItem setPaletteLabel: @"Show Detail"]; + [toolbarItem setLabel: @"Detail"]; + [toolbarItem setPaletteLabel: @"Detail"]; // Set up a reasonable tooltip, and image - [toolbarItem setToolTip: @"Show Detail"]; - [toolbarItem setImage: [NSImage imageNamed: @"Info"]]; + [toolbarItem setToolTip: @"Displays detailed information in the queue"]; + [toolbarItem setImage: [NSImage imageNamed: @"Detail"]]; // Tell the item what message to send when it is clicked [toolbarItem setTarget: self]; - [toolbarItem setAction: @selector(toggleShowsDetail:)]; + [toolbarItem setAction: fShowsDetail ? @selector(hideDetail:) : @selector(showDetail:)]; } else if ([itemIdentifier isEqual: HBShowGroupsToolbarIdentifier]) { toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdentifier] autorelease]; +/* // Set the text label to be displayed in the toolbar and customization palette - [toolbarItem setLabel: @"View"]; - [toolbarItem setPaletteLabel: @"View"]; + [toolbarItem setLabel: @"Passes"]; + [toolbarItem setPaletteLabel: @"Passes"]; // Set up a reasonable tooltip, and image - [toolbarItem setToolTip: @"View"]; -// [toolbarItem setImage: [NSImage imageNamed: @"Disc"]]; - + [toolbarItem setToolTip: @"Displays individual passes in the queue"]; + [toolbarItem setImage: [NSImage imageNamed: @"Passes"]]; + // Tell the item what message to send when it is clicked + [toolbarItem setTarget: self]; + [toolbarItem setAction: fShowsJobsAsGroups ? @selector(showJobsAsPasses:) : @selector(showJobsAsGroups:)]; +*/ + +// Various attempts at other button types in the toolbar. A matrix worked fine to display +// a button for encodes & passes, but ultimately I decided to go with a single button +// called "Passes" that toggles on or off. All these suffer from the fact taht you need +// to override NSToolbarItem for them in order to validate their state. + [toolbarItem setLabel: @"View"]; + [toolbarItem setPaletteLabel: @"View"]; + NSButtonCell * buttonCell = [[[NSButtonCell alloc] initImageCell:nil] autorelease]; - [buttonCell setBezelStyle:NSShadowlessSquareBezelStyle];//NSShadowlessSquareBezelStyle + [buttonCell setBezelStyle:NSShadowlessSquareBezelStyle]; [buttonCell setButtonType:NSToggleButton]; [buttonCell setBordered:NO]; [buttonCell setImagePosition:NSImageOnly]; @@ -1003,10 +1091,16 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo [buttonCell setTitle:@""]; [buttonCell setImage:[NSImage imageNamed: @"Encodes"]]; [buttonCell setAlternateImage:[NSImage imageNamed: @"EncodesPressed"]]; + [buttonCell setAction: @selector(showJobsAsGroups:)]; + [matrix setToolTip: @"Displays encodes in the queue" forCell:buttonCell]; + buttonCell = [matrix cellAtRow:0 column:1]; [buttonCell setTitle:@""]; [buttonCell setImage:[NSImage imageNamed: @"Passes"]]; [buttonCell setAlternateImage:[NSImage imageNamed: @"PassesPressed"]]; + [buttonCell setAction: @selector(showJobsAsPasses:)]; + [matrix setToolTip: @"Displays individual passes in the queue" forCell:buttonCell]; + [toolbarItem setMinSize: [matrix frame].size]; [toolbarItem setMaxSize: [matrix frame].size]; [toolbarItem setView: matrix]; @@ -1027,18 +1121,18 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo */ /* - NSButton * button = [[[NSButton alloc] initWithFrame:NSMakeRect(0,0,20,20)] autorelease]; + NSButton * button = [[[NSButton alloc] initWithFrame:NSMakeRect(0,0,32,32)] autorelease]; [button setButtonType:NSSwitchButton]; [button setTitle:@""]; [button setState: fShowsJobsAsGroups ? NSOnState : NSOffState]; [toolbarItem setMinSize: NSMakeSize(20,20)]; [toolbarItem setMaxSize: NSMakeSize(20,20)]; [toolbarItem setView: button]; -*/ // Tell the item what message to send when it is clicked [toolbarItem setTarget: self]; [toolbarItem setAction: @selector(jobGroupsChanged:)]; +*/ } return toolbarItem; @@ -1134,38 +1228,34 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo } } -/* not used because HBShowGroupsToolbarIdentifier is now a custom view else if ([[toolbarItem itemIdentifier] isEqual: HBShowGroupsToolbarIdentifier]) { enable = hb_count(fHandle) > 0; + [toolbarItem setAction: fShowsJobsAsGroups ? @selector(showJobsAsPasses:) : @selector(showJobsAsGroups:)]; if (fShowsJobsAsGroups) { - [toolbarItem setLabel: @"View Passes"]; - [toolbarItem setPaletteLabel: @"View Passes"]; - [toolbarItem setToolTip: @"Displays items in the queue as individual passes"]; + [toolbarItem setImage: [NSImage imageNamed: @"Passes"]]; + [toolbarItem setToolTip: @"Displays individual passes in the queue"]; } else { - [toolbarItem setLabel: @"View Encodes"]; - [toolbarItem setPaletteLabel: @"View Encodes"]; - [toolbarItem setToolTip: @"Displays items in the queue as encodes"]; + [toolbarItem setImage: [NSImage imageNamed: @"PassesPressed"]]; + [toolbarItem setToolTip: @"Displays encodes in the queue"]; } } -*/ else if ([[toolbarItem itemIdentifier] isEqual: HBShowDetailToolbarIdentifier]) { enable = hb_count(fHandle) > 0; + [toolbarItem setAction: fShowsDetail ? @selector(hideDetail:) : @selector(showDetail:)]; if (fShowsDetail) { - [toolbarItem setLabel: @"Hide Detail"]; - [toolbarItem setPaletteLabel: @"Hide Detail"]; - [toolbarItem setToolTip: @"Displays detailed information in the queue"]; + [toolbarItem setImage: [NSImage imageNamed: @"DetailPressed"]]; + [toolbarItem setToolTip: @"Hides detailed information in the queue"]; } else { - [toolbarItem setLabel: @"Show Detail"]; - [toolbarItem setPaletteLabel: @"Show Detail"]; + [toolbarItem setImage: [NSImage imageNamed: @"Detail"]]; [toolbarItem setToolTip: @"Displays detailed information in the queue"]; } } @@ -1191,6 +1281,16 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo [self setShowsDetail:fShowsDetail]; [self setShowsJobsAsGroups:fShowsJobsAsGroups]; [self showCurrentJobPane:NO]; + +#if HB_QUEUE_DRAGGING + [fTaskView registerForDraggedTypes: [NSArray arrayWithObject:HBQueueDataType] ]; +#endif + +#if HB_OUTLINE_QUEUE + // Don't allow autoresizing of main column, else the "delete" column will get + // pushed out of view. + [fOutlineView setAutoresizesOutlineColumn: NO]; +#endif } @@ -1210,11 +1310,18 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo //------------------------------------------------------------------------------------ - (int)numberOfRowsInTableView: (NSTableView *)aTableView { - BOOL jobGroups = [[NSUserDefaults standardUserDefaults] boolForKey:@"QueueShowsJobsAsGroups"]; - if (jobGroups) +#if HB_UNI_QUEUE + int numItems = hb_current_job(fHandle) ? 1 : 0; + if (fShowsJobsAsGroups) + return numItems + hb_group_count(fHandle); + else + return numItems + hb_count(fHandle); +#else + if (fShowsJobsAsGroups) return hb_group_count(fHandle); else return hb_count(fHandle); +#endif } //------------------------------------------------------------------------------------ @@ -1227,28 +1334,47 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo if (!fHandle) return @""; // fatal error! - hb_job_t * job; + hb_job_t * job = nil; - BOOL jobGroups = [[NSUserDefaults standardUserDefaults] boolForKey:@"QueueShowsJobsAsGroups"]; - if (jobGroups) +#if HB_UNI_QUEUE + // Looking for the current job? + int jobIndex = rowIndex; + if (hb_current_job(fHandle)) + { + if (rowIndex == 0) + job = hb_current_job(fHandle); + else + jobIndex = rowIndex - 1; + } + + if (!job) + { + if (fShowsJobsAsGroups) + job = hb_group(fHandle, jobIndex); + else + job = hb_job(fHandle, jobIndex); + } +#else + if (fShowsJobsAsGroups) job = hb_group(fHandle, rowIndex); else job = hb_job(fHandle, rowIndex); - +#endif + if (!job) return @""; // fatal error! if ([[aTableColumn identifier] isEqualToString:@"desc"]) { BOOL highlighted = [aTableView isRowSelected:rowIndex] && [[aTableView window] isKeyWindow] && ([[aTableView window] firstResponder] == aTableView); - return [self attributedDescriptionForJob:job withDetail:fShowsDetail withHighlighting:highlighted]; + return [self attributedDescriptionForJob:job withTitle:YES withDetail:fShowsDetail withHighlighting:highlighted]; } else if ([[aTableColumn identifier] isEqualToString:@"delete"]) return @""; else if ([[aTableColumn identifier] isEqualToString:@"icon"]) - return fShowsJobsAsGroups ? [NSImage imageNamed:@"JobSmall"] : [NSImage imageNamed:@"JobPassSmall"]; + return fShowsJobsAsGroups ? [NSImage imageNamed:@"JobSmall"] : [self smallImageForPass: job->pass]; return @""; } @@ -1276,4 +1402,153 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo } } +//------------------------------------------------------------------------------------ +// NSTableView delegate +//------------------------------------------------------------------------------------ +#if HB_UNI_QUEUE +- (float)tableView:(NSTableView *)tableView heightOfRow:(int)row +{ + if ((row == 0) && hb_current_job(fHandle)) + return HB_ROW_HEIGHT_ACTIVE_JOB; + else + return fShowsDetail ? HB_ROW_HEIGHT_DETAIL : HB_ROW_HEIGHT_NO_DETAIL; +} +#endif + +#if HB_QUEUE_DRAGGING +- (BOOL)tableView:(NSTableView *)tv writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard*)pboard +{ + // Copy the row numbers to the pasteboard. + NSData *data = [NSKeyedArchiver archivedDataWithRootObject:rowIndexes]; + [pboard declareTypes:[NSArray arrayWithObject:HBQueueDataType] owner:self]; + [pboard setData:data forType:HBQueueDataType]; + return YES; +} +#endif + +#if HB_QUEUE_DRAGGING +- (NSDragOperation)tableView:(NSTableView*)tv validateDrop:(id )info proposedRow:(int)row proposedDropOperation:(NSTableViewDropOperation)op +{ + // Add code here to validate the drop + NSLog(@"validate Drop"); + return NSDragOperationEvery; +} +#endif + +#if HB_QUEUE_DRAGGING +- (BOOL)tableView:(NSTableView *)aTableView acceptDrop:(id )info + row:(int)row dropOperation:(NSTableViewDropOperation)operation +{ + NSPasteboard* pboard = [info draggingPasteboard]; + NSData* rowData = [pboard dataForType:HBQueueDataType]; + NSIndexSet* rowIndexes = [NSKeyedUnarchiver unarchiveObjectWithData:rowData]; + int dragRow = [rowIndexes firstIndex]; + + // Move the specified row to its new location... + + return YES; +} +#endif + + +#if HB_OUTLINE_QUEUE + +- (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item +{ + if (item == nil) + return [fEncodes objectAtIndex:index]; + else + return [item objectAtIndex:index]; +} + +- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item +{ + return ! [item isKindOfClass:[HBJob class]]; +} + +- (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item +{ + if (item == nil) + return [fEncodes count]; + else + return [item count]; +} + +- (float)outlineView:(NSOutlineView *)outlineView heightOfRowByItem:(id)item +{ + if (fShowsDetail && [item isKindOfClass:[HBJob class]]) + return HB_ROW_HEIGHT_DETAIL; + else + return HB_ROW_HEIGHT_NO_DETAIL; +} + +- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item +{ + BOOL highlighted = [outlineView isRowSelected:[outlineView rowForItem: item]] && [[outlineView window] isKeyWindow] && ([[outlineView window] firstResponder] == outlineView); + if ([item isKindOfClass:[HBJob class]]) + { + if ([[tableColumn identifier] isEqualToString:@"desc"]) + { + hb_job_t * job = [item job]; +// return [self attributedDescriptionForJob:job withTitle:NO withDetail:fShowsDetail withHighlighting:highlighted]; + if (job->pass == -1) + return @"Subtitle Scan"; + else + { + int passNum = MAX( 1, job->pass ); + if (passNum == 1) + return @"1st Pass"; + if (passNum == 2) + return @"2nd Pass"; + else + return [NSString stringWithFormat: @"Pass %d", passNum]; + } + } + } + + else + { + hb_job_t * job = [[item objectAtIndex:0] job]; + if ([[tableColumn identifier] isEqualToString:@"desc"]) + return [self attributedDescriptionForJob:job withTitle:YES withDetail:NO withHighlighting:highlighted]; + } + + return @""; +} + +- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item +{ + if ([[tableColumn identifier] isEqualToString:@"desc"]) + { + if ([item isKindOfClass:[HBJob class]]) + [cell setImage:[self smallImageForPass: [item job]->pass]]; + else + [cell setImage:[NSImage imageNamed:@"JobSmall"]]; + } + + else if ([[tableColumn identifier] isEqualToString:@"delete"]) + { + // The Delete action can only be applied for group items, not indivdual jobs. + if ([item isKindOfClass:[HBJob class]]) + { + [cell setEnabled: NO]; + [cell setImage: nil]; + } + else + { + [cell setEnabled: YES]; + BOOL highlighted = [outlineView isRowSelected:[outlineView rowForItem: item]] && [[outlineView window] isKeyWindow] && ([[outlineView window] firstResponder] == outlineView); + if (highlighted) + { + [cell setImage:[NSImage imageNamed:@"DeleteHighlight"]]; + [cell setAlternateImage:[NSImage imageNamed:@"DeleteHighlightPressed"]]; + } + else + [cell setImage:[NSImage imageNamed:@"Delete"]]; + } + } +} + +#endif + @end diff --git a/macosx/HandBrake.xcodeproj/project.pbxproj b/macosx/HandBrake.xcodeproj/project.pbxproj index 9f0045429..aec33037a 100644 --- a/macosx/HandBrake.xcodeproj/project.pbxproj +++ b/macosx/HandBrake.xcodeproj/project.pbxproj @@ -131,7 +131,6 @@ A9AC41DF0C918DB500DDF9B8 /* HBAdvancedController.m in Sources */ = {isa = PBXBuildFile; fileRef = A9AC41DD0C918DB500DDF9B8 /* HBAdvancedController.m */; }; A9AC41E00C918DB500DDF9B8 /* HBAdvancedController.h in Headers */ = {isa = PBXBuildFile; fileRef = A9AC41DE0C918DB500DDF9B8 /* HBAdvancedController.h */; }; A9AC41E70C918DC000DDF9B8 /* AdvancedView.nib in Resources */ = {isa = PBXBuildFile; fileRef = A9AC41E50C918DC000DDF9B8 /* AdvancedView.nib */; }; - A9B4CEC80C95752B0086548A /* pref-general.png in Resources */ = {isa = PBXBuildFile; fileRef = A9B4CEC70C95752B0086548A /* pref-general.png */; }; A9DE40450C959834008A5440 /* minus-8.png in Resources */ = {isa = PBXBuildFile; fileRef = A9DE40430C959834008A5440 /* minus-8.png */; }; A9DE40460C959834008A5440 /* plus-8.png in Resources */ = {isa = PBXBuildFile; fileRef = A9DE40440C959834008A5440 /* plus-8.png */; }; B48359A80C82960500E04440 /* lang.c in Sources */ = {isa = PBXBuildFile; fileRef = B48359A70C82960500E04440 /* lang.c */; }; @@ -142,9 +141,16 @@ E30EC7740C90BDD0004B9545 /* PassesPressed.png in Resources */ = {isa = PBXBuildFile; fileRef = E30EC7700C90BDD0004B9545 /* PassesPressed.png */; }; E30EC7750C90BDD0004B9545 /* Passes.png in Resources */ = {isa = PBXBuildFile; fileRef = E30EC7710C90BDD0004B9545 /* Passes.png */; }; E30EC7760C90BDD0004B9545 /* EncodesPressed.png in Resources */ = {isa = PBXBuildFile; fileRef = E30EC7720C90BDD0004B9545 /* EncodesPressed.png */; }; - E318F0470C90D6D3003EFB59 /* JobPassLarge.png in Resources */ = {isa = PBXBuildFile; fileRef = E318F0460C90D6D3003EFB59 /* JobPassLarge.png */; }; - E318F0580C90D88C003EFB59 /* JobPassSmall.png in Resources */ = {isa = PBXBuildFile; fileRef = E318F0570C90D88C003EFB59 /* JobPassSmall.png */; }; - E318F0830C90DC4A003EFB59 /* Info.png in Resources */ = {isa = PBXBuildFile; fileRef = E318F0820C90DC4A003EFB59 /* Info.png */; }; + E37167800C92F5090072B384 /* DetailPressed.png in Resources */ = {isa = PBXBuildFile; fileRef = E371677E0C92F5090072B384 /* DetailPressed.png */; }; + E37167810C92F5090072B384 /* Detail.png in Resources */ = {isa = PBXBuildFile; fileRef = E371677F0C92F5090072B384 /* Detail.png */; }; + E37167890C92F6180072B384 /* JobPassSecondSmall.png in Resources */ = {isa = PBXBuildFile; fileRef = E37167830C92F6180072B384 /* JobPassSecondSmall.png */; }; + E371678A0C92F6180072B384 /* JobPassSubtitleSmall.png in Resources */ = {isa = PBXBuildFile; fileRef = E37167840C92F6180072B384 /* JobPassSubtitleSmall.png */; }; + E371678B0C92F6180072B384 /* JobPassFirstSmall.png in Resources */ = {isa = PBXBuildFile; fileRef = E37167850C92F6180072B384 /* JobPassFirstSmall.png */; }; + E371678C0C92F6180072B384 /* JobPassFirstLarge.png in Resources */ = {isa = PBXBuildFile; fileRef = E37167860C92F6180072B384 /* JobPassFirstLarge.png */; }; + E371678D0C92F6180072B384 /* JobPassSubtitleLarge.png in Resources */ = {isa = PBXBuildFile; fileRef = E37167870C92F6180072B384 /* JobPassSubtitleLarge.png */; }; + E371678E0C92F6180072B384 /* JobPassSecondLarge.png in Resources */ = {isa = PBXBuildFile; fileRef = E37167880C92F6180072B384 /* JobPassSecondLarge.png */; }; + E37167A90C92FAA50072B384 /* JobPassUnknownSmall.png in Resources */ = {isa = PBXBuildFile; fileRef = E37167A70C92FAA50072B384 /* JobPassUnknownSmall.png */; }; + E37167AA0C92FAA50072B384 /* JobPassUnknownLarge.png in Resources */ = {isa = PBXBuildFile; fileRef = E37167A80C92FAA50072B384 /* JobPassUnknownLarge.png */; }; E37C89410C83988F00C1B919 /* DeleteHighlight.png in Resources */ = {isa = PBXBuildFile; fileRef = E37C893D0C83988F00C1B919 /* DeleteHighlight.png */; }; E37C89420C83988F00C1B919 /* Delete.png in Resources */ = {isa = PBXBuildFile; fileRef = E37C893E0C83988F00C1B919 /* Delete.png */; }; E37C89430C83988F00C1B919 /* JobSmall.png in Resources */ = {isa = PBXBuildFile; fileRef = E37C893F0C83988F00C1B919 /* JobSmall.png */; }; @@ -307,9 +313,16 @@ E30EC7700C90BDD0004B9545 /* PassesPressed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = PassesPressed.png; sourceTree = ""; }; E30EC7710C90BDD0004B9545 /* Passes.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Passes.png; sourceTree = ""; }; E30EC7720C90BDD0004B9545 /* EncodesPressed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = EncodesPressed.png; sourceTree = ""; }; - E318F0460C90D6D3003EFB59 /* JobPassLarge.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = JobPassLarge.png; sourceTree = ""; }; - E318F0570C90D88C003EFB59 /* JobPassSmall.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = JobPassSmall.png; sourceTree = ""; }; - E318F0820C90DC4A003EFB59 /* Info.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Info.png; sourceTree = ""; }; + E371677E0C92F5090072B384 /* DetailPressed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = DetailPressed.png; sourceTree = ""; }; + E371677F0C92F5090072B384 /* Detail.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Detail.png; sourceTree = ""; }; + E37167830C92F6180072B384 /* JobPassSecondSmall.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = JobPassSecondSmall.png; sourceTree = ""; }; + E37167840C92F6180072B384 /* JobPassSubtitleSmall.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = JobPassSubtitleSmall.png; sourceTree = ""; }; + E37167850C92F6180072B384 /* JobPassFirstSmall.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = JobPassFirstSmall.png; sourceTree = ""; }; + E37167860C92F6180072B384 /* JobPassFirstLarge.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = JobPassFirstLarge.png; sourceTree = ""; }; + E37167870C92F6180072B384 /* JobPassSubtitleLarge.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = JobPassSubtitleLarge.png; sourceTree = ""; }; + E37167880C92F6180072B384 /* JobPassSecondLarge.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = JobPassSecondLarge.png; sourceTree = ""; }; + E37167A70C92FAA50072B384 /* JobPassUnknownSmall.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = JobPassUnknownSmall.png; sourceTree = ""; }; + E37167A80C92FAA50072B384 /* JobPassUnknownLarge.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = JobPassUnknownLarge.png; sourceTree = ""; }; E37C893D0C83988F00C1B919 /* DeleteHighlight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = DeleteHighlight.png; sourceTree = ""; }; E37C893E0C83988F00C1B919 /* Delete.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Delete.png; sourceTree = ""; }; E37C893F0C83988F00C1B919 /* JobSmall.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = JobSmall.png; sourceTree = ""; }; @@ -558,15 +571,22 @@ E3003CB40C8852B70072F2A8 /* DeletePressed.png */, E37C893D0C83988F00C1B919 /* DeleteHighlight.png */, E3003C7E0C88505D0072F2A8 /* DeleteHighlightPressed.png */, - E37C89400C83988F00C1B919 /* JobLarge.png */, - E37C893F0C83988F00C1B919 /* JobSmall.png */, E30EC76F0C90BDD0004B9545 /* Encodes.png */, E30EC7720C90BDD0004B9545 /* EncodesPressed.png */, E30EC7700C90BDD0004B9545 /* PassesPressed.png */, E30EC7710C90BDD0004B9545 /* Passes.png */, - E318F0570C90D88C003EFB59 /* JobPassSmall.png */, - E318F0460C90D6D3003EFB59 /* JobPassLarge.png */, - E318F0820C90DC4A003EFB59 /* Info.png */, + E37C89400C83988F00C1B919 /* JobLarge.png */, + E37C893F0C83988F00C1B919 /* JobSmall.png */, + E37167850C92F6180072B384 /* JobPassFirstSmall.png */, + E37167860C92F6180072B384 /* JobPassFirstLarge.png */, + E37167830C92F6180072B384 /* JobPassSecondSmall.png */, + E37167880C92F6180072B384 /* JobPassSecondLarge.png */, + E37167840C92F6180072B384 /* JobPassSubtitleSmall.png */, + E37167870C92F6180072B384 /* JobPassSubtitleLarge.png */, + E37167A70C92FAA50072B384 /* JobPassUnknownSmall.png */, + E37167A80C92FAA50072B384 /* JobPassUnknownLarge.png */, + E371677E0C92F5090072B384 /* DetailPressed.png */, + E371677F0C92F5090072B384 /* Detail.png */, ); path = icons; sourceTree = ""; @@ -760,13 +780,19 @@ E30EC7740C90BDD0004B9545 /* PassesPressed.png in Resources */, E30EC7750C90BDD0004B9545 /* Passes.png in Resources */, E30EC7760C90BDD0004B9545 /* EncodesPressed.png in Resources */, - E318F0470C90D6D3003EFB59 /* JobPassLarge.png in Resources */, - E318F0580C90D88C003EFB59 /* JobPassSmall.png in Resources */, - E318F0830C90DC4A003EFB59 /* Info.png in Resources */, A9AC41E70C918DC000DDF9B8 /* AdvancedView.nib in Resources */, A97A1DB40C91A6800015BC08 /* Express.nib in Resources */, A9ABA2270C92AECA00D98324 /* PictureSettings.nib in Resources */, - A9B4CEC80C95752B0086548A /* pref-general.png in Resources */, + E37167800C92F5090072B384 /* DetailPressed.png in Resources */, + E37167810C92F5090072B384 /* Detail.png in Resources */, + E37167890C92F6180072B384 /* JobPassSecondSmall.png in Resources */, + E371678A0C92F6180072B384 /* JobPassSubtitleSmall.png in Resources */, + E371678B0C92F6180072B384 /* JobPassFirstSmall.png in Resources */, + E371678C0C92F6180072B384 /* JobPassFirstLarge.png in Resources */, + E371678D0C92F6180072B384 /* JobPassSubtitleLarge.png in Resources */, + E371678E0C92F6180072B384 /* JobPassSecondLarge.png in Resources */, + E37167A90C92FAA50072B384 /* JobPassUnknownSmall.png in Resources */, + E37167AA0C92FAA50072B384 /* JobPassUnknownLarge.png in Resources */, A9DE40450C959834008A5440 /* minus-8.png in Resources */, A9DE40460C959834008A5440 /* plus-8.png in Resources */, A94537560C95E6A300EBB9B1 /* pref-picture.png in Resources */, diff --git a/macosx/icons/Detail.png b/macosx/icons/Detail.png new file mode 100644 index 0000000000000000000000000000000000000000..b98500a08337b65d088f25e0b48ae4ce12d34dd2 GIT binary patch literal 1808 zcmV+r2k-caP)Dt9Tl zXex-cpbIDhp>gSAnRv|vEX$m1x=iH^W`1)H=Q-zp&htL+ zyJ}(a|N74?OAAX!mqDH{`;O4gkA1c#EPXA&k8?QpU+q2Wc?ZRum18Q4 zTVv4lRRJ#jqQ~`{E%^D@QxfcRteN&WXD;P(%|C8zV{h#=Nij0BxHb0nsqaehWmf~v z{<0s<-{<1+Hyfe5x<-P1j`7}=u6l58ajWJw*RsanYHmNYpZkpP(Yhn;8EC&zjgNjT zLDjV+lz*uq;v^0ToAvH8?70*z`JBVKTvJQ6tif9M)x5u*wUbY%tFGbmY+Sr?5DnM2 zV*eEl_J3g@PO{|`QzlJ@x6&Pc(J#t50lBoIt`Wqdj2cUjzq2h;YR=3KAA2WHmqNreP52+ ztD8`IS%ZC@v3IyE+fsr5>haP5t4n<8Z;dg|d8NdWtDDjGLpgHmRJU2X`|kAlObL9d zvhhkjj$O;e-u77R?TC?SXUolHySG!`+t(om>Jae`QNy(Y)@r}qj2PZ z5Q?IcYP4Q0!Nz@y!9C0l;5Kon_Q2_6)PI#pVzS`wi_x^QL;p{Y}`xi%20?cT-#V)ADot2vlh_6M??#V{=)sHNY8SrKksW(S}j zj4nO>dKI>*=^Kv{sOf$qko#UJGMj>lAZ$MtM4#Ww#sRby3ge!{yKI$4Ka2LVn?s^WM>>hJ`0rVf z;bj~kwqPd30`KhC2V%2i?;7C2p4q)@}L!J>?KG^YL6ipqBP4u#*9SJ16 zSn@ZKpGLl7m4|VFB;7*1ruUaf6FJ6Q;cuy@D`-_=Nzz1c53>W%vUDE%Nae<=K)Tmp zq}BvTqzF>0Wou~8L}q$pX6Uns%A0|d>cw)d!AgDrGDs`A(jU%a9V)p;cLP}1I`mN} z;$OOz*02PrH2p?8nO46@vIa~Cm=p0l;)-UAJpa4$m{fieq@{@WxW(GtHaDyxBW*KR zWKTm%eE_u8{xtm}Bp+lHl0Q#94m0S~p=ndG{;h>lEU8l7Pog}AW7;aZnuY)@&zXiH z&bIgV&oQr_y&rTM<}yeZQQ(E7x`jxpQXrA;dV_@QCmL*p98auJ$T7ARa!vBlgC_T;`2roqC^tdxi=eHOF!afR z6{PjdeKi-WhgGi!M%g>|%kzmGb4#_`3-Q&nkx(@kYb)nr-P?Xx_tpX#@;R1J<%>0x zquS*KuCaIQUqBkJ{7_l%ewtf~B3oiu-+{d~4kK(DJ;Pj~+&%&7GB3m(^1-Wzndykr zPlvkH3(Cw1@C+M`!A}f0PBm+&_9?CxIz27^>I*PEJz-5a5H7?x;uY(DJ>zW$_bqd9 zvN`$K(}S)LcYpZi@G)WP)c_cgn zq7X>{S>++hSZ5dAZDp*wKI%A&!xRC55RzO>ASB^&WDVNlR*<{r=G>6P$Iw5v|Lm89 zbME>4e!ufO_uSt-lP&(?Oo{^qX$fq8W&SRsyoQD-Yq$7^&|jM}U%g2QhOGnqv$W=6 zoY4GBWkzQFY;JD$sl8_Bp3Rd6^K;V^hS3qN=5BrEzOWeW4jIfp`_F^X zA(f(zv-X#+Yu;YI!r4cvP^z`#Gh~GM+3)}T;O1xU?pwXQeSCeqxBc4XkJl!_^i%5u zv#r}UdHZ^A_uB65iy28INOgvJ3d5)={~Knc3K zlimdyXu-k3fq@~v%OttUJA@btg*Yrcj2=!8riBKF(C8~o$l%f^5zv(ux-*o)2xmZ( z&`>&!MvvTZ4)GGt@K8c@IwPiOq@58K#@HE3k7RkpBhCqA&M3iV%w>0H7^4aaU|y zEL399=ZOD(Q#>1~8Gz%7TplkDikq^DT)*i9-fj-(GZ?Z10Df|^8OQBO`hdKDcmX4o z$K`V4;O2lvT{Y}-xxBQ{EEFEcr#7eTg;9At$W=vzDVLkN_fHG^hu`qpm&}dd&Fj^j zP2$EAI3@klYZiCdp77t7nh?JShTz6Pp0F>??=LnO$6L1Y(o+ZyEfV);By4H1!#Mt3 zh+k|*#urJcd($)G`~tsw4#UeYSs(ibFvF>SA4h&^rDUZNjkD|O_uha1z143z+YJ8P zU2`TcEq`nM%>VTI|8x4Q>wnh<4-aq8jqa-gUsnISyqNp>*;!Br*dJ|uq5cD6vvT+c zG7n_(4<5`s$o=gZ`}+4w7i2;Ny=#O50sr8E&2`rN@!K@MfS;9EF@AQFiRi%W`&N(%D}MDSA>V5xs*X@O8EguEE?;*uh0C=?cz?ruc^%2LIJgo=tw zDy|s%h!91E#fOh%kPrCh`Nbq})BvCnmxxP?iVq*HD2PS=%(4=sD|*N~%gV)NCFPZs z6{S&#(<{VC?NwI+_*z_AB0eIKNGgsp5s$1WMJf~b0&qfHcJ#O~n{ohJERWGfslBo?hk4w$G;q<<5E$*;Aoq4LMrn-j6O;RnD)|@)c zZ??fW{D0eTP$&lFZTyJq&z=A0qt6Ts^mKK1_uT90?&-Ucbk@H9d3O|D-S>L?`ubGz{=TlB zp2|ks`rmV}zq_};zhB;O0ONAGysxjf>f41)m`dxA_sa*M6oUXv3@8TVaz$_M!t+zt zFeHb0K`E7EU3iKHZR6m=?YthDQu~10m2&`nTOQB7R>F->!P2(MVvU>Dm<( z-_&f-X*Am5kr9}_1sfhbJY%W<2E`-7MGxJ<_~aPjZ7_b{cN)3F`fr^w8DLl=VN7qFm>h?mguCg7o9z~N*#6_r<45B}1fxL@`S{}>I=-^OIR4G$ zu^H0@vY0SEnYen%4&!*w={x!-Gp2`+re~fQI-2f1hvDVr=8JbaRfC-!7aK2IsZD)5 zxxBIR?YCCG@e3!L!T+DG169<9&CFnJBC6##i|yjr zI|~o;D7D(Ode|7ay?}AN)h2?(>Sygq76P#C=C)YOS(0?H$=m{o_5!&~s_md{pNeJ> z*^b%vMTnEH30s2tZHQwp5;TG#KJzL*^V9fZ@fXW)vGpx>e-^vH6!z@PRyb?f9|~oW z{iQ7Sd{AC|zRv#v-8}T)aYMCT4ztHUa&oj9I5@ek+i(57iQmj}U+3y%tpZ2q)f+wi zvd?yo{rKZp=egV){uDeXuYxLR|DRxC=&@{5KjE;}3?=K%l&~Q1jUhwf1xz+91!9DoBT4&XH#2Y7t=fUMu4dpH0GSQFs>?j5pzhwkA3 z9DoBX2AKaKZu7S{T?AQ;9*S}R65#sk4MEo2SmpqB0R&~!bK!;XQh4EW=ey2K5A6aR z36F^=D*0ssL2{{sM;R{G3Q&y6_%0000vu{l4~#e-zWU*?n=pN|&f6+?@kbV6yt#de;U+w&HKB)86nhF#P|| Z%%EiN{K3XR_$|;E44$rjF6*2Ung9r{anAq% literal 0 HcmV?d00001 diff --git a/macosx/icons/JobPassSecondLarge.png b/macosx/icons/JobPassSecondLarge.png new file mode 100644 index 0000000000000000000000000000000000000000..f5f6dcd693909622b3b35055d46bcfd1f0cdf33e GIT binary patch literal 923 zcmV;M17!S(P)Sf1xLZ9P1Dqrwu)^midK{K z+k4?G&-X4l&wF>trSA(LLc;N0zMsqedJvaOMn*{0-T!4}ug&~ztozhcDz!2&@ zYDX!coPbcZzo6AoI=+S!P(eVk_y;sj58FoykOEv`R1%QS7eV9nuzjQey+c3>_}>NG z-Q_{!^ss%TfNBZIX0u2plUQC}#@yT-B9REDrlzp8w1h+=f#c(2VRO+jEa2wm4m4(R zczB4}*;)AgeloZ&gM)+E-Q5+@`(M~Twh9OY0#7Q=GBPrPLZMKf0y;W6N_%=>U;v$+ zon>!uRaogJiu~mSPjE;_S0=l}oOpogr0rT_ooPdUg2Hf7>ni^L_K;U^N7gD*;=cu(GmZdhD7P zP%IWp_XKQtpU-Fd_$R4(0SgNYT>0kaW*i+I2^rt8fFBoEps_NWo13LGJzd`8@gN?L z3!8)OHJ?d>=?I1oOUhJcEP zfaL;KS653vbGm$YcQ;b0l<>Joj0y;ypZx-j$Y|Z|kq4#g>uaI&&|&*jO#pekWy_Q2 z{`>oTVRLAuCIn1RPjltR#>SA(TfgR5bpeZui(L8s{(fOAK6)`M;M><6Xv}0|V}rZS z6ZZG_g_L_r*gm!iI5{~%OG^t^J{Sz*^z`&ekdA5oVfsv)5G?W0;B*P0iV+6pmBQGK2m@bAO$=Y@bE@`4S!6X zp`LNEi=t8hBjCgP@2F>#j^k2*mH;*53U5``RNkqqIh==HZxno50$!-RWO${*e(q#s xxZoLoT&xG|65vs>a%`hW0ffH*009600{}y7f#^)RJktOG002ovPDHLkV1nmFtfBw_ literal 0 HcmV?d00001 diff --git a/macosx/icons/JobPassSecondSmall.png b/macosx/icons/JobPassSecondSmall.png new file mode 100644 index 0000000000000000000000000000000000000000..ec111d2f93b23d87e114ac04a8b5fe832af03e7f GIT binary patch literal 322 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSNH#i3J&% z$H&j2;>=f! z7Q8=xlwm8+i(S(>Ht96K-c=yOKJWR$OexL<(-?Dq&$*j6OYM=xw0A2~9co|SI36f+ zaNFDaZa-zW@~qI~*Yvt9GA(tX1{YiK>4r~tx)$hoOSCnrc&62NN3qT6D;H#OWbnPb z;Po$)LSScV;K(aBw&rjsO7IF3bf8bPE}l;;zzks|gr} zDo5(b1(Xutw)zd4jnL5pT!4yzLg5XRu{&fRE`SSgjDnhge7*q6*d4MD7oc?tZ~_0j zfR~p%C}VfXK3ss60y3EloSvS-&dv_Z&(Fj7_&ChW%)sK}B5ZAK!O6)9#9}d~W9k-= z&Axy#EO>r?hK-F4XlZG|K{SKUJ3c;UGB(+#;sQdU5V%~fvWhDc2m}m|jaVumo6SN` zPfy8`PNx$Z8X77sz+Eu`v$M0*a+8yjaCmqKsZ>gQUOXO$^Ye39T3Y%m%rXH_PdQM= z2pt_AMdcS37Bv4Z91cSy5-~Kk4B4k*0`SwNefl>yH%y9^i)8|?uCAy8_V)Iel`98| z0QD^~Rss@<1XVz9Z?7;PvzcDYLAQW(It$7ep|!P@Dq&z?0HV<-lY&~1eH>cTAWH%3 z>+2<_z{bW#adBk!(O{{7TrLNlot>%+9-JwTj*gg=rD3T61n2m!t}e}$pU2~YySqEX zD-tj< zG4by4Wh@hb)0})5_xJaUS9{zNM=|+)9$sHx#hss(l@;pZ2!&i+T$mw1eM2PnGX=^R z6+laEZEeY^PmbU3H(VYe`+NuiYN@ZUhvnsECgm*^aC>_T?d|Pl7svg9xw$!Usmv0~ z1jyhth8H=X&j+iktKwH;xXz!Ro`$uxHQ3+Z7ti&_M{{Nz-2$SKBq(Ed$Ua;E7oZ^^ z9C`p{><-z73*Z8{fPV$Z52T-?!5{Zf&2f;MqFewW;QO}(RC9!mV_X1DfW(-PuTp$c z{8D^2kKD^E#6=VENy=v;U!;(~w{ti}z&rkNu^Lh-0Zu7qzP8?Q0hm7k009600{~}p VPgIJjzkL7z002ovPDHLkV1hEv&!zwX literal 0 HcmV?d00001 diff --git a/macosx/icons/JobPassSubtitleSmall.png b/macosx/icons/JobPassSubtitleSmall.png new file mode 100644 index 0000000000000000000000000000000000000000..c6e04bee1830ec1d85d070db0cb0e1f5df931068 GIT binary patch literal 333 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSNH#i3J&% z$ZWwQ#v!E&KOJ$DS7`a^%JQ5U`u9 zuV`|y|7yyTj%hnB3VC}@>u!*;(0f)>cV=!RL&TrSA1AAD)^Q4d`P;CwJ3?_s-22U} zN4Okse*;sO??_B}Zdr4`{dr}_qK;CaL})3G*JY7yxr;Tp3Yn5xAH{efsYD;v`GzFS+Ft0kX$)fM! zu6Gu05^Zag!#K=dZ#&1}8+#3Jthae>_q!yy1=06U`qmo# zcip%xWGzdR;*s-#%L?{xGu8;(IrII2g(lsX-aBYWt|)F1c*K}+E}s8^WR?5DMa%h; z8Qor3CMq-Ma0UGNE`Ge8#p}j(D}`9I+YisbNVmI6b7~v zHU|zbY6434d&_n{m0NH|!QqS82|EYF`L@nkvU}SZfyO*yTvqNsA@AGUOES|1u**gzq^?J_n0B`8g2oJ>i(w5 z4+;yC?p$5x{Qli8hU$a0PZd_IkDgY;X#eAJlKh|54Auv8>%NtzHk987#>D^s%nX(B V@~^I|3i|-L44$rjF6*2Ung9hCx848% literal 0 HcmV?d00001 diff --git a/macosx/icons/JobPassUnknownSmall.png b/macosx/icons/JobPassUnknownSmall.png new file mode 100644 index 0000000000000000000000000000000000000000..d60542e3f5c2dd11aa79a5a50b062df20396e1b4 GIT binary patch literal 234 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSNH#i3J&% z$>$vRm~Rw5ck(I;)sL=fJjZ(UqO`aj zvx2jnzrK2Y`i#!*&Hq2&yFFF5VMUAK%~=;Q$X^VB8c4e zO_@1^v%mf+S8Yn$Ea|MWnJki~WFQdiXZx@@Quh literal 0 HcmV?d00001 -- 2.40.0