/**
* Copyright (c) Red Hat, Inc., contributors and others 2013 - 2014. All rights reserved
*
* Licensed under the Eclipse Public License version 1.0, available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.jboss.tools.forge.ui.internal.ext.control;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.jboss.forge.addon.convert.Converter;
import org.jboss.forge.addon.ui.controller.CommandController;
import org.jboss.forge.addon.ui.hints.InputType;
import org.jboss.forge.addon.ui.input.InputComponent;
import org.jboss.forge.addon.ui.input.UISelectOne;
import org.jboss.forge.addon.ui.util.InputComponents;
import org.jboss.forge.furnace.util.Sets;
import org.jboss.tools.forge.core.furnace.FurnaceService;
import org.jboss.tools.forge.ui.internal.ext.wizards.ForgeWizardPage;
public class ComboControlBuilder extends ControlBuilder<Combo> {
private static final Set<Combo> COMBO_STATUS_CHANGE = Sets.getConcurrentSet();
@Override
public Combo build(final ForgeWizardPage page, final InputComponent<?, ?> input, final String inputName,
final Composite container) {
final CommandController controller = page.getController();
// Create the label
Label label = new Label(container, SWT.NULL);
label.setText(getMnemonicLabel(input, true));
label.setToolTipText(input.getDescription());
final Combo combo = new Combo(container, SWT.BORDER | SWT.DROP_DOWN | SWT.READ_ONLY);
combo.setData(LABEL_DATA_KEY, label);
combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
combo.setToolTipText(input.getDescription());
// skip the third column
Label dummy = new Label(container, SWT.NONE);
dummy.setText("");
updateValues(combo, input);
combo.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
String text = combo.getText();
controller.setValueFor(inputName, text);
}
});
return combo;
}
@Override
public void setEnabled(Combo control, boolean enabled) {
if (enabled != control.isEnabled()) {
control.setEnabled(enabled);
}
}
@Override
protected Class<Object> getProducedType() {
return Object.class;
}
@Override
protected String getSupportedInputType() {
return InputType.DROPDOWN;
}
@Override
protected Class<?>[] getSupportedInputComponentTypes() {
return new Class<?>[] { UISelectOne.class };
}
@Override
public Control[] getModifiableControlsFor(Combo control) {
return new Control[] { control };
}
@Override
public void updateState(Combo combo, InputComponent<?, ?> input) {
if (!COMBO_STATUS_CHANGE.add(combo)) {
return;
}
try {
super.updateState(combo, input);
updateValues(combo, input);
} finally {
COMBO_STATUS_CHANGE.remove(combo);
}
}
private Converter<Object, String> getConverter(UISelectOne<Object> selectOne) {
return InputComponents.getItemLabelConverter(FurnaceService.INSTANCE.getConverterFactory(), selectOne);
}
@SuppressWarnings("unchecked")
private void updateValues(Combo combo, InputComponent<?, ?> input) {
UISelectOne<Object> selectOne = (UISelectOne<Object>) input;
updateValueChoices(combo, selectOne);
updateDefaultValue(combo, selectOne);
}
private void updateDefaultValue(Combo combo, UISelectOne<Object> selectOne) {
Converter<Object, String> converter = getConverter(selectOne);
Object inputValue = InputComponents.getValueFor(selectOne);
String value = inputValue == null ? null : converter.convert(inputValue);
if (value == null) {
combo.setText("");
} else if (!value.equals(combo.getText())) {
combo.setText(value);
}
}
private void updateValueChoices(Combo combo, UISelectOne<Object> selectOne) {
List<String> newItems = new ArrayList<>();
Iterable<Object> valueChoices = selectOne.getValueChoices();
Converter<Object, String> converter = getConverter(selectOne);
if (valueChoices != null) {
for (Object choice : valueChoices) {
String itemLabel = converter.convert(choice);
newItems.add(itemLabel);
}
}
int newSize = newItems.size();
String[] newItemsArray = newItems.toArray(new String[newSize]);
String[] oldItems = combo.getItems();
if (Arrays.equals(newItemsArray, oldItems) == false) {
Object value = selectOne.getValue();
String currentValue = (value == null) ? null : converter.convert(value);
if (!Arrays.asList(newItemsArray).contains(currentValue))
selectOne.setValue(null);
combo.setItems(newItemsArray);
}
}
}