--- a/SelectionInTree.st Sun Feb 05 01:36:42 2017 +0100
+++ b/SelectionInTree.st Sun Feb 05 03:37:03 2017 +0100
@@ -41,17 +41,18 @@
documentation
"
- list and selection holder for hierarchical list structures. Used
- to buildup file-trees, class trees etc.
+ list and selection holder for hierarchical list structures.
+ Used to buildup file-trees, class trees etc.
Especially suited for use with SelectionInTreeView.
- Notice: this class replaces SelectionInHierarchy, which provides
- similar (but less sphisticated) functionality.
+ Notice: this class replaces SelectionInHierarchy,
+ which provides similar (but less sophisticated) functionality.
[See also:]
TreeItem
SelectionInTreeView
+ SelectionInHierarchy
[Author:]
W. Olberding
@@ -68,31 +69,34 @@
!SelectionInTree class methodsFor:'defaults'!
defaultItemClass
- "returns the default item class or nil (the default)
- "
+ "returns the default item class or nil (the default)"
+
^ nil
-
-
+ "Modified (comment): / 04-02-2017 / 19:48:09 / cg"
! !
!SelectionInTree methodsFor:'accessing'!
list
- "get the list of currently shown objects
- "
+ "get the list of currently shown objects"
+
^ list
+
+ "Modified (comment): / 04-02-2017 / 19:38:18 / cg"
!
root
- "get the root node
- "
+ "get the root node"
+
^ root
+
+ "Modified (comment): / 04-02-2017 / 19:40:07 / cg"
!
root:aRoot
- "set a new root
- "
+ "set a new root"
+
|tree|
root notNil ifTrue: [
@@ -108,6 +112,8 @@
root parent:nil.
].
self recomputeList
+
+ "Modified (comment): / 04-02-2017 / 19:40:12 / cg"
!
value
@@ -117,8 +123,8 @@
!SelectionInTree methodsFor:'accessing hierarchy new'!
doMakeVisible:something
- "make an item or list of items to become visible
- "
+ "make an item or list of items to become visible"
+
|anchor parent|
self each:something do:[:anItem|
@@ -137,72 +143,106 @@
]
].
]
+
+ "Modified (comment): / 04-02-2017 / 19:37:02 / cg"
! !
!SelectionInTree methodsFor:'accessing-behavior'!
childrenAction
- "get children action block
- "
+ "get the children action block.
+ This is called by tree items to retrieve the children of a node"
+
^childrenAction
+
+ "Modified (comment): / 04-02-2017 / 19:31:38 / cg"
!
childrenAction:aBlock
- "set children action block
- "
+ "set the children action block
+ This is called by tree items to retrieve the children of a node"
+
childrenAction := aBlock.
+
+ "Modified (comment): / 04-02-2017 / 19:31:51 / cg"
!
contentsAction
"get contents action block
- "
+ This is called by tree items to retrieve the contents of a node"
+
^contentsAction
+
+ "Modified (comment): / 04-02-2017 / 19:32:04 / cg"
!
contentsAction:aBlock
"set contents action block
- "
+ This is called by tree items to retrieve the contents of a node"
+
contentsAction := aBlock.
+
+ "Modified (comment): / 04-02-2017 / 19:32:09 / cg"
!
iconAction
"get icon action block
- "
+ This is called by tree items to retrieve the icon of a node"
+
^iconAction
+
+ "Modified (comment): / 04-02-2017 / 19:32:22 / cg"
!
iconAction:aBlock
"set icon action block
- "
+ This is called by tree items to retrieve the icon of a node"
+
iconAction := aBlock.
+
+ "Modified (comment): / 04-02-2017 / 19:32:17 / cg"
!
labelAction
"get label action block
- "
+ This is called by tree items to retrieve the label of a node"
+
^labelAction
+
+ "Modified (comment): / 04-02-2017 / 19:32:27 / cg"
!
labelAction:aBlock
"set label action block
- "
+ This is called by tree items to retrieve the label of a node"
+
labelAction := aBlock.
+
+ "Modified (comment): / 04-02-2017 / 19:32:35 / cg"
!
showRoot
- "list with or without root
- "
+ "controls if the list is shown with or without root.
+ Notice that technically, there is always one single root item;
+ however, its visibility can be suppressed to make the tree look like a list
+ on the top level"
+
^ showRoot
+
+ "Modified (comment): / 04-02-2017 / 19:33:45 / cg"
!
-showRoot:aState
- "list with or without root
- "
- aState ~~ showRoot ifTrue:[
- showRoot := aState.
+showRoot:aBoolean
+ "controls if the list is shown with or without root.
+ Notice that technically, there is always one single root item;
+ however, its visibility can be suppressed to make the tree look like a list
+ on the top level"
+
+ aBoolean ~~ showRoot ifTrue:[
+ showRoot := aBoolean.
root notNil ifTrue:[
- aState ifTrue:[
+ aBoolean ifTrue:[
list addFirst:root.
self changed:#insertCollection: with:(Array with:1 with:1 with:nil).
] ifFalse:[
@@ -211,13 +251,15 @@
].
].
].
+
+ "Modified (format): / 04-02-2017 / 21:34:26 / cg"
! !
!SelectionInTree methodsFor:'accessing-hierarchy'!
collapse:something
- "collapse a node or collection of nodes
- "
+ "collapse a node or collection of nodes"
+
|listChanged|
listChanged := false.
@@ -233,17 +275,20 @@
self changed:#list.
]
+ "Modified (comment): / 04-02-2017 / 19:34:09 / cg"
!
expand
- "expand the root
- "
+ "expand the root"
+
self expand:root
+
+ "Modified (comment): / 04-02-2017 / 19:34:13 / cg"
!
expand:something
- "expand a node or collection of nodes
- "
+ "expand a node or collection of nodes"
+
|listChanged|
listChanged := false.
@@ -258,59 +303,69 @@
self listFromRoot.
self changed:#list.
]
+
+ "Modified (comment): / 04-02-2017 / 19:34:17 / cg"
! !
!SelectionInTree methodsFor:'accessing-hierarchy new'!
doCollapse:something
"collapse all children under an item or a sequence of items;
- if the list changed, notifications are raised
- "
+ if the list changed, a change notifications are sent"
+
self each:something do:[:anItem|
self collapseItem:anItem do:[ anItem collapse ]
]
+
+ "Modified (comment): / 04-02-2017 / 19:36:30 / cg"
!
doCollapseAll:something
"collapse all children and subChildren under an item or sequence of items;
- if the list changed, notifications are raised
- "
+ if the list changed, a change notifications are sent"
+
self each:something do:[:anItem|
self collapseItem:anItem do:[ anItem collapseAll ]
]
+
+ "Modified (comment): / 04-02-2017 / 19:36:39 / cg"
!
doExpand:something
"expand all children under an item or collection of items;
- if the list changed, notifications are raised
- "
+ if the list changed, a change notifications are sent"
+
self each:something do:[:anItem|
self expandItem:anItem do:[anItem expand]
]
+
+ "Modified (comment): / 04-02-2017 / 19:36:44 / cg"
!
doExpandAll:something
"expand all children and subChildren under an item or sequence of items;
- if the list changed, notifications are raised
- "
+ if the list changed, change notifications are sent"
+
self each:something do:[:anItem|
self expandItem:anItem do:[anItem expandAll]
]
+
+ "Modified (comment): / 04-02-2017 / 19:36:55 / cg"
! !
!SelectionInTree methodsFor:'adding & removing'!
add:something after:aChild
- "add a node or collection of nodes to parent after a child
- "
- "add a node or collection of nodes to after a child
- "
+ "add a node or collection of nodes to the parent of aChild
+ after that child in the sublist"
+
|p|
(aChild notNil and:[(p := aChild parent) notNil]) ifTrue:[
self add:something afterIndex:(p indexOfChild:aChild) below:p
]
+ "Modified (comment): / 04-02-2017 / 19:35:11 / cg"
!
add:something afterIndex:anIndex below:aParent
@@ -320,19 +375,21 @@
!
add:something before:aChild
- "add a node or collection of nodes to before a child
- "
+ "add a node or collection of nodes to before a child"
+
|p|
(aChild notNil and:[(p := aChild parent) notNil]) ifTrue:[
self add:something beforeIndex:(p indexOfChild:aChild) below:p
]
+
+ "Modified (comment): / 04-02-2017 / 19:35:19 / cg"
!
add:something beforeIndex:anIndex below:aParent
"add a node or collection of nodes to aParents children
- before anIndex (which is a child-index)
- "
+ before anIndex (which is a child-index)"
+
|children start index size pList|
( aParent isNil
@@ -394,19 +451,23 @@
self changed:#insertCollection:
with:(Array with:start with:pList size with:aParent).
+ "Modified (comment): / 04-02-2017 / 19:35:23 / cg"
!
add:something below:aParent
- "add a node or collection of nodes to parent
- "
+ "add a node or collection of nodes to parent"
+
aParent notNil ifTrue:[
self add:something beforeIndex:(aParent numberOfChildren + 1) below:aParent
]
+
+ "Modified (comment): / 04-02-2017 / 19:35:28 / cg"
!
remove:something
- "remove a node or collection of nodes
- "
+ "remove a node or collection of nodes.
+ Change notifications are sent"
+
|node index loNums loItem start size parent stop|
something isNil ifTrue:[
@@ -459,11 +520,14 @@
]
].
^ something
+
+ "Modified (comment): / 04-02-2017 / 19:39:07 / cg"
!
removeAllOtherThanRoot
- "remove all other than the root
- "
+ "remove all children from the root
+ Change notifications are sent"
+
|listChanged|
root notNil ifTrue:[
@@ -475,29 +539,37 @@
self changed:#list
]
]
+
+ "Modified (comment): / 04-02-2017 / 19:39:31 / cg"
!
removeIndex:something
- "remove a node at index or collection of indexed nodes
- "
+ "remove a node at index or collection of indexed nodes.
+ Change notifications are sent"
+
self remove:something
+
+ "Modified (comment): / 04-02-2017 / 19:39:42 / cg"
!
removeSelection
- "remove selected nodes
- "
+ "remove selected nodes.
+ Change notifications are sent"
+
|sel|
sel := self selectionIndex.
self selectionIndex:nil.
self remove:sel.
+
+ "Modified (comment): / 04-02-2017 / 19:39:51 / cg"
!
replaceNode:aNode with:aNewNode
"replace a node by a new node; if the new node is nil, the node and its
- children are removed. Otherwise the children are taken over to the new
- node.
- "
+ children are removed.
+ Otherwise the children are taken over to the new node."
+
|parent index children|
(aNode isNil or:[aNode == aNewNode]) ifTrue:[
@@ -532,19 +604,21 @@
list at:index put:aNewNode.
self changed:#at: with:index
].
+
+ "Modified (comment): / 04-02-2017 / 19:40:02 / cg"
! !
!SelectionInTree methodsFor:'change & update'!
invalidate
- "called; something changed what requires a redraw but no recomputation.
- for example a name
- "
+ "called whenever something changed that requires a redraw but no recomputation.
+ For example a name or icon"
+
self dependents do:[:aDependent|
aDependent isView ifTrue:[ aDependent invalidate ]
].
-
+ "Modified (comment): / 04-02-2017 / 19:38:06 / cg"
!
update:something with:aParameter from:aModel
@@ -558,13 +632,14 @@
each:something do:aBlock
"evaluate a block for something or in case of a collection for each
- element in the collection
- "
+ element in the collection"
+
something notNil ifTrue:[
something isCollection ifTrue:[something do:[:el|aBlock value:el]]
ifFalse:[aBlock value:something]
]
+ "Modified (comment): / 04-02-2017 / 19:37:07 / cg"
! !
!SelectionInTree methodsFor:'initialization'!
@@ -589,9 +664,9 @@
!SelectionInTree methodsFor:'private-hierarchy'!
collapseItem:anItem do:collapseBlock
- "collapse all children under an item; raise a notification if
- the list changed
- "
+ "collapse all children under an item;
+ send a change notification if the list changed"
+
|start stop size|
anItem isCollapsable ifFalse:[
@@ -619,12 +694,14 @@
self changed:#removeFrom: with:(Array with:start with:stop with:anItem).
]
]
+
+ "Modified (comment): / 04-02-2017 / 19:35:52 / cg"
!
expandItem:anItem do:expandBlock
- "expand all children under an item; raise a notification if
- the list changed
- "
+ "expand all children under an item;
+ send out change a notification if the list changed"
+
|start size pList|
anItem isExpandable ifFalse:[
@@ -645,12 +722,14 @@
self changed:#at: with:start
]
]
+
+ "Modified (comment): / 04-02-2017 / 19:37:29 / cg"
!
listFromRoot
"Traverse the tree and build a new list;
- no change notification is raised
- "
+ no change notification are sent"
+
list clearContents.
root notNil ifTrue:[
@@ -658,15 +737,18 @@
root addVisibleChildrenTo:list
]
+ "Modified (comment): / 04-02-2017 / 19:38:29 / cg"
! !
!SelectionInTree methodsFor:'queries'!
indexOf:anItem
- "returns the index of an item or 0
- "
+ "returns the index of an item or 0"
+
^ anItem notNil ifTrue:[list identityIndexOf:anItem]
ifFalse:[0]
+
+ "Modified (comment): / 04-02-2017 / 19:37:38 / cg"
! !
!SelectionInTree methodsFor:'searching'!
@@ -675,27 +757,27 @@
"detect an item the evaluation of the block returns true.
The argument to the block is the item.
This recursively enumerates the tree for the first item for which
- the block returns true.
- "
+ the block returns true."
+
root notNil ifTrue:[
^ root detectFirstChild:aOneArgBlock
].
^ nil
-
+ "Modified (comment): / 04-02-2017 / 19:36:01 / cg"
!
detectItem:aOneArgBlock
"detect an item the evaluation of the block returns true.
The argument to the block is the item.
- This searches top-level items only.
- "
+ This searches top-level items only."
+
root notNil ifTrue:[
^ root detectChild:aOneArgBlock
].
^ nil
-
+ "Modified (comment): / 04-02-2017 / 19:36:06 / cg"
!
detectItem:aTwoArgBlock arguments:aListOfArgs
@@ -704,28 +786,33 @@
the value derived from the argument list at level.
This recursively walks down the tree up to aListOfArgs size levels;
i.e. if you pass (1 to:10) as aListOfArgs, the block will get the sub-level
- as second argument and stop the search after 10 levels.
- "
+ as second argument and stop the search after 10 levels."
root notNil ifTrue:[
^ root detectChild:aTwoArgBlock arguments:aListOfArgs
].
^ nil
-
+ "Modified (comment): / 04-02-2017 / 19:36:15 / cg"
! !
!SelectionInTree methodsFor:'selection'!
selectNode:aNode
+ "select a given node (by identity - not by index)"
+
|index|
(index := self indexOf:aNode) ~~ 0 ifTrue:[
self selectionIndex:index
]
+
+ "Modified (comment): / 04-02-2017 / 19:40:42 / cg"
!
selectNodes:aCollectionOfNodes
+ "select a given set of nodes (by identity - not by index)"
+
| indices|
indices := aCollectionOfNodes
@@ -734,24 +821,25 @@
indices sort.
self selectionIndex:indices
- "Created: / 6.3.1999 / 22:37:59 / cg"
+ "Created: / 06-03-1999 / 22:37:59 / cg"
+ "Modified (comment): / 04-02-2017 / 19:40:55 / cg"
!
selectedNode
- "returns selected node or nil
- "
+ "returns the selected node or nil"
+
|nodes|
(nodes := self selectedNodes) notNil ifTrue: [
^nodes first
].
^nil
-
+ "Modified (comment): / 04-02-2017 / 19:41:04 / cg"
!
selectedNodes
- "returns list of selected nodes or nil
- "
+ "returns a collection of selected nodes or nil"
+
|node coll|
selection isNil ifTrue:[
@@ -760,7 +848,7 @@
selection isCollection ifFalse:[
node := list at:selection ifAbsent:nil.
- ^ node notNil ifTrue:[Array with:node] ifFalse:[nil]
+ ^ node notNil ifTrue:[Array with:node] ifFalse:[nil]
].
selection isEmpty ifTrue:[
@@ -775,11 +863,13 @@
]
].
^ coll asNilIfEmpty
+
+ "Modified (format): / 04-02-2017 / 19:41:19 / cg"
!
selectedNodesDo:aOneArgBlock
- "evaluate the block on eack node selected
- "
+ "evaluate the block on each node selected"
+
|node|
selection isNil ifTrue:[
@@ -801,29 +891,37 @@
aOneArgBlock value:node
].
].
+
+ "Modified (comment): / 04-02-2017 / 19:41:54 / cg"
!
selection
- "get the selection or nil
- "
+ "get the selection index or nil"
+
^ self selectionIndex
+
+ "Modified (comment): / 04-02-2017 / 19:42:40 / cg"
!
selection:indexesOrNil
- "set the selection"
+ "set the selection index"
self selectionIndex:indexesOrNil
+
+ "Modified (comment): / 04-02-2017 / 19:42:45 / cg"
!
selectionIndex
- "get the selection or nil
- "
+ "get the selection index or nil"
+
^ selection
+
+ "Modified (comment): / 04-02-2017 / 19:42:59 / cg"
!
selectionIndex:indexesOrNil
- "set the selection
- "
+ "set the selection index (or nil to deselect)"
+
|oldSel|
oldSel := selection.
@@ -836,17 +934,21 @@
aNode changedSelected
]
]
+
+ "Modified (comment): / 04-02-2017 / 19:43:12 / cg"
!
setSelection:indexesOrNil
- "set the selection without raising a notification
- "
+ "set the selection index without sending out change notifications"
+
self setSelectionIndex:indexesOrNil
+
+ "Modified (comment): / 04-02-2017 / 19:43:41 / cg"
!
setSelectionIndex:indexesOrNil
- "set the selection without raising a notification
- "
+ "set the selection index without sending out change notifications"
+
|indexes|
indexes := indexesOrNil.
@@ -858,13 +960,18 @@
].
selection := indexes
+ "Modified (comment): / 04-02-2017 / 19:43:37 / cg"
! !
!SelectionInTree methodsFor:'update indication task'!
startIndicatorValidationFor:aNode
- "add a node to list of updating indications
- "
+ "add a node to the list of nodes which are automatically
+ monitored for changes in their children list (by a background task),
+ and which will then update their 'has-children' arrow indicator icon.
+ This is typically used to check for changed folders in file trees,
+ data in databases etc."
+
|index|
accessLock critical:[
@@ -879,19 +986,21 @@
indicatorTask isNil ifTrue:[
prio := Processor activePriority.
- indicatorTask := [
- [ self taskCycle ] whileTrue:[ Processor yield ]
- ] forkAt:(prio - 1).
+ indicatorTask :=
+ [
+ [ self taskCycle ] whileTrue:[ Processor yield ]
+ ] forkAt:(prio - 1).
indicatorTask priorityRange:(prio-1 to:prio).
]
].
- "Modified: / 26.9.1998 / 15:20:44 / cg"
+ "Modified: / 26-09-1998 / 15:20:44 / cg"
+ "Modified (comment): / 04-02-2017 / 19:47:28 / cg"
!
stopIndicatorValidationFor:aNodeOrList
- "remove a node or list of nodes from list of updating indications
- "
+ "remove a node or list of nodes from the list of automatically monitored nodes."
+
accessLock critical:[
aNodeOrList isCollection ifTrue:[
aNodeOrList do:[:aNode|
@@ -902,21 +1011,22 @@
]
]
-
+ "Modified (comment): / 04-02-2017 / 19:46:18 / cg"
!
stopRunningTasks
- "stop task
- "
+ "stop the running update task"
+
accessLock critical:[ indicatorList removeAll ]
+ "Modified (comment): / 04-02-2017 / 19:46:33 / cg"
!
taskCycle
"run one cycle fetching indicator state.
This is done in the background to avoid long startup
delays, in case the indicator information takes long to
- gather (i.e. when reading directories)"
+ gather (i.e. when reading network directories)"
|node flag|
@@ -936,7 +1046,8 @@
node showIndicator:flag.
^ true
- "Modified: / 26.9.1998 / 15:11:16 / cg"
+ "Modified: / 26-09-1998 / 15:11:16 / cg"
+ "Modified (comment): / 04-02-2017 / 19:47:51 / cg"
! !
!SelectionInTree class methodsFor:'documentation'!