-
- if (fSavedSelectedItem)
- {
- // Ugh. Have to cycle through each row looking for the previously selected job.
- // See the explanation in saveExpandedItems about the logic here.
-
- // Find out if the selection was a job or a group.
- BOOL isJob = (fSavedSelectedItem & 0x80000000) == 0x80000000;
- // Find out what hb_job_t was selected
- hb_job_t * j = (hb_job_t *)(fSavedSelectedItem & ~0x80000000); // strip high bit
-
- int rowToSelect = -1;
- for (int i = 0; i < [fOutlineView numberOfRows]; i++)
- {
- id obj = [fOutlineView itemAtRow: i];
- if (isJob && [obj isKindOfClass:[HBJob class]])
- {
- // For a job in the outline view, test to see if it is a match
- if ([obj job] == j)
- {
- rowToSelect = i;
- break;
- }
- }
- else if (!isJob && ![obj isKindOfClass:[HBJob class]])
- {
- // For a group, test to see if the group's first job is a match
- if ([[obj objectAtIndex:0] job] == j)
- {
- rowToSelect = i;
- break;
- }
- }
- }
- if (rowToSelect == -1)
- [fOutlineView deselectAll: nil];
- else
- [fOutlineView selectRow:rowToSelect byExtendingSelection:NO];
- }
-}
-#endif
-
-//------------------------------------------------------------------------------------
-// Generates a multi-line text string that includes the job name on the first line
-// followed by details of the job on subsequent lines. If the text is to be drawn as
-// part of a highlighted cell, set isHighlighted to true. The returned string may
-// contain multiple fonts and paragraph formating.
-//------------------------------------------------------------------------------------
-- (NSAttributedString *)attributedDescriptionForJob: (hb_job_t *)job
- withTitle: (BOOL)withTitle
- withDetail: (BOOL)withDetail
- withHighlighting: (BOOL)highlighted
-{
- NSMutableAttributedString * finalString; // the return value
- NSAttributedString* anAttributedString; // a temp string for building up attributed substrings
- NSMutableString* aMutableString; // a temp string for non-attributed substrings
- hb_title_t * title = job->title;
-
- NSMutableParagraphStyle *ps = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
- [ps setLineBreakMode:NSLineBreakByClipping];
-
- static NSDictionary* detailAttribute = [[NSDictionary dictionaryWithObjectsAndKeys:
- [NSFont systemFontOfSize:11.0], NSFontAttributeName,
- [NSColor darkGrayColor], NSForegroundColorAttributeName,
- ps, NSParagraphStyleAttributeName,
- nil] retain];
- static NSDictionary* detailHighlightedAttribute = [[NSDictionary dictionaryWithObjectsAndKeys:
- [NSFont systemFontOfSize:11.0], NSFontAttributeName,
- [NSColor whiteColor], NSForegroundColorAttributeName,
- ps, NSParagraphStyleAttributeName,
- nil] retain];
- static NSDictionary* titleAttribute = [[NSDictionary dictionaryWithObjectsAndKeys:
- [NSFont systemFontOfSize:[NSFont systemFontSize]], NSFontAttributeName,
- ps, NSParagraphStyleAttributeName,
- nil] retain];
-
- finalString = [[[NSMutableAttributedString alloc] init] autorelease];
-
- // Title, in bold
- // Show the name of the source Note: use title->name instead of title->dvd since
- // name is just the chosen folder, instead of dvd which is the full path
- if (withTitle)
- {
- anAttributedString = [[[NSAttributedString alloc] initWithString:[NSString stringWithUTF8String:title->name] attributes:titleAttribute] autorelease];
- [finalString appendAttributedString:anAttributedString];
- }
-
- // Other info in plain
-
- aMutableString = [NSMutableString stringWithCapacity:200];
-
- // The subtitle scan doesn't contain all the stuff we need (like x264opts).
- // So grab the next job in the group for display purposes.
-/*
- if (fShowsJobsAsGroups && job->pass == -1)
- {
- // When job is the one currently being processed, then the next in its group
- // is the the first job in the queue.
- hb_job_t * nextjob;
- if (job == hb_current_job(fHandle))
- nextjob = hb_job(fHandle, 0);
- else
- nextjob = hb_next_job(fHandle, job);
- if (nextjob) // Overly cautious in case there is no next job!
- job = nextjob;
- }
-*/
-
- if (withTitle)
- {
- NSString * chapterString = (job->chapter_start == job->chapter_end) ?
- [NSString stringWithFormat:@"Chapter %d", job->chapter_start] :
- [NSString stringWithFormat:@"Chapters %d through %d", job->chapter_start, job->chapter_end];
-
- // Scan pass
- if (job->pass == -1)
- {
- [aMutableString appendString:[NSString stringWithFormat:
- @" (Title %d, %@, In-depth Scan)", title->index, chapterString]];
- }
- else
- {
- int numPasses = MIN( 2, job->pass + 1 );
- if (fShowsJobsAsGroups)
- {
- if (numPasses == 1)
- [aMutableString appendString:[NSString stringWithFormat:
- @" (Title %d, %@, 1 Passes)",
- title->index, chapterString]];
- else
- [aMutableString appendString:[NSString stringWithFormat:
- @" (Title %d, %@, %d Passes)",
- title->index, chapterString, numPasses]];
- }
- else
- [aMutableString appendString:[NSString stringWithFormat:
- @" (Title %d, %@, Pass %d of %d)",
- title->index, chapterString, MAX( 1, job->pass ), numPasses]];
- }
- }
-
- // End of title stuff
-
-
- // Normal pass - show detail
- if (withDetail && job->pass == -1)
- {
- [aMutableString appendString:@"Subtitle Pass"];
- }
-
- else if (withDetail && job->pass != -1)
- {
- NSString * jobFormat;
- NSString * jobPictureDetail;
- NSString * jobVideoDetail;
- NSString * jobVideoCodec;
- NSString * jobVideoQuality;
- NSString * jobAudioDetail;
- NSString * jobAudioCodec;
-
- if ([aMutableString length] != 0)
- [aMutableString appendString:@"\n"];
-
-// if (job->pass == -1)
-// [aMutableString appendString:@"Subtitle Pass"];
-// else
- {
- int passNum = MAX( 1, job->pass );
- if (passNum == 1)
- [aMutableString appendString:@"1st Pass"];
- else if (passNum == 2)
- [aMutableString appendString:@"2nd Pass"];
- else
- [aMutableString appendString:[NSString stringWithFormat: @"Pass %d", passNum]];
- }
-
- /* Muxer settings (File Format in the gui) */
- if (job->mux == 65536 || job->mux == 131072 || job->mux == 1048576)
- jobFormat = @"MP4"; // HB_MUX_MP4,HB_MUX_PSP,HB_MUX_IPOD
- else if (job->mux == 262144)
- jobFormat = @"AVI"; // HB_MUX_AVI
- else if (job->mux == 524288)
- jobFormat = @"OGM"; // HB_MUX_OGM
- else if (job->mux == 2097152)
- jobFormat = @"MKV"; // HB_MUX_MKV
- else
- jobFormat = @"unknown";
-
- // 2097152
- /* Video Codec settings (Encoder in the gui) */
- if (job->vcodec == 1)
- jobVideoCodec = @"FFmpeg"; // HB_VCODEC_FFMPEG
- else if (job->vcodec == 2)
- jobVideoCodec = @"XviD"; // HB_VCODEC_XVID
- else if (job->vcodec == 4)
- {
- /* Deterimine for sure how we are now setting iPod uuid atom */
- if (job->h264_level) // We are encoding for iPod
- jobVideoCodec = @"x264 (H.264 iPod)"; // HB_VCODEC_X264
- else
- jobVideoCodec = @"x264 (H.264 Main)"; // HB_VCODEC_X264
- }
- else
- jobVideoCodec = @"unknown";
-
- /* Audio Codecs (Second half of Codecs in the gui) */
- if (job->acodec == 256)
- jobAudioCodec = @"AAC"; // HB_ACODEC_FAAC
- else if (job->acodec == 512)
- jobAudioCodec = @"MP3"; // HB_ACODEC_LAME
- else if (job->acodec == 1024)
- jobAudioCodec = @"Vorbis"; // HB_ACODEC_VORBIS
- else if (job->acodec == 2048)
- jobAudioCodec = @"AC3"; // HB_ACODEC_AC3
- else
- jobAudioCodec = @"unknown";
- /* Show Basic File info */
- if (job->chapter_markers == 1)
- [aMutableString appendString:[NSString stringWithFormat:@"\nFormat: %@ Container, %@ Video + %@ Audio, Chapter Markers", jobFormat, jobVideoCodec, jobAudioCodec]];
- else
- [aMutableString appendString:[NSString stringWithFormat:@"\nFormat: %@ Container, %@ Video + %@ Audio", jobFormat, jobVideoCodec, jobAudioCodec]];
-
- /*Picture info*/
- /*integers for picture values deinterlace, crop[4], keep_ratio, grayscale, pixel_ratio, pixel_aspect_width, pixel_aspect_height,
- maxWidth, maxHeight */
- if (job->pixel_ratio == 1)
- {
- int titlewidth = title->width - job->crop[2] - job->crop[3];
- int displayparwidth = titlewidth * job->pixel_aspect_width / job->pixel_aspect_height;
- int displayparheight = title->height - job->crop[0] - job->crop[1];
- jobPictureDetail = [NSString stringWithFormat:@"Picture: %dx%d (%dx%d Anamorphic)", displayparwidth, displayparheight, job->width, displayparheight];
- }
- else
- jobPictureDetail = [NSString stringWithFormat:@"Picture: %dx%d", job->width, job->height];
- if (job->keep_ratio == 1)
- jobPictureDetail = [jobPictureDetail stringByAppendingString:@" Keep Aspect Ratio"];
-
- if (job->grayscale == 1)
- jobPictureDetail = [jobPictureDetail stringByAppendingString:@", Grayscale"];
-
- if (job->deinterlace == 1)
- jobPictureDetail = [jobPictureDetail stringByAppendingString:@", Deinterlace"];
- /* Show Picture info */
- [aMutableString appendString:[NSString stringWithFormat:@"\n%@", jobPictureDetail]];
-
- /* Detailed Video info */
- if (job->vquality <= 0 || job->vquality >= 1)
- jobVideoQuality =[NSString stringWithFormat:@"%d kbps", job->vbitrate];
- else
- {
- NSNumber * vidQuality;
- vidQuality = [NSNumber numberWithInt:job->vquality * 100];
- /* this is screwed up kind of. Needs to be formatted properly */
- if (job->crf == 1)
- jobVideoQuality =[NSString stringWithFormat:@"%@%% CRF", vidQuality];
- else
- jobVideoQuality =[NSString stringWithFormat:@"%@%% CQP", vidQuality];
- }
-
- if (job->vrate_base == 1126125)
- {
- /* NTSC FILM 23.976 */
- jobVideoDetail = [NSString stringWithFormat:@"Video: %@, %@, 23.976 fps", jobVideoCodec, jobVideoQuality];
- }
- else if (job->vrate_base == 900900)
- {
- /* NTSC 29.97 */
- jobVideoDetail = [NSString stringWithFormat:@"Video: %@, %@, 29.97 fps", jobVideoCodec, jobVideoQuality];
- }
- else
- {
- /* Everything else */
- jobVideoDetail = [NSString stringWithFormat:@"Video: %@, %@, %d fps", jobVideoCodec, jobVideoQuality, job->vrate / job->vrate_base];
- }
-
- /* Add the video detail string to the job filed in the window */
- [aMutableString appendString:[NSString stringWithFormat:@"\n%@", jobVideoDetail]];
-
- /* if there is an x264 option string, lets add it here*/
- /*NOTE: Due to size, lets get this in a tool tip*/
-
- if (job->x264opts)
- [aMutableString appendString:[NSString stringWithFormat:@"\nx264 Options: %@", [NSString stringWithUTF8String:job->x264opts]]];
-
- /* Audio Detail */
- if ([jobAudioCodec isEqualToString: @"AC3"])
- jobAudioDetail = [NSString stringWithFormat:@"Audio: %@, Pass-Through", jobAudioCodec];
- else
- jobAudioDetail = [NSString stringWithFormat:@"Audio: %@, %d kbps, %d Hz", jobAudioCodec, job->abitrate, job->arate];
-
- /* we now get the audio mixdown info for each of the two gui audio tracks */
- /* lets do it the long way here to get a handle on things.
- Hardcoded for two tracks for gui: audio_mixdowns[i] audio_mixdowns[i] */
- int ai; // counter for each audios [] , macgui only allows for two audio tracks currently
- for( ai = 0; ai < 2; ai++ )
- {
- if (job->audio_mixdowns[ai] == HB_AMIXDOWN_MONO)
- jobAudioDetail = [jobAudioDetail stringByAppendingString:[NSString stringWithFormat:@", Track %d: Mono",ai + 1]];
- if (job->audio_mixdowns[ai] == HB_AMIXDOWN_STEREO)
- jobAudioDetail = [jobAudioDetail stringByAppendingString:[NSString stringWithFormat:@", Track %d: Stereo",ai + 1]];
- if (job->audio_mixdowns[ai] == HB_AMIXDOWN_DOLBY)
- jobAudioDetail = [jobAudioDetail stringByAppendingString:[NSString stringWithFormat:@", Track %d: Dolby Surround",ai + 1]];
- if (job->audio_mixdowns[ai] == HB_AMIXDOWN_DOLBYPLII)
- jobAudioDetail = [jobAudioDetail stringByAppendingString:[NSString stringWithFormat:@", Track %d: Dolby Pro Logic II",ai + 1]];
- if (job->audio_mixdowns[ai] == HB_AMIXDOWN_6CH)
- jobAudioDetail = [jobAudioDetail stringByAppendingString:[NSString stringWithFormat:@", Track %d: 6-channel discreet",ai + 1]];
- }
-
- /* Add the Audio detail string to the job field in the window */
- [aMutableString appendString:[NSString stringWithFormat: @"\n%@", jobAudioDetail]];
-
- /*Destination Field */
- [aMutableString appendString:[NSString stringWithFormat:@"\nDestination: %@", [NSString stringWithUTF8String:job->file]]];
- }
-
- anAttributedString = [[[NSAttributedString alloc] initWithString:aMutableString attributes:highlighted ? detailHighlightedAttribute : detailAttribute] autorelease];
- [finalString appendAttributedString:anAttributedString];
-
-
- return finalString;
-}
-
-
-
-- (NSAttributedString *)attributedDescriptionForJob: (hb_job_t *)job
- withTitle: (BOOL)withTitle
- withPassName: (BOOL)withPassName
- withFormatInfo: (BOOL)withFormatInfo
- withDestination: (BOOL)withDestination
- withPictureInfo: (BOOL)withPictureInfo
- withVideoInfo: (BOOL)withVideoInfo
- withx264Info: (BOOL)withx264Info
- withAudioInfo: (BOOL)withAudioInfo
- withHighlighting: (BOOL)highlighted
-{
- NSMutableArray * stringParts = [NSMutableArray arrayWithCapacity:0];
-
- hb_title_t * title = job->title;
-
- // Attributes
- static NSMutableParagraphStyle *ps = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] retain];
- [ps setLineBreakMode:NSLineBreakByClipping];
-
- static NSDictionary* detailAttribute = [[NSDictionary dictionaryWithObjectsAndKeys:
- [NSFont systemFontOfSize:10.0], NSFontAttributeName,
- [NSColor darkGrayColor], NSForegroundColorAttributeName,
- ps, NSParagraphStyleAttributeName,
- nil] retain];
- static NSDictionary* detailHighlightedAttribute = [[NSDictionary dictionaryWithObjectsAndKeys:
- [NSFont systemFontOfSize:10.0], NSFontAttributeName,
- [NSColor whiteColor], NSForegroundColorAttributeName,
- ps, NSParagraphStyleAttributeName,
- nil] retain];
- static NSDictionary* titleAttribute = [[NSDictionary dictionaryWithObjectsAndKeys:
- [NSFont systemFontOfSize:[NSFont systemFontSize]], NSFontAttributeName,
- ps, NSParagraphStyleAttributeName,
- nil] retain];
-
-
- // Title with summary
- NSString * titleString;
- if (withTitle)
- {
- // Note: use title->name instead of title->dvd since name is just the chosen
- // folder, instead of dvd which is the full path
- titleString = [NSString stringWithUTF8String:title->name];
-
- NSString * summaryInfo;
-
- NSString * chapterString = (job->chapter_start == job->chapter_end) ?
- [NSString stringWithFormat:@"Chapter %d", job->chapter_start] :
- [NSString stringWithFormat:@"Chapters %d through %d", job->chapter_start, job->chapter_end];
-
- BOOL hasIndepthScan = (job->pass == -1);
- int numVideoPasses = 0;
-
- // To determine number of video passes, we need to skip past the in-depth scan.
- if (fShowsJobsAsGroups && hasIndepthScan)
- {
- // When job is the one currently being processed, then the next in its group
- // is the the first job in the queue.
- hb_job_t * nextjob;
- if (job == hb_current_job(fHandle))
- nextjob = hb_job(fHandle, 0);
- else
- nextjob = hb_next_job(fHandle, job);
- if (nextjob) // Overly cautious in case there is no next job!
- numVideoPasses = MIN( 2, nextjob->pass + 1 );
- }
- else
- numVideoPasses = MIN( 2, job->pass + 1 );
-
- if (hasIndepthScan && numVideoPasses == 1)
- summaryInfo = [NSString stringWithFormat: @" (Title %d, %@, In-depth Scan, Single Video Pass)", title->index, chapterString];
- else if (hasIndepthScan && numVideoPasses > 1)
- summaryInfo = [NSString stringWithFormat: @" (Title %d, %@, In-depth Scan, %d Video Passes)", title->index, chapterString, numVideoPasses];
- else if (numVideoPasses == 1)
- summaryInfo = [NSString stringWithFormat: @" (Title %d, %@, Single Video Pass)", title->index, chapterString];
- else
- summaryInfo = [NSString stringWithFormat: @" (Title %d, %@, %d Video Passes)", title->index, chapterString, numVideoPasses];
-
- [stringParts addObject: [NSString stringWithFormat:@"%@%@", titleString, summaryInfo]];
- }
-
- // End of title stuff
-
-
- // Pass Name
- if (withPassName)
- {
- NSString * jobPassName;
- if (job->pass == -1)
- jobPassName = NSLocalizedString (@"In-depth Scan", nil);
- else
- {
- int passNum = MAX( 1, job->pass );
- if (passNum == 0)
- jobPassName = NSLocalizedString (@"Encode Pass", nil);
- else if (passNum == 1)
- jobPassName = NSLocalizedString (@"1st Pass", nil);
- else if (passNum == 2)
- jobPassName = NSLocalizedString (@"2nd Pass", nil);
- else
- jobPassName = [NSString stringWithFormat: NSLocalizedString(@"Pass %d", nil), passNum];
- }
- [stringParts addObject: jobPassName];
- }
-
- // Video Codec needed by FormatInfo and withVideoInfo
- NSString * jobVideoCodec;
- if (withFormatInfo || withVideoInfo)
- {
- // 2097152
- /* Video Codec settings (Encoder in the gui) */
- if (job->vcodec == 1)
- jobVideoCodec = @"FFmpeg"; // HB_VCODEC_FFMPEG
- else if (job->vcodec == 2)
- jobVideoCodec = @"XviD"; // HB_VCODEC_XVID
- else if (job->vcodec == 4)
- {
- /* Deterimine for sure how we are now setting iPod uuid atom */
- if (job->h264_level) // We are encoding for iPod
- jobVideoCodec = @"x264 (H.264 iPod)"; // HB_VCODEC_X264
- else
- jobVideoCodec = @"x264 (H.264 Main)"; // HB_VCODEC_X264
- }
- else
- jobVideoCodec = @"unknown";
- }
-
- // Audio Codec needed by FormatInfo and AudioInfo
- NSString * jobAudioCodec;
- if (withFormatInfo || withAudioInfo)
- {
- if (job->acodec == 256)
- jobAudioCodec = @"AAC"; // HB_ACODEC_FAAC
- else if (job->acodec == 512)
- jobAudioCodec = @"MP3"; // HB_ACODEC_LAME
- else if (job->acodec == 1024)
- jobAudioCodec = @"Vorbis"; // HB_ACODEC_VORBIS
- else if (job->acodec == 2048)
- jobAudioCodec = @"AC3"; // HB_ACODEC_AC3
- else
- jobAudioCodec = @"unknown";
- }
-
-
- if (withFormatInfo)
- {
- NSString * jobFormatInfo;
- // Muxer settings (File Format in the gui)
- if (job->mux == 65536 || job->mux == 131072 || job->mux == 1048576)
- jobFormatInfo = @"MP4"; // HB_MUX_MP4,HB_MUX_PSP,HB_MUX_IPOD
- else if (job->mux == 262144)
- jobFormatInfo = @"AVI"; // HB_MUX_AVI
- else if (job->mux == 524288)
- jobFormatInfo = @"OGM"; // HB_MUX_OGM
- else if (job->mux == 2097152)
- jobFormatInfo = @"MKV"; // HB_MUX_MKV
- else
- jobFormatInfo = @"unknown";
-
- if (job->chapter_markers == 1)
- jobFormatInfo = [NSString stringWithFormat:@"Format: %@ Container, %@ Video + %@ Audio, Chapter Markers", jobFormatInfo, jobVideoCodec, jobAudioCodec];
- else
- jobFormatInfo = [NSString stringWithFormat:@"Format: %@ Container, %@ Video + %@ Audio", jobFormatInfo, jobVideoCodec, jobAudioCodec];
-
- [stringParts addObject: jobFormatInfo];
- }
-
- if (withDestination)
- {
- NSString * jobDestinationInfo = [NSString stringWithFormat:@"Destination: %@", [NSString stringWithUTF8String:job->file]];
- [stringParts addObject: jobDestinationInfo];
- }
-
-
- if (withPictureInfo)
- {
- NSString * jobPictureInfo;
- /*integers for picture values deinterlace, crop[4], keep_ratio, grayscale, pixel_ratio, pixel_aspect_width, pixel_aspect_height,
- maxWidth, maxHeight */
- if (job->pixel_ratio == 1)
- {
- int titlewidth = title->width - job->crop[2] - job->crop[3];
- int displayparwidth = titlewidth * job->pixel_aspect_width / job->pixel_aspect_height;
- int displayparheight = title->height - job->crop[0] - job->crop[1];
- jobPictureInfo = [NSString stringWithFormat:@"Picture: %dx%d (%dx%d Anamorphic)", displayparwidth, displayparheight, job->width, displayparheight];
- }
- else
- jobPictureInfo = [NSString stringWithFormat:@"Picture: %dx%d", job->width, job->height];
- if (job->keep_ratio == 1)
- jobPictureInfo = [jobPictureInfo stringByAppendingString:@" Keep Aspect Ratio"];
-
- if (job->grayscale == 1)
- jobPictureInfo = [jobPictureInfo stringByAppendingString:@", Grayscale"];
-
- if (job->deinterlace == 1)
- jobPictureInfo = [jobPictureInfo stringByAppendingString:@", Deinterlace"];
- [stringParts addObject: jobPictureInfo];
- }
-
- if (withVideoInfo)
- {
- NSString * jobVideoQuality;
- NSString * jobVideoDetail;
-
- if (job->vquality <= 0 || job->vquality >= 1)
- jobVideoQuality = [NSString stringWithFormat:@"%d kbps", job->vbitrate];
- else
- {
- NSNumber * vidQuality;
- vidQuality = [NSNumber numberWithInt:job->vquality * 100];
- // this is screwed up kind of. Needs to be formatted properly.
- if (job->crf == 1)
- jobVideoQuality = [NSString stringWithFormat:@"%@%% CRF", vidQuality];
- else
- jobVideoQuality = [NSString stringWithFormat:@"%@%% CQP", vidQuality];
- }
-
- if (job->vrate_base == 1126125)
- {
- /* NTSC FILM 23.976 */
- jobVideoDetail = [NSString stringWithFormat:@"Video: %@, %@, 23.976 fps", jobVideoCodec, jobVideoQuality];
- }
- else if (job->vrate_base == 900900)
- {
- /* NTSC 29.97 */
- jobVideoDetail = [NSString stringWithFormat:@"Video: %@, %@, 29.97 fps", jobVideoCodec, jobVideoQuality];
- }
- else
- {
- /* Everything else */
- jobVideoDetail = [NSString stringWithFormat:@"Video: %@, %@, %d fps", jobVideoCodec, jobVideoQuality, job->vrate / job->vrate_base];
- }
- [stringParts addObject: jobVideoDetail];
- }
-
- if (withx264Info)
- {
- NSString * jobx264Info;
- if (job->x264opts)
- {
- jobx264Info = [NSString stringWithFormat:@"x264 Options: %@", [NSString stringWithUTF8String:job->x264opts]];
- [stringParts addObject: jobx264Info];
- }
- }
-
- if (withAudioInfo)
- {
- NSString * jobAudioInfo;
- if ([jobAudioCodec isEqualToString: @"AC3"])
- jobAudioInfo = [NSString stringWithFormat:@"Audio: %@, Pass-Through", jobAudioCodec];
- else
- jobAudioInfo = [NSString stringWithFormat:@"Audio: %@, %d kbps, %d Hz", jobAudioCodec, job->abitrate, job->arate];
-
- /* we now get the audio mixdown info for each of the two gui audio tracks */
- /* lets do it the long way here to get a handle on things.
- Hardcoded for two tracks for gui: audio_mixdowns[i] audio_mixdowns[i] */
- int ai; // counter for each audios [] , macgui only allows for two audio tracks currently
- for( ai = 0; ai < 2; ai++ )
- {
- if (job->audio_mixdowns[ai] == HB_AMIXDOWN_MONO)
- jobAudioInfo = [jobAudioInfo stringByAppendingString:[NSString stringWithFormat:@", Track %d: Mono", ai + 1]];
- if (job->audio_mixdowns[ai] == HB_AMIXDOWN_STEREO)
- jobAudioInfo = [jobAudioInfo stringByAppendingString:[NSString stringWithFormat:@", Track %d: Stereo", ai + 1]];
- if (job->audio_mixdowns[ai] == HB_AMIXDOWN_DOLBY)
- jobAudioInfo = [jobAudioInfo stringByAppendingString:[NSString stringWithFormat:@", Track %d: Dolby Surround", ai + 1]];
- if (job->audio_mixdowns[ai] == HB_AMIXDOWN_DOLBYPLII)
- jobAudioInfo = [jobAudioInfo stringByAppendingString:[NSString stringWithFormat:@", Track %d: Dolby Pro Logic II", ai + 1]];
- if (job->audio_mixdowns[ai] == HB_AMIXDOWN_6CH)
- jobAudioInfo = [jobAudioInfo stringByAppendingString:[NSString stringWithFormat:@", Track %d: 6-channel discreet", ai + 1]];
- }
- [stringParts addObject: jobAudioInfo];
- }
-
-
- NSMutableAttributedString * anAttributedString = [[[NSMutableAttributedString alloc]
- initWithString:[stringParts componentsJoinedByString:@"\n"]
- attributes:highlighted ? detailHighlightedAttribute : detailAttribute] autorelease];
-
- if (withTitle)
- [anAttributedString setAttributes: titleAttribute range: NSMakeRange(0, [titleString length])];
-
- return anAttributedString;
-}
-
-//------------------------------------------------------------------------------------
-// Generate string to display in UI.
-//------------------------------------------------------------------------------------
-- (NSString *) progressStatusStringForJob: (hb_job_t *)job state: (hb_state_t *)s
-{
- if (s->state == HB_STATE_WORKING)
- {
- NSString * msg;
- if (job->pass == -1)
- msg = NSLocalizedString( @"Analyzing subtitles", nil );
- else if (job->pass == 1)
- msg = NSLocalizedString( @"Analyzing video", nil );
- else if ((job->pass == 0) || (job->pass == 2))
- msg = NSLocalizedString( @"Encoding movie", nil );
- else
- return @""; // unknown condition!
-
- if( s->param.working.seconds > -1 )
- {
- return [NSString stringWithFormat:
- NSLocalizedString( @"%@ (%.2f fps, avg %.2f fps)", nil ),
- msg, s->param.working.rate_cur, s->param.working.rate_avg];
- }
- else
- return msg;
-
- }
-
- else if (s->state == HB_STATE_MUXING)
- return NSLocalizedString( @"Muxing", nil );
-
- else if (s->state == HB_STATE_PAUSED)
- return NSLocalizedString( @"Paused", nil );
-
- else if (s->state == HB_STATE_WORKDONE)
- return NSLocalizedString( @"Done", nil );
-
- return @"";
-}
-
-//------------------------------------------------------------------------------------
-// Generate string to display in UI.
-//------------------------------------------------------------------------------------
-- (NSString *) progressTimeRemainingStringForJob: (hb_job_t *)job state: (hb_state_t *)s
-{
- if (s->state == HB_STATE_WORKING)
- {
- #define p s->param.working
- if (p.seconds < 0)
- return @"";
-
- // Minutes always needed
- NSString * minutes;
- if (p.minutes > 1)
- minutes = [NSString stringWithFormat:NSLocalizedString( @"%d minutes ", nil ), p.minutes];
- else if (p.minutes == 1)
- minutes = NSLocalizedString( @"1 minute ", nil );
- else
- minutes = @"";
-
- if (p.hours >= 1)
- {
- NSString * hours;
- if (p.hours > 1)
- hours = [NSString stringWithFormat:NSLocalizedString( @"%d hours ", nil ), p.hours];
- else
- hours = NSLocalizedString( @"1 hour ", nil );
-
- return [NSString stringWithFormat:NSLocalizedString( @"%@%@remaining", nil ), hours, minutes];
- }
-
- else
- {
- NSString * seconds;
- if (p.seconds > 1)
- seconds = [NSString stringWithFormat:NSLocalizedString( @"%d seconds ", nil ), p.seconds];
- else
- seconds = NSLocalizedString( @"1 second ", nil );
-
- return [NSString stringWithFormat:NSLocalizedString( @"%@%@remaining", nil ), minutes, seconds];
- }
-
-/* here is code that does it more like the Finder
- if( p.seconds > -1 )
- {
- float estHours = (p.hours + (p.minutes / 60.0));
- float estMinutes = (p.minutes + (p.seconds / 60.0));
-
- if (estHours > 1.5)
- return [NSString stringWithFormat:NSLocalizedString( @"Time remaining: About %d hours", nil ), lrintf(estHours)];
- else if (estHours > 0.983) // 59 minutes
- return NSLocalizedString( @"Time remaining: About 1 hour", nil );
- else if (estMinutes > 1.5)
- return [NSString stringWithFormat:NSLocalizedString( @"Time remaining: About %d minutes", nil ), lrintf(estMinutes)];
- else if (estMinutes > 0.983) // 59 seconds
- return NSLocalizedString( @"Time remaining: About 1 minute", nil );
- else if (p.seconds <= 5)
- return NSLocalizedString( @"Time remaining: Less than 5 seconds", nil );
- else if (p.seconds <= 10)
- return NSLocalizedString( @"Time remaining: Less than 10 seconds", nil );
- else
- return NSLocalizedString( @"Time remaining: Less than 1 minute", nil );
- }
- else
- return NSLocalizedString( @"Time remaining: Calculating...", nil );
-*/
- #undef p
- }
-
- return @"";
-}
-
-//------------------------------------------------------------------------------------
-// Refresh progress bar (fProgressBar) from current state.
-//------------------------------------------------------------------------------------
-- (void) updateProgressBarWithState: (hb_state_t *)s
-{
- if (s->state == HB_STATE_WORKING)
- {
- #define p s->param.working
- [fProgressBar setIndeterminate:NO];
-
- float progress_total = fShowsJobsAsGroups ?
- 100.0 * ( p.progress + p.job_cur - 1 ) / p.job_count :
- 100.0 * p.progress;
-
- [fProgressBar setDoubleValue:progress_total];
- #undef p
- }
-
- else if (s->state == HB_STATE_MUXING)
- {
- #define p s->param.muxing
- [fProgressBar setIndeterminate:YES];
- [fProgressBar startAnimation:nil];
- #undef p
- }
-
- else if (s->state == HB_STATE_WORKDONE)
- {
- [fProgressBar setIndeterminate:NO];
- [fProgressBar setDoubleValue:0.0];
- }
-}
-
-//------------------------------------------------------------------------------------
-// Refresh queue count text field (fQueueCountField).
-//------------------------------------------------------------------------------------
-- (void)updateQueueCountField
-{
- NSString * msg;
- int jobCount;
-
- if (fShowsJobsAsGroups)
- {
- jobCount = fHandle ? hb_group_count(fHandle) : 0;
- if (jobCount == 1)
- msg = NSLocalizedString(@"1 pending encode", nil);
- else
- msg = [NSString stringWithFormat:NSLocalizedString(@"%d pending encodes", nil), jobCount];
- }
- else
- {
- jobCount = fHandle ? hb_count(fHandle) : 0;
- if (jobCount == 1)
- msg = NSLocalizedString(@"1 pending pass", nil);
- else
- msg = [NSString stringWithFormat:NSLocalizedString(@"%d pending passes", nil), jobCount];
-
- }
-
- [fQueueCountField setStringValue:msg];
-}
-
-//------------------------------------------------------------------------------------
-// Refresh the UI in the current job pane. Should be called whenever the current job
-// being processed has changed or when progress has changed.
-//------------------------------------------------------------------------------------
-- (void)updateCurrentJobUI
-{
- hb_state_t s;
- hb_job_t * job = nil;
-
- if (fHandle)
- {
- hb_get_state2( fHandle, &s );
- job = hb_current_job(fHandle);
- }
-
- if (job)
- {
- if (fLastKnownCurrentJob != job)
- {
- switch (job->pass)
- {
- case -1: // in-depth scan
- [fJobDescTextField setAttributedStringValue:
- [self attributedDescriptionForJob:job
- withTitle: YES
- withPassName: YES
- withFormatInfo: NO
- withDestination: NO
- withPictureInfo: NO
- withVideoInfo: NO
- withx264Info: NO
- withAudioInfo: NO
- withHighlighting: NO]];
- break;
-
- case 1: // video 1st pass
- [fJobDescTextField setAttributedStringValue:
- [self attributedDescriptionForJob:job
- withTitle: YES
- withPassName: YES
- withFormatInfo: NO
- withDestination: NO
- withPictureInfo: YES
- withVideoInfo: YES
- withx264Info: YES
- withAudioInfo: NO
- withHighlighting: NO]];
- break;
-
- case 0: // single pass
- case 2: // video 2nd pass + audio
- [fJobDescTextField setAttributedStringValue:
- [self attributedDescriptionForJob:job
- withTitle: YES
- withPassName: YES
- withFormatInfo: NO
- withDestination: NO
- withPictureInfo: YES
- withVideoInfo: YES
- withx264Info: YES
- withAudioInfo: YES
- withHighlighting: NO]];
- break;
-
- default: // unknown
- [fJobDescTextField setAttributedStringValue:
- [self attributedDescriptionForJob:job
- withTitle: YES
- withPassName: YES
- withFormatInfo: NO
- withDestination: NO
- withPictureInfo: YES
- withVideoInfo: YES
- withx264Info: YES
- withAudioInfo: YES
- withHighlighting: NO]];
- }
-
- [self showCurrentJobPane:YES];
- [fJobIconView setImage: fShowsJobsAsGroups ? [NSImage imageNamed:@"JobLarge"] : [self largeImageForPass: job->pass] ];
- }
-
- NSString * statusMsg = [self progressStatusStringForJob:job state:&s];
- NSString * timeMsg = [self progressTimeRemainingStringForJob:job state:&s];
- if ([timeMsg length] > 0)
- statusMsg = [NSString stringWithFormat:@"%@ - %@", statusMsg, timeMsg];
- [fProgressTextField setStringValue:statusMsg];
- [self updateProgressBarWithState:&s];
- }
- else
- {
- [fJobDescTextField setStringValue:NSLocalizedString(@"No job processing", nil)];
-
- [self showCurrentJobPane:NO];
- [fProgressBar stopAnimation:nil]; // just in case in was animating
- }
-
- fLastKnownCurrentJob = job;
-}
-
-//------------------------------------------------------------------------------------
-// Refresh the UI in the queue pane. Should be called whenever the content of HB's job
-// list has changed so that HBQueueController can sync up.
-//------------------------------------------------------------------------------------
-- (void)updateQueueUI
-{
-#if HB_OUTLINE_QUEUE
- [self saveOutlineViewState];
- [self rebuildEncodes];
- [fOutlineView noteNumberOfRowsChanged];
- [fOutlineView reloadData];
- [self restoreOutlineViewState];
-#else
- [fTaskView noteNumberOfRowsChanged];
- [fTaskView reloadData];
-#endif
-
- [self updateQueueCountField];
-}
-
-//------------------------------------------------------------------------------------
-// Deletes the selected job from HB and the queue UI
-//------------------------------------------------------------------------------------
-- (IBAction)removeSelectedJob: (id)sender
-{
- if (!fHandle) return;
-
- int row = [sender selectedRow];
- if (row != -1)
- {
-#if HB_UNI_QUEUE
- if (row == 0)
- {
- [self cancelCurrentJob:sender];
- }
- else
- {
- row--;
- if (fShowsJobsAsGroups)
- hb_rem_group( fHandle, hb_group( fHandle, row ) );
- else
- hb_rem( fHandle, hb_job( fHandle, row ) );
- }
-#else
- #if HB_OUTLINE_QUEUE
- hb_job_t * job = [[[fOutlineView itemAtRow: row] objectAtIndex: 0] job];
- hb_rem_group( fHandle, job );
- #else
- if (fShowsJobsAsGroups)
- hb_rem_group( fHandle, hb_group( fHandle, row ) );
- else
- hb_rem( fHandle, hb_job( fHandle, row ) );
- #endif
-#endif
- [self updateQueueUI];
- }
-}
-
-//------------------------------------------------------------------------------------
-// Prompts user if the want to cancel encoding of current job. If so, doCancelCurrentJob
-// gets called.
-//------------------------------------------------------------------------------------
-- (IBAction)cancelCurrentJob: (id)sender
-{
- [fHBController Cancel:sender];
-}
-
-//------------------------------------------------------------------------------------
-// Turns on the display of detail information for each job. Does nothing if detail is
-// already turned on.
-//------------------------------------------------------------------------------------
-- (IBAction)showDetail: (id)sender
-{
- if (!fShowsDetail)
- [self setShowsDetail:YES];
-}
-
-//------------------------------------------------------------------------------------
-// Turns off the display of detail information for each job. Does nothing if detail is
-// already turned off.
-//------------------------------------------------------------------------------------
-- (IBAction)hideDetail: (id)sender
-{
- if (fShowsDetail)
- [self setShowsDetail:NO];
-}
-
-//------------------------------------------------------------------------------------
-// Turns on displaying of jobs as groups by calling setShowsJobsAsGroups:YES. Does
-// nothing if groups are already turned on.
-//------------------------------------------------------------------------------------
-- (IBAction)showJobsAsGroups: (id)sender
-{
- if (!fShowsJobsAsGroups)
- [self setShowsJobsAsGroups:YES];