| /******************************************************************************* |
| * 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.Files; |
| import java.nio.file.Paths; |
| |
| import org.eclipse.core.databinding.DataBindingContext; |
| import org.eclipse.core.databinding.UpdateValueStrategy; |
| 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.IStatus; |
| 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.ui.SWTImagesFactory; |
| 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.DirectoryDialog; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Text; |
| |
| public class PackageVMPage extends WizardPage { |
| |
| private final PackageVMPageModel model; |
| private final DataBindingContext dbc; |
| |
| public PackageVMPage() { |
| super("PackageVMPage", //$NON-NLS-1$ |
| WizardMessages.getString("PackageVMPage.label"), //$NON-NLS-1$ |
| SWTImagesFactory.DESC_BANNER_REPOSITORY); |
| setMessage(WizardMessages.getString("PackageVMPage.desc")); //$NON-NLS-1$ |
| this.model = new PackageVMPageModel(); |
| this.dbc = new DataBindingContext(); |
| } |
| |
| @Override |
| public void dispose() { |
| dbc.dispose(); |
| super.dispose(); |
| } |
| |
| public String getBoxName() { |
| return this.model.getBoxName(); |
| } |
| |
| public String getBoxFolder() { |
| return this.model.getBoxFolder(); |
| } |
| |
| @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); |
| GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).span(1, 1) |
| .grab(true, false).applyTo(container); |
| |
| // Box name |
| final Label boxNameLabel = new Label(container, SWT.NONE); |
| boxNameLabel |
| .setText(WizardMessages.getString("ImagePull.name.label")); //$NON-NLS-1$ |
| GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER) |
| .grab(false, false).applyTo(boxNameLabel); |
| |
| final Text boxNameText = new Text(container, SWT.BORDER); |
| GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER) |
| .grab(true, false).span(2, 1).applyTo(boxNameText); |
| boxNameText.setToolTipText( |
| WizardMessages.getString("ImagePull.name.tooltip")); //$NON-NLS-1$ |
| // Name binding |
| final IObservableValue<String> boxNameObservable = BeanProperties |
| .value(PackageVMPageModel.class, PackageVMPageModel.BOX_NAME) |
| .observe(model); |
| dbc.bindValue(WidgetProperties.text(SWT.Modify).observe(boxNameText), |
| boxNameObservable, new UpdateValueStrategy(), null); |
| |
| // Box folder |
| final Label boxFolderLabel = new Label(container, SWT.NONE); |
| boxFolderLabel.setText(WizardMessages.getString("PackageVMPage.folder.label")); //$NON-NLS-1$ |
| GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER) |
| .grab(false, false).applyTo(boxFolderLabel); |
| |
| final Text boxFolderText = new Text(container, SWT.BORDER); |
| GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER) |
| .grab(true, false).applyTo(boxFolderText); |
| boxFolderText.setToolTipText( |
| WizardMessages.getString("PackageVMPage.folder.desc")); //$NON-NLS-1$ |
| // Folder binding |
| final IObservableValue<String> boxFolderObservable = BeanProperties |
| .value(PackageVMPageModel.class, PackageVMPageModel.BOX_FOLDER) |
| .observe(model); |
| dbc.bindValue(WidgetProperties.text(SWT.Modify).observe(boxFolderText), |
| boxFolderObservable, new UpdateValueStrategy(), null); |
| // search |
| final Button searchButton = new Button(container, SWT.NONE); |
| searchButton |
| .setText(WizardMessages.getString("ImagePull.search.label")); //$NON-NLS-1$ |
| GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER) |
| .grab(false, false).applyTo(searchButton); |
| searchButton.addSelectionListener(onSearchFolder()); |
| |
| dbc.addValidationStatusProvider(new PackageVMValidationStatusProvider( |
| boxNameObservable, boxFolderObservable)); |
| |
| // 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); |
| } |
| |
| /** |
| * Opens the folder selection dialog. |
| * |
| * @return |
| */ |
| private SelectionListener onSearchFolder() { |
| return SelectionListener.widgetSelectedAdapter(e -> { |
| DirectoryDialog fd = new DirectoryDialog(getShell()); |
| String location = fd.open(); |
| if (location != null && !location.isEmpty()) { |
| model.setBoxFolder(location); |
| } |
| }); |
| } |
| |
| private class PackageVMValidationStatusProvider extends MultiValidator { |
| |
| private IObservableValue<String> boxNameOb, boxFolderOb; |
| |
| public PackageVMValidationStatusProvider( |
| IObservableValue<String> boxNameOb, |
| IObservableValue<String> boxFolderOb) { |
| this.boxNameOb = boxNameOb; |
| this.boxFolderOb = boxFolderOb; |
| } |
| |
| @Override |
| public IObservableList<IObservable> getTargets() { |
| // Work around for NPE triggered by DialogPageSupport.dispose() |
| return new WritableList<>(); |
| } |
| |
| @Override |
| protected IStatus validate() { |
| String boxName = boxNameOb.getValue(); |
| String boxFolder = boxFolderOb.getValue(); |
| if (boxName == null || boxName.isEmpty()) { |
| return ValidationStatus.error( |
| WizardMessages.getString("AddBoxPage.emptyBoxName")); //$NON-NLS-1$ |
| } else if (boxFolder == null || boxFolder.isEmpty()) { |
| return ValidationStatus.error( |
| WizardMessages.getString("PackageVMPage.folder.empty")); //$NON-NLS-1$ |
| } else if (!Paths.get(boxFolder).toFile().exists()) { |
| return ValidationStatus.error(WizardMessages |
| .getString("PackageVMPage.folder.not.exist")); //$NON-NLS-1$ |
| } else if (!Files.isWritable(Paths.get(boxFolder))) { |
| return ValidationStatus.error(WizardMessages |
| .getString("PackageVMPage.folder.not.writeable")); //$NON-NLS-1$ |
| } |
| return ValidationStatus.ok(); |
| } |
| } |
| |
| } |