--- a/cnd.navigation/src/org/netbeans/modules/cnd/navigation/overrides/OverrideAnnotationAction.java Mon Jun 04 20:05:05 2012 +0200 +++ a/cnd.navigation/src/org/netbeans/modules/cnd/navigation/overrides/OverrideAnnotationAction.java Tue Jun 05 13:32:02 2012 +0200 @@ -81,6 +81,14 @@ public OverrideAnnotationAction() { putValue(NAME, NbBundle.getMessage(OverrideAnnotationAction.class, "CTL_IsOverriddenAnnotationAction")); //NOI18N + putValue("supported-annotation-types", new String[] { + "org-netbeans-modules-editor-annotations-is_overridden", + "org-netbeans-modules-editor-annotations-overrides", + "org-netbeans-modules-cnd-navigation-specializes", + "org-netbeans-modules-cnd-navigation-is_specialized", + "org-netbeans-modules-cnd-navigation-extended_specializes", + "org-netbeans-modules-cnd-navigation-extended_is_specialized" + }); setEnabled(true); } --- a/csl.api/src/org/netbeans/modules/csl/editor/overridden/IsOverriddenAnnotationAction.java Mon Jun 04 20:05:05 2012 +0200 +++ a/csl.api/src/org/netbeans/modules/csl/editor/overridden/IsOverriddenAnnotationAction.java Tue Jun 05 13:32:02 2012 +0200 @@ -89,6 +89,12 @@ public IsOverriddenAnnotationAction() { putValue(NAME, NbBundle.getMessage(IsOverriddenAnnotationAction.class, "CTL_IsOverriddenAnnotationAction")); //NOI18N + putValue("supported-annotation-types", new String[] { + "org-netbeans-modules-editor-annotations-is_overridden", + "org-netbeans-modules-editor-annotations-has_implementations", + "org-netbeans-modules-editor-annotations-implements", + "org-netbeans-modules-editor-annotations-overrides" + }); setEnabled(true); } --- a/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/ui/actions/ToggleMethodFieldBreakpointAction.java Mon Jun 04 20:05:05 2012 +0200 +++ a/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/ui/actions/ToggleMethodFieldBreakpointAction.java Tue Jun 05 13:32:02 2012 +0200 @@ -72,12 +72,30 @@ */ public class ToggleMethodFieldBreakpointAction extends AbstractAction {//implements PropertyChangeListener { + private static final String[] BREAKPOINT_ANNOTATION_TYPES = new String[] { + "Breakpoint_broken", + "Breakpoint", + "CondBreakpoint_broken", + "CondBreakpoint", + "DisabledBreakpoint", + "DisabledCondBreakpoint", + "ClassBreakpoint", + "DisabledClassBreakpoint", + "DisabledFieldBreakpoint", + "DisabledMethodBreakpoint", + "FieldBreakpoint", + "MethodBreakpoint", + }; + private Object action; private RequestProcessor postponedToggleRP; public ToggleMethodFieldBreakpointAction () { //EditorContextBridge.addPropertyChangeListener (this); setEnabled (true); + putValue("default-action", true); + putValue("supported-annotation-types", BREAKPOINT_ANNOTATION_TYPES); + putValue("default-action-excluded-annotation-types", BREAKPOINT_ANNOTATION_TYPES); } public Object getAction () { --- a/editor.lib/apichanges.xml Mon Jun 04 20:05:05 2012 +0200 +++ a/editor.lib/apichanges.xml Tue Jun 05 13:32:02 2012 +0200 @@ -107,6 +107,29 @@ + + Clickable annotations in the editor glyph gutter + + + + + +

+ Editors/.../GlyphGutterActions can now specify on which annotations they need to be invoked. Supported annotation value (set using + putValue): +

+
+
default-action
+
if true, this action will be invoked when the free space is clicked
+
default-action-excluded-annotation-types
+
an array containing annotation types. When any of the annotations on the current line has any of these type, this action will not be invoked when the free space is clicked. (See below for combined annotations unrolling.)
+
supported-annotation-types
+
an array containing annotation types. When an annotation is clicked, the first action that contains its type in the supported-annotation-types attribute is invoked.
+
+
+ +
+ Replace is done before insert and fix inserting empty text --- a/editor.lib/nbproject/project.properties Mon Jun 04 20:05:05 2012 +0200 +++ a/editor.lib/nbproject/project.properties Tue Jun 05 13:32:02 2012 +0200 @@ -42,7 +42,7 @@ javac.compilerargs=-Xlint:unchecked javac.source=1.6 -spec.version.base=3.23.0 +spec.version.base=3.24.0 is.autoload=true javadoc.arch=${basedir}/arch.xml --- a/editor.lib/src/org/netbeans/editor/Annotations.java Mon Jun 04 20:05:05 2012 +0200 +++ a/editor.lib/src/org/netbeans/editor/Annotations.java Tue Jun 05 13:32:02 2012 +0200 @@ -1333,7 +1333,7 @@ * annotations which are representd by this combined annotation. The only * added functionality is for tooltip text and annotation type. */ - private static final class AnnotationCombination extends AnnotationDesc implements Lookup.Provider { + static final class AnnotationCombination extends AnnotationDesc implements Lookup.Provider { /** Delegate annotaiton */ private AnnotationDesc delegate; --- a/editor.lib/src/org/netbeans/editor/GlyphGutter.java Mon Jun 04 20:05:05 2012 +0200 +++ a/editor.lib/src/org/netbeans/editor/GlyphGutter.java Tue Jun 05 13:32:02 2012 +0200 @@ -65,6 +65,13 @@ import java.awt.event.*; import java.awt.font.FontRenderContext; import java.awt.font.TextLayout; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; @@ -88,6 +95,8 @@ import org.netbeans.api.editor.settings.EditorStyleConstants; import org.netbeans.api.editor.settings.FontColorNames; import org.netbeans.api.editor.settings.FontColorSettings; +import org.netbeans.editor.AnnotationType.CombinationMember; +import org.netbeans.editor.Annotations.AnnotationCombination; import org.netbeans.modules.editor.lib.ColoringMap; import org.netbeans.modules.editor.lib2.view.*; import org.openide.util.ImageUtilities; @@ -874,33 +883,98 @@ annos.activateNextAnnotation(line); } else { Action actions[] = ImplementationProvider.getDefault().getGlyphGutterActions(eui.getComponent()); - if (actions != null && actions.length >0) { - Action a = actions[0]; //TODO - create GUI chooser - if (a!=null && a.isEnabled()){ - int currentLine = -1; - int line = getLineFromMouseEvent(e); - if (line == -1) return; - BaseDocument document = eui.getDocument(); - try { - currentLine = Utilities.getLineOffset(document, eui.getComponent().getCaret().getDot()); - } catch (BadLocationException ex) { - return; + if (actions == null && actions.length == 0) { + Toolkit.getDefaultToolkit().beep(); + return; + } + int currentLine = -1; + int line = getLineFromMouseEvent(e); + if (line == -1) { + Toolkit.getDefaultToolkit().beep(); + return; + } + Action toInvoke = null; + Action defaultAction = null; + AnnotationDesc active = annos.getActiveAnnotation(line); + if (active == null || !isMouseOverGlyph(e)) { + Collection base = new HashSet(); + if (active != null) { + base.add(active); + } + AnnotationDesc[] passive = annos.getPasiveAnnotations(line); + if (passive != null) { + base.addAll(Arrays.asList(passive)); + } + Collection annotationTypes = computeAnnotationTypesToAnalyze(base); + for (Action a : actions) { + Object defAction = a.getValue("default-action"); + if (toInvoke == null && defAction != null && ((Boolean) defAction)) { + Object supportedAnnotationTypes = a.getValue("default-action-excluded-annotation-types"); + if (supportedAnnotationTypes == null || !(supportedAnnotationTypes instanceof String[]) || Collections.disjoint(Arrays.asList((String[]) supportedAnnotationTypes), annotationTypes)) { + toInvoke = a; + } } - if (line != currentLine) { - int offset = Utilities.getRowStartFromLineOffset(document, line); - JumpList.checkAddEntry(); - eui.getComponent().getCaret().setDot(offset); + if (defaultAction == null && isLegacyAction(a)) { + defaultAction = a; } - e.consume(); - a.actionPerformed(new ActionEvent(eui.getComponent(), 0, "")); - repaint(); } } else { + Collection annotationTypes = computeAnnotationTypesToAnalyze(Arrays.asList(active)); + for (Action a : actions) { + Object supportedAnnotationTypes = a.getValue("supported-annotation-types"); + if (supportedAnnotationTypes instanceof String[]) { + if (toInvoke == null && !Collections.disjoint(Arrays.asList((String[]) supportedAnnotationTypes), annotationTypes)) { + toInvoke = a; + } + if (defaultAction == null && isLegacyAction(a)) { + defaultAction = a; + } + } + } + } + toInvoke = toInvoke != null ? toInvoke : defaultAction; + if (toInvoke != null && toInvoke.isEnabled()){ + BaseDocument document = eui.getDocument(); + try { + currentLine = Utilities.getLineOffset(document, eui.getComponent().getCaret().getDot()); + } catch (BadLocationException ex) { + return; + } + if (line != currentLine) { + int offset = Utilities.getRowStartFromLineOffset(document, line); + JumpList.checkAddEntry(); + eui.getComponent().getCaret().setDot(offset); + } + e.consume(); + toInvoke.actionPerformed(new ActionEvent(eui.getComponent(), 0, "")); + repaint(); + } else { Toolkit.getDefaultToolkit().beep(); } } } } + + private boolean isLegacyAction(Action a) { + return a.getValue("default-action") == null && a.getValue("supported-annotation-types") == null; + } + + private Collection computeAnnotationTypesToAnalyze(Collection startAt) { + Collection annotationTypes = new HashSet(); + List combinationsToAnalyze = new LinkedList(startAt); + + while (!combinationsToAnalyze.isEmpty()) { + AnnotationDesc desc = combinationsToAnalyze.remove(0); + + annotationTypes.add(desc.getAnnotationType()); + + if (!(desc instanceof AnnotationCombination)) continue; + + combinationsToAnalyze.addAll(((AnnotationCombination) desc).getCombinedAnnotations()); + } + + return annotationTypes; + } private void showPopup(MouseEvent e) { final EditorUI eui = editorUI; --- a/java.editor/src/org/netbeans/modules/java/editor/overridden/IsOverriddenAnnotationAction.java Mon Jun 04 20:05:05 2012 +0200 +++ a/java.editor/src/org/netbeans/modules/java/editor/overridden/IsOverriddenAnnotationAction.java Tue Jun 05 13:32:02 2012 +0200 @@ -86,6 +86,12 @@ public IsOverriddenAnnotationAction() { putValue(NAME, NbBundle.getMessage(IsOverriddenAnnotationAction.class, "CTL_IsOverriddenAnnotationAction")); //NOI18N + putValue("supported-annotation-types", new String[] { + "org-netbeans-modules-editor-annotations-is_overridden", + "org-netbeans-modules-editor-annotations-has_implementations", + "org-netbeans-modules-editor-annotations-implements", + "org-netbeans-modules-editor-annotations-overrides" + }); setEnabled(true); } --- a/spi.debugger.ui/src/org/netbeans/modules/debugger/ui/actions/DebuggerAction.java Mon Jun 04 20:05:05 2012 +0200 +++ a/spi.debugger.ui/src/org/netbeans/modules/debugger/ui/actions/DebuggerAction.java Tue Jun 05 13:32:02 2012 +0200 @@ -278,9 +278,21 @@ return action; } + private static final String[] BREAKPOINT_ANNOTATION_TYPES = new String[] { + "Breakpoint_broken", + "Breakpoint", + "CondBreakpoint_broken", + "CondBreakpoint", + "DisabledBreakpoint", + "DisabledCondBreakpoint" + }; + public static DebuggerAction createToggleBreakpointAction () { DebuggerAction action = new DebuggerAction(ActionsManager.ACTION_TOGGLE_BREAKPOINT); action.putValue (Action.NAME, "CTL_Toggle_breakpoint"); + action.putValue("default-action", true); + action.putValue("supported-annotation-types", BREAKPOINT_ANNOTATION_TYPES); + action.putValue("default-action-excluded-annotation-types", BREAKPOINT_ANNOTATION_TYPES); return action; } --- a/spi.editor.hints/src/org/netbeans/modules/editor/hints/FixAction.java Mon Jun 04 20:05:05 2012 +0200 +++ a/spi.editor.hints/src/org/netbeans/modules/editor/hints/FixAction.java Tue Jun 05 13:32:02 2012 +0200 @@ -61,6 +61,12 @@ public FixAction() { putValue(NAME, NbBundle.getMessage(FixAction.class, "NM_FixAction")); + putValue("supported-annotation-types", new String[] { + "org-netbeans-spi-editor-hints-parser_annotation_err_fixable", + "org-netbeans-spi-editor-hints-parser_annotation_warn_fixable", + "org-netbeans-spi-editor-hints-parser_annotation_verifier_fixable", + "org-netbeans-spi-editor-hints-parser_annotation_hint_fixable" + }); } public void actionPerformed(ActionEvent e) { --- a/web.beans/src/org/netbeans/modules/web/beans/navigation/actions/CdiGlyphAction.java Mon Jun 04 20:05:05 2012 +0200 +++ a/web.beans/src/org/netbeans/modules/web/beans/navigation/actions/CdiGlyphAction.java Tue Jun 05 13:32:02 2012 +0200 @@ -74,6 +74,15 @@ public CdiGlyphAction(){ putValue(NAME, NbBundle.getMessage(CdiGlyphAction.class, "TXT_GlyphActionName")); // NOI18N + putValue("supported-annotation-types", new String[] { + "org-netbeans-modules-web-beans-annotations-injection-point", + "org-netbeans-modules-web-beans-annotations-delegate-point", + "org-netbeans-modules-web-beans-annotations-decorated-bean", + "org-netbeans-modules-web-beans-annotations-event", + "org-netbeans-modules-web-beans-annotations-observer", + "org-netbeans-modules-editor-annotations-intercepted" + }); + } /* (non-Javadoc)