X-Git-Url: http://secure.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PaintManager.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PaintManager.java new file mode 100644 index 0000000..9bdc55b --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PaintManager.java @@ -0,0 +1,290 @@ +package net.sourceforge.phpeclipse.phpeditor; + +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.BadPositionCategoryException; +import org.eclipse.jface.text.DefaultPositionUpdater; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IPositionUpdater; +import org.eclipse.jface.text.ITextInputListener; +import org.eclipse.jface.text.ITextListener; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.TextEvent; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.widgets.Control; + +public final class PaintManager implements KeyListener, MouseListener, + ISelectionChangedListener, ITextListener, ITextInputListener { + + static class PaintPositionUpdater extends DefaultPositionUpdater { + + /** + * Creates the position updater. + */ + protected PaintPositionUpdater(String category) { + super(category); + } + + /** + * If an insertion happens at a position's offset, the position is + * extended rather than shifted. Also, if something is added right + * behind the end of the position, the position is extended rather than + * kept stable. + */ + protected void adaptToInsert() { + + int myStart = fPosition.offset; + int myEnd = fPosition.offset + fPosition.length; + myEnd = Math.max(myStart, myEnd); + + int yoursStart = fOffset; + int yoursEnd = fOffset + fReplaceLength;// - 1; + yoursEnd = Math.max(yoursStart, yoursEnd); + + if (myEnd < yoursStart) + return; + + if (myStart <= yoursStart) + fPosition.length += fReplaceLength; + else + fPosition.offset += fReplaceLength; + } + }; + + static class PositionManager implements IPositionManager { + + private IDocument fDocument; + + private IPositionUpdater fPositionUpdater; + + private String fCategory; + + public PositionManager() { + fCategory = getClass().getName() + hashCode(); + fPositionUpdater = new PaintPositionUpdater(fCategory); + } + + public void install(IDocument document) { + fDocument = document; + fDocument.addPositionCategory(fCategory); + fDocument.addPositionUpdater(fPositionUpdater); + } + + public void dispose() { + uninstall(fDocument); + } + + public void uninstall(IDocument document) { + if (document == fDocument && document != null) { + try { + fDocument.removePositionUpdater(fPositionUpdater); + fDocument.removePositionCategory(fCategory); + } catch (BadPositionCategoryException x) { + // should not happen + } + fDocument = null; + } + } + + /* + * @see IPositionManager#addManagedPosition(Position) + */ + public void addManagedPosition(Position position) { + try { + fDocument.addPosition(fCategory, position); + } catch (BadPositionCategoryException x) { + // should not happen + } catch (BadLocationException x) { + // should not happen + } + } + + /* + * @see IPositionManager#removeManagedPosition(Position) + */ + public void removeManagedPosition(Position position) { + try { + fDocument.removePosition(fCategory, position); + } catch (BadPositionCategoryException x) { + // should not happen + } + } + }; + + private List fPainters = new ArrayList(2); + + private PositionManager fManager; + + private ISourceViewer fSourceViewer; + + private boolean fTextChanged = false; + + //private boolean fAutoRepeat = false; + + public PaintManager(ISourceViewer sourceViewer) { + fSourceViewer = sourceViewer; + } + + public void addPainter(IPainter painter) { + if (!fPainters.contains(painter)) { + fPainters.add(painter); + if (fPainters.size() == 1) + install(); + painter.setPositionManager(fManager); + painter.paint(IPainter.INTERNAL); + } + } + + public void removePainter(IPainter painter) { + if (fPainters.remove(painter)) + painter.setPositionManager(null); + if (fPainters.size() == 0) + dispose(); + } + + private void install() { + + fManager = new PositionManager(); + fManager.install(fSourceViewer.getDocument()); + + fSourceViewer.addTextInputListener(this); + + ISelectionProvider provider = fSourceViewer.getSelectionProvider(); + provider.addSelectionChangedListener(this); + + fSourceViewer.addTextListener(this); + + StyledText text = fSourceViewer.getTextWidget(); + text.addKeyListener(this); + text.addMouseListener(this); + } + + public void dispose() { + + if (fManager != null) { + fManager.dispose(); + fManager = null; + } + + for (Iterator e = fPainters.iterator(); e.hasNext();) + ((IPainter) e.next()).dispose(); + fPainters.clear(); + + fSourceViewer.removeTextInputListener(this); + + ISelectionProvider provider = fSourceViewer.getSelectionProvider(); + if (provider != null) + provider.removeSelectionChangedListener(this); + + fSourceViewer.removeTextListener(this); + + StyledText text = fSourceViewer.getTextWidget(); + if (text != null && !text.isDisposed()) { + text.removeKeyListener(this); + text.removeMouseListener(this); + } + } + + private void paint(int reason) { + for (Iterator e = fPainters.iterator(); e.hasNext();) + ((IPainter) e.next()).paint(reason); + } + + /* + * @see KeyListener#keyPressed(KeyEvent) + */ + public void keyPressed(KeyEvent e) { + paint(IPainter.KEY_STROKE); + } + + /* + * @see KeyListener#keyReleased(KeyEvent) + */ + public void keyReleased(KeyEvent e) { + } + + /* + * @see MouseListener#mouseDoubleClick(MouseEvent) + */ + public void mouseDoubleClick(MouseEvent e) { + } + + /* + * @see MouseListener#mouseDown(MouseEvent) + */ + public void mouseDown(MouseEvent e) { + paint(IPainter.MOUSE_BUTTON); + } + + /* + * @see MouseListener#mouseUp(MouseEvent) + */ + public void mouseUp(MouseEvent e) { + } + + /* + * @see ISelectionChangedListener#selectionChanged(SelectionChangedEvent) + */ + public void selectionChanged(SelectionChangedEvent event) { + paint(IPainter.SELECTION); + } + + /* + * @see ITextListener#textChanged(TextEvent) + */ + public void textChanged(TextEvent event) { + + if (!event.getViewerRedrawState()) + return; + + fTextChanged = true; + Control control = fSourceViewer.getTextWidget(); + if (control != null) { + control.getDisplay().asyncExec(new Runnable() { + public void run() { + if (fTextChanged && fSourceViewer != null) + paint(IPainter.TEXT_CHANGE); + } + }); + } + } + + /* + * @see ITextInputListener#inputDocumentAboutToBeChanged(IDocument, + * IDocument) + */ + public void inputDocumentAboutToBeChanged(IDocument oldInput, + IDocument newInput) { + if (oldInput != null) { + for (Iterator e = fPainters.iterator(); e.hasNext();) + ((IPainter) e.next()).deactivate(false); + fManager.uninstall(oldInput); + } + } + + /* + * @see ITextInputListener#inputDocumentChanged(IDocument, IDocument) + */ + public void inputDocumentChanged(IDocument oldInput, IDocument newInput) { + if (newInput != null) { + fManager.install(newInput); + paint(IPainter.TEXT_CHANGE); + } + } +}