diff --git a/AppKit/CPControl.j b/AppKit/CPControl.j index 9e655d796..1d2a567f3 100644 --- a/AppKit/CPControl.j +++ b/AppKit/CPControl.j @@ -19,9 +19,10 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - + #import "../Foundation/Ref.h" +@import "../Foundation/CPFormatter.j" @import "CPFont.j" @import "CPShadow.j" @import "CPView.j" @@ -84,6 +85,7 @@ var CPControlBlackColor = [CPColor blackColor]; @implementation CPControl : CPView { id _value; + CPFormatter _formatter @accessors(property=formatter); // Target-Action Support id _target; @@ -91,8 +93,6 @@ var CPControlBlackColor = [CPColor blackColor]; int _sendActionOn; BOOL _sendsActionOnEndEditing @accessors(property=sendsActionOnEndEditing); - CPFormatter _formatter @accessors(property=formatter); - // Mouse Tracking Support BOOL _continuousTracking; BOOL _trackingWasWithinFrame; @@ -225,10 +225,11 @@ var CPControlBlackColor = [CPColor blackColor]; @param anAction the action to send @param anObject the object to which the action will be sent */ -- (void)sendAction:(SEL)anAction to:(id)anObject +- (BOOL)sendAction:(SEL)anAction to:(id)anObject { [self _reverseSetBinding]; - [CPApp sendAction:anAction to:anObject from:self]; + + return [CPApp sendAction:anAction to:anObject from:self]; } - (int)sendActionOn:(int)mask @@ -506,13 +507,12 @@ var CPControlBlackColor = [CPColor blackColor]; */ - (CPString)stringValue { - var formatted; - - if (_formatter) + if (_formatter && _value !== undefined && _value !== nil) { - formatted = [_formatter stringForObjectValue:_value]; - if (formatted !== nil && formatted !== undefined) - return formatted; + var formattedValue = [self hasThemeState:CPThemeStateEditing] ? [_formatter editingStringForObjectValue:_value] : [_formatter stringForObjectValue:_value]; + + if (formattedValue !== nil && formattedValue !== undefined) + return formattedValue; } return (_value === undefined || _value === nil) ? "" : String(_value); @@ -521,16 +521,30 @@ var CPControlBlackColor = [CPColor blackColor]; /*! Sets the receiver's string value. */ -- (void)setStringValue:(CPString)anObject +- (void)setStringValue:(CPString)aString { - var value = anObject; + // Cocoa raises an invalid parameter assertion and returns if you pass nil. + if (aString === nil || aString === undefined) + { + CPLog.warn("nil sent to CPControl -setStringValue"); + return; + } + + var value; if (_formatter) { - var formattedValue = nil; - if ([_formatter getObjectValue:AT_REF(formattedValue) forString:value errorDescription:NULL]) - value = formattedValue; + value = nil; + + if ([_formatter getObjectValue:AT_REF(value) forString:aString errorDescription:nil] === NO) + { + // If the given string is non-empty and doesn't work, Cocoa tries an empty string. + if (!aString || [_formatter getObjectValue:AT_REF(value) forString:@"" errorDescription:nil] === NO) + value = undefined; // Means the value is invalid + } } + else + value = aString; [self setObjectValue:value]; } @@ -548,21 +562,18 @@ var CPControlBlackColor = [CPColor blackColor]; [self setFloatValue:[sender floatValue]]; } - - (void)takeIntegerValueFrom:(id)sender { if ([sender respondsToSelector:@selector(integerValue)]) [self setIntegerValue:[sender integerValue]]; } - - (void)takeIntValueFrom:(id)sender { if ([sender respondsToSelector:@selector(intValue)]) [self setIntValue:[sender intValue]]; } - - (void)takeObjectValueFrom:(id)sender { if ([sender respondsToSelector:@selector(objectValue)]) @@ -904,7 +915,7 @@ var __Deprecated__CPImageViewImageKey = @"CPImageViewImageKey"; if (_target !== nil) [aCoder encodeConditionalObject:_target forKey:CPControlTargetKey]; - if (_action !== NULL) + if (_action !== nil) [aCoder encodeObject:_action forKey:CPControlActionKey]; [aCoder encodeInt:_sendActionOn forKey:CPControlSendActionOnKey]; diff --git a/AppKit/CPMenu/CPMenu.j b/AppKit/CPMenu/CPMenu.j index 961f2a421..cf9eb933a 100644 --- a/AppKit/CPMenu/CPMenu.j +++ b/AppKit/CPMenu/CPMenu.j @@ -711,10 +711,7 @@ var _CPMenuBarVisible = NO, if (aView && !theWindow) throw "In call to popUpMenuPositioningItem:atLocation:inView:callback:, view is not in any window."; - var delegate = [self delegate]; - - if ([delegate respondsToSelector:@selector(menuWillOpen:)]) - [delegate menuWillOpen:self]; + [self _menuWillOpen]; // Convert location to global coordinates if not already in them. if (aView) @@ -802,10 +799,7 @@ var _CPMenuBarVisible = NO, + (void)popUpContextMenu:(CPMenu)aMenu withEvent:(CPEvent)anEvent forView:(CPView)aView withFont:(CPFont)aFont { - var delegate = [aMenu delegate]; - - if ([delegate respondsToSelector:@selector(menuWillOpen:)]) - [delegate menuWillOpen:aMenu]; + [aMenu _menuWillOpen]; if (!aFont) aFont = [CPFont systemFontOfSize:12.0]; @@ -875,7 +869,15 @@ var _CPMenuBarVisible = NO, */ - (CPMenuItem)highlightedItem { - return _highlightedIndex >= 0 ? _items[_highlightedIndex] : nil; + if (_highlightedIndex < 0) + return nil; + + var highlightedItem = _items[_highlightedIndex]; + + if ([highlightedItem isSeparatorItem]) + return nil; + + return highlightedItem; } // Managing the Delegate @@ -890,6 +892,22 @@ var _CPMenuBarVisible = NO, return _delegate; } +- (void)_menuWillOpen +{ + var delegate = [self delegate]; + + if ([delegate respondsToSelector:@selector(menuWillOpen:)]) + [delegate menuWillOpen:self]; +} + +- (void)_menuDidClose +{ + var delegate = [self delegate]; + + if ([delegate respondsToSelector:@selector(menuDidClose:)]) + [delegate menuDidClose:self]; +} + // Handling Tracking /*! Cancels tracking. diff --git a/AppKit/CPMenu/_CPMenuManager.j b/AppKit/CPMenu/_CPMenuManager.j index 1aec30b9d..57f253a65 100644 --- a/AppKit/CPMenu/_CPMenuManager.j +++ b/AppKit/CPMenu/_CPMenuManager.j @@ -11,6 +11,7 @@ var STICKY_TIME_INTERVAL = 500, @implementation _CPMenuManager: CPObject { CPTimeInterval _startTime; + BOOL _hasMouseGoneUpAfterStartedTracking; int _scrollingState; CGPoint _lastGlobalLocation; @@ -87,6 +88,8 @@ var STICKY_TIME_INTERVAL = 500, return [self trackMenuBarButtonEvent:anEvent]; } + _hasMouseGoneUpAfterStartedTracking = NO; + [self trackEvent:anEvent]; } @@ -221,8 +224,13 @@ var STICKY_TIME_INTERVAL = 500, [CPEvent startPeriodicEventsAfterDelay:0.0 withPeriod:0.04]; } } - else if (type === CPLeftMouseUp && ([anEvent timestamp] - _startTime > (STICKY_TIME_INTERVAL + [activeMenu numberOfItems] * 5))) - [trackingMenu cancelTracking]; + else if (type === CPLeftMouseUp) + { + if (_hasMouseGoneUpAfterStartedTracking) + [trackingMenu cancelTracking]; + else + _hasMouseGoneUpAfterStartedTracking = YES; + } } // Prevent previous selected menu items from opening by stopping the timer if a @@ -306,11 +314,7 @@ var STICKY_TIME_INTERVAL = 500, // Hide all submenus. [self showMenu:nil fromMenu:trackingMenu atPoint:nil]; - - var delegate = [trackingMenu delegate]; - - if ([delegate respondsToSelector:@selector(menuDidClose:)]) - [delegate menuDidClose:trackingMenu]; + [trackingMenu _menuDidClose]; if (_trackingCallback) _trackingCallback([self trackingMenuContainer], trackingMenu); @@ -379,6 +383,8 @@ var STICKY_TIME_INTERVAL = 500, var count = _menuContainerStack.length, index = count; + [newMenu _menuWillOpen]; + // Hide all menus up to the base menu... while (index--) { @@ -398,6 +404,8 @@ var STICKY_TIME_INTERVAL = 500, [_CPMenuWindow poolMenuWindow:menuContainer]; [_menuContainerStack removeObjectAtIndex:index]; + + [menu _menuDidClose]; } if (!newMenu) diff --git a/AppKit/CPMenuItem/CPMenuItem.j b/AppKit/CPMenuItem/CPMenuItem.j index 0cff6177a..e8e39a15f 100644 --- a/AppKit/CPMenuItem/CPMenuItem.j +++ b/AppKit/CPMenuItem/CPMenuItem.j @@ -496,6 +496,7 @@ CPOffState if (_submenu) { [_submenu setSupermenu:_menu]; + [_submenu setTitle:[self title]] [self setTarget:_menu]; [self setAction:@selector(submenuAction:)]; diff --git a/AppKit/CPTextField.j b/AppKit/CPTextField.j index eee5dfd95..e7831c138 100644 --- a/AppKit/CPTextField.j +++ b/AppKit/CPTextField.j @@ -21,6 +21,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#import "../Foundation/Ref.h" + @import "CPControl.j" @import "CPStringDrawing.j" @import "CPCompatibility.j" @@ -83,12 +85,11 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); CPColor _textFieldBackgroundColor; - id _placeholderString; + CPString _placeholderString; + CPString _stringValue; id _delegate; - CPString _textDidChangeValue; - // NS-style Display Properties CPTextFieldBezelStyle _bezelStyle; BOOL _isBordered; @@ -481,17 +482,17 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); [self setNeedsLayout]; _isEditing = NO; + _stringValue = [self stringValue]; #if PLATFORM(DOM) - var string = [self stringValue], - element = [self _inputElement], + var element = [self _inputElement], font = [self currentValueForThemeAttribute:@"font"]; // generate the font metric [font _getMetrics]; - element.value = string; + element.value = _stringValue; element.style.color = [[self currentValueForThemeAttribute:@"text-color"] cssString]; element.style.font = [font cssString]; element.style.zIndex = 1000; @@ -548,8 +549,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); CPTextFieldInputOwner = self; }, 0.0); - element.value = [self stringValue]; - [[[self window] platformWindow] _propagateCurrentDOMEvent:YES]; CPTextFieldInputIsActive = YES; @@ -572,17 +571,33 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); { [self unsetThemeState:CPThemeStateEditing]; +#if PLATFORM(DOM) + + var element = [self _inputElement], + error = @""; + + // If there is a formatter, always give it a chance to reject the resignation, + // even if the value has not changed. + if ([self _valueIsValid:element.value] === NO) + { + [self setThemeState:CPThemeStateEditing]; + element.focus(); + return NO; + } + +#endif + + // Cache the formatted string + _stringValue = [self stringValue]; + + _willBecomeFirstResponderByClick = NO; + [self _updatePlaceholderState]; [self setNeedsLayout]; #if PLATFORM(DOM) - var element = [self _inputElement]; - - if ([self stringValue] !== element.value) - [self _setStringValue:element.value]; - CPTextFieldInputResigning = YES; if (CPTextFieldInputIsActive) @@ -610,7 +625,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); #endif - //post CPControlTextDidEndEditingNotification + // post CPControlTextDidEndEditingNotification if (_isEditing) { _isEditing = NO; @@ -625,6 +640,28 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); return YES; } +- (BOOL)_valueIsValid:(CPString)aValue +{ +#if PLATFORM(DOM) + + var error = @""; + + if ([self _setStringValue:aValue isNewValue:NO errorDescription:AT_REF(error)] === NO) + { + var acceptInvalidValue = NO; + + if ([_delegate respondsToSelector:@selector(control:didFailToFormatString:errorDescription:)]) + acceptInvalidValue = [_delegate control:self didFailToFormatString:[self _inputElement] errorDescription:error]; + + if (acceptInvalidValue === NO) + return NO; + } + +#endif + + return YES; +} + /*! Text fields require panels to become key window, so this returns \c YES. */ @@ -685,11 +722,14 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); - (void)keyUp:(CPEvent)anEvent { - var oldValue = [self stringValue]; - [self _setStringValue:[self _inputElement].value]; +#if PLATFORM(DOM) - if (oldValue !== [self stringValue]) + var newValue = [self _inputElement].value; + + if (newValue !== _stringValue) { + [self _setStringValue:newValue]; + if (!_isEditing) { _isEditing = YES; @@ -699,6 +739,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); [self textDidChange:[CPNotification notificationWithName:CPControlTextDidChangeNotification object:self userInfo:nil]]; } +#endif + [[[self window] platformWindow] _propagateCurrentDOMEvent:YES]; } @@ -735,45 +777,46 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); - (void)insertNewline:(id)sender { - if (_isEditing) + if ([self _valueIsValid:_stringValue]) { - _isEditing = NO; - [self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]]; - } + if (![self action] || [self sendAction:[self action] to:[self target]]) + { + if (_isEditing) + { + _isEditing = NO; + [self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]]; + } - [self sendAction:[self action] to:[self target]]; - [self selectText:nil]; + [self selectAll:nil]; + } + } [[[self window] platformWindow] _propagateCurrentDOMEvent:NO]; } - (void)insertNewlineIgnoringFieldEditor:(id)sender { - var oldValue = [self stringValue]; - - [self _inputElement].value += CPNewlineCharacter; - [self _setStringValue:[self _inputElement].value]; - - if (oldValue !== [self stringValue]) - { - if (!_isEditing) - { - _isEditing = YES; - [self textDidBeginEditing:[CPNotification notificationWithName:CPControlTextDidBeginEditingNotification object:self userInfo:nil]]; - } - - [self textDidChange:[CPNotification notificationWithName:CPControlTextDidChangeNotification object:self userInfo:nil]]; - } + [self _insertCharacterIgnoringFieldEditor:CPNewlineCharacter]; } - (void)insertTabIgnoringFieldEditor:(id)sender { - var oldValue = [self stringValue]; + [self _insertCharacterIgnoringFieldEditor:CPTabCharacter]; +} - [self _inputElement].value += CPTabCharacter; - [self _setStringValue:[self _inputElement].value]; +- (void)_insertCharacterIgnoringFieldEditor:(CPString)aCharacter +{ +#if PLATFORM(DOM) - if (oldValue !== [self stringValue]) + var oldValue = _stringValue, + range = [self selectedRange], + element = [self _inputElement]; + + element.value = [element.value stringByReplacingCharactersInRange:[self selectedRange] withString:aCharacter]; + [self _setStringValue:element.value]; + + // NOTE: _stringValue is now the current input element value + if (oldValue !== _stringValue) { if (!_isEditing) { @@ -783,6 +826,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); [self textDidChange:[CPNotification notificationWithName:CPControlTextDidChangeNotification object:self userInfo:nil]]; } + +#endif } - (void)textDidBlur:(CPNotification)note @@ -813,15 +858,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); [super textDidChange:note]; } -- (void)sendAction:(SEL)anAction to:(id)anObject -{ - [self _reverseSetBinding]; - - [CPApp sendAction:anAction to:anObject from:self]; -} - /*! - Returns the string the text field. + Returns the string in the text field. */ - (id)objectValue { @@ -830,24 +868,84 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); /* @ignore - Sets the internal string value without updating the value in the input element + Sets the internal string value without updating the value in the input element. + This should only be invoked when the underlying text element's value has changed. */ -- (void)_setStringValue:(id)aValue +- (BOOL)_setStringValue:(CPString)aValue { - [self willChangeValueForKey:@"objectValue"]; - [super setObjectValue:String(aValue)]; - [self _updatePlaceholderState]; - [self didChangeValueForKey:@"objectValue"]; + return [self _setStringValue:aValue isNewValue:YES errorDescription:nil]; +} + +/* + @ignore + Sets the internal string value without updating the value in the input element. + If there is a formatter and formatting fails, returns NO. Otherwise returns YES. +*/ +- (BOOL)_setStringValue:(CPString)aValue isNewValue:(BOOL)isNewValue errorDescription:(CPStringRef)anError +{ + _stringValue = aValue; + + var objectValue = aValue, + formatter = [self formatter], + result = YES; + + if (formatter) + { + var object = nil; + + if ([formatter getObjectValue:AT_REF(object) forString:aValue errorDescription:anError]) + objectValue = object; + else + { + objectValue = undefined; // Mark the value as invalid + result = NO; + } + + isNewValue |= objectValue !== [super objectValue]; + } + + if (isNewValue) + { + [self willChangeValueForKey:@"objectValue"]; + [super setObjectValue:objectValue]; + [self _updatePlaceholderState]; + [self didChangeValueForKey:@"objectValue"]; + } + + return result; } - (void)setObjectValue:(id)aValue { [super setObjectValue:aValue]; + var formatter = [self formatter]; + + if (formatter) + { + // If there is a formatter, make sure the object value can be formatted successfully + var formattedString = [self hasThemeState:CPThemeStateEditing] ? [formatter editingStringForObjectValue:aValue] : [formatter stringForObjectValue:aValue]; + + if (formattedString === nil) + { + var value = nil; + + // Formatting failed, get an "empty" object by formatting an empty string. + // If that fails, the value is undefined. + if ([formatter getObjectValue:AT_REF(value) forString:@"" errorDescription:nil] === NO) + value = undefined; + + [super setObjectValue:value]; + } + } + + _stringValue = [self stringValue]; + #if PLATFORM(DOM) if (CPTextFieldInputOwner === self || [[self window] firstResponder] === self) - [self _inputElement].value = aValue; + [self _inputElement].value = _stringValue; + #endif [self _updatePlaceholderState]; @@ -855,9 +953,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); - (void)_updatePlaceholderState { - var string = [self stringValue]; - - if ((!string || string.length === 0) && ![self hasThemeState:CPThemeStateEditing]) + if ((!_stringValue || _stringValue.length === 0) && ![self hasThemeState:CPThemeStateEditing]) [self setThemeState:CPTextFieldStatePlaceholder]; else [self unsetThemeState:CPTextFieldStatePlaceholder]; @@ -923,7 +1019,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); minSize = [self currentValueForThemeAttribute:@"min-size"], maxSize = [self currentValueForThemeAttribute:@"max-size"], lineBreakMode = [self lineBreakMode], - text = ([self stringValue] || @" "), + text = (_stringValue || @" "), textSize = _CGSizeMakeCopy(frameSize), font = [self currentValueForThemeAttribute:@"font"]; @@ -994,8 +1090,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); return; var pasteboard = [CPPasteboard generalPasteboard], - stringValue = [self stringValue], - stringForPasting = [stringValue substringWithRange:selectedRange]; + stringForPasting = [_stringValue substringWithRange:selectedRange]; [pasteboard declareTypes:[CPStringPboardType] owner:nil]; [pasteboard setString:stringForPasting forType:CPStringPboardType]; @@ -1025,9 +1120,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); [self deleteBackward:sender]; var selectedRange = [self selectedRange], - stringValue = [self stringValue], pasteString = [pasteboard stringForType:CPStringPboardType], - newValue = [stringValue stringByReplacingCharactersInRange:selectedRange withString:pasteString]; + newValue = [_stringValue stringByReplacingCharactersInRange:selectedRange withString:pasteString]; [self setStringValue:newValue]; [self setSelectedRange:CPMakeRange(selectedRange.location + pasteString.length, 0)]; @@ -1041,6 +1135,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); if ([[self window] firstResponder] !== self) return CPMakeRange(0, 0); +#if PLATFORM(DOM) + // we wrap this in try catch because firefox will throw an exception in certain instances try { @@ -1067,6 +1163,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); // fall through to the return } +#endif + return CPMakeRange(0, 0); } @@ -1075,6 +1173,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); if (![[self window] firstResponder] === self) return; +#if PLATFORM(DOM) + var inputElement = [self _inputElement]; try @@ -1103,6 +1203,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); catch (e) { } + +#endif } - (void)selectAll:(id)sender @@ -1120,8 +1222,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); selectedRange.location += 1; selectedRange.length -= 1; - var stringValue = [self stringValue], - newValue = [stringValue stringByReplacingCharactersInRange:selectedRange withString:""]; + var newValue = [_stringValue stringByReplacingCharactersInRange:selectedRange withString:""]; [self setStringValue:newValue]; [self setSelectedRange:CPMakeRange(selectedRange.location, 0)]; @@ -1274,7 +1375,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); string = [self placeholderString]; else { - string = [self stringValue]; + string = _stringValue; if ([self isSecure]) string = secureStringForString(string); diff --git a/Foundation/CPFormatter.j b/Foundation/CPFormatter.j index e74b0058c..d7cc4b11e 100644 --- a/Foundation/CPFormatter.j +++ b/Foundation/CPFormatter.j @@ -33,6 +33,8 @@ make sure that you cannot configure the public subclasses CPDateFormatter and CPNumberFormatter to satisfy your requirements. */ +#import "Ref.h" + @import "CPException.j" @import "CPObject.j" @@ -80,19 +82,19 @@ /*! The default implementation of this method raises an exception. - When implementing a subclass, return by reference the object anObject after creating it from string. - Return YES if the conversion is successful. If you return NO, also return by indirection (in error) + When implementing a subclass, return by reference the object anObject after creating it from aString. + Return \c YES if the conversion is successful. If you return \c NO, also return by reference (in anError) a localized user-presentable CPString object that explains the reason why the conversion failed; the delegate - (if any) of the CPControl object managing the cell can then respond to the failure in - control:didFailToFormatString:errorDescription:. However, if error is nil, the sender is not interested in + (if any) of the CPControl object can then respond to the failure in + control:didFailToFormatString:errorDescription:. However, if anError is nil, the sender is not interested in the error description, and you should not attempt to assign one. @param anObject if conversion is successful, upon return contains the object created from the string @param aString the string to parse. @param anError if non-nil, if there is an error during the conversion, upon return contains an CPString object that describes the problem. - @return BOOL YES if the conversion from the string to a view content object was successful, otherwise NO. + @return BOOL \c YES if the conversion from the string to a view content object was successful, otherwise \c NO. */ -- (BOOL)getObjectValue:(id)anObject forString:(CPString)aString errorDescription:(CPString)anError +- (BOOL)getObjectValue:(idRef)anObject forString:(CPString)aString errorDescription:(CPStringRef)anError { _CPRaiseInvalidAbstractInvocation(self, _cmd); return NO; @@ -104,11 +106,11 @@ This method is invoked each time the user presses a key while the cell has the keyboard focus it lets you verify and edit the cell text as the user types it. - In a subclass implementation, evaluate partialString according to the context, edit the text if necessary, and return - by reference any edited string in newString. Return YES if partialString is acceptable and NO if partialString is unacceptable. - If you return NO and newString is nil, the cell displays partialString minus the last character typed. If you return NO, you can - also return by indirection an CPString object (in error) that explains the reason why the validation failed; the delegate (if any) - of the CPControl object managing the cell can then respond to the failure in control:didFailToValidatePartialString:errorDescription:. + In a subclass implementation, evaluate aPartialString according to the context, edit the text if necessary, and return + by reference any edited string in aNewString. Return \c YES if aPartialString is acceptable and \c NO if aPartialString is unacceptable. + If you return \c NO and aNewString is nil, the control displays aPartialString minus the last character typed. If you return \c NO, you can + also return by reference a CPString object (in anError) that explains the reason why the validation failed; the delegate (if any) + of the CPControl can then respond to the failure in control:didFailToValidatePartialString:errorDescription:. The selection range will always be set to the end of the text if replacement occurs. This method is a compatibility method. If a subclass overrides this method and does not override @@ -118,12 +120,16 @@ @param aPartialString the text currently in the view. @param aNewString if aPartialString needs to be modified, upon return contains the replacement string. @param anError if non-nil, if validation fails contains a CPString object that describes the problem. - @return YES if aPartialString is an acceptable value, otherwise NO. + @return \c YES if aPartialString is an acceptable value, otherwise \c NO. */ -- (BOOL)isPartialStringValid:(CPString)aPartialString newEditingString:(CPString)aNewString errorDescription:(CPString)anError +- (BOOL)isPartialStringValid:(CPString)aPartialString newEditingString:(CPStringRef)aNewString errorDescription:(CPStringRef)anError { - _CPRaiseInvalidAbstractInvocation(self, _cmd); - return NO; + AT_DEREF(aPartialString, nil); + + if (anError) + AT_DEREF(anError, nil); + + return YES; } /*! @@ -131,24 +137,35 @@ not necessarily at the end of the string, and preserve the selection (or set a different one, such as selecting the erroneous part of the string the user has typed). - In a subclass implementation, evaluate partialString according to the context. Return YES if partialStringPtr is acceptable and NO if partialStringPtr - is unacceptable. Assign a new string to partialStringPtr and a new range to proposedSelRangePtr and return NO if you want to replace the string and - change the selection range. If you return NO, you can also return by indirection an CPString object (in error) that explains the reason why the - validation failed; the delegate (if any) of the CPControl object managing the cell can then respond to the failure in + In a subclass implementation, evaluate aPartialString according to the context. Return \c YES if aPartialString is acceptable and \c NO if aPartialString + is unacceptable. Assign a new string by reference to aPartialString and a new range by reference to aProposedSelectedRange and return \c NO if you want to replace the string and + change the selection range. If you return \c NO, you can also return by reference a CPString object (in anError) that explains the reason why the + validation failed; the delegate (if any) of the CPControl can then respond to the failure in control:didFailToValidatePartialString:errorDescription:. @param aPartialString The new string to validate. @param aProposedSelectedRange The selection range that will be used if the string is accepted or replaced. @param originalString The original string, before the proposed change. @param originalSelectedRange The selection range over which the change is to take place. - @param error If non-nil, if validation fails contains an CPString object that describes the problem. - @return YES if aPartialString is acceptable, otherwise NO. + @param anError If non-nil, if validation fails contains an CPString object that describes the problem. + @return \c YES if aPartialString is acceptable, otherwise \c NO. */ -- (BOOL)isPartialStringValue:(CPString)aPartialString proposedSelectedRange:(CPRange)aProposedSelectedRange originalString:(CPString)originalString originalSelectedRange:(CPRange)originalSelectedRange errorDescription:(CPString)anError +- (BOOL)isPartialStringValid:(CPStringRef)aPartialString proposedSelectedRange:(CPRangeRef)aProposedSelectedRange originalString:(CPString)originalString originalSelectedRange:(CPRange)originalSelectedRange errorDescription:(CPStringRef)anError { - _CPRaiseInvalidAbstractInvocation(self, _cmd); - return NO; + var newString = nil, + valid = [self isPartialStringValid:aPartialString newEditingString:AT_REF(newString) errorDescription:anError]; + + if (!valid) + { + AT_DEREF(aPartialString, newString); + + // If a new string is passed back, the selection is always put at the end + if (newString !== nil) + AT_DEREF(aProposedSelectedRange, CPMakeRange(newString.length, 0)); + } + + return valid; } - (id)initWithCoder:(CPCoder)aCoder @@ -158,7 +175,6 @@ - (void)encodeWithCoder:(CPCoder)aCoder { - } @end diff --git a/Tests/Manual/CPFormatterTest/AppController.j b/Tests/Manual/CPFormatterTest/AppController.j new file mode 100644 index 000000000..26b42c595 --- /dev/null +++ b/Tests/Manual/CPFormatterTest/AppController.j @@ -0,0 +1,205 @@ +/* + * AppController.j + * CPFormatterTest + * + * Created by aparajita on June 30, 2011. + * Copyright 2011, Victory-Heart Productions All rights reserved. + */ + +@import +@import "DateFormatter.j" + +var RecordData = [ + {name:"Tom", age:34}, + {name:"Dick", age:27}, + {name:"Harry", age:50} + ]; + +var randomFromTo = function(from, to) +{ + return Math.floor(Math.random() * (to - from + 1) + from); +}; + +@implementation AppController : CPObject +{ + CPWindow theWindow; + CPTextField dateField1; + CPTextField dateField2; + CPTextField error1; + CPTextField textField; + CPTextField error2; + CPTextField recordField; + CPPopUpButton recordMenu; +} + +- (void)awakeFromCib +{ + [theWindow setInitialFirstResponder:dateField1]; + [dateField1 setFormatter:[DateFormatter formatterWithDisplayFormat:@"D M jS, Y" editingFormat:@"m/j/Y" emptyIsValid:NO]]; + [dateField2 setFormatter:[DateFormatter formatterWithDisplayFormat:@"m-d-Y" editingFormat:@"m-d-Y" emptyIsValid:YES]]; + [dateField2 setDelegate:self]; + + [[CPNotificationCenter defaultCenter] addObserver:self + selector:@selector(resetErrorMessage:) + name:CPTextFieldDidFocusNotification + object:nil]; + + [textField setFormatter:[TextFormatter new]]; + [textField setDelegate:self]; + + [error1 setStringValue:@""]; + [error2 setStringValue:@""]; + + [recordField setFormatter:[ContactFormatter new]]; + [recordField setObjectValue:RecordData[0]]; +} + +- (void)selectRecord:(id)sender +{ + var record = RecordData[[sender selectedIndex]]; + + [recordField setObjectValue:record]; +} + +- (void)setDate1:(id)sender +{ + [self setDate:dateField1]; +} + +- (void)setDate2:(id)sender +{ + [self setDate:dateField2]; +} + +- (void)setDate:(CPTextField)field +{ + var date = new Date(randomFromTo(1931, 2012), randomFromTo(0, 11), randomFromTo(1, 31)); + + [field setObjectValue:date]; +} + +- (void)objectValue1:(id)sender +{ + CPLog.info("Date 1: %s", [[dateField1 objectValue] description]); +} + +- (void)objectValue2:(id)sender +{ + CPLog.info("Date 2: %s", [[dateField2 objectValue] description]); +} + +- (void)setNil:(id)sender +{ + [dateField1 setStringValue:nil]; // should log a warning and do nothing +} + +- (void)setEmptyOK:(id)sender +{ + [[dateField2 formatter] setEmptyIsValid:[sender state] === CPOnState]; +} + +- (void)controlTextDidChange:(CPNotification)aNotification +{ + var field = [aNotification object], + error; + + if (field === dateField2) + error = error1; + else if (field === textField) + error = error2; + + [error setStringValue:@""]; +} + +- (BOOL)control:(CPControl)aControl didFailToFormatString:(CPString)aString errorDescription:(CPString)anError +{ + CPLog.info("control:didFailToFormatString:%s errorDescription:%s", aString, anError); + + if (anError) + { + var error; + + if (aControl === dateField2) + error = error1; + else if (aControl === textField) + error = error2; + + [error setStringValue:anError]; + } + + return NO; +} + +- (void)resetErrorMessage:(CPNotification)aNotification +{ + [error2 setStringValue:@""]; +} + +@end + + +@implementation TextFormatter : CPFormatter + +- (CPString)stringForObjectValue:(id)anObject +{ + var result; + + if ([anObject isKindOfClass:[CPString class]]) + result = [self errorDescriptionForString:anObject] === nil ? anObject : nil; + else + result = nil; + + console.log("stringForObjectValue:%s ==> %s", [anObject description], result); + return result; +} + +- (BOOL)getObjectValue:(CPStringRef)anObject forString:(CPString)aString errorDescription:(CPStringRef)anError +{ + var error = [self errorDescriptionForString:aString]; + + if (error) + { + anObject(nil); + + if (anError) + anError(error); + } + else + anObject(aString); + + result = error === nil; + + console.log("getObjectValue:forString:%s ==> %s", aString, result); + return result; +} + +- (CPString)errorDescriptionForString:(CPString)aString +{ + if (aString.length > 7) + return @"Maximum length is 7 characters."; + else if (!/^[a-zA-Z0-9]*$/.test(aString)) + return @"Invalid characters in string."; + else + return nil; +} + +@end + + +@implementation ContactFormatter : CPFormatter + +- (CPString)stringForObjectValue:(id)anObject +{ + if (anObject && typeof(anObject) === "object" && anObject.hasOwnProperty("name")) + return [CPString stringWithFormat:@"%s (age %d)", anObject.name, anObject.age]; + else + return nil; +} + +- (BOOL)getObjectValue:(CPStringRef)anObject forString:(CPString)aString errorDescription:(CPStringRef)anError +{ + // We don't support reverse conversion + return NO; +} + +@end diff --git a/Tests/Manual/CPFormatterTest/DateFormatter.j b/Tests/Manual/CPFormatterTest/DateFormatter.j new file mode 100644 index 000000000..6b90d364a --- /dev/null +++ b/Tests/Manual/CPFormatterTest/DateFormatter.j @@ -0,0 +1,125 @@ +/* + * AppController.j + * CPFormatterTest + * + * Created by aparajita on July 6, 2011. + * Copyright 2011, Victory-Heart Productions All rights reserved. + */ + +@import + + +@implementation DateFormatter : CPFormatter +{ + CPString displayFormat; + CPString editingFormat; + BOOL emptyIsValid @accessors(getter=isEmptyValid); +} + ++ (DateFormatter)formatterWithDisplayFormat:(CPString)aDisplayFormat editingFormat:(CPString)anEditingFormat emptyIsValid:(BOOL)emptyValid +{ + return [[self alloc] initWithDisplayFormat:aDisplayFormat editingFormat:anEditingFormat emptyIsValid:emptyValid]; +} + +- (id)initWithDisplayFormat:(CPString)aDisplayFormat editingFormat:(CPString)anEditingFormat emptyIsValid:(BOOL)emptyValid +{ + self = [super init]; + + if (self) + { + displayFormat = aDisplayFormat; + editingFormat = anEditingFormat; + emptyIsValid = emptyValid; + } + + return self; +} + +- (CPString)stringForObjectValue:(id)anObject +{ + var result; + + if ([anObject isKindOfClass:[CPDate class]]) + result = anObject.dateFormat(displayFormat); + else + result = nil; + + console.log("stringForObjectValue:%s ==> %s", [anObject description], result); + return result; +} + +- (CPString)editingStringForObjectValue:(id)anObject +{ + var result; + + if ([anObject isKindOfClass:[CPDate class]]) + result = anObject.dateFormat(editingFormat); + else + result = nil; + + console.log("editingStringForObjectValue:%s ==> %s", [anObject description], result); + return result; +} + +- (BOOL)getObjectValue:(CPStringRef)anObject forString:(CPString)aString errorDescription:(CPStringRef)anError +{ + var result; + + if (anError) + anError(nil); + + if (aString.length === 0) + { + anObject(nil); + result = emptyIsValid; + + if (anError) + anError(@"Please enter a date."); + } + else + { + var date = Date.parseDate(aString, editingFormat); + + anObject(date); + + if (date === nil && anError) + anError(@"Invalid date format."); + + result = date !== nil; + } + + console.log("getObjectValue:forString:%s ==> %s", aString, result); + return result; +} + +@end + +var DateFormatterDisplayFormatKey = @"DateFormatterDisplayFormatKey", + DateFormatterEditingFormatKey = @"DateFormatterEditingFormatKey", + DateFormatterEmptyIsValidKey = @"DateFormatterEmptyIsValidKey"; + +@implementation DateFormatter (CPCoding) + +- (id)initWithCoder:(CPCoder)aCoder +{ + self = [super initWithCoder:aCoder]; + + if (self) + { + displayFormat = [aCoder decodeObjectForKey:DateFormatterDisplayFormatKey]; + editingFormat = [aCoder decodeObjectForKey:DateFormatterEditingFormatKey]; + emptyIsValid = [aCoder decodeObjectForKey:DateFormatterEmptyIsValidKey]; + } + + return self; +} + +- (void)encodeWithCoder:(CPCoder)aCoder +{ + [super encodeWithCoder:aCoder]; + [aCoder encodeObject:displayFormat forKey:DateFormatterDisplayFormatKey]; + [aCoder encodeObject:editingFormat forKey:DateFormatterEditingFormatKey]; + [aCoder encodeObject:emptyIsValid forKey:DateFormatterEmptyIsValidKey]; +} + +@end diff --git a/Tests/Manual/CPFormatterTest/Info.plist b/Tests/Manual/CPFormatterTest/Info.plist new file mode 100644 index 000000000..813950e7e --- /dev/null +++ b/Tests/Manual/CPFormatterTest/Info.plist @@ -0,0 +1,10 @@ + + + + + Main cib file base name + MainMenu.cib + CPBundleName + CPFormatterTest + + diff --git a/Tests/Manual/CPFormatterTest/Jakefile b/Tests/Manual/CPFormatterTest/Jakefile new file mode 100644 index 000000000..4b4864d37 --- /dev/null +++ b/Tests/Manual/CPFormatterTest/Jakefile @@ -0,0 +1,94 @@ +/* + * Jakefile + * CPFormatterTest + * + * Created by aparajita on June 30, 2011. + * Copyright 2011, Victory-Heart Productions All rights reserved. + */ + +var ENV = require("system").env, + FILE = require("file"), + JAKE = require("jake"), + task = JAKE.task, + FileList = JAKE.FileList, + app = require("cappuccino/jake").app, + configuration = ENV["CONFIG"] || ENV["CONFIGURATION"] || ENV["c"] || "Debug", + OS = require("os"); + +app ("CPFormatterTest", function(task) +{ + task.setBuildIntermediatesPath(FILE.join("Build", "CPFormatterTest.build", configuration)); + task.setBuildPath(FILE.join("Build", configuration)); + + task.setProductName("CPFormatterTest"); + task.setIdentifier("com.aparajita.CPFormatterTest"); + task.setVersion("1.0"); + task.setAuthor("Victory-Heart Productions"); + task.setEmail("feedback @nospam@ yourcompany.com"); + task.setSummary("CPFormatterTest"); + task.setSources((new FileList("**/*.j")).exclude(FILE.join("Build", "**"))); + task.setResources(new FileList("Resources/**")); + task.setIndexFilePath("index.html"); + task.setInfoPlistPath("Info.plist"); + task.setNib2CibFlags("-R Resources/"); + + if (configuration === "Debug") + task.setCompilerFlags("-DDEBUG -g"); + else + task.setCompilerFlags("-O"); +}); + +task ("default", ["CPFormatterTest"], function() +{ + printResults(configuration); +}); + +task ("build", ["default"]); + +task ("debug", function() +{ + ENV["CONFIGURATION"] = "Debug"; + JAKE.subjake(["."], "build", ENV); +}); + +task ("release", function() +{ + ENV["CONFIGURATION"] = "Release"; + JAKE.subjake(["."], "build", ENV); +}); + +task ("run", ["debug"], function() +{ + OS.system(["open", FILE.join("Build", "Debug", "CPFormatterTest", "index.html")]); +}); + +task ("run-release", ["release"], function() +{ + OS.system(["open", FILE.join("Build", "Release", "CPFormatterTest", "index.html")]); +}); + +task ("deploy", ["release"], function() +{ + FILE.mkdirs(FILE.join("Build", "Deployment", "CPFormatterTest")); + OS.system(["press", "-f", FILE.join("Build", "Release", "CPFormatterTest"), FILE.join("Build", "Deployment", "CPFormatterTest")]); + printResults("Deployment") +}); + +task ("desktop", ["release"], function() +{ + FILE.mkdirs(FILE.join("Build", "Desktop", "CPFormatterTest")); + require("cappuccino/nativehost").buildNativeHost(FILE.join("Build", "Release", "CPFormatterTest"), FILE.join("Build", "Desktop", "CPFormatterTest", "CPFormatterTest.app")); + printResults("Desktop") +}); + +task ("run-desktop", ["desktop"], function() +{ + OS.system([FILE.join("Build", "Desktop", "CPFormatterTest", "CPFormatterTest.app", "Contents", "MacOS", "NativeHost"), "-i"]); +}); + +function printResults(configuration) +{ + print("----------------------------"); + print(configuration+" app built at path: "+FILE.join("Build", configuration, "CPFormatterTest")); + print("----------------------------"); +} diff --git a/Tests/Manual/CPFormatterTest/Resources/MainMenu.cib b/Tests/Manual/CPFormatterTest/Resources/MainMenu.cib new file mode 100644 index 000000000..76de15636 --- /dev/null +++ b/Tests/Manual/CPFormatterTest/Resources/MainMenu.cib @@ -0,0 +1 @@ +280NPLIST;1.0;D;K;4;$topD;K;18;CPCibObjectDataKeyD;K;6;CP$UIDd;1;2E;E;K;8;$objectsA;S;5;$nullD;K;10;$classnameS;16;_CPCibObjectDataK;8;$classesA;S;16;_CPCibObjectDataS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;1;1E;K;28;_CPCibObjectDataNamesKeysKeyD;K;6;CP$UIDd;1;4E;K;30;_CPCibObjectDataNamesValuesKeyD;K;6;CP$UIDd;1;5E;K;30;_CPCibObjectDataClassesKeysKeyD;K;6;CP$UIDd;1;6E;K;32;_CPCibObjectDataClassesValuesKeyD;K;6;CP$UIDd;1;7E;K;30;_CPCibObjectDataConnectionsKeyD;K;6;CP$UIDd;1;8E;K;28;_CPCibObjectDataFrameworkKeyD;K;6;CP$UIDd;1;9E;K;26;_CPCibObjectDataNextOidKeyD;K;6;CP$UIDd;2;10E;K;30;_CPCibObjectDataObjectsKeysKeyD;K;6;CP$UIDd;2;11E;K;32;_CPCibObjectDataObjectsValuesKeyD;K;6;CP$UIDd;2;12E;K;26;_CPCibObjectDataOidKeysKeyD;K;6;CP$UIDd;2;13E;K;28;_CPCibObjectDataOidValuesKeyD;K;6;CP$UIDd;2;14E;K;28;_CPCibObjectDataFileOwnerKeyD;K;6;CP$UIDd;2;16E;K;33;_CPCibObjectDataVisibleWindowsKeyD;K;6;CP$UIDd;2;18E;E;D;K;10;$classnameS;7;CPArrayK;8;$classesA;S;7;CPArrayS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;20E;D;K;6;CP$UIDd;2;22E;D;K;6;CP$UIDd;2;24E;D;K;6;CP$UIDd;2;25E;D;K;6;CP$UIDd;2;26E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;16E;D;K;6;CP$UIDd;2;27E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;30E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;2;33E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;34E;D;K;6;CP$UIDd;2;35E;D;K;6;CP$UIDd;2;36E;D;K;6;CP$UIDd;2;37E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;38E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;39E;D;K;6;CP$UIDd;2;40E;D;K;6;CP$UIDd;2;41E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;42E;D;K;6;CP$UIDd;2;44E;D;K;6;CP$UIDd;2;46E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;47E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;48E;D;K;6;CP$UIDd;2;50E;D;K;6;CP$UIDd;2;51E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;52E;D;K;6;CP$UIDd;2;53E;D;K;6;CP$UIDd;2;54E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;55E;D;K;6;CP$UIDd;2;56E;D;K;6;CP$UIDd;2;57E;D;K;6;CP$UIDd;2;58E;D;K;6;CP$UIDd;2;59E;D;K;6;CP$UIDd;2;60E;D;K;6;CP$UIDd;2;61E;D;K;6;CP$UIDd;2;62E;D;K;6;CP$UIDd;2;63E;D;K;6;CP$UIDd;2;64E;D;K;6;CP$UIDd;2;65E;D;K;6;CP$UIDd;2;66E;D;K;6;CP$UIDd;2;67E;D;K;6;CP$UIDd;2;68E;D;K;6;CP$UIDd;2;69E;D;K;6;CP$UIDd;2;70E;D;K;6;CP$UIDd;2;71E;D;K;6;CP$UIDd;2;72E;D;K;6;CP$UIDd;2;73E;D;K;6;CP$UIDd;2;74E;D;K;6;CP$UIDd;2;75E;D;K;6;CP$UIDd;2;76E;D;K;6;CP$UIDd;2;77E;D;K;6;CP$UIDd;2;78E;D;K;6;CP$UIDd;2;79E;D;K;6;CP$UIDd;2;80E;D;K;6;CP$UIDd;2;81E;D;K;6;CP$UIDd;2;82E;D;K;6;CP$UIDd;2;83E;D;K;6;CP$UIDd;2;84E;D;K;6;CP$UIDd;2;85E;D;K;6;CP$UIDd;2;86E;D;K;6;CP$UIDd;2;87E;D;K;6;CP$UIDd;2;88E;D;K;6;CP$UIDd;2;89E;D;K;6;CP$UIDd;2;90E;D;K;6;CP$UIDd;2;91E;D;K;6;CP$UIDd;2;92E;D;K;6;CP$UIDd;2;93E;D;K;6;CP$UIDd;2;94E;D;K;6;CP$UIDd;2;95E;D;K;6;CP$UIDd;2;96E;D;K;6;CP$UIDd;2;97E;D;K;6;CP$UIDd;2;98E;D;K;6;CP$UIDd;2;99E;D;K;6;CP$UIDd;3;100E;D;K;6;CP$UIDd;3;101E;D;K;6;CP$UIDd;3;102E;D;K;6;CP$UIDd;3;103E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;105E;D;K;6;CP$UIDd;3;106E;D;K;6;CP$UIDd;3;107E;D;K;6;CP$UIDd;3;108E;D;K;6;CP$UIDd;3;109E;D;K;6;CP$UIDd;3;110E;D;K;6;CP$UIDd;3;111E;D;K;6;CP$UIDd;3;112E;D;K;6;CP$UIDd;3;114E;D;K;6;CP$UIDd;3;115E;D;K;6;CP$UIDd;3;116E;D;K;6;CP$UIDd;3;117E;D;K;6;CP$UIDd;3;118E;D;K;6;CP$UIDd;3;119E;D;K;6;CP$UIDd;3;120E;E;E;S;16;IBCocoaFrameworkD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;20E;D;K;6;CP$UIDd;2;22E;D;K;6;CP$UIDd;2;24E;D;K;6;CP$UIDd;2;25E;D;K;6;CP$UIDd;2;26E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;27E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;33E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;30E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;34E;D;K;6;CP$UIDd;2;35E;D;K;6;CP$UIDd;2;36E;D;K;6;CP$UIDd;2;37E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;39E;D;K;6;CP$UIDd;2;40E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;38E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;42E;D;K;6;CP$UIDd;2;44E;D;K;6;CP$UIDd;2;41E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;47E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;48E;D;K;6;CP$UIDd;2;50E;D;K;6;CP$UIDd;2;51E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;52E;D;K;6;CP$UIDd;2;53E;D;K;6;CP$UIDd;2;54E;D;K;6;CP$UIDd;2;46E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;16E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;36E;D;K;6;CP$UIDd;2;50E;D;K;6;CP$UIDd;2;48E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;37E;D;K;6;CP$UIDd;2;24E;D;K;6;CP$UIDd;2;46E;D;K;6;CP$UIDd;2;44E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;35E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;27E;D;K;6;CP$UIDd;2;53E;D;K;6;CP$UIDd;2;54E;D;K;6;CP$UIDd;2;46E;D;K;6;CP$UIDd;2;46E;D;K;6;CP$UIDd;2;20E;D;K;6;CP$UIDd;2;25E;D;K;6;CP$UIDd;2;26E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;38E;D;K;6;CP$UIDd;2;41E;D;K;6;CP$UIDd;2;30E;D;K;6;CP$UIDd;2;51E;D;K;6;CP$UIDd;2;47E;D;K;6;CP$UIDd;2;16E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;22E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;34E;D;K;6;CP$UIDd;2;16E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;44E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;D;K;10;$classnameS;18;_CPCibCustomObjectK;8;$classesA;S;18;_CPCibCustomObjectS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;15E;K;27;_CPCibCustomObjectClassNameD;K;6;CP$UIDd;3;121E;E;D;K;10;$classnameS;5;CPSetK;8;$classesA;S;5;CPSetS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;17E;K;15;CPSetObjectsKeyD;K;6;CP$UIDd;3;122E;E;D;K;10;$classnameS;11;CPTextFieldK;8;$classesA;S;11;CPTextFieldS;9;CPControlS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;29E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;123E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;124E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;125E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;29E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;126E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;127E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;128E;K;6;$afontD;K;6;CP$UIDd;3;130E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;131E;K;11;$aalignmentD;K;6;CP$UIDd;3;132E;K;35;CPControlSendsActionOnEndEditingKeyD;K;6;CP$UIDd;3;133E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;134E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;135E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;3;136E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;3;136E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;3;136E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;1;0E;K;27;CPTextFieldLineBreakModeKeyD;K;6;CP$UIDd;3;131E;K;23;CPTextFieldAlignmentKeyD;K;6;CP$UIDd;3;132E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;1;0E;E;D;K;10;$classnameS;8;CPButtonK;8;$classesA;S;8;CPButtonS;9;CPControlS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;29E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;123E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;137E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;138E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;29E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;126E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;139E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;140E;K;16;$aimage-positionD;K;6;CP$UIDd;3;123E;K;6;$afontD;K;6;CP$UIDd;3;141E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;123E;K;11;$aalignmentD;K;6;CP$UIDd;3;131E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;142E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;132E;K;16;CPButtonTitleKeyD;K;6;CP$UIDd;3;143E;K;25;CPButtonAlternateTitleKeyD;K;6;CP$UIDd;1;0E;K;27;CPButtonAllowsMixedStateKeyD;K;6;CP$UIDd;3;136E;K;32;CPButtonImageDimsWhenDisabledKeyD;K;6;CP$UIDd;1;0E;K;24;CPButtonImagePositionKeyD;K;6;CP$UIDd;3;123E;K;28;CPButtonKeyEquivalentMaskKeyD;K;6;CP$UIDd;3;123E;K;24;CPButtonPeriodicDelayKeyD;K;6;CP$UIDd;1;0E;K;27;CPButtonPeriodicIntervalKeyD;K;6;CP$UIDd;1;0E;E;D;K;10;$classnameS;20;_CPCibWindowTemplateK;8;$classesA;S;20;_CPCibWindowTemplateS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;23E;K;30;_CPCibWindowTemplateMaxSizeKeyD;K;6;CP$UIDd;3;144E;K;32;_CPCibWindowTemplateViewClassKeyD;K;6;CP$UIDd;1;0E;K;34;_CPCibWindowTemplateWindowClassKeyD;K;6;CP$UIDd;3;145E;K;33;_CPCibWindowTemplateWindowRectKeyD;K;6;CP$UIDd;3;146E;K;30;_CPCibWindowTempatStyleMaskKeyD;K;6;CP$UIDd;3;147E;K;34;_CPCibWindowTemplateWindowTitleKeyD;K;6;CP$UIDd;3;148E;K;33;_CPCibWindowTemplateWindowViewKeyD;K;6;CP$UIDd;2;29E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;29E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;123E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;149E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;150E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;29E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;126E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;127E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;128E;K;6;$afontD;K;6;CP$UIDd;3;130E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;131E;K;11;$aalignmentD;K;6;CP$UIDd;3;132E;K;35;CPControlSendsActionOnEndEditingKeyD;K;6;CP$UIDd;3;133E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;151E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;135E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;3;136E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;3;136E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;3;136E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;1;0E;K;27;CPTextFieldLineBreakModeKeyD;K;6;CP$UIDd;3;131E;K;23;CPTextFieldAlignmentKeyD;K;6;CP$UIDd;3;132E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;1;0E;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;29E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;123E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;152E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;153E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;29E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;126E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;139E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;140E;K;16;$aimage-positionD;K;6;CP$UIDd;3;123E;K;6;$afontD;K;6;CP$UIDd;3;141E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;123E;K;11;$aalignmentD;K;6;CP$UIDd;3;131E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;142E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;132E;K;16;CPButtonTitleKeyD;K;6;CP$UIDd;3;154E;K;25;CPButtonAlternateTitleKeyD;K;6;CP$UIDd;1;0E;K;27;CPButtonAllowsMixedStateKeyD;K;6;CP$UIDd;3;136E;K;32;CPButtonImageDimsWhenDisabledKeyD;K;6;CP$UIDd;1;0E;K;24;CPButtonImagePositionKeyD;K;6;CP$UIDd;3;123E;K;28;CPButtonKeyEquivalentMaskKeyD;K;6;CP$UIDd;3;123E;K;24;CPButtonPeriodicDelayKeyD;K;6;CP$UIDd;1;0E;K;27;CPButtonPeriodicIntervalKeyD;K;6;CP$UIDd;1;0E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;29E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;123E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;155E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;156E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;29E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;126E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;127E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;128E;K;6;$afontD;K;6;CP$UIDd;3;130E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;131E;K;11;$aalignmentD;K;6;CP$UIDd;3;132E;K;35;CPControlSendsActionOnEndEditingKeyD;K;6;CP$UIDd;3;133E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;157E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;135E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;3;136E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;3;136E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;3;136E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;1;0E;K;27;CPTextFieldLineBreakModeKeyD;K;6;CP$UIDd;3;131E;K;23;CPTextFieldAlignmentKeyD;K;6;CP$UIDd;3;132E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;1;0E;E;D;K;10;$classnameS;6;CPViewK;8;$classesA;S;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;28E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;123E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;158E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;158E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;159E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;1;0E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;128E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;29E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;123E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;160E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;161E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;29E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;126E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;127E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;162E;K;6;$afontD;K;6;CP$UIDd;3;130E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;131E;K;11;$aalignmentD;K;6;CP$UIDd;3;132E;K;35;CPControlSendsActionOnEndEditingKeyD;K;6;CP$UIDd;3;133E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;163E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;135E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;3;133E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;3;133E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;3;133E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;3;165E;K;27;CPTextFieldLineBreakModeKeyD;K;6;CP$UIDd;3;131E;K;23;CPTextFieldAlignmentKeyD;K;6;CP$UIDd;3;132E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;1;0E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;29E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;123E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;166E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;167E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;29E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;126E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;127E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;128E;K;6;$afontD;K;6;CP$UIDd;3;130E;K;12;$atext-colorD;K;6;CP$UIDd;3;168E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;131E;K;11;$aalignmentD;K;6;CP$UIDd;3;132E;K;35;CPControlSendsActionOnEndEditingKeyD;K;6;CP$UIDd;3;133E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;169E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;135E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;3;136E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;3;136E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;3;136E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;1;0E;K;27;CPTextFieldLineBreakModeKeyD;K;6;CP$UIDd;3;131E;K;23;CPTextFieldAlignmentKeyD;K;6;CP$UIDd;3;132E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;1;0E;E;D;K;10;$classnameS;10;CPMenuItemK;8;$classesA;S;10;CPMenuItemS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;32E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;170E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;2;44E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;171E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;46E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;172E;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;29E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;123E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;173E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;138E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;29E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;126E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;139E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;140E;K;16;$aimage-positionD;K;6;CP$UIDd;3;123E;K;6;$afontD;K;6;CP$UIDd;3;141E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;123E;K;11;$aalignmentD;K;6;CP$UIDd;3;131E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;142E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;132E;K;16;CPButtonTitleKeyD;K;6;CP$UIDd;3;143E;K;25;CPButtonAlternateTitleKeyD;K;6;CP$UIDd;1;0E;K;27;CPButtonAllowsMixedStateKeyD;K;6;CP$UIDd;3;136E;K;32;CPButtonImageDimsWhenDisabledKeyD;K;6;CP$UIDd;1;0E;K;24;CPButtonImagePositionKeyD;K;6;CP$UIDd;3;123E;K;28;CPButtonKeyEquivalentMaskKeyD;K;6;CP$UIDd;3;123E;K;24;CPButtonPeriodicDelayKeyD;K;6;CP$UIDd;1;0E;K;27;CPButtonPeriodicIntervalKeyD;K;6;CP$UIDd;1;0E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;29E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;123E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;174E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;175E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;29E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;126E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;127E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;128E;K;6;$afontD;K;6;CP$UIDd;3;130E;K;12;$atext-colorD;K;6;CP$UIDd;3;176E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;131E;K;11;$aalignmentD;K;6;CP$UIDd;3;132E;K;35;CPControlSendsActionOnEndEditingKeyD;K;6;CP$UIDd;3;133E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;177E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;135E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;3;136E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;3;136E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;3;136E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;1;0E;K;27;CPTextFieldLineBreakModeKeyD;K;6;CP$UIDd;3;131E;K;23;CPTextFieldAlignmentKeyD;K;6;CP$UIDd;3;132E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;1;0E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;29E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;123E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;178E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;161E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;29E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;126E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;127E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;162E;K;6;$afontD;K;6;CP$UIDd;3;130E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;131E;K;11;$aalignmentD;K;6;CP$UIDd;3;132E;K;35;CPControlSendsActionOnEndEditingKeyD;K;6;CP$UIDd;3;133E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;163E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;135E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;3;133E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;3;133E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;3;133E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;3;165E;K;27;CPTextFieldLineBreakModeKeyD;K;6;CP$UIDd;3;131E;K;23;CPTextFieldAlignmentKeyD;K;6;CP$UIDd;3;132E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;1;0E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;29E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;123E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;179E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;161E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;29E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;126E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;127E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;162E;K;6;$afontD;K;6;CP$UIDd;3;130E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;131E;K;11;$aalignmentD;K;6;CP$UIDd;3;132E;K;35;CPControlSendsActionOnEndEditingKeyD;K;6;CP$UIDd;3;133E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;163E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;135E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;3;133E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;3;133E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;3;133E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;3;165E;K;27;CPTextFieldLineBreakModeKeyD;K;6;CP$UIDd;3;131E;K;23;CPTextFieldAlignmentKeyD;K;6;CP$UIDd;3;132E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;1;0E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;29E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;123E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;180E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;167E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;29E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;126E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;127E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;128E;K;6;$afontD;K;6;CP$UIDd;3;130E;K;12;$atext-colorD;K;6;CP$UIDd;3;181E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;131E;K;11;$aalignmentD;K;6;CP$UIDd;3;132E;K;35;CPControlSendsActionOnEndEditingKeyD;K;6;CP$UIDd;3;133E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;182E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;135E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;3;136E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;3;136E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;3;136E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;1;0E;K;27;CPTextFieldLineBreakModeKeyD;K;6;CP$UIDd;3;131E;K;23;CPTextFieldAlignmentKeyD;K;6;CP$UIDd;3;132E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;1;0E;E;D;K;6;$classD;K;6;CP$UIDd;2;32E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;183E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;2;44E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;171E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;3;142E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;46E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;172E;E;D;K;6;$classD;K;6;CP$UIDd;2;32E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;184E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;2;44E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;171E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;46E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;172E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;29E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;123E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;185E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;175E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;29E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;126E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;127E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;128E;K;6;$afontD;K;6;CP$UIDd;3;130E;K;12;$atext-colorD;K;6;CP$UIDd;3;186E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;131E;K;11;$aalignmentD;K;6;CP$UIDd;3;132E;K;35;CPControlSendsActionOnEndEditingKeyD;K;6;CP$UIDd;3;133E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;187E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;135E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;3;136E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;3;136E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;3;136E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;1;0E;K;27;CPTextFieldLineBreakModeKeyD;K;6;CP$UIDd;3;131E;K;23;CPTextFieldAlignmentKeyD;K;6;CP$UIDd;3;132E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;1;0E;E;D;K;6;$classD;K;6;CP$UIDd;2;15E;K;27;_CPCibCustomObjectClassNameD;K;6;CP$UIDd;3;121E;E;D;K;10;$classnameS;13;CPPopUpButtonK;8;$classesA;S;13;CPPopUpButtonS;8;CPButtonS;9;CPControlS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;43E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;29E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;2;46E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;123E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;188E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;189E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;29E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;126E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;190E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;191E;K;6;$afontD;K;6;CP$UIDd;3;141E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;132E;K;11;$aalignmentD;K;6;CP$UIDd;3;123E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;123E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;132E;K;16;CPButtonTitleKeyD;K;6;CP$UIDd;1;0E;K;25;CPButtonAlternateTitleKeyD;K;6;CP$UIDd;1;0E;K;27;CPButtonAllowsMixedStateKeyD;K;6;CP$UIDd;3;136E;K;32;CPButtonImageDimsWhenDisabledKeyD;K;6;CP$UIDd;1;0E;K;24;CPButtonImagePositionKeyD;K;6;CP$UIDd;3;131E;K;28;CPButtonKeyEquivalentMaskKeyD;K;6;CP$UIDd;3;123E;K;24;CPButtonPeriodicDelayKeyD;K;6;CP$UIDd;1;0E;K;27;CPButtonPeriodicIntervalKeyD;K;6;CP$UIDd;1;0E;E;D;K;10;$classnameS;6;CPMenuK;8;$classesA;S;6;CPMenuS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;45E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;192E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;193E;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;29E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;123E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;194E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;153E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;29E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;126E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;139E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;140E;K;16;$aimage-positionD;K;6;CP$UIDd;3;123E;K;6;$afontD;K;6;CP$UIDd;3;141E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;123E;K;11;$aalignmentD;K;6;CP$UIDd;3;131E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;142E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;132E;K;16;CPButtonTitleKeyD;K;6;CP$UIDd;3;154E;K;25;CPButtonAlternateTitleKeyD;K;6;CP$UIDd;1;0E;K;27;CPButtonAllowsMixedStateKeyD;K;6;CP$UIDd;3;136E;K;32;CPButtonImageDimsWhenDisabledKeyD;K;6;CP$UIDd;1;0E;K;24;CPButtonImagePositionKeyD;K;6;CP$UIDd;3;123E;K;28;CPButtonKeyEquivalentMaskKeyD;K;6;CP$UIDd;3;123E;K;24;CPButtonPeriodicDelayKeyD;K;6;CP$UIDd;1;0E;K;27;CPButtonPeriodicIntervalKeyD;K;6;CP$UIDd;1;0E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;29E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;123E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;195E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;175E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;29E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;126E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;127E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;128E;K;6;$afontD;K;6;CP$UIDd;3;130E;K;12;$atext-colorD;K;6;CP$UIDd;3;196E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;131E;K;11;$aalignmentD;K;6;CP$UIDd;3;132E;K;35;CPControlSendsActionOnEndEditingKeyD;K;6;CP$UIDd;3;133E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;197E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;135E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;3;136E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;3;136E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;3;136E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;1;0E;K;27;CPTextFieldLineBreakModeKeyD;K;6;CP$UIDd;3;131E;K;23;CPTextFieldAlignmentKeyD;K;6;CP$UIDd;3;132E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;1;0E;E;D;K;10;$classnameS;10;CPCheckBoxK;8;$classesA;S;10;CPCheckBoxS;8;CPButtonS;9;CPControlS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;49E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;29E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;123E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;198E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;199E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;29E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;126E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;200E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;201E;K;16;$aimage-positionD;K;6;CP$UIDd;3;131E;K;6;$afontD;K;6;CP$UIDd;3;130E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;123E;K;11;$aalignmentD;K;6;CP$UIDd;3;123E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;142E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;132E;K;16;CPButtonTitleKeyD;K;6;CP$UIDd;3;202E;K;25;CPButtonAlternateTitleKeyD;K;6;CP$UIDd;1;0E;K;27;CPButtonAllowsMixedStateKeyD;K;6;CP$UIDd;3;136E;K;32;CPButtonImageDimsWhenDisabledKeyD;K;6;CP$UIDd;1;0E;K;24;CPButtonImagePositionKeyD;K;6;CP$UIDd;3;131E;K;28;CPButtonKeyEquivalentMaskKeyD;K;6;CP$UIDd;3;123E;K;24;CPButtonPeriodicDelayKeyD;K;6;CP$UIDd;1;0E;K;27;CPButtonPeriodicIntervalKeyD;K;6;CP$UIDd;1;0E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;29E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;123E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;203E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;156E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;29E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;126E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;127E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;128E;K;6;$afontD;K;6;CP$UIDd;3;130E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;131E;K;11;$aalignmentD;K;6;CP$UIDd;3;132E;K;35;CPControlSendsActionOnEndEditingKeyD;K;6;CP$UIDd;3;133E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;204E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;135E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;3;136E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;3;136E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;3;136E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;1;0E;K;27;CPTextFieldLineBreakModeKeyD;K;6;CP$UIDd;3;131E;K;23;CPTextFieldAlignmentKeyD;K;6;CP$UIDd;3;132E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;1;0E;E;D;K;6;$classD;K;6;CP$UIDd;2;15E;K;27;_CPCibCustomObjectClassNameD;K;6;CP$UIDd;3;205E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;29E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;123E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;206E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;156E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;29E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;126E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;127E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;128E;K;6;$afontD;K;6;CP$UIDd;3;130E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;131E;K;11;$aalignmentD;K;6;CP$UIDd;3;132E;K;35;CPControlSendsActionOnEndEditingKeyD;K;6;CP$UIDd;3;133E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;207E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;135E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;3;136E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;3;136E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;3;136E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;1;0E;K;27;CPTextFieldLineBreakModeKeyD;K;6;CP$UIDd;3;131E;K;23;CPTextFieldAlignmentKeyD;K;6;CP$UIDd;3;132E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;1;0E;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;29E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;123E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;208E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;138E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;29E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;126E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;139E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;140E;K;16;$aimage-positionD;K;6;CP$UIDd;3;123E;K;6;$afontD;K;6;CP$UIDd;3;141E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;123E;K;11;$aalignmentD;K;6;CP$UIDd;3;131E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;142E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;132E;K;16;CPButtonTitleKeyD;K;6;CP$UIDd;3;209E;K;25;CPButtonAlternateTitleKeyD;K;6;CP$UIDd;1;0E;K;27;CPButtonAllowsMixedStateKeyD;K;6;CP$UIDd;3;136E;K;32;CPButtonImageDimsWhenDisabledKeyD;K;6;CP$UIDd;1;0E;K;24;CPButtonImagePositionKeyD;K;6;CP$UIDd;3;123E;K;28;CPButtonKeyEquivalentMaskKeyD;K;6;CP$UIDd;3;123E;K;24;CPButtonPeriodicDelayKeyD;K;6;CP$UIDd;1;0E;K;27;CPButtonPeriodicIntervalKeyD;K;6;CP$UIDd;1;0E;E;S;21;Static Text (Record:)S;30;Round Textured Button (Random)S;30;Window (CPFormatter & Friends)S;18;Static Text (name)S;35;Round Textured Button (objectValue)S;17;Text Field Cell-1S;24;Text Field Cell (error1)S;22;Button Cell (Empty OK)S;12;File's OwnerS;20;Static Text (Date 1)S;17;Text Field Cell-2S;12;Content ViewS;10;Text FieldS;29;Pop Up Button Cell (Tom - 34)S;46;Static Text (Input: [a-zA-Z0-9], max length 7)S;22;Menu Item (Harry - 50)S;24;Text Field Cell (error2)S;32;Round Textured Button (Random)-1S;20;Static Text (error2)S;12;Text Field-1S;12;Text Field-2S;24;Text Field Cell (Date 1)S;22;Text Field Cell (Text)S;24;Text Field Cell (Date 2)S;21;Button Cell (Set nil)S;22;Text Field Cell (name)S;25;Text Field Cell (Record:)S;58;Text Field Cell (Input: mm-dd-yyyy Display: mm-dd-yyyy)S;25;Button Cell (objectValue)S;54;Static Text (Input: mm-dd-yyyy Display: mm-dd-yyyy)S;59;Text Field Cell (Input: mm/dd/yyyy Display: abbreviated)S;15;Text Field CellS;20;Menu Item (Tom - 34)S;21;Menu Item (Dick - 27)S;55;Static Text (Input: mm/dd/yyyy Display: abbreviated)S;27;Button Cell (objectValue)-1S;11;ApplicationS;13;Pop Up ButtonS;17;Menu (OtherViews)S;20;Button Cell (Random)S;37;Round Textured Button (objectValue)-1S;50;Text Field Cell (Input: [a-zA-Z0-9], max length 7)S;20;Static Text (error1)S;20;Check Box (Empty OK)S;18;Static Text (Text)S;22;Button Cell (Random)-1S;14;App ControllerS;20;Static Text (Date 2)S;31;Round Textured Button (Set nil)D;K;10;$classnameS;20;CPCibOutletConnectorK;8;$classesA;S;20;CPCibOutletConnectorS;14;CPCibConnectorS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;104E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;52E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;36E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;210E;E;D;K;6;$classD;K;6;CP$UIDd;3;104E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;52E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;37E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;211E;E;D;K;6;$classD;K;6;CP$UIDd;3;104E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;52E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;48E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;197E;E;D;K;6;$classD;K;6;CP$UIDd;3;104E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;52E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;35E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;177E;E;D;K;6;$classD;K;6;CP$UIDd;3;104E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;52E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;25E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;212E;E;D;K;6;$classD;K;6;CP$UIDd;3;104E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;52E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;44E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;213E;E;D;K;6;$classD;K;6;CP$UIDd;3;104E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;52E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;30E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;214E;E;D;K;6;$classD;K;6;CP$UIDd;3;104E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;52E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;24E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;215E;E;D;K;10;$classnameS;21;CPCibControlConnectorK;8;$classesA;S;21;CPCibControlConnectorS;14;CPCibConnectorS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;113E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;44E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;52E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;216E;E;D;K;6;$classD;K;6;CP$UIDd;3;113E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;22E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;52E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;217E;E;D;K;6;$classD;K;6;CP$UIDd;3;113E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;34E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;52E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;218E;E;D;K;6;$classD;K;6;CP$UIDd;3;113E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;54E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;52E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;219E;E;D;K;6;$classD;K;6;CP$UIDd;3;113E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;47E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;52E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;3;113E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;26E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;52E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;221E;E;D;K;6;$classD;K;6;CP$UIDd;3;113E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;50E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;52E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;222E;E;S;13;CPApplicationD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;24E;E;E;d;1;0S;21;{{31, 284}, {58, 17}}S;18;{{0, 0}, {58, 17}}d;2;36S;9;textfieldS;6;normalD;K;10;$classnameS;6;CPFontK;8;$classesA;S;6;CPFontS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;129E;K;13;CPFontNameKeyD;K;6;CP$UIDd;3;223E;K;13;CPFontSizeKeyD;K;6;CP$UIDd;3;224E;K;15;CPFontIsBoldKeyD;K;6;CP$UIDd;3;136E;K;17;CPFontIsItalicKeyD;K;6;CP$UIDd;3;136E;E;d;1;2d;1;4T;S;7;Record:d;4;3072F;S;21;{{406, 37}, {66, 24}}S;18;{{0, 0}, {66, 24}}S;6;buttonS;17;selected+borderedD;K;6;$classD;K;6;CP$UIDd;3;129E;K;13;CPFontNameKeyD;K;6;CP$UIDd;3;223E;K;13;CPFontSizeKeyD;K;6;CP$UIDd;3;224E;K;15;CPFontIsBoldKeyD;K;6;CP$UIDd;3;133E;K;17;CPFontIsItalicKeyD;K;6;CP$UIDd;3;136E;E;d;1;1S;6;RandomS;28;{1.79769e+308, 1.79769e+308}S;8;CPWindowS;24;{{233, 100}, {734, 327}}d;1;7S;21;CPFormatter & FriendsS;22;{{96, 284}, {200, 17}}S;19;{{0, 0}, {200, 17}}S;4;nameS;22;{{493, 122}, {88, 24}}S;18;{{0, 0}, {88, 24}}S;11;objectValueS;20;{{31, 42}, {50, 17}}S;18;{{0, 0}, {50, 17}}S;6;Date 1S;20;{{0, 0}, {734, 327}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;36E;D;K;6;CP$UIDd;2;27E;D;K;6;CP$UIDd;2;20E;D;K;6;CP$UIDd;2;25E;D;K;6;CP$UIDd;2;41E;D;K;6;CP$UIDd;2;44E;D;K;6;CP$UIDd;2;37E;D;K;6;CP$UIDd;2;53E;D;K;6;CP$UIDd;2;38E;D;K;6;CP$UIDd;2;22E;D;K;6;CP$UIDd;2;47E;D;K;6;CP$UIDd;2;54E;D;K;6;CP$UIDd;2;34E;D;K;6;CP$UIDd;2;26E;D;K;6;CP$UIDd;2;50E;D;K;6;CP$UIDd;2;48E;D;K;6;CP$UIDd;2;30E;D;K;6;CP$UIDd;2;51E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;2;35E;E;E;S;22;{{88, 210}, {279, 29}}S;19;{{0, 0}, {279, 29}}S;19;bezeled+placeholderS;0;D;K;10;$classnameS;7;CPColorK;8;$classesA;S;7;CPColorS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;164E;K;20;CPColorComponentsKeyD;K;6;CP$UIDd;3;225E;E;S;22;{{96, 189}, {357, 17}}S;19;{{0, 0}, {357, 17}}D;K;6;$classD;K;6;CP$UIDd;3;164E;K;20;CPColorComponentsKeyD;K;6;CP$UIDd;3;226E;E;S;32;Input: [a-zA-Z0-9], max length 7S;10;Harry - 50S;17;_popUpItemAction:d;7;1048576S;22;{{406, 122}, {66, 24}}S;22;{{96, 241}, {282, 17}}S;19;{{0, 0}, {282, 17}}D;K;6;$classD;K;6;CP$UIDd;3;164E;K;20;CPColorComponentsKeyD;K;6;CP$UIDd;3;227E;E;S;6;error2S;21;{{88, 35}, {279, 29}}S;22;{{88, 122}, {279, 29}}S;22;{{96, 101}, {357, 17}}D;K;6;$classD;K;6;CP$UIDd;3;164E;K;20;CPColorComponentsKeyD;K;6;CP$UIDd;3;228E;E;S;40;Input: mm-dd-yyyy Display: mm-dd-yyyyS;8;Tom - 34S;9;Dick - 27S;21;{{96, 14}, {282, 17}}D;K;6;$classD;K;6;CP$UIDd;3;164E;K;20;CPColorComponentsKeyD;K;6;CP$UIDd;3;229E;E;S;41;Input: mm/dd/yyyy Display: abbreviatedS;23;{{204, 279}, {120, 24}}S;19;{{0, 0}, {120, 24}}S;12;popup-buttonS;8;borderedS;10;OtherViewsD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;39E;D;K;6;CP$UIDd;2;40E;D;K;6;CP$UIDd;2;33E;E;E;S;21;{{493, 37}, {88, 24}}S;22;{{96, 153}, {282, 17}}D;K;6;$classD;K;6;CP$UIDd;3;164E;K;20;CPColorComponentsKeyD;K;6;CP$UIDd;3;230E;E;S;6;error1S;22;{{604, 127}, {84, 18}}S;18;{{0, 0}, {84, 18}}S;9;check-boxS;8;selectedS;8;Empty OKS;21;{{31, 217}, {50, 17}}S;4;TextS;13;AppControllerS;21;{{31, 129}, {50, 17}}S;6;Date 2S;21;{{604, 37}, {66, 24}}S;7;Set nilS;10;dateField1S;10;dateField2S;11;recordFieldS;10;recordMenuS;9;textFieldS;9;theWindowS;13;selectRecord:S;9;setDate1:S;9;setDate2:S;7;setNil:S;13;objectValue1:S;13;objectValue2:S;11;setEmptyOK:S;17;Arial, sans-serifd;2;12D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;142E;D;K;6;CP$UIDd;3;142E;D;K;6;CP$UIDd;3;142E;D;K;6;CP$UIDd;3;142E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;231E;D;K;6;CP$UIDd;3;231E;D;K;6;CP$UIDd;3;231E;D;K;6;CP$UIDd;3;142E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;232E;D;K;6;CP$UIDd;3;123E;D;K;6;CP$UIDd;3;123E;D;K;6;CP$UIDd;3;142E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;231E;D;K;6;CP$UIDd;3;231E;D;K;6;CP$UIDd;3;231E;D;K;6;CP$UIDd;3;142E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;231E;D;K;6;CP$UIDd;3;231E;D;K;6;CP$UIDd;3;231E;D;K;6;CP$UIDd;3;142E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;232E;D;K;6;CP$UIDd;3;123E;D;K;6;CP$UIDd;3;123E;D;K;6;CP$UIDd;3;142E;E;E;f;3;0.5f;12;0.8816326531E;K;9;$archiverS;15;CPKeyedArchiverK;8;$versionS;6;100000E; \ No newline at end of file diff --git a/Tests/Manual/CPFormatterTest/Resources/MainMenu.xib b/Tests/Manual/CPFormatterTest/Resources/MainMenu.xib new file mode 100644 index 000000000..21153c71f --- /dev/null +++ b/Tests/Manual/CPFormatterTest/Resources/MainMenu.xib @@ -0,0 +1,1435 @@ + + + + 1050 + 10K540 + 804 + 1038.36 + 461.00 + + com.apple.InterfaceBuilder.CocoaPlugin + 804 + + + YES + + + + YES + com.apple.InterfaceBuilder.CocoaPlugin + + + PluginDependencyRecalculationVersion + + + + YES + + NSApplication + + + FirstResponder + + + NSApplication + + + 7 + 2 + {{233, 991}, {734, 327}} + 1946157056 + CPFormatter & Friends + NSWindow + + {1.79769e+308, 1.79769e+308} + + + 256 + + YES + + + 268 + {{94, 266}, {271, 22}} + + YES + + -1804468671 + 272630784 + + + LucidaGrande + 13 + 1044 + + + YES + + 6 + System + textBackgroundColor + + 3 + MQA + + + + 6 + System + textColor + + 3 + MAA + + + + + + + 268 + {{31, 268}, {50, 17}} + + YES + + 68288064 + 272630784 + Date 1 + + LucidaGrande + 13 + 16 + + + + 6 + System + controlColor + + 3 + MC42NjY2NjY2NjY3AA + + + + 6 + System + controlTextColor + + + + + + + 268 + {{31, 26}, {58, 17}} + + YES + + 68288064 + 272630784 + Record: + + + + + + + + + 268 + {{96, 26}, {200, 17}} + + YES + + 68288064 + 272630784 + name + + + + + + + + + 268 + {{96, 296}, {282, 17}} + + YES + + 68288064 + 272630784 + Input: mm/dd/yyyy Display: abbreviated + + + + + 3 + MC41AA + + 2 + + + + + + + 268 + {{203, 22}, {126, 26}} + + YES + + -2076049856 + 2048 + + + 109199615 + 129 + + + 400 + 75 + + + Tom - 34 + + 1048576 + 2147483647 + 1 + + NSImage + NSMenuCheckmark + + + NSImage + NSMenuMixedState + + _popUpItemAction: + + + YES + + OtherViews + + YES + + + + Dick - 27 + + 1048576 + 2147483647 + + + _popUpItemAction: + + + + + Harry - 50 + + 1048576 + 2147483647 + + + _popUpItemAction: + + + + + + 1 + YES + YES + 2 + + + + + 268 + {{94, 179}, {271, 22}} + + YES + + -1804468671 + 272630784 + + + + YES + + + + + + + 268 + {{31, 181}, {50, 17}} + + YES + + 68288064 + 272630784 + Date 2 + + + + + + + + + 268 + {{96, 209}, {357, 17}} + + YES + + 68288064 + 272630784 + Input: mm-dd-yyyy Display: mm-dd-yyyy + + + + + 3 + MC41AA + + + + + + + 268 + {{408, 264}, {66, 25}} + + YES + + -2080244224 + 134217728 + Random + + + -2038152961 + 163 + + + 400 + 75 + + + + + 268 + {{495, 264}, {88, 25}} + + YES + + -2080244224 + 134217728 + objectValue + + + -2038152961 + 163 + + + 400 + 75 + + + + + 268 + {{606, 264}, {66, 25}} + + YES + + -2080244224 + 134217728 + Set nil + + + -2038152961 + 163 + + + 400 + 75 + + + + + 268 + {{408, 179}, {66, 25}} + + YES + + -2080244224 + 134217728 + Random + + + -2038152961 + 163 + + + 400 + 75 + + + + + 268 + {{495, 179}, {88, 25}} + + YES + + -2080244224 + 134217728 + objectValue + + + -2038152961 + 163 + + + 400 + 75 + + + + + 268 + {{604, 182}, {84, 18}} + + YES + + -2080244224 + 0 + Empty OK + + + 1211912703 + 2 + + NSImage + NSSwitch + + + NSSwitch + + + + 200 + 25 + + + + + 268 + {{96, 157}, {282, 17}} + + YES + + 68288064 + 272630784 + error1 + + + + + 1 + MC44ODE2MzI2NTMxIDAgMAA + + + + + + 268 + {{94, 91}, {271, 22}} + + YES + + -1804468671 + 272630784 + + + + YES + + + + + + + 268 + {{31, 93}, {50, 17}} + + YES + + 68288064 + 272630784 + Text + + + + + + + + + 268 + {{96, 121}, {357, 17}} + + YES + + 68288064 + 272630784 + Input: [a-zA-Z0-9], max length 7 + + + + + 3 + MC41AA + + + + + + + 268 + {{96, 69}, {282, 17}} + + YES + + 68288064 + 272630784 + error2 + + + + + 1 + MC44ODE2MzI2NTMxIDAgMAA + + + + + {734, 327} + + + {{0, 0}, {2560, 1418}} + {1.79769e+308, 1.79769e+308} + + + AppController + + + + + YES + + + theWindow + + + + 467 + + + + recordField + + + + 482 + + + + recordMenu + + + + 483 + + + + selectRecord: + + + + 484 + + + + dateField1 + + + + 491 + + + + dateField2 + + + + 492 + + + + setDate1: + + + + 497 + + + + setDate2: + + + + 498 + + + + setNil: + + + + 504 + + + + objectValue1: + + + + 511 + + + + objectValue2: + + + + 512 + + + + setEmptyOK: + + + + 517 + + + + textField + + + + 532 + + + + error1 + + + + 533 + + + + error2 + + + + 534 + + + + + YES + + 0 + + YES + + + + + + -2 + + + File's Owner + + + -1 + + + First Responder + + + -3 + + + Application + + + 371 + + + YES + + + + + + 372 + + + YES + + + + + + + + + + + + + + + + + + + + + + + + + 456 + + + YES + + + + + + 457 + + + + + 460 + + + YES + + + + + + 461 + + + + + 463 + + + YES + + + + + + 464 + + + + + 466 + + + + + 472 + + + YES + + + + + + 473 + + + + + 474 + + + YES + + + + + + 475 + + + YES + + + + + + 476 + + + YES + + + + + + + + 477 + + + + + 478 + + + + + 479 + + + + + 480 + + + YES + + + + + + 481 + + + + + 485 + + + YES + + + + + + 486 + + + YES + + + + + + 487 + + + YES + + + + + + 488 + + + + + 489 + + + + + 490 + + + + + 493 + + + YES + + + + + + 494 + + + + + 495 + + + YES + + + + + + 496 + + + + + 501 + + + YES + + + + + + 502 + + + + + 505 + + + YES + + + + + + 506 + + + + + 508 + + + YES + + + + + + 509 + + + + + 515 + + + YES + + + + + + 516 + + + + + 520 + + + YES + + + + + + 521 + + + + + 524 + + + YES + + + + + + 525 + + + YES + + + + + + 526 + + + YES + + + + + + 527 + + + YES + + + + + + 528 + + + + + 529 + + + + + 530 + + + + + 531 + + + + + + + YES + + YES + -3.IBPluginDependency + 371.IBEditorWindowLastContentRect + 371.IBPluginDependency + 371.IBWindowTemplateEditedContentRect + 371.NSWindowTemplate.visibleAtLaunch + 371.editorWindowContentRectSynchronizationRect + 372.IBPluginDependency + 456.IBPluginDependency + 456.IBViewBoundsToFrameTransform + 457.IBPluginDependency + 460.IBPluginDependency + 460.IBViewBoundsToFrameTransform + 461.IBPluginDependency + 463.IBPluginDependency + 463.IBViewBoundsToFrameTransform + 464.IBPluginDependency + 472.IBPluginDependency + 472.IBViewBoundsToFrameTransform + 473.IBPluginDependency + 474.IBPluginDependency + 475.IBPluginDependency + 476.IBEditorWindowLastContentRect + 476.IBPluginDependency + 477.IBPluginDependency + 478.IBPluginDependency + 479.IBPluginDependency + 480.IBPluginDependency + 480.IBViewBoundsToFrameTransform + 481.IBPluginDependency + 485.IBPluginDependency + 485.IBViewBoundsToFrameTransform + 486.IBPluginDependency + 486.IBViewBoundsToFrameTransform + 487.IBPluginDependency + 487.IBViewBoundsToFrameTransform + 488.IBPluginDependency + 489.IBPluginDependency + 490.IBPluginDependency + 493.IBPluginDependency + 493.IBViewBoundsToFrameTransform + 494.IBPluginDependency + 495.IBPluginDependency + 495.IBViewBoundsToFrameTransform + 496.IBPluginDependency + 501.IBPluginDependency + 501.IBViewBoundsToFrameTransform + 502.IBPluginDependency + 505.IBPluginDependency + 505.IBViewBoundsToFrameTransform + 506.IBPluginDependency + 508.IBPluginDependency + 508.IBViewBoundsToFrameTransform + 509.IBPluginDependency + 515.IBPluginDependency + 515.IBViewBoundsToFrameTransform + 516.IBPluginDependency + 520.IBPluginDependency + 520.IBViewBoundsToFrameTransform + 521.IBPluginDependency + 524.IBPluginDependency + 524.IBViewBoundsToFrameTransform + 525.IBPluginDependency + 525.IBViewBoundsToFrameTransform + 526.IBPluginDependency + 526.IBViewBoundsToFrameTransform + 527.IBPluginDependency + 527.IBViewBoundsToFrameTransform + 528.IBPluginDependency + 529.IBPluginDependency + 530.IBPluginDependency + 531.IBPluginDependency + + + YES + com.apple.InterfaceBuilder.CocoaPlugin + {{563, 711}, {734, 327}} + com.apple.InterfaceBuilder.CocoaPlugin + {{563, 711}, {734, 327}} + + {{33, 99}, {480, 360}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABCvAAAw5+AAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABB+AAAw0YAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABB+AAAw4uAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABCwAAAw4AAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{885, 954}, {138, 63}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABCwAAAwmAAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABCvAAAw0cAAA + + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABB+AAAw0QAAA + + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABCwAAAw2AAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABDzAAAw0gAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABDygAAw4EAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABD+4AAw0gAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABD94AAw0gAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABD94AAw0gAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABEFwAAwwIAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABCwAAAwywAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABCxgAAw0IAAA + + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABCEAAAwz8AAA + + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABCygAAw1sAAA + + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABCygAAwycAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 534 + + + + YES + + AppController + + theWindow + NSWindow + + + theWindow + + theWindow + NSWindow + + + + IBProjectSource + ./Classes/AppController.h + + + + AppController + + YES + + YES + objectValue1: + objectValue2: + selectRecord: + setDate1: + setDate2: + setEmptyOK: + setNil: + + + YES + id + id + id + id + id + id + id + + + + YES + + YES + objectValue1: + objectValue2: + selectRecord: + setDate1: + setDate2: + setEmptyOK: + setNil: + + + YES + + objectValue1: + id + + + objectValue2: + id + + + selectRecord: + id + + + setDate1: + id + + + setDate2: + id + + + setEmptyOK: + id + + + setNil: + id + + + + + YES + + YES + dateField1 + dateField2 + error1 + error2 + recordField + recordMenu + textField + + + YES + NSTextField + NSTextField + NSTextField + NSTextField + NSTextField + NSPopUpButton + NSTextField + + + + YES + + YES + dateField1 + dateField2 + error1 + error2 + recordField + recordMenu + textField + + + YES + + dateField1 + NSTextField + + + dateField2 + NSTextField + + + error1 + NSTextField + + + error2 + NSTextField + + + recordField + NSTextField + + + recordMenu + NSPopUpButton + + + textField + NSTextField + + + + + IBUserSource + + + + + + 0 + IBCocoaFramework + + com.apple.InterfaceBuilder.CocoaPlugin.macosx + + + + com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 + + + YES + + 3 + + YES + + YES + NSMenuCheckmark + NSMenuMixedState + NSSwitch + + + YES + {9, 8} + {7, 2} + {15, 15} + + + + diff --git a/Tests/Manual/CPFormatterTest/Resources/date-functions.js b/Tests/Manual/CPFormatterTest/Resources/date-functions.js new file mode 100644 index 000000000..639a6c2ee --- /dev/null +++ b/Tests/Manual/CPFormatterTest/Resources/date-functions.js @@ -0,0 +1,471 @@ +/* + * http://code.google.com/p/flexible-js-formatting/ + * + * Copyright (C) 2004 Baron Schwartz + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +Date.parseFunctions = {count:0}; +Date.parseRegexes = []; +Date.formatFunctions = {count:0}; + +Date.prototype.dateFormat = function(format, ignore_offset) { + if (Date.formatFunctions[format] == null) { + Date.createNewFormat(format); + } + var func = Date.formatFunctions[format]; + if (ignore_offset || ! this.offset) { + return this[func](); + } else { + return (new Date(this.valueOf() - this.offset))[func](); + } +}; + +Date.createNewFormat = function(format) { + var funcName = "format" + Date.formatFunctions.count++; + Date.formatFunctions[format] = funcName; + var code = "Date.prototype." + funcName + " = function(){return "; + var special = false; + var ch = ''; + for (var i = 0; i < format.length; ++i) { + ch = format.charAt(i); + // escape character start + if (!special && ch == "\\") { + special = true; + } + // escaped string + else if (!special && ch == '"') { + var end = format.indexOf('"', i+1); + if (end==-1) + { + end = format.length; + } + code += "'" + String.escape(format.substring(i+1, end)) + "' + "; + i = end; + } + // escaped character + else if (special) { + special = false; + code += "'" + String.escape(ch) + "' + "; + } + else { + code += Date.getFormatCode(ch); + } + } + eval(code.substring(0, code.length - 3) + ";}"); +}; + +Date.getFormatCode = function(character) { + switch (character) { + case "d": + return "String.leftPad(this.getDate(), 2, '0') + "; + case "D": + return "Date.dayNames[this.getDay()].substring(0, 3) + "; + case "j": + return "this.getDate() + "; + case "l": + return "Date.dayNames[this.getDay()] + "; + case "S": + return "this.getSuffix() + "; + case "w": + return "this.getDay() + "; + case "z": + return "this.getDayOfYear() + "; + case "W": + return "this.getWeekOfYear() + "; + case "F": + return "Date.monthNames[this.getMonth()] + "; + case "m": + return "String.leftPad(this.getMonth() + 1, 2, '0') + "; + case "M": + return "Date.monthNames[this.getMonth()].substring(0, 3) + "; + case "n": + return "(this.getMonth() + 1) + "; + case "t": + return "this.getDaysInMonth() + "; + case "L": + return "(this.isLeapYear() ? 1 : 0) + "; + case "Y": + return "this.getFullYear() + "; + case "y": + return "('' + this.getFullYear()).substring(2, 4) + "; + case "a": + return "(this.getHours() < 12 ? 'am' : 'pm') + "; + case "A": + return "(this.getHours() < 12 ? 'AM' : 'PM') + "; + case "g": + return "((this.getHours() %12) ? this.getHours() % 12 : 12) + "; + case "G": + return "this.getHours() + "; + case "h": + return "String.leftPad((this.getHours() %12) ? this.getHours() % 12 : 12, 2, '0') + "; + case "H": + return "String.leftPad(this.getHours(), 2, '0') + "; + case "i": + return "String.leftPad(this.getMinutes(), 2, '0') + "; + case "s": + return "String.leftPad(this.getSeconds(), 2, '0') + "; + case "X": + return "String.leftPad(this.getMilliseconds(), 3, '0') + "; + case "O": + return "this.getGMTOffset() + "; + case "T": + return "this.getTimezone() + "; + case "Z": + return "(this.getTimezoneOffset() * -60) + "; + case "q": // quarter num, Q for name? + return "this.getQuarter() + "; + default: + return "'" + String.escape(character) + "' + "; + } +}; + +Date.parseDate = function(input, format) { + if (Date.parseFunctions[format] == null) { + Date.createParser(format); + } + var func = Date.parseFunctions[format]; + return Date[func](input); +}; + +Date.createParser = function(format) { + var funcName = "parse" + Date.parseFunctions.count++; + var regexNum = Date.parseRegexes.length; + var currentGroup = 1; + Date.parseFunctions[format] = funcName; + + var code = "Date." + funcName + " = function(input){\n" + + "var y = -1, m = -1, d = -1, h = -1, i = -1, s = -1, ms = -1, z = 0;\n" + + "var d = new Date();\n" + + "y = d.getFullYear();\n" + + "m = d.getMonth();\n" + + "d = d.getDate();\n" + + "var results = input.match(Date.parseRegexes[" + regexNum + "]);\n" + + "if (results && results.length > 0) {" ; + var regex = ""; + + var special = false; + var ch = ''; + for (var i = 0; i < format.length; ++i) { + ch = format.charAt(i); + if (!special && ch == "\\") { + special = true; + } + else if (special) { + special = false; + regex += String.escape(ch); + } + else { + obj = Date.formatCodeToRegex(ch, currentGroup); + currentGroup += obj.g; + regex += obj.s; + if (obj.g && obj.c) { + code += obj.c; + } + } + } + + code += "if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0 && ms >= 0)\n" + + "{return new Date(y, m, d, h, i, s, ms).applyOffset(z);}\n" + + "if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0)\n" + + "{return new Date(y, m, d, h, i, s).applyOffset(z);}\n" + + "else if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0)\n" + + "{return new Date(y, m, d, h, i).applyOffset(z);}\n" + + "else if (y > 0 && m >= 0 && d > 0 && h >= 0)\n" + + "{return new Date(y, m, d, h).applyOffset(z);}\n" + + "else if (y > 0 && m >= 0 && d > 0)\n" + + "{return new Date(y, m, d).applyOffset(z);}\n" + + "else if (y > 0 && m >= 0)\n" + + "{return new Date(y, m).applyOffset(z);}\n" + + "else if (y > 0)\n" + + "{return new Date(y).applyOffset(z);}\n" + + "}return null;}"; + + Date.parseRegexes[regexNum] = new RegExp("^" + regex + "$"); + eval(code); +}; + +Date.formatCodeToRegex = function(character, currentGroup) { + switch (character) { + case "D": + return {g:0, + c:null, + s:"(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)"}; + case "j": + case "d": + return {g:1, + c:"d = parseInt(results[" + currentGroup + "], 10);\n", + s:"(\\d{1,2})"}; + case "l": + return {g:0, + c:null, + s:"(?:" + Date.dayNames.join("|") + ")"}; + case "S": + return {g:0, + c:null, + s:"(?:st|nd|rd|th)"}; + case "w": + return {g:0, + c:null, + s:"\\d"}; + case "z": + return {g:0, + c:null, + s:"(?:\\d{1,3})"}; + case "W": + return {g:0, + c:null, + s:"(?:\\d{2})"}; + case "F": + return {g:1, + c:"m = parseInt(Date.monthNumbers[results[" + currentGroup + "].substring(0, 3)], 10);\n", + s:"(" + Date.monthNames.join("|") + ")"}; + case "M": + return {g:1, + c:"m = parseInt(Date.monthNumbers[results[" + currentGroup + "]], 10);\n", + s:"(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)"}; + case "n": + case "m": + return {g:1, + c:"m = parseInt(results[" + currentGroup + "], 10) - 1;\n", + s:"(\\d{1,2})"}; + case "t": + return {g:0, + c:null, + s:"\\d{1,2}"}; + case "L": + return {g:0, + c:null, + s:"(?:1|0)"}; + case "Y": + return {g:1, + c:"y = parseInt(results[" + currentGroup + "], 10);\n", + s:"(\\d{4})"}; + case "y": + return {g:1, + c:"var ty = parseInt(results[" + currentGroup + "], 10);\n" + + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n", + s:"(\\d{1,2})"}; + case "a": + return {g:1, + c:"if (results[" + currentGroup + "] == 'am') {\n" + + "if (h == 12) { h = 0; }\n" + + "} else { if (h < 12) { h += 12; }}", + s:"(am|pm)"}; + case "A": + return {g:1, + c:"if (results[" + currentGroup + "] == 'AM') {\n" + + "if (h == 12) { h = 0; }\n" + + "} else { if (h < 12) { h += 12; }}", + s:"(AM|PM)"}; + case "g": + case "G": + case "h": + case "H": + return {g:1, + c:"h = parseInt(results[" + currentGroup + "], 10);\n", + s:"(\\d{1,2})"}; + case "i": + return {g:1, + c:"i = parseInt(results[" + currentGroup + "], 10);\n", + s:"(\\d{2})"}; + case "s": + return {g:1, + c:"s = parseInt(results[" + currentGroup + "], 10);\n", + s:"(\\d{2})"}; + case "X": + return {g:1, + c:"ms = parseInt(results[" + currentGroup + "], 10);\n", + s:"(\\d{3})"}; + case "O": + case "P": + return {g:1, + c:"z = Date.parseOffset(results[" + currentGroup + "], 10);\n", + s:"(Z|[+-]\\d{2}:?\\d{2})"}; // "Z", "+05:00", "+0500" all acceptable. + case "T": + return {g:0, + c:null, + s:"[A-Z]{3}"}; + case "Z": + return {g:1, + c:"s = parseInt(results[" + currentGroup + "], 10);\n", + s:"([+-]\\d{1,5})"}; + default: + return {g:0, + c:null, + s:String.escape(character)}; + } +}; + +Date.parseOffset = function(str) { + if (str == "Z") { return 0 ; } // UTC, no offset. + var seconds ; + seconds = parseInt(str[0] + str[1] + str[2]) * 3600 ; // e.g., "+05" or "-08" + if (str[3] == ":") { // "+HH:MM" is preferred iso8601 format ("O") + seconds += parseInt(str[4] + str[5]) * 60; + } else { // "+HHMM" is frequently used, though. ("P") + seconds += parseInt(str[3] + str[4]) * 60; + } + return seconds ; +}; + +// convert the parsed date into UTC, but store the offset so we can optionally use it in dateFormat() +Date.prototype.applyOffset = function(offset_seconds) { + this.offset = offset_seconds * 1000 ; + this.setTime(this.valueOf() + this.offset); + return this ; +}; + +Date.prototype.getTimezone = function() { + return this.toString().replace( + /^.*? ([A-Z]{3}) [0-9]{4}.*$/, "$1").replace( + /^.*?\(([A-Z])[a-z]+ ([A-Z])[a-z]+ ([A-Z])[a-z]+\)$/, "$1$2$3").replace( + /^.*?[0-9]{4} \(([A-Z]{3})\)/, "$1"); +}; + +Date.prototype.getGMTOffset = function() { + return (this.getTimezoneOffset() > 0 ? "-" : "+") + + String.leftPad(Math.floor(this.getTimezoneOffset() / 60), 2, "0") + + String.leftPad(this.getTimezoneOffset() % 60, 2, "0"); +}; + +Date.prototype.getDayOfYear = function() { + var num = 0; + Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28; + for (var i = 0; i < this.getMonth(); ++i) { + num += Date.daysInMonth[i]; + } + return num + this.getDate() - 1; +}; + +Date.prototype.getWeekOfYear = function() { + // Skip to Thursday of this week + var now = this.getDayOfYear() + (4 - this.getDay()); + // Find the first Thursday of the year + var jan1 = new Date(this.getFullYear(), 0, 1); + var then = (7 - jan1.getDay() + 4); + document.write(then); + return String.leftPad(((now - then) / 7) + 1, 2, "0"); +}; + +Date.prototype.isLeapYear = function() { + var year = this.getFullYear(); + return ((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year))); +}; + +Date.prototype.getFirstDayOfMonth = function() { + var day = (this.getDay() - (this.getDate() - 1)) % 7; + return (day < 0) ? (day + 7) : day; +}; + +Date.prototype.getLastDayOfMonth = function() { + var day = (this.getDay() + (Date.daysInMonth[this.getMonth()] - this.getDate())) % 7; + return (day < 0) ? (day + 7) : day; +}; + +Date.prototype.getDaysInMonth = function() { + Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28; + return Date.daysInMonth[this.getMonth()]; +}; +Date.prototype.getQuarter = function() { + return Date.quarterFromMonthNum[this.getMonth()]; +}; + +Date.prototype.getSuffix = function() { + switch (this.getDate()) { + case 1: + case 21: + case 31: + return "st"; + case 2: + case 22: + return "nd"; + case 3: + case 23: + return "rd"; + default: + return "th"; + } +}; + +String.escape = function(string) { + return string.replace(/('|\\)/g, "\\$1"); +}; + +String.leftPad = function (val, size, ch) { + var result = new String(val); + if (ch == null) { + ch = " "; + } + while (result.length < size) { + result = ch + result; + } + return result; +}; + +Date.quarterFromMonthNum = [1,1,1,2,2,2,3,3,3,4,4,4]; +Date.daysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31]; +Date.monthNames = + ["January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December"]; +Date.dayNames = + ["Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday"]; +Date.y2kYear = 50; +Date.monthNumbers = { + Jan:0, + Feb:1, + Mar:2, + Apr:3, + May:4, + Jun:5, + Jul:6, + Aug:7, + Sep:8, + Oct:9, + Nov:10, + Dec:11}; +Date.patterns = { + ISO8601LongPattern: "Y\\-m\\-d\\TH\\:i\\:sO", + ISO8601ShortPattern: "Y\\-m\\-d", + ShortDatePattern: "n/j/Y", + LongDatePattern: "l, F d, Y", + FullDateTimePattern: "l, F d, Y g:i:s A", + MonthDayPattern: "F d", + ShortTimePattern: "g:i A", + LongTimePattern: "g:i:s A", + SortableDateTimePattern: "Y-m-d\\TH:i:s", + UniversalSortableDateTimePattern: "Y-m-d H:i:sO", + YearMonthPattern: "F, Y"}; diff --git a/Tests/Manual/CPFormatterTest/Resources/spinner.gif b/Tests/Manual/CPFormatterTest/Resources/spinner.gif new file mode 100644 index 000000000..06dbc2bc2 Binary files /dev/null and b/Tests/Manual/CPFormatterTest/Resources/spinner.gif differ diff --git a/Tests/Manual/CPFormatterTest/index-debug.html b/Tests/Manual/CPFormatterTest/index-debug.html new file mode 100644 index 000000000..106d36a06 --- /dev/null +++ b/Tests/Manual/CPFormatterTest/index-debug.html @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + CPFormatterTest + + + + + + + + + + + + + + + + +
+
+ + + +
+
+ + + diff --git a/Tests/Manual/CPFormatterTest/index.html b/Tests/Manual/CPFormatterTest/index.html new file mode 100644 index 000000000..80e399ef6 --- /dev/null +++ b/Tests/Manual/CPFormatterTest/index.html @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + CPFormatterTest + + + + + + + + + + + + + + +
+
+ + + +
+
+ + + diff --git a/Tests/Manual/CPFormatterTest/main.j b/Tests/Manual/CPFormatterTest/main.j new file mode 100644 index 000000000..d827b2325 --- /dev/null +++ b/Tests/Manual/CPFormatterTest/main.j @@ -0,0 +1,23 @@ +/* + * AppController.j + * CPFormatterTest + * + * Created by aparajita on June 30, 2011. + * Copyright 2011, Victory-Heart Productions All rights reserved. + */ + +@import +@import + +@import "AppController.j" + +function formatter(aString, aLevel, aTitle) +{ + return aString; +} + +function main(args, namedArgs) +{ + CPLogRegister(CPLogConsole, null, formatter); + CPApplicationMain(args, namedArgs); +}