Skip to content

Content of file SelectLocationPage.java

/*******************************************************************************
 * Copyright (c) 2011-2015 EclipseSource Muenchen GmbH and others.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 * Stefan Dirix - initial API and implementation
 ******************************************************************************/
package org.eclipse.emf.ecp.emf2web.ui.wizard;

import java.io.File;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.beans.PojoProperties;
import org.eclipse.core.databinding.conversion.IConverter;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.validation.IValidator;
import org.eclipse.core.databinding.validation.ValidationStatus;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.common.ui.dialogs.WorkspaceResourceDialog;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecp.emf2web.controller.xtend.GenerationInfo;
import org.eclipse.emf.ecp.emf2web.ui.messages.Messages;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.databinding.wizard.WizardPageSupport; import org.eclipse.jface.fieldassist.ControlDecoration; import org.eclipse.jface.fieldassist.FieldDecoration; import org.eclipse.jface.fieldassist.FieldDecorationRegistry; import org.eclipse.jface.window.Window; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.model.WorkbenchContentProvider; import org.eclipse.ui.model.WorkbenchLabelProvider; /** * A page for a single generated file which's main purpose is to select a location for the file. * * @author Stefan Dirix * */ public class SelectLocationPage extends WizardPage { private DataBindingContext bindingContext; private final GenerationInfo generationInfo; private Text locationText; private Text generatedText; private Button btnWrap; private ControlDecoration requiredLocationDecoration; private boolean wasAlreadyVisible; /** * Constructor. * * @param generationInfo The {@link GenerationInfo} for which this page is responsible. */ public SelectLocationPage(GenerationInfo generationInfo) { super("wizardPage"); //$NON-NLS-1$ this.generationInfo = generationInfo; wasAlreadyVisible = false; setTitleAndDescription(); } /** * Sets title and description of this page according to the {@link GenerationInfo}. */ protected void setTitleAndDescription() { if (GenerationInfo.MODEL_TYPE.equals(generationInfo.getType())) { setTitle(Messages.getString("SelectLocationPage.Title_ModelType")); //$NON-NLS-1$ setDescription(Messages.getString("SelectLocationPage.Description_ModelType")); //$NON-NLS-1$ } else if (GenerationInfo.VIEW_TYPE.equals(generationInfo.getType())) { setTitle(Messages.getString("SelectLocationPage.Title_ViewType")); //$NON-NLS-1$ setDescription(Messages.getString("SelectLocationPage.Description_ViewType")); //$NON-NLS-1$ } else if (GenerationInfo.MODEL_AND_VIEW_TYPE.equals(generationInfo.getType())) { setTitle(Messages.getString("SelectLocationPage.Title_ModelAndViewType")); //$NON-NLS-1$ setDescription(Messages.getString("SelectLocationPage.Description_ModelAndViewType")); //$NON-NLS-1$ } else { setTitle(Messages.getString("SelectLocationPage.Title_OtherType") + generationInfo.getNameProposal()); //$NON-NLS-1$ setDescription(Messages.getString("SelectLocationPage.Description_OtherType")); //$NON-NLS-1$ } } /** * Returns the linked {@link GenerationInfo}. * * @return The {@link GenerationInfo}. */ public GenerationInfo getGenerationInfo() { return generationInfo; } /** * Returns the bindingContext of this page. * * @return The {@link DataBindingContext}. */ public DataBindingContext getBindingContext() { return bindingContext; } @Override public void createControl(Composite parent) { final Composite container = new Composite(parent, SWT.NULL); setControl(container); container.setLayout(new GridLayout(3, false)); final Label lblLocation = new Label(container, SWT.NONE); lblLocation.setText(Messages.getString("SelectLocationPage.LocationLabel")); //$NON-NLS-1$ new Label(container, SWT.NONE); new Label(container, SWT.NONE); locationText = new Text(container, SWT.BORDER); locationText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1)); requiredLocationDecoration = new ControlDecoration(locationText, SWT.LEFT | SWT.TOP); final FieldDecoration fieldDecoration = FieldDecorationRegistry.getDefault() .getFieldDecoration(FieldDecorationRegistry.DEC_ERROR); requiredLocationDecoration.setImage(fieldDecoration.getImage()); requiredLocationDecoration.setDescriptionText(Messages.getString("SelectLocationPage.RequiredDecorationText")); //$NON-NLS-1$ requiredLocationDecoration.hide(); final Button browseWorkspaceButton = new Button(container, SWT.NONE); browseWorkspaceButton.addSelectionListener(new BrowseWorkspaceButtonSelectionListener()); browseWorkspaceButton.setText(Messages.getString("SelectLocationPage.BrowseWorkspaceButtonLabel")); //$NON-NLS-1$ final Button browseFilesystemButton = new Button(container, SWT.NONE); browseFilesystemButton.addSelectionListener(new BrowseFilesystemButtonSelectionListener()); browseFilesystemButton.setText(Messages.getString("SelectLocationPage.BrowseFilesystemButtonLabel")); //$NON-NLS-1$ new Label(container, SWT.NONE); if (generationInfo.getWrapper() != null) { final Group grpWrapper = new Group(container, SWT.NONE); grpWrapper.setLayout(new GridLayout(1, false)); grpWrapper.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1)); grpWrapper.setText(Messages.getString("SelectLocationPage.OptionalSettingsGroupText")); //$NON-NLS-1$ btnWrap = new Button(grpWrapper, SWT.CHECK); btnWrap.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1)); final String buttonText = Messages.getString("SelectLocationPage.WrapButtonText") //$NON-NLS-1$ + ' ' + generationInfo.getWrapper().getName(); btnWrap.setText(buttonText); } final Group grpPreview = new Group(container, SWT.NONE); grpPreview.setLayout(new FillLayout(SWT.HORIZONTAL)); grpPreview.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1)); grpPreview.setText(Messages.getString("SelectLocationPage.ContentGroupText")); //$NON-NLS-1$ generatedText = new Text(grpPreview, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.CANCEL | SWT.MULTI); bindingContext = initDataBindings(); WizardPageSupport.create(this, bindingContext); } /** * {@inheritDoc} * * @see org.eclipse.jface.dialogs.DialogPage#setVisible(boolean) */ @Override public void setVisible(boolean visible) { super.setVisible(visible); if (visible && !wasAlreadyVisible) { wasAlreadyVisible = true; } } /** * Indicates if this page was already shown to the user. * * @return * {@code true} if this page was already shown to the user, {@code false} if this page was never shown to * the user. */ public boolean wasAlreadyVisible() { return wasAlreadyVisible; } /** * Selection Listener for the Browse Workspace button opening a WorkspaceResourceDialog. */ private class BrowseWorkspaceButtonSelectionListener extends SelectionAdapter { @Override public void widgetSelected(final SelectionEvent e) { final WorkspaceResourceDialog dialog = new WorkspaceResourceDialog(getShell(), new WorkbenchLabelProvider(), new WorkbenchContentProvider()); dialog.setAllowMultiple(false); dialog.setTitle(Messages.getString("SelectLocationPage.SelectLocationDialogTitle")); //$NON-NLS-1$ dialog.setShowNewFolderControl(true); dialog.setShowFileControl(true); // preselect if file exists in workspace if (generationInfo.getLocation() != null && generationInfo.getLocation().isPlatform()) { final IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); final IResource resource = root .findMember(generationInfo.getLocation().trimSegments(1).toPlatformString(true)); if (resource != null && resource.isAccessible()) { dialog.setInitialSelection(resource); final int segment = generationInfo.getLocation().segmentCount() > 0 ? generationInfo.getLocation().segmentCount() - 1 : 0; dialog.setFileText(generationInfo.getLocation().segment(segment)); } } dialog.loadContents(); if (dialog.open() == Window.OK) { final IFile file = dialog.getFile(); final URI newLocation = URI.createPlatformResourceURI(file.getFullPath().toString(), true); setNewLocation(newLocation); } } } /** * Selection Listener for the Browse Filesystem button opening a FileDialog. */ private class BrowseFilesystemButtonSelectionListener extends SelectionAdapter { @Override public void widgetSelected(final SelectionEvent e) { final FileDialog fileDialog = new FileDialog(getShell(), SWT.SINGLE | SWT.SAVE); // preselect if proposal is not in workspace if (generationInfo.getLocation() != null && !generationInfo.getLocation().isPlatform()) { final File file = new File(generationInfo.getLocation().toFileString()); final File parent = file.getParentFile(); if (parent != null && parent.exists()) { fileDialog.setFilterPath(parent.getAbsolutePath()); } fileDialog.setFileName(file.getName()); } final String result = fileDialog.open(); if (result != null) { final URI newLocation = URI.createFileURI(result); setNewLocation(newLocation); } } } /** * Handles the propagation of a new location. * * @param location * The new location for the generated file. */ private void setNewLocation(URI location) { generationInfo.setLocation(location); bindingContext.updateTargets(); requiredLocationDecoration.hide(); } /** * Validates the given location. */ private class LocationValidator implements IValidator { @Override public IStatus validate(Object value) { if (value == null) { requiredLocationDecoration.show(); return ValidationStatus.error(Messages.getString("SelectLocationPage.LocationError")); //$NON-NLS-1$ } if (URI.class.isInstance(value)) { final URI uri = URI.class.cast(value); if (uri.isPlatform()) { final IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); final IResource resource = root.findMember(uri.toPlatformString(true)); if (IContainer.class.isInstance(resource)) { requiredLocationDecoration.show(); return ValidationStatus.error(Messages.getString("SelectLocationPage.LocationDirectoryError")); //$NON-NLS-1$ } } else { if (uri.toFileString() == null) { requiredLocationDecoration.show(); return ValidationStatus.error(Messages.getString("SelectLocationPage.LocationValidError")); //$NON-NLS-1$ } final File file = new File(uri.toFileString()); if (file.isDirectory()) { requiredLocationDecoration.show(); return ValidationStatus.error(Messages.getString("SelectLocationPage.LocationDirectoryError")); //$NON-NLS-1$ } } } requiredLocationDecoration.hide(); return ValidationStatus.ok(); } } /** * Converts a manually entered string to an {@link URI}. */ private class StringToURIConverter implements IConverter { @Override public Object getToType() { return URI.class; } @Override public Object getFromType() { return String.class; } @Override public Object convert(Object fromObject) { if (fromObject == null || "".equals(fromObject)) { //$NON-NLS-1$ return null; } final String path = (String) fromObject; if (path.startsWith("platform:") || path.startsWith("file:")) { //$NON-NLS-1$ //$NON-NLS-2$ return URI.createURI(path, false); } return URI.createFileURI(path); } } /** * Converts an URI to a String. */ private class URItoStringConverter implements IConverter { @Override public Object getToType() { return String.class; } @Override public Object getFromType() { return URI.class; } @Override public Object convert(Object fromObject) { if (fromObject == null) { return ""; //$NON-NLS-1$ } final URI path = (URI) fromObject; if (path.isFile()) { return path.toFileString(); } return path.toString(); } } /** * Creates and initializes the used data bindings. * * @return The initialized {@link DataBindingContext}. */ protected DataBindingContext initDataBindings() { final DataBindingContext bindingContext = new DataBindingContext(); final IObservableValue observeTextLocationTextObserveWidget = WidgetProperties.text(SWT.Modify) .observe(locationText); final IObservableValue locationGenerationInfoObserveValue = PojoProperties.value("location") //$NON-NLS-1$ .observe(generationInfo); bindingContext.bindValue( observeTextLocationTextObserveWidget, locationGenerationInfoObserveValue, new UpdateValueStrategy() .setConverter(new StringToURIConverter()).setAfterConvertValidator(new LocationValidator()), new UpdateValueStrategy().setConverter(new URItoStringConverter())); final IObservableValue observeTextGeneratedTextObserveWidget = WidgetProperties.text(SWT.Modify) .observe(generatedText); final IObservableValue generatedStringGenerationInfoObserveValue = PojoProperties.value("generatedString") //$NON-NLS-1$ .observe(generationInfo); bindingContext.bindValue(observeTextGeneratedTextObserveWidget, generatedStringGenerationInfoObserveValue, null, null); if (generationInfo.getWrapper() != null) { final IObservableValue observeSelectionBtnWrapObserveWidget = WidgetProperties.selection().observe(btnWrap); final IObservableValue wrapGenerationInfoObserveValue = PojoProperties.value("wrap") //$NON-NLS-1$ .observe(generationInfo); bindingContext.bindValue(observeSelectionBtnWrapObserveWidget, wrapGenerationInfoObserveValue, null, null); } return bindingContext; } }