Makde some enhancements to make NSOutlineView much faster for large sets of items.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@13253 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
gcasa 2002-03-28 00:23:37 +00:00
parent 5947f65588
commit 16d024bf31
3 changed files with 64 additions and 82 deletions

View file

@ -1,3 +1,10 @@
2002-03-27 Gregory John Casamento <greg_casamento@yahoo.com>
* Source/NSOutlineView.m make more efficient for large sets of
items
* Headers/gnustep/gui/NSOutlineView.h Added new ivar to cache
item level information.
2002-03-26 Pierre-Yves Rivaille <pyrivail@ens-lyon.fr> 2002-03-26 Pierre-Yves Rivaille <pyrivail@ens-lyon.fr>
* Source/NSBundleAdditions.m * Source/NSBundleAdditions.m

View file

@ -39,6 +39,7 @@
NSMutableDictionary *_itemDict; NSMutableDictionary *_itemDict;
NSMutableArray *_items; NSMutableArray *_items;
NSMutableArray *_expandedItems; NSMutableArray *_expandedItems;
NSMutableDictionary *_levelOfItems;
BOOL _autoResizesOutlineColumn; BOOL _autoResizesOutlineColumn;
BOOL _indentationMarkerFollowsCell; BOOL _indentationMarkerFollowsCell;
BOOL _autosaveExpandedItems; BOOL _autosaveExpandedItems;

View file

@ -89,82 +89,8 @@ static NSImage *unexpandable = nil;
- (void) _autoloadTableColumns; - (void) _autoloadTableColumns;
- (void) _openItem: (id)item; - (void) _openItem: (id)item;
- (void) _closeItem: (id)item; - (void) _closeItem: (id)item;
- (NSDictionary *) _itemDictionary;
@end @end
// static functions
static void _loadDictionary(NSOutlineView *outline,
id startitem,
NSMutableDictionary *allItems)
{
int num = [[outline dataSource] outlineView: outline
numberOfChildrenOfItem: startitem];
int i = 0;
id sitem = startitem;
if((num > 0) && !([allItems objectForKey: startitem]))
{
if(sitem == nil)
{
sitem = [NSNull null];
}
[allItems setObject: [NSMutableArray array]
forKey: sitem];
}
for(i = 0; i < num; i++)
{
id anitem = [[outline dataSource] outlineView: outline
child: i
ofItem: startitem];
id anarray = [allItems objectForKey: sitem];
[anarray addObject: anitem];
_loadDictionary(outline, anitem, allItems);
}
}
static int _levelForItem(NSDictionary *outlineDict,
id startitem,
id searchitem,
int level,
BOOL *found)
{
id sitem = startitem;
int num = 0;
int i = 0;
int finallevel = 0;
if(sitem == nil)
sitem = [NSNull null];
// get the count for the array...
num = [[outlineDict objectForKey: sitem] count];
if(*found == YES)
{
return level;
}
if(searchitem == startitem)
{
*found = YES;
return level;
}
for(i = 0; i < num; i++)
{
id anitem = [[outlineDict objectForKey: sitem] objectAtIndex: i];
finallevel = _levelForItem(outlineDict, anitem, searchitem, level + 1, found);
if(*found) break;
}
return finallevel;
}
@implementation NSOutlineView @implementation NSOutlineView
// Initialize the class when it is loaded // Initialize the class when it is loaded
@ -194,11 +120,13 @@ static int _levelForItem(NSDictionary *outlineDict,
_itemDict = [NSMutableDictionary dictionary]; _itemDict = [NSMutableDictionary dictionary];
_items = [NSMutableArray array]; _items = [NSMutableArray array];
_expandedItems = [NSMutableArray array]; _expandedItems = [NSMutableArray array];
_levelOfItems = [NSMutableDictionary dictionary];
// Retain items // Retain items
RETAIN(_items); RETAIN(_items);
RETAIN(_expandedItems); RETAIN(_expandedItems);
RETAIN(_itemDict); RETAIN(_itemDict);
RETAIN(_levelOfItems);
return self; return self;
} }
@ -240,6 +168,42 @@ static int _levelForItem(NSDictionary *outlineDict,
} }
} }
- (void) _loadDictionaryStartingWith: (id) startitem
atLevel: (int) level
{
int num = [_dataSource outlineView: self
numberOfChildrenOfItem: startitem];
int i = 0;
id sitem = startitem;
if(num > 0)
{
if(sitem == nil)
{
sitem = [NSNull null];
}
[_itemDict setObject: [NSMutableArray array]
forKey: sitem];
}
[_levelOfItems setObject: [NSNumber numberWithInt: level]
forKey: sitem];
for(i = 0; i < num; i++)
{
id anitem = [_dataSource outlineView: self
child: i
ofItem: startitem];
id anarray = [_itemDict objectForKey: sitem];
[anarray addObject: anitem];
[self _loadDictionaryStartingWith: anitem
atLevel: level + 1];
}
}
- (void)_closeItem: (id)item - (void)_closeItem: (id)item
{ {
int numchildren = 0; int numchildren = 0;
@ -257,7 +221,6 @@ static int _levelForItem(NSDictionary *outlineDict,
// For the close method it doesn't matter what order they are // For the close method it doesn't matter what order they are
// removed in. // removed in.
for(i=0; i < numchildren; i++) for(i=0; i < numchildren; i++)
{ {
id child = [removeAll objectAtIndex: i]; id child = [removeAll objectAtIndex: i];
@ -503,8 +466,7 @@ static int _levelForItem(NSDictionary *outlineDict,
{ {
if(item != nil) if(item != nil)
{ {
BOOL found = NO; return [[_levelOfItems objectForKey: item] intValue];
return _levelForItem(_itemDict, nil, item, -1, &found);
} }
return -1; return -1;
@ -583,7 +545,8 @@ static int _levelForItem(NSDictionary *outlineDict,
if(reloadChildren && haschildren) // expand all if(reloadChildren && haschildren) // expand all
{ {
NSMutableDictionary *allChildren = [NSMutableDictionary dictionary]; NSMutableDictionary *allChildren = [NSMutableDictionary dictionary];
_loadDictionary(self, item, allChildren); [self _loadDictionaryStartingWith: item
atLevel: [self levelForItem: item]];
[_itemDict addEntriesFromDictionary: allChildren]; [_itemDict addEntriesFromDictionary: allChildren];
// release the old array // release the old array
@ -635,7 +598,7 @@ static int _levelForItem(NSDictionary *outlineDict,
- (void) noteNumberOfRowsChanged - (void) noteNumberOfRowsChanged
{ {
_numberOfRows = [_items count]; _numberOfRows = [_items count];
/* If we are selecting rows, we have to check that we have no /* If we are selecting rows, we have to check that we have no
selected rows below the new end of the table */ selected rows below the new end of the table */
if (!_selectingColumns) if (!_selectingColumns)
@ -764,13 +727,19 @@ static int _levelForItem(NSDictionary *outlineDict,
RELEASE(_itemDict); RELEASE(_itemDict);
} }
if(_levelOfItems != nil)
{
RELEASE(_levelOfItems);
}
// create a new empty one // create a new empty one
_items = RETAIN([NSMutableArray array]); _items = RETAIN([NSMutableArray array]);
_itemDict = RETAIN([NSMutableDictionary dictionary]); _itemDict = RETAIN([NSMutableDictionary dictionary]);
_levelOfItems = RETAIN([NSMutableDictionary dictionary]);
// reload all the open items... // reload all the open items...
_loadDictionary(self, nil, _itemDict); [self _loadDictionaryStartingWith: nil
// NSLog(@"Dictionary = %@",_itemDict); atLevel: -1];
[self _openItem: nil]; [self _openItem: nil];
[super reloadData]; [super reloadData];
} }
@ -897,6 +866,11 @@ static int _levelForItem(NSDictionary *outlineDict,
/* Using columnAtPoint: here would make it called twice per row per drawn /* Using columnAtPoint: here would make it called twice per row per drawn
rect - so we avoid it and do it natively */ rect - so we avoid it and do it natively */
if(rowIndex >= _numberOfRows)
{
return;
}
/* Determine starting column as fast as possible */ /* Determine starting column as fast as possible */
x_pos = NSMinX (aRect); x_pos = NSMinX (aRect);
i = 0; i = 0;