package org.ovirt.engine.ui.common.widget.form; import org.ovirt.engine.ui.common.CommonApplicationConstants; import org.ovirt.engine.ui.common.gin.AssetProvider; import org.ovirt.engine.ui.common.widget.label.StringValueLabel; import org.ovirt.engine.ui.uicompat.external.StringUtils; import com.google.gwt.user.client.ui.HasText; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; /** * Represents a name/value item rendered within an {@link AbstractFormPanel}. */ public class FormItem { /** * If {@link #showDefaultValue} returns {@code true}, show the default value, otherwise show the actual value. */ public interface DefaultValueCondition { boolean showDefaultValue(); } private static final CommonApplicationConstants constants = AssetProvider.getConstants(); private static final int UNASSIGNED_ROW = -1; private AbstractFormPanel formPanel; private int row; private final int column; private final String isAvailablePropertyName; private boolean isAvailable = true; private String name; private Widget valueWidget; /** * Replaces provided value widget if {@code defaultValueCondition} holds {@code true}. */ private StringValueLabel defaultValueLabel; private DefaultValueCondition defaultValueCondition; /** * Replaces resolved value widget if the widget's text is {@code null} or empty string. */ private final StringValueLabel emptyValueLabel = new StringValueLabel(constants.unAvailablePropertyLabel()); private boolean autoPlacement = false; private int autoPlacementRow = UNASSIGNED_ROW; public FormItem(int row, int column) { this("", new StringValueLabel(), row, column); //$NON-NLS-1$ } public FormItem(String name, IsWidget valueWidget, int column) { this(name, valueWidget, 0 , column, null, true); withAutoPlacement(); } public FormItem(String name, IsWidget valueWidget, int column, boolean isAvailable) { this(name, valueWidget, 0 , column, null, isAvailable); withAutoPlacement(); } public FormItem(String name, IsWidget valueWidget, int row, int column) { this(name, valueWidget, row, column, null); } public FormItem(String name, IsWidget valueWidget, int row, int column, boolean isAvailable) { this(name, valueWidget, row, column, null, isAvailable); } public FormItem(String name, IsWidget valueWidget, int row, int column, String isAvailablePropertyName) { this(name, valueWidget, row, column, isAvailablePropertyName, true); } public FormItem(String name, IsWidget valueWidget, int row, int column, String isAvailablePropertyName, boolean isAvailable) { this.row = row; this.column = column; this.isAvailablePropertyName = isAvailablePropertyName; this.valueWidget = valueWidget.asWidget(); this.isAvailable = isAvailable; // Add trailing ':' to the item name, if necessary if (name != null && !name.trim().isEmpty() && !name.endsWith(":")) { //$NON-NLS-1$ this.name = name + ":"; //$NON-NLS-1$ } else { this.name = name; } } /** * Use {@code defaultValue} based on dynamic {@code defaultValueCondition}. */ public FormItem withDefaultValue(String defaultValue, DefaultValueCondition defaultValueCondition) { this.defaultValueLabel = new StringValueLabel(defaultValue); this.defaultValueCondition = defaultValueCondition; return this; } /** * Set custom "empty" value shown when the resolved value widget's text is {@code null} or empty string. */ public FormItem withEmptyValue(String emptyValue) { emptyValueLabel.setValue(emptyValue); return this; } /** * Automatically place this form item into next available row for the given column. * <p> * This works only when the form item is {@linkplain #getIsAvailable available} when being added to the * {@link AbstractFormPanel}. Otherwise, the form item is marked as dead and will be discarded by the form panel. * * @see #setFormPanel(AbstractFormPanel) */ public FormItem withAutoPlacement() { this.autoPlacement = true; return this; } public void setFormPanel(AbstractFormPanel formPanel) { this.formPanel = formPanel; // Compute autoPlacementRow if this item is available if (autoPlacement && getIsAvailable()) { this.autoPlacementRow = formPanel.getNextAvailableRow(column); } } /** * If {@code false}, this form item shouldn't be processed by the {@link AbstractFormPanel}. */ public boolean isValid() { if (autoPlacement && autoPlacementRow == UNASSIGNED_ROW) { // Failed to assign autoPlacementRow return false; } return true; } public void update() { assert formPanel != null : "FormItem must be adopted by FormPanel"; //$NON-NLS-1$ formPanel.updateFormItem(this); } public int getRow() { return (autoPlacement && autoPlacementRow != UNASSIGNED_ROW) ? autoPlacementRow : row; } public int getColumn() { return column; } public String getIsAvailablePropertyName() { return isAvailablePropertyName; } public boolean getIsAvailable() { return isAvailable; } public void setIsAvailable(boolean isAvailable) { this.isAvailable = isAvailable; update(); } public String getName() { return name; } /** * Resolves the appropriate value widget for this form item based on {@link DefaultValueCondition} (if any). */ public Widget resolveValueWidget() { boolean showDefaultValue = defaultValueCondition != null && defaultValueCondition.showDefaultValue(); Widget resolvedValueWidget = showDefaultValue ? defaultValueLabel : valueWidget; boolean showEmptyValue = (resolvedValueWidget instanceof HasText) && StringUtils.isEmpty(((HasText) resolvedValueWidget).getText()); return showEmptyValue ? emptyValueLabel : resolvedValueWidget; } }