DnD fixes and cleanups in NSOutlineView.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@18306 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Ludovic Marcotte 2004-01-04 03:39:09 +00:00
parent ce15bf2417
commit 6d49a2b2fc
3 changed files with 140 additions and 136 deletions

View file

@ -1,3 +1,12 @@
2003-01-03 Ludovic Marcotte <ludovic@Sophos.ca>
* Source/NSOutlineView.m: Started to fix the DnD code.
Modified -mouseDown: to not select the row when clicking
only on the expand/collapse image. Rewrote
-noteNumberOfRowsChanged to correctly restore the list
of selected rows after an expand/collapse operation.
Also did some general cleanups. More to come on this class.
2004-01-03 19:00 Gregory John Casamento <greg_casamento@yahoo.com>
* Source/NSBundleAdditions.m: Removed some uneeded includes.

View file

@ -40,6 +40,7 @@
NSMapTable *_itemDict;
NSMutableArray *_items;
NSMutableArray *_expandedItems;
NSMutableArray *_selectedItems;
NSMapTable *_levelOfItems;
BOOL _autoResizesOutlineColumn;
BOOL _indentationMarkerFollowsCell;

View file

@ -139,12 +139,12 @@ static NSImage *unexpandable = nil;
_itemDict = NSCreateMapTable(NSObjectMapKeyCallBacks,
NSObjectMapValueCallBacks,
64);
_items = [NSMutableArray new];
_expandedItems = [NSMutableArray new];
_items = [[NSMutableArray alloc] init];
_expandedItems = [[NSMutableArray alloc] init];
_selectedItems = [[NSMutableArray alloc] init];
_levelOfItems = NSCreateMapTable(NSObjectMapKeyCallBacks,
NSObjectMapValueCallBacks,
64);
return self;
}
@ -152,6 +152,8 @@ static NSImage *unexpandable = nil;
{
RELEASE(_items);
RELEASE(_expandedItems);
RELEASE(_selectedItems);
NSFreeMapTable(_itemDict);
NSFreeMapTable(_levelOfItems);
@ -347,7 +349,9 @@ static NSImage *unexpandable = nil;
if([self isExpandable: item] && [self isItemExpanded: item] && canCollapse)
{
NSMutableDictionary *infoDict = [NSMutableDictionary dictionary];
NSMutableDictionary *infoDict = [NSMutableDictionary dictionary];
int i, count, row;
[infoDict setObject: item forKey: @"NSObject"];
// Send out the notification to let observers know that this is about
@ -356,6 +360,20 @@ static NSImage *unexpandable = nil;
object: self
userInfo: infoDict];
// We save the selection
[_selectedItems removeAllObjects];
count = [_selectedRows count];
for (i = 0; i < count; i++)
{
row = [[_selectedRows objectAtIndex: i] intValue];
if ([self itemAtRow: row])
{
[_selectedItems addObject: [self itemAtRow: row]];
}
}
// collapse...
[self _closeItem: item];
@ -421,6 +439,7 @@ static NSImage *unexpandable = nil;
if(![self isItemExpanded: item] && canExpand)
{
NSMutableDictionary *infoDict = [NSMutableDictionary dictionary];
int i, count, row;
[infoDict setObject: item forKey: @"NSObject"];
@ -430,6 +449,20 @@ static NSImage *unexpandable = nil;
object: self
userInfo: infoDict];
// We save the selection
[_selectedItems removeAllObjects];
count = [_selectedRows count];
for (i = 0; i < count; i++)
{
row = [[_selectedRows objectAtIndex: i] intValue];
if ([self itemAtRow: row])
{
[_selectedItems addObject: [self itemAtRow: row]];
}
}
// insert the root element, if necessary otherwise insert the
// actual object.
[self _openItem: item];
@ -618,7 +651,7 @@ static NSImage *unexpandable = nil;
// release the old array
if(_items != nil)
{
RELEASE(_items);
DESTROY(_items);
}
// regenerate the _items array based on the new dictionary
@ -721,72 +754,29 @@ static NSImage *unexpandable = nil;
return YES;
}
/**
* This method returns the number of rows changed in the data source.
* We override the super class's method.
*/
- (void) noteNumberOfRowsChanged
{
_numberOfRows = [_items count];
/* If we are selecting rows, we have to check that we have no
selected rows below the new end of the table */
if (!_selectingColumns)
{
int i, count = [_selectedRows count];
int row = -1;
int i, count, row;
/* Check that all selected rows are in the new range of rows */
/* We restore the selection */
[_selectedRows removeAllObjects];
count = [_selectedItems count];
for (i = 0; i < count; i++)
{
row = [[_selectedRows objectAtIndex: i] intValue];
row = [self rowForItem: [_selectedItems objectAtIndex: i]];
if (row >= _numberOfRows)
if (row >= 0 && row < _numberOfRows)
{
break;
}
}
if (i < count && row > -1)
{
/* Some of them are outside the table ! - Remove them */
for (; i < count; i++)
{
[_selectedRows removeLastObject];
}
/* Now if the _selectedRow is outside the table, reset it to be
the last selected row (if any) */
if (_selectedRow >= _numberOfRows)
{
if ([_selectedRows count] > 0)
{
_selectedRow = [[_selectedRows lastObject] intValue];
}
else
{
/* Argh - all selected rows were outside the table */
if (_allowsEmptySelection)
{
_selectedRow = -1;
}
else
{
/* We shouldn't allow empty selection - try
selecting the last row */
int lastRow = _numberOfRows - 1;
if (lastRow > -1)
{
[_selectedRows addObject:
[NSNumber numberWithInt: lastRow]];
_selectedRow = lastRow;
}
else
{
/* problem - there are no rows at all */
_selectedRow = -1;
}
}
}
[_selectedRows addObject: [NSNumber numberWithInt: row]];
}
}
}
@ -857,7 +847,7 @@ static NSImage *unexpandable = nil;
}
// create a new empty one
_items = RETAIN([NSMutableArray array]);
_items = [[NSMutableArray alloc] init];
_itemDict = NSCreateMapTable(NSObjectMapKeyCallBacks,
NSObjectMapValueCallBacks,
64);
@ -926,14 +916,12 @@ static NSImage *unexpandable = nil;
_itemDict = NSCreateMapTable(NSObjectMapKeyCallBacks,
NSObjectMapValueCallBacks,
64);
_items = [NSMutableArray array];
_expandedItems = [NSMutableArray array];
_items = [[NSMutableArray alloc] init];
_expandedItems = [[NSMutableArray alloc] init];
_selectedItems = [[NSMutableArray alloc] init];
_levelOfItems = NSCreateMapTable(NSObjectMapKeyCallBacks,
NSObjectMapValueCallBacks,
64);
// Retain items
RETAIN(_items);
RETAIN(_expandedItems);
return self;
}
@ -941,38 +929,37 @@ static NSImage *unexpandable = nil;
- (void) mouseDown: (NSEvent *)theEvent
{
NSPoint location = [theEvent locationInWindow];
NSTableColumn *tb;
NSImage *image = nil;
location = [self convertPoint: location fromView: nil];
_clickedRow = [self rowAtPoint: location];
_clickedColumn = [self columnAtPoint: location];
if([self isItemExpanded: [self itemAtRow: _clickedRow]])
{
image = expanded;
}
else
{
image = collapsed;
}
tb = [_tableColumns objectAtIndex: _clickedColumn];
if(tb == _outlineTableColumn)
if ([_tableColumns objectAtIndex: _clickedColumn] == _outlineTableColumn)
{
NSImage *image;
int level = [self levelForRow: _clickedRow];
int position = 0;
if(_indentationMarkerFollowsCell)
if ([self isItemExpanded: [self itemAtRow: _clickedRow]])
{
image = expanded;
}
else
{
image = collapsed;
}
if (_indentationMarkerFollowsCell)
{
position = _indentationPerLevel * level;
}
position += _columnOrigins[_clickedColumn];
if(location.x >= position && location.x <= position + [image size].width)
if (location.x >= position && location.x <= position + [image size].width)
{
if(![self isItemExpanded: [self itemAtRow: _clickedRow]])
if (![self isItemExpanded: [self itemAtRow: _clickedRow]])
{
[self expandItem: [self itemAtRow: _clickedRow]];
}
@ -980,6 +967,7 @@ static NSImage *unexpandable = nil;
{
[self collapseItem: [self itemAtRow: _clickedRow]];
}
return;
}
}
@ -1098,9 +1086,6 @@ static NSImage *unexpandable = nil;
imageRect.origin.x = drawingRect.origin.x;
imageRect.origin.y = drawingRect.origin.y;
}
imageRect.size.width = [image size].width;
imageRect.size.height = [image size].height;
if ([_delegate respondsToSelector: @selector(outlineView:willDisplayOutlineCell:forTableColumn:item:)])
{
@ -1109,16 +1094,26 @@ static NSImage *unexpandable = nil;
forTableColumn: tb
item: item];
}
/* Do not indent if the delegate set the image to nil. */
if ( [imageCell image] )
{
imageRect.size.width = [image size].width;
imageRect.size.height = [image size].height;
[imageCell drawWithFrame: imageRect inView: self];
drawingRect.origin.x += indentationFactor + [image size].width + 5;
drawingRect.size.width -= indentationFactor + [image size].width + 5;
}
else
{
drawingRect.origin.x += indentationFactor;
drawingRect.size.width -= indentationFactor;
}
[imageCell drawWithFrame: imageRect inView: self];
drawingRect.origin.x += indentationFactor + [image size].width + 5;
drawingRect.size.width -= indentationFactor + [image size].width + 5;
RELEASE(imageCell);
}
[cell drawWithFrame: drawingRect inView: self];
}
}
}
@ -1292,11 +1287,6 @@ static NSImage *unexpandable = nil;
return;
}
if ([self isItemExpanded: item] == NO)
{
return;
}
if (childIndex == NSOutlineViewDropOnItemIndex)
{
currentDropRow = row;
@ -1349,7 +1339,7 @@ static NSImage *unexpandable = nil;
- (unsigned int) draggingEntered: (id <NSDraggingInfo>) sender
{
NSLog(@"draggingEntered");
//NSLog(@"draggingEntered");
currentDropRow = -1;
// currentDropOperation = -1;
oldDropRow = -1;
@ -1395,9 +1385,9 @@ static NSImage *unexpandable = nil;
if (row > _numberOfRows)
row = _numberOfRows;
// NSLog(@"horizontalHalfPosition = %d", horizontalHalfPosition);
// NSLog(@"dropRow %d", row);
//NSLog(@"horizontalHalfPosition = %d", horizontalHalfPosition);
//NSLog(@"dropRow %d", row);
if (row == 0)
{
@ -1416,16 +1406,13 @@ static NSImage *unexpandable = nil;
levelAfter = [self levelForRow: row];
}
//NSLog(@"horizontalHalfPosition = %d", horizontalHalfPosition);
//NSLog(@"level before = %d", levelBefore);
//NSLog(@"level after = %d", levelAfter);
if (levelBefore < levelAfter)
levelBefore = levelAfter;
// NSLog(@"horizontalHalfPosition = %d", horizontalHalfPosition);
// NSLog(@"level before = %d", levelBefore);
// NSLog(@"level after = %d", levelAfter);
if ((lastVerticalQuarterPosition != verticalQuarterPosition)
|| (lastHorizontalHalfPosition != horizontalHalfPosition))
{
@ -1442,8 +1429,8 @@ static NSImage *unexpandable = nil;
lastVerticalQuarterPosition = verticalQuarterPosition;
lastHorizontalHalfPosition = horizontalHalfPosition;
// NSLog(@"horizontalHalfPosition = %d", horizontalHalfPosition);
// NSLog(@"verticalQuarterPosition = %d", verticalQuarterPosition);
//NSLog(@"horizontalHalfPosition = %d", horizontalHalfPosition);
//NSLog(@"verticalQuarterPosition = %d", verticalQuarterPosition);
currentDropRow = row;
currentDropLevel = level;
@ -1464,7 +1451,7 @@ static NSImage *unexpandable = nil;
j++;
}
}
// NSLog(@"found %d (proposed childIndex = %d)", i, j);
//NSLog(@"found %d (proposed childIndex = %d)", i, j);
if (i == -1)
item = nil;
else
@ -1478,14 +1465,14 @@ static NSImage *unexpandable = nil;
if ([_dataSource respondsToSelector:
@selector(outlineView:validateDrop:proposedItem:proposedChildIndex:)])
{
// NSLog(@"currentDropLevel %d, currentDropRow %d",
// currentDropRow, currentDropLevel);
//NSLog(@"currentDropLevel %d, currentDropRow %d",
//currentDropLevel, currentDropRow);
[_dataSource outlineView: self
validateDrop: sender
proposedItem: item
proposedChildIndex: childIndex];
// NSLog(@"currentDropLevel %d, currentDropRow %d",
// currentDropRow, currentDropLevel);
//NSLog(@"currentDropLevel %d, currentDropRow %d",
//currentDropLevel, currentDropRow);
}
if ((currentDropRow != oldDropRow) || (currentDropLevel != oldDropLevel))
@ -1497,8 +1484,9 @@ static NSImage *unexpandable = nil;
[[NSColor darkGrayColor] set];
// NSLog(@"currentDropLevel %d, currentDropRow %d",
// currentDropRow, currentDropLevel);
//NSLog(@"currentDropLevel %d, currentDropRow %d",
//currentDropLevel, currentDropRow);
if (currentDropLevel != NSOutlineViewDropOnItemIndex)
{
if (currentDropRow == 0)
@ -1578,44 +1566,50 @@ static NSImage *unexpandable = nil;
- (BOOL) performDragOperation: (id<NSDraggingInfo>)sender
{
NSLog(@"performDragOperation");
if ([_dataSource
respondsToSelector:
@selector(outlineView:acceptDrop:item:childIndex:)])
{
id item;
int childIndex;
int i;
int j = 0;
int lvl;
for ( i = currentDropRow - 1; i >= 0; i-- )
if (currentDropLevel == NSOutlineViewDropOnItemIndex)
{
lvl = [self levelForRow: i];
if (lvl == currentDropLevel - 1)
{
break;
}
else if (lvl == currentDropLevel)
{
j++;
}
item = [self itemAtRow: currentDropRow];
childIndex = currentDropLevel;
}
if (i == -1)
item = nil;
else
item = [self itemAtRow: i];
childIndex = j;
{
int lvl, i, j = 0;
for ( i = currentDropRow - 1; i >= 0; i-- )
{
lvl = [self levelForRow: i];
if (lvl == currentDropLevel - 1)
{
break;
}
else if (lvl == currentDropLevel)
{
j++;
}
}
if (i == -1)
item = nil;
else
item = [self itemAtRow: i];
childIndex = j;
}
return [_dataSource
outlineView: self
acceptDrop: sender
item: item
childIndex: childIndex];
}
else
return NO;
return NO;
}
- (BOOL) prepareForDragOperation: (id<NSDraggingInfo>)sender