refactory: added UI removed from core plugin.
[phpeclipse.git] / net.sourceforge.phpeclipse.ui / src / net / sourceforge / phpeclipse / phpeditor / PaintManager.java
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PaintManager.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/phpeditor/PaintManager.java
new file mode 100644 (file)
index 0000000..9e880b4
--- /dev/null
@@ -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);
+               }
+       }
+}