OSDN Git Service

MacGui: New Queue Enhancements courtesy of travistex
authordynaflash <dynaflash@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Fri, 14 Sep 2007 04:42:46 +0000 (04:42 +0000)
committerdynaflash <dynaflash@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Fri, 14 Sep 2007 04:42:46 +0000 (04:42 +0000)
- New hierarchical queue view.
- New Start/Cancel and Pause/Resume buttons in Queue toolbar to match those in the main window.
- When canceling a job, you now have the option to delete all pending jobs.
- This one is the real deal!

git-svn-id: svn://localhost/HandBrake/trunk@963 b64f7644-9d1e-0410-96f1-a4d463321fa5

Jamfile
macosx/Controller.mm
macosx/English.lproj/Queue.nib/classes.nib
macosx/English.lproj/Queue.nib/info.nib
macosx/English.lproj/Queue.nib/keyedobjects.nib
macosx/HBImageAndTextCell.h [new file with mode: 0644]
macosx/HBImageAndTextCell.m [new file with mode: 0644]
macosx/HBQueueController.h
macosx/HBQueueController.mm
macosx/HandBrake.xcodeproj/project.pbxproj

diff --git a/Jamfile b/Jamfile
index 86a6990..410b9e6 100644 (file)
--- a/Jamfile
+++ b/Jamfile
@@ -61,6 +61,7 @@ if $(OS) = MACOSX
               macosx/PictureGLView.h macosx/PictureGLView.mm
               macosx/HBQueueController.h macosx/HBQueueController.mm
                          macosx/HBAdvancedController.h macosx/HBAdvancedController.m
+              macosx/HBImageAndTextCell.h macosx/HBImageAndTextCell.m
               macosx/HBPreferencesController.h macosx/HBPreferencesController.m
               macosx/English.lproj/InfoPlist.strings
               macosx/English.lproj/MainMenu.nib/classes.nib
index 253e0ee..d92619a 100644 (file)
@@ -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];
+    }
 }
 
 
index 3e0a529..8976f9e 100644 (file)
             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; 
                 fQueueCountField = NSTextField; 
                 fQueuePane = NSView; 
                 fQueueWindow = NSWindow; 
+                fSpacing = NSSlider; 
                 fTaskView = NSTableView; 
             }; 
             SUPERCLASS = NSObject; 
index 0d9cf8e..9db2ce5 100644 (file)
@@ -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>
index b43b41b..504ed1b 100644 (file)
Binary files a/macosx/English.lproj/Queue.nib/keyedobjects.nib and b/macosx/English.lproj/Queue.nib/keyedobjects.nib differ
diff --git a/macosx/HBImageAndTextCell.h b/macosx/HBImageAndTextCell.h
new file mode 100644 (file)
index 0000000..1da12cf
--- /dev/null
@@ -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 (file)
index 0000000..7052c35
--- /dev/null
@@ -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
+
index 4743925..1d5dd58 100644 (file)
@@ -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----------------+
     
     // 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
     
 }
 
 - (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
index 755692a..09c73ec 100644 (file)
@@ -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
index ad84ce2..d1c7ee8 100644 (file)
                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 */; };
                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>"; };
                                E37C89450C83989F00C1B919 /* HBQueueController.mm */,
                                A9AC41DE0C918DB500DDF9B8 /* HBAdvancedController.h */,
                                A9AC41DD0C918DB500DDF9B8 /* HBAdvancedController.m */,
+                               E37172660C977D340072B384 /* HBImageAndTextCell.h */,
+                               E37172650C977D340072B384 /* HBImageAndTextCell.m */,
                        );
                        name = "HandBrake Sources";
                        sourceTree = "<group>";
                                25DE1FB60C169A0C00F01FC8 /* HBPreferencesController.h in Headers */,
                                E37C89480C83989F00C1B919 /* HBQueueController.h in Headers */,
                                A9AC41E00C918DB500DDF9B8 /* HBAdvancedController.h in Headers */,
+                               E37172680C977D340072B384 /* HBImageAndTextCell.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                A2DFC6770C61980700E66E89 /* MVMenuButton.m in Sources */,
                                E37C89470C83989F00C1B919 /* HBQueueController.mm in Sources */,
                                A9AC41DF0C918DB500DDF9B8 /* HBAdvancedController.m in Sources */,
+                               E37172670C977D340072B384 /* HBImageAndTextCell.m in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };