// Copyright (c) 2006 by Leif Frenzel <himself@leiffrenzel.de>
// All rights reserved.
package net.sf.eclipsefp.haskell.ui.internal.editors.cabal;
import net.sf.eclipsefp.haskell.core.cabalmodel.CabalSyntax;
import net.sf.eclipsefp.haskell.ui.internal.util.UITexts;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
/** <p>detects places on the Cabal editor where a hyperlink can be shown that
* leads to referenced resources.</p>
*
* @author Leif Frenzel
*/
class CabalHyperlinkDetector implements IHyperlinkDetector {
private final CabalFormEditor editor;
CabalHyperlinkDetector( final CabalFormEditor editor ) {
this.editor = editor;
}
// interface methods of IHyperlinkDetector
//////////////////////////////////////////
@Override
public IHyperlink[] detectHyperlinks( final ITextViewer textViewer,
final IRegion region,
final boolean canShowMultiple ) {
IHyperlink[] result = null;
String line = getLine( textViewer, region );
if( line != null ) {
String key = CabalSyntax.FIELD_LICENSE_FILE.getCabalName().toLowerCase();
if( line.toLowerCase().startsWith( key ) ) {
int index = line.indexOf( ':' );
if( index > 0 ) {
String fileName = line.substring( index + 1 ).trim();
IPath path = new Path( fileName );
IFile file = getContainer().getFile( path );
if( file.exists() ) {
int linkOffset = getHighlightRegionStart( textViewer, region )
+ line.indexOf( fileName );
int linkLength = fileName.length();
IRegion linkRegion = new Region( linkOffset, linkLength );
result = new IHyperlink[] { new CabalHyperlink( file, linkRegion ) };
}
}
}
}
return result;
}
// helping methods
//////////////////
private String getLine( final ITextViewer textViewer,
final IRegion region ) {
String result = null;
try {
IDocument doc = textViewer.getDocument();
int lineNumber = doc.getLineOfOffset( region.getOffset() );
int start = doc.getLineOffset( lineNumber );
int length = doc.getLineLength( lineNumber );
result = doc.get( start, length );
} catch( BadLocationException badlox ) {
// ignore
}
return result;
}
private int getHighlightRegionStart( final ITextViewer textViewer,
final IRegion region ) {
int result = region.getOffset();
try {
IDocument doc = textViewer.getDocument();
int lineNumber = doc.getLineOfOffset( region.getOffset() );
result = doc.getLineOffset( lineNumber );
} catch( BadLocationException badlox ) {
// ignore
}
return result;
}
private IContainer getContainer() {
IContainer result = null;
IEditorInput input = editor.getEditorInput();
if( input instanceof IFileEditorInput ) {
IFileEditorInput fei = ( IFileEditorInput )input;
IFile file = fei.getFile();
if( file != null && file.exists() ) {
result = file.getParent();
}
}
return result;
}
// inner classes
////////////////
private class CabalHyperlink implements IHyperlink {
private final IFile file;
private final IRegion region;
CabalHyperlink( final IFile file, final IRegion region ) {
this.file = file;
this.region = region;
}
// interface methods of IHyperlink
//////////////////////////////////
@Override
public IRegion getHyperlinkRegion() {
return region;
}
@Override
public void open() {
IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
IWorkbenchPage page = window.getActivePage();
try {
IDE.openEditor( page, file );
} catch( PartInitException paix ) {
Shell shell = window.getShell();
String title = UITexts.cabalHyperLinkDetector_errorTitle;
String msg = paix.getMessage();
ErrorDialog.openError( shell, title, msg, paix.getStatus() );
}
}
@Override
public String getHyperlinkText() {
// unused
return null;
}
@Override
public String getTypeLabel() {
// unused
return null;
}
}
}