org.eclipse.ui.dialogs.NewFolderDialog.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.ui.dialogs.NewFolderDialog.java

Source

/*******************************************************************************
 * Copyright (c) 2000, 2010 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
 *     Sebastian Davids <sdavids@gmx.de> - Fix for bug 19346 - Dialog
 *     font should be activated and used by other components.
 *******************************************************************************/

package org.eclipse.ui.dialogs;

import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectNatureDescriptor;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Point;
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.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
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.dialogs.CreateLinkedResourceGroup;

/**
 * The NewFolderDialog is used to create a new folder.
 * The folder can optionally be linked to a file system folder.
 * <p>
 * This class may be instantiated; it is not intended to be subclassed.
 * </p>
 * @noextend This class is not intended to be subclassed by clients.
 */
public class NewFolderDialog extends SelectionStatusDialog {
    // widgets
    private Text folderNameField;

    private Button advancedButton;

    private CreateLinkedResourceGroup linkedResourceGroup;

    private IContainer container;

    private boolean firstLinkCheck = true;

    /**
     * Parent composite of the advanced widget group for creating 
     * linked resources.
     */
    private Composite linkedResourceParent;

    /**
     * Linked resources widget group. Null if advanced section is not visible.
     */
    private Composite linkedResourceComposite;

    /**
     * Height of the dialog without the "advanced" linked resource group. 
     * Set when the advanced group is first made visible. 
     */
    private int basicShellHeight = -1;

    /**
     * Creates a NewFolderDialog
     * 
     * @param parentShell parent of the new dialog
     * @param container parent of the new folder
     */
    public NewFolderDialog(Shell parentShell, IContainer container) {
        super(parentShell);
        this.container = container;
        setTitle(IDEWorkbenchMessages.NewFolderDialog_title);
        setStatusLineAboveButtons(true);
    }

    /**
     * Creates the folder using the name and link target entered
     * by the user.
     * Sets the dialog result to the created folder.  
     */
    protected void computeResult() {
        //Do nothing here as we 
        //need to know the result
    }

    /* (non-Javadoc)
     * Method declared in Window.
     */
    protected void configureShell(Shell shell) {
        super.configureShell(shell);
        PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, IIDEHelpContextIds.NEW_FOLDER_DIALOG);
    }

    /**
     * @see org.eclipse.jface.window.Window#create()
     */
    public void create() {
        super.create();
        // initially disable the ok button since we don't preset the
        // folder name field
        getButton(IDialogConstants.OK_ID).setEnabled(false);
    }

    /**
     * Creates the widget for advanced options.
     *  
     * @param parent the parent composite
     */
    protected void createAdvancedControls(Composite parent) {
        Preferences preferences = ResourcesPlugin.getPlugin().getPluginPreferences();

        if (preferences.getBoolean(ResourcesPlugin.PREF_DISABLE_LINKING) == false && isValidContainer()) {
            linkedResourceParent = new Composite(parent, SWT.NONE);
            linkedResourceParent.setFont(parent.getFont());
            linkedResourceParent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
            GridLayout layout = new GridLayout();
            layout.marginHeight = 0;
            layout.marginWidth = 0;
            linkedResourceParent.setLayout(layout);

            advancedButton = new Button(linkedResourceParent, SWT.PUSH);
            advancedButton.setFont(linkedResourceParent.getFont());
            advancedButton.setText(IDEWorkbenchMessages.showAdvanced);
            setButtonLayoutData(advancedButton);
            GridData data = (GridData) advancedButton.getLayoutData();
            data.horizontalAlignment = GridData.BEGINNING;
            advancedButton.setLayoutData(data);
            advancedButton.addSelectionListener(new SelectionAdapter() {
                public void widgetSelected(SelectionEvent e) {
                    handleAdvancedButtonSelect();
                }
            });
        }
        linkedResourceGroup = new CreateLinkedResourceGroup(IResource.FOLDER, new Listener() {
            public void handleEvent(Event e) {
                validateLinkedResource();
                firstLinkCheck = false;
            }
        }, new CreateLinkedResourceGroup.IStringValue() {
            public void setValue(String string) {
                folderNameField.setText(string);
            }

            public String getValue() {
                return folderNameField.getText();
            }

            public IResource getResource() {
                return container;
            }
        });
    }

    /* (non-Javadoc)
     * Method declared on Dialog.
     */
    protected Control createDialogArea(Composite parent) {
        Composite composite = (Composite) super.createDialogArea(parent);
        composite.setLayout(new GridLayout());
        composite.setLayoutData(new GridData(GridData.FILL_BOTH));

        createFolderNameGroup(composite);
        createAdvancedControls(composite);
        return composite;
    }

    /**
     * Creates the folder name specification controls.
     *
     * @param parent the parent composite
     */
    private void createFolderNameGroup(Composite parent) {
        Font font = parent.getFont();
        // project specification group
        Composite folderGroup = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.numColumns = 2;
        folderGroup.setLayout(layout);
        folderGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        // new folder label
        Label folderLabel = new Label(folderGroup, SWT.NONE);
        folderLabel.setFont(font);
        folderLabel.setText(IDEWorkbenchMessages.NewFolderDialog_nameLabel);

        // new folder name entry field
        folderNameField = new Text(folderGroup, SWT.BORDER);
        GridData data = new GridData(GridData.FILL_HORIZONTAL);
        data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
        folderNameField.setLayoutData(data);
        folderNameField.setFont(font);
        folderNameField.addListener(SWT.Modify, new Listener() {
            public void handleEvent(Event event) {
                validateLinkedResource();
            }
        });
    }

    /**
     * Creates a folder resource handle for the folder with the given name.
     * The folder handle is created relative to the container specified during 
     * object creation. 
     *
     * @param folderName the name of the folder resource to create a handle for
     * @return the new folder resource handle
     */
    private IFolder createFolderHandle(String folderName) {
        IWorkspaceRoot workspaceRoot = container.getWorkspace().getRoot();
        IPath folderPath = container.getFullPath().append(folderName);
        IFolder folderHandle = workspaceRoot.getFolder(folderPath);

        return folderHandle;
    }

    /**
     * Creates a new folder with the given name and optionally linking to
     * the specified link target.
     * 
     * @param folderName name of the new folder
     * @param linkTarget name of the link target folder. may be null.
     * @return IFolder the new folder
     */
    private IFolder createNewFolder(String folderName, final URI linkTarget) {
        final IFolder folderHandle = createFolderHandle(folderName);

        WorkspaceModifyOperation operation = new WorkspaceModifyOperation() {
            public void execute(IProgressMonitor monitor) throws CoreException {
                try {
                    monitor.beginTask(IDEWorkbenchMessages.NewFolderDialog_progress, 2000);
                    if (monitor.isCanceled()) {
                        throw new OperationCanceledException();
                    }
                    if (linkTarget == null) {
                        folderHandle.create(false, true, monitor);
                    } else {
                        folderHandle.createLink(linkTarget, IResource.ALLOW_MISSING_LOCAL, monitor);
                    }
                    if (monitor.isCanceled()) {
                        throw new OperationCanceledException();
                    }
                } finally {
                    monitor.done();
                }
            }
        };
        try {
            PlatformUI.getWorkbench().getProgressService().busyCursorWhile(operation);
        } catch (InterruptedException exception) {
            return null;
        } catch (InvocationTargetException exception) {
            if (exception.getTargetException() instanceof CoreException) {
                ErrorDialog.openError(getShell(), IDEWorkbenchMessages.NewFolderDialog_errorTitle, null, // no special message
                        ((CoreException) exception.getTargetException()).getStatus());
            } else {
                // CoreExceptions are handled above, but unexpected runtime exceptions and errors may still occur.
                IDEWorkbenchPlugin.log(getClass(), "createNewFolder", exception.getTargetException()); //$NON-NLS-1$
                MessageDialog.openError(getShell(), IDEWorkbenchMessages.NewFolderDialog_errorTitle,
                        NLS.bind(IDEWorkbenchMessages.NewFolderDialog_internalError,
                                exception.getTargetException().getMessage()));
            }
            return null;
        }
        return folderHandle;
    }

    /**
     * Shows/hides the advanced option widgets. 
     */
    protected void handleAdvancedButtonSelect() {
        Shell shell = getShell();
        Point shellSize = shell.getSize();
        Composite composite = (Composite) getDialogArea();

        if (linkedResourceComposite != null) {
            linkedResourceComposite.dispose();
            linkedResourceComposite = null;
            composite.layout();
            shell.setSize(shellSize.x, basicShellHeight);
            advancedButton.setText(IDEWorkbenchMessages.showAdvanced);
        } else {
            if (basicShellHeight == -1) {
                basicShellHeight = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).y;
            }
            linkedResourceComposite = linkedResourceGroup.createContents(linkedResourceParent);
            shellSize = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
            shell.setSize(shellSize);
            composite.layout();
            advancedButton.setText(IDEWorkbenchMessages.hideAdvanced);
        }
    }

    /**
     * Returns whether the container specified in the constructor is
     * a valid parent for creating linked resources.
     * 
     * @return boolean <code>true</code> if the container specified in 
     *    the constructor is a valid parent for creating linked resources.
     *    <code>false</code> if no linked resources may be created with the
     *    specified container as a parent. 
     */
    private boolean isValidContainer() {
        if (container.getType() != IResource.PROJECT && container.getType() != IResource.FOLDER) {
            return false;
        }

        try {
            IWorkspace workspace = IDEWorkbenchPlugin.getPluginWorkspace();
            IProject project = container.getProject();
            String[] natureIds = project.getDescription().getNatureIds();

            for (int i = 0; i < natureIds.length; i++) {
                IProjectNatureDescriptor descriptor = workspace.getNatureDescriptor(natureIds[i]);
                if (descriptor != null && descriptor.isLinkingAllowed() == false) {
                    return false;
                }
            }
        } catch (CoreException exception) {
            // project does not exist or is closed
            return false;
        }
        return true;
    }

    /**
     * Update the dialog's status line to reflect the given status. It is safe to call
     * this method before the dialog has been opened.
     */
    protected void updateStatus(IStatus status) {
        if (firstLinkCheck && status != null) {
            // don't show the first validation result as an error.
            // fixes bug 29659
            Status newStatus = new Status(IStatus.OK, status.getPlugin(), status.getCode(), status.getMessage(),
                    status.getException());
            super.updateStatus(newStatus);
        } else {
            super.updateStatus(status);
        }
    }

    /**
     * Update the dialog's status line to reflect the given status. It is safe to call
     * this method before the dialog has been opened.
     * @param severity
     * @param message
     */
    private void updateStatus(int severity, String message) {
        updateStatus(new Status(severity, IDEWorkbenchPlugin.IDE_WORKBENCH, severity, message, null));
    }

    /**
     * Checks whether the folder name and link location are valid.
     * Disable the OK button if the folder name and link location are valid.
     * a message that indicates the problem otherwise.
     */
    private void validateLinkedResource() {
        boolean valid = validateFolderName();

        if (valid) {
            IFolder linkHandle = createFolderHandle(folderNameField.getText());
            IStatus status = linkedResourceGroup.validateLinkLocation(linkHandle);

            if (status.getSeverity() != IStatus.ERROR) {
                getOkButton().setEnabled(true);
            } else {
                getOkButton().setEnabled(false);
            }

            if (status.isOK() == false) {
                updateStatus(status);
            }
        } else {
            getOkButton().setEnabled(false);
        }
    }

    /**
     * Checks if the folder name is valid.
     *
     * @return null if the new folder name is valid.
     *    a message that indicates the problem otherwise.
     */
    private boolean validateFolderName() {
        String name = folderNameField.getText();
        IWorkspace workspace = container.getWorkspace();
        IStatus nameStatus = workspace.validateName(name, IResource.FOLDER);

        if ("".equals(name)) { //$NON-NLS-1$
            updateStatus(IStatus.ERROR, IDEWorkbenchMessages.NewFolderDialog_folderNameEmpty);
            return false;
        }
        if (nameStatus.isOK() == false) {
            updateStatus(nameStatus);
            return false;
        }
        IPath path = new Path(name);
        if (container.getFolder(path).exists() || container.getFile(path).exists()) {
            updateStatus(IStatus.ERROR, NLS.bind(IDEWorkbenchMessages.NewFolderDialog_alreadyExists, name));
            return false;
        }
        updateStatus(IStatus.OK, ""); //$NON-NLS-1$
        return true;
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.dialogs.SelectionStatusDialog#okPressed()
     */
    protected void okPressed() {
        URI linkTarget = linkedResourceGroup.getLinkTargetURI();
        IFolder folder = createNewFolder(folderNameField.getText(), linkTarget);
        if (folder == null) {
            return;
        }

        setSelectionResult(new IFolder[] { folder });

        super.okPressed();
    }
}