HierarchicalFileList.st
changeset 2475 1f90c55c4f78
parent 2457 d1505cba8e39
child 2479 82e797682bf9
--- a/HierarchicalFileList.st	Tue Apr 08 14:29:42 2003 +0200
+++ b/HierarchicalFileList.st	Tue Apr 08 15:38:08 2003 +0200
@@ -35,8 +35,8 @@
 !
 
 HierarchicalFileList::HierarchicalFileItem subclass:#Directory
-	instanceVariableNames:'modificationTime fetchOperation makeIconGray'
-	classVariableNames:''
+	instanceVariableNames:'modificationTime makeIconGray quickChildrenInfo'
+	classVariableNames:'StateUnknown StateHasChildren StateHasNoChildren StateFetching'
 	poolDictionaries:''
 	privateIn:HierarchicalFileList
 !
@@ -222,7 +222,7 @@
         index := children findFirst:[:el| el fileName = oldDir ].
         index ~~ 0 ifTrue:[ newRoot at:index put:oldRoot ].
     ].
-    doExpand ifTrue:[ newRoot expand ].
+    doExpand ifTrue:[ newRoot enforcedExpand ].
 !
 
 root:aRoot
@@ -472,7 +472,7 @@
                 item := indicatorList removeFirst.
 
                 (self includesIdentical:item) ifFalse:[
-                    "/ no longer visible
+                    "/ item is no longer visible
                     item resetFetchIndicator.
                     item := nil
                 ]
@@ -783,6 +783,19 @@
 "
 ! !
 
+!HierarchicalFileList::Directory class methodsFor:'initialization'!
+
+initialize
+    StateUnknown := nil.
+    StateHasChildren := #hasChildren.
+    StateHasNoChildren := #hasNoChildren.
+    StateFetching := #fetching
+
+    "
+     self initialize
+    "
+! !
+
 !HierarchicalFileList::Directory methodsFor:'accessing'!
 
 children
@@ -801,30 +814,28 @@
     ^ children
 !
 
-flushChildren
-    "flush the children because node not visible ....
+icon
+    "returns the icon
     "
-    children notNil ifTrue:[
-        "keep hasChildren information
-        "
-        children size ~~ 0 ifTrue:[ fetchOperation := #hasChildren ]
-                          ifFalse:[ fetchOperation := #hasNoChildren ].
-        children := nil.
-    ].
-!
+
+    |nameKey|
 
-icon
-    "returns the icon key
-    "
     isExpanded ifTrue:[
+        (makeIconGray == true) ifTrue:[
+            nameKey := #directoryOpenGray
+        ] ifFalse:[
+            nameKey := #directoryOpen
+        ]
+    ] ifFalse:[
         makeIconGray == true ifTrue:[
-            ^ FileBrowser iconForKeyMatching:#directoryOpenGray
-        ].
-        ^ FileBrowser iconForKeyMatching:#directoryOpen
+            nameKey := #directoryGray
+        ]
     ].
-    makeIconGray == true ifTrue:[
-        ^ FileBrowser iconForKeyMatching:#directoryGray
+
+    nameKey notNil ifTrue:[
+        ^ FileBrowser iconForKeyMatching:nameKey
     ].
+
     icon isNil ifTrue:[
         ^ super icon
     ].
@@ -843,7 +854,7 @@
 !
 
 makeIconGray:something
-    "set the value of the instance variable 'makeIconGray' (automatically generated)"
+    "set/clear the flag which enforces the icon to be shown in grey"
 
     makeIconGray := something.
 !
@@ -859,19 +870,19 @@
     "
     |model list hadChildren hasChildren|
 
+    self forgetAboutChildren.
+
     model := self model.
-
     model isNil ifTrue:[
         "/ must reread later
-        fetchOperation := modificationTime := children := nil.
-      ^ nil
+        modificationTime := children := nil.
+        ^ nil
     ].
 
     hadChildren := children size ~~ 0.
 
     "/ set to suppress reading of children
     children := #().
-    fetchOperation   := nil.
     modificationTime := self fileName modificationTime.
     model stopIndicatorValidationFor:self.
 
@@ -926,12 +937,10 @@
 basicFetchIndicator
     |hasChildren|
 
-    hasChildren := DirectoryContents directoryNamed:self fileName detect:(self model matchBlock).
-    hasChildren ifTrue:[
-        fetchOperation := #hasChildren
-    ] ifFalse:[
-        fetchOperation := #hasNoChildren
-    ].
+    hasChildren := DirectoryContents directoryNamed:(self fileName) detect:(self model matchBlock).
+    self knownToHaveChildren:hasChildren.
+    children notNil ifTrue:[self halt].
+
     children isNil ifTrue:[
         "setup modification time to suppress monitorCycle
         "
@@ -940,29 +949,31 @@
 !
 
 fetchIndicator
-    "fetch the indicator value which indicates whether children exists or not
-     called by the list
+    "fetch the indicator value which indicates whether children exist or not.
+     Called by the lists update process.
     "
     children notNil ifTrue:[
         "/ children already read
-        fetchOperation := nil.
-      ^ self
+        self forgetAboutChildren.
+        ^ self
     ].
 
-    fetchOperation ~~ #fetching ifTrue:[
-        "/ children will be updated ....
+    self isFetchingChildrenInfo ifFalse:[
+        "/ children will be updated in a second....
         ^ self
     ].
     "/ suppress restart of fetchIndicator
 
     self basicFetchIndicator.
 
+    children notNil ifTrue:[self halt].
+
     children notNil ifTrue:[
-        fetchOperation := nil.
+        self forgetAboutChildren.
         children notEmpty ifTrue:[ self changed:#redraw ].
     ] ifFalse:[
         "/ is a remote or very slow file system
-        fetchOperation == #hasChildren ifTrue:[
+        self isKnownToHaveChildren ifTrue:[
             self changed:#redraw
         ].
     ].
@@ -971,35 +982,95 @@
 resetFetchIndicator
     "update indication cycle has deregistered the item
     "
-    fetchOperation := nil.
+
+    self forgetAboutChildren.
+! !
+
+!HierarchicalFileList::Directory methodsFor:'private'!
+
+flushChildren
+    "flush the children because the node is going to be invisible.
+    "
+    children notNil ifTrue:[
+        self knownToHaveChildren:(children size ~~ 0).
+        children := nil.
+    ].
+! !
+
+!HierarchicalFileList::Directory methodsFor:'private - quick children info'!
+
+forgetAboutChildren
+    quickChildrenInfo := StateUnknown
+!
+
+isChildrenInfoValid
+    ^ quickChildrenInfo ~~ StateUnknown and:[quickChildrenInfo ~~ StateFetching]
+!
+
+isFetchingChildrenInfo
+    ^ quickChildrenInfo == StateFetching
+!
+
+isKnownToHaveChildren
+    ^ quickChildrenInfo == StateHasChildren
+!
+
+isKnownToHaveNoChildren
+    ^ quickChildrenInfo == StateHasNoChildren
+!
+
+knownToHaveChildren:aBoolean
+    aBoolean ifTrue:[
+        quickChildrenInfo := StateHasChildren.
+    ] ifFalse:[
+        quickChildrenInfo := StateHasNoChildren.
+    ].
+!
+
+setFetchingChildrenInfo
+    quickChildrenInfo := StateFetching
 ! !
 
 !HierarchicalFileList::Directory methodsFor:'queries'!
 
+canExpand
+    super canExpand ifTrue:[^ true].
+    "/ in case we are fetching the subdirectory
+    self isFetchingChildrenInfo ifTrue:[
+self halt.  
+    ].
+    
+    ^ false
+!
+
 hasChildren
-    "returns true if children exists
+    "returns true if children exist
     "
     |model|
 
     children notNil ifTrue:[
-        fetchOperation := nil.
-      ^ children size ~~ 0
+        self forgetAboutChildren.
+        ^ children size ~~ 0
     ].
 
-    fetchOperation notNil ifTrue:[
-        ^ fetchOperation == #hasChildren
+    self isFetchingChildrenInfo ifTrue:[
+        ^ false.
+    ].
+    self isChildrenInfoValid ifTrue:[
+        ^ self isKnownToHaveChildren
     ].
 
     model := self model.
 
     model notNil ifTrue:[
-        fetchOperation := #fetching.
+        self setFetchingChildrenInfo.
         model startIndicatorValidationFor:self.
     ] ifFalse:[
         self error:'should not happen' mayProceed:true.
-        fetchOperation := nil
+        self forgetAboutChildren
     ].
-    ^ children size ~~ 0
+    children size ~~ 0 ifTrue:[self halt. ^ true].
+    ^ false
 !
 
 isDirectory
@@ -1015,7 +1086,8 @@
 invalidateRepairNow:doRepair
     "invalidate contents
     "
-    fetchOperation := modificationTime := nil.
+    modificationTime := nil.
+    self forgetAboutChildren
 
     isExpanded ifFalse:[
         children := nil
@@ -1037,7 +1109,8 @@
     modificationTime := nil.
 
     isExpanded ifFalse:[
-        fetchOperation := children := nil.
+        children := nil.
+        self forgetAboutChildren
     ] ifTrue:[
         self monitoringCycle.
 
@@ -1064,20 +1137,22 @@
             ^ self
         ].
     ].
+
     DirectoryContents flushCachedDirectoryFor:(self fileName).
     isExpanded ifFalse:[
         timeChanged ifTrue:[
-            fetchOperation := children := nil.
+            children := nil.
+            self forgetAboutChildren.
             self changed:#redraw.
         ].
         ^ self
     ].
-    model := self model.
+
     children isNil ifTrue:[ children := #() ].         "/ disable update during merge
 
-
-    fetchOperation := nil.
-    mergedList     := model childrenFor:self.
+    self forgetAboutChildren.
+    model := self model.
+    mergedList := model childrenFor:self.
 
     mergedList size == 0 ifTrue:[
         self removeAll.
@@ -1085,7 +1160,6 @@
     ].
 
     size := children size.
-
     size == 0 ifTrue:[
         self addAll:mergedList.
         ^ self
@@ -1139,11 +1213,15 @@
     "returns true if children exists
     "
     children notNil ifTrue:[
-        fetchOperation := nil.
+        self forgetAboutChildren.
         ^ children size ~~ 0
     ].
-    fetchOperation := #hasChildren.
-  ^ true
+
+    "/ assume that there are children;
+    "/ this might be wrong and clicking on the expand-icon
+    "/ will then not perform an expand, but remove the can-expand indicator.
+    self knownToHaveChildren:true.
+    ^ true
 !
 
 isRemoteDirectory
@@ -1153,5 +1231,7 @@
 !HierarchicalFileList class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libwidg2/HierarchicalFileList.st,v 1.43 2003-03-03 10:21:56 penk Exp $'
+    ^ '$Header: /cvs/stx/stx/libwidg2/HierarchicalFileList.st,v 1.44 2003-04-08 13:38:08 cg Exp $'
 ! !
+
+HierarchicalFileList::Directory initialize!