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.jface.text.BadLocationException;
14 import org.eclipse.jface.text.BadPositionCategoryException;
15 import org.eclipse.jface.text.DefaultPositionUpdater;
16 import org.eclipse.jface.text.IDocument;
17 import org.eclipse.jface.text.IPositionUpdater;
18 import org.eclipse.jface.text.ITextInputListener;
19 import org.eclipse.jface.text.ITextListener;
20 import org.eclipse.jface.text.Position;
21 import org.eclipse.jface.text.TextEvent;
22 import org.eclipse.jface.text.source.ISourceViewer;
23 import org.eclipse.jface.viewers.ISelectionChangedListener;
24 import org.eclipse.jface.viewers.ISelectionProvider;
25 import org.eclipse.jface.viewers.SelectionChangedEvent;
26 import org.eclipse.swt.custom.StyledText;
27 import org.eclipse.swt.events.KeyEvent;
28 import org.eclipse.swt.events.KeyListener;
29 import org.eclipse.swt.events.MouseEvent;
30 import org.eclipse.swt.events.MouseListener;
31 import org.eclipse.swt.widgets.Control;
34 public final class PaintManager implements KeyListener, MouseListener, ISelectionChangedListener, ITextListener, ITextInputListener {
37 static class PaintPositionUpdater extends DefaultPositionUpdater {
40 * Creates the position updater.
42 protected PaintPositionUpdater(String category) {
47 * If an insertion happens at a position's offset, the
48 * position is extended rather than shifted. Also, if something is added
49 * right behind the end of the position, the position is extended rather
52 protected void adaptToInsert() {
54 int myStart= fPosition.offset;
55 int myEnd= fPosition.offset + fPosition.length;
56 myEnd= Math.max(myStart, myEnd);
58 int yoursStart= fOffset;
59 int yoursEnd= fOffset + fReplaceLength;// - 1;
60 yoursEnd= Math.max(yoursStart, yoursEnd);
62 if (myEnd < yoursStart)
65 if (myStart <= yoursStart)
66 fPosition.length += fReplaceLength;
68 fPosition.offset += fReplaceLength;
72 static class PositionManager implements IPositionManager {
74 private IDocument fDocument;
75 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) {
131 private List fPainters= new ArrayList(2);
132 private PositionManager fManager;
133 private ISourceViewer fSourceViewer;
134 private boolean fTextChanged= false;
135 private boolean fAutoRepeat= false;
138 public PaintManager(ISourceViewer sourceViewer) {
139 fSourceViewer= sourceViewer;
142 public void addPainter(IPainter painter) {
143 if (!fPainters.contains(painter)) {
144 fPainters.add(painter);
145 if (fPainters.size() == 1)
147 painter.setPositionManager(fManager);
148 painter.paint(IPainter.INTERNAL);
152 public void removePainter(IPainter painter) {
153 if (fPainters.remove(painter))
154 painter.setPositionManager(null);
155 if (fPainters.size() == 0)
159 private void install() {
161 fManager= new PositionManager();
162 fManager.install(fSourceViewer.getDocument());
164 fSourceViewer.addTextInputListener(this);
166 ISelectionProvider provider= fSourceViewer.getSelectionProvider();
167 provider.addSelectionChangedListener(this);
169 fSourceViewer.addTextListener(this);
171 StyledText text= fSourceViewer.getTextWidget();
172 text.addKeyListener(this);
173 text.addMouseListener(this);
176 public void dispose() {
178 if (fManager != null) {
183 for (Iterator e = fPainters.iterator(); e.hasNext();)
184 ((IPainter) e.next()).dispose();
187 fSourceViewer.removeTextInputListener(this);
189 ISelectionProvider provider= fSourceViewer.getSelectionProvider();
190 if (provider != null)
191 provider.removeSelectionChangedListener(this);
193 fSourceViewer.removeTextListener(this);
195 StyledText text= fSourceViewer.getTextWidget();
196 if (text != null && !text.isDisposed()) {
197 text.removeKeyListener(this);
198 text.removeMouseListener(this);
202 private void paint(int reason) {
203 for (Iterator e = fPainters.iterator(); e.hasNext();)
204 ((IPainter) e.next()).paint(reason);
208 * @see KeyListener#keyPressed(KeyEvent)
210 public void keyPressed(KeyEvent e) {
211 paint(IPainter.KEY_STROKE);
215 * @see KeyListener#keyReleased(KeyEvent)
217 public void keyReleased(KeyEvent e) {
221 * @see MouseListener#mouseDoubleClick(MouseEvent)
223 public void mouseDoubleClick(MouseEvent e) {
227 * @see MouseListener#mouseDown(MouseEvent)
229 public void mouseDown(MouseEvent e) {
230 paint(IPainter.MOUSE_BUTTON);
234 * @see MouseListener#mouseUp(MouseEvent)
236 public void mouseUp(MouseEvent e) {
240 * @see ISelectionChangedListener#selectionChanged(SelectionChangedEvent)
242 public void selectionChanged(SelectionChangedEvent event) {
243 paint(IPainter.SELECTION);
247 * @see ITextListener#textChanged(TextEvent)
249 public void textChanged(TextEvent event) {
251 if (!event.getViewerRedrawState())
255 Control control= fSourceViewer.getTextWidget();
256 if (control != null) {
257 control.getDisplay().asyncExec(new Runnable() {
259 if (fTextChanged && fSourceViewer != null)
260 paint(IPainter.TEXT_CHANGE);
267 * @see ITextInputListener#inputDocumentAboutToBeChanged(IDocument, IDocument)
269 public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
270 if (oldInput != null) {
271 for (Iterator e = fPainters.iterator(); e.hasNext();)
272 ((IPainter) e.next()).deactivate(false);
273 fManager.uninstall(oldInput);
278 * @see ITextInputListener#inputDocumentChanged(IDocument, IDocument)
280 public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
281 if (newInput != null) {
282 fManager.install(newInput);
283 paint(IPainter.TEXT_CHANGE);