/*
* Copyright 2016 Nokia Solutions and Networks
* Licensed under the Apache License, Version 2.0,
* see license.txt file for details.
*/
package org.robotframework.ide.eclipse.main.plugin.tableeditor.source;
import java.util.Iterator;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.TextPresentation;
import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
import org.eclipse.jface.text.rules.ITokenScanner;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.swt.custom.StyleRange;
import org.robotframework.ide.eclipse.main.plugin.tableeditor.source.colouring.RedTokenScanner.UnableToScanTokensException;
import org.robotframework.red.swt.SwtThread;
class RedDamagerRepairer extends DefaultDamagerRepairer {
private final SourceViewer viewer;
RedDamagerRepairer(final ITokenScanner scanner, final SourceViewer sourceViewer) {
super(scanner);
this.viewer = sourceViewer;
}
@Override
public void createPresentation(final TextPresentation presentation, final ITypedRegion region) {
try {
super.createPresentation(presentation, region);
fixOverlappingRanges(presentation);
} catch (final UnableToScanTokensException e) {
// lets try to repaint
SwtThread.asyncExec(new Runnable() {
@Override
public void run() {
viewer.invalidateTextPresentation();
}
});
}
}
// sometimes it may happen that ranges are overlapping when
// one thread cleared tokens stored after reparsing while
// repainting is done; this will be repainted and fixed
// anyway in subsequent calls, but we don't want exceptions
// being thrown in such situations
private void fixOverlappingRanges(final TextPresentation presentation) {
final Iterator<?> iterator = presentation.getAllStyleRangeIterator();
StyleRange prev = null;
while (iterator.hasNext()) {
final Object next = iterator.next();
final StyleRange range = (StyleRange) next;
if (prev != null && prev.start + prev.length > range.start) {
range.start = prev.start + prev.length;
}
prev = range;
}
}
}