View | Details | Raw Unified | Return to bug 13672 | Differences between
and this patch

Collapse All | Expand All

(-)contexts_JDT.xml (+5 lines)
Lines 88-93 Link Here
88
    <context id="toggle_mark_occurrences_action_context">
88
    <context id="toggle_mark_occurrences_action_context">
89
        <description>Allows you to switch mark occurrences on and off.</description>
89
        <description>Allows you to switch mark occurrences on and off.</description>
90
    </context>
90
    </context>
91
    
92
    <context id="toggle_method_boundary_lines_action_context">
93
        <description>Allows you to toggle method boundary lines on and off.</description>
94
        <topic label="Java editor reference" href="reference/views/ref-java-editor.htm"/>
95
    </context>
91
96
92
    <context id="display_action_context">
97
    <context id="display_action_context">
93
        <description>This command evaluates the selected expression and shows the result in the Display view.</description>
98
        <description>This command evaluates the selected expression and shows the result in the Display view.</description>
(-)reference/preferences/java/ref-preferences-editor.htm (+18 lines)
Lines 127-132 Link Here
127
        </tr>
127
        </tr>
128
        <tr>
128
        <tr>
129
          <td valign="top">
129
          <td valign="top">
130
          Method boundary Lines
131
          </td>
132
          <td valign="top">
133
            <p>
134
              If enabled, the Java editor will show the Method boundary lines to indicate the beginning and end of a method.
135
            </p>
136
          </td>
137
          <td valign="top">
138
            <p>
139
              Off
140
            </p>
141
          </td>
142
        </tr>
143
        <tr>
144
          <td valign="top">
130
            Appearance color options
145
            Appearance color options
131
          </td>
146
          </td>
132
          <td valign="top">
147
          <td valign="top">
Lines 151-156 Link Here
151
              
166
              
152
              <dt>Source hover background</dt>
167
              <dt>Source hover background</dt>
153
              <dd>The background color for the source hover. The source hover shows the source code of the element under the mouse pointer.</dd>
168
              <dd>The background color for the source hover. The source hover shows the source code of the element under the mouse pointer.</dd>
169
              
170
              <dt>Method Boundary Lines</dt>
171
              <dd>The color of the method boundary lines</dd>
154
            </dl>
172
            </dl>
155
          </td>
173
          </td>
156
          <td valign="top">
174
          <td valign="top">
(-)reference/views/ref-java-editor.htm (+16 lines)
Lines 38-43 Link Here
38
      <tbody>
38
      <tbody>
39
        <tr>
39
        <tr>
40
        <td align="center" valign="top">
40
        <td align="center" valign="top">
41
            <p><img src="../../images/org.eclipse.jdt.ui/etool16/toggle_method_boundary.gif" alt="Toggle Method Boundary Lines"></p>
42
          </td>
43
          <td valign="top">
44
            <p>
45
              Toggle Method Boundary Lines
46
            </p>
47
          </td>
48
          <td valign="top">
49
            <p>
50
              This button shows the Method boundary lines in the Java Editor.
51
            </p>
52
          </td>
53
        </tr>
54
        
55
        <tr>
56
        <td align="center" valign="top">
41
            <p><img src="../../images/org.eclipse.jdt.ui/etool16/toggle_breadcrumb.gif" alt="Toggle Java Editor Breadcrumb"></p>
57
            <p><img src="../../images/org.eclipse.jdt.ui/etool16/toggle_breadcrumb.gif" alt="Toggle Java Editor Breadcrumb"></p>
42
          </td>
58
          </td>
43
          <td valign="top">
59
          <td valign="top">
(-)plugin.properties (+4 lines)
Lines 240-245 Link Here
240
toggleMarkOccurrences.tooltip= Toggle Mark Occurrences
240
toggleMarkOccurrences.tooltip= Toggle Mark Occurrences
241
toggleMarkOccurrences.description= Toggles mark occurrences in Java editors
241
toggleMarkOccurrences.description= Toggles mark occurrences in Java editors
242
242
243
toggleMethodBoundaryLines.label= Toggle Method Boundary Lines
244
toggleMethodBoundaryLines.tooltip= Toggle Method Boundary Lines
245
toggleMethodBoundaryLines.description= Toggles method boundary lines in Java editors
246
243
toggleBreadcrumb.label= Toggle Java Editor Breadcrumb
247
toggleBreadcrumb.label= Toggle Java Editor Breadcrumb
244
toggleBreadcrumb.tooltip= Toggle Java Editor Breadcrumb
248
toggleBreadcrumb.tooltip= Toggle Java Editor Breadcrumb
245
toggleBreadcrumb.description= Toggle the Java editor breadcrumb
249
toggleBreadcrumb.description= Toggle the Java editor breadcrumb
(-)plugin.xml (+19 lines)
Lines 1333-1338 Link Here
1333
               retarget="true"
1333
               retarget="true"
1334
               tooltip="%toggleBreadcrumb.tooltip">
1334
               tooltip="%toggleBreadcrumb.tooltip">
1335
         </action>
1335
         </action>
1336
         <action
1337
               allowLabelUpdate="true"
1338
               style="toggle"
1339
               toolbarPath="org.eclipse.ui.edit.text.actionSet.presentation/Presentation"
1340
               id="org.eclipse.jdt.ui.edit.text.java.toggleMethodBoundaryLines"
1341
               definitionId="org.eclipse.jdt.ui.edit.text.java.toggleMethodBoundaryLines"
1342
               disabledIcon="$nl$/icons/full/dtool16/toggle_method_boundary.gif"
1343
               icon="$nl$/icons/full/etool16/toggle_method_boundary.gif"
1344
               helpContextId="org.eclipse.jdt.ui.toggle_mark_occurrences_action_context"
1345
               label="%toggleMethodBoundaryLines.label"
1346
               retarget="true"
1347
               tooltip="%toggleMethodBoundaryLines.tooltip">
1348
         </action>
1336
      </actionSet>
1349
      </actionSet>
1337
   </extension>
1350
   </extension>
1338
1351
Lines 3557-3562 Link Here
3557
	        id="org.eclipse.jdt.ui.edit.text.java.toggleMarkOccurrences">
3570
	        id="org.eclipse.jdt.ui.edit.text.java.toggleMarkOccurrences">
3558
	  </command>
3571
	  </command>
3559
	  <command
3572
	  <command
3573
	        name="%toggleMethodBoundaryLines.label"
3574
	        description="%toggleMethodBoundaryLines.description"
3575
	        categoryId="org.eclipse.jdt.ui.category.source"
3576
	        id="org.eclipse.jdt.ui.edit.text.java.toggleMethodBoundaryLines">
3577
	  </command>
3578
	  <command
3560
	        name="%toggleBreadcrumb.label"
3579
	        name="%toggleBreadcrumb.label"
3561
	        description="%toggleBreadcrumb.description"
3580
	        description="%toggleBreadcrumb.description"
3562
	        categoryId="org.eclipse.jdt.ui.category.source"
3581
	        categoryId="org.eclipse.jdt.ui.category.source"
(-)ui/org/eclipse/jdt/internal/ui/IJavaHelpContextIds.java (+1 lines)
Lines 61-66 Link Here
61
61
62
	public static final String TOGGLE_PRESENTATION_ACTION= 								PREFIX + "toggle_presentation_action_context"; //$NON-NLS-1$
62
	public static final String TOGGLE_PRESENTATION_ACTION= 								PREFIX + "toggle_presentation_action_context"; //$NON-NLS-1$
63
	public static final String TOGGLE_MARK_OCCURRENCES_ACTION= 								PREFIX + "toggle_mark_occurrences_action_context"; //$NON-NLS-1$
63
	public static final String TOGGLE_MARK_OCCURRENCES_ACTION= 								PREFIX + "toggle_mark_occurrences_action_context"; //$NON-NLS-1$
64
	public static final String TOGGLE_METHOD_BOUNDARY_LINES_ACTION= PREFIX + "toggle_method_boundary_lines_action_context"; //$NON-NLS-1$
64
	public static final String TOGGLE_BREADCRUMB_ACTION= PREFIX + "toggle_breadcrumb_action_context"; //$NON-NLS-1$
65
	public static final String TOGGLE_BREADCRUMB_ACTION= PREFIX + "toggle_breadcrumb_action_context"; //$NON-NLS-1$
65
	public static final String TOGGLE_TEXTHOVER_ACTION= 									PREFIX + "toggle_texthover_action_context"; //$NON-NLS-1$
66
	public static final String TOGGLE_TEXTHOVER_ACTION= 									PREFIX + "toggle_texthover_action_context"; //$NON-NLS-1$
66
67
(-)ui/org/eclipse/jdt/internal/ui/IJavaThemeConstants.java (-1 / +6 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2007, 2008 IBM Corporation and others.
2
 * Copyright (c) 2007, 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 29-34 Link Here
29
	public final String EDITOR_MATCHING_BRACKETS_COLOR= ID_PREFIX + PreferenceConstants.EDITOR_MATCHING_BRACKETS_COLOR;
29
	public final String EDITOR_MATCHING_BRACKETS_COLOR= ID_PREFIX + PreferenceConstants.EDITOR_MATCHING_BRACKETS_COLOR;
30
30
31
	/**
31
	/**
32
	 * Theme constant for the color used to render method boundary lines.
33
	 */
34
	public final String METHOD_BOUNDARY_LINES_COLOR= ID_PREFIX + PreferenceConstants.METHOD_BOUNDARY_LINES_COLOR;
35
36
	/**
32
	 * Theme constant for the color used to render multi-line comments.
37
	 * Theme constant for the color used to render multi-line comments.
33
	 */
38
	 */
34
	public final String EDITOR_MULTI_LINE_COMMENT_COLOR= ID_PREFIX + PreferenceConstants.EDITOR_MULTI_LINE_COMMENT_COLOR;
39
	public final String EDITOR_MULTI_LINE_COMMENT_COLOR= ID_PREFIX + PreferenceConstants.EDITOR_MULTI_LINE_COMMENT_COLOR;
(-)ui/org/eclipse/jdt/internal/ui/JavaUIPreferenceInitializer.java (-1 / +5 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2008 IBM Corporation and others.
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 125-130 Link Here
125
				findRGB(registry, IJavaThemeConstants.CODEASSIST_REPLACEMENT_BACKGROUND, new RGB(255, 255, 0)), fireEvent);
125
				findRGB(registry, IJavaThemeConstants.CODEASSIST_REPLACEMENT_BACKGROUND, new RGB(255, 255, 0)), fireEvent);
126
		setDefault(
126
		setDefault(
127
				store,
127
				store,
128
				PreferenceConstants.METHOD_BOUNDARY_LINES_COLOR,
129
				findRGB(registry, IJavaThemeConstants.METHOD_BOUNDARY_LINES_COLOR, new RGB(192, 192, 192)), fireEvent);
130
		setDefault(
131
				store,
128
				PreferenceConstants.CODEASSIST_REPLACEMENT_FOREGROUND,
132
				PreferenceConstants.CODEASSIST_REPLACEMENT_FOREGROUND,
129
				findRGB(registry, IJavaThemeConstants.CODEASSIST_REPLACEMENT_FOREGROUND, new RGB(255, 0, 0)), fireEvent);
133
				findRGB(registry, IJavaThemeConstants.CODEASSIST_REPLACEMENT_FOREGROUND, new RGB(255, 0, 0)), fireEvent);
130
134
(-)ui/org/eclipse/jdt/internal/ui/javaeditor/BasicJavaEditorActionContributor.java (+5 lines)
Lines 51-56 Link Here
51
	private ToggleMarkOccurrencesAction fToggleMarkOccurrencesAction;
51
	private ToggleMarkOccurrencesAction fToggleMarkOccurrencesAction;
52
	private ToggleBreadcrumbAction fToggleBreadcrumbAction;
52
	private ToggleBreadcrumbAction fToggleBreadcrumbAction;
53
53
54
	private ToggleMethodBoundaryLinesAction fToggleMethodBoundaryLinesAction;
55
54
	private RetargetTextEditorAction fGotoMatchingBracket;
56
	private RetargetTextEditorAction fGotoMatchingBracket;
55
	private RetargetTextEditorAction fShowOutline;
57
	private RetargetTextEditorAction fShowOutline;
56
	private RetargetTextEditorAction fOpenStructure;
58
	private RetargetTextEditorAction fOpenStructure;
Lines 80-85 Link Here
80
		fTogglePresentation= new TogglePresentationAction();
82
		fTogglePresentation= new TogglePresentationAction();
81
83
82
		fToggleMarkOccurrencesAction= new ToggleMarkOccurrencesAction();
84
		fToggleMarkOccurrencesAction= new ToggleMarkOccurrencesAction();
85
		fToggleMethodBoundaryLinesAction= new ToggleMethodBoundaryLinesAction();
83
86
84
		fGotoMatchingBracket= new RetargetTextEditorAction(b, "GotoMatchingBracket."); //$NON-NLS-1$
87
		fGotoMatchingBracket= new RetargetTextEditorAction(b, "GotoMatchingBracket."); //$NON-NLS-1$
85
		fGotoMatchingBracket.setActionDefinitionId(IJavaEditorActionDefinitionIds.GOTO_MATCHING_BRACKET);
88
		fGotoMatchingBracket.setActionDefinitionId(IJavaEditorActionDefinitionIds.GOTO_MATCHING_BRACKET);
Lines 129-134 Link Here
129
		bars.setGlobalActionHandler(ITextEditorActionDefinitionIds.TOGGLE_SHOW_SELECTED_ELEMENT_ONLY, fTogglePresentation);
132
		bars.setGlobalActionHandler(ITextEditorActionDefinitionIds.TOGGLE_SHOW_SELECTED_ELEMENT_ONLY, fTogglePresentation);
130
		bars.setGlobalActionHandler(IJavaEditorActionDefinitionIds.TOGGLE_MARK_OCCURRENCES, fToggleMarkOccurrencesAction);
133
		bars.setGlobalActionHandler(IJavaEditorActionDefinitionIds.TOGGLE_MARK_OCCURRENCES, fToggleMarkOccurrencesAction);
131
		bars.setGlobalActionHandler(IJavaEditorActionDefinitionIds.TOGGLE_BREADCRUMB, fToggleBreadcrumbAction);
134
		bars.setGlobalActionHandler(IJavaEditorActionDefinitionIds.TOGGLE_BREADCRUMB, fToggleBreadcrumbAction);
135
		bars.setGlobalActionHandler(IJavaEditorActionDefinitionIds.TOGGLE_METHOD_BOUNDARY_LINES, fToggleMethodBoundaryLinesAction);
132
	}
136
	}
133
137
134
	/*
138
	/*
Lines 179-184 Link Here
179
183
180
		fTogglePresentation.setEditor(textEditor);
184
		fTogglePresentation.setEditor(textEditor);
181
		fToggleMarkOccurrencesAction.setEditor(textEditor);
185
		fToggleMarkOccurrencesAction.setEditor(textEditor);
186
		fToggleMethodBoundaryLinesAction.setEditor(textEditor);
182
187
183
		fGotoMatchingBracket.setAction(getAction(textEditor, GotoMatchingBracketAction.GOTO_MATCHING_BRACKET));
188
		fGotoMatchingBracket.setAction(getAction(textEditor, GotoMatchingBracketAction.GOTO_MATCHING_BRACKET));
184
		fShowOutline.setAction(getAction(textEditor, IJavaEditorActionDefinitionIds.SHOW_OUTLINE));
189
		fShowOutline.setAction(getAction(textEditor, IJavaEditorActionDefinitionIds.SHOW_OUTLINE));
(-)ui/org/eclipse/jdt/internal/ui/javaeditor/ConstructedJavaEditorMessages.properties (+3 lines)
Lines 46-51 Link Here
46
TogglePresentation.label=Show Source of Selected Element Only
46
TogglePresentation.label=Show Source of Selected Element Only
47
TogglePresentation.tooltip=Show Source of Selected Element Only
47
TogglePresentation.tooltip=Show Source of Selected Element Only
48
48
49
ToggleMethodBoundaryLinesAction.label=Toggle Method Boundary Lines
50
ToggleMethodBoundaryLinesAction.tooltip=Toggle Method Boundary Lines
51
49
ToggleMarkOccurrencesAction.label= Toggle Mark Occurrences
52
ToggleMarkOccurrencesAction.label= Toggle Mark Occurrences
50
ToggleMarkOccurrencesAction.tooltip= Toggle Mark Occurrences
53
ToggleMarkOccurrencesAction.tooltip= Toggle Mark Occurrences
51
54
(-)ui/org/eclipse/jdt/internal/ui/javaeditor/JavaEditor.java (-1 / +50 lines)
Lines 30-35 Link Here
30
import org.eclipse.swt.SWT;
30
import org.eclipse.swt.SWT;
31
import org.eclipse.swt.custom.ST;
31
import org.eclipse.swt.custom.ST;
32
import org.eclipse.swt.custom.StyledText;
32
import org.eclipse.swt.custom.StyledText;
33
import org.eclipse.swt.graphics.Color;
33
import org.eclipse.swt.graphics.Image;
34
import org.eclipse.swt.graphics.Image;
34
import org.eclipse.swt.graphics.Point;
35
import org.eclipse.swt.graphics.Point;
35
import org.eclipse.swt.layout.FillLayout;
36
import org.eclipse.swt.layout.FillLayout;
Lines 63-68 Link Here
63
import org.eclipse.jface.action.IMenuManager;
64
import org.eclipse.jface.action.IMenuManager;
64
import org.eclipse.jface.action.MenuManager;
65
import org.eclipse.jface.action.MenuManager;
65
import org.eclipse.jface.preference.IPreferenceStore;
66
import org.eclipse.jface.preference.IPreferenceStore;
67
import org.eclipse.jface.preference.PreferenceConverter;
66
import org.eclipse.jface.util.IPropertyChangeListener;
68
import org.eclipse.jface.util.IPropertyChangeListener;
67
import org.eclipse.jface.util.PropertyChangeEvent;
69
import org.eclipse.jface.util.PropertyChangeEvent;
68
import org.eclipse.jface.viewers.DoubleClickEvent;
70
import org.eclipse.jface.viewers.DoubleClickEvent;
Lines 1507-1513 Link Here
1507
	}
1509
	}
1508
1510
1509
1511
1510
1511
	/** Preference key for matching brackets */
1512
	/** Preference key for matching brackets */
1512
	protected final static String MATCHING_BRACKETS=  PreferenceConstants.EDITOR_MATCHING_BRACKETS;
1513
	protected final static String MATCHING_BRACKETS=  PreferenceConstants.EDITOR_MATCHING_BRACKETS;
1513
	/** Preference key for matching brackets color */
1514
	/** Preference key for matching brackets color */
Lines 1743-1748 Link Here
1743
	private long fErrorMessageTime;
1744
	private long fErrorMessageTime;
1744
1745
1745
	/**
1746
	/**
1747
	 * The method boundary lines capability provider.
1748
	 * 
1749
	 * @since 3.7
1750
	 */
1751
	private MethodBoundaryLinesProvider fMethodBoundaryLinesProvider;
1752
1753
	/**
1746
	 * Timeout for the error message.
1754
	 * Timeout for the error message.
1747
	 * 
1755
	 * 
1748
	 * @since 3.5
1756
	 * @since 3.5
Lines 2586-2591 Link Here
2586
			fProjectionSupport= null;
2594
			fProjectionSupport= null;
2587
		}
2595
		}
2588
2596
2597
		if (fMethodBoundaryLinesProvider != null) {
2598
			fMethodBoundaryLinesProvider.dispose();
2599
			fMethodBoundaryLinesProvider= null;
2600
		}
2601
2589
		// cancel possible running computation
2602
		// cancel possible running computation
2590
		fMarkOccurrenceAnnotations= false;
2603
		fMarkOccurrenceAnnotations= false;
2591
		uninstallOccurrencesFinder();
2604
		uninstallOccurrencesFinder();
Lines 2944-2949 Link Here
2944
				return;
2957
				return;
2945
			}
2958
			}
2946
2959
2960
			if (PreferenceConstants.METHOD_BOUNDARY_LINES_COLOR.equals(property)) {
2961
				if (fMethodBoundaryLinesProvider != null) {
2962
					Color methodBoundaryColor= getSharedColors().getColor(PreferenceConverter.getColor(getPreferenceStore(), PreferenceConstants.METHOD_BOUNDARY_LINES_COLOR));
2963
					fMethodBoundaryLinesProvider.setColor(methodBoundaryColor);
2964
				}
2965
			}
2966
2967
			if (PreferenceConstants.SHOW_METHOD_BOUNDARY_LINES.equals(property)) {
2968
				if (!JavaPlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.SHOW_METHOD_BOUNDARY_LINES)) {
2969
					if (fMethodBoundaryLinesProvider != null) {
2970
						fMethodBoundaryLinesProvider.deactivate();
2971
					}
2972
				} else {
2973
					if (fMethodBoundaryLinesProvider != null) {
2974
						fMethodBoundaryLinesProvider.activate();
2975
					}
2976
				}
2977
			}
2978
2947
		} finally {
2979
		} finally {
2948
			super.handlePreferenceStoreChanged(event);
2980
			super.handlePreferenceStoreChanged(event);
2949
		}
2981
		}
Lines 3063-3068 Link Here
3063
		if (fIsBreadcrumbVisible)
3095
		if (fIsBreadcrumbVisible)
3064
			showBreadcrumb();
3096
			showBreadcrumb();
3065
3097
3098
		Color methodBoundaryColor= getSharedColors().getColor(PreferenceConverter.getColor(getPreferenceStore(), PreferenceConstants.METHOD_BOUNDARY_LINES_COLOR));
3099
		fMethodBoundaryLinesProvider= new MethodBoundaryLinesProvider(this, (JavaSourceViewer)getViewer(), getAnnotationAccess(), methodBoundaryColor);
3100
		if (JavaPlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.SHOW_METHOD_BOUNDARY_LINES)) {
3101
			fMethodBoundaryLinesProvider.activate();
3102
		}
3103
3066
		PlatformUI.getWorkbench().addWindowListener(fActivationListener);
3104
		PlatformUI.getWorkbench().addWindowListener(fActivationListener);
3067
	}
3105
	}
3068
3106
Lines 3352-3357 Link Here
3352
	}
3390
	}
3353
3391
3354
	/**
3392
	/**
3393
	 * Checks if the method boundary lines is enabled.
3394
	 * 
3395
	 * @return <code>true</code> if the method boundary lines preference is checked
3396
	 * @since 3.7
3397
	 */
3398
	protected boolean isShowingMethodBoundaryLines() {
3399
		IPreferenceStore store= getPreferenceStore();
3400
		return store != null && store.getBoolean(PreferenceConstants.SHOW_METHOD_BOUNDARY_LINES);
3401
	}
3402
3403
	/**
3355
	 * @return true if editor breadcrumbs are enabled
3404
	 * @return true if editor breadcrumbs are enabled
3356
	 * @since 3.4
3405
	 * @since 3.4
3357
	 */
3406
	 */
(-)ui/org/eclipse/jdt/internal/ui/javaeditor/MethodBoundaryLinesProvider.java (+708 lines)
Added Link Here
1
package org.eclipse.jdt.internal.ui.javaeditor;
2
3
import java.util.Iterator;
4
5
import org.eclipse.swt.custom.StyledText;
6
import org.eclipse.swt.graphics.Color;
7
import org.eclipse.swt.graphics.GC;
8
9
import org.eclipse.jface.text.BadLocationException;
10
import org.eclipse.jface.text.IDocument;
11
import org.eclipse.jface.text.IPainter;
12
import org.eclipse.jface.text.IRegion;
13
import org.eclipse.jface.text.Position;
14
import org.eclipse.jface.text.source.Annotation;
15
import org.eclipse.jface.text.source.AnnotationModel;
16
import org.eclipse.jface.text.source.AnnotationPainter;
17
import org.eclipse.jface.text.source.IAnnotationAccess;
18
import org.eclipse.jface.text.source.IAnnotationModel;
19
import org.eclipse.jface.text.source.IAnnotationModelExtension;
20
import org.eclipse.jface.text.source.ISourceViewer;
21
import org.eclipse.jface.text.source.ISourceViewerExtension2;
22
23
import org.eclipse.ui.texteditor.IDocumentProvider;
24
25
import org.eclipse.jdt.core.ElementChangedEvent;
26
import org.eclipse.jdt.core.IElementChangedListener;
27
import org.eclipse.jdt.core.IJavaElement;
28
import org.eclipse.jdt.core.IJavaElementDelta;
29
import org.eclipse.jdt.core.IParent;
30
import org.eclipse.jdt.core.ISourceRange;
31
import org.eclipse.jdt.core.ISourceReference;
32
import org.eclipse.jdt.core.IType;
33
import org.eclipse.jdt.core.ITypeRoot;
34
import org.eclipse.jdt.core.JavaCore;
35
import org.eclipse.jdt.core.JavaModelException;
36
37
import org.eclipse.jdt.internal.ui.JavaPlugin;
38
39
/**
40
 * Draws lines that visually demarcate the boundary for methods and types.
41
 * 
42
 * @since 3.7
43
 */
44
class MethodBoundaryLinesProvider {
45
46
	/**
47
	 * Updates the annotation model to reflect the incoming element changes.
48
	 */
49
	private class ElementChangedListener implements IElementChangedListener {
50
51
		/*
52
		 * @see org.eclipse.jdt.core.IElementChangedListener#elementChanged(org.eclipse.jdt.core.ElementChangedEvent)
53
		 */
54
		public void elementChanged(ElementChangedEvent event) {
55
			IJavaElementDelta delta= findElement(fInput, event.getDelta());
56
			if (delta != null && (delta.getFlags() & (IJavaElementDelta.F_CHILDREN | IJavaElementDelta.F_CONTENT)) != 0) {
57
				//System.out.println("Element Changed: " + delta);
58
				if ((delta.getFlags() & IJavaElementDelta.F_CHILDREN) != 0)
59
					updateAnnotationModel(delta.getAffectedChildren());
60
				else
61
					updateAnnotationPositions();
62
			}
63
		}
64
65
		/**
66
		 * Find the element in the java element delta that matches the target element.
67
		 * 
68
		 * @param target the target java element to be searched for in the delta
69
		 * @param delta the java element delta that is to be searched for the target element
70
		 * @return the delta that contains the java element matching the target element
71
		 */
72
		private IJavaElementDelta findElement(IJavaElement target, IJavaElementDelta delta) {
73
74
			if (delta == null || target == null)
75
				return null;
76
77
			IJavaElement element= delta.getElement();
78
79
			if (element.getElementType() > IJavaElement.CLASS_FILE)
80
				return null;
81
82
			if (target.equals(element))
83
				return delta;
84
85
			IJavaElementDelta[] children= delta.getAffectedChildren();
86
87
			for (int i= 0; i < children.length; i++) {
88
				IJavaElementDelta d= findElement(target, children[i]);
89
				if (d != null)
90
					return d;
91
			}
92
93
			return null;
94
		}
95
	}
96
97
	/**
98
	 * The annotation model that holds the annotations for method boundary lines.
99
	 */
100
	private class MethodBoundaryAnnotationModel extends AnnotationModel {
101
		private MethodBoundaryAnnotationModel() {
102
		}
103
104
		/**
105
		 * Sets the position for the annotation associated with a given element to the new position.
106
		 * If position is null then the annotation, if found, is removed from the model.
107
		 * 
108
		 * @param element the element whose corresponding annotation position is to be modified
109
		 * @param newPosition The new position for the concerned annotation
110
		 */
111
		public void modifyAnnotationForElement(IJavaElement element, Position newPosition) {
112
			MethodBoundaryAnnotation methodBoundaryAnnotation= getAnnotationForElement(element);
113
			if (methodBoundaryAnnotation != null)
114
				modifyAnnotationPosition(methodBoundaryAnnotation, newPosition);
115
		}
116
117
		/**
118
		 * Searches and returns the annotation associated with given element.
119
		 * 
120
		 * @param element the element whose associated annotation we are looking for
121
		 * @return returns the associated annotation if found, else returns null
122
		 */
123
		public MethodBoundaryAnnotation getAnnotationForElement(IJavaElement element) {
124
			Iterator iterator= getAnnotationIterator();
125
			while (iterator.hasNext()) {
126
				MethodBoundaryAnnotation methodBoundaryAnnotation= (MethodBoundaryAnnotation)iterator.next();
127
				if (element.equals(methodBoundaryAnnotation.getElement())) {
128
					return methodBoundaryAnnotation;
129
				}
130
			}
131
			return null;
132
		}
133
	}
134
135
	/**
136
	 * The drawing strategy for method boundary lines draws the lines that visual separate methods
137
	 * and types.
138
	 */
139
	private static class MethodBoundaryDrawingStrategy implements AnnotationPainter.IDrawingStrategy {
140
141
		/*
142
		 * @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)
143
		 */
144
		public void draw(Annotation annotation, GC gc, StyledText textWidget, int offset, int length, Color color) {
145
			if (annotation instanceof MethodBoundaryAnnotation) {
146
				MethodBoundaryAnnotation methodBoundaryAnnotation= (MethodBoundaryAnnotation)annotation;
147
				if (gc != null) {
148
					int lineIndex= textWidget.getLineAtOffset(offset);
149
					int lineY= textWidget.getLinePixel(lineIndex);
150
					IJavaElement element= methodBoundaryAnnotation.getElement();
151
					if (element.getElementType() == IJavaElement.TYPE) {
152
						//System.out.println(methodBoundaryAnnotation.getElement().getElementName() + ":  Off-" + offset + "  Len-" + length + "  Width-" + 2);
153
						gc.setLineWidth(2);
154
						lineY++;
155
					} else if (element.getElementType() == IJavaElement.METHOD) {
156
						//System.out.println(methodBoundaryAnnotation.getElement().getElementName() + ":  Off-" + offset + "  Len-" + length + "  Width-" + 0);
157
						gc.setLineWidth(0);
158
					} else {
159
						//System.out.println(methodBoundaryAnnotation.getElement().getElementName() + ":  Off-" + offset + "  Len-" + length + "  Width- ?");
160
						if (methodBoundaryAnnotation.getPreviousElementType() == IJavaElement.TYPE) {
161
							gc.setLineWidth(2);
162
							lineY++;
163
						} else {
164
							gc.setLineWidth(0);
165
						}
166
					}
167
					Color defaultColor= gc.getForeground();
168
					gc.setForeground(color);
169
					gc.drawLine(2, lineY, textWidget.getClientArea().width, lineY);
170
					gc.setForeground(defaultColor);
171
				} else {
172
					//System.out.println("Clearing: " + methodBoundaryAnnotation.getElement().getElementName() + ":  " + offset + "  " + length);
173
					textWidget.redraw(2, textWidget.getLinePixel(textWidget.getLineAtOffset(offset)), textWidget.getClientArea().width, 2, true);
174
				}
175
			}
176
		}
177
	}
178
179
	/**
180
	 * Annotation for method boundary lines.
181
	 */
182
	private class MethodBoundaryAnnotation extends Annotation {
183
184
		/**
185
		 * The type for method boundary annotation.
186
		 */
187
		public static final String TYPE= "org.eclipse.separator"; //$NON-NLS-1$
188
		/**
189
		 * The java element associated with this annotation.
190
		 */
191
		private IJavaElement fElementToBeAnnotated;
192
193
		/**
194
		 * The type of the element thats is previous to the element associated with this annotation.
195
		 */
196
		private int fPreviousElementType;
197
198
		/**
199
		 * Creates a new method boundary annotation.
200
		 * 
201
		 * @param element the java element that this annotation is associated with
202
		 * @param previousElementType the previous element type
203
		 */
204
		public MethodBoundaryAnnotation(IJavaElement element, int previousElementType) {
205
			super(TYPE, false, null);
206
			fElementToBeAnnotated= element;
207
			fPreviousElementType= previousElementType;
208
		}
209
210
		/**
211
		 * Getter for the java element associated with this annotation.
212
		 * 
213
		 * @return returns the java element associated with this annotation
214
		 */
215
		public IJavaElement getElement() {
216
			return fElementToBeAnnotated;
217
		}
218
219
		/**
220
		 * Getter for previous element type.
221
		 * 
222
		 * @return returns the previous element type
223
		 */
224
		public int getPreviousElementType() {
225
			return fPreviousElementType;
226
		}
227
228
		/**
229
		 * Sets the previous element type.
230
		 * 
231
		 * @param previousElementType the previous element type
232
		 */
233
		public void setPreviousElementType(int previousElementType) {
234
			fPreviousElementType= previousElementType;
235
		}
236
	}
237
238
	/**
239
	 * Paints the method boundary lines.
240
	 */
241
	private class MethodBoundaryAnnotationsPainter extends AnnotationPainter {
242
243
		/**
244
		 * Constructs a new <code>MethodSeparatorPainter</code>.
245
		 * 
246
		 * @param sourceViewer the source viewer for the painter
247
		 * @param access the annotation access
248
		 */
249
		public MethodBoundaryAnnotationsPainter(ISourceViewer sourceViewer, IAnnotationAccess access) {
250
			super(sourceViewer, access);
251
		}
252
253
		/**
254
		 * Retrieves the annotation model from the given source viewer.
255
		 * 
256
		 * @param sourceViewer the source viewer
257
		 * @return the source viewer's annotation model or <code>null</code> if none can be found
258
		 */
259
		protected IAnnotationModel findAnnotationModel(ISourceViewer sourceViewer) {
260
			if (sourceViewer != null && sourceViewer instanceof ISourceViewerExtension2)
261
				return ((IAnnotationModelExtension)(((ISourceViewerExtension2)sourceViewer).getVisualAnnotationModel())).getAnnotationModel(METHOD_BOUNDARY);
262
			return null;
263
		}
264
	}
265
266
	/**
267
	 * Key of the method boundary annotation model inside the visual annotation model. Also
268
	 * internally used as key for the drawing strategy.
269
	 */
270
	public final static Object METHOD_BOUNDARY= new Object();
271
	/**
272
	 * The source viewer associated with the editor.
273
	 */
274
	private JavaSourceViewer fViewer;
275
	/**
276
	 * The method boundary painter that paints the boundary lines.
277
	 */
278
	private MethodBoundaryAnnotationsPainter fPainter;
279
	
280
	/**
281
	 * The annotation access.
282
	 */
283
	private IAnnotationAccess fAnnotationAccess;
284
	/**
285
	 * The drawing strategy that is used for drawing the method boundary lines.
286
	 */
287
	private static AnnotationPainter.IDrawingStrategy fDrawingStrategy;
288
	/**
289
	 * The method boundary annotation model that holds the annotations and is connected to the
290
	 * document.
291
	 */
292
	private MethodBoundaryAnnotationModel fMethodBoundaryAnnotationModel;
293
	/**
294
	 * The listener that listens for element changes from the java model.
295
	 */
296
	private IElementChangedListener fElementListener;
297
	/**
298
	 * The java input element associated with the java editor.
299
	 */
300
	private IJavaElement fInput;
301
	/**
302
	 * The java editor.
303
	 */
304
	private JavaEditor fEditor;
305
306
	/**
307
	 * The method boundary color.
308
	 */
309
	private Color fMethodBoundaryColor;
310
311
	/**
312
	 * Constructs the <code>MethodBoundaryLinesProvider</code>.
313
	 * 
314
	 * @param editor the java editor
315
	 * @param viewer the source viewer associated with the editor
316
	 * @param annotationAccess the annotation access
317
	 * @param methodBoundaryColor the color to be used for drawing the method boundary lines
318
	 */
319
	public MethodBoundaryLinesProvider(JavaEditor editor, JavaSourceViewer viewer, IAnnotationAccess annotationAccess, Color methodBoundaryColor) {
320
		fEditor= editor;
321
		fViewer= viewer;
322
		fAnnotationAccess= annotationAccess;
323
		fMethodBoundaryColor= methodBoundaryColor;
324
325
		fInput= EditorUtility.getEditorInputJavaElement(fEditor, false);
326
		fMethodBoundaryAnnotationModel= new MethodBoundaryAnnotationModel();
327
		try {
328
			initializeModel(((IParent)fInput).getChildren());
329
		} catch (JavaModelException e) {
330
			JavaPlugin.log(e);
331
		}
332
333
		((IAnnotationModelExtension)(fViewer.getVisualAnnotationModel())).addAnnotationModel(METHOD_BOUNDARY, fMethodBoundaryAnnotationModel);
334
		if (fElementListener == null) {
335
			//System.out.println("New Listener Registered: " + fEditor.getContentDescription());
336
			fElementListener= new ElementChangedListener();
337
			JavaCore.addElementChangedListener(fElementListener);
338
		}
339
	}
340
341
	/**
342
	 * Initializes the annotation model with annotations based on the array of java elements.
343
	 * 
344
	 * @param elements the java elements for which the annotation model is to be initialized
345
	 */
346
	private void initializeModel(IJavaElement[] elements) {
347
		for (int i= 0; i < elements.length; i++) {
348
			int elementType= elements[i].getElementType();
349
			try {
350
				if (isElementOfTypeWeCanAnnotate(elements[i], true)) {
351
					if (isElementMethodOrType(elementType)) {
352
						fMethodBoundaryAnnotationModel.addAnnotation(new MethodBoundaryAnnotation(elements[i], 0), getAlignedFirstLineElementPosition(elements[i]));
353
					} else if (i != 0 && isElementMethodOrType(elements[i - 1].getElementType())) {
354
						fMethodBoundaryAnnotationModel.addAnnotation(new MethodBoundaryAnnotation(elements[i], elements[i - 1].getElementType()), getAlignedFirstLineElementPosition(elements[i]));
355
					}
356
				}
357
				if (elements[i] instanceof IParent) {
358
					IJavaElement[] children= ((IParent)elements[i]).getChildren();
359
					if (children.length > 0)
360
						initializeModel(children);
361
				}
362
			} catch (JavaModelException e) {
363
				JavaPlugin.log(e);
364
			}
365
		}
366
	}
367
368
	/**
369
	 * Get the aligned position of the first line of the java element.
370
	 * 
371
	 * @param element the java element whose first line position is to be determined
372
	 * @return returns the position of the first line of the java element
373
	 */
374
	private Position getAlignedFirstLineElementPosition(IJavaElement element) {
375
		IDocument document= getDocument();
376
		try {
377
			ISourceRange sourceRange= ((ISourceReference)element).getSourceRange();
378
			IRegion elementFirstLineRegion= document.getLineInformationOfOffset(sourceRange.getOffset());
379
			return new Position(elementFirstLineRegion.getOffset(), elementFirstLineRegion.getLength());
380
		} catch (JavaModelException e) {
381
			JavaPlugin.log(e);
382
		} catch (BadLocationException e) {
383
			JavaPlugin.log(e);
384
		}
385
		return null;
386
	}
387
388
	/**
389
	 * Returns <code>true</code> if the element type is one of the types that we can annotate and it
390
	 * should not be of primary type if <code>checkForPrimaryType</code> is true. Types we can
391
	 * annotate are {@link IJavaElement#TYPE}, METHOD, FIELD & INITIALIZER.
392
	 * 
393
	 * @param element the element whose type is to be checked
394
	 * @param checkForPrimaryType if <code>true</code> checks if the element is of primary type
395
	 * @return <code>true</code> if element type matches any in our list
396
	 */
397
	private boolean isElementOfTypeWeCanAnnotate(IJavaElement element, boolean checkForPrimaryType) {
398
		int elementType= element.getElementType();
399
		if (element instanceof ISourceReference && (elementType == IJavaElement.TYPE
400
				|| elementType == IJavaElement.METHOD || elementType == IJavaElement.FIELD
401
				|| elementType == IJavaElement.INITIALIZER)) {
402
			if (elementType == IJavaElement.TYPE && checkForPrimaryType)
403
				return !isPrimaryType((IType)element);
404
			return true;
405
		}
406
		return false;
407
	}
408
409
	/**
410
	 * Returns <code>true</code> if <code>type</code> is not a top-level type, <code>false</code> if
411
	 * it is.
412
	 * 
413
	 * @param type the type to test
414
	 * @return <code>true</code> if <code>type</code> is an inner type
415
	 */
416
	private boolean isInnerType(IType type) {
417
		return type.getDeclaringType() != null;
418
	}
419
420
	/**
421
	 * Returns <code>true</code> if <code>element</code> is the primary type, <code>false</code> if
422
	 * it is not. This is based on {@link ITypeRoot#findPrimaryType()}.
423
	 * 
424
	 * @param element the <code>element</code> to be evaluated if it is the primary type
425
	 * @return <code>true</code> if it is the primary type
426
	 */
427
	private boolean isPrimaryType(IType element) {
428
		IType primaryType= ((ITypeRoot)fInput).findPrimaryType();
429
		if (primaryType != null && primaryType.equals(element))
430
			return true;
431
		return false;
432
	}
433
434
	/**
435
	 * Update the annotations in the method boundary annotation model with the
436
	 * {@link IJavaElementDelta} changes. Based on ({@link IJavaElementDelta#getKind()}, annotation
437
	 * corresponding to the element in the delta is added, removed or changed.
438
	 * 
439
	 * @param delta the java element deltas that contain the changes done to the Java model
440
	 */
441
	private void updateAnnotationModel(IJavaElementDelta[] delta) {
442
		for (int i= 0; i < delta.length; i++) {
443
			IJavaElement element= delta[i].getElement();
444
			if (isElementOfTypeWeCanAnnotate(element, false)) {
445
				int elementType= element.getElementType();
446
				int deltaKind= delta[i].getKind();
447
				if (deltaKind == IJavaElementDelta.REMOVED) {
448
					//System.out.println("Element 'Removed': " + element.getElementName());
449
					fMethodBoundaryAnnotationModel.modifyAnnotationForElement(element, null);
450
					updateAnnotationModelForDanglingElements(element.getParent());
451
452
				} else if (deltaKind == IJavaElementDelta.ADDED) {
453
					int previousElementType= getPreviousElementType(element);
454
					if (isElementMethodOrType(elementType) || previousElementType != 0) {
455
						addAnnotationForNewElementToModel(element, previousElementType);
456
						updateAnnotationModelForDanglingElements(element.getParent());
457
					}
458
				} else if (deltaKind == IJavaElementDelta.CHANGED) {
459
					//System.out.println("Element 'Changed': " + element.getElementName());
460
					fMethodBoundaryAnnotationModel.modifyAnnotationForElement(element, getAlignedFirstLineElementPosition(element));
461
				}
462
			}
463
			if (element instanceof IParent) {
464
				updateAnnotationModel(delta[i].getAffectedChildren());
465
			}
466
		}
467
	}
468
469
	private int getPreviousElementType(IJavaElement element) {
470
		try {
471
			IJavaElement parentElement= element.getParent();
472
			if (parentElement != null && parentElement.getElementType() == IJavaElement.TYPE && ((IType)parentElement).hasChildren()) {
473
				IJavaElement[] childrenElements= ((IType)parentElement).getChildren();
474
				for (int i= 0; i < childrenElements.length; i++) {
475
					if (childrenElements[i].equals(element)) {
476
						if (i == 0)
477
							return 0;
478
						int childElementType= childrenElements[i - 1].getElementType();
479
						if (childElementType == IJavaElement.METHOD)
480
							return IJavaElement.METHOD;
481
						else if (childElementType == IJavaElement.TYPE)
482
							return IJavaElement.TYPE;
483
						return 0;
484
					}
485
				}
486
			}
487
		} catch (JavaModelException e) {
488
			JavaPlugin.log(e);
489
		}
490
		return 0;
491
	}
492
493
	/**
494
	 * Return <code>true</code> if the given elementType is of type {@link IJavaElement#METHOD} or
495
	 * {@link IJavaElement#TYPE}.
496
	 * 
497
	 * @param elementType the element type to check against
498
	 * @return <code>true</code> if the given elementType is of type {@link IJavaElement#METHOD} or
499
	 *         {@link IJavaElement#TYPE}
500
	 */
501
	private boolean isElementMethodOrType(int elementType) {
502
		if (elementType == IJavaElement.METHOD || elementType == IJavaElement.TYPE)
503
			return true;
504
		return false;
505
	}
506
507
	/**
508
	 * For all the children of parentElement, it checks and updates if any does not have a required
509
	 * Method boundary.
510
	 * 
511
	 * @param parentElement the parent element whose children are checked for missing boundary lines
512
	 */
513
	private void updateAnnotationModelForDanglingElements(IJavaElement parentElement) {
514
		try {
515
			if (parentElement != null && parentElement.getElementType() == IJavaElement.TYPE && ((IType)parentElement).hasChildren()) {
516
				IJavaElement[] childrenElements= ((IType)parentElement).getChildren();
517
				for (int i= 0; i < childrenElements.length; i++) {
518
					if (!isElementMethodOrType(childrenElements[i].getElementType()) && isElementOfTypeWeCanAnnotate(childrenElements[i], true)) {
519
						if (i == 0) {
520
							fMethodBoundaryAnnotationModel.modifyAnnotationForElement(childrenElements[i], null);
521
						} else {
522
							int previousElementType= childrenElements[i - 1].getElementType();
523
							if (isElementMethodOrType(previousElementType)) {
524
								MethodBoundaryAnnotation methodBoundaryAnnotation= fMethodBoundaryAnnotationModel.getAnnotationForElement(childrenElements[i]);
525
								if (methodBoundaryAnnotation == null) {
526
									fMethodBoundaryAnnotationModel.addAnnotation(new MethodBoundaryAnnotation(childrenElements[i], previousElementType),
527
										getAlignedFirstLineElementPosition(childrenElements[i]));
528
								} else {
529
									methodBoundaryAnnotation.setPreviousElementType(previousElementType);
530
									Position position= fMethodBoundaryAnnotationModel.getPosition(methodBoundaryAnnotation);
531
									fMethodBoundaryAnnotationModel.modifyAnnotationPosition(methodBoundaryAnnotation, null);
532
									fMethodBoundaryAnnotationModel.addAnnotation(methodBoundaryAnnotation, position);
533
								}
534
							} else {
535
								fMethodBoundaryAnnotationModel.modifyAnnotationForElement(childrenElements[i], null);
536
							}
537
						}
538
					}
539
				}
540
			}
541
		} catch (JavaModelException e) {
542
			JavaPlugin.log(e);
543
		}
544
	}
545
546
	/**
547
	 * Returns <code>true</code> if the given element is immediately preceded by an element of type
548
	 * IJavaElement.METHOD or TYPE in the source code.
549
	 * 
550
	 * @param element the element
551
	 * @return <code>true</code> if the given element is preceded by an IMethod or IType element
552
	 */
553
	private boolean isElementAfterTypeOrMethod(IJavaElement element) {
554
		try {
555
			IJavaElement parentElement= element.getParent();
556
			if (parentElement != null && parentElement.getElementType() == IJavaElement.TYPE && ((IType)parentElement).hasChildren()) {
557
				IJavaElement[] childrenElements= ((IType)parentElement).getChildren();
558
				for (int i= 0; i < childrenElements.length; i++) {
559
					if (childrenElements[i].equals(element)) {
560
						if (i == 0)
561
							return false;
562
						int childElementType= childrenElements[i - 1].getElementType();
563
						if (childElementType == IJavaElement.METHOD || (childElementType == IJavaElement.TYPE && isInnerType((IType)childrenElements[i - 1]))) {
564
							return true;
565
						}
566
					}
567
				}
568
			}
569
		} catch (JavaModelException e) {
570
			JavaPlugin.log(e);
571
		}
572
		return false;
573
	}
574
575
	/**
576
	 * For a new element added to the Java, create and add an annotation to the method boundary
577
	 * annotation model.
578
	 * 
579
	 * @param element the new element for which annotation is to be added to the annotation model
580
	 * @param previousElementType the type of the previous element
581
	 */
582
	private void addAnnotationForNewElementToModel(IJavaElement element, int previousElementType) {
583
		//System.out.println("Element 'Added': " + element.getElementName());
584
		if (isElementOfTypeWeCanAnnotate(element, true))
585
			fMethodBoundaryAnnotationModel.addAnnotation(new MethodBoundaryAnnotation(element, previousElementType), getAlignedFirstLineElementPosition(element));
586
		if (element instanceof IParent) {
587
			try {
588
				IJavaElement[] children= ((IParent)element).getChildren();
589
				for (int i= 0; i < children.length; i++) {
590
					int elementType= children[i].getElementType();
591
					if (isElementMethodOrType(elementType) || isElementAfterTypeOrMethod(children[i])) {
592
						if (i != 0)
593
							previousElementType= children[i - 1].getElementType();
594
						else
595
							previousElementType= 0;
596
						addAnnotationForNewElementToModel(children[i], previousElementType);
597
					}
598
				}
599
			} catch (JavaModelException e) {
600
				JavaPlugin.log(e);
601
			}
602
		}
603
	}
604
605
	/**
606
	 * Update the Positions in the annotation model for all the elements whose current source range
607
	 * in the document is different from the Position stored with the corresponding annotation.
608
	 */
609
	private void updateAnnotationPositions() {
610
		Iterator iterator= fMethodBoundaryAnnotationModel.getAnnotationIterator();
611
		while (iterator.hasNext()) {
612
			MethodBoundaryAnnotation methodBoundaryAnnotation= (MethodBoundaryAnnotation)iterator.next();
613
			Position existingPosition= fMethodBoundaryAnnotationModel.getPosition(methodBoundaryAnnotation);
614
			IJavaElement element= methodBoundaryAnnotation.getElement();
615
			if (element != null && ((ISourceReference)element).exists()) {
616
				Position newPosition= getAlignedFirstLineElementPosition(element);
617
				if (newPosition.getOffset() != existingPosition.getOffset() || newPosition.getLength() != existingPosition.getLength()) {
618
					fMethodBoundaryAnnotationModel.modifyAnnotationPosition(methodBoundaryAnnotation, null);
619
					fMethodBoundaryAnnotationModel.modifyAnnotationPosition(methodBoundaryAnnotation, newPosition);
620
				}
621
			}
622
		}
623
	}
624
625
	/**
626
	 * Gets the document associated with the Java editor.
627
	 * 
628
	 * @return returns the document
629
	 */
630
	private IDocument getDocument() {
631
		JavaEditor editor= fEditor;
632
		if (editor == null)
633
			return null;
634
635
		IDocumentProvider provider= editor.getDocumentProvider();
636
		if (provider == null)
637
			return null;
638
639
		return provider.getDocument(editor.getEditorInput());
640
	}
641
642
	/**
643
	 * Returns the drawing strategy to be used by the method boundary annotation painter.
644
	 * 
645
	 * @return the drawing strategy to be used by the method boundary annotation painter
646
	 */
647
	private AnnotationPainter.IDrawingStrategy getDrawingStrategy() {
648
		if (fDrawingStrategy == null)
649
			fDrawingStrategy= new MethodBoundaryDrawingStrategy();
650
		return fDrawingStrategy;
651
	}
652
653
	/**
654
	 * Disposes the method boundary lines provider and associated painter.
655
	 */
656
	public void dispose() {
657
		if (fPainter != null) {
658
			fViewer.removePainter(fPainter);
659
			fPainter.deactivate(true);
660
			fPainter.dispose();
661
			fPainter= null;
662
		}
663
		IAnnotationModelExtension visualModel= ((IAnnotationModelExtension)(fViewer.getVisualAnnotationModel()));
664
		if (visualModel != null)
665
			visualModel.removeAnnotationModel(METHOD_BOUNDARY);
666
		fMethodBoundaryAnnotationModel= null;
667
		JavaCore.removeElementChangedListener(fElementListener);
668
		fViewer= null;
669
		fEditor= null;
670
		fMethodBoundaryColor= null;
671
	}
672
673
	/**
674
	 * Sets the color for the method boundary lines.
675
	 * 
676
	 * @param methodBoundaryColor the color to be used for drawing the method boundary lines
677
	 */
678
	public void setColor(Color methodBoundaryColor) {
679
		fMethodBoundaryColor= methodBoundaryColor;
680
		fPainter.setAnnotationTypeColor(MethodBoundaryAnnotation.TYPE, fMethodBoundaryColor);
681
		fPainter.paint(IPainter.CONFIGURATION);
682
	}
683
684
	/**
685
	 * Deactivates the boundary line drawing.
686
	 */
687
	public void deactivate() {
688
		if (fPainter != null) {
689
			fViewer.removePainter(fPainter);
690
			//fPainter.deactivate(true);
691
			fPainter.dispose();
692
			fPainter= null;
693
		}
694
	}
695
696
	/**
697
	 * Activates the boundary line drawing.
698
	 */
699
	public void activate() {
700
		if (fPainter == null) {
701
			fPainter= new MethodBoundaryAnnotationsPainter(fViewer, fAnnotationAccess);
702
			fPainter.addDrawingStrategy(METHOD_BOUNDARY, getDrawingStrategy());
703
			fPainter.addAnnotationType(MethodBoundaryAnnotation.TYPE, METHOD_BOUNDARY);
704
			fPainter.setAnnotationTypeColor(MethodBoundaryAnnotation.TYPE, fMethodBoundaryColor);
705
			fViewer.addPainter(fPainter);
706
		}
707
	}
708
}
(-)ui/org/eclipse/jdt/internal/ui/javaeditor/ToggleMethodBoundaryLinesAction.java (+101 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jdt.internal.ui.javaeditor;
12
13
14
import org.eclipse.jface.action.IAction;
15
import org.eclipse.jface.preference.IPreferenceStore;
16
import org.eclipse.jface.util.IPropertyChangeListener;
17
import org.eclipse.jface.util.PropertyChangeEvent;
18
19
import org.eclipse.ui.PlatformUI;
20
21
import org.eclipse.ui.texteditor.ITextEditor;
22
import org.eclipse.ui.texteditor.TextEditorAction;
23
24
import org.eclipse.jdt.ui.PreferenceConstants;
25
26
import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
27
import org.eclipse.jdt.internal.ui.JavaPlugin;
28
import org.eclipse.jdt.internal.ui.JavaPluginImages;
29
30
31
/**
32
 * A toolbar action which toggles the
33
 * {@linkplain org.eclipse.jdt.ui.PreferenceConstants#SHOW_METHOD_BOUNDARY_LINES preference}.
34
 * 
35
 * @since 3.7
36
 */
37
public class ToggleMethodBoundaryLinesAction extends TextEditorAction implements IPropertyChangeListener {
38
39
	private IPreferenceStore fStore;
40
41
	/**
42
	 * Constructs and updates the action.
43
	 */
44
	public ToggleMethodBoundaryLinesAction() {
45
		super(JavaEditorMessages.getBundleForConstructedKeys(), "ToggleMethodBoundaryLinesAction.", null, IAction.AS_CHECK_BOX); //$NON-NLS-1$
46
		JavaPluginImages.setToolImageDescriptors(this, "toggle_method_boundary.gif"); //$NON-NLS-1$
47
		PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.TOGGLE_METHOD_BOUNDARY_LINES_ACTION);
48
		update();
49
	}
50
51
	/*
52
	 * @see IAction#actionPerformed
53
	 */
54
	public void run() {
55
		fStore.setValue(PreferenceConstants.SHOW_METHOD_BOUNDARY_LINES, isChecked());
56
	}
57
58
	/*
59
	 * @see TextEditorAction#update
60
	 */
61
	public void update() {
62
		ITextEditor editor= getTextEditor();
63
64
		boolean checked= false;
65
		if (editor instanceof JavaEditor)
66
			checked= ((JavaEditor)editor).isShowingMethodBoundaryLines();
67
68
		setChecked(checked);
69
		setEnabled(editor != null);
70
	}
71
72
	/*
73
	 * @see TextEditorAction#setEditor(ITextEditor)
74
	 */
75
	public void setEditor(ITextEditor editor) {
76
77
		super.setEditor(editor);
78
79
		if (editor != null) {
80
81
			if (fStore == null) {
82
				fStore= JavaPlugin.getDefault().getPreferenceStore();
83
				fStore.addPropertyChangeListener(this);
84
			}
85
86
		} else if (fStore != null) {
87
			fStore.removePropertyChangeListener(this);
88
			fStore= null;
89
		}
90
91
		update();
92
	}
93
94
	/*
95
	 * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
96
	 */
97
	public void propertyChange(PropertyChangeEvent event) {
98
		if (event.getProperty().equals(PreferenceConstants.SHOW_METHOD_BOUNDARY_LINES))
99
			setChecked(Boolean.valueOf(event.getNewValue().toString()).booleanValue());
100
	}
101
}
(-)ui/org/eclipse/jdt/internal/ui/preferences/JavaEditorAppearanceConfigurationBlock.java (+6 lines)
Lines 59-64 Link Here
59
			{PreferencesMessages.JavaEditorPreferencePage_backgroundForCompletionReplacement, PreferenceConstants.CODEASSIST_REPLACEMENT_BACKGROUND, null },
59
			{PreferencesMessages.JavaEditorPreferencePage_backgroundForCompletionReplacement, PreferenceConstants.CODEASSIST_REPLACEMENT_BACKGROUND, null },
60
			{PreferencesMessages.JavaEditorPreferencePage_foregroundForCompletionReplacement, PreferenceConstants.CODEASSIST_REPLACEMENT_FOREGROUND, null },
60
			{PreferencesMessages.JavaEditorPreferencePage_foregroundForCompletionReplacement, PreferenceConstants.CODEASSIST_REPLACEMENT_FOREGROUND, null },
61
			{PreferencesMessages.JavaEditorPreferencePage_sourceHoverBackgroundColor, PreferenceConstants.EDITOR_SOURCE_HOVER_BACKGROUND_COLOR, PreferenceConstants.EDITOR_SOURCE_HOVER_BACKGROUND_COLOR_SYSTEM_DEFAULT},
61
			{PreferencesMessages.JavaEditorPreferencePage_sourceHoverBackgroundColor, PreferenceConstants.EDITOR_SOURCE_HOVER_BACKGROUND_COLOR, PreferenceConstants.EDITOR_SOURCE_HOVER_BACKGROUND_COLOR_SYSTEM_DEFAULT},
62
			{ PreferencesMessages.JavaEditorPreferencePage_methodBoundaryLinesColor, PreferenceConstants.METHOD_BOUNDARY_LINES_COLOR, null },
62
63
63
		};
64
		};
64
65
Lines 84-89 Link Here
84
		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_SUB_WORD_NAVIGATION));
85
		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_SUB_WORD_NAVIGATION));
85
		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_EVALUTE_TEMPORARY_PROBLEMS));
86
		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_EVALUTE_TEMPORARY_PROBLEMS));
86
		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_SHOW_SEGMENTS));
87
		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_SHOW_SEGMENTS));
88
		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.SHOW_METHOD_BOUNDARY_LINES));
89
		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.METHOD_BOUNDARY_LINES_COLOR));
87
		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.CODEASSIST_PARAMETERS_BACKGROUND));
90
		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.CODEASSIST_PARAMETERS_BACKGROUND));
88
		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.CODEASSIST_PARAMETERS_FOREGROUND));
91
		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.CODEASSIST_PARAMETERS_FOREGROUND));
89
		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.CODEASSIST_REPLACEMENT_BACKGROUND));
92
		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.CODEASSIST_REPLACEMENT_BACKGROUND));
Lines 234-239 Link Here
234
		label= PreferencesMessages.JavaEditorPreferencePage_showJavaElementOnly;
237
		label= PreferencesMessages.JavaEditorPreferencePage_showJavaElementOnly;
235
		addCheckBox(appearanceComposite, label, PreferenceConstants.EDITOR_SHOW_SEGMENTS, 0);
238
		addCheckBox(appearanceComposite, label, PreferenceConstants.EDITOR_SHOW_SEGMENTS, 0);
236
239
240
		label= PreferencesMessages.JavaEditorPreferencePage_ShowMethodBoundaryLines;
241
		addCheckBox(appearanceComposite, label, PreferenceConstants.SHOW_METHOD_BOUNDARY_LINES, 0);
242
237
		Label l= new Label(appearanceComposite, SWT.LEFT );
243
		Label l= new Label(appearanceComposite, SWT.LEFT );
238
		gd= new GridData(GridData.HORIZONTAL_ALIGN_FILL);
244
		gd= new GridData(GridData.HORIZONTAL_ALIGN_FILL);
239
		gd.horizontalSpan= 2;
245
		gd.horizontalSpan= 2;
(-)ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.java (+4 lines)
Lines 151-156 Link Here
151
	public static String JavaEditorPreferencePage_enable;
151
	public static String JavaEditorPreferencePage_enable;
152
	public static String JavaEditorPreferencePage_preview;
152
	public static String JavaEditorPreferencePage_preview;
153
	public static String JavaEditorPreferencePage_highlightMatchingBrackets;
153
	public static String JavaEditorPreferencePage_highlightMatchingBrackets;
154
155
	public static String JavaEditorPreferencePage_ShowMethodBoundaryLines;
154
	public static String JavaEditorPreferencePage_insertSingleProposalsAutomatically;
156
	public static String JavaEditorPreferencePage_insertSingleProposalsAutomatically;
155
	public static String JavaEditorPreferencePage_showOnlyProposalsVisibleInTheInvocationContext;
157
	public static String JavaEditorPreferencePage_showOnlyProposalsVisibleInTheInvocationContext;
156
	public static String JavaEditorPreferencePage_presentProposalsInAlphabeticalOrder;
158
	public static String JavaEditorPreferencePage_presentProposalsInAlphabeticalOrder;
Lines 178-183 Link Here
178
	public static String JavaEditorPreferencePage_empty_input;
180
	public static String JavaEditorPreferencePage_empty_input;
179
	public static String JavaEditorPreferencePage_invalid_input;
181
	public static String JavaEditorPreferencePage_invalid_input;
180
	public static String JavaEditorPreferencePage_matchingBracketsHighlightColor2;
182
	public static String JavaEditorPreferencePage_matchingBracketsHighlightColor2;
183
184
	public static String JavaEditorPreferencePage_methodBoundaryLinesColor;
181
	public static String JavaEditorPreferencePage_appearanceOptions;
185
	public static String JavaEditorPreferencePage_appearanceOptions;
182
	public static String JavaEditorPreferencePage_typing_tabTitle;
186
	public static String JavaEditorPreferencePage_typing_tabTitle;
183
	public static String JavaEditorPreferencePage_closeStrings;
187
	public static String JavaEditorPreferencePage_closeStrings;
(-)ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.properties (+2 lines)
Lines 131-136 Link Here
131
JavaEditorPreferencePage_enable=Enab&le
131
JavaEditorPreferencePage_enable=Enab&le
132
JavaEditorPreferencePage_preview=Previe&w:
132
JavaEditorPreferencePage_preview=Previe&w:
133
JavaEditorPreferencePage_highlightMatchingBrackets=Highlight &matching brackets
133
JavaEditorPreferencePage_highlightMatchingBrackets=Highlight &matching brackets
134
JavaEditorPreferencePage_ShowMethodBoundaryLines=Separator line &between types and method
134
JavaEditorPreferencePage_insertSingleProposalsAutomatically=Insert single &proposals automatically
135
JavaEditorPreferencePage_insertSingleProposalsAutomatically=Insert single &proposals automatically
135
JavaEditorPreferencePage_showOnlyProposalsVisibleInTheInvocationContext=Hide proposals not visible in the in&vocation context
136
JavaEditorPreferencePage_showOnlyProposalsVisibleInTheInvocationContext=Hide proposals not visible in the in&vocation context
136
JavaEditorPreferencePage_presentProposalsInAlphabeticalOrder=&Sort proposals
137
JavaEditorPreferencePage_presentProposalsInAlphabeticalOrder=&Sort proposals
Lines 160-165 Link Here
160
JavaEditorPreferencePage_empty_input=Empty input
161
JavaEditorPreferencePage_empty_input=Empty input
161
JavaEditorPreferencePage_invalid_input=''{0}'' is not a valid input.
162
JavaEditorPreferencePage_invalid_input=''{0}'' is not a valid input.
162
JavaEditorPreferencePage_matchingBracketsHighlightColor2=Matching brackets highlight
163
JavaEditorPreferencePage_matchingBracketsHighlightColor2=Matching brackets highlight
164
JavaEditorPreferencePage_methodBoundaryLinesColor= Separator line between types and method
163
JavaEditorPreferencePage_appearanceOptions=Appearance co&lor options:
165
JavaEditorPreferencePage_appearanceOptions=Appearance co&lor options:
164
166
165
JavaEditorPreferencePage_typing_tabTitle=T&yping
167
JavaEditorPreferencePage_typing_tabTitle=T&yping
(-)ui/org/eclipse/jdt/ui/PreferenceConstants.java (-1 / +23 lines)
Lines 2275-2285 Link Here
2275
	public static final String EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK= "browserLikeLinksKeyModifierMask"; //$NON-NLS-1$
2275
	public static final String EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK= "browserLikeLinksKeyModifierMask"; //$NON-NLS-1$
2276
2276
2277
	/**
2277
	/**
2278
	 * A named preference that controls whether method boundary lines are shown in the editor.
2279
	 * <p>
2280
	 * Value is of type <code>Boolean</code>.
2281
	 * </p>
2282
	 * 
2283
	 * @since 3.7
2284
	 */
2285
	public static final String SHOW_METHOD_BOUNDARY_LINES= "showMethodBoundaryLines"; //$NON-NLS-1$
2286
2287
	/**
2288
	 * A named preference that holds the color used for method boundary lines.
2289
	 * <p>
2290
	 * Value is of type <code>String</code>. A RGB color value encoded as a string using class
2291
	 * <code>PreferenceConverter</code>
2292
	 * </p>
2293
	 * 
2294
	 * @since 3.7
2295
	 */
2296
	public static final String METHOD_BOUNDARY_LINES_COLOR= "methodBoundaryLinesColor"; //$NON-NLS-1$
2297
2298
	/**
2278
	 * A named preference that controls whether occurrences are marked in the editor.
2299
	 * A named preference that controls whether occurrences are marked in the editor.
2279
	 * <p>
2300
	 * <p>
2280
	 * Value is of type <code>Boolean</code>.
2301
	 * Value is of type <code>Boolean</code>.
2281
	 * </p>
2302
	 * </p>
2282
	 *
2303
	 * 
2283
	 * @since 3.0
2304
	 * @since 3.0
2284
	 */
2305
	 */
2285
	public static final String EDITOR_MARK_OCCURRENCES= "markOccurrences"; //$NON-NLS-1$
2306
	public static final String EDITOR_MARK_OCCURRENCES= "markOccurrences"; //$NON-NLS-1$
Lines 3707-3712 Link Here
3707
3728
3708
		// JavaEditorPreferencePage
3729
		// JavaEditorPreferencePage
3709
		store.setDefault(PreferenceConstants.EDITOR_MATCHING_BRACKETS, true);
3730
		store.setDefault(PreferenceConstants.EDITOR_MATCHING_BRACKETS, true);
3731
		store.setDefault(PreferenceConstants.SHOW_METHOD_BOUNDARY_LINES, false);
3710
3732
3711
		store.setDefault(PreferenceConstants.EDITOR_CORRECTION_INDICATION, true);
3733
		store.setDefault(PreferenceConstants.EDITOR_CORRECTION_INDICATION, true);
3712
		store.setDefault(PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE, true);
3734
		store.setDefault(PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE, true);
(-)ui/org/eclipse/jdt/ui/actions/IJavaEditorActionDefinitionIds.java (-2 / +11 lines)
Lines 718-725 Link Here
718
	public static final String TOGGLE_MARK_OCCURRENCES= "org.eclipse.jdt.ui.edit.text.java.toggleMarkOccurrences"; //$NON-NLS-1$
718
	public static final String TOGGLE_MARK_OCCURRENCES= "org.eclipse.jdt.ui.edit.text.java.toggleMarkOccurrences"; //$NON-NLS-1$
719
719
720
	/**
720
	/**
721
	 * Action definition id of toggle breadcrumb action
721
	 * Action definition id of toggle method boundary lines action (value:
722
	 * (value: <code>"org.eclipse.jdt.ui.edit.text.java.toggleBreadcrumb"</code>).
722
	 * <code>"org.eclipse.jdt.ui.edit.text.java.toggleMethodBoundaryLines"</code>).
723
	 * 
724
	 * @since 3.7
725
	 */
726
	public static final String TOGGLE_METHOD_BOUNDARY_LINES= "org.eclipse.jdt.ui.edit.text.java.toggleMethodBoundaryLines"; //$NON-NLS-1$
727
728
	/**
729
	 * Action definition id of toggle breadcrumb action (value:
730
	 * <code>"org.eclipse.jdt.ui.edit.text.java.toggleBreadcrumb"</code>).
731
	 * 
723
	 * @since 3.4
732
	 * @since 3.4
724
	 */
733
	 */
725
	public static final String TOGGLE_BREADCRUMB= "org.eclipse.jdt.ui.edit.text.java.toggleBreadcrumb"; //$NON-NLS-1$
734
	public static final String TOGGLE_BREADCRUMB= "org.eclipse.jdt.ui.edit.text.java.toggleBreadcrumb"; //$NON-NLS-1$
(-)reference/ref-68.htm (-2 / +2 lines)
Lines 175-182 Link Here
175
<tr>
175
<tr>
176
<td align="center" valign="middle"><img src="../images/segment_edit.png" alt="Show source of selected element only image"></td>
176
<td align="center" valign="middle"><img src="../images/segment_edit.png" alt="Show source of selected element only image"></td>
177
<td>Show source of selected element only</td>
177
<td>Show source of selected element only</td>
178
<td>&nbsp;</td>
178
<td align="center" valign="middle"><img src="../images/toggle_method_boundary.gif" alt="Toggle Method Boundary Lines"></td>
179
<td>&nbsp;</td>
179
<td>Toggle Method Boundary Lines</td>
180
</tr>
180
</tr>
181
</tbody>
181
</tbody>
182
</table>
182
</table>

Return to bug 13672