/*******************************************************************************
* Copyright (c) 2011 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is 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:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.jboss.tools.common.ui.databinding;
import org.eclipse.core.databinding.AggregateValidationStatus;
import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.ValidationStatusProvider;
import org.eclipse.core.databinding.beans.BeanProperties;
import org.eclipse.core.databinding.observable.IObservableCollection;
import org.eclipse.core.databinding.observable.list.WritableList;
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.fieldassist.ControlDecorationSupport;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Text;
import org.jboss.tools.common.ui.CommonUIMessages;
/**
* @author André Dietisheim
*/
public class DataBindingUtils {
/**
* Binds the enabled status of the given button to the validity status of
* the given providers. If those are not provided the validation status of
* the whole context is used.
*
* @param button
* the button whose enablement is bound
* @param validationStatusProviders
* the providers that shall toggle the button enablement
* @param dbc
* the data binding context to use when binding
*/
public static void bindEnablementToValidationStatus(final Control control,
DataBindingContext dbc, Binding... bindings) {
bindEnablementToValidationStatus(control, IStatus.OK, dbc, bindings);
}
public static void bindEnablementToValidationStatus(final Control control, int enabledSeverityMask,
DataBindingContext dbc, Binding... bindings) {
dbc.bindValue(
WidgetProperties.enabled().observe(control),
createAggregateValidationStatus(dbc, bindings),
new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER),
new UpdateValueStrategy().setConverter(new StatusSeverity2BooleanConverter(enabledSeverityMask)));
}
/**
* Creates an aggregated validation status for the given providers and
* databinding context. If no providers are given the whole context is used
* a provider.
*
* @param validationStatusProviders
* to use
* @param dbc
* the data binding context to use
* @return
*/
protected static AggregateValidationStatus createAggregateValidationStatus(
DataBindingContext dbc, Binding... bindings) {
AggregateValidationStatus aggregatedValidationStatus;
if (bindings.length == 0) {
aggregatedValidationStatus =
new AggregateValidationStatus(
dbc, AggregateValidationStatus.MAX_SEVERITY);
} else {
aggregatedValidationStatus =
new AggregateValidationStatus(
toObservableCollection(bindings),
AggregateValidationStatus.MAX_SEVERITY);
}
return aggregatedValidationStatus;
}
/**
* Returns an observable collection for a given array of validation status
* providers.
*
* @param observableValue
* the array of observable values
* @return an observable collection
*/
private static IObservableCollection toObservableCollection(ValidationStatusProvider... validationStatusProviders) {
WritableList observableCollection = new WritableList();
for (ValidationStatusProvider validationStatusProvider : validationStatusProviders) {
observableCollection.add(validationStatusProvider);
}
return observableCollection;
}
/**
* Binds the given text field with the given name to the given model
* property. A validator, that wont validate if there's no content in the
* text field is attached.
*
* @param text
* the text field to bind
* @param fieldName
* the name of the text field
* @param modelProperty
* the property of the model to bind to
* @param model
* the model to bind to
* @param dbc
* the data binding context to use
* @return
*/
public static Binding bindMandatoryTextField(Text text, String fieldName, String modelProperty,
Object model, DataBindingContext dbc) {
Binding binding = dbc.bindValue(
WidgetProperties.text(SWT.Modify).observe(text),
BeanProperties.value(modelProperty).observe(model),
new UpdateValueStrategy().setAfterGetValidator(
new MandatoryStringValidator(NLS.bind(
CommonUIMessages.MANDATORYSTRING_VALIDATOR_MUST_PROVIDE_VALUE, fieldName))),
null);
ControlDecorationSupport.create(binding, SWT.LEFT | SWT.TOP);
return binding;
}
/**
* Observe and print validation state changes. Utility method to ease bug
* tracking.
*
* @param label the label to use when printing validation state changes
* @param dbc the databinding context to observe for validation changes
*/
public static void observeAndPrintValidationState(final String label, DataBindingContext dbc) {
AggregateValidationStatus status = new AggregateValidationStatus(dbc, AggregateValidationStatus.MAX_SEVERITY);
status.addValueChangeListener(new IValueChangeListener() {
@Override
public void handleValueChange(ValueChangeEvent event) {
System.err.println("========================");
System.err.println(label);
System.err.println("------------------------");
System.err.println(event.diff.getNewValue());
System.err.println("========================");
}
});
}
/**
* Observe and print validation state changes. Utility method to ease bug
* tracking in wizards.
*
* @param label the label to use when printing validation state changes
* @param dbc the databinding context to observe for validation changes
* @param wizardPage the wizard page whose databinding context shall get observed
*/
public static void observeAndPrintValidationState(IWizardPage wizardPage, DataBindingContext dbc) {
observeAndPrintValidationState(wizardPage.getName(), dbc);
}
/**
* Adds the given value change listener to the given observable and removes
* it once the given control is disposed.
*
* @param listener
* the listener that shall be added
* @param observable
* the observable that the listener shall be attached to
* @param control
* the control that triggers removal once it's disposed
*/
public static void addDisposableValueChangeListener(
final IValueChangeListener listener, final IObservableValue observable, Control control) {
Assert.isLegal(listener != null);
Assert.isLegal(observable != null);
Assert.isLegal(control != null);
if (control.isDisposed()) {
return;
}
observable.addValueChangeListener(listener);
control.addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
observable.removeValueChangeListener(listener);
}
});
}
}