/******************************************************************************* * Copyright (c) 2011, 2013 Wind River Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Wind River Systems - initial API and implementation * IBM Corporation - bug fixing *******************************************************************************/ package org.eclipse.debug.internal.ui.viewers.model.provisional; import java.util.HashSet; import java.util.Set; import org.eclipse.swt.SWT; /** * Tree of virtual items that is analogous to SWT's tree control. The tree is used * by the {@link VirtualTreeModelViewer}. * * @see VirtualTreeModelViewer * @since 3.8 */ public class VirtualTree extends VirtualItem { /** * Lazy virtual tree does not retrieve elements or labels, * except for the selected elements. */ private boolean fLazy; private IVirtualItemValidator fValidator; private class SelectedItemValidator implements IVirtualItemValidator { @Override public boolean isItemVisible(VirtualItem item) { // visible items. For now only mark the selected items as visible. for (int i = 0; i < fSelection.length; i++) { VirtualItem selectionItem = fSelection[i]; while (selectionItem != null) { if (item.equals(selectionItem)) { return true; } selectionItem = selectionItem.getParent(); } } return false; } @Override public void showItem(VirtualItem item) { } } /** * Set of listeners of the virtual tree. */ private Set<IVirtualItemListener> fVirtualItemListeners = new HashSet<IVirtualItemListener>(1); /** * The currently selected items. This array contains only * the leaf items which are selected. */ private VirtualItem[] fSelection = new VirtualItem[0]; /** * Constructs the virtual tree with the given style and validator. * * @param style The style flag. Only SWT.VIRTUAL flag is used. * @param validator Item validator used to determine item visibility. */ public VirtualTree(int style, IVirtualItemValidator validator) { super(null, new VirtualItem.Index(0)); fLazy = (style & SWT.VIRTUAL) != 0; if (fLazy && validator == null) { fValidator = new SelectedItemValidator(); } else { fValidator = validator; } clearNeedsLabelUpdate(); clearNeedsDataUpdate(); } /** * Disposes the virtual tree. */ @Override public void dispose() { super.dispose(); fVirtualItemListeners.clear(); } @Override public void setNeedsCountUpdate() { super.setNeedsCountUpdate(); clearNeedsLabelUpdate(); clearNeedsDataUpdate(); } @Override public void setNeedsLabelUpdate() { // no-op } @Override public void setData(String key, Object data) { super.setData(key, data); if (data == null) { clearNeedsDataUpdate(); } } /** * Adds a listener for when virtual items are revealed in the view. * @param listener Listener to add to list of listeners. */ public void addItemListener(IVirtualItemListener listener) { fVirtualItemListeners.add(listener); } public void removeItemListener(IVirtualItemListener listener) { fVirtualItemListeners.remove(listener); } public VirtualItem[] getSelection() { return fSelection; } public void setSelection(VirtualItem[] items) { fSelection = items; } public void showItem(VirtualItem item) { if (fValidator != null) { fValidator.showItem(item); } } public void fireItemDisposed(VirtualItem item) { for (IVirtualItemListener listener : fVirtualItemListeners) { listener.disposed(item); } } public void fireItemRevealed(VirtualItem item) { for (IVirtualItemListener listener : fVirtualItemListeners) { listener.revealed(item); } } @Override public void setData(Object data) { super.setData(data); // The root item always has children as long as the input is non-null, // so that it should be expanded. setHasItems(data != null); } @Override public void setHasItems(boolean hasChildren) { super.setHasItems(hasChildren); // The root item is always expanded as long as it has children. if (hasChildren) { setExpanded(true); } } /** * Returns whether the given item is considered visible by the tree as * determined by its virtual item validator. * * @param item Item to check. * @return true if items is vislble. * @see IVirtualItemValidator */ public boolean isItemVisible(VirtualItem item) { if (fLazy) { return fValidator.isItemVisible(item); } return true; } /** * Validates the entire tree. */ public void validate() { validate(VirtualTree.this); } /** * Validates the item and its children, identifying children which were * revealed and need to be updated. * * @param item The item which to validate. */ public void validate(VirtualItem item) { if (item.needsDataUpdate()) { if (isItemVisible(item)) { fireItemRevealed(item); } } else if (item.getData() != null) { if ( item.needsLabelUpdate() || (item.needsCountUpdate() && item.hasItems() && item.getExpanded()) ) { if (isItemVisible(item)) { fireItemRevealed(item); } } if (item.getData() != null && item.getItemCount() > 0 && item.getExpanded()) { for (int i = 0; i < item.getItemCount(); i++) { validate(item.getItem(new Index(i))); } } } } }