Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 24521

Summary: [Viewers] TreeViewer.update() does not work correctly with filter
Product: [Eclipse Project] Platform Reporter: Pavel Nejedly <nejedly>
Component: UIAssignee: Boris Bokowski <bokowski>
Status: VERIFIED FIXED QA Contact:
Severity: normal    
Priority: P4 CC: heath.borders, jacek.pospychala, matthew.phillips, ob1.eclipse, ovidr, rsqrd, Tod_Creasey, tom.schindl
Version: 2.0   
Target Milestone: 3.5 M5   
Hardware: All   
OS: All   
Whiteboard:
Bug Depends on:    
Bug Blocks: 259882    
Attachments:
Description Flags
test case none

Description Pavel Nejedly CLA 2002-10-08 12:13:36 EDT
When I add an element which does not satisfy the filtering condition and then 
update it so that it does, call to update does not show the element.
This is because[StructuredViewer.update]:

public void update(Object element, String[] properties) {
	Assert.isNotNull(element);
|	Widget item = findItem(element);
|	if (item == null)
|		return;

the code silently ignores that the element may become visible...

btw. later in code of this method:
	if (needsRefilter) {
		refresh();
		return;
	}

This is quite inefficient, as it needs to query all visible items; however only 
one element may actually change (change visibility and/or sort order).
Comment 1 Tod Creasey CLA 2002-10-09 11:12:36 EDT
Can you please give a more concrete example of how you do this? Here are the 
steps I followed:

1) Open the Resource Perspective
2) Selected the .* filter.
3) Created a file called *.fred
4) It is not shown
5) Opened another window
6) Renamed .fred to red.fred
7) It showed up

The update should have occured as a result of the rename. Please give more 
details of what you are doing.
Comment 2 Pavel Nejedly CLA 2002-10-10 02:50:35 EDT
I' ve created a simple filter

	public static class NonWSTextFilter extends ViewerFilter {
		public boolean isFilterProperty(Object element, String 
property) {
			return true;
		}
		public boolean select(
			Viewer viewer,
			Object parentElement,
			Object element) {
			
                        if(isWhiteSpaceString(((IText)element).getText()))
                              return false;
			return true;
		}


and simply call
IText t = new Text(parent,' ');
tv.add(t,parent);
//text is not shown

later on, I call
t.setText('aaaa');
tv.update(t);
// text isn't shown either!

but if I start with t = new Text(parent,'bbb');,
update works fine... (my labelProvider shows the text, so I see that it has 
changed)

btw. I'm afraid that file rename is dispatched as REMOVE and ADD, therefore 
remove() and add() will be used - and this obviously works...

Just see the semantics of findItem - it returns null if the element is not 
visible, therefore if I try to call update(), the element will remain 
invisible, although it should show up
Comment 3 Nick Edgar CLA 2003-02-10 08:18:49 EST
There are no plans for the UI team to work on this defect until higher priority 
items are addressed. 
If you would like to work on this defect, please let us know on the platform-ui-
dev mailing list.

As a workaround, the content provider can call add instead of update in this 
case.
Comment 4 Tod Creasey CLA 2006-06-22 10:52:41 EDT
Is this still an issue in 3.2?
Comment 5 Matthew Phillips CLA 2006-08-02 04:45:01 EDT
(In reply to comment #4)
> Is this still an issue in 3.2?
> 

Yes, I just ran into it using 3.2 final. This is not my first encounter: I first banged my head on it with JFace 2.1.1.

Although the doc for StructuredViewer.update () states "If the viewer has a filter which is affected by a change to one of the properties, the element may appear or disappear if the change affects whether or not the element is filtered out.", the code is simply:

  Widget[] items = findItems(element);

  for (int i = 0; i < items.length; i++) {
    internalUpdate(items[i], element, properties);
  }		

Which will do nothing for items that are filtered out.

It would be nice if, until this is fixed, at least the doc could be changed so as not to blatently mislead :/
Comment 6 Jacek Pospychala CLA 2009-01-05 06:19:53 EST
this is still the case in Eclipse 3.5 and is hurting PDE Plug-in registry view.
The only difference is that we're calling TreeViewer.refresh(element), not update(element).

I can attach sample to reproduce.
Comment 7 Boris Bokowski CLA 2009-01-05 12:37:35 EST
(In reply to comment #6)
> I can attach sample to reproduce.

A snippet would be great.
Comment 8 Jacek Pospychala CLA 2009-01-06 04:07:11 EST
Created attachment 121596 [details]
test case

Test case
Comment 9 Boris Bokowski CLA 2009-01-06 12:38:24 EST
I believe it would be too risky to change the behaviour of this after so many years, which is why I prefer a JavaDoc clarification. I am adding the following to StructuredViewer.update:

"Note that filtering does not happen if <code>properties</code> is <code>null</code>."

This updates the section on filtering to be like the section on sorting, which already includes a similar disclaimer.

Jacek, when you call refresh(Object), only structural changes to children of the given object, not the object itself will be performed. You should call refresh(getParent(element)) instead. Do you want me to clarify the JavaDoc for refresh(Object), and if yes, in which way?
Comment 10 Jacek Pospychala CLA 2009-01-08 08:59:31 EST
(In reply to comment #9)
> Jacek, when you call refresh(Object), only structural changes to children of
> the given object, not the object itself will be performed. You should call
> refresh(getParent(element)) instead. Do you want me to clarify the JavaDoc for
> refresh(Object), and if yes, in which way?

I don't really like it. Assuming I have 2000 children and only one of them has to be removed (filtered) but all other have to be refreshed, it sounds very ineffective.

Comment 11 Boris Bokowski CLA 2009-01-08 10:04:01 EST
(In reply to comment #10)
> I don't really like it. Assuming I have 2000 children and only one of them has
> to be removed (filtered) but all other have to be refreshed, it sounds very
> ineffective.

Can you explain how this affects you in the Plug-in Registry view (concretely)?
Comment 12 Jacek Pospychala CLA 2009-01-08 10:15:39 EST
not yet, I haven't tried refresh(getParent(element)) yet. But earlier I had some flickering when doing refresh() too often, that's why I'm worried.
Comment 13 Boris Bokowski CLA 2009-01-08 12:23:13 EST
(In reply to comment #12)
> not yet, I haven't tried refresh(getParent(element)) yet. But earlier I had
> some flickering when doing refresh() too often, that's why I'm worried.

Cases like this can usually be improved a lot by wrapping the calls in:

treeViewer.getTree().setRedraw(false);
try {
  // ... do work
} finally {
  treeViewer.getTree().setRedraw(true);
}
Comment 14 Oleg Besedin CLA 2009-01-30 16:50:53 EST
Verified in I20090129-0100 that both Help contents and source Javadoc include text from the comment 9.

(The actual text is: "Note that filtering may not happen if properties is null.")