Added patch for #1589521 "3 character function names invalid?"
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / phpeditor / BracketPainter.java
1 package net.sourceforge.phpeclipse.phpeditor;
2
3 /*
4  * (c) Copyright IBM Corp. 2000, 2001.
5  * All Rights Reserved.
6  */
7
8 import net.sourceforge.phpdt.internal.ui.text.PHPPairMatcher;
9
10 import org.eclipse.jface.text.IRegion;
11 import org.eclipse.jface.text.ITextViewerExtension5;
12 import org.eclipse.jface.text.Position;
13 import org.eclipse.jface.text.Region;
14 import org.eclipse.jface.text.source.ISourceViewer;
15 import org.eclipse.swt.custom.StyledText;
16 import org.eclipse.swt.events.PaintEvent;
17 import org.eclipse.swt.events.PaintListener;
18 import org.eclipse.swt.graphics.Color;
19 import org.eclipse.swt.graphics.GC;
20 import org.eclipse.swt.graphics.Point;
21
22 public final class BracketPainter implements IPainter, PaintListener {
23
24         private PHPPairMatcher fMatcher = new PHPPairMatcher(new char[] { '{', '}',
25                         '(', ')', '[', ']' });
26
27         private Position fBracketPosition = new Position(0, 0);
28
29         private int fAnchor;
30
31         private boolean fIsActive = false;
32
33         private ISourceViewer fSourceViewer;
34
35         private StyledText fTextWidget;
36
37         private Color fColor;
38
39         private IPositionManager fPositionManager;
40
41         public BracketPainter(ISourceViewer sourceViewer) {
42                 fSourceViewer = sourceViewer;
43                 fTextWidget = sourceViewer.getTextWidget();
44         }
45
46         public void setHighlightColor(Color color) {
47                 fColor = color;
48         }
49
50         public void dispose() {
51                 if (fMatcher != null) {
52                         fMatcher.dispose();
53                         fMatcher = null;
54                 }
55
56                 fColor = null;
57                 fTextWidget = null;
58         }
59
60         public void deactivate(boolean redraw) {
61                 if (fIsActive) {
62                         fIsActive = false;
63                         fTextWidget.removePaintListener(this);
64                         if (fPositionManager != null)
65                                 fPositionManager.removeManagedPosition(fBracketPosition);
66                         if (redraw)
67                                 handleDrawRequest(null);
68                 }
69         }
70
71         public void paintControl(PaintEvent event) {
72                 if (fTextWidget != null)
73                         handleDrawRequest(event.gc);
74         }
75
76         private void handleDrawRequest(GC gc) {
77
78                 if (fBracketPosition.isDeleted)
79                         return;
80
81                 int offset = fBracketPosition.getOffset();
82                 int length = fBracketPosition.getLength();
83                 if (length < 1)
84                         return;
85
86                 if (fSourceViewer instanceof ITextViewerExtension5) {
87                         ITextViewerExtension5 extension = (ITextViewerExtension5) fSourceViewer;
88                         IRegion widgetRange = extension.modelRange2WidgetRange(new Region(
89                                         offset, length));
90                         if (widgetRange == null)
91                                 return;
92
93                         offset = widgetRange.getOffset();
94                         length = widgetRange.getLength();
95
96                 } else {
97                         IRegion region = fSourceViewer.getVisibleRegion();
98                         if (region.getOffset() > offset
99                                         || region.getOffset() + region.getLength() < offset
100                                                         + length)
101                                 return;
102                         offset -= region.getOffset();
103                 }
104
105                 if (PHPPairMatcher.RIGHT == fAnchor)
106                         draw(gc, offset, 1);
107                 else
108                         draw(gc, offset + length - 1, 1);
109         }
110
111         private void draw(GC gc, int offset, int length) {
112                 if (gc != null) {
113                         Point left = fTextWidget.getLocationAtOffset(offset);
114                         Point right = fTextWidget.getLocationAtOffset(offset + length);
115
116                         gc.setForeground(fColor);
117                         gc.drawRectangle(left.x, left.y, right.x - left.x - 1, gc
118                                         .getFontMetrics().getHeight() - 1);
119
120                 } else {
121                         fTextWidget.redrawRange(offset, length, true);
122                 }
123         }
124
125         /*
126          * @see IPainter#paint(int)
127          */
128         public void paint(int reason) {
129                 Point selection = fSourceViewer.getSelectedRange();
130                 if (selection.y > 0) {
131                         deactivate(true);
132                         return;
133                 }
134
135                 IRegion pair = fMatcher.match(fSourceViewer.getDocument(), selection.x);
136                 if (pair == null) {
137                         deactivate(true);
138                         return;
139                 }
140
141                 if (fIsActive) {
142                         // only if different
143                         if (pair.getOffset() != fBracketPosition.getOffset()
144                                         || pair.getLength() != fBracketPosition.getLength()
145                                         || fMatcher.getAnchor() != fAnchor) {
146
147                                 // remove old highlighting
148                                 handleDrawRequest(null);
149                                 // update position
150                                 fBracketPosition.isDeleted = false;
151                                 fBracketPosition.offset = pair.getOffset();
152                                 fBracketPosition.length = pair.getLength();
153                                 fAnchor = fMatcher.getAnchor();
154                                 // apply new highlighting
155                                 handleDrawRequest(null);
156
157                         }
158                 } else {
159
160                         fIsActive = true;
161
162                         fBracketPosition.isDeleted = false;
163                         fBracketPosition.offset = pair.getOffset();
164                         fBracketPosition.length = pair.getLength();
165                         fAnchor = fMatcher.getAnchor();
166
167                         fTextWidget.addPaintListener(this);
168                         fPositionManager.addManagedPosition(fBracketPosition);
169                         handleDrawRequest(null);
170                 }
171         }
172
173         /*
174          * @see IPainter#setPositionManager(IPositionManager)
175          */
176         public void setPositionManager(IPositionManager manager) {
177                 fPositionManager = manager;
178         }
179 }