2 // NJMappingsController.m
5 // Created by Sam McCall on 4/05/09.
8 #import "NJMappingsController.h"
14 @implementation NJMappingsController {
15 NSMutableArray *_mappings;
16 NJMapping *_manualMapping;
20 if ((self = [super init])) {
21 _mappings = [[NSMutableArray alloc] init];
22 _currentMapping = [[NJMapping alloc] initWithName:
23 NSLocalizedString(@"(default)", @"default name for first the mapping")];
24 _manualMapping = _currentMapping;
25 [_mappings addObject:_currentMapping];
30 - (NJMapping *)objectForKeyedSubscript:(NSString *)name {
31 for (NJMapping *mapping in _mappings)
32 if ([name isEqualToString:mapping.name])
37 - (NJMapping *)objectAtIndexedSubscript:(NSUInteger)idx {
38 return idx < _mappings.count ? _mappings[idx] : nil;
42 [self postLoadProcess];
43 [NSNotificationCenter.defaultCenter
44 postNotificationName:NJEventMappingListChanged
46 userInfo:@{ NJMappingListKey: _mappings,
47 NJMappingKey: _currentMapping }];
50 - (void)mappingsChanged {
55 - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state
56 objects:(__unsafe_unretained id [])buffer
57 count:(NSUInteger)len {
58 return [_mappings countByEnumeratingWithState:state
63 - (void)activateMappingForProcess:(NSRunningApplication *)app {
64 NJMapping *oldMapping = _manualMapping;
65 NSArray *names = app.possibleMappingNames;
67 for (NSString *name in names) {
68 NJMapping *mapping = self[name];
70 [self activateMapping:mapping];
77 [self activateMapping:oldMapping];
78 if ([oldMapping.name.lowercaseString isEqualToString:@"@application"]
79 || [oldMapping.name.lowercaseString isEqualToString:
80 NSLocalizedString(@"@Application", nil).lowercaseString]) {
81 oldMapping.name = app.bestMappingName;
82 [self mappingsChanged];
85 _manualMapping = oldMapping;
88 - (void)activateMappingForcibly:(NJMapping *)mapping {
89 NSLog(@"Switching to mapping %@.", mapping.name);
90 _currentMapping = mapping;
91 NSUInteger idx = [self indexOfMapping:_currentMapping];
92 [NSNotificationCenter.defaultCenter
93 postNotificationName:NJEventMappingChanged
95 userInfo:@{ NJMappingKey : _currentMapping,
96 NJMappingIndexKey: @(idx) }];
99 - (void)activateMapping:(NJMapping *)mapping {
101 mapping = _manualMapping;
102 if (mapping == _currentMapping)
104 _manualMapping = mapping;
105 [self activateMappingForcibly:mapping];
109 NSLog(@"Saving mappings to defaults.");
110 NSMutableArray *ary = [[NSMutableArray alloc] initWithCapacity:_mappings.count];
111 for (NJMapping *mapping in _mappings)
112 [ary addObject:[mapping serialize]];
113 [NSUserDefaults.standardUserDefaults setObject:ary forKey:@"mappings"];
116 - (void)postLoadProcess {
117 for (NJMapping *mapping in self)
118 [mapping postLoadProcess:self];
122 NSUInteger selected = [NSUserDefaults.standardUserDefaults integerForKey:@"selected"];
123 NSArray *storedMappings = [NSUserDefaults.standardUserDefaults arrayForKey:@"mappings"];
124 NSMutableArray* newMappings = [[NSMutableArray alloc] initWithCapacity:storedMappings.count];
126 for (NSDictionary *serialization in storedMappings)
127 [newMappings addObject:
128 [[NJMapping alloc] initWithSerialization:serialization]];
130 if (newMappings.count) {
131 _mappings = newMappings;
132 if (selected >= newMappings.count)
134 [self activateMapping:_mappings[selected]];
139 - (NSInteger)indexOfMapping:(NJMapping *)mapping {
140 return [_mappings indexOfObjectIdenticalTo:mapping];
143 - (void)mergeMapping:(NJMapping *)mapping intoMapping:(NJMapping *)existing {
144 [existing mergeEntriesFrom:mapping];
145 [self mappingsChanged];
146 if (existing == _currentMapping)
147 [self activateMappingForcibly:mapping];
150 - (void)renameMapping:(NJMapping *)mapping to:(NSString *)name {
152 [self mappingsChanged];
153 if (mapping == _currentMapping)
154 [self activateMappingForcibly:mapping];
157 - (void)addMapping:(NJMapping *)mapping {
158 [self insertMapping:mapping atIndex:_mappings.count];
161 - (void)insertMapping:(NJMapping *)mapping atIndex:(NSInteger)idx {
162 [_mappings insertObject:mapping atIndex:idx];
163 [self mappingsChanged];
166 - (void)removeMappingAtIndex:(NSInteger)idx {
167 NSInteger currentIdx = [self indexOfMapping:_currentMapping];
168 [_mappings removeObjectAtIndex:idx];
169 [self activateMapping:self[MIN(currentIdx, _mappings.count - 1)]];
170 [self mappingsChanged];
173 - (void)moveMoveMappingFromIndex:(NSInteger)fromIdx toIndex:(NSInteger)toIdx {
174 [_mappings moveObjectAtIndex:fromIdx toIndex:toIdx];
175 [self mappingsChanged];
178 - (NSUInteger)count {
179 return _mappings.count;