Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 5429f3f6c0386fb27829d5634dc512e5193e25bc (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
/*******************************************************************************
 * Copyright (c) 2005, 2015 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.debug.internal.ui.importexport.breakpoints;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;

import org.eclipse.core.runtime.Assert;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.DelegatingModelPresentation;
import org.eclipse.debug.internal.ui.SWTFactory;
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointContainer;
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointOrganizer;
import org.eclipse.debug.internal.ui.views.breakpoints.BreakpointContainer;
import org.eclipse.debug.internal.ui.views.breakpoints.BreakpointsComparator;
import org.eclipse.debug.internal.ui.views.breakpoints.BreakpointsContentProvider;
import org.eclipse.debug.internal.ui.views.breakpoints.BreakpointsLabelProvider;
import org.eclipse.debug.internal.ui.views.breakpoints.BreakpointsView;
import org.eclipse.debug.internal.ui.views.breakpoints.BreakpointsViewer;
import org.eclipse.debug.ui.IDebugModelPresentation;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.IViewPart;

/**
 * This class creates a simplified debug view that can be used in wizards etc., to emulate the current debug view
 *
 * @see WizardExportBreakpointsPage
 * @see WizardImportBreakpointsPage
 *
 * @since 3.2
 */
public class EmbeddedBreakpointsViewer {

	//widgets
	private IStructuredSelection fSelection = null;
	private BreakpointsContentProvider fProvider = null;
	private Tree fTree = null;
	private BreakpointsViewer fViewer = null;
	private ICheckStateListener fCheckListener = new ICheckStateListener() {
		@Override
		public void checkStateChanged(CheckStateChangedEvent event) {
			updateCheckedState(event.getElement(), event.getChecked());
		}
	};

	/**
	 * This constructor allows a specific selection to be used in stead of the default
	 *
	 * @param parent the parent composite to add this one to
	 * @param input the input to the viewer
	 * @param selection the selection to set on the viewer
	 */
	public EmbeddedBreakpointsViewer(Composite parent, Object input, IStructuredSelection selection) {
		Assert.isNotNull(parent);
		Assert.isNotNull(input);
		createControl(parent, input, selection);
	}

	/**
	 * Creates the control initialized to the current view, selection, and organization of the breakpoints view
	 * @param parent the parent composite to add this one to.
	 *
	 * @param parent the parent composite to add this one to
	 * @param input the input for the viewer
	 * @param selection the selection for the viewer to be initialized to. If null the selection from the breakpoints view is used
	 */
	private void createControl(Composite parent, Object input, IStructuredSelection selection) {
		fSelection = selection;
		if(fSelection == null) {
			IViewPart fViewpart = DebugUIPlugin.getActiveWorkbenchWindow().getActivePage().findView(IDebugUIConstants.ID_BREAKPOINT_VIEW);
			if(fViewpart != null) {
				fSelection = (IStructuredSelection)fViewpart.getViewSite().getSelectionProvider().getSelection();
			}
			else {
				fSelection = new StructuredSelection();
			}
		}
		Composite composite = SWTFactory.createComposite(parent, parent.getFont(), 1, 1, GridData.FILL_BOTH, 0, 0);

		// create the treeview
		fTree = new Tree(composite, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.CHECK);
		GridData gd = new GridData(GridData.FILL_BOTH);
		gd.heightHint = 150;
		fTree.setLayoutData(gd);
		fProvider = new BreakpointsContentProvider();
		BreakpointsView view = ((BreakpointsView)DebugUIPlugin.getActiveWorkbenchWindow().getActivePage().findView(IDebugUIConstants.ID_BREAKPOINT_VIEW));
		fViewer = new BreakpointsViewer(fTree);
		BreakpointsLabelProvider labelprovider = new BreakpointsLabelProvider();
		if(view != null) {
			//if we have handle to the view try get the current attributes, that way the
			//presentation of the embedded viewer matches the current view
			Map<String, Object> map = null;
			IDebugModelPresentation current = view.getAdapter(IDebugModelPresentation.class);
		    if (current instanceof DelegatingModelPresentation) {
				map = ((DelegatingModelPresentation) current).getAttributes();
			}
			if(map != null) {
				Object key = null;
				IDebugModelPresentation newpres = labelprovider.getPresentation();
				for (Iterator<String> iter = map.keySet().iterator(); iter.hasNext();) {
					key = iter.next();
					newpres.setAttribute((String) key, map.get(key));
				}
			}
		}
		fViewer.setComparator(new BreakpointsComparator());
		fViewer.setLabelProvider(labelprovider);
		fViewer.addCheckStateListener(fCheckListener);
		IBreakpointOrganizer[] orgs = null;
		if(view != null) {
			 orgs = view.getBreakpointOrganizers();
		}
		fViewer.setContentProvider(fProvider);
		fViewer.setInput(input);
		fProvider.setOrganizers(orgs);
		initViewerState();
	}

	/**
	 * Performs the initialization of the viewer from a selection
	 */
	private void initViewerState() {
		Object[] items = fSelection.toArray();
		fViewer.setGrayedElements(new Object[] {});
		fViewer.setCheckedElements(new Object[] {});
		ArrayList<IBreakpoint> list = new ArrayList<>();
		for(int i = 0; i < items.length; i++) {
			Object item = items[i];
			IBreakpoint breakpoint = (IBreakpoint)DebugPlugin.getAdapter(item, IBreakpoint.class);
			if(breakpoint != null) {
				list.add(breakpoint);
			}
			else if (item instanceof IBreakpointContainer) {
			    getBreakpointsFromContainers((IBreakpointContainer)item, list);
			}
		}
		for(int i = 0; i < list.size(); i++) {
			updateCheckedState(list.get(i), true);
		}
	}

	/**
	 * FInds the breakpoints of a given container
	 * @param container the container to get breakpoints from
	 * @param list the list of breakpoints to update state for
	 */
	private void getBreakpointsFromContainers(IBreakpointContainer container, ArrayList<IBreakpoint> list) {
        IBreakpoint[] bps = container.getBreakpoints();
        list.ensureCapacity(list.size() + bps.length);
        for (int j = 0; j < bps.length; j++) {
            list.add(bps[j]);
        }
	}

	/**
	 * Returns the selection from the viewer with no duplicates
	 * @return the selection from the viewer with no duplicates
	 */
	public IStructuredSelection getCheckedElements() {
		Object[] list = fViewer.getCheckedElements();
		Vector<Object> selected = new Vector<>();
		for(int i = 0; i < list.length; i++) {
			if(!selected.contains(list[i])) {
				selected.addElement(list[i]);
			}
		}
		return new StructuredSelection(selected);
	}

	/**
	 * Allows access to the viewer
	 * @return the viewer
	 */
	public BreakpointsViewer getViewer() {
		return fViewer;
	}

	/**
	 * finds all occurrences of a widget to update
	 * @param element the element to search for when finding occurrences
	 * @return a list of widget occurrences to update or an empty list
	 */
    private Widget[] searchItems(Object element) {
		ArrayList<TreeItem> list = new ArrayList<>();
        TreeItem[] items = fTree.getItems();
        for (int i = 0; i < items.length; i++) {
        	findAllOccurrences(items[i], element, list);
        }
        return list.toArray(new Widget[0]);
    }

    /**
     * performs the actual search for items in the tree
     * @param list the list to add matches to
     * @param item the item in the tree
     * @param element the element to compare
     */
	private void findAllOccurrences(TreeItem item, Object element, ArrayList<TreeItem> list) {
        if (element.equals(item.getData())) {
                list.add(item);
        }
        TreeItem[] items = item.getItems();
        for (int i = 0; i < items.length; i++) {
        	findAllOccurrences(items[i], element, list);
        }
    }

	 /**
     * Update the checked state of the given element and all of its children.
     *
     * @param obj the object that has been changed
     * @param enable the checked status of the obj
     */
    private void updateCheckedState(Object obj, boolean enable) {
        IBreakpoint breakpoint = (IBreakpoint)DebugPlugin.getAdapter(obj, IBreakpoint.class);
        if (breakpoint != null) {
        	Widget[] list = searchItems(obj);
        	TreeItem item = null;
        	for(int i = 0; i < list.length; i++) {
	        	item = (TreeItem)list[i];
	            item.setChecked(enable);
	            refreshParents(item);
        	}
        }
        else if (obj instanceof BreakpointContainer) {
			ArrayList<IBreakpoint> bps = new ArrayList<>();
        	getBreakpointsFromContainers((BreakpointContainer)obj, bps);
        	for(int j = 0; j < bps.size(); j++) {
        		updateCheckedState(bps.get(j), enable);
        	}
        }
     }

    /**
     * refreshes the grayed/checked state of the parents of item
     * @param item the item to refresh parents of
     */
    private void refreshParents(TreeItem item) {
    	TreeItem parent = item.getParentItem();
    	while (parent != null) {
    		int checked = getNumberChildrenChecked(parent);
        	if(checked == 0) {
        		parent.setGrayed(false);
            	parent.setChecked(false);
        	}
        	else if(checked == parent.getItemCount()) {
        		if(getNumberChildrenGrayed(parent) > 0) {
        			parent.setGrayed(true);
        		}
        		else {
        			parent.setGrayed(false);
        		}
         		parent.setChecked(true);
        	}
        	else {
        		parent.setGrayed(true);
            	parent.setChecked(true);
        	}
    		parent = parent.getParentItem();
    	}
    }

    /**
     * Gets the number of grayed children for this parent
     * @param parent the parent to inspect
     * @return treu is any one or more children is grayed, false otherwise
     */
    private int getNumberChildrenGrayed(TreeItem parent) {
    	TreeItem[] children = parent.getItems();
    	int count = 0;
    	for(int i = 0; i < children.length; i++) {
    		if(children[i].getGrayed()) {
    			count++;
    		}
    	}
    	return count;
    }

    /**
     * Checks to see if all of the children under an given parent are checked or not
     * @param children the children to check
     * @return true if all children are checked, false otherwise
     */
    private int getNumberChildrenChecked(TreeItem parent) {
    	TreeItem[] children = parent.getItems();
    	int count = 0;
    	for(int i = 0; i < children.length; i++) {
    		if(children[i].getChecked()) {
    			count++;
    		}
    	}
    	return count;
    }
}

Back to the top