8f0492cc7d88d3ac00c5aac8e7132f1e37e35849
[enjoyable.git] / Classes / NJMappingsController.m
1 //
2 // NJMappingsController.m
3 // Enjoy
4 //
5 // Created by Sam McCall on 4/05/09.
6 //
7
8 #import "NJMappingsController.h"
9
10 #import "NJMapping.h"
11 #import "NJOutput.h"
12 #import "NJEvents.h"
13
14 #define PB_ROW @"com.yukkurigames.Enjoyable.MappingRow"
15
16 @implementation NJMappingsController {
17 NSMutableArray *_mappings;
18 NJMapping *_manualMapping;
19 }
20
21 - (id)init {
22 if ((self = [super init])) {
23 _mappings = [[NSMutableArray alloc] init];
24 _currentMapping = [[NJMapping alloc] initWithName:
25 NSLocalizedString(@"(default)", @"default name for first the mapping")];
26 _manualMapping = _currentMapping;
27 [_mappings addObject:_currentMapping];
28 }
29 return self;
30 }
31
32 - (NJMapping *)objectForKeyedSubscript:(NSString *)name {
33 for (NJMapping *mapping in _mappings)
34 if ([name isEqualToString:mapping.name])
35 return mapping;
36 return nil;
37 }
38
39 - (NJMapping *)objectAtIndexedSubscript:(NSUInteger)idx {
40 return idx < _mappings.count ? _mappings[idx] : nil;
41 }
42
43 - (void)mappingsSet {
44 [self postLoadProcess];
45 [NSNotificationCenter.defaultCenter
46 postNotificationName:NJEventMappingListChanged
47 object:self
48 userInfo:@{ NJMappingListKey: _mappings,
49 NJMappingKey: _currentMapping }];
50 }
51
52 - (void)mappingsChanged {
53 [self save];
54 [self mappingsSet];
55 }
56
57 - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state
58 objects:(__unsafe_unretained id [])buffer
59 count:(NSUInteger)len {
60 return [_mappings countByEnumeratingWithState:state
61 objects:buffer
62 count:len];
63 }
64
65 - (void)activateMappingForProcess:(NSRunningApplication *)app {
66 NJMapping *oldMapping = _manualMapping;
67 NSArray *names = app.possibleMappingNames;
68 BOOL found = NO;
69 for (NSString *name in names) {
70 NJMapping *mapping = self[name];
71 if (mapping) {
72 [self activateMapping:mapping];
73 found = YES;
74 break;
75 }
76 }
77
78 if (!found) {
79 [self activateMapping:oldMapping];
80 if ([oldMapping.name.lowercaseString isEqualToString:@"@application"]
81 || [oldMapping.name.lowercaseString isEqualToString:
82 NSLocalizedString(@"@Application", nil).lowercaseString]) {
83 oldMapping.name = app.bestMappingName;
84 [self mappingsChanged];
85 }
86 }
87 _manualMapping = oldMapping;
88 }
89
90 - (void)activateMapping:(NJMapping *)mapping {
91 if (!mapping)
92 mapping = _manualMapping;
93 if (mapping == _currentMapping)
94 return;
95 NSLog(@"Switching to mapping %@.", mapping.name);
96 _manualMapping = mapping;
97 _currentMapping = mapping;
98 NSUInteger idx = [_mappings indexOfObjectIdenticalTo:_currentMapping];
99 [NSNotificationCenter.defaultCenter
100 postNotificationName:NJEventMappingChanged
101 object:self
102 userInfo:@{ NJMappingKey : _currentMapping,
103 NJMappingIndexKey: @(idx) }];
104 }
105
106 - (void)save {
107 NSLog(@"Saving mappings to defaults.");
108 NSMutableArray *ary = [[NSMutableArray alloc] initWithCapacity:_mappings.count];
109 for (NJMapping *mapping in _mappings)
110 [ary addObject:[mapping serialize]];
111 [NSUserDefaults.standardUserDefaults setObject:ary forKey:@"mappings"];
112 }
113
114 - (void)postLoadProcess {
115 for (NJMapping *mapping in self)
116 [mapping postLoadProcess:self];
117 }
118
119 - (void)load {
120 NSUInteger selected = [NSUserDefaults.standardUserDefaults integerForKey:@"selected"];
121 NSArray *storedMappings = [NSUserDefaults.standardUserDefaults arrayForKey:@"mappings"];
122 NSMutableArray* newMappings = [[NSMutableArray alloc] initWithCapacity:storedMappings.count];
123
124 for (unsigned i = 0; i < storedMappings.count; ++i) {
125 NJMapping *mapping = [[NJMapping alloc] initWithSerialization:storedMappings[i]];
126 [newMappings addObject:mapping];
127 }
128
129
130 if (newMappings.count) {
131 _mappings = newMappings;
132 if (selected >= newMappings.count)
133 selected = 0;
134 [self activateMapping:_mappings[selected]];
135 [self mappingsSet];
136 }
137 }
138
139 - (NSInteger)indexOfMapping:(NJMapping *)mapping {
140 return [_mappings indexOfObjectIdenticalTo:mapping];
141 }
142
143 - (void)mergeMapping:(NJMapping *)mapping intoMapping:(NJMapping *)existing {
144 [existing mergeEntriesFrom:mapping];
145 [self mappingsChanged];
146 if (existing == _currentMapping) {
147 // FIXME: Hack to trigger updates in the rest of the UI.
148 _currentMapping = nil;
149 NJMapping *manual = _manualMapping;
150 [self activateMapping:existing];
151 _manualMapping = manual;
152 }
153 }
154
155 - (void)renameMapping:(NJMapping *)mapping to:(NSString *)name {
156 mapping.name = name;
157 if (mapping == _currentMapping) {
158 // FIXME: Hack to trigger updates in the rest of the UI.
159 _currentMapping = nil;
160 NJMapping *manual = _manualMapping;
161 [self activateMapping:mapping];
162 _manualMapping = manual;
163 }
164 [self mappingsChanged];
165 }
166
167 - (void)addMapping:(NJMapping *)mapping {
168 [self insertMapping:mapping atIndex:_mappings.count];
169 }
170
171 - (void)insertMapping:(NJMapping *)mapping atIndex:(NSInteger)idx {
172 [_mappings insertObject:mapping atIndex:idx];
173 [self mappingsChanged];
174 }
175
176 - (void)removeMappingAtIndex:(NSInteger)idx {
177 NSInteger currentIdx = [self indexOfMapping:_currentMapping];
178 [_mappings removeObjectAtIndex:idx];
179 [self activateMapping:self[MIN(currentIdx, _mappings.count - 1)]];
180 [self mappingsChanged];
181 }
182
183 - (void)moveMoveMappingFromIndex:(NSInteger)fromIdx toIndex:(NSInteger)toIdx {
184 [_mappings moveObjectAtIndex:fromIdx toIndex:toIdx];
185 [self mappingsChanged];
186 }
187
188 - (NSUInteger)count {
189 return _mappings.count;
190 }
191
192 @end