blob: a3edd08c49f53406738715bc98ba3167722d59b1 [file] [log] [blame]
/*******************************************************************************
* 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 org.eclipse.ui.texteditor;
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.ITextSelection;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.INavigationLocation;
import org.eclipse.ui.NavigationLocation;
import org.eclipse.ui.internal.IWorkbenchConstants;
/**
* Represents the text selection context marked for the user in the navigation history.
*
* @since 2.1
*/
public class TextSelectionNavigationLocation extends NavigationLocation {
private final static String DELETED= "deleted"; //$NON-NLS-1$
private final static String NOT_DELETED= "not_deleted"; //$NON-NLS-1$
private final static String CATEGORY= "__navigation_" + TextSelectionNavigationLocation.class.hashCode(); //$NON-NLS-1$
private static IPositionUpdater fgPositionUpdater= new DefaultPositionUpdater(CATEGORY);
private Position fPosition;
private IDocument fDocument;
private Position fSavedPosition;
/**
* Creates a new text selection navigation location.
*
* @param part the text editor part
* @param initialize a boolean indicating whether to initialize the new instance from the current selection
*/
public TextSelectionNavigationLocation(ITextEditor part, boolean initialize) {
super(part);
if (initialize) {
ISelection s= part.getSelectionProvider().getSelection();
if(s == null || s.isEmpty())
return;
ITextSelection selection= (ITextSelection) s;
if(selection.getOffset() == 0 && selection.getLength() == 0)
return;
IDocument document= getDocument(part);
Position position= new Position(selection.getOffset(), selection.getLength());
if (installOnDocument(document, position)) {
fDocument= document;
fPosition= position;
if (!part.isDirty())
fSavedPosition= new Position(fPosition.offset, fPosition.length);
}
}
}
/**
* Returns the text editor's document.
*
* @param the text editor
* @return the document of the given text editor
*/
private IDocument getDocument(ITextEditor part) {
IDocumentProvider provider= part.getDocumentProvider();
return provider.getDocument(part.getEditorInput());
}
/**
* Installs the given position on the given document.
*
* @param document the document
* @param position the position
* @return <code>true</code> if the position could be installed
*/
private boolean installOnDocument(IDocument document, Position position) {
if (document != null && position != null) {
if (!document.containsPositionCategory(CATEGORY)) {
document.addPositionCategory(CATEGORY);
document.addPositionUpdater(fgPositionUpdater);
}
try {
document.addPosition(CATEGORY, position);
return true;
} catch (BadLocationException e) {
} catch (BadPositionCategoryException e) {
}
}
return false;
}
/**
* Uninstalls the given position from the given document.
*
* @param document the document
* @param position the position
* @return <code>true</code> if the position could be uninstalled
*/
private boolean uninstallFromDocument(IDocument document, Position position) {
if (document != null && position != null) {
try {
document.removePosition(CATEGORY, position);
Position[] category= document.getPositions(CATEGORY);
if (category == null || category.length == 0) {
document.removePositionCategory(CATEGORY);
document.removePositionUpdater(fgPositionUpdater);
}
return true;
} catch (BadPositionCategoryException e) {
}
}
return false;
}
/*
* @see Object#toString()
*/
public String toString() {
return "Selection<" + fPosition + ">"; //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* Tells whether this location is equal to the current
* location in the given text editor.
*
* @param part the text editor
* @return <code>true</code> if the locations are equal
*/
private boolean equalsLocationOf(ITextEditor part) {
if (fPosition == null)
return true;
if (fPosition.isDeleted)
return false;
ISelectionProvider provider= part.getSite().getSelectionProvider();
ISelection selection= provider.getSelection();
if (selection instanceof ITextSelection) {
ITextSelection textSelection= (ITextSelection) selection;
if (textSelection.getOffset() == fPosition.offset && textSelection.getLength() == fPosition.length) {
String text= textSelection.getText();
if (text != null) {
try {
return text.equals(fDocument.get(fPosition.offset, fPosition.length));
} catch (BadLocationException e) {
}
}
}
}
return false;
}
public void dispose() {
uninstallFromDocument(fDocument, fPosition);
fDocument= null;
fPosition= null;
fSavedPosition= null;
super.dispose();
}
/**
* Releases the state of this location.
*/
public void releaseState() {
// deactivate
uninstallFromDocument(fDocument, fPosition);
fDocument= null;
fPosition= null;
fSavedPosition= null;
super.releaseState();
}
/**
* Merges the given location into this one.
*
* @param location the location to merge into this one
* @return <code>true<code> if merging was successful
*/
public boolean mergeInto(INavigationLocation location) {
if (location == null)
return false;
if (getClass() != location.getClass())
return false;
if (fPosition == null || fPosition.isDeleted)
return true;
TextSelectionNavigationLocation s= (TextSelectionNavigationLocation) location;
if (s.fPosition == null || s.fPosition.isDeleted) {
uninstallFromDocument(fDocument, fPosition);
s.fDocument= fDocument;
s. fPosition= fPosition;
s.fSavedPosition= fSavedPosition;
return true;
}
return s.fDocument == fDocument && s.fPosition.equals(fPosition);
}
/**
* Restores this location.
*/
public void restoreLocation() {
if (fPosition == null || fPosition.isDeleted)
return;
IEditorPart part= getEditorPart();
if (part instanceof ITextEditor) {
ITextEditor editor= (ITextEditor) getEditorPart();
editor.selectAndReveal(fPosition.offset, fPosition.length);
}
}
/**
* Restores the object state from the given memento.
*
* @param memento the memento
*/
public void restoreState(IMemento memento) {
IEditorPart part= getEditorPart();
if (part instanceof ITextEditor) {
// restore
fDocument= getDocument((ITextEditor) part);
Integer offset= memento.getInteger(IWorkbenchConstants.TAG_X);
Integer length= memento.getInteger(IWorkbenchConstants.TAG_Y);
String deleted= memento.getString(IWorkbenchConstants.TAG_INFO);
if (offset != null && length != null) {
Position p= new Position(offset.intValue(), length.intValue());
if (deleted != null)
p.isDeleted= DELETED.equals(deleted) ? true : false;
// activate
if (installOnDocument(fDocument, p)) {
fPosition= p;
if (!part.isDirty())
fSavedPosition= new Position(fPosition.offset, fPosition.length);
}
}
}
}
/**
* Stores the object state into the given memento.
*
* @param memento the memento
*/
public void saveState(IMemento memento) {
if (fSavedPosition != null) {
memento.putInteger(IWorkbenchConstants.TAG_X, fSavedPosition.offset);
memento.putInteger(IWorkbenchConstants.TAG_Y, fSavedPosition.length);
memento.putString(IWorkbenchConstants.TAG_INFO, (fSavedPosition.isDeleted ? DELETED : NOT_DELETED));
}
}
/**
* Hook method which is called when the given editor has been saved.
*
* @param part the editor part
*/
public void partSaved(IEditorPart part) {
// http://dev.eclipse.org/bugs/show_bug.cgi?id=25440
if (fPosition == null || fPosition.isDeleted())
fSavedPosition= null;
else
fSavedPosition= new Position(fPosition.offset, fPosition.length);
}
/**
* Updates the this location.
*/
public void update() {
IEditorPart part= getEditorPart();
if (part instanceof ITextEditor) {
ITextEditor textEditor= (ITextEditor) getEditorPart();
if(equalsLocationOf(textEditor))
return;
ISelection s= textEditor.getSelectionProvider().getSelection();
if(s == null || s.isEmpty())
return;
ITextSelection selection= (ITextSelection) s;
if(selection.getOffset() == 0 && selection.getLength() == 0)
return;
fPosition.offset= selection.getOffset();
fPosition.length= selection.getLength();
fPosition.isDeleted= false;
if (!part.isDirty())
fSavedPosition= new Position(fPosition.offset, fPosition.length);
}
}
}