diff --git a/AppKit/CPCollectionView.j b/AppKit/CPCollectionView.j index 62069c8e1..f206d1473 100644 --- a/AppKit/CPCollectionView.j +++ b/AppKit/CPCollectionView.j @@ -177,7 +177,7 @@ */ - (BOOL)isFirstResponder { - return [[self window] firstResponder] == self; + return [[self window] firstResponder] === self; } // Setting the Content diff --git a/AppKit/CPColor.j b/AppKit/CPColor.j index 23f2415df..636f96a3f 100644 --- a/AppKit/CPColor.j +++ b/AppKit/CPColor.j @@ -375,6 +375,16 @@ var cachedBlackColor, return cachedClearColor; } ++ (CPColor)alternateSelectedControlColor +{ + return [[CPColor alloc] _initWithRGBA:[0.22, 0.46, 0.84, 1.0]]; +} + ++ (CPColor)secondarySelectedControlColor +{ + return [[CPColor alloc] _initWithRGBA:[0.83, 0.83, 0.83, 1.0]]; +} + /*! Creates a color using a tile pattern with \c anImage @param the image to tile diff --git a/AppKit/CPScrollView.j b/AppKit/CPScrollView.j index 49a844ed2..c6703958a 100644 --- a/AppKit/CPScrollView.j +++ b/AppKit/CPScrollView.j @@ -38,7 +38,8 @@ @implementation CPScrollView : CPView { CPClipView _contentView; - + CPClipView _headerClipView; + BOOL _hasVerticalScroller; BOOL _hasHorizontalScroller; BOOL _autohidesScrollers; @@ -57,23 +58,27 @@ - (id)initWithFrame:(CGRect)aFrame { self = [super initWithFrame:aFrame]; - + if (self) { _verticalLineScroll = 10.0; _verticalPageScroll = 10.0; - + _horizontalLineScroll = 10.0; _horizontalPageScroll = 10.0; _contentView = [[CPClipView alloc] initWithFrame:[self bounds]]; - + [self addSubview:_contentView]; - + + _headerClipView = [[CPClipView alloc] init]; + + [self addSubview:_headerClipView]; + [self setHasVerticalScroller:YES]; [self setHasHorizontalScroller:YES]; } - + return self; } @@ -100,24 +105,24 @@ */ - (void)setContentView:(CPClipView)aContentView { - if (!aContentView) + if (_contentView !== aContentView || !aContentView) return; - + var documentView = [aContentView documentView]; - + if (documentView) [documentView removeFromSuperview]; - + [_contentView removeFromSuperview]; - - var size = [self contentSize]; - + _contentView = aContentView; - - [_contentView setFrame:CGRectMake(0.0, 0.0, size.width, size.height)]; + [_contentView setDocumentView:documentView]; [self addSubview:_contentView]; + + // This will size the content view appropriately, so no need to size it in this method. + [self reflectScrolledClipView:_contentView]; } /*! @@ -134,8 +139,15 @@ */ - (void)setDocumentView:(CPView)aView { - [_contentView setDocumentView:aView]; - [self reflectScrolledClipView:_contentView]; + [_contentView setDocumentView:aView]; + [_headerClipView setDocumentView:[self _headerView]]; + + var cornerView = [self _cornerView]; + + if (cornerView) + [self addSubview:cornerView]; + + [self reflectScrolledClipView:_contentView]; } /*! @@ -166,72 +178,98 @@ // [_verticalScroller setEnabled:NO]; // [_horizontalScroller setEnabled:NO]; } - + [_contentView setFrame:[self bounds]]; - + [_headerClipView setFrame:_CGRectMakeZero()]; + --_recursionCount; - + return; } - var documentFrame = [documentView frame], - contentViewFrame = [self bounds], - scrollPoint = [_contentView bounds].origin, - difference = _CGSizeMake(CPRectGetWidth(documentFrame) - CPRectGetWidth(contentViewFrame), CPRectGetHeight(documentFrame) - CPRectGetHeight(contentViewFrame)), - shouldShowVerticalScroller = (!_autohidesScrollers || difference.height > 0.0) && _hasVerticalScroller, - shouldShowHorizontalScroller = (!_autohidesScrollers || difference.width > 0.0) && _hasHorizontalScroller, - wasShowingVerticalScroller = ![_verticalScroller isHidden], - wasShowingHorizontalScroller = ![_horizontalScroller isHidden], - verticalScrollerWidth = _CGRectGetWidth([_verticalScroller frame]); - horizontalScrollerHeight = _CGRectGetHeight([_horizontalScroller frame]); + var documentFrame = [documentView frame], // the size of the whole document + contentFrame = [self bounds], // assume it takes up the entire size of the scrollview (no scrollers) + headerClipViewFrame = [self headerClipViewFrame], + headerClipViewHeight = _CGRectGetHeight(headerClipViewFrame); - if (_autohidesScrollers) - { - // Check to see if either affected the other! - if (shouldShowVerticalScroller) - shouldShowHorizontalScroller = (!_autohidesScrollers || difference.width > -verticalScrollerWidth) && _hasHorizontalScroller; + contentFrame.origin.y += headerClipViewHeight; + contentFrame.size.height -= headerClipViewHeight; - if (shouldShowHorizontalScroller) - shouldShowVerticalScroller = (!_autohidesScrollers || difference.height > -horizontalScrollerHeight) && _hasVerticalScroller; - } - - [_verticalScroller setHidden:!shouldShowVerticalScroller]; - [_verticalScroller setEnabled:difference.height > 0.0]; - - [_horizontalScroller setHidden:!shouldShowHorizontalScroller]; - [_horizontalScroller setEnabled:difference.width > 0.0]; + var difference = _CGSizeMake(_CGRectGetWidth(documentFrame) - _CGRectGetWidth(contentFrame), _CGRectGetHeight(documentFrame) - _CGRectGetHeight(contentFrame)), + verticalScrollerWidth = _CGRectGetWidth([_verticalScroller frame]), + horizontalScrollerHeight = _CGRectGetHeight([_horizontalScroller frame]), + hasVerticalScroll = difference.height > 0.0, + hasHorizontalScroll = difference.width > 0.0, + shouldShowVerticalScroller = _hasVerticalScroller && (!_autohidesScrollers || hasVerticalScroll), + shouldShowHorizontalScroller = _hasHorizontalScroller && (!_autohidesScrollers || hasHorizontalScroll); + // Now we have to account for the shown scrollers affecting the deltas. if (shouldShowVerticalScroller) { - var verticalScrollerHeight = CPRectGetHeight(contentViewFrame); - - if (shouldShowHorizontalScroller) - verticalScrollerHeight -= horizontalScrollerHeight; - difference.width += verticalScrollerWidth; - contentViewFrame.size.width -= verticalScrollerWidth; - - [_verticalScroller setFloatValue:(difference.height <= 0.0) ? 0.0 : scrollPoint.y / difference.height - knobProportion:CPRectGetHeight(contentViewFrame) / CPRectGetHeight(documentFrame)]; - [_verticalScroller setFrame:CPRectMake(CPRectGetMaxX(contentViewFrame), 0.0, verticalScrollerWidth, verticalScrollerHeight)]; + hasHorizontalScroll = difference.width > 0.0; + shouldShowHorizontalScroller = _hasHorizontalScroller && (!_autohidesScrollers || hasHorizontalScroll); } - else if (wasShowingVerticalScroller) - [_verticalScroller setFloatValue:0.0 knobProportion:1.0]; - + if (shouldShowHorizontalScroller) { difference.height += horizontalScrollerHeight; - contentViewFrame.size.height -= horizontalScrollerHeight; - - [_horizontalScroller setFloatValue:(difference.width <= 0.0) ? 0.0 : scrollPoint.x / difference.width - knobProportion:CPRectGetWidth(contentViewFrame) / CPRectGetWidth(documentFrame)]; - [_horizontalScroller setFrame:CPRectMake(0.0, CPRectGetMaxY(contentViewFrame), CPRectGetWidth(contentViewFrame), horizontalScrollerHeight)]; + hasVerticalScroll = difference.height > 0.0; + shouldShowVerticalScroller = _hasVerticalScroller && (!_autohidesScrollers || hasVerticalScroll); + } + + // We now definitively know which scrollers are shown or not, as well as whether they are showing scroll values. + [_verticalScroller setHidden:!shouldShowVerticalScroller]; + [_verticalScroller setEnabled:hasVerticalScroll]; + + [_horizontalScroller setHidden:!shouldShowHorizontalScroller]; + [_horizontalScroller setEnabled:hasHorizontalScroll]; + + // We can thus appropriately account for them changing the content size. + if (shouldShowVerticalScroller) + contentFrame.size.width -= verticalScrollerWidth; + + if (shouldShowHorizontalScroller) + contentFrame.size.height -= horizontalScrollerHeight; + + var scrollPoint = [_contentView bounds].origin, + wasShowingVerticalScroller = ![_verticalScroller isHidden], + wasShowingHorizontalScroller = ![_horizontalScroller isHidden]; + + if (shouldShowVerticalScroller) + { + var verticalScrollerY = MAX(_CGRectGetHeight([self cornerViewFrame]), headerClipViewHeight), + verticalScrollerHeight = _CGRectGetHeight([self bounds]) - verticalScrollerY; + + if (shouldShowHorizontalScroller) + verticalScrollerHeight -= horizontalScrollerHeight; + + [_verticalScroller setFloatValue:(difference.height <= 0.0) ? 0.0 : scrollPoint.y / difference.height]; + [_verticalScroller setKnobProportion:_CGRectGetHeight(contentFrame) / _CGRectGetHeight(documentFrame)]; + [_verticalScroller setFrame:_CGRectMake(_CGRectGetMaxX(contentFrame), verticalScrollerY, verticalScrollerWidth, verticalScrollerHeight)]; + } + else if (wasShowingVerticalScroller) + { + [_verticalScroller setFloatValue:0.0]; + [_verticalScroller setKnobProportion:1.0]; + } + + if (shouldShowHorizontalScroller) + { + [_horizontalScroller setFloatValue:(difference.width <= 0.0) ? 0.0 : scrollPoint.x / difference.width]; + [_horizontalScroller setKnobProportion:_CGRectGetWidth(contentFrame) / _CGRectGetWidth(documentFrame)]; + [_horizontalScroller setFrame:_CGRectMake(0.0, _CGRectGetMaxY(contentFrame), _CGRectGetWidth(contentFrame), horizontalScrollerHeight)]; } else if (wasShowingHorizontalScroller) - [_horizontalScroller setFloatValue:0.0 knobProportion:1.0]; - - [_contentView setFrame:contentViewFrame]; - + { + [_horizontalScroller setFloatValue:0.0]; + [_horizontalScroller setKnobProportion:1.0]; + } + + [_contentView setFrame:contentFrame]; + [_headerClipView setFrame:headerClipViewFrame]; + [[self _cornerView] setFrame:[self cornerViewFrame]]; + --_recursionCount; } @@ -280,7 +318,7 @@ _hasHorizontalScroller = shouldHaveHorizontalScroller; if (_hasHorizontalScroller && !_horizontalScroller) - [self setHorizontalScroller:[[CPScroller alloc] initWithFrame:CGRectMake(0.0, 0.0, CPRectGetWidth([self bounds]), [CPScroller scrollerWidth])]]; + [self setHorizontalScroller:[[CPScroller alloc] initWithFrame:CGRectMake(0.0, 0.0, _CGRectGetWidth([self bounds]), [CPScroller scrollerWidth])]]; else if (!_hasHorizontalScroller && _horizontalScroller) { @@ -343,7 +381,7 @@ _hasVerticalScroller = shouldHaveVerticalScroller; if (_hasVerticalScroller && !_verticalScroller) - [self setVerticalScroller:[[CPScroller alloc] initWithFrame:CPRectMake(0.0, 0.0, [CPScroller scrollerWidth], CPRectGetHeight([self bounds]))]]; + [self setVerticalScroller:[[CPScroller alloc] initWithFrame:_CGRectMake(0.0, 0.0, [CPScroller scrollerWidth], _CGRectGetHeight([self bounds]))]]; else if (!_hasVerticalScroller && _verticalScroller) { @@ -384,13 +422,56 @@ { return _autohidesScrollers; } -/* -- (void)setFrameSize:(CPRect)aSize + +- (CPView)_headerView { - [super setFrameSize:aSize]; + var documentView = [self documentView]; - [self reflectScrolledClipView:_contentView]; -}*/ + if ([documentView respondsToSelector:@selector(headerView)]) + return [documentView headerView]; + + return nil; +} + +- (CPView)_cornerView +{ + var documentView = [self documentView]; + + if ([documentView respondsToSelector:@selector(cornerView)]) + return [documentView cornerView]; +} + +- (CGRect)cornerViewFrame +{ + var cornerView = [self _cornerView], + cornerBounds = [cornerView bounds], + bounds = [self bounds]; + + if (!cornerView) + return _CGRectMakeZero(); + + cornerBounds.origin.x = CGRectGetMaxX(bounds) - CGRectGetWidth(cornerBounds); + cornerBounds.origin.y = 0; + + return cornerBounds; +} + +- (CGRect)headerClipViewFrame +{ + var headerView = [self _headerView], + cornerView = [self _cornerView], + bounds = [self bounds]; + + if (!headerView) + return _CGRectMakeZero(); + + bounds.size.height = [headerView bounds].size.height; + + if (cornerView) + bounds.size.width -= CGRectGetWidth([cornerView bounds]); + + return bounds; +} /* @ignore */ - (void)_verticalScrollerDidScroll:(CPScroller)aScroller @@ -448,6 +529,7 @@ } [_contentView scrollToPoint:contentBounds.origin]; + [_headerClipView scrollToPoint:CGPointMake(contentBounds.origin.x, 0.0)]; } /*! @@ -587,6 +669,7 @@ contentBounds.origin.y += [anEvent deltaY] * _verticalLineScroll; [_contentView scrollToPoint:contentBounds.origin]; + [_headerClipView scrollToPoint:CGPointMake(contentBounds.origin.x, 0.0)]; } - (void)keyDown:(CPEvent)anEvent @@ -625,6 +708,7 @@ } [_contentView scrollToPoint:contentBounds.origin]; + [_headerClipView scrollToPoint:CGPointMake(contentBounds.origin, 0)]; } @end diff --git a/AppKit/CPScroller.j b/AppKit/CPScroller.j index 77248fb23..b6664f474 100644 --- a/AppKit/CPScroller.j +++ b/AppKit/CPScroller.j @@ -64,9 +64,9 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob"; BOOL _isVertical @accessors(readonly, getter=isVertical); float _knobProportion; - + CPScrollerPart _hitPart; - + CPScrollerPart _trackingPart; float _trackingFloatValue; CGPoint _trackingStartPoint; @@ -104,11 +104,12 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob"; _controlSize = CPRegularControlSize; _partRects = []; - [self setFloatValue:0.0 knobProportion:1.0]; + [self setFloatValue:0.0]; + [self setKnobProportion:1.0]; _hitPart = CPScrollerNoPart; - [self _recalculateIsVertical]; + [self _calculateIsVertical]; } return self; @@ -155,28 +156,17 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob"; return _controlSize; } -// Setting the Knob Position -/*! - Sets the scroller's knob position (ranges from 0.0 to 1.0). - @param aValue the knob position (ranges from 0.0 to 1.0) -*/ -- (void)setFloatValue:(float)aValue +- (void)setObjectValue:(id)aValue { - [super setFloatValue:MIN(1.0, MAX(0.0, aValue))]; - - [self setNeedsLayout]; + [super setObjectValue:MIN(1.0, MAX(0.0, +aValue))]; } -/*! - Sets the position and proportion of the knob. - @param aValue the knob position (ranges from 0.0 to 1.0) - @param aProportion the knob's proportion (ranges from 0.0 to 1.0) -*/ -- (void)setFloatValue:(float)aValue knobProportion:(float)aProportion +- (void)setKnobProportion:(float)aProportion { _knobProportion = MIN(1.0, MAX(0.0001, aProportion)); - [self setFloatValue:aValue]; + [self setNeedsDisplay:YES]; + [self setNeedsLayout]; } /*! @@ -533,15 +523,15 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob"; } -- (void)_recalculateIsVertical +- (void)_calculateIsVertical { // Recalculate isVertical. var bounds = [self bounds], width = _CGRectGetWidth(bounds), height = _CGRectGetHeight(bounds); - + _isVertical = width < height ? 1 : (width > height ? 0 : -1); - + if (_isVertical === 1) [self setThemeState:CPThemeStateVertical]; else if (_isVertical === 0) @@ -552,8 +542,6 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob"; { [super setFrameSize:aSize]; - [self _recalculateIsVertical]; - [self checkSpaceForParts]; [self setNeedsLayout]; } @@ -590,18 +578,16 @@ var CPScrollerControlSizeKey = "CPScrollerControlSize", _controlSize = CPRegularControlSize; if ([aCoder containsValueForKey:CPScrollerControlSizeKey]) _controlSize = [aCoder decodeIntForKey:CPScrollerControlSizeKey]; - + _knobProportion = 1.0; if ([aCoder containsValueForKey:CPScrollerKnobProportionKey]) _knobProportion = [aCoder decodeFloatForKey:CPScrollerKnobProportionKey]; - + _partRects = []; _hitPart = CPScrollerNoPart; - [self _recalculateIsVertical]; -// [self checkSpaceForParts]; -// [self setNeedsLayout]; + [self _calculateIsVertical]; } return self; @@ -616,3 +602,18 @@ var CPScrollerControlSizeKey = "CPScrollerControlSize", } @end + +@implementation CPScroller (Deprecated) + +/*! + Sets the position and proportion of the knob. + @param aValue the knob position (ranges from 0.0 to 1.0) + @param aProportion the knob's proportion (ranges from 0.0 to 1.0) +*/ +- (void)setFloatValue:(float)aValue knobProportion:(float)aProportion +{ + [self setFloatValue:aValue]; + [self setKnobProportion:aProportion]; +} + +@end diff --git a/AppKit/CPTableColumn.j b/AppKit/CPTableColumn.j index 8d44cc0b2..9da18cfe3 100644 --- a/AppKit/CPTableColumn.j +++ b/AppKit/CPTableColumn.j @@ -3,7 +3,7 @@ * AppKit * * Created by Francisco Tolmasky. - * Copyright 2008, 280 North, Inc. + * Copyright 2009, 280 North, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,12 +20,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -@import +@import +@import +@import +@import +@import "CPTableHeaderView.j" -/* -@ignore -*/ /* @global @@ -43,389 +44,290 @@ CPTableColumnAutoresizingMask = 1; */ CPTableColumnUserResizingMask = 2; -#define PurgableInfoMake(aView, aRow) { view:(aView), row:(aRow) } -#define PurgableInfoView(anInfo) ((anInfo).view) -#define PurgableInfoRow(anInfo) ((anInfo).row) - -/*! - @ingroup appkit - @class CPTableColumn - - An CPTableColumn object mainly keeps information about the width of the column, its minimum and maximum width; whether the column can be edited or resized; and the cells used to draw the column header and the data in the column. You can change all these attributes of the column by calling the appropriate methods. Please note that the table column does not hold nor has access to the data to be displayed in the column; this data is maintained in the table view's data source.

- -

Each CPTableColumn object is identified by a CPString, called the column identifier. The reason is that, after a column has been added to a table view, the user might move the columns around, so there is a need to identify the columns regardless of its position in the table. - - @ignore -*/ @implementation CPTableColumn : CPObject { - CPString _identifier; - CPView _headerView; - - CPTableView _tableView; - - float _width; - float _minWidth; - float _maxWidth; - - unsigned _resizingMask; + CPTableView _tableView; + CPView _headerView; + CPView _dataView; + Object _dataViewData; - CPView _dataView; // default data view for this column + float _width; + float _minWidth; + float _maxWidth; - Object _dataViewData; // cache of data view archives (key=data view UID, value=data view archive) - Object _dataViewForView; // mapping from view instances back to their data view prototype (key=view instance UID, value=data view) - Object _purgableInfosForDataView; // (key=data view UID, value=) + id _identifier; + BOOL _isEditable; + CPSortDescriptor _sortDescriptorPrototype; + BOOL _isHidden; + CPString _headerToolTip; } -/*! - Initializes the table column with the specified identifier. - @param anIdentifier the identifier - @return the initialized table column -*/ -- (id)initWithIdentifier:(CPString)anIdentifier +- (id)initWithIdentifier:(id)anIdentifier { self = [super init]; - + if (self) { - [self _init]; - - _identifier = anIdentifier; - - _width = 40.0; - _minWidth = 8.0; - _maxWidth = 1000.0; - - var dataView = [[CPTextField alloc] initWithFrame:CPRectMakeZero()]; - [dataView setValue:[CPColor whiteColor] forThemeAttribute:"text-color" inState:CPThemeStateHighlighted]; - - [self setDataView:dataView]; - - _headerView = [[CPTextField alloc] initWithFrame:CPRectMakeZero()]; - [_headerView setBackgroundColor:[CPColor greenColor]]; + _dataViewData = { }; + + _width = 100.0; + _minWidth = 10.0; + _maxWidth = 1000000.0; + + [self setIdentifier:anIdentifier]; + [self setHeaderView:[CPTextField new]]; + [self setDataView:[CPTextField new]]; } - + return self; } -- (void)_init -{ - _dataViewData = {}; - _dataViewForView = {}; - _purgableInfosForDataView = {}; -} - -/*! - Sets the table column's identifier - @param anIdentifier the new identifier -*/ -- (void)setIdentifier:(CPString)anIdentifier -{ - _identifier = anIdentifier; -} - -/*! - Returns the table column's identifier -*/ -- (CPString)identifier -{ - return _identifier; -} - -// Setting the CPTableView -/*! - Sets the table's view. This is called automatically by Cappuccino. - @param aTableView the new table view -*/ - (void)setTableView:(CPTableView)aTableView { _tableView = aTableView; } -/*! - Returns the column's table view. -*/ - (CPTableView)tableView { return _tableView; } -// Controlling size -/*! - Sets the column's width. - @param aWidth the new column width -*/ - (void)setWidth:(float)aWidth { - _width = aWidth; + aWidth = +aWidth; + + if (_width === aWidth) + return; + + var newWidth = MIN(MAX(aWidth, [self minWidth]), [self maxWidth]); + + if (_width === newWidth) + return; + + var oldWidth = _width; + + _width = newWidth; + + var tableView = [self tableView]; + + if (tableView) + [[CPNotificationCenter defaultCenter] + postNotificationName:CPTableViewColumnDidResizeNotification + object:tableView + userInfo:[CPDictionary dictionaryWithObjects:[self, oldWidth] forKeys:[@"CPTableColumn", "CPOldWidth"]]]; } -/*! - Returns the column's width -*/ - (float)width { return _width; } -/*! - Sets column's minimum width. - @param aWidth the new minimum column width -*/ -- (void)setMinWidth:(float)aWidth +- (void)setMinWidth:(float)aMinWidth { - if (_width < (_minWidth = aWidth)) - [self setWidth:_minWidth]; + aMinWidth = +aMinWidth; + + if (_minWidth === aMinWidth) + return; + + _minWidth = aMinWidth; + + var width = [self width], + newWidth = MAX(width, [self minWidth]); + + if (width !== newWidth) + [self setWidth:newWidth]; } -/*! - The column's minimum width -*/ - (float)minWidth { return _minWidth; } -/*! - Sets the column's maximum width. - @param aWidth the new maximum width -*/ -- (void)setMaxWidth:(float)aWidth +- (void)setMaxWidth:(float)aMaxWidth { - if (_width > (_maxmimumWidth = aWidth)) - [self setWidth:_maxWidth]; + aMaxWidth = +aMaxWidth; + + if (_maxWidth === aMaxWidth) + return; + + _maxWidth = aMaxWidth; + + var width = [self width], + newWidth = MAX(width, [self maxWidth]); + + if (width !== newWidth) + [self setWidth:newWidth]; } -/*! - Sets the resizing mask. The mask is one of: -

-CPTableColumnNoResizing;
-CPTableColumnAutoresizingMask;
-CPTableColumnUserResizingMask;
-
- @param aMask the new resizing mask -*/ -- (void)setResizingMask:(unsigned)aMask +- (float)maxWidth { - _resizingMask = aMask; + return _maxWidth; } -/*! - Returns the column's resizing mask. One of: -
-CPTableColumnNoResizing;
-CPTableColumnAutoresizingMask;
-CPTableColumnUserResizingMask;
-
-*/ -- (unsigned)resizingMask +- (void)setResizingMask:(unsigned)aResizingMask +{ + _resizingMask = aResizingMask; +} + +- (float)resizingMask { return _resizingMask; } -/*! - Resizes the column according to the min, max and set width. -*/ - (void)sizeToFit { - var width = CPRectGetWidth([_headerView frame]); - - if (width < _minWidth) + var width = _CGRectGetWidth([_headerView frame]); + + if (width < [self minWidth]) [self setMinWidth:width]; - else if (width > _maxWidth) + else if (width > [self maxWidth]) [self setMaxWidth:width] - if (_width != width) + if (_width !== width) [self setWidth:width]; } -/*! - Sets whether the column in this data is editable. - @param aFlag \c YES means the column data is editable -*/ -- (void)setEditable:(BOOL)aFlag +//Setting Component Cells +- (void)setHeaderView:(CPView)aView { - _isEditable = aFlag; + if (!aView) + [CPException raise:CPInvalidArgumentException reason:@"Attempt to set nil header view on " + [self description]]; + + _headerView = aView; } -/*! - Returns \c YES if the column data is editable. +- (CPView)headerView +{ + return _headerView; +} + +- (void)setDataView:(CPView)aView +{ + if (_dataView === aView) + return; + + if (_dataView) + _dataViewData[[_dataView UID]] = nil; + + _dataView = aView; + _dataViewData[[aView UID]] = [CPKeyedArchiver archivedDataWithRootObject:aView]; +} + +- (CPView)dataView +{ + return _dataView; +} + +/* + Returns the CPView object used by the CPTableView to draw values for the receiver. + + By default, this method just calls dataView. Subclassers can override if they need to + potentially use different cells for different rows. Subclasses should expect this method + to be invoked with row equal to -1 in cases where no actual row is involved but the table + view needs to get some generic cell info. +*/ +- (id)dataViewForRow:(int)aRowIndex +{ + return [self dataView]; +} + +- (id)_newDataViewForRow:(int)aRowIndex +{ + var dataView = [self dataViewForRow:aRowIndex], + dataViewUID = [dataView UID]; + +var x = [self tableView]._cachedDataViews[dataViewUID]; +if (x && x.length) +return x.pop(); + + // if we haven't cached an archive of the data view, do it now + if (!_dataViewData[dataViewUID]) + _dataViewData[dataViewUID] = [CPKeyedArchiver archivedDataWithRootObject:dataView]; + + // unarchive the data view cache + var newDataView = [CPKeyedUnarchiver unarchiveObjectWithData:_dataViewData[dataViewUID]]; +newDataView.identifier = dataViewUID; + return newDataView; +} + +//Setting the Identifier + +/* + Sets the receiver identifier to anIdentifier. +*/ +- (void)setIdentifier:(id)anIdentifier +{ + _identifier = anIdentifier; +} + +/* + Returns the object used by the data source to identify the attribute corresponding to the receiver. +*/ +- (id)identifier +{ + return _identifier; +} + +//Controlling Editability + +/* + Controls whether the user can edit cells in the receiver by double-clicking them. +*/ +- (void)setEditable:(BOOL)shouldBeEditable +{ + _isEditable = shouldBeEditable; +} + +/* + Returns YES if the user can edit cells associated with the receiver by double-clicking the + column in the NSTableView, NO otherwise. */ - (BOOL)isEditable { return _isEditable; } -//Setting the column header view - -/*! - Sets the view that draws the column's header. - @param aHeaderView the view that will draws the column header -*/ - -- (void)setHeaderView:(CPView)aView +//Sorting +- (void)setSortDescriptorPrototype:(CPSortDescriptor)aSortDescriptor { - _headerView = aView; + _sortDescriptorPrototype = aSortDescriptor; } -/*! - Return the view that draws the column's header -*/ -- (CPView)headerView +- (CPSortDescriptor)sortDescriptorPrototype { - return _headerView; + return _sortDescriptorPrototype; } -/*! - Sets the data cell that draws rows in this column. -*/ -- (void)setDataCell:(CPView )aView +//Setting Column Visibility + +- (void)setHidden:(BOOL)shouldBeHidden { - [self setDataView:aView]; + _isHidden = shouldBeHidden; } +- (BOOL)isHidden +{ + return _isHidden; +} + +//Setting Tool Tips + /* - Sets the data view that draws rows in this column. + Sets the tooltip string that is displayed when the cursor pauses over the + header cell of the receiver. */ -- (void)setDataView:(CPView )aView +- (void)setHeaderToolTip:(CPString)aToolTip { - if (_dataView) - _dataViewData[[_dataView UID]] = nil; - - _dataView = aView; - _dataViewData[[aView UID]] = [CPKeyedArchiver archivedDataWithRootObject:aView]; + _headerToolTip = aToolTip; } -/*! - Returns the data cell that draws rows in this column -*/ -- (CPCell)dataCell +- (CPString)headerToolTip { - return _dataView; -} - -/* - Returns the data view that draws rows in this column -*/ -- (CPView)dataView -{ - return [self dataCell]; -} - -/*! - By default returns the value from \c -dataCell. This can - be overridden by a subclass to return different cells for different - rows. - @param aRowIndex the index of the row to obtain the cell for -*/ -- (CPCell)dataCellForRow:(int)aRowIndex -{ - return [self dataView]; -} - -- (CPView)dataViewForRow:(int)aRowIndex -{ - return [self dataCellForRow:aRowIndex]; -} -/* -- (void)_markViewAsPurgable:(CPView)aView -{ - var viewUID = [aView UID], - dataViewUID = [_dataViewForView[viewUID] UID]; - - if (!_purgableInfosForDataView[dataViewUID]) - _purgableInfosForDataView[dataViewUID] = [CPDictionary dictionary]; - - [_purgableInfosForDataView[dataViewUID] setObject:aView forKey:viewUID]; -} -*/ -- (void)_markView:(CPView)aView inRow:(unsigned)aRow asPurgable:(BOOL)isPurgable -{ - var viewUID = [aView UID], - dataViewUID = [_dataViewForView[viewUID] UID]; - - if (!_purgableInfosForDataView[dataViewUID]) - { - if (!isPurgable) - return; - - _purgableInfosForDataView[dataViewUID] = {}; - } - - if (!isPurgable) { - if (_purgableInfosForDataView[dataViewUID][viewUID]) - CPLog.warn("removing unpurgable " + _purgableInfosForDataView[dataViewUID][viewUID]); - delete _purgableInfosForDataView[dataViewUID][viewUID]; - } - else - _purgableInfosForDataView[dataViewUID][viewUID] = PurgableInfoMake(aView, aRow); -} - -- (CPView)_newDataViewForRow:(int)aRowIndex avoidingRows:(CPRange)rows -{ - var view = [self dataViewForRow:aRowIndex], - viewUID = [view UID], - purgableInfos = _purgableInfosForDataView[viewUID]; - - if (purgableInfos) - { - for (var key in purgableInfos) - { - var info = purgableInfos[key]; - //if (!CPLocationInRange(PurgableInfoRow(info), rows)) - //{ - //CPLog.debug("yes, a purged view is usable, its called: " + PurgableInfoView(info)); - delete purgableInfos[key]; - return PurgableInfoView(info); - //} - //else - // CPLog.warn("avoiding"); - } - } - - // if we haven't cached an archive of the data view, do it now - if (!_dataViewData[viewUID]) - _dataViewData[viewUID] = [CPKeyedArchiver archivedDataWithRootObject:view]; - - // unarchive the data view cache - var newView = [CPKeyedUnarchiver unarchiveObjectWithData:_dataViewData[viewUID]]; - - // map the new view's UID to it's data view prototype - _dataViewForView[[newView UID]] = view; - - CPLog.warn("creating cell: %s", newView); - - return newView; -} - -- (void)_purge -{ - for (var viewUID in _purgableInfosForDataView) - { - var purgableInfos = _purgableInfosForDataView[viewUID]; - - for (var key in purgableInfos) - { - var view = PurgableInfoView(purgableInfos[key]); - - if (!view) - CPLog.info("key="+key+" view=" + view + " purgableInfos[key]="+purgableInfos[key]) - else if (view._superview) { - //CPLog.error("PURGING: (removing)" + view); - //[view removeFromSuperview]; - [view setHidden:YES]; - } - //else - // CPLog.warn("PURGING: (already removed)" + view); - - //delete purgableInfos[key]; - } - } + return _headerToolTip; } @end - var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey", CPTableColumnHeaderViewKey = @"CPTableColumnHeaderViewKey", CPTableColumnDataViewKey = @"CPTableColumnDataViewKey", @@ -438,18 +340,26 @@ var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey", - (id)initWithCoder:(CPCoder)aCoder { - [self _init]; - - _identifier = [aCoder decodeObjectForKey:CPTableColumnIdentifierKey]; + self = [super init]; - [self setHeaderView:[aCoder decodeObjectForKey:CPTableColumnHeaderViewKey]]; - [self setDataView:[aCoder decodeObjectForKey:CPTableColumnDataViewKey]]; - - _width = [aCoder decodeFloatForKey:CPTableColumnWidthKey]; - _minWidth = [aCoder decodeFloatForKey:CPTableColumnMinWidthKey]; - _maxWidth = [aCoder decodeFloatForKey:CPTableColumnMaxWidthKey]; - - _resizingMask = [aCoder decodeBoolForKey:CPTableColumnResizingMaskKey]; + if (self) + { + _dataViewData = { }; + + _width = [aCoder decodeFloatForKey:CPTableColumnWidthKey]; + _minWidth = [aCoder decodeFloatForKey:CPTableColumnMinWidthKey]; + _maxWidth = [aCoder decodeFloatForKey:CPTableColumnMaxWidthKey]; + + [self setIdentifier:[aCoder decodeObjectForKey:CPTableColumnIdentifierKey]]; + // [self setHeaderView:[aCoder decodeObjectForKey:CPTableColumnHeaderViewKey]]; + // [self setDataView:[aCoder decodeObjectForKey:CPTableColumnDataViewKey]]; + + [self setHeaderView:[CPTextField new]]; + [self setDataView:[CPTextField new]]; + + + // _resizingMask = [aCoder decodeBoolForKey:CPTableColumnResizingMaskKey]; + } return self; } @@ -457,15 +367,49 @@ var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey", - (void)encodeWithCoder:(CPCoder)aCoder { [aCoder encodeObject:_identifier forKey:CPTableColumnIdentifierKey]; - - [aCoder encodeObject:_headerView forKey:CPTableColumnHeaderViewKey]; - [aCoder encodeObject:_dataView forKey:CPTableColumnDataViewKey]; - + [aCoder encodeObject:_width forKey:CPTableColumnWidthKey]; [aCoder encodeObject:_minWidth forKey:CPTableColumnMinWidthKey]; [aCoder encodeObject:_maxWidth forKey:CPTableColumnMaxWidthKey]; - - [aCoder encodeObject:_resizingMask forKey:CPTableColumnResizingMaskKey]; + +// [aCoder encodeObject:_headerView forKey:CPTableColumnHeaderViewKey]; +// [aCoder encodeObject:_dataView forKey:CPTableColumnDataViewKey]; + +// [aCoder encodeObject:_resizingMask forKey:CPTableColumnResizingMaskKey]; } @end + +@implementation CPTableColumn (NSInCompatibility) + +- (void)setHeaderCell:(CPView)aView +{ + [CPException raise:CPUnsupportedMethodException + reason:@"setHeaderCell: is not supported. -setHeaderCell:aView instead."]; +} + +- (CPView)headerCell +{ + [CPException raise:CPUnsupportedMethodException + reason:@"headCell is not supported. -headerView instead."]; +} + +- (void)setDataCell:(CPView)aView +{ + [CPException raise:CPUnsupportedMethodException + reason:@"setDataCell: is not supported. Use -setHeaderCell:aView instead."]; +} + +- (CPView)dataCell +{ + [CPException raise:CPUnsupportedMethodException + reason:@"dataCell is not supported. Use -dataCell instead."]; +} + +- (id)dataCellForRow:(int)row +{ + [CPException raise:CPUnsupportedMethodException + reason:@"dataCellForRow: is not supported. Use -dataViewForRow:row instead."]; +} + +@end \ No newline at end of file diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j new file mode 100644 index 000000000..2be231527 --- /dev/null +++ b/AppKit/CPTableHeaderView.j @@ -0,0 +1,145 @@ +/* + * CPTableHeaderView.j + * AppKit + * + * Created by Ross Boucher. + * Copyright 2009 280 North, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * 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 "CPTableColumn.j" +@import "CPTableView.j" +@import "CPView.j" + + +@implementation CPTableHeaderView : CPView +{ + int _resizedColumn @accessors(readonly, property=resizedColumn); + int _draggedColumn @accessors(readonly, property=draggedColumn); + + float _draggedDistance @accessors(readonly, property=draggedDistance); + + CPTableView _tableView @accessors(property=tableView); +} + +- (void)initWithFrame:(CGRect)aFrame +{ + self = [super initWithFrame:aFrame]; + + if (self) + { + _resizedColumn = CPNotFound; + _draggedColumn = CPNotFound; + _draggedDistance = 0.0; + } + + return self; +} + +- (int)columnAtPoint:(CGPoint)aPoint +{ + if (!CGRectContainsPoint([self bounds], aPoint)) + return CPNotFound; + + // at this point, we can essentially ignore height, because all columns have equal heights + // and that height is equal to the height of our own bounds, which we know we are inside of + + var index = 0, + count = [[_tableView tableColumns] count], + tableSpacing = [_tableView intercellSpacing], + tableColumns = [_tableView tableColumns], + leftOffset = 0, + pointX = aPoint.x; + + for (; index < count; index++) + { + var width = [tableColumns[index] width] + tableSpacing.width; + + if (pointX >= leftOffset && pointX < leftOffset + width) + return index; + + leftOffset += width; + } + + return CPNotFound; +} + +- (CGRect)headerRectOfColumn:(int)aColumnIndex +{ + var tableColumns = [_tableView tableColumns], + tableSpacing = [_tableView intercellSpacing], + bounds = [self bounds]; + + if (aColumnIndex < 0 || aColumnIndex > [tableColumns count]) + [CPException raise:"invalid" reason:"tried to get headerRectOfColumn: on invalid column"]; + + bounds.size.width = [tableColumns[aColumnIndex] width] + tableSpacing.width; + + while (--aColumnIndex >= 0) + bounds.origin.x += [tableColumns[aColumnIndex] width] + tableSpacing.width; + + return bounds; +} + +- (void)layoutSubviews +{ + var tableColumns = [_tableView tableColumns], + count = [tableColumns count], + columnRect = [self bounds], + spacing = [_tableView intercellSpacing]; + + for (i = 0; i < count; ++i) + { + var column = [tableColumns objectAtIndex:i], + headerView = [column headerView]; + + columnRect.size.width = [column width] + spacing.width; + + [headerView setFrame:columnRect]; + + columnRect.origin.x += [column width] + spacing.width; + + [self addSubview:headerView]; + } +} + +- (void)drawRect:(CGRect)aRect +{ + [[_tableView gridColor] setStroke]; + + var context = [[CPGraphicsContext currentContext] graphicsPort], + exposedColumnIndexes = exposedColumnIndexes = [_tableView columnIndexesInRect:aRect], + columnsArray = []; + + [exposedColumnIndexes getIndexes:columnsArray maxCount:-1 inIndexRange:nil]; + + var columnArrayIndex = 0, + columnArrayCount = columnsArray.length; + + for(; columnArrayIndex < columnArrayCount; ++columnArrayIndex) + { + // grab each column rect and add horizontal lines + var columnToStroke = [self headerRectOfColumn:columnArrayIndex]; + + CGContextBeginPath(context); + CGContextMoveToPoint(context, ROUND(columnToStroke.origin.x + columnToStroke.size.width) - 0.5, ROUND(columnToStroke.origin.y) - 0.5); + CGContextAddLineToPoint(context, ROUND(columnToStroke.origin.x + columnToStroke.size.width) - 0.5, ROUND(columnToStroke.origin.y + columnToStroke.size.height) - 0.5); + CGContextSetLineWidth(context, 1); + CGContextStrokePath(context); + } +} + +@end diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index b9143c62a..8b41d7506 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -3,7 +3,7 @@ * AppKit * * Created by Francisco Tolmasky. - * Copyright 2008, 280 North, Inc. + * Copyright 2009, 280 North, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,1219 +20,1657 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +@import + @import "CPControl.j" @import "CPTableColumn.j" +@import "_CPCornerView.j" +@import "CPScroller.j" -@import "CPColor.j" -@import "CPTextField.j" -#define ROW_HEIGHT(aRow) (_hasVariableHeightRows ? _rowHeights[aRow] : _rowHeight) -#define ROW_MIN_Y(aRow) (_hasVariableHeightRows ? _rowMinYs[aRow] : (aRow * (_rowHeight + _intercellSpacing.height))) +CPTableViewColumnDidMoveNotification = @"CPTableViewColumnDidMoveNotification"; +CPTableViewColumnDidResizeNotification = @"CPTableViewColumnDidResizeNotification"; +CPTableViewSelectionDidChangeNotification = @"CPTableViewSelectionDidChangeNotification"; +CPTableViewSelectionIsChangingNotification = @"CPTableViewSelectionIsChangingNotification"; -CPTableViewColumnDidMoveNotification = "CPTableViewColumnDidMoveNotification"; -CPTableViewColumnDidResizeNotification = "CPTableViewColumnDidResizeNotification"; -CPTableViewSelectionDidChangeNotification = "CPTableViewSelectionDidChangeNotification"; -CPTableViewSelectionIsChangingNotification = "CPTableViewSelectionIsChangingNotification"; +#include "CoreGraphics/CGGeometry.h" -var _CPTableViewWillDisplayCellSelector = 1 << 0, - _CPTableViewShouldSelectRowSelector = 1 << 1, - _CPTableViewShouldSelectTableColumnSelector = 1 << 2, - _CPTableViewSelectionShouldChangeSelector = 1 << 3, - _CPTableViewShouldEditTableColumnSelector = 1 << 4, - _CPTableViewSelectionIndexesForProposedSelectionSelector = 1 << 5, - _CPTableViewHeightOfRowSelector = 1 << 6; - -/* - @ingroup appkit - - This class is not yet stable. - - CPTableView is located within the AppKit framework and is used to display tables. - It uses a delegate model for getting its data i.e. you give it an object that provides - it with the data it should display. - - @ignore -*/ -@implementation CPTableView : CPControl +var CPTableViewDataSource_tableView_setObjectValue_forTableColumn_row_ = 1 << 2, + + CPTableViewDataSource_tableView_acceptDrop_row_dropOperation_ = 1 << 3, + CPTableViewDataSource_tableView_namesOfPromisedFilesDroppedAtDestination_forDraggedRowsWithIndexes_ = 1 << 4, + CPTableViewDataSource_tableView_validateDrop_proposedRow_proposedDropOperation_ = 1 << 5, + CPTableViewDataSource_tableView_writeRowsWithIndexes_toPasteboard_ = 1 << 6, + + CPTableViewDataSource_tableView_sortDescriptorsDidChange_ = 1 << 7; + +var CPTableViewDelegate_selectionShouldChangeInTableView_ = 1 << 0, + CPTableViewDelegate_tableView_dataViewForTableColumn_row_ = 1 << 1, + CPTableViewDelegate_tableView_didClickTableColumn_ = 1 << 2, + CPTableViewDelegate_tableView_didDragTableColumn_ = 1 << 3, + CPTableViewDelegate_tableView_heightOfRow_ = 1 << 4, + CPTableViewDelegate_tableView_isGroupRow_ = 1 << 5, + CPTableViewDelegate_tableView_mouseDownInHeaderOfTableColumn_ = 1 << 6, + CPTableViewDelegate_tableView_nextTypeSelectMatchFromRow_toRow_forString_ = 1 << 7, + CPTableViewDelegate_tableView_selectionIndexesForProposedSelection_ = 1 << 8, + CPTableViewDelegate_tableView_shouldEditTableColumn_row_ = 1 << 9, + CPTableViewDelegate_tableView_shouldSelectRow_ = 1 << 10, + CPTableViewDelegate_tableView_shouldSelectTableColumn_ = 1 << 11, + CPTableViewDelegate_tableView_shouldShowViewExpansionForTableColumn_row_ = 1 << 12, + CPTableViewDelegate_tableView_shouldTrackView_forTableColumn_row_ = 1 << 13, + CPTableViewDelegate_tableView_shouldTypeSelectForEvent_withCurrentSearchString_ = 1 << 14, + CPTableViewDelegate_tableView_toolTipForView_rect_tableColumn_row_mouseLocation_ = 1 << 15, + CPTableViewDelegate_tableView_typeSelectStringForTableColumn_row_ = 1 << 16, + CPTableViewDelegate_tableView_willDisplayView_forTableColumn_row_ = 1 << 17, + CPTableViewDelegate_tableViewSelectionDidChange_ = 1 << 18, + CPTableViewDelegate_tableViewSelectionIsChanging_ = 1 << 19; + +// TODO: add docs + +CPTableViewSelectionHighlightStyleRegular = 0; +CPTableViewSelectionHighlightStyleSourceList = 1; + +CPTableViewGridNone = 0; +CPTableViewSolidVerticalGridLineMask = 1 << 0; +CPTableViewSolidHorizontalGridLineMask = 1 << 1; + + +#define NUMBER_OF_COLUMNS() (_tableColumns.length) +//#define ENSURE_COLUMN_WIDTHS() + +@implementation _CPTableDrawView : CPView { - // Archived: - - id _dataSource; - id _delegate; - - //CPTableHeaderView _headerView; - //CPView _cornerView; - - CPArray _tableColumns; - - CPIndexSet _selectedRowIndexes; - //CPArray _selectedColumns; - - float _rowHeight; - CGSize _intercellSpacing; - - BOOL _allowsMultipleSelection; - BOOL _allowsEmptySelection; - //BOOL _allowsColumnReordering; - //BOOL _allowsColumnResizing; - //BOOL _allowsColumnSelection; - //BOOL _autoresizesAllColumnsToFit; - - //CPColor _gridColor; - //BOOL _drawsGrid; - - SEL _doubleAction; - - // Not archived: - - int _delegateSelectorsCache; - - //CPScrollView _scrollView; - - unsigned _numberOfRows; - //unsigned _numberOfColumns; - - BOOL _hasVariableHeightRows; - - // Heights - float _columnHeight; // calculated - - CPArray _rowHeights; - CPArray _rowMinYs; - - CPArray _tableCells; - CPArray _tableColumnViews; - - // Caching - Object _dataViewCache; - CPArray _objectValueCache; - - CPRange _visibleRows; - CPRange _visibleColumns; - - CPRange _populatedRows; - CPRange _populatedColumns; - - // Selection - CPIndexSet _previousSelectedRowIndexes; - int _selectionStartRow; - int _selectionModifier; - - CPIndexSet _currentlySelected; - CPArray _selectionViews; - CPArray _selectionViewsPool; - - CPDate _scrollTimer; + CPTableView _tableView; } -+ (void)initialize +- (id)initWithTableView:(CPTableView)aTableView { - + self = [super init]; + + if (self) + _tableView = aTableView; + + return self; +} + +- (void)drawRect:(CGRect)aRect +{ + var frame = [self frame], + context = [[CPGraphicsContext currentContext] graphicsPort]; + + CGContextTranslateCTM(context, -_CGRectGetMinX(frame), -_CGRectGetMinY(frame)); + + [_tableView _drawRect:aRect]; +} + +@end + +@implementation CPTableView : CPControl +{ + id _dataSource; + CPInteger _implementedDataSourceMethods; + + id _delegate; + CPInteger _implementedDelegateMethods; + + CPArray _tableColumns; + CPArray _tableColumnRanges; + CPInteger _dirtyTableColumnRangeIndex; + CPInteger _numberOfHiddenColumns; + + Object _objectValues; + CPRange _exposedRows; + CPIndexSet _exposedColumns; + + Object _dataViewsForTableColumns; + Object _cachedDataViews; + + //Configuring Behavior + BOOL _allowsColumnReordering; + BOOL _allowsColumnResizing; + BOOL _allowsMultipleSelection; + BOOL _allowsEmptySelection; + + //Setting Display Attributes + CGSize _intercellSpacing; + float _rowHeight; + + BOOL _usesAlternatingRowBackgroundColors; + CPArray _alternatingRowBackgroundColors; + + unsigned _selectionHighlightMask; + unsigned _currentHighlightedTableColumn; + unsigned _gridStyleMask; + CPColor _gridColor; + + unsigned _numberOfRows; + + + CPTableHeaderView _headerView; + _CPCornerView _cornerView; + + CPIndexSet _selectedColumnIndexes; + CPIndexSet _selectedRowIndexes; + CPInteger _selectionAnchorRow; + + _CPTableDrawView _tableDrawView; } - (id)initWithFrame:(CGRect)aFrame { self = [super initWithFrame:aFrame]; - + if (self) { - [self _init]; + //Configuring Behavior + _allowsColumnReordering = YES; + _allowsColumnResizing = YES; + _allowsMultipleSelection = NO; + _allowsEmptySelection = YES; + _allowsColumnSelection = NO; + + _tableViewFlags = 0; + + //Setting Display Attributes + _selectionHighlightMask = CPTableViewSelectionHighlightStyleRegular; + + [self setUsesAlternatingRowBackgroundColors:NO]; + [self setAlternatingRowBackgroundColors:[[CPColor whiteColor], [CPColor colorWithHexString:@"e4e7ff"]]]; + + _tableColumns = []; + _tableColumnRanges = []; + _dirtyTableColumnRangeIndex = CPNotFound; + _numberOfHiddenColumns = 0; + + _objectValues = { }; + _dataViewsForTableColumns = { }; + _dataViews= []; + _numberOfRows = 0; + _exposedRows = [CPIndexSet indexSet]; + _exposedColumns = [CPIndexSet indexSet]; + _cachedDataViews = { }; + _intercellSpacing = _CGSizeMake(0.0, 0.0); + _rowHeight = 19.0; + + [self setGridColor:[CPColor grayColor]]; + [self setGridStyleMask:CPTableViewGridNone]; + + _headerView = [[CPTableHeaderView alloc] initWithFrame:CGRectMake(0, 0, [self bounds].size.width, _rowHeight)]; + + [_headerView setTableView:self]; + + _cornerView = [[_CPCornerView alloc] initWithFrame:CGRectMake(0, 0, [CPScroller scrollerWidth], CGRectGetHeight([_headerView frame]))]; + + _selectedColumnIndexes = [CPIndexSet indexSet]; + _selectedRowIndexes = [CPIndexSet indexSet]; + + _tableDrawView = [[_CPTableDrawView alloc] initWithTableView:self]; + [_tableDrawView setBackgroundColor:[CPColor clearColor]]; + [self addSubview:_tableDrawView]; + } - + return self; } -- (void)_init -{ - _tableColumns = []; - //_numberOfColumns = 0; - - _selectedRowIndexes = [CPIndexSet indexSet]; - - _rowHeight = 17.0; - _intercellSpacing = CPSizeMake(3.0, 2.0); - - _allowsMultipleSelection = YES; - _allowsEmptySelection = YES; - - - _tableCells = []; - _tableColumnViews = []; - - _dataViewCache = {}; - _objectValueCache = []; - - _visibleRows = CPMakeRange(0, 0); - _visibleColumns = CPMakeRange(0, 0); - - _rowHeights = []; - _rowMinYs = []; -} - -/* - Returns the table's column height -*/ -- (float)_columnHeight -{ - return _columnHeight;//_numberOfRows * (_rowHeight + _intercellSpacing.height); -} - -- (void)newCellForRow:(unsigned)aRowIndex column:(unsigned)aColumnIndex avoidingRows:(CPRange)rows -{ - var dataView = [_tableColumns[aColumnIndex] _newDataViewForRow:aRowIndex avoidingRows:rows]; - - [dataView setFrame:CGRectMake(0.0, ROW_MIN_Y(aRowIndex), [_tableColumns[aColumnIndex] width], ROW_HEIGHT(aRowIndex))]; - - if ([dataView respondsToSelector:@selector(highlight:)]) - [dataView highlight:[_selectedRowIndexes containsIndex:aRowIndex]]; - - if (!_objectValueCache[aColumnIndex]) - _objectValueCache[aColumnIndex] = []; - - // We may be storing 0 after all! - if (_objectValueCache[aColumnIndex][aRowIndex] === undefined) - _objectValueCache[aColumnIndex][aRowIndex] = [_dataSource tableView:self objectValueForTableColumn:_tableColumns[aColumnIndex] row:aRowIndex]; - - [dataView setObjectValue:_objectValueCache[aColumnIndex][aRowIndex]]; - - return dataView; -} - -- (void)clearCells -{ - var columnEnd = CPMaxRange(_visibleColumns), - rowEnd = CPMaxRange(_visibleRows); - - for (var column = _visibleColumns.location; column < columnEnd; column++) - { - var tableColumn = _tableColumns[column], - tableColumnCells = _tableCells[column]; - - for (var row = _visibleRows.location; row < rowEnd; row++) - { - var cell = tableColumnCells[row]; - if (cell) - { - tableColumnCells[row] = nil; - [tableColumn _markView:cell inRow:row asPurgable:YES]; - } - else - { - CPLog.warn("Missing cell? " + row + "," + column); - } - } - } - - _visibleColumns = CPMakeRange(0,0); - _visibleRows = CPMakeRange(0,0); -} - -- (void)loadTableCellsInRect:(CGRect)aRect -{ - if (!_dataSource) - return; - - // Determine new visible rows and columns. - - var rowStart = MAX(0, [self _rowAtY:CGRectGetMinY(aRect)] - 1), - rowEnd = MIN(_numberOfRows, [self _rowAtY:CGRectGetMaxY(aRect)] + 1), - - visibleRows = CPMakeRange(rowStart, rowEnd - rowStart), - - columnStart = MAX(0, [self _columnAtX:CGRectGetMinX(aRect)]), - columnEnd = MIN(_tableColumns.length, [self _columnAtX:CGRectGetMaxX(aRect)] + 1), - - visibleColumns = CPMakeRange(columnStart, columnEnd - columnStart); - - if (CPEqualRanges(_visibleRows, visibleRows) && CPEqualRanges(_visibleColumns, visibleColumns)) - return; - - var unionVisibleRows = CPUnionRange(_visibleRows, visibleRows), - unionVisibleColumns = CPUnionRange(_visibleColumns, visibleColumns); - - - // Determine whether to use 2 sweeps or one. If we have lots of overlap of cells, use just one. - if (unionVisibleRows.length * unionVisibleColumns.length <= - (_visibleRows.length * _visibleColumns.length) + (visibleRows.length * visibleColumns.length)) - { - //CPLog.info("single sweep"); - - var cEnd = CPMaxRange(unionVisibleColumns), - rEnd = CPMaxRange(unionVisibleRows), - cell; - - for (var column = unionVisibleColumns.location; column < cEnd; ++column) - { - var tableColumn = _tableColumns[column], - tableColumnCells = _tableCells[column], - columnIsVisible = CPLocationInRange(column, visibleColumns), - newCells = []; - - for (var row = unionVisibleRows.location; row < rEnd; ++row) - { - if (cell = tableColumnCells[row]) - { - if (!columnIsVisible || !CPLocationInRange(row, visibleRows)) - { - tableColumnCells[row] = nil; - [tableColumn _markView:cell inRow:row asPurgable:YES]; - } - } - else - { - newCells.push(row); - } - } - - while (newCells.length > 0) - { - var row = newCells.pop(); - - tableColumnCells[row] = [self newCellForRow:row column:column avoidingRows:visibleRows]; - - if (!tableColumnCells[row]._superview) - [_tableColumnViews[column] addSubview:tableColumnCells[row]]; - else if (tableColumnCells[row]._isHidden) - [tableColumnCells[row] setHidden:NO]; - } - - [tableColumn _purge]; - } - } - else { - //CPLog.info("double sweep"); - - // first sweep: remove old cells - - var cEnd = CPMaxRange(_visibleColumns), - rEnd = CPMaxRange(_visibleRows), - cell; - - for (var column = _visibleColumns.location; column < cEnd; ++column) - { - var tableColumn = _tableColumns[column], - tableColumnCells = _tableCells[column], - columnIsVisible = CPLocationInRange(column, visibleColumns); - - for (var row = _visibleRows.location; row < rEnd; ++row) - { - if (cell = tableColumnCells[row]) - { - if (!columnIsVisible || !CPLocationInRange(row, visibleRows)) - { - tableColumnCells[row] = nil; - [tableColumn _markView:cell inRow:row asPurgable:YES]; - } - } - } - } - - // second sweep: add new cells - - var cEnd = CPMaxRange(visibleColumns), - rEnd = CPMaxRange(visibleRows); - - for (var column = visibleColumns.location; column < cEnd; ++column) - { - var tableColumn = _tableColumns[column], - tableColumnCells = _tableCells[column]; - - for (var row = visibleRows.location; row < rEnd; ++row) - { - tableColumnCells[row] = [self newCellForRow:row column:column avoidingRows:visibleRows]; - - if (!tableColumnCells[row]._superview) - [_tableColumnViews[column] addSubview:tableColumnCells[row]]; - else if (tableColumnCells[row]._isHidden) - [tableColumnCells[row] setHidden:NO]; - } - - [tableColumn _purge]; - } - } - - - _visibleRows = visibleRows; - _visibleColumns = visibleColumns; - -} - -// Setting display attributes -/* - Sets the width and height between cell. The default is (3.0, 2.0) (width, height). - @param the width and height spacing -*/ -- (void)setIntercellSpacing:(CGSize)aSize -{ - if (_intercellSpacing.width != aSize.width) - { - var i = 1, - delta = aSize.width - _intercellSpacing.width; - total = delta; - - for (; i < _tableColumns.length; ++i, total += delta) - { - var origin = [_tableColumnViews[i] frame].origin; - [_tableColumnViews[i] setFrameOrigin:CGPointMake(origin.x + total, origin.y)]; - } - } - - if (_intercellSpacing.height != aSize.height) - { - var i = 0; - - for (; i < _tableColumns.length; ++i, total += delta) - { - [_tableColumnViews[i] setFrameSize:CGSizeMake([_tableColumnViews[i] width], _numberOfRows * (_rowHeight + _intercellSpacing.height))]; - - var j = 1, - y = _rowHeight + _intercellSpacing.height; - - for (; j < _numberOfRows; ++i, y += _rowHeight + _intercellSpacing.height) - { - if (!_tableCells[i][j]) - continue; - - [_tableCells[i][j] setFrameOrigin:CPPointMake(0.0, y)]; - } - } - - // FIXME: variable height rows - } - - _intercellSpacing = CPSizeCreateCopy(aSize); -} - -/* - Returns the width and height of the space between - cells. -*/ -- (CGSize)intercellSpacing -{ - return _intercellSpacing; -} - -/* - Sets the height of table rows - @param aRowHeight the new height of the table rows -*/ -- (void)setRowHeight:(unsigned)aRowHeight -{ - if (_rowHeight == aRowHeight) - return; - - _rowHeight = aRowHeight; - - // don't perform adjustments if we're using variable height rows - if (_hasVariableHeightRows) - return; - - for (var row = 0; row < _numberOfRows; ++row) - for (var column = 0; column < _tableColumns.length; ++column) - [_tableCells[column][row] setFrameOrigin:CPPointMake(0.0, row * (_rowHeight + _intercellSpacing.height))]; -} - -/* - Returns the height of a table row -*/ -- (unsigned)rowHeight -{ - return _rowHeight; -} - -/* - Adds a column to the table - @param aTableColumn the column to be added -*/ -- (void)addTableColumn:(CPTableColumn)aTableColumn -{ - var i = 0, - x = _tableColumns.length ? CPRectGetMaxX([self rectOfColumn:_tableColumns.length - 1]) + _intercellSpacing.width : 0.0, - tableColumnView = [[CPView alloc] initWithFrame:CPRectMake(x, 0.0, [aTableColumn width], [self _columnHeight])], - tableColumnCells = []; - - [_tableColumns addObject:aTableColumn]; - [_tableColumnViews addObject:tableColumnView]; - -// [tableColumnView setBackgroundColor:[CPColor greenColor]]; - - [self addSubview:tableColumnView]; - - [_tableCells addObject:tableColumnCells]; - - // TODO: do we really need to initialize this, or is undefined good enough? - for (; i < _numberOfRows; ++i) - _tableCells[_tableColumns.length-1][i] = nil; - - //++_numberOfColumns; -} - -/* - Removes a column from the table - @param aTableColumn the column to remove -*/ -- (void)removeTableColumn:(CPTableColumn)aTableColumn -{ - var frame = [self frame], - width = [aTableColumn width] + _intercellSpacing.width, - index = [_tableColumns indexOfObjectIdenticalTo:aTableColumn]; - - // Remove the column view and all the cell views from the view hierarchy. - [_tableColumnViews[i] removeFromSuperview]; - - [_tableCells removeObjectAtIndex:index]; - [_tableColumns removeObjectAtIndex:index]; - [_tableColumnViews removeObjectAtIndex:index]; - - // Shift remaining column views to the left. - for (; index < _tableColumns.length; ++ index) - [_tableColumnViews[index] setFrameOrigin:CPPointMake(CPRectGetMinX([_tableColumnViews[index] frame]) - width, 0.0)] - - // Resize ourself. - [self setFrameSize:CPSizeMake(CPRectGetWidth(frame) - width, CPRectGetHeight(frame))]; -} - -/* - Not yet implemented. Changes the position of the column in - the table. - @param fromIndex the original index of the column - @param toIndex the desired index of the column -*/ -- (void)moveColumn:(unsigned)fromIndex toColumn:(unsinged)toIndex -{ - if (fromIndex == toIndex) - return; -// FIXME: IMPLEMENT -} - -/* - Returns an array containing the table's CPTableColumns. -*/ -- (CPArray)tableColumns -{ - return _tableColumns; -} - -/* - Returns the first CPTableColumn equal to the given object (as determined by the "isEqual:" selector), or nil if none exists. - @param anObject the object to look for -*/ -- (CPTableColumn)tableColumnWithIdentifier:(id)anObject -{ - for (var i = 0; i < _tableColumns.length; i++) - if ([_tableColumns[i] isEqual:anObject]) - return _tableColumns[i]; - return nil; -} - -// Getting the dimensions of the table -/* - Returns the number of columns in the table -*/ -- (int)numberOfColumns -{ - return _tableColumns.length; -} - -/* - Returns the number of rows in the table -*/ -- (int)numberOfRows -{ - return _numberOfRows; -} - -/* - Adjusts the size of the table and it's header view. -*/ -- (void)tile -{ - var HEIGHT = 10.0; - -// [_headerView setFrame:CPRectMake(0.0, 0.0, CPRectGetWidth([self bounds]), HEIGHT)]; -// [_scrollView setFrame:CPRectMake(0.0, HEIGHT, CPRectGetWidth([self bounds]), CPRectGetHeight([self bounds]) - HEIGHT)]; -} - -/* - Sets the object that is used to obtain the table data. The data source must implement the following - methods: -
-- (int)numberOfRowsInTableView:(CPTableView)aTableView
-- (id)tableView:(CPTableView)aTableView objectValueForTableColumn:(CPTableColumn)aTableColumn row:(int)rowIndex
-
- @param aDataSource the object with the table data - @throws CPInternalInconsistencyException if \c aDataSource doesn't implement all the required methods -*/ - (void)setDataSource:(id)aDataSource { - if (![aDataSource respondsToSelector:@selector(numberOfRowsInTableView:)]) - [CPException raise:CPInternalInconsistencyException reason:"Data source doesn't support 'numberOfRowsInTableView:'"]; - if (![aDataSource respondsToSelector:@selector(tableView:objectValueForTableColumn:row:)]) - [CPException raise:CPInternalInconsistencyException reason:"Data source doesn't support 'tableView:objectValueForTableColumn:row:'"]; + if (_dataSource === aDataSource) + return; _dataSource = aDataSource; - + _implementedDataSourceMethods = 0; + + if (!_dataSource) + return; + + if (![_dataSource respondsToSelector:@selector(numberOfRowsInTableView:)]) + [CPException raise:CPInternalInconsistencyException + reason:[aDataSource description] + " does not implement numberOfRowsInTableView:."]; + + if (![_dataSource respondsToSelector:@selector(tableView:objectValueForTableColumn:row:)]) + [CPException raise:CPInternalInconsistencyException + reason:[aDataSource description] + " does not implement tableView:objectValueForTableColumn:row:"]; + + if ([_dataSource respondsToSelector:@selector(tableView:setObjectValue:forTableColumn:row:)]) + _implementedDataSourceMethods |= CPTableViewDataSource_tableView_setObjectValue_forTableColumn_row_; + + if ([_dataSource respondsToSelector:@selector(tableView:setObjectValue:forTableColumn:row:)]) + _implementedDataSourceMethods |= CPTableViewDataSource_tableView_acceptDrop_row_dropOperation_; + + if ([_dataSource respondsToSelector:@selector(tableView:namesOfPromisedFilesDroppedAtDestination:forDraggedRowsWithIndexes:)]) + _implementedDataSourceMethods |= CPTableViewDataSource_tableView_namesOfPromisedFilesDroppedAtDestination_forDraggedRowsWithIndexes_; + + if ([_dataSource respondsToSelector:@selector(tableView:validateDrop:proposedRow:proposedDropOperation:)]) + _implementedDataSourceMethods |= CPTableViewDataSource_tableView_validateDrop_proposedRow_proposedDropOperation_; + + if ([_dataSource respondsToSelector:@selector(tableView:writeRowsWithIndexes:toPasteboard:)]) + _implementedDataSourceMethods |= CPTableViewDataSource_tableView_writeRowsWithIndexes_toPasteboard_; + [self reloadData]; } -/* - Returns the object that has access to the table data -*/ - (id)dataSource { return _dataSource; } +//Loading Data + +- (void)reloadData +{ + if (!_dataSource) + return; + + _objectValues = { }; + + [self noteNumberOfRowsChanged]; + [self _sizeToParent]; + + [self setNeedsLayout]; + [self setNeedsDisplay:YES]; +} + +//Target-action Behavior + +- (void)setDoubleAction:(SEL)anAction +{ + _doubleAction = anAction; +} + +- (SEL)doubleAction +{ + return _doubleAction; +} + +/* + * - clickedColumn + * - clickedRow +*/ +//Configuring Behavior + +- (void)setAllowsColumnReordering:(BOOL)shouldAllowColumnReordering +{ + _allowsColumnReordering = !!shouldAllowColumnReordering; +} + +- (BOOL)allowsColumnReordering +{ + return _allowsColumnReordering; +} + +- (void)setAllowsColumnResizing:(BOOL)shouldAllowColumnResizing +{ + _allowsColumnResizing = !!shouldAllowColumnResizing; +} + +- (BOOL)allowsColumnResizing +{ + return _allowsColumnResizing; +} + +- (void)setAllowsMultipleSelection:(BOOL)shouldAllowMultipleSelection +{ + _allowsMultipleSelection = !!shouldAllowMultipleSelection; +} + +- (BOOL)allowsMultipleSelection +{ + return _allowsMultipleSelection; +} + +- (void)setAllowsEmptySelection:(BOOL)shouldAllowEmptySelection +{ + _allowsEmptySelection = !!shouldAllowEmptySelection; +} + +- (BOOL)allowsEmptySelection +{ + return _allowsEmptySelection; +} + +- (void)setAllowsColumnSelection:(BOOL)shouldAllowColumnSelection +{ + _allowsColumnSelection = !!shouldAllowColumnSelection; +} + +- (BOOL)allowsColumnSelection +{ + return _allowsColumnSelection; +} + +//Setting Display Attributes + +- (void)setIntercellSpacing:(CGSize)aSize +{ + if (_CGSizeEqualToSize(_intercellSpacing, aSize)) + return; + + _intercellSpacing = _CGSizeMakeCopy(aSize); + + [self setNeedsLayout]; +} + +- (void)setThemeState:(int)astae +{ +} + +- (CGSize)intercellSpacing +{ + return _CGSizeMakeCopy(_intercellSpacing); +} + +- (void)setRowHeight:(unsigned)aRowHeight +{ + aRowHeight = +aRowHeight; + + if (_rowHeight === aRowHeight) + return; + + _rowHeight = MAX(0.0, aRowHeight); + + [self setNeedsLayout]; +} + +- (unsigned)rowHeight +{ + return _rowHeight; +} + +- (void)setUsesAlternatingRowBackgroundColors:(BOOL)shouldUseAlternatingRowBackgroundColors +{ + // TODO:need to look at how one actually sets the alternating row, a tip at: + // http://forums.macnn.com/79/developer-center/228347/nstableview-alternating-row-colors/ + // otherwise this may not be feasible or may introduce an additional change req'd in CP + // we'd probably need to iterate through rowId % 2 == 0 and setBackgroundColor with + // whatever the alternating row color is. + _usesAlternatingRowBackgroundColors = shouldUseAlternatingRowBackgroundColors; +} + +- (BOOL)usesAlternatingRowBackgroundColors +{ + return _usesAlternatingRowBackgroundColors; +} + +- (void)setAlternatingRowBackgroundColors:(CPArray)alternatingRowBackgroundColors +{ + if ([_alternatingRowBackgroundColors isEqual:alternatingRowBackgroundColors]) + return; + + _alternatingRowBackgroundColors = alternatingRowBackgroundColors; + + [self setNeedsDisplay:YES]; +} + +- (CPArray)alternatingRowBackgroundColors +{ + return _alternatingRowBackgroundColors; +} + +- (unsigned)selectionHighlightStyle +{ + return _selectionHighlightMask; +} + +- (void)setSelectionHighlightStyle:(unsigned)aSelectionHighlightStyle +{ + _selectionHighlightMask = aSelectionHighlightStyle; +} + +/* + * - indicatorImageInTableColumn: + * - setIndicatorImage:inTableColumn: +*/ + +- (void)setGridColor:(CPColor)aColor +{ + if (_gridColor === aColor) + return; + + _gridColor = aColor; + + [self setNeedsDisplay:YES]; +} + +- (CPColor)gridColor +{ + return _gridColor; +} + +- (void)setGridStyleMask:(unsigned)aGrideStyleMask +{ + if (_gridStyleMask === aGrideStyleMask) + return; + + _gridStyleMask = aGrideStyleMask + + [self setNeedsDisplay:YES]; +} + +- (unsigned)gridStyleMask +{ + return _gridStyleMask; +} + +//Column Management + +- (void)addTableColumn:(CPTableColumn)aTableColumn +{ + [_tableColumns addObject:aTableColumn]; + [aTableColumn setTableView:self]; + + if (_dirtyTableColumnRangeIndex < 0) + _dirtyTableColumnRangeIndex = NUMBER_OF_COLUMNS() - 1; + else + _dirtyTableColumnRangeIndex = MIN(NUMBER_OF_COLUMNS() - 1, _dirtyTableColumnRangeIndex); + + [self setNeedsLayout]; +} + +- (void)removeTableColumn:(CPTableColumn)aTableColumn +{ + if ([aTableColumn tableView] !== self) + return; + + var index = [_tableColumns indeOfObjectIdenticalTo:aTableColumn]; + + if (index === CPNotFound) + return; + + [aTableColumn setTableView:nil]; + [_tableColumns removeObjectAtIndex:index]; + + var tableColumnUID = [aTableColumn UID]; + + if (_objectValues[tableColumnUID]) + _objectValues[tableColumnUID] = nil; + + if (_dirtyTableColumnRangeIndex < 0) + _dirtyTableColumnRangeIndex = index; + else + _dirtyTableColumnRangeIndex = MIN(index, _dirtyTableColumnRangeIndex); + + [self setNeedsLayout]; +} + +- (void)moveColumn:(unsigned)fromIndex toColumn:(unsigned)toIndex +{ + fromIndex = +fromIndex; + toIndex = +toIndex; + + if (fromIndex === toIndex) + return; + + if (_dirtyTableColumnRangeIndex < 0) + _dirtyTableColumnRangeIndex = MIN(fromIndex, toIndex); + else + _dirtyTableColumnRangeIndex = MIN(fromIndex, toIndex, _dirtyTableColumnRangeIndex); + + if (toIndex > fromIndex) + --toIndex; + + var tableColumn = _tableColumns[fromIndex]; + + [_tableColumns removeObjectAtIndex:fromIndex]; + [_tableColumns insertObject:tableColumn atIndex:toIndex]; + + [self setNeedsLayout]; +} + +- (CPArray)tableColumns +{ + return _tableColumns; +} + +- (CPInteger)columnWithIdentifier:(CPString)anIdentifier +{ + var index = 0, + count = NUMBER_OF_COLUMNS(); + + for (; index < count; ++index) + if ([_tableColumns identifier] === anIdentifier) + return index; + + return CPNotFound; +} + +- (CPTableColumn)tableColumnWithIdentifier:(CPString)anIdentifier +{ + var index = [self columnWithIdentifier:anIdentifier]; + + if (index === CPNotFound) + return nil; + + return _tableColumns[index]; +} + +//Selecting Columns and Rows +- (void)selectColumnIndexes:(CPIndexSet)columns byExtendingSelection:(BOOL)shouldExtendSelection +{ + // We deselect all columns when selecting rows. + _selectedRowIndexes = [CPIndexSet indexSet]; + + if (shouldExtendSelection) + [_selectedColumnIndexes addIndexes:columns]; + else + _selectedColumnIndexes = [columns copy]; + + [self setNeedsLayout]; +} + +- (void)selectRowIndexes:(CPIndexSet)rows byExtendingSelection:(BOOL)shouldExtendSelection +{ + // We deselect all rows when selecting columns. + _selectedColumnIndexes = [CPIndexSet indexSet]; + + if (shouldExtendSelection) + [_selectedRowIndexes addIndexes:rows]; + else + _selectedRowIndexes = [rows copy]; + + [self setNeedsLayout]; +} + +- (CPIndexSet)selectedColumnIndexes +{ + return _selectedColumnIndexes; +} + +- (void)selectedRowIndexes +{ + return _selectedRowIndexes; +} + +- (void)deselectColumn:(CPInteger)aColumn +{ + [_selectedColumnIndexes removeIndex:aColumn]; +} + +- (void)deselectRow:(CPInteger)aRow +{ + [_selectedRowIndexes removeIndex:aRow]; +} + +- (CPInteger)numberOfSelectedColumns +{ + return [_selectedColumnIndexes count]; +} + +- (CPInteger)numberOfSelectedRows +{ + return [_selectedRowIndexes count]; +} + +/* +- (CPInteger)selectedColumn + * - selectedRow +*/ + +- (BOOL)isColumnSelected:(CPInteger)aColumn +{ + return [_selectedColumnIndexes containsIndex:aColumn]; +} + +- (BOOL)isRowSelected:(CPInteger)aRow +{ + return [_selectedRowIndexes containsIndex:aRow]; +} +/* +- (void)selectAll: + * - deselectAll: + * - allowsTypeSelect + * - setAllowsTypeSelect: +*/ +//Table Dimensions + +- (int)numberOfColumns +{ + return NUMBER_OF_COLUMNS(); +} + +/* + Returns the number of rows in the receiver. +*/ +- (int)numberOfRows +{ + if (!_dataSource) + return 0; + + return [_dataSource numberOfRowsInTableView:self]; +} + +//Displaying Cell +/* + * - preparedCellAtColumn:row: +*/ +//Editing Cells +/* + * - editColumn:row:withEvent:select: + * - editedColumn + * - editedRow +*/ +//Setting Auxiliary Views +/* + * - setHeaderView: + * - headerView + * - setCornerView: + * - cornerView +*/ + +- (CPView)cornerView +{ + return _cornerView; +} + +- (void)setCornerView:(CPView)aView +{ + _cornerView = aView; +} + +- (CPView)headerView +{ + return _headerView; +} + +- (void)setHeaderView:(CPView)aHeaderView +{ + _headerView = aHeaderView; + [_headerView setTableView:self]; +} + +//Layout Support + +// Complexity: +// O(Columns) +- (void)_recalculateTableColumnRanges +{ + if (_dirtyTableColumnRangeIndex < 0) + return; + + var index = _dirtyTableColumnRangeIndex, + count = NUMBER_OF_COLUMNS(), + x = index === 0 ? 0.0 : CPMaxRange(_tableColumnRanges[index - 1]); + + for (; index < count; ++index) + { + var tableColumn = _tableColumns[index]; + + if ([tableColumn isHidden]) + _tableColumnRanges[index] = CPMakeRange(x, 0.0); + + else + { + var width = [_tableColumns[index] width]; + + _tableColumnRanges[index] = CPMakeRange(x, width); + + x += width; + } + } + + _tableColumnRanges.length = count; + _dirtyTableColumnRangeIndex = CPNotFound; +} + +// Complexity: +// O(1) +- (CGRect)rectOfColumn:(CPInteger)aColumnIndex +{ + aColumnIndex = +aColumnIndex; + + if (aColumnIndex < 0 || aColumnIndex >= NUMBER_OF_COLUMNS()) + return _CGRectMakeZero(); + + if (_dirtyTableColumnRangeIndex !== CPNotFound) + [self _recalculateTableColumnRanges]; + + var range = _tableColumnRanges[aColumnIndex]; + + return _CGRectMake(range.location, 0.0, range.length, CGRectGetHeight([self bounds])); +} + +- (CGRect)rectOfRow:(CPInteger)aRowIndex +{ + if (NO) + return NULL; + + // FIXME: WRONG: ASK TABLE COLUMN RANGE + return _CGRectMake(0.0, (aRowIndex * (_rowHeight + _intercellSpacing.height)), _CGRectGetWidth([self bounds]), _rowHeight); +} + +// Complexity: +// O(1) +- (CPRange)rowsInRect:(CGRect)aRect +{ + var bounds = nil, + firstRow = [self rowAtPoint:aRect.origin], + lastRow = [self rowAtPoint:_CGPointMake(0.0, _CGRectGetMaxY(aRect))]; + + if (firstRow < 0) + { + bounds = [self bounds]; + + if (_CGRectGetMinY(aRect) < _CGRectGetMinY(bounds)) + firstRow = 0; + else + firstRow = _numberOfRows - 1; + } + + if (lastRow < 0) + { + if (!bounds) + bounds = [self bounds]; + + if (_CGRectGetMaxY(aRect) < _CGRectGetMinY(bounds)) + lastRow = 0; + else + lastRow = _numberOfRows - 1; + } + + return CPMakeRange(firstRow, lastRow - firstRow + 1); +} + +// Complexity: +// O(lg Columns) if table view contains no hidden columns +// O(Columns) if table view contains hidden columns +- (CPIndexSet)columnIndexesInRect:(CGRect)aRect +{ + var column = MAX(0, [self columnAtPoint:_CGPointMake(aRect.origin.x, 0.0)]), + lastColumn = [self columnAtPoint:_CGPointMake(_CGRectGetMaxX(aRect), 0.0)]; + + if (lastColumn === CPNotFound) + lastColumn = NUMBER_OF_COLUMNS() - 1; + + // Don't bother doing the expensive removal of hidden indexes if we have no hidden columns. + if (_numberOfHiddenColumns <= 0) + return [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(column, lastColumn - column + 1)]; + + // + var indexSet = [CPIndexSet indexSet]; + + for (; column <= lastColumn; ++column) + { + var tableColumn = _tableColumns[column]; + + if (![tableColumn isHidden]) + [indexSet addIndex:column]; + } + + return indexSet; +} + +// Complexity: +// O(lg Columns) if table view contains now hidden columns +// O(Columns) if table view contains hidden columns +- (CPInteger)columnAtPoint:(CGPoint)aPoint +{ + var bounds = [self bounds]; + + if (!_CGRectContainsPoint(bounds, aPoint)) + return CPNotFound; + + if (_dirtyTableColumnRangeIndex !== CPNotFound) + [self _recalculateTableColumnRanges]; + + var x = aPoint.x, + low = 0, + high = _tableColumnRanges.length - 1; + + while (low <= high) + { + var middle = FLOOR(low + (high - low) / 2), + range = _tableColumnRanges[middle]; + + if (x < range.location) + high = middle - 1; + + else if (x >= CPMaxRange(range)) + low = middle + 1; + + else + { + var numberOfColumns = _tableColumnRanges.length; + + while (middle < numberOfColumns && [_tableColumns[middle] isHidden]) + ++middle; + + if (middle < numberOfColumns) + return middle; + + return CPNotFound; + } + } + + return CPNotFound; +} + +- (CPInteger)rowAtPoint:(CGPoint)aPoint +{ + var y = aPoint.y; + + if (NO) + { + } + + var row = FLOOR(y / (_rowHeight + _intercellSpacing.height)); + + if (row >= _numberOfRows) + return -1; + + return row; +} + +- (CGRect)frameOfDataViewAtColumn:(CPInteger)aColumnIndex row:(CPInteger)aRowIndex +{ + var tableColumnRange = _tableColumns[aColumnIndex], + rectOfRow = [self rectOfRow:aRowIndex]; + + return _CGRectMake(tableColumnRange.location, _CGRectGetMinY(rectOfRow), tableColumnRange.length, _CGRectGetHeight(rectOfRow)); +} +/* + * - columnAutoresizingStyle + * - setColumnAutoresizingStyle: +*/ +- (void)sizeLastColumnToFit +{ + var superview = [self superview]; + + if (!superview) + return; + + var superviewSize = [superview bounds].size; + + if (_dirtyTableColumnRangeIndex !== CPNotFound) + [self _recalculateTableColumnRanges]; + + var count = NUMBER_OF_COLUMNS(); + + while (count-- && [_tableColumns[count] isHidden]) ; + + if (count >= 0) + [_tableColumns[count] setWidth:MAX(0.0, superviewSize.width - _CGRectGetMinX([self rectOfColumn:count]))]; + + [self setNeedsLayout]; +} + +- (void)noteNumberOfRowsChanged +{ + _numberOfRows = [_dataSource numberOfRowsInTableView:self]; + + [self setNeedsLayout]; +} +/* + * - tile + * - sizeToFit + * - noteHeightOfRowsWithIndexesChanged: +*/ +//Scrolling +/* + * - scrollRowToVisible: + * - scrollColumnToVisible: +*/ +//Persistence +/* + * - autosaveName + * - autosaveTableColumns + * - setAutosaveName: + * - setAutosaveTableColumns: +*/ + +- (void)_sizeToParent +{ + var superviewSize = [[self superview] bounds].size; + + if (_dirtyTableColumnRangeIndex !== CPNotFound) + [self _recalculateTableColumnRanges]; + + if (_tableColumnRanges.length > 0) + var naturalWidth = CPMaxRange([_tableColumnRanges lastObject]); + + else + var naturalWidth = 0.0; + + [self setFrameSize:_CGSizeMake( MAX(superviewSize.width, naturalWidth), + MAX(superviewSize.height, (_rowHeight + _intercellSpacing.height) * _numberOfRows))]; +} + +//Setting the Delegate:(id)aDelegate + +- (void)setDelegate:(id)aDelegate +{ + if (_delegate === aDelegate) + return; + + var defaultCenter = [CPNotificationCenter defaultCenter]; + + if (_delegate) + { + if ([_delegate respondsToSelector:@selector(tableViewColumnDidMove:)]) + [defaultCenter + removeObserver:_delegate + name:CPTableViewColumnDidMoveNotification + object:self]; + + if ([_delegate respondsToSelector:@selector(tableViewColumnDidResize:)]) + [defaultCenter + removeObserver:_delegate + name:CPTableViewColumnDidResizeNotification + object:self]; + + if ([_delegate respondsToSelector:@selector(tableViewSelectionDidChange:)]) + [defaultCenter + removeObserver:_delegate + name:CPTableViewSelectionDidChangeNotification + object:self]; + + if ([_delegate respondsToSelector:@selector(tableViewSelectionIsChanging:)]) + [defaultCenter + removeObserver:_delegate + name:CPTableViewSelectionIsChangingNotification + object:self]; + } + + _delegate = aDelegate; + _implementedDelegateMethods = 0; + + if ([_delegate respondsToSelector:@selector(selectionShouldChangeInTableView:)]) + _implementedDelegateMethods |= CPTableViewDelegate_selectionShouldChangeInTableView_; + + if ([_delegate respondsToSelector:@selector(tableView:dataViewForTableColumn:row:)]) + _implementedDelegateMethods |= CPTableViewDelegate_tableView_dataViewForTableColumn_row_; + + if ([_delegate respondsToSelector:@selector(tableView:didClickTableColumn:)]) + _implementedDelegateMethods |= CPTableViewDelegate_tableView_didClickTableColumn_; + + if ([_delegate respondsToSelector:@selector(tableView:didDragTableColumn:)]) + _implementedDelegateMethods |= CPTableViewDelegate_tableView_didDragTableColumn_; + + if ([_delegate respondsToSelector:@selector(tableView:heightOfRow:)]) + _implementedDelegateMethods |= CPTableViewDelegate_tableView_heightOfRow_; + + if ([_delegate respondsToSelector:@selector(tableView:isGroupRow:)]) + _implementedDelegateMethods |= CPTableViewDelegate_tableView_isGroupRow_; + + if ([_delegate respondsToSelector:@selector(tableView:mouseDownInHeaderOfTableColumn:)]) + _implementedDelegateMethods |= CPTableViewDelegate_tableView_mouseDownInHeaderOfTableColumn_; + + if ([_delegate respondsToSelector:@selector(tableView:nextTypeSelectMatchFromRow:toRow:forString:)]) + _implementedDelegateMethods |= CPTableViewDelegate_tableView_nextTypeSelectMatchFromRow_toRow_forString_; + + if ([_delegate respondsToSelector:@selector(tableView:selectionIndexesForProposedSelection:)]) + _implementedDelegateMethods |= CPTableViewDelegate_tableView_selectionIndexesForProposedSelection_; + + if ([_delegate respondsToSelector:@selector(tableView:shouldEditTableColumn:row:)]) + _implementedDelegateMethods |= CPTableViewDelegate_tableView_shouldEditTableColumn_row_; + + if ([_delegate respondsToSelector:@selector(tableView:shouldSelectRow:)]) + _implementedDelegateMethods |= CPTableViewDelegate_tableView_shouldSelectRow_; + + if ([_delegate respondsToSelector:@selector(tableView:shouldSelectTableColumn:)]) + _implementedDelegateMethods |= CPTableViewDelegate_tableView_shouldSelectTableColumn_; + + if ([_delegate respondsToSelector:@selector(tableView:shouldShowViewExpansionForTableColumn:row:)]) + _implementedDelegateMethods |= CPTableViewDelegate_tableView_shouldShowViewExpansionForTableColumn_row_; + + if ([_delegate respondsToSelector:@selector(tableView:shouldTrackView:forTableColumn:row:)]) + _implementedDelegateMethods |= CPTableViewDelegate_tableView_shouldTrackView_forTableColumn_row_; + + if ([_delegate respondsToSelector:@selector(tableView:shouldTypeSelectForEvent:withCurrentSearchString:)]) + _implementedDelegateMethods |= CPTableViewDelegate_tableView_shouldTypeSelectForEvent_withCurrentSearchString_; + + if ([_delegate respondsToSelector:@selector(tableView:toolTipForView:rect:tableColumn:row:mouseLocation:)]) + _implementedDelegateMethods |= CPTableViewDelegate_tableView_toolTipForView_rect_tableColumn_row_mouseLocation_; + + if ([_delegate respondsToSelector:@selector(tableView:typeSelectStringForTableColumn:row:)]) + _implementedDelegateMethods |= CPTableViewDelegate_tableView_typeSelectStringForTableColumn_row_; + + if ([_delegate respondsToSelector:@selector(tableView:willDisplayView:forTableColumn:row:)]) + _implementedDelegateMethods |= CPTableViewDelegate_tableView_willDisplayView_forTableColumn_row_; + + if ([_delegate respondsToSelector:@selector(tableViewColumnDidMove:)]) + [defaultCenter + addObserver:_delegate + selector:@selector(tableViewColumnDidMove:) + name:CPTableViewColumnDidMoveNotification + object:self]; + + if ([_delegate respondsToSelector:@selector(tableViewColumnDidResize:)]) + [defaultCenter + addObserver:_delegate + selector:@selector(tableViewColumnDidMove:) + name:CPTableViewColumnDidResizeNotification + object:self]; + + if ([_delegate respondsToSelector:@selector(tableViewSelectionDidChange:)]) + [defaultCenter + addObserver:_delegate + selector:@selector(tableViewSelectionDidChange:) + name:CPTableViewSelectionDidChangeNotification + object:self]; + + if ([_delegate respondsToSelector:@selector(tableViewSelectionIsChanging:)]) + [defaultCenter + addObserver:_delegate + selector:@selector(tableViewSelectionIsChanging:) + name:CPTableViewSelectionIsChangingNotification + object:self]; +} - (id)delegate { return _delegate; } - -/*! - Sets the delegate for the tableview. -*/ -- (void)setDelegate:(id)aDelegate +//Highlightable Column Headers +/* +- (CPTableColumn)highlightedTableColumn { - if (_delegate === aDelegate) - return; - - var notificationCenter = [CPNotificationCenter defaultCenter]; - - if ([_delegate respondsToSelector:@selector(tableViewColumnDidMove:)]) - [notificationCenter removeObserver:_delegate name:CPTableViewColumnDidMoveNotification object:self]; - if ([_delegate respondsToSelector:@selector(tableViewColumnDidResize:)]) - [notificationCenter removeObserver:_delegate name:CPTableViewColumnDidResizeNotification object:self]; - if ([_delegate respondsToSelector:@selector(tableViewSelectionDidChange:)]) - [notificationCenter removeObserver:_delegate name:CPTableViewSelectionDidChangeNotification object:self]; - if ([_delegate respondsToSelector:@selector(tableViewSelectionIsChanging:)]) - [notificationCenter removeObserver:_delegate name:CPTableViewSelectionIsChangingNotification object:self]; - - _delegate = aDelegate; - - if ([_delegate respondsToSelector:@selector(tableViewColumnDidMove:)]) - [notificationCenter addObserver:_delegate selector:@selector(tableViewColumnDidMove:) name:CPTableViewColumnDidMoveNotification object:self]; - if ([_delegate respondsToSelector:@selector(tableViewColumnDidResize:)]) - [notificationCenter addObserver:_delegate selector:@selector(tableViewColumnDidResize:) name:CPTableViewColumnDidResizeNotification object:self]; - if ([_delegate respondsToSelector:@selector(tableViewSelectionDidChange:)]) - [notificationCenter addObserver:_delegate selector:@selector(tableViewSelectionDidChange:) name:CPTableViewSelectionDidChangeNotification object:self]; - if ([_delegate respondsToSelector:@selector(tableViewSelectionIsChanging:)]) - [notificationCenter addObserver:_delegate selector:@selector(tableViewSelectionIsChanging:) name:CPTableViewSelectionIsChangingNotification object:self]; - _delegateSelectorsCache = 0; +} - if ([_delegate respondsToSelector:@selector(tableView:willDisplayCell:forTableColumn:row:)]) - _delegateSelectorsCache |= _CPTableViewWillDisplayCellSelector; - if ([_delegate respondsToSelector:@selector(tableView:shouldSelectRow:)]) - _delegateSelectorsCache |= _CPTableViewShouldSelectRowSelector; - if ([_delegate respondsToSelector:@selector(tableView:shouldSelectTableColumn:)]) - _delegateSelectorsCache |= _CPTableViewShouldSelectTableColumnSelector; - if ([_delegate respondsToSelector:@selector(selectionShouldChangeInTableView:)]) - _delegateSelectorsCache |= _CPTableViewSelectionShouldChangeSelector; - if ([_delegate respondsToSelector:@selector(tableView:shouldEditTableColumn:row:)]) - _delegateSelectorsCache |= _CPTableViewShouldEditTableColumnSelector; - if ([_delegate respondsToSelector:@selector(tableView:selectionIndexesForProposedSelection:)]) - _delegateSelectorsCache |= _CPTableViewSelectionIndexesForProposedSelectionSelector; - if ([_delegate respondsToSelector:@selector(tableView:heightOfRow:)]) + * - setHighlightedTableColumn: +*/ +//Dragging +/* + * - dragImageForRowsWithIndexes:tableColumns:event:offset: + * - canDragRowsWithIndexes:atPoint: + * - setDraggingSourceOperationMask:forLocal: + * - setDropRow:dropOperation: + * - setVerticalMotionCanBeginDrag: + * - verticalMotionCanBeginDrag +*/ +//Sorting +/* + * - setSortDescriptors: + * - sortDescriptors +*/ + +//Text Delegate Methods +/* + * - textShouldBeginEditing: + * - textDidBeginEditing: + * - textDidChange: + * - textShouldEndEditing: + * - textDidEndEditing: +*/ + +- (id)_objectValueForTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRowIndex +{ + var tableColumnUID = [aTableColumn UID], + tableColumnObjectValues = _objectValues[tableColumnUID]; + + if (!tableColumnObjectValues) { - _delegateSelectorsCache |= _CPTableViewHeightOfRowSelector; - _hasVariableHeightRows = YES; + tableColumnObjectValues = []; + _objectValues[tableColumnUID] = tableColumnObjectValues; } - else - _hasVariableHeightRows = NO; -} + var objectValue = tableColumnObjectValues[aRowIndex]; -/* - Tells the table view that the number of rows in the table - has changed. -*/ -- (void)noteNumberOfRowsChanged -{ - var numberOfRows = [_dataSource numberOfRowsInTableView:self]; - - if (_numberOfRows != numberOfRows) + if (objectValue === undefined) { - _numberOfRows = numberOfRows; - - [self _recalculateColumnHeight]; + objectValue = [_dataSource tableView:self objectValueForTableColumn:aTableColumn row:aRowIndex]; + tableColumnObjectValues[aRowIndex] = objectValue; } + + return objectValue; } -- (void)noteHeightOfRowsWithIndexesChanged:(CPIndexSet)indexSet -{ - // FIXME: more efficient version is possible since we know which indexes changes - [self _recalculateColumnHeight]; -} - -/* - Returns the rectangle bounding the specified row. - @param aRowIndex the row to obtain a rectangle for - @return the bounding rectangle -*/ -- (CGRect)rectOfRow:(int)aRowIndex -{ - return CPRectMake(0.0, ROW_MIN_Y(aRowIndex), CPRectGetWidth([self bounds]), ROW_HEIGHT(aRowIndex)); -} - -/* - Returns the rectangle bounding the specified column - @param aColumnIndex the column to obtain a rectangle for - @return the bounding column -*/ -- (CGRect)rectOfColumn:(int)aColumnIndex -{ - return [_tableColumnViews[aColumnIndex] frame]; -} - -/* - Adjusts column widths to make them all visible at once. Same as \c -tile. -*/ -- (void)sizeToFit -{ -// [self tile]; -} - -- (void)_recalculateColumnHeight -{ - var oldColumnHeight = _columnHeight; - - if (_hasVariableHeightRows) - { - _rowMinYs[0] = 0; - for (var row = 0; row < _numberOfRows; row++) - { - _rowHeights[row] = [_delegate tableView:self heightOfRow:row]; - _rowMinYs[row+1] = _rowMinYs[row] + _rowHeights[row] + _intercellSpacing.height; - } - _columnHeight = _rowMinYs[_numberOfRows]; // last index is one more than last row, and is the total column height - } - else - _columnHeight = _numberOfRows * (_rowHeight + _intercellSpacing.height); - - var count = _tableColumnViews.length; - - while (count--) - [_tableColumnViews[count] setFrameSize:CGSizeMake([_tableColumns[count] width], _columnHeight)]; - - [self setFrameSize:CGSizeMake(CGRectGetWidth([self frame]), _columnHeight)]; -} - -- (CGRect)visibleRectInParent +- (CGRect)_exposedRect { var superview = [self superview]; - - if (!superview) + + if (![superview isKindOfClass:[CPClipView class]]) return [self bounds]; - + return [self convertRect:CGRectIntersection([superview bounds], [self frame]) fromView:superview]; } -/* - Reloads the data from the \c -dataSource. This is an - expensive method, so use it lightly. -*/ -- (void)reloadData +- (void)load { - var oldNumberOfRows = _numberOfRows; - - _numberOfRows = [_dataSource numberOfRowsInTableView:self]; - - if (oldNumberOfRows != _numberOfRows) + if (!_dataSource) { - [self _recalculateColumnHeight]; - [self setFrameSize:CGSizeMake(CGRectGetWidth([self frame]), [self _columnHeight])]; + // remove? + return; } - - _objectValueCache = []; - - [self clearCells]; - - [self setNeedsLayout]; + +// if (!window.blah) +// return window.setTimeout(function() { window.blah = true; [self load]; window.blah = false}, 0.0); + + // if (window.console && window.console.profile) + // console.profile("cell-load"); + + var exposedRect = [self _exposedRect], + exposedRows = [CPIndexSet indexSetWithIndexesInRange:[self rowsInRect:exposedRect]], + exposedColumns = [self columnIndexesInRect:exposedRect], + obscuredRows = [_exposedRows copy], + obscuredColumns = [_exposedColumns copy]; + + [obscuredRows removeIndexes:exposedRows]; + [obscuredColumns removeIndexes:exposedColumns]; + + var newlyExposedRows = [exposedRows copy], + newlyExposedColumns = [exposedColumns copy]; + + [newlyExposedRows removeIndexes:_exposedRows]; + [newlyExposedColumns removeIndexes:_exposedColumns]; + + var previouslyExposedRows = [exposedRows copy], + previouslyExposedColumns = [exposedColumns copy]; + + [previouslyExposedRows removeIndexes:newlyExposedRows]; + [previouslyExposedColumns removeIndexes:newlyExposedColumns]; + +// console.log("will remove:" + '\n\n' + +// previouslyExposedRows + "\n" + obscuredColumns + "\n\n" + +// obscuredRows + "\n" + previouslyExposedColumns + "\n\n" + +// obscuredRows + "\n" + obscuredColumns); + [self _unloadDataViewsInRows:previouslyExposedRows columns:obscuredColumns]; + [self _unloadDataViewsInRows:obscuredRows columns:previouslyExposedColumns]; + [self _unloadDataViewsInRows:obscuredRows columns:obscuredColumns]; + + [self _loadDataViewsInRows:previouslyExposedRows columns:newlyExposedColumns]; + [self _loadDataViewsInRows:newlyExposedRows columns:previouslyExposedColumns]; + [self _loadDataViewsInRows:newlyExposedRows columns:newlyExposedColumns]; + +// console.log("newly exposed rows: " + newlyExposedRows + "\nnewly exposed columns: " + newlyExposedColumns); + _exposedRows = exposedRows; + _exposedColumns = exposedColumns; + + [_tableDrawView setFrame:exposedRect]; + +// [_tableDrawView setBounds:exposedRect]; + [_tableDrawView display]; + + // if (window.console && window.console.profile) +// console.profileEnd("cell-load"); +} + +- (void)_unloadDataViewsInRows:(CPIndexSet)rows columns:(CPIndexSet)columns +{ + if (![rows count] || ![columns count]) + return; + + var rowArray = [], + columnArray = []; + + [rows getIndexes:rowArray maxCount:-1 inIndexRange:nil]; + [columns getIndexes:columnArray maxCount:-1 inIndexRange:nil]; + + var columnIndex = 0, + columnsCount = columnArray.length; + + for (; columnIndex < columnsCount; ++columnIndex) + { + var column = columnArray[columnIndex], + tableColumn = _tableColumns[column], + tableColumnUID = [tableColumn UID]; + + var rowIndex = 0, + rowsCount = rowArray.length; + + for (; rowIndex < rowsCount; ++rowIndex) + { + var row = rowArray[rowIndex], + dataView = _dataViewsForTableColumns[tableColumnUID][row]; + + _dataViewsForTableColumns[tableColumnUID][row] = nil; +if (!_cachedDataViews[dataView.identifier]) +_cachedDataViews[dataView.identifier] = [dataView]; +else +_cachedDataViews[dataView.identifier].push(dataView); + } + } +} + +- (void)_loadDataViewsInRows:(CPIndexSet)rows columns:(CPIndexSet)columns +{ + if (![rows count] || ![columns count]) + return; + + var rowArray = [], + rowRects = [], + columnArray = []; + + [rows getIndexes:rowArray maxCount:-1 inIndexRange:nil]; + [columns getIndexes:columnArray maxCount:-1 inIndexRange:nil]; + + var columnIndex = 0, + columnsCount = columnArray.length; + + for (; columnIndex < columnsCount; ++columnIndex) + { + var column = columnArray[columnIndex], + tableColumn = _tableColumns[column], + tableColumnUID = [tableColumn UID], + tableColumnRange = _tableColumnRanges[column]; + + if (!_dataViewsForTableColumns[tableColumnUID]) + _dataViewsForTableColumns[tableColumnUID] = []; + + var rowIndex = 0, + rowsCount = rowArray.length; + + for (; rowIndex < rowsCount; ++rowIndex) + { + var row = rowArray[rowIndex], + dataView = [tableColumn _newDataViewForRow:row], + rectOfRow = rowRects[row]; + + if (!rectOfRow) + rectOfRow = rowRects[row] = [self rectOfRow:row]; + + [dataView setFrame:_CGRectMake(tableColumnRange.location, _CGRectGetMinY(rectOfRow), tableColumnRange.length, _CGRectGetHeight(rectOfRow))]; + [dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]]; + + if ([dataView superview] !== self) + [self addSubview:dataView]; + + _dataViewsForTableColumns[tableColumnUID][row] = dataView; + } + } +} + +- (void)setFrameSize:(CGSize)aSize +{ + [super setFrameSize:aSize]; + [_headerView setFrameSize:CGSizeMake(aSize.width, [_headerView frame].size.height)]; +} + +- (CGRect)exposedClipRect +{ + var superview = [self superview]; + + if (![superview isKindOfClass:[CPClipView class]]) + return [self bounds]; + + return [self convertRect:CGRectIntersection([superview bounds], [self frame]) fromView:superview]; +} + +- (void)_drawRect:(CGRect)aRect +{ + var exposedRect = [self _exposedRect]; + + [self drawBackgroundInClipRect:exposedRect]; + [self highlightSelectionInClipRect:exposedRect]; + [self drawGridInClipRect:exposedRect]; +} + +- (void)drawBackgroundInClipRect:(CGRect)aRect +{ + if (![self usesAlternatingRowBackgroundColors]) + return; + + var rowColors = [self alternatingRowBackgroundColors], + colorCount = [rowColors count]; + + if (colorCount === 0) + return; + + var context = [[CPGraphicsContext currentContext] graphicsPort]; + + if (colorCount === 1) + { + CGContextSetFillColor(context, rowColors[0]); + CGContextFillRect(context, aRect); + + return; + } + // CGContextFillRect(context, CGRectIntersection(aRect, fillRect)); + // console.profile("row-paint"); + var exposedRows = [self rowsInRect:aRect], + firstRow = exposedRows.location, + lastRow = CPMaxRange(exposedRows) - 1, + colorIndex = MIN(exposedRows.length, colorCount); + + while (colorIndex--) + { + var row = firstRow % colorCount + firstRow + colorIndex, + fillRect = nil; + + CGContextBeginPath(context); + + for (; row <= lastRow; row += colorCount) + CGContextAddRect(context, CGRectIntersection(aRect, fillRect = [self rectOfRow:row])); + + if (row - colorCount === lastRow) + heightFilled = _CGRectGetMaxY(fillRect); + + CGContextClosePath(context); + + CGContextSetFillColor(context, rowColors[colorIndex]); + CGContextFillPath(context); + } + // console.profileEnd("row-paint"); + + var totalHeight = _CGRectGetMaxY(aRect); + + if (heightFilled >= totalHeight || _rowHeight <= 0.0) + return; + + var rowHeight = _rowHeight + _intercellSpacing.height, + fillRect = _CGRectMake(_CGRectGetMinX(aRect), _CGRectGetMinY(aRect) + heightFilled, _CGRectGetWidth(aRect), rowHeight); + + for (row = lastRow + 1; heightFilled < totalHeight; ++row) + { + CGContextSetFillColor(context, rowColors[row % colorCount]); + CGContextFillRect(context, fillRect); + + heightFilled += rowHeight; + fillRect.origin.y += rowHeight; + } +} + +- (void)drawGridInClipRect:(CGRect)aRect +{ + var context = [[CPGraphicsContext currentContext] graphicsPort], + gridStyleMask = [self gridStyleMask]; + + if (!(gridStyleMask & (CPTableViewSolidHorizontalGridLineMask | CPTableViewSolidVerticalGridLineMask))) + return; + + CGContextBeginPath(context); + + if (gridStyleMask & CPTableViewSolidHorizontalGridLineMask) + { + var exposedRows = [self rowsInRect:aRect]; + row = exposedRows.location, + lastRow = CPMaxRange(exposedRows) - 1, + rowY = 0.0, + minX = _CGRectGetMinX(aRect), + maxX = _CGRectGetMaxX(aRect); + + for (; row <= lastRow; ++row) + { + // grab each row rect and add the top and bottom lines + var rowRect = [self rectOfRow:row], + rowY = _CGRectGetMaxY(rowRect) - 0.5; + + CGContextMoveToPoint(context, minX, rowY); + CGContextAddLineToPoint(context, maxX, rowY); + } + + if (_rowHeight > 0.0) + { + var rowHeight = _rowHeight + _intercellSpacing.height, + totalHeight = _CGRectGetMaxY(aRect); + + while (rowY < totalHeight) + { + rowY += rowHeight; + + CGContextMoveToPoint(context, minX, rowY); + CGContextAddLineToPoint(context, maxX, rowY); + } + } + } + + if (gridStyleMask & CPTableViewSolidVerticalGridLineMask) + { + var exposedColumnIndexes = [self columnIndexesInRect:aRect], + columnsArray = []; + + [exposedColumnIndexes getIndexes:columnsArray maxCount:-1 inIndexRange:nil]; + + var columnArrayIndex = 0, + columnArrayCount = columnsArray.length, + minY = _CGRectGetMinY(aRect), + maxY = _CGRectGetMaxY(aRect); + + for (; columnArrayIndex < columnArrayCount; ++columnArrayIndex) + { + var columnRect = [self rectOfColumn:columnArrayIndex], + columnX = _CGRectGetMaxX(columnRect) - 0.5; + + CGContextMoveToPoint(context, columnX, minY); + CGContextAddLineToPoint(context, columnX, maxY); + } + } + + CGContextClosePath(context); + CGContextSetStrokeColor(context, _gridColor); + CGContextStrokePath(context); +} + + +- (void)highlightSelectionInClipRect:(CGRect)aRect +{ + // FIXME: This color thingy is terrible probably. + if ([self selectionHighlightStyle] === CPTableViewSelectionHighlightStyleSourceList) + [[CPColor selectionColorSourceView] setFill]; + else + [[CPColor selectionColor] setFill]; + + var context = [[CPGraphicsContext currentContext] graphicsPort], + indexes = [], + rectSelector = @selector(rectOfRow:); + + if ([_selectedRowIndexes count] >= 1) + { + var exposedRows = [CPIndexSet indexSetWithIndexesInRange:[self rowsInRect:aRect]], + firstRow = [exposedRows firstIndex], + exposedRange = CPMakeRange(firstRow, [exposedRows lastIndex] - firstRow + 1); + + [_selectedRowIndexes getIndexes:indexes maxCount:-1 inIndexRange:exposedRange]; + } + + else if ([_selectedColumnIndexes count] >= 1) + { + rectSelector = @selector(rectOfColumn:); + + var exposedColumns = [self columnIndexesInRect:aRect], + firstColumn = [exposedColumns firstIndex], + exposedRange = CPMakeRange(firstColumn, [exposedColumns lastIndex] - firstColumn + 1); + + [_selectedColumnIndexes getIndexes:indexes maxCount:-1 inIndexRange:exposedRange]; + } + + var count = [indexes count]; + + if (!count) + return; + + CGContextBeginPath(context); + + while (count--) + CGContextAddRect(context, CGRectIntersection(objj_msgSend(self, rectSelector, indexes[count]), aRect)); + + CGContextClosePath(context); + CGContextFillPath(context); } - (void)layoutSubviews { - [self loadTableCellsInRect:[self visibleRectInParent]]; + [self load]; } -- (void)displaySoon +- (void)viewWillMoveToSuperview:(CPView)aView { - [_scrollTimer invalidate]; - _scrollTimer = [CPTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(displayNow) userInfo:nil repeats:NO]; + var superview = [self superview], + defaultCenter = [CPNotificationCenter defaultCenter]; + + if (superview) + { + [defaultCenter + removeObserver:self + name:CPViewFrameDidChangeNotification + object:superview]; + + [defaultCenter + removeObserver:self + name:CPViewBoundsDidChangeNotification + object:superview]; + } + + if (aView) + { + [aView setPostsFrameChangedNotifications:YES]; + [aView setPostsBoundsChangedNotifications:YES]; + + [defaultCenter + addObserver:self + selector:@selector(superviewFrameChanged:) + name:CPViewFrameDidChangeNotification + object:aView]; + + [defaultCenter + addObserver:self + selector:@selector(superviewBoundsChanged:) + name:CPViewBoundsDidChangeNotification + object:aView]; + } } -- (void)displayNow +- (void)superviewBoundsChanged:(CPNotification)aNotification { + [self setNeedsDisplay:YES]; [self setNeedsLayout]; } -- (void)viewDidMoveToSuperview +- (void)superviewFrameChanged:(CPNotification)aNotification { - [[[self enclosingScrollView] contentView] setPostsBoundsChangedNotifications:YES]; - - [[CPNotificationCenter defaultCenter] - addObserver:self - selector:@selector(viewBoundsChanged:) - name:CPViewBoundsDidChangeNotification - object:[[self enclosingScrollView] contentView]]; + [self _sizeToParent]; + + // Call this explicitly because *our* size may not change, but the exposedRect may change. + [self setNeedsDisplay:YES]; + [self setNeedsLayout]; } -- (void)viewBoundsChanged:(CPNotification)aNotification -{ - //CPLog.info(_cmd + CPStringFromRect([[[self enclosingScrollView] contentView] bounds])); - //objj_debug_print_backtrace(); - //[self setNeedsLayout]; - [self displayNow]; -} +// /* -- (void)setAllowsColumnReordering:(BOOL)allowsColumnReordering -{ - if (_allowsColumnReordering === _allowsColumnReordering) - return; - - _allowsColumnReordering = allowsColumnReordering; -} -- (void)allowsColumnReordering -{ - return _allowsColumnReordering; -} - -- (void)setAllowsColumnResizing:(BOOL)allowsColumnResizing -{ - if (_allowsColumnResizing === allowsColumnResizing) - return; - - _allowsColumnResizing = allowsColumnResizing; -} -- (void)allowsColumnResizing -{ - return _allowsColumnResizing; -} - -- (void)setAllowsColumnSelection:(BOOL)allowsColumnSelection -{ - if (_allowsColumnSelection === allowsColumnSelection) - return; - - _allowsColumnSelection = allowsColumnSelection; -} -- (void)allowsColumnSelection -{ - return _allowsColumnSelection; -} -*/ - -- (void)setAllowsMultipleSelection:(BOOL)allowsMultipleSelection -{ - if (_allowsMultipleSelection === allowsMultipleSelection) - return; - - _allowsMultipleSelection = allowsMultipleSelection; - - // TODO: more stuff? -} -- (void)allowsMultipleSelection -{ - return _allowsMultipleSelection; -} - -- (void)setAllowsEmptySelection:(BOOL)allowsEmptySelection -{ - if (_allowsEmptySelection === allowsEmptySelection) - return; - - _allowsEmptySelection = allowsEmptySelection; -} -- (void)allowsEmptySelection -{ - return _allowsEmptySelection; -} - - -/* - Returns the index of the row at the given point, or CPNotFound (-1) if it is out of range. - @param aPoint the point - @return the index of the row at aPoint -*/ -- (int)rowAtPoint:(CGPoint)aPoint -{ - var index = [self _rowAtY:aPoint.y] - - if (index >= 0 && index < _numberOfRows) - return index; - else - return CPNotFound; -} - -- (int)columnAtPoint:(CGPoint)aPoint -{ - var index = [self _columnAtX:aPoint.x] - - if (index >= 0 && index < _tableColumns.length) - return index; - else - return CPNotFound; -} - -/* - @ignore - - Internal version takes a Y value, returns an index, or -1 if its beyond the min, or numberOfRows if it's beyond the max -*/ -- (int)_rowAtY:(float)y -{ - if (_hasVariableHeightRows) - { - var a = 0, - b = _numberOfRows; - - if (y < _rowMinYs[0]) - return -1; - if (y >= _rowMinYs[_rowMinYs.length-1]) - return _numberOfRows; - - // binary search - while (true) - { - var half = a + Math.floor((b - a) / 2); - - if (y < _rowMinYs[half]) - b = half; - else if (half < _numberOfRows-1 && y >= _rowMinYs[half+1]) - a = half; - else - return half; - } - } - else - return FLOOR(y / (_rowHeight + _intercellSpacing.height)); -} - -/* - @ignore - - Internal version takes a X value, returns an index, or -1 if its beyond the min, or numberOfColumns if it's beyond the max -*/ -- (int)_columnAtX:(float)x -{ - var a = 0, - b = _tableColumns.length; - - var last = [_tableColumnViews[_tableColumns.length-1] frame]; - if (x < [_tableColumnViews[0] frame].origin.x) - return -1; - if (x >= last.origin.x + last.size.width) - return _tableColumns.length; - - // binary search - while (true) - { - var half = a + Math.floor((b - a) / 2); - - if (x < [_tableColumnViews[half] frame].origin.x) - b = half; - else if (half < _tableColumns.length-1 && x >= [_tableColumnViews[half+1] frame].origin.x) - a = half; - else - return half; - } -} - -/* - Selects the specified row indexes, optionally adding to existing selection - @param indexes the indexes to select - @param extend whether or not to add to the existing selection -*/ -- (void)selectRowIndexes:(CPIndexSet)indexes byExtendingSelection:(BOOL)extend -{ - // FIXME: should this be subject to the delegate filters, etc? - - if (extend) - _selectedRowIndexes = [[_selectedRowIndexes copy] addIndexes:indexes]; - else if ([indexes count] > 0 || _allowsEmptySelection) - _selectedRowIndexes = [indexes copy]; - - [self _drawSelection]; -} - -/* - Returns a CPIndexSet of the selected rows - @return indexes of the selected rows -*/ -- (CPIndexSet)selectedRowIndexes -{ - return _selectedRowIndexes; -} - -/* - Returns the number of selected rows - @return number of selected rows -*/ -- (int)numberOfSelectedRows -{ - return [_selectedRowIndexes count]; -} - - -/* - Deselects all rows if allowsEmptySelection is true. If delegate responds to "selectionShouldChangeInTableView:", asks if it should chnage. - Sends the CPTableViewSelectionDidChangeNotification on deselection. - @param the sender in a target/action -*/ -- (void)deselectAll:(id)sender -{ - if (!_allowsEmptySelection || [_selectedRowIndexes count] === 0 || - ((_delegateSelectorsCache & _CPTableViewSelectionShouldChangeSelector) && ![_delegate selectionShouldChangeInTableView:self])) - return; - - [self selectRowIndexes:[CPIndexSet indexSet] byExtendingSelection:NO]; - [[CPNotificationCenter defaultCenter] postNotificationName:CPTableViewSelectionDidChangeNotification object:self userInfo:nil]; -} - -- (void)editColumn:(int)columnIndex row:(int)rowIndex withEvent:(CPEvent)theEvent select:(BOOL)flag -{ - -} - -/* - @ignore -*/ -- (void)_updateSelectionWithMouseAtRow:(int)aRow -{ - // Make a preliminary new selection - var newSelection; - if (_allowsMultipleSelection) - newSelection = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(MIN(aRow, _selectionStartRow), ABS(aRow-_selectionStartRow)+1)]; - else if (aRow >= 0 && aRow < _numberOfRows) - newSelection = [CPIndexSet indexSetWithIndex:aRow]; - else - newSelection = [CPIndexSet indexSet]; - - // If cmd/ctrl was held down XOR the old selection with the proposed selection - if (_allowsMultipleSelection && _selectionModifier & (CPCommandKeyMask | CPControlKeyMask | CPAlternateKeyMask)) - { - // A = newSelection, B = _previousSelectedRowIndexes - // (A intersection B) = (A - (A - B)) - var intersection = [newSelection copy], - difference = [newSelection copy]; - [difference removeIndexes:_previousSelectedRowIndexes]; - [intersection removeIndexes:difference] - - // (A xor B) = (A + B) - (A intersection B) - [newSelection addIndexes:_previousSelectedRowIndexes]; - [newSelection removeIndexes:intersection]; - - // FIXME: if multiple selection is off, and we cmd/ctrl click the previously selected row, then deselect it. - } - - // if the new selection is different than the old selection - if (![newSelection isEqualToIndexSet:_selectedRowIndexes]) - { - // ask the delegate if we should change the selection - if ((_delegateSelectorsCache & _CPTableViewSelectionShouldChangeSelector) && ![_delegate selectionShouldChangeInTableView:self]) - return; - - // ask the delegate which indexes can be selected. selectionIndexesForProposedSelection is faster than shouldSelectRow - if (_delegateSelectorsCache & _CPTableViewSelectionIndexesForProposedSelectionSelector) - newSelection = [_delegate tableView:self selectionIndexesForProposedSelection:newSelection]; - else if (_delegateSelectorsCache & _CPTableViewShouldSelectRowSelector) - { - var indexes = []; - [newSelection getIndexes:indexes maxCount:Number.MAX_VALUE inIndexRange:nil]; - for (var i = 0; i < indexes.length; i++) - if (![_delegate tableView:self shouldSelectRow:indexes[i]]) - [newSelection removeIndex:indexes[i]]; - } - } - - // if empty selection is not allowed and the new selection has nothing selected, abort - if (!_allowsEmptySelection && [newSelection count] === 0) - return; - - // if the new selection is *still* different, and update the selection and send a notification - if (![newSelection isEqualToIndexSet:_selectedRowIndexes]) - { - [self selectRowIndexes:newSelection byExtendingSelection:NO]; - [[CPNotificationCenter defaultCenter] postNotificationName:CPTableViewSelectionIsChangingNotification object:self userInfo:nil]; - } -} - -/* - @ignore -*/ -- (void)mouseDown:(CPEvent)anEvent -{ - [self trackSelection:anEvent]; -} - -/* - Sets the message to be sent to the target when a cell is double clicked - @param aSelector the selector to be performed -*/ -- (void)setDoubleAction:(SEL)aSelector -{ - _doubleAction = aSelector; -} -- (SEL)doubleAction -{ - return _doubleAction; -} - -- (int)clickedColumn -{ - return _clickedColumn; -} -- (int)clickedRow -{ - return _clickedRow; -} - -/* - @ignore -*/ -- (void)trackSelection:(CPEvent)anEvent -{ var type = [anEvent type], point = [self convertPoint:[anEvent locationInWindow] fromView:nil], currentRow = MAX(0, MIN(_numberOfRows-1, [self _rowAtY:point.y])); - - if (type == CPLeftMouseUp) - { - _clickedRow = [self rowAtPoint:point]; - _clickedColumn = [self columnAtPoint:point]; - - if ([anEvent clickCount] === 2) - { - CPLog.warn("edit?!"); - - [self sendAction:_doubleAction to:_target]; - } - else - { - if (![_previousSelectedRowIndexes isEqualToIndexSet:_selectedRowIndexes]) - { - [[CPNotificationCenter defaultCenter] postNotificationName:CPTableViewSelectionDidChangeNotification object:self userInfo:nil]; - } - - [self sendAction:_action to:_target]; - } - - return; - } - - if (type == CPLeftMouseDown) - { - _previousSelectedRowIndexes = _selectedRowIndexes; - _selectionModifier = [anEvent modifierFlags]; - - if (_selectionModifier & CPShiftKeyMask) - _selectionStartRow = (ABS([_previousSelectedRowIndexes firstIndex] - currentRow) < ABS([_previousSelectedRowIndexes lastIndex] - currentRow)) ? - [_previousSelectedRowIndexes firstIndex] : [_previousSelectedRowIndexes lastIndex]; - else - _selectionStartRow = currentRow; - - [self _updateSelectionWithMouseAtRow:currentRow]; - } - else if (type == CPLeftMouseDragged) - { - [self _updateSelectionWithMouseAtRow:currentRow]; - } - - [CPApp setTarget:self selector:@selector(trackSelection:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES]; + +*/ + +- (BOOL)tracksMouseOutsideOfFrame +{ + return YES; } -/* - @ignore -*/ -- (void)_drawSelection +- (BOOL)startTrackingAt:(CGPoint)aPoint { - if (!_currentlySelected) { - _currentlySelected = [CPIndexSet indexSet]; - _selectionViews = []; - _selectionViewsPool = []; - } + var row = [self rowAtPoint:aPoint]; - // TODO: we could also remove selections that aren't visible, but then we'll need to run this on every scroll/resize? - - // get array of indexes we can remove - var removeSet = [_currentlySelected copy], - indexesToRemove = []; - [removeSet removeIndexes:_selectedRowIndexes]; - [removeSet getIndexes:indexesToRemove maxCount:Number.MAX_VALUE inIndexRange:nil]; - - // get array of indexes we need to add - var addSet = [_selectedRowIndexes copy], - indexesToAdd = []; - [addSet removeIndexes:_currentlySelected]; - [addSet getIndexes:indexesToAdd maxCount:Number.MAX_VALUE inIndexRange:nil]; - - for (var i = 0; i < indexesToRemove.length; i++) - { - var row = indexesToRemove[i]; - for (var column = 0; column < _tableColumns.length; column++) - if ([_tableCells[column][row] respondsToSelector:@selector(highlight:)]) - [_tableCells[column][row] highlight:NO]; - } - for (var i = 0; i < indexesToAdd.length; i++) - { - var row = indexesToAdd[i]; - for (var column = 0; column < _tableColumns.length; column++) - if ([_tableCells[column][row] respondsToSelector:@selector(highlight:)]) - [_tableCells[column][row] highlight:YES]; - } + if ([self mouseDownFlags] & CPShiftKeyMask) + _selectionAnchorRow = (ABS([_selectedRowIndexes firstIndex] - row) < ABS([_selectedRowIndexes lastIndex] - row)) ? + [_selectedRowIndexes firstIndex] : [_selectedRowIndexes lastIndex]; + else + _selectionAnchorRow = row; - // add each one we need to add, taking the selection views from removed seelctions, the pool, or new - for (var i = 0; i < indexesToAdd.length; i++) + [self _updateSelectionWithMouseAtRow:row]; + + return YES; +} + +- (BOOL)continueTracking:(CGPoint)lastPoint at:(CGPoint)aPoint +{ + [self _updateSelectionWithMouseAtRow:[self rowAtPoint:aPoint]]; + + return YES; +} + +- (void)stopTracking:(CGPoint)lastPoint at:(CGPoint)aPoint mouseIsUp:(BOOL)mouseIsUp +{/* + _clickedRow = [self rowAtPoint:point]; + _clickedColumn = [self columnAtPoint:point]; + + if ([anEvent clickCount] === 2) { - var index = indexesToAdd[i], - view; - - if (indexesToRemove.length > 0) + CPLog.warn("edit?!"); + + [self sendAction:_doubleAction to:_target]; + } + else + { + if (![_previousSelectedRowIndexes isEqualToIndexSet:_selectedRowIndexes]) { - view = _selectionViews[indexesToRemove.pop()]; + [[CPNotificationCenter defaultCenter] postNotificationName:CPTableViewSelectionDidChangeNotification object:self userInfo:nil]; } - else if (_selectionViewsPool.length > 0) + + [self sendAction:_action to:_target]; + } +*/ +} + +- (void)_updateSelectionWithMouseAtRow:(CPInteger)aRow +{ + // If cmd/ctrl was held down XOR the old selection with the proposed selection + if ([self mouseDownFlags] & (CPCommandKeyMask | CPControlKeyMask | CPAlternateKeyMask)) + { + if ([_selectedRowIndexes containsIndex:aRow]) { - view = _selectionViewsPool.pop(); - [self addSubview:view positioned:CPWindowBelow relativeTo:nil]; + newSelection = [_selectedRowIndexes copy]; + + [newSelection removeIndex:aRow]; } + + else if (_allowsMultipleSelection) + { + newSelection = [_selectedRowIndexes copy]; + + [newSelection addIndex:aRow]; + } + else - { - view = [[CPView alloc] init]; - [view setBackgroundColor:[CPColor alternateSelectedControlColor]]; - - [self addSubview:view positioned:CPWindowBelow relativeTo:nil]; - } - - _selectionViews[index] = view; - - var frame = [self rectOfRow:index]; - frame.size.height += _intercellSpacing.height - 1; - //frame.size.width += 500; - - [view setFrame:frame]; + newSelection = [CPIndexSet indexSetWithIndex:aRow]; } - - // remove any selections that weren't already reused - for (var i = 0; i < indexesToRemove.length; i++) + + else if (_allowsMultipleSelection) + newSelection = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(MIN(aRow, _selectionAnchorRow), ABS(aRow - _selectionAnchorRow) + 1)]; + + else if (aRow >= 0 && aRow < _numberOfRows) + newSelection = [CPIndexSet indexSetWithIndex:aRow]; + + else + newSelection = [CPIndexSet indexSet]; + + if ([newSelection isEqualToIndexSet:_selectedRowIndexes]) + return; + + if (_implementedDelegateMethods & CPTableViewDelegate_selectionShouldChangeInTableView_ && + ![_delegate selectionShouldChangeInTableView:self]) + return; + + if (_implementedDelegateMethods & CPTableViewDelegate_tableView_selectionIndexesForProposedSelection_) + newSelection = [_delegate tableView:self selectionIndexesForProposedSelection:newSelection]; + + if (_implementedDelegateMethods & CPTableViewDelegate_tableView_shouldSelectRow_) { - var row = indexesToRemove[i], - view = _selectionViews[row]; - - [view removeFromSuperview]; - _selectionViewsPool.push(view); + var indexArray = []; + + [newSelection getIndexes:indexArray maxCount:-1 inIndexRange:nil]; + + var indexCount = indexArray.length; + + while (indexCount--) + { + var index = indexArray[indexCount]; + + if (![_delegate tableView:self shouldSelectRow:index]) + [newSelection removeIndex:index]; + } } - - // update the currently selected index set - _currentlySelected = [_selectedRowIndexes copy]; + + // if empty selection is not allowed and the new selection has nothing selected, abort + if (!_allowsEmptySelection && [newSelection count] === 0) + return; + + if ([newSelection isEqualToIndexSet:_selectedRowIndexes]) + return; + + [self selectRowIndexes:newSelection byExtendingSelection:NO]; + + [[CPNotificationCenter defaultCenter] + postNotificationName:CPTableViewSelectionIsChangingNotification + object:self + userInfo:nil]; } @end - var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey", CPTableViewDelegateKey = @"CPTableViewDelegateKey", CPTableViewHeaderViewKey = @"CPTableViewHeaderViewKey", @@ -1246,10 +1684,13 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey", - (id)initWithCoder:(CPCoder)aCoder { - if (self = [super initWithCoder:aCoder]) + //FIXME:!!!! + [self init]; + + self = [super initWithCoder:aCoder]; + + if (self) { - [self _init]; - _dataSource = [aCoder decodeObjectForKey:CPTableViewDataSourceKey]; _delegate = [aCoder decodeObjectForKey:CPTableViewDelegateKey]; @@ -1259,9 +1700,12 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey", _allowsMultipleSelection = [aCoder decodeBoolForKey:CPTableViewMultipleSelectionKey]; _allowsEmptySelection = [aCoder decodeBoolForKey:CPTableViewEmptySelectionKey]; - var tableColumns = [aCoder decodeObjectForKey:CPTableViewTableColumnsKey]; - for (var i = 0; i < tableColumns.length; i++) - [self addTableColumn:tableColumns[i]]; + _tableColumns = [aCoder decodeObjectForKey:CPTableViewTableColumnsKey]; + + [_tableColumns makeObjectsPerformSelector:@selector(setTableView:) withObject:self]; + _dirtyTableColumnRangeIndex = 0; + + [self viewWillMoveToSuperview:[self superview]]; } return self; @@ -1274,29 +1718,28 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey", [aCoder encodeObject:_dataSource forKey:CPTableViewDataSourceKey]; [aCoder encodeObject:_delegate forKey:CPTableViewDelegateKey]; - [aCoder encodeObject:_tableColumns forKey:CPTableViewTableColumnsKey]; - [aCoder encodeFloat:_rowHeight forKey:CPTableViewRowHeightKey]; [aCoder encodeSize:_intercellSpacing forKey:CPTableViewIntercellSpacingKey]; [aCoder encodeBool:_allowsMultipleSelection forKey:CPTableViewMultipleSelectionKey]; [aCoder encodeBool:_allowsEmptySelection forKey:CPTableViewEmptySelectionKey]; + + [aCoder encodeObject:_tableColumns forKey:CPTableViewTableColumnsKey]; } @end +@implementation CPColor (tableview) - -@implementation CPColor (TableView) - -+ (CPColor)alternateSelectedControlColor ++ (CPColor)selectionColor { - return [[CPColor alloc] _initWithRGBA:[0.22, 0.46, 0.84, 1.0]]; + return [CPColor colorWithHexString:@"5f83b9"]; } -+ (CPColor)secondarySelectedControlColor ++ (CPColor)selectionColorSourceView { - return [[CPColor alloc] _initWithRGBA:[0.83, 0.83, 0.83, 1.0]]; + return [CPColor colorWithPatternImage:[[CPImage alloc] initByReferencingFile:@"Resources/tableviewselection.png" size:CGSizeMake(6,22)]]; } -@end + +@end \ No newline at end of file diff --git a/AppKit/CPTextField.j b/AppKit/CPTextField.j index 87ea6f8c9..6672a4596 100644 --- a/AppKit/CPTextField.j +++ b/AppKit/CPTextField.j @@ -692,7 +692,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); { var string = [self stringValue]; - if ((!string || [string length] === 0) && ![self hasThemeState:CPThemeStateEditing]) + if ((!string || string.length === 0) && ![self hasThemeState:CPThemeStateEditing]) [self setThemeState:CPTextFieldStatePlaceholder]; else [self unsetThemeState:CPTextFieldStatePlaceholder]; diff --git a/AppKit/CPView.j b/AppKit/CPView.j index 047e2ccc4..504569d5b 100644 --- a/AppKit/CPView.j +++ b/AppKit/CPView.j @@ -94,12 +94,13 @@ var DOMElementPrototype = nil, BackgroundTrivialColor = 0, BackgroundVerticalThreePartImage = 1, BackgroundHorizontalThreePartImage = 2, - BackgroundNinePartImage = 3, - - CustomDrawRectViews = {}, - CustomLayoutSubviewsViews = {}; + BackgroundNinePartImage = 3; #endif +var CPViewFlags = { }, + CPViewHasCustomDrawRect = 1 << 0, + CPViewHasCustomLayoutSubviews = 1 << 1; + /*! @ingroup appkit @class CPView @@ -184,6 +185,8 @@ var DOMElementPrototype = nil, // Key View Support CPView _nextKeyView; CPView _previousKeyView; + + unsigned _viewClassFlags; } /* @@ -209,6 +212,27 @@ var DOMElementPrototype = nil, CachedNotificationCenter = [CPNotificationCenter defaultCenter]; } +- (void)setupViewFlags +{ + var theClass = [self class], + classUID = [theClass UID]; + + if (CPViewFlags[classUID] === undefined) + { + var flags = 0; + + if ([theClass instanceMethodForSelector:@selector(drawRect:)] !== [CPView instanceMethodForSelector:@selector(drawRect:)]) + flags |= CPViewHasCustomDrawRect; + + if ([theClass instanceMethodForSelector:@selector(layoutSubviews)] !== [CPView instanceMethodForSelector:@selector(layoutSubviews)]) + flags |= CPViewHasCustomLayoutSubviews; + + CPViewFlags[classUID] = flags; + } + + _viewClassFlags = CPViewFlags[classUID]; +} + + (CPSet)keyPathsForValuesAffectingFrame { return [CPSet setWithObjects:@"frameOrigin", @"frameSize"]; @@ -261,6 +285,8 @@ var DOMElementPrototype = nil, _theme = [CPTheme defaultTheme]; _themeState = CPThemeStateNormal; + [self setupViewFlags]; + [self _loadThemeAttributes]; } @@ -1549,16 +1575,7 @@ setBoundsOrigin: - (void)setNeedsDisplayInRect:(CPRect)aRect { #if PLATFORM(DOM) - var UID = [[self class] UID], - hasCustomDrawRect = CustomDrawRectViews[UID]; - - if (!hasCustomDrawRect && typeof hasCustomDrawRect === "undefined") - { - hasCustomDrawRect = [self methodForSelector:@selector(drawRect:)] != [CPView instanceMethodForSelector:@selector(drawRect:)]; - CustomDrawRectViews[UID] = hasCustomDrawRect; - } - - if (!hasCustomDrawRect) + if (!(_viewClassFlags & CPViewHasCustomDrawRect)) return; #endif @@ -1680,22 +1697,10 @@ setBoundsOrigin: _needsLayout = YES; #if PLATFORM(DOM) - var UID = [[self class] UID], - hasCustomLayoutSubviews = CustomLayoutSubviewsViews[UID]; - - if (hasCustomLayoutSubviews === undefined) - { - hasCustomLayoutSubviews = [self methodForSelector:@selector(layoutSubviews)] != [CPView instanceMethodForSelector:@selector(layoutSubviews)]; - CustomLayoutSubviewsViews[UID] = hasCustomLayoutSubviews; - } - - if (!hasCustomLayoutSubviews) + if (!(_viewClassFlags & CPViewHasCustomLayoutSubviews)) return; - if (_needsLayout) - { - CPDOMDisplayServerAddView(self); - } + CPDOMDisplayServerAddView(self); #endif } @@ -2335,6 +2340,8 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask", [self setBackgroundColor:[aCoder decodeObjectForKey:CPViewBackgroundColorKey]]; + [self setupViewFlags]; + _theme = [CPTheme defaultTheme]; _themeState = CPThemeState([aCoder decodeIntForKey:CPViewThemeStateKey]); _themeAttributes = {}; @@ -2450,6 +2457,7 @@ var _CPViewGetTransform = function(/*CPView*/ fromView, /*CPView */ toView) { var view = fromView; + // FIXME: This doesn't handle the case when the outside views are equal. // If we have a fromView, "climb up" the view tree until // we hit the root node or we hit the toLayer. while (view && view != toView) diff --git a/AppKit/OLDCPTableColumn.j b/AppKit/OLDCPTableColumn.j new file mode 100644 index 000000000..6d37c1de9 --- /dev/null +++ b/AppKit/OLDCPTableColumn.j @@ -0,0 +1,471 @@ +/* + * CPTableColumn.j + * AppKit + * + * Created by Francisco Tolmasky. + * Copyright 2008, 280 North, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * 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 + + +/* +@ignore +*/ + +/* + @global + @class CPTableColumn +*/ +CPTableColumnNoResizing = 0; +/* + @global + @class CPTableColumn +*/ +CPTableColumnAutoresizingMask = 1; +/* + @global + @class CPTableColumn +*/ +CPTableColumnUserResizingMask = 2; + +#define PurgableInfoMake(aView, aRow) { view:(aView), row:(aRow) } +#define PurgableInfoView(anInfo) ((anInfo).view) +#define PurgableInfoRow(anInfo) ((anInfo).row) + +/*! + @ingroup appkit + @class CPTableColumn + + An CPTableColumn object mainly keeps information about the width of the column, its minimum and maximum width; whether the column can be edited or resized; and the cells used to draw the column header and the data in the column. You can change all these attributes of the column by calling the appropriate methods. Please note that the table column does not hold nor has access to the data to be displayed in the column; this data is maintained in the table view's data source.

+ +

Each CPTableColumn object is identified by a CPString, called the column identifier. The reason is that, after a column has been added to a table view, the user might move the columns around, so there is a need to identify the columns regardless of its position in the table. + + @ignore +*/ +@implementation CPTableColumn : CPObject +{ + CPString _identifier; + CPView _headerView; + + CPTableView _tableView; + + float _width; + float _minWidth; + float _maxWidth; + + unsigned _resizingMask; + + CPView _dataView; // default data view for this column + + Object _dataViewData; // cache of data view archives (key=data view UID, value=data view archive) + Object _dataViewForView; // mapping from view instances back to their data view prototype (key=view instance UID, value=data view) + Object _purgableInfosForDataView; // (key=data view UID, value=) +} + +/*! + Initializes the table column with the specified identifier. + @param anIdentifier the identifier + @return the initialized table column +*/ +- (id)initWithIdentifier:(CPString)anIdentifier +{ + self = [super init]; + + if (self) + { + [self _init]; + + _identifier = anIdentifier; + + _width = 40.0; + _minWidth = 8.0; + _maxWidth = 1000.0; + + var dataView = [[CPTextField alloc] initWithFrame:CPRectMakeZero()]; + [dataView setValue:[CPColor whiteColor] forThemeAttribute:"text-color" inState:CPThemeStateHighlighted]; + + [self setDataView:dataView]; + + _headerView = [[CPTextField alloc] initWithFrame:CPRectMakeZero()]; + [_headerView setBackgroundColor:[CPColor greenColor]]; + } + + return self; +} + +- (void)_init +{ + _dataViewData = {}; + _dataViewForView = {}; + _purgableInfosForDataView = {}; +} + +/*! + Sets the table column's identifier + @param anIdentifier the new identifier +*/ +- (void)setIdentifier:(CPString)anIdentifier +{ + _identifier = anIdentifier; +} + +/*! + Returns the table column's identifier +*/ +- (CPString)identifier +{ + return _identifier; +} + +// Setting the CPTableView +/*! + Sets the table's view. This is called automatically by Cappuccino. + @param aTableView the new table view +*/ +- (void)setTableView:(CPTableView)aTableView +{ + _tableView = aTableView; +} + +/*! + Returns the column's table view. +*/ +- (CPTableView)tableView +{ + return _tableView; +} + +// Controlling size +/*! + Sets the column's width. + @param aWidth the new column width +*/ +- (void)setWidth:(float)aWidth +{ + _width = aWidth; +} + +/*! + Returns the column's width +*/ +- (float)width +{ + return _width; +} + +/*! + Sets column's minimum width. + @param aWidth the new minimum column width +*/ +- (void)setMinWidth:(float)aWidth +{ + if (_width < (_minWidth = aWidth)) + [self setWidth:_minWidth]; +} + +/*! + The column's minimum width +*/ +- (float)minWidth +{ + return _minWidth; +} + +/*! + Sets the column's maximum width. + @param aWidth the new maximum width +*/ +- (void)setMaxWidth:(float)aWidth +{ + if (_width > (_maxmimumWidth = aWidth)) + [self setWidth:_maxWidth]; +} + +/*! + Sets the resizing mask. The mask is one of: +

+CPTableColumnNoResizing;
+CPTableColumnAutoresizingMask;
+CPTableColumnUserResizingMask;
+
+ @param aMask the new resizing mask +*/ +- (void)setResizingMask:(unsigned)aMask +{ + _resizingMask = aMask; +} + +/*! + Returns the column's resizing mask. One of: +
+CPTableColumnNoResizing;
+CPTableColumnAutoresizingMask;
+CPTableColumnUserResizingMask;
+
+*/ +- (unsigned)resizingMask +{ + return _resizingMask; +} + +/*! + Resizes the column according to the min, max and set width. +*/ +- (void)sizeToFit +{ + var width = CPRectGetWidth([_headerView frame]); + + if (width < _minWidth) + [self setMinWidth:width]; + else if (width > _maxWidth) + [self setMaxWidth:width] + + if (_width != width) + [self setWidth:width]; +} + +/*! + Sets whether the column in this data is editable. + @param aFlag YES means the column data is editable +*/ +- (void)setEditable:(BOOL)aFlag +{ + _isEditable = aFlag; +} + +/*! + Returns YES if the column data is editable. +*/ +- (BOOL)isEditable +{ + return _isEditable; +} + +//Setting the column header view + +/*! + Sets the view that draws the column's header. + @param aHeaderView the view that will draws the column header +*/ + +- (void)setHeaderView:(CPView)aView +{ + _headerView = aView; +} + +/*! + Return the view that draws the column's header +*/ +- (CPView)headerView +{ + return _headerView; +} + +/*! + Sets the data cell that draws rows in this column. +*/ +- (void)setDataCell:(CPView )aView +{ + [self setDataView:aView]; +} + +/* + Sets the data view that draws rows in this column. +*/ +- (void)setDataView:(CPView )aView +{ + if (_dataView) + _dataViewData[[_dataView UID]] = nil; + + _dataView = aView; + _dataViewData[[aView UID]] = [CPKeyedArchiver archivedDataWithRootObject:aView]; +} + +/*! + Returns the data cell that draws rows in this column +*/ +- (CPCell)dataCell +{ + return _dataView; +} + +/* + Returns the data view that draws rows in this column +*/ +- (CPView)dataView +{ + return [self dataCell]; +} + +/*! + By default returns the value from dataCell. This can + be overridden by a subclass to return different cells for different + rows. + @param aRowIndex the index of the row to obtain the cell for +*/ +- (CPCell)dataCellForRow:(int)aRowIndex +{ + return [self dataView]; +} + +- (CPView)dataViewForRow:(int)aRowIndex +{ + return [self dataCellForRow:aRowIndex]; +} +/* +- (void)_markViewAsPurgable:(CPView)aView +{ + var viewUID = [aView UID], + dataViewUID = [_dataViewForView[viewUID] UID]; + + if (!_purgableInfosForDataView[dataViewUID]) + _purgableInfosForDataView[dataViewUID] = [CPDictionary dictionary]; + + [_purgableInfosForDataView[dataViewUID] setObject:aView forKey:viewUID]; +} +*/ +- (void)_markView:(CPView)aView inRow:(unsigned)aRow asPurgable:(BOOL)isPurgable +{ + var viewUID = [aView UID], + dataViewUID = [_dataViewForView[viewUID] UID]; + + if (!_purgableInfosForDataView[dataViewUID]) + { + if (!isPurgable) + return; + + _purgableInfosForDataView[dataViewUID] = {}; + } + + if (!isPurgable) { + if (_purgableInfosForDataView[dataViewUID][viewUID]) + CPLog.warn("removing unpurgable " + _purgableInfosForDataView[dataViewUID][viewUID]); + delete _purgableInfosForDataView[dataViewUID][viewUID]; + } + else + _purgableInfosForDataView[dataViewUID][viewUID] = PurgableInfoMake(aView, aRow); +} + +- (CPView)_newDataViewForRow:(int)aRowIndex avoidingRows:(CPRange)rows +{ + var view = [self dataViewForRow:aRowIndex], + viewUID = [view UID], + purgableInfos = _purgableInfosForDataView[viewUID]; + + if (purgableInfos) + { + for (var key in purgableInfos) + { + var info = purgableInfos[key]; + //if (!CPLocationInRange(PurgableInfoRow(info), rows)) + //{ + //CPLog.debug("yes, a purged view is usable, its called: " + PurgableInfoView(info)); + delete purgableInfos[key]; + return PurgableInfoView(info); + //} + //else + // CPLog.warn("avoiding"); + } + } + + // if we haven't cached an archive of the data view, do it now + if (!_dataViewData[viewUID]) + _dataViewData[viewUID] = [CPKeyedArchiver archivedDataWithRootObject:view]; + + // unarchive the data view cache + var newView = [CPKeyedUnarchiver unarchiveObjectWithData:_dataViewData[viewUID]]; + + // map the new view's UID to it's data view prototype + _dataViewForView[[newView UID]] = view; + + CPLog.warn("creating cell: %s", newView); + + return newView; +} + +- (void)_purge +{ + for (var viewUID in _purgableInfosForDataView) + { + var purgableInfos = _purgableInfosForDataView[viewUID]; + + for (var key in purgableInfos) + { + var view = PurgableInfoView(purgableInfos[key]); + + if (!view) + CPLog.info("key="+key+" view=" + view + " purgableInfos[key]="+purgableInfos[key]) + else if (view._superview) { + //CPLog.error("PURGING: (removing)" + view); + //[view removeFromSuperview]; + [view setHidden:YES]; + } + //else + // CPLog.warn("PURGING: (already removed)" + view); + + //delete purgableInfos[key]; + } + } +} + +@end + + +var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey", + CPTableColumnHeaderViewKey = @"CPTableColumnHeaderViewKey", + CPTableColumnDataViewKey = @"CPTableColumnDataViewKey", + CPTableColumnWidthKey = @"CPTableColumnWidthKey", + CPTableColumnMinWidthKey = @"CPTableColumnMinWidthKey", + CPTableColumnMaxWidthKey = @"CPTableColumnMaxWidthKey", + CPTableColumnResizingMaskKey = @"CPTableColumnResizingMaskKey"; + +@implementation CPTableColumn (CPCoding) + +- (id)initWithCoder:(CPCoder)aCoder +{ + [self _init]; + + _identifier = [aCoder decodeObjectForKey:CPTableColumnIdentifierKey]; + + [self setHeaderView:[aCoder decodeObjectForKey:CPTableColumnHeaderViewKey]]; + [self setDataView:[aCoder decodeObjectForKey:CPTableColumnDataViewKey]]; + + _width = [aCoder decodeFloatForKey:CPTableColumnWidthKey]; + _minWidth = [aCoder decodeFloatForKey:CPTableColumnMinWidthKey]; + _maxWidth = [aCoder decodeFloatForKey:CPTableColumnMaxWidthKey]; + + _resizingMask = [aCoder decodeBoolForKey:CPTableColumnResizingMaskKey]; + + return self; +} + +- (void)encodeWithCoder:(CPCoder)aCoder +{ + [aCoder encodeObject:_identifier forKey:CPTableColumnIdentifierKey]; + + [aCoder encodeObject:_headerView forKey:CPTableColumnHeaderViewKey]; + [aCoder encodeObject:_dataView forKey:CPTableColumnDataViewKey]; + + [aCoder encodeObject:_width forKey:CPTableColumnWidthKey]; + [aCoder encodeObject:_minWidth forKey:CPTableColumnMinWidthKey]; + [aCoder encodeObject:_maxWidth forKey:CPTableColumnMaxWidthKey]; + + [aCoder encodeObject:_resizingMask forKey:CPTableColumnResizingMaskKey]; +} + +@end diff --git a/AppKit/OLDCPTableView.j b/AppKit/OLDCPTableView.j new file mode 100644 index 000000000..02b2e5cd9 --- /dev/null +++ b/AppKit/OLDCPTableView.j @@ -0,0 +1,1302 @@ +/* + * CPTableView.j + * AppKit + * + * Created by Francisco Tolmasky. + * Copyright 2008, 280 North, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * 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 "CPControl.j" +@import "CPTableColumn.j" + +@import "CPColor.j" +@import "CPTextField.j" + +#define ROW_HEIGHT(aRow) (_hasVariableHeightRows ? _rowHeights[aRow] : _rowHeight) +#define ROW_MIN_Y(aRow) (_hasVariableHeightRows ? _rowMinYs[aRow] : (aRow * (_rowHeight + _intercellSpacing.height))) + +CPTableViewColumnDidMoveNotification = "CPTableViewColumnDidMoveNotification"; +CPTableViewColumnDidResizeNotification = "CPTableViewColumnDidResizeNotification"; +CPTableViewSelectionDidChangeNotification = "CPTableViewSelectionDidChangeNotification"; +CPTableViewSelectionIsChangingNotification = "CPTableViewSelectionIsChangingNotification"; + +var _CPTableViewWillDisplayCellSelector = 1 << 0, + _CPTableViewShouldSelectRowSelector = 1 << 1, + _CPTableViewShouldSelectTableColumnSelector = 1 << 2, + _CPTableViewSelectionShouldChangeSelector = 1 << 3, + _CPTableViewShouldEditTableColumnSelector = 1 << 4, + _CPTableViewSelectionIndexesForProposedSelectionSelector = 1 << 5, + _CPTableViewHeightOfRowSelector = 1 << 6; + +/* + @ingroup appkit + + This class is not yet stable. + + CPTableView is located within the AppKit framework and is used to display tables. + It uses a delegate model for getting its data i.e. you give it an object that provides + it with the data it should display. + + @ignore +*/ +@implementation CPTableView : CPControl +{ + // Archived: + + id _dataSource; + id _delegate; + + //CPTableHeaderView _headerView; + //CPView _cornerView; + + CPArray _tableColumns; + + CPIndexSet _selectedRowIndexes; + //CPArray _selectedColumns; + + float _rowHeight; + CGSize _intercellSpacing; + + BOOL _allowsMultipleSelection; + BOOL _allowsEmptySelection; + //BOOL _allowsColumnReordering; + //BOOL _allowsColumnResizing; + //BOOL _allowsColumnSelection; + //BOOL _autoresizesAllColumnsToFit; + + //CPColor _gridColor; + //BOOL _drawsGrid; + + SEL _doubleAction; + + // Not archived: + + int _delegateSelectorsCache; + + //CPScrollView _scrollView; + + unsigned _numberOfRows; + //unsigned _numberOfColumns; + + BOOL _hasVariableHeightRows; + + // Heights + float _columnHeight; // calculated + + CPArray _rowHeights; + CPArray _rowMinYs; + + CPArray _tableCells; + CPArray _tableColumnViews; + + // Caching + Object _dataViewCache; + CPArray _objectValueCache; + + CPRange _visibleRows; + CPRange _visibleColumns; + + CPRange _populatedRows; + CPRange _populatedColumns; + + // Selection + CPIndexSet _previousSelectedRowIndexes; + int _selectionStartRow; + int _selectionModifier; + + CPIndexSet _currentlySelected; + CPArray _selectionViews; + CPArray _selectionViewsPool; + + CPDate _scrollTimer; +} + ++ (void)initialize +{ + +} + +- (id)initWithFrame:(CGRect)aFrame +{ + self = [super initWithFrame:aFrame]; + + if (self) + { + [self _init]; + } + + return self; +} + +- (void)_init +{ + _tableColumns = []; + //_numberOfColumns = 0; + + _selectedRowIndexes = [CPIndexSet indexSet]; + + _rowHeight = 17.0; + _intercellSpacing = CPSizeMake(3.0, 2.0); + + _allowsMultipleSelection = YES; + _allowsEmptySelection = YES; + + + _tableCells = []; + _tableColumnViews = []; + + _dataViewCache = {}; + _objectValueCache = []; + + _visibleRows = CPMakeRange(0, 0); + _visibleColumns = CPMakeRange(0, 0); + + _rowHeights = []; + _rowMinYs = []; +} + +/* + Returns the table's column height +*/ +- (float)_columnHeight +{ + return _columnHeight;//_numberOfRows * (_rowHeight + _intercellSpacing.height); +} + +- (void)newCellForRow:(unsigned)aRowIndex column:(unsigned)aColumnIndex avoidingRows:(CPRange)rows +{ + var dataView = [_tableColumns[aColumnIndex] _newDataViewForRow:aRowIndex avoidingRows:rows]; + + [dataView setFrame:CGRectMake(0.0, ROW_MIN_Y(aRowIndex), [_tableColumns[aColumnIndex] width], ROW_HEIGHT(aRowIndex))]; + + if ([dataView respondsToSelector:@selector(highlight:)]) + [dataView highlight:[_selectedRowIndexes containsIndex:aRowIndex]]; + + if (!_objectValueCache[aColumnIndex]) + _objectValueCache[aColumnIndex] = []; + + // We may be storing 0 after all! + if (_objectValueCache[aColumnIndex][aRowIndex] === undefined) + _objectValueCache[aColumnIndex][aRowIndex] = [_dataSource tableView:self objectValueForTableColumn:_tableColumns[aColumnIndex] row:aRowIndex]; + + [dataView setObjectValue:_objectValueCache[aColumnIndex][aRowIndex]]; + + return dataView; +} + +- (void)clearCells +{ + var columnEnd = CPMaxRange(_visibleColumns), + rowEnd = CPMaxRange(_visibleRows); + + for (var column = _visibleColumns.location; column < columnEnd; column++) + { + var tableColumn = _tableColumns[column], + tableColumnCells = _tableCells[column]; + + for (var row = _visibleRows.location; row < rowEnd; row++) + { + var cell = tableColumnCells[row]; + if (cell) + { + tableColumnCells[row] = nil; + [tableColumn _markView:cell inRow:row asPurgable:YES]; + } + else + { + CPLog.warn("Missing cell? " + row + "," + column); + } + } + } + + _visibleColumns = CPMakeRange(0,0); + _visibleRows = CPMakeRange(0,0); +} + +- (void)loadTableCellsInRect:(CGRect)aRect +{ + if (!_dataSource) + return; + + // Determine new visible rows and columns. + + var rowStart = MAX(0, [self _rowAtY:CGRectGetMinY(aRect)] - 1), + rowEnd = MIN(_numberOfRows, [self _rowAtY:CGRectGetMaxY(aRect)] + 1), + + visibleRows = CPMakeRange(rowStart, rowEnd - rowStart), + + columnStart = MAX(0, [self _columnAtX:CGRectGetMinX(aRect)]), + columnEnd = MIN(_tableColumns.length, [self _columnAtX:CGRectGetMaxX(aRect)] + 1), + + visibleColumns = CPMakeRange(columnStart, columnEnd - columnStart); + + if (CPEqualRanges(_visibleRows, visibleRows) && CPEqualRanges(_visibleColumns, visibleColumns)) + return; + + var unionVisibleRows = CPUnionRange(_visibleRows, visibleRows), + unionVisibleColumns = CPUnionRange(_visibleColumns, visibleColumns); + + + // Determine whether to use 2 sweeps or one. If we have lots of overlap of cells, use just one. + if (unionVisibleRows.length * unionVisibleColumns.length <= + (_visibleRows.length * _visibleColumns.length) + (visibleRows.length * visibleColumns.length)) + { + //CPLog.info("single sweep"); + + var cEnd = CPMaxRange(unionVisibleColumns), + rEnd = CPMaxRange(unionVisibleRows), + cell; + + for (var column = unionVisibleColumns.location; column < cEnd; ++column) + { + var tableColumn = _tableColumns[column], + tableColumnCells = _tableCells[column], + columnIsVisible = CPLocationInRange(column, visibleColumns), + newCells = []; + + for (var row = unionVisibleRows.location; row < rEnd; ++row) + { + if (cell = tableColumnCells[row]) + { + if (!columnIsVisible || !CPLocationInRange(row, visibleRows)) + { + tableColumnCells[row] = nil; + [tableColumn _markView:cell inRow:row asPurgable:YES]; + } + } + else + { + newCells.push(row); + } + } + + while (newCells.length > 0) + { + var row = newCells.pop(); + + tableColumnCells[row] = [self newCellForRow:row column:column avoidingRows:visibleRows]; + + if (!tableColumnCells[row]._superview) + [_tableColumnViews[column] addSubview:tableColumnCells[row]]; + else if (tableColumnCells[row]._isHidden) + [tableColumnCells[row] setHidden:NO]; + } + + [tableColumn _purge]; + } + } + else { + //CPLog.info("double sweep"); + + // first sweep: remove old cells + + var cEnd = CPMaxRange(_visibleColumns), + rEnd = CPMaxRange(_visibleRows), + cell; + + for (var column = _visibleColumns.location; column < cEnd; ++column) + { + var tableColumn = _tableColumns[column], + tableColumnCells = _tableCells[column], + columnIsVisible = CPLocationInRange(column, visibleColumns); + + for (var row = _visibleRows.location; row < rEnd; ++row) + { + if (cell = tableColumnCells[row]) + { + if (!columnIsVisible || !CPLocationInRange(row, visibleRows)) + { + tableColumnCells[row] = nil; + [tableColumn _markView:cell inRow:row asPurgable:YES]; + } + } + } + } + + // second sweep: add new cells + + var cEnd = CPMaxRange(visibleColumns), + rEnd = CPMaxRange(visibleRows); + + for (var column = visibleColumns.location; column < cEnd; ++column) + { + var tableColumn = _tableColumns[column], + tableColumnCells = _tableCells[column]; + + for (var row = visibleRows.location; row < rEnd; ++row) + { + tableColumnCells[row] = [self newCellForRow:row column:column avoidingRows:visibleRows]; + + if (!tableColumnCells[row]._superview) + [_tableColumnViews[column] addSubview:tableColumnCells[row]]; + else if (tableColumnCells[row]._isHidden) + [tableColumnCells[row] setHidden:NO]; + } + + [tableColumn _purge]; + } + } + + + _visibleRows = visibleRows; + _visibleColumns = visibleColumns; + +} + +// Setting display attributes +/* + Sets the width and height between cell. The default is (3.0, 2.0) (width, height). + @param the width and height spacing +*/ +- (void)setIntercellSpacing:(CGSize)aSize +{ + if (_intercellSpacing.width != aSize.width) + { + var i = 1, + delta = aSize.width - _intercellSpacing.width; + total = delta; + + for (; i < _tableColumns.length; ++i, total += delta) + { + var origin = [_tableColumnViews[i] frame].origin; + [_tableColumnViews[i] setFrameOrigin:CGPointMake(origin.x + total, origin.y)]; + } + } + + if (_intercellSpacing.height != aSize.height) + { + var i = 0; + + for (; i < _tableColumns.length; ++i, total += delta) + { + [_tableColumnViews[i] setFrameSize:CGSizeMake([_tableColumnViews[i] width], _numberOfRows * (_rowHeight + _intercellSpacing.height))]; + + var j = 1, + y = _rowHeight + _intercellSpacing.height; + + for (; j < _numberOfRows; ++i, y += _rowHeight + _intercellSpacing.height) + { + if (!_tableCells[i][j]) + continue; + + [_tableCells[i][j] setFrameOrigin:CPPointMake(0.0, y)]; + } + } + + // FIXME: variable height rows + } + + _intercellSpacing = CPSizeCreateCopy(aSize); +} + +/* + Returns the width and height of the space between + cells. +*/ +- (CGSize)intercellSpacing +{ + return _intercellSpacing; +} + +/* + Sets the height of table rows + @param aRowHeight the new height of the table rows +*/ +- (void)setRowHeight:(unsigned)aRowHeight +{ + if (_rowHeight == aRowHeight) + return; + + _rowHeight = aRowHeight; + + // don't perform adjustments if we're using variable height rows + if (_hasVariableHeightRows) + return; + + for (var row = 0; row < _numberOfRows; ++row) + for (var column = 0; column < _tableColumns.length; ++column) + [_tableCells[column][row] setFrameOrigin:CPPointMake(0.0, row * (_rowHeight + _intercellSpacing.height))]; +} + +/* + Returns the height of a table row +*/ +- (unsigned)rowHeight +{ + return _rowHeight; +} + +/* + Adds a column to the table + @param aTableColumn the column to be added +*/ +- (void)addTableColumn:(CPTableColumn)aTableColumn +{ + var i = 0, + x = _tableColumns.length ? CPRectGetMaxX([self rectOfColumn:_tableColumns.length - 1]) + _intercellSpacing.width : 0.0, + tableColumnView = [[CPView alloc] initWithFrame:CPRectMake(x, 0.0, [aTableColumn width], [self _columnHeight])], + tableColumnCells = []; + + [_tableColumns addObject:aTableColumn]; + [_tableColumnViews addObject:tableColumnView]; + +// [tableColumnView setBackgroundColor:[CPColor greenColor]]; + + [self addSubview:tableColumnView]; + + [_tableCells addObject:tableColumnCells]; + + // TODO: do we really need to initialize this, or is undefined good enough? + for (; i < _numberOfRows; ++i) + _tableCells[_tableColumns.length-1][i] = nil; + + //++_numberOfColumns; +} + +/* + Removes a column from the table + @param aTableColumn the column to remove +*/ +- (void)removeTableColumn:(CPTableColumn)aTableColumn +{ + var frame = [self frame], + width = [aTableColumn width] + _intercellSpacing.width, + index = [_tableColumns indexOfObjectIdenticalTo:aTableColumn]; + + // Remove the column view and all the cell views from the view hierarchy. + [_tableColumnViews[i] removeFromSuperview]; + + [_tableCells removeObjectAtIndex:index]; + [_tableColumns removeObjectAtIndex:index]; + [_tableColumnViews removeObjectAtIndex:index]; + + // Shift remaining column views to the left. + for (; index < _tableColumns.length; ++ index) + [_tableColumnViews[index] setFrameOrigin:CPPointMake(CPRectGetMinX([_tableColumnViews[index] frame]) - width, 0.0)] + + // Resize ourself. + [self setFrameSize:CPSizeMake(CPRectGetWidth(frame) - width, CPRectGetHeight(frame))]; +} + +/* + Not yet implemented. Changes the position of the column in + the table. + @param fromIndex the original index of the column + @param toIndex the desired index of the column +*/ +- (void)moveColumn:(unsigned)fromIndex toColumn:(unsinged)toIndex +{ + if (fromIndex == toIndex) + return; +// FIXME: IMPLEMENT +} + +/* + Returns an array containing the table's CPTableColumns. +*/ +- (CPArray)tableColumns +{ + return _tableColumns; +} + +/* + Returns the first CPTableColumn equal to the given object (as determined by the "isEqual:" selector), or nil if none exists. + @param anObject the object to look for +*/ +- (CPTableColumn)tableColumnWithIdentifier:(id)anObject +{ + for (var i = 0; i < _tableColumns.length; i++) + if ([_tableColumns[i] isEqual:anObject]) + return _tableColumns[i]; + return nil; +} + +// Getting the dimensions of the table +/* + Returns the number of columns in the table +*/ +- (int)numberOfColumns +{ + return _tableColumns.length; +} + +/* + Returns the number of rows in the table +*/ +- (int)numberOfRows +{ + return _numberOfRows; +} + +/* + Adjusts the size of the table and it's header view. +*/ +- (void)tile +{ + var HEIGHT = 10.0; + +// [_headerView setFrame:CPRectMake(0.0, 0.0, CPRectGetWidth([self bounds]), HEIGHT)]; +// [_scrollView setFrame:CPRectMake(0.0, HEIGHT, CPRectGetWidth([self bounds]), CPRectGetHeight([self bounds]) - HEIGHT)]; +} + +/* + Sets the object that is used to obtain the table data. The data source must implement the following + methods: +
+- (int)numberOfRowsInTableView:(CPTableView)aTableView
+- (id)tableView:(CPTableView)aTableView objectValueForTableColumn:(CPTableColumn)aTableColumn row:(int)rowIndex
+
+ @param aDataSource the object with the table data + @throws CPInternalInconsistencyException if aDataSource doesn't implement all the required methods +*/ +- (void)setDataSource:(id)aDataSource +{ + if (![aDataSource respondsToSelector:@selector(numberOfRowsInTableView:)]) + [CPException raise:CPInternalInconsistencyException reason:"Data source doesn't support 'numberOfRowsInTableView:'"]; + if (![aDataSource respondsToSelector:@selector(tableView:objectValueForTableColumn:row:)]) + [CPException raise:CPInternalInconsistencyException reason:"Data source doesn't support 'tableView:objectValueForTableColumn:row:'"]; + + _dataSource = aDataSource; + + [self reloadData]; +} + +/* + Returns the object that has access to the table data +*/ +- (id)dataSource +{ + return _dataSource; +} + + +- (id)delegate +{ + return _delegate; +} + + +/*! + Sets the delegate for the tableview. +*/ +- (void)setDelegate:(id)aDelegate +{ + if (_delegate === aDelegate) + return; + + var notificationCenter = [CPNotificationCenter defaultCenter]; + + if ([_delegate respondsToSelector:@selector(tableViewColumnDidMove:)]) + [notificationCenter removeObserver:_delegate name:CPTableViewColumnDidMoveNotification object:self]; + if ([_delegate respondsToSelector:@selector(tableViewColumnDidResize:)]) + [notificationCenter removeObserver:_delegate name:CPTableViewColumnDidResizeNotification object:self]; + if ([_delegate respondsToSelector:@selector(tableViewSelectionDidChange:)]) + [notificationCenter removeObserver:_delegate name:CPTableViewSelectionDidChangeNotification object:self]; + if ([_delegate respondsToSelector:@selector(tableViewSelectionIsChanging:)]) + [notificationCenter removeObserver:_delegate name:CPTableViewSelectionIsChangingNotification object:self]; + + _delegate = aDelegate; + + if ([_delegate respondsToSelector:@selector(tableViewColumnDidMove:)]) + [notificationCenter addObserver:_delegate selector:@selector(tableViewColumnDidMove:) name:CPTableViewColumnDidMoveNotification object:self]; + if ([_delegate respondsToSelector:@selector(tableViewColumnDidResize:)]) + [notificationCenter addObserver:_delegate selector:@selector(tableViewColumnDidResize:) name:CPTableViewColumnDidResizeNotification object:self]; + if ([_delegate respondsToSelector:@selector(tableViewSelectionDidChange:)]) + [notificationCenter addObserver:_delegate selector:@selector(tableViewSelectionDidChange:) name:CPTableViewSelectionDidChangeNotification object:self]; + if ([_delegate respondsToSelector:@selector(tableViewSelectionIsChanging:)]) + [notificationCenter addObserver:_delegate selector:@selector(tableViewSelectionIsChanging:) name:CPTableViewSelectionIsChangingNotification object:self]; + + _delegateSelectorsCache = 0; + + if ([_delegate respondsToSelector:@selector(tableView:willDisplayCell:forTableColumn:row:)]) + _delegateSelectorsCache |= _CPTableViewWillDisplayCellSelector; + if ([_delegate respondsToSelector:@selector(tableView:shouldSelectRow:)]) + _delegateSelectorsCache |= _CPTableViewShouldSelectRowSelector; + if ([_delegate respondsToSelector:@selector(tableView:shouldSelectTableColumn:)]) + _delegateSelectorsCache |= _CPTableViewShouldSelectTableColumnSelector; + if ([_delegate respondsToSelector:@selector(selectionShouldChangeInTableView:)]) + _delegateSelectorsCache |= _CPTableViewSelectionShouldChangeSelector; + if ([_delegate respondsToSelector:@selector(tableView:shouldEditTableColumn:row:)]) + _delegateSelectorsCache |= _CPTableViewShouldEditTableColumnSelector; + if ([_delegate respondsToSelector:@selector(tableView:selectionIndexesForProposedSelection:)]) + _delegateSelectorsCache |= _CPTableViewSelectionIndexesForProposedSelectionSelector; + if ([_delegate respondsToSelector:@selector(tableView:heightOfRow:)]) + { + _delegateSelectorsCache |= _CPTableViewHeightOfRowSelector; + _hasVariableHeightRows = YES; + } + else + _hasVariableHeightRows = NO; +} + + +/* + Tells the table view that the number of rows in the table + has changed. +*/ +- (void)noteNumberOfRowsChanged +{ + var numberOfRows = [_dataSource numberOfRowsInTableView:self]; + + if (_numberOfRows != numberOfRows) + { + _numberOfRows = numberOfRows; + + [self _recalculateColumnHeight]; + } +} + +- (void)noteHeightOfRowsWithIndexesChanged:(CPIndexSet)indexSet +{ + // FIXME: more efficient version is possible since we know which indexes changes + [self _recalculateColumnHeight]; +} + +/* + Returns the rectangle bounding the specified row. + @param aRowIndex the row to obtain a rectangle for + @return the bounding rectangle +*/ +- (CGRect)rectOfRow:(int)aRowIndex +{ + return CPRectMake(0.0, ROW_MIN_Y(aRowIndex), CPRectGetWidth([self bounds]), ROW_HEIGHT(aRowIndex)); +} + +/* + Returns the rectangle bounding the specified column + @param aColumnIndex the column to obtain a rectangle for + @return the bounding column +*/ +- (CGRect)rectOfColumn:(int)aColumnIndex +{ + return [_tableColumnViews[aColumnIndex] frame]; +} + +/* + Adjusts column widths to make them all visible at once. Same as tile. +*/ +- (void)sizeToFit +{ +// [self tile]; +} + +- (void)_recalculateColumnHeight +{ + var oldColumnHeight = _columnHeight; + + if (_hasVariableHeightRows) + { + _rowMinYs[0] = 0; + for (var row = 0; row < _numberOfRows; row++) + { + _rowHeights[row] = [_delegate tableView:self heightOfRow:row]; + _rowMinYs[row+1] = _rowMinYs[row] + _rowHeights[row] + _intercellSpacing.height; + } + _columnHeight = _rowMinYs[_numberOfRows]; // last index is one more than last row, and is the total column height + } + else + _columnHeight = _numberOfRows * (_rowHeight + _intercellSpacing.height); + + var count = _tableColumnViews.length; + + while (count--) + [_tableColumnViews[count] setFrameSize:CGSizeMake([_tableColumns[count] width], _columnHeight)]; + + [self setFrameSize:CGSizeMake(CGRectGetWidth([self frame]), _columnHeight)]; +} + +- (CGRect)visibleRectInParent +{ + var superview = [self superview]; + + if (!superview) + return [self bounds]; + + return [self convertRect:CGRectIntersection([superview bounds], [self frame]) fromView:superview]; +} + +/* + Reloads the data from the dataSource. This is an + expensive method, so use it lightly. +*/ +- (void)reloadData +{ + var oldNumberOfRows = _numberOfRows; + + _numberOfRows = [_dataSource numberOfRowsInTableView:self]; + + if (oldNumberOfRows != _numberOfRows) + { + [self _recalculateColumnHeight]; + [self setFrameSize:CGSizeMake(CGRectGetWidth([self frame]), [self _columnHeight])]; + } + + _objectValueCache = []; + + [self clearCells]; + + [self setNeedsLayout]; +} + +- (void)layoutSubviews +{ + [self loadTableCellsInRect:[self visibleRectInParent]]; +} + +- (void)displaySoon +{ + [_scrollTimer invalidate]; + _scrollTimer = [CPTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(displayNow) userInfo:nil repeats:NO]; +} + +- (void)displayNow +{ + [self setNeedsLayout]; +} + +- (void)viewDidMoveToSuperview +{ + [[[self enclosingScrollView] contentView] setPostsBoundsChangedNotifications:YES]; + + [[CPNotificationCenter defaultCenter] + addObserver:self + selector:@selector(viewBoundsChanged:) + name:CPViewBoundsDidChangeNotification + object:[[self enclosingScrollView] contentView]]; +} + +- (void)viewBoundsChanged:(CPNotification)aNotification +{ + //CPLog.info(_cmd + CPStringFromRect([[[self enclosingScrollView] contentView] bounds])); + //objj_debug_print_backtrace(); + //[self setNeedsLayout]; + [self displayNow]; +} + +/* +- (void)setAllowsColumnReordering:(BOOL)allowsColumnReordering +{ + if (_allowsColumnReordering === _allowsColumnReordering) + return; + + _allowsColumnReordering = allowsColumnReordering; +} +- (void)allowsColumnReordering +{ + return _allowsColumnReordering; +} + +- (void)setAllowsColumnResizing:(BOOL)allowsColumnResizing +{ + if (_allowsColumnResizing === allowsColumnResizing) + return; + + _allowsColumnResizing = allowsColumnResizing; +} +- (void)allowsColumnResizing +{ + return _allowsColumnResizing; +} + +- (void)setAllowsColumnSelection:(BOOL)allowsColumnSelection +{ + if (_allowsColumnSelection === allowsColumnSelection) + return; + + _allowsColumnSelection = allowsColumnSelection; +} +- (void)allowsColumnSelection +{ + return _allowsColumnSelection; +} +*/ + +- (void)setAllowsMultipleSelection:(BOOL)allowsMultipleSelection +{ + if (_allowsMultipleSelection === allowsMultipleSelection) + return; + + _allowsMultipleSelection = allowsMultipleSelection; + + // TODO: more stuff? +} +- (void)allowsMultipleSelection +{ + return _allowsMultipleSelection; +} + +- (void)setAllowsEmptySelection:(BOOL)allowsEmptySelection +{ + if (_allowsEmptySelection === allowsEmptySelection) + return; + + _allowsEmptySelection = allowsEmptySelection; +} +- (void)allowsEmptySelection +{ + return _allowsEmptySelection; +} + + +/* + Returns the index of the row at the given point, or CPNotFound (-1) if it is out of range. + @param aPoint the point + @return the index of the row at aPoint +*/ +- (int)rowAtPoint:(CGPoint)aPoint +{ + var index = [self _rowAtY:aPoint.y] + + if (index >= 0 && index < _numberOfRows) + return index; + else + return CPNotFound; +} + +- (int)columnAtPoint:(CGPoint)aPoint +{ + var index = [self _columnAtX:aPoint.x] + + if (index >= 0 && index < _tableColumns.length) + return index; + else + return CPNotFound; +} + +/* + @ignore + + Internal version takes a Y value, returns an index, or -1 if its beyond the min, or numberOfRows if it's beyond the max +*/ +- (int)_rowAtY:(float)y +{ + if (_hasVariableHeightRows) + { + var a = 0, + b = _numberOfRows; + + if (y < _rowMinYs[0]) + return -1; + if (y >= _rowMinYs[_rowMinYs.length-1]) + return _numberOfRows; + + // binary search + while (true) + { + var half = a + Math.floor((b - a) / 2); + + if (y < _rowMinYs[half]) + b = half; + else if (half < _numberOfRows-1 && y >= _rowMinYs[half+1]) + a = half; + else + return half; + } + } + else + return FLOOR(y / (_rowHeight + _intercellSpacing.height)); +} + +/* + @ignore + + Internal version takes a X value, returns an index, or -1 if its beyond the min, or numberOfColumns if it's beyond the max +*/ +- (int)_columnAtX:(float)x +{ + var a = 0, + b = _tableColumns.length; + + var last = [_tableColumnViews[_tableColumns.length-1] frame]; + if (x < [_tableColumnViews[0] frame].origin.x) + return -1; + if (x >= last.origin.x + last.size.width) + return _tableColumns.length; + + // binary search + while (true) + { + var half = a + Math.floor((b - a) / 2); + + if (x < [_tableColumnViews[half] frame].origin.x) + b = half; + else if (half < _tableColumns.length-1 && x >= [_tableColumnViews[half+1] frame].origin.x) + a = half; + else + return half; + } +} + +/* + Selects the specified row indexes, optionally adding to existing selection + @param indexes the indexes to select + @param extend whether or not to add to the existing selection +*/ +- (void)selectRowIndexes:(CPIndexSet)indexes byExtendingSelection:(BOOL)extend +{ + // FIXME: should this be subject to the delegate filters, etc? + + if (extend) + _selectedRowIndexes = [[_selectedRowIndexes copy] addIndexes:indexes]; + else if ([indexes count] > 0 || _allowsEmptySelection) + _selectedRowIndexes = [indexes copy]; + + [self _drawSelection]; +} + +/* + Returns a CPIndexSet of the selected rows + @return indexes of the selected rows +*/ +- (CPIndexSet)selectedRowIndexes +{ + return _selectedRowIndexes; +} + +/* + Returns the number of selected rows + @return number of selected rows +*/ +- (int)numberOfSelectedRows +{ + return [_selectedRowIndexes count]; +} + + +/* + Deselects all rows if allowsEmptySelection is true. If delegate responds to "selectionShouldChangeInTableView:", asks if it should chnage. + Sends the CPTableViewSelectionDidChangeNotification on deselection. + @param the sender in a target/action +*/ +- (void)deselectAll:(id)sender +{ + if (!_allowsEmptySelection || [_selectedRowIndexes count] === 0 || + ((_delegateSelectorsCache & _CPTableViewSelectionShouldChangeSelector) && ![_delegate selectionShouldChangeInTableView:self])) + return; + + [self selectRowIndexes:[CPIndexSet indexSet] byExtendingSelection:NO]; + [[CPNotificationCenter defaultCenter] postNotificationName:CPTableViewSelectionDidChangeNotification object:self userInfo:nil]; +} + +- (void)editColumn:(int)columnIndex row:(int)rowIndex withEvent:(CPEvent)theEvent select:(BOOL)flag +{ + +} + +/* + @ignore +*/ +- (void)_updateSelectionWithMouseAtRow:(int)aRow +{ + // Make a preliminary new selection + var newSelection; + if (_allowsMultipleSelection) + newSelection = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(MIN(aRow, _selectionStartRow), ABS(aRow-_selectionStartRow)+1)]; + else if (aRow >= 0 && aRow < _numberOfRows) + newSelection = [CPIndexSet indexSetWithIndex:aRow]; + else + newSelection = [CPIndexSet indexSet]; + + // If cmd/ctrl was held down XOR the old selection with the proposed selection + if (_allowsMultipleSelection && _selectionModifier & (CPCommandKeyMask | CPControlKeyMask | CPAlternateKeyMask)) + { + // A = newSelection, B = _previousSelectedRowIndexes + // (A intersection B) = (A - (A - B)) + var intersection = [newSelection copy], + difference = [newSelection copy]; + [difference removeIndexes:_previousSelectedRowIndexes]; + [intersection removeIndexes:difference] + + // (A xor B) = (A + B) - (A intersection B) + [newSelection addIndexes:_previousSelectedRowIndexes]; + [newSelection removeIndexes:intersection]; + + // FIXME: if multiple selection is off, and we cmd/ctrl click the previously selected row, then deselect it. + } + + // if the new selection is different than the old selection + if (![newSelection isEqualToIndexSet:_selectedRowIndexes]) + { + // ask the delegate if we should change the selection + if ((_delegateSelectorsCache & _CPTableViewSelectionShouldChangeSelector) && ![_delegate selectionShouldChangeInTableView:self]) + return; + + // ask the delegate which indexes can be selected. selectionIndexesForProposedSelection is faster than shouldSelectRow + if (_delegateSelectorsCache & _CPTableViewSelectionIndexesForProposedSelectionSelector) + newSelection = [_delegate tableView:self selectionIndexesForProposedSelection:newSelection]; + else if (_delegateSelectorsCache & _CPTableViewShouldSelectRowSelector) + { + var indexes = []; + [newSelection getIndexes:indexes maxCount:Number.MAX_VALUE inIndexRange:nil]; + for (var i = 0; i < indexes.length; i++) + if (![_delegate tableView:self shouldSelectRow:indexes[i]]) + [newSelection removeIndex:indexes[i]]; + } + } + + // if empty selection is not allowed and the new selection has nothing selected, abort + if (!_allowsEmptySelection && [newSelection count] === 0) + return; + + // if the new selection is *still* different, and update the selection and send a notification + if (![newSelection isEqualToIndexSet:_selectedRowIndexes]) + { + [self selectRowIndexes:newSelection byExtendingSelection:NO]; + [[CPNotificationCenter defaultCenter] postNotificationName:CPTableViewSelectionIsChangingNotification object:self userInfo:nil]; + } +} + +/* + @ignore +*/ +- (void)mouseDown:(CPEvent)anEvent +{ + [self trackSelection:anEvent]; +} + +/* + Sets the message to be sent to the target when a cell is double clicked + @param aSelector the selector to be performed +*/ +- (void)setDoubleAction:(SEL)aSelector +{ + _doubleAction = aSelector; +} +- (SEL)doubleAction +{ + return _doubleAction; +} + +- (int)clickedColumn +{ + return _clickedColumn; +} +- (int)clickedRow +{ + return _clickedRow; +} + +/* + @ignore +*/ +- (void)trackSelection:(CPEvent)anEvent +{ + var type = [anEvent type], + point = [self convertPoint:[anEvent locationInWindow] fromView:nil], + currentRow = MAX(0, MIN(_numberOfRows-1, [self _rowAtY:point.y])); + + if (type == CPLeftMouseUp) + { + _clickedRow = [self rowAtPoint:point]; + _clickedColumn = [self columnAtPoint:point]; + + if ([anEvent clickCount] === 2) + { + CPLog.warn("edit?!"); + + [self sendAction:_doubleAction to:_target]; + } + else + { + if (![_previousSelectedRowIndexes isEqualToIndexSet:_selectedRowIndexes]) + { + [[CPNotificationCenter defaultCenter] postNotificationName:CPTableViewSelectionDidChangeNotification object:self userInfo:nil]; + } + + [self sendAction:_action to:_target]; + } + + return; + } + + if (type == CPLeftMouseDown) + { + _previousSelectedRowIndexes = _selectedRowIndexes; + _selectionModifier = [anEvent modifierFlags]; + + if (_selectionModifier & CPShiftKeyMask) + _selectionStartRow = (ABS([_previousSelectedRowIndexes firstIndex] - currentRow) < ABS([_previousSelectedRowIndexes lastIndex] - currentRow)) ? + [_previousSelectedRowIndexes firstIndex] : [_previousSelectedRowIndexes lastIndex]; + else + _selectionStartRow = currentRow; + + [self _updateSelectionWithMouseAtRow:currentRow]; + } + else if (type == CPLeftMouseDragged) + { + [self _updateSelectionWithMouseAtRow:currentRow]; + } + + [CPApp setTarget:self selector:@selector(trackSelection:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES]; +} + +/* + @ignore +*/ +- (void)_drawSelection +{ + if (!_currentlySelected) { + _currentlySelected = [CPIndexSet indexSet]; + _selectionViews = []; + _selectionViewsPool = []; + } + + // TODO: we could also remove selections that aren't visible, but then we'll need to run this on every scroll/resize? + + // get array of indexes we can remove + var removeSet = [_currentlySelected copy], + indexesToRemove = []; + [removeSet removeIndexes:_selectedRowIndexes]; + [removeSet getIndexes:indexesToRemove maxCount:Number.MAX_VALUE inIndexRange:nil]; + + // get array of indexes we need to add + var addSet = [_selectedRowIndexes copy], + indexesToAdd = []; + [addSet removeIndexes:_currentlySelected]; + [addSet getIndexes:indexesToAdd maxCount:Number.MAX_VALUE inIndexRange:nil]; + + for (var i = 0; i < indexesToRemove.length; i++) + { + var row = indexesToRemove[i]; + for (var column = 0; column < _tableColumns.length; column++) + if ([_tableCells[column][row] respondsToSelector:@selector(highlight:)]) + [_tableCells[column][row] highlight:NO]; + } + for (var i = 0; i < indexesToAdd.length; i++) + { + var row = indexesToAdd[i]; + for (var column = 0; column < _tableColumns.length; column++) + if ([_tableCells[column][row] respondsToSelector:@selector(highlight:)]) + [_tableCells[column][row] highlight:YES]; + } + + // add each one we need to add, taking the selection views from removed seelctions, the pool, or new + for (var i = 0; i < indexesToAdd.length; i++) + { + var index = indexesToAdd[i], + view; + + if (indexesToRemove.length > 0) + { + view = _selectionViews[indexesToRemove.pop()]; + } + else if (_selectionViewsPool.length > 0) + { + view = _selectionViewsPool.pop(); + [self addSubview:view positioned:CPWindowBelow relativeTo:nil]; + } + else + { + view = [[CPView alloc] init]; + [view setBackgroundColor:[CPColor alternateSelectedControlColor]]; + + [self addSubview:view positioned:CPWindowBelow relativeTo:nil]; + } + + _selectionViews[index] = view; + + var frame = [self rectOfRow:index]; + frame.size.height += _intercellSpacing.height - 1; + //frame.size.width += 500; + + [view setFrame:frame]; + } + + // remove any selections that weren't already reused + for (var i = 0; i < indexesToRemove.length; i++) + { + var row = indexesToRemove[i], + view = _selectionViews[row]; + + [view removeFromSuperview]; + _selectionViewsPool.push(view); + } + + // update the currently selected index set + _currentlySelected = [_selectedRowIndexes copy]; +} + +@end + + +var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey", + CPTableViewDelegateKey = @"CPTableViewDelegateKey", + CPTableViewHeaderViewKey = @"CPTableViewHeaderViewKey", + CPTableViewTableColumnsKey = @"CPTableViewTableColumnsKey", + CPTableViewRowHeightKey = @"CPTableViewRowHeightKey", + CPTableViewIntercellSpacingKey = @"CPTableViewIntercellSpacingKey", + CPTableViewMultipleSelectionKey = @"CPTableViewMultipleSelectionKey", + CPTableViewEmptySelectionKey = @"CPTableViewEmptySelectionKey"; + +@implementation CPTableView (CPCoding) + +- (id)initWithCoder:(CPCoder)aCoder +{ + if (self = [super initWithCoder:aCoder]) + { + [self _init]; + + _dataSource = [aCoder decodeObjectForKey:CPTableViewDataSourceKey]; + _delegate = [aCoder decodeObjectForKey:CPTableViewDelegateKey]; + + _rowHeight = [aCoder decodeFloatForKey:CPTableViewRowHeightKey]; + _intercellSpacing = [aCoder decodeSizeForKey:CPTableViewIntercellSpacingKey]; + + _allowsMultipleSelection = [aCoder decodeBoolForKey:CPTableViewMultipleSelectionKey]; + _allowsEmptySelection = [aCoder decodeBoolForKey:CPTableViewEmptySelectionKey]; + + var tableColumns = [aCoder decodeObjectForKey:CPTableViewTableColumnsKey]; + for (var i = 0; i < tableColumns.length; i++) + [self addTableColumn:tableColumns[i]]; + } + + return self; +} + +- (void)encodeWithCoder:(CPCoder)aCoder +{ + [super encodeWithCoder:aCoder]; + + [aCoder encodeObject:_dataSource forKey:CPTableViewDataSourceKey]; + [aCoder encodeObject:_delegate forKey:CPTableViewDelegateKey]; + + [aCoder encodeObject:_tableColumns forKey:CPTableViewTableColumnsKey]; + + [aCoder encodeFloat:_rowHeight forKey:CPTableViewRowHeightKey]; + [aCoder encodeSize:_intercellSpacing forKey:CPTableViewIntercellSpacingKey]; + + [aCoder encodeBool:_allowsMultipleSelection forKey:CPTableViewMultipleSelectionKey]; + [aCoder encodeBool:_allowsEmptySelection forKey:CPTableViewEmptySelectionKey]; +} + +@end + + + +@implementation CPColor (TableView) + ++ (CPColor)alternateSelectedControlColor +{ + return [[CPColor alloc] _initWithRGBA:[0.22, 0.46, 0.84, 1.0]]; +} + ++ (CPColor)secondarySelectedControlColor +{ + return [[CPColor alloc] _initWithRGBA:[0.83, 0.83, 0.83, 1.0]]; +} + +@end diff --git a/AppKit/Themes/Aristo/ThemeDescriptors.j b/AppKit/Themes/Aristo/ThemeDescriptors.j index bde1704c8..7f747a324 100644 --- a/AppKit/Themes/Aristo/ThemeDescriptors.j +++ b/AppKit/Themes/Aristo/ThemeDescriptors.j @@ -203,7 +203,8 @@ [scroller setValue:knobColor forThemeAttribute:@"knob-color" inState:CPThemeStateVertical]; - [scroller setFloatValue:0.1 knobProportion:0.5]; + [scroller setFloatValue:0.1]; + [scroller setKnobProportion:0.5]; return scroller; } @@ -246,10 +247,11 @@ [_CPCibCustomResource imageResourceWithName:"scroller-horizontal-knob-right.png" size:CGSizeMake(9.0, 15.0)] ] isVertical:NO]); - + [scroller setValue:knobColor forThemeAttribute:@"knob-color"]; - - [scroller setFloatValue:0.1 knobProportion:0.5]; + + [scroller setFloatValue:0.1]; + [scroller setKnobProportion:0.5]; return scroller; } diff --git a/AppKit/_CPCornerView.j b/AppKit/_CPCornerView.j new file mode 100644 index 000000000..5a30dfc90 --- /dev/null +++ b/AppKit/_CPCornerView.j @@ -0,0 +1,18 @@ + +@import "CPView.j" + +@implementation _CPCornerView : CPView +{ +} + +- (id)initWithFrame:(CGRect)aFrame +{ + if (self = [super initWithFrame:aFrame]) + { + [self setBackgroundColor:[CPColor purpleColor]]; + } + + return self; +} + +@end diff --git a/Foundation/CPIndexSet.j b/Foundation/CPIndexSet.j index 932483ca4..ead56ea10 100644 --- a/Foundation/CPIndexSet.j +++ b/Foundation/CPIndexSet.j @@ -23,6 +23,9 @@ @import "CPRange.j" @import "CPObject.j" +#define _CPMaxRange(aRange) ((aRange).location + (aRange).length) +#define _CPMakeRange(aLocation, aLength) { location:(aLocation), length:aLength } +#define _CPMakeRangeCopy(aRange) { location:(aRange).location, length:(aRange).length } /*! @class CPIndexSet @@ -35,7 +38,6 @@ @implementation CPIndexSet : CPObject { unsigned _count; - unsigned _cachedRangeIndex; CPArray _ranges; } @@ -45,7 +47,7 @@ */ + (id)indexSet { - return [[self alloc] init]; + return [[self alloc] init]; } /*! @@ -53,7 +55,7 @@ */ + (id)indexSetWithIndex:(int)anIndex { - return [[self alloc] initWithIndex:anIndex]; + return [[self alloc] initWithIndex:anIndex]; } /*! @@ -62,41 +64,23 @@ */ + (id)indexSetWithIndexesInRange:(CPRange)aRange { - return [[self alloc] initWithIndexesInRange:aRange]; + return [[self alloc] initWithIndexesInRange:aRange]; } // Initializing and Index Set - (id)init { - self = [super init]; - - if (self) - { - _count = 0; - _ranges = []; - _cachedRangeIndex = 0; - } - - return self; + return [self initWithIndexesInRange:_CPMakeRange(0, 0)]; } /*! Initializes the index set with a single index. @return the initialized index set */ -- (id)initWithIndex:(int)anIndex +- (id)initWithIndex:(CPInteger)anIndex { - self = [super init]; - - if (self) - { - _count = 1; - _ranges = [CPArray arrayWithObject:CPMakeRange(anIndex, 1)]; - _cachedRangeIndex = 0; - } - - return self; + return [self initWithIndexesInRange:_CPMakeRange(anIndex, 1)]; } /*! @@ -107,14 +91,17 @@ - (id)initWithIndexesInRange:(CPRange)aRange { self = [super init]; - + if (self) { - _count = aRange.length; - _ranges = [CPArray arrayWithObject:aRange]; - _cachedRangeIndex = 0; + _count = MAX(0, aRange.length); + + if (_count > 0) + _ranges = [aRange]; + else + _ranges = []; } - + return self; } @@ -126,20 +113,19 @@ - (id)initWithIndexSet:(CPIndexSet)anIndexSet { self = [super init]; - + if (self) { _count = [anIndexSet count]; _ranges = []; - _cachedRangeIndex = 0; - - var index = 0, - count = anIndexSet._ranges.length; - - for (; index < count; ++index) - _ranges.push(CPCopyRange(anIndexSet._ranges[index])); + + var otherRanges = anIndexSet._ranges, + otherRangesCount = otherRanges.length; + + while (otherRangesCount--) + _ranges[otherRangesCount] = _CPMakeRangeCopy(otherRanges[otherRangesCount]); } - + return self; } @@ -151,24 +137,26 @@ */ - (BOOL)isEqualToIndexSet:(CPIndexSet)anIndexSet { + if (!anIndexSet) + return NO; + // Comparisons to ourself are always return YES. - if (self == anIndexSet) - return YES; - - var i = 0, - count = _ranges.length; + if (self === anIndexSet) + return YES; + + var rangesCount = _ranges.length, otherRanges = anIndexSet._ranges; - - // If we have a discrepency in the number of ranges or the number of indexes, - // simply return NO. - if (count != otherRanges.length || _count != [anIndexSet count]) - return NO; - - for (; i < count; ++i) - if (!CPEqualRanges(_ranges[i], otherRanges[i])) - return NO; - - return YES; + + // If we have a discrepency in the number of ranges or the number of indexes, + // simply return NO. + if (rangesCount !== otherRanges.length || _count !== anIndexSet._count) + return NO; + + while (rangesCount--) + if (!CPEqualRanges(_ranges[rangesCount], otherRanges[rangesCount])) + return NO; + + return YES; } /*! @@ -176,9 +164,9 @@ @param anIndex the index to check for in the set @return \c YES if \c anIndex is in the receiver index set */ -- (BOOL)containsIndex:(unsigned)anIndex +- (BOOL)containsIndex:(CPInteger)anIndex { - return [self containsIndexesInRange:CPMakeRange(anIndex, 1)]; + return positionOfIndex(_ranges, anIndex) !== CPNotFound; } /*! @@ -187,29 +175,24 @@ */ - (BOOL)containsIndexesInRange:(CPRange)aRange { - if(!_count) + if (aRange.length <= 0) return NO; - var i = SOERangeIndex(self, aRange.location), - lower = aRange.location, - upper = CPMaxRange(aRange), - count = _ranges.length; + // If we have less total indexes than aRange, we can't possibly contain aRange. + if(_count < aRange.length) + return NO; - // Stop if the location is ever bigger than or equal to our - // non-inclusive upper bound - for(;i < count && _ranges[i].location < upper; ++i) - // The range must be a subset of one our ranges. - if (_ranges[i].location <= lower && CPMaxRange(_ranges[i]) >= upper) - { - _cachedRangeIndex = i; - return YES; - } - - // The value isn't here, but values greater than anIndex should - // start from here regardless. - _cachedRangeIndex = i; - - return NO; + // Search for first location + var rangeIndex = positionOfIndex(_ranges, aRange.location); + + // If we don't have the first location, then we don't contain aRange. + if (rangeIndex === CPNotFound) + return NO; + + var range = _ranges[rangeIndex]; + + // The intersection must contain all the indexes from the original range. + return CPIntersectionRange(range, aRange).length === aRange.length; } /*! @@ -218,22 +201,22 @@ */ - (BOOL)containsIndexes:(CPIndexSet)anIndexSet { - // Return YES if anIndexSet has no indexes - if(![anIndexSet count]) - return YES; - - // Return NO if we have no indexes. - if(!_count) + var otherCount = anIndexSet._count; + + if(otherCount <= 0) + return YES; + + // If we have less total indexes than anIndexSet, we can't possibly contain aRange. + if (_count < otherCount) return NO; - var i = 0, - count = _ranges.length; - - // This is fast thanks to the _cachedIndexRange. - for(; i < count; ++i) - if (![anIndexSet containsIndexesInRange:_ranges[i]]) + var otherRanges = anIndexSet._ranges, + otherRangesCount = otherRanges.length; + + while (otherRangesCount--) + if (![self containsIndexesInRange:otherRanges[otherRangesCount]]) return NO; - + return YES; } @@ -244,21 +227,20 @@ */ - (BOOL)intersectsIndexesInRange:(CPRange)aRange { - // This is fast thanks to the _cachedIndexRange. - if(!_count) + if (_count <= 0) return NO; - - var i = SOERangeIndex(self, aRange.location), - count = _ranges.length, - upper = CPMaxRange(aRange); - - // Stop if the location is ever bigger than or equal to our - // non-inclusive upper bound - for (; i < count && _ranges[i].location < upper; ++i) - if(CPIntersectionRange(aRange, _ranges[i]).length) - return YES; - - return NO; + + var lhsRangeIndex = assumedPositionOfIndex(_ranges, aRange.location); + + if (FLOOR(lhsRangeIndex) === lhsRangeIndex) + return YES; + + var rhsRangeIndex = assumedPositionOfIndex(_ranges, _CPMaxRange(aRange) - 1); + + if (FLOOR(rhsRangeIndex) === rhsRangeIndex) + return YES; + + return lhsRangeIndex !== rhsRangeIndex; } /*! @@ -273,87 +255,103 @@ /*! Return the first index in the set */ -- (int)firstIndex +- (CPInteger)firstIndex { - return _count ? _ranges[0].location : CPNotFound; + if (_count > 0) + return _ranges[0].location; + + return CPNotFound; } /*! Returns the last index in the set */ -- (int)lastIndex +- (CPInteger)lastIndex { - return _count ? CPMaxRange(_ranges[_ranges.length - 1]) - 1 : CPNotFound; + if (_count > 0) + return _CPMaxRange(_ranges[_ranges.length - 1]) - 1; + + return CPNotFound; } /*! Returns the first index value in the receiver which is greater than \c anIndex. @return the closest index or CPNotFound if no match was found */ -- (unsigned)indexGreaterThanIndex:(unsigned)anIndex +- (CPInteger)indexGreaterThanIndex:(CPInteger)anIndex { - if(!_count) - return CPNotFound; - - var i = SOERangeIndex(self, anIndex++), - count = _ranges.length; - - for(; i < count && anIndex >= CPMaxRange(_ranges[i]); ++i) ; + // The first possible index that would satisfy this requirement. + ++anIndex; - if (i == count) - return CPNotFound; - - _cachedRangeIndex = i; - - if (anIndex < _ranges[i].location) - return _ranges[i].location; + // Attempt to find it or something bigger. + var rangeIndex = assumedPositionOfIndex(_ranges, anIndex); - return anIndex; + // Nothing at all found? + if (rangeIndex === CPNotFound) + return CPNotFound; + + rangeIndex = CEIL(rangeIndex); + + if (rangeIndex >= _ranges.length) + return CPNotFound; + + var range = _ranges[rangeIndex]; + + // Check if it's actually in this range. + if (CPLocationInRange(anIndex, range)) + return anIndex; + + // If not, it must be the first element of this range. + return range.location; } /*! Returns the first index value in the receiver which is less than \c anIndex. @return the closest index or CPNotFound if no match was found */ -- (unsigned)indexLessThanIndex:(unsigned)anIndex +- (CPInteger)indexLessThanIndex:(CPInteger)anIndex { - if (!_count) - return CPNotFound; - - var i = GOERangeIndex(self, anIndex--); - - for (; i >= 0 && anIndex < _ranges[i].location; --i) ; + // The first possible index that would satisfy this requirement. + --anIndex; - if(i < 0) - return CPNotFound; - - _cachedRangeIndex = i; + // Attempt to find it or something smaller. + var rangeIndex = assumedPositionOfIndex(_ranges, anIndex); - if (CPLocationInRange(anIndex, _ranges[i])) + // Nothing at all found? + if (rangeIndex === CPNotFound) + return CPNotFound; + + rangeIndex = FLOOR(rangeIndex); + + if (rangeIndex < 0) + return CPNotFound; + + var range = _ranges[rangeIndex]; + + // Check if it's actually in this range. + if (CPLocationInRange(anIndex, range)) return anIndex; - - if (CPMaxRange(_ranges[i]) - 1 < anIndex) - return CPMaxRange(_ranges[i]) - 1; - return CPNotFound; + // If not, it must be the first element of this range. + return _CPMaxRange(range) - 1; } /*! Returns the first index value in the receiver which is greater than or equal to \c anIndex. @return the matching index or CPNotFound if no match was found */ -- (unsigned int)indexGreaterThanOrEqualToIndex:(unsigned)anIndex +- (CPInteger)indexGreaterThanOrEqualToIndex:(CPInteger)anIndex { - return [self indexGreaterThanIndex:anIndex - 1]; + return [self indexGreaterThanIndex:anIndex - 1]; } /*! Returns the first index value in the receiver which is less than or equal to \c anIndex. @return the matching index or CPNotFound if no match was found */ -- (unsigned int)indexLessThanOrEqualToIndex:(unsigned)anIndex +- (CPInteger)indexLessThanOrEqualToIndex:(CPInteger)anIndex { - return [self indexLessThanIndex:anIndex + 1]; + return [self indexLessThanIndex:anIndex + 1]; } /*! @@ -365,71 +363,105 @@ @param aRangePointer the range of indices to add @return the number of elements added to the array */ -- (unsigned)getIndexes:(CPArray)anArray maxCount:(unsigned)aMaxCount inIndexRange:(CPRange)aRangePointer +- (CPInteger)getIndexes:(CPArray)anArray maxCount:(CPInteger)aMaxCount inIndexRange:(CPRange)aRange { - if (!_count || aMaxCount <= 0 || aRangePointer && !aRangePointer.length) - return 0; - - var i = SOERangeIndex(self, aRangePointer? aRangePointer.location : 0), - total = 0, - count = _ranges.length; - - for (; i < count; ++i) + if (!_count || aMaxCount === 0 || aRange && !aRange.length) { - // If aRangePointer is nil, all indexes are acceptable. - var intersection = aRangePointer ? CPIntersectionRange(_ranges[i], aRangePointer) : _ranges[i], - index = intersection.location, - maximum = CPMaxRange(intersection); - - for (; index < maximum; ++index) + if (aRange) + aRange.length = 0; + + return 0; + } + + var total = 0; + + if (aRange) + { + var firstIndex = aRange.location, + lastIndex = _CPMaxRange(aRange) - 1, + rangeIndex = CEIL(assumedPositionOfIndex(_ranges, firstIndex)), + lastRangeIndex = FLOOR(assumedPositionOfIndex(_ranges, lastIndex)); + } + else + { + var firstIndex = [self firstIndex], + lastIndex = [self lastIndex], + rangeIndex = 0, + lastRangeIndex = _ranges.length - 1; + } + + while (rangeIndex <= lastRangeIndex) + { + var range = _ranges[rangeIndex], + index = MAX(firstIndex, range.location), + maxRange = MIN(lastIndex + 1, _CPMaxRange(range)); + + for (; index < maxRange; ++index) { anArray[total++] = index; - - if (total == aMaxCount) + + if (total === aMaxCount) { - // Update aRangePointer if it exists... - if (aRangePointer) + // Update aRange if it exists... + if (aRange) { - var upper = CPMaxRange(aRangePointer); - - // Don't use CPMakeRange since the values need to persist. - aRangePointer.location = index + 1; - aRangePointer.length = upper - index - 1; + aRange.location = index + 1; + aRange.length = lastIndex + 1 - index - 1; } - + return aMaxCount; } } + + ++rangeIndex; } - - // Update aRangePointer if it exists... - if (aRangePointer) + + // Update aRange if it exists... + if (aRange) { - aRangePointer.location = CPNotFound; - aRangePointer.length = 0; + aRange.location = CPNotFound; + aRange.length = 0; } - + return total; } - (CPString)description { - var desc = [super description] + " "; - - if (_count) - { - desc += "[number of indexes: " + _count + " (in " + _ranges.length + " ranges), indexes: ("; - for (i = 0; i < _ranges.length; i++) - { - desc += _ranges[i].location; - if (_ranges[i].length > 1) desc += "-" + (CPMaxRange(_ranges[i])-1) + ":"+_ranges[i].length+":"; - if (i+1 < _ranges.length) desc += " "; - } - desc += ")]"; - } - else - desc += "(no indexes)"; - return desc; + var description = [super description]; + + if (_count) + { + var index = 0, + count = _ranges.length; + + description += "[number of indexes: " + _count + " (in " + count; + + if (count === 1) + description += " range), indexes: ("; + else + description += " ranges), indexes: ("; + + for (; index < count; ++index) + { + var range = _ranges[index]; + + description += range.location; + + if (range.length > 1) + description += "-" + (CPMaxRange(range) - 1); + + if (index + 1 < count) + description += " "; + } + + description += ")]"; + } + + else + description += "(no indexes)"; + + return description; } @end @@ -441,9 +473,9 @@ Adds an index to the set. @param anIndex the index to add */ -- (void)addIndex:(unsigned)anIndex +- (void)addIndex:(CPInteger)anIndex { - [self addIndexesInRange:CPMakeRange(anIndex, 1)]; + [self addIndexesInRange:_CPMakeRange(anIndex, 1)]; } /*! @@ -452,13 +484,12 @@ */ - (void)addIndexes:(CPIndexSet)anIndexSet { - var i = 0, - ranges = anIndexSet._ranges, - count = ranges.length; - + var otherRanges = anIndexSet._ranges, + otherRangesCount = otherRanges.length; + // Simply add each range within anIndexSet. - for(; i < count; ++i) - [self addIndexesInRange:ranges[i]]; + while (otherRangesCount--) + [self addIndexesInRange:otherRanges[otherRangesCount]]; } /*! @@ -467,91 +498,66 @@ */ - (void)addIndexesInRange:(CPRange)aRange { - if (_ranges.length == 0) + // If empty range, bail. + if (aRange.length <= 0) + return; + + // If we currently don't have any indexes, this represents our entire set. + if (_count <= 0) { _count = aRange.length; - - return [_ranges addObject:CPCopyRange(aRange)]; - } - - // FIXME: Should we really use SOERangeIndex here? There is no real - // reason the cached index would be a better guess than 0, and it - // would avoid a function call. - var i = SOERangeIndex(self, aRange.location), - count = _ranges.length, - padded = CPMakeRange(aRange.location - 1, aRange.length + 2), - maximum = CPMaxRange(aRange); + _ranges = [aRange]; + + return; + } + + var rangeCount = _ranges.length, + lhsRangeIndex = assumedPositionOfIndex(_ranges, aRange.location - 1), + lhsRangeIndexCEIL = CEIL(lhsRangeIndex); + + if (lhsRangeIndexCEIL === lhsRangeIndex && lhsRangeIndexCEIL < rangeCount) + aRange = CPUnionRange(aRange, _ranges[lhsRangeIndexCEIL]); + + var rhsRangeIndex = assumedPositionOfIndex(_ranges, CPMaxRange(aRange)), + rhsRangeIndexFLOOR = FLOOR(rhsRangeIndex); + + if (rhsRangeIndexFLOOR === rhsRangeIndex && rhsRangeIndexFLOOR > 0) + aRange = CPUnionRange(aRange, _ranges[rhsRangeIndexFLOOR]); + + var removalCount = rhsRangeIndexFLOOR - lhsRangeIndexCEIL + 1; + + if (removalCount === _ranges.length) + { + _ranges = [aRange]; + _count = aRange.length; + } + + else if (removalCount === 1) + { + if (lhsRangeIndexCEIL < _ranges.length) + _count -= _ranges[lhsRangeIndexCEIL].length; + + _count += aRange.length; + _ranges[lhsRangeIndexCEIL] = aRange; + } - // If our range won't intersect with the last range, just append it to the end. - if (count && CPMaxRange(_ranges[count - 1]) < aRange.location) - [_ranges addObject:CPCopyRange(aRange)]; else - for (; i < count; ++i) + { + if (removalCount > 0) { - // This range is completely independent of existing ranges, - // simply add it to the array. - if (maximum < _ranges[i].location) - { - _count += aRange.length; - - // Keep _cachedRangeIndex relevant. - if (i < _cachedRangeIndex) ++_cachedRangeIndex; - - return [_ranges insertObject:CPCopyRange(aRange) atIndex:i]; - } - - if (CPIntersectionRange(_ranges[i], padded).length) - { - var union = CPUnionRange(_ranges[i], aRange); - - // We already contain all the indexes in this range. - if (union.length == _ranges[i].length) - return; - - // Pad the length to collapse with later ranges. - ++union.length; - - // We only need to check if we now intersect with any following - // ranges since if we now intersected with the previous range, - // it would have already been handled. We start at i and not i + 1 - // to make sure we subtract i's length. - var j = i; - - for(; j < count; ++j) - // Bail as soon as we don't find an intersection. - if(CPIntersectionRange(union, _ranges[j]).length) - _count -= _ranges[j].length; - else - break; - - // Remove the padding now that we are done. - // NOTE: We could have set _ranges[i] = CPCopyRange(union), - // and then not had to bother decerementing here, but this avoids - // a lookup above during unioning, and a function call (CPCopyRange). - --union.length; - _ranges[i] = union; - - // Now remove indexes [i + 1, j - 1] - if (j - i - 1 > 0) - { - var remove = CPMakeRange(i + 1, j - i - 1); - - _ranges[i] = CPUnionRange(_ranges[i], _ranges[j - 1]); - [_ranges removeObjectsInRange:remove]; - - // Keep _cachedRangeIndex relevant. - if (_cachedRangeIndex >= CPMaxRange(remove)) _cachedRangedIndex -= remove.length; - else if (CPLocationInRange(_cachedRangeIndex, remove)) _cachedRangeIndex = i; - } - - // Update count. - _count += _ranges[i].length; - - return; - } + var removal = lhsRangeIndexCEIL, + lastRemoval = lhsRangeIndexCEIL + removalCount - 1; + + for (; removal <= lastRemoval; ++removal) + _count -= _ranges[removal].length; + + [_ranges removeObjectsInRange:_CPMakeRange(lhsRangeIndexCEIL, removalCount)]; } - - _count += aRange.length; + + [_ranges insertObject:aRange atIndex:lhsRangeIndexCEIL]; + + _count += aRange.length; + } } // Removing Indexes @@ -559,9 +565,9 @@ Removes an index from the set @param anIndex the index to remove */ -- (void)removeIndex:(unsigned int)anIndex +- (void)removeIndex:(CPInteger)anIndex { - [self removeIndexesInRange:CPMakeRange(anIndex, 1)]; + [self removeIndexesInRange:_CPMakeRange(anIndex, 1)]; } /*! @@ -571,13 +577,12 @@ */ - (void)removeIndexes:(CPIndexSet)anIndexSet { - var i = 0, - ranges = anIndexSet._ranges, - count = ranges.length; - + var otherRanges = anIndexSet._ranges, + otherRangesCount = otherRanges.length; + // Simply remove each index from anIndexSet - for(; i < count; ++i) - [self removeIndexesInRange:ranges[i]]; + while (otherRangesCount--) + [self removeIndexesInRange:otherRanges[otherRangesCount]]; } /*! @@ -586,8 +591,7 @@ - (void)removeAllIndexes { _ranges = []; - _count = 0; - _cachedRangeIndex = 0; + _count = 0; } /*! @@ -597,63 +601,78 @@ */ - (void)removeIndexesInRange:(CPRange)aRange { - // FIXME: Should we really use SOERangeIndex here? There is no real - // reason the cached index would be a better guess than 0, and it - // would avoid a function call. - var i = SOERangeIndex(self, aRange.location), - count = _ranges.length, - maximum = CPMaxRange(aRange), - removal = CPMakeRange(CPNotFound, 0); - - for (; i < count; ++i) - { - var range = _ranges[i]; - - // Our range will not intersect with any coming ranges. - if (maximum < range.location) - break; + // If empty range, bail. + if (aRange.length <= 0) + return; - var intersection = CPIntersectionRange(range, aRange); - - // If we don't have an intersection, then just continue iterating. - if (!intersection.length) - continue; - - // If the intersection consists of the entirety of this range, - // then remove it completely. - else if (intersection.length == range.length) + // If we currently don't have any indexes, there's nothing to remove. + if (_count <= 0) + return; + + var rangeCount = _ranges.length, + lhsRangeIndex = assumedPositionOfIndex(_ranges, aRange.location), + lhsRangeIndexCEIL = CEIL(lhsRangeIndex); + + // Do we fall on an actual existing range? + if (lhsRangeIndex === lhsRangeIndexCEIL && lhsRangeIndexCEIL < rangeCount) + { + var existingRange = _ranges[lhsRangeIndexCEIL]; + + // If these ranges don't start in the same place, we have to cull it. + if (aRange.location !== existingRange.location) { - if (removal.location == CPNotFound) - removal = CPMakeRange(i, 1); + var maxRange = CPMaxRange(aRange), + existingMaxRange = CPMaxRange(existingRange); + + existingRange.length = aRange.location - existingRange.location; + + // If this range is internal to the existing range, we have a unique splitting case. + if (maxRange < existingMaxRange) + { + _count -= aRange.length; + [_ranges insertObject:_CPMakeRange(maxRange, existingMaxRange - maxRange) atIndex:lhsRangeIndexCEIL + 1]; + + return; + } else - ++removal.length; + { + _count -= existingMaxRange - aRange.location; + lhsRangeIndexCEIL += 1; + } } - // If the intersection is contained entirely within this range, - // then split it into two and return. - else if (intersection.location > range.location && CPMaxRange(intersection) < CPMaxRange(range)) - { - var insert = CPMakeRange(CPMaxRange(intersection), CPMaxRange(range) - CPMaxRange(intersection)); - - range.length = intersection.location - range.location; - - _count -= intersection.length; - - return [_ranges insertObject:insert atIndex:i + 1]; - } - // Else if we at least have an intersection, then trim the existing range. - else - { - range.length -= intersection.length; - - if (intersection.location <= range.location) - range.location += intersection.length; - } - - _count -= intersection.length; } - - if (removal.length) - [_ranges removeObjectsInRange:removal]; + + var rhsRangeIndex = assumedPositionOfIndex(_ranges, CPMaxRange(aRange) - 1), + rhsRangeIndexFLOOR = FLOOR(rhsRangeIndex); + + if (rhsRangeIndex === rhsRangeIndexFLOOR && rhsRangeIndexFLOOR >= 0) + { + var maxRange = CPMaxRange(aRange), + existingRange = _ranges[rhsRangeIndexFLOOR], + existingMaxRange = CPMaxRange(existingRange); + + if (maxRange !== existingMaxRange) + { + _count -= maxRange - existingRange.location; + rhsRangeIndexFLOOR -= 1; // This is accounted for, and thus as if we got the previous spot. + + existingRange.location = maxRange; + existingRange.length = existingMaxRange - maxRange; + } + } + + var removalCount = rhsRangeIndexFLOOR - lhsRangeIndexCEIL + 1; + + if (removalCount > 0) + { + var removal = lhsRangeIndexCEIL, + lastRemoval = lhsRangeIndexCEIL + removalCount - 1; + + for (; removal <= lastRemoval; ++removal) + _count -= _ranges[removal].length; + + [_ranges removeObjectsInRange:_CPMakeRange(lhsRangeIndexCEIL, removalCount)]; + } } // Shifting Index Groups @@ -663,11 +682,11 @@ @param aDelta the amount and direction to shift. A positive value shifts to the right. A negative value shifts to the left. */ -- (void)shiftIndexesStartingAtIndex:(unsigned)anIndex by:(int)aDelta -{ - if (!_count || aDelta == 0) - return; - +- (void)shiftIndexesStartingAtIndex:(CPInteger)anIndex by:(int)aDelta +{ + if (!_count || aDelta == 0) + return; + // Later indexes have a higher probability of being shifted // than lower ones, so start at the end and work backwards. var i = _ranges.length - 1, @@ -677,7 +696,7 @@ { var range = _ranges[i], maximum = CPMaxRange(range); - + if (anIndex > maximum) break; @@ -699,11 +718,11 @@ shifted.length = CPMaxRange(shifted); shifted.location = 0; } - + // We don't need to continue. break; } - + // Shift the range, and normalize it if the result is negative. if ((range.location += aDelta) < 0) { @@ -711,21 +730,21 @@ range.location = 0; } } - + // We need to add the shifted ranges if the delta is negative. if (aDelta < 0) { var j = i + 1, count = _ranges.length, shifts = []; - + for (; j < count; ++j) [shifts addObject:_ranges[j]]; - + if ((j = i + 1) < count) { [_ranges removeObjectsInRange:CPMakeRange(j, count - j)]; - + for (j = 0, count = shifts.length; j < count; ++j) [self addIndexesInRange:shifts[j]]; } @@ -738,7 +757,6 @@ @end var CPIndexSetCountKey = @"CPIndexSetCountKey", - CPIndexSetCachedRangeIndexKey = @"CPIndexSetCachedRangeIndexKey", CPIndexSetRangeStringsKey = @"CPIndexSetRangeStringsKey"; @implementation CPIndexSet (CPCoding) @@ -752,21 +770,20 @@ var CPIndexSetCountKey = @"CPIndexSetCountKey", - (id)initWithCoder:(CPCoder)aCoder { self = [super init]; - + if (self) { _count = [aCoder decodeIntForKey:CPIndexSetCountKey]; - _cachedRangeIndex = [aCoder decodeIntForKey:CPIndexSetCachedRangeIndexKey]; _ranges = []; - + var rangeStrings = [aCoder decodeObjectForKey:CPIndexSetRangeStringsKey], index = 0, count = rangeStrings.length; - + for (; index < count; ++index) _ranges.push(CPRangeFromString(rangeStrings[index])); } - + return self; } @@ -778,12 +795,11 @@ var CPIndexSetCountKey = @"CPIndexSetCountKey", - (void)encodeWithCoder:(CPCoder)aCoder { [aCoder encodeInt:_count forKey:CPIndexSetCountKey]; - [aCoder encodeInt:_cachedRangeIndex forKey:CPIndexSetCachedRangeIndexKey]; - + var index = 0, count = _ranges.length, rangeStrings = []; - + for (; index < count; ++index) rangeStrings[index] = CPStringFromRange(_ranges[index]); @@ -830,56 +846,102 @@ var CPIndexSetCountKey = @"CPIndexSetCountKey", @end -var SOERangeIndex = function(anIndexSet, anIndex) +var positionOfIndex = function(ranges, anIndex) { - var ranges = anIndexSet._ranges, - cachedRangeIndex = 0;//anIndexSet._cachedRangeIndex; - - if(cachedRangeIndex < ranges.length && anIndex >= ranges[cachedRangeIndex].location) - return cachedRangeIndex; + var low = 0, + high = ranges.length - 1; - return 0; + while (low <= high) + { + var middle = FLOOR(low + (high - low) / 2), + range = ranges[middle]; + + if (anIndex < range.location) + high = middle - 1; + + else if (anIndex >= CPMaxRange(range)) + low = middle + 1; + + else + return middle; + } + + return CPNotFound; } -var GOERangeIndex = function(anIndexSet, anIndex) +var assumedPositionOfIndex = function(ranges, anIndex) { - var ranges = anIndexSet._ranges, - cachedRangeIndex = anIndexSet._ranges.length;//anIndexSet._cachedRangeIndex; - - if(cachedRangeIndex < ranges.length && anIndex <= ranges[cachedRangeIndex].location) - return cachedRangeIndex; - - return ranges.length - 1; + var count = ranges.length; + + if (count <= 0) + return CPNotFound; + + var low = 0, + high = count * 2; + + while (low <= high) + { + var middle = FLOOR(low + (high - low) / 2), + position = middle / 2, + positionFLOOR = FLOOR(position); + + if (position === positionFLOOR) + { + if (positionFLOOR - 1 >= 0 && anIndex < CPMaxRange(ranges[positionFLOOR - 1])) + high = middle - 1; + + else if (positionFLOOR < count && anIndex >= ranges[positionFLOOR].location) + low = middle + 1; + + else + return positionFLOOR - 0.5; + } + else + { + var range = ranges[positionFLOOR]; + + if (anIndex < range.location) + high = middle - 1; + + else if (anIndex >= CPMaxRange(range)) + low = middle + 1; + + else + return positionFLOOR; + } + } + + return CPNotFound; } /* new old method -X + (id)indexSet; -X + (id)indexSetWithIndex:(unsigned int)value; -X + (id)indexSetWithIndexesInRange:(NSRange)range; -X X - (id)init; -X X - (id)initWithIndex:(unsigned int)value; -X X - (id)initWithIndexesInRange:(NSRange)range; // designated initializer -X X - (id)initWithIndexSet:(NSIndexSet *)indexSet; // designated initializer -X - (BOOL)isEqualToIndexSet:(NSIndexSet *)indexSet; -X X - (unsigned int)count; -X X - (unsigned int)firstIndex; -X X - (unsigned int)lastIndex; -X X - (unsigned int)indexGreaterThanIndex:(unsigned int)value; -X X - (unsigned int)indexLessThanIndex:(unsigned int)value; -X X - (unsigned int)indexGreaterThanOrEqualToIndex:(unsigned int)value; -X X - (unsigned int)indexLessThanOrEqualToIndex:(unsigned int)value; -X - (unsigned int)getIndexes:(unsigned int *)indexBuffer maxCount:(unsigned int)bufferSize inIndexRange:(NSRangePointer)range; -X X - (BOOL)containsIndex:(unsigned int)value; -X X - (BOOL)containsIndexesInRange:(NSRange)range; -X X - (BOOL)containsIndexes:(NSIndexSet *)indexSet; -X X - (BOOL)intersectsIndexesInRange:(NSRange)range; -X X - (void)addIndexes:(NSIndexSet *)indexSet; -X - (void)removeIndexes:(NSIndexSet *)indexSet; -X X - (void)removeAllIndexes; -X - (void)addIndex:(unsigned int)value; -X - (void)removeIndex:(unsigned int)value; -X - (void)addIndexesInRange:(NSRange)range; -X - (void)removeIndexesInRange:(NSRange)range; - - (void)shiftIndexesStartingAtIndex:(unsigned int)index by:(int)delta; +X + (id)indexSet; +X + (id)indexSetWithIndex:(unsigned int)value; +X + (id)indexSetWithIndexesInRange:(NSRange)range; +X X - (id)init; +X X - (id)initWithIndex:(unsigned int)value; +X X - (id)initWithIndexesInRange:(NSRange)range; // designated initializer +X X - (id)initWithIndexSet:(NSIndexSet *)indexSet; // designated initializer +X - (BOOL)isEqualToIndexSet:(NSIndexSet *)indexSet; +X X - (unsigned int)count; +X X - (unsigned int)firstIndex; +X X - (unsigned int)lastIndex; +X X - (unsigned int)indexGreaterThanIndex:(unsigned int)value; +X X - (unsigned int)indexLessThanIndex:(unsigned int)value; +X X - (unsigned int)indexGreaterThanOrEqualToIndex:(unsigned int)value; +X X - (unsigned int)indexLessThanOrEqualToIndex:(unsigned int)value; +X - (unsigned int)getIndexes:(unsigned int *)indexBuffer maxCount:(unsigned int)bufferSize inIndexRange:(NSRangePointer)range; +X X - (BOOL)containsIndex:(unsigned int)value; +X X - (BOOL)containsIndexesInRange:(NSRange)range; +X X - (BOOL)containsIndexes:(NSIndexSet *)indexSet; +X X - (BOOL)intersectsIndexesInRange:(NSRange)range; +X X - (void)addIndexes:(NSIndexSet *)indexSet; +X - (void)removeIndexes:(NSIndexSet *)indexSet; +X X - (void)removeAllIndexes; +X - (void)addIndex:(unsigned int)value; +X - (void)removeIndex:(unsigned int)value; +X - (void)addIndexesInRange:(NSRange)range; +X - (void)removeIndexesInRange:(NSRange)range; + - (void)shiftIndexesStartingAtIndex:(unsigned int)index by:(int)delta; */ diff --git a/Foundation/CPKeyedUnarchiver.j b/Foundation/CPKeyedUnarchiver.j index 05b737bb6..f9be40a40 100644 --- a/Foundation/CPKeyedUnarchiver.j +++ b/Foundation/CPKeyedUnarchiver.j @@ -108,7 +108,7 @@ var _CPKeyedUnarchiverArrayClass = Ni CPDictionary _replacementClasses; - CPDictionary _objects; + CPArray _objects; CPDictionary _archive; CPDictionary _plistObject; diff --git a/TableCibTest/AppController.j b/TableCibTest/AppController.j new file mode 100644 index 000000000..a079fb6e1 --- /dev/null +++ b/TableCibTest/AppController.j @@ -0,0 +1,45 @@ +/* + * AppController.j + * TableCibTest + * + * Created by Francisco Tolmasky on July 5, 2009. + * Copyright 2009, 280 North, Inc. All rights reserved. + */ + +@import + + +@implementation AppController : CPObject +{ + CPWindow theWindow; //this "outlet" is connected automatically by the Cib +} + +- (void)applicationDidFinishLaunching:(CPNotification)aNotification +{ + // This is called when the application is done loading. +} + +- (void)awakeFromCib +{ + // This is called when the cib is done loading. + // You can implement this method on any object instantiated from a Cib. + // It's a useful hook for setting up current UI values, and other things. + + // In this case, we want the window from Cib to become our full browser window + [theWindow setFullBridge:YES]; +} + +- (int)numberOfRowsInTableView:(CPTableView)tableView +{ + return 700000; +} + +- (id)tableView:(CPTableView)tableView objectValueForTableColumn:(CPTableColumn)tableColumn row:(int)row +{ + if ([tableColumn identifier] === "icons") + return iconImage; + else + return String((row + 1) * [[tableColumn identifier] intValue]); +} + +@end diff --git a/TableCibTest/Info.plist b/TableCibTest/Info.plist new file mode 100644 index 000000000..f2ebe529d --- /dev/null +++ b/TableCibTest/Info.plist @@ -0,0 +1,12 @@ + + + + + Main cib file base name + MainMenu.cib + CPBundleName + TableCibTest + CPPrincipalClass + CPApplication + + diff --git a/TableCibTest/Rakefile b/TableCibTest/Rakefile new file mode 100644 index 000000000..ead2456ce --- /dev/null +++ b/TableCibTest/Rakefile @@ -0,0 +1,25 @@ + +require 'objective-j' +require 'objective-j/bundletask' + +if !ENV['CONFIG'] + ENV['CONFIG'] = 'Debug' +end + +ObjectiveJ::BundleTask.new(:TableCibTest) do |t| + t.name = 'TableCibTest' + t.identifier = 'com.280n.TableCibTest' + t.version = '1.0' + t.author = '280 North, Inc.' + t.email = 'feedback @nospam@ 280north.com' + t.summary = 'TableCibTest' + t.sources = FileList['*.j'] + t.resources = FileList['Resources/*'] + t.index_file = 'index.html' + t.info_plist = 'Info.plist' + t.build_path = File.join('Build', ENV['CONFIG'], 'TableCibTest') + t.flag = '-DDEBUG' if ENV['CONFIG'] == 'Debug' + t.flag = '-O' if ENV['CONFIG'] == 'Release' +end + +task :default => [:TableCibTest] diff --git a/TableCibTest/Resources/MainMenu.cib b/TableCibTest/Resources/MainMenu.cib new file mode 100644 index 000000000..cc4ca88e9 --- /dev/null +++ b/TableCibTest/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;21E;D;K;6;CP$UIDd;2;23E;D;K;6;CP$UIDd;2;25E;D;K;6;CP$UIDd;2;26E;D;K;6;CP$UIDd;2;27E;D;K;6;CP$UIDd;2;28E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;30E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;2;32E;D;K;6;CP$UIDd;2;33E;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;2;39E;D;K;6;CP$UIDd;2;16E;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;43E;D;K;6;CP$UIDd;2;44E;D;K;6;CP$UIDd;2;45E;D;K;6;CP$UIDd;2;46E;D;K;6;CP$UIDd;2;47E;D;K;6;CP$UIDd;2;48E;D;K;6;CP$UIDd;2;49E;D;K;6;CP$UIDd;2;50E;D;K;6;CP$UIDd;2;51E;D;K;6;CP$UIDd;2;52E;D;K;6;CP$UIDd;2;54E;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;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;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;1;0E;D;K;6;CP$UIDd;1;0E;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;1;0E;D;K;6;CP$UIDd;3;101E;D;K;6;CP$UIDd;3;102E;D;K;6;CP$UIDd;3;103E;D;K;6;CP$UIDd;3;104E;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;113E;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;1;0E;D;K;6;CP$UIDd;3;118E;D;K;6;CP$UIDd;3;119E;D;K;6;CP$UIDd;3;120E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;3;122E;D;K;6;CP$UIDd;3;123E;D;K;6;CP$UIDd;3;124E;D;K;6;CP$UIDd;3;126E;D;K;6;CP$UIDd;3;127E;D;K;6;CP$UIDd;3;128E;D;K;6;CP$UIDd;3;129E;D;K;6;CP$UIDd;3;130E;D;K;6;CP$UIDd;3;131E;D;K;6;CP$UIDd;3;132E;D;K;6;CP$UIDd;3;133E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;134E;D;K;6;CP$UIDd;3;135E;D;K;6;CP$UIDd;3;136E;D;K;6;CP$UIDd;3;137E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;138E;D;K;6;CP$UIDd;3;139E;D;K;6;CP$UIDd;3;140E;D;K;6;CP$UIDd;3;141E;D;K;6;CP$UIDd;3;142E;D;K;6;CP$UIDd;3;143E;D;K;6;CP$UIDd;3;144E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;145E;D;K;6;CP$UIDd;3;146E;D;K;6;CP$UIDd;3;147E;D;K;6;CP$UIDd;3;148E;D;K;6;CP$UIDd;3;149E;D;K;6;CP$UIDd;3;150E;D;K;6;CP$UIDd;3;151E;D;K;6;CP$UIDd;3;152E;D;K;6;CP$UIDd;3;153E;D;K;6;CP$UIDd;3;154E;D;K;6;CP$UIDd;3;155E;D;K;6;CP$UIDd;3;156E;D;K;6;CP$UIDd;3;157E;D;K;6;CP$UIDd;3;158E;D;K;6;CP$UIDd;3;159E;D;K;6;CP$UIDd;3;160E;D;K;6;CP$UIDd;3;161E;D;K;6;CP$UIDd;3;162E;D;K;6;CP$UIDd;3;163E;D;K;6;CP$UIDd;3;164E;D;K;6;CP$UIDd;3;165E;D;K;6;CP$UIDd;3;166E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;167E;D;K;6;CP$UIDd;3;168E;D;K;6;CP$UIDd;3;169E;D;K;6;CP$UIDd;3;170E;D;K;6;CP$UIDd;3;171E;D;K;6;CP$UIDd;3;172E;D;K;6;CP$UIDd;3;173E;D;K;6;CP$UIDd;3;174E;D;K;6;CP$UIDd;3;175E;D;K;6;CP$UIDd;3;176E;D;K;6;CP$UIDd;3;177E;D;K;6;CP$UIDd;3;178E;D;K;6;CP$UIDd;3;179E;D;K;6;CP$UIDd;3;180E;D;K;6;CP$UIDd;3;181E;D;K;6;CP$UIDd;3;182E;D;K;6;CP$UIDd;3;183E;D;K;6;CP$UIDd;3;184E;D;K;6;CP$UIDd;3;185E;D;K;6;CP$UIDd;3;186E;D;K;6;CP$UIDd;3;187E;D;K;6;CP$UIDd;3;188E;D;K;6;CP$UIDd;3;189E;D;K;6;CP$UIDd;3;190E;D;K;6;CP$UIDd;3;191E;D;K;6;CP$UIDd;3;192E;D;K;6;CP$UIDd;3;193E;D;K;6;CP$UIDd;3;194E;D;K;6;CP$UIDd;3;195E;D;K;6;CP$UIDd;3;196E;D;K;6;CP$UIDd;3;197E;D;K;6;CP$UIDd;3;198E;D;K;6;CP$UIDd;3;199E;D;K;6;CP$UIDd;3;200E;D;K;6;CP$UIDd;3;201E;D;K;6;CP$UIDd;3;202E;D;K;6;CP$UIDd;3;203E;D;K;6;CP$UIDd;3;204E;D;K;6;CP$UIDd;3;205E;D;K;6;CP$UIDd;3;206E;D;K;6;CP$UIDd;3;207E;D;K;6;CP$UIDd;3;208E;D;K;6;CP$UIDd;3;209E;D;K;6;CP$UIDd;3;210E;D;K;6;CP$UIDd;3;211E;D;K;6;CP$UIDd;3;212E;D;K;6;CP$UIDd;3;213E;D;K;6;CP$UIDd;3;214E;D;K;6;CP$UIDd;3;215E;D;K;6;CP$UIDd;3;216E;D;K;6;CP$UIDd;3;217E;D;K;6;CP$UIDd;3;218E;D;K;6;CP$UIDd;3;219E;D;K;6;CP$UIDd;3;220E;D;K;6;CP$UIDd;3;221E;D;K;6;CP$UIDd;3;222E;D;K;6;CP$UIDd;3;223E;D;K;6;CP$UIDd;3;224E;D;K;6;CP$UIDd;3;225E;D;K;6;CP$UIDd;3;226E;D;K;6;CP$UIDd;3;227E;D;K;6;CP$UIDd;3;228E;D;K;6;CP$UIDd;3;229E;D;K;6;CP$UIDd;3;230E;D;K;6;CP$UIDd;3;231E;D;K;6;CP$UIDd;3;232E;D;K;6;CP$UIDd;3;233E;D;K;6;CP$UIDd;3;234E;D;K;6;CP$UIDd;3;235E;D;K;6;CP$UIDd;3;236E;D;K;6;CP$UIDd;3;237E;D;K;6;CP$UIDd;3;238E;D;K;6;CP$UIDd;3;239E;D;K;6;CP$UIDd;3;240E;D;K;6;CP$UIDd;3;241E;D;K;6;CP$UIDd;3;242E;D;K;6;CP$UIDd;3;243E;D;K;6;CP$UIDd;3;244E;D;K;6;CP$UIDd;3;245E;D;K;6;CP$UIDd;3;246E;D;K;6;CP$UIDd;3;247E;D;K;6;CP$UIDd;3;248E;D;K;6;CP$UIDd;3;249E;D;K;6;CP$UIDd;3;250E;D;K;6;CP$UIDd;3;251E;D;K;6;CP$UIDd;3;252E;D;K;6;CP$UIDd;3;253E;D;K;6;CP$UIDd;3;254E;D;K;6;CP$UIDd;3;255E;D;K;6;CP$UIDd;3;256E;D;K;6;CP$UIDd;3;257E;D;K;6;CP$UIDd;3;258E;D;K;6;CP$UIDd;3;259E;D;K;6;CP$UIDd;3;260E;D;K;6;CP$UIDd;3;261E;D;K;6;CP$UIDd;3;262E;D;K;6;CP$UIDd;3;263E;D;K;6;CP$UIDd;3;264E;D;K;6;CP$UIDd;3;265E;D;K;6;CP$UIDd;3;266E;D;K;6;CP$UIDd;3;267E;D;K;6;CP$UIDd;3;268E;D;K;6;CP$UIDd;3;269E;D;K;6;CP$UIDd;3;270E;D;K;6;CP$UIDd;3;271E;D;K;6;CP$UIDd;3;272E;D;K;6;CP$UIDd;3;273E;D;K;6;CP$UIDd;3;274E;D;K;6;CP$UIDd;3;275E;D;K;6;CP$UIDd;3;276E;D;K;6;CP$UIDd;3;277E;D;K;6;CP$UIDd;3;278E;D;K;6;CP$UIDd;3;279E;D;K;6;CP$UIDd;3;280E;D;K;6;CP$UIDd;3;281E;D;K;6;CP$UIDd;3;282E;D;K;6;CP$UIDd;3;283E;D;K;6;CP$UIDd;3;284E;D;K;6;CP$UIDd;3;285E;D;K;6;CP$UIDd;3;286E;D;K;6;CP$UIDd;3;287E;D;K;6;CP$UIDd;3;288E;D;K;6;CP$UIDd;3;289E;D;K;6;CP$UIDd;3;290E;D;K;6;CP$UIDd;3;291E;D;K;6;CP$UIDd;3;292E;D;K;6;CP$UIDd;3;293E;D;K;6;CP$UIDd;3;294E;D;K;6;CP$UIDd;3;295E;D;K;6;CP$UIDd;3;296E;D;K;6;CP$UIDd;3;297E;D;K;6;CP$UIDd;3;298E;D;K;6;CP$UIDd;3;299E;D;K;6;CP$UIDd;3;300E;D;K;6;CP$UIDd;3;301E;D;K;6;CP$UIDd;3;302E;D;K;6;CP$UIDd;3;303E;D;K;6;CP$UIDd;3;304E;D;K;6;CP$UIDd;3;305E;D;K;6;CP$UIDd;3;306E;D;K;6;CP$UIDd;3;307E;D;K;6;CP$UIDd;3;308E;D;K;6;CP$UIDd;3;309E;D;K;6;CP$UIDd;3;310E;D;K;6;CP$UIDd;3;311E;D;K;6;CP$UIDd;3;312E;D;K;6;CP$UIDd;3;313E;D;K;6;CP$UIDd;3;314E;D;K;6;CP$UIDd;3;315E;D;K;6;CP$UIDd;3;316E;D;K;6;CP$UIDd;3;317E;D;K;6;CP$UIDd;3;318E;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;320E;D;K;6;CP$UIDd;3;321E;D;K;6;CP$UIDd;3;322E;D;K;6;CP$UIDd;3;323E;D;K;6;CP$UIDd;3;324E;D;K;6;CP$UIDd;3;325E;D;K;6;CP$UIDd;3;326E;D;K;6;CP$UIDd;3;327E;D;K;6;CP$UIDd;3;328E;D;K;6;CP$UIDd;3;329E;D;K;6;CP$UIDd;3;330E;D;K;6;CP$UIDd;3;331E;D;K;6;CP$UIDd;3;332E;D;K;6;CP$UIDd;3;333E;D;K;6;CP$UIDd;3;334E;D;K;6;CP$UIDd;3;335E;D;K;6;CP$UIDd;3;336E;D;K;6;CP$UIDd;3;337E;D;K;6;CP$UIDd;3;338E;D;K;6;CP$UIDd;3;339E;D;K;6;CP$UIDd;3;340E;D;K;6;CP$UIDd;3;341E;D;K;6;CP$UIDd;3;342E;D;K;6;CP$UIDd;3;343E;D;K;6;CP$UIDd;3;344E;D;K;6;CP$UIDd;3;345E;D;K;6;CP$UIDd;3;346E;D;K;6;CP$UIDd;3;347E;D;K;6;CP$UIDd;3;348E;D;K;6;CP$UIDd;3;349E;D;K;6;CP$UIDd;3;350E;D;K;6;CP$UIDd;3;351E;D;K;6;CP$UIDd;3;352E;D;K;6;CP$UIDd;3;353E;D;K;6;CP$UIDd;3;354E;D;K;6;CP$UIDd;3;355E;D;K;6;CP$UIDd;3;356E;D;K;6;CP$UIDd;3;357E;D;K;6;CP$UIDd;3;358E;D;K;6;CP$UIDd;3;359E;D;K;6;CP$UIDd;3;360E;D;K;6;CP$UIDd;3;361E;D;K;6;CP$UIDd;3;362E;D;K;6;CP$UIDd;3;363E;D;K;6;CP$UIDd;3;364E;D;K;6;CP$UIDd;3;365E;D;K;6;CP$UIDd;3;366E;D;K;6;CP$UIDd;3;367E;D;K;6;CP$UIDd;3;368E;D;K;6;CP$UIDd;3;369E;D;K;6;CP$UIDd;3;370E;D;K;6;CP$UIDd;3;371E;D;K;6;CP$UIDd;3;372E;D;K;6;CP$UIDd;3;373E;D;K;6;CP$UIDd;3;375E;D;K;6;CP$UIDd;3;376E;D;K;6;CP$UIDd;3;377E;D;K;6;CP$UIDd;3;378E;D;K;6;CP$UIDd;3;379E;D;K;6;CP$UIDd;3;380E;D;K;6;CP$UIDd;3;381E;D;K;6;CP$UIDd;3;382E;D;K;6;CP$UIDd;3;383E;D;K;6;CP$UIDd;3;384E;E;E;S;16;IBCocoaFrameworkd;3;490D;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;21E;D;K;6;CP$UIDd;2;23E;D;K;6;CP$UIDd;2;25E;D;K;6;CP$UIDd;2;26E;D;K;6;CP$UIDd;2;27E;D;K;6;CP$UIDd;2;28E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;30E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;2;32E;D;K;6;CP$UIDd;2;33E;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;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;43E;D;K;6;CP$UIDd;2;44E;D;K;6;CP$UIDd;2;45E;D;K;6;CP$UIDd;2;46E;D;K;6;CP$UIDd;2;47E;D;K;6;CP$UIDd;2;48E;D;K;6;CP$UIDd;2;49E;D;K;6;CP$UIDd;2;51E;D;K;6;CP$UIDd;2;50E;D;K;6;CP$UIDd;2;52E;D;K;6;CP$UIDd;2;54E;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;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;72E;D;K;6;CP$UIDd;2;71E;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;79E;D;K;6;CP$UIDd;2;81E;D;K;6;CP$UIDd;2;82E;D;K;6;CP$UIDd;2;80E;D;K;6;CP$UIDd;2;77E;D;K;6;CP$UIDd;2;78E;D;K;6;CP$UIDd;2;83E;D;K;6;CP$UIDd;2;86E;D;K;6;CP$UIDd;2;84E;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;96E;D;K;6;CP$UIDd;2;93E;D;K;6;CP$UIDd;2;92E;D;K;6;CP$UIDd;2;91E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;94E;D;K;6;CP$UIDd;2;95E;D;K;6;CP$UIDd;2;90E;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;102E;D;K;6;CP$UIDd;3;101E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;103E;D;K;6;CP$UIDd;3;104E;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;113E;D;K;6;CP$UIDd;3;114E;D;K;6;CP$UIDd;3;116E;D;K;6;CP$UIDd;3;115E;D;K;6;CP$UIDd;3;117E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;118E;D;K;6;CP$UIDd;3;119E;D;K;6;CP$UIDd;3;120E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;3;122E;D;K;6;CP$UIDd;3;123E;D;K;6;CP$UIDd;3;124E;D;K;6;CP$UIDd;3;126E;D;K;6;CP$UIDd;3;127E;D;K;6;CP$UIDd;3;128E;D;K;6;CP$UIDd;3;129E;D;K;6;CP$UIDd;3;131E;D;K;6;CP$UIDd;3;130E;D;K;6;CP$UIDd;3;133E;D;K;6;CP$UIDd;3;132E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;136E;D;K;6;CP$UIDd;3;134E;D;K;6;CP$UIDd;3;135E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;137E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;138E;D;K;6;CP$UIDd;3;139E;D;K;6;CP$UIDd;3;140E;D;K;6;CP$UIDd;3;144E;D;K;6;CP$UIDd;3;142E;D;K;6;CP$UIDd;3;143E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;141E;D;K;6;CP$UIDd;3;145E;D;K;6;CP$UIDd;3;146E;D;K;6;CP$UIDd;3;147E;D;K;6;CP$UIDd;3;148E;D;K;6;CP$UIDd;3;149E;D;K;6;CP$UIDd;3;151E;D;K;6;CP$UIDd;3;150E;D;K;6;CP$UIDd;3;152E;D;K;6;CP$UIDd;3;153E;D;K;6;CP$UIDd;3;155E;D;K;6;CP$UIDd;3;154E;D;K;6;CP$UIDd;3;156E;D;K;6;CP$UIDd;3;157E;D;K;6;CP$UIDd;3;158E;D;K;6;CP$UIDd;3;159E;D;K;6;CP$UIDd;3;160E;D;K;6;CP$UIDd;3;161E;D;K;6;CP$UIDd;3;162E;D;K;6;CP$UIDd;3;163E;D;K;6;CP$UIDd;3;164E;D;K;6;CP$UIDd;3;166E;D;K;6;CP$UIDd;3;165E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;95E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;2;71E;D;K;6;CP$UIDd;2;39E;D;K;6;CP$UIDd;2;98E;D;K;6;CP$UIDd;3;153E;D;K;6;CP$UIDd;2;32E;D;K;6;CP$UIDd;3;132E;D;K;6;CP$UIDd;2;44E;D;K;6;CP$UIDd;3;153E;D;K;6;CP$UIDd;2;74E;D;K;6;CP$UIDd;2;32E;D;K;6;CP$UIDd;2;32E;D;K;6;CP$UIDd;2;91E;D;K;6;CP$UIDd;2;16E;D;K;6;CP$UIDd;3;136E;D;K;6;CP$UIDd;3;141E;D;K;6;CP$UIDd;2;86E;D;K;6;CP$UIDd;2;39E;D;K;6;CP$UIDd;2;45E;D;K;6;CP$UIDd;2;40E;D;K;6;CP$UIDd;3;105E;D;K;6;CP$UIDd;2;50E;D;K;6;CP$UIDd;2;16E;D;K;6;CP$UIDd;3;164E;D;K;6;CP$UIDd;2;39E;D;K;6;CP$UIDd;3;132E;D;K;6;CP$UIDd;2;39E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;3;108E;D;K;6;CP$UIDd;2;44E;D;K;6;CP$UIDd;3;142E;D;K;6;CP$UIDd;2;16E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;3;124E;D;K;6;CP$UIDd;3;131E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;2;98E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;2;86E;D;K;6;CP$UIDd;3;153E;D;K;6;CP$UIDd;3;124E;D;K;6;CP$UIDd;2;16E;D;K;6;CP$UIDd;3;145E;D;K;6;CP$UIDd;2;32E;D;K;6;CP$UIDd;3;153E;D;K;6;CP$UIDd;3;132E;D;K;6;CP$UIDd;3;108E;D;K;6;CP$UIDd;3;124E;D;K;6;CP$UIDd;2;98E;D;K;6;CP$UIDd;2;98E;D;K;6;CP$UIDd;2;45E;D;K;6;CP$UIDd;2;45E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;2;95E;D;K;6;CP$UIDd;3;145E;D;K;6;CP$UIDd;2;44E;D;K;6;CP$UIDd;2;91E;D;K;6;CP$UIDd;2;86E;D;K;6;CP$UIDd;2;39E;D;K;6;CP$UIDd;3;126E;D;K;6;CP$UIDd;2;39E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;3;153E;D;K;6;CP$UIDd;2;39E;D;K;6;CP$UIDd;3;136E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;2;98E;D;K;6;CP$UIDd;3;134E;D;K;6;CP$UIDd;2;83E;D;K;6;CP$UIDd;2;89E;D;K;6;CP$UIDd;3;132E;D;K;6;CP$UIDd;3;133E;D;K;6;CP$UIDd;2;39E;D;K;6;CP$UIDd;3;131E;D;K;6;CP$UIDd;2;30E;D;K;6;CP$UIDd;2;44E;D;K;6;CP$UIDd;3;124E;D;K;6;CP$UIDd;3;136E;D;K;6;CP$UIDd;2;98E;D;K;6;CP$UIDd;2;46E;D;K;6;CP$UIDd;3;108E;D;K;6;CP$UIDd;3;153E;D;K;6;CP$UIDd;2;99E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;3;148E;D;K;6;CP$UIDd;2;44E;D;K;6;CP$UIDd;3;105E;D;K;6;CP$UIDd;3;124E;D;K;6;CP$UIDd;2;45E;D;K;6;CP$UIDd;3;132E;D;K;6;CP$UIDd;3;124E;D;K;6;CP$UIDd;2;95E;D;K;6;CP$UIDd;3;136E;D;K;6;CP$UIDd;3;153E;D;K;6;CP$UIDd;3;154E;D;K;6;CP$UIDd;3;153E;D;K;6;CP$UIDd;2;98E;D;K;6;CP$UIDd;2;23E;D;K;6;CP$UIDd;2;25E;D;K;6;CP$UIDd;2;35E;D;K;6;CP$UIDd;2;39E;D;K;6;CP$UIDd;3;132E;D;K;6;CP$UIDd;3;109E;D;K;6;CP$UIDd;2;54E;D;K;6;CP$UIDd;2;98E;D;K;6;CP$UIDd;3;153E;D;K;6;CP$UIDd;3;153E;D;K;6;CP$UIDd;3;143E;D;K;6;CP$UIDd;3;124E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;2;77E;D;K;6;CP$UIDd;2;48E;D;K;6;CP$UIDd;2;79E;D;K;6;CP$UIDd;2;44E;D;K;6;CP$UIDd;2;98E;D;K;6;CP$UIDd;2;90E;D;K;6;CP$UIDd;3;131E;D;K;6;CP$UIDd;2;84E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;3;108E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;2;92E;D;K;6;CP$UIDd;2;98E;D;K;6;CP$UIDd;3;122E;D;K;6;CP$UIDd;2;39E;D;K;6;CP$UIDd;3;138E;D;K;6;CP$UIDd;2;98E;D;K;6;CP$UIDd;2;98E;D;K;6;CP$UIDd;2;44E;D;K;6;CP$UIDd;3;124E;D;K;6;CP$UIDd;2;95E;D;K;6;CP$UIDd;3;132E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;2;80E;D;K;6;CP$UIDd;3;142E;D;K;6;CP$UIDd;2;39E;D;K;6;CP$UIDd;3;145E;D;K;6;CP$UIDd;3;124E;D;K;6;CP$UIDd;3;136E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;3;124E;D;K;6;CP$UIDd;2;43E;D;K;6;CP$UIDd;3;132E;D;K;6;CP$UIDd;2;32E;D;K;6;CP$UIDd;2;98E;D;K;6;CP$UIDd;3;153E;D;K;6;CP$UIDd;3;124E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;325E;D;K;6;CP$UIDd;3;380E;D;K;6;CP$UIDd;2;21E;D;K;6;CP$UIDd;2;23E;D;K;6;CP$UIDd;3;336E;D;K;6;CP$UIDd;2;26E;D;K;6;CP$UIDd;3;339E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;32E;D;K;6;CP$UIDd;2;34E;D;K;6;CP$UIDd;2;33E;D;K;6;CP$UIDd;2;37E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;375E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;373E;D;K;6;CP$UIDd;2;42E;D;K;6;CP$UIDd;2;44E;D;K;6;CP$UIDd;2;45E;D;K;6;CP$UIDd;2;46E;D;K;6;CP$UIDd;2;48E;D;K;6;CP$UIDd;3;364E;D;K;6;CP$UIDd;3;328E;D;K;6;CP$UIDd;2;50E;D;K;6;CP$UIDd;2;54E;D;K;6;CP$UIDd;3;366E;D;K;6;CP$UIDd;3;370E;D;K;6;CP$UIDd;2;57E;D;K;6;CP$UIDd;2;58E;D;K;6;CP$UIDd;2;60E;D;K;6;CP$UIDd;3;354E;D;K;6;CP$UIDd;2;63E;D;K;6;CP$UIDd;2;64E;D;K;6;CP$UIDd;3;332E;D;K;6;CP$UIDd;2;67E;D;K;6;CP$UIDd;3;327E;D;K;6;CP$UIDd;2;70E;D;K;6;CP$UIDd;2;72E;D;K;6;CP$UIDd;2;74E;D;K;6;CP$UIDd;2;75E;D;K;6;CP$UIDd;2;77E;D;K;6;CP$UIDd;3;323E;D;K;6;CP$UIDd;2;82E;D;K;6;CP$UIDd;2;86E;D;K;6;CP$UIDd;3;368E;D;K;6;CP$UIDd;2;87E;D;K;6;CP$UIDd;2;89E;D;K;6;CP$UIDd;2;96E;D;K;6;CP$UIDd;3;363E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;98E;D;K;6;CP$UIDd;2;99E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;103E;D;K;6;CP$UIDd;3;352E;D;K;6;CP$UIDd;3;108E;D;K;6;CP$UIDd;3;110E;D;K;6;CP$UIDd;3;322E;D;K;6;CP$UIDd;3;111E;D;K;6;CP$UIDd;3;362E;D;K;6;CP$UIDd;3;112E;D;K;6;CP$UIDd;3;381E;D;K;6;CP$UIDd;3;113E;D;K;6;CP$UIDd;3;361E;D;K;6;CP$UIDd;3;337E;D;K;6;CP$UIDd;3;114E;D;K;6;CP$UIDd;3;116E;D;K;6;CP$UIDd;3;117E;D;K;6;CP$UIDd;3;365E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;341E;D;K;6;CP$UIDd;3;118E;D;K;6;CP$UIDd;3;119E;D;K;6;CP$UIDd;3;120E;D;K;6;CP$UIDd;3;321E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;347E;D;K;6;CP$UIDd;3;351E;D;K;6;CP$UIDd;3;358E;D;K;6;CP$UIDd;3;359E;D;K;6;CP$UIDd;3;340E;D;K;6;CP$UIDd;3;326E;D;K;6;CP$UIDd;3;127E;D;K;6;CP$UIDd;3;129E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;132E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;137E;D;K;6;CP$UIDd;3;138E;D;K;6;CP$UIDd;3;139E;D;K;6;CP$UIDd;3;369E;D;K;6;CP$UIDd;3;141E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;376E;D;K;6;CP$UIDd;3;371E;D;K;6;CP$UIDd;3;145E;D;K;6;CP$UIDd;3;147E;D;K;6;CP$UIDd;3;148E;D;K;6;CP$UIDd;3;152E;D;K;6;CP$UIDd;3;153E;D;K;6;CP$UIDd;3;155E;D;K;6;CP$UIDd;3;154E;D;K;6;CP$UIDd;3;383E;D;K;6;CP$UIDd;3;159E;D;K;6;CP$UIDd;3;160E;D;K;6;CP$UIDd;3;161E;D;K;6;CP$UIDd;3;367E;D;K;6;CP$UIDd;3;330E;D;K;6;CP$UIDd;3;320E;D;K;6;CP$UIDd;3;165E;D;K;6;CP$UIDd;3;324E;D;K;6;CP$UIDd;2;20E;D;K;6;CP$UIDd;3;333E;D;K;6;CP$UIDd;2;25E;D;K;6;CP$UIDd;3;342E;D;K;6;CP$UIDd;2;27E;D;K;6;CP$UIDd;2;28E;D;K;6;CP$UIDd;3;384E;D;K;6;CP$UIDd;3;353E;D;K;6;CP$UIDd;3;382E;D;K;6;CP$UIDd;2;30E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;2;35E;D;K;6;CP$UIDd;2;36E;D;K;6;CP$UIDd;3;360E;D;K;6;CP$UIDd;2;39E;D;K;6;CP$UIDd;2;16E;D;K;6;CP$UIDd;2;40E;D;K;6;CP$UIDd;2;41E;D;K;6;CP$UIDd;3;331E;D;K;6;CP$UIDd;3;355E;D;K;6;CP$UIDd;2;43E;D;K;6;CP$UIDd;2;47E;D;K;6;CP$UIDd;2;49E;D;K;6;CP$UIDd;2;51E;D;K;6;CP$UIDd;3;345E;D;K;6;CP$UIDd;2;52E;D;K;6;CP$UIDd;2;55E;D;K;6;CP$UIDd;3;346E;D;K;6;CP$UIDd;2;56E;D;K;6;CP$UIDd;3;356E;D;K;6;CP$UIDd;2;59E;D;K;6;CP$UIDd;2;61E;D;K;6;CP$UIDd;2;65E;D;K;6;CP$UIDd;2;66E;D;K;6;CP$UIDd;2;68E;D;K;6;CP$UIDd;2;69E;D;K;6;CP$UIDd;2;71E;D;K;6;CP$UIDd;2;73E;D;K;6;CP$UIDd;3;338E;D;K;6;CP$UIDd;2;76E;D;K;6;CP$UIDd;2;79E;D;K;6;CP$UIDd;3;344E;D;K;6;CP$UIDd;2;81E;D;K;6;CP$UIDd;2;78E;D;K;6;CP$UIDd;2;80E;D;K;6;CP$UIDd;3;335E;D;K;6;CP$UIDd;2;83E;D;K;6;CP$UIDd;2;84E;D;K;6;CP$UIDd;2;88E;D;K;6;CP$UIDd;2;90E;D;K;6;CP$UIDd;2;93E;D;K;6;CP$UIDd;2;92E;D;K;6;CP$UIDd;2;91E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;348E;D;K;6;CP$UIDd;2;94E;D;K;6;CP$UIDd;2;95E;D;K;6;CP$UIDd;2;97E;D;K;6;CP$UIDd;3;102E;D;K;6;CP$UIDd;3;100E;D;K;6;CP$UIDd;3;101E;D;K;6;CP$UIDd;3;104E;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;329E;D;K;6;CP$UIDd;3;109E;D;K;6;CP$UIDd;3;377E;D;K;6;CP$UIDd;3;115E;D;K;6;CP$UIDd;3;357E;D;K;6;CP$UIDd;3;378E;D;K;6;CP$UIDd;3;343E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;3;122E;D;K;6;CP$UIDd;3;123E;D;K;6;CP$UIDd;3;124E;D;K;6;CP$UIDd;3;126E;D;K;6;CP$UIDd;3;131E;D;K;6;CP$UIDd;3;128E;D;K;6;CP$UIDd;3;130E;D;K;6;CP$UIDd;3;133E;D;K;6;CP$UIDd;3;136E;D;K;6;CP$UIDd;3;134E;D;K;6;CP$UIDd;3;135E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;140E;D;K;6;CP$UIDd;3;144E;D;K;6;CP$UIDd;3;142E;D;K;6;CP$UIDd;3;143E;D;K;6;CP$UIDd;3;350E;D;K;6;CP$UIDd;3;372E;D;K;6;CP$UIDd;3;146E;D;K;6;CP$UIDd;3;149E;D;K;6;CP$UIDd;3;150E;D;K;6;CP$UIDd;3;151E;D;K;6;CP$UIDd;3;349E;D;K;6;CP$UIDd;3;334E;D;K;6;CP$UIDd;3;156E;D;K;6;CP$UIDd;3;157E;D;K;6;CP$UIDd;3;158E;D;K;6;CP$UIDd;3;379E;D;K;6;CP$UIDd;3;162E;D;K;6;CP$UIDd;3;163E;D;K;6;CP$UIDd;3;164E;D;K;6;CP$UIDd;3;166E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;385E;D;K;6;CP$UIDd;3;386E;D;K;6;CP$UIDd;3;387E;D;K;6;CP$UIDd;3;388E;D;K;6;CP$UIDd;3;389E;D;K;6;CP$UIDd;3;390E;D;K;6;CP$UIDd;3;391E;D;K;6;CP$UIDd;3;392E;D;K;6;CP$UIDd;3;393E;D;K;6;CP$UIDd;3;394E;D;K;6;CP$UIDd;3;395E;D;K;6;CP$UIDd;3;396E;D;K;6;CP$UIDd;3;397E;D;K;6;CP$UIDd;3;398E;D;K;6;CP$UIDd;3;399E;D;K;6;CP$UIDd;3;400E;D;K;6;CP$UIDd;3;401E;D;K;6;CP$UIDd;3;402E;D;K;6;CP$UIDd;3;403E;D;K;6;CP$UIDd;3;404E;D;K;6;CP$UIDd;3;405E;D;K;6;CP$UIDd;3;406E;D;K;6;CP$UIDd;3;407E;D;K;6;CP$UIDd;3;408E;D;K;6;CP$UIDd;3;409E;D;K;6;CP$UIDd;3;410E;D;K;6;CP$UIDd;3;411E;D;K;6;CP$UIDd;3;412E;D;K;6;CP$UIDd;3;413E;D;K;6;CP$UIDd;3;414E;D;K;6;CP$UIDd;3;415E;D;K;6;CP$UIDd;3;416E;D;K;6;CP$UIDd;3;417E;D;K;6;CP$UIDd;3;418E;D;K;6;CP$UIDd;3;419E;D;K;6;CP$UIDd;3;420E;D;K;6;CP$UIDd;3;421E;D;K;6;CP$UIDd;3;422E;D;K;6;CP$UIDd;3;423E;D;K;6;CP$UIDd;3;424E;D;K;6;CP$UIDd;3;425E;D;K;6;CP$UIDd;3;426E;D;K;6;CP$UIDd;3;427E;D;K;6;CP$UIDd;3;428E;D;K;6;CP$UIDd;3;429E;D;K;6;CP$UIDd;3;430E;D;K;6;CP$UIDd;3;431E;D;K;6;CP$UIDd;3;432E;D;K;6;CP$UIDd;3;433E;D;K;6;CP$UIDd;3;434E;D;K;6;CP$UIDd;3;435E;D;K;6;CP$UIDd;3;436E;D;K;6;CP$UIDd;3;437E;D;K;6;CP$UIDd;3;438E;D;K;6;CP$UIDd;3;439E;D;K;6;CP$UIDd;3;440E;D;K;6;CP$UIDd;3;441E;D;K;6;CP$UIDd;3;442E;D;K;6;CP$UIDd;3;443E;D;K;6;CP$UIDd;3;444E;D;K;6;CP$UIDd;3;445E;D;K;6;CP$UIDd;3;446E;D;K;6;CP$UIDd;3;447E;D;K;6;CP$UIDd;3;448E;D;K;6;CP$UIDd;3;449E;D;K;6;CP$UIDd;3;450E;D;K;6;CP$UIDd;3;451E;D;K;6;CP$UIDd;3;452E;D;K;6;CP$UIDd;3;453E;D;K;6;CP$UIDd;3;454E;D;K;6;CP$UIDd;3;455E;D;K;6;CP$UIDd;3;456E;D;K;6;CP$UIDd;3;457E;D;K;6;CP$UIDd;3;458E;D;K;6;CP$UIDd;3;459E;D;K;6;CP$UIDd;3;460E;D;K;6;CP$UIDd;3;461E;D;K;6;CP$UIDd;3;462E;D;K;6;CP$UIDd;3;463E;D;K;6;CP$UIDd;3;464E;D;K;6;CP$UIDd;3;465E;D;K;6;CP$UIDd;3;466E;D;K;6;CP$UIDd;3;467E;D;K;6;CP$UIDd;3;468E;D;K;6;CP$UIDd;3;469E;D;K;6;CP$UIDd;3;470E;D;K;6;CP$UIDd;3;471E;D;K;6;CP$UIDd;3;472E;D;K;6;CP$UIDd;3;473E;D;K;6;CP$UIDd;3;474E;D;K;6;CP$UIDd;3;475E;D;K;6;CP$UIDd;3;476E;D;K;6;CP$UIDd;3;477E;D;K;6;CP$UIDd;3;478E;D;K;6;CP$UIDd;3;479E;D;K;6;CP$UIDd;3;480E;D;K;6;CP$UIDd;3;481E;D;K;6;CP$UIDd;3;482E;D;K;6;CP$UIDd;3;483E;D;K;6;CP$UIDd;3;484E;D;K;6;CP$UIDd;3;485E;D;K;6;CP$UIDd;3;486E;D;K;6;CP$UIDd;3;487E;D;K;6;CP$UIDd;3;488E;D;K;6;CP$UIDd;3;489E;D;K;6;CP$UIDd;3;490E;D;K;6;CP$UIDd;3;491E;D;K;6;CP$UIDd;3;492E;D;K;6;CP$UIDd;3;493E;D;K;6;CP$UIDd;3;494E;D;K;6;CP$UIDd;3;495E;D;K;6;CP$UIDd;3;496E;D;K;6;CP$UIDd;3;497E;D;K;6;CP$UIDd;3;498E;D;K;6;CP$UIDd;3;499E;D;K;6;CP$UIDd;3;500E;D;K;6;CP$UIDd;3;501E;D;K;6;CP$UIDd;3;502E;D;K;6;CP$UIDd;3;503E;D;K;6;CP$UIDd;3;504E;D;K;6;CP$UIDd;3;505E;D;K;6;CP$UIDd;3;506E;D;K;6;CP$UIDd;3;507E;D;K;6;CP$UIDd;3;508E;D;K;6;CP$UIDd;3;509E;D;K;6;CP$UIDd;3;510E;D;K;6;CP$UIDd;3;511E;D;K;6;CP$UIDd;3;512E;D;K;6;CP$UIDd;3;513E;D;K;6;CP$UIDd;3;514E;D;K;6;CP$UIDd;3;515E;D;K;6;CP$UIDd;3;516E;D;K;6;CP$UIDd;3;517E;D;K;6;CP$UIDd;3;518E;D;K;6;CP$UIDd;3;519E;D;K;6;CP$UIDd;3;520E;D;K;6;CP$UIDd;3;521E;D;K;6;CP$UIDd;3;522E;D;K;6;CP$UIDd;3;523E;D;K;6;CP$UIDd;3;524E;D;K;6;CP$UIDd;3;525E;D;K;6;CP$UIDd;3;526E;D;K;6;CP$UIDd;3;527E;D;K;6;CP$UIDd;3;528E;D;K;6;CP$UIDd;3;529E;D;K;6;CP$UIDd;3;530E;D;K;6;CP$UIDd;3;531E;D;K;6;CP$UIDd;3;532E;D;K;6;CP$UIDd;3;533E;D;K;6;CP$UIDd;3;534E;D;K;6;CP$UIDd;3;535E;D;K;6;CP$UIDd;3;536E;D;K;6;CP$UIDd;3;537E;D;K;6;CP$UIDd;3;538E;D;K;6;CP$UIDd;3;539E;D;K;6;CP$UIDd;3;540E;D;K;6;CP$UIDd;3;541E;D;K;6;CP$UIDd;3;542E;D;K;6;CP$UIDd;3;543E;D;K;6;CP$UIDd;3;544E;D;K;6;CP$UIDd;3;545E;D;K;6;CP$UIDd;3;546E;D;K;6;CP$UIDd;3;547E;D;K;6;CP$UIDd;3;548E;D;K;6;CP$UIDd;3;549E;D;K;6;CP$UIDd;3;550E;D;K;6;CP$UIDd;3;551E;D;K;6;CP$UIDd;3;552E;D;K;6;CP$UIDd;3;553E;D;K;6;CP$UIDd;3;554E;D;K;6;CP$UIDd;3;555E;D;K;6;CP$UIDd;3;556E;D;K;6;CP$UIDd;3;557E;D;K;6;CP$UIDd;3;558E;D;K;6;CP$UIDd;3;559E;D;K;6;CP$UIDd;3;560E;D;K;6;CP$UIDd;3;561E;D;K;6;CP$UIDd;3;562E;D;K;6;CP$UIDd;3;563E;D;K;6;CP$UIDd;3;564E;D;K;6;CP$UIDd;3;565E;D;K;6;CP$UIDd;3;566E;D;K;6;CP$UIDd;3;567E;D;K;6;CP$UIDd;3;568E;D;K;6;CP$UIDd;3;569E;D;K;6;CP$UIDd;3;570E;D;K;6;CP$UIDd;3;571E;D;K;6;CP$UIDd;3;572E;D;K;6;CP$UIDd;3;573E;D;K;6;CP$UIDd;3;574E;D;K;6;CP$UIDd;3;575E;D;K;6;CP$UIDd;3;576E;D;K;6;CP$UIDd;3;577E;D;K;6;CP$UIDd;3;578E;D;K;6;CP$UIDd;3;579E;D;K;6;CP$UIDd;3;580E;D;K;6;CP$UIDd;3;581E;D;K;6;CP$UIDd;3;582E;D;K;6;CP$UIDd;3;583E;D;K;6;CP$UIDd;3;584E;D;K;6;CP$UIDd;3;585E;D;K;6;CP$UIDd;3;586E;D;K;6;CP$UIDd;3;587E;D;K;6;CP$UIDd;3;588E;D;K;6;CP$UIDd;3;589E;D;K;6;CP$UIDd;3;590E;D;K;6;CP$UIDd;3;591E;D;K;6;CP$UIDd;3;592E;D;K;6;CP$UIDd;3;593E;D;K;6;CP$UIDd;3;594E;D;K;6;CP$UIDd;3;595E;D;K;6;CP$UIDd;3;596E;D;K;6;CP$UIDd;3;597E;D;K;6;CP$UIDd;3;598E;D;K;6;CP$UIDd;3;599E;D;K;6;CP$UIDd;3;600E;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;601E;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;602E;E;D;K;10;$classnameS;10;CPMenuItemK;8;$classesA;S;10;CPMenuItemS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;603E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;95E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;604E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;121E;E;D;K;10;$classnameS;6;CPMenuK;8;$classesA;S;6;CPMenuS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;22E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;605E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;606E;E;D;K;10;$classnameS;13;CPTableColumnK;8;$classesA;S;13;CPTableColumnS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;26;CPTableColumnIdentifierKeyD;K;6;CP$UIDd;3;197E;K;21;CPTableColumnWidthKeyD;K;6;CP$UIDd;3;607E;K;24;CPTableColumnMinWidthKeyD;K;6;CP$UIDd;3;608E;K;24;CPTableColumnMaxWidthKeyD;K;6;CP$UIDd;3;609E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;610E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;611E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;612E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;98E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;610E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;611E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;612E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;153E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;613E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;32E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;614E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;132E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;615E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;616E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;2;98E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;44E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;617E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;616E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;2;93E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;153E;E;D;K;6;$classD;K;6;CP$UIDd;2;22E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;618E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;619E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;620E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;32E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;621E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;32E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;622E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;616E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;3;121E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;91E;E;D;K;6;$classD;K;6;CP$UIDd;2;15E;K;27;_CPCibCustomObjectClassNameD;K;6;CP$UIDd;3;623E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;624E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;136E;E;D;K;10;$classnameS;11;CPTableViewK;8;$classesA;S;11;CPTableViewS;9;CPControlS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;38E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;625E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;626E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;626E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;625E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;627E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;628E;K;24;CPTableViewDataSourceKeyD;K;6;CP$UIDd;1;0E;K;22;CPTableViewDelegateKeyD;K;6;CP$UIDd;1;0E;K;23;CPTableViewRowHeightKeyD;K;6;CP$UIDd;3;629E;K;30;CPTableViewIntercellSpacingKeyD;K;6;CP$UIDd;3;630E;K;31;CPTableViewMultipleSelectionKeyD;K;6;CP$UIDd;3;612E;K;28;CPTableViewEmptySelectionKeyD;K;6;CP$UIDd;3;610E;K;26;CPTableViewTableColumnsKeyD;K;6;CP$UIDd;3;631E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;26;CPTableColumnIdentifierKeyD;K;6;CP$UIDd;3;632E;K;21;CPTableColumnWidthKeyD;K;6;CP$UIDd;3;633E;K;24;CPTableColumnMinWidthKeyD;K;6;CP$UIDd;3;634E;K;24;CPTableColumnMaxWidthKeyD;K;6;CP$UIDd;3;635E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;636E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;45E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;637E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;105E;E;D;K;6;$classD;K;6;CP$UIDd;2;22E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;638E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;639E;E;D;K;6;$classD;K;6;CP$UIDd;2;22E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;640E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;641E;E;D;K;6;$classD;K;6;CP$UIDd;2;22E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;642E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;643E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;26;CPTableColumnIdentifierKeyD;K;6;CP$UIDd;3;202E;K;21;CPTableColumnWidthKeyD;K;6;CP$UIDd;3;633E;K;24;CPTableColumnMinWidthKeyD;K;6;CP$UIDd;3;634E;K;24;CPTableColumnMaxWidthKeyD;K;6;CP$UIDd;3;635E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;644E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;132E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;26;CPTableColumnIdentifierKeyD;K;6;CP$UIDd;3;645E;K;21;CPTableColumnWidthKeyD;K;6;CP$UIDd;3;646E;K;24;CPTableColumnMinWidthKeyD;K;6;CP$UIDd;3;608E;K;24;CPTableColumnMaxWidthKeyD;K;6;CP$UIDd;3;609E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;647E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;121E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;638E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;616E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;2;43E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;44E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;648E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;108E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;649E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;142E;E;D;K;10;$classnameS;20;_CPCibWindowTemplateK;8;$classesA;S;20;_CPCibWindowTemplateS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;53E;K;30;_CPCibWindowTemplateMaxSizeKeyD;K;6;CP$UIDd;3;650E;K;32;_CPCibWindowTemplateViewClassKeyD;K;6;CP$UIDd;1;0E;K;34;_CPCibWindowTemplateWindowClassKeyD;K;6;CP$UIDd;3;651E;K;33;_CPCibWindowTemplateWindowRectKeyD;K;6;CP$UIDd;3;652E;K;30;_CPCibWindowTempatStyleMaskKeyD;K;6;CP$UIDd;3;653E;K;34;_CPCibWindowTemplateWindowTitleKeyD;K;6;CP$UIDd;3;654E;K;33;_CPCibWindowTemplateWindowViewKeyD;K;6;CP$UIDd;3;126E;K;41;_CPCibWindowTemplateWindowIsFullBridgeKeyD;K;6;CP$UIDd;3;612E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;655E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;121E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;656E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;124E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;657E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;131E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;658E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;121E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;659E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;98E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;660E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;121E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;661E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;121E;E;D;K;10;$classnameS;10;CPScrollerK;8;$classesA;S;10;CPScrollerS;9;CPControlS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;62E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;86E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;662E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;663E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;86E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;664E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;665E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;666E;K;18;CPControlTargetKeyD;K;6;CP$UIDd;2;86E;K;18;CPControlActionKeyD;K;6;CP$UIDd;3;667E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;628E;K;21;CPScrollerControlSizeD;K;6;CP$UIDd;3;666E;K;24;CPScrollerKnobProportionD;K;6;CP$UIDd;3;668E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;610E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;611E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;612E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;153E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;610E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;611E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;612E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;124E;E;D;K;6;$classD;K;6;CP$UIDd;2;15E;K;27;_CPCibCustomObjectClassNameD;K;6;CP$UIDd;3;601E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;669E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;145E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;670E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;32E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;671E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;153E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;672E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;132E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;605E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;616E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;2;23E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;124E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;673E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;108E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;674E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;98E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;618E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;616E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;2;32E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;98E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;675E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;45E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;676E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;45E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;677E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;616E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;3;132E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;91E;E;D;K;6;$classD;K;6;CP$UIDd;2;62E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;86E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;678E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;679E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;86E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;664E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;627E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;666E;K;18;CPControlTargetKeyD;K;6;CP$UIDd;2;86E;K;18;CPControlActionKeyD;K;6;CP$UIDd;3;680E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;628E;K;21;CPScrollerControlSizeD;K;6;CP$UIDd;3;666E;K;24;CPScrollerKnobProportionD;K;6;CP$UIDd;3;681E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;682E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;616E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;3;136E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;121E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;683E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;616E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;3;153E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;44E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;669E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;95E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;684E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;145E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;26;CPTableColumnIdentifierKeyD;K;6;CP$UIDd;3;261E;K;21;CPTableColumnWidthKeyD;K;6;CP$UIDd;3;633E;K;24;CPTableColumnMinWidthKeyD;K;6;CP$UIDd;3;634E;K;24;CPTableColumnMaxWidthKeyD;K;6;CP$UIDd;3;635E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;26;CPTableColumnIdentifierKeyD;K;6;CP$UIDd;3;278E;K;21;CPTableColumnWidthKeyD;K;6;CP$UIDd;3;633E;K;24;CPTableColumnMinWidthKeyD;K;6;CP$UIDd;3;634E;K;24;CPTableColumnMaxWidthKeyD;K;6;CP$UIDd;3;635E;E;D;K;10;$classnameS;12;CPScrollViewK;8;$classesA;S;12;CPScrollViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;85E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;126E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;685E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;686E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;687E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;126E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;688E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;627E;K;23;CPScrollViewContentViewD;K;6;CP$UIDd;3;625E;K;21;CPScrollViewVScrollerD;K;6;CP$UIDd;2;63E;K;21;CPScrollViewHScrollerD;K;6;CP$UIDd;2;78E;K;23;CPScrollViewVLineScrollD;K;6;CP$UIDd;3;634E;K;23;CPScrollViewVPageScrollD;K;6;CP$UIDd;3;634E;K;23;CPScrollViewHLineScrollD;K;6;CP$UIDd;3;634E;K;23;CPScrollViewHPageScrollD;K;6;CP$UIDd;3;634E;K;24;CPScrollViewHasVScrollerD;K;6;CP$UIDd;3;610E;K;24;CPScrollViewHasHScrollerD;K;6;CP$UIDd;3;610E;K;29;CPScrollViewAutohidesScrollerD;K;6;CP$UIDd;3;612E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;610E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;611E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;612E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;121E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;690E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;153E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;26;CPTableColumnIdentifierKeyD;K;6;CP$UIDd;3;210E;K;21;CPTableColumnWidthKeyD;K;6;CP$UIDd;3;633E;K;24;CPTableColumnMinWidthKeyD;K;6;CP$UIDd;3;634E;K;24;CPTableColumnMaxWidthKeyD;K;6;CP$UIDd;3;635E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;26;CPTableColumnIdentifierKeyD;K;6;CP$UIDd;3;312E;K;21;CPTableColumnWidthKeyD;K;6;CP$UIDd;3;633E;K;24;CPTableColumnMinWidthKeyD;K;6;CP$UIDd;3;634E;K;24;CPTableColumnMaxWidthKeyD;K;6;CP$UIDd;3;635E;E;D;K;6;$classD;K;6;CP$UIDd;2;22E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;691E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;692E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;693E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;616E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;3;142E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;98E;E;D;K;6;$classD;K;6;CP$UIDd;2;22E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;617E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;694E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;695E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;132E;E;D;K;6;$classD;K;6;CP$UIDd;2;22E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;696E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;697E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;684E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;136E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;698E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;131E;E;D;K;6;$classD;K;6;CP$UIDd;2;22E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;615E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;699E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;700E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;616E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;3;105E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;44E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;610E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;611E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;612E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;124E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;701E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;98E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;702E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;136E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;703E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;108E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;704E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;153E;E;D;K;6;$classD;K;6;CP$UIDd;2;22E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;700E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;705E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;610E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;611E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;612E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;121E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;706E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;121E;E;D;K;6;$classD;K;6;CP$UIDd;2;22E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;654E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;707E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;708E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;616E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;3;124E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;44E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;709E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;105E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;710E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;124E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;711E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;45E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;712E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;132E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;713E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;124E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;714E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;136E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;684E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;95E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;610E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;611E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;612E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;153E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;715E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;153E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;610E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;611E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;612E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;98E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;716E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;23E;E;D;K;6;$classD;K;6;CP$UIDd;2;22E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;622E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;717E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;26;CPTableColumnIdentifierKeyD;K;6;CP$UIDd;3;190E;K;21;CPTableColumnWidthKeyD;K;6;CP$UIDd;3;633E;K;24;CPTableColumnMinWidthKeyD;K;6;CP$UIDd;3;634E;K;24;CPTableColumnMaxWidthKeyD;K;6;CP$UIDd;3;635E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;718E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;132E;E;D;K;6;$classD;K;6;CP$UIDd;2;22E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;708E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;719E;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;3;125E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;720E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;720E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;721E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;627E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;722E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;98E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;723E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;153E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;724E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;153E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;725E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;124E;E;D;K;6;$classD;K;6;CP$UIDd;2;22E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;726E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;727E;E;D;K;6;$classD;K;6;CP$UIDd;2;22E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;677E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;728E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;696E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;616E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;2;95E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;121E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;691E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;616E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;2;91E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;44E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;729E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;98E;E;D;K;6;$classD;K;6;CP$UIDd;2;22E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;682E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;730E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;731E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;131E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;732E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;616E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;3;145E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;121E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;610E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;611E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;612E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;121E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;610E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;611E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;612E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;108E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;26;CPTableColumnIdentifierKeyD;K;6;CP$UIDd;3;309E;K;21;CPTableColumnWidthKeyD;K;6;CP$UIDd;3;634E;K;24;CPTableColumnMinWidthKeyD;K;6;CP$UIDd;3;634E;K;24;CPTableColumnMaxWidthKeyD;K;6;CP$UIDd;3;635E;E;D;K;6;$classD;K;6;CP$UIDd;2;22E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;693E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;733E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;726E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;616E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;3;131E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;98E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;734E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;121E;E;D;K;6;$classD;K;6;CP$UIDd;2;22E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;732E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;735E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;736E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;98E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;737E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;98E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;654E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;616E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;3;108E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;44E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;738E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;124E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;610E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;611E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;612E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;132E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;739E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;95E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;740E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;121E;E;D;K;6;$classD;K;6;CP$UIDd;2;22E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;683E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;741E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;26;CPTableColumnIdentifierKeyD;K;6;CP$UIDd;3;301E;K;21;CPTableColumnWidthKeyD;K;6;CP$UIDd;3;633E;K;24;CPTableColumnMinWidthKeyD;K;6;CP$UIDd;3;634E;K;24;CPTableColumnMaxWidthKeyD;K;6;CP$UIDd;3;635E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;742E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;142E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;743E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;145E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;744E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;124E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;745E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;136E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;610E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;611E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;612E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;121E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;746E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;124E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;747E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;43E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;748E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;132E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;749E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;32E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;642E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;616E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;1;0E;K;18;CPMenuItemStateKeyD;K;6;CP$UIDd;1;0E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;2;45E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;98E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;750E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;124E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;610E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;611E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;612E;K;21;CPMenuItemIsHiddenKeyD;K;6;CP$UIDd;1;0E;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;3;153E;E;S;18;Menu Item (Loosen)S;19;Menu Item (Smaller)S;18;Menu (Open Recent)S;16;Table Column (1)S;9;SeparatorS;11;Separator-2S;25;Menu Item (Find Previous)S;18;Menu Item (Center)S;16;Menu Item (Edit)S;20;Menu Item (Services)S;11;Menu (Find)S;29;Menu Item (Jump to Selection)S;17;Menu Item (Find…)S;16;Menu Item (Font)S;14;App ControllerS;17;Menu Item (Raise)S;29;Text Field Cell (Text Cell)-9S;10;Table ViewS;12;File's OwnerS;16;Table Column (4)S;39;Menu Item (Check Spelling While Typing)S;29;Text Field Cell (Text Cell)-1S;24;Menu Item (Show Toolbar)S;1;2S;8;MainMenuS;27;Menu (Spelling and Grammar)S;16;Table Column (6)S;22;Menu Item (Copy Ruler)S;16;Table Column (0)S;22;Menu Item (Copy Style)S;1;1S;16;Menu Item (Zoom)S;25;Menu Item (Stop Speaking)S;15;Window (Window)S;22;Menu Item (Show Fonts)S;1;6S;23;Menu Item (Smart Links)S;16;Menu Item (Bold)S;16;Menu Item (Copy)S;18;Menu Item (Italic)S;23;Menu Item (Show Colors)S;17;Vertical ScrollerS;11;Separator-3S;1;7S;11;ApplicationS;22;Menu Item (Use None)-1S;34;Menu Item (Use Selection for Find)S;23;Menu Item (Hide Others)S;22;Menu Item (Align Left)S;23;Menu Item (Open Recent)S;30;Menu Item (Bring All to Front)S;16;Menu Item (Redo)S;16;Menu Item (Find)S;26;Menu Item (Check Spelling)S;26;Menu Item (Show Spelling…)S;16;Menu Item (Text)S;19;Horizontal ScrollerS;20;Menu Item (Baseline)S;26;Menu Item (NewApplication)S;20;Menu Item (Use None)S;25;Menu Item (Use Default)-2S;16;Table Column (5)S;16;Table Column (3)S;33;Bordered Scroll View (Table View)S;11;Separator-7S;32;Menu Item (About NewApplication)S;16;Table Column (7)S;16;Table Column (9)S;13;Menu (Format)S;18;Menu Item (Speech)S;15;Menu (Services)S;29;Text Field Cell (Text Cell)-4S;29;Text Field Cell (Text Cell)-6S;23;Menu Item (Align Right)S;11;Menu (Kern)S;23;Menu Item (Use Default)S;28;Menu Item (Smart Copy/Paste)S;11;Menu (Edit)S;16;Menu Item (View)S;3;2-1S;29;Text Field Cell (Text Cell)-2S;18;Menu Item (Delete)S;23;Menu Item (Superscript)S;20;Menu Item (Minimize)S;31;Menu Item (Hide NewApplication)S;11;Menu (View)S;11;Separator-8S;23;Menu Item (Paste Style)S;13;Menu (Window)S;16;Menu Item (File)S;30;Menu Item (Customize Toolbar…)S;3;1-1S;39;Menu Item (Check Grammar With Spelling)S;23;Menu Item (Paste Ruler)S;1;5S;21;Menu Item (Subscript)S;25;Menu Item (Use Default)-1S;11;Separator-4S;30;Text Field Cell (Text Cell)-10S;20;Menu Item (Show All)S;11;Separator-1S;22;Menu Item (Clear Menu)S;27;Text Field Cell (Text Cell)S;11;Menu (Font)S;16;Table Column (2)S;19;Menu Item (Justify)S;11;Menu (File)S;12;Content ViewS;16;Menu Item (Undo)S;3;121S;4;1111S;1;3S;20;Menu (Substitutions)S;11;Menu (Text)S;16;Menu Item (Kern)S;29;Text Field Cell (Text Cell)-3S;29;Text Field Cell (Text Cell)-7S;18;Menu Item (Format)S;22;Menu Item (Select All)S;15;Menu (Baseline)S;24;Menu Item (Smart Quotes)S;29;Text Field Cell (Text Cell)-5S;20;Menu Item (Ligature)S;11;Separator-9S;11;Separator-6S;17;Table Column (10)S;13;Menu (Speech)S;25;Menu Item (Substitutions)S;21;Menu Item (Underline)S;29;Text Field Cell (Text Cell)-8S;15;Menu (Ligature)S;15;Menu Item (Cut)S;17;Menu Item (Paste)S;18;Menu Item (Window)S;1;8S;12;Separator-11S;19;Menu Item (Tighten)S;18;Menu Item (Bigger)S;21;Menu (NewApplication)S;16;Table Column (8)S;26;Menu Item (Start Speaking)S;19;Menu Item (Use All)S;2;10S;17;Menu Item (Lower)S;12;Separator-10S;1;9S;31;Menu Item (NewApplication Help)S;22;Menu Item (Show Ruler)S;21;Menu Item (Find Next)S;32;Menu Item (Spelling and Grammar)S;17;Menu Item (Open…)S;11;Separator-5D;K;10;$classnameS;22;_CPCibControlConnectorK;8;$classesA;S;22;_CPCibControlConnectorS;15;_CPCibConnectorS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;42E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;751E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;33E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;752E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;52E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;753E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;112E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;754E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;69E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;755E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;116E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;756E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;20E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;757E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;130E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;758E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;76E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;759E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;110E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;760E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;127E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;761E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;146E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;762E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;101E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;763E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;157E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;764E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;49E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;765E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;151E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;766E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;61E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;767E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;144E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;768E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;29E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;769E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;161E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;770E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;88E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;16E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;771E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;51E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;772E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;149E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;773E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;158E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;774E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;118E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;775E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;81E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;776E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;107E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;777E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;102E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;778E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;129E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;66E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;779E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;156E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;780E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;137E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;781E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;147E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;782E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;41E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;783E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;96E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;784E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;56E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;785E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;82E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;786E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;103E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;787E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;120E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;788E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;57E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;789E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;115E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;790E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;135E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;791E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;113E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;792E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;75E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;793E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;70E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;794E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;59E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;795E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;104E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;796E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;72E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;797E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;34E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;798E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;162E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;799E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;165E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;800E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;73E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;801E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;155E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;802E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;97E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;803E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;160E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;804E;E;D;K;10;$classnameS;21;_CPCibOutletConnectorK;8;$classesA;S;21;_CPCibOutletConnectorS;15;_CPCibConnectorS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;374E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;16E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;36E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;805E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;114E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;806E;E;D;K;6;$classD;K;6;CP$UIDd;3;374E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;36E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;54E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;807E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;67E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;808E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;37E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;809E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;94E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;810E;E;D;K;6;$classD;K;6;CP$UIDd;3;374E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;39E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;36E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;811E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;111E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;812E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;47E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;813E;E;D;K;6;$classD;K;6;CP$UIDd;3;319E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;123E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;814E;E;d;3;438d;3;447d;3;395d;3;125d;3;433d;3;206d;3;360d;3;381d;3;220d;3;209d;3;210d;3;409d;3;486d;3;451d;3;474d;3;373d;3;297d;2;29d;3;200d;3;477d;3;465d;3;224d;3;230d;3;103d;3;371d;2;39d;3;231d;3;354d;3;390d;3;391d;2;86d;3;461d;3;236d;3;235d;3;413d;3;362d;3;380d;1;5d;3;218d;3;201d;3;378d;3;347d;3;412d;3;460d;3;446d;3;396d;3;479d;3;406d;3;442d;3;476d;3;205d;3;295d;3;478d;2;23d;3;222d;2;24d;3;298d;3;227d;2;73d;3;225d;3;346d;3;488d;3;387d;3;448d;3;432d;2;77d;3;416d;3;149d;3;367d;3;482d;3;240d;3;150d;3;214d;3;126d;3;245d;3;467d;3;430d;3;226d;3;357d;3;429d;3;142d;3;435d;3;207d;3;136d;3;484d;3;379d;3;468d;3;351d;3;398d;3;400d;3;374d;3;485d;3;470d;2;87d;3;233d;3;411d;3;203d;2;19d;3;394d;2;57d;3;196d;3;481d;3;444d;3;393d;2;82d;3;111d;3;241d;3;223d;3;366d;2;72d;3;368d;3;419d;3;364d;3;466d;3;363d;3;143d;3;213d;3;443d;3;437d;3;193d;3;217d;3;131d;3;377d;3;450d;3;232d;3;463d;3;489d;3;473d;3;219d;3;228d;3;439d;3;106d;3;386d;3;403d;3;239d;3;441d;3;195d;3;389d;3;436d;2;78d;2;37d;3;197d;3;401d;2;79d;2;-3d;3;221d;3;145d;3;124d;3;215d;3;445d;3;204d;3;399d;3;370d;3;417d;3;462d;2;56d;3;431d;3;475d;3;471d;2;58d;3;483d;3;130d;3;211d;3;376d;3;480d;3;449d;3;383d;3;415d;3;350d;3;407d;2;74d;3;202d;3;134d;3;296d;3;402d;3;404d;3;365d;2;83d;3;459d;3;408d;3;127d;3;440d;3;427d;3;388d;3;469d;3;382d;2;81d;3;372d;3;349d;3;129d;2;75d;3;397d;3;405d;3;375d;3;198d;3;472d;2;92d;3;392d;3;212d;3;348d;3;356d;3;355d;3;199d;2;80d;3;384d;3;418d;3;434d;3;428d;3;414d;3;112d;3;410d;3;426d;3;385d;3;208d;3;216d;3;144S;13;CPApplicationD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;54E;E;E;S;6;LoosenS;7;SmallerS;11;Open RecentD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;120E;E;E;d;2;67d;2;40d;4;1000T;S;0;F;S;13;Find PreviousS;6;CenterS;4;EditS;14;submenuAction:S;8;ServicesS;4;FindD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;34E;D;K;6;CP$UIDd;3;163E;D;K;6;CP$UIDd;2;28E;D;K;6;CP$UIDd;2;68E;D;K;6;CP$UIDd;2;33E;E;E;S;17;Jump to SelectionS;5;Find…S;4;FontS;13;AppControllerS;5;RaiseD;K;6;$classD;K;6;CP$UIDd;3;689E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;86E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;815E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;816E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;817E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;86E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;664E;K;21;CPViewBackgroundColorD;K;6;CP$UIDd;3;819E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;627E;K;24;CPScrollViewDocumentViewD;K;6;CP$UIDd;2;39E;E;S;20;{{0, 0}, {691, 348}}S;6;normald;1;4d;2;17S;6;{3, 2}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;48E;D;K;6;CP$UIDd;2;25E;D;K;6;CP$UIDd;3;122E;D;K;6;CP$UIDd;2;84E;D;K;6;CP$UIDd;2;40E;D;K;6;CP$UIDd;2;83E;D;K;6;CP$UIDd;2;46E;D;K;6;CP$UIDd;2;89E;D;K;6;CP$UIDd;3;154E;D;K;6;CP$UIDd;2;90E;D;K;6;CP$UIDd;3;141E;E;E;S;1;4d;2;64d;2;10d;22;3.4028230607370965e+38S;27;Check Spelling While TypingS;12;Show ToolbarS;4;HelpD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;161E;E;E;S;9;AMainMenuD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;80E;D;K;6;CP$UIDd;3;109E;D;K;6;CP$UIDd;2;30E;D;K;6;CP$UIDd;3;134E;D;K;6;CP$UIDd;2;99E;D;K;6;CP$UIDd;3;148E;D;K;6;CP$UIDd;2;50E;E;E;S;20;Spelling and GrammarD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;76E;D;K;6;CP$UIDd;2;75E;D;K;6;CP$UIDd;2;41E;D;K;6;CP$UIDd;3;112E;E;E;S;10;Copy RulerS;1;0d;2;69S;10;Copy StyleS;4;ZoomS;13;Stop SpeakingS;26;{3.40282e+38, 3.40282e+38}S;8;CPWindowS;24;{{335, 128}, {491, 363}}d;1;7S;6;WindowS;10;Show FontsS;6;Print…S;11;Smart LinksS;4;BoldS;4;CopyS;6;ItalicS;11;Show ColorsS;22;{{477, 16}, {17, 348}}S;19;{{0, 0}, {17, 348}}d;1;8S;17;disabled+verticald;1;0S;27;_verticalScrollerDidScroll:f;18;0.9971429109573364S;8;Use NoneS;22;Use Selection for FindS;11;Hide OthersS;10;Align LeftS;18;Bring All to FrontS;4;RedoS;14;Check SpellingS;14;Show Spelling…S;4;TextS;20;{{1, -1}, {476, 17}}S;19;{{0, 0}, {476, 17}}S;29;_horizontalScrollerDidScroll:f;18;0.6888567209243774S;8;BaselineS;14;NewApplicationS;11;Use DefaultS;22;{{-1, -1}, {493, 365}}S;20;{{0, 0}, {493, 365}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;625E;D;K;6;CP$UIDd;2;63E;D;K;6;CP$UIDd;2;78E;E;E;d;2;18D;K;10;$classnameS;10;CPClipViewK;8;$classesA;S;10;CPClipViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;S;20;About NewApplicationS;6;FormatD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;35E;D;K;6;CP$UIDd;2;77E;E;E;S;6;SpeechD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;S;11;Align RightS;4;KernD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;116E;D;K;6;CP$UIDd;2;81E;D;K;6;CP$UIDd;3;151E;D;K;6;CP$UIDd;2;20E;E;E;S;16;Smart Copy/PasteD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;127E;D;K;6;CP$UIDd;2;73E;D;K;6;CP$UIDd;2;26E;D;K;6;CP$UIDd;3;146E;D;K;6;CP$UIDd;2;59E;D;K;6;CP$UIDd;3;147E;D;K;6;CP$UIDd;3;101E;D;K;6;CP$UIDd;3;135E;D;K;6;CP$UIDd;3;119E;D;K;6;CP$UIDd;2;74E;D;K;6;CP$UIDd;3;164E;D;K;6;CP$UIDd;3;143E;D;K;6;CP$UIDd;2;92E;E;E;S;4;ViewS;6;DeleteS;11;SuperscriptS;8;MinimizeS;19;Hide NewApplicationD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;42E;D;K;6;CP$UIDd;3;110E;E;E;S;11;Paste StyleD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;103E;D;K;6;CP$UIDd;2;51E;D;K;6;CP$UIDd;3;140E;D;K;6;CP$UIDd;2;72E;E;E;S;4;FileS;18;Customize Toolbar…S;5;CloseS;27;Check Grammar With SpellingS;11;Paste RulerS;13;Page Setup...S;9;SubscriptS;8;Show AllS;10;Clear MenuD;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;58E;D;K;6;CP$UIDd;2;60E;D;K;6;CP$UIDd;3;144E;D;K;6;CP$UIDd;3;159E;D;K;6;CP$UIDd;3;152E;D;K;6;CP$UIDd;2;21E;D;K;6;CP$UIDd;2;87E;D;K;6;CP$UIDd;3;133E;D;K;6;CP$UIDd;3;138E;D;K;6;CP$UIDd;2;79E;D;K;6;CP$UIDd;3;139E;D;K;6;CP$UIDd;2;61E;D;K;6;CP$UIDd;3;106E;D;K;6;CP$UIDd;2;49E;D;K;6;CP$UIDd;3;107E;E;E;S;7;JustifyD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;160E;D;K;6;CP$UIDd;3;165E;D;K;6;CP$UIDd;2;71E;D;K;6;CP$UIDd;2;65E;D;K;6;CP$UIDd;3;111E;D;K;6;CP$UIDd;3;130E;D;K;6;CP$UIDd;3;149E;D;K;6;CP$UIDd;3;157E;D;K;6;CP$UIDd;3;100E;D;K;6;CP$UIDd;3;114E;D;K;6;CP$UIDd;2;56E;E;E;S;20;{{0, 0}, {491, 363}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;86E;E;E;S;4;UndoS;12;Preferences…S;19;Quit NewApplicationS;4;SaveS;13;SubstitutionsD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;97E;D;K;6;CP$UIDd;3;137E;D;K;6;CP$UIDd;2;57E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;70E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;3;123E;D;K;6;CP$UIDd;2;94E;D;K;6;CP$UIDd;3;150E;D;K;6;CP$UIDd;3;162E;D;K;6;CP$UIDd;2;47E;D;K;6;CP$UIDd;3;113E;E;E;S;10;Select AllD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;96E;D;K;6;CP$UIDd;3;102E;D;K;6;CP$UIDd;3;115E;D;K;6;CP$UIDd;2;37E;D;K;6;CP$UIDd;3;158E;E;E;S;12;Smart QuotesS;8;LigatureD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;155E;D;K;6;CP$UIDd;2;52E;E;E;S;9;UnderlineD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;82E;D;K;6;CP$UIDd;2;67E;D;K;6;CP$UIDd;3;156E;E;E;S;3;CutS;5;PasteS;8;Save As…S;7;TightenS;6;BiggerD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;88E;D;K;6;CP$UIDd;2;64E;D;K;6;CP$UIDd;3;128E;D;K;6;CP$UIDd;2;27E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;3;166E;D;K;6;CP$UIDd;3;104E;D;K;6;CP$UIDd;2;69E;D;K;6;CP$UIDd;3;118E;D;K;6;CP$UIDd;3;117E;D;K;6;CP$UIDd;3;129E;E;E;S;14;Start SpeakingS;7;Use AllS;15;Revert to SavedS;5;LowerS;3;NewS;19;NewApplication HelpS;10;Show RulerS;9;Find NextS;5;Open…S;19;toggleToolbarShown:S;29;centerSelectionInVisibleArea:S;13;stopSpeaking:S;22;toggleGrammarChecking:S;22;hideOtherApplications:S;19;useStandardKerning:S;14;loosenKerning:S;13;saveDocument:S;15;showGuessPanel:S;31;runToolbarCustomizationPalette:S;5;undo:S;4;cut:S;7;delete:S;22;revertDocumentToSaved:S;9;copyFont:S;15;tightenKerning:S;21;orderFrontColorPanel:S;10;underline:S;12;alignCenter:S;9;showHelp:S;29;orderFrontStandardAboutPanel:S;12;performZoom:S;15;saveDocumentAs:S;14;lowerBaseline:S;22;unhideAllApplications:S;15;turnOffKerning:S;10;pasteFont:S;12;superscript:S;10;terminate:S;16;useAllLigatures:S;33;toggleAutomaticQuoteSubstitution:S;6;paste:S;30;toggleContinuousSpellChecking:S;9;unscript:S;6;print:S;21;useStandardLigatures:S;19;performMiniaturize:S;21;clearRecentDocuments:S;29;toggleAutomaticLinkDetection:S;10;subscript:S;10;selectAll:S;11;pasteRuler:S;14;checkSpelling:S;10;alignLeft:S;5;copy:S;5;hide:S;15;arrangeInFront:S;23;performFindPanelAction:S;12;toggleRuler:S;13;openDocument:S;5;redo:S;14;startSpeaking:S;24;toggleSmartInsertDelete:S;12;newDocument:S;8;delegateS;14;runPageLayout:S;9;theWindowS;17;turnOffLigatures:S;14;raiseBaseline:S;11;alignRight:S;10;dataSourceS;13;performClose:S;10;copyRuler:S;15;alignJustified:S;21;{{1, 16}, {476, 348}}S;20;{{0, 0}, {476, 348}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;39E;E;E;D;K;10;$classnameS;7;CPColorK;8;$classesA;S;7;CPColorS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;818E;K;20;CPColorComponentsKeyD;K;6;CP$UIDd;3;820E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;821E;D;K;6;CP$UIDd;3;821E;D;K;6;CP$UIDd;3;821E;D;K;6;CP$UIDd;3;822E;E;E;f;10;0.66666669d;1;1E;K;9;$archiverS;15;CPKeyedArchiverK;8;$versionS;6;100000E; \ No newline at end of file diff --git a/TableCibTest/Resources/MainMenu.xib b/TableCibTest/Resources/MainMenu.xib new file mode 100644 index 000000000..69234c332 --- /dev/null +++ b/TableCibTest/Resources/MainMenu.xib @@ -0,0 +1,3712 @@ + + + + 1050 + 9J61 + 677 + 949.46 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilderKit + com.apple.InterfaceBuilder.CocoaPlugin + + + YES + + YES + + + YES + + + + YES + + NSApplication + + + FirstResponder + + + NSApplication + + + AMainMenu + + YES + + + NewApplication + + 1048576 + 2147483647 + + NSImage + NSMenuCheckmark + + + NSImage + NSMenuMixedState + + submenuAction: + + NewApplication + + YES + + + About NewApplication + + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + UHJlZmVyZW5jZXPigKY + , + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Services + + 1048576 + 2147483647 + + + submenuAction: + + Services + + YES + + _NSServicesMenu + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Hide NewApplication + h + 1048576 + 2147483647 + + + + + + Hide Others + h + 1572864 + 2147483647 + + + + + + Show All + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Quit NewApplication + q + 1048576 + 2147483647 + + + + + _NSAppleMenu + + + + + File + + 1048576 + 2147483647 + + + submenuAction: + + File + + YES + + + New + n + 1048576 + 2147483647 + + + + + + T3BlbuKApg + o + 1048576 + 2147483647 + + + + + + Open Recent + + 1048576 + 2147483647 + + + submenuAction: + + Open Recent + + YES + + + Clear Menu + + 1048576 + 2147483647 + + + + + _NSRecentDocumentsMenu + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Close + w + 1048576 + 2147483647 + + + + + + Save + s + 1048576 + 2147483647 + + + + + + U2F2ZSBBc+KApg + S + 1179648 + 2147483647 + + + + + + Revert to Saved + + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Page Setup... + P + 1179648 + 2147483647 + + + + + + + UHJpbnTigKY + p + 1048576 + 2147483647 + + + + + + + + + Edit + + 1048576 + 2147483647 + + + submenuAction: + + Edit + + YES + + + Undo + z + 1048576 + 2147483647 + + + + + + Redo + Z + 1179648 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Cut + x + 1048576 + 2147483647 + + + + + + Copy + c + 1048576 + 2147483647 + + + + + + Paste + v + 1048576 + 2147483647 + + + + + + Delete + + 1048576 + 2147483647 + + + + + + Select All + a + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Find + + 1048576 + 2147483647 + + + submenuAction: + + Find + + YES + + + RmluZOKApg + f + 1048576 + 2147483647 + + + 1 + + + + Find Next + g + 1048576 + 2147483647 + + + 2 + + + + Find Previous + G + 1179648 + 2147483647 + + + 3 + + + + Use Selection for Find + e + 1048576 + 2147483647 + + + 7 + + + + Jump to Selection + j + 1048576 + 2147483647 + + + + + + + + + Spelling and Grammar + + 1048576 + 2147483647 + + + submenuAction: + + Spelling and Grammar + + YES + + + U2hvdyBTcGVsbGluZ+KApg + : + 1048576 + 2147483647 + + + + + + Check Spelling + ; + 1048576 + 2147483647 + + + + + + Check Spelling While Typing + + 1048576 + 2147483647 + + + + + + Check Grammar With Spelling + + 1048576 + 2147483647 + + + + + + + + + Substitutions + + 1048576 + 2147483647 + + + submenuAction: + + Substitutions + + YES + + + Smart Copy/Paste + f + 1048576 + 2147483647 + + + 1 + + + + Smart Quotes + g + 1048576 + 2147483647 + + + 2 + + + + Smart Links + G + 1179648 + 2147483647 + + + 3 + + + + + + + Speech + + 1048576 + 2147483647 + + + submenuAction: + + Speech + + YES + + + Start Speaking + + 1048576 + 2147483647 + + + + + + Stop Speaking + + 1048576 + 2147483647 + + + + + + + + + + + + Format + + 2147483647 + + + submenuAction: + + Format + + YES + + + Font + + 2147483647 + + + submenuAction: + + Font + + YES + + + Show Fonts + t + 1048576 + 2147483647 + + + + + + Bold + b + 1048576 + 2147483647 + + + 2 + + + + Italic + i + 1048576 + 2147483647 + + + 1 + + + + Underline + u + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Bigger + + + 1048576 + 2147483647 + + + 3 + + + + Smaller + - + 1048576 + 2147483647 + + + 4 + + + + YES + YES + + + 2147483647 + + + + + + Kern + + 2147483647 + + + submenuAction: + + Kern + + YES + + + Use Default + + 2147483647 + + + + + + Use None + + 2147483647 + + + + + + Tighten + + 2147483647 + + + + + + Loosen + + 2147483647 + + + + + + + + + Ligature + + 2147483647 + + + submenuAction: + + Ligature + + YES + + + Use Default + + 2147483647 + + + + + + Use None + + 2147483647 + + + + + + Use All + + 2147483647 + + + + + + + + + Baseline + + 2147483647 + + + submenuAction: + + Baseline + + YES + + + Use Default + + 2147483647 + + + + + + Superscript + + 2147483647 + + + + + + Subscript + + 2147483647 + + + + + + Raise + + 2147483647 + + + + + + Lower + + 2147483647 + + + + + + + + + YES + YES + + + 2147483647 + + + + + + Show Colors + C + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Copy Style + c + 1572864 + 2147483647 + + + + + + Paste Style + v + 1572864 + 2147483647 + + + + + _NSFontMenu + + + + + Text + + 2147483647 + + + submenuAction: + + Text + + YES + + + Align Left + { + 1048576 + 2147483647 + + + + + + Center + | + 1048576 + 2147483647 + + + + + + Justify + + 2147483647 + + + + + + Align Right + } + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Show Ruler + + 2147483647 + + + + + + Copy Ruler + c + 1310720 + 2147483647 + + + + + + Paste Ruler + v + 1310720 + 2147483647 + + + + + + + + + + + + View + + 1048576 + 2147483647 + + + submenuAction: + + View + + YES + + + Show Toolbar + t + 1572864 + 2147483647 + + + + + + Q3VzdG9taXplIFRvb2xiYXLigKY + + 1048576 + 2147483647 + + + + + + + + + Window + + 1048576 + 2147483647 + + + submenuAction: + + Window + + YES + + + Minimize + m + 1048576 + 2147483647 + + + + + + Zoom + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Bring All to Front + + 1048576 + 2147483647 + + + + + _NSWindowsMenu + + + + + Help + + 1048576 + 2147483647 + + + submenuAction: + + Help + + YES + + + NewApplication Help + ? + 1048576 + 2147483647 + + + + + + + + _NSMainMenu + + + 7 + 2 + {{335, 387}, {491, 363}} + 1946157056 + Window + NSWindow + + {3.40282e+38, 3.40282e+38} + + + 256 + + YES + + + 274 + + YES + + + 2304 + + YES + + + 256 + {691, 348} + + YES + + + 256 + {{477, 0}, {16, 17}} + + + YES + + 0 + 6.900000e+01 + 4.000000e+01 + 1.000000e+03 + + 75628032 + 0 + + + LucidaGrande + 1.100000e+01 + 3100 + + + 3 + MC4zMzMzMzI5OQA + + + 6 + System + headerTextColor + + 3 + MAA + + + + + 337772096 + 2048 + Text Cell + + LucidaGrande + 1.300000e+01 + 1044 + + + + 6 + System + controlBackgroundColor + + 3 + MC42NjY2NjY2OQA + + + + 6 + System + controlTextColor + + + + 3 + YES + YES + + + + 1 + 6.700000e+01 + 4.000000e+01 + 1.000000e+03 + + 75628032 + 0 + + + + + + + 337772096 + 2048 + Text Cell + + + + + + 3 + YES + YES + + + + 2 + 6.400000e+01 + 1.000000e+01 + 3.402823e+38 + + 75628032 + 0 + + + + 6 + System + headerColor + + 3 + MQA + + + + + + 337772096 + 2048 + Text Cell + + + + + + 3 + YES + YES + + + + 3 + 6.400000e+01 + 1.000000e+01 + 3.402823e+38 + + 75628032 + 0 + + + + + + + 337772096 + 2048 + Text Cell + + + + + + 3 + YES + YES + + + + 4 + 6.400000e+01 + 1.000000e+01 + 3.402823e+38 + + 75628032 + 0 + + + + + + + 337772096 + 2048 + Text Cell + + + + + + 3 + YES + YES + + + + 5 + 6.400000e+01 + 1.000000e+01 + 3.402823e+38 + + 75628032 + 0 + + + + + + + 337772096 + 2048 + Text Cell + + + + + + 3 + YES + YES + + + + 6 + 6.400000e+01 + 1.000000e+01 + 3.402823e+38 + + 75628032 + 0 + + + + + + + 337772096 + 2048 + Text Cell + + + + + + 3 + YES + YES + + + + 7 + 6.400000e+01 + 1.000000e+01 + 3.402823e+38 + + 75628032 + 0 + + + + + + + 337772096 + 2048 + Text Cell + + + + + + 3 + YES + YES + + + + 8 + 6.400000e+01 + 1.000000e+01 + 3.402823e+38 + + 75628032 + 0 + + + + + + + 337772096 + 2048 + Text Cell + + + + + + 3 + YES + YES + + + + 9 + 6.400000e+01 + 1.000000e+01 + 3.402823e+38 + + 75628032 + 0 + + + + + + + 337772096 + 2048 + Text Cell + + + + + + 3 + YES + YES + + + + 10 + 1.000000e+01 + 1.000000e+01 + 3.402823e+38 + + 75628032 + 0 + + + + + + + 337772096 + 2048 + Text Cell + + + + + + 3 + YES + YES + + + + 3.000000e+00 + 2.000000e+00 + + + 6 + System + gridColor + + 3 + MC41AA + + + 1.700000e+01 + -698351616 + 4 + 15 + 0 + YES + + + {{1, 1}, {476, 348}} + + + + + 4 + + + + 256 + {{477, 1}, {15, 348}} + + + _doScroller: + 9.971429e-01 + + + + 256 + {{1, 349}, {476, 15}} + + YES + 1 + + _doScroller: + 6.888567e-01 + + + {{-1, -1}, {493, 365}} + + + 178 + + + + QSAAAEEgAABBmAAAQZgAAA + + + {491, 363} + + + {{0, 0}, {1440, 878}} + {3.40282e+38, 3.40282e+38} + + + AppController + + + + + YES + + + performMiniaturize: + + + + 37 + + + + arrangeInFront: + + + + 39 + + + + print: + + + + 86 + + + + runPageLayout: + + + + 87 + + + + clearRecentDocuments: + + + + 127 + + + + orderFrontStandardAboutPanel: + + + + 142 + + + + performClose: + + + + 193 + + + + toggleContinuousSpellChecking: + + + + 222 + + + + undo: + + + + 223 + + + + copy: + + + + 224 + + + + checkSpelling: + + + + 225 + + + + paste: + + + + 226 + + + + stopSpeaking: + + + + 227 + + + + cut: + + + + 228 + + + + showGuessPanel: + + + + 230 + + + + redo: + + + + 231 + + + + selectAll: + + + + 232 + + + + startSpeaking: + + + + 233 + + + + delete: + + + + 235 + + + + performZoom: + + + + 240 + + + + performFindPanelAction: + + + + 241 + + + + centerSelectionInVisibleArea: + + + + 245 + + + + toggleGrammarChecking: + + + + 347 + + + + toggleSmartInsertDelete: + + + + 355 + + + + toggleAutomaticQuoteSubstitution: + + + + 356 + + + + toggleAutomaticLinkDetection: + + + + 357 + + + + showHelp: + + + + 360 + + + + saveDocument: + + + + 362 + + + + saveDocumentAs: + + + + 363 + + + + revertDocumentToSaved: + + + + 364 + + + + runToolbarCustomizationPalette: + + + + 365 + + + + toggleToolbarShown: + + + + 366 + + + + hide: + + + + 367 + + + + hideOtherApplications: + + + + 368 + + + + unhideAllApplications: + + + + 370 + + + + newDocument: + + + + 373 + + + + openDocument: + + + + 374 + + + + raiseBaseline: + + + + 426 + + + + lowerBaseline: + + + + 427 + + + + copyFont: + + + + 428 + + + + subscript: + + + + 429 + + + + superscript: + + + + 430 + + + + tightenKerning: + + + + 431 + + + + underline: + + + + 432 + + + + orderFrontColorPanel: + + + + 433 + + + + useAllLigatures: + + + + 434 + + + + loosenKerning: + + + + 435 + + + + pasteFont: + + + + 436 + + + + unscript: + + + + 437 + + + + useStandardKerning: + + + + 438 + + + + useStandardLigatures: + + + + 439 + + + + turnOffLigatures: + + + + 440 + + + + turnOffKerning: + + + + 441 + + + + alignLeft: + + + + 442 + + + + alignJustified: + + + + 443 + + + + copyRuler: + + + + 444 + + + + alignCenter: + + + + 445 + + + + toggleRuler: + + + + 446 + + + + alignRight: + + + + 447 + + + + pasteRuler: + + + + 448 + + + + terminate: + + + + 449 + + + + delegate + + + + 451 + + + + theWindow + + + + 459 + + + + dataSource + + + + 488 + + + + + YES + + 0 + + YES + + + + + + -2 + + + RmlsZSdzIE93bmVyA + + + -1 + + + First Responder + + + -3 + + + Application + + + 29 + + + YES + + + + + + + + + + MainMenu + + + 19 + + + YES + + + + + + 56 + + + YES + + + + + + 103 + + + YES + + + + 1 + + + 217 + + + YES + + + + + + 83 + + + YES + + + + + + 81 + + + YES + + + + + + + + + + + + + + + + 75 + + + 3 + + + 80 + + + 8 + + + 78 + + + 6 + + + 72 + + + + + 82 + + + 9 + + + 124 + + + YES + + + + + + 77 + + + 5 + + + 73 + + + 1 + + + 79 + + + 7 + + + 112 + + + 10 + + + 74 + + + 2 + + + 125 + + + YES + + + + + + 126 + + + + + 205 + + + YES + + + + + + + + + + + + + + + + + + 202 + + + + + 198 + + + + + 207 + + + + + 214 + + + + + 199 + + + + + 203 + + + + + 197 + + + + + 206 + + + + + 215 + + + + + 218 + + + YES + + + + + + 216 + + + YES + + + + + + 200 + + + YES + + + + + + + + + 219 + + + + + 201 + + + + + 204 + + + + + 220 + + + YES + + + + + + + + + + 213 + + + + + 210 + + + + + 221 + + + + + 208 + + + + + 209 + + + + + 106 + + + YES + + + + 2 + + + 111 + + + + + 57 + + + YES + + + + + + + + + + + + + + + + 58 + + + + + 134 + + + + + 150 + + + + + 136 + + + 1111 + + + 144 + + + + + 129 + + + 121 + + + 143 + + + + + 236 + + + + + 131 + + + YES + + + + + + 149 + + + + + 145 + + + + + 130 + + + + + 24 + + + YES + + + + + + + + + 92 + + + + + 5 + + + + + 239 + + + + + 23 + + + + + 295 + + + YES + + + + + + 296 + + + YES + + + + + + + 297 + + + + + 298 + + + + + 211 + + + YES + + + + + + 212 + + + YES + + + + + + + 195 + + + + + 196 + + + + + 346 + + + + + 348 + + + YES + + + + + + 349 + + + YES + + + + + + + + 350 + + + + + 351 + + + + + 354 + + + + + 371 + + + YES + + + + + + 372 + + + YES + + + + + + 375 + + + YES + + + + + + 376 + + + YES + + + + + + + 377 + + + YES + + + + + + 378 + + + YES + + + + + + 379 + + + YES + + + + + + + + + + + + + 380 + + + + + 381 + + + + + 382 + + + + + 383 + + + + + 384 + + + + + 385 + + + + + 386 + + + + + 387 + + + + + 388 + + + YES + + + + + + + + + + + + + + + + + + + + + 389 + + + + + 390 + + + + + 391 + + + + + 392 + + + + + 393 + + + + + 394 + + + + + 395 + + + + + 396 + + + + + 397 + + + YES + + + + + + 398 + + + YES + + + + + + 399 + + + YES + + + + + + 400 + + + + + 401 + + + + + 402 + + + + + 403 + + + + + 404 + + + + + 405 + + + YES + + + + + + + + + + 406 + + + + + 407 + + + + + 408 + + + + + 409 + + + + + 410 + + + + + 411 + + + YES + + + + + + + + 412 + + + + + 413 + + + + + 414 + + + + + 415 + + + YES + + + + + + + + + 416 + + + + + 417 + + + + + 418 + + + + + 419 + + + + + 450 + + + + + 460 + + + YES + + + + + + + + 461 + + + + + 462 + + + + + 463 + + + YES + + + + + + + + + + + + + + + + 465 + + + YES + + + + + + 466 + + + YES + + + + + + 467 + + + + + 468 + + + + + 469 + + + YES + + + + + + 470 + + + + + 471 + + + YES + + + + + + 472 + + + + + 473 + + + YES + + + + + + 474 + + + + + 475 + + + YES + + + + + + 476 + + + + + 477 + + + YES + + + + + + 478 + + + + + 479 + + + YES + + + + + + 480 + + + + + 481 + + + YES + + + + + + 482 + + + + + 483 + + + YES + + + + + + 484 + + + + + 485 + + + YES + + + + + + 486 + + + + + + + YES + + YES + -1.IBPluginDependency + -2.IBPluginDependency + -3.IBPluginDependency + 103.IBPluginDependency + 103.ImportedFromIB2 + 106.IBPluginDependency + 106.ImportedFromIB2 + 106.editorWindowContentRectSynchronizationRect + 111.IBPluginDependency + 111.ImportedFromIB2 + 112.IBPluginDependency + 112.ImportedFromIB2 + 124.IBPluginDependency + 124.ImportedFromIB2 + 125.IBPluginDependency + 125.ImportedFromIB2 + 125.editorWindowContentRectSynchronizationRect + 126.IBPluginDependency + 126.ImportedFromIB2 + 129.IBPluginDependency + 129.ImportedFromIB2 + 130.IBPluginDependency + 130.ImportedFromIB2 + 130.editorWindowContentRectSynchronizationRect + 131.IBPluginDependency + 131.ImportedFromIB2 + 134.IBPluginDependency + 134.ImportedFromIB2 + 136.IBPluginDependency + 136.ImportedFromIB2 + 143.IBPluginDependency + 143.ImportedFromIB2 + 144.IBPluginDependency + 144.ImportedFromIB2 + 145.IBPluginDependency + 145.ImportedFromIB2 + 149.IBPluginDependency + 149.ImportedFromIB2 + 150.IBPluginDependency + 150.ImportedFromIB2 + 19.IBPluginDependency + 19.ImportedFromIB2 + 195.IBPluginDependency + 195.ImportedFromIB2 + 196.IBPluginDependency + 196.ImportedFromIB2 + 197.IBPluginDependency + 197.ImportedFromIB2 + 198.IBPluginDependency + 198.ImportedFromIB2 + 199.IBPluginDependency + 199.ImportedFromIB2 + 200.IBPluginDependency + 200.ImportedFromIB2 + 200.editorWindowContentRectSynchronizationRect + 201.IBPluginDependency + 201.ImportedFromIB2 + 202.IBPluginDependency + 202.ImportedFromIB2 + 203.IBPluginDependency + 203.ImportedFromIB2 + 204.IBPluginDependency + 204.ImportedFromIB2 + 205.IBPluginDependency + 205.ImportedFromIB2 + 205.editorWindowContentRectSynchronizationRect + 206.IBPluginDependency + 206.ImportedFromIB2 + 207.IBPluginDependency + 207.ImportedFromIB2 + 208.IBPluginDependency + 208.ImportedFromIB2 + 209.IBPluginDependency + 209.ImportedFromIB2 + 210.IBPluginDependency + 210.ImportedFromIB2 + 211.IBPluginDependency + 211.ImportedFromIB2 + 212.IBPluginDependency + 212.ImportedFromIB2 + 212.editorWindowContentRectSynchronizationRect + 213.IBPluginDependency + 213.ImportedFromIB2 + 214.IBPluginDependency + 214.ImportedFromIB2 + 215.IBPluginDependency + 215.ImportedFromIB2 + 216.IBPluginDependency + 216.ImportedFromIB2 + 217.IBPluginDependency + 217.ImportedFromIB2 + 218.IBPluginDependency + 218.ImportedFromIB2 + 219.IBPluginDependency + 219.ImportedFromIB2 + 220.IBPluginDependency + 220.ImportedFromIB2 + 220.editorWindowContentRectSynchronizationRect + 221.IBPluginDependency + 221.ImportedFromIB2 + 23.IBPluginDependency + 23.ImportedFromIB2 + 236.IBPluginDependency + 236.ImportedFromIB2 + 239.IBPluginDependency + 239.ImportedFromIB2 + 24.IBPluginDependency + 24.ImportedFromIB2 + 24.editorWindowContentRectSynchronizationRect + 29.IBEditorWindowLastContentRect + 29.IBPluginDependency + 29.ImportedFromIB2 + 29.WindowOrigin + 29.editorWindowContentRectSynchronizationRect + 295.IBPluginDependency + 296.IBPluginDependency + 296.editorWindowContentRectSynchronizationRect + 297.IBPluginDependency + 298.IBPluginDependency + 346.IBPluginDependency + 346.ImportedFromIB2 + 348.IBPluginDependency + 348.ImportedFromIB2 + 349.IBPluginDependency + 349.ImportedFromIB2 + 349.editorWindowContentRectSynchronizationRect + 350.IBPluginDependency + 350.ImportedFromIB2 + 351.IBPluginDependency + 351.ImportedFromIB2 + 354.IBPluginDependency + 354.ImportedFromIB2 + 371.IBEditorWindowLastContentRect + 371.IBWindowTemplateEditedContentRect + 371.NSWindowTemplate.visibleAtLaunch + 371.editorWindowContentRectSynchronizationRect + 371.windowTemplate.maxSize + 372.IBPluginDependency + 375.IBPluginDependency + 376.IBEditorWindowLastContentRect + 376.IBPluginDependency + 377.IBPluginDependency + 378.IBPluginDependency + 379.IBPluginDependency + 380.IBPluginDependency + 381.IBPluginDependency + 382.IBPluginDependency + 383.IBPluginDependency + 384.IBPluginDependency + 385.IBPluginDependency + 386.IBPluginDependency + 387.IBPluginDependency + 388.IBEditorWindowLastContentRect + 388.IBPluginDependency + 389.IBPluginDependency + 390.IBPluginDependency + 391.IBPluginDependency + 392.IBPluginDependency + 393.IBPluginDependency + 394.IBPluginDependency + 395.IBPluginDependency + 396.IBPluginDependency + 397.IBPluginDependency + 398.IBPluginDependency + 399.IBPluginDependency + 400.IBPluginDependency + 401.IBPluginDependency + 402.IBPluginDependency + 403.IBPluginDependency + 404.IBPluginDependency + 405.IBPluginDependency + 406.IBPluginDependency + 407.IBPluginDependency + 408.IBPluginDependency + 409.IBPluginDependency + 410.IBPluginDependency + 411.IBPluginDependency + 412.IBPluginDependency + 413.IBPluginDependency + 414.IBPluginDependency + 415.IBPluginDependency + 416.IBPluginDependency + 417.IBPluginDependency + 418.IBPluginDependency + 419.IBPluginDependency + 450.IBPluginDependency + 460.IBPluginDependency + 461.IBPluginDependency + 462.IBPluginDependency + 463.IBPluginDependency + 465.IBPluginDependency + 466.IBPluginDependency + 467.IBPluginDependency + 468.IBPluginDependency + 469.IBPluginDependency + 470.IBPluginDependency + 471.IBPluginDependency + 472.IBPluginDependency + 473.IBPluginDependency + 474.IBPluginDependency + 475.IBPluginDependency + 476.IBPluginDependency + 477.IBPluginDependency + 478.IBPluginDependency + 479.IBPluginDependency + 480.IBPluginDependency + 481.IBPluginDependency + 482.IBPluginDependency + 483.IBPluginDependency + 484.IBPluginDependency + 485.IBPluginDependency + 486.IBPluginDependency + 5.IBPluginDependency + 5.ImportedFromIB2 + 56.IBPluginDependency + 56.ImportedFromIB2 + 57.IBEditorWindowLastContentRect + 57.IBPluginDependency + 57.ImportedFromIB2 + 57.editorWindowContentRectSynchronizationRect + 58.IBPluginDependency + 58.ImportedFromIB2 + 72.IBPluginDependency + 72.ImportedFromIB2 + 73.IBPluginDependency + 73.ImportedFromIB2 + 74.IBPluginDependency + 74.ImportedFromIB2 + 75.IBPluginDependency + 75.ImportedFromIB2 + 77.IBPluginDependency + 77.ImportedFromIB2 + 78.IBPluginDependency + 78.ImportedFromIB2 + 79.IBPluginDependency + 79.ImportedFromIB2 + 80.IBPluginDependency + 80.ImportedFromIB2 + 81.IBPluginDependency + 81.ImportedFromIB2 + 81.editorWindowContentRectSynchronizationRect + 82.IBPluginDependency + 82.ImportedFromIB2 + 83.IBPluginDependency + 83.ImportedFromIB2 + 92.IBPluginDependency + 92.ImportedFromIB2 + + + YES + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilderKit + com.apple.InterfaceBuilderKit + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{596, 852}, {216, 23}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{522, 812}, {146, 23}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{436, 809}, {64, 6}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{608, 612}, {275, 83}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{187, 434}, {243, 243}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{608, 612}, {167, 43}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{608, 612}, {241, 103}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{525, 802}, {197, 73}} + {{143, 285}, {478, 20}} + com.apple.InterfaceBuilder.CocoaPlugin + + {74, 862} + {{6, 978}, {478, 20}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{475, 832}, {234, 43}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{608, 612}, {215, 63}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{83, 84}, {491, 363}} + {{83, 84}, {491, 363}} + + {{33, 99}, {480, 360}} + {3.40282e+38, 3.40282e+38} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{437, 242}, {86, 43}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{523, 2}, {178, 283}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{155, 102}, {245, 183}} + com.apple.InterfaceBuilder.CocoaPlugin + + {{23, 794}, {245, 183}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{145, 474}, {199, 203}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 488 + + + + YES + + AppController + + theWindow + NSWindow + + + IBUserSource + + + + + + 0 + ../adsfsdf.xcodeproj + 3 + + diff --git a/TableCibTest/Resources/spinner.gif b/TableCibTest/Resources/spinner.gif new file mode 100644 index 000000000..06dbc2bc2 Binary files /dev/null and b/TableCibTest/Resources/spinner.gif differ diff --git a/TableCibTest/index-debug.html b/TableCibTest/index-debug.html new file mode 100644 index 000000000..218ae015c --- /dev/null +++ b/TableCibTest/index-debug.html @@ -0,0 +1,69 @@ + + + + + + + + TableCibTest + + + + + + + + + + + + +
+ + + +
+ + + diff --git a/TableCibTest/index.html b/TableCibTest/index.html new file mode 100644 index 000000000..41eca60ef --- /dev/null +++ b/TableCibTest/index.html @@ -0,0 +1,68 @@ + + + + + + + + TableCibTest + + + + + + + + + + + + +
+ + + +
+ + + diff --git a/TableCibTest/main.j b/TableCibTest/main.j new file mode 100755 index 000000000..af6279da3 --- /dev/null +++ b/TableCibTest/main.j @@ -0,0 +1,18 @@ +/* + * AppController.j + * TableCibTest + * + * Created by Francisco Tolmasky on July 5, 2009. + * Copyright 2009, 280 North, Inc. All rights reserved. + */ + +@import +@import + +@import "AppController.j" + + +function main(args, namedArgs) +{ + CPApplicationMain(args, namedArgs); +} diff --git a/TableTest/AppController.j b/TableTest/AppController.j new file mode 100644 index 000000000..10c271dd4 --- /dev/null +++ b/TableTest/AppController.j @@ -0,0 +1,130 @@ + +@import + +@import +@import +@import + + +CPLogRegister(CPLogConsole); + +@implementation AppController : CPObject +{ + CPTableView tableView; + CPImage iconImage; +} + +- (void)applicationDidFinishLaunching:(CPNotification)aNotification +{ + var view = [[CPView alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 100.0)]; + + [view setBackgroundColor:[CPColor whiteColor]]; + [view enterFullScreenMode:nil withOptions:nil]; + + tableView = [[CPTableView alloc] initWithFrame:CGRectMake(0.0, 0.0, 500.0, 500.0)];//[view bounds]]; + + [tableView setAllowsMultipleSelection:YES]; + [tableView setUsesAlternatingRowBackgroundColors:YES]; + [tableView setGridStyleMask:CPTableViewSolidHorizontalGridLineMask | CPTableViewSolidVerticalGridLineMask]; + +// [tableView setBackgroundColor:[CPColor blueColor]]; + + var iconView = [[CPImageView alloc] initWithFrame:CGRectMake(16,16,0,0)]; + + [iconView setImageScaling:CPScaleNone]; + + var iconColumn = [[CPTableColumn alloc] initWithIdentifier:"icons"]; + + [iconColumn setWidth:32.0]; + [iconColumn setDataView:iconView]; + + [tableView addTableColumn:iconColumn]; + + iconImage = [[CPImage alloc] initWithContentsOfFile:"http://cappuccino.org/images/favicon.png" size:CGSizeMake(16,16)]; + + var textDataView = [CPTextField new]; + +// [textDataView setBackgroundColor:[[CPColor redColor] colorWithAlphaComponent:0.5]]; + + for (var i = 1; i <= 10; i++) + { + var column = [[CPTableColumn alloc] initWithIdentifier:String(i)]; + + [[column headerView] setStringValue:"Number "+i]; + [[column headerView] sizeToFit]; + //[column setWidth:[[column headerView] frame].size.width + 20]; + + [column setWidth:200.0]; + + [column setDataView:textDataView]; + + [tableView addTableColumn:column]; + } + + [tableView selectColumnIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0,2)] byExtendingSelection:YES]; + + var scrollView = [[CPScrollView alloc] initWithFrame:[view bounds]]; + + [scrollView setDocumentView:tableView]; + [scrollView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable]; + + [view addSubview:scrollView]; + + [scrollView setAutohidesScrollers:YES]; + + [tableView setDelegate:self]; + [tableView setDataSource:self]; +} + +- (int)numberOfRowsInTableView:(CPTableView)tableView +{ + return 700000; +} + +- (id)tableView:(CPTableView)tableView objectValueForTableColumn:(CPTableColumn)tableColumn row:(int)row +{ + if ([tableColumn identifier] === "icons") + return iconImage; + else + return String((row + 1) * [[tableColumn identifier] intValue]); +} +/* +- (id)tableView:(CPTableView)tableView heightOfRow:(int)row +{ + //CPLog.info("heightOfRow:"+row); + return 20.0 + ROUND(row * 0.5); +} +*/ +//- (void)tableViewSelectionIsChanging:(CPNotification)aNotification +//{ +// CPLog.debug(@"changing! %@", [aNotification description]); +//} +// +//- (void)tableViewSelectionDidChange:(CPNotification)aNotification +//{ +// CPLog.debug(@"did change! %@", [aNotification description]); +//} + +- (BOOL)tableView:(CPTableView)aTableView shouldSelectRow:(int)rowIndex +{ + //CPLog.debug(@"shouldSelectRow %d", rowIndex); + for (var i = 2, sqrt = SQRT(rowIndex+1); i <= sqrt; i++) + if ((rowIndex+1) % i === 0) + return false; + + return true; +} + +- (BOOL)selectionShouldChangeInTableView:(CPTableView)aTableView +{ + //CPLog.debug(@"selectionShouldChangeInTableView"); + return YES; +} + +//- (CPIndexSet)tableView:(CPTableView)tableView selectionIndexesForProposedSelection:(CPIndexSet)proposedSelectionIndexes +//{ +// CPLog.debug(@"selectionIndexesForProposedSelection %@", [proposedSelectionIndexes description]); +// return proposedSelectionIndexes; +//} + +@end diff --git a/TableTest/Info.plist b/TableTest/Info.plist new file mode 100644 index 000000000..78ac6aab8 --- /dev/null +++ b/TableTest/Info.plist @@ -0,0 +1,12 @@ + + + + + CPApplicationDelegateClass + AppController + CPBundleName + TableTest + CPPrincipalClass + CPApplication + + diff --git a/TableTest/Rakefile b/TableTest/Rakefile new file mode 100644 index 000000000..26682d25f --- /dev/null +++ b/TableTest/Rakefile @@ -0,0 +1,25 @@ + +require 'objective-j' +require 'objective-j/bundletask' + +if !ENV['CONFIG'] + ENV['CONFIG'] = 'Debug' +end + +ObjectiveJ::BundleTask.new(:TableTest) do |t| + t.name = 'TableTest' + t.identifier = 'com.yourcompany.TableTest' + t.version = '1.0' + t.author = 'Your Company' + t.email = 'feedback @nospam@ yourcompany.com' + t.summary = 'TableTest' + t.sources = FileList['*.j'] + t.resources = FileList['Resources/*'] + t.index_file = 'index.html' + t.info_plist = 'Info.plist' + t.build_path = File.join('Build', ENV['CONFIG'], 'TableTest') + t.flag = '-DDEBUG' if ENV['CONFIG'] == 'Debug' + t.flag = '-O' if ENV['CONFIG'] == 'Release' +end + +task :default => [:TableTest] diff --git a/TableTest/Resources/spinner.gif b/TableTest/Resources/spinner.gif new file mode 100644 index 000000000..06dbc2bc2 Binary files /dev/null and b/TableTest/Resources/spinner.gif differ diff --git a/TableTest/index-debug.html b/TableTest/index-debug.html new file mode 100644 index 000000000..9bb71cc81 --- /dev/null +++ b/TableTest/index-debug.html @@ -0,0 +1,69 @@ + + + + + + + + TableTest + + + + + + + + + + + + +
+ + + +
+ + + diff --git a/TableTest/index.html b/TableTest/index.html new file mode 100644 index 000000000..9965f27f7 --- /dev/null +++ b/TableTest/index.html @@ -0,0 +1,69 @@ + + + + + + + + TableTest + + + + + + + + + + + + +
+ + + +
+ + + + diff --git a/TableTest/main.j b/TableTest/main.j new file mode 100755 index 000000000..ee431dc77 --- /dev/null +++ b/TableTest/main.j @@ -0,0 +1,18 @@ +/* + * AppController.j + * TableTest + * + * Created by You on June 7, 2009. + * Copyright 2009, Your Company All rights reserved. + */ + +@import +@import + +@import "AppController.j" + + +function main(args, namedArgs) +{ + CPApplicationMain(args, namedArgs); +} diff --git a/Tests/AppKit/CPScrollViewTest.j b/Tests/AppKit/CPScrollViewTest.j new file mode 100644 index 000000000..428268c09 --- /dev/null +++ b/Tests/AppKit/CPScrollViewTest.j @@ -0,0 +1,177 @@ +@import + +@implementation CPScrollViewTest : OJTestCase +{ +} + +- (void)testBothScrollersVisible +{ + var scrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 100.0)]; + + [scrollView setAutohidesScrollers:NO]; + [scrollView setHasHorizontalScroller:YES]; + [scrollView setHasVerticalScroller:YES]; + + var documentView = [[CPView alloc] init]; + + [scrollView setDocumentView:documentView]; + + // Test document view size smaller than scroll view size. + [documentView setFrameSize:CGSizeMake(50.0, 50.0)]; + + [self assert:[[scrollView horizontalScroller] isHidden] equals:NO]; + [self assert:[[scrollView horizontalScroller] isEnabled] equals:NO]; + + [self assert:[[scrollView verticalScroller] isHidden] equals:NO]; + [self assert:[[scrollView verticalScroller] isEnabled] equals:NO]; + + // Test document view size much larger than scroll view size. + [documentView setFrameSize:CGSizeMake(1000.0, 1000.0)]; + + [self assert:[[scrollView horizontalScroller] isHidden] equals:NO]; + [self assert:[[scrollView horizontalScroller] isEnabled] equals:YES]; + + [self assert:[[scrollView verticalScroller] isHidden] equals:NO]; + [self assert:[[scrollView verticalScroller] isEnabled] equals:YES]; + + // Test document view size much taller than scroll view size. + [documentView setFrameSize:CGSizeMake(50.0, 1000.0)]; + + [self assert:[[scrollView horizontalScroller] isHidden] equals:NO]; + [self assert:[[scrollView horizontalScroller] isEnabled] equals:NO]; + + [self assert:[[scrollView verticalScroller] isHidden] equals:NO]; + [self assert:[[scrollView verticalScroller] isEnabled] equals:YES]; + + // Test document view size much wider than scroll view size. + [documentView setFrameSize:CGSizeMake(1000.0, 50.0)]; + + [self assert:[[scrollView horizontalScroller] isHidden] equals:NO]; + [self assert:[[scrollView horizontalScroller] isEnabled] equals:YES]; + + [self assert:[[scrollView verticalScroller] isHidden] equals:NO]; + [self assert:[[scrollView verticalScroller] isEnabled] equals:NO]; + + // Test document view size equal to scroll view size. + [documentView setFrameSize:CGSizeMake(100.0, 100.0)]; + + [self assert:[[scrollView horizontalScroller] isHidden] equals:NO]; + [self assert:[[scrollView horizontalScroller] isEnabled] equals:YES]; + + [self assert:[[scrollView verticalScroller] isHidden] equals:NO]; + [self assert:[[scrollView verticalScroller] isEnabled] equals:YES]; + + // Test document view size taller than scroll view size only because of scrollers. + [documentView setFrameSize:CGSizeMake(50.0, 100.0)]; + + [self assert:[[scrollView horizontalScroller] isHidden] equals:NO]; + [self assert:[[scrollView horizontalScroller] isEnabled] equals:NO]; + + [self assert:[[scrollView verticalScroller] isHidden] equals:NO]; + [self assert:[[scrollView verticalScroller] isEnabled] equals:YES]; + + // Test document view size wider than scroll view size only because of scrollers. + [documentView setFrameSize:CGSizeMake(100.0, 50.0)]; + + [self assert:[[scrollView horizontalScroller] isHidden] equals:NO]; + [self assert:[[scrollView horizontalScroller] isEnabled] equals:YES]; + + [self assert:[[scrollView verticalScroller] isHidden] equals:NO]; + [self assert:[[scrollView verticalScroller] isEnabled] equals:NO]; + + // Test document view size exactly the right size relative to the scroll view size. + [documentView setFrameSize:CGSizeMake(100.0 - 17.0, 100.0 - 17.0)]; + + [self assert:[[scrollView horizontalScroller] isHidden] equals:NO]; + [self assert:[[scrollView horizontalScroller] isEnabled] equals:NO]; + + [self assert:[[scrollView verticalScroller] isHidden] equals:NO]; + [self assert:[[scrollView verticalScroller] isEnabled] equals:NO]; +} + +- (void)testAutoHidesScrollers +{ + var scrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 100.0)]; + + [scrollView setAutohidesScrollers:YES]; + [scrollView setHasHorizontalScroller:YES]; + [scrollView setHasVerticalScroller:YES]; + + var documentView = [[CPView alloc] init]; + + [scrollView setDocumentView:documentView]; + + // Test document view size smaller than scroll view size. + [documentView setFrameSize:CGSizeMake(50.0, 50.0)]; + + [self assert:[[scrollView horizontalScroller] isHidden] equals:YES]; + [self assert:[[scrollView horizontalScroller] isEnabled] equals:NO]; + + [self assert:[[scrollView verticalScroller] isHidden] equals:YES]; + [self assert:[[scrollView verticalScroller] isEnabled] equals:NO]; + + // Test document view size much larger than scroll view size. + [documentView setFrameSize:CGSizeMake(1000.0, 1000.0)]; + + [self assert:[[scrollView horizontalScroller] isHidden] equals:NO]; + [self assert:[[scrollView horizontalScroller] isEnabled] equals:YES]; + + [self assert:[[scrollView verticalScroller] isHidden] equals:NO]; + [self assert:[[scrollView verticalScroller] isEnabled] equals:YES]; + + // Test document view size much taller than scroll view size. + [documentView setFrameSize:CGSizeMake(50.0, 1000.0)]; + + [self assert:[[scrollView horizontalScroller] isHidden] equals:YES]; + [self assert:[[scrollView horizontalScroller] isEnabled] equals:NO]; + + [self assert:[[scrollView verticalScroller] isHidden] equals:NO]; + [self assert:[[scrollView verticalScroller] isEnabled] equals:YES]; + + // Test document view size much wider than scroll view size. + [documentView setFrameSize:CGSizeMake(1000.0, 50.0)]; + + [self assert:[[scrollView horizontalScroller] isHidden] equals:NO]; + [self assert:[[scrollView horizontalScroller] isEnabled] equals:YES]; + + [self assert:[[scrollView verticalScroller] isHidden] equals:YES]; + [self assert:[[scrollView verticalScroller] isEnabled] equals:NO]; + + // Test document view size equal to scroll view size. + [documentView setFrameSize:CGSizeMake(100.0, 100.0)]; + + [self assert:[[scrollView horizontalScroller] isHidden] equals:YES]; + [self assert:[[scrollView horizontalScroller] isEnabled] equals:NO]; + + [self assert:[[scrollView verticalScroller] isHidden] equals:YES]; + [self assert:[[scrollView verticalScroller] isEnabled] equals:NO]; + + // Test document view size taller than scroll view size only because of scrollers. + [documentView setFrameSize:CGSizeMake(50.0, 100.0)]; + + [self assert:[[scrollView horizontalScroller] isHidden] equals:YES]; + [self assert:[[scrollView horizontalScroller] isEnabled] equals:NO]; + + [self assert:[[scrollView verticalScroller] isHidden] equals:YES]; + [self assert:[[scrollView verticalScroller] isEnabled] equals:NO]; + + // Test document view size wider than scroll view size only because of scrollers. + [documentView setFrameSize:CGSizeMake(100.0, 50.0)]; + + [self assert:[[scrollView horizontalScroller] isHidden] equals:YES]; + [self assert:[[scrollView horizontalScroller] isEnabled] equals:NO]; + + [self assert:[[scrollView verticalScroller] isHidden] equals:YES]; + [self assert:[[scrollView verticalScroller] isEnabled] equals:NO]; + + // Test document view size exactly the right size relative to the scroll view size. + [documentView setFrameSize:CGSizeMake(100.0 - 17.0, 100.0 - 17.0)]; + + [self assert:[[scrollView horizontalScroller] isHidden] equals:YES]; + [self assert:[[scrollView horizontalScroller] isEnabled] equals:NO]; + + [self assert:[[scrollView verticalScroller] isHidden] equals:YES]; + [self assert:[[scrollView verticalScroller] isEnabled] equals:NO]; +} + +@end \ No newline at end of file diff --git a/Tests/Foundation/CPIndexSetTest.j b/Tests/Foundation/CPIndexSetTest.j new file mode 100644 index 000000000..c659fff42 --- /dev/null +++ b/Tests/Foundation/CPIndexSetTest.j @@ -0,0 +1,357 @@ +@import + +function descriptionWithoutEntity(aString) +{ + var descriptionWithEntity = [aString description]; +//print(descriptionWithEntity); + return descriptionWithEntity.substr(descriptionWithEntity.indexOf('>') + 1); +} + +@implementation CPIndexSetTest : OJTestCase +{ + CPIndexSet _set; +} + +- (void)testAddIndexes +{ + var indexSet = [CPIndexSet indexSet]; + + // Test no indexes + [self assert:descriptionWithoutEntity(indexSet) equals:@"(no indexes)"]; + + // Test adding initial range + [indexSet addIndexesInRange:CPMakeRange(30,10)]; + + [self assert:@"[number of indexes: 10 (in 1 range), indexes: (30-39)]" equals:descriptionWithoutEntity(indexSet)]; + + // Test adding range after existing ranges. + [indexSet addIndexesInRange:CPMakeRange(50,10)]; + + [self assert:@"[number of indexes: 20 (in 2 ranges), indexes: (30-39 50-59)]" equals:descriptionWithoutEntity(indexSet)]; + + // Test adding range before existing ranges. + [indexSet addIndexesInRange:CPMakeRange(10,10)]; + + [self assert:@"[number of indexes: 30 (in 3 ranges), indexes: (10-19 30-39 50-59)]" equals:descriptionWithoutEntity(indexSet)]; + + // Test adding range inbetween existing ranges. + [indexSet addIndexesInRange:CPMakeRange(45,2)]; + + [self assert:@"[number of indexes: 32 (in 4 ranges), indexes: (10-19 30-39 45-46 50-59)]" equals:descriptionWithoutEntity(indexSet)]; + + // Test adding single index inbetween existing ranges. + [indexSet addIndexesInRange:CPMakeRange(23,1)]; + + [self assert:@"[number of indexes: 33 (in 5 ranges), indexes: (10-19 23 30-39 45-46 50-59)]" equals:descriptionWithoutEntity(indexSet)]; + + // Test adding range inbetween existing ranges that forces a combination + [indexSet addIndexesInRange:CPMakeRange(47,3)]; + + [self assert:@"[number of indexes: 36 (in 4 ranges), indexes: (10-19 23 30-39 45-59)]" equals:descriptionWithoutEntity(indexSet)]; + + // Test adding range across ranges forcing a combination + [indexSet addIndexesInRange:CPMakeRange(35,15)]; + + [self assert:@"[number of indexes: 41 (in 3 ranges), indexes: (10-19 23 30-59)]" equals:descriptionWithoutEntity(indexSet)]; + + // Test adding range across two empty slots forcing a combination + [indexSet addIndexesInRange:CPMakeRange(0,70)]; + + [self assert:@"[number of indexes: 70 (in 1 range), indexes: (0-69)]" equals:descriptionWithoutEntity(indexSet)]; +} + +- (void)testRemoveIndexes +{ + var indexSet = [CPIndexSet indexSet]; + + // Test no indexes + [self assert:descriptionWithoutEntity(indexSet) equals:@"(no indexes)"]; + + // Test adding initial range + [indexSet addIndexesInRange:CPMakeRange(0, 70)]; + + [self assert:@"[number of indexes: 70 (in 1 range), indexes: (0-69)]" equals:descriptionWithoutEntity(indexSet)]; + + // Test remove range that is subset of existing range, causing a split. + [indexSet removeIndexesInRange:CPMakeRange(30, 10)]; + + [self assert:@"[number of indexes: 60 (in 2 ranges), indexes: (0-29 40-69)]" equals:descriptionWithoutEntity(indexSet)]; + + // Test remove range that is subset of existing range, causing a split. + [indexSet removeIndexesInRange:CPMakeRange(50, 5)]; + + [self assert:@"[number of indexes: 55 (in 3 ranges), indexes: (0-29 40-49 55-69)]" equals:descriptionWithoutEntity(indexSet)]; + + // Test remove index that is subset of existing range, causing a split. + [indexSet removeIndex:57]; + + [self assert:@"[number of indexes: 54 (in 4 ranges), indexes: (0-29 40-49 55-56 58-69)]" equals:descriptionWithoutEntity(indexSet)]; + + // Test remove range that is an exactly represented in the set. + [indexSet removeIndexesInRange:CPMakeRange(40, 10)]; + + [self assert:@"[number of indexes: 44 (in 3 ranges), indexes: (0-29 55-56 58-69)]" equals:descriptionWithoutEntity(indexSet)]; + + // Test remove range that isn't in the set. + [indexSet removeIndexesInRange:CPMakeRange(35, 3)]; + + [self assert:@"[number of indexes: 44 (in 3 ranges), indexes: (0-29 55-56 58-69)]" equals:descriptionWithoutEntity(indexSet)]; + + // Test remove range that is partially in a left range. + [indexSet removeIndexesInRange:CPMakeRange(25, 7)]; + + [self assert:@"[number of indexes: 39 (in 3 ranges), indexes: (0-24 55-56 58-69)]" equals:descriptionWithoutEntity(indexSet)]; + + // Test remove range that is partially in a left range. + [indexSet removeIndexesInRange:CPMakeRange(57, 3)]; + + [self assert:@"[number of indexes: 37 (in 3 ranges), indexes: (0-24 55-56 60-69)]" equals:descriptionWithoutEntity(indexSet)]; + + // Test remove range that is partially in a left and right range. + [indexSet removeIndexesInRange:CPMakeRange(20, 36)]; + + [self assert:@"[number of indexes: 31 (in 3 ranges), indexes: (0-19 56 60-69)]" equals:descriptionWithoutEntity(indexSet)]; + + // Remove single index that represents an entire range. + [indexSet removeIndex:56]; + + [self assert:@"[number of indexes: 30 (in 2 ranges), indexes: (0-19 60-69)]" equals:descriptionWithoutEntity(indexSet)]; + + // Remove index set that is subset of existing range, causing a split. + [indexSet removeIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(5, 10)]]; + + [self assert:@"[number of indexes: 20 (in 3 ranges), indexes: (0-4 15-19 60-69)]" equals:descriptionWithoutEntity(indexSet)]; + + // Remove indexes that are partially in 2 ranges and contains intermediate range. + [indexSet removeIndexesInRange:CPMakeRange(2, 62)]; + + [self assert:@"[number of indexes: 8 (in 2 ranges), indexes: (0-1 64-69)]" equals:descriptionWithoutEntity(indexSet)]; + + // Remove indexes that fit exactly in 2 ranges. + [indexSet removeIndexesInRange:CPMakeRange(0, 70)]; + + [self assert:@"(no indexes)" equals:descriptionWithoutEntity(indexSet)]; + + indexSet = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, 30)]; + + // Remove indexes from left hand of single range + [indexSet removeIndexesInRange:CPMakeRange(0, 29)]; + + [self assert:@"[number of indexes: 1 (in 1 range), indexes: (29)]" equals:descriptionWithoutEntity(indexSet)]; + + indexSet = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, 30)]; + + // Remove indexes from right hand of single range + [indexSet removeIndexesInRange:CPMakeRange(1, 29)]; + + [self assert:@"[number of indexes: 1 (in 1 range), indexes: (0)]" equals:descriptionWithoutEntity(indexSet)]; +} + +- (void)testGetIndexes +{ + var indexSet = [CPIndexSet indexSet]; + + // Test no indexes + [self assert:descriptionWithoutEntity(indexSet) equals:@"(no indexes)"]; + + // Test adding initial range + [indexSet addIndexesInRange:CPMakeRange(0, 10)]; + + [indexSet addIndexesInRange:CPMakeRange(15, 1)]; + + [indexSet addIndexesInRange:CPMakeRange(20, 10)]; + + [indexSet addIndexesInRange:CPMakeRange(50, 10)]; + + [self assert:@"[number of indexes: 31 (in 4 ranges), indexes: (0-9 15 20-29 50-59)]" equals:descriptionWithoutEntity(indexSet)]; + + var array = []; + + [indexSet getIndexes:array maxCount:1000 inIndexRange:nil]; + + [self assert:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 15, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59] equals:array]; +} + +- (void)setUp +{ + _set = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(10, 10)]; +} + +- (void)tearDown +{ + _set = nil; +} + +- (void)testIndexSet:(CPIndexSet)set containsRange:(CPRange)range +{ + [self assertFalse:[set containsIndex:range.location -1]]; + + for (var i=range.location, max=CPMaxRange(range); i +@import + +var File = require("file"), + popen = require("os").popen; + + +NibFormatUndetermined = 0, +NibFormatMac = 1, +NibFormatIPhone = 2; + +ConverterConversionException = @"ConverterConversionException"; + +@implementation Converter : CPObject +{ + NibFormat format @accessors; + CPString inputPath @accessors; + CPString outputPath @accessors; + CPString resourcesPath @accessors; +} + +- (id)init +{ + self = [super init]; + + if (self) + [self setFormat:NibFormatUndetermined]; + + return self; +} + +- (void)convert +{ + try + { + if ([resourcesPath length] && !File.isReadable(resourcesPath)) + [CPException raise:ConverterConversionException reason:@"Could not read Resources at path \"" + resourcesPath + "\""]; + + var stringContents = File.read(inputPath, { charset:"UTF-8" }), + inferredFormat = format; + + if (inferredFormat === NibFormatUndetermined) + { + // Assume its a Mac file. + inferredFormat = NibFormatMac; + + // Some .xibs are iPhone nibs, check the actual contents in this case. + if (File.extname(inputPath) !== ".nib" && + stringContents.indexOf("\s*CF\$UID\s*\<\/key\>/g, "CP$UID"); + plistContents = String(java.lang.String(plistContents).replaceAll("\\\\s*CF\\$UID\\s*\\<\/key\\>", "CP\\$UID")); + + return [CPData dataWithString:plistContents]; +} + +@end + +File.createTempFile = function(aName, anExtension, shouldDeleteOnExit) +{ + var tempFile = Packages.java.io.File.createTempFile(aName, anExtension), + tempFilePath = String(tempFile.getAbsolutePath()); + + if (shouldDeleteOnExit) + tempFile.deleteOnExit(); + + return String(tempFilePath); +} + +function cibExtension(aPath) +{ + var start = aPath.length - 1; + + while (aPath.charAt(start) === '/') + start--; + + aPath = aPath.substr(0, start + 1); + + var dotIndex = aPath.lastIndexOf('.'); + + if (dotIndex == -1) + return aPath + ".cib"; + + var slashIndex = aPath.lastIndexOf('/'); + + if (slashIndex > dotIndex) + return aPath + ".cib"; + + return aPath.substr(0, dotIndex) + ".cib"; +} + +@import "Converter+Mac.j" diff --git a/Tools/nib2cib/NSClipView.j b/Tools/nib2cib/NSClipView.j index 7ed55cfa5..7c0d9621c 100644 --- a/Tools/nib2cib/NSClipView.j +++ b/Tools/nib2cib/NSClipView.j @@ -40,6 +40,11 @@ return self; } +- (BOOL)NS_isFlipped +{ + return YES; +} + @end @implementation NSClipView : CPClipView diff --git a/Tools/nib2cib/NSCustomResource.j b/Tools/nib2cib/NSCustomResource.j index ccad4210e..e518ac020 100644 --- a/Tools/nib2cib/NSCustomResource.j +++ b/Tools/nib2cib/NSCustomResource.j @@ -41,7 +41,7 @@ importClass(javax.imageio.ImageIO); var size = CGSizeMakeZero(); - if (![aCoder resourcesFile]) + if (![[aCoder resourcesPath] length]) { CPLog.warn("***WARNING: Resources found in nib, but no resources path specified with -R option."); @@ -49,19 +49,20 @@ importClass(javax.imageio.ImageIO); } else { - var resourceFile = [aCoder resourceFileForName:_resourceName]; - - if (!resourceFile) + var resourcePath = [aCoder resourcePathForName:_resourceName]; + + if (!resourcePath) CPLog.warn("***WARNING: Resource named " + _resourceName + " not found in supplied resources path."); + else { - var imageStream = ImageIO.createImageInputStream(resourceFile), + var imageStream = ImageIO.createImageInputStream(new Packages.java.io.File(resourcePath).getCanonicalFile()), readers = ImageIO.getImageReaders(imageStream), reader = null; - + if(readers.hasNext()) reader = readers.next(); - + else { imageStream.close(); diff --git a/Tools/nib2cib/NSIBObjectData.j b/Tools/nib2cib/NSIBObjectData.j index 9031edd02..a30a7ba8c 100644 --- a/Tools/nib2cib/NSIBObjectData.j +++ b/Tools/nib2cib/NSIBObjectData.j @@ -20,20 +20,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -/*#import "NSIBObjectData.h" -#import -#import -#import -#import -#import -#import "NSNibKeyedUnarchiver.h" -#import "NSCustomObject.h" -#import -#import -#import */ - -@import - @import diff --git a/Tools/nib2cib/NSScroller.j b/Tools/nib2cib/NSScroller.j index 1c39d70bd..5909d8d93 100644 --- a/Tools/nib2cib/NSScroller.j +++ b/Tools/nib2cib/NSScroller.j @@ -45,6 +45,8 @@ if ([aCoder containsValueForKey:"NSCurValue"]) _value = [aCoder decodeFloatForKey:"NSCurValue"]; + [self _calculateIsVertical]; + var isVertical = [self isVertical]; if (CPStringFromSelector([self action]) === @"_doScroller:") diff --git a/Tools/nib2cib/NSTableColumn.j b/Tools/nib2cib/NSTableColumn.j index 0fb2055d7..2e67fd7c9 100644 --- a/Tools/nib2cib/NSTableColumn.j +++ b/Tools/nib2cib/NSTableColumn.j @@ -28,25 +28,23 @@ - (id)NS_initWithCoder:(CPCoder)aCoder { self = [self init]; - + if (self) { _identifier = [aCoder decodeObjectForKey:@"NSIdentifier"]; - - var template = [[CPTableColumn alloc] ] - + //var dataViewCell = [aCoder decodeObjectForKey:@"NSDataCell"]; - + _dataView = [[CPTextField alloc] initWithFrame:CPRectMakeZero()]; - [_dataView setValue:[CPColor whiteColor] forThemedAttributeName:"text-color" inControlState:CPThemeStateHighlighted]; - + [_dataView setValue:[CPColor whiteColor] forThemeAttribute:"text-color" inState:CPThemeStateHighlighted]; + //_headerView = [aCoder decodeObjectForKey:@"NSHeaderCell"]; _headerView = [[CPTextField alloc] initWithFrame:CPRectMakeZero()]; - + _width = [aCoder decodeFloatForKey:@"NSWidth"]; _minWidth = [aCoder decodeFloatForKey:@"NSMinWidth"]; _maxWidth = [aCoder decodeFloatForKey:@"NSMaxWidth"]; - + _resizingMask = [aCoder decodeBoolForKey:@"NSIsResizable"]; } diff --git a/Tools/nib2cib/NSView.j b/Tools/nib2cib/NSView.j index 0025bb7ef..8e0c8c219 100644 --- a/Tools/nib2cib/NSView.j +++ b/Tools/nib2cib/NSView.j @@ -56,42 +56,13 @@ _subviews = []; var vFlags = [aCoder decodeIntForKey:@"NSvFlags"]; - - var autoresizingMaskNS = vFlags & 0x3F; - - // swap Y coordinate flags: - _autoresizingMask = autoresizingMaskNS & ~(CPViewMaxYMargin | CPViewMinYMargin) - if (!(autoresizingMaskNS & (CPViewMaxYMargin | CPViewMinYMargin | CPViewHeightSizable))) - { - _autoresizingMask |= CPViewMinYMargin; - } - else - { - if (autoresizingMaskNS & CPViewMaxYMargin) - _autoresizingMask |= CPViewMinYMargin; - if (autoresizingMaskNS & CPViewMinYMargin) - _autoresizingMask |= CPViewMaxYMargin; - } - + + _autoresizingMask = vFlags & 0x3F; _autoresizesSubviews = vFlags & (1 << 8); _hitTests = YES; _isHidden = NO;//[aCoder decodeObjectForKey:CPViewIsHiddenKey]; _opacity = 1.0;//[aCoder decodeIntForKey:CPViewOpacityKey]; - - if (YES/*[_superview isFlipped]*/) - { - var height = CGRectGetHeight([self bounds]), - count = [_subviews count]; - - while (count--) - { - var subview = _subviews[count], - frame = [subview frame]; - - [subview setFrameOrigin:CGPointMake(CGRectGetMinX(frame), height - CGRectGetMaxY(frame))]; - } - } _themeAttributes = {}; _themeState = CPThemeStateNormal; @@ -101,6 +72,11 @@ return self; } +- (BOOL)NS_isFlipped +{ + return NO; +} + @end @implementation NSView : CPView diff --git a/Tools/nib2cib/Nib2CibKeyedUnarchiver.j b/Tools/nib2cib/Nib2CibKeyedUnarchiver.j index 03f5415b7..3ee13f4a5 100644 --- a/Tools/nib2cib/Nib2CibKeyedUnarchiver.j +++ b/Tools/nib2cib/Nib2CibKeyedUnarchiver.j @@ -1,52 +1,87 @@ +/* + * NSKeyedArchiver.j + * nib2cib + * + * Created by Francisco Tolmasky. + * Copyright 2008, 280 North, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * 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 +var File = require("file"); + @implementation Nib2CibKeyedUnarchiver : CPKeyedUnarchiver { - File resourcesFile; + CPString resourcesPath @accessors(readonly); } -- (id)initForReadingWithData:(CPData)data resourcesFile:(File)aResourcesFile +- (id)initForReadingWithData:(CPData)data resourcesPath:(CPString)aResourcesPath { self = [super initForReadingWithData:data]; - + if (self) - resourcesFile = aResourcesFile; - + resourcesPath = aResourcesPath; + return self; } -- (File)resourcesFile +- (CPArray)allObjects { - return resourcesFile; + return _objects; } -- (File)resourceFileForName:(CPString)aName +- (CPString)resourcePathForName:(CPString)aName { - var moreFiles = [resourcesFile.listFiles()]; + if (!resourcesPath) + return NULL; - do + var pathGroups = [File.listPaths(resourcesPath)]; + + while (pathGroups.length > 0) { - var files = moreFiles.shift(), + var paths = pathGroups.shift(), index = 0, - count = files.length; - + count = paths.length; + for (; index < count; ++index) { - var file = files[index].getCanonicalFile(), - name = String(file.getName()); - - if (name === aName) - return file; - - if (file.isDirectory()) - moreFiles.push(file.listFiles()); + var path = paths[index]; + + if (File.basename(path) === aName) + return path; + + if (File.isDirectory(path)) + pathGroups.push(File.listPaths(path)); } } - while (moreFiles.length > 0) - + return NULL; } @end + +File.listPaths = function(aPath) +{ + var paths = File.list(aPath), + count = paths.length; + + while (count--) + paths[count] = File.join(aPath, paths[count]); + + return paths; +} diff --git a/Tools/nib2cib/main.j b/Tools/nib2cib/main.j index 9654facc7..294748070 100644 --- a/Tools/nib2cib/main.j +++ b/Tools/nib2cib/main.j @@ -20,14 +20,15 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - @import @import @import "NSFoundation.j" @import "NSAppKit.j" + @import "Nib2CibKeyedUnarchiver.j" +@import "Converter.j" var File = require("file"); @@ -35,154 +36,56 @@ importPackage(java.io); CPLogRegister(CPLogPrint); -function exec(command) -{ - var p = Packages.java.lang.Runtime.getRuntime().exec(command); - var result = p.waitFor(); - - var reader = new Packages.java.io.BufferedReader(new Packages.java.io.InputStreamReader(p.getInputStream())); - while (s = reader.readLine()) - print(s); - - var reader = new Packages.java.io.BufferedReader(new Packages.java.io.InputStreamReader(p.getErrorStream())); - while (s = reader.readLine()) - print(s); - - return result; -} - function printUsage() { - java.lang.System.out.println("usage: nib2cib INPUT_FILE [OUTPUT_FILE] [-F /path/to/required/framework]"); + print("usage: nib2cib INPUT_FILE [OUTPUT_FILE] [-F /path/to/required/framework] [-R path/to/resources]"); java.lang.System.exit(1); } -function cibExtension(aPath) -{ - var start = aPath.length - 1; - - while (aPath.charAt(start) === '/') - start--; - - aPath = aPath.substr(0, start + 1); - - var dotIndex = aPath.lastIndexOf('.'); - - if (dotIndex == -1) - return aPath + ".cib"; - - var slashIndex = aPath.lastIndexOf('/'); - - if (slashIndex > dotIndex) - return aPath + ".cib"; - - return aPath.substr(0, dotIndex) + ".cib"; -} - -function convert(inputFileName, outputFileName, resourcesPath) -{ - var resourcesFile = nil; - - if (resourcesPath) - { - resourcesFile = new java.io.File(resourcesPath).getCanonicalFile(); - - if (!resourcesFile.canRead()) - { - print("Could not find Resources at " + resourcesFile); - return; - } - } - - // Make sure we can read the file - if (!(new Packages.java.io.File(inputFileName)).canRead()) - { - print("Could not read file at " + inputFileName); - return; - } - - // Compile xib or nib to make sure we have a non-new format nib. - var temporaryNibFile = java.io.File.createTempFile("temp", ".nib"), - temporaryNibFilePath = temporaryNibFile.getAbsolutePath(); - - temporaryNibFile.deleteOnExit(); - - if (exec(["/usr/bin/ibtool", inputFileName, "--compile", temporaryNibFilePath])) - { - print("Could not compile file at " + inputFileName); - return; - } - - // Convert from binary plist to XML plist - var temporaryPlistFile = java.io.File.createTempFile("temp", ".plist"), - temporaryPlistFilePath = String(temporaryPlistFile.getAbsolutePath()); - - temporaryPlistFile.deleteOnExit(); - - if (exec(["/usr/bin/plutil", "-convert", "xml1", temporaryNibFilePath, "-o", temporaryPlistFilePath])) - { - print("Could not convert to xml plist for file at " + inputFileName); - return; - } - - var data = [CPData dataWithString:File.read(String(temporaryPlistFilePath), { charset:"UTF-8" })]; - - // Minor NSKeyedArchive to CPKeyedArchive conversion. - [data setString:[data string].replace(/\\s*CF\$UID\s*\<\/key\>/g, "CP$UID")]; - - // Unarchive the NS data - var unarchiver = [[Nib2CibKeyedUnarchiver alloc] initForReadingWithData:data resourcesFile:resourcesFile], - objectData = [unarchiver decodeObjectForKey:@"IB.objectdata"], - - data = [CPData data], - archiver = [[CPKeyedArchiver alloc] initForWritingWithMutableData:data]; - - // Re-archive the CP data. - [archiver encodeObject:objectData forKey:@"CPCibObjectDataKey"]; - [archiver finishEncoding]; - - File.write(outputFileName, [data string], { charset:"UTF-8" }); -} - function loadFrameworks(frameworkPaths, aCallback) { - if (frameworkPaths.length === 0) + if (!frameworkPaths || frameworkPaths.length === 0) return aCallback(); - + var frameworkPath = frameworkPaths.shift(), - - infoPlist = new java.io.File(frameworkPath + "/Info.plist"); - - if (!infoPlist.exists()) + infoPlistPath = frameworkPath + "/Info.plist"; + + if (!File.isReadable(infoPlistPath)) { - java.lang.System.out.println("'" + frameworkPath + "' is not a framework or could not be found."); + print("'" + frameworkPath + "' is not a framework or could not be found."); java.lang.System.exit(1); } - - var infoDictionary = CPPropertyListCreateFromData([CPData dataWithString:File.read(frameworkPath + "/Info.plist", { charset:"UTF-8" })]); + + var infoDictionary = CPPropertyListCreateFromData([CPData dataWithString:File.read(infoPlistPath, { charset:"UTF-8" })]); if ([infoDictionary objectForKey:@"CPBundlePackageType"] !== "FMWK") { - java.lang.System.out.println("'" + frameworkPath + "' is not a framework."); + print("'" + frameworkPath + "' is not a framework."); java.lang.System.exit(1); } + print("Loading " + [infoDictionary objectForKey:@"CPBundleName"]); + var files = [infoDictionary objectForKey:@"CPBundleReplacedFiles"], count = files.length; - + if (count) { var context = new objj_context(); context.didCompleteCallback = function() { loadFrameworks(frameworkPaths, aCallback) }; - +print("2he"); while (count--) + { + print(frameworkPath + '/' + files[count]); context.pushFragment(fragment_create_file(frameworkPath + '/' + files[count], new objj_bundle(""), YES, NULL)); - - context.evaluate(); + } +print("hmmm"); + context.evaluate();print("wha???"); } else loadFrameworks(frameworkPaths, aCallback); +print("so far so good..."); } function main() @@ -190,41 +93,39 @@ function main() var count = arguments.length; if (count < 1) - printUsage(); + return printUsage(); var index = 0, - - inputFileName = nil, - outputFileName = nil, - resourcesPath = nil, - frameworkPaths = []; + + frameworkPaths = [], + converter = [[Converter alloc] init]; for (; index < count; ++index) { switch(arguments[index]) { case "-help": - case "--help": printUsage(); - - case "-F": frameworkPaths.push(arguments[++index]); - break; - - case "-R": resourcesPath = arguments[++index]; - break; - - default: if (inputFileName && inputFileName.length > 0) - outputFileName = arguments[index]; - else - inputFileName = arguments[index]; + case "--help": printUsage(); + break; + + case "--mac": [converter setFormat:NibFormatMac]; + break; + + case "-F": frameworkPaths.push(arguments[++index]); + break; + + case "-R": [converter setResourcesPath:arguments[++index]]; + break; + + default: if ([converter inputPath]) + [converter setOutputPath:arguments[index]]; + else + [converter setInputPath:arguments[index]]; } } - if (!outputFileName || outputFileName.length < 1) - outputFileName = cibExtension(inputFileName); - - if (frameworkPaths.length) - loadFrameworks(frameworkPaths, function() { convert(inputFileName, outputFileName, resourcesPath); }); - - else - convert(inputFileName, outputFileName, resourcesPath); + loadFrameworks(frameworkPaths, function() + { + [converter convert]; + }); }