From 6671d371e95c46935f94e0d0a85f7929ca172dab Mon Sep 17 00:00:00 2001 From: daboe01 Date: Sun, 15 Mar 2026 08:51:03 +0100 Subject: [PATCH 1/3] fixed: treeview binding issues --- AppKit/CPOutlineView.j | 72 +++++++++++++++--------------------------- AppKit/CPTableView.j | 23 ++++++++++---- 2 files changed, 42 insertions(+), 53 deletions(-) diff --git a/AppKit/CPOutlineView.j b/AppKit/CPOutlineView.j index d13bdd1fe..0380ad91d 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 item; + 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 []; } @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..c37356ef7 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 From 43936f640ce38bcbc7a26da50a53bfdb6ad71978 Mon Sep 17 00:00:00 2001 From: daboe01 Date: Sun, 15 Mar 2026 08:53:04 +0100 Subject: [PATCH 2/3] formatting --- AppKit/CPOutlineView.j | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/AppKit/CPOutlineView.j b/AppKit/CPOutlineView.j index 0380ad91d..8b00173d3 100644 --- a/AppKit/CPOutlineView.j +++ b/AppKit/CPOutlineView.j @@ -2454,12 +2454,12 @@ var colorForDisclosureTriangle = function(isSelected, isHighlighted) - (id)outlineView:(CPOutlineView)outlineView objectValueForTableColumn:(CPTableColumn)tableColumn byItem:(id)item { - var rep =[item respondsToSelector:@selector(representedObject)] ? [item representedObject] : 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] &&[tableColumn identifier] !== @"") + if (rep && [tableColumn identifier] && [tableColumn identifier] !== @"") return [rep valueForKey:[tableColumn identifier]]; - + return rep; } From b77a374f485f6b2dd0a386a7c770a1e9a97e93dd Mon Sep 17 00:00:00 2001 From: daboe01 Date: Sun, 15 Mar 2026 08:57:06 +0100 Subject: [PATCH 3/3] formatting --- AppKit/CPTableView.j | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index c37356ef7..5512e974a 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -3631,7 +3631,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad if (_implementedDataSourceMethods & CPTableViewDataSource_tableView_objectValueForTableColumn_row_) { - var objectValue =[self _objectValueForTableColumn:aTableColumn row:aRow useCache:useCache]; + var objectValue = [self _objectValueForTableColumn:aTableColumn row:aRow useCache:useCache]; [aDataView setObjectValue:objectValue]; providedByDataSource = YES; }