1 /*******************************************************************************
2 * Copyright (c) 2000, 2011 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.jdt.internal.ui.preferences;
13 import java.util.HashMap;
14 import java.util.HashSet;
17 import org.eclipse.swt.SWT;
18 import org.eclipse.swt.events.SelectionEvent;
19 import org.eclipse.swt.events.SelectionListener;
20 import org.eclipse.swt.layout.GridData;
21 import org.eclipse.swt.layout.GridLayout;
22 import org.eclipse.swt.widgets.Composite;
23 import org.eclipse.swt.widgets.Control;
24 import org.eclipse.swt.widgets.Label;
25 import org.eclipse.swt.widgets.Link;
27 import org.eclipse.core.runtime.IAdaptable;
28 import org.eclipse.core.runtime.IStatus;
30 import org.eclipse.core.resources.IProject;
31 import org.eclipse.core.resources.IResource;
32 import org.eclipse.core.resources.ResourcesPlugin;
34 import org.eclipse.jface.dialogs.ControlEnableState;
35 import org.eclipse.jface.dialogs.Dialog;
36 import org.eclipse.jface.preference.PreferencePage;
38 import org.eclipse.ui.IWorkbench;
39 import org.eclipse.ui.IWorkbenchPreferencePage;
40 import org.eclipse.ui.IWorkbenchPropertyPage;
41 import org.eclipse.ui.dialogs.PreferencesUtil;
43 import org.eclipse.jdt.core.IJavaProject;
44 import org.eclipse.jdt.core.JavaCore;
45 import org.eclipse.jdt.core.JavaModelException;
47 import org.eclipse.jdt.internal.ui.dialogs.StatusInfo;
48 import org.eclipse.jdt.internal.ui.dialogs.StatusUtil;
49 import org.eclipse.jdt.internal.ui.wizards.IStatusChangeListener;
50 import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField;
51 import org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
52 import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil;
53 import org.eclipse.jdt.internal.ui.wizards.dialogfields.SelectionButtonDialogField;
56 * Base for project property and preference pages
58 public abstract class PropertyAndPreferencePage extends PreferencePage implements IWorkbenchPreferencePage, IWorkbenchPropertyPage {
60 private Control fConfigurationBlockControl;
61 private ControlEnableState fBlockEnableState;
62 private Link fChangeWorkspaceSettings;
63 public SelectionButtonDialogField fUseProjectSettings;
64 private IStatus fBlockStatus;
65 private Composite fParentComposite;
67 private IProject fProject; // project or null
68 private Map<String, Object> fData; // page data
70 public static final String DATA_NO_LINK= "PropertyAndPreferencePage.nolink"; //$NON-NLS-1$
72 public PropertyAndPreferencePage() {
73 fBlockStatus= new StatusInfo();
74 fBlockEnableState= null;
79 protected abstract Control createPreferenceContent(Composite composite);
80 protected abstract boolean hasProjectSpecificOptions(IProject project);
82 protected abstract String getPreferencePageID();
83 protected abstract String getPropertyPageID();
85 protected boolean supportsProjectSpecificOptions() {
86 return getPropertyPageID() != null;
89 protected boolean offerLink() {
90 return fData == null || !Boolean.TRUE.equals(fData.get(DATA_NO_LINK));
94 protected Label createDescriptionLabel(Composite parent) {
95 fParentComposite= parent;
96 if (isProjectPreferencePage()) {
97 Composite composite= new Composite(parent, SWT.NONE);
98 composite.setFont(parent.getFont());
99 GridLayout layout= new GridLayout();
100 layout.marginHeight= 0;
101 layout.marginWidth= 0;
102 layout.numColumns= 2;
103 composite.setLayout(layout);
104 composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
106 IDialogFieldListener listener= new IDialogFieldListener() {
107 public void dialogFieldChanged(DialogField field) {
108 boolean enabled= ((SelectionButtonDialogField) field).isSelected();
109 enableProjectSpecificSettings(enabled);
111 if (enabled && getData() != null) {
112 applyData(getData());
117 fUseProjectSettings= new SelectionButtonDialogField(SWT.CHECK);
118 fUseProjectSettings.generated_3808165026892968926(composite, listener);
121 fChangeWorkspaceSettings= createLink(composite, PreferencesMessages.PropertyAndPreferencePage_useworkspacesettings_change);
122 fChangeWorkspaceSettings.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false));
124 LayoutUtil.setHorizontalSpan(fUseProjectSettings.getSelectionButton(null), 2);
127 Label horizontalLine= new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
128 horizontalLine.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false, 2, 1));
129 horizontalLine.setFont(composite.getFont());
130 } else if (supportsProjectSpecificOptions() && offerLink()) {
131 fChangeWorkspaceSettings= createLink(parent, PreferencesMessages.PropertyAndPreferencePage_showprojectspecificsettings_label);
132 fChangeWorkspaceSettings.setLayoutData(new GridData(SWT.END, SWT.CENTER, true, false));
135 return super.createDescriptionLabel(parent);
139 * @see org.eclipse.jface.preference.IPreferencePage#createContents(Composite)
142 protected Control createContents(Composite parent) {
143 Composite composite= new Composite(parent, SWT.NONE);
144 GridLayout layout= new GridLayout();
145 layout.marginHeight= 0;
146 layout.marginWidth= 0;
147 composite.setLayout(layout);
148 composite.setFont(parent.getFont());
150 GridData data= new GridData(GridData.FILL, GridData.FILL, true, true);
152 fConfigurationBlockControl= createPreferenceContent(composite);
153 fConfigurationBlockControl.setLayoutData(data);
155 if (isProjectPreferencePage()) {
156 boolean useProjectSettings= hasProjectSpecificOptions(getProject());
157 enableProjectSpecificSettings(useProjectSettings);
160 Dialog.applyDialogFont(composite);
164 private Link createLink(Composite composite, String text) {
165 Link link= new Link(composite, SWT.NONE);
166 link.setFont(composite.getFont());
167 link.setText("<A>" + text + "</A>"); //$NON-NLS-1$//$NON-NLS-2$
168 link.addSelectionListener(new SelectionListener() {
169 public void widgetSelected(SelectionEvent e) {
170 doLinkActivated((Link) e.widget);
173 public void widgetDefaultSelected(SelectionEvent e) {
174 doLinkActivated((Link) e.widget);
180 protected boolean useProjectSettings() {
181 return isProjectPreferencePage() && fUseProjectSettings != null && fUseProjectSettings.isSelected();
184 protected boolean isProjectPreferencePage() {
185 return fProject != null;
188 protected IProject getProject() {
193 * Handle link activation.
195 * @param link the link
197 final void doLinkActivated(Link link) {
198 Map<String, Object> data= getData();
200 data= new HashMap<String, Object>();
201 data.put(DATA_NO_LINK, Boolean.TRUE);
203 if (isProjectPreferencePage()) {
204 openWorkspacePreferences(data);
206 HashSet<IJavaProject> projectsWithSpecifics= new HashSet<IJavaProject>();
208 IJavaProject[] projects= JavaCore.create(ResourcesPlugin.getWorkspace().getRoot()).getJavaProjects();
209 for (int i= 0; i < projects.length; i++) {
210 IJavaProject curr= projects[i];
211 if (hasProjectSpecificOptions(curr.getProject())) {
212 projectsWithSpecifics.add(curr);
215 } catch (JavaModelException e) {
218 ProjectSelectionDialog dialog= new ProjectSelectionDialog(getShell(), projectsWithSpecifics);
219 dialog.generated_2705229931928849964(data, this);
223 protected final void openWorkspacePreferences(Object data) {
224 String id= getPreferencePageID();
225 PreferencesUtil.createPreferenceDialogOn(getShell(), id, new String[] { id }, data).open();
228 protected final void openProjectProperties(IProject project, Object data) {
229 String id= getPropertyPageID();
231 PreferencesUtil.createPropertyDialogOn(getShell(), project, id, new String[] { id }, data).open();
236 protected void enableProjectSpecificSettings(boolean useProjectSpecificSettings) {
237 fUseProjectSettings.setSelection(useProjectSpecificSettings);
238 enablePreferenceContent(useProjectSpecificSettings);
239 updateLinkVisibility();
243 private void updateLinkVisibility() {
244 if (fChangeWorkspaceSettings == null || fChangeWorkspaceSettings.isDisposed()) {
248 if (isProjectPreferencePage()) {
249 fChangeWorkspaceSettings.setEnabled(!useProjectSettings());
254 protected void setPreferenceContentStatus(IStatus status) {
255 fBlockStatus= status;
260 * Returns a new status change listener that calls {@link #setPreferenceContentStatus(IStatus)}
261 * when the status has changed
262 * @return The new listener
264 protected IStatusChangeListener getNewStatusChangedListener() {
265 return new IStatusChangeListener() {
266 public void statusChanged(IStatus status) {
267 setPreferenceContentStatus(status);
272 protected IStatus getPreferenceContentStatus() {
276 protected void doStatusChanged() {
277 if (!isProjectPreferencePage() || useProjectSettings()) {
278 updateStatus(fBlockStatus);
280 updateStatus(new StatusInfo());
284 protected void enablePreferenceContent(boolean enable) {
286 if (fBlockEnableState != null) {
287 fBlockEnableState.restore();
288 fBlockEnableState= null;
291 if (fBlockEnableState == null) {
292 fBlockEnableState= ControlEnableState.disable(fConfigurationBlockControl);
298 * @see org.eclipse.jface.preference.IPreferencePage#performDefaults()
301 protected void performDefaults() {
302 if (useProjectSettings()) {
303 enableProjectSpecificSettings(false);
305 super.performDefaults();
308 private void updateStatus(IStatus status) {
309 setValid(!status.matches(IStatus.ERROR));
310 StatusUtil.applyToStatusLine(this, status);
314 * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
316 public void init(IWorkbench workbench) {
320 * @see org.eclipse.ui.IWorkbenchPropertyPage#getElement()
322 public IAdaptable getElement() {
327 * @see org.eclipse.ui.IWorkbenchPropertyPage#setElement(org.eclipse.core.runtime.IAdaptable)
329 public void setElement(IAdaptable element) {
330 fProject= (IProject) element.getAdapter(IResource.class);
335 * @see org.eclipse.jface.preference.PreferencePage#applyData(java.lang.Object)
337 @SuppressWarnings("unchecked")
339 public void applyData(Object data) {
340 if (data instanceof Map) {
341 fData= (Map<String, Object>) data;
343 if (fChangeWorkspaceSettings != null) {
345 fChangeWorkspaceSettings.dispose();
346 fParentComposite.layout(true, true);
351 protected Map<String, Object> getData() {