X-Git-Url: https://git.yukkurigames.com/?p=enjoyable.git;a=blobdiff_plain;f=ConfigsController.m;h=d38ada85fed674d0dc2fe8e2c93bc3959f8a11c1;hp=d0d8401c9699e2baca65caa6c0a3123e3b2f9a99;hb=aaab00fd866af505e9a5e454f1aeb3e298fd38e3;hpb=b0e48a152d139c0b9aeb1ee4a32ba24a4e3aa805 diff --git a/ConfigsController.m b/ConfigsController.m index d0d8401..d38ada8 100644 --- a/ConfigsController.m +++ b/ConfigsController.m @@ -50,14 +50,14 @@ _currentConfig = config; [removeButton setEnabled:_configs[0] != config]; [targetController loadCurrent]; - [(ApplicationController *)[[NSApplication sharedApplication] delegate] configChanged]; + [(ApplicationController *)NSApplication.sharedApplication.delegate configChanged]; [tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:[_configs indexOfObject:config]] byExtendingSelection:NO]; } - (IBAction)addPressed:(id)sender { Config *newConfig = [[Config alloc] initWithName:@"Untitled"]; [_configs addObject:newConfig]; - [(ApplicationController *)[[NSApplication sharedApplication] delegate] configsChanged]; + [(ApplicationController *)NSApplication.sharedApplication.delegate configsChanged]; [tableView reloadData]; [tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:_configs.count - 1] byExtendingSelection:NO]; [tableView editColumn:0 row:_configs.count - 1 withEvent:nil select:YES]; @@ -69,7 +69,7 @@ [_configs removeObjectAtIndex:tableView.selectedRow]; [tableView reloadData]; - [(ApplicationController *)[[NSApplication sharedApplication] delegate] configsChanged]; + [(ApplicationController *)NSApplication.sharedApplication.delegate configsChanged]; [self activateConfig:_configs[0]]; [self save]; } @@ -86,7 +86,7 @@ - (void)tableView:(NSTableView *)view setObjectValue:(NSString *)obj forTableColumn:(NSTableColumn *)col row:(NSInteger)index { [(Config *)_configs[index] setName:obj]; [tableView reloadData]; - [(ApplicationController *)[[NSApplication sharedApplication] delegate] configsChanged]; + [(ApplicationController *)NSApplication.sharedApplication.delegate configsChanged]; } - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView { @@ -99,11 +99,11 @@ - (void)save { NSLog(@"Saving defaults."); - [[NSUserDefaults standardUserDefaults] setObject:[self dumpAll] forKey:@"configurations"]; + [NSUserDefaults.standardUserDefaults setObject:[self dumpAll] forKey:@"configurations"]; } - (void)load { - [self loadAllFrom:[[NSUserDefaults standardUserDefaults] objectForKey:@"configurations"]]; + [self loadAllFrom:[NSUserDefaults.standardUserDefaults objectForKey:@"configurations"]]; } - (NSDictionary *)dumpAll { @@ -141,100 +141,140 @@ current = 0; _configs = newConfigs; [tableView reloadData]; - [(ApplicationController *)[[NSApplication sharedApplication] delegate] configsChanged]; + [(ApplicationController *)NSApplication.sharedApplication.delegate configsChanged]; [self activateConfig:_configs[current]]; } } +- (Config *)configWithURL:(NSURL *)url error:(NSError **)error { + NSInputStream *stream = [NSInputStream inputStreamWithURL:url]; + [stream open]; + NSDictionary *serialization = !*error + ? [NSJSONSerialization JSONObjectWithStream:stream options:0 error:error] + : nil; + [stream close]; + + if (!([serialization isKindOfClass:NSDictionary.class] + && [serialization[@"name"] isKindOfClass:NSString.class] + && [serialization[@"entries"] isKindOfClass:NSDictionary.class])) { + *error = [NSError errorWithDomain:@"Enjoyable" + code:0 + description:@"This isn't a valid mapping file."]; + return nil; + } + + NSDictionary *entries = serialization[@"entries"]; + Config *cfg = [[Config alloc] initWithName:serialization[@"name"]]; + for (id key in entries) { + NSDictionary *value = entries[key]; + if ([key isKindOfClass:NSString.class]) { + Target *target = [Target targetDeserialize:value + withConfigs:_configs]; + if (target) + cfg.entries[key] = target; + } + } + return cfg; +} + - (void)importPressed:(id)sender { NSOpenPanel *panel = [NSOpenPanel openPanel]; panel.allowedFileTypes = @[ @"enjoyable", @"json", @"txt" ]; - if ([panel runModal] == NSFileHandlingPanelOKButton) { - NSError *error; - NSInputStream *stream = [NSInputStream inputStreamWithURL:panel.URL]; - [stream open]; - NSDictionary *serialization = !error - ? [NSJSONSerialization JSONObjectWithStream:stream options:0 error:&error] - : nil; - [stream close]; - - if (!([serialization isKindOfClass:[NSDictionary class]] - && serialization[@"entries"])) { - error = [NSError errorWithDomain:@"Enjoyable" - code:0 - description:@"This isn't a valid mapping file."]; - } - - - if (!error) { - NSDictionary *entries = serialization[@"entries"]; - Config *cfg = [[Config alloc] initWithName:serialization[@"name"]]; - Config *mergeInto = self[cfg.name]; - BOOL conflict = NO; - for (id key in entries) { - cfg.entries[key] = [Target targetDeserialize:entries[key] - withConfigs:_configs]; - if (mergeInto.entries[key]) - conflict = YES; - } - - 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?", cfg.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:cfg.entries]; - cfg = mergeInto; - } else { - [_configs addObject:cfg]; - [tableView reloadData]; - } - - [self save]; - [(ApplicationController *)[[NSApplication sharedApplication] delegate] configsChanged]; - [self activateConfig:cfg]; - [targetController loadCurrent]; - - if (conflict && !mergeInto) { - [tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:_configs.count - 1] byExtendingSelection:NO]; - [tableView editColumn:0 row:_configs.count - 1 withEvent:nil select:YES]; - } - } - - if (error) - [[NSAlert alertWithError:error] runModal]; - } + NSWindow *window = NSApplication.sharedApplication.keyWindow; + [panel beginSheetModalForWindow:window + completionHandler:^(NSInteger result) { + if (result != NSFileHandlingPanelOKButton) + return; + + [panel close]; + NSError *error; + Config *cfg = [self configWithURL:panel.URL error:&error]; + + if (!error) { + BOOL conflict; + Config *mergeInto = self[cfg.name]; + for (id key in cfg.entries) { + if (mergeInto.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?", cfg.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:cfg.entries]; + cfg = mergeInto; + } else { + [_configs addObject:cfg]; + [tableView reloadData]; + } + + [self save]; + [(ApplicationController *)NSApplication.sharedApplication.delegate configsChanged]; + [self activateConfig:cfg]; + [targetController loadCurrent]; + + if (conflict && !mergeInto) { + [tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:_configs.count - 1] byExtendingSelection:NO]; + [tableView editColumn:0 row:_configs.count - 1 withEvent:nil select:YES]; + } + } + + if (error) { + [window presentError:error + modalForWindow:window + delegate:nil + didPresentSelector:nil + contextInfo:nil]; + } + }]; + } - (void)exportPressed:(id)sender { NSSavePanel *panel = [NSSavePanel savePanel]; panel.allowedFileTypes = @[ @"enjoyable" ]; - if ([panel runModal] == NSFileHandlingPanelOKButton) { - NSError *error; - NSDictionary *serialization = [_currentConfig serialize]; - NSData *json = [NSJSONSerialization dataWithJSONObject:serialization - options:NSJSONWritingPrettyPrinted - error:&error]; - if (!error) - [json writeToURL:panel.URL options:NSDataWritingAtomic error:&error]; - - if (error) - [[NSAlert alertWithError:error] runModal]; - } + Config *cfg = _currentConfig; + panel.nameFieldStringValue = cfg.name; + NSWindow *window = NSApplication.sharedApplication.keyWindow; + [panel beginSheetModalForWindow:window + completionHandler:^(NSInteger result) { + if (result != NSFileHandlingPanelOKButton) + return; + [panel close]; + NSError *error; + NSDictionary *serialization = [cfg serialize]; + NSData *json = [NSJSONSerialization dataWithJSONObject:serialization + options:NSJSONWritingPrettyPrinted + error:&error]; + if (!error) + [json writeToURL:panel.URL options:NSDataWritingAtomic error:&error]; + + if (error) { + [window presentError:error + modalForWindow:window + delegate:nil + didPresentSelector:nil + contextInfo:nil]; + } + }]; } @end