| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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.apache.hop.ui.core.dialog; |
| |
| import org.apache.hop.core.Const; |
| import org.apache.hop.core.exception.HopValueException; |
| import org.apache.hop.core.row.IValueMeta; |
| import org.apache.hop.core.row.ValueMetaAndData; |
| import org.apache.hop.core.row.value.ValueMetaFactory; |
| import org.apache.hop.core.row.value.ValueMetaString; |
| import org.apache.hop.core.util.Utils; |
| import org.apache.hop.i18n.BaseMessages; |
| import org.apache.hop.ui.core.PropsUi; |
| import org.apache.hop.ui.core.gui.GuiResource; |
| import org.apache.hop.ui.core.gui.WindowProperty; |
| import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.custom.CCombo; |
| import org.eclipse.swt.events.FocusEvent; |
| import org.eclipse.swt.events.FocusListener; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.layout.FormAttachment; |
| import org.eclipse.swt.layout.FormData; |
| import org.eclipse.swt.layout.FormLayout; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Dialog; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.swt.widgets.Text; |
| |
| /** Dialog to enter a Hop Value */ |
| public class EnterValueDialog extends Dialog { |
| private static final Class<?> PKG = EnterValueDialog.class; // For Translator |
| |
| private CCombo wValueType; |
| |
| private Text wInputString; |
| |
| private CCombo wFormat; |
| |
| private Text wLength; |
| |
| private Text wPrecision; |
| |
| private Shell shell; |
| |
| private PropsUi props; |
| |
| private ValueMetaAndData valueMetaAndData; |
| |
| private IValueMeta valueMeta; |
| |
| private Object valueData; |
| |
| private boolean modalDialog; |
| |
| public EnterValueDialog(Shell parent, int style, IValueMeta value, Object data) { |
| super(parent, style); |
| this.props = PropsUi.getInstance(); |
| this.valueMeta = value; |
| this.valueData = data; |
| } |
| |
| public ValueMetaAndData open() { |
| Shell parent = getParent(); |
| shell = |
| new Shell( |
| parent, |
| SWT.DIALOG_TRIM |
| | SWT.RESIZE |
| | (modalDialog ? SWT.APPLICATION_MODAL | SWT.SHEET : SWT.NONE)); |
| PropsUi.setLook(shell); |
| shell.setImage(GuiResource.getInstance().getImageHopUi()); |
| |
| FormLayout formLayout = new FormLayout(); |
| formLayout.marginWidth = PropsUi.getFormMargin(); |
| formLayout.marginHeight = PropsUi.getFormMargin(); |
| |
| shell.setLayout(formLayout); |
| shell.setText(BaseMessages.getString(PKG, "EnterValueDialog.Title")); |
| |
| int middle = props.getMiddlePct(); |
| int margin = props.getMargin(); |
| |
| // Type of value |
| /* |
| * Type of Value: String, Number, Date, Boolean, Integer |
| */ |
| Label wlValueType = new Label(shell, SWT.RIGHT); |
| wlValueType.setText(BaseMessages.getString(PKG, "EnterValueDialog.Type.Label")); |
| PropsUi.setLook(wlValueType); |
| FormData fdlValueType = new FormData(); |
| fdlValueType.left = new FormAttachment(0, 0); |
| fdlValueType.right = new FormAttachment(middle, -margin); |
| fdlValueType.top = new FormAttachment(0, margin); |
| wlValueType.setLayoutData(fdlValueType); |
| wValueType = new CCombo(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER | SWT.READ_ONLY); |
| wValueType.setItems(ValueMetaFactory.getValueMetaNames()); |
| PropsUi.setLook(wValueType); |
| FormData fdValueType = new FormData(); |
| fdValueType.left = new FormAttachment(middle, 0); |
| fdValueType.top = new FormAttachment(0, margin); |
| fdValueType.right = new FormAttachment(100, -margin); |
| wValueType.setLayoutData(fdValueType); |
| wValueType.addModifyListener(arg0 -> setFormats()); |
| |
| // Value line |
| Label wlInputString = new Label(shell, SWT.RIGHT); |
| wlInputString.setText(BaseMessages.getString(PKG, "EnterValueDialog.Value.Label")); |
| PropsUi.setLook(wlInputString); |
| FormData fdlInputString = new FormData(); |
| fdlInputString.left = new FormAttachment(0, 0); |
| fdlInputString.right = new FormAttachment(middle, -margin); |
| fdlInputString.top = new FormAttachment(wValueType, margin); |
| wlInputString.setLayoutData(fdlInputString); |
| wInputString = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER); |
| PropsUi.setLook(wInputString); |
| FormData fdInputString = new FormData(); |
| fdInputString.left = new FormAttachment(middle, 0); |
| fdInputString.top = new FormAttachment(wValueType, margin); |
| fdInputString.right = new FormAttachment(100, -margin); |
| wInputString.setLayoutData(fdInputString); |
| |
| // Format mask |
| Label wlFormat = new Label(shell, SWT.RIGHT); |
| wlFormat.setText(BaseMessages.getString(PKG, "EnterValueDialog.ConversionFormat.Label")); |
| PropsUi.setLook(wlFormat); |
| FormData fdlFormat = new FormData(); |
| fdlFormat.left = new FormAttachment(0, 0); |
| fdlFormat.right = new FormAttachment(middle, -margin); |
| fdlFormat.top = new FormAttachment(wInputString, margin); |
| wlFormat.setLayoutData(fdlFormat); |
| wFormat = new CCombo(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER); |
| PropsUi.setLook(wFormat); |
| FormData fdFormat = new FormData(); |
| fdFormat.left = new FormAttachment(middle, 0); |
| fdFormat.right = new FormAttachment(100, -margin); |
| fdFormat.top = new FormAttachment(wInputString, margin); |
| wFormat.setLayoutData(fdFormat); |
| |
| // Length line |
| Label wlLength = new Label(shell, SWT.RIGHT); |
| wlLength.setText(BaseMessages.getString(PKG, "EnterValueDialog.Length.Label")); |
| PropsUi.setLook(wlLength); |
| FormData fdlLength = new FormData(); |
| fdlLength.left = new FormAttachment(0, 0); |
| fdlLength.right = new FormAttachment(middle, -margin); |
| fdlLength.top = new FormAttachment(wFormat, margin); |
| wlLength.setLayoutData(fdlLength); |
| wLength = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER); |
| PropsUi.setLook(wLength); |
| FormData fdLength = new FormData(); |
| fdLength.left = new FormAttachment(middle, 0); |
| fdLength.right = new FormAttachment(100, -margin); |
| fdLength.top = new FormAttachment(wFormat, margin); |
| wLength.setLayoutData(fdLength); |
| |
| // Precision line |
| Label wlPrecision = new Label(shell, SWT.RIGHT); |
| wlPrecision.setText(BaseMessages.getString(PKG, "EnterValueDialog.Precision.Label")); |
| PropsUi.setLook(wlPrecision); |
| FormData fdlPrecision = new FormData(); |
| fdlPrecision.left = new FormAttachment(0, 0); |
| fdlPrecision.right = new FormAttachment(middle, -margin); |
| fdlPrecision.top = new FormAttachment(wLength, margin); |
| wlPrecision.setLayoutData(fdlPrecision); |
| wPrecision = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER); |
| PropsUi.setLook(wPrecision); |
| FormData fdPrecision = new FormData(); |
| fdPrecision.left = new FormAttachment(middle, 0); |
| fdPrecision.right = new FormAttachment(100, -margin); |
| fdPrecision.top = new FormAttachment(wLength, margin); |
| wPrecision.setLayoutData(fdPrecision); |
| |
| // Some buttons |
| Button wOk = new Button(shell, SWT.PUSH); |
| wOk.setText(BaseMessages.getString(PKG, "System.Button.OK")); |
| Button wTest = new Button(shell, SWT.PUSH); |
| wTest.setText(BaseMessages.getString(PKG, "System.Button.Test")); |
| Button wCancel = new Button(shell, SWT.PUSH); |
| wCancel.setText(BaseMessages.getString(PKG, "System.Button.Cancel")); |
| |
| BaseTransformDialog.positionBottomButtons( |
| shell, new Button[] {wOk, wTest, wCancel}, margin, wPrecision); |
| |
| // Add listeners |
| wCancel.addListener(SWT.Selection, e -> cancel()); |
| wOk.addListener(SWT.Selection, e -> ok()); |
| wTest.addListener(SWT.Selection, e -> test()); |
| |
| // If the user changes data type or if we type a text, we set the default mask for the type |
| // We also set the list of possible masks in the wFormat |
| // |
| wInputString.addFocusListener( |
| new FocusListener() { |
| @Override |
| public void focusGained(FocusEvent focusEvent) {} |
| |
| @Override |
| public void focusLost(FocusEvent focusEvent) { |
| setFormats(); |
| } |
| }); |
| |
| wValueType.addSelectionListener( |
| new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent event) { |
| setFormats(); |
| } |
| }); |
| |
| getData(); |
| |
| BaseDialog.defaultShellHandling(shell, c -> ok(), c -> cancel()); |
| |
| return valueMetaAndData; |
| } |
| |
| protected void setFormats() { |
| // What is the selected type? |
| // |
| // The index must be set on the combobox after |
| // calling setItems(), otherwise the zeroth element |
| // is displayed, but the selectedIndex will be -1. |
| |
| int formatIndex = wFormat.getSelectionIndex(); |
| String formatString = formatIndex >= 0 ? wFormat.getItem(formatIndex) : ""; |
| int type = ValueMetaFactory.getIdForValueMeta(wValueType.getText()); |
| String string = wInputString.getText(); |
| |
| // remove white spaces if not a string field |
| if ((type != IValueMeta.TYPE_STRING) && (string.startsWith(" ") || string.endsWith(" "))) { |
| string = Const.trim(string); |
| wInputString.setText(string); |
| } |
| switch (type) { |
| case IValueMeta.TYPE_INTEGER: |
| wFormat.setItems(Const.getNumberFormats()); |
| int index = |
| (!Utils.isEmpty(formatString)) ? wFormat.indexOf(formatString) : wFormat.indexOf("#"); |
| // ... then we have a custom format mask |
| if ((!Utils.isEmpty(formatString)) && (index < 0)) { |
| wFormat.add(formatString); |
| index = wFormat.indexOf(formatString); |
| } |
| wFormat.select(index); // default |
| break; |
| case IValueMeta.TYPE_NUMBER: |
| wFormat.setItems(Const.getNumberFormats()); |
| index = |
| (!Utils.isEmpty(formatString)) ? wFormat.indexOf(formatString) : wFormat.indexOf("#.#"); |
| // ... then we have a custom format mask |
| if ((!Utils.isEmpty(formatString)) && (index < 0)) { |
| wFormat.add(formatString); |
| index = wFormat.indexOf(formatString); |
| } |
| wFormat.select(index); // default |
| break; |
| case IValueMeta.TYPE_DATE: |
| wFormat.setItems(Const.getDateFormats()); |
| index = |
| (!Utils.isEmpty(formatString)) |
| ? wFormat.indexOf(formatString) |
| : wFormat.indexOf("yyyy/MM/dd HH:mm:ss"); // default |
| // ... then we have a custom format mask |
| if ((!Utils.isEmpty(formatString)) && (index < 0)) { |
| wFormat.add(formatString); |
| index = wFormat.indexOf(formatString); |
| } |
| wFormat.select(index); // default |
| break; |
| case IValueMeta.TYPE_BIGNUMBER: |
| wFormat.setItems(new String[] {}); |
| break; |
| default: |
| wFormat.setItems(new String[] {}); |
| break; |
| } |
| } |
| |
| public void dispose() { |
| shell.dispose(); |
| } |
| |
| public void getData() { |
| wValueType.setText(valueMeta.getTypeDesc()); |
| try { |
| if (valueData != null) { |
| String value = valueMeta.getString(valueData); |
| if (value != null) { |
| wInputString.setText(value); |
| } |
| } |
| } catch (HopValueException e) { |
| wInputString.setText(valueMeta.toString()); |
| } |
| setFormats(); |
| |
| int index = -1; |
| // If there is a custom conversion mask set, |
| // we need to add that mask to the combo box |
| if (!Utils.isEmpty(valueMeta.getConversionMask())) { |
| index = wFormat.indexOf(valueMeta.getConversionMask()); |
| if (index < 0) { |
| wFormat.add(valueMeta.getConversionMask()); |
| index = wFormat.indexOf(valueMeta.getConversionMask()); |
| } |
| } |
| if (index >= 0) { |
| wFormat.select(index); |
| } |
| |
| wLength.setText(Integer.toString(valueMeta.getLength())); |
| wPrecision.setText(Integer.toString(valueMeta.getPrecision())); |
| |
| setFormats(); |
| |
| wInputString.setFocus(); |
| wInputString.selectAll(); |
| } |
| |
| private void cancel() { |
| props.setScreen(new WindowProperty(shell)); |
| valueMeta = null; |
| dispose(); |
| } |
| |
| private ValueMetaAndData getValue(String valuename) throws HopValueException { |
| try { |
| int valtype = ValueMetaFactory.getIdForValueMeta(wValueType.getText()); |
| ValueMetaAndData val = new ValueMetaAndData(valuename, wInputString.getText()); |
| |
| IValueMeta valueMeta = ValueMetaFactory.cloneValueMeta(val.getValueMeta(), valtype); |
| Object valueData = val.getValueData(); |
| |
| int formatIndex = wFormat.getSelectionIndex(); |
| valueMeta.setConversionMask( |
| formatIndex >= 0 ? wFormat.getItem(formatIndex) : wFormat.getText()); |
| valueMeta.setLength(Const.toInt(wLength.getText(), -1)); |
| valueMeta.setPrecision(Const.toInt(wPrecision.getText(), -1)); |
| val.setValueMeta(valueMeta); |
| |
| IValueMeta stringValueMeta = new ValueMetaString(valuename); |
| stringValueMeta.setConversionMetadata(valueMeta); |
| |
| Object targetData = stringValueMeta.convertDataUsingConversionMetaData(valueData); |
| val.setValueData(targetData); |
| |
| return val; |
| } catch (Exception e) { |
| throw new HopValueException(e); |
| } |
| } |
| |
| private void ok() { |
| try { |
| valueMetaAndData = getValue(valueMeta.getName()); // Keep the same name... |
| dispose(); |
| } catch (HopValueException e) { |
| new ErrorDialog(shell, "Error", "There was a conversion error: ", e); |
| } |
| } |
| |
| /** Test the entered value */ |
| public void test() { |
| try { |
| ValueMetaAndData v = getValue(valueMeta.getName()); |
| MessageBox mb = new MessageBox(shell, SWT.OK | SWT.ICON_INFORMATION); |
| |
| StringBuilder result = new StringBuilder(); |
| result.append(Const.CR).append(Const.CR).append(" ").append(v.toString()); |
| result.append(Const.CR).append(" ").append(v.toStringMeta()); |
| |
| mb.setMessage( |
| BaseMessages.getString(PKG, "EnterValueDialog.TestResult.Message", result.toString())); |
| mb.setText(BaseMessages.getString(PKG, "EnterValueDialog.TestResult.Title")); |
| mb.open(); |
| } catch (HopValueException e) { |
| new ErrorDialog(shell, "Error", "There was an error during data type conversion: ", e); |
| } |
| } |
| |
| /** |
| * @return the modalDialog |
| */ |
| public boolean isModalDialog() { |
| return modalDialog; |
| } |
| |
| /** |
| * @param modalDialog the modalDialog to set |
| */ |
| public void setModalDialog(boolean modalDialog) { |
| this.modalDialog = modalDialog; |
| } |
| } |