/*******************************************************************************
* Copyright (c) 2012 BMW Car IT 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
*******************************************************************************/
package org.jnario.feature.ui.editor;
import static org.eclipse.jface.text.IDocumentExtension3.DEFAULT_PARTITIONING;
import static org.eclipse.jface.text.TextUtilities.getContentType;
import static org.jnario.feature.ui.editor.FeatureTokenTypeToPartitionTypeMapper.NONE_CODE_PARTITION;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.source.AnnotationPainter.NullStrategy;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.projection.ProjectionSupport;
import org.eclipse.jface.text.source.projection.ProjectionViewer;
import org.eclipse.swt.custom.LineBackgroundEvent;
import org.eclipse.swt.custom.LineBackgroundListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.xtext.ui.editor.XtextSourceViewer;
import org.eclipse.xtext.xbase.ui.editor.XbaseEditor;
/**
* @author Birgit Engelmann - Initial contribution and API
*/
public class FeatureEditor extends XbaseEditor {
private static final RGB NONE_CODE_COLOR = new RGB(245, 245, 245);
public class CodeBackgroundColorizer implements LineBackgroundListener {
private Color background;
public void lineGetBackground(LineBackgroundEvent event) {
String trimedLine = event.lineText.trim();
if(trimedLine.isEmpty()){
event.lineBackground = getBackgroundColor();
}
// get offset in displayed document
int imageDocumentOffset = event.lineOffset + event.lineText.length() - 1;
// get offset in original document for matching with contentType
XtextSourceViewer viewer = (XtextSourceViewer) getSourceViewer();
int originalDocumentOffset = viewer.widgetOffset2ModelOffset(imageDocumentOffset);
if (!isNotCode(originalDocumentOffset)) {
return;
}
event.lineBackground = getBackgroundColor();
}
private Color getBackgroundColor() {
if (background == null) {
background = new Color(Display.getDefault(), NONE_CODE_COLOR);
}
return background;
}
private boolean isNotCode(int offset) {
if (offset < 0 || offset > getDocument().getLength()) {
return false;
}
try {
String contentType = getContentType(getDocument(), DEFAULT_PARTITIONING, offset, false);
return NONE_CODE_PARTITION.equals(contentType);
} catch (BadLocationException e) {
throw new RuntimeException(e);
}
}
public void dispose() {
if(background != null){
background.dispose();
background = null;
}
}
}
@Override
protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
ISourceViewer result = super.createSourceViewer(parent, ruler, styles);
result.getTextWidget().setWordWrap(true);
result.getTextWidget().addLineBackgroundListener(createBackgroundColorizer());
return result;
}
protected CodeBackgroundColorizer createBackgroundColorizer() {
return new CodeBackgroundColorizer();
}
@Override
public void dispose() {
super.dispose();
createBackgroundColorizer().dispose();
}
@Override
protected ProjectionSupport installProjectionSupport(ProjectionViewer projectionViewer) {
ProjectionSupport projectionSupport = super.installProjectionSupport(projectionViewer);
projectionSupport.setAnnotationPainterDrawingStrategy(new NullStrategy());
return projectionSupport;
}
}