import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
-import org.eclipse.jface.text.ITextViewerExtension3;
+import org.eclipse.jface.text.ITextViewerExtension5;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.source.Annotation;
/**
* Highlights the temporary problems.
*/
-public class ProblemPainter implements IPainter, PaintListener, IAnnotationModelListener {
-
+public class ProblemPainter implements IPainter, PaintListener, IAnnotationModelListener {
+
private static class ProblemPosition {
Position fPosition;
Color fColor;
boolean fMultiLine;
};
-
+
private boolean fIsActive= false;
private boolean fIsPainting= false;
private boolean fIsSettingModel= false;
-
+
private ITextEditor fTextEditor;
private ISourceViewer fSourceViewer;
private StyledText fTextWidget;
private IAnnotationModel fModel;
private List fProblemPositions= new ArrayList();
-
+
private Map fColorTable= new HashMap();
private Set fAnnotationSet= new HashSet();
-
-
+
+
public ProblemPainter(ITextEditor textEditor, ISourceViewer sourceViewer) {
fTextEditor= textEditor;
fSourceViewer= sourceViewer;
fTextWidget= sourceViewer.getTextWidget();
}
-
+
private boolean hasProblems() {
return !fProblemPositions.isEmpty();
- }
-
+ }
+
private void enablePainting() {
if (!fIsPainting && hasProblems()) {
fIsPainting= true;
handleDrawRequest(null);
}
}
-
+
private void disablePainting(boolean redraw) {
if (fIsPainting) {
fIsPainting= false;
handleDrawRequest(null);
}
}
-
+
private void setModel(IAnnotationModel model) {
if (fModel != model) {
if (fModel != null)
}
}
}
-
- private void catchupWithModel() {
+
+ private void catchupWithModel() {
if (fProblemPositions != null) {
fProblemPositions.clear();
if (fModel != null) {
-
+
Iterator e= new ProblemAnnotationIterator(fModel, true);
while (e.hasNext()) {
IProblemAnnotation pa= (IProblemAnnotation) e.next();
Annotation a= (Annotation) pa;
-
+
Color color= null;
AnnotationType type= pa.getAnnotationType();
if (fAnnotationSet.contains(type))
color= (Color) fColorTable.get(type);
-
+
if (color != null) {
ProblemPosition pp= new ProblemPosition();
pp.fPosition= fModel.getPosition(a);
}
}
}
-
+
private void updatePainting() {
disablePainting(true);
- catchupWithModel();
+ catchupWithModel();
enablePainting();
}
-
+
/*
* @see IAnnotationModelListener#modelChanged(IAnnotationModel)
*/
}
}
}
-
+
public void setColor(AnnotationType annotationType, Color color) {
if (color != null)
fColorTable.put(annotationType, color);
else
fColorTable.remove(annotationType);
}
-
+
public void paintAnnotations(AnnotationType annotationType, boolean paint) {
if (paint)
fAnnotationSet.add(annotationType);
else
fAnnotationSet.remove(annotationType);
}
-
+
public boolean isPaintingAnnotations() {
return !fAnnotationSet.isEmpty();
}
-
+
/*
* @see IPainter#dispose()
*/
public void dispose() {
-
- if (fColorTable != null)
+
+ if (fColorTable != null)
fColorTable.clear();
fColorTable= null;
-
+
if (fAnnotationSet != null)
fAnnotationSet.clear();
fAnnotationSet= null;
-
+
fTextWidget= null;
fModel= null;
fProblemPositions= null;
* possibly including partially visible lines.
*/
private int getInclusiveTopIndexStartOffset() {
-
- if (fTextWidget != null && !fTextWidget.isDisposed()) {
+
+ if (fTextWidget != null && !fTextWidget.isDisposed()) {
int top= fSourceViewer.getTopIndex();
if ((fTextWidget.getTopPixel() % fTextWidget.getLineHeight()) != 0)
top--;
} catch (BadLocationException ex) {
}
}
-
+
return -1;
}
-
+
/*
* @see PaintListener#paintControl(PaintEvent)
*/
if (fTextWidget != null)
handleDrawRequest(event.gc);
}
-
+
private void handleDrawRequest(GC gc) {
int vOffset= getInclusiveTopIndexStartOffset();
// http://bugs.eclipse.org/bugs/show_bug.cgi?id=17147
- int vLength= fSourceViewer.getBottomIndexEndOffset() + 1;
-
+ int vLength= fSourceViewer.getBottomIndexEndOffset() + 1;
+
for (Iterator e = fProblemPositions.iterator(); e.hasNext();) {
ProblemPosition pp = (ProblemPosition) e.next();
Position p= pp.fPosition;
if (p.overlapsWith(vOffset, vLength)) {
-
+
if (!pp.fMultiLine) {
-
+
IRegion widgetRange= getWidgetRange(p);
if (widgetRange != null)
draw(gc, widgetRange.getOffset(), widgetRange.getLength(), pp.fColor);
-
+
} else {
-
+
IDocument document= fSourceViewer.getDocument();
try {
-
- int startLine= document.getLineOfOffset(p.getOffset());
+
+ int startLine= document.getLineOfOffset(p.getOffset());
int lastInclusive= Math.max(p.getOffset(), p.getOffset() + p.getLength() - 1);
int endLine= document.getLineOfOffset(lastInclusive);
-
+
for (int i= startLine; i <= endLine; i++) {
IRegion line= document.getLineInformation(i);
int paintStart= Math.max(line.getOffset(), p.getOffset());
draw(gc, widgetRange.getOffset(), widgetRange.getLength(), pp.fColor);
}
}
-
+
} catch (BadLocationException x) {
}
}
}
}
}
-
+
private IRegion getWidgetRange(Position p) {
- if (fSourceViewer instanceof ITextViewerExtension3) {
-
- ITextViewerExtension3 extension= (ITextViewerExtension3) fSourceViewer;
+ if (fSourceViewer instanceof ITextViewerExtension5) {
+ ITextViewerExtension5 extension= (ITextViewerExtension5) fSourceViewer;
return extension.modelRange2WidgetRange(new Region(p.getOffset(), p.getLength()));
-
+
} else {
-
+
IRegion region= fSourceViewer.getVisibleRegion();
int offset= region.getOffset();
int length= region.getLength();
-
+
if (p.overlapsWith(offset , length)) {
int p1= Math.max(offset, p.getOffset());
int p2= Math.min(offset + length, p.getOffset() + p.getLength());
return new Region(p1 - offset, p2 - p1);
}
}
-
+
return null;
}
-
+
private int[] computePolyline(Point left, Point right, int height) {
-
+
final int WIDTH= 4; // must be even
final int HEIGHT= 2; // can be any number
// final int MINPEEKS= 2; // minimal number of peeks
-
+
int peeks= (right.x - left.x) / WIDTH;
// if (peeks < MINPEEKS) {
// int missing= (MINPEEKS - peeks) * WIDTH;
// left.x= Math.max(0, left.x - missing/2);
// peeks= MINPEEKS;
// }
-
+
int leftX= left.x;
-
+
// compute (number of point) * 2
int length= ((2 * peeks) + 1) * 2;
if (length < 0)
return new int[0];
-
+
int[] coordinates= new int[length];
-
+
// cache peeks' y-coordinates
int bottom= left.y + height - 1;
int top= bottom - HEIGHT;
-
+
// populate array with peek coordinates
for (int i= 0; i < peeks; i++) {
int index= 4 * i;
coordinates[index+2]= coordinates[index] + WIDTH/2;
coordinates[index+3]= top;
}
-
+
// the last down flank is missing
coordinates[length-2]= left.x + (WIDTH * peeks);
coordinates[length-1]= bottom;
-
+
return coordinates;
}
-
+
private void draw(GC gc, int offset, int length, Color color) {
if (gc != null) {
-
+
Point left= fTextWidget.getLocationAtOffset(offset);
Point right= fTextWidget.getLocationAtOffset(offset + length);
-
+
gc.setForeground(color);
int[] polyline= computePolyline(left, right, gc.getFontMetrics().getHeight());
gc.drawPolyline(polyline);
-
+
} else {
fTextWidget.redrawRange(offset, length, true);
}
}
-
+
/*
* @see IPainter#deactivate(boolean)
*/
catchupWithModel();
}
}
-
+
/*
* @see IPainter#paint(int)
*/