#import "HBQueueController.h"
+#import "HBQueueItem.h"
+
#import "HBController.h"
#import "HBAppDelegate.h"
@property (nonatomic) IBOutlet NSToolbarItem *ripToolbarItem;
@property (nonatomic) IBOutlet NSToolbarItem *pauseToolbarItem;
-@property (nonatomic, readonly) NSMutableDictionary<NSString *, NSNumber *> *expanded;
@property (nonatomic) NSTableCellView *dummyCell;
@property (nonatomic) NSLayoutConstraint *dummyCellWidth;
+@property (nonatomic, readonly) HBDistributedArray<HBQueueItem *> *items;
-@property (nonatomic, readonly) HBDistributedArray<HBJob *> *jobs;
-@property (nonatomic) HBJob *currentJob;
-@property (nonatomic) HBJobOutputFileWriter *currentLog;
+@property (nonatomic) HBQueueItem *currentItem;
+@property (nonatomic) HBJobOutputFileWriter *currentLog;
@property (nonatomic, readwrite) BOOL stop;
@property (nonatomic, readwrite) NSUInteger pendingItemsCount;
@property (nonatomic, readwrite) NSUInteger completedItemsCount;
-@property (nonatomic) NSArray<HBJob *> *dragNodesArray;
+@property (nonatomic) NSArray<HBQueueItem *> *dragNodesArray;
@end
if (self = [super initWithWindowNibName:@"Queue"])
{
- // Cached queue items expanded state
- _expanded = [[NSMutableDictionary alloc] init];
-
// Load the dockTile and instiante initial text fields
_dockTile = [[HBDockTile alloc] initWithDockTile:[[NSApplication sharedApplication] dockTile]
image:[[NSApplication sharedApplication] applicationIconImage]];
_progressInfo = @"";
// Load the queue from disk.
- _jobs = [[HBDistributedArray alloc] initWithURL:queueURL class:[HBJob class]];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadQueue) name:HBDistributedArrayChanged object:_jobs];
+ _items = [[HBDistributedArray alloc] initWithURL:queueURL class:[HBQueueItem class]];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadQueue) name:HBDistributedArrayChanged object:_items];
[NSUserNotificationCenter defaultUserNotificationCenter].delegate = self;
}
if (action == @selector(clearAll:))
{
- return self.jobs.count > 0;
+ return self.items.count > 0;
}
if (action == @selector(clearCompleted:))
[self addJobsFromArray:@[item]];
}
-- (void)addJobsFromArray:(NSArray<HBJob *> *)items;
+- (void)addJobsFromArray:(NSArray<HBJob *> *)jobs;
{
- NSParameterAssert(items);
- if (items.count)
+ NSParameterAssert(jobs);
+ NSMutableArray *itemsToAdd = [NSMutableArray array];
+ for (HBJob *job in jobs)
+ {
+ HBQueueItem *item = [[HBQueueItem alloc] initWithJob:job];
+ [itemsToAdd addObject:item];
+ }
+ if (itemsToAdd.count)
{
- [self addQueueItems:items];
+ [self addQueueItems:itemsToAdd];
}
}
{
NSParameterAssert(url);
- for (HBJob *item in self.jobs)
+ for (HBQueueItem *item in self.items)
{
- if ((item.state == HBJobStateReady || item.state == HBJobStateWorking)
+ if ((item.state == HBQueueItemStateReady || item.state == HBQueueItemStateWorking)
&& [item.completeOutputURL isEqualTo:url])
{
return YES;
- (NSUInteger)count
{
- return self.jobs.count;
+ return self.items.count;
}
/**
*/
- (void)removeCompletedJobs
{
- [self.jobs beginTransaction];
- NSIndexSet *indexes = [self.jobs indexesOfObjectsUsingBlock:^BOOL(HBJob *item) {
- return (item.state == HBJobStateCompleted || item.state == HBJobStateCanceled);
+ [self.items beginTransaction];
+ NSIndexSet *indexes = [self.items indexesOfObjectsUsingBlock:^BOOL(HBQueueItem *item) {
+ return (item.state == HBQueueItemStateCompleted || item.state == HBQueueItemStateCanceled);
}];
[self removeQueueItemsAtIndexes:indexes];
- [self.jobs commit];
+ [self.items commit];
}
/**
*/
- (void)removeAllJobs
{
- [self.jobs beginTransaction];
- [self removeQueueItemsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.jobs.count)]];
- [self.jobs commit];
+ [self.items beginTransaction];
+ [self removeQueueItemsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.items.count)]];
+ [self.items commit];
}
/**
*/
- (void)setEncodingJobsAsPending
{
- [self.jobs beginTransaction];
+ [self.items beginTransaction];
NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];
NSUInteger idx = 0;
- for (HBJob *job in self.jobs)
+ for (HBQueueItem *item in self.items)
{
// We want to keep any queue item that is pending or was previously being encoded
- if (job.state == HBJobStateWorking)
+ if (item.state == HBQueueItemStateWorking)
{
- job.state = HBJobStateReady;
+ item.state = HBQueueItemStateReady;
[indexes addIndex:idx];
}
idx++;
}
[self reloadQueueItemsAtIndexes:indexes];
- [self.jobs commit];
+ [self.items commit];
}
#pragma mark - Private queue editing methods
[self updateQueueStats];
}
-- (void)addQueueItems:(NSArray *)items
+- (void)addQueueItems:(NSArray<HBQueueItem *> *)items
{
NSParameterAssert(items);
- NSIndexSet *indexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(self.jobs.count, items.count)];
+ NSIndexSet *indexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(self.items.count, items.count)];
[self addQueueItems:items atIndexes:indexes];
}
{
NSParameterAssert(items);
NSParameterAssert(indexes);
- [self.jobs beginTransaction];
+ [self.items beginTransaction];
[self.tableView beginUpdates];
// Forward
NSUInteger currentObjectIndex = 0;
while (currentIndex != NSNotFound)
{
- [self.jobs insertObject:items[currentObjectIndex] atIndex:currentIndex];
+ [self.items insertObject:items[currentObjectIndex] atIndex:currentIndex];
currentIndex = [indexes indexGreaterThanIndex:currentIndex];
currentObjectIndex++;
}
[self.tableView endUpdates];
[self updateQueueStats];
- [self.jobs commit];
+ [self.items commit];
}
- (void)removeQueueItemAtIndex:(NSUInteger)index
return;
}
- [self.jobs beginTransaction];
+ [self.items beginTransaction];
[self.tableView beginUpdates];
- NSArray<HBJob *> *removeJobs = [self.jobs objectsAtIndexes:indexes];
+ NSArray<HBQueueItem *> *removeItems = [self.items objectsAtIndexes:indexes];
- if (self.jobs.count > indexes.lastIndex)
+ if (self.items.count > indexes.lastIndex)
{
- [self.jobs removeObjectsAtIndexes:indexes];
- }
-
- for (HBJob *job in removeJobs)
- {
- [self.expanded removeObjectForKey:job.uuid];
+ [self.items removeObjectsAtIndexes:indexes];
}
[self.tableView removeRowsAtIndexes:indexes withAnimation:NSTableViewAnimationSlideUp];
[self.tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:indexes.firstIndex] byExtendingSelection:NO];
NSUndoManager *undo = self.window.undoManager;
- [[undo prepareWithInvocationTarget:self] addQueueItems:removeJobs atIndexes:indexes];
+ [[undo prepareWithInvocationTarget:self] addQueueItems:removeItems atIndexes:indexes];
if (!undo.isUndoing)
{
[self.tableView endUpdates];
[self updateQueueStats];
- [self.jobs commit];
+ [self.items commit];
}
- (void)moveQueueItems:(NSArray *)items toIndex:(NSUInteger)index
{
- [self.jobs beginTransaction];
+ [self.items beginTransaction];
[self.tableView beginUpdates];
NSMutableArray *source = [NSMutableArray array];
for (id object in items.reverseObjectEnumerator)
{
- NSUInteger sourceIndex = [self.jobs indexOfObject:object];
- [self.jobs removeObjectAtIndex:sourceIndex];
+ NSUInteger sourceIndex = [self.items indexOfObject:object];
+ [self.items removeObjectAtIndex:sourceIndex];
if (sourceIndex < index)
index--;
}
- [self.jobs insertObject:object atIndex:index];
+ [self.items insertObject:object atIndex:index];
[source addObject:@(index)];
[dest addObject:@(sourceIndex)];
}
[self.tableView endUpdates];
- [self.jobs commit];
+ [self.items commit];
}
- (void)moveQueueItemsAtIndexes:(NSArray *)source toIndexes:(NSArray *)dest
{
- [self.jobs beginTransaction];
+ [self.items beginTransaction];
[self.tableView beginUpdates];
NSMutableArray *newSource = [NSMutableArray array];
[newSource addObject:@(destIndex)];
[newDest addObject:@(sourceIndex)];
- id obj = [self.jobs objectAtIndex:sourceIndex];
- [self.jobs removeObjectAtIndex:sourceIndex];
- [self.jobs insertObject:obj atIndex:destIndex];
+ id obj = [self.items objectAtIndex:sourceIndex];
+ [self.items removeObjectAtIndex:sourceIndex];
+ [self.items insertObject:obj atIndex:destIndex];
[self.tableView moveRowAtIndex:sourceIndex toIndex:destIndex];
}
}
[self.tableView endUpdates];
- [self.jobs commit];
+ [self.items commit];
}
- (void)windowDidChangeOcclusionState:(NSNotification *)notification
NSUInteger pendingCount = 0;
NSUInteger completedCount = 0;
- for (HBJob *job in self.jobs)
+ for (HBQueueItem *item in self.items)
{
- if (job.state == HBJobStateReady)
+ if (item.state == HBQueueItemStateReady)
{
pendingCount++;
}
- if (job.state == HBJobStateCompleted)
+ if (item.state == HBQueueItemStateCompleted)
{
completedCount++;
}
/**
* Used to get the next pending queue item and return it if found
*/
-- (HBJob *)getNextPendingQueueItem
+- (HBQueueItem *)getNextPendingQueueItem
{
- for (HBJob *job in self.jobs)
+ for (HBQueueItem *item in self.items)
{
- if (job.state == HBJobStateReady)
+ if (item.state == HBQueueItemStateReady)
{
- return job;
+ return item;
}
}
return nil;
*/
- (void)encodeNextQueueItem
{
- [self.jobs beginTransaction];
- self.currentJob = nil;
+ [self.items beginTransaction];
+ self.currentItem = nil;
// since we have completed an encode, we go to the next
if (self.stop)
else
{
// Check to see if there are any more pending items in the queue
- HBJob *nextJob = [self getNextPendingQueueItem];
+ HBQueueItem *nextItem = [self getNextPendingQueueItem];
- if (nextJob && [self _isDiskSpaceLowAtURL:nextJob.outputURL])
+ if (nextItem && [self _isDiskSpaceLowAtURL:nextItem.outputURL])
{
// Disk space is low, show an alert
[HBUtilities writeToActivityLog:"Queue Stopped, low space on destination disk"];
[self queueLowDiskSpaceAlert];
}
// If we still have more pending items in our queue, lets go to the next one
- else if (nextJob)
+ else if (nextItem)
{
// now we mark the queue item as working so another instance can not come along and try to scan it while we are scanning
- nextJob.state = HBJobStateWorking;
+ nextItem.state = HBQueueItemStateWorking;
// Tell HB to output a new activity log file for this encode
- self.currentLog = [[HBJobOutputFileWriter alloc] initWithJob:nextJob];
+ self.currentLog = [[HBJobOutputFileWriter alloc] initWithJob:nextItem.job];
if (self.currentLog)
{
[[HBOutputRedirect stderrRedirect] addListener:self.currentLog];
[[HBOutputRedirect stdoutRedirect] addListener:self.currentLog];
}
- self.currentJob = nextJob;
- [self reloadQueueItemAtIndex:[self.jobs indexOfObject:nextJob]];
+ self.currentItem = nextItem;
+ [self reloadQueueItemAtIndex:[self.items indexOfObject:nextItem]];
// now we can go ahead and scan the new pending queue item
- [self encodeJob:nextJob];
+ [self encodeItem:nextItem];
// erase undo manager history
[self.window.undoManager removeAllActions];
[self.core allowSleep];
}
}
- [self.jobs commit];
+ [self.items commit];
}
-- (void)completedJob:(HBJob *)job result:(HBCoreResult)result;
+- (void)completedItem:(HBQueueItem *)item result:(HBCoreResult)result;
{
- NSParameterAssert(job);
- [self.jobs beginTransaction];
+ NSParameterAssert(item);
+ [self.items beginTransaction];
// Since we are done with this encode, tell output to stop writing to the
// individual encode log.
if (result != HBCoreResultCanceled)
{
// Send to tagger
- [self sendToExternalApp:job];
+ [self sendToExternalApp:item];
}
// Mark the encode just finished
switch (result) {
case HBCoreResultDone:
- job.state = HBJobStateCompleted;
+ item.state = HBQueueItemStateCompleted;
break;
case HBCoreResultCanceled:
- job.state = HBJobStateCanceled;
+ item.state = HBQueueItemStateCanceled;
break;
default:
- job.state = HBJobStateFailed;
+ item.state = HBQueueItemStateFailed;
break;
}
- if ([self.jobs containsObject:job])
+ if ([self.items containsObject:item])
{
- [self reloadQueueItemAtIndex:[self.jobs indexOfObject:job]];
+ [self reloadQueueItemAtIndex:[self.items indexOfObject:item]];
}
[self.window.toolbar validateVisibleItems];
- [self.jobs commit];
+ [self.items commit];
// Update UI
NSString *info = nil;
switch (result) {
case HBCoreResultDone:
info = NSLocalizedString(@"Encode Finished.", @"Queue status");
- [self jobCompletedAlerts:job result:result];
+ [self itemCompletedAlerts:item result:result];
break;
case HBCoreResultCanceled:
info = NSLocalizedString(@"Encode Canceled.", @"Queue status");
break;
default:
info = NSLocalizedString(@"Encode Failed.", @"Queue status");
- [self jobCompletedAlerts:job result:result];
+ [self itemCompletedAlerts:item result:result];
break;
}
[self updateProgress:info progress:1.0 hidden:YES];
/**
* Here we actually tell hb_scan to perform the source scan, using the path to source and title number
*/
-- (void)encodeJob:(HBJob *)job
+- (void)encodeItem:(HBQueueItem *)item
{
- NSParameterAssert(job);
+ NSParameterAssert(item);
// Progress handler
void (^progressHandler)(HBState state, HBProgress progress, NSString *info) = ^(HBState state, HBProgress progress, NSString *info)
{
if (result == HBCoreResultDone)
{
- [self realEncodeJob:job];
+ [self realEncodeItem:item];
}
else
{
- [self completedJob:job result:result];
+ [self completedItem:item result:result];
[self encodeNextQueueItem];
}
};
// Only scan 10 previews before an encode - additional previews are
// only useful for autocrop and static previews, which are already taken care of at this point
- [self.core scanURL:job.fileURL
- titleIndex:job.titleIdx
+ [self.core scanURL:item.fileURL
+ titleIndex:item.job.titleIdx
previews:10
minDuration:0
progressHandler:progressHandler
/**
* This assumes that we have re-scanned and loaded up a new queue item to send to libhb
*/
-- (void)realEncodeJob:(HBJob *)job
+- (void)realEncodeItem:(HBQueueItem *)item
{
- NSParameterAssert(job);
+ NSParameterAssert(item);
+
+ HBJob *job = item.job;
// Reset the title in the job.
job.title = self.core.titles.firstObject;
// Completion handler
void (^completionHandler)(HBCoreResult result) = ^(HBCoreResult result)
{
- [self completedJob:job result:result];
+ [self completedItem:item result:result];
[self encodeNextQueueItem];
};
/**
* Cancels the current job
*/
-- (void)doCancelCurrentJob
+- (void)doCancelCurrentItem
{
if (self.core.state == HBStateScanning)
{
/**
* Cancels the current job and starts processing the next in queue.
*/
-- (void)cancelCurrentJobAndContinue
+- (void)cancelCurrentItemAndContinue
{
- [self doCancelCurrentJob];
+ [self doCancelCurrentItem];
}
/**
* Cancels the current job and stops libhb from processing the remaining encodes.
*/
-- (void)cancelCurrentJobAndStop
+- (void)cancelCurrentItemAndStop
{
self.stop = YES;
- [self doCancelCurrentJob];
+ [self doCancelCurrentItem];
}
/**
*
* @param job the job of the file to send
*/
-- (void)sendToExternalApp:(HBJob *)job
+- (void)sendToExternalApp:(HBQueueItem *)item
{
// This end of encode action is called as each encode rolls off of the queue
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"HBSendToAppEnabled"] == YES)
{
#ifdef __SANDBOX_ENABLED__
- BOOL accessingSecurityScopedResource = [job.outputURL startAccessingSecurityScopedResource];
+ BOOL accessingSecurityScopedResource = [item.outputURL startAccessingSecurityScopedResource];
#endif
NSWorkspace *workspace = [NSWorkspace sharedWorkspace];
if (app)
{
- if (![workspace openFile:job.completeOutputURL.path withApplication:app])
+ if (![workspace openFile:item.completeOutputURL.path withApplication:app])
{
[HBUtilities writeToActivityLog:"Failed to send file to: %s", app];
}
#ifdef __SANDBOX_ENABLED__
if (accessingSecurityScopedResource)
{
- [job.outputURL stopAccessingSecurityScopedResource];
+ [item.outputURL stopAccessingSecurityScopedResource];
}
#endif
}
/**
* Runs the alert for a single job
*/
-- (void)jobCompletedAlerts:(HBJob *)job result:(HBCoreResult)result
+- (void)itemCompletedAlerts:(HBQueueItem *)item result:(HBCoreResult)result
{
// Both the Notification and Sending to tagger can be done as encodes roll off the queue
if ([[NSUserDefaults standardUserDefaults] integerForKey:@"HBAlertWhenDone"] == HBDoneActionNotification ||
{
title = NSLocalizedString(@"Put down that cocktailā¦", @"Queue notification alert message");
description = [NSString stringWithFormat:NSLocalizedString(@"Your encode %@ is done!", @"Queue done notification message"),
- job.outputFileName];
+ item.outputFileName];
}
else
{
title = NSLocalizedString(@"Encode failed", @"Queue done notification failed message");
description = [NSString stringWithFormat:NSLocalizedString(@"Your encode %@ couldn't be completed.", @"Queue done notification message"),
- job.outputFileName];
+ item.outputFileName];
}
[self showNotificationWithTitle:title
description:description
- url:job.completeOutputURL
+ url:item.completeOutputURL
playSound:playSound];
}
}
*/
- (IBAction)removeSelectedQueueItem:(id)sender
{
- if ([self.jobs beginTransaction] == HBDistributedArrayContentReload)
+ if ([self.items beginTransaction] == HBDistributedArrayContentReload)
{
// Do not execture the action if the array changed.
- [self.jobs commit];
+ [self.items commit];
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
- NSIndexSet *workingIndexes = [self.jobs indexesOfObjectsUsingBlock:^BOOL(HBJob *item) {
- return item.state == HBJobStateWorking;
+ NSIndexSet *workingIndexes = [self.items indexesOfObjectsUsingBlock:^BOOL(HBQueueItem *item) {
+ return item.state == HBQueueItemStateWorking;
}];
if ([targetedRows containsIndexes:workingIndexes])
{
[targetedRows removeIndexes:workingIndexes];
- NSArray<HBJob *> *workingJobs = [self.jobs filteredArrayUsingBlock:^BOOL(HBJob *item) {
- return item.state == HBJobStateWorking;
+ NSArray<HBQueueItem *> *workingItems = [self.items filteredArrayUsingBlock:^BOOL(HBQueueItem *item) {
+ return item.state == HBQueueItemStateWorking;
}];
- if ([workingJobs containsObject:self.currentJob])
+ if ([workingItems containsObject:self.currentItem])
{
NSString *alertTitle = [NSString stringWithFormat:NSLocalizedString(@"Stop This Encode and Remove It?", @"Queue Stop Alert -> stop and remove message")];
[alert beginSheetModalForWindow:targetWindow completionHandler:^(NSModalResponse returnCode) {
if (returnCode == NSAlertSecondButtonReturn)
{
- [self.jobs beginTransaction];
+ [self.items beginTransaction];
- NSInteger index = [self.jobs indexOfObject:self.currentJob];
- [self cancelCurrentJobAndContinue];
+ NSInteger index = [self.items indexOfObject:self.currentItem];
+ [self cancelCurrentItemAndContinue];
[self removeQueueItemAtIndex:index];
- [self.jobs commit];
+ [self.items commit];
}
}];
}
// remove the non working items immediately
[self removeQueueItemsAtIndexes:targetedRows];
}
- [self.jobs commit];
+ [self.items commit];
}
/**
NSUInteger currentIndex = [targetedRows firstIndex];
while (currentIndex != NSNotFound) {
- NSURL *url = [[self.jobs objectAtIndex:currentIndex] completeOutputURL];
+ NSURL *url = [[self.items objectAtIndex:currentIndex] completeOutputURL];
[urls addObject:url];
currentIndex = [targetedRows indexGreaterThanIndex:currentIndex];
}
NSUInteger currentIndex = [targetedRows firstIndex];
while (currentIndex != NSNotFound) {
- NSURL *url = [[self.jobs objectAtIndex:currentIndex] fileURL];
+ NSURL *url = [[self.items objectAtIndex:currentIndex] fileURL];
[urls addObject:url];
currentIndex = [targetedRows indexGreaterThanIndex:currentIndex];
}
{
[self cancelRip:sender];
}
- // If there are pending jobs in the queue, then this is a rip the queue
+ // If there are pending items in the queue, then this is a rip the queue
else if (self.pendingItemsCount > 0)
{
// We check to see if we need to warn the user that the computer will go to sleep
}
/**
- * Displays an alert asking user if the want to cancel encoding of current job.
+ * Displays an alert asking user if the want to cancel encoding of current item.
* Cancel: returns immediately after posting the alert. Later, when the user
- * acknowledges the alert, doCancelCurrentJob is called.
+ * acknowledges the alert, doCancelCurrentItem is called.
*/
- (IBAction)cancelRip:(id)sender
{
[alert beginSheetModalForWindow:window completionHandler:^(NSModalResponse returnCode) {
if (returnCode == NSAlertSecondButtonReturn)
{
- [self cancelCurrentJobAndContinue];
+ [self cancelCurrentItemAndContinue];
}
else if (returnCode == NSAlertThirdButtonReturn)
{
}
else if (returnCode == NSAlertThirdButtonReturn + 1)
{
- [self cancelCurrentJobAndStop];
+ [self cancelCurrentItemAndStop];
}
}];
}
/**
- * Starts or cancels the processing of jobs depending on the current state
+ * Starts or cancels the processing of items depending on the current state
*/
- (IBAction)toggleStartCancel:(id)sender
{
}
/**
- * Resets the job state to ready.
+ * Resets the item state to ready.
*/
- (IBAction)resetJobState:(id)sender
{
- if ([self.jobs beginTransaction] == HBDistributedArrayContentReload)
+ if ([self.items beginTransaction] == HBDistributedArrayContentReload)
{
// Do not execture the action if the array changed.
- [self.jobs commit];
+ [self.items commit];
return;
}
NSUInteger currentIndex = [targetedRows firstIndex];
while (currentIndex != NSNotFound) {
- HBJob *job = self.jobs[currentIndex];
+ HBQueueItem *item = self.items[currentIndex];
- if (job.state == HBJobStateCanceled || job.state == HBJobStateCompleted || job.state == HBJobStateFailed)
+ if (item.state == HBQueueItemStateCanceled || item.state == HBQueueItemStateCompleted || item.state == HBQueueItemStateFailed)
{
- job.state = HBJobStateReady;
+ item.state = HBQueueItemStateReady;
[updatedIndexes addIndex:currentIndex];
}
currentIndex = [targetedRows indexGreaterThanIndex:currentIndex];
}
[self reloadQueueItemsAtIndexes:updatedIndexes];
- [self.jobs commit];
+ [self.items commit];
}
-- (void)editQueueItem:(HBJob *)job
+- (void)editQueueItem:(HBQueueItem *)item
{
- NSParameterAssert(job);
- [self.jobs beginTransaction];
+ NSParameterAssert(item);
+ [self.items beginTransaction];
- if (job != self.currentJob)
+ if (item != self.currentItem)
{
- job.state = HBJobStateWorking;
+ item.state = HBQueueItemStateWorking;
- NSUInteger row = [self.jobs indexOfObject:job];
+ NSUInteger row = [self.items indexOfObject:item];
[self reloadQueueItemAtIndex:row];
- [self.controller openJob:[job copy] completionHandler:^(BOOL result) {
- [self.jobs beginTransaction];
+ [self.controller openJob:[item.job copy] completionHandler:^(BOOL result) {
+ [self.items beginTransaction];
if (result)
{
// Now that source is loaded and settings applied, delete the queue item from the queue
- NSInteger index = [self.jobs indexOfObject:job];
- job.state = HBJobStateReady;
+ NSInteger index = [self.items indexOfObject:item];
+ item.state = HBQueueItemStateReady;
[self removeQueueItemAtIndex:index];
}
else
{
- job.state = HBJobStateFailed;
+ item.state = HBQueueItemStateFailed;
NSBeep();
}
- [self.jobs commit];
+ [self.items commit];
}];
}
else
NSBeep();
}
- [self.jobs commit];
+ [self.items commit];
}
/**
*/
- (IBAction)editSelectedQueueItem:(id)sender
{
- if ([self.jobs beginTransaction] == HBDistributedArrayContentReload)
+ if ([self.items beginTransaction] == HBDistributedArrayContentReload)
{
// Do not execture the action if the array changed.
- [self.jobs commit];
+ [self.items commit];
return;
}
NSInteger row = self.tableView.clickedRow;
if (row != NSNotFound)
{
- // if this is a currently encoding job, we need to be sure to alert the user,
+ // if this is a currently encoding item, 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
- HBJob *job = self.jobs[row];
- if (job == self.currentJob)
+ HBQueueItem *item = self.items[row];
+ if (item == self.currentItem)
{
NSString *alertTitle = [NSString stringWithFormat:NSLocalizedString(@"Stop This Encode and Edit It?", @"Queue Edit Alert -> stop and edit message")];
[alert beginSheetModalForWindow:docWindow completionHandler:^(NSModalResponse returnCode) {
if (returnCode == NSAlertSecondButtonReturn)
{
- [self editQueueItem:job];
+ [self editQueueItem:item];
}
}];
}
- else if (job.state != HBJobStateWorking)
+ else if (item.state != HBQueueItemStateWorking)
{
- [self editQueueItem:job];
+ [self editQueueItem:item];
}
}
- [self.jobs commit];
+ [self.items commit];
}
- (IBAction)clearAll:(id)sender
{
- [self.jobs beginTransaction];
- NSIndexSet *indexes = [self.jobs indexesOfObjectsUsingBlock:^BOOL(HBJob *item) {
- return (item.state != HBJobStateWorking);
+ [self.items beginTransaction];
+ NSIndexSet *indexes = [self.items indexesOfObjectsUsingBlock:^BOOL(HBQueueItem *item) {
+ return (item.state != HBQueueItemStateWorking);
}];
[self removeQueueItemsAtIndexes:indexes];
- [self.jobs commit];
+ [self.items commit];
}
- (IBAction)clearCompleted:(id)sender
{
- [self.jobs beginTransaction];
- NSIndexSet *indexes = [self.jobs indexesOfObjectsUsingBlock:^BOOL(HBJob *item) {
- return (item.state == HBJobStateCompleted);
+ [self.items beginTransaction];
+ NSIndexSet *indexes = [self.items indexesOfObjectsUsingBlock:^BOOL(HBQueueItem *item) {
+ return (item.state == HBQueueItemStateCompleted);
}];
[self removeQueueItemsAtIndexes:indexes];
- [self.jobs commit];
+ [self.items commit];
}
#pragma mark - NSTableView data source
row:(NSInteger)row {
HBQueueItemView *view = [tableView makeViewWithIdentifier:@"MainCell" owner:self];
- HBJob *job = self.jobs[row];
+ HBQueueItem *item = self.items[row];
- view.expanded = [self.expanded[job.uuid] boolValue];
view.delegate = self;
-
- view.job = job;
+ view.item = item;
return view;
}
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
{
- return self.jobs.count;
+ return self.items.count;
}
- (NSTableCellView *)dummyCell
{
if (!_dummyCell) {
- _dummyCell = [self.tableView makeViewWithIdentifier:@"MainCell" owner: self];
+ _dummyCell = [self.tableView makeViewWithIdentifier:@"MainCellForSizing" owner: self];
_dummyCellWidth = [NSLayoutConstraint constraintWithItem:_dummyCell
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
- (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row
{
- HBJob *job = self.jobs[row];
- BOOL expanded = [self.expanded[job.uuid] boolValue];
+ HBQueueItem *item = self.items[row];
- if (expanded)
+ if (item.expanded)
{
CGFloat width = tableView.frame.size.width;
self.dummyCellWidth.constant = width;
- self.dummyCell.textField.preferredMaxLayoutWidth = width;
- self.dummyCell.textField.attributedStringValue = job.attributedDescription;
+ self.dummyCell.textField.preferredMaxLayoutWidth = width - 60;
+ self.dummyCell.textField.attributedStringValue = item.attributedDescription;
CGFloat height = self.dummyCell.fittingSize.height;
return height;
{
NSMutableIndexSet *rowsToExpand = [NSMutableIndexSet indexSet];
[rowIndexes enumerateIndexesUsingBlock:^(NSUInteger index, BOOL *stop) {
- HBJob *job = self.jobs[index];
- BOOL expanded = [self.expanded[job.uuid] boolValue];
+ HBQueueItem *item = self.items[index];
+ BOOL expanded = item.expanded;
if (expanded != expand)
{
- self.expanded[job.uuid] = @(!expanded);
+ item.expanded = !expanded;
[rowsToExpand addIndex:index];
}
#pragma mark NSQueueItemView delegate
-- (void)removeQueueItem:(nonnull HBJob *)job
+- (void)removeQueueItem:(nonnull HBQueueItem *)item
{
- NSUInteger index = [self.jobs indexOfObject:job];
+ NSUInteger index = [self.items indexOfObject:item];
[self removeQueueItemAtIndex:index];
}
-- (void)revealQueueItem:(nonnull HBJob *)job
+- (void)revealQueueItem:(nonnull HBQueueItem *)item
{
- [[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs:@[job.completeOutputURL]];
+ [[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs:@[item.completeOutputURL]];
}
-- (void)toggleQueueItemHeight:(nonnull HBJob *)job
+- (void)toggleQueueItemHeight:(nonnull HBQueueItem *)item
{
- NSInteger row = [self.jobs indexOfObject:job];
- BOOL expanded = [self.expanded[job.uuid] boolValue];
- [self toggleRowsAtIndexes:[NSIndexSet indexSetWithIndex:row] expand:!expanded];
+ NSInteger row = [self.items indexOfObject:item];
+ [self toggleRowsAtIndexes:[NSIndexSet indexSetWithIndex:row] expand:!item.expanded];
}
#pragma mark NSTableView delegate
- (BOOL)tableView:(NSTableView *)tableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard;
{
- NSArray<HBJob *> *items = [self.jobs objectsAtIndexes:rowIndexes];
+ NSArray<HBQueueItem *> *items = [self.items objectsAtIndexes:rowIndexes];
// Dragging is only allowed of the pending items.
- if ([items[0] state] != HBJobStateReady)
+ if (items[0].state != HBQueueItemStateReady)
{
return NO;
}
return NSDragOperationNone;
}
- // We do not let the user drop a pending job before or *above*
- // already finished or currently encoding jobs.
- NSInteger encodingRow = [self.jobs indexOfObject:self.currentJob];
+ // We do not let the user drop a pending item before or *above*
+ // already finished or currently encoding items.
+ NSInteger encodingRow = [self.items indexOfObject:self.currentItem];
if (encodingRow != NSNotFound && row <= encodingRow)
{
return NSDragOperationNone;
A91119A21C7DD58B001C463C /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 273F203B14ADBC210021BE6D /* Cocoa.framework */; };
A91119A31C7DD591001C463C /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 273F202214ADB8650021BE6D /* IOKit.framework */; };
A91119A41C7DD614001C463C /* HBSubtitlesDefaults.h in Headers */ = {isa = PBXBuildFile; fileRef = A9F4728B1976BAA70009EC65 /* HBSubtitlesDefaults.h */; settings = {ATTRIBUTES = (Public, ); }; };
- A91119A51C7DD644001C463C /* HBDistributedArray.h in Headers */ = {isa = PBXBuildFile; fileRef = A9E66D6E1A67A2A8007B641D /* HBDistributedArray.h */; settings = {ATTRIBUTES = (Public, ); }; };
- A91119A61C7DD64A001C463C /* HBDistributedArray.m in Sources */ = {isa = PBXBuildFile; fileRef = A9E66D6F1A67A2A8007B641D /* HBDistributedArray.m */; };
A91485FE1F61296100374C12 /* HBFiltersViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A91485FD1F61296100374C12 /* HBFiltersViewController.m */; };
A914BCB31BC441C700157917 /* HBPreviewView.m in Sources */ = {isa = PBXBuildFile; fileRef = A914BCB21BC441C700157917 /* HBPreviewView.m */; };
A916180E1C845161000556C6 /* NSDictionary+HBAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = A93B0DF71C804CF50051A3FA /* NSDictionary+HBAdditions.m */; };
A95121E61B5F7BE700FD773D /* NSArray+HBAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = A95121E51B5F7BE700FD773D /* NSArray+HBAdditions.m */; };
A955128B1A320B02001BFC6F /* libjansson.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A95512881A320A12001BFC6F /* libjansson.a */; };
A957EBCD218DBE5900007988 /* HBAutoNamer.m in Sources */ = {isa = PBXBuildFile; fileRef = A957EBCC218DBE5900007988 /* HBAutoNamer.m */; };
+ A95BA15D220C968500A2F9F9 /* HBQueueItem.m in Sources */ = {isa = PBXBuildFile; fileRef = A95BA15C220C968500A2F9F9 /* HBQueueItem.m */; };
+ A95BA161220CA5DB00A2F9F9 /* HBDistributedArray.m in Sources */ = {isa = PBXBuildFile; fileRef = A95BA160220CA5DB00A2F9F9 /* HBDistributedArray.m */; };
A95BC1E71CD2548A008D6A33 /* volHighTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = A95BC1E51CD2548A008D6A33 /* volHighTemplate.pdf */; };
A95BC1E81CD2548A008D6A33 /* volLowTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = A95BC1E61CD2548A008D6A33 /* volLowTemplate.pdf */; };
A96664B01CCE45BF00DA4A57 /* HBPlayerHUDController.m in Sources */ = {isa = PBXBuildFile; fileRef = A96664AE1CCE45BF00DA4A57 /* HBPlayerHUDController.m */; };
A957EBCC218DBE5900007988 /* HBAutoNamer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HBAutoNamer.m; sourceTree = "<group>"; };
A9597A281A49749D00007771 /* HBRange+UIAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "HBRange+UIAdditions.h"; sourceTree = "<group>"; };
A9597A291A49749D00007771 /* HBRange+UIAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "HBRange+UIAdditions.m"; sourceTree = "<group>"; };
+ A95BA15B220C968500A2F9F9 /* HBQueueItem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HBQueueItem.h; sourceTree = "<group>"; };
+ A95BA15C220C968500A2F9F9 /* HBQueueItem.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HBQueueItem.m; sourceTree = "<group>"; };
+ A95BA15F220CA5DB00A2F9F9 /* HBDistributedArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBDistributedArray.h; sourceTree = "<group>"; };
+ A95BA160220CA5DB00A2F9F9 /* HBDistributedArray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBDistributedArray.m; sourceTree = "<group>"; };
A95BC1E51CD2548A008D6A33 /* volHighTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = volHighTemplate.pdf; sourceTree = "<group>"; };
A95BC1E61CD2548A008D6A33 /* volLowTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = volLowTemplate.pdf; sourceTree = "<group>"; };
A95CB2FB217B6D07001E9F51 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
A9E2FD241A21BC4A000E8D3F /* HBAddPresetController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBAddPresetController.h; sourceTree = "<group>"; };
A9E2FD251A21BC4A000E8D3F /* HBAddPresetController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBAddPresetController.m; sourceTree = "<group>"; };
A9E52CD7218DD52A00E17B86 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ExceptionAlert.xib; sourceTree = "<group>"; };
- A9E66D6E1A67A2A8007B641D /* HBDistributedArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HBDistributedArray.h; path = ../HBDistributedArray.h; sourceTree = "<group>"; };
- A9E66D6F1A67A2A8007B641D /* HBDistributedArray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HBDistributedArray.m; path = ../HBDistributedArray.m; sourceTree = "<group>"; };
A9EA43661A2210C400785E95 /* HBTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBTableView.h; sourceTree = "<group>"; };
A9EA43671A2210C400785E95 /* HBTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBTableView.m; sourceTree = "<group>"; };
A9F217E41E2F897D00C10C6E /* HandBrake.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = HandBrake.entitlements; sourceTree = "<group>"; };
A901C2401BC7CFDC00D77735 /* Queue */ = {
isa = PBXGroup;
children = (
+ A95BA15B220C968500A2F9F9 /* HBQueueItem.h */,
+ A95BA15C220C968500A2F9F9 /* HBQueueItem.m */,
A9D3634F2209C08500D8EFEA /* HBQueueItemView.h */,
A9D363502209C08500D8EFEA /* HBQueueItemView.m */,
A9EA43661A2210C400785E95 /* HBTableView.h */,
children = (
A9706CB21AC1436F00BAEAA8 /* HBApplication.h */,
A9706CB31AC1436F00BAEAA8 /* HBApplication.m */,
+ A95BA15F220CA5DB00A2F9F9 /* HBDistributedArray.h */,
+ A95BA160220CA5DB00A2F9F9 /* HBDistributedArray.m */,
A9706CB51AC1437800BAEAA8 /* HBExceptionAlertController.h */,
A9706CB61AC1437800BAEAA8 /* HBExceptionAlertController.m */,
A9E52CD6218DD52A00E17B86 /* ExceptionAlert.xib */,
children = (
A98C29C51977C00000AF5DED /* Core */,
A952392E199A647F00588AEF /* Presets */,
- A9E66D6E1A67A2A8007B641D /* HBDistributedArray.h */,
- A9E66D6F1A67A2A8007B641D /* HBDistributedArray.m */,
A9AA44781970664A00D7DEFC /* HBUtilities.h */,
A9AA44791970664A00D7DEFC /* HBUtilities.m */,
A9736F041C7DA5FE008F1D18 /* HandBrakeKit.h */,
A91CE2DB1C7DAEEE0068F46F /* HBVideo.h in Headers */,
A91CE2DC1C7DAEEE0068F46F /* HBPicture.h in Headers */,
A91CE2DD1C7DAEEE0068F46F /* HBFilters.h in Headers */,
- A91119A51C7DD644001C463C /* HBDistributedArray.h in Headers */,
A91CE2DE1C7DAEEE0068F46F /* HBChapter.h in Headers */,
A91CE2DF1C7DAEEE0068F46F /* HBAudio.h in Headers */,
A91CE2E01C7DAEEE0068F46F /* HBAudioTrack.h in Headers */,
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ A95BA161220CA5DB00A2F9F9 /* HBDistributedArray.m in Sources */,
A916C99B1C844A0800C7B560 /* HBTableView.m in Sources */,
A916C9991C8449E200C7B560 /* main.mm in Sources */,
A973E10C216E74E900D498EC /* HBThumbnailItemView.m in Sources */,
273F20B214ADBE670021BE6D /* HBImageAndTextCell.m in Sources */,
273F20B314ADBE670021BE6D /* HBOutputPanelController.m in Sources */,
273F20B414ADBE670021BE6D /* HBOutputRedirect.m in Sources */,
+ A95BA15D220C968500A2F9F9 /* HBQueueItem.m in Sources */,
A9D0FA771C1C284D0003F2A9 /* HBFocusRingView.m in Sources */,
A9D0FA7A1C1C36820003F2A9 /* HBTabView.m in Sources */,
A91AFD0C1A948827009BECED /* HBOutputFileWriter.m in Sources */,
A91CE2A21C7DA7320068F46F /* HBVideo+UIAdditions.m in Sources */,
A91CE2A41C7DA7320068F46F /* HBPicture+UIAdditions.m in Sources */,
A91D54881E378ABD006D0997 /* HBSecurityAccessToken.m in Sources */,
- A91119A61C7DD64A001C463C /* HBDistributedArray.m in Sources */,
A91CE2A61C7DA7320068F46F /* HBFilters+UIAdditions.m in Sources */,
A91CE2A81C7DA7320068F46F /* HBDVDDetector.m in Sources */,
A91CE2AD1C7DA7320068F46F /* HBStateFormatter.m in Sources */,