From 4a8e67a7294e8e527e2be9d8f5f39aae60691697 Mon Sep 17 00:00:00 2001 From: Joe Wreschnig Date: Mon, 18 Mar 2013 01:41:19 +0100 Subject: [PATCH] View-free NJMappingsController. --- Classes/EnjoyableApplicationDelegate.h | 3 + Classes/EnjoyableApplicationDelegate.m | 129 ++++++++++++++++++++++- Classes/NJMappingsController.h | 11 +- Classes/NJMappingsController.m | 136 +++---------------------- Classes/NJMappingsViewController.h | 6 +- Classes/NJMappingsViewController.m | 16 ++- Info.plist | 2 +- Other Sources/NJEvents.h | 1 + Resources/English.lproj/MainMenu.xib | 64 +++++------- 9 files changed, 194 insertions(+), 174 deletions(-) diff --git a/Classes/EnjoyableApplicationDelegate.h b/Classes/EnjoyableApplicationDelegate.h index b28269b..dbc17ee 100644 --- a/Classes/EnjoyableApplicationDelegate.h +++ b/Classes/EnjoyableApplicationDelegate.h @@ -9,8 +9,10 @@ @class NJMappingsController; #import "NJMappingMenuController.h" +#import "NJMappingsViewController.h" @interface EnjoyableApplicationDelegate : NSObject { IBOutlet NSMenu *dockMenu; @@ -19,6 +21,7 @@ } @property (nonatomic, strong) IBOutlet NJMappingsController *mappingsController; +@property (nonatomic, strong) IBOutlet NJMappingsViewController *mvc; - (IBAction)restoreToForeground:(id)sender; - (IBAction)importMappingClicked:(id)sender; diff --git a/Classes/EnjoyableApplicationDelegate.m b/Classes/EnjoyableApplicationDelegate.m index 9fef7c3..7c9ae7e 100644 --- a/Classes/EnjoyableApplicationDelegate.m +++ b/Classes/EnjoyableApplicationDelegate.m @@ -41,6 +41,10 @@ object:nil]; [self.mappingsController load]; + [self.mvc.mappingList reloadData]; + [self.mvc changedActiveMappingToIndex: + [self.mappingsController indexOfMapping: + self.mappingsController.currentMapping]]; statusItem = [NSStatusBar.systemStatusBar statusItemWithLength:36]; statusItem.image = [NSImage imageNamed:@"Status Menu Icon Disabled"]; @@ -122,6 +126,9 @@ } - (void)mappingDidChange:(NSNotification *)note { + NSUInteger idx = [note.userInfo[NJMappingIndexKey] intValue]; + [self.mvc changedActiveMappingToIndex:idx]; + if (!window.isVisible) for (int i = 0; i < 4; ++i) [self performSelector:@selector(flashStatusItem) @@ -140,7 +147,7 @@ NJMapping *mapping = [NJMapping mappingWithContentsOfURL:URL error:&error]; if ([self.mappingsController[mapping.name] hasConflictWith:mapping]) { - [self.mappingsController promptForMapping:mapping atIndex:self.mappingsController.count]; + [self promptForMapping:mapping atIndex:self.mappingsController.count]; } else if (self.mappingsController[mapping.name]) { [self.mappingsController[mapping.name] mergeEntriesFrom:mapping]; } else if (mapping) { @@ -161,7 +168,7 @@ - (void)mappingListShouldOpen { [self restoreToForeground:self]; - [self.mappingsController.mvc mappingTriggerClicked:self]; + [self.mvc mappingTriggerClicked:self]; } - (void)loginItemPromptDidEnd:(NSWindow *)sheet @@ -217,7 +224,7 @@ NJMapping *mapping = [NJMapping mappingWithContentsOfURL:panel.URL error:&error]; if ([self.mappingsController[mapping.name] hasConflictWith:mapping]) { - [self.mappingsController promptForMapping:mapping atIndex:self.mappingsController.count]; + [self promptForMapping:mapping atIndex:self.mappingsController.count]; } else if (self.mappingsController[mapping.name]) { [self.mappingsController[mapping.name] mergeEntriesFrom:mapping]; } else if (mapping) { @@ -254,6 +261,122 @@ }]; } +- (void)mappingConflictDidResolve:(NSAlert *)alert + returnCode:(NSInteger)returnCode + contextInfo:(void *)contextInfo { + NSDictionary *userInfo = CFBridgingRelease(contextInfo); + NJMapping *oldMapping = userInfo[@"old mapping"]; + NJMapping *newMapping = userInfo[@"new mapping"]; + NSInteger idx = [userInfo[@"index"] intValue]; + [alert.window orderOut:nil]; + switch (returnCode) { + case NSAlertFirstButtonReturn: // Merge + [self.mappingsController mergeMapping:newMapping intoMapping:oldMapping]; + [self.mappingsController activateMapping:oldMapping]; + break; + case NSAlertThirdButtonReturn: // New Mapping + [self.mvc beginUpdates]; + [self.mappingsController addMapping:newMapping]; + [self.mvc addedMappingAtIndex:idx startEditing:YES]; + [self.mvc endUpdates]; + [self.mappingsController activateMapping:newMapping]; + break; + default: // Cancel, other. + break; + } +} + +- (void)promptForMapping:(NJMapping *)mapping atIndex:(NSInteger)idx { + NJMapping *mergeInto = self.mappingsController[mapping.name]; + NSAlert *conflictAlert = [[NSAlert alloc] init]; + conflictAlert.messageText = NSLocalizedString(@"import conflict prompt", @"Title of import conflict alert"); + conflictAlert.informativeText = + [NSString stringWithFormat:NSLocalizedString(@"import conflict in %@", @"Explanation of import conflict"), + mapping.name]; + [conflictAlert addButtonWithTitle:NSLocalizedString(@"import and merge", @"button to merge imported mappings")]; + [conflictAlert addButtonWithTitle:NSLocalizedString(@"cancel import", @"button to cancel import")]; + [conflictAlert addButtonWithTitle:NSLocalizedString(@"import new mapping", @"button to import as new mapping")]; + [conflictAlert beginSheetModalForWindow:window + modalDelegate:self + didEndSelector:@selector(mappingConflictDidResolve:returnCode:contextInfo:) + contextInfo:(void *)CFBridgingRetain(@{ @"index": @(idx), + @"old mapping": mergeInto, + @"new mapping": mapping })]; +} + +- (NSInteger)numberOfMappings:(NJMappingsViewController *)mvc { + return self.mappingsController.count; +} + +- (NJMapping *)mappingsViewController:(NJMappingsViewController *)mvc + mappingForIndex:(NSUInteger)idx { + return self.mappingsController[idx]; +} + +- (void)mappingsViewController:(NJMappingsViewController *)mvc + renameMappingAtIndex:(NSInteger)index + toName:(NSString *)name { + [self.mappingsController renameMapping:self.mappingsController[index] + to:name]; +} + +- (BOOL)mappingsViewController:(NJMappingsViewController *)mvc + canMoveMappingFromIndex:(NSInteger)fromIdx + toIndex:(NSInteger)toIdx { + return fromIdx != toIdx && fromIdx != 0 && toIdx != 0 + && toIdx < (NSInteger)self.mappingsController.count; +} + +- (void)mappingsViewController:(NJMappingsViewController *)mvc + moveMappingFromIndex:(NSInteger)fromIdx + toIndex:(NSInteger)toIdx { + [mvc beginUpdates]; + [mvc.mappingList moveRowAtIndex:fromIdx toIndex:toIdx]; + [self.mappingsController moveMoveMappingFromIndex:fromIdx toIndex:toIdx]; + [mvc endUpdates]; +} + +- (BOOL)mappingsViewController:(NJMappingsViewController *)mvc + canRemoveMappingAtIndex:(NSInteger)idx { + return idx != 0; +} + +- (void)mappingsViewController:(NJMappingsViewController *)mvc + removeMappingAtIndex:(NSInteger)idx { + [mvc beginUpdates]; + [mvc removedMappingAtIndex:idx]; + [self.mappingsController removeMappingAtIndex:idx]; + [mvc endUpdates]; +} + +- (BOOL)mappingsViewController:(NJMappingsViewController *)mvc + importMappingFromURL:(NSURL *)url + atIndex:(NSInteger)index + error:(NSError **)error { + NJMapping *mapping = [NJMapping mappingWithContentsOfURL:url + error:error]; + if ([self.mappingsController[mapping.name] hasConflictWith:mapping]) { + [self promptForMapping:mapping atIndex:index]; + } else if (self.mappingsController[mapping.name]) { + [self.mappingsController[mapping.name] mergeEntriesFrom:mapping]; + } else if (mapping) { + [self.mappingsController insertMapping:mapping atIndex:index]; + } + return !!mapping; +} + +- (void)mappingsViewController:(NJMappingsViewController *)mvc + addMapping:(NJMapping *)mapping { + [mvc beginUpdates]; + [mvc addedMappingAtIndex:self.mappingsController.count startEditing:YES]; + [self.mappingsController addMapping:mapping]; + [mvc endUpdates]; + [self.mappingsController activateMapping:mapping]; +} +- (void)mappingsViewController:(NJMappingsViewController *)mvc + choseMappingAtIndex:(NSInteger)idx { + [self.mappingsController activateMapping:self.mappingsController[idx]]; +} @end diff --git a/Classes/NJMappingsController.h b/Classes/NJMappingsController.h index 85ba54f..83ed8ef 100644 --- a/Classes/NJMappingsController.h +++ b/Classes/NJMappingsController.h @@ -9,16 +9,11 @@ @class NJMapping; @class NJOutputController; -#import "NJMappingsViewController.h" - -@interface NJMappingsController : NSObject +@interface NJMappingsController : NSObject @property (nonatomic, readonly) NJMapping *currentMapping; @property (nonatomic, readonly) NSUInteger count; -@property (nonatomic, strong) IBOutlet NJMappingsViewController *mvc; - - (NJMapping *)objectForKeyedSubscript:(NSString *)name; - (NJMapping *)objectAtIndexedSubscript:(NSUInteger)idx; - (NSInteger)indexOfMapping:(NJMapping *)mapping; @@ -28,12 +23,10 @@ - (void)removeMappingAtIndex:(NSInteger)idx; - (void)mergeMapping:(NJMapping *)mapping intoMapping:(NJMapping *)existing; - (void)moveMoveMappingFromIndex:(NSInteger)fromIdx toIndex:(NSInteger)toIdx; +- (void)renameMapping:(NJMapping *)mapping to:(NSString *)name; - (void)mappingsChanged; -- (void)promptForMapping:(NJMapping *)mapping atIndex:(NSInteger)idx; - // FIXME: Doesn't belong here. - - (void)activateMapping:(NJMapping *)mapping; - (void)activateMappingForProcess:(NSRunningApplication *)app; - (void)save; diff --git a/Classes/NJMappingsController.m b/Classes/NJMappingsController.m index 2b08a52..8f0492c 100644 --- a/Classes/NJMappingsController.m +++ b/Classes/NJMappingsController.m @@ -8,7 +8,6 @@ #import "NJMappingsController.h" #import "NJMapping.h" -#import "NJMappingsController.h" #import "NJOutput.h" #import "NJEvents.h" @@ -48,7 +47,6 @@ object:self userInfo:@{ NJMappingListKey: _mappings, NJMappingKey: _currentMapping }]; - [self.mvc changedActiveMappingToIndex:[_mappings indexOfObjectIdenticalTo:_currentMapping]]; } - (void)mappingsChanged { @@ -97,11 +95,12 @@ NSLog(@"Switching to mapping %@.", mapping.name); _manualMapping = mapping; _currentMapping = mapping; - [self.mvc changedActiveMappingToIndex:[_mappings indexOfObjectIdenticalTo:_currentMapping]]; + NSUInteger idx = [_mappings indexOfObjectIdenticalTo:_currentMapping]; [NSNotificationCenter.defaultCenter postNotificationName:NJEventMappingChanged object:self - userInfo:@{ NJMappingKey : _currentMapping }]; + userInfo:@{ NJMappingKey : _currentMapping, + NJMappingIndexKey: @(idx) }]; } - (void)save { @@ -132,7 +131,6 @@ _mappings = newMappings; if (selected >= newMappings.count) selected = 0; - [self.mvc reloadData]; [self activateMapping:_mappings[selected]]; [self mappingsSet]; } @@ -146,7 +144,7 @@ [existing mergeEntriesFrom:mapping]; [self mappingsChanged]; if (existing == _currentMapping) { - // FIXME: Hack to trigger updates when renaming. + // FIXME: Hack to trigger updates in the rest of the UI. _currentMapping = nil; NJMapping *manual = _manualMapping; [self activateMapping:existing]; @@ -154,6 +152,18 @@ } } +- (void)renameMapping:(NJMapping *)mapping to:(NSString *)name { + mapping.name = name; + if (mapping == _currentMapping) { + // FIXME: Hack to trigger updates in the rest of the UI. + _currentMapping = nil; + NJMapping *manual = _manualMapping; + [self activateMapping:mapping]; + _manualMapping = manual; + } + [self mappingsChanged]; +} + - (void)addMapping:(NJMapping *)mapping { [self insertMapping:mapping atIndex:_mappings.count]; } @@ -179,118 +189,4 @@ return _mappings.count; } -- (void)mappingConflictDidResolve:(NSAlert *)alert - returnCode:(NSInteger)returnCode - contextInfo:(void *)contextInfo { - NSDictionary *userInfo = CFBridgingRelease(contextInfo); - NJMapping *oldMapping = userInfo[@"old mapping"]; - NJMapping *newMapping = userInfo[@"new mapping"]; - [alert.window orderOut:nil]; - switch (returnCode) { - case NSAlertFirstButtonReturn: // Merge - [self mergeMapping:newMapping intoMapping:oldMapping]; - [self activateMapping:oldMapping]; - break; - case NSAlertThirdButtonReturn: // New Mapping - [self.mvc.mappingList beginUpdates]; - [self addMapping:newMapping]; - [self.mvc addedMappingAtIndex:_mappings.count - 1 startEditing:YES]; - [self.mvc.mappingList endUpdates]; - [self activateMapping:newMapping]; - break; - default: // Cancel, other. - break; - } -} - -- (void)promptForMapping:(NJMapping *)mapping atIndex:(NSInteger)idx { - NSWindow *window = NSApplication.sharedApplication.keyWindow; - NJMapping *mergeInto = self[mapping.name]; - NSAlert *conflictAlert = [[NSAlert alloc] init]; - conflictAlert.messageText = NSLocalizedString(@"import conflict prompt", @"Title of import conflict alert"); - conflictAlert.informativeText = - [NSString stringWithFormat:NSLocalizedString(@"import conflict in %@", @"Explanation of import conflict"), - mapping.name]; - [conflictAlert addButtonWithTitle:NSLocalizedString(@"import and merge", @"button to merge imported mappings")]; - [conflictAlert addButtonWithTitle:NSLocalizedString(@"cancel import", @"button to cancel import")]; - [conflictAlert addButtonWithTitle:NSLocalizedString(@"import new mapping", @"button to import as new mapping")]; - [conflictAlert beginSheetModalForWindow:window - modalDelegate:self - didEndSelector:@selector(mappingConflictDidResolve:returnCode:contextInfo:) - contextInfo:(void *)CFBridgingRetain(@{ @"old mapping": mergeInto, - @"new mapping": mapping })]; -} - -- (NSInteger)numberOfMappings:(NJMappingsViewController *)mvc { - return self.count; -} - -- (NJMapping *)mappingsViewController:(NJMappingsViewController *)mvc - mappingForIndex:(NSUInteger)idx { - return self[idx]; -} - -- (void)mappingsViewController:(NJMappingsViewController *)mvc - editedMappingAtIndex:(NSInteger)index { - [self mappingsChanged]; -} - -- (BOOL)mappingsViewController:(NJMappingsViewController *)mvc - canMoveMappingFromIndex:(NSInteger)fromIdx - toIndex:(NSInteger)toIdx { - return fromIdx != toIdx && fromIdx != 0 && toIdx != 0; -} - -- (void)mappingsViewController:(NJMappingsViewController *)mvc - moveMappingFromIndex:(NSInteger)fromIdx - toIndex:(NSInteger)toIdx { - [mvc.mappingList beginUpdates]; - [mvc.mappingList moveRowAtIndex:fromIdx toIndex:toIdx]; - [self moveMoveMappingFromIndex:fromIdx toIndex:toIdx]; - [mvc.mappingList endUpdates]; -} - -- (BOOL)mappingsViewController:(NJMappingsViewController *)mvc - canRemoveMappingAtIndex:(NSInteger)idx { - return idx != 0; -} - -- (void)mappingsViewController:(NJMappingsViewController *)mvc - removeMappingAtIndex:(NSInteger)idx { - [mvc.mappingList beginUpdates]; - [mvc removedMappingAtIndex:idx]; - [self removeMappingAtIndex:idx]; - [mvc.mappingList endUpdates]; -} - -- (BOOL)mappingsViewController:(NJMappingsViewController *)mvc - importMappingFromURL:(NSURL *)url - atIndex:(NSInteger)index - error:(NSError **)error { - NJMapping *mapping = [NJMapping mappingWithContentsOfURL:url - error:error]; - if ([self[mapping.name] hasConflictWith:mapping]) { - [self promptForMapping:mapping atIndex:index]; - } else if (self[mapping.name]) { - [self[mapping.name] mergeEntriesFrom:mapping]; - } else if (mapping) { - [self insertMapping:mapping atIndex:index]; - } - return !!mapping; -} - -- (void)mappingsViewController:(NJMappingsViewController *)mvc - addMapping:(NJMapping *)mapping { - [mvc.mappingList beginUpdates]; - [mvc addedMappingAtIndex:_mappings.count startEditing:YES]; - [self addMapping:mapping]; - [mvc.mappingList endUpdates]; - [self activateMapping:mapping]; -} - -- (void)mappingsViewController:(NJMappingsViewController *)mvc - choseMappingAtIndex:(NSInteger)idx { - [self activateMapping:self[idx]]; -} - @end diff --git a/Classes/NJMappingsViewController.h b/Classes/NJMappingsViewController.h index 2d0bd25..8e1055a 100644 --- a/Classes/NJMappingsViewController.h +++ b/Classes/NJMappingsViewController.h @@ -34,6 +34,9 @@ - (void)changedActiveMappingToIndex:(NSInteger)index; - (void)reloadData; +- (void)beginUpdates; +- (void)endUpdates; + @end @@ -45,7 +48,8 @@ - (void)mappingsViewController:(NJMappingsViewController *)mvc - editedMappingAtIndex:(NSInteger)index; + renameMappingAtIndex:(NSInteger)index + toName:(NSString *)name; - (BOOL)mappingsViewController:(NJMappingsViewController *)mvc canMoveMappingFromIndex:(NSInteger)fromIdx diff --git a/Classes/NJMappingsViewController.m b/Classes/NJMappingsViewController.m index e7c28da..854c114 100644 --- a/Classes/NJMappingsViewController.m +++ b/Classes/NJMappingsViewController.m @@ -67,6 +67,15 @@ self.mappingListTrigger.state = NSOffState; } +- (void)beginUpdates { + [self.mappingList beginUpdates]; +} + +- (void)endUpdates { + [self.mappingList endUpdates]; + [self changedActiveMappingToIndex:self.mappingList.selectedRow]; +} + - (void)addedMappingAtIndex:(NSInteger)index startEditing:(BOOL)startEditing { [self.mappingList abortEditing]; [self.mappingList insertRowsAtIndexes:[[NSIndexSet alloc] initWithIndex:index] @@ -116,10 +125,9 @@ setObjectValue:(NSString *)obj forTableColumn:(NSTableColumn *)col row:(NSInteger)index { - NJMapping *mapping = [self.delegate mappingsViewController:self - mappingForIndex:index]; - mapping.name = obj; - [self.delegate mappingsViewController:self editedMappingAtIndex:index]; + [self.delegate mappingsViewController:self + renameMappingAtIndex:index + toName:obj]; } - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView { diff --git a/Info.plist b/Info.plist index a750109..98f8dd5 100644 --- a/Info.plist +++ b/Info.plist @@ -46,7 +46,7 @@ CFBundleSignature ???? CFBundleVersion - 502 + 517 LSApplicationCategoryType public.app-category.utilities NSHumanReadableCopyright diff --git a/Other Sources/NJEvents.h b/Other Sources/NJEvents.h index 204a270..646bbf6 100644 --- a/Other Sources/NJEvents.h +++ b/Other Sources/NJEvents.h @@ -12,4 +12,5 @@ #define NJEventSimulationStopped @"com.yukkurigames.Enjoyable.EventSimulationStopped" #define NJMappingKey @"com.yukkurigames.Enjoyable.Mapping" +#define NJMappingIndexKey @"com.yukkurigames.Enjoyable.MappingIndex" #define NJMappingListKey @"com.yukkurigames.Enjoyable.MappingList" diff --git a/Resources/English.lproj/MainMenu.xib b/Resources/English.lproj/MainMenu.xib index e045c4d..b2cc462 100644 --- a/Resources/English.lproj/MainMenu.xib +++ b/Resources/English.lproj/MainMenu.xib @@ -566,7 +566,7 @@ aW5nLg {232, 321} - + YES NO YES @@ -696,7 +696,7 @@ aW5nLg {234, 323} - + 150034 @@ -791,7 +791,6 @@ aW5nLg {{343, 31}, {70, 18}} - _NS:9 YES @@ -1233,7 +1232,7 @@ aW5nLg {198, 198} - + YES NO YES @@ -1325,7 +1324,7 @@ aW5nLg {{0, 20}, {200, 200}} - + 150034 @@ -1397,7 +1396,6 @@ aW5nLg {{166, -1}, {34, 23}} - YES 67108864 @@ -1784,14 +1782,6 @@ aW5nLg 930 - - - mappingsMenu - - - - 931 - restoreToForeground: @@ -1816,6 +1806,14 @@ aW5nLg 1016 + + + mvc + + + + 1024 + performClick: @@ -2176,14 +2174,6 @@ aW5nLg 989 - - - delegate - - - - 994 - view @@ -2280,6 +2270,14 @@ aW5nLg 1011 + + + delegate + + + + 1023 + @@ -3387,7 +3385,7 @@ aW5nLg - 1022 + 1024 @@ -3416,6 +3414,7 @@ aW5nLg NSMenu NJMappingsController + NJMappingsViewController NSMenu NSWindow @@ -3428,6 +3427,10 @@ aW5nLg mappingsController NJMappingsController + + mvc + NJMappingsViewController + statusItemMenu NSMenu @@ -3566,17 +3569,6 @@ aW5nLg NJMappingsController NSObject - - mvc - NJMappingsViewController - - - mvc - - mvc - NJMappingsViewController - - IBProjectSource ./Classes/NJMappingsController.h @@ -3713,7 +3705,7 @@ aW5nLg NSSlider NSButton NSTextField - NSBUtton + NSButton @@ -3766,7 +3758,7 @@ aW5nLg unknownMapping - NSBUtton + NSButton -- 2.30.2