Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousViewer.java')
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousViewer.java1193
1 files changed, 0 insertions, 1193 deletions
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousViewer.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousViewer.java
deleted file mode 100644
index e5878c461..000000000
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousViewer.java
+++ /dev/null
@@ -1,1193 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation 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:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.debug.internal.ui.viewers;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.core.runtime.Assert;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.debug.internal.ui.DebugUIPlugin;
-import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener;
-import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy;
-import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelSelectionPolicy;
-import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelSelectionPolicyFactory;
-import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
-import org.eclipse.debug.internal.ui.viewers.model.provisional.IStatusMonitor;
-import org.eclipse.debug.internal.ui.viewers.model.provisional.PresentationContext;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.jface.viewers.StructuredViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.FontData;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.RGB;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Item;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Widget;
-import org.eclipse.ui.progress.WorkbenchJob;
-
-/**
- * A viewer that retrieves labels and content asynchronously via adapters and supports
- * duplicate elements in the viewer. Retrieving content and labels asynchronously allows
- * for arbitrary latency without blocking the UI thread.
- * <p>
- * This viewer uses adapters to retrieve labels and content rather than
- * a label provider and content provider. As such, the label provider for this viewer
- * is <code>null</code> by default. The content provider returned by this viewer is
- * non-<code>null</code> to conform to the viewer specification, but performs no
- * useful function.
- * </p>
- * <p>
- * The selection in this viewer is also set asynchronously. When the selection is set,
- * the viewer attempts to perform the selection. If the elements in the specified selection
- * are not yet in the viewer, the portion of the selection that could not be honored
- * becomes a pending selection. As more elements are added to viewer, the pending selection
- * is attempted to be set.
- * </p>
- * @since 3.2
- */
-public abstract class AsynchronousViewer extends StructuredViewer implements Listener {
-
- /**
- * Model of elements for this viewer
- */
- private AsynchronousModel fModel;
-
- /**
- * Cache of images used for elements in this tree viewer. Label updates
- * use the method <code>getImage(...)</code> to cache images for
- * image descriptors. The images are disposed when this viewer is disposed.
- */
- private Map fImageCache = new HashMap();
-
- /**
- * Cache of the fonts used for elements in this tree viewer. Label updates
- * use the method <code>getFont(...)</code> to cache fonts for
- * FontData objects. The fonts are disposed with the viewer.
- */
- private Map fFontCache = new HashMap();
-
- /**
- * Cache of the colors used for elements in this tree viewer. Label updates
- * use the method <code>getColor(...)</code> to cache colors for
- * RGB values. The colors are disposed with the viewer.
- */
- private Map fColorCache = new HashMap();
-
- /**
- * The context in which this viewer is being used - i.e. what part it is contained
- * in any any preference settings associated with it.
- */
- private IPresentationContext fContext;
-
- private ISelection fPendingSelection;
-
- private ISelection fCurrentSelection;
-
- /**
- * Array used to store indices of the path to an item in the viewer being mapped
- * by a 'set data' callback. Indices are bottom up. For example when 'set data' for
- * the 3rd child of the 4th child of the 2nd root element were being asked for,
- * the first 3 indices would look like: [3, 4, 2, ....]. We re-use an array to avoid
- * creating a new one all the time. The array grows as needed to accommodate deep
- * elements.
- */
- private int[] fSetDataIndicies = new int[5];
-
- /**
- * The update policy for this viewer.
- */
- private AbstractUpdatePolicy fUpdatePolicy;
-
- protected static final String OLD_LABEL = "old_label"; //$NON-NLS-1$
- protected static final String OLD_IMAGE = "old_image"; //$NON-NLS-1$
-
- // debug flags
- public static boolean DEBUG_VIEWER = false;
-
- static {
- DEBUG_VIEWER = DebugUIPlugin.DEBUG && "true".equals( //$NON-NLS-1$
- Platform.getDebugOption("org.eclipse.debug.ui/debug/viewers/viewer")); //$NON-NLS-1$
- }
-
- /**
- * Creates a new viewer
- */
- protected AsynchronousViewer() {
- setContentProvider(new NullContentProvider());
- setUseHashlookup(true);
- }
-
- /**
- * Hash lookup is required, don't let subclasses change behavior.
- */
- public final void setUseHashlookup(boolean enable) {
- Assert.isTrue(enable);
- super.setUseHashlookup(enable);
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.viewers.StructuredViewer#hookControl(org.eclipse.swt.widgets.Control)
- */
- protected void hookControl(Control control) {
- super.hookControl(control);
- control.addListener(SWT.SetData, this);
- }
-
- /**
- * Clients must call this methods when this viewer is no longer needed
- * so it can perform cleanup.
- */
- public synchronized void dispose() {
- Iterator images = fImageCache.values().iterator();
- while (images.hasNext()) {
- Image image = (Image) images.next();
- image.dispose();
- }
- fImageCache.clear();
-
- Iterator fonts = fFontCache.values().iterator();
- while (fonts.hasNext()) {
- Font font = (Font) fonts.next();
- font.dispose();
- }
- fFontCache.clear();
-
- Iterator colors = fColorCache.values().iterator();
- while (colors.hasNext()) {
- Color color = (Color) colors.next();
- color.dispose();
- }
- fColorCache.clear();
-
- if (fModel != null) {
- fModel.dispose();
- }
- if (fUpdatePolicy != null) {
- fUpdatePolicy.dispose();
- }
- if (fContext != null) {
- ((PresentationContext)fContext).dispose();
- }
- }
-
- /**
- * Updates all occurrences of the given element in this viewer.
- *
- * @param element element to update
- */
- public void update(Object element) {
- ModelNode[] nodes = getModel().getNodes(element);
- if (nodes != null) {
- for (int i = 0; i < nodes.length; i++) {
- updateLabel(nodes[i]);
- }
- }
- }
-
- /**
- * Updates the label for a specific element (node) in the model.
- *
- * @param node node to update
- * @param item its associated item
- */
- protected void updateLabel(ModelNode node) {
- // the input is not displayed
- if (!node.getElement().equals(getInput())) {
- getModel().updateLabel(node);
- }
- }
-
- /**
- * Returns the presentation context to be used in update requests.
- * Clients may override this method if required to provide special
- * implementations of contexts.
- *
- * @return presentation context
- */
- public IPresentationContext getPresentationContext() {
- return fContext;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.viewers.StructuredViewer#unmapAllElements()
- */
- protected synchronized void unmapAllElements() {
- super.unmapAllElements();
- AsynchronousModel model = getModel();
- if (model != null) {
- model.dispose();
- }
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.viewers.Viewer#inputChanged(java.lang.Object, java.lang.Object)
- */
- protected synchronized void inputChanged(Object input, Object oldInput) {
- fPendingSelection = null;
- if (fCurrentSelection != null) {
- updateSelection(new StructuredSelection());
- fCurrentSelection = null;
- }
- if (fUpdatePolicy == null) {
- fUpdatePolicy = createUpdatePolicy();
- fUpdatePolicy.init(this);
- }
- if (fModel != null) {
- fModel.dispose();
- }
- fModel = createModel();
- fModel.init(input);
- if (input != null) {
- mapElement(fModel.getRootNode(), getControl());
- getControl().setData(fModel.getRootNode().getElement());
- } else {
- unmapAllElements();
- getControl().setData(null);
- }
- refresh();
- }
-
- /**
- * Creates a new empty model for this viewer that
- * is *not* initialized.
- *
- * @return a new model
- */
- protected abstract AsynchronousModel createModel();
-
- /**
- * Creates and returns this viewers update policy.
- * @return update policy
- */
- public abstract AbstractUpdatePolicy createUpdatePolicy();
-
- Image[] getImages(ImageDescriptor[] descriptors) {
- if (descriptors == null || descriptors.length == 0) {
- String[] columns = getPresentationContext().getColumns();
- if (columns == null) {
- return new Image[1];
- } else {
- return new Image[columns.length];
- }
- }
- Image[] images = new Image[descriptors.length];
- for (int i = 0; i < images.length; i++) {
- images[i] = getImage(descriptors[i]);
- }
- return images;
- }
-
- /**
- * Returns an image for the given image descriptor or <code>null</code>. Adds the image
- * to a cache of images if it does not already exist. The cache is cleared when this viewer
- * is disposed.
- *
- * @param descriptor image descriptor or <code>null</code>
- * @return image or <code>null</code>
- */
- protected Image getImage(ImageDescriptor descriptor) {
- if (descriptor == null) {
- return null;
- }
- Image image = (Image) fImageCache.get(descriptor);
- if (image == null) {
- image = new Image(getControl().getDisplay(), descriptor.getImageData());
- fImageCache.put(descriptor, image);
- }
- return image;
- }
-
- protected Font[] getFonts(FontData[] fontDatas) {
- if (fontDatas == null || fontDatas.length == 0) {
- String[] columns = getPresentationContext().getColumns();
- if (columns == null) {
- return new Font[1];
- } else {
- return new Font[columns.length];
- }
- }
-
- Font[] fonts = new Font[fontDatas.length];
- for (int i = 0; i < fonts.length; i++) {
- fonts[i] = getFont(fontDatas[i]);
- }
- return fonts;
- }
-
- /**
- * Returns a font for the given font data or <code>null</code>. Adds the font to this viewer's font
- * cache which is disposed when this viewer is disposed.
- *
- * @param fontData font data or <code>null</code>
- * @return font font or <code>null</code>
- */
- protected Font getFont(FontData fontData) {
- if (fontData == null) {
- return null;
- }
- Font font = (Font) fFontCache.get(fontData);
- if (font == null) {
- font = new Font(getControl().getDisplay(), fontData);
- fFontCache.put(fontData, font);
- }
- return font;
- }
-
- protected Color[] getColors(RGB[] rgb) {
- if (rgb == null || rgb.length == 0) {
- String[] columns = getPresentationContext().getColumns();
- if (columns == null) {
- return new Color[1];
- } else {
- return new Color[columns.length];
- }
- }
- Color[] colors = new Color[rgb.length];
- for (int i = 0; i < colors.length; i++) {
- colors[i] = getColor(rgb[i]);
- }
- return colors;
- }
- /**
- * Returns a color for the given RGB or <code>null</code>. Adds the color to this viewer's color
- * cache which is disposed when this viewer is disposed.
- *
- * @param rgb RGB or <code>null</code>
- * @return color or <code>null</code>
- */
- protected Color getColor(RGB rgb) {
- if (rgb == null) {
- return null;
- }
- Color color = (Color) fColorCache.get(rgb);
- if (color == null) {
- color = new Color(getControl().getDisplay(), rgb);
- fColorCache.put(rgb, color);
- }
- return color;
- }
-
- /**
- * Sets the context for this viewer.
- *
- * @param context
- */
- public void setContext(IPresentationContext context) {
- fContext = context;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.viewers.StructuredViewer#doFindItem(java.lang.Object)
- */
- protected Widget doFindItem(Object element) {
- // this viewer maps model nodes to widgets, so the element is a ModelNode
- AsynchronousModel model = getModel();
- if (model != null) {
- if (element.equals(model.getRootNode())) {
- return doFindInputItem(element);
- }
- Widget[] widgets = findItems(element);
- if (widgets.length > 0) {
- return widgets[0];
- }
- }
- return null;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.jface.viewers.StructuredViewer#doFindInputItem(java.lang.Object)
- */
- protected Widget doFindInputItem(Object element) {
- if (element instanceof ModelNode) {
- ModelNode node = (ModelNode) element;
- if (node.getElement().equals(getInput())) {
- return getControl();
- }
- }
- return null;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.viewers.StructuredViewer#doUpdateItem(org.eclipse.swt.widgets.Widget, java.lang.Object, boolean)
- */
- protected void doUpdateItem(Widget item, Object element, boolean fullMap) {
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.viewers.StructuredViewer#internalRefresh(java.lang.Object)
- */
- protected void internalRefresh(Object element) {
- // get the nodes in the model
- AsynchronousModel model = getModel();
- if (model != null) {
- ModelNode[] nodes = model.getNodes(element);
- if (nodes != null) {
- for (int i = 0; i < nodes.length; i++) {
- ModelNode node = nodes[i];
- // get the widget for the node
- Widget item = findItem(node);
- if (item != null) {
- internalRefresh(node);
- }
- }
- }
- }
- }
-
- /**
- * Refreshes a specific occurrence of an element (a node).
- *
- * @param node node to update
- *
- * Subclasses should override and call super
- */
- protected void internalRefresh(ModelNode node) {
- updateLabel(node);
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.viewers.Viewer#setSelection(org.eclipse.jface.viewers.ISelection, boolean)
- */
- public synchronized void setSelection(ISelection selection, boolean reveal) {
- setSelection(selection, reveal, false);
- }
-
- /**
- * Sets the selection in this viewer.
- *
- * @param selection new selection
- * @param reveal whether to reveal the selection
- * @param force whether to force the selection change without consulting the model
- * selection policy
- */
- public synchronized void setSelection(ISelection selection, final boolean reveal, boolean force) {
- Control control = getControl();
- if (control == null || control.isDisposed()) {
- return;
- }
- if (!acceptsSelection(selection)) {
- selection = getEmptySelection();
- }
- if (!force && !overrideSelection(fCurrentSelection, selection)) {
- return;
- }
-
- fPendingSelection = selection;
-
- if (getControl().getDisplay().getThread() == Thread.currentThread()) {
- attemptSelection(reveal);
- } else {
- WorkbenchJob job = new WorkbenchJob("attemptSelection") { //$NON-NLS-1$
- public IStatus runInUIThread(IProgressMonitor monitor) {
- attemptSelection(reveal);
- return Status.OK_STATUS;
- }
-
- };
- job.setSystem(true);
- job.schedule();
- }
- }
-
-
- /**
- * Returns whether the candidate selection should override the current
- * selection.
- *
- * @param current
- * @param curr
- * @return
- */
- protected boolean overrideSelection(ISelection current, ISelection candidate) {
- IModelSelectionPolicy selectionPolicy = getSelectionPolicy(current);
- if (selectionPolicy == null) {
- return true;
- }
- if (selectionPolicy.contains(candidate, getPresentationContext())) {
- return selectionPolicy.overrides(current, candidate, getPresentationContext());
- }
- return !selectionPolicy.isSticky(current, getPresentationContext());
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.viewers.StructuredViewer#getSelection()
- */
- public ISelection getSelection() {
- Control control = getControl();
- if (control == null || control.isDisposed() || fCurrentSelection == null) {
- return StructuredSelection.EMPTY;
- }
- return fCurrentSelection;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.viewers.StructuredViewer#handleSelect(org.eclipse.swt.events.SelectionEvent)
- */
- protected void handleSelect(SelectionEvent event) {
- // handle case where an earlier selection listener disposed the control.
- Control control = getControl();
- if (control != null && !control.isDisposed()) {
- updateSelection(newSelectionFromWidget());
- }
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.viewers.StructuredViewer#handlePostSelect(org.eclipse.swt.events.SelectionEvent)
- */
- protected void handlePostSelect(SelectionEvent e) {
- SelectionChangedEvent event = new SelectionChangedEvent(this, newSelectionFromWidget());
- firePostSelectionChanged(event);
- }
-
- /**
- * Creates and returns a new selection from this viewer, based on the selected
- * elements in the widget.
- *
- * @return a new selection
- */
- protected abstract ISelection newSelectionFromWidget();
-
- /**
- * Returns the selection policy associated with the given selection
- * or <code>null</code> if none.
- *
- * @param selection or <code>null</code>
- * @return selection policy or <code>null</code>
- */
- protected IModelSelectionPolicy getSelectionPolicy(ISelection selection) {
- if (selection instanceof IStructuredSelection) {
- IStructuredSelection ss = (IStructuredSelection) selection;
- Object element = ss.getFirstElement();
- if (element instanceof IAdaptable) {
- IAdaptable adaptable = (IAdaptable) element;
- IModelSelectionPolicyFactory factory = (IModelSelectionPolicyFactory) adaptable.getAdapter(IModelSelectionPolicyFactory.class);
- if (factory != null) {
- return factory.createModelSelectionPolicyAdapter(adaptable, getPresentationContext());
- }
- }
- }
- return null;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.viewers.StructuredViewer#setSelectionToWidget(org.eclipse.jface.viewers.ISelection, boolean)
- */
- final protected void setSelectionToWidget(ISelection selection, final boolean reveal) {
- // NOT USED
- throw new IllegalArgumentException("This method should not be called"); //$NON-NLS-1$
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.viewers.StructuredViewer#setSelectionToWidget(java.util.List, boolean)
- */
- final protected void setSelectionToWidget(List l, boolean reveal) {
- // NOT USED
- throw new IllegalArgumentException("This method should not be called"); //$NON-NLS-1$
- }
-
- /**
- * Attempts to update any pending selection.
- *
- * @param reveal whether to reveal the selection
- */
- protected void attemptSelection(boolean reveal) {
- ISelection currentSelection = null;
- synchronized (this) {
- if (fPendingSelection != null) {
- ISelection remaining = doAttemptSelectionToWidget(fPendingSelection, reveal);
- if (remaining.isEmpty()) {
- remaining = null;
- }
- if (!fPendingSelection.equals(remaining)) {
- fPendingSelection = remaining;
- currentSelection = newSelectionFromWidget();
- if (isSuppressEqualSelections() && currentSelection.equals(fCurrentSelection)) {
- return;
- }
- }
- }
- }
- if (currentSelection != null) {
- updateSelection(currentSelection);
- firePostSelectionChanged(new SelectionChangedEvent(this, currentSelection));
- }
- }
-
- /**
- * Controls whether selection change notification is sent even when
- * successive selections are equal.
- *
- * TODO: what we really want is to fire selection change on ACTIVATE model
- * change, even when selection is the same.
- *
- * @return whether to suppress change notification for equal successive
- * selections
- */
- protected boolean isSuppressEqualSelections() {
- return true;
- }
-
- /**
- * Attempts to selection the specified selection and returns a selection
- * representing the portion of the selection that could not be honored
- * and still needs to be selected.
- *
- * @param selection selection to attempt
- * @param reveal whether to reveal the selection
- * @return remaining selection
- */
- protected abstract ISelection doAttemptSelectionToWidget(ISelection selection, boolean reveal);
-
- /**
- * Returns whether this viewer supports the given selection.
- *
- * @param selection a selection
- * @return whether this viewer supports the given selection
- */
- protected abstract boolean acceptsSelection(ISelection selection);
-
- /**
- * Returns an empty selection supported by this viewer.
- *
- * @return an empty selection supported by this viewer
- */
- protected abstract ISelection getEmptySelection();
-
- /**
- * A content provider that does nothing.
- */
- private class NullContentProvider implements IStructuredContentProvider {
- public void dispose() {
- }
-
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- }
-
- public Object[] getElements(Object inputElement) {
- return null;
- }
- }
-
- /**
- * Notification that a presentation update has failed.
- * Subclasses may override as required. The default implementation
- * does nothing.
- *
- * @param monitor monitor for the presentation request that failed
- * @param status status of update
- */
- protected void handlePresentationFailure(IStatusMonitor monitor, IStatus status) {
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.viewers.StructuredViewer#preservingSelection(java.lang.Runnable)
- */
- protected synchronized void preservingSelection(Runnable updateCode) {
- if (fPendingSelection == null || fPendingSelection.isEmpty()) {
- ISelection oldSelection = null;
- try {
- // preserve selection
- oldSelection = fCurrentSelection;
- // perform the update
- updateCode.run();
- } finally {
- // restore selection
- if (oldSelection == null) {
- oldSelection = new StructuredSelection();
- }
- if (getControl().getDisplay().getThread() == Thread.currentThread()) {
- if (!oldSelection.equals(newSelectionFromWidget())) {
- restoreSelection(oldSelection);
- }
- } else {
- WorkbenchJob job = new WorkbenchJob("attemptSelection") { //$NON-NLS-1$
- public IStatus runInUIThread(IProgressMonitor monitor) {
- synchronized (AsynchronousViewer.this) {
- if (!getControl().isDisposed()) {
- if (fPendingSelection == null || fPendingSelection.isEmpty()) {
- ISelection tempSelection = fCurrentSelection;
- if (tempSelection == null) {
- tempSelection = new StructuredSelection();
- }
- if (!tempSelection.equals(newSelectionFromWidget())) {
- restoreSelection(tempSelection);
- }
- }
- }
- }
- return Status.OK_STATUS;
- }
-
- };
- job.setSystem(true);
- job.schedule();
- }
- }
- } else {
- updateCode.run();
- }
- }
-
- protected synchronized void restoreSelection(ISelection oldSelection) {
- ISelection remaining = doAttemptSelectionToWidget(oldSelection, false);
- // send out notification if old and new differ
- fCurrentSelection = newSelectionFromWidget();
- if (!selectionExists(fCurrentSelection)) {
- if (selectionExists(oldSelection)) {
- // old selection exists in the model, but not widget
- fCurrentSelection = oldSelection;
- } else {
- fCurrentSelection = getEmptySelection();
- }
- }
- if (!fCurrentSelection.equals(oldSelection)) {
- handleInvalidSelection(oldSelection, fCurrentSelection);
- // if the remaining selection still exists in the model, make it pending
- if (selectionExists(remaining)) {
- setSelection(remaining);
- }
- }
- }
-
- /**
- * Returns whether the selection exists in the model
- */
- protected boolean selectionExists(ISelection selection) {
- if (selection.isEmpty()) {
- return false;
- }
- if (selection instanceof IStructuredSelection) {
- IStructuredSelection ss = (IStructuredSelection) selection;
- Iterator iterator = ss.iterator();
- while (iterator.hasNext()) {
- Object element = iterator.next();
- if (getModel().getNodes(element) == null) {
- return false;
- }
- }
- }
- return true;
- }
-
- /**
- * Sets the color attributes of the given widget.
- *
- * @param widget the widget to update
- * @param foreground foreground color of the widget or <code>null</code> if default
- * @param background background color of the widget or <code>null</code> if default
- */
- protected abstract void setColors(Widget widget, RGB foreground[], RGB background[]);
-
- /**
- * Sets the label attributes of the given widget.
- *
- * @param widget the widget to update
- * @param text label text
- * @param image label image or <code>null</code>
- */
- protected abstract void setLabels(Widget widget, String[] text, ImageDescriptor[] image);
-
- /**
- * Sets the font attributes of the given widget.
- *
- * @param widget widget to update
- * @param font font of the widget or <code>null</code> if default.
- */
- protected abstract void setFonts(Widget widget, FontData[] font);
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.viewers.StructuredViewer#updateSelection(org.eclipse.jface.viewers.ISelection)
- */
- protected synchronized void updateSelection(ISelection selection) {
- fCurrentSelection = selection;
- super.updateSelection(selection);
- }
-
-
-
- /**
- * Notification the given model proxy has been added to this viewer's model.
- *
- * @param proxy
- */
- protected void modelProxyAdded(IModelProxy proxy) {
- if (fUpdatePolicy instanceof IModelChangedListener) {
- proxy.addModelChangedListener((IModelChangedListener)fUpdatePolicy);
- }
- }
-
- /**
- * Notification the given model proxy has been removed from this viewer's model.
- *
- * @param proxy
- */
- protected void modelProxyRemoved(IModelProxy proxy) {
- if (fUpdatePolicy instanceof IModelChangedListener) {
- proxy.removeModelChangedListener((IModelChangedListener)fUpdatePolicy);
- }
- }
-
- /**
- * Returns this viewer's model
- *
- * @return model
- */
- protected AsynchronousModel getModel() {
- return fModel;
- }
-
- /**
- * A node in the model has been updated
- *
- * @param node
- */
- protected void nodeChanged(ModelNode node) {
- Widget widget = findItem(node);
- if (widget != null) {
- clear(widget);
- attemptPendingUpdates();
- }
- }
-
- /**
- * @return if there are any more pending updates in the viewer
- */
- public synchronized boolean hasPendingUpdates() {
- return getModel().hasPendingUpdates();
- }
-
- /**
- * Notification from the model that the update for the given request
- * has completed.
- *
- * @param monitor
- */
- protected void updateComplete(IStatusMonitor monitor) {
- }
-
- /**
- * Clears the given widget
- *
- * @param item
- */
- protected abstract void clear(Widget item);
-
- /**
- * Clears the children of the widget.
- *
- * @param item
- */
- protected abstract void clearChildren(Widget item);
-
- /**
- * Clears the child at the given index.
- *
- * @param parent
- * @param childIndex
- */
- protected abstract void clearChild(Widget parent, int childIndex);
-
- /**
- * Returns the child widget at the given index for the given parent or
- * <code>null</code>
- *
- * @param parent
- * @param index
- * @return
- */
- protected abstract Widget getChildWidget(Widget parent, int index);
-
- /**
- * Sets the item count for a parent widget
- *
- * @param parent
- * @param itemCount
- */
- protected abstract void setItemCount(Widget parent, int itemCount);
-
- /**
- * Attempt pending updates. Subclasses may override but should call super.
- */
- protected void attemptPendingUpdates() {
- attemptSelection(false);
- }
-
- /**
- * Notification a node's children have changed.
- * Updates the child count for the parent's widget
- * and clears children to be updated.
- *
- * @param parentNode
- */
- protected void nodeChildrenChanged(ModelNode parentNode) {
- Widget widget = findItem(parentNode);
- if (widget != null && !widget.isDisposed()) {
- int childCount = parentNode.getChildCount();
- setItemCount(widget, childCount);
- clearChildren(widget);
- attemptPendingUpdates();
- }
- }
-
- /**
- * Notification children have been added to the end
- * of the given parent.
- *
- * @param parentNode
- */
- protected void nodeChildrenAdded(ModelNode parentNode) {
- Widget widget = findItem(parentNode);
- if (widget != null && !widget.isDisposed()) {
- int childCount = parentNode.getChildCount();
- setItemCount(widget, childCount);
- attemptPendingUpdates();
- }
- }
-
- /**
- * Notification children have been added to the end
- * of the given parent.
- *
- * @param parentNode
- */
- protected void nodeChildRemoved(ModelNode parentNode, int index) {
- Widget widget = findItem(parentNode);
- if (widget != null && !widget.isDisposed()) {
- Widget childWidget = getChildWidget(widget, index);
- int childCount = parentNode.getChildCount();
- // if the child widget exists, dispose it so item state remains, otherwise update child count
- if (childWidget == null) {
- setItemCount(widget, childCount);
- } else {
- childWidget.dispose();
- }
- for (int i = index; i < childCount; i ++) {
- clearChild(widget, i);
- }
- attemptPendingUpdates();
- }
- }
-
- /**
- * Unmaps the node from its widget and all of its children nodes from
- * their widgets.
- *
- * @param node
- */
- protected void unmapNode(ModelNode node) {
- unmapElement(node);
- ModelNode[] childrenNodes = node.getChildrenNodes();
- if (childrenNodes != null) {
- for (int i = 0; i < childrenNodes.length; i++) {
- unmapNode(childrenNodes[i]);
- }
- }
- }
-
- /**
- * Returns the node corresponding to the given widget or <code>null</code>
- * @param widget widget for which a node is requested
- * @return node or <code>null</code>
- */
- protected ModelNode findNode(Widget widget) {
- ModelNode[] nodes = getModel().getNodes(widget.getData());
- if (nodes != null) {
- for (int i = 0; i < nodes.length; i++) {
- ModelNode node = nodes[i];
- Widget item = findItem(node);
- if (widget == item) {
- return node;
- }
- }
- }
- return null;
- }
-
- /**
- * Returns the item for the node or <code>null</code>
- * @param node
- * @return
- */
- protected Widget findItem(ModelNode node) {
- return findItem((Object)node);
- }
-
- /*
- * (non-Javadoc)
- *
- * A virtual item has been exposed in the control, map its data.
- *
- * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
- */
- public void handleEvent(final Event event) {
- update((Item)event.item, event.index);
- }
-
- /**
- * Update the given item.
- *
- * @param item item to update
- * @param index index of item in parent's children
- */
- protected void update(Item item, int index) {
- restoreLabels(item);
- int level = 0;
-
- Widget parentItem = getParentWidget(item);
- if (DEBUG_VIEWER) {
- DebugUIPlugin.debug("SET DATA [" + index + "]: " + parentItem); //$NON-NLS-1$//$NON-NLS-2$
- }
- ModelNode node = null;
- // first, see if the parent element is in the model
- // and look directly for the child
- if (parentItem != null) {
- ModelNode[] nodes = getModel().getNodes(parentItem.getData());
- if (nodes != null) {
- for (int i = 0; i < nodes.length; i++) {
- ModelNode parentNode = nodes[i];
- Widget parentWidget = findItem(parentNode);
- if (parentWidget == parentItem) {
- ModelNode[] childrenNodes = parentNode.getChildrenNodes();
- if (childrenNodes != null && index < childrenNodes.length) {
- node = childrenNodes[index];
- }
- }
- }
- }
- }
-
- // otherwise, build a path to the model node
- if (node == null) {
- setNodeIndex(index, level);
- while (parentItem instanceof Item) {
- level++;
- Widget parent = getParentWidget(parentItem);
- int pindex = indexOf(parent, parentItem);
- if (pindex < 0) {
- return;
- }
- setNodeIndex(pindex, level);
- parentItem = parent;
- }
-
- node = getModel().getRootNode();
- if (node == null) {
- if (DEBUG_VIEWER) {
- DebugUIPlugin.debug("\tFAILED - root model node is null"); //$NON-NLS-1$
- }
- return;
- }
- for (int i = level; i >= 0; i--) {
- ModelNode[] childrenNodes = node.getChildrenNodes();
- if (childrenNodes == null) {
- if (DEBUG_VIEWER) {
- DebugUIPlugin.debug("\tFAILED - no children nodes for " + node); //$NON-NLS-1$
- }
- return;
- }
- int pindex = getNodeIndex(i);
- if (pindex < childrenNodes.length) {
- node = childrenNodes[pindex];
- } else {
- if (DEBUG_VIEWER) {
- DebugUIPlugin.debug("\tFAILED - no children nodes for " + node); //$NON-NLS-1$
- }
- return;
- }
- }
- }
-
-
- // map the node to the element and refresh it
- if (node != null) {
- mapElement(node, item);
- item.setData(node.getElement());
- if (DEBUG_VIEWER) {
- DebugUIPlugin.debug("\titem mapped: " + node); //$NON-NLS-1$
- }
- internalRefresh(node);
- } else {
- if (DEBUG_VIEWER) {
- DebugUIPlugin.debug("\tFAILED - unable to find corresponding node"); //$NON-NLS-1$
- }
- }
- }
-
- /**
- * Sets the index of a child node being mapped at the given expansion level
- * in the tree.
- *
- * @param nodeIndex
- * @param level
- */
- private void setNodeIndex(int nodeIndex, int level) {
- if (level > (fSetDataIndicies.length - 1)) {
- // grow the array
- int[] next = new int[level+5];
- System.arraycopy(fSetDataIndicies, 0, next, 0, fSetDataIndicies.length);
- fSetDataIndicies = next;
- }
- fSetDataIndicies[level] = nodeIndex;
- }
-
- /**
- * Returns the index of a child node being mapped at the given expansion level in
- * the tree.
- *
- * @param level
- * @return
- */
- private int getNodeIndex(int level) {
- return fSetDataIndicies[level];
- }
-
- protected abstract int indexOf(Widget parent, Widget child);
-
- protected abstract void restoreLabels(Item item);
-
- /**
- * Returns the parent widget for the given widget or <code>null</code>
- *
- * @param widget
- * @return parent widget or <code>null</code>
- */
- protected abstract Widget getParentWidget(Widget widget);
-
- /**
- * Updates the children of the given node.
- *
- * @param parent
- * node of which to update children
- */
- protected void updateChildren(ModelNode parent) {
- getModel().updateChildren(parent);
- }
-}

Back to the top