blob: 3375b7f2f01218e88f73cb819890c39f2cb7f16d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2007 ILOG 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:
* Joel Cheuoua - Initial API and implementation
*******************************************************************************/
package org.eclipse.jet.internal.editor.partition;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.text.*;
import org.eclipse.jface.text.presentation.IPresentationDamager;
import org.eclipse.jface.text.presentation.IPresentationRepairer;
import org.eclipse.jface.text.rules.*;
import org.eclipse.swt.custom.StyleRange;
public class PartitionScannerBasedDamagerRepairer implements IPresentationDamager, IPresentationRepairer {
protected IDocument document;
protected IPartitionTokenScanner partitionScanner;
protected ITokenScannerProvider tokenScannerProvider;
protected TextAttribute defaultTextAttribute;
public PartitionScannerBasedDamagerRepairer(IPartitionTokenScanner scanner, ITokenScannerProvider provider) {
Assert.isNotNull(scanner);
Assert.isNotNull(provider);
partitionScanner = scanner;
tokenScannerProvider = provider;
defaultTextAttribute = new TextAttribute(null);
}
public void setDocument(IDocument document) {
this.document = document;
}
public void setPartitionScanner(IPartitionTokenScanner partitionScanner) {
this.partitionScanner = partitionScanner;
}
public void setTokenScannerProvider(ITokenScannerProvider provider) {
tokenScannerProvider = provider;
}
public IRegion getDamageRegion(ITypedRegion partition, DocumentEvent e, boolean documentPartitioningChanged) {
if (!documentPartitioningChanged)
return new Region(partition.getOffset(), partition.getLength());
else
return partition;
}
public void createPresentation(TextPresentation presentation, ITypedRegion region) {
partitionScanner.setRange(document, region.getOffset(), region.getLength());
String lastContentType = null;
int partitionScannerTokenLength = 0;
int partitionScannerTokenOffset = region.getOffset();
do {
IToken partitionToken = partitionScanner.nextToken();
if (partitionToken.isEOF()) {
if (lastContentType != null) {
ITokenScanner tokenScanner = tokenScannerProvider.getTokenScanner(lastContentType);
if (tokenScanner == null)
addRange(presentation, partitionScanner.getTokenOffset(), partitionScanner.getTokenLength(),
defaultTextAttribute);
else
applyTokenScanner(presentation, partitionScannerTokenLength, partitionScannerTokenOffset, tokenScanner);
}
break;
}
String contentType = getTokenContentType(partitionToken);
if (contentType == null)
contentType = IDocument.DEFAULT_CONTENT_TYPE;
if (contentType.equals(lastContentType)) {
partitionScannerTokenLength += partitionScanner.getTokenLength();
} else {
if (lastContentType != null) {
ITokenScanner tokenScanner = tokenScannerProvider.getTokenScanner(lastContentType);
if (tokenScanner == null)
addRange(presentation, partitionScanner.getTokenOffset(), partitionScanner.getTokenLength(),
defaultTextAttribute);
else
applyTokenScanner(presentation, partitionScannerTokenLength, partitionScannerTokenOffset, tokenScanner);
}
lastContentType = contentType;
partitionScannerTokenOffset = partitionScanner.getTokenOffset();
partitionScannerTokenLength = partitionScanner.getTokenLength();
}
} while (true);
}
private void applyTokenScanner(TextPresentation presentation, int partitionScannerTokenLength,
int partitionScannerTokenOffset, ITokenScanner tokenScanner) {
int lastStart = partitionScannerTokenOffset;
int length = 0;
boolean firstToken = true;
IToken lastToken = Token.UNDEFINED;
TextAttribute lastAttribute = getTokenTextAttribute(lastToken);
tokenScanner.setRange(document, partitionScannerTokenOffset, partitionScannerTokenLength);
do {
IToken token = tokenScanner.nextToken();
if (!token.isEOF()) {
TextAttribute attribute = getTokenTextAttribute(token);
if (lastAttribute != null && lastAttribute.equals(attribute)) {
length += tokenScanner.getTokenLength();
firstToken = false;
} else {
if (!firstToken)
addRange(presentation, lastStart, length, lastAttribute);
firstToken = false;
lastToken = token;
lastAttribute = attribute;
lastStart = tokenScanner.getTokenOffset();
length = tokenScanner.getTokenLength();
}
} else {
addRange(presentation, lastStart, length, lastAttribute);
return;
}
} while (true);
}
protected String getTokenContentType(IToken token) {
Object data = token.getData();
if (data instanceof String)
return (String) data;
else
return null;
}
protected TextAttribute getTokenTextAttribute(IToken token) {
Object data = token.getData();
if (data instanceof TextAttribute)
return (TextAttribute) data;
else
return defaultTextAttribute;
}
protected void addRange(TextPresentation presentation, int offset, int length, TextAttribute attr) {
if (attr != null) {
int style = attr.getStyle();
int fontStyle = style & 3;
StyleRange styleRange = new StyleRange(offset, length, attr.getForeground(), attr.getBackground(), fontStyle);
styleRange.strikeout = (style & 0x20000000) != 0;
styleRange.underline = (style & 0x40000000) != 0;
styleRange.font = attr.getFont();
presentation.addStyleRange(styleRange);
}
}
}