| /******************************************************************************* |
| * Copyright (c) 2000, 2016 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 |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.ui.wizards.buildpaths; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.equinox.bidi.StructuredTextTypeHandlerFactory; |
| |
| import org.eclipse.swt.SWT; |
| 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.Shell; |
| import org.eclipse.swt.widgets.Text; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IStatus; |
| |
| import org.eclipse.core.resources.IContainer; |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IWorkspaceRoot; |
| |
| import org.eclipse.jface.dialogs.StatusDialog; |
| import org.eclipse.jface.util.BidiUtils; |
| import org.eclipse.jface.viewers.ILabelProvider; |
| import org.eclipse.jface.viewers.ITreeContentProvider; |
| import org.eclipse.jface.viewers.ViewerFilter; |
| import org.eclipse.jface.window.Window; |
| |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.dialogs.ISelectionStatusValidator; |
| import org.eclipse.ui.model.WorkbenchContentProvider; |
| import org.eclipse.ui.model.WorkbenchLabelProvider; |
| import org.eclipse.ui.views.navigator.ResourceComparator; |
| |
| import org.eclipse.jdt.core.IJavaProject; |
| |
| import org.eclipse.jdt.internal.corext.buildpath.CPJavaProject; |
| import org.eclipse.jdt.internal.corext.buildpath.ClasspathModifier; |
| import org.eclipse.jdt.internal.corext.util.Messages; |
| |
| import org.eclipse.jdt.internal.ui.IJavaHelpContextIds; |
| import org.eclipse.jdt.internal.ui.JavaPlugin; |
| import org.eclipse.jdt.internal.ui.dialogs.StatusInfo; |
| import org.eclipse.jdt.internal.ui.util.SWTUtil; |
| import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels; |
| import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages; |
| import org.eclipse.jdt.internal.ui.wizards.TypedElementSelectionValidator; |
| import org.eclipse.jdt.internal.ui.wizards.TypedViewerFilter; |
| import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField; |
| import org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener; |
| import org.eclipse.jdt.internal.ui.wizards.dialogfields.IStringButtonAdapter; |
| import org.eclipse.jdt.internal.ui.wizards.dialogfields.SelectionButtonDialogField; |
| import org.eclipse.jdt.internal.ui.wizards.dialogfields.StringButtonDialogField; |
| |
| public class OutputLocationDialog extends StatusDialog { |
| |
| private StringButtonDialogField fContainerDialogField; |
| private SelectionButtonDialogField fUseDefault; |
| private SelectionButtonDialogField fUseSpecific; |
| private IStatus fContainerFieldStatus; |
| |
| private IPath fOutputLocation; |
| private final IProject fCurrProject; |
| private final CPListElement fEntryToEdit; |
| private final boolean fAllowInvalidClasspath; |
| private CPJavaProject fCPJavaProject; |
| |
| public OutputLocationDialog(Shell parent, CPListElement entryToEdit, List<CPListElement> classPathList, IPath defaultOutputFolder, boolean allowInvalidClasspath) { |
| super(parent); |
| fEntryToEdit= entryToEdit; |
| fAllowInvalidClasspath= allowInvalidClasspath; |
| setTitle(NewWizardMessages.OutputLocationDialog_title); |
| fContainerFieldStatus= new StatusInfo(); |
| |
| OutputLocationAdapter adapter= new OutputLocationAdapter(); |
| |
| fUseDefault= new SelectionButtonDialogField(SWT.RADIO); |
| fUseDefault.setLabelText(Messages.format(NewWizardMessages.OutputLocationDialog_usedefault_label, BasicElementLabels.getPathLabel(defaultOutputFolder, false))); |
| fUseDefault.setDialogFieldListener(adapter); |
| |
| String label= Messages.format(NewWizardMessages.OutputLocationDialog_usespecific_label, BasicElementLabels.getResourceName(entryToEdit.getPath().segment(0))); |
| fUseSpecific= new SelectionButtonDialogField(SWT.RADIO); |
| fUseSpecific.setLabelText(label); |
| fUseSpecific.setDialogFieldListener(adapter); |
| |
| fContainerDialogField= new StringButtonDialogField(adapter); |
| fContainerDialogField.setButtonLabel(NewWizardMessages.OutputLocationDialog_location_button); |
| fContainerDialogField.setDialogFieldListener(adapter); |
| |
| fUseSpecific.attachDialogField(fContainerDialogField); |
| |
| IJavaProject javaProject= entryToEdit.getJavaProject(); |
| fCurrProject= javaProject.getProject(); |
| fCPJavaProject= new CPJavaProject(javaProject, classPathList, defaultOutputFolder); |
| |
| IPath outputLocation= (IPath) entryToEdit.getAttribute(CPListElement.OUTPUT); |
| if (outputLocation == null) { |
| fUseDefault.setSelection(true); |
| } else { |
| fUseSpecific.setSelection(true); |
| fContainerDialogField.setText(outputLocation.removeFirstSegments(1).makeRelative().toString()); |
| } |
| } |
| |
| @Override |
| protected Control createDialogArea(Composite parent) { |
| Composite composite= (Composite)super.createDialogArea(parent); |
| |
| int widthHint= convertWidthInCharsToPixels(70); |
| int indent= convertWidthInCharsToPixels(4); |
| |
| Composite inner= new Composite(composite, SWT.NONE); |
| GridLayout layout= new GridLayout(); |
| layout.marginHeight= 0; |
| layout.marginWidth= 0; |
| layout.numColumns= 2; |
| inner.setLayout(layout); |
| |
| fUseDefault.doFillIntoGrid(inner, 2); |
| fUseSpecific.doFillIntoGrid(inner, 2); |
| |
| Text textControl= fContainerDialogField.getTextControl(inner); |
| GridData textData= new GridData(); |
| textData.widthHint= widthHint; |
| textData.grabExcessHorizontalSpace= true; |
| textData.horizontalIndent= indent; |
| textControl.setLayoutData(textData); |
| BidiUtils.applyBidiProcessing(textControl, StructuredTextTypeHandlerFactory.FILE); |
| |
| Button buttonControl= fContainerDialogField.getChangeControl(inner); |
| GridData buttonData= new GridData(); |
| buttonData.widthHint= SWTUtil.getButtonWidthHint(buttonControl); |
| buttonControl.setLayoutData(buttonData); |
| |
| applyDialogFont(composite); |
| return composite; |
| } |
| |
| |
| // -------- OutputLocationAdapter -------- |
| |
| private class OutputLocationAdapter implements IDialogFieldListener, IStringButtonAdapter { |
| |
| // -------- IDialogFieldListener |
| |
| @Override |
| public void dialogFieldChanged(DialogField field) { |
| doStatusLineUpdate(); |
| } |
| |
| @Override |
| public void changeControlPressed(DialogField field) { |
| doChangeControlPressed(); |
| } |
| } |
| |
| protected void doChangeControlPressed() { |
| IContainer container= chooseOutputLocation(); |
| if (container != null) { |
| fContainerDialogField.setText(container.getProjectRelativePath().toString()); |
| } |
| } |
| |
| protected void doStatusLineUpdate() { |
| checkIfPathValid(); |
| updateStatus(fContainerFieldStatus); |
| } |
| |
| protected void checkIfPathValid() { |
| fOutputLocation= null; |
| fContainerFieldStatus= StatusInfo.OK_STATUS; |
| |
| if (fUseDefault.isSelected()) { |
| return; |
| } |
| |
| String pathStr= fContainerDialogField.getText(); |
| if (pathStr.length() == 0) { |
| fContainerFieldStatus= new StatusInfo(IStatus.ERROR, ""); //$NON-NLS-1$ |
| return; |
| } |
| |
| IPath projectPath= fCPJavaProject.getJavaProject().getProject().getFullPath(); |
| IPath outputPath= projectPath.append(pathStr); |
| |
| try { |
| fContainerFieldStatus= ClasspathModifier.checkSetOutputLocationPrecondition(fEntryToEdit, outputPath, fAllowInvalidClasspath, fCPJavaProject); |
| if (fContainerFieldStatus.getSeverity() != IStatus.ERROR) { |
| fOutputLocation= outputPath; |
| } |
| } catch (CoreException e) { |
| JavaPlugin.log(e); |
| } |
| } |
| |
| public IPath getOutputLocation() { |
| return fOutputLocation; |
| } |
| |
| /* |
| * @see org.eclipse.jface.window.Window#configureShell(Shell) |
| */ |
| @Override |
| protected void configureShell(Shell newShell) { |
| super.configureShell(newShell); |
| PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell, IJavaHelpContextIds.OUTPUT_LOCATION_DIALOG); |
| } |
| |
| // ---------- util method ------------ |
| |
| private IContainer chooseOutputLocation() { |
| IWorkspaceRoot root= fCurrProject.getWorkspace().getRoot(); |
| final Class<?>[] acceptedClasses= new Class[] { IProject.class, IFolder.class }; |
| IProject[] allProjects= root.getProjects(); |
| ArrayList<IProject> rejectedElements= new ArrayList<>(allProjects.length); |
| for (IProject project : allProjects) { |
| if (!project.equals(fCurrProject)) { |
| rejectedElements.add(project); |
| } |
| } |
| ViewerFilter filter= new TypedViewerFilter(acceptedClasses, rejectedElements.toArray()); |
| |
| ILabelProvider lp= new WorkbenchLabelProvider(); |
| ITreeContentProvider cp= new WorkbenchContentProvider(); |
| |
| IResource initSelection= null; |
| if (fOutputLocation != null) { |
| initSelection= root.findMember(fOutputLocation); |
| } |
| |
| FolderSelectionDialog dialog= new FolderSelectionDialog(getShell(), lp, cp); |
| dialog.setTitle(NewWizardMessages.OutputLocationDialog_ChooseOutputFolder_title); |
| |
| dialog.setValidator(new ISelectionStatusValidator() { |
| ISelectionStatusValidator validator= new TypedElementSelectionValidator(acceptedClasses, false); |
| @Override |
| public IStatus validate(Object[] selection) { |
| IStatus typedStatus= validator.validate(selection); |
| if (!typedStatus.isOK()) |
| return typedStatus; |
| if (selection[0] instanceof IFolder) { |
| IFolder folder= (IFolder) selection[0]; |
| try { |
| IStatus result= ClasspathModifier.checkSetOutputLocationPrecondition(fEntryToEdit, folder.getFullPath(), fAllowInvalidClasspath, fCPJavaProject); |
| if (result.getSeverity() == IStatus.ERROR) |
| return result; |
| } catch (CoreException e) { |
| JavaPlugin.log(e); |
| } |
| return new StatusInfo(); |
| } else { |
| return new StatusInfo(IStatus.ERROR, ""); //$NON-NLS-1$ |
| } |
| } |
| }); |
| dialog.setMessage(NewWizardMessages.OutputLocationDialog_ChooseOutputFolder_description); |
| dialog.addFilter(filter); |
| dialog.setInput(root); |
| dialog.setInitialSelection(initSelection); |
| dialog.setComparator(new ResourceComparator(ResourceComparator.NAME)); |
| |
| if (dialog.open() == Window.OK) { |
| return (IContainer)dialog.getFirstResult(); |
| } |
| return null; |
| } |
| } |