X-Git-Url: https://git.yukkurigames.com/?p=enjoyable.git;a=blobdiff_plain;f=NJMappingsController.m;h=45085b5c79dc56abb97c1c7f2e494c753e9a276c;hp=cb5baf11a3a6d726d5950183e1ae5de01b8939cf;hb=b8c30e0c06effb8f4a937378e5c4cf8a22f40c59;hpb=a2cc76128896f61d5f5cc4039c0dcbb1b6cdff23 diff --git a/NJMappingsController.m b/NJMappingsController.m index cb5baf1..45085b5 100644 --- a/NJMappingsController.m +++ b/NJMappingsController.m @@ -18,6 +18,7 @@ @implementation NJMappingsController { NSMutableArray *_mappings; NJMapping *manualMapping; + NSString *draggingName; } - (id)init { @@ -31,7 +32,8 @@ } - (void)awakeFromNib { - [tableView registerForDraggedTypes:@[PB_ROW]]; + [tableView registerForDraggedTypes:@[PB_ROW, NSURLPboardType]]; + [tableView setDraggingSourceOperationMask:NSDragOperationCopy forLocal:NO]; } - (NJMapping *)objectForKeyedSubscript:(NSString *)name { @@ -114,12 +116,13 @@ if (tableView.selectedRow == 0) return; - [_mappings removeObjectAtIndex:tableView.selectedRow]; - [self activateMapping:_mappings[0]]; + NSInteger selectedRow = tableView.selectedRow; + [_mappings removeObjectAtIndex:selectedRow]; + [self activateMapping:_mappings[MIN(selectedRow, _mappings.count - 1)]]; [self mappingsChanged]; } --(void)tableViewSelectionDidChange:(NSNotification *)notify { +- (void)tableViewSelectionDidChange:(NSNotification *)notify { [self activateMapping:self[tableView.selectedRow]]; } @@ -217,6 +220,67 @@ return mapping; } +- (void)addMappingWithContentsOfURL:(NSURL *)url { + NSWindow *window = popoverActivate.window; + NSError *error; + NJMapping *mapping = [NJMapping mappingWithContentsOfURL:url + mappings:_mappings + error:&error]; + + if (mapping && !error) { + BOOL conflict = NO; + NJMapping *mergeInto = self[mapping.name]; + for (id key in mapping.entries) { + if (mergeInto.entries[key] + && ![mergeInto.entries[key] isEqual:mapping.entries[key]]) { + conflict = YES; + break; + } + } + + if (conflict) { + NSAlert *conflictAlert = [[NSAlert alloc] init]; + conflictAlert.messageText = @"Replace existing mappings?"; + conflictAlert.informativeText = + [NSString stringWithFormat: + @"This file contains inputs you've already mapped in \"%@\". Do you " + @"want to merge them and replace your existing mappings, or import this " + @"as a separate mapping?", mapping.name]; + [conflictAlert addButtonWithTitle:@"Merge"]; + [conflictAlert addButtonWithTitle:@"Cancel"]; + [conflictAlert addButtonWithTitle:@"New Mapping"]; + NSInteger res = [conflictAlert runModal]; + if (res == NSAlertSecondButtonReturn) + return; + else if (res == NSAlertThirdButtonReturn) + mergeInto = nil; + } + + if (mergeInto) { + [mergeInto.entries addEntriesFromDictionary:mapping.entries]; + mapping = mergeInto; + } else { + [_mappings addObject:mapping]; + } + + [self activateMapping:mapping]; + [self mappingsChanged]; + + if (conflict && !mergeInto) { + [tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:_mappings.count - 1] byExtendingSelection:NO]; + [tableView editColumn:0 row:_mappings.count - 1 withEvent:nil select:YES]; + } + } + + if (error) { + [window presentError:error + modalForWindow:window + delegate:nil + didPresentSelector:nil + contextInfo:nil]; + } +} + - (void)importPressed:(id)sender { NSOpenPanel *panel = [NSOpenPanel openPanel]; panel.allowedFileTypes = @[ @"enjoyable", @"json", @"txt" ]; @@ -225,65 +289,10 @@ completionHandler:^(NSInteger result) { if (result != NSFileHandlingPanelOKButton) return; - [panel close]; - NSError *error; - NJMapping *mapping = [self mappingWithURL:panel.URL error:&error]; - - if (!error) { - BOOL conflict = NO; - NJMapping *mergeInto = self[mapping.name]; - for (id key in mapping.entries) { - if (mergeInto.entries[key] - && ![mergeInto.entries[key] isEqual:mapping.entries[key]]) { - conflict = YES; - break; - } - } - - if (conflict) { - NSAlert *conflictAlert = [[NSAlert alloc] init]; - conflictAlert.messageText = @"Replace existing mappings?"; - conflictAlert.informativeText = - [NSString stringWithFormat: - @"This file contains inputs you've already mapped in \"%@\". Do you " - @"want to merge them and replace your existing mappings, or import this " - @"as a separate mapping?", mapping.name]; - [conflictAlert addButtonWithTitle:@"Merge"]; - [conflictAlert addButtonWithTitle:@"Cancel"]; - [conflictAlert addButtonWithTitle:@"New Mapping"]; - NSInteger res = [conflictAlert runModal]; - if (res == NSAlertSecondButtonReturn) - return; - else if (res == NSAlertThirdButtonReturn) - mergeInto = nil; - } - - if (mergeInto) { - [mergeInto.entries addEntriesFromDictionary:mapping.entries]; - mapping = mergeInto; - } else { - [_mappings addObject:mapping]; - } - - [self activateMapping:mapping]; - [self mappingsChanged]; - - if (conflict && !mergeInto) { - [tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:_mappings.count - 1] byExtendingSelection:NO]; - [tableView editColumn:0 row:_mappings.count - 1 withEvent:nil select:YES]; - } - } - - if (error) { - [window presentError:error - modalForWindow:window - delegate:nil - didPresentSelector:nil - contextInfo:nil]; - } + [self addMappingWithContentsOfURL:panel.URL]; }]; - + } - (void)exportPressed:(id)sender { @@ -297,16 +306,8 @@ if (result != NSFileHandlingPanelOKButton) return; [panel close]; - [NSProcessInfo.processInfo disableSuddenTermination]; NSError *error; - NSDictionary *serialization = [mapping serialize]; - NSData *json = [NSJSONSerialization dataWithJSONObject:serialization - options:NSJSONWritingPrettyPrinted - error:&error]; - if (!error) - [json writeToURL:panel.URL options:NSDataWritingAtomic error:&error]; - - [NSProcessInfo.processInfo enableSuddenTermination]; + [mapping writeToURL:panel.URL error:&error]; if (error) { [window presentError:error modalForWindow:window @@ -318,7 +319,9 @@ } - (IBAction)mappingPressed:(id)sender { - [popover showRelativeToRect:popoverActivate.bounds ofView:popoverActivate preferredEdge:NSMinXEdge]; + [popover showRelativeToRect:popoverActivate.bounds + ofView:popoverActivate + preferredEdge:NSMinXEdge]; } - (void)popoverWillShow:(NSNotification *)notification { @@ -345,7 +348,7 @@ } } -- (BOOL)tableView:(NSTableView *)tableView +- (BOOL)tableView:(NSTableView *)tableView_ acceptDrop:(id )info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)dropOperation { @@ -356,6 +359,20 @@ [_mappings moveObjectAtIndex:srcRow toIndex:row]; [self mappingsChanged]; return YES; + } else if ([pboard.types containsObject:NSURLPboardType]) { + NSURL *url = [NSURL URLFromPasteboard:pboard]; + NSError *error; + NJMapping *mapping = [NJMapping mappingWithContentsOfURL:url + mappings:_mappings + error:&error]; + if (error) { + [tableView_ presentError:error]; + return NO; + } else { + [_mappings insertObject:mapping atIndex:row]; + [self mappingsChanged]; + return YES; + } } else { return NO; } @@ -368,23 +385,48 @@ NSPasteboard *pboard = [info draggingPasteboard]; if ([pboard.types containsObject:PB_ROW]) { [tableView_ setDropRow:MAX(1, row) dropOperation:NSTableViewDropAbove]; - return NSDragOperationGeneric; + return NSDragOperationMove; + } else if ([pboard.types containsObject:NSURLPboardType]) { + NSURL *url = [NSURL URLFromPasteboard:pboard]; + if ([url.pathExtension isEqualToString:@"enjoyable"]) { + [tableView_ setDropRow:MAX(1, row) dropOperation:NSTableViewDropAbove]; + return NSDragOperationCopy; + } else { + return NSDragOperationNone; + } } else { return NSDragOperationNone; } } -- (BOOL)tableView:(NSTableView *)tableView +- (NSArray *)tableView:(NSTableView *)tableView_ +namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination +forDraggedRowsWithIndexes:(NSIndexSet *)indexSet { + NJMapping *toSave = self[indexSet.firstIndex]; + NSString *filename = [[toSave.name stringByFixingPathComponent] + stringByAppendingPathExtension:@"enjoyable"]; + NSURL *dst = [dropDestination URLByAppendingPathComponent:filename]; + dst = [NSFileManager.defaultManager generateUniqueURLWithBase:dst]; + NSError *error; + if (![toSave writeToURL:dst error:&error]) { + [tableView_ presentError:error]; + return @[]; + } else { + return @[dst.lastPathComponent]; + } +} + +- (BOOL)tableView:(NSTableView *)tableView_ writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard { if (rowIndexes.count == 1 && rowIndexes.firstIndex != 0) { - [pboard declareTypes:@[PB_ROW] owner:nil]; + [pboard declareTypes:@[PB_ROW, NSFilesPromisePboardType] owner:nil]; [pboard setString:@(rowIndexes.firstIndex).stringValue forType:PB_ROW]; + [pboard setPropertyList:@[@"enjoyable"] forType:NSFilesPromisePboardType]; return YES; } else { return NO; } - } @end