00001 00002 @import <Foundation/CPObject.j> 00003 00004 00005 @implementation CPTreeNode : CPObject 00006 { 00007 id _representedObject @accessors(readonly, property=representedObject); 00008 00009 CPTreeNode _parentNode @accessors(readonly, property=parentNode); 00010 CPMutableArray _childNodes; 00011 } 00012 00013 + (id)treeNodeWithRepresentedObject:(id)anObject 00014 { 00015 return [[self alloc] initWithRepresentedObject:anObject]; 00016 } 00017 00018 - (id)initWithRepresentedObject:(id)anObject 00019 { 00020 self = [super init]; 00021 00022 if (self) 00023 { 00024 _representedObject = anObject; 00025 _childNodes = []; 00026 } 00027 00028 return self; 00029 } 00030 00031 - (BOOL)isLeaf 00032 { 00033 return [_childNodes count] <= 0; 00034 } 00035 00036 - (CPArray)childNodes 00037 { 00038 return [_childNodes copy]; 00039 } 00040 00041 - (CPMutableArray)mutableChildNodes 00042 { 00043 return [self mutableArrayValueForKey:@"childNodes"]; 00044 } 00045 00046 - (void)insertObject:(id)aTreeNode inChildNodesAtIndex:(CPInteger)anIndex 00047 { 00048 [[aTreeNode._parentNode mutableChildNodes] removeObjectIdenticalTo:aTreeNode]; 00049 00050 aTreeNode._parentNode = self; 00051 00052 [_childNodes insertObject:aTreeNode atIndex:anIndex]; 00053 } 00054 00055 - (void)removeObjectFromChildNodesAtIndex:(CPInteger)anIndex 00056 { 00057 [_childNodes objectAtIndex:anIndex]._parentNode = nil; 00058 00059 [_childNodes removeObjectAtIndex:anIndex]; 00060 } 00061 00062 - (void)replaceObjectFromChildNodesAtIndex:(CPInteger)anIndex withObject:(id)aTreeNode 00063 { 00064 var oldTreeNode = [_childNodes objectAtIndex:anIndex]; 00065 00066 oldTreeNode._parentNode = nil; 00067 aTreeNode._parentNode = self; 00068 00069 [_childNodes replaceObjectAtIndex:anIndex withObject:aTreeNode]; 00070 } 00071 00072 - (id)objectInChildNodesAtIndex:(CPInteger)anIndex 00073 { 00074 return _childNodes[anIndex]; 00075 } 00076 00077 - (void)sortWithSortDescriptors:(CPArray)sortDescriptors recursively:(BOOL)shouldSortRecursively 00078 { 00079 [_childNodes sortUsingDescriptors:sortDescriptors]; 00080 00081 if (!shouldSortRecursively) 00082 return; 00083 00084 var count = [_childNodes count]; 00085 00086 while (count--) 00087 [_childNodes[count] sortWithSortDescriptors:sortDescriptors recursively:YES]; 00088 } 00089 00090 @end 00091 00092 var CPTreeNodeRepresentedObjectKey = @"CPTreeNodeRepresentedObjectKey", 00093 CPTreeNodeParentNodeKey = @"CPTreeNodeParentNodeKey", 00094 CPTreeNodeChildNodesKey = @"CPTreeNodeChildNodesKey"; 00095 00096 @implementation CPTreeNode (CPCoding) 00097 00098 - (id)initWithCoder:(CPCoder)aCoder 00099 { 00100 self = [super init]; 00101 00102 if (self) 00103 { 00104 _representedObject = [aCoder decodeObjectForKey:CPTreeNodeRepresentedObjectKey]; 00105 _parentNode = [aCoder decodeObjectForKey:CPTreeNodeParentNodeKey]; 00106 _childNodes = [aCoder decodeObjectForKey:CPTreeNodeChildNodesKey]; 00107 } 00108 00109 return self; 00110 } 00111 00112 - (void)encodeWithCoder:(CPCoder)aCoder 00113 { 00114 [aCoder encodeObject:_representedObject forKey:CPTreeNodeRepresentedObjectKey]; 00115 [aCoder encodeConditionalObject:_parentNode forKey:CPTreeNodeParentNodeKey]; 00116 [aCoder encodeObject:_childNodes forKey:CPTreeNodeChildNodesKey]; 00117 } 00118 00119 @end