/*! ****************************************************************************** * * Pentaho Data Integration * * Copyright (C) 2002-2017 by Pentaho : http://www.pentaho.com * ******************************************************************************* * * 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.pentaho.di.ui.core.dialog; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; import org.eclipse.swt.custom.CTabFolder; import org.eclipse.swt.custom.CTabItem; import org.eclipse.swt.custom.StackLayout; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; 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.Composite; import org.eclipse.swt.widgets.Dialog; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.TableItem; import org.pentaho.di.ExecutionConfiguration; import org.pentaho.di.base.AbstractMeta; import org.pentaho.di.core.Const; import org.pentaho.di.core.util.Utils; import org.pentaho.di.core.Props; import org.pentaho.di.core.parameters.UnknownParamException; import org.pentaho.di.i18n.BaseMessages; import org.pentaho.di.ui.core.PropsUI; import org.pentaho.di.ui.core.gui.GUIResource; import org.pentaho.di.ui.core.gui.WindowProperty; import org.pentaho.di.ui.core.widget.ColumnInfo; import org.pentaho.di.ui.core.widget.TableView; import org.pentaho.di.ui.util.HelpUtils; public abstract class ConfigurationDialog extends Dialog { protected AbstractMeta abstractMeta; protected ExecutionConfiguration configuration; protected TableView wVariables; protected boolean retval; protected Shell shell; protected PropsUI props; protected Button wExecLocal; protected Button wExecRemote; protected Button wGatherMetrics; protected Label wlLogLevel; protected Group gDetails; protected CCombo wLogLevel; protected Button wSafeMode; protected Button wClearLog; protected Label wlRemoteHost; protected CCombo wRemoteHost; protected Button wPassExport; protected Composite localOptionsComposite; protected Composite serverOptionsComposite; protected Label environmentSeparator; protected StackLayout stackedLayout; protected int margin = Const.MARGIN; protected Group gLocal; protected Composite stackedLayoutComposite; protected Composite composite; private TableView wParams; private Display display; private Shell parent; private Button wOK; private Button wCancel; private FormData fdLocal; protected FormData fdDetails; private FormData fd_tabFolder; private FormData fdExecLocal; private FormData fdExecRemote; private FormData fdComposite; private CTabFolder tabFolder; private Button alwaysShowOption; public ConfigurationDialog( Shell parent, ExecutionConfiguration configuration, AbstractMeta meta ) { super( parent ); this.parent = parent; this.configuration = configuration; this.abstractMeta = meta; // Fill the parameters, maybe do this in another place? Map<String, String> params = configuration.getParams(); params.clear(); String[] paramNames = meta.listParameters(); for ( String name : paramNames ) { params.put( name, "" ); } props = PropsUI.getInstance(); } protected void getInfoVariables() { Map<String, String> map = new HashMap<String, String>(); int nrNonEmptyVariables = wVariables.nrNonEmpty(); for ( int i = 0; i < nrNonEmptyVariables; i++ ) { TableItem tableItem = wVariables.getNonEmpty( i ); String varName = tableItem.getText( 1 ); String varValue = tableItem.getText( 2 ); if ( !Utils.isEmpty( varName ) ) { map.put( varName, varValue ); } } configuration.setVariables( map ); } /** * Get the parameters from the dialog. */ protected void getInfoParameters() { Map<String, String> map = new HashMap<String, String>(); int nrNonEmptyVariables = wParams.nrNonEmpty(); for ( int i = 0; i < nrNonEmptyVariables; i++ ) { TableItem tableItem = wParams.getNonEmpty( i ); String paramName = tableItem.getText( 1 ); String defaultValue = tableItem.getText( 2 ); String paramValue = tableItem.getText( 3 ); if ( Utils.isEmpty( paramValue ) ) { paramValue = Const.NVL( defaultValue, "" ); } map.put( paramName, paramValue ); } configuration.setParams( map ); } protected void ok() { abstractMeta.setAlwaysShowRunOptions( alwaysShowOption.getSelection() ); abstractMeta.setShowDialog( alwaysShowOption.getSelection() ); if ( Const.isOSX() ) { // OSX bug workaround. wVariables.applyOSXChanges(); wParams.applyOSXChanges(); } getInfo(); retval = true; dispose(); } private void dispose() { props.setScreen( new WindowProperty( shell ) ); shell.dispose(); } protected void cancel() { dispose(); } public abstract void getInfo(); protected void getParamsData() { wParams.clearAll( false ); ArrayList<String> paramNames = new ArrayList<String>( configuration.getParams().keySet() ); Collections.sort( paramNames ); for ( int i = 0; i < paramNames.size(); i++ ) { String paramName = paramNames.get( i ); String paramValue = configuration.getParams().get( paramName ); String defaultValue; try { defaultValue = abstractMeta.getParameterDefault( paramName ); } catch ( UnknownParamException e ) { defaultValue = ""; } String description; try { description = abstractMeta.getParameterDescription( paramName ); } catch ( UnknownParamException e ) { description = ""; } TableItem tableItem = new TableItem( wParams.table, SWT.NONE ); tableItem.setText( 1, paramName ); tableItem.setText( 2, Const.NVL( defaultValue, "" ) ); tableItem.setText( 3, Const.NVL( paramValue, "" ) ); tableItem.setText( 4, Const.NVL( description, "" ) ); } wParams.removeEmptyRows(); wParams.setRowNums(); wParams.optWidth( true ); } /** * @param configuration * the configuration to set */ public void setConfiguration( ExecutionConfiguration configuration ) { this.configuration = configuration; } protected void mainLayout( Class<?> PKG, String prefix, Image img ) { display = parent.getDisplay(); shell = new Shell( parent, SWT.DIALOG_TRIM | SWT.MIN | SWT.APPLICATION_MODAL ); props.setLook( shell ); shell.setImage( img ); shell.setLayout( new FormLayout() ); shell.setText( BaseMessages.getString( PKG, prefix + ".Shell.Title" ) ); } protected void optionsSectionLayout( Class<?> PKG, String prefix ) { gDetails = new Group( shell, SWT.SHADOW_ETCHED_IN ); gDetails.setText( BaseMessages.getString( PKG, prefix + ".DetailsGroup.Label" ) ); props.setLook( gDetails ); // The layout gDetails.setLayout( new FormLayout() ); fdDetails = new FormData(); fdDetails.top = new FormAttachment( gLocal, 15 ); fdDetails.right = new FormAttachment( 100, -15 ); fdDetails.left = new FormAttachment( 0, 15 ); gDetails.setBackground( shell.getBackground() ); // the default looks ugly gDetails.setLayoutData( fdDetails ); optionsSectionControls(); } protected void parametersSectionLayout( Class<?> PKG, String prefix ) { tabFolder = new CTabFolder( shell, SWT.BORDER ); props.setLook( tabFolder, Props.WIDGET_STYLE_TAB ); fd_tabFolder = new FormData(); fd_tabFolder.right = new FormAttachment( 100, -15 ); fd_tabFolder.left = new FormAttachment( 0, 15 ); fd_tabFolder.top = new FormAttachment( gDetails, 15 ); fd_tabFolder.bottom = new FormAttachment( gDetails, 370 ); tabFolder.setLayoutData( fd_tabFolder ); // Parameters CTabItem tbtmParameters = new CTabItem( tabFolder, SWT.NONE ); tbtmParameters.setText( BaseMessages.getString( PKG, prefix + ".Params.Label" ) ); Composite parametersComposite = new Composite( tabFolder, SWT.NONE ); props.setLook( parametersComposite ); parametersComposite.setLayout( new FormLayout() ); tbtmParameters.setControl( parametersComposite ); ColumnInfo[] cParams = { new ColumnInfo( BaseMessages.getString( PKG, prefix + ".ParamsColumn.Argument" ), ColumnInfo.COLUMN_TYPE_TEXT, false, true, 126 ), // Stepname new ColumnInfo( BaseMessages.getString( PKG, prefix + ".ParamsColumn.Default" ), ColumnInfo.COLUMN_TYPE_TEXT, false, true, 138 ), // Preview size new ColumnInfo( BaseMessages.getString( PKG, prefix + ".ParamsColumn.Value" ), ColumnInfo.COLUMN_TYPE_TEXT, false, false, 142 ), // Preview size new ColumnInfo( BaseMessages.getString( PKG, prefix + ".ParamsColumn.Description" ), ColumnInfo.COLUMN_TYPE_TEXT, false, true, 181 ), // Preview size }; String[] namedParams = abstractMeta.listParameters(); int nrParams = namedParams.length; wParams = new TableView( abstractMeta, parametersComposite, SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI, cParams, nrParams, false, null, props, false ); FormData fdParams = new FormData(); fdParams.top = new FormAttachment( 0, 10 ); fdParams.right = new FormAttachment( 100, -10 ); fdParams.bottom = new FormAttachment( 100, -45 ); fdParams.left = new FormAttachment( 0, 10 ); wParams.setLayoutData( fdParams ); tabFolder.setSelection( 0 ); Button argsButton = new Button( parametersComposite, SWT.NONE ); FormData fd_argsButton = new FormData(); fd_argsButton.right = new FormAttachment( 100, -10 ); fd_argsButton.top = new FormAttachment( wParams, 6 ); fd_argsButton.bottom = new FormAttachment( 100, -10 ); argsButton.setLayoutData( fd_argsButton ); argsButton.setText( BaseMessages.getString( PKG, prefix + ".Arguments.Label" ) ); argsButton.addSelectionListener( new SelectionAdapter() { public void widgetSelected( SelectionEvent e ) { new ArgumentsDialog( shell, configuration, abstractMeta ); } } ); // Variables CTabItem tbtmVariables = new CTabItem( tabFolder, SWT.NONE ); tbtmVariables.setText( BaseMessages.getString( PKG, prefix + ".Variables.Label" ) ); Composite variablesComposite = new Composite( tabFolder, SWT.NONE ); props.setLook( variablesComposite ); variablesComposite.setLayout( new FormLayout() ); tbtmVariables.setControl( variablesComposite ); ColumnInfo[] cVariables = { new ColumnInfo( BaseMessages.getString( PKG, prefix + ".VariablesColumn.Argument" ), ColumnInfo.COLUMN_TYPE_TEXT, false, false, 287 ), // Stepname new ColumnInfo( BaseMessages.getString( PKG, prefix + ".VariablesColumn.Value" ), ColumnInfo.COLUMN_TYPE_TEXT, false, false, 300 ), // Preview size }; int nrVariables = configuration.getVariables() != null ? configuration.getVariables().size() : 0; wVariables = new TableView( abstractMeta, variablesComposite, SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI, cVariables, nrVariables, false, null, props, false ); FormData fdVariables = new FormData(); fdVariables.top = new FormAttachment( 0, 10 ); fdVariables.right = new FormAttachment( 100, -10 ); fdVariables.bottom = new FormAttachment( 100, -10 ); fdVariables.left = new FormAttachment( 0, 10 ); wVariables.setLayoutData( fdVariables ); } protected void buttonsSectionLayout( Class<?> PKG, String prefix, final String docTitle, final String docUrl, final String docHeader ) { // Bottom buttons and separator alwaysShowOption = new Button( shell, SWT.CHECK ); props.setLook( alwaysShowOption ); alwaysShowOption.setSelection( abstractMeta.isAlwaysShowRunOptions() ); alwaysShowOption.setToolTipText( BaseMessages.getString( PKG, prefix + ".alwaysShowOption" ) ); FormData fd_alwaysShowOption = new FormData(); fd_alwaysShowOption.left = new FormAttachment( 0, 15 ); fd_alwaysShowOption.top = new FormAttachment( tabFolder, 15 ); alwaysShowOption.setLayoutData( fd_alwaysShowOption ); alwaysShowOption.setText( BaseMessages.getString( PKG, prefix + ".AlwaysOption.Value" ) ); wCancel = new Button( shell, SWT.PUSH ); FormData fd_wCancel = new FormData(); fd_wCancel.bottom = new FormAttachment( 100, -15 ); wCancel.setLayoutData( fd_wCancel ); wCancel.setText( BaseMessages.getString( PKG, "System.Button.Cancel" ) ); wCancel.addSelectionListener( new SelectionAdapter() { public void widgetSelected( SelectionEvent e ) { cancel(); } } ); wOK = new Button( shell, SWT.PUSH ); FormData fd_wOK = new FormData(); fd_wOK.top = new FormAttachment( wCancel, 0, SWT.TOP ); fd_wOK.right = new FormAttachment( wCancel, -5 ); fd_wOK.bottom = new FormAttachment( 100, -15 ); wOK.setLayoutData( fd_wOK ); wOK.setText( BaseMessages.getString( PKG, prefix + ".Button.Launch" ) ); wOK.addSelectionListener( new SelectionAdapter() { public void widgetSelected( SelectionEvent e ) { ok(); } } ); Button btnHelp = new Button( shell, SWT.NONE ); btnHelp.setImage( GUIResource.getInstance().getImageHelpWeb() ); btnHelp.setText( BaseMessages.getString( PKG, "System.Button.Help" ) ); btnHelp.setToolTipText( BaseMessages.getString( PKG, "System.Tooltip.Help" ) ); FormData fd_btnHelp = new FormData(); fd_btnHelp.bottom = new FormAttachment( 100, -15 ); fd_btnHelp.left = new FormAttachment( 0, 15 ); btnHelp.setLayoutData( fd_btnHelp ); btnHelp.addSelectionListener( new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent evt ) { HelpUtils.openHelpDialog( parent.getShell(), docTitle, docUrl, docHeader ); } } ); Label separator = new Label( shell, SWT.SEPARATOR | SWT.HORIZONTAL ); if ( Const.isLinux() ) { fd_wCancel.top = new FormAttachment( separator, 10 ); } else { fd_wCancel.top = new FormAttachment( separator, 15 ); } if ( Const.isLinux() ) { fd_btnHelp.top = new FormAttachment( separator, 10 ); } else { fd_btnHelp.top = new FormAttachment( separator, 15 ); } fd_wCancel.right = new FormAttachment( 100, -15 ); FormData fd_separator = new FormData(); fd_separator.right = new FormAttachment( 100, -15 ); fd_separator.left = new FormAttachment( 0, 15 ); fd_separator.top = new FormAttachment( alwaysShowOption, 15 ); separator.setLayoutData( fd_separator ); } protected void openDialog() { shell.pack(); // Set the focus on the OK button wOK.setFocus(); Rectangle shellBounds = getParent().getBounds(); Point dialogSize = shell.getSize(); shell.setLocation( shellBounds.x + ( shellBounds.width - dialogSize.x ) / 2, shellBounds.y + ( shellBounds.height - dialogSize.y ) / 2 ); shell.open(); while ( !shell.isDisposed() ) { if ( !display.readAndDispatch() ) { display.sleep(); } } } protected void environmentTypeSectionLayout( Class<?> PKG, String prefix ) { gLocal = new Group( shell, SWT.SHADOW_ETCHED_IN ); gLocal.setText( BaseMessages.getString( PKG, prefix + ".LocalGroup.Label" ) ); gLocal.setLayout( new FormLayout() ); props.setLook( gLocal ); fdLocal = new FormData(); fdLocal.top = new FormAttachment( 0, 15 ); fdLocal.right = new FormAttachment( 100, -15 ); fdLocal.left = new FormAttachment( 0, 15 ); gLocal.setBackground( shell.getBackground() ); // the default looks ugly gLocal.setLayoutData( fdLocal ); wExecLocal = new Button( gLocal, SWT.RADIO ); wExecLocal.setText( BaseMessages.getString( PKG, prefix + ".ExecLocal.Label" ) ); wExecLocal.setToolTipText( BaseMessages.getString( PKG, prefix + ".ExecLocal.Tooltip" ) ); props.setLook( wExecLocal ); fdExecLocal = new FormData(); fdExecLocal.top = new FormAttachment( 0, 10 ); fdExecLocal.left = new FormAttachment( 0, 10 ); wExecLocal.setLayoutData( fdExecLocal ); wExecLocal.addSelectionListener( new SelectionAdapter() { public void widgetSelected( SelectionEvent e ) { stackedLayout.topControl = localOptionsComposite; stackedLayoutComposite.layout(); } } ); if ( abstractMeta.getSlaveServers() == null || abstractMeta.getSlaveServers().size() == 0 ) { composite = new Composite( gLocal, SWT.NONE ); composite.setLayout( new FormLayout() ); props.setLook( composite ); composite.setToolTipText( BaseMessages.getString( PKG, prefix + ".ExecRemote.DisabledTooltip" ) ); fdComposite = new FormData(); fdComposite.left = new FormAttachment( 0, 10 ); fdComposite.top = new FormAttachment( wExecLocal, 7 ); composite.setLayoutData( fdComposite ); wExecRemote = new Button( composite, SWT.RADIO ); wExecRemote.setText( BaseMessages.getString( PKG, prefix + ".ExecRemote.Label" ) ); props.setLook( wExecRemote ); wExecRemote.setEnabled( false ); fdExecRemote = new FormData(); fdExecRemote.top = new FormAttachment( 0 ); wExecRemote.setLayoutData( fdExecRemote ); } else { wExecRemote = new Button( gLocal, SWT.RADIO ); wExecRemote.setText( BaseMessages.getString( PKG, prefix + ".ExecRemote.Label" ) ); wExecRemote.setToolTipText( BaseMessages.getString( PKG, prefix + ".ExecRemote.Tooltip" ) ); props.setLook( wExecRemote ); fdExecRemote = new FormData(); fdExecRemote.left = new FormAttachment( 0, 10 ); fdExecRemote.top = new FormAttachment( wExecLocal, 7 ); wExecRemote.setLayoutData( fdExecRemote ); wExecRemote.addSelectionListener( new SelectionAdapter() { public void widgetSelected( SelectionEvent e ) { stackedLayout.topControl = serverOptionsComposite; stackedLayoutComposite.layout(); } } ); } // separator environmentSeparator = new Label( gLocal, SWT.SEPARATOR | SWT.VERTICAL ); FormData fd_environmentSeparator = new FormData(); fd_environmentSeparator.top = new FormAttachment( 0, 10 ); fd_environmentSeparator.left = new FormAttachment( wExecLocal, 50 ); fd_environmentSeparator.bottom = new FormAttachment( 100, -10 ); environmentSeparator.setLayoutData( fd_environmentSeparator ); // stacked layout composite stackedLayoutComposite = new Composite( gLocal, SWT.NONE ); props.setLook( stackedLayoutComposite ); stackedLayout = new StackLayout(); stackedLayoutComposite.setLayout( stackedLayout ); FormData fd_stackedLayoutComposite = new FormData(); fd_stackedLayoutComposite.top = new FormAttachment( 0 ); fd_stackedLayoutComposite.left = new FormAttachment( environmentSeparator, 5 ); fd_stackedLayoutComposite.bottom = new FormAttachment( 100, -10 ); fd_stackedLayoutComposite.right = new FormAttachment( 100, -7 ); stackedLayoutComposite.setLayoutData( fd_stackedLayoutComposite ); localOptionsComposite = new Composite( stackedLayoutComposite, SWT.NONE ); localOptionsComposite.setLayout( new FormLayout() ); props.setLook( localOptionsComposite ); serverOptionsComposite = new Composite( stackedLayoutComposite, SWT.NONE ); serverOptionsComposite.setLayout( new FormLayout() ); props.setLook( serverOptionsComposite ); stackedLayout.topControl = localOptionsComposite; localOptionsComposite( PKG, prefix ); serverOptionsComposite( PKG, prefix ); } protected void localOptionsComposite( Class<?> PKG, String prefix ) { Label localDescriptionLabel = new Label( localOptionsComposite, SWT.NONE ); props.setLook( localDescriptionLabel ); localDescriptionLabel.setText( BaseMessages.getString( PKG, prefix + ".LocalHost.Label" ) ); FormData fd_localDescriptionLabel = new FormData(); fd_localDescriptionLabel.left = new FormAttachment( environmentSeparator, 5 ); fd_localDescriptionLabel.top = new FormAttachment( 0, 12 ); if ( Const.isOSX() ) { fd_localDescriptionLabel.top = new FormAttachment( 0, 10 ); } localDescriptionLabel.setLayoutData( fd_localDescriptionLabel ); } protected abstract void serverOptionsComposite( Class<?> PKG, String prefix ); protected abstract void optionsSectionControls(); }