/** * 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); } } }