1 package net.sourceforge.phpeclipse.phpeditor;
5 * (c) Copyright IBM Corp. 2000, 2001.
9 import java.util.ArrayList;
10 import java.util.Iterator;
11 import java.util.List;
13 import org.eclipse.swt.custom.StyledText;
14 import org.eclipse.swt.events.KeyEvent;
15 import org.eclipse.swt.events.KeyListener;
16 import org.eclipse.swt.events.MouseEvent;
17 import org.eclipse.swt.events.MouseListener;
18 import org.eclipse.swt.widgets.Control;
20 import org.eclipse.jface.text.BadLocationException;
21 import org.eclipse.jface.text.BadPositionCategoryException;
22 import org.eclipse.jface.text.DefaultPositionUpdater;
23 import org.eclipse.jface.text.IDocument;
24 import org.eclipse.jface.text.IPositionUpdater;
25 import org.eclipse.jface.text.ITextInputListener;
26 import org.eclipse.jface.text.ITextListener;
27 import org.eclipse.jface.text.Position;
28 import org.eclipse.jface.text.TextEvent;
29 import org.eclipse.jface.text.source.ISourceViewer;
30 import org.eclipse.jface.viewers.ISelectionChangedListener;
31 import org.eclipse.jface.viewers.ISelectionProvider;
32 import org.eclipse.jface.viewers.SelectionChangedEvent;
35 public final class PaintManager implements KeyListener, MouseListener, ISelectionChangedListener, ITextListener, ITextInputListener {
38 static class PaintPositionUpdater extends DefaultPositionUpdater {
41 * Creates the position updater.
43 protected PaintPositionUpdater(String category) {
48 * If an insertion happens at a position's offset, the
49 * position is extended rather than shifted. Also, if something is added
50 * right behind the end of the position, the position is extended rather
53 protected void adaptToInsert() {
55 int myStart= fPosition.offset;
56 int myEnd= fPosition.offset + fPosition.length;
57 myEnd= Math.max(myStart, myEnd);
59 int yoursStart= fOffset;
60 int yoursEnd= fOffset + fReplaceLength;// - 1;
61 yoursEnd= Math.max(yoursStart, yoursEnd);
63 if (myEnd < yoursStart)
66 if (myStart <= yoursStart)
67 fPosition.length += fReplaceLength;
69 fPosition.offset += fReplaceLength;
73 static class PositionManager implements IPositionManager {
75 private IDocument fDocument;
76 private IPositionUpdater fPositionUpdater;
77 private String fCategory;
79 public PositionManager() {
80 fCategory= getClass().getName() + hashCode();
81 fPositionUpdater= new PaintPositionUpdater(fCategory);
84 public void install(IDocument document) {
86 fDocument.addPositionCategory(fCategory);
87 fDocument.addPositionUpdater(fPositionUpdater);
90 public void dispose() {
94 public void uninstall(IDocument document) {
95 if (document == fDocument && document != null) {
97 fDocument.removePositionUpdater(fPositionUpdater);
98 fDocument.removePositionCategory(fCategory);
99 } catch (BadPositionCategoryException x) {
107 * @see IPositionManager#addManagedPosition(Position)
109 public void addManagedPosition(Position position) {
111 fDocument.addPosition(fCategory, position);
112 } catch (BadPositionCategoryException x) {
114 } catch (BadLocationException x) {
120 * @see IPositionManager#removeManagedPosition(Position)
122 public void removeManagedPosition(Position position) {
124 fDocument.removePosition(fCategory, position);
125 } catch (BadPositionCategoryException x) {
132 private List fPainters= new ArrayList(2);
133 private PositionManager fManager;
134 private ISourceViewer fSourceViewer;
135 private boolean fTextChanged= false;
136 private boolean fAutoRepeat= false;
139 public PaintManager(ISourceViewer sourceViewer) {
140 fSourceViewer= sourceViewer;
143 public void addPainter(IPainter painter) {
144 if (!fPainters.contains(painter)) {
145 fPainters.add(painter);
146 if (fPainters.size() == 1)
148 painter.setPositionManager(fManager);
149 painter.paint(IPainter.INTERNAL);
153 public void removePainter(IPainter painter) {
154 if (fPainters.remove(painter))
155 painter.setPositionManager(null);
156 if (fPainters.size() == 0)
160 private void install() {
162 fManager= new PositionManager();
163 fManager.install(fSourceViewer.getDocument());
165 fSourceViewer.addTextInputListener(this);
167 ISelectionProvider provider= fSourceViewer.getSelectionProvider();
168 provider.addSelectionChangedListener(this);
170 fSourceViewer.addTextListener(this);
172 StyledText text= fSourceViewer.getTextWidget();
173 text.addKeyListener(this);
174 text.addMouseListener(this);
177 public void dispose() {
179 if (fManager != null) {
184 for (Iterator e = fPainters.iterator(); e.hasNext();)
185 ((IPainter) e.next()).dispose();
188 fSourceViewer.removeTextInputListener(this);
190 ISelectionProvider provider= fSourceViewer.getSelectionProvider();
191 if (provider != null)
192 provider.removeSelectionChangedListener(this);
194 fSourceViewer.removeTextListener(this);
196 StyledText text= fSourceViewer.getTextWidget();
197 if (text != null && !text.isDisposed()) {
198 text.removeKeyListener(this);
199 text.removeMouseListener(this);
203 private void paint(int reason) {
204 for (Iterator e = fPainters.iterator(); e.hasNext();)
205 ((IPainter) e.next()).paint(reason);
209 * @see KeyListener#keyPressed(KeyEvent)
211 public void keyPressed(KeyEvent e) {
212 paint(IPainter.KEY_STROKE);
216 * @see KeyListener#keyReleased(KeyEvent)
218 public void keyReleased(KeyEvent e) {
222 * @see MouseListener#mouseDoubleClick(MouseEvent)
224 public void mouseDoubleClick(MouseEvent e) {
228 * @see MouseListener#mouseDown(MouseEvent)
230 public void mouseDown(MouseEvent e) {
231 paint(IPainter.MOUSE_BUTTON);
235 * @see MouseListener#mouseUp(MouseEvent)
237 public void mouseUp(MouseEvent e) {
241 * @see ISelectionChangedListener#selectionChanged(SelectionChangedEvent)
243 public void selectionChanged(SelectionChangedEvent event) {
244 paint(IPainter.SELECTION);
248 * @see ITextListener#textChanged(TextEvent)
250 public void textChanged(TextEvent event) {
252 if (!event.getViewerRedrawState())
256 Control control= fSourceViewer.getTextWidget();
257 if (control != null) {
258 control.getDisplay().asyncExec(new Runnable() {
260 if (fTextChanged && fSourceViewer != null)
261 paint(IPainter.TEXT_CHANGE);
268 * @see ITextInputListener#inputDocumentAboutToBeChanged(IDocument, IDocument)
270 public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
271 if (oldInput != null) {
272 for (Iterator e = fPainters.iterator(); e.hasNext();)
273 ((IPainter) e.next()).deactivate(false);
274 fManager.uninstall(oldInput);
279 * @see ITextInputListener#inputDocumentChanged(IDocument, IDocument)
281 public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
282 if (newInput != null) {
283 fManager.install(newInput);
284 paint(IPainter.TEXT_CHANGE);