OSDN Git Service

MacGui: Use libdvdnav by default.
[handbrake-jp/handbrake-jp-git.git] / macosx / HBQueueController.mm
index bb06ae4..bcc6ada 100644 (file)
@@ -118,21 +118,21 @@ static NSString*    HBQueuePauseResumeToolbarIdentifier       = @"HBQueuePauseRe
 - (void)setQueueArray: (NSMutableArray *)QueueFileArray
 {
     [fJobGroups setArray:QueueFileArray];
+    fIsDragging = NO; 
     /* First stop any timer working now */
-[self stopAnimatingCurrentJobGroupInQueue];
-          [fOutlineView reloadData];
-
-
-
-/* lets get the stats on the status of the queue array */
-
-fEncodingQueueItem = 0;
-fPendingCount = 0;
-fCompletedCount = 0;
-fCanceledCount = 0;
-fWorkingCount = 0;
-
+    [self stopAnimatingCurrentJobGroupInQueue];
+    [fOutlineView reloadData];
+    
+    
+    
+    /* lets get the stats on the status of the queue array */
+    
+    fEncodingQueueItem = 0;
+    fPendingCount = 0;
+    fCompletedCount = 0;
+    fCanceledCount = 0;
+    fWorkingCount = 0;
+    
     /* We use a number system to set the encode status of the queue item
      * in controller.mm
      * 0 == already encoded
@@ -140,11 +140,9 @@ fWorkingCount = 0;
      * 2 == is yet to be encoded
      * 3 == cancelled
      */
-
+    
        int i = 0;
-    NSEnumerator *enumerator = [fJobGroups objectEnumerator];
-       id tempObject;
-       while (tempObject = [enumerator nextObject])
+       for(id tempObject in fJobGroups)
        {
                NSDictionary *thisQueueDict = tempObject;
                if ([[thisQueueDict objectForKey:@"Status"] intValue] == 0) // Completed
@@ -166,16 +164,16 @@ fWorkingCount = 0;
                }
                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 */
+    
+    /* 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)
     {
@@ -186,7 +184,7 @@ if (fWorkingCount > 0)
         string = [NSMutableString stringWithFormat: NSLocalizedString( @"%d encode(s) pending", @"" ), fPendingCount];
     }
     [fQueueCountField setStringValue:string];
-
+    
 }
 /* This method sets the status string in the queue window
  * and is called from Controller.mm (fHBController)
@@ -478,12 +476,14 @@ if (fWorkingCount > 0)
 - (IBAction)removeSelectedQueueItem: (id)sender
 {
     NSIndexSet * selectedRows = [fOutlineView selectedRowIndexes];
-    int row = [selectedRows firstIndex];
+    NSUInteger row = [selectedRows firstIndex];
+    if( row == NSNotFound )
+        return;
     /* if this is a currently encoding job, we need to be sure to alert the user,
      * to let them decide to cancel it first, then if they do, we can come back and
      * remove it */
     
-    if ([[[fJobGroups objectAtIndex:row] objectForKey:@"Status"] intValue] == 1)
+    if ([[[fJobGroups objectAtIndex:row] objectForKey:@"Status"] integerValue] == 1)
     {
        /* We pause the encode here so that it doesn't finish right after and then
         * screw up the sync while the window is open
@@ -491,7 +491,7 @@ if (fWorkingCount > 0)
        [fHBController Pause:NULL];
          NSString * alertTitle = [NSString stringWithFormat:NSLocalizedString(@"Stop This Encode and Remove It ?", nil)];
         // Which window to attach the sheet to?
-        NSWindow * docWindow;
+        NSWindow * docWindow = nil;
         if ([sender respondsToSelector: @selector(window)])
             docWindow = [sender window];
         
@@ -582,14 +582,20 @@ if (fWorkingCount > 0)
 - (IBAction)togglePauseResume: (id)sender
 {
     if (!fQueueEncodeLibhb) return;
-
+    
     hb_state_t s;
     hb_get_state2 (fQueueEncodeLibhb, &s);
-
+    
     if (s.state == HB_STATE_PAUSED)
+    {
         hb_resume (fQueueEncodeLibhb);
+        [self startAnimatingCurrentWorkingEncodeInQueue];
+    }
     else if ((s.state == HB_STATE_WORKING) || (s.state == HB_STATE_MUXING))
+    {
         hb_pause (fQueueEncodeLibhb);
+        [self stopAnimatingCurrentJobGroupInQueue];
+    }
 }
 
 #pragma mark -
@@ -708,16 +714,11 @@ if (fWorkingCount > 0)
     return YES;
 }
 
-- (BOOL)outlineView:(NSOutlineView *)fOutlineView shouldExpandItem:(id)item
+- (BOOL)outlineView:(NSOutlineView *)outlineView shouldExpandItem:(id)item
 {
     // Our outline view has no levels, but we can still expand every item. Doing so
     // just makes the row taller. See heightOfRowByItem below.
-
-    // Don't autoexpand while dragging, since we can't drop into the items
- //   return ![(HBQueueOutlineView*)fOutlineView isDragging];
-
-    return YES; //<-- Needs to be YES to allow expanding
-
+return ![(HBQueueOutlineView*)outlineView isDragging];
 }
 
 - (NSInteger)outlineView:(NSOutlineView *)fOutlineView numberOfChildrenOfItem:(id)item
@@ -748,6 +749,12 @@ if (fWorkingCount > 0)
 {
     if ([outlineView isItemExpanded: item])
     {
+        /* Below is the original code to accommodate a live resize,
+         * however as stated in travistex's comments it's very buggy.
+         * For now I will leave it here ... commented out and use
+         * the code below to determine the row height based on each
+         * encodes optional parameters and how they are displayed. */
+        
         // Short-circuit here if in a live resize primarily to fix a bug but also to
         // increase resposivness during a resize. There's a bug in NSTableView that
         // causes row heights to get messed up if you try to change them during a live
@@ -755,8 +762,8 @@ if (fWorkingCount > 0)
         // height. The row heights will get fixed up after the resize because we have
         // implemented viewDidEndLiveResize to force all of them to be recalculated.
         // if ([outlineView inLiveResize] && [item lastDescriptionHeight] > 0)
-         //   return [item lastDescriptionHeight];
-
+        //   return [item lastDescriptionHeight];
+        
         // CGFloat width = [[outlineView tableColumnWithIdentifier: @"desc"] width];
         // Column width is NOT what is ultimately used. I can't quite figure out what
         // width to use for calculating text metrics. No matter how I tweak this value,
@@ -764,14 +771,114 @@ if (fWorkingCount > 0)
         // of the row cell. In previous versions, which ran under Tiger, I was
         // reducing width by 47 pixles.
         // width -= 2;     // (?) for intercell spacing
-
+        
         // CGFloat height = [item heightOfDescriptionForWidth: width];
         // return height;
         
-        return HB_ROW_HEIGHT_FULL_DESCRIPTION;
+        /* So, we know several rows of text that are in all queue items for display.
+         * These are the title line, Preset, Format, Destination, Picture, and Video Lines
+         */
+        CGFloat rowHeightNonTitle = 15.0;
+        /* Add the title line height, then the non title line height for Preset, Format, Destination
+         * Picture and Video
+         */
+        CGFloat itemHeightForDisplay = HB_ROW_HEIGHT_TITLE_ONLY + (rowHeightNonTitle * 5);
+        
+        /* get our item row number so we an use it to calc how many lines we have to display based
+         * on MP4 Options, Filter Options, X264 Options, Audio Tracks and Subtitles from our queue array */
+        int itemRowNum = [outlineView rowForItem: item];
+        NSMutableDictionary *queueItemToCheck = [outlineView itemAtRow: itemRowNum];
+        
+        /* Check to see if we need to allow for mp4 opts */
+        BOOL mp4OptsPresent = NO;
+        if ([[queueItemToCheck objectForKey:@"FileFormat"] isEqualToString: @"MP4 file"])
+        {
+            
+            if( [[queueItemToCheck objectForKey:@"Mp4LargeFile"] intValue] == 1)
+            {
+                mp4OptsPresent = YES;
+            }
+            if( [[queueItemToCheck objectForKey:@"Mp4HttpOptimize"] intValue] == 1)
+            {
+                mp4OptsPresent = YES;
+            }
+            if( [[queueItemToCheck objectForKey:@"Mp4iPodCompatible"] intValue] == 1)
+            {
+                mp4OptsPresent = YES;
+            }
+        }
+        
+        if (mp4OptsPresent == YES)
+        {
+            itemHeightForDisplay +=  rowHeightNonTitle;   
+        }
+        
+        /* check to see if we need to allow for the Picture Filters row */
+        BOOL pictureFiltersPresent = NO;
+        if( [[queueItemToCheck objectForKey:@"PictureDetelecine"] intValue] > 0)
+        {
+            pictureFiltersPresent = YES;
+        }
+        if( [[queueItemToCheck objectForKey:@"PictureDecomb"] intValue] > 0)
+        {
+            pictureFiltersPresent = YES;
+        }
+        if( [[queueItemToCheck objectForKey:@"PictureDeinterlace"] intValue] > 0)
+        {
+            pictureFiltersPresent = YES;
+        }
+        if( [[queueItemToCheck objectForKey:@"PictureDenoise"] intValue] > 0)
+        {
+            pictureFiltersPresent = YES;
+        }
+        if( [[queueItemToCheck objectForKey:@"PictureDeblock"] intValue] > 0)
+        {
+            pictureFiltersPresent = YES;
+        }
+        if( [[queueItemToCheck objectForKey:@"VideoGrayScale"] intValue] > 0)
+        {
+            pictureFiltersPresent = YES;
+        }
+        
+        if (pictureFiltersPresent == YES)
+        {
+            itemHeightForDisplay +=  rowHeightNonTitle;
+        }
+        
+        /* check to see if we need a line to display x264 options */
+        if ([[queueItemToCheck objectForKey:@"VideoEncoder"] isEqualToString: @"H.264 (x264)"])
+        {
+            itemHeightForDisplay +=  rowHeightNonTitle;
+        }
+        
+        /* check to see how many audio track lines to allow for */
+        if ([[queueItemToCheck objectForKey:@"Audio1Track"] intValue] > 0)
+        {
+            itemHeightForDisplay +=  rowHeightNonTitle; 
+        }
+        if ([[queueItemToCheck objectForKey:@"Audio2Track"] intValue] > 0)
+        {
+            itemHeightForDisplay +=  rowHeightNonTitle; 
+        }
+        if ([[queueItemToCheck objectForKey:@"Audio3Track"] intValue] > 0)
+        {
+            itemHeightForDisplay +=  rowHeightNonTitle; 
+        }
+        if ([[queueItemToCheck objectForKey:@"Audio4Track"] intValue] > 0)
+        {
+            itemHeightForDisplay +=  rowHeightNonTitle; 
+        }
+        
+        /* add in subtitle lines for each subtitle in the SubtitleList array */
+        itemHeightForDisplay +=  rowHeightNonTitle * [[queueItemToCheck objectForKey:@"SubtitleList"] count];
+        
+        return itemHeightForDisplay;
+        
     }
     else
+    {
         return HB_ROW_HEIGHT_TITLE_ONLY;
+    }
 }
 
 - (CGFloat) heightOfDescriptionForWidth:(CGFloat)width
@@ -860,26 +967,34 @@ if (fWorkingCount > 0)
         [NSString stringWithFormat:@"Chapter %d", [[item objectForKey:@"ChapterStart"] intValue]] :
         [NSString stringWithFormat:@"Chapters %d through %d", [[item objectForKey:@"ChapterStart"] intValue], [[item objectForKey:@"ChapterEnd"] intValue]];
         
-        NSString * passesString;
+        NSString * passesString = @"";
+        /* check to see if our first subtitle track is Foreign Language Search, in which case there is an in depth scan */
+        if ([item objectForKey:@"SubtitleList"] && [[[[item objectForKey:@"SubtitleList"] objectAtIndex:0] objectForKey:@"subtitleSourceTrackNum"] intValue] == 1)
+        {
+          passesString = [passesString stringByAppendingString:@"1 Foreign Language Search Pass - "];
+        }
         if ([[item objectForKey:@"VideoTwoPass"] intValue] == 0)
         {
-            passesString = [NSString stringWithFormat:@"1 Video Pass"];
+            passesString = [passesString stringByAppendingString:@"1 Video Pass"];
         }
         else
         {
             if ([[item objectForKey:@"VideoTurboTwoPass"] intValue] == 1)
             {
-                passesString = [NSString stringWithFormat:@"2 Video Passes Turbo"];
+                passesString = [passesString stringByAppendingString:@"2 Video Passes First Turbo"];
             }
             else
             {
-                passesString = [NSString stringWithFormat:@"2 Video Passes"];
+                passesString = [passesString stringByAppendingString:@"2 Video Passes"];
             }
         }
         
         [finalString appendString:[NSString stringWithFormat:@"%@", [item objectForKey:@"SourceName"]] withAttributes:titleAttr];
         
-        summaryInfo = [NSString stringWithFormat: @"  (%@, %@, %@)", titleString, chapterString, passesString];
+        /* lets add the output file name to the title string here */
+        NSString * outputFilenameString = [[item objectForKey:@"DestinationPath"] lastPathComponent];
+        
+        summaryInfo = [NSString stringWithFormat: @" (%@, %@, %@) -> %@", titleString, chapterString, passesString, outputFilenameString];
         
         [finalString appendString:[NSString stringWithFormat:@"%@\n", summaryInfo] withAttributes:detailAttr];  
         
@@ -894,10 +1009,10 @@ if (fWorkingCount > 0)
         /* Third Line  (Format Summary) */
         NSString * audioCodecSummary = @"";
         /* Lets also get our audio track detail since we are going through the logic for use later */
-        NSString * audioDetail1 = @"None";
-        NSString * audioDetail2 = @"None";
-        NSString * audioDetail3 = @"None";
-        NSString * audioDetail4 = @"None";
+        NSString * audioDetail1 = @"";
+        NSString * audioDetail2 = @"";
+        NSString * audioDetail3 = @"";
+        NSString * audioDetail4 = @"";
         if ([[item objectForKey:@"Audio1Track"] intValue] > 0)
         {
             audioCodecSummary = [NSString stringWithFormat:@"%@", [item objectForKey:@"Audio1Encoder"]];
@@ -907,6 +1022,15 @@ if (fWorkingCount > 0)
                             [item objectForKey:@"Audio1Mixdown"] ,
                             [item objectForKey:@"Audio1Samplerate"],
                             [item objectForKey:@"Audio1Bitrate"]];
+            
+            if ([[item objectForKey:@"Audio1TrackDRCSlider"] floatValue] > 1.00)
+            {
+                audioDetail1 = [NSString stringWithFormat:@"%@, DRC: %@",audioDetail1,[item objectForKey:@"Audio1TrackDRCSlider"]];
+            }
+            else
+            {
+                audioDetail1 = [NSString stringWithFormat:@"%@, DRC: Off",audioDetail1];
+            }
         }
         
         if ([[item objectForKey:@"Audio2Track"] intValue] > 0)
@@ -918,6 +1042,15 @@ if (fWorkingCount > 0)
                             [item objectForKey:@"Audio2Mixdown"] ,
                             [item objectForKey:@"Audio2Samplerate"],
                             [item objectForKey:@"Audio2Bitrate"]];
+            
+            if ([[item objectForKey:@"Audio2TrackDRCSlider"] floatValue] > 1.00)
+            {
+                audioDetail2 = [NSString stringWithFormat:@"%@, DRC: %@",audioDetail2,[item objectForKey:@"Audio2TrackDRCSlider"]];
+            }
+            else
+            {
+                audioDetail2 = [NSString stringWithFormat:@"%@, DRC: Off",audioDetail2];
+            }
         }
         
         if ([[item objectForKey:@"Audio3Track"] intValue] > 0)
@@ -929,7 +1062,17 @@ if (fWorkingCount > 0)
                             [item objectForKey:@"Audio3Mixdown"] ,
                             [item objectForKey:@"Audio3Samplerate"],
                             [item objectForKey:@"Audio3Bitrate"]];
+            
+            if ([[item objectForKey:@"Audio3TrackDRCSlider"] floatValue] > 1.00)
+            {
+                audioDetail3 = [NSString stringWithFormat:@"%@, DRC: %@",audioDetail3,[item objectForKey:@"Audio3TrackDRCSlider"]];
+            }
+            else
+            {
+                audioDetail3 = [NSString stringWithFormat:@"%@, DRC: Off",audioDetail3];
+            }
         }
+        
         if ([[item objectForKey:@"Audio4Track"] intValue] > 0)
         {
             audioCodecSummary = [NSString stringWithFormat:@"%@, %@",audioCodecSummary ,[item objectForKey:@"Audio3Encoder"]];
@@ -939,6 +1082,15 @@ if (fWorkingCount > 0)
                             [item objectForKey:@"Audio4Mixdown"] ,
                             [item objectForKey:@"Audio4Samplerate"],
                             [item objectForKey:@"Audio4Bitrate"]];
+            
+            if ([[item objectForKey:@"Audio4TrackDRCSlider"] floatValue] > 1.00)
+            {
+                audioDetail4 = [NSString stringWithFormat:@"%@, DRC: %@",audioDetail4,[item objectForKey:@"Audio4TrackDRCSlider"]];
+            }
+            else
+            {
+                audioDetail4 = [NSString stringWithFormat:@"%@, DRC: Off",audioDetail4];
+            }
         }
         
         NSString * jobFormatInfo;
@@ -959,18 +1111,18 @@ if (fWorkingCount > 0)
             if( [[item objectForKey:@"Mp4LargeFile"] intValue] == 1)
             {
                 mp4OptsPresent = YES;
-                MP4Opts = [MP4Opts stringByAppendingString:@" - 64 Bit"];
+                MP4Opts = [MP4Opts stringByAppendingString:@" - Large file size"];
             }
             if( [[item objectForKey:@"Mp4HttpOptimize"] intValue] == 1)
             {
                 mp4OptsPresent = YES;
-                MP4Opts = [MP4Opts stringByAppendingString:@" - Http Optimized"];
+                MP4Opts = [MP4Opts stringByAppendingString:@" - Web optimized"];
             }
             
             if( [[item objectForKey:@"Mp4iPodCompatible"] intValue] == 1)
             {
                 mp4OptsPresent = YES;
-                MP4Opts = [MP4Opts stringByAppendingString:@" - iPod Atom "];
+                MP4Opts = [MP4Opts stringByAppendingString:@" - iPod 5G support "];
             }
             if (mp4OptsPresent == YES)
             {
@@ -1004,62 +1156,92 @@ if (fWorkingCount > 0)
         
         NSString * pictureFilters = @"";
         BOOL pictureFiltersPresent = NO;
-        if( [[item objectForKey:@"VFR"] intValue] == 1)
-        {
-            pictureFiltersPresent = YES;
-            pictureFilters = [pictureFilters stringByAppendingString:@" - VFR"];
-        }
-        if( [[item objectForKey:@"PictureDetelecine"] intValue] == 1 )
+        
+        if( [[item objectForKey:@"PictureDetelecine"] intValue] == 1)
         {
             pictureFiltersPresent = YES;
-            pictureFilters = [pictureFilters stringByAppendingString:@" - Detelecine"];
+            pictureFilters = [pictureFilters stringByAppendingString:[NSString stringWithFormat:@" - Detelecine (%@)",[item objectForKey:@"PictureDetelecineCustom"]]];
         }
-        
-        if( [[item objectForKey:@"PictureDecomb"] intValue] == 1)
+        else if( [[item objectForKey:@"PictureDetelecine"] intValue] == 2)
         {
             pictureFiltersPresent = YES;
-            pictureFilters = [pictureFilters stringByAppendingString:@" - Decomb "];
+            pictureFilters = [pictureFilters stringByAppendingString:@" - Detelecine (Default)"];
         }
         
-        if ([[item objectForKey:@"PictureDeinterlace"] intValue] != 0)
+        if( [[item objectForKey:@"PictureDecombDeinterlace"] intValue] == 1)
         {
-            pictureFiltersPresent = YES;
-            if ([[item objectForKey:@"PictureDeinterlace"] intValue] == 1)
-            {
-                pictureFilters = [pictureFilters stringByAppendingString:@" - Decomb: Fast "];
-            }
-            else if ([[item objectForKey:@"PictureDeinterlace"] intValue] == 2)
+            if ([[item objectForKey:@"PictureDecomb"] intValue] != 0)
             {
-                pictureFilters = [pictureFilters stringByAppendingString:@" - Decomb: Slow "];           
+                pictureFiltersPresent = YES;
+                if( [[item objectForKey:@"PictureDecomb"] intValue] == 1)
+                {
+                    pictureFiltersPresent = YES;
+                    pictureFilters = [pictureFilters stringByAppendingString:[NSString stringWithFormat:@" - Decomb (%@)",[item objectForKey:@"PictureDecombCustom"]]];
+                }
+                else if( [[item objectForKey:@"PictureDecomb"] intValue] == 2)
+                {
+                    pictureFiltersPresent = YES;
+                    pictureFilters = [pictureFilters stringByAppendingString:@" - Decomb (Default)"];
+                }
             }
-            else if ([[item objectForKey:@"PictureDeinterlace"] intValue] == 3)
+        }
+        else
+        {
+            if ([[item objectForKey:@"PictureDeinterlace"] intValue] != 0)
             {
-                pictureFilters = [pictureFilters stringByAppendingString:@" - Decomb: Slower "];            
+                pictureFiltersPresent = YES;
+                if ([[item objectForKey:@"PictureDeinterlace"] intValue] == 1)
+                {
+                    pictureFilters = [pictureFilters stringByAppendingString:[NSString stringWithFormat:@" - Deinterlace (%@)",[item objectForKey:@"PictureDeinterlaceCustom"]]];            
+                }
+                else if ([[item objectForKey:@"PictureDeinterlace"] intValue] == 2)
+                {
+                    pictureFilters = [pictureFilters stringByAppendingString:@" - Deinterlace (Fast)"];
+                }
+                else if ([[item objectForKey:@"PictureDeinterlace"] intValue] == 3)
+                {
+                    pictureFilters = [pictureFilters stringByAppendingString:@" - Deinterlace (Slow)"];           
+                }
+                else if ([[item objectForKey:@"PictureDeinterlace"] intValue] == 4)
+                {
+                    pictureFilters = [pictureFilters stringByAppendingString:@" - Deinterlace (Slower)"];            
+                }
+                
             }
-            
         }
         if ([[item objectForKey:@"PictureDenoise"] intValue] != 0)
         {
             pictureFiltersPresent = YES;
             if ([[item objectForKey:@"PictureDenoise"] intValue] == 1)
             {
-                pictureFilters = [pictureFilters stringByAppendingString:@" - Denoise: Weak "];
+                pictureFilters = [pictureFilters stringByAppendingString:[NSString stringWithFormat:@" - Denoise (%@)",[item objectForKey:@"PictureDenoiseCustom"]]];            
             }
             else if ([[item objectForKey:@"PictureDenoise"] intValue] == 2)
             {
-                pictureFilters = [pictureFilters stringByAppendingString:@" - Denoise: Medium "];           
+                pictureFilters = [pictureFilters stringByAppendingString:@" - Denoise (Weak)"];
             }
             else if ([[item objectForKey:@"PictureDenoise"] intValue] == 3)
             {
-                pictureFilters = [pictureFilters stringByAppendingString:@" - Denoise: Strong "];            
+                pictureFilters = [pictureFilters stringByAppendingString:@" - Denoise (Medium)"];           
+            }
+            else if ([[item objectForKey:@"PictureDenoise"] intValue] == 4)
+            {
+                pictureFilters = [pictureFilters stringByAppendingString:@" - Denoise (Strong)"];            
             }
             
         }
         if ([[item objectForKey:@"PictureDeblock"] intValue] != 0)
         {
             pictureFiltersPresent = YES;
-            pictureFilters = [pictureFilters stringByAppendingString: [NSString stringWithFormat:@" - Deblock (pp7) (%d) ",[[item objectForKey:@"PictureDeblock"] intValue]]];
+            pictureFilters = [pictureFilters stringByAppendingString: [NSString stringWithFormat:@" - Deblock (pp7) (%d)",[[item objectForKey:@"PictureDeblock"] intValue]]];
+        }
+        
+        if ([[item objectForKey:@"VideoGrayScale"] intValue] == 1)
+        {
+            pictureFiltersPresent = YES;
+            pictureFilters = [pictureFilters stringByAppendingString:@" - Grayscale"];
         }
+        
         if (pictureFiltersPresent == YES)
         {
             [finalString appendString: @"Filters: " withAttributes:detailBoldAttr];
@@ -1070,11 +1252,30 @@ if (fWorkingCount > 0)
         /* Sixth Line Video Details*/
         NSString * videoInfo;
         videoInfo = [NSString stringWithFormat:@"Encoder: %@", [item objectForKey:@"VideoEncoder"]];
-        videoInfo = [NSString stringWithFormat:@"%@ Framerate: %@", videoInfo ,[item objectForKey:@"VideoFramerate"]];
+        
+        /* for framerate look to see if we are using vfr detelecine */
+        if ([[item objectForKey:@"JobIndexVideoFramerate"] intValue] == 0)
+        {
+            if ([[item objectForKey:@"PictureDetelecine"] intValue] == 1)
+            {
+                /* we are using same as source with vfr detelecine */
+                videoInfo = [NSString stringWithFormat:@"%@ Framerate: Same as source (vfr detelecine)", videoInfo];
+            }
+            else
+            {
+                /* we are using a variable framerate without dropping frames */
+                videoInfo = [NSString stringWithFormat:@"%@ Framerate: Same as source (variable)", videoInfo];
+            }
+        }
+        else
+        {
+            /* we have a specified, constant framerate */
+            videoInfo = [NSString stringWithFormat:@"%@ Framerate: %@ (constant framerate)", videoInfo ,[item objectForKey:@"VideoFramerate"]];
+        }
         
         if ([[item objectForKey:@"VideoQualityType"] intValue] == 0)// Target Size MB
         {
-            videoInfo = [NSString stringWithFormat:@"%@ Target Size: %@(MB)", videoInfo ,[item objectForKey:@"VideoTargetSize"]];
+            videoInfo = [NSString stringWithFormat:@"%@ Target Size: %@(MB) (%d(kbps) abr)", videoInfo ,[item objectForKey:@"VideoTargetSize"],[[item objectForKey:@"VideoAvgBitrate"] intValue]];
         }
         else if ([[item objectForKey:@"VideoQualityType"] intValue] == 1) // ABR
         {
@@ -1082,7 +1283,7 @@ if (fWorkingCount > 0)
         }
         else // CRF
         {
-            videoInfo = [NSString stringWithFormat:@"%@ Constant Quality: %.0f %%", videoInfo ,[[item objectForKey:@"VideoQualitySlider"] floatValue] * 100];
+            videoInfo = [NSString stringWithFormat:@"%@ Constant Quality: %.2f", videoInfo ,[[item objectForKey:@"VideoQualitySlider"] floatValue]];
         }
         
         [finalString appendString: @"Video: " withAttributes:detailBoldAttr];
@@ -1097,21 +1298,66 @@ if (fWorkingCount > 0)
         }
         
         
+        
         /* Seventh Line Audio Details*/
-        [finalString appendString: @"Audio Track 1: " withAttributes:detailBoldAttr];
-        [finalString appendString: audioDetail1 withAttributes:detailAttr];
-        [finalString appendString:@"\n" withAttributes:detailAttr];
+        if ([audioDetail1 length] != 0)
+        {
+            [finalString appendString: @"Audio Track 1: " withAttributes:detailBoldAttr];
+            [finalString appendString: audioDetail1 withAttributes:detailAttr];
+            [finalString appendString:@"\n" withAttributes:detailAttr];
+        }
         
-        [finalString appendString: @"Audio Track 2: " withAttributes:detailBoldAttr];
-        [finalString appendString: audioDetail2 withAttributes:detailAttr];
-        [finalString appendString:@"\n" withAttributes:detailAttr];
+        if ([audioDetail2 length] != 0)
+        {
+            [finalString appendString: @"Audio Track 2: " withAttributes:detailBoldAttr];
+            [finalString appendString: audioDetail2 withAttributes:detailAttr];
+            [finalString appendString:@"\n" withAttributes:detailAttr];
+        }
         
-        [finalString appendString: @"Audio Track 3: " withAttributes:detailBoldAttr];
-        [finalString appendString: audioDetail3 withAttributes:detailAttr];
-        [finalString appendString:@"\n" withAttributes:detailAttr];
+        if ([audioDetail3 length] != 0)
+        {
+            [finalString appendString: @"Audio Track 3: " withAttributes:detailBoldAttr];
+            [finalString appendString: audioDetail3 withAttributes:detailAttr];
+            [finalString appendString:@"\n" withAttributes:detailAttr];
+        }
         
-        [finalString appendString: @"Audio Track 4: " withAttributes:detailBoldAttr];
-        [finalString appendString: audioDetail4 withAttributes:detailAttr];
+        if ([audioDetail4 length] != 0)
+        {
+            [finalString appendString: @"Audio Track 4: " withAttributes:detailBoldAttr];
+            [finalString appendString: audioDetail4 withAttributes:detailAttr];
+            [finalString appendString:@"\n" withAttributes:detailAttr];
+        }
+        /* Eighth Line Subtitle Details */
+        
+        int i = 0;
+        NSEnumerator *enumerator = [[item objectForKey:@"SubtitleList"] objectEnumerator];
+        id tempObject;
+        while (tempObject = [enumerator nextObject])
+        {
+            /* since the subtitleSourceTrackNum 0 is "None" in our array of the subtitle popups,
+             * we want to ignore it for display as well as encoding.
+             */
+            if ([[tempObject objectForKey:@"subtitleSourceTrackNum"] intValue] > 0)
+            { 
+                /* remember that index 0 of Subtitles can contain "Foreign Audio Search*/
+                [finalString appendString: @"Subtitle: " withAttributes:detailBoldAttr];
+                [finalString appendString: [tempObject objectForKey:@"subtitleSourceTrackName"] withAttributes:detailAttr];
+                if ([[tempObject objectForKey:@"subtitleTrackForced"] intValue] == 1)
+                {
+                    [finalString appendString: @" - Forced Only" withAttributes:detailAttr];
+                }
+                if ([[tempObject objectForKey:@"subtitleTrackBurned"] intValue] == 1)
+                {
+                    [finalString appendString: @" - Burned In" withAttributes:detailAttr];
+                }
+                if ([[tempObject objectForKey:@"subtitleTrackDefault"] intValue] == 1)
+                {
+                    [finalString appendString: @" - Default" withAttributes:detailAttr];
+                }
+                [finalString appendString:@"\n" withAttributes:detailAttr];
+            }
+            i++;
+        }      
         
         return finalString;
     }
@@ -1203,7 +1449,7 @@ if (fWorkingCount > 0)
 - (BOOL)outlineView:(NSOutlineView *)outlineView writeItems:(NSArray *)items toPasteboard:(NSPasteboard *)pboard
 {
     // Dragging is only allowed of the pending items.
-    if ([[[fJobGroups objectAtIndex:[outlineView selectedRow]] objectForKey:@"Status"] intValue] != 2) // 2 is pending
+    if ([[[items objectAtIndex:0] objectForKey:@"Status"] integerValue] != 2) // 2 is pending
     {
         return NO;
     }
@@ -1228,15 +1474,17 @@ if (fWorkingCount > 0)
     // Don't allow dropping ONTO an item since they can't really contain any children.
     BOOL isOnDropTypeProposal = index == NSOutlineViewDropOnItemIndex;
     if (isOnDropTypeProposal)
+    {
         return NSDragOperationNone;
-
+    }
+    
     // Don't allow dropping INTO an item since they can't really contain any children.
     if (item != nil)
     {
         index = [fOutlineView rowForItem: item] + 1;
         item = nil;
     }
-
+    
     // NOTE: Should we allow dropping a pending job *above* the
     // finished or already encoded jobs ?
     // We do not let the user drop a pending job before or *above*
@@ -1247,60 +1495,24 @@ if (fWorkingCount > 0)
         index = MAX (index, fEncodingQueueItem);
        }
     
-    
     [outlineView setDropItem:item dropChildIndex:index];
     return NSDragOperationGeneric;
 }
 
-
-
 - (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id <NSDraggingInfo>)info item:(id)item childIndex:(NSInteger)index
 {
-        NSMutableIndexSet *moveItems = [NSMutableIndexSet indexSet];
-    
-    id obj;
-    NSEnumerator *enumerator = [fDraggedNodes objectEnumerator];
-    while (obj = [enumerator nextObject])
-    {
+    NSMutableIndexSet *moveItems = [NSMutableIndexSet indexSet];
+
+    for( id obj in fDraggedNodes )
         [moveItems addIndex:[fJobGroups indexOfObject:obj]];
-    }
 
     // Successful drop, we use moveObjectsInQueueArray:... in fHBController
     // to properly rearrange the queue array, save it to plist and then send it back here.
     // since Controller.mm is handling all queue array manipulation.
     // We *could do this here, but I think we are better served keeping that code together.
-    [fHBController moveObjectsInQueueArray:fJobGroups fromIndexes:moveItems toIndex: index];    
+    [fHBController moveObjectsInQueueArray:fJobGroups fromIndexes:moveItems toIndex: index];
     return YES;
 }
-- (void)moveObjectsInQueueArray:(NSMutableArray *)array fromIndexes:(NSIndexSet *)indexSet toIndex:(unsigned)insertIndex
-{
-    unsigned index = [indexSet lastIndex];
-    unsigned aboveInsertIndexCount = 0;
-    
-    while (index != NSNotFound)
-    {
-        unsigned removeIndex;
-        
-        if (index >= insertIndex)
-        {
-            removeIndex = index + aboveInsertIndexCount;
-            aboveInsertIndexCount++;
-        }
-        else
-        {
-            removeIndex = index;
-            insertIndex--;
-        }
-        
-        id object = [[array objectAtIndex:removeIndex] retain];
-        [array removeObjectAtIndex:removeIndex];
-        [array insertObject:object atIndex:insertIndex];
-        [object release];
-        
-        index = [indexSet indexLessThanIndex:index];
-    }
-}
-
 
 
 @end