/******************************************************************************* * Copyright (c) 2007 IBM Corporation. * 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: * Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation *******************************************************************************/ package org.eclipse.imp.editor.internal; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IMarkerDelta; import org.eclipse.core.resources.IResource; 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.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.IBreakpointListener; import org.eclipse.debug.core.model.IBreakpoint; import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget; import org.eclipse.imp.editor.UniversalEditor; import org.eclipse.imp.services.IToggleBreakpointsHandler; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.viewers.ISelection; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.IWorkbenchPart; /** * Stan Sutton, suttons@us.ibm.com: * * Modified constructor to take a UniversalEditor (presumably the one creating * the adapter and to save that editor and the filename extension of the source * file opened in that editor (the "original" source file). * * The original filename extension is useful for methods that may need * the extension but that don't have access to the original file or to an * editor (or other IWorkbenchPart) from which to obtain the extension. * * The editor that created the adapter may serve as a convenient replacement * for the IWorkbenchParts that are passed into the methods that control toggling. * The interface IToggleBreakpointsTarget requires that each of these methods * be passed an IWorkbenchPart, so we can't eliminate those parameters from * the method signatures in which they occur. Another consideration is whether * the IWorkbenchParts that are passed into these methods are guaranteed to be * the same as the editor that created the adapter. I guess that in general * the adapters might be created by things other than the parts on which they * may operate (consider that a single adapter should be able to handle multiple * parts). However, I also suspect that in our usage the editors that create * the adapters are likely to be the only parts that get passed into these * methods (at least so far). In any case, the editor is availble here for * future implementors of these methods to use or not as they see fit. */ public class ToggleBreakpointsAdapter implements IToggleBreakpointsTarget, IBreakpointListener { private final IToggleBreakpointsHandler fHandler; public ToggleBreakpointsAdapter(UniversalEditor editor, IToggleBreakpointsHandler handler) { fHandler= handler; DebugPlugin.getDefault().getBreakpointManager().addBreakpointListener(this); } public void toggleLineBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException { if (selection instanceof ITextSelection) { ITextSelection textSel= (ITextSelection) selection; IEditorPart editorPart= (IEditorPart) part.getAdapter(IEditorPart.class); IFileEditorInput fileInput= (IFileEditorInput) editorPart.getEditorInput(); final IFile origSrcFile= fileInput.getFile(); final int lineNumber = textSel.getStartLine()+1; IWorkspaceRunnable wr= new IWorkspaceRunnable() { public void run(IProgressMonitor monitor) throws CoreException { IMarker marker = findBreakpointMarker(origSrcFile, lineNumber); if (marker != null) { // The following will delete the associated marker fHandler.clearLineBreakpoint(origSrcFile, lineNumber); } else { // The following will create a marker as a side-effect fHandler.setLineBreakpoint(origSrcFile, lineNumber); } } }; try { ResourcesPlugin.getWorkspace().run(wr, null); } catch (CoreException e) { throw new DebugException(e.getStatus()); } } } private IMarker findBreakpointMarker(IFile srcFile, int lineNumber) throws CoreException { IMarker[] markers = srcFile.findMarkers(IBreakpoint.LINE_BREAKPOINT_MARKER, true, IResource.DEPTH_INFINITE); for (int k = 0; k < markers.length; k++ ){ if (((Integer) markers[k].getAttribute(IMarker.LINE_NUMBER)).intValue() == lineNumber){ return markers[k]; } } return null; } public boolean canToggleLineBreakpoints(IWorkbenchPart part, ISelection selection) { return true; } public void toggleMethodBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException { } public boolean canToggleMethodBreakpoints(IWorkbenchPart part, ISelection selection) { return false; } public void toggleWatchpoints(IWorkbenchPart part, ISelection selection) throws CoreException { } public boolean canToggleWatchpoints(IWorkbenchPart part, ISelection selection) { return false; } public void breakpointAdded(IBreakpoint breakpoint) { } public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) { } public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) { } }