001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 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.preferences;
011:
012: import java.lang.reflect.InvocationTargetException;
013: import java.util.Map;
014:
015: import org.eclipse.core.runtime.CoreException;
016: import org.eclipse.core.runtime.IAdaptable;
017: import org.eclipse.core.runtime.IProgressMonitor;
018: import org.eclipse.core.runtime.IStatus;
019: import org.eclipse.core.runtime.OperationCanceledException;
020:
021: import org.eclipse.core.resources.IProject;
022: import org.eclipse.core.resources.IWorkspaceRunnable;
023:
024: import org.eclipse.swt.SWT;
025: import org.eclipse.swt.widgets.Composite;
026: import org.eclipse.swt.widgets.Control;
027: import org.eclipse.swt.widgets.Label;
028:
029: import org.eclipse.jface.dialogs.Dialog;
030: import org.eclipse.jface.dialogs.IDialogSettings;
031: import org.eclipse.jface.dialogs.MessageDialog;
032: import org.eclipse.jface.dialogs.ProgressMonitorDialog;
033: import org.eclipse.jface.preference.IPreferencePageContainer;
034:
035: import org.eclipse.ui.PlatformUI;
036: import org.eclipse.ui.dialogs.PropertyPage;
037: import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
038:
039: import org.eclipse.jdt.core.IClasspathEntry;
040: import org.eclipse.jdt.core.IJavaElement;
041: import org.eclipse.jdt.core.IJavaProject;
042: import org.eclipse.jdt.core.JavaCore;
043:
044: import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
045: import org.eclipse.jdt.internal.ui.JavaPlugin;
046: import org.eclipse.jdt.internal.ui.actions.WorkbenchRunnableAdapter;
047: import org.eclipse.jdt.internal.ui.dialogs.StatusUtil;
048: import org.eclipse.jdt.internal.ui.util.BusyIndicatorRunnableContext;
049: import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
050: import org.eclipse.jdt.internal.ui.wizards.IStatusChangeListener;
051: import org.eclipse.jdt.internal.ui.wizards.buildpaths.BuildPathsBlock;
052:
053: /**
054: * Property page for configuring the Java build path
055: */
056: public class BuildPathsPropertyPage extends PropertyPage implements
057: IStatusChangeListener {
058:
059: public static final String PROP_ID = "org.eclipse.jdt.ui.propertyPages.BuildPathsPropertyPage"; //$NON-NLS-1$
060:
061: private static final String PAGE_SETTINGS = "BuildPathsPropertyPage"; //$NON-NLS-1$
062: private static final String INDEX = "pageIndex"; //$NON-NLS-1$
063:
064: public static final Object DATA_ADD_ENTRY = "add_classpath_entry"; //$NON-NLS-1$
065:
066: public static final Object DATA_REVEAL_ENTRY = "select_classpath_entry"; //$NON-NLS-1$
067: public static final Object DATA_REVEAL_ATTRIBUTE_KEY = "select_classpath_attribute_key"; //$NON-NLS-1$
068:
069: public static final Object DATA_BLOCK = "block_until_buildpath_applied"; //$NON-NLS-1$
070:
071: private BuildPathsBlock fBuildPathsBlock;
072: private boolean fBlockOnApply = false;
073:
074: /*
075: * @see PreferencePage#createControl(Composite)
076: */
077: protected Control createContents(Composite parent) {
078: // ensure the page has no special buttons
079: noDefaultAndApplyButton();
080:
081: IProject project = getProject();
082: Control result;
083: if (project == null || !isJavaProject(project)) {
084: result = createWithoutJava(parent);
085: } else if (!project.isOpen()) {
086: result = createForClosedProject(parent);
087: } else {
088: result = createWithJava(parent, project);
089: }
090: Dialog.applyDialogFont(result);
091: return result;
092: }
093:
094: /*
095: * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
096: */
097: public void createControl(Composite parent) {
098: super .createControl(parent);
099: PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(),
100: IJavaHelpContextIds.BUILD_PATH_PROPERTY_PAGE);
101: }
102:
103: private IDialogSettings getSettings() {
104: IDialogSettings javaSettings = JavaPlugin.getDefault()
105: .getDialogSettings();
106: IDialogSettings pageSettings = javaSettings
107: .getSection(PAGE_SETTINGS);
108: if (pageSettings == null) {
109: pageSettings = javaSettings.addNewSection(PAGE_SETTINGS);
110: pageSettings.put(INDEX, 3);
111: }
112: return pageSettings;
113: }
114:
115: /* (non-Javadoc)
116: * @see org.eclipse.jface.dialogs.IDialogPage#setVisible(boolean)
117: */
118: public void setVisible(boolean visible) {
119: if (fBuildPathsBlock != null) {
120: if (!visible) {
121: if (fBuildPathsBlock.hasChangesInDialog()) {
122: String title = PreferencesMessages.BuildPathsPropertyPage_unsavedchanges_title;
123: String message = PreferencesMessages.BuildPathsPropertyPage_unsavedchanges_message;
124: String[] buttonLabels = new String[] {
125: PreferencesMessages.BuildPathsPropertyPage_unsavedchanges_button_save,
126: PreferencesMessages.BuildPathsPropertyPage_unsavedchanges_button_discard,
127: PreferencesMessages.BuildPathsPropertyPage_unsavedchanges_button_ignore };
128: MessageDialog dialog = new MessageDialog(
129: getShell(), title, null, message,
130: MessageDialog.QUESTION, buttonLabels, 0);
131: int res = dialog.open();
132: if (res == 0) {
133: performOk();
134: } else if (res == 1) {
135: fBuildPathsBlock.init(JavaCore
136: .create(getProject()), null, null);
137: } else {
138: // keep unsaved
139: }
140: }
141: } else {
142: if (!fBuildPathsBlock.hasChangesInDialog()
143: && fBuildPathsBlock.hasChangesInClasspathFile()) {
144: fBuildPathsBlock.init(
145: JavaCore.create(getProject()), null, null);
146: }
147: }
148: }
149: super .setVisible(visible);
150: }
151:
152: /*
153: * Content for valid projects.
154: */
155: private Control createWithJava(Composite parent, IProject project) {
156: IWorkbenchPreferenceContainer pageContainer = null;
157: IPreferencePageContainer container = getContainer();
158: if (container instanceof IWorkbenchPreferenceContainer) {
159: pageContainer = (IWorkbenchPreferenceContainer) container;
160: }
161:
162: fBuildPathsBlock = new BuildPathsBlock(
163: new BusyIndicatorRunnableContext(), this , getSettings()
164: .getInt(INDEX), false, pageContainer);
165: fBuildPathsBlock.init(JavaCore.create(project), null, null);
166: return fBuildPathsBlock.createControl(parent);
167: }
168:
169: /*
170: * Content for non-Java projects.
171: */
172: private Control createWithoutJava(Composite parent) {
173: Label label = new Label(parent, SWT.LEFT);
174: label
175: .setText(PreferencesMessages.BuildPathsPropertyPage_no_java_project_message);
176:
177: fBuildPathsBlock = null;
178: setValid(true);
179: return label;
180: }
181:
182: /*
183: * Content for closed projects.
184: */
185: private Control createForClosedProject(Composite parent) {
186: Label label = new Label(parent, SWT.LEFT);
187: label
188: .setText(PreferencesMessages.BuildPathsPropertyPage_closed_project_message);
189:
190: fBuildPathsBlock = null;
191: setValid(true);
192: return label;
193: }
194:
195: private IProject getProject() {
196: IAdaptable adaptable = getElement();
197: if (adaptable != null) {
198: IJavaElement elem = (IJavaElement) adaptable
199: .getAdapter(IJavaElement.class);
200: if (elem instanceof IJavaProject) {
201: return ((IJavaProject) elem).getProject();
202: }
203: }
204: return null;
205: }
206:
207: private boolean isJavaProject(IProject proj) {
208: try {
209: return proj.hasNature(JavaCore.NATURE_ID);
210: } catch (CoreException e) {
211: JavaPlugin.log(e);
212: }
213: return false;
214: }
215:
216: /*
217: * @see IPreferencePage#performOk
218: */
219: public boolean performOk() {
220: if (fBuildPathsBlock != null) {
221: getSettings().put(INDEX, fBuildPathsBlock.getPageIndex());
222: if (fBuildPathsBlock.hasChangesInDialog()
223: || fBuildPathsBlock.isClassfileMissing()) {
224: IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
225: public void run(IProgressMonitor monitor)
226: throws CoreException,
227: OperationCanceledException {
228: fBuildPathsBlock.configureJavaProject(monitor);
229: }
230: };
231: WorkbenchRunnableAdapter op = new WorkbenchRunnableAdapter(
232: runnable);
233: if (fBlockOnApply) {
234: try {
235: new ProgressMonitorDialog(getShell()).run(true,
236: true, op);
237: } catch (InvocationTargetException e) {
238: ExceptionHandler
239: .handle(
240: e,
241: getShell(),
242: PreferencesMessages.BuildPathsPropertyPage_error_title,
243: PreferencesMessages.BuildPathsPropertyPage_error_message);
244: return false;
245: } catch (InterruptedException e) {
246: return false;
247: }
248: } else {
249: op
250: .runAsUserJob(
251: PreferencesMessages.BuildPathsPropertyPage_job_title,
252: null);
253: }
254: }
255: }
256: return true;
257: }
258:
259: /* (non-Javadoc)
260: * @see IStatusChangeListener#statusChanged
261: */
262: public void statusChanged(IStatus status) {
263: setValid(!status.matches(IStatus.ERROR));
264: StatusUtil.applyToStatusLine(this , status);
265: }
266:
267: /* (non-Javadoc)
268: * @see org.eclipse.jface.preference.PreferencePage#applyData(java.lang.Object)
269: */
270: public void applyData(Object data) {
271: if (data instanceof Map) {
272: Map map = (Map) data;
273: Object selectedLibrary = map.get(DATA_REVEAL_ENTRY);
274: if (selectedLibrary instanceof IClasspathEntry) {
275: IClasspathEntry entry = (IClasspathEntry) selectedLibrary;
276: Object attr = map.get(DATA_REVEAL_ATTRIBUTE_KEY);
277: String attributeKey = attr instanceof String ? (String) attr
278: : null;
279: if (fBuildPathsBlock != null) {
280: fBuildPathsBlock.setElementToReveal(entry,
281: attributeKey);
282: }
283: }
284: Object entryToAdd = map.get(DATA_ADD_ENTRY);
285: if (entryToAdd instanceof IClasspathEntry) {
286: if (fBuildPathsBlock != null) {
287: fBuildPathsBlock
288: .addElement((IClasspathEntry) entryToAdd);
289: }
290: }
291: fBlockOnApply = Boolean.TRUE.equals(map.get(DATA_BLOCK));
292: }
293: }
294:
295: }
|