/* * Copyright 2014-2015 CyberVision, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.kaaproject.avro.ui.gwt.client.widget; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.kaaproject.avro.ui.gwt.client.AvroUiResources.AvroUiStyle; import org.kaaproject.avro.ui.gwt.client.widget.nav.NavigationContainer; import org.kaaproject.avro.ui.shared.FormField; import org.kaaproject.avro.ui.shared.FormField.ValueChangeListener; import org.kaaproject.avro.ui.shared.UnionField; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.text.shared.Renderer; import com.google.gwt.user.client.ui.FlexTable; import com.google.gwt.user.client.ui.ListBox; import com.google.gwt.user.client.ui.Widget; import com.google.gwt.view.client.ProvidesKey; public class UnionFieldWidget extends AbstractFieldWidget<UnionField> implements ValueChangeHandler<FormField> { private List<HandlerRegistration> recordTableRegistrations = new ArrayList<HandlerRegistration>(); private FieldWidgetPanel fieldWidgetPanel; private FlexTable recordTable; public UnionFieldWidget(AvroWidgetsConfig config, NavigationContainer container, boolean readOnly) { super(config, container, readOnly); } public UnionFieldWidget(AvroWidgetsConfig config, AvroUiStyle style, NavigationContainer container, boolean readOnly) { super(config, style, container, readOnly); } @Override protected Widget constructForm() { fieldWidgetPanel = new FieldWidgetPanel(style, value, readOnly, value.getValue() != null); if (value.isOverride() && !readOnly && !value.isReadOnly()) { registrations.add(fieldWidgetPanel.addValueChangeHandler(new ValueChangeHandler<Boolean>() { @Override public void onValueChange(ValueChangeEvent<Boolean> event) { fireChanged(); } })); } recordTable = new FlexTable(); fieldWidgetPanel.setWidth(config.getUnionPanelWidth()); fieldWidgetPanel.setContent(recordTable); boolean isReadOnly = readOnly || value.isReadOnly(); final FormValuesListBox formValuesBox = new FormValuesListBox(style, isReadOnly ? null : value.getDisplayPrompt()); formValuesBox.setEnabled(!isReadOnly); fieldWidgetPanel.setLegendWidget(formValuesBox); value.finalizeMetadata(); if (!isReadOnly) { registrations.add(formValuesBox.addValueChangeHandler(this)); if (!value.isOptional()) { formValuesBox.setValue(value.getValue()); } formValuesBox.setAcceptableValues(value.getAcceptableValues()); if (value.isOptional()) { formValuesBox.setValue(value.getValue()); } } else { formValuesBox.setValue(value.getValue()); } final ValueChangeListener listener = new ValueChangeListener() { private static final long serialVersionUID = 1L; @Override public void onValueChanged (Object value) { FormField field = null; if (value != null) { field = (FormField)value; } formValuesBox.setValue(field); updateForm(); }; }; value.addTransientValueChangeListener(listener); registrations.add(new HandlerRegistration() { @Override public void removeHandler() { value.removeTransientValueChangeListener(listener); } }); recordTable.getColumnFormatter().setWidth(0, config.getLabelsColumnWidth()); recordTable.getColumnFormatter().setWidth(1, config.getFieldsColumnWidth()); constructFormData(recordTable, value.getValue(), recordTableRegistrations); return fieldWidgetPanel; } @Override public void updateConfig(AvroWidgetsConfig config) { super.updateConfig(config); if (fieldWidgetPanel != null) { fieldWidgetPanel.setWidth(config.getUnionPanelWidth()); } if (recordTable != null) { recordTable.getColumnFormatter().setWidth(0, config.getLabelsColumnWidth()); recordTable.getColumnFormatter().setWidth(1, config.getFieldsColumnWidth()); } } public void setOpen(boolean open) { if (value != null && !value.isOverride()) { boolean isOpen = value.getValue() == null ? false : open; fieldWidgetPanel.setOpen(isOpen, false); } } @Override public void onValueChange(ValueChangeEvent<FormField> event) { FormField formField = event.getValue(); if (formField != null) { formField = formField.clone(); formField.finalizeMetadata(); } value.setValue(formField); updateForm(); } private void updateForm() { clearRecordTableRegistrations(); if (value.getValue() == null) { recordTable.clear(); } else { constructFormData(recordTable, value.getValue(), recordTableRegistrations); } fieldWidgetPanel.setValue(true, false, true); fireChanged(); } @Override protected void onUnload() { //clearRecordTableRegistrations(); super.onUnload(); } private void clearRecordTableRegistrations() { for (HandlerRegistration registration : recordTableRegistrations) { registration.removeHandler(); } recordTableRegistrations.clear(); } static class FormValuesListBox extends ExtendedValueListBox<FormField> { public FormValuesListBox(AvroUiStyle style, String promptText) { super(new FormFieldRenderer(), new FormFieldKeyProvider(), style, promptText); } public ListBox getListBox() { return (ListBox) getWidget(); } } static class FormFieldKeyProvider implements ProvidesKey<FormField> { @Override public Object getKey(FormField item) { return item != null ? item.getFieldName() : null; } } static class FormFieldRenderer implements Renderer<FormField> { @Override public String render(FormField object) { return object != null ? object.getDisplayName() : ""; } @Override public void render(FormField object, Appendable appendable) throws IOException { appendable.append(render(object)); } } }