| /******************************************************************************* |
| * Copyright (c) 2000, 2005 IBM Corporation 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: |
| * IBM Corporation - initial API and implementation |
| * Bob Foster <bob@objfac.com> |
| * - Fix for bug 23025 - SaveAsDialog should not assume what is being saved is an IFile |
| *******************************************************************************/ |
| package org.eclipse.ui.dialogs; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.jface.dialogs.IDialogConstants; |
| import org.eclipse.jface.dialogs.IDialogSettings; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.dialogs.TitleAreaDialog; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.graphics.Image; |
| 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.Control; |
| import org.eclipse.swt.widgets.Event; |
| import org.eclipse.swt.widgets.Listener; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.internal.ide.IDEInternalWorkbenchImages; |
| import org.eclipse.ui.internal.ide.IDEWorkbenchMessages; |
| import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; |
| import org.eclipse.ui.internal.ide.IIDEHelpContextIds; |
| import org.eclipse.ui.internal.ide.misc.ResourceAndContainerGroup; |
| |
| /** |
| * A standard "Save As" dialog which solicits a path from the user. The |
| * <code>getResult</code> method returns the path. Note that the folder |
| * at the specified path might not exist and might need to be created. |
| * <p> |
| * This class may be instantiated; it is not intended to be subclassed. |
| * </p> |
| * |
| * @see org.eclipse.ui.dialogs.ContainerGenerator |
| */ |
| public class SaveAsDialog extends TitleAreaDialog { |
| |
| private static final String DIALOG_SETTINGS_SECTION = "SaveAsDialogSettings"; //$NON-NLS-1$ |
| |
| private IFile originalFile = null; |
| |
| private String originalName = null; |
| |
| private IPath result; |
| |
| // widgets |
| private ResourceAndContainerGroup resourceGroup; |
| |
| private Button okButton; |
| |
| /** |
| * Image for title area |
| */ |
| private Image dlgTitleImage = null; |
| |
| /** |
| * Creates a new Save As dialog for no specific file. |
| * |
| * @param parentShell the parent shell |
| */ |
| public SaveAsDialog(Shell parentShell) { |
| super(parentShell); |
| setShellStyle(getShellStyle() | SWT.RESIZE); |
| } |
| |
| /* (non-Javadoc) |
| * Method declared in Window. |
| */ |
| protected void configureShell(Shell shell) { |
| super.configureShell(shell); |
| shell.setText(IDEWorkbenchMessages.SaveAsDialog_text); |
| PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, |
| IIDEHelpContextIds.SAVE_AS_DIALOG); |
| } |
| |
| /* (non-Javadoc) |
| * Method declared in Window. |
| */ |
| protected Control createContents(Composite parent) { |
| |
| Control contents = super.createContents(parent); |
| |
| initializeControls(); |
| validatePage(); |
| resourceGroup.setFocus(); |
| setTitle(IDEWorkbenchMessages.SaveAsDialog_title); |
| dlgTitleImage = IDEInternalWorkbenchImages.getImageDescriptor( |
| IDEInternalWorkbenchImages.IMG_DLGBAN_SAVEAS_DLG).createImage(); |
| setTitleImage(dlgTitleImage); |
| setMessage(IDEWorkbenchMessages.SaveAsDialog_message); |
| |
| return contents; |
| } |
| |
| /** |
| * The <code>SaveAsDialog</code> implementation of this <code>Window</code> |
| * method disposes of the banner image when the dialog is closed. |
| */ |
| public boolean close() { |
| if (dlgTitleImage != null) |
| dlgTitleImage.dispose(); |
| return super.close(); |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on Dialog. |
| */ |
| protected void createButtonsForButtonBar(Composite parent) { |
| okButton = createButton(parent, IDialogConstants.OK_ID, |
| IDialogConstants.OK_LABEL, true); |
| createButton(parent, IDialogConstants.CANCEL_ID, |
| IDialogConstants.CANCEL_LABEL, false); |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on Dialog. |
| */ |
| protected Control createDialogArea(Composite parent) { |
| // top level composite |
| Composite parentComposite = (Composite) super.createDialogArea(parent); |
| |
| // create a composite with standard margins and spacing |
| Composite composite = new Composite(parentComposite, SWT.NONE); |
| GridLayout layout = new GridLayout(); |
| layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN); |
| layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN); |
| layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING); |
| layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); |
| composite.setLayout(layout); |
| composite.setLayoutData(new GridData(GridData.FILL_BOTH)); |
| composite.setFont(parentComposite.getFont()); |
| |
| Listener listener = new Listener() { |
| public void handleEvent(Event event) { |
| setDialogComplete(validatePage()); |
| } |
| }; |
| |
| resourceGroup = new ResourceAndContainerGroup( |
| composite, |
| listener, |
| IDEWorkbenchMessages.SaveAsDialog_fileLabel, IDEWorkbenchMessages.SaveAsDialog_file); |
| resourceGroup.setAllowExistingResources(true); |
| |
| return parentComposite; |
| } |
| |
| /** |
| * Returns the full path entered by the user. |
| * <p> |
| * Note that the file and container might not exist and would need to be created. |
| * See the <code>IFile.create</code> method and the |
| * <code>ContainerGenerator</code> class. |
| * </p> |
| * |
| * @return the path, or <code>null</code> if Cancel was pressed |
| */ |
| public IPath getResult() { |
| return result; |
| } |
| |
| /** |
| * Initializes the controls of this dialog. |
| */ |
| private void initializeControls() { |
| if (originalFile != null) { |
| resourceGroup.setContainerFullPath(originalFile.getParent() |
| .getFullPath()); |
| resourceGroup.setResource(originalFile.getName()); |
| } else if (originalName != null) |
| resourceGroup.setResource(originalName); |
| setDialogComplete(validatePage()); |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on Dialog. |
| */ |
| protected void okPressed() { |
| // Get new path. |
| IPath path = resourceGroup.getContainerFullPath().append( |
| resourceGroup.getResource()); |
| |
| //If the user does not supply a file extension and if the save |
| //as dialog was provided a default file name append the extension |
| //of the default filename to the new name |
| if (path.getFileExtension() == null) { |
| if (originalFile != null && originalFile.getFileExtension() != null) |
| path = path.addFileExtension(originalFile.getFileExtension()); |
| else if (originalName != null) { |
| int pos = originalName.lastIndexOf('.'); |
| if (++pos > 0 && pos < originalName.length()) |
| path = path.addFileExtension(originalName.substring(pos)); |
| } |
| } |
| |
| // If the path already exists then confirm overwrite. |
| IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path); |
| if (file.exists()) { |
| String[] buttons = new String[] { IDialogConstants.YES_LABEL, |
| IDialogConstants.NO_LABEL, IDialogConstants.CANCEL_LABEL }; |
| String question = NLS.bind(IDEWorkbenchMessages.SaveAsDialog_overwriteQuestion, path.toOSString()); |
| MessageDialog d = new MessageDialog(getShell(), |
| IDEWorkbenchMessages.Question, |
| null, question, MessageDialog.QUESTION, buttons, 0); |
| int overwrite = d.open(); |
| switch (overwrite) { |
| case 0: // Yes |
| break; |
| case 1: // No |
| return; |
| case 2: // Cancel |
| default: |
| cancelPressed(); |
| return; |
| } |
| } |
| |
| // Store path and close. |
| result = path; |
| close(); |
| } |
| |
| /** |
| * Sets the completion state of this dialog and adjusts the enable state of |
| * the Ok button accordingly. |
| * |
| * @param value <code>true</code> if this dialog is compelete, and |
| * <code>false</code> otherwise |
| */ |
| protected void setDialogComplete(boolean value) { |
| okButton.setEnabled(value); |
| } |
| |
| /** |
| * Sets the original file to use. |
| * |
| * @param originalFile the original file |
| */ |
| public void setOriginalFile(IFile originalFile) { |
| this.originalFile = originalFile; |
| } |
| |
| /** |
| * Set the original file name to use. |
| * Used instead of <code>setOriginalFile</code> |
| * when the original resource is not an IFile. |
| * Must be called before <code>create</code>. |
| * @param originalName default file name |
| */ |
| public void setOriginalName(String originalName) { |
| this.originalName = originalName; |
| } |
| |
| /** |
| * Returns whether this page's visual components all contain valid values. |
| * |
| * @return <code>true</code> if valid, and <code>false</code> otherwise |
| */ |
| private boolean validatePage() { |
| setErrorMessage(null); |
| |
| if (!resourceGroup.areAllValuesValid()) { |
| if (!resourceGroup.getResource().equals("")) // if blank name then fail silently//$NON-NLS-1$ |
| setErrorMessage(resourceGroup.getProblemMessage()); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.window.Dialog#getDialogBoundsSettings() |
| * |
| * @since 3.2 |
| */ |
| protected IDialogSettings getDialogBoundsSettings() { |
| IDialogSettings settings = IDEWorkbenchPlugin.getDefault().getDialogSettings(); |
| IDialogSettings section = settings.getSection(DIALOG_SETTINGS_SECTION); |
| if (section == null) { |
| section = settings.addNewSection(DIALOG_SETTINGS_SECTION); |
| } |
| return section; |
| } |
| } |