/*
* Copyright (C) 2006-2016 DLR, Germany
*
* All rights reserved
*
* http://www.rcenvironment.de/
*/
package de.rcenvironment.core.gui.workflow.executor.properties;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.StyledTextContent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Display;
/**
* Helper class to make whitespace,tab and carriageReturn visible in StyledText.
*
* @author Goekhan Guerkan
*/
public class WhitespaceShowListener implements PaintListener {
private static final char SPACE_SIGN = '\u00b7';
private static final char IDEOGRAPHIC_SPACE_SIGN = '\u00b0';
private static final char TAB_SIGN = '\u00bb';
private static final char CARRIAGE_RETURN_SIGN = '\u00a4';
private static final char LINE_FEED_SIGN = '\u00b6';
private StyledText scriptingText;
private boolean on;
public WhitespaceShowListener() {
on = false;
}
/**
* Checks if script for whitespace and redraws showing whitespace.
*
* @param gc drawing capabilities for Control
*/
public void handleDrawRequest(GC gc) {
if (on) {
StyledTextContent content = scriptingText.getContent();
int length = scriptingText.getCharCount();
String text = content.getTextRange(0, length);
StyleRange styleRange = null;
Color fg = null;
Point selection = scriptingText.getSelection();
StringBuffer visibleChar = new StringBuffer(10);
for (int textOffset = 0; textOffset <= length; ++textOffset) {
int delta = 0;
boolean eol = false;
if (textOffset < length) {
delta = 1;
char c = text.charAt(textOffset);
switch (c) {
case ' ':
visibleChar.append(SPACE_SIGN);
break;
case '\u3000':
visibleChar.append(IDEOGRAPHIC_SPACE_SIGN);
break;
case '\t':
visibleChar.append(TAB_SIGN);
break;
case '\r':
visibleChar.append(CARRIAGE_RETURN_SIGN);
if (textOffset >= length - 1 || text.charAt(textOffset + 1) != '\n') {
eol = true;
break;
}
continue;
case '\n':
visibleChar.append(LINE_FEED_SIGN);
break;
default:
delta = 0;
break;
}
}
if (!eol && visibleChar.length() > 0) {
int widgetOffset = 0 + textOffset - visibleChar.length() + delta;
fg = Display.getCurrent().getSystemColor(SWT.COLOR_GRAY);
draw(gc, widgetOffset, visibleChar.toString(), fg);
}
visibleChar.delete(0, visibleChar.length());
}
}
}
private void draw(GC gc, int offset, String s, Color fg) {
int baseline = scriptingText.getBaseline(offset);
FontMetrics fontMetrics = gc.getFontMetrics();
int fontBaseline = fontMetrics.getAscent() + fontMetrics.getLeading();
int baslineDelta = baseline - fontBaseline;
Point pos = scriptingText.getLocationAtOffset(offset);
gc.setForeground(fg);
gc.drawString(s, pos.x, pos.y + baslineDelta, true);
}
/**
* Is called when Check Button 'Show Whitespace' is clicked, as the Listener is not called in
* this case a new instance of GC has to be created.
*
*/
public void drawStyledText() {
GC gc = new GC(scriptingText);
gc.setAdvanced(false);
handleDrawRequest(gc);
}
/**
* Redraws the script without showing whitespace.
*
*/
public void redrawAll() {
scriptingText.redraw();
}
@Override
public void paintControl(PaintEvent event) {
handleDrawRequest(event.gc);
}
public void setScriptingText(StyledText scriptingText) {
this.scriptingText = scriptingText;
}
public boolean isOn() {
return on;
}
public void setOn(boolean on) {
this.on = on;
}
}