Skip to main content
summaryrefslogtreecommitdiffstats
blob: e48513d541765423b3c5ab5cb2d85598758143c5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
package org.eclipse.debug.internal.ui.views;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
 
import org.eclipse.core.resources.IMarkerDelta;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IBreakpointListener;
import org.eclipse.debug.core.IBreakpointManager;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.ILineBreakpoint;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.DelegatingModelPresentation;
import org.eclipse.debug.internal.ui.IDebugHelpContextIds;
import org.eclipse.debug.internal.ui.actions.OpenBreakpointMarkerAction;
import org.eclipse.debug.internal.ui.actions.RemoveAllBreakpointsAction;
import org.eclipse.debug.internal.ui.actions.RemoveBreakpointAction;
import org.eclipse.debug.internal.ui.actions.ShowBreakpointsForModelAction;
import org.eclipse.debug.ui.AbstractDebugView;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.IBasicPropertyConstants;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IWorkbenchActionConstants;

/**
 * This view shows the breakpoints registered with the breakpoint manager
 */
public class BreakpointsView extends AbstractDebugView {
	
	class BreakpointsSorter extends ViewerSorter {
		/**
		 * @see ViewerSorter#isSorterProperty(Object, String)
		 */
		public boolean isSorterProperty(Object element,String propertyId) {
			return propertyId.equals(IBasicPropertyConstants.P_TEXT);
		}
		
		/**
		 * Returns a negative, zero, or positive number depending on whether
		 * the first element is less than, equal to, or greater than
		 * the second element.
		 * <p>
		 * Group breakpoints by debug model
		 * 	within debug model, group breakpoints by type 
		 * 		within type groups, sort by line number (if applicable) and then
		 * 		alphabetically by label
		 * 
		 * @param viewer the viewer
		 * @param e1 the first element
		 * @param e2 the second element
		 * @return a negative number if the first element is less than the 
		 *  second element; the value <code>0</code> if the first element is
		 *  equal to the second element; and a positive number if the first
		 *  element is greater than the second element
		 */
		public int compare(Viewer viewer, Object e1, Object e2) {
	
			IBreakpoint b1= (IBreakpoint)e1;
			IBreakpoint b2= (IBreakpoint)e2;
			String modelId1= b1.getModelIdentifier();
			String modelId2= b2.getModelIdentifier();
			int result= modelId1.compareTo(modelId2);
			if (result != 0) {
				return result;
			}
			String type1= ""; //$NON-NLS-1$
			String type2= ""; //$NON-NLS-1$
			try {
				type1= b1.getMarker().getType();
			} catch (CoreException ce) {
				DebugUIPlugin.log(ce);
			}
			try {
				type2= b2.getMarker().getType();	
			} catch (CoreException e) {
				DebugUIPlugin.log(e);
			}
		
			result= type1.compareTo(type2);
			if (result != 0) {
				return result;
			}
			// model and type are the same
		
			ILabelProvider lprov = (ILabelProvider) ((StructuredViewer)viewer).getLabelProvider();
			String name1= lprov.getText(e1);
			String name2= lprov.getText(e2);
	
			boolean lineBreakpoint= false;
			try {
				lineBreakpoint= b1.getMarker().isSubtypeOf(IBreakpoint.LINE_BREAKPOINT_MARKER);
			} catch (CoreException ce) {
				DebugUIPlugin.log(ce);
			}
			if (lineBreakpoint) {
				return compareLineBreakpoints(b1, b2, name1,name2);
			} 
			
			return name1.compareTo(name2);		
		}
		
		protected int compareLineBreakpoints(IBreakpoint b1, IBreakpoint b2, String name1, String name2) {
			int colon1= name1.indexOf(':');
			if (colon1 != -1) {
				int colon2= name2.indexOf(':');
				if (colon2 != -1) {
					String upToColon1= name1.substring(0, colon1);
					if (name2.startsWith(upToColon1)) {
						int l1= 0;
						int l2= 0;
						try {
							l1= ((ILineBreakpoint)b1).getLineNumber();	
						} catch (CoreException e) {
							DebugUIPlugin.log(e);
						}
						try {
							l2= ((ILineBreakpoint)b2).getLineNumber();	
						} catch (CoreException e) {
							DebugUIPlugin.log(e);
						}
						return l1 - l2;
					}
				}
			}
			return name1.compareTo(name2);
		}
	}

	private BreakpointsViewEventHandler fEventHandler;
	
	/**
	 * @see AbstractDebugView#createViewer(Composite)
	 */
	protected Viewer createViewer(Composite parent) {
		StructuredViewer viewer = new TableViewer(parent, SWT.MULTI| SWT.H_SCROLL | SWT.V_SCROLL);
		viewer.setContentProvider(new BreakpointsViewContentProvider());
		viewer.setLabelProvider(new DelegatingModelPresentation());
		viewer.setSorter(new BreakpointsSorter());
		viewer.setInput(DebugPlugin.getDefault().getBreakpointManager());		
		// Necessary so that the PropertySheetView hears about selections in this view
		getSite().setSelectionProvider(viewer);
		setEventHandler(new BreakpointsViewEventHandler());
		return viewer;
	}	
	
	/**
	 * @see AbstractDebugView#getHelpContextId()
	 */
	protected String getHelpContextId() {
		return IDebugHelpContextIds.BREAKPOINT_VIEW;
	}

	/**
	 * @see IWorkbenchPart#dispose()
	 */
	public void dispose() {
		IAction action= getAction("ShowBreakpointsForModel"); //$NON-NLS-1$
		if (action != null) {
			((ShowBreakpointsForModelAction)action).dispose(); 
		}
		
		super.dispose();
		
		if (getEventHandler() != null) {
			getEventHandler().dispose();
		}
	}

	/**
	 * @see AbstractDebugView#createActions()
	 */
	protected void createActions() {
		IAction action = new OpenBreakpointMarkerAction(getViewer());
		setAction("GotoMarker", action); //$NON-NLS-1$
		setAction(DOUBLE_CLICK_ACTION, action);
		setAction("ShowBreakpointsForModel", new ShowBreakpointsForModelAction(getStructuredViewer(),this)); //$NON-NLS-1$
	}

	/**
	 * Adds items to the context menu.
	 * 
	 * @param menu The menu to contribute to
	 */
	protected void fillContextMenu(IMenuManager menu) {
		updateActions();
		menu.add(new Separator(IDebugUIConstants.EMPTY_NAVIGATION_GROUP));
		menu.add(new Separator(IDebugUIConstants.NAVIGATION_GROUP));
		menu.add(getAction("GotoMarker")); //$NON-NLS-1$
		menu.add(new Separator(IDebugUIConstants.EMPTY_BREAKPOINT_GROUP));
		menu.add(new Separator(IDebugUIConstants.BREAKPOINT_GROUP));
		menu.add(new Separator(IDebugUIConstants.EMPTY_RENDER_GROUP));
		menu.add(new Separator(IDebugUIConstants.RENDER_GROUP));
		menu.add(getAction("ShowBreakpointsForModel")); //$NON-NLS-1$
		menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
	}
	
	/**
	 * @see AbstractDebugView#configureToolBar(IToolBarManager)
	 */
	protected void configureToolBar(IToolBarManager tbm) {
		tbm.add(new Separator(IDebugUIConstants.BREAKPOINT_GROUP));
		tbm.add(getAction("ShowBreakpointsForModel")); //$NON-NLS-1$
		tbm.add(getAction("GotoMarker")); //$NON-NLS-1$
		tbm.add(new Separator(IDebugUIConstants.RENDER_GROUP));
	}

	/**
	 * Provides the contents for a this view
	 */
	class BreakpointsViewContentProvider implements IStructuredContentProvider {

		/**
		 * @see IStructuredContentProvider#getElements(Object)
		 */
		public Object[] getElements(Object parent) {
			return ((IBreakpointManager) parent).getBreakpoints();
		}
		
		/**
		 * @see IContentProvider#dispose()
		 */
		public void dispose() {
		}
	
		/**
		 * @see IContentProvider#inputChanged(Viewer, Object, Object)
		 */
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
		}
	}
	
	/**
	 * Handles breakpoint events, updating the breakpoints view
	 * and viewer.
	 */
	class BreakpointsViewEventHandler implements IBreakpointListener {
	
		/**
		 * Constructs an enent handler for the breakpoints view.
		 */
		public BreakpointsViewEventHandler() {
			DebugPlugin.getDefault().getBreakpointManager().addBreakpointListener(this);
		}
		
		public void dispose() {
			DebugPlugin.getDefault().getBreakpointManager().removeBreakpointListener(this);
		}
	
	
		/**
		 * @see IBreakpointListener#breakpointAdded(IBreakpoint)
		 */
		public void breakpointAdded(final IBreakpoint breakpoint) {
			if (isAvailable()&& breakpoint.getMarker().exists()) {		
				asyncExec(new Runnable() {
					public void run() {
						if (isAvailable() && breakpoint.getMarker().exists()) {
							((TableViewer)getViewer()).add(breakpoint);
							updateActions();
						}
					}
				});
			}
		}
	
	
		/**
		 * @see IBreakpointListener#breakpointRemoved(IBreakpoint, IMarkerDelta)
		 */
		public void breakpointRemoved(final IBreakpoint breakpoint, IMarkerDelta delta) {
			if (isAvailable()) {
				asyncExec(new Runnable() {
					public void run() {
						if (isAvailable()) {
							((TableViewer)getViewer()).remove(breakpoint);
							updateActions();
						}
					}
				});
			}
		}
	
		/**
		 * @see IBreakpointListener#breakpointChanged(IBreakpoint, IMarkerDelta)
		 */
		public void breakpointChanged(final IBreakpoint breakpoint, IMarkerDelta delta) {
			if (isAvailable()&& breakpoint.getMarker().exists()) {
				asyncExec(new Runnable() {
					public void run() {
						if (isAvailable() && breakpoint.getMarker().exists()) {
							((TableViewer)getViewer()).refresh(breakpoint);
							updateActions();
						}
					}
				});
			}
		}
	}
	
	/**
	 * Returns this view's event handler
	 * 
	 * @return a breakpoint view event handler
	 */
	protected BreakpointsViewEventHandler getEventHandler() {
		return fEventHandler;
	}

	/**
	 * Sets this view's event handler.
	 * 
	 * @param eventHandler a breakpoint view event handler
	 */
	private void setEventHandler(BreakpointsViewEventHandler eventHandler) {
		fEventHandler = eventHandler;
	}
}

Back to the top