| /******************************************************************************* |
| * 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(); |
| } |
| |
| } |
| } |