Mercurial > projects > dwt2
diff org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/wizard/WizardPageSupport.d @ 78:0a55d2d5a946
Added file for databinding
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Tue, 14 Apr 2009 11:35:29 +0200 |
parents | |
children | 6be48cf9f95c |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/wizard/WizardPageSupport.d Tue Apr 14 11:35:29 2009 +0200 @@ -0,0 +1,301 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 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 + * Boris Bokowski - bug 218269 + * Matthew Hall - bug 218269 + * Ashley Cambrell - bug 199179 + *******************************************************************************/ +module org.eclipse.jface.databinding.wizard.WizardPageSupport; + +import java.lang.all; + +import java.util.Iterator; + +import org.eclipse.core.databinding.AggregateValidationStatus; +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.ValidationStatusProvider; +import org.eclipse.core.databinding.observable.ChangeEvent; +import org.eclipse.core.databinding.observable.IChangeListener; +import org.eclipse.core.databinding.observable.IObservable; +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.ListDiff; +import org.eclipse.core.databinding.observable.list.ListDiffEntry; +import org.eclipse.core.databinding.observable.value.IValueChangeListener; +import org.eclipse.core.databinding.observable.value.ValueChangeEvent; +import org.eclipse.core.databinding.util.Policy; +import org.eclipse.core.runtime.AssertionFailedException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.wizard.WizardPage; + +/** + * Connects the validation result from the given data binding context to the + * given wizard page, updating the wizard page's completion state and its error + * message accordingly. + * + * @noextend This class is not intended to be subclassed by clients. + * + * @since 1.1 + */ +public class WizardPageSupport { + + private WizardPage wizardPage; + private DataBindingContext dbc; + private AggregateValidationStatus aggregateStatus; + private bool uiChanged = false; + + /** + * Connect the validation result from the given data binding context to the + * given wizard page. Upon creation, the wizard page support will use the + * context's validation result to determine whether the page is complete. + * The page's error message will not be set at this time ensuring that the + * wizard page does not show an error right away. Upon any validation result + * change, {@link WizardPage#setPageComplete(bool)} will be called + * reflecting the new validation result, and the wizard page's error message + * will be updated according to the current validation result. + * + * @param wizardPage + * @param dbc + * @return an instance of WizardPageSupport + */ + public static WizardPageSupport create(WizardPage wizardPage, + DataBindingContext dbc) { + return new WizardPageSupport(wizardPage, dbc); + } + + private this(WizardPage wizardPage, DataBindingContext dbc) { + this.wizardPage = wizardPage; + this.dbc = dbc; + init(); + } + + private IChangeListener uiChangeListener = new class() IChangeListener { + public void handleChange(ChangeEvent event) { + handleUIChanged(); + } + }; + private IListChangeListener validationStatusProvidersListener = new class() IListChangeListener { + public void handleListChange(ListChangeEvent event) { + ListDiff diff = event.diff; + ListDiffEntry[] differences = diff.getDifferences(); + for (int i = 0; i < differences.length; i++) { + ListDiffEntry listDiffEntry = differences[i]; + ValidationStatusProvider validationStatusProvider = cast(ValidationStatusProvider) listDiffEntry + .getElement(); + IObservableList targets = validationStatusProvider.getTargets(); + if (listDiffEntry.isAddition()) { + targets + .addListChangeListener(validationStatusProviderTargetsListener); + for (Iterator it = targets.iterator(); it.hasNext();) { + (cast(IObservable) it.next()) + .addChangeListener(uiChangeListener); + } + } else { + targets + .removeListChangeListener(validationStatusProviderTargetsListener); + for (Iterator it = targets.iterator(); it.hasNext();) { + (cast(IObservable) it.next()) + .removeChangeListener(uiChangeListener); + } + } + } + } + }; + private IListChangeListener validationStatusProviderTargetsListener = new class() IListChangeListener { + public void handleListChange(ListChangeEvent event) { + ListDiff diff = event.diff; + ListDiffEntry[] differences = diff.getDifferences(); + for (int i = 0; i < differences.length; i++) { + ListDiffEntry listDiffEntry = differences[i]; + IObservable target = cast(IObservable) listDiffEntry.getElement(); + if (listDiffEntry.isAddition()) { + target.addChangeListener(uiChangeListener); + } else { + target.removeChangeListener(uiChangeListener); + } + } + } + }; + private IStatus currentStatus; + + protected void init() { + aggregateStatus = new AggregateValidationStatus(dbc + .getValidationStatusProviders(), + AggregateValidationStatus.MAX_SEVERITY); + aggregateStatus.addValueChangeListener(new class() IValueChangeListener { + public void handleValueChange(ValueChangeEvent event) { + + currentStatus = cast(IStatus) event.diff.getNewValue(); + handleStatusChanged(); + } + }); + currentStatus = cast(IStatus) aggregateStatus.getValue(); + handleStatusChanged(); + dbc.getValidationStatusProviders().addListChangeListener( + validationStatusProvidersListener); + for (Iterator it = dbc.getValidationStatusProviders().iterator(); it + .hasNext();) { + ValidationStatusProvider validationStatusProvider = cast(ValidationStatusProvider) it + .next(); + IObservableList targets = validationStatusProvider.getTargets(); + targets + .addListChangeListener(validationStatusProviderTargetsListener); + for (Iterator iter = targets.iterator(); iter.hasNext();) { + (cast(IObservable) iter.next()).addChangeListener(uiChangeListener); + } + } + } + + protected void handleUIChanged() { + uiChanged = true; + if (currentStatus !is null) { + handleStatusChanged(); + } + dbc.getValidationStatusProviders().removeListChangeListener( + validationStatusProvidersListener); + for (Iterator it = dbc.getValidationStatusProviders().iterator(); it + .hasNext();) { + ValidationStatusProvider validationStatusProvider = cast(ValidationStatusProvider) it + .next(); + IObservableList targets = validationStatusProvider.getTargets(); + targets + .removeListChangeListener(validationStatusProviderTargetsListener); + for (Iterator iter = targets.iterator(); iter.hasNext();) { + (cast(IObservable) iter.next()) + .removeChangeListener(uiChangeListener); + } + } + } + + protected void handleStatusChanged() { + if (currentStatus !is null + && currentStatus.getSeverity() is IStatus.ERROR) { + wizardPage.setPageComplete(false); + wizardPage.setMessage(null); + wizardPage.setErrorMessage(uiChanged ? currentStatus.getMessage() + : null); + if (currentStatusHasException()) { + handleStatusException(); + } + } else if (currentStatus !is null + && currentStatus.getSeverity() !is IStatus.OK) { + int severity = currentStatus.getSeverity(); + wizardPage.setPageComplete((severity & IStatus.CANCEL) !is 0); + int type; + switch (severity) { + case IStatus.OK: + type = IMessageProvider.NONE; + break; + case IStatus.CANCEL: + type = IMessageProvider.NONE; + break; + case IStatus.INFO: + type = IMessageProvider.INFORMATION; + break; + case IStatus.WARNING: + type = IMessageProvider.WARNING; + break; + case IStatus.ERROR: + type = IMessageProvider.ERROR; + break; + default: + throw new AssertionFailedException( + "incomplete switch statement"); //$NON-NLS-1$ + } + wizardPage.setErrorMessage(null); + wizardPage.setMessage(currentStatus.getMessage(), type); + } else { + wizardPage.setPageComplete(true); + wizardPage.setMessage(null); + wizardPage.setErrorMessage(null); + } + } + + private bool currentStatusHasException() { + bool hasException = false; + if (currentStatus.getException() !is null) { + hasException = true; + } + if (null !is cast(MultiStatus)currentStatus) { + MultiStatus multiStatus = cast(MultiStatus) currentStatus; + + for (int i = 0; i < multiStatus.getChildren().length; i++) { + IStatus status = multiStatus.getChildren()[i]; + if (status.getException() !is null) { + hasException = true; + break; + } + } + } + return hasException; + } + + /** + * This is called when a Override to provide custom exception handling and + * reporting. + */ + protected void handleStatusException() { + if (currentStatus.getException() !is null) { + logThrowable(currentStatus.getException()); + } else if (null !is cast(MultiStatus)currentStatus) { + MultiStatus multiStatus = cast(MultiStatus) currentStatus; + for (int i = 0; i < multiStatus.getChildren().length; i++) { + IStatus status = multiStatus.getChildren()[i]; + if (status.getException() !is null) { + logThrowable(status.getException()); + } + } + } + } + + private void logThrowable(Throwable throwable) { + Policy + .getLog() + .log( + new Status( + IStatus.ERROR, + Policy.JFACE_DATABINDING, + IStatus.OK, + "Unhandled exception: " + throwable.getMessage(), throwable)); //$NON-NLS-1$ + } + + /** + * Disposes of this wizard page support object, removing any listeners it + * may have attached. + */ + public void dispose() { + aggregateStatus.dispose(); + if (!uiChanged) { + for (Iterator it = dbc.getValidationStatusProviders().iterator(); it + .hasNext();) { + ValidationStatusProvider validationStatusProvider = cast(ValidationStatusProvider) it + .next(); + IObservableList targets = validationStatusProvider.getTargets(); + targets + .removeListChangeListener(validationStatusProviderTargetsListener); + for (Iterator iter = targets.iterator(); iter.hasNext();) { + (cast(IObservable) iter.next()) + .removeChangeListener(uiChangeListener); + } + } + dbc.getValidationStatusProviders().removeListChangeListener( + validationStatusProvidersListener); + } + aggregateStatus = null; + dbc = null; + uiChangeListener = null; + validationStatusProvidersListener = null; + validationStatusProviderTargetsListener = null; + wizardPage = null; + } +}