Change two-pass behavior for loading mappings. Allow lazy binding of mappings by...
authorJoe Wreschnig <joe.wreschnig@gmail.com>
Sun, 17 Mar 2013 21:18:46 +0000 (22:18 +0100)
committerJoe Wreschnig <joe.wreschnig@gmail.com>
Sun, 17 Mar 2013 21:18:46 +0000 (22:18 +0100)
Don't sleep the HID when debugging, as it's just a pain.

21 files changed:
Categories/NSProcessInfo+Debugging.h [new file with mode: 0644]
Categories/NSProcessInfo+Debugging.m [new file with mode: 0644]
Classes/EnjoyableApplicationDelegate.m
Classes/NJDeviceController.m
Classes/NJMapping.h
Classes/NJMapping.m
Classes/NJMappingsController.m
Classes/NJOutput.h
Classes/NJOutput.m
Classes/NJOutputController.h
Classes/NJOutputController.m
Classes/NJOutputKeyPress.m
Classes/NJOutputMapping.h
Classes/NJOutputMapping.m
Classes/NJOutputMouseButton.m
Classes/NJOutputMouseMove.m
Classes/NJOutputMouseScroll.m
Enjoyable.xcodeproj/project.pbxproj
Info.plist
Other Sources/Enjoyable_Prefix.pch
Resources/English.lproj/MainMenu.xib

diff --git a/Categories/NSProcessInfo+Debugging.h b/Categories/NSProcessInfo+Debugging.h
new file mode 100644 (file)
index 0000000..75533ed
--- /dev/null
@@ -0,0 +1,15 @@
+//
+//  NSProcessInfo+Debugging.h
+//  Enjoyable
+//
+//  Created by Joe Wreschnig on 3/17/13.
+//
+//
+
+#import <Foundation/Foundation.h>
+
+@interface NSProcessInfo (Debugging)
+
+- (BOOL)isBeingDebugged;
+
+@end
diff --git a/Categories/NSProcessInfo+Debugging.m b/Categories/NSProcessInfo+Debugging.m
new file mode 100644 (file)
index 0000000..649de3b
--- /dev/null
@@ -0,0 +1,35 @@
+//
+//  NSProcessInfo+Debugging.m
+//  Enjoyable
+//
+//  Created by Joe Wreschnig on 3/17/13.
+//
+//
+
+#import "NSProcessInfo+Debugging.h"
+
+#include <assert.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/sysctl.h>
+
+@implementation NSProcessInfo (Debugging)
+
+- (BOOL)isBeingDebugged {
+    int mib[4];
+    struct kinfo_proc info;
+    size_t size = sizeof(info);
+    
+    info.kp_proc.p_flag = 0;
+    
+    mib[0] = CTL_KERN;
+    mib[1] = KERN_PROC;
+    mib[2] = KERN_PROC_PID;
+    mib[3] = self.processIdentifier;
+    
+    return sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0) == 0
+        && (info.kp_proc.p_flag & P_TRACED) != 0;
+}
+
+@end
index fe781efbfd49b50430c6935729e16f5589bfd26d..26ea09cdf3321660eaceef0cc96dce8e03d155e5 100644 (file)
     NSError *error;
     NSURL *URL = [NSURL fileURLWithPath:filename];
     NJMapping *mapping = [NJMapping mappingWithContentsOfURL:URL
-                                                    mappings:self.mappingsController
                                                        error:&error];
     if (mapping) {
         [self.mappingsController addOrMergeMapping:mapping];
                       [panel close];
                       NSError *error;
                       NJMapping *mapping = [NJMapping mappingWithContentsOfURL:panel.URL
-                                                                      mappings:self.mappingsController
                                                                          error:&error];
                       if (mapping) {
                           [self.mappingsController addOrMergeMapping:mapping];
index 329b353ec1d595a9e213244a11d25e3100e3a851..000df5f60a4f4d6be91dd8f1e391b02bc2423de7 100644 (file)
 }
 
 - (void)stopHidIfDisabled:(NSNotification *)application {
-    if (!self.simulatingEvents)
+    if (!self.simulatingEvents && !NSProcessInfo.processInfo.isBeingDebugged)
         [self stopHid];
 }
 
index 0d5db8919f4fc39e5bfcc05badc4198154b4cc7c..be3aa7689c3c44eef4780e7083e696491d833d64 100644 (file)
 @property (nonatomic, readonly) NSUInteger count;
 
 + (id)mappingWithContentsOfURL:(NSURL *)url
-                      mappings:(id <NSFastEnumeration>)mappings
                          error:(NSError **)error;
 
 - (id)initWithName:(NSString *)name;
-- (id)initWithSerialization:(NSDictionary *)serialization
-                   mappings:(id <NSFastEnumeration>)mappings;
+- (id)initWithSerialization:(NSDictionary *)serialization;
 
 - (NJOutput *)objectForKeyedSubscript:(NJInput *)input;
 - (void)setObject:(NJOutput *)output forKeyedSubscript:(NJInput *)input;
@@ -29,4 +27,6 @@
 - (BOOL)hasConflictWith:(NJMapping *)other;
 - (void)mergeEntriesFrom:(NJMapping *)other;
 
+- (void)postLoadProcess:(id <NSFastEnumeration>)allMappings;
+
 @end
index 04f6e68d7c6fa9bc0d383b58b8ea787434e87fb3..3d5cd67f5a7470c4d143f8e6173404861444c16d 100644 (file)
     return self;
 }
 
-- (id)initWithSerialization:(NSDictionary *)serialization
-                   mappings:(id <NSFastEnumeration>)mappings {
+- (id)initWithSerialization:(NSDictionary *)serialization {
     if ((self = [self initWithName:serialization[@"name"]])) {
         NSDictionary *entries = serialization[@"entries"];
         if ([entries isKindOfClass:NSDictionary.class]) {
             for (id key in entries) {
                 if ([key isKindOfClass:NSString.class]) {
-                    NJOutput *output = [NJOutput outputDeserialize:entries[key]
-                                                      withMappings:mappings];
+                    NJOutput *output = [NJOutput outputDeserialize:entries[key]];
                     if (output)
                         _entries[key] = output;
                 }
     return NO;
 }
 
-+ (id)mappingWithContentsOfURL:(NSURL *)url mappings:(id <NSFastEnumeration>)mappings error:(NSError **)error {
++ (id)mappingWithContentsOfURL:(NSURL *)url error:(NSError **)error {
     NSInputStream *stream = [NSInputStream inputStreamWithURL:url];
     [stream open];
     NSDictionary *serialization = stream && !*error
         return nil;
     }
     
-    return [[NJMapping alloc] initWithSerialization:serialization
-                                           mappings:mappings];
+    return [[NJMapping alloc] initWithSerialization:serialization];
 }
 
 - (void)mergeEntriesFrom:(NJMapping *)other {
         [_entries addEntriesFromDictionary:other->_entries];
 }
 
+- (void)postLoadProcess:(id <NSFastEnumeration>)allMappings {
+    for (NJOutput *o in _entries.allValues)
+        [o postLoadProcess:allMappings];
+}
+
+
 @end
index 4859970fc63ff07b81788bf655978ec33d63f019..9c7b641e848ab9e7eec9b7d611a4d89670272afe 100644 (file)
@@ -42,6 +42,7 @@
 }
 
 - (void)mappingsSet {
+    [self postLoadProcess];
     [NSNotificationCenter.defaultCenter
         postNotificationName:NJEventMappingListChanged
                       object:self
     [NSUserDefaults.standardUserDefaults setObject:ary forKey:@"mappings"];
 }
 
+- (void)postLoadProcess {
+    for (NJMapping *mapping in self)
+        [mapping postLoadProcess:self];
+}
+
 - (void)load {
     NSUInteger selected = [NSUserDefaults.standardUserDefaults integerForKey:@"selected"];
     NSArray *storedMappings = [NSUserDefaults.standardUserDefaults arrayForKey:@"mappings"];
     NSMutableArray* newMappings = [[NSMutableArray alloc] initWithCapacity:storedMappings.count];
 
-    // Requires two passes to deal with inter-mapping references. First make
-    // an empty mapping for each serialized mapping. Then, deserialize the
-    // data pointing to the empty mappings. Then merge that data back into
-    // its equivalent empty one, which is the one we finally use.
-    for (NSDictionary *storedMapping in storedMappings) {
-        NJMapping *mapping = [[NJMapping alloc] initWithName:storedMapping[@"name"]];
-        [newMappings addObject:mapping];
-    }
-
     for (unsigned i = 0; i < storedMappings.count; ++i) {
-        NJMapping *realMapping = [[NJMapping alloc] initWithSerialization:storedMappings[i]
-                                                                 mappings:newMappings];
-        [newMappings[i] mergeEntriesFrom:realMapping];
+        NJMapping *mapping = [[NJMapping alloc] initWithSerialization:storedMappings[i]];
+        [newMappings addObject:mapping];
     }
     
+    
     if (newMappings.count) {
         _mappings = newMappings;
         if (selected >= newMappings.count)
                        atIndex:(NSInteger)index
                          error:(NSError **)error {
     NJMapping *mapping = [NJMapping mappingWithContentsOfURL:url
-                                                    mappings:_mappings
                                                        error:error];
     [self addOrMergeMapping:mapping atIndex:index];
     return !!mapping;
index 5d4d4705169d2bb4f779cccea3c1cc2158d19da0..aeb8e4683343c52d9060a9607ca4d6f08cdd4a64 100644 (file)
@@ -19,8 +19,9 @@
 - (BOOL)update:(NJDeviceController *)jc;
 
 - (NSDictionary *)serialize;
-+ (NJOutput *)outputDeserialize:(NSDictionary *)serialization
-                   withMappings:(id <NSFastEnumeration>)mappings;
++ (NJOutput *)outputDeserialize:(NSDictionary *)serialization;
 + (NSString *)serializationCode;
 
+- (void)postLoadProcess:(id <NSFastEnumeration>)allMappings;
+
 @end
index 35a56d925f40f331351fcb4928ef8e03716cbc94..54809ceaee1ab7b1dd203899c2f5417b647ab864 100644 (file)
@@ -36,8 +36,7 @@
     return [[self serialize] hash];
 }
 
-+ (NJOutput *)outputDeserialize:(NSDictionary *)serialization
-                  withMappings:(id <NSFastEnumeration>)mappings {
++ (NJOutput *)outputDeserialize:(NSDictionary *)serialization {
     // Don't crash loading old/bad mappings (but don't load them either).
     if (![serialization isKindOfClass:NSDictionary.class])
         return nil;
@@ -49,7 +48,7 @@
                         NJOutputMouseScroll.class
          ]) {
         if ([type isEqualToString:cls.serializationCode])
-            return [cls outputDeserialize:serialization withMappings:mappings];
+            return [cls outputDeserialize:serialization];
     }
     
     return nil;
@@ -83,5 +82,7 @@
     }
 }
 
+- (void)postLoadProcess:(id <NSFastEnumeration>)allMappings {
+}
 
 @end
index 6f4c8664c3987a74b33be742d304e88c4725fa7e..3974e2e2132c16b696b14d092161257273164384 100644 (file)
@@ -26,6 +26,7 @@
     IBOutlet NJMappingsController *mappingsController;
     IBOutlet NJDeviceController *inputController;
     IBOutlet NSButton *smoothCheck;
+    IBOutlet NSButton *unknownMapping;
 }
 
 @property (assign) BOOL enabled;
index 07c077b4048294c783a48bde8086dc938e639cbd..fd160e65af84f00995c93d36b0999ad1d8f99f83 100644 (file)
@@ -53,8 +53,8 @@
     if (row != 2) {
         [mappingPopup selectItemAtIndex:-1];
         [mappingPopup resignIfFirstResponder];
-    } else if (!mappingPopup.selectedItem)
-        [mappingPopup selectItemAtIndex:0];
+        unknownMapping.hidden = YES;
+    }
     
     if (row != 3) {
         mouseDirSelect.selectedSegment = -1;
 - (void)mappingChosen:(id)sender {
     [radioButtons selectCellAtRow:2 column:0];
     [mappingPopup.window makeFirstResponder:mappingPopup];
+    unknownMapping.hidden = YES;
     [self commit];
 }
 
     scrollDirSelect.enabled = enabled;
     smoothCheck.enabled = enabled;
     scrollSpeedSlider.enabled = enabled && smoothCheck.state;
+    if (!enabled)
+        unknownMapping.hidden = YES;
 }
 
 - (void)loadOutput:(NJOutput *)output forInput:(NJInput *)input {
         [radioButtons selectCellAtRow:2 column:0];
         NSMenuItem *item = [mappingPopup itemWithRepresentedObject:[(NJOutputMapping *)output mapping]];
         [mappingPopup selectItem:item];
-        if (!item)
-            [radioButtons selectCellAtRow:self.enabled ? 0 : -1 column:0];
+        unknownMapping.hidden = !!item;
+        unknownMapping.title = [(NJOutputMapping *)output mappingName];
     }
     else if ([output isKindOfClass:NJOutputMouseMove.class]) {
         [radioButtons selectCellAtRow:3 column:0];
index e80aba53691f43073ed46652b74969697072f270..7b8c63106d54d2f928ca7e9621223d822aac9f6a 100644 (file)
@@ -21,8 +21,7 @@
         : nil;
 }
 
-+ (NJOutput *)outputDeserialize:(NSDictionary *)serialization
-                  withMappings:(id <NSFastEnumeration>)mappings {
++ (NJOutput *)outputDeserialize:(NSDictionary *)serialization {
     NJOutputKeyPress *output = [[NJOutputKeyPress alloc] init];
     output.keyCode = [serialization[@"key"] intValue];
     return output;
index e8c3029d7780bfe7aecfc4a73a4268c89019f6bf..cc5b3edd1799fdf1fb5028a173f837657a1090c6 100644 (file)
@@ -13,5 +13,6 @@
 @interface NJOutputMapping : NJOutput
 
 @property (nonatomic, weak) NJMapping *mapping;
+@property (nonatomic, copy) NSString *mappingName;
 
 @end
index 28a84aba0d1b53897c3b3371edb4fb4bf0b8f539..efb7c003425763057388695a82901f6bc8b30a9a 100644 (file)
 }
 
 - (NSDictionary *)serialize {
-    return _mapping
-        ? @{ @"type": self.class.serializationCode, @"name": _mapping.name }
+    NSString *name = _mapping ? _mapping.name : self.mappingName;
+    return name
+        ? @{ @"type": self.class.serializationCode, @"name": name }
         : nil;
 }
 
-+ (NJOutputMapping *)outputDeserialize:(NSDictionary *)serialization
-                        withMappings:(id <NSFastEnumeration>)mappings {
++ (NJOutputMapping *)outputDeserialize:(NSDictionary *)serialization {
     NSString *name = serialization[@"name"];
     NJOutputMapping *output = [[NJOutputMapping alloc] init];
-    for (NJMapping *mapping in mappings) {
-        if ([mapping.name isEqualToString:name]) {
-            output.mapping = mapping;
-            return output;
-        }
-    }
-    return nil;
+    output.mappingName = name;
+    return name ? output : nil;
 }
 
 - (void)trigger {
     EnjoyableApplicationDelegate *ctrl = (EnjoyableApplicationDelegate *)NSApplication.sharedApplication.delegate;
-    [ctrl.mappingsController activateMapping:_mapping];
+    if (_mapping) {
+        [ctrl.mappingsController activateMapping:_mapping];
+        self.mappingName = _mapping.name;
+    } else {
+        // TODO: Show an error message? Unobtrusively since something
+        // is probably running.
+    }
+}
+
+- (void)postLoadProcess:(id <NSFastEnumeration>)allMappings {
+    if (!self.mapping) {
+        for (NJMapping *mapping in allMappings) {
+            if ([mapping.name isEqualToString:self.mappingName]) {
+                self.mapping = mapping;
+                break;
+            }
+        }
+    }
 }
 
 @end
index e01e76372f2bbfe42bb890c0604593b69c42d411..0b039d108d2eaef2821eb6e2ba94b9cff6e28cb0 100644 (file)
@@ -36,8 +36,7 @@
     return @{ @"type": self.class.serializationCode, @"button": @(_button) };
 }
 
-+ (NJOutput *)outputDeserialize:(NSDictionary *)serialization
-                  withMappings:(id <NSFastEnumeration>)mappings {
++ (NJOutput *)outputDeserialize:(NSDictionary *)serialization {
     NJOutputMouseButton *output = [[NJOutputMouseButton alloc] init];
     output.button = [serialization[@"button"] intValue];
     return output;
index 85919236dce008566c2e632d4717f1dca115c73c..84c0ea37630f8b37a77debea8d2e1f72dbf2eb44 100644 (file)
@@ -22,8 +22,7 @@
               };
 }
 
-+ (NJOutput *)outputDeserialize:(NSDictionary *)serialization
-                  withMappings:(id <NSFastEnumeration>)mappings {
++ (NJOutput *)outputDeserialize:(NSDictionary *)serialization {
     NJOutputMouseMove *output = [[NJOutputMouseMove alloc] init];
     output.axis = [serialization[@"axis"] intValue];
     output.speed = [serialization[@"speed"] floatValue];
index 6fdc918c6844abfd246ea71713f81785b6bf6330..06913d6173dbbf0af1d3fbc29f61b5a8fda98757 100644 (file)
@@ -21,8 +21,7 @@
               };
 }
 
-+ (NJOutput *)outputDeserialize:(NSDictionary *)serialization
-                  withMappings:(id <NSFastEnumeration>)mappings {
++ (NJOutput *)outputDeserialize:(NSDictionary *)serialization {
     NJOutputMouseScroll *output = [[NJOutputMouseScroll alloc] init];
     output.direction = [serialization[@"direction"] intValue];
     output.speed = [serialization[@"speed"] floatValue];
index 27ca44a67eca9f93a0a6449621afeed5ad400720..890b562328134a724ac6add156b1e49fe3e2ff10 100644 (file)
@@ -14,6 +14,7 @@
                EE3D897C16EA806E00596D1F /* Status Menu Icon Disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = EE3D897B16EA806E00596D1F /* Status Menu Icon Disabled@2x.png */; };
                EE3D897F16EA817E00596D1F /* Status Menu Icon Disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = EE3D897D16EA817E00596D1F /* Status Menu Icon Disabled.png */; };
                EE3D898016EA817E00596D1F /* Status Menu Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = EE3D897E16EA817E00596D1F /* Status Menu Icon.png */; };
+               EE48263016F6680D001B0C64 /* NSProcessInfo+Debugging.m in Sources */ = {isa = PBXBuildFile; fileRef = EE48262F16F6680D001B0C64 /* NSProcessInfo+Debugging.m */; };
                EE52145C16F3E8BD00E3C574 /* NSOutlineView+ItemAccessors.m in Sources */ = {isa = PBXBuildFile; fileRef = EE52145B16F3E8BD00E3C574 /* NSOutlineView+ItemAccessors.m */; };
                EE52145F16F404D500E3C574 /* NJDeviceViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = EE52145E16F404D500E3C574 /* NJDeviceViewController.m */; };
                EE6A122E16E8F46300EDBD32 /* Icon.icns in Resources */ = {isa = PBXBuildFile; fileRef = EE6A122D16E8F46300EDBD32 /* Icon.icns */; };
@@ -81,6 +82,8 @@
                EE3D897B16EA806E00596D1F /* Status Menu Icon Disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Status Menu Icon Disabled@2x.png"; path = "Resources/Status Menu Icon Disabled@2x.png"; sourceTree = "<group>"; };
                EE3D897D16EA817E00596D1F /* Status Menu Icon Disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Status Menu Icon Disabled.png"; path = "Resources/Status Menu Icon Disabled.png"; sourceTree = "<group>"; };
                EE3D897E16EA817E00596D1F /* Status Menu Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Status Menu Icon.png"; path = "Resources/Status Menu Icon.png"; sourceTree = "<group>"; };
+               EE48262E16F6680D001B0C64 /* NSProcessInfo+Debugging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSProcessInfo+Debugging.h"; path = "Categories/NSProcessInfo+Debugging.h"; sourceTree = "<group>"; };
+               EE48262F16F6680D001B0C64 /* NSProcessInfo+Debugging.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSProcessInfo+Debugging.m"; path = "Categories/NSProcessInfo+Debugging.m"; sourceTree = "<group>"; };
                EE52145A16F3E8BD00E3C574 /* NSOutlineView+ItemAccessors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSOutlineView+ItemAccessors.h"; path = "Categories/NSOutlineView+ItemAccessors.h"; sourceTree = "<group>"; };
                EE52145B16F3E8BD00E3C574 /* NSOutlineView+ItemAccessors.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSOutlineView+ItemAccessors.m"; path = "Categories/NSOutlineView+ItemAccessors.m"; sourceTree = "<group>"; };
                EE52145D16F404D500E3C574 /* NJDeviceViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NJDeviceViewController.h; path = Classes/NJDeviceViewController.h; sourceTree = "<group>"; };
                                EEE73B1516EA42E5009D9D99 /* NSRunningApplication+NJPossibleNames.m */,
                                EE52145A16F3E8BD00E3C574 /* NSOutlineView+ItemAccessors.h */,
                                EE52145B16F3E8BD00E3C574 /* NSOutlineView+ItemAccessors.m */,
+                               EE48262E16F6680D001B0C64 /* NSProcessInfo+Debugging.h */,
+                               EE48262F16F6680D001B0C64 /* NSProcessInfo+Debugging.m */,
                        );
                        name = Categories;
                        sourceTree = "<group>";
                                EE52145C16F3E8BD00E3C574 /* NSOutlineView+ItemAccessors.m in Sources */,
                                EE52145F16F404D500E3C574 /* NJDeviceViewController.m in Sources */,
                                EE83ACEC16F545EA00083E94 /* NJMappingsViewController.m in Sources */,
+                               EE48263016F6680D001B0C64 /* NSProcessInfo+Debugging.m in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 94c58253434e2874b12f8628cc7fccf60d75362a..15d916eb2339a745b35b9584b2af64b3dcb4e4f8 100644 (file)
@@ -46,7 +46,7 @@
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>448</string>
+       <string>479</string>
        <key>LSApplicationCategoryType</key>
        <string>public.app-category.utilities</string>
        <key>NSHumanReadableCopyright</key>
index e074f78688e99489f46df192f41f6ede2512b7f8..a873aec786b339e3de1b3f34c629f8cf7aacfb62 100644 (file)
@@ -17,3 +17,4 @@
 #import "NSRunningApplication+NJPossibleNames.h"
 #import "NSRunningApplication+LoginItem.h"
 #import "NSOutlineView+ItemAccessors.h"
+#import "NSProcessInfo+Debugging.h"
index 6afbc500001fc4167eac36516866c3d4426e8bc6..e045c4d3598a79a4ef1a396f834b43bac4e0673e 100644 (file)
@@ -566,7 +566,7 @@ aW5nLg</string>
                                                                                                        <string key="NSFrameSize">{232, 321}</string>
                                                                                                        <reference key="NSSuperview" ref="698362889"/>
                                                                                                        <reference key="NSWindow"/>
-                                                                                                       <reference key="NSNextKeyView" ref="892486973"/>
+                                                                                                       <reference key="NSNextKeyView" ref="1036252745"/>
                                                                                                        <bool key="NSEnabled">YES</bool>
                                                                                                        <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
                                                                                                        <bool key="NSControlAllowsExpansionToolTips">YES</bool>
@@ -696,7 +696,7 @@ aW5nLg</string>
                                                                        <string key="NSFrameSize">{234, 323}</string>
                                                                        <reference key="NSSuperview" ref="734312853"/>
                                                                        <reference key="NSWindow"/>
-                                                                       <reference key="NSNextKeyView" ref="698362889"/>
+                                                                       <reference key="NSNextKeyView" ref="892486973"/>
                                                                        <int key="NSsFlags">150034</int>
                                                                        <reference key="NSVScroller" ref="1036252745"/>
                                                                        <reference key="NSHScroller" ref="892486973"/>
@@ -718,6 +718,31 @@ aW5nLg</string>
                                                        <reference key="NSNextResponder" ref="177223957"/>
                                                        <int key="NSvFlags">285</int>
                                                        <array class="NSMutableArray" key="NSSubviews">
+                                                               <object class="NSButton" id="529992855">
+                                                                       <reference key="NSNextResponder" ref="471332453"/>
+                                                                       <int key="NSvFlags">268</int>
+                                                                       <string key="NSFrame">{{197, 157}, {193, 21}}</string>
+                                                                       <reference key="NSSuperview" ref="471332453"/>
+                                                                       <reference key="NSWindow"/>
+                                                                       <reference key="NSNextKeyView" ref="875916470"/>
+                                                                       <string key="NSReuseIdentifierKey">_NS:9</string>
+                                                                       <bool key="NSEnabled">YES</bool>
+                                                                       <object class="NSButtonCell" key="NSCell" id="420588612">
+                                                                               <int key="NSCellFlags">603979776</int>
+                                                                               <int key="NSCellFlags2">33554432</int>
+                                                                               <string key="NSContents">Unknown Mapping</string>
+                                                                               <reference key="NSSupport" ref="45863614"/>
+                                                                               <string key="NSCellIdentifier">_NS:9</string>
+                                                                               <reference key="NSControlView" ref="529992855"/>
+                                                                               <int key="NSButtonFlags">-2046672896</int>
+                                                                               <int key="NSButtonFlags2">129</int>
+                                                                               <string key="NSAlternateContents"/>
+                                                                               <string key="NSKeyEquivalent"/>
+                                                                               <int key="NSPeriodicDelay">200</int>
+                                                                               <int key="NSPeriodicInterval">25</int>
+                                                                       </object>
+                                                                       <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+                                                               </object>
                                                                <object class="NSSegmentedControl" id="875916470">
                                                                        <reference key="NSNextResponder" ref="471332453"/>
                                                                        <int key="NSvFlags">265</int>
@@ -766,6 +791,7 @@ aW5nLg</string>
                                                                        <string key="NSFrame">{{343, 31}, {70, 18}}</string>
                                                                        <reference key="NSSuperview" ref="471332453"/>
                                                                        <reference key="NSWindow"/>
+                                                                       <reference key="NSNextKeyView"/>
                                                                        <string key="NSReuseIdentifierKey">_NS:9</string>
                                                                        <bool key="NSEnabled">YES</bool>
                                                                        <object class="NSButtonCell" key="NSCell" id="868379451">
@@ -958,7 +984,7 @@ aW5nLg</string>
                                                                        <string key="NSFrame">{{188, 153}, {226, 26}}</string>
                                                                        <reference key="NSSuperview" ref="471332453"/>
                                                                        <reference key="NSWindow"/>
-                                                                       <reference key="NSNextKeyView" ref="875916470"/>
+                                                                       <reference key="NSNextKeyView" ref="529992855"/>
                                                                        <bool key="NSEnabled">YES</bool>
                                                                        <object class="NSPopUpButtonCell" key="NSCell" id="74311158">
                                                                                <int key="NSCellFlags">-2076180416</int>
@@ -1207,7 +1233,7 @@ aW5nLg</string>
                                                                                <string key="NSFrameSize">{198, 198}</string>
                                                                                <reference key="NSSuperview" ref="947403733"/>
                                                                                <reference key="NSWindow"/>
-                                                                               <reference key="NSNextKeyView" ref="553414014"/>
+                                                                               <reference key="NSNextKeyView" ref="968378655"/>
                                                                                <bool key="NSEnabled">YES</bool>
                                                                                <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
                                                                                <bool key="NSControlAllowsExpansionToolTips">YES</bool>
@@ -1299,7 +1325,7 @@ aW5nLg</string>
                                                <string key="NSFrame">{{0, 20}, {200, 200}}</string>
                                                <reference key="NSSuperview" ref="671181514"/>
                                                <reference key="NSWindow"/>
-                                               <reference key="NSNextKeyView" ref="947403733"/>
+                                               <reference key="NSNextKeyView" ref="553414014"/>
                                                <int key="NSsFlags">150034</int>
                                                <reference key="NSVScroller" ref="968378655"/>
                                                <reference key="NSHScroller" ref="553414014"/>
@@ -1371,6 +1397,7 @@ aW5nLg</string>
                                                <string key="NSFrame">{{166, -1}, {34, 23}}</string>
                                                <reference key="NSSuperview" ref="671181514"/>
                                                <reference key="NSWindow"/>
+                                               <reference key="NSNextKeyView"/>
                                                <bool key="NSEnabled">YES</bool>
                                                <object class="NSButtonCell" key="NSCell" id="828611353">
                                                        <int key="NSCellFlags">67108864</int>
@@ -1973,6 +2000,14 @@ aW5nLg</string>
                                        </object>
                                        <int key="connectionID">949</int>
                                </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBOutletConnection" key="connection">
+                                               <string key="label">unknownMapping</string>
+                                               <reference key="source" ref="801536542"/>
+                                               <reference key="destination" ref="529992855"/>
+                                       </object>
+                                       <int key="connectionID">1022</int>
+                               </object>
                                <object class="IBConnectionRecord">
                                        <object class="IBOutletConnection" key="connection">
                                                <string key="label">delegate</string>
@@ -2730,6 +2765,7 @@ aW5nLg</string>
                                                        <reference ref="385416822"/>
                                                        <reference ref="792189805"/>
                                                        <reference ref="20704797"/>
+                                                       <reference ref="529992855"/>
                                                </array>
                                                <reference key="parent" ref="177223957"/>
                                        </object>
@@ -3079,12 +3115,27 @@ aW5nLg</string>
                                                <reference key="object" ref="70919963"/>
                                                <reference key="parent" ref="0"/>
                                        </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">1020</int>
+                                               <reference key="object" ref="529992855"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="420588612"/>
+                                               </array>
+                                               <reference key="parent" ref="471332453"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">1021</int>
+                                               <reference key="object" ref="420588612"/>
+                                               <reference key="parent" ref="529992855"/>
+                                       </object>
                                </array>
                        </object>
                        <dictionary class="NSMutableDictionary" key="flattenedProperties">
                                <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
                                <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
                                <string key="-3.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="1020.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="1021.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
                                <string key="130.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
                                <string key="131.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
                                <string key="134.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -3336,7 +3387,7 @@ aW5nLg</string>
                        <nil key="activeLocalization"/>
                        <dictionary class="NSMutableDictionary" key="localizations"/>
                        <nil key="sourceID"/>
-                       <int key="maxID">1016</int>
+                       <int key="maxID">1022</int>
                </object>
                <object class="IBClassDescriber" key="IBDocument.Classes">
                        <array class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -3662,6 +3713,7 @@ aW5nLg</string>
                                                <string key="scrollSpeedSlider">NSSlider</string>
                                                <string key="smoothCheck">NSButton</string>
                                                <string key="title">NSTextField</string>
+                                               <string key="unknownMapping">NSBUtton</string>
                                        </dictionary>
                                        <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
                                                <object class="IBToOneOutletInfo" key="inputController">
@@ -3712,6 +3764,10 @@ aW5nLg</string>
                                                        <string key="name">title</string>
                                                        <string key="candidateClassName">NSTextField</string>
                                                </object>
+                                               <object class="IBToOneOutletInfo" key="unknownMapping">
+                                                       <string key="name">unknownMapping</string>
+                                                       <string key="candidateClassName">NSBUtton</string>
+                                               </object>
                                        </dictionary>
                                        <object class="IBClassDescriptionSource" key="sourceIdentifier">
                                                <string key="majorKey">IBProjectSource</string>