Permalink
Browse files

Update README. Update classes from growth-charts project.

  • Loading branch information...
1 parent 99d7880 commit 4ace9a3168f4abb0825ffa5d6d65d6dce2b57e00 @p2 committed Feb 10, 2013
View
4 README.md
@@ -1,4 +1,6 @@
Growth Charts Helper
====================
-Work in progress.
+This is an experimental Mac app that can read and write [growth chart JSON][growth-charts-json] files, a file format that aims to make existing pediatric growth charts computer-usable.
+
+[growth-charts-json]: https://github.com/p2/growth-charts-json
View
37 growth-charts-helper/FromCharts/CHChart.m
@@ -40,20 +40,28 @@ + (id)newFromJSONObject:(id)object
}
/**
- * Reads "Charts.plist" from the main bundle and returns the charts contained therein
+ * Finds all JSON files in the bundle, checks if they start with a given prefix, and assumes that those are charts if they do.
*/
+ (NSArray *)bundledCharts
{
NSArray *bundled = [[NSBundle mainBundle] pathsForResourcesOfType:@"json" inDirectory:nil];
if ([bundled count] > 0) {
- NSString *prefix = @"grchrt";
+ NSArray *prefixes = @[@"WHO.2006", @"CDC.2000"];
NSError *error = nil;
NSMutableArray *arr = [NSMutableArray arrayWithCapacity:[bundled count]];
for (NSString *path in bundled) {
- // for now, all our charts start with "grchrt", so let's use this as a filter
+ // check if they have one of our prefixes
NSString *file = [path lastPathComponent];
- if (![prefix isEqualToString:[file substringToIndex:MIN([file length], [prefix length])]]) {
+ BOOL hasPrefix = NO;
+ for (NSString *prefix in prefixes) {
+ if ([prefix isEqualToString:[file substringToIndex:MIN([file length], [prefix length])]]) {
+ hasPrefix = YES;
+ break;
+ }
+ }
+
+ if (!hasPrefix) {
continue;
}
@@ -77,6 +85,27 @@ + (NSArray *)bundledCharts
}
}
+ // sort by age, WHO first then by age range
+ [arr sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
+ CHChart *chart1 = (CHChart *)obj1;
+ CHChart *chart2 = (CHChart *)obj2;
+
+ NSComparisonResult acro = [chart2.sourceAcronym caseInsensitiveCompare:chart1.sourceAcronym];
+ if (NSOrderedSame != acro) {
+ return acro;
+ }
+
+ // same source, order by age range
+ PPRange *range1 = chart1.ageRangeMonths;
+ PPRange *range2 = chart2.ageRangeMonths;
+
+ NSComparisonResult lower = [range1.from compare:range2.from];
+ if (NSOrderedSame == lower) {
+ return [range1.to compare:range2.to];
+ }
+ return lower;
+ }];
+
return arr;
}
View
36 growth-charts-helper/FromCharts/CHDateUnit.m
@@ -13,6 +13,12 @@
@implementation CHDateUnit
+/**
+ * Composes a string that best describes the receiver as an age for a human being.
+ *
+ * Ages below 2 years will be displayed in months and days.
+ * Ages above 2 years will be displayed in years and months, with days for the "CHValueStringSizeLong" format.
+ */
- (NSString *)stringValueForNumber:(NSDecimalNumber *)number withSize:(CHValueStringSize)size
{
// convert to NSDate and get components
@@ -22,45 +28,47 @@ - (NSString *)stringValueForNumber:(NSDecimalNumber *)number withSize:(CHValueSt
// compose a string -- year
NSMutableArray *parts = [NSMutableArray arrayWithCapacity:3];
if (comp.year > 0) {
- if (1 == comp.year) {
+ if (comp.year < 2) {
comp.month += 12;
}
else {
if (CHValueStringSizeLong == size) {
- [parts addObject:[NSString stringWithFormat:@"%d years", (int)comp.year]];
+ [parts addObject:[NSString stringWithFormat:@"%d years", comp.year]];
}
else if (CHValueStringSizeCompact == size) {
- [parts addObject:[NSString stringWithFormat:@"%dy", (int)comp.year]];
+ [parts addObject:[NSString stringWithFormat:@"%dy", comp.year]];
}
else {
- [parts addObject:[NSString stringWithFormat:@"%d y", (int)comp.year]];
+ [parts addObject:[NSString stringWithFormat:@"%d y", comp.year]];
}
}
}
// months
if (comp.month > 0) {
if (CHValueStringSizeLong == size) {
- [parts addObject:[NSString stringWithFormat:@"%d month%@", (int)comp.month, (1 == comp.month ? @"" : @"s")]];
+ [parts addObject:[NSString stringWithFormat:@"%d month%@", comp.month, (1 == comp.month ? @"" : @"s")]];
}
else if (CHValueStringSizeCompact == size) {
- [parts addObject:[NSString stringWithFormat:@"%dm", (int)comp.month]];
+ [parts addObject:[NSString stringWithFormat:@"%dm", comp.month]];
}
else {
- [parts addObject:[NSString stringWithFormat:@"%d mth", (int)comp.month]];
+ [parts addObject:[NSString stringWithFormat:@"%d mth", comp.month]];
}
}
// days
if (comp.day > 0) {
if (CHValueStringSizeLong == size) {
- [parts addObject:[NSString stringWithFormat:@"%d day%@", (int)comp.day, (1 == comp.day ? @"" : @"s")]];
- }
- else if (CHValueStringSizeCompact == size) {
- [parts addObject:[NSString stringWithFormat:@"%dd", (int)comp.day]];
+ [parts addObject:[NSString stringWithFormat:@"%d day%@", comp.day, (1 == comp.day ? @"" : @"s")]];
}
- else {
- [parts addObject:[NSString stringWithFormat:@"%d d", (int)comp.day]];
+ else if (comp.year < 2) {
+ if (CHValueStringSizeCompact == size) {
+ [parts addObject:[NSString stringWithFormat:@"%dd", comp.day]];
+ }
+ else {
+ [parts addObject:[NSString stringWithFormat:@"%d d", comp.day]];
+ }
}
}
@@ -142,7 +150,7 @@ - (NSDecimalNumber *)numberInBaseUnit:(NSDecimalNumber *)number
NSDate *date = [self dateValueFor:number fromDate:self.referenceDate];
NSDateComponents *comp = [[NSCalendar currentCalendar] components:NSSecondCalendarUnit fromDate:self.referenceDate toDate:date options:0];
- return [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:@"%d", (int)comp.second]];
+ return [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:@"%i", comp.second]];
}
View
9 growth-charts-helper/FromCharts/CHUnit.h
@@ -23,10 +23,15 @@
@property (nonatomic, assign) short precision; ///< The default precision to round to, 2 by default
@property (nonatomic, strong) NSDecimalNumber *baseMultiplier; ///< How to convert to base unit
@property (nonatomic, assign) BOOL isBaseUnit;
+@property (nonatomic, strong) NSDecimalNumber *plausibleMin;
+@property (nonatomic, strong) NSDecimalNumber *plausibleMax;
+
+ (NSArray *)unitsOfDimension:(NSString *)dimension baseUnit:(CHUnit * __autoreleasing *)defaultUnit;
++ (NSArray *)unitsForDataType:(NSString *)dataType;
+ (id)newWithPath:(NSString *)aPath;
++ (id)newFromDictionary:(NSDictionary *)dict withName:(NSString *)name inDimension:(NSString *)dimension;
- (NSString *)path;
- (NSString *)stringValueForNumber:(NSDecimalNumber *)number;
@@ -38,6 +43,10 @@
- (BOOL)isSameDimension:(CHUnit *)otherUnit;
+- (NSInteger)checkPlausibilityOfNumber:(NSDecimalNumber *)number;
+- (void)setMinPlausibleFromBaseUnit:(NSString *)numString;
+- (void)setMaxPlausibleFromBaseUnit:(NSString *)numString;
+
+ (NSDictionary *)dictionaryForDimension:(NSString *)dimension;
+ (Class)classForDimension:(NSString *)dimension;
View
250 growth-charts-helper/FromCharts/CHUnit.m
@@ -14,57 +14,6 @@ @implementation CHUnit
/**
- * You really should use this method to create new unit instances!
- * @param aPath The unit path in the form "dimension.unitname"
- */
-+ (id)newWithPath:(NSString *)aPath
-{
- NSArray *parts = [aPath componentsSeparatedByString:@"."];
- if (2 == [parts count]) {
- NSString *dimension = [parts objectAtIndex:0];
- NSString *name = [parts objectAtIndex:1];
-
- // instantiate the correct class
- NSDictionary *dimDict = [self dictionaryForDimension:dimension];
- if (dimDict) {
- NSString *baseName = [dimDict objectForKey:@"base"];
- if ([baseName length] > 0) {
-
- // instantiate
- Class class = [self classForDimension:dimension];
- NSDictionary *dict = nil;
- for (NSDictionary *unitDict in [dimDict objectForKey:@"units"]) {
- if ([name isEqualToString:[unitDict objectForKey:@"name"]]) {
- dict = unitDict;
- break;
- }
- }
-
- CHUnit *unit = [class new];
- unit.dimension = dimension;
- unit.name = name;
- unit.label = [dict objectForKey:@"label"];
- unit.baseMultiplier = [dict objectForKey:@"baseMultiplier"] ? [NSDecimalNumber decimalNumberWithString:[dict objectForKey:@"baseMultiplier"]] : nil;
- unit.isBaseUnit = [baseName isEqualToString:name];
-
- return unit;
- }
- else {
- DLog(@"There is no base unit for dimension %@", dimension);
- }
- }
- else {
- DLog(@"There is no definition of the dimension \"%@\" in units.plist", dimension);
- }
- }
- else {
- DLog(@"Failed to instantiate from path \"%@\", which should be in the form \"dimension.unitname\"", aPath);
- }
-
- return nil;
-}
-
-/**
* This is the designated initializer.
*/
- (id)init
@@ -174,11 +123,16 @@ - (NSDecimalNumber *)numberFromBaseUnit:(NSDecimalNumber *)number
}
/**
- * Assumes that number is in the receivers unit and converts it to the given unit
- * TODO: Implement
+ * Assumes that number is in the receivers unit and converts it to the given unit.
*/
- (NSDecimalNumber *)convertNumber:(NSDecimalNumber *)number toUnit:(CHUnit *)unit
{
+ // no unit or same unit anyway?
+ if (!unit || [self isEqual:unit]) {
+ return number;
+ }
+
+ // must be same dimension
if (![self isSameDimension:unit]) {
DLog(@"I can not convert to a unit from another dimension (%@ -> %@)", self.dimension, unit.dimension);
return nil;
@@ -189,7 +143,7 @@ - (NSDecimalNumber *)convertNumber:(NSDecimalNumber *)number toUnit:(CHUnit *)un
}
/**
- * Rounds the number according to the unit's information
+ * Rounds the number according to the unit's information.
*/
- (NSDecimalNumber *)roundedNumber:(NSDecimalNumber *)number
{
@@ -207,8 +161,133 @@ - (NSDecimalNumber *)roundedNumber:(NSDecimalNumber *)number
+#pragma mark - Plausibility Testing
+/**
+ * Checks whether a number in the receiver's unit physiologically makes sense.
+ */
+- (NSInteger)checkPlausibilityOfNumber:(NSDecimalNumber *)number
+{
+ if (!number || [number isEqual:[NSDecimalNumber notANumber]]) {
+ return 0;
+ }
+
+ if (_plausibleMin && NSOrderedAscending == [number compare:_plausibleMin]) {
+ return -1;
+ }
+ if (_plausibleMax && NSOrderedDescending == [number compare:_plausibleMax]) {
+ return 1;
+ }
+ return 0;
+}
+
+- (void)setMinPlausibleFromBaseUnit:(NSString *)numString
+{
+ if ([numString length] < 1) {
+ return;
+ }
+ if (!_isBaseUnit && !_baseMultiplier) {
+ DLog(@"I need to know the base unit first");
+ return;
+ }
+
+ NSDecimalNumber *number = [NSDecimalNumber decimalNumberWithString:numString];
+ self.plausibleMin = [self numberFromBaseUnit:number];
+}
+
+- (void)setMaxPlausibleFromBaseUnit:(NSString *)numString
+{
+ if ([numString length] < 1) {
+ return;
+ }
+ if (!_isBaseUnit && !_baseMultiplier) {
+ DLog(@"I need to know the base unit first");
+ return;
+ }
+
+ NSDecimalNumber *number = [NSDecimalNumber decimalNumberWithString:numString];
+ self.plausibleMax = [self numberFromBaseUnit:number];
+}
+
+
+
#pragma mark - Unit Loading
/**
+ * You really should use this method to create new unit instances!
+ * @param aPath The unit path in the form "dimension.unitname"
+ */
++ (id)newWithPath:(NSString *)aPath
+{
+ NSArray *parts = [aPath componentsSeparatedByString:@"."];
+ if (2 == [parts count]) {
+ NSString *dimension = [parts objectAtIndex:0];
+ NSString *name = [parts objectAtIndex:1];
+
+ // instantiate the correct class
+ NSDictionary *dimDict = [self dictionaryForDimension:dimension];
+ if (dimDict) {
+ NSString *baseName = [dimDict objectForKey:@"base"];
+ if ([baseName length] > 0) {
+ NSString *plausMin = [dimDict objectForKey:@"plausible-min"];
+ NSString *plausMax = [dimDict objectForKey:@"plausible-max"];
+
+ // find the respective dictionary in the dimension's dictionary
+ Class class = [self classForDimension:dimension];
+ NSDictionary *dict = nil;
+ for (NSDictionary *unitDict in [dimDict objectForKey:@"units"]) {
+ if ([name isEqualToString:[unitDict objectForKey:@"name"]]) {
+ dict = unitDict;
+ break;
+ }
+ }
+
+ // instantiate
+ CHUnit *unit = [class newFromDictionary:dict withName:name inDimension:dimension];
+ if (!unit) {
+ DLog(@"Could not instantiate a unit for \"%@\"", aPath);
+ }
+
+ // set dimension properties
+ unit.isBaseUnit = [baseName isEqualToString:name];
+ [unit setMinPlausibleFromBaseUnit:plausMin];
+ [unit setMinPlausibleFromBaseUnit:plausMax];
+
+ return unit;
+ }
+ else {
+ DLog(@"There is no base unit for dimension %@", dimension);
+ }
+ }
+ else {
+ DLog(@"There is no definition of the dimension \"%@\" in units.plist", dimension);
+ }
+ }
+ else if (aPath) {
+ DLog(@"Failed to instantiate from path \"%@\", which should be in the form \"dimension.unitname\"", aPath);
+ }
+
+ return nil;
+}
+
+/**
+ * Creates a new instance with the properties found in the dictionary.
+ */
++ (id)newFromDictionary:(NSDictionary *)dict withName:(NSString *)name inDimension:(NSString *)dimension
+{
+ if (!dimension && (!dict || !name)) {
+ return nil;
+ }
+
+ CHUnit *unit = [self new];
+ unit.dimension = dimension;
+ unit.name = ([name length] > 0) ? name : [dict objectForKey:@"name"];
+ unit.label = [dict objectForKey:@"label"];
+ unit.baseMultiplier = [dict objectForKey:@"baseMultiplier"] ? [NSDecimalNumber decimalNumberWithString:[dict objectForKey:@"baseMultiplier"]] : nil;
+
+ return unit;
+}
+
+
+/**
* Returns an array of all units for a given dimension.
* @param dimension The name of the dimension
* @param defaultUnit A pointer that will be filled with the default unit
@@ -220,23 +299,25 @@ + (NSArray *)unitsOfDimension:(NSString *)dimension baseUnit:(CHUnit * __autorel
Class class = [self classForDimension:dimension];
NSString *baseName = [dimDict objectForKey:@"base"];
if ([baseName length] > 0) {
+ NSString *plausMin = [dimDict objectForKey:@"plausible-min"];
+ NSString *plausMax = [dimDict objectForKey:@"plausible-max"];
NSArray *units = [dimDict objectForKey:@"units"];
NSMutableArray *arr = [NSMutableArray arrayWithCapacity:[units count]];
// loop the dimension
for (NSDictionary *dict in units) {
- CHUnit *unit = [class new];
- unit.dimension = dimension;
- unit.name = [dict objectForKey:@"name"];
- unit.label = [dict objectForKey:@"label"];
- unit.baseMultiplier = [dict objectForKey:@"baseMultiplier"] ? [NSDecimalNumber decimalNumberWithString:[dict objectForKey:@"baseMultiplier"]] : nil;
- unit.isBaseUnit = [baseName isEqualToString:unit.name];
-
- [arr addObject:unit];
-
- // default?
- if (unit.isBaseUnit && NULL != defaultUnit) {
- *defaultUnit = unit;
+ CHUnit *unit = [class newFromDictionary:dict withName:nil inDimension:dimension];
+ if (unit) {
+ [arr addObject:unit];
+
+ // default?
+ unit.isBaseUnit = [baseName isEqualToString:unit.name];
+ if (unit.isBaseUnit && NULL != defaultUnit) {
+ *defaultUnit = unit;
+ }
+
+ [unit setMinPlausibleFromBaseUnit:plausMin];
+ [unit setMaxPlausibleFromBaseUnit:plausMax];
}
}
@@ -252,6 +333,38 @@ + (NSArray *)unitsOfDimension:(NSString *)dimension baseUnit:(CHUnit * __autorel
return nil;
}
+/**
+ * Returns the appropriate units from the appropriate dimension for a given data type.
+ * @todo Hardcoded, should move to plist
+ */
++ (NSArray *)unitsForDataType:(NSString *)dataType
+{
+ if ([@"bodyweight" isEqualToString:dataType]) {
+ return [self unitsOfDimension:@"weight" baseUnit:nil];
+ }
+ if ([@"bodylength" isEqualToString:dataType]) {
+ return [self unitsOfDimension:@"length" baseUnit:nil];
+ }
+ if ([@"headcircumference" isEqualToString:dataType]) {
+ NSMutableArray *lengthUnits = [[self unitsOfDimension:@"length" baseUnit:nil] mutableCopy];
+ CHUnit *meterUnit = nil;
+ for (CHUnit *unit in lengthUnits) {
+ if ([@"meter" isEqualToString:unit.name]) {
+ meterUnit = unit;
+ break;
+ }
+ }
+ [lengthUnits removeObject:meterUnit];
+ return lengthUnits;
+ }
+ if ([@"age" isEqualToString:dataType]) {
+ return [self unitsOfDimension:@"age" baseUnit:nil];
+ }
+
+ DLog(@"No data type or none that we understand: %@", dataType);
+ return nil;
+}
+
+ (NSDictionary *)dictionaryForDimension:(NSString *)dimension
{
@@ -282,7 +395,7 @@ + (Class)classForDimension:(NSString *)dimension
/**
- * Assumes default units for some measurement types, e.g. "length.centimeter" for "bodylength"
+ * Assumes default units for some measurement types, e.g. "length.centimeter" for "bodylength"
*/
+ (id)defaultUnitForDataType:(NSString *)measurementType
{
@@ -295,6 +408,9 @@ + (id)defaultUnitForDataType:(NSString *)measurementType
if ([@"age" isEqualToString:measurementType]) {
return [self newWithPath:@"age.second"];
}
+ if ([@"bmi" isEqualToString:measurementType]) {
+ return [self newWithPath:@"bmi.kilogram-per-square-meter"];
+ }
DLog(@"There is no default unit for \"%@\", returning an empty unit", measurementType);
return [self new];
View
3 growth-charts-helper/FromCharts/CHValue.h
@@ -24,13 +24,16 @@
+ (id)newWithNumber:(NSDecimalNumber *)number inUnit:(CHUnit *)unit;
- (BOOL)convertToUnit:(CHUnit *)aUnit;
+- (CHValue *)valueInUnit:(CHUnit *)aUnit;
+- (CHValue *)valueInUnitWithName:(NSString *)unitName;
- (NSDecimalNumber *)numberInUnit:(CHUnit *)aUnit;
- (NSDecimalNumber *)numberInUnitWithName:(NSString *)unitName;
- (NSString *)stringValue;
- (NSString *)stringValueWithSize:(CHValueStringSize)size;
+- (NSInteger)checkPlausibility;
- (BOOL)isNull;
View
36 growth-charts-helper/FromCharts/CHValue.m
@@ -26,6 +26,18 @@ + (id)newWithNumber:(NSDecimalNumber *)number inUnit:(CHUnit *)unit
#pragma mark - Properties
/**
+ * Checks whether the measurement seems physiologically plausible; 0 is plausible, -1 too low and 1 too high.
+ */
+- (NSInteger)checkPlausibility
+{
+ if (!_number || !_unit) {
+ return 0;
+ }
+
+ return [_unit checkPlausibilityOfNumber:_number];
+}
+
+/**
* Returns YES if we don't have a number assigned, but *not* if we are zero (!).
*/
- (BOOL)isNull
@@ -38,7 +50,7 @@ - (BOOL)isNull
#pragma mark - Conversion
- (BOOL)convertToUnit:(CHUnit *)aUnit
{
- NSDecimalNumber *newNumber = _unit ? [_unit convertNumber:_number toUnit:aUnit] : _number;
+ NSDecimalNumber *newNumber = (_unit && aUnit) ? [_unit convertNumber:_number toUnit:aUnit] : _number;
if (_number && !newNumber) {
return NO;
}
@@ -49,6 +61,28 @@ - (BOOL)convertToUnit:(CHUnit *)aUnit
return YES;
}
+/**
+ * @return A copy of the receiver, converted to the given unit
+ */
+- (CHValue *)valueInUnit:(CHUnit *)aUnit
+{
+ NSDecimalNumber *newNumber = (_unit && aUnit) ? [_unit convertNumber:_number toUnit:aUnit] : _number;
+ if (_number && !newNumber) {
+ return nil;
+ }
+
+ return [[self class] newWithNumber:newNumber inUnit:aUnit];
+}
+
+- (CHValue *)valueInUnitWithName:(NSString *)unitName
+{
+ CHUnit *otherUnit = [CHUnit newWithPath:[NSString stringWithFormat:@"%@.%@", _unit.dimension, unitName]];
+ return [self valueInUnit:otherUnit];
+}
+
+/**
+ * @return A number in the given unit, calculated from the receiver's number and unit
+ */
- (NSDecimalNumber *)numberInUnit:(CHUnit *)aUnit
{
return [_unit convertNumber:_number toUnit:aUnit];
View
3 growth-charts-helper/FromCharts/PPRange.m
@@ -47,7 +47,8 @@ + (PPRange *)rangeFrom:(NSDecimalNumber *)min to:(NSDecimalNumber *)max
*/
+ (PPRange *)rangeFromString:(NSString *)min toString:(NSString *)max
{
- return [PPRange rangeFrom:[NSDecimalNumber decimalNumberWithString:min] to:[NSDecimalNumber decimalNumberWithString:max]];
+ return [PPRange rangeFrom:(min ? [NSDecimalNumber decimalNumberWithString:min] : nil)
+ to:(max ? [NSDecimalNumber decimalNumberWithString:max] : nil)];
}
/**
View
45 growth-charts-helper/en.lproj/CHDocument.xib
@@ -3,12 +3,12 @@
<data>
<int key="IBDocument.SystemTarget">1070</int>
<string key="IBDocument.SystemVersion">12C60</string>
- <string key="IBDocument.InterfaceBuilderVersion">2844</string>
+ <string key="IBDocument.InterfaceBuilderVersion">3084</string>
<string key="IBDocument.AppKitVersion">1187.34</string>
<string key="IBDocument.HIToolboxVersion">625.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string key="NS.object.0">2844</string>
+ <string key="NS.object.0">3084</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>NSBox</string>
@@ -368,7 +368,7 @@
<object class="NSSegmentedControl" id="9922798">
<reference key="NSNextResponder" ref="94279693"/>
<int key="NSvFlags">266</int>
- <string key="NSFrame">{{151, 615}, {186, 25}}</string>
+ <string key="NSFrame">{{153, 615}, {182, 25}}</string>
<reference key="NSSuperview" ref="94279693"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="266308193"/>
@@ -399,7 +399,7 @@
<int key="NSSegmentItemImageScaling">0</int>
</object>
</array>
- <int key="NSSegmentStyle">2</int>
+ <int key="NSSegmentStyle">4</int>
</object>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
@@ -705,7 +705,6 @@
<int key="NSvFlags">10</int>
<string key="NSFrame">{{10, 295}, {334, 345}}</string>
<reference key="NSSuperview" ref="355261897"/>
- <reference key="NSNextKeyView" ref="935831569"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<array class="NSMutableArray" key="NSTabViewItems">
<object class="NSTabViewItem" id="762433259">
@@ -1362,27 +1361,28 @@
<string key="NSKeyEquivalent"/>
<int key="NSPeriodicDelay">400</int>
<int key="NSPeriodicInterval">75</int>
- <nil key="NSMenuItem"/>
+ <object class="NSMenuItem" key="NSMenuItem" id="53896478">
+ <reference key="NSMenu" ref="627883034"/>
+ <string key="NSTitle">plot</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <int key="NSState">1</int>
+ <object class="NSCustomResource" key="NSOnImage" id="626103815">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">NSMenuCheckmark</string>
+ </object>
+ <object class="NSCustomResource" key="NSMixedImage" id="913302606">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">NSMenuMixedState</string>
+ </object>
+ <string key="NSAction">_popUpItemAction:</string>
+ <reference key="NSTarget" ref="627935610"/>
+ </object>
<bool key="NSMenuItemRespectAlignment">YES</bool>
<object class="NSMenu" key="NSMenu" id="627883034">
<string key="NSTitle">OtherViews</string>
<array class="NSMutableArray" key="NSMenuItems">
- <object class="NSMenuItem" id="53896478">
- <reference key="NSMenu" ref="627883034"/>
- <string key="NSTitle">plot</string>
- <string key="NSKeyEquiv"/>
- <int key="NSMnemonicLoc">2147483647</int>
- <object class="NSCustomResource" key="NSOnImage" id="626103815">
- <string key="NSClassName">NSImage</string>
- <string key="NSResourceName">NSMenuCheckmark</string>
- </object>
- <object class="NSCustomResource" key="NSMixedImage" id="913302606">
- <string key="NSClassName">NSImage</string>
- <string key="NSResourceName">NSMenuMixedState</string>
- </object>
- <string key="NSAction">_popUpItemAction:</string>
- <reference key="NSTarget" ref="627935610"/>
- </object>
+ <reference ref="53896478"/>
<object class="NSMenuItem" id="981282632">
<reference key="NSMenu" ref="627883034"/>
<string key="NSTitle">text</string>
@@ -1443,7 +1443,6 @@
<int key="NSvFlags">274</int>
<string key="NSFrame">{{1, 1}, {324, 97}}</string>
<reference key="NSSuperview" ref="27707940"/>
- <reference key="NSNextKeyView"/>
<string key="NSReuseIdentifierKey">_NS:11</string>
</object>
</array>

0 comments on commit 4ace9a3

Please sign in to comment.