blob: 43cf3e6f41e37392996f2cf9d07881190ca50c28 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 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
*******************************************************************************/
package org.eclipse.ui.internal.ide.dialogs;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.DirectoryDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
/**
* ProjectContentsLocationArea is a convenience class for area that handle entry
* of locations using URIs.
*
* @since 3.2
*
*/
public class ProjectContentsLocationArea {
/**
* IErrorMessageReporter is an interface for type that allow message
* reporting.
*
*/
public interface IErrorMessageReporter {
/**
* Report the error message
*
* @param errorMessage
* String or <code>null</code>. If the errorMessage is
* null then clear any error state.
*/
public void reportError(String errorMessage);
}
private static String BROWSE_LABEL = IDEWorkbenchMessages.ProjectLocationSelectionDialog_browseLabel;
private static final int SIZING_TEXT_FIELD_WIDTH = 250;
private static final String FILE_SCHEME = "file"; //$NON-NLS-1$
private Label locationLabel;
private Text locationPathField;
private Button browseButton;
private IErrorMessageReporter errorReporter;
private String projectName = IDEResourceInfoUtils.EMPTY_STRING;
private String userPath = IDEResourceInfoUtils.EMPTY_STRING;
private Button useDefaultsButton;
private IProject existingProject;
/**
* Create a new instance of the receiver.
*
* @param reporter
* @param composite
* @param startProject
*/
public ProjectContentsLocationArea(IErrorMessageReporter reporter,
Composite composite, IProject startProject) {
errorReporter = reporter;
projectName = startProject.getName();
existingProject = startProject;
boolean defaultEnabled = true;
try {
defaultEnabled = startProject.getDescription().getLocationURI() == null;
} catch (CoreException e1) {
// If we get a CoreException assume the default.
}
createContents(composite, defaultEnabled);
}
/**
* Create a new instance of a ProjectContentsLocationArea.
*
* @param reporter
* @param composite
*/
public ProjectContentsLocationArea(IErrorMessageReporter reporter,
Composite composite) {
errorReporter = reporter;
// If it is a new project always start enabled
createContents(composite, true);
}
private void createContents(Composite composite, boolean defaultEnabled) {
// project specification group
Composite projectGroup = new Composite(composite, SWT.NONE);
GridLayout layout = new GridLayout();
layout.numColumns = 3;
projectGroup.setLayout(layout);
projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
useDefaultsButton = new Button(projectGroup, SWT.CHECK | SWT.RIGHT);
useDefaultsButton
.setText(IDEWorkbenchMessages.ProjectLocationSelectionDialog_useDefaultLabel);
useDefaultsButton.setSelection(defaultEnabled);
GridData buttonData = new GridData();
buttonData.horizontalSpan = 3;
useDefaultsButton.setLayoutData(buttonData);
createUserEntryArea(projectGroup, defaultEnabled);
useDefaultsButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
boolean useDefaults = useDefaultsButton.getSelection();
if (useDefaults) {
userPath = locationPathField.getText();
locationPathField.setText(getDefaultPathDisplayString());
} else
locationPathField.setText(userPath);
setUserAreaEnabled(!useDefaults);
}
});
setUserAreaEnabled(!defaultEnabled);
}
/**
* Return whether or not we are currently showing the default location for
* the project.
*
* @return boolean
*/
public boolean isDefault() {
return useDefaultsButton.getSelection();
}
/**
* Create the area for user entry.
*
* @param composite
* @param defaultEnabled
*/
private void createUserEntryArea(Composite composite, boolean defaultEnabled) {
// location label
locationLabel = new Label(composite, SWT.NONE);
locationLabel
.setText(IDEWorkbenchMessages.ProjectLocationSelectionDialog_locationLabel);
// project location entry field
locationPathField = new Text(composite, SWT.BORDER);
GridData data = new GridData(GridData.FILL_HORIZONTAL);
data.widthHint = SIZING_TEXT_FIELD_WIDTH;
locationPathField.setLayoutData(data);
// browse button
browseButton = new Button(composite, SWT.PUSH);
browseButton.setText(BROWSE_LABEL);
browseButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
handleLocationBrowseButtonPressed();
}
});
if (defaultEnabled)// Will be null if it is not set
locationPathField.setText(getDefaultPathDisplayString());
else {
if (existingProject == null)
locationPathField.setText(IDEResourceInfoUtils.EMPTY_STRING);
else {
locationPathField.setText(existingProject.getLocation()
.toString());
}
}
locationPathField.addModifyListener(new ModifyListener() {
/*
* (non-Javadoc)
*
* @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent)
*/
public void modifyText(ModifyEvent e) {
errorReporter.reportError(checkValidLocation());
}
});
}
/**
* Return the path we are going to display. If it is a file URI then remove
* the file prefix.
*
* @return String
*/
private String getDefaultPathDisplayString() {
URI defaultURI = null;
if (existingProject != null)
defaultURI = existingProject.getLocationURI();
// Handle files specially. Assume a file if there is no project to query
if (defaultURI == null || defaultURI.getScheme().equals(FILE_SCHEME)) {
return Platform.getLocation().append(projectName).toString();
}
return defaultURI.toString();
}
/**
* Set the enablement state of the receiver.
*
* @param enabled
*/
private void setUserAreaEnabled(boolean enabled) {
locationLabel.setEnabled(enabled);
locationPathField.setEnabled(enabled);
browseButton.setEnabled(enabled);
}
/**
* Return the browse button. Usually referenced in order to set the layout
* data for a dialog.
*
* @return Button
*/
public Button getBrowseButton() {
return browseButton;
}
/**
* Open an appropriate directory browser
*/
private void handleLocationBrowseButtonPressed() {
DirectoryDialog dialog = new DirectoryDialog(locationPathField
.getShell());
dialog
.setMessage(IDEWorkbenchMessages.ProjectLocationSelectionDialog_directoryLabel);
String dirName = getPathFromLocationField();
if (!dirName.equals(IDEResourceInfoUtils.EMPTY_STRING)) {
IFileInfo info = IDEResourceInfoUtils.getFileInfo(dirName);
if (info != null && info.exists())
dialog.setFilterPath(dirName);
}
String selectedDirectory = dialog.open();
if (selectedDirectory != null)
updateLocationField(selectedDirectory);
}
/**
* Update the location field based on the selected path.
*
* @param selectedPath
*/
private void updateLocationField(String selectedPath) {
locationPathField.setText(selectedPath);
}
/**
* Return the path on the location field.
*
* @return String
*/
private String getPathFromLocationField() {
URI fieldURI;
try {
fieldURI = new URI(locationPathField.getText());
} catch (URISyntaxException e) {
return locationPathField.getText();
}
return fieldURI.getPath();
}
/**
* Check if the entry in the widget location is valid. If it is valid return
* null. Otherwise return a string that indicates the problem.
*
* @return String
*/
public String checkValidLocation() {
if(isDefault())
return null;
String locationFieldContents = locationPathField.getText();
if (locationFieldContents.length() == 0) {
return (IDEWorkbenchMessages.WizardNewProjectCreationPage_projectLocationEmpty);
}
URI newPath = getLocationFieldURI();
if (newPath == null) {
return IDEWorkbenchMessages.ProjectLocationSelectionDialog_locationError;
}
if (existingProject == null) {
IPath projectPath = new Path(locationFieldContents);
if (Platform.getLocation().isPrefixOf(projectPath)) {
return IDEWorkbenchMessages.WizardNewProjectCreationPage_defaultLocationError;
}
} else {
IStatus locationStatus = existingProject.getWorkspace()
.validateProjectLocationURI(existingProject, newPath);
if (!locationStatus.isOK())
return locationStatus.getMessage();
URI projectPath = existingProject.getLocationURI();
if (projectPath != null && projectPath.equals(newPath)) {
return IDEWorkbenchMessages.ProjectLocationSelectionDialog_locationError;
}
}
return null;
}
/**
* Get the URI for the location field if possible.
*
* @return URI or <code>null</code> if it is not valid.
*/
private URI getLocationFieldURI() {
String locationContents = locationPathField.getText();
try {
return new URI(locationContents);
} catch (URISyntaxException e) {
// See if it was acceptable as a file
return new File(locationContents).toURI();
}
}
/**
* Set the text to the default or clear it if not using the defaults.
*
* @param useDefaults
* @param newName
* the name of the project to use. If <code>null</code> use the
* existing project name.
*/
public void updateProjectName(String newName) {
projectName = newName;
if (isDefault())
locationPathField.setText(getDefaultPathDisplayString());
}
/**
* Return the location for the project. If we are using defaults then return
* the workspace root so that core creates it with default values.
*
* @return String
*/
public String getProjectLocation() {
if (isDefault())
return Platform.getLocation().toString();
return locationPathField.getText();
}
}