/******************************************************************************* * 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 CheckoutAsLocationSelectionPage.COMBO_HISTORY_LENGTH. * * @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 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 CheckoutAsLocationSelectionPage.COMBO_HISTORY_LENGTH. * * @param history the current history * @param newEntry the entry to add to the history */ private void addToHistory(List 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; } }