OSDN Git Service

MacGui: Initial implementation of new queue sync code which allows multi-instance...
authordynaflash <dynaflash@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Sat, 17 Jul 2010 19:15:38 +0000 (19:15 +0000)
committerdynaflash <dynaflash@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Sat, 17 Jul 2010 19:15:38 +0000 (19:15 +0000)
This allows more than one instances of HandBrake.app to run off of the same queue file.
In the case of multi-instance use these changes occur in the queue window:
- The delete icon for a given queue item does not exist in the queue window if another instance is doing the encoding.
- The encoding icon does not spin if another instance is doing the encoding.
- As before if the queue window is for the instance doing the encoding on that item it will be animated and "spins".
- The queue window  status readout now also includes the output file name for the file being encoded for that instance.

Known bugs:
- Drag and Drop queue reordering is somwehat borked. Doesn't corrupt queue but can not allow a drop in some instances.
- I have tested this over 20 multi instance encodes and not once had an issue, but anytime more than one instance is writing to the same external file anything can happen. Beware!
- The session activity log will of course be full of activity log info from all instances in a multi instance scenario. Individual encode logs are unaffected.

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

macosx/Controller.h
macosx/Controller.m
macosx/English.lproj/Queue.xib
macosx/HBQueueController.h
macosx/HBQueueController.mm

index 742aa3a..662563e 100644 (file)
@@ -275,7 +275,8 @@ BOOL                        fIsDragging;
     int                          fWorkingCount;
     
     int                          fqueueEditRescanItemNum; // queue array item to be reloaded into the main window
-    
+    int                          pidNum; // The pid number for this instance
+    NSString                     * currentQueueEncodeNameString;
     
     /* integer to set to determine the previous state
                of encode 0==idle, 1==encoding, 2==cancelled*/
@@ -285,11 +286,12 @@ BOOL                        fIsDragging;
     BOOL                           SuccessfulScan;
     BOOL                           applyQueueToScan;
        NSString                      * currentSource;
-    NSString                     * browsedSourceDisplayName;
+    NSString                      * browsedSourceDisplayName;
     
     double                         dockIconProgress;
 }
 
+- (int) getThisHBInstancePID;
 - (IBAction) showAboutPanel:(id)sender;
 
 - (void) writeToActivityLog:(const char *) format, ...;
@@ -458,6 +460,7 @@ BOOL                        fIsDragging;
 - (void)moveObjectsInPresetsArray:(NSMutableArray *)array fromIndexes:(NSIndexSet *)indexSet toIndex:(NSUInteger)insertIndex;
 
 - (int) hbInstances;
+- (int) getThisHBInstancePID;
 
 // Chapter files methods
 - (IBAction) browseForChapterFile: (id) sender;
index 60e1694..66d7674 100644 (file)
@@ -83,7 +83,12 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
     fPreferencesController = [[HBPreferencesController alloc] init];
     /* Lets report the HandBrake version number here to the activity log and text log file */
     NSString *versionStringFull = [[NSString stringWithFormat: @"Handbrake Version: %@", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]] stringByAppendingString: [NSString stringWithFormat: @" (%@)", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]]];
-    [self writeToActivityLog: "%s", [versionStringFull UTF8String]];    
+    [self writeToActivityLog: "%s", [versionStringFull UTF8String]];
+    
+    /* Get the PID number for this hb instance, used in multi instance encoding */
+    pidNum = [self getThisHBInstancePID];
+    /* Report this pid to the activity log */
+    [self writeToActivityLog: "Pid for this instance:%d", pidNum];
     
     return self;
 }
@@ -122,12 +127,19 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
     [fPresetsOutlineView setAutosaveExpandedItems:YES];
     
     dockIconProgress = 0;
-
+    
+    /* Init QueueFile .plist */
+    [self loadQueueFile];
+    
     /* Call UpdateUI every 1/2 sec */
+    
     [[NSRunLoop currentRunLoop] addTimer:[NSTimer
-                                          scheduledTimerWithTimeInterval:0.5 target:self
-                                          selector:@selector(updateUI:) userInfo:nil repeats:YES]
-                                 forMode:NSDefaultRunLoopMode];
+                                          scheduledTimerWithTimeInterval:0.5 
+                                          target:self
+                                          selector:@selector(updateUI:) 
+                                          userInfo:nil repeats:YES]
+                                          forMode:NSDefaultRunLoopMode];
+                             
 
     // Open debug output window now if it was visible when HB was closed
     if ([[NSUserDefaults standardUserDefaults] boolForKey:@"OutputPanelIsOpen"])
@@ -217,29 +229,42 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
             [self browseSources:(id)fOpenSourceTitleMMenu];
         }
     }
+    currentQueueEncodeNameString = @"";
 }
 
+#pragma mark -
+#pragma mark Multiple Instances
 - (int) hbInstances
 {
     /* check to see if another instance of HandBrake.app is running */
     NSArray *runningAppDictionaries = [[NSWorkspace sharedWorkspace] launchedApplications];
-    NSDictionary *aDictionary;
+    NSDictionary *runningAppsDictionary;
     int hbInstances = 0;
-    for (aDictionary in runningAppDictionaries)
+    for (runningAppsDictionary in runningAppDictionaries)
        {
-        if ([[aDictionary valueForKey:@"NSApplicationName"] isEqualToString:@"HandBrake"])
+        if ([[runningAppsDictionary valueForKey:@"NSApplicationName"] isEqualToString:@"HandBrake"])
                {
             hbInstances++;
                }
        }
     return hbInstances;
 }
+/* Gets the Process Identifer (PID) for this instance and returns it as an integer */
+- (int) getThisHBInstancePID
+{
+    /* Get the PID of this HB instance */
+    int hbInstancePID = [[NSRunningApplication currentApplication] processIdentifier];
+    return hbInstancePID;
+}
+
+#pragma mark -
 
 - (void) didDimissReloadQueue: (NSWindow *)sheet returnCode: (int)returnCode contextInfo: (void *)contextInfo
 {
     if (returnCode == NSAlertOtherReturn)
     {
         [self clearQueueAllItems];
+        
         /* We show whichever open source window specified in LaunchSourceBehavior preference key */
         if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"LaunchSourceBehavior"] isEqualToString: @"Open Source"])
         {
@@ -302,7 +327,7 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
 
 - (void)applicationWillTerminate:(NSNotification *)aNotification
 {
-    
+    [currentQueueEncodeNameString release];
     [browsedSourceDisplayName release];
     [outputPanel release];
        [fQueueController release];
@@ -336,9 +361,6 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
     
     /* Init UserPresets .plist */
        [self loadPresets];
-    
-    /* Init QueueFile .plist */
-    [self loadQueueFile];
        
     fRipIndicatorShown = NO;  // initially out of view in the nib
     
@@ -490,8 +512,6 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
        [self getDefaultPresets:nil];
        /* lets initialize the current successful scancount here to 0 */
        currentSuccessfulScanCount = 0;
-    
-    
 }
 
 - (void) enableUI: (bool) b
@@ -758,10 +778,10 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
                        break;
         }
 #undef p
-
+            
             
 #define p s.param.working
-        
+            
         case HB_STATE_SEARCHING:
                {
             NSMutableString * string;
@@ -808,7 +828,7 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
             break;  
         }
             
-
+            
         case HB_STATE_WORKING:
         {
             NSMutableString * string;
@@ -840,8 +860,12 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
             }
             
             [fStatusField setStringValue: string];
-            /* Set the status string in fQueueController as well */
-            [fQueueController setQueueStatusString: string];
+            /* Set the status string in fQueueController as well but add currentQueueEncodeNameString to delineate
+             * which encode is being worked on by this instance in a multiple instance situation
+             */
+            NSString * queueStatusString = [NSString stringWithFormat:@"%@ -> %@",string,currentQueueEncodeNameString];
+            [fQueueController setQueueStatusString:queueStatusString];
+            
             /* Update slider */
             CGFloat progress_total = ( p.progress + p.job_cur - 1 ) / p.job_count;
             [fRipIndicator setIndeterminate: NO];
@@ -862,14 +886,14 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
                 fRipIndicatorShown = YES;
                 
             }
-
+            
             /* Update dock icon */
             if( dockIconProgress < 100.0 * progress_total )
             {
                 [self UpdateDockIcon: progress_total];
                 dockIconProgress += 5;
             }
-
+            
             break;
         }
 #undef p
@@ -946,7 +970,7 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
                 [self sendToMetaX:pathOfFinishedEncode];
                 
                 /* since we have successfully completed an encode, we increment the queue counter */
-                [self incrementQueueItemDone:nil]; 
+                [self incrementQueueItemDone:currentQueueEncodeIndex]; 
                 
                 /* all end of queue actions below need to be done after all queue encodes have finished 
                  * and there are no pending jobs left to process
@@ -986,16 +1010,23 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
                         returnDescriptor = [scriptObject executeAndReturnError: &errorDict];
                         [scriptObject release];
                     }
-                    
                 }
-                
-                
             }
             
             break;
         }
     }
     
+    /* Since we can use multiple instance off of the same queue file it is imperative that we keep the QueueFileArray updated off of the QueueFile.plist
+     * so we go ahead and do it in this existing timer as opposed to using a new one */
+    
+    NSMutableArray * tempQueueArray = [[NSMutableArray alloc] initWithContentsOfFile:QueueFile];
+    [QueueFileArray setArray:tempQueueArray];
+    [tempQueueArray release]; 
+    /* Send Fresh QueueFileArray to fQueueController to update queue window */
+    [fQueueController setQueueArray: QueueFileArray];
+    [self getQueueStats];
+    
 }
 
 /* We use this to write messages to stderr from the macgui which show up in the activity window and log*/
@@ -1887,53 +1918,38 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
        /*We define the location of the user presets file */
     QueueFile = @"~/Library/Application Support/HandBrake/Queue.plist";
        QueueFile = [[QueueFile stringByExpandingTildeInPath]retain];
-    /* We check for the presets.plist */
+    /* We check for the Queue.plist */
        if ([fileManager fileExistsAtPath:QueueFile] == 0)
        {
                [fileManager createFileAtPath:QueueFile contents:nil attributes:nil];
        }
-
+    
        QueueFileArray = [[NSMutableArray alloc] initWithContentsOfFile:QueueFile];
        /* lets check to see if there is anything in the queue file .plist */
     if (nil == QueueFileArray)
        {
         /* if not, then lets initialize an empty array */
                QueueFileArray = [[NSMutableArray alloc] init];
-        
-     /* Initialize our curQueueEncodeIndex to 0
-     * so we can use it to track which queue
-     * item is to be used to track our encodes */
-     /* NOTE: this should be changed if and when we
-      * are able to get the last unfinished encode
-      * in the case of a crash or shutdown */
-    
-       }
+    }
     else
     {
-    [self clearQueueEncodedItems];
+        /* ONLY clear out encoded items if we are single instance */
+        if ([self hbInstances] == 1)
+        {
+            [self clearQueueEncodedItems];
+        }
     }
-    currentQueueEncodeIndex = 0;
 }
 
 - (void)addQueueFileItem
 {
-        [QueueFileArray addObject:[self createQueueFileItem]];
-        [self saveQueueFileItem];
-
+    [QueueFileArray addObject:[self createQueueFileItem]];
+    [self saveQueueFileItem];
+    
 }
 
 - (void) removeQueueFileItem:(int) queueItemToRemove
 {
-   
-   /* Find out if the item we are removing is a cancelled (3) or a finished (0) item*/
-   if ([[[QueueFileArray objectAtIndex:queueItemToRemove] objectForKey:@"Status"] intValue] == 3 || [[[QueueFileArray objectAtIndex:queueItemToRemove] objectForKey:@"Status"] intValue] == 0)
-    {
-    /* Since we are removing a cancelled or finished item, WE need to decrement the currentQueueEncodeIndex
-     * by one to keep in sync with the queue array
-     */
-    currentQueueEncodeIndex--;
-
-    }
     [QueueFileArray removeObjectAtIndex:queueItemToRemove];
     [self saveQueueFileItem];
 
@@ -1977,7 +1993,13 @@ fWorkingCount = 0;
                if ([[thisQueueDict objectForKey:@"Status"] intValue] == 1) // being encoded
                {
                        fWorkingCount++;
-            fEncodingQueueItem = i;    
+            fEncodingQueueItem = i;
+            /* check to see if we are the instance doing this encoding */
+            if ([thisQueueDict objectForKey:@"EncodingPID"] && [[thisQueueDict objectForKey:@"EncodingPID"] intValue] == pidNum)
+            {
+                currentQueueEncodeIndex = i;
+            }
+               
                }
         if ([[thisQueueDict objectForKey:@"Status"] intValue] == 2) // pending         
         {
@@ -2003,6 +2025,30 @@ fWorkingCount = 0;
     [fQueueStatus setStringValue:string];
 }
 
+/* Used to get the next pending queue item index and return it if found */
+- (int)getNextPendingQueueIndex
+{
+    /* initialize nextPendingIndex to -1, this value tells incrementQueueItemDone that there are no pending items in the queue */
+    int nextPendingIndex = -1;
+       BOOL nextPendingFound = NO;
+    NSEnumerator *enumerator = [QueueFileArray objectEnumerator];
+       id tempObject;
+    int i = 0;
+       while (tempObject = [enumerator nextObject])
+       {
+               NSDictionary *thisQueueDict = tempObject;
+        if ([[thisQueueDict objectForKey:@"Status"] intValue] == 2 && nextPendingFound == NO) // pending               
+        {
+                       nextPendingFound = YES;
+            nextPendingIndex = [QueueFileArray indexOfObject: tempObject];
+            [self writeToActivityLog: "getNextPendingQueueIndex next pending encod index is:%d", nextPendingIndex];
+               }
+        i++;
+       }
+    return nextPendingIndex;
+}
+
+
 /* This method will set any item marked as encoding back to pending
  * currently used right after a queue reload
  */
@@ -2401,8 +2447,8 @@ fWorkingCount = 0;
 
 - (void) incrementQueueItemDone:(int) queueItemDoneIndexNum
 {
-    int i = currentQueueEncodeIndex;
-    [[QueueFileArray objectAtIndex:i] setObject:[NSNumber numberWithInt:0] forKey:@"Status"];
+    /* Mark the encode just finished as done (status 0)*/
+    [[QueueFileArray objectAtIndex:currentQueueEncodeIndex] setObject:[NSNumber numberWithInt:0] forKey:@"Status"];
        
     /* We save all of the Queue data here */
     [self saveQueueFileItem];
@@ -2411,25 +2457,41 @@ fWorkingCount = 0;
      * we can go ahead and increment currentQueueEncodeIndex 
      * so that if there is anything left in the queue we can
      * go ahead and move to the next item if we want to */
-    currentQueueEncodeIndex++ ;
     int queueItems = [QueueFileArray count];
-    /* If we still have more items in our queue, lets go to the next one */
-    if (currentQueueEncodeIndex < queueItems)
-    {
+    /* Check to see if there are any more pending items in the queue */
+    int newQueueItemIndex = [self getNextPendingQueueIndex];
+    /* If we still have more pending items in our queue, lets go to the next one */
+    if (newQueueItemIndex >= 0 && newQueueItemIndex < queueItems)
+    {
+        /*Set our currentQueueEncodeIndex now to the newly found Pending encode as we own it */
+        currentQueueEncodeIndex = newQueueItemIndex;
+        /* now we mark the queue item as Status = 1 ( being encoded ) so another instance can not come along and try to scan it while we are scanning */
+        [[QueueFileArray objectAtIndex:currentQueueEncodeIndex] setObject:[NSNumber numberWithInt:1] forKey:@"Status"];
+        [self writeToActivityLog: "incrementQueueItemDone new pending items found: %d", currentQueueEncodeIndex];
+        [self saveQueueFileItem];
+        /* now we can go ahead and scan the new pending queue item */
         [self performNewQueueScan:[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"SourcePath"] scanTitleNum:[[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"TitleNumber"]intValue]];
+
     }
     else
     {
-        [self writeToActivityLog: "incrementQueueItemDone the %d item queue is complete", currentQueueEncodeIndex - 1];
+        [self writeToActivityLog: "incrementQueueItemDone there are no more pending encodes"];
     }
 }
 
 /* Here we actually tell hb_scan to perform the source scan, using the path to source and title number*/
 - (void) performNewQueueScan:(NSString *) scanPath scanTitleNum: (int) scanTitleNum
 {
-   /* Tell HB to output a new activity log file for this encode */
+    /* Tell HB to output a new activity log file for this encode */
     [outputPanel startEncodeLog:[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"DestinationPath"]];
     
+    /* We now flag the queue item as being owned by this instance of HB using the PID */
+    [[QueueFileArray objectAtIndex:currentQueueEncodeIndex] setObject:[NSNumber numberWithInt:pidNum] forKey:@"EncodingPID"];
+    /* Get the currentQueueEncodeNameString from the queue item to display in the status field */
+    currentQueueEncodeNameString = [[[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"DestinationPath"] lastPathComponent]retain];
+    /* We save all of the Queue data here */
+    [self saveQueueFileItem];
+    
     /* use a bool to determine whether or not we can decrypt using vlc */
     BOOL cancelScanDecrypt = 0;
     /* set the bool so that showNewScan knows to apply the appropriate queue
@@ -3960,7 +4022,7 @@ bool one_burned = FALSE;
 
 
 /* addToQueue: puts up an alert before ultimately calling doAddToQueue
-*/
+ */
 - (IBAction) addToQueue: (id) sender
 {
        /* We get the destination directory from the destination field here */
@@ -4010,7 +4072,7 @@ bool one_burned = FALSE;
     }
     else if (fileExistsInQueue == YES)
     {
-    NSBeginCriticalAlertSheet( NSLocalizedString( @"There is already a queue item for this destination.", @"" ),
+        NSBeginCriticalAlertSheet( NSLocalizedString( @"There is already a queue item for this destination.", @"" ),
                                   NSLocalizedString( @"Cancel", @"" ), NSLocalizedString( @"Overwrite", @"" ), nil, fWindow, self,
                                   @selector( overwriteAddToQueueAlertDone:returnCode:contextInfo: ),
                                   NULL, NULL, [NSString stringWithFormat:
@@ -4062,6 +4124,7 @@ bool one_burned = FALSE;
     // If there are pending jobs in the queue, then this is a rip the queue
     if (fPendingCount > 0)
     {
+        currentQueueEncodeIndex = [self getNextPendingQueueIndex];
         /* here lets start the queue with the first pending item */
         [self performNewQueueScan:[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"SourcePath"] scanTitleNum:[[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"TitleNumber"]intValue]]; 
         
@@ -4099,6 +4162,7 @@ bool one_burned = FALSE;
         }
         
         /* go right to processing the new queue encode */
+        currentQueueEncodeIndex = [self getNextPendingQueueIndex];
         [self performNewQueueScan:[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"SourcePath"] scanTitleNum:[[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"TitleNumber"]intValue]]; 
         
     }
@@ -4236,23 +4300,29 @@ bool one_burned = FALSE;
     // and as always, save it in the queue .plist...
     /* We save all of the Queue data here */
     [self saveQueueFileItem];
-    // so now lets move to 
-    currentQueueEncodeIndex++ ;
+    
     // ... and see if there are more items left in our queue
     int queueItems = [QueueFileArray count];
     /* If we still have more items in our queue, lets go to the next one */
-    if (currentQueueEncodeIndex < queueItems)
-    {
-    [self writeToActivityLog: "doCancelCurrentJob currentQueueEncodeIndex is incremented to: %d", currentQueueEncodeIndex];
-    [self writeToActivityLog: "doCancelCurrentJob moving to the next job"];
-    
-    [self performNewQueueScan:[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"SourcePath"] scanTitleNum:[[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"TitleNumber"]intValue]];
+    /* Check to see if there are any more pending items in the queue */
+    int newQueueItemIndex = [self getNextPendingQueueIndex];
+    /* If we still have more pending items in our queue, lets go to the next one */
+    if (newQueueItemIndex >= 0 && newQueueItemIndex < queueItems)
+    {
+        /*Set our currentQueueEncodeIndex now to the newly found Pending encode as we own it */
+        currentQueueEncodeIndex = newQueueItemIndex;
+        /* now we mark the queue item as Status = 1 ( being encoded ) so another instance can not come along and try to scan it while we are scanning */
+        [[QueueFileArray objectAtIndex:currentQueueEncodeIndex] setObject:[NSNumber numberWithInt:1] forKey:@"Status"];
+        [self writeToActivityLog: "incrementQueueItemDone new pending items found: %d", currentQueueEncodeIndex];
+        [self saveQueueFileItem];
+        /* now we can go ahead and scan the new pending queue item */
+        [self performNewQueueScan:[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"SourcePath"] scanTitleNum:[[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"TitleNumber"]intValue]];
+
     }
     else
     {
-        [self writeToActivityLog: "doCancelCurrentJob the item queue is complete"];
+        [self writeToActivityLog: "incrementQueueItemDone there are no more pending encodes"];
     }
-
 }
 
 - (void) doCancelCurrentJobAndStop
index 4baa538..d834ed5 100644 (file)
@@ -2,17 +2,18 @@
 <archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
        <data>
                <int key="IBDocument.SystemTarget">1050</int>
-               <string key="IBDocument.SystemVersion">10C540</string>
-               <string key="IBDocument.InterfaceBuilderVersion">732</string>
-               <string key="IBDocument.AppKitVersion">1038.25</string>
-               <string key="IBDocument.HIToolboxVersion">458.00</string>
+               <string key="IBDocument.SystemVersion">10F569</string>
+               <string key="IBDocument.InterfaceBuilderVersion">788</string>
+               <string key="IBDocument.AppKitVersion">1038.29</string>
+               <string key="IBDocument.HIToolboxVersion">461.00</string>
                <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
                        <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
-                       <string key="NS.object.0">732</string>
+                       <string key="NS.object.0">788</string>
                </object>
                <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
                        <bool key="EncodedWithXMLCoder">YES</bool>
                        <integer value="2649"/>
+                       <integer value="2577"/>
                </object>
                <object class="NSArray" key="IBDocument.PluginDependencies">
                        <bool key="EncodedWithXMLCoder">YES</bool>
@@ -41,7 +42,7 @@
                        <object class="NSWindowTemplate" id="238545558">
                                <int key="NSWindowStyleMask">4111</int>
                                <int key="NSWindowBacking">2</int>
-                               <string key="NSWindowRect">{{893, 137}, {574, 423}}</string>
+                               <string key="NSWindowRect">{{893, 130}, {594, 430}}</string>
                                <int key="NSWTFlags">1886912512</int>
                                <string key="NSWindowTitle">Queue - HandBrake</string>
                                <string key="NSWindowClass">NSWindow</string>
@@ -51,7 +52,7 @@
                                <string key="NSWindowContentMaxSize">{1.79769e+308, 1.79769e+308}</string>
                                <string key="NSWindowContentMinSize">{525, 340}</string>
                                <object class="NSView" key="NSWindowView" id="431299686">
-                                       <nil key="NSNextResponder"/>
+                                       <reference key="NSNextResponder"/>
                                        <int key="NSvFlags">256</int>
                                        <object class="NSMutableArray" key="NSSubviews">
                                                <bool key="EncodedWithXMLCoder">YES</bool>
                                                                                        </object>
                                                                                        <string key="NSFrame">{{1, 1}, {517, 342}}</string>
                                                                                        <reference key="NSSuperview" ref="9160137"/>
+                                                                                       <reference key="NSNextKeyView" ref="790027174"/>
                                                                                        <reference key="NSDocView" ref="790027174"/>
                                                                                        <object class="NSColor" key="NSBGColor">
                                                                                                <int key="NSColorSpace">6</int>
                                                                        </object>
                                                                        <string key="NSFrame">{{20, 20}, {534, 344}}</string>
                                                                        <reference key="NSSuperview" ref="60629844"/>
+                                                                       <reference key="NSNextKeyView" ref="13598910"/>
                                                                        <int key="NSsFlags">18</int>
                                                                        <reference key="NSVScroller" ref="459639248"/>
                                                                        <reference key="NSHScroller" ref="636348341"/>
                                                                        </object>
                                                                </object>
                                                        </object>
-                                                       <string key="NSFrameSize">{574, 371}</string>
+                                                       <string key="NSFrame">{{0, 7}, {574, 371}}</string>
                                                        <reference key="NSSuperview" ref="431299686"/>
                                                        <string key="NSClassName">NSView</string>
                                                        <string key="NSExtension">NSResponder</string>
                                                <object class="NSTextField" id="463845363">
                                                        <reference key="NSNextResponder" ref="431299686"/>
                                                        <int key="NSvFlags">264</int>
-                                                       <string key="NSFrame">{{17, 398}, {148, 14}}</string>
+                                                       <string key="NSFrame">{{17, 405}, {148, 14}}</string>
                                                        <reference key="NSSuperview" ref="431299686"/>
                                                        <bool key="NSEnabled">YES</bool>
                                                        <object class="NSTextFieldCell" key="NSCell" id="617812287">
                                                </object>
                                                <object class="NSTextField" id="138063786">
                                                        <reference key="NSNextResponder" ref="431299686"/>
-                                                       <int key="NSvFlags">264</int>
-                                                       <string key="NSFrame">{{17, 376}, {540, 14}}</string>
+                                                       <int key="NSvFlags">266</int>
+                                                       <string key="NSFrame">{{17, 383}, {560, 14}}</string>
                                                        <reference key="NSSuperview" ref="431299686"/>
                                                        <bool key="NSEnabled">YES</bool>
                                                        <object class="NSTextFieldCell" key="NSCell" id="108133680">
                                                                <int key="NSCellFlags">67239424</int>
-                                                               <int key="NSCellFlags2">272760832</int>
+                                                               <int key="NSCellFlags2">4325376</int>
                                                                <string key="NSContents">There are no jobs currently encoding</string>
                                                                <reference key="NSSupport" ref="26"/>
                                                                <reference key="NSControlView" ref="138063786"/>
                                                        </object>
                                                </object>
                                        </object>
-                                       <string key="NSFrameSize">{574, 423}</string>
+                                       <string key="NSFrameSize">{594, 430}</string>
+                                       <reference key="NSSuperview"/>
                                </object>
                                <string key="NSScreenRect">{{0, 0}, {1920, 1178}}</string>
                                <string key="NSMinSize">{525, 362}</string>
                                        <integer value="1"/>
                                        <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
                                        <integer value="1"/>
-                                       <string>{{-1207, 366}, {574, 423}}</string>
+                                       <string>{{-1207, 359}, {594, 430}}</string>
                                        <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
-                                       <string>{{-1207, 366}, {574, 423}}</string>
+                                       <string>{{-1207, 359}, {594, 430}}</string>
                                        <integer value="1"/>
                                        <boolean value="NO"/>
                                        <integer value="1"/>
                                                        <string>id</string>
                                                </object>
                                        </object>
+                                       <object class="NSMutableDictionary" key="actionInfosByName">
+                                               <bool key="EncodedWithXMLCoder">YES</bool>
+                                               <object class="NSArray" key="dict.sortedKeys">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <string>editSelectedQueueItem:</string>
+                                                       <string>imageSpacingChanged:</string>
+                                                       <string>indentChanged:</string>
+                                                       <string>removeSelectedQueueItem:</string>
+                                                       <string>revealSelectedQueueItem:</string>
+                                                       <string>showQueueWindow:</string>
+                                               </object>
+                                               <object class="NSMutableArray" key="dict.values">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <object class="IBActionInfo">
+                                                               <string key="name">editSelectedQueueItem:</string>
+                                                               <string key="candidateClassName">id</string>
+                                                       </object>
+                                                       <object class="IBActionInfo">
+                                                               <string key="name">imageSpacingChanged:</string>
+                                                               <string key="candidateClassName">id</string>
+                                                       </object>
+                                                       <object class="IBActionInfo">
+                                                               <string key="name">indentChanged:</string>
+                                                               <string key="candidateClassName">id</string>
+                                                       </object>
+                                                       <object class="IBActionInfo">
+                                                               <string key="name">removeSelectedQueueItem:</string>
+                                                               <string key="candidateClassName">id</string>
+                                                       </object>
+                                                       <object class="IBActionInfo">
+                                                               <string key="name">revealSelectedQueueItem:</string>
+                                                               <string key="candidateClassName">id</string>
+                                                       </object>
+                                                       <object class="IBActionInfo">
+                                                               <string key="name">showQueueWindow:</string>
+                                                               <string key="candidateClassName">id</string>
+                                                       </object>
+                                               </object>
+                                       </object>
                                        <object class="NSMutableDictionary" key="outlets">
                                                <bool key="EncodedWithXMLCoder">YES</bool>
                                                <object class="NSArray" key="dict.sortedKeys">
                                                        <string>NSSlider</string>
                                                </object>
                                        </object>
+                                       <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+                                               <bool key="EncodedWithXMLCoder">YES</bool>
+                                               <object class="NSArray" key="dict.sortedKeys">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <string>fCurrentJobPane</string>
+                                                       <string>fIndentation</string>
+                                                       <string>fJobDescTextField</string>
+                                                       <string>fJobIconView</string>
+                                                       <string>fOutlineView</string>
+                                                       <string>fProgressBar</string>
+                                                       <string>fProgressTextField</string>
+                                                       <string>fQueueCountField</string>
+                                                       <string>fQueuePane</string>
+                                                       <string>fSpacing</string>
+                                               </object>
+                                               <object class="NSMutableArray" key="dict.values">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">fCurrentJobPane</string>
+                                                               <string key="candidateClassName">NSView</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">fIndentation</string>
+                                                               <string key="candidateClassName">NSSlider</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">fJobDescTextField</string>
+                                                               <string key="candidateClassName">NSTextField</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">fJobIconView</string>
+                                                               <string key="candidateClassName">NSImageView</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">fOutlineView</string>
+                                                               <string key="candidateClassName">HBQueueOutlineView</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">fProgressBar</string>
+                                                               <string key="candidateClassName">NSProgressIndicator</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">fProgressTextField</string>
+                                                               <string key="candidateClassName">NSTextField</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">fQueueCountField</string>
+                                                               <string key="candidateClassName">NSTextField</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">fQueuePane</string>
+                                                               <string key="candidateClassName">NSView</string>
+                                                       </object>
+                                                       <object class="IBToOneOutletInfo">
+                                                               <string key="name">fSpacing</string>
+                                                               <string key="candidateClassName">NSSlider</string>
+                                                       </object>
+                                               </object>
+                                       </object>
                                        <object class="IBClassDescriptionSource" key="sourceIdentifier" id="333889241">
                                                <string key="majorKey">IBProjectSource</string>
                                                <string key="minorKey">HBQueueController.h</string>
                                                        <string>id</string>
                                                </object>
                                        </object>
+                                       <object class="NSMutableDictionary" key="actionInfosByName">
+                                               <bool key="EncodedWithXMLCoder">YES</bool>
+                                               <object class="NSArray" key="dict.sortedKeys">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <string>cancelCurrentJob:</string>
+                                                       <string>revealSelectedJobGroups:</string>
+                                                       <string>togglePauseResume:</string>
+                                                       <string>toggleStartCancel:</string>
+                                               </object>
+                                               <object class="NSMutableArray" key="dict.values">
+                                                       <bool key="EncodedWithXMLCoder">YES</bool>
+                                                       <object class="IBActionInfo">
+                                                               <string key="name">cancelCurrentJob:</string>
+                                                               <string key="candidateClassName">id</string>
+                                                       </object>
+                                                       <object class="IBActionInfo">
+                                                               <string key="name">revealSelectedJobGroups:</string>
+                                                               <string key="candidateClassName">id</string>
+                                                       </object>
+                                                       <object class="IBActionInfo">
+                                                               <string key="name">togglePauseResume:</string>
+                                                               <string key="candidateClassName">id</string>
+                                                       </object>
+                                                       <object class="IBActionInfo">
+                                                               <string key="name">toggleStartCancel:</string>
+                                                               <string key="candidateClassName">id</string>
+                                                       </object>
+                                               </object>
+                                       </object>
                                        <object class="IBClassDescriptionSource" key="sourceIdentifier">
                                                <string key="majorKey">IBUserSource</string>
                                                <string key="minorKey"/>
                                                <string key="NS.key.0">showWindow:</string>
                                                <string key="NS.object.0">id</string>
                                        </object>
+                                       <object class="NSMutableDictionary" key="actionInfosByName">
+                                               <string key="NS.key.0">showWindow:</string>
+                                               <object class="IBActionInfo" key="NS.object.0">
+                                                       <string key="name">showWindow:</string>
+                                                       <string key="candidateClassName">id</string>
+                                               </object>
+                                       </object>
                                        <object class="IBClassDescriptionSource" key="sourceIdentifier">
                                                <string key="majorKey">IBFrameworkSource</string>
                                                <string key="minorKey">AppKit.framework/Headers/NSWindowController.h</string>
                        </object>
                </object>
                <int key="IBDocument.localizationMode">0</int>
+               <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
                <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
                        <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
                        <integer value="1050" key="NS.object.0"/>
                <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
                <string key="IBDocument.LastKnownRelativeProjectPath">../HandBrake.xcodeproj</string>
                <int key="IBDocument.defaultPropertyAccessControl">3</int>
+               <object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
+                       <bool key="EncodedWithXMLCoder">YES</bool>
+                       <object class="NSArray" key="dict.sortedKeys">
+                               <bool key="EncodedWithXMLCoder">YES</bool>
+                               <string>Delete</string>
+                               <string>NSMenuCheckmark</string>
+                               <string>NSMenuMixedState</string>
+                       </object>
+                       <object class="NSMutableArray" key="dict.values">
+                               <bool key="EncodedWithXMLCoder">YES</bool>
+                               <string>{16, 16}</string>
+                               <string>{9, 8}</string>
+                               <string>{7, 2}</string>
+                       </object>
+               </object>
        </data>
 </archive>
index ddae3e6..8f1268e 100644 (file)
@@ -53,8 +53,9 @@ BOOL                        fIsDragging;
     hb_handle_t                  *fQueueEncodeLibhb;              // reference to libhb
     HBController                 *fHBController;        // reference to HBController
     NSMutableArray               *fJobGroups;           // mirror image of the queue array from controller.mm
-
-    int                          fEncodingQueueItem;     // corresponds to the index of fJobGroups encoding item
+    
+    int                          pidNum;                // Records the PID number from HBController for this instance
+    int                          fEncodingQueueItem;    // corresponds to the index of fJobGroups encoding item
     int                          fPendingCount;         // Number of various kinds of job groups in fJobGroups.
     int                          fCompletedCount;
     int                          fCanceledCount;
@@ -106,7 +107,6 @@ BOOL                        fIsDragging;
 #endif
 
 }
-
 - (void)setHandle: (hb_handle_t *)handle;
 - (void)setHBController: (HBController *)controller;
 
index 856f10f..451d96e 100644 (file)
@@ -109,7 +109,8 @@ static NSString*    HBQueuePauseResumeToolbarIdentifier       = @"HBQueuePauseRe
             nil]];
 
         fJobGroups = [[NSMutableArray arrayWithCapacity:0] retain];
-       } 
+       }
+
         return self;
 }
 
@@ -118,14 +119,13 @@ static NSString*    HBQueuePauseResumeToolbarIdentifier       = @"HBQueuePauseRe
     [fJobGroups setArray:QueueFileArray];
     fIsDragging = NO; 
     /* First stop any timer working now */
-    [self stopAnimatingCurrentJobGroupInQueue];
+    //[self stopAnimatingCurrentJobGroupInQueue];
     [fOutlineView reloadData];
     
     
     
     /* lets get the stats on the status of the queue array */
     
-    fEncodingQueueItem = 0;
     fPendingCount = 0;
     fCompletedCount = 0;
     fCanceledCount = 0;
@@ -138,11 +138,11 @@ static NSString*    HBQueuePauseResumeToolbarIdentifier       = @"HBQueuePauseRe
      * 2 == is yet to be encoded
      * 3 == cancelled
      */
-    
        int i = 0;
+    NSDictionary *thisQueueDict = nil;
        for(id tempObject in fJobGroups)
        {
-               NSDictionary *thisQueueDict = tempObject;
+               thisQueueDict = tempObject;
                if ([[thisQueueDict objectForKey:@"Status"] intValue] == 0) // Completed
                {
                        fCompletedCount++;      
@@ -150,7 +150,11 @@ static NSString*    HBQueuePauseResumeToolbarIdentifier       = @"HBQueuePauseRe
                if ([[thisQueueDict objectForKey:@"Status"] intValue] == 1) // being encoded
                {
                        fWorkingCount++;
-            fEncodingQueueItem = i;    
+            /* we have an encoding job so, lets start the animation timer */
+            if ([thisQueueDict objectForKey:@"EncodingPID"] && [[thisQueueDict objectForKey:@"EncodingPID"] intValue] == pidNum)
+            {
+                fEncodingQueueItem = i;
+            }
                }
         if ([[thisQueueDict objectForKey:@"Status"] intValue] == 2) // pending         
         {
@@ -163,14 +167,6 @@ static NSString*    HBQueuePauseResumeToolbarIdentifier       = @"HBQueuePauseRe
                i++;
        }
     
-    /* We should fire up the encoding timer here based on fWorkingCount */
-    
-    if (fWorkingCount > 0)
-    {
-        /* we have an encoding job so, lets start the animation timer */
-        [self startAnimatingCurrentWorkingEncodeInQueue];
-    }
-    
     /* Set the queue status field in the queue window */
     NSMutableString * string;
     if (fPendingCount == 1)
@@ -184,6 +180,7 @@ static NSString*    HBQueuePauseResumeToolbarIdentifier       = @"HBQueuePauseRe
     [fQueueCountField setStringValue:string];
     
 }
+
 /* This method sets the status string in the queue window
  * and is called from Controller.mm (fHBController)
  * instead of running another timer here polling libhb
@@ -191,7 +188,9 @@ static NSString*    HBQueuePauseResumeToolbarIdentifier       = @"HBQueuePauseRe
  */
 - (void)setQueueStatusString: (NSString *)statusString
 {
-[fProgressTextField setStringValue:statusString];
+    
+    [fProgressTextField setStringValue:statusString];
+    
 }
 
 //------------------------------------------------------------------------------------
@@ -227,6 +226,9 @@ static NSString*    HBQueuePauseResumeToolbarIdentifier       = @"HBQueuePauseRe
 - (void)setHBController: (HBController *)controller
 {
     fHBController = controller;
+    /* Now get this pidnum from HBController */
+    pidNum = [fHBController getThisHBInstancePID];
+    [fHBController writeToActivityLog: "HBQueueController : My Pidnum is %d", pidNum];
 }
 
 #pragma mark -
@@ -238,6 +240,7 @@ static NSString*    HBQueuePauseResumeToolbarIdentifier       = @"HBQueuePauseRe
 {
     [self showWindow:sender];
     [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"QueueWindowIsOpen"];
+    [self startAnimatingCurrentWorkingEncodeInQueue];
 }
 
 
@@ -252,7 +255,6 @@ static NSString*    HBQueuePauseResumeToolbarIdentifier       = @"HBQueuePauseRe
     if( ![[self window] setFrameUsingName:@"Queue"] )
         [[self window] center];
     [self setWindowFrameAutosaveName:@"Queue"];
-    //[[self window] setExcludedFromWindowsMenu:YES];
 
     /* lets setup our queue list outline view for drag and drop here */
     [fOutlineView registerForDraggedTypes: [NSArray arrayWithObject:DragDropSimplePboardType] ];
@@ -273,9 +275,7 @@ static NSString*    HBQueuePauseResumeToolbarIdentifier       = @"HBQueuePauseRe
 
     // Show/hide UI elements
     fCurrentJobPaneShown = NO;     // it's shown in the nib
-    //[self showCurrentJobPane:NO];
 
-    //[self updateQueueCountField];
 }
 
 
@@ -285,6 +285,7 @@ static NSString*    HBQueuePauseResumeToolbarIdentifier       = @"HBQueuePauseRe
 - (void)windowWillClose:(NSNotification *)aNotification
 {
     [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"QueueWindowIsOpen"];
+    [self stopAnimatingCurrentJobGroupInQueue];
 }
 
 #pragma mark Toolbar
@@ -507,7 +508,7 @@ static NSString*    HBQueuePauseResumeToolbarIdentifier       = @"HBQueuePauseRe
     }
     else
     { 
-    /* since we are not a currently encoding item, we can just be cancelled */
+    /* since we are not a currently encoding item, we can just be removed */
             [fHBController removeQueueFileItem:row];
     }
 }
@@ -520,19 +521,19 @@ static NSString*    HBQueuePauseResumeToolbarIdentifier       = @"HBQueuePauseRe
      * In this case, we are paused from the calling window, so calling
      * [fHBController Pause:NULL]; Again will resume encoding
      */
-       [fHBController Pause:NULL];
+    [fHBController Pause:NULL];
     if (returnCode == NSAlertOtherReturn)
     {
-    /* We need to save the currently encoding item number first */
-    int encodingItemToRemove = fEncodingQueueItem;
-    /* Since we are encoding, we need to let fHBController Cancel this job
-     * upon which it will move to the next one if there is one
-     */
-    [fHBController doCancelCurrentJob];
-    /* Now, we can go ahead and remove the job we just cancelled since
-     * we have its item number from above
-     */
-    [fHBController removeQueueFileItem:encodingItemToRemove];
+        /* We need to save the currently encoding item number first */
+        int encodingItemToRemove = fEncodingQueueItem;
+        /* Since we are encoding, we need to let fHBController Cancel this job
+         * upon which it will move to the next one if there is one
+         */
+        [fHBController doCancelCurrentJob];
+        /* Now, we can go ahead and remove the job we just cancelled since
+         * we have its item number from above
+         */
+        [fHBController removeQueueFileItem:encodingItemToRemove];
     }
     
 }
@@ -676,7 +677,7 @@ static NSString*    HBQueuePauseResumeToolbarIdentifier       = @"HBQueuePauseRe
     }
 }
 
-
+/* We need to make sure we denote only working encodes even for multiple instances */
 - (void) animateWorkingEncodeIconInQueue
 {
     NSInteger row = fEncodingQueueItem; /// need to set to fEncodingQueueItem
@@ -959,9 +960,6 @@ return ![(HBQueueOutlineView*)outlineView isDragging];
 
 - (id)outlineView:(NSOutlineView *)fOutlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
 {
-    // nb: The "desc" column is currently an HBImageAndTextCell. However, we are longer
-    // using the image portion of the cell so we could switch back to a regular NSTextFieldCell.
-    
     if ([[tableColumn identifier] isEqualToString:@"desc"])
     {
         
@@ -996,7 +994,6 @@ return ![(HBQueueOutlineView*)outlineView isDragging];
                                          nil];
         
         /* First line, we should strip the destination path and just show the file name and add the title num and chapters (if any) */
-        //finalDescription = [finalDescription stringByAppendingString:[NSString stringWithFormat:@"Source: %@ Output: %@\n", [item objectForKey:@"SourceName"],[item objectForKey:@"DestinationPath"]]];
         NSString * summaryInfo;
         
         NSString * titleString = [NSString stringWithFormat:@"Title %d", [[item objectForKey:@"TitleNumber"] intValue]];
@@ -1448,7 +1445,7 @@ return ![(HBQueueOutlineView*)outlineView isDragging];
         return @"";
     }
 }
-
+/* This method inserts the proper action icons into the far right of the queue window */
 - (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
 {
     if ([[tableColumn identifier] isEqualToString:@"desc"])
@@ -1465,7 +1462,8 @@ return ![(HBQueueOutlineView*)outlineView isDragging];
     {
         [cell setEnabled: YES];
         BOOL highlighted = [outlineView isRowSelected:[outlineView rowForItem: item]] && [[outlineView window] isKeyWindow] && ([[outlineView window] firstResponder] == outlineView);
-        if ([[item objectForKey:@"Status"] intValue] == 0)
+        
+        if ([[item objectForKey:@"Status"] intValue] == 0 || ([[item objectForKey:@"Status"] intValue] == 1 && [[item objectForKey:@"EncodingPID"] intValue] != pidNum))
         {
             [cell setAction: @selector(revealSelectedQueueItem:)];
             if (highlighted)
@@ -1478,21 +1476,23 @@ return ![(HBQueueOutlineView*)outlineView isDragging];
         }
         else
         {
-            [cell setAction: @selector(removeSelectedQueueItem:)];
-            if (highlighted)
-            {
-                [cell setImage:[NSImage imageNamed:@"DeleteHighlight"]];
-                [cell setAlternateImage:[NSImage imageNamed:@"DeleteHighlightPressed"]];
-            }
-            else
-                [cell setImage:[NSImage imageNamed:@"Delete"]];
+            
+                [cell setAction: @selector(removeSelectedQueueItem:)];
+                if (highlighted)
+                {
+                    [cell setImage:[NSImage imageNamed:@"DeleteHighlight"]];
+                    [cell setAlternateImage:[NSImage imageNamed:@"DeleteHighlightPressed"]];
+                }
+                else
+                    [cell setImage:[NSImage imageNamed:@"Delete"]];
+   
         }
     }
 }
 
 - (void)outlineView:(NSOutlineView *)outlineView willDisplayOutlineCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
 {
-    // By default, the discolsure image gets centered vertically in the cell. We want
+    // By default, the disclosure image gets centered vertically in the cell. We want
     // always at the top.
     if ([outlineView isItemExpanded: item])
         [cell setImagePosition: NSImageAbove];