/*=============================================================================# # Copyright (c) 2005-2016 Stephan Wahlbrink (WalWare.de) and others. # All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License v1.0 # which accompanies this distribution, and is available at # http://www.eclipse.org/legal/epl-v10.html # # Contributors: # Stephan Wahlbrink - initial API and implementation #=============================================================================*/ package de.walware.statet.ext.ui.wizards; import java.util.Iterator; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Text; import de.walware.ecommons.ui.SharedMessages; import de.walware.ecommons.ui.components.StatusInfo; import de.walware.ecommons.ui.dialogs.groups.Layouter; import de.walware.ecommons.ui.workbench.ContainerSelectionComposite; import de.walware.ecommons.ui.workbench.ContainerSelectionComposite.ContainerFilter; import de.walware.statet.base.core.StatetProject; /** * Standard main page for a wizard that creates a file resource. * <p> * This page may be used by clients as-is; it may be also be subclassed to suit. * </p> * <p> * Subclasses may override * <ul> * <li><code>getInitialContents</code></li> * <li><code>getNewFileLabel</code></li> * </ul> * </p> * <p> * Subclasses may extend * <ul> * <li><code>handleEvent</code></li> * </ul> * </p> */ public abstract class NewElementWizardPage extends WizardPage { private static class StatetProjectFilter extends ContainerSelectionComposite.ContainerFilter { @Override public boolean select(final IContainer container) { try { final IProject project= container.getProject(); if (project.hasNature(StatetProject.NATURE_ID)) { return true; } } catch (final CoreException e) {} return false; } } public class ResourceGroup implements Listener { private static final int SIZING_CONTAINER_GROUP_HEIGHT = 250; private static final String DIALOGSETTING_ENABLEFILTER = "de.walware.statet.NewElementWizard.ContainerFilter"; //$NON-NLS-1$ private final String resourceNameDefaultSuffix; private final ContainerFilter containerFilter; private ContainerSelectionComposite fContainerGroup; private Text fResourceNameControl; private IPath fContainerFullPath; private String fResourceName; private boolean fResourceNameEdited; public ResourceGroup(final String defaultResourceNameExtension, final ContainerFilter containerFilter) { this.resourceNameDefaultSuffix= defaultResourceNameExtension; this.containerFilter= containerFilter; } public ResourceGroup(final String defaultResourceNameExtension) { this(defaultResourceNameExtension, new StatetProjectFilter()); } public void createGroup(final Layouter parentLayouter) { final Layouter layouter = new Layouter(new Composite(parentLayouter.composite, SWT.NONE), 2); layouter.composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); // resource and container group fContainerGroup = new ContainerSelectionComposite( layouter.composite, true, false, null, SIZING_CONTAINER_GROUP_HEIGHT); fContainerGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); fContainerGroup.setListener(this); boolean enableFilter = true; if (getDialogSettings().get(DIALOGSETTING_ENABLEFILTER) != null) { enableFilter = getDialogSettings().getBoolean(DIALOGSETTING_ENABLEFILTER); } fContainerGroup.setToggleFilter(this.containerFilter, enableFilter); fResourceNameControl = layouter.addLabeledTextControl(getNewFileLabel()); fResourceNameControl.addListener(SWT.Modify, this); initFields(); } /** * Returns the label to display in the file name specification visual * component group. * <p> * Subclasses may reimplement. * </p> * * @return the label to display in the file name specification visual * component group */ protected String getNewFileLabel() { return StatetWizardsMessages.ResourceGroup_NewFile_label; } /** * Sets the initial contents of the container name entry field, based upon * either a previously-specified initial value or the ability to determine * such a value. */ protected void initFields() { IPath path = null; if (fContainerFullPath != null) { path = fContainerFullPath; } else { final Iterator<?> it = fResourceSelection.iterator(); if (it.hasNext()) { final Object object = it.next(); IResource selectedResource = null; if (object instanceof IResource) { selectedResource = (IResource) object; } else if (object instanceof IAdaptable) { selectedResource = ((IAdaptable) object).getAdapter(IResource.class); } if (selectedResource != null) { if (selectedResource.getType() == IResource.FILE) { selectedResource = selectedResource.getParent(); } if (selectedResource.isAccessible()) { path = selectedResource.getFullPath(); } } } } if (path != null) { fContainerGroup.selectContainer(path); } if (fResourceName != null) { fResourceNameControl.setText(fResourceName); } } @Override public void handleEvent(final Event event) { fContainerFullPath = fContainerGroup.getContainerFullPath(); final String name = fResourceNameControl.getText(); if (!fResourceNameEdited && event.widget == fResourceNameControl && name.length() > 0 && !name.equals(fResourceName)) { fResourceNameEdited = true; } fResourceName = name; validatePage(); } // /** // * Sets the value of this page's container name field, or stores // * it for future use if this page's controls do not exist yet. // * // * @param path the full path to the container // */ // public void setContainerFullPath(IPath path) { // if (fResourceGroup != null) // fResourceGroup.setContainerFullPath(path); // update fResourceName? // else // fContainerFullPath = path; // } // // /** // * Sets the value of this page's file name field, or stores // * it for future use if this page's controls do not exist yet. // * // * @param value new file name // */ // public void setFileName(String value) { // if (fResourceGroup != null) // fResourceGroup.setResource(value); // update fResourceName? // else // fResourceName = value; // } /** * Returns the current full path of the containing resource as entered or * selected by the user, or its anticipated initial value. * * @return the container's full path, anticipated initial value, * or <code>null</code> if no path is known */ public IPath getContainerFullPath() { return fContainerFullPath; } /** * Returns the current file name as entered by the user, or its anticipated * initial value. * * @return the file name, its anticipated initial value, or <code>null</code> * if no file name is known */ public String getResourceName() { String name = fResourceName; if (!name.endsWith(this.resourceNameDefaultSuffix)) { name += this.resourceNameDefaultSuffix; } return name; } public void setFocus() { fResourceNameControl.setFocus(); } /** * * @return true, if ok */ public IStatus validate() { // don't attempt to validate controls until they have been created if (fContainerGroup == null) { return null; } final IStatus containerSelectionStatus = ContainerSelectionComposite.validate(fContainerFullPath); if (containerSelectionStatus.matches(IStatus.ERROR)) { return containerSelectionStatus; } final IStatus resourceNameStatus = validateResourceName(fResourceName); if (resourceNameStatus == null || resourceNameStatus.matches(IStatus.ERROR)) { return resourceNameStatus; } final IPath path = fContainerGroup.getContainerFullPath().append(getResourceName()); // no warnings return validateFullResourcePath(path); } protected IStatus validateResourceName(final String resourceName) { if (resourceName == null || resourceName.trim().isEmpty()) { if (fResourceNameEdited) { return new StatusInfo(IStatus.ERROR, NLS.bind( StatetWizardsMessages.ResourceGroup_error_EmptyName, SharedMessages.Resources_File)); } else { return null; } } if (!(new Path("")).isValidSegment(resourceName)) { return new StatusInfo(IStatus.ERROR, NLS.bind( StatetWizardsMessages.ResourceGroup_error_InvalidFilename, resourceName)); } return new StatusInfo(); } /** * Returns a <code>boolean</code> indicating whether the specified resource * path represents a valid new resource in the workbench. An error message * is stored for future reference if the path does not represent a valid * new resource path. * * @param resourcePath the path to validate * @return IStatus indicating validity of the resource path */ protected IStatus validateFullResourcePath(final IPath resourcePath) { final IWorkspace workspace = ResourcesPlugin.getWorkspace(); final IStatus result = workspace.validatePath(resourcePath.toString(), IResource.FILE); if (!result.isOK()) { return result; } if ( // !allowExistingResources && workspace.getRoot().getFolder(resourcePath).exists() || workspace.getRoot().getFile(resourcePath).exists()) { return new StatusInfo(IStatus.ERROR, StatetWizardsMessages.ResourceGroup_error_ResourceExists); } return new StatusInfo(); } public void saveSettings() { getDialogSettings().put(DIALOGSETTING_ENABLEFILTER, fContainerGroup.getToggleFilterSetting()); } } /** the current resource selection */ protected IStructuredSelection fResourceSelection; /** * Creates a new file creation wizard page. If the initial resource selection * contains exactly one container resource then it will be used as the default * container resource. * * @param pageName the name of the page * @param selection the current resource selection */ public NewElementWizardPage(final String pageName, final IStructuredSelection selection) { super(pageName); setPageComplete(false); fResourceSelection = selection; } /** (non-Javadoc) * Method declared on IDialogPage. */ @Override public void createControl(final Composite parent) { initializeDialogUnits(parent); // top level group final GridLayout layout = new GridLayout(); layout.marginHeight = 0; final Layouter layouter = new Layouter(new Composite(parent, SWT.NONE), layout); layouter.composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); createContents(layouter); // validatePage(); // Show description on opening setErrorMessage(null); setMessage(null); setControl(layouter.composite); } /** * Subclasses should ADDHELP * * @param layouter */ protected abstract void createContents(Layouter layouter); /** * Returns whether this page's controls currently all contain valid * values. * * @return <code>true</code> if all controls are valid, and * <code>false</code> if at least one is invalid */ protected void validatePage() { updateStatus(new StatusInfo()); } /** * Updates the status line and the OK button according to the given status * * @param status status to apply */ protected void updateStatus(IStatus status) { if (status != null) { setPageComplete(!status.matches(IStatus.ERROR)); } else { setPageComplete(false); status = new StatusInfo(); } final Control control = getControl(); if (control != null && control.isVisible()) { StatusInfo.applyToStatusLine(this, status); } } }