diff --git a/core/org.eclipse.cdt.ui/ChangeLog b/core/org.eclipse.cdt.ui/ChangeLog index d5d90b8db48..4b84bb4596d 100644 --- a/core/org.eclipse.cdt.ui/ChangeLog +++ b/core/org.eclipse.cdt.ui/ChangeLog @@ -1,3 +1,18 @@ +2004-12-14 Alain Magloire + PR 80631 Patch form Przemek Tomaszewski + * src/org/eclipse/cdt/internal/ui/editor/CContentOutilinePage.java + * src/org/eclipse/cdt/internal/ui/editor/CContentOutlinerProvider.java + * src/org/eclipse/cdt/internal/ui/editor/CEditor.java + * src/org/eclipse/cdt/internal/ui/editor/CEditorMessages.properties + * src/org/eclipse/cdt/internal/ui/editor/CSourceViewer.java + * src/org/eclipse/cdt/internal/ui/editor/ICEdtiroActionDefinitionIds.java + * src/org/eclipse/cdt/internal/ui/text/COutlineInformationControl.java + * src/org/eclipse/cdt/internal/ui/text/CSourceViewerConfiguration.java + * src/org/eclipse/cdt/internal/ui/util/ProblemTreeViewer.java + * src/org/eclpse/cdt/ui/CElementContentProvider.java + * plugin.properties. + * plugin.xml + 2004-12-12 Alain Magloire PR 80631 Patch form Przemek Tomaszewski * src/org/eclipse/cdt/internal.ui/preferences/CEditorPreferencePage.java diff --git a/core/org.eclipse.cdt.ui/plugin.properties b/core/org.eclipse.cdt.ui/plugin.properties index bf974e62149..fde6c7fa567 100644 --- a/core/org.eclipse.cdt.ui/plugin.properties +++ b/core/org.eclipse.cdt.ui/plugin.properties @@ -158,6 +158,10 @@ ActionDefinition.openType.description= Open a type in a C editor ActionDefinition.addInclude.name= Add Include ActionDefinition.addInclude.description= Create include statement on selection +#Show outline dialog +ActionDefinition.showOutline.name= Show outline +ActionDefinition.showOutline.description= Shows outline + CElementWorkingSetPage.name = C/C++ CEditorFontDefinition.description = The C/C++ editor text font is used by C/C++ editors. diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml index cf5d353eead..20ccb87cb02 100644 --- a/core/org.eclipse.cdt.ui/plugin.xml +++ b/core/org.eclipse.cdt.ui/plugin.xml @@ -938,6 +938,18 @@ command="org.eclipse.cdt.ui.edit.text.c.add.include" configuration="org.eclipse.ui.defaultAcceleratorConfiguration"> + + + + ICElement.C_UNIT) - return null; - - ICElementDelta[] children= delta.getAffectedChildren(); - if (children == null || children.length == 0) - return null; - - for (int i= 0; i < children.length; i++) { - ICElementDelta d= findElement(unit, children[i]); - if (d != null) - return d; - } - - return null; - } - } + /** + * Creates new content provider for dialog. + * @param viewer Tree viewer. + */ + public CContentOutlinerProvider(TreeViewer viewer) + { + super(true, true); + treeViewer = viewer; + setIncludesGrouping(PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.OUTLINE_GROUP_INCLUDES)); + } - class PropertyListener implements IPropertyChangeListener { + /** + * Sets new filter and updates contents. + * @param newFilter New filter. + */ + public void updateFilter(String newFilter) + { + filter = newFilter; + contentUpdated(); + } - /* (non-Javadoc) - * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) - */ - public void propertyChange(PropertyChangeEvent event) { - String prop = event.getProperty(); - if (prop.equals(PreferenceConstants.OUTLINE_GROUP_INCLUDES)) { - Object newValue = event.getNewValue(); - if (newValue instanceof Boolean) { - boolean value = ((Boolean)newValue).booleanValue(); - if (areIncludesGroup() != value) { - setIncludesGrouping(value); - if (fOutliner != null) { - fOutliner.contentUpdated(); - } - } - } - } else if (prop.equals(PreferenceConstants.OUTLINE_GROUP_NAMESPACES)) { - Object newValue = event.getNewValue(); - if (newValue instanceof Boolean) { - boolean value = ((Boolean)newValue).booleanValue(); - if (areNamespacesGroup() != value) { - setNamespacesGrouping(value); - if (fOutliner != null) { - fOutliner.contentUpdated(); - } - } - } - } - } + /** + * Called by the editor to signal that the content has updated. + */ + public void contentUpdated() + { + if (treeViewer != null && !treeViewer.getControl().isDisposed()) + { + treeViewer.getControl().getDisplay().asyncExec(new Runnable() + { + public void run() + { + if (!treeViewer.getControl().isDisposed()) + { + final ISelection sel = treeViewer.getSelection(); + treeViewer.setSelection(updateSelection(sel)); + treeViewer.refresh(); + } + } + } + ); + } + } - } + /** + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public void dispose() + { + super.dispose(); + if (fListener != null) + { + CoreModel.getDefault().removeElementChangedListener(fListener); + fListener = null; + } + if (fPropertyListener != null) { + PreferenceConstants.getPreferenceStore().removePropertyChangeListener(fPropertyListener); + fPropertyListener = null; + } + } - /** - * - */ - public CContentOutlinerProvider(CContentOutlinePage outliner) { - super(true, true); - fOutliner = outliner; - setIncludesGrouping(PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.OUTLINE_GROUP_INCLUDES)); - } + /** + * @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) + { + final boolean isTU = newInput instanceof ITranslationUnit; - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.IContentProvider#dispose() - */ - public void dispose() { - super.dispose(); - if (fListener != null) { - CoreModel.getDefault().removeElementChangedListener(fListener); - fListener= null; - } - if (fPropertyListener != null) { - PreferenceConstants.getPreferenceStore().removePropertyChangeListener(fPropertyListener); - fPropertyListener = null; - } - } + if (isTU && fListener == null) + { + root = (ITranslationUnit) newInput; + fListener = new ElementChangedListener(); + CoreModel.getDefault().addElementChangedListener(fListener); + fPropertyListener = new PropertyListener(); + PreferenceConstants.getPreferenceStore().addPropertyChangeListener(fPropertyListener); + } + else if (!isTU && fListener != null) + { + CoreModel.getDefault().removeElementChangedListener(fListener); + fListener = null; + root = null; + } + } - /* (non-Javadoc) - * @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) { - boolean isTU= (newInput instanceof ITranslationUnit); + /** + * @see org.eclipse.cdt.internal.ui.BaseCElementContentProvider#getChildren(java.lang.Object) + */ + public Object[] getChildren(Object element) + { + final StringMatcher stringMatcher = new StringMatcher(filter, true, false); + Object[] children = super.getChildren(element); + final List filtered = new ArrayList(); + for (int i = 0; i < children.length; i++) + { + if (stringMatcher.match(children[i].toString())) + { + filtered.add(children[i]); + } + } + final int size = filtered.size(); + children = new Object[size]; + filtered.toArray(children); + return children; + } - if (isTU && fListener == null) { - root = (ITranslationUnit)newInput; - fListener= new ElementChangedListener(); - CoreModel.getDefault().addElementChangedListener(fListener); - fPropertyListener = new PropertyListener(); - PreferenceConstants.getPreferenceStore().addPropertyChangeListener(fPropertyListener); - } else if (!isTU && fListener != null) { - CoreModel.getDefault().removeElementChangedListener(fListener); - fListener= null; - root = null; - } - } + /** + * Updates current selection. + * @param sel Selection to update. + * @return Updated selection. + */ + protected ISelection updateSelection(ISelection sel) + { + final ArrayList newSelection = new ArrayList(); + if (sel instanceof IStructuredSelection) + { + final Iterator iter = ((IStructuredSelection) sel).iterator(); + while (iter.hasNext()) + { + final Object o = iter.next(); + if (o instanceof ICElement) + { + newSelection.add(o); + } + } + } + return new StructuredSelection(newSelection); + } + + /** + * The element change listener of the C outline viewer. + * @see IElementChangedListener + */ + class ElementChangedListener implements IElementChangedListener + { + + /** + * Default constructor. + */ + public ElementChangedListener() + { + // nothing to initialize. + } + + /** + * @see org.eclipse.cdt.core.model.IElementChangedListener#elementChanged(org.eclipse.cdt.core.model.ElementChangedEvent) + */ + public void elementChanged(final ElementChangedEvent e) + { + final ICElementDelta delta = findElement(root, e.getDelta()); + if (delta != null) + { + contentUpdated(); + return; + } + } + + /** + * Determines is structural change. + * @param cuDelta Delta to check. + * @return true if structural change. + */ + private boolean isPossibleStructuralChange(ICElementDelta cuDelta) + { + boolean ret; + if (cuDelta.getKind() != ICElementDelta.CHANGED) + { + ret = true; // add or remove + } + else + { + final int flags = cuDelta.getFlags(); + if ((flags & ICElementDelta.F_CHILDREN) != 0) + { + ret = true; + } + else + { + ret = (flags & (ICElementDelta.F_CONTENT | ICElementDelta.F_FINE_GRAINED)) == ICElementDelta.F_CONTENT; + } + } + return ret; + } + + /** + * Searches for element. + * @param unit Unit to search in. + * @param delta Delta. + * @return Found element. + */ + protected ICElementDelta findElement(ICElement unit, ICElementDelta delta) + { + if (delta == null || unit == null) + { + return null; + } + + final ICElement element = delta.getElement(); + + if (unit.equals(element)) + { + if (isPossibleStructuralChange(delta)) + { + return delta; + } + return null; + } + + if (element.getElementType() > ICElement.C_UNIT) + { + return null; + } + + final ICElementDelta[] children = delta.getAffectedChildren(); + if (children == null || children.length == 0) + { + return null; + } + + for (int i = 0; i < children.length; i++) + { + final ICElementDelta d = findElement(unit, children[i]); + if (d != null) + { + return d; + } + } + + return null; + } + } + + /** + * + * Property change listener. + * @author P.Tomaszewski + */ + class PropertyListener implements IPropertyChangeListener { + + /** + * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) + */ + public void propertyChange(PropertyChangeEvent event){ + String prop = event.getProperty(); + if (prop.equals(PreferenceConstants.OUTLINE_GROUP_INCLUDES)) { + Object newValue = event.getNewValue(); + if (newValue instanceof Boolean) { + boolean value = ((Boolean)newValue).booleanValue(); + if (areIncludesGroup() != value) { + setIncludesGrouping(value); + contentUpdated(); + } + } + } else if (prop.equals(PreferenceConstants.OUTLINE_GROUP_NAMESPACES)) { + Object newValue = event.getNewValue(); + if (newValue instanceof Boolean) { + boolean value = ((Boolean)newValue).booleanValue(); + if (areNamespacesGroup() != value) { + setNamespacesGrouping(value); + contentUpdated(); + } + } + } + } + + } } 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 7b89dd662d5..1a268c2ba40 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 @@ -5,9 +5,7 @@ package org.eclipse.cdt.internal.ui.editor; * All Rights Reserved. */ -import java.util.ArrayList; import java.util.Iterator; -import java.util.List; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePreferenceConstants; @@ -55,13 +53,11 @@ import org.eclipse.jface.text.ILineTracker; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.ITextOperationTarget; import org.eclipse.jface.text.ITextSelection; -import org.eclipse.jface.text.ITextViewerExtension; import org.eclipse.jface.text.Position; import org.eclipse.jface.text.contentassist.ContentAssistant; import org.eclipse.jface.text.contentassist.IContentAssistant; import org.eclipse.jface.text.source.Annotation; import org.eclipse.jface.text.source.IAnnotationModel; -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; @@ -293,7 +289,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS * @param event the property change event */ protected void handlePreferenceStoreChanged(PropertyChangeEvent event) { - AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer(); + CSourceViewer asv = (CSourceViewer) getSourceViewer(); try { if (asv != null) { @@ -519,6 +515,12 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS preferenceStore.removePropertyChangeListener(fPropertyChangeListener); fPropertyChangeListener = null; } + + final CSourceViewer sourceViewer = (CSourceViewer) getSourceViewer(); + if (sourceViewer != null) + { + sourceViewer.unconfigure(); + } if (fSelectionUpdateListener != null) { getSelectionProvider().addSelectionChangedListener(fSelectionUpdateListener); @@ -653,7 +655,11 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS action = fShowInCViewAction; action.setActionDefinitionId(ICEditorActionDefinitionIds.OPEN_CVIEW); setAction("ShowInCView", action); //$NON-NLS-1$ - + + action = new TextOperationAction(CEditorMessages.getResourceBundle(), "OpenOutline.", this, CSourceViewer.SHOW_OUTLINE); + action.setActionDefinitionId(ICEditorActionDefinitionIds.OPEN_OUTLINE); + setAction("OpenOutline", action); //$NON-NLS-1$*/ + //Assorted action groupings fSelectionSearchGroup = new SelectionSearchGroup(this); fRefactoringActionGroup = new RefactoringActionGroup(this, null); @@ -686,8 +692,8 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS addAction(menu, IContextMenuConstants.GROUP_GENERATE, "Format"); //$NON-NLS-1$ addAction(menu, IContextMenuConstants.GROUP_GENERATE, "ShowInCView"); //$NON-NLS-1$ - - fRefactoringActionGroup.fillContextMenu(menu); + + fRefactoringActionGroup.fillContextMenu(menu); fSelectionSearchGroup.fillContextMenu(menu); } @@ -885,14 +891,14 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS fTabConverter = new TabConverter(); configureTabConverter(); fTabConverter.setNumberOfSpacesPerTab(getPreferenceStore().getInt(CSourceViewerConfiguration.PREFERENCE_TAB_WIDTH)); - AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer(); + CSourceViewer asv = (CSourceViewer) getSourceViewer(); asv.addTextConverter(fTabConverter); } } private void stopTabConversion() { if (fTabConverter != null) { - AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer(); + CSourceViewer asv = (CSourceViewer) getSourceViewer(); asv.removeTextConverter(fTabConverter); fTabConverter = null; } @@ -987,98 +993,6 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS public final static String LANGUAGE_CPP = "CEditor.language.cpp"; //$NON-NLS-1$ public final static String LANGUAGE_C = "CEditor.language.c"; //$NON-NLS-1$ - /** - * Adapted source viewer for CEditor - */ - - public class AdaptedSourceViewer extends ProjectionViewer implements ITextViewerExtension { - - private List fTextConverters; - private String fDisplayLanguage; - - public AdaptedSourceViewer( - Composite parent, - IVerticalRuler ruler, - int styles, - IOverviewRuler fOverviewRuler, - boolean isOverviewRulerShowing, - String language) { - super(parent, ruler, fOverviewRuler, isOverviewRulerShowing, styles); - fDisplayLanguage = language; - } - public IContentAssistant getContentAssistant() { - return fContentAssistant; - } - - /* - * @see ITextOperationTarget#doOperation(int) - */ - public void doOperation(int operation) { - - if (getTextWidget() == null) { - return; - } - switch (operation) { - case CONTENTASSIST_PROPOSALS: - String msg= fContentAssistant.showPossibleCompletions(); - setStatusLineErrorMessage(msg); - return; - } - super.doOperation(operation); - } - - public void insertTextConverter(ITextConverter textConverter, int index) { - throw new UnsupportedOperationException(); - } - - public void addTextConverter(ITextConverter textConverter) { - if (fTextConverters == null) { - fTextConverters = new ArrayList(1); - fTextConverters.add(textConverter); - } else if (!fTextConverters.contains(textConverter)) - fTextConverters.add(textConverter); - } - - public void removeTextConverter(ITextConverter textConverter) { - if (fTextConverters != null) { - fTextConverters.remove(textConverter); - if (fTextConverters.size() == 0) - fTextConverters = null; - } - } - - /* - * @see TextViewer#customizeDocumentCommand(DocumentCommand) - */ - protected void customizeDocumentCommand(DocumentCommand command) { - super.customizeDocumentCommand(command); - if (fTextConverters != null) { - for (Iterator e = fTextConverters.iterator(); e.hasNext();) - ((ITextConverter) e.next()).customizeDocumentCommand(getDocument(), command); - } - } - - public void setDisplayLanguage(String language) { - fDisplayLanguage = language; - } - - public String getDisplayLanguage() { - return fDisplayLanguage; - } - /* (non-Javadoc) - * @see org.eclipse.jface.text.source.ISourceViewer#setRangeIndication(int, int, boolean) - */ - public void setRangeIndication(int offset, int length, boolean moveCursor) { - // Fixin a bug in the ProjectViewer implemenation - // PR: https://bugs.eclipse.org/bugs/show_bug.cgi?id=72914 - if (isProjectionMode()) { - super.setRangeIndication(offset, length, moveCursor); - } else { - super.setRangeIndication(offset, length, false); - } - } - } - /* * @see AbstractTextEditor#createSourceViewer(Composite, IVerticalRuler, int) */ @@ -1102,13 +1016,14 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS fOverviewRuler = createOverviewRuler(sharedColors); ISourceViewer sourceViewer = - new AdaptedSourceViewer( - parent, + new CSourceViewer( + this, parent, ruler, styles, fOverviewRuler, isOverviewRulerVisible(), fileType); + sourceViewer.configure(getSourceViewerConfiguration()); fSourceViewerDecorationSupport = new SourceViewerDecorationSupport(sourceViewer, fOverviewRuler, fAnnotationAccess, sharedColors); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorMessages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorMessages.properties index b45e8a1dc04..f10569f7ac8 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorMessages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorMessages.properties @@ -75,6 +75,11 @@ OpenDeclarations.dialog.title=Open Declaration OpenDeclarations.label=&Open Declaration@F3 OpenDeclarations.tooltip=Open an editor on the selected element's declaration +OpenOutline.description=Shows outline +OpenOutline.dialog.title=Show outline +OpenOutline.label=&Show outline@Ctrl+O +OpenOutline.tooltip=Shows outline + OrganizeImports.description=Evaluate all required imports and replace the current imports OrganizeImports.error.message2=Syntax errors in compilation unit prevent correct evaluation\nof type references. Fix errors first. OrganizeImports.error.title1=Organize Imports diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CSourceViewer.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CSourceViewer.java new file mode 100644 index 00000000000..8a843d26281 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CSourceViewer.java @@ -0,0 +1,176 @@ +package org.eclipse.cdt.internal.ui.editor; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.cdt.internal.ui.editor.CEditor.ITextConverter; +import org.eclipse.cdt.internal.ui.text.CSourceViewerConfiguration; +import org.eclipse.jface.text.DocumentCommand; +import org.eclipse.jface.text.ITextViewerExtension; +import org.eclipse.jface.text.contentassist.IContentAssistant; +import org.eclipse.jface.text.information.IInformationPresenter; +import org.eclipse.jface.text.source.IOverviewRuler; +import org.eclipse.jface.text.source.IVerticalRuler; +import org.eclipse.jface.text.source.SourceViewerConfiguration; +import org.eclipse.jface.text.source.projection.ProjectionViewer; +import org.eclipse.swt.widgets.Composite; + +/** + * Adapted source viewer for CEditor + */ + +public class CSourceViewer extends ProjectionViewer implements ITextViewerExtension { + + /** Show outline operation id. */ + public static final int SHOW_OUTLINE = 101; + + /** Editor. */ + private final CEditor editor; + /** Presents outline. */ + private IInformationPresenter fOutlinePresenter; + + + private List fTextConverters; + private String fDisplayLanguage; + + /** + * Creates new source viewer. + * @param editor + * @param parent + * @param ruler + * @param styles + * @param fOverviewRuler + * @param isOverviewRulerShowing + * @param language + */ + public CSourceViewer( + CEditor editor, Composite parent, + IVerticalRuler ruler, + int styles, + IOverviewRuler fOverviewRuler, + boolean isOverviewRulerShowing, + String language) { + super(parent, ruler, fOverviewRuler, isOverviewRulerShowing, styles); + this.editor = editor; + fDisplayLanguage = language; + } + public IContentAssistant getContentAssistant() { + return fContentAssistant; + } + + /** + * @see org.eclipse.jface.text.source.SourceViewer#configure(org.eclipse.jface.text.source.SourceViewerConfiguration) + */ + public void configure(SourceViewerConfiguration configuration) + { + super.configure(configuration); + System.out.println("Configuration..."); + if (configuration instanceof CSourceViewerConfiguration) + { + System.out.println("configured"); + fOutlinePresenter = ((CSourceViewerConfiguration) configuration).getOutlinePresenter(editor); + fOutlinePresenter.install(this); + } + } + + /** + * @see org.eclipse.jface.text.source.SourceViewer#unconfigure() + */ + public void unconfigure() + { + if (fOutlinePresenter != null) { + fOutlinePresenter.uninstall(); + fOutlinePresenter= null; + } + super.unconfigure(); + } + + /** + * @see org.eclipse.jface.text.ITextOperationTarget#doOperation(int) + */ + public void doOperation(int operation) { + + if (getTextWidget() == null) { + return; + } + switch (operation) { + case CONTENTASSIST_PROPOSALS: + { + String msg= fContentAssistant.showPossibleCompletions(); + this.editor.setStatusLineErrorMessage(msg); + return; + } + case SHOW_OUTLINE: + { + System.out.println("Show outline operation called."); + fOutlinePresenter.showInformation(); + return; + } + } + super.doOperation(operation); + } + + /** + * @see org.eclipse.jface.text.source.projection.ProjectionViewer#canDoOperation(int) + */ + public boolean canDoOperation(int operation) + { + if (operation == SHOW_OUTLINE) + { + return fOutlinePresenter != null; + } + return super.canDoOperation(operation); + } + + public void insertTextConverter(ITextConverter textConverter, int index) { + throw new UnsupportedOperationException(); + } + + public void addTextConverter(ITextConverter textConverter) { + if (fTextConverters == null) { + fTextConverters = new ArrayList(1); + fTextConverters.add(textConverter); + } else if (!fTextConverters.contains(textConverter)) + fTextConverters.add(textConverter); + } + + public void removeTextConverter(ITextConverter textConverter) { + if (fTextConverters != null) { + fTextConverters.remove(textConverter); + if (fTextConverters.size() == 0) + fTextConverters = null; + } + } + + /* + * @see TextViewer#customizeDocumentCommand(DocumentCommand) + */ + protected void customizeDocumentCommand(DocumentCommand command) { + super.customizeDocumentCommand(command); + if (fTextConverters != null) { + for (Iterator e = fTextConverters.iterator(); e.hasNext();) + ((ITextConverter) e.next()).customizeDocumentCommand(getDocument(), command); + } + } + + public void setDisplayLanguage(String language) { + fDisplayLanguage = language; + } + + public String getDisplayLanguage() { + return fDisplayLanguage; + } + /* (non-Javadoc) + * @see org.eclipse.jface.text.source.ISourceViewer#setRangeIndication(int, int, boolean) + */ + public void setRangeIndication(int offset, int length, boolean moveCursor) { + // Fixin a bug in the ProjectViewer implemenation + // PR: https://bugs.eclipse.org/bugs/show_bug.cgi?id=72914 + if (isProjectionMode()) { + super.setRangeIndication(offset, length, moveCursor); + } else { + super.setRangeIndication(offset, length, false); + } + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICEditorActionDefinitionIds.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICEditorActionDefinitionIds.java index 18b0f15049b..91626e13556 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICEditorActionDefinitionIds.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICEditorActionDefinitionIds.java @@ -118,4 +118,9 @@ public interface ICEditorActionDefinitionIds extends ITextEditorActionDefinition */ public static final String OPEN_EDITOR= "org.eclipse.cdt.ui.edit.text.c.open.editor"; //$NON-NLS-1$ + /** + * Action definition ID of the open outline dialog. + * (value "org.eclipse.cdt.ui.edit.open.outline"). + */ + public static final String OPEN_OUTLINE= "org.eclipse.cdt.ui.edit.open.outline"; //$NON-NLS-1$ } 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 dcd38b0b03d..cc1e3f19e29 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 @@ -507,10 +507,10 @@ public class CEditorPreferencePage extends PreferencePage implements IWorkbenchP fOverlayStore.addPropertyChangeListener(new IPropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { String p = event.getProperty(); -// if (p.equals(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND) -// || p.equals(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT)) { + if (p.equals(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND) + || p.equals(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT)) { initializeViewerColors(fPreviewViewer); -// } + } fPreviewViewer.getDocument().set(fPreviewViewer.getDocument().get()); fPreviewViewer.invalidateTextPresentation(); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/COutlineInformationControl.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/COutlineInformationControl.java new file mode 100644 index 00000000000..2372c493df6 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/COutlineInformationControl.java @@ -0,0 +1,815 @@ +/* + * COutlineInformationControl.java 2004-12-14 / 08:17:41 + + * $Revision:$ $Date:$ + * + * @author P.Tomaszewski + */ +package org.eclipse.cdt.internal.ui.text; + +import org.eclipse.cdt.internal.core.model.CElement; +import org.eclipse.cdt.internal.ui.editor.CContentOutlinerProvider; +import org.eclipse.cdt.internal.ui.editor.CEditor; +import org.eclipse.cdt.internal.ui.util.ProblemTreeViewer; +import org.eclipse.cdt.internal.ui.viewsupport.DecoratingCLabelProvider; +import org.eclipse.cdt.internal.ui.viewsupport.StandardCElementLabelProvider; +import org.eclipse.cdt.ui.CElementGrouping; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.ui.IWorkingCopyManager; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.text.IInformationControl; +import org.eclipse.jface.text.IInformationControlExtension; +import org.eclipse.jface.text.IInformationControlExtension3; +import org.eclipse.jface.viewers.AbstractTreeViewer; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ControlAdapter; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.events.ShellAdapter; +import org.eclipse.swt.events.ShellEvent; +import org.eclipse.swt.events.ShellListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.FontMetrics; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +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.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeItem; + +/** + * Control which shows outline information in C/C++ editor. Based on + * AbstracInformationContol/JavaOutlineInformationControl from JDT. + * + * TODO: Bounds restoring, sorting. + * + * @author P.Tomaszewski + */ +public class COutlineInformationControl implements IInformationControl, + IInformationControlExtension, IInformationControlExtension3 { + /** Border thickness in pixels. */ + private static final int BORDER = 1; + + /** Right margin in pixels. */ + private static final int RIGHT_MARGIN = 3; + + /** Minimum width set by setSizeConstrains to tree viewer. */ + private static final int MIN_WIDTH = 300; + + /** Source viewer which shows this control. */ + private CEditor fEditor; + + /** Shell for this control. */ + private Shell fShell; + + /** Control's composite. */ + private Composite fComposite; + + /** Tree viewer used to display outline. */ + private TreeViewer fTreeViewer; + + /** Text control for filter. */ + private Text fFilterText; + + /** Content provider for tree control. */ + private IContentProvider fTreeContentProvider; + + /** Sorter for tree viewer. */ + private OutlineSorter fSorter; + + /** Control bounds. */ + private Rectangle fBounds; + + /** Control trim. */ + private Rectangle fTrim; + + /** Deactivation adapter. */ + private Listener fDeactivateListener; + + /** This prevents to notify listener when it is adding. */ + private boolean fIsDeactivationActive; + + /** Shell adapter, used for control deactivation. */ + private ShellListener fShellListener; + + /** Control adapter for shell, used in resize action. */ + private ControlListener fControlListener; + + /** Should outline be sorted. */ + private boolean fSort = true; + + /** + * Creates new outline control. + * + * @param editor + * CEditor editor which uses this control. + * @param parent + * Shell parent. + * @param shellStyle + * Style of new shell. + * @param treeStyle + * Style of the tree viewer. + */ + public COutlineInformationControl(CEditor editor, Shell parent, + int shellStyle, int treeStyle) { + super(); + this.fEditor = editor; + createShell(parent, shellStyle); + createComposite(); + createFilterText(); + createHorizontalSeparator(); + createTreeeViewer(treeStyle); + } + + /** + * @see org.eclipse.jface.text.IInformationControl#setInformation(java.lang.String) + */ + public void setInformation(String information) { + // Does not need implementation. + } + + /** + * @see org.eclipse.jface.text.IInformationControl#setSizeConstraints(int, + * int) + */ + public void setSizeConstraints(int maxWidth, int maxHeight) { + // Copied from AbstractInformationContol. + if (maxWidth > -1 && maxHeight > -1) { + final GridData gd = new GridData(GridData.FILL_BOTH); + if (maxWidth > -1) { + if (maxWidth < MIN_WIDTH) { + gd.widthHint = MIN_WIDTH; + } else { + gd.widthHint = maxWidth; + } + } + if (maxHeight > -1) { + gd.heightHint = maxHeight; + } + + fTreeViewer.getTree().setLayoutData(gd); + } + } + + /** + * @see org.eclipse.jface.text.IInformationControl#computeSizeHint() + */ + public Point computeSizeHint() { + return fShell.computeSize(SWT.DEFAULT, SWT.DEFAULT); + } + + /** + * @see org.eclipse.jface.text.IInformationControl#setVisible(boolean) + */ + public void setVisible(boolean visible) { + if (visible || fIsDeactivationActive) { + fShell.setVisible(visible); + } + } + + /** + * @see org.eclipse.jface.text.IInformationControl#setSize(int, int) + */ + public void setSize(int width, int height) { + fShell.setSize(width, height); + } + + /** + * @see org.eclipse.jface.text.IInformationControl#setLocation(org.eclipse.swt.graphics.Point) + */ + public void setLocation(Point location) { + fTrim = fShell.computeTrim(0, 0, 0, 0); + Point compositeLocation = fComposite.getLocation(); + location.x += fTrim.x - compositeLocation.x; + location.y += fTrim.y - compositeLocation.y; + fShell.setLocation(location); + } + + /** + * @see org.eclipse.jface.text.IInformationControl#dispose() + */ + public void dispose() { + if (fShell != null && !fShell.isDisposed()) { + fShell.removeShellListener(fShellListener); + fShell.removeListener(SWT.Deactivate, fDeactivateListener); + fShell.dispose(); + fFilterText.dispose(); + fComposite.dispose(); + } else { + fShell = null; + fComposite = null; + fTreeViewer = null; + fFilterText = null; + fDeactivateListener = null; + fShellListener = null; + } + } + + /** + * @see org.eclipse.jface.text.IInformationControl#addDisposeListener(org.eclipse.swt.events.DisposeListener) + */ + public void addDisposeListener(DisposeListener listener) { + fShell.addDisposeListener(listener); + } + + /** + * @see org.eclipse.jface.text.IInformationControl#removeDisposeListener(org.eclipse.swt.events.DisposeListener) + */ + public void removeDisposeListener(DisposeListener listener) { + fShell.removeDisposeListener(listener); + } + + /** + * @see org.eclipse.jface.text.IInformationControl#setForegroundColor(org.eclipse.swt.graphics.Color) + */ + public void setForegroundColor(Color foreground) { + fTreeViewer.getTree().setForeground(foreground); + fFilterText.setForeground(foreground); + fComposite.setForeground(foreground); + } + + /** + * @see org.eclipse.jface.text.IInformationControl#setBackgroundColor(org.eclipse.swt.graphics.Color) + */ + public void setBackgroundColor(Color background) { + fTreeViewer.getTree().setBackground(background); + fFilterText.setBackground(background); + fComposite.setBackground(background); + } + + /** + * @see org.eclipse.jface.text.IInformationControl#isFocusControl() + */ + public boolean isFocusControl() { + return fTreeViewer.getControl().isFocusControl() + || fFilterText.isFocusControl(); + } + + /** + * @see org.eclipse.jface.text.IInformationControl#setFocus() + */ + public void setFocus() { + fShell.forceFocus(); + fFilterText.setFocus(); + } + + /** + * @see org.eclipse.jface.text.IInformationControl#addFocusListener(org.eclipse.swt.events.FocusListener) + */ + public void addFocusListener(FocusListener listener) { + fShell.addFocusListener(listener); + } + + /** + * @see org.eclipse.jface.text.IInformationControl#removeFocusListener(org.eclipse.swt.events.FocusListener) + */ + public void removeFocusListener(FocusListener listener) { + fShell.removeFocusListener(listener); + } + + /** + * @see org.eclipse.jface.text.IInformationControlExtension#hasContents() + */ + public boolean hasContents() { + return fTreeViewer != null + && ((Tree) fTreeViewer.getControl()).getItemCount() > 0; + } + + /** + * @see org.eclipse.jface.text.IInformationControlExtension3#getBounds() + */ + public Rectangle getBounds() { + return fBounds; + } + + /** + * @see org.eclipse.jface.text.IInformationControlExtension3#computeTrim() + */ + public Rectangle computeTrim() { + // Copied from AbstractInformationControl. + if (fTrim != null) { + return fTrim; + } + return new Rectangle(0, 0, 0, 0); + } + + /** + * @see org.eclipse.jface.text.IInformationControlExtension3#restoresLocation() + */ + public boolean restoresLocation() { + // TODO: To implement. + return false; + } + + /** + * @see org.eclipse.jface.text.IInformationControlExtension3#restoresSize() + */ + public boolean restoresSize() { + // TODO: To implement. + return false; + } + + /** + * Creates shell for outline control. + * + * @param parent + * Parent shell. + * @param shellStyle + * Shell style. + */ + private void createShell(Shell parent, int shellStyle) { + fShell = new Shell(parent, shellStyle); + final Display display = fShell.getDisplay(); + fShell.setBackground(display.getSystemColor(SWT.COLOR_BLACK)); + final int border = ((shellStyle & SWT.NO_TRIM) == 0) ? 0 : BORDER; + fShell.setLayout(new BorderFillLayout(border)); + createDeactivationListener(); + fShell.addListener(SWT.Deactivate, fDeactivateListener); + fIsDeactivationActive = true; + createShellListener(); + fShell.addShellListener(fShellListener); + createControlListener(); + fShell.addControlListener(fControlListener); + } + + /** + * Creates composite of the outline control. + * + */ + private void createComposite() { + fComposite = new org.eclipse.swt.widgets.Composite(fShell, SWT.RESIZE); + GridLayout layout = new GridLayout(1, false); + fComposite.setLayout(layout); + fComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + } + + /** + * Creates tree viewer control. + */ + private void createTreeeViewer(int treeStyle) { + final IWorkingCopyManager manager = CUIPlugin.getDefault() + .getWorkingCopyManager(); + fTreeViewer = new ProblemTreeViewer(fComposite, treeStyle); + final Tree tree = fTreeViewer.getTree(); + tree.setLayoutData(new GridData(GridData.FILL_BOTH)); + fTreeContentProvider = new CContentOutlinerProvider(fTreeViewer); + fSorter = new OutlineSorter(); + fTreeViewer.setContentProvider(fTreeContentProvider); + fTreeViewer.setSorter(fSorter); + fTreeViewer.setLabelProvider(new DecoratingCLabelProvider( + new StandardCElementLabelProvider(), true)); + fTreeViewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS); + fTreeViewer.setInput(manager.getWorkingCopy(fEditor.getEditorInput())); + tree.addKeyListener(createKeyListenerForTreeViewer()); + tree.addSelectionListener(createSelectionListenerForTreeViewer()); + tree.addMouseMoveListener(createMouseMoveListenerForTreeViewer()); + tree.addMouseListener(createMouseListenerForTreeViewer()); + } + + /** + * Creates control for filter text. + */ + private void createFilterText() { + fFilterText = new Text(fComposite, SWT.NONE); + GridData data = new GridData(GridData.FILL_HORIZONTAL); + GC gc = new GC(fComposite); + gc.setFont(fComposite.getFont()); + FontMetrics fontMetrics = gc.getFontMetrics(); + gc.dispose(); + + data.heightHint = Dialog.convertHeightInCharsToPixels(fontMetrics, 1); + data.horizontalAlignment = GridData.FILL; + data.verticalAlignment = GridData.CENTER; + fFilterText.setLayoutData(data); + + fFilterText.addKeyListener(createKeyListenerForFilterContol()); + fFilterText.addModifyListener(createModifyListenerForFilterControl()); + } + + /** + * Creates horizontal separator between filter text and outline. + */ + private void createHorizontalSeparator() { + Label separator = new Label(fComposite, SWT.SEPARATOR | SWT.HORIZONTAL + | SWT.LINE_DOT); + separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + } + + /** + * Creates mouse listener for tree viewer. + * + * @return Created mouse listener. + */ + private MouseListener createMouseListenerForTreeViewer() { + final MouseListener mouseListener = new MouseAdapter() { + public void mouseUp(MouseEvent e) { + final Tree tree = fTreeViewer.getTree(); + if (tree.getSelectionCount() < 1) { + return; + } + if (e.button != 1) { + return; + } + + if (tree.equals(e.getSource())) { + Object o = tree.getItem(new Point(e.x, e.y)); + final TreeItem selection = tree.getSelection()[0]; + if (selection.equals(o)) { + CElement selectedElement = (CElement) selection + .getData(); + fEditor.setSelection(selectedElement); + dispose(); + } + fBounds = fComposite.getBounds(); + } + } + }; + return mouseListener; + } + + /** + * Creates mouse move listener for tree viewer. + * + * @return Mouse move listener. + */ + private MouseMoveListener createMouseMoveListenerForTreeViewer() { + // Copied from AbstractInformationControl. + final MouseMoveListener moveListener = new MouseMoveListener() { + TreeItem fLastItem = null; + + public void mouseMove(MouseEvent e) { + final Tree tree = fTreeViewer.getTree(); + if (tree.equals(e.getSource())) { + Object o = tree.getItem(new Point(e.x, e.y)); + if (o instanceof TreeItem) { + if (!o.equals(fLastItem)) { + fLastItem = (TreeItem) o; + tree.setSelection(new TreeItem[] { fLastItem }); + } else if (e.y < tree.getItemHeight() / 4) { + // Scroll up + Point p = tree.toDisplay(e.x, e.y); + Item item = fTreeViewer.scrollUp(p.x, p.y); + if (item instanceof TreeItem) { + fLastItem = (TreeItem) item; + tree.setSelection(new TreeItem[] { fLastItem }); + } + } else if (e.y > tree.getBounds().height + - tree.getItemHeight() / 4) { + // Scroll down + Point p = tree.toDisplay(e.x, e.y); + Item item = fTreeViewer.scrollDown(p.x, p.y); + if (item instanceof TreeItem) { + fLastItem = (TreeItem) item; + tree.setSelection(new TreeItem[] { fLastItem }); + } + } + } + } + } + }; + return moveListener; + } + + /** + * Creates selection listener for tree viewer. + * + * @return Created selection listener. + */ + private SelectionListener createSelectionListenerForTreeViewer() { + final SelectionListener selectionListener = new SelectionListener() { + /** + * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { + // Does not need implementation. + } + + /** + * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetDefaultSelected( + org.eclipse.swt.events.SelectionEvent e) { + final TreeItem[] selection = ((Tree) fTreeViewer.getControl()) + .getSelection(); + if (selection.length > 0) { + CElement selectedElement = (CElement) selection[0] + .getData(); + fEditor.setSelection(selectedElement); + dispose(); + } + } + }; + return selectionListener; + } + + /** + * Creates key listener for tree viewer. + * + * @return Created listener. + */ + private KeyListener createKeyListenerForTreeViewer() { + final KeyListener listener = new KeyListener() { + public void keyPressed(KeyEvent e) { + if (e.keyCode == 0x1B) // ESC + { + dispose(); + } + } + + public void keyReleased(KeyEvent e) { + // Does not need implementation. + } + }; + return listener; + } + + /** + * Creates modify listener for filter text control. + * + * @return Modify listener. + */ + private ModifyListener createModifyListenerForFilterControl() { + final ModifyListener modifyListener = new ModifyListener() { + public void modifyText(ModifyEvent e) { + String text = ((Text) e.widget).getText(); + final int length = text.length(); + if (length > 0 && text.charAt(length - 1) != '*') { + text = text + '*'; + } + ((CContentOutlinerProvider) fTreeContentProvider) + .updateFilter(text); + } + }; + return modifyListener; + } + + /** + * Creates key listener for filter text control. + * + * @return Key listener. + */ + private KeyListener createKeyListenerForFilterContol() { + final KeyListener keyListener = new KeyListener() { + /** + * @see org.eclipse.swt.events.KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent) + */ + public void keyPressed(KeyEvent e) { + if (e.keyCode == 0x0D) { + // Should select entered element. + } + if (e.keyCode == SWT.ARROW_DOWN) { + fTreeViewer.getTree().setFocus(); + } + if (e.keyCode == SWT.ARROW_UP) { + fTreeViewer.getTree().setFocus(); + } + if (e.character == 0x1B) // ESC + { + dispose(); + } + } + + /** + * @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent) + */ + public void keyReleased(KeyEvent e) { + // Does not need implementation. + } + }; + return keyListener; + } + + /** + * Creates control listener for shell. + */ + private void createControlListener() { + // Copied from AbstractInformationControl. + fControlListener = new ControlAdapter() { + /** + * @see org.eclipse.swt.events.ControlListener#controlMoved(org.eclipse.swt.events.ControlEvent) + */ + public void controlMoved(ControlEvent e) { + fBounds = fShell.getBounds(); + if (fTrim != null) { + final Point location = fComposite.getLocation(); + fBounds.x = fBounds.x - fTrim.x + location.x; + fBounds.y = fBounds.y - fTrim.y + location.y; + } + + } + + /** + * @see org.eclipse.swt.events.ControlListener#controlResized(org.eclipse.swt.events.ControlEvent) + */ + public void controlResized(ControlEvent e) { + fBounds = fShell.getBounds(); + if (fTrim != null) { + final Point location = fComposite.getLocation(); + fBounds.x = fBounds.x - fTrim.x + location.x; + fBounds.y = fBounds.y - fTrim.y + location.y; + } + } + }; + } + + /** + * Creates deactivation listener. It closes the control is shell becomes + * active. + */ + private void createDeactivationListener() { + fDeactivateListener = new Listener() { + /** + * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event) + */ + public void handleEvent(Event event) { + if (fIsDeactivationActive) { + dispose(); + } + } + }; + } + + /** + * Creates shell listener for management deactivation state. + */ + private void createShellListener() { + fShellListener = new ShellAdapter() { + /** + * @see org.eclipse.swt.events.ShellListener#shellActivated(org.eclipse.swt.events.ShellEvent) + */ + public void shellActivated(ShellEvent e) { + if (e.widget == fShell && fShell.getShells().length == 0) { + fIsDeactivationActive = true; + } + } + }; + } + + /** + * + * Border fill layout. Copied from AbstractInformationControl. + * + * @author P.Tomaszewski + */ + private static class BorderFillLayout extends Layout { + + /** The border widths. */ + final int fBorderSize; + + /** + * Creates a fill layout with a border. + * + * @param borderSize + * the border size + */ + public BorderFillLayout(int borderSize) { + if (borderSize < 0) + throw new IllegalArgumentException(); + fBorderSize = borderSize; + } + + /** + * Returns the border size. + * + * @return the border size + */ + public int getBorderSize() { + return fBorderSize; + } + + /** + * @see org.eclipse.swt.widgets.Layout#computeSize(org.eclipse.swt.widgets.Composite, + * int, int, boolean) + */ + protected Point computeSize(Composite composite, int wHint, int hHint, + boolean flushCache) { + + Control[] children = composite.getChildren(); + Point minSize = new Point(0, 0); + + if (children != null) { + for (int i = 0; i < children.length; i++) { + Point size = children[i].computeSize(wHint, hHint, + flushCache); + minSize.x = Math.max(minSize.x, size.x); + minSize.y = Math.max(minSize.y, size.y); + } + } + + minSize.x += fBorderSize * 2 + RIGHT_MARGIN; + minSize.y += fBorderSize * 2; + + return minSize; + } + + /** + * @see org.eclipse.swt.widgets.Layout#layout(org.eclipse.swt.widgets.Composite, + * boolean) + */ + protected void layout(Composite composite, boolean flushCache) { + + Control[] children = composite.getChildren(); + Point minSize = new Point(composite.getClientArea().width, + composite.getClientArea().height); + + if (children != null) { + for (int i = 0; i < children.length; i++) { + Control child = children[i]; + child.setSize(minSize.x - fBorderSize * 2, minSize.y + - fBorderSize * 2); + child.setLocation(fBorderSize, fBorderSize); + } + } + } + } + + /** + * A-Z Sorter for outline. + * + * @author P.Tomaszewski + */ + private class OutlineSorter extends ViewerSorter { + /** + * @see org.eclipse.jface.viewers.ViewerSorter#sort(org.eclipse.jface.viewers.Viewer, + * java.lang.Object[]) + */ + public void sort(Viewer viewer, Object[] elements) { + if (fSort) { + super.sort(viewer, elements); + } + } + + /** + * @see org.eclipse.jface.viewers.ViewerSorter#compare(org.eclipse.jface.viewers.Viewer, + * java.lang.Object, java.lang.Object) + */ + public int compare(Viewer viewer, Object e1, Object e2) { + int result = 0; + if (e1 instanceof CElementGrouping && e2 instanceof CElement) { + result = -1; + } else if (e1 instanceof CElement && e2 instanceof CElementGrouping) { + result = 1; + } else { + int elType1; + int elType2; + String elName1; + String elName2; + if (e1 instanceof CElement && e2 instanceof CElement) { + CElement cel1 = (CElement) e1; + CElement cel2 = (CElement) e2; + elType1 = cel1.getElementType(); + elType2 = cel2.getElementType(); + elName1 = cel1.getElementName(); + elName2 = cel2.getElementName(); + + } else { + CElementGrouping cel1 = (CElementGrouping) e1; + CElementGrouping cel2 = (CElementGrouping) e2; + elType1 = cel1.getType(); + elType2 = cel2.getType(); + elName1 = cel1.toString(); + elName2 = cel2.toString(); + } + if (elType1 == elType2) { + result = elName1.compareTo(elName2); + } else { + if (elType1 > elType2) { + result = -1; + } else if (elType1 < elType2) { + result = 1; + } else { + result = 0; + } + } + } + return result; + } + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CSourceViewerConfiguration.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CSourceViewerConfiguration.java index f12d91b0276..179577c275e 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CSourceViewerConfiguration.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CSourceViewerConfiguration.java @@ -6,11 +6,13 @@ package org.eclipse.cdt.internal.ui.text; import java.util.Vector; +import org.eclipse.cdt.internal.ui.editor.CSourceViewer; import org.eclipse.cdt.internal.ui.editor.CEditor; import org.eclipse.cdt.internal.ui.text.c.hover.CEditorTextHoverDescriptor; import org.eclipse.cdt.internal.ui.text.c.hover.CEditorTextHoverProxy; import org.eclipse.cdt.internal.ui.text.contentassist.CCompletionProcessor; import org.eclipse.cdt.internal.ui.text.contentassist.ContentAssistPreference; +import org.eclipse.cdt.ui.CElementContentProvider; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.text.DefaultInformationControl; @@ -27,6 +29,8 @@ import org.eclipse.jface.text.contentassist.IContentAssistant; import org.eclipse.jface.text.formatter.IContentFormatter; import org.eclipse.jface.text.formatter.MultiPassContentFormatter; import org.eclipse.jface.text.information.IInformationPresenter; +import org.eclipse.jface.text.information.IInformationProvider; +import org.eclipse.jface.text.information.InformationPresenter; import org.eclipse.jface.text.presentation.IPresentationReconciler; import org.eclipse.jface.text.presentation.PresentationReconciler; import org.eclipse.jface.text.reconciler.IReconciler; @@ -109,18 +113,36 @@ public class CSourceViewerConfiguration extends SourceViewerConfiguration { protected ITextEditor getEditor() { return fEditor; } - - /** - * @see ISourceViewerConfiguration#getPresentationReconciler(ISourceViewer) + + /** + * Creates outline presenter. + * @param editor Editor. + * @return Presenter with outline view. + */ + public IInformationPresenter getOutlinePresenter(CEditor editor) + { + final InformationPresenter presenter = new InformationPresenter(getOutlineContolCreator(editor)); + presenter.setSizeConstraints(20, 20, true, false); + final IInformationProvider provider = new CElementContentProvider(getEditor()); + presenter.setInformationProvider(provider, IDocument.DEFAULT_CONTENT_TYPE); + presenter.setInformationProvider(provider, ICPartitions.C_MULTILINE_COMMENT); + presenter.setInformationProvider(provider, ICPartitions.C_SINGLE_LINE_COMMENT); + presenter.setInformationProvider(provider, ICPartitions.C_STRING); + + return presenter; + } + + /** + * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getPresentationReconciler(org.eclipse.jface.text.source.ISourceViewer) */ - public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) { + public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) { PresentationReconciler reconciler= new PresentationReconciler(); RuleBasedScanner scanner; - if(sourceViewer instanceof CEditor.AdaptedSourceViewer) { - String language = ((CEditor.AdaptedSourceViewer)sourceViewer).getDisplayLanguage(); + if(sourceViewer instanceof CSourceViewer) { + String language = ((CSourceViewer)sourceViewer).getDisplayLanguage(); if(language != null && language.equals(CEditor.LANGUAGE_CPP)) { scanner= fTextTools.getCppCodeScanner(); } else { @@ -395,5 +417,30 @@ public class CSourceViewerConfiguration extends SourceViewerConfiguration { public IInformationPresenter getInformationPresenter(ISourceViewer sourceViewer) { return super.getInformationPresenter(sourceViewer); } + + + /** + * Creates control for outline presentation in editor. + * @param editor Editor. + * @return Control. + */ + private IInformationControlCreator getOutlineContolCreator(final CEditor editor) + { + final IInformationControlCreator conrolCreator = new IInformationControlCreator() + { + /** + * @see org.eclipse.jface.text.IInformationControlCreator#createInformationControl(org.eclipse.swt.widgets.Shell) + */ + public IInformationControl createInformationControl(Shell parent) + { + int shellStyle= SWT.RESIZE; + int treeStyle= SWT.V_SCROLL | SWT.H_SCROLL; + return new COutlineInformationControl(editor, parent, shellStyle, treeStyle); + } + }; + return conrolCreator; + } + + } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/ProblemTreeViewer.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/ProblemTreeViewer.java index 202b4516f7c..e90b9e5410e 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/ProblemTreeViewer.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/ProblemTreeViewer.java @@ -114,6 +114,17 @@ public class ProblemTreeViewer extends TreeViewer { return; } + /** + * @see org.eclipse.jface.viewers.StructuredViewer#update(java.lang.Object, java.lang.String[]) + */ + public void update(Object element, String[] properties) + { + /* Calling StructuredViewer.update() causes + * RunnableLock deadlock with StructuredViewer.doInternalUpdate() + * when long h file (with lots of declarations) is edited. + * This is only workaround, it only protects against + * deadlock but may cause other problems. */ + } /* (non-Javadoc) * @see org.eclipse.jface.viewers.AbstractTreeViewer#isExpandable(java.lang.Object) diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CElementContentProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CElementContentProvider.java index 4a2c6816552..5582386a1aa 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CElementContentProvider.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CElementContentProvider.java @@ -27,12 +27,20 @@ import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.internal.core.model.ArchiveContainer; import org.eclipse.cdt.internal.core.model.BinaryContainer; import org.eclipse.cdt.internal.ui.BaseCElementContentProvider; +import org.eclipse.cdt.internal.ui.actions.SelectionConverter; +import org.eclipse.cdt.internal.ui.text.CWordFinder; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.information.IInformationProvider; +import org.eclipse.jface.text.information.IInformationProviderExtension; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.StructuredViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.texteditor.ITextEditor; /** * A content provider for C elements. @@ -53,42 +61,30 @@ C model (ICModel)
* */ -public class CElementContentProvider extends BaseCElementContentProvider implements ITreeContentProvider, IElementChangedListener { +public class CElementContentProvider extends BaseCElementContentProvider implements ITreeContentProvider, IElementChangedListener, IInformationProvider, IInformationProviderExtension{ - protected StructuredViewer fViewer; + /** Editor. */ + protected ITextEditor fEditor; + protected StructuredViewer fViewer; protected Object fInput; - /* (non-Cdoc) - * Method declared on IContentProvider. - */ - public void dispose() { - super.dispose(); - CoreModel.getDefault().removeElementChangedListener(this); - } - - /* (non-Cdoc) - * Method declared on IContentProvider. - */ - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - - super.inputChanged(viewer, oldInput, newInput); - - fViewer = (StructuredViewer)viewer; - - if (oldInput == null && newInput != null) { - CoreModel.getDefault().addElementChangedListener(this); - } else if (oldInput != null && newInput == null) { - CoreModel.getDefault().removeElementChangedListener(this); - } - fInput= newInput; - } - + /** + * Creates a new content provider for C elements. + */ + public CElementContentProvider() + { + // Empty. + } + /** * Creates a new content provider for C elements. + * @param editor Editor. */ - public CElementContentProvider() { + public CElementContentProvider(ITextEditor editor) + { + fEditor = editor; } - + /** * Creates a new content provider for C elements. */ @@ -96,10 +92,35 @@ public class CElementContentProvider extends BaseCElementContentProvider impleme super(provideMembers, provideWorkingCopy); } - /* (non-Cdoc) - * Method declared on IElementChangedListener. + /** + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public void dispose() { + super.dispose(); + CoreModel.getDefault().removeElementChangedListener(this); + } + + /** + * @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) { + + super.inputChanged(viewer, oldInput, newInput); + + fViewer = (StructuredViewer) viewer; + + if (oldInput == null && newInput != null) { + CoreModel.getDefault().addElementChangedListener(this); + } else if (oldInput != null && newInput == null) { + CoreModel.getDefault().removeElementChangedListener(this); + } + fInput= newInput; + } + + /** + * @see org.eclipse.cdt.core.model.IElementChangedListener#elementChanged(org.eclipse.cdt.core.model.ElementChangedEvent) */ - public void elementChanged(final ElementChangedEvent event) { + public void elementChanged(final ElementChangedEvent event) { try { processDelta(event.getDelta()); } catch(CModelException e) { @@ -323,4 +344,44 @@ public class CElementContentProvider extends BaseCElementContentProvider impleme } } + /** + * @see org.eclipse.jface.text.information.IInformationProvider#getSubject(org.eclipse.jface.text.ITextViewer, int) + */ + public IRegion getSubject(ITextViewer textViewer, int offset) { + if (textViewer != null && fEditor != null) { + IRegion region = CWordFinder.findWord(textViewer.getDocument(), + offset); + if (region != null) { + return region; + } + return new Region(offset, 0); + } + return null; + } + + /** + * @see org.eclipse.jface.text.information.IInformationProvider#getInformation(org.eclipse.jface.text.ITextViewer, + * org.eclipse.jface.text.IRegion) + */ + public String getInformation(ITextViewer textViewer, IRegion subject) + { + return getInformation2(textViewer, subject).toString(); + } + + /** + * @see org.eclipse.jface.text.information.IInformationProviderExtension#getInformation2(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion) + */ + public Object getInformation2(ITextViewer textViewer, IRegion subject) { + if (fEditor == null) + return null; + try { + ICElement element = SelectionConverter.getElementAtOffset(fEditor); + if (element != null) { + return element.toString(); + } + return SelectionConverter.getInput(fEditor).toString(); + } catch (CModelException e) { + return null; + } + } }