blob: 1d177911170f6652edf97ce2c08f0b38bb67f36a [file] [log] [blame]
/*
*(c) Copyright QNX Software Systems Ltd. 2002.
* All Rights Reserved.
*
*/
package org.eclipse.cdt.debug.internal.ui.actions;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.cdt.debug.core.CDebugModel;
import org.eclipse.cdt.debug.core.sourcelookup.IDisassemblyStorage;
import org.eclipse.cdt.debug.internal.ui.editors.DisassemblyEditorInput;
import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IBreakpointManager;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.IVerticalRulerInfo;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.ui.texteditor.IUpdate;
/**
*
* Enter type comment.
*
* @since Aug 23, 2002
*/
public class ManageBreakpointRulerAction extends Action implements IUpdate
{
private IVerticalRulerInfo fRuler;
private ITextEditor fTextEditor;
private List fMarkers;
private String fAddLabel;
private String fRemoveLabel;
/**
* Constructor for ManageBreakpointRulerAction.
*
* @param ruler
* @param editor
*/
public ManageBreakpointRulerAction( IVerticalRulerInfo ruler, ITextEditor editor )
{
fRuler = ruler;
fTextEditor = editor;
fAddLabel = "Add Breakpoint";
fRemoveLabel = "Remove Breakpoint";
}
/* (non-Javadoc)
* @see org.eclipse.ui.texteditor.IUpdate#update()
*/
public void update()
{
fMarkers = getMarkers();
setText( fMarkers.isEmpty() ? fAddLabel : fRemoveLabel );
}
/**
* @see Action#run()
*/
public void run()
{
if ( fMarkers.isEmpty() )
{
addMarker();
}
else
{
removeMarkers( fMarkers );
}
}
protected List getMarkers()
{
List breakpoints = new ArrayList();
IResource resource = getResource();
IDocument document = getDocument();
AbstractMarkerAnnotationModel model = getAnnotationModel();
if ( model != null )
{
try
{
IMarker[] markers = null;
if ( resource instanceof IFile && !(getTextEditor().getEditorInput() instanceof DisassemblyEditorInput) )
{
markers = resource.findMarkers( IBreakpoint.BREAKPOINT_MARKER,
true,
IResource.DEPTH_INFINITE );
}
else
{
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
markers = root.findMarkers( IBreakpoint.BREAKPOINT_MARKER,
true,
IResource.DEPTH_INFINITE );
}
if ( markers != null )
{
IBreakpointManager breakpointManager = DebugPlugin.getDefault().getBreakpointManager();
for ( int i = 0; i < markers.length; i++ )
{
IBreakpoint breakpoint = breakpointManager.getBreakpoint( markers[i] );
if ( breakpoint != null &&
breakpointManager.isRegistered( breakpoint ) &&
includesRulerLine( model.getMarkerPosition( markers[i] ), document ) )
breakpoints.add( markers[i] );
}
}
}
catch( CoreException x )
{
CDebugUIPlugin.log( x.getStatus() );
}
}
return breakpoints;
}
/**
* Returns the resource for which to create the marker,
* or <code>null</code> if there is no applicable resource.
*
* @return the resource for which to create the marker or <code>null</code>
*/
protected IResource getResource()
{
IEditorInput input = fTextEditor.getEditorInput();
IResource resource = (IResource)input.getAdapter( IFile.class );
if ( resource == null )
resource = (IResource)input.getAdapter( IResource.class );
return resource;
}
/**
* Checks whether a position includes the ruler's line of activity.
*
* @param position the position to be checked
* @param document the document the position refers to
* @return <code>true</code> if the line is included by the given position
*/
protected boolean includesRulerLine( Position position, IDocument document )
{
if ( position != null )
{
try
{
int markerLine = document.getLineOfOffset( position.getOffset() );
int line = fRuler.getLineOfLastMouseButtonActivity();
if ( line == markerLine )
{
return true;
}
}
catch( BadLocationException x )
{
}
}
return false;
}
/**
* Returns this action's vertical ruler info.
*
* @return this action's vertical ruler
*/
protected IVerticalRulerInfo getVerticalRulerInfo()
{
return fRuler;
}
/**
* Returns this action's editor.
*
* @return this action's editor
*/
protected ITextEditor getTextEditor()
{
return fTextEditor;
}
/**
* Returns the <code>AbstractMarkerAnnotationModel</code> of the editor's input.
*
* @return the marker annotation model
*/
protected AbstractMarkerAnnotationModel getAnnotationModel()
{
IDocumentProvider provider = fTextEditor.getDocumentProvider();
IAnnotationModel model = provider.getAnnotationModel( fTextEditor.getEditorInput() );
if ( model instanceof AbstractMarkerAnnotationModel )
{
return (AbstractMarkerAnnotationModel)model;
}
return null;
}
/**
* Returns the <code>IDocument</code> of the editor's input.
*
* @return the document of the editor's input
*/
protected IDocument getDocument()
{
IDocumentProvider provider = fTextEditor.getDocumentProvider();
return provider.getDocument( fTextEditor.getEditorInput() );
}
protected void addMarker()
{
IEditorInput editorInput = getTextEditor().getEditorInput();
int rulerLine = getVerticalRulerInfo().getLineOfLastMouseButtonActivity();
try
{
if ( editorInput instanceof IFileEditorInput )
{
createLineBreakpoint( (IFileEditorInput)editorInput, rulerLine );
}
else if ( editorInput.getAdapter( DisassemblyEditorInput.class ) != null )
{
createAddressBreakpoint( (DisassemblyEditorInput)editorInput.getAdapter( DisassemblyEditorInput.class ), rulerLine );
}
}
catch( DebugException e )
{
CDebugUIPlugin.errorDialog( "Cannot add breakpoint", e );
}
catch( CoreException e )
{
CDebugUIPlugin.errorDialog( "Cannot add breakpoint", e );
}
}
private void createLineBreakpoint( IFileEditorInput editorInput, int rulerLine ) throws CoreException
{
IDocument document = getDocument();
BreakpointLocationVerifier bv = new BreakpointLocationVerifier();
int lineNumber = bv.getValidLineBreakpointLocation( document, rulerLine );
if ( lineNumber > -1 )
{
String fileName = editorInput.getFile().getLocation().toString();
if ( fileName != null )
{
if ( CDebugModel.lineBreakpointExists( fileName, lineNumber ) == null )
{
CDebugModel.createLineBreakpoint( editorInput.getFile(), lineNumber, true, 0, "", true );
}
}
}
}
private void createAddressBreakpoint( DisassemblyEditorInput editorInput, int rulerLine ) throws CoreException
{
IDocument document = getDocument();
BreakpointLocationVerifier bv = new BreakpointLocationVerifier();
int lineNumber = bv.getValidAddressBreakpointLocation( document, rulerLine );
if ( lineNumber > -1 )
{
IResource resource = (IResource)editorInput.getAdapter( IResource.class );
if ( resource != null )
{
if ( editorInput.getStorage() != null )
{
long address = ((IDisassemblyStorage)editorInput.getStorage()).getAddress( lineNumber );
if ( address != 0 && CDebugModel.addressBreakpointExists( resource, address ) == null )
{
CDebugModel.createAddressBreakpoint( resource, address, true, 0, "", true );
}
}
}
}
}
protected void removeMarkers( List markers )
{
IBreakpointManager breakpointManager = DebugPlugin.getDefault().getBreakpointManager();
try
{
Iterator e = markers.iterator();
while( e.hasNext() )
{
IBreakpoint breakpoint = breakpointManager.getBreakpoint( (IMarker)e.next() );
breakpointManager.removeBreakpoint( breakpoint, true );
}
}
catch( CoreException e )
{
CDebugUIPlugin.errorDialog( "Cannot remove breakpoint", e );
}
}
}