How best to use ViewerFilter on a TreeViewer?
Asked Answered
F

4

10

I am applying a ViewerFilter to a tree of a few branches, but mostly leaves. The filter really applies to the leaves, using properties within the leaf. All branches are left untouched so that their leaves can appear.

However I would like to filter out branches that contain no selected leaves, and I can see no mechanism within ViewerFilter that allows this.

Is this possible at all?

For example, given the notional tree below (where b is a branch, a L is a leaf)

b0
  b1
    L2
    L4
    L8
  b2
    L1
    L3
    L5

I would like to apply a ViewerFilter that only selects even leaves and branches that contain even leaves. The resulting tree would be ..

b0
  b1
    L2
    L4
    L8

.. where branch b2 does not display as it contains no selected children, but branches b0 and b1 do.

Foreyard answered 23/6, 2009 at 22:20 Comment(0)
O
14
class MyFilter extends ViewerFilter{

  private boolean isLeaf(Object element){
    // implement this
  }

  private boolean isEvenLeaf(Object leaf){
    // implement this
  }

  @Override
  public boolean select(Viewer viewer, Object parentElement, Object element){
    if (isLeaf(element))
      return isEventLeaf(element);
    else {
      StructuredViewer sviewer = (StructuredViewer) viewer;
      ITreeContentProvider provider = (ITreeContentProvider) sviewer.getContentProvider();
      for (Object child: provider.getChildren(element)){
        if (select(viewer, element, child))
          return true;
      }
      return false;
    }
  }
}
Occultism answered 16/7, 2009 at 22:5 Comment(2)
I suspect that the running time of this pretty bad for large collections of elements. For example, all the resources is a workspace. I think this would, for each resource, visit all its contained resources. It is hence O(n^2). There should be an O(n) solution.Teak
This solution works really badly when the viewer has other filters. For example in the case of workspace resources, when another filter has filtered away all resources from a folder, this filter will still report the folder as non-empty, since this filter is not aware of the other filter.Teak
F
2

Yes, if you don't filter out the branch nodes, they'll be shown even if there are no leaves in it. If you want the filter to be permanently on, something you can consider is using the ITreeContentProvider as a filter.

Since the content provider has both getChildren() and hasChildren() methods, you have a little more control.

Flaccid answered 21/9, 2009 at 22:59 Comment(0)
C
2

Also have a look at org.eclipse.ui.dialogs.FilteredTree which the right thing in regard to child leaves.

Cheerful answered 1/12, 2011 at 15:4 Comment(0)
J
0

I'm not sure what you mean by selected leaves. If you mean selected in the view, you can find this out by calling Viewer.getSelection(). The select method that you implement in your filter passes in the viewer, parent, and leaf. You should be able to use this information to decide if the leaf is selected or not and filter them out. If you can give some more information, I can probably answer with more detail.

Juta answered 23/6, 2009 at 22:30 Comment(2)
Instead of leaves & branches, lets talk of directories & files. Given an arbitrary directory tree I wish to display only files matching *.foo. Furthermore I would like to only display directories that contain *.foo files, or recursively contain directories that do. Directories containing no such files should not be displayed. Does this help? M.Foreyard
In that case, in the select method, you will need to look recursively starting the element, getting its children until you reach an even leaf(return true) or the end (return false).Juta

© 2022 - 2024 — McMap. All rights reserved.