Update internal data source to collect items properly

This commit is contained in:
Gregory John Casamento 2023-07-22 17:39:22 -04:00
parent 1829525175
commit 48ea6692e1

View file

@ -60,6 +60,7 @@
#import "AppKit/NSImage.h" #import "AppKit/NSImage.h"
#import "AppKit/NSKeyValueBinding.h" #import "AppKit/NSKeyValueBinding.h"
#import "AppKit/NSOutlineView.h" #import "AppKit/NSOutlineView.h"
#import "AppKit/NSPasteboard.h"
#import "AppKit/NSScroller.h" #import "AppKit/NSScroller.h"
#import "AppKit/NSTableColumn.h" #import "AppKit/NSTableColumn.h"
#import "AppKit/NSTableHeaderView.h" #import "AppKit/NSTableHeaderView.h"
@ -104,11 +105,13 @@ static NSDate *lastDragChange = nil;
NSString *_childrenKeyPath; NSString *_childrenKeyPath;
NSString *_leafKeyPath; NSString *_leafKeyPath;
NSMutableDictionary *_internalRepresentation;
id _observedObject; id _observedObject;
NSOutlineView *_outlineView; NSOutlineView *_outlineView;
} }
- (instancetype) initWithOutlineView: (NSOutlineView *)ov; - (instancetype) initWithOutlineView: (NSOutlineView *)ov;
- (void) collectNodes;
@end @end
@ -252,7 +255,12 @@ static NSImage *unexpandable = nil;
if (theBinding != nil) if (theBinding != nil)
{ {
_bindingDataSource = [[GSOutlineViewBindingDataSource alloc] initWithOutlineView: self]; _bindingDataSource = [[GSOutlineViewBindingDataSource alloc] initWithOutlineView: self];
NSLog(@"A binding data source was created %@", _bindingDataSource); RETAIN(_bindingDataSource);
NSDebugLog(@"A binding data source was created %@", _bindingDataSource);
}
else
{
NSDebugLog(@"No binding...");
} }
_internalDataSource = (_bindingDataSource != nil) ? _bindingDataSource : _dataSource; _internalDataSource = (_bindingDataSource != nil) ? _bindingDataSource : _dataSource;
@ -746,7 +754,6 @@ static NSImage *unexpandable = nil;
// If the binding is present, the data source becomes like a delegate // If the binding is present, the data source becomes like a delegate
if (_bindingDataSource == nil) if (_bindingDataSource == nil)
{ {
NSLog(@"Checking methods");
CHECK_REQUIRED_METHOD(outlineView:child:ofItem:); CHECK_REQUIRED_METHOD(outlineView:child:ofItem:);
CHECK_REQUIRED_METHOD(outlineView:isItemExpandable:); CHECK_REQUIRED_METHOD(outlineView:isItemExpandable:);
CHECK_REQUIRED_METHOD(outlineView:numberOfChildrenOfItem:); CHECK_REQUIRED_METHOD(outlineView:numberOfChildrenOfItem:);
@ -759,10 +766,14 @@ static NSImage *unexpandable = nil;
/* We do *not* retain the dataSource, it's like a delegate */ /* We do *not* retain the dataSource, it's like a delegate */
_dataSource = anObject; _dataSource = anObject;
_internalDataSource = anObject; // override the binding data source if it was created...
NSLog(@"_bindingDataSource = %@", _bindingDataSource); if (_internalDataSource == nil)
NSLog(@"dataSource = %@", _dataSource); {
_internalDataSource = anObject; // override the binding data source if it was created...
}
NSDebugLog(@"_bindingDataSource = %@", _bindingDataSource);
NSDebugLog(@"dataSource = %@", _dataSource);
[self tile]; [self tile];
[self reloadData]; [self reloadData];
@ -798,6 +809,11 @@ static NSImage *unexpandable = nil;
NSObjectMapValueCallBacks, NSObjectMapValueCallBacks,
64); 64);
if ([_internalDataSource respondsToSelector: @selector(collectNodes)])
{
[_internalDataSource collectNodes];
}
// reload all the open items... // reload all the open items...
[self _openItem: nil]; [self _openItem: nil];
[super reloadData]; [super reloadData];
@ -1039,7 +1055,6 @@ static NSImage *unexpandable = nil;
- (NSDragOperation) draggingEntered: (id <NSDraggingInfo>) sender - (NSDragOperation) draggingEntered: (id <NSDraggingInfo>) sender
{ {
//NSLog(@"draggingEntered");
oldDropItem = currentDropItem = nil; oldDropItem = currentDropItem = nil;
oldDropIndex = currentDropIndex = -1; oldDropIndex = currentDropIndex = -1;
lastVerticalQuarterPosition = -1; lastVerticalQuarterPosition = -1;
@ -1243,7 +1258,6 @@ Also returns the child index relative to this parent. */
ASSIGN(lastDragUpdate, [NSDate date]); ASSIGN(lastDragUpdate, [NSDate date]);
//NSLog(@"draggingUpdated");
/* _bounds.origin is (0, 0) when the outline view is not clipped. /* _bounds.origin is (0, 0) when the outline view is not clipped.
* When the view is scrolled, _bounds.origin.y returns the scrolled height. */ * When the view is scrolled, _bounds.origin.y returns the scrolled height. */
@ -1261,10 +1275,6 @@ Also returns the child index relative to this parent. */
positionInRow = 1; // inside the root item (we could also use 2) positionInRow = 1; // inside the root item (we could also use 2)
} }
//NSLog(@"horizontalHalfPosition = %d", horizontalHalfPosition);
//NSLog(@"verticalQuarterPosition = %d", verticalQuarterPosition);
//NSLog(@"insertion row = %d", row);
if (row == 0) if (row == 0)
{ {
levelBefore = 0; levelBefore = 0;
@ -1281,8 +1291,6 @@ Also returns the child index relative to this parent. */
{ {
levelAfter = [self levelForRow: row]; levelAfter = [self levelForRow: row];
} }
//NSLog(@"level before = %d", levelBefore);
//NSLog(@"level after = %d", levelAfter);
if ((lastVerticalQuarterPosition != verticalQuarterPosition) if ((lastVerticalQuarterPosition != verticalQuarterPosition)
|| (lastHorizontalHalfPosition != horizontalHalfPosition)) || (lastHorizontalHalfPosition != horizontalHalfPosition))
@ -1331,11 +1339,6 @@ Also returns the child index relative to this parent. */
level = pointerInsertionLevel; level = pointerInsertionLevel;
} }
//NSLog(@"min insert level = %d", minInsertionLevel);
//NSLog(@"max insert level = %d", maxInsertionLevel);
//NSLog(@"insert level = %d", level);
//NSLog(@"row = %d and position in row = %d", row, positionInRow);
if (positionInRow > 0 && positionInRow < 3) /* Drop on */ if (positionInRow > 0 && positionInRow < 3) /* Drop on */
{ {
/* We are directly over the middle of a row ... so the drop /* We are directly over the middle of a row ... so the drop
@ -1351,8 +1354,6 @@ Also returns the child index relative to this parent. */
atLevel: level atLevel: level
andReturnChildIndex: &childIndex]; andReturnChildIndex: &childIndex];
//NSLog(@"found %d (proposed childIndex = %d)", parentRow, childIndex);
currentDropItem = (parentRow == -1 ? nil : [self itemAtRow: parentRow]); currentDropItem = (parentRow == -1 ? nil : [self itemAtRow: parentRow]);
currentDropIndex = childIndex; currentDropIndex = childIndex;
} }
@ -1366,8 +1367,6 @@ Also returns the child index relative to this parent. */
proposedChildIndex: currentDropIndex]; proposedChildIndex: currentDropIndex];
} }
//NSLog(@"Drop on %@ %d", currentDropItem, currentDropIndex);
if ((currentDropItem != oldDropItem) if ((currentDropItem != oldDropItem)
|| (currentDropIndex != oldDropIndex)) || (currentDropIndex != oldDropIndex))
{ {
@ -1849,16 +1848,8 @@ Also returns the child index relative to this parent. */
row: (NSInteger) index row: (NSInteger) index
{ {
id result = nil; id result = nil;
GSKeyValueBinding *binding =
[GSKeyValueBinding getBinding: NSValueBinding
forObject: tb];
if (binding != nil) if ([_internalDataSource respondsToSelector:
{
result = [(NSArray *)[binding destinationValue]
objectAtIndex: index];
}
else if ([_internalDataSource respondsToSelector:
@selector(outlineView:objectValueForTableColumn:byItem:)]) @selector(outlineView:objectValueForTableColumn:byItem:)])
{ {
id item = [self itemAtRow: index]; id item = [self itemAtRow: index];
@ -1868,8 +1859,6 @@ Also returns the child index relative to this parent. */
byItem: item]; byItem: item];
} }
NSLog(@"RESULT ======= %@, class = %@", result, NSStringFromClass([result class]));
return result; return result;
} }
@ -1891,12 +1880,6 @@ Also returns the child index relative to this parent. */
- (NSInteger) _numRows - (NSInteger) _numRows
{ {
/*
if (_theBinding != nil)
{
return [(NSArray *)[_theBinding destinationValue] count];
}
*/
return [_items count]; return [_items count];
} }
@ -1968,7 +1951,6 @@ Also returns the child index relative to this parent. */
id sitem = (startitem == nil) ? (id)[NSNull null] : (id)startitem; id sitem = (startitem == nil) ? (id)[NSNull null] : (id)startitem;
NSArray *anarray = NSMapGet(_itemDict, sitem); NSArray *anarray = NSMapGet(_itemDict, sitem);
NSLog(@"anarray = %@", anarray);
FOR_IN(id, anitem, anarray) FOR_IN(id, anitem, anarray)
{ {
// Only collect the children if the item is expanded // Only collect the children if the item is expanded
@ -2006,8 +1988,6 @@ Also returns the child index relative to this parent. */
BOOL expandable = YES; BOOL expandable = YES;
NSInteger i = 0; NSInteger i = 0;
NSLog(@"_internalDataSource = %@", _internalDataSource);
// See if the item is expandable... // See if the item is expandable...
if ([_internalDataSource respondsToSelector: @selector(outlineView:isItemExpandable:)]) if ([_internalDataSource respondsToSelector: @selector(outlineView:isItemExpandable:)])
{ {
@ -2095,11 +2075,8 @@ Also returns the child index relative to this parent. */
object = NSMapGet(_itemDict, sitem); object = NSMapGet(_itemDict, sitem);
NSLog(@"object = %@", object);
numChildren = numDescendants = [object count]; numChildren = numDescendants = [object count];
NSLog(@"numChildren = %ld", numChildren);
insertionPoint = [_items indexOfObjectIdenticalTo: item]; insertionPoint = [_items indexOfObjectIdenticalTo: item];
if (insertionPoint == NSNotFound) if (insertionPoint == NSNotFound)
{ {
@ -2293,7 +2270,10 @@ Also returns the child index relative to this parent. */
// _mapTable = RETAIN([NSMapTable strongToStrongObjectsMapTable]); // _mapTable = RETAIN([NSMapTable strongToStrongObjectsMapTable]);
_outlineView = ov; // don't retain, so we don't have a circular reference. _outlineView = ov; // don't retain, so we don't have a circular reference.
_theBinding = [GSKeyValueBinding getBinding: NSContentBinding _theBinding = [GSKeyValueBinding getBinding: NSContentBinding
forObject: self]; forObject: ov];
if (_theBinding != nil)
{
_observedObject = [_theBinding observedObject]; _observedObject = [_theBinding observedObject];
if ([_observedObject isKindOfClass: [NSTreeController class]]) if ([_observedObject isKindOfClass: [NSTreeController class]])
@ -2303,6 +2283,8 @@ Also returns the child index relative to this parent. */
ASSIGNCOPY(_leafKeyPath, [tc leafKeyPath]); ASSIGNCOPY(_leafKeyPath, [tc leafKeyPath]);
ASSIGNCOPY(_childrenKeyPath, [tc childrenKeyPath]); ASSIGNCOPY(_childrenKeyPath, [tc childrenKeyPath]);
ASSIGNCOPY(_countKeyPath, [tc countKeyPath]); ASSIGNCOPY(_countKeyPath, [tc countKeyPath]);
_internalRepresentation = [[NSMutableDictionary alloc] init];
} }
else else
{ {
@ -2312,6 +2294,12 @@ Also returns the child index relative to this parent. */
NSLog(@"_observedObject = %@, leafKeyPath = %@, childrenKeyPath = %@, countKeyPath = %@", NSLog(@"_observedObject = %@, leafKeyPath = %@, childrenKeyPath = %@, countKeyPath = %@",
_observedObject, _leafKeyPath, _childrenKeyPath, _countKeyPath); _observedObject, _leafKeyPath, _childrenKeyPath, _countKeyPath);
} }
else
{
NSLog(@"No binding found...");
return nil;
}
}
return self; return self;
} }
@ -2321,56 +2309,57 @@ Also returns the child index relative to this parent. */
RELEASE(_leafKeyPath); RELEASE(_leafKeyPath);
RELEASE(_childrenKeyPath); RELEASE(_childrenKeyPath);
RELEASE(_countKeyPath); RELEASE(_countKeyPath);
RELEASE(_internalRepresentation);
_outlineView = nil; _outlineView = nil;
[super dealloc]; [super dealloc];
} }
- (id) _findItemValue: (id)value - (void) _collectNodes: (id)node
startItem: (id)start
{ {
id result = nil; if ([node isKindOfClass: [NSArray class]])
NSTableColumn *outlineTableColumn = [_outlineView outlineTableColumn]; {
GSKeyValueBinding *binding = [GSKeyValueBinding getBinding: NSValueBinding NSArray *array = (NSArray *)node;
forObject: outlineTableColumn];
if (value != nil) FOR_IN(id, c, array)
{ {
id v = nil; // [start valueForKeyPath: valueKey]; [self _collectNodes: c]; // withBinding: binding];
if ([v isEqual: value] || result == start)
{
result = start;
}
else
{
NSArray *array = nil;
if ([start isKindOfClass: [NSArray class]])
{
array = start;
}
else
{
array = (NSArray *)[start valueForKeyPath: _childrenKeyPath];
}
FOR_IN(id, i, array)
{
result = [self _findItemValue: value
startItem: i];
if (result != nil)
{
break;
}
} }
END_FOR_IN(array); END_FOR_IN(array);
} }
} else
{
NSArray *children = (NSArray *)[node valueForKeyPath: _childrenKeyPath];
return result; if (children == nil)
{
[_internalRepresentation setObject: [NSMutableArray array]
forKey: node];
}
else
{
[_internalRepresentation setObject: children
forKey: node];
FOR_IN(id, c, children)
{
[self _collectNodes: c]; // withBinding: binding];
}
END_FOR_IN(children);
}
}
} }
- (void) collectNodes
{
if (_theBinding != nil)
{
NSArray *contentArray = (NSArray *)[_theBinding destinationValue];
[self _collectNodes: contentArray];
NSLog(@"_internalRepresentation = %@", _internalRepresentation);
}
}
// Internal delegate...
- (BOOL) outlineView: (NSOutlineView *)outlineView - (BOOL) outlineView: (NSOutlineView *)outlineView
acceptDrop: (id <NSDraggingInfo>)info acceptDrop: (id <NSDraggingInfo>)info
item: (id)item item: (id)item
@ -2393,35 +2382,43 @@ Also returns the child index relative to this parent. */
child: (NSInteger)index child: (NSInteger)index
ofItem: (id)item ofItem: (id)item
{ {
id childItem = nil;
// If there is a [outlineView dataSource] set, then we return that methods // If there is a [outlineView dataSource] set, then we return that methods
// result if it responds to it. // result if it responds to it.
if ([[outlineView dataSource] respondsToSelector: _cmd]) if ([[outlineView dataSource] respondsToSelector: _cmd])
{ {
return [[outlineView dataSource] outlineView: outlineView childItem = [[outlineView dataSource] outlineView: outlineView
child: index child: index
ofItem: item]; ofItem: item];
} }
else
{
NSArray *children = [_internalRepresentation objectForKey: item];
// id item = [contentArray objectAtIndex: i]; childItem = [children objectAtIndex: index];
id v = nil; // [(NSArray *)[b destinationValue] objectAtIndex: i]; }
return v; return childItem;
} }
- (BOOL) outlineView: (NSOutlineView *)outlineView - (BOOL) outlineView: (NSOutlineView *)outlineView
isItemExpandable: (id)i isItemExpandable: (id)item
{ {
BOOL f = NO;
// If there is a [outlineView dataSource] set, then we return that methods // If there is a [outlineView dataSource] set, then we return that methods
// result if it responds to it. // result if it responds to it.
if ([[outlineView dataSource] respondsToSelector: _cmd]) if ([[outlineView dataSource] respondsToSelector: _cmd])
{ {
return [[outlineView dataSource] outlineView: outlineView f = [[outlineView dataSource] outlineView: outlineView
isItemExpandable: i]; isItemExpandable: item];
}
else
{
NSNumber *n = [item valueForKeyPath: _leafKeyPath];
f = [n boolValue];
} }
id item = [self _findItemValue: i
startItem: nil];
BOOL f = [[item valueForKeyPath: _leafKeyPath] boolValue];
return f; return f;
} }
@ -2429,11 +2426,19 @@ Also returns the child index relative to this parent. */
- (id) outlineView: (NSOutlineView *)outlineView - (id) outlineView: (NSOutlineView *)outlineView
itemForPersistentObject: (id)object itemForPersistentObject: (id)object
{ {
return nil; id po = nil;
if ([[outlineView dataSource] respondsToSelector: _cmd])
{
po = [[outlineView dataSource] outlineView: outlineView
itemForPersistentObject: object];
}
return po;
} }
- (NSInteger) outlineView: (NSOutlineView *)outlineView - (NSInteger) outlineView: (NSOutlineView *)outlineView
numberOfChildrenOfItem: (id)value numberOfChildrenOfItem: (id)item
{ {
NSInteger num = 0; NSInteger num = 0;
@ -2442,42 +2447,13 @@ Also returns the child index relative to this parent. */
if ([[outlineView dataSource] respondsToSelector: _cmd]) if ([[outlineView dataSource] respondsToSelector: _cmd])
{ {
num = [[outlineView dataSource] outlineView: outlineView num = [[outlineView dataSource] outlineView: outlineView
numberOfChildrenOfItem: value]; numberOfChildrenOfItem: item];
} }
else else
{ {
NSNumber *n = nil; NSNumber *n = [item valueForKeyPath: _countKeyPath];
id item = nil;
if (value == nil)
{
id dest = [_theBinding destinationValue];
if ([dest isKindOfClass: [NSArray class]])
{
NSArray *contentArray = (NSArray *)dest;
num = [contentArray count];
}
else
{
item = [self _findItemValue: value
startItem: nil];
n = [item valueForKeyPath: _countKeyPath];
num = [n integerValue]; num = [n integerValue];
} }
}
else
{
item = [self _findItemValue: value
startItem: nil];
n = [item valueForKeyPath: _countKeyPath];
num = [n integerValue];
}
}
return num; return num;
} }
@ -2496,6 +2472,12 @@ Also returns the child index relative to this parent. */
objectValueForTableColumn: tableColumn objectValueForTableColumn: tableColumn
byItem: item]; byItem: item];
} }
else
{
GSKeyValueBinding *vb = [GSKeyValueBinding getBinding: NSValueBinding
forObject: tableColumn];
NSLog(@"valueBinding = %@", vb);
}
return ov; return ov;
} }
@ -2539,7 +2521,7 @@ Also returns the child index relative to this parent. */
proposedItem: (id)item proposedItem: (id)item
proposedChildIndex: (NSInteger)index proposedChildIndex: (NSInteger)index
{ {
NSDragOperation op = 0; NSDragOperation op = NSDragOperationGeneric;
// If there is a [outlineView dataSource] set, then we return that methods // If there is a [outlineView dataSource] set, then we return that methods
// result if it responds to it. // result if it responds to it.
@ -2568,6 +2550,15 @@ Also returns the child index relative to this parent. */
writeItems: items writeItems: items
toPasteboard: pboard]; toPasteboard: pboard];
} }
else
{
NSData *data = [NSArchiver archivedDataWithRootObject: items];
if (data != nil)
{
flag = [pboard setData: data
forType: NSGeneralPboardType];
}
}
return flag; return flag;
} }