| 1 | package de.uka.ipd.sdq.pcm.gmf.resource.editors; |
| 2 | |
| 3 | import org.eclipse.core.runtime.Assert; |
| 4 | import org.eclipse.jface.text.BadLocationException; |
| 5 | import org.eclipse.jface.text.DocumentEvent; |
| 6 | import org.eclipse.jface.text.IDocument; |
| 7 | import org.eclipse.jface.text.IRegion; |
| 8 | import org.eclipse.jface.text.ITypedRegion; |
| 9 | import org.eclipse.jface.text.Region; |
| 10 | import org.eclipse.jface.text.TextAttribute; |
| 11 | import org.eclipse.jface.text.TextPresentation; |
| 12 | import org.eclipse.jface.text.presentation.IPresentationDamager; |
| 13 | import org.eclipse.jface.text.presentation.IPresentationRepairer; |
| 14 | import org.eclipse.swt.custom.StyleRange; |
| 15 | |
| 16 | public class NonRuleBasedDamagerRepairer |
| 17 | implements IPresentationDamager, IPresentationRepairer { |
| 18 | |
| 19 | /** The document this object works on */ |
| 20 | protected IDocument fDocument; |
| 21 | /** The default text attribute if non is returned as data by the current token */ |
| 22 | protected TextAttribute fDefaultTextAttribute; |
| 23 | |
| 24 | /** |
| 25 | * Constructor for NonRuleBasedDamagerRepairer. |
| 26 | */ |
| 27 | public NonRuleBasedDamagerRepairer(TextAttribute defaultTextAttribute) { |
| 28 | Assert.isNotNull(defaultTextAttribute); |
| 29 | |
| 30 | fDefaultTextAttribute = defaultTextAttribute; |
| 31 | } |
| 32 | |
| 33 | /** |
| 34 | * @see IPresentationRepairer#setDocument(IDocument) |
| 35 | */ |
| 36 | public void setDocument(IDocument document) { |
| 37 | fDocument = document; |
| 38 | } |
| 39 | |
| 40 | /** |
| 41 | * Returns the end offset of the line that contains the specified offset or |
| 42 | * if the offset is inside a line delimiter, the end offset of the next line. |
| 43 | * |
| 44 | * @param offset the offset whose line end offset must be computed |
| 45 | * @return the line end offset for the given offset |
| 46 | * @exception BadLocationException if offset is invalid in the current document |
| 47 | */ |
| 48 | protected int endOfLineOf(int offset) throws BadLocationException { |
| 49 | |
| 50 | IRegion info = fDocument.getLineInformationOfOffset(offset); |
| 51 | if (offset <= info.getOffset() + info.getLength()) |
| 52 | return info.getOffset() + info.getLength(); |
| 53 | |
| 54 | int line = fDocument.getLineOfOffset(offset); |
| 55 | try { |
| 56 | info = fDocument.getLineInformation(line + 1); |
| 57 | return info.getOffset() + info.getLength(); |
| 58 | } catch (BadLocationException x) { |
| 59 | return fDocument.getLength(); |
| 60 | } |
| 61 | } |
| 62 | |
| 63 | /** |
| 64 | * @see IPresentationDamager#getDamageRegion(ITypedRegion, DocumentEvent, boolean) |
| 65 | */ |
| 66 | public IRegion getDamageRegion( |
| 67 | ITypedRegion partition, |
| 68 | DocumentEvent event, |
| 69 | boolean documentPartitioningChanged) { |
| 70 | if (!documentPartitioningChanged) { |
| 71 | try { |
| 72 | |
| 73 | IRegion info = |
| 74 | fDocument.getLineInformationOfOffset(event.getOffset()); |
| 75 | int start = Math.max(partition.getOffset(), info.getOffset()); |
| 76 | |
| 77 | int end = |
| 78 | event.getOffset() |
| 79 | + (event.getText() == null |
| 80 | ? event.getLength() |
| 81 | : event.getText().length()); |
| 82 | |
| 83 | if (info.getOffset() <= end |
| 84 | && end <= info.getOffset() + info.getLength()) { |
| 85 | // optimize the case of the same line |
| 86 | end = info.getOffset() + info.getLength(); |
| 87 | } else |
| 88 | end = endOfLineOf(end); |
| 89 | |
| 90 | end = |
| 91 | Math.min( |
| 92 | partition.getOffset() + partition.getLength(), |
| 93 | end); |
| 94 | return new Region(start, end - start); |
| 95 | |
| 96 | } catch (BadLocationException x) { |
| 97 | } |
| 98 | } |
| 99 | |
| 100 | return partition; |
| 101 | } |
| 102 | |
| 103 | /** |
| 104 | * @see IPresentationRepairer#createPresentation(TextPresentation, ITypedRegion) |
| 105 | */ |
| 106 | public void createPresentation( |
| 107 | TextPresentation presentation, |
| 108 | ITypedRegion region) { |
| 109 | addRange( |
| 110 | presentation, |
| 111 | region.getOffset(), |
| 112 | region.getLength(), |
| 113 | fDefaultTextAttribute); |
| 114 | } |
| 115 | |
| 116 | /** |
| 117 | * Adds style information to the given text presentation. |
| 118 | * |
| 119 | * @param presentation the text presentation to be extended |
| 120 | * @param offset the offset of the range to be styled |
| 121 | * @param length the length of the range to be styled |
| 122 | * @param attr the attribute describing the style of the range to be styled |
| 123 | */ |
| 124 | protected void addRange( |
| 125 | TextPresentation presentation, |
| 126 | int offset, |
| 127 | int length, |
| 128 | TextAttribute attr) { |
| 129 | if (attr != null) |
| 130 | presentation.addStyleRange( |
| 131 | new StyleRange( |
| 132 | offset, |
| 133 | length, |
| 134 | attr.getForeground(), |
| 135 | attr.getBackground(), |
| 136 | attr.getStyle())); |
| 137 | } |
| 138 | } |