Merge remote-tracking branch 'origin/master' into upstream_master
@@ -165,6 +165,19 @@ var DefaultLineWidth = 1.0;
|
||||
CGPathAddCurveToPoint(_path, nil, controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y, endPoint.x, endPoint.y);
|
||||
}
|
||||
|
||||
- (CGRect)bounds
|
||||
{
|
||||
// TODO: this should return this. The controlPointBounds is not a tight fit.
|
||||
// return CGPathGetPathBoundingBox(_path);
|
||||
|
||||
return [self controlPointBounds];
|
||||
}
|
||||
|
||||
- (CGRect)controlPointBounds
|
||||
{
|
||||
return CGPathGetBoundingBox(_path);
|
||||
}
|
||||
|
||||
/*!
|
||||
Create a line segment between the first and last points in the subpath, closing it.
|
||||
*/
|
||||
@@ -272,6 +285,11 @@ var DefaultLineWidth = 1.0;
|
||||
CGPathAddPath(_path, nil, CGPathWithRoundedRectangleInRect(rect, xRadius, yRadius, YES, YES, YES, YES));
|
||||
}
|
||||
|
||||
- (void)appendBezierPathWithArcFromPoint:(CGPoint)fromPoint toPoint:(CGPoint)toPoint radius:(float)radius
|
||||
{
|
||||
CGPathAddArcToPoint(_path, null, fromPoint.x, fromPoint.y, toPoint.x, toPoint.y, radius);
|
||||
}
|
||||
|
||||
/*!
|
||||
Append the contents of a CPBezierPath object.
|
||||
*/
|
||||
@@ -288,4 +306,21 @@ var DefaultLineWidth = 1.0;
|
||||
_path = CGPathCreateMutable();
|
||||
}
|
||||
|
||||
- (void)addClip
|
||||
{
|
||||
var ctx = [[CPGraphicsContext currentContext] graphicsPort];
|
||||
|
||||
CGContextAddPath(ctx, _path);
|
||||
CGContextClip(ctx);
|
||||
}
|
||||
|
||||
- (void)setClip
|
||||
{
|
||||
var ctx = [[CPGraphicsContext currentContext] graphicsPort];
|
||||
|
||||
CGContextBeginPath(ctx);
|
||||
CGContextAddPath(ctx, _path);
|
||||
CGContextClip(ctx);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -322,6 +322,16 @@ CPBelowBottom = 6;
|
||||
[self _manageTitlePositioning];
|
||||
}
|
||||
|
||||
- (CPFont)titleFont
|
||||
{
|
||||
return [_titleView font];
|
||||
}
|
||||
|
||||
- (void)setTitleFont:(CPFont)aFont
|
||||
{
|
||||
[_titleView setFont:aFont];
|
||||
}
|
||||
|
||||
- (void)_manageTitlePositioning
|
||||
{
|
||||
if (_titlePosition == CPNoTitle)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
@import "CPView.j"
|
||||
@import "CPCollectionViewItem.j"
|
||||
|
||||
@import "CPCompatibility.j"
|
||||
|
||||
/*!
|
||||
@ingroup appkit
|
||||
@@ -647,9 +647,9 @@
|
||||
|
||||
if (index >= 0 && index < _items.length)
|
||||
{
|
||||
if (_allowsMultipleSelection && ([anEvent modifierFlags] & CPCommandKeyMask || [anEvent modifierFlags] & CPShiftKeyMask))
|
||||
if (_allowsMultipleSelection && ([anEvent modifierFlags] & CPPlatformActionKeyMask || [anEvent modifierFlags] & CPShiftKeyMask))
|
||||
{
|
||||
if ([anEvent modifierFlags] & CPCommandKeyMask)
|
||||
if ([anEvent modifierFlags] & CPPlatformActionKeyMask)
|
||||
{
|
||||
var indexes = [_selectionIndexes copy];
|
||||
|
||||
@@ -690,6 +690,10 @@
|
||||
|
||||
- (void)mouseDragged:(CPEvent)anEvent
|
||||
{
|
||||
// Don't crash if we never registered the intial click.
|
||||
if (!_mouseDownEvent)
|
||||
return;
|
||||
|
||||
var locationInWindow = [anEvent locationInWindow],
|
||||
mouseDownLocationInWindow = [_mouseDownEvent locationInWindow];
|
||||
|
||||
|
||||
@@ -611,6 +611,14 @@ function CPColorWithImages()
|
||||
return [[[self class] alloc] _initWithRGBA:components];
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the receiver. This method is a placeholder that does nothing but may be implemented in the future.
|
||||
*/
|
||||
- (CPColor)colorUsingColorSpaceName:(id)aColorSpaceName
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns an array with the HSB values for this color.
|
||||
The index values are ordered as:
|
||||
|
||||
@@ -174,6 +174,21 @@ following:
|
||||
return _CPFontSystemFontSize;
|
||||
}
|
||||
|
||||
+ (float)systemFontSizeForControlSize:(CPControlSize)aSize
|
||||
{
|
||||
// TODO These sizes should be themable or made less arbitrary in some other way.
|
||||
switch (aSize)
|
||||
{
|
||||
case CPSmallControlSize:
|
||||
return _CPFontSystemFontSize - 1;
|
||||
case CPMiniControlSize:
|
||||
return _CPFontSystemFontSize - 2;
|
||||
case CPRegularControlSize:
|
||||
default:
|
||||
return _CPFontSystemFontSize;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the default system font size.
|
||||
*/
|
||||
|
||||
@@ -23,6 +23,16 @@
|
||||
@import "CPColor.j"
|
||||
@import "CPGraphicsContext.j"
|
||||
|
||||
CPCalibratedWhiteColorSpace = @"CalibratedWhiteColorSpace";
|
||||
CPCalibratedBlackColorSpace = @"CalibratedBlackColorSpace";
|
||||
CPCalibratedRGBColorSpace = @"CalibratedRGBColorSpace";
|
||||
CPDeviceWhiteColorSpace = @"DeviceWhiteColorSpace";
|
||||
CPDeviceBlackColorSpace = @"DeviceBlackColorSpace";
|
||||
CPDeviceRGBColorSpace = @"DeviceRGBColorSpace";
|
||||
CPDeviceCMYKColorSpace = @"DeviceCMYKColorSpace";
|
||||
CPNamedColorSpace = @"NamedColorSpace";
|
||||
CPPatternColorSpace = @"PatternColorSpace";
|
||||
CPCustomColorSpace = @"CustomColorSpace";
|
||||
|
||||
function CPDrawTiledRects(
|
||||
/* CGRect */ boundsRect,
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
@import "CGContext.j"
|
||||
|
||||
|
||||
var CPGraphicsContextCurrent = nil;
|
||||
var CPGraphicsContextCurrent = nil,
|
||||
CPGraphicsContextThreadStack = nil;
|
||||
|
||||
/*!
|
||||
@ingroup appkit
|
||||
@@ -52,6 +53,28 @@ var CPGraphicsContextCurrent = nil;
|
||||
CPGraphicsContextCurrent = aGraphicsContext;
|
||||
}
|
||||
|
||||
+ (void)saveGraphicsState
|
||||
{
|
||||
if (!CPGraphicsContextCurrent)
|
||||
return;
|
||||
|
||||
if (!CPGraphicsContextThreadStack)
|
||||
CPGraphicsContextThreadStack = [CPMutableArray array];
|
||||
|
||||
[CPGraphicsContextThreadStack addObject:CPGraphicsContextCurrent];
|
||||
[CPGraphicsContextCurrent saveGraphicsState];
|
||||
}
|
||||
|
||||
+ (void)restoreGraphicsState
|
||||
{
|
||||
var lastContext = [CPGraphicsContextThreadStack lastObject];
|
||||
if (lastContext)
|
||||
{
|
||||
[lastContext restoreGraphicsState];
|
||||
[CPGraphicsContextThreadStack removeLastObject];
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Creates a graphics context with a provided port.
|
||||
@param aContext the context to initialize with
|
||||
@@ -99,4 +122,14 @@ var CPGraphicsContextCurrent = nil;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)saveGraphicsState
|
||||
{
|
||||
CGContextSaveGState(_graphicsPort);
|
||||
}
|
||||
|
||||
- (void)restoreGraphicsState
|
||||
{
|
||||
CGContextRestoreGState(_graphicsPort);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -976,8 +976,7 @@ var _CPMenuBarVisible = NO,
|
||||
|
||||
for (; index < count; ++index)
|
||||
{
|
||||
var item = _items[index],
|
||||
modifierMask = [item keyEquivalentModifierMask];
|
||||
var item = _items[index];
|
||||
|
||||
if ([anEvent _triggersKeyEquivalent:[item keyEquivalent] withModifierMask:[item keyEquivalentModifierMask]])
|
||||
{
|
||||
|
||||
@@ -376,9 +376,8 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
var previousRowCount = [self numberOfRows];
|
||||
|
||||
itemInfo.isExpanded = YES;
|
||||
// XXX Shouldn't the items reload before the notification is sent?
|
||||
[self _noteItemDidExpand:anItem];
|
||||
[self reloadItem:anItem reloadChildren:YES];
|
||||
[self _noteItemDidExpand:anItem];
|
||||
|
||||
// Shift selection indexes below so that the same items remain selected.
|
||||
var rowCountDelta = [self numberOfRows] - previousRowCount;
|
||||
@@ -469,9 +468,8 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
}
|
||||
itemInfo.isExpanded = NO;
|
||||
|
||||
// XXX Shouldn't the items reload before the notification is sent?
|
||||
[self _noteItemDidCollapse:anItem];
|
||||
[self reloadItem:anItem reloadChildren:YES];
|
||||
[self _noteItemDidCollapse:anItem];
|
||||
|
||||
// Send selection notifications only after the items have loaded so that
|
||||
// the new selection is consistent with the actual rows for any observers.
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
{
|
||||
var context = [[CPGraphicsContext currentContext] graphicsPort],
|
||||
bounds = [self bounds],
|
||||
maxX = CGRectGetWidth(bounds) - 2,
|
||||
maxX = CGRectGetWidth(bounds),
|
||||
maxY = CGRectGetHeight(bounds);
|
||||
|
||||
// Draw background
|
||||
@@ -63,7 +63,7 @@
|
||||
|
||||
// Draw Top Border
|
||||
CGContextBeginPath(context);
|
||||
CGContextMoveToPoint(context, 1, 0);
|
||||
CGContextMoveToPoint(context, 0, 0);
|
||||
CGContextAddLineToPoint(context, maxX, 0);
|
||||
CGContextClosePath(context);
|
||||
CGContextSetStrokeColor(context, [_ruleEditor _sliceTopBorderColor]);
|
||||
@@ -71,8 +71,8 @@
|
||||
|
||||
// Draw Bottom Border
|
||||
CGContextBeginPath(context);
|
||||
CGContextMoveToPoint(context, 1, maxY - 0.5);
|
||||
CGContextAddLineToPoint(context, maxX, maxY - 0.5);
|
||||
CGContextMoveToPoint(context, 0, maxY);
|
||||
CGContextAddLineToPoint(context, maxX, maxY);
|
||||
CGContextClosePath(context);
|
||||
var bottomColor = (_rowIndex == [_ruleEditor _lastRow]) ? [_ruleEditor _sliceLastBottomBorderColor] : [_ruleEditor _sliceBottomBorderColor];
|
||||
CGContextSetStrokeColor(context, bottomColor);
|
||||
@@ -106,4 +106,4 @@
|
||||
return [CPString stringWithFormat:@"<%@ %p index:%d indentation:%d>",[self className],self,[self rowIndex],[self indentation]];
|
||||
}
|
||||
|
||||
@end
|
||||
@end
|
||||
|
||||
@@ -121,7 +121,7 @@ var CONTROL_HEIGHT = 16.,
|
||||
return [CPMenuItem separatorItem];
|
||||
}
|
||||
|
||||
- (_CPRuleEditorTextField)_createStaticTextFieldWithStringValue:(CPString )text
|
||||
- (_CPRuleEditorTextField)_createStaticTextFieldWithStringValue:(CPString)text
|
||||
{
|
||||
var textField = [[_CPRuleEditorTextField alloc] initWithFrame:CPMakeRect(0, 0, 200, CONTROL_HEIGHT)],
|
||||
refont = [_ruleEditor font],
|
||||
@@ -352,6 +352,15 @@ var CONTROL_HEIGHT = 16.,
|
||||
optionFrame = _ruleOptionFrames[i];
|
||||
|
||||
optionFrame.origin.y = (rowHeight - CGRectGetHeight(optionFrame)) / 2 - 2;
|
||||
|
||||
// small positioning fix
|
||||
if ([ruleOptionView isKindOfClass:CPTextField])
|
||||
{
|
||||
optionFrame.origin.y += 2;
|
||||
[_ruleOptionViews[i] setValue:CGInsetMake(7, 7, 7, 8) forThemeAttribute:@"content-inset"];
|
||||
}
|
||||
|
||||
|
||||
if (widthChanged)
|
||||
{
|
||||
optionFrame.origin.x = optionViewOriginX;
|
||||
|
||||
@@ -172,10 +172,10 @@ var CPScrollerStyleGlobal = CPScrollerStyleOverlay,
|
||||
scrollerWidth = [CPScroller scrollerWidth];
|
||||
|
||||
if (hFlag)
|
||||
frameSize.height -= scrollerWidth;
|
||||
frameSize.height += scrollerWidth;
|
||||
|
||||
if (vFlag)
|
||||
frameSize.width -= scrollerWidth;
|
||||
frameSize.width += scrollerWidth;
|
||||
|
||||
return frameSize;
|
||||
}
|
||||
|
||||
@@ -501,7 +501,12 @@ var RECENT_SEARCH_PREFIX = @" ";
|
||||
if (_CGRectContainsPoint([self searchButtonRectForBounds:[self bounds]], point))
|
||||
{
|
||||
if (_searchMenuTemplate == nil)
|
||||
[self _sendAction:self];
|
||||
{
|
||||
if ([_searchButton target] && [_searchButton action])
|
||||
[_searchButton mouseDown:anEvent];
|
||||
else
|
||||
[self _sendAction:self];
|
||||
}
|
||||
else
|
||||
[self _showMenu];
|
||||
}
|
||||
|
||||
@@ -366,11 +366,14 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
@param aSegment the segment to enable/disable
|
||||
@throws CPRangeException if \c aSegment is out of bounds
|
||||
*/
|
||||
- (void)setEnabled:(BOOL)isEnabled forSegment:(unsigned)aSegment
|
||||
- (void)setEnabled:(BOOL)shouldBeEnabled forSegment:(unsigned)aSegment
|
||||
{
|
||||
[_segments[aSegment] setEnabled:isEnabled];
|
||||
if ([_segments[aSegment] enabled] === shouldBeEnabled)
|
||||
return;
|
||||
|
||||
if (isEnabled)
|
||||
[_segments[aSegment] setEnabled:shouldBeEnabled];
|
||||
|
||||
if (shouldBeEnabled)
|
||||
_themeStates[aSegment] &= ~CPThemeStateDisabled;
|
||||
else
|
||||
_themeStates[aSegment] |= CPThemeStateDisabled;
|
||||
|
||||
@@ -494,7 +494,13 @@ CPTableColumnUserResizingMask = 1 << 1;
|
||||
*/
|
||||
- (CPSortDescriptor)sortDescriptorPrototype
|
||||
{
|
||||
return _sortDescriptorPrototype;
|
||||
if (_sortDescriptorPrototype)
|
||||
return _sortDescriptorPrototype;
|
||||
|
||||
var binderClass = [[self class] _binderClassForBinding:CPValueBinding],
|
||||
binding = [binderClass getBinding:CPValueBinding forObject:self];
|
||||
|
||||
return [binding _defaultSortDescriptorPrototype];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -570,6 +576,30 @@ CPTableColumnUserResizingMask = 1 << 1;
|
||||
[tableView reloadDataForRowIndexes:rowIndexes columnIndexes:columnIndexes];
|
||||
}
|
||||
|
||||
- (CPSortDescriptor)_defaultSortDescriptorPrototype
|
||||
{
|
||||
if (![self createsSortDescriptor])
|
||||
return nil;
|
||||
|
||||
var keyPath = [_info objectForKey:CPObservedKeyPathKey],
|
||||
dotIndex = keyPath.indexOf(".");
|
||||
|
||||
if (dotIndex === CPNotFound)
|
||||
return nil;
|
||||
|
||||
var firstPart = keyPath.substring(0, dotIndex),
|
||||
key = keyPath.substring(dotIndex + 1);
|
||||
|
||||
return [CPSortDescriptor sortDescriptorWithKey:key ascending:YES];
|
||||
}
|
||||
|
||||
- (BOOL)createsSortDescriptor
|
||||
{
|
||||
var options = [_info objectForKey:CPOptionsKey],
|
||||
optionValue = [options objectForKey:CPCreatesSortDescriptorBindingOption];
|
||||
return optionValue === nil ? YES : [optionValue boolValue];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation CPTableColumn (Bindings)
|
||||
|
||||
@@ -39,8 +39,8 @@
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], CGInsetMakeZero(), [CPNull null], [CPNull null], [CPNull null], CGSizeMakeZero()]
|
||||
forKeys:[@"background-color", @"text-alignment", @"text-inset", @"text-color", @"font", @"text-shadow-color", @"text-shadow-offset"]];
|
||||
return [CPDictionary dictionaryWithObjects:[[CPNull null], CPLeftTextAlignment, CPLineBreakByTruncatingTail, CGInsetMakeZero(), [CPNull null], [CPNull null], [CPNull null], CGSizeMakeZero()]
|
||||
forKeys:[@"background-color", @"text-alignment", @"line-break-mode", @"text-inset", @"text-color", @"font", @"text-shadow-color", @"text-shadow-offset"]];
|
||||
}
|
||||
|
||||
- (void)initWithFrame:(CGRect)frame
|
||||
@@ -78,6 +78,7 @@
|
||||
[_textField setTextShadowColor:[self currentValueForThemeAttribute:@"text-shadow-color"]];
|
||||
[_textField setTextShadowOffset:[self currentValueForThemeAttribute:@"text-shadow-offset"]];
|
||||
[_textField setAlignment:[self currentValueForThemeAttribute:@"text-alignment"]];
|
||||
[_textField setLineBreakMode:[self currentValueForThemeAttribute:@"line-break-mode"]];
|
||||
}
|
||||
|
||||
- (void)setStringValue:(CPString)string
|
||||
@@ -102,7 +103,52 @@
|
||||
|
||||
- (void)setFont:(CPFont)aFont
|
||||
{
|
||||
[self setValue:aFont forThemeAttribute:"font"];
|
||||
[self setValue:aFont forThemeAttribute:@"font"];
|
||||
}
|
||||
|
||||
- (CPFont)font
|
||||
{
|
||||
return [self currentValueForThemeAttribute:@"font"]
|
||||
}
|
||||
|
||||
- (void)setAlignment:(CPTextAlignment)alignment
|
||||
{
|
||||
[self setValue:alignment forThemeAttribute:@"text-alignment"];
|
||||
}
|
||||
|
||||
- (CPTextAlignment)alignment
|
||||
{
|
||||
return [self currentValueForThemeAttribute:@"text-alignment"]
|
||||
}
|
||||
|
||||
- (void)setLineBreakMode:(CPLineBreakMode)mode
|
||||
{
|
||||
[self setValue:mode forThemeAttribute:@"line-break-mode"];
|
||||
}
|
||||
|
||||
- (CPLineBreakMode)lineBreakMode
|
||||
{
|
||||
return [self currentValueForThemeAttribute:@"line-break-mode"]
|
||||
}
|
||||
|
||||
- (void)setTextColor:(CPColor)aColor
|
||||
{
|
||||
[self setValue:aColor forThemeAttribute:@"text-color"];
|
||||
}
|
||||
|
||||
- (CPColor)textColor
|
||||
{
|
||||
return [self currentValueForThemeAttribute:@"text-color"]
|
||||
}
|
||||
|
||||
- (void)setTextShadowColor:(CPColor)aColor
|
||||
{
|
||||
[self setValue:aColor forThemeAttribute:@"text-shadow-color"];
|
||||
}
|
||||
|
||||
- (CPColor)textShadowColor
|
||||
{
|
||||
return [self currentValueForThemeAttribute:@"text-shadow-color"]
|
||||
}
|
||||
|
||||
- (void)_setIndicatorImage:(CPImage)anImage
|
||||
@@ -122,6 +168,10 @@
|
||||
|
||||
var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringValueKey",
|
||||
_CPTableColumnHeaderViewFontKey = @"_CPTableColumnHeaderViewFontKey",
|
||||
_CPTableColumnHeaderViewTextColorKey = @"_CPTableColumnHeaderViewTextColorKey",
|
||||
_CPTableColumnHeaderViewTextShadowColorKey = @"_CPTableColumnHeaderViewTextShadowColorKey",
|
||||
_CPTableColumnHeaderViewAlignmentKey = @"_CPTableColumnHeaderViewAlignmentKey",
|
||||
_CPTableColumnHeaderViewLineBreakModeKey = @"_CPTableColumnHeaderViewLineBreakModeKey",
|
||||
_CPTableColumnHeaderViewImageKey = @"_CPTableColumnHeaderViewImageKey";
|
||||
|
||||
@implementation _CPTableColumnHeaderView (CPCoding)
|
||||
@@ -134,6 +184,10 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
||||
[self _setIndicatorImage:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewImageKey]];
|
||||
[self setStringValue:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewStringValueKey]];
|
||||
[self setFont:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewFontKey]];
|
||||
[self setTextColor:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewTextColorKey]];
|
||||
[self setTextShadowColor:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewTextShadowColorKey]];
|
||||
[self setAlignment:[aCoder decodeIntForKey:_CPTableColumnHeaderViewAlignmentKey]];
|
||||
[self setLineBreakMode:[aCoder decodeIntForKey:_CPTableColumnHeaderViewLineBreakModeKey]];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -145,7 +199,11 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
||||
|
||||
[aCoder encodeObject:[_textField text] forKey:_CPTableColumnHeaderViewStringValueKey];
|
||||
[aCoder encodeObject:[_textField image] forKey:_CPTableColumnHeaderViewImageKey];
|
||||
[aCoder encodeObject:[_textField font] forKey:_CPTableColumnHeaderViewFontKey];
|
||||
[aCoder encodeObject:[self font] forKey:_CPTableColumnHeaderViewFontKey];
|
||||
[aCoder encodeObject:[self textColor] forKey:_CPTableColumnHeaderViewTextColorKey];
|
||||
[aCoder encodeObject:[self textShadowColor] forKey:_CPTableColumnHeaderViewTextShadowColorKey];
|
||||
[aCoder encodeInt:[self alignment] forKey:_CPTableColumnHeaderViewAlignmentKey];
|
||||
[aCoder encodeInt:[self lineBreakMode] forKey:_CPTableColumnHeaderViewLineBreakModeKey];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
@import "CPTableColumn.j"
|
||||
@import "_CPCornerView.j"
|
||||
@import "CPScroller.j"
|
||||
@import "CPCompatibility.j"
|
||||
|
||||
|
||||
CPTableViewColumnDidMoveNotification = @"CPTableViewColumnDidMoveNotification";
|
||||
@@ -221,6 +222,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
|
||||
|
||||
SEL _doubleAction;
|
||||
CPInteger _clickedRow;
|
||||
CPInteger _clickedColumn;
|
||||
unsigned _columnAutoResizingStyle;
|
||||
|
||||
int _lastTrackedRowIndex;
|
||||
@@ -323,7 +325,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
|
||||
*/
|
||||
- (void)_init
|
||||
{
|
||||
_lastSelectedRow = -1;
|
||||
_lastSelectedRow = _clickedColumn = _clickedRow = -1;
|
||||
|
||||
_selectedColumnIndexes = [CPIndexSet indexSet];
|
||||
_selectedRowIndexes = [CPIndexSet indexSet];
|
||||
@@ -541,8 +543,12 @@ NOT YET IMPLEMENTED
|
||||
}
|
||||
|
||||
/*
|
||||
* - clickedColumn
|
||||
Returns the index of the the column the user clicked to trigger an action, or -1 if no column was clicked.
|
||||
*/
|
||||
- (CPInteger)clickedColumn
|
||||
{
|
||||
return _clickedColumn;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the index of the the row the user clicked to trigger an action, or -1 if no row was clicked.
|
||||
@@ -2644,7 +2650,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
if (_allowsColumnSelection)
|
||||
{
|
||||
[self _noteSelectionIsChanging];
|
||||
if (modifierFlags & CPCommandKeyMask)
|
||||
if (modifierFlags & CPPlatformActionKeyMask)
|
||||
{
|
||||
if ([self isColumnSelected:clickedColumn])
|
||||
[self deselectColumn:clickedColumn];
|
||||
@@ -2881,13 +2887,8 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
row = [_exposedRows indexGreaterThanIndex:row];
|
||||
}
|
||||
|
||||
// Add the column header view
|
||||
var headerFrame = [headerView frame];
|
||||
headerFrame.origin = _CGPointMakeZero();
|
||||
|
||||
var columnHeaderView = [[_CPTableColumnHeaderView alloc] initWithFrame:headerFrame];
|
||||
[columnHeaderView setStringValue:[headerView stringValue]];
|
||||
[columnHeaderView setThemeState:[headerView themeState]];
|
||||
// Add a copy of the header view.
|
||||
var columnHeaderView = [CPKeyedUnarchiver unarchiveObjectWithData:[CPKeyedArchiver archivedDataWithRootObject:headerView]];
|
||||
[dragView addSubview:columnHeaderView];
|
||||
|
||||
[dragView setBackgroundColor:[CPColor whiteColor]];
|
||||
@@ -3380,12 +3381,15 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
rowIndex = 0,
|
||||
rowsCount = rowArray.length;
|
||||
|
||||
for (; rowIndex < rowsCount; ++rowIndex)
|
||||
if (dataViewsForTableColumn)
|
||||
{
|
||||
var row = rowArray[rowIndex],
|
||||
dataView = dataViewsForTableColumn[row];
|
||||
for (; rowIndex < rowsCount; ++rowIndex)
|
||||
{
|
||||
var row = rowArray[rowIndex],
|
||||
dataView = dataViewsForTableColumn[row];
|
||||
|
||||
[dataView setFrame:[self frameOfDataViewAtColumn:column row:row]];
|
||||
[dataView setFrame:[self frameOfDataViewAtColumn:column row:row]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4192,7 +4196,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
_isSelectingSession = NO;
|
||||
|
||||
var CLICK_TIME_DELTA = 1000,
|
||||
columnIndex,
|
||||
columnIndex = -1,
|
||||
column,
|
||||
rowIndex,
|
||||
shouldEdit = YES;
|
||||
@@ -4200,6 +4204,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
if (_implementedDataSourceMethods & CPTableViewDataSource_tableView_writeRowsWithIndexes_toPasteboard_)
|
||||
{
|
||||
rowIndex = [self rowAtPoint:aPoint];
|
||||
|
||||
if (rowIndex !== -1)
|
||||
{
|
||||
if ([_draggedRowIndexes count] > 0)
|
||||
@@ -4221,12 +4226,15 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
|| [self infoForBinding:@"content"]))
|
||||
{
|
||||
columnIndex = [self columnAtPoint:lastPoint];
|
||||
|
||||
if (columnIndex !== -1)
|
||||
{
|
||||
column = _tableColumns[columnIndex];
|
||||
|
||||
if ([column isEditable])
|
||||
{
|
||||
rowIndex = [self rowAtPoint:aPoint];
|
||||
|
||||
if (rowIndex !== -1)
|
||||
{
|
||||
if (_implementedDelegateMethods & CPTableViewDelegate_tableView_shouldEditTableColumn_row_)
|
||||
@@ -4246,6 +4254,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
if ([[CPApp currentEvent] clickCount] === 2 && _doubleAction)
|
||||
{
|
||||
_clickedRow = [self rowAtPoint:aPoint];
|
||||
_clickedColumn = [self columnAtPoint:lastPoint];
|
||||
[self sendAction:_doubleAction to:_target];
|
||||
}
|
||||
}
|
||||
@@ -4785,10 +4794,15 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
_contentBindingExpicitelySet = NO;
|
||||
}
|
||||
|
||||
if ([[self infoForBinding:@"selectionIndexes"] objectForKey:CPObservedObjectKey] !== destination)
|
||||
[self bind:@"selectionIndexes" toObject:destination withKeyPath:@"selectionIndexes" options:nil];
|
||||
// If the content binding was set manually assume the user is taking manual control of establishing bindings.
|
||||
if (!_contentBindingExpicitelySet)
|
||||
{
|
||||
if ([[self infoForBinding:@"selectionIndexes"] objectForKey:CPObservedObjectKey] !== destination)
|
||||
[self bind:@"selectionIndexes" toObject:destination withKeyPath:@"selectionIndexes" options:nil];
|
||||
|
||||
//[self bind:@"sortDescriptors" toObject:destination withKeyPath:@"sortDescriptors" options:nil];
|
||||
if ([[self infoForBinding:@"sortDescriptors"] objectForKey:CPObservedObjectKey] !== destination)
|
||||
[self bind:@"sortDescriptors" toObject:destination withKeyPath:@"sortDescriptors" options:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)bind:(CPString)aBinding toObject:(id)anObject withKeyPath:(CPString)aKeyPath options:(CPDictionary)options
|
||||
|
||||
@@ -1174,6 +1174,10 @@ var LABEL_MARGIN = 2.0;
|
||||
|
||||
- (void)setEnabled:(BOOL)shouldBeEnabled
|
||||
{
|
||||
// Tiling is very expensive so try to avoid it. The CPToolbarItem should already be careful to not notifying about its enabled state needlessly.
|
||||
if ([self isEnabled] === shouldBeEnabled)
|
||||
return;
|
||||
|
||||
[super setEnabled:shouldBeEnabled];
|
||||
|
||||
if (shouldBeEnabled)
|
||||
|
||||
@@ -275,6 +275,9 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
|
||||
*/
|
||||
- (void)setEnabled:(BOOL)shouldBeEnabled
|
||||
{
|
||||
if (_isEnabled === shouldBeEnabled)
|
||||
return;
|
||||
|
||||
if ([_view respondsToSelector:@selector(setEnabled:)])
|
||||
[_view setEnabled:shouldBeEnabled];
|
||||
|
||||
@@ -457,26 +460,49 @@ CPToolbarItemVisibilityPriorityUser
|
||||
if (_view)
|
||||
{
|
||||
if ([target respondsToSelector:@selector(validateToolbarItem:)])
|
||||
[self setEnabled:[target validateToolbarItem:self]];
|
||||
{
|
||||
var shouldBeEnabled = [target validateToolbarItem:self];
|
||||
if (_isEnabled !== shouldBeEnabled)
|
||||
[self setEnabled:shouldBeEnabled];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!action)
|
||||
return [self setEnabled:NO];
|
||||
{
|
||||
if (_isEnabled)
|
||||
return [self setEnabled:NO];
|
||||
return;
|
||||
}
|
||||
|
||||
if (target && ![target respondsToSelector:action])
|
||||
return [self setEnabled:NO];
|
||||
{
|
||||
if (_isEnabled)
|
||||
return [self setEnabled:NO];
|
||||
return;
|
||||
}
|
||||
|
||||
target = [CPApp targetForAction:action to:target from:self];
|
||||
|
||||
if (!target)
|
||||
return [self setEnabled:NO];
|
||||
{
|
||||
if (_isEnabled)
|
||||
return [self setEnabled:NO];
|
||||
return;
|
||||
}
|
||||
|
||||
if ([target respondsToSelector:@selector(validateToolbarItem:)])
|
||||
[self setEnabled:[target validateToolbarItem:self]];
|
||||
{
|
||||
var shouldBeEnabled = [target validateToolbarItem:self];
|
||||
if (_isEnabled !== shouldBeEnabled)
|
||||
[self setEnabled:shouldBeEnabled];
|
||||
}
|
||||
else
|
||||
[self setEnabled:YES];
|
||||
{
|
||||
if (!_isEnabled)
|
||||
[self setEnabled:YES];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)autovalidates
|
||||
|
||||
@@ -98,9 +98,6 @@ var CPViewFlags = { },
|
||||
CPViewHasCustomDrawRect = 1 << 0,
|
||||
CPViewHasCustomLayoutSubviews = 1 << 1;
|
||||
|
||||
var CPCurrentToolTip,
|
||||
CPCurrentToolTipTimer,
|
||||
CPToolTipDelay = 1.0;
|
||||
|
||||
/*!
|
||||
@ingroup appkit
|
||||
@@ -246,8 +243,8 @@ var CPCurrentToolTip,
|
||||
- (void)_setupToolTipHandlers
|
||||
{
|
||||
_toolTipInstalled = NO;
|
||||
_toolTipFunctionIn = function(e) { [self _fireToolTip]; }
|
||||
_toolTipFunctionOut = function(e) { [self _invalidateToolTip]; };
|
||||
_toolTipFunctionIn = function(e) { [_CPToolTip scheduleToolTipForView:self]; }
|
||||
_toolTipFunctionOut = function(e) { [_CPToolTip invalidateCurrentToolTipIfNeeded]; };
|
||||
}
|
||||
|
||||
+ (CPSet)keyPathsForValuesAffectingFrame
|
||||
@@ -336,6 +333,9 @@ var CPCurrentToolTip,
|
||||
if (_toolTip == aToolTip)
|
||||
return;
|
||||
|
||||
if (aToolTip && ![aToolTip isKindOfClass:CPString])
|
||||
aToolTip = [aToolTip description];
|
||||
|
||||
_toolTip = aToolTip;
|
||||
|
||||
if (_toolTip)
|
||||
@@ -398,54 +398,6 @@ var CPCurrentToolTip,
|
||||
_toolTipInstalled = NO;
|
||||
}
|
||||
|
||||
/*! @ignore
|
||||
Starts the tooltip timer.
|
||||
*/
|
||||
- (void)_fireToolTip
|
||||
{
|
||||
if (CPCurrentToolTipTimer)
|
||||
{
|
||||
[CPCurrentToolTipTimer invalidate];
|
||||
|
||||
if (CPCurrentToolTip)
|
||||
[CPCurrentToolTip close];
|
||||
|
||||
CPCurrentToolTip = nil;
|
||||
}
|
||||
|
||||
if (_toolTip)
|
||||
CPCurrentToolTipTimer = [CPTimer scheduledTimerWithTimeInterval:CPToolTipDelay target:self selector:@selector(_showToolTip:) userInfo:nil repeats:NO];
|
||||
}
|
||||
|
||||
/*! @ignore
|
||||
Stop the tooltip timer if any
|
||||
*/
|
||||
- (void)_invalidateToolTip
|
||||
{
|
||||
if (CPCurrentToolTipTimer)
|
||||
{
|
||||
[CPCurrentToolTipTimer invalidate];
|
||||
CPCurrentToolTipTimer = nil;
|
||||
}
|
||||
|
||||
if (CPCurrentToolTip)
|
||||
{
|
||||
[CPCurrentToolTip close];
|
||||
CPCurrentToolTip = nil;
|
||||
}
|
||||
}
|
||||
|
||||
/*! @ignore
|
||||
Actually shows the tooltip if any
|
||||
*/
|
||||
- (void)_showToolTip:(CPTimer)aTimer
|
||||
{
|
||||
if (CPCurrentToolTip)
|
||||
[CPCurrentToolTip close];
|
||||
|
||||
CPCurrentToolTip = [_CPToolTip toolTipWithString:_toolTip];
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the container view of the receiver
|
||||
@return the receiver's containing view
|
||||
@@ -987,32 +939,90 @@ var CPCurrentToolTip,
|
||||
}
|
||||
else
|
||||
{
|
||||
var images = [[_backgroundColor patternImage] imageSlices];
|
||||
var images = [[_backgroundColor patternImage] imageSlices],
|
||||
partIndex = 0;
|
||||
|
||||
if (_backgroundType === BackgroundVerticalThreePartImage)
|
||||
{
|
||||
var top = _DOMImageSizes[0] ? _DOMImageSizes[0].height : 0,
|
||||
bottom = _DOMImageSizes[2] ? _DOMImageSizes[2].height : 0;
|
||||
|
||||
// Make sure to repeat the top and bottom pieces horizontally if they're not the exact width needed.
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[0], size.width, _DOMImageSizes[0].height);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], size.width, size.height - _DOMImageSizes[0].height - _DOMImageSizes[2].height);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[2], size.width, _DOMImageSizes[2].height);
|
||||
if (top)
|
||||
{
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width, top);
|
||||
partIndex++;
|
||||
}
|
||||
if (_DOMImageSizes[1])
|
||||
{
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width, size.height - top - bottom);
|
||||
partIndex++;
|
||||
}
|
||||
if (bottom)
|
||||
{
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width, bottom);
|
||||
}
|
||||
}
|
||||
else if (_backgroundType === BackgroundHorizontalThreePartImage)
|
||||
{
|
||||
var left = _DOMImageSizes[0] ? _DOMImageSizes[0].width : 0,
|
||||
right = _DOMImageSizes[2] ? _DOMImageSizes[2].width : 0;
|
||||
|
||||
// Make sure to repeat the left and right pieces vertically if they're not the exact height needed.
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[0], _DOMImageSizes[0].width, size.height);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], size.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width, size.height);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[2], _DOMImageSizes[2].width, size.height);
|
||||
if (left)
|
||||
{
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], left, size.height);
|
||||
partIndex++;
|
||||
}
|
||||
if (_DOMImageSizes[1])
|
||||
{
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width - left - right, size.height);
|
||||
partIndex++;
|
||||
}
|
||||
if (right)
|
||||
{
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], right, size.height);
|
||||
}
|
||||
}
|
||||
else if (_backgroundType === BackgroundNinePartImage)
|
||||
{
|
||||
var width = size.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width,
|
||||
height = size.height - _DOMImageSizes[0].height - _DOMImageSizes[6].height;
|
||||
var left = _DOMImageSizes[0] ? _DOMImageSizes[0].width : 0,
|
||||
right = _DOMImageSizes[2] ? _DOMImageSizes[2].width : 0,
|
||||
top = _DOMImageSizes[0] ? _DOMImageSizes[0].height : 0,
|
||||
bottom = _DOMImageSizes[6] ? _DOMImageSizes[6].height : 0,
|
||||
width = size.width - left - right,
|
||||
height = size.height - top - bottom;
|
||||
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], width, _DOMImageSizes[0].height);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[3], _DOMImageSizes[3].width, height);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[4], width, height);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[5], _DOMImageSizes[5].width, height);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[7], width, _DOMImageSizes[7].height);
|
||||
if (_DOMImageSizes[0])
|
||||
partIndex++;
|
||||
if (_DOMImageSizes[1])
|
||||
{
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, top);
|
||||
partIndex++;
|
||||
}
|
||||
if (_DOMImageSizes[2])
|
||||
partIndex++;
|
||||
if (_DOMImageSizes[3])
|
||||
{
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], _DOMImageSizes[3].width, height);
|
||||
partIndex++;
|
||||
}
|
||||
if (_DOMImageSizes[4])
|
||||
{
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, height);
|
||||
partIndex++;
|
||||
}
|
||||
if (_DOMImageSizes[5])
|
||||
{
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], _DOMImageSizes[5].width, height);
|
||||
partIndex++;
|
||||
}
|
||||
if (_DOMImageSizes[6])
|
||||
partIndex++;
|
||||
if (_DOMImageSizes[7])
|
||||
{
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, _DOMImageSizes[7].height);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1508,7 +1518,7 @@ var CPCurrentToolTip,
|
||||
*/
|
||||
- (CPView)hitTest:(CPPoint)aPoint
|
||||
{
|
||||
if (_isHidden || !_hitTests || !CPRectContainsPoint(_frame, aPoint))
|
||||
if (_isHidden || !_hitTests || !_CGRectContainsPoint(_frame, aPoint))
|
||||
return nil;
|
||||
|
||||
var view = nil,
|
||||
@@ -1584,17 +1594,18 @@ var CPCurrentToolTip,
|
||||
colorHasAlpha = colorExists && [_backgroundColor alphaComponent] < 1.0,
|
||||
supportsRGBA = CPFeatureIsCompatible(CPCSSRGBAFeature),
|
||||
colorNeedsDOMElement = colorHasAlpha && !supportsRGBA,
|
||||
amount = 0;
|
||||
amount = 0,
|
||||
slices;
|
||||
|
||||
if ([patternImage isThreePartImage])
|
||||
{
|
||||
_backgroundType = [patternImage isVertical] ? BackgroundVerticalThreePartImage : BackgroundHorizontalThreePartImage;
|
||||
amount = 3 - _DOMImageParts.length;
|
||||
amount = 3;
|
||||
}
|
||||
else if ([patternImage isNinePartImage])
|
||||
{
|
||||
_backgroundType = BackgroundNinePartImage;
|
||||
amount = 9 - _DOMImageParts.length;
|
||||
amount = 9;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1602,6 +1613,34 @@ var CPCurrentToolTip,
|
||||
amount = (colorNeedsDOMElement ? 1 : 0) - _DOMImageParts.length;
|
||||
}
|
||||
|
||||
// Prepare multipart image data and reduce number of required DOM parts by number of empty slices in the multipart image to save needless DOM elements.
|
||||
if (_backgroundType === BackgroundVerticalThreePartImage || _backgroundType === BackgroundHorizontalThreePartImage || _backgroundType === BackgroundNinePartImage)
|
||||
{
|
||||
slices = [patternImage imageSlices];
|
||||
|
||||
// We won't need more divs than there are slices.
|
||||
amount = MIN(amount, slices.length);
|
||||
|
||||
for (var i = 0, count = slices.length; i < count; i++)
|
||||
{
|
||||
var image = slices[i],
|
||||
size = [image size];
|
||||
|
||||
if (!size || (size.width == 0 && size.height == 0))
|
||||
size = nil;
|
||||
|
||||
_DOMImageSizes[i] = size;
|
||||
|
||||
// If there's a nil slice or a slice with no size, it won't need a div.
|
||||
if (!size)
|
||||
amount--;
|
||||
}
|
||||
|
||||
// Now that we know how many divs we really need, compare that to number we actually have.
|
||||
amount -= _DOMImageParts.length;
|
||||
}
|
||||
|
||||
// Make sure the number of divs we have match our needs.
|
||||
if (amount > 0)
|
||||
{
|
||||
while (amount--)
|
||||
@@ -1643,70 +1682,148 @@ var CPCurrentToolTip,
|
||||
}
|
||||
else
|
||||
{
|
||||
var slices = [patternImage imageSlices],
|
||||
count = MIN(_DOMImageParts.length, slices.length),
|
||||
frameSize = _frame.size;
|
||||
var frameSize = _frame.size,
|
||||
partIndex = 0;
|
||||
|
||||
while (count--)
|
||||
for (var i = 0; i < slices.length; i++)
|
||||
{
|
||||
var image = slices[count],
|
||||
size = _DOMImageSizes[count] = image ? [image size] : _CGSizeMakeZero();
|
||||
var size = _DOMImageSizes[i];
|
||||
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[count], size.width, size.height);
|
||||
if (!size)
|
||||
continue;
|
||||
|
||||
_DOMImageParts[count].style.background = image ? "url(\"" + [image filename] + "\")" : "";
|
||||
var image = slices[i];
|
||||
|
||||
// // If image was nil, size should have been nil too.
|
||||
// assert(image != nil);
|
||||
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width, size.height);
|
||||
|
||||
_DOMImageParts[partIndex].style.background = "url(\"" + [image filename] + "\")";
|
||||
|
||||
if (!supportsRGBA)
|
||||
{
|
||||
if (CPFeatureIsCompatible(CPOpacityRequiresFilterFeature))
|
||||
try { _DOMImageParts[count].style.removeAttribute("filter") } catch (anException) { }
|
||||
try { _DOMImageParts[partIndex].style.removeAttribute("filter") } catch (anException) { }
|
||||
else
|
||||
_DOMImageParts[count].style.opacity = 1.0;
|
||||
_DOMImageParts[partIndex].style.opacity = 1.0;
|
||||
}
|
||||
|
||||
partIndex++;
|
||||
}
|
||||
|
||||
if (_backgroundType == BackgroundNinePartImage)
|
||||
{
|
||||
var width = frameSize.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width,
|
||||
height = frameSize.height - _DOMImageSizes[0].height - _DOMImageSizes[6].height;
|
||||
var left = _DOMImageSizes[0] ? _DOMImageSizes[0].width : 0,
|
||||
right = _DOMImageSizes[2] ? _DOMImageSizes[2].width : 0,
|
||||
top = _DOMImageSizes[0] ? _DOMImageSizes[0].height : 0,
|
||||
bottom = _DOMImageSizes[6] ? _DOMImageSizes[6].height : 0,
|
||||
width = frameSize.width - left - right,
|
||||
height = frameSize.height - top - bottom;
|
||||
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], width, _DOMImageSizes[0].height);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[3], _DOMImageSizes[3].width, height);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[4], width, height);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[5], _DOMImageSizes[5].width, height);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[7], width, _DOMImageSizes[7].height);
|
||||
partIndex = 0;
|
||||
|
||||
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[0], NULL, 0.0, 0.0);
|
||||
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[1], NULL, _DOMImageSizes[0].width, 0.0);
|
||||
CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[2], NULL, 0.0, 0.0);
|
||||
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[3], NULL, 0.0, _DOMImageSizes[1].height);
|
||||
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[4], NULL, _DOMImageSizes[0].width, _DOMImageSizes[0].height);
|
||||
CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[5], NULL, 0.0, _DOMImageSizes[1].height);
|
||||
CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[6], NULL, 0.0, 0.0);
|
||||
CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[7], NULL, _DOMImageSizes[6].width, 0.0);
|
||||
CPDOMDisplayServerSetStyleRightBottom(_DOMImageParts[8], NULL, 0.0, 0.0);
|
||||
if (_DOMImageSizes[0])
|
||||
{
|
||||
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
|
||||
partIndex++;
|
||||
}
|
||||
if (_DOMImageSizes[1])
|
||||
{
|
||||
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, left, 0.0);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, _DOMImageSizes[1].height);
|
||||
partIndex++;
|
||||
}
|
||||
if (_DOMImageSizes[2])
|
||||
{
|
||||
CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
|
||||
partIndex++;
|
||||
}
|
||||
if (_DOMImageSizes[3])
|
||||
{
|
||||
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, top);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], _DOMImageSizes[3].width, height);
|
||||
partIndex++;
|
||||
}
|
||||
if (_DOMImageSizes[4])
|
||||
{
|
||||
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, left, top);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, height);
|
||||
partIndex++;
|
||||
}
|
||||
if (_DOMImageSizes[5])
|
||||
{
|
||||
CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[partIndex], NULL, 0.0, top);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], _DOMImageSizes[5].width, height);
|
||||
partIndex++;
|
||||
}
|
||||
if (_DOMImageSizes[6])
|
||||
{
|
||||
CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
|
||||
partIndex++;
|
||||
}
|
||||
if (_DOMImageSizes[7])
|
||||
{
|
||||
CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[partIndex], NULL, left, 0.0);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, _DOMImageSizes[7].height);
|
||||
partIndex++;
|
||||
}
|
||||
if (_DOMImageSizes[8])
|
||||
{
|
||||
CPDOMDisplayServerSetStyleRightBottom(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
else if (_backgroundType == BackgroundVerticalThreePartImage)
|
||||
{
|
||||
// Make sure to repeat the top and bottom pieces horizontally if they're not the exact width needed.
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[0], frameSize.width, _DOMImageSizes[0].height);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], frameSize.width, frameSize.height - _DOMImageSizes[0].height - _DOMImageSizes[2].height);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[2], frameSize.width, _DOMImageSizes[2].height);
|
||||
var top = _DOMImageSizes[0] ? _DOMImageSizes[0].height : 0,
|
||||
bottom = _DOMImageSizes[2] ? _DOMImageSizes[2].height : 0;
|
||||
|
||||
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[0], NULL, 0.0, 0.0);
|
||||
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[1], NULL, 0.0, _DOMImageSizes[0].height);
|
||||
CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[2], NULL, 0.0, 0.0);
|
||||
partIndex = 0;
|
||||
|
||||
// Make sure to repeat the top and bottom pieces horizontally if they're not the exact width needed.
|
||||
if (top)
|
||||
{
|
||||
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], frameSize.width, top);
|
||||
partIndex++;
|
||||
}
|
||||
if (_DOMImageSizes[1])
|
||||
{
|
||||
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, top);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], frameSize.width, frameSize.height - top - bottom);
|
||||
partIndex++;
|
||||
}
|
||||
if (bottom)
|
||||
{
|
||||
CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], frameSize.width, bottom);
|
||||
}
|
||||
}
|
||||
else if (_backgroundType == BackgroundHorizontalThreePartImage)
|
||||
{
|
||||
// Make sure to repeat the left and right pieces vertically if they're not the exact height needed.
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[0], _DOMImageSizes[0].width, frameSize.height);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], frameSize.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width, frameSize.height);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[2], _DOMImageSizes[2].width, frameSize.height);
|
||||
var left = _DOMImageSizes[0] ? _DOMImageSizes[0].width : 0,
|
||||
right = _DOMImageSizes[2] ? _DOMImageSizes[2].width : 0;
|
||||
|
||||
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[0], NULL, 0.0, 0.0);
|
||||
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[1], NULL, _DOMImageSizes[0].width, 0.0);
|
||||
CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[2], NULL, 0.0, 0.0);
|
||||
partIndex = 0;
|
||||
|
||||
// Make sure to repeat the left and right pieces vertically if they're not the exact height needed.
|
||||
if (left)
|
||||
{
|
||||
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], left, frameSize.height);
|
||||
partIndex++;
|
||||
}
|
||||
if (_DOMImageSizes[1])
|
||||
{
|
||||
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, left, 0.0);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], frameSize.width - left - right, frameSize.height);
|
||||
partIndex++;
|
||||
}
|
||||
if (right)
|
||||
{
|
||||
CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], right, frameSize.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -2907,6 +3024,7 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
|
||||
|
||||
[self _setupToolTipHandlers];
|
||||
_toolTip = [aCoder decodeObjectForKey:CPViewToolTipKey];
|
||||
|
||||
if (_toolTip)
|
||||
[self _installToolTipEventHandlers];
|
||||
|
||||
@@ -3143,5 +3261,3 @@ var _CPViewGetTransform = function(/*CPView*/ fromView, /*CPView */ toView)
|
||||
|
||||
return transform;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1032,6 +1032,11 @@ CPWebViewAppKitScrollMaxPollCount = 3;
|
||||
var documentURL = [CPURL URLWithString:window.location.href];
|
||||
if ([documentURL isFileURL] && CPFeatureIsCompatible(CPSOPDisabledFromFileURLs))
|
||||
return YES;
|
||||
|
||||
// Relative URLs always pass the SOP.
|
||||
if (![self scheme] && ![self host] && ![self port])
|
||||
return YES;
|
||||
|
||||
return ([documentURL scheme] == [self scheme] && [documentURL host] == [self host] && [documentURL port] == [self port]);
|
||||
}
|
||||
|
||||
|
||||
@@ -287,6 +287,9 @@ var CPWindowActionMessageKeys = [
|
||||
unsigned _shadowStyle;
|
||||
BOOL _showsResizeIndicator;
|
||||
|
||||
int _positioningMask;
|
||||
CGRect _positioningScreenRect;
|
||||
|
||||
BOOL _isDocumentEdited;
|
||||
BOOL _isDocumentSaving;
|
||||
|
||||
@@ -535,6 +538,49 @@ CPTexturedBackgroundWindowMask
|
||||
// set up a default key view loop.
|
||||
if (_keyViewLoopIsDirty && ![self autorecalculatesKeyViewLoop])
|
||||
[self recalculateKeyViewLoop];
|
||||
|
||||
// At this time we know the final screen (or browser) size and can apply the positioning mask, if any, from the nib.
|
||||
if (_positioningScreenRect)
|
||||
{
|
||||
var actualScreenRect = [CPPlatform isBrowser] ? [_platformWindow contentBounds] : [[self screen] visibleFrame],
|
||||
frame = [self frame],
|
||||
origin = frame.origin;
|
||||
|
||||
if (actualScreenRect)
|
||||
{
|
||||
if ((_positioningMask & CPWindowPositionFlexibleLeft) && (_positioningMask & CPWindowPositionFlexibleRight))
|
||||
{
|
||||
// Proportional Horizontal.
|
||||
origin.x *= (actualScreenRect.size.width / _positioningScreenRect.size.width);
|
||||
}
|
||||
else if (_positioningMask & CPWindowPositionFlexibleLeft)
|
||||
{
|
||||
// Fixed from Right
|
||||
origin.x += actualScreenRect.size.width - _positioningScreenRect.size.width;
|
||||
}
|
||||
else if (_positioningMask & CPWindowPositionFlexibleRight)
|
||||
{
|
||||
// Fixed from Left
|
||||
}
|
||||
|
||||
if ((_positioningMask & CPWindowPositionFlexibleTop) && (_positioningMask & CPWindowPositionFlexibleBottom))
|
||||
{
|
||||
// Proportional Vertical.
|
||||
origin.y *= (actualScreenRect.size.height / _positioningScreenRect.size.height);
|
||||
}
|
||||
else if (_positioningMask & CPWindowPositionFlexibleTop)
|
||||
{
|
||||
// Fixed from Bottom
|
||||
origin.y += actualScreenRect.size.height - _positioningScreenRect.size.height;
|
||||
}
|
||||
else if (_positioningMask & CPWindowPositionFlexibleBottom)
|
||||
{
|
||||
// Fixed from Top
|
||||
}
|
||||
|
||||
[self setFrameOrigin:origin];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_setWindowView:(CPView)aWindowView
|
||||
|
||||
@@ -4,29 +4,20 @@
|
||||
@import "CGGeometry.j"
|
||||
@import "CPWindow.j"
|
||||
|
||||
CPWindowPositionFlexibleRight = 1 << 19;
|
||||
CPWindowPositionFlexibleLeft = 1 << 20;
|
||||
CPWindowPositionFlexibleBottom = 1 << 21;
|
||||
CPWindowPositionFlexibleTop = 1 << 22;
|
||||
|
||||
var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinSizeKey",
|
||||
_CPCibWindowTemplateMaxSizeKey = @"_CPCibWindowTemplateMaxSizeKey",
|
||||
|
||||
_CPCibWindowTemplateViewClassKey = @"_CPCibWindowTemplateViewClassKey",
|
||||
_CPCibWindowTemplateWindowClassKey = @"_CPCibWindowTemplateWindowClassKey",
|
||||
|
||||
_CPCibWindowTemplateWindowRectKey = @"_CPCibWindowTemplateWindowRectKey",
|
||||
_CPCibWindowTemplateWindowStyleMaskKey = @"_CPCibWindowTempatStyleMaskKey",
|
||||
_CPCibWindowTemplateWindowTitleKey = @"_CPCibWindowTemplateWindowTitleKey",
|
||||
_CPCibWindowTemplateWindowViewKey = @"_CPCibWindowTemplateWindowViewKey",
|
||||
|
||||
_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop = @"_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop",
|
||||
_CPCibWindowTemplateWindowIsFullPlatformWindowKey = @"_CPCibWindowTemplateWindowIsFullPlatformWindowKey";
|
||||
|
||||
@implementation _CPCibWindowTemplate : CPObject
|
||||
{
|
||||
CGSize _minSize;
|
||||
CGSize _maxSize;
|
||||
//CGSize _screenRect;
|
||||
CGRect _screenRect;
|
||||
|
||||
id _viewClass;
|
||||
//unsigned _wtFlags;
|
||||
unsigned _wtFlags;
|
||||
CPString _windowClass;
|
||||
CGRect _windowRect;
|
||||
unsigned _windowStyleMask;
|
||||
@@ -52,67 +43,18 @@ var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemp
|
||||
_windowView = [[CPView alloc] initWithFrame:CGRectMake(0.0, 0.0, 400.0, 200.0)];
|
||||
|
||||
_windowIsFullPlatformWindow = NO;
|
||||
|
||||
_wtFlags = CPPositionProportionalHorizontal | CPPositionProportionalVertical;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
if (self)
|
||||
{
|
||||
if ([aCoder containsValueForKey:_CPCibWindowTemplateMinSizeKey])
|
||||
_minSize = [aCoder decodeSizeForKey:_CPCibWindowTemplateMinSizeKey];
|
||||
if ([aCoder containsValueForKey:_CPCibWindowTemplateMaxSizeKey])
|
||||
_maxSize = [aCoder decodeSizeForKey:_CPCibWindowTemplateMaxSizeKey];
|
||||
|
||||
_viewClass = [aCoder decodeObjectForKey:_CPCibWindowTemplateViewClassKey];
|
||||
|
||||
_windowClass = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowClassKey];
|
||||
_windowRect = [aCoder decodeRectForKey:_CPCibWindowTemplateWindowRectKey];
|
||||
_windowStyleMask = [aCoder decodeIntForKey:_CPCibWindowTemplateWindowStyleMaskKey];
|
||||
|
||||
_windowTitle = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowTitleKey];
|
||||
_windowView = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowViewKey];
|
||||
|
||||
_windowAutorecalculatesKeyViewLoop = [aCoder decodeBoolForKey:_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop];
|
||||
_windowIsFullPlatformWindow = [aCoder decodeBoolForKey:_CPCibWindowTemplateWindowIsFullPlatformWindowKey];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
if (_minSize)
|
||||
[aCoder encodeSize:_minSize forKey:_CPCibWindowTemplateMinSizeKey];
|
||||
if (_maxSize)
|
||||
[aCoder encodeSize:_maxSize forKey:_CPCibWindowTemplateMaxSizeKey];
|
||||
|
||||
[aCoder encodeObject:_viewClass forKey:_CPCibWindowTemplateViewClassKey];
|
||||
|
||||
[aCoder encodeObject:_windowClass forKey:_CPCibWindowTemplateWindowClassKey];
|
||||
[aCoder encodeRect:_windowRect forKey:_CPCibWindowTemplateWindowRectKey];
|
||||
[aCoder encodeInt:_windowStyleMask forKey:_CPCibWindowTemplateWindowStyleMaskKey];
|
||||
|
||||
[aCoder encodeObject:_windowTitle forKey:_CPCibWindowTemplateWindowTitleKey];
|
||||
[aCoder encodeObject:_windowView forKey:_CPCibWindowTemplateWindowViewKey];
|
||||
|
||||
if (_windowAutorecalculatesKeyViewLoop)
|
||||
[aCoder encodeObject:_windowAutorecalculatesKeyViewLoop forKey:_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop];
|
||||
|
||||
if (_windowIsFullPlatformWindow)
|
||||
[aCoder encodeObject:_windowIsFullPlatformWindow forKey:_CPCibWindowTemplateWindowIsFullPlatformWindowKey];
|
||||
}
|
||||
|
||||
- (CPString)customClassName
|
||||
{
|
||||
return _windowClass;
|
||||
}
|
||||
|
||||
|
||||
- (void)setCustomClassName:(CPString)aClassName
|
||||
{
|
||||
_windowClass = aClassName;
|
||||
@@ -155,7 +97,85 @@ var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemp
|
||||
[theWindow setAutorecalculatesKeyViewLoop:_windowAutorecalculatesKeyViewLoop];
|
||||
[theWindow setFullBridge:_windowIsFullPlatformWindow];
|
||||
|
||||
theWindow._positioningMask = _wtFlags;
|
||||
theWindow._positioningScreenRect = _screenRect;
|
||||
|
||||
return theWindow;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinSizeKey",
|
||||
_CPCibWindowTemplateMaxSizeKey = @"_CPCibWindowTemplateMaxSizeKey",
|
||||
|
||||
_CPCibWindowTemplateViewClassKey = @"_CPCibWindowTemplateViewClassKey",
|
||||
_CPCibWindowTemplateWTFlagsKey = @"_CPCibWindowTemplateWTFlagsKey",
|
||||
_CPCibWindowTemplateWindowClassKey = @"_CPCibWindowTemplateWindowClassKey",
|
||||
|
||||
_CPCibWindowTemplateWindowRectKey = @"_CPCibWindowTemplateWindowRectKey",
|
||||
_CPCibWindowTemplateScreenRectKey = @"_CPCibWindowTemplateScreenRectKey",
|
||||
_CPCibWindowTemplateWindowStyleMaskKey = @"_CPCibWindowTempatStyleMaskKey",
|
||||
_CPCibWindowTemplateWindowTitleKey = @"_CPCibWindowTemplateWindowTitleKey",
|
||||
_CPCibWindowTemplateWindowViewKey = @"_CPCibWindowTemplateWindowViewKey",
|
||||
|
||||
_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop = @"_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop",
|
||||
_CPCibWindowTemplateWindowIsFullPlatformWindowKey = @"_CPCibWindowTemplateWindowIsFullPlatformWindowKey";
|
||||
|
||||
@implementation _CPCibWindowTemplate (Coding)
|
||||
|
||||
- (id)initWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
if (self)
|
||||
{
|
||||
if ([aCoder containsValueForKey:_CPCibWindowTemplateMinSizeKey])
|
||||
_minSize = [aCoder decodeSizeForKey:_CPCibWindowTemplateMinSizeKey];
|
||||
if ([aCoder containsValueForKey:_CPCibWindowTemplateMaxSizeKey])
|
||||
_maxSize = [aCoder decodeSizeForKey:_CPCibWindowTemplateMaxSizeKey];
|
||||
|
||||
_viewClass = [aCoder decodeObjectForKey:_CPCibWindowTemplateViewClassKey];
|
||||
|
||||
_windowClass = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowClassKey];
|
||||
_wtFlags = [aCoder decodeIntForKey:_CPCibWindowTemplateWTFlagsKey];
|
||||
_windowRect = [aCoder decodeRectForKey:_CPCibWindowTemplateWindowRectKey];
|
||||
_screenRect = [aCoder decodeRectForKey:_CPCibWindowTemplateScreenRectKey];
|
||||
_windowStyleMask = [aCoder decodeIntForKey:_CPCibWindowTemplateWindowStyleMaskKey];
|
||||
|
||||
_windowTitle = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowTitleKey];
|
||||
_windowView = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowViewKey];
|
||||
|
||||
_windowAutorecalculatesKeyViewLoop = [aCoder decodeBoolForKey:_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop];
|
||||
_windowIsFullPlatformWindow = [aCoder decodeBoolForKey:_CPCibWindowTemplateWindowIsFullPlatformWindowKey];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
if (_minSize)
|
||||
[aCoder encodeSize:_minSize forKey:_CPCibWindowTemplateMinSizeKey];
|
||||
if (_maxSize)
|
||||
[aCoder encodeSize:_maxSize forKey:_CPCibWindowTemplateMaxSizeKey];
|
||||
|
||||
[aCoder encodeObject:_viewClass forKey:_CPCibWindowTemplateViewClassKey];
|
||||
|
||||
[aCoder encodeObject:_windowClass forKey:_CPCibWindowTemplateWindowClassKey];
|
||||
[aCoder encodeInt:_wtFlags forKey:_CPCibWindowTemplateWTFlagsKey];
|
||||
[aCoder encodeRect:_windowRect forKey:_CPCibWindowTemplateWindowRectKey];
|
||||
[aCoder encodeRect:_screenRect forKey:_CPCibWindowTemplateScreenRectKey];
|
||||
[aCoder encodeInt:_windowStyleMask forKey:_CPCibWindowTemplateWindowStyleMaskKey];
|
||||
|
||||
[aCoder encodeObject:_windowTitle forKey:_CPCibWindowTemplateWindowTitleKey];
|
||||
[aCoder encodeObject:_windowView forKey:_CPCibWindowTemplateWindowViewKey];
|
||||
|
||||
if (_windowAutorecalculatesKeyViewLoop)
|
||||
[aCoder encodeObject:_windowAutorecalculatesKeyViewLoop forKey:_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop];
|
||||
|
||||
if (_windowIsFullPlatformWindow)
|
||||
[aCoder encodeObject:_windowIsFullPlatformWindow forKey:_CPCibWindowTemplateWindowIsFullPlatformWindowKey];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -321,6 +321,16 @@ function CGContextClosePath(aContext)
|
||||
CGPathCloseSubpath(aContext.path);
|
||||
}
|
||||
|
||||
/*!
|
||||
Return YES if the current path in the given context is empty.
|
||||
@param aContext the CGContext to examine
|
||||
@return BOOL
|
||||
*/
|
||||
function CGContextIsPathEmpty(aContext)
|
||||
{
|
||||
return (!aContext.path || CGPathIsEmpty(aContext.path));
|
||||
}
|
||||
|
||||
/*!
|
||||
Moves the current location of aContext to the given x and y coordinates
|
||||
@param aContext the CGContext to move
|
||||
|
||||
@@ -129,7 +129,7 @@ function CGContextAddPath(aContext, aPath)
|
||||
break;
|
||||
case kCGPathElementAddArc: _CGContextAddArcCanvas(aContext, element.x, element.y, element.radius, element.startAngle, element.endAngle, element.clockwise);
|
||||
break;
|
||||
case kCGPathElementAddArcTo: //_CGContextAddArcToPointCanvas(aContext, element.cp1x, element.cp1.y, element.cp2.x, element.cp2y, element.radius);
|
||||
case kCGPathElementAddArcToPoint: _CGContextAddArcToPointCanvas(aContext, element.p1x, element.p1y, element.p2x, element.p2y, element.radius);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,7 +215,7 @@ function CGContextDrawPath(aContext, aMode)
|
||||
COORD(start.x), ',', COORD(start.y), " ",
|
||||
COORD(end.x), ',', COORD(end.y));
|
||||
break;
|
||||
case kCGPathElementAddArcTo: break;
|
||||
case kCGPathElementAddArcToPoint: break;
|
||||
}
|
||||
|
||||
// TODO: Following is broken for curves due to
|
||||
@@ -332,4 +332,4 @@ function CGContextDrawLinearGradient(aContext, aGradient, aStartPoint, anEndPoin
|
||||
// aContext.buffer += vml.join("");
|
||||
// else
|
||||
// aContext.DOMElement.innerHTML = vml.join("");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,6 +118,17 @@ function CGPathAddArc(aPath, aTransform, x, y, aRadius, aStartAngle, anEndAngle,
|
||||
|
||||
function CGPathAddArcToPoint(aPath, aTransform, x1, y1, x2, y2, aRadius)
|
||||
{
|
||||
var p1 = _CGPointMake(x1, y1),
|
||||
p2 = _CGPointMake(x2, y2);
|
||||
|
||||
if (aTransform)
|
||||
{
|
||||
p1 = _CGPointApplyAffineTransform(p1, aTransform);
|
||||
p2 = _CGPointApplyAffineTransform(p2, aTransform);
|
||||
}
|
||||
|
||||
aPath.current = p2;
|
||||
aPath.elements[aPath.count++] = { type:kCGPathElementAddArcToPoint, p1x:p1.x, p1y:p1.y, p2x:p2.x, p2y:p2.y, radius:aRadius };
|
||||
}
|
||||
|
||||
function CGPathAddCurveToPoint(aPath, aTransform, cp1x, cp1y, cp2x, cp2y, x, y)
|
||||
@@ -186,6 +197,12 @@ function CGPathAddPath(aPath, aTransform, anotherPath)
|
||||
element.endAngle, element.isClockwise);
|
||||
break;
|
||||
|
||||
case kCGPathElementAddArcToPoint: CGPathAddArcToPoint(aPath, aTransform,
|
||||
element.p1x, element.p1y,
|
||||
element.p2x, element.p2y,
|
||||
element.radius);
|
||||
break;
|
||||
|
||||
case kCGPathElementAddQuadCurveToPoint: CGPathAddQuadCurveToPoint(aPath, aTransform,
|
||||
element.cpx, element.cpy,
|
||||
element.x, element.y);
|
||||
@@ -389,6 +406,108 @@ function CGPathIsEmpty(aPath)
|
||||
return !aPath || aPath.count == 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
Calculate the smallest rectangle to contain both the path of the receiver and all control points.
|
||||
*/
|
||||
function CGPathGetBoundingBox(aPath)
|
||||
{
|
||||
if (!aPath || !aPath.count)
|
||||
return _CGRectMakeZero();
|
||||
|
||||
var ox = 0,
|
||||
oy = 0,
|
||||
rx = 0,
|
||||
ry = 0,
|
||||
movePoint = nil;
|
||||
|
||||
function addPoint(x, y)
|
||||
{
|
||||
ox = MIN(ox, x);
|
||||
oy = MIN(oy, y);
|
||||
rx = MAX(rx, x);
|
||||
ry = MAX(ry, y);
|
||||
}
|
||||
|
||||
for (var i = 0, count = aPath.count; i < count; ++i)
|
||||
{
|
||||
var element = aPath.elements[i];
|
||||
|
||||
// Just enclose all the control points. The curves must be inside of the control points.
|
||||
// This won't work for CGPathGetPathBoundingBox.
|
||||
switch (element.type)
|
||||
{
|
||||
case kCGPathElementAddLineToPoint:
|
||||
if (movePoint)
|
||||
{
|
||||
addPoint(movePoint.x, movePoint.y);
|
||||
movePoint = nil;
|
||||
}
|
||||
|
||||
addPoint(element.x, element.y);
|
||||
break;
|
||||
|
||||
case kCGPathElementAddCurveToPoint:
|
||||
if (movePoint)
|
||||
{
|
||||
addPoint(movePoint.x, movePoint.y);
|
||||
movePoint = nil;
|
||||
}
|
||||
|
||||
addPoint(element.cp1x, element.cp1y);
|
||||
addPoint(element.cp2x, element.cp2y);
|
||||
addPoint(element.x, element.y);
|
||||
break;
|
||||
|
||||
case kCGPathElementAddArc:
|
||||
if (movePoint)
|
||||
{
|
||||
addPoint(movePoint.x, movePoint.y);
|
||||
movePoint = nil;
|
||||
}
|
||||
|
||||
addPoint(element.x, element.y);
|
||||
break;
|
||||
|
||||
case kCGPathElementAddArcToPoint:
|
||||
if (movePoint)
|
||||
{
|
||||
addPoint(movePoint.x, movePoint.y);
|
||||
movePoint = nil;
|
||||
}
|
||||
|
||||
addPoint(element.p1x, element.p1y);
|
||||
addPoint(element.p2x, element.p2y);
|
||||
break;
|
||||
|
||||
case kCGPathElementAddQuadCurveToPoint:
|
||||
if (movePoint)
|
||||
{
|
||||
addPoint(movePoint.x, movePoint.y);
|
||||
movePoint = nil;
|
||||
}
|
||||
|
||||
addPoint(element.cpx, element.cpy);
|
||||
addPoint(element.x, element.y);
|
||||
break;
|
||||
|
||||
case kCGPathElementMoveToPoint:
|
||||
movePoint = _CGPointMake(element.x, element.y);
|
||||
break;
|
||||
|
||||
case kCGPathElementCloseSubpath:
|
||||
if (movePoint)
|
||||
{
|
||||
addPoint(movePoint.x, movePoint.y);
|
||||
movePoint = nil;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return _CGRectMake(ox, oy, rx - ox, ry - oy);
|
||||
}
|
||||
|
||||
/*!
|
||||
@}
|
||||
*/
|
||||
|
||||
@@ -113,14 +113,12 @@
|
||||
@import "CPEvent.j"
|
||||
@import "CPText.j"
|
||||
@import "CPCompatibility.j"
|
||||
|
||||
@import "CPDOMWindowLayer.j"
|
||||
|
||||
@import "CPPlatform.j"
|
||||
@import "CPPlatformWindow.j"
|
||||
@import "CPPlatformWindow+DOMKeys.j"
|
||||
|
||||
|
||||
// List of all open native windows
|
||||
var PlatformWindows = [CPSet set];
|
||||
|
||||
@@ -1242,6 +1240,10 @@ var resizeTimer = nil;
|
||||
|
||||
else if (type === "mousedown")
|
||||
{
|
||||
// If we receive a click event, then we invalidate any scheduled
|
||||
// or visible tooltips
|
||||
[_CPToolTip invalidateCurrentToolTipIfNeeded];
|
||||
|
||||
var button = aDOMEvent.button;
|
||||
_mouseDownIsRightClick = button == 2 || (CPBrowserIsOperatingSystem(CPMacOperatingSystem) && button == 0 && modifierFlags & CPControlKeyMask);
|
||||
|
||||
@@ -1601,7 +1603,7 @@ var _CPEventFromNativeMouseEvent = function(aNativeEvent, anEventType, aPoint, m
|
||||
};
|
||||
|
||||
var CLICK_SPACE_DELTA = 5.0,
|
||||
CLICK_TIME_DELTA = (typeof document != "undefined" && document.addEventListener) ? 350.0 : 1000.0;
|
||||
CLICK_TIME_DELTA = (typeof document != "undefined" && document.addEventListener) ? 0.55 : 1.0;
|
||||
|
||||
var CPDOMEventGetClickCount = function(aComparisonEvent, aTimestamp, aLocation)
|
||||
{
|
||||
|
||||
|
Before Width: | Height: | Size: 170 B After Width: | Height: | Size: 229 B |
|
Before Width: | Height: | Size: 138 B After Width: | Height: | Size: 174 B |
|
Before Width: | Height: | Size: 135 B After Width: | Height: | Size: 169 B |
|
Before Width: | Height: | Size: 178 B After Width: | Height: | Size: 235 B |
|
Before Width: | Height: | Size: 138 B After Width: | Height: | Size: 169 B |
|
Before Width: | Height: | Size: 145 B After Width: | Height: | Size: 170 B |
|
Before Width: | Height: | Size: 183 B After Width: | Height: | Size: 252 B |
|
Before Width: | Height: | Size: 108 B After Width: | Height: | Size: 167 B |
|
Before Width: | Height: | Size: 109 B After Width: | Height: | Size: 169 B |
|
Before Width: | Height: | Size: 192 B After Width: | Height: | Size: 247 B |
|
Before Width: | Height: | Size: 114 B After Width: | Height: | Size: 174 B |
|
Before Width: | Height: | Size: 112 B After Width: | Height: | Size: 172 B |
|
Before Width: | Height: | Size: 190 B After Width: | Height: | Size: 244 B |
|
Before Width: | Height: | Size: 118 B After Width: | Height: | Size: 181 B |
|
Before Width: | Height: | Size: 120 B After Width: | Height: | Size: 184 B |
|
Before Width: | Height: | Size: 190 B After Width: | Height: | Size: 247 B |
|
Before Width: | Height: | Size: 115 B After Width: | Height: | Size: 180 B |
|
Before Width: | Height: | Size: 116 B After Width: | Height: | Size: 180 B |
@@ -1678,6 +1678,7 @@ var themedButtonValues = nil,
|
||||
[@"text-shadow-color", [CPColor whiteColor]],
|
||||
[@"text-shadow-offset", CGSizeMake(0.0, 1.0)],
|
||||
[@"text-alignment", CPLeftTextAlignment],
|
||||
[@"line-break-mode", CPLineBreakByTruncatingTail],
|
||||
|
||||
[@"background-color", pressed, CPThemeStateHighlighted],
|
||||
[@"background-color", highlighted, CPThemeStateSelected],
|
||||
|
||||
@@ -27,7 +27,10 @@
|
||||
_CPToolTipWindowMask = 1 << 27;
|
||||
|
||||
var _CPToolTipHeight = 24.0,
|
||||
_CPToolTipFontSize = 11.0;
|
||||
_CPToolTipFontSize = 11.0,
|
||||
_CPToolTipDelay = 1.0,
|
||||
_CPToolTipCurrentToolTip,
|
||||
_CPToolTipCurrentToolTipTimer;
|
||||
|
||||
/*! @ingroup appkit
|
||||
This is a basic tooltip that behaves mostly like Cocoa ones.
|
||||
@@ -41,6 +44,46 @@ var _CPToolTipHeight = 24.0,
|
||||
#pragma mark -
|
||||
#pragma mark Class Methods
|
||||
|
||||
/*! @ignore
|
||||
Invalidate any scheduled tooltips, or hide any visible one
|
||||
*/
|
||||
+ (void)invalidateCurrentToolTipIfNeeded
|
||||
{
|
||||
if (_CPToolTipCurrentToolTipTimer)
|
||||
{
|
||||
[_CPToolTipCurrentToolTipTimer invalidate];
|
||||
_CPToolTipCurrentToolTipTimer = nil;
|
||||
}
|
||||
|
||||
if (_CPToolTipCurrentToolTip)
|
||||
{
|
||||
[_CPToolTipCurrentToolTip close];
|
||||
_CPToolTipCurrentToolTip = nil;
|
||||
}
|
||||
}
|
||||
|
||||
/*! @ignore
|
||||
Schedule a tooltip for the given view
|
||||
@param aView the view that might display the tooltip
|
||||
*/
|
||||
+ (void)scheduleToolTipForView:(CPView)aView
|
||||
{
|
||||
if (![aView toolTip] || ![[aView toolTip] length])
|
||||
return;
|
||||
|
||||
[_CPToolTip invalidateCurrentToolTipIfNeeded];
|
||||
|
||||
var callbackFunction = function() {
|
||||
[_CPToolTip invalidateCurrentToolTipIfNeeded];
|
||||
_CPToolTipCurrentToolTip = [_CPToolTip toolTipWithString:[aView toolTip]];
|
||||
};
|
||||
|
||||
_CPToolTipCurrentToolTipTimer = [CPTimer scheduledTimerWithTimeInterval:_CPToolTipDelay
|
||||
callback:callbackFunction
|
||||
repeats:NO];
|
||||
}
|
||||
|
||||
|
||||
/*! Returns an initialized _CPToolTip with the given text and attach it to given view.
|
||||
@param aString the content of the tooltip
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,480 @@
|
||||
Contributing
|
||||
------------
|
||||
|
||||
As an open source project, your contributions are important to the future of Cappuccino. Whether you're looking to write code, add new documentation, or just report a bug, you'll be helping everyone who uses Cappuccino in the future.
|
||||
|
||||
## Reporting Bugs
|
||||
|
||||
We use [GitHub to track issues](https://github.com/cappuccino/cappuccino/issues). You might be interested in our [issue life cycle](http://www.cappuccino-project.org/community/contribute/the-issue-lifecycle/) which explains the process of how an issue is taken from new to resolved.
|
||||
|
||||
## Patches
|
||||
|
||||
To contribute a patch or a fix, fork Cappuccino and then clone your fork and make the changes to a branch of your fork:
|
||||
|
||||
git clone https://github.com/<your username>/cappuccino.git
|
||||
git checkout -b descriptive-branch-name master
|
||||
|
||||
# Check that the unit tests work.
|
||||
jake test
|
||||
|
||||
# Make changes. Make sure you follow the coding style guidelines and write unit tests.
|
||||
|
||||
# Check that everything is still working, then commit.
|
||||
jake test
|
||||
git commit
|
||||
|
||||
git push origin descriptive-branch-name
|
||||
|
||||
Now you can go to GitHub and [make a pull request](https://help.github.com/articles/using-pull-requests).
|
||||
|
||||
Some things are difficult to unit test in a way that's worthwhile. For instance a change to the mouse interaction of a `CPButton`. In this case a manual test is fine instead. Find the closest related manual test in `Tests/Manual` and add whatever it takes to easily reproduce the patched behavior, ideally with some labels describing how someone running the manual test should exercise it.
|
||||
|
||||
## Cappuccino Coding Style Guidelines
|
||||
|
||||
### Trailing whitespace
|
||||
Leave no trailing spaces or tabs at the end of a line (`trailing whitespace`), even if the line is empty and in an otherwise indented block.
|
||||
|
||||
### Indentation
|
||||
|
||||
Use spaces, not tabs. Tabs should only appear in files that require them for semantic meaning, like Makefiles (which there are currently none of). The indent size is 4 spaces.
|
||||
|
||||
##### Right:
|
||||
|
||||
function main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
##### Wrong:
|
||||
|
||||
function main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
A case label should be indented once from its switch statement. The case statement is indented out from the longest label.
|
||||
|
||||
##### Right:
|
||||
|
||||
switch (condition)
|
||||
{
|
||||
case fooCondition:
|
||||
case barCondition: i++;
|
||||
break;
|
||||
|
||||
default: i--;
|
||||
}
|
||||
|
||||
##### Wrong:
|
||||
|
||||
switch (condition) {
|
||||
case fooCondition:
|
||||
case barCondition:
|
||||
i++;
|
||||
break;
|
||||
default:
|
||||
i--;
|
||||
}
|
||||
|
||||
### Spacing
|
||||
|
||||
Do not place spaces around unary operators.
|
||||
|
||||
##### Right:
|
||||
|
||||
i++
|
||||
|
||||
##### Wrong:
|
||||
|
||||
i ++
|
||||
|
||||
---
|
||||
|
||||
Do place spaces around binary and ternary operators.
|
||||
|
||||
##### Right:
|
||||
|
||||
y = m * x + b;
|
||||
f(a, b);
|
||||
c = a | b;
|
||||
return condition ? 1 : 0;
|
||||
|
||||
##### Wrong:
|
||||
|
||||
y=m*x+b;
|
||||
f(a,b);
|
||||
c = a|b;
|
||||
return condition ? 1:0;
|
||||
|
||||
---
|
||||
|
||||
Place spaces between control statements and their parentheses.
|
||||
|
||||
##### Right:
|
||||
|
||||
if (condition)
|
||||
doIt();
|
||||
|
||||
##### Wrong:
|
||||
|
||||
if(condition)
|
||||
doIt();
|
||||
|
||||
---
|
||||
|
||||
Do not place spaces between a function and its parentheses, or between a parenthesis and its content.
|
||||
|
||||
##### Right:
|
||||
|
||||
f(a, b);
|
||||
|
||||
##### Wrong:
|
||||
|
||||
f (a, b);
|
||||
f( a, b );
|
||||
|
||||
---
|
||||
|
||||
Do not place spaces between the return type of an Objective-J method and the selector name. DO place spaces between the method type and the method return type.
|
||||
|
||||
##### Right:
|
||||
|
||||
- (void)method;
|
||||
|
||||
##### Wrong:
|
||||
|
||||
- (void) method;
|
||||
-(void)method;
|
||||
|
||||
---
|
||||
|
||||
Do not place spaces between Objective-J selectors and arguments.
|
||||
|
||||
##### Right:
|
||||
|
||||
[myNumber addNumber:5]
|
||||
|
||||
##### Wrong:
|
||||
|
||||
[myNumber addNumber: 5]
|
||||
|
||||
### Line breaking
|
||||
|
||||
Each statement should get its own line.
|
||||
|
||||
##### Right:
|
||||
|
||||
var x,
|
||||
y;
|
||||
x++;
|
||||
y++;
|
||||
if (condition)
|
||||
doIt();
|
||||
|
||||
##### Wrong:
|
||||
|
||||
var x, y;
|
||||
x++; y++;
|
||||
if (condition) doIt();
|
||||
|
||||
### Braces
|
||||
|
||||
Every brace gets its own line, very simple to remember:
|
||||
|
||||
##### Right:
|
||||
|
||||
int main()
|
||||
{
|
||||
//...
|
||||
}
|
||||
|
||||
if (condition)
|
||||
{
|
||||
//...
|
||||
}
|
||||
else if (condition)
|
||||
{
|
||||
//...
|
||||
}
|
||||
|
||||
@implementation MyObject : CPObject
|
||||
{
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
##### Wrong:
|
||||
|
||||
int main() {
|
||||
...
|
||||
}
|
||||
|
||||
if (condition) {
|
||||
...
|
||||
} else if (condition) {
|
||||
...
|
||||
}
|
||||
|
||||
@implementation MyObject : CPObject {}
|
||||
@end
|
||||
|
||||
### Null, false and 0
|
||||
|
||||
In JavaScript, the null object value should be written as null. In Objective-J, it should be written as `nil` when the variable refers to an object, and `Nil` when it refers to a `Class`. Objective-J `BOOL` values should be written as `YES` and `NO`.
|
||||
|
||||
Tests for `true/false`, `null/non-null`, and zero/non-zero should all be done without equality comparisons, except for cases when a value could be both 0 or `null` (or another "falsey" value). In this case, the comparison should be preceded by a comment explaining the distinction.
|
||||
|
||||
##### Right:
|
||||
|
||||
if (condition)
|
||||
doIt();
|
||||
|
||||
if (!ptr)
|
||||
return;
|
||||
|
||||
if (!count)
|
||||
return;
|
||||
|
||||
// object is an ID number, so 0 is OK, but null is not.
|
||||
if (object === null)
|
||||
return;
|
||||
|
||||
##### Wrong:
|
||||
|
||||
if (condition == true)
|
||||
doIt();
|
||||
|
||||
if (ptr == NULL)
|
||||
return;
|
||||
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
if (object == null)
|
||||
return;
|
||||
|
||||
---
|
||||
|
||||
In Objective-J, instance variables are initialized to `nil` automatically. Don't add explicit initializations to `nil` or `NO` in an init method.
|
||||
|
||||
### Names
|
||||
|
||||
Use CamelCase. Capitalize the first letter of a class. Lower-case the first letter of a variable or function name. Fully capitalize acronyms.
|
||||
|
||||
##### Right:
|
||||
|
||||
@implementation Data : //...
|
||||
@implementation HTMLDocument : //...
|
||||
|
||||
##### Wrong:
|
||||
|
||||
@implementation data : //...
|
||||
@implementation HtmlDocument : //...
|
||||
|
||||
---
|
||||
|
||||
Multiple var declarations should be collapsed with commas.
|
||||
|
||||
##### Right:
|
||||
|
||||
var index = 0,
|
||||
count = 5;
|
||||
|
||||
##### Wrong:
|
||||
|
||||
var index = 0;
|
||||
var count = 5;
|
||||
|
||||
---
|
||||
|
||||
Variable declarations should be created as needed, rather than up front ("hoisted").
|
||||
|
||||
##### Right:
|
||||
|
||||
- (BOOL)doSomething:(id)aFoo
|
||||
{
|
||||
var importantVariable = [aFoo message];
|
||||
if (!importantVariable)
|
||||
return;
|
||||
|
||||
var index = [aFoo count];
|
||||
while (index--)
|
||||
{
|
||||
var innerVariable = [aFoo objectAtIndex:index];
|
||||
//do something;
|
||||
}
|
||||
}
|
||||
|
||||
##### Wrong:
|
||||
|
||||
- (BOOL)doSomething:(id)aFoo
|
||||
{
|
||||
var importantVariable = [aFoo message],
|
||||
index = [aFoo count],
|
||||
innerVariable;
|
||||
|
||||
if (!importantVariable)
|
||||
return;
|
||||
|
||||
while (index--)
|
||||
{
|
||||
innerVariable = [aFoo objectAtIndex:index];
|
||||
//do something;
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
Use full words, except in the rare case where an abbreviation would be more canonical and easier to understand.
|
||||
|
||||
##### Right:
|
||||
|
||||
var characterSize,
|
||||
length,
|
||||
tabIndex; // more canonical
|
||||
|
||||
##### Wrong:
|
||||
|
||||
var charSize,
|
||||
len,
|
||||
tabulationIndex; // bizarre
|
||||
|
||||
---
|
||||
|
||||
Prefix Objective-J instance variables with `_`, but only when writing code for the Cappuccino frameworks. User level (application) code should not prefix variables with `_`. This prevents conflicts between the two scopes.
|
||||
|
||||
##### Right:
|
||||
|
||||
@implementation CPString
|
||||
{
|
||||
unsigned _length;
|
||||
}
|
||||
@end
|
||||
|
||||
##### Wrong:
|
||||
|
||||
@implementation CPString
|
||||
{
|
||||
unsigned length;
|
||||
}
|
||||
@end
|
||||
|
||||
---
|
||||
|
||||
Precede boolean values with words like "is" and "did".
|
||||
|
||||
##### Right:
|
||||
|
||||
var isValid;
|
||||
var didSendData;
|
||||
- (BOOL)isEditable;
|
||||
- (BOOL)didReceiveResponse;
|
||||
|
||||
##### Wrong:
|
||||
|
||||
var valid;
|
||||
var sentData;
|
||||
- (BOOL)editable;
|
||||
- (BOOL)receivedResponse;
|
||||
|
||||
---
|
||||
|
||||
Precede setters with the word "set". Use bare words for getters. Setter and getter names should match the names of the variables being set/gotten.
|
||||
|
||||
##### Right:
|
||||
|
||||
- (void)setCount:(unsigned)aCount; // sets _count
|
||||
- (unsigned)count; // returns _count
|
||||
|
||||
##### Wrong:
|
||||
|
||||
- (unsigned)getCount;
|
||||
|
||||
---
|
||||
|
||||
Use descriptive verbs in function names, and place desired types in comments.
|
||||
|
||||
##### Right:
|
||||
|
||||
function convertToASCII(/*String*/ aString)
|
||||
|
||||
##### Wrong:
|
||||
|
||||
function toASCII(str)
|
||||
|
||||
---
|
||||
|
||||
Use descriptive parameter names that are not abbreviated.
|
||||
|
||||
##### Right:
|
||||
|
||||
- (void)convertString:(CPString)aString toFormat:(Format)aFormat;
|
||||
- (void)appendSubviews:(CPArray)subviews inOrder:(BOOL)shouldBeInOrder;
|
||||
|
||||
##### Wrong:
|
||||
|
||||
- (void)convertString:(CPString)str toFormat:(Format)f;
|
||||
- (void)appendSubviews:(CPArray)s inOrder:(BOOL)flag;
|
||||
|
||||
---
|
||||
|
||||
Use descriptive parameter types, despite not being fully supported in JavaScript. At some point we will be adding optional static typing, and even until then this serves as a much better indicator of what the method expects. Of course, if the method can truly take any input or return any output, it is perfectly acceptable to use `id`, `CPObject`, or `var`.
|
||||
|
||||
##### Right:
|
||||
|
||||
- (char)characterAtIndex:(unsigned)anIndex;
|
||||
- (void)insertObject:(id)anObject;
|
||||
|
||||
##### Wrong:
|
||||
|
||||
- (String)characterAtIndex:(var)index;
|
||||
|
||||
---
|
||||
|
||||
Objective-J method names should follow the Cocoa naming guidelines — they should read like a phrase and each piece of the selector should start with a lowercase letter and use intercaps.
|
||||
|
||||
Enum members should user InterCaps with an initial capital letter.
|
||||
|
||||
`#defined` constants should use all uppercase names with words separated by underscores.
|
||||
|
||||
Macros that expand to function calls or other non-constant computation: these should be named like functions, and should have parentheses at the end, even if they take no arguments (with the exception of some special macros like ASSERT).
|
||||
|
||||
##### Right:
|
||||
|
||||
#define StopButtonTitle() \
|
||||
CPLocalizedString(@"Stop", @"Stop button title")
|
||||
|
||||
##### Wrong:
|
||||
|
||||
#define STOP_BUTTON_TITLE \
|
||||
CPLocalizedString(@"Stop", @"Stop button title")
|
||||
|
||||
#define StopButtontitle \
|
||||
CPLocalizedString(@"Stop", @"Stop button title")
|
||||
|
||||
### import Statements
|
||||
|
||||
1. Include external frameworks first.
|
||||
2. Include Foundation classes before AppKit classes.
|
||||
3. Include files in alphabetical order.
|
||||
4. Use local imports whenever possible.
|
||||
|
||||
##### Right:
|
||||
|
||||
// (Within AppKit)
|
||||
import <Foundation/CPObject.j>
|
||||
import <Foundation/CPArray.j>
|
||||
|
||||
import "CPTabViewItem.j"
|
||||
import "CPTabView.j"
|
||||
|
||||
##### Wrong:
|
||||
|
||||
// (Within AppKit)
|
||||
import "CPTabView.j"
|
||||
import <AppKit/CPTabViewItem.j>
|
||||
|
||||
import <Foundation/CPArray.j>
|
||||
import <Foundation/CPObject.j>
|
||||
@@ -176,8 +176,6 @@ var _CPKeyedArchiverStringClass = Nil,
|
||||
|
||||
_replacementObjects = [CPDictionary dictionary];
|
||||
|
||||
_data = data;
|
||||
|
||||
_plistObject = [CPDictionary dictionary];
|
||||
_plistObjects = [CPArray arrayWithObject:_CPKeyedArchiverNullString];
|
||||
}
|
||||
|
||||
@@ -90,6 +90,11 @@ CPNumberFormatterRoundHalfUp = CPRoundPlain;
|
||||
|
||||
- (CPString)stringFromNumber:(CPNumber)number
|
||||
{
|
||||
if (_numberStyle == CPNumberFormatterPercentStyle)
|
||||
{
|
||||
number *= 100.0;
|
||||
}
|
||||
|
||||
var dcmn = [number isKindOfClass:CPDecimalNumber] ? number : [[CPDecimalNumber alloc] _initWithJSNumber:number];
|
||||
|
||||
// TODO Add locale support.
|
||||
@@ -97,6 +102,7 @@ CPNumberFormatterRoundHalfUp = CPRoundPlain;
|
||||
{
|
||||
case CPNumberFormatterCurrencyStyle:
|
||||
case CPNumberFormatterDecimalStyle:
|
||||
case CPNumberFormatterPercentStyle:
|
||||
UPDATE_NUMBER_HANDLER_IF_NECESSARY();
|
||||
|
||||
dcmn = [dcmn decimalNumberByRoundingAccordingToBehavior:_numberHandler];
|
||||
@@ -134,6 +140,11 @@ CPNumberFormatterRoundHalfUp = CPRoundPlain;
|
||||
string = _currencyCode + string;
|
||||
}
|
||||
|
||||
if (_numberStyle == CPNumberFormatterPercentStyle)
|
||||
{
|
||||
string += "%";
|
||||
}
|
||||
|
||||
return string;
|
||||
default:
|
||||
return [number description];
|
||||
|
||||
@@ -161,6 +161,17 @@
|
||||
[self assert:2 equals:[[outlineView selectedRowIndexes] count] message:"selections should remain"];
|
||||
}
|
||||
|
||||
|
||||
- (void)testExpandCollapseItemVisibility
|
||||
{
|
||||
var delegate = [TestExpandCollapseVisibilityDelegate new];
|
||||
[delegate setTester:self];
|
||||
[outlineView setDelegate:delegate];
|
||||
|
||||
[outlineView collapseItem:".1"];
|
||||
[outlineView expandItem:".1"];
|
||||
}
|
||||
|
||||
/*!
|
||||
Test that the outline view archives properly.
|
||||
*/
|
||||
@@ -270,3 +281,50 @@
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation TestExpandCollapseVisibilityDelegate : CPObject
|
||||
{
|
||||
id tester @accessors;
|
||||
}
|
||||
|
||||
- (void)outlineViewItemWillCollapse:(CPNotification)aNotification
|
||||
{
|
||||
var anOutlineView = [aNotification object],
|
||||
visibleRows = [anOutlineView rowsInRect:[anOutlineView visibleRect]];
|
||||
|
||||
[tester assertTrue:[anOutlineView isItemExpanded:".1"]];
|
||||
[tester assert:0 equals:visibleRows.location];
|
||||
[tester assert:8 equals:visibleRows.length];
|
||||
}
|
||||
|
||||
- (void)outlineViewItemDidCollapse:(CPNotification)aNotification
|
||||
{
|
||||
var anOutlineView = [aNotification object],
|
||||
visibleRows = [anOutlineView rowsInRect:[anOutlineView visibleRect]];
|
||||
|
||||
[tester assertFalse:[anOutlineView isItemExpanded:".1"]];
|
||||
[tester assert:0 equals:visibleRows.location];
|
||||
[tester assert:4 equals:visibleRows.length];
|
||||
}
|
||||
|
||||
- (void)outlineViewItemWillExpand:(CPNotification)aNotification
|
||||
{
|
||||
var anOutlineView = [aNotification object],
|
||||
visibleRows = [anOutlineView rowsInRect:[anOutlineView visibleRect]];
|
||||
|
||||
[tester assertFalse:[anOutlineView isItemExpanded:".1"]];
|
||||
[tester assert:0 equals:visibleRows.location];
|
||||
[tester assert:4 equals:visibleRows.length];
|
||||
}
|
||||
|
||||
- (void)outlineViewItemDidExpand:(CPNotification)aNotification
|
||||
{
|
||||
var anOutlineView = [aNotification object],
|
||||
visibleRows = [anOutlineView rowsInRect:[anOutlineView visibleRect]];
|
||||
|
||||
[tester assertTrue:[anOutlineView isItemExpanded:".1"]];
|
||||
[tester assert:0 equals:visibleRows.location];
|
||||
[tester assert:8 equals:visibleRows.length];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -267,6 +267,41 @@
|
||||
[contentBindingTable reloadData];
|
||||
}
|
||||
|
||||
- (void)testInitiallyHiddenColumns
|
||||
{
|
||||
var table = [[CPTableView alloc] initWithFrame:CGRectMake(0, 0, 400, 400)],
|
||||
tableColumn1 = [[CPTableColumn alloc] initWithIdentifier:@"A"],
|
||||
tableColumn2 = [[CPTableColumn alloc] initWithIdentifier:@"B"],
|
||||
delegate = [ContentBindingTableDelegate new];
|
||||
|
||||
[delegate setTester:self];
|
||||
[table setDelegate:delegate];
|
||||
|
||||
[delegate setTableEntries:[[@"A1", @"B1"], [@"A2", @"B2"], [@"A3", @"B3"]]];
|
||||
[table bind:@"content" toObject:delegate withKeyPath:@"tableEntries" options:nil];
|
||||
|
||||
[[theWindow contentView] addSubview:table];
|
||||
|
||||
[tableColumn1 setHidden:YES];
|
||||
|
||||
[tableColumn1 setWidth:50.0];
|
||||
[tableColumn2 setWidth:100.0];
|
||||
|
||||
[table addTableColumn:tableColumn1];
|
||||
[table addTableColumn:tableColumn2];
|
||||
|
||||
[table reloadData];
|
||||
|
||||
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
|
||||
|
||||
[self assertTrue:[table bounds].size.width > 100 && [table bounds].size.width < 200];
|
||||
|
||||
[tableColumn1 setHidden:NO];
|
||||
[tableColumn1 setWidth:100.0];
|
||||
|
||||
[self assertTrue:[table bounds].size.width >= 200];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation FirstResponderConfigurableTableView : CPTableView
|
||||
|
||||
@@ -71,10 +71,10 @@
|
||||
var rawString = "cappuccino",
|
||||
bytes = [99, 97, 112, 112, 117, 99, 99, 105, 110, 111],
|
||||
base64 = "Y2FwcHVjY2lubw==";
|
||||
|
||||
|
||||
var data = [CPData dataWithBase64:base64];
|
||||
[self assert:rawString equals:[data rawString]];
|
||||
|
||||
|
||||
data = [CPData dataWithBase64:base64];
|
||||
[self assert:bytes equals:[data bytes]];
|
||||
|
||||
@@ -84,17 +84,16 @@
|
||||
|
||||
data = [CPData dataWithRawString:rawString];
|
||||
[self assert:rawString equals:[data rawString]];
|
||||
|
||||
|
||||
data = [CPData dataWithRawString:rawString];
|
||||
[self assert:bytes equals:[data bytes]];
|
||||
|
||||
data = [CPData dataWithRawString:rawString];
|
||||
[self assert:base64 equals:[data base64]];
|
||||
|
||||
|
||||
data = [CPData dataWithBytes:bytes];
|
||||
[self assert:rawString equals:[data rawString]];
|
||||
|
||||
|
||||
data = [CPData dataWithBytes:bytes];
|
||||
[self assert:bytes equals:[data bytes]];
|
||||
|
||||
|
||||
@@ -143,6 +143,23 @@
|
||||
[self assert:@"SEK0.02" equals:[numberFormatter stringFromNumber:[CPDecimalNumber decimalNumberWithString:@"0.015"]]];
|
||||
}
|
||||
|
||||
- (void)testPercentStyle
|
||||
{
|
||||
var numberFormatter = [CPNumberFormatter new];
|
||||
[numberFormatter setNumberStyle:CPNumberFormatterPercentStyle];
|
||||
|
||||
[self assert:@"1%" equals:[numberFormatter stringFromNumber:[CPDecimalNumber decimalNumberWithString:@"0.01"]]];
|
||||
[self assert:@"100%" equals:[numberFormatter stringFromNumber:[CPDecimalNumber decimalNumberWithString:@"1.0"]]];
|
||||
[self assert:@"150%" equals:[numberFormatter stringFromNumber:[CPDecimalNumber decimalNumberWithString:@"1.5"]]];
|
||||
|
||||
[numberFormatter setMinimumFractionDigits:1];
|
||||
[numberFormatter setMaximumFractionDigits:1];
|
||||
|
||||
[self assert:@"1.0%" equals:[numberFormatter stringFromNumber:[CPDecimalNumber decimalNumberWithString:@"0.01"]]];
|
||||
[self assert:@"100.2%" equals:[numberFormatter stringFromNumber:[CPDecimalNumber decimalNumberWithString:@"1.002"]]];
|
||||
[self assert:@"150.7%" equals:[numberFormatter stringFromNumber:[CPDecimalNumber decimalNumberWithString:@"1.507"]]];
|
||||
}
|
||||
|
||||
- (void)testSetGeneratesDecimalNumbers_
|
||||
{
|
||||
var numberFormatter = [CPNumberFormatter new];
|
||||
|
||||
@@ -26,11 +26,9 @@ CPLogRegister(CPLogConsole);
|
||||
|
||||
- (void)awakeFromCib
|
||||
{
|
||||
var contentView = [theWindow contentView];
|
||||
var contentView = [theWindow contentView],
|
||||
notWrongItem = [Item new];
|
||||
|
||||
//create our non ui objects
|
||||
|
||||
var notWrongItem = [Item new];
|
||||
[notWrongItem setRightOrWrong:"also right"];
|
||||
itemsArray = [[Item new], notWrongItem];
|
||||
|
||||
@@ -104,8 +102,7 @@ CPLogRegister(CPLogConsole);
|
||||
{
|
||||
// bind array controller to self's itemsArray
|
||||
|
||||
[arrayController bind:@"contentArray" toObject:self
|
||||
withKeyPath:@"itemsArray" options:nil];
|
||||
[arrayController bind:@"contentArray" toObject:self withKeyPath:@"itemsArray" options:nil];
|
||||
|
||||
// bind the total field -- no options on this one
|
||||
[totalCountField bind:CPValueBinding toObject:arrayController
|
||||
@@ -113,13 +110,14 @@ CPLogRegister(CPLogConsole);
|
||||
|
||||
var bindingOptions = [CPDictionary dictionary];
|
||||
//[bindingOptions setObject:@"No Name" forKey:@"NSNullPlaceholder"];
|
||||
[selectedNameField bind: @"value" toObject:arrayController
|
||||
withKeyPath:@"selection.name" options:bindingOptions];
|
||||
[selectedNameField bind:CPValueBinding toObject:arrayController
|
||||
withKeyPath:@"selection.name" options:bindingOptions];
|
||||
|
||||
// binding for "name" column
|
||||
var tableColumn = [tableView tableColumnWithIdentifier:@"name"],
|
||||
bindingOptions = [CPDictionary dictionary];
|
||||
[tableColumn bind:@"value" toObject: arrayController
|
||||
bindingOptions = [CPDictionary dictionary];
|
||||
|
||||
[tableColumn bind:CPValueBinding toObject:arrayController
|
||||
withKeyPath:@"arrangedObjects.name" options:bindingOptions];
|
||||
|
||||
|
||||
@@ -129,13 +127,13 @@ CPLogRegister(CPLogConsole);
|
||||
//[bindingOptions removeObjectForKey:@"NSNullPlaceholder"];
|
||||
//[bindingOptions setObject:YES
|
||||
// forKey:CPValidatesImmediatelyBindingOption];
|
||||
[selectedPriceField bind:@"value" toObject: arrayController
|
||||
[selectedPriceField bind:CPValueBinding toObject: arrayController
|
||||
withKeyPath:@"selection.price" options:bindingOptions];
|
||||
|
||||
// binding for "price" column
|
||||
tableColumn = [tableView tableColumnWithIdentifier:@"price"];
|
||||
bindingOptions = [CPDictionary dictionary];
|
||||
[tableColumn bind:@"value" toObject: arrayController
|
||||
[tableColumn bind:CPValueBinding toObject:arrayController
|
||||
withKeyPath:@"arrangedObjects.price" options:bindingOptions];
|
||||
|
||||
tableColumn = [tableView tableColumnWithIdentifier:@"all right"];
|
||||
@@ -215,4 +213,4 @@ CPLogRegister(CPLogConsole);
|
||||
return aValue == "wrong" ? "right" : aValue;
|
||||
}
|
||||
|
||||
@end
|
||||
@end
|
||||
|
||||
@@ -69,11 +69,6 @@ CPLogRegister(CPLogConsole);
|
||||
[[radio1 radioGroup] setAction:@selector(radioGroupClicked:)];
|
||||
[multiCheckbox setState:CPMixedState];
|
||||
|
||||
[pushInButton setButtonType:CPMomentaryLightButton];
|
||||
[pushOnOffButton setButtonType:CPPushOnPushOffButton];
|
||||
[toggleButton setButtonType:CPToggleButton];
|
||||
[momentaryChangeButton setButtonType:CPMomentaryChangeButton];
|
||||
|
||||
[pushInButton setAlternateTitle:@"Should Not See Me"];
|
||||
[toggleButton setAlternateTitle:@"Alternate Title For Toggle"];
|
||||
[momentaryChangeButton setAlternateTitle:@"Changed!"];
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
var data = [[CPData alloc] initWithRawString:dataString],
|
||||
theRows = [CPPropertyListSerialization propertyListFromData:data format:CPPropertyListXMLFormat_v1_0];
|
||||
|
||||
// Add a CPImage to the model to test CPValueBinding.
|
||||
// Add a CPImage to the model to test CPValueBinding.
|
||||
var path = [[CPBundle mainBundle] pathForResource:@"value.jpg"],
|
||||
image = [[CPImage alloc] initWithContentsOfFile:path],
|
||||
dict = [CPDictionary dictionaryWithObject:image forKey:@"image"];
|
||||
|
||||
@@ -2,39 +2,36 @@
|
||||
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
|
||||
<data>
|
||||
<int key="IBDocument.SystemTarget">1050</int>
|
||||
<string key="IBDocument.SystemVersion">10J3210</string>
|
||||
<string key="IBDocument.InterfaceBuilderVersion">1306</string>
|
||||
<string key="IBDocument.AppKitVersion">1038.35</string>
|
||||
<string key="IBDocument.HIToolboxVersion">461.00</string>
|
||||
<string key="IBDocument.SystemVersion">12C60</string>
|
||||
<string key="IBDocument.InterfaceBuilderVersion">2843</string>
|
||||
<string key="IBDocument.AppKitVersion">1187.34</string>
|
||||
<string key="IBDocument.HIToolboxVersion">625.00</string>
|
||||
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
|
||||
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="NS.object.0">1306</string>
|
||||
<string key="NS.object.0">2843</string>
|
||||
</object>
|
||||
<object class="NSArray" key="IBDocument.IntegratedClassDependencies">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>NSScroller</string>
|
||||
<string>NSTableHeaderView</string>
|
||||
<string>NSScrollView</string>
|
||||
<string>NSTextFieldCell</string>
|
||||
<string>NSButtonCell</string>
|
||||
<string>NSImageCell</string>
|
||||
<string>NSTableView</string>
|
||||
<string>NSCustomObject</string>
|
||||
<string>NSImageCell</string>
|
||||
<string>NSLevelIndicatorCell</string>
|
||||
<string>NSScrollView</string>
|
||||
<string>NSScroller</string>
|
||||
<string>NSTableColumn</string>
|
||||
<string>NSTableHeaderView</string>
|
||||
<string>NSTableView</string>
|
||||
<string>NSTextFieldCell</string>
|
||||
<string>NSView</string>
|
||||
<string>NSWindowTemplate</string>
|
||||
<string>NSLevelIndicatorCell</string>
|
||||
<string>NSTableColumn</string>
|
||||
</object>
|
||||
<object class="NSArray" key="IBDocument.PluginDependencies">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
</object>
|
||||
<object class="NSMutableDictionary" key="IBDocument.Metadata">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSArray" key="dict.sortedKeys" id="0">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
</object>
|
||||
<reference key="dict.values" ref="0"/>
|
||||
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
|
||||
<integer value="1" key="NS.object.0"/>
|
||||
</object>
|
||||
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1048">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
@@ -55,6 +52,7 @@
|
||||
<string key="NSWindowTitle">Window</string>
|
||||
<string key="NSWindowClass">NSWindow</string>
|
||||
<nil key="NSViewClass"/>
|
||||
<nil key="NSUserInterfaceItemIdentifier"/>
|
||||
<object class="NSView" key="NSWindowView" id="439893737">
|
||||
<reference key="NSNextResponder"/>
|
||||
<int key="NSvFlags">256</int>
|
||||
@@ -78,21 +76,21 @@
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView" ref="347610108"/>
|
||||
<bool key="NSEnabled">YES</bool>
|
||||
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
|
||||
<bool key="NSControlAllowsExpansionToolTips">YES</bool>
|
||||
<object class="NSTableHeaderView" key="NSHeaderView" id="393525317">
|
||||
<reference key="NSNextResponder" ref="471528550"/>
|
||||
<int key="NSvFlags">256</int>
|
||||
<string key="NSFrameSize">{644, 17}</string>
|
||||
<reference key="NSSuperview" ref="471528550"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView" ref="167646100"/>
|
||||
<reference key="NSNextKeyView" ref="331394667"/>
|
||||
<reference key="NSTableView" ref="86489736"/>
|
||||
</object>
|
||||
<object class="_NSCornerView" key="NSCornerView" id="167646100">
|
||||
<reference key="NSNextResponder" ref="1048514227"/>
|
||||
<object class="_NSCornerView" key="NSCornerView">
|
||||
<nil key="NSNextResponder"/>
|
||||
<int key="NSvFlags">-2147483392</int>
|
||||
<string key="NSFrame">{{502, 0}, {16, 17}}</string>
|
||||
<reference key="NSSuperview" ref="1048514227"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView" ref="331394667"/>
|
||||
</object>
|
||||
<object class="NSMutableArray" key="NSTableColumns">
|
||||
@@ -103,13 +101,13 @@
|
||||
<double key="NSMinWidth">10</double>
|
||||
<double key="NSMaxWidth">3.0282346638528862e+53</double>
|
||||
<object class="NSTableHeaderCell" key="NSHeaderCell">
|
||||
<int key="NSCellFlags">75628096</int>
|
||||
<int key="NSCellFlags2">2048</int>
|
||||
<string key="NSContents">ImageView</string>
|
||||
<object class="NSFont" key="NSSupport" id="26">
|
||||
<string key="NSName">LucidaGrande</string>
|
||||
<int key="NSCellFlags">75497536</int>
|
||||
<int key="NSCellFlags2">134219776</int>
|
||||
<string key="NSContents">Image</string>
|
||||
<object class="NSFont" key="NSSupport">
|
||||
<string key="NSName">Georgia</string>
|
||||
<double key="NSSize">11</double>
|
||||
<int key="NSfFlags">3100</int>
|
||||
<int key="NSfFlags">16</int>
|
||||
</object>
|
||||
<object class="NSColor" key="NSBackgroundColor" id="676350359">
|
||||
<int key="NSColorSpace">6</int>
|
||||
@@ -131,13 +129,8 @@
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSImageCell" key="NSDataCell" id="1016771331">
|
||||
<int key="NSCellFlags">67239424</int>
|
||||
<int key="NSCellFlags">134217728</int>
|
||||
<int key="NSCellFlags2">33554432</int>
|
||||
<object class="NSFont" key="NSSupport" id="390959245">
|
||||
<string key="NSName">LucidaGrande</string>
|
||||
<double key="NSSize">13</double>
|
||||
<int key="NSfFlags">1044</int>
|
||||
</object>
|
||||
<int key="NSAlign">0</int>
|
||||
<int key="NSScale">0</int>
|
||||
<int key="NSStyle">0</int>
|
||||
@@ -154,10 +147,14 @@
|
||||
<double key="NSMinWidth">40</double>
|
||||
<double key="NSMaxWidth">1000</double>
|
||||
<object class="NSTableHeaderCell" key="NSHeaderCell">
|
||||
<int key="NSCellFlags">75628096</int>
|
||||
<int key="NSCellFlags">75497536</int>
|
||||
<int key="NSCellFlags2">2048</int>
|
||||
<string key="NSContents">Column 1</string>
|
||||
<reference key="NSSupport" ref="26"/>
|
||||
<object class="NSFont" key="NSSupport" id="26">
|
||||
<string key="NSName">LucidaGrande</string>
|
||||
<double key="NSSize">11</double>
|
||||
<int key="NSfFlags">3100</int>
|
||||
</object>
|
||||
<object class="NSColor" key="NSBackgroundColor" id="1073356944">
|
||||
<int key="NSColorSpace">3</int>
|
||||
<bytes key="NSWhite">MC4zMzMzMzI5ODU2AA</bytes>
|
||||
@@ -165,10 +162,14 @@
|
||||
<reference key="NSTextColor" ref="678139720"/>
|
||||
</object>
|
||||
<object class="NSTextFieldCell" key="NSDataCell" id="279840144">
|
||||
<int key="NSCellFlags">337772096</int>
|
||||
<int key="NSCellFlags">337641536</int>
|
||||
<int key="NSCellFlags2">2048</int>
|
||||
<string key="NSContents">Text Cell</string>
|
||||
<reference key="NSSupport" ref="390959245"/>
|
||||
<object class="NSFont" key="NSSupport" id="390959245">
|
||||
<string key="NSName">LucidaGrande</string>
|
||||
<double key="NSSize">13</double>
|
||||
<int key="NSfFlags">1044</int>
|
||||
</object>
|
||||
<reference key="NSControlView" ref="86489736"/>
|
||||
<object class="NSColor" key="NSBackgroundColor" id="979654510">
|
||||
<int key="NSColorSpace">6</int>
|
||||
@@ -195,19 +196,23 @@
|
||||
<double key="NSMinWidth">40</double>
|
||||
<double key="NSMaxWidth">1000</double>
|
||||
<object class="NSTableHeaderCell" key="NSHeaderCell">
|
||||
<int key="NSCellFlags">75628096</int>
|
||||
<int key="NSCellFlags2">2048</int>
|
||||
<int key="NSCellFlags">75497536</int>
|
||||
<int key="NSCellFlags2">67110912</int>
|
||||
<string key="NSContents">Two</string>
|
||||
<reference key="NSSupport" ref="26"/>
|
||||
<object class="NSFont" key="NSSupport">
|
||||
<string key="NSName">LucidaGrande-Bold</string>
|
||||
<double key="NSSize">20</double>
|
||||
<int key="NSfFlags">16</int>
|
||||
</object>
|
||||
<reference key="NSBackgroundColor" ref="1073356944"/>
|
||||
<reference key="NSTextColor" ref="678139720"/>
|
||||
</object>
|
||||
<object class="NSTextFieldCell" key="NSDataCell" id="642682655">
|
||||
<int key="NSCellFlags">337772096</int>
|
||||
<int key="NSCellFlags2">2048</int>
|
||||
<int key="NSCellFlags">337641536</int>
|
||||
<int key="NSCellFlags2">67110912</int>
|
||||
<string key="NSContents">Text Cell</string>
|
||||
<object class="NSFont" key="NSSupport">
|
||||
<string key="NSName">LucidaGrande</string>
|
||||
<string key="NSName">TimesNewRomanPSMT</string>
|
||||
<double key="NSSize">20</double>
|
||||
<int key="NSfFlags">16</int>
|
||||
</object>
|
||||
@@ -226,24 +231,24 @@
|
||||
<reference key="NSTableView" ref="86489736"/>
|
||||
</object>
|
||||
<object class="NSTableColumn" id="467346610">
|
||||
<double key="NSWidth">81</double>
|
||||
<double key="NSWidth">94.078125</double>
|
||||
<double key="NSMinWidth">10</double>
|
||||
<double key="NSMaxWidth">3.4028234663852885e+54</double>
|
||||
<object class="NSTableHeaderCell" key="NSHeaderCell">
|
||||
<int key="NSCellFlags">75628096</int>
|
||||
<int key="NSCellFlags">75497536</int>
|
||||
<int key="NSCellFlags2">2048</int>
|
||||
<string key="NSContents">Checkbox</string>
|
||||
<string key="NSContents">Checkbox really long</string>
|
||||
<reference key="NSSupport" ref="26"/>
|
||||
<reference key="NSBackgroundColor" ref="676350359"/>
|
||||
<reference key="NSTextColor" ref="678139720"/>
|
||||
</object>
|
||||
<object class="NSButtonCell" key="NSDataCell" id="271362548">
|
||||
<int key="NSCellFlags">67239424</int>
|
||||
<int key="NSCellFlags">67108864</int>
|
||||
<int key="NSCellFlags2">134217728</int>
|
||||
<string key="NSContents">Check</string>
|
||||
<reference key="NSSupport" ref="390959245"/>
|
||||
<reference key="NSControlView" ref="86489736"/>
|
||||
<int key="NSButtonFlags">1211912703</int>
|
||||
<int key="NSButtonFlags">1211912448</int>
|
||||
<int key="NSButtonFlags2">2</int>
|
||||
<object class="NSCustomResource" key="NSNormalImage">
|
||||
<string key="NSClassName">NSImage</string>
|
||||
@@ -263,11 +268,11 @@
|
||||
<reference key="NSTableView" ref="86489736"/>
|
||||
</object>
|
||||
<object class="NSTableColumn" id="991776537">
|
||||
<double key="NSWidth">105</double>
|
||||
<double key="NSWidth">92</double>
|
||||
<double key="NSMinWidth">10</double>
|
||||
<double key="NSMaxWidth">3.4028234663852885e+54</double>
|
||||
<object class="NSTableHeaderCell" key="NSHeaderCell">
|
||||
<int key="NSCellFlags">75628096</int>
|
||||
<int key="NSCellFlags">75497536</int>
|
||||
<int key="NSCellFlags2">2048</int>
|
||||
<string key="NSContents">Level Indicator</string>
|
||||
<reference key="NSSupport" ref="26"/>
|
||||
@@ -275,7 +280,7 @@
|
||||
<reference key="NSTextColor" ref="678139720"/>
|
||||
</object>
|
||||
<object class="NSLevelIndicatorCell" key="NSDataCell" id="801202458">
|
||||
<int key="NSCellFlags">-2080244224</int>
|
||||
<int key="NSCellFlags">-2080374784</int>
|
||||
<int key="NSCellFlags2">0</int>
|
||||
<reference key="NSSupport" ref="390959245"/>
|
||||
<reference key="NSControlView" ref="86489736"/>
|
||||
@@ -313,6 +318,7 @@
|
||||
<int key="NSDraggingSourceMaskForNonLocal">0</int>
|
||||
<bool key="NSAllowsTypeSelect">YES</bool>
|
||||
<int key="NSTableViewDraggingDestinationStyle">0</int>
|
||||
<int key="NSTableViewGroupRowStyle">1</int>
|
||||
</object>
|
||||
</object>
|
||||
<string key="NSFrame">{{1, 17}, {644, 290}}</string>
|
||||
@@ -330,6 +336,7 @@
|
||||
<reference key="NSSuperview" ref="1048514227"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView" ref="480583225"/>
|
||||
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
|
||||
<reference key="NSTarget" ref="1048514227"/>
|
||||
<string key="NSAction">_doScroller:</string>
|
||||
<double key="NSPercent">0.94827586206896552</double>
|
||||
@@ -337,14 +344,15 @@
|
||||
<object class="NSScroller" id="480583225">
|
||||
<reference key="NSNextResponder" ref="1048514227"/>
|
||||
<int key="NSvFlags">-2147483392</int>
|
||||
<string key="NSFrame">{{1, 292}, {516, 15}}</string>
|
||||
<string key="NSFrame">{{1, 291}, {644, 16}}</string>
|
||||
<reference key="NSSuperview" ref="1048514227"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView"/>
|
||||
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
|
||||
<int key="NSsFlags">1</int>
|
||||
<reference key="NSTarget" ref="1048514227"/>
|
||||
<string key="NSAction">_doScroller:</string>
|
||||
<double key="NSPercent">0.99382716049382713</double>
|
||||
<double key="NSPercent">0.94152046783625731</double>
|
||||
</object>
|
||||
<object class="NSClipView" id="471528550">
|
||||
<reference key="NSNextResponder" ref="1048514227"/>
|
||||
@@ -361,28 +369,30 @@
|
||||
<reference key="NSBGColor" ref="979654510"/>
|
||||
<int key="NScvFlags">4</int>
|
||||
</object>
|
||||
<reference ref="167646100"/>
|
||||
</object>
|
||||
<string key="NSFrame">{{20, 20}, {646, 308}}</string>
|
||||
<reference key="NSSuperview" ref="439893737"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView" ref="471528550"/>
|
||||
<int key="NSsFlags">562</int>
|
||||
<int key="NSsFlags">133682</int>
|
||||
<reference key="NSVScroller" ref="347610108"/>
|
||||
<reference key="NSHScroller" ref="480583225"/>
|
||||
<reference key="NSContentView" ref="331394667"/>
|
||||
<reference key="NSHeaderClipView" ref="471528550"/>
|
||||
<reference key="NSCornerView" ref="167646100"/>
|
||||
<bytes key="NSScrollAmts">QSAAAEEgAABCNAAAQjQAAA</bytes>
|
||||
<double key="NSMinMagnification">0.25</double>
|
||||
<double key="NSMaxMagnification">4</double>
|
||||
<double key="NSMagnification">1</double>
|
||||
</object>
|
||||
</object>
|
||||
<string key="NSFrame">{{7, 11}, {686, 348}}</string>
|
||||
<string key="NSFrameSize">{686, 348}</string>
|
||||
<reference key="NSSuperview"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView" ref="1048514227"/>
|
||||
</object>
|
||||
<string key="NSScreenRect">{{0, 0}, {1920, 1178}}</string>
|
||||
<string key="NSMaxSize">{1e+13, 1e+13}</string>
|
||||
<string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
|
||||
<string key="NSMaxSize">{10000000000000, 10000000000000}</string>
|
||||
<bool key="NSWindowIsRestorable">YES</bool>
|
||||
</object>
|
||||
<object class="NSCustomObject" id="635946545">
|
||||
<string key="NSClassName">AppController</string>
|
||||
@@ -421,7 +431,9 @@
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">0</int>
|
||||
<reference key="object" ref="0"/>
|
||||
<object class="NSArray" key="object" id="0">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
</object>
|
||||
<reference key="children" ref="1048"/>
|
||||
<nil key="parent"/>
|
||||
</object>
|
||||
@@ -582,13 +594,14 @@
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSArray" key="dict.sortedKeys">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>-1.IBPluginDependency</string>
|
||||
<string>-2.IBPluginDependency</string>
|
||||
<string>-3.IBPluginDependency</string>
|
||||
<string>371.IBEditorWindowLastContentRect</string>
|
||||
<string>371.IBPluginDependency</string>
|
||||
<string>371.IBWindowTemplateEditedContentRect</string>
|
||||
<string>371.NSWindowTemplate.visibleAtLaunch</string>
|
||||
<string>371.editorWindowContentRectSynchronizationRect</string>
|
||||
<string>372.IBPluginDependency</string>
|
||||
<string>450.IBPluginDependency</string>
|
||||
<string>489.IBPluginDependency</string>
|
||||
<string>490.IBPluginDependency</string>
|
||||
<string>491.IBPluginDependency</string>
|
||||
@@ -598,18 +611,25 @@
|
||||
<string>495.IBPluginDependency</string>
|
||||
<string>496.IBPluginDependency</string>
|
||||
<string>497.IBPluginDependency</string>
|
||||
<string>501.IBPluginDependency</string>
|
||||
<string>503.IBPluginDependency</string>
|
||||
<string>504.IBPluginDependency</string>
|
||||
<string>506.IBPluginDependency</string>
|
||||
<string>508.IBPluginDependency</string>
|
||||
<string>510.IBPluginDependency</string>
|
||||
</object>
|
||||
<object class="NSMutableArray" key="dict.values">
|
||||
<object class="NSArray" key="dict.values">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>{{370, 244}, {558, 348}}</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>{{370, 244}, {558, 348}}</string>
|
||||
<integer value="1"/>
|
||||
<string>{{33, 99}, {480, 360}}</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
|
||||
@@ -188,9 +188,24 @@ dl.el {
|
||||
margin-left: -1cm;
|
||||
}
|
||||
|
||||
.fragment {
|
||||
font-family: Courier, monospace, fixed;
|
||||
font-size: 105%;
|
||||
.fragment .line {
|
||||
font-family: Consolas, Courier, monospace, fixed;
|
||||
white-space: pre-wrap; /* css-3 */
|
||||
white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */
|
||||
white-space: -pre-wrap; /* Opera 4-6 */
|
||||
white-space: -o-pre-wrap; /* Opera 7 */
|
||||
word-wrap: break-word; /* Internet Explorer 5.5+ */
|
||||
font-size: 11px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.fragment .lineno {
|
||||
color: #d4d4d4;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.fragment .lineno a {
|
||||
color: #d4d4d4;
|
||||
}
|
||||
|
||||
pre.fragment {
|
||||
@@ -443,7 +458,7 @@ table.memberdecls {
|
||||
}
|
||||
|
||||
.memItemLeft, .memItemRight, .memTemplParams {
|
||||
border-top: 1px solid #ccc;
|
||||
border-top: 1px solid #f3f3f3;
|
||||
}
|
||||
|
||||
.memItemLeft, .memTemplItemLeft {
|
||||
@@ -813,7 +828,7 @@ table.fieldtable {
|
||||
float:left;
|
||||
padding-left:10px;
|
||||
padding-right: 15px;
|
||||
background-image:url('bc_s.png');
|
||||
padding-top: 0px;
|
||||
background-repeat:no-repeat;
|
||||
background-position:right;
|
||||
color:#374E7C;
|
||||
@@ -1079,7 +1094,7 @@ dl.citelist dd {
|
||||
/* ADDITIONS */
|
||||
.tabs, .tabs2, .tabs3 {
|
||||
background: -moz-linear-gradient(-90deg, #fff, #eee);
|
||||
background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#eee));
|
||||
background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#eee));
|
||||
border-bottom: 1px solid #ccc;
|
||||
width: 100%;
|
||||
z-index: 101;
|
||||
@@ -1150,7 +1165,7 @@ dl.citelist dd {
|
||||
|
||||
.tablist li.current a {
|
||||
background: -moz-linear-gradient(-90deg, #eee, #fff);
|
||||
background: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#fff));
|
||||
background: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#fff));
|
||||
color: #444;
|
||||
text-shadow: 0px 1px 1px #f2f2f2;
|
||||
}
|
||||
@@ -1283,3 +1298,23 @@ dl.citelist dd {
|
||||
#nav-tree-contents {
|
||||
margin: 6px 0px 0px 0px;
|
||||
}
|
||||
|
||||
.memSeparator {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.inherit_header td {
|
||||
padding-top: 30px;
|
||||
padding-bottom: 10px;
|
||||
font: 13px normal "Lucida Grande", Helvetica, Arial, Geneva, sans-serif;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#nav-sync {
|
||||
right: 5px;
|
||||
}
|
||||
#nav-sync img {
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -73,7 +73,9 @@ extern NSString * const XCCListeningStartNotification;
|
||||
- (BOOL)isXIBFile:(NSString *)path;
|
||||
- (BOOL)isXCCIgnoreFile:(NSString *)path;
|
||||
- (BOOL)prepareXCodeSupportProject;
|
||||
- (NSURL*)shadowURLForSourceURL:(NSURL*)aSourceURL;
|
||||
- (NSURL*)shadowHeaderURLForSourceURL:(NSURL*)aSourceURL;
|
||||
- (void)cleanUpShadowsRelatedToSourceURL:(NSURL*)aSourceURL;
|
||||
- (NSURL*)shadowImplementationURLForSourceURL:(NSURL*)aSourceURL;
|
||||
- (NSURL*)sourceURLForShadowName:(NSString *)aString;
|
||||
- (void)handleFileModification:(NSString*)fullPath notify:(BOOL)shouldNotify;
|
||||
- (void)handleFileRemoval:(NSString*)fullPath;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#import "TNXCodeCapp.h"
|
||||
#include "macros.h"
|
||||
|
||||
NSString * const XCCUnderscoreReplacement = @"DoNotPutThisStringInFileNameOrWorldWillDie";
|
||||
NSString * const XCCDidPopulateProjectNotification = @"XCCDidPopulateProjectNotification";
|
||||
NSString * const XCCConversionStartNotification = @"XCCConversionStartNotification";
|
||||
NSString * const XCCConversionStopNotification = @"XCCConversionStopNotification";
|
||||
@@ -39,8 +40,8 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
@synthesize supportFileLevelAPI;
|
||||
@synthesize isUsingFileLevelAPI;
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Initialization
|
||||
|
||||
#pragma mark - Initialization
|
||||
|
||||
/*!
|
||||
Initialize the AppController
|
||||
@@ -48,7 +49,7 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
- (id)init
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
|
||||
if (self)
|
||||
{
|
||||
errorList = [NSMutableArray arrayWithCapacity:10];
|
||||
@@ -57,7 +58,7 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
parserPath = [[NSBundle mainBundle] pathForResource:@"parser" ofType:@"j"];
|
||||
lastEventId = [[NSUserDefaults standardUserDefaults] objectForKey:@"lastEventId"];
|
||||
appStartedTimestamp = [NSDate date];
|
||||
|
||||
|
||||
[self setIsListening:NO];
|
||||
[self setIsUsingFileLevelAPI:NO];
|
||||
|
||||
@@ -65,11 +66,11 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
SInt32 versionMinor = 0;
|
||||
Gestalt(gestaltSystemVersionMajor, &versionMajor);
|
||||
Gestalt(gestaltSystemVersionMinor, &versionMinor);
|
||||
|
||||
|
||||
[self setSupportFileLevelAPI:versionMajor >= 10 && versionMinor >= 7];
|
||||
// Uncomment to simulate 10.6 mode
|
||||
// [self setSupportFileLevelAPI:NO];
|
||||
|
||||
|
||||
[self configure];
|
||||
|
||||
if([fm fileExistsAtPath:[@"~/.bash_profile" stringByExpandingTildeInPath]])
|
||||
@@ -91,21 +92,21 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
profilePath = @"";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)start
|
||||
{
|
||||
{
|
||||
if (![[NSUserDefaults standardUserDefaults] boolForKey:@"XCCReopenLastProject"])
|
||||
return;
|
||||
|
||||
NSString *lastOpenedPath = [[NSUserDefaults standardUserDefaults] objectForKey:@"LastOpenedPath"];
|
||||
|
||||
|
||||
if (lastOpenedPath)
|
||||
{
|
||||
if ([fm fileExistsAtPath:lastOpenedPath])
|
||||
{
|
||||
{
|
||||
[self listenProjectAtPath:[NSString stringWithFormat:@"%@/", lastOpenedPath]];
|
||||
}
|
||||
else
|
||||
@@ -115,6 +116,135 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Project Management
|
||||
|
||||
/*!
|
||||
Check if .XcodeSupport needs to be initialized.
|
||||
If not needed, check that all J files are mirrored. If no,
|
||||
then launch conversion for missing mirrored h files
|
||||
@return YES or NO
|
||||
*/
|
||||
- (BOOL)prepareXCodeSupportProject
|
||||
{
|
||||
XCodeSupportProjectName = [NSString stringWithFormat:@"%@.xcodeproj/", currentProjectName];
|
||||
XCodeTemplatePBXPath = [[NSBundle mainBundle] pathForResource:@"project.pbxproj" ofType:@"sample"];
|
||||
XCodeSupportProject = [NSURL URLWithString:XCodeSupportProjectName relativeToURL:currentProjectURL];
|
||||
XCodeSupportProjectSources = [NSURL URLWithString:@".XcodeSupport/" relativeToURL:currentProjectURL];
|
||||
XCodeSupportPBXPath = [NSString stringWithFormat:@"%@/project.pbxproj", [XCodeSupportProject path]];
|
||||
PBXModifierScriptPath = [[NSBundle mainBundle] pathForResource:@"pbxprojModifier" ofType:@"py"];
|
||||
|
||||
|
||||
//[fm removeItemAtURL:XCodeSupportProjectSources error:nil];
|
||||
//[fm removeItemAtURL:XCodeSupportProject error:nil];
|
||||
|
||||
// create the template project if it doesn't exist
|
||||
if (![fm fileExistsAtPath:[XCodeSupportProjectSources path]])
|
||||
{
|
||||
NSLog(@"prepareXCodeSupportProject: Xcode support folder created at: %@", [XCodeSupportProject path]);
|
||||
[fm createDirectoryAtPath:[XCodeSupportProject path] withIntermediateDirectories:YES attributes:nil error:nil];
|
||||
|
||||
DLog(@"prepareXCodeSupportProject: Copying project.pbxproj from %@ to %@", XCodeTemplatePBXPath, [XCodeSupportProject path]);
|
||||
[fm copyItemAtPath:XCodeTemplatePBXPath toPath:XCodeSupportPBXPath error:nil];
|
||||
|
||||
DLog(@"prepareXCodeSupportProject: Reading the content of the project.pbxproj");
|
||||
NSMutableString *PBXContent = [NSMutableString stringWithContentsOfFile:XCodeSupportPBXPath encoding:NSUTF8StringEncoding error:nil];
|
||||
|
||||
[PBXContent writeToFile:XCodeSupportPBXPath atomically:YES encoding:NSUTF8StringEncoding error:nil];
|
||||
DLog(@"prepareXCodeSupportProject: PBX file adapted to the project");
|
||||
|
||||
[self createXcodeSupportProjectSourcesDirIfNecessary];
|
||||
return NO;
|
||||
}
|
||||
|
||||
[self createXcodeSupportProjectSourcesDirIfNecessary];
|
||||
return YES;
|
||||
}
|
||||
|
||||
/*!
|
||||
Create the .XcodeSupport/Sources folder if necessary.
|
||||
*/
|
||||
- (void)createXcodeSupportProjectSourcesDirIfNecessary
|
||||
{
|
||||
if ([fm fileExistsAtPath:[XCodeSupportProjectSources path]])
|
||||
return;
|
||||
|
||||
DLog(@"createXcodeSupportProjectSourcesDirIfNecessary: Creating source folder %@", [XCodeSupportProjectSources path]);
|
||||
[fm createDirectoryAtPath:[XCodeSupportProjectSources path] withIntermediateDirectories:YES attributes:nil error:nil];
|
||||
}
|
||||
|
||||
/*!
|
||||
Initialize the creation of the .XcodeSupport project. This
|
||||
Operation is threaded
|
||||
@param arguments Thread arguments (not used)
|
||||
@param shouldNotify is YES, XCCDidPopulateProjectNotification will be send
|
||||
*/
|
||||
- (void)populateXCodeProject:(NSNumber *)shouldNotify
|
||||
{
|
||||
if ([shouldNotify boolValue])
|
||||
[delegate performSelector:@selector(growlWithTitle:message:) withObject:@"Loading project" withObject:[currentProjectURL path]];
|
||||
|
||||
NSArray *subdpaths = [fm subpathsAtPath:[currentProjectURL path]];
|
||||
|
||||
for (NSString *p in subdpaths)
|
||||
{
|
||||
NSString *filePath = [NSString stringWithFormat:@"%@/%@", [currentProjectURL path], p];
|
||||
|
||||
BOOL isDir = NO;
|
||||
[fm fileExistsAtPath:filePath isDirectory:&isDir];
|
||||
|
||||
if (isDir || ![self isObjJFile:filePath] || [self isPathMatchingIgnoredPaths:filePath])
|
||||
continue;
|
||||
|
||||
NSURL *eventualShadow = [self shadowHeaderURLForSourceURL:[NSURL fileURLWithPath:filePath]];
|
||||
|
||||
if (![fm fileExistsAtPath:[eventualShadow path]])
|
||||
{
|
||||
DLog(@"populateXCodeProject: Computing missing shadow file for %@", filePath);
|
||||
[self handleFileModification:filePath notify:NO];
|
||||
}
|
||||
}
|
||||
|
||||
if ([shouldNotify boolValue])
|
||||
{
|
||||
NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:currentProjectURL, @"URL", nil];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:XCCDidPopulateProjectNotification object:self userInfo:info];
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Start all needed processes for listening to a given path
|
||||
@param path The folder path to listen to
|
||||
*/
|
||||
- (void)listenProjectAtPath:(NSString *)path
|
||||
{
|
||||
NSMutableString *tempName = [NSMutableString stringWithString:[path lastPathComponent]];
|
||||
|
||||
currentProjectURL = [NSURL fileURLWithPath:path];
|
||||
|
||||
[tempName replaceOccurrencesOfString:@" "
|
||||
withString:@"_"
|
||||
options:NSCaseInsensitiveSearch
|
||||
range:NSMakeRange(0, [tempName length])];
|
||||
currentProjectName = [NSString stringWithString:tempName];
|
||||
|
||||
[self computeIgnoredPaths];
|
||||
|
||||
BOOL isProjectReady = [self prepareXCodeSupportProject];
|
||||
|
||||
[NSThread detachNewThreadSelector:@selector(populateXCodeProject:) toTarget:self withObject:[NSNumber numberWithBool:!isProjectReady]];
|
||||
|
||||
[self initializeEventStreamWithPath:[currentProjectURL path]];
|
||||
|
||||
NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:path, @"path", [NSNumber numberWithInt:(isProjectReady) ? 1 : 0], @"ready", nil];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:XCCListeningStartNotification object:self userInfo:info];
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] setObject:[currentProjectURL path] forKey:@"LastOpenedPath"];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Event Stream
|
||||
|
||||
/*!
|
||||
Initializes the FSEvent stream
|
||||
@param aPath the path of the folder to listen
|
||||
@@ -123,18 +253,18 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
{
|
||||
if ([self isListening])
|
||||
return;
|
||||
|
||||
|
||||
[self stopEventStream];
|
||||
|
||||
|
||||
NSMutableArray *pathsToWatch = [NSMutableArray arrayWithObject:aPath];
|
||||
void *appPointer = (void *)self;
|
||||
FSEventStreamContext context = {0, appPointer, NULL, NULL, NULL};
|
||||
CFTimeInterval latency = 2.0;
|
||||
FSEventStreamCreateFlags flags = 0;
|
||||
|
||||
|
||||
if (supportsFileBasedListening)
|
||||
{
|
||||
DLog(@"Initializing the FSEventStream at file level (clean)");
|
||||
DLog(@"initializeEventStreamWithPath: Initializing the FSEventStream at file level (clean)");
|
||||
flags = kFSEventStreamCreateFlagUseCFTypes | kFSEventStreamCreateFlagNoDefer | kFSEventStreamCreateFlagFileEvents;
|
||||
}
|
||||
else
|
||||
@@ -142,10 +272,10 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
NSLog(@"Initializing the FSEventStream at folder level (dirty)");
|
||||
flags = kFSEventStreamCreateFlagUseCFTypes;
|
||||
}
|
||||
|
||||
|
||||
// add symlinked directories
|
||||
NSArray *fileList = [fm contentsOfDirectoryAtPath:aPath error:nil];
|
||||
|
||||
|
||||
for (NSString *node in fileList)
|
||||
{
|
||||
NSDictionary *attributes = [fm attributesOfItemAtPath:aPath error:nil];
|
||||
@@ -160,19 +290,15 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
stream = FSEventStreamCreate(NULL, &fsevents_callback, &context, (CFArrayRef) pathsToWatch,
|
||||
[lastEventId unsignedLongLongValue], latency, flags);
|
||||
|
||||
|
||||
FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
||||
FSEventStreamStart(stream);
|
||||
[self setIsListening:YES];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Utilities
|
||||
|
||||
/*!
|
||||
Stop listening the FSEvent stream if active
|
||||
*/
|
||||
@@ -210,7 +336,7 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
{
|
||||
if (![self supportFileLevelAPI])
|
||||
{
|
||||
DLog(@"System doesn't support file level API");
|
||||
DLog(@"configure: System doesn't support file level API");
|
||||
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:2] forKey:@"XCCAPIMode"];
|
||||
}
|
||||
|
||||
@@ -229,7 +355,7 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
|
||||
if (supportsFileBasedListening)
|
||||
{
|
||||
DLog(@"using 10.7+ mode listening (clean)");
|
||||
DLog(@"configure: using 10.7+ mode listening (clean)");
|
||||
|
||||
[self setCurrentAPIMode:@"File level (Lion)"];
|
||||
[self setIsUsingFileLevelAPI:YES];
|
||||
@@ -237,7 +363,7 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
}
|
||||
else
|
||||
{
|
||||
DLog(@"using 10.6 mode listening (dirty)");
|
||||
DLog(@"configure: using 10.6 mode listening (dirty)");
|
||||
reactToInodeModification = NO;
|
||||
[self setCurrentAPIMode:@"Folder level (Snow Leopard)"];
|
||||
[self setIsUsingFileLevelAPI:NO];
|
||||
@@ -273,6 +399,9 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Shell Helpers
|
||||
|
||||
/*!
|
||||
Run a NSTask with the given arguments
|
||||
@param arguments NSArray containing the NSTask arguments
|
||||
@@ -284,22 +413,25 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
NSData *stdOut;
|
||||
NSString *response;
|
||||
NSNumber *status;
|
||||
|
||||
|
||||
task = [[NSTask alloc] init];
|
||||
|
||||
|
||||
[task setLaunchPath: @"/bin/bash"];
|
||||
[task setArguments: arguments];
|
||||
[task setStandardOutput:[NSPipe pipe]];
|
||||
[task launch];
|
||||
[task waitUntilExit];
|
||||
|
||||
|
||||
stdOut = [[[task standardOutput] fileHandleForReading] availableData];
|
||||
response = [[NSString alloc] initWithData:stdOut encoding:NSUTF8StringEncoding];
|
||||
status = [NSNumber numberWithInt:[task terminationStatus]];
|
||||
|
||||
|
||||
return [NSArray arrayWithObjects:status, response, nil];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Event Handlers
|
||||
|
||||
/*!
|
||||
Handle a file modification. If it's a .J or XIB or NIB, it will
|
||||
perform the according conversion. If it's .xcodecapp-ignore, it will
|
||||
@@ -315,7 +447,7 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
if ([self isPathMatchingIgnoredPaths:fullPath] || ![fm fileExistsAtPath:fullPath])
|
||||
return;
|
||||
|
||||
DLog(@"Parsing modified file: %@", fullPath);
|
||||
DLog(@"handleFileModification:notify: Parsing modified file: %@", fullPath);
|
||||
|
||||
NSArray *arguments = nil;
|
||||
NSArray *PBXArguments = nil;
|
||||
@@ -324,16 +456,19 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
NSString *response = nil;
|
||||
NSNumber *status = [NSNumber numberWithInt:0];
|
||||
NSString *splitPath = [fullPath substringFromIndex:[[currentProjectURL path] length] + 1];
|
||||
NSString *shadowPath = [[self shadowURLForSourceURL:[NSURL URLWithString:[fullPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]] path];
|
||||
|
||||
DLog(@"Shadow path: %@", shadowPath);
|
||||
|
||||
NSURL *encodedURL = [NSURL URLWithString:[fullPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
|
||||
NSURL *shadowHeaderURL = [self shadowHeaderURLForSourceURL:encodedURL];
|
||||
NSURL *shadowImplementationURL = [self shadowImplementationURLForSourceURL:encodedURL];
|
||||
|
||||
DLog(@"handleFileModification:notify: Shadow header path: %@", shadowHeaderURL);
|
||||
DLog(@"handleFileModification:notify: Shadow implementation path: %@", shadowImplementationURL);
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:XCCConversionStartNotification object:self];
|
||||
|
||||
if ([self isXIBFile:fullPath])
|
||||
{
|
||||
arguments = [NSArray arrayWithObjects: @"-c",
|
||||
[NSString stringWithFormat:@"(%@; nib2cib '%@';) 2>&1", profilePath, fullPath],@"",nil];
|
||||
[NSString stringWithFormat:@"(%@; nib2cib '%@';) 2>&1", profilePath, fullPath],@"",nil];
|
||||
|
||||
successTitle = @"XIB converted";
|
||||
successMsg = splitPath;
|
||||
@@ -341,19 +476,20 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
else if ([self isObjJFile:fullPath])
|
||||
{
|
||||
arguments = [NSArray arrayWithObjects: @"-c",
|
||||
[NSString stringWithFormat:@"(%@; objj '%@' '%@' '%@';) 2>&1",
|
||||
profilePath,
|
||||
parserPath,
|
||||
fullPath,
|
||||
shadowPath],
|
||||
@"",nil];
|
||||
[NSString stringWithFormat:@"(%@; objj '%@' '%@' '%@' '%@';) 2>&1",
|
||||
profilePath,
|
||||
parserPath,
|
||||
fullPath,
|
||||
[shadowHeaderURL path],
|
||||
[shadowImplementationURL path]],nil];
|
||||
|
||||
PBXArguments = [NSArray arrayWithObjects: @"-c",
|
||||
[NSString stringWithFormat:@"(%@; python %@ add '%@' '%@' '%@' '%@') 2>&1",
|
||||
[NSString stringWithFormat:@"(%@; python %@ add '%@' '%@' '%@' '%@' '%@') 2>&1",
|
||||
profilePath,
|
||||
PBXModifierScriptPath,
|
||||
XCodeSupportPBXPath,
|
||||
shadowPath,
|
||||
[shadowHeaderURL path],
|
||||
[shadowImplementationURL path],
|
||||
fullPath,
|
||||
[currentProjectURL path]],nil];
|
||||
|
||||
@@ -371,22 +507,22 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
// Run the task and get the response if needed
|
||||
if (arguments)
|
||||
{
|
||||
DLog(@"Running conversion task...");
|
||||
DLog(@"handleFileModification:notify: Running conversion task...");
|
||||
NSArray *statusInfo = [self runTask:arguments];
|
||||
|
||||
|
||||
status = [statusInfo objectAtIndex:0];
|
||||
response = [statusInfo objectAtIndex:1];
|
||||
|
||||
DLog(@"Conversion task result/response: %@/%@", status, response);
|
||||
|
||||
DLog(@"handleFileModification:notify: Conversion task result/response: %@/%@", status, response);
|
||||
}
|
||||
|
||||
if (PBXArguments)
|
||||
{
|
||||
DLog(@"Running update PBX task...");
|
||||
DLog(@"handleFileModification:notify: Running update PBX task...");
|
||||
NSArray *statusInfo = [self runTask:PBXArguments];
|
||||
status = [statusInfo objectAtIndex:0];
|
||||
response = [statusInfo objectAtIndex:1];
|
||||
DLog(@"Update PBX Task result/response: %@/%@", status, response);
|
||||
DLog(@"handleFileModification:notify: Update PBX Task result/response: %@/%@", status, response);
|
||||
}
|
||||
|
||||
if ([status intValue] == 0 && shouldNotify)
|
||||
@@ -397,12 +533,12 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
{
|
||||
if (response)
|
||||
[errorList addObject:response];
|
||||
|
||||
|
||||
[delegate performSelector:@selector(growlWithTitle:message:) withObject:@"Error processing file" withObject:splitPath];
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:XCCConversionStopNotification object:self];
|
||||
DLog(@"Processed: %@", fullPath);
|
||||
DLog(@"handleFileModification:notify: Processed: %@", fullPath);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -416,37 +552,18 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
{
|
||||
if ([self isPathMatchingIgnoredPaths:fullPath] || [fm fileExistsAtPath:fullPath])
|
||||
return;
|
||||
|
||||
|
||||
NSString *encodedPath = [fullPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
if ([self isObjJFile:fullPath])
|
||||
{
|
||||
NSString *shadowPath = [[self shadowURLForSourceURL:[NSURL URLWithString:[fullPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]] path];
|
||||
|
||||
DLog(@"Removing shadow file: %@", shadowPath);
|
||||
[fm removeItemAtPath:shadowPath error:nil];
|
||||
|
||||
DLog(@"Removing PBX reference task...");
|
||||
|
||||
#if DEBUG
|
||||
NSArray *PBXArguments = [NSArray arrayWithObjects: @"-c",
|
||||
[NSString stringWithFormat:@"(%@; python %@ remove '%@' '%@' '%@' '%@') 2>&1",
|
||||
profilePath,
|
||||
PBXModifierScriptPath,
|
||||
XCodeSupportPBXPath,
|
||||
shadowPath,
|
||||
fullPath,
|
||||
[currentProjectURL path]],nil];
|
||||
NSArray *statusInfo = [self runTask:PBXArguments];
|
||||
NSNumber *status = [statusInfo objectAtIndex:0];
|
||||
NSString *response = [statusInfo objectAtIndex:1];
|
||||
#endif
|
||||
DLog(@"PBX Reference removal status/response: %@/%@", status, response);
|
||||
}
|
||||
[self cleanUpShadowsRelatedToSourceURL:[NSURL URLWithString:encodedPath]];
|
||||
else if ([self isXCCIgnoreFile:fullPath])
|
||||
{
|
||||
[self computeIgnoredPaths];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Source Files Management
|
||||
|
||||
/*!
|
||||
Check if given full path is Objective-J file
|
||||
@param path the path to check
|
||||
@@ -480,114 +597,23 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Check if .XcodeSupport needs to be initialized.
|
||||
If not needed, check that all J files are mirrored. If no,
|
||||
then launch conversion for missing mirrored h files
|
||||
@return YES or NO
|
||||
*/
|
||||
- (BOOL)prepareXCodeSupportProject
|
||||
{
|
||||
XCodeSupportProjectName = [NSString stringWithFormat:@"%@.xcodeproj/", currentProjectName];
|
||||
XCodeTemplatePBXPath = [[NSBundle mainBundle] pathForResource:@"project.pbxproj" ofType:@"sample"];
|
||||
XCodeSupportProject = [NSURL URLWithString:XCodeSupportProjectName relativeToURL:currentProjectURL];
|
||||
XCodeSupportProjectSources = [NSURL URLWithString:@".XcodeSupport/" relativeToURL:currentProjectURL];
|
||||
XCodeSupportPBXPath = [NSString stringWithFormat:@"%@/project.pbxproj", [XCodeSupportProject path]];
|
||||
PBXModifierScriptPath = [[NSBundle mainBundle] pathForResource:@"pbxprojModifier" ofType:@"py"];
|
||||
|
||||
|
||||
//[fm removeItemAtURL:XCodeSupportProjectSources error:nil];
|
||||
//[fm removeItemAtURL:XCodeSupportProject error:nil];
|
||||
|
||||
// create the template project if it doesn't exist
|
||||
if (![fm fileExistsAtPath:[XCodeSupportProjectSources path]])
|
||||
{
|
||||
NSLog(@"Xcode support folder created at: %@", [XCodeSupportProject path]);
|
||||
[fm createDirectoryAtPath:[XCodeSupportProject path] withIntermediateDirectories:YES attributes:nil error:nil];
|
||||
|
||||
DLog(@"Copying project.pbxproj from %@ to %@", XCodeTemplatePBXPath, [XCodeSupportProject path]);
|
||||
[fm copyItemAtPath:XCodeTemplatePBXPath toPath:XCodeSupportPBXPath error:nil];
|
||||
|
||||
DLog(@"Reading the content of the project.pbxproj");
|
||||
NSMutableString *PBXContent = [NSMutableString stringWithContentsOfFile:XCodeSupportPBXPath encoding:NSUTF8StringEncoding error:nil];
|
||||
|
||||
[PBXContent writeToFile:XCodeSupportPBXPath atomically:YES encoding:NSUTF8StringEncoding error:nil];
|
||||
DLog(@"PBX file adapted to the project");
|
||||
|
||||
[self createXcodeSupportProjectSourcesDirIfNecessary];
|
||||
return NO;
|
||||
}
|
||||
|
||||
[self createXcodeSupportProjectSourcesDirIfNecessary];
|
||||
return YES;
|
||||
}
|
||||
#pragma mark - Shadow Files Management
|
||||
|
||||
/*!
|
||||
Create the .XcodeSupport/Sources folder if necessary.
|
||||
*/
|
||||
- (void)createXcodeSupportProjectSourcesDirIfNecessary
|
||||
{
|
||||
if ([fm fileExistsAtPath:[XCodeSupportProjectSources path]])
|
||||
return;
|
||||
|
||||
DLog(@"Creating source folder %@", [XCodeSupportProjectSources path]);
|
||||
[fm createDirectoryAtPath:[XCodeSupportProjectSources path] withIntermediateDirectories:YES attributes:nil error:nil];
|
||||
}
|
||||
|
||||
/*!
|
||||
Initialize the creation of the .XcodeSupport project. This
|
||||
Operation is threaded
|
||||
@param arguments Thread arguments (not used)
|
||||
@param shouldNotify is YES, XCCDidPopulateProjectNotification will be send
|
||||
*/
|
||||
- (void)populateXCodeProject:(NSNumber *)shouldNotify
|
||||
{
|
||||
if ([shouldNotify boolValue])
|
||||
[delegate performSelector:@selector(growlWithTitle:message:) withObject:@"Loading project" withObject:[currentProjectURL path]];
|
||||
|
||||
NSArray *subdpaths = [fm subpathsAtPath:[currentProjectURL path]];
|
||||
|
||||
for (NSString *p in subdpaths)
|
||||
{
|
||||
NSString *filePath = [NSString stringWithFormat:@"%@/%@", [currentProjectURL path], p];
|
||||
|
||||
BOOL isDir = NO;
|
||||
[fm fileExistsAtPath:filePath isDirectory:&isDir];
|
||||
|
||||
if (isDir || ![self isObjJFile:filePath] || [self isPathMatchingIgnoredPaths:filePath])
|
||||
continue;
|
||||
|
||||
NSURL *eventualShadow = [self shadowURLForSourceURL:[NSURL fileURLWithPath:filePath]];
|
||||
|
||||
if (![fm fileExistsAtPath:[eventualShadow path]])
|
||||
{
|
||||
DLog(@"Computing missing shadow file for %@", filePath);
|
||||
[self handleFileModification:filePath notify:NO];
|
||||
}
|
||||
}
|
||||
|
||||
if ([shouldNotify boolValue])
|
||||
{
|
||||
NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:currentProjectURL, @"URL", nil];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:XCCDidPopulateProjectNotification object:self userInfo:info];
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Compute the mirorred (shadow) name for a given path
|
||||
Compute the mirorred (shadow) header file name for a given path
|
||||
@param aSourceURL the origin path
|
||||
@return NSURL representing the shadow path
|
||||
@return NSURL representing the shadow URL for the header file
|
||||
*/
|
||||
- (NSURL *)shadowURLForSourceURL:(NSURL*)aSourceURL
|
||||
- (NSURL *)shadowHeaderURLForSourceURL:(NSURL*)aSourceURL
|
||||
{
|
||||
if (!aSourceURL)
|
||||
[NSException raise:NSInvalidArgumentException format:@"shadowURLForSourceURL: aSource URL must not be null"];
|
||||
[NSException raise:NSInvalidArgumentException format:@"shadowHeaderURLForSourceURL: aSource URL must not be null"];
|
||||
|
||||
NSMutableString *flattenedPath = [NSMutableString stringWithString:[aSourceURL path]];
|
||||
|
||||
|
||||
// Replace "_" with a substring that is unlikely to be in a filename
|
||||
[flattenedPath replaceOccurrencesOfString:@"_"
|
||||
withString:@"≤‹°∞°›≥"
|
||||
withString:XCCUnderscoreReplacement
|
||||
options:0
|
||||
range:NSMakeRange(0, [flattenedPath length])];
|
||||
|
||||
@@ -596,12 +622,33 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
options:0
|
||||
range:NSMakeRange(0, [flattenedPath length])];
|
||||
|
||||
DLog(@"Flattened path: %@", flattenedPath);
|
||||
NSString *basename = [NSString stringWithFormat:@"%@.m", [[flattenedPath stringByDeletingPathExtension] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
|
||||
|
||||
DLog(@"shadowHeaderURLForSourceURL: Flattened path: %@", flattenedPath);
|
||||
NSString *basename = [NSString stringWithFormat:@"%@.h", [[flattenedPath stringByDeletingPathExtension] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
|
||||
|
||||
return [NSURL URLWithString:basename relativeToURL:XCodeSupportProjectSources];
|
||||
}
|
||||
|
||||
/*!
|
||||
Compute the mirorred (shadow) implementation file name for a given path
|
||||
@param aSourceURL the origin path
|
||||
@return NSURL representing the shadow URL for the implementation file
|
||||
*/
|
||||
- (NSURL *)shadowImplementationURLForSourceURL:(NSURL*)aSourceURL
|
||||
{
|
||||
if (!aSourceURL)
|
||||
[NSException raise:NSInvalidArgumentException format:@"shadowImplementationURLForSourceURL: aSource URL must not be null"];
|
||||
|
||||
NSURL *shadowHeaderURL = [self shadowHeaderURLForSourceURL:aSourceURL];
|
||||
NSURL *shadowImplPath = [[shadowHeaderURL URLByDeletingPathExtension] URLByAppendingPathExtension:@"m"];
|
||||
|
||||
return shadowImplPath;
|
||||
}
|
||||
|
||||
/*!
|
||||
Compute the Cappuccino source file that is related to the given shadow header file URL
|
||||
@param aString the origin path
|
||||
@return NSURL representing the URL for the related Cappuccino source file
|
||||
*/
|
||||
- (NSURL *)sourceURLForShadowName:(NSString *)aString
|
||||
{
|
||||
NSMutableString * unshadowedPath = [NSMutableString stringWithString:aString];
|
||||
@@ -611,12 +658,12 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
options:0
|
||||
range:NSMakeRange(0, [unshadowedPath length])];
|
||||
|
||||
[unshadowedPath replaceOccurrencesOfString:@"≤‹°∞°›≥"
|
||||
withString:@"_"
|
||||
options:0
|
||||
range:NSMakeRange(0, [unshadowedPath length])];
|
||||
[unshadowedPath replaceOccurrencesOfString:XCCUnderscoreReplacement
|
||||
withString:@"_"
|
||||
options:0
|
||||
range:NSMakeRange(0, [unshadowedPath length])];
|
||||
|
||||
[unshadowedPath replaceOccurrencesOfString:@".m"
|
||||
[unshadowedPath replaceOccurrencesOfString:@".h"
|
||||
withString:@".j"
|
||||
options:0
|
||||
range:NSMakeRange(0, [unshadowedPath length])];
|
||||
@@ -624,6 +671,64 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
return [NSURL fileURLWithPath:[NSString stringWithString:unshadowedPath]];
|
||||
}
|
||||
|
||||
/*!
|
||||
Clean up any shadow files and PBX entries related to given the Cappuccino source file URL
|
||||
@param anURL the Cappuccino source file URL
|
||||
*/
|
||||
- (void)cleanUpShadowsRelatedToSourceURL:(NSURL *)anURL
|
||||
{
|
||||
NSURL *shadowHeaderURL = [self shadowHeaderURLForSourceURL:anURL];
|
||||
NSURL *shadowImplementationURL = [self shadowImplementationURLForSourceURL:anURL];
|
||||
|
||||
DLog(@"cleanUpShadowsRelatedToSourceURL: Removing shadow header file: %@", shadowHeaderURL);
|
||||
[fm removeItemAtURL:shadowHeaderURL error:nil];
|
||||
|
||||
DLog(@"cleanUpShadowsRelatedToSourceURL: Removing shadow implementation file: %@", shadowImplementationURL);
|
||||
[fm removeItemAtURL:shadowImplementationURL error:nil];
|
||||
|
||||
DLog(@"cleanUpShadowsRelatedToSourceURL:Removing PBX reference task...");
|
||||
NSArray *PBXArguments = [NSArray arrayWithObjects: @"-c",
|
||||
[NSString stringWithFormat:@"(%@; python %@ remove '%@' '%@' '%@' '%@' '%@') 2>&1",
|
||||
profilePath,
|
||||
PBXModifierScriptPath,
|
||||
XCodeSupportPBXPath,
|
||||
[shadowHeaderURL path],
|
||||
[shadowImplementationURL path],
|
||||
[anURL path],
|
||||
[currentProjectURL path]],nil];
|
||||
|
||||
NSArray *statusInfo = [self runTask:PBXArguments];
|
||||
NSNumber *status = [statusInfo objectAtIndex:0];
|
||||
NSString *response = [statusInfo objectAtIndex:1];
|
||||
DLog(@"cleanUpShadowsRelatedToSourceURL: PBX Reference removal status/response: %@/%@", status, response);
|
||||
}
|
||||
|
||||
/*!
|
||||
Clean the support folder according to files present in given path
|
||||
*/
|
||||
- (void)tidyShadowedFiles
|
||||
{
|
||||
NSArray *subpaths = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[XCodeSupportProjectSources path] error:NULL];
|
||||
|
||||
for (NSString *subpath in subpaths)
|
||||
{
|
||||
if ([subpath pathExtension] != @".h" || [subpath lastPathComponent] == @"xcc_general_include.h")
|
||||
continue;
|
||||
|
||||
NSURL *unshadowed = [self sourceURLForShadowName:subpath];
|
||||
|
||||
if (![fm fileExistsAtPath:[unshadowed path]])
|
||||
{
|
||||
[self cleanUpShadowsRelatedToSourceURL:unshadowed];
|
||||
|
||||
if (![self supportFileLevelAPI] && [self respondsToSelector:@selector(updateLastModificationDate:forPath:)])
|
||||
[self performSelector:@selector(updateLastModificationDate:forPath:) withObject:nil withObject:unshadowed];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - XCC Ignore management
|
||||
|
||||
/*!
|
||||
Compute the ignored paths according to any existing
|
||||
@@ -645,7 +750,7 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
[ignoredFilePaths addObject:pattern];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[ignoredFilePaths addObject:@"*/.git/*"];
|
||||
[ignoredFilePaths addObject:@"*/.svn/*"];
|
||||
[ignoredFilePaths addObject:@"*/.hg/*"];
|
||||
@@ -656,7 +761,7 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
[ignoredFilePaths addObject:@"*main.j"];
|
||||
[ignoredFilePaths addObject:@"*.xcodeproj/*"];
|
||||
[ignoredFilePaths addObject:@"*.DS_Store"];
|
||||
|
||||
|
||||
NSLog(@"Ignoring file paths: %@", ignoredFilePaths);
|
||||
}
|
||||
|
||||
@@ -706,76 +811,6 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
return NO;
|
||||
}
|
||||
|
||||
/*!
|
||||
Start all needed processes for listening to a given path
|
||||
@param path The folder path to listen to
|
||||
*/
|
||||
- (void)listenProjectAtPath:(NSString *)path
|
||||
{
|
||||
NSMutableString *tempName = [NSMutableString stringWithString:[path lastPathComponent]];
|
||||
|
||||
currentProjectURL = [NSURL fileURLWithPath:path];
|
||||
|
||||
[tempName replaceOccurrencesOfString:@" "
|
||||
withString:@"_"
|
||||
options:NSCaseInsensitiveSearch
|
||||
range:NSMakeRange(0, [tempName length])];
|
||||
currentProjectName = [NSString stringWithString:tempName];
|
||||
|
||||
[self computeIgnoredPaths];
|
||||
|
||||
BOOL isProjectReady = [self prepareXCodeSupportProject];
|
||||
|
||||
[NSThread detachNewThreadSelector:@selector(populateXCodeProject:) toTarget:self withObject:[NSNumber numberWithBool:!isProjectReady]];
|
||||
|
||||
[self initializeEventStreamWithPath:[currentProjectURL path]];
|
||||
|
||||
NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:path, @"path", [NSNumber numberWithInt:(isProjectReady) ? 1 : 0], @"ready", nil];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:XCCListeningStartNotification object:self userInfo:info];
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] setObject:[currentProjectURL path] forKey:@"LastOpenedPath"];
|
||||
}
|
||||
|
||||
/*!
|
||||
Clean the support folder according to files present in given path
|
||||
*/
|
||||
- (void)tidyShadowedFiles
|
||||
{
|
||||
NSArray *subpaths = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[XCodeSupportProjectSources path] error:NULL];
|
||||
|
||||
for (NSString *subpath in subpaths)
|
||||
{
|
||||
NSString *unshadowed = [[self sourceURLForShadowName:subpath] path];
|
||||
NSString *shadowFullPath = [NSString stringWithFormat:@"%@/%@", [XCodeSupportProjectSources path], subpath];
|
||||
|
||||
if (![fm fileExistsAtPath:unshadowed])
|
||||
{
|
||||
DLog(@"cleaning shadow file: %@", subpath);
|
||||
[fm removeItemAtPath:shadowFullPath error:nil];
|
||||
|
||||
#if DEBUG
|
||||
NSArray *PBXArguments = [NSArray arrayWithObjects: @"-c",
|
||||
[NSString stringWithFormat:@"(%@; python %@ remove '%@' '%@' '%@' '%@') 2>&1",
|
||||
profilePath,
|
||||
PBXModifierScriptPath,
|
||||
XCodeSupportPBXPath,
|
||||
shadowFullPath,
|
||||
unshadowed,
|
||||
[currentProjectURL path]],nil];
|
||||
|
||||
DLog(@"Cleaning PBX reference task...");
|
||||
NSArray *statusInfo = [self runTask:PBXArguments];
|
||||
NSNumber *status = [statusInfo objectAtIndex:0];
|
||||
NSString *response = [statusInfo objectAtIndex:1];
|
||||
#endif
|
||||
DLog(@"PBX Reference cleaning status/response: %@/%@", status, response);
|
||||
|
||||
if (![self supportFileLevelAPI] && [self respondsToSelector:@selector(updateLastModificationDate:forPath:)])
|
||||
[self performSelector:@selector(updateLastModificationDate:forPath:) withObject:nil withObject:unshadowed];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -786,7 +821,7 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
if (!pathModificationDates)
|
||||
{
|
||||
pathModificationDates = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:@"pathModificationDates"] mutableCopy];
|
||||
|
||||
|
||||
if (!pathModificationDates)
|
||||
pathModificationDates = [NSMutableDictionary new];
|
||||
}
|
||||
@@ -804,7 +839,7 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification
|
||||
if (!pathModificationDates)
|
||||
{
|
||||
pathModificationDates = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:@"pathModificationDates"] mutableCopy];
|
||||
|
||||
|
||||
if (!pathModificationDates)
|
||||
pathModificationDates = [NSMutableDictionary new];
|
||||
}
|
||||
|
||||
@@ -194,6 +194,7 @@
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 027D99A313696A7000D3DB13 /* Build configuration list for PBXNativeTarget "XcodeCapp" */;
|
||||
buildPhases = (
|
||||
024699001602C04A00F0AE43 /* ShellScript */,
|
||||
027D999A13696A7000D3DB13 /* Resources */,
|
||||
027D999D13696A7000D3DB13 /* Sources */,
|
||||
02998CF81369C383006C73DB /* CopyFiles */,
|
||||
@@ -255,6 +256,25 @@
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
024699001602C04A00F0AE43 /* ShellScript */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"$(SRCROOT)/*.m",
|
||||
"$(SRCROOT)/*.h",
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /usr/bin/perl;
|
||||
shellScript = "#!/usr/bin/perl\n\nwhile (<>) {\n s/\\s+$//;\n print \"$_\\n\";\n}";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
027D999D13696A7000D3DB13 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
|
||||
@@ -26,7 +26,8 @@ var FILE = require("file");
|
||||
function main(args)
|
||||
{
|
||||
var fileURL = new CFURL(args[1]),
|
||||
outputURL = new CFURL(args[2]),
|
||||
outputHeaderURL = new CFURL(args[2]),
|
||||
outputSourceURL = new CFURL(args[3]),
|
||||
source = FILE.read(fileURL, { charset: "UTF-8" }),
|
||||
flags = ObjectiveJ.Preprocessor.Flags.IncludeDebugSymbols |
|
||||
ObjectiveJ.Preprocessor.Flags.IncludeTypeSignatures,
|
||||
@@ -65,7 +66,8 @@ function main(args)
|
||||
|
||||
eval(source);
|
||||
|
||||
var ObjectiveCSource = "";
|
||||
var ObjectiveCSource = "",
|
||||
ObjectiveCHeader = "";
|
||||
|
||||
classes.forEach(function(aClass)
|
||||
{
|
||||
@@ -104,22 +106,29 @@ function main(args)
|
||||
var className = class_getName(aClass),
|
||||
superClassName = superClasses[className];
|
||||
|
||||
ObjectiveCSource +=
|
||||
ObjectiveCHeader +=
|
||||
"#import <Foundation/Foundation.h>\n" +
|
||||
"#import <Cocoa/Cocoa.h>\n" +
|
||||
"#import \"xcc_general_include.h\"\n" +
|
||||
"\n@interface " + class_getName(aClass) +
|
||||
(superClassName === "Nil" ? "" : (" : " + NSCompatibleClassName(superClassName))) +
|
||||
"\n\n" +
|
||||
outlets.join("\n") +
|
||||
"\n" +
|
||||
actions.join("\n") +
|
||||
"\n@end\n\n"+
|
||||
"\n@end\n";
|
||||
|
||||
ObjectiveCSource +=
|
||||
"#import \"" + outputHeaderURL.absoluteString().replace(/\\/g,'/').replace( /.*\//, '' ) + "\"" +
|
||||
"\n@implementation " + class_getName(aClass) +
|
||||
"\n@end\n";
|
||||
});
|
||||
|
||||
if (ObjectiveCSource.length)
|
||||
FILE.write(outputURL, ObjectiveCSource, { charset:"UTF-8" });
|
||||
FILE.write(outputSourceURL, ObjectiveCSource, { charset:"UTF-8" });
|
||||
|
||||
if (ObjectiveCHeader.length)
|
||||
FILE.write(outputHeaderURL, ObjectiveCHeader, { charset:"UTF-8" });
|
||||
}
|
||||
|
||||
function NSCompatibleClassName(aClassName, asPointer)
|
||||
@@ -127,10 +136,10 @@ function NSCompatibleClassName(aClassName, asPointer)
|
||||
if (aClassName === "var" || aClassName === "id")
|
||||
return "id";
|
||||
|
||||
var suffix = aClassName.substr(0, 2),
|
||||
var prefix = aClassName.substr(0, 2),
|
||||
asterisk = asPointer ? "*" : "";
|
||||
|
||||
if (suffix !== "CP")
|
||||
if (prefix !== "CP")
|
||||
return aClassName + asterisk;
|
||||
|
||||
var NSClassName = "NS" + aClassName.substr(2);
|
||||
@@ -138,9 +147,16 @@ function NSCompatibleClassName(aClassName, asPointer)
|
||||
if (NSClasses[NSClassName])
|
||||
return NSClassName + asterisk;
|
||||
|
||||
if (ReplacementClasses[aClassName])
|
||||
return ReplacementClasses[aClassName] + asterisk;
|
||||
|
||||
return aClassName + asterisk;
|
||||
}
|
||||
|
||||
var ReplacementClasses = {
|
||||
"CPWebView": "WebView"
|
||||
};
|
||||
|
||||
var NSClasses = {
|
||||
"NSAffineTransform" : YES,
|
||||
"NSAppleEventDescriptor" : YES,
|
||||
@@ -486,4 +502,4 @@ var NSClasses = {
|
||||
"NSWindowController" : YES,
|
||||
"NSWorkspace" : YES,
|
||||
"NSPopover": YES
|
||||
};
|
||||
};
|
||||
|
||||
@@ -3,49 +3,58 @@ from mod_pbxproj import XcodeProject
|
||||
|
||||
XCODESUPPORTFOLDER = ".XcodeSupport"
|
||||
|
||||
def add_file(project, shadowGroup, sourceGroup, shadowPath, sourcePath, projectBaseURL):
|
||||
project.add_file(shadowPath, parent=shadowGroup)
|
||||
project.add_file(sourcePath, parent=sourceGroup)
|
||||
project.save()
|
||||
def update_general_include(project, projectBaseURL):
|
||||
xcc_general_include_file = "%s/%s/xcc_general_include.h" % (projectBaseURL, XCODESUPPORTFOLDER)
|
||||
content = ""
|
||||
|
||||
def remove_file(project, shadowGroup, sourceGroup, shadowPath, sourcePath, projectBaseURL):
|
||||
project.remove_file("%s/%s" % (XCODESUPPORTFOLDER, os.path.basename(shadowPath)), parent=shadowGroup)
|
||||
for file in os.listdir("%s/%s" % (projectBaseURL, XCODESUPPORTFOLDER)):
|
||||
if file.endswith(".h"):
|
||||
content += "#include \"%s\"\n" % file
|
||||
|
||||
f = open(xcc_general_include_file, "w")
|
||||
f.write(content)
|
||||
f.close()
|
||||
|
||||
if len(project.get_files_by_os_path("%s/%s" % (XCODESUPPORTFOLDER, os.path.basename(xcc_general_include_file)))) == 0:
|
||||
project.add_file(xcc_general_include_file, parent=shadowGroup)
|
||||
|
||||
|
||||
def add_file(project, shadowGroup, sourceGroup, shadowHeaderPath, shadowImplementationFilePath, sourcePath, projectBaseURL):
|
||||
project.add_file(shadowHeaderPath, parent=shadowGroup)
|
||||
project.add_file(shadowImplementationFilePath, parent=shadowGroup)
|
||||
project.add_file(sourcePath, parent=sourceGroup)
|
||||
|
||||
def remove_file(project, shadowGroup, sourceGroup, shadowHeaderPath, shadowImplementationFilePath, sourcePath, projectBaseURL):
|
||||
project.remove_file("%s/%s" % (XCODESUPPORTFOLDER, os.path.basename(shadowHeaderPath)), parent=shadowGroup)
|
||||
project.remove_file("%s/%s" % (XCODESUPPORTFOLDER, os.path.basename(shadowImplementationFilePath)), parent=shadowGroup)
|
||||
project.remove_file(os.path.relpath(sourcePath, projectBaseURL), parent=sourceGroup)
|
||||
project.save()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
action = sys.argv[1]
|
||||
PBXProjectFilePath = sys.argv[2]
|
||||
shadowFilePath = sys.argv[3]
|
||||
sourceFilePath = sys.argv[4]
|
||||
projectBaseURL = sys.argv[5]
|
||||
|
||||
action = sys.argv[1]
|
||||
PBXProjectFilePath = sys.argv[2]
|
||||
shadowHeaderFilePath = sys.argv[3]
|
||||
shadowImplementationFilePath = sys.argv[4]
|
||||
sourceFilePath = sys.argv[5]
|
||||
projectBaseURL = sys.argv[6]
|
||||
|
||||
project = XcodeProject.Load(PBXProjectFilePath)
|
||||
|
||||
|
||||
shadowGroup = project.get_or_create_group('Classes')
|
||||
sourceGroup = project.get_or_create_group('Sources')
|
||||
|
||||
if "main.m" in shadowFilePath:
|
||||
|
||||
if "main.j" in sourceFilePath:
|
||||
sys.exit(0)
|
||||
|
||||
files = project.get_files_by_os_path("%s/%s" % (XCODESUPPORTFOLDER, os.path.basename(shadowFilePath)))
|
||||
|
||||
files = project.get_files_by_os_path("%s/%s" % (XCODESUPPORTFOLDER, os.path.basename(shadowHeaderFilePath)))
|
||||
|
||||
if action == "add" and len(files) == 0:
|
||||
add_file(project, shadowGroup, sourceGroup, shadowFilePath, sourceFilePath, projectBaseURL)
|
||||
update_general_include(project, projectBaseURL)
|
||||
add_file(project, shadowGroup, sourceGroup, shadowHeaderFilePath, shadowImplementationFilePath, sourceFilePath, projectBaseURL)
|
||||
project.save()
|
||||
|
||||
elif action == "remove" and len(files) == 1:
|
||||
remove_file(project, shadowGroup, sourceGroup, shadowFilePath, sourceFilePath, projectBaseURL)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
update_general_include(project, projectBaseURL)
|
||||
remove_file(project, shadowGroup, sourceGroup, shadowHeaderFilePath, shadowImplementationFilePath, sourceFilePath, projectBaseURL)
|
||||
project.save()
|
||||
|
||||
@@ -269,8 +269,6 @@ var NSButtonIsBorderedMask = 0x00800000,
|
||||
_highlightsBy = [cell highlightsBy];
|
||||
_showsStateBy = [cell showsStateBy];
|
||||
|
||||
[self setTag:[cell tag]];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,9 @@
|
||||
CPLog.debug("NSColorWell: adjusting height from %d to %d", frameSize.height, 24.0);
|
||||
frameSize.height = 24.0;
|
||||
[self setFrameSize:frameSize];
|
||||
|
||||
// Adjust for differences between Cocoa and Cappuccino widget framing.
|
||||
_frame.origin.x -= 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,9 @@
|
||||
size = [self frameSize];
|
||||
|
||||
[self setFrameSize:CGSizeMake(size.width, MIN(size.height, maxSize.height))];
|
||||
|
||||
// Adjust for differences between Cocoa and Cappuccino widget framing.
|
||||
_frame.origin.x += 1;
|
||||
}
|
||||
|
||||
return self;
|
||||
|
||||
@@ -56,6 +56,11 @@
|
||||
[self setLineBreakMode:[cell lineBreakMode]];
|
||||
|
||||
[self setFormatter:[cell formatter]];
|
||||
|
||||
// In IB, both cells and controls can have tags.
|
||||
// If the control has a tag, that takes precedence.
|
||||
if ([aCoder containsValueForKey:@"NSTag"])
|
||||
[self setTag:[aCoder decodeIntForKey:@"NSTag"]];
|
||||
}
|
||||
|
||||
return self;
|
||||
|
||||
@@ -82,6 +82,7 @@ var NSMatrixRadioModeMask = 0x40000000,
|
||||
[self setBackgroundColor:backgroundColor];
|
||||
|
||||
self.isa = [CPView class];
|
||||
NIB_CONNECTION_EQUIVALENCY_TABLE[[self UID]] = radioGroup;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -36,10 +36,10 @@
|
||||
_menu = [cell menu];
|
||||
|
||||
// adjust the frame
|
||||
_frame.origin.x -= 3;
|
||||
_frame.origin.x -= 4;
|
||||
_frame.origin.y -= 4;
|
||||
_frame.size.width += 6;
|
||||
_bounds.size.width += 6;
|
||||
_frame.size.width += 7;
|
||||
_bounds.size.width += 7;
|
||||
|
||||
[self setPullsDown:[cell pullsDown]];
|
||||
_preferredEdge = [cell preferredEdge];
|
||||
|
||||
@@ -57,6 +57,8 @@
|
||||
[self tileWithChangedSegment:i];
|
||||
}
|
||||
|
||||
// Adjust for differences between Cocoa and Cappuccino widget framing.
|
||||
frame.origin.x += 4;
|
||||
frame.size.width = originalWidth;
|
||||
[self setFrame:frame];
|
||||
}
|
||||
|
||||
@@ -38,6 +38,11 @@
|
||||
_valueWraps = [cell valueWraps];
|
||||
_autorepeat = [cell autorepeat];
|
||||
_objectValue = [cell objectValue];
|
||||
|
||||
// Convert Cocoa normal size to Cappuccino normal size.
|
||||
_frame.origin.y += 2;
|
||||
_frame.size.height -= 2;
|
||||
_bounds.size.height -= 2;
|
||||
}
|
||||
|
||||
return self;
|
||||
|
||||
@@ -90,7 +90,8 @@
|
||||
headerView = [[_CPTableColumnHeaderView alloc] initWithFrame:CPRectMakeZero()];
|
||||
|
||||
[headerView setStringValue:[headerCell objectValue]];
|
||||
[headerView setValue:[dataViewCell alignment] forThemeAttribute:@"text-alignment"];
|
||||
[headerView setFont:[headerCell font]];
|
||||
[headerView setAlignment:[headerCell alignment]];
|
||||
|
||||
[self setHeaderView:headerView];
|
||||
|
||||
|
||||
@@ -23,15 +23,20 @@
|
||||
@import <AppKit/_CPCibWindowTemplate.j>
|
||||
|
||||
|
||||
var NSBorderlessWindowMask = 0x00,
|
||||
NSTitledWindowMask = 0x01,
|
||||
NSClosableWindowMask = 0x02,
|
||||
NSMiniaturizableWindowMask = 0x04,
|
||||
NSResizableWindowMask = 0x08,
|
||||
NSUtilityWindowMask = 0x10,
|
||||
NSDocModalWindowMask = 0x40,
|
||||
NSTexturedBackgroundWindowMask = 0x100,
|
||||
NSHUDBackgroundWindowMask = 0x2000,
|
||||
var NSBorderlessWindowMask = 0x00,
|
||||
NSTitledWindowMask = 0x01,
|
||||
NSClosableWindowMask = 0x02,
|
||||
NSMiniaturizableWindowMask = 0x04,
|
||||
NSResizableWindowMask = 0x08,
|
||||
NSUtilityWindowMask = 0x10,
|
||||
NSDocModalWindowMask = 0x40,
|
||||
NSTexturedBackgroundWindowMask = 0x100,
|
||||
NSHUDBackgroundWindowMask = 0x2000,
|
||||
|
||||
NSPositionFlexibleRight = 1 << 19,
|
||||
NSPositionFlexibleLeft = 1 << 20,
|
||||
NSPositionFlexibleBottom = 1 << 21,
|
||||
NSPositionFlexibleTop = 1 << 22,
|
||||
|
||||
NSAutorecalculatesKeyViewLoopWTFlag = 0x800;
|
||||
|
||||
|
||||
@@ -466,8 +466,18 @@ global.sudo = function(/*Array or String*/ command)
|
||||
// First try without sudo
|
||||
command = normalizeCommand(command);
|
||||
|
||||
if (OS.system(command + " >/dev/null 2>&1"))
|
||||
var returnCode = OS.system(command + " >/dev/null 2>&1")
|
||||
|
||||
if (returnCode)
|
||||
{
|
||||
// if this is set, then disable the use of sudo.
|
||||
// This is very usefull for CI scripts and stuff like that
|
||||
if (SYSTEM.env["CAPP_NOSUDO"] == 1)
|
||||
return returnCode;
|
||||
|
||||
return OS.system("sudo -p '\nEnter your admin password: ' " + command);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||