1/* 2 NSTreeNode.m 3 4 The tree node class 5 6 Copyright (C) 2013 Free Software Foundation, Inc. 7 8 Author: Fred Kiefer <fredkiefer@gmx.de> 9 Date: 2013 10 11 This file is part of the GNUstep GUI Library. 12 13 This library is free software; you can redistribute it and/or 14 modify it under the terms of the GNU Lesser General Public 15 License as published by the Free Software Foundation; either 16 version 2 of the License, or (at your option) any later version. 17 18 This library is distributed in the hope that it will be useful, 19 but WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 Lesser General Public License for more details. 22 23 You should have received a copy of the GNU Lesser General Public 24 License along with this library; see the file COPYING.LIB. 25 If not, see <http://www.gnu.org/licenses/> or write to the 26 Free Software Foundation, 51 Franklin Street, Fifth Floor, 27 Boston, MA 02110-1301, USA. 28*/ 29 30#import <Foundation/NSArray.h> 31#import <Foundation/NSIndexPath.h> 32#import <Foundation/NSString.h> 33#import <Foundation/NSSortDescriptor.h> 34 35#import <AppKit/NSTreeNode.h> 36 37@interface NSTreeNode (Private) 38- (NSMutableArray*) _childNodes; 39- (void) _setParentNode: (NSTreeNode*)parentNode; 40@end 41 42@implementation NSTreeNode (Private) 43- (NSMutableArray*) _childNodes 44{ 45 return _childNodes; 46} 47 48- (void) _setParentNode: (NSTreeNode*)parentNode 49{ 50 _parentNode = parentNode; 51} 52 53@end 54 55 56@interface GSTreeNodeArray : NSMutableArray 57{ 58 NSMutableArray *array; 59 NSTreeNode *parent; 60} 61 62@end 63 64@implementation GSTreeNodeArray 65 66- (id) initForTreeNode: (NSTreeNode*)node 67{ 68 ASSIGN(parent, node); 69 array = [parent _childNodes]; 70 return self; 71} 72 73- (void) dealloc 74{ 75 RELEASE(parent); 76 [super dealloc]; 77} 78 79- (NSUInteger) count 80{ 81 return [array count]; 82} 83 84- (id) objectAtIndex: (NSUInteger)index 85{ 86 return [array objectAtIndex: index]; 87} 88 89- (void) addObject: (id)anObject 90{ 91 [array addObject: anObject]; 92 [(NSTreeNode*)anObject _setParentNode: parent]; 93} 94 95- (void) replaceObjectAtIndex: (NSUInteger)index withObject: (id)anObject 96{ 97 id old = [array objectAtIndex: index]; 98 99 [(NSTreeNode*)old _setParentNode: nil]; 100 [array replaceObjectAtIndex: index withObject: anObject]; 101 [(NSTreeNode*)anObject _setParentNode: parent]; 102} 103 104- (void) insertObject: anObject atIndex: (NSUInteger)index 105{ 106 [array insertObject: anObject atIndex: index]; 107 [(NSTreeNode*)anObject _setParentNode: parent]; 108} 109 110- (void) removeObjectAtIndex: (NSUInteger)index 111{ 112 id old = [array objectAtIndex: index]; 113 114 [(NSTreeNode*)old _setParentNode: nil]; 115 [array removeObjectAtIndex: index]; 116} 117 118@end 119 120 121@implementation NSTreeNode 122 123+ (id) treeNodeWithRepresentedObject: (id)modelObject 124{ 125 NSTreeNode *node = [[NSTreeNode alloc] initWithRepresentedObject: modelObject]; 126 127 return AUTORELEASE(node); 128} 129 130- (NSArray*) childNodes 131{ 132 return [NSArray arrayWithArray: _childNodes]; 133} 134 135- (NSTreeNode*) descendantNodeAtIndexPath: (NSIndexPath*)path 136{ 137 NSUInteger len = [path length]; 138 NSUInteger i; 139 NSTreeNode *node = self; 140 141 for (i = 0; i < len; i++) 142 { 143 NSUInteger index = [path indexAtPosition: i]; 144 145 node = [node->_childNodes objectAtIndex: index]; 146 if (node == nil) 147 { 148 return nil; 149 } 150 } 151 152 return node; 153} 154 155- (NSIndexPath*) indexPath 156{ 157 if (_parentNode != nil) 158 { 159 NSIndexPath *path; 160 NSUInteger index; 161 162 index = [_parentNode->_childNodes indexOfObject: self]; 163 path = [_parentNode indexPath]; 164 if (path != nil) 165 { 166 return [path indexPathByAddingIndex: index]; 167 } 168 else 169 { 170 return [NSIndexPath indexPathWithIndex: index]; 171 } 172 } 173 else 174 { 175 return nil; 176 } 177} 178 179- (id) initWithRepresentedObject: (id)repObj 180{ 181 ASSIGN(_representedObject, repObj); 182 _childNodes = [[NSMutableArray alloc] init]; 183 return self; 184} 185 186- (void) dealloc 187{ 188 RELEASE(_representedObject); 189 RELEASE(_childNodes); 190 [super dealloc]; 191} 192 193- (BOOL) isLeaf 194{ 195 return [_childNodes count] == 0; 196} 197 198- (NSMutableArray*) mutableChildNodes 199{ 200 GSTreeNodeArray *nodeArray = [[GSTreeNodeArray alloc] initForTreeNode: self]; 201 202 return AUTORELEASE(nodeArray); 203} 204 205- (NSTreeNode*) parentNode 206{ 207 return _parentNode; 208} 209 210- (id) representedObject 211{ 212 return _representedObject; 213} 214 215- (void) sortWithSortDescriptors: (NSArray*)sortDescs recursively: (BOOL)flag 216{ 217 // Sort children nodes 218 NSUInteger i; 219 NSUInteger len = [sortDescs count]; 220 NSMutableArray *newSortDescs = [[NSMutableArray alloc] init]; 221 222 for (i = 0; i < len; i++) 223 { 224 NSSortDescriptor *oldDesc = [sortDescs objectAtIndex: i]; 225 NSString * newKey = [@"representedObject." stringByAppendingString: [oldDesc key]]; 226 NSSortDescriptor *newDesc = [[NSSortDescriptor alloc] 227 initWithKey: newKey 228 ascending: [oldDesc ascending] 229 selector: [oldDesc selector]]; 230 231 [newSortDescs addObject: newDesc]; 232 RELEASE(newDesc); 233 } 234 235 [_childNodes sortUsingDescriptors: newSortDescs]; 236 RELEASE(newSortDescs); 237 238 if (flag) 239 { 240 // sort recursive 241 NSUInteger count = [_childNodes count]; 242 243 for (i = 0; i < count; i++) 244 { 245 [[_childNodes objectAtIndex: i] sortWithSortDescriptors: sortDescs 246 recursively: YES]; 247 } 248 } 249} 250 251@end 252