blob: 111b1ef9d810a84aa3fe1839017848d71fb49205 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2009 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
* Philippe Ombredanne - bug 84808
*******************************************************************************/
package org.eclipse.team.internal.ccvs.ui.wizards;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.*;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.*;
import org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder;
import org.eclipse.team.internal.ccvs.ui.CVSUIMessages;
import org.eclipse.team.internal.ccvs.ui.IHelpContextIds;
import org.eclipse.ui.PlatformUI;
/**
* @author Administrator
*
* To change the template for this generated type comment go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
public class CheckoutAsLocationSelectionPage extends CVSWizardPage {
public static final String NAME = "CheckoutAsLocationSelectionPage"; //$NON-NLS-1$
private Button browseButton;
private Combo locationPathField;
private Label locationLabel;
private boolean useDefaults = true;
private ICVSRemoteFolder[] remoteFolders;
private String targetLocation;
private IProject singleProject;
// constants
private static final int SIZING_TEXT_FIELD_WIDTH = 250;
private static final int COMBO_HISTORY_LENGTH = 5;
// store id constants
private static final String STORE_PREVIOUS_LOCATIONS =
"CheckoutAsLocationSelectionPage.STORE_PREVIOUS_LOCATIONS";//$NON-NLS-1$
/**
* @param pageName
* @param title
* @param titleImage
* @param description
*/
public CheckoutAsLocationSelectionPage(ImageDescriptor titleImage, ICVSRemoteFolder[] remoteFolders) {
super(NAME, CVSUIMessages.CheckoutAsLocationSelectionPage_title, titleImage, CVSUIMessages.CheckoutAsLocationSelectionPage_description); //
this.remoteFolders = remoteFolders;
}
/**
* @return
*/
private boolean isSingleFolder() {
return remoteFolders.length == 1;
}
/**
* @param string
*/
public void setProject(IProject project) {
singleProject = project;
setLocationForSelection(true);
}
/**
* @param string
*/
public void setProjectName(String string) {
if (string == null || string.equals(".")) return; //$NON-NLS-1$
if (singleProject != null && singleProject.getName().equals(string)) return;
setProject(ResourcesPlugin.getWorkspace().getRoot().getProject(string));
}
private IProject getSingleProject() {
if (singleProject == null) {
setProjectName(getPreferredFolderName(remoteFolders[0]));
}
return singleProject;
}
@Override
public void createControl(Composite parent) {
Composite composite= createComposite(parent, 1, false);
setControl(composite);
// required in order to use setButtonLayoutData
initializeDialogUnits(composite);
PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IHelpContextIds.CHECKOUT_LOCATION_SELECTION_PAGE);
final Button useDefaultsButton =
new Button(composite, SWT.CHECK | SWT.RIGHT);
useDefaultsButton.setText(CVSUIMessages.CheckoutAsLocationSelectionPage_useDefaultLabel);
useDefaultsButton.setSelection(this.useDefaults);
createUserSpecifiedProjectLocationGroup(composite, !this.useDefaults);
initializeValues();
SelectionListener listener = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
useDefaults = useDefaultsButton.getSelection();
browseButton.setEnabled(!useDefaults);
locationPathField.setEnabled(!useDefaults);
locationLabel.setEnabled(!useDefaults);
setLocationForSelection(true);
setErrorMessage(useDefaults ? null : checkValidLocation());
}
};
useDefaultsButton.addSelectionListener(listener);
Dialog.applyDialogFont(parent);
}
/**
* Creates the project location specification controls.
*
* @return the parent of the widgets created
* @param projectGroup the parent composite
* @param enabled - sets the initial enabled state of the widgets
*/
private Composite createUserSpecifiedProjectLocationGroup(Composite parent, boolean enabled) {
// This group needs 3 columns
Composite projectGroup = createComposite(parent, 3, true);
// location label
locationLabel = new Label(projectGroup, SWT.NONE);
if (isSingleFolder()) {
locationLabel.setText(CVSUIMessages.CheckoutAsLocationSelectionPage_locationLabel);
} else {
locationLabel.setText(CVSUIMessages.CheckoutAsLocationSelectionPage_parentDirectoryLabel);
}
locationLabel.setEnabled(enabled);
// project location entry field
locationPathField = new Combo(projectGroup, SWT.DROP_DOWN);
GridData data = new GridData(GridData.FILL_HORIZONTAL);
data.widthHint = SIZING_TEXT_FIELD_WIDTH;
locationPathField.setLayoutData(data);
locationPathField.setEnabled(enabled);
// browse button
this.browseButton = new Button(projectGroup, SWT.PUSH);
this.browseButton.setText(CVSUIMessages.CheckoutAsLocationSelectionPage_browseLabel);
this.browseButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
handleLocationBrowseButtonPressed();
}
});
this.browseButton.setEnabled(enabled);
setButtonLayoutData(this.browseButton);
// Set the initial value first before listener
// to avoid handling an event during the creation.
setLocationForSelection(true);
locationPathField.addModifyListener(e -> setErrorMessage(checkValidLocation()));
return projectGroup;
}
/**
* Initializes states of the controls.
*/
private void initializeValues() {
// Set remembered values
IDialogSettings settings = getDialogSettings();
if (settings != null) {
String[] previouseLocations = settings.getArray(STORE_PREVIOUS_LOCATIONS);
if (previouseLocations != null) {
for (int i = 0; i < previouseLocations.length; i++) {
if(isSingleFolder())
locationPathField.add(new Path(previouseLocations[i]).append(getSingleProject().getName()).toOSString());
else
locationPathField.add(previouseLocations[i]);
}
}
}
}
/**
* Saves the widget values
*/
private void saveWidgetValues() {
// Update history
IDialogSettings settings = getDialogSettings();
if (settings != null) {
String[] previouseLocations = settings.getArray(STORE_PREVIOUS_LOCATIONS);
if (previouseLocations == null) previouseLocations = new String[0];
if(isSingleFolder())
previouseLocations = addToHistory(previouseLocations, new Path(locationPathField.getText()).removeLastSegments(1).toOSString());
else
previouseLocations = addToHistory(previouseLocations, locationPathField.getText());
settings.put(STORE_PREVIOUS_LOCATIONS, previouseLocations);
}
}
/**
* Adds an entry to a history, while taking care of duplicate history items
* and excessively long histories. The assumption is made that all histories
* should be of length <code>CheckoutAsLocationSelectionPage.COMBO_HISTORY_LENGTH</code>.
*
* @param history the current history
* @param newEntry the entry to add to the history
* @return the history with the new entry appended
*/
private String[] addToHistory(String[] history, String newEntry) {
ArrayList<String> l = new ArrayList<>(Arrays.asList(history));
addToHistory(l, newEntry);
String[] r = new String[l.size()];
l.toArray(r);
return r;
}
/**
* Adds an entry to a history, while taking care of duplicate history items
* and excessively long histories. The assumption is made that all histories
* should be of length <code>CheckoutAsLocationSelectionPage.COMBO_HISTORY_LENGTH</code>.
*
* @param history the current history
* @param newEntry the entry to add to the history
*/
private void addToHistory(List<String> history, String newEntry) {
history.remove(newEntry);
history.add(0,newEntry);
// since only one new item was added, we can be over the limit
// by at most one item
if (history.size() > COMBO_HISTORY_LENGTH)
history.remove(COMBO_HISTORY_LENGTH);
}
/**
* Check if the entry in the widget location is valid. If it is valid return null. Otherwise
* return a string that indicates the problem.
*/
private String checkValidLocation() {
if (useDefaults) {
targetLocation = null;
return null;
} else {
targetLocation = locationPathField.getText();
if (targetLocation.equals("")) {//$NON-NLS-1$
return(CVSUIMessages.CheckoutAsLocationSelectionPage_locationEmpty);
}
else{
IPath path = new Path("");//$NON-NLS-1$
if (!path.isValidPath(targetLocation)) {
return CVSUIMessages.CheckoutAsLocationSelectionPage_invalidLocation;
}
}
if (isSingleFolder()) {
IStatus locationStatus =
ResourcesPlugin.getWorkspace().validateProjectLocation(
getSingleProject(),
new Path(targetLocation));
if (!locationStatus.isOK())
return locationStatus.getMessage();
} else {
for (int i = 0; i < remoteFolders.length; i++) {
String projectName = getPreferredFolderName(remoteFolders[i]);
IStatus locationStatus = ResourcesPlugin.getWorkspace().validateProjectLocation(
ResourcesPlugin.getWorkspace().getRoot().getProject(projectName),
new Path(targetLocation).append(projectName));
if (!locationStatus.isOK())
return locationStatus.getMessage();
}
}
return null;
}
}
/**
* Set the location to the default location if we are set to useDefaults.
*/
private void setLocationForSelection(boolean changed) {
if (useDefaults) {
IPath defaultPath = null;
if (isSingleFolder()) {
IProject singleProject = getSingleProject();
if (singleProject != null) {
try {
defaultPath = singleProject.getDescription().getLocation();
} catch (CoreException e) {
// ignore
}
if (defaultPath == null) {
defaultPath = Platform.getLocation().append(singleProject.getName());
}
}
} else {
defaultPath = Platform.getLocation();
}
if (defaultPath != null) {
locationPathField.setText(defaultPath.toOSString());
}
targetLocation = null;
} else if (changed) {
IPath location = null;
IProject project = getSingleProject();
if (project != null) {
try {
location = project.getDescription().getLocation();
} catch (CoreException e) {
// ignore the exception
}
}
if (location == null) {
targetLocation = null;
locationPathField.setText(""); //$NON-NLS-1$
} else {
if (isSingleFolder()) {
targetLocation = location.toOSString();
} else {
targetLocation = location.removeLastSegments(1).toOSString();
}
locationPathField.setText(targetLocation);
}
}
}
/**
* Open an appropriate directory browser
*/
private void handleLocationBrowseButtonPressed() {
DirectoryDialog dialog = new DirectoryDialog(locationPathField.getShell());
if (isSingleFolder()) {
dialog.setMessage(NLS.bind(CVSUIMessages.CheckoutAsLocationSelectionPage_messageForSingle, new String[] { getSingleProject().getName() }));
} else {
dialog.setMessage(NLS.bind(CVSUIMessages.CheckoutAsLocationSelectionPage_messageForMulti, new String[] { Integer.valueOf(remoteFolders.length).toString() }));
}
String dirName = locationPathField.getText();
if (!dirName.equals("")) {//$NON-NLS-1$
File path = new File(dirName);
if (path.exists())
dialog.setFilterPath(dirName);
}
String selectedDirectory = dialog.open();
if (selectedDirectory != null) {
if (isSingleFolder()) {
locationPathField.setText(new Path(selectedDirectory).append(getSingleProject().getName()).toOSString());
} else {
locationPathField.setText(new Path(selectedDirectory).toOSString());
}
}
targetLocation = locationPathField.getText();
}
/**
* Return the custom location for a single project. In this case, the specified
* location is used as the location of the project.
*
* @param project
* @return
*/
public String getTargetLocation() {
if (isCustomLocationSpecified()) {
saveWidgetValues();
return targetLocation;
}
return null;
}
/**
* @return
*/
private boolean isCustomLocationSpecified() {
return !useDefaults;
}
}