diff --git a/core/org.eclipse.cdt.ui/icons/obj16/implm_co.gif b/core/org.eclipse.cdt.ui/icons/obj16/implm_co.gif
new file mode 100644
index 00000000000..b9871227abd
Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/obj16/implm_co.gif differ
diff --git a/core/org.eclipse.cdt.ui/icons/obj16/over_co.gif b/core/org.eclipse.cdt.ui/icons/obj16/over_co.gif
new file mode 100644
index 00000000000..938767b200e
Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/obj16/over_co.gif differ
diff --git a/core/org.eclipse.cdt.ui/icons/obj16/shad_co.gif b/core/org.eclipse.cdt.ui/icons/obj16/shad_co.gif
new file mode 100644
index 00000000000..ecf8aa36d35
Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/obj16/shad_co.gif differ
diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml
index c816a884fe7..47996073534 100644
--- a/core/org.eclipse.cdt.ui/plugin.xml
+++ b/core/org.eclipse.cdt.ui/plugin.xml
@@ -2525,6 +2525,31 @@
textStylePreferenceKey="org.eclipse.cdt.ui.occurrenceTextStyle"
textStylePreferenceValue="NONE">
+
+
@@ -2676,6 +2701,7 @@
+
Name:
DefaultCEditorTextHover_html_prototype=
Prototype:
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ConstructedCEditorMessages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ConstructedCEditorMessages.properties
index 5da3bc90c3b..c14964f394e 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ConstructedCEditorMessages.properties
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ConstructedCEditorMessages.properties
@@ -11,6 +11,7 @@
# Anton Leherbauer (Wind River Systems)
# Markus Schorn (Wind River Systems)
# Sergey Prigogin (Google)
+# Tomasz Wesolowski
###############################################################################
AddIncludeOnSelection.description=Add include statement for selected name
@@ -131,3 +132,8 @@ CSelectAnnotationRulerAction.GotoAnnotation.label= &Go to Annotation
CSelectAnnotationRulerAction.GotoAnnotation.tooltip= Go to Annotation
CSelectAnnotationRulerAction.GotoAnnotation.description= Selects the annotation in the editor
CSelectAnnotationRulerAction.GotoAnnotation.image=
+
+CSelectAnnotationRulerAction.OpenSuperImplementation.label= &Open Super Implementation
+CSelectAnnotationRulerAction.OpenSuperImplementation.tooltip= Open Super Implementation
+CSelectAnnotationRulerAction.OpenSuperImplementation.description= Opens the super implementation
+CSelectAnnotationRulerAction.OpenSuperImplementation.image=
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/OverrideIndicatorImageProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/OverrideIndicatorImageProvider.java
new file mode 100644
index 00000000000..d0114ed09bc
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/OverrideIndicatorImageProvider.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tomasz Wesolowski 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:
+ * Tomasz Wesolowski - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.ui.editor;
+
+import org.eclipse.cdt.internal.ui.CPluginImages;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.texteditor.IAnnotationImageProvider;
+
+/**
+ * @author Tomasz Wesolowski
+ *
+ */
+public class OverrideIndicatorImageProvider implements
+ IAnnotationImageProvider {
+
+ private static final String OVERRIDE_IMG_DESC_ID = "CPluginImages.DESC_OBJS_OVERRIDES";
+ private static final String IMPLEMENT_IMG_DESC_ID = "CPluginImages.DESC_OBJS_IMPLEMENTS";
+ private static final String SHADOW_IMG_DESC_ID = "CPluginImages.DESC_OBJS_SHADOWS";
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.texteditor.IAnnotationImageProvider#getManagedImage(org.eclipse.jface.text.source.Annotation)
+ */
+ public Image getManagedImage(Annotation annotation) {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.texteditor.IAnnotationImageProvider#getImageDescriptorId(org.eclipse.jface.text.source.Annotation)
+ */
+ public String getImageDescriptorId(Annotation annotation) {
+ if (!isImageProviderFor(annotation)) {
+ return null;
+ }
+ switch (getAnnotationType(annotation)) {
+ case OverrideIndicatorManager.RESULT_OVERRIDES:
+ return OVERRIDE_IMG_DESC_ID;
+ case OverrideIndicatorManager.RESULT_IMPLEMENTS:
+ return IMPLEMENT_IMG_DESC_ID;
+ case OverrideIndicatorManager.RESULT_SHADOWS:
+ return SHADOW_IMG_DESC_ID;
+ }
+ assert false;
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.texteditor.IAnnotationImageProvider#getImageDescriptor(java.lang.String)
+ */
+ public ImageDescriptor getImageDescriptor(String imageDescritporId) {
+ if (imageDescritporId.equals(OVERRIDE_IMG_DESC_ID)) {
+ return CPluginImages.DESC_OBJS_OVERRIDES;
+ } else if (imageDescritporId.equals(IMPLEMENT_IMG_DESC_ID)) {
+ return CPluginImages.DESC_OBJS_IMPLEMENTS;
+ } else if (imageDescritporId.equals(SHADOW_IMG_DESC_ID)) {
+ return CPluginImages.DESC_OBJS_SHADOWS;
+ }
+ assert false;
+ return null;
+ }
+
+ private boolean isImageProviderFor(Annotation annotation) {
+ return annotation != null && OverrideIndicatorManager.OverrideIndicator.ANNOTATION_TYPE_ID.equals(annotation.getType());
+ }
+
+ private int getAnnotationType(Annotation annotation) {
+ return ((OverrideIndicatorManager.OverrideIndicator)annotation).getIndicationType();
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/OverrideIndicatorManager.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/OverrideIndicatorManager.java
new file mode 100644
index 00000000000..a9a74dd9edd
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/OverrideIndicatorManager.java
@@ -0,0 +1,426 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tomasz Wesolowski 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:
+ * Tomasz Wesolowski - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.ui.editor;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Vector;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.text.ISynchronizable;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+
+import org.eclipse.cdt.core.dom.ast.ASTVisitor;
+import org.eclipse.cdt.core.dom.ast.DOMException;
+import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
+import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
+import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
+import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
+import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
+import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
+import org.eclipse.cdt.core.dom.ast.IASTNode;
+import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
+import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
+import org.eclipse.cdt.core.dom.ast.IBinding;
+import org.eclipse.cdt.core.dom.ast.IType;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
+import org.eclipse.cdt.core.index.IIndex;
+import org.eclipse.cdt.ui.CDTUITools;
+
+import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
+import org.eclipse.cdt.internal.core.model.ASTStringUtil;
+import org.eclipse.cdt.internal.core.model.ext.ICElementHandle;
+
+import org.eclipse.cdt.internal.ui.text.ICReconcilingListener;
+import org.eclipse.cdt.internal.ui.viewsupport.IndexUI;
+
+public class OverrideIndicatorManager implements ICReconcilingListener {
+
+ private static final String MESSAGE_SEPARATOR = ";\n"; //$NON-NLS-1$
+
+ public static class OverrideInfo {
+
+ public int nodeOffset;
+ public int resultType;
+ public String message;
+ public int nodeLength;
+
+ public IBinding binding;
+
+ public OverrideInfo(int nodeOffset, int nodeLength, int markerType, String message, IBinding binding) {
+ this.nodeOffset = nodeOffset;
+ this.resultType = markerType;
+ this.message = message;
+ this.binding = binding;
+ }
+ }
+
+ public static final int RESULT_OVERRIDES = 0;
+ public static final int RESULT_IMPLEMENTS = 1;
+ public static final int RESULT_SHADOWS = 2;
+
+ public class OverrideIndicator extends Annotation {
+
+ public static final String ANNOTATION_TYPE_ID = "org.eclipse.cdt.ui.overrideIndicator"; //$NON-NLS-1$
+ private int type;
+ private ICElementHandle declaration;
+
+ public OverrideIndicator(int resultType, String message, IBinding binding, IIndex index) {
+ super(ANNOTATION_TYPE_ID, false, message);
+ this.type = resultType;
+ try {
+ declaration = IndexUI.findAnyDeclaration(index, null, binding);
+ if (declaration == null) {
+ ICElementHandle[] allDefinitions = IndexUI.findAllDefinitions(index, binding);
+ if (allDefinitions.length > 0) {
+ declaration = allDefinitions[0];
+ }
+ }
+ } catch (CoreException e) {
+ }
+ }
+
+ public int getIndicationType() {
+ return type;
+ }
+
+ public void open() {
+ try {
+ CDTUITools.openInEditor(declaration, true, true);
+ } catch (CoreException e) {
+ }
+
+ }
+
+ }
+
+ private IAnnotationModel fAnnotationModel;
+ private Vector fOverrideAnnotations = new Vector();
+ private Object fAnnotationModelLockObject;
+
+ public OverrideIndicatorManager(IAnnotationModel annotationModel) {
+ fAnnotationModel = annotationModel;
+ fAnnotationModelLockObject = getLockObject(fAnnotationModel);
+ }
+
+ private void handleResult(OverrideInfo info, IIndex index) {
+
+ Position position = new Position(info.nodeOffset, info.nodeLength);
+
+ OverrideIndicator indicator = new OverrideIndicator(info.resultType, info.message, info.binding, index);
+ synchronized (fAnnotationModelLockObject) {
+ fAnnotationModel.addAnnotation(indicator, position);
+ }
+ fOverrideAnnotations.add(indicator);
+ }
+
+ /**
+ * Removes all override indicators from this manager's annotation model.
+ */
+ public void removeAnnotations() {
+ if (fOverrideAnnotations == null)
+ return;
+
+ synchronized (fAnnotationModelLockObject) {
+ for (Annotation i : fOverrideAnnotations)
+ fAnnotationModel.removeAnnotation(i);
+ fOverrideAnnotations.clear();
+ }
+ }
+
+ public void generateAnnotations(IASTTranslationUnit ast, final IIndex index) {
+
+ class MethodDeclarationFinder extends ASTVisitor {
+ {
+ shouldVisitDeclarations = true;
+ }
+
+ @Override
+ public int visit(IASTDeclaration declaration) {
+ try {
+ IBinding binding = null;
+ ICPPMethod method = null;
+ if (isFunctionDeclaration(declaration)) {
+ binding = getDeclarationBinding(declaration);
+ } else if (declaration instanceof IASTFunctionDefinition) {
+ binding = getDefinitionBinding((IASTFunctionDefinition) declaration);
+ }
+ if (binding instanceof ICPPMethod) {
+ method = (ICPPMethod) binding;
+ OverrideInfo overrideInfo = testForOverride(method, declaration.getFileLocation());
+ if (overrideInfo != null) {
+ handleResult(overrideInfo, index);
+ }
+ }
+ } catch (DOMException e) {
+ }
+ // go to next declaration
+ return PROCESS_SKIP;
+ }
+ }
+ class CompositeTypeFinder extends ASTVisitor {
+ {
+ shouldVisitDeclSpecifiers = true;
+ }
+
+ @Override
+ public int visit(IASTDeclSpecifier declSpec) {
+ if (declSpec instanceof ICPPASTCompositeTypeSpecifier) {
+ declSpec.accept(new MethodDeclarationFinder());
+ }
+ return PROCESS_CONTINUE;
+ }
+ }
+
+ class MethodDefinitionFinder extends ASTVisitor {
+ {
+ shouldVisitDeclarations = true;
+ }
+
+ @Override
+ public int visit(IASTDeclaration declaration) {
+ try {
+ if (!(declaration instanceof IASTFunctionDefinition)) {
+ return PROCESS_SKIP;
+ }
+ IASTFunctionDefinition definition = (IASTFunctionDefinition) declaration;
+ IBinding definitionBinding = getDefinitionBinding(definition);
+ if (!(definitionBinding instanceof ICPPMethod)) {
+ return PROCESS_SKIP;
+ }
+ ICPPMethod method = (ICPPMethod) definitionBinding;
+ OverrideInfo overrideInfo = testForOverride(method, definition.getFileLocation());
+ if (overrideInfo != null) {
+ handleResult(overrideInfo, index);
+ }
+ } catch (DOMException e) {
+ }
+ return PROCESS_SKIP;
+ }
+ }
+
+ ast.accept(new CompositeTypeFinder());
+ ast.accept(new MethodDefinitionFinder());
+ }
+
+ public static OverrideInfo testForOverride(ICPPMethod testedOverride, IASTFileLocation location) throws DOMException {
+
+ testedOverride.getClassOwner().getBases();
+
+ boolean onlyPureVirtual = true;
+ StringBuilder sb = new StringBuilder();
+ Set overridenMethods = new HashSet();
+ Set shadowedMethods = new HashSet();
+
+ Set alreadyTestedBases = new HashSet();
+
+ ICPPBase[] bases = testedOverride.getClassOwner().getBases();
+
+ // Don't override 'self' in cyclic inheritance
+ alreadyTestedBases.add(testedOverride.getClassOwner());
+
+ for (ICPPBase base : bases) {
+ ICPPClassType testedClass;
+ if (!(base.getBaseClass() instanceof ICPPClassType)) {
+ continue;
+ }
+ testedClass = (ICPPClassType) base.getBaseClass();
+
+ overridenMethods.clear();
+ shadowedMethods.clear();
+ handleBaseClass(testedClass, testedOverride, overridenMethods, shadowedMethods, alreadyTestedBases);
+
+ for (ICPPMethod overriddenMethod : overridenMethods) {
+
+ if (sb.length() > 0) {
+ sb.append(MESSAGE_SEPARATOR);
+ }
+ if (overriddenMethod.isPureVirtual()) {
+ sb.append(CEditorMessages.OverrideIndicatorManager_implements);
+ } else {
+ sb.append(CEditorMessages.OverrideIndicatorManager_overrides);
+ onlyPureVirtual = false;
+ }
+ sb.append(' ');
+ sb.append(getQualifiedNameString(overriddenMethod));
+
+ if (bases.length > 1 && overriddenMethod.getClassOwner() != testedClass) {
+ sb.append(' ');
+ sb.append(CEditorMessages.OverrideIndicatorManager_via);
+ sb.append(' ');
+ sb.append(getQualifiedNameString(testedClass));
+ }
+ }
+ for (ICPPMethod shadowedMethod : shadowedMethods) {
+ if (sb.length() > 0) {
+ sb.append(MESSAGE_SEPARATOR);
+ }
+ sb.append(CEditorMessages.OverrideIndicatorManager_shadows);
+ sb.append(' ');
+ sb.append(getQualifiedNameString(shadowedMethod));
+ }
+ }
+
+ int markerType;
+ if (overridenMethods.size() > 0) {
+ markerType = onlyPureVirtual ? RESULT_IMPLEMENTS : RESULT_OVERRIDES;
+ } else {
+ markerType = RESULT_SHADOWS;
+ }
+
+ IBinding bindingToOpen = null;
+ if (overridenMethods.size() > 0) {
+ bindingToOpen = overridenMethods.iterator().next();
+ } else if (shadowedMethods.size() > 0) {
+ bindingToOpen = shadowedMethods.iterator().next();
+ }
+
+ if (sb.length() > 0) {
+ OverrideInfo info = new OverrideInfo(location.getNodeOffset(), location.getNodeLength(), markerType,
+ sb.toString(), bindingToOpen);
+ return info;
+ }
+ return null;
+
+ }
+
+ /**
+ * If the class directly has a valid override for testedOverride, it is added to foundBindings. Otherwise
+ * each base class is added to handleBaseClass.
+ *
+ * @param shadowedMethods
+ * @param alreadyTestedBases
+ *
+ * @throws DOMException
+ */
+ private static void handleBaseClass(ICPPClassType aClass, ICPPMethod testedOverride,
+ Set foundMethods, Set shadowedMethods, Set alreadyTestedBases) throws DOMException {
+
+ if (alreadyTestedBases.contains(aClass)) {
+ return;
+ } else {
+ alreadyTestedBases.add(aClass);
+ }
+
+ Vector validOverrides = new Vector();
+ for (ICPPMethod method : aClass.getDeclaredMethods()) {
+ if (testedOverride.getName().equals(method.getName())) {
+ if (ClassTypeHelper.isOverrider(testedOverride, method)) {
+ validOverrides.add(method);
+ } else if (sameParameters(testedOverride, method)) {
+ shadowedMethods.add(method);
+ }
+ }
+ }
+ if (validOverrides.size() > 1) {
+ /* System.err.println("Found many valid overrides"); */
+ }
+ if (validOverrides.size() >= 1) {
+ foundMethods.addAll(validOverrides);
+ return;
+ }
+
+ for (ICPPBase b : aClass.getBases()) {
+ if (!(b.getBaseClass() instanceof ICPPClassType)) {
+ continue;
+ }
+ ICPPClassType baseClass = (ICPPClassType) b.getBaseClass();
+ handleBaseClass(baseClass, testedOverride, foundMethods, shadowedMethods, alreadyTestedBases);
+ }
+ }
+
+ private static boolean sameParameters(ICPPMethod a, ICPPMethod b) throws DOMException {
+ ICPPFunctionType aType = a.getType();
+ ICPPFunctionType bType = b.getType();
+ if (aType.getParameterTypes().length != bType.getParameterTypes().length) {
+ return false;
+ }
+ for (int i = 0; i < aType.getParameterTypes().length; ++i) {
+ IType overrideParamType = aType.getParameterTypes()[i];
+ IType methodParamType = bType.getParameterTypes()[i];
+ if (!overrideParamType.isSameType(methodParamType)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static String getQualifiedNameString(ICPPBinding binding) throws DOMException {
+ String methodQualifiedName = ASTStringUtil.join(binding.getQualifiedName(), "::"); //$NON-NLS-1$
+ return methodQualifiedName;
+ }
+
+ private static boolean isFunctionDeclaration(IASTDeclaration declaration) {
+ if (!(declaration instanceof IASTSimpleDeclaration)) {
+ return false;
+ }
+ IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration) declaration;
+ IASTDeclarator[] declarators = simpleDecl.getDeclarators();
+ if (declarators.length < 1) {
+ return false;
+ }
+ IASTDeclarator declarator = ASTQueries.findInnermostDeclarator(declarators[0]);
+ return (declarator instanceof IASTFunctionDeclarator);
+ }
+
+ private static IBinding getDefinitionBinding(IASTFunctionDefinition definition) {
+ IASTDeclarator declarator = ASTQueries.findInnermostDeclarator(definition.getDeclarator());
+ return declarator.getName().resolveBinding();
+ }
+
+ private static IBinding getDeclarationBinding(IASTDeclaration declaration) {
+ for (IASTNode node : declaration.getChildren()) {
+ if (node instanceof IASTDeclarator) {
+ IASTDeclarator decl = ASTQueries.findInnermostDeclarator((IASTDeclarator) node);
+ return decl.getName().resolveBinding();
+ }
+ }
+ return null;
+ }
+
+ public void aboutToBeReconciled() {
+ }
+
+ public void reconciled(IASTTranslationUnit ast, boolean force, IProgressMonitor progressMonitor) {
+ if (ast == null) {
+ return;
+ }
+ IIndex index = ast.getIndex();
+ removeAnnotations();
+ generateAnnotations(ast, index);
+ }
+
+ /**
+ * Returns the lock object for the given annotation model.
+ *
+ * @param annotationModel
+ * the annotation model
+ * @return the annotation model's lock object
+ */
+ private Object getLockObject(IAnnotationModel annotationModel) {
+ if (annotationModel instanceof ISynchronizable) {
+ Object lock = ((ISynchronizable) annotationModel).getLockObject();
+ if (lock != null)
+ return lock;
+ }
+ return annotationModel;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/correction/CSelectAnnotationRulerAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/correction/CSelectAnnotationRulerAction.java
index 1ed6619eb3b..172ce109fa5 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/correction/CSelectAnnotationRulerAction.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/correction/CSelectAnnotationRulerAction.java
@@ -33,6 +33,8 @@ import org.eclipse.ui.texteditor.SelectMarkerRulerAction;
import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.cdt.internal.ui.editor.OverrideIndicatorManager;
+
/**
* Action which gets triggered when selecting (annotations) in the vertical ruler.
* based upon org.eclipse.jdt.internal.ui.javaeditor.JavaSelectMarkerRulerAction
@@ -45,6 +47,7 @@ public class CSelectAnnotationRulerAction extends SelectMarkerRulerAction {
private IPreferenceStore fStore;
private boolean fHasCorrection;
private ResourceBundle fBundle;
+ private Annotation fAnnotation;
public CSelectAnnotationRulerAction(ResourceBundle bundle, String prefix, ITextEditor editor, IVerticalRulerInfo ruler) {
super(bundle, prefix, editor, ruler);
@@ -69,6 +72,11 @@ public class CSelectAnnotationRulerAction extends SelectMarkerRulerAction {
*/
@Override
public void runWithEvent(Event event) {
+ if (fAnnotation instanceof OverrideIndicatorManager.OverrideIndicator) {
+ ((OverrideIndicatorManager.OverrideIndicator)fAnnotation).open();
+ return;
+ }
+
if (fHasCorrection) {
ITextOperationTarget operation= (ITextOperationTarget) fTextEditor.getAdapter(ITextOperationTarget.class);
final int opCode= ISourceViewer.QUICK_ASSIST;
@@ -91,6 +99,10 @@ public class CSelectAnnotationRulerAction extends SelectMarkerRulerAction {
findCAnnotation();
setEnabled(true);
+ if (fAnnotation instanceof OverrideIndicatorManager.OverrideIndicator) {
+ initialize(fBundle, "CSelectAnnotationRulerAction.OpenSuperImplementation."); //$NON-NLS-1$
+ return;
+ }
if (fHasCorrection) {
initialize(fBundle, "CSelectAnnotationRulerAction.QuickFix."); //$NON-NLS-1$
return;
@@ -102,6 +114,7 @@ public class CSelectAnnotationRulerAction extends SelectMarkerRulerAction {
private void findCAnnotation() {
fPosition= null;
+ fAnnotation = null;
fHasCorrection= false;
AbstractMarkerAnnotationModel model= getAnnotationModel();
@@ -135,6 +148,7 @@ public class CSelectAnnotationRulerAction extends SelectMarkerRulerAction {
if (!isReadOnly && CCorrectionProcessor.hasCorrections(annotation)) {
fPosition= position;
+ fAnnotation = annotation;
fHasCorrection= true;
layer= annotationLayer;
continue;
@@ -149,6 +163,7 @@ public class CSelectAnnotationRulerAction extends SelectMarkerRulerAction {
if (fStore.getBoolean(key)) {
fPosition= position;
+ fAnnotation = annotation;
fHasCorrection= false;
layer= annotationLayer;
}