1+ /*******************************************************************************
2+ * Copyright (c) 2025 IBM Corporation
3+ *
4+ * This program and the accompanying materials
5+ * are made available under the terms of the Eclipse Public License 2.0
6+ * which accompanies this distribution, and is available at
7+ * https://www.eclipse.org/legal/epl-2.0/
8+ *
9+ * SPDX-License-Identifier: EPL-2.0
10+ *
11+ * Contributors:
12+ * IBM Corporation - initial API and implementation
13+ *******************************************************************************/
14+ package org .eclipse .jdt .internal .debug .ui .actions ;
15+
16+ import org .eclipse .core .runtime .CoreException ;
17+ import org .eclipse .debug .internal .ui .DebugUIPlugin ;
18+ import org .eclipse .jdt .debug .core .IJavaLineBreakpoint ;
19+ import org .eclipse .jdt .internal .debug .ui .JDIDebugUIPlugin ;
20+ import org .eclipse .jface .action .Action ;
21+ import org .eclipse .jface .action .IAction ;
22+ import org .eclipse .jface .dialogs .IInputValidator ;
23+ import org .eclipse .jface .dialogs .InputDialog ;
24+ import org .eclipse .jface .text .BadLocationException ;
25+ import org .eclipse .jface .text .IDocument ;
26+ import org .eclipse .jface .text .IRegion ;
27+ import org .eclipse .jface .text .ITextSelection ;
28+ import org .eclipse .jface .text .TextSelection ;
29+ import org .eclipse .jface .text .source .IVerticalRulerInfo ;
30+ import org .eclipse .jface .viewers .ISelection ;
31+ import org .eclipse .jface .viewers .ISelectionProvider ;
32+ import org .eclipse .jface .window .Window ;
33+ import org .eclipse .swt .widgets .Event ;
34+ import org .eclipse .swt .widgets .Shell ;
35+ import org .eclipse .ui .IActionDelegate2 ;
36+ import org .eclipse .ui .IEditorPart ;
37+ import org .eclipse .ui .texteditor .AbstractRulerActionDelegate ;
38+ import org .eclipse .ui .texteditor .IDocumentProvider ;
39+ import org .eclipse .ui .texteditor .ITextEditor ;
40+
41+ public class RulerToggleHitBreakpointActionDelegate extends AbstractRulerActionDelegate implements IActionDelegate2 {
42+
43+ private IEditorPart currentEditor ;
44+ private IAction dummyAction ;
45+
46+ @ Override
47+ protected IAction createAction (ITextEditor editor , IVerticalRulerInfo rulerInfo ) {
48+ dummyAction = new Action () {
49+ };
50+ return dummyAction ;
51+ }
52+
53+ @ Override
54+ public void setActiveEditor (IAction callerAction , IEditorPart targetEditor ) {
55+ currentEditor = targetEditor ;
56+ }
57+
58+ @ Override
59+ public void init (IAction action ) {
60+ }
61+
62+ @ Override
63+ public void dispose () {
64+ currentEditor = null ;
65+ dummyAction = null ;
66+ super .dispose ();
67+ }
68+
69+ @ Override
70+ public void runWithEvent (IAction action , Event event ) {
71+ if (!(currentEditor instanceof ITextEditor )) {
72+ return ;
73+ }
74+ IVerticalRulerInfo rulerInfo = currentEditor .getAdapter (IVerticalRulerInfo .class );
75+ if (rulerInfo == null ) {
76+ return ;
77+ }
78+ int lineOfLastMouseButtonActivity = rulerInfo .getLineOfLastMouseButtonActivity ();
79+ if (lineOfLastMouseButtonActivity < 0 ) {
80+ return ;
81+ }
82+ IDocument document = getDocument ((ITextEditor ) currentEditor );
83+ if (document == null ) {
84+ return ;
85+ }
86+ ToggleBreakpointAdapter toggle = new ToggleBreakpointAdapter ();
87+ try {
88+ ITextSelection selection = getTextSelection (currentEditor , document , lineOfLastMouseButtonActivity );
89+ if (toggle .canToggleLineBreakpoints (currentEditor , selection )) {
90+ IJavaLineBreakpoint jlp = ToggleBreakpointAdapter .findExistingBreakpoint ((ITextEditor ) currentEditor , selection );
91+ if (jlp == null ) {
92+ hitCountDialog ();
93+
94+ if (BreakpointToggleUtils .getHitCount () < 2 ) {
95+
96+ return ;
97+
98+ }
99+ }
100+ BreakpointToggleUtils .setHitpoints (true );
101+ toggle .toggleBreakpoints (currentEditor , selection );
102+ }
103+ } catch (BadLocationException | CoreException e ) {
104+ DebugUIPlugin .log (e );
105+ }
106+ }
107+
108+ private static IDocument getDocument (ITextEditor editor ) {
109+ IDocumentProvider provider = editor .getDocumentProvider ();
110+ if (provider != null ) {
111+ return provider .getDocument (editor .getEditorInput ());
112+ }
113+ IDocument doc = editor .getAdapter (IDocument .class );
114+ if (doc != null ) {
115+ return doc ;
116+ }
117+ return null ;
118+ }
119+
120+ private static ITextSelection getTextSelection (IEditorPart editor , IDocument document , int line ) throws BadLocationException {
121+ IRegion region = document .getLineInformation (line );
122+ ITextSelection textSelection = new TextSelection (document , region .getOffset (), 0 );
123+ ISelectionProvider provider = editor .getSite ().getSelectionProvider ();
124+ if (provider != null ) {
125+ ISelection selection = provider .getSelection ();
126+ if (selection instanceof ITextSelection && ((ITextSelection ) selection ).getStartLine () <= line
127+ && ((ITextSelection ) selection ).getEndLine () >= line ) {
128+ textSelection = (ITextSelection ) selection ;
129+ }
130+ }
131+ return textSelection ;
132+ }
133+
134+ private void hitCountDialog () {
135+ String title = ActionMessages .BreakpointHitCountAction_Set_Breakpoint_Hit_Count_2 ;
136+ String message = ActionMessages .BreakpointHitCountAction__Enter_the_new_hit_count_for_the_breakpoint__3 ;
137+ IInputValidator validator = new IInputValidator () {
138+ int hitCount = -1 ;
139+
140+ @ Override
141+ public String isValid (String value ) {
142+ try {
143+ hitCount = Integer .parseInt (value .trim ());
144+ } catch (NumberFormatException nfe ) {
145+ hitCount = -1 ;
146+ }
147+ if (hitCount < 1 ) {
148+ return ActionMessages .BreakpointHitCountAction_Value_must_be_positive_integer ;
149+ }
150+ // no error
151+ return null ;
152+ }
153+ };
154+
155+ Shell activeShell = JDIDebugUIPlugin .getActiveWorkbenchShell ();
156+ InputDialog input = new InputDialog (activeShell , title , message , "" , validator ); //$NON-NLS-1$
157+ if (input .open () == Window .CANCEL ) {
158+ return ;
159+ }
160+ String hit = input .getValue ();
161+ if (hit != null && !hit .isEmpty ()) {
162+ BreakpointToggleUtils .setHitCount (Integer .parseInt (hit ));
163+ }
164+ }
165+ }
0 commit comments