/* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * 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.kie.workbench.common.stunner.bpmn.client.forms.fields.variablesEditor; import java.io.IOException; import javax.annotation.PostConstruct; import javax.enterprise.event.Event; import javax.inject.Inject; import com.google.gwt.event.dom.client.BlurEvent; import com.google.gwt.event.dom.client.BlurHandler; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.event.dom.client.KeyDownHandler; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.text.shared.Renderer; import org.gwtbootstrap3.client.ui.Button; import org.gwtbootstrap3.client.ui.TextBox; import org.gwtbootstrap3.client.ui.ValueListBox; import org.gwtbootstrap3.client.ui.constants.IconType; import org.jboss.errai.databinding.client.api.DataBinder; import org.jboss.errai.ui.shared.api.annotations.AutoBound; import org.jboss.errai.ui.shared.api.annotations.Bound; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.EventHandler; import org.jboss.errai.ui.shared.api.annotations.Templated; import org.kie.workbench.common.stunner.bpmn.client.StunnerSpecific; import org.kie.workbench.common.stunner.bpmn.client.forms.fields.model.Variable.VariableType; import org.kie.workbench.common.stunner.bpmn.client.forms.fields.model.VariableRow; import org.kie.workbench.common.stunner.bpmn.client.forms.util.ListBoxValues; import org.kie.workbench.common.stunner.bpmn.client.forms.widgets.ComboBox; import org.kie.workbench.common.stunner.bpmn.client.forms.widgets.ComboBoxView; import org.kie.workbench.common.stunner.bpmn.client.forms.widgets.VariableNameTextBox; import org.uberfire.workbench.events.NotificationEvent; /** * A templated widget that will be used to display a row in a table of * {@link VariableRow}s. * <p/> * The Name field of VariableRow is Bound, but other fields are not bound because * they use a combination of ListBox and TextBox to implement a drop-down combo * to hold the values. */ @Templated("VariablesEditorWidget.html#variableRow") public class VariableListItemWidgetViewImpl implements VariableListItemWidgetView, ComboBoxView.ModelPresenter { /** * Errai's data binding module will automatically bind the provided instance * of the model (see {@link #setModel(VariableRow)}) to all fields annotated * with {@link Bound}. If not specified otherwise, the bindings occur based on * matching field names (e.g. variableRow.name will automatically be kept in * sync with the data-field "name") */ @Inject @AutoBound protected DataBinder<VariableRow> variableRow; @Inject @Bound @DataField @StunnerSpecific protected VariableNameTextBox name; private boolean allowDuplicateNames = false; private String duplicateNameErrorMessage = "A Variable with this name already exists"; private String currentValue; @DataField protected ValueListBox<String> dataType = new ValueListBox<String>(new Renderer<String>() { public String render(final String object) { String s = ""; if (object != null) { s = object.toString(); } return s; } public void render(final String object, final Appendable appendable) throws IOException { String s = render(object); appendable.append(s); } }); @Inject @DataField protected TextBox customDataType; @Inject protected ComboBox dataTypeComboBox; @Inject protected Event<NotificationEvent> notification; @Inject @DataField protected Button deleteButton; /** * Required for implementation of Delete button. */ private VariablesEditorWidgetView.Presenter parentWidget; public void setParentWidget(final VariablesEditorWidgetView.Presenter parentWidget) { this.parentWidget = parentWidget; } @Override public void setTextBoxModelValue(final TextBox textBox, final String value) { setCustomDataType(value); } @Override public void setListBoxModelValue(final ValueListBox<String> listBox, final String value) { setDataTypeDisplayName(value); } @Override public String getModelValue(final ValueListBox<String> listBox) { String value = getCustomDataType(); if (value == null || value.isEmpty()) { value = getDataTypeDisplayName(); } return value; } @PostConstruct public void init() { // Configure dataType and customDataType controls dataTypeComboBox.init(this, true, dataType, customDataType, false, true, CUSTOM_PROMPT, ENTER_TYPE_PROMPT); name.setRegExp("^[a-zA-Z0-9\\-\\.\\_]*$", "Removed invalid characters from name", "Invalid character in name"); customDataType.addKeyDownHandler(new KeyDownHandler() { @Override public void onKeyDown(final KeyDownEvent event) { int iChar = event.getNativeKeyCode(); if (iChar == ' ') { event.preventDefault(); } } }); name.addBlurHandler(new BlurHandler() { @Override public void onBlur(final BlurEvent event) { if (!allowDuplicateNames) { String value = name.getText(); if (isDuplicateName(value)) { notification.fire(new NotificationEvent(duplicateNameErrorMessage, NotificationEvent.NotificationType.ERROR)); name.setValue(""); ValueChangeEvent.fire(name, ""); } } notifyModelChanged(); } }); } @Override public VariableRow getModel() { return variableRow.getModel(); } @Override public void setModel(final VariableRow model) { variableRow.setModel(model); initVariableControls(); currentValue = getModel().toString(); } @Override public VariableType getVariableType() { return getModel().getVariableType(); } @Override public String getDataTypeDisplayName() { return getModel().getDataTypeDisplayName(); } @Override public void setDataTypeDisplayName(final String dataTypeDisplayName) { getModel().setDataTypeDisplayName(dataTypeDisplayName); } @Override public String getCustomDataType() { return getModel().getCustomDataType(); } @Override public void setCustomDataType(final String customDataType) { getModel().setCustomDataType(customDataType); } @Override public void setDataTypes(final ListBoxValues dataTypeListBoxValues) { dataTypeComboBox.setCurrentTextValue(""); dataTypeComboBox.setListBoxValues(dataTypeListBoxValues); dataTypeComboBox.setShowCustomValues(true); String cdt = getCustomDataType(); if (cdt != null && !cdt.isEmpty()) { dataTypeComboBox.addCustomValueToListBoxValues(cdt, ""); } } @Override public boolean isDuplicateName(final String name) { return parentWidget.isDuplicateName(name); } @EventHandler("deleteButton") public void handleDeleteButton(final ClickEvent e) { parentWidget.removeVariable(getModel()); } /** * Updates the display of this row according to the state of the * corresponding {@link VariableRow}. */ private void initVariableControls() { deleteButton.setIcon(IconType.TRASH); String cdt = getCustomDataType(); if (cdt != null && !cdt.isEmpty()) { customDataType.setValue(cdt); dataType.setValue(cdt); } else if (getDataTypeDisplayName() != null) { dataType.setValue(getDataTypeDisplayName()); } } @Override public void notifyModelChanged() { String oldValue = currentValue; currentValue = getModel().toString(); if (oldValue == null) { if (currentValue != null && currentValue.length() > 0) { parentWidget.notifyModelChanged(); } } else if (!oldValue.equals(currentValue)) { parentWidget.notifyModelChanged(); } } }