1 package net.sourceforge.phpeclipse.phpeditor;
4 * (c) Copyright IBM Corp. 2000, 2001.
8 import java.util.ArrayList;
9 import java.util.Iterator;
10 import java.util.List;
12 import org.eclipse.jface.text.BadLocationException;
13 import org.eclipse.jface.text.BadPositionCategoryException;
14 import org.eclipse.jface.text.DefaultPositionUpdater;
15 import org.eclipse.jface.text.IDocument;
16 import org.eclipse.jface.text.IPositionUpdater;
17 import org.eclipse.jface.text.ITextInputListener;
18 import org.eclipse.jface.text.ITextListener;
19 import org.eclipse.jface.text.Position;
20 import org.eclipse.jface.text.TextEvent;
21 import org.eclipse.jface.text.source.ISourceViewer;
22 import org.eclipse.jface.viewers.ISelectionChangedListener;
23 import org.eclipse.jface.viewers.ISelectionProvider;
24 import org.eclipse.jface.viewers.SelectionChangedEvent;
25 import org.eclipse.swt.custom.StyledText;
26 import org.eclipse.swt.events.KeyEvent;
27 import org.eclipse.swt.events.KeyListener;
28 import org.eclipse.swt.events.MouseEvent;
29 import org.eclipse.swt.events.MouseListener;
30 import org.eclipse.swt.widgets.Control;
32 public final class PaintManager implements KeyListener, MouseListener,
33 ISelectionChangedListener, ITextListener, ITextInputListener {
35 static class PaintPositionUpdater extends DefaultPositionUpdater {
38 * Creates the position updater.
40 protected PaintPositionUpdater(String category) {
45 * If an insertion happens at a position's offset, the position is
46 * extended rather than shifted. Also, if something is added right
47 * behind the end of the position, the position is extended rather than
50 protected void adaptToInsert() {
52 int myStart = fPosition.offset;
53 int myEnd = fPosition.offset + fPosition.length;
54 myEnd = Math.max(myStart, myEnd);
56 int yoursStart = fOffset;
57 int yoursEnd = fOffset + fReplaceLength;// - 1;
58 yoursEnd = Math.max(yoursStart, yoursEnd);
60 if (myEnd < yoursStart)
63 if (myStart <= yoursStart)
64 fPosition.length += fReplaceLength;
66 fPosition.offset += fReplaceLength;
70 static class PositionManager implements IPositionManager {
72 private IDocument fDocument;
74 private IPositionUpdater fPositionUpdater;
76 private String fCategory;
78 public PositionManager() {
79 fCategory = getClass().getName() + hashCode();
80 fPositionUpdater = new PaintPositionUpdater(fCategory);
83 public void install(IDocument document) {
85 fDocument.addPositionCategory(fCategory);
86 fDocument.addPositionUpdater(fPositionUpdater);
89 public void dispose() {
93 public void uninstall(IDocument document) {
94 if (document == fDocument && document != null) {
96 fDocument.removePositionUpdater(fPositionUpdater);
97 fDocument.removePositionCategory(fCategory);
98 } catch (BadPositionCategoryException x) {
106 * @see IPositionManager#addManagedPosition(Position)
108 public void addManagedPosition(Position position) {
110 fDocument.addPosition(fCategory, position);
111 } catch (BadPositionCategoryException x) {
113 } catch (BadLocationException x) {
119 * @see IPositionManager#removeManagedPosition(Position)
121 public void removeManagedPosition(Position position) {
123 fDocument.removePosition(fCategory, position);
124 } catch (BadPositionCategoryException x) {
130 private List fPainters = new ArrayList(2);
132 private PositionManager fManager;
134 private ISourceViewer fSourceViewer;
136 private boolean fTextChanged = false;
138 //private boolean fAutoRepeat = false;
140 public PaintManager(ISourceViewer sourceViewer) {
141 fSourceViewer = sourceViewer;
144 public void addPainter(IPainter painter) {
145 if (!fPainters.contains(painter)) {
146 fPainters.add(painter);
147 if (fPainters.size() == 1)
149 painter.setPositionManager(fManager);
150 painter.paint(IPainter.INTERNAL);
154 public void removePainter(IPainter painter) {
155 if (fPainters.remove(painter))
156 painter.setPositionManager(null);
157 if (fPainters.size() == 0)
161 private void install() {
163 fManager = new PositionManager();
164 fManager.install(fSourceViewer.getDocument());
166 fSourceViewer.addTextInputListener(this);
168 ISelectionProvider provider = fSourceViewer.getSelectionProvider();
169 provider.addSelectionChangedListener(this);
171 fSourceViewer.addTextListener(this);
173 StyledText text = fSourceViewer.getTextWidget();
174 text.addKeyListener(this);
175 text.addMouseListener(this);
178 public void dispose() {
180 if (fManager != null) {
185 for (Iterator e = fPainters.iterator(); e.hasNext();)
186 ((IPainter) e.next()).dispose();
189 fSourceViewer.removeTextInputListener(this);
191 ISelectionProvider provider = fSourceViewer.getSelectionProvider();
192 if (provider != null)
193 provider.removeSelectionChangedListener(this);
195 fSourceViewer.removeTextListener(this);
197 StyledText text = fSourceViewer.getTextWidget();
198 if (text != null && !text.isDisposed()) {
199 text.removeKeyListener(this);
200 text.removeMouseListener(this);
204 private void paint(int reason) {
205 for (Iterator e = fPainters.iterator(); e.hasNext();)
206 ((IPainter) e.next()).paint(reason);
210 * @see KeyListener#keyPressed(KeyEvent)
212 public void keyPressed(KeyEvent e) {
213 paint(IPainter.KEY_STROKE);
217 * @see KeyListener#keyReleased(KeyEvent)
219 public void keyReleased(KeyEvent e) {
223 * @see MouseListener#mouseDoubleClick(MouseEvent)
225 public void mouseDoubleClick(MouseEvent e) {
229 * @see MouseListener#mouseDown(MouseEvent)
231 public void mouseDown(MouseEvent e) {
232 paint(IPainter.MOUSE_BUTTON);
236 * @see MouseListener#mouseUp(MouseEvent)
238 public void mouseUp(MouseEvent e) {
242 * @see ISelectionChangedListener#selectionChanged(SelectionChangedEvent)
244 public void selectionChanged(SelectionChangedEvent event) {
245 paint(IPainter.SELECTION);
249 * @see ITextListener#textChanged(TextEvent)
251 public void textChanged(TextEvent event) {
253 if (!event.getViewerRedrawState())
257 Control control = fSourceViewer.getTextWidget();
258 if (control != null) {
259 control.getDisplay().asyncExec(new Runnable() {
261 if (fTextChanged && fSourceViewer != null)
262 paint(IPainter.TEXT_CHANGE);
269 * @see ITextInputListener#inputDocumentAboutToBeChanged(IDocument,
272 public void inputDocumentAboutToBeChanged(IDocument oldInput,
273 IDocument newInput) {
274 if (oldInput != null) {
275 for (Iterator e = fPainters.iterator(); e.hasNext();)
276 ((IPainter) e.next()).deactivate(false);
277 fManager.uninstall(oldInput);
282 * @see ITextInputListener#inputDocumentChanged(IDocument, IDocument)
284 public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
285 if (newInput != null) {
286 fManager.install(newInput);
287 paint(IPainter.TEXT_CHANGE);