X-Git-Url: http://secure.phpeclipse.com diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/TypingRunDetector.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/TypingRunDetector.java deleted file mode 100644 index aa63874..0000000 --- a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/TypingRunDetector.java +++ /dev/null @@ -1,493 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package net.sourceforge.phpdt.internal.ui.text; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import net.sourceforge.phpdt.internal.ui.text.TypingRun.ChangeType; - -//incastrix -//import org.eclipse.jface.text.Assert; -import org.eclipse.core.runtime.Assert; -import org.eclipse.jface.text.DocumentEvent; -import org.eclipse.jface.text.ITextListener; -import org.eclipse.jface.text.ITextViewer; -import org.eclipse.jface.text.TextEvent; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.StyledText; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.KeyListener; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; - -/** - * When connected to a text viewer, a TypingRunDetector observes - * TypingRun events. A typing run is a sequence of similar text - * modifications, such as inserting or deleting single characters. - *

- * Listeners are informed about the start and end of a TypingRun. - *

- * - * @since 3.0 - */ -public class TypingRunDetector { - /* - * Implementation note: This class is independent of JDT and may be pulled - * up to jface.text if needed. - */ - - /** Debug flag. */ - private static final boolean DEBUG = false; - - /** - * Instances of this class abstract a text modification into a simple - * description. Typing runs consists of a sequence of one or more modifying - * changes of the same type. Every change records the type of change - * described by a text modification, and an offset it can be followed by - * another change of the same run. - */ - private static final class Change { - private ChangeType fType; - - private int fNextOffset; - - /** - * Creates a new change of type type. - * - * @param type - * the ChangeType of the new change - * @param nextOffset - * the offset of the next change in a typing run - */ - public Change(ChangeType type, int nextOffset) { - fType = type; - fNextOffset = nextOffset; - } - - /** - * Returns true if the receiver can extend the typing - * range the last change of which is described by change. - * - * @param change - * the last change in a typing run - * @return true if the receiver is a valid extension to - * change,false otherwise - */ - public boolean canFollow(Change change) { - if (fType == TypingRun.NO_CHANGE) - return true; - else if (fType.equals(TypingRun.UNKNOWN)) - return false; - if (fType.equals(change.fType)) { - if (fType == TypingRun.DELETE) - return fNextOffset == change.fNextOffset - 1; - else if (fType == TypingRun.INSERT) - return fNextOffset == change.fNextOffset + 1; - else if (fType == TypingRun.OVERTYPE) - return fNextOffset == change.fNextOffset + 1; - else if (fType == TypingRun.SELECTION) - return true; - } - return false; - } - - /** - * Returns true if the receiver describes a text - * modification, false if it describes a focus / - * selection change. - * - * @return true if the receiver is a text modification - */ - public boolean isModification() { - return fType.isModification(); - } - - /* - * @see java.lang.Object#toString() - */ - public String toString() { - return fType.toString() + "@" + fNextOffset; //$NON-NLS-1$ - } - - /** - * Returns the change type of this change. - * - * @return the change type of this change - */ - public ChangeType getType() { - return fType; - } - } - - /** - * Observes any events that modify the content of the document displayed in - * the editor. Since text events may start a new run, this listener is - * always registered if the detector is connected. - */ - private class TextListener implements ITextListener { - - /* - * @see org.eclipse.jface.text.ITextListener#textChanged(org.eclipse.jface.text.TextEvent) - */ - public void textChanged(TextEvent event) { - handleTextChanged(event); - } - } - - /** - * Observes non-modifying events that will end a run, such as clicking into - * the editor, moving the caret, and the editor losing focus. These events - * can never start a run, therefore this listener is only registered if - * there is an ongoing run. - */ - private class SelectionListener implements MouseListener, KeyListener, - FocusListener { - - /* - * @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent) - */ - public void focusGained(FocusEvent e) { - handleSelectionChanged(); - } - - /* - * @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent) - */ - public void focusLost(FocusEvent e) { - } - - /* - * @see MouseListener#mouseDoubleClick - */ - public void mouseDoubleClick(MouseEvent e) { - } - - /* - * If the right mouse button is pressed, the current editing command is - * closed - * - * @see MouseListener#mouseDown - */ - public void mouseDown(MouseEvent e) { - if (e.button == 1) - handleSelectionChanged(); - } - - /* - * @see MouseListener#mouseUp - */ - public void mouseUp(MouseEvent e) { - } - - /* - * @see KeyListener#keyPressed - */ - public void keyReleased(KeyEvent e) { - } - - /* - * On cursor keys, the current editing command is closed - * - * @see KeyListener#keyPressed - */ - public void keyPressed(KeyEvent e) { - switch (e.keyCode) { - case SWT.ARROW_UP: - case SWT.ARROW_DOWN: - case SWT.ARROW_LEFT: - case SWT.ARROW_RIGHT: - case SWT.END: - case SWT.HOME: - case SWT.PAGE_DOWN: - case SWT.PAGE_UP: - handleSelectionChanged(); - break; - } - } - } - - /** The listeners. */ - private final Set fListeners = new HashSet(); - - /** - * The viewer we work upon. Set to null in - * uninstall. - */ - private ITextViewer fViewer; - - /** The text event listener. */ - private final TextListener fTextListener = new TextListener(); - - /** - * The selection listener. Set to null when no run is active. - */ - private SelectionListener fSelectionListener; - - /* state variables */ - - /** The most recently observed change. Never null. */ - private Change fLastChange; - - /** The current run, or null if there is none. */ - private TypingRun fRun; - - /** - * Installs the receiver with a text viewer. - * - * @param viewer - * the viewer to install on - */ - public void install(ITextViewer viewer) { - Assert.isLegal(viewer != null); - fViewer = viewer; - connect(); - } - - /** - * Initializes the state variables and registers any permanent listeners. - */ - private void connect() { - if (fViewer != null) { - fLastChange = new Change(TypingRun.UNKNOWN, -1); - fRun = null; - fSelectionListener = null; - fViewer.addTextListener(fTextListener); - } - } - - /** - * Uninstalls the receiver and removes all listeners. install() - * must be called for events to be generated. - */ - public void uninstall() { - if (fViewer != null) { - fListeners.clear(); - disconnect(); - fViewer = null; - } - } - - /** - * Disconnects any registered listeners. - */ - private void disconnect() { - fViewer.removeTextListener(fTextListener); - ensureSelectionListenerRemoved(); - } - - /** - * Adds a listener for TypingRun events. Repeatedly adding - * the same listener instance has no effect. Listeners may be added even if - * the receiver is neither connected nor installed. - * - * @param listener - * the listener add - */ - public void addTypingRunListener(ITypingRunListener listener) { - Assert.isLegal(listener != null); - fListeners.add(listener); - if (fListeners.size() == 1) - connect(); - } - - /** - * Removes the listener from this manager. If listener is not - * registered with the receiver, nothing happens. - * - * @param listener - * the listener to remove, or null - */ - public void removeTypingRunListener(ITypingRunListener listener) { - fListeners.remove(listener); - if (fListeners.size() == 0) - disconnect(); - } - - /** - * Handles an incoming text event. - * - * @param event - * the text event that describes the text modification - */ - void handleTextChanged(TextEvent event) { - Change type = computeChange(event); - handleChange(type); - } - - /** - * Computes the change abstraction given a text event. - * - * @param event - * the text event to analyze - * @return a change object describing the event - */ - private Change computeChange(TextEvent event) { - DocumentEvent e = event.getDocumentEvent(); - if (e == null) - return new Change(TypingRun.NO_CHANGE, -1); - - int start = e.getOffset(); - int end = e.getOffset() + e.getLength(); - String newText = e.getText(); - if (newText == null) - newText = new String(); - - if (start == end) { - // no replace / delete / overwrite - if (newText.length() == 1) - return new Change(TypingRun.INSERT, end + 1); - } else if (start == end - 1) { - if (newText.length() == 1) - return new Change(TypingRun.OVERTYPE, end); - if (newText.length() == 0) - return new Change(TypingRun.DELETE, start); - } - - return new Change(TypingRun.UNKNOWN, -1); - } - - /** - * Handles an incoming selection event. - */ - void handleSelectionChanged() { - handleChange(new Change(TypingRun.SELECTION, -1)); - } - - /** - * State machine. Changes state given the current state and the incoming - * change. - * - * @param change - * the incoming change - */ - private void handleChange(Change change) { - if (change.getType() == TypingRun.NO_CHANGE) - return; - - if (DEBUG) - System.err.println("Last change: " + fLastChange); //$NON-NLS-1$ - - if (!change.canFollow(fLastChange)) - endIfStarted(change); - fLastChange = change; - if (change.isModification()) - startOrContinue(); - - if (DEBUG) - System.err.println("New change: " + change); //$NON-NLS-1$ - } - - /** - * Starts a new run if there is none and informs all listeners. If there - * already is a run, nothing happens. - */ - private void startOrContinue() { - if (!hasRun()) { - if (DEBUG) - System.err.println("+Start run"); //$NON-NLS-1$ - fRun = new TypingRun(fLastChange.getType()); - ensureSelectionListenerAdded(); - fireRunBegun(fRun); - } - } - - /** - * Returns true if there is an active run, false - * otherwise. - * - * @return true if there is an active run, false - * otherwise - */ - private boolean hasRun() { - return fRun != null; - } - - /** - * Ends any active run and informs all listeners. If there is none, nothing - * happens. - * - * @param change - * the change that triggered ending the active run - */ - private void endIfStarted(Change change) { - if (hasRun()) { - ensureSelectionListenerRemoved(); - if (DEBUG) - System.err.println("-End run"); //$NON-NLS-1$ - fireRunEnded(fRun, change.getType()); - fRun = null; - } - } - - /** - * Adds the selection listener to the text widget underlying the viewer, if - * not already done. - */ - private void ensureSelectionListenerAdded() { - if (fSelectionListener == null) { - fSelectionListener = new SelectionListener(); - StyledText textWidget = fViewer.getTextWidget(); - textWidget.addFocusListener(fSelectionListener); - textWidget.addKeyListener(fSelectionListener); - textWidget.addMouseListener(fSelectionListener); - } - } - - /** - * If there is a selection listener, it is removed from the text widget - * underlying the viewer. - */ - private void ensureSelectionListenerRemoved() { - if (fSelectionListener != null) { - StyledText textWidget = fViewer.getTextWidget(); - textWidget.removeFocusListener(fSelectionListener); - textWidget.removeKeyListener(fSelectionListener); - textWidget.removeMouseListener(fSelectionListener); - fSelectionListener = null; - } - } - - /** - * Informs all listeners about a newly started TypingRun. - * - * @param run - * the new run - */ - private void fireRunBegun(TypingRun run) { - List listeners = new ArrayList(fListeners); - for (Iterator it = listeners.iterator(); it.hasNext();) { - ITypingRunListener listener = (ITypingRunListener) it.next(); - listener.typingRunStarted(fRun); - } - } - - /** - * Informs all listeners about an ended TypingRun. - * - * @param run - * the previously active run - * @param reason - * the type of change that caused the run to be ended - */ - private void fireRunEnded(TypingRun run, ChangeType reason) { - List listeners = new ArrayList(fListeners); - for (Iterator it = listeners.iterator(); it.hasNext();) { - ITypingRunListener listener = (ITypingRunListener) it.next(); - listener.typingRunEnded(fRun, reason); - } - } -}