package net.sf.eclipsefp.haskell.ui.internal.resolve;
import net.sf.eclipsefp.haskell.ui.HaskellUIPlugin;
import net.sf.eclipsefp.haskell.ui.internal.editors.cabal.CabalFormEditor;
import net.sf.eclipsefp.haskell.ui.internal.editors.haskell.HaskellEditor;
import net.sf.eclipsefp.haskell.util.FileUtil;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IMarkerResolution;
import org.eclipse.ui.editors.text.TextFileDocumentProvider;
import org.eclipse.ui.texteditor.IDocumentProvider;
/**
* <p>
* Bridges the gap between IMarkerResolution and QuickAssist CompletionProposal
* </p>
*
* @author JP Moresmau
*/
public abstract class MarkerCompletion implements IMarkerResolution {
/**
* @param marker
* the marker carrying the error/warning
* @param document
* the document we are working in
* @return a completion proposal
*/
public abstract ICompletionProposal getCompletionProposal(
final IMarker marker, final IDocument document );
/**
* applies the completion chosen for the given marker to the document
*/
@Override
public void run( final IMarker marker ) {
try {
IFile f = ( IFile )marker.getResource();
IDocument doc = null;
for( IEditorReference er: HaskellUIPlugin.getDefault().getWorkbench()
.getActiveWorkbenchWindow().getActivePage().getEditorReferences() ) {
IEditorInput input = er.getEditorInput();
if( input instanceof IFileEditorInput ) {
if( f.equals( ( ( IFileEditorInput )input ).getFile() ) ) {
IEditorPart editor = er.getEditor( true );
if( editor instanceof HaskellEditor ) {
doc = ( ( HaskellEditor )editor ).getDocument();
} else if (editor instanceof CabalFormEditor ) {
doc = ( ( CabalFormEditor )editor ).getModel();
}
}
}
}
IDocumentProvider prov = null;
if( doc == null ) {
prov = new TextFileDocumentProvider();
prov.connect( f );
doc = prov.getDocument( f );
}
ICompletionProposal cp = getCompletionProposal( marker, doc );
if( cp != null ) {
cp.apply( doc );
if( prov != null ) {
prov.saveDocument( new NullProgressMonitor(), f, doc, true );
}
marker.delete();
}
} catch( CoreException ex ) {
HaskellUIPlugin.log( ex );
}
}
protected String getLineStartAddition( final String added,
final IResource file ) {
if( FileUtil.hasLiterateExtension( file ) ) {
return "> " + added;
}
return added;
}
public static class MarkerCompletionProposal implements ICompletionProposal {
private final String fDisplayString;
private final String fReplacementString;
private final int fReplacementOffset;
private final int fReplacementLength;
private final int fCursorPosition;
private final IMarker fMarker;
private final String fAdditionalInfo;
public MarkerCompletionProposal( final String replacementString,
final int replacementOffset, final int replacementLength,
final int cursorPosition, final String displayString,final IMarker marker,final String additionalInfo ) {
Assert.isNotNull( replacementString );
Assert.isTrue( replacementOffset >= 0 );
Assert.isTrue( replacementLength >= 0 );
Assert.isTrue( cursorPosition >= 0 );
this.fReplacementString = replacementString;
this.fReplacementOffset = replacementOffset;
this.fReplacementLength = replacementLength;
this.fCursorPosition = cursorPosition;
this.fDisplayString = displayString;
this.fMarker=marker;
this.fAdditionalInfo=additionalInfo;
}
@Override
public void apply( final IDocument document ) {
try {
document.replace( this.fReplacementOffset, this.fReplacementLength,
this.fReplacementString );
} catch( BadLocationException localBadLocationException ) {
HaskellUIPlugin.log( localBadLocationException );
}
try {
if (this.fMarker!=null){
this.fMarker.delete();
}
} catch (CoreException ce){
HaskellUIPlugin.log( ce );
}
}
@Override
public Point getSelection( final IDocument document ) {
return new Point( this.fReplacementOffset + this.fCursorPosition, 0 );
}
@Override
public IContextInformation getContextInformation() {
return null;
}
@Override
public Image getImage() {
return null;
}
@Override
public String getDisplayString() {
if( this.fDisplayString != null ) {
return this.fDisplayString;
}
return this.fReplacementString;
}
@Override
public String getAdditionalProposalInfo() {
return fAdditionalInfo;
}
}
}