diff options
Diffstat (limited to 'macosx')
-rw-r--r-- | macosx/Controller.mm | 21 | ||||
-rw-r--r-- | macosx/English.lproj/Queue.nib/classes.nib | 7 | ||||
-rw-r--r-- | macosx/English.lproj/Queue.nib/info.nib | 4 | ||||
-rw-r--r-- | macosx/English.lproj/Queue.nib/keyedobjects.nib | bin | 59867 -> 13233 bytes | |||
-rw-r--r-- | macosx/HBImageAndTextCell.h | 30 | ||||
-rw-r--r-- | macosx/HBImageAndTextCell.m | 298 | ||||
-rw-r--r-- | macosx/HBQueueController.h | 24 | ||||
-rw-r--r-- | macosx/HBQueueController.mm | 401 | ||||
-rw-r--r-- | macosx/HandBrake.xcodeproj/project.pbxproj | 8 |
9 files changed, 719 insertions, 74 deletions
diff --git a/macosx/Controller.mm b/macosx/Controller.mm index 253e0ee2e..d92619a82 100644 --- a/macosx/Controller.mm +++ b/macosx/Controller.mm @@ -1828,6 +1828,15 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It +//------------------------------------------------------------------------------------ +// Removes all jobs from the queue. Does not cancel the current processing job. +//------------------------------------------------------------------------------------ +- (void) doDeleteQueuedJobs +{ + hb_job_t * job; + while( ( job = hb_job( fHandle, 0 ) ) ) + hb_rem( fHandle, job ); +} //------------------------------------------------------------------------------------ // Cancels the current job and proceeds with the next one in the queue. @@ -1869,7 +1878,10 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It NSBeginCriticalAlertSheet( alertTitle, - NSLocalizedString(@"Keep Encoding", nil), NSLocalizedString(@"Stop Encoding", nil), nil, docWindow, self, + NSLocalizedString(@"Keep Encoding", nil), + NSLocalizedString(@"Delete All", nil), + NSLocalizedString(@"Stop Encoding", nil), + docWindow, self, nil, @selector(didDimissCancelCurrentJob:returnCode:contextInfo:), nil, NSLocalizedString(@"Your movie will be lost if you don't continue encoding.", nil), [NSString stringWithUTF8String:job->title->name]); @@ -1886,8 +1898,13 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It - (void) didDimissCancelCurrentJob: (NSWindow *)sheet returnCode: (int)returnCode contextInfo: (void *)contextInfo { - if (returnCode == NSAlertAlternateReturn) + if (returnCode == NSAlertOtherReturn) [self doCancelCurrentJob]; + else if (returnCode == NSAlertAlternateReturn) + { + [self doDeleteQueuedJobs]; + [self doCancelCurrentJob]; + } } diff --git a/macosx/English.lproj/Queue.nib/classes.nib b/macosx/English.lproj/Queue.nib/classes.nib index 3e0a52912..8976f9e99 100644 --- a/macosx/English.lproj/Queue.nib/classes.nib +++ b/macosx/English.lproj/Queue.nib/classes.nib @@ -218,17 +218,21 @@ ACTIONS = { cancelCurrentJob = id; hideDetail = id; + imageSpacingChanged = id; + indentChanged = id; removeSelectedJob = id; showDetail = id; showJobsAsGroups = id; showJobsAsPasses = id; showQueueWindow = id; - toggleStartPause = id; + togglePauseResume = id; + toggleStartCancel = id; }; CLASS = HBQueueController; LANGUAGE = ObjC; OUTLETS = { fCurrentJobPane = NSView; + fIndentation = NSSlider; fJobDescTextField = NSTextField; fJobIconView = NSImageView; fOutlineView = NSOutlineView; @@ -237,6 +241,7 @@ fQueueCountField = NSTextField; fQueuePane = NSView; fQueueWindow = NSWindow; + fSpacing = NSSlider; fTaskView = NSTableView; }; SUPERCLASS = NSObject; diff --git a/macosx/English.lproj/Queue.nib/info.nib b/macosx/English.lproj/Queue.nib/info.nib index 0d9cf8ed4..9db2ce543 100644 --- a/macosx/English.lproj/Queue.nib/info.nib +++ b/macosx/English.lproj/Queue.nib/info.nib @@ -3,7 +3,7 @@ <plist version="1.0"> <dict> <key>IBDocumentLocation</key> - <string>361 594 453 434 0 0 1680 1028 </string> + <string>121 594 453 434 0 0 1680 1028 </string> <key>IBFramework Version</key> <string>446.1</string> <key>IBLockedObjects</key> @@ -22,7 +22,5 @@ </array> <key>IBSystem Version</key> <string>8R2218</string> - <key>IBUsesTextArchiving</key> - <true/> </dict> </plist> diff --git a/macosx/English.lproj/Queue.nib/keyedobjects.nib b/macosx/English.lproj/Queue.nib/keyedobjects.nib Binary files differindex b43b41bee..504ed1b7e 100644 --- a/macosx/English.lproj/Queue.nib/keyedobjects.nib +++ b/macosx/English.lproj/Queue.nib/keyedobjects.nib diff --git a/macosx/HBImageAndTextCell.h b/macosx/HBImageAndTextCell.h new file mode 100644 index 000000000..1da12cf94 --- /dev/null +++ b/macosx/HBImageAndTextCell.h @@ -0,0 +1,30 @@ +/* HBImageAndTextCell + + This file is part of the HandBrake source code. + Homepage: <http://handbrake.m0k.org/>. + It may be used under the terms of the GNU General Public License. +*/ + +#import <Cocoa/Cocoa.h> + +@interface HBImageAndTextCell : NSTextFieldCell +{ +@private + NSImage *image; + NSImageAlignment imageAlignment; // defaults to NSImageAlignTop. Supports NSImageAlignCenter & NSImageAlignBottom + NSSize imageSpacing; // horizontal and vertical spacing around the image +} + +- (void) setImage:(NSImage *)anImage; +- (NSImage *) image; + +- (void) setImageAlignment:(NSImageAlignment)alignment; +- (NSImageAlignment) imageAlignment; + +- (void)setImageSpacing:(NSSize)aSize; +- (NSSize)imageSpacing; + +- (void) drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView; +- (NSSize) cellSize; + +@end diff --git a/macosx/HBImageAndTextCell.m b/macosx/HBImageAndTextCell.m new file mode 100644 index 000000000..7052c357d --- /dev/null +++ b/macosx/HBImageAndTextCell.m @@ -0,0 +1,298 @@ +/* HBImageAndTextCell + + This file is part of the HandBrake source code. + Homepage: <http://handbrake.m0k.org/>. + It may be used under the terms of the GNU General Public License. +*/ + + +#import "HBImageAndTextCell.h" + + +static inline float +xLeftInRect(NSSize innerSize, NSRect outerRect) +{ + return NSMinX(outerRect); +} + +static inline float +xCenterInRect(NSSize innerSize, NSRect outerRect) +{ + return MAX(NSMidX(outerRect) - (innerSize.width/2.0), 0.0); +} + +static inline float +xRightInRect(NSSize innerSize, NSRect outerRect) +{ + return MAX(NSMaxX(outerRect) - innerSize.width, 0.0); +} + +static inline float +yTopInRect(NSSize innerSize, NSRect outerRect, BOOL flipped) +{ + if (flipped) + return NSMinY(outerRect); + else + return MAX(NSMaxY(outerRect) - innerSize.height, 0.0); +} + +static inline float +yCenterInRect(NSSize innerSize, NSRect outerRect, BOOL flipped) +{ + return MAX(NSMidY(outerRect) - innerSize.height/2.0, 0.0); +} + +static inline float +yBottomInRect(NSSize innerSize, NSRect outerRect, BOOL flipped) +{ + if (flipped) + return MAX(NSMaxY(outerRect) - innerSize.height, 0.0); + else + return NSMinY(outerRect); +} + +static inline NSSize +scaleProportionally(NSSize imageSize, NSRect canvasRect) +{ + float ratio; + + // get the smaller ratio and scale the image size by it + ratio = MIN(NSWidth(canvasRect) / imageSize.width, + NSHeight(canvasRect) / imageSize.height); + + imageSize.width *= ratio; + imageSize.height *= ratio; + + return imageSize; +} + + + +@implementation HBImageAndTextCell + +-(id)initTextCell:(NSString *)aString +{ + if (self = [super initTextCell:aString]) + { + imageAlignment = NSImageAlignTop; + imageSpacing = NSMakeSize (3.0, 2.0); + } + return self; +} + +-(id)initWithCoder:(NSCoder *)decoder +{ + if (self = [super initWithCoder:decoder]) + { + imageAlignment = NSImageAlignTop; + imageSpacing = NSMakeSize (3.0, 2.0); + } + return self; +} + +- (void)dealloc +{ + [image release]; + image = nil; + [super dealloc]; +} + +- copyWithZone:(NSZone *)zone +{ + HBImageAndTextCell *cell = (HBImageAndTextCell *)[super copyWithZone:zone]; + cell->image = [image retain]; + return cell; +} + +- (void)setImage:(NSImage *)anImage +{ + if (anImage != image) + { + [image release]; + image = [anImage retain]; + } +} + +- (NSImage *)image +{ + return image; +} + +- (void) setImageAlignment:(NSImageAlignment)alignment; +{ + imageAlignment = alignment; +} + +- (NSImageAlignment) imageAlignment; +{ + return imageAlignment; +} + +- (void)setImageSpacing:(NSSize)aSize; +{ + imageSpacing = aSize; +} + +- (NSSize)imageSpacing +{ + return imageSpacing; +} + +- (void)editWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject event:(NSEvent *)theEvent +{ + NSRect textFrame, imageFrame; + NSDivideRect (aRect, &imageFrame, &textFrame, (imageSpacing.width * 2) + [image size].width, NSMinXEdge); + [super editWithFrame: textFrame inView: controlView editor:textObj delegate:anObject event: theEvent]; +} + +- (void)selectWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject start:(int)selStart length:(int)selLength +{ + NSRect textFrame, imageFrame; + NSDivideRect (aRect, &imageFrame, &textFrame, (imageSpacing.width * 2) + [image size].width, NSMinXEdge); + [super selectWithFrame: textFrame inView: controlView editor:textObj delegate:anObject start:selStart length:selLength]; +} + +- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView +{ +#if 1 + if (image != nil) + { + NSSize imageSize; + NSRect imageFrame; + + imageSize = [image size]; + NSDivideRect(cellFrame, &imageFrame, &cellFrame, (imageSpacing.width * 2) + imageSize.width, NSMinXEdge); + if ([self drawsBackground]) + { + [[self backgroundColor] set]; + NSRectFill(imageFrame); + } + imageFrame.origin.x += imageSpacing.width; + imageFrame.size = imageSize; + + switch (imageAlignment) + { + default: + case NSImageAlignTop: + if ([controlView isFlipped]) + imageFrame.origin.y += imageFrame.size.height; + else + imageFrame.origin.y += (cellFrame.size.height - imageFrame.size.height); + break; + + case NSImageAlignCenter: + if ([controlView isFlipped]) + imageFrame.origin.y += ceil((cellFrame.size.height + imageFrame.size.height) / 2); + else + imageFrame.origin.y += ceil((cellFrame.size.height - imageFrame.size.height) / 2); + break; + + case NSImageAlignBottom: + if ([controlView isFlipped]) + imageFrame.origin.y += cellFrame.size.height; + // for unflipped, imageFrame is already correct + break; + + } + + [image compositeToPoint:imageFrame.origin operation:NSCompositeSourceOver]; + } + + [super drawWithFrame:cellFrame inView:controlView]; +#endif + + +#if 0 // this snippet supports all alignment values plus potentially scaling. + if (image != nil) + { + NSSize imageSize; + NSSize srcImageSize; + NSRect imageFrame; + NSPoint position; + BOOL flipped = [controlView isFlipped]; + + imageSize = [image size]; + srcImageSize = imageSize; // this will be more useful once/if we support scaling + + NSDivideRect(cellFrame, &imageFrame, &cellFrame, 12 + imageSize.width, NSMinXEdge); + if ([self drawsBackground]) + { + [[self backgroundColor] set]; + NSRectFill(imageFrame); + } + + switch (imageAlignment) + { + default: + case NSImageAlignLeft: + position.x = xLeftInRect(imageSize, imageFrame); + position.y = yCenterInRect(imageSize, imageFrame, flipped); + break; + case NSImageAlignRight: + position.x = xRightInRect(imageSize, imageFrame); + position.y = yCenterInRect(imageSize, imageFrame, flipped); + break; + case NSImageAlignCenter: + position.x = xCenterInRect(imageSize, imageFrame); + position.y = yCenterInRect(imageSize, imageFrame, flipped); + break; + case NSImageAlignTop: + position.x = xCenterInRect(imageSize, imageFrame); + position.y = yTopInRect(imageSize, imageFrame, flipped); + break; + case NSImageAlignBottom: + position.x = xCenterInRect(imageSize, imageFrame); + position.y = yBottomInRect(imageSize, imageFrame, flipped); + break; + case NSImageAlignTopLeft: + position.x = xLeftInRect(imageSize, imageFrame); + position.y = yTopInRect(imageSize, imageFrame, flipped); + break; + case NSImageAlignTopRight: + position.x = xRightInRect(imageSize, imageFrame); + position.y = yTopInRect(imageSize, imageFrame, flipped); + break; + case NSImageAlignBottomLeft: + position.x = xLeftInRect(imageSize, imageFrame); + position.y = yBottomInRect(imageSize, imageFrame, flipped); + break; + case NSImageAlignBottomRight: + position.x = xRightInRect(imageSize, imageFrame); + position.y = yBottomInRect(imageSize, imageFrame, flipped); + break; + } + + // account for flipped views + if (flipped) + { + position.y += imageSize.height; + imageSize.height = -imageSize.height; + } + + // Set image flipping to match view. Don't know if this is really the best way + // to deal with flipped views and images. + if ([image isFlipped] != flipped) + [image setFlipped: flipped]; + + // draw! + [image drawInRect: NSMakeRect(position.x, position.y, imageSize.width, imageSize.height) + fromRect: NSMakeRect(0, 0, srcImageSize.width, + srcImageSize.height) + operation: NSCompositeSourceOver + fraction: 1.0]; + + } + + [super drawWithFrame:cellFrame inView:controlView]; +#endif +} + +- (NSSize)cellSize +{ + NSSize cellSize = [super cellSize]; + cellSize.width += (image ? [image size].width + (imageSpacing.width * 2) : 0); + return cellSize; +} + +@end + diff --git a/macosx/HBQueueController.h b/macosx/HBQueueController.h index 474392507..1d5dd5842 100644 --- a/macosx/HBQueueController.h +++ b/macosx/HBQueueController.h @@ -11,7 +11,8 @@ @class HBController; // HB_OUTLINE_QUEUE turns on an outline view for the queue. -#define HB_OUTLINE_QUEUE 0 +#define HB_OUTLINE_QUEUE 1 +#define HB_OUTLINE_METRIC_CONTROLS 0 // for tweaking the outline cell spacings @interface HBQueueController : NSObject @@ -23,8 +24,9 @@ BOOL fShowsJobsAsGroups; BOOL fShowsDetail; #if HB_OUTLINE_QUEUE - NSMutableArray *fEncodes; - IBOutlet NSOutlineView *fOutlineView; + NSMutableArray *fEncodes; // hblib's job list organized in a hierarchy. Contents are HBJobs. + NSMutableIndexSet *fSavedExpandedItems; + unsigned int fSavedSelectedItem; #endif // +---------------fQueueWindow----------------+ @@ -55,8 +57,16 @@ // fQueuePane - always visible; fills entire window when fCurrentJobPane is hidden IBOutlet NSView *fQueuePane; +#if HB_OUTLINE_QUEUE + IBOutlet NSOutlineView *fOutlineView; +#else IBOutlet NSTableView *fTaskView; +#endif IBOutlet NSTextField *fQueueCountField; +#if HB_OUTLINE_METRIC_CONTROLS + IBOutlet NSSlider *fIndentation; // debug + IBOutlet NSSlider *fSpacing; // debug +#endif } @@ -72,6 +82,12 @@ - (IBAction)hideDetail: (id)sender; - (IBAction)showJobsAsGroups: (id)sender; - (IBAction)showJobsAsPasses: (id)sender; -- (IBAction)toggleStartPause: (id)sender; +- (IBAction)toggleStartCancel: (id)sender; +- (IBAction)togglePauseResume: (id)sender; + +#if HB_OUTLINE_METRIC_CONTROLS +- (IBAction)imageSpacingChanged: (id)sender; +- (IBAction)indentChanged: (id)sender; +#endif @end diff --git a/macosx/HBQueueController.mm b/macosx/HBQueueController.mm index 755692a02..09c73ecf3 100644 --- a/macosx/HBQueueController.mm +++ b/macosx/HBQueueController.mm @@ -6,14 +6,15 @@ #include "HBQueueController.h" #include "Controller.h" +#import "HBImageAndTextCell.h" -#define HB_QUEUE_DRAGGING 0 -#define HBQueueDataType @"HBQueueDataType" +#define HB_QUEUE_DRAGGING 0 // <--- NOT COMPLETELY FUNCTIONAL YET +#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_UNI_QUEUE 0 // <--- NOT COMPLETELY FUNCTIONAL YET #define HB_ROW_HEIGHT_DETAIL 98.0 #define HB_ROW_HEIGHT_NO_DETAIL 17.0 @@ -91,6 +92,7 @@ static void hb_rem_group( hb_handle_t * h, hb_job_t * job ) } } +#if HB_OUTLINE_QUEUE /** * Returns handle to the next job after the given job. * @param h Handle to hb_handle_t. @@ -108,6 +110,7 @@ static hb_job_t * hb_next_job( hb_handle_t * h, hb_job_t * job ) } return NULL; } +#endif #pragma mark - //------------------------------------------------------------------------------------ @@ -148,15 +151,22 @@ static hb_job_t * hb_next_job( hb_handle_t * h, hb_job_t * job ) @end + + + + #endif // HB_OUTLINE_QUEUE #pragma mark - // Toolbar identifiers -static NSString* HBQueueToolbar = @"HBQueueToolbar"; -static NSString* HBStartPauseResumeToolbarIdentifier = @"HBStartPauseResumeToolbarIdentifier"; -static NSString* HBShowDetailToolbarIdentifier = @"HBShowDetailToolbarIdentifier"; -static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsToolbarIdentifier"; +static NSString* HBQueueToolbar = @"HBQueueToolbar1"; +static NSString* HBQueueStartCancelToolbarIdentifier = @"HBQueueStartCancelToolbarIdentifier"; +static NSString* HBQueuePauseResumeToolbarIdentifier = @"HBQueuePauseResumeToolbarIdentifier"; +#if !HB_OUTLINE_QUEUE +static NSString* HBShowDetailToolbarIdentifier = @"HBQueueShowDetailToolbarIdentifier"; +static NSString* HBShowGroupsToolbarIdentifier = @"HBQueueShowGroupsToolbarIdentifier"; +#endif @implementation HBQueueController @@ -175,10 +185,11 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo @"YES", @"QueueShowsJobsAsGroups", nil]]; - fShowsDetail = [[NSUserDefaults standardUserDefaults] boolForKey:@"QueueShowsDetail"]; #if HB_OUTLINE_QUEUE + fShowsDetail = YES; fShowsJobsAsGroups = YES; #else + fShowsDetail = [[NSUserDefaults standardUserDefaults] boolForKey:@"QueueShowsDetail"]; fShowsJobsAsGroups = [[NSUserDefaults standardUserDefaults] boolForKey:@"QueueShowsJobsAsGroups"]; #endif @@ -202,6 +213,7 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo #if HB_OUTLINE_QUEUE [fEncodes release]; + [fSavedExpandedItems release]; #endif [super dealloc]; @@ -294,26 +306,22 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo //------------------------------------------------------------------------------------ - (void)setShowsDetail: (BOOL)showsDetail { +#if HB_OUTLINE_QUEUE + return; // Can't modify this value. It's always YES. +#else fShowsDetail = showsDetail; [[NSUserDefaults standardUserDefaults] setBool:showsDetail forKey:@"QueueShowsDetail"]; [[NSUserDefaults standardUserDefaults] synchronize]; [fTaskView setRowHeight:showsDetail ? HB_ROW_HEIGHT_DETAIL : HB_ROW_HEIGHT_NO_DETAIL]; -#if HB_UNI_QUEUE + #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 - + #endif if ([fTaskView selectedRow] != -1) [fTaskView scrollRowToVisible:[fTaskView selectedRow]]; +#endif } //------------------------------------------------------------------------------------ @@ -323,7 +331,7 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo { #if HB_OUTLINE_QUEUE return; // Can't modify this value. It's always YES. -#endif +#else fShowsJobsAsGroups = showsGroups; [[NSUserDefaults standardUserDefaults] setBool:showsGroups forKey:@"QueueShowsJobsAsGroups"]; @@ -332,6 +340,7 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo [self updateQueueUI]; if ([fTaskView selectedRow] != -1) [fTaskView scrollRowToVisible:[fTaskView selectedRow]]; +#endif } //------------------------------------------------------------------------------------ @@ -368,9 +377,11 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo //------------------------------------------------------------------------------------ - (void)rebuildEncodes { - [fEncodes removeAllObjects]; + [fEncodes autorelease]; + fEncodes = [[NSMutableArray arrayWithCapacity:0] retain]; NSMutableArray * aJobGroup = [NSMutableArray arrayWithCapacity:0]; + hb_job_t * nextJob = hb_group( fHandle, 0 ); while( nextJob ) { @@ -387,7 +398,118 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo nextJob = hb_next_job (fHandle, nextJob); } if ([aJobGroup count] > 0) + { [fEncodes addObject:aJobGroup]; + } +} +#endif + +#if HB_OUTLINE_QUEUE +//------------------------------------------------------------------------------------ +// Saves the state of the items that are currently expanded. Calling restoreExpandedItems +// will restore the state of all items to match what was saved by saveExpandedItems. +//------------------------------------------------------------------------------------ +- (void) saveExpandedItems +{ + if (!fSavedExpandedItems) + fSavedExpandedItems = [[NSMutableIndexSet alloc] init]; + else + [fSavedExpandedItems removeAllIndexes]; + + // NB: This code is stuffing the address of each job into an index set. While it + // works 99.9% of the time, it's not the ideal solution. We need unique ids in + // each job, possibly using the existing sequence_id field. Could use the high + // word as a unique encode id and the low word the sequence number. + + id anEncode; + NSEnumerator * e = [fEncodes objectEnumerator]; + while ( (anEncode = [e nextObject]) ) + { + if ([fOutlineView isItemExpanded: anEncode]) + [fSavedExpandedItems addIndex: (unsigned int)[[anEncode objectAtIndex:0] job]]; + } + + // Save the selection also. This is really UGLY code. Since I have to rebuild the + // entire outline hierachy every time hblib changes its job list, there's no easy + // way for me to remember the selection state. So here's the strategy. If a *group* + // object is selected, then the first hb_job_t item in the group is saved in + // fSavedSelectedItem. If a job is selected, then its hb_job_t item is saved. To + // distinguish between a group being selected vs an actual job, the high bit of + // fSavedSelectedItem is set when it refers to a job object. I know, not pretty. + // This could go away if I'd save a unique id in each job object. + + int selection = [fOutlineView selectedRow]; + if (selection == -1) + fSavedSelectedItem = 0; + else + { + id obj = [fOutlineView itemAtRow: selection]; + if ([obj isKindOfClass:[HBJob class]]) + fSavedSelectedItem = (unsigned int)[obj job] | 0x80000000; // set high bit! + else + fSavedSelectedItem = (unsigned int)[[obj objectAtIndex:0] job]; + } + +} +#endif + +#if HB_OUTLINE_QUEUE +//------------------------------------------------------------------------------------ +// Restores the expanded state of items in the outline view to match those saved by a +// previous call to saveExpandedItems. +//------------------------------------------------------------------------------------ +- (void) restoreExpandedItems +{ + if (fSavedExpandedItems) + { + id anEncode; + NSEnumerator * e = [fEncodes objectEnumerator]; + while ( (anEncode = [e nextObject]) ) + { + hb_job_t * j = [[anEncode objectAtIndex:0] job]; + if ([fSavedExpandedItems containsIndex: (unsigned int)j]) + [fOutlineView expandItem: anEncode]; + } + } + + if (fSavedSelectedItem) + { + // Ugh. Have to cycle through each row looking for the previously selected job. + // See the explanation in saveExpandedItems about the logic here. + + // Find out if the selection was a job or a group. + BOOL isJob = (fSavedSelectedItem & 0x80000000) == 0x80000000; + // Find out what hb_job_t was selected + hb_job_t * j = (hb_job_t *)(fSavedSelectedItem & ~0x80000000); // strip high bit + + int rowToSelect = -1; + for (int i = 0; i < [fOutlineView numberOfRows]; i++) + { + id obj = [fOutlineView itemAtRow: i]; + if (isJob && [obj isKindOfClass:[HBJob class]]) + { + // For a job in the outline view, test to see if it is a match + if ([obj job] == j) + { + rowToSelect = i; + break; + } + } + else if (!isJob && ![obj isKindOfClass:[HBJob class]]) + { + // For a group, test to see if the group's first job is a match + if ([[obj objectAtIndex:0] job] == j) + { + rowToSelect = i; + break; + } + } + } + if (rowToSelect == -1) + [fOutlineView deselectAll: nil]; + else + [fOutlineView selectRow:rowToSelect byExtendingSelection:NO]; + } } #endif @@ -442,6 +564,7 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo // 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 (fShowsJobsAsGroups && job->pass == -1) { // When job is the one currently being processed, then the next in its group @@ -454,6 +577,7 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo if (nextjob) // Overly cautious in case there is no next job! job = nextjob; } +*/ if (withTitle) { @@ -469,14 +593,22 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo } else { + int numPasses = MIN( 2, job->pass + 1 ); if (fShowsJobsAsGroups) - [aMutableString appendString:[NSString stringWithFormat: - @" (Title %d, %@, %d-Pass)", - title->index, chapterString, MIN( 2, job->pass + 1 )]]; + { + if (numPasses == 1) + [aMutableString appendString:[NSString stringWithFormat: + @" (Title %d, %@, 1 Passes)", + title->index, chapterString]]; + else + [aMutableString appendString:[NSString stringWithFormat: + @" (Title %d, %@, %d Passes)", + title->index, chapterString, numPasses]]; + } else [aMutableString appendString:[NSString stringWithFormat: @" (Title %d, %@, Pass %d of %d)", - title->index, chapterString, MAX( 1, job->pass ), MIN( 2, job->pass + 1 )]]; + title->index, chapterString, MAX( 1, job->pass ), numPasses]]; } } @@ -484,7 +616,12 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo // Normal pass - show detail - if (withDetail && job->pass != -1) + if (withDetail && job->pass == -1) + { + [aMutableString appendString:@"Subtitle Pass"]; + } + + else if (withDetail && job->pass != -1) { NSString * jobFormat; NSString * jobPictureDetail; @@ -494,6 +631,22 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo NSString * jobAudioDetail; NSString * jobAudioCodec; + if ([aMutableString length] != 0) + [aMutableString appendString:@"\n"]; + +// if (job->pass == -1) +// [aMutableString appendString:@"Subtitle Pass"]; +// else + { + int passNum = MAX( 1, job->pass ); + if (passNum == 1) + [aMutableString appendString:@"1st Pass"]; + else if (passNum == 2) + [aMutableString appendString:@"2nd Pass"]; + else + [aMutableString appendString:[NSString stringWithFormat: @"Pass %d", passNum]]; + } + /* 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 @@ -626,7 +779,7 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo jobAudioDetail = [jobAudioDetail stringByAppendingString:[NSString stringWithFormat:@", Track %d: 6-channel discreet",ai + 1]]; } - /* Add the Audio detail string to the job filed in the window */ + /* Add the Audio detail string to the job field in the window */ [aMutableString appendString:[NSString stringWithFormat: @"\n%@", jobAudioDetail]]; /*Destination Field */ @@ -859,12 +1012,15 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo - (void)updateQueueUI { #if HB_OUTLINE_QUEUE + [self saveExpandedItems]; [self rebuildEncodes]; [fOutlineView noteNumberOfRowsChanged]; [fOutlineView reloadData]; -#endif + [self restoreExpandedItems]; +#else [fTaskView noteNumberOfRowsChanged]; [fTaskView reloadData]; +#endif [self updateQueueCountField]; } @@ -893,10 +1049,15 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo hb_rem( fHandle, hb_job( fHandle, row ) ); } #else + #if HB_OUTLINE_QUEUE + hb_job_t * job = [[[fOutlineView itemAtRow: row] objectAtIndex: 0] job]; + hb_rem_group( fHandle, job ); + #else if (fShowsJobsAsGroups) hb_rem_group( fHandle, hb_group( fHandle, row ) ); else hb_rem( fHandle, hb_job( fHandle, row ) ); + #endif #endif [self updateQueueUI]; } @@ -952,19 +1113,18 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo } //------------------------------------------------------------------------------------ -// Toggles the processing of jobs on or off depending on the current state +// Starts or cancels the processing of jobs depending on the current state //------------------------------------------------------------------------------------ -- (IBAction)toggleStartPause: (id)sender +- (IBAction)toggleStartCancel: (id)sender { if (!fHandle) return; hb_state_t s; hb_get_state2 (fHandle, &s); - if (s.state == HB_STATE_PAUSED) - hb_resume (fHandle); - else if ((s.state == HB_STATE_WORKING) || (s.state == HB_STATE_MUXING)) - hb_pause (fHandle); + if ((s.state == HB_STATE_PAUSED) || (s.state == HB_STATE_WORKING) || (s.state == HB_STATE_MUXING)) + [fHBController Cancel: fQueuePane]; // sender == fQueuePane so that warning alert shows up on queue window + else { if (fShowsJobsAsGroups) @@ -977,6 +1137,37 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo } } +//------------------------------------------------------------------------------------ +// Toggles the pause/resume state of hblib +//------------------------------------------------------------------------------------ +- (IBAction)togglePauseResume: (id)sender +{ + if (!fHandle) return; + + hb_state_t s; + hb_get_state2 (fHandle, &s); + + if (s.state == HB_STATE_PAUSED) + hb_resume (fHandle); + else if ((s.state == HB_STATE_WORKING) || (s.state == HB_STATE_MUXING)) + hb_pause (fHandle); +} + +#if HB_OUTLINE_METRIC_CONTROLS +static float spacingWidth = 3.0; +- (IBAction)imageSpacingChanged: (id)sender; +{ + spacingWidth = [sender floatValue]; + [fOutlineView setNeedsDisplay: YES]; +} +- (IBAction)indentChanged: (id)sender +{ + [fOutlineView setIndentationPerLevel: [sender floatValue]]; + [fOutlineView setNeedsDisplay: YES]; +} +#endif + + #pragma mark - #pragma mark Toolbar @@ -1013,13 +1204,13 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo NSToolbarItem *toolbarItem = nil; - if ([itemIdentifier isEqual: HBStartPauseResumeToolbarIdentifier]) + if ([itemIdentifier isEqual: HBQueueStartCancelToolbarIdentifier]) { toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdentifier] autorelease]; // Set the text label to be displayed in the toolbar and customization palette [toolbarItem setLabel: @"Start"]; - [toolbarItem setPaletteLabel: @"Start/Pause"]; + [toolbarItem setPaletteLabel: @"Start/Cancel"]; // Set up a reasonable tooltip, and image [toolbarItem setToolTip: @"Start Encoding"]; @@ -1027,9 +1218,27 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo // Tell the item what message to send when it is clicked [toolbarItem setTarget: self]; - [toolbarItem setAction: @selector(toggleStartPause:)]; + [toolbarItem setAction: @selector(toggleStartCancel:)]; + } + + if ([itemIdentifier isEqual: HBQueuePauseResumeToolbarIdentifier]) + { + toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdentifier] autorelease]; + + // Set the text label to be displayed in the toolbar and customization palette + [toolbarItem setLabel: @"Pause"]; + [toolbarItem setPaletteLabel: @"Pause/Resume"]; + + // Set up a reasonable tooltip, and image + [toolbarItem setToolTip: @"Pause Encoding"]; + [toolbarItem setImage: [NSImage imageNamed: @"Pause"]]; + + // Tell the item what message to send when it is clicked + [toolbarItem setTarget: self]; + [toolbarItem setAction: @selector(togglePauseResume:)]; } +#if !HB_OUTLINE_QUEUE else if ([itemIdentifier isEqual: HBShowDetailToolbarIdentifier]) { toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdentifier] autorelease]; @@ -1134,6 +1343,7 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo [toolbarItem setAction: @selector(jobGroupsChanged:)]; */ } +#endif return toolbarItem; } @@ -1147,10 +1357,13 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo // toolbar by default. return [NSArray arrayWithObjects: - HBStartPauseResumeToolbarIdentifier, + HBQueueStartCancelToolbarIdentifier, + HBQueuePauseResumeToolbarIdentifier, +#if !HB_OUTLINE_QUEUE NSToolbarSeparatorItemIdentifier, HBShowGroupsToolbarIdentifier, HBShowDetailToolbarIdentifier, +#endif nil]; } @@ -1164,9 +1377,12 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo // separator. So, every allowed item must be explicitly listed. return [NSArray arrayWithObjects: - HBStartPauseResumeToolbarIdentifier, + HBQueueStartCancelToolbarIdentifier, + HBQueuePauseResumeToolbarIdentifier, +#if !HB_OUTLINE_QUEUE HBShowGroupsToolbarIdentifier, HBShowDetailToolbarIdentifier, +#endif NSToolbarCustomizeToolbarItemIdentifier, NSToolbarFlexibleSpaceItemIdentifier, NSToolbarSpaceItemIdentifier, @@ -1189,24 +1405,14 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo hb_state_t s; hb_get_state2 (fHandle, &s); - if ([[toolbarItem itemIdentifier] isEqual: HBStartPauseResumeToolbarIdentifier]) + if ([[toolbarItem itemIdentifier] isEqual: HBQueueStartCancelToolbarIdentifier]) { - if (s.state == HB_STATE_PAUSED) - { - enable = YES; - [toolbarItem setImage:[NSImage imageNamed: @"Play"]]; - [toolbarItem setLabel: @"Resume"]; - [toolbarItem setPaletteLabel: @"Resume"]; - [toolbarItem setToolTip: @"Resume Encoding"]; - } - - else if ((s.state == HB_STATE_WORKING) || (s.state == HB_STATE_MUXING)) + if ((s.state == HB_STATE_PAUSED) || (s.state == HB_STATE_WORKING) || (s.state == HB_STATE_MUXING)) { enable = YES; - [toolbarItem setImage:[NSImage imageNamed: @"Pause"]]; - [toolbarItem setLabel: @"Pause"]; - [toolbarItem setPaletteLabel: @"Pause"]; - [toolbarItem setToolTip: @"Pause Encoding"]; + [toolbarItem setImage:[NSImage imageNamed: @"Stop"]]; + [toolbarItem setLabel: @"Stop"]; + [toolbarItem setToolTip: @"Stop Encoding"]; } else if (hb_count(fHandle) > 0) @@ -1214,7 +1420,6 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo enable = YES; [toolbarItem setImage:[NSImage imageNamed: @"Play"]]; [toolbarItem setLabel: @"Start"]; - [toolbarItem setPaletteLabel: @"Start"]; [toolbarItem setToolTip: @"Start Encoding"]; } @@ -1223,11 +1428,37 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo enable = NO; [toolbarItem setImage:[NSImage imageNamed: @"Play"]]; [toolbarItem setLabel: @"Start"]; - [toolbarItem setPaletteLabel: @"Start"]; [toolbarItem setToolTip: @"Start Encoding"]; } } + if ([[toolbarItem itemIdentifier] isEqual: HBQueuePauseResumeToolbarIdentifier]) + { + if (s.state == HB_STATE_PAUSED) + { + enable = YES; + [toolbarItem setImage:[NSImage imageNamed: @"Play"]]; + [toolbarItem setLabel: @"Resume"]; + [toolbarItem setToolTip: @"Resume Encoding"]; + } + + else if ((s.state == HB_STATE_WORKING) || (s.state == HB_STATE_MUXING)) + { + enable = YES; + [toolbarItem setImage:[NSImage imageNamed: @"Pause"]]; + [toolbarItem setLabel: @"Pause"]; + [toolbarItem setToolTip: @"Pause Encoding"]; + } + else + { + enable = NO; + [toolbarItem setImage:[NSImage imageNamed: @"Pause"]]; + [toolbarItem setLabel: @"Pause"]; + [toolbarItem setToolTip: @"Pause Encoding"]; + } + } + +#if !HB_OUTLINE_QUEUE else if ([[toolbarItem itemIdentifier] isEqual: HBShowGroupsToolbarIdentifier]) { enable = hb_count(fHandle) > 0; @@ -1259,6 +1490,7 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo [toolbarItem setToolTip: @"Displays detailed information in the queue"]; } } +#endif return enable; } @@ -1276,21 +1508,38 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo [fQueueWindow center]; [fQueueWindow setFrameAutosaveName: @"Queue"]; [fQueueWindow setExcludedFromWindowsMenu:YES]; - - // Show/hide UI elements - [self setShowsDetail:fShowsDetail]; - [self setShowsJobsAsGroups:fShowsJobsAsGroups]; - [self showCurrentJobPane:NO]; + +#if HB_OUTLINE_QUEUE + [[fOutlineView enclosingScrollView] setHidden: NO]; +#else + [[fTaskView enclosingScrollView] setHidden: NO]; +#endif #if HB_QUEUE_DRAGGING + #if HB_OUTLINE_QUEUE + [fOutlineView registerForDraggedTypes: [NSArray arrayWithObject:HBQueueDataType] ]; + #else [fTaskView registerForDraggedTypes: [NSArray arrayWithObject:HBQueueDataType] ]; + #endif #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]; + [fOutlineView setIndentationPerLevel:21]; +#endif +#if HB_OUTLINE_METRIC_CONTROLS + [fIndentation setHidden: NO]; + [fSpacing setHidden: NO]; + [fIndentation setIntValue:[fOutlineView indentationPerLevel]]; // debug + [fSpacing setIntValue:3]; // debug #endif + + // Show/hide UI elements + [self setShowsDetail:fShowsDetail]; + [self setShowsJobsAsGroups:fShowsJobsAsGroups]; + [self showCurrentJobPane:NO]; } @@ -1450,6 +1699,8 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo } #endif +#pragma mark - +#pragma mark NSOutlineView delegate #if HB_OUTLINE_QUEUE @@ -1476,10 +1727,24 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo - (float)outlineView:(NSOutlineView *)outlineView heightOfRowByItem:(id)item { - if (fShowsDetail && [item isKindOfClass:[HBJob class]]) +/* + if (fShowsDetail && [item isKindOfClass:[HBJob class]] && ([item job]->pass != -1)) return HB_ROW_HEIGHT_DETAIL; else return HB_ROW_HEIGHT_NO_DETAIL; +*/ + + if (fShowsDetail && [item isKindOfClass:[HBJob class]]) + { + hb_job_t * j = [item job]; + NSAssert (j != nil, @"job is nil"); + if (j->pass != -1) + return HB_ROW_HEIGHT_DETAIL; + else + return HB_ROW_HEIGHT_NO_DETAIL; + } + else + return HB_ROW_HEIGHT_NO_DETAIL; } - (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item @@ -1490,7 +1755,8 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo if ([[tableColumn identifier] isEqualToString:@"desc"]) { hb_job_t * job = [item job]; -// return [self attributedDescriptionForJob:job withTitle:NO withDetail:fShowsDetail withHighlighting:highlighted]; + return [self attributedDescriptionForJob:job withTitle:NO withDetail:fShowsDetail withHighlighting:highlighted]; +/* if (job->pass == -1) return @"Subtitle Scan"; else @@ -1500,9 +1766,9 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo return @"1st Pass"; if (passNum == 2) return @"2nd Pass"; - else - return [NSString stringWithFormat: @"Pass %d", passNum]; + return [NSString stringWithFormat: @"Pass %d", passNum]; } +*/ } } @@ -1520,6 +1786,13 @@ static NSString* HBShowGroupsToolbarIdentifier = @"HBShowGroupsTo { if ([[tableColumn identifier] isEqualToString:@"desc"]) { +#if HB_OUTLINE_METRIC_CONTROLS + NSSize theSize = [cell imageSpacing]; + theSize.width = spacingWidth; + [cell setImageSpacing: theSize]; +#endif + + // Set the image here since the value returned from outlineView:objectValueForTableColumn: didn't specify the image part if ([item isKindOfClass:[HBJob class]]) [cell setImage:[self smallImageForPass: [item job]->pass]]; else diff --git a/macosx/HandBrake.xcodeproj/project.pbxproj b/macosx/HandBrake.xcodeproj/project.pbxproj index ad84ce26c..d1c7ee8ce 100644 --- a/macosx/HandBrake.xcodeproj/project.pbxproj +++ b/macosx/HandBrake.xcodeproj/project.pbxproj @@ -161,6 +161,8 @@ 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 */; }; + E37172670C977D340072B384 /* HBImageAndTextCell.m in Sources */ = {isa = PBXBuildFile; fileRef = E37172650C977D340072B384 /* HBImageAndTextCell.m */; }; + E37172680C977D340072B384 /* HBImageAndTextCell.h in Headers */ = {isa = PBXBuildFile; fileRef = E37172660C977D340072B384 /* HBImageAndTextCell.h */; }; 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 */; }; @@ -342,6 +344,8 @@ E37167880C92F6180072B384 /* JobPassSecondLarge.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = JobPassSecondLarge.png; sourceTree = "<group>"; }; E37167A70C92FAA50072B384 /* JobPassUnknownSmall.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = JobPassUnknownSmall.png; sourceTree = "<group>"; }; E37167A80C92FAA50072B384 /* JobPassUnknownLarge.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = JobPassUnknownLarge.png; sourceTree = "<group>"; }; + E37172650C977D340072B384 /* HBImageAndTextCell.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = HBImageAndTextCell.m; sourceTree = "<group>"; }; + E37172660C977D340072B384 /* HBImageAndTextCell.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = HBImageAndTextCell.h; sourceTree = "<group>"; }; E37C893D0C83988F00C1B919 /* DeleteHighlight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = DeleteHighlight.png; sourceTree = "<group>"; }; E37C893E0C83988F00C1B919 /* Delete.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Delete.png; sourceTree = "<group>"; }; E37C893F0C83988F00C1B919 /* JobSmall.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = JobSmall.png; sourceTree = "<group>"; }; @@ -561,6 +565,8 @@ E37C89450C83989F00C1B919 /* HBQueueController.mm */, A9AC41DE0C918DB500DDF9B8 /* HBAdvancedController.h */, A9AC41DD0C918DB500DDF9B8 /* HBAdvancedController.m */, + E37172660C977D340072B384 /* HBImageAndTextCell.h */, + E37172650C977D340072B384 /* HBImageAndTextCell.m */, ); name = "HandBrake Sources"; sourceTree = "<group>"; @@ -651,6 +657,7 @@ 25DE1FB60C169A0C00F01FC8 /* HBPreferencesController.h in Headers */, E37C89480C83989F00C1B919 /* HBQueueController.h in Headers */, A9AC41E00C918DB500DDF9B8 /* HBAdvancedController.h in Headers */, + E37172680C977D340072B384 /* HBImageAndTextCell.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -965,6 +972,7 @@ A2DFC6770C61980700E66E89 /* MVMenuButton.m in Sources */, E37C89470C83989F00C1B919 /* HBQueueController.mm in Sources */, A9AC41DF0C918DB500DDF9B8 /* HBAdvancedController.m in Sources */, + E37172670C977D340072B384 /* HBImageAndTextCell.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; |