Package org.eclipse.jface.databinding.fieldassist

Source Code of org.eclipse.jface.databinding.fieldassist.ControlDecorationSupport$TargetDecoration

/*******************************************************************************
* Copyright (c) 2009, 2010 Matthew Hall 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:
*     Matthew Hall - initial API and implementation (bug 268472)
*     Matthew Hall - bug 300953
******************************************************************************/

package org.eclipse.jface.databinding.fieldassist;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.databinding.ValidationStatusProvider;
import org.eclipse.core.databinding.observable.DisposeEvent;
import org.eclipse.core.databinding.observable.IDecoratingObservable;
import org.eclipse.core.databinding.observable.IDisposeListener;
import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.core.databinding.observable.IObserving;
import org.eclipse.core.databinding.observable.list.IListChangeListener;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.list.ListChangeEvent;
import org.eclipse.core.databinding.observable.list.ListDiffVisitor;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.IValueChangeListener;
import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.databinding.swt.ISWTObservable;
import org.eclipse.jface.databinding.viewers.IViewerObservable;
import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Widget;

/**
* Decorates the underlying controls of the target observables of a
* {@link ValidationStatusProvider} with {@link ControlDecoration}s mirroring
* the current validation status. Only those target observables which implement
* {@link ISWTObservable} or {@link IViewerObservable} are decorated.
*
* @since 1.4
*/
public class ControlDecorationSupport {
  /**
   * Creates a ControlDecorationSupport which observes the validation status
   * of the specified {@link ValidationStatusProvider}, and displays a
   * {@link ControlDecoration} over the underlying SWT control of all target
   * observables that implement {@link ISWTObservable} or
   * {@link IViewerObservable}.
   *
   * @param validationStatusProvider
   *            the {@link ValidationStatusProvider} to monitor.
   * @param position
   *            SWT alignment constant (e.g. SWT.LEFT | SWT.TOP) to use when
   *            constructing {@link ControlDecorationSupport}
   * @return a ControlDecorationSupport which observes the validation status
   *         of the specified {@link ValidationStatusProvider}, and displays a
   *         {@link ControlDecoration} over the underlying SWT control of all
   *         target observables that implement {@link ISWTObservable} or
   *         {@link IViewerObservable}.
   */
  public static ControlDecorationSupport create(
      ValidationStatusProvider validationStatusProvider, int position) {
    return create(validationStatusProvider, position, null,
        new ControlDecorationUpdater());
  }

  /**
   * Creates a ControlDecorationSupport which observes the validation status
   * of the specified {@link ValidationStatusProvider}, and displays a
   * {@link ControlDecoration} over the underlying SWT control of all target
   * observables that implement {@link ISWTObservable} or
   * {@link IViewerObservable}.
   *
   * @param validationStatusProvider
   *            the {@link ValidationStatusProvider} to monitor.
   * @param position
   *            SWT alignment constant (e.g. SWT.LEFT | SWT.TOP) to use when
   *            constructing {@link ControlDecoration} instances.
   * @param composite
   *            the composite to use when constructing
   *            {@link ControlDecoration} instances.
   * @return a ControlDecorationSupport which observes the validation status
   *         of the specified {@link ValidationStatusProvider}, and displays a
   *         {@link ControlDecoration} over the underlying SWT control of all
   *         target observables that implement {@link ISWTObservable} or
   *         {@link IViewerObservable}.
   */
  public static ControlDecorationSupport create(
      ValidationStatusProvider validationStatusProvider, int position,
      Composite composite) {
    return create(validationStatusProvider, position, composite,
        new ControlDecorationUpdater());
  }

  /**
   * Creates a ControlDecorationSupport which observes the validation status
   * of the specified {@link ValidationStatusProvider}, and displays a
   * {@link ControlDecoration} over the underlying SWT control of all target
   * observables that implement {@link ISWTObservable} or
   * {@link IViewerObservable}.
   *
   * @param validationStatusProvider
   *            the {@link ValidationStatusProvider} to monitor.
   * @param position
   *            SWT alignment constant (e.g. SWT.LEFT | SWT.TOP) to use when
   *            constructing {@link ControlDecoration} instances.
   * @param composite
   *            the composite to use when constructing
   *            {@link ControlDecoration} instances.
   * @param updater
   *            custom strategy for updating the {@link ControlDecoration}(s)
   *            whenever the validation status changes.
   * @return a ControlDecorationSupport which observes the validation status
   *         of the specified {@link ValidationStatusProvider}, and displays a
   *         {@link ControlDecoration} over the underlying SWT control of all
   *         target observables that implement {@link ISWTObservable} or
   *         {@link IViewerObservable}.
   */
  public static ControlDecorationSupport create(
      ValidationStatusProvider validationStatusProvider, int position,
      Composite composite, ControlDecorationUpdater updater) {
    return new ControlDecorationSupport(validationStatusProvider, position,
        composite, updater);
  }

  private final int position;
  private final Composite composite;
  private final ControlDecorationUpdater updater;

  private IObservableValue validationStatus;
  private IObservableList targets;

  private IDisposeListener disposeListener = new IDisposeListener() {
    public void handleDispose(DisposeEvent staleEvent) {
      dispose();
    }
  };

  private IValueChangeListener statusChangeListener = new IValueChangeListener() {
    public void handleValueChange(ValueChangeEvent event) {
      statusChanged((IStatus) validationStatus.getValue());
    }
  };

  private IListChangeListener targetsChangeListener = new IListChangeListener() {
    public void handleListChange(ListChangeEvent event) {
      event.diff.accept(new ListDiffVisitor() {
        public void handleAdd(int index, Object element) {
          targetAdded((IObservable) element);
        }

        public void handleRemove(int index, Object element) {
          targetRemoved((IObservable) element);
        }
      });
      statusChanged((IStatus) validationStatus.getValue());
    }
  };

  private static class TargetDecoration {
    public final IObservable target;
    public final ControlDecoration decoration;

    TargetDecoration(IObservable target, ControlDecoration decoration) {
      this.target = target;
      this.decoration = decoration;
    }
  }

  private List targetDecorations;

  private ControlDecorationSupport(
      ValidationStatusProvider validationStatusProvider, int position,
      Composite composite, ControlDecorationUpdater updater) {
    this.position = position;
    this.composite = composite;
    this.updater = updater;

    this.validationStatus = validationStatusProvider.getValidationStatus();
    Assert.isTrue(!this.validationStatus.isDisposed());

    this.targets = validationStatusProvider.getTargets();
    Assert.isTrue(!this.targets.isDisposed());

    this.targetDecorations = new ArrayList();

    validationStatus.addDisposeListener(disposeListener);
    validationStatus.addValueChangeListener(statusChangeListener);

    targets.addDisposeListener(disposeListener);
    targets.addListChangeListener(targetsChangeListener);

    for (Iterator it = targets.iterator(); it.hasNext();)
      targetAdded((IObservable) it.next());

    statusChanged((IStatus) validationStatus.getValue());
  }

  private void targetAdded(IObservable target) {
    Control control = findControl(target);
    if (control != null)
      targetDecorations.add(new TargetDecoration(target,
          new ControlDecoration(control, position, composite)));
  }

  private void targetRemoved(IObservable target) {
    for (Iterator it = targetDecorations.iterator(); it.hasNext();) {
      TargetDecoration targetDecoration = (TargetDecoration) it.next();
      if (targetDecoration.target == target) {
        targetDecoration.decoration.dispose();
        it.remove();
      }
    }
  }

  private Control findControl(IObservable target) {
    if (target instanceof ISWTObservable) {
      Widget widget = ((ISWTObservable) target).getWidget();
      if (widget instanceof Control)
        return (Control) widget;
    }

    if (target instanceof IViewerObservable) {
      Viewer viewer = ((IViewerObservable) target).getViewer();
      return viewer.getControl();
    }

    if (target instanceof IDecoratingObservable) {
      IObservable decorated = ((IDecoratingObservable) target)
          .getDecorated();
      Control control = findControl(decorated);
      if (control != null)
        return control;
    }

    if (target instanceof IObserving) {
      Object observed = ((IObserving) target).getObserved();
      if (observed instanceof IObservable)
        return findControl((IObservable) observed);
    }

    return null;
  }

  private void statusChanged(IStatus status) {
    for (Iterator it = targetDecorations.iterator(); it.hasNext();) {
      TargetDecoration targetDecoration = (TargetDecoration) it.next();
      ControlDecoration decoration = targetDecoration.decoration;
      updater.update(decoration, status);
    }
  }

  /**
   * Disposes this ControlDecorationSupport, including all control decorations
   * managed by it. A ControlDecorationSupport is automatically disposed when
   * its target ValidationStatusProvider is disposed.
   */
  public void dispose() {
    if (validationStatus != null) {
      validationStatus.removeDisposeListener(disposeListener);
      validationStatus.removeValueChangeListener(statusChangeListener);
      validationStatus = null;
    }

    if (targets != null) {
      targets.removeDisposeListener(disposeListener);
      targets.removeListChangeListener(targetsChangeListener);
      targets = null;
    }

    disposeListener = null;
    statusChangeListener = null;
    targetsChangeListener = null;

    if (targetDecorations != null) {
      for (Iterator it = targetDecorations.iterator(); it.hasNext();) {
        TargetDecoration targetDecoration = (TargetDecoration) it
            .next();
        targetDecoration.decoration.dispose();
      }
      targetDecorations.clear();
      targetDecorations = null;
    }
  }
}
TOP

Related Classes of org.eclipse.jface.databinding.fieldassist.ControlDecorationSupport$TargetDecoration

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.