/*
* Copyright (C) 2006-2016 DLR, Germany
*
* All rights reserved
*
* http://www.rcenvironment.de/
*/
package de.rcenvironment.core.gui.wizards.toolintegration;
import java.io.File;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import de.rcenvironment.core.component.integration.ToolIntegrationConstants;
import de.rcenvironment.core.gui.resources.api.ImageManager;
import de.rcenvironment.core.gui.resources.api.StandardImages;
import de.rcenvironment.core.utils.common.StringUtils;
/**
* A dialog for inserting a copy command in pre/post script.
*
* @author Sascha Zur
*/
public class WizardInsertCopyCommandDialog extends Dialog {
private static final String REQUIRED = " (required)";
private static final String FILE = "File";
private static final String SLASH = "/";
private static final String DIRECTORY_PREFIX = "Directory: ";
private static final String INPUT_PREFIX = "Input ";
private static final String TARGET_STRING = "*TARGET*";
private static final String SOURCE_STRING = "*SOURCE*";
private static final String SHUTIL_COPYTREE_STRING = StringUtils
.format("shutil.copytree(\"%s\", \"%s\")", SOURCE_STRING, TARGET_STRING);
private static final String SHUTIL_COPY_STRING = StringUtils.format("shutil.copy(\"%s\", \"%s\")", SOURCE_STRING, TARGET_STRING);
private static final int SOURCE = 0;
private static final int TARGET = 1;
private Button fileToFileButton;
private Button dirButton;
private String command;
private final List<String> inputs;
private final String[] directories;
private Button fileToDirButton;
private Button[] predefOptionButtons;
private Button[] customOptionButtons;
private Combo[] predefCombos;
private Text[] predefTexts;
private Text[] customTexts;
private Button[] customChooseButtons;
private Label previewCommandLabel;
private Label[] slashLabel;
private CLabel validationLabel;
public WizardInsertCopyCommandDialog(Shell parentShell, List<String> endpointNames, String[] directories) {
super(parentShell);
this.inputs = endpointNames;
this.directories = directories;
setShellStyle(SWT.CLOSE | SWT.MAX | SWT.TITLE | SWT.BORDER | SWT.RESIZE
| getDefaultOrientation());
}
@Override
protected void configureShell(Shell shell) {
super.configureShell(shell);
shell.setText(Messages.copyDialogShellText);
command = SHUTIL_COPY_STRING;
}
@Override
protected Control createDialogArea(Composite parent) {
Composite container = (Composite) super.createDialogArea(parent);
container.setLayout(new GridLayout(1, false));
GridData g = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL);
container.setLayoutData(g);
Composite typeContainer = new Composite(container, SWT.NONE);
typeContainer.setLayout(new GridLayout(5, false));
Label sourceType = new Label(typeContainer, SWT.NONE);
sourceType.setText(Messages.copy);
GridData labelData = new GridData();
labelData.horizontalSpan = 1;
sourceType.setLayoutData(labelData);
fileToFileButton = new Button(typeContainer, SWT.RADIO);
fileToFileButton.setText(Messages.copyFileToFile);
GridData fileData = new GridData();
fileToFileButton.setLayoutData(fileData);
fileToFileButton.setSelection(true);
fileToDirButton = new Button(typeContainer, SWT.RADIO);
fileToDirButton.setText(Messages.copyFileToDir);
GridData fileToDirData = new GridData();
fileToDirButton.setLayoutData(fileToDirData);
dirButton = new Button(typeContainer, SWT.RADIO);
dirButton.setText(Messages.copyDirToDir);
GridData dirData = new GridData();
dirData.horizontalSpan = 2;
dirButton.setLayoutData(dirData);
predefOptionButtons = new Button[2];
customOptionButtons = new Button[2];
predefCombos = new Combo[2];
predefTexts = new Text[2];
slashLabel = new Label[2];
customTexts = new Text[2];
customChooseButtons = new Button[2];
Label separator = new Label(container, SWT.HORIZONTAL | SWT.SEPARATOR);
separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
buildUpElements(SOURCE, container);
Label separator3 = new Label(container, SWT.HORIZONTAL | SWT.SEPARATOR);
separator3.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
separator3.setVisible(false);
buildUpElements(TARGET, container);
Label separator2 = new Label(container, SWT.HORIZONTAL | SWT.SEPARATOR);
separator2.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
Label previewLabel = new Label(container, SWT.NONE);
previewLabel.setText(Messages.insertCommand);
previewCommandLabel = new Label(container, SWT.NONE);
previewCommandLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL));
validationLabel = new CLabel(container, SWT.NONE);
validationLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL));
validationLabel.setVisible(false);
validationLabel.setImage(ImageManager.getInstance().getSharedImage(StandardImages.ERROR_16));
return container;
}
private Text buildUpElements(int type, Composite container) {
Label label = new Label(container, SWT.NONE);
if (type == 0) {
label.setText(Messages.source);
} else {
label.setText(Messages.target);
}
GridData data = new GridData();
label.setLayoutData(data);
Composite composite = new Composite(container, SWT.NONE);
composite.setLayout(new GridLayout(5, false));
GridData compData = new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL);
compData.horizontalIndent = 10;
composite.setLayoutData(compData);
Button predefPathButton = new Button(composite, SWT.RADIO);
predefPathButton.setText(Messages.predefinedPath);
GridData pathButtonData = new GridData();
pathButtonData.horizontalSpan = 5;
predefPathButton.setLayoutData(pathButtonData);
predefPathButton.setSelection(true);
predefOptionButtons[type] = predefPathButton;
Combo combo = new Combo(composite, SWT.READ_ONLY);
GridData comboData = new GridData();
fillCombo(combo, type);
combo.setLayoutData(comboData);
predefCombos[type] = combo;
Label slash = new Label(composite, SWT.NONE);
slash.setText(SLASH);
GridData slashData = new GridData();
slashData.widthHint = 5;
slash.setLayoutData(slashData);
slashLabel[type] = slash;
Text predefText = new Text(composite, SWT.BORDER);
GridData predefTextData = new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL);
predefTextData.horizontalSpan = 3;
predefText.setLayoutData(predefTextData);
predefText.setMessage(Messages.subfolderOrFilename);
predefTexts[type] = predefText;
Button customPathButton = new Button(composite, SWT.RADIO);
customPathButton.setText(Messages.customPath);
GridData customButtonData = new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL);
customButtonData.horizontalSpan = 5;
customPathButton.setLayoutData(customButtonData);
customOptionButtons[type] = customPathButton;
Text text = new Text(composite, SWT.BORDER);
GridData sourceTextData = new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL);
sourceTextData.horizontalSpan = 4;
text.setLayoutData(sourceTextData);
text.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent arg0) {
updateSelectionAndValidateInput();
}
});
customTexts[type] = text;
Button selectionButton = new Button(composite, SWT.PUSH);
selectionButton.setText(" ... ");
selectionButton.addSelectionListener(new FileDirButtonChooser(text));
customChooseButtons[type] = selectionButton;
return text;
}
private void fillCombo(Combo combo, int type) {
String selection = combo.getText();
combo.removeAll();
for (String input : inputs) {
if (input.startsWith(FILE) && type == SOURCE && (fileToFileButton.getSelection() || fileToDirButton.getSelection())) {
combo.add(INPUT_PREFIX + input);
} else if (input.startsWith(FILE) && type == TARGET && fileToFileButton.getSelection()) {
combo.add(INPUT_PREFIX + input);
}
}
for (String dir : directories) {
combo.add(DIRECTORY_PREFIX + dir);
}
if (selection != null && combo.indexOf(selection) >= 0) {
combo.select(combo.indexOf(selection));
}
}
/**
* {@inheritDoc}
*/
@Override
public void create() {
super.create();
installListeners();
updateSelectionAndValidateInput();
}
private void installListeners() {
UpdateListener ul = new UpdateListener();
fileToFileButton.addSelectionListener(ul);
fileToDirButton.addSelectionListener(ul);
dirButton.addSelectionListener(ul);
for (int i = 0; i < 2; i++) {
predefOptionButtons[i].addSelectionListener(ul);
customOptionButtons[i].addSelectionListener(ul);
predefCombos[i].addSelectionListener(ul);
customChooseButtons[i].addSelectionListener(ul);
}
for (int i = 0; i < 2; i++) {
predefTexts[i].addModifyListener(ul);
customTexts[i].addModifyListener(ul);
}
}
protected void updateSelectionAndValidateInput() {
for (int i = 0; i < 2; i++) {
customTexts[i].setEnabled(!predefOptionButtons[i].getSelection());
customChooseButtons[i].setEnabled(!predefOptionButtons[i].getSelection());
predefCombos[i].setEnabled(predefOptionButtons[i].getSelection());
predefTexts[i].setEnabled(predefOptionButtons[i].getSelection());
if (predefCombos[i].getText() != null && predefCombos[i].getText().startsWith(INPUT_PREFIX + FILE)) {
predefTexts[i].setVisible(false);
slashLabel[i].setVisible(false);
} else {
predefTexts[i].setVisible(true);
slashLabel[i].setVisible(true);
}
}
if (fileToFileButton.getSelection()) {
predefTexts[SOURCE].setMessage(Messages.subfolderOrFilename + REQUIRED);
predefTexts[TARGET].setMessage(Messages.subfolderOrFilename);
} else if (fileToDirButton.getSelection()) {
predefTexts[SOURCE].setMessage(Messages.subfolderOrFilename + REQUIRED);
predefTexts[TARGET].setMessage(Messages.subfolderOrFilename.substring(0, Messages.subfolderOrFilename.indexOf(SLASH)));
} else if (dirButton.getSelection()) {
predefTexts[SOURCE].setMessage(Messages.subfolderOrFilename.substring(0, Messages.subfolderOrFilename.indexOf(SLASH)));
predefTexts[TARGET].setMessage(Messages.subfolderOrFilename.substring(0, Messages.subfolderOrFilename.indexOf(SLASH))
+ REQUIRED);
}
boolean isSourceValid = true;
List<String> validationMessages = new LinkedList<>();
if (predefOptionButtons[SOURCE].getSelection()) {
if (predefCombos[SOURCE].getText() == null || predefCombos[SOURCE].getText().isEmpty()) {
isSourceValid = false;
validationMessages.add("Relative source path not valid.");
}
if (fileToFileButton.getSelection() || fileToDirButton.getSelection()) {
if (predefTexts[SOURCE].getText() == null || predefTexts[SOURCE].getText().isEmpty()
&& !predefCombos[SOURCE].getText().startsWith(INPUT_PREFIX + FILE)) {
isSourceValid = false;
validationMessages.add("Relative source file not valid.");
}
}
} else {
if (customTexts[SOURCE].getText() == null || customTexts[SOURCE].getText().isEmpty()) {
isSourceValid = false;
validationMessages.add("Absolute source path not valid.");
} else if (!(new File(customTexts[SOURCE].getText())).isAbsolute()) {
isSourceValid = false;
validationMessages.add("Source path is not absolute.");
}
}
boolean isTargetValid = true;
if (predefOptionButtons[TARGET].getSelection()) {
if (predefCombos[TARGET].getText() == null || predefCombos[TARGET].getText().isEmpty()) {
isTargetValid = false;
validationMessages.add("Relative target path not valid.");
}
if (dirButton.getSelection()) {
if (predefTexts[TARGET].getText() == null || predefTexts[TARGET].getText().isEmpty()) {
isTargetValid = false;
validationMessages.add("Relative target directory not valid.");
}
}
} else {
if (customTexts[TARGET].getText() == null || customTexts[TARGET].getText().isEmpty()) {
isTargetValid = false;
validationMessages.add("Absolute target path not valid.");
} else if (!(new File(customTexts[TARGET].getText())).isAbsolute()) {
isTargetValid = false;
validationMessages.add("Target path is not absolute.");
}
}
if (!validationMessages.isEmpty()) {
validationLabel.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_RED));
validationLabel.setText(validationMessages.get(0));
validationLabel.setVisible(true);
validationLabel.pack();
} else {
validationLabel.setVisible(false);
}
boolean isValid = isSourceValid && isTargetValid;
buildCommand(isValid);
getButton(IDialogConstants.OK_ID).setEnabled(isValid);
}
private void buildCommand(boolean isValid) {
if (dirButton.getSelection()) {
command = SHUTIL_COPYTREE_STRING;
} else {
command = SHUTIL_COPY_STRING;
}
if (predefOptionButtons[SOURCE].getSelection()) {
String slash = SLASH;
if (predefCombos[SOURCE].getText() != null && predefCombos[SOURCE].getText().startsWith(INPUT_PREFIX + FILE)) {
slash = "";
}
command =
command.replace(SOURCE_STRING, getPlaceholder(predefCombos[SOURCE].getText()) + slash + predefTexts[SOURCE].getText());
} else {
command = command.replace(SOURCE_STRING, customTexts[SOURCE].getText());
}
if (predefOptionButtons[TARGET].getSelection()) {
String slash = SLASH;
if (predefCombos[TARGET].getText() != null && predefCombos[TARGET].getText().startsWith(INPUT_PREFIX + FILE)) {
slash = "";
}
command =
command.replace(TARGET_STRING, getPlaceholder(predefCombos[TARGET].getText()) + slash + predefTexts[TARGET].getText());
} else {
command = command.replace(TARGET_STRING, customTexts[TARGET].getText());
}
if (isValid) {
previewCommandLabel.setText(command);
} else {
previewCommandLabel.setText("-");
}
}
private String getPlaceholder(String selection) {
if (selection != null && !selection.isEmpty()) {
String name = selection.substring(selection.indexOf(":") + 2);
String insertString = "${%s:%s}";
if (selection.startsWith(INPUT_PREFIX)) {
insertString = StringUtils.format(insertString, "in", name);
} else if (selection.startsWith(DIRECTORY_PREFIX)) {
int i = 0;
while (!name.equals(ToolIntegrationConstants.DIRECTORIES_PLACEHOLDERS_DISPLAYNAMES[i])) {
i++;
}
if (i < ToolIntegrationConstants.DIRECTORIES_PLACEHOLDER.length) {
insertString = StringUtils.format(insertString, "dir", ToolIntegrationConstants.DIRECTORIES_PLACEHOLDER[i]);
}
}
return insertString;
}
return "";
}
public String getCopyCommand() {
return command;
}
/**
* Listener for updating the dialog.
*
* @author Sascha Zur
*/
private class UpdateListener implements SelectionListener, ModifyListener {
@Override
public void widgetSelected(SelectionEvent arg0) {
if (arg0.getSource().equals(fileToDirButton) || arg0.getSource().equals(fileToFileButton)
|| arg0.getSource().equals(dirButton)) {
fillCombo(predefCombos[SOURCE], SOURCE);
fillCombo(predefCombos[TARGET], TARGET);
}
updateSelectionAndValidateInput();
}
@Override
public void widgetDefaultSelected(SelectionEvent arg0) {
widgetSelected(arg0);
}
@Override
public void modifyText(ModifyEvent arg0) {
updateSelectionAndValidateInput();
}
}
/**
* Opens the correct dialog for the file or directory choose buttons.
*
* @author Sascha Zur
*/
private class FileDirButtonChooser implements SelectionListener {
private final Text text;
FileDirButtonChooser(Text text) {
this.text = text;
}
@Override
public void widgetDefaultSelected(SelectionEvent arg0) {
widgetSelected(arg0);
}
@Override
public void widgetSelected(SelectionEvent arg0) {
String result = "";
if (fileToFileButton.getSelection() || fileToDirButton.getSelection() && arg0.getSource().equals(customChooseButtons[SOURCE])) {
FileDialog f = new FileDialog(getShell());
result = f.open();
} else {
DirectoryDialog d = new DirectoryDialog(getShell());
result = d.open();
}
if (result != null) {
text.clearSelection();
text.setText(result.replaceAll("\\\\", "/"));
text.forceFocus();
}
}
}
}