diff --git a/AppKit/CPOutlineView.j b/AppKit/CPOutlineView.j index 7c396f1f9..df90c688d 100644 --- a/AppKit/CPOutlineView.j +++ b/AppKit/CPOutlineView.j @@ -216,7 +216,7 @@ CPOutlineViewDropOnItemIndex = -1; - (void)expandItem:(id)anItem expandChildren:(BOOL)shouldExpandChildren { var itemInfo = null; - + if (!anItem) itemInfo = _rootItemInfo; else @@ -224,10 +224,16 @@ CPOutlineViewDropOnItemIndex = -1; if (!itemInfo) return; - - itemInfo.isExpanded = YES; - [self reloadItem:anItem reloadChildren:YES]; - + + // to prevent items which are already expanded from firing notifications + if (!itemInfo.isExpanded) + { + [self _noteItemWillExpand:anItem]; + itemInfo.isExpanded = YES; + [self _noteItemDidExpand:anItem]; + [self reloadItem:anItem reloadChildren:YES]; + } + if (shouldExpandChildren) { var children = itemInfo.children, @@ -251,7 +257,9 @@ CPOutlineViewDropOnItemIndex = -1; if (!itemInfo.isExpanded) return; + [self _noteItemWillCollapse:anItem]; itemInfo.isExpanded = NO; + [self _noteItemDidCollapse:anItem]; [self reloadItem:anItem reloadChildren:YES]; } @@ -427,6 +435,35 @@ CPOutlineViewDropOnItemIndex = -1; removeObserver:_outlineViewDelegate name:CPOutlineViewSelectionIsChangingNotification object:self]; + + + + if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemWillExpand:)]) + [defaultCenter + removeObserver:_outlineViewDelegate + name:CPOutlineViewItemWillExpandNotification + object:self]; + + + if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemDidExpand:)]) + [defaultCenter + removeObserver:_outlineViewDelegate + name:CPOutlineViewItemDidExpandNotification + object:self]; + + + if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemWillCollapse:)]) + [defaultCenter + removeObserver:_outlineViewDelegate + name:CPOutlineViewItemWillCollapseNotification + object:self]; + + + if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemDidCollapse:)]) + [defaultCenter + removeObserver:_outlineViewDelegate + name:CPOutlineViewItemDidCollapseNotification + object:self]; } _outlineViewDelegate = aDelegate; @@ -474,6 +511,36 @@ CPOutlineViewDropOnItemIndex = -1; selector:@selector(outlineViewSelectionIsChanging:) name:CPOutlineViewSelectionIsChangingNotification object:self]; + + + if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemWillExpand:)]) + [defaultCenter + addObserver:_outlineViewDelegate + selector:@selector(outlineViewItemWillExpand:) + name:CPOutlineViewItemWillExpandNotification + object:self]; + + if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemDidExpand:)]) + [defaultCenter + addObserver:_outlineViewDelegate + selector:@selector(outlineViewItemDidExpand:) + name:CPOutlineViewItemDidExpandNotification + object:self]; + + if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemWillCollapse:)]) + [defaultCenter + addObserver:_outlineViewDelegate + selector:@selector(outlineViewItemWillCollapse:) + name:CPOutlineViewItemWillCollapseNotification + object:self]; + + if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemDidCollapse:)]) + [defaultCenter + addObserver:_outlineViewDelegate + selector:@selector(outlineViewItemDidCollapse:) + name:CPOutlineViewItemDidCollapseNotification + object:self]; + } - (id)delegate @@ -536,6 +603,12 @@ CPOutlineViewDropOnItemIndex = -1; _retargedChildIndex = theIndex; _shouldRetargetChildIndex = YES; + + // set CPTableView's _retargetedDropRow based on retargetedItem and retargetedChildIndex + var retargetedItemInfo = (_retargetedItem !== nil) ? _itemInfosForItems[[_retargetedItem UID]] : _rootItemInfo, + retargetedChildItem = (_retargedChildIndex !== CPOutlineViewDropOnItemIndex) ? retargetedItemInfo.children[_retargedChildIndex] : _retargetedItem; + + _retargetedDropRow = [self rowForItem:retargetedChildItem]; } - (void)_draggingEnded @@ -716,6 +789,38 @@ CPOutlineViewDropOnItemIndex = -1; userInfo:nil]; } +- (void)_noteItemWillExpand:(id)item +{ + [[CPNotificationCenter defaultCenter] + postNotificationName:CPOutlineViewItemWillExpandNotification + object:self + userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]]; +} + +- (void)_noteItemDidExpand:(id)item +{ + [[CPNotificationCenter defaultCenter] + postNotificationName:CPOutlineViewItemDidExpandNotification + object:self + userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]]; +} + +- (void)_noteItemWillCollapse:(id)item +{ + [[CPNotificationCenter defaultCenter] + postNotificationName:CPOutlineViewItemWillCollapseNotification + object:self + userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]]; +} + +- (void)_noteItemDidCollapse:(id)item +{ + [[CPNotificationCenter defaultCenter] + postNotificationName:CPOutlineViewItemDidCollapseNotification + object:self + userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]]; +} + @end // FIX ME: We're using with() here because Safari fails if we use anOutlineView._itemInfosForItems or whatever... @@ -887,6 +992,13 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt return [_outlineView._outlineViewDataSource outlineView:_outlineView objectValueForTableColumn:aTableColumn byItem:_outlineView._itemsForRows[aRow]]; } +- (void)tableView:(CPTableView)aTableView setObjectValue:(id)aValue forTableColumn:(CPTableColumn)aColumn row:(CPInteger)aRow +{ + if (!(_outlineView._implementedOutlineViewDataSourceMethods & CPOutlineViewDataSource_outlineView_setObjectValue_forTableColumn_byItem_)) + return; + [_outlineView._outlineViewDataSource outlineView:_outlineView setObjectValue:aValue forTableColumn:aColumn byItem:_outlineView._itemsForRows[aRow]]; +} + - (BOOL)tableView:(CPTableView)aTableColumn writeRowsWithIndexes:(CPIndexSet)theIndexes toPasteboard:(CPPasteboard)thePasteboard { if (!(_outlineView._implementedOutlineViewDataSourceMethods & CPOutlineViewDataSource_outlineView_writeItems_toPasteboard_)) @@ -1014,6 +1126,14 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt return YES; } +- (BOOL)tableView:(CPTableView)aTableView shouldEditTableColumn:(CPTableColumn)aColumn row:(int)aRow +{ + if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_shouldEditTableColumn_item_)) + return [_outlineView._outlineViewDelegate outlineView:_outlineView shouldEditTableColumn:aColumn item:[_outlineView itemAtRow:aRow]]; + + return NO; +} + - (float)tableView:(CPTableView)theTableView heightOfRow:(int)theRow { if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_heightOfRowByItem_)) diff --git a/AppKit/CPTableColumn.j b/AppKit/CPTableColumn.j index 2d4e5af03..e8b6f1c5e 100644 --- a/AppKit/CPTableColumn.j +++ b/AppKit/CPTableColumn.j @@ -81,8 +81,8 @@ CPTableColumnUserResizingMask = 1 << 1; var textDataView = [CPTextField new]; [textDataView setLineBreakMode:CPLineBreakByTruncatingTail]; [textDataView setValue:[CPColor colorWithHexString:@"333333"] forThemeAttribute:@"text-color"]; - [textDataView setValue:[CPColor whiteColor] forThemeAttribute:@"text-color" inState:CPThemeStateSelected]; - [textDataView setValue:[CPFont boldSystemFontOfSize:12] forThemeAttribute:@"font" inState:CPThemeStateSelected]; + [textDataView setValue:[CPColor whiteColor] forThemeAttribute:@"text-color" inState:CPThemeStateSelectedDataView]; + [textDataView setValue:[CPFont boldSystemFontOfSize:12] forThemeAttribute:@"font" inState:CPThemeStateSelectedDataView]; [textDataView setValue:CPCenterVerticalTextAlignment forThemeAttribute:@"vertical-alignment"]; [self setDataView:textDataView]; } diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index 75e096ce5..2ef0dde9b 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -28,7 +28,6 @@ @import "_CPCornerView.j" @import "CPScroller.j" - CPTableViewColumnDidMoveNotification = @"CPTableViewColumnDidMoveNotification"; CPTableViewColumnDidResizeNotification = @"CPTableViewColumnDidResizeNotification"; CPTableViewSelectionDidChangeNotification = @"CPTableViewSelectionDidChangeNotification"; @@ -866,7 +865,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; var view = context[rowIndex], selector = select ? @"setThemeState:" : @"unsetThemeState:"; - [view performSelector:CPSelectorFromString(selector) withObject:CPThemeStateSelected]; + [view performSelector:CPSelectorFromString(selector) withObject:CPThemeStateSelectedDataView]; } - (void)_updateHighlightWithOldColumns:(CPIndexSet)oldColumns newColumns:(CPIndexSet)newColumns @@ -896,7 +895,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; { var rowIndex = selectRows[i], dataView = dataViewsInTableColumn[rowIndex]; - [dataView unsetThemeState:CPThemeStateSelected]; + [dataView unsetThemeState:CPThemeStateSelectedDataView]; } if (_headerView) @@ -917,7 +916,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; { var rowIndex = selectRows[i], dataView = dataViewsInTableColumn[rowIndex]; - [dataView setThemeState:CPThemeStateSelected]; + [dataView setThemeState:CPThemeStateSelectedDataView]; } if (_headerView) { @@ -1025,12 +1024,44 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; /* * - preparedCellAtColumn:row: */ + //Editing Cells -/* - * - editColumn:row:withEvent:select: - * - editedColumn - * - editedRow + +/*! + Edits the indicated row. */ +- (void)editColumn:(CPInteger)columnIndex row:(CPInteger)rowIndex withEvent:(CPEvent)theEvent select:(BOOL)flag +{ + if (![self isRowSelected:rowIndex]) + [[CPException exceptionWithName:@"Error" reason:@"Attempt to edit row="+rowIndex+" when not selected." userInfo:nil] raise]; + + // TODO Do something with flag. + + _editingCellIndex = CGPointMake(columnIndex, rowIndex); + [self reloadDataForRowIndexes:[CPIndexSet indexSetWithIndex:rowIndex] + columnIndexes:[CPIndexSet indexSetWithIndex:columnIndex]]; +} + +/*! + Returns the column of the currently edited cell, or -1 if none. +*/ +- (CPInteger)editedColumn +{ + if (!_editingCellIndex) + return -1; + return _editingCellIndex.x; +} + +/*! + Returns the row of the currently edited cell, or -1 if none. +*/ +- (CPInteger)editedRow +{ + if (!_editingCellIndex) + return -1; + return _editingCellIndex.x; +} + //Setting Auxiliary Views /* * - setHeaderView: @@ -1469,8 +1500,19 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; - (void)noteNumberOfRowsChanged { + var oldNumberOfRows = _numberOfRows; + _numberOfRows = [_dataSource numberOfRowsInTableView:self]; + // remove row indexes from the selection if they no longer exist + var hangingSelections = oldNumberOfRows - _numberOfRows; + + if (hangingSelections > 0) + { + [_selectedRowIndexes removeIndexesInRange:CPMakeRange(_numberOfRows, hangingSelections)]; + [self _noteSelectionDidChange]; + } + [self tile]; } @@ -1692,6 +1734,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; if (_allowsColumnSelection) { + [self _noteSelectionIsChanging]; if (modifierFlags & CPCommandKeyMask) { if ([self isColumnSelected:clickedColumn]) @@ -1794,7 +1837,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; if (_headerView) { if (_currentHighlightedTableColumn != nil) - [[_currentHighlightedTableColumn headerView] unsetThemeState:CPThemeStateSelected]; + [[_currentHighlightedTableColumn headerView] unsetThemeState:CPThemeStateSelectedDataView]; if (aTableColumn != nil) [[aTableColumn headerView] setThemeState:CPThemeStateSelected]; @@ -2168,9 +2211,9 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; [dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]]; if (isColumnSelected || [self isRowSelected:row]) - [dataView setThemeState:CPThemeStateSelected]; + [dataView setThemeState:CPThemeStateSelectedDataView]; else - [dataView unsetThemeState:CPThemeStateSelected]; + [dataView unsetThemeState:CPThemeStateSelectedDataView]; if (_implementedDelegateMethods & CPTableViewDelegate_tableView_willDisplayView_forTableColumn_row_) [_delegate tableView:self willDisplayView:dataView forTableColumn:tableColumn row:row]; @@ -2454,7 +2497,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; - (void)highlightSelectionInClipRect:(CGRect)aRect { - if (_selectionHighlightStyle === CPTableViewDraggingDestinationFeedbackStyleNone) + if (_selectionHighlightStyle === CPTableViewSelectionHighlightStyleNone) return; var context = [[CPGraphicsContext currentContext] graphicsPort], @@ -2814,10 +2857,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; shouldEdit = [_delegate tableView:self shouldEditTableColumn:column row:rowIndex]; if (shouldEdit) { - _editingCellIndex = CGPointMake(columnIndex, rowIndex); - [self reloadDataForRowIndexes:[CPIndexSet indexSetWithIndex:rowIndex] - columnIndexes:[CPIndexSet indexSetWithIndex:columnIndex]]; - + [self editColumn:columnIndex row:rowIndex withEvent:nil select:YES]; return; } } diff --git a/AppKit/CPTheme.j b/AppKit/CPTheme.j index 77bac886d..4b37e6d7a 100644 --- a/AppKit/CPTheme.j +++ b/AppKit/CPTheme.j @@ -242,6 +242,7 @@ CPThemeStateNormal = CPThemeStates["normal"] = 0; CPThemeStateDisabled = CPThemeState("disabled"); CPThemeStateHighlighted = CPThemeState("highlighted"); CPThemeStateSelected = CPThemeState("selected"); +CPThemeStateSelectedDataView = CPThemeState("selectedDataView"); CPThemeStateBezeled = CPThemeState("bezeled"); CPThemeStateBordered = CPThemeState("bordered"); CPThemeStateEditable = CPThemeState("editable"); diff --git a/Foundation/CPUndoManager.j b/Foundation/CPUndoManager.j index 7d9c8d8f0..94b9f6516 100644 --- a/Foundation/CPUndoManager.j +++ b/Foundation/CPUndoManager.j @@ -317,8 +317,8 @@ if (_currentGroup == nil) { if (_undoStack.length > 0) return YES; - - return [_currentGrouping actions].length > 0; + + return [[_currentGrouping invocations] count] > 0; } // Preform Undo and Redo