2024-06-19 05:46:27 +00:00
|
|
|
/*
|
|
|
|
NSTreeController.m
|
2013-08-19 19:10:22 +00:00
|
|
|
|
|
|
|
The tree controller class.
|
|
|
|
|
2024-06-28 12:39:39 +00:00
|
|
|
Copyright (C) 2012, 2024 Free Software Foundation, Inc.
|
2013-08-19 19:10:22 +00:00
|
|
|
|
|
|
|
Author: Gregory Casamento <greg.casamento@gmail.com>
|
2024-06-28 12:39:39 +00:00
|
|
|
Date: 2012, 2024
|
2013-08-19 19:10:22 +00:00
|
|
|
|
|
|
|
This file is part of the GNUstep GUI Library.
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Lesser General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Lesser General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
|
|
License along with this library; see the file COPYING.LIB.
|
2024-06-19 05:46:27 +00:00
|
|
|
If not, see <http://www.gnu.org/licenses/> or write to the
|
|
|
|
Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
2013-08-19 19:10:22 +00:00
|
|
|
Boston, MA 02110-1301, USA.
|
2024-06-19 05:46:27 +00:00
|
|
|
*/
|
2013-08-19 19:10:22 +00:00
|
|
|
|
2024-06-19 05:46:27 +00:00
|
|
|
#import <Foundation/NSArchiver.h>
|
2013-08-19 19:10:22 +00:00
|
|
|
#import <Foundation/NSArray.h>
|
2024-06-25 21:11:57 +00:00
|
|
|
#import <Foundation/NSDictionary.h>
|
2013-08-19 19:10:22 +00:00
|
|
|
#import <Foundation/NSIndexPath.h>
|
2024-06-19 05:46:27 +00:00
|
|
|
#import <Foundation/NSKeyedArchiver.h>
|
2024-07-12 10:22:56 +00:00
|
|
|
#import <Foundation/NSKeyValueCoding.h>
|
2024-06-19 05:46:27 +00:00
|
|
|
#import <Foundation/NSKeyValueObserving.h>
|
2013-08-19 19:10:22 +00:00
|
|
|
#import <Foundation/NSString.h>
|
|
|
|
#import <Foundation/NSSortDescriptor.h>
|
|
|
|
|
2024-06-19 05:46:27 +00:00
|
|
|
#import "AppKit/NSKeyValueBinding.h"
|
|
|
|
#import "AppKit/NSTreeController.h"
|
2024-06-24 12:50:22 +00:00
|
|
|
#import "AppKit/NSTreeNode.h"
|
2024-06-19 05:46:27 +00:00
|
|
|
|
|
|
|
#import "GSBindingHelpers.h"
|
|
|
|
#import "GSFastEnumeration.h"
|
2024-06-25 21:11:57 +00:00
|
|
|
#import "GSControllerTreeProxy.h"
|
2012-02-29 15:32:09 +00:00
|
|
|
|
|
|
|
@implementation NSTreeController
|
|
|
|
|
2024-06-19 05:46:27 +00:00
|
|
|
+ (void) initialize
|
|
|
|
{
|
|
|
|
if (self == [NSTreeController class])
|
|
|
|
{
|
2024-06-25 21:11:57 +00:00
|
|
|
[self exposeBinding: NSContentArrayBinding];
|
2024-06-24 12:50:22 +00:00
|
|
|
[self exposeBinding: NSContentBinding];
|
2024-07-19 12:04:13 +00:00
|
|
|
[self exposeBinding: NSSelectionIndexPathsBinding];
|
2024-06-19 05:46:27 +00:00
|
|
|
[self setKeys: [NSArray arrayWithObjects: NSContentBinding, NSContentObjectBinding, nil]
|
|
|
|
triggerChangeNotificationsForDependentKey: @"arrangedObjects"];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-02 08:05:53 +00:00
|
|
|
- (void) _initDefaults
|
|
|
|
{
|
|
|
|
_childrenKeyPath = nil;
|
|
|
|
_countKeyPath = nil;
|
|
|
|
_leafKeyPath = nil;
|
|
|
|
_sortDescriptors = nil;
|
|
|
|
_selection_index_paths = [[NSMutableArray alloc] init];
|
|
|
|
|
|
|
|
_canInsert = YES;
|
|
|
|
_canInsertChild = YES;
|
|
|
|
_canAddChild = YES;
|
|
|
|
|
|
|
|
[self setObjectClass: [NSMutableDictionary class]];
|
|
|
|
}
|
|
|
|
|
2013-08-19 19:10:22 +00:00
|
|
|
- (id) initWithContent: (id)content
|
|
|
|
{
|
|
|
|
if ((self = [super initWithContent: content]) != nil)
|
|
|
|
{
|
2024-07-02 08:05:53 +00:00
|
|
|
[self _initDefaults];
|
2013-08-19 19:10:22 +00:00
|
|
|
}
|
2024-06-19 05:46:27 +00:00
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) init
|
|
|
|
{
|
|
|
|
NSMutableArray *array = [[NSMutableArray alloc] init];
|
|
|
|
|
|
|
|
self = [self initWithContent: array];
|
|
|
|
RELEASE(array);
|
2024-07-12 12:49:52 +00:00
|
|
|
|
2013-08-19 19:10:22 +00:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) dealloc
|
|
|
|
{
|
|
|
|
RELEASE(_childrenKeyPath);
|
|
|
|
RELEASE(_countKeyPath);
|
|
|
|
RELEASE(_leafKeyPath);
|
|
|
|
RELEASE(_sortDescriptors);
|
2024-06-19 05:46:27 +00:00
|
|
|
RELEASE(_arranged_objects);
|
2013-08-19 19:10:22 +00:00
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
2024-06-19 05:46:27 +00:00
|
|
|
- (BOOL) addSelectionIndexPaths: (NSArray *)indexPaths
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
2024-06-28 12:39:39 +00:00
|
|
|
BOOL f = [self commitEditing];
|
|
|
|
|
|
|
|
if (YES == f)
|
|
|
|
{
|
|
|
|
[_selection_index_paths addObjectsFromArray: indexPaths];
|
|
|
|
}
|
|
|
|
|
|
|
|
return f;
|
2013-08-19 19:10:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) alwaysUsesMultipleValuesMarker
|
|
|
|
{
|
|
|
|
return _alwaysUsesMultipleValuesMarker;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) avoidsEmptySelection
|
|
|
|
{
|
|
|
|
return _avoidsEmptySelection;
|
|
|
|
}
|
|
|
|
|
2024-06-19 05:46:27 +00:00
|
|
|
- (BOOL) canAddChild
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
2024-06-19 05:46:27 +00:00
|
|
|
return _canAddChild;
|
2013-08-19 19:10:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) canInsert
|
|
|
|
{
|
2024-06-19 05:46:27 +00:00
|
|
|
return _canInsert;
|
2013-08-19 19:10:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) canInsertChild
|
|
|
|
{
|
2024-06-19 05:46:27 +00:00
|
|
|
return _canInsertChild;
|
2013-08-19 19:10:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) preservesSelection
|
|
|
|
{
|
|
|
|
return _preservesSelection;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) selectsInsertedObjects
|
|
|
|
{
|
|
|
|
return _selectsInsertedObjects;
|
|
|
|
}
|
|
|
|
|
2024-06-19 05:46:27 +00:00
|
|
|
- (BOOL) setSelectionIndexPath: (NSIndexPath *)indexPath
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
2024-06-19 05:46:27 +00:00
|
|
|
BOOL f = [self commitEditing];
|
|
|
|
|
|
|
|
if (YES == f)
|
|
|
|
{
|
|
|
|
[_selection_index_paths addObject: indexPath];
|
|
|
|
}
|
2024-07-12 12:49:52 +00:00
|
|
|
|
2024-06-19 05:46:27 +00:00
|
|
|
return f;
|
2013-08-19 19:10:22 +00:00
|
|
|
}
|
|
|
|
|
2024-06-19 05:46:27 +00:00
|
|
|
- (BOOL) setSelectionIndexPaths: (NSArray *)indexPaths
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
2024-06-19 05:46:27 +00:00
|
|
|
BOOL f = [self commitEditing];
|
|
|
|
|
|
|
|
if (YES == f)
|
|
|
|
{
|
|
|
|
NSMutableArray *mutable_index_paths = [NSMutableArray arrayWithArray: indexPaths];
|
|
|
|
ASSIGN(_selection_index_paths, mutable_index_paths);
|
|
|
|
}
|
2024-07-12 12:49:52 +00:00
|
|
|
|
2024-06-19 05:46:27 +00:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
2024-06-24 12:50:22 +00:00
|
|
|
- (NSTreeNode *) arrangedObjects
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
2024-06-19 05:46:27 +00:00
|
|
|
if (_arranged_objects == nil)
|
|
|
|
{
|
|
|
|
[self rearrangeObjects];
|
|
|
|
}
|
|
|
|
return _arranged_objects;
|
2013-08-19 19:10:22 +00:00
|
|
|
}
|
|
|
|
|
2024-06-19 05:46:27 +00:00
|
|
|
- (void) rearrangeObjects
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
2024-06-19 05:46:27 +00:00
|
|
|
[self willChangeValueForKey: @"arrangedObjects"];
|
|
|
|
DESTROY(_arranged_objects);
|
2024-06-25 21:11:57 +00:00
|
|
|
|
|
|
|
if ([_content isKindOfClass: [NSArray class]])
|
|
|
|
{
|
2024-07-27 22:51:59 +00:00
|
|
|
_arranged_objects = [[GSControllerTreeProxy alloc] initWithContent: _content
|
|
|
|
withController: self];
|
2024-06-25 21:11:57 +00:00
|
|
|
}
|
2024-07-12 12:49:52 +00:00
|
|
|
|
2024-06-19 05:46:27 +00:00
|
|
|
[self didChangeValueForKey: @"arrangedObjects"];
|
2013-08-19 19:10:22 +00:00
|
|
|
}
|
|
|
|
|
2024-07-19 14:14:18 +00:00
|
|
|
- (id) _objectAtIndexPath: (NSIndexPath *)indexPath
|
|
|
|
{
|
|
|
|
NSUInteger length = [indexPath length];
|
|
|
|
NSUInteger pos = 0;
|
|
|
|
NSMutableArray *children = [_arranged_objects mutableChildNodes];
|
|
|
|
NSUInteger lastIndex = 0;
|
|
|
|
id obj = nil;
|
|
|
|
|
|
|
|
for (pos = 0; pos < length - 1; pos++)
|
|
|
|
{
|
|
|
|
NSUInteger i = [indexPath indexAtPosition: pos];
|
|
|
|
id node = [children objectAtIndex: i];
|
|
|
|
|
|
|
|
children = [node valueForKeyPath: _childrenKeyPath];
|
|
|
|
}
|
|
|
|
|
|
|
|
lastIndex = [indexPath indexAtPosition: length - 1];
|
|
|
|
obj = [children objectAtIndex: lastIndex];
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
2024-06-19 05:46:27 +00:00
|
|
|
- (NSArray *) selectedObjects
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
2024-07-19 14:14:18 +00:00
|
|
|
NSMutableArray *selectedObjects = [NSMutableArray array];
|
|
|
|
|
2024-07-27 23:46:51 +00:00
|
|
|
FOR_IN(NSIndexPath*, path, _selection_index_paths)
|
2024-07-19 14:14:18 +00:00
|
|
|
{
|
|
|
|
id obj = [self _objectAtIndexPath: path];
|
|
|
|
[selectedObjects addObject: obj];
|
|
|
|
}
|
2024-07-27 23:46:51 +00:00
|
|
|
END_FOR_IN(_selection_index_paths);
|
2024-07-29 00:49:18 +00:00
|
|
|
|
2024-07-19 14:14:18 +00:00
|
|
|
return selectedObjects;
|
2013-08-19 19:10:22 +00:00
|
|
|
}
|
|
|
|
|
2024-07-12 14:39:47 +00:00
|
|
|
- (NSIndexPath *) selectionIndexPath
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
2024-07-19 14:14:18 +00:00
|
|
|
return [_selection_index_paths objectAtIndex: 0];
|
2013-08-19 19:10:22 +00:00
|
|
|
}
|
|
|
|
|
2024-07-12 14:39:47 +00:00
|
|
|
- (NSArray *) selectionIndexPaths
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
2024-07-19 14:14:18 +00:00
|
|
|
return _selection_index_paths;
|
2013-08-19 19:10:22 +00:00
|
|
|
}
|
|
|
|
|
2024-07-12 14:39:47 +00:00
|
|
|
- (NSArray *) sortDescriptors
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
|
|
|
return _sortDescriptors;
|
|
|
|
}
|
|
|
|
|
2024-07-12 14:39:47 +00:00
|
|
|
- (NSString *) childrenKeyPath
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
|
|
|
return _childrenKeyPath;
|
|
|
|
}
|
|
|
|
|
2024-07-12 14:39:47 +00:00
|
|
|
- (NSString *) countKeyPath
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
|
|
|
return _countKeyPath;;
|
|
|
|
}
|
|
|
|
|
2024-07-12 14:39:47 +00:00
|
|
|
- (NSString *) leafKeyPath
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
|
|
|
return _leafKeyPath;
|
|
|
|
}
|
|
|
|
|
2024-07-12 10:22:56 +00:00
|
|
|
- (IBAction) add: (id)sender
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
2024-07-02 08:05:53 +00:00
|
|
|
if ([self canAddChild]
|
|
|
|
&& [self countKeyPath] == nil)
|
2024-06-19 05:46:27 +00:00
|
|
|
{
|
2024-07-02 08:05:53 +00:00
|
|
|
id newObject = [self newObject];
|
2024-06-19 05:46:27 +00:00
|
|
|
|
2024-07-02 08:05:53 +00:00
|
|
|
if (newObject != nil)
|
|
|
|
{
|
|
|
|
NSMutableArray *newContent = [NSMutableArray arrayWithArray: [self content]];
|
|
|
|
GSControllerTreeProxy *node = [[GSControllerTreeProxy alloc]
|
2024-07-27 22:51:59 +00:00
|
|
|
initWithContent: newObject
|
|
|
|
withController: self];
|
2024-07-02 08:05:53 +00:00
|
|
|
|
|
|
|
[newContent addObject: node];
|
2024-07-19 14:14:18 +00:00
|
|
|
|
2024-07-02 08:05:53 +00:00
|
|
|
[self setContent: newContent];
|
|
|
|
RELEASE(newObject);
|
|
|
|
}
|
2024-06-19 05:46:27 +00:00
|
|
|
}
|
2013-08-19 19:10:22 +00:00
|
|
|
}
|
|
|
|
|
2024-07-12 10:22:56 +00:00
|
|
|
- (IBAction) addChild: (id)sender
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
2024-07-19 14:14:18 +00:00
|
|
|
NSIndexPath *p = [self selectionIndexPath];
|
|
|
|
id newObject = [self newObject];
|
|
|
|
|
2024-07-27 22:51:59 +00:00
|
|
|
if (p != nil)
|
|
|
|
{
|
|
|
|
[self insertObject: newObject atArrangedObjectIndexPath: p];
|
|
|
|
}
|
2024-06-19 05:46:27 +00:00
|
|
|
}
|
|
|
|
|
2024-07-12 10:22:56 +00:00
|
|
|
- (IBAction) remove: (id)sender
|
2024-06-19 05:46:27 +00:00
|
|
|
{
|
2024-07-02 08:05:53 +00:00
|
|
|
if ([self canRemove]
|
|
|
|
&& [self countKeyPath] == nil)
|
2024-06-19 05:46:27 +00:00
|
|
|
{
|
|
|
|
[self removeObject: [self content]];
|
|
|
|
}
|
2013-08-19 19:10:22 +00:00
|
|
|
}
|
|
|
|
|
2024-07-12 10:22:56 +00:00
|
|
|
- (IBAction) insertChild: (id)sender
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
2024-07-19 14:14:18 +00:00
|
|
|
[self addChild: sender];
|
2013-08-19 19:10:22 +00:00
|
|
|
}
|
|
|
|
|
2024-07-12 14:39:47 +00:00
|
|
|
- (void) insertObject: (id)object atArrangedObjectIndexPath: (NSIndexPath *)indexPath
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
2024-07-19 14:14:18 +00:00
|
|
|
if ([self canAddChild]
|
|
|
|
&& [self countKeyPath] == nil)
|
2024-07-12 10:22:56 +00:00
|
|
|
{
|
2024-07-19 14:14:18 +00:00
|
|
|
NSUInteger length = [indexPath length];
|
|
|
|
NSUInteger pos = 0;
|
|
|
|
NSMutableArray *children = [_arranged_objects mutableChildNodes];
|
|
|
|
NSUInteger lastIndex = 0;
|
|
|
|
|
|
|
|
for (pos = 0; pos < length - 1; pos++)
|
|
|
|
{
|
|
|
|
NSUInteger i = [indexPath indexAtPosition: pos];
|
|
|
|
id node = [children objectAtIndex: i];
|
|
|
|
|
|
|
|
children = [node valueForKeyPath: _childrenKeyPath];
|
|
|
|
}
|
|
|
|
|
|
|
|
lastIndex = [indexPath indexAtPosition: length - 1];
|
|
|
|
[children insertObject: object atIndex: lastIndex];
|
|
|
|
[self rearrangeObjects];
|
2024-07-12 10:22:56 +00:00
|
|
|
}
|
2013-08-19 19:10:22 +00:00
|
|
|
}
|
|
|
|
|
2024-07-12 14:39:47 +00:00
|
|
|
- (void) insertObjects: (NSArray *)objects atArrangedObjectIndexPaths: (NSArray *)indexPaths
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
2024-07-19 14:14:18 +00:00
|
|
|
if ([self canAddChild]
|
|
|
|
&& [self countKeyPath] == nil)
|
|
|
|
{
|
|
|
|
if ([objects count] != [indexPaths count])
|
2024-07-12 10:22:56 +00:00
|
|
|
{
|
2024-07-19 14:14:18 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
NSUInteger i = 0;
|
|
|
|
|
|
|
|
FOR_IN(id, object, objects)
|
|
|
|
{
|
|
|
|
NSIndexPath *indexPath = [indexPaths objectAtIndex: i];
|
|
|
|
|
|
|
|
[self insertObject: object atArrangedObjectIndexPath: indexPath];
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
END_FOR_IN(objects);
|
2024-07-12 10:22:56 +00:00
|
|
|
}
|
|
|
|
}
|
2013-08-19 19:10:22 +00:00
|
|
|
}
|
|
|
|
|
2024-07-12 10:22:56 +00:00
|
|
|
- (IBAction) insert: (id)sender
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
2024-07-19 14:14:18 +00:00
|
|
|
[self addChild: sender];
|
2013-08-19 19:10:22 +00:00
|
|
|
}
|
|
|
|
|
2024-07-12 14:39:47 +00:00
|
|
|
- (void) removeObjectAtArrangedObjectIndexPath: (NSIndexPath *)indexPath
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
2024-07-12 12:49:52 +00:00
|
|
|
NSUInteger length = [indexPath length];
|
|
|
|
NSUInteger pos = 0;
|
|
|
|
NSMutableArray *children = [_arranged_objects mutableChildNodes];
|
|
|
|
NSUInteger lastIndex = 0;
|
|
|
|
|
|
|
|
for (pos = 0; pos < length - 1; pos++)
|
|
|
|
{
|
|
|
|
NSUInteger i = [indexPath indexAtPosition: pos];
|
|
|
|
id node = [children objectAtIndex: i];
|
|
|
|
|
|
|
|
children = [node valueForKeyPath: _childrenKeyPath];
|
|
|
|
}
|
|
|
|
|
|
|
|
lastIndex = [indexPath indexAtPosition: length - 1];
|
|
|
|
[children removeObjectAtIndex: lastIndex];
|
|
|
|
[self rearrangeObjects];
|
2013-08-19 19:10:22 +00:00
|
|
|
}
|
|
|
|
|
2024-07-12 14:39:47 +00:00
|
|
|
- (void) removeObjectsAtArrangedObjectIndexPaths: (NSArray *)indexPaths
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
2024-07-12 12:49:52 +00:00
|
|
|
FOR_IN(NSIndexPath*, indexPath, indexPaths)
|
|
|
|
{
|
|
|
|
[self removeObjectAtArrangedObjectIndexPath: indexPath];
|
|
|
|
}
|
|
|
|
END_FOR_IN(indexPaths);
|
2013-08-19 19:10:22 +00:00
|
|
|
}
|
|
|
|
|
2024-07-12 14:39:47 +00:00
|
|
|
- (void) removeSelectionIndexPaths: (NSArray *)indexPaths
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
2024-07-12 13:42:26 +00:00
|
|
|
[self removeObjectsAtArrangedObjectIndexPaths: indexPaths];
|
2013-08-19 19:10:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setAlwaysUsesMultipleValuesMarker: (BOOL)flag
|
|
|
|
{
|
|
|
|
_alwaysUsesMultipleValuesMarker = flag;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setAvoidsEmptySelection: (BOOL)flag
|
|
|
|
{
|
|
|
|
_avoidsEmptySelection = flag;
|
|
|
|
}
|
|
|
|
|
2024-07-12 14:39:47 +00:00
|
|
|
- (void) setChildrenKeyPath: (NSString *)path
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
|
|
|
ASSIGN(_childrenKeyPath, path);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setContent: (id)content
|
|
|
|
{
|
|
|
|
[super setContent: content];
|
2024-06-19 05:46:27 +00:00
|
|
|
[self rearrangeObjects];
|
2013-08-19 19:10:22 +00:00
|
|
|
}
|
|
|
|
|
2024-07-12 14:39:47 +00:00
|
|
|
- (void) setCountKeyPath: (NSString *)path
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
|
|
|
ASSIGN(_countKeyPath, path);
|
|
|
|
}
|
|
|
|
|
2024-07-12 14:39:47 +00:00
|
|
|
- (void) setLeafKeyPath: (NSString *)key
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
|
|
|
ASSIGN(_leafKeyPath, key);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setPreservesSelection: (BOOL)flag
|
|
|
|
{
|
|
|
|
_preservesSelection = flag;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setSelectsInsertedObjects: (BOOL)flag
|
|
|
|
{
|
|
|
|
_selectsInsertedObjects = flag;
|
|
|
|
}
|
|
|
|
|
2024-07-12 14:39:47 +00:00
|
|
|
- (void) setSortDescriptors: (NSArray *)descriptors
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
|
|
|
ASSIGN(_sortDescriptors, descriptors);
|
|
|
|
}
|
|
|
|
|
2024-07-12 14:39:47 +00:00
|
|
|
- (NSString *) childrenKeyPathForNode: (NSTreeNode *)node
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
2024-06-19 05:46:27 +00:00
|
|
|
return _childrenKeyPath;
|
2013-08-19 19:10:22 +00:00
|
|
|
}
|
|
|
|
|
2024-07-12 14:39:47 +00:00
|
|
|
- (NSString *) countKeyPathForNode: (NSTreeNode *)node
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
2024-06-19 05:46:27 +00:00
|
|
|
return _countKeyPath;
|
2013-08-19 19:10:22 +00:00
|
|
|
}
|
|
|
|
|
2024-07-12 14:39:47 +00:00
|
|
|
- (NSString *) leafKeyPathForNode: (NSTreeNode *)node
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
2024-06-19 05:46:27 +00:00
|
|
|
return _leafKeyPath;
|
2013-08-19 19:10:22 +00:00
|
|
|
}
|
|
|
|
|
2024-07-12 14:39:47 +00:00
|
|
|
- (void) moveNode: (NSTreeNode *)node toIndexPath: (NSIndexPath *)indexPath
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
|
|
|
// FIXME
|
|
|
|
}
|
|
|
|
|
2024-07-12 14:39:47 +00:00
|
|
|
- (void) moveNodes: (NSArray *)nodes toIndexPath: (NSIndexPath *)startingIndexPath
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
|
|
|
// FIXME
|
|
|
|
}
|
|
|
|
|
2024-07-12 14:39:47 +00:00
|
|
|
- (NSArray *) selectedNodes
|
2013-08-19 19:10:22 +00:00
|
|
|
{
|
|
|
|
// FIXME
|
2024-07-19 14:14:18 +00:00
|
|
|
return [self selectedObjects];
|
2013-08-19 19:10:22 +00:00
|
|
|
}
|
|
|
|
|
2024-06-19 05:46:27 +00:00
|
|
|
|
|
|
|
- (void) bind: (NSString *)binding
|
|
|
|
toObject: (id)anObject
|
|
|
|
withKeyPath: (NSString *)keyPath
|
|
|
|
options: (NSDictionary *)options
|
|
|
|
{
|
|
|
|
if ([binding isEqual: NSContentArrayBinding])
|
|
|
|
{
|
|
|
|
GSKeyValueBinding *kvb;
|
|
|
|
|
|
|
|
[self unbind: binding];
|
|
|
|
kvb = [[GSKeyValueBinding alloc] initWithBinding: @"content"
|
|
|
|
withName: binding
|
|
|
|
toObject: anObject
|
|
|
|
withKeyPath: keyPath
|
|
|
|
options: options
|
|
|
|
fromObject: self];
|
|
|
|
// The binding will be retained in the binding table
|
|
|
|
RELEASE(kvb);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
[super bind: binding
|
|
|
|
toObject: anObject
|
|
|
|
withKeyPath: keyPath
|
|
|
|
options: options];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-12 14:39:47 +00:00
|
|
|
- (id) initWithCoder: (NSCoder *)coder
|
2012-02-29 15:32:09 +00:00
|
|
|
{
|
2024-06-19 05:46:27 +00:00
|
|
|
self = [super initWithCoder: coder];
|
|
|
|
|
|
|
|
if (self != nil)
|
|
|
|
{
|
2024-07-02 08:05:53 +00:00
|
|
|
[self _initDefaults]; // set up default values...
|
2024-06-19 05:46:27 +00:00
|
|
|
if ([coder allowsKeyedCoding])
|
|
|
|
{
|
|
|
|
// These names do not stick to convention. Usually it would be
|
|
|
|
// NS* or NSTreeController* so they must be overriden in
|
|
|
|
// GSXib5KeyedUnarchver.
|
|
|
|
if ([coder containsValueForKey: @"NSTreeContentChildrenKey"])
|
|
|
|
{
|
|
|
|
[self setChildrenKeyPath:
|
|
|
|
[coder decodeObjectForKey: @"NSTreeContentChildrenKey"]];
|
|
|
|
}
|
|
|
|
if ([coder containsValueForKey: @"NSTreeContentCountKey"])
|
|
|
|
{
|
|
|
|
[self setCountKeyPath:
|
|
|
|
[coder decodeObjectForKey: @"NSTreeContentCountKey"]];
|
|
|
|
}
|
|
|
|
if ([coder containsValueForKey: @"NSTreeContentLeafKey"])
|
|
|
|
{
|
|
|
|
[self setLeafKeyPath:
|
|
|
|
[coder decodeObjectForKey: @"NSTreeContentLeafKey"]];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Since we don't inherit from NSArrayController these are decoded here
|
|
|
|
// as well.
|
|
|
|
if ([coder containsValueForKey: @"NSAvoidsEmptySelection"])
|
|
|
|
{
|
|
|
|
[self setAvoidsEmptySelection:
|
|
|
|
[coder decodeBoolForKey: @"NSAvoidsEmptySelection"]];
|
|
|
|
}
|
|
|
|
if ([coder containsValueForKey: @"NSPreservesSelection"])
|
|
|
|
{
|
|
|
|
[self setPreservesSelection:
|
|
|
|
[coder decodeBoolForKey: @"NSPreservesSelection"]];
|
|
|
|
}
|
|
|
|
if ([coder containsValueForKey: @"NSSelectsInsertedObjects"])
|
|
|
|
{
|
|
|
|
[self setSelectsInsertedObjects:
|
|
|
|
[coder decodeBoolForKey: @"NSSelectsInsertedObjects"]];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
id obj = nil;
|
|
|
|
BOOL f = NO;
|
|
|
|
|
|
|
|
obj = [coder decodeObject];
|
|
|
|
[self setChildrenKeyPath: obj];
|
|
|
|
obj = [coder decodeObject];
|
|
|
|
[self setCountKeyPath: obj];
|
|
|
|
obj = [coder decodeObject];
|
|
|
|
[self setLeafKeyPath: obj];
|
|
|
|
|
|
|
|
[coder decodeValueOfObjCType: @encode(BOOL)
|
|
|
|
at: &f];
|
|
|
|
[self setAvoidsEmptySelection: f];
|
|
|
|
[coder decodeValueOfObjCType: @encode(BOOL)
|
|
|
|
at: &f];
|
|
|
|
[self setPreservesSelection: f];
|
|
|
|
[coder decodeValueOfObjCType: @encode(BOOL)
|
|
|
|
at: &f];
|
|
|
|
[self setSelectsInsertedObjects: f];
|
|
|
|
}
|
|
|
|
|
2012-02-29 15:32:09 +00:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2024-07-12 14:39:47 +00:00
|
|
|
- (void) encodeWithCoder: (NSCoder *)coder
|
2012-02-29 15:32:09 +00:00
|
|
|
{
|
2024-06-19 05:46:27 +00:00
|
|
|
[super encodeWithCoder: coder];
|
|
|
|
if ([coder allowsKeyedCoding])
|
|
|
|
{
|
|
|
|
[coder encodeObject: _childrenKeyPath
|
|
|
|
forKey: @"NSTreeContentChildrenKey"];
|
|
|
|
[coder encodeObject: _countKeyPath
|
|
|
|
forKey: @"NSTreeContentCountKey"];
|
|
|
|
[coder encodeObject: _leafKeyPath
|
|
|
|
forKey: @"NSTreeContentLeafKey"];
|
|
|
|
|
|
|
|
|
|
|
|
[coder encodeBool: _avoidsEmptySelection
|
|
|
|
forKey: @"NSAvoidsEmptySelection"];
|
|
|
|
[coder encodeBool: _preservesSelection
|
|
|
|
forKey: @"NSPreservesSelection"];
|
|
|
|
[coder encodeBool: _selectsInsertedObjects
|
|
|
|
forKey: @"NSSelectsInsertedObjects"];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
id obj = nil;
|
|
|
|
BOOL f = NO;
|
|
|
|
|
|
|
|
obj = [self childrenKeyPath];
|
|
|
|
[coder encodeObject: obj];
|
|
|
|
obj = [self countKeyPath];
|
|
|
|
[coder encodeObject: obj];
|
|
|
|
obj = [self leafKeyPath];
|
|
|
|
[coder encodeObject: obj];
|
|
|
|
|
|
|
|
f = [self avoidsEmptySelection];
|
|
|
|
[coder encodeValueOfObjCType: @encode(BOOL)
|
|
|
|
at: &f];
|
|
|
|
f = [self preservesSelection];
|
|
|
|
[coder encodeValueOfObjCType: @encode(BOOL)
|
|
|
|
at: &f];
|
|
|
|
f = [self selectsInsertedObjects];
|
|
|
|
[coder encodeValueOfObjCType: @encode(BOOL)
|
|
|
|
at: &f];
|
|
|
|
}
|
2012-02-29 15:32:09 +00:00
|
|
|
}
|
|
|
|
|
2024-07-12 14:39:47 +00:00
|
|
|
- (id) copyWithZone: (NSZone *)zone
|
2012-02-29 15:32:09 +00:00
|
|
|
{
|
2024-06-28 12:39:39 +00:00
|
|
|
id copy = [[NSTreeController allocWithZone: zone] initWithContent: [self content]];
|
|
|
|
|
|
|
|
if (copy != nil)
|
|
|
|
{
|
|
|
|
[copy setChildrenKeyPath: [self childrenKeyPath]];
|
|
|
|
[copy setCountKeyPath: [self countKeyPath]];
|
|
|
|
[copy setLeafKeyPath: [self leafKeyPath]];
|
|
|
|
|
|
|
|
[copy setAvoidsEmptySelection: [self avoidsEmptySelection]];
|
|
|
|
[copy setPreservesSelection: [self preservesSelection]];
|
|
|
|
[copy setSelectsInsertedObjects: [self selectsInsertedObjects]];
|
|
|
|
}
|
2024-07-12 12:49:52 +00:00
|
|
|
|
2024-06-28 12:39:39 +00:00
|
|
|
return copy;
|
2012-02-29 15:32:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@end
|