diff options
Diffstat (limited to 'macosx/HBChapterTitlesController.m')
-rw-r--r-- | macosx/HBChapterTitlesController.m | 313 |
1 files changed, 313 insertions, 0 deletions
diff --git a/macosx/HBChapterTitlesController.m b/macosx/HBChapterTitlesController.m new file mode 100644 index 000000000..c4f6a6583 --- /dev/null +++ b/macosx/HBChapterTitlesController.m @@ -0,0 +1,313 @@ +/* ChapterTitles.m $ + + This file is part of the HandBrake source code. + Homepage: <http://handbrake.fr/>. + It may be used under the terms of the GNU General Public License. */ + +#import "HBChapterTitlesController.h" +#import "Controller.h" +#include "hb.h" + +@interface HBChapterTitlesController () <NSTableViewDataSource, NSTableViewDelegate> +{ + NSMutableArray *fChapterTitlesArray; + + IBOutlet NSTableView * fChapterTable; + IBOutlet NSButton * fLoadChaptersButton; + IBOutlet NSButton * fSaveChaptersButton; + IBOutlet NSButton * fCreateChaptersMarkers; + IBOutlet NSTableColumn * fChapterTableNameColumn; +} + +@end + +@implementation HBChapterTitlesController + +- (instancetype)init +{ + self = [super initWithNibName:@"ChaptersTitles" bundle:nil]; + if (self) + { + fChapterTitlesArray = [[[NSMutableArray alloc] init] retain]; + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(titleChanged:) name: HBTitleChangedNotification object: nil]; + } + return self; +} + +- (void)dealloc +{ + [fChapterTitlesArray release]; + [super dealloc]; +} + +- (void)titleChanged:(NSNotification *)aNotification +{ + NSDictionary *notDict = [aNotification userInfo]; + NSData *theData = [notDict objectForKey: keyTitleTag]; + hb_title_t *title = NULL; + + [theData getBytes: &title length: sizeof(title)]; + + [fChapterTitlesArray removeAllObjects]; + + if (title) + { + for (int i = 0; i < hb_list_count(title->job->list_chapter); i++) + { + hb_chapter_t *chapter = hb_list_item(title->job->list_chapter, i); + if (chapter != NULL) + { + if (chapter->title != NULL) + { + [fChapterTitlesArray addObject:[NSString + stringWithFormat:@"%s", + chapter->title]]; + } + else + { + [fChapterTitlesArray addObject:[NSString + stringWithFormat:@"Chapter %d", + i + 1]]; + } + } + } + } + + [fChapterTable reloadData]; +} + +- (void)addChaptersFromQueue:(NSMutableArray *)newChaptersArray +{ + [fChapterTitlesArray removeAllObjects]; + [fChapterTitlesArray addObjectsFromArray:newChaptersArray]; + [fChapterTable reloadData]; +} + +- (void)enableUI:(BOOL)b +{ + [fCreateChaptersMarkers setEnabled:b]; + [fChapterTable setEnabled:b]; + [fLoadChaptersButton setEnabled:b]; + [fSaveChaptersButton setEnabled:b]; +} + +- (NSArray *)chapterTitlesArray +{ + return [NSArray arrayWithArray:fChapterTitlesArray]; +} + +- (IBAction)createChapterMarkersChanged:(id)sender +{ + [[NSNotificationCenter defaultCenter] postNotificationName:HBMixdownChangedNotification object:self]; +} + +- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView +{ + return [fChapterTitlesArray count]; +} + +- (void)tableView:(NSTableView *)aTableView + setObjectValue:(id)anObject + forTableColumn:(NSTableColumn *)aTableColumn + row:(NSInteger)rowIndex +{ + if (aTableColumn != nil && [[aTableColumn identifier] intValue] == 2) + { + [fChapterTitlesArray replaceObjectAtIndex:rowIndex + withObject:[NSString + stringWithString:anObject]]; + } +} + +- (id)tableView:(NSTableView *)aTableView + objectValueForTableColumn:(NSTableColumn *)aTableColumn + row:(NSInteger)rowIndex +{ + if ([[aTableColumn identifier] intValue] == 1) + { + return [NSString stringWithFormat:@"%ld", rowIndex + 1]; + } + else + { + return [NSString stringWithString:[fChapterTitlesArray + objectAtIndex:rowIndex]]; + } + return @"__DATA ERROR__"; +} + +/* Method to edit the next chapter when the user presses Return. We have to use +a timer to avoid interfering with the chain of events that handles the edit. */ +- (void)controlTextDidEndEditing: (NSNotification *) notification +{ + NSTableView *chapterTable = [notification object]; + NSInteger column = [chapterTable editedColumn]; + NSInteger row = [chapterTable editedRow]; + NSInteger textMovement; + + // Edit the cell in the next row, same column + row++; + textMovement = [[[notification userInfo] objectForKey:@"NSTextMovement"] integerValue]; + if( textMovement == NSReturnTextMovement && row < [chapterTable numberOfRows] ) + { + NSArray *info = [NSArray arrayWithObjects:chapterTable, + [NSNumber numberWithInteger:column], [NSNumber numberWithInteger:row], nil]; + /* The delay is unimportant; editNextRow: won't be called until the responder + chain finishes because the event loop containing the timer is on this thread */ + [self performSelector:@selector(editNextRow:) withObject:info afterDelay:0.0]; + } +} + +- (void)editNextRow: (id) objects +{ + NSTableView *chapterTable = [objects objectAtIndex:0]; + NSInteger column = [[objects objectAtIndex:1] integerValue]; + NSInteger row = [[objects objectAtIndex:2] integerValue]; + + if( row >= 0 && row < [chapterTable numberOfRows] ) + { + [chapterTable selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO]; + [chapterTable editColumn:column row:row withEvent:nil select:YES]; + } +} + +#pragma mark - +#pragma mark Chapter Files Import / Export + +- (IBAction) browseForChapterFile: (id) sender +{ + /* We get the current file name and path from the destination field here */ + NSString *sourceDirectory = [[NSUserDefaults standardUserDefaults] stringForKey:@"LastDestinationDirectory"]; + + /* Open a panel to let the user choose the file */ + NSOpenPanel *panel = [NSOpenPanel openPanel]; + [panel setDirectoryURL:[NSURL fileURLWithPath:sourceDirectory]]; + [panel setAllowedFileTypes:@[@"csv"]]; + + [panel beginSheetModalForWindow:[[self view] window] completionHandler:^(NSInteger result) { + NSArray *chaptersArray = nil; /* temp array for chapters */ + NSMutableArray *chaptersMutableArray = nil; /* temp array for chapters */ + NSString *chapterName = nil; /* temp string from file */ + NSInteger chapters, i; + + if (result == NSOKButton) /* if they click OK */ + { + chapterName = [[NSString alloc] initWithContentsOfURL:[panel URL] encoding:NSUTF8StringEncoding error:NULL]; + chaptersArray = [chapterName componentsSeparatedByString:@"\n"]; + [chapterName release]; + chaptersMutableArray = [[chaptersArray mutableCopy] autorelease]; + chapters = [self numberOfRowsInTableView:fChapterTable]; + if ([chaptersMutableArray count] > 0) + { + /* if last item is empty remove it */ + if ([[chaptersMutableArray objectAtIndex:[chaptersArray count]-1] length] == 0) + { + [chaptersMutableArray removeLastObject]; + } + } + /* if chapters in table is not equal to array count */ + if ((unsigned int) chapters != [chaptersMutableArray count]) + { + [panel close]; + [[NSAlert alertWithMessageText:NSLocalizedString(@"Unable to load chapter file", @"Unable to load chapter file") + defaultButton:NSLocalizedString(@"OK", @"OK") + alternateButton:NULL + otherButton:NULL + informativeTextWithFormat:NSLocalizedString(@"%d chapters expected, %d chapters found in %@", @"%d chapters expected, %d chapters found in %@"), + chapters, [chaptersMutableArray count], [[panel URL] lastPathComponent]] runModal]; + return; + } + /* otherwise, go ahead and populate table with array */ + for (i=0; i<chapters; i++) + { + + if([[chaptersMutableArray objectAtIndex:i] length] > 5) + { + /* avoid a segfault */ + /* Get the Range.location of the first comma in the line and then put everything after that into chapterTitle */ + NSRange firstCommaRange = [[chaptersMutableArray objectAtIndex:i] rangeOfString:@","]; + NSString *chapterTitle = [[chaptersMutableArray objectAtIndex:i] substringFromIndex:firstCommaRange.location + 1]; + /* Since we store our chapterTitle commas as "\," for the cli, we now need to remove the escaping "\" from the title */ + chapterTitle = [chapterTitle stringByReplacingOccurrencesOfString:@"\\," withString:@","]; + [self tableView:fChapterTable + setObjectValue:chapterTitle + forTableColumn:fChapterTableNameColumn + row:i]; + } + else + { + [panel close]; + [[NSAlert alertWithMessageText:NSLocalizedString(@"Unable to load chapter file", @"Unable to load chapter file") + defaultButton:NSLocalizedString(@"OK", @"OK") + alternateButton:NULL + otherButton:NULL + informativeTextWithFormat:NSLocalizedString(@"%@ was not formatted as expected.", @"%@ was not formatted as expected."), [[panel URL] lastPathComponent]] runModal]; + [fChapterTable reloadData]; + return; + } + } + [fChapterTable reloadData]; + } + }]; +} + +- (IBAction) browseForChapterFileSave: (id) sender +{ + NSString *destinationDirectory = [[NSUserDefaults standardUserDefaults] stringForKey:@"LastDestinationDirectory"]; + + /* Open a panel to let the user save to a file */ + NSSavePanel *panel = [NSSavePanel savePanel]; + [panel setAllowedFileTypes:@[@"csv"]]; + [panel setDirectoryURL:[NSURL fileURLWithPath:destinationDirectory]]; + //[panel setNameFieldStringValue:[[[fDstFile2Field stringValue] lastPathComponent] stringByDeletingPathExtension]]; + + [panel beginSheetModalForWindow:[[self view] window] completionHandler:^(NSInteger result) { + NSString *chapterName; /* pointer for string for later file-writing */ + NSString *chapterTitle; + NSError *saveError = nil; + NSInteger chapters, i; /* ints for the number of chapters in the table and the loop */ + + if( result == NSOKButton ) /* if they clicked OK */ + { + chapters = [self numberOfRowsInTableView:fChapterTable]; + chapterName = [NSString string]; + for (i=0; i<chapters; i++) + { + /* put each chapter title from the table into the array */ + if (i<9) + { /* if i is from 0 to 8 (chapters 1 to 9) add two leading zeros */ + chapterName = [chapterName stringByAppendingFormat:@"00%ld,",i+1]; + } + else if (i<99) + { /* if i is from 9 to 98 (chapters 10 to 99) add one leading zero */ + chapterName = [chapterName stringByAppendingFormat:@"0%ld,",i+1]; + } + else if (i<999) + { /* in case i is from 99 to 998 (chapters 100 to 999) no leading zeros */ + chapterName = [chapterName stringByAppendingFormat:@"%ld,",i+1]; + } + + chapterTitle = [self tableView:fChapterTable objectValueForTableColumn:fChapterTableNameColumn row:i]; + /* escape any commas in the chapter name with "\," */ + chapterTitle = [chapterTitle stringByReplacingOccurrencesOfString:@"," withString:@"\\,"]; + chapterName = [chapterName stringByAppendingString:chapterTitle]; + if (i+1 != chapters) + { /* if not the last chapter */ + chapterName = [chapterName stringByAppendingString:@ "\n"]; + } + + + } + /* try to write it to where the user wanted */ + if (![chapterName writeToURL:[panel URL] + atomically:NO + encoding:NSUTF8StringEncoding + error:&saveError]) + { + [panel close]; + [[NSAlert alertWithError:saveError] runModal]; + } + } + }]; +} + +@end |