*** empty log message ***
authorca
Fri, 15 Feb 2002 13:01:52 +0100
changeset 2081 409ed8b04ae2
parent 2080 f37673e44158
child 2082 fcb8b7ab1664
*** empty log message ***
HierarchicalItem.st
--- a/HierarchicalItem.st	Mon Feb 11 20:52:06 2002 +0100
+++ b/HierarchicalItem.st	Fri Feb 15 13:01:52 2002 +0100
@@ -73,8 +73,23 @@
     ^ (self basicNew) initialize
 ! !
 
+!HierarchicalItem class methodsFor:'protocol'!
+
+doResetExtentOnChange
+    "true: the extent of the item is reset if a change
+     notification is raised from the item. the default is true
+    "
+    ^ true
+! !
+
 !HierarchicalItem methodsFor:'accessing'!
 
+getChildren
+    "returns the children at it is; not going to the model ...
+    "
+    ^ children
+!
+
 level
     "returns the level starting with 1
     "
@@ -138,29 +153,35 @@
 at:anIndex put:anItem
     "replace a child by a new item
     "
-    |oldItem itemExpanded size|
-
-    size := self children size.
-
-    (anIndex between:1 and:size) ifFalse:[
-        ^ self subscriptBoundsError
-    ].
+    |item list|
 
     anItem isNil ifTrue:[
         ^ self removeFromIndex:anIndex toIndex:anIndex.
     ].
-    self criticalDo:[
-        oldItem := children at:anIndex.
-        oldItem collapse.
-        itemExpanded := anItem isExpanded.
-        anItem setExpanded:false.
-        children at:anIndex put:anItem.
-        self changed.
+
+    (    (list := self children) isNil
+     or:[(item := list at:anIndex ifAbsent:nil) isNil]
+    ) ifTrue:[
+        ^ self subscriptBoundsError
+    ].
+
+    self criticalDo:[ |expFlag newIdx|
+        item collapse.
 
-        itemExpanded ifTrue:[
-            anItem expand
-        ]
+        (list := self children) notNil ifTrue:[
+            newIdx := list identityIndexOf:item.
+
+            newIdx ~~ 0 ifTrue:[
+                expFlag := anItem isExpanded.
+                anItem setExpanded:false.
+                list at:anIndex put:anItem.
+                self changed.
+
+                expFlag ifTrue:[anItem expand].
+            ].
+        ].
     ].
+    ^ anItem
 !
 
 children:aListOfChildren
@@ -182,7 +203,7 @@
 last
     "returns the last child
     "
-    ^ self at:(self children size)
+    ^ self at:(self size)
 !
 
 second
@@ -194,18 +215,19 @@
 !HierarchicalItem methodsFor:'accessing-hierarchy'!
 
 collapse
-    "hide children
+    "hide all my subitems
     "
-    |visChd model index|
+    |visChd index|
 
     self canCollapse ifTrue:[
         isExpanded := false.
 
         self criticalDo:[
             (index := self listIndex) notNil ifTrue:[
+                "/ do not call :#size: children will be autoloaded !!!!
                 (visChd := children size) ~~ 0 ifTrue:[
-                    children do:[:aChild|
-                        visChd := visChd + aChild numberOfVisibleChildren
+                    self noneCriticalFrom:1 to:nil do:[:el|
+                        visChd := visChd + el numberOfVisibleChildren
                     ].
                     self model itemRemoveFromIndex:(index + 1) toIndex:(index + visChd).
                     index ~~ 0 ifTrue:[self hierarchyChanged]
@@ -218,19 +240,18 @@
 expand
     "expand children
     "
-    |index list|
-
     self canExpand ifTrue:[
-        self criticalDo:[
+        self criticalDo:[ |index list|
             (index := self listIndex) notNil ifTrue:[
                 "/ must set expand-flag to false, otherwise change notifications
                 "/ are raised durring lazy auto creation (to the list).
                 isExpanded := false.
+                list := self children.
 
-                (children notNil or:[self children notNil]) ifTrue:[
+                list notNil ifTrue:[
                     isExpanded := true.
 
-                    children notEmpty ifTrue:[
+                    list notEmpty ifTrue:[
                         list := OrderedCollection new:64.
                         self addVisibleChildrenTo:list.
                         self model itemAddAll:list beforeIndex:(index + 1).
@@ -257,7 +278,7 @@
 !
 
 recursiveCollapse
-    "collapse children and sub-children
+    "collapse all item and sub items
      **** must be expanded
     "
     |visChd index|
@@ -265,10 +286,11 @@
     self canCollapse ifTrue:[
         self criticalDo:[
             (index := self listIndex) notNil ifTrue:[
+                "/ do not call :#size: children will be autoloaded !!!!
                 (visChd := children size) ~~ 0 ifTrue:[
-                    children do:[:aChild|
-                        visChd := visChd + aChild numberOfVisibleChildren
-                    ]
+                    self noneCriticalFrom:1 to:nil do:[:el|
+                        visChd := visChd + el numberOfVisibleChildren
+                    ].
                 ].
                 self recursiveSetCollapsed.
 
@@ -284,22 +306,23 @@
             ]
         ]
     ]
-
 !
 
 recursiveExpand
     "expand children and sub-children
      **** must be collapsed
     "
-    |model index list|
+    |index list|
 
     self canExpand ifTrue:[
         isExpanded := true.
 
         self criticalDo:[
-            self children size ~~ 0 ifTrue:[
+            self size ~~ 0 ifTrue:[
                 (index := self listIndex) isNil ifTrue:[
-                    children do:[:aChild| aChild setExpanded:true ]
+                    self noneCriticalFrom:1 to:nil do:[:el|
+                        el setExpanded:true
+                    ].
                 ] ifFalse:[
                     list := OrderedCollection new:512.
                     self recursiveSetExpandedAndAddToList:list.
@@ -313,29 +336,25 @@
 !
 
 recursiveToggleExpand
-    "if the item is collapsed, the children and all sub-children
+    "if the item is collapsed, the item and all its sub-items
      are expanded otherwise collapsed
     "
-    (isExpanded == true) ifTrue:[
+    isExpanded == true ifTrue:[
         self recursiveCollapse
     ] ifFalse:[
         self recursiveExpand
     ]
-
 !
 
 toggleExpand
-    "if the item is collapsed, the children are expanded
-     otherwise collapsed
+    "if the item is collapsed, the item is expanded otherwise
+     collapsed.
     "
-    self criticalDo:[
-        (isExpanded == true) ifTrue:[
-            self collapse
-        ] ifFalse:[
-            self expand
-        ]
-    ]
-
+    isExpanded == true ifTrue:[
+        self collapse
+    ] ifFalse:[
+        self expand
+    ].
 ! !
 
 !HierarchicalItem methodsFor:'accessing-mvc'!
@@ -724,7 +743,9 @@
 
     what ~~ #redraw ifTrue:[
         (what ~~ #hierarchy and:[what ~~ #icon]) ifTrue:[
-            width := height := nil
+            self class doResetExtentOnChange ifTrue:[
+                width := height := nil
+            ].
         ].
         why := what
     ].
@@ -764,64 +785,105 @@
     "
     |coll|
 
-    coll := #().
-
-    self criticalNoneEmptyChildren:[:list|
-        coll := OrderedCollection new.
-        list do:[:aChild| coll add:(aBlock value:aChild) ]
-    ].
-    ^ coll
+    coll := OrderedCollection new.
+    self do:[:el| coll add:(aBlock value:el) ].
+  ^ coll
 !
 
 do:aOneArgBlock
     "evaluate a block on each child
     "
-    ^ self criticalNoneEmptyChildren:[:list|
-        list do:aOneArgBlock
-    ].
+    ^ self from:1 do:aOneArgBlock
 !
 
 from:startIndex do:aOneArgBlock
     "evaluate a block on each child starting with the
      child at startIndex to the end.
     "
-    ^ self from:startIndex to:self size do:aOneArgBlock
+    |res|
+
+    self size < startIndex ifTrue:[^ nil].
+    res := nil.
+
+    self criticalDo:[
+        res := self noneCriticalFrom:startIndex to:nil do:aOneArgBlock
+    ].
+    ^ res
+!
+
+from:startIndex reverseDo:aOneArgBlock
+    "evaluate a block on each child starting at end to the startIndex
+    "
+    |res|
+
+    self size < startIndex ifTrue:[^ nil].
+    res := nil.
+
+    self criticalDo:[
+        res := self noneCriticalFrom:startIndex to:nil reverseDo:aOneArgBlock
+    ].
+    ^ res
 !
 
 from:startIndex to:endIndex do:aOneArgBlock
     "evaluate a block on each child starting with the
      child at startIndex to the endIndex.
     "
-    ^ self criticalNoneEmptyChildren:[:list|
-        list from:startIndex to:endIndex do:aOneArgBlock
+    |res|
+
+    self size < startIndex ifTrue:[^ nil].
+    res := nil.
+
+    self criticalDo:[
+        res := self noneCriticalFrom:startIndex to:endIndex do:aOneArgBlock
     ].
+    ^ res
 !
 
 from:startIndex to:endIndex reverseDo:aOneArgBlock
     "evaluate a block on each child starting with the
      child at endIndex to the startIndex.
     "
-    ^ self criticalNoneEmptyChildren:[:list|
-        list from:startIndex to:endIndex reverseDo:aOneArgBlock
+    |res|
+
+    self size < startIndex ifTrue:[^ nil].
+    res := nil.
+
+    self criticalDo:[
+        res := self noneCriticalFrom:startIndex to:endIndex reverseDo:aOneArgBlock
     ].
+    ^ res
 !
 
 keysAndValuesDo:aTwoArgBlock
     "evaluate the argument, aBlock for every child,
-     passing both index and element as arguments."
+     passing both index and element as arguments.
+    "
+    |key res|
 
-    ^ self criticalNoneEmptyChildren:[:list|
-        list keysAndValuesDo:aTwoArgBlock
+    key := 1.
+    res := nil.
+
+    self do:[:el|
+        res := el value:key value:el.
+        key := key + 1.
     ].
+    ^ res
 !
 
 keysAndValuesReverseDo:aTwoArgBlock
     "evaluate the argument, aBlock in reverse order for every
-     child, passing both index and element as arguments."
+     child, passing both index and element as arguments.
+    "
+    |res|
 
-    ^ self criticalNoneEmptyChildren:[:list|
-        list keysAndValuesReverseDo:aTwoArgBlock
+    self size == 0 ifTrue:[^ nil].
+    res := nil.
+
+    self criticalDo:[
+        res := self noneCriticalKeysAndValuesReverseDo:aTwoArgBlock
     ].
+    ^ res
 !
 
 recursiveCollect:aBlock
@@ -866,34 +928,30 @@
 !
 
 reverseDo:aOneArgBlock
-    "evaluate a block on each child
-     proccesing children in reverse direction
+    "evaluate a block on each child in reverse direction
     "
-    ^ self criticalNoneEmptyChildren:[:list|
-        list reverseDo:aOneArgBlock
-    ].
+    ^ self from:1 reverseDo:aOneArgBlock
 !
 
 select:aBlock
-    "return a new collection with all children from the receiver, for which
+    "return a new collection with all items from the receiver, for which
      the argument aBlock evaluates to true.
     "
     |coll|
 
-    coll := #().
-
-    self criticalNoneEmptyChildren:[:list|
-        coll := OrderedCollection new.
-        list do:[:el| (aBlock value:el) ifTrue:[coll add:el] ].
-    ].
-    ^ coll
+    coll := OrderedCollection new.
+    self do:[:el| (aBlock value:el) ifTrue:[coll add:el] ].
+  ^ coll
 !
 
 withAllDo:aOneArgBlock
-    "evaluate the block on each item including self
+    "evaluate the block on each item and subitem including self
     "
-    ^ self criticalDo:[
-        self noneCriticalWithAllDo:aOneArgBlock
+    aOneArgBlock value:self.
+
+    self do:[:el|
+        aOneArgBlock value:el.
+        el noneCriticalRecursiveDo:aOneArgBlock.
     ].
 ! !
 
@@ -947,19 +1005,12 @@
 addVisibleChildrenTo:aList
     "add all visible children and sub-children to the list
     "
-    isExpanded == true ifTrue:[
-        (children notNil or:[self children notNil]) ifTrue:[
-            children do:[:aChild|
-                aList add:aChild.
-                aChild addVisibleChildrenTo:aList
-            ]
-        ]
-    ]
+    isExpanded == true ifFalse:[^ self].
 
-
-
-
-
+    self noneCriticalFrom:1 to:nil do:[:el|
+        aList add:el.
+        el addVisibleChildrenTo:aList.
+    ].
 !
 
 criticalDo:aBlock
@@ -972,24 +1023,6 @@
     ]
 !
 
-criticalNoneEmptyChildren:aOneArgBlockTheChildren
-    "evaluate the block on the list of children if not empty
-     within a critical region
-    "
-    |resp|
-
-    self children size ~~ 0 ifTrue:[
-        self criticalDo:[ |list|
-            list := self children.
-
-            list size ~~ 0 ifTrue:[
-                resp := aOneArgBlockTheChildren value:list
-            ]
-        ]
-    ].
-    ^ resp
-!
-
 listIndex
     "returns the visible index or nil; for a none visible root
      0 is returned
@@ -1009,23 +1042,15 @@
 numberOfVisibleChildren
     "returns number of all visible children including subchildren
     "
-    |size  "{ Class: SmallInteger }"
-    |
-    (isExpanded == true) ifTrue:[
-        (children notNil or:[self children notNil]) ifTrue:[
-            (size := children size) ~~ 0 ifTrue:[
-                self criticalDo:[
-                    children do:[:el| size := size + el numberOfVisibleChildren ].
-                ].
-                ^ size
-            ]
-        ]
+    |size|
+
+    isExpanded == true ifFalse:[^ 0].
+    size := 0.
+
+    self noneCriticalFrom:1 to:nil do:[:el|
+        size := 1 + size + el numberOfVisibleChildren
     ].
-    ^ 0
-
-
-
-
+    ^ size
 !
 
 parentOrModel
@@ -1117,18 +1142,74 @@
 
 !HierarchicalItem methodsFor:'private enumerating'!
 
+noneCriticalFrom:startIndex to:endIndex do:aOneArgBlock
+    "evaluate a block none critical on each child starting with the
+     child at startIndex to the endIndex (if nil to end of list).
+    "
+    |list size resp|
+
+    list := self children.
+    size := list size.
+
+    startIndex > size ifTrue:[^ nil].
+    resp := nil.
+
+    endIndex notNil ifTrue:[
+        size := size min:endIndex
+    ].
+    startIndex to:size do:[:i| |item|
+        item := list at:i ifAbsent:nil.
+        item isNil ifTrue:[^ resp].
+        resp := aOneArgBlock value:item.
+    ].
+    ^ resp
+!
+
+noneCriticalFrom:startIndex to:endIndex reverseDo:aOneArgBlock
+    "evaluate a block none critical on each child starting with the
+     child at endIndex (if nil to end of list) to startIndex.
+    "
+    |list size resp|
+
+    list := self children.
+    size := list size.
+    resp := nil.
+
+    endIndex notNil ifTrue:[
+        size := size min:endIndex
+    ].
+    size to:startIndex by:-1 do:[:i| |item|
+        item := list at:i ifAbsent:nil.
+        item isNil ifTrue:[^ resp].
+        resp := aOneArgBlock value:item.
+    ].
+    ^ resp
+!
+
+noneCriticalKeysAndValuesReverseDo:aOneArgBlock
+    "evaluate the argument, aBlock in reverse order for every
+     child, passing both index and element as arguments.
+    "
+    |list size resp|
+
+    list := self children.
+    size := list size.
+    resp := nil.
+
+    size to:1 by:-1 do:[:i| |item|
+        item := list at:i ifAbsent:nil.
+        item isNil ifTrue:[^ resp].
+        resp := aOneArgBlock value:i value:item.
+    ].
+    ^ resp
+!
+
 noneCriticalRecursiveDo:anOneArgBlock
     "evaluate the block none critical on each item and all the sub-items
     "
-    |loe|
-
-    loe := self children.
-
-    loe size ~~ 0 ifTrue:[
-        loe do:[:aChild|
-            anOneArgBlock value:aChild.
-            aChild noneCriticalRecursiveDo:anOneArgBlock
-        ]
+    self noneCriticalFrom:1 to:nil do:[:aChild|
+        anOneArgBlock value:aChild.
+        aChild noneCriticalRecursiveDo:anOneArgBlock
     ].
 !
 
@@ -1136,29 +1217,9 @@
     "evaluate the block none critical on each item and all the sub-items;
      proccesing children in reverse direction
     "
-    |loe|
-
-    loe := self children.
-
-    loe size ~~ 0 ifTrue:[
-        loe reverseDo:[:aChild|
-            aChild noneCriticalRecursiveReverseDo:anOneArgBlock.
-            anOneArgBlock value:aChild.
-        ]
-    ].
-!
-
-noneCriticalWithAllDo:aOneArgBlock
-    "evaluate the block none critical on each item including self
-    "
-    |loe|
-
-    aOneArgBlock value:self.
-
-    loe := self children.
-
-    loe size ~~ 0 ifTrue:[
-        loe do:[:el| el withAllDo:aOneArgBlock ]
+    self noneCriticalFrom:1 to:nil reverseDo:[:aChild|
+        aChild noneCriticalRecursiveReverseDo:anOneArgBlock.
+        anOneArgBlock value:aChild.
     ].
 ! !
 
@@ -1169,8 +1230,9 @@
     "
     isExpanded := false.
 
-    children notNil ifTrue:[
-        children do:[:aChild| aChild recursiveSetCollapsed ]
+    "/ do not call :#size: children will be autoloaded !!!!
+    children size ~~ 0 ifTrue:[
+        self noneCriticalFrom:1 to:nil do:[:el| el recursiveSetCollapsed ].
     ]
 !
 
@@ -1180,15 +1242,10 @@
     "
     isExpanded := true.
 
-    (children notNil or:[self children notNil]) ifTrue:[
-        self criticalDo:[
-            children do:[:aChild|
-                aList add:aChild.
-                aChild recursiveSetExpandedAndAddToList:aList.
-            ]
-        ]
-    ]
-
+    self do:[:anItem|
+        aList add:anItem.
+        anItem recursiveSetExpandedAndAddToList:aList.
+    ].
 ! !
 
 !HierarchicalItem methodsFor:'protocol accessing'!
@@ -1331,8 +1388,7 @@
      be loaded yet( ex. FileDirectory ).
      *** to optimize:redefine by subClass
     "
-    ^ children notNil ifTrue:[children notEmpty]
-                     ifFalse:[self children size ~~ 0]
+    ^ self children size ~~ 0
 !
 
 string
@@ -1433,8 +1489,7 @@
 size
     "return the number of children
     "
-    ^ children notNil ifTrue:[children size]
-                     ifFalse:[self children size]
+    ^ self children size
 ! !
 
 !HierarchicalItem methodsFor:'searching'!
@@ -1447,23 +1502,12 @@
 
 !
 
-detect:aOneArgBlock ifNone:anExceptionBlock
+detect:anOneArgBlock ifNone:anExceptionBlock
     "find the first child, for which evaluation of the block returns
      true; if none does so, return the evaluation of anExceptionBlock
     "
-    |item|
-
-    self children size ~~ 0 ifTrue:[
-        self criticalDo:[
-            item := children detect:aOneArgBlock ifNone:nil
-        ].
-        item notNil ifTrue:[
-            ^ item
-        ] 
-    ].
-    ^ anExceptionBlock value
-
-
+    self do:[:el| (anOneArgBlock value:el) ifTrue:[^ el] ].
+  ^ anExceptionBlock value
 !
 
 detectLast:aOneArgBlock
@@ -1474,43 +1518,28 @@
 
 !
 
-detectLast:aOneArgBlock ifNone:anExceptionBlock
+detectLast:anOneArgBlock ifNone:anExceptionBlock
     "find the last child, for which evaluation of the block returns
      true; if none does so, return the evaluation of anExceptionBlock
     "
-    |item|
-
-    self children size ~~ 0 ifTrue:[
-        self criticalDo:[
-            item := children detectLast:aOneArgBlock ifNone:nil
-        ].
-        item notNil ifTrue:[
-            ^ item
-        ]
-    ].
-    ^ anExceptionBlock value
-
-
+    self reverseDo:[:el| (anOneArgBlock value:el) ifTrue:[^ el] ].
+  ^ anExceptionBlock value
 !
 
-findFirst:aOneArgBlock
+findFirst:anOneArgBlock
     "find the first child, for which evaluation of the argument, aOneArgBlock
      returns true; return its index or 0 if none detected.
     "
-    self keysAndValuesDo:[:anIndex :aChild|
-        (aOneArgBlock value:aChild) ifTrue:[^ anIndex]
-    ].
-    ^ 0
+    self keysAndValuesDo:[:i :el| (anOneArgBlock value:el) ifTrue:[^ i] ].
+  ^ 0
 !
 
-findLast:aOneArgBlock
+findLast:anOneArgBlock
     "find the last child, for which evaluation of the argument, aOneArgBlock
      returns true; return its index or 0 if none detected.
     "
-    self keysAndValuesReverseDo:[:anIndex :aChild|
-        (aOneArgBlock value:aChild) ifTrue:[^ anIndex]
-    ].
-    ^ 0
+    self keysAndValuesReverseDo:[:i :el| (anOneArgBlock value:el) ifTrue:[^ i] ].
+  ^ 0
 !
 
 identityIndexOf:aChild
@@ -1525,14 +1554,13 @@
     "
     |index|
 
-    index := 0.
+    index := startIndex.
 
-    self children size ~~ 0 ifTrue:[
-        self criticalDo:[
-            index := children identityIndexOf:aChild startingAt:startIndex
-        ]
+    self from:startIndex do:[:el|
+        el == aChild ifTrue:[^ index ].
+        index := index + 1.
     ].
-    ^ index
+    ^ 0
 !
 
 recursiveDetect:aOneArgBlock
@@ -1704,5 +1732,5 @@
 !HierarchicalItem class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libwidg2/HierarchicalItem.st,v 1.36 2001-10-15 07:21:10 martin Exp $'
+    ^ '$Header: /cvs/stx/stx/libwidg2/HierarchicalItem.st,v 1.37 2002-02-15 12:01:52 ca Exp $'
 ! !