/*******************************************************************************
* Copyright (c) 2016 Bruno Medeiros and other Contributors.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Bruno Medeiros - initial API and implementation
*******************************************************************************/
package melnorme.lang.ide.ui.build;
import org.eclipse.debug.ui.StringVariableSelectionDialog;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import melnorme.lang.ide.core.operations.build.VariablesResolver;
import melnorme.lang.ide.ui.fields.FieldDialog;
import melnorme.lang.ide.ui.utils.ControlUtils;
import melnorme.lang.tooling.commands.CommandInvocation;
import melnorme.lang.tooling.commands.EnvironmentSettings;
import melnorme.util.swt.components.ButtonWidget;
import melnorme.util.swt.components.CompositeWidget;
import melnorme.util.swt.components.fields.EnablementCompositeWidget;
import melnorme.util.swt.components.fields.SetFieldValueOperation;
import melnorme.util.swt.components.fields.TextFieldWidget;
import melnorme.utilbox.concurrency.OperationCancellation;
import melnorme.utilbox.core.CommonException;
import melnorme.utilbox.core.fntypes.CommonGetter;
import melnorme.utilbox.fields.Field;
import melnorme.utilbox.fields.validation.ValidationSource;
import melnorme.utilbox.status.StatusException;
public class CommandInvocationEditor extends EnablementCompositeWidget<CommandInvocation> {
protected final Field<CommandInvocation> commandInvocation;
protected final CommonGetter<CommandInvocation> getDefaultArguments;
protected final VariablesResolver variablesResolver;
protected final TextFieldWidget commandArgumentsField;
public CommandInvocationEditor(CommonGetter<CommandInvocation> getDefaultCommandInvocation,
VariablesResolver variablesResolver) {
super("Command Invocation:", LABEL_UseDefault);
this.createInlined = false;
this.commandInvocation = field();
this.getDefaultArguments = getDefaultCommandInvocation;
this.variablesResolver = variablesResolver;
commandArgumentsField = init_createButtonTextField();
addChildWidget(commandArgumentsField);
commandArgumentsField.addChangeListener(this::updateCommandInvocationField);
commandArgumentsField.validation().addFieldValidation2(commandArgumentsField,
ValidationSource.fromRunnable(this::validateArguments));
commandArgumentsField.onlyValidateWhenEnabled = false;
createButtonArea();
commandInvocation.addChangeListener(this::updateWidgetFromInput);
}
public TextFieldWidget getCommandArgumentsWidget() {
return commandArgumentsField;
}
@Override
protected void doUpdateWidgetFromInput() {
CommandInvocation commandInvocation = this.commandInvocation.get();
if(commandInvocation == null) {
commandArgumentsField.set("");
return; // Ignore
}
commandArgumentsField.set(commandInvocation.getCommandLine());
}
protected void updateCommandInvocationField() {
CommandInvocation current = commandInvocation.get();
if(current == null) {
return;
}
commandInvocation.set(new CommandInvocation(
commandArgumentsField.get(),
current.getEnvironmentVars(),
current.isAppendEnvironment()
));
}
@Override
protected CommandInvocation getDefaultFieldValue() throws CommonException {
return getDefaultArguments.get();
}
/* ----------------- controls & layout ----------------- */
protected void createButtonArea() {
ButtonWidget environmentVarButton = new ButtonWidget("Edit Environment variables...",
this::handleEditEnvironmentVars);
ButtonWidget variablesDialogButton = new ButtonWidget("Insert/Edit Substitution Variables...",
new SetFieldValueOperation<String>(commandArgumentsField, this::newValueFromCommandVariablesDialog));
CompositeWidget buttonArea = addChildWidget(new CompositeWidget(false) {
{ layoutColumns = 2; }
@Override
protected void createContents(Composite topControl) {
super.createContents(topControl);
GridData layoutData = (GridData) variablesDialogButton.getButton().getLayoutData();
layoutData.grabExcessHorizontalSpace = true;
layoutData.horizontalAlignment = GridData.END;
}
});
buttonArea.addChildWidget(environmentVarButton);
buttonArea.addChildWidget(variablesDialogButton);
}
protected TextFieldWidget init_createButtonTextField() {
TextFieldWidget buttonTextField = new TextFieldWidget(null) {
@Override
protected void createContents_layout() {
text.setLayoutData(gdGrabAll(40, 100));
}
};
buttonTextField.setMultiLineStyle();
return buttonTextField;
}
/* ----------------- ----------------- */
protected void validateArguments() throws StatusException {
validateArguments(field());
}
protected void validateArguments(Field<CommandInvocation> field) throws StatusException {
CommandInvocation fieldValue = field.get();
if(fieldValue == null) {
return;
}
fieldValue.evaluateCommandArguments(variablesResolver);
}
/* ----------------- button handlers ----------------- */
protected String newValueFromCommandVariablesDialog() throws OperationCancellation {
StringVariableSelectionDialog variablesDialog = new StringVariableSelectionDialog(
commandArgumentsField.getFieldControl().getShell());
variablesDialog.setElements(variablesResolver.getVariables());
String addedVar = ControlUtils.openStringVariableSelectionDialog(variablesDialog);
return commandArgumentsField.getFieldValue() + addedVar;
}
protected void handleEditEnvironmentVars() {
Shell shell = getCommandArgumentsWidget().getFieldControl().getShell();
CommandInvocation cmd = getFieldValue();
EnvironmentSettings envSettings = new EnvironmentSettings(
cmd.getEnvironmentVars().copyToHashMap(), cmd.isAppendEnvironment());
try {
envSettings = new FieldDialog<>(shell, new EnvironmentSettingsEditor()).openDialog(envSettings);
} catch(OperationCancellation e) {
return;
}
setFieldValue(new CommandInvocation(
cmd.getCommandLine(),
envSettings.envVars.copy(),
envSettings.appendEnv
));
}
}