blob: 6e9027ac50b7256cb6968f8c6401dd7905d16d4e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2005 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
* Brock Janiczak - bug 78494
*******************************************************************************/
package org.eclipse.debug.internal.ui.views.breakpoints;
import com.ibm.icu.text.MessageFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IBreakpointManagerListener;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IThread;
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.LazyModelPresentation;
import org.eclipse.debug.internal.ui.actions.breakpointGroups.CopyBreakpointsAction;
import org.eclipse.debug.internal.ui.actions.breakpointGroups.PasteBreakpointsAction;
import org.eclipse.debug.internal.ui.actions.breakpointGroups.RemoveFromWorkingSetAction;
import org.eclipse.debug.internal.ui.actions.breakpoints.OpenBreakpointMarkerAction;
import org.eclipse.debug.internal.ui.actions.breakpoints.ShowSupportedBreakpointsAction;
import org.eclipse.debug.internal.ui.actions.breakpoints.SkipAllBreakpointsAction;
import org.eclipse.debug.internal.ui.views.DebugUIViewsMessages;
import org.eclipse.debug.ui.AbstractDebugView;
import org.eclipse.debug.ui.IDebugModelPresentation;
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.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.ITreeViewerListener;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TreeExpansionEvent;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveListener2;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.XMLMemento;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.actions.SelectionListenerAction;
import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds;
import org.eclipse.ui.views.navigator.LocalSelectionTransfer;
/**
* This view shows the breakpoints registered with the breakpoint manager
*/
public class BreakpointsView extends AbstractDebugView implements ISelectionListener, IBreakpointManagerListener, IPerspectiveListener2 {
private BreakpointsViewEventHandler fEventHandler;
private ICheckStateListener fCheckListener= new ICheckStateListener() {
public void checkStateChanged(CheckStateChangedEvent event) {
handleCheckStateChanged(event);
}
};
private boolean fIsTrackingSelection= false;
// Persistance constants
private static String KEY_IS_TRACKING_SELECTION= "isTrackingSelection"; //$NON-NLS-1$
private static String KEY_VALUE="value"; //$NON-NLS-1$
private static final String ACTION_REMOVE_FROM_GROUP = "RemoveFromGroup"; //$NON-NLS-1$
private BreakpointsContentProvider fContentProvider;
private Clipboard fClipboard;
/**
* This memento allows the Breakpoints view to save and restore state
* when it is closed and opened within a session. A different
* memento is supplied by the platform for persistance at
* workbench shutdown.
*/
private static IMemento fgMemento;
/**
* @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
*/
public void createPartControl(Composite parent) {
super.createPartControl(parent);
DebugPlugin.getDefault().getBreakpointManager().addBreakpointManagerListener(this);
getSite().getWorkbenchWindow().addPerspectiveListener(this);
}
/**
* @see AbstractDebugView#createViewer(Composite)
*/
protected Viewer createViewer(Composite parent) {
fContentProvider= new BreakpointsContentProvider();
CheckboxTreeViewer viewer = new BreakpointsViewer(new Tree(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.CHECK));
setViewer(viewer);
viewer.setContentProvider(fContentProvider);
viewer.setSorter(new BreakpointsSorter());
viewer.setInput(DebugPlugin.getDefault().getBreakpointManager());
viewer.addCheckStateListener(fCheckListener);
viewer.addTreeListener(new ITreeViewerListener() {
public void treeExpanded(TreeExpansionEvent event) {
((BreakpointsViewer)getViewer()).updateCheckedState(event.getElement());
}
public void treeCollapsed(TreeExpansionEvent event) {
}
});
viewer.setLabelProvider(new BreakpointsLabelProvider());
// Necessary so that the PropertySheetView hears about selections in this view
getSite().setSelectionProvider(viewer);
initIsTrackingSelection();
initBreakpointOrganizers();
setEventHandler(new BreakpointsViewEventHandler(this));
initDragAndDrop();
return viewer;
}
private void initDragAndDrop() {
StructuredViewer viewer = (StructuredViewer)getViewer();
int ops= DND.DROP_MOVE | DND.DROP_COPY;
// drop
Transfer[] dropTransfers= new Transfer[] {
LocalSelectionTransfer.getInstance()
};
viewer.addDropSupport(ops, dropTransfers, new BreakpointsDropAdapter(this, viewer));
// Drag
Transfer[] dragTransfers= new Transfer[] {
LocalSelectionTransfer.getInstance()
};
viewer.addDragSupport(ops, dragTransfers, new BreakpointsDragAdapter(this, viewer));
}
/**
* Initializes whether this view tracks selection in the
* debug view from the persisted state.
*/
private void initIsTrackingSelection() {
IMemento memento= getMemento();
if (memento != null) {
IMemento node= memento.getChild(KEY_IS_TRACKING_SELECTION);
if (node != null) {
setTrackSelection(Boolean.valueOf(node.getString(KEY_VALUE)).booleanValue());
return;
}
}
setTrackSelection(false);
}
private void initBreakpointOrganizers() {
IMemento memento = getMemento();
if (memento != null) {
IMemento node = memento.getChild(IDebugUIConstants.EXTENSION_POINT_BREAKPOINT_ORGANIZERS);
if (node == null) {
fContentProvider.setOrganizers(null);
} else {
String value = node.getString(KEY_VALUE);
if (value != null) {
String[] ids = value.split(","); //$NON-NLS-1$
BreakpointOrganizerManager manager = BreakpointOrganizerManager.getDefault();
List organziers= new ArrayList();
for (int i = 0; i < ids.length; i++) {
IBreakpointOrganizer organizer = manager.getOrganizer(ids[i]);
if (organizer != null) {
organziers.add(organizer);
}
}
fContentProvider.setOrganizers((IBreakpointOrganizer[]) organziers.toArray(new IBreakpointOrganizer[organziers.size()]));
}
}
}
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.AbstractDebugView#getMemento()
*/
protected IMemento getMemento() {
if (fgMemento != null) {
return fgMemento;
}
return super.getMemento();
}
/**
* Update the checked state up the given element and all of its children.
*
* @param element
*/
public void updateCheckedState(Object element) {
((BreakpointsViewer)getViewer()).updateCheckedState(element);
}
/**
* Returns this view's viewer as a checkbox tree viewer.
* @return this view's viewer as a checkbox tree viewer
*/
public CheckboxTreeViewer getCheckboxViewer() {
return (CheckboxTreeViewer) getViewer();
}
/**
* Returns this view's content provider as a tree content provider.
* @return this view's content provider as a tree content provider
*/
public ITreeContentProvider getTreeContentProvider() {
return fContentProvider;
}
/**
* Responds to the user checking and unchecking breakpoints by enabling
* and disabling them.
*
* @param event the check state change event
*/
private void handleCheckStateChanged(CheckStateChangedEvent event) {
Object source= event.getElement();
if (source instanceof BreakpointContainer) {
handleContainerChecked(event, (BreakpointContainer) source);
} else if (source instanceof IBreakpoint) {
handleBreakpointChecked(event, (IBreakpoint) source);
}
}
/**
* A breakpoint has been checked/unchecked. Update the group
* element's checked/grayed state as appropriate.
*/
private void handleBreakpointChecked(final CheckStateChangedEvent event, final IBreakpoint breakpoint) {
final boolean enable= event.getChecked();
String jobName = enable ? DebugUIViewsMessages.BreakpointsView_0 : DebugUIViewsMessages.BreakpointsView_1; //
new Job(jobName) {
protected IStatus run(IProgressMonitor monitor) {
try {
breakpoint.setEnabled(enable);
return Status.OK_STATUS;
} catch (final CoreException e) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
String titleState= enable ? DebugUIViewsMessages.BreakpointsView_6 : DebugUIViewsMessages.BreakpointsView_7; //
String messageState= enable ? DebugUIViewsMessages.BreakpointsView_8 : DebugUIViewsMessages.BreakpointsView_9; //
DebugUIPlugin.errorDialog(DebugUIPlugin.getShell(), MessageFormat.format(DebugUIViewsMessages.BreakpointsView_10, new String[] { titleState }), MessageFormat.format(DebugUIViewsMessages.BreakpointsView_11, new String[] { messageState }), e); //
// If the breakpoint fails to update, reset its check state.
getCheckboxViewer().removeCheckStateListener(fCheckListener);
event.getCheckable().setChecked(breakpoint, !event.getChecked());
getCheckboxViewer().addCheckStateListener(fCheckListener);
}
});
}
return Status.CANCEL_STATUS;
}
}.schedule();
}
/**
* A group has been checked or unchecked. Enable/disable all of the
* breakpoints in that group to match.
*/
private void handleContainerChecked(CheckStateChangedEvent event, BreakpointContainer container) {
final IBreakpoint[] breakpoints = container.getBreakpoints();
final boolean enable= event.getChecked();
IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
public void run(IProgressMonitor monitor) throws CoreException {
for (int i = 0; i < breakpoints.length; i++) {
IBreakpoint breakpoint = breakpoints[i];
breakpoint.setEnabled(enable);
}
}
};
try {
// TODO: should use scheduling rule
ResourcesPlugin.getWorkspace().run(runnable, null);
} catch (CoreException e) {
DebugUIPlugin.log(e);
}
}
/**
* @see AbstractDebugView#getHelpContextId()
*/
protected String getHelpContextId() {
return IDebugHelpContextIds.BREAKPOINT_VIEW;
}
/**
* @see IWorkbenchPart#dispose()
*/
public void dispose() {
disposeAction(IWorkbenchActionDefinitionIds.COPY);
disposeAction(IWorkbenchActionDefinitionIds.PASTE);
disposeAction(ACTION_REMOVE_FROM_GROUP);
if (getCheckboxViewer() != null) {
getCheckboxViewer().removeCheckStateListener(fCheckListener);
}
IAction action= getAction("ShowBreakpointsForModel"); //$NON-NLS-1$
if (action != null) {
((ShowSupportedBreakpointsAction)action).dispose();
}
getSite().getPage().removeSelectionListener(IDebugUIConstants.ID_DEBUG_VIEW, this);
DebugPlugin.getDefault().getBreakpointManager().removeBreakpointManagerListener(this);
super.dispose();
if (getEventHandler() != null) {
getEventHandler().dispose();
}
if (fClipboard != null) {
fClipboard.dispose();
}
getSite().getWorkbenchWindow().removePerspectiveListener(this);
}
/**
* @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 ShowSupportedBreakpointsAction(getStructuredViewer(),this)); //$NON-NLS-1$
setAction("SkipBreakpoints", new SkipAllBreakpointsAction()); //$NON-NLS-1$
fClipboard= new Clipboard(getSite().getShell().getDisplay());
PasteBreakpointsAction paste = new PasteBreakpointsAction(this);
configure(paste, IWorkbenchActionDefinitionIds.PASTE, ActionFactory.PASTE.getId(),ISharedImages.IMG_TOOL_PASTE);
SelectionListenerAction copy = new CopyBreakpointsAction(this, fClipboard, paste);
configure(copy, IWorkbenchActionDefinitionIds.COPY, ActionFactory.COPY.getId(), ISharedImages.IMG_TOOL_COPY);
SelectionListenerAction remove = new RemoveFromWorkingSetAction(this);
setAction(ACTION_REMOVE_FROM_GROUP, remove);
getViewer().addSelectionChangedListener(remove);
}
/**
* Configures the action to override the global action, registers
* the action for selection change notification, and registers
* the action with this view.
*
* @param sla action
* @param defId action definition id
* @param globalId global action id
* @param imgId image identifier
*/
private void configure(SelectionListenerAction action, String defId, String globalId, String imgId) {
setAction(defId, action);
action.setActionDefinitionId(defId);
getViewSite().getActionBars().setGlobalActionHandler(globalId, action);
getViewer().addSelectionChangedListener(action);
action.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(imgId));
}
/**
* Cleans up selection listener action
*
* @param id action id
*/
private void disposeAction(String id) {
IAction action = getAction(id);
if (action instanceof SelectionListenerAction) {
SelectionListenerAction sla = (SelectionListenerAction) action;
if (getViewer() != null) {
getViewer().removeSelectionChangedListener(sla);
}
}
}
/**
* Adds items to the context menu.
*
* @param menu The menu to contribute to
*/
protected void fillContextMenu(IMenuManager menu) {
updateObjects();
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(getAction(IWorkbenchActionDefinitionIds.COPY));
menu.add(getAction(IWorkbenchActionDefinitionIds.PASTE));
IAction action = getAction(ACTION_REMOVE_FROM_GROUP);
if (action.isEnabled()) {
menu.add(action);
}
menu.add(new Separator(IDebugUIConstants.EMPTY_RENDER_GROUP));
menu.add(new Separator(IDebugUIConstants.BREAKPOINT_GROUP_GROUP));
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(getAction("SkipBreakpoints")); //$NON-NLS-1$
tbm.add(new Separator(IDebugUIConstants.RENDER_GROUP));
}
/**
* 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;
}
/**
* @see org.eclipse.debug.ui.AbstractDebugView#becomesVisible()
*/
protected void becomesVisible() {
super.becomesVisible();
CheckboxTreeViewer viewer = getCheckboxViewer();
ISelection selection = viewer.getSelection();
viewer.getControl().setRedraw(false);
((BreakpointsContentProvider)viewer.getContentProvider()).reorganize();
viewer.setSelection(new StructuredSelection(selection));
viewer.getControl().setRedraw(true);
}
/* (non-Javadoc)
* @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
*/
public void selectionChanged(IWorkbenchPart part, ISelection sel) {
if (sel.isEmpty() || !isTrackingSelection()) {
return;
}
IStructuredSelection selection= (IStructuredSelection) sel;
Iterator iter= selection.iterator();
Object firstElement= iter.next();
if (firstElement == null || iter.hasNext()) {
return;
}
IThread thread= null;
if (firstElement instanceof IStackFrame) {
thread= ((IStackFrame) firstElement).getThread();
} else if (firstElement instanceof IThread) {
thread= (IThread) firstElement;
} else {
return;
}
IBreakpoint[] breakpoints= thread.getBreakpoints();
getViewer().setSelection(new StructuredSelection(breakpoints), true);
}
/**
* Returns whether this view is currently tracking the
* selection from the debug view.
*
* @return whether this view is currently tracking the
* debug view's selection
*/
public boolean isTrackingSelection() {
return fIsTrackingSelection;
}
/**
* Sets whether this view should track the selection from
* the debug view.
*
* @param trackSelection whether or not this view should
* track the debug view's selection.
*/
public void setTrackSelection(boolean trackSelection) {
fIsTrackingSelection= trackSelection;
if (trackSelection) {
getSite().getPage().addSelectionListener(IDebugUIConstants.ID_DEBUG_VIEW, this);
} else {
getSite().getPage().removeSelectionListener(IDebugUIConstants.ID_DEBUG_VIEW, this);
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.IViewPart#saveState(org.eclipse.ui.IMemento)
*/
public void saveState(IMemento memento) {
super.saveState(memento);
IMemento node= memento.createChild(KEY_IS_TRACKING_SELECTION);
node.putString(KEY_VALUE, String.valueOf(fIsTrackingSelection));
StringBuffer buffer= new StringBuffer();
IBreakpointOrganizer[] organizers = getBreakpointOrganizers();
if (organizers != null) {
for (int i = 0; i < organizers.length; i++) {
IBreakpointOrganizer organizer = organizers[i];
buffer.append(organizer.getIdentifier());
if (i < (organizers.length - 1)) {
buffer.append(',');
}
}
node = memento.createChild(IDebugUIConstants.EXTENSION_POINT_BREAKPOINT_ORGANIZERS);
node.putString(KEY_VALUE, buffer.toString());
}
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.IBreakpointManagerListener#breakpointManagerEnablementChanged(boolean)
*/
public void breakpointManagerEnablementChanged(boolean enabled) {
DebugUIPlugin.getStandardDisplay().asyncExec(new Runnable() {
public void run() {
IAction action = getAction("SkipBreakpoints"); //$NON-NLS-1$
if (action != null) {
((SkipAllBreakpointsAction) action).updateActionCheckedState();
}
}
});
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.IDoubleClickListener#doubleClick(org.eclipse.jface.viewers.DoubleClickEvent)
*/
public void doubleClick(DoubleClickEvent event) {
IStructuredSelection selection= (IStructuredSelection) event.getSelection();
if (selection.size() == 1) {
Object element = selection.getFirstElement();
if (element instanceof BreakpointContainer) {
getCheckboxViewer().setExpandedState(element, !getCheckboxViewer().getExpandedState(element));
return;
}
}
super.doubleClick(event);
}
/**
* @param selectedContainers
*/
public void setBreakpointOrganizers(IBreakpointOrganizer[] organizers) {
Viewer viewer = getViewer();
ISelection selection = viewer.getSelection();
fContentProvider.setOrganizers(organizers);
viewer.setSelection(selection);
}
public IBreakpointOrganizer[] getBreakpointOrganizers() {
return fContentProvider.getOrganizers();
}
/* (non-Javadoc)
* @see org.eclipse.ui.IPerspectiveListener2#perspectiveChanged(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor, org.eclipse.ui.IWorkbenchPartReference, java.lang.String)
*/
public void perspectiveChanged(IWorkbenchPage page, IPerspectiveDescriptor perspective, IWorkbenchPartReference partRef, String changeId) {
if (partRef instanceof IViewReference && changeId.equals(IWorkbenchPage.CHANGE_VIEW_HIDE)) {
String id = ((IViewReference) partRef).getId();
if (id.equals(getViewSite().getId())) {
// BreakpointsView closed. Persist settings.
fgMemento= XMLMemento.createWriteRoot("BreakpointsViewMemento"); //$NON-NLS-1$
saveState(fgMemento);
}
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.IPerspectiveListener#perspectiveActivated(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor)
*/
public void perspectiveActivated(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
}
/* (non-Javadoc)
* @see org.eclipse.ui.IPerspectiveListener#perspectiveChanged(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor, java.lang.String)
*/
public void perspectiveChanged(IWorkbenchPage page, IPerspectiveDescriptor perspective, String changeId) {
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.IDebugView#getPresentation(java.lang.String)
*/
public IDebugModelPresentation getPresentation(String id) {
if (getViewer() instanceof StructuredViewer) {
IBaseLabelProvider lp = ((StructuredViewer)getViewer()).getLabelProvider();
if (lp instanceof BreakpointsLabelProvider) {
BreakpointsLabelProvider blp = (BreakpointsLabelProvider) lp;
lp = blp.getPresentation();
}
if (lp instanceof DelegatingModelPresentation) {
return ((DelegatingModelPresentation)lp).getPresentation(id);
}
if (lp instanceof LazyModelPresentation) {
if (((LazyModelPresentation)lp).getDebugModelIdentifier().equals(id)) {
return (IDebugModelPresentation)lp;
}
}
}
return null;
}
/**
* Checks if the elements contained in the given selection can
* be moved.
*
* @param selection containing the elements to be moved
*/
public boolean canMove(ISelection selection) {
if (selection.isEmpty() || !fContentProvider.isShowingGroups()) {
return false;
}
if (selection instanceof IStructuredSelection) {
IStructuredSelection ss = (IStructuredSelection) selection;
Object[] objects = ss.toArray();
for (int i = 0; i < objects.length; i++) {
Object object = objects[i];
if (object instanceof IBreakpoint) {
IBreakpoint breakpoint = (IBreakpoint) object;
BreakpointContainer[] containers = getMovedFromContainers(breakpoint);
if (containers == null || containers.length == 0) {
return false;
}
} else {
return false;
}
}
} else {
return false;
}
return true;
}
/**
* Returns whether the given selection can be pasted into the given target.
*
* @param target target of the paste
* @param selection the selection to paste
* @return whether the given selection can be pasted into the given target
*/
public boolean canPaste(Object target, ISelection selection) {
if (target instanceof BreakpointContainer) {
BreakpointContainer container = (BreakpointContainer) target;
if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
Object[] objects = ((IStructuredSelection)selection).toArray();
for (int i = 0; i < objects.length; i++) {
if (objects[i] instanceof IBreakpoint) {
IBreakpoint breakpoint = (IBreakpoint)objects[i];
if (container.contains(breakpoint) || !container.getOrganizer().canAdd(breakpoint, container.getCategory())) {
return false;
}
} else {
return false;
}
}
return true;
}
}
if(target instanceof IBreakpoint){
IBreakpoint bp = (IBreakpoint)target;
BreakpointContainer cont = getBreakpointContainer(bp);
if(cont!=null){
return canPaste(cont,selection);
}
}
return false;
}
/**
* Returns the BreakpointContainer which holds the
* given breakpoint, or null if such a container cannot be found.
* @param breakpoint the breakpoint whose container is to be returned
* @return the container of the given breakpoint.
* @since 3.2
*/
private BreakpointContainer getBreakpointContainer(IBreakpoint breakpoint) {
BreakpointContainer[] containers = fContentProvider.getContainers(breakpoint);
if (containers != null && containers.length > 0) {
return containers[0];
}
return null;
}
public void performRemove(BreakpointContainer[] containers, ISelection ss) {
if (ss instanceof IStructuredSelection) {
// remove from source on move operation
IStructuredSelection selection = (IStructuredSelection) ss;
Object[] breakpoints = selection.toArray();
for (int i = 0; i < breakpoints.length; i++) {
IBreakpoint breakpoint = (IBreakpoint) breakpoints[i];
for (int j = 0; j < containers.length; j++) {
BreakpointContainer container = containers[j];
container.getOrganizer().removeBreakpoint(breakpoint, container.getCategory());
}
}
}
}
/**
* Pastes the selection into the given target
*
* @param target target of the paste, either a BreakpointContainer,
* or a Breakpoint within a BreakpointContainer
* @param selection breakpoints
* @return whehther successful
*/
public boolean performPaste(Object target, ISelection selection) {
if (target instanceof BreakpointContainer && selection instanceof IStructuredSelection) {
BreakpointContainer container = (BreakpointContainer) target;
Object[] objects = ((IStructuredSelection)selection).toArray();
for (int i = 0; i < objects.length; i++) {
container.getOrganizer().addBreakpoint((IBreakpoint)objects[i], container.getCategory());
}
return true;
}
if(target instanceof IBreakpoint){
return performPaste(getBreakpointContainer((IBreakpoint)target),selection);
}
return false;
}
public BreakpointContainer[] getMovedFromContainers(ISelection selection) {
List list = new ArrayList();
if (selection instanceof IStructuredSelection) {
IStructuredSelection ss = (IStructuredSelection) selection;
Object[] objects = ss.toArray();
for (int i = 0; i < objects.length; i++) {
if (objects[i] instanceof IBreakpoint) {
IBreakpoint breakpoint = (IBreakpoint) objects[i];
BreakpointContainer[] containers = getMovedFromContainers(breakpoint);
for (int j = 0; j < containers.length; j++) {
list.add(containers[j]);
}
}
}
}
return (BreakpointContainer[]) list.toArray(new BreakpointContainer[list.size()]);
}
/**
* Returns the parent of the given breakpoint that allows the breakpoint
* to be removed. Only parents of selected breakpoints are considered.
*
* @param breakpoint candidate for removal
* @return containers that the breakpoint should be removed from
*/
public BreakpointContainer[] getMovedFromContainers(IBreakpoint breakpoint) {
BreakpointsViewer viewer = (BreakpointsViewer) getViewer();
Item[] items = viewer.getSelectedItems();
List list = new ArrayList();
for (int i = 0; i < items.length; i++) {
TreeItem item = (TreeItem) items[i];
if (breakpoint.equals(item.getData())) {
BreakpointContainer parent = getRemoveableParent(item, breakpoint);
if (parent != null) {
list.add(parent);
}
}
}
return (BreakpointContainer[]) list.toArray(new BreakpointContainer[list.size()]);
}
private BreakpointContainer getRemoveableParent(TreeItem item, IBreakpoint breakpoint) {
TreeItem parentItem = item.getParentItem();
if (parentItem != null) {
Object data = parentItem.getData();
if (data instanceof BreakpointContainer) {
BreakpointContainer container = (BreakpointContainer) data;
if (container.getOrganizer().canRemove(breakpoint, container.getCategory())) {
return container;
}
}
return getRemoveableParent(parentItem, breakpoint);
}
return null;
}
public boolean isShowingGroups() {
return fContentProvider.isShowingGroups();
}
/**
* Returns a list containing a point indicating the breakpoint to attempt to
* select a list of groups to select, or <code>null</code> if none.
*
* @return
*/
public List getSelectionState() {
Tree tree = ((BreakpointsViewer)getViewer()).getTree();
TreeItem[] selection = tree.getSelection();
if (selection.length > 0) {
List list = new ArrayList();
TreeItem[] roots = tree.getItems();
TreeItem first = getFirstSelectedItem(roots, selection);
if (first.getData() instanceof IBreakpoint) {
TreeItem parentItem = first.getParentItem();
if (parentItem == null) {
list.add(new Point(0, indexOf(roots, first)));
} else {
int breakpointIndex = indexOf(parentItem.getItems(),first);
while (parentItem.getParentItem() != null) {
parentItem = parentItem.getParentItem();
}
int groupIndex = indexOf(roots, parentItem);
list.add(new Point(groupIndex, breakpointIndex));
}
} else {
for (int i = 0; i < selection.length; i++) {
TreeItem item = selection[i];
list.add(item.getData());
}
}
return list;
}
return null;
}
private TreeItem getFirstSelectedItem(TreeItem[] items, TreeItem[] selection) {
for (int i = 0; i < items.length; i++) {
TreeItem item = items[i];
if (indexOf(selection, item) >= 0) {
return item;
}
TreeItem first = getFirstSelectedItem(item.getItems(), selection);
if (first != null) {
return first;
}
}
return null;
}
private int indexOf(Object[] list, Object object) {
for (int i = 0; i < list.length; i++) {
if (object.equals(list[i])) {
return i;
}
}
return -1;
}
public void preserveSelectionState(List state) {
if (state != null) {
if (state.get(0) instanceof Point) {
Point p = (Point) state.get(0);
int groupIndex = p.x;
int bpIndex = p.y;
Tree tree = ((BreakpointsViewer)getViewer()).getTree();
TreeItem[] roots = tree.getItems();
TreeItem selection = null;
if (roots.length > 0 && groupIndex < roots.length) {
TreeItem group = roots[groupIndex];
if (group.getData() instanceof IBreakpoint) {
if (bpIndex < roots.length) {
selection = roots[bpIndex];
} else {
selection = roots[roots.length -1];
}
} else {
TreeItem[] bps = group.getItems();
while (bps.length > 0 && !(bps[0].getData() instanceof IBreakpoint)) {
group = bps[0];
bps = group.getItems();
}
if (bpIndex < bps.length) {
selection = bps[bpIndex];
} else if (bps.length > 0) {
selection = bps[bps.length - 1];
} else {
selection = group;
}
}
}
if (selection != null) {
((BreakpointsViewer)getViewer()).setSelection(selection);
}
} else {
getViewer().setSelection(new StructuredSelection(state));
}
}
}
}