blob: 396ab2aebcf2cf3c9f89673363eabd1db3d53bdc [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2015, 2018 Red Hat.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat - Initial Contribution
*******************************************************************************/
package org.eclipse.linuxtools.internal.vagrant.ui.wizards;
import java.nio.file.Paths;
import java.util.Map;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.beans.BeanProperties;
import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.list.WritableList;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.validation.MultiValidator;
import org.eclipse.core.databinding.validation.ValidationStatus;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.databinding.wizard.WizardPageSupport;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.linuxtools.internal.vagrant.core.EnvironmentsManager;
import org.eclipse.linuxtools.internal.vagrant.ui.SWTImagesFactory;
import org.eclipse.linuxtools.vagrant.core.IVagrantBox;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
public class CreateVMPage extends WizardPage {
private final CreateVMPageModel model;
private final DataBindingContext dbc;
private CreateVMAdvancedComposite advanced;
public CreateVMPage(IVagrantBox box) {
super("createVMPage", //$NON-NLS-1$
WizardMessages.getString("CreateVM.label"), //$NON-NLS-1$
SWTImagesFactory.DESC_BANNER_REPOSITORY);
setMessage(WizardMessages.getString("CreateVM.desc")); //$NON-NLS-1$
this.model = new CreateVMPageModel();
if (box != null) {
this.model.setBoxRef(box.getName());
}
this.dbc = new DataBindingContext();
}
@Override
public void dispose() {
dbc.dispose();
super.dispose();
}
public String getVMName() {
return model.getVFileMode() ? null : this.model.getVMName();
}
public String getBoxReference() {
return model.getVFileMode() ? null : this.model.getBoxRef();
}
public String getVMFile() {
return model.getVFileMode() ? this.model.getVMFile() : null;
}
public Map<String, String> getEnvironment() {
return model.getEnvironment();
}
@Override
public void createControl(Composite parent) {
ScrolledComposite scrollTop = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL);
scrollTop.setExpandVertical(true);
scrollTop.setExpandHorizontal(true);
final Composite container = new Composite(scrollTop, SWT.NONE);
GridLayoutFactory.fillDefaults().numColumns(3).margins(6, 6)
.applyTo(container);
// VM Name
final Label vmNameLabel = new Label(container, SWT.NONE);
vmNameLabel
.setText(WizardMessages.getString("CreateVM.name.label")); //$NON-NLS-1$
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(false, false).applyTo(vmNameLabel);
final Text vmNameText = new Text(container, SWT.BORDER);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(true, false).span(2, 1).applyTo(vmNameText);
vmNameText.setToolTipText(
WizardMessages.getString("CreateVMPage.name.tooltip")); //$NON-NLS-1$
// VM Name binding
final IObservableValue<String> vmmNameObservable = BeanProperties
.value(CreateVMPageModel.class, CreateVMPageModel.VM_NAME)
.observe(model);
dbc.bindValue(WidgetProperties.text(SWT.Modify).observe(vmNameText),
vmmNameObservable);
// Box name
final Label boxRefLabel = new Label(container, SWT.NONE);
boxRefLabel
.setText(WizardMessages.getString("CreateVMPage.boxRef.label")); //$NON-NLS-1$
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(false, false).applyTo(boxRefLabel);
final Text boxRefText = new Text(container, SWT.BORDER);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(true, false).applyTo(boxRefText);
boxRefText.setToolTipText(
WizardMessages.getString("CreateVMPage.boxRef.tooltip")); //$NON-NLS-1$
// Box Name binding
final IObservableValue<String> boxRefObservable = BeanProperties
.value(CreateVMPageModel.class, CreateVMPageModel.BOX_REF)
.observe(model);
dbc.bindValue(WidgetProperties.text(SWT.Modify).observe(boxRefText),
boxRefObservable);
// Box name search
final Button boxSearchButton = new Button(container, SWT.NONE);
boxSearchButton
.setText(WizardMessages.getString("CreateVMPage.search.label")); //$NON-NLS-1$
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(false, false).applyTo(boxSearchButton);
boxSearchButton.addSelectionListener(onSearchImage());
// VM File Checkbox
final Button customVMFileButton = new Button(container, SWT.CHECK);
customVMFileButton
.setText(WizardMessages.getString("CreateVMPage.File.CheckBox")); //$NON-NLS-1$
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(false, false).span(3, 1).applyTo(customVMFileButton);
final IObservableValue<String> customVMFileObservable = BeanProperties
.value(CreateVMPageModel.class, CreateVMPageModel.V_FILE_MODE)
.observe(model);
dbc.bindValue(WidgetProperties.selection().observe(customVMFileButton),
customVMFileObservable);
// VM File
final Label boxLocLabel = new Label(container, SWT.NONE);
boxLocLabel
.setText(WizardMessages.getString("CreateVMPage.loc.label")); //$NON-NLS-1$
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(false, false).applyTo(boxLocLabel);
final Text boxLocText = new Text(container, SWT.BORDER);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(true, false).applyTo(boxLocText);
boxLocText.setToolTipText(
WizardMessages.getString("CreateVMPage.loc.tooltip")); //$NON-NLS-1$
boxLocText.setEnabled(false);
// Location binding
final IObservableValue<String> boxLocObservable = BeanProperties
.value(CreateVMPageModel.class, CreateVMPageModel.VM_FILE)
.observe(model);
dbc.bindValue(WidgetProperties.text(SWT.Modify).observe(boxLocText),
boxLocObservable);
boxLocText.addModifyListener(e -> vmFileChanged(boxLocText.getText()));
// Vagrantfile search
final Button vgFilesearchButton = new Button(container, SWT.NONE);
vgFilesearchButton
.setText(WizardMessages.getString("CreateVMPage.search.label")); //$NON-NLS-1$
vgFilesearchButton.setEnabled(false);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(false, false).applyTo(vgFilesearchButton);
vgFilesearchButton.addSelectionListener(onSearchVMFile());
customVMFileButton.addSelectionListener(
onCheckCustomVMFile(vmNameText, boxRefText, boxLocText, vgFilesearchButton, boxSearchButton));
dbc.addValidationStatusProvider(new CreateVMValidationStatusProvider(vmmNameObservable,
boxRefObservable, boxLocObservable));
advanced = new CreateVMAdvancedComposite(
container, scrollTop, model);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).span(3, 1)
.grab(true, false).applyTo(advanced);
// setup validation support
WizardPageSupport.create(this, dbc);
scrollTop.setContent(container);
Point point = container.computeSize(SWT.DEFAULT, SWT.DEFAULT);
scrollTop.setSize(point);
scrollTop.setMinSize(point);
setControl(container);
}
private SelectionListener onCheckCustomVMFile(Text vmNameText,
Text boxRefText, Text boxLocText, Button searchButton,
Button boxSearchButton) {
return SelectionListener.widgetSelectedAdapter(e -> {
if (e.widget instanceof Button) {
Button bt = (Button) e.widget;
if (bt.getSelection()) {
vmNameText.setEnabled(false);
boxRefText.setEnabled(false);
boxSearchButton.setEnabled(false);
searchButton.setEnabled(true);
boxLocText.setEnabled(true);
model.setVFileMode(true);
} else {
vmNameText.setEnabled(true);
boxRefText.setEnabled(true);
boxSearchButton.setEnabled(true);
searchButton.setEnabled(false);
boxLocText.setEnabled(false);
model.setVFileMode(false);
}
}
});
}
private SelectionListener onSearchImage() {
return SelectionListener.widgetSelectedAdapter(e -> {
FileDialog fd = new FileDialog(getShell());
String location = fd.open();
if (location != null && !location.isEmpty()) {
model.setBoxRef(location);
}
});
}
private SelectionListener onSearchVMFile() {
return SelectionListener.widgetSelectedAdapter(e -> {
FileDialog fd = new FileDialog(getShell());
String location = fd.open();
if (location != null && !location.isEmpty()) {
model.setVMFile(location);
vmFileChanged(location);
}
});
}
private void vmFileChanged(String vagrantFile) {
IPath folder = new Path(vagrantFile).removeLastSegments(1);
Map<String, String> existingEnv = EnvironmentsManager.getSingleton()
.getEnvironment(folder.toFile());
if (existingEnv != null) {
model.setEnvironment(existingEnv);
advanced.refresh();
}
}
private class CreateVMValidationStatusProvider extends MultiValidator {
private IObservableValue<String> vmNameOb, boxRefOb, boxLocOb;
public CreateVMValidationStatusProvider(
IObservableValue<String> vmNameOb,
IObservableValue<String> boxRefOb,
IObservableValue<String> boxLocOb) {
this.vmNameOb = vmNameOb;
this.boxRefOb = boxRefOb;
this.boxLocOb = boxLocOb;
}
@Override
public IObservableList<IObservable> getTargets() {
// Work around for NPE triggered by DialogPageSupport.dispose()
return new WritableList<>();
}
@Override
protected IStatus validate() {
String vmName = vmNameOb.getValue();
String boxRef = boxRefOb.getValue();
String boxLoc = boxLocOb.getValue();
if (!model.getVFileMode()) {
if (vmName == null || vmName.isEmpty()) {
return ValidationStatus.error(WizardMessages
.getString("CreateVMPage.emptyVMName")); //$NON-NLS-1$
} else if (boxRef == null || boxRef.isEmpty()) {
return ValidationStatus.error(WizardMessages
.getString("CreateVMPage.emptyBoxRef")); //$NON-NLS-1$
}
} else {
if (boxLoc == null || boxLoc.isEmpty()) {
return ValidationStatus.error(WizardMessages
.getString("CreateVMPage.emptyVagrantfile")); //$NON-NLS-1$
}
if (!Paths.get(boxLoc).toFile().canRead()) {
return ValidationStatus.error(WizardMessages
.getString("CreateVMPage.invalidVagrantfile")); //$NON-NLS-1$
}
}
return ValidationStatus.ok();
}
}
}