aboutsummaryrefslogtreecommitdiff
path: root/AppKit
diff options
context:
space:
mode:
authorGravatar gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3>2009-03-27 17:15:24 +0000
committerGravatar gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3>2009-03-27 17:15:24 +0000
commite3c268753ab7a8cf62bdf66d64d86707a850a933 (patch)
tree24c0380f59a0ec0d5f9999e53ea634c0b1b974c1 /AppKit
parent6545da262e160fc959e1fe869c517daeff1e184e (diff)
[Author: dmaclach]
Change build script so that it removes all of the gcda files for the current config project wide, which in general is what people will want. Added unit testing to GTMHotKeyTextField. From about 6% up to 90%. DELTA=10 (3 added, 0 deleted, 7 changed) R=thomasvl
Diffstat (limited to 'AppKit')
-rw-r--r--AppKit/GTMHotKeyTextField.m213
-rw-r--r--AppKit/GTMHotKeyTextFieldTest.h31
-rw-r--r--AppKit/GTMHotKeyTextFieldTest.m255
-rw-r--r--AppKit/GTMHotKeyTextFieldTest.xib383
4 files changed, 718 insertions, 164 deletions
diff --git a/AppKit/GTMHotKeyTextField.m b/AppKit/GTMHotKeyTextField.m
index 6573743..fb479fd 100644
--- a/AppKit/GTMHotKeyTextField.m
+++ b/AppKit/GTMHotKeyTextField.m
@@ -61,7 +61,6 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL;
#endif
- (void)dealloc {
-
if (boundObject_ && boundKeyPath_) {
[boundObject_ gtm_removeObserver:self
forKeyPath:boundKeyPath_
@@ -71,7 +70,6 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL;
[boundKeyPath_ release];
[hotKeyDict_ release];
[super dealloc];
-
}
#pragma mark Bindings
@@ -80,7 +78,6 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL;
- (void)bind:(NSString *)binding toObject:(id)observableController
withKeyPath:(NSString *)keyPath
options:(NSDictionary *)options {
-
if ([binding isEqualToString:NSValueBinding]) {
// Update to our new binding
[self setupBinding:observableController withPath:keyPath];
@@ -90,11 +87,9 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL;
toObject:observableController
withKeyPath:keyPath
options:options];
-
}
- (void)unbind:(NSString *)binding {
-
// Clean up value on unbind
if ([binding isEqualToString:NSValueBinding]) {
if (boundObject_ && boundKeyPath_) {
@@ -108,7 +103,6 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL;
boundKeyPath_ = nil;
}
[super unbind:binding];
-
}
- (void)hotKeyValueChanged:(GTMKeyValueChangeNotification *)note {
@@ -131,7 +125,6 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL;
// Private convenience method for attaching to a new binding
- (void)setupBinding:(id)bound withPath:(NSString *)path {
-
// Release previous
if (boundObject_ && boundKeyPath_) {
[boundObject_ gtm_removeObserver:self
@@ -154,174 +147,117 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL;
hotKeyDict_ = [[boundObject_ valueForKeyPath:boundKeyPath_] copy];
// Update the display string
[self updateDisplayedPrettyString];
-
}
#pragma mark Defeating NSControl
-- (double)doubleValue {
-
+- (int)logBadValueAccess {
// Defeating NSControl
- _GTMDevAssert(NO, @"Hot key fields don't take numbers.");
- return 0.0;
-
+ _GTMDevLog(@"Hot key fields don't take numbers.");
+ return 0;
}
-- (void)setDoubleValue:(double)value {
-
+- (void)logBadStringValueAccess {
// Defeating NSControl
- _GTMDevAssert(NO, @"Hot key fields don't take numbers.");
- return;
-
+ _GTMDevLog(@"Hot key fields want dictionaries, not strings.");
+}
+
+
+- (double)doubleValue {
+ return [self logBadValueAccess];
+}
+
+- (void)setDoubleValue:(double)value {
+ [self logBadValueAccess];
}
- (float)floatValue {
-
- // Defeating NSControl
- _GTMDevAssert(NO, @"Hot key fields don't take numbers.");
- return 0.0f;
-
+ return [self logBadValueAccess];
}
- (void)setFloatValue:(float)value {
-
- // Defeating NSControl
- _GTMDevAssert(NO, @"Hot key fields don't take numbers.");
- return;
-
+ [self logBadValueAccess];
}
- (int)intValue {
-
- // Defeating NSControl
- _GTMDevAssert(NO, @"Hot key fields don't take numbers.");
- return 0;
-
+ return [self logBadValueAccess];
}
- (void)setIntValue:(int)value {
-
- // Defeating NSControl
- _GTMDevAssert(NO, @"Hot key fields don't take numbers.");
- return;
-
+ [self logBadValueAccess];
}
#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
- (NSInteger)integerValue {
-
- // Defeating NSControl
- _GTMDevAssert(NO, @"Hot key fields don't take numbers.");
- return 0;
-
+ return [self logBadValueAccess];
}
- (void)setIntegerValue:(NSInteger)value {
-
- // Defeating NSControl
- _GTMDevAssert(NO, @"Hot key fields don't take numbers.");
- return;
-
+ [self logBadValueAccess];
}
#endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
- (id)objectValue {
-
return [self hotKeyValue];
-
}
- (void)setObjectValue:(id)object {
-
[self setHotKeyValue:object];
-
}
- (NSString *)stringValue {
-
return [[self class] displayStringForHotKey:hotKeyDict_];
-
}
- (void)setStringValue:(NSString *)string {
-
- // Defeating NSControl
- _GTMDevAssert(NO, @"Hot key fields want dictionaries, not strings.");
- return;
-
+ [self logBadStringValueAccess];
}
- (NSAttributedString *)attributedStringValue {
-
+ NSAttributedString *attrString = nil;
NSString *prettyString = [self stringValue];
- if (!prettyString) return nil;
- return [[[NSAttributedString alloc] initWithString:prettyString] autorelease];
-
+ if (prettyString) {
+ attrString = [[[NSAttributedString alloc]
+ initWithString:prettyString] autorelease];
+ }
+ return attrString;
}
- (void)setAttributedStringValue:(NSAttributedString *)string {
-
- // Defeating NSControl
- _GTMDevAssert(NO, @"Hot key fields want dictionaries, not strings.");
- return;
-
+ [self logBadStringValueAccess];
}
- (void)takeDoubleValueFrom:(id)sender {
-
- // Defeating NSControl
- _GTMDevAssert(NO, @"Hot key fields don't take numbers.");
- return;
-
+ [self logBadValueAccess];
}
- (void)takeFloatValueFrom:(id)sender {
-
- // Defeating NSControl
- _GTMDevAssert(NO, @"Hot key fields don't take numbers.");
- return;
-
+ [self logBadValueAccess];
}
- (void)takeIntValueFrom:(id)sender {
-
- // Defeating NSControl
- _GTMDevAssert(NO, @"Hot key fields don't take numbers.");
- return;
-
+ [self logBadValueAccess];
}
- (void)takeObjectValueFrom:(id)sender {
-
// Defeating NSControl
- _GTMDevAssert(NO,
- @"Hot key fields want dictionaries via bindings, not from controls.");
- return;
-
+ _GTMDevLog(@"Hot key fields want dictionaries via bindings, "
+ @"not from controls.");
}
- (void)takeStringValueFrom:(id)sender {
-
- // Defeating NSControl
- _GTMDevAssert(NO, @"Hot key fields want dictionaries, not strings.");
- return;
-
+ [self logBadStringValueAccess];
}
- (id)formatter {
-
return nil;
-
}
- (void)setFormatter:(NSFormatter *)newFormatter {
-
// Defeating NSControl
- _GTMDevAssert(NO, @"Hot key fields don't accept formatters.");
- return;
-
+ _GTMDevLog(@"Hot key fields don't accept formatters.");
}
#pragma mark Hot Key Support
@@ -338,7 +274,6 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL;
}
- (void)setHotKeyValue:(NSDictionary *)hotKey {
-
// Sanity only if set, nil is OK
if (hotKey && ![[self class] isValidHotKey:hotKey]) {
return;
@@ -348,26 +283,21 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL;
if (boundObject_ && boundKeyPath_) {
// If the change is accepted this will call us back as an observer
[boundObject_ setValue:hotKey forKeyPath:boundKeyPath_];
- return;
+ } else {
+ // Otherwise we directly update ourself
+ [hotKeyDict_ autorelease];
+ hotKeyDict_ = [hotKey copy];
+ [self updateDisplayedPrettyString];
}
-
- // Otherwise we directly update ourself
- [hotKeyDict_ autorelease];
- hotKeyDict_ = [hotKey copy];
- [self updateDisplayedPrettyString];
-
}
- (NSDictionary *)hotKeyValue {
-
return hotKeyDict_;
-
}
// Private method to update the displayed text of the field with the
// user-readable representation.
- (void)updateDisplayedPrettyString {
-
// Basic validation
if (![[self class] isValidHotKey:hotKeyDict_]) {
[super setStringValue:@""];
@@ -384,7 +314,6 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL;
}
+ (NSString *)displayStringForHotKey:(NSDictionary *)hotKeyDict {
-
if (!hotKeyDict) return nil;
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
@@ -406,14 +335,12 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL;
resourceBundle:bundle];
if (!keystroke || ![keystroke length]) return nil;
return [NSString stringWithFormat:@"%@%@", mods, keystroke];
-
}
#pragma mark Field Editor Callbacks
- (BOOL)textShouldBeginEditing:(GTMHotKeyFieldEditor *)fieldEditor {
-
// Sanity
if (![fieldEditor isKindOfClass:[GTMHotKeyFieldEditor class]]) {
_GTMDevLog(@"Field editor not appropriate for field, check window delegate");
@@ -431,11 +358,9 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL;
// Update the field editor internal hotkey representation
[fieldEditor setHotKeyDictionary:hotKeyDict_]; // OK if its nil
return YES;
-
}
- (void)textDidChange:(NSNotification *)notification {
-
// Sanity
GTMHotKeyFieldEditor *fieldEditor = [notification object];
if (![fieldEditor isKindOfClass:[GTMHotKeyFieldEditor class]]) {
@@ -449,11 +374,9 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL;
// Let super handle the notifications
[super textDidChange:notification];
-
}
- (BOOL)textShouldEndEditing:(GTMHotKeyFieldEditor *)fieldEditor {
-
// Sanity
if (![fieldEditor isKindOfClass:[GTMHotKeyFieldEditor class]]) {
_GTMDevLog(@"Field editor not appropriate for field, check window delegate");
@@ -475,7 +398,6 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL;
[self setHotKeyValue:[fieldEditor hotKeyDictionary]];
return YES;
-
}
#pragma mark Class methods building strings for use w/in the UI.
@@ -511,7 +433,6 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL;
// conflicts.
+ (NSString *)stringForModifierFlags:(unsigned int)flags {
-
UniChar modChars[4]; // We only look for 4 flags
unsigned int charCount = 0;
// These are in the same order as the menu manager shows them
@@ -521,13 +442,11 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL;
if (flags & NSCommandKeyMask) modChars[charCount++] = kCommandUnicode;
if (charCount == 0) return nil;
return [NSString stringWithCharacters:modChars length:charCount];
-
}
+ (NSString *)stringForKeycode:(UInt16)keycode
useGlyph:(BOOL)useGlyph
resourceBundle:(NSBundle *)bundle {
-
// Some keys never move in any layout (to the best of our knowledge at least)
// so we can hard map them.
UniChar key = 0;
@@ -774,7 +693,6 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL;
}
return keystrokeString;
-
}
@end
@@ -784,45 +702,37 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL;
GTMOBJECT_SINGLETON_BOILERPLATE(GTMHotKeyFieldEditor, sharedHotKeyFieldEditor)
- (id)init {
-
- self = [super init];
- if (!self) return nil;
- [self setFieldEditor:YES]; // We are a field editor
-
+ if ((self = [super init])) {
+ [self setFieldEditor:YES]; // We are a field editor
+ }
return self;
-
}
+// COV_NF_START
+// Singleton so never called.
- (void)dealloc {
-
[hotKeyDict_ release];
[super dealloc];
-
}
+// COV_NF_END
+
- (NSArray *)acceptableDragTypes {
-
// Don't take drags
return [NSArray array];
-
}
- (NSArray *)readablePasteboardTypes {
-
// No pasting
return [NSArray array];
-
}
- (NSArray *)writablePasteboardTypes {
-
// No copying
return [NSArray array];
-
}
- (BOOL)becomeFirstResponder {
-
// We need to lose focus any time the window is not key
NSNotificationCenter *dc = [NSNotificationCenter defaultCenter];
[dc addObserver:self
@@ -830,55 +740,45 @@ GTMOBJECT_SINGLETON_BOILERPLATE(GTMHotKeyFieldEditor, sharedHotKeyFieldEditor)
name:NSWindowDidResignKeyNotification
object:[self window]];
return [super becomeFirstResponder];
-
}
- (BOOL)resignFirstResponder {
-
// No longer interested in window resign
[[NSNotificationCenter defaultCenter] removeObserver:self];
return [super resignFirstResponder];
-
}
// Private method we use to get out of global hotkey capture when the window
// is no longer front
- (void)windowResigned:(NSNotification *)notification {
-
// Lose our focus
- [[self window] makeFirstResponder:[self window]];
+ NSWindow *window = [self window];
+ [window makeFirstResponder:window];
}
- (BOOL)shouldDrawInsertionPoint {
-
// Show an insertion point, because we'll kill our own focus after
// each entry
return YES;
-
}
- (NSRange)selectionRangeForProposedRange:(NSRange)proposedSelRange
granularity:(NSSelectionGranularity)granularity {
-
// Always select everything
return NSMakeRange(0, [[self textStorage] length]);
-
}
- (void)keyDown:(NSEvent *)theEvent {
-
if ([self shouldBypassEvent:theEvent]) {
[super keyDown:theEvent];
} else {
// Try to eat the event
[self processEventToHotKeyAndString:theEvent];
}
-
}
- (BOOL)performKeyEquivalent:(NSEvent *)theEvent {
-
if ([self shouldBypassEvent:theEvent]) {
return [super performKeyEquivalent:theEvent];
} else {
@@ -886,12 +786,10 @@ GTMOBJECT_SINGLETON_BOILERPLATE(GTMHotKeyFieldEditor, sharedHotKeyFieldEditor)
[self processEventToHotKeyAndString:theEvent];
return YES;
}
-
}
// Private do method that tell us to ignore certain events
- (BOOL)shouldBypassEvent:(NSEvent *)theEvent {
-
UInt16 keyCode = [theEvent keyCode];
NSUInteger modifierFlags
= [theEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask;
@@ -920,13 +818,11 @@ GTMOBJECT_SINGLETON_BOILERPLATE(GTMHotKeyFieldEditor, sharedHotKeyFieldEditor)
}
return NO;
-
}
// Private method that turns events into strings and dictionaries for our
// hotkey plumbing.
- (void)processEventToHotKeyAndString:(NSEvent *)theEvent {
-
// Construct a dictionary of the event as a hotkey pref
NSDictionary *newHotKey = [self hotKeyDictionaryForEvent:theEvent];
if (!newHotKey) {
@@ -964,17 +860,13 @@ GTMOBJECT_SINGLETON_BOILERPLATE(GTMHotKeyFieldEditor, sharedHotKeyFieldEditor)
// its better than constantly capturing user events. This is exactly
// like the Apple editor in their Keyboard pref pane.
[[[self delegate] cell] endEditing:self];
-
}
- (NSDictionary *)hotKeyDictionary {
-
return hotKeyDict_;
-
}
- (void)setHotKeyDictionary:(NSDictionary *)hotKey {
-
[hotKeyDict_ autorelease];
hotKeyDict_ = [hotKey copy];
// Update content
@@ -986,11 +878,9 @@ GTMOBJECT_SINGLETON_BOILERPLATE(GTMHotKeyFieldEditor, sharedHotKeyFieldEditor)
prettyString = @"";
}
[self setString:prettyString];
-
}
-- (NSDictionary *)hotKeyDictionaryForEvent:(NSEvent *)event{
-
+- (NSDictionary *)hotKeyDictionaryForEvent:(NSEvent *)event {
if (!event) return nil;
// Check event
@@ -1018,7 +908,6 @@ GTMOBJECT_SINGLETON_BOILERPLATE(GTMHotKeyFieldEditor, sharedHotKeyFieldEditor)
[NSNumber numberWithUnsignedInt:cleanFlags],
kGTMHotKeyModifierFlagsKey,
nil];
-
}
-@end
+@end
diff --git a/AppKit/GTMHotKeyTextFieldTest.h b/AppKit/GTMHotKeyTextFieldTest.h
new file mode 100644
index 0000000..8cf05c2
--- /dev/null
+++ b/AppKit/GTMHotKeyTextFieldTest.h
@@ -0,0 +1,31 @@
+// GTMHotKeyTextFieldTest.h
+//
+// Copyright 2006-2009 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+//
+
+#import <Cocoa/Cocoa.h>
+
+@class GTMHotKeyTextField;
+
+@interface GTMHotKeyTextFieldTestController : NSWindowController {
+ @private
+ IBOutlet GTMHotKeyTextField *view_;
+}
+
+- (GTMHotKeyTextField *)view;
+@end
+
+@interface GTMHotKeyTextFieldTestControllerWindowDelegate : NSObject
+@end
diff --git a/AppKit/GTMHotKeyTextFieldTest.m b/AppKit/GTMHotKeyTextFieldTest.m
index ee1bfc2..971737a 100644
--- a/AppKit/GTMHotKeyTextFieldTest.m
+++ b/AppKit/GTMHotKeyTextFieldTest.m
@@ -15,9 +15,11 @@
// the License.
//
+#import "GTMHotKeyTextFieldTest.h"
#import "GTMHotKeyTextField.h"
-
#import "GTMSenTestCase.h"
+#import "GTMUnitTestDevLog.h"
+#import <Carbon/Carbon.h>
@interface GTMHotKeyTextField (PrivateMethods)
// Private methods which we want to access to test
@@ -25,11 +27,34 @@
+ (NSString *)displayStringForHotKey:(NSDictionary *)hotKey;
@end
-@interface GTMHotKeyTextFieldTest : GTMTestCase
+@interface GTMHotKeyTextFieldTest : GTMTestCase {
+ @private
+ GTMHotKeyTextFieldTestController *controller_;
+ NSMutableDictionary *hotkeyValues_;
+}
@end
@implementation GTMHotKeyTextFieldTest
+- (void)setUp {
+ controller_ = [[GTMHotKeyTextFieldTestController alloc] init];
+ hotkeyValues_
+ = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
+ [NSNumber numberWithInt:NSCommandKeyMask], kGTMHotKeyModifierFlagsKey,
+ [NSNumber numberWithInt:42], kGTMHotKeyKeyCodeKey,
+ [NSNumber numberWithBool:NO], kGTMHotKeyDoubledModifierKey,
+ nil];
+ STAssertNotNil(hotkeyValues_, nil);
+ STAssertNotNil(controller_, nil);
+ STAssertNotNil([controller_ window], nil);
+}
+
+- (void)tearDown {
+ [controller_ close];
+ [controller_ release];
+ [hotkeyValues_ release];
+}
+
- (void)testStringForModifierFlags {
// Make sure only the flags we expect generate things in their strings
@@ -201,4 +226,230 @@
STAssertFalse([GTMHotKeyTextField isValidHotKey:hkDict], nil);
}
+- (void)testFieldEditorSettersAndGetters {
+ NSWindow *window = [controller_ window];
+ GTMHotKeyTextField *field = [controller_ view];
+ STAssertNotNil(field, nil);
+ GTMHotKeyFieldEditor *editor
+ = (GTMHotKeyFieldEditor *)[window fieldEditor:YES forObject:field];
+ STAssertTrue([editor isMemberOfClass:[GTMHotKeyFieldEditor class]], nil);
+ STAssertEqualObjects(editor,
+ [GTMHotKeyFieldEditor sharedHotKeyFieldEditor],
+ nil);
+ SEL selectors[] =
+ {
+ @selector(readablePasteboardTypes),
+ @selector(acceptableDragTypes),
+ @selector(writablePasteboardTypes)
+ };
+ for (size_t i = 0; i < sizeof(selectors) / sizeof(selectors[0]); ++i) {
+ NSArray *array = [editor performSelector:selectors[i]];
+ STAssertNotNil(array, nil);
+ STAssertEquals([array count], (NSUInteger)0,
+ @"Failed Selector: %@", NSStringFromSelector(selectors[i]));
+ }
+}
+
+- (void)testTextFieldSettersAndGetters {
+ GTMHotKeyTextField *field = [controller_ view];
+ STAssertNotNil(field, nil);
+ NSString *expectedNumberString = @"Hot key fields don't take numbers.";
+ [GTMUnitTestDevLog expect:6 casesOfString:expectedNumberString];
+ [field setDoubleValue:2];
+ [field setIntValue:-1];
+ [field setFloatValue:0];
+ STAssertEquals([field doubleValue], 0.0, nil);
+ STAssertEquals([field intValue], 0, nil);
+ STAssertEquals([field floatValue], 0.0f, nil);
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
+ [GTMUnitTestDevLog expect:2 casesOfString:expectedNumberString];
+ [field setIntegerValue:5];
+ STAssertEquals([field integerValue], (NSInteger)0, nil);
+#endif
+ SEL takeNumberSels[] =
+ {
+ @selector(takeDoubleValueFrom:),
+ @selector(takeFloatValueFrom:),
+ @selector(takeIntValueFrom:)
+ };
+ for (size_t i = 0;
+ i < sizeof(takeNumberSels) / sizeof(takeNumberSels[0]); ++i) {
+ [GTMUnitTestDevLog expect:2 casesOfString:expectedNumberString];
+ [field performSelector:takeNumberSels[i] withObject:self];
+ [field performSelector:takeNumberSels[i] withObject:nil];
+ }
+
+ NSString *expectedStringString
+ = @"Hot key fields want dictionaries, not strings.";
+ [GTMUnitTestDevLog expect:6 casesOfString:expectedStringString];
+ [field takeStringValueFrom:self];
+ [field takeStringValueFrom:nil];
+ [field setStringValue:nil];
+ [field setStringValue:@"foo"];
+
+ NSAttributedString *attrString
+ = [[[NSAttributedString alloc] initWithString:@"foo"] autorelease];
+ [field setAttributedStringValue:nil];
+ [field setAttributedStringValue:attrString];
+
+ STAssertNil([field formatter], nil);
+ [GTMUnitTestDevLog expectString:@"Hot key fields don't accept formatters."];
+ [field setFormatter:nil];
+
+ [GTMUnitTestDevLog expect:2 casesOfString:
+ @"Hot key fields want dictionaries via bindings, not from controls."];
+ [field takeObjectValueFrom:self];
+ [field takeObjectValueFrom:nil];
+}
+
+- (void)pressKey:(NSString *)key code:(NSInteger)code
+ modifierFlags:(NSInteger)flags window:(NSWindow *)window {
+ NSInteger windNum = [window windowNumber];
+ NSGraphicsContext *context = [NSGraphicsContext currentContext];
+ EventTime evtTime = GetCurrentEventTime();
+ NSPoint loc = [NSEvent mouseLocation];
+ NSEvent *keyDownEvt = [NSEvent keyEventWithType:NSKeyDown
+ location:loc
+ modifierFlags:flags
+ timestamp:evtTime
+ windowNumber:windNum
+ context:context
+ characters:key
+ charactersIgnoringModifiers:key
+ isARepeat:NO
+ keyCode:code];
+ NSEvent *keyUpEvt = [NSEvent keyEventWithType:NSKeyUp
+ location:loc
+ modifierFlags:flags
+ timestamp:evtTime
+ windowNumber:windNum
+ context:context
+ characters:key
+ charactersIgnoringModifiers:key
+ isARepeat:NO
+ keyCode:code];
+ STAssertNotNil(keyDownEvt, nil);
+ STAssertNotNil(keyUpEvt, nil);
+ [window sendEvent:keyDownEvt];
+ [window sendEvent:keyUpEvt];
+}
+
+- (void)testTextFieldBindings {
+ NSObjectController *controller
+ = [[[NSObjectController alloc] init] autorelease];
+ [controller bind:NSContentBinding
+ toObject:self
+ withKeyPath:@"self"
+ options:nil];
+ STAssertNotNil(controller, nil);
+ GTMHotKeyTextField *field = [controller_ view];
+ STAssertNotNil(field, nil);
+ [field bind:NSValueBinding
+ toObject:controller
+ withKeyPath:@"selection.hotkeyValues_"
+ options:nil];
+ id value = [field objectValue];
+ STAssertEqualObjects(value, hotkeyValues_, nil);
+ NSString *stringValue = [field stringValue];
+ STAssertEqualObjects(stringValue, @"⌘\\", nil);
+ NSAttributedString *attrStringValue = [field attributedStringValue];
+ STAssertEqualObjects([attrStringValue string], stringValue, nil);
+
+ // Try changing some values
+ [self willChangeValueForKey:@"hotkeyValues_"];
+ [hotkeyValues_ setObject:[NSNumber numberWithInt:43]
+ forKey:kGTMHotKeyKeyCodeKey];
+ [self didChangeValueForKey:@"hotkeyValues_"];
+ stringValue = [field stringValue];
+ STAssertEqualObjects(stringValue, @"⌘,", nil);
+
+ // Now try some typing
+ NSWindow *window = [controller_ window];
+ [window makeFirstResponder:field];
+ [self pressKey:@"A" code:0 modifierFlags:NSShiftKeyMask window:window];
+ stringValue = [field stringValue];
+ STAssertEqualObjects(stringValue, @"⇧A", nil);
+
+ // field is supposed to give up first responder when editing is done.
+ STAssertNotEqualObjects([window firstResponder], field, nil);
+
+ [window makeFirstResponder:field];
+ [self pressKey:@"A" code:0 modifierFlags:NSCommandKeyMask window:window];
+ stringValue = [field stringValue];
+ STAssertEqualObjects(stringValue, @"⌘A", nil);
+
+ // Try without a modifier. This should fail.
+ [window makeFirstResponder:field];
+ [self pressKey:@"s" code:1 modifierFlags:0 window:window];
+ stringValue = [field stringValue];
+ STAssertEqualObjects(stringValue, @"⌘A", nil);
+
+ // Try cmd-q this should fail
+ [window makeFirstResponder:field];
+ [self pressKey:@"Q" code:12 modifierFlags:NSCommandKeyMask window:window];
+ stringValue = [field stringValue];
+ STAssertEqualObjects(stringValue, @"⌘A", nil);
+
+ // Try cmd-w this should fail
+ [window makeFirstResponder:field];
+ [self pressKey:@"W" code:13 modifierFlags:NSCommandKeyMask window:window];
+ stringValue = [field stringValue];
+ STAssertEqualObjects(stringValue, @"⌘A", nil);
+
+ // Try cmd-tab this should fail
+ [window makeFirstResponder:field];
+ [self pressKey:@"\t" code:48 modifierFlags:NSCommandKeyMask window:window];
+ stringValue = [field stringValue];
+ STAssertEqualObjects(stringValue, @"⌘A", nil);
+
+ // Do it by dictionary
+ NSDictionary *cmdSHotKey
+ = [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithInt:NSCommandKeyMask], kGTMHotKeyModifierFlagsKey,
+ [NSNumber numberWithInt:1], kGTMHotKeyKeyCodeKey,
+ [NSNumber numberWithBool:NO], kGTMHotKeyDoubledModifierKey,
+ nil];
+ [field setObjectValue:cmdSHotKey];
+ stringValue = [field stringValue];
+ STAssertEqualObjects(stringValue, @"⌘S", nil);
+
+ // Check to make sure the binding stuck
+ STAssertEqualObjects(cmdSHotKey, hotkeyValues_, nil);
+
+ [field unbind:NSValueBinding];
+ [controller unbind:NSContentBinding];
+
+ NSDictionary *cmdDHotKey
+ = [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithInt:NSCommandKeyMask], kGTMHotKeyModifierFlagsKey,
+ [NSNumber numberWithInt:2], kGTMHotKeyKeyCodeKey,
+ [NSNumber numberWithBool:NO], kGTMHotKeyDoubledModifierKey,
+ nil];
+ [field setObjectValue:cmdDHotKey];
+ stringValue = [field stringValue];
+ STAssertEqualObjects(stringValue, @"⌘D", nil);
+}
+@end
+
+@implementation GTMHotKeyTextFieldTestController
+- (id)init {
+ return [super initWithWindowNibName:@"GTMHotKeyTextFieldTest"];
+}
+
+- (GTMHotKeyTextField *)view {
+ return view_;
+}
+
@end
+
+@implementation GTMHotKeyTextFieldTestControllerWindowDelegate
+
+-(id)windowWillReturnFieldEditor:(NSWindow *)sender toObject:(id)anObject {
+ id editor = nil;
+ if ([anObject isKindOfClass:[GTMHotKeyTextField class]]) {
+ editor = [GTMHotKeyFieldEditor sharedHotKeyFieldEditor];
+ }
+ return editor;
+}
+@end
+
diff --git a/AppKit/GTMHotKeyTextFieldTest.xib b/AppKit/GTMHotKeyTextFieldTest.xib
new file mode 100644
index 0000000..c95b39d
--- /dev/null
+++ b/AppKit/GTMHotKeyTextFieldTest.xib
@@ -0,0 +1,383 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.03">
+ <data>
+ <int key="IBDocument.SystemTarget">1050</int>
+ <string key="IBDocument.SystemVersion">9G55</string>
+ <string key="IBDocument.InterfaceBuilderVersion">677</string>
+ <string key="IBDocument.AppKitVersion">949.43</string>
+ <string key="IBDocument.HIToolboxVersion">353.00</string>
+ <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <integer value="1"/>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSCustomObject" id="1001">
+ <string key="NSClassName">GTMHotKeyTextFieldTestController</string>
+ </object>
+ <object class="NSCustomObject" id="1003">
+ <string key="NSClassName">FirstResponder</string>
+ </object>
+ <object class="NSCustomObject" id="1004">
+ <string key="NSClassName">NSApplication</string>
+ </object>
+ <object class="NSWindowTemplate" id="1005">
+ <int key="NSWindowStyleMask">1</int>
+ <int key="NSWindowBacking">2</int>
+ <string key="NSWindowRect">{{196, 448}, {136, 62}}</string>
+ <int key="NSWTFlags">536870912</int>
+ <string key="NSWindowTitle">Window</string>
+ <string key="NSWindowClass">NSWindow</string>
+ <nil key="NSViewClass"/>
+ <string key="NSWindowContentMaxSize">{3.40282e+38, 3.40282e+38}</string>
+ <object class="NSView" key="NSWindowView" id="1006">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">256</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSTextField" id="972143176">
+ <reference key="NSNextResponder" ref="1006"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{20, 20}, {96, 22}}</string>
+ <reference key="NSSuperview" ref="1006"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="781959520">
+ <int key="NSCellFlags">-1804468671</int>
+ <int key="NSCellFlags2">272630784</int>
+ <string key="NSContents"/>
+ <object class="NSFont" key="NSSupport">
+ <string key="NSName">LucidaGrande</string>
+ <double key="NSSize">1.300000e+01</double>
+ <int key="NSfFlags">1044</int>
+ </object>
+ <reference key="NSControlView" ref="972143176"/>
+ <bool key="NSDrawsBackground">YES</bool>
+ <object class="NSColor" key="NSBackgroundColor">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">textBackgroundColor</string>
+ <object class="NSColor" key="NSColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ </object>
+ </object>
+ <object class="NSColor" key="NSTextColor">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">textColor</string>
+ <object class="NSColor" key="NSColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MAA</bytes>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <string key="NSFrameSize">{136, 62}</string>
+ <reference key="NSSuperview"/>
+ </object>
+ <string key="NSScreenRect">{{0, 0}, {1680, 1028}}</string>
+ <string key="NSMaxSize">{3.40282e+38, 3.40282e+38}</string>
+ </object>
+ <object class="NSCustomObject" id="421484812">
+ <string key="NSClassName">GTMHotKeyTextFieldTestControllerWindowDelegate</string>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">window</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="1005"/>
+ </object>
+ <int key="connectionID">3</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">view_</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="972143176"/>
+ </object>
+ <int key="connectionID">7</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">initialFirstResponder</string>
+ <reference key="source" ref="1005"/>
+ <reference key="destination" ref="972143176"/>
+ </object>
+ <int key="connectionID">12</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="1005"/>
+ <reference key="destination" ref="421484812"/>
+ </object>
+ <int key="connectionID">13</int>
+ </object>
+ </object>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <object class="NSArray" key="orderedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <object class="NSArray" key="object" id="1002">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="1001"/>
+ <reference key="parent" ref="1002"/>
+ <string type="base64-UTF8" key="objectName">RmlsZSdzIE93bmVyA</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="1003"/>
+ <reference key="parent" ref="1002"/>
+ <string key="objectName">First Responder</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-3</int>
+ <reference key="object" ref="1004"/>
+ <reference key="parent" ref="1002"/>
+ <string key="objectName">Application</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">1</int>
+ <reference key="object" ref="1005"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="1006"/>
+ </object>
+ <reference key="parent" ref="1002"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">2</int>
+ <reference key="object" ref="1006"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="972143176"/>
+ </object>
+ <reference key="parent" ref="1005"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">4</int>
+ <reference key="object" ref="972143176"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="781959520"/>
+ </object>
+ <reference key="parent" ref="1006"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">5</int>
+ <reference key="object" ref="781959520"/>
+ <reference key="parent" ref="972143176"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">10</int>
+ <reference key="object" ref="421484812"/>
+ <reference key="parent" ref="1002"/>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="flattenedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSMutableArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>-1.IBPluginDependency</string>
+ <string>-2.IBPluginDependency</string>
+ <string>-3.IBPluginDependency</string>
+ <string>1.IBEditorWindowLastContentRect</string>
+ <string>1.IBPluginDependency</string>
+ <string>1.IBWindowTemplateEditedContentRect</string>
+ <string>1.NSWindowTemplate.visibleAtLaunch</string>
+ <string>1.WindowOrigin</string>
+ <string>1.editorWindowContentRectSynchronizationRect</string>
+ <string>10.IBPluginDependency</string>
+ <string>2.IBPluginDependency</string>
+ <string>4.CustomClassName</string>
+ <string>4.IBPluginDependency</string>
+ <string>5.IBPluginDependency</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>{{746, 673}, {136, 62}}</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>{{746, 673}, {136, 62}}</string>
+ <boolean value="NO"/>
+ <string>{196, 240}</string>
+ <string>{{357, 418}, {480, 270}}</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>GTMHotKeyTextField</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="unlocalizedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="activeLocalization"/>
+ <object class="NSMutableDictionary" key="localizations">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="sourceID"/>
+ <int key="maxID">13</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">GTMHotKeyTextField</string>
+ <string key="superclassName">NSTextField</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">AppKit/GTMHotKeyTextField.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">GTMHotKeyTextFieldTestController</string>
+ <string key="superclassName">NSWindowController</string>
+ <object class="NSMutableDictionary" key="outlets">
+ <string key="NS.key.0">view_</string>
+ <string key="NS.object.0">GTMHotKeyTextField</string>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="690883007">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">AppKit/GTMHotKeyTextFieldTest.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">GTMHotKeyTextFieldTestControllerWindowDelegate</string>
+ <string key="superclassName">NSObject</string>
+ <reference key="sourceIdentifier" ref="690883007"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSApplication</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="837783357">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">UnitTesting/GTMAppKit+UnitTesting.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSCell</string>
+ <reference key="sourceIdentifier" ref="837783357"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSControl</string>
+ <reference key="sourceIdentifier" ref="837783357"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSMenu</string>
+ <reference key="sourceIdentifier" ref="837783357"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">AppKit/GTMCarbonEvent.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">AppKit/GTMDelegatingTableColumn.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Foundation/GTMHTTPServer.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Foundation/GTMNSAppleEventDescriptor+Foundation.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Foundation/GTMNSObject+KeyValueObserving.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">UnitTesting/GTMCALayer+UnitTesting.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">UnitTesting/GTMNSObject+BindingUnitTesting.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">UnitTesting/GTMNSObject+UnitTesting.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSTextField</string>
+ <reference key="sourceIdentifier" ref="837783357"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSView</string>
+ <reference key="sourceIdentifier" ref="837783357"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSWindow</string>
+ <reference key="sourceIdentifier" ref="837783357"/>
+ </object>
+ </object>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.LastKnownRelativeProjectPath">../GTM.xcodeproj</string>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ </data>
+</archive>