001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.ui.wizards.buildpaths;
011:
012: import java.io.File;
013: import java.util.HashSet;
014: import java.util.Set;
015:
016: import org.eclipse.core.runtime.IPath;
017: import org.eclipse.core.runtime.IStatus;
018: import org.eclipse.core.runtime.Path;
019:
020: import org.eclipse.swt.SWT;
021: import org.eclipse.swt.custom.CLabel;
022: import org.eclipse.swt.graphics.Point;
023: import org.eclipse.swt.layout.GridData;
024: import org.eclipse.swt.layout.GridLayout;
025: import org.eclipse.swt.widgets.Composite;
026: import org.eclipse.swt.widgets.Control;
027: import org.eclipse.swt.widgets.Shell;
028:
029: import org.eclipse.jface.dialogs.StatusDialog;
030: import org.eclipse.jface.window.Window;
031:
032: import org.eclipse.ui.PlatformUI;
033:
034: import org.eclipse.jdt.core.JavaCore;
035:
036: import org.eclipse.jdt.internal.corext.util.Messages;
037:
038: import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
039: import org.eclipse.jdt.internal.ui.dialogs.StatusInfo;
040: import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages;
041: import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField;
042: import org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
043: import org.eclipse.jdt.internal.ui.wizards.dialogfields.IStringButtonAdapter;
044: import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil;
045:
046: /**
047: */
048: public class EditVariableEntryDialog extends StatusDialog {
049:
050: /**
051: * The path to which the archive variable points.
052: * Null if invalid path or not resolvable. Must not exist.
053: */
054: private IPath fFileVariablePath;
055:
056: private IStatus fNameStatus;
057:
058: private Set fExistingEntries;
059: private VariablePathDialogField fFileNameField;
060: private CLabel fFullPathResolvedLabel;
061:
062: /**
063: * Constructor for EditVariableEntryDialog.
064: * @param parent
065: */
066: public EditVariableEntryDialog(Shell parent, IPath initialEntry,
067: IPath[] existingEntries) {
068: super (parent);
069: setTitle(NewWizardMessages.EditVariableEntryDialog_title);
070: setShellStyle(getShellStyle() | SWT.RESIZE);
071:
072: fExistingEntries = new HashSet();
073: if (existingEntries != null) {
074: for (int i = 0; i < existingEntries.length; i++) {
075: IPath curr = existingEntries[i];
076: if (!curr.equals(initialEntry)) {
077: fExistingEntries.add(curr);
078: }
079: }
080: }
081:
082: SourceAttachmentAdapter adapter = new SourceAttachmentAdapter();
083:
084: fFileNameField = new VariablePathDialogField(adapter);
085: fFileNameField.setDialogFieldListener(adapter);
086: fFileNameField
087: .setLabelText(NewWizardMessages.EditVariableEntryDialog_filename_varlabel);
088: fFileNameField
089: .setButtonLabel(NewWizardMessages.EditVariableEntryDialog_filename_external_varbutton);
090: fFileNameField
091: .setVariableButtonLabel(NewWizardMessages.EditVariableEntryDialog_filename_variable_button);
092: String initialString = initialEntry != null ? initialEntry
093: .toString() : ""; //$NON-NLS-1$
094: fFileNameField.setText(initialString);
095: }
096:
097: public IPath getPath() {
098: return Path.fromOSString(fFileNameField.getText());
099: }
100:
101: /* (non-Javadoc)
102: * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
103: */
104: protected Control createDialogArea(Composite parent) {
105: initializeDialogUnits(parent);
106: Composite composite = (Composite) super
107: .createDialogArea(parent);
108:
109: GridLayout layout = (GridLayout) composite.getLayout();
110: layout.numColumns = 3;
111:
112: int widthHint = convertWidthInCharsToPixels(50);
113:
114: GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
115: gd.horizontalSpan = 3;
116:
117: // archive name field
118: fFileNameField.doFillIntoGrid(composite, 4);
119: LayoutUtil.setHorizontalSpan(fFileNameField
120: .getLabelControl(null), 3);
121: LayoutUtil.setWidthHint(fFileNameField.getTextControl(null),
122: widthHint);
123: LayoutUtil.setHorizontalGrabbing(fFileNameField
124: .getTextControl(null));
125:
126: // label that shows the resolved path for variable jars
127: //DialogField.createEmptySpace(composite, 1);
128: fFullPathResolvedLabel = new CLabel(composite, SWT.LEFT);
129: fFullPathResolvedLabel.setText(getResolvedLabelString());
130: fFullPathResolvedLabel.setLayoutData(new GridData(
131: GridData.HORIZONTAL_ALIGN_FILL));
132: DialogField.createEmptySpace(composite, 2);
133:
134: fFileNameField.postSetFocusOnDialogField(parent.getDisplay());
135:
136: PlatformUI.getWorkbench().getHelpSystem().setHelp(composite,
137: IJavaHelpContextIds.SOURCE_ATTACHMENT_BLOCK);
138: applyDialogFont(composite);
139: return composite;
140: }
141:
142: private class SourceAttachmentAdapter implements
143: IStringButtonAdapter, IDialogFieldListener {
144:
145: // -------- IStringButtonAdapter --------
146: public void changeControlPressed(DialogField field) {
147: attachmentChangeControlPressed(field);
148: }
149:
150: // ---------- IDialogFieldListener --------
151: public void dialogFieldChanged(DialogField field) {
152: attachmentDialogFieldChanged(field);
153: }
154: }
155:
156: private void attachmentChangeControlPressed(DialogField field) {
157: if (field == fFileNameField) {
158: IPath jarFilePath = chooseExtJarFile();
159: if (jarFilePath != null) {
160: fFileNameField.setText(jarFilePath.toString());
161: }
162: }
163: }
164:
165: // ---------- IDialogFieldListener --------
166:
167: private void attachmentDialogFieldChanged(DialogField field) {
168: if (field == fFileNameField) {
169: fNameStatus = updateFileNameStatus();
170: }
171: doStatusLineUpdate();
172: }
173:
174: private IPath chooseExtJarFile() {
175: IPath currPath = getPath();
176: IPath resolvedPath = getResolvedPath(currPath);
177: File initialSelection = resolvedPath != null ? resolvedPath
178: .toFile() : null;
179:
180: String currVariable = currPath.segment(0);
181: JARFileSelectionDialog dialog = new JARFileSelectionDialog(
182: getShell(), false, false);
183: dialog
184: .setTitle(NewWizardMessages.EditVariableEntryDialog_extvardialog_title);
185: dialog
186: .setMessage(NewWizardMessages.EditVariableEntryDialog_extvardialog_description);
187: dialog.setInput(fFileVariablePath.toFile());
188: dialog.setInitialSelection(initialSelection);
189: if (dialog.open() == Window.OK) {
190: File result = (File) dialog.getResult()[0];
191: IPath returnPath = Path.fromOSString(result.getPath())
192: .makeAbsolute();
193: return modifyPath(returnPath, currVariable);
194: }
195: return null;
196: }
197:
198: private IPath getResolvedPath(IPath path) {
199: if (path != null) {
200: String varName = path.segment(0);
201: if (varName != null) {
202: IPath varPath = JavaCore.getClasspathVariable(varName);
203: if (varPath != null) {
204: return varPath.append(path.removeFirstSegments(1));
205: }
206: }
207: }
208: return null;
209: }
210:
211: /**
212: * Takes a path and replaces the beginning with a variable name
213: * (if the beginning matches with the variables value)
214: */
215: private IPath modifyPath(IPath path, String varName) {
216: if (varName == null || path == null) {
217: return null;
218: }
219: if (path.isEmpty()) {
220: return new Path(varName);
221: }
222:
223: IPath varPath = JavaCore.getClasspathVariable(varName);
224: if (varPath != null) {
225: if (varPath.isPrefixOf(path)) {
226: path = path.removeFirstSegments(varPath.segmentCount());
227: } else {
228: path = new Path(path.lastSegment());
229: }
230: } else {
231: path = new Path(path.lastSegment());
232: }
233: return new Path(varName).append(path);
234: }
235:
236: private IStatus updateFileNameStatus() {
237: StatusInfo status = new StatusInfo();
238: fFileVariablePath = null;
239:
240: String fileName = fFileNameField.getText();
241: if (fileName.length() == 0) {
242: status
243: .setError(NewWizardMessages.EditVariableEntryDialog_filename_empty);
244: return status;
245: } else {
246: if (!Path.EMPTY.isValidPath(fileName)) {
247: status
248: .setError(NewWizardMessages.EditVariableEntryDialog_filename_error_notvalid);
249: return status;
250: }
251: IPath filePath = Path.fromOSString(fileName);
252: IPath resolvedPath;
253:
254: if (filePath.getDevice() != null) {
255: status
256: .setError(NewWizardMessages.EditVariableEntryDialog_filename_error_deviceinpath);
257: return status;
258: }
259: String varName = filePath.segment(0);
260: if (varName == null) {
261: status
262: .setError(NewWizardMessages.EditVariableEntryDialog_filename_error_notvalid);
263: return status;
264: }
265: fFileVariablePath = JavaCore.getClasspathVariable(varName);
266: if (fFileVariablePath == null) {
267: status
268: .setError(NewWizardMessages.EditVariableEntryDialog_filename_error_varnotexists);
269: return status;
270: }
271:
272: String deprecationMessage = BuildPathSupport
273: .getDeprecationMessage(varName);
274:
275: resolvedPath = fFileVariablePath.append(filePath
276: .removeFirstSegments(1));
277: if (resolvedPath.isEmpty()) {
278: String message = NewWizardMessages.EditVariableEntryDialog_filename_warning_varempty;
279: if (deprecationMessage != null) {
280: message = deprecationMessage + "\n" + message; //$NON-NLS-1$
281: }
282: status.setWarning(message);
283: return status;
284: }
285: File file = resolvedPath.toFile();
286: if (!file.isFile()) {
287: String message = Messages
288: .format(
289: NewWizardMessages.EditVariableEntryDialog_filename_error_filenotexists,
290: resolvedPath.toOSString());
291: if (deprecationMessage != null) {
292: message = deprecationMessage + "\n" + message; //$NON-NLS-1$
293: status.setWarning(message);
294: } else {
295: status.setInfo(message);
296: }
297: return status;
298: }
299: if (deprecationMessage != null) {
300: status.setWarning(deprecationMessage);
301: return status;
302: }
303: }
304: return status;
305: }
306:
307: private String getResolvedLabelString() {
308: IPath resolvedPath = getResolvedPath(getPath());
309: if (resolvedPath != null) {
310: return resolvedPath.toOSString();
311: }
312: return ""; //$NON-NLS-1$
313: }
314:
315: private boolean canBrowseFileName() {
316: // to browse with a variable JAR, the variable name must point to a directory
317: if (fFileVariablePath != null) {
318: return fFileVariablePath.toFile().isDirectory();
319: }
320: return false;
321: }
322:
323: private void doStatusLineUpdate() {
324: fFileNameField.enableButton(canBrowseFileName());
325:
326: // set the resolved path for variable jars
327: if (fFullPathResolvedLabel != null) {
328: fFullPathResolvedLabel.setText(getResolvedLabelString());
329: }
330:
331: IStatus status = fNameStatus;
332: if (!status.matches(IStatus.ERROR)) {
333: IPath path = getPath();
334: if (fExistingEntries.contains(path)) {
335: String message = NewWizardMessages.EditVariableEntryDialog_filename_error_alreadyexists;
336: status = new StatusInfo(IStatus.ERROR, message);
337: }
338: }
339: updateStatus(status);
340: }
341:
342: /*
343: * overridden to ensure full message is visible
344: * @see org.eclipse.jface.dialogs.StatusDialog#updateStatus(org.eclipse.core.runtime.IStatus)
345: */
346: protected void updateStatus(IStatus status) {
347: super .updateStatus(status);
348: Shell shell = getShell();
349: if (shell != null && !shell.isDisposed()) {
350: Point size = shell.getSize();
351: Point minSize = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT,
352: true);
353: if (minSize.x > size.x || minSize.y > size.y) {
354: shell.setSize(minSize);
355: }
356: }
357: }
358: }
|