### Eclipse Workspace Patch 1.0 #P org.eclipse.jface.databinding Index: src/org/eclipse/jface/databinding/wizard/WizardPageSupport.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/wizard/WizardPageSupport.java,v retrieving revision 1.5 diff -u -r1.5 WizardPageSupport.java --- src/org/eclipse/jface/databinding/wizard/WizardPageSupport.java 15 May 2008 23:19:43 -0000 1.5 +++ src/org/eclipse/jface/databinding/wizard/WizardPageSupport.java 7 Jul 2008 22:36:39 -0000 @@ -13,27 +13,9 @@ *******************************************************************************/ package org.eclipse.jface.databinding.wizard; -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.databinding.dialog.DialogPageSupport; import org.eclipse.jface.wizard.WizardPage; /** @@ -42,15 +24,13 @@ * 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 boolean uiChanged = false; +public class WizardPageSupport extends DialogPageSupport { + private WizardPageSupport(WizardPage wizardPage, DataBindingContext dbc) { + super(wizardPage, dbc); + } /** * Connect the validation result from the given data binding context to the @@ -71,229 +51,15 @@ return new WizardPageSupport(wizardPage, dbc); } - private WizardPageSupport(WizardPage wizardPage, DataBindingContext dbc) { - this.wizardPage = wizardPage; - this.dbc = dbc; - init(); - } - - private IChangeListener uiChangeListener = new IChangeListener() { - public void handleChange(ChangeEvent event) { - handleUIChanged(); - } - }; - private IListChangeListener validationStatusProvidersListener = new 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 = (ValidationStatusProvider) listDiffEntry - .getElement(); - IObservableList targets = validationStatusProvider.getTargets(); - if (listDiffEntry.isAddition()) { - targets - .addListChangeListener(validationStatusProviderTargetsListener); - for (Iterator it = targets.iterator(); it.hasNext();) { - ((IObservable) it.next()) - .addChangeListener(uiChangeListener); - } - } else { - targets - .removeListChangeListener(validationStatusProviderTargetsListener); - for (Iterator it = targets.iterator(); it.hasNext();) { - ((IObservable) it.next()) - .removeChangeListener(uiChangeListener); - } - } - } - } - }; - private IListChangeListener validationStatusProviderTargetsListener = new 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 = (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 IValueChangeListener() { - public void handleValueChange(ValueChangeEvent event) { - - currentStatus = (IStatus) event.diff.getNewValue(); - handleStatusChanged(); - } - }); - currentStatus = (IStatus) aggregateStatus.getValue(); - handleStatusChanged(); - dbc.getValidationStatusProviders().addListChangeListener( - validationStatusProvidersListener); - for (Iterator it = dbc.getValidationStatusProviders().iterator(); it - .hasNext();) { - ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it - .next(); - IObservableList targets = validationStatusProvider.getTargets(); - targets - .addListChangeListener(validationStatusProviderTargetsListener); - for (Iterator iter = targets.iterator(); iter.hasNext();) { - ((IObservable) iter.next()).addChangeListener(uiChangeListener); - } - } - } - - protected void handleUIChanged() { - uiChanged = true; - if (currentStatus != null) { - handleStatusChanged(); - } - dbc.getValidationStatusProviders().removeListChangeListener( - validationStatusProvidersListener); - for (Iterator it = dbc.getValidationStatusProviders().iterator(); it - .hasNext();) { - ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it - .next(); - IObservableList targets = validationStatusProvider.getTargets(); - targets - .removeListChangeListener(validationStatusProviderTargetsListener); - for (Iterator iter = targets.iterator(); iter.hasNext();) { - ((IObservable) iter.next()) - .removeChangeListener(uiChangeListener); - } - } - } - protected void handleStatusChanged() { - if (currentStatus != null - && currentStatus.getSeverity() == IStatus.ERROR) { - wizardPage.setPageComplete(false); - wizardPage.setMessage(null); - wizardPage.setErrorMessage(uiChanged ? currentStatus.getMessage() - : null); - if (currentStatusHasException()) { - handleStatusException(); - } - } else if (currentStatus != null - && currentStatus.getSeverity() != IStatus.OK) { - int severity = currentStatus.getSeverity(); - wizardPage.setPageComplete((severity & IStatus.CANCEL) != 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 boolean currentStatusHasException() { - boolean hasException = false; - if (currentStatus.getException() != null) { - hasException = true; - } - if (currentStatus instanceof MultiStatus) { - MultiStatus multiStatus = (MultiStatus) currentStatus; - - for (int i = 0; i < multiStatus.getChildren().length; i++) { - IStatus status = multiStatus.getChildren()[i]; - if (status.getException() != 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() != null) { - logThrowable(currentStatus.getException()); - } else if (currentStatus instanceof MultiStatus) { - MultiStatus multiStatus = (MultiStatus) currentStatus; - for (int i = 0; i < multiStatus.getChildren().length; i++) { - IStatus status = multiStatus.getChildren()[i]; - if (status.getException() != 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 = (ValidationStatusProvider) it - .next(); - IObservableList targets = validationStatusProvider.getTargets(); - targets - .removeListChangeListener(validationStatusProviderTargetsListener); - for (Iterator iter = targets.iterator(); iter.hasNext();) { - ((IObservable) iter.next()) - .removeChangeListener(uiChangeListener); - } - } - dbc.getValidationStatusProviders().removeListChangeListener( - validationStatusProvidersListener); + super.handleStatusChanged(); + boolean pageComplete = true; + if (currentStatus != null) { + if (currentStatus.getSeverity() == IStatus.ERROR) + pageComplete = false; + if ((currentStatus.getSeverity() & IStatus.CANCEL) != 0) + pageComplete = false; } - aggregateStatus = null; - dbc = null; - uiChangeListener = null; - validationStatusProvidersListener = null; - validationStatusProviderTargetsListener = null; - wizardPage = null; + ((WizardPage) getDialogPage()).setPageComplete(pageComplete); } } Index: src/org/eclipse/jface/databinding/dialog/DialogPageSupport.java =================================================================== RCS file: src/org/eclipse/jface/databinding/dialog/DialogPageSupport.java diff -N src/org/eclipse/jface/databinding/dialog/DialogPageSupport.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/jface/databinding/dialog/DialogPageSupport.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,294 @@ +/******************************************************************************* + * Copyright (c) 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 + ******************************************************************************/ + +package org.eclipse.jface.databinding.dialog; + +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.IObservableValue; +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.DialogPage; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.wizard.WizardPage; + +/** + * @since 3.3 + * + */ +public class DialogPageSupport { + private DialogPage dialogPage; + private DataBindingContext dbc; + private IObservableValue aggregateStatus; + private boolean uiChanged = false; + private IChangeListener uiChangeListener = new IChangeListener() { + public void handleChange(ChangeEvent event) { + handleUIChanged(); + } + }; + private IListChangeListener validationStatusProvidersListener = new 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 = (ValidationStatusProvider) listDiffEntry + .getElement(); + IObservableList targets = validationStatusProvider.getTargets(); + if (listDiffEntry.isAddition()) { + targets + .addListChangeListener(validationStatusProviderTargetsListener); + for (Iterator it = targets.iterator(); it.hasNext();) { + ((IObservable) it.next()) + .addChangeListener(uiChangeListener); + } + } else { + targets + .removeListChangeListener(validationStatusProviderTargetsListener); + for (Iterator it = targets.iterator(); it.hasNext();) { + ((IObservable) it.next()) + .removeChangeListener(uiChangeListener); + } + } + } + } + }; + private IListChangeListener validationStatusProviderTargetsListener = new 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 = (IObservable) listDiffEntry.getElement(); + if (listDiffEntry.isAddition()) { + target.addChangeListener(uiChangeListener); + } else { + target.removeChangeListener(uiChangeListener); + } + } + } + }; + protected IStatus currentStatus; + + protected DialogPageSupport(DialogPage dialogPage, DataBindingContext dbc) { + this.dialogPage = dialogPage; + this.dbc = dbc; + init(); + } + + /** + * 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(boolean)} 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 DialogPageSupport create(DialogPage wizardPage, + DataBindingContext dbc) { + return new DialogPageSupport(wizardPage, dbc); + } + + protected DialogPage getDialogPage() { + return dialogPage; + } + + protected void init() { + aggregateStatus = new AggregateValidationStatus(dbc + .getValidationStatusProviders(), + AggregateValidationStatus.MAX_SEVERITY); + aggregateStatus.addValueChangeListener(new IValueChangeListener() { + public void handleValueChange(ValueChangeEvent event) { + + currentStatus = (IStatus) event.diff.getNewValue(); + handleStatusChanged(); + } + }); + currentStatus = (IStatus) aggregateStatus.getValue(); + handleStatusChanged(); + dbc.getValidationStatusProviders().addListChangeListener( + validationStatusProvidersListener); + for (Iterator it = dbc.getValidationStatusProviders().iterator(); it + .hasNext();) { + ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it + .next(); + IObservableList targets = validationStatusProvider.getTargets(); + targets + .addListChangeListener(validationStatusProviderTargetsListener); + for (Iterator iter = targets.iterator(); iter.hasNext();) { + ((IObservable) iter.next()).addChangeListener(uiChangeListener); + } + } + } + + protected void handleUIChanged() { + uiChanged = true; + if (currentStatus != null) { + handleStatusChanged(); + } + dbc.getValidationStatusProviders().removeListChangeListener( + validationStatusProvidersListener); + for (Iterator it = dbc.getValidationStatusProviders().iterator(); it + .hasNext();) { + ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it + .next(); + IObservableList targets = validationStatusProvider.getTargets(); + targets + .removeListChangeListener(validationStatusProviderTargetsListener); + for (Iterator iter = targets.iterator(); iter.hasNext();) { + ((IObservable) iter.next()) + .removeChangeListener(uiChangeListener); + } + } + } + + protected void handleStatusChanged() { + if (currentStatus != null + && currentStatus.getSeverity() == IStatus.ERROR) { + dialogPage.setMessage(null); + dialogPage.setErrorMessage(uiChanged ? currentStatus.getMessage() + : null); + if (currentStatusHasException()) { + handleStatusException(); + } + } else if (currentStatus != null + && currentStatus.getSeverity() != IStatus.OK) { + int severity = currentStatus.getSeverity(); + 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$ + } + dialogPage.setErrorMessage(null); + dialogPage.setMessage(currentStatus.getMessage(), type); + } else { + dialogPage.setMessage(null); + dialogPage.setErrorMessage(null); + } + } + + private boolean currentStatusHasException() { + boolean hasException = false; + if (currentStatus.getException() != null) { + hasException = true; + } + if (currentStatus instanceof MultiStatus) { + MultiStatus multiStatus = (MultiStatus) currentStatus; + + for (int i = 0; i < multiStatus.getChildren().length; i++) { + IStatus status = multiStatus.getChildren()[i]; + if (status.getException() != 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() != null) { + logThrowable(currentStatus.getException()); + } else if (currentStatus instanceof MultiStatus) { + MultiStatus multiStatus = (MultiStatus) currentStatus; + for (int i = 0; i < multiStatus.getChildren().length; i++) { + IStatus status = multiStatus.getChildren()[i]; + if (status.getException() != 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 = (ValidationStatusProvider) it + .next(); + IObservableList targets = validationStatusProvider.getTargets(); + targets + .removeListChangeListener(validationStatusProviderTargetsListener); + for (Iterator iter = targets.iterator(); iter.hasNext();) { + ((IObservable) iter.next()) + .removeChangeListener(uiChangeListener); + } + } + dbc.getValidationStatusProviders().removeListChangeListener( + validationStatusProvidersListener); + } + aggregateStatus = null; + dbc = null; + uiChangeListener = null; + validationStatusProvidersListener = null; + validationStatusProviderTargetsListener = null; + dialogPage = null; + } + +} Index: src/org/eclipse/jface/databinding/dialog/TitleAreaDialogSupport.java =================================================================== RCS file: src/org/eclipse/jface/databinding/dialog/TitleAreaDialogSupport.java diff -N src/org/eclipse/jface/databinding/dialog/TitleAreaDialogSupport.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/jface/databinding/dialog/TitleAreaDialogSupport.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,293 @@ +/******************************************************************************* + * Copyright (c) 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 + ******************************************************************************/ + +package org.eclipse.jface.databinding.dialog; + +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.IObservableValue; +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.dialogs.TitleAreaDialog; +import org.eclipse.jface.wizard.WizardPage; + +/** + * @since 3.3 + * + */ +public class TitleAreaDialogSupport { + private TitleAreaDialog dialog; + private DataBindingContext dbc; + private IObservableValue aggregateStatus; + private boolean uiChanged = false; + private IChangeListener uiChangeListener = new IChangeListener() { + public void handleChange(ChangeEvent event) { + handleUIChanged(); + } + }; + private IListChangeListener validationStatusProvidersListener = new 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 = (ValidationStatusProvider) listDiffEntry + .getElement(); + IObservableList targets = validationStatusProvider.getTargets(); + if (listDiffEntry.isAddition()) { + targets + .addListChangeListener(validationStatusProviderTargetsListener); + for (Iterator it = targets.iterator(); it.hasNext();) { + ((IObservable) it.next()) + .addChangeListener(uiChangeListener); + } + } else { + targets + .removeListChangeListener(validationStatusProviderTargetsListener); + for (Iterator it = targets.iterator(); it.hasNext();) { + ((IObservable) it.next()) + .removeChangeListener(uiChangeListener); + } + } + } + } + }; + private IListChangeListener validationStatusProviderTargetsListener = new 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 = (IObservable) listDiffEntry.getElement(); + if (listDiffEntry.isAddition()) { + target.addChangeListener(uiChangeListener); + } else { + target.removeChangeListener(uiChangeListener); + } + } + } + }; + protected IStatus currentStatus; + + protected TitleAreaDialogSupport(TitleAreaDialog dialogPage, + DataBindingContext dbc) { + this.dialog = dialogPage; + this.dbc = dbc; + init(); + } + + /** + * 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(boolean)} 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 TitleAreaDialogSupport create(TitleAreaDialog wizardPage, + DataBindingContext dbc) { + return new TitleAreaDialogSupport(wizardPage, dbc); + } + + protected void init() { + aggregateStatus = new AggregateValidationStatus(dbc + .getValidationStatusProviders(), + AggregateValidationStatus.MAX_SEVERITY); + aggregateStatus.addValueChangeListener(new IValueChangeListener() { + public void handleValueChange(ValueChangeEvent event) { + + currentStatus = (IStatus) event.diff.getNewValue(); + handleStatusChanged(); + } + }); + currentStatus = (IStatus) aggregateStatus.getValue(); + handleStatusChanged(); + dbc.getValidationStatusProviders().addListChangeListener( + validationStatusProvidersListener); + for (Iterator it = dbc.getValidationStatusProviders().iterator(); it + .hasNext();) { + ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it + .next(); + IObservableList targets = validationStatusProvider.getTargets(); + targets + .addListChangeListener(validationStatusProviderTargetsListener); + for (Iterator iter = targets.iterator(); iter.hasNext();) { + ((IObservable) iter.next()).addChangeListener(uiChangeListener); + } + } + } + + protected void handleUIChanged() { + uiChanged = true; + if (currentStatus != null) { + handleStatusChanged(); + } + dbc.getValidationStatusProviders().removeListChangeListener( + validationStatusProvidersListener); + for (Iterator it = dbc.getValidationStatusProviders().iterator(); it + .hasNext();) { + ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it + .next(); + IObservableList targets = validationStatusProvider.getTargets(); + targets + .removeListChangeListener(validationStatusProviderTargetsListener); + for (Iterator iter = targets.iterator(); iter.hasNext();) { + ((IObservable) iter.next()) + .removeChangeListener(uiChangeListener); + } + } + } + + protected void handleStatusChanged() { + if (dialog.getShell() == null || dialog.getShell().isDisposed()) + return; + if (currentStatus != null + && currentStatus.getSeverity() == IStatus.ERROR) { + dialog.setMessage(null); + dialog.setErrorMessage(uiChanged ? currentStatus.getMessage() + : null); + if (currentStatusHasException()) { + handleStatusException(); + } + } else if (currentStatus != null + && currentStatus.getSeverity() != IStatus.OK) { + int severity = currentStatus.getSeverity(); + 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$ + } + dialog.setErrorMessage(null); + dialog.setMessage(currentStatus.getMessage(), type); + } else { + dialog.setMessage(null); + dialog.setErrorMessage(null); + } + } + + private boolean currentStatusHasException() { + boolean hasException = false; + if (currentStatus.getException() != null) { + hasException = true; + } + if (currentStatus instanceof MultiStatus) { + MultiStatus multiStatus = (MultiStatus) currentStatus; + + for (int i = 0; i < multiStatus.getChildren().length; i++) { + IStatus status = multiStatus.getChildren()[i]; + if (status.getException() != 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() != null) { + logThrowable(currentStatus.getException()); + } else if (currentStatus instanceof MultiStatus) { + MultiStatus multiStatus = (MultiStatus) currentStatus; + for (int i = 0; i < multiStatus.getChildren().length; i++) { + IStatus status = multiStatus.getChildren()[i]; + if (status.getException() != 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 = (ValidationStatusProvider) it + .next(); + IObservableList targets = validationStatusProvider.getTargets(); + targets + .removeListChangeListener(validationStatusProviderTargetsListener); + for (Iterator iter = targets.iterator(); iter.hasNext();) { + ((IObservable) iter.next()) + .removeChangeListener(uiChangeListener); + } + } + dbc.getValidationStatusProviders().removeListChangeListener( + validationStatusProvidersListener); + } + aggregateStatus = null; + dbc = null; + uiChangeListener = null; + validationStatusProvidersListener = null; + validationStatusProviderTargetsListener = null; + dialog = null; + } + +} Index: src/org/eclipse/jface/databinding/preference/PreferencePageSupport.java =================================================================== RCS file: src/org/eclipse/jface/databinding/preference/PreferencePageSupport.java diff -N src/org/eclipse/jface/databinding/preference/PreferencePageSupport.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/jface/databinding/preference/PreferencePageSupport.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,69 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.jface.databinding.preference; + +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jface.databinding.dialog.DialogPageSupport; +import org.eclipse.jface.preference.PreferencePage; + +/** + * Connects the validation result from the given data binding context to the + * given preference page, updating the preference page's valid state and its + * error message accordingly. + * + * @noextend This class is not intended to be subclassed by clients. + * + * @since 1.1 + */ +public class PreferencePageSupport extends DialogPageSupport { + private PreferencePage preferencePage; + + private PreferencePageSupport(PreferencePage preferencePage, + DataBindingContext dbc) { + super(preferencePage, dbc); + this.preferencePage = preferencePage; + } + + /** + * Connect the validation result from the given data binding context to the + * given preference page. Upon creation, the preference page support will + * use the context's validation result to determine whether the page is + * valid. The page's error message will not be set at this time ensuring + * that the preference page does not show an error right away. Upon any + * validation result change, {@link PreferencePage#setValid(boolean)} will + * be called reflecting the new validation result, and the preference page's + * error message will be updated according to the current validation result. + * + * @param preferencePage + * @param dbc + * @return an instance of PreferencePageSupport + */ + public static PreferencePageSupport create(PreferencePage preferencePage, + DataBindingContext dbc) { + return new PreferencePageSupport(preferencePage, dbc); + } + + protected void handleStatusChanged() { + super.handleStatusChanged(); + boolean valid = true; + if (currentStatus != null) { + if (currentStatus.getSeverity() == IStatus.ERROR) + valid = false; + if ((currentStatus.getSeverity() & IStatus.CANCEL) != 0) + valid = false; + } + preferencePage.setValid(valid); + } +}