diff -r 7a98b1bd40c3 cnd.navigation/src/org/netbeans/modules/cnd/navigation/overrides/OverrideAnnotationAction.java --- a/cnd.navigation/src/org/netbeans/modules/cnd/navigation/overrides/OverrideAnnotationAction.java Mon Jun 04 20:05:05 2012 +0200 +++ b/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); } diff -r 7a98b1bd40c3 csl.api/src/org/netbeans/modules/csl/editor/overridden/IsOverriddenAnnotationAction.java --- a/csl.api/src/org/netbeans/modules/csl/editor/overridden/IsOverriddenAnnotationAction.java Mon Jun 04 20:05:05 2012 +0200 +++ b/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); } diff -r 7a98b1bd40c3 debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/ui/actions/ToggleMethodFieldBreakpointAction.java --- a/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/ui/actions/ToggleMethodFieldBreakpointAction.java Mon Jun 04 20:05:05 2012 +0200 +++ b/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 () { diff -r 7a98b1bd40c3 editor.lib/apichanges.xml --- a/editor.lib/apichanges.xml Mon Jun 04 20:05:05 2012 +0200 +++ b/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 diff -r 7a98b1bd40c3 editor.lib/nbproject/project.properties --- a/editor.lib/nbproject/project.properties Mon Jun 04 20:05:05 2012 +0200 +++ b/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 diff -r 7a98b1bd40c3 editor.lib/src/org/netbeans/editor/Annotations.java --- a/editor.lib/src/org/netbeans/editor/Annotations.java Mon Jun 04 20:05:05 2012 +0200 +++ b/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; diff -r 7a98b1bd40c3 editor.lib/src/org/netbeans/editor/GlyphGutter.java --- a/editor.lib/src/org/netbeans/editor/GlyphGutter.java Mon Jun 04 20:05:05 2012 +0200 +++ b/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; diff -r 7a98b1bd40c3 java.editor/src/org/netbeans/modules/java/editor/overridden/IsOverriddenAnnotationAction.java --- a/java.editor/src/org/netbeans/modules/java/editor/overridden/IsOverriddenAnnotationAction.java Mon Jun 04 20:05:05 2012 +0200 +++ b/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); } diff -r 7a98b1bd40c3 spi.debugger.ui/src/org/netbeans/modules/debugger/ui/actions/DebuggerAction.java --- a/spi.debugger.ui/src/org/netbeans/modules/debugger/ui/actions/DebuggerAction.java Mon Jun 04 20:05:05 2012 +0200 +++ b/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; } diff -r 7a98b1bd40c3 spi.editor.hints/src/org/netbeans/modules/editor/hints/FixAction.java --- a/spi.editor.hints/src/org/netbeans/modules/editor/hints/FixAction.java Mon Jun 04 20:05:05 2012 +0200 +++ b/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) { diff -r 7a98b1bd40c3 web.beans/src/org/netbeans/modules/web/beans/navigation/actions/CdiGlyphAction.java --- a/web.beans/src/org/netbeans/modules/web/beans/navigation/actions/CdiGlyphAction.java Mon Jun 04 20:05:05 2012 +0200 +++ b/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)