EwIconTree migration may cause walkback
Under certain circumstances, users who migrate from VisualAge Smalltalk V3.0 to VA Smalltalk may experience walkbacks associated with changes in EwIconTree. The walkbacks will look like the following:
Exception: (ExCLDTIndexOutOfRange) Index out of range.
There were many bug fixes as well as major changes made in VisualAge Smalltalk V4.0 for EwIconTree. Making these fixes caused some code that previously worked to fail with a walkback. The code should have failed all along, but due to bugs in VisualAge Smalltalk V3.0, the code actually worked fine.
The problem occurs if an application deletes items from the tree using a script such as the one that follows below:
In the following example, self is an instance of an AbtAppBldrView, selectedItemFromTree is the domain object, and myContainerIconTree is an instance an AbtContainerIconTreeView.
delete
 
self selectedItemFromTree notNil
ifTrue: ["remove the object from the OrderedCollection that contains it"
self selectedItemFromTree delete.
"set the instance variable to nil"
self selectedItemFromTree: nil.
self myContainerIconTree deselectAllItems;
refreshAllItems].
 
I found these methods to be interesting on EwIconTree.
 
deleteItem: item
"Delete an item from the list. This message is not supported in
tree lists. Rather, the application must delete the item from the
logical list itself, then call #deletedAt:count:."
 
^self error: (NlsCatEWe indexedMsg: 1) "$NLS$ Not valid for tree widgets"
 
 
deletedAt: position count: count
"Item(s) were deleted from the collection of root items at the
specified position. The position is specified as an index in the
collection of root items only. Refresh the list.
 
Usage:
This API can be used after the widget is created.
 
position
The index of the first item that was deleted.
 
count
The number of items deleted."
 
"Fully refresh the tree by resetting the items collection."
self items: self items.

The following comment from above does seem appropriate here:
Rather, the application must delete the item from the logical list itself, then call #deletedAt:count:."
So, if the items in the tree are refreshed by resetting the items collection, then the code will work.
The delete method should be changed to look like the following:
delete
 
self selectedItemFromTree notNil
ifTrue: ["remove the object from the OrderedCollection that contains it"
self selectedItemFromTree delete.
"set the instance variable to nil"
self selectedItemFromTree: nil.
self myContainerIconTree widget items:
(self myContainerIconTree widget items).
"self myContainerIconTree deselectAllItems;
refreshAllItems"].
By making this change, you should be able to turn #refreshEntireListOnChange to false (the default) and it should work. Also notice that I commented out #deselectAllItems and #refreshAllItems; they are not needed. However, the code also works if those lines of code are left in.
In summary, due to bugs in V3.0 Ew containers, it is possible some application code will work in V3.0 when in fact it should have failed because it doesn't use the #deleteAt:count: method technique for deleting items. Furthermore, the changes in V4 that fixed these bugs will break this code. Thus, as a result of fixing problems with the EwIconTree, this problem is now apparent.
Solution
"Fully refresh the tree by resetting the items collection."
self items: self items.
 
 
Last modified date: 07/02/2019