| package org.eclipse.ui.internal.misc; |
| |
| /******************************************************************************* |
| * 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 |
| * Leon J. Breedt: Added multiple folder creation support |
| */ |
| |
| import org.eclipse.core.resources.*; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.graphics.Font; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.*; |
| import org.eclipse.ui.internal.WorkbenchMessages; |
| |
| /** |
| * Workbench-level composite for resource and container specification by the user. |
| * Services such as field validation are performed by the group. |
| * The group can be configured to accept existing resources, or only |
| * new resources. |
| */ |
| public class ResourceAndContainerGroup implements Listener { |
| // problem identifiers |
| public static final int PROBLEM_NONE = 0; |
| public static final int PROBLEM_RESOURCE_EMPTY = 1; |
| public static final int PROBLEM_RESOURCE_EXIST = 2; |
| public static final int PROBLEM_RESOURCE_CONTAINS_SEPARATOR = 3; |
| public static final int PROBLEM_PATH_INVALID = 4; |
| public static final int PROBLEM_CONTAINER_EMPTY = 5; |
| public static final int PROBLEM_PROJECT_DOES_NOT_EXIST = 6; |
| public static final int PROBLEM_NAME_INVALID = 7; |
| |
| // the client to notify of changes |
| private Listener client; |
| |
| // whether to allow existing resources |
| private boolean allowExistingResources = false; |
| |
| // resource type (file, folder, project) |
| private String resourceType = WorkbenchMessages.getString("ResourceGroup.resource"); //$NON-NLS-1$ |
| |
| // show closed projects in the tree, by default |
| private boolean showClosedProjects = true; |
| |
| // problem indicator |
| private String problemMessage = "";//$NON-NLS-1$ |
| private int problemType = PROBLEM_NONE; |
| |
| // widgets |
| private ContainerSelectionGroup containerGroup; |
| private Text resourceNameField; |
| |
| // constants |
| private static final int SIZING_TEXT_FIELD_WIDTH = 250; |
| /** |
| * Create an instance of the group to allow the user |
| * to enter/select a container and specify a resource |
| * name. |
| * |
| * @param parent composite widget to parent the group |
| * @param client object interested in changes to the group's fields value |
| * @param resourceFieldLabel label to use in front of the resource name field |
| * @param resourceType one word, in lowercase, to describe the resource to the user (file, folder, project) |
| */ |
| public ResourceAndContainerGroup(Composite parent, Listener client, String resourceFieldLabel, String resourceType) { |
| this(parent, client, resourceFieldLabel, resourceType, true); |
| } |
| /** |
| * Create an instance of the group to allow the user |
| * to enter/select a container and specify a resource |
| * name. |
| * |
| * @param parent composite widget to parent the group |
| * @param client object interested in changes to the group's fields value |
| * @param resourceFieldLabel label to use in front of the resource name field |
| * @param resourceType one word, in lowercase, to describe the resource to the user (file, folder, project) |
| * @param showClosedProjects whether or not to show closed projects |
| */ |
| public ResourceAndContainerGroup(Composite parent, Listener client, String resourceFieldLabel, String resourceType, boolean showClosedProjects) { |
| this(parent,client,resourceFieldLabel, resourceType, showClosedProjects, SWT.DEFAULT); |
| } |
| /** |
| * Create an instance of the group to allow the user |
| * to enter/select a container and specify a resource |
| * name. |
| * |
| * @param parent composite widget to parent the group |
| * @param client object interested in changes to the group's fields value |
| * @param resourceFieldLabel label to use in front of the resource name field |
| * @param resourceType one word, in lowercase, to describe the resource to the user (file, folder, project) |
| * @param showClosedProjects whether or not to show closed projects |
| * @param heightHint height hint for the container selection widget group |
| */ |
| public ResourceAndContainerGroup(Composite parent, Listener client, String resourceFieldLabel, String resourceType, boolean showClosedProjects, int heightHint) { |
| super(); |
| this.resourceType = resourceType; |
| this.showClosedProjects = showClosedProjects; |
| createContents(parent,resourceFieldLabel,heightHint); |
| this.client = client; |
| } |
| /** |
| * Returns a boolean indicating whether all controls in this group |
| * contain valid values. |
| * |
| * @return boolean |
| */ |
| public boolean areAllValuesValid() { |
| return problemType == PROBLEM_NONE; |
| } |
| /** |
| * Creates this object's visual components. |
| * |
| * @param parent org.eclipse.swt.widgets.Composite |
| * @param heightHint height hint for the container selection widget group |
| */ |
| protected void createContents(Composite parent,String resourceLabelString,int heightHint) { |
| |
| Font font = parent.getFont(); |
| // server name group |
| Composite composite = new Composite(parent,SWT.NONE); |
| GridLayout layout = new GridLayout(); |
| layout.marginWidth = 0; |
| layout.marginHeight = 0; |
| composite.setLayout(layout); |
| composite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); |
| composite.setFont(font); |
| |
| // container group |
| if (heightHint == SWT.DEFAULT) |
| containerGroup = new ContainerSelectionGroup(composite, this, true, null,showClosedProjects); |
| else |
| containerGroup = new ContainerSelectionGroup(composite, this, true, null,showClosedProjects, heightHint); |
| |
| // resource name group |
| Composite nameGroup = new Composite(composite,SWT.NONE); |
| layout = new GridLayout(); |
| layout.numColumns = 2; |
| layout.marginWidth = 0; |
| nameGroup.setLayout(layout); |
| nameGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); |
| nameGroup.setFont(font); |
| |
| Label label = new Label(nameGroup,SWT.NONE); |
| label.setText(resourceLabelString); |
| label.setFont(font); |
| |
| // resource name entry field |
| resourceNameField = new Text(nameGroup,SWT.BORDER); |
| resourceNameField.addListener(SWT.Modify,this); |
| GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL); |
| data.widthHint = SIZING_TEXT_FIELD_WIDTH; |
| resourceNameField.setLayoutData(data); |
| resourceNameField.setFont(font); |
| |
| validateControls(); |
| } |
| /** |
| * Returns the path of the currently selected container |
| * or null if no container has been selected. Note that |
| * the container may not exist yet if the user entered |
| * a new container name in the field. |
| */ |
| public IPath getContainerFullPath() { |
| return containerGroup.getContainerFullPath(); |
| } |
| /** |
| * Returns an error message indicating the current problem with the value |
| * of a control in the group, or an empty message if all controls in the |
| * group contain valid values. |
| * |
| * @return java.lang.String |
| */ |
| public String getProblemMessage() { |
| return problemMessage; |
| } |
| /** |
| * Returns the type of problem with the value of a control |
| * in the group. |
| * |
| * @return one of the PROBLEM_* constants |
| */ |
| public int getProblemType() { |
| return problemType; |
| } |
| /** |
| * Returns a string that is the path of the currently selected |
| * container. Returns an empty string if no container has been |
| * selected. |
| */ |
| public String getResource() { |
| return resourceNameField.getText(); |
| } |
| /** |
| * Handles events for all controls in the group. |
| * |
| * @param e org.eclipse.swt.widgets.Event |
| */ |
| public void handleEvent(Event e) { |
| validateControls(); |
| if (client != null) { |
| client.handleEvent(e); |
| } |
| } |
| /** |
| * Sets the flag indicating whether existing resources are permitted. |
| */ |
| public void setAllowExistingResources(boolean value) { |
| allowExistingResources = value; |
| } |
| /** |
| * Sets the value of this page's container. |
| * |
| * @param value Full path to the container. |
| */ |
| public void setContainerFullPath(IPath path) { |
| IResource initial = |
| ResourcesPlugin.getWorkspace().getRoot().findMember(path); |
| if (initial != null) { |
| if (!(initial instanceof IContainer)) { |
| initial = initial.getParent(); |
| } |
| containerGroup.setSelectedContainer((IContainer) initial); |
| } |
| validateControls(); |
| } |
| /** |
| * Gives focus to the resource name field and selects its contents |
| */ |
| public void setFocus() { |
| //select the whole resource name. |
| resourceNameField.setSelection(0, resourceNameField.getText().length()); |
| resourceNameField.setFocus(); |
| } |
| /** |
| * Sets the value of this page's resource name. |
| * |
| * @param value new value |
| */ |
| public void setResource(String value) { |
| resourceNameField.setText(value); |
| validateControls(); |
| } |
| /** |
| * Returns a <code>boolean</code> indicating whether a container name represents |
| * a valid container resource in the workbench. An error message is stored for |
| * future reference if the name does not represent a valid container. |
| * |
| * @return <code>boolean</code> indicating validity of the container name |
| */ |
| protected boolean validateContainer() { |
| IPath path = containerGroup.getContainerFullPath(); |
| if (path == null) { |
| problemType = PROBLEM_CONTAINER_EMPTY; |
| problemMessage = WorkbenchMessages.getString("ResourceGroup.folderEmpty"); //$NON-NLS-1$ |
| return false; |
| } |
| IWorkspace workspace = ResourcesPlugin.getWorkspace(); |
| String projectName = path.segment(0); |
| if (projectName == null || !workspace.getRoot().getProject(projectName).exists()) { |
| problemType = PROBLEM_PROJECT_DOES_NOT_EXIST; |
| problemMessage = WorkbenchMessages.getString("ResourceGroup.noProject"); //$NON-NLS-1$ |
| return false; |
| } |
| return true; |
| } |
| /** |
| * Validates the values for each of the group's controls. If an invalid |
| * value is found then a descriptive error message is stored for later |
| * reference. Returns a boolean indicating the validity of all of the |
| * controls in the group. |
| */ |
| protected boolean validateControls() { |
| // don't attempt to validate controls until they have been created |
| if (containerGroup == null) { |
| return false; |
| } |
| problemType = PROBLEM_NONE; |
| problemMessage = "";//$NON-NLS-1$ |
| |
| if (!validateContainer() || !validateResourceName()) |
| return false; |
| |
| IPath path = containerGroup.getContainerFullPath().append(resourceNameField.getText()); |
| return validateFullResourcePath(path); |
| } |
| /** |
| * 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 containerName the container name to validate |
| * @return <code>boolean</code> indicating validity of the resource path |
| */ |
| protected boolean validateFullResourcePath(IPath resourcePath) { |
| IWorkspace workspace = ResourcesPlugin.getWorkspace(); |
| |
| IStatus result = workspace.validatePath(resourcePath.toString(),IResource.FOLDER); |
| if (!result.isOK()) { |
| problemType = PROBLEM_PATH_INVALID; |
| problemMessage = result.getMessage(); |
| return false; |
| } |
| |
| if (!allowExistingResources && (workspace.getRoot().getFolder(resourcePath).exists() || workspace.getRoot().getFile(resourcePath).exists())) { |
| problemType = PROBLEM_RESOURCE_EXIST; |
| problemMessage = WorkbenchMessages.getString("ResourceGroup.nameExists"); //$NON-NLS-1$ |
| return false; |
| } |
| return true; |
| } |
| /** |
| * Returns a <code>boolean</code> indicating whether the resource name rep- |
| * resents a valid resource name in the workbench. An error message is stored |
| * for future reference if the name does not represent a valid resource name. |
| * |
| * @return <code>boolean</code> indicating validity of the resource name |
| */ |
| protected boolean validateResourceName() { |
| String resourceName = resourceNameField.getText(); |
| |
| if (resourceName.equals("")) {//$NON-NLS-1$ |
| problemType = PROBLEM_RESOURCE_EMPTY; |
| problemMessage = WorkbenchMessages.format("ResourceGroup.emptyName", new Object[] {resourceType}); //$NON-NLS-1$ |
| return false; |
| } |
| |
| if(!(new Path("")).isValidSegment(resourceName)){ //$NON-NLS-1$ |
| problemType = PROBLEM_NAME_INVALID; |
| problemMessage = WorkbenchMessages.format("ResourceGroup.invalidFilename", new String[] {resourceName}); //$NON-NLS-1$ |
| return false; |
| } |
| |
| return true; |
| } |
| |
| } |