X-Git-Url: http://secure.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/link/LinkedPositionManager.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/link/LinkedPositionManager.java index 425891b..0745ef7 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/link/LinkedPositionManager.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/link/LinkedPositionManager.java @@ -1,7 +1,14 @@ -/* - * (c) Copyright IBM Corp. 2000, 2001. - * All Rights Reserved. - */ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. 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 implementation +**********************************************************************/ + package net.sourceforge.phpdt.internal.ui.text.link; import java.util.Arrays; @@ -13,7 +20,9 @@ import net.sourceforge.phpeclipse.PHPeclipsePlugin; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.BadPositionCategoryException; +import org.eclipse.jface.text.DocumentCommand; import org.eclipse.jface.text.DocumentEvent; +import org.eclipse.jface.text.IAutoEditStrategy; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocumentExtension; import org.eclipse.jface.text.IDocumentListener; @@ -22,7 +31,6 @@ import org.eclipse.jface.text.Position; import org.eclipse.jface.text.TypedPosition; import org.eclipse.jface.util.Assert; -//import org.eclipse.jdt.internal.ui.JavaPlugin; /** * This class manages linked positions in a document. Positions are linked @@ -42,20 +50,17 @@ import org.eclipse.jface.util.Assert; * gain control of the same document. * */ -public class LinkedPositionManager implements IDocumentListener, IPositionUpdater { - - private static class PositionComparator implements Comparator { - /* - * @see Comparator#compare(Object, Object) - */ - public int compare(Object object0, Object object1) { - Position position0= (Position) object0; - Position position1= (Position) object1; - - return position0.getOffset() - position1.getOffset(); - } - } - +public class LinkedPositionManager implements IDocumentListener, IPositionUpdater, IAutoEditStrategy { + + // This class still exists to properly handle code assist. + // This is due to the fact that it cannot be distinguished betweeen document changes which are + // issued by code assist and document changes which origin from another text viewer. + // There is a conflict in interest since in the latter case the linked mode should be left, but in the former case + // the linked mode should remain. + // To support content assist, document changes have to be propagated to connected positions + // by registering replace commands using IDocumentExtension. + // if it wasn't for the support of content assist, the documentChanged() method could be reduced to + // a simple call to leave(true) private class Replace implements IDocumentExtension.IReplace { private Position fReplacePosition; @@ -81,6 +86,18 @@ public class LinkedPositionManager implements IDocumentListener, IPositionUpdate document.addDocumentListener(owner); } } + + private static class PositionComparator implements Comparator { + /* + * @see Comparator#compare(Object, Object) + */ + public int compare(Object object0, Object object1) { + Position position0= (Position) object0; + Position position1= (Position) object1; + + return position0.getOffset() - position1.getOffset(); + } + } private static final String LINKED_POSITION= "LinkedPositionManager.linked.position"; //$NON-NLS-1$ private static final Comparator fgPositionComparator= new PositionComparator(); @@ -140,7 +157,7 @@ public class LinkedPositionManager implements IDocumentListener, IPositionUpdate try { fDocument.addPosition(LINKED_POSITION, new TypedPosition(offset, length, type)); } catch (BadPositionCategoryException e) { - PHPeclipsePlugin.log(e); + PHPeclipsePlugin.log(e); Assert.isTrue(false); } } @@ -184,11 +201,11 @@ public class LinkedPositionManager implements IDocumentListener, IPositionUpdate fDocument.removePositionCategory(LINKED_POSITION); } catch (BadLocationException e) { - PHPeclipsePlugin.log(e); + PHPeclipsePlugin.log(e); Assert.isTrue(false); } catch (BadPositionCategoryException e) { - PHPeclipsePlugin.log(e); + PHPeclipsePlugin.log(e); Assert.isTrue(false); } finally { @@ -198,6 +215,24 @@ public class LinkedPositionManager implements IDocumentListener, IPositionUpdate } /** + * Returns the position at the given offset, null if there is no position. + * @since 2.1 + */ + public Position getPosition(int offset) { + Position[] positions= getPositions(fDocument); + if (positions == null) + return null; + + for (int i= positions.length - 1; i >= 0; i--) { + Position position= positions[i]; + if (offset >= position.getOffset() && offset <= position.getOffset() + position.getLength()) + return positions[i]; + } + + return null; + } + + /** * Returns the first linked position. * * @return returns null if no linked position exist. @@ -242,17 +277,20 @@ public class LinkedPositionManager implements IDocumentListener, IPositionUpdate * @return returns null if no linked position exist. */ public Position getPreviousPosition(int offset) { - Position[] positions= getPositions(fDocument); + Position[] positions= getPositions(fDocument); if (positions == null) return null; + TypedPosition currentPosition= (TypedPosition) findCurrentPosition(positions, offset); + String currentType= currentPosition == null ? null : currentPosition.getType(); + Position lastPosition= null; Position position= getFirstPosition(); - - while ((position != null) && (position.getOffset() < offset)) { + + while ((position != null) && (position.getOffset() < offset) && !((TypedPosition) position).getType().equals(currentType)) { lastPosition= position; position= findNextPosition(positions, position.getOffset()); - } + } return lastPosition; } @@ -264,7 +302,7 @@ public class LinkedPositionManager implements IDocumentListener, IPositionUpdate return positions; } catch (BadPositionCategoryException e) { - PHPeclipsePlugin.log(e); + PHPeclipsePlugin.log(e); Assert.isTrue(false); } @@ -303,29 +341,21 @@ public class LinkedPositionManager implements IDocumentListener, IPositionUpdate * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent) */ public void documentAboutToBeChanged(DocumentEvent event) { + IDocument document= event.getDocument(); Position[] positions= getPositions(document); - Position position= findCurrentEditablePosition(positions, event.getOffset()); + Position position= findCurrentPosition(positions, event.getOffset()); // modification outside editable position if (position == null) { - position= findCurrentPosition(positions, event.getOffset()); - - // modification outside any position - if (position == null) { - // check for destruction of constraints (spacing of at least 1) - if ((event.getText().length() == 0) && - (findCurrentPosition(positions, event.getOffset()) != null) && - (findCurrentPosition(positions, event.getOffset() + event.getLength()) != null)) - { - leave(true); - } - - // modification intersects non-editable position - } else { + // check for destruction of constraints (spacing of at least 1) + if ((event.getText() == null || event.getText().length() == 0) && + (findCurrentPosition(positions, event.getOffset()) != null) && + (findCurrentPosition(positions, event.getOffset() + event.getLength()) != null)) + { leave(true); - } + } // modification intersects editable position } else { @@ -344,11 +374,15 @@ public class LinkedPositionManager implements IDocumentListener, IPositionUpdate /* * @see IDocumentListener#documentChanged(DocumentEvent) */ - public void documentChanged(DocumentEvent event) { + public void documentChanged(DocumentEvent event) { + + // have to handle code assist, so can't just leave the linked mode + // leave(true); + IDocument document= event.getDocument(); Position[] positions= getPositions(document); - TypedPosition currentPosition= (TypedPosition) findCurrentEditablePosition(positions, event.getOffset()); + TypedPosition currentPosition= (TypedPosition) findCurrentPosition(positions, event.getOffset()); // ignore document changes (assume it won't invalidate constraints) if (currentPosition == null) @@ -356,9 +390,11 @@ public class LinkedPositionManager implements IDocumentListener, IPositionUpdate int deltaOffset= event.getOffset() - currentPosition.getOffset(); - if (fListener != null) - fListener.setCurrentPosition(currentPosition, deltaOffset + event.getText().length()); - + if (fListener != null) { + int length= event.getText() == null ? 0 : event.getText().length(); + fListener.setCurrentPosition(currentPosition, deltaOffset + length); + } + for (int i= 0; i != positions.length; i++) { TypedPosition p= (TypedPosition) positions[i]; @@ -373,7 +409,7 @@ public class LinkedPositionManager implements IDocumentListener, IPositionUpdate * @see IPositionUpdater#update(DocumentEvent) */ public void update(DocumentEvent event) { - int deltaLength= event.getText().length() - event.getLength(); + int deltaLength= (event.getText() == null ? 0 : event.getText().length()) - event.getLength(); Position[] positions= getPositions(event.getDocument()); TypedPosition currentPosition= (TypedPosition) findCurrentPosition(positions, event.getOffset()); @@ -414,16 +450,11 @@ public class LinkedPositionManager implements IDocumentListener, IPositionUpdate return null; } - private static Position findCurrentEditablePosition(Position[] positions, int offset) { - Position position= positions[0]; - - while ((position != null) && !includes(position, offset, 0)) - position= findNextPosition(positions, position.getOffset()); - - return position; - } - private boolean containsLineDelimiters(String string) { + + if (string == null) + return false; + String[] delimiters= fDocument.getLegalLineDelimiters(); for (int i= 0; i != delimiters.length; i++) @@ -439,11 +470,55 @@ public class LinkedPositionManager implements IDocumentListener, IPositionUpdate public boolean anyPositionIncludes(int offset, int length) { Position[] positions= getPositions(fDocument); - Position position= findCurrentEditablePosition(positions, offset); + Position position= findCurrentPosition(positions, offset); if (position == null) return false; return includes(position, offset, length); } -} + /* + * @see org.eclipse.jface.text.IAutoIndentStrategy#customizeDocumentCommand(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.DocumentCommand) + */ + public void customizeDocumentCommand(IDocument document, DocumentCommand command) { + + // don't interfere with preceding auto edit strategies + if (command.getCommandCount() != 1) { + leave(true); + return; + } + + Position[] positions= getPositions(document); + TypedPosition currentPosition= (TypedPosition) findCurrentPosition(positions, command.offset); + + // handle edits outside of a position + if (currentPosition == null) { + leave(true); + return; + } + + if (! command.doit) + return; + + command.doit= false; + command.owner= this; + command.caretOffset= command.offset + command.length; + + int deltaOffset= command.offset - currentPosition.getOffset(); + + if (fListener != null) + fListener.setCurrentPosition(currentPosition, deltaOffset + command.text.length()); + + for (int i= 0; i != positions.length; i++) { + TypedPosition position= (TypedPosition) positions[i]; + + try { + if (position.getType().equals(currentPosition.getType()) && !position.equals(currentPosition)) + command.addCommand(position.getOffset() + deltaOffset, command.length, command.text, this); + } catch (BadLocationException e) { + PHPeclipsePlugin.log(e); + } + } + } + +} \ No newline at end of file