blob: 7b37bc0609fdb2bd175bc2d30005b694c1a031c7 [file] [log] [blame]
/*
* 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;
}
}