diff --git a/AppKit/CPOutlineView.j b/AppKit/CPOutlineView.j index d13bdd1fe..8b00173d3 100644 --- a/AppKit/CPOutlineView.j +++ b/AppKit/CPOutlineView.j @@ -2413,7 +2413,7 @@ var colorForDisclosureTriangle = function(isSelected, isHighlighted) - (void)setValueFor:(CPString)aBinding { var destination = [_info objectForKey:CPObservedObjectKey], - keyPath =[_info objectForKey:CPObservedKeyPathKey], + keyPath = [_info objectForKey:CPObservedKeyPathKey], value = [destination valueForKeyPath:keyPath]; if (!value || ![value isKindOfClass:[CPTreeNode class]]) @@ -2421,19 +2421,10 @@ var colorForDisclosureTriangle = function(isSelected, isHighlighted) else _rootNode = value; - // Because CPBinder triggers setValueFor: synchronously during its initialization - // (before -bind is ever called), we must lazily assign the data source here. if ([_source dataSource] !== self) - { - // Assigning the data source automatically triggers [_source reloadData] - // inside CPOutlineView, so we don't need to call it manually here. [_source setDataSource:self]; - } else - { - // If it was already set, we just manually trigger the reload. [_source reloadData]; - } } - (CPTreeNode)rootNode @@ -2463,10 +2454,31 @@ var colorForDisclosureTriangle = function(isSelected, isHighlighted) - (id)outlineView:(CPOutlineView)outlineView objectValueForTableColumn:(CPTableColumn)tableColumn byItem:(id)item { - if ([item respondsToSelector:@selector(representedObject)]) - return [item representedObject]; + var rep = [item respondsToSelector:@selector(representedObject)] ? [item representedObject] : item; + + // Dynamically fetch the value using the column's identifier (e.g., "name") + if (rep && [tableColumn identifier] && [tableColumn identifier] !== @"") + return [rep valueForKey:[tableColumn identifier]]; + + return rep; +} + +- (void)outlineView:(CPOutlineView)outlineView setObjectValue:(id)value forTableColumn:(CPTableColumn)tableColumn byItem:(id)item +{ + var rep = [item respondsToSelector:@selector(representedObject)] ?[item representedObject] : item; + + // Push the inline edit back to the model using the column's identifier + if (rep && [tableColumn identifier] && [tableColumn identifier] !== @"") + [rep setValue:value forKey:[tableColumn identifier]]; +} + +- (id)content +{ + // CPTableView internals probe the binder for its flat content to draw rows. + if (_source && _source._itemsForRows) + return _source._itemsForRows; - return item; + return []; } @end @@ -2566,37 +2578,3 @@ var colorForDisclosureTriangle = function(isSelected, isHighlighted) @end -@implementation _CPOutlineViewContentBinder (DynamicColumns) - -- (id)outlineView:(CPOutlineView)outlineView objectValueForTableColumn:(CPTableColumn)tableColumn byItem:(id)item -{ - var rep = [item respondsToSelector:@selector(representedObject)] ? [item representedObject] : item; - - // Dynamically fetch the value using the column's identifier (e.g., "name") - if (rep && [tableColumn identifier]) - return [rep valueForKey:[tableColumn identifier]]; - - return rep; -} - -// Add this to support inline bidirectional editing in the outline view -- (void)outlineView:(CPOutlineView)outlineView setObjectValue:(id)value forTableColumn:(CPTableColumn)tableColumn byItem:(id)item -{ - var rep = [item respondsToSelector:@selector(representedObject)] ?[item representedObject] : item; - - // Push the inline edit back to the model using the column's identifier - if (rep && [tableColumn identifier]) - [rep setValue:value forKey:[tableColumn identifier]]; -} - -- (id)content -{ - // CPTableView internals probe the binder for its flat content to draw rows. - // For an outline view, the flat content is exactly the internally mapped items for rows. - if (_source && _source._itemsForRows) - return _source._itemsForRows; - - return []; -} - -@end diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index fcef50846..5512e974a 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -3627,17 +3627,28 @@ Your delegate can implement this method to avoid subclassing the tableview to ad - (void)_setObjectValueForTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRow forView:(CPView)aDataView useCache:(BOOL)useCache { + var providedByDataSource = NO; + if (_implementedDataSourceMethods & CPTableViewDataSource_tableView_objectValueForTableColumn_row_) - [aDataView setObjectValue:[self _objectValueForTableColumn:aTableColumn row:aRow useCache:useCache]]; + { + var objectValue = [self _objectValueForTableColumn:aTableColumn row:aRow useCache:useCache]; + [aDataView setObjectValue:objectValue]; + providedByDataSource = YES; + } // This gives the table column an opportunity to apply its bindings. - // It will override the value set above if there is a binding. + // It will override the value set above if there is an explicit column binding. + var columnHasBindings = [[[CPBinder allBindingsForObject:aTableColumn] allKeys] count] > 0; - if (_contentBindingExplicitlySet) - [self _prepareContentBindedDataView:aDataView forRow:aRow]; - else - // For both cell-based and view-based + if (columnHasBindings) + { [aTableColumn _prepareDataView:aDataView forRow:aRow]; + } + // Only forcefully bind the raw content object if the data source didn't already provide a formatted value + else if (_contentBindingExplicitlySet && !providedByDataSource) + { + [self _prepareContentBindedDataView:aDataView forRow:aRow]; + } } - (void)_prepareContentBindedDataView:(CPView)dataView forRow:(CPInteger)aRow