Skip to content

Commit 28920b0

Browse files
authored
Add project property page for folding (eclipse-jdt#1979)
- support setting folding preferences for a project in addition to the workspace - project settings do not allow setting of folding provider (workspace-only option)
1 parent f0ca579 commit 28920b0

12 files changed

+277
-61
lines changed

org.eclipse.jdt.ui/plugin.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,6 +1055,17 @@
10551055
<keywordReference id="org.eclipse.jdt.ui.saveparticipant"/>
10561056
</page>
10571057

1058+
<page
1059+
name="%editorFoldingPage"
1060+
class="org.eclipse.jdt.internal.ui.preferences.FoldingPreferencePage"
1061+
category="org.eclipse.jdt.ui.propertyPages.JavaEditorPropertyPage"
1062+
id="org.eclipse.jdt.ui.propertyPages.FoldingPreferencePage">
1063+
<enabledWhen>
1064+
<adapt type="org.eclipse.core.resources.IProject">
1065+
<test property="org.eclipse.core.resources.projectNature" value="org.eclipse.jdt.core.javanature"/>
1066+
</adapt>
1067+
</enabledWhen>
1068+
</page>
10581069
<page
10591070
name="%classpathContainerPageName"
10601071
class="org.eclipse.jdt.internal.ui.preferences.ClasspathContainerPreferencePage"

org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaEditor.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2024 IBM Corporation and others.
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -229,6 +229,7 @@
229229
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectNextAction;
230230
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectPreviousAction;
231231
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectionAction;
232+
import org.eclipse.jdt.internal.ui.preferences.FoldingPreferencePage;
232233
import org.eclipse.jdt.internal.ui.text.DocumentCharacterIterator;
233234
import org.eclipse.jdt.internal.ui.text.JavaChangeHover;
234235
import org.eclipse.jdt.internal.ui.text.JavaPairMatcher;
@@ -2055,6 +2056,7 @@ private IPreferenceStore createCombinedPreferenceStore(IEditorInput input) {
20552056

20562057
IJavaProject project= EditorUtility.getJavaProject(input);
20572058
if (project != null) {
2059+
stores.add(new EclipsePreferencesAdapter(new ProjectScope(project.getProject()), JavaUI.ID_PLUGIN));
20582060
stores.add(new EclipsePreferencesAdapter(new ProjectScope(project.getProject()), JavaCore.PLUGIN_ID));
20592061
}
20602062

@@ -3082,7 +3084,7 @@ protected void doSetSelection(ISelection selection) {
30823084
}
30833085

30843086
boolean isFoldingEnabled() {
3085-
return JavaPlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_FOLDING_ENABLED);
3087+
return FoldingPreferencePage.getFoldingPreferenceStore(this).getBoolean(PreferenceConstants.EDITOR_FOLDING_ENABLED);
30863088
}
30873089

30883090
/*

org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/FoldingConfigurationBlock.java

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2011 IBM Corporation and others.
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -35,9 +35,12 @@
3535
import org.eclipse.core.runtime.CoreException;
3636
import org.eclipse.core.runtime.IStatus;
3737
import org.eclipse.core.runtime.Status;
38+
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
39+
import org.eclipse.core.runtime.preferences.IScopeContext;
3840

3941
import org.eclipse.jface.dialogs.Dialog;
4042
import org.eclipse.jface.layout.PixelConverter;
43+
import org.eclipse.jface.preference.IPreferenceStore;
4144
import org.eclipse.jface.viewers.ArrayContentProvider;
4245
import org.eclipse.jface.viewers.ComboViewer;
4346
import org.eclipse.jface.viewers.IStructuredSelection;
@@ -46,8 +49,10 @@
4649

4750
import org.eclipse.jdt.internal.corext.util.Messages;
4851

52+
import org.eclipse.jdt.ui.JavaUI;
4953
import org.eclipse.jdt.ui.PreferenceConstants;
5054
import org.eclipse.jdt.ui.text.folding.IJavaFoldingPreferenceBlock;
55+
import org.eclipse.jdt.ui.text.folding.IScopedJavaFoldingPreferenceBlock;
5156

5257
import org.eclipse.jdt.internal.ui.JavaPlugin;
5358
import org.eclipse.jdt.internal.ui.preferences.OverlayPreferenceStore.OverlayKey;
@@ -61,7 +66,7 @@
6166
*
6267
* @since 3.0
6368
*/
64-
class FoldingConfigurationBlock implements IPreferenceConfigurationBlock {
69+
class FoldingConfigurationBlock implements IPreferenceAndPropertyConfigurationBlock {
6570

6671
private static class ErrorPreferences implements IJavaFoldingPreferenceBlock {
6772
private String fMessage;
@@ -117,14 +122,20 @@ public void dispose() {
117122
private final Map<String, IJavaFoldingPreferenceBlock> fProviderPreferences;
118123
private final Map<String, Control> fProviderControls;
119124

125+
private IScopeContext fContext;
120126

121-
public FoldingConfigurationBlock(OverlayPreferenceStore store) {
127+
private boolean fIsProjectPreferencePage;
128+
129+
130+
public FoldingConfigurationBlock(OverlayPreferenceStore store, IScopeContext context, boolean isProjectPreferencePage) {
122131
Assert.isNotNull(store);
123132
fStore= store;
124133
fStore.addKeys(createOverlayStoreKeys());
125134
fProviderDescriptors= createListModel();
126135
fProviderPreferences= new HashMap<>();
127136
fProviderControls= new HashMap<>();
137+
this.fContext= context;
138+
this.fIsProjectPreferencePage= isProjectPreferencePage;
128139
}
129140

130141
private Map<String, JavaFoldingStructureProviderDescriptor> createListModel() {
@@ -194,7 +205,7 @@ public void widgetDefaultSelected(SelectionEvent e) {
194205
gd= new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING);
195206
label.setLayoutData(gd);
196207

197-
if (fProviderDescriptors.size() > 1) {
208+
if (fProviderDescriptors.size() > 1 && !fIsProjectPreferencePage) {
198209
/* list */
199210
Composite comboComp= new Composite(composite, SWT.NONE);
200211
gd= new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING);
@@ -275,12 +286,12 @@ private void updateCheckboxDependencies() {
275286
}
276287

277288
void updateListDependencies() {
278-
String id= fStore.getString(PreferenceConstants.EDITOR_FOLDING_PROVIDER);
289+
String id= getGlobalPreferenceStore().getString(PreferenceConstants.EDITOR_FOLDING_PROVIDER);
279290
JavaFoldingStructureProviderDescriptor desc= fProviderDescriptors.get(id);
280291
IJavaFoldingPreferenceBlock prefs;
281292

282293
if (desc == null) {
283-
// safety in case there is no such descriptor
294+
// fallback in case there is no such descriptor
284295
String message= Messages.format(PreferencesMessages.FoldingConfigurationBlock_error_not_exist, id);
285296
JavaPlugin.log(new Status(IStatus.WARNING, JavaPlugin.getPluginId(), IStatus.OK, message, null));
286297
prefs= new ErrorPreferences(message);
@@ -289,6 +300,14 @@ void updateListDependencies() {
289300
if (prefs == null) {
290301
try {
291302
prefs= desc.createPreferences();
303+
if (fIsProjectPreferencePage) {
304+
if (prefs instanceof IScopedJavaFoldingPreferenceBlock scopedPrefs) {
305+
scopedPrefs.setScopeContext(fContext);
306+
} else {
307+
String message= Messages.format(PreferencesMessages.FoldingConfigurationBlock_error_project_prefs_not_supported, desc.getName());
308+
prefs= new ErrorPreferences(message);
309+
}
310+
}
292311
fProviderPreferences.put(id, prefs);
293312
} catch (CoreException e) {
294313
JavaPlugin.log(e);
@@ -348,25 +367,51 @@ private void restoreFromPreferences() {
348367
fFoldingCheckbox.setSelection(enabled);
349368
updateCheckboxDependencies();
350369

351-
String id= fStore.getString(PreferenceConstants.EDITOR_FOLDING_PROVIDER);
370+
IPreferenceStore globalStore = getGlobalPreferenceStore();
371+
372+
String id= globalStore.getString(PreferenceConstants.EDITOR_FOLDING_PROVIDER);
352373
Object provider= fProviderDescriptors.get(id);
353374

354375
// Fallback to default
355376
if (provider == null) {
356377
String message= Messages.format(PreferencesMessages.FoldingConfigurationBlock_warning_providerNotFound_resetToDefault, id);
357378
JavaPlugin.log(new Status(IStatus.WARNING, JavaPlugin.getPluginId(), IStatus.OK, message, null));
358379

359-
id= JavaPlugin.getDefault().getPreferenceStore().getDefaultString(PreferenceConstants.EDITOR_FOLDING_PROVIDER);
380+
id= globalStore.getDefaultString(PreferenceConstants.EDITOR_FOLDING_PROVIDER);
360381

361382
provider= fProviderDescriptors.get(id);
362383
Assert.isNotNull(provider);
363384

364-
fStore.setToDefault(PreferenceConstants.EDITOR_FOLDING_PROVIDER);
385+
globalStore.setToDefault(PreferenceConstants.EDITOR_FOLDING_PROVIDER);
365386
}
366387

367388
if (fProviderViewer == null)
368389
updateListDependencies();
369390
else
370391
fProviderViewer.setSelection(new StructuredSelection(provider), true);
371392
}
393+
394+
private IPreferenceStore getGlobalPreferenceStore() {
395+
return fIsProjectPreferencePage ? JavaPlugin.getDefault().getPreferenceStore() : fStore;
396+
}
397+
398+
@Override
399+
public void disableProjectSettings() {
400+
if(fContext != null) {
401+
IEclipsePreferences node= fContext.getNode(JavaUI.ID_PLUGIN);
402+
node.remove(PreferenceConstants.EDITOR_FOLDING_PROJECT_SPECIFIC_SETTINGS_ENABLED);
403+
// This preference used by the JavaEditor.
404+
// To make sure it reacts to this change, it must be removed from the project.
405+
node.remove(PreferenceConstants.EDITOR_FOLDING_ENABLED);
406+
// update the preference screen
407+
restoreFromPreferences();
408+
}
409+
}
410+
411+
@Override
412+
public void enableProjectSettings() {
413+
if(fContext != null) {
414+
fContext.getNode(JavaUI.ID_PLUGIN).putBoolean(PreferenceConstants.EDITOR_FOLDING_PROJECT_SPECIFIC_SETTINGS_ENABLED, true);
415+
}
416+
}
372417
}
Lines changed: 107 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2011 IBM Corporation and others.
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -15,53 +15,137 @@
1515
package org.eclipse.jdt.internal.ui.preferences;
1616

1717

18-
import org.eclipse.swt.widgets.Composite;
19-
import org.eclipse.swt.widgets.Label;
18+
import java.util.ArrayList;
19+
import java.util.List;
20+
21+
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
22+
import org.eclipse.core.runtime.preferences.IScopeContext;
23+
24+
import org.eclipse.core.resources.IProject;
25+
import org.eclipse.core.resources.ProjectScope;
26+
27+
import org.eclipse.jface.preference.IPreferenceStore;
28+
29+
import org.eclipse.ui.preferences.ScopedPreferenceStore;
30+
31+
import org.eclipse.jdt.core.IJavaProject;
32+
33+
import org.eclipse.jdt.ui.JavaUI;
34+
import org.eclipse.jdt.ui.PreferenceConstants;
2035

2136
import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
2237
import org.eclipse.jdt.internal.ui.JavaPlugin;
38+
import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
39+
import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
2340

2441
/**
2542
* The page for setting the editor options.
2643
*/
27-
public final class FoldingPreferencePage extends AbstractConfigurationBlockPreferencePage {
44+
public final class FoldingPreferencePage extends AbstractConfigurationBlockPreferenceAndPropertyPage {
45+
46+
public static final String PROPERTY_PAGE_ID= "org.eclipse.jdt.ui.propertyPages.FoldingPreferencePage"; //$NON-NLS-1$
47+
public static final String PREFERENCE_PAGE_ID= "org.eclipse.jdt.ui.preferences.FoldingPreferencePage"; //$NON-NLS-1$
48+
private OverlayPreferenceStore fOverlayStore;
49+
private IScopeContext fContext;
50+
51+
52+
public FoldingPreferencePage() {
53+
setDescription(PreferencesMessages.JavaEditorPreferencePage_folding_title);
54+
}
2855

2956
/*
30-
* @see org.eclipse.ui.internal.editors.text.AbstractConfigureationBlockPreferencePage#getHelpId()
57+
* @see org.eclipse.jdt.internal.ui.preferences.AbstractConfigurationBlockPreferenceAndPropertyPage#getHelpId()
3158
*/
3259
@Override
3360
protected String getHelpId() {
3461
return IJavaHelpContextIds.JAVA_EDITOR_PREFERENCE_PAGE;
3562
}
3663

37-
/*
38-
* @see org.eclipse.ui.internal.editors.text.AbstractConfigurationBlockPreferencePage#setDescription()
39-
*/
4064
@Override
41-
protected void setDescription() {
42-
String description= PreferencesMessages.JavaEditorPreferencePage_folding_title;
43-
setDescription(description);
65+
protected IPreferenceAndPropertyConfigurationBlock createConfigurationBlock(IScopeContext context) {
66+
this.fContext= context;
67+
ScopedPreferenceStore scopedStore= new ScopedPreferenceStore(context, JavaUI.ID_PLUGIN);
68+
fOverlayStore= new OverlayPreferenceStore(
69+
scopedStore,
70+
new OverlayPreferenceStore.OverlayKey[] {});
71+
FoldingConfigurationBlock foldingConfigurationBlock= new FoldingConfigurationBlock(fOverlayStore, context, isProjectPreferencePage());
72+
fOverlayStore.load();
73+
fOverlayStore.start();
74+
return foldingConfigurationBlock;
4475
}
4576

46-
/*
47-
* @see org.org.eclipse.ui.internal.editors.text.AbstractConfigurationBlockPreferencePage#setPreferenceStore()
48-
*/
4977
@Override
50-
protected void setPreferenceStore() {
51-
setPreferenceStore(JavaPlugin.getDefault().getPreferenceStore());
78+
protected boolean hasProjectSpecificOptions(IProject project) {
79+
return JavaPlugin.getDefault().getFoldingStructureProviderRegistry().hasProjectSpecificOptions(new ProjectScope(project));
5280
}
5381

82+
@Override
83+
protected String getPreferencePageID() {
84+
return PREFERENCE_PAGE_ID;
85+
}
5486

5587
@Override
56-
protected Label createDescriptionLabel(Composite parent) {
57-
return null; // no description for new look.
88+
protected String getPropertyPageID() {
89+
return PROPERTY_PAGE_ID;
5890
}
5991

60-
/*
61-
* @see org.eclipse.ui.internal.editors.text.AbstractConfigureationBlockPreferencePage#createConfigurationBlock(org.eclipse.ui.internal.editors.text.OverlayPreferenceStore)
62-
*/
6392
@Override
64-
protected IPreferenceConfigurationBlock createConfigurationBlock(OverlayPreferenceStore overlayPreferenceStore) {
65-
return new FoldingConfigurationBlock(overlayPreferenceStore);
93+
public boolean performOk() {
94+
boolean result= super.performOk();
95+
fOverlayStore.propagate();
96+
// When a boolean preference is put to its default value in OverlayPreferenceStore, it is removed
97+
// To ensure compatibility with ChainedPreferenceStore, it must be set manually
98+
IEclipsePreferences node= fContext.getNode(JavaUI.ID_PLUGIN);
99+
if(isProjectSpecificPreferencesEnabled(node)) {
100+
node.putBoolean(PreferenceConstants.EDITOR_FOLDING_ENABLED, fOverlayStore.getBoolean(PreferenceConstants.EDITOR_FOLDING_ENABLED));
101+
}
102+
return result;
103+
}
104+
105+
@Override
106+
public void performDefaults() {
107+
fOverlayStore.loadDefaults();
108+
super.performDefaults();
109+
110+
}
111+
112+
@Override
113+
public void dispose() {
114+
super.dispose();
115+
fOverlayStore.stop();
116+
}
117+
118+
public static IPreferenceStore getFoldingPreferenceStore(JavaEditor editor) {
119+
IJavaProject project= EditorUtility.getJavaProject(editor);
120+
if (project != null) {
121+
ProjectScope projectScope= new ProjectScope(project.getProject());
122+
if (isProjectSpecificPreferencesEnabled(projectScope.getNode(JavaUI.ID_PLUGIN))) {
123+
return getProjectPreferenceStore(projectScope);
124+
}
125+
}
126+
return getDefaultPreferenceStore();
127+
}
128+
129+
private static boolean isProjectSpecificPreferencesEnabled(IEclipsePreferences node) {
130+
return node.getBoolean(PreferenceConstants.EDITOR_FOLDING_PROJECT_SPECIFIC_SETTINGS_ENABLED, false);
131+
}
132+
133+
public static List<IPreferenceStore> getAllFoldingPreferenceStores(JavaEditor editor) {
134+
List<IPreferenceStore> preferenceStores= new ArrayList<>();
135+
preferenceStores.add(getDefaultPreferenceStore());
136+
IJavaProject project= EditorUtility.getJavaProject(editor);
137+
if (project != null) {
138+
ProjectScope projectScope= new ProjectScope(project.getProject());
139+
preferenceStores.add(getProjectPreferenceStore(projectScope));
140+
}
141+
return preferenceStores;
142+
}
143+
144+
private static ScopedPreferenceStore getProjectPreferenceStore(ProjectScope projectScope) {
145+
return new ScopedPreferenceStore(projectScope, JavaUI.ID_PLUGIN);
146+
}
147+
148+
private static IPreferenceStore getDefaultPreferenceStore() {
149+
return JavaPlugin.getDefault().getPreferenceStore();
66150
}
67151
}

org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2024 IBM Corporation and others.
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -773,6 +773,7 @@ private PreferencesMessages() {
773773
public static String FoldingConfigurationBlock_combo_caption;
774774
public static String FoldingConfigurationBlock_info_no_preferences;
775775
public static String FoldingConfigurationBlock_error_not_exist;
776+
public static String FoldingConfigurationBlock_error_project_prefs_not_supported;
776777
public static String FoldingConfigurationBlock_warning_providerNotFound_resetToDefault;
777778
public static String PropertiesFileEditorPreferencePage_key;
778779
public static String PropertiesFileEditorPreferencePage_value;

0 commit comments

Comments
 (0)