### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.doc.user Index: contexts_JDT.xml =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.doc.user/contexts_JDT.xml,v retrieving revision 1.152 diff -u -r1.152 contexts_JDT.xml --- contexts_JDT.xml 27 Oct 2010 15:36:10 -0000 1.152 +++ contexts_JDT.xml 23 Nov 2010 23:23:44 -0000 @@ -88,6 +88,11 @@ Allows you to switch mark occurrences on and off. + + + Allows you to toggle method boundary lines on and off. + + This command evaluates the selected expression and shows the result in the Display view. Index: reference/preferences/java/ref-preferences-editor.htm =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.doc.user/reference/preferences/java/ref-preferences-editor.htm,v retrieving revision 1.5 diff -u -r1.5 ref-preferences-editor.htm --- reference/preferences/java/ref-preferences-editor.htm 6 Apr 2009 14:09:25 -0000 1.5 +++ reference/preferences/java/ref-preferences-editor.htm 23 Nov 2010 23:23:45 -0000 @@ -127,6 +127,21 @@ + Method boundary Lines + + +

+ If enabled, the Java editor will show the Method boundary lines to indicate the beginning and end of a method. +

+ + +

+ Off +

+ + + + Appearance color options @@ -151,6 +166,9 @@
Source hover background
The background color for the source hover. The source hover shows the source code of the element under the mouse pointer.
+ +
Method Boundary Lines
+
The color of the method boundary lines
Index: reference/views/ref-java-editor.htm =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.doc.user/reference/views/ref-java-editor.htm,v retrieving revision 1.7 diff -u -r1.7 ref-java-editor.htm --- reference/views/ref-java-editor.htm 3 Jun 2010 07:18:34 -0000 1.7 +++ reference/views/ref-java-editor.htm 23 Nov 2010 23:23:45 -0000 @@ -38,6 +38,22 @@ +

Toggle Method Boundary Lines

+ + +

+ Toggle Method Boundary Lines +

+ + +

+ This button shows the Method boundary lines in the Java Editor. +

+ + + + +

Toggle Java Editor Breadcrumb

#P org.eclipse.jdt.ui Index: plugin.properties =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/plugin.properties,v retrieving revision 1.540 diff -u -r1.540 plugin.properties --- plugin.properties 25 Oct 2010 14:46:12 -0000 1.540 +++ plugin.properties 23 Nov 2010 23:23:49 -0000 @@ -240,6 +240,10 @@ toggleMarkOccurrences.tooltip= Toggle Mark Occurrences toggleMarkOccurrences.description= Toggles mark occurrences in Java editors +toggleMethodBoundaryLines.label= Toggle Method Boundary Lines +toggleMethodBoundaryLines.tooltip= Toggle Method Boundary Lines +toggleMethodBoundaryLines.description= Toggles method boundary lines in Java editors + toggleBreadcrumb.label= Toggle Java Editor Breadcrumb toggleBreadcrumb.tooltip= Toggle Java Editor Breadcrumb toggleBreadcrumb.description= Toggle the Java editor breadcrumb Index: plugin.xml =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/plugin.xml,v retrieving revision 1.845 diff -u -r1.845 plugin.xml --- plugin.xml 8 Nov 2010 11:43:21 -0000 1.845 +++ plugin.xml 23 Nov 2010 23:23:55 -0000 @@ -1333,6 +1333,19 @@ retarget="true" tooltip="%toggleBreadcrumb.tooltip"> + + @@ -3557,6 +3570,12 @@ id="org.eclipse.jdt.ui.edit.text.java.toggleMarkOccurrences"> + + true if the method boundary lines preference is checked + * @since 3.7 + */ + protected boolean isShowingMethodBoundaryLines() { + IPreferenceStore store= getPreferenceStore(); + return store != null && store.getBoolean(PreferenceConstants.SHOW_METHOD_BOUNDARY_LINES); + } + + /** * @return true if editor breadcrumbs are enabled * @since 3.4 */ Index: ui/org/eclipse/jdt/internal/ui/javaeditor/MethodBoundaryLinesProvider.java =================================================================== RCS file: ui/org/eclipse/jdt/internal/ui/javaeditor/MethodBoundaryLinesProvider.java diff -N ui/org/eclipse/jdt/internal/ui/javaeditor/MethodBoundaryLinesProvider.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ui/org/eclipse/jdt/internal/ui/javaeditor/MethodBoundaryLinesProvider.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,609 @@ +package org.eclipse.jdt.internal.ui.javaeditor; + +import java.util.Iterator; + +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IPainter; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.AnnotationModel; +import org.eclipse.jface.text.source.AnnotationPainter; +import org.eclipse.jface.text.source.IAnnotationAccess; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.IAnnotationModelExtension; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.ISourceViewerExtension2; + +import org.eclipse.ui.texteditor.IDocumentProvider; + +import org.eclipse.jdt.core.ElementChangedEvent; +import org.eclipse.jdt.core.IElementChangedListener; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IJavaElementDelta; +import org.eclipse.jdt.core.IParent; +import org.eclipse.jdt.core.ISourceRange; +import org.eclipse.jdt.core.ISourceReference; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.ITypeRoot; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.JavaModelException; + +import org.eclipse.jdt.internal.ui.JavaPlugin; + +/** + * Draws lines that visually demarcate the boundary for methods and types. + * + * @since 3.7 + */ +class MethodBoundaryLinesProvider { + + /** + * Updates the annotation model to reflect the incoming element changes. + */ + private class ElementChangedListener implements IElementChangedListener { + + /* + * @see org.eclipse.jdt.core.IElementChangedListener#elementChanged(org.eclipse.jdt.core.ElementChangedEvent) + */ + public void elementChanged(ElementChangedEvent event) { + IJavaElementDelta delta= findElement(fInput, event.getDelta()); + if (delta != null && (delta.getFlags() & (IJavaElementDelta.F_CHILDREN | IJavaElementDelta.F_CONTENT)) != 0) { + //System.out.println("Element Changed: " + delta); + //if (shouldIgnoreDelta(event.getDelta().getCompilationUnitAST(), delta)) + // return; + if ((delta.getFlags() & IJavaElementDelta.F_CHILDREN) != 0) + updateAnnotationModel(delta.getAffectedChildren()); + else + updateAnnotationPositions(); + } + } + + /** + * Find the element in the java element delta that matches the target element. + * + * @param target the target java element to be searched for in the delta + * @param delta the java element delta that is to be searched for the target element + * @return the delta that contains the java element matching the target element + */ + private IJavaElementDelta findElement(IJavaElement target, IJavaElementDelta delta) { + + if (delta == null || target == null) + return null; + + IJavaElement element= delta.getElement(); + + if (element.getElementType() > IJavaElement.CLASS_FILE) + return null; + + if (target.equals(element)) + return delta; + + IJavaElementDelta[] children= delta.getAffectedChildren(); + + for (int i= 0; i < children.length; i++) { + IJavaElementDelta d= findElement(target, children[i]); + if (d != null) + return d; + } + + return null; + } + } + + /** + * The annotation model that holds the annotations for method boundary lines. + */ + private class MethodBoundaryAnnotationModel extends AnnotationModel { + private MethodBoundaryAnnotationModel() { + } + + /** + * Sets the position for the annotation associated with a given element to the new position. + * If position is null then the annotation, if found, is removed from the model. + * + * @param element the element whose corresponding annotation position is to be modified + * @param newPosition The new position for the concerned annotation + */ + public void modifyAnnotationForElement(IJavaElement element, Position newPosition) { + MethodBoundaryAnnotation methodBoundaryAnnotation= (MethodBoundaryAnnotation)getAnnotationForElement(element); + if (methodBoundaryAnnotation != null) + modifyAnnotationPosition(methodBoundaryAnnotation, newPosition); + } + + /** + * Searches and returns the annotation associated with given element. + * + * @param element the element whose associated annotation we are looking for + * @return returns the associated annotation if found, else returns null + */ + public Object getAnnotationForElement(IJavaElement element) { + Iterator iterator= getAnnotationIterator(); + while (iterator.hasNext()) { + MethodBoundaryAnnotation methodBoundaryAnnotation= (MethodBoundaryAnnotation)iterator.next(); + if (element.equals(methodBoundaryAnnotation.getElement())) { + return methodBoundaryAnnotation; + } + } + return null; + } + } + + /** + * The drawing strategy for method boundary lines draws the lines that visual separate methods + * and types. + */ + private static class MethodBoundaryDrawingStrategy implements AnnotationPainter.IDrawingStrategy { + + /* + * @see org.eclipse.jface.text.source.AnnotationPainter.IDrawingStrategy#draw(org.eclipse.swt.graphics.GC, org.eclipse.swt.custom.StyledText, int, int, org.eclipse.swt.graphics.Color) + */ + public void draw(Annotation annotation, GC gc, StyledText textWidget, int offset, int length, Color color) { + if (annotation instanceof MethodBoundaryAnnotation) { + MethodBoundaryAnnotation methodBoundaryAnnotation= (MethodBoundaryAnnotation)annotation; + if (gc != null) { + int lineIndex= textWidget.getLineAtOffset(offset); + int lineY= textWidget.getLinePixel(lineIndex); + IJavaElement element= methodBoundaryAnnotation.getElement(); + if (element.getElementType() == IJavaElement.TYPE) { + //System.out.println(methodBoundaryAnnotation.getElement().getElementName() + ": Off-" + offset + " Len-" + length + " Width-" + 2); + gc.setLineWidth(2); + lineY++; + } else { + //System.out.println(methodBoundaryAnnotation.getElement().getElementName() + ": Off-" + offset + " Len-" + length + " Width-" + 0); + gc.setLineWidth(0); + } + Color defaultColor= gc.getForeground(); + gc.setForeground(color); + gc.drawLine(2, lineY, textWidget.getClientArea().width, lineY); + gc.setForeground(defaultColor); + } else { + //System.out.println("Clearing: " + methodBoundaryAnnotation.getElement().getElementName() + ": " + offset + " " + length); + textWidget.redraw(2, textWidget.getLinePixel(textWidget.getLineAtOffset(offset)), textWidget.getClientArea().width, 2, true); + } + } + } + } + + /** + * Annotation for method boundary lines. + */ + private class MethodBoundaryAnnotation extends Annotation { + + /** + * The type for method boundary annotation. + */ + public static final String TYPE= "org.eclipse.separator"; //$NON-NLS-1$ + + /** + * The java element associated with this annotation. + */ + private IJavaElement fElementToBeAnnotated; + + /** + * Creates a new method boundary annotation. + * + * @param element the java element that this annotation is associated with + */ + public MethodBoundaryAnnotation(IJavaElement element) { + super(TYPE, false, null); + fElementToBeAnnotated= element; + } + + /** + * Getter for the java element associated with this annotation. + * + * @return returns the java element associated with this annotation + */ + public IJavaElement getElement() { + return fElementToBeAnnotated; + } + } + + /** + * Paints the method boundary lines. + */ + private class MethodBoundaryAnnotationsPainter extends AnnotationPainter { + + /** + * Constructs a new MethodSeparatorPainter. + * + * @param sourceViewer the source viewer for the painter + * @param access the annotation access + */ + public MethodBoundaryAnnotationsPainter(ISourceViewer sourceViewer, IAnnotationAccess access) { + super(sourceViewer, access); + } + + /** + * Retrieves the annotation model from the given source viewer. + * + * @param sourceViewer the source viewer + * @return the source viewer's annotation model or null if none can be found + */ + protected IAnnotationModel findAnnotationModel(ISourceViewer sourceViewer) { + if (sourceViewer != null && sourceViewer instanceof ISourceViewerExtension2) + return ((IAnnotationModelExtension)(((ISourceViewerExtension2)sourceViewer).getVisualAnnotationModel())).getAnnotationModel(METHOD_BOUNDARY); + return null; + } + } + + /** + * Key of the method boundary annotation model inside the visual annotation model. Also + * internally used as key for the drawing strategy. + */ + public final static Object METHOD_BOUNDARY= new Object(); + /** + * The source viewer associated with the editor. + */ + private JavaSourceViewer fViewer; + /** + * The method boundary painter that paints the boundary lines. + */ + private MethodBoundaryAnnotationsPainter fPainter; + + /** + * The annotation access. + */ + private IAnnotationAccess fAnnotationAccess; + /** + * The drawing strategy that is used for drawing the method boundary lines. + */ + private static AnnotationPainter.IDrawingStrategy fDrawingStrategy; + /** + * The method boundary annotation model that holds the annotations and is connected to the + * document. + */ + private MethodBoundaryAnnotationModel fMethodBoundaryAnnotationModel; + /** + * The listener that listens for element changes from the java model. + */ + private IElementChangedListener fElementListener; + /** + * The java input element associated with the java editor. + */ + private IJavaElement fInput; + /** + * The java editor. + */ + private JavaEditor fEditor; + /** + * Constructs the MethodBoundaryLinesProvider. + * + * @param editor the java editor + * @param viewer the source viewer associated with the editor + * @param annotationAccess the annotation access + * @param methodBoundaryColor the color to be used for drawing the method boundary lines + */ + public MethodBoundaryLinesProvider(JavaEditor editor, JavaSourceViewer viewer, IAnnotationAccess annotationAccess, Color methodBoundaryColor) { + fEditor= editor; + fViewer= viewer; + fAnnotationAccess= annotationAccess; + if (fPainter == null) { + fPainter= new MethodBoundaryAnnotationsPainter(fViewer, fAnnotationAccess); + fPainter.addDrawingStrategy(METHOD_BOUNDARY, getDrawingStrategy()); + fPainter.addAnnotationType(MethodBoundaryAnnotation.TYPE, METHOD_BOUNDARY); + fPainter.setAnnotationTypeColor(MethodBoundaryAnnotation.TYPE, methodBoundaryColor); + fViewer.addPainter(fPainter); + } + + fInput= EditorUtility.getEditorInputJavaElement(fEditor, false); + fMethodBoundaryAnnotationModel= new MethodBoundaryAnnotationModel(); + try { + initializeModel(((IParent)fInput).getChildren()); + } catch (JavaModelException e) { + JavaPlugin.log(e); + } + ((IAnnotationModelExtension)(fViewer.getVisualAnnotationModel())).addAnnotationModel(METHOD_BOUNDARY, fMethodBoundaryAnnotationModel); + if (fElementListener == null) { + //System.out.println("New Listener Registered: " + fEditor.getContentDescription()); + fElementListener= new ElementChangedListener(); + JavaCore.addElementChangedListener(fElementListener); + } + } + + /** + * Initializes the annotation model with annotations based on the array of java elements. + * + * @param elements the java elements for which the annotation model is to be initialized + */ + private void initializeModel(IJavaElement[] elements) { + for (int i= 0; i < elements.length; i++) { + int elementType= elements[i].getElementType(); + try { + if (isElementOfTypeWeCanAnnotate(elements[i])) { + if (isMethodOrType(elementType)) { + fMethodBoundaryAnnotationModel.addAnnotation(new MethodBoundaryAnnotation(elements[i]), getAlignedFirstLineElementPosition(elements[i])); + } else if (i != 0 && isMethodOrType(elements[i - 1].getElementType())) { + fMethodBoundaryAnnotationModel.addAnnotation(new MethodBoundaryAnnotation(elements[i]), getAlignedFirstLineElementPosition(elements[i])); + } + } + if (elements[i] instanceof IParent) { + IJavaElement[] children= ((IParent)elements[i]).getChildren(); + if (children.length > 0) + initializeModel(children); + } + } catch (JavaModelException e) { + JavaPlugin.log(e); + } + } + } + + /** + * Get the aligned position of the first line of the java element. + * + * @param element the java element whose first line position is to be determined + * @return returns the position of the first line of the java element + */ + private Position getAlignedFirstLineElementPosition(IJavaElement element) { + IDocument document= getDocument(); + try { + ISourceRange sourceRange= ((ISourceReference)element).getSourceRange(); + IRegion elementFirstLineRegion= document.getLineInformationOfOffset(sourceRange.getOffset()); + return new Position(elementFirstLineRegion.getOffset(), elementFirstLineRegion.getLength()); + } catch (JavaModelException e) { + JavaPlugin.log(e); + } catch (BadLocationException e) { + JavaPlugin.log(e); + } + return null; + } + + /** + * Returns true if the element type is one of the types that we can annotate and it + * should not be of primary type. Types we can annotate are TYPE, METHOD, FIELD & INITIALIZER. + * + * @param element the element whose type is to be checked + * @return true if element type matches any in our list + */ + private boolean isElementOfTypeWeCanAnnotate(IJavaElement element) { + int elementType= element.getElementType(); + if (element instanceof ISourceReference && ((elementType == IJavaElement.TYPE && !isPrimaryType((IType)element)) + || elementType == IJavaElement.METHOD || elementType == IJavaElement.FIELD + || elementType == IJavaElement.INITIALIZER)) { + return true; + } + return false; + } + + /** + * Returns true if type is not a top-level type, false if + * it is. + * + * @param type the type to test + * @return true if type is an inner type + */ + private boolean isInnerType(IType type) { + return type.getDeclaringType() != null; + } + + /** + * Returns true if element is the primary type, false if + * it is not. This is based on {@link ITypeRoot#findPrimaryType()}. + * + * @param element the element to be evaluated if it is the primary type + * @return true if it is the primary type + */ + private boolean isPrimaryType(IType element) { + IType primaryType= ((ITypeRoot)fInput).findPrimaryType(); + if (primaryType != null && primaryType.equals(element)) + return true; + return false; + } + + /** + * Update the annotations in the method boundary annotation model with the + * {@link IJavaElementDelta} changes. Based on ({@link IJavaElementDelta#getKind()}, annotation + * corresponding to the element in the delta is added, removed or changed. + * + * @param delta the java element deltas that contain the changes done to the Java model + */ + private void updateAnnotationModel(IJavaElementDelta[] delta) { + for (int i= 0; i < delta.length; i++) { + IJavaElement element= delta[i].getElement(); + if (isElementOfTypeWeCanAnnotate(element)) { + int elementType= element.getElementType(); + int deltaKind= delta[i].getKind(); + if (deltaKind == IJavaElementDelta.REMOVED) { + //System.out.println("Element 'Removed': " + element.getElementName()); + fMethodBoundaryAnnotationModel.modifyAnnotationForElement(element, null); + updateAnnotationModelForDanglingElements(element.getParent()); + + } else if (deltaKind == IJavaElementDelta.ADDED) { + if (!isMethodOrType(elementType) && isElementAfterTypeOrMethod(element)) { + //modifyAnnotationForNextElement(element, false); + addAnnotationForNewElementToModel(element); + updateAnnotationModelForDanglingElements(element.getParent()); + } else if (isMethodOrType(elementType)) { + //modifyAnnotationForNextElement(element, true); + addAnnotationForNewElementToModel(element); + updateAnnotationModelForDanglingElements(element.getParent()); + } + } else if (deltaKind == IJavaElementDelta.CHANGED) { + //System.out.println("Element 'Changed': " + element.getElementName()); + fMethodBoundaryAnnotationModel.modifyAnnotationForElement(element, getAlignedFirstLineElementPosition(element)); + } + } + if (element instanceof IParent) { + updateAnnotationModel(delta[i].getAffectedChildren()); + } + } + } + + /** + * Return true if the given elementType is of type {@link IJavaElement#METHOD} or + * {@link IJavaElement#TYPE}. + * + * @param elementType the element type to check against + * @return true if the given elementType is of type {@link IJavaElement#METHOD} or + * {@link IJavaElement#TYPE} + */ + private boolean isMethodOrType(int elementType) { + if (elementType == IJavaElement.METHOD || elementType == IJavaElement.TYPE) + return true; + return false; + } + + /** + * For all the children of parentElement, it checks and updates if any does not have a required + * Method boundary. + * + * @param parentElement the parent element whose children are checked for missing boundary lines + */ + private void updateAnnotationModelForDanglingElements(IJavaElement parentElement) { + try { + if (parentElement != null && parentElement.getElementType() == IJavaElement.TYPE && ((IType)parentElement).hasChildren()) { + IJavaElement[] childrenElements= ((IType)parentElement).getChildren(); + for (int i= 0; i < childrenElements.length; i++) { + int childElementType= childrenElements[i].getElementType(); + if (!isMethodOrType(childElementType)) { + if (i == 0) { + fMethodBoundaryAnnotationModel.modifyAnnotationForElement(childrenElements[i], null); + } else { + childElementType= childrenElements[i - 1].getElementType(); + if (isMethodOrType(childElementType) && isElementOfTypeWeCanAnnotate(childrenElements[i]) + && fMethodBoundaryAnnotationModel.getAnnotationForElement(childrenElements[i]) == null) { + fMethodBoundaryAnnotationModel.addAnnotation(new MethodBoundaryAnnotation(childrenElements[i]), getAlignedFirstLineElementPosition(childrenElements[i])); + } else if (!isMethodOrType(childElementType)) { + fMethodBoundaryAnnotationModel.modifyAnnotationForElement(childrenElements[i], null); + } + } + } + } + } + } catch (JavaModelException e) { + JavaPlugin.log(e); + } + } + + /** + * Returns true if the given element is immediately preceded by an element of type + * IJavaElement.METHOD or TYPE in the source code. + * + * @param element the element + * @return true if the given element is preceded by an IMethod or IType element + */ + private boolean isElementAfterTypeOrMethod(IJavaElement element) { + try { + IJavaElement parentElement= element.getParent(); + if (parentElement != null && parentElement.getElementType() == IJavaElement.TYPE && ((IType)parentElement).hasChildren()) { + IJavaElement[] childrenElements= ((IType)parentElement).getChildren(); + for (int i= 0; i < childrenElements.length; i++) { + if (childrenElements[i].equals(element)) { + if (i == 0) + return false; + int childElementType= childrenElements[i - 1].getElementType(); + if (childElementType == IJavaElement.METHOD || (childElementType == IJavaElement.TYPE && isInnerType((IType)childrenElements[i - 1]))) { + return true; + } + } + } + } + } catch (JavaModelException e) { + JavaPlugin.log(e); + } + return false; + } + + /** + * For a new element added to the Java, create and add an annotation to the method boundary + * annotation model. + * + * @param element the new element for which annotation is to be added to the annotation model + */ + private void addAnnotationForNewElementToModel(IJavaElement element) { + //System.out.println("Element 'Added': " + element.getElementName()); + fMethodBoundaryAnnotationModel.addAnnotation(new MethodBoundaryAnnotation(element), getAlignedFirstLineElementPosition(element)); + if (element instanceof IParent) { + try { + IJavaElement[] children= ((IParent)element).getChildren(); + for (int i= 0; i < children.length; i++) { + int elementType= children[i].getElementType(); + if (elementType == IJavaElement.METHOD || elementType == IJavaElement.TYPE) { + addAnnotationForNewElementToModel(children[i]); + } + } + } catch (JavaModelException e) { + JavaPlugin.log(e); + } + } + } + + /** + * Update the Positions in the annotation model for all the elements whose current source range + * in the document is different from the Position stored with the corresponding annotation. + */ + private void updateAnnotationPositions() { + Iterator iterator= fMethodBoundaryAnnotationModel.getAnnotationIterator(); + while (iterator.hasNext()) { + MethodBoundaryAnnotation methodBoundaryAnnotation= (MethodBoundaryAnnotation)iterator.next(); + Position existingPosition= fMethodBoundaryAnnotationModel.getPosition(methodBoundaryAnnotation); + IJavaElement element= methodBoundaryAnnotation.getElement(); + if (element != null && ((ISourceReference)element).exists()) { + Position newPosition= getAlignedFirstLineElementPosition(element); + if (newPosition.getOffset() != existingPosition.getOffset() || newPosition.getLength() != existingPosition.getLength()) { + fMethodBoundaryAnnotationModel.modifyAnnotationPosition(methodBoundaryAnnotation, newPosition); + } + } + } + } + + /** + * Gets the document associated with the Java editor. + * + * @return returns the document + */ + private IDocument getDocument() { + JavaEditor editor= fEditor; + if (editor == null) + return null; + + IDocumentProvider provider= editor.getDocumentProvider(); + if (provider == null) + return null; + + return provider.getDocument(editor.getEditorInput()); + } + + /** + * Returns the drawing strategy to be used by the method boundary annotation painter. + * + * @return the drawing strategy to be used by the method boundary annotation painter + */ + private AnnotationPainter.IDrawingStrategy getDrawingStrategy() { + if (fDrawingStrategy == null) + fDrawingStrategy= new MethodBoundaryDrawingStrategy(); + return fDrawingStrategy; + } + + /** + * Disposes the method boundary lines provider and associated painter. + */ + public void dispose() { + if (fPainter != null) { + fViewer.removePainter(fPainter); + fPainter.deactivate(true); + fPainter.dispose(); + fPainter= null; + } + fMethodBoundaryAnnotationModel= null; + JavaCore.removeElementChangedListener(fElementListener); + fViewer= null; + fEditor= null; + } + + /** + * Sets the color for the method boundary lines. + * + * @param methodBoundaryColor the color to be used for drawing the method boundary lines + */ + public void setColor(Color methodBoundaryColor) { + fPainter.setAnnotationTypeColor(MethodBoundaryAnnotation.TYPE, methodBoundaryColor); + fPainter.paint(IPainter.CONFIGURATION); + } +} \ No newline at end of file Index: ui/org/eclipse/jdt/internal/ui/javaeditor/ToggleMethodBoundaryLinesAction.java =================================================================== RCS file: ui/org/eclipse/jdt/internal/ui/javaeditor/ToggleMethodBoundaryLinesAction.java diff -N ui/org/eclipse/jdt/internal/ui/javaeditor/ToggleMethodBoundaryLinesAction.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ui/org/eclipse/jdt/internal/ui/javaeditor/ToggleMethodBoundaryLinesAction.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.ui.javaeditor; + + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; + +import org.eclipse.ui.PlatformUI; + +import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.ui.texteditor.TextEditorAction; + +import org.eclipse.jdt.ui.PreferenceConstants; + +import org.eclipse.jdt.internal.ui.IJavaHelpContextIds; +import org.eclipse.jdt.internal.ui.JavaPlugin; +import org.eclipse.jdt.internal.ui.JavaPluginImages; + + +/** + * A toolbar action which toggles the + * {@linkplain org.eclipse.jdt.ui.PreferenceConstants#SHOW_METHOD_BOUNDARY_LINES preference}. + * + * @since 3.7 + */ +public class ToggleMethodBoundaryLinesAction extends TextEditorAction implements IPropertyChangeListener { + + private IPreferenceStore fStore; + + /** + * Constructs and updates the action. + */ + public ToggleMethodBoundaryLinesAction() { + super(JavaEditorMessages.getBundleForConstructedKeys(), "ToggleMethodBoundaryLinesAction.", null, IAction.AS_CHECK_BOX); //$NON-NLS-1$ + JavaPluginImages.setToolImageDescriptors(this, "toggle_method_boundary.gif"); //$NON-NLS-1$ + PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.TOGGLE_METHOD_BOUNDARY_LINES_ACTION); + update(); + } + + /* + * @see IAction#actionPerformed + */ + public void run() { + fStore.setValue(PreferenceConstants.SHOW_METHOD_BOUNDARY_LINES, isChecked()); + } + + /* + * @see TextEditorAction#update + */ + public void update() { + ITextEditor editor= getTextEditor(); + + boolean checked= false; + if (editor instanceof JavaEditor) + checked= ((JavaEditor)editor).isShowingMethodBoundaryLines(); + + setChecked(checked); + setEnabled(editor != null); + } + + /* + * @see TextEditorAction#setEditor(ITextEditor) + */ + public void setEditor(ITextEditor editor) { + + super.setEditor(editor); + + if (editor != null) { + + if (fStore == null) { + fStore= JavaPlugin.getDefault().getPreferenceStore(); + fStore.addPropertyChangeListener(this); + } + + } else if (fStore != null) { + fStore.removePropertyChangeListener(this); + fStore= null; + } + + update(); + } + + /* + * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent) + */ + public void propertyChange(PropertyChangeEvent event) { + if (event.getProperty().equals(PreferenceConstants.SHOW_METHOD_BOUNDARY_LINES)) + setChecked(Boolean.valueOf(event.getNewValue().toString()).booleanValue()); + } +} Index: ui/org/eclipse/jdt/internal/ui/preferences/JavaEditorAppearanceConfigurationBlock.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/JavaEditorAppearanceConfigurationBlock.java,v retrieving revision 1.29 diff -u -r1.29 JavaEditorAppearanceConfigurationBlock.java --- ui/org/eclipse/jdt/internal/ui/preferences/JavaEditorAppearanceConfigurationBlock.java 7 Oct 2010 09:57:54 -0000 1.29 +++ ui/org/eclipse/jdt/internal/ui/preferences/JavaEditorAppearanceConfigurationBlock.java 23 Nov 2010 23:24:03 -0000 @@ -59,6 +59,7 @@ {PreferencesMessages.JavaEditorPreferencePage_backgroundForCompletionReplacement, PreferenceConstants.CODEASSIST_REPLACEMENT_BACKGROUND, null }, {PreferencesMessages.JavaEditorPreferencePage_foregroundForCompletionReplacement, PreferenceConstants.CODEASSIST_REPLACEMENT_FOREGROUND, null }, {PreferencesMessages.JavaEditorPreferencePage_sourceHoverBackgroundColor, PreferenceConstants.EDITOR_SOURCE_HOVER_BACKGROUND_COLOR, PreferenceConstants.EDITOR_SOURCE_HOVER_BACKGROUND_COLOR_SYSTEM_DEFAULT}, + { PreferencesMessages.JavaEditorPreferencePage_methodBoundaryLinesColor, PreferenceConstants.METHOD_BOUNDARY_LINES_COLOR, null }, }; @@ -84,6 +85,8 @@ overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_SUB_WORD_NAVIGATION)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_EVALUTE_TEMPORARY_PROBLEMS)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_SHOW_SEGMENTS)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.SHOW_METHOD_BOUNDARY_LINES)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.METHOD_BOUNDARY_LINES_COLOR)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.CODEASSIST_PARAMETERS_BACKGROUND)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.CODEASSIST_PARAMETERS_FOREGROUND)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.CODEASSIST_REPLACEMENT_BACKGROUND)); @@ -234,6 +237,9 @@ label= PreferencesMessages.JavaEditorPreferencePage_showJavaElementOnly; addCheckBox(appearanceComposite, label, PreferenceConstants.EDITOR_SHOW_SEGMENTS, 0); + label= PreferencesMessages.JavaEditorPreferencePage_ShowMethodBoundaryLines; + addCheckBox(appearanceComposite, label, PreferenceConstants.SHOW_METHOD_BOUNDARY_LINES, 0); + Label l= new Label(appearanceComposite, SWT.LEFT ); gd= new GridData(GridData.HORIZONTAL_ALIGN_FILL); gd.horizontalSpan= 2; Index: ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.java,v retrieving revision 1.137 diff -u -r1.137 PreferencesMessages.java --- ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.java 5 Nov 2010 05:49:58 -0000 1.137 +++ ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.java 23 Nov 2010 23:24:04 -0000 @@ -151,6 +151,8 @@ public static String JavaEditorPreferencePage_enable; public static String JavaEditorPreferencePage_preview; public static String JavaEditorPreferencePage_highlightMatchingBrackets; + + public static String JavaEditorPreferencePage_ShowMethodBoundaryLines; public static String JavaEditorPreferencePage_insertSingleProposalsAutomatically; public static String JavaEditorPreferencePage_showOnlyProposalsVisibleInTheInvocationContext; public static String JavaEditorPreferencePage_presentProposalsInAlphabeticalOrder; @@ -178,6 +180,8 @@ public static String JavaEditorPreferencePage_empty_input; public static String JavaEditorPreferencePage_invalid_input; public static String JavaEditorPreferencePage_matchingBracketsHighlightColor2; + + public static String JavaEditorPreferencePage_methodBoundaryLinesColor; public static String JavaEditorPreferencePage_appearanceOptions; public static String JavaEditorPreferencePage_typing_tabTitle; public static String JavaEditorPreferencePage_closeStrings; Index: ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.properties =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.properties,v retrieving revision 1.521 diff -u -r1.521 PreferencesMessages.properties --- ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.properties 5 Nov 2010 05:49:58 -0000 1.521 +++ ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.properties 23 Nov 2010 23:24:06 -0000 @@ -131,6 +131,7 @@ JavaEditorPreferencePage_enable=Enab&le JavaEditorPreferencePage_preview=Previe&w: JavaEditorPreferencePage_highlightMatchingBrackets=Highlight &matching brackets +JavaEditorPreferencePage_ShowMethodBoundaryLines=Separator line &between types and method JavaEditorPreferencePage_insertSingleProposalsAutomatically=Insert single &proposals automatically JavaEditorPreferencePage_showOnlyProposalsVisibleInTheInvocationContext=Hide proposals not visible in the in&vocation context JavaEditorPreferencePage_presentProposalsInAlphabeticalOrder=&Sort proposals @@ -160,6 +161,7 @@ JavaEditorPreferencePage_empty_input=Empty input JavaEditorPreferencePage_invalid_input=''{0}'' is not a valid input. JavaEditorPreferencePage_matchingBracketsHighlightColor2=Matching brackets highlight +JavaEditorPreferencePage_methodBoundaryLinesColor= Separator line between types and method JavaEditorPreferencePage_appearanceOptions=Appearance co&lor options: JavaEditorPreferencePage_typing_tabTitle=T&yping Index: ui/org/eclipse/jdt/ui/PreferenceConstants.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/PreferenceConstants.java,v retrieving revision 1.257 diff -u -r1.257 PreferenceConstants.java --- ui/org/eclipse/jdt/ui/PreferenceConstants.java 5 Nov 2010 05:49:58 -0000 1.257 +++ ui/org/eclipse/jdt/ui/PreferenceConstants.java 23 Nov 2010 23:24:09 -0000 @@ -2275,11 +2275,32 @@ public static final String EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK= "browserLikeLinksKeyModifierMask"; //$NON-NLS-1$ /** + * A named preference that controls whether method boundary lines are shown in the editor. + *

+ * Value is of type Boolean. + *

+ * + * @since 3.7 + */ + public static final String SHOW_METHOD_BOUNDARY_LINES= "showMethodBoundaryLines"; //$NON-NLS-1$ + + /** + * A named preference that holds the color used for method boundary lines. + *

+ * Value is of type String. A RGB color value encoded as a string using class + * PreferenceConverter + *

+ * + * @since 3.7 + */ + public static final String METHOD_BOUNDARY_LINES_COLOR= "methodBoundaryLinesColor"; //$NON-NLS-1$ + + /** * A named preference that controls whether occurrences are marked in the editor. *

* Value is of type Boolean. *

- * + * * @since 3.0 */ public static final String EDITOR_MARK_OCCURRENCES= "markOccurrences"; //$NON-NLS-1$ @@ -3707,6 +3728,7 @@ // JavaEditorPreferencePage store.setDefault(PreferenceConstants.EDITOR_MATCHING_BRACKETS, true); + store.setDefault(PreferenceConstants.SHOW_METHOD_BOUNDARY_LINES, false); store.setDefault(PreferenceConstants.EDITOR_CORRECTION_INDICATION, true); store.setDefault(PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE, true); Index: ui/org/eclipse/jdt/ui/actions/IJavaEditorActionDefinitionIds.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/IJavaEditorActionDefinitionIds.java,v retrieving revision 1.76 diff -u -r1.76 IJavaEditorActionDefinitionIds.java --- ui/org/eclipse/jdt/ui/actions/IJavaEditorActionDefinitionIds.java 25 Oct 2010 08:42:46 -0000 1.76 +++ ui/org/eclipse/jdt/ui/actions/IJavaEditorActionDefinitionIds.java 23 Nov 2010 23:24:09 -0000 @@ -718,8 +718,17 @@ public static final String TOGGLE_MARK_OCCURRENCES= "org.eclipse.jdt.ui.edit.text.java.toggleMarkOccurrences"; //$NON-NLS-1$ /** - * Action definition id of toggle breadcrumb action - * (value: "org.eclipse.jdt.ui.edit.text.java.toggleBreadcrumb"). + * Action definition id of toggle method boundary lines action (value: + * "org.eclipse.jdt.ui.edit.text.java.toggleMethodBoundaryLines"). + * + * @since 3.7 + */ + public static final String TOGGLE_METHOD_BOUNDARY_LINES= "org.eclipse.jdt.ui.edit.text.java.toggleMethodBoundaryLines"; //$NON-NLS-1$ + + /** + * Action definition id of toggle breadcrumb action (value: + * "org.eclipse.jdt.ui.edit.text.java.toggleBreadcrumb"). + * * @since 3.4 */ public static final String TOGGLE_BREADCRUMB= "org.eclipse.jdt.ui.edit.text.java.toggleBreadcrumb"; //$NON-NLS-1$ #P org.eclipse.platform.doc.user Index: reference/ref-68.htm =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.platform.doc.user/reference/ref-68.htm,v retrieving revision 1.31 diff -u -r1.31 ref-68.htm --- reference/ref-68.htm 29 May 2009 10:25:13 -0000 1.31 +++ reference/ref-68.htm 23 Nov 2010 23:24:12 -0000 @@ -175,8 +175,8 @@ Show source of selected element only image Show source of selected element only -  -  +Toggle Method Boundary Lines +Toggle Method Boundary Lines