001: /*******************************************************************************
002: * Copyright (c) 2000, 2005 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.util.HashMap;
013: import java.util.HashSet;
014: import java.util.Map;
015:
016: import org.eclipse.core.runtime.IAdaptable;
017: import org.eclipse.core.runtime.IStatus;
018:
019: import org.eclipse.core.resources.IProject;
020: import org.eclipse.core.resources.IResource;
021: import org.eclipse.core.resources.ResourcesPlugin;
022:
023: import org.eclipse.swt.SWT;
024: import org.eclipse.swt.events.SelectionEvent;
025: import org.eclipse.swt.events.SelectionListener;
026: import org.eclipse.swt.layout.GridData;
027: import org.eclipse.swt.layout.GridLayout;
028: import org.eclipse.swt.widgets.Composite;
029: import org.eclipse.swt.widgets.Control;
030: import org.eclipse.swt.widgets.Label;
031: import org.eclipse.swt.widgets.Link;
032:
033: import org.eclipse.jface.dialogs.ControlEnableState;
034: import org.eclipse.jface.dialogs.Dialog;
035: import org.eclipse.jface.preference.PreferencePage;
036: import org.eclipse.jface.window.Window;
037:
038: import org.eclipse.ui.IWorkbench;
039: import org.eclipse.ui.IWorkbenchPreferencePage;
040: import org.eclipse.ui.IWorkbenchPropertyPage;
041: import org.eclipse.ui.dialogs.PreferencesUtil;
042:
043: import org.eclipse.jdt.core.IJavaProject;
044: import org.eclipse.jdt.core.JavaCore;
045: import org.eclipse.jdt.core.JavaModelException;
046:
047: import org.eclipse.jdt.internal.ui.dialogs.StatusInfo;
048: import org.eclipse.jdt.internal.ui.dialogs.StatusUtil;
049: import org.eclipse.jdt.internal.ui.wizards.IStatusChangeListener;
050: import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField;
051: import org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
052: import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil;
053: import org.eclipse.jdt.internal.ui.wizards.dialogfields.SelectionButtonDialogField;
054:
055: /**
056: * Base for project property and preference pages
057: */
058: public abstract class PropertyAndPreferencePage extends PreferencePage
059: implements IWorkbenchPreferencePage, IWorkbenchPropertyPage {
060:
061: private Control fConfigurationBlockControl;
062: private ControlEnableState fBlockEnableState;
063: private Link fChangeWorkspaceSettings;
064: private SelectionButtonDialogField fUseProjectSettings;
065: private IStatus fBlockStatus;
066: private Composite fParentComposite;
067:
068: private IProject fProject; // project or null
069: private Map fData; // page data
070:
071: public static final String DATA_NO_LINK = "PropertyAndPreferencePage.nolink"; //$NON-NLS-1$
072:
073: public PropertyAndPreferencePage() {
074: fBlockStatus = new StatusInfo();
075: fBlockEnableState = null;
076: fProject = null;
077: fData = null;
078: }
079:
080: protected abstract Control createPreferenceContent(
081: Composite composite);
082:
083: protected abstract boolean hasProjectSpecificOptions(
084: IProject project);
085:
086: protected abstract String getPreferencePageID();
087:
088: protected abstract String getPropertyPageID();
089:
090: protected boolean supportsProjectSpecificOptions() {
091: return getPropertyPageID() != null;
092: }
093:
094: protected boolean offerLink() {
095: return fData == null
096: || !Boolean.TRUE.equals(fData.get(DATA_NO_LINK));
097: }
098:
099: protected Label createDescriptionLabel(Composite parent) {
100: fParentComposite = parent;
101: if (isProjectPreferencePage()) {
102: Composite composite = new Composite(parent, SWT.NONE);
103: composite.setFont(parent.getFont());
104: GridLayout layout = new GridLayout();
105: layout.marginHeight = 0;
106: layout.marginWidth = 0;
107: layout.numColumns = 2;
108: composite.setLayout(layout);
109: composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER,
110: true, false));
111:
112: IDialogFieldListener listener = new IDialogFieldListener() {
113: public void dialogFieldChanged(DialogField field) {
114: enableProjectSpecificSettings(((SelectionButtonDialogField) field)
115: .isSelected());
116: }
117: };
118:
119: fUseProjectSettings = new SelectionButtonDialogField(
120: SWT.CHECK);
121: fUseProjectSettings.setDialogFieldListener(listener);
122: fUseProjectSettings
123: .setLabelText(PreferencesMessages.PropertyAndPreferencePage_useprojectsettings_label);
124: fUseProjectSettings.doFillIntoGrid(composite, 1);
125: LayoutUtil.setHorizontalGrabbing(fUseProjectSettings
126: .getSelectionButton(null));
127:
128: if (offerLink()) {
129: fChangeWorkspaceSettings = createLink(
130: composite,
131: PreferencesMessages.PropertyAndPreferencePage_useworkspacesettings_change);
132: fChangeWorkspaceSettings.setLayoutData(new GridData(
133: SWT.END, SWT.CENTER, false, false));
134: } else {
135: LayoutUtil.setHorizontalSpan(fUseProjectSettings
136: .getSelectionButton(null), 2);
137: }
138:
139: Label horizontalLine = new Label(composite, SWT.SEPARATOR
140: | SWT.HORIZONTAL);
141: horizontalLine.setLayoutData(new GridData(GridData.FILL,
142: GridData.FILL, true, false, 2, 1));
143: horizontalLine.setFont(composite.getFont());
144: } else if (supportsProjectSpecificOptions() && offerLink()) {
145: fChangeWorkspaceSettings = createLink(
146: parent,
147: PreferencesMessages.PropertyAndPreferencePage_showprojectspecificsettings_label);
148: fChangeWorkspaceSettings.setLayoutData(new GridData(
149: SWT.END, SWT.CENTER, true, false));
150: }
151:
152: return super .createDescriptionLabel(parent);
153: }
154:
155: /*
156: * @see org.eclipse.jface.preference.IPreferencePage#createContents(Composite)
157: */
158: protected Control createContents(Composite parent) {
159: Composite composite = new Composite(parent, SWT.NONE);
160: GridLayout layout = new GridLayout();
161: layout.marginHeight = 0;
162: layout.marginWidth = 0;
163: composite.setLayout(layout);
164: composite.setFont(parent.getFont());
165:
166: GridData data = new GridData(GridData.FILL, GridData.FILL,
167: true, true);
168:
169: fConfigurationBlockControl = createPreferenceContent(composite);
170: fConfigurationBlockControl.setLayoutData(data);
171:
172: if (isProjectPreferencePage()) {
173: boolean useProjectSettings = hasProjectSpecificOptions(getProject());
174: enableProjectSpecificSettings(useProjectSettings);
175: }
176:
177: Dialog.applyDialogFont(composite);
178: return composite;
179: }
180:
181: private Link createLink(Composite composite, String text) {
182: Link link = new Link(composite, SWT.NONE);
183: link.setFont(composite.getFont());
184: link.setText("<A>" + text + "</A>"); //$NON-NLS-1$//$NON-NLS-2$
185: link.addSelectionListener(new SelectionListener() {
186: public void widgetSelected(SelectionEvent e) {
187: doLinkActivated((Link) e.widget);
188: }
189:
190: public void widgetDefaultSelected(SelectionEvent e) {
191: doLinkActivated((Link) e.widget);
192: }
193: });
194: return link;
195: }
196:
197: protected boolean useProjectSettings() {
198: return isProjectPreferencePage() && fUseProjectSettings != null
199: && fUseProjectSettings.isSelected();
200: }
201:
202: protected boolean isProjectPreferencePage() {
203: return fProject != null;
204: }
205:
206: protected IProject getProject() {
207: return fProject;
208: }
209:
210: final void doLinkActivated(Link link) {
211: Map data = new HashMap();
212: data.put(DATA_NO_LINK, Boolean.TRUE);
213:
214: if (isProjectPreferencePage()) {
215: openWorkspacePreferences(data);
216: } else {
217: HashSet projectsWithSpecifics = new HashSet();
218: try {
219: IJavaProject[] projects = JavaCore.create(
220: ResourcesPlugin.getWorkspace().getRoot())
221: .getJavaProjects();
222: for (int i = 0; i < projects.length; i++) {
223: IJavaProject curr = projects[i];
224: if (hasProjectSpecificOptions(curr.getProject())) {
225: projectsWithSpecifics.add(curr);
226: }
227: }
228: } catch (JavaModelException e) {
229: // ignore
230: }
231: ProjectSelectionDialog dialog = new ProjectSelectionDialog(
232: getShell(), projectsWithSpecifics);
233: if (dialog.open() == Window.OK) {
234: IJavaProject res = (IJavaProject) dialog
235: .getFirstResult();
236: openProjectProperties(res.getProject(), data);
237: }
238: }
239: }
240:
241: protected final void openWorkspacePreferences(Object data) {
242: String id = getPreferencePageID();
243: PreferencesUtil.createPreferenceDialogOn(getShell(), id,
244: new String[] { id }, data).open();
245: }
246:
247: protected final void openProjectProperties(IProject project,
248: Object data) {
249: String id = getPropertyPageID();
250: if (id != null) {
251: PreferencesUtil.createPropertyDialogOn(getShell(), project,
252: id, new String[] { id }, data).open();
253: }
254: }
255:
256: protected void enableProjectSpecificSettings(
257: boolean useProjectSpecificSettings) {
258: fUseProjectSettings.setSelection(useProjectSpecificSettings);
259: enablePreferenceContent(useProjectSpecificSettings);
260: updateLinkVisibility();
261: doStatusChanged();
262: }
263:
264: private void updateLinkVisibility() {
265: if (fChangeWorkspaceSettings == null
266: || fChangeWorkspaceSettings.isDisposed()) {
267: return;
268: }
269:
270: if (isProjectPreferencePage()) {
271: fChangeWorkspaceSettings.setEnabled(!useProjectSettings());
272: }
273: }
274:
275: protected void setPreferenceContentStatus(IStatus status) {
276: fBlockStatus = status;
277: doStatusChanged();
278: }
279:
280: /**
281: * Returns a new status change listener that calls {@link #setPreferenceContentStatus(IStatus)}
282: * when the status has changed
283: * @return The new listener
284: */
285: protected IStatusChangeListener getNewStatusChangedListener() {
286: return new IStatusChangeListener() {
287: public void statusChanged(IStatus status) {
288: setPreferenceContentStatus(status);
289: }
290: };
291: }
292:
293: protected IStatus getPreferenceContentStatus() {
294: return fBlockStatus;
295: }
296:
297: protected void doStatusChanged() {
298: if (!isProjectPreferencePage() || useProjectSettings()) {
299: updateStatus(fBlockStatus);
300: } else {
301: updateStatus(new StatusInfo());
302: }
303: }
304:
305: protected void enablePreferenceContent(boolean enable) {
306: if (enable) {
307: if (fBlockEnableState != null) {
308: fBlockEnableState.restore();
309: fBlockEnableState = null;
310: }
311: } else {
312: if (fBlockEnableState == null) {
313: fBlockEnableState = ControlEnableState
314: .disable(fConfigurationBlockControl);
315: }
316: }
317: }
318:
319: /*
320: * @see org.eclipse.jface.preference.IPreferencePage#performDefaults()
321: */
322: protected void performDefaults() {
323: if (useProjectSettings()) {
324: enableProjectSpecificSettings(false);
325: }
326: super .performDefaults();
327: }
328:
329: private void updateStatus(IStatus status) {
330: setValid(!status.matches(IStatus.ERROR));
331: StatusUtil.applyToStatusLine(this , status);
332: }
333:
334: /* (non-Javadoc)
335: * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
336: */
337: public void init(IWorkbench workbench) {
338: }
339:
340: /* (non-Javadoc)
341: * @see org.eclipse.ui.IWorkbenchPropertyPage#getElement()
342: */
343: public IAdaptable getElement() {
344: return fProject;
345: }
346:
347: /* (non-Javadoc)
348: * @see org.eclipse.ui.IWorkbenchPropertyPage#setElement(org.eclipse.core.runtime.IAdaptable)
349: */
350: public void setElement(IAdaptable element) {
351: fProject = (IProject) element.getAdapter(IResource.class);
352: }
353:
354: /* (non-Javadoc)
355: * @see org.eclipse.jface.preference.PreferencePage#applyData(java.lang.Object)
356: */
357: public void applyData(Object data) {
358: if (data instanceof Map) {
359: fData = (Map) data;
360: }
361: if (fChangeWorkspaceSettings != null) {
362: if (!offerLink()) {
363: fChangeWorkspaceSettings.dispose();
364: fParentComposite.layout(true, true);
365: }
366: }
367: }
368:
369: protected Map getData() {
370: return fData;
371: }
372:
373: }
|