diff --git a/core/org.eclipse.cdt.ui/ChangeLog b/core/org.eclipse.cdt.ui/ChangeLog index c7e6357f7bc..554408d514e 100644 --- a/core/org.eclipse.cdt.ui/ChangeLog +++ b/core/org.eclipse.cdt.ui/ChangeLog @@ -1,3 +1,34 @@ +2004-08-24 Alain Magloire + + Implementation for PR 69118: Folding. + Framework taken from the JDT folding adapted to C + + * src/org/eclipse/cdt/internal/ui/action/ActionMessages.java + * src/org/eclipse/cdt/internal/ui/action/FoldingActionGroup.java + + * src/org/eclipse/cdt/internal/ui/editor/CEditor.java + + * src/org/eclipse/cdt/internal/ui/preference/CEditorPreferencePage.java + * src/org/eclipse/cdt/internal/ui/preference/FoldingConfigurationBlock.java + * src/org/eclipse/cdt/internal/ui/preference/PreferencesMessages.properties + + * src/org/eclipse/cdt/internal/ui/text/folding/CFoldingStructureProviderDescriptor.java + * src/org/eclipse/cdt/internal/ui/text/folding/CFoldingStructureProviderRegistry.java + * src/org/eclipse/cdt/internal/ui/text/folding/DefaultCFoldingPreferenceBlock.java + * src/org/eclipse/cdt/internal/ui/text/folding/DefaultCFoldingStructureProvider.java + * src/org/eclipse/cdt/internal/ui/text/folding/EmptyCFoldingPrefernceBlock.java + * src/org/eclipse/cdt/internal/ui/text/folding/FoldingMessages.java + * src/org/eclipse/cdt/internal/ui/text/folding/FoldingMessages.properties + + * src/org/eclipse/cdt/ui/CUIPlugin.java + * src/org/eclipse/cdt/ui/PreferenceConstants.java + + * src/org/eclipse/cdt/ui/text/folding/ICFoldingPreferenceBlock.java + * src/org/eclipse/cdt/ui/text/folding/ICFoldingStructureProvider.java + + * plugin.properties + * plugin.xml + 2004-08-24 Chris Wiebe fix sorting bug diff --git a/core/org.eclipse.cdt.ui/plugin.properties b/core/org.eclipse.cdt.ui/plugin.properties index 454f8f43d48..4cb83b80219 100644 --- a/core/org.eclipse.cdt.ui/plugin.properties +++ b/core/org.eclipse.cdt.ui/plugin.properties @@ -245,3 +245,9 @@ problemHoverDescription= Shows the description of the selected problem. # appearancePrefName= Appearance + +#--- folding +foldingStructureProvidersExtensionPoint= Folding Structure Providers +defaultFoldingStructureProviderName= Default C Folding +Folding.label= F&olding + diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml index bfd88dc0a49..08d062d7290 100644 --- a/core/org.eclipse.cdt.ui/plugin.xml +++ b/core/org.eclipse.cdt.ui/plugin.xml @@ -34,6 +34,9 @@ + + + @@ -928,4 +931,16 @@ point="org.eclipse.core.runtime.preferences"> + + + + + + + diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/ActionMessages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/ActionMessages.java index 109ab38e441..1a1ec058189 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/ActionMessages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/ActionMessages.java @@ -35,6 +35,17 @@ public class ActionMessages { // no instance } + /** + * Returns the resource bundle managed by the receiver. + * + * @return the resource bundle + * @since 3.0 + */ + public static ResourceBundle getResourceBundle() { + return fgResourceBundle; + } + + /** * Returns the resource string associated with the given key in the resource bundle. If there isn't * any value under the given key, the key is returned. diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/FoldingActionGroup.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/FoldingActionGroup.java new file mode 100644 index 00000000000..f415662927f --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/FoldingActionGroup.java @@ -0,0 +1,141 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.actions; + +import org.eclipse.jface.action.IMenuManager; + +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.source.projection.IProjectionListener; +import org.eclipse.jface.text.source.projection.ProjectionViewer; + +import org.eclipse.ui.actions.ActionGroup; +import org.eclipse.ui.editors.text.IFoldingCommandIds; +import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.ui.texteditor.TextOperationAction; + + +/** + * Groups the JDT folding actions. + * + * @since 3.0 + */ +public class FoldingActionGroup extends ActionGroup { + private ProjectionViewer fViewer; + + private TextOperationAction fToggle; + private TextOperationAction fExpand; + private TextOperationAction fCollapse; + private TextOperationAction fExpandAll; + + private IProjectionListener fProjectionListener; + + /** + * Creates a new projection action group for editor. If the + * supplied viewer is not an instance of ProjectionViewer, the + * action group is disabled. + * + * @param editor the text editor to operate on + * @param viewer the viewer of the editor + */ + public FoldingActionGroup(ITextEditor editor, ITextViewer viewer) { + if (viewer instanceof ProjectionViewer) { + fViewer= (ProjectionViewer) viewer; + + fProjectionListener= new IProjectionListener() { + + public void projectionEnabled() { + update(); + } + + public void projectionDisabled() { + update(); + } + }; + + fViewer.addProjectionListener(fProjectionListener); + + fToggle= new TextOperationAction(ActionMessages.getResourceBundle(), "Projection.Toggle.", editor, ProjectionViewer.TOGGLE, true); //$NON-NLS-1$ + fToggle.setChecked(true); + fToggle.setActionDefinitionId(IFoldingCommandIds.FOLDING_TOGGLE); + editor.setAction("FoldingToggle", fToggle); //$NON-NLS-1$ + + fExpandAll= new TextOperationAction(ActionMessages.getResourceBundle(), "Projection.ExpandAll.", editor, ProjectionViewer.EXPAND_ALL, true); //$NON-NLS-1$ + fExpandAll.setActionDefinitionId(IFoldingCommandIds.FOLDING_EXPAND_ALL); + editor.setAction("FoldingExpandAll", fExpandAll); //$NON-NLS-1$ + + fExpand= new TextOperationAction(ActionMessages.getResourceBundle(), "Projection.Expand.", editor, ProjectionViewer.EXPAND, true); //$NON-NLS-1$ + fExpand.setActionDefinitionId(IFoldingCommandIds.FOLDING_EXPAND); + editor.setAction("FoldingExpand", fExpand); //$NON-NLS-1$ + + fCollapse= new TextOperationAction(ActionMessages.getResourceBundle(), "Projection.Collapse.", editor, ProjectionViewer.COLLAPSE, true); //$NON-NLS-1$ + fCollapse.setActionDefinitionId(IFoldingCommandIds.FOLDING_COLLAPSE); + editor.setAction("FoldingCollapse", fCollapse); //$NON-NLS-1$ + } + } + + /** + * Returns true if the group is enabled. + *
+	 * Invariant: isEnabled() <=> fViewer and all actions are != null.
+	 * 
+ * + * @return true if the group is enabled + */ + protected boolean isEnabled() { + return fViewer != null; + } + + /* + * @see org.eclipse.ui.actions.ActionGroup#dispose() + */ + public void dispose() { + if (isEnabled()) { + fViewer.removeProjectionListener(fProjectionListener); + fViewer= null; + } + super.dispose(); + } + + /** + * Updates the actions. + */ + protected void update() { + if (isEnabled()) { + fToggle.update(); + fToggle.setChecked(fViewer.getProjectionAnnotationModel() != null); + fExpand.update(); + fExpandAll.update(); + fCollapse.update(); + } + } + + /** + * Fills the menu with all folding actions. + * + * @param manager the menu manager for the folding submenu + */ + public void fillMenu(IMenuManager manager) { + if (isEnabled()) { + update(); + manager.add(fToggle); + manager.add(fExpandAll); + manager.add(fExpand); + manager.add(fCollapse); + } + } + + /* + * @see org.eclipse.ui.actions.ActionGroup#updateActionBars() + */ + public void updateActionBars() { + update(); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java index ca6c4be9e67..c065d27d004 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java @@ -21,6 +21,7 @@ import org.eclipse.cdt.core.model.ISourceReference; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.internal.ui.ICHelpContextIds; import org.eclipse.cdt.internal.ui.IContextMenuConstants; +import org.eclipse.cdt.internal.ui.actions.FoldingActionGroup; import org.eclipse.cdt.internal.ui.browser.typehierarchy.OpenTypeHierarchyAction; import org.eclipse.cdt.internal.ui.editor.asm.AsmTextTools; import org.eclipse.cdt.internal.ui.search.actions.OpenDeclarationsAction; @@ -31,8 +32,10 @@ import org.eclipse.cdt.internal.ui.text.CTextTools; import org.eclipse.cdt.internal.ui.text.contentassist.ContentAssistPreference; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.IWorkingCopyManager; +import org.eclipse.cdt.ui.PreferenceConstants; import org.eclipse.cdt.ui.actions.RefactoringActionGroup; import org.eclipse.cdt.ui.actions.ShowInCViewAction; +import org.eclipse.cdt.ui.text.folding.ICFoldingStructureProvider; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; @@ -58,8 +61,10 @@ import org.eclipse.jface.text.source.IOverviewRuler; import org.eclipse.jface.text.source.ISharedTextColors; import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.jface.text.source.IVerticalRuler; -import org.eclipse.jface.text.source.SourceViewer; import org.eclipse.jface.text.source.SourceViewerConfiguration; +import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel; +import org.eclipse.jface.text.source.projection.ProjectionSupport; +import org.eclipse.jface.text.source.projection.ProjectionViewer; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; @@ -73,6 +78,7 @@ import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IEditorActionBarContributor; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IFileEditorInput; +import org.eclipse.ui.IPageLayout; import org.eclipse.ui.IPartService; import org.eclipse.ui.IViewPart; import org.eclipse.ui.IWorkbenchPage; @@ -84,6 +90,7 @@ import org.eclipse.ui.help.WorkbenchHelp; import org.eclipse.ui.ide.IDE; import org.eclipse.ui.part.EditorActionBarContributor; import org.eclipse.ui.part.IShowInSource; +import org.eclipse.ui.part.IShowInTargetList; import org.eclipse.ui.part.ShowInContext; import org.eclipse.ui.texteditor.ChainedPreferenceStore; import org.eclipse.ui.texteditor.ContentAssistAction; @@ -144,6 +151,22 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS /** Preference key for hyperlink enablement */ public final static String HYPERLINK_ENABLED = "hyperlinkEnable"; //$NON-NLS-1$ + /** + * This editor's projection support + */ + private ProjectionSupport fProjectionSupport; + /** + * This editor's projection model updater + */ + private ICFoldingStructureProvider fProjectionModelUpdater; + + /** + * The action group for folding. + * + */ + private FoldingActionGroup fFoldingGroup; + + private class PropertyChangeListener implements org.eclipse.core.runtime.Preferences.IPropertyChangeListener, org.eclipse.jface.util.IPropertyChangeListener { /* * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent) @@ -193,6 +216,10 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS fCEditorErrorTickUpdater.setAnnotationModel(getDocumentProvider().getAnnotationModel(input)); } setOutlinePageInput(fOutlinePage, input); + + if (fProjectionModelUpdater != null) { + fProjectionModelUpdater.initialize(); + } } /** @@ -237,6 +264,21 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS if (IContentOutlinePage.class.equals(required)) { return getOutlinePage(); } + if (required == IShowInTargetList.class) { + return new IShowInTargetList() { + public String[] getShowInTargetIds() { + return new String[] { CUIPlugin.CVIEW_ID, IPageLayout.ID_OUTLINE, IPageLayout.ID_RES_NAV }; + } + + }; + } + if (ProjectionAnnotationModel.class.equals(required)) { + if (fProjectionSupport != null) { + Object adapter= fProjectionSupport.getAdapter(getSourceViewer(), required); + if (adapter != null) + return adapter; + } + } return super.getAdapter(required); } /** @@ -289,7 +331,21 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS disableBrowserLikeLinks(); return; } - + + if (PreferenceConstants.EDITOR_FOLDING_PROVIDER.equals(property)) { + if (asv instanceof ProjectionViewer) { + ProjectionViewer projectionViewer= (ProjectionViewer) asv; + if (fProjectionModelUpdater != null) + fProjectionModelUpdater.uninstall(); + // either freshly enabled or provider changed + fProjectionModelUpdater= CUIPlugin.getDefault().getFoldingStructureProviderRegistry().getCurrentFoldingProvider(); + if (fProjectionModelUpdater != null) { + fProjectionModelUpdater.install(this, projectionViewer); + } + } + return; + } + IContentAssistant c= asv.getContentAssistant(); if (c instanceof ContentAssistant) ContentAssistPreference.changeConfiguration((ContentAssistant) c, getPreferenceStore(), event); @@ -428,6 +484,16 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS public void dispose() { + if (fProjectionModelUpdater != null) { + fProjectionModelUpdater.uninstall(); + fProjectionModelUpdater= null; + } + + if (fProjectionSupport != null) { + fProjectionSupport.dispose(); + fProjectionSupport= null; + } + if (fCEditorErrorTickUpdater != null) { fCEditorErrorTickUpdater.setAnnotationModel(null); fCEditorErrorTickUpdater.dispose(); @@ -440,7 +506,6 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS IPreferenceStore preferenceStore = getPreferenceStore(); preferenceStore.removePropertyChangeListener(fPropertyChangeListener); fPropertyChangeListener = null; - } if (fSelectionUpdateListener != null) { @@ -478,7 +543,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS fSelectionSearchGroup.dispose(); fSelectionSearchGroup = null; } - + stopTabConversion(); disableBrowserLikeLinks(); @@ -518,6 +583,8 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS protected void createActions() { super.createActions(); + fFoldingGroup= new FoldingActionGroup(this, getSourceViewer()); + // Default text editing menu items IAction action = new TextOperationAction(CEditorMessages.getResourceBundle(), "Comment.", this, ITextOperationTarget.PREFIX); //$NON-NLS-1$ @@ -603,6 +670,11 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS } } + boolean isFoldingEnabled() { + return CUIPlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_FOLDING_ENABLED); + } + + /** * The AbstractTextEditor implementation of this * IWorkbenchPart method creates the vertical ruler and @@ -614,6 +686,27 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS */ public void createPartControl(Composite parent) { super.createPartControl(parent); + + ProjectionViewer projectionViewer= (ProjectionViewer) getSourceViewer(); + + fProjectionSupport= new ProjectionSupport(projectionViewer, getAnnotationAccess(), getSharedColors()); + fProjectionSupport.addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.error"); //$NON-NLS-1$ + fProjectionSupport.addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.warning"); //$NON-NLS-1$ +// fProjectionSupport.setHoverControlCreator(new IInformationControlCreator() { +// public IInformationControl createInformationControl(Shell shell) { +// return new CustomSourceInformationControl(shell, IDocument.DEFAULT_CONTENT_TYPE); +// } +// }); + fProjectionSupport.install(); + + fProjectionModelUpdater= CUIPlugin.getDefault().getFoldingStructureProviderRegistry().getCurrentFoldingProvider(); + if (fProjectionModelUpdater != null) + fProjectionModelUpdater.install(this, projectionViewer); + + if (isFoldingEnabled()) + projectionViewer.doOperation(ProjectionViewer.TOGGLE); + + WorkbenchHelp.setHelp(parent, ICHelpContextIds.CEDITOR_VIEW); fSelectionUpdateListener = new ISelectionChangedListener() { private Runnable fRunnable = new Runnable() { @@ -831,7 +924,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS * Adapted source viewer for CEditor */ - public class AdaptedSourceViewer extends SourceViewer implements ITextViewerExtension { + public class AdaptedSourceViewer extends ProjectionViewer implements ITextViewerExtension { private List fTextConverters; private String fDisplayLanguage; @@ -975,6 +1068,43 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS return textTools.affectsBehavior(event) || asmTools.affectsBehavior(event); } + /** + * Returns the folding action group, or null if there is none. + * + * @return the folding action group, or null if there is none + */ + protected FoldingActionGroup getFoldingActionGroup() { + return fFoldingGroup; + } + + /* + * @see org.eclipse.ui.texteditor.AbstractTextEditor#performRevert() + */ + protected void performRevert() { + ProjectionViewer projectionViewer= (ProjectionViewer) getSourceViewer(); + projectionViewer.setRedraw(false); + try { + + boolean projectionMode= projectionViewer.isProjectionMode(); + if (projectionMode) { + projectionViewer.disableProjection(); + if (fProjectionModelUpdater != null) + fProjectionModelUpdater.uninstall(); + } + + super.performRevert(); + + if (projectionMode) { + if (fProjectionModelUpdater != null) + fProjectionModelUpdater.install(this, projectionViewer); + projectionViewer.enableProjection(); + } + + } finally { + projectionViewer.setRedraw(true); + } + } + /** * Handles a property change event describing a change * of the C core's preferences and updates the preference diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CEditorPreferencePage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CEditorPreferencePage.java index 79d0dda4952..cc644c91eaa 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CEditorPreferencePage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CEditorPreferencePage.java @@ -67,12 +67,12 @@ import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants; public class CEditorPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { protected final String[][] fListModel = new String[][] { { PreferencesMessages.getString("CEditorPreferencePage.cCommentTaskTags.MultiLine"), ICColorConstants.C_MULTI_LINE_COMMENT }, { //$NON-NLS-1$ - PreferencesMessages.getString("CEditorPreferencePage.cCommentTaskTags.singleLine"), ICColorConstants.C_SINGLE_LINE_COMMENT }, { //$NON-NLS-1$ - PreferencesMessages.getString("CEditorPreferencePage.cCommentTaskTags.keywords"), ICColorConstants.C_KEYWORD }, { //$NON-NLS-1$ - PreferencesMessages.getString("CEditorPreferencePage.cCommentTaskTags.builtInTypes"), ICColorConstants.C_TYPE }, { //$NON-NLS-1$ - PreferencesMessages.getString("CEditorPreferencePage.cCommentTaskTags.strings"), ICColorConstants.C_STRING }, { //$NON-NLS-1$ - PreferencesMessages.getString("CEditorPreferencePage.cCommentTaskTags.others"), ICColorConstants.C_DEFAULT }, { //$NON-NLS-1$ - PreferencesMessages.getString("CEditorPreferencePage.cCommentTaskTags"), PreferenceConstants.EDITOR_TASK_TAG_COLOR } //$NON-NLS-1$ + PreferencesMessages.getString("CEditorPreferencePage.cCommentTaskTags.singleLine"), ICColorConstants.C_SINGLE_LINE_COMMENT }, { //$NON-NLS-1$ + PreferencesMessages.getString("CEditorPreferencePage.cCommentTaskTags.keywords"), ICColorConstants.C_KEYWORD }, { //$NON-NLS-1$ + PreferencesMessages.getString("CEditorPreferencePage.cCommentTaskTags.builtInTypes"), ICColorConstants.C_TYPE }, { //$NON-NLS-1$ + PreferencesMessages.getString("CEditorPreferencePage.cCommentTaskTags.strings"), ICColorConstants.C_STRING }, { //$NON-NLS-1$ + PreferencesMessages.getString("CEditorPreferencePage.cCommentTaskTags.others"), ICColorConstants.C_DEFAULT }, { //$NON-NLS-1$ + PreferencesMessages.getString("CEditorPreferencePage.cCommentTaskTags"), PreferenceConstants.EDITOR_TASK_TAG_COLOR } //$NON-NLS-1$ }; protected final String[][] fAppearanceColorListModel = new String[][] { { PreferencesMessages.getString("CEditorPreferencePage.behaviorPage.lineNumberColor"), AbstractDecoratedTextEditorPreferenceConstants.EDITOR_LINE_NUMBER_RULER_COLOR, null }, //$NON-NLS-1$ @@ -82,7 +82,6 @@ public class CEditorPreferencePage extends PreferencePage implements IWorkbenchP {PreferencesMessages.getString("CEditorPreferencePage.behaviorPage.linkedPositionColor"), CEditor.LINKED_POSITION_COLOR, null }, //$NON-NLS-1$ {PreferencesMessages.getString("CEditorPreferencePage.behaviorPage.selectionForegroundColor"), AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_FOREGROUND_COLOR, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_FOREGROUND_DEFAULT_COLOR}, //$NON-NLS-1$ {PreferencesMessages.getString("CEditorPreferencePage.behaviorPage.selectionBackgroundColor"), AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_BACKGROUND_COLOR, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_BACKGROUND_DEFAULT_COLOR}, //$NON-NLS-1$ - }; protected OverlayPreferenceStore fOverlayStore; @@ -136,6 +135,8 @@ public class CEditorPreferencePage extends PreferencePage implements IWorkbenchP protected ColorEditor fAppearanceColorEditor; private Button fAppearanceColorDefault; private CEditorHoverConfigurationBlock fCEditorHoverConfigurationBlock; + private FoldingConfigurationBlock fFoldingConfigurationBlock; + public CEditorPreferencePage() { setDescription(CUIPlugin.getResourceString("CEditorPreferencePage.description")); //$NON-NLS-1$ @@ -827,6 +828,7 @@ public class CEditorPreferencePage extends PreferencePage implements IWorkbenchP initializeDefaultColors(); fCEditorHoverConfigurationBlock= new CEditorHoverConfigurationBlock(this, fOverlayStore); + fFoldingConfigurationBlock= new FoldingConfigurationBlock(fOverlayStore); fOverlayStore.load(); fOverlayStore.start(); @@ -855,6 +857,9 @@ public class CEditorPreferencePage extends PreferencePage implements IWorkbenchP item.setImage(CPluginImages.get(CPluginImages.IMG_OBJS_TUNIT)); item.setControl(fCEditorHoverConfigurationBlock.createControl(folder)); + item= new TabItem(folder, SWT.NONE); + item.setText(PreferencesMessages.getString("CEditorPreferencePage.folding.title")); //$NON-NLS-1$ + item.setControl(fFoldingConfigurationBlock.createControl(folder)); item = new TabItem(folder, SWT.NONE); item.setText(PreferencesMessages.getString("CEditorPreferencePage.Navigation")); //$NON-NLS-1$ @@ -910,6 +915,8 @@ public class CEditorPreferencePage extends PreferencePage implements IWorkbenchP } }); + fFoldingConfigurationBlock.initialize(); + } private void initializeFields() { @@ -958,6 +965,7 @@ public class CEditorPreferencePage extends PreferencePage implements IWorkbenchP */ public boolean performOk() { fCEditorHoverConfigurationBlock.performOk(); + fFoldingConfigurationBlock.performOk(); fOverlayStore.propagate(); return true; } @@ -973,6 +981,7 @@ public class CEditorPreferencePage extends PreferencePage implements IWorkbenchP handleAppearanceColorListSelection(); fCEditorHoverConfigurationBlock.performDefaults(); + fFoldingConfigurationBlock.performDefaults(); super.performDefaults(); @@ -984,6 +993,8 @@ public class CEditorPreferencePage extends PreferencePage implements IWorkbenchP */ public void dispose() { + fFoldingConfigurationBlock.dispose(); + if (fCTextTools != null) { fCTextTools = null; } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/FoldingConfigurationBlock.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/FoldingConfigurationBlock.java new file mode 100644 index 00000000000..2fb87c67846 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/FoldingConfigurationBlock.java @@ -0,0 +1,349 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.ui.preferences; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.cdt.internal.ui.text.folding.CFoldingStructureProviderDescriptor; +import org.eclipse.cdt.internal.ui.text.folding.CFoldingStructureProviderRegistry; +import org.eclipse.cdt.internal.ui.util.PixelConverter; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.ui.PreferenceConstants; +import org.eclipse.cdt.ui.text.folding.ICFoldingPreferenceBlock; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.text.Assert; +import org.eclipse.jface.viewers.ComboViewer; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StackLayout; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; + +/** + * Configures C Editor folding preferences. + * + * @since 3.0 + */ +class FoldingConfigurationBlock { + + private static class ErrorPreferences implements ICFoldingPreferenceBlock { + private String fMessage; + + protected ErrorPreferences(String message) { + fMessage= message; + } + + /* + * @see org.eclipse.cdt.internal.ui.text.folding.ICFoldingPreferences#createControl(org.eclipse.swt.widgets.Group) + */ + public Control createControl(Composite composite) { + Composite inner= new Composite(composite, SWT.NONE); + inner.setLayout(new FillLayout(SWT.VERTICAL)); + + Label label= new Label(inner, SWT.CENTER); + label.setText(fMessage); + + return inner; + } + + public void initialize() { + } + + public void performOk() { + } + + public void performDefaults() { + } + + public void dispose() { + } + + } + + /** The overlay preference store. */ + protected final OverlayPreferenceStore fStore; + + /* The controls */ + private Combo fProviderCombo; + protected Button fFoldingCheckbox; + private ComboViewer fProviderViewer; + protected Map fProviderDescriptors; + private Composite fGroup; + private Map fProviderPreferences; + private Map fProviderControls; + private StackLayout fStackLayout; + + + public FoldingConfigurationBlock(OverlayPreferenceStore store) { + Assert.isNotNull(store); + fStore= store; + fStore.addKeys(createOverlayStoreKeys()); + fProviderDescriptors= createListModel(); + fProviderPreferences= new HashMap(); + fProviderControls= new HashMap(); + } + + private Map createListModel() { + CFoldingStructureProviderRegistry reg= CUIPlugin.getDefault().getFoldingStructureProviderRegistry(); + reg.reloadExtensions(); + CFoldingStructureProviderDescriptor[] descs= reg.getFoldingProviderDescriptors(); + Map map= new HashMap(); + for (int i= 0; i < descs.length; i++) { + map.put(descs[i].getId(), descs[i]); + } + return map; + } + + private OverlayPreferenceStore.OverlayKey[] createOverlayStoreKeys() { + + ArrayList overlayKeys= new ArrayList(); + + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_FOLDING_ENABLED)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.EDITOR_FOLDING_PROVIDER)); + + OverlayPreferenceStore.OverlayKey[] keys= new OverlayPreferenceStore.OverlayKey[overlayKeys.size()]; + overlayKeys.toArray(keys); + return keys; + } + + /** + * Creates page for folding preferences. + * + * @param parent the parent composite + * @return the control for the preference page + */ + Control createControl(Composite parent) { + + Composite composite= new Composite(parent, SWT.NULL); + // assume parent page uses griddata + GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_CENTER | GridData.VERTICAL_ALIGN_FILL); + composite.setLayoutData(gd); + GridLayout layout= new GridLayout(); + layout.numColumns= 2; + PixelConverter pc= new PixelConverter(composite); + layout.verticalSpacing= pc.convertHeightInCharsToPixels(1) / 2; + composite.setLayout(layout); + + + /* check box for new editors */ + fFoldingCheckbox= new Button(composite, SWT.CHECK); + fFoldingCheckbox.setText(PreferencesMessages.getString("FoldingConfigurationBlock.enable")); //$NON-NLS-1$ + gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING); + fFoldingCheckbox.setLayoutData(gd); + fFoldingCheckbox.addSelectionListener(new SelectionListener() { + public void widgetSelected(SelectionEvent e) { + boolean enabled= fFoldingCheckbox.getSelection(); + fStore.setValue(PreferenceConstants.EDITOR_FOLDING_ENABLED, enabled); + updateCheckboxDependencies(); + } + + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + + Label label= new Label(composite, SWT.CENTER); + gd= new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING); + label.setLayoutData(gd); + + /* list */ + Composite comboComp= new Composite(composite, SWT.NONE); + gd= new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING); + GridLayout gridLayout= new GridLayout(2, false); + gridLayout.marginWidth= 0; + comboComp.setLayout(gridLayout); + + Label comboLabel= new Label(comboComp, SWT.CENTER); + gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_CENTER); + comboLabel.setLayoutData(gd); + comboLabel.setText(PreferencesMessages.getString("FoldingConfigurationBlock.combo_caption")); //$NON-NLS-1$ + + label= new Label(composite, SWT.CENTER); + gd= new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING); + label.setLayoutData(gd); + + fProviderCombo= new Combo(comboComp, SWT.READ_ONLY | SWT.DROP_DOWN); + gd= new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.VERTICAL_ALIGN_CENTER); + fProviderCombo.setLayoutData(gd); + + /* list viewer */ + fProviderViewer= new ComboViewer(fProviderCombo); + fProviderViewer.setContentProvider(new IStructuredContentProvider() { + + /* + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public void dispose() { + } + + /* + * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + /* + * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) + */ + public Object[] getElements(Object inputElement) { + return fProviderDescriptors.values().toArray(); + } + }); + fProviderViewer.setLabelProvider(new LabelProvider() { + /* + * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object) + */ + public Image getImage(Object element) { + return null; + } + + /* + * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object) + */ + public String getText(Object element) { + return ((CFoldingStructureProviderDescriptor) element).getName(); + } + }); + fProviderViewer.addSelectionChangedListener(new ISelectionChangedListener() { + + public void selectionChanged(SelectionChangedEvent event) { + IStructuredSelection sel= (IStructuredSelection) event.getSelection(); + if (!sel.isEmpty()) { + fStore.setValue(PreferenceConstants.EDITOR_FOLDING_PROVIDER, ((CFoldingStructureProviderDescriptor) sel.getFirstElement()).getId()); + updateListDependencies(); + } + } + }); + fProviderViewer.setInput(fProviderDescriptors); + fProviderViewer.refresh(); + + Composite groupComp= new Composite(composite, SWT.NONE); + gd= new GridData(GridData.FILL_BOTH); + gd.horizontalSpan= 2; + groupComp.setLayoutData(gd); + gridLayout= new GridLayout(1, false); + gridLayout.marginWidth= 0; + groupComp.setLayout(gridLayout); + + /* contributed provider preferences. */ + fGroup= new Composite(groupComp, SWT.NONE); + gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING); + fGroup.setLayoutData(gd); + fStackLayout= new StackLayout(); + fGroup.setLayout(fStackLayout); + + return composite; + } + + protected void updateCheckboxDependencies() { + } + + void updateListDependencies() { + String id= fStore.getString(PreferenceConstants.EDITOR_FOLDING_PROVIDER); + CFoldingStructureProviderDescriptor desc= (CFoldingStructureProviderDescriptor) fProviderDescriptors.get(id); + ICFoldingPreferenceBlock prefs; + + if (desc == null) { + // safety in case there is no such descriptor + String message= PreferencesMessages.getString("FoldingConfigurationBlock.error.not_exist"); //$NON-NLS-1$ + CUIPlugin.getDefault().log(new Status(IStatus.WARNING, CUIPlugin.getPluginId(), IStatus.OK, message, null)); + prefs= new ErrorPreferences(message); + } else { + prefs= (ICFoldingPreferenceBlock) fProviderPreferences.get(id); + if (prefs == null) { + try { + prefs= desc.createPreferences(); + fProviderPreferences.put(id, prefs); + } catch (CoreException e) { + CUIPlugin.getDefault().log(e); + prefs= new ErrorPreferences(e.getLocalizedMessage()); + } + } + } + + Control control= (Control) fProviderControls.get(id); + if (control == null) { + control= prefs.createControl(fGroup); + if (control == null) { + String message= PreferencesMessages.getString("FoldingConfigurationBlock.info.no_preferences"); //$NON-NLS-1$ + control= new ErrorPreferences(message).createControl(fGroup); + } else { + fProviderControls.put(id, control); + } + } + fStackLayout.topControl= control; + control.pack(); + fGroup.layout(); + fGroup.getParent().layout(); + + prefs.initialize(); + } + + void initialize() { + restoreFromPreferences(); + } + + void performOk() { + for (Iterator it= fProviderPreferences.values().iterator(); it.hasNext();) { + ICFoldingPreferenceBlock prefs= (ICFoldingPreferenceBlock) it.next(); + prefs.performOk(); + } + } + + void performDefaults() { + restoreFromPreferences(); + for (Iterator it= fProviderPreferences.values().iterator(); it.hasNext();) { + ICFoldingPreferenceBlock prefs= (ICFoldingPreferenceBlock) it.next(); + prefs.performDefaults(); + } + } + + void dispose() { + for (Iterator it= fProviderPreferences.values().iterator(); it.hasNext();) { + ICFoldingPreferenceBlock prefs= (ICFoldingPreferenceBlock) it.next(); + prefs.dispose(); + } + } + + private void restoreFromPreferences() { + boolean enabled= fStore.getBoolean(PreferenceConstants.EDITOR_FOLDING_ENABLED); + fFoldingCheckbox.setSelection(enabled); + updateCheckboxDependencies(); + + String id= fStore.getString(PreferenceConstants.EDITOR_FOLDING_PROVIDER); + Object provider= fProviderDescriptors.get(id); + if (provider != null) { + fProviderViewer.setSelection(new StructuredSelection(provider), true); + updateListDependencies(); + } + } +} + diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties index bf38fe28327..29854266035 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties @@ -189,3 +189,11 @@ AppearancePreferencePage.cviewGroupIncludes.label= Group the includes in the C/C AppearancePreferencePage.outlineGroupIncludes.label= Group the includes in the outliner AppearancePreferencePage.note=Note: AppearancePreferencePage.preferenceOnlyEffectiveForNewPerspectives=This preference may only take effect on new perspectives + +#Folding +CEditorPreferencePage.folding.title= &Folding + +FoldingConfigurationBlock.enable= Enable folding when &opening a new editor +FoldingConfigurationBlock.combo_caption= Select folding to &use: +FoldingConfigurationBlock.info.no_preferences= The selected folding provider did not provide a preference control +FoldingConfigurationBlock.error.not_exist= The selected folding provider does not exist diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/CFoldingStructureProviderDescriptor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/CFoldingStructureProviderDescriptor.java new file mode 100644 index 00000000000..8d4ebdc2946 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/CFoldingStructureProviderDescriptor.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.ui.text.folding; + +import org.eclipse.cdt.ui.text.folding.ICFoldingPreferenceBlock; +import org.eclipse.cdt.ui.text.folding.ICFoldingStructureProvider; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.jface.text.Assert; + +/** + * Describes a contribution to the folding provider extension point. + * + */ +public final class CFoldingStructureProviderDescriptor { + + /* extension point attribute names */ + + private static final String PREFERENCES_CLASS= "preferencesClass"; //$NON-NLS-1$ + private static final String CLASS= "class"; //$NON-NLS-1$ + private static final String NAME= "name"; //$NON-NLS-1$ + private static final String ID= "id"; //$NON-NLS-1$ + + /** The identifier of the extension. */ + private String fId; + /** The name of the extension. */ + private String fName; + /** The class name of the provided ICFoldingStructureProvider. */ + private String fClass; + /** + * true if the extension specifies a custom + * ICFoldingPreferenceBlock. + */ + private boolean fHasPreferences; + /** The configuration element of this extension. */ + private IConfigurationElement fElement; + + /** + * Creates a new descriptor. + * + * @param element the configuration element to read + */ + CFoldingStructureProviderDescriptor(IConfigurationElement element) { + fElement= element; + fId= element.getAttributeAsIs(ID); + Assert.isLegal(fId != null); + + fName= element.getAttribute(NAME); + if (fName == null) + fName= fId; + + fClass= element.getAttributeAsIs(CLASS); + Assert.isLegal(fClass != null); + + if (element.getAttributeAsIs(PREFERENCES_CLASS) == null) + fHasPreferences= false; + else + fHasPreferences= true; + } + + /** + * Creates a folding provider as described in the extension's xml. + * + * @return a new instance of the folding provider described by this + * descriptor + * @throws CoreException if creation fails + */ + public ICFoldingStructureProvider createProvider() throws CoreException { + ICFoldingStructureProvider prov= (ICFoldingStructureProvider) fElement.createExecutableExtension(CLASS); + return prov; + } + + /** + * Creates a preferences object as described in the extension's xml. + * + * @return a new instance of the reference provider described by this + * descriptor + * @throws CoreException if creation fails + */ + public ICFoldingPreferenceBlock createPreferences() throws CoreException { + if (fHasPreferences) { + ICFoldingPreferenceBlock prefs= (ICFoldingPreferenceBlock) fElement.createExecutableExtension(PREFERENCES_CLASS); + return prefs; + } + return new EmptyCFoldingPreferenceBlock(); + } + + /** + * Returns the identifier of the described extension. + * + * @return Returns the id + */ + public String getId() { + return fId; + } + + /** + * Returns the name of the described extension. + * + * @return Returns the name + */ + public String getName() { + return fName; + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/CFoldingStructureProviderRegistry.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/CFoldingStructureProviderRegistry.java new file mode 100644 index 00000000000..6cad22b529e --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/CFoldingStructureProviderRegistry.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.ui.text.folding; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.ui.PreferenceConstants; +import org.eclipse.cdt.ui.text.folding.ICFoldingStructureProvider; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.Platform; + +public class CFoldingStructureProviderRegistry { + + private static final String EXTENSION_POINT= "foldingStructureProviders"; //$NON-NLS-1$ + + /** The map of descriptors, indexed by their identifiers. */ + private Map fDescriptors; + + /** + * Creates a new instance. + */ + public CFoldingStructureProviderRegistry() { + } + + /** + * Returns an array of ICFoldingProviderDescriptor describing + * all extension to the foldingProviders extension point. + * + * @return the list of extensions to the + * quickDiffReferenceProvider extension point. + */ + public CFoldingStructureProviderDescriptor[] getFoldingProviderDescriptors() { + synchronized (this) { + ensureRegistered(); + return (CFoldingStructureProviderDescriptor[]) fDescriptors.values().toArray(new CFoldingStructureProviderDescriptor[fDescriptors.size()]); + } + } + + /** + * Returns the folding provider with identifier id or + * null if no such provider is registered. + * + * @param id the identifier for which a provider is wanted + * @return the corresponding provider, or null if none can be + * found + */ + public CFoldingStructureProviderDescriptor getFoldingProviderDescriptor(String id) { + synchronized (this) { + ensureRegistered(); + return (CFoldingStructureProviderDescriptor) fDescriptors.get(id); + } + } + + /** + * Instantiates and returns the provider that is currently configured in the + * preferences. + * + * @return the current provider according to the preferences + */ + public ICFoldingStructureProvider getCurrentFoldingProvider() { + String id= CUIPlugin.getDefault().getPreferenceStore().getString(PreferenceConstants.EDITOR_FOLDING_PROVIDER); + CFoldingStructureProviderDescriptor desc= getFoldingProviderDescriptor(id); + if (desc != null) { + try { + return desc.createProvider(); + } catch (CoreException e) { + CUIPlugin.getDefault().log(e); + } + } + return null; + } + + /** + * Ensures that the extensions are read and stored in + * fDescriptors. + */ + private void ensureRegistered() { + if (fDescriptors == null) + reloadExtensions(); + } + + /** + * Reads all extensions. + *

+ * This method can be called more than once in + * order to reload from a changed extension registry. + *

+ */ + public void reloadExtensions() { + IExtensionRegistry registry= Platform.getExtensionRegistry(); + Map map= new HashMap(); + + IConfigurationElement[] elements= registry.getConfigurationElementsFor(CUIPlugin.getPluginId(), EXTENSION_POINT); + for (int i= 0; i < elements.length; i++) { + CFoldingStructureProviderDescriptor desc= new CFoldingStructureProviderDescriptor(elements[i]); + map.put(desc.getId(), desc); + } + + synchronized(this) { + fDescriptors= Collections.unmodifiableMap(map); + } + } + + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/DefaultCFoldingPreferenceBlock.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/DefaultCFoldingPreferenceBlock.java new file mode 100644 index 00000000000..ec212f4664f --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/DefaultCFoldingPreferenceBlock.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.ui.text.folding; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.cdt.internal.ui.preferences.OverlayPreferenceStore; +import org.eclipse.cdt.internal.ui.preferences.OverlayPreferenceStore.OverlayKey; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.ui.PreferenceConstants; +import org.eclipse.cdt.ui.text.folding.ICFoldingPreferenceBlock; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; + +/** + */ +public class DefaultCFoldingPreferenceBlock implements ICFoldingPreferenceBlock { + + private IPreferenceStore fStore; + protected OverlayPreferenceStore fOverlayStore; + private OverlayKey[] fKeys; + protected Map fCheckBoxes= new HashMap(); + + private SelectionListener fCheckBoxListener= new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + } + public void widgetSelected(SelectionEvent e) { + Button button= (Button) e.widget; + fOverlayStore.setValue((String) fCheckBoxes.get(button), button.getSelection()); + } + }; + + + public DefaultCFoldingPreferenceBlock() { + fStore= CUIPlugin.getDefault().getPreferenceStore(); + fKeys= createKeys(); + fOverlayStore= new OverlayPreferenceStore(fStore, fKeys); + } + + private OverlayKey[] createKeys() { + ArrayList overlayKeys= new ArrayList(); + + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_FOLDING_MACROS)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_FOLDING_FUNCTIONS)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_FOLDING_METHODS)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_FOLDING_STRUCTURES)); + + return (OverlayKey[]) overlayKeys.toArray(new OverlayKey[overlayKeys.size()]); + } + + /* + * @see org.eclipse.jdt.internal.ui.text.folding.ICFoldingPreferences#createControl(org.eclipse.swt.widgets.Group) + */ + public Control createControl(Composite composite) { + fOverlayStore.load(); + fOverlayStore.start(); + + Composite inner= new Composite(composite, SWT.NONE); + GridLayout layout= new GridLayout(1, true); + layout.verticalSpacing= 3; + layout.marginWidth= 0; + inner.setLayout(layout); + + Label label= new Label(inner, SWT.LEFT); + label.setText(FoldingMessages.getString("DefaultCFoldingPreferenceBlock.title")); //$NON-NLS-1$ + + addCheckBox(inner, FoldingMessages.getString("DefaultCFoldingPreferenceBlock.macros"), PreferenceConstants.EDITOR_FOLDING_MACROS, 0); //$NON-NLS-1$ + addCheckBox(inner, FoldingMessages.getString("DefaultCFoldingPreferenceBlock.functions"), PreferenceConstants.EDITOR_FOLDING_FUNCTIONS, 0); //$NON-NLS-1$ + addCheckBox(inner, FoldingMessages.getString("DefaultCFoldingPreferenceBlock.methods"), PreferenceConstants.EDITOR_FOLDING_METHODS, 0); //$NON-NLS-1$ + addCheckBox(inner, FoldingMessages.getString("DefaultCFoldingPreferenceBlock.structures"), PreferenceConstants.EDITOR_FOLDING_STRUCTURES, 0); //$NON-NLS-1$ + + return inner; + } + + private Button addCheckBox(Composite parent, String label, String key, int indentation) { + Button checkBox= new Button(parent, SWT.CHECK); + checkBox.setText(label); + + GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); + gd.horizontalIndent= indentation; + gd.horizontalSpan= 1; + gd.grabExcessVerticalSpace= false; + checkBox.setLayoutData(gd); + checkBox.addSelectionListener(fCheckBoxListener); + + fCheckBoxes.put(checkBox, key); + + return checkBox; + } + + private void initializeFields() { + Iterator it= fCheckBoxes.keySet().iterator(); + while (it.hasNext()) { + Button b= (Button) it.next(); + String key= (String) fCheckBoxes.get(b); + b.setSelection(fOverlayStore.getBoolean(key)); + } + } + + /* + * @see org.eclipse.cdt.internal.ui.text.folding.AbstractCFoldingPreferences#performOk() + */ + public void performOk() { + fOverlayStore.propagate(); + } + + + /* + * @see org.eclipse.cdt.internal.ui.text.folding.AbstractCFoldingPreferences#initialize() + */ + public void initialize() { + initializeFields(); + } + + /* + * @see org.eclipse.cdt.internal.ui.text.folding.AbstractCFoldingPreferences#performDefaults() + */ + public void performDefaults() { + fOverlayStore.loadDefaults(); + initializeFields(); + } + + /* + * @see org.eclipse.cdt.internal.ui.text.folding.AbstractCFoldingPreferences#dispose() + */ + public void dispose() { + fOverlayStore.stop(); + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/DefaultCFoldingStructureProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/DefaultCFoldingStructureProvider.java new file mode 100644 index 00000000000..887d01203d2 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/DefaultCFoldingStructureProvider.java @@ -0,0 +1,477 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.ui.text.folding; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ElementChangedEvent; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ICElementDelta; +import org.eclipse.cdt.core.model.IElementChangedListener; +import org.eclipse.cdt.core.model.IParent; +import org.eclipse.cdt.core.model.ISourceRange; +import org.eclipse.cdt.core.model.ISourceReference; +import org.eclipse.cdt.core.model.IWorkingCopy; +import org.eclipse.cdt.internal.ui.editor.CEditor; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.ui.IWorkingCopyManager; +import org.eclipse.cdt.ui.PreferenceConstants; +import org.eclipse.cdt.ui.text.folding.ICFoldingStructureProvider; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.projection.IProjectionListener; +import org.eclipse.jface.text.source.projection.ProjectionAnnotation; +import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel; +import org.eclipse.jface.text.source.projection.ProjectionViewer; +import org.eclipse.ui.texteditor.IDocumentProvider; +import org.eclipse.ui.texteditor.ITextEditor; + +/** + */ +public class DefaultCFoldingStructureProvider implements IProjectionListener, ICFoldingStructureProvider { + + private static class CProjectionAnnotation extends ProjectionAnnotation { + + private ICElement fCElement; + private boolean fIsComment; + + public CProjectionAnnotation(ICElement element, boolean isCollapsed, boolean isComment) { + super(isCollapsed); + fCElement= element; + fIsComment= isComment; + } + + public ICElement getElement() { + return fCElement; + } + + public void setElement(ICElement element) { + fCElement= element; + } + + public boolean isComment() { + return fIsComment; + } + + public void setIsComment(boolean isComment) { + fIsComment= isComment; + } + } + + private class ElementChangedListener implements IElementChangedListener { + + /* + * @see org.eclipse.jdt.core.IElementChangedListener#elementChanged(org.eclipse.jdt.core.ElementChangedEvent) + */ + public void elementChanged(ElementChangedEvent e) { + ICElementDelta delta= findElement(fInput, e.getDelta()); + if (delta != null) + processDelta(delta); + } + + private ICElementDelta findElement(ICElement target, ICElementDelta delta) { + + if (delta == null || target == null) + return null; + + ICElement element= delta.getElement(); + + if (element.getElementType() > ICElement.C_UNIT) + return null; + + if (target.equals(element)) + return delta; + + ICElementDelta[] children= delta.getAffectedChildren(); + if (children == null || children.length == 0) + return null; + + for (int i= 0; i < children.length; i++) { + ICElementDelta d= findElement(target, children[i]); + if (d != null) + return d; + } + + return null; + } + } + + + private IDocument fCachedDocument; + + private ITextEditor fEditor; + private ProjectionViewer fViewer; + protected ICElement fInput; + private IElementChangedListener fElementListener; + + private boolean fAllowCollapsing= false; + private boolean fCollapseMacros= false; + private boolean fCollapseFunctions= true; + private boolean fCollapseStructures= true; + private boolean fCollapseMethods= false; + + public DefaultCFoldingStructureProvider() { + } + + public void install(ITextEditor editor, ProjectionViewer viewer) { + if (editor instanceof CEditor) { + fEditor= editor; + fViewer= viewer; + fViewer.addProjectionListener(this); + } + } + + public void uninstall() { + if (isInstalled()) { + projectionDisabled(); + fViewer.removeProjectionListener(this); + fViewer= null; + fEditor= null; + } + } + + protected boolean isInstalled() { + return fEditor != null; + } + + /* + * @see org.eclipse.jface.text.source.projection.IProjectionListener#projectionEnabled() + */ + public void projectionEnabled() { + // http://home.ott.oti.com/teams/wswb/anon/out/vms/index.html + // projectionEnabled messages are not always paired with projectionDisabled + // i.e. multiple enabled messages may be sent out. + // we have to make sure that we disable first when getting an enable + // message. + projectionDisabled(); + + if (fEditor instanceof CEditor) { + initialize(); + fElementListener= new ElementChangedListener(); + CoreModel.getDefault().addElementChangedListener(fElementListener); + } + } + + /* + * @see org.eclipse.jface.text.source.projection.IProjectionListener#projectionDisabled() + */ + public void projectionDisabled() { + fCachedDocument= null; + if (fElementListener != null) { + CoreModel.getDefault().removeElementChangedListener(fElementListener); + fElementListener= null; + } + } + + public void initialize() { + + if (!isInstalled()) + return; + + initializePreferences(); + + try { + + IDocumentProvider provider= fEditor.getDocumentProvider(); + fCachedDocument= provider.getDocument(fEditor.getEditorInput()); + fAllowCollapsing= true; + + if (fEditor instanceof CEditor) { + IWorkingCopyManager manager= CUIPlugin.getDefault().getWorkingCopyManager(); + fInput= manager.getWorkingCopy(fEditor.getEditorInput()); + } + + if (fInput != null) { + ProjectionAnnotationModel model= (ProjectionAnnotationModel) fEditor.getAdapter(ProjectionAnnotationModel.class); + if (model != null) { + + if (fInput instanceof IWorkingCopy) { + IWorkingCopy unit= (IWorkingCopy) fInput; + synchronized (unit) { + try { + unit.reconcile(); + } catch (CModelException x) { + } + } + } + + Map additions= computeAdditions((IParent) fInput); + model.removeAllAnnotations(); + model.replaceAnnotations(null, additions); + } + } + + } finally { + fCachedDocument= null; + fAllowCollapsing= false; + } + } + + private void initializePreferences() { + IPreferenceStore store= CUIPlugin.getDefault().getPreferenceStore(); + fCollapseFunctions= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_FUNCTIONS); + fCollapseStructures= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_STRUCTURES); + fCollapseMacros= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_MACROS); + fCollapseMethods= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_METHODS); + } + + private Map computeAdditions(IParent parent) { + Map map= new HashMap(); + try { + computeAdditions(parent.getChildren(), map); + } catch (CModelException x) { + } + return map; + } + + private void computeAdditions(ICElement[] elements, Map map) throws CModelException { + for (int i= 0; i < elements.length; i++) { + ICElement element= elements[i]; + + computeAdditions(element, map); + + if (element instanceof IParent) { + IParent parent= (IParent) element; + computeAdditions(parent.getChildren(), map); + } + } + } + + private void computeAdditions(ICElement element, Map map) { + + boolean createProjection= false; + + boolean collapse= false; + switch (element.getElementType()) { + + case ICElement.C_STRUCT: + case ICElement.C_CLASS: + collapse= fAllowCollapsing && fCollapseStructures; + createProjection= true; + break; + case ICElement.C_MACRO: + collapse= fAllowCollapsing && fCollapseMacros; + createProjection= true; + break; + case ICElement.C_FUNCTION: + collapse= fAllowCollapsing && fCollapseFunctions; + createProjection= true; + break; + case ICElement.C_METHOD: + collapse= fAllowCollapsing && fCollapseMethods; + createProjection= true; + break; + } + + if (createProjection) { + Position position= createProjectionPosition(element); + if (position != null) { + map.put(new CProjectionAnnotation(element, collapse, false), position); + } + } + } + + private Position createProjectionPosition(ICElement element) { + + if (fCachedDocument == null) + return null; + + try { + if (element instanceof ISourceReference) { + ISourceReference reference= (ISourceReference) element; + ISourceRange range= reference.getSourceRange(); + + int start= fCachedDocument.getLineOfOffset(range.getStartPos()); + int end= fCachedDocument.getLineOfOffset(range.getStartPos() + range.getLength()); + if (start != end) { + int offset= fCachedDocument.getLineOffset(start); + int endOffset= fCachedDocument.getLineOffset(end + 1); + return new Position(offset, endOffset - offset); + } + } + } catch (BadLocationException x) { + } catch (CModelException e) { + } + return null; + } + + protected void processDelta(ICElementDelta delta) { + + if (!isInstalled()) + return; + + ProjectionAnnotationModel model= (ProjectionAnnotationModel) fEditor.getAdapter(ProjectionAnnotationModel.class); + if (model == null) + return; + + try { + + IDocumentProvider provider= fEditor.getDocumentProvider(); + fCachedDocument= provider.getDocument(fEditor.getEditorInput()); + fAllowCollapsing= false; + + Map additions= new HashMap(); + List deletions= new ArrayList(); + List updates= new ArrayList(); + + Map updated= computeAdditions((IParent) fInput); + Map previous= createAnnotationMap(model); + + + Iterator e= updated.keySet().iterator(); + while (e.hasNext()) { + CProjectionAnnotation annotation= (CProjectionAnnotation) e.next(); + ICElement element= annotation.getElement(); + Position position= (Position) updated.get(annotation); + + List annotations= (List) previous.get(element); + if (annotations == null) { + + additions.put(annotation, position); + + } else { + + Iterator x= annotations.iterator(); + while (x.hasNext()) { + CProjectionAnnotation a= (CProjectionAnnotation) x.next(); + if (annotation.isComment() == a.isComment()) { + Position p= model.getPosition(a); + if (p != null && !position.equals(p)) { + p.setOffset(position.getOffset()); + p.setLength(position.getLength()); + updates.add(a); + } + x.remove(); + break; + } + } + + if (annotations.isEmpty()) + previous.remove(element); + } + } + + e= previous.values().iterator(); + while (e.hasNext()) { + List list= (List) e.next(); + int size= list.size(); + for (int i= 0; i < size; i++) + deletions.add(list.get(i)); + } + + match(model, deletions, additions, updates); + + Annotation[] removals= new Annotation[deletions.size()]; + deletions.toArray(removals); + Annotation[] changes= new Annotation[updates.size()]; + updates.toArray(changes); + model.modifyAnnotations(removals, additions, changes); + + } finally { + fCachedDocument= null; + fAllowCollapsing= true; + } + } + + private void match(ProjectionAnnotationModel model, List deletions, Map additions, List changes) { + if (deletions.isEmpty() || (additions.isEmpty() && changes.isEmpty())) + return; + + List newDeletions= new ArrayList(); + List newChanges= new ArrayList(); + + Iterator deletionIterator= deletions.iterator(); + outer: while (deletionIterator.hasNext()) { + CProjectionAnnotation deleted= (CProjectionAnnotation) deletionIterator.next(); + Position deletedPosition= model.getPosition(deleted); + if (deletedPosition == null) + continue; + + Iterator changesIterator= changes.iterator(); + while (changesIterator.hasNext()) { + CProjectionAnnotation changed= (CProjectionAnnotation) changesIterator.next(); + if (deleted.isComment() == changed.isComment()) { + Position changedPosition= model.getPosition(changed); + if (changedPosition == null) + continue; + + if (deletedPosition.getOffset() == changedPosition.getOffset()) { + + deletedPosition.setLength(changedPosition.getLength()); + deleted.setElement(changed.getElement()); + + deletionIterator.remove(); + newChanges.add(deleted); + + changesIterator.remove(); + newDeletions.add(changed); + + continue outer; + } + } + } + + Iterator additionsIterator= additions.keySet().iterator(); + while (additionsIterator.hasNext()) { + CProjectionAnnotation added= (CProjectionAnnotation) additionsIterator.next(); + if (deleted.isComment() == added.isComment()) { + Position addedPosition= (Position) additions.get(added); + + if (deletedPosition.getOffset() == addedPosition.getOffset()) { + + deletedPosition.setLength(addedPosition.getLength()); + deleted.setElement(added.getElement()); + + deletionIterator.remove(); + newChanges.add(deleted); + + additionsIterator.remove(); + + break; + } + } + } + } + + deletions.addAll(newDeletions); + changes.addAll(newChanges); + } + + private Map createAnnotationMap(IAnnotationModel model) { + Map map= new HashMap(); + Iterator e= model.getAnnotationIterator(); + while (e.hasNext()) { + Object annotation= e.next(); + if (annotation instanceof CProjectionAnnotation) { + CProjectionAnnotation c= (CProjectionAnnotation) annotation; + List list= (List) map.get(c.getElement()); + if (list == null) { + list= new ArrayList(2); + map.put(c.getElement(), list); + } + list.add(c); + } + } + return map; + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/EmptyCFoldingPreferenceBlock.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/EmptyCFoldingPreferenceBlock.java new file mode 100644 index 00000000000..c2656690f24 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/EmptyCFoldingPreferenceBlock.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.ui.text.folding; + +import org.eclipse.cdt.ui.text.folding.ICFoldingPreferenceBlock; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; + +/** + * Empty preference block for extensions to the + * org.eclipse.jdt.ui.javaFoldingStructureProvider extension + * point that do not specify their own. + * + * @since 3.0 + */ +public class EmptyCFoldingPreferenceBlock implements ICFoldingPreferenceBlock { + /* + * @see org.eclipse.cdt.internal.ui.text.folding.ICFoldingPreferences#createControl(org.eclipse.swt.widgets.Group) + */ + public Control createControl(Composite composite) { + Composite inner= new Composite(composite, SWT.NONE); + inner.setLayout(new GridLayout(3, false)); + + Label label= new Label(inner, SWT.CENTER); + GridData gd= new GridData(GridData.FILL_BOTH); + gd.widthHint= 30; + label.setLayoutData(gd); + + label= new Label(inner, SWT.CENTER); + label.setText(FoldingMessages.getString("EmptyCFoldingPreferenceBlock.emptyCaption")); //$NON-NLS-1$ + gd= new GridData(GridData.CENTER); + label.setLayoutData(gd); + + label= new Label(inner, SWT.CENTER); + gd= new GridData(GridData.FILL_BOTH); + gd.widthHint= 30; + label.setLayoutData(gd); + + return inner; + } + + /* + * @see org.eclipse.cdt.internal.ui.text.folding.ICFoldingPreferenceBlock#initialize() + */ + public void initialize() { + } + + /* + * @see org.eclipse.cdt.internal.ui.text.folding.ICFoldingPreferenceBlock#performOk() + */ + public void performOk() { + } + + /* + * @see org.eclipse.cdt.internal.ui.text.folding.ICFoldingPreferenceBlock#performDefaults() + */ + public void performDefaults() { + } + + /* + * @see org.eclipse.cdt.internal.ui.text.folding.ICFoldingPreferenceBlock#dispose() + */ + public void dispose() { + } + + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/FoldingMessages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/FoldingMessages.java new file mode 100644 index 00000000000..78096192871 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/FoldingMessages.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.ui.text.folding; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +/** + * @since 3.0 + */ +class FoldingMessages { + + private static final String BUNDLE_NAME= FoldingMessages.class.getName(); + + private static final ResourceBundle RESOURCE_BUNDLE= ResourceBundle.getBundle(BUNDLE_NAME); + + private FoldingMessages() { + } + + public static String getString(String key) { + try { + return RESOURCE_BUNDLE.getString(key); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/FoldingMessages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/FoldingMessages.properties new file mode 100644 index 00000000000..1249eb06d0f --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/folding/FoldingMessages.properties @@ -0,0 +1,19 @@ +############################################################################### +# Copyright (c) 2000, 2004 IBM Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Common Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/cpl-v10.html +# +# Contributors: +# IBM Corporation - initial API and implementation +############################################################################### + + +DefaultCFoldingPreferenceBlock.title= Initially fold these region types: +DefaultCFoldingPreferenceBlock.macros= &Macros +DefaultCFoldingPreferenceBlock.functions= &Functions +DefaultCFoldingPreferenceBlock.methods= &Methods +DefaultCFoldingPreferenceBlock.structures= &Structures + +EmptyCFoldingPreferenceBlock.emptyCaption= diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPlugin.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPlugin.java index 9229666fc1b..5448005862f 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPlugin.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPlugin.java @@ -41,6 +41,7 @@ import org.eclipse.cdt.internal.ui.editor.asm.AsmTextTools; import org.eclipse.cdt.internal.ui.text.CTextTools; import org.eclipse.cdt.internal.ui.text.PreferencesAdapter; import org.eclipse.cdt.internal.ui.text.c.hover.CEditorTextHoverDescriptor; +import org.eclipse.cdt.internal.ui.text.folding.CFoldingStructureProviderRegistry; import org.eclipse.cdt.internal.ui.util.ImageDescriptorRegistry; import org.eclipse.cdt.internal.ui.util.ProblemMarkerManager; import org.eclipse.cdt.internal.ui.util.Util; @@ -54,7 +55,6 @@ import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; -import org.eclipse.jface.action.Action; import org.eclipse.jface.action.GroupMarker; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.Separator; @@ -104,6 +104,13 @@ public class CUIPlugin extends AbstractUIPlugin { private ImageDescriptorRegistry fImageDescriptorRegistry; private CEditorTextHoverDescriptor[] fCEditorTextHoverDescriptors; + /** + * The extension point registry for the org.eclipse.jdt.ui.javaFoldingStructureProvider + * extension point. + * + */ + private CFoldingStructureProviderRegistry fFoldingStructureProviderRegistry; + /** * The combined preference store. * @since 3.0 @@ -706,5 +713,18 @@ public class CUIPlugin extends AbstractUIPlugin { CActions.addAll(CCActions); return (String[]) CActions.toArray(new String[CActions.size()]); } - + + /** + * Returns the registry of the extensions to the org.eclipse.jdt.ui.javaFoldingStructureProvider + * extension point. + * + * @return the registry of contributed IJavaFoldingStructureProvider + * @since 3.0 + */ + public synchronized CFoldingStructureProviderRegistry getFoldingStructureProviderRegistry() { + if (fFoldingStructureProviderRegistry == null) + fFoldingStructureProviderRegistry= new CFoldingStructureProviderRegistry(); + return fFoldingStructureProviderRegistry; + } + } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java index ea5df213c93..573a25fa961 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java @@ -288,6 +288,64 @@ public class PreferenceConstants { */ public static final String CVIEW_GROUP_INCLUDES= "org.eclipse.cdt.ui.cview.groupincludes"; //$NON-NLS-1$ + /** + * A named preference that controls whether folding is enabled in the C editor. + *

+ * Value is of type Boolean. + *

+ * + */ + public static final String EDITOR_FOLDING_ENABLED= "editor_folding_enabled"; //$NON-NLS-1$ + + /** + * A named preference that stores the configured folding provider. + *

+ * Value is of type String. + *

+ * + */ + public static final String EDITOR_FOLDING_PROVIDER= "editor_folding_provider"; //$NON-NLS-1$ + + /** + * A named preference that stores the value for Structure folding for the default folding provider. + *

+ * Value is of type Boolean. + *

+ * + * @since 3.0 + */ + public static final String EDITOR_FOLDING_STRUCTURES= "editor_folding_default_structures"; //$NON-NLS-1$ + + /** + * A named preference that stores the value for functions folding for the default folding provider. + *

+ * Value is of type Boolean. + *

+ * + * @since 3.0 + */ + public static final String EDITOR_FOLDING_FUNCTIONS= "editor_folding_default_functions"; //$NON-NLS-1$ + + /** + * A named preference that stores the value for method folding for the default folding provider. + *

+ * Value is of type Boolean. + *

+ * + * @since 3.0 + */ + public static final String EDITOR_FOLDING_METHODS= "editor_folding_default_methods"; //$NON-NLS-1$ + + /** + * A named preference that stores the value for macros folding for the default folding provider. + *

+ * Value is of type Boolean. + *

+ * + * @since 3.0 + */ + public static final String EDITOR_FOLDING_MACROS= "editor_folding_default_macros"; //$NON-NLS-1$ + /** * Returns the CDT-UI preference store. * @@ -318,5 +376,14 @@ public class PreferenceConstants { store.setDefault(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS, "org.eclipse.cdt.ui.BestMatchHover;0;org.eclipse.cdt.ui.CSourceHover;" + SWT.MOD1); //$NON-NLS-1$ //store.setDefault(PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE, true); + // folding + store.setDefault(PreferenceConstants.EDITOR_FOLDING_ENABLED, false); + store.setDefault(PreferenceConstants.EDITOR_FOLDING_PROVIDER, "org.eclipse.cdt.ui.text.defaultFoldingProvider"); //$NON-NLS-1$ + store.setDefault(PreferenceConstants.EDITOR_FOLDING_FUNCTIONS, false); + store.setDefault(PreferenceConstants.EDITOR_FOLDING_STRUCTURES, true); + store.setDefault(PreferenceConstants.EDITOR_FOLDING_METHODS, false); + store.setDefault(PreferenceConstants.EDITOR_FOLDING_MACROS, true); + + } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/folding/ICFoldingPreferenceBlock.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/folding/ICFoldingPreferenceBlock.java new file mode 100644 index 00000000000..d7cf819b6d4 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/folding/ICFoldingPreferenceBlock.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.ui.text.folding; + +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +/** + * Contributors to the org.eclipse.jdt.ui.foldingStructureProvider extension point + * can specify an implementation of this interface to be displayed on the C > Editor > Folding + * preference page. + *

+ * Clients may implement this interface. + *

+ * + */ +public interface ICFoldingPreferenceBlock { + + /** + * Creates the control that will be displayed on the C > Editor > Folding + * preference page. + * + * @param parent the parent composite to which to add the preferences control + * @return the control that was added to parent + */ + Control createControl(Composite parent); + + /** + * Called after creating the control. Implementations should load the + * preferences values and update the controls accordingly. + */ + void initialize(); + + /** + * Called when the OK button is pressed on the preference + * page. Implementations should commit the configured preference settings + * into their form of preference storage. + */ + void performOk(); + + /** + * Called when the Defaults button is pressed on the + * preference page. Implementation should reset any preference settings to + * their default values and adjust the controls accordingly. + */ + void performDefaults(); + + /** + * Called when the preference page is being disposed. Implementations should + * free any resources they are holding on to. + */ + void dispose(); + + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/folding/ICFoldingStructureProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/folding/ICFoldingStructureProvider.java new file mode 100644 index 00000000000..d9e4bb33693 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/folding/ICFoldingStructureProvider.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.ui.text.folding; + +import org.eclipse.jface.text.source.projection.ProjectionViewer; +import org.eclipse.ui.texteditor.ITextEditor; + +/** + * Contributors to the + * org.eclipse.jdt.ui.foldingStructureProvider extension + * point must specify an implementation of this interface which will create and + * maintain {@link org.eclipse.jface.text.source.projection.ProjectionAnnotation} objects + * that define folded regions in the the {@link org.eclipse.jface.text.source.projection.ProjectionViewer}. + *

+ * Clients may implement this interface. + *

+ * + */ +public interface ICFoldingStructureProvider { + + /** + * Installs this structure provider on the given editor and viewer. + * Implementations should listen to the projection events generated by + * viewer and enable / disable generation of projection + * structure accordingly. + * + * @param editor the editor that this provider works on + * @param viewer the projection viewer that displays the annotations created + * by this structure provider + */ + public abstract void install(ITextEditor editor, ProjectionViewer viewer); + + /** + * Uninstalls this structure provider. Any references to editors or viewers + * should be cleared. + */ + public abstract void uninstall(); + + /** + * (Re-)initializes the structure provided by the receiver. + */ + public abstract void initialize(); + +}