/******************************************************************************* * Copyright (c) 2000, 2003 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.ui.dialogs; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.text.MessageFormat; import java.util.Iterator; import org.eclipse.core.resources.*; import org.eclipse.core.runtime.*; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.IStructuredSelection; 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.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.*; import org.eclipse.ui.actions.WorkspaceModifyOperation; import org.eclipse.ui.help.WorkbenchHelp; import org.eclipse.ui.internal.*; import org.eclipse.ui.internal.dialogs.CreateLinkedResourceGroup; import org.eclipse.ui.internal.misc.ResourceAndContainerGroup; /** * Standard main page for a wizard that creates a file resource. *
* This page may be used by clients as-is; it may be also be subclassed to suit. *
** Subclasses may override *
getInitialContents
getNewFileLabel
* Subclasses may extend *
handleEvent
null
if none (equivalent to an empty stream)
* @param monitor the progress monitor to show visual progress with
* @exception CoreException if the operation fails
* @exception OperationCanceledException if the operation is canceled
*/
protected void createFile(IFile fileHandle, InputStream contents, IProgressMonitor monitor) throws CoreException {
if (contents == null)
contents = new ByteArrayInputStream(new byte[0]);
try {
// Create a new file resource in the workspace
if (linkTargetPath != null)
fileHandle.createLink(linkTargetPath, IResource.ALLOW_MISSING_LOCAL, monitor);
else
fileHandle.create(contents, false, monitor);
}
catch (CoreException e) {
// If the file already existed locally, just refresh to get contents
if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED)
fileHandle.refreshLocal(IResource.DEPTH_ZERO, null);
else
throw e;
}
if (monitor.isCanceled())
throw new OperationCanceledException();
}
/**
* Creates a file resource handle for the file with the given workspace path.
* This method does not create the file resource; this is the responsibility
* of createFile
.
*
* @param filePath the path of the file resource to create a handle for
* @return the new file resource handle
* @see #createFile
*/
protected IFile createFileHandle(IPath filePath) {
return WorkbenchPlugin.getPluginWorkspace().getRoot().getFile(filePath);
}
/**
* Creates the link target path if a link target has been specified.
*/
protected void createLinkTarget() {
String linkTarget = linkedResourceGroup.getLinkTarget();
if (linkTarget != null) {
linkTargetPath = new Path(linkTarget);
}
else {
linkTargetPath = null;
}
}
/**
* Creates a new file resource in the selected container and with the selected
* name. Creates any missing resource containers along the path; does nothing if
* the container resources already exist.
* * In normal usage, this method is invoked after the user has pressed Finish on * the wizard; the enablement of the Finish button implies that all controls on * on this page currently contain valid values. *
** Note that this page caches the new file once it has been successfully * created; subsequent invocations of this method will answer the same * file resource without attempting to create it again. *
** This method should be called within a workspace modify operation since * it creates resources. *
* * @return the created file resource, ornull
if the file
* was not created
*/
public IFile createNewFile() {
if (newFile != null)
return newFile;
// create the new file and cache it if successful
final IPath containerPath = resourceGroup.getContainerFullPath();
IPath newFilePath = containerPath.append(resourceGroup.getResource());
final IFile newFileHandle = createFileHandle(newFilePath);
final InputStream initialContents = getInitialContents();
createLinkTarget();
WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
protected void execute(IProgressMonitor monitor) throws CoreException,
InterruptedException
{
try {
monitor.beginTask(WorkbenchMessages.getString("WizardNewFileCreationPage.progress"), 2000); //$NON-NLS-1$
ContainerGenerator generator = new ContainerGenerator(containerPath);
generator.generateContainer(new SubProgressMonitor(monitor, 1000));
createFile(newFileHandle,initialContents, new SubProgressMonitor(monitor, 1000));
} finally {
monitor.done();
}
}
};
try {
getContainer().run(true, true, op);
} catch (InterruptedException e) {
return null;
} catch (InvocationTargetException e) {
if (e.getTargetException() instanceof CoreException) {
ErrorDialog.openError(
getContainer().getShell(), // Was Utilities.getFocusShell()
WorkbenchMessages.getString("WizardNewFileCreationPage.errorTitle"), //$NON-NLS-1$
null, // no special message
((CoreException) e.getTargetException()).getStatus());
}
else {
// CoreExceptions are handled above, but unexpected runtime exceptions and errors may still occur.
WorkbenchPlugin.log(MessageFormat.format("Exception in {0}.getNewFile(): {1}", new Object[] {getClass().getName(), e.getTargetException()}));//$NON-NLS-1$
MessageDialog.openError(getContainer().getShell(), WorkbenchMessages.getString("WizardNewFileCreationPage.internalErrorTitle"), WorkbenchMessages.format("WizardNewFileCreationPage.internalErrorMessage", new Object[] {e.getTargetException().getMessage()})); //$NON-NLS-2$ //$NON-NLS-1$
}
return null;
}
newFile = newFileHandle;
return newFile;
}
/**
* 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 null
if no path is known
*/
public IPath getContainerFullPath() {
return resourceGroup.getContainerFullPath();
}
/**
* Returns the current file name as entered by the user, or its anticipated
* initial value.
*
* @return the file name, its anticipated initial value, or null
* if no file name is known
*/
public String getFileName() {
if (resourceGroup == null)
return initialFileName;
return resourceGroup.getResource();
}
/**
* Returns a stream containing the initial contents to be given to new file resource
* instances. Subclasses may wish to override. This default implementation
* provides no initial contents.
*
* @return initial contents to be given to new file resource instances
*/
protected InputStream getInitialContents() {
return null;
}
/**
* Returns the label to display in the file name specification visual
* component group.
* * Subclasses may reimplement. *
* * @return the label to display in the file name specification visual * component group */ protected String getNewFileLabel() { return WorkbenchMessages.getString("WizardNewFileCreationPage.fileLabel"); //$NON-NLS-1$ } /** * Shows/hides the advanced option widgets. */ protected void handleAdvancedButtonSelect() { Shell shell = getShell(); Point shellSize = shell.getSize(); Composite composite = (Composite) getControl(); if (linkedResourceComposite != null) { linkedResourceComposite.dispose(); linkedResourceComposite = null; composite.layout(); shell.setSize(shellSize.x, shellSize.y - linkedResourceGroupHeight); advancedButton.setText(WorkbenchMessages.getString("showAdvanced")); //$NON-NLS-1$ } else { linkedResourceComposite = linkedResourceGroup.createContents(linkedResourceParent); if (linkedResourceGroupHeight == -1) { Point groupSize = linkedResourceComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); linkedResourceGroupHeight = groupSize.y; } shell.setSize(shellSize.x, shellSize.y + linkedResourceGroupHeight); composite.layout(); advancedButton.setText(WorkbenchMessages.getString("hideAdvanced")); //$NON-NLS-1$ } } /** * TheWizardNewFileCreationPage
implementation of this
* Listener
method handles all events and enablements for controls
* on this page. Subclasses may extend.
*/
public void handleEvent(Event event) {
setPageComplete(validatePage());
}
/**
* 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 initialPopulateContainerNameField() {
if (initialContainerFullPath != null)
resourceGroup.setContainerFullPath(initialContainerFullPath);
else {
Iterator enum = currentSelection.iterator();
if (enum.hasNext()) {
Object object = enum.next();
IResource selectedResource = null;
if (object instanceof IResource) {
selectedResource = (IResource)object;
} else if (object instanceof IAdaptable) {
selectedResource = (IResource)((IAdaptable)object).getAdapter(IResource.class);
}
if (selectedResource != null) {
if (selectedResource.getType() == IResource.FILE)
selectedResource = selectedResource.getParent();
if (selectedResource.isAccessible())
resourceGroup.setContainerFullPath(selectedResource.getFullPath());
}
}
}
}
/**
* 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 (resourceGroup == null)
initialContainerFullPath = path;
else
resourceGroup.setContainerFullPath(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 (resourceGroup == null)
initialFileName = value;
else
resourceGroup.setResource(value);
}
/**
* Checks whether the linked resource target is valid.
* Sets the error message accordingly and returns the status.
*
* @return IStatus validation result from the CreateLinkedResourceGroup
*/
protected IStatus validateLinkedResource() {
IPath containerPath = resourceGroup.getContainerFullPath();
IPath newFilePath = containerPath.append(resourceGroup.getResource());
IFile newFileHandle = createFileHandle(newFilePath);
IStatus status = linkedResourceGroup.validateLinkLocation(newFileHandle);
if (status.getSeverity() == IStatus.ERROR) {
if (firstLinkCheck)
setMessage(status.getMessage());
else
setErrorMessage(status.getMessage());
} else if (status.getSeverity() == IStatus.WARNING) {
setMessage(status.getMessage(), WARNING);
setErrorMessage(null);
}
return status;
}
/**
* Returns whether this page's controls currently all contain valid
* values.
*
* @return true
if all controls are valid, and
* false
if at least one is invalid
*/
protected boolean validatePage() {
boolean valid = true;
if (!resourceGroup.areAllValuesValid()) {
// if blank name then fail silently
if (resourceGroup.getProblemType() == ResourceAndContainerGroup.PROBLEM_RESOURCE_EMPTY
|| resourceGroup.getProblemType() == ResourceAndContainerGroup.PROBLEM_CONTAINER_EMPTY) {
setMessage(resourceGroup.getProblemMessage());
setErrorMessage(null);
} else
setErrorMessage(resourceGroup.getProblemMessage());
valid = false;
}
IStatus linkedResourceStatus = null;
if (valid) {
linkedResourceStatus = validateLinkedResource();
if (linkedResourceStatus.getSeverity() == IStatus.ERROR)
valid = false;
}
// validateLinkedResource sets messages itself
if (valid && (linkedResourceStatus == null || linkedResourceStatus.isOK())) {
setMessage(null);
setErrorMessage(null);
}
return valid;
}
/*
* @see DialogPage.setVisible(boolean)
*/
public void setVisible(boolean visible) {
super.setVisible(visible);
if(visible)
resourceGroup.setFocus();
}
}