/*******************************************************************************
* Copyright (c) 2015 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.openshift.internal.common.ui.wizard;
import org.apache.commons.lang.StringUtils;
import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.beans.BeanProperties;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.validation.MultiValidator;
import org.eclipse.core.databinding.validation.ValidationStatus;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.databinding.fieldassist.ControlDecorationSupport;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.wizard.IWizard;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.jboss.tools.common.ui.databinding.ValueBindingBuilder;
import org.jboss.tools.openshift.internal.common.ui.databinding.RequiredControlDecorationUpdater;
/**
* A generic page for editing key value pairs (e.g. env vars; labels)
*
* @author jeff.cantrill
*/
public class KeyValueWizardPage<T extends IKeyValueItem> extends AbstractOpenShiftWizardPage {
private IKeyValueWizardModel<T> model;
private String initialKey;
private String initialValue;
public KeyValueWizardPage(IWizard wizard, IKeyValueWizardModel<T> model) {
super(model.getTitle(), model.getDescription(), "", wizard);
this.model = model;
initialKey = model.getKey();
initialValue = model.getValue();
}
@Override
protected void doCreateControls(Composite parent, DataBindingContext dbc) {
GridLayoutFactory.fillDefaults()
.margins(10, 10).applyTo(parent);
Group group = new Group(parent, SWT.NONE);
group.setText(model.getGroupLabel());
group.setLayout(new GridLayout());
GridDataFactory.fillDefaults().hint(550, SWT.DEFAULT)
.align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(group);
Composite composite = new Composite(group, SWT.NONE);
GridDataFactory.fillDefaults()
.align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(composite);
GridLayoutFactory.fillDefaults()
.numColumns(4).margins(25, 25).applyTo(composite);
Label nameLabel = new Label(composite, SWT.NONE);
nameLabel.setText(model.getKeyLabel()+":");
if(model.getKeyDescription() != null) {
nameLabel.setToolTipText(model.getKeyDescription());
}
GridDataFactory.fillDefaults()
.align(SWT.LEFT, SWT.CENTER).applyTo(nameLabel);
Text nameText = new Text(composite, SWT.BORDER);
nameText.setEditable(model.isKeyEditable());
IObservableValue keyModel = BeanProperties.value(IKeyValueWizardModel.PROPERTY_KEY).observe(model);
IObservableValue keyTextObservable = WidgetProperties.text(SWT.Modify).observe(nameText);
GridDataFactory.fillDefaults()
.align(SWT.FILL, SWT.CENTER).grab(true, false).span(3, 1).applyTo(nameText);
Binding nameBinding = ValueBindingBuilder
.bind(keyTextObservable)
.validatingAfterConvert(model.getKeyAfterConvertValidator())
.to(keyModel)
.in(dbc);
ControlDecorationSupport.create(
nameBinding, SWT.LEFT | SWT.TOP, null, new RequiredControlDecorationUpdater());
Label valueLabel = new Label(composite, SWT.NONE);
valueLabel.setText(model.getValueLabel()+":");
if(model.getValueDescription() != null) {
valueLabel.setToolTipText(model.getValueDescription());
}
GridDataFactory.fillDefaults()
.align(SWT.LEFT, SWT.CENTER).applyTo(valueLabel);
Text valueText = new Text(composite, SWT.BORDER);
GridDataFactory.fillDefaults()
.align(SWT.FILL, SWT.CENTER).grab(true, false).span(3, 1).applyTo(valueText);
IObservableValue valueModel = BeanProperties.value(IKeyValueWizardModel.PROPERTY_VALUE).observe(model);
IObservableValue valueTextObservable = WidgetProperties.text(SWT.Modify).observe(valueText);
Binding valeuBinding = ValueBindingBuilder
.bind(valueTextObservable)
.validatingAfterConvert(model.getValueAfterConvertValidator())
.to(valueModel)
.in(dbc);
ControlDecorationSupport.create(
valeuBinding, SWT.LEFT | SWT.TOP, null, new RequiredControlDecorationUpdater());
if(initialKey != null && !initialKey.isEmpty()) {
DataChangedValidator validator = new DataChangedValidator(keyTextObservable, valueTextObservable);
dbc.addValidationStatusProvider(validator);
}
if(!model.isKeyEditable() || nameText.getText().length() > 0) {
valueText.forceFocus(); //if name is set, it is more important to modify value.
if(!StringUtils.isEmpty(valueText.getText())) {
valueText.setSelection(0, valueText.getText().length());
}
}
}
class DataChangedValidator extends MultiValidator {
IObservableValue keyTextObservable;
IObservableValue valueTextObservable;
public DataChangedValidator(IObservableValue keyTextObservable, IObservableValue valueTextObservable) {
this.keyTextObservable = keyTextObservable;
this.valueTextObservable = valueTextObservable;
}
@Override
protected IStatus validate() {
String key = (String)keyTextObservable.getValue();
String value = (String)valueTextObservable.getValue();
if(initialKey != null && initialKey.equals(key)
&& initialValue != null && initialValue.equals(value)) {
return ValidationStatus.cancel("Provide new values.");
}
return ValidationStatus.ok();
}
}
}