/******************************************************************************* * 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<IBreakpoint>(); 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<Object>(); 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>(); 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<IBreakpoint>(); 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; } }